@ai-matrx/coding-sessions 0.1.83 → 0.1.86

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/dist/index.d.cts CHANGED
@@ -1,3 +1,4 @@
1
+ import { JsonValue } from '@ai-matrx/agents/portable';
1
2
  import { ChatMessage } from '@ai-matrx/chat';
2
3
 
3
4
  /**
@@ -6,6 +7,7 @@ import { ChatMessage } from '@ai-matrx/chat';
6
7
  * touches Node or the DOM, and every value is JSON-serializable because it
7
8
  * crosses a transport (WebSocket today, desktop IPC later).
8
9
  */
10
+
9
11
  /** The coding agents this package drives. "coding session" is the canonical
10
12
  * platform term (chat.coding_session, the Coding Session Bridge). */
11
13
  type CodingProvider = "claude" | "codex";
@@ -197,6 +199,10 @@ interface CodingSession {
197
199
  lastRunStatus: RunStatus | null;
198
200
  /** Prompts waiting for the active run to finish, oldest first. */
199
201
  queued: string[];
202
+ /** The AI Matrx agent loaded into every run of this session, when one was picked. */
203
+ agent?: SessionAgent | null | undefined;
204
+ /** Codex must be told, in the next prompt, that an earlier agent no longer applies. */
205
+ agentRemovedDue?: boolean | undefined;
200
206
  }
201
207
  /**
202
208
  * One normalized transcript item — the same shape from Claude and Codex, from
@@ -277,12 +283,105 @@ interface StartInput {
277
283
  prompt: string;
278
284
  model?: string | null | undefined;
279
285
  effort?: string | null | undefined;
286
+ /** An AI Matrx agent to load into the CLI. Needs the host's `agents` credentials. */
287
+ agent?: AgentSelection | null | undefined;
288
+ }
289
+ /** Which AI Matrx agent a new session loads, and the person's variable values. */
290
+ interface AgentSelection {
291
+ agentId: string;
292
+ /** Pin one saved version; omitted = the latest, pinned at start. */
293
+ versionId?: string | null | undefined;
294
+ variables?: Record<string, JsonValue> | undefined;
295
+ }
296
+ /** One part of an agent and whether this session's CLI carries it. */
297
+ interface SessionAgentPart {
298
+ part: "instructions" | "skills" | "tools";
299
+ loaded: number;
300
+ total: number;
301
+ }
302
+ /**
303
+ * The agent a session runs with. Recorded at start and never drifts: every
304
+ * later turn reloads the SAME bundle (same version, same hash).
305
+ */
306
+ interface SessionAgent {
307
+ agentId: string;
308
+ versionId: string | null;
309
+ versionNumber: number | null;
310
+ name: string;
311
+ definitionHash: string;
312
+ loaded: SessionAgentPart[];
313
+ /** What could not be carried, with the reason. */
314
+ unavailable: {
315
+ kind: string;
316
+ name: string;
317
+ reason: string;
318
+ }[];
319
+ /** The skills it carries (labels) and the tools it serves (names) — the agent's own set. */
320
+ skills?: string[] | undefined;
321
+ tools?: string[] | undefined;
322
+ /** The person's variable values, kept so "Update to vN" can reuse them. */
323
+ variables?: Record<string, JsonValue> | undefined;
324
+ /**
325
+ * The CLI must be TOLD in the next prompt (a delimited block): a Codex
326
+ * takeover or agent switch (Codex ignores developer_instructions on resume),
327
+ * or a Codex compaction that dropped the block. Cleared once delivered.
328
+ */
329
+ blockDue?: boolean | undefined;
330
+ /** When the block (or native instructions) last reached the CLI. */
331
+ deliveredAt?: string | null | undefined;
332
+ }
333
+ /** Whether this host can reach AI Matrx as a signed-in person. */
334
+ interface AgentAccess {
335
+ signedIn: boolean;
336
+ userId: string | null;
337
+ organizationId: string | null;
338
+ /** True when the host was started with no AI Matrx connection at all. */
339
+ configured: boolean;
340
+ }
341
+ /** A catalogue read the picker asks the host to make (PostgREST RPC shape). */
342
+ interface AgentCatalogRpcRequest {
343
+ fn: string;
344
+ args?: Record<string, unknown> | undefined;
345
+ count?: "exact" | "planned" | "estimated" | undefined;
346
+ range?: [number, number] | undefined;
347
+ order?: {
348
+ column: string;
349
+ ascending?: boolean | undefined;
350
+ } | undefined;
351
+ }
352
+ interface AgentCatalogRpcResult {
353
+ data: unknown;
354
+ error: {
355
+ message: string;
356
+ code?: string | undefined;
357
+ details?: string | null | undefined;
358
+ hint?: string | null | undefined;
359
+ } | null;
360
+ count?: number | null;
361
+ }
362
+ /** What a picker needs about one agent — the LIGHT read (no skills, no tools). */
363
+ interface AgentDetails {
364
+ agentId: string;
365
+ name: string;
366
+ /** Variable declarations as authored (camelCase). */
367
+ variables: Record<string, JsonValue>[];
368
+ /** Newest first. */
369
+ versions: {
370
+ id: string;
371
+ versionNumber: number;
372
+ changedAt: string | null;
373
+ }[];
374
+ /** The version "Latest" resolves to right now. */
375
+ latestVersionNumber: number | null;
376
+ latestVersionId: string | null;
280
377
  }
