@entelligentsia/forgecli 0.6.6 → 0.7.7

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.
Files changed (187) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +99 -190
  3. package/dist/bin/forge.js +20 -0
  4. package/dist/bin/forge.js.map +1 -1
  5. package/dist/extensions/forgecli/approve.d.ts +24 -0
  6. package/dist/extensions/forgecli/approve.js +202 -0
  7. package/dist/extensions/forgecli/approve.js.map +1 -0
  8. package/dist/extensions/forgecli/audience-gate.d.ts +4 -0
  9. package/dist/extensions/forgecli/audience-gate.js +8 -5
  10. package/dist/extensions/forgecli/audience-gate.js.map +1 -1
  11. package/dist/extensions/forgecli/collate.d.ts +24 -0
  12. package/dist/extensions/forgecli/collate.js +199 -0
  13. package/dist/extensions/forgecli/collate.js.map +1 -0
  14. package/dist/extensions/forgecli/commit.d.ts +24 -0
  15. package/dist/extensions/forgecli/commit.js +202 -0
  16. package/dist/extensions/forgecli/commit.js.map +1 -0
  17. package/dist/extensions/forgecli/fix-bug.d.ts +75 -0
  18. package/dist/extensions/forgecli/fix-bug.js +1133 -0
  19. package/dist/extensions/forgecli/fix-bug.js.map +1 -0
  20. package/dist/extensions/forgecli/forge-commands.js +7 -0
  21. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  22. package/dist/extensions/forgecli/forge-header.js +10 -4
  23. package/dist/extensions/forgecli/forge-header.js.map +1 -1
  24. package/dist/extensions/forgecli/forge-init.js +16 -8
  25. package/dist/extensions/forgecli/forge-init.js.map +1 -1
  26. package/dist/extensions/forgecli/forge-subagent.d.ts +29 -0
  27. package/dist/extensions/forgecli/forge-subagent.js +14 -1
  28. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  29. package/dist/extensions/forgecli/hook-dispatcher.d.ts +53 -1
  30. package/dist/extensions/forgecli/hook-dispatcher.js +47 -1
  31. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  32. package/dist/extensions/forgecli/hooks/post-init-hook.d.ts +15 -0
  33. package/dist/extensions/forgecli/hooks/post-init-hook.js +127 -0
  34. package/dist/extensions/forgecli/hooks/post-init-hook.js.map +1 -0
  35. package/dist/extensions/forgecli/hooks/post-sprint-hook.d.ts +37 -0
  36. package/dist/extensions/forgecli/hooks/post-sprint-hook.js +166 -0
  37. package/dist/extensions/forgecli/hooks/post-sprint-hook.js.map +1 -0
  38. package/dist/extensions/forgecli/index.js +56 -5
  39. package/dist/extensions/forgecli/index.js.map +1 -1
  40. package/dist/extensions/forgecli/review-code.d.ts +24 -0
  41. package/dist/extensions/forgecli/review-code.js +202 -0
  42. package/dist/extensions/forgecli/review-code.js.map +1 -0
  43. package/dist/extensions/forgecli/review-plan.d.ts +24 -0
  44. package/dist/extensions/forgecli/review-plan.js +203 -0
  45. package/dist/extensions/forgecli/review-plan.js.map +1 -0
  46. package/dist/extensions/forgecli/run-sprint.d.ts +18 -0
  47. package/dist/extensions/forgecli/run-sprint.js +33 -1
  48. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  49. package/dist/extensions/forgecli/run-task.d.ts +21 -2
  50. package/dist/extensions/forgecli/run-task.js +33 -9
  51. package/dist/extensions/forgecli/run-task.js.map +1 -1
  52. package/dist/extensions/forgecli/session-registry.d.ts +10 -0
  53. package/dist/extensions/forgecli/session-registry.js +9 -0
  54. package/dist/extensions/forgecli/session-registry.js.map +1 -1
  55. package/dist/extensions/forgecli/validate.d.ts +24 -0
  56. package/dist/extensions/forgecli/validate.js +202 -0
  57. package/dist/extensions/forgecli/validate.js.map +1 -0
  58. package/dist/extensions/forgecli/wf-engine/engine.d.ts +23 -0
  59. package/dist/extensions/forgecli/wf-engine/engine.js +384 -0
  60. package/dist/extensions/forgecli/wf-engine/engine.js.map +1 -0
  61. package/dist/extensions/forgecli/wf-engine/event-parser.d.ts +6 -0
  62. package/dist/extensions/forgecli/wf-engine/event-parser.js +29 -0
  63. package/dist/extensions/forgecli/wf-engine/event-parser.js.map +1 -0
  64. package/dist/extensions/forgecli/wf-engine/id-gen.d.ts +6 -0
  65. package/dist/extensions/forgecli/wf-engine/id-gen.js +17 -0
  66. package/dist/extensions/forgecli/wf-engine/id-gen.js.map +1 -0
  67. package/dist/extensions/forgecli/wf-engine/loader.d.ts +2 -0
  68. package/dist/extensions/forgecli/wf-engine/loader.js +100 -0
  69. package/dist/extensions/forgecli/wf-engine/loader.js.map +1 -0
  70. package/dist/extensions/forgecli/wf-engine/predicate.d.ts +7 -0
  71. package/dist/extensions/forgecli/wf-engine/predicate.js +36 -0
  72. package/dist/extensions/forgecli/wf-engine/predicate.js.map +1 -0
  73. package/dist/extensions/forgecli/wf-engine/prompt-compiler.d.ts +15 -0
  74. package/dist/extensions/forgecli/wf-engine/prompt-compiler.js +23 -0
  75. package/dist/extensions/forgecli/wf-engine/prompt-compiler.js.map +1 -0
  76. package/dist/extensions/forgecli/wf-engine/register.d.ts +9 -0
  77. package/dist/extensions/forgecli/wf-engine/register.js +59 -0
  78. package/dist/extensions/forgecli/wf-engine/register.js.map +1 -0
  79. package/dist/extensions/forgecli/wf-engine/remit-check.d.ts +6 -0
  80. package/dist/extensions/forgecli/wf-engine/remit-check.js +42 -0
  81. package/dist/extensions/forgecli/wf-engine/remit-check.js.map +1 -0
  82. package/dist/extensions/forgecli/wf-engine/state-store.d.ts +13 -0
  83. package/dist/extensions/forgecli/wf-engine/state-store.js +43 -0
  84. package/dist/extensions/forgecli/wf-engine/state-store.js.map +1 -0
  85. package/dist/extensions/forgecli/wf-engine/types.d.ts +66 -0
  86. package/dist/extensions/forgecli/wf-engine/types.js +2 -0
  87. package/dist/extensions/forgecli/wf-engine/types.js.map +1 -0
  88. package/dist/extensions/forgecli/wf-engine/worker.d.ts +11 -0
  89. package/dist/extensions/forgecli/wf-engine/worker.js +50 -0
  90. package/dist/extensions/forgecli/wf-engine/worker.js.map +1 -0
  91. package/dist/forge-payload/.base-pack/workflows/_fragments/context-injection.md +10 -4
  92. package/dist/forge-payload/.base-pack/workflows/fix_bug.md +12 -0
  93. package/dist/forge-payload/.schemas/bug.schema.json +4 -2
  94. package/dist/forge-payload/.schemas/event.schema.json +22 -3
  95. package/dist/forge-payload/commands/add-pipeline.md +342 -0
  96. package/dist/forge-payload/commands/add-task.md +269 -0
  97. package/dist/forge-payload/commands/ask.md +43 -0
  98. package/dist/forge-payload/commands/calibrate.md +356 -0
  99. package/dist/forge-payload/commands/config.md +202 -0
  100. package/dist/forge-payload/commands/enhance.md +38 -0
  101. package/dist/forge-payload/commands/health.md +225 -0
  102. package/dist/forge-payload/commands/init.md +165 -0
  103. package/dist/forge-payload/commands/materialize.md +119 -0
  104. package/dist/forge-payload/commands/migrate.md +160 -0
  105. package/dist/forge-payload/commands/quiz-agent.md +38 -0
  106. package/dist/forge-payload/commands/regenerate.md +673 -0
  107. package/dist/forge-payload/commands/remove.md +174 -0
  108. package/dist/forge-payload/commands/report-bug.md +191 -0
  109. package/dist/forge-payload/commands/store-query.md +73 -0
  110. package/dist/forge-payload/commands/store-repair.md +187 -0
  111. package/dist/forge-payload/commands/update-tools.md +56 -0
  112. package/dist/forge-payload/commands/update.md +1376 -0
  113. package/dist/forge-payload/tools/preflight-gate.cjs +2 -1
  114. package/dist/forge-payload/tools/read-verdict.cjs +41 -8
  115. package/dist/forge-payload/tools/store-cli.cjs +4 -3
  116. package/node_modules/argparse/CHANGELOG.md +216 -0
  117. package/node_modules/argparse/LICENSE +254 -0
  118. package/node_modules/argparse/README.md +84 -0
  119. package/node_modules/argparse/argparse.js +3707 -0
  120. package/node_modules/argparse/lib/sub.js +67 -0
  121. package/node_modules/argparse/lib/textwrap.js +440 -0
  122. package/node_modules/argparse/package.json +31 -0
  123. package/node_modules/cliui/CHANGELOG.md +121 -0
  124. package/node_modules/color-convert/CHANGELOG.md +54 -0
  125. package/node_modules/esprima/ChangeLog +235 -0
  126. package/node_modules/js-yaml/LICENSE +21 -0
  127. package/node_modules/js-yaml/README.md +247 -0
  128. package/node_modules/js-yaml/bin/js-yaml.js +126 -0
  129. package/node_modules/js-yaml/dist/js-yaml.js +3880 -0
  130. package/node_modules/js-yaml/dist/js-yaml.min.js +2 -0
  131. package/node_modules/js-yaml/dist/js-yaml.mjs +3856 -0
  132. package/node_modules/js-yaml/index.js +47 -0
  133. package/node_modules/js-yaml/lib/common.js +59 -0
  134. package/node_modules/js-yaml/lib/dumper.js +965 -0
  135. package/node_modules/js-yaml/lib/exception.js +55 -0
  136. package/node_modules/js-yaml/lib/loader.js +1733 -0
  137. package/node_modules/js-yaml/lib/schema/core.js +11 -0
  138. package/node_modules/js-yaml/lib/schema/default.js +22 -0
  139. package/node_modules/js-yaml/lib/schema/failsafe.js +17 -0
  140. package/node_modules/js-yaml/lib/schema/json.js +19 -0
  141. package/node_modules/js-yaml/lib/schema.js +121 -0
  142. package/node_modules/js-yaml/lib/snippet.js +101 -0
  143. package/node_modules/js-yaml/lib/type/binary.js +125 -0
  144. package/node_modules/js-yaml/lib/type/bool.js +35 -0
  145. package/node_modules/js-yaml/lib/type/float.js +97 -0
  146. package/node_modules/js-yaml/lib/type/int.js +156 -0
  147. package/node_modules/js-yaml/lib/type/map.js +8 -0
  148. package/node_modules/js-yaml/lib/type/merge.js +12 -0
  149. package/node_modules/js-yaml/lib/type/null.js +35 -0
  150. package/node_modules/js-yaml/lib/type/omap.js +44 -0
  151. package/node_modules/js-yaml/lib/type/pairs.js +53 -0
  152. package/node_modules/js-yaml/lib/type/seq.js +8 -0
  153. package/node_modules/js-yaml/lib/type/set.js +29 -0
  154. package/node_modules/js-yaml/lib/type/str.js +8 -0
  155. package/node_modules/js-yaml/lib/type/timestamp.js +88 -0
  156. package/node_modules/js-yaml/lib/type.js +66 -0
  157. package/node_modules/js-yaml/package.json +66 -0
  158. package/node_modules/mz/HISTORY.md +66 -0
  159. package/node_modules/proper-lockfile/CHANGELOG.md +108 -0
  160. package/node_modules/source-map/CHANGELOG.md +301 -0
  161. package/node_modules/thenify/History.md +11 -0
  162. package/node_modules/thenify-all/History.md +11 -0
  163. package/node_modules/y18n/CHANGELOG.md +100 -0
  164. package/node_modules/yargs/CHANGELOG.md +88 -0
  165. package/node_modules/yargs-parser/CHANGELOG.md +263 -0
  166. package/package.json +6 -2
  167. package/themes/forge-matrix.json +89 -0
  168. package/themes/forge-mono.json +86 -0
  169. package/workflows/lead-qualifier/prompts/digest.md +44 -0
  170. package/workflows/lead-qualifier/prompts/draft-outreach.md +44 -0
  171. package/workflows/lead-qualifier/prompts/enrich.md +52 -0
  172. package/workflows/lead-qualifier/prompts/intake.md +48 -0
  173. package/workflows/lead-qualifier/prompts/mark-cold.md +38 -0
  174. package/workflows/lead-qualifier/prompts/score.md +45 -0
  175. package/workflows/lead-qualifier/workflow.yaml +95 -0
  176. package/workflows/research-brief/prompts/brief-synthesize.md +43 -0
  177. package/workflows/research-brief/prompts/intake.md +51 -0
  178. package/workflows/research-brief/prompts/source-critique.md +38 -0
  179. package/workflows/research-brief/prompts/source-score.md +38 -0
  180. package/workflows/research-brief/prompts/source-summarize.md +54 -0
  181. package/workflows/research-brief/workflow.yaml +66 -0
  182. package/dist/extensions/forgecli/session-monitor-widget.d.ts +0 -37
  183. package/dist/extensions/forgecli/session-monitor-widget.js +0 -320
  184. package/dist/extensions/forgecli/session-monitor-widget.js.map +0 -1
  185. package/dist/extensions/forgecli/session-monitor.d.ts +0 -2
  186. package/dist/extensions/forgecli/session-monitor.js +0 -135
  187. package/dist/extensions/forgecli/session-monitor.js.map +0 -1
