@myagentroam/node 0.1.4 → 0.1.7

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 (210) hide show
  1. package/README.md +9 -1
  2. package/dist/capabilities.d.ts +2 -0
  3. package/dist/capabilities.js +15 -4
  4. package/dist/claude-agent-sdk.d.ts +3 -1
  5. package/dist/claude-agent-sdk.js +9 -2
  6. package/dist/claude-channel.js +0 -1
  7. package/dist/codex-app-server.d.ts +1 -0
  8. package/dist/codex-app-server.js +8 -1
  9. package/dist/config.d.ts +3 -0
  10. package/dist/config.js +18 -2
  11. package/dist/connector/node-connector-options.d.ts +3 -0
  12. package/dist/connector/node-connector-options.js +0 -1
  13. package/dist/connector/node-operation-router.js +0 -1
  14. package/dist/connector.d.ts +3 -0
  15. package/dist/connector.js +109 -7
  16. package/dist/control-outbound-scheduler.js +0 -1
  17. package/dist/database.d.ts +4 -0
  18. package/dist/database.js +14 -9
  19. package/dist/event-buffer.js +0 -1
  20. package/dist/fake-runner.js +0 -1
  21. package/dist/health.js +0 -1
  22. package/dist/main.js +6 -1
  23. package/dist/migrations/v001.js +0 -1
  24. package/dist/migrations/v002.js +0 -1
  25. package/dist/migrations/v003.d.ts +4 -0
  26. package/dist/migrations/v003.js +44 -0
  27. package/dist/native-jsonl-reader.js +0 -1
  28. package/dist/native-session-history.d.ts +19 -1
  29. package/dist/native-session-history.js +65 -3
  30. package/dist/opencode-runtime.d.ts +33 -0
  31. package/dist/opencode-runtime.js +80 -0
  32. package/dist/opencode-server.d.ts +47 -0
  33. package/dist/opencode-server.js +250 -0
  34. package/dist/operational.js +10 -3
  35. package/dist/process-tree.js +0 -1
  36. package/dist/runner/abstract-runner.d.ts +7 -2
  37. package/dist/runner/abstract-runner.js +17 -2
  38. package/dist/runner/claude/managed-run-controller.js +20 -1
  39. package/dist/runner/claude-code-runner.d.ts +3 -1
  40. package/dist/runner/claude-code-runner.js +26 -8
  41. package/dist/runner/codex/conversation-parser.d.ts +1 -3
  42. package/dist/runner/codex/conversation-parser.js +174 -34
  43. package/dist/runner/codex/managed-run-controller.d.ts +2 -1
  44. package/dist/runner/codex/managed-run-controller.js +13 -4
  45. package/dist/runner/codex-runner.d.ts +4 -0
  46. package/dist/runner/codex-runner.js +27 -4
  47. package/dist/runner/fake-test-runner.js +0 -1
  48. package/dist/runner/opencode/conversation-parser.d.ts +27 -0
  49. package/dist/runner/opencode/conversation-parser.js +217 -0
  50. package/dist/runner/opencode/managed-run-controller.d.ts +76 -0
  51. package/dist/runner/opencode/managed-run-controller.js +451 -0
  52. package/dist/runner/opencode-runner.d.ts +60 -0
  53. package/dist/runner/opencode-runner.js +330 -0
  54. package/dist/runner/runner-registry.d.ts +3 -1
  55. package/dist/runner/runner-registry.js +12 -3
  56. package/dist/runner-command-engine.js +0 -1
  57. package/dist/runner-profiles.d.ts +4 -0
  58. package/dist/runner-profiles.js +76 -3
  59. package/dist/runner-usage.js +0 -1
  60. package/dist/runtime-state.js +20 -9
  61. package/dist/service/attachment-domain-state.js +0 -1
  62. package/dist/service/conversation-history-service.js +0 -1
  63. package/dist/service/external-session-resume-service.js +0 -1
  64. package/dist/service/fake-managed-run-service.js +0 -1
  65. package/dist/service/managed-runner-session-service.d.ts +3 -1
  66. package/dist/service/managed-runner-session-service.js +8 -4
  67. package/dist/service/native-session-projection-service.d.ts +2 -1
  68. package/dist/service/native-session-projection-service.js +8 -5
  69. package/dist/service/native-session-watch-service.js +0 -1
  70. package/dist/service/node-connection-lifecycle-service.js +3 -2
  71. package/dist/service/node-control-channel.d.ts +1 -1
  72. package/dist/service/node-control-channel.js +5 -4
  73. package/dist/service/node-control-message-service.js +0 -1
  74. package/dist/service/node-request-service.js +0 -1
  75. package/dist/service/node-run-event-bridge.d.ts +2 -0
  76. package/dist/service/node-run-event-bridge.js +4 -1
  77. package/dist/service/node-terminal-channel.js +16 -10
  78. package/dist/service/node-upgrade-coordinator.d.ts +29 -0
  79. package/dist/service/node-upgrade-coordinator.js +137 -0
  80. package/dist/service/node-workspace-coordinator.js +0 -1
  81. package/dist/service/run-attachment-service.js +0 -1
  82. package/dist/service/run-domain-state.js +0 -1
  83. package/dist/service/run-event-service.js +0 -1
  84. package/dist/service/run-workbench-service.js +0 -1
  85. package/dist/service/runner-channel-message-service.js +0 -1
  86. package/dist/service/runner-interaction-service.js +2 -1
  87. package/dist/service/runner-service.d.ts +5 -4
  88. package/dist/service/runner-service.js +19 -6
  89. package/dist/service/session-catalog-service.d.ts +16 -1
  90. package/dist/service/session-catalog-service.js +82 -3
  91. package/dist/service/session-command-service.js +0 -1
  92. package/dist/service/session-context-service.js +0 -1
  93. package/dist/service/session-domain-state.js +0 -1
  94. package/dist/service/session-identity-service.js +0 -1
  95. package/dist/service/session-lifecycle-service.js +13 -7
  96. package/dist/service/session-message-service.js +0 -1
  97. package/dist/service/session-presentation-service.js +0 -1
  98. package/dist/service/session-query-service.js +0 -1
  99. package/dist/service/terminal-relay-state.js +0 -1
  100. package/dist/service/terminal-service.js +0 -1
  101. package/dist/service/workbench-event-service.js +0 -1
  102. package/dist/service/workbench-manifest-service.d.ts +5 -4
  103. package/dist/service/workbench-manifest-service.js +3 -2
  104. package/dist/service/workspace-change-service.js +2 -2
  105. package/dist/service/workspace-content-search-service.d.ts +14 -0
  106. package/dist/service/workspace-content-search-service.js +477 -0
  107. package/dist/service/workspace-domain-state.js +0 -1
  108. package/dist/service/workspace-file-service.d.ts +3 -0
  109. package/dist/service/workspace-file-service.js +35 -3
  110. package/dist/service/workspace-queue-workbench-service.js +0 -1
  111. package/dist/service/workspace-service.js +23 -10
  112. package/dist/service/workspace-session-service.js +0 -1
  113. package/dist/service/workspace-upload-service.js +0 -1
  114. package/dist/service/workspace-watch-service.js +0 -1
  115. package/dist/service/workspace-workbench-service.d.ts +9 -0
  116. package/dist/service/workspace-workbench-service.js +69 -2
  117. package/dist/service.js +2 -3
  118. package/dist/storage.js +0 -1
  119. package/dist/supervisor.d.ts +1 -0
  120. package/dist/supervisor.js +154 -0
  121. package/dist/terminal.js +0 -1
  122. package/dist/util/node-operation-parsers.d.ts +1 -0
  123. package/dist/util/node-operation-parsers.js +3 -1
  124. package/dist/util/runner-native-session-parsers.js +117 -73
  125. package/dist/util/secret-environment.js +0 -1
  126. package/dist/workspace.d.ts +62 -2
  127. package/dist/workspace.js +539 -57
  128. package/package.json +3 -2
  129. package/dist/capabilities.js.map +0 -1
  130. package/dist/claude-agent-sdk.js.map +0 -1
  131. package/dist/claude-channel.js.map +0 -1
  132. package/dist/codex-app-server.js.map +0 -1
  133. package/dist/config.js.map +0 -1
  134. package/dist/connector/node-connector-options.js.map +0 -1
  135. package/dist/connector/node-operation-router.js.map +0 -1
  136. package/dist/connector.js.map +0 -1
  137. package/dist/control-outbound-scheduler.js.map +0 -1
  138. package/dist/database.js.map +0 -1
  139. package/dist/event-buffer.js.map +0 -1
  140. package/dist/fake-runner.js.map +0 -1
  141. package/dist/health.js.map +0 -1
  142. package/dist/main.js.map +0 -1
  143. package/dist/migrations/v001.js.map +0 -1
  144. package/dist/migrations/v002.js.map +0 -1
  145. package/dist/native-jsonl-reader.js.map +0 -1
  146. package/dist/native-session-history.js.map +0 -1
  147. package/dist/operational.js.map +0 -1
  148. package/dist/process-tree.js.map +0 -1
  149. package/dist/runner/abstract-runner.js.map +0 -1
  150. package/dist/runner/claude/managed-run-controller.js.map +0 -1
  151. package/dist/runner/claude-code-runner.js.map +0 -1
  152. package/dist/runner/codex/conversation-parser.js.map +0 -1
  153. package/dist/runner/codex/managed-run-controller.js.map +0 -1
  154. package/dist/runner/codex-runner.js.map +0 -1
  155. package/dist/runner/fake-test-runner.js.map +0 -1
  156. package/dist/runner/runner-registry.js.map +0 -1
  157. package/dist/runner-command-engine.js.map +0 -1
  158. package/dist/runner-profiles.js.map +0 -1
  159. package/dist/runner-usage.js.map +0 -1
  160. package/dist/runtime-state.js.map +0 -1
  161. package/dist/service/attachment-domain-state.js.map +0 -1
  162. package/dist/service/conversation-history-service.js.map +0 -1
  163. package/dist/service/external-session-resume-service.js.map +0 -1
  164. package/dist/service/fake-managed-run-service.js.map +0 -1
  165. package/dist/service/managed-runner-session-service.js.map +0 -1
  166. package/dist/service/native-session-projection-service.js.map +0 -1
  167. package/dist/service/native-session-watch-service.js.map +0 -1
  168. package/dist/service/node-connection-lifecycle-service.js.map +0 -1
  169. package/dist/service/node-control-channel.js.map +0 -1
  170. package/dist/service/node-control-message-service.js.map +0 -1
  171. package/dist/service/node-request-service.js.map +0 -1
  172. package/dist/service/node-run-event-bridge.js.map +0 -1
  173. package/dist/service/node-terminal-channel.js.map +0 -1
  174. package/dist/service/node-workspace-coordinator.js.map +0 -1
  175. package/dist/service/run-attachment-service.js.map +0 -1
  176. package/dist/service/run-domain-state.js.map +0 -1
  177. package/dist/service/run-event-service.js.map +0 -1
  178. package/dist/service/run-workbench-service.js.map +0 -1
  179. package/dist/service/runner-channel-message-service.js.map +0 -1
  180. package/dist/service/runner-interaction-service.js.map +0 -1
  181. package/dist/service/runner-service.js.map +0 -1
  182. package/dist/service/session-catalog-service.js.map +0 -1
  183. package/dist/service/session-command-service.js.map +0 -1
  184. package/dist/service/session-context-service.js.map +0 -1
  185. package/dist/service/session-domain-state.js.map +0 -1
  186. package/dist/service/session-identity-service.js.map +0 -1
  187. package/dist/service/session-lifecycle-service.js.map +0 -1
  188. package/dist/service/session-message-service.js.map +0 -1
  189. package/dist/service/session-presentation-service.js.map +0 -1
  190. package/dist/service/session-query-service.js.map +0 -1
  191. package/dist/service/terminal-relay-state.js.map +0 -1
  192. package/dist/service/terminal-service.js.map +0 -1
  193. package/dist/service/workbench-event-service.js.map +0 -1
  194. package/dist/service/workbench-manifest-service.js.map +0 -1
  195. package/dist/service/workspace-change-service.js.map +0 -1
  196. package/dist/service/workspace-domain-state.js.map +0 -1
  197. package/dist/service/workspace-file-service.js.map +0 -1
  198. package/dist/service/workspace-queue-workbench-service.js.map +0 -1
  199. package/dist/service/workspace-service.js.map +0 -1
  200. package/dist/service/workspace-session-service.js.map +0 -1
  201. package/dist/service/workspace-upload-service.js.map +0 -1
  202. package/dist/service/workspace-watch-service.js.map +0 -1
  203. package/dist/service/workspace-workbench-service.js.map +0 -1
  204. package/dist/service.js.map +0 -1
  205. package/dist/storage.js.map +0 -1
  206. package/dist/terminal.js.map +0 -1
  207. package/dist/util/node-operation-parsers.js.map +0 -1
  208. package/dist/util/runner-native-session-parsers.js.map +0 -1
  209. package/dist/util/secret-environment.js.map +0 -1
  210. package/dist/workspace.js.map +0 -1
