@gajae-code/coding-agent 0.7.9 → 0.7.11

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 (123) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +2 -0
  3. package/dist/types/config/keybindings.d.ts +11 -5
  4. package/dist/types/config/settings-schema.d.ts +10 -1
  5. package/dist/types/defaults/gjc-defaults.d.ts +7 -0
  6. package/dist/types/extensibility/extensions/types.d.ts +11 -0
  7. package/dist/types/gjc-runtime/launch-tmux.d.ts +10 -0
  8. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +3 -2
  9. package/dist/types/gjc-runtime/restricted-role-agent-bash.d.ts +1 -0
  10. package/dist/types/gjc-runtime/state-writer.d.ts +1 -0
  11. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -0
  12. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +0 -4
  13. package/dist/types/modes/components/custom-editor.d.ts +2 -1
  14. package/dist/types/modes/components/hook-selector.d.ts +5 -0
  15. package/dist/types/modes/components/skill-message.d.ts +1 -0
  16. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  17. package/dist/types/modes/controllers/input-controller.d.ts +4 -0
  18. package/dist/types/modes/interactive-mode.d.ts +1 -0
  19. package/dist/types/modes/prompt-action-autocomplete.d.ts +2 -0
  20. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +20 -6
  21. package/dist/types/modes/slash-command-visibility.d.ts +1 -0
  22. package/dist/types/modes/types.d.ts +1 -0
  23. package/dist/types/notifications/html-format.d.ts +2 -0
  24. package/dist/types/notifications/recent-activity.d.ts +5 -1
  25. package/dist/types/notifications/telegram-daemon-control.d.ts +8 -0
  26. package/dist/types/notifications/telegram-reference.d.ts +4 -0
  27. package/dist/types/notifications/threaded-render.d.ts +1 -0
  28. package/dist/types/sdk.d.ts +1 -1
  29. package/dist/types/session/agent-session.d.ts +8 -5
  30. package/dist/types/slash-commands/types.d.ts +2 -0
  31. package/dist/types/tools/ask.d.ts +2 -0
  32. package/dist/types/utils/cmux-workspace.d.ts +52 -0
  33. package/dist/types/web/search/index.d.ts +4 -2
  34. package/dist/types/web/search/provider.d.ts +14 -0
  35. package/dist/types/web/search/providers/utils.d.ts +42 -13
  36. package/dist/types/web/search/render.d.ts +1 -0
  37. package/package.json +7 -7
  38. package/src/cli/update-cli.ts +24 -0
  39. package/src/cli/web-search-cli.ts +5 -7
  40. package/src/cli.ts +1 -1
  41. package/src/commands/launch.ts +1 -1
  42. package/src/commands/ralplan.ts +1 -0
  43. package/src/config/keybindings.ts +14 -5
  44. package/src/config/model-profiles.ts +16 -0
  45. package/src/config/settings-schema.ts +11 -1
  46. package/src/coordinator-mcp/server.ts +9 -3
  47. package/src/defaults/gjc/skills/deep-interview/SKILL.md +26 -2
  48. package/src/defaults/gjc/skills/ralplan/SKILL.md +16 -14
  49. package/src/defaults/gjc/skills/ultragoal/SKILL.md +37 -112
  50. package/src/defaults/gjc-defaults.ts +16 -0
  51. package/src/extensibility/extensions/runner.ts +2 -1
  52. package/src/extensibility/extensions/types.ts +11 -0
  53. package/src/gjc-runtime/launch-tmux.ts +209 -26
  54. package/src/gjc-runtime/ralplan-runtime.ts +22 -6
  55. package/src/gjc-runtime/restricted-role-agent-bash.ts +1 -0
  56. package/src/gjc-runtime/state-runtime.ts +8 -5
  57. package/src/gjc-runtime/state-writer.ts +5 -5
  58. package/src/gjc-runtime/ultragoal-guard.ts +139 -19
  59. package/src/gjc-runtime/ultragoal-runtime.ts +16 -124
  60. package/src/gjc-runtime/workflow-manifest.generated.json +0 -8
  61. package/src/gjc-runtime/workflow-manifest.ts +0 -1
  62. package/src/hooks/skill-state.ts +33 -73
  63. package/src/internal-urls/docs-index.generated.ts +6 -4
  64. package/src/main.ts +2 -2
  65. package/src/migrate/executor.ts +23 -6
  66. package/src/modes/components/custom-editor.ts +8 -0
  67. package/src/modes/components/hook-selector.ts +21 -3
  68. package/src/modes/components/model-selector.ts +6 -2
  69. package/src/modes/components/settings-selector.ts +47 -5
  70. package/src/modes/components/skill-message.ts +18 -10
  71. package/src/modes/components/status-line/presets.ts +11 -0
  72. package/src/modes/controllers/command-controller.ts +23 -0
  73. package/src/modes/controllers/extension-ui-controller.ts +18 -2
  74. package/src/modes/controllers/input-controller.ts +41 -9
  75. package/src/modes/interactive-mode.ts +16 -7
  76. package/src/modes/prompt-action-autocomplete.ts +23 -1
  77. package/src/modes/shared/agent-wire/deep-interview-gate.ts +53 -9
  78. package/src/modes/slash-command-visibility.ts +9 -0
  79. package/src/modes/types.ts +1 -0
  80. package/src/modes/utils/hotkeys-markdown.ts +5 -2
  81. package/src/modes/utils/ui-helpers.ts +76 -3
  82. package/src/notifications/html-format.ts +75 -1
  83. package/src/notifications/index.ts +12 -1
  84. package/src/notifications/recent-activity.ts +32 -8
  85. package/src/notifications/telegram-daemon-control.ts +9 -0
  86. package/src/notifications/telegram-daemon.ts +68 -25
  87. package/src/notifications/telegram-reference.ts +36 -14
  88. package/src/notifications/threaded-render.ts +14 -6
  89. package/src/prompts/agents/architect.md +7 -4
  90. package/src/prompts/agents/critic.md +15 -6
  91. package/src/prompts/agents/planner.md +8 -3
  92. package/src/prompts/system/system-prompt.md +5 -1
  93. package/src/prompts/tools/bash.md +1 -1
  94. package/src/sdk.ts +6 -11
  95. package/src/session/agent-session.ts +60 -17
  96. package/src/slash-commands/builtin-registry.ts +30 -10
  97. package/src/slash-commands/types.ts +2 -0
  98. package/src/tools/ask.ts +136 -16
  99. package/src/tools/bash.ts +24 -8
  100. package/src/utils/cmux-workspace.ts +233 -0
  101. package/src/utils/title-generator.ts +2 -0
  102. package/src/web/kagi.ts +1 -1
  103. package/src/web/parallel.ts +2 -2
  104. package/src/web/search/index.ts +137 -52
  105. package/src/web/search/provider.ts +80 -0
  106. package/src/web/search/providers/anthropic.ts +1 -1
  107. package/src/web/search/providers/brave.ts +1 -1
  108. package/src/web/search/providers/codex.ts +1 -1
  109. package/src/web/search/providers/duckduckgo.ts +1 -1
  110. package/src/web/search/providers/exa.ts +1 -1
  111. package/src/web/search/providers/gemini.ts +7 -3
  112. package/src/web/search/providers/jina.ts +1 -1
  113. package/src/web/search/providers/kimi.ts +6 -1
  114. package/src/web/search/providers/openai-compatible.ts +1 -1
  115. package/src/web/search/providers/parallel.ts +1 -1
  116. package/src/web/search/providers/perplexity.ts +2 -2
  117. package/src/web/search/providers/searxng.ts +1 -1
  118. package/src/web/search/providers/synthetic.ts +1 -1
  119. package/src/web/search/providers/tavily.ts +1 -1
  120. package/src/web/search/providers/utils.ts +67 -17
  121. package/src/web/search/providers/xai.ts +1 -1
  122. package/src/web/search/providers/zai.ts +1 -1
  123. package/src/web/search/render.ts +3 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,53 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.7.11] - 2026-07-03
