aiwcli 0.12.6 → 0.12.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/bin/dev.cmd +3 -3
- package/bin/dev.js +16 -16
- package/bin/run.cmd +3 -3
- package/bin/run.js +21 -21
- package/dist/commands/branch.js +7 -2
- package/dist/lib/bmad-installer.js +37 -37
- package/dist/lib/terminal.d.ts +2 -0
- package/dist/lib/terminal.js +57 -7
- package/dist/templates/CLAUDE.md +232 -205
- package/dist/templates/_shared/.claude/settings.json +65 -65
- package/dist/templates/_shared/.claude/{commands/handoff.md → skills/handoff/SKILL.md} +13 -12
- package/dist/templates/_shared/.claude/{commands/handoff-resume.md → skills/handoff-resume/SKILL.md} +13 -12
- package/dist/templates/_shared/.codex/workflows/handoff.md +226 -226
- package/dist/templates/_shared/.windsurf/workflows/handoff.md +226 -226
- package/dist/templates/_shared/handoff-system/CLAUDE.md +15 -3
- package/dist/templates/_shared/handoff-system/lib/document-generator.ts +215 -215
- package/dist/templates/_shared/handoff-system/lib/handoff-reader.ts +158 -158
- package/dist/templates/_shared/handoff-system/scripts/resume_handoff.ts +373 -373
- package/dist/templates/_shared/handoff-system/scripts/save_handoff.ts +469 -469
- package/dist/templates/_shared/handoff-system/workflows/handoff-resume.md +66 -66
- package/dist/templates/_shared/handoff-system/workflows/handoff.md +254 -254
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -2
- package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -159
- package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -147
- package/dist/templates/_shared/hooks-ts/file-suggestion.ts +128 -128
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -49
- package/dist/templates/_shared/hooks-ts/session_end.ts +196 -196
- package/dist/templates/_shared/hooks-ts/session_start.ts +163 -163
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -48
- package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -74
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +93 -93
- package/dist/templates/_shared/lib-ts/CLAUDE.md +367 -367
- package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -138
- package/dist/templates/_shared/lib-ts/base/constants.ts +24 -6
- package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -58
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +582 -582
- package/dist/templates/_shared/lib-ts/base/inference.ts +301 -301
- package/dist/templates/_shared/lib-ts/base/logger.ts +247 -247
- package/dist/templates/_shared/lib-ts/base/state-io.ts +202 -202
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -184
- package/dist/templates/_shared/lib-ts/base/utils.ts +184 -184
- package/dist/templates/_shared/lib-ts/context/CLAUDE.md +134 -0
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +566 -566
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +524 -524
- package/dist/templates/_shared/lib-ts/context/context-store.ts +712 -712
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +312 -312
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -185
- package/dist/templates/_shared/lib-ts/package.json +20 -20
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +102 -102
- package/dist/templates/_shared/lib-ts/templates/plan-context.ts +58 -58
- package/dist/templates/_shared/lib-ts/tsconfig.json +13 -13
- package/dist/templates/_shared/lib-ts/types.ts +186 -186
- package/dist/templates/_shared/scripts/resolve_context.ts +33 -33
- package/dist/templates/_shared/scripts/status_line.ts +687 -690
- package/dist/templates/cc-native/.claude/commands/cc-native/rlm/ask.md +136 -136
- package/dist/templates/cc-native/.claude/commands/cc-native/rlm/index.md +21 -21
- package/dist/templates/cc-native/.claude/commands/cc-native/rlm/overview.md +56 -56
- package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +10 -10
- package/dist/templates/cc-native/.claude/settings.json +3 -2
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/fix.md +8 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/implement.md +8 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/research.md +8 -8
- package/dist/templates/cc-native/CC-NATIVE-README.md +189 -189
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +304 -304
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +143 -143
- package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +213 -213
- package/dist/templates/cc-native/_cc-native/agents/plan-questions/PLAN-QUESTIONER.md +70 -70
- package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +64 -0
- package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/format.ts +1 -1
- package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/write.ts +2 -2
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +96 -96
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +14 -24
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +1 -1
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +54 -54
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +51 -51
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +53 -53
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -61
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +76 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +9 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +319 -319
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -144
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -57
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -83
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +79 -79
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +4 -4
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -168
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +80 -80
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +41 -41
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/CLAUDE.md +480 -480
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +287 -287
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +148 -148
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +54 -54
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +58 -58
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +208 -208
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +460 -460
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +446 -446
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +280 -280
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +274 -274
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +201 -201
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +278 -278
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +184 -184
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +275 -275
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -18
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +1 -1
- package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +149 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +143 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +213 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +70 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +56 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +53 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +66 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +70 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +72 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +64 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +56 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +86 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +59 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +58 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +66 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +66 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +71 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +74 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +77 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +68 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +71 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +67 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +65 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +74 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +69 -0
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/agent-selection.ts +3 -3
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/corroboration.ts +1 -1
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/graduation.ts +1 -1
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/orchestrator.ts +2 -2
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/output-builder.ts +3 -3
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/plan-questions.ts +6 -6
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/review-pipeline.ts +15 -15
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/agent.ts +5 -5
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/base/base-agent.ts +4 -4
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/claude-agent.ts +4 -4
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/codex-agent.ts +6 -6
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/gemini-agent.ts +1 -1
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/orchestrator-claude-agent.ts +4 -4
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/types.ts +3 -3
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/verdict.ts +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +108 -108
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +0 -21
- package/dist/templates/cc-native/_cc-native/lib-ts/nul +0 -3
- /package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/index.ts +0 -0
- /package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/tracker.ts +0 -0
- /package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/index.ts +0 -0
- /package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/schemas.ts +0 -0
- /package/dist/templates/cc-native/_cc-native/{workflows → plan-review/workflows}/specdev.md +0 -0
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-context debug logging for cc-native hooks.
|
|
3
|
-
* Thin delegation layer over the unified logger.
|
|
4
|
-
* See cc-native-plan-review-spec.md §4.13
|
|
5
|
-
*
|
|
6
|
-
* Can be disabled via CCNATIVE_DEBUG_DISABLE=1 environment variable.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import * as fs from "node:fs";
|
|
1
|
+
/**
|
|
2
|
+
* Per-context debug logging for cc-native hooks.
|
|
3
|
+
* Thin delegation layer over the unified logger.
|
|
4
|
+
* See cc-native-plan-review-spec.md §4.13
|
|
5
|
+
*
|
|
6
|
+
* Can be disabled via CCNATIVE_DEBUG_DISABLE=1 environment variable.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as fs from "node:fs";
|
|
10
10
|
import * as path from "node:path";
|
|
11
|
-
|
|
12
|
-
import { hookLog } from "../../_shared/lib-ts/base/logger.js";
|
|
13
|
-
|
|
14
|
-
/** Feature flag — set CCNATIVE_DEBUG_DISABLE=1 to turn off */
|
|
15
|
-
const DEBUG_ENABLED = !["1", "true", "yes"].includes(
|
|
16
|
-
(process.env.CCNATIVE_DEBUG_DISABLE ?? "").toLowerCase(),
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Get or create debug directory within context folder.
|
|
21
|
-
*/
|
|
22
|
-
export function getDebugDir(contextPath: string): string {
|
|
23
|
-
const debugDir = path.join(contextPath, "debug");
|
|
24
|
-
fs.mkdirSync(debugDir, { recursive: true });
|
|
25
|
-
return debugDir;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Write a debug log entry. Delegates to unified logger.
|
|
30
|
-
*/
|
|
31
|
-
export function debugLog(
|
|
32
|
-
contextPath: string,
|
|
33
|
-
sessionName: string,
|
|
34
|
-
component: string,
|
|
35
|
-
message: string,
|
|
36
|
-
data?: unknown,
|
|
37
|
-
): void {
|
|
38
|
-
if (!DEBUG_ENABLED) return;
|
|
39
|
-
|
|
40
|
-
hookLog("debug", sessionName, message, {
|
|
41
|
-
component,
|
|
42
|
-
data,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Log raw output (stdout, stderr, etc). Delegates to unified logger.
|
|
48
|
-
*/
|
|
49
|
-
export function debugRaw(
|
|
50
|
-
contextPath: string,
|
|
51
|
-
sessionName: string,
|
|
52
|
-
component: string,
|
|
53
|
-
label: string,
|
|
54
|
-
raw: string,
|
|
55
|
-
maxLen = 10_000,
|
|
56
|
-
): void {
|
|
57
|
-
if (!DEBUG_ENABLED) return;
|
|
58
|
-
|
|
59
|
-
const truncated = raw.length > maxLen ? raw.slice(0, maxLen) : raw;
|
|
60
|
-
const suffix =
|
|
61
|
-
raw.length > maxLen ? ` [TRUNCATED from ${raw.length} chars]` : "";
|
|
62
|
-
|
|
63
|
-
hookLog("debug", sessionName, `${label}${suffix}: ${truncated}`, {
|
|
64
|
-
component,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Remove debug folder during context archive.
|
|
70
|
-
*/
|
|
71
|
-
export function cleanupDebugFolder(contextPath: string): void {
|
|
72
|
-
try {
|
|
73
|
-
const debugDir = path.join(contextPath, "debug");
|
|
74
|
-
if (fs.existsSync(debugDir)) {
|
|
75
|
-
fs.rmSync(debugDir, { recursive: true, force: true });
|
|
76
|
-
}
|
|
77
|
-
} catch {
|
|
78
|
-
// Best effort cleanup
|
|
79
|
-
}
|
|
80
|
-
}
|
|
11
|
+
|
|
12
|
+
import { hookLog } from "../../_shared/lib-ts/base/logger.js";
|
|
13
|
+
|
|
14
|
+
/** Feature flag — set CCNATIVE_DEBUG_DISABLE=1 to turn off */
|
|
15
|
+
const DEBUG_ENABLED = !["1", "true", "yes"].includes(
|
|
16
|
+
(process.env.CCNATIVE_DEBUG_DISABLE ?? "").toLowerCase(),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get or create debug directory within context folder.
|
|
21
|
+
*/
|
|
22
|
+
export function getDebugDir(contextPath: string): string {
|
|
23
|
+
const debugDir = path.join(contextPath, "debug");
|
|
24
|
+
fs.mkdirSync(debugDir, { recursive: true });
|
|
25
|
+
return debugDir;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Write a debug log entry. Delegates to unified logger.
|
|
30
|
+
*/
|
|
31
|
+
export function debugLog(
|
|
32
|
+
contextPath: string,
|
|
33
|
+
sessionName: string,
|
|
34
|
+
component: string,
|
|
35
|
+
message: string,
|
|
36
|
+
data?: unknown,
|
|
37
|
+
): void {
|
|
38
|
+
if (!DEBUG_ENABLED) return;
|
|
39
|
+
|
|
40
|
+
hookLog("debug", sessionName, message, {
|
|
41
|
+
component,
|
|
42
|
+
data,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Log raw output (stdout, stderr, etc). Delegates to unified logger.
|
|
48
|
+
*/
|
|
49
|
+
export function debugRaw(
|
|
50
|
+
contextPath: string,
|
|
51
|
+
sessionName: string,
|
|
52
|
+
component: string,
|
|
53
|
+
label: string,
|
|
54
|
+
raw: string,
|
|
55
|
+
maxLen = 10_000,
|
|
56
|
+
): void {
|
|
57
|
+
if (!DEBUG_ENABLED) return;
|
|
58
|
+
|
|
59
|
+
const truncated = raw.length > maxLen ? raw.slice(0, maxLen) : raw;
|
|
60
|
+
const suffix =
|
|
61
|
+
raw.length > maxLen ? ` [TRUNCATED from ${raw.length} chars]` : "";
|
|
62
|
+
|
|
63
|
+
hookLog("debug", sessionName, `${label}${suffix}: ${truncated}`, {
|
|
64
|
+
component,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Remove debug folder during context archive.
|
|
70
|
+
*/
|
|
71
|
+
export function cleanupDebugFolder(contextPath: string): void {
|
|
72
|
+
try {
|
|
73
|
+
const debugDir = path.join(contextPath, "debug");
|
|
74
|
+
if (fs.existsSync(debugDir)) {
|
|
75
|
+
fs.rmSync(debugDir, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
// Best effort cleanup
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -20,7 +20,7 @@ export {
|
|
|
20
20
|
formatReviewMarkdown,
|
|
21
21
|
generateReviewIndex,
|
|
22
22
|
writeCombinedArtifacts,
|
|
23
|
-
} from "
|
|
23
|
+
} from "../artifacts/lib/index.js";
|
|
24
24
|
|
|
25
25
|
// CC-native state
|
|
26
26
|
export {
|
|
@@ -59,13 +59,13 @@ export { cleanupDebugFolder, debugLog, debugRaw, getDebugDir } from "./debug.js"
|
|
|
59
59
|
export { coerceToReview, parseJsonMaybe } from "./json-parser.js";
|
|
60
60
|
|
|
61
61
|
// Orchestrator
|
|
62
|
-
export { buildOrchestratorSchema, runOrchestrator } from "
|
|
62
|
+
export { buildOrchestratorSchema, runOrchestrator } from "../plan-review/lib/orchestrator.js";
|
|
63
63
|
|
|
64
64
|
// Reviewers
|
|
65
65
|
export {
|
|
66
66
|
AgentReviewer,
|
|
67
67
|
runAgentReview,
|
|
68
|
-
} from "
|
|
68
|
+
} from "../plan-review/lib/reviewers/index.js";
|
|
69
69
|
|
|
70
70
|
// Iteration state
|
|
71
71
|
export {
|
|
@@ -113,4 +113,4 @@ export {
|
|
|
113
113
|
} from "./types.js";
|
|
114
114
|
|
|
115
115
|
// Verdict aggregation
|
|
116
|
-
export { computeReviewDecision, worstVerdict } from "
|
|
116
|
+
export { computeReviewDecision, worstVerdict } from "../plan-review/lib/verdict.js";
|
|
@@ -1,168 +1,168 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON parsing utilities for LLM responses.
|
|
3
|
-
* See cc-native-plan-review-spec.md §4.10-4.11
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { ReviewData, Verdict } from "./types.js";
|
|
7
|
-
import { logDebug, logWarn } from "../../_shared/lib-ts/base/logger.js";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Try strict JSON parse. If that fails, attempt to extract the first {...} block.
|
|
11
|
-
*
|
|
12
|
-
* @param text - Raw text that may contain JSON
|
|
13
|
-
* @param requireFields - Optional list of field names to check for
|
|
14
|
-
* @returns Parsed dict or null if parsing failed entirely
|
|
15
|
-
*/
|
|
16
|
-
export function parseJsonMaybe(
|
|
17
|
-
text: string,
|
|
18
|
-
requireFields?: string[],
|
|
19
|
-
): null | Record<string, unknown> {
|
|
20
|
-
const trimmed = text.trim();
|
|
21
|
-
if (!trimmed) return null;
|
|
22
|
-
|
|
23
|
-
let obj: null | Record<string, unknown> = null;
|
|
24
|
-
let parseMethod: null | string = null;
|
|
25
|
-
|
|
26
|
-
// Strict parse
|
|
27
|
-
try {
|
|
28
|
-
const parsed: unknown = JSON.parse(trimmed);
|
|
29
|
-
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
30
|
-
obj = parsed as Record<string, unknown>;
|
|
31
|
-
parseMethod = "strict";
|
|
32
|
-
}
|
|
33
|
-
} catch {
|
|
34
|
-
// Fall through to heuristic
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Heuristic: try to extract a JSON object substring
|
|
38
|
-
if (obj === null) {
|
|
39
|
-
const start = trimmed.indexOf("{");
|
|
40
|
-
const end = trimmed.lastIndexOf("}");
|
|
41
|
-
if (start !== -1 && end !== -1 && end > start) {
|
|
42
|
-
const candidate = trimmed.slice(start, end + 1);
|
|
43
|
-
try {
|
|
44
|
-
const parsed: unknown = JSON.parse(candidate);
|
|
45
|
-
if (
|
|
46
|
-
parsed !== null &&
|
|
47
|
-
typeof parsed === "object" &&
|
|
48
|
-
!Array.isArray(parsed)
|
|
49
|
-
) {
|
|
50
|
-
obj = parsed as Record<string, unknown>;
|
|
51
|
-
parseMethod = "heuristic";
|
|
52
|
-
logDebug(
|
|
53
|
-
"parse",
|
|
54
|
-
`Used heuristic extraction (chars ${start}-${end})`,
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
} catch {
|
|
58
|
-
logDebug(
|
|
59
|
-
"parse",
|
|
60
|
-
`Heuristic extraction failed for candidate at chars ${start}-${end}`,
|
|
61
|
-
);
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Validate required fields if parsed
|
|
68
|
-
if (obj && requireFields) {
|
|
69
|
-
const missing = requireFields.filter((f) => !(f in obj!) || !obj![f]);
|
|
70
|
-
if (missing.length > 0) {
|
|
71
|
-
logWarn(
|
|
72
|
-
"parse",
|
|
73
|
-
`Parsed JSON (${parseMethod}) missing/empty fields: ${JSON.stringify(missing)}`,
|
|
74
|
-
);
|
|
75
|
-
logDebug("parse", `Keys present: ${JSON.stringify(Object.keys(obj))}`);
|
|
76
|
-
// Heuristic extraction grabbed the wrong object — reject it.
|
|
77
|
-
// Strict parse still returns partial objects (caller handles defaults).
|
|
78
|
-
if (parseMethod === "heuristic") {
|
|
79
|
-
logWarn("parse", "Rejecting heuristic result due to missing required fields");
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return obj;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Validate/normalize parsed JSON to ReviewData shape with safe defaults.
|
|
90
|
-
*
|
|
91
|
-
* @param obj - Parsed JSON object (possibly null)
|
|
92
|
-
* @param defaultFixMsg - Default suggested_fix message for error case
|
|
93
|
-
* @returns Tuple of [ok, verdict, normalizedData]
|
|
94
|
-
*/
|
|
95
|
-
export function coerceToReview(
|
|
96
|
-
obj: null | Record<string, unknown>,
|
|
97
|
-
defaultFixMsg = "Retry or check configuration.",
|
|
98
|
-
): [boolean, Verdict, ReviewData] {
|
|
99
|
-
if (!obj) {
|
|
100
|
-
logWarn("coerce", "No object provided to coerceToReview");
|
|
101
|
-
return [
|
|
102
|
-
false,
|
|
103
|
-
"error",
|
|
104
|
-
{
|
|
105
|
-
verdict: "fail",
|
|
106
|
-
summary: "No structured output returned.",
|
|
107
|
-
summary_source: "default",
|
|
108
|
-
issues: [
|
|
109
|
-
{
|
|
110
|
-
severity: "high",
|
|
111
|
-
category: "tooling",
|
|
112
|
-
issue: "Reviewer returned no JSON.",
|
|
113
|
-
suggested_fix: defaultFixMsg,
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
missing_sections: [],
|
|
117
|
-
questions: [],
|
|
118
|
-
},
|
|
119
|
-
];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const rawVerdict = obj.verdict;
|
|
123
|
-
let verdict: Verdict;
|
|
124
|
-
if (rawVerdict === "pass" || rawVerdict === "warn" || rawVerdict === "fail") {
|
|
125
|
-
verdict = rawVerdict;
|
|
126
|
-
} else {
|
|
127
|
-
logWarn(
|
|
128
|
-
"coerce",
|
|
129
|
-
`Invalid or missing verdict '${String(rawVerdict)}', defaulting to 'warn'`,
|
|
130
|
-
);
|
|
131
|
-
verdict = "warn";
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Log when fields are being defaulted
|
|
135
|
-
const summaryRaw = String(obj.summary ?? "").trim();
|
|
136
|
-
if (!summaryRaw) {
|
|
137
|
-
logWarn(
|
|
138
|
-
"coerce",
|
|
139
|
-
"summary missing or empty from parsed output, using default",
|
|
140
|
-
);
|
|
141
|
-
logDebug("coerce", `Raw object keys: ${JSON.stringify(Object.keys(obj))}`);
|
|
142
|
-
logDebug(
|
|
143
|
-
"coerce",
|
|
144
|
-
`verdict=${obj.verdict}, issues_count=${Array.isArray(obj.issues) ? (obj.issues as unknown[]).length : 0}`,
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (!obj.issues) {
|
|
149
|
-
logDebug("coerce", "issues array empty or missing");
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const norm: ReviewData = {
|
|
153
|
-
verdict,
|
|
154
|
-
summary: summaryRaw || "No summary provided.",
|
|
155
|
-
summary_source: summaryRaw ? "reviewer" : "default",
|
|
156
|
-
issues: Array.isArray(obj.issues)
|
|
157
|
-
? (obj.issues as ReviewData["issues"])
|
|
158
|
-
: [],
|
|
159
|
-
missing_sections: Array.isArray(obj.missing_sections)
|
|
160
|
-
? (obj.missing_sections as string[])
|
|
161
|
-
: [],
|
|
162
|
-
questions: Array.isArray(obj.questions)
|
|
163
|
-
? (obj.questions as string[])
|
|
164
|
-
: [],
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
return [true, verdict, norm];
|
|
168
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* JSON parsing utilities for LLM responses.
|
|
3
|
+
* See cc-native-plan-review-spec.md §4.10-4.11
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ReviewData, Verdict } from "./types.js";
|
|
7
|
+
import { logDebug, logWarn } from "../../_shared/lib-ts/base/logger.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Try strict JSON parse. If that fails, attempt to extract the first {...} block.
|
|
11
|
+
*
|
|
12
|
+
* @param text - Raw text that may contain JSON
|
|
13
|
+
* @param requireFields - Optional list of field names to check for
|
|
14
|
+
* @returns Parsed dict or null if parsing failed entirely
|
|
15
|
+
*/
|
|
16
|
+
export function parseJsonMaybe(
|
|
17
|
+
text: string,
|
|
18
|
+
requireFields?: string[],
|
|
19
|
+
): null | Record<string, unknown> {
|
|
20
|
+
const trimmed = text.trim();
|
|
21
|
+
if (!trimmed) return null;
|
|
22
|
+
|
|
23
|
+
let obj: null | Record<string, unknown> = null;
|
|
24
|
+
let parseMethod: null | string = null;
|
|
25
|
+
|
|
26
|
+
// Strict parse
|
|
27
|
+
try {
|
|
28
|
+
const parsed: unknown = JSON.parse(trimmed);
|
|
29
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
30
|
+
obj = parsed as Record<string, unknown>;
|
|
31
|
+
parseMethod = "strict";
|
|
32
|
+
}
|
|
33
|
+
} catch {
|
|
34
|
+
// Fall through to heuristic
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Heuristic: try to extract a JSON object substring
|
|
38
|
+
if (obj === null) {
|
|
39
|
+
const start = trimmed.indexOf("{");
|
|
40
|
+
const end = trimmed.lastIndexOf("}");
|
|
41
|
+
if (start !== -1 && end !== -1 && end > start) {
|
|
42
|
+
const candidate = trimmed.slice(start, end + 1);
|
|
43
|
+
try {
|
|
44
|
+
const parsed: unknown = JSON.parse(candidate);
|
|
45
|
+
if (
|
|
46
|
+
parsed !== null &&
|
|
47
|
+
typeof parsed === "object" &&
|
|
48
|
+
!Array.isArray(parsed)
|
|
49
|
+
) {
|
|
50
|
+
obj = parsed as Record<string, unknown>;
|
|
51
|
+
parseMethod = "heuristic";
|
|
52
|
+
logDebug(
|
|
53
|
+
"parse",
|
|
54
|
+
`Used heuristic extraction (chars ${start}-${end})`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
logDebug(
|
|
59
|
+
"parse",
|
|
60
|
+
`Heuristic extraction failed for candidate at chars ${start}-${end}`,
|
|
61
|
+
);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Validate required fields if parsed
|
|
68
|
+
if (obj && requireFields) {
|
|
69
|
+
const missing = requireFields.filter((f) => !(f in obj!) || !obj![f]);
|
|
70
|
+
if (missing.length > 0) {
|
|
71
|
+
logWarn(
|
|
72
|
+
"parse",
|
|
73
|
+
`Parsed JSON (${parseMethod}) missing/empty fields: ${JSON.stringify(missing)}`,
|
|
74
|
+
);
|
|
75
|
+
logDebug("parse", `Keys present: ${JSON.stringify(Object.keys(obj))}`);
|
|
76
|
+
// Heuristic extraction grabbed the wrong object — reject it.
|
|
77
|
+
// Strict parse still returns partial objects (caller handles defaults).
|
|
78
|
+
if (parseMethod === "heuristic") {
|
|
79
|
+
logWarn("parse", "Rejecting heuristic result due to missing required fields");
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return obj;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Validate/normalize parsed JSON to ReviewData shape with safe defaults.
|
|
90
|
+
*
|
|
91
|
+
* @param obj - Parsed JSON object (possibly null)
|
|
92
|
+
* @param defaultFixMsg - Default suggested_fix message for error case
|
|
93
|
+
* @returns Tuple of [ok, verdict, normalizedData]
|
|
94
|
+
*/
|
|
95
|
+
export function coerceToReview(
|
|
96
|
+
obj: null | Record<string, unknown>,
|
|
97
|
+
defaultFixMsg = "Retry or check configuration.",
|
|
98
|
+
): [boolean, Verdict, ReviewData] {
|
|
99
|
+
if (!obj) {
|
|
100
|
+
logWarn("coerce", "No object provided to coerceToReview");
|
|
101
|
+
return [
|
|
102
|
+
false,
|
|
103
|
+
"error",
|
|
104
|
+
{
|
|
105
|
+
verdict: "fail",
|
|
106
|
+
summary: "No structured output returned.",
|
|
107
|
+
summary_source: "default",
|
|
108
|
+
issues: [
|
|
109
|
+
{
|
|
110
|
+
severity: "high",
|
|
111
|
+
category: "tooling",
|
|
112
|
+
issue: "Reviewer returned no JSON.",
|
|
113
|
+
suggested_fix: defaultFixMsg,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
missing_sections: [],
|
|
117
|
+
questions: [],
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const rawVerdict = obj.verdict;
|
|
123
|
+
let verdict: Verdict;
|
|
124
|
+
if (rawVerdict === "pass" || rawVerdict === "warn" || rawVerdict === "fail") {
|
|
125
|
+
verdict = rawVerdict;
|
|
126
|
+
} else {
|
|
127
|
+
logWarn(
|
|
128
|
+
"coerce",
|
|
129
|
+
`Invalid or missing verdict '${String(rawVerdict)}', defaulting to 'warn'`,
|
|
130
|
+
);
|
|
131
|
+
verdict = "warn";
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Log when fields are being defaulted
|
|
135
|
+
const summaryRaw = String(obj.summary ?? "").trim();
|
|
136
|
+
if (!summaryRaw) {
|
|
137
|
+
logWarn(
|
|
138
|
+
"coerce",
|
|
139
|
+
"summary missing or empty from parsed output, using default",
|
|
140
|
+
);
|
|
141
|
+
logDebug("coerce", `Raw object keys: ${JSON.stringify(Object.keys(obj))}`);
|
|
142
|
+
logDebug(
|
|
143
|
+
"coerce",
|
|
144
|
+
`verdict=${obj.verdict}, issues_count=${Array.isArray(obj.issues) ? (obj.issues as unknown[]).length : 0}`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!obj.issues) {
|
|
149
|
+
logDebug("coerce", "issues array empty or missing");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const norm: ReviewData = {
|
|
153
|
+
verdict,
|
|
154
|
+
summary: summaryRaw || "No summary provided.",
|
|
155
|
+
summary_source: summaryRaw ? "reviewer" : "default",
|
|
156
|
+
issues: Array.isArray(obj.issues)
|
|
157
|
+
? (obj.issues as ReviewData["issues"])
|
|
158
|
+
: [],
|
|
159
|
+
missing_sections: Array.isArray(obj.missing_sections)
|
|
160
|
+
? (obj.missing_sections as string[])
|
|
161
|
+
: [],
|
|
162
|
+
questions: Array.isArray(obj.questions)
|
|
163
|
+
? (obj.questions as string[])
|
|
164
|
+
: [],
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
return [true, verdict, norm];
|
|
168
|
+
}
|