@adhdev/daemon-core 0.9.82-rc.143 → 0.9.82-rc.145

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 (92) hide show
  1. package/dist/boot/process-hardening.d.ts +50 -0
  2. package/dist/cli-adapters/cli-script-runner.d.ts +73 -1
  3. package/dist/cli-adapters/provider-cli-adapter.d.ts +17 -0
  4. package/dist/cli-adapters/provider-cli-shared.d.ts +6 -0
  5. package/dist/commands/handler.d.ts +66 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +2943 -435
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +2957 -456
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/ipc/local-ipc-server.d.ts +91 -0
  12. package/dist/providers/contracts.d.ts +31 -5
  13. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  14. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  15. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  16. package/dist/providers/native-history/index.d.ts +11 -0
  17. package/dist/providers/provider-loader.d.ts +19 -1
  18. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  19. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
  20. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  21. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +64 -0
  22. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  23. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  24. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  25. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  26. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  27. package/dist/providers/sdk/v1/index.d.ts +30 -0
  28. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  29. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  30. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  31. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  32. package/dist/providers/sdk/v1/types/common/index.d.ts +169 -0
  33. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  34. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  35. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  36. package/package.json +4 -2
  37. package/src/boot/daemon-lifecycle.ts +14 -10
  38. package/src/boot/process-hardening.ts +89 -0
  39. package/src/cli-adapters/cli-script-runner.ts +289 -13
  40. package/src/cli-adapters/cli-state-engine.ts +8 -5
  41. package/src/cli-adapters/provider-cli-adapter.ts +36 -2
  42. package/src/cli-adapters/provider-cli-shared.ts +6 -0
  43. package/src/commands/chat-commands.ts +35 -14
  44. package/src/commands/cli-manager.ts +39 -0
  45. package/src/commands/handler.ts +539 -1
  46. package/src/commands/router.ts +2 -1
  47. package/src/index.ts +27 -0
  48. package/src/ipc/local-ipc-server.ts +278 -0
  49. package/src/providers/cli-provider-instance.ts +18 -3
  50. package/src/providers/contracts.ts +33 -5
  51. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  52. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  53. package/src/providers/native-history/codex-cli-transcript.ts +419 -0
  54. package/src/providers/native-history/index.ts +23 -0
  55. package/src/providers/provider-loader.ts +263 -17
  56. package/src/providers/provider-schema.ts +21 -15
  57. package/src/providers/sdk/README.md +49 -0
  58. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  59. package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
  60. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  61. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +245 -0
  62. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  63. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  64. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  65. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  66. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  67. package/src/providers/sdk/v1/index.ts +152 -0
  68. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  69. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  70. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  71. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +444 -0
  72. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  73. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  74. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  75. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  76. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  77. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  78. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  79. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  80. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +119 -0
  81. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  82. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  83. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  84. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  85. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  86. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  87. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  88. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  89. package/src/providers/sdk/v1/types/common/index.ts +210 -0
  90. package/src/providers/sdk/v1/validators/index.ts +19 -0
  91. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  92. package/src/providers/sdk/v1/validators/taint.ts +309 -0
