larkin 0.2.70

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 (144) hide show
  1. package/CONTRIBUTING.md +48 -0
  2. package/LICENSE +201 -0
  3. package/README.md +122 -0
  4. package/SECURITY.md +14 -0
  5. package/artifacts/release/THIRD_PARTY_NOTICES.txt +5488 -0
  6. package/dist/agent/agent-cli-capabilities.cjs +43 -0
  7. package/dist/agent/agent-cli-capabilities.mjs +35 -0
  8. package/dist/agent/agent-state-store.cjs +961 -0
  9. package/dist/agent/agent-state-store.mjs +923 -0
  10. package/dist/agent/agent-transport.cjs +201 -0
  11. package/dist/agent/agent-transport.mjs +194 -0
  12. package/dist/agent/config-cli-contract.cjs +19 -0
  13. package/dist/agent/config-cli-contract.mjs +16 -0
  14. package/dist/agent/context-prompt.cjs +159 -0
  15. package/dist/agent/context-prompt.mjs +155 -0
  16. package/dist/agent/freshness-gate.mjs +24 -0
  17. package/dist/agent/history-projection.cjs +72 -0
  18. package/dist/agent/history-projection.mjs +65 -0
  19. package/dist/agent/host-reminder-orchestrator.cjs +289 -0
  20. package/dist/agent/host-reminder-orchestrator.mjs +252 -0
  21. package/dist/agent/inbox-projection.cjs +92 -0
  22. package/dist/agent/inbox-projection.mjs +85 -0
  23. package/dist/agent/interaction-state-machine.cjs +710 -0
  24. package/dist/agent/interaction-state-machine.mjs +705 -0
  25. package/dist/agent/reminder-routes.cjs +192 -0
  26. package/dist/agent/reminder-routes.mjs +156 -0
  27. package/dist/agent/reminder-store.cjs +220 -0
  28. package/dist/agent/reminder-store.mjs +205 -0
  29. package/dist/agent/transport-business-context.cjs +486 -0
  30. package/dist/agent/transport-business-context.mjs +446 -0
  31. package/dist/agent/transport-shell.cjs +45 -0
  32. package/dist/agent/transport-shell.mjs +39 -0
  33. package/dist/app/agent-cli.mjs +596 -0
  34. package/dist/app/agent-config.mjs +633 -0
  35. package/dist/app/agent-lark-cli-workspace.cjs +95 -0
  36. package/dist/app/agent-lark-cli-workspace.mjs +85 -0
  37. package/dist/app/agent-readiness.cjs +42 -0
  38. package/dist/app/agent-readiness.mjs +38 -0
  39. package/dist/app/binary-entry.mjs +86 -0
  40. package/dist/app/cli.mjs +176 -0
  41. package/dist/app/dashboard.mjs +205 -0
  42. package/dist/app/internal-command.cjs +57 -0
  43. package/dist/app/internal-command.mjs +48 -0
  44. package/dist/app/lark-channel-secret.mjs +22 -0
  45. package/dist/app/lark-cli.mjs +887 -0
  46. package/dist/app/lark.mjs +45 -0
  47. package/dist/app/local-control.mjs +728 -0
  48. package/dist/app/official-lark-cli.cjs +138 -0
  49. package/dist/app/official-lark-cli.mjs +128 -0
  50. package/dist/app/pi-auth-cli.mjs +67 -0
  51. package/dist/app/run.mjs +364 -0
  52. package/dist/app/runtime-agent-config.mjs +416 -0
  53. package/dist/app/runtime-model-directory.mjs +78 -0
  54. package/dist/app/runtime-process.mjs +113 -0
  55. package/dist/app/session-cli.mjs +83 -0
  56. package/dist/app/setup-dashboard.mjs +26 -0
  57. package/dist/app/setup.mjs +166 -0
  58. package/dist/app/telemetry.mjs +83 -0
  59. package/dist/dashboard/dashboard-assets.mjs +21 -0
  60. package/dist/dashboard/dashboard-avatar.mjs +128 -0
  61. package/dist/dashboard/dashboard-config-controller.mjs +525 -0
  62. package/dist/dashboard/dashboard-lifecycle.cjs +97 -0
  63. package/dist/dashboard/dashboard-lifecycle.mjs +88 -0
  64. package/dist/dashboard/dashboard-template.mjs +29 -0
  65. package/dist/dashboard/dashboard-view-model.mjs +556 -0
  66. package/dist/dashboard/dashboard-workspace.mjs +104 -0
  67. package/dist/dashboard/web/assets/dashboard.css +3 -0
  68. package/dist/dashboard/web/assets/dashboard.js +49 -0
  69. package/dist/feishu/channel-transport.cjs +151 -0
  70. package/dist/feishu/channel-transport.mjs +148 -0
  71. package/dist/feishu/document-comment.cjs +120 -0
  72. package/dist/feishu/document-comment.mjs +109 -0
  73. package/dist/feishu/host-business-state.cjs +477 -0
  74. package/dist/feishu/host-business-state.mjs +462 -0
  75. package/dist/feishu/host-channel-business.cjs +161 -0
  76. package/dist/feishu/host-channel-business.mjs +157 -0
  77. package/dist/feishu/host-processing-eye.cjs +185 -0
  78. package/dist/feishu/host-processing-eye.mjs +181 -0
  79. package/dist/feishu/host-shell.cjs +1425 -0
  80. package/dist/feishu/host-shell.mjs +1385 -0
  81. package/dist/feishu/im-freshness-adapter.mjs +89 -0
  82. package/dist/feishu/interaction-orchestrator.cjs +279 -0
  83. package/dist/feishu/interaction-orchestrator.mjs +242 -0
  84. package/dist/feishu/lark-passthrough.mjs +70 -0
  85. package/dist/feishu/message-policy.cjs +111 -0
  86. package/dist/feishu/message-policy.mjs +98 -0
  87. package/dist/feishu/outbound-transport.cjs +221 -0
  88. package/dist/feishu/outbound-transport.mjs +215 -0
  89. package/dist/platform/build-info.cjs +25 -0
  90. package/dist/platform/build-info.mjs +18 -0
  91. package/dist/platform/callback-capability.cjs +301 -0
  92. package/dist/platform/callback-capability.mjs +252 -0
  93. package/dist/platform/check-bun-version.cjs +12 -0
  94. package/dist/platform/config.cjs +751 -0
  95. package/dist/platform/config.mjs +694 -0
  96. package/dist/platform/process-inspect.cjs +89 -0
  97. package/dist/platform/process-state.cjs +237 -0
  98. package/dist/platform/process-state.mjs +223 -0
  99. package/dist/platform/release-artifacts.mjs +61 -0
  100. package/dist/platform/root-layout.cjs +111 -0
  101. package/dist/platform/root-layout.mjs +72 -0
  102. package/dist/platform/telemetry-config.cjs +64 -0
  103. package/dist/platform/telemetry-config.mjs +56 -0
  104. package/dist/platform/telemetry-spool.cjs +661 -0
  105. package/dist/platform/telemetry-spool.mjs +653 -0
  106. package/dist/platform/telemetry-tracing.cjs +602 -0
  107. package/dist/platform/telemetry-tracing.mjs +596 -0
  108. package/dist/platform/telemetry-uploader.cjs +150 -0
  109. package/dist/platform/telemetry-uploader.mjs +146 -0
  110. package/dist/platform/workspace-service.cjs +469 -0
  111. package/dist/platform/workspace-service.mjs +430 -0
  112. package/dist/runtime/builtin-pi-assets.mjs +33 -0
  113. package/dist/runtime/claude-model-catalog.cjs +102 -0
  114. package/dist/runtime/claude-model-catalog.mjs +99 -0
  115. package/dist/runtime/codex-model-catalog.cjs +108 -0
  116. package/dist/runtime/codex-model-catalog.mjs +105 -0
  117. package/dist/runtime/pi-bash-timeout-extension.mjs +60 -0
  118. package/dist/runtime/pi-bash-timeout-injection.mjs +60 -0
  119. package/dist/runtime/pi-bash-timeout.bundle.js +43 -0
  120. package/dist/runtime/pi-model-catalog.cjs +116 -0
  121. package/dist/runtime/pi-model-catalog.mjs +75 -0
  122. package/dist/runtime/pi-official-auth.mjs +480 -0
  123. package/dist/runtime/pi-provider-config.cjs +252 -0
  124. package/dist/runtime/pi-provider-config.mjs +239 -0
  125. package/dist/runtime/pi-rpc-client.cjs +255 -0
  126. package/dist/runtime/pi-rpc-client.mjs +251 -0
  127. package/dist/runtime/pi-subagent-injection.mjs +129 -0
  128. package/dist/runtime/pi-subagents.bundle.js +8990 -0
  129. package/dist/runtime/runtime-adapters.mjs +1019 -0
  130. package/dist/runtime/runtime-contracts.cjs +2 -0
  131. package/dist/runtime/runtime-contracts.mjs +1 -0
  132. package/dist/runtime/runtime-host.cjs +930 -0
  133. package/dist/runtime/runtime-host.mjs +922 -0
  134. package/dist/runtime/runtime-model-catalog.cjs +43 -0
  135. package/dist/runtime/runtime-model-catalog.mjs +40 -0
  136. package/dist/runtime/runtime-readiness.cjs +177 -0
  137. package/dist/runtime/runtime-readiness.mjs +133 -0
  138. package/dist/setup/bot-register.mjs +655 -0
  139. package/dist/setup/grant-scopes.mjs +133 -0
  140. package/dist/setup/run-credential-preflight.mjs +89 -0
  141. package/dist/setup/setup-agent-choice.mjs +172 -0
  142. package/dist/setup/setup-bind.mjs +337 -0
  143. package/dist/setup/setup-binding.mjs +52 -0
  144. package/package.json +112 -0
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env bun
2
+ import "../platform/check-bun-version.cjs";
3
+ // Internal dashboard child —— 本地监控与受限配置面板,由 larkin start supervisor 启动和恢复。
4
+ // 连接状态/各自的活动时间线/指示灯是否卡住/最近错误/工作空间/提醒。Ctrl+C 停止,不常驻、不落 launchd
5
+ // (与 start 同哲学)。零新依赖:只用 node:http 读本地状态文件,不打飞书 API,所以哪怕 daemon
6
+ // 没在跑也能看最后一次的状态(daemon 存活单独判定:daemon-status.json 的 pid 探活)。
7
+ //
8
+ // 分层:本文件只做 server/controller(端口、锁、路由、退出);状态投影在 dashboard-view-model.ts,
9
+ // 页面模板在 dashboard-template.ts。
10
+ //
11
+ // 内部启动参数:默认从 9996 开始,端口占用时依次尝试;`--port` 可固定测试端口。
12
+ // 公开入口只有 `larkin start`,不要重新暴露独立 dashboard 命令。
13
+ import fs from "node:fs";
14
+ import http from "node:http";
15
+ import path from "node:path";
16
+ import crypto from "node:crypto";
17
+ import { spawnSync } from "node:child_process";
18
+ import { fileURLToPath } from "node:url";
19
+ import { currentProcessMetadata, readJson } from "../platform/process-state.mjs";
20
+ import { prepareDashboardLaunch } from "../dashboard/dashboard-lifecycle.mjs";
21
+ import { DASHBOARD_BUILD_FINGERPRINT, DASHBOARD_BUILD_VERSION, PACKAGE_VERSION, collectStatus, collectWorkspaceEntry, loadDashboardConfig, resolveDashboardAvatarSource } from "../dashboard/dashboard-view-model.mjs";
22
+ import { renderDashboardHtml } from "../dashboard/dashboard-template.mjs";
23
+ import { createDashboardConfigController, createPiModelDirectoryResolver } from "../dashboard/dashboard-config-controller.mjs";
24
+ import { createDashboardAvatarController } from "../dashboard/dashboard-avatar.mjs";
25
+ import { processCommandToken } from "./internal-command.mjs";
26
+ import { dashboardAsset } from "../dashboard/dashboard-assets.mjs";
27
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
28
+ const ROOT = path.resolve(HERE, "../..");
29
+ const argv = process.argv.slice(2);
30
+ const flag = (name) => { const i = argv.indexOf(name); return i >= 0 ? argv[i + 1] : undefined; };
31
+ const has = (name) => argv.includes(name);
32
+ const explicitPort = flag("--port");
33
+ let port = Number(explicitPort || process.env.LARKIN_DASHBOARD_PORT || 9996);
34
+ const listenHost = "127.0.0.1"; // 会话摘要只允许本机读取,不能意外暴露到局域网。
35
+ const autoSelectPort = !explicitPort;
36
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
37
+ console.error("✗ dashboard 端口必须是 1-65535 的整数");
38
+ process.exit(1);
39
+ }
40
+ const { config: startupConfig } = loadDashboardConfig();
41
+ const DASHBOARD_STATUS_FILE = path.join(startupConfig.larkinHome, "dashboard-status.json");
42
+ const BUILD_FINGERPRINT = DASHBOARD_BUILD_FINGERPRINT;
43
+ const DASHBOARD_COMMAND_TOKEN = processCommandToken("dashboard", "app/dashboard.mjs");
44
+ function openBrowser(url) {
45
+ const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
46
+ const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
47
+ return spawnSync(command, args, { stdio: "ignore" }).status === 0;
48
+ }
49
+ let preparedDashboard;
50
+ try {
51
+ preparedDashboard = await prepareDashboardLaunch(startupConfig.larkinHome, BUILD_FINGERPRINT, DASHBOARD_COMMAND_TOKEN);
52
+ }
53
+ catch (error) {
54
+ console.error(`✗ 无法准备 dashboard:${error instanceof Error ? error.message : String(error)}`);
55
+ process.exit(1);
56
+ }
57
+ if (preparedDashboard.action === "reuse") {
58
+ preparedDashboard.release();
59
+ console.log(`✓ dashboard 已在运行(pid ${preparedDashboard.record.pid}):${preparedDashboard.record.url}`);
60
+ if (has("--open") && preparedDashboard.record.url) {
61
+ const existingUrl = String(preparedDashboard.record.url);
62
+ console.log(openBrowser(existingUrl) ? "dashboard 已在默认浏览器打开" : `请手动打开 ${existingUrl}`);
63
+ }
64
+ process.exit(0);
65
+ }
66
+ const dashboardLaunchLock = { release: preparedDashboard.release };
67
+ const csrfCapability = crypto.randomBytes(32).toString("base64url");
68
+ const HTML = renderDashboardHtml(PACKAGE_VERSION, DASHBOARD_BUILD_VERSION, BUILD_FINGERPRINT, csrfCapability);
69
+ const piModelResolver = createPiModelDirectoryResolver();
70
+ const configController = createDashboardConfigController({ csrfCapability, piModelDirectoryResolver: piModelResolver });
71
+ const avatarController = createDashboardAvatarController({ resolveSource: resolveDashboardAvatarSource });
72
+ const server = http.createServer(async (req, res) => {
73
+ const requestUrl = new URL(req.url || "/", "http://localhost");
74
+ if (req.url === "/assets/larkin-mark.svg") {
75
+ const asset = dashboardAsset("larkin-mark.svg", ROOT);
76
+ if (!asset) {
77
+ res.writeHead(404);
78
+ res.end("not found");
79
+ return;
80
+ }
81
+ res.writeHead(200, { "Content-Type": asset.contentType, "Cache-Control": "public, max-age=3600" });
82
+ res.end(asset.body);
83
+ return;
84
+ }
85
+ const webAsset = /^\/dashboard-assets\/([A-Za-z0-9._-]+)$/.exec(requestUrl.pathname);
86
+ if (webAsset) {
87
+ const name = webAsset[1];
88
+ if (name !== "dashboard.css" && name !== "dashboard.js") {
89
+ res.writeHead(404);
90
+ res.end("not found");
91
+ return;
92
+ }
93
+ const asset = dashboardAsset(name, ROOT);
94
+ if (!asset) {
95
+ res.writeHead(404);
96
+ res.end("not found");
97
+ return;
98
+ }
99
+ res.writeHead(200, { "Content-Type": asset.contentType, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff" });
100
+ res.end(asset.body);
101
+ return;
102
+ }
103
+ if (req.url === "/api/status") {
104
+ let body;
105
+ try {
106
+ body = JSON.stringify(await collectStatus({ piModelResolver }));
107
+ }
108
+ catch (error) {
109
+ res.writeHead(500, { "Content-Type": "application/json" });
110
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
111
+ return;
112
+ }
113
+ res.writeHead(200, { "Content-Type": "application/json", "Cache-Control": "no-store" });
114
+ res.end(body);
115
+ return;
116
+ }
117
+ if (await avatarController.handle(req, res, requestUrl))
118
+ return;
119
+ if (await configController.handle(req, res, requestUrl))
120
+ return;
121
+ if (requestUrl.pathname === "/api/workspace") {
122
+ try {
123
+ const body = JSON.stringify(collectWorkspaceEntry(requestUrl.searchParams.get("agent"), requestUrl.searchParams.get("path") || ""));
124
+ res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store" });
125
+ res.end(body);
126
+ }
127
+ catch (error) {
128
+ const statusCode = typeof error === "object" && error !== null && "statusCode" in error && typeof error.statusCode === "number" ? error.statusCode : 500;
129
+ res.writeHead(statusCode, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store" });
130
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
131
+ }
132
+ return;
133
+ }
134
+ if (requestUrl.pathname === "/") {
135
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store" });
136
+ res.end(HTML);
137
+ return;
138
+ }
139
+ res.writeHead(404);
140
+ res.end("not found");
141
+ });
142
+ server.on("error", (error) => {
143
+ if (error.code === "EADDRINUSE" && autoSelectPort && port < 65535) {
144
+ const occupied = port++;
145
+ console.error(`端口 ${occupied} 已被占用,尝试 ${port}…`);
146
+ server.listen(port, listenHost);
147
+ return;
148
+ }
149
+ dashboardLaunchLock.release();
150
+ const reason = error.code === "EADDRINUSE"
151
+ ? (autoSelectPort ? "已尝试到端口上限 65535" : `指定端口 ${port} 已被占用`)
152
+ : error.message;
153
+ console.error("✗ dashboard 启动失败: " + reason);
154
+ process.exit(1);
155
+ });
156
+ server.listen(port, listenHost, () => {
157
+ const url = `http://localhost:${port}`;
158
+ fs.mkdirSync(path.dirname(DASHBOARD_STATUS_FILE), { recursive: true });
159
+ fs.writeFileSync(DASHBOARD_STATUS_FILE, JSON.stringify({
160
+ ...currentProcessMetadata(DASHBOARD_COMMAND_TOKEN),
161
+ pid: process.pid,
162
+ port,
163
+ url,
164
+ startedAt: new Date().toISOString(),
165
+ buildFingerprint: BUILD_FINGERPRINT,
166
+ }, null, 2) + "\n", { mode: 0o600 });
167
+ try {
168
+ fs.chmodSync(DASHBOARD_STATUS_FILE, 0o600);
169
+ }
170
+ catch { }
171
+ dashboardLaunchLock.release();
172
+ console.log(`larkin dashboard ready: ${url} (由 larkin start 管理;仅本机访问,配置编辑受 CSRF 保护)`);
173
+ if (has("--open"))
174
+ console.log(openBrowser(url) ? "dashboard 已在默认浏览器打开" : "未能自动打开浏览器,请手动打开上面的地址");
175
+ });
176
+ function clearDashboardStatus() {
177
+ const current = readJson(DASHBOARD_STATUS_FILE, null);
178
+ if (current?.pid === process.pid) {
179
+ try {
180
+ fs.unlinkSync(DASHBOARD_STATUS_FILE);
181
+ }
182
+ catch { }
183
+ }
184
+ }
185
+ let stopping = false;
186
+ let stopped = false;
187
+ const finishStop = () => {
188
+ if (stopped)
189
+ return;
190
+ stopped = true;
191
+ clearDashboardStatus();
192
+ console.log("\n已停止");
193
+ process.exit(0);
194
+ };
195
+ const stop = () => {
196
+ if (stopping)
197
+ return;
198
+ stopping = true;
199
+ server.close(finishStop);
200
+ server.closeAllConnections?.();
201
+ setTimeout(finishStop, 2000).unref();
202
+ };
203
+ process.on("exit", () => { dashboardLaunchLock.release(); clearDashboardStatus(); });
204
+ process.on("SIGINT", stop);
205
+ process.on("SIGTERM", stop);
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.INTERNAL_AGENT_CLI = exports.PROCESS_COMMAND_TOKENS = exports.INTERNAL_MODES = exports.INTERNAL_COMMAND_MARKER = void 0;
7
+ exports.processCommandToken = processCommandToken;
8
+ exports.internalCommandSpec = internalCommandSpec;
9
+ exports.internalCommandShell = internalCommandShell;
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ exports.INTERNAL_COMMAND_MARKER = "__internal";
12
+ exports.INTERNAL_MODES = [
13
+ "run",
14
+ "setup",
15
+ "agent-config",
16
+ "session-cli",
17
+ "lark",
18
+ "runtime-process",
19
+ "dashboard",
20
+ "agent-cli",
21
+ "lark-cli",
22
+ "runtime-model-directory",
23
+ "bot-register",
24
+ "setup-bind",
25
+ "grant-scopes",
26
+ "lark-channel-secret",
27
+ "pi-rpc",
28
+ "pi-auth",
29
+ "telemetry",
30
+ ];
31
+ exports.PROCESS_COMMAND_TOKENS = Object.freeze({
32
+ setup: `${exports.INTERNAL_COMMAND_MARKER} setup`,
33
+ supervisor: `${exports.INTERNAL_COMMAND_MARKER} run`,
34
+ daemon: `${exports.INTERNAL_COMMAND_MARKER} runtime-process`,
35
+ dashboard: `${exports.INTERNAL_COMMAND_MARKER} dashboard`,
36
+ });
37
+ function processCommandToken(mode, legacyToken) {
38
+ return process.env.LARKIN_INTERNAL_DISPATCH === "1" ? exports.PROCESS_COMMAND_TOKENS[mode] : legacyToken;
39
+ }
40
+ exports.INTERNAL_AGENT_CLI = "@larkin/internal-agent-cli";
41
+ function internalCommandSpec(mode, args = [], env = process.env) {
42
+ if (env.LARKIN_STANDALONE === "1") {
43
+ return { command: process.execPath, args: [exports.INTERNAL_COMMAND_MARKER, mode, ...args] };
44
+ }
45
+ const entry = env.LARKIN_BINARY_ENTRY_PATH || (() => {
46
+ const callerDir = node_path_1.default.dirname(node_path_1.default.resolve(process.argv[1] || "dist/app/binary-entry.mjs"));
47
+ return node_path_1.default.join(node_path_1.default.basename(callerDir) === "setup" ? node_path_1.default.resolve(callerDir, "../app") : callerDir, "binary-entry.mjs");
48
+ })();
49
+ return { command: process.execPath, args: [entry, exports.INTERNAL_COMMAND_MARKER, mode, ...args] };
50
+ }
51
+ function posixQuote(value) {
52
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
53
+ }
54
+ function internalCommandShell(mode, env = process.env) {
55
+ const spec = internalCommandSpec(mode, [], env);
56
+ return [spec.command, ...spec.args].map(posixQuote).join(" ");
57
+ }
@@ -0,0 +1,48 @@
1
+ import path from "node:path";
2
+ export const INTERNAL_COMMAND_MARKER = "__internal";
3
+ export const INTERNAL_MODES = [
4
+ "run",
5
+ "setup",
6
+ "agent-config",
7
+ "session-cli",
8
+ "lark",
9
+ "runtime-process",
10
+ "dashboard",
11
+ "agent-cli",
12
+ "lark-cli",
13
+ "runtime-model-directory",
14
+ "bot-register",
15
+ "setup-bind",
16
+ "grant-scopes",
17
+ "lark-channel-secret",
18
+ "pi-rpc",
19
+ "pi-auth",
20
+ "telemetry",
21
+ ];
22
+ export const PROCESS_COMMAND_TOKENS = Object.freeze({
23
+ setup: `${INTERNAL_COMMAND_MARKER} setup`,
24
+ supervisor: `${INTERNAL_COMMAND_MARKER} run`,
25
+ daemon: `${INTERNAL_COMMAND_MARKER} runtime-process`,
26
+ dashboard: `${INTERNAL_COMMAND_MARKER} dashboard`,
27
+ });
28
+ export function processCommandToken(mode, legacyToken) {
29
+ return process.env.LARKIN_INTERNAL_DISPATCH === "1" ? PROCESS_COMMAND_TOKENS[mode] : legacyToken;
30
+ }
31
+ export const INTERNAL_AGENT_CLI = "@larkin/internal-agent-cli";
32
+ export function internalCommandSpec(mode, args = [], env = process.env) {
33
+ if (env.LARKIN_STANDALONE === "1") {
34
+ return { command: process.execPath, args: [INTERNAL_COMMAND_MARKER, mode, ...args] };
35
+ }
36
+ const entry = env.LARKIN_BINARY_ENTRY_PATH || (() => {
37
+ const callerDir = path.dirname(path.resolve(process.argv[1] || "dist/app/binary-entry.mjs"));
38
+ return path.join(path.basename(callerDir) === "setup" ? path.resolve(callerDir, "../app") : callerDir, "binary-entry.mjs");
39
+ })();
40
+ return { command: process.execPath, args: [entry, INTERNAL_COMMAND_MARKER, mode, ...args] };
41
+ }
42
+ function posixQuote(value) {
43
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
44
+ }
45
+ export function internalCommandShell(mode, env = process.env) {
46
+ const spec = internalCommandSpec(mode, [], env);
47
+ return [spec.command, ...spec.args].map(posixQuote).join(" ");
48
+ }
@@ -0,0 +1,22 @@
1
+ import * as larkinConfig from "../platform/config.mjs";
2
+ import { hydrateRuntimeAgent } from "./runtime-agent-config.mjs";
3
+ export async function main(env = process.env) {
4
+ if (env.LARKIN_INTERNAL_DISPATCH !== "1" || env.LARKIN_SECRET_PROVIDER_CONTEXT !== "bind") {
5
+ throw new Error("lark-channel secret provider 只允许 Runtime/setup 内部 bind 调用");
6
+ }
7
+ let input = "";
8
+ for await (const chunk of process.stdin) {
9
+ input += String(chunk);
10
+ if (Buffer.byteLength(input) > 16 * 1024)
11
+ throw new Error("secret provider request too large");
12
+ }
13
+ const request = JSON.parse(input);
14
+ const { configDir, config } = larkinConfig.loadConfig(env);
15
+ const agent = larkinConfig.selectAgent(config, env);
16
+ if (request.protocolVersion !== 1 || request.provider !== "larkin-bot-credential"
17
+ || !Array.isArray(request.ids) || request.ids.length !== 1 || request.ids[0] !== agent.feishuAppId) {
18
+ throw new Error("secret provider request does not match the bound Agent");
19
+ }
20
+ const hydrated = hydrateRuntimeAgent(configDir, agent);
21
+ process.stdout.write(`${JSON.stringify({ protocolVersion: 1, values: { [agent.feishuAppId]: hydrated.feishuAppSecret } })}\n`);
22
+ }