@harness-engineering/cli 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agents-md-GOFDOUEI.js → agents-md-OTKZE5HH.js} +4 -4
- package/dist/{analyzer-XRCV63KC-CUGBENHK.js → analyzer-XRCV63KC-FALMS3MO.js} +2 -2
- package/dist/{architecture-UJZTBKJ2.js → architecture-3VYDN7MQ.js} +5 -5
- package/dist/{assess-project-S3UOQUQW.js → assess-project-27X2FSZZ.js} +1 -1
- package/dist/bin/harness-mcp.js +15 -15
- package/dist/bin/harness.js +25 -25
- package/dist/{check-phase-gate-SQ2X2Q7T.js → check-phase-gate-IXLFZ6YH.js} +5 -5
- package/dist/{chunk-FXO3EODY.js → chunk-354MCPT3.js} +3 -3
- package/dist/{chunk-OIMJWYWF.js → chunk-3H7JA24B.js} +7 -7
- package/dist/{chunk-WHPZG5TX.js → chunk-3MKQKNY3.js} +6 -6
- package/dist/{chunk-DPG2WNSN.js → chunk-6Y6M3AZA.js} +3 -3
- package/dist/{chunk-JGW4CHIJ.js → chunk-BMNHLKBA.js} +2 -2
- package/dist/{chunk-CFK4RJFP.js → chunk-CTMHHMHQ.js} +15 -3
- package/dist/{chunk-RD75T4XK.js → chunk-D7QXGI6E.js} +2 -2
- package/dist/{chunk-4ITYAEOA.js → chunk-EFWRZHZ7.js} +101 -97
- package/dist/{chunk-V6QYVM6K.js → chunk-IOJGLIEQ.js} +2 -2
- package/dist/{chunk-DU6AUYTA.js → chunk-IXGYIQSR.js} +1 -1
- package/dist/{chunk-T2PQWRRK.js → chunk-JJLOWMGC.js} +2 -2
- package/dist/{chunk-YE7NZ44F.js → chunk-KPBGAB35.js} +2 -2
- package/dist/{chunk-OWJTMHVP.js → chunk-L5UKNGC5.js} +2 -2
- package/dist/{chunk-R5C7ZFON.js → chunk-LHWBQD7F.js} +10 -1
- package/dist/{chunk-KI64IQLS.js → chunk-LISEPDVT.js} +5 -5
- package/dist/{chunk-UJW4POA3.js → chunk-MEIUXTFY.js} +2 -2
- package/dist/{chunk-RPOBWUKV.js → chunk-NZ5AXKRA.js} +1 -1
- package/dist/{chunk-6RXT67Q4.js → chunk-QHFXVVUY.js} +2 -2
- package/dist/{chunk-SQDQMVNE.js → chunk-S2ETJDQJ.js} +6 -6
- package/dist/{chunk-AIFPI3UZ.js → chunk-TM4KFUWP.js} +2 -2
- package/dist/{chunk-PSFJ5YKQ.js → chunk-VGDZAWCJ.js} +335 -177
- package/dist/{chunk-DFWM2SNS.js → chunk-VRA64HYI.js} +2 -2
- package/dist/{chunk-DSXUS6KG.js → chunk-WAFTJFT3.js} +3 -3
- package/dist/{chunk-7BBQ5C7I.js → chunk-XF6RE3JQ.js} +2 -2
- package/dist/{chunk-XC7NR63Q.js → chunk-XNHKXELN.js} +2 -2
- package/dist/{ci-workflow-5WHUEHOF.js → ci-workflow-Y5GBKNZP.js} +4 -4
- package/dist/{dist-SOKOW7BC.js → dist-4CZLCE33.js} +5 -3
- package/dist/{dist-O7MTFDG5.js → dist-S3KCRI7X.js} +3 -1
- package/dist/{docs-AEHPPDKX.js → docs-3MWDPK4S.js} +5 -5
- package/dist/{engine-HYM5SLCD.js → engine-RJXQ5DHK.js} +4 -4
- package/dist/{entropy-6KH5G3NR.js → entropy-OX5LSM4S.js} +5 -5
- package/dist/{feedback-AUP2JK43.js → feedback-OODAP2G2.js} +1 -1
- package/dist/{generate-agent-definitions-OH4RF445.js → generate-agent-definitions-CCREQZEA.js} +5 -5
- package/dist/hooks/adoption-tracker.js +41 -25
- package/dist/hooks/pre-compact-state.js +45 -27
- package/dist/hooks/sentinel-post.js +125 -102
- package/dist/hooks/sentinel-pre.js +70 -53
- package/dist/hooks/telemetry-reporter.js +44 -25
- package/dist/index.js +25 -25
- package/dist/{loader-KWRPA7D5.js → loader-ZICOJBVX.js} +4 -4
- package/dist/{mcp-JTPO5RAK.js → mcp-XX6EIBLL.js} +15 -15
- package/dist/{performance-HW53ZIAF.js → performance-OLZVGMAY.js} +5 -5
- package/dist/{review-pipeline-2R7UBFTG.js → review-pipeline-3QPHMWPC.js} +4 -4
- package/dist/{runtime-BB35PFZY.js → runtime-ZFFIH76Z.js} +4 -4
- package/dist/{security-IDJHGBBH.js → security-7YW3UK2C.js} +1 -1
- package/dist/{state-events-H3GGBKTB.js → state-events-PTWAEGJ2.js} +4 -4
- package/dist/{validate-6SDGP7AH.js → validate-H5SB7X3Z.js} +5 -5
- package/dist/{validate-cross-check-OF3FPM32.js → validate-cross-check-YYVYMSPA.js} +4 -4
- package/package.json +8 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveProjectConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XNHKXELN.js";
|
|
4
4
|
import {
|
|
5
5
|
sanitizePath
|
|
6
6
|
} from "./chunk-W6Y7ZW3Y.js";
|
|
@@ -49,7 +49,7 @@ async function handleValidateProject(input) {
|
|
|
49
49
|
checks.config = "pass";
|
|
50
50
|
const config = configResult.value;
|
|
51
51
|
try {
|
|
52
|
-
const core = await import("./dist-
|
|
52
|
+
const core = await import("./dist-4CZLCE33.js");
|
|
53
53
|
if (typeof core.validateFileStructure === "function" && Array.isArray(config.conventions)) {
|
|
54
54
|
const conventions = config.conventions;
|
|
55
55
|
const structureResult = await core.validateFileStructure(projectPath, conventions);
|
|
@@ -68,7 +68,7 @@ async function handleValidateProject(input) {
|
|
|
68
68
|
} catch {
|
|
69
69
|
}
|
|
70
70
|
try {
|
|
71
|
-
const core = await import("./dist-
|
|
71
|
+
const core = await import("./dist-4CZLCE33.js");
|
|
72
72
|
if (typeof core.validateAgentsMap === "function") {
|
|
73
73
|
const agentsMapPath = path.join(projectPath, "AGENTS.md");
|
|
74
74
|
const agentsResult = await core.validateAgentsMap(agentsMapPath);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateCIWorkflow
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-XF6RE3JQ.js";
|
|
4
|
+
import "./chunk-CTMHHMHQ.js";
|
|
5
|
+
import "./chunk-NZ5AXKRA.js";
|
|
6
|
+
import "./chunk-LHWBQD7F.js";
|
|
7
7
|
import "./chunk-WZJR6SOI.js";
|
|
8
8
|
import "./chunk-QCLOIUMX.js";
|
|
9
9
|
import "./chunk-XARGEOJV.js";
|
|
@@ -525,7 +525,7 @@ import {
|
|
|
525
525
|
writeStrategyDoc,
|
|
526
526
|
writeTaint,
|
|
527
527
|
xssRules
|
|
528
|
-
} from "./chunk-
|
|
528
|
+
} from "./chunk-CTMHHMHQ.js";
|
|
529
529
|
import {
|
|
530
530
|
EXTENSION_MAP,
|
|
531
531
|
EntropyAnalyzer,
|
|
@@ -551,7 +551,7 @@ import {
|
|
|
551
551
|
resetParserCache,
|
|
552
552
|
resolveFileToLayer,
|
|
553
553
|
validateDependencies
|
|
554
|
-
} from "./chunk-
|
|
554
|
+
} from "./chunk-NZ5AXKRA.js";
|
|
555
555
|
import {
|
|
556
556
|
AuthAuditEntrySchema,
|
|
557
557
|
AuthTokenPublicSchema,
|
|
@@ -590,6 +590,7 @@ import {
|
|
|
590
590
|
ProposalStatusSchema,
|
|
591
591
|
ProposalTypeSchema,
|
|
592
592
|
REQUIRED_STRATEGY_SECTIONS,
|
|
593
|
+
RoutingError,
|
|
593
594
|
SESSIONS_DEFAULTS,
|
|
594
595
|
SESSION_SECTION_NAMES,
|
|
595
596
|
STANDARD_COGNITIVE_MODES,
|
|
@@ -606,7 +607,7 @@ import {
|
|
|
606
607
|
isErr,
|
|
607
608
|
isOk,
|
|
608
609
|
migrateProposalRecord
|
|
609
|
-
} from "./chunk-
|
|
610
|
+
} from "./chunk-LHWBQD7F.js";
|
|
610
611
|
import "./chunk-WZJR6SOI.js";
|
|
611
612
|
import {
|
|
612
613
|
ArchBaselineSchema,
|
|
@@ -807,6 +808,7 @@ export {
|
|
|
807
808
|
ROADMAP_READ_ALLOWLIST,
|
|
808
809
|
RUNNER_PRESETS,
|
|
809
810
|
RegressionDetector,
|
|
811
|
+
RoutingError,
|
|
810
812
|
RuleRegistry,
|
|
811
813
|
SECURITY_DESCRIPTOR,
|
|
812
814
|
SESSIONS_DEFAULTS,
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
ProposalStatusSchema,
|
|
37
37
|
ProposalTypeSchema,
|
|
38
38
|
REQUIRED_STRATEGY_SECTIONS,
|
|
39
|
+
RoutingError,
|
|
39
40
|
SESSIONS_DEFAULTS,
|
|
40
41
|
SESSION_SECTION_NAMES,
|
|
41
42
|
STANDARD_COGNITIVE_MODES,
|
|
@@ -53,7 +54,7 @@ import {
|
|
|
53
54
|
isErr,
|
|
54
55
|
isOk,
|
|
55
56
|
migrateProposalRecord
|
|
56
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-LHWBQD7F.js";
|
|
57
58
|
import "./chunk-KFQGP6VL.js";
|
|
58
59
|
init_dist();
|
|
59
60
|
export {
|
|
@@ -94,6 +95,7 @@ export {
|
|
|
94
95
|
ProposalStatusSchema,
|
|
95
96
|
ProposalTypeSchema,
|
|
96
97
|
REQUIRED_STRATEGY_SECTIONS,
|
|
98
|
+
RoutingError,
|
|
97
99
|
SESSIONS_DEFAULTS,
|
|
98
100
|
SESSION_SECTION_NAMES,
|
|
99
101
|
STANDARD_COGNITIVE_MODES,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
checkDocsDefinition,
|
|
3
3
|
handleCheckDocs
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3MKQKNY3.js";
|
|
5
5
|
import "./chunk-RC3OI5NK.js";
|
|
6
6
|
import "./chunk-W6Y7ZW3Y.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-IOJGLIEQ.js";
|
|
8
8
|
import "./chunk-ZCZD7FHU.js";
|
|
9
9
|
import "./chunk-3WGJMBKH.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-CTMHHMHQ.js";
|
|
11
|
+
import "./chunk-NZ5AXKRA.js";
|
|
12
|
+
import "./chunk-LHWBQD7F.js";
|
|
13
13
|
import "./chunk-WZJR6SOI.js";
|
|
14
14
|
import "./chunk-QCLOIUMX.js";
|
|
15
15
|
import "./chunk-XARGEOJV.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TemplateEngine
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-JJLOWMGC.js";
|
|
4
|
+
import "./chunk-CTMHHMHQ.js";
|
|
5
|
+
import "./chunk-NZ5AXKRA.js";
|
|
6
|
+
import "./chunk-LHWBQD7F.js";
|
|
7
7
|
import "./chunk-WZJR6SOI.js";
|
|
8
8
|
import "./chunk-QCLOIUMX.js";
|
|
9
9
|
import "./chunk-XARGEOJV.js";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectEntropyDefinition,
|
|
3
3
|
handleDetectEntropy
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LISEPDVT.js";
|
|
5
5
|
import "./chunk-RC3OI5NK.js";
|
|
6
6
|
import "./chunk-W6Y7ZW3Y.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-IOJGLIEQ.js";
|
|
8
8
|
import "./chunk-ZCZD7FHU.js";
|
|
9
9
|
import "./chunk-3WGJMBKH.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-CTMHHMHQ.js";
|
|
11
|
+
import "./chunk-NZ5AXKRA.js";
|
|
12
|
+
import "./chunk-LHWBQD7F.js";
|
|
13
13
|
import "./chunk-WZJR6SOI.js";
|
|
14
14
|
import "./chunk-QCLOIUMX.js";
|
|
15
15
|
import "./chunk-XARGEOJV.js";
|
package/dist/{generate-agent-definitions-OH4RF445.js → generate-agent-definitions-CCREQZEA.js}
RENAMED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createGenerateAgentDefinitionsCommand,
|
|
3
3
|
generateAgentDefinitions
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IXGYIQSR.js";
|
|
5
5
|
import "./chunk-KET4QQZB.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-KPBGAB35.js";
|
|
7
7
|
import "./chunk-3ISINLYT.js";
|
|
8
8
|
import "./chunk-UTJJJDNN.js";
|
|
9
9
|
import "./chunk-3WGJMBKH.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-CTMHHMHQ.js";
|
|
11
|
+
import "./chunk-NZ5AXKRA.js";
|
|
12
|
+
import "./chunk-LHWBQD7F.js";
|
|
13
13
|
import "./chunk-WZJR6SOI.js";
|
|
14
14
|
import "./chunk-QCLOIUMX.js";
|
|
15
15
|
import "./chunk-XARGEOJV.js";
|
|
@@ -112,23 +112,56 @@ function deriveDuration(events) {
|
|
|
112
112
|
return max - min;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
/** Read stdin (fd 0) and parse it as JSON. Returns null when it should exit-0. */
|
|
116
|
+
function readStdinJson() {
|
|
117
|
+
let raw;
|
|
117
118
|
try {
|
|
118
119
|
raw = readFileSync(0, 'utf-8');
|
|
119
120
|
} catch {
|
|
120
|
-
|
|
121
|
+
return null;
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
if (!raw.trim()) {
|
|
124
|
-
|
|
125
|
+
return null;
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
let input;
|
|
128
128
|
try {
|
|
129
|
-
|
|
129
|
+
return JSON.parse(raw);
|
|
130
130
|
} catch {
|
|
131
131
|
process.stderr.write('[adoption-tracker] Could not parse stdin — skipping\n');
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Group events by their skill name, preserving order. */
|
|
137
|
+
function groupBySkill(events) {
|
|
138
|
+
const skillGroups = new Map();
|
|
139
|
+
for (const event of events) {
|
|
140
|
+
if (!skillGroups.has(event.skill)) {
|
|
141
|
+
skillGroups.set(event.skill, []);
|
|
142
|
+
}
|
|
143
|
+
skillGroups.get(event.skill).push(event);
|
|
144
|
+
}
|
|
145
|
+
return skillGroups;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Build a single adoption record for one skill's events. */
|
|
149
|
+
function buildRecord(skill, events, allEvents, sessionId) {
|
|
150
|
+
// Use all events for this skill (including non-relevant) for timing
|
|
151
|
+
const allSkillEvents = allEvents.filter((e) => e.skill === skill);
|
|
152
|
+
return {
|
|
153
|
+
skill,
|
|
154
|
+
session: sessionId,
|
|
155
|
+
startedAt: allSkillEvents[0]?.timestamp ?? events[0].timestamp,
|
|
156
|
+
duration: deriveDuration(allSkillEvents.length > 0 ? allSkillEvents : events),
|
|
157
|
+
outcome: deriveOutcome(events),
|
|
158
|
+
phasesReached: derivePhasesReached(events),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function main() {
|
|
163
|
+
const input = readStdinJson();
|
|
164
|
+
if (input === null) {
|
|
132
165
|
process.exit(0);
|
|
133
166
|
}
|
|
134
167
|
|
|
@@ -170,13 +203,7 @@ function main() {
|
|
|
170
203
|
}
|
|
171
204
|
|
|
172
205
|
// Group events by skill
|
|
173
|
-
const skillGroups =
|
|
174
|
-
for (const event of relevantEvents) {
|
|
175
|
-
if (!skillGroups.has(event.skill)) {
|
|
176
|
-
skillGroups.set(event.skill, []);
|
|
177
|
-
}
|
|
178
|
-
skillGroups.get(event.skill).push(event);
|
|
179
|
-
}
|
|
206
|
+
const skillGroups = groupBySkill(relevantEvents);
|
|
180
207
|
|
|
181
208
|
// Reconstruct invocation records
|
|
182
209
|
const sessionId = input.session_id ?? 'unknown';
|
|
@@ -186,18 +213,7 @@ function main() {
|
|
|
186
213
|
|
|
187
214
|
let written = 0;
|
|
188
215
|
for (const [skill, events] of skillGroups) {
|
|
189
|
-
|
|
190
|
-
const allSkillEvents = allEvents.filter((e) => e.skill === skill);
|
|
191
|
-
|
|
192
|
-
const record = {
|
|
193
|
-
skill,
|
|
194
|
-
session: sessionId,
|
|
195
|
-
startedAt: allSkillEvents[0]?.timestamp ?? events[0].timestamp,
|
|
196
|
-
duration: deriveDuration(allSkillEvents.length > 0 ? allSkillEvents : events),
|
|
197
|
-
outcome: deriveOutcome(events),
|
|
198
|
-
phasesReached: derivePhasesReached(events),
|
|
199
|
-
};
|
|
200
|
-
|
|
216
|
+
const record = buildRecord(skill, events, allEvents, sessionId);
|
|
201
217
|
appendFileSync(adoptionFile, JSON.stringify(record) + '\n');
|
|
202
218
|
written++;
|
|
203
219
|
}
|
|
@@ -43,7 +43,11 @@ function findActiveSession(sessionsDir) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Read and validate stdin as JSON. On any failure, writes the matching
|
|
48
|
+
* fail-open stderr message and exits 0. Returns the raw string on success.
|
|
49
|
+
*/
|
|
50
|
+
function readValidStdin() {
|
|
47
51
|
let raw = '';
|
|
48
52
|
try {
|
|
49
53
|
raw = readFileSync(0, 'utf-8');
|
|
@@ -64,39 +68,53 @@ function main() {
|
|
|
64
68
|
process.exit(0);
|
|
65
69
|
}
|
|
66
70
|
|
|
71
|
+
return raw;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Map a decision entry to its display string. */
|
|
75
|
+
function decisionToString(d) {
|
|
76
|
+
return typeof d === 'string' ? d : (d?.decision ?? d?.summary ?? JSON.stringify(d));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The active session's current state string, or null when absent. */
|
|
80
|
+
function sessionCurrentState(session) {
|
|
81
|
+
return session?.state?.currentState ?? null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Last five decisions from harness state, each mapped to a display string. */
|
|
85
|
+
function recentDecisionsFrom(state) {
|
|
86
|
+
const decisions = state?.decisions ?? [];
|
|
87
|
+
return decisions.slice(-5).map(decisionToString);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Current phase: prefer the live session state, fall back to the persisted position. */
|
|
91
|
+
function currentPhaseFrom(state, session) {
|
|
92
|
+
return sessionCurrentState(session) ?? state?.position?.phase ?? null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Build the pre-compact summary object from harness state and active session. */
|
|
96
|
+
function buildSummary(state, session) {
|
|
97
|
+
return {
|
|
98
|
+
timestamp: new Date().toISOString(),
|
|
99
|
+
sessionId: session?.dir ?? null,
|
|
100
|
+
activeStream: sessionCurrentState(session),
|
|
101
|
+
recentDecisions: recentDecisionsFrom(state),
|
|
102
|
+
openQuestions: state?.blockers ?? [],
|
|
103
|
+
currentPhase: currentPhaseFrom(state, session),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function main() {
|
|
108
|
+
readValidStdin();
|
|
109
|
+
|
|
67
110
|
try {
|
|
68
111
|
const cwd = process.cwd();
|
|
69
112
|
const harnessDir = join(cwd, '.harness');
|
|
70
113
|
const stateDir = join(harnessDir, 'state');
|
|
71
114
|
|
|
72
|
-
// Read harness state
|
|
73
115
|
const state = readJsonSafe(join(harnessDir, 'state.json'));
|
|
74
|
-
|
|
75
|
-
// Find active session
|
|
76
116
|
const session = findActiveSession(join(harnessDir, 'sessions'));
|
|
77
|
-
|
|
78
|
-
// Extract recent decisions (last 5)
|
|
79
|
-
const decisions = state?.decisions ?? [];
|
|
80
|
-
const recentDecisions = decisions.slice(-5).map((d) =>
|
|
81
|
-
typeof d === 'string' ? d : (d?.decision ?? d?.summary ?? JSON.stringify(d))
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
// Extract open questions / blockers
|
|
85
|
-
const openQuestions = state?.blockers ?? [];
|
|
86
|
-
|
|
87
|
-
// Determine current phase from session state
|
|
88
|
-
const currentPhase = session?.state?.currentState
|
|
89
|
-
?? (state?.position?.phase ?? null);
|
|
90
|
-
|
|
91
|
-
// Build summary
|
|
92
|
-
const summary = {
|
|
93
|
-
timestamp: new Date().toISOString(),
|
|
94
|
-
sessionId: session?.dir ?? null,
|
|
95
|
-
activeStream: session?.state?.currentState ?? null,
|
|
96
|
-
recentDecisions,
|
|
97
|
-
openQuestions,
|
|
98
|
-
currentPhase,
|
|
99
|
-
};
|
|
117
|
+
const summary = buildSummary(state, session);
|
|
100
118
|
|
|
101
119
|
mkdirSync(stateDir, { recursive: true });
|
|
102
120
|
writeFileSync(
|