@@ -0,0 +1,278 @@
1
+ /**
2
+ * LocalIpcServer — generic HTTP + WebSocket IPC endpoint for daemon processes.
3
+ *
4
+ * Both daemon-cloud and daemon-standalone need a local IPC surface so
5
+ * external tools — the `adhdev mcp --mode ipc` MCP server and anything
6
+ * else that wants to issue commands without going through the cloud
7
+ * Worker — can connect over `ws://127.0.0.1:<port>/ipc`.
8
+ *
9
+ * Until now the implementation lived only in daemon-cloud. Standalone
10
+ * sessions therefore couldn't host MCP mesh tools — codex/claude config
11
+ * pointing at `--mode ipc` got `Cannot reach ipc daemon`. This module
12
+ * moves the transport into daemon-core so both daemons can mount it.
13
+ *
14
+ * The transport itself is daemon-agnostic. Cloud-specific behaviors
15
+ * (mesh relay, mandatory update gates) are injected via the caller's
16
+ * `handleCommand` hook; the IPC layer just frames/unframes JSON and
17
+ * routes messages.
18
+ */
19
+
20
+ import { createServer, type IncomingMessage, type Server as HttpServer } from 'http';
21
+ import { WebSocketServer, WebSocket } from 'ws';
22
+ import { LOG } from '../logging/logger.js';
23
+ import { DAEMON_WS_PATH } from '../ipc-protocol.js';
24
+
25
+ /** Parameters passed to `handleCommand` for each incoming ext:command frame. */
26
+ export interface IpcCommandContext {
27
+ /** The raw `command` field from the message — caller decides routing. */
28
+ command: string;
29
+ /** Args provided by the client; may have been normalized by the caller. */
30
+ args: Record<string, unknown>;
31
+ /** Stable id correlating the request and the eventual ext:command_result. */
32
+ requestId: string;
33
+ /** The connected WebSocket — only needed if the caller wants to send extra events. */
34
+ ws: WebSocket;
35
+ }
36
+
37
+ /** Result reported back to the client. `result` is optional context for success. */
38
+ export interface IpcCommandResult {
39
+ success: boolean;
40
+ result?: unknown;
41
+ error?: string;
42
+ /**
43
+ * Additional fields the caller wants merged into the response payload
44
+ * (e.g. the cloud daemon's mandatory-update-block fields). Reserved.
45
+ */
46
+ extra?: Record<string, unknown>;
47
+ }
48
+
49
+ /** Status payload returned from GET / on the IPC HTTP port. */
50
+ export interface IpcStatusPayload {
51
+ ok: true;
52
+ pid: number;
53
+ wsPath: string;
54
+ port: number;
55
+ /** Arbitrary daemon-specific summary. Cloud daemon includes mesh state, etc. */
56
+ status: Record<string, unknown> | null;
57
+ }
58
+
59
+ export interface LocalIpcServerOptions {
60
+ /** TCP port to listen on. 19222 is the conventional default. */
61
+ port: number;
62
+ /** Build the GET / status payload. Called on every health probe. */
63
+ buildStatusPayload: () => Record<string, unknown> | null;
64
+ /** Build the welcome message sent to a freshly-connected client. */
65
+ buildWelcomePayload: () => Record<string, unknown>;
66
+ /** Handle a single ext:command frame. Caller decides routing and returns the result. */
67
+ handleCommand: (ctx: IpcCommandContext) => Promise<IpcCommandResult>;
68
+ /** Optional notification when a new client connects (lets daemon track them for broadcasts). */
69
+ onClientConnected?: (ws: WebSocket) => void;
70
+ /** Optional notification when a client disconnects. */
71
+ onClientDisconnected?: (ws: WebSocket) => void;
72
+ /** Optional logger label (defaults to "IPC"). */
73
+ logCategory?: string;
74
+ }
75
+
76
+ /**
77
+ * Returned controller for stopping the server and broadcasting to clients.
78
+ * Stored by the daemon and torn down at shutdown.
79
+ */
80
+ export interface LocalIpcServerHandle {
81
+ /** True once `listen()` succeeded. */
82
+ isListening(): boolean;
83
+ /** Push a message to every connected client. */
84
+ broadcast(type: string, payload: unknown): void;
85
+ /** Close all client sockets + the HTTP server. */
86
+ close(): Promise<void>;
87
+ }
88
+
89
+ /**
90
+ * Build a JSON HTTP response describing the IPC endpoint. Exposed so caller
91
+ * code (and tests) can build the same shape without spinning a real server.
92
+ */
93
+ export function buildIpcStatusHttpResponse(
94
+ method: string | undefined,
95
+ url: string | undefined,
96
+ payload: IpcStatusPayload,
97
+ ): { statusCode: number; body: Record<string, unknown> } {
98
+ if (method && method.toUpperCase() !== 'GET') {
99
+ return { statusCode: 405, body: { ok: false, error: 'method not allowed' } };
100
+ }
101
+ // `/health` is the probe path used by the MCP IpcTransport ping —
102
+ // mirror cloud daemon behavior so `adhdev mcp --mode ipc` recognizes
103
+ // us as a live IPC host. `/` and `/status` return the same shape.
104
+ if (url && url !== '/' && url !== '/status' && url !== '/health') {
105
+ return { statusCode: 404, body: { ok: false, error: 'not found' } };
106
+ }
107
+ return { statusCode: 200, body: payload as unknown as Record<string, unknown> };
108
+ }
109
+
110
+ /**
111
+ * Start the local IPC server. Returns a handle the caller can use to broadcast
112
+ * events and tear down at shutdown.
113
+ */
114
+ export async function startLocalIpcServer(opts: LocalIpcServerOptions): Promise<LocalIpcServerHandle> {
115
+ const logCategory = opts.logCategory || 'IPC';
116
+ const clients = new Set<WebSocket>();
117
+ let httpServer: HttpServer | null = null;
118
+ let wss: WebSocketServer | null = null;
119
+ let listening = false;
120
+
121
+ httpServer = createServer((req, res) => {
122
+ const payload: IpcStatusPayload = {
123
+ ok: true,
124
+ pid: process.pid,
125
+ wsPath: DAEMON_WS_PATH,
126
+ port: opts.port,
127
+ status: opts.buildStatusPayload(),
128
+ };
129
+ const response = buildIpcStatusHttpResponse(req.method, req.url, payload);
130
+ const body = JSON.stringify(response.body);
131
+ res.writeHead(response.statusCode, {
132
+ 'Content-Type': 'application/json',
133
+ 'Content-Length': Buffer.byteLength(body),
134
+ 'Connection': 'close',
135
+ });
136
+ res.end(body);
137
+ });
138
+
139
+ wss = new WebSocketServer({ noServer: true });
140
+ wss.on('connection', (ws) => handleConnection(ws));
141
+
142
+ httpServer.on('upgrade', (req: IncomingMessage, socket, head) => {
143
+ const wsUrl = new URL(req.url || '/', `http://${req.headers.host || '127.0.0.1'}`);
144
+ if (wsUrl.pathname !== DAEMON_WS_PATH) {
145
+ socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
146
+ socket.destroy();
147
+ return;
148
+ }
149
+ wss!.handleUpgrade(req, socket, head, (ws) => {
150
+ wss!.emit('connection', ws, req);
151
+ });
152
+ });
153
+
154
+ function handleConnection(ws: WebSocket): void {
155
+ clients.add(ws);
156
+ sendWelcome(ws);
157
+ opts.onClientConnected?.(ws);
158
+
159
+ ws.on('message', (raw) => {
160
+ void handleMessage(ws, raw.toString());
161
+ });
162
+ ws.on('close', () => {
163
+ clients.delete(ws);
164
+ opts.onClientDisconnected?.(ws);
165
+ });
166
+ ws.on('error', () => {
167
+ clients.delete(ws);
168
+ opts.onClientDisconnected?.(ws);
169
+ });
170
+ }
171
+
172
+ function sendWelcome(ws: WebSocket): void {
173
+ try {
174
+ ws.send(JSON.stringify({
175
+ type: 'daemon:welcome',
176
+ payload: opts.buildWelcomePayload(),
177
+ }));
178
+ } catch (error: any) {
179
+ LOG.warn(logCategory, `Failed to send welcome: ${error?.message || error}`);
180
+ }
181
+ }
182
+
183
+ async function handleMessage(ws: WebSocket, raw: string): Promise<void> {
184
+ let msg: any;
185
+ try { msg = JSON.parse(raw); } catch { return; }
186
+ if (!msg || typeof msg !== 'object') return;
187
+
188
+ // Re-issue welcome on client request (used by reconnecting MCP servers).
189
+ if (msg.type === 'ext:register') {
190
+ sendWelcome(ws);
191
+ return;
192
+ }
193
+ if (msg.type !== 'ext:command') return;
194
+
195
+ const payload = msg.payload && typeof msg.payload === 'object' ? msg.payload : {};
196
+ const command = typeof payload.command === 'string' ? payload.command : '';
197
+ const args = payload.args && typeof payload.args === 'object'
198
+ ? payload.args as Record<string, unknown>
199
+ : {};
200
+ const requestId = typeof payload.requestId === 'string'
201
+ ? payload.requestId
202
+ : typeof payload.messageId === 'string'
203
+ ? payload.messageId
204
+ : `ipc-${Date.now()}`;
205
+
206
+ if (!command) {
207
+ ws.send(JSON.stringify({
208
+ type: 'ext:command_result',
209
+ payload: { requestId, success: false, error: 'command required' },
210
+ }));
211
+ return;
212
+ }
213
+
214
+ try {
215
+ const result = await opts.handleCommand({ command, args, requestId, ws });
216
+ ws.send(JSON.stringify({
217
+ type: 'ext:command_result',
218
+ payload: {
219
+ requestId,
220
+ success: result.success,
221
+ result: result.result,
222
+ error: result.error,
223
+ ...(result.extra || {}),
224
+ },
225
+ }));
226
+ } catch (error: any) {
227
+ ws.send(JSON.stringify({
228
+ type: 'ext:command_result',
229
+ payload: {
230
+ requestId,
231
+ success: false,
232
+ error: error?.message || String(error),
233
+ },
234
+ }));
235
+ }
236
+ }
237
+
238
+ await new Promise<void>((resolve, reject) => {
239
+ const onError = (error: Error) => {
240
+ httpServer?.off('listening', onListening);
241
+ reject(error);
242
+ };
243
+ const onListening = () => {
244
+ httpServer?.off('error', onError);
245
+ listening = true;
246
+ resolve();
247
+ };
248
+ httpServer!.once('error', onError);
249
+ httpServer!.once('listening', onListening);
250
+ httpServer!.listen(opts.port, '127.0.0.1');
251
+ });
252
+
253
+ LOG.info(logCategory, `Local IPC listening on ws://127.0.0.1:${opts.port}${DAEMON_WS_PATH}`);
254
+
255
+ return {
256
+ isListening: () => listening,
257
+ broadcast(type, payload) {
258
+ const message = JSON.stringify({ type, payload });
259
+ for (const client of clients) {
260
+ if (client.readyState !== WebSocket.OPEN) continue;
261
+ try { client.send(message); } catch { /* drop silently */ }
262
+ }
263
+ },
264
+ async close() {
265
+ for (const client of clients) {
266
+ try { client.close(); } catch { /* ignore */ }
267
+ }
268
+ clients.clear();
269
+ await new Promise<void>((resolve) => {
270
+ if (!httpServer) { resolve(); return; }
271
+ httpServer.close(() => resolve());
272
+ });
273
+ httpServer = null;
274
+ wss = null;
275
+ listening = false;
276
+ },
277
+ };
278
+ }
@@ -508,6 +508,21 @@ export class CliProviderInstance implements ProviderInstance {
508
508
  }
