@nac3/forge-cli 1.18.0 → 1.19.1

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 (181) hide show
  1. package/dist/bin/yf.d.ts.map +1 -1
  2. package/dist/bin/yf.js +4 -0
  3. package/dist/bin/yf.js.map +1 -1
  4. package/dist/chat/doctrine_digest.d.ts.map +1 -1
  5. package/dist/chat/doctrine_digest.js +11 -0
  6. package/dist/chat/doctrine_digest.js.map +1 -1
  7. package/dist/chat/panel.d.ts.map +1 -1
  8. package/dist/chat/panel.js +287 -2
  9. package/dist/chat/panel.js.map +1 -1
  10. package/dist/chat/project_slug.d.ts.map +1 -1
  11. package/dist/chat/project_slug.js +29 -0
  12. package/dist/chat/project_slug.js.map +1 -1
  13. package/dist/chat/server.d.ts.map +1 -1
  14. package/dist/chat/server.js +144 -22
  15. package/dist/chat/server.js.map +1 -1
  16. package/dist/chat/tools/evidence.d.ts +30 -0
  17. package/dist/chat/tools/evidence.d.ts.map +1 -0
  18. package/dist/chat/tools/evidence.js +74 -0
  19. package/dist/chat/tools/evidence.js.map +1 -0
  20. package/dist/chat/tools/pending.d.ts +3 -0
  21. package/dist/chat/tools/pending.d.ts.map +1 -1
  22. package/dist/chat/tools/pending.js +71 -1
  23. package/dist/chat/tools/pending.js.map +1 -1
  24. package/dist/chat/tools/urazuke.d.ts +22 -0
  25. package/dist/chat/tools/urazuke.d.ts.map +1 -0
  26. package/dist/chat/tools/urazuke.js +54 -0
  27. package/dist/chat/tools/urazuke.js.map +1 -0
  28. package/dist/chat/tools/workflow.d.ts.map +1 -1
  29. package/dist/chat/tools/workflow.js +5 -3
  30. package/dist/chat/tools/workflow.js.map +1 -1
  31. package/dist/chat/tools.d.ts.map +1 -1
  32. package/dist/chat/tools.js +22 -0
  33. package/dist/chat/tools.js.map +1 -1
  34. package/dist/chat/urazuke_section.d.ts +8 -0
  35. package/dist/chat/urazuke_section.d.ts.map +1 -0
  36. package/dist/chat/urazuke_section.js +42 -0
  37. package/dist/chat/urazuke_section.js.map +1 -0
  38. package/dist/commands/pending.d.ts +1 -0
  39. package/dist/commands/pending.d.ts.map +1 -1
  40. package/dist/commands/pending.js +82 -8
  41. package/dist/commands/pending.js.map +1 -1
  42. package/dist/commands/start.d.ts +60 -0
  43. package/dist/commands/start.d.ts.map +1 -0
  44. package/dist/commands/start.js +265 -0
  45. package/dist/commands/start.js.map +1 -0
  46. package/dist/commands/urazuke.d.ts +17 -0
  47. package/dist/commands/urazuke.d.ts.map +1 -0
  48. package/dist/commands/urazuke.js +541 -0
  49. package/dist/commands/urazuke.js.map +1 -0
  50. package/dist/commands/workflow.js +4 -4
  51. package/dist/commands/workflow.js.map +1 -1
  52. package/dist/core/brain_config.d.ts +4 -0
  53. package/dist/core/brain_config.d.ts.map +1 -1
  54. package/dist/core/brain_config.js +2 -0
  55. package/dist/core/brain_config.js.map +1 -1
  56. package/dist/core/forge_embed.d.ts.map +1 -1
  57. package/dist/core/forge_embed.js +10 -0
  58. package/dist/core/forge_embed.js.map +1 -1
  59. package/dist/core/native_dialogs.d.ts +13 -0
  60. package/dist/core/native_dialogs.d.ts.map +1 -0
  61. package/dist/core/native_dialogs.js +111 -0
  62. package/dist/core/native_dialogs.js.map +1 -0
  63. package/dist/core/projects.d.ts +6 -0
  64. package/dist/core/projects.d.ts.map +1 -1
  65. package/dist/core/projects.js +1 -1
  66. package/dist/core/projects.js.map +1 -1
  67. package/dist/docs/doctrine/urazuke.md +38 -0
  68. package/dist/nac3/internal_manifest.d.ts.map +1 -1
  69. package/dist/nac3/internal_manifest.js +96 -2
  70. package/dist/nac3/internal_manifest.js.map +1 -1
  71. package/dist/pending/store.d.ts +8 -1
  72. package/dist/pending/store.d.ts.map +1 -1
  73. package/dist/pending/store.js +8 -1
  74. package/dist/pending/store.js.map +1 -1
  75. package/dist/pending/types.d.ts +41 -1
  76. package/dist/pending/types.d.ts.map +1 -1
  77. package/dist/pending/types.js.map +1 -1
  78. package/dist/urazuke/catalog.d.ts +109 -0
  79. package/dist/urazuke/catalog.d.ts.map +1 -0
  80. package/dist/urazuke/catalog.js +459 -0
  81. package/dist/urazuke/catalog.js.map +1 -0
  82. package/dist/urazuke/close_gate.d.ts +36 -0
  83. package/dist/urazuke/close_gate.d.ts.map +1 -0
  84. package/dist/urazuke/close_gate.js +48 -0
  85. package/dist/urazuke/close_gate.js.map +1 -0
  86. package/dist/urazuke/current.d.ts +63 -0
  87. package/dist/urazuke/current.d.ts.map +1 -0
  88. package/dist/urazuke/current.js +133 -0
  89. package/dist/urazuke/current.js.map +1 -0
  90. package/dist/urazuke/cycle.d.ts +91 -0
  91. package/dist/urazuke/cycle.d.ts.map +1 -0
  92. package/dist/urazuke/cycle.js +310 -0
  93. package/dist/urazuke/cycle.js.map +1 -0
  94. package/dist/urazuke/enabled.d.ts +31 -0
  95. package/dist/urazuke/enabled.d.ts.map +1 -0
  96. package/dist/urazuke/enabled.js +51 -0
  97. package/dist/urazuke/enabled.js.map +1 -0
  98. package/dist/urazuke/evidence.d.ts +45 -0
  99. package/dist/urazuke/evidence.d.ts.map +1 -0
  100. package/dist/urazuke/evidence.js +264 -0
  101. package/dist/urazuke/evidence.js.map +1 -0
  102. package/dist/urazuke/gate.d.ts +68 -0
  103. package/dist/urazuke/gate.d.ts.map +1 -0
  104. package/dist/urazuke/gate.js +249 -0
  105. package/dist/urazuke/gate.js.map +1 -0
  106. package/dist/urazuke/probes.d.ts +13 -0
  107. package/dist/urazuke/probes.d.ts.map +1 -0
  108. package/dist/urazuke/probes.js +87 -0
  109. package/dist/urazuke/probes.js.map +1 -0
  110. package/dist/urazuke/prompts.generated.d.ts +12 -0
  111. package/dist/urazuke/prompts.generated.d.ts.map +1 -0
  112. package/dist/urazuke/prompts.generated.js +135 -0
  113. package/dist/urazuke/prompts.generated.js.map +1 -0
  114. package/dist/urazuke/prompts_client.d.ts +44 -0
  115. package/dist/urazuke/prompts_client.d.ts.map +1 -0
  116. package/dist/urazuke/prompts_client.js +151 -0
  117. package/dist/urazuke/prompts_client.js.map +1 -0
  118. package/dist/urazuke/quality.d.ts +99 -0
  119. package/dist/urazuke/quality.d.ts.map +1 -0
  120. package/dist/urazuke/quality.js +269 -0
  121. package/dist/urazuke/quality.js.map +1 -0
  122. package/dist/urazuke/receipts.d.ts +90 -0
  123. package/dist/urazuke/receipts.d.ts.map +1 -0
  124. package/dist/urazuke/receipts.js +171 -0
  125. package/dist/urazuke/receipts.js.map +1 -0
  126. package/dist/urazuke/report.d.ts +23 -0
  127. package/dist/urazuke/report.d.ts.map +1 -0
  128. package/dist/urazuke/report.js +62 -0
  129. package/dist/urazuke/report.js.map +1 -0
  130. package/dist/urazuke/retro.d.ts +52 -0
  131. package/dist/urazuke/retro.d.ts.map +1 -0
  132. package/dist/urazuke/retro.js +145 -0
  133. package/dist/urazuke/retro.js.map +1 -0
  134. package/dist/urazuke/section.d.ts +43 -0
  135. package/dist/urazuke/section.d.ts.map +1 -0
  136. package/dist/urazuke/section.js +64 -0
  137. package/dist/urazuke/section.js.map +1 -0
  138. package/dist/urazuke/stacks.d.ts +42 -0
  139. package/dist/urazuke/stacks.d.ts.map +1 -0
  140. package/dist/urazuke/stacks.js +264 -0
  141. package/dist/urazuke/stacks.js.map +1 -0
  142. package/dist/urazuke/workflow.d.ts +23 -0
  143. package/dist/urazuke/workflow.d.ts.map +1 -0
  144. package/dist/urazuke/workflow.js +64 -0
  145. package/dist/urazuke/workflow.js.map +1 -0
  146. package/dist/version.d.ts +1 -1
  147. package/dist/version.js +1 -1
  148. package/dist/workflow/config.d.ts +9 -4
  149. package/dist/workflow/config.d.ts.map +1 -1
  150. package/dist/workflow/config.js +4 -1
  151. package/dist/workflow/config.js.map +1 -1
  152. package/dist/workflow/definitions.d.ts +20 -4
  153. package/dist/workflow/definitions.d.ts.map +1 -1
  154. package/dist/workflow/definitions.js +16 -3
  155. package/dist/workflow/definitions.js.map +1 -1
  156. package/dist/workflow/instances.d.ts.map +1 -1
  157. package/dist/workflow/instances.js +6 -0
  158. package/dist/workflow/instances.js.map +1 -1
  159. package/dist/workflow/orchestrator.d.ts +10 -1
  160. package/dist/workflow/orchestrator.d.ts.map +1 -1
  161. package/dist/workflow/orchestrator.js +54 -7
  162. package/dist/workflow/orchestrator.js.map +1 -1
  163. package/dist/workflow/select.d.ts +5 -1
  164. package/dist/workflow/select.d.ts.map +1 -1
  165. package/dist/workflow/select.js +16 -5
  166. package/dist/workflow/select.js.map +1 -1
  167. package/dist/workflow/state.d.ts +3 -2
  168. package/dist/workflow/state.d.ts.map +1 -1
  169. package/dist/workflow/state.js.map +1 -1
  170. package/docs/doctrine/urazuke.md +38 -0
  171. package/package.json +18 -20
  172. package/src/i18n/catalogs/ar.json +550 -542
  173. package/src/i18n/catalogs/de.json +550 -542
  174. package/src/i18n/catalogs/en.json +550 -542
  175. package/src/i18n/catalogs/es.json +550 -542
  176. package/src/i18n/catalogs/fr.json +550 -542
  177. package/src/i18n/catalogs/hi.json +550 -542
  178. package/src/i18n/catalogs/it.json +550 -542
  179. package/src/i18n/catalogs/ja.json +550 -542
  180. package/src/i18n/catalogs/pt.json +550 -542
  181. package/src/i18n/catalogs/zh.json +550 -542
