@router-agent/runtime 0.0.0-stage → 0.3.31

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 (124) hide show
  1. package/dist/agents/claude.d.ts +51 -0
  2. package/dist/agents/claude.js +270 -0
  3. package/dist/agents/claude.js.map +1 -0
  4. package/dist/agents/codex.d.ts +36 -0
  5. package/dist/agents/codex.js +292 -0
  6. package/dist/agents/codex.js.map +1 -0
  7. package/dist/agents/profile.d.ts +39 -0
  8. package/dist/agents/profile.js +2 -0
  9. package/dist/agents/profile.js.map +1 -0
  10. package/dist/agents/registry.d.ts +21 -0
  11. package/dist/agents/registry.js +78 -0
  12. package/dist/agents/registry.js.map +1 -0
  13. package/dist/errors.d.ts +4 -0
  14. package/dist/errors.js +9 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/evidence-gate.d.ts +78 -0
  17. package/dist/evidence-gate.js +196 -0
  18. package/dist/evidence-gate.js.map +1 -0
  19. package/dist/index.d.ts +22 -0
  20. package/dist/index.js +21 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/naming.d.ts +23 -0
  23. package/dist/naming.js +40 -0
  24. package/dist/naming.js.map +1 -0
  25. package/dist/orca/commands.js +60 -0
  26. package/dist/orca/commands.js.map +1 -0
  27. package/dist/orca/index.js +452 -0
  28. package/dist/orca/index.js.map +1 -0
  29. package/dist/orca/options.js +33 -0
  30. package/dist/orca/options.js.map +1 -0
  31. package/dist/orca/report-poller.js +143 -0
  32. package/dist/orca/report-poller.js.map +1 -0
  33. package/dist/permissions/acp.d.ts +21 -0
  34. package/dist/permissions/acp.js +73 -0
  35. package/dist/permissions/acp.js.map +1 -0
  36. package/dist/permissions.d.ts +1 -0
  37. package/dist/permissions.js +2 -0
  38. package/dist/permissions.js.map +1 -0
  39. package/dist/plugins/loader.d.ts +46 -0
  40. package/dist/plugins/loader.js +117 -0
  41. package/dist/plugins/loader.js.map +1 -0
  42. package/dist/plugins/types.d.ts +52 -0
  43. package/dist/plugins/types.js +2 -0
  44. package/dist/plugins/types.js.map +1 -0
  45. package/dist/port.d.ts +295 -0
  46. package/dist/port.js +17 -0
  47. package/dist/port.js.map +1 -0
  48. package/dist/registry.d.ts +13 -0
  49. package/dist/registry.js +35 -0
  50. package/dist/registry.js.map +1 -0
  51. package/dist/report-poller.d.ts +58 -0
  52. package/dist/report-poller.js +130 -0
  53. package/dist/report-poller.js.map +1 -0
  54. package/dist/resume.d.ts +52 -0
  55. package/dist/resume.js +109 -0
  56. package/dist/resume.js.map +1 -0
  57. package/dist/runtimes/acp/admin.js +470 -0
  58. package/dist/runtimes/acp/admin.js.map +1 -0
  59. package/dist/runtimes/acp/agents.js +167 -0
  60. package/dist/runtimes/acp/agents.js.map +1 -0
  61. package/dist/runtimes/acp/detect.js +379 -0
  62. package/dist/runtimes/acp/detect.js.map +1 -0
  63. package/dist/runtimes/acp/index.js +633 -0
  64. package/dist/runtimes/acp/index.js.map +1 -0
  65. package/dist/runtimes/acp/install.js +264 -0
  66. package/dist/runtimes/acp/install.js.map +1 -0
  67. package/dist/runtimes/acp/permissions.js +83 -0
  68. package/dist/runtimes/acp/permissions.js.map +1 -0
  69. package/dist/runtimes/acp/protocol.js +207 -0
  70. package/dist/runtimes/acp/protocol.js.map +1 -0
  71. package/dist/runtimes/acp-agents.d.ts +85 -0
  72. package/dist/runtimes/acp-agents.js +167 -0
  73. package/dist/runtimes/acp-agents.js.map +1 -0
  74. package/dist/runtimes/acp-detect-utils.d.ts +4 -0
  75. package/dist/runtimes/acp-detect-utils.js +35 -0
  76. package/dist/runtimes/acp-detect-utils.js.map +1 -0
  77. package/dist/runtimes/builtin-options.d.ts +3 -0
  78. package/dist/runtimes/builtin-options.js +44 -0
  79. package/dist/runtimes/builtin-options.js.map +1 -0
  80. package/dist/runtimes/catalog.d.ts +31 -0
  81. package/dist/runtimes/catalog.js +75 -0
  82. package/dist/runtimes/catalog.js.map +1 -0
  83. package/dist/runtimes/claude-code/index.js +544 -0
  84. package/dist/runtimes/claude-code/index.js.map +1 -0
  85. package/dist/runtimes/claude-code/inject.js +71 -0
  86. package/dist/runtimes/claude-code/inject.js.map +1 -0
  87. package/dist/runtimes/codex/client.js +203 -0
  88. package/dist/runtimes/codex/client.js.map +1 -0
  89. package/dist/runtimes/codex/detect.js +240 -0
  90. package/dist/runtimes/codex/detect.js.map +1 -0
  91. package/dist/runtimes/codex/index.js +1066 -0
  92. package/dist/runtimes/codex/index.js.map +1 -0
  93. package/dist/runtimes/herdr/agents.js +38 -0
  94. package/dist/runtimes/herdr/agents.js.map +1 -0
  95. package/dist/runtimes/herdr/commands.js +68 -0
  96. package/dist/runtimes/herdr/commands.js.map +1 -0
  97. package/dist/runtimes/herdr/index.js +712 -0
  98. package/dist/runtimes/herdr/index.js.map +1 -0
  99. package/dist/runtimes/herdr/options.js +29 -0
  100. package/dist/runtimes/herdr/options.js.map +1 -0
  101. package/dist/runtimes/herdr/server.js +75 -0
  102. package/dist/runtimes/herdr/server.js.map +1 -0
  103. package/dist/runtimes/options.d.ts +60 -0
  104. package/dist/runtimes/options.js +89 -0
  105. package/dist/runtimes/options.js.map +1 -0
  106. package/dist/spec/contract.md +120 -0
  107. package/dist/spec/index.d.ts +35 -0
  108. package/dist/spec/index.js +59 -0
  109. package/dist/spec/index.js.map +1 -0
  110. package/dist/spec/prompt-mode.md +176 -0
  111. package/dist/spec/reader.d.ts +5 -0
  112. package/dist/spec/reader.js +32 -0
  113. package/dist/spec/reader.js.map +1 -0
  114. package/dist/status.d.ts +8 -0
  115. package/dist/status.js +22 -0
  116. package/dist/status.js.map +1 -0
  117. package/dist/workspaces/git-worktree.d.ts +44 -0
  118. package/dist/workspaces/git-worktree.js +183 -0
  119. package/dist/workspaces/git-worktree.js.map +1 -0
  120. package/dist/workspaces/overview.d.ts +66 -0
  121. package/dist/workspaces/overview.js +12 -0
  122. package/dist/workspaces/overview.js.map +1 -0
  123. package/package.json +36 -4
  124. package/README.md +0 -3
