@gajae-code/coding-agent 0.11.8 → 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 +18 -1
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/config/model-profiles.d.ts +2 -3
- 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/state-writer.d.ts +44 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +5 -3
- package/dist/types/modes/components/welcome.d.ts +2 -0
- package/dist/types/runtime-mcp/redaction.d.ts +2 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -1
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +3 -1
- package/dist/types/session/internal/managed-session-scope.d.ts +12 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +8 -3
- package/dist/types/session/session-manager.d.ts +5 -1
- package/dist/types/session/session-storage.d.ts +13 -0
- package/dist/types/skill-state/active-state.d.ts +4 -0
- package/package.json +8 -8
- package/src/cli/mcp-cli.ts +4 -21
- package/src/cli.ts +32 -0
- package/src/commands/deep-interview.ts +9 -4
- package/src/commit/agentic/index.ts +3 -3
- package/src/commit/map-reduce/index.ts +2 -2
- package/src/config/model-profiles.ts +2 -3
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +78 -163
- 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/ralplan-runtime.ts +3 -1
- package/src/gjc-runtime/state-writer.ts +166 -2
- 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 +3 -2
- package/src/modes/components/welcome.ts +10 -2
- package/src/modes/interactive-mode.ts +29 -9
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/runtime-mcp/json-rpc.ts +7 -4
- package/src/runtime-mcp/redaction.ts +30 -0
- package/src/sdk/broker/session-index.ts +11 -1
- package/src/sdk/bus/chat-daemon-control.ts +5 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +3 -1
- package/src/sdk/bus/telegram-daemon.ts +18 -2
- package/src/session/agent-session.ts +86 -0
- package/src/session/internal/managed-session-scope.ts +206 -111
- package/src/session/internal/managed-session-storage.ts +17 -4
- package/src/session/session-manager.ts +96 -33
- package/src/session/session-storage.ts +23 -0
- package/src/skill-state/active-state.ts +10 -0
- package/src/task/executor.ts +13 -5
- package/src/tools/ask.ts +1 -0
|
@@ -327,6 +327,9 @@ export declare class SessionMigrationPolicyError extends Error {
|
|
|
327
327
|
readonly code = "legacy_migration_disabled";
|
|
328
328
|
constructor();
|
|
329
329
|
}
|
|
330
|
+
export declare class SessionArtifactCapacityError extends Error {
|
|
331
|
+
constructor(message: string);
|
|
332
|
+
}
|
|
330
333
|
export type ResumeTailInspection = ResumeTailResumable | ResumeTailTerminal | ResumeTailError;
|
|
331
334
|
export interface StrictSessionOpenSuccess {
|
|
332
335
|
kind: "opened";
|
|
@@ -334,7 +337,8 @@ export interface StrictSessionOpenSuccess {
|
|
|
334
337
|
}
|
|
335
338
|
export interface StrictSessionOpenFailure {
|
|
336
339
|
kind: "error";
|
|
337
|
-
reason: ResumeTailError["reason"] | "identity-mismatch" | "migration-required";
|
|
340
|
+
reason: ResumeTailError["reason"] | "identity-mismatch" | "migration-required" | "artifact_capacity_exceeded";
|
|
341
|
+
message?: string;
|
|
338
342
|
}
|
|
339
343
|
/** Exact transcript bytes and authority captured from one descriptor-bound read. */
|
|
340
344
|
export interface CapturedSessionTranscriptSnapshot {
|
|
@@ -112,6 +112,11 @@ export interface SessionStorage {
|
|
|
112
112
|
readSnapshotSync?(path: string): SessionStorageSnapshot;
|
|
113
113
|
statSync(path: string): SessionStorageStat;
|
|
114
114
|
listFilesSync(dir: string, pattern: string): string[];
|
|
115
|
+
/** List matching files with mtimes without issuing one JavaScript stat call per path. */
|
|
116
|
+
listFilesByMtime?(dir: string, pattern: string): Promise<Array<{
|
|
117
|
+
path: string;
|
|
118
|
+
mtimeMs: number;
|
|
119
|
+
}>>;
|
|
115
120
|
/**
|
|
116
121
|
* Strict directory scan that never suppresses scan/root errors. Used by strict
|
|
117
122
|
* authorization inventory; the forgiving {@link listFilesSync} stays display-only.
|
|
@@ -267,6 +272,10 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
267
272
|
readSnapshotSync(fpath: string): SessionStorageSnapshot;
|
|
268
273
|
statSync(path: string): SessionStorageStat;
|
|
269
274
|
listFilesSync(dir: string, pattern: string): string[];
|
|
275
|
+
listFilesByMtime(dir: string, pattern: string): Promise<Array<{
|
|
276
|
+
path: string;
|
|
277
|
+
mtimeMs: number;
|
|
278
|
+
}>>;
|
|
270
279
|
listFilesStrictSync(dir: string, pattern: string): string[];
|
|
271
280
|
exists(path: string): Promise<boolean>;
|
|
272
281
|
readText(path: string): Promise<string>;
|
|
@@ -299,6 +308,10 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
299
308
|
readSnapshotSync(path: string): SessionStorageSnapshot;
|
|
300
309
|
statSync(path: string): SessionStorageStat;
|
|
301
310
|
listFilesSync(dir: string, pattern: string): string[];
|
|
311
|
+
listFilesByMtime(dir: string, pattern: string): Promise<Array<{
|
|
312
|
+
path: string;
|
|
313
|
+
mtimeMs: number;
|
|
314
|
+
}>>;
|
|
302
315
|
listFilesStrictSync(dir: string, pattern: string): string[];
|
|
303
316
|
exists(path: string): Promise<boolean>;
|
|
304
317
|
readText(path: string): Promise<string>;
|
|
@@ -45,6 +45,8 @@ export interface SkillActiveEntry {
|
|
|
45
45
|
handoff_at?: string;
|
|
46
46
|
active_subskills?: ActiveSubskillEntry[];
|
|
47
47
|
source_state_revision?: number;
|
|
48
|
+
/** Durable ordering token from the source workflow mode-state, not this cache file's revision. */
|
|
49
|
+
committed_mode_state_revision?: number;
|
|
48
50
|
}
|
|
49
51
|
export interface SkillActiveState {
|
|
50
52
|
version?: number;
|
|
@@ -85,6 +87,8 @@ export interface SyncSkillActiveStateOptions {
|
|
|
85
87
|
handoff_at?: string;
|
|
86
88
|
active_subskills?: ActiveSubskillEntry[];
|
|
87
89
|
sourceRevision?: number;
|
|
90
|
+
/** Durable ordering token from the source workflow mode-state, not this cache file's revision. */
|
|
91
|
+
committedModeRevision?: number;
|
|
88
92
|
}
|
|
89
93
|
export declare function normalizeWorkflowHudSummary(raw: unknown): WorkflowHudSummary | undefined;
|
|
90
94
|
export declare function isCanonicalGjcWorkflowSkill(skill: string): skill is CanonicalGjcWorkflowSkill;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.9",
|
|
5
5
|
"description": "Gajae Code CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
"@agentclientprotocol/sdk": "1.2.1",
|
|
54
54
|
"@babel/parser": "^7.29.3",
|
|
55
55
|
"@mozilla/readability": "^0.6.0",
|
|
56
|
-
"@gajae-code/stats": "0.11.
|
|
57
|
-
"@gajae-code/agent-core": "0.11.
|
|
58
|
-
"@gajae-code/ai": "0.11.
|
|
59
|
-
"@gajae-code/bridge-client": "0.11.
|
|
60
|
-
"@gajae-code/natives": "0.11.
|
|
61
|
-
"@gajae-code/tui": "0.11.
|
|
62
|
-
"@gajae-code/utils": "0.11.
|
|
56
|
+
"@gajae-code/stats": "0.11.9",
|
|
57
|
+
"@gajae-code/agent-core": "0.11.9",
|
|
58
|
+
"@gajae-code/ai": "0.11.9",
|
|
59
|
+
"@gajae-code/bridge-client": "0.11.9",
|
|
60
|
+
"@gajae-code/natives": "0.11.9",
|
|
61
|
+
"@gajae-code/tui": "0.11.9",
|
|
62
|
+
"@gajae-code/utils": "0.11.9",
|
|
63
63
|
"@puppeteer/browsers": "^2.13.0",
|
|
64
64
|
"@types/turndown": "5.0.6",
|
|
65
65
|
"@xterm/headless": "^6.0.0",
|
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.ts
CHANGED
|
@@ -118,6 +118,36 @@ Options:
|
|
|
118
118
|
`);
|
|
119
119
|
}
|
|
120
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
|
+
|
|
121
151
|
function isNotifyDaemonInternalFastPath(argv: string[]): boolean {
|
|
122
152
|
return argv[0] === "notify" && argv[1] === "daemon-internal";
|
|
123
153
|
}
|
|
@@ -412,6 +442,8 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
412
442
|
showStatsFastHelp();
|
|
413
443
|
return;
|
|
414
444
|
}
|
|
445
|
+
const bootstrap = interactiveBootstrapText(runArgv);
|
|
446
|
+
if (bootstrap) process.stdout.write(bootstrap);
|
|
415
447
|
await installRuntimeGlobals();
|
|
416
448
|
return run({ bin: APP_NAME, version: VERSION, argv: runArgv, commands, help: showHelp });
|
|
417
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> {
|
|
@@ -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;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { sanitizeText } from "@gajae-code/utils";
|
|
2
|
-
import type { GjcModelAssignmentTargetId } from "./model-registry";
|
|
3
2
|
import { type ModelSelectorValue, normalizeModelSelectorValue } from "./model-selector-value";
|
|
4
|
-
import type { ModelsConfig } from "./models-config-schema";
|
|
3
|
+
import type { GJC_MODEL_ASSIGNMENT_TARGET_IDS, ModelsConfig } from "./models-config-schema";
|
|
5
4
|
|
|
6
|
-
export type ModelProfileRole =
|
|
5
|
+
export type ModelProfileRole = (typeof GJC_MODEL_ASSIGNMENT_TARGET_IDS)[number];
|
|
7
6
|
|
|
8
7
|
export interface ModelProfileDefinition {
|
|
9
8
|
name: string;
|