@@ -0,0 +1,31 @@
1
+ /**
2
+ * URAZUKE ON/OFF -- one switch, in the brain config of the instance.
3
+ *
4
+ * Pablo (2026-10-19): the method is enabled by default in Forge developer
5
+ * (the panel a person opens on their machine) and disabled by default in
6
+ * Forge embed (the resident assistant that runs on a server with YF_ENV
7
+ * set to prod / uat / ops). The user flips it in Settings; the explicit
8
+ * value, when present, wins over the default.
9
+ *
10
+ * What the switch gates: the prompt injected into the brain, the Urazuke
11
+ * startup tab, the automatic choice of a urazuke / urazuke-legacy workflow
12
+ * for a newly mapped project, the step gate on canonical tasks, the
13
+ * receipt gate on plan items, and the yujin.urazuke.* / yujin.evidence.*
14
+ * verbs. The `yf urazuke` CLI stays explicit and always works.
15
+ *
16
+ * ASCII-only.
17
+ */
18
+ /** True when this process is a Forge embed (resident assistant). */
19
+ export declare function isEmbedRuntime(env?: NodeJS.ProcessEnv): boolean;
20
+ /** The default when the config does not say: developer on, embed off. */
21
+ export declare function urazukeDefaultEnabled(env?: NodeJS.ProcessEnv): boolean;
22
+ /** Resolve the effective switch: explicit config value, else the default. */
23
+ export declare function resolveUrazukeEnabled(cfg: {
24
+ urazuke_enabled?: boolean;
25
+ } | undefined, env?: NodeJS.ProcessEnv): boolean;
26
+ /** Read the instance config and resolve. Never throws: on any failure the
27
+ * default for this runtime applies. Tests may force it with
28
+ * YF_URAZUKE_ENABLED=0|1. */
29
+ export declare function urazukeEnabled(): Promise<boolean>;
30
+ export declare const URAZUKE_DISABLED_MESSAGE = "Urazuke is disabled for this Forge (Settings > Urazuke). Enable it there, or use the yf urazuke CLI explicitly.";
31
+ //# sourceMappingURL=enabled.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enabled.d.ts","sourceRoot":"","sources":["../../src/urazuke/enabled.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAE5E;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAEnF;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,GAAG,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAGnI;AAED;;8BAE8B;AAC9B,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAUvD;AAED,eAAO,MAAM,wBAAwB,oHAAoH,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * URAZUKE ON/OFF -- one switch, in the brain config of the instance.
3
+ *
4
+ * Pablo (2026-10-19): the method is enabled by default in Forge developer
5
+ * (the panel a person opens on their machine) and disabled by default in
6
+ * Forge embed (the resident assistant that runs on a server with YF_ENV
7
+ * set to prod / uat / ops). The user flips it in Settings; the explicit
8
+ * value, when present, wins over the default.
9
+ *
10
+ * What the switch gates: the prompt injected into the brain, the Urazuke
11
+ * startup tab, the automatic choice of a urazuke / urazuke-legacy workflow
12
+ * for a newly mapped project, the step gate on canonical tasks, the
13
+ * receipt gate on plan items, and the yujin.urazuke.* / yujin.evidence.*
14
+ * verbs. The `yf urazuke` CLI stays explicit and always works.
15
+ *
16
+ * ASCII-only.
17
+ */
18
+ const EMBED_ENVS = new Set(['prod', 'uat', 'ops']);
19
+ /** True when this process is a Forge embed (resident assistant). */
20
+ export function isEmbedRuntime(env = process.env) {
21
+ return EMBED_ENVS.has(String(env['YF_ENV'] ?? '').trim().toLowerCase());
22
+ }
23
+ /** The default when the config does not say: developer on, embed off. */
24
+ export function urazukeDefaultEnabled(env = process.env) {
25
+ return !isEmbedRuntime(env);
26
+ }
27
+ /** Resolve the effective switch: explicit config value, else the default. */
28
+ export function resolveUrazukeEnabled(cfg, env = process.env) {
29
+ if (cfg && typeof cfg.urazuke_enabled === 'boolean')
30
+ return cfg.urazuke_enabled;
31
+ return urazukeDefaultEnabled(env);
32
+ }
33
+ /** Read the instance config and resolve. Never throws: on any failure the
34
+ * default for this runtime applies. Tests may force it with
35
+ * YF_URAZUKE_ENABLED=0|1. */
36
+ export async function urazukeEnabled() {
37
+ const forced = process.env['YF_URAZUKE_ENABLED'];
38
+ if (forced === '0')
39
+ return false;
40
+ if (forced === '1')
41
+ return true;
42
+ try {
43
+ const { readBrainConfig } = await import('../core/brain_config.js');
44
+ return resolveUrazukeEnabled(await readBrainConfig());
45
+ }
46
+ catch {
47
+ return urazukeDefaultEnabled();
48
+ }
49
+ }
50
+ export const URAZUKE_DISABLED_MESSAGE = 'Urazuke is disabled for this Forge (Settings > Urazuke). Enable it there, or use the yf urazuke CLI explicitly.';
51
+ //# sourceMappingURL=enabled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enabled.js","sourceRoot":"","sources":["../../src/urazuke/enabled.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEnD,oEAAoE;AACpE,MAAM,UAAU,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjE,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,qBAAqB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACxE,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CAAC,GAA8C,EAAE,MAAyB,OAAO,CAAC,GAAG;IACxH,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,eAAe,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,eAAe,CAAC;IAChF,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;8BAE8B;AAC9B,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACjD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACpE,OAAO,qBAAqB,CAAC,MAAM,eAAe,EAAE,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,qBAAqB,EAAE,CAAC;IACjC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,iHAAiH,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { type Receipt, type ReceiptKind } from './receipts.js';
2
+ export interface RunEvidenceInput {
3
+ slug: string;
4
+ projectRoot: string;
5
+ kind: ReceiptKind;
6
+ command: string;
7
+ pending_id?: string;
8
+ step?: number;
9
+ /** Default 10 min, max 30 min. */
10
+ timeout_ms?: number;
11
+ /** red_proof only: the ref of the code BEFORE the change (default HEAD). */
12
+ base_ref?: string;
13
+ /** red_proof only: the new test files (project-relative) to carry into
14
+ * the base worktree. Required for a base red proof: a test that does not
15
+ * exist at the base cannot fail there. */
16
+ test_files?: string[];
17
+ /** red_proof only, D-037: a unified diff that plants ONE deliberate
18
+ * defect in the NEW code. Forge copies the working tree (HEAD plus the
19
+ * uncommitted changes) into a temporary worktree, applies the diff
20
+ * there, runs the command and expects TESTS to fail. The diff is kept in
21
+ * the receipt. For the first block of a new project, where the previous
22
+ * version does not even have the module. */
23
+ mutation_diff?: string;
24
+ note?: string;
25
+ }
26
+ export interface RunEvidenceResult {
27
+ receipt: Receipt;
28
+ /** For red_proof: the worktree was created at this path (already removed). */
29
+ worktree?: string;
30
+ }
31
+ /** Spawn a shell command, capture everything, never throw. */
32
+ export declare function runCommand(command: string, cwd: string, timeout_ms: number): Promise<{
33
+ exit_code: number;
34
+ output: string;
35
+ duration_ms: number;
36
+ timed_out: boolean;
37
+ }>;
38
+ /** Remove ONLY the link at `p`, never what it points to. On Windows a
39
+ * junction is removed with rmdir; a symlink with unlink. Both leave the
40
+ * target untouched. */
41
+ export declare function unlinkDir(p: string): Promise<void>;
42
+ /** Run a command and record its receipt. For red_proof, run it in a base
43
+ * worktree with the new test files copied in. */
44
+ export declare function runEvidence(input: RunEvidenceInput): Promise<RunEvidenceResult>;
45
+ //# sourceMappingURL=evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/urazuke/evidence.ts"],"names":[],"mappings":"AAsBA,OAAO,EAA8B,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAI3F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;+CAE2C;IAC3C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;iDAK6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAqBD,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CA4BpK;AAgCD;;wBAEwB;AACxB,wBAAsB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIxD;AAMD;kDACkD;AAClD,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA4FrF"}
@@ -0,0 +1,264 @@
1
+ /**
2
+ * EVIDENCE RUNNER -- Forge runs the command and writes the receipt.
3
+ *
4
+ * The brain asks for a run (yujin.evidence.run); Forge spawns it in the
5
+ * project root, captures exit code, output and counts, reads the git ref
6
+ * and the dirty flag itself, and appends a receipt. Nothing in the receipt
7
+ * comes from the brain's prose.
8
+ *
9
+ * The red proof (step 8, D-033) is the mechanical answer to "the agent can
10
+ * fake the red": Forge creates a temporary git worktree at the base ref
11
+ * (the code BEFORE the change), copies the new test files into it, runs the
12
+ * command there and expects a failure; then the same command on the
13
+ * working tree is the green. Both are receipts; the owner can rerun either
14
+ * with the command printed in it.
15
+ *
16
+ * ASCII-only.
17
+ */
18
+ import { spawn, execFile } from 'node:child_process';
19
+ import { promisify } from 'node:util';
20
+ import fs from 'node:fs/promises';
21
+ import os from 'node:os';
22
+ import path from 'node:path';
23
+ import { appendReceipt, parseCounts } from './receipts.js';
24
+ const execFileP = promisify(execFile);
25
+ const TAIL_CHARS = 4000;
26
+ const DEFAULT_TIMEOUT = 10 * 60 * 1000;
27
+ const MAX_TIMEOUT = 30 * 60 * 1000;
28
+ async function git(cwd, args) {
29
+ const { stdout } = await execFileP('git', args, { cwd, encoding: 'utf8', windowsHide: true });
30
+ return stdout.trim();
31
+ }
32
+ async function gitRef(cwd) {
33
+ try {
34
+ const ref = await git(cwd, ['rev-parse', '--short', 'HEAD']);
35
+ const status = await git(cwd, ['status', '--porcelain']);
36
+ return { ref, dirty: status.length > 0 };
37
+ }
38
+ catch {
39
+ return { ref: 'no-git', dirty: false };
40
+ }
41
+ }
42
+ /** Spawn a shell command, capture everything, never throw. */
43
+ export function runCommand(command, cwd, timeout_ms) {
44
+ return new Promise((resolve) => {
45
+ const started = Date.now();
46
+ const isWin = process.platform === 'win32';
47
+ const child = spawn(isWin ? (process.env['ComSpec'] || 'cmd.exe') : '/bin/sh', isWin ? ['/d', '/c', command] : ['-c', command], {
48
+ cwd, windowsHide: true, env: { ...process.env, CI: process.env['CI'] ?? '1', FORCE_COLOR: '0', NO_COLOR: '1' },
49
+ });
50
+ /* On Windows the shell is cmd.exe and the real work is a grandchild:
51
+ * child.kill() would leave it running. taskkill /T takes the tree. */
52
+ const killTree = () => {
53
+ if (isWin && child.pid) {
54
+ try {
55
+ spawn('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' });
56
+ }
57
+ catch { /* best effort */ }
58
+ }
59
+ else {
60
+ try {
61
+ child.kill('SIGKILL');
62
+ }
63
+ catch { /* gone */ }
64
+ }
65
+ };
66
+ let out = '';
67
+ const push = (b) => { out += b.toString('utf8'); if (out.length > 200000)
68
+ out = out.slice(-100000); };
69
+ child.stdout?.on('data', push);
70
+ child.stderr?.on('data', push);
71
+ let timedOut = false;
72
+ const timer = setTimeout(() => { timedOut = true; killTree(); }, timeout_ms);
73
+ child.on('error', (e) => { clearTimeout(timer); resolve({ exit_code: 127, output: out + '\n[spawn error] ' + e.message, duration_ms: Date.now() - started, timed_out: false }); });
74
+ child.on('close', (code) => {
75
+ clearTimeout(timer);
76
+ resolve({ exit_code: timedOut ? 124 : (code ?? 1), output: out + (timedOut ? '\n[timed out after ' + timeout_ms + ' ms]' : ''), duration_ms: Date.now() - started, timed_out: timedOut });
77
+ });
78
+ });
79
+ }
80
+ /** Copy the uncommitted changes of the working tree (modified + untracked,
81
+ * minus node_modules) into the worktree, and delete there what was deleted
82
+ * here, so the worktree is the CURRENT code. */
83
+ async function overlayDirtyFiles(projectRoot, wt) {
84
+ let status = '';
85
+ try {
86
+ status = await git(projectRoot, ['status', '--porcelain', '--untracked-files=all']);
87
+ }
88
+ catch {
89
+ return;
90
+ }
91
+ for (const line of status.split('\n')) {
92
+ if (!line.trim())
93
+ continue;
94
+ const code = line.slice(0, 2);
95
+ let rel = line.slice(3).trim();
96
+ if (rel.includes(' -> '))
97
+ rel = rel.split(' -> ')[1].trim();
98
+ if (rel.startsWith('"') && rel.endsWith('"'))
99
+ rel = rel.slice(1, -1);
100
+ if (rel.split(/[\\/]/).includes('node_modules'))
101
+ continue;
102
+ const src = path.join(projectRoot, rel);
103
+ const dst = path.join(wt, rel);
104
+ if (code.includes('D')) {
105
+ try {
106
+ await fs.rm(dst, { force: true });
107
+ }
108
+ catch { /* ok */ }
109
+ continue;
110
+ }
111
+ try {
112
+ const st = await fs.stat(src);
113
+ if (!st.isFile())
114
+ continue;
115
+ await fs.mkdir(path.dirname(dst), { recursive: true });
116
+ await fs.copyFile(src, dst);
117
+ }
118
+ catch { /* gone meanwhile */ }
119
+ }
120
+ }
121
+ /** Is there a symlink / junction at this path? (lstat, never follows.) */
122
+ async function isLink(p) {
123
+ try {
124
+ return (await fs.lstat(p)).isSymbolicLink();
125
+ }
126
+ catch {
127
+ return false;
128
+ }
129
+ }
130
+ /** Remove ONLY the link at `p`, never what it points to. On Windows a
131
+ * junction is removed with rmdir; a symlink with unlink. Both leave the
132
+ * target untouched. */
133
+ export async function unlinkDir(p) {
134
+ if (!(await isLink(p)))
135
+ return;
136
+ try {
137
+ await fs.unlink(p);
138
+ }
139
+ catch { /* junction: rmdir removes the link only */ }
140
+ if (await isLink(p)) {
141
+ try {
142
+ await fs.rmdir(p);
143
+ }
144
+ catch { /* best effort */ }
145
+ }
146
+ }
147
+ function tail(s) {
148
+ return s.length > TAIL_CHARS ? '...' + s.slice(-TAIL_CHARS) : s;
149
+ }
150
+ /** Run a command and record its receipt. For red_proof, run it in a base
151
+ * worktree with the new test files copied in. */
152
+ export async function runEvidence(input) {
153
+ const timeout = Math.min(Math.max(input.timeout_ms ?? DEFAULT_TIMEOUT, 1000), MAX_TIMEOUT);
154
+ const head = await gitRef(input.projectRoot);
155
+ const started = Date.now();
156
+ if (input.kind === 'red_proof') {
157
+ const files = (input.test_files ?? []).map((f) => f.trim()).filter(Boolean);
158
+ const mutation = (input.mutation_diff ?? '').trim();
159
+ if (!files.length && !mutation)
160
+ throw new Error('red_proof needs test_files (the new test(s) to carry into the base worktree) or mutation_diff (a defect planted in the new code, D-037)');
161
+ if (mutation && !/^(diff --git|--- |\+\+\+ |@@ )/m.test(mutation))
162
+ throw new Error('mutation_diff must be a unified diff (diff --git / --- / +++ / @@ hunks)');
163
+ const baseRef = mutation ? 'HEAD' : (input.base_ref ?? 'HEAD').trim();
164
+ const wt = await fs.mkdtemp(path.join(os.tmpdir(), 'yf-redproof-'));
165
+ const link = path.join(wt, 'node_modules');
166
+ let linked = false;
167
+ let r;
168
+ let baseShort = baseRef;
169
+ let applyError = '';
170
+ try {
171
+ /* autocrlf off: the worktree gets the bytes as stored (LF), so a diff
172
+ * written from the working tree applies on Windows too. */
173
+ await git(input.projectRoot, ['-c', 'core.autocrlf=false', 'worktree', 'add', '--detach', wt, baseRef]);
174
+ try {
175
+ baseShort = await git(wt, ['rev-parse', '--short', 'HEAD']);
176
+ }
177
+ catch { /* keep */ }
178
+ if (mutation) {
179
+ /* The mutant is planted on the CURRENT code: HEAD plus whatever is
180
+ * uncommitted in the working tree, overlaid file by file. */
181
+ await overlayDirtyFiles(input.projectRoot, wt);
182
+ const patch = path.join(wt, '.yf-mutant.diff');
183
+ await fs.writeFile(patch, mutation.endsWith('\n') ? mutation : mutation + '\n', 'utf8');
184
+ try {
185
+ await git(wt, ['apply', '--whitespace=nowarn', '--ignore-whitespace', patch]);
186
+ }
187
+ catch (e) {
188
+ applyError = 'mutation diff does not apply to the current code: ' + (e instanceof Error ? e.message.split('\n')[0] : String(e));
189
+ }
190
+ try {
191
+ await fs.unlink(patch);
192
+ }
193
+ catch { /* ok */ }
194
+ baseShort = baseShort + '+mutant';
195
+ }
196
+ for (const f of files) {
197
+ const src = path.join(input.projectRoot, f);
198
+ const dst = path.join(wt, f);
199
+ await fs.mkdir(path.dirname(dst), { recursive: true });
200
+ await fs.copyFile(src, dst);
201
+ }
202
+ /* node_modules are not in git: link the project's so the runner exists. */
203
+ try {
204
+ const nm = path.join(input.projectRoot, 'node_modules');
205
+ await fs.access(nm);
206
+ await fs.symlink(nm, link, 'junction');
207
+ linked = true;
208
+ }
209
+ catch { /* no node_modules or cannot link: the command may still work */ }
210
+ r = applyError
211
+ ? { exit_code: 0, output: '[forge] ' + applyError, duration_ms: 0, timed_out: false }
212
+ : await runCommand(input.command, wt, timeout);
213
+ }
214
+ finally {
215
+ /* The link goes FIRST and by itself: a recursive remove (git's or
216
+ * ours) that walks through the junction would delete the project's
217
+ * real node_modules. Found the hard way on 2026-10-19 (Turnera). */
218
+ if (linked)
219
+ await unlinkDir(link);
220
+ if (!(await isLink(link))) {
221
+ try {
222
+ await git(input.projectRoot, ['worktree', 'remove', '--force', wt]);
223
+ }
224
+ catch { /* best effort */ }
225
+ try {
226
+ await fs.rm(wt, { recursive: true, force: true });
227
+ }
228
+ catch { /* best effort */ }
229
+ }
230
+ try {
231
+ await git(input.projectRoot, ['worktree', 'prune']);
232
+ }
233
+ catch { /* best effort */ }
234
+ }
235
+ const counts = parseCounts(r.output);
236
+ const receipt = await appendReceipt(input.slug, {
237
+ kind: 'red_proof', command: input.command, cwd: input.projectRoot,
238
+ ref: head.ref, dirty: head.dirty, base_ref: baseShort,
239
+ mode: mutation ? 'mutation' : 'base',
240
+ ...(mutation ? { mutation_diff: mutation.length > 6000 ? mutation.slice(0, 6000) + '\n...[truncated]' : mutation } : {}),
241
+ exit_code: r.exit_code, started_at: started, duration_ms: r.duration_ms,
242
+ counts, output_tail: tail(r.output),
243
+ ...(input.pending_id ? { pending_id: input.pending_id } : {}),
244
+ ...(input.step != null ? { step: input.step } : {}),
245
+ note: (input.note ? input.note + ' ' : '')
246
+ + (mutation ? 'mutation red (D-037): a defect planted on the current code, diff on record' : 'test files carried into the base worktree: ' + files.join(', '))
247
+ + (files.length && mutation ? '; test files carried: ' + files.join(', ') : ''),
248
+ });
249
+ return { receipt, worktree: wt };
250
+ }
251
+ const r = await runCommand(input.command, input.projectRoot, timeout);
252
+ const counts = parseCounts(r.output);
253
+ const receipt = await appendReceipt(input.slug, {
254
+ kind: input.kind, command: input.command, cwd: input.projectRoot,
255
+ ref: head.ref, dirty: head.dirty,
256
+ exit_code: r.exit_code, started_at: started, duration_ms: r.duration_ms,
257
+ counts, output_tail: tail(r.output),
258
+ ...(input.pending_id ? { pending_id: input.pending_id } : {}),
259
+ ...(input.step != null ? { step: input.step } : {}),
260
+ ...(input.note ? { note: input.note } : {}),
261
+ });
262
+ return { receipt };
263
+ }
264
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/urazuke/evidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { type UrazukeStep, type UrazukeStation } from './catalog.js';
2
+ export type UrazukeCheckStatus = 'ok' | 'fail' | 'skip';
3
+ export interface UrazukeCheck {
4
+ label: string;
5
+ status: UrazukeCheckStatus;
6
+ detail: string;
7
+ }
8
+ export type UrazukeStepStatus = 'green' | 'red' | 'owner';
9
+ export interface UrazukeStepResult {
10
+ num: number;
11
+ id: string;
12
+ title: string;
13
+ status: UrazukeStepStatus;
14
+ /** Owner inputs ("antes de enviar el prompt"): present or missing. */
15
+ inputs: UrazukeCheck[];
16
+ /** The agent's artifacts + registry checks. */
17
+ checks: UrazukeCheck[];
18
+ }
19
+ /** Optional registry probes, injected so this module stays pure and the
20
+ * tests can drive it without touching ~/.yujin-forge. */
21
+ export interface UrazukeProbes {
22
+ /** G9: is the sizing record admissible for construction? */
23
+ sizingOk?: () => Promise<{
24
+ ok: boolean;
25
+ detail: string;
26
+ }>;
27
+ /** Step 5 / N7: how many open pendings carry a spec (acceptance +
28
+ * how_verified), and how many do not. */
29
+ pendingsSpec?: () => Promise<{
30
+ with_spec: number;
31
+ without_spec: number;
32
+ }>;
33
+ /** Step 8: evidence receipts recorded for this project. */
34
+ receipts?: () => Promise<{
35
+ red_proofs: number;
36
+ greens: number;
37
+ e2e: number;
38
+ last_at?: number;
39
+ }>;
40
+ /** Step 12: closed plan items with / without their honest report. */
41
+ reports?: () => Promise<{
42
+ with_report: number;
43
+ without_report: number;
44
+ }>;
45
+ }
46
+ export interface UrazukeGateOptions {
47
+ projectRoot: string;
48
+ probes?: UrazukeProbes;
49
+ /** Clock, for freshness checks (tests). */
50
+ now?: number;
51
+ }
52
+ /** CI definition present: GitHub Actions, GitLab, Azure, Jenkins, CircleCI,
53
+ * Bitbucket, or a generic ci/ directory. */
54
+ export declare function detectCi(root: string): Promise<{
55
+ ok: boolean;
56
+ detail: string;
57
+ }>;
58
+ /** Evaluate one step of the new-project ladder. */
59
+ export declare function evaluateStep(step: UrazukeStep, opts: UrazukeGateOptions): Promise<UrazukeStepResult>;
60
+ /** Evaluate one station of the legacy normalisation path. */
61
+ export declare function evaluateStation(station: UrazukeStation, opts: UrazukeGateOptions): Promise<UrazukeStepResult>;
62
+ /** The whole ladder, in order. */
63
+ export declare function evaluateLadder(opts: UrazukeGateOptions): Promise<UrazukeStepResult[]>;
64
+ /** The whole legacy path, in order. */
65
+ export declare function evaluateLegacyPath(opts: UrazukeGateOptions): Promise<UrazukeStepResult[]>;
66
+ /** One line per step, for the CLI and the prompt: `[x] 08 Tests ...`. */
67
+ export declare function renderLadderLine(r: UrazukeStepResult): string;
68
+ //# sourceMappingURL=gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/urazuke/gate.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEwC,KAAK,WAAW,EAAE,KAAK,cAAc,EACnF,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;IAC1B,sEAAsE;IACtE,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,+CAA+C;IAC/C,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED;0DAC0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D;8CAC0C;IAC1C,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChG,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA2ED;6CAC6C;AAC7C,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAOrF;AAiGD,mDAAmD;AACnD,wBAAsB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE1G;AAED,6DAA6D;AAC7D,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAEnH;AAED,kCAAkC;AAClC,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAI3F;AAED,uCAAuC;AACvC,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAI/F;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAK7D"}