281
378
  interface TakeoverInput {
282
379
  provider: CodingProvider;
283
380
  providerSessionId: string;
284
381
  cwd: string;
285
382
  title?: string | undefined;
383
+ /** Continue the chat WITH an AI Matrx agent ("Continue with agent"). */
384
+ agent?: AgentSelection | null | undefined;
286
385
  }
287
386
  interface SendResult {
288
387
  session: CodingSession;
@@ -353,6 +452,18 @@ interface CodingSessionsApi {
353
452
  model?: string | null;
354
453
  effort?: string | null;
355
454
  }): Promise<CodingSession>;
455
+ /** Is this host signed in to AI Matrx (so agents can load)? */
456
+ agentAccess(): Promise<AgentAccess>;
457
+ /** One allowlisted agent-catalogue read, made by the host as the signed-in person. */
458
+ agentCatalogRpc(request: AgentCatalogRpcRequest): Promise<AgentCatalogRpcResult>;
459
+ /** An agent's variables and saved versions, for the New session form. */
460
+ agentDetails(agentId: string): Promise<AgentDetails>;
461
+ /**
462
+ * Load a different agent into a session from its next message on (or
463
+ * remove it, with `null`). Claude reads it every turn; Codex is told in the
464
+ * next prompt.
465
+ */
466
+ setAgent(sessionId: string, agent: AgentSelection | null): Promise<CodingSession>;
356
467
  }
