@gajae-code/coding-agent 0.13.1 → 0.13.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.13.2] - 2026-08-13
6
+
7
+ ### Added
8
+ - `/theme <name>` now switches the theme immediately without opening the selector: the name is validated against built-in and custom themes, persisted to the detected `theme.dark`/`theme.light` slot, and applied to the running session in one step. Bare `/theme` keeps the existing live-preview selector, and an unknown name is rejected with the list of available themes.
9
+
10
+ ### Fixed
11
+ - The Telegram notification daemon now contains transient Windows state or ownership-lock read failures during steady heartbeat renewal instead of terminating its run loop. Staging files are cleaned in a `finally` block, and only a proven ownership mismatch stops the owner (#4200).
12
+ - Coordinator MCP now answers the standard `ping` keepalive with an empty result instead of `method not found`, preventing liveness clients from reconnecting repeatedly.
13
+ - Task-launched canonical subagents no longer receive an ACP exact-config `toolsOnly` MCP manager that they are forbidden to reuse. Planner, Architect, Critic, and Ralplan consensus lanes now start normally while reusable plugin MCP managers continue to inherit across sub-sessions.
14
+ - Managed output publication no longer freezes the resident event loop when a no-replace rename stalls in the kernel (#4394). Async managed publication now uses async file operations and native blocking-pool rename/link boundaries, while per-session stores also reap scrubbed protocol remnants on a throttled, serialized schedule. Atomic no-replace semantics and the synchronous publication path are unchanged.
15
+ - The SDK broker's Windows process-liveness probe no longer opens a console window on every poll. `runProcessIncarnationCommand` spawned `powershell.exe` without `windowsHide`, and on Windows 11 — where the default terminal delegation hands every new console to Windows Terminal — each probe therefore created a visible terminal window that stole focus. The PowerShell path runs whenever the native reader cannot bind the target pid, so one dead or inaccessible pid turned the broker's ~2s liveness polling into a continuous window flash for the life of the process. Every other internal spawn in the repo already passed `windowsHide: true`; this one did not.
16
+ - Foreground Bash calls that finish before their auto-background deadline now cancel that deadline instead of leaving an uncancellable `Bun.sleep()` behind. In print mode the losing sleep kept the compiled CLI alive for the full command timeout after Bash and subagent work had already completed, which appeared as a shutdown hang with no active Node handles.
17
+ - Prompt suggestions now remain visible after cancelling another interactive action and returning to the composer.
5
18
  ## [0.13.1] - 2026-08-11
6
19
 
7
20
  ### Added
@@ -12,6 +25,7 @@
12
25
  - Custom OpenAI-compatible providers can opt into `/fast` forwarding with `compat.supportsServiceTier: true`; first-class OpenCodex discovery enables it automatically so client `service_tier: "priority"` reaches an OpenCodex proxy running in passthrough (`Auto`) mode.
13
26
 
14
27
  ### Fixed
28
+ - Foreground Bash calls that finish before their auto-background deadline now cancel that deadline instead of leaving an uncancellable `Bun.sleep()` behind. In print mode the losing sleep kept the compiled CLI alive for the full command timeout after Bash and subagent work had already completed, which appeared as a shutdown hang with no active Node handles.
15
29
  - A just-created or just-registered SDK session no longer reads as not-live (failing immediate `session.close`/`session.delete`, endpoint resolution, and chat-daemon attachment) for up to one heartbeat interval: the host-written registration now counts as initial liveness evidence, aging out exactly like a heartbeat, with the OS process-incarnation match still required. The broker's shutdown-escalation identity proof also accepts the incarnation the index auto-stamps at registration, and ACP `session/list` no longer advertises or re-adopts closed/unregistered (DR-1 terminal) rows — repeated ACP deletes answer already-gone instead of escalating against a host that no longer exists.
16
30
  - Insane public-route search now cancels and rejects response bodies larger than 1 MiB instead of buffering unbounded feed, HTML, or JSON payloads.
17
31
  - The Telegram notification daemon no longer terminates with an uncaught `EPERM` when publishing its heartbeat sidecar while an external Windows file lock (antivirus, indexer) briefly holds the destination. The rename is retried a bounded number of times under the ownership-lock fence, a still-failing publication is contained as a diagnostic-logged transient (the next heartbeat cycle republishes), and only a proven ownership loss stops the daemon; the stale-writer fence and staging-temp cleanup are preserved on every path (#4200).
@@ -132,6 +146,8 @@
132
146
  - Profile activation/materialization, memory maintenance, interactive selectors, slash-command assignment, model-profile previews, and SDK extension contexts now use the same explicit credential identity as request dispatch; canonical session IDs remain reserved for sticky routing and provider transport/cache identities remain isolated.
133
147
  - Task subagents and branch commit-message generation now inherit the parent's credential identity separately from logical/canonical state. Extension model preflight, custom tools (including image generation and web search), title/prompt maintenance, background ephemeral metadata, and profile materialization use the same credential scope. Preset landing auth now requires usable effective credentials rather than catalog presence alone.
134
148
  - SDK tool sessions, deferred SDK selectors, slash-command aliases, memory role resolution, and provider-order status now carry credential identity. Provider alias invalidation updates canonical storage/backoff/session state, and preset landing availability is derived from actual credential-scoped `getApiKey` results (including keyless providers) rather than credential-type metadata.
149
+ - Prompt suggestions now remain visible after cancelling another interactive action and returning to the composer.
150
+
135
151
  - `todo_write` and `ask` no longer reject valid calls before the tool loads. Both tools carried two independent copies of their raw-argument rules — one in the loaded tool, one in the cold descriptor registry that runs first — and the deferred copies had drifted: `todo_write`'s dropped the `content` synonym for `task` and the `complete`/`completed` aliases for `done`, accepted targetless `complete` entries the loaded tool rejects, and returned every rejection without its correction code, so the model saw a bare "raw arguments rejected before coercion" with nothing to fix and retried the same shape until the turn died. Both also rejected the harness's own injected `_i` intent field, failing any call carrying it with an unknown-root-key error the model could not repair. `todo_write` validation now lives in a single shared contract module (`tools/todo-contract.ts`) used by both paths, and both tools tolerate `_i` at the root while still rejecting genuinely unknown keys.
136
152
  - A stalled ACP session is no longer unrecoverable. The SDK host drops a session whose client has not ponged within `HEARTBEAT_TTL_MS` (20s), but the ACP client inherited the transport's one-shot reconnect defaults — 3 attempts at a 25ms base backoff, a total budget of 175ms — so any event-loop stall long enough for the host to reap the session exceeded the client's entire retry window by two orders of magnitude and surfaced as a terminal `-32603 ACP session transport was lost: SDK WebSocket reconnect attempts exhausted`. Under machine load this killed long-running agent sessions outright while their processes stayed alive. The ACP adapter and the broker connection now share an explicit `ACP_SESSION_RECONNECT` budget derived from `HEARTBEAT_TTL_MS` rather than a magic number: backoff ramps 250ms → 500ms → 1s and holds at a 2s cap for 23 attempts (~41.75s), so the client outlives twice the host TTL while individual sleeps stay short enough to reattach promptly once the host answers again.
137
153
  - Managed scope prepare and legacy-local resume no longer report success while group/other-readable descendants remain on disk (e.g. mode `0o036`/`0o644`): prepare uses a mode-only walk (not `snapshotManagedTree("")`, which races concurrent writers and broke `/move`) to detect drift, re-secures with apply+verify, and retries once; legacy-local capture uses the same resecure helper.
@@ -103,8 +103,10 @@ export declare const NOTIFICATION_PROTOCOL_VERSION = 3;
103
103
  * settles non-forum close responses. Generation 62 rejects replay-gap
104
104
  * authority claims that do not match the requested cursor, answer bounds,
105
105
  * and retained replay suffix.
106
+ * Generation 63 contains transient steady-heartbeat state and ownership-lock
107
+ * read failures and cleans every staged sidecar before retrying (#4200).
106
108
  */
107
- export declare const DAEMON_GENERATION = 62;
109
+ export declare const DAEMON_GENERATION = 63;
108
110
  /**
109
111
  * Serving-compatibility boundary for daemon lifecycle requests. Epoch 5
110
112
  * requires the complete generation-36 topic authority contract, so older
@@ -87,6 +87,10 @@ export interface ManagedBoundedAppendExpectation {
87
87
  readonly ctimeNs: string;
88
88
  readonly sha256: string;
89
89
  }
90
+ export interface ScrubbedProtocolRemnantReapResult {
91
+ readonly reaped: number;
92
+ readonly failures: number;
93
+ }
90
94
  /**
91
95
  * Best-effort removal of scrubbed write-protocol remnants from one managed
92
96
  * directory. Only zero-length, single-link, non-symlink regular files whose
@@ -98,6 +102,15 @@ export interface ManagedBoundedAppendExpectation {
98
102
  * have reconciled any candidate.
99
103
  */
100
104
  export declare function reapScrubbedProtocolRemnantsSync(directory: string, minAgeMs?: number): number;
105
+ /**
106
+ * Async twin of {@link reapScrubbedProtocolRemnantsSync} with the same safety
107
+ * filters (terminal remnant prefix, zero-length, single-link, non-symlink,
108
+ * older than the age gate), yielding between bounded batches. Long-lived
109
+ * processes reap per-session descendant directories through this path so a
110
+ * legacy oversized directory cannot starve timers or sibling subagents while
111
+ * it is being drained (issue #4394).
112
+ */
113
+ export declare function reapScrubbedProtocolRemnants(directory: string, minAgeMs?: number): Promise<ScrubbedProtocolRemnantReapResult>;
101
114
  export declare function validateNativeSecurityResult(value: unknown, operation: "apply" | "verify", kind: "directory" | "file"): NativeOwnerOnlySecurityResult;
102
115
  export interface ManagedLockRetirementTestEvent {
103
116
  readonly path: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/coding-agent",
4
- "version": "0.13.1",
4
+ "version": "0.13.2",
5
5
  "description": "Gajae Code CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://gajae-code.com",
7
7
  "author": "Yeachan-Heo and Gajae Code Contributors",
@@ -54,13 +54,13 @@
54
54
  "@agentclientprotocol/sdk": "1.3.0",
55
55
  "@babel/parser": "^7.29.3",
56
56
  "@mozilla/readability": "^0.6.0",
57
- "@gajae-code/stats": "0.13.1",
58
- "@gajae-code/agent-core": "0.13.1",
59
- "@gajae-code/ai": "0.13.1",
60
- "@gajae-code/bridge-client": "0.13.1",
61
- "@gajae-code/natives": "0.13.1",
62
- "@gajae-code/tui": "0.13.1",
63
- "@gajae-code/utils": "0.13.1",
57
+ "@gajae-code/stats": "0.13.2",
58
+ "@gajae-code/agent-core": "0.13.2",
59
+ "@gajae-code/ai": "0.13.2",
60
+ "@gajae-code/bridge-client": "0.13.2",
61
+ "@gajae-code/natives": "0.13.2",
62
+ "@gajae-code/tui": "0.13.2",
63
+ "@gajae-code/utils": "0.13.2",
64
64
  "@puppeteer/browsers": "^2.13.0",
65
65
  "@types/turndown": "5.0.6",
66
66
  "@xterm/headless": "^6.0.0",
@@ -5693,6 +5693,9 @@ export function createCoordinatorMcpServer(options: CoordinatorMcpServerOptions
5693
5693
  },
5694
5694
  };
5695
5695
  }
5696
+ if (request.method === "ping") {
5697
+ return { jsonrpc: "2.0", id, result: {} };
5698
+ }
5696
5699
  if (request.method === "tools/list") {
5697
5700
  return { jsonrpc: "2.0", id, result: { tools: COORDINATOR_MCP_TOOL_NAMES.map(toolSchema) } };
5698
5701
  }