@gajae-code/coding-agent 0.7.8 → 0.7.10
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 +40 -0
- package/README.md +8 -0
- package/dist/types/config/keybindings.d.ts +1 -1
- package/dist/types/config/model-profile-activation.d.ts +19 -2
- package/dist/types/config/model-profiles.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/settings-schema.d.ts +12 -3
- package/dist/types/extensibility/extensions/types.d.ts +11 -0
- package/dist/types/gjc-runtime/launch-tmux.d.ts +19 -3
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +7 -1
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +0 -4
- package/dist/types/modes/components/hook-input.d.ts +1 -0
- package/dist/types/modes/components/hook-selector.d.ts +5 -0
- package/dist/types/modes/components/model-selector.d.ts +9 -0
- package/dist/types/modes/components/status-line.d.ts +3 -0
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +3 -1
- package/dist/types/modes/interactive-mode.d.ts +3 -1
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +41 -7
- package/dist/types/modes/types.d.ts +3 -1
- package/dist/types/notifications/daemon-paths.d.ts +9 -0
- package/dist/types/notifications/html-format.d.ts +2 -0
- package/dist/types/notifications/recent-activity.d.ts +5 -1
- package/dist/types/notifications/telegram-daemon-cli.d.ts +8 -2
- package/dist/types/notifications/telegram-daemon-control.d.ts +8 -0
- package/dist/types/notifications/telegram-daemon.d.ts +1 -10
- package/dist/types/notifications/telegram-reference.d.ts +4 -0
- package/dist/types/notifications/threaded-render.d.ts +1 -0
- package/dist/types/tools/ask.d.ts +26 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +9 -2
- package/dist/types/utils/cmux-workspace.d.ts +23 -0
- package/dist/types/web/search/index.d.ts +1 -1
- package/dist/types/web/search/provider.d.ts +5 -0
- package/dist/types/web/search/render.d.ts +1 -0
- package/package.json +7 -7
- package/src/cli/notify-cli.ts +1 -1
- package/src/cli/web-search-cli.ts +3 -2
- package/src/cli.ts +1 -0
- package/src/config/keybindings.ts +1 -1
- package/src/config/model-profile-activation.ts +92 -11
- package/src/config/model-profiles.ts +15 -2
- package/src/config/model-registry.ts +81 -5
- package/src/config/settings-schema.ts +14 -3
- package/src/coordinator-mcp/server.ts +4 -2
- package/src/deep-interview/render-middleware.ts +1 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +40 -8
- package/src/defaults/gjc/skills/ralplan/SKILL.md +14 -7
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +37 -112
- package/src/extensibility/extensions/types.ts +11 -0
- package/src/gjc-runtime/deep-interview-runtime.ts +1 -1
- package/src/gjc-runtime/launch-tmux.ts +366 -48
- package/src/gjc-runtime/team-runtime.ts +69 -4
- package/src/gjc-runtime/ultragoal-guard.ts +150 -24
- package/src/gjc-runtime/ultragoal-runtime.ts +16 -124
- package/src/gjc-runtime/workflow-manifest.generated.json +0 -8
- package/src/gjc-runtime/workflow-manifest.ts +0 -1
- package/src/hooks/skill-state.ts +33 -73
- package/src/internal-urls/docs-index.generated.ts +8 -7
- package/src/modes/components/custom-model-preset-wizard.ts +2 -4
- package/src/modes/components/hook-editor.ts +7 -4
- package/src/modes/components/hook-input.ts +4 -0
- package/src/modes/components/hook-selector.ts +21 -3
- package/src/modes/components/model-selector.ts +84 -13
- package/src/modes/components/settings-selector.ts +83 -24
- package/src/modes/components/status-line/presets.ts +11 -0
- package/src/modes/components/status-line/segments.ts +10 -2
- package/src/modes/components/status-line.ts +1 -0
- package/src/modes/controllers/extension-ui-controller.ts +20 -2
- package/src/modes/controllers/selector-controller.ts +130 -7
- package/src/modes/interactive-mode.ts +7 -2
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +64 -13
- package/src/modes/types.ts +6 -1
- package/src/notifications/daemon-paths.ts +22 -0
- package/src/notifications/html-format.ts +75 -1
- package/src/notifications/index.ts +12 -1
- package/src/notifications/recent-activity.ts +32 -8
- package/src/notifications/telegram-daemon-cli.ts +13 -4
- package/src/notifications/telegram-daemon-control.ts +9 -0
- package/src/notifications/telegram-daemon.ts +69 -45
- package/src/notifications/telegram-reference.ts +36 -14
- package/src/notifications/threaded-render.ts +14 -6
- package/src/prompts/system/system-prompt.md +10 -1
- package/src/sdk.ts +13 -6
- package/src/session/agent-session.ts +10 -1
- package/src/tools/ask.ts +147 -17
- package/src/tools/eval.ts +2 -2
- package/src/tools/render-utils.ts +2 -0
- package/src/tools/ultragoal-ask-guard.ts +39 -5
- package/src/utils/cmux-workspace.ts +106 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/search/index.ts +22 -10
- package/src/web/search/provider.ts +15 -0
- package/src/web/search/render.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.7.10] - 2026-07-02
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- GJC now best-effort renames the containing cmux workspace to the current GJC session name when running inside a cmux terminal.
|
|
9
|
+
- Added a status line default usage preset (#1305).
|
|
10
|
+
- Telegram threaded updates now include verbose session identity (session id and cwd) metadata.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Deep Interview option-clarification prompts now stay out of the interview transcript and ambiguity recorder, so asking about displayed choices no longer persists as the round answer before the user selects an actual option.
|
|
15
|
+
- `gjc daemon reload telegram` now spawns the replacement daemon with a stable owner pid so the new daemon does not exit immediately after the short-lived reload CLI process ends.
|
|
16
|
+
- Managed `gjc --tmux` launches now size the initial window correctly (#1376).
|
|
17
|
+
- Coordinator tmux-delivered turns now submit correctly on Enter (#1372).
|
|
18
|
+
- Generic long `retry-after` rate limits are now kept retryable instead of being treated as fatal (#1370).
|
|
19
|
+
- Anthropic hard 429 responses are now surfaced before the stream watchdog fires (#1369).
|
|
20
|
+
- Internal sessions are now hidden from the Telegram recent-session list (#1367).
|
|
21
|
+
- Telegram messages exceeding the length limit are now chunked correctly.
|
|
22
|
+
- Web search now falls back correctly when the preferred provider is unavailable (#1348).
|
|
23
|
+
- Restored the Ultragoal team checkpoint snapshot wording (#1349).
|
|
24
|
+
- Deep Interview now exits early for simple tasks instead of running unnecessary rounds (#1311).
|
|
25
|
+
- Ultragoal goal identity and state now resolve solely from the canonical session-scoped `goals.json`, eliminating goal-identity drift from transcript-replayed snapshots (#1344).
|
|
26
|
+
|
|
27
|
+
## [0.7.9] - 2026-07-01
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Added an optional Tavily web search provider selectable through `providers.webSearch`, using `TAVILY_API_KEY` only when Tavily is selected (#1323).
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Deep Interview now treats English `implementation` and Korean `구현` wording as eventual-target language, not permission to edit code or launch implementation before post-interview approval (#1320).
|
|
35
|
+
- Restored default Enter = submit in the main chat composer. #1326 rerouted plain Enter in the prompt to insert a newline (making Ctrl+Enter the submit chord); this reverts that so Enter submits again and Shift+Enter inserts a newline.
|
|
36
|
+
- Registered the optional `gjc acp` subcommand so Zed/custom ACP clients can launch the ACP stdio server through the documented command entrypoint, and documented the Zed `agent_servers` custom-agent shape (#1327).
|
|
37
|
+
- Compiled binaries can now include the hidden Telegram daemon CLI entrypoint without hanging root startup, and release builds preserve that entry so `gjc notify daemon-internal --smoke` is available in standalone binaries (#1288).
|
|
38
|
+
- Documented Windows Terminal BEL limitations for terminal bell notifications and added a PowerShell `completion.notifyCommand` beep workaround example (#1318).
|
|
39
|
+
|
|
5
40
|
## [0.7.8] - 2026-06-30
|
|
6
41
|
### Added
|
|
7
42
|
|
|
@@ -11,10 +46,15 @@
|
|
|
11
46
|
|
|
12
47
|
### Fixed
|
|
13
48
|
|
|
49
|
+
- Fixed a class of TUI renderer crashes (`TypeError: undefined is not an object (evaluating 'x.trim'/'x.split')`) where render helpers typed `(x: string)` ran a string op on an optional/possibly-undefined tool-detail field. The deep-interview/ralplan `ask` renderer crashed on a result with a missing `question`; caught during streaming but fatal on render/teardown paths such as `/background` detach. Hardened `normalizeText`, `getPreviewLines`, `shortenPath`, and the eval git_log status-event renderer (#1290).
|
|
50
|
+
|
|
14
51
|
- `gjc update` now verifies the installed runtime after package-manager failures and treats a nonzero Bun/npm exit as recoverable when the requested version and smoke test actually landed, avoiding false failures from Bun tarball extraction errors (#1280).
|
|
52
|
+
- Deep Interview now prefers the native hook's pre-resolved ambiguity threshold state and avoids surfacing missing optional settings files as failed `Read` calls during Phase 0.
|
|
53
|
+
- Scoped Ultragoal ask-guard checks for `deep-interview` and `ralplan` asks to the current session, so stale or ambiguous Ultragoal state from other sessions no longer suppresses the choice UI while same-session active Ultragoal blockers still apply.
|
|
15
54
|
- Submitted user prompts now use the live terminal viewport width in wide Windows Terminal/PowerShell sessions, keeping Korean/CJK prompt wrapping responsive without changing narrow layouts (#1239).
|
|
16
55
|
- Coordinator MCP now fails tmux-delivered turns that never receive a runtime prompt acknowledgement/`turn_start`, surfacing an explicit unacknowledged delivery reason instead of leaving Hermes/Oren waiting on a normal active/running state (#1237).
|
|
17
56
|
- Telegram now advertises `/session_create`, `/session_recent`, `/session_close`, and `/session_resume` in the bot command menu so lifecycle control commands are discoverable from `/` autocomplete.
|
|
57
|
+
- `gjc --tmux` now prefixes the root terminal title (`GJC: tmp`) and managed tmux window names (`GJC-tmp`) with a GJC workspace label so terminal multiplexers and workspace switchers do not fall back to noisy launch paths.
|
|
18
58
|
|
|
19
59
|
## [0.7.7] - 2026-06-28
|
|
20
60
|
### Added
|
package/README.md
CHANGED
|
@@ -24,6 +24,14 @@ For simple local side effects that do not need a full extension, set the user-le
|
|
|
24
24
|
gjc config set completion.notifyCommand 'cmux notify --title "$GJC_NOTIFICATION_TITLE" --body "$GJC_NOTIFICATION_BODY"'
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
When GJC is running inside a cmux terminal (`CMUX_WORKSPACE_ID` is set), GJC also best-effort renames that cmux workspace to the current GJC session name whenever the session title is set or restored.
|
|
28
|
+
|
|
29
|
+
Windows Terminal may keep BEL (`[Console]::Write([char]7)`) silent depending on profile and system sound settings even when `notifications.terminalBell` is enabled. For an audible Windows completion beep, configure a user-level PowerShell command hook instead:
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
gjc config set completion.notifyCommand 'powershell.exe -NoProfile -Command "[Console]::Beep(880, 300)"'
|
|
33
|
+
```
|
|
34
|
+
|
|
27
35
|
`cmux notify` returning successfully means GJC handed the completion event to cmux. cmux may still suppress the native desktop banner when the app/window is focused, the emitting workspace is active, or the notification panel is open. In those cases, check cmux's notification panel or unread workspace state instead of treating the missing banner as a GJC delivery failure.
|
|
28
36
|
|
|
29
37
|
Recommended external mapping:
|
|
@@ -231,7 +231,7 @@ export declare const KEYBINDINGS: {
|
|
|
231
231
|
};
|
|
232
232
|
readonly "app.message.followUp": {
|
|
233
233
|
readonly defaultKeys: [];
|
|
234
|
-
readonly description: "Send follow-up message (no default; Ctrl+Enter
|
|
234
|
+
readonly description: "Send follow-up message (no default; Ctrl+Enter submits)";
|
|
235
235
|
};
|
|
236
236
|
readonly "app.message.queue": {
|
|
237
237
|
readonly defaultKeys: "alt+enter";
|
|
@@ -21,7 +21,7 @@ export interface PreparedModelProfileActivation {
|
|
|
21
21
|
session: ModelProfileActivationSession & {
|
|
22
22
|
setModelTemporary: AgentSession["setModelTemporary"];
|
|
23
23
|
};
|
|
24
|
-
settings: Pick<Settings, "get" | "override" | "set" | "flush">;
|
|
24
|
+
settings: Pick<Settings, "clearOverride" | "get" | "getGlobal" | "override" | "set" | "flush">;
|
|
25
25
|
previousModel: Model<Api> | undefined;
|
|
26
26
|
previousThinkingLevel: ThinkingLevel | undefined;
|
|
27
27
|
previousAgentModelOverrides: Record<string, string>;
|
|
@@ -47,11 +47,28 @@ export interface MaterializeModelProfileAssignmentOptions {
|
|
|
47
47
|
selector: string;
|
|
48
48
|
}
|
|
49
49
|
export declare function materializeActiveModelProfileAssignment(options: MaterializeModelProfileAssignmentOptions): boolean;
|
|
50
|
-
export declare function formatModelProfileCredentialError(
|
|
50
|
+
export declare function formatModelProfileCredentialError(profileLabel: string, providers: readonly string[]): string;
|
|
51
51
|
export declare function prepareModelProfileActivation(options: PrepareModelProfileActivationOptions): Promise<PreparedModelProfileActivation>;
|
|
52
52
|
export declare function applyPreparedModelProfileActivation(prepared: PreparedModelProfileActivation, options?: {
|
|
53
53
|
persistDefault?: boolean;
|
|
54
54
|
}): Promise<void>;
|
|
55
|
+
export interface MaterializeModelProfileForDeletionResult {
|
|
56
|
+
modelRoles: Record<string, string>;
|
|
57
|
+
agentModelOverrides: Record<string, string>;
|
|
58
|
+
previousModelRoles: Record<string, string>;
|
|
59
|
+
previousAgentModelOverrides: Record<string, string>;
|
|
60
|
+
previousDefaultProfile: string | undefined;
|
|
61
|
+
previousPersistedDefaultProfile: string | undefined;
|
|
62
|
+
previousActiveModelProfile: string | undefined;
|
|
63
|
+
}
|
|
64
|
+
export declare function materializeModelProfileForDeletion(options: PrepareModelProfileActivationOptions & {
|
|
65
|
+
settings: Pick<Settings, "clearOverride" | "flush" | "get" | "getGlobal" | "override" | "set">;
|
|
66
|
+
}): Promise<MaterializeModelProfileForDeletionResult>;
|
|
67
|
+
export declare function restoreMaterializedModelProfileForDeletion(options: {
|
|
68
|
+
settings: Pick<Settings, "flush" | "override" | "set">;
|
|
69
|
+
session: Pick<ModelProfileActivationSession, "setActiveModelProfile">;
|
|
70
|
+
snapshot: MaterializeModelProfileForDeletionResult;
|
|
71
|
+
}): Promise<void>;
|
|
55
72
|
export declare function activateModelProfile(options: PrepareModelProfileActivationOptions, applyOptions?: {
|
|
56
73
|
persistDefault?: boolean;
|
|
57
74
|
}): Promise<void>;
|
|
@@ -31,6 +31,7 @@ export interface ModelProfilePresentation {
|
|
|
31
31
|
providerGroup: string;
|
|
32
32
|
}
|
|
33
33
|
export declare function getModelProfilePresentation(profile: string | Pick<ModelProfileDefinition, "name" | "displayName">): ModelProfilePresentation;
|
|
34
|
+
export declare function formatModelProfileDisplayLabel(profile: Pick<ModelProfileDefinition, "name" | "displayName">): string;
|
|
34
35
|
export declare function groupModelProfilesForPresetLanding(profiles: ReadonlyMap<string, ModelProfileDefinition>): Map<string, ModelProfileDefinition[]>;
|
|
35
36
|
export declare function recommendModelProfileForProvider(providerId: string, profiles: ReadonlyMap<string, ModelProfileDefinition>): ModelProfileDefinition | undefined;
|
|
36
37
|
export declare function mergeModelProfiles(userProfiles?: ModelsConfig["profiles"]): Map<string, ModelProfileDefinition>;
|
|
@@ -19,6 +19,8 @@ export interface ModelRoleInfo {
|
|
|
19
19
|
}
|
|
20
20
|
export declare const MODEL_ROLES: Record<ModelRole, ModelRoleInfo>;
|
|
21
21
|
export declare const MODEL_ROLE_IDS: ModelRole[];
|
|
22
|
+
export declare const MODEL_PROFILE_NAME_PATTERN: RegExp;
|
|
23
|
+
export declare const MODEL_PROFILE_NAME_PATTERN_DESCRIPTION = "lowercase letters, numbers, dots, underscores, or hyphens";
|
|
22
24
|
export type GjcModelAssignmentTargetId = "default" | "executor" | "architect" | "planner" | "critic";
|
|
23
25
|
export interface GjcModelAssignmentTargetInfo extends ModelRoleInfo {
|
|
24
26
|
id: GjcModelAssignmentTargetId;
|
|
@@ -342,6 +344,8 @@ export declare class ModelRegistry {
|
|
|
342
344
|
getModelProfile(name: string): ModelProfileDefinition | undefined;
|
|
343
345
|
getAvailableModelProfileNames(): string[];
|
|
344
346
|
saveCustomModelProfile(name: string, definition: ModelProfileConfig): Promise<ModelProfileDefinition>;
|
|
347
|
+
renameCustomModelProfile(name: string, displayName: string): Promise<ModelProfileDefinition>;
|
|
348
|
+
deleteCustomModelProfile(name: string): Promise<ModelProfileConfig>;
|
|
345
349
|
applyConfiguredModelBindings(targetSettings: Settings): void;
|
|
346
350
|
/**
|
|
347
351
|
* Get all models (built-in + custom).
|
|
@@ -166,7 +166,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
166
166
|
readonly ui: {
|
|
167
167
|
readonly tab: "interaction";
|
|
168
168
|
readonly label: "Terminal Bell";
|
|
169
|
-
readonly description: "Emit a BEL character for local terminal notifications";
|
|
169
|
+
readonly description: "Emit a BEL character for local terminal notifications. Windows Terminal may keep BEL silent depending on profile/system sound settings; use completion.notifyCommand for a PowerShell Console.Beep workaround.";
|
|
170
170
|
};
|
|
171
171
|
};
|
|
172
172
|
readonly "notifications.bellOnComplete": {
|
|
@@ -351,7 +351,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
351
351
|
};
|
|
352
352
|
readonly "statusLine.preset": {
|
|
353
353
|
readonly type: "enum";
|
|
354
|
-
readonly values: readonly ["default", "minimal", "compact", "full", "nerd", "ascii", "custom"];
|
|
354
|
+
readonly values: readonly ["default", "default-usage", "minimal", "compact", "full", "nerd", "ascii", "custom"];
|
|
355
355
|
readonly default: "default";
|
|
356
356
|
readonly ui: {
|
|
357
357
|
readonly tab: "appearance";
|
|
@@ -361,6 +361,10 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
361
361
|
readonly value: "default";
|
|
362
362
|
readonly label: "Default";
|
|
363
363
|
readonly description: "Model, path, git, context, tokens, cost";
|
|
364
|
+
}, {
|
|
365
|
+
readonly value: "default-usage";
|
|
366
|
+
readonly label: "Default + Usage";
|
|
367
|
+
readonly description: "Default layout with provider usage quota";
|
|
364
368
|
}, {
|
|
365
369
|
readonly value: "minimal";
|
|
366
370
|
readonly label: "Minimal";
|
|
@@ -1343,7 +1347,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
1343
1347
|
readonly ui: {
|
|
1344
1348
|
readonly tab: "interaction";
|
|
1345
1349
|
readonly label: "Completion Notification Command";
|
|
1346
|
-
readonly description: "Optional user-level shell command to run when an agent turn completes; receives GJC_NOTIFICATION_* environment variables.";
|
|
1350
|
+
readonly description: "Optional user-level shell command to run when an agent turn completes; receives GJC_NOTIFICATION_* environment variables. On Windows, this can call PowerShell [Console]::Beep when terminal BEL is silent.";
|
|
1347
1351
|
};
|
|
1348
1352
|
};
|
|
1349
1353
|
readonly "ask.timeout": {
|
|
@@ -2575,6 +2579,11 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2575
2579
|
readonly description: "Enable the web_search tool for web searching";
|
|
2576
2580
|
};
|
|
2577
2581
|
};
|
|
2582
|
+
readonly "web_search.provider": {
|
|
2583
|
+
readonly type: "enum";
|
|
2584
|
+
readonly values: readonly ["auto", "duckduckgo", "insane", "exa", "brave", "jina", "kimi", "zai", "anthropic", "perplexity", "gemini", "codex", "xai", "tavily", "parallel", "kagi", "synthetic", "searxng"];
|
|
2585
|
+
readonly default: "auto";
|
|
2586
|
+
};
|
|
2578
2587
|
readonly "web_search.fallback": {
|
|
2579
2588
|
readonly type: "array";
|
|
2580
2589
|
readonly default: string[];
|
|
@@ -76,6 +76,17 @@ export interface ExtensionUIDialogOptions {
|
|
|
76
76
|
optionLabel: string;
|
|
77
77
|
onSubmit: (text: string) => void;
|
|
78
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* Inline free-text input for a non-answer clarification action. It is
|
|
81
|
+
* separate from `customInput` so callers can distinguish "ask about these
|
|
82
|
+
* choices" from "provide my own answer". Empty/whitespace-only submissions
|
|
83
|
+
* may be rejected by the selector when `allowEmpty` is false.
|
|
84
|
+
*/
|
|
85
|
+
clarificationInput?: {
|
|
86
|
+
optionLabel: string;
|
|
87
|
+
onSubmit: (text: string) => void;
|
|
88
|
+
allowEmpty?: boolean;
|
|
89
|
+
};
|
|
79
90
|
}
|
|
80
91
|
/** Raw terminal input listener for extensions. */
|
|
81
92
|
export type TerminalInputHandler = (data: string) => {
|
|
@@ -8,6 +8,8 @@ export declare const GJC_PSMUX_PROFILE_FORCE_ENV = "GJC_PSMUX_PROFILE_FORCE";
|
|
|
8
8
|
interface TtyState {
|
|
9
9
|
stdin: boolean;
|
|
10
10
|
stdout: boolean;
|
|
11
|
+
columns?: number;
|
|
12
|
+
rows?: number;
|
|
11
13
|
}
|
|
12
14
|
export interface TmuxLaunchContext {
|
|
13
15
|
parsed: Args;
|
|
@@ -31,13 +33,26 @@ export interface TmuxSpawnResult {
|
|
|
31
33
|
signalCode?: string | null;
|
|
32
34
|
stderr?: string;
|
|
33
35
|
}
|
|
36
|
+
export interface TmuxTerminalSize {
|
|
37
|
+
columns: number;
|
|
38
|
+
rows: number;
|
|
39
|
+
}
|
|
34
40
|
export type TmuxSpawnSync = (command: string, args: string[], options: TmuxSpawnOptions) => TmuxSpawnResult;
|
|
35
41
|
export interface TmuxSpawnOptions {
|
|
36
42
|
cwd: string;
|
|
37
43
|
env: NodeJS.ProcessEnv;
|
|
38
|
-
stdin: "inherit";
|
|
39
|
-
stdout: "inherit";
|
|
40
|
-
stderr: "inherit";
|
|
44
|
+
stdin: "inherit" | "pipe";
|
|
45
|
+
stdout: "inherit" | "pipe";
|
|
46
|
+
stderr: "inherit" | "pipe";
|
|
47
|
+
/**
|
|
48
|
+
* When true, the spawn captures stderr into a buffer and forwards it to
|
|
49
|
+
* the parent stderr so the user still sees the live output. The captured
|
|
50
|
+
* text is also returned in TmuxSpawnResult.stderr for diagnostic
|
|
51
|
+
* surfacing in "attach failed" / "profile tagging failed" messages.
|
|
52
|
+
* Defaults to false to preserve the previous PTY-binding behavior for
|
|
53
|
+
* attach-session and other interactive commands.
|
|
54
|
+
*/
|
|
55
|
+
captureStderr?: boolean;
|
|
41
56
|
}
|
|
42
57
|
export interface TmuxLaunchPlan {
|
|
43
58
|
tmuxCommand: string;
|
|
@@ -45,6 +60,7 @@ export interface TmuxLaunchPlan {
|
|
|
45
60
|
cwd: string;
|
|
46
61
|
innerCommand: string;
|
|
47
62
|
newSessionArgs: string[];
|
|
63
|
+
initialSize?: TmuxTerminalSize;
|
|
48
64
|
branch?: string | null;
|
|
49
65
|
attachSessionName?: string;
|
|
50
66
|
project?: string | null;
|
|
@@ -29,7 +29,13 @@ export declare function readUltragoalVerificationState(input: {
|
|
|
29
29
|
currentGoal?: CurrentGoalLike | null;
|
|
30
30
|
sessionId?: string | null;
|
|
31
31
|
}): Promise<UltragoalGuardDiagnostic>;
|
|
32
|
-
export declare function
|
|
32
|
+
export declare function verifyUltragoalDurableCompletionState(input: {
|
|
33
|
+
cwd: string;
|
|
34
|
+
sessionId?: string | null;
|
|
35
|
+
}): Promise<UltragoalGuardDiagnostic>;
|
|
36
|
+
export declare function isUltragoalAskBlocked(cwd: string, options?: {
|
|
37
|
+
sessionId?: string | null;
|
|
38
|
+
}): Promise<UltragoalAskBlockDiagnostic>;
|
|
33
39
|
/**
|
|
34
40
|
* Escalating per-attempt refusal text. Deliberately avoids every
|
|
35
41
|
* `isUltragoalBypassPrompt` trigger: no `update_goal(`, no "skip/weaken verification",
|
|
@@ -36,7 +36,6 @@ export interface UltragoalCompletionVerification {
|
|
|
36
36
|
gjcGoalMode: UltragoalGjcGoalMode;
|
|
37
37
|
gjcObjective: string;
|
|
38
38
|
qualityGateHash: string;
|
|
39
|
-
gjcGoalSnapshotHash: string;
|
|
40
39
|
planGeneration: string;
|
|
41
40
|
basis: {
|
|
42
41
|
planHashBeforeCheckpoint: string;
|
|
@@ -237,7 +236,6 @@ export declare function checkpointUltragoalGoal(input: {
|
|
|
237
236
|
goalId: string;
|
|
238
237
|
status: UltragoalGoalStatus;
|
|
239
238
|
evidence: string;
|
|
240
|
-
gjcGoalJson?: string;
|
|
241
239
|
qualityGateJson?: string;
|
|
242
240
|
}): Promise<UltragoalPlan>;
|
|
243
241
|
export interface UltragoalCheckpointContinuation {
|
|
@@ -253,7 +251,6 @@ export declare function checkpointAndContinueUltragoalGoal(input: {
|
|
|
253
251
|
goalId: string;
|
|
254
252
|
status: UltragoalGoalStatus;
|
|
255
253
|
evidence: string;
|
|
256
|
-
gjcGoalJson?: string;
|
|
257
254
|
qualityGateJson?: string;
|
|
258
255
|
advanceNext?: boolean;
|
|
259
256
|
retryFailed?: boolean;
|
|
@@ -271,7 +268,6 @@ export declare function recordUltragoalReviewBlockers(input: {
|
|
|
271
268
|
title: string;
|
|
272
269
|
objective: string;
|
|
273
270
|
evidence: string;
|
|
274
|
-
gjcGoalJson?: string;
|
|
275
271
|
}): Promise<UltragoalPlan>;
|
|
276
272
|
export type UltragoalBlockerClassification = "human_blocked" | "resolvable";
|
|
277
273
|
/**
|
|
@@ -33,6 +33,11 @@ export interface HookSelectorOptions {
|
|
|
33
33
|
optionLabel: string;
|
|
34
34
|
onSubmit: (text: string) => void;
|
|
35
35
|
};
|
|
36
|
+
clarificationInput?: {
|
|
37
|
+
optionLabel: string;
|
|
38
|
+
onSubmit: (text: string) => void;
|
|
39
|
+
allowEmpty?: boolean;
|
|
40
|
+
};
|
|
36
41
|
/**
|
|
37
42
|
* Autocomplete provider for the inline custom-input editor. When present,
|
|
38
43
|
* the "Other (type your own)" editor gains the same `@` file-link and `/`
|
|
@@ -19,6 +19,12 @@ export type ModelSelectorSelection = {
|
|
|
19
19
|
} | {
|
|
20
20
|
kind: "createProfile";
|
|
21
21
|
profile: ModelProfileConfig;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "renameProfile";
|
|
24
|
+
profileName: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "deleteProfile";
|
|
27
|
+
profileName: string;
|
|
22
28
|
};
|
|
23
29
|
type RoleSelectCallback = (selection: ModelSelectorSelection) => void | Promise<void>;
|
|
24
30
|
/**
|
|
@@ -47,7 +53,10 @@ export declare class ModelSelectorComponent extends Container {
|
|
|
47
53
|
activeModelProfile?: string;
|
|
48
54
|
}): void;
|
|
49
55
|
handleInput(keyData: string): void;
|
|
56
|
+
refreshPresetProfiles(profileName?: string): void;
|
|
50
57
|
getSearchInput(): Input;
|
|
51
58
|
__testSelectProfile(profileName: string, setDefault: boolean): Promise<void>;
|
|
59
|
+
__testSelectPresetAction(profileName: string, action: "rename" | "delete"): Promise<void>;
|
|
60
|
+
__testSelectedPresetRowIdentity(): string | undefined;
|
|
52
61
|
}
|
|
53
62
|
export {};
|
|
@@ -41,7 +41,9 @@ export declare class ExtensionUiController {
|
|
|
41
41
|
/**
|
|
42
42
|
* Show a text input for hooks.
|
|
43
43
|
*/
|
|
44
|
-
showHookInput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions
|
|
44
|
+
showHookInput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions, inputOptions?: {
|
|
45
|
+
readonly initialValue?: string;
|
|
46
|
+
}): Promise<string | undefined>;
|
|
45
47
|
/**
|
|
46
48
|
* Hide the hook input.
|
|
47
49
|
*/
|
|
@@ -250,7 +250,9 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
250
250
|
setHookStatus(key: string, text: string | undefined): void;
|
|
251
251
|
showHookSelector(title: string, options: string[], dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;
|
|
252
252
|
hideHookSelector(): void;
|
|
253
|
-
showHookInput(title: string, placeholder?: string
|
|
253
|
+
showHookInput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions, inputOptions?: {
|
|
254
|
+
readonly initialValue?: string;
|
|
255
|
+
}): Promise<string | undefined>;
|
|
254
256
|
hideHookInput(): void;
|
|
255
257
|
showHookEditor(title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: {
|
|
256
258
|
promptStyle?: boolean;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep-interview gate mapping (#316).
|
|
3
|
+
*
|
|
4
|
+
* Converts deep-interview `ask`-tool questions into machine-addressable
|
|
5
|
+
* `workflow_gate` { kind: "question" } events (option set + free-text shape
|
|
6
|
+
* encoded in `schema`/`options`) and decodes a `workflow_gate_response` answer
|
|
7
|
+
* back into the exact QuestionResult shape the human path produces, so ambiguity
|
|
8
|
+
* scoring/state updates proceed identically whether a human or an agent answers.
|
|
9
|
+
*
|
|
10
|
+
* This is the pure mapping primitive. Routing the ask tool through it (instead of
|
|
11
|
+
* the interactive select/editor UI) when an unattended controller + gate broker
|
|
12
|
+
* are attached is wired with the transport in #321 and exercised by #323.
|
|
13
|
+
*/
|
|
14
|
+
import type { RpcWorkflowGateKind, RpcWorkflowStage } from "../../rpc/rpc-types";
|
|
1
15
|
import type { OpenGateInput } from "./workflow-gate-broker";
|
|
2
16
|
/** "Other (type your own)" sentinel, mirroring the interactive ask tool. */
|
|
3
17
|
export declare const GATE_OTHER_OPTION = "Other (type your own)";
|
|
@@ -9,6 +23,10 @@ export interface AskGateDeepInterviewState {
|
|
|
9
23
|
dimension: string;
|
|
10
24
|
ambiguity: number;
|
|
11
25
|
}
|
|
26
|
+
export interface AskGateWorkflowGateMeta {
|
|
27
|
+
stage: RpcWorkflowStage;
|
|
28
|
+
kind: RpcWorkflowGateKind;
|
|
29
|
+
}
|
|
12
30
|
export interface AskGateQuestion {
|
|
13
31
|
id: string;
|
|
14
32
|
question: string;
|
|
@@ -22,6 +40,8 @@ export interface AskGateQuestion {
|
|
|
22
40
|
* `stage_state`; when absent, the question text is regex-parsed as a fallback.
|
|
23
41
|
*/
|
|
24
42
|
deepInterview?: AskGateDeepInterviewState;
|
|
43
|
+
/** Override the emitted workflow gate address for non-deep-interview ask prompts. */
|
|
44
|
+
workflowGate?: AskGateWorkflowGateMeta;
|
|
25
45
|
}
|
|
26
46
|
export interface AskGateResult {
|
|
27
47
|
id: string;
|
|
@@ -30,6 +50,7 @@ export interface AskGateResult {
|
|
|
30
50
|
multi: boolean;
|
|
31
51
|
selectedOptions: string[];
|
|
32
52
|
customInput?: string;
|
|
53
|
+
clarificationQuestion?: string;
|
|
33
54
|
}
|
|
34
55
|
/**
|
|
35
56
|
* The answer shape an agent returns for a deep-interview question gate.
|
|
@@ -37,17 +58,30 @@ export interface AskGateResult {
|
|
|
37
58
|
* `selected` are picked option labels; free text is conveyed by `other: true`
|
|
38
59
|
* plus `custom`, encoded separately from `selected` so a real option whose label
|
|
39
60
|
* happens to equal the display sentinel can never collide with the free-text path.
|
|
61
|
+
*
|
|
62
|
+
* `action: "clarify"` is a non-answer. It lets a Deep Interview user ask about
|
|
63
|
+
* the presented choices without advancing the round, scoring ambiguity, or
|
|
64
|
+
* recording selection state.
|
|
40
65
|
*/
|
|
41
|
-
export
|
|
66
|
+
export type DeepInterviewGateAnswer = {
|
|
42
67
|
selected: string[];
|
|
43
|
-
other?:
|
|
44
|
-
custom?:
|
|
45
|
-
|
|
68
|
+
other?: false;
|
|
69
|
+
custom?: undefined;
|
|
70
|
+
action?: "answer";
|
|
71
|
+
} | {
|
|
72
|
+
selected: string[];
|
|
73
|
+
other: true;
|
|
74
|
+
custom: string;
|
|
75
|
+
action?: "answer";
|
|
76
|
+
} | {
|
|
77
|
+
action: "clarify";
|
|
78
|
+
question: string;
|
|
79
|
+
};
|
|
46
80
|
export declare class DeepInterviewGateError extends Error {
|
|
47
|
-
readonly code: "invalid_answer_shape" | "unknown_option" | "multi_not_allowed" | "missing_custom" | "empty_selection" | "duplicate_selection";
|
|
48
|
-
constructor(code: "invalid_answer_shape" | "unknown_option" | "multi_not_allowed" | "missing_custom" | "empty_selection" | "duplicate_selection", message: string);
|
|
81
|
+
readonly code: "invalid_answer_shape" | "unknown_option" | "multi_not_allowed" | "missing_custom" | "missing_clarification" | "empty_selection" | "duplicate_selection";
|
|
82
|
+
constructor(code: "invalid_answer_shape" | "unknown_option" | "multi_not_allowed" | "missing_custom" | "missing_clarification" | "empty_selection" | "duplicate_selection", message: string);
|
|
49
83
|
}
|
|
50
|
-
/** Build the `workflow_gate` open-input for one
|
|
84
|
+
/** Build the `workflow_gate` open-input for one ask question. */
|
|
51
85
|
export declare function questionToGate(question: AskGateQuestion): OpenGateInput;
|
|
52
86
|
/**
|
|
53
87
|
* Decode a gate answer into the QuestionResult the interactive path produces.
|
|
@@ -260,7 +260,9 @@ export interface InteractiveModeContext {
|
|
|
260
260
|
setHookStatus(key: string, text: string | undefined): void;
|
|
261
261
|
showHookSelector(title: string, options: string[], dialogOptions?: ExtensionUIDialogOptions): Promise<string | undefined>;
|
|
262
262
|
hideHookSelector(): void;
|
|
263
|
-
showHookInput(title: string, placeholder?: string
|
|
263
|
+
showHookInput(title: string, placeholder?: string, dialogOptions?: ExtensionUIDialogOptions, inputOptions?: {
|
|
264
|
+
readonly initialValue?: string;
|
|
265
|
+
}): Promise<string | undefined>;
|
|
264
266
|
hideHookInput(): void;
|
|
265
267
|
showHookEditor(title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: {
|
|
266
268
|
promptStyle?: boolean;
|
|
@@ -38,6 +38,8 @@ export declare function markdownToTelegramHtml(markdown: string): string;
|
|
|
38
38
|
* `marker`. The final string is guaranteed to be <= `max`.
|
|
39
39
|
*/
|
|
40
40
|
export declare function truncateTelegramHtml(message: string, max?: number, marker?: string): string;
|
|
41
|
+
/** Split a finished Telegram HTML message into ordered chunks without splitting tags or entities. */
|
|
42
|
+
export declare function splitTelegramHtml(message: string, max?: number): string[];
|
|
41
43
|
/** Finalize an optional message: undefined passthrough, else safe-truncate. */
|
|
42
44
|
export declare function finalizeTelegramHtml(message?: string): string | undefined;
|
|
43
45
|
/**
|
|
@@ -14,6 +14,8 @@ export interface RecentSessionEntry {
|
|
|
14
14
|
mtimeMs: number;
|
|
15
15
|
/** True when a terminal breadcrumb points at this session file. */
|
|
16
16
|
currentTerminal?: boolean;
|
|
17
|
+
/** True when this history is an internal helper/sub-agent session. */
|
|
18
|
+
internal?: boolean;
|
|
17
19
|
}
|
|
18
20
|
export interface RecentActivityDeps {
|
|
19
21
|
/** Root holding `<encoded-cwd>/<sessionId>.jsonl` history files. */
|
|
@@ -22,8 +24,10 @@ export interface RecentActivityDeps {
|
|
|
22
24
|
breadcrumbPaths?: string[];
|
|
23
25
|
/** Max entries to return (default 20). */
|
|
24
26
|
limit?: number;
|
|
27
|
+
/** Include internal helper/sub-agent sessions (default true). */
|
|
28
|
+
includeInternal?: boolean;
|
|
25
29
|
/** Injection seam for tests. */
|
|
26
|
-
|
|
30
|
+
readInitialLines?: (file: string, maxLines: number) => string[];
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
33
|
* List recent sessions ranked by history-file mtime (newest first).
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import type { Settings } from "../config/settings";
|
|
2
|
-
import {
|
|
2
|
+
import type { TelegramDaemonOptions } from "./telegram-daemon";
|
|
3
|
+
type TelegramDaemonRunner = {
|
|
4
|
+
run(): Promise<void>;
|
|
5
|
+
requestStop(reason?: "reload" | "signal" | "stop"): void;
|
|
6
|
+
};
|
|
7
|
+
type TelegramDaemonConstructor = new (opts: TelegramDaemonOptions) => TelegramDaemonRunner;
|
|
3
8
|
export interface RunDaemonInternalDeps {
|
|
4
9
|
SettingsImpl?: {
|
|
5
10
|
init: (options?: {
|
|
6
11
|
agentDir?: string;
|
|
7
12
|
}) => Promise<Pick<Settings, "get" | "getAgentDir">>;
|
|
8
13
|
};
|
|
9
|
-
DaemonImpl?:
|
|
14
|
+
DaemonImpl?: TelegramDaemonConstructor;
|
|
10
15
|
processPid?: number;
|
|
11
16
|
pidAlive?: (pid: number) => boolean;
|
|
12
17
|
}
|
|
@@ -20,3 +25,4 @@ export declare function runDaemonSmoke(opts?: {
|
|
|
20
25
|
agentDir?: string;
|
|
21
26
|
}): Promise<void>;
|
|
22
27
|
export declare function runDaemonInternal(argv: string[], deps?: RunDaemonInternalDeps): Promise<void>;
|
|
28
|
+
export {};
|
|
@@ -29,6 +29,14 @@ export interface TelegramDaemonControlDeps {
|
|
|
29
29
|
sendSignal?: (pid: number, signal: NodeJS.Signals) => void;
|
|
30
30
|
spawn?: TelegramDaemonDeps["spawn"];
|
|
31
31
|
execPath?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Stable process id encoded into freshly-spawned daemon owner ids.
|
|
34
|
+
*
|
|
35
|
+
* The daemon-internal entrypoint rejects numeric owner ids whose process is
|
|
36
|
+
* already gone. `gjc daemon reload` is a short-lived CLI process, so using its
|
|
37
|
+
* own pid can race the child startup and make the replacement exit immediately.
|
|
38
|
+
*/
|
|
39
|
+
ownerPid?: number;
|
|
32
40
|
randomId?: () => string;
|
|
33
41
|
sleep?: (ms: number) => Promise<void>;
|
|
34
42
|
waitStepMs?: number;
|
|
@@ -16,14 +16,6 @@ export interface DaemonState {
|
|
|
16
16
|
version: 1;
|
|
17
17
|
stoppedAt?: number;
|
|
18
18
|
}
|
|
19
|
-
export interface DaemonPaths {
|
|
20
|
-
dir: string;
|
|
21
|
-
lock: string;
|
|
22
|
-
state: string;
|
|
23
|
-
roots: string;
|
|
24
|
-
steal: string;
|
|
25
|
-
aliases: string;
|
|
26
|
-
}
|
|
27
19
|
export interface TelegramDaemonFs {
|
|
28
20
|
mkdir(path: string, opts?: fs.MakeDirectoryOptions): Promise<void>;
|
|
29
21
|
readFile(path: string, encoding: BufferEncoding): Promise<string>;
|
|
@@ -59,7 +51,7 @@ export declare const DAEMON_VERSION = 1;
|
|
|
59
51
|
export declare const CLIENT_PING_PONG_CAPABILITY = "client_ping_pong";
|
|
60
52
|
/** Protocol version the daemon advertises in its ClientHello. */
|
|
61
53
|
export declare const NOTIFICATION_PROTOCOL_VERSION = 2;
|
|
62
|
-
export
|
|
54
|
+
export { type DaemonPaths, daemonPaths } from "./daemon-paths";
|
|
63
55
|
/**
|
|
64
56
|
* Attach session-lifecycle control (create/close/resume) to the running daemon.
|
|
65
57
|
*
|
|
@@ -390,4 +382,3 @@ export declare class TelegramNotificationDaemon {
|
|
|
390
382
|
run(): Promise<void>;
|
|
391
383
|
private controlStopRequested;
|
|
392
384
|
}
|
|
393
|
-
export {};
|
|
@@ -23,6 +23,7 @@ export interface RenderedMessage {
|
|
|
23
23
|
text: string;
|
|
24
24
|
inline_keyboard?: InlineButton[][];
|
|
25
25
|
}
|
|
26
|
+
type TelegramSend = (method: string, body: unknown) => Promise<Response>;
|
|
26
27
|
/** Encode `actionId` + option `index` into Telegram callback_data (<=64 bytes). */
|
|
27
28
|
export declare function encodeCallbackData(actionId: string, index: number): string;
|
|
28
29
|
/** Decode callback_data produced by {@link encodeCallbackData}. */
|
|
@@ -58,6 +59,8 @@ export declare function buildActionMessage(action: {
|
|
|
58
59
|
options?: string[];
|
|
59
60
|
summary?: string;
|
|
60
61
|
}): RenderedMessage;
|
|
62
|
+
/** Send Telegram HTML text chunks sequentially so long messages preserve order. */
|
|
63
|
+
export declare function sendTelegramHtmlChunks(send: TelegramSend, chatId: string, text: string, inlineKeyboard?: InlineButton[][]): Promise<void>;
|
|
61
64
|
/** A protocol `reply` frame the client should send to the server. */
|
|
62
65
|
export interface ReplyFrame {
|
|
63
66
|
type: "reply";
|
|
@@ -111,3 +114,4 @@ export interface TelegramReferenceOptions {
|
|
|
111
114
|
* production clients add reconnection, multi-chat routing, and persistence.
|
|
112
115
|
*/
|
|
113
116
|
export declare function runTelegramReferenceClient(opts: TelegramReferenceOptions): Promise<void>;
|
|
117
|
+
export {};
|