357
468
  type RawTranscript = {
358
469
  available: true;
@@ -527,4 +638,4 @@ declare function friendlyToolName(name: string): string;
527
638
  /** The key argument, for the card's subtitle. null when there is none worth showing. */
528
639
  declare function toolSubtitle(name: string, input: unknown): string | null;
529
640
 
530
- export { type ActiveElsewhere, type Billing, type BinarySource, CODING_PROVIDERS, type ChatPreference, type ChatSearchHit, type ChatSearchResult, type ClaudeNormalizer, type CodexRolloutNormalizer, type CodexStreamNormalizer, type CodingEvent, type CodingProvider, type CodingSession, type CodingSessionsApi, type CodingSessionsMethod, type CodingSessionsTransport, type DiscoveredSession, type FolderCheck, type HistoryOptions, type LineSplitter, type ModelOption, type OpenTarget, PROVIDER_LABEL, type ProviderBinary, type ProviderProblem, type ProviderStatus, type QuotaWindow, type RawTranscript, type RecentFolder, type RunRecord, type RunStatus, type RunUsage, type SendResult, type SessionHistory, type SessionOrigin, type StartInput, TERMINAL_RUN_STATUSES, type TakeoverInput, type TranscriptBuilder, type TranscriptItem, type TransportStatus, type WebSocketTransportOptions, chatKey, createClaudeNormalizer, createCodexRolloutNormalizer, createCodexStreamNormalizer, createLineSplitter, createTranscriptBuilder, createWebSocketTransport, friendlyToolName, isSyntheticClaudeUserText, isTerminalRunStatus, parseJsonl, parseMcpToolName, stripCodexInjectedContext, toolSubtitle };
641
+ export { type ActiveElsewhere, type AgentAccess, type AgentCatalogRpcRequest, type AgentCatalogRpcResult, type AgentDetails, type AgentSelection, type Billing, type BinarySource, CODING_PROVIDERS, type ChatPreference, type ChatSearchHit, type ChatSearchResult, type ClaudeNormalizer, type CodexRolloutNormalizer, type CodexStreamNormalizer, type CodingEvent, type CodingProvider, type CodingSession, type CodingSessionsApi, type CodingSessionsMethod, type CodingSessionsTransport, type DiscoveredSession, type FolderCheck, type HistoryOptions, type LineSplitter, type ModelOption, type OpenTarget, PROVIDER_LABEL, type ProviderBinary, type ProviderProblem, type ProviderStatus, type QuotaWindow, type RawTranscript, type RecentFolder, type RunRecord, type RunStatus, type RunUsage, type SendResult, type SessionAgent, type SessionAgentPart, type SessionHistory, type SessionOrigin, type StartInput, TERMINAL_RUN_STATUSES, type TakeoverInput, type TranscriptBuilder, type TranscriptItem, type TransportStatus, type WebSocketTransportOptions, chatKey, createClaudeNormalizer, createCodexRolloutNormalizer, createCodexStreamNormalizer, createLineSplitter, createTranscriptBuilder, createWebSocketTransport, friendlyToolName, isSyntheticClaudeUserText, isTerminalRunStatus, parseJsonl, parseMcpToolName, stripCodexInjectedContext, toolSubtitle };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { JsonValue } from '@ai-matrx/agents/portable';
1
2
  import { ChatMessage } from '@ai-matrx/chat';
2
3
 
3
4
  /**
@@ -6,6 +7,7 @@ import { ChatMessage } from '@ai-matrx/chat';
6
7
  * touches Node or the DOM, and every value is JSON-serializable because it
7
8
  * crosses a transport (WebSocket today, desktop IPC later).
8
9
  */
10
+
9
11
  /** The coding agents this package drives. "coding session" is the canonical
10
12
  * platform term (chat.coding_session, the Coding Session Bridge). */
11
13
  type CodingProvider = "claude" | "codex";
@@ -197,6 +199,10 @@ interface CodingSession {
197
199
  lastRunStatus: RunStatus | null;
198
200
  /** Prompts waiting for the active run to finish, oldest first. */
199
201
  queued: string[];
202
+ /** The AI Matrx agent loaded into every run of this session, when one was picked. */
203
+ agent?: SessionAgent | null | undefined;
204
+ /** Codex must be told, in the next prompt, that an earlier agent no longer applies. */
205
+ agentRemovedDue?: boolean | undefined;
200
206
  }
201
207
  /**
202
208
  * One normalized transcript item — the same shape from Claude and Codex, from
@@ -277,12 +283,105 @@ interface StartInput {
277
283
  prompt: string;
278
284
  model?: string | null | undefined;
279
285
  effort?: string | null | undefined;
286
+ /** An AI Matrx agent to load into the CLI. Needs the host's `agents` credentials. */
287
+ agent?: AgentSelection | null | undefined;
288
+ }
289
+ /** Which AI Matrx agent a new session loads, and the person's variable values. */
290
+ interface AgentSelection {
291
+ agentId: string;
292
+ /** Pin one saved version; omitted = the latest, pinned at start. */
293
+ versionId?: string | null | undefined;
294
+ variables?: Record<string, JsonValue> | undefined;
295
+ }
296
+ /** One part of an agent and whether this session's CLI carries it. */
297
+ interface SessionAgentPart {
298
+ part: "instructions" | "skills" | "tools";
299
+ loaded: number;
300
+ total: number;
301
+ }
302
+ /**
303
+ * The agent a session runs with. Recorded at start and never drifts: every
304
+ * later turn reloads the SAME bundle (same version, same hash).
305
+ */
306
+ interface SessionAgent {
307
+ agentId: string;
308
+ versionId: string | null;
309
+ versionNumber: number | null;
310
+ name: string;
311
+ definitionHash: string;
312
+ loaded: SessionAgentPart[];
313
+ /** What could not be carried, with the reason. */
314
+ unavailable: {
315
+ kind: string;
316
+ name: string;
317
+ reason: string;
318
+ }[];
319
+ /** The skills it carries (labels) and the tools it serves (names) — the agent's own set. */
320
+ skills?: string[] | undefined;
321
+ tools?: string[] | undefined;
322
+ /** The person's variable values, kept so "Update to vN" can reuse them. */
323
+ variables?: Record<string, JsonValue> | undefined;
324
+ /**
325
+ * The CLI must be TOLD in the next prompt (a delimited block): a Codex
326
+ * takeover or agent switch (Codex ignores developer_instructions on resume),
327
+ * or a Codex compaction that dropped the block. Cleared once delivered.
328
+ */
329
+ blockDue?: boolean | undefined;
330
+ /** When the block (or native instructions) last reached the CLI. */
331
+ deliveredAt?: string | null | undefined;
332
+ }
333
+ /** Whether this host can reach AI Matrx as a signed-in person. */
334
+ interface AgentAccess {
335
+ signedIn: boolean;
336
+ userId: string | null;
337
+ organizationId: string | null;
338
+ /** True when the host was started with no AI Matrx connection at all. */
339
+ configured: boolean;
340
+ }
341
+ /** A catalogue read the picker asks the host to make (PostgREST RPC shape). */
342
+ interface AgentCatalogRpcRequest {
343
+ fn: string;
344
+ args?: Record<string, unknown> | undefined;
345
+ count?: "exact" | "planned" | "estimated" | undefined;
346
+ range?: [number, number] | undefined;
347
+ order?: {
348
+ column: string;
349
+ ascending?: boolean | undefined;
350
+ } | undefined;
351
+ }
352
+ interface AgentCatalogRpcResult {
353
+ data: unknown;
354
+ error: {
355
+ message: string;
356
+ code?: string | undefined;
357
+ details?: string | null | undefined;
358
+ hint?: string | null | undefined;
359
+ } | null;
360
+ count?: number | null;
361
+ }
362
+ /** What a picker needs about one agent — the LIGHT read (no skills, no tools). */
363
+ interface AgentDetails {
364
+ agentId: string;
365
+ name: string;
366
+ /** Variable declarations as authored (camelCase). */
367
+ variables: Record<string, JsonValue>[];
368
+ /** Newest first. */
369
+ versions: {
370
+ id: string;
371
+ versionNumber: number;
372
+ changedAt: string | null;
373
+ }[];
374
+ /** The version "Latest" resolves to right now. */
375
+ latestVersionNumber: number | null;
376
+ latestVersionId: string | null;
280
377
  }