@@ -8,6 +8,7 @@ import { discoverAllNativeSessions } from '../native-session-history.js';
8
8
  import { readCodexNativeContextUsage } from '../native-session-history.js';
9
9
  import { codexActiveTurnId, codexOfficialConversationPage, codexThreadCwd, codexThreadActivity, deduplicateDirectSessions, externalResumeFailureDetail, extractCodexThreads, isWithinWorkspace, latestNativeActivity } from './codex/conversation-parser.js';
10
10
  import { codexSessionControl } from '../codex-app-server.js';
11
+ import { extractId } from '../util/runner-native-session-parsers.js';
11
12
  export class CodexRunner extends AbstractRunner {
12
13
  client;
13
14
  name = 'codex';
@@ -23,7 +24,8 @@ export class CodexRunner extends AbstractRunner {
23
24
  profile(capabilities) {
24
25
  return declaredRunnerProfiles({
25
26
  codexAvailable: capabilities.codex.available,
26
- claudeCodeAvailable: capabilities.claudeCode.available
27
+ claudeCodeAvailable: capabilities.claudeCode.available,
28
+ openCodeAvailable: capabilities.openCode?.available === true
27
29
  }).find((profile) => profile.runner === this.name);
28
30
  }
29
31
  available(capabilities) {
@@ -105,6 +107,11 @@ export class CodexRunner extends AbstractRunner {
105
107
  acceptsTruncatedNativeHistory() {
106
108
  return false;
107
109
  }
110
+ async readManagedRunnerTitle(session, nativeSessionId) {
111
+ void session;
112
+ await this.start();
113
+ return extractCodexThreads(await this.listThreads()).find((thread) => thread.id === nativeSessionId)?.title;
114
+ }
108
115
  nativeImageRoot(session) {
109
116
  return session.externalSessionId === null
110
117
  ? undefined
@@ -120,7 +127,8 @@ export class CodexRunner extends AbstractRunner {
120
127
  nodeAppVersion: 'validation',
121
128
  nodeVersion: 'validation',
122
129
  codex: { available: true },
123
- claudeCode: { available: false }
130
+ claudeCode: { available: false },
131
+ openCode: { available: false }
124
132
  });
125
133
  }
126
134
  defaultConfiguration() {
@@ -256,7 +264,8 @@ export class CodexRunner extends AbstractRunner {
256
264
  ...(control.level === 'MANAGED' ? ['turn.queue', 'run.cancel', 'approval.respond'] : []),
257
265
  'session.rename',
258
266
  'session.remove',
259
- 'session.pin'
267
+ 'session.pin',
268
+ ...(session.externalSessionId === null ? [] : ['session.rewind'])
260
269
  ],
261
270
  reasonCode: control.level === 'UNAVAILABLE' ? 'RUNNER_UNAVAILABLE' : null
262
271
  }
@@ -317,6 +326,21 @@ export class CodexRunner extends AbstractRunner {
317
326
  startThread(cwd, configuration) {
318
327
  return this.client.startThread(cwd, configuration);
319
328
  }
329
+ forkThread(threadId, cwd, lastTurnId, configuration) {
330
+ return this.client.forkThread(threadId, cwd, lastTurnId, configuration);
331
+ }
332
+ async forkNative(session, boundary, title) {
333
+ if (session.externalSessionId === null)
334
+ throw new Error('SESSION_REWIND_UNAVAILABLE');
335
+ await this.start();
336
+ const configuration = { model: session.model, effort: session.effort, access: session.access };
337
+ const result = boundary === null
338
+ ? await this.startThread(session.cwd, configuration)
339
+ : await this.forkThread(session.externalSessionId, session.cwd, boundary, configuration);
340
+ const threadId = extractId(result, 'thread');
341
+ await this.setThreadName(threadId, title);
342
+ return threadId;
343
+ }
320
344
  resumeThread(threadId, cwd, configuration) {
321
345
  return this.client.resumeThread(threadId, cwd, configuration);
322
346
  }
@@ -339,4 +363,3 @@ export class CodexExecutionState {
339
363
  approvals = new Map();
340
364
  userInputs = new Map();
341
365
  }
342
- //# sourceMappingURL=codex-runner.js.map
@@ -45,4 +45,3 @@ export class FakeTestRunner extends AbstractRunner {
45
45
  return this.runner.cancel(runId);
46
46
  }
47
47
  }
48
- //# sourceMappingURL=fake-test-runner.js.map
@@ -0,0 +1,27 @@
1
+ import type { NodeAgentSession, NodeConversationTurn } from '../../database.js';
2
+ export declare function openCodeConversationPage(session: NodeAgentSession, messages: readonly unknown[], input: {
3
+ readonly cursor?: string;
4
+ readonly limit?: number;
5
+ }, managedTurn: (nativeTurnId: string) => NodeConversationTurn | undefined): {
6
+ readonly turns: readonly NodeConversationTurn[];
7
+ readonly nextCursor: string | null;
8
+ } | undefined;
9
+ export declare function openCodeQuestions(value: unknown): {
10
+ id: string;
11
+ prompt: string;
12
+ input: string;
13
+ options: {
14
+ value: string;
15
+ label: string;
16
+ description: string | null;
17
+ }[];
18
+ allowOther: boolean;
19
+ multiSelect: boolean;
20
+ }[];
21
+ export declare function openCodePatchChanges(value: unknown): {
22
+ path: string;
23
+ change: string;
24
+ additions: null;
25
+ deletions: null;
26
+ diffAvailable: boolean;
27
+ }[];
@@ -0,0 +1,217 @@
1
+ import { basename } from 'node:path';
2
+ import { boundedConversationItemId, compactRunnerText, compactRunnerValue } from '../codex/conversation-parser.js';
3
+ export function openCodeConversationPage(session, messages, input, managedTurn) {
4
+ const records = messages.flatMap((value) => {
5
+ const entry = record(value);
6
+ const info = record(entry?.info);
7
+ return info === undefined || typeof info.id !== 'string'
8
+ ? []
9
+ : [{ info, parts: array(entry?.parts) }];
10
+ });
11
+ const parsedTurns = records
12
+ .filter(({ info }) => info.role === 'user')
13
+ .flatMap(({ info, parts }, sequence) => {
14
+ const assistants = records.filter((candidate) => candidate.info.role === 'assistant' && candidate.info.parentID === info.id);
15
+ const existing = managedTurn(info.id);
16
+ const turn = openCodeTurn(session, info, parts, assistants, sequence, existing);
17
+ const after = assistants.at(-1)?.info.id ?? info.id;
18
+ return turn === undefined || typeof after !== 'string' ? [] : [{ after, turn }];
19
+ });
20
+ const turns = parsedTurns.map(({ after, turn }, index) => ({
21
+ ...turn,
22
+ rewind: { before: parsedTurns[index - 1]?.after ?? null, after }
23
+ }));
24
+ if (turns.length === 0)
25
+ return undefined;
26
+ const limit = Math.min(Math.max(input.limit ?? 30, 1), 500);
27
+ const end = pageEnd(input.cursor, session.id, turns.length);
28
+ const start = Math.max(0, end - limit);
29
+ return {
30
+ turns: turns.slice(start, end),
31
+ nextCursor: start === 0
32
+ ? null
33
+ : Buffer.from(JSON.stringify({ sessionId: session.id, end: start })).toString('base64url')
34
+ };
35
+ }
36
+ function openCodeTurn(session, user, userParts, assistants, sequence, managed) {
37
+ const nativeTurnId = user.id;
38
+ const startedAt = number(record(user.time)?.created);
39
+ const items = [];
40
+ const userText = userParts
41
+ .flatMap((part) => {
42
+ const value = record(part);
43
+ return value?.type === 'text' && typeof value.text === 'string' ? [value.text] : [];
44
+ })
45
+ .join('\n');
46
+ const localUser = managed?.items.find((item) => item.kind === 'user_message');
47
+ if (localUser !== undefined)
48
+ items.push({ ...localUser, turnId: managed.id });
49
+ else if (userText.length > 0)
50
+ items.push(item(session, nativeTurnId, `user-${nativeTurnId}`, 'user_message', 'COMPLETED', {
51
+ text: compactRunnerText(userText, 20_000),
52
+ attachments: []
53
+ }, startedAt, startedAt, sequence));
54
+ for (const assistant of assistants) {
55
+ const completedAt = number(record(assistant.info.time)?.completed);
56
+ for (const part of assistant.parts) {
57
+ const projected = partItem(session, nativeTurnId, part, assistant.info.mode === 'plan', startedAt, completedAt, sequence);
58
+ if (projected !== undefined)
59
+ items.push(projected);
60
+ }
61
+ }
62
+ if (items.length === 0)
63
+ return undefined;
64
+ const completedAt = Math.max(startedAt ?? 0, ...assistants.map(({ info }) => number(record(info.time)?.completed) ?? 0)) || startedAt;
65
+ const id = managed?.id ?? `${session.id}:official:${nativeTurnId}`;
66
+ const runId = managed?.runId ?? null;
67
+ return {
68
+ id,
69
+ sessionId: session.id,
70
+ runId,
71
+ userItemId: items.find((value) => value.kind === 'user_message')?.id ?? null,
72
+ status: assistants.some(({ info }) => info.error !== undefined) ? 'FAILED' : 'SUCCEEDED',
73
+ model: assistants.find(({ info }) => typeof info.modelID === 'string')?.info.modelID ?? null,
74
+ effort: managed?.effort ?? null,
75
+ access: managed?.access ?? null,
76
+ items: items.map((value) => ({ ...value, turnId: id, runId })),
77
+ startedAt,
78
+ completedAt
79
+ };
80
+ }
81
+ function partItem(session, turnId, raw, planMode, startedAt, completedAt, sequence) {
82
+ const part = record(raw);
83
+ if (typeof part?.id !== 'string' || typeof part.type !== 'string')
84
+ return undefined;
85
+ if ((part.type === 'text' || part.type === 'reasoning') && typeof part.text === 'string')
86
+ return item(session, turnId, part.id, part.type === 'text' ? (planMode ? 'plan' : 'assistant_message') : 'reasoning_summary', completedAt === null ? 'IN_PROGRESS' : 'COMPLETED', part.type === 'text'
87
+ ? planMode
88
+ ? { explanation: compactRunnerText(part.text, 20_000), steps: [] }
89
+ : { text: compactRunnerText(part.text, 20_000), format: 'markdown', model: null }
90
+ : { sections: [{ index: 0, text: compactRunnerText(part.text, 10_000) }] }, startedAt, completedAt, sequence);
91
+ if (part.type === 'tool' && typeof part.tool === 'string') {
92
+ const state = record(part.state);
93
+ if (part.tool === 'question' && typeof part.callID === 'string') {
94
+ const questions = openCodeQuestions(record(state?.input)?.questions);
95
+ if (questions.length > 0)
96
+ return item(session, turnId, part.id, 'user_input_request', 'COMPLETED', { requestId: `native:${part.callID}`, questions }, startedAt, completedAt, sequence);
97
+ }
98
+ const status = state?.status === 'completed'
99
+ ? 'COMPLETED'
100
+ : state?.status === 'error'
101
+ ? 'FAILED'
102
+ : 'IN_PROGRESS';
103
+ return item(session, turnId, part.id, 'tool_call', status, {
104
+ namespace: 'opencode',
105
+ toolName: compactRunnerText(part.tool, 128),
106
+ title: compactRunnerText(typeof state?.title === 'string' ? state.title : part.tool, 500),
107
+ inputSummary: compactRunnerValue(state?.input, 10_000).text || null,
108
+ outputSummary: typeof state?.output === 'string' ? compactRunnerText(state.output, 10_000) : null,
109
+ progressLabel: null,
110
+ errorCode: status === 'FAILED' ? 'OPENCODE_TOOL_FAILED' : null,
111
+ truncated: false
112
+ }, startedAt, completedAt, sequence);
113
+ }
114
+ if (part.type === 'compaction')
115
+ return item(session, turnId, part.id, 'context_compaction', 'COMPLETED', {
116
+ phase: 'COMPLETED',
117
+ summary: '上下文已整理'
118
+ }, startedAt, completedAt, sequence);
119
+ if (part.type === 'patch')
120
+ return item(session, turnId, part.id, 'file_change', 'COMPLETED', { changes: openCodePatchChanges(part.files) }, startedAt, completedAt, sequence);
121
+ if (part.type === 'step-start' || part.type === 'step-finish')
122
+ return undefined;
123
+ if (part.type === 'text' || part.type === 'reasoning')
124
+ return undefined;
125
+ return item(session, turnId, part.id, 'unknown', completedAt === null ? 'IN_PROGRESS' : 'COMPLETED', {
126
+ sourceEventType: `opencode:${part.type}`,
127
+ label: `OpenCode ${compactRunnerText(part.type, 128)}`
128
+ }, startedAt, completedAt, sequence);
129
+ }
130
+ export function openCodeQuestions(value) {
131
+ if (!Array.isArray(value) || value.length === 0 || value.length > 4)
132
+ return [];
133
+ return value.flatMap((value, index) => {
134
+ const question = record(value);
135
+ if (typeof question?.question !== 'string')
136
+ return [];
137
+ const options = (Array.isArray(question.options) ? question.options : []).flatMap((value) => {
138
+ const option = record(value);
139
+ const label = typeof option?.label === 'string' ? compactRunnerText(option.label, 500) : '';
140
+ return label.length === 0
141
+ ? []
142
+ : [
143
+ {
144
+ value: label,
145
+ label,
146
+ description: typeof option?.description === 'string'
147
+ ? compactRunnerText(option.description, 1_000)
148
+ : null
149
+ }
150
+ ];
151
+ });
152
+ const multiSelect = question.multiple === true;
153
+ return [
154
+ {
155
+ id: `question-${index + 1}`,
156
+ prompt: compactRunnerText(question.question, 5_000),
157
+ input: options.length === 0 ? 'SHORT_TEXT' : multiSelect ? 'MULTI_SELECT' : 'SINGLE_SELECT',
158
+ options,
159
+ allowOther: true,
160
+ multiSelect
161
+ }
162
+ ];
163
+ });
164
+ }
165
+ export function openCodePatchChanges(value) {
166
+ return (Array.isArray(value) ? value : []).flatMap((path) => typeof path === 'string' && path.length > 0
167
+ ? [
168
+ {
169
+ path: basename(path),
170
+ change: 'MODIFIED',
171
+ additions: null,
172
+ deletions: null,
173
+ diffAvailable: false
174
+ }
175
+ ]
176
+ : []);
177
+ }
178
+ function item(session, turnId, nativeId, kind, status, payload, startedAt, completedAt, sequence) {
179
+ return {
180
+ id: boundedConversationItemId(`${session.id}:official:${turnId}`, nativeId),
181
+ sessionId: session.id,
182
+ turnId: `${session.id}:official:${turnId}`,
183
+ runId: null,
184
+ parentItemId: null,
185
+ sourceSequence: sequence,
186
+ revision: 1,
187
+ kind,
188
+ status,
189
+ payload,
190
+ startedAt,
191
+ completedAt
192
+ };
193
+ }
194
+ function pageEnd(cursor, sessionId, fallback) {
195
+ if (cursor === undefined)
196
+ return fallback;
197
+ try {
198
+ const parsed = record(JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8')));
199
+ return parsed?.sessionId === sessionId && Number.isInteger(parsed.end)
200
+ ? Math.min(Math.max(Number(parsed.end), 0), fallback)
201
+ : fallback;
202
+ }
203
+ catch {
204
+ return fallback;
205
+ }
206
+ }
207
+ function record(value) {
208
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
209
+ ? value
210
+ : undefined;
211
+ }
212
+ function array(value) {
213
+ return Array.isArray(value) ? value : [];
214
+ }
215
+ function number(value) {
216
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
217
+ }
@@ -0,0 +1,76 @@
1
+ import type { NodeEnvelope, RunnerCommandDescriptor, RunnerCommandState } from '@myagentroam/protocol';
2
+ import type { NodeAgentSession } from '../../database.js';
3
+ import type { FakeRunnerStatus } from '../../fake-runner.js';
4
+ import type { RunnerImageAttachment } from '../../service/run-attachment-service.js';
5
+ import { OpenCodeRunner } from '../opencode-runner.js';
6
+ interface OpenCodeManagedRunHost {
7
+ intercepted(): boolean;
8
+ readonly active: Set<string>;
9
+ parseAttachments(value: unknown): readonly RunnerImageAttachment[];
10
+ emit(runId: string, eventType: string, payload: unknown, status?: FakeRunnerStatus): void;
11
+ emitItem(runId: string, item: OpenCodePublicItem): void;
12
+ adopt(input: {
13
+ runId: string;
14
+ sessionId: string;
15
+ runner: 'opencode';
16
+ cwd: string;
17
+ externalSessionId?: string;
18
+ }): void;
19
+ promote(sessionId: string, nativeSessionId: string): void;
20
+ rememberNative(nativeSessionId: string, sessionId: string): void;
21
+ send(type: string, payload: unknown): void;
22
+ captureSnapshot(runId: string, cwd: string): Promise<void>;
23
+ createApproval(input: {
24
+ readonly runId: string;
25
+ readonly approvalId: string;
26
+ readonly payload: unknown;
27
+ readonly expiresAt: number;
28
+ }): void;
29
+ publishApproval(input: {
30
+ readonly runId: string;
31
+ readonly approvalId: string;
32
+ readonly payload: unknown;
33
+ readonly expiresAt: number;
34
+ }): void;
35
+ expireApproval(approvalId: string): void;
36
+ commandState(sessionId: string, commandId: string): RunnerCommandState | undefined;
37
+ setCommandState(sessionId: string, state: RunnerCommandState): void;
38
+ clearCommandState(sessionId: string, commandId: string): void;
39
+ commandStates(sessionId: string): readonly RunnerCommandState[];
40
+ }
41
+ type OpenCodePublicItem = {
42
+ readonly itemId: string;
43
+ readonly kind: 'assistant_message' | 'plan' | 'reasoning_summary' | 'tool_call' | 'user_input_request' | 'context_compaction' | 'file_change' | 'unknown';
44
+ readonly status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';
45
+ readonly payload: Record<string, unknown>;
46
+ readonly merge?: boolean;
47
+ };
48
+ export declare class OpenCodeManagedRunController {
49
+ private readonly runner;
50
+ private readonly host;
51
+ private readonly interactionTimeoutMs;
52
+ private readonly permissions;
53
+ private readonly questions;
54
+ private readonly startingCwds;
55
+ private readonly promptAdmitted;
56
+ private readonly pendingIdle;
57
+ private readonly startingClients;
58
+ constructor(runner: OpenCodeRunner, host: OpenCodeManagedRunHost, interactionTimeoutMs?: number);
59
+ executeCommand(session: NodeAgentSession, command: RunnerCommandDescriptor, context: {
60
+ readonly secretEnvironment: Readonly<Record<string, string>>;
61
+ }): Promise<unknown>;
62
+ start(envelope: NodeEnvelope): void;
63
+ cancel(runId: string, intent: 'CANCEL' | 'INTERRUPT'): boolean;
64
+ decideApproval(input: {
65
+ readonly runId: string;
66
+ readonly approvalId: string;
67
+ readonly decision: 'APPROVED' | 'REJECTED';
68
+ }): boolean;
69
+ respondUserInput(runId: string, requestId: string, answers: Record<string, unknown>): boolean;
70
+ private run;
71
+ private event;
72
+ private requestPermission;
73
+ private requestQuestion;
74
+ private finish;
75
+ }
76
+ export {};