509
509
 
510
510
  getState(): ProviderState {
511
+ // TODO(phase5-sandbox): JS override scripts (detectStatus, parseApproval,
512
+ // parseSession) are currently invoked by CliScriptRunner.invoke() via direct
513
+ // function calls — the scripts run in the daemon process with full Node.js
514
+ // access and no resource limits.
515
+ //
516
+ // When Phase 5 lands, CliScriptRunner should route these calls through a
517
+ // SandboxedScriptRunner (see providers/sdk/v1/sandbox/script-runner.ts) so
518
+ // that each call gets a fresh isolated-vm context with a 50 ms CPU limit and
519
+ // a 32 MB memory cap. The execution path to change is:
520
+ // CliScriptRunner.invoke() → SandboxedScriptRunner.run(scriptSource, context)
521
+ //
522
+ // This getState() call-site is NOT where the change goes — the wiring belongs
523
+ // in cli-script-runner.ts (CliScriptRunner.detectStatus / parseApproval /
524
+ // parseSession), with provider-loader.ts updated to store script source strings
525
+ // alongside the loaded function references for extended-legacy providers.
511
526
  const adapterStatus = this.adapter.getStatus();
512
527
  let parsedStatus: any = null;
513
528
  let parseErrorMessage: string | undefined;
@@ -1677,7 +1692,7 @@ export class CliProviderInstance implements ProviderInstance {
1677
1692
 
1678
1693
  private syncCanonicalSavedHistoryIfNeeded(): boolean {
1679
1694
  if (!this.providerSessionId) return false;
1680
- const canonicalHistory = this.provider.canonicalHistory;
1695
+ const canonicalHistory = this.provider.nativeHistory;
1681
1696
  if (!canonicalHistory) return false;
1682
1697
 
1683
1698
  if (isNativeSourceCanonicalHistory(canonicalHistory)) {
@@ -1739,9 +1754,9 @@ export class CliProviderInstance implements ProviderInstance {
1739
1754
  private restorePersistedHistoryFromCurrentSession(): void {
1740
1755
  if (!this.providerSessionId) return;
1741
1756
  this.syncCanonicalSavedHistoryIfNeeded();
1742
- const restoredHistory = isNativeSourceCanonicalHistory(this.provider.canonicalHistory)
1757
+ const restoredHistory = isNativeSourceCanonicalHistory(this.provider.nativeHistory)
1743
1758
  ? readProviderChatHistory(this.type, {
1744
- canonicalHistory: this.provider.canonicalHistory,
1759
+ canonicalHistory: this.provider.nativeHistory,
1745
1760
  historySessionId: this.providerSessionId,
1746
1761
  workspace: this.workingDir,
1747
1762
  offset: 0,
@@ -480,6 +480,14 @@ export interface ProviderModule {
480
480
  extensionIdPattern_flags?: string;
481
481
  compatibility?: ProviderCompatibilityEntry[];
482
482
  defaultScriptDir?: string;
483
+ /**
484
+ * v1 declarative tui block (spinner/settledPrompt/modal/dispatchOrder/etc).
485
+ * When present, the daemon's CliScriptRunner builds canonical
486
+ * (input → verdict) functions from this and injects them into provider
487
+ * scripts as `sdk.declarativeDetectStatus` and `sdk.declarativeParseApproval`.
488
+ * v0 / verified-tier providers can omit this entirely.
489
+ */
490
+ tui?: Record<string, unknown>;
483
491
  /**
484
492
  * Scripts that can run at the IDE main-page level (not just inside the extension webview session frame).
485
493
  * Default: ['listModes', 'setMode', 'listModels', 'setModel'].
@@ -533,8 +541,16 @@ export interface ProviderModule {
533
541
  /** History behavior config — controls message filtering and collapse during replay */
534
542
  historyBehavior?: ProviderHistoryBehavior;
535
543
  /**
536
- * Canonical history sync config — for providers that maintain native history files.
537
- * When set, daemon syncs from native format into ADHDev JSONL store on each tick.
544
+ * Native history config — for providers that maintain native history files.
545
+ * When set, daemon reads/lists provider-native transcripts directly. This is
546
+ * the canonical v1 field name; the legacy `canonicalHistory` field name is
547
+ * still accepted by the loader and aliased onto this field at load time.
548
+ */
549
+ nativeHistory?: NativeHistoryConfig;
550
+ /**
551
+ * @deprecated Legacy v0 alias for {@link ProviderModule.nativeHistory}.
552
+ * Loader populates this from `nativeHistory` so existing internal readers
553
+ * keep working during the transition. Remove after one release.
538
554
  */
539
555
  canonicalHistory?: ProviderCanonicalHistoryConfig;
540
556
  /**
@@ -680,7 +696,7 @@ export interface ProviderHistoryBehavior {
680
696
  * daemon-core. They let each provider own native transcript file discovery and
681
697
  * parsing while daemon-core only validates/pages the normalized result.
682
698
  */
683
- export interface ProviderCanonicalHistoryScriptsConfig {
699
+ export interface NativeHistoryScriptsConfig {
684
700
  /** Reads one native session. Default: 'readNativeHistory'. */
685
701
  readSession?: string;
686
702
  /** Lists native sessions with summary metadata. Default: 'listNativeHistory'. */
@@ -688,13 +704,19 @@ export interface ProviderCanonicalHistoryScriptsConfig {
688
704
  }
689
705
 
690
706
  /**
691
- * Canonical history sync config for providers that maintain their own native history files.
707
+ * @deprecated Use {@link NativeHistoryScriptsConfig}. Retained as an alias for
708
+ * one release so external consumers that referenced the old name keep compiling.
709
+ */
710
+ export type ProviderCanonicalHistoryScriptsConfig = NativeHistoryScriptsConfig;
711
+
712
+ /**
713
+ * Native history config — for providers that maintain their own native history files.
692
714
  *
693
715
  * Preferred mode is provider-owned scripts via `scripts`. `format` is now an
694
716
  * opaque provider label retained for diagnostics/backward compatibility; daemon
695
717
  * live paths must not branch on provider-specific format values.
696
718
  */
697
- export interface ProviderCanonicalHistoryConfig {
719
+ export interface NativeHistoryConfig {
698
720
  /** Opaque provider-owned history format label. */
699
721
  format?: string;
700
722
  /** Optional native history glob/template for diagnostics only. */
@@ -723,6 +745,12 @@ export interface ProviderCanonicalHistoryConfig {
723
745
  contractVersion?: import('./transcript-v2.js').ChatContractVersion;
724
746
  }
725
747
 
748
+ /**
749
+ * @deprecated Use {@link NativeHistoryConfig}. Retained as an alias for one
750
+ * release so external consumers that referenced the old name keep compiling.
751
+ */
752
+ export type ProviderCanonicalHistoryConfig = NativeHistoryConfig;
753
+
726
754
  /**
727
755
  * Auto-implement spawn config — controls how the provider is spawned for autonomous AI-driven
728
756
  * provider script implementation (dev-auto-implement.ts).