@entelligentsia/forgecli 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +138 -0
- package/README.md +177 -38
- package/dist/bin/argv.js +5 -0
- package/dist/bin/argv.js.map +1 -1
- package/dist/bin/forge.js +1 -0
- package/dist/bin/forge.js.map +1 -1
- package/dist/extensions/forgecli/ask-user-tool.d.ts +17 -0
- package/dist/extensions/forgecli/ask-user-tool.js +139 -0
- package/dist/extensions/forgecli/ask-user-tool.js.map +1 -0
- package/dist/extensions/forgecli/forge-commands.d.ts +21 -0
- package/dist/extensions/forgecli/forge-commands.js +141 -0
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-init.d.ts +26 -0
- package/dist/extensions/forgecli/forge-init.js +948 -0
- package/dist/extensions/forgecli/forge-init.js.map +1 -0
- package/dist/extensions/forgecli/health-check.d.ts +18 -0
- package/dist/extensions/forgecli/health-check.js +154 -0
- package/dist/extensions/forgecli/health-check.js.map +1 -0
- package/dist/extensions/forgecli/hook-dispatcher.d.ts +34 -1
- package/dist/extensions/forgecli/hook-dispatcher.js +237 -3
- package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
- package/dist/extensions/forgecli/index.js +28 -11
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/init-context.d.ts +99 -0
- package/dist/extensions/forgecli/init-context.js +163 -0
- package/dist/extensions/forgecli/init-context.js.map +1 -0
- package/dist/extensions/forgecli/init-progress.d.ts +39 -0
- package/dist/extensions/forgecli/init-progress.js +117 -0
- package/dist/extensions/forgecli/init-progress.js.map +1 -0
- package/dist/extensions/forgecli/refresh-kb-links.d.ts +18 -0
- package/dist/extensions/forgecli/refresh-kb-links.js +228 -0
- package/dist/extensions/forgecli/refresh-kb-links.js.map +1 -0
- package/dist/extensions/forgecli/store-validator.d.ts +13 -0
- package/dist/extensions/forgecli/store-validator.js +35 -0
- package/dist/extensions/forgecli/store-validator.js.map +1 -0
- package/dist/extensions/forgecli/transition-guard.d.ts +20 -0
- package/dist/extensions/forgecli/transition-guard.js +125 -0
- package/dist/extensions/forgecli/transition-guard.js.map +1 -0
- package/dist/forge-payload/.base-pack/commands/approve.md +22 -0
- package/dist/forge-payload/.base-pack/commands/collate.md +22 -0
- package/dist/forge-payload/.base-pack/commands/commit.md +22 -0
- package/dist/forge-payload/.base-pack/commands/enhance.md +37 -0
- package/dist/forge-payload/.base-pack/commands/fix-bug.md +22 -0
- package/dist/forge-payload/.base-pack/commands/implement.md +22 -0
- package/dist/forge-payload/.base-pack/commands/plan.md +22 -0
- package/dist/forge-payload/.base-pack/commands/quiz-agent.md +22 -0
- package/dist/forge-payload/.base-pack/commands/retrospective.md +22 -0
- package/dist/forge-payload/.base-pack/commands/review-code.md +22 -0
- package/dist/forge-payload/.base-pack/commands/review-plan.md +22 -0
- package/dist/forge-payload/.base-pack/commands/run-sprint.md +22 -0
- package/dist/forge-payload/.base-pack/commands/run-task.md +22 -0
- package/dist/forge-payload/.base-pack/commands/sprint-intake.md +22 -0
- package/dist/forge-payload/.base-pack/commands/sprint-plan.md +22 -0
- package/dist/forge-payload/.base-pack/commands/validate.md +22 -0
- package/dist/forge-payload/.claude-plugin/plugin.json +15 -0
- package/dist/forge-payload/.init/discovery/discover-database.md +32 -0
- package/dist/forge-payload/.init/discovery/discover-processes.md +31 -0
- package/dist/forge-payload/.init/discovery/discover-routing.md +31 -0
- package/dist/forge-payload/.init/discovery/discover-stack.md +33 -0
- package/dist/forge-payload/.init/discovery/discover-testing.md +34 -0
- package/dist/forge-payload/.init/generation/generate-kb-doc.md +60 -0
- package/dist/forge-payload/.schemas/bug.schema.json +53 -0
- package/dist/forge-payload/.schemas/collation-state.schema.json +16 -0
- package/dist/forge-payload/.schemas/event-sidecar.schema.json +22 -0
- package/dist/forge-payload/.schemas/event.schema.json +32 -0
- package/dist/forge-payload/.schemas/feature.schema.json +22 -0
- package/dist/forge-payload/.schemas/progress-entry.schema.json +16 -0
- package/dist/forge-payload/.schemas/project-context.schema.json +167 -0
- package/dist/forge-payload/.schemas/project-overlay.schema.json +25 -0
- package/dist/forge-payload/.schemas/sprint.schema.json +27 -0
- package/dist/forge-payload/.schemas/structure-versions.schema.json +57 -0
- package/dist/forge-payload/.schemas/task.schema.json +58 -0
- package/dist/forge-payload/.tools/banners.cjs +435 -0
- package/dist/forge-payload/.tools/build-context-pack.cjs +290 -0
- package/dist/forge-payload/.tools/build-init-context.cjs +322 -0
- package/dist/forge-payload/.tools/build-overlay.cjs +326 -0
- package/dist/forge-payload/.tools/build-persona-pack.cjs +226 -0
- package/dist/forge-payload/.tools/collate.cjs +1041 -0
- package/dist/forge-payload/.tools/generation-manifest.cjs +311 -0
- package/dist/forge-payload/.tools/lib/forge-root.cjs +59 -0
- package/dist/forge-payload/.tools/lib/paths.cjs +29 -0
- package/dist/forge-payload/.tools/lib/pricing.cjs +165 -0
- package/dist/forge-payload/.tools/lib/project-root.cjs +32 -0
- package/dist/forge-payload/.tools/lib/result.js +40 -0
- package/dist/forge-payload/.tools/lib/validate.js +131 -0
- package/dist/forge-payload/.tools/manage-config.cjs +340 -0
- package/dist/forge-payload/.tools/manage-versions.cjs +365 -0
- package/dist/forge-payload/.tools/seed-store.cjs +237 -0
- package/dist/forge-payload/.tools/store-cli.cjs +1123 -0
- package/dist/forge-payload/.tools/store.cjs +315 -0
- package/dist/forge-payload/.tools/substitute-placeholders.cjs +625 -0
- package/dist/forge-payload/.tools/validate-store.cjs +522 -0
- package/package.json +1 -1
- /package/dist/forge-payload/{personas → .base-pack/personas}/architect.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/bug-fixer.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/collator.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/engineer.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/librarian.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/orchestrator.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/product-manager.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/qa-engineer.md +0 -0
- /package/dist/forge-payload/{personas → .base-pack/personas}/supervisor.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/architect-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/bug-fixer-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/collator-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/engineer-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/generic-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/librarian-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/qa-engineer-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/store-custodian-skills.md +0 -0
- /package/dist/forge-payload/{skills → .base-pack/skills}/supervisor-skills.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/CODE_REVIEW_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/COST_REPORT_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/PLAN_REVIEW_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/PLAN_SUMMARY_TEMPLATE.json +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/PLAN_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/PROGRESS_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/RETROSPECTIVE_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/SPRINT_MANIFEST_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/SPRINT_REQUIREMENTS_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{templates → .base-pack/templates}/TASK_PROMPT_TEMPLATE.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/_fragments/context-injection.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/_fragments/event-emission-schema.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/_fragments/finalize.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/_fragments/progress-reporting.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/architect_approve.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/architect_review_sprint_completion.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/architect_sprint_intake.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/architect_sprint_plan.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/collator_agent.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/commit_task.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/fix_bug.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/implement_plan.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/migrate_structural.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/orchestrate_task.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/plan_task.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/quiz_agent.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/review_code.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/review_plan.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/run_sprint.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/sprint_retrospective.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/update_implementation.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/update_plan.md +0 -0
- /package/dist/forge-payload/{workflows → .base-pack/workflows}/validate_task.md +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,141 @@ All notable changes to `@entelligentsia/forgecli` are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## [0.3.0] — 2026-05-09
|
|
13
|
+
|
|
14
|
+
Headline: Pi-runtime parity adapters — interactive UX + hook safety net.
|
|
15
|
+
`forge:ask_user` delivers real TUI prompts for all `/forge:init` gate sites;
|
|
16
|
+
the hook safety net enforces store-cli write validity and legal status
|
|
17
|
+
transitions at runtime. Fixes BUG-026 (non-blocking Y/N prompts) and BUG-027
|
|
18
|
+
(unguarded store-cli writes under pi runtime).
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`forge:ask_user` custom tool** (FORGE-S18-T04).
|
|
23
|
+
Registers `forge_ask_user` via `pi.registerTool`. Accepts `{question, type, options?, default?}`
|
|
24
|
+
where `type` is `confirm` (Y/N), `choice` (select from list), or `text` (free-form input).
|
|
25
|
+
Uses `ctx.ui.confirm / select / input` from the pi `ExtensionContext` — no raw pi-tui
|
|
26
|
+
component wiring needed. Blocks the model loop until the user responds. Non-interactive
|
|
27
|
+
bypass: `FORGE_YES=1`, `--non-interactive`, or headless mode returns the default
|
|
28
|
+
immediately. Cancellation surfaces as `isError: true`. 14 Vitest tests.
|
|
29
|
+
|
|
30
|
+
- **`registerHookDispatcher` wired to `tool_call` / `tool_result`** (FORGE-S18-T02).
|
|
31
|
+
Replaces the 7-line empty shim with a real implementation. Subscribes both pi events
|
|
32
|
+
(wired to tool_call/tool_result; enforcement layer added by T03).
|
|
33
|
+
Exports `parseStoreCLIInvocation()` + `StoreCLICall` interface for T03 to layer
|
|
34
|
+
validation on top. Hook inventory document produced at
|
|
35
|
+
`engineering/sprints/FORGE-S18/FORGE-S18-T02/HOOK_INVENTORY.md`.
|
|
36
|
+
|
|
37
|
+
- **Store-cli pushback correction loop + audit-log mode** (FORGE-S18-T03).
|
|
38
|
+
Extends the T02 hook-dispatcher scaffold from audit-only to enforcement.
|
|
39
|
+
`store-validator.ts` spawns `store-cli validate` synchronously on every write call;
|
|
40
|
+
`transition-guard.ts` enforces the legal status-transition table for task/sprint/bug
|
|
41
|
+
records. Returns `{ block: true, reason }` on violation. `FORGE_HOOK_AUDIT=1` logs
|
|
42
|
+
every decision (would-block/would-allow) with timestamp, entity, reason — returns
|
|
43
|
+
`undefined` (allow-through) regardless, enabling observation without disruption.
|
|
44
|
+
Closes FORGE-BUG-027.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- **Gate sites in `/forge:init` now use `forge:ask_user`** (FORGE-S18-T05). G2
|
|
49
|
+
(pre-flight phase selector) and G3 (KB folder prompt) replaced from
|
|
50
|
+
`sendToAgent+waitForIdle` to `ctx.ui.confirm / ctx.ui.input`. Operator receives a
|
|
51
|
+
real TUI prompt instead of model-generated text. Gate audit captured in
|
|
52
|
+
`GATE_AUDIT.md`.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- **BUG-026** — Pi runtime: TUI Y/N prompts in command bodies don't wait for user
|
|
57
|
+
input. Fixed by `forge:ask_user` tool (T04) + gate-site retrofit (T05). `/forge:init`
|
|
58
|
+
gate sites G2 and G3 now use `ctx.ui.confirm/input` and block until the operator
|
|
59
|
+
responds.
|
|
60
|
+
- **BUG-027** — Pi runtime: validation hooks not wired — store-cli writes unguarded,
|
|
61
|
+
no pushback correction loop. Fixed by hook adapter (T02) + enforcement layer (T03).
|
|
62
|
+
`registerHookDispatcher` intercepts `store-cli write` and `store-cli update-status`
|
|
63
|
+
calls, validates against schema and transition table, returns `{ block: true, reason }`
|
|
64
|
+
on violation.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## [0.2.1] — 2026-05-09
|
|
69
|
+
|
|
70
|
+
Headline: Non-interactive mode for CI and scripted use. `FORGE_YES=1` and
|
|
71
|
+
`forge --non-interactive` both bypass every Y/N gate in `/forge:init`, resolving
|
|
72
|
+
each to its documented default. Unblocks scripted adoption immediately (BUG-026
|
|
73
|
+
short-circuit; T04/T05 deliver the real interactive TUI path).
|
|
74
|
+
|
|
75
|
+
### Added
|
|
76
|
+
|
|
77
|
+
- **`--non-interactive` CLI flag** (FORGE-S18-T01). Parsed by `argv.ts`,
|
|
78
|
+
sets `FORGE_NON_INTERACTIVE=1`. Documented in `--help` output.
|
|
79
|
+
- **`FORGE_YES=1` environment variable** (FORGE-S18-T01). Ergonomic shorthand
|
|
80
|
+
for scripts (`FORGE_YES=1 forge`). Checked alongside `FORGE_NON_INTERACTIVE`.
|
|
81
|
+
- **`isNonInteractive()` helper** in `forge-init.ts`. Bypasses G1 (resume
|
|
82
|
+
confirm), G2 (pre-flight phase selector), G3 (KB folder name), G4 (CLAUDE.md
|
|
83
|
+
create confirm) when active.
|
|
84
|
+
- **README non-interactive mode section** — flag, env var, and default-resolution
|
|
85
|
+
table for all four gate sites.
|
|
86
|
+
- **Vitest gate coverage** — 12 new test cases covering each gate under
|
|
87
|
+
interactive, `FORGE_NON_INTERACTIVE=1`, and `FORGE_YES=1` arms.
|
|
88
|
+
- **E2E smoke gates E2E-04/05/06** — auth-free checks that flag and env vars
|
|
89
|
+
are accepted without errors.
|
|
90
|
+
|
|
91
|
+
## [0.2.0] — 2026-05-09
|
|
92
|
+
|
|
93
|
+
Headline: `/forge:init` is now a real implementation. The 0.1.0 stub at
|
|
94
|
+
`src/extensions/forgecli/index.ts:77-82` is replaced with a full-parity port of
|
|
95
|
+
the Claude-Code plugin's `/forge:init` flow. Default payload trimmed by 35.8%
|
|
96
|
+
unpacked. Tarball size-budget gate enforced in smoke + CI.
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
|
|
100
|
+
- **`/forge:init` real implementation** (FORGE-S17-T02). Full parity to the
|
|
101
|
+
plugin: 4-phase flow, `--fast` / `--full` flags, resume detection via
|
|
102
|
+
`.forge/init-progress.json`, hero banner with project-name discovery, idempotent
|
|
103
|
+
re-run. Consumes `dist/forge-payload/`, substitutes placeholders against user
|
|
104
|
+
project context, writes `.forge/{personas,skills,workflows,templates,config.json,project-context.json}`.
|
|
105
|
+
- **Tarball size-budget gate** (FORGE-S17-T05) at
|
|
106
|
+
`test/e2e/lib/tarball-size-gate.sh` (sourceable) plus
|
|
107
|
+
`test/e2e/size-budget.test.sh` (18 boundary assertions). Smoke gate runs after
|
|
108
|
+
`npm pack` with PASS / WARN (>35 MB) / FAIL (>50 MB) status. Thresholds
|
|
109
|
+
env-overridable via `FORGE_TARBALL_SIZE_*`.
|
|
110
|
+
- **`scripts/build-payload.cjs --include-full`** flag and `--help`
|
|
111
|
+
(FORGE-S17-T04). Opt-in to the legacy un-trimmed payload for forensic /
|
|
112
|
+
round-trip verification — round-trip verified byte-exact.
|
|
113
|
+
- **Mid-sprint runtime fixes** (FORGE-BUG-017..025) — `/forge:init` runtime
|
|
114
|
+
defects discovered during init-port adaptation review; pi-aware
|
|
115
|
+
`paths.forgeRoot`; skip Claude-Code-only command output during init.
|
|
116
|
+
|
|
117
|
+
### Changed
|
|
118
|
+
|
|
119
|
+
- **Default payload trimmed by 35.8% unpacked** (FORGE-S17-T03 audit applied
|
|
120
|
+
by FORGE-S17-T04). Files 175 → 105, unpacked 704,388 → 452,445 bytes,
|
|
121
|
+
forge-payload tar.gz 194,067 → 123,505 bytes (−36.4%). Trim sites:
|
|
122
|
+
- top-level `personas/skills/workflows/templates/` removed (Pass 1 vestige,
|
|
123
|
+
never read at runtime),
|
|
124
|
+
- `.tools/lib/` allowlisted to runtime-loaded subset
|
|
125
|
+
(`forge-root, paths, pricing, project-root, result.js, validate.js`),
|
|
126
|
+
- `.init/generation/` reduced to `generate-kb-doc.md`,
|
|
127
|
+
- `.schemas/` reduced to `*.schema.json`.
|
|
128
|
+
- **Full `npm pack` output** (the published artifact, with bundled pi runtime
|
|
129
|
+
as bulk): 30.42 MB compressed, 19.58 MB headroom under the 50 MB hard gate.
|
|
130
|
+
|
|
131
|
+
### Documentation
|
|
132
|
+
|
|
133
|
+
- README updated with size-budget tuning surface and trimmed-payload note.
|
|
134
|
+
|
|
135
|
+
### Bundled / pinned (unchanged from 0.1.0)
|
|
136
|
+
|
|
137
|
+
- `@earendil-works/pi-coding-agent@0.74.0`,
|
|
138
|
+
`@earendil-works/pi-ai@0.74.0`,
|
|
139
|
+
`@earendil-works/pi-tui@0.74.0` via `bundledDependencies`.
|
|
140
|
+
- `forge.bundledVersion: 0.40.3` (`Entelligentsia/forge@v0.40.3`) — drift audit
|
|
141
|
+
clean, no upstream movement during sprint.
|
|
142
|
+
|
|
8
143
|
## [0.1.0] — 2026-05-08
|
|
9
144
|
|
|
10
145
|
First public stable release of `@entelligentsia/forgecli` — the Forge SDLC
|
|
@@ -57,4 +192,7 @@ ported onto `@earendil-works/pi-coding-agent`.
|
|
|
57
192
|
- `claude-agent-sdk` plan-limit support (deferred to S17+).
|
|
58
193
|
- Cost telemetry surfacing in `/forge:*` (waived for S16).
|
|
59
194
|
|
|
195
|
+
[0.3.0]: https://github.com/Entelligentsia/forge-cli/releases/tag/v0.3.0
|
|
196
|
+
[0.2.1]: https://github.com/Entelligentsia/forge-cli/releases/tag/v0.2.1
|
|
197
|
+
[0.2.0]: https://github.com/Entelligentsia/forge-cli/releases/tag/v0.2.0
|
|
60
198
|
[0.1.0]: https://github.com/Entelligentsia/forge-cli/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -1,52 +1,191 @@
|
|
|
1
|
-
|
|
1
|
+
## @entelligentsia/forgecli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Forge SDLC on the [pi-coding-agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) runtime. Three bin aliases: `forge`, `forgecli`, `4ge`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Bundled Forge plugin: **v0.40.3**.
|
|
6
|
+
Bundled pi runtime: pinned in `package.json`.
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
+
## Install
|
|
8
9
|
|
|
10
|
+
```sh
|
|
11
|
+
npm install -g @entelligentsia/forgecli
|
|
9
12
|
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
|
|
14
|
+
Requires Node 20+.
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
cd your-project
|
|
20
|
+
forge # launch interactive session (forge | forgecli | 4ge)
|
|
21
|
+
> /forge:init # bootstrap Forge SDLC — 4 phases, ~45s
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`/forge:init` is idempotent and resumable via `.forge/init-progress.json`. Re-running picks up where the previous run stopped.
|
|
25
|
+
|
|
26
|
+
## What `/forge:init` does
|
|
27
|
+
|
|
28
|
+
1. **Collect** — 5 parallel discovery scans → `.forge/config.json`
|
|
29
|
+
2. **Discover** — KB doc generation + `.forge/project-context.json`
|
|
30
|
+
3. **Materialize** — substitute placeholders → fully functional workflows
|
|
31
|
+
4. **Register** — versioning, manifest, cache, store entries
|
|
32
|
+
|
|
33
|
+
Outputs land in `.forge/{personas,skills,workflows,templates,config.json,project-context.json}` and the configured KB folder (default `engineering/`).
|
|
34
|
+
|
|
35
|
+
## CLI flags
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
forge --version Print version triplet (forgecli, forge, pi)
|
|
39
|
+
forge --help Show forge + pi help
|
|
40
|
+
forge --no-update-check Skip update check
|
|
41
|
+
forge --non-interactive Bypass all Y/N gates with defaults (CI/scripted use)
|
|
42
|
+
forge --registry <path> Override model registry
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Pi flags (`-p`, `--cwd`, `--session`, `--model`, `--tools`, `--thinking`, …) are forwarded verbatim. Run `forge --help` for the full list.
|
|
46
|
+
|
|
47
|
+
## Non-interactive mode
|
|
48
|
+
|
|
49
|
+
For CI, scripts, or any context where the model cannot answer Y/N prompts:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
# Using the flag
|
|
53
|
+
forge --non-interactive
|
|
54
|
+
|
|
55
|
+
# Using the environment variable
|
|
56
|
+
FORGE_YES=1 forge
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Both activate the same bypass. When active, every Y/N gate in `/forge:init` resolves to its documented default:
|
|
60
|
+
|
|
61
|
+
| Gate | Default resolution |
|
|
62
|
+
|------|--------------------|
|
|
63
|
+
| Resume previous init? | No — delete checkpoint, start fresh |
|
|
64
|
+
| Pre-flight phase selector (Phase 1–4 prompt) | Skip prompt — proceed from Phase 1 |
|
|
65
|
+
| Knowledge base folder name | Use default `engineering/` |
|
|
66
|
+
| Create CLAUDE.md? | Yes — create with KB links |
|
|
67
|
+
|
|
68
|
+
## Hook safety net
|
|
69
|
+
|
|
70
|
+
forge-cli intercepts `store-cli write` and `store-cli update-status` bash calls and validates them before they reach the store. This prevents malformed payloads and illegal status transitions from corrupting the project's engineering knowledge base.
|
|
71
|
+
|
|
72
|
+
### Default-on enforcement
|
|
73
|
+
|
|
74
|
+
When enforcement is active (default), the hook dispatcher:
|
|
75
|
+
|
|
76
|
+
1. **Schema validation** — every `store-cli write <entity> '<json>'` invocation is validated against the entity schema. If the payload is invalid, the model receives a structured error via `{ block: true, reason: <error> }` and is expected to self-correct on the next attempt.
|
|
77
|
+
|
|
78
|
+
2. **Transition guard** — every `store-cli update-status <entity> <id> status <value>` invocation is checked against the legal transition table for the entity. Illegal transitions (e.g. `draft → committed`, skipping required intermediate states) are blocked with an explanatory message naming both `from` and `to` states and the legal next states.
|
|
79
|
+
|
|
80
|
+
Both checks are enforced by default. The hooks fire synchronously before the tool executes, so the model sees the error as the tool result and retries with a corrected payload.
|
|
81
|
+
|
|
82
|
+
### `--force` scope
|
|
83
|
+
|
|
84
|
+
When `--force` is present in the `store-cli` argv:
|
|
85
|
+
|
|
86
|
+
- **Transition guard** is bypassed — `--force` is an explicit operator override for status transitions.
|
|
87
|
+
- **Schema validation still runs** — a malformed payload is always invalid regardless of intent.
|
|
88
|
+
|
|
89
|
+
### `FORGE_HOOK_AUDIT=1` — audit-only mode
|
|
90
|
+
|
|
91
|
+
Set `FORGE_HOOK_AUDIT=1` to observe hook decisions without taking action. In audit mode:
|
|
92
|
+
|
|
93
|
+
- Every decision (would-block, would-allow, lookup-failed) is logged to `.forge/logs/hooks.log`.
|
|
94
|
+
- Nothing is blocked — all calls proceed regardless of validation outcome.
|
|
95
|
+
- Useful for calibrating the false-positive rate before enabling enforcement in a new project.
|
|
96
|
+
|
|
97
|
+
Log format (one entry per line):
|
|
98
|
+
|
|
27
99
|
```
|
|
100
|
+
[store-cli-intercept] subcmd=write entity=task payload={"taskId":"..."}
|
|
101
|
+
[store-cli-intercept] decision=would-block reason=missing required field: taskId
|
|
102
|
+
[store-cli-intercept] decision=would-allow
|
|
103
|
+
[store-cli-intercept] decision=lookup-failed entity=task entityId=FORGE-S18-T03
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Interpreting block messages
|
|
107
|
+
|
|
108
|
+
When the model emits a malformed `store-cli` call and the hook blocks it, the tool result will contain:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
block: true
|
|
112
|
+
reason: <error text>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The model should read the `reason` field and self-correct the payload or transition before retrying. Common block reasons:
|
|
28
116
|
|
|
29
|
-
|
|
117
|
+
| Reason pattern | Cause | Fix |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `missing required field: <field>` | Schema validation — required field absent | Add the missing field to the payload |
|
|
120
|
+
| `<from> → <to> is not a legal transition...` | Transition guard — illegal status jump | Use the listed legal next states |
|
|
121
|
+
| `store-cli validate exited with code 1` | Schema validation — malformed JSON or unknown entity | Fix the JSON payload |
|
|
30
122
|
|
|
31
|
-
|
|
32
|
-
- `forge-cli-feasibility.txt` — feasibility study and PoC notes.
|
|
33
|
-
- `.claude/skills/forge-cli-engineer/SKILL.md` — implementer skill (boundary rules, git protocol).
|
|
123
|
+
## Custom tools
|
|
34
124
|
|
|
35
|
-
|
|
125
|
+
### `forge:ask_user` — interactive prompt
|
|
36
126
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| FORGE-S15-T03 | No-op extension entrypoint + `pi -e` smoke load |
|
|
41
|
-
| FORGE-S15-T04–T09 | Spike R1–R6 PoCs |
|
|
42
|
-
| FORGE-S15-T10 | Stage 2 gate |
|
|
127
|
+
The `forge_ask_user` custom tool allows Forge workflows to request user input
|
|
128
|
+
during model execution. It presents the appropriate TUI prompt and blocks the
|
|
129
|
+
model loop until the user responds.
|
|
43
130
|
|
|
44
|
-
|
|
131
|
+
**Schema:**
|
|
45
132
|
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
133
|
+
```typescript
|
|
134
|
+
{
|
|
135
|
+
question: string; // The prompt shown to the user
|
|
136
|
+
type: "confirm" // Y/N boolean confirmation
|
|
137
|
+
| "choice" // Select from a list
|
|
138
|
+
| "text"; // Free-form single-line input
|
|
139
|
+
options?: string[]; // Required when type === "choice"
|
|
140
|
+
default?: string; // Returned in non-interactive mode
|
|
141
|
+
}
|
|
50
142
|
```
|
|
51
143
|
|
|
52
|
-
|
|
144
|
+
**Returns:** A string — `"Y"` or `"N"` for `confirm`, the selected option for
|
|
145
|
+
`choice`, or the entered text for `text`. On cancellation (user dismisses the
|
|
146
|
+
dialog), the tool returns `isError: true` with a structured message.
|
|
147
|
+
|
|
148
|
+
**Examples:**
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
// Confirm
|
|
152
|
+
forge_ask_user({ question: "Overwrite existing files?", type: "confirm" })
|
|
153
|
+
// → "Y" or "N"
|
|
154
|
+
|
|
155
|
+
// Choice
|
|
156
|
+
forge_ask_user({
|
|
157
|
+
question: "Select environment:",
|
|
158
|
+
type: "choice",
|
|
159
|
+
options: ["development", "staging", "production"]
|
|
160
|
+
})
|
|
161
|
+
// → "development" | "staging" | "production"
|
|
162
|
+
|
|
163
|
+
// Text
|
|
164
|
+
forge_ask_user({ question: "Enter project name:", type: "text", default: "myproject" })
|
|
165
|
+
// → user-entered string (or "myproject" in non-interactive mode)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Non-interactive behaviour:** When `FORGE_YES=1`, `--non-interactive` is set,
|
|
169
|
+
or pi is running in headless/RPC mode, the tool returns the `default` immediately
|
|
170
|
+
without rendering any TUI. Fallback defaults when no explicit `default` is
|
|
171
|
+
provided: `confirm` → `"Y"`, `choice` → `options[0]`, `text` → `""`.
|
|
172
|
+
|
|
173
|
+
## Roadmap
|
|
174
|
+
|
|
175
|
+
| Command | Status |
|
|
176
|
+
|---------------------------|---------------------|
|
|
177
|
+
| `/forge:init` | Shipped (0.3.0) |
|
|
178
|
+
| Other `/forge:*` commands | Roadmap |
|
|
179
|
+
|
|
180
|
+
Track via [issues](https://github.com/Entelligentsia/forge-cli/issues).
|
|
181
|
+
|
|
182
|
+
## Links
|
|
183
|
+
|
|
184
|
+
- Source: <https://github.com/Entelligentsia/forge-cli>
|
|
185
|
+
- Issues: <https://github.com/Entelligentsia/forge-cli/issues>
|
|
186
|
+
- Forge plugin (Claude Code): <https://github.com/Entelligentsia/forge>
|
|
187
|
+
- Changelog: [CHANGELOG.md](./CHANGELOG.md)
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT — see [LICENSE](./LICENSE).
|
package/dist/bin/argv.js
CHANGED
|
@@ -71,6 +71,11 @@ export function parseForgeArgv(argv) {
|
|
|
71
71
|
i++;
|
|
72
72
|
continue;
|
|
73
73
|
}
|
|
74
|
+
if (token === "--non-interactive") {
|
|
75
|
+
env.FORGE_NON_INTERACTIVE = "1";
|
|
76
|
+
i++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
74
79
|
if (token === "--registry") {
|
|
75
80
|
if (i + 1 >= argv.length) {
|
|
76
81
|
return { error: "forge: --registry requires a path argument. Run `forge --help` for usage." };
|
package/dist/bin/argv.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/bin/argv.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/bin/argv.ts"],"names":[],"mappings":"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"}
|
package/dist/bin/forge.js
CHANGED
|
@@ -56,6 +56,7 @@ Forge-owned options:
|
|
|
56
56
|
--version Print version triplet and exit
|
|
57
57
|
--help, -h Print this help message
|
|
58
58
|
--no-update-check Skip forge update check (sets FORGE_NO_UPDATE_CHECK=1)
|
|
59
|
+
--non-interactive Bypass all Y/N gates with defaults, e.g. for CI (sets FORGE_NON_INTERACTIVE=1)
|
|
59
60
|
--registry <path> Override model registry path (sets FORGE_MODEL_REGISTRY=path)
|
|
60
61
|
|
|
61
62
|
Pi options (forwarded verbatim):
|
package/dist/bin/forge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forge.js","sourceRoot":"","sources":["../../src/bin/forge.ts"],"names":[],"mappings":";AAEA,+CAA+C;AAC/C,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAE/E,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AACvD,OAAO,QAAQ,MAAM,iCAAiC,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEzD,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAE9E,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAS3C,SAAS,eAAe;IACvB,IAAI,CAAC;QACJ,0DAA0D;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;AACF,CAAC;AAED,KAAK,UAAU,aAAa;IAC3B,IAAI,CAAC;QACJ,iFAAiF;QACjF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QACpD,OAAO,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,KAAK,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;IACjD,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,EAAE,cAAc,IAAI,SAAS,CAAC;IAC9D,MAAM,SAAS,GAAG,MAAM,aAAa,EAAE,CAAC;IACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,4BAA4B,eAAe,kBAAkB,cAAc,QAAQ,SAAS,KAAK,CACjG,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB
|
|
1
|
+
{"version":3,"file":"forge.js","sourceRoot":"","sources":["../../src/bin/forge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
export declare const AskUserParams: Type.TObject<{
|
|
4
|
+
question: Type.TString;
|
|
5
|
+
type: Type.TUnion<[Type.TLiteral<"confirm">, Type.TLiteral<"choice">, Type.TLiteral<"text">]>;
|
|
6
|
+
options: Type.TOptional<Type.TArray<Type.TString>>;
|
|
7
|
+
default: Type.TOptional<Type.TString>;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Register the forge_ask_user tool with the pi ExtensionAPI.
|
|
11
|
+
*
|
|
12
|
+
* The tool is named `forge_ask_user` (snake_case per pi convention); the
|
|
13
|
+
* human/LLM-facing name `forge:ask_user` appears in description and promptSnippet.
|
|
14
|
+
*
|
|
15
|
+
* @param pi The pi ExtensionAPI instance.
|
|
16
|
+
*/
|
|
17
|
+
export declare function registerAskUserTool(pi: ExtensionAPI): void;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// forge:ask_user custom tool — FORGE-S18-T04
|
|
2
|
+
//
|
|
3
|
+
// Registers forge_ask_user via pi.registerTool. The tool accepts a question and
|
|
4
|
+
// an input type (confirm | choice | text), presents the appropriate TUI prompt
|
|
5
|
+
// via ctx.ui.confirm / ctx.ui.select / ctx.ui.input, and returns the user's
|
|
6
|
+
// answer as a string.
|
|
7
|
+
//
|
|
8
|
+
// Non-interactive bypass:
|
|
9
|
+
// When FORGE_YES=1 or FORGE_NON_INTERACTIVE=1 (set by `forge --non-interactive`),
|
|
10
|
+
// or when ctx.hasUI is false (headless / RPC mode), the tool returns the supplied
|
|
11
|
+
// default without rendering any TUI. Fallback defaults when no explicit default:
|
|
12
|
+
// confirm → "Y"
|
|
13
|
+
// choice → options[0] (or "" if empty)
|
|
14
|
+
// text → ""
|
|
15
|
+
//
|
|
16
|
+
// Cancellation:
|
|
17
|
+
// ctx.ui.* returns undefined when the user cancels. The tool surfaces this as
|
|
18
|
+
// isError: true with a structured message — never silently defaults.
|
|
19
|
+
//
|
|
20
|
+
// Iron Law 6 compliance: no shell-string interpolation. No subprocess spawning.
|
|
21
|
+
import { Type } from "typebox";
|
|
22
|
+
// ── Schema ────────────────────────────────────────────────────────────────────
|
|
23
|
+
export const AskUserParams = Type.Object({
|
|
24
|
+
question: Type.String({
|
|
25
|
+
description: "The question or prompt to display to the user.",
|
|
26
|
+
}),
|
|
27
|
+
type: Type.Union([Type.Literal("confirm"), Type.Literal("choice"), Type.Literal("text")], {
|
|
28
|
+
description: "Input modality: confirm (Y/N boolean), choice (select from list), or text (free-form single-line input).",
|
|
29
|
+
}),
|
|
30
|
+
options: Type.Optional(Type.Array(Type.String(), {
|
|
31
|
+
description: "Required when type === 'choice'. The list of options to present to the user.",
|
|
32
|
+
})),
|
|
33
|
+
default: Type.Optional(Type.String({
|
|
34
|
+
description: "Default value returned in non-interactive mode or when no default is needed. " +
|
|
35
|
+
"If absent, the fallback is: confirm → 'Y', choice → options[0], text → ''.",
|
|
36
|
+
})),
|
|
37
|
+
});
|
|
38
|
+
// ── Non-interactive helper ────────────────────────────────────────────────────
|
|
39
|
+
/**
|
|
40
|
+
* Returns true when running in non-interactive / CI mode.
|
|
41
|
+
*
|
|
42
|
+
* Inlined here (not imported from forge-init.ts) to keep the module boundary
|
|
43
|
+
* clean and avoid any risk of circular imports.
|
|
44
|
+
*
|
|
45
|
+
* Activated by:
|
|
46
|
+
* - `FORGE_YES=1` — ergonomic shell shorthand (FORGE-S18-T01)
|
|
47
|
+
* - `FORGE_NON_INTERACTIVE=1` — set by `forge --non-interactive` flag
|
|
48
|
+
*/
|
|
49
|
+
function isNonInteractive() {
|
|
50
|
+
return process.env.FORGE_YES === "1" || process.env.FORGE_NON_INTERACTIVE === "1";
|
|
51
|
+
}
|
|
52
|
+
// ── Result helpers ────────────────────────────────────────────────────────────
|
|
53
|
+
function okResult(text) {
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: "text", text: text || "" }],
|
|
56
|
+
details: {},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function errResult(text) {
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: "text", text }],
|
|
62
|
+
details: {},
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// ── Fallback computation ──────────────────────────────────────────────────────
|
|
67
|
+
/**
|
|
68
|
+
* Compute the non-interactive fallback value.
|
|
69
|
+
*
|
|
70
|
+
* Priority: explicit `default` field → type-specific hardcoded fallback.
|
|
71
|
+
*/
|
|
72
|
+
function computeFallback(params) {
|
|
73
|
+
if (params.default !== undefined)
|
|
74
|
+
return params.default;
|
|
75
|
+
if (params.type === "confirm")
|
|
76
|
+
return "Y";
|
|
77
|
+
if (params.type === "choice")
|
|
78
|
+
return params.options?.[0] ?? "";
|
|
79
|
+
return ""; // text
|
|
80
|
+
}
|
|
81
|
+
// ── Public registration ───────────────────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* Register the forge_ask_user tool with the pi ExtensionAPI.
|
|
84
|
+
*
|
|
85
|
+
* The tool is named `forge_ask_user` (snake_case per pi convention); the
|
|
86
|
+
* human/LLM-facing name `forge:ask_user` appears in description and promptSnippet.
|
|
87
|
+
*
|
|
88
|
+
* @param pi The pi ExtensionAPI instance.
|
|
89
|
+
*/
|
|
90
|
+
export function registerAskUserTool(pi) {
|
|
91
|
+
pi.registerTool({
|
|
92
|
+
name: "forge_ask_user",
|
|
93
|
+
label: "Forge Ask User",
|
|
94
|
+
description: "forge:ask_user — Present an interactive prompt to the user and return their answer. " +
|
|
95
|
+
"Accepts three input types: 'confirm' (Y/N), 'choice' (select from a list), or 'text' " +
|
|
96
|
+
"(free-form single-line input). Blocks the model loop until the user responds. " +
|
|
97
|
+
"In non-interactive mode (FORGE_YES=1 or --non-interactive), returns the default immediately.",
|
|
98
|
+
promptSnippet: "Use forge_ask_user when a Forge workflow needs synchronous user input — confirm (Y/N), choice from a list, or free-form text.",
|
|
99
|
+
parameters: AskUserParams,
|
|
100
|
+
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
101
|
+
// Non-interactive bypass: applies when env flag is set OR when running
|
|
102
|
+
// headless (ctx.hasUI=false, e.g. RPC mode / print mode).
|
|
103
|
+
if (isNonInteractive() || !ctx.hasUI) {
|
|
104
|
+
const fallback = computeFallback(params);
|
|
105
|
+
// Emit a one-line audit entry to stderr (not a file) so CI logs capture it.
|
|
106
|
+
process.stderr.write(`[forge:ask_user] non-interactive fallback — type=${params.type} question="${params.question}" default="${fallback}"\n`);
|
|
107
|
+
return okResult(fallback);
|
|
108
|
+
}
|
|
109
|
+
const opts = signal !== undefined ? { signal } : {};
|
|
110
|
+
if (params.type === "confirm") {
|
|
111
|
+
// ctx.ui.confirm returns true/false or undefined (cancel).
|
|
112
|
+
const answer = await ctx.ui.confirm("forge:ask_user", params.question, opts);
|
|
113
|
+
if (answer === undefined) {
|
|
114
|
+
return errResult(`forge:ask_user cancelled — user dismissed the prompt. question: "${params.question}"`);
|
|
115
|
+
}
|
|
116
|
+
return okResult(answer ? "Y" : "N");
|
|
117
|
+
}
|
|
118
|
+
if (params.type === "choice") {
|
|
119
|
+
if (!params.options || params.options.length === 0) {
|
|
120
|
+
return errResult("forge:ask_user error — type 'choice' requires a non-empty 'options' array.");
|
|
121
|
+
}
|
|
122
|
+
// ctx.ui.select returns the selected string or undefined (cancel).
|
|
123
|
+
const answer = await ctx.ui.select("forge:ask_user", params.options, opts);
|
|
124
|
+
if (answer === undefined) {
|
|
125
|
+
return errResult(`forge:ask_user cancelled — user dismissed the prompt. question: "${params.question}"`);
|
|
126
|
+
}
|
|
127
|
+
return okResult(answer);
|
|
128
|
+
}
|
|
129
|
+
// type === "text"
|
|
130
|
+
// ctx.ui.input returns the entered string or undefined (cancel/ESC).
|
|
131
|
+
const answer = await ctx.ui.input("forge:ask_user", params.question, opts);
|
|
132
|
+
if (answer === undefined) {
|
|
133
|
+
return errResult(`forge:ask_user cancelled — user dismissed the prompt. question: "${params.question}"`);
|
|
134
|
+
}
|
|
135
|
+
return okResult(answer);
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=ask-user-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-user-tool.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/ask-user-tool.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,sBAAsB;AACtB,EAAE;AACF,0BAA0B;AAC1B,oFAAoF;AACpF,oFAAoF;AACpF,mFAAmF;AACnF,qBAAqB;AACrB,6CAA6C;AAC7C,oBAAoB;AACpB,EAAE;AACF,gBAAgB;AAChB,gFAAgF;AAChF,uEAAuE;AACvE,EAAE;AACF,gFAAgF;AAGhF,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,iFAAiF;AAEjF,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;QACrB,WAAW,EAAE,gDAAgD;KAC7D,CAAC;IACF,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;QACzF,WAAW,EACV,0GAA0G;KAC3G,CAAC;IACF,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE;QACzB,WAAW,EAAE,8EAA8E;KAC3F,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EACV,+EAA+E;YAC/E,4EAA4E;KAC7E,CAAC,CACF;CACD,CAAC,CAAC;AAEH,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,SAAS,gBAAgB;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,CAAC;AACnF,CAAC;AAED,iFAAiF;AAEjF,SAAS,QAAQ,CAAC,IAAY;IAC7B,OAAO;QACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;QACtD,OAAO,EAAE,EAAa;KACtB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC9B,OAAO;QACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,EAAa;QACtB,OAAO,EAAE,IAAa;KACtB,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF;;;;GAIG;AACH,SAAS,eAAe,CAAC,MAIxB;IACA,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAC1C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/D,OAAO,EAAE,CAAC,CAAC,OAAO;AACnB,CAAC;AAED,iFAAiF;AAEjF;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAgB;IACnD,EAAE,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACV,sFAAsF;YACtF,uFAAuF;YACvF,gFAAgF;YAChF,8FAA8F;QAC/F,aAAa,EACZ,+HAA+H;QAChI,UAAU,EAAE,aAAa;QACzB,KAAK,CAAC,OAAO,CACZ,WAAmB,EACnB,MAAuG,EACvG,MAA+B,EAC/B,SAAkB,EAClB,GAAqB;YAErB,uEAAuE;YACvE,0DAA0D;YAC1D,IAAI,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACzC,4EAA4E;gBAC5E,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,oDAAoD,MAAM,CAAC,IAAI,cAAc,MAAM,CAAC,QAAQ,cAAc,QAAQ,KAAK,CACvH,CAAC;gBACF,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC3B,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAEpD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC7E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1B,OAAO,SAAS,CAAC,oEAAoE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAC1G,CAAC;gBACD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACrC,CAAC;YAED,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACpD,OAAO,SAAS,CAAC,4EAA4E,CAAC,CAAC;gBAChG,CAAC;gBACD,mEAAmE;gBACnE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC3E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1B,OAAO,SAAS,CAAC,oEAAoE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAC1G,CAAC;gBACD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAED,kBAAkB;YAClB,qEAAqE;YACrE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAC3E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,SAAS,CAAC,oEAAoE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;YAC1G,CAAC;YACD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -7,8 +7,29 @@ interface RegisterOptions {
|
|
|
7
7
|
}
|
|
8
8
|
declare function resetTomoshibiState(): void;
|
|
9
9
|
export declare function registerForgeCommands(pi: ExtensionAPI, options: RegisterOptions): void;
|
|
10
|
+
/** Parse YAML frontmatter from a markdown file. Returns name and description or null. */
|
|
11
|
+
declare function parseFrontmatter(content: string): {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
} | null;
|
|
15
|
+
export interface RegisterAllOptions {
|
|
16
|
+
/** Absolute path to dist/forge-payload/ (containing .base-pack/commands/). */
|
|
17
|
+
bundlePayloadRoot: string;
|
|
18
|
+
/** Current working directory (for health check). */
|
|
19
|
+
cwd?: string;
|
|
20
|
+
/** Absolute path to dist/forge-payload/ for health check bundle root. */
|
|
21
|
+
bundleRoot?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Register all forge commands from the bundled .base-pack/commands/ directory.
|
|
25
|
+
* Commands already registered (real handlers) are skipped.
|
|
26
|
+
* Returns the number of commands registered.
|
|
27
|
+
*/
|
|
28
|
+
export declare function registerAllForgeCommands(pi: ExtensionAPI, options: RegisterAllOptions): number;
|
|
10
29
|
export declare const __test__: {
|
|
11
30
|
resetTomoshibiState: typeof resetTomoshibiState;
|
|
12
31
|
getTomoshibiPending: () => boolean;
|
|
32
|
+
parseFrontmatter: typeof parseFrontmatter;
|
|
33
|
+
REAL_HANDLERS: Set<string>;
|
|
13
34
|
};
|
|
14
35
|
export {};
|