agentix-cli 0.28.0 → 0.30.0

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 (101) hide show
  1. package/README.md +29 -3
  2. package/dist/{App-CKPH3HHF.js → App-IEQXWJ7B.js} +2 -2
  3. package/dist/{ChatApp-MX7IG4K2.js → ChatApp-NWOSAP5U.js} +2 -2
  4. package/dist/{agent-2U574KBZ.js → agent-SPE7Q7MD.js} +2 -2
  5. package/dist/{board-dashboard-QR7CVTKA.js → board-dashboard-K4DM32SO.js} +4 -4
  6. package/dist/{chunk-VIH7ARPF.js → chunk-42DCRKUD.js} +130 -129
  7. package/dist/chunk-42DCRKUD.js.map +1 -0
  8. package/dist/chunk-45BLFNDG.js +170 -0
  9. package/dist/chunk-45BLFNDG.js.map +1 -0
  10. package/dist/{chunk-ZMYGXHPT.js → chunk-4KXBUORV.js} +2 -2
  11. package/dist/{chunk-H2QQU2XV.js → chunk-AUNDQPDR.js} +2 -2
  12. package/dist/{chunk-5IA2CYHN.js → chunk-DI7FMCDK.js} +2 -2
  13. package/dist/chunk-DWADWDMU.js +96 -0
  14. package/dist/chunk-DWADWDMU.js.map +1 -0
  15. package/dist/{chunk-YLBERT7N.js → chunk-EL3J74N2.js} +2 -2
  16. package/dist/{chunk-S2MNL5V6.js → chunk-GK7XAM3D.js} +2 -2
  17. package/dist/chunk-GK7XAM3D.js.map +1 -0
  18. package/dist/{chunk-P5ZBBEPL.js → chunk-GMNKJXTR.js} +1 -1
  19. package/dist/chunk-GMNKJXTR.js.map +1 -0
  20. package/dist/{chunk-E3UJHQGN.js → chunk-GUBMLV34.js} +142 -130
  21. package/dist/chunk-GUBMLV34.js.map +1 -0
  22. package/dist/{chunk-64CAIB3C.js → chunk-IVQO43U2.js} +2 -2
  23. package/dist/{chunk-G2HMRDUQ.js → chunk-JKYMXLYL.js} +2 -2
  24. package/dist/{chunk-YLGIZRHV.js → chunk-MGNJWBVP.js} +2 -2
  25. package/dist/{chunk-3LYM22IV.js → chunk-Q7CZIRBB.js} +2 -2
  26. package/dist/{chunk-SCTIUFL4.js → chunk-SC5DIKBB.js} +2 -2
  27. package/dist/{chunk-MHIMGM4G.js → chunk-UU4WOZNR.js} +2 -2
  28. package/dist/{chunk-QHTQPBHU.js → chunk-V4HURNMX.js} +2 -2
  29. package/dist/cli.js +1 -1
  30. package/dist/cli.js.map +1 -1
  31. package/dist/client-5Z3URGPY.js +2 -0
  32. package/dist/config-ORSGLVRW.js +2 -0
  33. package/dist/config-mutator-JB3S2E7H.js +2 -0
  34. package/dist/doctor-FS2BX6H4.js +2 -0
  35. package/dist/index.d.ts +187 -185
  36. package/dist/index.js +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/program-DWZAI4GY.js +2 -0
  39. package/dist/query-3HXGBKGM.js +2 -0
  40. package/dist/registry-EJRWAJYG.js +2 -0
  41. package/dist/request-planner-BCOXUAPA.js +2 -0
  42. package/dist/request-planner-BCOXUAPA.js.map +1 -0
  43. package/dist/{review-candidates-RQU5KNZM.js → review-candidates-O2PS7L3B.js} +2 -2
  44. package/dist/routing-5K7PGHPL.js +2 -0
  45. package/dist/scheduler-DSAOMV4O.js +2 -0
  46. package/dist/seat-FZRNRAHQ.js +2 -0
  47. package/dist/{select-X4KVMOP5.js → select-SOJYFAMI.js} +2 -2
  48. package/dist/wiki-34XVI32N.js +2 -0
  49. package/dist/workspace-setup-G6KGWPHY.js +2 -0
  50. package/package.json +1 -1
  51. package/dist/chunk-67Q4DCPS.js +0 -54
  52. package/dist/chunk-67Q4DCPS.js.map +0 -1
  53. package/dist/chunk-E3UJHQGN.js.map +0 -1
  54. package/dist/chunk-I3SIXTJO.js +0 -44
  55. package/dist/chunk-I3SIXTJO.js.map +0 -1
  56. package/dist/chunk-P5ZBBEPL.js.map +0 -1
  57. package/dist/chunk-S2MNL5V6.js.map +0 -1
  58. package/dist/chunk-ULLAE6LE.js +0 -157
  59. package/dist/chunk-ULLAE6LE.js.map +0 -1
  60. package/dist/chunk-VIH7ARPF.js.map +0 -1
  61. package/dist/client-ZLSXGPTV.js +0 -2
  62. package/dist/config-HMW3EBZL.js +0 -2
  63. package/dist/config-mutator-4SZ5YEVD.js +0 -2
  64. package/dist/doctor-LRYV3QLK.js +0 -2
  65. package/dist/program-GSZ5AYAM.js +0 -2
  66. package/dist/query-SQDHE4HV.js +0 -2
  67. package/dist/registry-LE6FWYZC.js +0 -2
  68. package/dist/routing-ILERJXB6.js +0 -2
  69. package/dist/scheduler-BFM3EINS.js +0 -2
  70. package/dist/seat-7WM7II2B.js +0 -2
  71. package/dist/wiki-2AUFSIKO.js +0 -2
  72. package/dist/workspace-setup-B3F3TUDE.js +0 -2
  73. /package/dist/{App-CKPH3HHF.js.map → App-IEQXWJ7B.js.map} +0 -0
  74. /package/dist/{ChatApp-MX7IG4K2.js.map → ChatApp-NWOSAP5U.js.map} +0 -0
  75. /package/dist/{agent-2U574KBZ.js.map → agent-SPE7Q7MD.js.map} +0 -0
  76. /package/dist/{board-dashboard-QR7CVTKA.js.map → board-dashboard-K4DM32SO.js.map} +0 -0
  77. /package/dist/{chunk-ZMYGXHPT.js.map → chunk-4KXBUORV.js.map} +0 -0
  78. /package/dist/{chunk-H2QQU2XV.js.map → chunk-AUNDQPDR.js.map} +0 -0
  79. /package/dist/{chunk-5IA2CYHN.js.map → chunk-DI7FMCDK.js.map} +0 -0
  80. /package/dist/{chunk-YLBERT7N.js.map → chunk-EL3J74N2.js.map} +0 -0
  81. /package/dist/{chunk-64CAIB3C.js.map → chunk-IVQO43U2.js.map} +0 -0
  82. /package/dist/{chunk-G2HMRDUQ.js.map → chunk-JKYMXLYL.js.map} +0 -0
  83. /package/dist/{chunk-YLGIZRHV.js.map → chunk-MGNJWBVP.js.map} +0 -0
  84. /package/dist/{chunk-3LYM22IV.js.map → chunk-Q7CZIRBB.js.map} +0 -0
  85. /package/dist/{chunk-SCTIUFL4.js.map → chunk-SC5DIKBB.js.map} +0 -0
  86. /package/dist/{chunk-MHIMGM4G.js.map → chunk-UU4WOZNR.js.map} +0 -0
  87. /package/dist/{chunk-QHTQPBHU.js.map → chunk-V4HURNMX.js.map} +0 -0
  88. /package/dist/{client-ZLSXGPTV.js.map → client-5Z3URGPY.js.map} +0 -0
  89. /package/dist/{config-HMW3EBZL.js.map → config-ORSGLVRW.js.map} +0 -0
  90. /package/dist/{config-mutator-4SZ5YEVD.js.map → config-mutator-JB3S2E7H.js.map} +0 -0
  91. /package/dist/{doctor-LRYV3QLK.js.map → doctor-FS2BX6H4.js.map} +0 -0
  92. /package/dist/{program-GSZ5AYAM.js.map → program-DWZAI4GY.js.map} +0 -0
  93. /package/dist/{query-SQDHE4HV.js.map → query-3HXGBKGM.js.map} +0 -0
  94. /package/dist/{registry-LE6FWYZC.js.map → registry-EJRWAJYG.js.map} +0 -0
  95. /package/dist/{review-candidates-RQU5KNZM.js.map → review-candidates-O2PS7L3B.js.map} +0 -0
  96. /package/dist/{routing-ILERJXB6.js.map → routing-5K7PGHPL.js.map} +0 -0
  97. /package/dist/{scheduler-BFM3EINS.js.map → scheduler-DSAOMV4O.js.map} +0 -0
  98. /package/dist/{seat-7WM7II2B.js.map → seat-FZRNRAHQ.js.map} +0 -0
  99. /package/dist/{select-X4KVMOP5.js.map → select-SOJYFAMI.js.map} +0 -0
  100. /package/dist/{wiki-2AUFSIKO.js.map → wiki-34XVI32N.js.map} +0 -0
  101. /package/dist/{workspace-setup-B3F3TUDE.js.map → workspace-setup-G6KGWPHY.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1585,18 +1585,16 @@ declare const agentConfigSchema: z.ZodObject<{
1585
1585
  * (right for chatty agents whose reasoning shouldn't land as a comment).
1586
1586
  * Unset → fall back to the channel default. */
1587
1587
  gitlabAutoReply: z.ZodOptional<z.ZodBoolean>;
1588
- /** When true, this agent's claude-code dispatches reuse a long-lived
1589
- * subprocess per (channel, chatId) instead of spawning a fresh
1590
- * `claude -p` per turn. Driven over stdin via stream-json input,
1591
- * which keeps the prompt cache warm across turns within a chat
1592
- * (turn 1 cache_create=12897 → turn 2 cache_create=20 + cache_read
1593
- * =24575 in the 2026-05-03 spike — 3-5× latency win on chat-shaped
1594
- * workloads). When the registry can't allocate a slot (global or
1595
- * per-agent cap exceeded), the dispatch falls back to spawn-per-task
1596
- * silently with a warning log. Other tiers (sdk, orchestrator)
1597
- * ignore this flag. Default false until the persistent path
1598
- * finishes its soak; flip per-agent first, then per-fleet.
1599
- * See docs/architecture/persistent-claude-process.md for the design. */
1588
+ /** Opt into process reuse for claude-code (stream-json) or codex-cli
1589
+ * (app-server), or opencode (dedicated v2 server). Conversations have isolated processes. Unsupported Codex
1590
+ * versions fall back to exec before submitting any turn. Other tiers
1591
+ * ignore this flag. Codex loads the operator's Codex config, unlike exec's
1592
+ * --ignore-user-config path: review additional MCP servers before enabling.
1593
+ * Codex and OpenCode each use an 8-process cap and 5-minute idle eviction; processPool
1594
+ * settings apply to Claude only. Default false for gradual rollout.
1595
+ * See docs/architecture/persistent-codex-process.md and
1596
+ * docs/architecture/persistent-claude-process.md and
1597
+ * docs/architecture/persistent-opencode-process.md for details. */
1600
1598
  persistentProcess: z.ZodDefault<z.ZodBoolean>;
1601
1599
  queueMode: z.ZodDefault<z.ZodEnum<["collect", "followup", "drop"]>>;
1602
1600
  heartbeat: z.ZodDefault<z.ZodObject<{
@@ -2086,18 +2084,16 @@ declare const daemonConfigSchema: z.ZodObject<{
2086
2084
  * (right for chatty agents whose reasoning shouldn't land as a comment).
2087
2085
  * Unset → fall back to the channel default. */
2088
2086
  gitlabAutoReply: z.ZodOptional<z.ZodBoolean>;
2089
- /** When true, this agent's claude-code dispatches reuse a long-lived
2090
- * subprocess per (channel, chatId) instead of spawning a fresh
2091
- * `claude -p` per turn. Driven over stdin via stream-json input,
2092
- * which keeps the prompt cache warm across turns within a chat
2093
- * (turn 1 cache_create=12897 → turn 2 cache_create=20 + cache_read
2094
- * =24575 in the 2026-05-03 spike — 3-5× latency win on chat-shaped
2095
- * workloads). When the registry can't allocate a slot (global or
2096
- * per-agent cap exceeded), the dispatch falls back to spawn-per-task
2097
- * silently with a warning log. Other tiers (sdk, orchestrator)
2098
- * ignore this flag. Default false until the persistent path
2099
- * finishes its soak; flip per-agent first, then per-fleet.
2100
- * See docs/architecture/persistent-claude-process.md for the design. */
2087
+ /** Opt into process reuse for claude-code (stream-json) or codex-cli
2088
+ * (app-server), or opencode (dedicated v2 server). Conversations have isolated processes. Unsupported Codex
2089
+ * versions fall back to exec before submitting any turn. Other tiers
2090
+ * ignore this flag. Codex loads the operator's Codex config, unlike exec's
2091
+ * --ignore-user-config path: review additional MCP servers before enabling.
2092
+ * Codex and OpenCode each use an 8-process cap and 5-minute idle eviction; processPool
2093
+ * settings apply to Claude only. Default false for gradual rollout.
2094
+ * See docs/architecture/persistent-codex-process.md and
2095
+ * docs/architecture/persistent-claude-process.md and
2096
+ * docs/architecture/persistent-opencode-process.md for details. */
2101
2097
  persistentProcess: z.ZodDefault<z.ZodBoolean>;
2102
2098
  queueMode: z.ZodDefault<z.ZodEnum<["collect", "followup", "drop"]>>;
2103
2099
  heartbeat: z.ZodDefault<z.ZodObject<{
@@ -6379,6 +6375,159 @@ interface FriendlyError {
6379
6375
  raw?: string;
6380
6376
  }
6381
6377
 
6378
+ /**
6379
+ * Verified channel context — facts the channel adapter knows for certain.
6380
+ * Prevents agents from hallucinating about their environment.
6381
+ */
6382
+ interface ChannelMeta {
6383
+ /** Channel name */
6384
+ channel: string;
6385
+ /** Verified agents/bots present in this chat/group/project */
6386
+ agents?: Array<{
6387
+ id: string;
6388
+ name: string;
6389
+ handle?: string;
6390
+ }>;
6391
+ /** Project path (GitLab) or group topic */
6392
+ project?: string;
6393
+ /** Issue/MR context (GitLab) */
6394
+ issue?: {
6395
+ type: string;
6396
+ iid: string;
6397
+ title: string;
6398
+ };
6399
+ /** Channel-specific facts (e.g., pipeline status, group description) */
6400
+ facts?: string[];
6401
+ }
6402
+ interface IncomingMessage {
6403
+ id: string;
6404
+ channel: string;
6405
+ accountId: string;
6406
+ sender: {
6407
+ id: string;
6408
+ name: string;
6409
+ username?: string;
6410
+ /** True when the origin is another bot account (Telegram `from.is_bot`).
6411
+ * Used by the router to apply strict @-mention-only routing — prevents
6412
+ * cross-daemon cascades from bare-word matches in bot replies. */
6413
+ isBot?: boolean;
6414
+ };
6415
+ group?: {
6416
+ id: string;
6417
+ name: string;
6418
+ };
6419
+ text: string;
6420
+ replyTo?: string;
6421
+ replyToText?: string;
6422
+ timestamp: Date;
6423
+ media?: {
6424
+ path: string;
6425
+ type: string;
6426
+ fileName?: string;
6427
+ };
6428
+ raw?: unknown;
6429
+ resolvedAgent?: string;
6430
+ preferNode?: string;
6431
+ channelMeta?: ChannelMeta;
6432
+ /** Correlator threaded by the workflow engine. When a workflow dispatches
6433
+ * an agent, this carries the run id through the pipeline so post:response
6434
+ * can re-enter the engine with `kind: agentResult` transitions. Opaque
6435
+ * everywhere outside src/workflows/. */
6436
+ workflowRunId?: string;
6437
+ /** Phase 1 / 6 — when set, identifies the intent-ledger decision row
6438
+ * this message corresponds to. The agent registry calls
6439
+ * `ledger.recordResolution(...)` when the dispatched task completes,
6440
+ * so Inv-ActiveTaskSafety's "decision in flight" check can clear.
6441
+ * Set by the channel adapter (gitlab, router) right after
6442
+ * recordGitLabTargetDispatch / recordRouterDispatch returns the
6443
+ * decision row. Undefined when the dispatch was deduped/halted by
6444
+ * the ledger (no resolution to write) or when the source is in
6445
+ * mode=off. */
6446
+ intentRef?: {
6447
+ eventId: string;
6448
+ decidedBy: string;
6449
+ };
6450
+ /** Path to the project root whose runbook (CLAUDE.md / AGENTS.md / etc.)
6451
+ * the agent should consult for this task. Set by the gitlab/github
6452
+ * adapters when a project rule resolves a `runbook:` path. The agent
6453
+ * registry reads the file set into the cacheable system prefix.
6454
+ * Undefined when no rule matched — agent uses its own workspace's
6455
+ * CLAUDE.md as before. */
6456
+ runbookPath?: string;
6457
+ /** Override list of files the registry should read from runbookPath.
6458
+ * Carried alongside the path so per-project customisation applies
6459
+ * without the registry re-reading the rule. */
6460
+ runbookFiles?: string[];
6461
+ }
6462
+ interface OutgoingMessage {
6463
+ channel: string;
6464
+ chatId: string;
6465
+ text: string;
6466
+ replyTo?: string;
6467
+ parseMode?: "markdown" | "html" | "plain";
6468
+ agentId?: string;
6469
+ poll?: {
6470
+ name: string;
6471
+ values: string[];
6472
+ selectableCount?: number;
6473
+ };
6474
+ media?: {
6475
+ type: "image" | "document" | "audio" | "video";
6476
+ url: string;
6477
+ caption?: string;
6478
+ mimetype?: string;
6479
+ fileName?: string;
6480
+ };
6481
+ /** URL inline buttons (Phase 1). Telegram renders an inline_keyboard;
6482
+ * channels without button support ignore them. */
6483
+ buttons?: Array<{
6484
+ label: string;
6485
+ url: string;
6486
+ }>;
6487
+ }
6488
+ interface ChannelAdapter {
6489
+ readonly name: string;
6490
+ /** Start polling or webhook listener */
6491
+ start(): Promise<void>;
6492
+ /** Stop the adapter gracefully */
6493
+ stop(): Promise<void>;
6494
+ /** Send a message back to a chat */
6495
+ send(msg: OutgoingMessage): Promise<string | void>;
6496
+ /** Edit an existing message (returns false if not supported) */
6497
+ editMessage?(chatId: string, messageId: string, text: string, parseMode?: string): Promise<boolean>;
6498
+ /** Send typing/action indicator */
6499
+ sendTyping?(chatId: string): Promise<void>;
6500
+ /** React to a message with an emoji (e.g., 👀 for seen) */
6501
+ react?(chatId: string, messageId: string, emoji?: string): Promise<void>;
6502
+ /** Register handler for incoming messages */
6503
+ onMessage(handler: (msg: IncomingMessage) => Promise<void>): void;
6504
+ /** Get verified context for a chat (optional — channels implement what they can) */
6505
+ getChannelMeta?(chatId: string): Promise<ChannelMeta | undefined>;
6506
+ /** Fetch the most recent messages from the live channel for cold-start
6507
+ * session seeding. Called once per (agent, channel, chatId, day) when a
6508
+ * fresh session is created — never on warm cache hits. Bounded by
6509
+ * maxMessages and maxChars (enforced by the caller). Channels return their
6510
+ * own externalId so SessionStore can dedup against re-seeds. */
6511
+ seedHistory?(chatId: string, opts: {
6512
+ sinceISO?: string;
6513
+ maxMessages: number;
6514
+ maxChars: number;
6515
+ }): Promise<Array<SeededMessage>>;
6516
+ }
6517
+ /** A message returned by seedHistory — flat, channel-agnostic. */
6518
+ interface SeededMessage {
6519
+ role: "user" | "agent";
6520
+ name: string;
6521
+ content: string;
6522
+ timestamp: string;
6523
+ externalId?: string;
6524
+ /** Optional channel-side account/bot identity that handled this message
6525
+ * (e.g., Telegram accountId "acme_cx_bot"). Captured by adapters that
6526
+ * shadow-log outbound, so seeded history preserves the audit trail of
6527
+ * which bot identity actually sent each line. Renderers may ignore it. */
6528
+ accountId?: string;
6529
+ }
6530
+
6382
6531
  interface AgentPeer {
6383
6532
  id: string;
6384
6533
  name: string;
@@ -6443,6 +6592,10 @@ interface AgentTask {
6443
6592
  * that pattern without requiring callers to invent unique
6444
6593
  * chatIds. */
6445
6594
  freshSession?: boolean;
6595
+ /** Transcript held by a client that owns the conversation (OpenCode).
6596
+ * Seeds an empty AgentX session the same way a channel adapter's
6597
+ * seedHistory does, so a new or rotated session starts with it. */
6598
+ seedHistory?: SeededMessage[];
6446
6599
  context?: {
6447
6600
  channel?: string;
6448
6601
  sender?: string;
@@ -6649,159 +6802,6 @@ declare class MemoryStore {
6649
6802
  prune(agentId: string): void;
6650
6803
  }
6651
6804
 
6652
- /**
6653
- * Verified channel context — facts the channel adapter knows for certain.
6654
- * Prevents agents from hallucinating about their environment.
6655
- */
6656
- interface ChannelMeta {
6657
- /** Channel name */
6658
- channel: string;
6659
- /** Verified agents/bots present in this chat/group/project */
6660
- agents?: Array<{
6661
- id: string;
6662
- name: string;
6663
- handle?: string;
6664
- }>;
6665
- /** Project path (GitLab) or group topic */
6666
- project?: string;
6667
- /** Issue/MR context (GitLab) */
6668
- issue?: {
6669
- type: string;
6670
- iid: string;
6671
- title: string;
6672
- };
6673
- /** Channel-specific facts (e.g., pipeline status, group description) */
6674
- facts?: string[];
6675
- }
6676
- interface IncomingMessage {
6677
- id: string;
6678
- channel: string;
6679
- accountId: string;
6680
- sender: {
6681
- id: string;
6682
- name: string;
6683
- username?: string;
6684
- /** True when the origin is another bot account (Telegram `from.is_bot`).
6685
- * Used by the router to apply strict @-mention-only routing — prevents
6686
- * cross-daemon cascades from bare-word matches in bot replies. */
6687
- isBot?: boolean;
6688
- };
6689
- group?: {
6690
- id: string;
6691
- name: string;
6692
- };
6693
- text: string;
6694
- replyTo?: string;
6695
- replyToText?: string;
6696
- timestamp: Date;
6697
- media?: {
6698
- path: string;
6699
- type: string;
6700
- fileName?: string;
6701
- };
6702
- raw?: unknown;
6703
- resolvedAgent?: string;
6704
- preferNode?: string;
6705
- channelMeta?: ChannelMeta;
6706
- /** Correlator threaded by the workflow engine. When a workflow dispatches
6707
- * an agent, this carries the run id through the pipeline so post:response
6708
- * can re-enter the engine with `kind: agentResult` transitions. Opaque
6709
- * everywhere outside src/workflows/. */
6710
- workflowRunId?: string;
6711
- /** Phase 1 / 6 — when set, identifies the intent-ledger decision row
6712
- * this message corresponds to. The agent registry calls
6713
- * `ledger.recordResolution(...)` when the dispatched task completes,
6714
- * so Inv-ActiveTaskSafety's "decision in flight" check can clear.
6715
- * Set by the channel adapter (gitlab, router) right after
6716
- * recordGitLabTargetDispatch / recordRouterDispatch returns the
6717
- * decision row. Undefined when the dispatch was deduped/halted by
6718
- * the ledger (no resolution to write) or when the source is in
6719
- * mode=off. */
6720
- intentRef?: {
6721
- eventId: string;
6722
- decidedBy: string;
6723
- };
6724
- /** Path to the project root whose runbook (CLAUDE.md / AGENTS.md / etc.)
6725
- * the agent should consult for this task. Set by the gitlab/github
6726
- * adapters when a project rule resolves a `runbook:` path. The agent
6727
- * registry reads the file set into the cacheable system prefix.
6728
- * Undefined when no rule matched — agent uses its own workspace's
6729
- * CLAUDE.md as before. */
6730
- runbookPath?: string;
6731
- /** Override list of files the registry should read from runbookPath.
6732
- * Carried alongside the path so per-project customisation applies
6733
- * without the registry re-reading the rule. */
6734
- runbookFiles?: string[];
6735
- }
6736
- interface OutgoingMessage {
6737
- channel: string;
6738
- chatId: string;
6739
- text: string;
6740
- replyTo?: string;
6741
- parseMode?: "markdown" | "html" | "plain";
6742
- agentId?: string;
6743
- poll?: {
6744
- name: string;
6745
- values: string[];
6746
- selectableCount?: number;
6747
- };
6748
- media?: {
6749
- type: "image" | "document" | "audio" | "video";
6750
- url: string;
6751
- caption?: string;
6752
- mimetype?: string;
6753
- fileName?: string;
6754
- };
6755
- /** URL inline buttons (Phase 1). Telegram renders an inline_keyboard;
6756
- * channels without button support ignore them. */
6757
- buttons?: Array<{
6758
- label: string;
6759
- url: string;
6760
- }>;
6761
- }
6762
- interface ChannelAdapter {
6763
- readonly name: string;
6764
- /** Start polling or webhook listener */
6765
- start(): Promise<void>;
6766
- /** Stop the adapter gracefully */
6767
- stop(): Promise<void>;
6768
- /** Send a message back to a chat */
6769
- send(msg: OutgoingMessage): Promise<string | void>;
6770
- /** Edit an existing message (returns false if not supported) */
6771
- editMessage?(chatId: string, messageId: string, text: string, parseMode?: string): Promise<boolean>;
6772
- /** Send typing/action indicator */
6773
- sendTyping?(chatId: string): Promise<void>;
6774
- /** React to a message with an emoji (e.g., 👀 for seen) */
6775
- react?(chatId: string, messageId: string, emoji?: string): Promise<void>;
6776
- /** Register handler for incoming messages */
6777
- onMessage(handler: (msg: IncomingMessage) => Promise<void>): void;
6778
- /** Get verified context for a chat (optional — channels implement what they can) */
6779
- getChannelMeta?(chatId: string): Promise<ChannelMeta | undefined>;
6780
- /** Fetch the most recent messages from the live channel for cold-start
6781
- * session seeding. Called once per (agent, channel, chatId, day) when a
6782
- * fresh session is created — never on warm cache hits. Bounded by
6783
- * maxMessages and maxChars (enforced by the caller). Channels return their
6784
- * own externalId so SessionStore can dedup against re-seeds. */
6785
- seedHistory?(chatId: string, opts: {
6786
- sinceISO?: string;
6787
- maxMessages: number;
6788
- maxChars: number;
6789
- }): Promise<Array<SeededMessage>>;
6790
- }
6791
- /** A message returned by seedHistory — flat, channel-agnostic. */
6792
- interface SeededMessage {
6793
- role: "user" | "agent";
6794
- name: string;
6795
- content: string;
6796
- timestamp: string;
6797
- externalId?: string;
6798
- /** Optional channel-side account/bot identity that handled this message
6799
- * (e.g., Telegram accountId "acme_cx_bot"). Captured by adapters that
6800
- * shadow-log outbound, so seeded history preserves the audit trail of
6801
- * which bot identity actually sent each line. Renderers may ignore it. */
6802
- accountId?: string;
6803
- }
6804
-
6805
6805
  interface SessionMessage {
6806
6806
  role: "user" | "agent";
6807
6807
  name?: string;
@@ -6884,10 +6884,12 @@ declare class SessionStore {
6884
6884
  * - the session already has messages (warm cache or partially loaded)
6885
6885
  * - no adapter resolver is installed
6886
6886
  * - the channel adapter has no seedHistory method
6887
+ * Caller-supplied seeds (from a client that owns the transcript, such
6888
+ * as OpenCode) take the adapter's place.
6887
6889
  * Concurrent calls against the same key share one in-flight promise so
6888
6890
  * the channel API is hit exactly once per cold create. Errors are
6889
6891
  * swallowed — a seeding failure should never block a turn. */
6890
- seedIfEmpty(agentId: string, channel: string, chatId: string): Promise<void>;
6892
+ seedIfEmpty(agentId: string, channel: string, chatId: string, callerSeeds?: SeededMessage[]): Promise<void>;
6891
6893
  /** Append seeded messages to a session in chronological order, deduping
6892
6894
  * by externalId against anything already present. Marks each entry with
6893
6895
  * `seeded: true` so observers can distinguish them; the model's prompt
@@ -7800,16 +7802,16 @@ declare const fingerprintEntrySchema: z.ZodObject<{
7800
7802
  updatedAt: z.ZodString;
7801
7803
  }, "strip", z.ZodTypeAny, {
7802
7804
  path: string[];
7805
+ fingerprint: string;
7803
7806
  updatedAt: string;
7804
7807
  leaf: {
7805
7808
  output?: string | undefined;
7806
7809
  input?: string | undefined;
7807
7810
  };
7808
- fingerprint: string;
7809
7811
  }, {
7810
7812
  path: string[];
7811
- updatedAt: string;
7812
7813
  fingerprint: string;
7814
+ updatedAt: string;
7813
7815
  leaf?: {
7814
7816
  output?: string | undefined;
7815
7817
  input?: string | undefined;
@@ -7887,16 +7889,16 @@ declare const indexFileSchema: z.ZodObject<{
7887
7889
  updatedAt: z.ZodString;
7888
7890
  }, "strip", z.ZodTypeAny, {
7889
7891
  path: string[];
7892
+ fingerprint: string;
7890
7893
  updatedAt: string;
7891
7894
  leaf: {
7892
7895
  output?: string | undefined;
7893
7896
  input?: string | undefined;
7894
7897
  };
7895
- fingerprint: string;
7896
7898
  }, {
7897
7899
  path: string[];
7898
- updatedAt: string;
7899
7900
  fingerprint: string;
7901
+ updatedAt: string;
7900
7902
  leaf?: {
7901
7903
  output?: string | undefined;
7902
7904
  input?: string | undefined;
@@ -7905,19 +7907,19 @@ declare const indexFileSchema: z.ZodObject<{
7905
7907
  }, "strip", z.ZodTypeAny, {
7906
7908
  entries: Record<string, {
7907
7909
  path: string[];
7910
+ fingerprint: string;
7908
7911
  updatedAt: string;
7909
7912
  leaf: {
7910
7913
  output?: string | undefined;
7911
7914
  input?: string | undefined;
7912
7915
  };
7913
- fingerprint: string;
7914
7916
  }>;
7915
7917
  version: number;
7916
7918
  }, {
7917
7919
  entries?: Record<string, {
7918
7920
  path: string[];
7919
- updatedAt: string;
7920
7921
  fingerprint: string;
7922
+ updatedAt: string;
7921
7923
  leaf?: {
7922
7924
  output?: string | undefined;
7923
7925
  input?: string | undefined;
@@ -8497,7 +8499,7 @@ declare class AgentRegistry {
8497
8499
  byChannel: Record<string, {
8498
8500
  tasks: number;
8499
8501
  cost: number;
8500
- }>;
8502
+ }>; /** Runtime handover store — shared with MessageRouter via file on disk. */
8501
8503
  sessionStats: Record<string, {
8502
8504
  sessions: number;
8503
8505
  avgTasksPerSession: number;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as L}from"./chunk-W5C2GDNC.js";import{B as bt,C as Tt,D as Mt,a as St,b as kt,c as vt,d as xt,e as $t,f as Ct,g as Pt}from"./chunk-E3UJHQGN.js";import"./chunk-F6CNF7V3.js";import"./chunk-YLBERT7N.js";import"./chunk-IWMW5432.js";import"./chunk-ZVP6GB4G.js";import{F as yt,d as lt,e as ct,f as dt,g as mt,h as pt}from"./chunk-ULLAE6LE.js";import"./chunk-64CAIB3C.js";import"./chunk-M4AMWP3H.js";import"./chunk-4BR7D2OU.js";import{A as D,B as z,C as V,a as ye,b as we,c as Se,d as Ae,e as Ie,f as Oe,g as Ne,h as He,i as je,j as Ue,k as _e,l as I,m as q,n as Be,o as qe,p as Ye,q as O,r as ze,s as Ve,t as Xe,u as x,v as Y,w as Qe,x as Ze,y as et,z as wt}from"./chunk-MHIMGM4G.js";import{a as B,b as M,c as F}from"./chunk-SFQUP3BP.js";import"./chunk-3SCPRYJB.js";import"./chunk-I3SIXTJO.js";import"./chunk-67Q4DCPS.js";import"./chunk-K33GIBSE.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import{h as ut}from"./chunk-ZMYGXHPT.js";import"./chunk-SCTIUFL4.js";import"./chunk-S2MNL5V6.js";import"./chunk-77OV7346.js";import"./chunk-VWTBHLMX.js";import{a as gt,b as ft,e as ht}from"./chunk-H2QQU2XV.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-QHTQPBHU.js";import"./chunk-AJ5RMU7X.js";import"./chunk-EVWEG3VD.js";import{j as it,k as rt,l as at}from"./chunk-YLGIZRHV.js";import"./chunk-AJONZWLT.js";import"./chunk-F4HZTZHW.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-WPMX3VGI.js";import{a as ke,b as ve,c as xe,d as $e,e as Ce,f as Pe,g as be,h as Te,i as Me,j as Re,l as Ee,m as Ge,o as T,p as W}from"./chunk-LCIREYTD.js";import{a as m,b as G}from"./chunk-L2WSPY6S.js";import{a as Fe,b as Le,c as A,d as De}from"./chunk-VDMYBPYB.js";import{a as Ke,b as Je,e as We}from"./chunk-DSYKYZMT.js";import{e as tt,g as st,h as ot,j as nt}from"./chunk-P5ZBBEPL.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";W();G();import{execa as Rt}from"execa";import{existsSync as se,promises as X}from"fs";import S from"path";import ie from"node-fetch";async function Et(o,e){let t=o.split("/");if(t.length<2)throw new Error(`Invalid skill package ID: ${o}. Expected format: owner/repo`);let s=t[0],i=t[1],n=t[2];try{let a=n?`${s}/${i}/${n}`:`${s}/${i}`;await Rt("npx",["-y","skills","add",a],{cwd:e,stdio:"pipe"}),m.success(`Installed skill package: ${o}`);let r=S.resolve(e,".skills",`${s}_${i}`);if(se(r))return await ne(r,o);let d=S.resolve(e,".skills");return se(d)?await ne(d,o):[]}catch{return m.info(`Fetching skills directly from GitHub: ${s}/${i}`),await Gt(s,i,n,e)}}async function Gt(o,e,t,s){let i=[];try{let n=`https://api.github.com/repos/${o}/${e}/git/trees/main?recursive=1`,a=await ie(n);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let d=(await a.json()).tree.filter(p=>p.type==="blob"&&p.path.endsWith("SKILL.md"));if(t){let p=d.find(f=>f.path.includes(`/${t}/`)||f.path===`${t}/SKILL.md`);if(p){let f=await oe(o,e,p.path,s);f&&i.push(f)}}else for(let p of d){let f=await oe(o,e,p.path,s);f&&i.push(f)}}catch(n){m.error(`Failed to fetch skills from GitHub: ${n.message}`)}return i}async function oe(o,e,t,s){try{let i=`https://raw.githubusercontent.com/${o}/${e}/main/${t}`,n=await ie(i);if(!n.ok)return null;let a=await n.text(),r=A(a);if(r){r.source="remote",r.packageId=`${o}/${e}`;let d=S.dirname(t),p=S.resolve(s,".skills",`${o}_${e}`,d);await X.mkdir(p,{recursive:!0}),await X.writeFile(S.resolve(p,"SKILL.md"),a),r.path=S.resolve(p,"SKILL.md")}return r}catch{return null}}async function ne(o,e){let t=[],{default:s}=await import("fast-glob"),i=await s.glob("**/SKILL.md",{cwd:o,deep:5});for(let n of i)try{let a=S.resolve(o,n),r=await X.readFile(a,"utf8"),d=A(r);d&&(d.source="remote",d.path=a,d.packageId=e,t.push(d))}catch{}return t}async function At(o,e,t,s,i){let n=["---",`name: ${o}`,`description: ${e}`];if(s?.length){n.push("tags:");for(let a of s)n.push(` - ${a}`)}if(i?.length){n.push("globs:");for(let a of i)n.push(` - ${a}`)}return n.push("---"),`${n.join(`
1
+ import{a as L}from"./chunk-W5C2GDNC.js";import{B as bt,C as Tt,D as Mt,a as St,b as kt,c as vt,d as xt,e as $t,f as Ct,g as Pt}from"./chunk-GUBMLV34.js";import"./chunk-F6CNF7V3.js";import"./chunk-EL3J74N2.js";import"./chunk-IWMW5432.js";import"./chunk-ZVP6GB4G.js";import{J as yt,h as lt,i as ct,j as dt,k as mt,l as pt}from"./chunk-45BLFNDG.js";import"./chunk-IVQO43U2.js";import"./chunk-4BR7D2OU.js";import"./chunk-M4AMWP3H.js";import{h as ut}from"./chunk-4KXBUORV.js";import{A as D,B as z,C as V,a as ye,b as we,c as Se,d as Ae,e as Ie,f as Oe,g as Ne,h as He,i as je,j as Ue,k as _e,l as I,m as q,n as Be,o as qe,p as Ye,q as O,r as ze,s as Ve,t as Xe,u as x,v as Y,w as Qe,x as Ze,y as et,z as wt}from"./chunk-UU4WOZNR.js";import{a as B,b as M,c as F}from"./chunk-SFQUP3BP.js";import"./chunk-3SCPRYJB.js";import"./chunk-WPMX3VGI.js";import"./chunk-K33GIBSE.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-SC5DIKBB.js";import"./chunk-GK7XAM3D.js";import"./chunk-DWADWDMU.js";import"./chunk-77OV7346.js";import"./chunk-VWTBHLMX.js";import{a as gt,b as ft,e as ht}from"./chunk-AUNDQPDR.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-V4HURNMX.js";import"./chunk-AJ5RMU7X.js";import"./chunk-EVWEG3VD.js";import{j as it,k as rt,l as at}from"./chunk-MGNJWBVP.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-AJONZWLT.js";import"./chunk-F4HZTZHW.js";import"./chunk-QOYAX2FT.js";import{a as ke,b as ve,c as xe,d as $e,e as Ce,f as Pe,g as be,h as Te,i as Me,j as Re,l as Ee,m as Ge,o as T,p as W}from"./chunk-LCIREYTD.js";import{a as m,b as G}from"./chunk-L2WSPY6S.js";import{a as Fe,b as Le,c as A,d as De}from"./chunk-VDMYBPYB.js";import{a as Ke,b as Je,e as We}from"./chunk-DSYKYZMT.js";import{e as tt,g as st,h as ot,j as nt}from"./chunk-GMNKJXTR.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";W();G();import{execa as Rt}from"execa";import{existsSync as se,promises as X}from"fs";import S from"path";import ie from"node-fetch";async function Et(o,e){let t=o.split("/");if(t.length<2)throw new Error(`Invalid skill package ID: ${o}. Expected format: owner/repo`);let s=t[0],i=t[1],n=t[2];try{let a=n?`${s}/${i}/${n}`:`${s}/${i}`;await Rt("npx",["-y","skills","add",a],{cwd:e,stdio:"pipe"}),m.success(`Installed skill package: ${o}`);let r=S.resolve(e,".skills",`${s}_${i}`);if(se(r))return await ne(r,o);let d=S.resolve(e,".skills");return se(d)?await ne(d,o):[]}catch{return m.info(`Fetching skills directly from GitHub: ${s}/${i}`),await Gt(s,i,n,e)}}async function Gt(o,e,t,s){let i=[];try{let n=`https://api.github.com/repos/${o}/${e}/git/trees/main?recursive=1`,a=await ie(n);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let d=(await a.json()).tree.filter(p=>p.type==="blob"&&p.path.endsWith("SKILL.md"));if(t){let p=d.find(f=>f.path.includes(`/${t}/`)||f.path===`${t}/SKILL.md`);if(p){let f=await oe(o,e,p.path,s);f&&i.push(f)}}else for(let p of d){let f=await oe(o,e,p.path,s);f&&i.push(f)}}catch(n){m.error(`Failed to fetch skills from GitHub: ${n.message}`)}return i}async function oe(o,e,t,s){try{let i=`https://raw.githubusercontent.com/${o}/${e}/main/${t}`,n=await ie(i);if(!n.ok)return null;let a=await n.text(),r=A(a);if(r){r.source="remote",r.packageId=`${o}/${e}`;let d=S.dirname(t),p=S.resolve(s,".skills",`${o}_${e}`,d);await X.mkdir(p,{recursive:!0}),await X.writeFile(S.resolve(p,"SKILL.md"),a),r.path=S.resolve(p,"SKILL.md")}return r}catch{return null}}async function ne(o,e){let t=[],{default:s}=await import("fast-glob"),i=await s.glob("**/SKILL.md",{cwd:o,deep:5});for(let n of i)try{let a=S.resolve(o,n),r=await X.readFile(a,"utf8"),d=A(r);d&&(d.source="remote",d.path=a,d.packageId=e,t.push(d))}catch{}return t}async function At(o,e,t,s,i){let n=["---",`name: ${o}`,`description: ${e}`];if(s?.length){n.push("tags:");for(let a of s)n.push(` - ${a}`)}if(i?.length){n.push("globs:");for(let a of i)n.push(` - ${a}`)}return n.push("---"),`${n.join(`
2
2
  `)}
3
3
 
4
4
  ${t}`}async function It(o){let{loadLocalSkills:e}=await import("./loader-BOKE5M5S.js");return e(o)}async function Ot(o,e,t,s,i){let a=[{role:"system",content:`You are a skill author for the Agent Skills ecosystem (skills.sh).