@gajae-code/coding-agent 0.11.0 → 0.11.1

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 (36) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/types/async/job-manager.d.ts +46 -7
  3. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +11 -0
  4. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  5. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
  6. package/dist/types/modes/interactive-mode.d.ts +2 -2
  7. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +1 -0
  8. package/dist/types/modes/types.d.ts +2 -2
  9. package/dist/types/sdk/broker/ensure.d.ts +9 -0
  10. package/dist/types/sdk/bus/discord-daemon.d.ts +5 -0
  11. package/dist/types/sdk/bus/telegram-daemon.d.ts +23 -0
  12. package/dist/types/tools/subagent-render.d.ts +1 -0
  13. package/dist/types/tools/subagent.d.ts +6 -1
  14. package/package.json +8 -8
  15. package/scripts/build-sdk-package-smoke.ts +5 -0
  16. package/src/async/job-manager.ts +406 -63
  17. package/src/gjc-runtime/ultragoal-guard.ts +55 -8
  18. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
  19. package/src/gjc-runtime/ultragoal-runtime.ts +72 -8
  20. package/src/internal-urls/docs-index.generated.ts +2 -2
  21. package/src/modes/controllers/command-controller.ts +9 -15
  22. package/src/modes/controllers/extension-ui-controller.ts +48 -24
  23. package/src/modes/interactive-mode.ts +28 -16
  24. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +7 -3
  25. package/src/modes/types.ts +2 -2
  26. package/src/sdk/broker/discovery.ts +20 -1
  27. package/src/sdk/broker/ensure.ts +82 -24
  28. package/src/sdk/bus/chat-effect-journal.ts +6 -4
  29. package/src/sdk/bus/discord-daemon.ts +25 -8
  30. package/src/sdk/bus/index.ts +57 -21
  31. package/src/sdk/bus/native-runtime-compatibility.ts +1 -1
  32. package/src/sdk/bus/telegram-daemon.ts +102 -10
  33. package/src/session/agent-session.ts +176 -29
  34. package/src/task/index.ts +26 -16
  35. package/src/tools/subagent-render.ts +19 -8
  36. package/src/tools/subagent.ts +84 -32
