knoxis-helper 1.6.2 → 1.6.3

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.
@@ -289,6 +289,52 @@ function readIdentityFromEnv() {
289
289
  };
290
290
  }
291
291
 
292
+ // === STATE-FILE UPDATE PROMPT ===
293
+ // Forces Claude to actually write docs/state/*.md before the session closes.
294
+ // The QIG dashboard reads these files; without this step they stay as scaffold
295
+ // placeholders and the dashboard tiles show "0 done" regardless of what
296
+ // happened in the session.
297
+ function buildUpdateStatePrompt(task) {
298
+ return [
299
+ "Now update the project's state files to reflect what just happened.",
300
+ "This is non-negotiable — the QIG dashboard reads these files and skipping them",
301
+ "means the team loses visibility on what was accomplished.",
302
+ "",
303
+ "**Write the files. Do not describe what you would put in them — actually write them.**",
304
+ "",
305
+ "1. **`docs/state/STATUS.md`** — overwrite. Update `_Last updated:` line. Then:",
306
+ " - `## Done`: one bullet per concrete thing completed in this session.",
307
+ " - `## In flight`: anything started but not finished. Empty if none.",
308
+ " - `## Next`: ONE concrete next step.",
309
+ " - `## Notes`: caveats. Empty if none.",
310
+ "",
311
+ "2. **`docs/state/HANDOFF.md`** — overwrite the whole file:",
312
+ " - `## Where I stopped`: 2-4 sentences (file, function, feature, state).",
313
+ " - `## Why I stopped here`: brief reason.",
314
+ " - `## First thing to do next session`: ONE concrete action with file:line if relevant.",
315
+ " - `## Landmines / gotchas`: anything surprising. \"None.\" if none.",
316
+ " - `## Environment state`: running services / env / branches. \"None.\" if none.",
317
+ "",
318
+ "3. **`docs/state/CHANGELOG.md`** — if code shipped or behavior changed, append a one-line bullet under `## [Unreleased]` in the right section (Added/Changed/Fixed/Removed). Skip if nothing shipped.",
319
+ "",
320
+ "4. **`docs/state/DECISIONS.md`** — if a non-trivial choice was made, append:",
321
+ " ```",
322
+ " ## <today's date>: <one-line title>",
323
+ " **Context:** <2 sentences>",
324
+ " **Decision:** <what you chose>",
325
+ " **Alternatives considered:** <what else and why not>",
326
+ " **Consequences:** <implications>",
327
+ " ```",
328
+ " Skip if no real decisions.",
329
+ "",
330
+ "5. **`docs/state/OPEN_QUESTIONS.md`** — if any genuine unresolved question emerged, append to `## Active`. Skip if none.",
331
+ "",
332
+ "Original task: " + task,
333
+ "",
334
+ "Write the files now. Then briefly summarize which files you wrote and which you skipped."
335
+ ].join('\n');
336
+ }
337
+
292
338
  // === RECORDER + PORTAL FINALIZATION ===
293
339
  // Saves the session JSON locally and POSTs to the portal stub. Called from
294
340
  // every exit path so partial / fallback sessions still surface in the UI.
