@gajae-code/coding-agent 0.8.0 → 0.8.2

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.
Files changed (116) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/types/cli/completion-cli.d.ts +41 -0
  3. package/dist/types/cli/config-cli.d.ts +1 -0
  4. package/dist/types/cli/notify-cli.d.ts +7 -0
  5. package/dist/types/cli.d.ts +124 -1
  6. package/dist/types/commands/completion.d.ts +29 -0
  7. package/dist/types/commands/config.d.ts +3 -0
  8. package/dist/types/commands/deep-interview.d.ts +3 -0
  9. package/dist/types/config/file-lock.d.ts +7 -6
  10. package/dist/types/config/keybindings.d.ts +2 -2
  11. package/dist/types/config/model-profile-activation.d.ts +6 -0
  12. package/dist/types/config/settings.d.ts +8 -0
  13. package/dist/types/extensibility/extensions/runner.d.ts +2 -1
  14. package/dist/types/extensibility/extensions/types.d.ts +8 -0
  15. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +39 -0
  16. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +10 -1
  17. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +1 -1
  18. package/dist/types/gjc-runtime/deep-interview-state.d.ts +12 -0
  19. package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
  20. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
  21. package/dist/types/main.d.ts +4 -1
  22. package/dist/types/modes/components/model-selector.d.ts +4 -0
  23. package/dist/types/modes/components/queued-message-selector.d.ts +12 -0
  24. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  25. package/dist/types/modes/controllers/input-controller.d.ts +1 -3
  26. package/dist/types/modes/print-mode.d.ts +13 -1
  27. package/dist/types/modes/prompt-action-autocomplete.d.ts +1 -1
  28. package/dist/types/notifications/config.d.ts +8 -1
  29. package/dist/types/notifications/daemon-paths.d.ts +1 -0
  30. package/dist/types/notifications/index.d.ts +6 -3
  31. package/dist/types/notifications/lifecycle-commands.d.ts +11 -3
  32. package/dist/types/notifications/telegram-daemon.d.ts +18 -3
  33. package/dist/types/notifications/telegram-reference.d.ts +0 -5
  34. package/dist/types/runtime-api-key.d.ts +7 -0
  35. package/dist/types/session/agent-session.d.ts +10 -0
  36. package/dist/types/session/agent-storage.d.ts +1 -0
  37. package/dist/types/task/executor.d.ts +2 -0
  38. package/dist/types/tools/computer.d.ts +2 -2
  39. package/dist/types/tools/skill.d.ts +1 -1
  40. package/dist/types/workflow/workflow-intent-diff.d.ts +8 -2
  41. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +50 -0
  42. package/dist/types/workflow/workflow-intent-report-schema.d.ts +2 -0
  43. package/dist/types/workflow/workflow-intent-report.d.ts +48 -0
  44. package/package.json +7 -7
  45. package/src/cli/completion-cli.ts +234 -0
  46. package/src/cli/config-cli.ts +37 -9
  47. package/src/cli/fast-help.ts +1 -0
  48. package/src/cli/notify-cli.ts +91 -7
  49. package/src/cli.ts +3 -1
  50. package/src/commands/completion.ts +84 -0
  51. package/src/commands/config.ts +2 -0
  52. package/src/commands/deep-interview.ts +2 -1
  53. package/src/config/file-lock.ts +73 -34
  54. package/src/config/keybindings.ts +2 -2
  55. package/src/config/model-profile-activation.ts +65 -0
  56. package/src/config/model-registry.ts +14 -2
  57. package/src/config/settings.ts +22 -0
  58. package/src/coordinator-mcp/server.ts +67 -12
  59. package/src/defaults/gjc/skills/deep-interview/SKILL.md +38 -5
  60. package/src/defaults/gjc/skills/ralplan/SKILL.md +15 -11
  61. package/src/defaults/gjc/skills/team/SKILL.md +1 -1
  62. package/src/extensibility/extensions/runner.ts +2 -0
  63. package/src/extensibility/extensions/types.ts +9 -0
  64. package/src/extensibility/skills.ts +30 -2
  65. package/src/gjc-runtime/deep-interview-ambiguity.ts +206 -0
  66. package/src/gjc-runtime/deep-interview-recorder.ts +62 -8
  67. package/src/gjc-runtime/deep-interview-runtime.ts +210 -2
  68. package/src/gjc-runtime/deep-interview-state.ts +13 -0
  69. package/src/gjc-runtime/session-state-sidecar.ts +59 -11
  70. package/src/gjc-runtime/state-runtime.ts +12 -2
  71. package/src/gjc-runtime/team-runtime.ts +23 -0
  72. package/src/gjc-runtime/ultragoal-runtime.ts +73 -19
  73. package/src/hooks/native-skill-hook.ts +29 -0
  74. package/src/internal-urls/docs-index.generated.ts +2 -2
  75. package/src/main.ts +52 -41
  76. package/src/modes/acp/acp-agent.ts +7 -6
  77. package/src/modes/components/model-selector.ts +54 -11
  78. package/src/modes/components/queued-message-selector.ts +92 -0
  79. package/src/modes/components/settings-selector.ts +4 -0
  80. package/src/modes/components/welcome.ts +160 -44
  81. package/src/modes/controllers/command-controller.ts +4 -4
  82. package/src/modes/controllers/extension-ui-controller.ts +4 -10
  83. package/src/modes/controllers/input-controller.ts +186 -25
  84. package/src/modes/controllers/selector-controller.ts +122 -27
  85. package/src/modes/interactive-mode.ts +43 -16
  86. package/src/modes/print-mode.ts +43 -4
  87. package/src/modes/prompt-action-autocomplete.ts +24 -13
  88. package/src/modes/utils/hotkeys-markdown.ts +1 -0
  89. package/src/modes/utils/ui-helpers.ts +2 -2
  90. package/src/notifications/config.ts +9 -1
  91. package/src/notifications/daemon-paths.ts +2 -0
  92. package/src/notifications/index.ts +39 -9
  93. package/src/notifications/lifecycle-commands.ts +37 -7
  94. package/src/notifications/lifecycle-orchestrator.ts +19 -6
  95. package/src/notifications/telegram-daemon-control.ts +3 -1
  96. package/src/notifications/telegram-daemon.ts +231 -43
  97. package/src/notifications/telegram-reference.ts +0 -16
  98. package/src/prompts/system/system-prompt.md +3 -0
  99. package/src/prompts/tools/computer.md +2 -2
  100. package/src/runtime-api-key.ts +16 -0
  101. package/src/sdk.ts +20 -6
  102. package/src/session/agent-session.ts +225 -31
  103. package/src/session/agent-storage.ts +4 -0
  104. package/src/session/session-manager.ts +44 -2
  105. package/src/slash-commands/builtin-registry.ts +153 -71
  106. package/src/task/executor.ts +7 -4
  107. package/src/task/index.ts +9 -3
  108. package/src/task/output-manager.ts +16 -6
  109. package/src/task/receipt.ts +26 -7
  110. package/src/tools/computer.ts +246 -43
  111. package/src/tools/skill.ts +1 -1
  112. package/src/tools/telegram-send.ts +6 -0
  113. package/src/workflow/workflow-intent-diff.ts +29 -6
  114. package/src/workflow/workflow-intent-report-consumer.ts +221 -0
  115. package/src/workflow/workflow-intent-report-schema.ts +129 -0
  116. package/src/workflow/workflow-intent-report.ts +135 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,54 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.8.2] - 2026-07-06
