Commit graph

84 commits

Author SHA1 Message Date
Facu_Viñas
492daaf709 fix(reliability): add 15s per-request fetch timeout to adapters
Individual HTTP calls to Slack/Discord APIs could hang indefinitely
if the network stalls. The overall poll deadline only bounds the loop,
not each request. Now each fetch() gets AbortSignal.timeout(15_000).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 18:00:19 -03:00
Facu_Viñas
c67151bef3 fix(security): cap user_note at 500 chars to prevent LLM context DoS
Arbitrary-length free-text replies from remote channels were passed
directly into the LLM context. Now truncated to 500 chars with
trailing ellipsis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:59:32 -03:00
Facu_Viñas
41f362841e fix(security): validate channel ID format to prevent SSRF
Slack IDs must match ^[A-Z0-9]{9,12}$, Discord snowflakes must match
^\d{17,20}$. resolveRemoteConfig() and getRemoteConfigStatus() now
reject malformed IDs before they reach any URL interpolation.

Also fixes pre-existing false-positive in config tests (env overrides
couldn't affect module-level homedir() cache) — replaced with direct
isValidChannelId() unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:58:47 -03:00
Facu_Viñas
9b80c221ce fix: isolate remote-questions config test for Windows compatibility
resolveRemoteConfig test used process.env.HOME which is undefined on
Windows (Node uses USERPROFILE). Use a temp directory with both HOME
and USERPROFILE set, and clean up in a finally block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:46:44 -03:00
Facu_Viñas
8a00605e51 fix: sort prompt store by updatedAt instead of filename
getLatestPromptSummary() sorted JSON filenames alphabetically to find
the most recent prompt. Since filenames are UUIDs (random, not temporal),
this returned arbitrary results. Now reads updatedAt from each record
and picks the highest.

Also fixes test isolation on Windows (USERPROFILE) and adds a regression
test that fails with the old alphabetical sort.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:46:01 -03:00
Lex Christopherson
a37ef56146 feat: harden remote questions flow 2026-03-11 15:46:01 -03:00
Facu_Viñas
0643d63480 fix: desugar TypeScript parameter properties for strip-types compat
Node's --experimental-strip-types doesn't support parameter properties
(private readonly in constructor params). Convert to explicit field
declarations + constructor assignments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:02:23 -03:00
Facu_Viñas
c39388b2e3 fix: use Editor from pi-tui for remote command input prompts
The custom input handlers called tui.invalidate() which caused infinite
recursion. Rewrite promptMaskedInput and promptInput to use the Editor
component (same pattern as get-secrets-from-user.ts) with proper
tui.requestRender() and cache invalidation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:02:23 -03:00
Facu_Viñas
c9cb8dd1eb fix: rename remote-questions/index.ts to send.ts to avoid extension loader
Pi's DefaultResourceLoader auto-discovers extensions/*/index.ts and
expects a default export factory. remote-questions is an internal
library (consumed via dynamic import), not an extension — having an
index.ts caused the loader to try loading it as one and fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:02:23 -03:00
Facu_Viñas
45fdf5d54d feat: remote user questions via Slack/Discord for headless auto-mode
When ask_user_questions is called in non-interactive mode (ctx.hasUI = false),
transparently route questions to a configured Slack or Discord channel and poll
for the user's response. Same tool interface, automatic routing.

- Add adapter pattern for Slack (Bot Token API) and Discord (HTTP API)
- Add /gsd remote command for interactive setup wizard
- Add SLACK_BOT_TOKEN / DISCORD_BOT_TOKEN to wizard and env hydration
- Add remote_questions config to GSD preferences with merge support
- Fix parseScalar to preserve large numeric IDs (Discord channel IDs)
- Show remote channel status on session_start

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:02:23 -03:00
Marcel Reschke
8e1ddd51f2 fix: /gsd-run uses hardcoded ~/.pi/ path instead of GSD_WORKFLOW_PATH (#38)
* feat: /gsd migrate — .planning to .gsd migration tool

Add `/gsd migrate [path]` command that reads old get-shit-done .planning
directories and writes complete .gsd directory trees for GSD-2.

Pipeline: validate → parse → transform → preview → confirm → write → review

Parser (S01):
- 7 per-file parsers: roadmap, plan, summary, requirements, project, state, config
- Handles flat, milestone-sectioned, and <details>-block roadmap formats
- Bold phase entries, "Phase N:" format, decimal numbering, duplicate phase numbers
- Bullet-format requirements (- [x] **ID**: Description)
- Graceful null returns for missing files, severity-classified validation

Transformer (S02):
- Phases → slices, plans → tasks, milestones → milestones
- Float-sorted decimal phases renumbered sequentially (S01, S02, ...)
- Completion state preserved (roadmap [x] → slice done, summary → task done)
- Research consolidated with fixed file-type ordering
- Requirements classified with complete/done/shipped → validated normalization
- Vision derived from PROJECT.md with three-level fallback
- Duplicate phase numbers disambiguated by title similarity

Writer (S03):
- Format functions for all GSD-2 file types with round-trip verification
- writeGSDDirectory produces tree that deriveState() reads correctly
- generatePreview computes milestone/slice/task counts + completion %
- Null research and empty requirements silently skipped

Command (S04):
- Default to cwd when no args given; ~/path expansion
- Validation gating (fatal issues block pipeline)
- Preview with showNextAction confirmation
- Post-write agent review via prompts/review-migration.md template
- Wired into commands.ts with tab completion

Also:
- .gitignore: replace granular .gsd/* entries with .gsd/ catch-all
- README: add /gsd migrate to commands table + "Migrating from v1" section
- files.ts: widen parseRequirementCounts regex for non-R prefixed IDs

478 assertions across 6 test suites, all passing.
UAT against blade/bladeai (28 phases, 8 milestones) and aire (10 phases, 2 milestones).

* fix: persist skipped API keys so wizard doesn't repeat on every launch

When users skip optional API keys (Brave, Context7, Jina) by pressing
Enter, the wizard stores nothing. On next launch, authStorage.has()
returns false for those providers, so the wizard prompts again.

Fix: store an empty-key sentinel for skipped providers. Also guard
loadStoredEnvKeys against injecting empty strings into process.env.

* fix: respect GSD_WORKFLOW_PATH in /gsd-run command

---------

Co-authored-by: Jonathan Costin <jonathan.costin@outlook.com>
Co-authored-by: vp275 <vedantp42@gmail.com>
2026-03-11 08:11:54 -06:00
Lex Christopherson
a5fcc3964a Merge PR #24: Rename 'Get Stuff Done' to 'Get Shit Done' 2026-03-11 08:11:20 -06:00
amanape
c5c2ec4949 Replace remaining 'get stuff done' instances in verify script 2026-03-11 08:11:11 -06:00
amanape
1a05266326 Rename 'Get Stuff Done' to 'Get Shit Done' 2026-03-11 08:11:11 -06:00
Lex Christopherson
a32d6fb7b5 fix: handle Windows backspace in masked input + support custom browser path (#36, #34)
- wizard.ts: also check for \b (0x08) which Windows terminals send for backspace
- browser-tools: read BROWSER_PATH env var and pass as executablePath to Playwright

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 07:47:37 -06:00
Lex Christopherson
71f749c6da 0.3.0 2026-03-11 07:11:40 -06:00
Vedant
93ffe22e47 fix: persist skipped API keys so wizard doesn't repeat on every launch (#27) 2026-03-11 06:59:22 -06:00
jonathancostin
6b2f8b0a05 feat: /worktree (/wt) — git worktree lifecycle for GSD (#31) 2026-03-11 06:59:02 -06:00
jonathancostin
0b1f02219b fix: restore scoped models from settings on new session startup (#22) 2026-03-11 06:57:55 -06:00
Vedant
afa1fffaac fix: startup fallback overwrites user's default model with Sonnet (#29) 2026-03-11 06:57:31 -06:00
jonathancostin
f214912e66 feat: /gsd migrate — .planning to .gsd migration tool (#28) 2026-03-11 06:56:37 -06:00
Lex Christopherson
0ec7a36cd6 0.2.9 2026-03-11 02:42:27 -06:00
TÂCHES
b7e73a1b34 fix: idle recovery skips stuck units instead of silently stalling (#19)
Non-execute-task and execute-task idle recovery now:
- Checks if the artifact already exists before steering (early advance)
- Escalates steering on final attempt ("last chance before skip")
- Writes blocker placeholder artifacts and advances the pipeline when
  retries are exhausted, instead of pausing auto-mode silently

Closes #17

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:33:41 -06:00
TÂCHES
46c112bd37 Merge pull request #15 from alphinus/fix/pkg-version-sync
fix: sync pkg/package.json version with pi-coding-agent to prevent false update banner
2026-03-11 02:19:56 -06:00
alphinus_biosdesk
32156ec036 fix: sync pkg/package.json version with pi-coding-agent to prevent false update banner
pkg/package.json had a hardcoded version (0.1.0) that never got updated.
Since gsd-pi sets PI_PACKAGE_DIR=pkg/, pi's config.js reads VERSION from
pkg/package.json. The update check compares this stale version against npm
registry and always shows 'Update Available' even when the user is already
on the latest release.

Fix:
- Update pkg/package.json to current pi-coding-agent version (0.57.1)
- Add sync-pkg-version.cjs script that reads the installed pi-coding-agent
  version and writes it into pkg/package.json
- Run the sync script in prepublishOnly so the version stays correct on
  every publish
2026-03-11 09:07:17 +01:00
jonathancostin
424f7edf72 fix: treat milestones with summary but no roadmap as complete (#13)
Milestones completed before the roadmap convention (e.g. M001-M003)
have SUMMARY files but no ROADMAP. Previously these were treated as
incomplete, causing the first one to become the active milestone with
a fallback title like 'M001: M001'.

Now getActiveMilestoneId(), the completeMilestoneIds pre-computation,
and the deriveState() registry loop all check for a SUMMARY file when
no roadmap exists and mark the milestone as complete, extracting the
title from the summary H1.
2026-03-11 02:01:18 -06:00
Lex Christopherson
729218e58e chore: bump version to 0.2.8 2026-03-11 01:57:53 -06:00
Lex Christopherson
537c4b8ce8 feat: add mac-tools extension (macOS native automation) 2026-03-11 01:57:53 -06:00
Lex Christopherson
b05fb8df2c chore: bump version to 0.2.7 2026-03-11 01:53:34 -06:00
Lex Christopherson
d1636482d5 chore: bump version to 0.2.6 2026-03-11 01:51:54 -06:00
Lex Christopherson
cce10ffc89 fix: validate default model against full registry on every startup
Uses getAll() instead of getAvailable() so stale models like grok-2
are caught even when the user has no auth for the correct provider yet.
Resets thinking to off when the configured model was invalid.
2026-03-11 01:51:48 -06:00
Lex Christopherson
8d19c2ee5e chore: bump version to 0.2.5 2026-03-11 01:48:13 -06:00
Lex Christopherson
b364e369d5 fix: remove circular self-dependency, default to anthropic/claude-sonnet-4-6 with thinking off
- Remove gsd-pi from its own dependencies (circular dep caused ENOTEMPTY install failures)
- Auto-select anthropic/claude-sonnet-4-6 as default model for new installs
- Reset to valid model if configured model no longer exists in registry
- Default thinking level to off
2026-03-11 01:47:36 -06:00
Lex Christopherson
1c714e09e3 fix: update all .pi/ paths to .gsd/ 2026-03-11 01:36:03 -06:00
Lex Christopherson
67edb120d4 chore: bump version to 0.2.3 2026-03-11 01:34:10 -06:00
Lex Christopherson
3086e5d979 fix(cli): match default model by id.includes('sonnet') — API returns dated IDs not aliases 2026-03-11 01:33:34 -06:00
Lex Christopherson
aafa823319 fix: remove circular gsd-pi self-dependency from package.json 2026-03-11 01:31:54 -06:00
Lex Christopherson
0ce45020af fix: keep selected options lit when notes field is focused
When Tab opens the notes field, committed/checked options now stay
visually prominent (text color + muted description) while unselected
options dim. Previously Tab greyed everything out equally.

- optionUnselected: respect isCommitted when isFocusDimmed
- checkboxUnselected: respect isChecked for description color when isFocusDimmed
2026-03-11 01:31:03 -06:00
Lex Christopherson
647ecbba16 chore: bump version to 0.2.1 2026-03-11 01:30:20 -06:00
Lex Christopherson
838ff01b40 fix(loader): suppress pi SDK version check — irrelevant to gsd users 2026-03-11 01:30:11 -06:00
Lex Christopherson
45ed047140 chore: bump version to 0.2.0 2026-03-11 01:23:11 -06:00
Lex Christopherson
7039a8d653 feat(wizard): branded setup UI with visual hierarchy, descriptions, and status feedback 2026-03-11 01:22:38 -06:00
Lex Christopherson
2645ef7f5d chore: bump version to 0.1.9 2026-03-11 01:16:55 -06:00
Lex Christopherson
60e54f58a5 feat(loader): show branded banner on first launch instead of postinstall 2026-03-11 01:16:40 -06:00
Lex Christopherson
501a004122 chore: bump version to 0.1.8 2026-03-11 01:13:26 -06:00
Lex Christopherson
ab5682177c fix(postinstall): write banner to stderr so npm doesn't suppress it 2026-03-11 01:13:19 -06:00
Lex Christopherson
cf9a41f1ed chore: bump version to 0.1.7 2026-03-11 01:10:19 -06:00
Lex Christopherson
bd3309d31b feat(postinstall): add branded GSD banner with version and next-step hint 2026-03-11 01:10:13 -06:00
Lex Christopherson
dea9fa5a60 chore: bump version to 0.1.6 2026-03-11 01:07:40 -06:00
Lex Christopherson
1421222b27 feat(system-prompt): add skills trigger table for frontend, swiftui, and debug tasks 2026-03-11 01:07:40 -06:00