@@ -1,4 +1,56 @@
1
- import type { ExtensionAPI } from "@entelligentsia/pi-coding-agent";
1
+ import type { ExtensionAPI, ExtensionCommandContext } from "@entelligentsia/pi-coding-agent";
2
+ /** Payload for the init-complete synthetic event. */
3
+ export interface InitCompleteEvent {
4
+ type: "init-complete";
5
+ /** Project prefix from .forge/config.json project.prefix */
6
+ projectPrefix: string;
7
+ /** Absolute path to the project root (process.cwd() at init time). */
8
+ cwd: string;
9
+ }
10
+ /**
11
+ * Payload for the sprint-collate-complete synthetic event (FORGE-S21-T05).
12
+ *
13
+ * Emitted by run-sprint.ts after the sprint's collate phase completes
14
+ * successfully. Consumed by hooks/post-sprint-hook.ts to trigger
15
+ * /forge:enhance --phase 2.
16
+ *
17
+ * Sprint-ID shape gate: `^[A-Z]+-S\d+$` — bug IDs (FORGE-BUG-015,
18
+ * BUG-031, etc.) are excluded so bug-fix collate runs do NOT trigger
19
+ * sprint-level enhancement. Parity with forge/forge/hooks/post-sprint.cjs
20
+ * trigger regex `\S*-S\d+`.
21
+ */
22
+ export interface SprintCollateCompleteEvent {
23
+ type: "sprint-collate-complete";
24
+ /** Sprint ID — must match ^[A-Z]+-S\d+$ */
25
+ sprintId: string;
26
+ /** Absolute path to the project root (process.cwd() at emit time). */
27
+ cwd: string;
28
+ }
29
+ /** Union of all synthetic event payloads. Extend here as new events are added. */
30
+ export type SyntheticEvent = InitCompleteEvent | SprintCollateCompleteEvent;
31
+ /**
32
+ * Handler signature for synthetic events.
33
+ * ctx is the ExtensionCommandContext of the emitting phase — callers must
34
+ * forward the context object they received from pi at handler invocation time.
35
+ */
36
+ export type SyntheticEventHandler<T extends SyntheticEvent = SyntheticEvent> = (event: T, ctx: ExtensionCommandContext) => void | Promise<void>;
37
+ /**
38
+ * Register a handler for a synthetic event type.
39
+ * Handlers are called in registration order when emitSyntheticEvent fires.
40
+ * Exported for use by hooks/post-init-hook.ts and future hook modules.
41
+ */
42
+ export declare function onSyntheticEvent<T extends SyntheticEvent>(eventType: T["type"], handler: SyntheticEventHandler<T>): void;
43
+ /**
44
+ * Emit a synthetic event, invoking all registered handlers sequentially.
45
+ * Each handler error is caught and logged to stderr (fail-open) — a
46
+ * misbehaving hook MUST NOT block the emitting phase.
47
+ */
48
+ export declare function emitSyntheticEvent(event: SyntheticEvent, ctx: ExtensionCommandContext): Promise<void>;
49
+ /**
50
+ * Reset the synthetic handler registry.
51
+ * Exported for use in unit tests — do NOT call in production code.
52
+ */
53
+ export declare function _resetSyntheticHandlers(): void;
2
54
  /** Parsed representation of a store-cli invocation intercepted from a bash command. */