6
+ ### Added
7
+
8
+ - Queued message selector entries can now be reordered with `Ctrl+Up` / `Ctrl+Down`, with `Ctrl+Shift+Up` / `Ctrl+Shift+Down` still accepted when the terminal forwards them, while keeping the current draft intact.
9
+
10
+ - Added `gjc completion inshellisense`, which generates or installs a Fig/withfig-compatible `gjc` completion spec for Microsoft inshellisense without adding inshellisense as a runtime dependency.
11
+
12
+ ### Fixed
13
+ - `gjc team` packaged binaries now avoid persisting Bun virtual `/$bunfs/...` entrypoints as worker commands, so tmux worker panes launch through a real executable or the `gjc` fallback instead of immediately disappearing (#1661).
14
+ - `computer` now honors `include_screenshot` and `computer.autoScreenshot` by returning bounded post-action screenshots, and batch steps now respect nested per-step `timeout` values.
15
+ - Custom-provider `gpt-5.5` entries without an explicit `contextWindow` now default to the 272K Codex prompt budget unless the provider uses first-party `openai-responses`, so Codex passthrough proxies (e.g. CLIProxyAPI) compact in time instead of dying with `context_length_exceeded` at ~272K while the registry advertises 1M.
16
+ - `telegram_send` now rejects files over Telegram's document upload limit before reading them into memory or handing them to the notification sink.
17
+ - `telegram_send` now rejects file attachments while Telegram notification redaction is enabled, preventing explicit file sends from bypassing the redaction boundary.
18
+ - Telegram notification daemons now persist consumed update ids so threaded replies are not reinjected after a daemon restart replays old `getUpdates` entries.
19
+ - Telegram notify setup now hides the interactive BotFather token prompt input, preventing the raw bot token from being echoed into terminal scrollback while pairing notifications.
20
+ - Telegram unattended workflow-gate listeners are now disposed when a notification session stops, preventing stale stopped servers from retaining future gate emissions after shutdown or notification restart.
21
+ - Telegram notification setup and daemon delivery now reject non-private Telegram chat ids before saving configuration, creating forum topics, or sending session content, preserving the private-chat-only routing boundary.
22
+ - Telegram daemon autostart now refuses to attach a new session to a live daemon whose persisted bot-token fingerprint or chat id differs from the current settings, and it avoids registering the session root until ownership is trusted so rotated Telegram credentials cannot keep leaking through the old daemon.
23
+ - Skill autocomplete now supports direct skill-name prefixes after prompt text (for example, `please /ra` → `/skill:ralplan`) while keeping bare `/` menus free of skill entries.
24
+ - `gjc --tmux` on native Windows/psmux now keeps the status line and composer pinned to the bottom after viewport redraws by honoring the GJC tmux launch marker as a multiplexer signal even when `$TMUX` is absent.
25
+ - Provider safety refusals (e.g. Anthropic `stop_reason: "refusal"` → `Refusal (<category>): …`, and `sensitive` → `Content flagged by safety filters`) are now classified as terminal retry errors and surface immediately. They previously fell through to the unbounded `"unknown"` retry class, and because a refusal is deterministic for the submitted context, the session looped refusal → retry → refusal forever — resubmitting the full context every `retry.maxDelayMs` and re-billing it as a prompt-cache write whenever the backoff outlived the cache TTL (#1655).
26
+ - Coordinator event watches now wake on runtime sidecar state changes and emit a bounded `turn.acknowledged` event, so a tmux-resident session that accepts a prompt and then vanishes is durably classified as recoverable `tmux_session_missing_after_prompt_acknowledgement` instead of leaving only a watch registration with no terminal verdict (#1496).
27
+ - Raw tmux-resident sessions now persist public-safe runtime state under their `.gjc/_session-*/runtime/runtime-state.json` even when no coordinator sidecar env is present, so post-ack owner exits leave recoverable `process_exit_before_terminal_state` evidence instead of looking like successful cleanup with no durable output (#1496).
28
+
29
+ - `gjc config list`, `gjc config get`, and `gjc config set` now redact secret-like string settings by default, with `--show-secrets` as an explicit unsafe opt-in.
30
+
31
+ - `/new` session-start notifications now render directly under the welcome panel instead of leaving an extra blank row above the confirmation line.
32
+ - Goal completion now preserves the terminal `goal({op: "complete"})` state even when a `goal_updated` extension hook throws, preventing hook-side write errors from trapping a verified ultragoal run in the continuation loop.
33
+ - Ultragoal completion no longer requires the computer-use red-team suite for non-computer changes that only touch the shared `tools/index.ts` registration file.
34
+ - Task subagent output-ID allocation (`AgentOutputManager`) is now concurrency-safe. `#ensureInitialized` previously set a boolean flag *before* the awaited `readdir`, so when two `task` calls are dispatched in the same turn (they run concurrently as shared-concurrency tools on one session-scoped manager) the second allocation short-circuited initialization and started from index `0` while the first scan was still in flight — colliding with existing `N-*.md` outputs and duplicating ids across batches, which overwrote prior subagent outputs on resume. The scan is now memoized as a promise so concurrent `allocate`/`allocateBatch`/`peekNextIndex` calls await the same `readdir` before `#nextId` is derived.
35
+ - Task fork-context seeds (`inheritContext`) now keep a *contiguous* run of the most recent messages. The selection loop in `buildForkContextSeed` walks newest→oldest but used `continue` when a message overflowed the token budget, so it skipped the oversized recent message and scavenged smaller *older* ones — yielding a non-contiguous seed that misrepresents the conversation and breaks the recency contract of the `receipt`/`last-turn`/`bounded` modes. It now `break`s at the first over-budget message, so a subagent receives the actual recent context (or none) instead of a jumbled mix of recent and stale messages.
36
+ - The `/settings` → Model → **Default Model Profile** submenu now lists the model profiles from the registry instead of rendering an empty `No matching commands` list. The setting declared `options: "runtime"`, but the selector layer only injected runtime choices for themes, thinking level, and the status-line preset — never for model profiles — so the submenu was always empty. Selecting a profile there now also applies it live (the same `activateModelProfile` path as the `/model` preset flow) and persists it as the startup default, instead of only persisting for the next startup.
37
+ - `gjc stats` now resolves to the usage-statistics command instead of being treated as a chat prompt. `src/commands/stats.ts` (backed by the `@gajae-code/stats` dependency via `src/cli/stats-cli.ts`) existed and was fully functional, but the entry was never added to the `commands` registry in `cli.ts`, so `isSubcommand()` returned false for `stats` and the invocation fell through to the default `launch` command — leaving the usage dashboard/summary unreachable and absent from `gjc --help`. Registered the command and listed it in the help surface.
38
+
39
+ ## [0.8.1] - 2026-07-04
40
+
41
+ ### Added
42
+
43
+ - Skills can now be invoked inline within a prompt (for example, mid-message `/skill:*` references) instead of only as a standalone prompt, with matching autocomplete, input-controller queueing, and ACP dispatch support.
44
+
45
+ ### Fixed
46
+
47
+ - The Telegram notification daemon now tombstones a session endpoint generation after `session_closed`, preventing the scan loop from reconnecting to the still-live old endpoint and recreating an empty topic immediately after deleting the original topic.
48
+ - `/contribute-pr` in the interactive TUI now prepares the redacted manifest and worker prompt without spawning a second GJC process on the same terminal, avoiding competing TUI renderers that make the chat viewport jump around. Run the generated worker prompt from a separate terminal instead.
49
+ - The `skill` tool is now a default-registered essential tool instead of a discoverable one, so skill chaining is always available without first activating it through tool discovery.
50
+ - The coordinator MCP server now classifies vanished-but-acknowledged tmux turns correctly, avoiding spurious delivery failures when a delegated turn's pane disappears after its prompt was already acknowledged.
51
+ - Tool-call argument strings are now sanitized of invalid Unicode surrogate sequences across providers (Anthropic, Bedrock, Google, OpenAI chat/completions/responses, and Codex), including custom Responses tool input, preventing malformed tool calls from breaking requests.
52
+
5
53
  ## [0.8.0] - 2026-07-04
6
54
 
7
55
  ### Added
@@ -0,0 +1,41 @@
1
+ import type { CommandCtor, CommandEntry } from "@gajae-code/utils/cli";
2
+ export type FigName = string | string[];
3
+ export interface FigArg {
4
+ name: string;
5
+ description?: string;
6
+ isOptional?: boolean;
7
+ isVariadic?: boolean;
8
+ suggestions?: string[];
9
+ }
10
+ export interface FigOption {
11
+ name: FigName;
12
+ description?: string;
13
+ args?: FigArg;
14
+ isRepeatable?: boolean;
15
+ }
16
+ export interface FigSubcommand {
17
+ name: FigName;
18
+ description?: string;
19
+ options?: FigOption[];
20
+ args?: FigArg | FigArg[];
21
+ }
22
+ export interface FigSpec extends FigSubcommand {
23
+ name: string;
24
+ subcommands?: FigSubcommand[];
25
+ }
26
+ export type InshellisenseIndexStatus = "created" | "updated" | "already-compatible" | "overwritten";
27
+ export interface InstallGjcInshellisenseSpecOptions {
28
+ dir?: string;
29
+ force?: boolean;
30
+ }
31
+ export interface InstallGjcInshellisenseSpecResult {
32
+ directory: string;
33
+ specPath: string;
34
+ indexPath: string;
35
+ indexStatus: InshellisenseIndexStatus;
36
+ }
37
+ export declare function defaultInshellisenseSpecDir(homeDir?: string): string;
38
+ export declare function buildGjcFigSpec(entries: CommandEntry[], rootCommandOverride?: CommandCtor): Promise<FigSpec>;
39
+ export declare function renderFigSpecModule(spec: FigSpec): string;
40
+ export declare function renderInshellisenseIndexModule(): string;
41
+ export declare function installGjcInshellisenseSpec(spec: FigSpec, options?: InstallGjcInshellisenseSpecOptions): Promise<InstallGjcInshellisenseSpecResult>;
@@ -11,6 +11,7 @@ export interface ConfigCommandArgs {
11
11
  value?: string;
12
12
  flags: {
13
13
  json?: boolean;
14
+ showSecrets?: boolean;
14
15
  };
15
16
  }
16
17
  /**
@@ -22,4 +22,11 @@ export interface NotifyCommandDeps {
22
22
  }
23
23
  export declare function parseNotifyArgs(args: string[]): NotifyCommandArgs | undefined;
24
24
  export declare function runNotifyCommand(cmd: NotifyCommandArgs, deps?: NotifyCommandDeps): Promise<void>;
25
+ type TokenPromptInput = NodeJS.ReadStream & {
26
+ isRaw?: boolean;
27
+ setRawMode?: (mode: boolean) => unknown;
28
+ };
29
+ type TokenPromptOutput = Pick<NodeJS.WriteStream, "write">;
30
+ export declare function promptForToken(input?: TokenPromptInput, output?: TokenPromptOutput): Promise<string>;
25
31
  export declare function printNotifyHelp(): void;
32
+ export {};
@@ -3,7 +3,130 @@
3
3
  * CLI entry point — registers all commands explicitly and delegates to the
4
4
  * lightweight CLI runner from pi-utils.
5
5
  */
6
- import { type CommandEntry } from "@gajae-code/utils/cli";
6
+ import { Command, type CommandEntry } from "@gajae-code/utils/cli";
7
7
  export declare const commands: CommandEntry[];
8
+ export declare class RootHelpCommand extends Command {
9
+ static description: string;
10
+ static hidden: boolean;
11
+ static args: {
12
+ messages: import("@gajae-code/utils/cli").ArgDescriptor & {
13
+ description: string;
14
+ required: false;
15
+ multiple: true;
16
+ };
17
+ };
18
+ static flags: {
19
+ model: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
20
+ description: string;
21
+ };
22
+ smol: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
23
+ description: string;
24
+ };
25
+ slow: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
26
+ description: string;
27
+ };
28
+ plan: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
29
+ description: string;
30
+ };
31
+ mpreset: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
32
+ description: string;
33
+ };
34
+ default: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
35
+ description: string;
36
+ };
37
+ provider: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
38
+ description: string;
39
+ };
40
+ "api-key": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
41
+ description: string;
42
+ };
43
+ "system-prompt": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
44
+ description: string;
45
+ };
46
+ "append-system-prompt": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
47
+ description: string;
48
+ };
49
+ "allow-home": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
50
+ description: string;
51
+ };
52
+ mode: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
53
+ description: string;
54
+ options: string[];
55
+ };
56
+ print: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
57
+ char: string;
58
+ description: string;
59
+ };
60
+ continue: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
61
+ char: string;
62
+ description: string;
63
+ };
64
+ resume: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
65
+ char: string;
66
+ description: string;
67
+ };
68
+ "session-dir": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
69
+ description: string;
70
+ };
71
+ "no-session": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
72
+ description: string;
73
+ };
74
+ models: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
75
+ description: string;
76
+ };
77
+ "no-tools": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
78
+ description: string;
79
+ };
80
+ "no-lsp": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
81
+ description: string;
82
+ };
83
+ "no-pty": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
84
+ description: string;
85
+ };
86
+ tmux: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
87
+ description: string;
88
+ };
89
+ tools: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
90
+ description: string;
91
+ };
92
+ thinking: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
93
+ description: string;
94
+ options: string[];
95
+ };
96
+ hook: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
97
+ description: string;
98
+ multiple: true;
99
+ };
100
+ extension: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
101
+ char: string;
102
+ description: string;
103
+ multiple: true;
104
+ };
105
+ "no-extensions": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
106
+ description: string;
107
+ };
108
+ "no-skills": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
109
+ description: string;
110
+ };
111
+ skills: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
112
+ description: string;
113
+ };
114
+ "no-rules": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
115
+ description: string;
116
+ };
117
+ export: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
118
+ description: string;
119
+ };
120
+ "list-models": import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
121
+ description: string;
122
+ };
123
+ "no-title": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
124
+ description: string;
125
+ };
126
+ };
127
+ static examples: string[];
128
+ static strict: boolean;
129
+ run(): Promise<void>;
130
+ }
8
131
  /** Run the CLI with the given argv (no `process.argv` prefix). */
