@gajae-code/coding-agent 0.11.7 → 0.11.9
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 +73 -1
- package/dist/types/cli/args.d.ts +0 -2
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/config/keybindings.d.ts +33 -3
- package/dist/types/config/model-profile-activation.d.ts +4 -3
- package/dist/types/config/model-profile-contract.d.ts +38 -0
- package/dist/types/config/model-profiles.d.ts +2 -3
- package/dist/types/config/settings-schema.d.ts +15 -2
- package/dist/types/edit/modes/patch.d.ts +13 -0
- package/dist/types/edit/path-mutation-lock.d.ts +15 -0
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/eval/py/tool-bridge.d.ts +1 -2
- package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +12 -5
- package/dist/types/gjc-runtime/deep-interview-draft.d.ts +8 -0
- package/dist/types/gjc-runtime/deep-interview-payload.d.ts +41 -0
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +32 -17
- package/dist/types/gjc-runtime/deep-interview-repair.d.ts +17 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +135 -4
- package/dist/types/gjc-runtime/repository-binding.d.ts +63 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +44 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +1 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +24 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +5 -3
- package/dist/types/main.d.ts +8 -0
- package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
- package/dist/types/modes/components/tool-status-header.d.ts +3 -2
- package/dist/types/modes/components/welcome.d.ts +4 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +5 -2
- package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
- package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
- package/dist/types/modes/types.d.ts +3 -0
- package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
- package/dist/types/runtime-mcp/manager.d.ts +1 -1
- package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
- package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
- package/dist/types/runtime-mcp/redaction.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +7 -1
- package/dist/types/sdk/bus/config-commands.d.ts +2 -2
- package/dist/types/sdk/bus/config.d.ts +2 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +25 -0
- package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +105 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +15 -3
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +128 -1
- package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +1 -1
- package/dist/types/sdk/host/query/handlers.d.ts +9 -0
- package/dist/types/sdk/index.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +88 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/sdk/startup-capability.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +2 -0
- package/dist/types/session/internal/managed-session-scope.d.ts +22 -3
- package/dist/types/session/internal/managed-session-storage.d.ts +24 -4
- package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
- package/dist/types/session/session-manager.d.ts +5 -1
- package/dist/types/session/session-storage.d.ts +31 -0
- package/dist/types/skill-state/active-state.d.ts +4 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/receipt.d.ts +2 -0
- package/dist/types/task/types.d.ts +94 -0
- package/dist/types/tools/ask.d.ts +454 -174
- package/dist/types/tools/image-gen.d.ts +47 -1
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/utils/prompt-suggestion.d.ts +33 -0
- package/package.json +8 -8
- package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
- package/scripts/dogfood-repository-binding.ts +209 -0
- package/scripts/generate-sdk-operation-inventory.ts +2 -0
- package/scripts/run-test-manifest.ts +4 -4
- package/src/cli/args.ts +2 -92
- package/src/cli/mcp-cli.ts +4 -21
- package/src/cli/notify-cli.ts +5 -38
- package/src/cli.ts +50 -0
- package/src/commands/deep-interview.ts +9 -4
- package/src/commands/sdk.ts +2 -2
- package/src/commit/agentic/index.ts +3 -3
- package/src/commit/map-reduce/index.ts +2 -2
- package/src/config/keybindings.ts +157 -24
- package/src/config/model-profile-activation.ts +7 -18
- package/src/config/model-profile-contract.ts +161 -0
- package/src/config/model-profiles.ts +2 -3
- package/src/config/model-registry.ts +11 -1
- package/src/config/settings-schema.ts +17 -2
- package/src/coordinator-mcp/model-preset.ts +21 -74
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +80 -165
- package/src/defaults/gjc/skills/ralplan/SKILL.md +3 -1
- package/src/edit/index.ts +3 -6
- package/src/edit/modes/patch.ts +38 -1
- package/src/edit/modes/replace.ts +42 -0
- package/src/edit/path-mutation-lock.ts +112 -0
- package/src/eval/py/executor.ts +30 -11
- package/src/eval/py/prelude.py +2 -2
- package/src/eval/py/tool-bridge.ts +34 -18
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +2 -1
- package/src/gjc-runtime/deep-interview-ambiguity.ts +68 -47
- package/src/gjc-runtime/deep-interview-draft.ts +842 -0
- package/src/gjc-runtime/deep-interview-payload.ts +262 -0
- package/src/gjc-runtime/deep-interview-recorder.ts +294 -226
- package/src/gjc-runtime/deep-interview-repair.ts +1674 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +264 -103
- package/src/gjc-runtime/deep-interview-state.ts +916 -4
- package/src/gjc-runtime/launch-tmux.ts +1 -1
- package/src/gjc-runtime/managed-owner-supervisor.ts +83 -4
- package/src/gjc-runtime/ralplan-runtime.ts +78 -4
- package/src/gjc-runtime/repository-binding.ts +267 -0
- package/src/gjc-runtime/session-state-sidecar.ts +25 -9
- package/src/gjc-runtime/state-writer.ts +166 -2
- package/src/gjc-runtime/tmux-owner-isolation.ts +2 -1
- package/src/gjc-runtime/tmux-sessions.ts +45 -6
- package/src/gjc-runtime/ultragoal-guard.ts +5 -5
- package/src/gjc-runtime/ultragoal-runtime.ts +181 -19
- package/src/gjc-runtime/workflow-manifest.generated.json +386 -1
- package/src/gjc-runtime/workflow-manifest.ts +191 -5
- package/src/internal-urls/docs-index.generated.ts +8 -6
- package/src/internal-urls/local-protocol.ts +33 -16
- package/src/internal-urls/mcp-protocol.ts +73 -11
- package/src/main.ts +25 -10
- package/src/modes/DESIGN.md +5 -0
- package/src/modes/acp/acp-agent.ts +50 -16
- package/src/modes/components/model-selector.ts +42 -8
- package/src/modes/components/plan-preview-overlay.ts +1 -1
- package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
- package/src/modes/components/tool-status-header.ts +20 -4
- package/src/modes/components/welcome.ts +32 -20
- package/src/modes/controllers/command-controller.ts +97 -54
- package/src/modes/controllers/event-controller.ts +10 -0
- package/src/modes/controllers/input-controller.ts +7 -2
- package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
- package/src/modes/controllers/selector-controller.ts +46 -54
- package/src/modes/interactive-mode.ts +70 -36
- package/src/modes/prompt-action-autocomplete.ts +32 -13
- package/src/modes/prompt-suggestion-controller.ts +96 -0
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
- package/src/modes/types.ts +3 -0
- package/src/modes/utils/hotkeys-markdown.ts +64 -36
- package/src/modes/utils/ui-helpers.ts +5 -3
- package/src/prompts/agents/architect.md +0 -1
- package/src/prompts/agents/critic.md +0 -1
- package/src/prompts/system/prompt-suggestion-system.md +32 -0
- package/src/prompts/system/system-prompt.md +7 -4
- package/src/prompts/tools/cron.md +3 -1
- package/src/runtime-mcp/json-rpc.ts +7 -4
- package/src/runtime-mcp/manager.ts +51 -53
- package/src/runtime-mcp/oauth-flow.ts +0 -72
- package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
- package/src/runtime-mcp/redaction.ts +30 -0
- package/src/runtime-mcp/transports/http.ts +13 -6
- package/src/sdk/broker/broker.ts +34 -20
- package/src/sdk/broker/lifecycle.ts +185 -36
- package/src/sdk/broker/session-index.ts +11 -1
- package/src/sdk/bus/chat-daemon-control.ts +20 -5
- package/src/sdk/bus/config-commands.ts +2 -2
- package/src/sdk/bus/config.ts +9 -1
- package/src/sdk/bus/conversation-store.ts +40 -6
- package/src/sdk/bus/index.ts +240 -65
- package/src/sdk/bus/lifecycle-commands.ts +47 -3
- package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
- package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
- package/src/sdk/bus/notification-orchestration.ts +12 -0
- package/src/sdk/bus/notification-service.ts +27 -2
- package/src/sdk/bus/prompt-reconciliation.ts +239 -0
- package/src/sdk/bus/recent-activity.ts +90 -26
- package/src/sdk/bus/telegram-daemon-contract.ts +15 -3
- package/src/sdk/bus/telegram-daemon-control.ts +145 -33
- package/src/sdk/bus/telegram-daemon.ts +853 -112
- package/src/sdk/bus/telegram-reference.ts +20 -2
- package/src/sdk/cli/session-cli.ts +15 -2
- package/src/sdk/host/control/dispatch.ts +1 -1
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/host.ts +2 -6
- package/src/sdk/host/query/handlers.ts +70 -5
- package/src/sdk/index.ts +12 -0
- package/src/sdk/prompt-status.ts +97 -0
- package/src/sdk/protocol/operation-inventory.generated.json +47 -0
- package/src/sdk/protocol/operation-registry.ts +18 -4
- package/src/sdk/session-directory.ts +5 -1
- package/src/sdk/session.ts +2 -0
- package/src/sdk/startup-capability.ts +9 -1
- package/src/session/agent-session.ts +138 -5
- package/src/session/blob-store.ts +7 -2
- package/src/session/internal/managed-session-scope.ts +998 -133
- package/src/session/internal/managed-session-storage.ts +268 -203
- package/src/session/internal/native-publish-outcome.ts +266 -0
- package/src/session/session-manager.ts +406 -360
- package/src/session/session-storage.ts +151 -11
- package/src/skill-state/active-state.ts +10 -0
- package/src/task/executor.ts +13 -5
- package/src/task/gjc-command.ts +2 -2
- package/src/task/index.ts +121 -15
- package/src/task/receipt.ts +3 -0
- package/src/task/types.ts +34 -3
- package/src/tools/ask.ts +199 -88
- package/src/tools/ast-edit.ts +2 -2
- package/src/tools/bash-pty-selection.ts +2 -2
- package/src/tools/browser/screenshot-format.ts +6 -1
- package/src/tools/cron.ts +1 -1
- package/src/tools/image-gen.ts +178 -6
- package/src/tools/index.ts +4 -0
- package/src/tools/render-utils.ts +7 -1
- package/src/utils/edit-mode.ts +2 -2
- package/src/utils/prompt-suggestion.ts +265 -0
- package/src/utils/sixel.ts +3 -3
- package/src/web/insane/url-guard.ts +3 -1
- package/src/web/scrapers/docs-rs.ts +30 -5
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product-surface dogfood for #2901 repository binding.
|
|
3
|
+
*
|
|
4
|
+
* Creates two sibling git repos, runs real `gjc ultragoal` / `gjc ralplan`
|
|
5
|
+
* CLI entrypoints from source, and prints fail-closed mismatch evidence.
|
|
6
|
+
*
|
|
7
|
+
* Usage (from monorepo root):
|
|
8
|
+
* bun packages/coding-agent/scripts/dogfood-repository-binding.ts
|
|
9
|
+
*/
|
|
10
|
+
import * as fsp from "node:fs/promises";
|
|
11
|
+
import * as os from "node:os";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import {
|
|
15
|
+
assertCwdMatchesRepositoryBinding,
|
|
16
|
+
assertPathUnderRepositoryBinding,
|
|
17
|
+
parseRepositoryBinding,
|
|
18
|
+
resolveTaskRepositoryBinding,
|
|
19
|
+
} from "../src/gjc-runtime/repository-binding";
|
|
20
|
+
import { readUltragoalPlan, startNextUltragoalGoal } from "../src/gjc-runtime/ultragoal-runtime";
|
|
21
|
+
|
|
22
|
+
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../..");
|
|
23
|
+
const cli = path.join(repoRoot, "packages/coding-agent/src/cli.ts");
|
|
24
|
+
|
|
25
|
+
async function runGit(cwd: string, args: string[]): Promise<void> {
|
|
26
|
+
const proc = Bun.spawn(["git", ...args], { cwd, stdout: "pipe", stderr: "pipe" });
|
|
27
|
+
const code = await proc.exited;
|
|
28
|
+
if (code !== 0) throw new Error(`git ${args.join(" ")} failed: ${await new Response(proc.stderr).text()}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function initRepo(root: string): Promise<void> {
|
|
32
|
+
await fsp.mkdir(root, { recursive: true });
|
|
33
|
+
await runGit(root, ["init"]);
|
|
34
|
+
await runGit(root, ["config", "user.email", "dogfood@example.com"]);
|
|
35
|
+
await runGit(root, ["config", "user.name", "Dogfood"]);
|
|
36
|
+
await fsp.writeFile(path.join(root, "README.md"), `repo ${path.basename(root)}\n`);
|
|
37
|
+
await runGit(root, ["add", "README.md"]);
|
|
38
|
+
await runGit(root, ["commit", "-m", `init ${path.basename(root)}`]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function runCli(
|
|
42
|
+
cwd: string,
|
|
43
|
+
args: string[],
|
|
44
|
+
env: NodeJS.ProcessEnv,
|
|
45
|
+
): Promise<{ code: number; stdout: string; stderr: string }> {
|
|
46
|
+
const proc = Bun.spawn(["bun", cli, ...args], { cwd, env, stdout: "pipe", stderr: "pipe" });
|
|
47
|
+
const [code, stdout, stderr] = await Promise.all([
|
|
48
|
+
proc.exited,
|
|
49
|
+
new Response(proc.stdout).text(),
|
|
50
|
+
new Response(proc.stderr).text(),
|
|
51
|
+
]);
|
|
52
|
+
return { code, stdout, stderr };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function main(): Promise<void> {
|
|
56
|
+
const dogfoodRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "gjc-dogfood-2901-"));
|
|
57
|
+
const left = path.join(dogfoodRoot, "gajae-code");
|
|
58
|
+
const right = path.join(dogfoodRoot, "oh-my-openagent-senpi");
|
|
59
|
+
await initRepo(left);
|
|
60
|
+
await initRepo(right);
|
|
61
|
+
|
|
62
|
+
const sessionId = `dogfood-2901-${process.pid}`;
|
|
63
|
+
const env = { ...process.env, GJC_SESSION_ID: sessionId };
|
|
64
|
+
|
|
65
|
+
console.log("# Dogfood: repository binding (#2901)");
|
|
66
|
+
console.log(`root=${dogfoodRoot}`);
|
|
67
|
+
console.log(`left=${left}`);
|
|
68
|
+
console.log(`right=${right}`);
|
|
69
|
+
console.log(`session=${sessionId}`);
|
|
70
|
+
console.log(`cli=${cli}`);
|
|
71
|
+
console.log(`bun=${Bun.version}`);
|
|
72
|
+
console.log(
|
|
73
|
+
`commit=${Bun.spawnSync(["git", "-C", repoRoot, "rev-parse", "--short", "HEAD"]).stdout.toString().trim()}`,
|
|
74
|
+
);
|
|
75
|
+
console.log();
|
|
76
|
+
|
|
77
|
+
// 1) Product CLI: create goals stamps binding
|
|
78
|
+
const create = await runCli(
|
|
79
|
+
left,
|
|
80
|
+
[
|
|
81
|
+
"ultragoal",
|
|
82
|
+
"create-goals",
|
|
83
|
+
"--brief",
|
|
84
|
+
"@goal dogfood binding\nProve repository binding stamps and fail-closed sibling mismatch.",
|
|
85
|
+
"--json",
|
|
86
|
+
],
|
|
87
|
+
env,
|
|
88
|
+
);
|
|
89
|
+
console.log("## 1) gjc ultragoal create-goals (LEFT)");
|
|
90
|
+
console.log(`exit=${create.code}`);
|
|
91
|
+
console.log(create.stdout.trim() || create.stderr.trim());
|
|
92
|
+
if (create.code !== 0) process.exit(1);
|
|
93
|
+
|
|
94
|
+
const plan = await readUltragoalPlan(left, sessionId);
|
|
95
|
+
if (!plan?.repositoryBinding) {
|
|
96
|
+
console.error("FAIL: plan missing repositoryBinding");
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
console.log();
|
|
100
|
+
console.log("## 2) goals.json repositoryBinding");
|
|
101
|
+
console.log(JSON.stringify(plan.repositoryBinding, null, 2));
|
|
102
|
+
|
|
103
|
+
// 2) Matching cwd starts goal
|
|
104
|
+
console.log();
|
|
105
|
+
console.log("## 3) startNextUltragoalGoal on LEFT (match)");
|
|
106
|
+
const started = await startNextUltragoalGoal({ cwd: left, sessionId });
|
|
107
|
+
console.log(`ok goal=${started.goal?.id} status=${started.goal?.status}`);
|
|
108
|
+
|
|
109
|
+
// 3) Sibling mismatch fails closed
|
|
110
|
+
console.log();
|
|
111
|
+
console.log("## 4) assertCwdMatchesRepositoryBinding on RIGHT (sibling)");
|
|
112
|
+
try {
|
|
113
|
+
await assertCwdMatchesRepositoryBinding(right, plan.repositoryBinding);
|
|
114
|
+
console.error("FAIL: expected identity_mismatch");
|
|
115
|
+
process.exit(1);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.log(`fail_closed: ${error instanceof Error ? error.message : String(error)}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 4) Path escape fails closed
|
|
121
|
+
console.log();
|
|
122
|
+
console.log("## 5) assertPathUnderRepositoryBinding sibling absolute path");
|
|
123
|
+
try {
|
|
124
|
+
assertPathUnderRepositoryBinding(plan.repositoryBinding, path.join(right, "README.md"));
|
|
125
|
+
console.error("FAIL: expected path_outside_root");
|
|
126
|
+
process.exit(1);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.log(`fail_closed: ${error instanceof Error ? error.message : String(error)}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 5) Task binding stamp + sibling fail-closed (pre-discovery authority)
|
|
132
|
+
console.log();
|
|
133
|
+
console.log("## 6) task binding stamp (omit declaration) + sibling reject");
|
|
134
|
+
const stamped = await resolveTaskRepositoryBinding(left, undefined);
|
|
135
|
+
console.log(`stamped_worktreeRoot=${stamped.worktreeRoot}`);
|
|
136
|
+
await assertCwdMatchesRepositoryBinding(left, stamped);
|
|
137
|
+
console.log("task_stamp_ok on LEFT");
|
|
138
|
+
const taskBinding = parseRepositoryBinding(plan.repositoryBinding);
|
|
139
|
+
try {
|
|
140
|
+
await resolveTaskRepositoryBinding(right, taskBinding);
|
|
141
|
+
console.error("FAIL: task binding should reject RIGHT");
|
|
142
|
+
process.exit(1);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.log(`task_binding_fail_closed on RIGHT: ${error instanceof Error ? error.message : String(error)}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 6) Ralplan seed stamps binding via product CLI
|
|
148
|
+
console.log();
|
|
149
|
+
console.log("## 7) gjc ralplan seed (LEFT)");
|
|
150
|
+
const ralplan = await runCli(left, ["ralplan", "--json", "dogfood multi-repo binding"], env);
|
|
151
|
+
console.log(`exit=${ralplan.code}`);
|
|
152
|
+
console.log(ralplan.stdout.trim() || ralplan.stderr.trim());
|
|
153
|
+
if (ralplan.code !== 0) process.exit(1);
|
|
154
|
+
const statePath = path.join(left, ".gjc", `_session-${sessionId}`, "state", "ralplan-state.json");
|
|
155
|
+
const state = JSON.parse(await fsp.readFile(statePath, "utf8")) as {
|
|
156
|
+
repository_binding?: unknown;
|
|
157
|
+
run_id?: string;
|
|
158
|
+
};
|
|
159
|
+
console.log();
|
|
160
|
+
console.log("## 8) ralplan-state.json repository_binding");
|
|
161
|
+
console.log(JSON.stringify({ run_id: state.run_id, repository_binding: state.repository_binding }, null, 2));
|
|
162
|
+
if (!state.repository_binding) {
|
|
163
|
+
console.error("FAIL: ralplan state missing repository_binding");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 7) Ralplan stage write on LEFT succeeds and echoes repository_binding
|
|
168
|
+
console.log();
|
|
169
|
+
console.log("## 9) gjc ralplan --write planner on LEFT (match)");
|
|
170
|
+
const notePath = path.join(left, "dogfood-planner.md");
|
|
171
|
+
await fsp.writeFile(notePath, "# dogfood planner\n");
|
|
172
|
+
const writeLeft = await runCli(
|
|
173
|
+
left,
|
|
174
|
+
["ralplan", "--write", "--stage", "planner", "--stage_n", "1", "--artifact", notePath, "--json"],
|
|
175
|
+
env,
|
|
176
|
+
);
|
|
177
|
+
console.log(`exit=${writeLeft.code}`);
|
|
178
|
+
console.log(writeLeft.stdout.trim() || writeLeft.stderr.trim());
|
|
179
|
+
if (writeLeft.code !== 0) process.exit(1);
|
|
180
|
+
const writePayload = JSON.parse(writeLeft.stdout) as { repository_binding?: { worktreeRoot?: string } };
|
|
181
|
+
if (!writePayload.repository_binding?.worktreeRoot) {
|
|
182
|
+
console.error("FAIL: write receipt missing repository_binding");
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 8) Copy seed authority into RIGHT session layout → stage write fails closed
|
|
187
|
+
console.log();
|
|
188
|
+
console.log("## 10) ralplan --write on RIGHT with LEFT binding (fail-closed)");
|
|
189
|
+
const rightStateDir = path.join(right, ".gjc", `_session-${sessionId}`, "state");
|
|
190
|
+
await fsp.mkdir(rightStateDir, { recursive: true });
|
|
191
|
+
await fsp.copyFile(statePath, path.join(rightStateDir, "ralplan-state.json"));
|
|
192
|
+
const writeRight = await runCli(
|
|
193
|
+
right,
|
|
194
|
+
["ralplan", "--write", "--stage", "architect", "--stage_n", "1", "--artifact", "# arch\n", "--json"],
|
|
195
|
+
env,
|
|
196
|
+
);
|
|
197
|
+
console.log(`exit=${writeRight.code}`);
|
|
198
|
+
console.log((writeRight.stderr || writeRight.stdout).trim());
|
|
199
|
+
if (writeRight.code === 0) {
|
|
200
|
+
console.error("FAIL: expected sibling write to fail closed");
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
console.log("fail_closed: ralplan write on sibling rejected");
|
|
204
|
+
|
|
205
|
+
console.log();
|
|
206
|
+
console.log("DOGFOOD_OK");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await main();
|
|
@@ -39,6 +39,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
39
39
|
"agent_session:setForcedToolChoice": "internal accessor/plumbing, not a user-facing control seam",
|
|
40
40
|
"agent_session:getActiveSkillState": "internal accessor/plumbing, not a user-facing control seam",
|
|
41
41
|
"agent_session:getActiveSkillPhase": "internal accessor/plumbing, not a user-facing control seam",
|
|
42
|
+
"agent_session:getDeepInterviewAskStage":
|
|
43
|
+
"internal AskTool schema-selection accessor, not a user-facing SDK control seam",
|
|
42
44
|
"agent_session:peekQueueInvoker": "internal accessor/plumbing, not a user-facing control seam",
|
|
43
45
|
"agent_session:peekStandingResolveHandler": "internal accessor/plumbing, not a user-facing control seam",
|
|
44
46
|
"agent_session:setStandingResolveHandler": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -60,11 +60,11 @@ function validateRowReceipts(rows: ManifestAdapterRow[]): void {
|
|
|
60
60
|
}
|
|
61
61
|
counts.set(row.adapter, (counts.get(row.adapter) ?? 0) + 1);
|
|
62
62
|
}
|
|
63
|
-
if (rows.length !== ADAPTERS.length *
|
|
64
|
-
throw new Error(`Expected ${ADAPTERS.length *
|
|
63
|
+
if (rows.length !== ADAPTERS.length * 93)
|
|
64
|
+
throw new Error(`Expected ${ADAPTERS.length * 93} adapter rows; received ${rows.length}.`);
|
|
65
65
|
for (const adapter of ADAPTERS) {
|
|
66
|
-
if (counts.get(adapter) !==
|
|
67
|
-
throw new Error(`Expected
|
|
66
|
+
if (counts.get(adapter) !== 93)
|
|
67
|
+
throw new Error(`Expected 93 ${adapter} rows; received ${counts.get(adapter) ?? 0}.`);
|
|
68
68
|
}
|
|
69
69
|
process.stdout.write(
|
|
70
70
|
`manifest check: ${rows.length} row receipts (${[...counts].map(([adapter, count]) => `${adapter}=${count}`).join(", ")})\n`,
|
package/src/cli/args.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI argument parsing
|
|
2
|
+
* CLI argument parsing
|
|
3
3
|
*/
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { type Effort, THINKING_EFFORTS } from "@gajae-code/ai";
|
|
6
|
-
import {
|
|
6
|
+
import { logger } from "@gajae-code/utils";
|
|
7
7
|
import { CliParseError } from "@gajae-code/utils/cli";
|
|
8
|
-
import chalk from "chalk";
|
|
9
8
|
import { parseEffort } from "../thinking";
|
|
10
9
|
import { BUILTIN_TOOLS } from "../tools";
|
|
11
10
|
|
|
@@ -253,92 +252,3 @@ export function parseArgs(args: string[]): Args {
|
|
|
253
252
|
|
|
254
253
|
return result;
|
|
255
254
|
}
|
|
256
|
-
|
|
257
|
-
export function getExtraHelpText(): string {
|
|
258
|
-
return `${chalk.bold("Environment Variables:")}
|
|
259
|
-
${chalk.dim("# Core Providers")}
|
|
260
|
-
ANTHROPIC_API_KEY - Anthropic Claude models
|
|
261
|
-
ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth (takes precedence over API key)
|
|
262
|
-
CLAUDE_CODE_USE_FOUNDRY - Enable Anthropic Foundry mode (uses Foundry endpoint + mTLS)
|
|
263
|
-
FOUNDRY_BASE_URL - Anthropic Foundry base URL (e.g., https://<foundry-host>)
|
|
264
|
-
ANTHROPIC_FOUNDRY_API_KEY - Anthropic token used as Authorization: Bearer <token> in Foundry mode
|
|
265
|
-
ANTHROPIC_CUSTOM_HEADERS - Extra Foundry headers (e.g., "user-id: USERNAME")
|
|
266
|
-
CLAUDE_CODE_CLIENT_CERT - Client certificate (PEM path or inline PEM) for mTLS
|
|
267
|
-
CLAUDE_CODE_CLIENT_KEY - Client private key (PEM path or inline PEM) for mTLS
|
|
268
|
-
NODE_EXTRA_CA_CERTS - CA bundle path (or inline PEM) for server certificate validation
|
|
269
|
-
OPENAI_API_KEY - OpenAI GPT models
|
|
270
|
-
GEMINI_API_KEY - Google Gemini models
|
|
271
|
-
GITHUB_TOKEN - GitHub Copilot (or GH_TOKEN, COPILOT_GITHUB_TOKEN)
|
|
272
|
-
|
|
273
|
-
${chalk.dim("# Additional LLM Providers")}
|
|
274
|
-
AZURE_OPENAI_API_KEY - Azure OpenAI models
|
|
275
|
-
GROQ_API_KEY - Groq models
|
|
276
|
-
CEREBRAS_API_KEY - Cerebras models
|
|
277
|
-
XAI_API_KEY - xAI Grok models
|
|
278
|
-
OPENROUTER_API_KEY - OpenRouter aggregated models
|
|
279
|
-
KILO_API_KEY - Kilo Gateway models
|
|
280
|
-
MISTRAL_API_KEY - Mistral models
|
|
281
|
-
ZAI_API_KEY - z.ai models (ZhipuAI/GLM)
|
|
282
|
-
MINIMAX_API_KEY - MiniMax models
|
|
283
|
-
OPENCODE_API_KEY - OpenCode Zen/OpenCode Go models
|
|
284
|
-
CURSOR_ACCESS_TOKEN - Cursor AI models
|
|
285
|
-
AI_GATEWAY_API_KEY - Vercel AI Gateway
|
|
286
|
-
|
|
287
|
-
${chalk.dim("# Cloud Providers")}
|
|
288
|
-
AWS_PROFILE - AWS Bedrock (or AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)
|
|
289
|
-
GOOGLE_CLOUD_PROJECT - Google Vertex AI (requires GOOGLE_CLOUD_LOCATION)
|
|
290
|
-
GOOGLE_APPLICATION_CREDENTIALS - Service account for Vertex AI
|
|
291
|
-
|
|
292
|
-
${chalk.dim("# Search & Tools")}
|
|
293
|
-
EXA_API_KEY - Exa web search
|
|
294
|
-
BRAVE_API_KEY - Brave web search
|
|
295
|
-
PERPLEXITY_API_KEY - Perplexity web search (API)
|
|
296
|
-
PERPLEXITY_COOKIES - Perplexity web search (session cookie)
|
|
297
|
-
TAVILY_API_KEY - Tavily web search
|
|
298
|
-
ANTHROPIC_SEARCH_API_KEY - Anthropic search provider
|
|
299
|
-
|
|
300
|
-
${chalk.dim("# Configuration")}
|
|
301
|
-
GJC_CODING_AGENT_DIR - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)
|
|
302
|
-
GJC_PACKAGE_DIR - Override package directory (for Nix/Guix store paths)
|
|
303
|
-
GJC_SMOL_MODEL - Override smol/fast model (see --smol)
|
|
304
|
-
GJC_SLOW_MODEL - Override slow/reasoning model (see --slow)
|
|
305
|
-
GJC_PLAN_MODEL - Override planning model (see --plan)
|
|
306
|
-
GJC_NO_PTY - Disable PTY-based interactive bash execution
|
|
307
|
-
--tmux - Launch interactive startup inside a fresh tmux session
|
|
308
|
-
gjc session - List, inspect, create, remove, or attach tagged GJC-managed tmux sessions
|
|
309
|
-
GJC_LAUNCH_POLICY - Launch policy for --tmux startup: tmux or direct
|
|
310
|
-
GJC_TMUX_SESSION - Explicit tmux session name override for --tmux startup
|
|
311
|
-
GJC_TMUX_PROFILE - Apply GJC tmux scroll/mouse/clipboard profile to --tmux sessions (set 0/off to skip)
|
|
312
|
-
GJC_MOUSE - Mouse-wheel scroll in --tmux sessions (set 0/off to let the host terminal scroll)
|
|
313
|
-
|
|
314
|
-
For complete environment variable reference, see:
|
|
315
|
-
${chalk.dim("docs/environment-variables.md")}
|
|
316
|
-
${chalk.bold("Available Tools (default-enabled unless noted):")}
|
|
317
|
-
read - Read file contents
|
|
318
|
-
bash - Execute bash commands
|
|
319
|
-
edit - Edit files with find/replace
|
|
320
|
-
write - Write files (creates/overwrites)
|
|
321
|
-
grep - Search file contents
|
|
322
|
-
find - Find files by glob pattern
|
|
323
|
-
lsp - Language server protocol (code intelligence)
|
|
324
|
-
python - Execute Python code (requires: ${APP_NAME} setup python)
|
|
325
|
-
notebook - Edit Jupyter notebooks
|
|
326
|
-
browser - Browser automation (Puppeteer)
|
|
327
|
-
task - Launch sub-agents for parallel tasks
|
|
328
|
-
todo_write - Manage todo/task lists
|
|
329
|
-
web_search - Search the web
|
|
330
|
-
ask - Ask user questions (interactive mode only)
|
|
331
|
-
|
|
332
|
-
${chalk.bold("Useful Commands:")}
|
|
333
|
-
${APP_NAME} --list-models - List configured provider models
|
|
334
|
-
${APP_NAME} --help - Show this help`;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export function printHelp(): void {
|
|
338
|
-
process.stdout.write(
|
|
339
|
-
`${chalk.bold(APP_NAME)} - red-claw AI coding assistant\n\n` +
|
|
340
|
-
`Run ${APP_NAME} --help for full command and option details.\n` +
|
|
341
|
-
`Run ${APP_NAME} <command> --help for command-specific help.\n\n` +
|
|
342
|
-
`${getExtraHelpText()}\n`,
|
|
343
|
-
);
|
|
344
|
-
}
|
package/src/cli/mcp-cli.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { getMCPConfigPath, getProjectDir } from "@gajae-code/utils";
|
|
8
8
|
import { getMCPServer, readMCPConfigFile, removeMCPServer, upsertMCPServer } from "../runtime-mcp/config-writer";
|
|
9
|
+
import { redactMCPEndpoint } from "../runtime-mcp/redaction";
|
|
9
10
|
import type { MCPConfigFile, MCPServerConfig } from "../runtime-mcp/types";
|
|
10
11
|
|
|
11
12
|
export type MCPAction = "add" | "list" | "remove";
|
|
@@ -141,24 +142,6 @@ function redactRecord(
|
|
|
141
142
|
);
|
|
142
143
|
}
|
|
143
144
|
|
|
144
|
-
function redactUrl(value: string | undefined): string | undefined {
|
|
145
|
-
if (!value) return value;
|
|
146
|
-
try {
|
|
147
|
-
const url = new URL(value);
|
|
148
|
-
if (url.username) url.username = REDACTED;
|
|
149
|
-
if (url.password) url.password = REDACTED;
|
|
150
|
-
if (url.search) {
|
|
151
|
-
for (const key of Array.from(url.searchParams.keys())) {
|
|
152
|
-
url.searchParams.set(key, REDACTED);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
url.hash = "";
|
|
156
|
-
return url.toString();
|
|
157
|
-
} catch {
|
|
158
|
-
return SENSITIVE_KEY_PATTERN.test(value) ? REDACTED : value;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
145
|
function redactArgs(args: string[] | undefined): string[] | undefined {
|
|
163
146
|
if (!args) return undefined;
|
|
164
147
|
const redacted: string[] = [];
|
|
@@ -196,7 +179,7 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
196
179
|
if (headers) redacted.headers = headers;
|
|
197
180
|
}
|
|
198
181
|
if ("url" in redacted) {
|
|
199
|
-
const url =
|
|
182
|
+
const url = redactMCPEndpoint(redacted.url);
|
|
200
183
|
if (url) redacted.url = url;
|
|
201
184
|
}
|
|
202
185
|
if ("args" in redacted) {
|
|
@@ -207,7 +190,7 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
207
190
|
redacted.auth = {
|
|
208
191
|
type: redacted.auth.type,
|
|
209
192
|
credentialId: redacted.auth.credentialId ? REDACTED : undefined,
|
|
210
|
-
tokenUrl:
|
|
193
|
+
tokenUrl: redactMCPEndpoint(redacted.auth.tokenUrl),
|
|
211
194
|
clientId: redacted.auth.clientId ? REDACTED : undefined,
|
|
212
195
|
clientSecret: redacted.auth.clientSecret ? REDACTED : undefined,
|
|
213
196
|
};
|
|
@@ -216,7 +199,7 @@ export function redactMCPServerConfig(config: MCPServerConfig): MCPServerConfig
|
|
|
216
199
|
redacted.oauth = {
|
|
217
200
|
clientId: redacted.oauth.clientId ? REDACTED : undefined,
|
|
218
201
|
clientSecret: redacted.oauth.clientSecret ? REDACTED : undefined,
|
|
219
|
-
redirectUri:
|
|
202
|
+
redirectUri: redactMCPEndpoint(redacted.oauth.redirectUri),
|
|
220
203
|
callbackPort: redacted.oauth.callbackPort,
|
|
221
204
|
callbackPath: redacted.oauth.callbackPath,
|
|
222
205
|
};
|
package/src/cli/notify-cli.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { createInterface } from "node:readline/promises";
|
|
|
7
7
|
import { APP_NAME } from "@gajae-code/utils/dirs";
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
import { Settings, type SettingsAtomicPatch } from "../config/settings";
|
|
10
|
-
import { isProcessIncarnation, processIncarnation } from "../sdk/broker/process-incarnation";
|
|
11
10
|
import { type EnsureChatDaemonResult, ensureDiscordDaemon, ensureSlackDaemon } from "../sdk/bus/chat-daemon-control";
|
|
12
11
|
import { getNotificationConfig, maskToken, tokenFingerprint } from "../sdk/bus/config";
|
|
13
12
|
import {
|
|
@@ -33,7 +32,7 @@ import {
|
|
|
33
32
|
import {
|
|
34
33
|
type EnsureTelegramDaemonDetailedResult,
|
|
35
34
|
ensureTelegramDaemonRunningDetailed,
|
|
36
|
-
|
|
35
|
+
resolveTelegramSetupPreflight,
|
|
37
36
|
} from "../sdk/bus/telegram-daemon";
|
|
38
37
|
import { runDaemonInternal } from "../sdk/bus/telegram-daemon-cli";
|
|
39
38
|
import {
|
|
@@ -458,42 +457,10 @@ function proposedIdentityFromSetupPreflight(
|
|
|
458
457
|
|
|
459
458
|
async function resolveSetupPreflight(settings: Settings, deps: NotifyCommandDeps): Promise<TelegramSetupPreflight> {
|
|
460
459
|
if (deps.setupPreflight) return deps.setupPreflight;
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const validPid = Number.isSafeInteger(state.pid) && state.pid > 0;
|
|
466
|
-
if (!validPid || !(deps.setupPidAlive ?? daemonPidAlive)(state.pid)) return { storedChatId: cfg.chatId };
|
|
467
|
-
const persistedIncarnation = state.incarnation;
|
|
468
|
-
const currentIncarnation = (deps.setupPidIncarnation ?? processIncarnation)(state.pid);
|
|
469
|
-
if (
|
|
470
|
-
!isProcessIncarnation(persistedIncarnation) ||
|
|
471
|
-
!isProcessIncarnation(currentIncarnation) ||
|
|
472
|
-
persistedIncarnation !== currentIncarnation
|
|
473
|
-
)
|
|
474
|
-
return { storedChatId: cfg.chatId };
|
|
475
|
-
return {
|
|
476
|
-
storedChatId: cfg.chatId,
|
|
477
|
-
daemon: {
|
|
478
|
-
live: true,
|
|
479
|
-
tokenFingerprint: typeof state.tokenFingerprint === "string" ? state.tokenFingerprint : undefined,
|
|
480
|
-
chatId: typeof state.chatId === "string" ? state.chatId : undefined,
|
|
481
|
-
},
|
|
482
|
-
};
|
|
483
|
-
} catch {
|
|
484
|
-
// A state read failure is not proof of a live daemon; proceed normally. The
|
|
485
|
-
// daemon's own 409 handling remains the backstop against poller contention.
|
|
486
|
-
return { storedChatId: cfg.chatId };
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
function daemonPidAlive(pid: number): boolean {
|
|
491
|
-
try {
|
|
492
|
-
process.kill(pid, 0);
|
|
493
|
-
return true;
|
|
494
|
-
} catch (error) {
|
|
495
|
-
return (error as NodeJS.ErrnoException).code === "EPERM";
|
|
496
|
-
}
|
|
460
|
+
return await resolveTelegramSetupPreflight(settings, {
|
|
461
|
+
pidAlive: deps.setupPidAlive,
|
|
462
|
+
pidIncarnation: deps.setupPidIncarnation,
|
|
463
|
+
});
|
|
497
464
|
}
|
|
498
465
|
|
|
499
466
|
type TokenPromptInput = NodeJS.ReadStream & {
|
package/src/cli.ts
CHANGED
|
@@ -8,6 +8,12 @@ import "@gajae-code/utils/postmortem";
|
|
|
8
8
|
import { Args, type CliConfig, Command, type CommandEntry, Flags, run } from "@gajae-code/utils/cli";
|
|
9
9
|
import { APP_NAME, formatBunRuntimeError, MIN_BUN_VERSION, VERSION } from "@gajae-code/utils/dirs";
|
|
10
10
|
import { runFixtureReport } from "./cli/fixture-report";
|
|
11
|
+
import { admitManagedOwnerBeforeCli, completeManagedOwnerRecovery } from "./gjc-runtime/managed-owner-admission";
|
|
12
|
+
import {
|
|
13
|
+
isManagedOwnerSupervisorArgv,
|
|
14
|
+
MANAGED_OWNER_CHILD_TOKEN_ENV,
|
|
15
|
+
runManagedOwnerSupervisor,
|
|
16
|
+
} from "./gjc-runtime/managed-owner-supervisor";
|
|
11
17
|
import { isTmuxOwnerIsolationCliArgv, runTmuxOwnerIsolationCliFromStdin } from "./gjc-runtime/tmux-owner-isolation-cli";
|
|
12
18
|
import { smokeTestTabWorker } from "./tools/browser/tab-worker-smoke";
|
|
13
19
|
|
|
@@ -112,6 +118,36 @@ Options:
|
|
|
112
118
|
`);
|
|
113
119
|
}
|
|
114
120
|
|
|
121
|
+
export function interactiveBootstrapText(
|
|
122
|
+
argv: readonly string[],
|
|
123
|
+
stdinIsTTY = process.stdin.isTTY,
|
|
124
|
+
stdoutIsTTY = process.stdout.isTTY,
|
|
125
|
+
): string | undefined {
|
|
126
|
+
if (!stdinIsTTY || !stdoutIsTTY || argv[0] !== "launch") return undefined;
|
|
127
|
+
for (let index = 1; index < argv.length; index++) {
|
|
128
|
+
const arg = argv[index];
|
|
129
|
+
if (
|
|
130
|
+
arg === "--print" ||
|
|
131
|
+
arg?.startsWith("--print=") ||
|
|
132
|
+
arg === "-p" ||
|
|
133
|
+
arg === "--export" ||
|
|
134
|
+
arg?.startsWith("--export=") ||
|
|
135
|
+
arg === "--list-models" ||
|
|
136
|
+
arg?.startsWith("--list-models=") ||
|
|
137
|
+
arg === "--mode" ||
|
|
138
|
+
arg?.startsWith("--mode=") ||
|
|
139
|
+
arg === "--help" ||
|
|
140
|
+
arg?.startsWith("--help=") ||
|
|
141
|
+
arg === "-h" ||
|
|
142
|
+
arg === "--version" ||
|
|
143
|
+
arg?.startsWith("--version=") ||
|
|
144
|
+
arg === "-v"
|
|
145
|
+
)
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
return "\u001b[?25h\u001b[38;5;45mGJC\u001b[0m warming workspace\r\n\r\n> ";
|
|
149
|
+
}
|
|
150
|
+
|
|
115
151
|
function isNotifyDaemonInternalFastPath(argv: string[]): boolean {
|
|
116
152
|
return argv[0] === "notify" && argv[1] === "daemon-internal";
|
|
117
153
|
}
|
|
@@ -350,6 +386,18 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
350
386
|
await runTmuxOwnerIsolationCliFromStdin();
|
|
351
387
|
return;
|
|
352
388
|
}
|
|
389
|
+
if (isManagedOwnerSupervisorArgv(argv)) {
|
|
390
|
+
await runManagedOwnerSupervisor();
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (process.env[MANAGED_OWNER_CHILD_TOKEN_ENV] !== undefined) {
|
|
394
|
+
const admission = await admitManagedOwnerBeforeCli();
|
|
395
|
+
if (admission.kind === "blocked") return;
|
|
396
|
+
if (admission.kind === "recovery") {
|
|
397
|
+
await completeManagedOwnerRecovery(admission.context);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
353
401
|
if (isNotifyDaemonInternalFastPath(argv)) {
|
|
354
402
|
await runNotifyDaemonInternalFastPath(argv);
|
|
355
403
|
return;
|
|
@@ -394,6 +442,8 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
394
442
|
showStatsFastHelp();
|
|
395
443
|
return;
|
|
396
444
|
}
|
|
445
|
+
const bootstrap = interactiveBootstrapText(runArgv);
|
|
446
|
+
if (bootstrap) process.stdout.write(bootstrap);
|
|
397
447
|
await installRuntimeGlobals();
|
|
398
448
|
return run({ bin: APP_NAME, version: VERSION, argv: runArgv, commands, help: showHelp });
|
|
399
449
|
}
|
|
@@ -2,7 +2,8 @@ import { Command, Flags } from "@gajae-code/utils/cli";
|
|
|
2
2
|
import { runNativeDeepInterviewCommand } from "../gjc-runtime/deep-interview-runtime";
|
|
3
3
|
|
|
4
4
|
export default class DeepInterview extends Command {
|
|
5
|
-
static description =
|
|
5
|
+
static description =
|
|
6
|
+
"Run native GJC deep-interview workflow. Use `draft` for editable CLI-owned mutation inputs; JSON repair verbs are compatibility-only.";
|
|
6
7
|
static strict = false;
|
|
7
8
|
static flags = {
|
|
8
9
|
quick: Flags.boolean({ description: "Seed a quick deep-interview run" }),
|
|
@@ -26,9 +27,13 @@ export default class DeepInterview extends Command {
|
|
|
26
27
|
json: Flags.boolean({ description: "Output JSON" }),
|
|
27
28
|
};
|
|
28
29
|
static examples = [
|
|
29
|
-
'$ gjc deep-interview --trace --standard "<idea>"',
|
|
30
|
-
"$ gjc deep-interview
|
|
31
|
-
"$ gjc deep-interview --
|
|
30
|
+
'$ gjc deep-interview --trace --standard "<idea>" --json',
|
|
31
|
+
"$ gjc deep-interview draft create --for initialize-context --session-id <id> --json",
|
|
32
|
+
"$ gjc deep-interview draft edit --draft-id <id> --expected-draft-revision 1 --op set --path /type --value greenfield --json",
|
|
33
|
+
"$ gjc deep-interview draft check --draft-id <id> --json",
|
|
34
|
+
"$ gjc deep-interview initialize-context --draft-id <id> --expected-draft-revision <n> --json",
|
|
35
|
+
"$ gjc deep-interview --write --stage final --slug my-feature --spec ./final-spec.md --json",
|
|
36
|
+
"$ gjc deep-interview inspect --session-id <id> --selector summary --json",
|
|
32
37
|
];
|
|
33
38
|
|
|
34
39
|
async run(): Promise<void> {
|
package/src/commands/sdk.ts
CHANGED
|
@@ -295,14 +295,14 @@ export async function runSessionHost(
|
|
|
295
295
|
rollback.recordAbsent();
|
|
296
296
|
const failure = normalizeSdkStartupFailure("registration", "failed", error);
|
|
297
297
|
await writeFailure(failure, rollback.result);
|
|
298
|
-
throw
|
|
298
|
+
throw failure;
|
|
299
299
|
}
|
|
300
300
|
const { parsed } = opened;
|
|
301
301
|
if ("failure" in created) {
|
|
302
302
|
created.rollback.recordAbsent();
|
|
303
303
|
await writeFailure(created.failure, created.rollback.result);
|
|
304
304
|
|
|
305
|
-
throw
|
|
305
|
+
throw created.failure;
|
|
306
306
|
}
|
|
307
307
|
const { session, capability, rollback } = created;
|
|
308
308
|
let sessionDisposal: Promise<void> | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
|
-
import { $env, getProjectDir, isEnoent, prompt } from "@gajae-code/utils";
|
|
3
|
+
import { $env, $pickenv, getProjectDir, isEnoent, prompt } from "@gajae-code/utils";
|
|
4
4
|
import { applyChangelogProposals } from "../../commit/changelog";
|
|
5
5
|
import { detectChangelogBoundaries } from "../../commit/changelog/detect";
|
|
6
6
|
import { parseUnreleasedSection } from "../../commit/changelog/parse";
|
|
@@ -88,7 +88,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
88
88
|
} else {
|
|
89
89
|
process.stdout.write(" └─ (none found)\n");
|
|
90
90
|
}
|
|
91
|
-
const forceFallback = $
|
|
91
|
+
const forceFallback = $pickenv("GJC_COMMIT_TEST_FALLBACK", "PI_COMMIT_TEST_FALLBACK")?.toLowerCase() === "true";
|
|
92
92
|
if (forceFallback) {
|
|
93
93
|
process.stdout.write("● Forcing fallback commit generation...\n");
|
|
94
94
|
const fallbackProposal = generateFallbackProposal(numstat);
|
|
@@ -152,7 +152,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
if (!usedFallback && !commitState.proposal && !commitState.splitProposal) {
|
|
155
|
-
if ($
|
|
155
|
+
if ($pickenv("GJC_COMMIT_NO_FALLBACK", "PI_COMMIT_NO_FALLBACK")?.toLowerCase() !== "true") {
|
|
156
156
|
process.stdout.write("● Agent did not provide proposal, using fallback...\n");
|
|
157
157
|
commitState.proposal = generateFallbackProposal(numstat);
|
|
158
158
|
usedFallback = true;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@gajae-code/agent-core";
|
|
2
2
|
import type { Api, Model } from "@gajae-code/ai";
|
|
3
|
-
import { $
|
|
3
|
+
import { $pickenv } from "@gajae-code/utils";
|
|
4
4
|
import { parseFileDiffs } from "../../commit/git/diff";
|
|
5
5
|
import type { ConventionalAnalysis } from "../../commit/types";
|
|
6
6
|
import { isExcludedFile } from "../../commit/utils/exclusions";
|
|
@@ -34,7 +34,7 @@ export interface MapReduceInput {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function shouldUseMapReduce(diff: string, settings?: MapReduceSettings): boolean {
|
|
37
|
-
if ($
|
|
37
|
+
if ($pickenv("GJC_COMMIT_MAP_REDUCE", "PI_COMMIT_MAP_REDUCE")?.toLowerCase() === "false") return false;
|
|
38
38
|
if (settings?.enabled === false) return false;
|
|
39
39
|
const minFiles = settings?.minFiles ?? MIN_FILES_FOR_MAP_REDUCE;
|
|
40
40
|
const maxFileTokens = settings?.maxFileTokens ?? MAX_FILE_TOKENS;
|