6
+ ### Fixed
7
+
8
+ - Native Windows terminals now default `app.message.queue` to `Alt+Q` instead of `Alt+Enter`, avoiding the Windows Terminal fullscreen shortcut conflict (#1422).
9
+ - Coordinator MCP tmux prompt delivery now submits with tmux `Enter` instead of `C-m`, while preserving runtime prompt-ack/`turn_start` as the delivery success gate (#1409).
10
+ - The session-close resume hint now prints the `gjc --resume <id>` command on its own line so it can be selected and copied without the surrounding prose.
11
+ - Coordinator MCP tmux prompt delivery now uses a paste buffer for prompt text before submitting with `Enter`, preserving multiline delegated `/skill:*` prompt separators that `send-keys -l` could flatten into an unstarted visible prompt (#1416).
12
+
13
+ - `/retry` now resumes sessions left with an interrupted user/custom/tool-result tail after a crash or power loss, and recovers unresolved assistant tool-use tails instead of reporting "Nothing to retry".
14
+ - Queued prompt shortcuts now keep working during auto context-full compaction: Tab/Alt+Enter queue text immediately, `/skill:*` entries replay through the skill invocation path after compaction, and Alt+Up restores only the newest queued prompt for editing instead of merging the full queue.
15
+ - Skill prompt cards now size their collapsed arguments preview to the current terminal width instead of wrapping at a fixed narrow column.
16
+ - `gjc update` now refreshes opted-in on-disk default workflow skill copies (written by `gjc setup defaults` under the agent dir) after a successful update, so they no longer stay stale relative to the embedded defaults; copies that were never installed are left absent.
17
+ - `gjc migrate` skill imports now tolerate project or agent directories reached through macOS system symlinks such as `/var` while still rejecting symlinked destination skill directories, so local dry-run/live parity tests no longer fail on Darwin temp paths.
18
+ - cmux workspace auto-renames now include a `GJC: ` prefix so renamed workspaces remain identifiable as GJC sessions.
19
+ - The cmux workspace auto-rename is now ownership-guarded: GJC reads the current workspace title via `cmux workspace list` and only renames a workspace that still has its default title, so it no longer overwrites a user-pinned workspace name or thrash a shared workspace title across multiple sessions running under the same `CMUX_WORKSPACE_ID`. Opt out with `GJC_NO_CMUX_RENAME`.
20
+ - `gjc --tmux --resume` now reaches the session picker/resume target instead of auto-attaching a same-branch managed tmux session before the inner resume resolver runs.
21
+ - `gjc --tmux` now preserves a newly created managed tmux session when `attach-session` exits after the parent SSH/PTY closes but the tmux server still reports the session live, so closing a Windows Terminal tab no longer kills the Mac host session before reattach.
22
+ - Managed `gjc --tmux` launches now size the inner tmux window to the caller terminal minus inherited tmux status lines, preventing the bottom of the GJC input from being clipped when the user's tmux status bar is visible.
23
+ - Managed `gjc --tmux` launches no longer pin the initial window to `manual` sizing on native tmux. The pre-attach reassert used `resize-window`, which flips the window's `window-size` option to `manual` and stops `attach-session` from resizing the window to the real terminal; when the attaching terminal was larger than the capture-time size, tmux left a smaller-than-client window and painted the uncovered area with `·` fill. The window now stays on `window-size latest` so it tracks the attaching client (psmux keeps the explicit `resize-window` reassert).
24
+
25
+ ### Changed
26
+
27
+ - `web_search` latency overhaul: provider hard timeouts are now class-based (pure search APIs 15s, LLM-mediated providers 120s, Kimi 35s aligned to its upstream 30s budget, replacing the uniform 300s ceiling; an explicitly configured `web_search.timeout` still overrides — the schema default no longer reinstalls 300s), DuckDuckGo is fired as a background hedge 3s into a slower primary so a failing primary falls back to an already-settled result, the Gemini 429/5xx retry-delay budget dropped from 5 minutes to 30 seconds, resolved provider chains are cached per AuthStorage for 60s keyed on the credential generation (availability probes skipped on repeat searches; login/logout invalidates immediately), and `WebSearchTool` prewarms the chain at construction. Measured: hung-primary fallback 301s → 15s, slow-failing-primary fallback ~7s → 6s, repeat chain resolution ~26ms → ~0.01ms.
28
+
29
+ ## [0.7.10] - 2026-07-02
30
+ ### Added
31
+
32
+ - GJC now best-effort renames the containing cmux workspace to the current GJC session name when running inside a cmux terminal.
33
+ - Added a status line default usage preset (#1305).
34
+ - Telegram threaded updates now include verbose session identity (session id and cwd) metadata.
35
+
36
+ ### Fixed
37
+
38
+ - 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.
39
+ - `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.
40
+ - Ralplan role agents can now persist Planner/Architect/Critic artifacts through a sanctioned `GJC_RALPLAN_ARTIFACT` env handoff (`--artifact-env GJC_RALPLAN_ARTIFACT`), avoiding restricted-bash failures on markdown containing quotes, backslashes, shell-expansion characters, or command-substitution syntax.
41
+ - Managed `gjc --tmux` launches now size the initial window correctly (#1376).
42
+ - Coordinator tmux-delivered turns now submit correctly on Enter (#1372).
43
+ - Generic long `retry-after` rate limits are now kept retryable instead of being treated as fatal (#1370).
44
+ - Anthropic hard 429 responses are now surfaced before the stream watchdog fires (#1369).
45
+ - Internal sessions are now hidden from the Telegram recent-session list (#1367).
46
+ - Telegram messages exceeding the length limit are now chunked correctly.
47
+ - Web search now falls back correctly when the preferred provider is unavailable (#1348).
48
+ - Restored the Ultragoal team checkpoint snapshot wording (#1349).
49
+ - Deep Interview now exits early for simple tasks instead of running unnecessary rounds (#1311).
50
+ - Ultragoal goal identity and state now resolve solely from the canonical session-scoped `goals.json`, eliminating goal-identity drift from transcript-replayed snapshots (#1344).
51
+
5
52
  ## [0.7.9] - 2026-07-01
6
53
  ### Added
7
54
 
package/README.md CHANGED
@@ -24,6 +24,8 @@ 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 runs inside a cmux terminal (`CMUX_WORKSPACE_ID` is set), GJC best-effort renames that cmux workspace to the current GJC session name (with a `GJC: ` prefix) — but only when the workspace still has its default title, so a name you pinned (or one set by a peer session sharing the workspace) is never overwritten. Opt out with `GJC_NO_CMUX_RENAME=1`.
28
+
27
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:
28
30
 
29
31
  ```powershell
@@ -10,6 +10,7 @@ interface AppKeybindings {
10
10
  "app.suspend": true;
11
11
  "app.thinking.cycle": true;
12
12
  "app.thinking.toggle": true;
13
+ "app.commandPalette.open": true;
13
14
  "app.model.cycleForward": true;
14
15
  "app.model.cycleBackward": true;
15
16
  "app.model.select": true;
@@ -45,6 +46,7 @@ declare module "@gajae-code/tui" {
45
46
  interface Keybindings extends AppKeybindings {
46
47
  }
47
48
  }
49
+ export declare function defaultMessageQueueKeysForPlatform(platform?: NodeJS.Platform): KeyId;
48
50
  /**
49
51
  * All keybindings definitions: TUI + app-specific.
50
52
  */
@@ -201,12 +203,16 @@ export declare const KEYBINDINGS: {
201
203
  readonly defaultKeys: "ctrl+t";
202
204
  readonly description: "Toggle thinking mode";
203
205
  };
204
- readonly "app.model.cycleForward": {
206
+ readonly "app.commandPalette.open": {
205
207
  readonly defaultKeys: "ctrl+p";
208
+ readonly description: "Open command palette";
209
+ };
210
+ readonly "app.model.cycleForward": {
211
+ readonly defaultKeys: "alt+n";
206
212
  readonly description: "Cycle to next model";
207
213
  };
208
214
  readonly "app.model.cycleBackward": {
209
- readonly defaultKeys: "shift+ctrl+p";
215
+ readonly defaultKeys: "alt+shift+n";
210
216
  readonly description: "Cycle to previous model";
211
217
  };
212
218
  readonly "app.model.select": {
@@ -234,7 +240,7 @@ export declare const KEYBINDINGS: {
234
240
  readonly description: "Send follow-up message (no default; Ctrl+Enter submits)";
235
241
  };
236
242
  readonly "app.message.queue": {
237
- readonly defaultKeys: "alt+enter";
243
+ readonly defaultKeys: KeyId;
238
244
  readonly description: "Queue message for next turn";
239
245
  };
240
246
  readonly "app.message.dequeue": {
@@ -254,8 +260,8 @@ export declare const KEYBINDINGS: {
254
260
  readonly description: "Copy prompt";
255
261
  };
256
262
  readonly "app.session.new": {
257
- readonly defaultKeys: [];
258
- readonly description: "Create new session";
263
+ readonly defaultKeys: "ctrl+n";
264
+ readonly description: "Start a new session";
259
265
  };
260
266
  readonly "app.session.tree": {
261
267
  readonly defaultKeys: [];
@@ -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";
@@ -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[];
@@ -27,6 +27,13 @@ export type DefaultGjcDefinition = DefaultGjcSkillDefinition | DefaultGjcSkillFr
27
27
  export interface InstallDefaultGjcDefinitionsOptions {
28
28
  check?: boolean;
29
29
  force?: boolean;
30
+ /**
31
+ * Only rewrite default definition files that already exist on disk but whose
32
+ * content differs from the embedded defaults. Files that are absent are left
33
+ * absent (status "missing"). Used by `gjc update` to refresh opted-in copies
34
+ * without materializing new on-disk copies for users who never installed them.
35
+ */
36
+ refreshOnly?: boolean;
30
37
  targetRoot?: string;
31
38
  }
32
39
  export type DefaultGjcDefinitionInstallFile = {
@@ -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;
@@ -20,6 +22,7 @@ export interface TmuxLaunchContext {
20
22
  tty?: TtyState;
21
23
  spawnSync?: TmuxSpawnSync;
22
24
  tmuxAvailable?: boolean;
25
+ tmuxStatusLines?: number;
23
26
  worktreeBranch?: string | null;
24
27
  currentBranch?: string | null;
25
28
  existingBranchSessionName?: string | null;
@@ -31,6 +34,10 @@ export interface TmuxSpawnResult {
31
34
  signalCode?: string | null;
32
35
  stderr?: string;
33
36
  }
37
+ export interface TmuxTerminalSize {
38
+ columns: number;
39
+ rows: number;
40
+ }
34
41
  export type TmuxSpawnSync = (command: string, args: string[], options: TmuxSpawnOptions) => TmuxSpawnResult;
35
42
  export interface TmuxSpawnOptions {
36
43
  cwd: string;
@@ -54,11 +61,14 @@ export interface TmuxLaunchPlan {
54
61
  cwd: string;
55
62
  innerCommand: string;
56
63
  newSessionArgs: string[];
64
+ initialSize?: TmuxTerminalSize;
57
65
  branch?: string | null;
58
66
  attachSessionName?: string;
59
67
  project?: string | null;
60
68
  sessionId?: string | null;
61
69
  sessionStateFile?: string | null;
70
+ isPsmux: boolean;
71
+ platform: NodeJS.Platform;
62
72
  }
63
73
  export interface GjcTmuxProfileResult {
64
74
  skipped: boolean;
@@ -10,8 +10,9 @@
10
10
  * that lives in the bundled `/skill:ralplan` skill — but it accepts every documented flag so
11
11
  * scripted users see a useful response and the active run is visible to the TUI.
12
12
  *
13
- * 2. **Artifact write**: `gjc ralplan --write --stage <type> --stage_n <N> --artifact
14
- * <path-or-string> [--run-id <id>] [--session-id <id>] [--json]` persists Planner / Architect
13
+ * 2. **Artifact write**: `gjc ralplan --write --stage <type> --stage_n <N>
14
+ * (--artifact <path-or-string> | --artifact-env GJC_RALPLAN_ARTIFACT)
15
+ * [--run-id <id>] [--session-id <id>] [--json]` persists Planner / Architect
15
16
  * / Critic / revision / post-interview / ADR / final markdown under `.gjc/plans/ralplan/<run-id>/`, maintains
16
17
  * an `index.jsonl` audit log, copies `final` stages to `pending-approval.md`, and advances
17
18
  * the HUD chip to reflect the latest persisted stage.
@@ -1,2 +1,3 @@
1
1
  export declare const GJC_RESTRICTED_ROLE_AGENT_BASH_ENV = "GJC_RESTRICTED_ROLE_AGENT_BASH";
2
+ export declare const GJC_RALPLAN_ARTIFACT_ENV = "GJC_RALPLAN_ARTIFACT";
2
3
  export declare function isRestrictedRoleAgentBash(): boolean;
@@ -67,6 +67,7 @@ export type GuardedWriteResult = {
67
67
  path: string;
68
68
  written: true;
69
69
  revision: number;
70
+ stamped: unknown;
70
71
  } | {
71
72
  path: string;
72
73
  written: false;
@@ -29,6 +29,10 @@ export declare function readUltragoalVerificationState(input: {
29
29
  currentGoal?: CurrentGoalLike | null;
30
30
  sessionId?: string | null;
31
31
  }): Promise<UltragoalGuardDiagnostic>;
32
+ export declare function verifyUltragoalDurableCompletionState(input: {
33
+ cwd: string;
34
+ sessionId?: string | null;
35
+ }): Promise<UltragoalGuardDiagnostic>;
32
36
  export declare function isUltragoalAskBlocked(cwd: string, options?: {
33
37
  sessionId?: string | null;
34
38
  }): Promise<UltragoalAskBlockDiagnostic>;
@@ -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
  /**
@@ -1,6 +1,6 @@
1
1
  import { Editor, type KeyId } from "@gajae-code/tui";
2
2
  import { type AppKeybinding } from "../../config/keybindings";
3
- type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.message.followUp" | "app.message.queue" | "app.clipboard.pasteImage" | "app.clipboard.copyPrompt">;
3
+ type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.thinking.cycle" | "app.commandPalette.open" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.message.followUp" | "app.message.queue" | "app.clipboard.pasteImage" | "app.clipboard.copyPrompt">;
4
4
  type PastePendingClearReason = "timeout" | "queue-limit";
5
5
  /**
6
6
  * Custom editor that handles configurable app-level shortcuts for coding-agent.
@@ -19,6 +19,7 @@ export declare class CustomEditor extends Editor {
19
19
  onClear?: () => void;
20
20
  onExit?: () => void;
21
21
  onCycleThinkingLevel?: () => void;
22
+ onOpenCommandPalette?: () => void;
22
23
  onCycleModelForward?: () => void;
23
24
  onCycleModelBackward?: () => void;
24
25
  onSelectModel?: () => void;
@@ -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 `/`
@@ -6,4 +6,5 @@ export declare class SkillMessageComponent extends Container {
6
6
  constructor(message: CustomMessage<SkillPromptDetails>);
7
7
  setExpanded(expanded: boolean): void;
8
8
  invalidate(): void;
9
+ render(width: number): string[];
9
10
  }
@@ -18,6 +18,7 @@ export declare class CommandController {
18
18
  handleUsageCommand(reports?: UsageReport[] | null): Promise<void>;
19
19
  handleChangelogCommand(showFull?: boolean): Promise<void>;
20
20
  handleHotkeysCommand(): void;
21
+ handleHelpCommand(): void;
21
22
  handleToolsCommand(): void;
22
23
  handleContextCommand(): void;
23
24
  handleMemoryCommand(text: string): Promise<void>;
@@ -14,6 +14,9 @@ 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
20
  restoreQueuedMessagesToEditor(options?: {
18
21
  abort?: boolean;
19
22
  currentText?: string;
@@ -27,6 +30,7 @@ export declare class InputController {
27
30
  handleCopyCurrentLine(): void;
28
31
  /** Copy current prompt text to system clipboard. */
29
32
  handleCopyPrompt(): void;
33
+ openCommandPalette(): void;
30
34
  cycleThinkingLevel(): void;
31
35
  cycleRoleModel(options?: {
32
36
  temporary?: boolean;
@@ -184,6 +184,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
184
184
  handleUsageCommand(reports?: UsageReport[] | null): Promise<void>;
185
185
  handleChangelogCommand(showFull?: boolean): Promise<void>;
186
186
  handleHotkeysCommand(): void;
187
+ handleHelpCommand(): void;
187
188
  handleToolsCommand(): void;
188
189
  handleContextCommand(): void;
189
190
  handleClearCommand(): Promise<void>;
@@ -14,6 +14,8 @@ interface PromptActionAutocompleteOptions {
14
14
  copyCurrentLine: () => void;
15
15
  copyPrompt: () => void;
16
16
  pasteImage: () => void;
17
+ newSession: () => void;
18
+ showHelp: () => void;
17
19
  scrollTmuxToPreviousUserInput: () => void;
18
20
  undo: (prefix: string) => void;
19
21
  moveCursorToMessageEnd: () => void;
@@ -50,6 +50,7 @@ export interface AskGateResult {
50
50
  multi: boolean;
51
51
  selectedOptions: string[];
52
52
  customInput?: string;
53
+ clarificationQuestion?: string;
53
54
  }
54
55
  /**
55
56
  * The answer shape an agent returns for a deep-interview question gate.
@@ -57,15 +58,28 @@ export interface AskGateResult {
57
58
  * `selected` are picked option labels; free text is conveyed by `other: true`
58
59
  * plus `custom`, encoded separately from `selected` so a real option whose label
59
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.
60
65
  */
61
- export interface DeepInterviewGateAnswer {
66
+ export type DeepInterviewGateAnswer = {
62
67
  selected: string[];
63
- other?: boolean;
64
- custom?: string;
65
- }
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
+ };
66
80
  export declare class DeepInterviewGateError extends Error {
67
- readonly code: "invalid_answer_shape" | "unknown_option" | "multi_not_allowed" | "missing_custom" | "empty_selection" | "duplicate_selection";
68
- 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);
69
83
  }
70
84
  /** Build the `workflow_gate` open-input for one ask question. */
71
85
  export declare function questionToGate(question: AskGateQuestion): OpenGateInput;
@@ -0,0 +1 @@
1
+ export declare function shouldShowExtensionCommand(name: string, activeProvider: string | undefined): boolean;
@@ -191,6 +191,7 @@ export interface InteractiveModeContext {
191
191
  handleUsageCommand(reports?: UsageReport[] | null): Promise<void>;
192
192
  handleChangelogCommand(showFull?: boolean): Promise<void>;
193
193
  handleHotkeysCommand(): void;
194
+ handleHelpCommand(): void;
194
195
  handleToolsCommand(): void;
195
196
  handleContextCommand(): void;
196
197
  handleDumpCommand(): void;
@@ -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
- readFirstLine?: (file: string) => string | undefined;
30
+ readInitialLines?: (file: string, maxLines: number) => string[];
27
31
  }
28
32
  /**
29
33
  * List recent sessions ranked by history-file mtime (newest first).
@@ -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;
@@ -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 {};
@@ -42,6 +42,7 @@ interface ThreadedFrame {
42
42
  tokenUsage?: unknown;
43
43
  model?: unknown;
44
44
  diff?: unknown;
45
+ cwd?: unknown;
45
46
  phase?: unknown;
46
47
  text?: unknown;
47
48
  messageRef?: unknown;
@@ -47,7 +47,7 @@ export interface CreateAgentSessionOptions {
47
47
  requestedModel: Model;
48
48
  reason: string;
49
49
  };
50
- /** Models available for cycling (Ctrl+P in interactive mode) */
50
+ /** Models available for cycling (Alt+N in interactive mode) */
51
51
  scopedModels?: ScopedModelSelection[];
52
52
  /** System prompt blocks. Array replaces default, function receives default blocks and returns final blocks. */
53
53
  systemPrompt?: string[] | ((defaultPrompt: string[]) => string[]);
@@ -159,7 +159,7 @@ export interface AgentSessionConfig {
159
159
  agent: Agent;
160
160
  sessionManager: SessionManager;
161
161
  settings: Settings;
162
- /** Models to cycle through with Ctrl+P (from --models flag) */
162
+ /** Models to cycle through with Alt+N (from --models flag) */
163
163
  scopedModels?: ScopedModelSelection[];
164
164
  /** Initial session thinking selector. */
165
165
  thinkingLevel?: ThinkingLevel;
@@ -671,7 +671,7 @@ export declare class AgentSession {
671
671
  followUp: readonly string[];
672
672
  };
673
673
  /**
674
- * Pop the last queued message (steering first, then follow-up).
674
+ * Pop the newest queued message across steering and follow-up queues.
675
675
  * Used by dequeue keybinding to restore messages to editor one at a time.
676
676
  * Returns the popped entry's `.text`; the tag (if any) dies with the
677
677
  * record — no orphan state can outlive the queue entry.
@@ -905,9 +905,12 @@ export declare class AgentSession {
905
905
  */
906
906
  setAutoRetryEnabled(enabled: boolean): void;
907
907
  /**
908
- * Manually retry the last failed assistant turn.
909
- * Removes the error message from agent state and re-attempts with a fresh retry budget.
910
- * @returns true if retry was initiated, false if no failed turn to retry or agent is busy
908
+ * Manually retry the last failed assistant turn, or resume an interrupted tail
909
+ * left by a non-graceful process exit after the user/custom/tool-result message
910
+ * was persisted but before the agent emitted a terminal assistant response.
911
+ * Removes failed/aborted/unresolved tool-use assistant tails before
912
+ * re-attempting with a fresh retry budget.
913
+ * @returns true if retry/resume was initiated, false if no retryable tail exists or agent is busy
911
914
  */
912
915
  retry(): Promise<boolean>;
913
916
  /**
@@ -17,6 +17,8 @@ export interface BuiltinSlashCommand {
17
17
  subcommands?: SubcommandDef[];
18
18
  /** Static inline hint when command takes a simple argument (no subcommands). */
19
19
  inlineHint?: string;
20
+ /** Higher values sort earlier in TUI slash-command autocomplete. */
21
+ priority?: number;
20
22
  }
21
23
  /** Parsed slash-command text after stripping the leading "/". */
22
24
  export interface ParsedSlashCommand {
@@ -59,6 +59,7 @@ export interface QuestionResult {
59
59
  multi: boolean;
60
60
  selectedOptions: string[];
61
61
  customInput?: string;
62
+ clarificationQuestion?: string;
62
63
  }
63
64
  export interface AskToolDetails {
64
65
  question?: string;
@@ -66,6 +67,7 @@ export interface AskToolDetails {
66
67
  multi?: boolean;
67
68
  selectedOptions?: string[];
68
69
  customInput?: string;
70
+ clarificationQuestion?: string;
69
71
  /** Multi-part question mode */
70
72
  results?: QuestionResult[];
71
73
  }