9
132
  export declare function runCli(argv: string[]): Promise<void>;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Generate shell completion specs for external completion engines.
3
+ */
4
+ import { Command } from "@gajae-code/utils/cli";
5
+ export default class Completion extends Command {
6
+ static description: string;
7
+ static args: {
8
+ target: import("@gajae-code/utils/cli").ArgDescriptor & {
9
+ description: string;
10
+ required: false;
11
+ options: readonly ["inshellisense", "fig"];
12
+ };
13
+ };
14
+ static flags: {
15
+ install: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
16
+ description: string;
17
+ };
18
+ dir: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
19
+ description: string;
20
+ };
21
+ force: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
22
+ description: string;
23
+ };
24
+ json: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
25
+ description: string;
26
+ };
27
+ };
28
+ run(): Promise<void>;
29
+ }
@@ -25,6 +25,9 @@ export default class Config extends Command {
25
25
  json: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
26
26
  description: string;
27
27
  };
28
+ "show-secrets": import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
29
+ description: string;
30
+ };
28
31
  };
29
32
  run(): Promise<void>;
30
33
  }
@@ -12,6 +12,9 @@ export default class DeepInterview extends Command {
12
12
  deep: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
13
13
  description: string;
14
14
  };
15
+ trace: import("@gajae-code/utils/cli").FlagDescriptor<"boolean"> & {
16
+ description: string;
17
+ };
15
18
  threshold: import("@gajae-code/utils/cli").FlagDescriptor<"string"> & {
16
19
  description: string;
17
20
  };