package/CHANGELOG.md CHANGED
@@ -2,15 +2,23 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.11.1] - 2026-07-16
6
+
7
+ ### Fixed
8
+ - Published the Windows Bun workflow-gate durability fix that tolerates unsupported `EPERM` directory `fsync` failures after an already-committed atomic rename; the 0.11.0 package changelog described the fix, but the released artifact did not contain it (#2316).
9
+
5
10
  ## [0.11.0] - 2026-07-15
6
11
 
7
12
  ### Fixed
13
+ - Discord inbound lease recovery now exposes a deterministic scheduler seam, preserves exponential retry wakeups after transient endpoint lookup failures, and cancels pending recovery exactly on daemon stop instead of relying on wall-clock sleeps in regression coverage.
8
14
  - Input-free interactive TTY startup now keeps the TUI reachable when configured model profiles are missing required provider credentials, skips only the blocked profiles, and preserves later `--mpreset` and explicit model/thinking precedence; redirected terminals, input-bearing, resume-continuation, image-only, print/text, and unrelated activation failures remain fail-closed (#2277).
15
+ - Windows Bun runtimes no longer crash while committing the durable workflow-gate store when directory `fsync` reports the unsupported-operation code `EPERM`; unexpected directory-sync failures remain fail-closed.
9
16
  - Browser geo settings now propagate coherently across request `Accept-Language`, navigator languages, and `Intl` locale/timezone surfaces; configured managed browsers are isolated by geo/profile posture, concurrent acquisition is serialized, and unset geo preserves Chromium's native locale/timezone instead of injecting a fixed New York profile.
10
17
 
11
18
  - Cooperative mid-run context maintenance now waits at a cancellation-aware FIFO consumer-drain checkpoint before flushing or rewriting session history. Materialized tool results and steering messages are synchronously canonicalized first; aborted barriers and hook/signal-cancelled compactions settle without rewriting or scheduling a continuation. Promotion, pruning, and compaction each start a clean provider/prompt-cache epoch. Script-aware #2067 unsent-delta accounting remains cache-free and distinct from the lifecycle checkpoint.
12
19
  - Classified the cooperative mid-run maintenance driver and token estimator test seams as locked non-public SDK exclusions, restoring deterministic operation-inventory generation and post-merge dev CI coverage.
13
20
  - Accepted SDK prompts now deliver correlated `agent_start` and exactly one terminal lifecycle frame directly to the requesting authenticated WebSocket connection while retaining replayable host events. Harness owner observation also waits for every previously accepted frame to finish serial persistence, so message-update storms and polling gaps cannot hide sticky completion evidence (#2169).
21
+ - `/new` now fails closed while owned subagent shutdown is unproven: it preserves the current session identity and shows an actionable cleanup notice. Successful replacement waits for cooperative child cancellation, cancels owner jobs before switching identity, and `/drop` creates the replacement before attempting old-session deletion (#2261).
14
22
 
15
23
  ### Added
16
24
 
@@ -27,7 +35,7 @@
27
35
  - Removed the `--mode rpc`, `--mode rpc-ui`, and `--mode bridge` external ingress modes. Machine clients must use the SDK WebSocket interfaces documented in `docs/sdk.md`; no RPC or Bridge compatibility path remains.
28
36
  - Documented the current GPT-5.6 Codex and combo profile mappings as product judgments, including the durable `opus-codex` `anthropic/claude-sonnet-5` planner override and `fable-opus-codex` `anthropic/claude-opus-4-8:medium` planner.
29
37
  - Resolved the SDK v3 workflow-gate shipping classification (#2171): `workflowGateId` and Q12 diagnostics are additive SDK v3 surfaces, while `action_needed.id` remains the transient, generic `reply.id` authority. `expectedSessionId` omission remains accepted and audited for the entire SDK v3 line; new clients must send it, and mandatory enforcement or removal can occur no earlier than SDK v4 only after at least one full published deprecation release/window with deployed-client notice. Explicit session mismatches fail closed before resolution; mismatched sessions, stale/reissued actions, and unsafe ambiguity never regain authority.
30
- - Documented release pairing: the `@gajae-code/coding-agent` runtime and `@gajae-code/natives` native addon ship from the same source release at exact matching package versions (currently `0.10.2`), with the native loader version sentinel enforcing the pair. Mixed native/runtime versions are unsupported and cannot claim SDK compatibility.
38
+ - Documented release pairing: the `@gajae-code/coding-agent` runtime and `@gajae-code/natives` native addon ship from the same source release at exact matching package versions, with the native loader version sentinel enforcing the pair. Mixed native/runtime versions are unsupported and cannot claim SDK compatibility.
31
39
  ### Fixed
32
40
  - Startup continuation now participates in the existing managed fallback and in-flight recovery envelope, preventing a retryable resumed turn from publishing `agent_end`/idle before retry success, exhaustion, cancellation, or startup failure has settled (#2092).
33
41
 
@@ -59,6 +59,31 @@ export type SubagentRunOutcome = {
59
59
  };
60
60
  /** Canonical lifecycle of a subagent across pause/resume cycles. */
61
61
  export type SubagentLifecycle = "running" | "paused" | "queued" | "completed" | "failed" | "cancelled";
62
+ /** Maximum time allowed to prove owned subagents have stopped before replacement. */
63
+ export declare const OWNER_SUBAGENT_SHUTDOWN_TIMEOUT_MS = 5000;
64
+ export declare class OwnerSubagentShutdownError extends Error {
65
+ readonly code = "owner_shutdown_in_progress";
66
+ constructor();
67
+ }
68
+ export interface OwnerSubagentShutdownTarget {
69
+ subagentId: string;
70
+ jobId: string | null;
71
+ source: "record" | "metadata_job";
72
+ }
73
+ export interface OwnerSubagentShutdownLease {
74
+ ownerId: string;
75
+ id: string;
76
+ targets: readonly OwnerSubagentShutdownTarget[];
77
+ }
78
+ export interface OwnerSubagentShutdownProof {
79
+ ownerId: string;
80
+ leaseId: string;
81
+ confirmed: boolean;
82
+ reason: "confirmed" | "deadline_exceeded" | "missing_terminal_evidence" | "lease_lost";
83
+ targets: readonly OwnerSubagentShutdownTarget[];
84
+ terminalIds: readonly string[];
85
+ unresolvedIds: readonly string[];
86
+ }
62
87
  /**
63
88
  * Live, executor-owned control handle for a RUNNING subagent. Registered when a
64
89
  * subagent run starts and removed on pause/terminal so a paused subagent retains
@@ -106,6 +131,11 @@ export interface ResumeDescriptor {
106
131
  ownerId?: string;
107
132
  data: unknown;
108
133
  }
134
+ /**
135
+ * In-memory resume runner bound to the session that originally launched a
136
+ * subagent. Never serialized: process restart drops it so resume fails closed.
137
+ */
138
+ export type ResumeRunner = (subagentId: string, message?: string, descriptor?: ResumeDescriptor) => string | undefined;
109
139
  export interface AsyncJobManagerOptions {
110
140
  onJobComplete: (jobId: string, text: string, job?: AsyncJob) => void | Promise<void>;
111
141
  maxRunningJobs?: number;
@@ -241,9 +271,16 @@ export declare class AsyncJobManager {
241
271
  */
242
272
  hasLiveSubagent(subagentId: string, filter?: AsyncJobFilter): boolean;
243
273
  /** Install the TaskTool-owned resume runner. Returns the new job id, or undefined on failure. */
244
- setResumeRunner(runner: (subagentId: string, message?: string, descriptor?: ResumeDescriptor) => string | undefined): void;
245
- registerResumeDescriptor(descriptor: ResumeDescriptor): void;
274
+ setResumeRunner(runner: ResumeRunner): void;
275
+ registerResumeDescriptor(descriptor: ResumeDescriptor, runner?: ResumeRunner): void;
246
276
  getResumeDescriptor(subagentId: string, filter?: AsyncJobFilter): ResumeDescriptor | undefined;
277
+ beginOwnerSubagentShutdown(ownerId: string): OwnerSubagentShutdownLease | undefined;
278
+ runOwnerProducerCleanups(filter?: AsyncJobFilter): void;
279
+ runOwnerProducerCleanupsStrict(filter?: AsyncJobFilter): void;
280
+ cancelAndProveOwnerSubagents(lease: OwnerSubagentShutdownLease, options?: {
281
+ timeoutMs?: number;
282
+ }): Promise<OwnerSubagentShutdownProof>;
283
+ finishOwnerSubagentShutdown(lease: OwnerSubagentShutdownLease, outcome: "commit" | "release"): void;
247
284
  /** Request a graceful safe-boundary pause of a running subagent. */
248
285
  pauseSubagent(subagentId: string, filter?: AsyncJobFilter): {
249
286
  ok: boolean;
@@ -298,11 +335,7 @@ export declare class AsyncJobManager {
298
335
  * teardown.
299
336
  */
300
337
  registerOwnerCleanup(ownerId: string, cleanup: () => void): () => void;
301
- /**
302
- * Run and clear every registered cleanup for the given filter. Idempotent
303
- * and error-isolated: a throwing cleanup does not prevent siblings from
304
- * running and never escalates to the caller.
305
- */
338
+ /** Run producer cleanups, then perform the legacy destructive subagent purge. */
306
339
  runOwnerCleanups(filter?: AsyncJobFilter): void;
307
340
  getDeliveryState(filter?: AsyncJobFilter): AsyncJobDeliveryState;
308
341
  hasPendingDeliveries(filter?: AsyncJobFilter): boolean;
@@ -315,6 +348,12 @@ export declare class AsyncJobManager {
315
348
  * (used by `dispose()` to nuke the manager's state).
316
349
  */
317
350
  cancelAll(filter?: AsyncJobFilter): void;
351
+ waitForOwnerInFlightDeliveries(ownerId: string, options?: {
352
+ timeoutMs?: number;
353
+ }): Promise<boolean>;
354
+ cancelAndSettleOwnerJobs(ownerId: string, options?: {
355
+ timeoutMs?: number;
356
+ }): Promise<boolean>;
318
357
  getLastDisposeDiagnostics(): AsyncJobDisposeDiagnostics;
319
358
  waitForAll(): Promise<void>;
320
359
  drainDeliveries(options?: {
@@ -26,6 +26,17 @@ export declare function validateReceiptFreshBase(input: {
26
26
  receipt: UltragoalCompletionVerification;
27
27
  receiptKind: UltragoalReceiptKind;
28
28
  }): UltragoalReceiptFreshnessDiagnostic | null;
29
+ /**
30
+ * Validate a final-aggregate receipt that was legitimately superseded — its
31
+ * aggregate claim staled by later plan growth (e.g. `steer add_subgoal`
32
+ * appending goals after a terminal run) — as historical evidence for its own
33
+ * goal. Returns null when the receipt stands.
34
+ */
35
+ export declare function validateSupersededFinalAggregateReceipt(input: {
36
+ ledger: readonly UltragoalLedgerEvent[];
37
+ goal: UltragoalGoal;
38
+ receipt: UltragoalCompletionVerification;
39
+ }): UltragoalReceiptFreshnessDiagnostic | null;
29
40
  export declare function findFreshBatchCloseReceipt(input: {
30
41
  plan: UltragoalPlan;
31
42
  ledger: readonly UltragoalLedgerEvent[];
@@ -22,9 +22,9 @@ export declare class CommandController {
22
22
  handleToolsCommand(): void;
23
23
  handleContextCommand(): void;
24
24
  handleMemoryCommand(text: string): Promise<void>;
25
- handleClearCommand(): Promise<void>;
25
+ handleClearCommand(): Promise<boolean>;
26
26
  handleContextClearCommand(): Promise<void>;
27
- handleDropCommand(): Promise<void>;
27
+ handleDropCommand(): Promise<boolean>;
28
28
  handleForkCommand(): Promise<void>;
29
29
  handleMoveCommand(targetPath: string): Promise<void>;
30
30
  handleRenameCommand(title: string): Promise<void>;
@@ -7,6 +7,7 @@ export declare class ExtensionUiController {
7
7
  #private;
8
8
  private ctx;
9
9
  constructor(ctx: InteractiveModeContext);
10
+ captureSessionUiCleanup(): () => void;
10
11
  /**
11
12
  * Initialize the hook system with TUI-based UI context.
12
13
  */
@@ -211,9 +211,9 @@ export declare class InteractiveMode implements InteractiveModeContext {
211
211
  handleHelpCommand(): void;
212
212
  handleToolsCommand(): void;
213
213
  handleContextCommand(): void;
214
- handleClearCommand(): Promise<void>;
214
+ handleClearCommand(): Promise<boolean>;
215
215
  handleContextClearCommand(): Promise<void>;
216
- handleDropCommand(): Promise<void>;
216
+ handleDropCommand(): Promise<boolean>;
217
217
  handleForkCommand(): Promise<void>;
218
218
  handleMoveCommand(targetPath: string): Promise<void>;
219
219
  handleRenameCommand(title: string): Promise<void>;
@@ -145,6 +145,7 @@ export declare class MemoryGateStore implements GateStore {
145
145
  beginRuntimeInstance(instanceId: string): void;
146
146
  list(): PersistedGate[];
147
147
  }
148
+ export declare function isUnsupportedWindowsDirectorySyncError(error: unknown, platform?: NodeJS.Platform): boolean;
148
149
  /** A write may have reached `rename` but not the directory fsync durability barrier. */
149
150
  export declare class GateStoreWriteError extends Error {
150
151
  readonly certainty: "not_committed" | "uncertain";
@@ -239,9 +239,9 @@ export interface InteractiveModeContext {
239
239
  handleContextCommand(): void;
240
240
  handleDumpCommand(): void;
241
241
  handleDebugTranscriptCommand(): Promise<void>;
242
- handleClearCommand(): Promise<void>;
242
+ handleClearCommand(): Promise<boolean>;
243
243
  handleContextClearCommand(): Promise<void>;
244
- handleDropCommand(): Promise<void>;
244
+ handleDropCommand(): Promise<boolean>;
245
245
  handleForkCommand(): Promise<void>;
246
246
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
247
247
  handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
@@ -11,6 +11,13 @@ export interface EnsureBrokerSettings {
11
11
  */
12
12
  env?: NodeJS.ProcessEnv;
13
13
  }
14
+ export interface FixtureBrokerLease {
15
+ close(): Promise<void>;
16
+ }
17
+ export interface StartedFixtureBroker {
18
+ discovery: BrokerDiscovery;
19
+ lease: FixtureBrokerLease;
20
+ }
14
21
  interface BrokerOwner {
15
22
  stop(): Promise<void>;
16
23
  canReuse(discovery: BrokerDiscovery | null): boolean;
@@ -22,6 +29,8 @@ interface ReapTiming {
22
29
  }
23
30
  /** Starts the detached broker entrypoint when discovery has no live owner. */
24
31
  export declare function ensureBroker(settings: EnsureBrokerSettings): Promise<BrokerDiscovery>;
32
+ /** Starts one fresh fixture broker and returns its sole exact-child close lease. */
33
+ export declare function startFixtureBrokerWithLeaseForTest(settings: EnsureBrokerSettings): Promise<StartedFixtureBroker>;
25
34
  /** Test hook: returns a stop handle for the detached broker this process spawned. */
26
35
  export declare function brokerOwnerForTest(agentDir: string): BrokerOwner | undefined;
27
36
  /** Test hook: drives the detached-broker reap on a controllable child surface. */
@@ -9,6 +9,10 @@ export interface DiscordEndpointBinding {
9
9
  isCurrent(): boolean;
10
10
  send(frame: Record<string, unknown>): void | Promise<void>;
11
11
  }
12
+ export interface DiscordLeaseRecoveryScheduler {
13
+ setTimeout(callback: () => void | Promise<void>, delayMs: number): unknown;
14
+ clearTimeout(handle: unknown): void;
15
+ }
12
16
  export interface DiscordNotificationDaemonOptions {
13
17
  agentDir: string;
14
18
  repo: string;
@@ -16,6 +20,7 @@ export interface DiscordNotificationDaemonOptions {
16
20
  parentChannelId: string;
17
21
  provider: DiscordProvider;
18
22
  now?: () => number;
23
+ leaseRecoveryScheduler?: DiscordLeaseRecoveryScheduler;
19
24
  resolveEndpoint: (sessionId: string, expectedGeneration?: number) => Promise<DiscordEndpointBinding | null>;
20
25
  onCommand?: (sessionId: string, content: string, endpoint: DiscordEndpointBinding, idempotencyKey: string) => Promise<boolean>;
21
26
  }
@@ -230,17 +230,40 @@ export declare class TelegramBotTransport implements BotApi {
230
230
  }): Promise<unknown>;
231
231
  }
232
232
  export type TelegramUpdateOutcome = "consumed" | "retry";
233
+ export type TelegramPollResult = {
234
+ kind: "success";
235
+ updateCount: number;
236
+ } | {
237
+ kind: "aborted";
238
+ } | {
239
+ kind: "getUpdates_failed";
240
+ error: string;
241
+ } | {
242
+ kind: "api_failure";
243
+ errorCode?: number;
244
+ description: string;
245
+ } | {
246
+ kind: "conflict";
247
+ description: string;
248
+ backoffMs: number;
249
+ };
233
250
  export interface TelegramUpdatePollerOptions {
234
251
  botApi: BotApi;
235
252
  runtime: NotificationOperatorRuntime;
236
253
  backoff: OperatorBackoffPolicy;
237
254
  processUpdate: (update: unknown) => Promise<TelegramUpdateOutcome>;
255
+ health?: TelegramPollHealth;
256
+ }
257
+ export declare class TelegramPollHealth {
258
+ #private;
259
+ record(result: TelegramPollResult): void;
238
260
  }
239
261
  /** Owns getUpdates offset, conflict backoff, and per-update error isolation. */
240
262
  export declare class TelegramUpdatePoller {
241
263
  #private;
242
264
  constructor(opts: TelegramUpdatePollerOptions);
243
265
  pollOnce(signal?: AbortSignal): Promise<number>;
266
+ pollOnceResult(signal?: AbortSignal): Promise<TelegramPollResult>;
244
267
  }
245
268
  /** Mutable dispatch state shared by session frames and inbound Telegram updates. */
246
269
  export declare class TelegramEventDispatchState {
@@ -11,6 +11,7 @@ import type { Component } from "@gajae-code/tui";
11
11
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
12
12
  import type { Theme } from "../modes/theme/theme";
13
13
  import { type SubagentToolDetails } from "./subagent";
14
+ export { subagentAwaitRenderedStateSignature } from "./subagent";
14
15
  /** Test-only seam (PR3 deterministic cache-hit assertions). */
15
16
  export declare const subagentBodyCacheTestHooks: {
16
17
  readonly bodyRenders: number;
@@ -56,8 +56,13 @@ export interface SubagentSnapshot {
56
56
  /** True when the requested model lacked credentials and fell back to the parent model. */
57
57
  modelFellBack?: boolean;
58
58
  }
59
+ export type SubagentAwaitOutcome = "completed" | "timed_out" | "interrupted";
59
60
  export interface SubagentToolDetails {
60
61
  subagents: SubagentSnapshot[];
62
+ /** Await outcome for a live await receipt; omitted when no wait was started. */
63
+ awaitOutcome?: SubagentAwaitOutcome;
64
+ /** True only when the parent await was interrupted; the child was not cancelled. */
65
+ interrupted?: true;
61
66
  }
62
67
  export declare class SubagentTool implements AgentTool<typeof subagentSchema, SubagentToolDetails> {
63
68
  #private;
@@ -113,5 +118,5 @@ export declare class SubagentTool implements AgentTool<typeof subagentSchema, Su
113
118
  * countdown ticking is sacrificed by design; every real transition still changes
114
119
  * the signature.
115
120
  */
116
- export declare function subagentAwaitRenderedStateSignature(subagents: readonly SubagentSnapshot[]): string;
121
+ export declare function subagentAwaitRenderedStateSignature(subagents: readonly SubagentSnapshot[], receipt?: Pick<SubagentToolDetails, "awaitOutcome" | "interrupted">): string;
117
122
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/coding-agent",
4
- "version": "0.11.0",
4
+ "version": "0.11.1",
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",
@@ -51,13 +51,13 @@
51
51
  "@agentclientprotocol/sdk": "1.2.1",
52
52
  "@babel/parser": "^7.29.3",
53
53
  "@mozilla/readability": "^0.6.0",
54
- "@gajae-code/stats": "0.11.0",
55
- "@gajae-code/agent-core": "0.11.0",
56
- "@gajae-code/ai": "0.11.0",
57
- "@gajae-code/bridge-client": "0.11.0",
58
- "@gajae-code/natives": "0.11.0",
59
- "@gajae-code/tui": "0.11.0",
60
- "@gajae-code/utils": "0.11.0",
54
+ "@gajae-code/stats": "0.11.1",
55
+ "@gajae-code/agent-core": "0.11.1",
56
+ "@gajae-code/ai": "0.11.1",
57
+ "@gajae-code/bridge-client": "0.11.1",
58
+ "@gajae-code/natives": "0.11.1",
59
+ "@gajae-code/tui": "0.11.1",
60
+ "@gajae-code/utils": "0.11.1",
61
61
  "@puppeteer/browsers": "^2.13.0",
62
62
  "@types/turndown": "5.0.6",
63
63
  "@xterm/headless": "^6.0.0",
@@ -8,6 +8,7 @@ const packageDir = path.resolve(import.meta.dir, "..");
8
8
  const packageName = "@gajae-code/coding-agent";
9
9
  const aiPackageDir = path.resolve(packageDir, "../ai");
10
10
  const bridgeClientPackageDir = path.resolve(packageDir, "../bridge-client");
11
+ const tuiPackageDir = path.resolve(packageDir, "../tui");
11
12
  const manifestsDir = path.join(packageDir, "test/manifests");
12
13
  const baselinePath = path.join(manifestsDir, "sdk-public-surface-v1.json");
13
14
  const generatedPath = path.join(manifestsDir, "sdk-public-surface.generated.json");
@@ -34,11 +35,13 @@ async function runSmoke(): Promise<Surface> {
34
35
  ["bun", "pm", "pack", "--destination", tempDir, "--quiet"],
35
36
  bridgeClientPackageDir,
36
37
  );
38
+ const tuiTarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], tuiPackageDir);
37
39
  const codingAgentTarball = run(["bun", "pm", "pack", "--destination", tempDir, "--quiet"], packageDir);
38
40
  const aiTarballPath = path.isAbsolute(aiTarball) ? aiTarball : path.join(aiPackageDir, aiTarball);
39
41
  const bridgeClientTarballPath = path.isAbsolute(bridgeClientTarball)
40
42
  ? bridgeClientTarball
41
43
  : path.join(bridgeClientPackageDir, bridgeClientTarball);
44
+ const tuiTarballPath = path.isAbsolute(tuiTarball) ? tuiTarball : path.join(tuiPackageDir, tuiTarball);
42
45
  const codingAgentTarballPath = path.isAbsolute(codingAgentTarball)
43
46
  ? codingAgentTarball
44
47
  : path.join(packageDir, codingAgentTarball);
@@ -52,10 +55,12 @@ async function runSmoke(): Promise<Surface> {
52
55
  "@gajae-code/ai": `file:${aiTarballPath}`,
53
56
  "@gajae-code/bridge-client": `file:${bridgeClientTarballPath}`,
54
57
  [packageName]: `file:${codingAgentTarballPath}`,
58
+ "@gajae-code/tui": `file:${tuiTarballPath}`,
55
59
  },
56
60
  overrides: {
57
61
  "@gajae-code/ai": `file:${aiTarballPath}`,
58
62
  "@gajae-code/bridge-client": `file:${bridgeClientTarballPath}`,
63
+ "@gajae-code/tui": `file:${tuiTarballPath}`,
59
64
  },
60
65
  },
61
66
  null,