@@ -517,6 +563,15 @@ async function main() {
517
563
  appendLog('## Phase 3: Verification\n' + phase3b.stdout.substring(0, 5000) + '\n');
518
564
  recorder.completeStep(phase3bIdx, phase3b.stdout, phase3b.code !== 0 ? `exit ${phase3b.code}` : null);
519
565
 
566
+ // Same Phase 4 (update state) as the normal path so the dashboard sees
567
+ // updates even when session-resume failed mid-flow.
568
+ const updateStatePromptFb = buildUpdateStatePrompt(task);
569
+ const phase4bIdx = recorder.startStep('update-state', 'Claude Code', updateStatePromptFb);
570
+ recorder.setStepPrompt(phase4bIdx, updateStatePromptFb);
571
+ const phase4b = await runClaudeTurn(updateStatePromptFb, true);
572
+ appendLog('## Phase 4: Update state files\n' + phase4b.stdout.substring(0, 5000) + '\n');
573
+ recorder.completeStep(phase4bIdx, phase4b.stdout, phase4b.code !== 0 ? `exit ${phase4b.code}` : null);
574
+
520
575
  console.log('');
521
576
  console.log('╔══════════════════════════════════════════════════════════════╗');
522
577
  console.log('║ PAIR PROGRAMMING SESSION COMPLETE ║');
@@ -570,6 +625,26 @@ async function main() {
570
625
  recorder.completeStep(phase3Idx, phase3.stdout, phase3.code !== 0 ? `exit ${phase3.code}` : null);
571
626
 
572
627
 
628
+ // ═══════════════════════════════════════════
629
+ // PHASE 4: UPDATE STATE FILES (non-skippable)
630
+ // The QIG dashboard reads docs/state/*.md from the captured session.
631
+ // Without this step, every dashboard tile shows "0 done" no matter what
632
+ // actually happened during the session.
633
+ // ═══════════════════════════════════════════
634
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
635
+ console.log(' PHASE 4: Update state files');
636
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
637
+ console.log('');
638
+ appendLog('## Phase 4: Update state files\n');
639
+
640
+ const updateStatePrompt = buildUpdateStatePrompt(task);
641
+ const phase4Idx = recorder.startStep('update-state', 'Claude Code', updateStatePrompt);
642
+ recorder.setStepPrompt(phase4Idx, updateStatePrompt);
643
+ const phase4 = await runClaudeTurn(updateStatePrompt, true);
644
+ appendLog(phase4.stdout.substring(0, 5000) + '\n');
645
+ recorder.completeStep(phase4Idx, phase4.stdout, phase4.code !== 0 ? `exit ${phase4.code}` : null);
646
+
647
+
573
648
  // ═══════════════════════════════════════════
574
649
  // DONE
575
650
  // ═══════════════════════════════════════════
@@ -307,6 +307,44 @@ Quick checklist:
307
307
  - Anything we should test?
308
308
 
309
309
  Give me the summary and any follow-up recommendations.`
310
+ },
311
+ {
312
+ key: 'update-state',
313
+ title: 'Update state files',
314
+ template: ({ taskDescription }) => `Now update the project's state files to reflect what just happened. This is non-negotiable — the QIG dashboard reads these files and skipping them means the team loses visibility on what was accomplished.
315
+
316
+ **Write the files. Do not describe what you would put in them — actually write them.**
317
+
318
+ 1. **\`docs/state/STATUS.md\`** — overwrite it. Update the \`_Last updated:\` line to today's date, then:
319
+ - \`## Done\`: one bullet per concrete thing completed in this session (specific file changes, features wired, bugs fixed). Be terse but specific.
320
+ - \`## In flight\`: anything started but not finished. Empty list if none.
321
+ - \`## Next\`: ONE concrete next step for the next session, not a list of wishes.
322
+ - \`## Notes\`: caveats, gotchas, or context that doesn't fit elsewhere. Empty list if none.
323
+
324
+ 2. **\`docs/state/HANDOFF.md\`** — overwrite the whole file:
325
+ - \`## Where I stopped\`: 2-4 sentences. Concrete: file, function, feature, what state.
326
+ - \`## Why I stopped here\`: brief. Finished a chunk / blocked / end of task.
327
+ - \`## First thing to do next session\`: ONE concrete action, not "continue the feature." Reference an exact file:line if applicable.
328
+ - \`## Landmines / gotchas\`: anything that would surprise next-session-me. Write "None." if none.
329
+ - \`## Environment state\`: running services, env vars, open branches, anything not normal config. Write "None." if none.
330
+
331
+ 3. **\`docs/state/CHANGELOG.md\`** — if code shipped or a meaningful behavior changed, append a one-line bullet under \`## [Unreleased]\` in the right section (Added / Changed / Fixed / Removed). If nothing shipped (planning, exploration), don't write anything to CHANGELOG.
332
+
333
+ 4. **\`docs/state/DECISIONS.md\`** — if a non-trivial choice was made (which library, which pattern, which abstraction), append:
334
+ \`\`\`
335
+ ## <today's date>: <one-line decision title>
336
+ **Context:** <2 sentences>
337
+ **Decision:** <what you chose>
338
+ **Alternatives considered:** <what else and why not>
339
+ **Consequences:** <what this implies going forward>
340
+ \`\`\`
341
+ If no real decisions were made, skip this file.
342
+
343
+ 5. **\`docs/state/OPEN_QUESTIONS.md\`** — if any genuine unresolved question emerged (not a question you already answered), append to \`## Active\` as \`### N. <question>\`. Skip if no new questions.
344
+
345
+ The original task was: ${taskDescription}
346
+
347
+ Use that as the frame for what to write. Then briefly summarize which files you wrote and which you skipped (with reason).`
310
348
  }
311
349
  ];
312
350
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knoxis-helper",
3
- "version": "1.6.2",
3
+ "version": "1.6.3",
4
4
  "description": "Local helper for Knoxis pair programming - connects your machine to Knoxis on qig.ai",
5
5
  "bin": {
6
6
  "knoxis-helper": "./bin/knoxis-helper.js"