@@ -13,16 +13,17 @@ export interface FileLockOwnerToken {
13
13
  pid: number;
14
14
  timestamp: number;
15
15
  }
16
- /** Outcome of a guarded GC removal attempt (`removeFileLockDirForGc`). */
16
+ /** Outcome of a guarded lock-dir removal attempt (`removeFileLockDirForGc`). */
17
17
  export type FileLockGcRemoval = "removed" | "owner_changed" | "missing";
18
18
  /**
19
19
  * @internal
20
- * Fail-closed removal of a dead lock dir for GC. Re-reads the on-disk owner
21
- * token as close to the unlink as possible and only deletes the dir when it
22
- * STILL holds the exact `{pid, timestamp}` identity the caller observed dead.
20
+ * Fail-closed removal of a lock dir whose owner is expected to be dead or
21
+ * finished. Re-reads the on-disk owner token as close to the unlink as possible
22
+ * and only deletes the dir when it STILL holds the exact `{pid, timestamp}`
23
+ * identity the caller observed.
23
24
  *
24
- * Closes the prune-time TOCTOU window (#606): between GC's dead re-read/probe
25
- * and the unlink, a live process can reclaim a stale lock at the same path
25
+ * Closes stale-cleanup TOCTOU windows (#606): between a dead/stale re-read and
26
+ * the unlink, a live process can reclaim a stale lock at the same path
26
27
  * (`acquireLock` rms the stale dir, then re-`mkdir`s and rewrites `info` with a
27
28
  * fresh pid+timestamp). Deleting by path alone would reap that LIVE lock. Any
28
29
  * mismatch (`owner_changed`) or absent/unreadable info (`missing` — e.g. a
@@ -244,8 +244,8 @@ export declare const KEYBINDINGS: {
244
244
  readonly description: "Queue message for next turn";
245
245
  };
246
246
  readonly "app.message.dequeue": {
247
- readonly defaultKeys: "alt+up";
248
- readonly description: "Dequeue message";
247
+ readonly defaultKeys: ["alt+up", "alt+down"];
248
+ readonly description: "Select queued message to edit";
249
249
  };
250
250
  readonly "app.clipboard.pasteImage": {
251
251
  readonly defaultKeys: "alt+v" | "ctrl+v";
@@ -46,7 +46,13 @@ export interface MaterializeModelProfileAssignmentOptions {
46
46
  role: GjcModelAssignmentTargetId;
47
47
  selector: string;
48
48
  }
49
+ export interface MaterializeModelProfileAssignmentsOptions {
50
+ session: Pick<ModelProfileActivationSession, "model" | "thinkingLevel" | "setActiveModelProfile" | "getActiveModelProfile">;
51
+ settings: Pick<Settings, "clearOverride" | "get" | "override" | "set">;
52
+ assignments: ReadonlyMap<GjcModelAssignmentTargetId, string> | Partial<Record<GjcModelAssignmentTargetId, string>>;
53
+ }
49
54
  export declare function materializeActiveModelProfileAssignment(options: MaterializeModelProfileAssignmentOptions): boolean;
55
+ export declare function materializeActiveModelProfileAssignments(options: MaterializeModelProfileAssignmentsOptions): boolean;
50
56
  export declare function formatModelProfileCredentialError(profileLabel: string, providers: readonly string[]): string;
51
57
  export declare function prepareModelProfileActivation(options: PrepareModelProfileActivationOptions): Promise<PreparedModelProfileActivation>;
52
58
  export declare function applyPreparedModelProfileActivation(prepared: PreparedModelProfileActivation, options?: {
@@ -108,6 +108,14 @@ export declare class Settings {
108
108
  * Set a model role (helper for modelRoles record).
109
109
  */
