parallax-opencode 0.3.6 → 0.3.8
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/plugin.js +70 -8
- package/dist-standalone/parallax-engine.js +65 -8
- package/package.json +1 -1
package/dist/plugin.js
CHANGED
|
@@ -96,7 +96,41 @@ function loadConfig() {
|
|
|
96
96
|
// State persistence (Phase 2.1)
|
|
97
97
|
// ---------------------------------------------------------------------------
|
|
98
98
|
let stateDebounceTimer = null;
|
|
99
|
-
function
|
|
99
|
+
function flushState() {
|
|
100
|
+
try {
|
|
101
|
+
const s = getFriction();
|
|
102
|
+
const m = getMode();
|
|
103
|
+
const p = getProtocol();
|
|
104
|
+
const state = {
|
|
105
|
+
sessionId: currentSessionId,
|
|
106
|
+
sessionStart: getTrace(sessionId()).session.startedAt,
|
|
107
|
+
mode: m.mode,
|
|
108
|
+
friction: {
|
|
109
|
+
successes: s.successes,
|
|
110
|
+
trials: s.trials,
|
|
111
|
+
retriesLeft: s.retriesLeft,
|
|
112
|
+
lastObservation: s.lastObservation,
|
|
113
|
+
},
|
|
114
|
+
protocol: {
|
|
115
|
+
ambiguityDone: p.ambiguityDone,
|
|
116
|
+
invariantsDone: p.invariantsDone,
|
|
117
|
+
gateDone: p.gateDone,
|
|
118
|
+
designDone: p.designDone,
|
|
119
|
+
commitDone: p.commitDone,
|
|
120
|
+
summaryDone: p.summaryDone,
|
|
121
|
+
writesBeforeGate: p.writesBeforeGate,
|
|
122
|
+
gateBlocked: p.gateBlocked,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
writeFileSync(STATE_FILE, JSON.stringify(state, null, 2), "utf8");
|
|
126
|
+
}
|
|
127
|
+
catch { }
|
|
128
|
+
}
|
|
129
|
+
function writeState(immediate = false) {
|
|
130
|
+
if (immediate) {
|
|
131
|
+
flushState();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
100
134
|
if (stateDebounceTimer)
|
|
101
135
|
clearTimeout(stateDebounceTimer);
|
|
102
136
|
stateDebounceTimer = setTimeout(() => {
|
|
@@ -104,7 +138,10 @@ function writeState() {
|
|
|
104
138
|
try {
|
|
105
139
|
const s = getFriction();
|
|
106
140
|
const m = getMode();
|
|
107
|
-
|
|
141
|
+
// Read from disk: OpenCode may load plugin in different contexts
|
|
142
|
+
// for tools vs hooks, causing separate in-memory Maps.
|
|
143
|
+
const diskState = readProtocolFromDisk();
|
|
144
|
+
const p = diskState || getProtocol();
|
|
108
145
|
const state = {
|
|
109
146
|
sessionId: currentSessionId,
|
|
110
147
|
sessionStart: getTrace(sessionId()).session.startedAt,
|
|
@@ -134,6 +171,31 @@ function writeState() {
|
|
|
134
171
|
}, STATE_DEBOUNCE_MS);
|
|
135
172
|
}
|
|
136
173
|
// ---------------------------------------------------------------------------
|
|
174
|
+
// Read protocol state from disk (write hook reads this, not in-memory Maps)
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
function readProtocolFromDisk() {
|
|
177
|
+
try {
|
|
178
|
+
if (existsSync(STATE_FILE)) {
|
|
179
|
+
const raw = readFileSync(STATE_FILE, "utf8");
|
|
180
|
+
const s = JSON.parse(raw);
|
|
181
|
+
if (s && s.protocol) {
|
|
182
|
+
return {
|
|
183
|
+
ambiguityDone: s.protocol.ambiguityDone === true,
|
|
184
|
+
invariantsDone: s.protocol.invariantsDone === true,
|
|
185
|
+
gateDone: s.protocol.gateDone === true,
|
|
186
|
+
designDone: s.protocol.designDone === true,
|
|
187
|
+
commitDone: s.protocol.commitDone === true,
|
|
188
|
+
summaryDone: s.protocol.summaryDone === true,
|
|
189
|
+
writesBeforeGate: typeof s.protocol.writesBeforeGate === "number" ? s.protocol.writesBeforeGate : 0,
|
|
190
|
+
gateBlocked: s.protocol.gateBlocked === true,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch { }
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
137
199
|
// Skill loader
|
|
138
200
|
// ---------------------------------------------------------------------------
|
|
139
201
|
const skillCache = {};
|
|
@@ -258,7 +320,7 @@ export default {
|
|
|
258
320
|
if (step === "ambiguity" && !p.ambiguityDone) {
|
|
259
321
|
p.ambiguityDone = true;
|
|
260
322
|
addPhase(sid, "ambiguity_check");
|
|
261
|
-
writeState();
|
|
323
|
+
writeState(true);
|
|
262
324
|
return "[parallax] Step 1/6: Ambiguity Check marked complete.";
|
|
263
325
|
}
|
|
264
326
|
if (step === "invariants") {
|
|
@@ -267,7 +329,7 @@ export default {
|
|
|
267
329
|
}
|
|
268
330
|
p.invariantsDone = true;
|
|
269
331
|
addPhase(sid, "four_invariants");
|
|
270
|
-
writeState();
|
|
332
|
+
writeState(true);
|
|
271
333
|
return "[parallax] Step 2/6: 4 Invariants marked complete.";
|
|
272
334
|
}
|
|
273
335
|
if (step === "gate") {
|
|
@@ -276,7 +338,7 @@ export default {
|
|
|
276
338
|
}
|
|
277
339
|
p.gateDone = true;
|
|
278
340
|
addPhase(sid, "verification_gate");
|
|
279
|
-
writeState();
|
|
341
|
+
writeState(true);
|
|
280
342
|
return "[parallax] Step 3/6: Verification Gate marked complete.";
|
|
281
343
|
}
|
|
282
344
|
if (step === "design") {
|
|
@@ -285,19 +347,19 @@ export default {
|
|
|
285
347
|
}
|
|
286
348
|
p.designDone = true;
|
|
287
349
|
addPhase(sid, "design_check");
|
|
288
|
-
writeState();
|
|
350
|
+
writeState(true);
|
|
289
351
|
return "[parallax] Step 4/6: Design Doc marked complete.";
|
|
290
352
|
}
|
|
291
353
|
if (step === "commit") {
|
|
292
354
|
p.commitDone = true;
|
|
293
355
|
addPhase(sid, "commit_decision");
|
|
294
|
-
writeState();
|
|
356
|
+
writeState(true);
|
|
295
357
|
return "[parallax] Step 5/6: Commit Decision marked complete.";
|
|
296
358
|
}
|
|
297
359
|
if (step === "summary") {
|
|
298
360
|
p.summaryDone = true;
|
|
299
361
|
addPhase(sid, "summary");
|
|
300
|
-
writeState();
|
|
362
|
+
writeState(true);
|
|
301
363
|
// Phase 2.3: Post-session retrospective
|
|
302
364
|
const trace = getTrace(sid);
|
|
303
365
|
const breakdown = computeCoherenceScore(trace);
|
|
@@ -287,14 +287,49 @@ function loadConfig() {
|
|
|
287
287
|
return configCache || {};
|
|
288
288
|
}
|
|
289
289
|
var stateDebounceTimer = null;
|
|
290
|
-
function
|
|
290
|
+
function flushState() {
|
|
291
|
+
try {
|
|
292
|
+
const s = getFriction();
|
|
293
|
+
const m = getMode();
|
|
294
|
+
const p = getProtocol();
|
|
295
|
+
const state = {
|
|
296
|
+
sessionId: currentSessionId,
|
|
297
|
+
sessionStart: getTrace(sessionId()).session.startedAt,
|
|
298
|
+
mode: m.mode,
|
|
299
|
+
friction: {
|
|
300
|
+
successes: s.successes,
|
|
301
|
+
trials: s.trials,
|
|
302
|
+
retriesLeft: s.retriesLeft,
|
|
303
|
+
lastObservation: s.lastObservation
|
|
304
|
+
},
|
|
305
|
+
protocol: {
|
|
306
|
+
ambiguityDone: p.ambiguityDone,
|
|
307
|
+
invariantsDone: p.invariantsDone,
|
|
308
|
+
gateDone: p.gateDone,
|
|
309
|
+
designDone: p.designDone,
|
|
310
|
+
commitDone: p.commitDone,
|
|
311
|
+
summaryDone: p.summaryDone,
|
|
312
|
+
writesBeforeGate: p.writesBeforeGate,
|
|
313
|
+
gateBlocked: p.gateBlocked
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
writeFileSync2(STATE_FILE, JSON.stringify(state, null, 2), "utf8");
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function writeState(immediate = false) {
|
|
321
|
+
if (immediate) {
|
|
322
|
+
flushState();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
291
325
|
if (stateDebounceTimer) clearTimeout(stateDebounceTimer);
|
|
292
326
|
stateDebounceTimer = setTimeout(() => {
|
|
293
327
|
stateDebounceTimer = null;
|
|
294
328
|
try {
|
|
295
329
|
const s = getFriction();
|
|
296
330
|
const m = getMode();
|
|
297
|
-
const
|
|
331
|
+
const diskState = readProtocolFromDisk();
|
|
332
|
+
const p = diskState || getProtocol();
|
|
298
333
|
const state = {
|
|
299
334
|
sessionId: currentSessionId,
|
|
300
335
|
sessionStart: getTrace(sessionId()).session.startedAt,
|
|
@@ -321,6 +356,28 @@ function writeState() {
|
|
|
321
356
|
}
|
|
322
357
|
}, STATE_DEBOUNCE_MS);
|
|
323
358
|
}
|
|
359
|
+
function readProtocolFromDisk() {
|
|
360
|
+
try {
|
|
361
|
+
if (existsSync3(STATE_FILE)) {
|
|
362
|
+
const raw = readFileSync2(STATE_FILE, "utf8");
|
|
363
|
+
const s = JSON.parse(raw);
|
|
364
|
+
if (s && s.protocol) {
|
|
365
|
+
return {
|
|
366
|
+
ambiguityDone: s.protocol.ambiguityDone === true,
|
|
367
|
+
invariantsDone: s.protocol.invariantsDone === true,
|
|
368
|
+
gateDone: s.protocol.gateDone === true,
|
|
369
|
+
designDone: s.protocol.designDone === true,
|
|
370
|
+
commitDone: s.protocol.commitDone === true,
|
|
371
|
+
summaryDone: s.protocol.summaryDone === true,
|
|
372
|
+
writesBeforeGate: typeof s.protocol.writesBeforeGate === "number" ? s.protocol.writesBeforeGate : 0,
|
|
373
|
+
gateBlocked: s.protocol.gateBlocked === true
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
} catch {
|
|
378
|
+
}
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
324
381
|
var skillCache = {};
|
|
325
382
|
function loadSkill(name) {
|
|
326
383
|
if (name in skillCache) return skillCache[name];
|
|
@@ -432,7 +489,7 @@ Use grep and read to investigate ${args.topic} in the codebase, then proceed wit
|
|
|
432
489
|
if (step === "ambiguity" && !p.ambiguityDone) {
|
|
433
490
|
p.ambiguityDone = true;
|
|
434
491
|
addPhase(sid, "ambiguity_check");
|
|
435
|
-
writeState();
|
|
492
|
+
writeState(true);
|
|
436
493
|
return "[parallax] Step 1/6: Ambiguity Check marked complete.";
|
|
437
494
|
}
|
|
438
495
|
if (step === "invariants") {
|
|
@@ -441,7 +498,7 @@ Use grep and read to investigate ${args.topic} in the codebase, then proceed wit
|
|
|
441
498
|
}
|
|
442
499
|
p.invariantsDone = true;
|
|
443
500
|
addPhase(sid, "four_invariants");
|
|
444
|
-
writeState();
|
|
501
|
+
writeState(true);
|
|
445
502
|
return "[parallax] Step 2/6: 4 Invariants marked complete.";
|
|
446
503
|
}
|
|
447
504
|
if (step === "gate") {
|
|
@@ -450,7 +507,7 @@ Use grep and read to investigate ${args.topic} in the codebase, then proceed wit
|
|
|
450
507
|
}
|
|
451
508
|
p.gateDone = true;
|
|
452
509
|
addPhase(sid, "verification_gate");
|
|
453
|
-
writeState();
|
|
510
|
+
writeState(true);
|
|
454
511
|
return "[parallax] Step 3/6: Verification Gate marked complete.";
|
|
455
512
|
}
|
|
456
513
|
if (step === "design") {
|
|
@@ -459,19 +516,19 @@ Use grep and read to investigate ${args.topic} in the codebase, then proceed wit
|
|
|
459
516
|
}
|
|
460
517
|
p.designDone = true;
|
|
461
518
|
addPhase(sid, "design_check");
|
|
462
|
-
writeState();
|
|
519
|
+
writeState(true);
|
|
463
520
|
return "[parallax] Step 4/6: Design Doc marked complete.";
|
|
464
521
|
}
|
|
465
522
|
if (step === "commit") {
|
|
466
523
|
p.commitDone = true;
|
|
467
524
|
addPhase(sid, "commit_decision");
|
|
468
|
-
writeState();
|
|
525
|
+
writeState(true);
|
|
469
526
|
return "[parallax] Step 5/6: Commit Decision marked complete.";
|
|
470
527
|
}
|
|
471
528
|
if (step === "summary") {
|
|
472
529
|
p.summaryDone = true;
|
|
473
530
|
addPhase(sid, "summary");
|
|
474
|
-
writeState();
|
|
531
|
+
writeState(true);
|
|
475
532
|
const trace = getTrace(sid);
|
|
476
533
|
const breakdown = computeCoherenceScore(trace);
|
|
477
534
|
const s = getFriction();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "parallax-opencode",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "PARALLAX ENGINE plugin for OpenCode -- protocol enforcement, friction-loop verification, mode switching (plan/build/debug), trace recording, coherence scoring, CI gate, and PR-ready trace artifacts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/plugin.js",
|