specweave 3.0.3 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/README.md +2 -2
- package/bin/specweave.js +12 -7
- package/bin/startup-check.js +1 -1
- package/dist/src/cli/commands/auto-handoff.d.ts +17 -23
- package/dist/src/cli/commands/auto-handoff.d.ts.map +1 -1
- package/dist/src/cli/commands/auto-handoff.js +140 -65
- package/dist/src/cli/commands/auto-handoff.js.map +1 -1
- package/dist/src/cli/commands/handoff.d.ts +10 -0
- package/dist/src/cli/commands/handoff.d.ts.map +1 -1
- package/dist/src/cli/commands/handoff.js +50 -0
- package/dist/src/cli/commands/handoff.js.map +1 -1
- package/dist/src/cli/commands/jev-helpers.d.ts +1 -1
- package/dist/src/cli/commands/jev-helpers.d.ts.map +1 -1
- package/dist/src/cli/commands/jev-helpers.js +8 -4
- package/dist/src/cli/commands/jev-helpers.js.map +1 -1
- package/dist/src/cli/commands/jev.js +4 -4
- package/dist/src/cli/commands/jev.js.map +1 -1
- package/dist/src/cli/commands/pickup.d.ts +11 -0
- package/dist/src/cli/commands/pickup.d.ts.map +1 -1
- package/dist/src/cli/commands/pickup.js +28 -8
- package/dist/src/cli/commands/pickup.js.map +1 -1
- package/dist/src/cli/helpers/init/gitignore-generator.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/gitignore-generator.js +26 -5
- package/dist/src/cli/helpers/init/gitignore-generator.js.map +1 -1
- package/dist/src/core/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/jev/client.d.ts +4 -1
- package/dist/src/core/jev/client.d.ts.map +1 -1
- package/dist/src/core/jev/client.js +118 -23
- package/dist/src/core/jev/client.js.map +1 -1
- package/dist/src/core/jev/config.d.ts +1 -1
- package/dist/src/core/jev/config.d.ts.map +1 -1
- package/dist/src/core/jev/config.js +8 -3
- package/dist/src/core/jev/config.js.map +1 -1
- package/dist/src/core/jev/openai.d.ts +21 -0
- package/dist/src/core/jev/openai.d.ts.map +1 -0
- package/dist/src/core/jev/openai.js +116 -0
- package/dist/src/core/jev/openai.js.map +1 -0
- package/dist/src/core/jev/usage.d.ts +4 -0
- package/dist/src/core/jev/usage.d.ts.map +1 -1
- package/dist/src/core/jev/usage.js +3 -0
- package/dist/src/core/jev/usage.js.map +1 -1
- package/dist/src/core/session/checkpoint-worker.d.ts +2 -0
- package/dist/src/core/session/checkpoint-worker.d.ts.map +1 -0
- package/dist/src/core/session/checkpoint-worker.js +43 -0
- package/dist/src/core/session/checkpoint-worker.js.map +1 -0
- package/dist/src/core/session/handoff-all.d.ts +124 -0
- package/dist/src/core/session/handoff-all.d.ts.map +1 -0
- package/dist/src/core/session/handoff-all.js +429 -0
- package/dist/src/core/session/handoff-all.js.map +1 -0
- package/dist/src/core/session/handoff-doc-format.d.ts +9 -0
- package/dist/src/core/session/handoff-doc-format.d.ts.map +1 -1
- package/dist/src/core/session/handoff-doc-format.js +28 -4
- package/dist/src/core/session/handoff-doc-format.js.map +1 -1
- package/dist/src/core/session/handoff-git-state.d.ts +3 -1
- package/dist/src/core/session/handoff-git-state.d.ts.map +1 -1
- package/dist/src/core/session/handoff-git-state.js +32 -12
- package/dist/src/core/session/handoff-git-state.js.map +1 -1
- package/dist/src/core/session/handoff-report.js +1 -0
- package/dist/src/core/session/handoff-report.js.map +1 -1
- package/dist/src/core/session/nested-repos.d.ts +90 -0
- package/dist/src/core/session/nested-repos.d.ts.map +1 -0
- package/dist/src/core/session/nested-repos.js +239 -0
- package/dist/src/core/session/nested-repos.js.map +1 -0
- package/dist/src/core/session/pickup.d.ts +1 -0
- package/dist/src/core/session/pickup.d.ts.map +1 -1
- package/dist/src/core/session/pickup.js +4 -4
- package/dist/src/core/session/pickup.js.map +1 -1
- package/dist/src/core/session/session-checkpoint.d.ts +46 -0
- package/dist/src/core/session/session-checkpoint.d.ts.map +1 -0
- package/dist/src/core/session/session-checkpoint.js +262 -0
- package/dist/src/core/session/session-checkpoint.js.map +1 -0
- package/dist/src/core/session/usage-guard.d.ts +59 -51
- package/dist/src/core/session/usage-guard.d.ts.map +1 -1
- package/dist/src/core/session/usage-guard.js +148 -88
- package/dist/src/core/session/usage-guard.js.map +1 -1
- package/dist/src/core/session/work-handoff.d.ts +6 -0
- package/dist/src/core/session/work-handoff.d.ts.map +1 -1
- package/dist/src/core/session/work-handoff.js +55 -13
- package/dist/src/core/session/work-handoff.js.map +1 -1
- package/dist/src/core/tasks/ledger.d.ts +5 -1
- package/dist/src/core/tasks/ledger.d.ts.map +1 -1
- package/dist/src/core/tasks/ledger.js +6 -2
- package/dist/src/core/tasks/ledger.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave/skills/handoff/SKILL.md +54 -9
- package/plugins/specweave/skills/jev/SKILL.md +81 -83
- package/src/templates/AGENTS.md.template +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export class DecisionsAdapterError extends Error {
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
// Application budgets, not claims about provider limits.
|
|
9
|
+
export const DECISIONS_BUDGET = { questions: 40, requestBytes: 512 * 1024, responseBytes: 1024 * 1024 };
|
|
10
|
+
export const DECISIONS_ADAPTER_VERSION = 'openai-decisions-v1';
|
|
11
|
+
function canonical(value) {
|
|
12
|
+
if (Array.isArray(value))
|
|
13
|
+
return value.map(canonical);
|
|
14
|
+
if (value !== null && typeof value === 'object')
|
|
15
|
+
return Object.fromEntries(Object.keys(value).sort().map(k => [k, canonical(value[k])]));
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
export const decisionsEvidenceHash = (request) => createHash('sha256')
|
|
19
|
+
.update(JSON.stringify({ version: DECISIONS_ADAPTER_VERSION, request: canonical(request) })).digest('hex');
|
|
20
|
+
const text = (value) => typeof value === 'string' ? value : JSON.stringify(value);
|
|
21
|
+
const record = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
22
|
+
export function decisionsRequest(model, state, questions) {
|
|
23
|
+
if (model !== 'gpt-6-luna')
|
|
24
|
+
throw new DecisionsAdapterError('validation', 'OpenAI Decisions currently requires gpt-6-luna');
|
|
25
|
+
if (Object.keys(questions).length > DECISIONS_BUDGET.questions) {
|
|
26
|
+
throw new DecisionsAdapterError('validation', 'OpenAI Decisions question budget exceeded');
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
model,
|
|
30
|
+
input: typeof state === 'string' ? state : JSON.stringify(state),
|
|
31
|
+
questions: Object.entries(questions).map(([name, q]) => {
|
|
32
|
+
const instructions = text(q.instructions);
|
|
33
|
+
if (q.type === 'noul')
|
|
34
|
+
return {
|
|
35
|
+
name, type: 'predicate',
|
|
36
|
+
instructions: q.criteria ? `${instructions}\nCriteria: ${JSON.stringify(q.criteria)}` : instructions,
|
|
37
|
+
};
|
|
38
|
+
if (q.type === 'choice')
|
|
39
|
+
return {
|
|
40
|
+
name, type: 'choice', instructions,
|
|
41
|
+
choices: Object.entries(q.criteria).map(([value, description]) => ({ value, description: text(description) })),
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
name, type: 'score', instructions,
|
|
45
|
+
levels: q.criteria.map((description, i) => ({ label: String(i), description: text(description) })),
|
|
46
|
+
};
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Normalize only after checking names, types, exact distributions and score consistency.
|
|
51
|
+
* The shared Jev parser then applies range, membership and probability-sum checks.
|
|
52
|
+
*/
|
|
53
|
+
export function decisionsResponse(payload, questions) {
|
|
54
|
+
if (!record(payload) || !Array.isArray(payload.answers) || payload.answers.length !== Object.keys(questions).length) {
|
|
55
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions returned an invalid answer set');
|
|
56
|
+
}
|
|
57
|
+
const seen = new Set();
|
|
58
|
+
const answers = Object.create(null);
|
|
59
|
+
for (const answer of payload.answers) {
|
|
60
|
+
if (!record(answer) || typeof answer.name !== 'string' || !Object.prototype.hasOwnProperty.call(questions, answer.name) || seen.has(answer.name)) {
|
|
61
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions returned missing, duplicate or unknown answer names');
|
|
62
|
+
}
|
|
63
|
+
const name = answer.name;
|
|
64
|
+
seen.add(name);
|
|
65
|
+
const q = questions[name];
|
|
66
|
+
if (answer.type === 'refusal')
|
|
67
|
+
throw new DecisionsAdapterError('refusal', 'OpenAI Decisions refused a question');
|
|
68
|
+
if (answer.type !== (q.type === 'noul' ? 'predicate' : q.type)) {
|
|
69
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions answer type mismatch');
|
|
70
|
+
}
|
|
71
|
+
if (q.type === 'noul') {
|
|
72
|
+
answers[name] = { type: 'noul', noul: answer.probability };
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!Array.isArray(answer.probabilities))
|
|
76
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions probabilities are missing');
|
|
77
|
+
const allowed = q.type === 'choice' ? Object.keys(q.criteria) : q.criteria.map((_, i) => String(i));
|
|
78
|
+
const probabilities = Object.create(null);
|
|
79
|
+
const legend = Object.create(null);
|
|
80
|
+
for (const entry of answer.probabilities) {
|
|
81
|
+
if (!record(entry) || (q.type === 'choice' ? typeof entry.value !== 'string' : !Number.isInteger(entry.value))) {
|
|
82
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions probability option is invalid');
|
|
83
|
+
}
|
|
84
|
+
const key = String(entry.value);
|
|
85
|
+
if (!allowed.includes(key) || Object.prototype.hasOwnProperty.call(probabilities, key)) {
|
|
86
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions probability option is duplicated or unknown');
|
|
87
|
+
}
|
|
88
|
+
probabilities[key] = entry.probability;
|
|
89
|
+
if (q.type === 'score') {
|
|
90
|
+
if (entry.label !== key)
|
|
91
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions score label disagrees with its level');
|
|
92
|
+
legend[key] = text(q.criteria[Number(key)]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (Object.keys(probabilities).length !== allowed.length) {
|
|
96
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions probability distribution is incomplete');
|
|
97
|
+
}
|
|
98
|
+
if (q.type === 'score') {
|
|
99
|
+
const weighted = Object.entries(probabilities).reduce((sum, [key, p]) => sum + Number(key) * Number(p), 0);
|
|
100
|
+
if (typeof answer.score !== 'number' || !Number.isFinite(weighted) || Math.abs(weighted - answer.score) > 0.001) {
|
|
101
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions score disagrees with its distribution');
|
|
102
|
+
}
|
|
103
|
+
answers[name] = { type: 'score', score: answer.score, probabilities, legend, confidence: answer.confidence };
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
const selected = probabilities[String(answer.choice)];
|
|
107
|
+
const highest = Math.max(...Object.values(probabilities).map(Number));
|
|
108
|
+
if (typeof selected === 'number' && selected + 0.000001 < highest) {
|
|
109
|
+
throw new DecisionsAdapterError('schema', 'OpenAI Decisions selected a lower-probability choice');
|
|
110
|
+
}
|
|
111
|
+
answers[name] = { type: 'choice', choice: answer.choice, probabilities, confidence: answer.confidence };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return { ...payload, answers };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../../src/core/jev/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,9 +17,13 @@ export interface JevUsageRecord {
|
|
|
17
17
|
latencyMs: number;
|
|
18
18
|
/** Secret-shaped spans masked out of the request state before it was sent. */
|
|
19
19
|
redactions?: number;
|
|
20
|
+
requestId?: string;
|
|
21
|
+
evidenceHash?: string;
|
|
20
22
|
ok: boolean;
|
|
21
23
|
}
|
|
22
24
|
export interface JevUsageSummary {
|
|
25
|
+
/** Count of calls whose cost was not supplied; cost is only the known subtotal. */
|
|
26
|
+
unknownCostCalls?: number;
|
|
23
27
|
calls: number;
|
|
24
28
|
input_tokens: number;
|
|
25
29
|
cost: number;
|
|
@@ -1 +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,
|
|
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,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,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,CAyCrE"}
|
|
@@ -59,6 +59,9 @@ export function readUsageSummary(projectRoot) {
|
|
|
59
59
|
if (typeof rec.cost === 'number' && Number.isFinite(rec.cost)) {
|
|
60
60
|
summary.cost += rec.cost;
|
|
61
61
|
}
|
|
62
|
+
else {
|
|
63
|
+
summary.unknownCostCalls = (summary.unknownCostCalls ?? 0) + 1;
|
|
64
|
+
}
|
|
62
65
|
const kind = typeof rec.kind === 'string' && rec.kind ? rec.kind : 'unknown';
|
|
63
66
|
summary.byKind[kind] = (summary.byKind[kind] ?? 0) + 1;
|
|
64
67
|
if (typeof rec.at === 'string' && rec.at && (!summary.since || rec.at < summary.since)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../../src/core/jev/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../../src/core/jev/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AA4B7B,sDAAsD;AACtD,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;AAC1E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB,EAAE,GAAmB;IAClE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAC3C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,MAAM,OAAO,GAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAEpF,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,OAAO,CAAC;QAC7C,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,GAA4B,CAAC;QACjC,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,SAAS;QAE9C,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACnB,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9E,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,YAAY,CAAC;QAC3C,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,gBAAgB,GAAG,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAEvD,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvF,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-worker.d.ts","sourceRoot":"","sources":["../../../../src/core/session/checkpoint-worker.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** A detached supervisor enforces the wall-clock budget even while Git blocks synchronously. */
|
|
2
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { CHECKPOINT_WORKER_TIMEOUT_MS, cleanupCheckpointRequest, runSessionCheckpoint } from './session-checkpoint.js';
|
|
5
|
+
const requestPath = process.argv[2];
|
|
6
|
+
if (requestPath) {
|
|
7
|
+
if (process.argv[3] === '--capture') {
|
|
8
|
+
void runSessionCheckpoint(requestPath).then(() => process.exit(0), () => process.exit(1));
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
const child = spawn(process.execPath, [fileURLToPath(import.meta.url), requestPath, '--capture'], {
|
|
12
|
+
stdio: 'ignore', windowsHide: true, detached: process.platform !== 'win32',
|
|
13
|
+
});
|
|
14
|
+
const stopOwnProcessTree = () => {
|
|
15
|
+
if (!child.pid)
|
|
16
|
+
return;
|
|
17
|
+
try {
|
|
18
|
+
if (process.platform === 'win32') {
|
|
19
|
+
spawnSync('taskkill', ['/PID', String(child.pid), '/T', '/F'], { stdio: 'ignore', windowsHide: true, timeout: 1000 });
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// This process group was created above. It also contains any Git
|
|
23
|
+
// helpers orphaned when a timed-out synchronous Git call was killed.
|
|
24
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch { /* already exited */ }
|
|
28
|
+
};
|
|
29
|
+
const timer = setTimeout(stopOwnProcessTree, CHECKPOINT_WORKER_TIMEOUT_MS);
|
|
30
|
+
let finished = false;
|
|
31
|
+
const finish = () => {
|
|
32
|
+
if (finished)
|
|
33
|
+
return;
|
|
34
|
+
finished = true;
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
stopOwnProcessTree();
|
|
37
|
+
cleanupCheckpointRequest(requestPath);
|
|
38
|
+
};
|
|
39
|
+
child.once('error', finish);
|
|
40
|
+
child.once('exit', finish);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=checkpoint-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-worker.js","sourceRoot":"","sources":["../../../../src/core/session/checkpoint-worker.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEvH,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,WAAW,EAAE,CAAC;IAChB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QACpC,KAAK,oBAAoB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5F,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE;YAChG,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SAC3E,CAAC,CAAC;QACH,MAAM,kBAAkB,GAAG,GAAG,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,GAAG;gBAAE,OAAO;YACvB,IAAI,CAAC;gBACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;oBACjC,SAAS,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACxH,CAAC;qBAAM,CAAC;oBACN,iEAAiE;oBACjE,qEAAqE;oBACrE,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAClC,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;QAC3E,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,kBAAkB,EAAE,CAAC;YACrB,wBAAwB,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff index: `specweave handoff --all` and `specweave pickup --all`.
|
|
3
|
+
*
|
|
4
|
+
* One read for switching accounts or tools with many increments in flight.
|
|
5
|
+
* `handoff --all` writes `.specweave/handoffs/<YYYY-MM-DD>-INDEX.md` plus
|
|
6
|
+
* `.specweave/handoffs/index.json` with one row per active increment (tasks,
|
|
7
|
+
* open ACs, last activity, what it waits on, a paste-ready resume prompt) and,
|
|
8
|
+
* in an umbrella workspace, every nested checkout holding work that exists only
|
|
9
|
+
* on this machine. `pickup --all` prints the newest index, actionable rows
|
|
10
|
+
* first.
|
|
11
|
+
*
|
|
12
|
+
* Read-only toward everything but the index files: no ledger events, no claims
|
|
13
|
+
* released, nothing committed or pushed, in the umbrella or in nested repos.
|
|
14
|
+
*
|
|
15
|
+
* @module core/session/handoff-all
|
|
16
|
+
*/
|
|
17
|
+
import { type PrLookup } from './nested-repos.js';
|
|
18
|
+
export declare const HANDOFFS_DIR = ".specweave/handoffs";
|
|
19
|
+
export declare const INDEX_JSON_FILE = "index.json";
|
|
20
|
+
/** Generator marker: an INDEX file without it was written by a person and is left alone. */
|
|
21
|
+
export declare const INDEX_MARKER = "<!-- Handoff index v1 -->";
|
|
22
|
+
export interface IndexRepo {
|
|
23
|
+
path: string;
|
|
24
|
+
branch: string;
|
|
25
|
+
sha: string;
|
|
26
|
+
dirty: number;
|
|
27
|
+
ahead: number;
|
|
28
|
+
noRemote: boolean;
|
|
29
|
+
upstream?: string;
|
|
30
|
+
lastCommitAt?: string;
|
|
31
|
+
pr?: {
|
|
32
|
+
number: number;
|
|
33
|
+
url: string;
|
|
34
|
+
state: string;
|
|
35
|
+
isDraft: boolean;
|
|
36
|
+
};
|
|
37
|
+
increments: string[];
|
|
38
|
+
}
|
|
39
|
+
export interface IndexRow {
|
|
40
|
+
id: string;
|
|
41
|
+
title: string;
|
|
42
|
+
status: string;
|
|
43
|
+
tasksDone: number;
|
|
44
|
+
tasksTotal: number;
|
|
45
|
+
openAcs: string[];
|
|
46
|
+
totalAcs: number;
|
|
47
|
+
lastActivityAt?: string;
|
|
48
|
+
/** What the increment waits on (a person, a decision), from `wait` events and handoff.md. */
|
|
49
|
+
waits: string[];
|
|
50
|
+
/** Repo-relative handoff docs that exist for it (`handoff.md`, `handoff.auto.md`). */
|
|
51
|
+
handoffDocs: string[];
|
|
52
|
+
/** Nested checkouts with local-only work whose path or branch carries this increment's id. */
|
|
53
|
+
repos: string[];
|
|
54
|
+
resumePrompt: string;
|
|
55
|
+
}
|
|
56
|
+
export interface HandoffIndex {
|
|
57
|
+
version: 1;
|
|
58
|
+
generatedAt: string;
|
|
59
|
+
/** Local date, YYYY-MM-DD. */
|
|
60
|
+
date: string;
|
|
61
|
+
root: string;
|
|
62
|
+
agent: string;
|
|
63
|
+
reason?: string;
|
|
64
|
+
rows: IndexRow[];
|
|
65
|
+
/** Absent when the workspace has no `repositories/` folder or the scan was skipped. */
|
|
66
|
+
repos?: {
|
|
67
|
+
scanned: number;
|
|
68
|
+
flagged: IndexRepo[];
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface HandoffIndexOptions {
|
|
72
|
+
reason?: string;
|
|
73
|
+
agent?: string;
|
|
74
|
+
/** Scan nested repos (default: when `repositories/` exists). */
|
|
75
|
+
scanRepos?: boolean;
|
|
76
|
+
/** PR lookup for the nested scan (default: gh when installed); `false` skips it. */
|
|
77
|
+
prLookup?: PrLookup | false;
|
|
78
|
+
now?: Date;
|
|
79
|
+
}
|
|
80
|
+
export interface WriteIndexOptions extends HandoffIndexOptions {
|
|
81
|
+
/** Directory to write into (default `.specweave/handoffs`). */
|
|
82
|
+
outDir?: string;
|
|
83
|
+
/** Build and render only; write nothing. */
|
|
84
|
+
dryRun?: boolean;
|
|
85
|
+
}
|
|
86
|
+
export interface WriteIndexResult {
|
|
87
|
+
index: HandoffIndex;
|
|
88
|
+
markdown: string;
|
|
89
|
+
mdPath: string;
|
|
90
|
+
jsonPath: string;
|
|
91
|
+
written: boolean;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Open waits of an increment: `wait` ledger events after the last clearing one,
|
|
95
|
+
* then "Waits on" / "Waiting on" lines (or a section with that heading) in its
|
|
96
|
+
* handoff docs.
|
|
97
|
+
*/
|
|
98
|
+
export declare function readWaits(incDir: string): string[];
|
|
99
|
+
/** "Waits on: X", "**Waiting on Anton:** X", or bullets under a "## Waiting on …" heading. */
|
|
100
|
+
export declare function parseWaitLines(text: string): string[];
|
|
101
|
+
export declare function buildResumePrompt(root: string, row: Omit<IndexRow, 'resumePrompt'>, repos: IndexRepo[]): string;
|
|
102
|
+
/** Build the index. Never writes. */
|
|
103
|
+
export declare function buildHandoffIndex(root: string, opts?: HandoffIndexOptions): Promise<HandoffIndex>;
|
|
104
|
+
/** Rows without waits first, then waiting rows; newest activity first inside each group. */
|
|
105
|
+
export declare function sortRows(rows: IndexRow[]): {
|
|
106
|
+
actionable: IndexRow[];
|
|
107
|
+
waiting: IndexRow[];
|
|
108
|
+
};
|
|
109
|
+
/** Render INDEX.md. `keep` blocks from the previous version go under the header. */
|
|
110
|
+
export declare function renderHandoffIndex(index: HandoffIndex, keep?: string[]): string;
|
|
111
|
+
/** Build, render and (unless `dryRun`) write INDEX.md and index.json. */
|
|
112
|
+
export declare function writeHandoffIndex(root: string, opts?: WriteIndexOptions): Promise<WriteIndexResult>;
|
|
113
|
+
export interface LatestIndex {
|
|
114
|
+
index?: HandoffIndex & {
|
|
115
|
+
markdown?: string;
|
|
116
|
+
};
|
|
117
|
+
/** The newest INDEX markdown file, when there is one. */
|
|
118
|
+
mdPath?: string;
|
|
119
|
+
}
|
|
120
|
+
/** The newest index: `index.json` when present, else the newest `*-INDEX*.md` file. */
|
|
121
|
+
export declare function readLatestIndex(root: string): LatestIndex;
|
|
122
|
+
/** What `pickup --all` prints: actionable rows first, then waiting rows, then local-only repos. */
|
|
123
|
+
export declare function renderPickupAll(root: string, latest: LatestIndex, now?: Date): string;
|
|
124
|
+
//# sourceMappingURL=handoff-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff-all.d.ts","sourceRoot":"","sources":["../../../../src/core/session/handoff-all.ts"],"names":[],"mappings":"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"}
|