@@ -0,0 +1,143 @@
1
+ import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { z } from 'zod';
4
+ /** 旧版 state.json 的交付物字段,仅用于向后兼容,不再参与新协议。 */
5
+ const LegacyDeliverableSchema = z.object({
6
+ kind: z.string().optional(),
7
+ content: z.string().default(''),
8
+ title: z.string().optional(),
9
+ url: z.string().default(''),
10
+ }).nullable().optional();
11
+ const StateSchema = z.object({
12
+ ticket_id: z.string().min(1),
13
+ assignment_id: z.string().default(''),
14
+ turn: z.coerce.number().int().min(0).default(0),
15
+ state: z.enum(['progress', 'ready', 'blocked', 'failed', 'dropped', 'waiting']),
16
+ summary: z.string().min(1),
17
+ human_action: z.string().nullable().optional(),
18
+ pr_number: z.coerce.number().int().min(0).default(0),
19
+ pr_url: z.string().default(''),
20
+ /** Worker 要发给发起人的完整回复(Markdown)。 */
21
+ reply: z.string().optional().default(''),
22
+ /** 旧版交付物字段,读取时拼进 reply。 */
23
+ deliverable: LegacyDeliverableSchema,
24
+ acked_inputs: z.array(z.string()).default([]),
25
+ updated_at: z.string().default(() => new Date().toISOString()),
26
+ });
27
+ /** 轮询 ~/.router-agent/workers/<ticketId>/state.json,按文件内容增量上报。 */
28
+ export class ReportPoller {
29
+ workersDir;
30
+ onState;
31
+ onError;
32
+ seen = new Map();
33
+ constructor(opts) {
34
+ this.workersDir = opts.workersDir;
35
+ this.onState = opts.onState;
36
+ this.onError = opts.onError;
37
+ }
38
+ /** 扫描一轮,返回新上报数量。 */
39
+ scan() {
40
+ if (!existsSync(this.workersDir))
41
+ return 0;
42
+ let count = 0;
43
+ const entries = readdirSync(this.workersDir, { withFileTypes: true });
44
+ for (const entry of entries) {
45
+ if (!entry.isDirectory())
46
+ continue;
47
+ const ticketId = entry.name;
48
+ const statePath = join(this.workersDir, ticketId, 'state.json');
49
+ if (!existsSync(statePath))
50
+ continue;
51
+ try {
52
+ const content = readFileSync(statePath, 'utf8');
53
+ const fingerprint = `${statSync(statePath).mtimeMs}:${content}`;
54
+ if (this.seen.get(ticketId) === fingerprint)
55
+ continue;
56
+ const { ticketId: parsedId, state } = parseStateFile(content, ticketId);
57
+ this.seen.set(ticketId, fingerprint);
58
+ const meta = readMeta(this.workersDir, ticketId);
59
+ this.onState({ ...state, ticketId: parsedId }, meta, statePath);
60
+ count += 1;
61
+ }
62
+ catch (error) {
63
+ this.onError?.(ticketId, error instanceof Error ? error : new Error(String(error)));
64
+ }
65
+ }
66
+ return count;
67
+ }
68
+ /** 清空基线,让下一轮重新上报(Router 重启对账时用)。 */
69
+ reset() {
70
+ this.seen.clear();
71
+ }
72
+ }
73
+ export function parseStateFile(content, expectedTicketId) {
74
+ let json;
75
+ try {
76
+ json = JSON.parse(content);
77
+ }
78
+ catch {
79
+ throw new Error('state:invalid-json');
80
+ }
81
+ const parsed = StateSchema.safeParse(json);
82
+ if (!parsed.success)
83
+ throw new Error(`state:invalid: ${parsed.error.issues.map(i => i.path.join('.')).join(',')}`);
84
+ if (expectedTicketId && parsed.data.ticket_id !== expectedTicketId) {
85
+ throw new Error(`state:ticket-mismatch: 目录 ${expectedTicketId} 收到 ${parsed.data.ticket_id}`);
86
+ }
87
+ const data = parsed.data;
88
+ const legacy = data.deliverable;
89
+ // 旧版 deliverable 升级成纯回复:正文 + 链接,不再保留 kind。
90
+ const reply = data.reply.trim() || [legacy?.content?.trim(), legacy?.url?.trim()].filter(Boolean).join('\n\n');
91
+ return {
92
+ ticketId: data.ticket_id,
93
+ state: {
94
+ ticketId: data.ticket_id,
95
+ assignmentId: data.assignment_id,
96
+ turn: data.turn,
97
+ state: data.state,
98
+ summary: data.summary,
99
+ ...(data.human_action ? { humanAction: data.human_action } : {}),
100
+ prNumber: data.pr_number,
101
+ prUrl: data.pr_url,
102
+ ...(reply ? { reply } : {}),
103
+ ackedInputs: data.acked_inputs,
104
+ updatedAt: data.updated_at,
105
+ },
106
+ };
107
+ }
108
+ function readMeta(workersDir, ticketId) {
109
+ const path = join(workersDir, ticketId, 'meta.json');
110
+ if (!existsSync(path))
111
+ return null;
112
+ try {
113
+ return JSON.parse(readFileSync(path, 'utf8'));
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ /**
120
+ * 基于 Orca 的结构化字段判定终端状态,绝不解析 TUI 屏幕文本。
121
+ */
122
+ export function judgeIdle(input) {
123
+ const { info, turn, lastTurn, now, idleAfterMs } = input;
124
+ if (!info)
125
+ return 'unknown';
126
+ if (!info.connected)
127
+ return 'dead';
128
+ // 实测:CLI 创建的终端可能 orphaned=true 但依然 connected+writable,不能直接判死。
129
+ if (info.orphaned && !info.writable)
130
+ return 'orphaned';
131
+ const lastOutput = Date.parse(info.lastOutputAt);
132
+ if (Number.isFinite(lastOutput) && now - lastOutput > idleAfterMs && turn <= lastTurn)
133
+ return 'idle';
134
+ return 'active';
135
+ }
136
+ /** 追加一条审计事件到 events.log。 */
137
+ export function appendEvent(path, event) {
138
+ mkdirSync(join(path, '..'), { recursive: true });
139
+ if (!existsSync(path))
140
+ writeFileSync(path, '', 'utf8');
141
+ appendFileSync(path, `${JSON.stringify(event)}\n`, 'utf8');
142
+ }
143
+ //# sourceMappingURL=report-poller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-poller.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/orca/report-poller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ToolPolicy } from '../port.js';
2
+ /** ACP 的 ToolKind 取值(允许后端扩展,未知值按 other 处理)。 */
3
+ export type AcpToolKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'think' | 'fetch' | 'other';
4
+ export interface AcpToolCallInfo {
5
+ toolCallId: string;
6
+ title?: string;
7
+ kind?: string;
8
+ rawInput?: unknown;
9
+ locations?: Array<{
10
+ path?: string;
11
+ }>;
12
+ }
13
+ export interface AcpPermissionOption {
14
+ optionId: string;
15
+ name?: string;
16
+ kind: string;
17
+ }
18
+ export declare function decidePermission(tools: ToolPolicy, toolCall: AcpToolCallInfo, options: AcpPermissionOption[]): AcpPermissionOption | null;
19
+ export declare function isAllowed(tools: ToolPolicy, kind: AcpToolKind, toolCall: AcpToolCallInfo): boolean;
20
+ export declare function shellAllowed(tools: ToolPolicy, command: string | null): boolean;
21
+ export declare function commandOf(toolCall: AcpToolCallInfo): string | null;
@@ -0,0 +1,73 @@
1
+ export function decidePermission(tools, toolCall, options) {
2
+ const kind = normalizeKind(toolCall.kind);
3
+ const allowed = isAllowed(tools, kind, toolCall);
4
+ const desired = allowed ? 'allow' : 'reject';
5
+ return options.find(option => option.kind.startsWith(desired)) ?? null;
6
+ }
7
+ export function isAllowed(tools, kind, toolCall) {
8
+ switch (kind) {
9
+ case 'read':
10
+ case 'search':
11
+ case 'think':
12
+ return true;
13
+ case 'fetch':
14
+ return tools.allowNetwork;
15
+ case 'edit':
16
+ case 'move':
17
+ case 'delete':
18
+ return tools.fileAccess === 'read-write';
19
+ case 'execute':
20
+ return shellAllowed(tools, commandOf(toolCall));
21
+ case 'other':
22
+ default:
23
+ return tools.fileAccess === 'read-write';
24
+ }
25
+ }
26
+ export function shellAllowed(tools, command) {
27
+ if (tools.shell === 'deny')
28
+ return false;
29
+ if (tools.shell === 'allow')
30
+ return true;
31
+ if (!command)
32
+ return false;
33
+ return (tools.shellAllow ?? []).some(prefix => {
34
+ const value = prefix.trim();
35
+ if (!value)
36
+ return false;
37
+ return command === value || command.startsWith(`${value} `);
38
+ });
39
+ }
40
+ export function commandOf(toolCall) {
41
+ const raw = toolCall.rawInput;
42
+ if (raw && typeof raw === 'object') {
43
+ const record = raw;
44
+ if (typeof record.command === 'string')
45
+ return record.command.trim() || null;
46
+ if (Array.isArray(record.command) && record.command.every(item => typeof item === 'string')) {
47
+ return record.command.join(' ').trim() || null;
48
+ }
49
+ const argv = record.argv ?? record.args;
50
+ if (Array.isArray(argv) && argv.every(item => typeof item === 'string')) {
51
+ return argv.join(' ').trim() || null;
52
+ }
53
+ }
54
+ if (typeof toolCall.title === 'string')
55
+ return toolCall.title.trim() || null;
56
+ return null;
57
+ }
58
+ function normalizeKind(kind) {
59
+ switch (kind) {
60
+ case 'read':
61
+ case 'edit':
62
+ case 'delete':
63
+ case 'move':
64
+ case 'search':
65
+ case 'execute':
66
+ case 'think':
67
+ case 'fetch':
68
+ return kind;
69
+ default:
70
+ return 'other';
71
+ }
72
+ }
73
+ //# sourceMappingURL=acp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acp.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/permissions/acp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './permissions/acp.js';
@@ -0,0 +1,2 @@
1
+ export * from './permissions/acp.js';
2
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../../../packages/runtime/src/permissions.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,46 @@
1
+ import type { RuntimeConfigView } from '@router-agent/core/config.js';
2
+ import { type Logger } from '@router-agent/infra/logger.js';
3
+ import type { CommandRunner } from '@router-agent/infra/process.js';
4
+ import { type PluginFailure } from '@router-agent/infra/plugin-loader.js';
5
+ import { RuntimeRegistry } from '../registry.js';
6
+ import type { RuntimeOptionSpec } from '../runtimes/options.js';
7
+ import type { PluginEntry, PluginModuleLoader } from '../plugins/types.js';
8
+ import type { RuntimePluginMeta } from './types.js';
9
+ export declare const DEFAULT_RUNTIME_PLUGINS: Readonly<Record<string, string>>;
10
+ export interface RuntimePluginConfigView extends RuntimeConfigView {
11
+ runtime: RuntimeConfigView['runtime'] & {
12
+ plugins?: Record<string, PluginEntry>;
13
+ };
14
+ }
15
+ export declare function pluginEntryOf(config: RuntimePluginConfigView, kind: 'runtime', id: string): string;
16
+ export declare function describePluginLoadError(kind: 'runtime' | 'channel', id: string, error: unknown): string;
17
+ export interface RuntimePluginDeps {
18
+ home: string;
19
+ workersDir: string;
20
+ logger?: Logger;
21
+ env?: NodeJS.ProcessEnv;
22
+ runners?: {
23
+ orca?: CommandRunner;
24
+ claude?: CommandRunner;
25
+ git?: CommandRunner;
26
+ herdr?: CommandRunner;
27
+ };
28
+ claudeBin?: string;
29
+ claudeProjectsDir?: string;
30
+ loader?: PluginModuleLoader;
31
+ /** 测试注入:跳过内置包加载。 */
32
+ builtins?: readonly string[];
33
+ }
34
+ export interface LoadedRuntimePlugins {
35
+ registry: RuntimeRegistry;
36
+ metas: RuntimePluginMeta[];
37
+ specs: RuntimeOptionSpec[];
38
+ /** 已加载的运行时 id;未知 id 用于配置校验。 */
39
+ ids: string[];
40
+ /** 插件元数据 id → createAll() 实际注册的运行时 id;自定义多实例运行时用。 */
41
+ loadedIds: Record<string, string[]>;
42
+ /** 加载失败的插件;启动不阻塞,但面板与 doctor 要能看到。 */
43
+ failures: PluginFailure[];
44
+ }
45
+ /** 加载 runtime 插件并创建 adapter;单个插件失败只记录,不阻塞其它运行时。 */
46
+ export declare function loadRuntimePlugins(config: RuntimePluginConfigView, deps: RuntimePluginDeps): Promise<LoadedRuntimePlugins>;
@@ -0,0 +1,117 @@
1
+ import { errorMessage, noopLogger } from '@router-agent/infra/logger.js';
2
+ import { loadPluginModules, pluginEntryTarget, pluginSpecifier, } from '@router-agent/infra/plugin-loader.js';
3
+ import { RuntimeRegistry } from '../registry.js';
4
+ import { RuntimePluginError } from '../errors.js';
5
+ export const DEFAULT_RUNTIME_PLUGINS = {
6
+ orca: '@router-agent/runtime-orca',
7
+ 'claude-code': '@router-agent/runtime-claude-code',
8
+ 'codex-app': '@router-agent/runtime-codex',
9
+ acp: '@router-agent/runtime-acp',
10
+ herdr: '@router-agent/runtime-herdr',
11
+ };
12
+ export function pluginEntryOf(config, kind, id) {
13
+ const entry = config.runtime.plugins?.[id];
14
+ return pluginSpecifier(entry) ?? DEFAULT_RUNTIME_PLUGINS[id] ?? id;
15
+ }
16
+ export function describePluginLoadError(kind, id, error) {
17
+ return `${kind} 插件 ${id} 加载失败:${errorMessage(error)}`;
18
+ }
19
+ /** 加载 runtime 插件并创建 adapter;单个插件失败只记录,不阻塞其它运行时。 */
20
+ export async function loadRuntimePlugins(config, deps) {
21
+ const logger = deps.logger ?? noopLogger;
22
+ const loader = deps.loader;
23
+ const entries = config.runtime.plugins;
24
+ const builtins = deps.builtins ?? Object.keys(DEFAULT_RUNTIME_PLUGINS);
25
+ const ids = [...new Set([...builtins, ...Object.keys(entries ?? {})])];
26
+ const loaded = await loadPluginModules({
27
+ kind: 'runtime',
28
+ home: deps.home,
29
+ ids,
30
+ ...(loader ? { loader } : {}),
31
+ logger,
32
+ specifierOf: id => specifierOf(entries, id),
33
+ entryOf: id => pluginEntryTarget(entries?.[id]),
34
+ });
35
+ const plugins = loaded.plugins;
36
+ const ctx = {
37
+ home: deps.home,
38
+ workersDir: deps.workersDir,
39
+ config,
40
+ env: deps.env ?? process.env,
41
+ logger,
42
+ runners: {
43
+ orca: deps.runners?.orca ?? missingRunner('orca'),
44
+ claude: deps.runners?.claude ?? missingRunner('claude'),
45
+ git: deps.runners?.git ?? missingRunner('git'),
46
+ herdr: deps.runners?.herdr ?? missingRunner('herdr'),
47
+ },
48
+ ...(deps.claudeBin ? { claudeBin: deps.claudeBin } : {}),
49
+ ...(deps.claudeProjectsDir ? { claudeProjectsDir: deps.claudeProjectsDir } : {}),
50
+ };
51
+ const runtimes = new Map();
52
+ const metas = [];
53
+ const specs = [];
54
+ const loadedIds = {};
55
+ for (const { id, plugin } of loaded.entries) {
56
+ try {
57
+ const instances = plugin.createAll ? await plugin.createAll(ctx) : [await plugin.create(ctx)];
58
+ const ids = [];
59
+ for (const runtime of instances) {
60
+ if (!runtime)
61
+ continue;
62
+ runtimes.set(runtime.id, runtime);
63
+ ids.push(runtime.id);
64
+ logger.info('plugin:loaded', { kind: 'runtime', id: runtime.id });
65
+ }
66
+ if (plugin.meta) {
67
+ if (plugin.meta.id !== id) {
68
+ logger.warn('plugin:id-mismatch', {
69
+ kind: 'runtime',
70
+ id,
71
+ declared: plugin.meta.id,
72
+ detail: '配置里的插件 id 与插件声明的 meta.id 不一致,请改成一致以便面板回链',
73
+ });
74
+ }
75
+ // 以配置 id 作为面板身份,声明 id 只用于说明;实例 id 另存。
76
+ metas.push({ ...plugin.meta, id });
77
+ loadedIds[id] = ids;
78
+ }
79
+ if (plugin.options)
80
+ specs.push(plugin.options);
81
+ // createAll 没声明 meta 时也要把实例 id 记下来,否则无法按插件回推。
82
+ if (!plugin.meta && ids.length > 0)
83
+ loadedIds[id] = ids;
84
+ }
85
+ catch (error) {
86
+ const failureId = id || plugin.meta?.id || 'unknown';
87
+ logger.error('plugin:create-failed', { kind: 'runtime', id: failureId, detail: errorMessage(error) });
88
+ loaded.failures.push({ kind: 'runtime', id: failureId, specifier: pluginEntryOf(config, 'runtime', failureId), message: errorMessage(error) });
89
+ }
90
+ }
91
+ const defaultId = config.runtime.default;
92
+ if (runtimes.size === 0) {
93
+ throw new RuntimePluginError('plugin:not-found', `没有可用的 runtime 插件,无法启动 ${defaultId}`);
94
+ }
95
+ return {
96
+ registry: new RuntimeRegistry(runtimes, defaultId),
97
+ metas,
98
+ specs,
99
+ ids: [...runtimes.keys()],
100
+ loadedIds,
101
+ failures: loaded.failures,
102
+ };
103
+ }
104
+ function specifierOf(entries, id) {
105
+ const entry = entries?.[id];
106
+ if (entry !== undefined)
107
+ return pluginSpecifier(entry);
108
+ return DEFAULT_RUNTIME_PLUGINS[id] ?? id;
109
+ }
110
+ function missingRunner(bin) {
111
+ return {
112
+ async run() {
113
+ throw new Error(`runtime 插件未注入 ${bin} 运行器`);
114
+ },
115
+ };
116
+ }
117
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/plugins/loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,+BAA+B,CAAA;AAErF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAEhB,MAAM,sCAAsC,CAAA;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAKjD,MAAM,CAAC,MAAM,uBAAuB,GAAqC;IACvE,IAAI,EAAE,4BAA4B;IAClC,aAAa,EAAE,mCAAmC;IAClD,WAAW,EAAE,6BAA6B;IAC1C,GAAG,EAAE,2BAA2B;IAChC,KAAK,EAAE,6BAA6B;CACrC,CAAA;AAQD,MAAM,UAAU,aAAa,CAC3B,MAA+B,EAC/B,IAAe,EACf,EAAU;IAEV,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;IAC1C,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAA2B,EAAE,EAAU,EAAE,KAAc;IAC7F,OAAO,GAAG,IAAI,OAAO,EAAE,SAAS,YAAY,CAAC,KAAK,CAAC,EAAE,CAAA;AACvD,CAAC;AAgCD,mDAAmD;AACnD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAA+B,EAC/B,IAAuB;IAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAA;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;IACtE,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACtE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAgB;QACpD,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG;QACH,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM;QACN,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;KAChD,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;IAC9B,MAAM,GAAG,GAAyB;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM;QACN,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG;QAC5B,MAAM;QACN,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC;YACjD,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC;YACvD,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC;YAC9C,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC;SACrD;QACD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjF,CAAA;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAA;IACjD,MAAM,KAAK,GAAwB,EAAE,CAAA;IACrC,MAAM,KAAK,GAAwB,EAAE,CAAA;IACrC,MAAM,SAAS,GAA6B,EAAE,CAAA;IAC9C,KAAK,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7F,MAAM,GAAG,GAAa,EAAE,CAAA;YACxB,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;gBAChC,IAAI,CAAC,OAAO;oBAAE,SAAQ;gBACtB,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;gBACjC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;gBACpB,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;YACnE,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;gBAChB,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;wBAChC,IAAI,EAAE,SAAS;wBACf,EAAE;wBACF,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;wBACxB,MAAM,EAAE,0CAA0C;qBACnD,CAAC,CAAA;gBACJ,CAAC;gBACD,sCAAsC;gBACtC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;gBAClC,SAAS,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;YACrB,CAAC;YACD,IAAI,MAAM,CAAC,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC9C,8CAA8C;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,SAAS,CAAA;YACpD,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACrG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAChJ,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAA;IACxC,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,yBAAyB,SAAS,EAAE,CAAC,CAAA;IACxF,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,IAAI,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC;QAClD,KAAK;QACL,KAAK;QACL,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzB,SAAS;QACT,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,OAAgD,EAAE,EAAU;IAC/E,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAA;IACtD,OAAO,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;AAC1C,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO;QACL,KAAK,CAAC,GAAG;YACP,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,MAAM,CAAC,CAAA;QAC7C,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { RuntimeConfigView } from '@router-agent/core/config.js';
2
+ import type { CommandRunner } from '@router-agent/infra/process.js';
3
+ import type { Logger } from '@router-agent/infra/logger.js';
4
+ import type { PluginEntry, PluginModuleLoader } from '@router-agent/infra/plugin-loader.js';
5
+ import type { WorkerRuntime } from '../port.js';
6
+ import type { RuntimeOptionSpec } from '../runtimes/options.js';
7
+ export type { PluginEntry, PluginModuleLoader };
8
+ /** 运行时插件元数据;Web 面板与配置校验共用。 */
9
+ export interface RuntimePluginMeta {
10
+ id: string;
11
+ name: string;
12
+ label: string;
13
+ hint: string;
14
+ installHint?: string;
15
+ installUrl?: string;
16
+ /** 是否可由 ra 自动安装(ACP 扩展)。 */
17
+ installable?: boolean;
18
+ packageName?: string;
19
+ /** 已有原生运行时替代品:面板不再作为可选项展示。 */
20
+ deprecated?: boolean;
21
+ /** 是否接受非本地仓库选择器(Orca 的 name: / id:)。 */
22
+ repoSelector?: boolean;
23
+ }
24
+ /** 运行时 adapter 创建上下文;宿主只注入中立依赖。 */
25
+ export interface RuntimePluginContext {
26
+ home: string;
27
+ workersDir: string;
28
+ config: RuntimeConfigView;
29
+ env: NodeJS.ProcessEnv;
30
+ logger: Logger;
31
+ /** 运行时可能需要的工作目录运行器;插件自行选择使用哪一个。 */
32
+ runners: {
33
+ orca: CommandRunner;
34
+ claude: CommandRunner;
35
+ git: CommandRunner;
36
+ herdr: CommandRunner;
37
+ };
38
+ claudeBin?: string;
39
+ claudeProjectsDir?: string;
40
+ }
41
+ /** 运行时插件:一个包可以导出多个运行时实例。 */
42
+ export interface RuntimePlugin {
43
+ kind: 'runtime';
44
+ meta?: RuntimePluginMeta;
45
+ /** 声明面板可配置项;配置落点统一为 runtime.options.<id>.<key>。 */
46
+ options?: RuntimeOptionSpec;
47
+ /** 创建 adapter;返回 null 表示当前配置下不启用(例如未配置 command)。 */
48
+ create(ctx: RuntimePluginContext): WorkerRuntime | null | Promise<WorkerRuntime | null>;
49
+ /** 附加运行时;ACP 这类目录型插件用它一次注册多个 id。 */
50
+ createAll?(ctx: RuntimePluginContext): Array<WorkerRuntime | null> | Promise<Array<WorkerRuntime | null>>;
51
+ }
52
+ export type Plugin = RuntimePlugin;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/plugins/types.ts"],"names":[],"mappings":""}