110
110
  setModelRole(role: ModelRole | string, modelId: string): void;
111
+ /**
112
+ * Set an agent model override while keeping any live runtime override aligned.
113
+ *
114
+ * Runtime model profiles override `task.agentModelOverrides` for the current
115
+ * session. A user-selected role assignment must win immediately in that same
116
+ * session, but only the explicit agent change should be persisted.
117
+ */
118
+ setAgentModelOverride(agentName: string, modelId: string): void;
111
119
  /**
112
120
  * Get a model role (helper for modelRoles record).
113
121
  */
@@ -61,7 +61,8 @@ export declare class ExtensionRunner {
61
61
  private readonly cwd;
62
62
  private readonly sessionManager;
63
63
  private readonly modelRegistry;
64
- constructor(extensions: Extension[], runtime: ExtensionRuntime, cwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry);
64
+ private readonly sessionMetadata?;
65
+ constructor(extensions: Extension[], runtime: ExtensionRuntime, cwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry, sessionMetadata?: ExtensionContext["sessionMetadata"]);
65
66
  initialize(actions: ExtensionActions, contextActions: ExtensionContextActions, commandContextActions?: ExtensionCommandContextActions, uiContext?: ExtensionUIContext): void;
66
67
  /**
67
68
  * Forward a `credential_disabled` event from `AuthStorage` to extension handlers.
@@ -186,6 +186,12 @@ export interface CompactOptions {
186
186
  onComplete?: (result: CompactionResult) => void;
187
187
  onError?: (error: Error) => void;
188
188
  }
189
+ export interface ExtensionSessionMetadata {
190
+ kind: "main" | "sub";
191
+ taskDepth: number;
192
+ parentTaskPrefix?: string;
193
+ currentAgentType?: string;
194
+ }
189
195
  /**
190
196
  * Context passed to extension event handlers.
191
197
  */
@@ -202,6 +208,8 @@ export interface ExtensionContext {
202
208
  cwd: string;
203
209
  /** Session manager (read-only) */
204
210
  sessionManager: ReadonlySessionManager;
211
+ /** Session classification supplied by the SDK for extension policy decisions. */
212
+ sessionMetadata?: ExtensionSessionMetadata;
205
213
  /** Model registry for API key resolution */
206
214
  modelRegistry: ModelRegistry;
207
215
  /** Current model (may be undefined) */
@@ -0,0 +1,39 @@
1
+ import { type DeepInterviewStateEnvelope } from "./deep-interview-state";
2
+ export interface AmbiguityFloorBreakdown {
3
+ floor: number;
4
+ disputed_fact_count: number;
5
+ unscored_active_component_count: number;
6
+ auto_answer_ratio: number;
7
+ }
8
+ export interface AmbiguityClampResult {
9
+ effective: number;
10
+ clamped: boolean;
11
+ }
12
+ /** Compute the deterministic floor from the inner deep-interview `state` object. */
13
+ export declare function computeAmbiguityFloor(inner: unknown): AmbiguityFloorBreakdown;
14
+ /** Clamp an LLM-reported ambiguity to the deterministic floor: `max(reported, floor)`. */
15
+ export declare function clampReportedAmbiguity(reported: number, floor: number): AmbiguityClampResult;
16
+ /**
17
+ * Mark every established fact recorded in `retractedRound` as disputed. This is the
18
+ * mechanical contradiction signal for answer retraction: when the user replaces an
19
+ * already-scored answer (A -> B pivot), the facts that answer established can no
20
+ * longer be trusted, so they raise the floor until re-confirmed or superseded.
21
+ * Returns new arrays/objects; never mutates the input.
22
+ */
23
+ export declare function disputeFactsFromRetractedRound(facts: readonly unknown[], retractedRound: number): {
24
+ facts: Record<string, unknown>[];
25
+ disputedIds: string[];
26
+ };
27
+ export interface AppliedAmbiguityFloor {
28
+ envelope: DeepInterviewStateEnvelope;
29
+ breakdown: AmbiguityFloorBreakdown;
30
+ clamped: boolean;
31
+ }
32
+ /**
33
+ * Enforce the floor invariant on a full deep-interview envelope: recompute the floor
34
+ * from persisted evidence, clamp `state.current_ambiguity`, and clamp the latest
35
+ * scored round (preserving the original value as `reported_ambiguity` for audit).
36
+ * Historical rounds are never rewritten. Idempotent and non-mutating; every writer
37
+ * (state CLI write/reconcile, recorder) applies this immediately before persisting.
38
+ */
39
+ export declare function applyAmbiguityFloorToEnvelope(value: unknown): AppliedAmbiguityFloor;
@@ -1,4 +1,5 @@
1
1
  import { type DeepInterviewEstablishedFact, type DeepInterviewRoundRecord, type DeepInterviewStateEnvelope, type DeepInterviewTriggerMetadata } from "./deep-interview-state";
2
+ export * from "./deep-interview-ambiguity";
2
3
  export * from "./deep-interview-state";
3
4
  /**
4
5
  * Runtime-owned deep-interview round recorder (conflict-aware scoring support).
@@ -86,12 +87,20 @@ export declare function projectCompactState(value: unknown, options?: {
86
87
  }): DeepInterviewCompactState;
87
88
  /** Refresh the best-effort HUD cache from persisted deep-interview state. */
88
89
  export declare function syncDeepInterviewRecorderHud(cwd: string, statePath: string, sessionId: string | undefined): Promise<void>;
89
- /** Record an `answered` shell for one round (append-or-merge by durable key). */
90
+ /**
91
+ * Record an `answered` shell for one round (append-or-merge by durable key).
92
+ *
93
+ * Retraction dynamics: replacing an already-`scored` answer is a mechanical
94
+ * contradiction signal (the user pivoted). The facts that round established are
95
+ * marked disputed, which raises the deterministic ambiguity floor immediately —
96
+ * without waiting for the LLM scorer to self-report a trigger.
97
+ */
90
98
  export declare function appendOrMergeDeepInterviewRound(cwd: string, statePath: string, input: DeepInterviewAnswerInput, options?: {
91
99
  sessionId?: string;
92
100
  }): Promise<{
93
101
  action: AppendOrMergeAction;
94
102
  record: DeepInterviewRoundRecord;
103
+ disputedFactIds?: string[];
95
104
  }>;
96
105
  /** Merge scoring output into the same round record, transitioning to `scored`. */
97
106
  export declare function enrichDeepInterviewRoundScoring(cwd: string, statePath: string, input: DeepInterviewScoringInput, options?: {
@@ -4,7 +4,7 @@ export * from "./deep-interview-recorder";
4
4
  *
5
5
  * The CLI itself does not run the Socratic interview; that lives inside the `/skill:deep-interview`
6
6
  * skill executed by the agent. This handler validates the documented argument-hint surface
7
- * (`[--quick|--standard|--deep] <idea>`), seeds `.gjc/state/deep-interview-state.json`, and
7
+ * (`[--trace] [--quick|--standard|--deep] <idea>`), seeds `.gjc/state/deep-interview-state.json`, and
8
8
  * updates the shared HUD rail via `syncSkillActiveState` so the active interview is visible to
9
9
  * the TUI.
10
10
  */
@@ -21,6 +21,13 @@ export interface DeepInterviewEstablishedFact {
21
21
  dimension?: string;
22
22
  evidence?: string;
23
23
  disputed: boolean;
24
+ /**
25
+ * Resolution pointer for a disputed fact: the id of the fact that replaced it
26
+ * after the user confirmed a pivot. A disputed fact without `superseded_by`
27
+ * keeps the deterministic ambiguity floor elevated; setting it releases the
28
+ * pressure while preserving the contradicted fact for audit.
29
+ */
30
+ superseded_by?: string;
24
31
  }
25
32
  export interface DeepInterviewTriggerMetadata {
26
33
  kind: DeepInterviewTriggerKind;
@@ -54,7 +61,12 @@ export interface DeepInterviewRoundRecord {
54
61
  answered_at: string;
55
62
  scored_at?: string;
56
63
  scores?: Record<string, number>;
64
+ /** Effective ambiguity after the deterministic floor clamp (`max(reported, floor)`). */
57
65
  ambiguity?: number;
66
+ /** Original LLM-reported ambiguity, preserved for audit when the floor clamped it. */
67
+ reported_ambiguity?: number;
68
+ /** Deterministic floor in effect when this round was scored, when it clamped. */
69
+ ambiguity_floor?: number;
58
70
  triggers?: DeepInterviewTriggerMetadata[];
59
71
  }
60
72
  export interface DeepInterviewStateEnvelope {
@@ -280,7 +280,8 @@ export declare function pruneTeamWorkerGcRecord(record: GcRecord, probe: GcPidPr
280
280
  export declare function persistGjcTeamModeStateSummary(snapshot: GjcTeamSnapshot, cwd?: string): Promise<void>;
281
281
  export declare function recoverGjcTeamStaleClaims(teamName: string, cwd?: string, env?: NodeJS.ProcessEnv): Promise<GjcTeamLivenessRecoveryResult>;
282
282
  type GjcTeamTaskMetadataInput = Partial<Pick<GjcTeamTask, "owner" | "lane" | "required_role" | "allowed_roles" | "depends_on" | "blocked_by">>;
283
- export declare function resolveGjcWorkerCommand(cwd?: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, argv?: string[], execPath?: string): string;
283
+ type CommandPathResolver = (command: string) => string | null;
284
+ export declare function resolveGjcWorkerCommand(cwd?: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, argv?: string[], execPath?: string, which?: CommandPathResolver): string;
284
285
  /** @internal Exported for unit tests. */
285
286
  export declare function buildWorkerCommand(config: GjcTeamConfig, worker: GjcTeamWorker, platform?: NodeJS.Platform): string;
286
287
  export type GjcWorkerCheckpointClassification = {
@@ -218,6 +218,7 @@ interface UltragoalChangeSet extends JsonObject {
218
218
  mergeBase?: string;
219
219
  paths: UltragoalChangeSetPath[];
220
220
  rawDiffStat?: string;
221
+ rawDiff?: string;
221
222
  trusted: true;
222
223
  }
223
224
  export declare function normalizeSurfaceToken(value: string): string;
@@ -18,6 +18,9 @@ export interface InteractiveModeNotify {
18
18
  message: string;
19
19
  }
20
20
  export declare function submitInteractiveInput(mode: Pick<InteractiveMode, "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested">, session: Pick<AgentSession, "prompt" | "promptCustomMessage">, input: SubmittedUserInput): Promise<void>;
21
+ type CreateSessionForMain = (options: CreateAgentSessionOptions, context?: {
22
+ skipPostCreateModelRefresh?: boolean;
23
+ }) => Promise<CreateAgentSessionResult>;
21
24
  type AcpSessionFactory = (cwd: string) => Promise<AgentSession>;
22
25
  export interface AcpSessionFactoryOptions {
23
26
  baseOptions: CreateAgentSessionOptions;
@@ -27,7 +30,7 @@ export interface AcpSessionFactoryOptions {
27
30
  modelRegistry: ModelRegistry;
28
31
  parsedArgs: Pick<Args, "apiKey" | "default" | "model" | "mpreset" | "thinking">;
29
32
  rawArgs: string[];
30
- createSession: (options: CreateAgentSessionOptions) => Promise<CreateAgentSessionResult>;
33
+ createSession: CreateSessionForMain;
31
34
  }
32
35
  export declare function applyStartupModelProfiles(args: {
33
36
  session: AgentSession;
@@ -10,6 +10,7 @@ export type ModelSelectorSelection = {
10
10
  kind: "assignment";
11
11
  model: Model;
12
12
  role: GjcModelAssignmentTargetId | null;
13
+ roles?: readonly GjcModelAssignmentTargetId[];
13
14
  thinkingLevel?: ThinkingLevel;
14
15
  selector?: string;
15
16
  } | {
@@ -56,6 +57,9 @@ export declare class ModelSelectorComponent extends Container {
56
57
  refreshPresetProfiles(profileName?: string): void;
57
58
  getSearchInput(): Input;
58
59
  __testSelectProfile(profileName: string, setDefault: boolean): Promise<void>;
60
+ __testSelectAssignment(selection: Omit<Extract<ModelSelectorSelection, {
61
+ kind: "assignment";
62
+ }>, "kind">): Promise<void>;
59
63
  __testSelectPresetAction(profileName: string, action: "rename" | "delete"): Promise<void>;
60
64
  __testSelectedPresetRowIdentity(): string | undefined;
61
65
  }
@@ -0,0 +1,12 @@
1
+ import { Container, SelectList } from "@gajae-code/tui";
2
+ import type { QueuedMessageEditEntry } from "../../session/agent-session";
3
+ type QueuedMessageMoveDirection = "up" | "down";
4
+ export type { QueuedMessageMoveDirection };
5
+ export declare class QueuedMessageSelectorComponent extends Container {
6
+ #private;
7
+ constructor(entries: QueuedMessageEditEntry[], onSelect: (entry: QueuedMessageEditEntry) => void, onDelete: (entry: QueuedMessageEditEntry, selectedIndex: number) => void, onMove: (entry: QueuedMessageEditEntry, selectedIndex: number, direction: QueuedMessageMoveDirection) => void, onCancel: () => void, options?: {
8
+ selectedIndex?: number;
9
+ });
10
+ handleInput(keyData: string): void;
11
+ getSelectList(): SelectList;
12
+ }
@@ -16,6 +16,8 @@ export interface SettingsRuntimeContext {
16
16
  thinkingLevel: ThinkingLevel | undefined;
17
17
  /** Available themes */
18
18
  availableThemes: string[];
19
+ /** Available model profile names (from the model registry) */
20
+ availableModelProfiles: string[];
19
21
  /** Working directory for plugins tab */
20
22
  cwd: string;
21
23
  }
@@ -14,9 +14,7 @@ export declare class InputController {
14
14
  handleFollowUp(): Promise<void>;
15
15
  /** Send editor text explicitly as a queued next-turn message. */
16
16
  handleQueueSubmit(): Promise<void>;
17
- restoreLatestQueuedMessageToEditor(options?: {
18
- currentText?: string;
19
- }): number;
17
+ restoreLatestQueuedMessageToEditor(): number;
20
18
  restoreQueuedMessagesToEditor(options?: {
21
19
  abort?: boolean;
22
20
  currentText?: string;