281
378
  interface TakeoverInput {
282
379
  provider: CodingProvider;
283
380
  providerSessionId: string;
284
381
  cwd: string;
285
382
  title?: string | undefined;
383
+ /** Continue the chat WITH an AI Matrx agent ("Continue with agent"). */
384
+ agent?: AgentSelection | null | undefined;
286
385
  }
287
386
  interface SendResult {
288
387
  session: CodingSession;
@@ -353,6 +452,18 @@ interface CodingSessionsApi {
353
452
  model?: string | null;
354
453
  effort?: string | null;
355
454
  }): Promise<CodingSession>;
455
+ /** Is this host signed in to AI Matrx (so agents can load)? */
456
+ agentAccess(): Promise<AgentAccess>;
457
+ /** One allowlisted agent-catalogue read, made by the host as the signed-in person. */
458
+ agentCatalogRpc(request: AgentCatalogRpcRequest): Promise<AgentCatalogRpcResult>;
459
+ /** An agent's variables and saved versions, for the New session form. */
460
+ agentDetails(agentId: string): Promise<AgentDetails>;
461
+ /**
462
+ * Load a different agent into a session from its next message on (or
463
+ * remove it, with `null`). Claude reads it every turn; Codex is told in the
464
+ * next prompt.
465
+ */
466
+ setAgent(sessionId: string, agent: AgentSelection | null): Promise<CodingSession>;
356
467
  }