3
55
  export interface StoreCLICall {
4
56
  /** Subcommand: write or update-status */
@@ -1,10 +1,13 @@
1
- // Pi-runtime hook adapter — FORGE-S18-T02 / FORGE-S18-T03
1
+ // Pi-runtime hook adapter — FORGE-S18-T02 / FORGE-S18-T03 / FORGE-S21-T04
2
2
  //
3
3
  // Wires Forge's hook semantics onto pi's tool_call / tool_result events.
4
4
  // T02: Provides audit-only observation scaffolding.
5
5
  // T03: Adds enforcement — validates store-cli write payloads via store-validator,
6
6
  // checks status transitions via transition-guard, and blocks on violation
7
7
  // by returning { block: true, reason } from the tool_call handler.
8
+ // T04: Adds typed synthetic event taxonomy (InitCompleteEvent) with
9
+ // onSyntheticEvent / emitSyntheticEvent for in-process hook dispatch
10
+ // that bridges deterministic TS handler phases to registered hook handlers.
8
11
  //
9
12
  // Audit logging: set FORGE_HOOK_AUDIT=1 to write to .forge/logs/hooks.log.
10
13
  // In enforcement mode (default): violations are blocked.
@@ -19,6 +22,49 @@ import { isToolCallEventType } from "@entelligentsia/pi-coding-agent";
19
22
  import { checkTwoLayerBoundary } from "./hooks/two-layer-guard.js";
20
23
  import { validateStoreCLIPayload } from "./store-validator.js";
21
24
  import { checkTransition } from "./transition-guard.js";
25
+ // Module-level registry. Pi extension processes are single-session; the
26
+ // registry lives for the lifetime of the process.
27
+ const _syntheticHandlers = new Map();
28
+ /**
29
+ * Register a handler for a synthetic event type.
30
+ * Handlers are called in registration order when emitSyntheticEvent fires.
31
+ * Exported for use by hooks/post-init-hook.ts and future hook modules.
32
+ */
33
+ export function onSyntheticEvent(eventType, handler) {
34
+ const existing = _syntheticHandlers.get(eventType) ?? [];
35
+ existing.push(handler);
36
+ _syntheticHandlers.set(eventType, existing);
37
+ }
38
+ /**
39
+ * Emit a synthetic event, invoking all registered handlers sequentially.
40
+ * Each handler error is caught and logged to stderr (fail-open) — a
41
+ * misbehaving hook MUST NOT block the emitting phase.
42
+ */
43
+ export async function emitSyntheticEvent(event, ctx) {
44
+ const handlers = _syntheticHandlers.get(event.type) ?? [];
45
+ for (const handler of handlers) {
46
+ try {
47
+ await handler(event, ctx);
48
+ }
49
+ catch (err) {
50
+ // Fail-open: log to stderr, never propagate.
51
+ const msg = err instanceof Error ? err.message : String(err);
52
+ try {
53
+ process.stderr.write(`[hook-dispatcher] synthetic event handler error (${event.type}): ${msg}\n`);
54
+ }
55
+ catch {
56
+ // even stderr write failing should not crash the process
57
+ }
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Reset the synthetic handler registry.
63
+ * Exported for use in unit tests — do NOT call in production code.
64
+ */
65
+ export function _resetSyntheticHandlers() {
66
+ _syntheticHandlers.clear();
67
+ }
22
68
  // ── Internal helpers ──────────────────────────────────────────────────────────
23
69
  function auditEnabled() {
24
70
  return process.env.FORGE_HOOK_AUDIT === "1";
@@ -1 +1 @@
1
- {"version":3,"file":"hook-dispatcher.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/hook-dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-dispatcher.js","sourceRoot":"","sources":["../../../src/extensions/forgecli/hook-dispatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ExtensionAPI, ExtensionCommandContext } from "@entelligentsia/pi-coding-agent";
2
+ import { type InitCompleteEvent } from "../hook-dispatcher.js";
3
+ /** Payload for the init-complete synthetic event (alias for test imports). */
4
+ export type InitCompleteEventPayload = InitCompleteEvent;
5
+ /**
6
+ * Create the init-complete handler bound to the given pi ExtensionAPI.
7
+ * Exported for unit testing — production code calls registerPostInitHook.
8
+ */
9
+ export declare function createPostInitHookHandler(pi: ExtensionAPI): (event: InitCompleteEvent, ctx: ExtensionCommandContext) => Promise<void>;
10
+ /**
11
+ * Register the post-init hook handler on the `init-complete` synthetic event.
12
+ * MUST be called BEFORE registerForgeInit in index.ts to prevent the
13
+ * emit-before-consumer race described in SPRINT_REQUIREMENTS.md §Risks row 3.
14
+ */
15
+ export declare function registerPostInitHook(pi: ExtensionAPI): void;
@@ -0,0 +1,127 @@
1
+ // hooks/post-init-hook.ts — Post-init enhancement auto-trigger (FORGE-S21-T04).
2
+ //
3
+ // Fires `/forge:enhance --phase 1 --auto` after each successful `/forge:init`
4
+ // Phase 4 closure. The handler is registered on the synthetic `init-complete`
5
+ // event emitted by forge-init.ts.
6
+ //
7
+ // Plugin parity reference: forge/forge/hooks/post-init.cjs (read-only — do NOT edit).
8
+ //
9
+ // Behaviour:
10
+ // 1. Check idempotency sentinel `.forge/cache/post-init-fired-<prefix>.json`.
11
+ // If present: notify "already fired" and return.
12
+ // 2. Load `.forge/workflows/enhance.md` and run the Pack-06 materialization
13
+ // marker check. If any marker is missing: notify "workflow regression" and
14
+ // return without dispatching (init already succeeded — this is post-init).
15
+ // 3. assertAudience: meta-enhance is orchestrator-only. Because the hook runs
16
+ // from the init orchestrator context, CallerContextStore.get() returns
17
+ // "orchestrator" → check passes. If the check fails (future pi evolution),
18
+ // notify and return without dispatching.
19
+ // 4. Write sentinel BEFORE dispatching (fail-open: if dispatch fails, the
20
+ // sentinel prevents re-fire flooding).
21
+ // 5. sendKickoff "/forge:enhance --phase 1 --auto". If this throws: catch,
22
+ // notify error, do NOT re-throw (init must still report success).
23
+ //
24
+ // Iron Laws:
25
+ // IL1 — code only under forge-cli/src/extensions/forgecli/.
26
+ // IL6 — no shell-string interpolation; no spawn calls.
27
+ // IL7 — every failure path emits ctx.ui.notify and returns; no silent
28
+ // continuation past a gate failure.
29
+ // AC#8 — NO ctx.ui.input/select. NO raw fs.writeFile to .forge/store/.
30
+ import * as fs from "node:fs";
31
+ import * as path from "node:path";
32
+ import { assertAudience } from "../audience-gate.js";
33
+ import { sendKickoff } from "../kickoff.js";
34
+ import { checkMaterialization } from "../enhance.js";
35
+ import { onSyntheticEvent } from "../hook-dispatcher.js";
36
+ import { loadWorkflow, WorkflowLoaderError } from "../loaders/workflow-loader.js";
37
+ // ── Sentinel helpers ──────────────────────────────────────────────────────────
38
+ function sentinelPath(cwd, projectPrefix) {
39
+ return path.join(cwd, ".forge", "cache", `post-init-fired-${projectPrefix}.json`);
40
+ }
41
+ function readSentinel(sentinel) {
42
+ return fs.existsSync(sentinel);
43
+ }
44
+ function writeSentinel(sentinel, projectPrefix) {
45
+ try {
46
+ const dir = path.dirname(sentinel);
47
+ fs.mkdirSync(dir, { recursive: true });
48
+ fs.writeFileSync(sentinel, JSON.stringify({ firedAt: new Date().toISOString(), projectPrefix }, null, 2) + "\n", "utf8");
49
+ }
50
+ catch {
51
+ // Non-fatal: if write fails the sentinel won't prevent re-fire.
52
+ // The worst case is a redundant enhance run — acceptable.
53
+ }
54
+ }
55
+ // ── Handler factory ───────────────────────────────────────────────────────────
56
+ const WORKFLOW_REL_PATH = path.join(".forge", "workflows", "enhance.md");
57
+ /**
58
+ * Create the init-complete handler bound to the given pi ExtensionAPI.
59
+ * Exported for unit testing — production code calls registerPostInitHook.
60
+ */
61
+ export function createPostInitHookHandler(pi) {
62
+ return async function postInitHookHandler(event, ctx) {
63
+ const { projectPrefix, cwd } = event;
64
+ // 1. Idempotency sentinel
65
+ const sentinel = sentinelPath(cwd, projectPrefix);
66
+ if (readSentinel(sentinel)) {
67
+ ctx.ui.notify(`post-init already fired for ${projectPrefix}, skipping`, "info");
68
+ return;
69
+ }
70
+ // 2. Load and marker-check the enhance workflow
71
+ const workflowPath = path.join(cwd, WORKFLOW_REL_PATH);
72
+ let workflowMd;
73
+ let workflowAudience;
74
+ try {
75
+ const loaded = loadWorkflow(workflowPath);
76
+ workflowMd = loaded.rawMarkdown;
77
+ workflowAudience = loaded.audience;
78
+ }
79
+ catch (err) {
80
+ if (err instanceof WorkflowLoaderError && err.code === "missing_file") {
81
+ ctx.ui.notify(`× post-init hook: enhance workflow not found at ${WORKFLOW_REL_PATH}; ` +
82
+ "run /forge:init or /forge:regenerate first. Skipping phase-1 enhance.", "info");
83
+ }
84
+ else {
85
+ const e = err;
86
+ ctx.ui.notify(`× post-init hook: failed to load enhance workflow: ${e.message ?? "unknown"}`, "error");
87
+ }
88
+ return;
89
+ }
90
+ const markerCheck = checkMaterialization(workflowPath, workflowMd);
91
+ if (!markerCheck.ok) {
92
+ for (const marker of markerCheck.missing) {
93
+ ctx.ui.notify(`× workflow regression: ${marker} not found in ${workflowPath}`, "error");
94
+ }
95
+ return;
96
+ }
97
+ // 3. Audience check — meta-enhance is orchestrator-only
98
+ // assertAudience reads CallerContextStore which defaults to "orchestrator"
99
+ // from the init handler context. Wrapped in CallerContextStore.asSubagent
100
+ // is NOT needed here — we ARE the orchestrator calling it, not a subagent.
101
+ if (!assertAudience({ workflowName: "enhance", audience: workflowAudience }, ctx)) {
102
+ // Error notification already emitted by assertAudience.
103
+ return;
104
+ }
105
+ // 4. Write sentinel BEFORE dispatch (fail-open on dispatch error)
106
+ writeSentinel(sentinel, projectPrefix);
107
+ // 5. Dispatch /forge:enhance --phase 1 --auto (best-effort, fail-open)
108
+ try {
109
+ sendKickoff(pi, "/forge:enhance --phase 1 --auto");
110
+ }
111
+ catch (err) {
112
+ const e = err;
113
+ ctx.ui.notify(`× post-init hook: failed to trigger /forge:enhance --phase 1 --auto: ${e.message ?? "unknown"}`, "error");
114
+ // Do NOT re-throw — /forge:init must still report success.
115
+ }
116
+ };
117
+ }
118
+ // ── Registration ──────────────────────────────────────────────────────────────
119
+ /**
120
+ * Register the post-init hook handler on the `init-complete` synthetic event.
121
+ * MUST be called BEFORE registerForgeInit in index.ts to prevent the
122
+ * emit-before-consumer race described in SPRINT_REQUIREMENTS.md §Risks row 3.
123
+ */
124
+ export function registerPostInitHook(pi) {
125
+ onSyntheticEvent("init-complete", createPostInitHookHandler(pi));
126
+ }
127
+ //# sourceMappingURL=post-init-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-init-hook.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/hooks/post-init-hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ExtensionAPI, ExtensionCommandContext } from "@entelligentsia/pi-coding-agent";
2
+ import { type SprintCollateCompleteEvent } from "../hook-dispatcher.js";
3
+ /** Payload for the sprint-collate-complete synthetic event (alias for test imports). */
4
+ export type SprintCollateCompleteEventPayload = SprintCollateCompleteEvent;
5
+ /**
6
+ * Sprint-ID shape gate. Bug IDs like `FORGE-BUG-015` or `BUG-031` do NOT
7
+ * match — they lack the `-S\d+` suffix. Parity with plugin post-sprint.cjs.
8
+ *
9
+ * Pattern requires:
10
+ * - One or more uppercase letters (e.g. FORGE, PROJECT)
11
+ * - Literal `-S`
12
+ * - One or more digits (sprint number)
13
+ *
14
+ * Examples:
15
+ * FORGE-S21 → matches (sprint)
16
+ * PROJECT-S3 → matches (sprint)
17
+ * FORGE-BUG-015 → no match (bug ID)
18
+ * BUG-031 → no match (bug ID — no uppercase prefix before -S)
19
+ * FORGE-BUG-S21 → no match (segment before -S\d+ must be first after prefix)
20
+ *
21
+ * Note: plugin regex `\S*-S\d+` is anchored by the collate.cjs trigger context;
22
+ * in the synthetic event path we have the sprintId directly so we can apply a
23
+ * stricter full-string match.
24
+ */
25
+ export declare const SPRINT_ID_REGEX: RegExp;
26
+ export declare function isSprintId(id: string): boolean;
27
+ /**
28
+ * Create the sprint-collate-complete handler bound to the given pi ExtensionAPI.
29
+ * Exported for unit testing — production code calls registerPostSprintHook.
30
+ */
31
+ export declare function createPostSprintHookHandler(pi: ExtensionAPI): (event: SprintCollateCompleteEvent, ctx: ExtensionCommandContext) => Promise<void>;
32
+ /**
33
+ * Register the post-sprint hook handler on the `sprint-collate-complete`
34
+ * synthetic event. MUST be called BEFORE registerRunSprint in index.ts to
35
+ * prevent the emit-before-consumer race.
36
+ */
37
+ export declare function registerPostSprintHook(pi: ExtensionAPI): void;
@@ -0,0 +1,166 @@
1
+ // hooks/post-sprint-hook.ts — Post-sprint enhancement auto-trigger (FORGE-S21-T05).
2
+ //
3
+ // Fires `/forge:enhance --phase 2` after each successful sprint collate phase.
4
+ // The handler is registered on the synthetic `sprint-collate-complete` event
5
+ // emitted by run-sprint.ts after the sprint's collate completes.
6
+ //
7
+ // Plugin parity reference: forge/forge/hooks/post-sprint.cjs (read-only — do NOT edit).
8
+ //
9
+ // Parity contract:
10
+ // - Filter regex `^[A-Z]+-S\d+$` excludes bug IDs (FORGE-BUG-015, BUG-031, etc.)
11
+ // matching the plugin's trigger regex `\S*-S\d+` which also requires the
12
+ // sprint-ID shape. Bug-fix collate runs must NOT trigger sprint enhancement.
13
+ // - Idempotency sentinel per sprint: `.forge/cache/post-sprint-<id>-enhancement-triggered`
14
+ // (mirrors plugin sentinel naming).
15
+ // - Fail-open: error in any step → ctx.ui.notify, return without throwing.
16
+ //
17
+ // Behaviour:
18
+ // 1. Validate sprint-ID regex gate `^[A-Z]+-S\d+$`. Bug IDs filtered out;
19
+ // handler notifies and returns without dispatching.
20
+ // 2. Check idempotency sentinel `.forge/cache/post-sprint-<id>-enhancement-triggered`.
21
+ // If present: notify "already fired" and return.
22
+ // 3. Load `.forge/workflows/enhance.md` and run the Pack-06 materialization
23
+ // marker check. If any marker is missing: notify "workflow regression" and
24
+ // return without dispatching.
25
+ // 4. assertAudience: meta-enhance is orchestrator-only. Hook runs from the
26
+ // run-sprint orchestrator context → CallerContextStore returns "orchestrator"
27
+ // → check passes.
28
+ // 5. Write sentinel BEFORE dispatching (fail-open: if dispatch fails, the
29
+ // sentinel prevents re-fire flooding).
30
+ // 6. sendKickoff "/forge:enhance --phase 2". If this throws: catch, notify
31
+ // error, do NOT re-throw (sprint must still report success).
32
+ //
33
+ // Iron Laws:
34
+ // IL1 — code only under forge-cli/src/extensions/forgecli/.
35
+ // IL6 — no shell-string interpolation; no spawn calls.
36
+ // IL7 — every failure path emits ctx.ui.notify and returns; no silent
37
+ // continuation past a gate failure.
38
+ // AC#8 — NO ctx.ui.input/select. NO raw fs.writeFile to .forge/store/.
39
+ import * as fs from "node:fs";
40
+ import * as path from "node:path";
41
+ import { assertAudience } from "../audience-gate.js";
42
+ import { sendKickoff } from "../kickoff.js";
43
+ import { checkMaterialization } from "../enhance.js";
44
+ import { onSyntheticEvent } from "../hook-dispatcher.js";
45
+ import { loadWorkflow, WorkflowLoaderError } from "../loaders/workflow-loader.js";
46
+ // ── Sprint-ID regex gate ──────────────────────────────────────────────────────
47
+ /**
48
+ * Sprint-ID shape gate. Bug IDs like `FORGE-BUG-015` or `BUG-031` do NOT
49
+ * match — they lack the `-S\d+` suffix. Parity with plugin post-sprint.cjs.
50
+ *
51
+ * Pattern requires:
52
+ * - One or more uppercase letters (e.g. FORGE, PROJECT)
53
+ * - Literal `-S`
54
+ * - One or more digits (sprint number)
55
+ *
56
+ * Examples:
57
+ * FORGE-S21 → matches (sprint)
58
+ * PROJECT-S3 → matches (sprint)
59
+ * FORGE-BUG-015 → no match (bug ID)
60
+ * BUG-031 → no match (bug ID — no uppercase prefix before -S)
61
+ * FORGE-BUG-S21 → no match (segment before -S\d+ must be first after prefix)
62
+ *
63
+ * Note: plugin regex `\S*-S\d+` is anchored by the collate.cjs trigger context;
64
+ * in the synthetic event path we have the sprintId directly so we can apply a
65
+ * stricter full-string match.
66
+ */
67
+ export const SPRINT_ID_REGEX = /^[A-Z]+-S\d+$/;
68
+ export function isSprintId(id) {
69
+ return SPRINT_ID_REGEX.test(id);
70
+ }
71
+ // ── Sentinel helpers ──────────────────────────────────────────────────────────
72
+ function sentinelPath(cwd, sprintId) {
73
+ return path.join(cwd, ".forge", "cache", `post-sprint-${sprintId}-enhancement-triggered`);
74
+ }
75
+ function readSentinel(sentinel) {
76
+ return fs.existsSync(sentinel);
77
+ }
78
+ function writeSentinel(sentinel, sprintId) {
79
+ try {
80
+ const dir = path.dirname(sentinel);
81
+ fs.mkdirSync(dir, { recursive: true });
82
+ fs.writeFileSync(sentinel, JSON.stringify({ firedAt: new Date().toISOString(), sprintId }, null, 2) + "\n", "utf8");
83
+ }
84
+ catch {
85
+ // Non-fatal: if write fails the sentinel won't prevent re-fire.
86
+ // The worst case is a redundant enhance run — acceptable.
87
+ }
88
+ }
89
+ // ── Handler factory ───────────────────────────────────────────────────────────
90
+ const WORKFLOW_REL_PATH = path.join(".forge", "workflows", "enhance.md");
91
+ /**
92
+ * Create the sprint-collate-complete handler bound to the given pi ExtensionAPI.
93
+ * Exported for unit testing — production code calls registerPostSprintHook.
94
+ */
95
+ export function createPostSprintHookHandler(pi) {
96
+ return async function postSprintHookHandler(event, ctx) {
97
+ const { sprintId, cwd } = event;
98
+ // 1. Sprint-ID regex gate — filter out bug IDs
99
+ if (!isSprintId(sprintId)) {
100
+ ctx.ui.notify(`post-sprint hook: sprintId "${sprintId}" does not match sprint-ID shape ` +
101
+ `(^[A-Z]+-S\\d+$); skipping enhance trigger (bug-fix collate, not sprint collate).`, "info");
102
+ return;
103
+ }
104
+ // 2. Idempotency sentinel
105
+ const sentinel = sentinelPath(cwd, sprintId);
106
+ if (readSentinel(sentinel)) {
107
+ ctx.ui.notify(`post-sprint already fired for ${sprintId}, skipping`, "info");
108
+ return;
109
+ }
110
+ // 3. Load and marker-check the enhance workflow
111
+ const workflowPath = path.join(cwd, WORKFLOW_REL_PATH);
112
+ let workflowMd;
113
+ let workflowAudience;
114
+ try {
115
+ const loaded = loadWorkflow(workflowPath);
116
+ workflowMd = loaded.rawMarkdown;
117
+ workflowAudience = loaded.audience;
118
+ }
119
+ catch (err) {
120
+ if (err instanceof WorkflowLoaderError && err.code === "missing_file") {
121
+ ctx.ui.notify(`× post-sprint hook: enhance workflow not found at ${WORKFLOW_REL_PATH}; ` +
122
+ "run /forge:init or /forge:regenerate first. Skipping phase-2 enhance.", "info");
123
+ }
124
+ else {
125
+ const e = err;
126
+ ctx.ui.notify(`× post-sprint hook: failed to load enhance workflow: ${e.message ?? "unknown"}`, "error");
127
+ }
128
+ return;
129
+ }
130
+ const markerCheck = checkMaterialization(workflowPath, workflowMd);
131
+ if (!markerCheck.ok) {
132
+ for (const marker of markerCheck.missing) {
133
+ ctx.ui.notify(`× workflow regression: ${marker} not found in ${workflowPath}`, "error");
134
+ }
135
+ return;
136
+ }
137
+ // 4. Audience check — meta-enhance is orchestrator-only
138
+ // assertAudience reads CallerContextStore which defaults to "orchestrator"
139
+ // from the run-sprint orchestrator context.
140
+ if (!assertAudience({ workflowName: "enhance", audience: workflowAudience }, ctx)) {
141
+ // Error notification already emitted by assertAudience.
142
+ return;
143
+ }
144
+ // 5. Write sentinel BEFORE dispatch (fail-open on dispatch error)
145
+ writeSentinel(sentinel, sprintId);
146
+ // 6. Dispatch /forge:enhance --phase 2 (best-effort, fail-open)
147
+ try {
148
+ sendKickoff(pi, "/forge:enhance --phase 2");
149
+ }
150
+ catch (err) {
151
+ const e = err;
152
+ ctx.ui.notify(`× post-sprint hook: failed to trigger /forge:enhance --phase 2: ${e.message ?? "unknown"}`, "error");
153
+ // Do NOT re-throw — sprint must still report success.
154
+ }
155
+ };
156
+ }
157
+ // ── Registration ──────────────────────────────────────────────────────────────
158
+ /**
159
+ * Register the post-sprint hook handler on the `sprint-collate-complete`
160
+ * synthetic event. MUST be called BEFORE registerRunSprint in index.ts to
161
+ * prevent the emit-before-consumer race.
162
+ */
163
+ export function registerPostSprintHook(pi) {
164
+ onSyntheticEvent("sprint-collate-complete", createPostSprintHookHandler(pi));
165
+ }
166
+ //# sourceMappingURL=post-sprint-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-sprint-hook.js","sourceRoot":"","sources":["../../../../src/extensions/forgecli/hooks/post-sprint-hook.ts"],"names":[],"mappings":"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"}
@@ -38,8 +38,18 @@ import { registerUsageHook } from "./usage-hook.js";
38
38
  import { registerReadCommand } from "./read-command.js";
39
39
  import { registerRunTask } from "./run-task.js";
40
40
  import { registerRunSprint } from "./run-sprint.js";
41
+ import { registerFixBug } from "./fix-bug.js";
42
+ import { registerReviewPlan } from "./review-plan.js";
43
+ import { registerReviewCode } from "./review-code.js";
44
+ import { registerApprove } from "./approve.js";
45
+ import { registerCommit } from "./commit.js";
46
+ import { registerValidate } from "./validate.js";
47
+ import { registerCollate } from "./collate.js";
41
48
  import { registerTestOrchestrate } from "./test-orchestrate.js";
42
49
  import { registerThreadSwitcher } from "./thread-switcher.js";
50
+ import { registerRunWorkflow } from "./wf-engine/register.js";
51
+ import { registerPostInitHook } from "./hooks/post-init-hook.js";
52
+ import { registerPostSprintHook } from "./hooks/post-sprint-hook.js";
43
53
  // Resolve the vendored prompts directory at module load. After build, this
44
54
  // file lives at <pkg>/dist/extensions/forgecli/index.js — go up three levels
45
55
  // to <pkg>/, then into prompts/. In the source tree (vitest runs raw .ts), the
@@ -94,6 +104,18 @@ export default async function forgecli(pi) {
94
104
  return { systemPrompt: `${orientation}\n${existing}` };
95
105
  });
96
106
  }
107
+ // ── post-init hook (FORGE-S21-T04) ───────────────────────────────────────
108
+ // Registered BEFORE registerForgeInit to prevent emit-before-consumer race.
109
+ // The hook fires after Phase 4 closure via the `init-complete` synthetic
110
+ // event and triggers /forge:enhance --phase 1 --auto with idempotency.
111
+ registerPostInitHook(pi);
112
+ // ── post-sprint hook (FORGE-S21-T05) ─────────────────────────────────────
113
+ // Registered BEFORE registerRunSprint to prevent emit-before-consumer race.
114
+ // The hook fires after sprint collate phase via the `sprint-collate-complete`
115
+ // synthetic event and triggers /forge:enhance --phase 2 with idempotency.
116
+ // Sprint-ID regex gate ^[A-Z]+-S\d+$ prevents bug-fix collate runs from
117
+ // triggering sprint-level enhancement.
118
+ registerPostSprintHook(pi);
97
119
  // ── Unconditional /forge:init (AC#4) ─────────────────────────────────────
98
120
  // Full 4-phase implementation — FORGE-S17-T02.
99
121
  // Banner suppression: outside-Forge banner below only fires when
@@ -113,15 +135,19 @@ export default async function forgecli(pi) {
113
135
  // Spawns an in-process pi AgentSession via runForgeSubagent and delegates
114
136
  // the user-supplied prompt. Multi-turn allowed. Status updates streamed.
115
137
  registerTestOrchestrate(pi);
116
- // ── Ensure forge-dark is in ~/.pi/agent/themes/ (global custom theme dir) ─
138
+ // ── Install bundled themes into ~/.pi/agent/themes/ ──────────────────────
117
139
  // Themes in that directory are loaded by pi BEFORE initTheme() runs, so
118
- // setTheme("forge-dark") will reliably find it by name in session_start.
119
- const forgeDarkSrc = path.join(PKG_ROOT, "themes", "forge-dark.json");
140
+ // pi's /settings > theme picker lists them and setTheme(name) finds them
141
+ // by name in session_start. We ship one or more JSON themes under
142
+ // forge-cli/themes/ and copy each one into the global theme directory.
143
+ const bundledThemesDir = path.join(PKG_ROOT, "themes");
120
144
  const globalThemesDir = path.join(getAgentDir(), "themes");
121
- const forgeDarkDest = path.join(globalThemesDir, "forge-dark.json");
122
145
  try {
123
146
  fs.mkdirSync(globalThemesDir, { recursive: true });
124
- fs.copyFileSync(forgeDarkSrc, forgeDarkDest);
147
+ const themeFiles = fs.readdirSync(bundledThemesDir).filter((f) => f.endsWith(".json"));
148
+ for (const file of themeFiles) {
149
+ fs.copyFileSync(path.join(bundledThemesDir, file), path.join(globalThemesDir, file));
150
+ }
125
151
  }
126
152
  catch {
127
153
  // Non-fatal — theme install skipped, fall back to default
@@ -272,6 +298,31 @@ export default async function forgecli(pi) {
272
298
  // Registered BEFORE registerAllForgeCommands so the real handler takes
273
299
  // precedence over the auto-stub from the command .md.
274
300
  registerRunSprint(pi);
301
+ // ── /forge:fix-bug native Orchestrator handler (FORGE-S21-T07) ────
302
+ // Bug-level orchestrator: chains triage → plan-fix → review-plan →
303
+ // implement → review-code → approve → commit via runForgeSubagent (IL10).
304
+ // Registered BEFORE registerAllForgeCommands so the real handler takes
305
+ // precedence over the auto-stub from the command .md.
306
+ registerFixBug(pi);
307
+ // ── Chain sub-workflow Kickoff Shims (FORGE-S21-T10) ─────────────────────
308
+ // Six native kickoff handlers replacing auto-generated stubs. Each is a
309
+ // Kickoff Shim (Pack-04 + Pack-06): reads the materialized workflow, runs
310
+ // marker checks, assertAudience, then sendKickoff. Standalone invocations
311
+ // of subagent-only workflows (review-plan, review-code, approve, commit,
312
+ // validate) receive audience refusal — this IS the contract.
313
+ // Orchestrator chains (run-task, run-sprint, fix-bug) MUST NOT route
314
+ // through these handlers — they dispatch via runForgeSubagent directly (IL10).
315
+ // Registered BEFORE registerAllForgeCommands so real handlers take precedence.
316
+ registerReviewPlan(pi);
317
+ registerReviewCode(pi);
318
+ registerApprove(pi);
319
+ registerCommit(pi);
320
+ registerValidate(pi);
321
+ registerCollate(pi);
322
+ // ── /forge:run-workflow generic workflow engine (Plan 14) ────────────────
323
+ // Resolution order: CWD/workflows/<id> first (user-authored workflows),
324
+ // then bundled PKG_ROOT/workflows/<id> (shipped examples). Registered unconditionally.
325
+ registerRunWorkflow(pi, { cwd: process.cwd(), bundledWorkflowsDir: path.join(PKG_ROOT, "workflows") });
275
326
  // ── /forge:threads native handler ────────────────────────────────────────
276
327
  // Single-viewport thread switcher: one-row chip strip below the editor.
277
328
  // ↓ from the editor activates it; ←→ navigate, Enter focuses a chip into