@gajae-code/coding-agent 0.11.10 → 0.12.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/CHANGELOG.md +86 -2
- package/dist/types/cli/read-cli.d.ts +1 -0
- package/dist/types/cli.d.ts +8 -1
- package/dist/types/commands/deep-interview.d.ts +9 -0
- package/dist/types/commands/harness.d.ts +22 -0
- package/dist/types/commands/read.d.ts +6 -0
- package/dist/types/config/model-profile-activation.d.ts +1 -0
- package/dist/types/config/model-profile-contract.d.ts +2 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/provider-auth-health.d.ts +14 -0
- package/dist/types/config/provider-ranking.d.ts +59 -0
- package/dist/types/config/settings-schema.d.ts +86 -3
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +43 -2
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
- package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
- package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/linux-proc.d.ts +22 -14
- package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +112 -1
- package/dist/types/gjc-runtime/state-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
- package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
- package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
- package/dist/types/gjc-runtime/team-store.d.ts +12 -0
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +7 -0
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
- package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
- package/dist/types/main.d.ts +1 -1
- package/dist/types/memories/index.d.ts +2 -0
- package/dist/types/modes/acp/acp-agent.d.ts +22 -9
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/queue-pane.d.ts +8 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/welcome.d.ts +1 -0
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +7 -1
- package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
- package/dist/types/runtime/memory-domain.d.ts +9 -0
- package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
- package/dist/types/runtime/memory-guard.d.ts +39 -0
- package/dist/types/runtime/memory-limit.d.ts +11 -0
- package/dist/types/runtime-mcp/manager.d.ts +8 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/final-text.d.ts +19 -0
- package/dist/types/sdk/acp/mcp.d.ts +23 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +7 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/index.d.ts +18 -2
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +23 -3
- package/dist/types/sdk/host/control/operations.d.ts +2 -1
- package/dist/types/sdk/host/host.d.ts +2 -0
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/lifecycle-session.d.ts +10 -1
- package/dist/types/sdk/startup-capability.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +51 -19
- package/dist/types/session/fallback-chain-controller.d.ts +18 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +27 -0
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +59 -13
- package/dist/types/session/streaming-output.d.ts +60 -5
- package/dist/types/skill-state/active-state.d.ts +0 -4
- package/dist/types/skill-state/workflow-hud.d.ts +3 -0
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/types.d.ts +36 -0
- package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +17 -1
- package/dist/types/tools/output-meta.d.ts +21 -1
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -1
- package/dist/types/tools/resource-gc.d.ts +23 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/package.json +9 -13
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/generate-sdk-operation-inventory.ts +4 -0
- package/scripts/run-test-manifest.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/capability/index.ts +8 -0
- package/src/cli/args.ts +14 -8
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/read-cli.ts +2 -1
- package/src/cli.ts +49 -2
- package/src/commands/deep-interview.ts +29 -9
- package/src/commands/harness.ts +35 -12
- package/src/commands/read.ts +11 -2
- package/src/commands/sdk.ts +91 -7
- package/src/commands/team.ts +1 -1
- package/src/config/model-profile-activation.ts +1 -0
- package/src/config/model-profile-contract.ts +13 -0
- package/src/config/model-profiles.ts +24 -0
- package/src/config/model-registry.ts +21 -2
- package/src/config/provider-auth-health.ts +42 -0
- package/src/config/provider-ranking.ts +119 -0
- package/src/config/settings-schema.ts +84 -3
- package/src/config/settings.ts +254 -108
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +229 -82
- package/src/defaults/gjc/skills/ralplan/SKILL.md +78 -26
- package/src/defaults/gjc/skills/team/SKILL.md +1 -1
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +26 -16
- package/src/eval/py/executor.ts +7 -2
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +42 -4
- package/src/extensibility/shared-events.ts +5 -0
- package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -68
- package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
- package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
- package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
- package/src/gjc-runtime/deep-interview-state.ts +12 -921
- package/src/gjc-runtime/gc-render.ts +1 -0
- package/src/gjc-runtime/gc-runtime.ts +11 -1
- package/src/gjc-runtime/linux-proc.ts +70 -36
- package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/gjc-runtime/ralplan-runtime.ts +979 -71
- package/src/gjc-runtime/state-runtime.ts +50 -12
- package/src/gjc-runtime/state-writer.ts +70 -222
- package/src/gjc-runtime/team-launch.ts +34 -5
- package/src/gjc-runtime/team-runtime.ts +970 -33
- package/src/gjc-runtime/team-store.ts +32 -0
- package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
- package/src/gjc-runtime/team-workers.ts +1 -0
- package/src/gjc-runtime/tmux-owner-isolation.ts +18 -0
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +13 -7
- package/src/gjc-runtime/workflow-manifest.generated.json +97 -350
- package/src/gjc-runtime/workflow-manifest.ts +34 -179
- package/src/hooks/native-skill-hook.ts +17 -4
- package/src/hooks/skill-state.ts +1 -23
- package/src/internal-urls/docs-index.generated.ts +10 -11
- package/src/internal-urls/local-protocol.ts +23 -4
- package/src/internal-urls/local-root-gc.ts +127 -0
- package/src/main.ts +9 -5
- package/src/memories/index.ts +10 -0
- package/src/modes/DESIGN.md +47 -0
- package/src/modes/acp/acp-agent.ts +597 -67
- package/src/modes/acp/acp-event-mapper.ts +106 -12
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +76 -5
- package/src/modes/components/notifications-settings-editor.ts +1 -1
- package/src/modes/components/oauth-selector.ts +42 -12
- package/src/modes/components/queue-pane.ts +55 -9
- package/src/modes/components/queued-message-selector.ts +53 -10
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/session-observer-overlay.ts +187 -32
- package/src/modes/components/settings-selector.ts +60 -18
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +1 -4
- package/src/modes/components/welcome.ts +18 -3
- package/src/modes/controllers/command-controller.ts +4 -0
- package/src/modes/controllers/event-controller.ts +109 -27
- package/src/modes/controllers/extension-ui-controller.ts +23 -12
- package/src/modes/controllers/input-controller.ts +62 -6
- package/src/modes/controllers/selector-controller.ts +83 -37
- package/src/modes/interactive-mode.ts +127 -29
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/runtime-init.ts +20 -2
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +94 -1
- package/src/prompts/agents/architect.md +9 -1
- package/src/prompts/agents/critic.md +9 -0
- package/src/prompts/agents/executor.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -1
- package/src/prompts/tools/read.md +4 -2
- package/src/runtime/memory-domain.ts +66 -0
- package/src/runtime/memory-guard-contract.ts +73 -0
- package/src/runtime/memory-guard.ts +292 -0
- package/src/runtime/memory-limit.ts +50 -0
- package/src/runtime-mcp/manager.ts +26 -6
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/sdk/acp/adapter.ts +8 -1
- package/src/sdk/acp/final-text.ts +40 -0
- package/src/sdk/acp/mcp.ts +26 -0
- package/src/sdk/broker/lifecycle.ts +107 -7
- package/src/sdk/bus/chat-daemon-cli.ts +2 -2
- package/src/sdk/bus/chat-daemon-control.ts +4 -3
- package/src/sdk/bus/config.ts +1 -1
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/index.ts +503 -60
- package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
- package/src/sdk/bus/prompt-reconciliation.ts +2 -1
- package/src/sdk/bus/rate-limit-pool.ts +8 -0
- package/src/sdk/bus/reconciliation-store.ts +224 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +6 -4
- package/src/sdk/bus/telegram-daemon.ts +531 -53
- package/src/sdk/host/control/dispatch.ts +7 -1
- package/src/sdk/host/control/operations.ts +2 -1
- package/src/sdk/host/host.ts +25 -3
- package/src/sdk/host/query/handlers.ts +55 -0
- package/src/sdk/lifecycle-session.ts +19 -3
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/protocol/operation-inventory.generated.json +76 -0
- package/src/sdk/protocol/operation-registry.ts +8 -2
- package/src/sdk/session.ts +25 -2
- package/src/sdk/startup-capability.ts +6 -0
- package/src/session/agent-session.ts +720 -190
- package/src/session/fallback-chain-controller.ts +47 -8
- package/src/session/internal/managed-session-scope.ts +40 -10
- package/src/session/internal/native-publish-outcome.ts +8 -3
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +1372 -42
- package/src/session/streaming-output.ts +262 -43
- package/src/setup/provider-onboarding.ts +19 -4
- package/src/skill-state/active-state.ts +0 -10
- package/src/skill-state/workflow-hud.ts +25 -2
- package/src/skill-state/workflow-mutation-guard.ts +65 -7
- package/src/task/executor.ts +11 -3
- package/src/task/index.ts +2 -0
- package/src/task/types.ts +22 -11
- package/src/task/ultragoal-redteam-activation.ts +75 -0
- package/src/tools/ask.ts +89 -69
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/fetch.ts +114 -23
- package/src/tools/output-meta.ts +176 -9
- package/src/tools/path-utils.ts +5 -1
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1542 -310
- package/src/tools/resource-gc.ts +665 -125
- package/src/tools/tool-result.ts +14 -1
- package/src/web/search/providers/codex.ts +1 -1
- package/src/workflow/workflow-intent-diff.ts +4 -1
- package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
- package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
- package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
- package/src/gjc-runtime/deep-interview-draft.ts +0 -843
- package/src/gjc-runtime/deep-interview-payload.ts +0 -262
- package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
|
-
import * as os from "node:os";
|
|
4
3
|
import * as path from "node:path";
|
|
4
|
+
import { getConfigRootDir } from "@gajae-code/utils";
|
|
5
5
|
import { YAML } from "bun";
|
|
6
|
+
import { syncSkillActiveState } from "../skill-state/active-state";
|
|
7
|
+
import { deriveDeepInterviewHud } from "../skill-state/workflow-hud";
|
|
6
8
|
import { WORKFLOW_STATE_VERSION } from "../skill-state/workflow-state-contract";
|
|
7
|
-
import {
|
|
8
|
-
import { runDeepInterviewDraftCommand } from "./deep-interview-draft";
|
|
9
|
-
import { runDeepInterviewPostCommitEffects } from "./deep-interview-recorder";
|
|
10
|
-
import { isDeepInterviewRepairVerb, runDeepInterviewRepairCommand } from "./deep-interview-repair";
|
|
9
|
+
import { isDeepInterviewStageVerb, runDeepInterviewStageCommand } from "./deep-interview-stage";
|
|
11
10
|
import {
|
|
12
11
|
assertDeepInterviewInputWithinLimit,
|
|
13
12
|
assertDeepInterviewIntentReview,
|
|
@@ -19,20 +18,12 @@ import {
|
|
|
19
18
|
MAX_INITIAL_CONTEXT_LENGTH,
|
|
20
19
|
normalizeDeepInterviewEnvelope,
|
|
21
20
|
reviewDeepInterviewIntent,
|
|
22
|
-
validateDeepInterviewV1Envelope,
|
|
23
21
|
} from "./deep-interview-state";
|
|
24
22
|
import { runNativeRalplanCommand } from "./ralplan-runtime";
|
|
25
23
|
import { modeStatePath, sessionSpecsDir } from "./session-layout";
|
|
26
|
-
import { resolveGjcSessionForWrite } from "./session-resolution";
|
|
24
|
+
import { resolveGjcSessionForWrite, writeSessionActivityMarker } from "./session-resolution";
|
|
27
25
|
import { runNativeStateCommand } from "./state-runtime";
|
|
28
|
-
import {
|
|
29
|
-
appendJsonl,
|
|
30
|
-
readExistingStateForMutation,
|
|
31
|
-
verifyWorkflowEnvelopeReceiptValue,
|
|
32
|
-
withWorkflowStateLock,
|
|
33
|
-
writeArtifact,
|
|
34
|
-
writeWorkflowEnvelopeAtomic,
|
|
35
|
-
} from "./state-writer";
|
|
26
|
+
import { appendJsonl, readExistingStateForMutation, writeArtifact, writeWorkflowEnvelopeAtomic } from "./state-writer";
|
|
36
27
|
import { assertSafePathComponent, CommandError, flagValue, hasFlag } from "./workflow-cli-common";
|
|
37
28
|
|
|
38
29
|
export * from "./deep-interview-recorder";
|
|
@@ -364,7 +355,7 @@ async function readSettingsAmbiguityThreshold(
|
|
|
364
355
|
} catch (error) {
|
|
365
356
|
const err = error as NodeJS.ErrnoException;
|
|
366
357
|
if (err.code === "ENOENT") return undefined;
|
|
367
|
-
|
|
358
|
+
return undefined;
|
|
368
359
|
}
|
|
369
360
|
let parsed: unknown;
|
|
370
361
|
try {
|
|
@@ -374,7 +365,7 @@ async function readSettingsAmbiguityThreshold(
|
|
|
374
365
|
}
|
|
375
366
|
const candidate = (parsed as { gjc?: { deepInterview?: { ambiguityThreshold?: unknown } } })?.gjc?.deepInterview
|
|
376
367
|
?.ambiguityThreshold;
|
|
377
|
-
if (typeof candidate !== "number" || !
|
|
368
|
+
if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate <= 0 || candidate > 1) {
|
|
378
369
|
return undefined;
|
|
379
370
|
}
|
|
380
371
|
return { threshold: candidate, source: settingsPath };
|
|
@@ -383,30 +374,21 @@ async function readSettingsAmbiguityThreshold(
|
|
|
383
374
|
function modernSettingsPath(): string {
|
|
384
375
|
const configDir = process.env.GJC_CODING_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
|
|
385
376
|
if (configDir) return path.join(configDir, "config.yml");
|
|
386
|
-
|
|
387
|
-
if (configRoot) return path.join(configRoot, "agent", "config.yml");
|
|
388
|
-
return path.join(os.homedir(), ".gjc", "agent", "config.yml");
|
|
377
|
+
return path.join(getConfigRootDir(), "agent", "config.yml");
|
|
389
378
|
}
|
|
390
379
|
|
|
391
380
|
async function readModernSettingsAmbiguityThreshold(): Promise<{ threshold: number; source: string } | undefined> {
|
|
392
381
|
const modernConfigPath = modernSettingsPath();
|
|
393
|
-
let raw: string;
|
|
394
|
-
try {
|
|
395
|
-
raw = await fs.readFile(modernConfigPath, "utf-8");
|
|
396
|
-
} catch (error) {
|
|
397
|
-
const err = error as NodeJS.ErrnoException;
|
|
398
|
-
if (err.code === "ENOENT") return undefined;
|
|
399
|
-
throw new Error(`failed to read deep-interview threshold config ${modernConfigPath}: ${err.message}`);
|
|
400
|
-
}
|
|
401
382
|
let parsed: unknown;
|
|
402
383
|
try {
|
|
403
|
-
parsed = YAML.parse(
|
|
384
|
+
parsed = YAML.parse(await fs.readFile(modernConfigPath, "utf-8"));
|
|
404
385
|
} catch {
|
|
405
386
|
return undefined;
|
|
406
387
|
}
|
|
407
388
|
const candidate = (parsed as { gjc?: { deepInterview?: { ambiguityThreshold?: unknown } } })?.gjc?.deepInterview
|
|
408
389
|
?.ambiguityThreshold;
|
|
409
|
-
if (typeof candidate !== "number" || !
|
|
390
|
+
if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate <= 0 || candidate > 1)
|
|
391
|
+
return undefined;
|
|
410
392
|
return { threshold: candidate, source: modernConfigPath };
|
|
411
393
|
}
|
|
412
394
|
|
|
@@ -418,8 +400,7 @@ async function resolveConfiguredAmbiguityThreshold(
|
|
|
418
400
|
const projectSettings = path.join(cwd, ".gjc", "settings.json");
|
|
419
401
|
const projectValue = await readSettingsAmbiguityThreshold(projectSettings);
|
|
420
402
|
if (projectValue) return projectValue;
|
|
421
|
-
const
|
|
422
|
-
const userSettings = path.join(configDir, "settings.json");
|
|
403
|
+
const userSettings = path.join(getConfigRootDir(), "settings.json");
|
|
423
404
|
return await readSettingsAmbiguityThreshold(userSettings);
|
|
424
405
|
}
|
|
425
406
|
|
|
@@ -521,15 +502,6 @@ async function resolveSpecWriteArgs(args: readonly string[], cwd: string): Promi
|
|
|
521
502
|
};
|
|
522
503
|
}
|
|
523
504
|
|
|
524
|
-
function isIntegralScore(value: number): boolean {
|
|
525
|
-
try {
|
|
526
|
-
scoreToUnits(value);
|
|
527
|
-
return true;
|
|
528
|
-
} catch {
|
|
529
|
-
return false;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
505
|
async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): Promise<ResolvedDeepInterviewArgs> {
|
|
534
506
|
const session = resolveGjcSessionForWrite(cwd, {
|
|
535
507
|
flagValue: flagValue(args, "--session-id"),
|
|
@@ -550,10 +522,10 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
|
|
|
550
522
|
const thresholdOverride = flagValue(args, "--threshold");
|
|
551
523
|
if (thresholdOverride !== undefined) {
|
|
552
524
|
const parsed = Number(thresholdOverride);
|
|
553
|
-
if (!
|
|
525
|
+
if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 1) {
|
|
554
526
|
throw new DeepInterviewCommandError(
|
|
555
527
|
2,
|
|
556
|
-
`invalid --threshold: ${thresholdOverride}. Expected
|
|
528
|
+
`invalid --threshold: ${thresholdOverride}. Expected 0 < threshold <= 1.`,
|
|
557
529
|
);
|
|
558
530
|
}
|
|
559
531
|
threshold = parsed;
|
|
@@ -571,16 +543,7 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
|
|
|
571
543
|
|
|
572
544
|
const ideaParts: string[] = [];
|
|
573
545
|
let skipNext = false;
|
|
574
|
-
let positionalOnly = false;
|
|
575
546
|
for (const arg of args) {
|
|
576
|
-
if (positionalOnly) {
|
|
577
|
-
ideaParts.push(arg);
|
|
578
|
-
continue;
|
|
579
|
-
}
|
|
580
|
-
if (arg === "--") {
|
|
581
|
-
positionalOnly = true;
|
|
582
|
-
continue;
|
|
583
|
-
}
|
|
584
547
|
if (skipNext) {
|
|
585
548
|
skipNext = false;
|
|
586
549
|
continue;
|
|
@@ -754,13 +717,13 @@ export async function persistDeepInterviewSpec(
|
|
|
754
717
|
forced: resolved.force,
|
|
755
718
|
},
|
|
756
719
|
});
|
|
757
|
-
await
|
|
720
|
+
await writeSessionActivityMarker(cwd, resolved.sessionId, { writer: "deep-interview-runtime", path: statePath });
|
|
721
|
+
await syncDeepInterviewHud({
|
|
758
722
|
cwd,
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
writer: "deep-interview-runtime",
|
|
723
|
+
sessionId: resolved.sessionId,
|
|
724
|
+
payload,
|
|
725
|
+
phase: "handoff",
|
|
726
|
+
specStatus: "persisted",
|
|
764
727
|
});
|
|
765
728
|
|
|
766
729
|
return {
|
|
@@ -773,169 +736,91 @@ export async function persistDeepInterviewSpec(
|
|
|
773
736
|
};
|
|
774
737
|
}
|
|
775
738
|
|
|
776
|
-
function
|
|
777
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
778
|
-
const topology = value as Record<string, unknown>;
|
|
779
|
-
return (
|
|
780
|
-
topology.status === "pending" &&
|
|
781
|
-
Array.isArray(topology.components) &&
|
|
782
|
-
topology.components.length === 0 &&
|
|
783
|
-
Array.isArray(topology.deferred_components) &&
|
|
784
|
-
topology.deferred_components.length === 0
|
|
785
|
-
);
|
|
786
|
-
}
|
|
787
|
-
function isUnresolvedNativeSetup(value: unknown): boolean {
|
|
788
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
789
|
-
const state = value as Record<string, unknown>;
|
|
790
|
-
return (
|
|
791
|
-
state.setup !== null &&
|
|
792
|
-
typeof state.setup === "object" &&
|
|
793
|
-
!Array.isArray(state.setup) &&
|
|
794
|
-
(state.setup as Record<string, unknown>).status === "unresolved"
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
async function seedDeepInterviewState(
|
|
798
|
-
cwd: string,
|
|
799
|
-
resolved: ResolvedDeepInterviewArgs,
|
|
800
|
-
): Promise<{ statePath: string; warnings: unknown[] }> {
|
|
739
|
+
async function seedDeepInterviewState(cwd: string, resolved: ResolvedDeepInterviewArgs): Promise<string> {
|
|
801
740
|
const statePath = deepInterviewStatePath(cwd, resolved.sessionId);
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
? (existing.value.state as Record<string, unknown>)
|
|
821
|
-
: {};
|
|
822
|
-
const exactEmptyNativeSeed =
|
|
823
|
-
isUnresolvedNativeSetup(priorState) &&
|
|
824
|
-
priorState.type === (resolved.trace ? "brownfield" : "greenfield") &&
|
|
825
|
-
existing.value.skill === "deep-interview" &&
|
|
826
|
-
existing.value.active === true &&
|
|
827
|
-
phase === "interviewing" &&
|
|
828
|
-
existing.value.resolution === resolved.resolution &&
|
|
829
|
-
existing.value.threshold === resolved.threshold &&
|
|
830
|
-
existing.value.threshold_source === resolved.thresholdSource &&
|
|
831
|
-
priorState.initial_idea === resolved.idea &&
|
|
832
|
-
priorState.intent_contract_required === true &&
|
|
833
|
-
Array.isArray(priorState.rounds) &&
|
|
834
|
-
priorState.rounds.length === 0 &&
|
|
835
|
-
Array.isArray(priorState.established_facts) &&
|
|
836
|
-
priorState.established_facts.length === 0 &&
|
|
837
|
-
Array.isArray(priorState.ontology_snapshots) &&
|
|
838
|
-
priorState.ontology_snapshots.length === 0 &&
|
|
839
|
-
Array.isArray(priorState.auto_researched_rounds) &&
|
|
840
|
-
priorState.auto_researched_rounds.length === 0 &&
|
|
841
|
-
Array.isArray(priorState.auto_answered_rounds) &&
|
|
842
|
-
priorState.auto_answered_rounds.length === 0 &&
|
|
843
|
-
isEmptyPendingTopology(priorState.topology) &&
|
|
844
|
-
priorState.architect_failures === 0 &&
|
|
845
|
-
priorState.current_ambiguity === 1 &&
|
|
846
|
-
JSON.stringify(existing.value.trace) === JSON.stringify(resolved.trace) &&
|
|
847
|
-
JSON.stringify(existing.value.language) === JSON.stringify(resolved.language);
|
|
848
|
-
if (exactEmptyNativeSeed) return { statePath, warnings: [] };
|
|
849
|
-
throw new DeepInterviewCommandError(2, "DI_INTERVIEW_ALREADY_ACTIVE");
|
|
850
|
-
}
|
|
851
|
-
if (existing.kind === "corrupt") throw new DeepInterviewCommandError(3, "DI_STATE_CORRUPT");
|
|
852
|
-
const now = new Date().toISOString();
|
|
853
|
-
const type = resolved.trace ? "brownfield" : "greenfield";
|
|
854
|
-
const payload: Record<string, unknown> = {
|
|
855
|
-
active: true,
|
|
856
|
-
current_phase: "interviewing",
|
|
857
|
-
schema_version: 1,
|
|
858
|
-
skill: "deep-interview",
|
|
859
|
-
version: WORKFLOW_STATE_VERSION,
|
|
860
|
-
resolution: resolved.resolution,
|
|
861
|
-
threshold: resolved.threshold,
|
|
862
|
-
threshold_units: scoreToUnits(resolved.threshold),
|
|
863
|
-
threshold_source: resolved.thresholdSource,
|
|
864
|
-
state: {
|
|
865
|
-
setup: { status: "unresolved" },
|
|
866
|
-
type,
|
|
867
|
-
initial_idea: resolved.idea,
|
|
868
|
-
intent_contract_required: true,
|
|
869
|
-
rounds: [],
|
|
870
|
-
established_facts: [],
|
|
871
|
-
topology: { status: "pending", components: [], deferred_components: [] },
|
|
872
|
-
ontology_snapshots: [],
|
|
873
|
-
auto_researched_rounds: [],
|
|
874
|
-
auto_answered_rounds: [],
|
|
875
|
-
architect_failures: 0,
|
|
876
|
-
current_ambiguity: 1.0,
|
|
877
|
-
threshold: resolved.threshold,
|
|
878
|
-
threshold_units: scoreToUnits(resolved.threshold),
|
|
879
|
-
threshold_source: resolved.thresholdSource,
|
|
880
|
-
},
|
|
881
|
-
updated_at: now,
|
|
882
|
-
};
|
|
883
|
-
validateDeepInterviewV1Envelope(payload);
|
|
884
|
-
if (resolved.trace) {
|
|
885
|
-
payload.trace = resolved.trace;
|
|
886
|
-
(payload.state as Record<string, unknown>).trace = resolved.trace;
|
|
887
|
-
(payload.state as Record<string, unknown>).trace_summary = resolved.trace;
|
|
888
|
-
(payload.state as Record<string, unknown>).codebase_context = {
|
|
889
|
-
source: "trace",
|
|
890
|
-
summary: resolved.trace.findings,
|
|
891
|
-
relevant_paths: resolved.trace.relevant_paths,
|
|
892
|
-
project_hints: resolved.trace.project_hints,
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
if (resolved.language) {
|
|
896
|
-
payload.language = resolved.language;
|
|
897
|
-
(payload.state as Record<string, unknown>).language = resolved.language;
|
|
898
|
-
}
|
|
899
|
-
if (resolved.sessionId) payload.session_id = resolved.sessionId;
|
|
900
|
-
await writeWorkflowEnvelopeAtomic(statePath, payload, {
|
|
901
|
-
cwd,
|
|
902
|
-
receipt: {
|
|
903
|
-
cwd,
|
|
904
|
-
skill: "deep-interview",
|
|
905
|
-
owner: "gjc-runtime",
|
|
906
|
-
command: "gjc deep-interview seed",
|
|
907
|
-
sessionId: resolved.sessionId,
|
|
908
|
-
nowIso: now,
|
|
909
|
-
},
|
|
910
|
-
audit: {
|
|
911
|
-
category: "state",
|
|
912
|
-
verb: "write",
|
|
913
|
-
owner: "gjc-runtime",
|
|
914
|
-
skill: "deep-interview",
|
|
915
|
-
sessionId: resolved.sessionId,
|
|
916
|
-
},
|
|
917
|
-
});
|
|
918
|
-
const stamped = await readExistingStateForMutation(statePath);
|
|
919
|
-
if (stamped.kind !== "valid") throw new DeepInterviewCommandError(3, "DI_STATE_CORRUPT");
|
|
920
|
-
try {
|
|
921
|
-
if (verifyWorkflowEnvelopeReceiptValue(stamped.value, statePath) !== "native-valid")
|
|
922
|
-
throw new Error("invalid receipt");
|
|
923
|
-
validateDeepInterviewV1Envelope(stamped.value);
|
|
924
|
-
} catch {
|
|
925
|
-
throw new DeepInterviewCommandError(3, "DI_STATE_CORRUPT");
|
|
926
|
-
}
|
|
927
|
-
const warnings = await runDeepInterviewPostCommitEffects({
|
|
928
|
-
cwd,
|
|
929
|
-
statePath,
|
|
930
|
-
sessionId: resolved.sessionId ?? "",
|
|
931
|
-
envelope: normalizeDeepInterviewEnvelope(stamped.value),
|
|
932
|
-
revision: typeof stamped.value.state_revision === "number" ? stamped.value.state_revision : 0,
|
|
933
|
-
writer: "deep-interview-runtime",
|
|
934
|
-
});
|
|
935
|
-
return { statePath, warnings };
|
|
741
|
+
assertDeepInterviewInputWithinLimit(resolved.idea, MAX_INITIAL_CONTEXT_LENGTH, "initial_idea");
|
|
742
|
+
const now = new Date().toISOString();
|
|
743
|
+
const payload: Record<string, unknown> = {
|
|
744
|
+
active: true,
|
|
745
|
+
current_phase: "interviewing",
|
|
746
|
+
skill: "deep-interview",
|
|
747
|
+
version: WORKFLOW_STATE_VERSION,
|
|
748
|
+
resolution: resolved.resolution,
|
|
749
|
+
threshold: resolved.threshold,
|
|
750
|
+
threshold_source: resolved.thresholdSource,
|
|
751
|
+
state: {
|
|
752
|
+
initial_idea: resolved.idea,
|
|
753
|
+
intent_contract_required: true,
|
|
754
|
+
rounds: [],
|
|
755
|
+
established_facts: [],
|
|
756
|
+
current_ambiguity: 1.0,
|
|
757
|
+
threshold: resolved.threshold,
|
|
758
|
+
threshold_source: resolved.thresholdSource,
|
|
936
759
|
},
|
|
937
|
-
|
|
938
|
-
|
|
760
|
+
updated_at: now,
|
|
761
|
+
};
|
|
762
|
+
if (resolved.trace) {
|
|
763
|
+
payload.trace = resolved.trace;
|
|
764
|
+
(payload.state as Record<string, unknown>).trace = resolved.trace;
|
|
765
|
+
(payload.state as Record<string, unknown>).trace_summary = resolved.trace;
|
|
766
|
+
(payload.state as Record<string, unknown>).codebase_context = {
|
|
767
|
+
source: "trace",
|
|
768
|
+
summary: resolved.trace.findings,
|
|
769
|
+
relevant_paths: resolved.trace.relevant_paths,
|
|
770
|
+
project_hints: resolved.trace.project_hints,
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
if (resolved.language) {
|
|
774
|
+
payload.language = resolved.language;
|
|
775
|
+
(payload.state as Record<string, unknown>).language = resolved.language;
|
|
776
|
+
}
|
|
777
|
+
if (resolved.sessionId) payload.session_id = resolved.sessionId;
|
|
778
|
+
await writeWorkflowEnvelopeAtomic(statePath, payload, {
|
|
779
|
+
cwd,
|
|
780
|
+
receipt: {
|
|
781
|
+
cwd,
|
|
782
|
+
skill: "deep-interview",
|
|
783
|
+
owner: "gjc-runtime",
|
|
784
|
+
command: "gjc deep-interview seed",
|
|
785
|
+
sessionId: resolved.sessionId,
|
|
786
|
+
nowIso: now,
|
|
787
|
+
},
|
|
788
|
+
audit: {
|
|
789
|
+
category: "state",
|
|
790
|
+
verb: "write",
|
|
791
|
+
owner: "gjc-runtime",
|
|
792
|
+
skill: "deep-interview",
|
|
793
|
+
sessionId: resolved.sessionId,
|
|
794
|
+
},
|
|
795
|
+
});
|
|
796
|
+
await writeSessionActivityMarker(cwd, resolved.sessionId, { writer: "deep-interview-runtime", path: statePath });
|
|
797
|
+
await syncDeepInterviewHud({ cwd, sessionId: resolved.sessionId, payload, phase: "interviewing" });
|
|
798
|
+
return statePath;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
async function syncDeepInterviewHud(options: {
|
|
802
|
+
cwd: string;
|
|
803
|
+
sessionId?: string;
|
|
804
|
+
payload: Record<string, unknown>;
|
|
805
|
+
phase?: string;
|
|
806
|
+
specStatus?: string;
|
|
807
|
+
}): Promise<void> {
|
|
808
|
+
try {
|
|
809
|
+
const phase =
|
|
810
|
+
options.phase ??
|
|
811
|
+
(typeof options.payload.current_phase === "string" ? options.payload.current_phase : "interviewing");
|
|
812
|
+
await syncSkillActiveState({
|
|
813
|
+
cwd: options.cwd,
|
|
814
|
+
skill: "deep-interview",
|
|
815
|
+
active: phase !== "complete",
|
|
816
|
+
phase,
|
|
817
|
+
sessionId: options.sessionId,
|
|
818
|
+
source: "gjc-deep-interview-native",
|
|
819
|
+
hud: deriveDeepInterviewHud(options.payload, { phase, specStatus: options.specStatus }),
|
|
820
|
+
});
|
|
821
|
+
} catch {
|
|
822
|
+
// HUD sync is best-effort and must not change command semantics.
|
|
823
|
+
}
|
|
939
824
|
}
|
|
940
825
|
|
|
941
826
|
async function handleSpecWrite(args: readonly string[], cwd: string): Promise<DeepInterviewCommandResult> {
|
|
@@ -1001,68 +886,23 @@ async function handleSpecWrite(args: readonly string[], cwd: string): Promise<De
|
|
|
1001
886
|
.join("\n");
|
|
1002
887
|
return { status: 0, stdout };
|
|
1003
888
|
}
|
|
1004
|
-
function isDeepInterviewRepairInvocation(args: readonly string[]): boolean {
|
|
1005
|
-
const separator = args.indexOf("--");
|
|
1006
|
-
return (separator === -1 || separator > 0) && isDeepInterviewRepairVerb(args[0] ?? "");
|
|
1007
|
-
}
|
|
1008
|
-
function isDeepInterviewDraftInvocation(args: readonly string[]): boolean {
|
|
1009
|
-
const separator = args.indexOf("--");
|
|
1010
|
-
return (separator === -1 || separator > 0) && args[0] === "draft";
|
|
1011
|
-
}
|
|
1012
|
-
function draftCommandArgs(args: readonly string[]): string[] {
|
|
1013
|
-
const normalized: string[] = [];
|
|
1014
|
-
for (let index = 1; index < args.length; index++) {
|
|
1015
|
-
const argument = args[index];
|
|
1016
|
-
if (argument === "--for") {
|
|
1017
|
-
normalized.push("--kind", args[++index] ?? "");
|
|
1018
|
-
continue;
|
|
1019
|
-
}
|
|
1020
|
-
normalized.push(argument);
|
|
1021
|
-
if (argument === "--json" && !args[index + 1]?.startsWith("--")) continue;
|
|
1022
|
-
if (argument === "--json") normalized.push("true");
|
|
1023
|
-
}
|
|
1024
|
-
return normalized;
|
|
1025
|
-
}
|
|
1026
889
|
|
|
1027
890
|
export async function runNativeDeepInterviewCommand(
|
|
1028
891
|
args: string[],
|
|
1029
892
|
cwd = process.cwd(),
|
|
1030
893
|
): Promise<DeepInterviewCommandResult> {
|
|
1031
894
|
try {
|
|
895
|
+
const [firstArg, ...restArgs] = args;
|
|
896
|
+
if (isDeepInterviewStageVerb(firstArg)) return await runDeepInterviewStageCommand(firstArg, restArgs, cwd);
|
|
1032
897
|
if (isDeepInterviewSpecWriteInvocation(args)) return await handleSpecWrite(args, cwd);
|
|
1033
|
-
if (isDeepInterviewRepairInvocation(args)) return await runDeepInterviewRepairCommand(args, cwd);
|
|
1034
|
-
if (isDeepInterviewDraftInvocation(args)) return await runDeepInterviewDraftCommand(draftCommandArgs(args), cwd);
|
|
1035
898
|
const resolved = await resolveDeepInterviewArgs(args, cwd);
|
|
1036
899
|
if (!resolved.idea) {
|
|
1037
|
-
const existing = await readExistingStateForMutation(deepInterviewStatePath(cwd, resolved.sessionId));
|
|
1038
|
-
if (existing.kind === "valid") {
|
|
1039
|
-
const phase =
|
|
1040
|
-
typeof existing.value.current_phase === "string" ? existing.value.current_phase : "interviewing";
|
|
1041
|
-
if (phase === "complete" || existing.value.active === false)
|
|
1042
|
-
throw new DeepInterviewCommandError(
|
|
1043
|
-
2,
|
|
1044
|
-
"deep-interview session is terminal; start a new session to kick off another interview.",
|
|
1045
|
-
);
|
|
1046
|
-
const state = existing.value.state as Record<string, unknown> | undefined;
|
|
1047
|
-
return {
|
|
1048
|
-
status: 0,
|
|
1049
|
-
stdout: `${JSON.stringify({
|
|
1050
|
-
skill: "deep-interview",
|
|
1051
|
-
resumed: true,
|
|
1052
|
-
session_id: resolved.sessionId ?? null,
|
|
1053
|
-
state_path: deepInterviewStatePath(cwd, resolved.sessionId),
|
|
1054
|
-
state_revision: existing.value.state_revision ?? 0,
|
|
1055
|
-
idea: typeof state?.initial_idea === "string" ? state.initial_idea : null,
|
|
1056
|
-
handoff: "/skill:deep-interview",
|
|
1057
|
-
})}\n`,
|
|
1058
|
-
};
|
|
1059
|
-
}
|
|
1060
900
|
throw new DeepInterviewCommandError(
|
|
1061
901
|
2,
|
|
1062
902
|
'gjc deep-interview requires an idea, e.g. `gjc deep-interview "<idea>"`.',
|
|
1063
903
|
);
|
|
1064
904
|
}
|
|
1065
|
-
const
|
|
905
|
+
const statePath = await seedDeepInterviewState(cwd, resolved);
|
|
1066
906
|
|
|
1067
907
|
const summary = {
|
|
1068
908
|
skill: "deep-interview",
|
|
@@ -1072,14 +912,13 @@ export async function runNativeDeepInterviewCommand(
|
|
|
1072
912
|
idea: resolved.idea,
|
|
1073
913
|
language: resolved.language,
|
|
1074
914
|
trace: resolved.trace,
|
|
1075
|
-
state_path:
|
|
1076
|
-
warnings: seeded.warnings,
|
|
915
|
+
state_path: statePath,
|
|
1077
916
|
handoff: "/skill:deep-interview",
|
|
1078
917
|
};
|
|
1079
918
|
const stdout = resolved.json
|
|
1080
919
|
? `${JSON.stringify(summary)}\n`
|
|
1081
920
|
: [
|
|
1082
|
-
`deep-interview seed state_path=${
|
|
921
|
+
`deep-interview seed state_path=${statePath}`,
|
|
1083
922
|
`resolution=${resolved.resolution} threshold=${resolved.threshold} threshold_source=${resolved.thresholdSource}`,
|
|
1084
923
|
resolved.trace ? `trace=enabled bounded_paths=${resolved.trace.relevant_paths.length}` : undefined,
|
|
1085
924
|
"handoff=/skill:deep-interview",
|