357
468
  type RawTranscript = {
358
469
  available: true;
@@ -527,4 +638,4 @@ declare function friendlyToolName(name: string): string;
527
638
  /** The key argument, for the card's subtitle. null when there is none worth showing. */
528
639
  declare function toolSubtitle(name: string, input: unknown): string | null;
529
640
 
530
- export { type ActiveElsewhere, type Billing, type BinarySource, CODING_PROVIDERS, type ChatPreference, type ChatSearchHit, type ChatSearchResult, type ClaudeNormalizer, type CodexRolloutNormalizer, type CodexStreamNormalizer, type CodingEvent, type CodingProvider, type CodingSession, type CodingSessionsApi, type CodingSessionsMethod, type CodingSessionsTransport, type DiscoveredSession, type FolderCheck, type HistoryOptions, type LineSplitter, type ModelOption, type OpenTarget, PROVIDER_LABEL, type ProviderBinary, type ProviderProblem, type ProviderStatus, type QuotaWindow, type RawTranscript, type RecentFolder, type RunRecord, type RunStatus, type RunUsage, type SendResult, type SessionHistory, type SessionOrigin, type StartInput, TERMINAL_RUN_STATUSES, type TakeoverInput, type TranscriptBuilder, type TranscriptItem, type TransportStatus, type WebSocketTransportOptions, chatKey, createClaudeNormalizer, createCodexRolloutNormalizer, createCodexStreamNormalizer, createLineSplitter, createTranscriptBuilder, createWebSocketTransport, friendlyToolName, isSyntheticClaudeUserText, isTerminalRunStatus, parseJsonl, parseMcpToolName, stripCodexInjectedContext, toolSubtitle };
641
+ export { type ActiveElsewhere, type AgentAccess, type AgentCatalogRpcRequest, type AgentCatalogRpcResult, type AgentDetails, type AgentSelection, type Billing, type BinarySource, CODING_PROVIDERS, type ChatPreference, type ChatSearchHit, type ChatSearchResult, type ClaudeNormalizer, type CodexRolloutNormalizer, type CodexStreamNormalizer, type CodingEvent, type CodingProvider, type CodingSession, type CodingSessionsApi, type CodingSessionsMethod, type CodingSessionsTransport, type DiscoveredSession, type FolderCheck, type HistoryOptions, type LineSplitter, type ModelOption, type OpenTarget, PROVIDER_LABEL, type ProviderBinary, type ProviderProblem, type ProviderStatus, type QuotaWindow, type RawTranscript, type RecentFolder, type RunRecord, type RunStatus, type RunUsage, type SendResult, type SessionAgent, type SessionAgentPart, type SessionHistory, type SessionOrigin, type StartInput, TERMINAL_RUN_STATUSES, type TakeoverInput, type TranscriptBuilder, type TranscriptItem, type TransportStatus, type WebSocketTransportOptions, chatKey, createClaudeNormalizer, createCodexRolloutNormalizer, createCodexStreamNormalizer, createLineSplitter, createTranscriptBuilder, createWebSocketTransport, friendlyToolName, isSyntheticClaudeUserText, isTerminalRunStatus, parseJsonl, parseMcpToolName, stripCodexInjectedContext, toolSubtitle };
package/dist/index.js CHANGED
@@ -205,6 +205,20 @@ function createClaudeNormalizer() {
205
205
  };
206
206
  }
207
207
 
208
+ // src/normalize/agent-block.ts
209
+ var AGENT_BLOCK_MARKER = "<ai_matrx_agent ";
210
+ function stripAgentBlock(text) {
211
+ const removed = text.match(/^<ai_matrx_agent_removed>[\s\S]*?<\/ai_matrx_agent_removed>\s*/);
212
+ if (removed) return text.slice(removed[0].length);
213
+ if (!text.startsWith(AGENT_BLOCK_MARKER)) return text;
214
+ const end = text.indexOf("</ai_matrx_agent>");
215
+ if (end < 0) return text;
216
+ let rest = text.slice(end + "</ai_matrx_agent>".length);
217
+ const skills = rest.match(/^\s*<skills_instructions>[\s\S]*?<\/skills_instructions>/);
218
+ if (skills) rest = rest.slice(skills[0].length);
219
+ return rest.replace(/^\s+/, "");
220
+ }
221
+
208
222
  // src/normalize/codex.ts
209
223
  function isObject2(value) {
210
224
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -380,7 +394,7 @@ function rolloutItem(item, fallbackId, at) {
380
394
  const id = str2(item.id) ?? fallbackId;
381
395
  switch (item.type) {
382
396
  case "UserMessage": {
383
- const text = stripCodexInjectedContext(itemText(item.content));
397
+ const text = stripCodexInjectedContext(stripAgentBlock(itemText(item.content)));
384
398
  return text.trim() ? [{ kind: "user", id, text, at }] : [];
385
399
  }
386
400
  case "AgentMessage": {
@@ -463,7 +477,7 @@ function createCodexRolloutNormalizer() {
463
477
  return rolloutItem(payload.item, fallbackId, at);
464
478
  }
465
479
  if (payload.type === "user_message" && !appItems) {
466
- const text = stripCodexInjectedContext(str2(payload.message) ?? "");
480
+ const text = stripCodexInjectedContext(stripAgentBlock(str2(payload.message) ?? ""));
467
481
  return text.trim() ? [{ kind: "user", id: fallbackId, text, at }] : [];
468
482
  }
469
483
  return [];