knoxis-helper 1.8.5 → 1.8.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.
|
@@ -81,6 +81,48 @@ function loadTask() {
|
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* When QIG sends a portal task-list or PHASES prompt, the local agent should
|
|
86
|
+
* treat only that text as scope — not a stale multi-goal handoff wrapped by
|
|
87
|
+
* the backend. Unwraps "# Pair Programming Task / ## Goal" when present.
|
|
88
|
+
*/
|
|
89
|
+
function extractScopedOperatorTask(raw) {
|
|
90
|
+
if (!raw) return raw;
|
|
91
|
+
let text = raw.trim();
|
|
92
|
+
|
|
93
|
+
const goalMatch = text.match(/## Goal\s*\n([\s\S]*?)(?=\n## |\n# |$)/i);
|
|
94
|
+
if (goalMatch && text.includes('# Pair Programming Task')) {
|
|
95
|
+
text = goalMatch[1].trim();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const selectedIdx = text.search(/Selected tasks:\s*\n/i);
|
|
99
|
+
if (selectedIdx >= 0) {
|
|
100
|
+
const header = text.includes('Execute the selected tasks')
|
|
101
|
+
? 'Execute the selected tasks exactly as written below.\n'
|
|
102
|
+
: '';
|
|
103
|
+
return (header + text.slice(selectedIdx)).trim();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (/execute the selected tasks/i.test(text)) {
|
|
107
|
+
return text;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (/phases\.md/i.test(text) || /run all unchecked steps/i.test(text)) {
|
|
111
|
+
return text;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return raw.trim();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function isScopedOperatorTask(raw) {
|
|
118
|
+
if (!raw) return false;
|
|
119
|
+
const lower = raw.toLowerCase();
|
|
120
|
+
return lower.includes('selected tasks:')
|
|
121
|
+
|| lower.includes('execute the selected tasks')
|
|
122
|
+
|| lower.includes('phases.md')
|
|
123
|
+
|| lower.includes('steps to complete:');
|
|
124
|
+
}
|
|
125
|
+
|
|
84
126
|
// === LOAD PROJECT CONTEXT (from CLAUDE.md) ===
|
|
85
127
|
function loadProjectContext() {
|
|
86
128
|
const claudeMd = path.join(process.cwd(), 'CLAUDE.md');
|
|
@@ -479,7 +521,9 @@ async function runKitMode(kitMode, task, identity, scaffoldResult) {
|
|
|
479
521
|
// === MAIN ===
|
|
480
522
|
async function main() {
|
|
481
523
|
const kitMode = process.env.KNOXIS_KIT_MODE || null;
|
|
482
|
-
const
|
|
524
|
+
const taskRaw = loadTask();
|
|
525
|
+
const scoped = isScopedOperatorTask(taskRaw);
|
|
526
|
+
const task = scoped ? extractScopedOperatorTask(taskRaw) : taskRaw;
|
|
483
527
|
if (!task && !kitMode) {
|
|
484
528
|
console.error('No task found. Set KNOXIS_TASK_FILE, pass as CLI argument, or include in CLAUDE.md.');
|
|
485
529
|
process.exit(1);
|
|
@@ -527,6 +571,9 @@ async function main() {
|
|
|
527
571
|
console.log('╚══════════════════════════════════════════════════════════════╝');
|
|
528
572
|
console.log('');
|
|
529
573
|
console.log(' Task: ' + task.substring(0, 100) + (task.length > 100 ? '...' : ''));
|
|
574
|
+
if (scoped) {
|
|
575
|
+
console.log(' Scope: portal task-list / PHASES (HANDOFF rounds ignored)');
|
|
576
|
+
}
|
|
530
577
|
console.log(' Session: ' + SESSION_ID);
|
|
531
578
|
console.log(' Recorded: ' + recorder.sessionId);
|
|
532
579
|
persistActiveSession(recorder, identity, { mode: 'interactive', taskHint: task });
|
|
@@ -577,6 +624,9 @@ async function main() {
|
|
|
577
624
|
'- NEVER ask Claude questions. You provide answers and direction only.',
|
|
578
625
|
'- If Claude lists multiple options, pick the most practical one.',
|
|
579
626
|
'- Push for minimal, focused changes. No scope creep.',
|
|
627
|
+
scoped
|
|
628
|
+
? '- SCOPED SESSION: The operator task below is the only scope. Reject doc-only or HANDOFF re-affirmation plans that skip application source changes when the task requires implementation.'
|
|
629
|
+
: '',
|
|
580
630
|
].join('\n');
|
|
581
631
|
|
|
582
632
|
|
|
@@ -590,16 +640,21 @@ async function main() {
|
|
|
590
640
|
appendLog('## Phase 1: Planning\n');
|
|
591
641
|
|
|
592
642
|
const planPrompt = [
|
|
593
|
-
|
|
643
|
+
scoped
|
|
644
|
+
? 'SCOPED TASK (only implement this — ignore unrelated HANDOFF.md round work):\n' + task
|
|
645
|
+
: task,
|
|
594
646
|
'',
|
|
595
647
|
'Before implementing, I need you to:',
|
|
596
648
|
'1. Read the relevant existing code in this workspace',
|
|
597
649
|
'2. Understand the current patterns and conventions',
|
|
598
650
|
'3. Create a brief implementation plan (which files to change, what approach)',
|
|
599
651
|
'4. Note any key decisions or trade-offs you see',
|
|
652
|
+
scoped
|
|
653
|
+
? '5. Plan changes under src/ (application code), not docs-only re-affirmation unless the scoped task explicitly requires docs'
|
|
654
|
+
: '',
|
|
600
655
|
'',
|
|
601
656
|
'Share your plan and then STOP. Do not implement yet. I will review it first.',
|
|
602
|
-
].join('\n');
|
|
657
|
+
].filter(Boolean).join('\n');
|
|
603
658
|
|
|
604
659
|
const phase1Idx = recorder.startStep('understand-plan', 'Claude Code', planPrompt);
|
|
605
660
|
recorder.setStepPrompt(phase1Idx, planPrompt);
|
|
@@ -635,7 +690,13 @@ async function main() {
|
|
|
635
690
|
|
|
636
691
|
const planReviewPrompt = 'Claude produced the following plan:\n\n'
|
|
637
692
|
+ phase1.stdout.substring(0, 8000)
|
|
638
|
-
+ '\n\
|
|
693
|
+
+ '\n\nScoped operator task (authoritative):\n'
|
|
694
|
+
+ task.substring(0, 4000)
|
|
695
|
+
+ '\n\nReview this plan against the scoped task only. Answer any questions Claude asked. '
|
|
696
|
+
+ (scoped
|
|
697
|
+
? 'Reject doc-only or HANDOFF re-affirmation plans that do not implement the scoped task in source code. '
|
|
698
|
+
: '')
|
|
699
|
+
+ 'Approve or suggest specific changes. Then tell Claude to proceed with implementation.';
|
|
639
700
|
const planReviewIdx = recorder.startStep('knoxis-plan-review', 'Knoxis (Groq)', planReviewPrompt);
|
|
640
701
|
recorder.setStepPrompt(planReviewIdx, planReviewPrompt);
|
|
641
702
|
const planReview = await callGroq(groqSystem, planReviewPrompt);
|
|
@@ -656,9 +717,26 @@ async function main() {
|
|
|
656
717
|
console.log('');
|
|
657
718
|
appendLog('## Phase 2: Implementation\n');
|
|
658
719
|
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
|
|
720
|
+
const phase2Prompt = scoped
|
|
721
|
+
? [
|
|
722
|
+
'IMPLEMENTATION PHASE — implement the scoped task in application source code.',
|
|
723
|
+
'',
|
|
724
|
+
'Scoped task (authoritative):',
|
|
725
|
+
task,
|
|
726
|
+
'',
|
|
727
|
+
'Knoxis feedback on your plan:',
|
|
728
|
+
planReview,
|
|
729
|
+
'',
|
|
730
|
+
'Requirements:',
|
|
731
|
+
'- Change application source (e.g. under src/) to complete the scoped task.',
|
|
732
|
+
'- Do NOT spend this phase only updating docs/state/*.md or HANDOFF re-affirmations unless the scoped task explicitly requires documentation.',
|
|
733
|
+
'- Follow existing patterns. Run the most relevant build/test when done.',
|
|
734
|
+
].join('\n')
|
|
735
|
+
: planReview;
|
|
736
|
+
|
|
737
|
+
const phase2Idx = recorder.startStep('implement', 'Claude Code', phase2Prompt);
|
|
738
|
+
recorder.setStepPrompt(phase2Idx, phase2Prompt);
|
|
739
|
+
const phase2 = await runClaudeTurn(phase2Prompt, true);
|
|
662
740
|
appendLog(phase2.stdout.substring(0, 10000) + '\n');
|
|
663
741
|
recorder.completeStep(phase2Idx, phase2.stdout, phase2.code !== 0 ? `exit ${phase2.code}: ${(phase2.stderr || '').slice(0, 200)}` : null);
|
|
664
742
|
|