specweave 2.0.3 → 2.2.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.
Files changed (156) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/README.md +21 -11
  3. package/bin/specweave.js +28 -0
  4. package/dist/dashboard/assets/index-BeKUULf0.css +1 -0
  5. package/dist/dashboard/assets/index-Bf5TF0_l.js +13 -0
  6. package/dist/dashboard/index.html +2 -2
  7. package/dist/src/cli/commands/jev-helpers.d.ts +148 -0
  8. package/dist/src/cli/commands/jev-helpers.d.ts.map +1 -0
  9. package/dist/src/cli/commands/jev-helpers.js +582 -0
  10. package/dist/src/cli/commands/jev-helpers.js.map +1 -0
  11. package/dist/src/cli/commands/jev.d.ts +21 -0
  12. package/dist/src/cli/commands/jev.d.ts.map +1 -0
  13. package/dist/src/cli/commands/jev.js +350 -0
  14. package/dist/src/cli/commands/jev.js.map +1 -0
  15. package/dist/src/cli/commands/sync.d.ts.map +1 -1
  16. package/dist/src/cli/commands/sync.js +23 -5
  17. package/dist/src/cli/commands/sync.js.map +1 -1
  18. package/dist/src/cli/helpers/init/instruction-file-writer.d.ts +4 -0
  19. package/dist/src/cli/helpers/init/instruction-file-writer.d.ts.map +1 -1
  20. package/dist/src/cli/helpers/init/instruction-file-writer.js +11 -6
  21. package/dist/src/cli/helpers/init/instruction-file-writer.js.map +1 -1
  22. package/dist/src/core/auto/completion-evaluator.d.ts +22 -1
  23. package/dist/src/core/auto/completion-evaluator.d.ts.map +1 -1
  24. package/dist/src/core/auto/completion-evaluator.js +99 -9
  25. package/dist/src/core/auto/completion-evaluator.js.map +1 -1
  26. package/dist/src/core/config/types.d.ts +39 -1
  27. package/dist/src/core/config/types.d.ts.map +1 -1
  28. package/dist/src/core/config/types.js +1 -0
  29. package/dist/src/core/config/types.js.map +1 -1
  30. package/dist/src/core/doctor/checkers/hooks-checker.d.ts +1 -1
  31. package/dist/src/core/doctor/checkers/hooks-checker.js +1 -1
  32. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts +28 -5
  33. package/dist/src/core/hooks/handlers/pre-tool-use.d.ts.map +1 -1
  34. package/dist/src/core/hooks/handlers/pre-tool-use.js +162 -7
  35. package/dist/src/core/hooks/handlers/pre-tool-use.js.map +1 -1
  36. package/dist/src/core/hooks/handlers/session-start.d.ts.map +1 -1
  37. package/dist/src/core/hooks/handlers/session-start.js +20 -0
  38. package/dist/src/core/hooks/handlers/session-start.js.map +1 -1
  39. package/dist/src/core/intent/portable-context.d.ts +4 -0
  40. package/dist/src/core/intent/portable-context.d.ts.map +1 -0
  41. package/dist/src/core/intent/portable-context.js +68 -0
  42. package/dist/src/core/intent/portable-context.js.map +1 -0
  43. package/dist/src/core/intent/types.d.ts +28 -0
  44. package/dist/src/core/intent/types.d.ts.map +1 -0
  45. package/dist/src/core/intent/types.js +3 -0
  46. package/dist/src/core/intent/types.js.map +1 -0
  47. package/dist/src/core/intent/validation.d.ts +5 -0
  48. package/dist/src/core/intent/validation.d.ts.map +1 -0
  49. package/dist/src/core/intent/validation.js +39 -0
  50. package/dist/src/core/intent/validation.js.map +1 -0
  51. package/dist/src/core/jev/browse.d.ts +56 -0
  52. package/dist/src/core/jev/browse.d.ts.map +1 -0
  53. package/dist/src/core/jev/browse.js +721 -0
  54. package/dist/src/core/jev/browse.js.map +1 -0
  55. package/dist/src/core/jev/client.d.ts +134 -0
  56. package/dist/src/core/jev/client.d.ts.map +1 -0
  57. package/dist/src/core/jev/client.js +329 -0
  58. package/dist/src/core/jev/client.js.map +1 -0
  59. package/dist/src/core/jev/config.d.ts +69 -0
  60. package/dist/src/core/jev/config.d.ts.map +1 -0
  61. package/dist/src/core/jev/config.js +181 -0
  62. package/dist/src/core/jev/config.js.map +1 -0
  63. package/dist/src/core/jev/decide.d.ts +160 -0
  64. package/dist/src/core/jev/decide.d.ts.map +1 -0
  65. package/dist/src/core/jev/decide.js +325 -0
  66. package/dist/src/core/jev/decide.js.map +1 -0
  67. package/dist/src/core/jev/index.d.ts +20 -0
  68. package/dist/src/core/jev/index.d.ts.map +1 -0
  69. package/dist/src/core/jev/index.js +20 -0
  70. package/dist/src/core/jev/index.js.map +1 -0
  71. package/dist/src/core/jev/questions.d.ts +56 -0
  72. package/dist/src/core/jev/questions.d.ts.map +1 -0
  73. package/dist/src/core/jev/questions.js +159 -0
  74. package/dist/src/core/jev/questions.js.map +1 -0
  75. package/dist/src/core/jev/redact.d.ts +44 -0
  76. package/dist/src/core/jev/redact.d.ts.map +1 -0
  77. package/dist/src/core/jev/redact.js +102 -0
  78. package/dist/src/core/jev/redact.js.map +1 -0
  79. package/dist/src/core/jev/usage.d.ts +38 -0
  80. package/dist/src/core/jev/usage.d.ts.map +1 -0
  81. package/dist/src/core/jev/usage.js +70 -0
  82. package/dist/src/core/jev/usage.js.map +1 -0
  83. package/dist/src/core/session/handoff-pointer.d.ts +4 -0
  84. package/dist/src/core/session/handoff-pointer.d.ts.map +1 -0
  85. package/dist/src/core/session/handoff-pointer.js +60 -0
  86. package/dist/src/core/session/handoff-pointer.js.map +1 -0
  87. package/dist/src/core/session/work-handoff.d.ts.map +1 -1
  88. package/dist/src/core/session/work-handoff.js +10 -3
  89. package/dist/src/core/session/work-handoff.js.map +1 -1
  90. package/dist/src/dashboard/server/dashboard-server.d.ts +1 -0
  91. package/dist/src/dashboard/server/dashboard-server.d.ts.map +1 -1
  92. package/dist/src/dashboard/server/dashboard-server.js +10 -90
  93. package/dist/src/dashboard/server/dashboard-server.js.map +1 -1
  94. package/dist/src/dashboard/server/data/cost-aggregator.d.ts +10 -5
  95. package/dist/src/dashboard/server/data/cost-aggregator.d.ts.map +1 -1
  96. package/dist/src/dashboard/server/data/cost-aggregator.js +31 -33
  97. package/dist/src/dashboard/server/data/cost-aggregator.js.map +1 -1
  98. package/dist/src/dashboard/server/data/dashboard-data-aggregator.d.ts +0 -1
  99. package/dist/src/dashboard/server/data/dashboard-data-aggregator.d.ts.map +1 -1
  100. package/dist/src/dashboard/server/data/dashboard-data-aggregator.js +14 -66
  101. package/dist/src/dashboard/server/data/dashboard-data-aggregator.js.map +1 -1
  102. package/dist/src/dashboard/server/data/dashboard-task-board.d.ts +4 -0
  103. package/dist/src/dashboard/server/data/dashboard-task-board.d.ts.map +1 -0
  104. package/dist/src/dashboard/server/data/dashboard-task-board.js +56 -0
  105. package/dist/src/dashboard/server/data/dashboard-task-board.js.map +1 -0
  106. package/dist/src/dashboard/server/data/intent-store.d.ts +19 -0
  107. package/dist/src/dashboard/server/data/intent-store.d.ts.map +1 -0
  108. package/dist/src/dashboard/server/data/intent-store.js +268 -0
  109. package/dist/src/dashboard/server/data/intent-store.js.map +1 -0
  110. package/dist/src/dashboard/server/data/local-sessions.d.ts +15 -0
  111. package/dist/src/dashboard/server/data/local-sessions.d.ts.map +1 -0
  112. package/dist/src/dashboard/server/data/local-sessions.js +197 -0
  113. package/dist/src/dashboard/server/data/local-sessions.js.map +1 -0
  114. package/dist/src/dashboard/server/data/work-projection.d.ts +8 -0
  115. package/dist/src/dashboard/server/data/work-projection.d.ts.map +1 -0
  116. package/dist/src/dashboard/server/data/work-projection.js +175 -0
  117. package/dist/src/dashboard/server/data/work-projection.js.map +1 -0
  118. package/dist/src/dashboard/server/file-watcher.d.ts.map +1 -1
  119. package/dist/src/dashboard/server/file-watcher.js +2 -1
  120. package/dist/src/dashboard/server/file-watcher.js.map +1 -1
  121. package/dist/src/dashboard/server/local-request.d.ts +4 -0
  122. package/dist/src/dashboard/server/local-request.d.ts.map +1 -0
  123. package/dist/src/dashboard/server/local-request.js +29 -0
  124. package/dist/src/dashboard/server/local-request.js.map +1 -0
  125. package/dist/src/dashboard/server/routes/work-routes.d.ts +5 -0
  126. package/dist/src/dashboard/server/routes/work-routes.d.ts.map +1 -0
  127. package/dist/src/dashboard/server/routes/work-routes.js +37 -0
  128. package/dist/src/dashboard/server/routes/work-routes.js.map +1 -0
  129. package/dist/src/dashboard/types.d.ts +3 -3
  130. package/dist/src/dashboard/types.d.ts.map +1 -1
  131. package/dist/src/dashboard/work-types.d.ts +39 -0
  132. package/dist/src/dashboard/work-types.d.ts.map +1 -0
  133. package/dist/src/dashboard/work-types.js +3 -0
  134. package/dist/src/dashboard/work-types.js.map +1 -0
  135. package/dist/src/sync/external-change-puller.d.ts +19 -0
  136. package/dist/src/sync/external-change-puller.d.ts.map +1 -1
  137. package/dist/src/sync/external-change-puller.js +87 -77
  138. package/dist/src/sync/external-change-puller.js.map +1 -1
  139. package/dist/src/utils/model-selection.d.ts +49 -0
  140. package/dist/src/utils/model-selection.d.ts.map +1 -1
  141. package/dist/src/utils/model-selection.js +70 -0
  142. package/dist/src/utils/model-selection.js.map +1 -1
  143. package/package.json +3 -3
  144. package/plugins/PLUGINS-INDEX.md +14 -4
  145. package/plugins/specweave/.claude-plugin/plugin.json +5 -3
  146. package/plugins/specweave/PLUGIN.md +16 -4
  147. package/plugins/specweave/hooks/hooks.json +1 -24
  148. package/plugins/specweave/hooks/run-worker.mjs +37 -2
  149. package/plugins/specweave/hooks/run.mjs +54 -1
  150. package/plugins/specweave/marketplace.json +6 -0
  151. package/plugins/specweave/skills/increment/SKILL.md +7 -5
  152. package/plugins/specweave/skills/jev/SKILL.md +201 -0
  153. package/src/templates/AGENTS.md.template +27 -5
  154. package/src/templates/CLAUDE.md.template +27 -5
  155. package/dist/dashboard/assets/index-BiJhGDZV.js +0 -13
  156. package/dist/dashboard/assets/index-heYRtWFf.css +0 -1
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Jev — the single redaction choke point.
3
+ *
4
+ * Every byte that leaves this machine for the System One endpoint goes through
5
+ * {@link redactSecrets} first: the client scrubs the serialized state before any
6
+ * request, and the PreToolUse Bash guard scrubs the command text it scores.
7
+ * One function, one set of patterns, one set of markers — a second copy is how a
8
+ * key eventually ships.
9
+ *
10
+ * Layers, in order:
11
+ * 1. the shared handoff scrubber (`sk-…`, `sk-or-…`, `ghp_`/`gho_`/`ghs_`,
12
+ * `vsk_`, `xox[abp]-`, `AKIA…`/`ASIA…`, `Bearer …`, PEM headers,
13
+ * `password=`, `api_key=`);
14
+ * 2. key shapes it does not carry (`github_pat_…`, JWT-looking `eyJ….….…`);
15
+ * 3. command-shaped secrets (`scheme:// USER : PASS @host`, `--otp=`/`--token …`,
16
+ * `SOMETHING_TOKEN=value`).
17
+ *
18
+ * Later layers carry a `(?!\[REDACTED)` guard so an already-masked span is never
19
+ * masked twice. Markers are normalised to `<REDACTED-…>` at the end: masking
20
+ * removes text, and removed text could otherwise turn a command the guard's
21
+ * prefilter calls 'check' into one it calls 'skip' (`echo PASSWORD="x; rm -rf ~"`
22
+ * → `echo PASSWORD=<…>`). `<` is in the prefilter's shell-power set, so a
23
+ * redacted command always still reaches Jev.
24
+ *
25
+ * HEURISTIC, never a guarantee: zero redactions does not mean the text is clean.
26
+ * That is why every Jev integration is opt-in and the docs state the export.
27
+ *
28
+ * @module core/jev/redact
29
+ */
30
+ /**
31
+ * Mask secret-shaped values before text leaves this machine.
32
+ *
33
+ * The markers keep the text's shape, so a command still scores the same way for
34
+ * scope and destructiveness and a state object still reads the same way.
35
+ *
36
+ * @param text - anything about to be sent to the System One endpoint
37
+ * @returns the redacted text and how many spans were masked (0 = nothing matched,
38
+ * which is not the same as "clean")
39
+ */
40
+ export declare function redactSecrets(text: string): {
41
+ text: string;
42
+ redactions: number;
43
+ };
44
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../../../src/core/jev/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AA4DH;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAiBhF"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Jev — the single redaction choke point.
3
+ *
4
+ * Every byte that leaves this machine for the System One endpoint goes through
5
+ * {@link redactSecrets} first: the client scrubs the serialized state before any
6
+ * request, and the PreToolUse Bash guard scrubs the command text it scores.
7
+ * One function, one set of patterns, one set of markers — a second copy is how a
8
+ * key eventually ships.
9
+ *
10
+ * Layers, in order:
11
+ * 1. the shared handoff scrubber (`sk-…`, `sk-or-…`, `ghp_`/`gho_`/`ghs_`,
12
+ * `vsk_`, `xox[abp]-`, `AKIA…`/`ASIA…`, `Bearer …`, PEM headers,
13
+ * `password=`, `api_key=`);
14
+ * 2. key shapes it does not carry (`github_pat_…`, JWT-looking `eyJ….….…`);
15
+ * 3. command-shaped secrets (`scheme:// USER : PASS @host`, `--otp=`/`--token …`,
16
+ * `SOMETHING_TOKEN=value`).
17
+ *
18
+ * Later layers carry a `(?!\[REDACTED)` guard so an already-masked span is never
19
+ * masked twice. Markers are normalised to `<REDACTED-…>` at the end: masking
20
+ * removes text, and removed text could otherwise turn a command the guard's
21
+ * prefilter calls 'check' into one it calls 'skip' (`echo PASSWORD="x; rm -rf ~"`
22
+ * → `echo PASSWORD=<…>`). `<` is in the prefilter's shell-power set, so a
23
+ * redacted command always still reaches Jev.
24
+ *
25
+ * HEURISTIC, never a guarantee: zero redactions does not mean the text is clean.
26
+ * That is why every Jev integration is opt-in and the docs state the export.
27
+ *
28
+ * @module core/jev/redact
29
+ */
30
+ import { scrubSecrets, totalRedactions } from '../session/handoff-secret-scrub.js';
31
+ /**
32
+ * Key shapes the shared scrubber does not carry.
33
+ *
34
+ * Fixed-literal prefixes, so they can never match inside a `[REDACTED-…]` marker.
35
+ */
36
+ const KEY_SHAPE_PATTERNS = [
37
+ {
38
+ // GitHub fine-grained PAT: `github_pat_11ABCDEF0…`
39
+ type: 'github-pat',
40
+ regex: /github_pat_[A-Za-z0-9_]{20,}/g,
41
+ replace: '[REDACTED-github-pat]',
42
+ },
43
+ {
44
+ // JWT-looking: `eyJhbGciOi….eyJzdWIi….<signature>` (the signature is optional).
45
+ type: 'jwt',
46
+ regex: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}(?:\.[A-Za-z0-9_-]+)?/g,
47
+ replace: '[REDACTED-jwt]',
48
+ },
49
+ ];
50
+ /**
51
+ * Command-shaped secrets: the value is identified by the flag or variable in
52
+ * front of it rather than by its own shape.
53
+ */
54
+ const COMMAND_SECRET_PATTERNS = [
55
+ {
56
+ // `psql postgres:// USER : PASS @host/db`, `git clone https:// U : TOK @github.com/...`
57
+ type: 'url-credentials',
58
+ regex: /([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]*@/gi,
59
+ replace: '$1[REDACTED-url-credentials]@',
60
+ },
61
+ {
62
+ // `npm publish --otp=123456`, `--token <value>`, `--password=…`
63
+ type: 'secret-flag',
64
+ regex: /(?<![\w-])(--?(?:otp|tokens?|passwords?|passwd|secrets?|api[-_]?keys?|access[-_]?tokens?|credentials?)[=\s])(?!\[REDACTED)("[^"]*"|'[^']*'|\S+)/gi,
65
+ replace: '$1[REDACTED-secret-flag]',
66
+ },
67
+ {
68
+ // `GITHUB_TOKEN=ghp_… cmd`, `MY_API_KEY="…"`, `DB_PASSWORD=…`
69
+ type: 'env-secret',
70
+ regex: /(^|[\s;&|(])([A-Za-z_][A-Za-z0-9_]*(?:TOKEN|SECRET|PASSWORD|PASSWD|KEY|CREDENTIALS?)[A-Za-z0-9_]*=)(?!\[REDACTED)("[^"]*"|'[^']*'|\S*)/gi,
71
+ replace: '$1$2[REDACTED-env-secret]',
72
+ },
73
+ ];
74
+ const EXTRA_PATTERNS = [...KEY_SHAPE_PATTERNS, ...COMMAND_SECRET_PATTERNS];
75
+ /**
76
+ * Mask secret-shaped values before text leaves this machine.
77
+ *
78
+ * The markers keep the text's shape, so a command still scores the same way for
79
+ * scope and destructiveness and a state object still reads the same way.
80
+ *
81
+ * @param text - anything about to be sent to the System One endpoint
82
+ * @returns the redacted text and how many spans were masked (0 = nothing matched,
83
+ * which is not the same as "clean")
84
+ */
85
+ export function redactSecrets(text) {
86
+ const base = scrubSecrets(text ?? '');
87
+ let redacted = base.scrubbed;
88
+ let redactions = totalRedactions(base.counts);
89
+ for (const { regex, replace } of EXTRA_PATTERNS) {
90
+ regex.lastIndex = 0;
91
+ const hits = redacted.match(regex);
92
+ if (!hits)
93
+ continue;
94
+ redactions += hits.length;
95
+ regex.lastIndex = 0;
96
+ redacted = redacted.replace(regex, replace);
97
+ }
98
+ if (redactions > 0)
99
+ redacted = redacted.replace(/\[REDACTED-([A-Za-z-]+)\]/g, '<REDACTED-$1>');
100
+ return { text: redacted, redactions };
101
+ }
102
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../../src/core/jev/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AASnF;;;;GAIG;AACH,MAAM,kBAAkB,GAAiC;IACvD;QACE,mDAAmD;QACnD,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,+BAA+B;QACtC,OAAO,EAAE,uBAAuB;KACjC;IACD;QACE,gFAAgF;QAChF,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,mEAAmE;QAC1E,OAAO,EAAE,gBAAgB;KAC1B;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,uBAAuB,GAAiC;IAC5D;QACE,wFAAwF;QACxF,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,+CAA+C;QACtD,OAAO,EAAE,+BAA+B;KACzC;IACD;QACE,gEAAgE;QAChE,IAAI,EAAE,aAAa;QACnB,KAAK,EACH,mJAAmJ;QACrJ,OAAO,EAAE,0BAA0B;KACpC;IACD;QACE,8DAA8D;QAC9D,IAAI,EAAE,YAAY;QAClB,KAAK,EACH,0IAA0I;QAC5I,OAAO,EAAE,2BAA2B;KACrC;CACF,CAAC;AAEF,MAAM,cAAc,GAAiC,CAAC,GAAG,kBAAkB,EAAE,GAAG,uBAAuB,CAAC,CAAC;AAEzG;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACtC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC7B,IAAI,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9C,KAAK,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,cAAc,EAAE,CAAC;QAChD,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC;QAC1B,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;QACpB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,UAAU,GAAG,CAAC;QAAE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,4BAA4B,EAAE,eAAe,CAAC,CAAC;IAE/F,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Jev usage ledger — append-only JSONL at `.specweave/state/jev-usage.jsonl`
3
+ *
4
+ * Every Jev call writes one line (tokens, cost, latency, ok). Reading is tolerant:
5
+ * a truncated or corrupt line is skipped, never thrown. Nothing here stores a key.
6
+ *
7
+ * @module core/jev/usage
8
+ */
9
+ export interface JevUsageRecord {
10
+ at: string;
11
+ kind: string;
12
+ provider: string;
13
+ model: string;
14
+ input_tokens: number;
15
+ output_tokens: number;
16
+ cost?: number;
17
+ latencyMs: number;
18
+ /** Secret-shaped spans masked out of the request state before it was sent. */
19
+ redactions?: number;
20
+ ok: boolean;
21
+ }
22
+ export interface JevUsageSummary {
23
+ calls: number;
24
+ input_tokens: number;
25
+ cost: number;
26
+ byKind: Record<string, number>;
27
+ since?: string;
28
+ }
29
+ /** Absolute path of the ledger for a project root. */
30
+ export declare function usageLogPath(projectRoot: string): string;
31
+ /**
32
+ * Append one record. Best-effort: never throws (the caller is mid-decision).
33
+ * O_APPEND keeps concurrent agents from interleaving partial lines.
34
+ */
35
+ export declare function appendUsage(projectRoot: string, rec: JevUsageRecord): void;
36
+ /** Totals over the whole ledger. Missing file → zeroes. Bad lines → skipped. */
37
+ export declare function readUsageSummary(projectRoot: string): JevUsageSummary;
38
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../../src/core/jev/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAQ1E;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAuCrE"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Jev usage ledger — append-only JSONL at `.specweave/state/jev-usage.jsonl`
3
+ *
4
+ * Every Jev call writes one line (tokens, cost, latency, ok). Reading is tolerant:
5
+ * a truncated or corrupt line is skipped, never thrown. Nothing here stores a key.
6
+ *
7
+ * @module core/jev/usage
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ /** Absolute path of the ledger for a project root. */
12
+ export function usageLogPath(projectRoot) {
13
+ return path.join(projectRoot, '.specweave', 'state', 'jev-usage.jsonl');
14
+ }
15
+ /**
16
+ * Append one record. Best-effort: never throws (the caller is mid-decision).
17
+ * O_APPEND keeps concurrent agents from interleaving partial lines.
18
+ */
19
+ export function appendUsage(projectRoot, rec) {
20
+ try {
21
+ const filePath = usageLogPath(projectRoot);
22
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
23
+ fs.appendFileSync(filePath, JSON.stringify(rec) + '\n', { flag: 'a' });
24
+ }
25
+ catch {
26
+ // Ledger writes are advisory; a full disk must not break a Jev decision.
27
+ }
28
+ }
29
+ /** Totals over the whole ledger. Missing file → zeroes. Bad lines → skipped. */
30
+ export function readUsageSummary(projectRoot) {
31
+ const summary = { calls: 0, input_tokens: 0, cost: 0, byKind: {} };
32
+ let raw;
33
+ try {
34
+ const filePath = usageLogPath(projectRoot);
35
+ if (!fs.existsSync(filePath))
36
+ return summary;
37
+ raw = fs.readFileSync(filePath, 'utf-8');
38
+ }
39
+ catch {
40
+ return summary;
41
+ }
42
+ for (const line of raw.split('\n')) {
43
+ const trimmed = line.trim();
44
+ if (!trimmed)
45
+ continue;
46
+ let rec;
47
+ try {
48
+ rec = JSON.parse(trimmed);
49
+ }
50
+ catch {
51
+ continue;
52
+ }
53
+ if (!rec || typeof rec !== 'object')
54
+ continue;
55
+ summary.calls += 1;
56
+ if (typeof rec.input_tokens === 'number' && Number.isFinite(rec.input_tokens)) {
57
+ summary.input_tokens += rec.input_tokens;
58
+ }
59
+ if (typeof rec.cost === 'number' && Number.isFinite(rec.cost)) {
60
+ summary.cost += rec.cost;
61
+ }
62
+ const kind = typeof rec.kind === 'string' && rec.kind ? rec.kind : 'unknown';
63
+ summary.byKind[kind] = (summary.byKind[kind] ?? 0) + 1;
64
+ if (typeof rec.at === 'string' && rec.at && (!summary.since || rec.at < summary.since)) {
65
+ summary.since = rec.at;
66
+ }
67
+ }
68
+ return summary;
69
+ }
70
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../../src/core/jev/usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function serializeHandoffPointer(root: string, docPath: string): string;
2
+ /** Broken, foreign, escaping relative and relocated foreign-platform paths are ignored. */
3
+ export declare function resolveHandoffPointer(root: string, pointer: string): string | null;
4
+ //# sourceMappingURL=handoff-pointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff-pointer.d.ts","sourceRoot":"","sources":["../../../../src/core/session/handoff-pointer.ts"],"names":[],"mappings":"AASA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAI7E;AAkBD,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAclF"}
@@ -0,0 +1,60 @@
1
+ /** Portable in-project pointers; explicit absolute external destinations stay absolute. */
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { DOC_FORMAT_MARKER, LEGACY_DOC_FORMAT_MARKER } from './handoff-doc-format.js';
5
+ function inside(relative) {
6
+ return relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
7
+ }
8
+ export function serializeHandoffPointer(root, docPath) {
9
+ const absolute = path.resolve(docPath);
10
+ const relative = path.relative(path.resolve(root), absolute);
11
+ return inside(relative) ? relative.replace(/\\/g, '/') : absolute;
12
+ }
13
+ /** Read only a bounded tail: owned handoff documents end with their format marker. */
14
+ function isOwnedHandoff(file) {
15
+ let fd;
16
+ try {
17
+ if (!fs.statSync(file).isFile())
18
+ return false;
19
+ fd = fs.openSync(file, 'r');
20
+ const stat = fs.fstatSync(fd);
21
+ if (!stat.isFile())
22
+ return false;
23
+ const buffer = Buffer.alloc(Math.min(stat.size, 8192));
24
+ const read = fs.readSync(fd, buffer, 0, buffer.length, Math.max(0, stat.size - buffer.length));
25
+ const tail = buffer.subarray(0, read).toString('utf8');
26
+ return [DOC_FORMAT_MARKER, LEGACY_DOC_FORMAT_MARKER].some(marker => tail.includes(`<!-- ${marker} -->`));
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ finally {
32
+ if (fd !== undefined)
33
+ fs.closeSync(fd);
34
+ }
35
+ }
36
+ /** Broken, foreign, escaping relative and relocated foreign-platform paths are ignored. */
37
+ export function resolveHandoffPointer(root, pointer) {
38
+ if (!pointer || pointer.length > 4096 || /[\u0000-\u001f]/.test(pointer))
39
+ return null;
40
+ const absolute = path.isAbsolute(pointer);
41
+ if (!absolute && (path.win32.isAbsolute(pointer) || path.posix.isAbsolute(pointer)))
42
+ return null;
43
+ if (!absolute && pointer.split(/[\\/]/).includes('..'))
44
+ return null;
45
+ const candidate = path.resolve(root, pointer);
46
+ if (!absolute) {
47
+ if (!inside(path.relative(path.resolve(root), candidate)))
48
+ return null;
49
+ // A relative pointer must not escape through a symlink either.
50
+ try {
51
+ if (!inside(path.relative(fs.realpathSync(root), fs.realpathSync(candidate))))
52
+ return null;
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ return isOwnedHandoff(candidate) ? candidate : null;
59
+ }
60
+ //# sourceMappingURL=handoff-pointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff-pointer.js","sourceRoot":"","sources":["../../../../src/core/session/handoff-pointer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"work-handoff.d.ts","sourceRoot":"","sources":["../../../../src/core/session/work-handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAqBH,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,6BAA8B,SAAQ,KAAK;aAC1B,UAAU,EAAE,MAAM,EAAE;gBAApB,UAAU,EAAE,MAAM,EAAE;CAIjD;AAED,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA6ElH;AAMD,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AA8CD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BxD;AA8CD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAIjE"}
1
+ {"version":3,"file":"work-handoff.d.ts","sourceRoot":"","sources":["../../../../src/core/session/work-handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAuBH,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,6BAA8B,SAAQ,KAAK;aAC1B,UAAU,EAAE,MAAM,EAAE;gBAApB,UAAU,EAAE,MAAM,EAAE;CAIjD;AAED,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiFlH;AAMD,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AA8CD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BxD;AA8CD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAIjE"}
@@ -23,6 +23,8 @@ import { getAgentId } from '../tasks/ledger.js';
23
23
  import { loadTaskBoard, nextTask } from '../tasks/task-board.js';
24
24
  import { resolveIncrement, listActiveIncrementIds, readLeaseHours, IncrementResolutionError } from '../tasks/resolve-increment.js';
25
25
  import { parseSpecAcs } from '../tasks/verify-runner.js';
26
+ import { INTENT_BOARD_PATH, readIntentContext } from '../intent/portable-context.js';
27
+ import { serializeHandoffPointer } from './handoff-pointer.js';
26
28
  import { renderHandoffDoc, renderPastePrompt, DOC_FORMAT_MARKER, LEGACY_DOC_FORMAT_MARKER, } from './handoff-doc-format.js';
27
29
  export class AmbiguousActiveIncrementError extends Error {
28
30
  constructor(candidates) {
@@ -75,13 +77,18 @@ export async function buildWorkHandoff(repoRoot, opts = {}) {
75
77
  const { docPath, diffPath } = resolveWritePaths(effectiveRoot, isSpecWeave, incDir, opts.out);
76
78
  // ── Git + scrub ────────────────────────────────────────────────────────
77
79
  const git = captureGitState(effectiveRoot, diffPath);
80
+ const intentRedactions = {};
81
+ const intents = isSpecWeave ? readIntentContext(effectiveRoot, intentRedactions) : undefined;
82
+ const intentLink = intents ? `[Open the intent board](${path.relative(path.dirname(docPath), path.join(effectiveRoot, INTENT_BOARD_PATH)).replace(/\\/g, '/')})` : undefined;
78
83
  const scrubbed = scrubFields({
79
84
  reason: opts.reason,
80
- summary: opts.summary,
85
+ summary: [opts.summary, intents, intentLink].filter(Boolean).join('\n\n') || undefined,
81
86
  next: opts.next,
82
87
  gotcha: opts.gotcha,
83
88
  decisions: [...fileDecisions, ...(opts.decisions ?? [])],
84
89
  });
90
+ for (const [kind, count] of Object.entries(intentRedactions))
91
+ scrubbed.counts[kind] = (scrubbed.counts[kind] ?? 0) + count;
85
92
  scrubDiffFileInPlace(diffPath, scrubbed.counts);
86
93
  const docInput = {
87
94
  docPath,
@@ -247,12 +254,12 @@ function writeDoc(docPath, markdown) {
247
254
  fs.mkdirSync(path.dirname(docPath), { recursive: true });
248
255
  fs.writeFileSync(docPath, markdown, 'utf-8');
249
256
  }
250
- /** `.specweave/state/handoff-latest.txt` → absolute path of the latest doc. */
257
+ /** Keep in-project destinations relative so copying the project preserves its handoff. */
251
258
  function writePointer(effectiveRoot, docPath) {
252
259
  try {
253
260
  const stateDir = path.join(effectiveRoot, '.specweave', 'state');
254
261
  fs.mkdirSync(stateDir, { recursive: true });
255
- fs.writeFileSync(path.join(stateDir, HANDOFF_POINTER_FILE), docPath + '\n', 'utf-8');
262
+ fs.writeFileSync(path.join(stateDir, HANDOFF_POINTER_FILE), serializeHandoffPointer(effectiveRoot, docPath) + '\n', 'utf-8');
256
263
  }
257
264
  catch {
258
265
  // best-effort
@@ -1 +1 @@
1
- {"version":3,"file":"work-handoff.js","sourceRoot":"","sources":["../../../../src/core/session/work-handoff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"work-handoff.js","sourceRoot":"","sources":["../../../../src/core/session/work-handoff.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,7 @@ export declare class DashboardServer {
36
36
  private registerHookRoutes;
37
37
  private mapEventToCategory;
38
38
  }
39
+ /** Get increment detail by reading metadata.json, tasks.md, and spec.md */
39
40
  /** Scan repositories/ directory for cloned repos, with single-repo git fallback */
40
41
  export declare function scanRepositories(projectRoot: string): Array<{
41
42
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../../../../src/dashboard/server/dashboard-server.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAK7D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAcD,qBAAa,eAAe;IAoBd,OAAO,CAAC,OAAO;IAnB3B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAWX;gBAEe,OAAO,EAAE,sBAAsB;IAoBnD,yCAAyC;IACzC,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW;IAwC5C,0CAA0C;IAC1C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAStC,OAAO,CAAC,cAAc;IAyBhB,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAyCzC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBb,aAAa;IAyC3B,sDAAsD;IACtD,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAC,cAAc;YA20BR,eAAe;IA6C7B,OAAO,CAAC,2BAA2B;IAoBnC,OAAO,CAAC,kBAAkB;IAgD1B,OAAO,CAAC,kBAAkB;CAgB3B;AAuHD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CA2GD"}
1
+ {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../../../../src/dashboard/server/dashboard-server.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAK7D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAcD,qBAAa,eAAe;IAoBd,OAAO,CAAC,OAAO;IAnB3B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAWX;gBAEe,OAAO,EAAE,sBAAsB;IAqBnD,yCAAyC;IACzC,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW;IAwC5C,0CAA0C;IAC1C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAStC,OAAO,CAAC,cAAc;IAyBhB,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAyCzC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBb,aAAa;IA6C3B,sDAAsD;IACtD,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAC,cAAc;YA20BR,eAAe;IA6C7B,OAAO,CAAC,2BAA2B;IAoBnC,OAAO,CAAC,kBAAkB;IAgD1B,OAAO,CAAC,kBAAkB;CAgB3B;AA8BD,2EAA2E;AAC3E,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC,CA2GD"}
@@ -1,3 +1,6 @@
1
+ import { registerWorkRoutes } from './routes/work-routes.js';
2
+ import { localRequestError } from './local-request.js';
3
+ import { getIncrementDetail } from './data/work-projection.js';
1
4
  import * as http from 'http';
2
5
  import * as fs from 'fs';
3
6
  import * as path from 'path';
@@ -57,6 +60,7 @@ export class DashboardServer {
57
60
  this.registerDefaultHookHandlers();
58
61
  }
59
62
  this.registerRoutes();
63
+ registerWorkRoutes(this.router, req => this.resolveProject(req)?.root, this.sseManager);
60
64
  }
61
65
  /** Add a new project to the dashboard */
62
66
  addProject(projectRoot) {
@@ -140,7 +144,7 @@ export class DashboardServer {
140
144
  this.server.on('error', (err) => {
141
145
  reject(err);
142
146
  });
143
- this.server.listen(this.options.port, () => {
147
+ this.server.listen(this.options.port, '127.0.0.1', () => {
144
148
  const actualPort = this.server.address()?.port ?? this.options.port;
145
149
  const url = `http://localhost:${actualPort}`;
146
150
  // Write PID file if hooks enabled
@@ -193,6 +197,11 @@ export class DashboardServer {
193
197
  }
194
198
  async handleRequest(req, res) {
195
199
  const url = req.url || '/';
200
+ const address = this.server?.address();
201
+ const port = address && typeof address !== 'string' ? address.port : this.options.port;
202
+ const rejected = localRequestError(req, port);
203
+ if (rejected)
204
+ return sendJson(res, { ok: false, error: rejected }, 403);
196
205
  // CORS preflight — only allow localhost origins
197
206
  if (req.method === 'OPTIONS') {
198
207
  const origin = req.headers.origin || '';
@@ -1220,95 +1229,6 @@ function deepMerge(target, source) {
1220
1229
  return target;
1221
1230
  }
1222
1231
  /** Get increment detail by reading metadata.json, tasks.md, and spec.md */
1223
- async function getIncrementDetail(projectRoot, incrementId) {
1224
- // Search for increment directory
1225
- const incrementsDir = path.join(projectRoot, '.specweave/increments');
1226
- if (!fs.existsSync(incrementsDir))
1227
- return null;
1228
- let incDir = null;
1229
- try {
1230
- const dirs = fs.readdirSync(incrementsDir, { withFileTypes: true });
1231
- for (const d of dirs) {
1232
- if (!d.isDirectory())
1233
- continue;
1234
- if (d.name === incrementId || d.name.startsWith(incrementId)) {
1235
- incDir = path.join(incrementsDir, d.name);
1236
- break;
1237
- }
1238
- }
1239
- }
1240
- catch {
1241
- return null;
1242
- }
1243
- if (!incDir)
1244
- return null;
1245
- // Read metadata
1246
- let metadata = {};
1247
- const metadataPath = path.join(incDir, 'metadata.json');
1248
- if (fs.existsSync(metadataPath)) {
1249
- try {
1250
- metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf-8'));
1251
- }
1252
- catch { /* */ }
1253
- }
1254
- // Parse tasks from tasks.md
1255
- const tasks = [];
1256
- const tasksPath = path.join(incDir, 'tasks.md');
1257
- if (fs.existsSync(tasksPath)) {
1258
- const content = fs.readFileSync(tasksPath, 'utf-8');
1259
- const taskRegex = /###\s+(T-\d+):\s*(.+)/g;
1260
- let match;
1261
- while ((match = taskRegex.exec(content)) !== null) {
1262
- const id = match[1];
1263
- const title = match[2].trim();
1264
- // Find status: look for [x] or [ ] nearby
1265
- const afterMatch = content.slice(match.index, match.index + 500);
1266
- const statusMatch = afterMatch.match(/\*\*Status\*\*:\s*\[([ x])\]/);
1267
- const usMatch = afterMatch.match(/\*\*User Story\*\*:\s*(US-\d+)/);
1268
- const acMatch = afterMatch.match(/\*\*(?:Satisfies ACs?|AC)\*\*:\s*(AC-[^\n]+)/);
1269
- tasks.push({
1270
- id,
1271
- title,
1272
- status: statusMatch?.[1] === 'x' ? 'completed' : 'pending',
1273
- userStory: usMatch?.[1],
1274
- acs: acMatch?.[1]?.split(',').map(s => s.trim()),
1275
- });
1276
- }
1277
- }
1278
- // Parse ACs from spec.md
1279
- const acs = [];
1280
- const specPath = path.join(incDir, 'spec.md');
1281
- if (fs.existsSync(specPath)) {
1282
- const content = fs.readFileSync(specPath, 'utf-8');
1283
- const acRegex = /- \[([ x])\] \*\*(AC-[^*]+)\*\*:\s*(.+)/g;
1284
- let match;
1285
- while ((match = acRegex.exec(content)) !== null) {
1286
- acs.push({
1287
- id: match[2].trim(),
1288
- text: match[3].trim(),
1289
- completed: match[1] === 'x',
1290
- });
1291
- }
1292
- }
1293
- const taskSummary = {
1294
- total: tasks.length,
1295
- completed: tasks.filter(t => t.status === 'completed').length,
1296
- pending: tasks.filter(t => t.status === 'pending').length,
1297
- };
1298
- const acSummary = {
1299
- total: acs.length,
1300
- completed: acs.filter(a => a.completed).length,
1301
- };
1302
- return {
1303
- id: incrementId,
1304
- metadata,
1305
- tasks,
1306
- taskSummary,
1307
- acs,
1308
- acSummary,
1309
- dirName: path.basename(incDir),
1310
- };
1311
- }
1312
1232
  /** Scan repositories/ directory for cloned repos, with single-repo git fallback */
1313
1233
  export function scanRepositories(projectRoot) {
1314
1234
  const reposDir = path.join(projectRoot, 'repositories');