@mininglamp-oss/octo-runtime 1.1.0 → 1.1.2

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 (149) hide show
  1. package/README.md +4 -2
  2. package/apps/cli/README.md +3 -1
  3. package/apps/cli/dist/build-info.json +2 -2
  4. package/apps/cli/dist/extras.d.ts +4 -2
  5. package/apps/cli/dist/extras.js +20 -21
  6. package/apps/cli/dist/help.js +3 -0
  7. package/apps/cli/dist/logs.d.ts +10 -0
  8. package/apps/cli/dist/logs.js +186 -0
  9. package/apps/cli/dist/main.d.ts +1 -0
  10. package/apps/cli/dist/main.js +94 -19
  11. package/apps/cli/dist/{default_adapters.json → manifest.json} +10 -0
  12. package/apps/cli/dist/module-manifest.d.ts +3 -0
  13. package/apps/cli/dist/module-manifest.js +11 -0
  14. package/apps/cli/dist/openclaw.js +30 -6
  15. package/apps/cli/dist/output.js +3 -0
  16. package/apps/cli/dist/playboard.js +10 -8
  17. package/apps/cli/dist/status-output.d.ts +10 -0
  18. package/apps/cli/dist/status-output.js +65 -0
  19. package/apps/cli/dist/worker.d.ts +1 -0
  20. package/apps/cli/dist/worker.js +18 -0
  21. package/dist/public/host.d.ts +1 -0
  22. package/node_modules/@mininglamp-oss/octo-runtime-acp-client/package.json +3 -3
  23. package/node_modules/@mininglamp-oss/octo-runtime-adapter-acp/package.json +4 -4
  24. package/node_modules/@mininglamp-oss/octo-runtime-adapter-antigravity/package.json +3 -3
  25. package/node_modules/@mininglamp-oss/octo-runtime-adapter-claude-code/package.json +3 -3
  26. package/node_modules/@mininglamp-oss/octo-runtime-adapter-codebuddy/package.json +4 -4
  27. package/node_modules/@mininglamp-oss/octo-runtime-adapter-codex/package.json +3 -3
  28. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.d.ts +54 -0
  29. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.js +399 -0
  30. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.d.ts +14 -0
  31. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.js +156 -0
  32. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.d.ts +29 -0
  33. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.js +273 -0
  34. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.d.ts +27 -0
  35. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.js +161 -0
  36. package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/package.json +17 -0
  37. package/node_modules/@mininglamp-oss/octo-runtime-adapter-hermes/package.json +2 -2
  38. package/node_modules/@mininglamp-oss/octo-runtime-adapter-kimi-code/package.json +2 -2
  39. package/node_modules/@mininglamp-oss/octo-runtime-adapter-mcode/package.json +2 -2
  40. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.d.ts +24 -0
  41. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.js +181 -0
  42. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.d.ts +9 -0
  43. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.js +24 -8
  44. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/index.js +229 -225
  45. package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/package.json +3 -3
  46. package/node_modules/@mininglamp-oss/octo-runtime-adapter-opencode/package.json +4 -4
  47. package/node_modules/@mininglamp-oss/octo-runtime-adapter-qodercli/package.json +2 -2
  48. package/node_modules/@mininglamp-oss/octo-runtime-adapter-qoderclicn/package.json +2 -2
  49. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.d.ts +4 -0
  50. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.js +5 -6
  51. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/index.d.ts +1 -0
  52. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/index.js +1 -0
  53. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/module-manifest.d.ts +33 -0
  54. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/module-manifest.js +118 -0
  55. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/runtime-log-worker.js +7 -5
  56. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/runtime-log.d.ts +3 -0
  57. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/runtime-log.js +45 -10
  58. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/service-status.d.ts +11 -0
  59. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/service-status.js +70 -0
  60. package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/package.json +5 -3
  61. package/node_modules/@mininglamp-oss/octo-runtime-adapter-zcode-gui/package.json +3 -3
  62. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/build-info.json +2 -2
  63. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/extras.d.ts +4 -2
  64. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/extras.js +20 -21
  65. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/help.js +3 -0
  66. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/logs.d.ts +10 -0
  67. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/logs.js +186 -0
  68. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/main.d.ts +1 -0
  69. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/main.js +94 -19
  70. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/{default_adapters.json → manifest.json} +10 -0
  71. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/module-manifest.d.ts +3 -0
  72. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/module-manifest.js +11 -0
  73. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/openclaw.js +30 -6
  74. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/output.js +3 -0
  75. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/playboard.js +10 -8
  76. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/status-output.d.ts +10 -0
  77. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/status-output.js +65 -0
  78. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/worker.d.ts +1 -0
  79. package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/worker.js +18 -0
  80. package/node_modules/@mininglamp-oss/octo-runtime-cli/package.json +23 -9
  81. package/node_modules/@mininglamp-oss/octo-runtime-cross-service/package.json +2 -2
  82. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.d.ts +1 -1
  83. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.js +13 -9
  84. package/node_modules/@mininglamp-oss/octo-runtime-executor-core/package.json +3 -3
  85. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/heartbeat.d.ts +16 -0
  86. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/heartbeat.js +59 -0
  87. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/invocation-manifest.d.ts +1 -0
  88. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/invocation-manifest.js +4 -1
  89. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/manifest-adapters.d.ts +6 -0
  90. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/manifest-adapters.js +88 -0
  91. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/module-specifier.d.ts +1 -2
  92. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/module-specifier.js +2 -9
  93. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/process.d.ts +7 -2
  94. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/process.js +138 -9
  95. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/runner.js +3 -92
  96. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/serve.js +36 -12
  97. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/server.d.ts +4 -1
  98. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/server.js +14 -6
  99. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/service.js +2 -1
  100. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/supervisor.d.ts +2 -2
  101. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/supervisor.js +57 -34
  102. package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/package.json +8 -16
  103. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/config-schema.json +2 -2
  104. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/application/im-channel.js +18 -18
  105. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/contracts.d.ts +1 -0
  106. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/execution/dispatcher.js +24 -0
  107. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/contexts.js +2 -2
  108. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.d.ts +5 -2
  109. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.js +19 -5
  110. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/normalize.js +1 -0
  111. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/package.json +6 -6
  112. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/config-schema.json +2 -2
  113. package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/package.json +5 -5
  114. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/config-schema.json +2 -2
  115. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/dist/index.js +1 -1
  116. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/dist/store.d.ts +4 -1
  117. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/dist/store.js +54 -4
  118. package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/package.json +2 -2
  119. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/extra-config.d.ts +8 -1
  120. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/extra-config.js +27 -12
  121. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/extra-service.js +39 -2
  122. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/index.d.ts +1 -0
  123. package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/package.json +4 -4
  124. package/node_modules/@mininglamp-oss/octo-runtime-protocol/package.json +1 -1
  125. package/node_modules/import-meta-resolve/index.d.ts +19 -0
  126. package/node_modules/import-meta-resolve/index.d.ts.map +1 -0
  127. package/node_modules/import-meta-resolve/index.js +47 -0
  128. package/node_modules/import-meta-resolve/lib/errors.d.ts +24 -0
  129. package/node_modules/import-meta-resolve/lib/errors.d.ts.map +1 -0
  130. package/node_modules/import-meta-resolve/lib/errors.js +504 -0
  131. package/node_modules/import-meta-resolve/lib/get-format.d.ts +13 -0
  132. package/node_modules/import-meta-resolve/lib/get-format.d.ts.map +1 -0
  133. package/node_modules/import-meta-resolve/lib/get-format.js +159 -0
  134. package/node_modules/import-meta-resolve/lib/package-json-reader.d.ts +31 -0
  135. package/node_modules/import-meta-resolve/lib/package-json-reader.d.ts.map +1 -0
  136. package/node_modules/import-meta-resolve/lib/package-json-reader.js +177 -0
  137. package/node_modules/import-meta-resolve/lib/resolve.d.ts +29 -0
  138. package/node_modules/import-meta-resolve/lib/resolve.d.ts.map +1 -0
  139. package/node_modules/import-meta-resolve/lib/resolve.js +1301 -0
  140. package/node_modules/import-meta-resolve/lib/utils.d.ts +6 -0
  141. package/node_modules/import-meta-resolve/lib/utils.d.ts.map +1 -0
  142. package/node_modules/import-meta-resolve/lib/utils.js +47 -0
  143. package/node_modules/import-meta-resolve/license +74 -0
  144. package/node_modules/import-meta-resolve/package.json +78 -0
  145. package/node_modules/import-meta-resolve/readme.md +252 -0
  146. package/package.json +30 -26
  147. package/packages/octo-runtime-extra-channel-gateway/config-schema.json +2 -2
  148. package/packages/octo-runtime-extra-channel-wecom/config-schema.json +2 -2
  149. package/packages/octo-runtime-extra-webui/config-schema.json +2 -2
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-opencode",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
7
7
  "dependencies": {
8
- "@mininglamp-oss/octo-runtime-protocol": "1.1.0",
9
- "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.0",
10
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.0"
8
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
9
+ "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.2",
10
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2"
11
11
  },
12
12
  "types": "./dist/index.d.ts",
13
13
  "files": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-qodercli",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -9,6 +9,6 @@
9
9
  "dist"
10
10
  ],
11
11
  "dependencies": {
12
- "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.0"
12
+ "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.2"
13
13
  }
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-qoderclicn",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -9,6 +9,6 @@
9
9
  "dist"
10
10
  ],
11
11
  "dependencies": {
12
- "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.0"
12
+ "@mininglamp-oss/octo-runtime-adapter-acp": "1.1.2"
13
13
  }
14
14
  }
@@ -7,10 +7,14 @@ export declare class AcpApprovalBridge {
7
7
  readonly options: {
8
8
  providerDecisions?: boolean;
9
9
  providerManagedExpiry?: boolean;
10
+ /** 仅由 Adapter 在首个审批前设置,用于已授权的原生兼容回退;不改写请求策略与身份。 */
11
+ effectiveApprovalMode?: "ask" | "full_access";
10
12
  };
11
13
  constructor(request: InvokeRequest, timeoutMs?: number, options?: {
12
14
  providerDecisions?: boolean;
13
15
  providerManagedExpiry?: boolean;
16
+ /** 仅由 Adapter 在首个审批前设置,用于已授权的原生兼容回退;不改写请求策略与身份。 */
17
+ effectiveApprovalMode?: "ask" | "full_access";
14
18
  });
15
19
  requestPermission(params: RecordValue, providerExpiresAt?: number): Promise<RecordValue>;
16
20
  respond(response: InteractionResponse): Promise<void>;
@@ -24,6 +24,7 @@ export class AcpApprovalBridge {
24
24
  requestPermission(params, providerExpiresAt) {
25
25
  if (this.#closed || this.request.signal?.aborted)
26
26
  return Promise.reject(new Error("APPROVAL_WAIT_UNAVAILABLE"));
27
+ const automatic = (this.options.effectiveApprovalMode ?? this.request.approvalMode) === "full_access";
27
28
  const options = Array.isArray(params.options) ? params.options.filter(isObject) : [];
28
29
  const option = (kind) => {
29
30
  const candidate = options.find((value) => value.kind === kind);
@@ -34,7 +35,7 @@ export class AcpApprovalBridge {
34
35
  const allow = option("allow_once");
35
36
  const always = this.options.providerDecisions ? option("allow_always") : undefined;
36
37
  const decline = option("reject_once");
37
- if (!allow && !always && !decline && this.request.approvalMode !== "full_access")
38
+ if (!allow && !always && !decline && !automatic)
38
39
  return Promise.resolve(cancelled());
39
40
  if (this.#pending.size >= 16 || this.request.signal?.aborted)
40
41
  return Promise.reject(new Error("APPROVAL_WAIT_UNAVAILABLE"));
@@ -90,10 +91,8 @@ export class AcpApprovalBridge {
90
91
  written,
91
92
  confirm,
92
93
  fail,
93
- responding: this.request.approvalMode === "full_access",
94
- ...(this.request.approvalMode === "full_access"
95
- ? { automaticOutcome: allow ? "accepted" : "cancelled" }
96
- : {})
94
+ responding: automatic,
95
+ ...(automatic ? { automaticOutcome: allow ? "accepted" : "cancelled" } : {})
97
96
  });
98
97
  });
99
98
  const tool = isObject(params.toolCall)
@@ -140,7 +139,7 @@ export class AcpApprovalBridge {
140
139
  }
141
140
  }
142
141
  });
143
- if (this.request.approvalMode === "full_access")
142
+ if (automatic)
144
143
  this.#pending.get(interactionId).resolve(allow ? selected(allow) : cancelled());
145
144
  return result;
146
145
  }
@@ -15,6 +15,7 @@ export { watchLineLimit } from "./line-limit.js";
15
15
  export { readBoundedLines } from "./bounded-lines.js";
16
16
  export { HourlyLogWriter, HOURLY_LOG_MAX_BYTES } from "./hourly-log.js";
17
17
  export { RuntimeLogging, assertRuntimeLogging, noopRuntimeLog, type RuntimeLog, type RuntimeLogLevel, type RuntimeLoggingOptions } from "./runtime-log.js";
18
+ export { extraStatusRecord, type ExtraStatusRecord } from "./service-status.js";
18
19
  export { sanitizePublicValue } from "./public-display.js";
19
20
  export { DEFAULT_REASONING_LEVEL_MAPS, OMNI_REASONING_LEVELS, mapReasoningEffort, reasoningLevelMap, type OmniReasoningLevel, type ReasoningLevelMap } from "./reasoning.js";
20
21
  export interface AdapterMetadata {
@@ -21,6 +21,7 @@ export { watchLineLimit } from "./line-limit.js";
21
21
  export { readBoundedLines } from "./bounded-lines.js";
22
22
  export { HourlyLogWriter, HOURLY_LOG_MAX_BYTES } from "./hourly-log.js";
23
23
  export { RuntimeLogging, assertRuntimeLogging, noopRuntimeLog } from "./runtime-log.js";
24
+ export { extraStatusRecord } from "./service-status.js";
24
25
  export { sanitizePublicValue } from "./public-display.js";
25
26
  export { DEFAULT_REASONING_LEVEL_MAPS, OMNI_REASONING_LEVELS, mapReasoningEffort, reasoningLevelMap } from "./reasoning.js";
26
27
  /**
@@ -0,0 +1,33 @@
1
+ export interface AdapterModuleEntry {
2
+ type?: string;
3
+ module: string;
4
+ export: string;
5
+ factory: boolean;
6
+ options: Record<string, unknown>;
7
+ sourceManifest: string;
8
+ }
9
+ export interface ExtraModuleEntry {
10
+ name: string;
11
+ module: string;
12
+ sourceManifest: string;
13
+ }
14
+ export interface ModuleManifest {
15
+ version: 1;
16
+ adapters: AdapterModuleEntry[];
17
+ extras: ExtraModuleEntry[];
18
+ }
19
+ /** CLI 清单边界:只校验声明、不导入模块;来源路径始终随条目保留,不能用合并位置替换。 */
20
+ export declare function parseModuleManifest(value: unknown, source: string, { legacy }?: {
21
+ legacy?: boolean | undefined;
22
+ }): ModuleManifest;
23
+ /** 只有可选用户文件的 ENOENT 表示无扩展;权限、JSON 或格式错误必须保留失败。 */
24
+ export declare function readModuleManifest(file: string, { optional, legacy }?: {
25
+ optional?: boolean | undefined;
26
+ legacy?: boolean | undefined;
27
+ }): Promise<ModuleManifest>;
28
+ /** 内置优先、用户追加;冲突项在解析/import 前剔除,诊断不得包含 options 或业务配置。 */
29
+ export declare function mergeModuleManifests(builtin: ModuleManifest, extension: ModuleManifest, report?: (message: string) => void): ModuleManifest;
30
+ /** 按原始清单解析裸包的 ESM import/exports;本机路径先转 URL,避免 Windows 盘符误判。 */
31
+ export declare function resolveModuleSpecifier(module: string, sourceManifest: string): string;
32
+ /** 仅解析选中 Adapter,生成可跨进程的启动快照;不提前解析或加载 Extra。 */
33
+ export declare function resolveAdapterModules(manifest: ModuleManifest): AdapterModuleEntry[];
@@ -0,0 +1,118 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { dirname, isAbsolute, resolve } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { resolve as resolveEsm } from "import-meta-resolve";
5
+ /** CLI 清单边界:只校验声明、不导入模块;来源路径始终随条目保留,不能用合并位置替换。 */
6
+ export function parseModuleManifest(value, source, { legacy = false } = {}) {
7
+ const manifest = record(value, "manifest");
8
+ if (manifest.version !== 1)
9
+ throw new TypeError("manifest.version must be 1");
10
+ if (!Array.isArray(manifest.adapters))
11
+ throw new TypeError("manifest.adapters must be an array");
12
+ const extras = manifest.extras === undefined && legacy ? [] : manifest.extras;
13
+ if (!Array.isArray(extras))
14
+ throw new TypeError("manifest.extras must be an array");
15
+ const sourceManifest = resolve(source);
16
+ const adapters = manifest.adapters.map((value, index) => {
17
+ const entry = record(value, `adapters[${index}]`);
18
+ const type = entry.type === undefined && legacy ? undefined : text(entry.type, "adapter.type");
19
+ if (entry.factory !== undefined && typeof entry.factory !== "boolean")
20
+ throw new TypeError("adapter.factory must be a boolean");
21
+ return {
22
+ ...(type === undefined ? {} : { type }),
23
+ module: text(entry.module, "adapter.module"),
24
+ export: entry.export === undefined ? "default" : text(entry.export, "adapter.export"),
25
+ factory: entry.factory === true,
26
+ options: entry.options === undefined ? {} : record(entry.options, "adapter.options"),
27
+ sourceManifest
28
+ };
29
+ });
30
+ const extraEntries = extras.map((value, index) => {
31
+ const entry = record(value, `extras[${index}]`);
32
+ const name = text(entry.name, "extra.name");
33
+ if (!/^[a-z][a-z0-9-]{0,63}$/.test(name))
34
+ throw new TypeError("extra.name is invalid");
35
+ return { name, module: text(entry.module, "extra.module"), sourceManifest };
36
+ });
37
+ unique(adapters, (entry) => entry.type, "adapter.type");
38
+ unique(extraEntries, (entry) => entry.name, "extra.name");
39
+ return { version: 1, adapters, extras: extraEntries };
40
+ }
41
+ /** 只有可选用户文件的 ENOENT 表示无扩展;权限、JSON 或格式错误必须保留失败。 */
42
+ export async function readModuleManifest(file, { optional = false, legacy = false } = {}) {
43
+ let content;
44
+ try {
45
+ content = await readFile(file, "utf8");
46
+ }
47
+ catch (error) {
48
+ if (optional && error.code === "ENOENT")
49
+ return { version: 1, adapters: [], extras: [] };
50
+ throw error;
51
+ }
52
+ try {
53
+ return parseModuleManifest(JSON.parse(content), file, { legacy });
54
+ }
55
+ catch (error) {
56
+ throw Object.assign(new TypeError(`Invalid manifest ${file}: ${error instanceof Error ? error.message : "invalid JSON"}`, { cause: error }), { code: "MANIFEST_INVALID" });
57
+ }
58
+ }
59
+ /** 内置优先、用户追加;冲突项在解析/import 前剔除,诊断不得包含 options 或业务配置。 */
60
+ export function mergeModuleManifests(builtin, extension, report = () => { }) {
61
+ function merge(first, second, key) {
62
+ const seen = new Set(first.map(key).filter((value) => value !== undefined));
63
+ return [
64
+ ...first,
65
+ ...second.filter((entry) => {
66
+ const name = key(entry);
67
+ if (name !== undefined && seen.has(name)) {
68
+ report(`Ignoring extension module "${name}": built-in declaration takes precedence`);
69
+ return false;
70
+ }
71
+ if (name !== undefined)
72
+ seen.add(name);
73
+ return true;
74
+ })
75
+ ];
76
+ }
77
+ return {
78
+ version: 1,
79
+ adapters: merge(builtin.adapters, extension.adapters, (entry) => entry.type),
80
+ extras: merge(builtin.extras, extension.extras, (entry) => entry.name)
81
+ };
82
+ }
83
+ /** 按原始清单解析裸包的 ESM import/exports;本机路径先转 URL,避免 Windows 盘符误判。 */
84
+ export function resolveModuleSpecifier(module, sourceManifest) {
85
+ if (module.startsWith(".") || isAbsolute(module))
86
+ return pathToFileURL(resolve(dirname(sourceManifest), module)).href;
87
+ if (/^[a-z][a-z0-9+.-]*:/i.test(module))
88
+ return module;
89
+ return resolveEsm(module, pathToFileURL(resolve(sourceManifest)).href);
90
+ }
91
+ /** 仅解析选中 Adapter,生成可跨进程的启动快照;不提前解析或加载 Extra。 */
92
+ export function resolveAdapterModules(manifest) {
93
+ return manifest.adapters.map((entry) => ({
94
+ ...entry,
95
+ module: resolveModuleSpecifier(entry.module, entry.sourceManifest)
96
+ }));
97
+ }
98
+ function record(value, label) {
99
+ if (!value || typeof value !== "object" || Array.isArray(value))
100
+ throw new TypeError(`${label} must be an object`);
101
+ return value;
102
+ }
103
+ function text(value, label) {
104
+ if (typeof value !== "string" || !value.trim())
105
+ throw new TypeError(`${label} must be a non-empty string`);
106
+ return value;
107
+ }
108
+ function unique(entries, key, label) {
109
+ const seen = new Set();
110
+ for (const entry of entries) {
111
+ const value = key(entry);
112
+ if (value === undefined)
113
+ continue;
114
+ if (seen.has(value))
115
+ throw new TypeError(`duplicate ${label}: ${value}`);
116
+ seen.add(value);
117
+ }
118
+ }
@@ -1,4 +1,4 @@
1
- /** 日志专用线程:复用小时桶、容量与跨进程互斥,不运行任何业务逻辑。 */
1
+ /** Dedicated log thread: reuse hourly retention, capacity limits and cross-process exclusion. */
2
2
  import { parentPort, workerData } from "node:worker_threads";
3
3
  import { join } from "node:path";
4
4
  import { HourlyLogWriter } from "./hourly-log.js";
@@ -13,8 +13,10 @@ parentPort.on("message", (message) => {
13
13
  return;
14
14
  }
15
15
  try {
16
- const category = message.extra ?? "kernel";
17
- const key = message.extra ? `extra:${message.extra}` : "kernel";
16
+ const category = message.extra
17
+ ? `${message.extra}${message.status ? "-status" : ""}`
18
+ : "kernel";
19
+ const key = message.extra ? `extra:${category}` : "kernel";
18
20
  let writer = writers.get(key);
19
21
  if (!writer && writers.size < 128) {
20
22
  writer = new HourlyLogWriter(message.extra ? join(directory, "extras") : directory, category, { onError: () => { } });
@@ -23,7 +25,7 @@ parentPort.on("message", (message) => {
23
25
  writer?.write(message.line);
24
26
  }
25
27
  catch {
26
- /* 写入失败只丢弃本条诊断,不影响执行。 */
28
+ /* Dropping a diagnostic must never affect execution. */
27
29
  }
28
- parentPort.postMessage("written");
30
+ parentPort.postMessage({ written: message.status === true });
29
31
  });
@@ -1,7 +1,10 @@
1
+ import { type ExtraStatusRecord } from "./service-status.js";
1
2
  export type RuntimeLogLevel = "info" | "warn" | "error";
2
3
  export type RuntimeLog = (level: RuntimeLogLevel, event: string, data?: Readonly<Record<string, unknown>>) => void;
3
4
  export interface RuntimeLoggingOptions {
4
5
  directory: string;
6
+ /** In-process status sink; SDK defaults to silence. Never placed in JSON config or workerData. */
7
+ statusOutput?: (record: ExtraStatusRecord) => void;
5
8
  }
6
9
  export declare const noopRuntimeLog: RuntimeLog;
7
10
  export declare function assertRuntimeLogging(options?: RuntimeLoggingOptions): void;
@@ -1,6 +1,7 @@
1
- /** 宿主可选的结构化日志;只接受执行元数据,磁盘写入隔离在有界 Worker。 */
1
+ /** Optional metadata logging; bounded queues isolate filesystem writes in a dedicated worker. */
2
2
  import { isAbsolute } from "node:path";
3
3
  import { Worker } from "node:worker_threads";
4
+ import { extraStatusRecord } from "./service-status.js";
4
5
  export const noopRuntimeLog = () => { };
5
6
  const strings = new Set([
6
7
  "run_id",
@@ -30,11 +31,15 @@ export function assertRuntimeLogging(options) {
30
31
  if (options !== undefined &&
31
32
  (!options || typeof options.directory !== "string" || !isAbsolute(options.directory)))
32
33
  throw new TypeError("LOG_DIRECTORY_MUST_BE_ABSOLUTE");
34
+ if (options?.statusOutput !== undefined && typeof options.statusOutput !== "function")
35
+ throw new TypeError("LOG_STATUS_OUTPUT_INVALID");
33
36
  }
34
37
  /** F31:.octospec/tasks/gateway-august-feature-assessment/assessment.md */
35
38
  export class RuntimeLogging {
36
39
  #worker;
37
40
  #pending = 0;
41
+ #statusPending = 0;
42
+ #statusOutput;
38
43
  #closed = false;
39
44
  #closing;
40
45
  #done;
@@ -42,27 +47,31 @@ export class RuntimeLogging {
42
47
  assertRuntimeLogging(options);
43
48
  if (!options)
44
49
  return;
50
+ this.#statusOutput = options.statusOutput;
45
51
  try {
46
52
  this.#worker = new Worker(new URL("./runtime-log-worker.js", import.meta.url), {
47
- workerData: options
53
+ workerData: { directory: options.directory }
48
54
  });
49
55
  }
50
56
  catch {
51
- this.#closed = true;
52
57
  return;
53
58
  }
54
59
  this.#worker.on("message", (message) => {
55
- if (message === "written")
56
- this.#pending = Math.max(0, this.#pending - 1);
60
+ if (typeof message === "object") {
61
+ if (message.written)
62
+ this.#statusPending = Math.max(0, this.#statusPending - 1);
63
+ else
64
+ this.#pending = Math.max(0, this.#pending - 1);
65
+ }
57
66
  if (message === "closed")
58
67
  this.#done?.();
59
68
  });
60
69
  this.#worker.on("error", () => {
61
- this.#closed = true;
70
+ this.#worker = undefined;
62
71
  this.#done?.();
63
72
  });
64
73
  this.#worker.on("exit", () => {
65
- this.#closed = true;
74
+ this.#worker = undefined;
66
75
  this.#done?.();
67
76
  });
68
77
  this.#worker.unref();
@@ -74,13 +83,39 @@ export class RuntimeLogging {
74
83
  return (level, event, data) => this.#write("extra", name, level, event, data);
75
84
  }
76
85
  #write(source, extra, level, event, data) {
77
- if (!this.#worker || this.#closed || this.#pending >= 128)
86
+ if (this.#closed)
87
+ return;
88
+ if (extra) {
89
+ try {
90
+ const status = extraStatusRecord(extra, level, event, data);
91
+ if (status) {
92
+ // Sink and mirror fail independently; neither failure may affect service recovery.
93
+ try {
94
+ const result = this.#statusOutput?.(status);
95
+ // TypeScript permits async functions in void sinks; observe rejection without waiting.
96
+ if (result && typeof result.then === "function")
97
+ void Promise.resolve(result).catch(() => undefined);
98
+ }
99
+ catch {
100
+ /* A host sink failure must not suppress the independent file mirror. */
101
+ }
102
+ if (this.#worker && this.#statusPending < 128) {
103
+ this.#worker.postMessage({ extra, status: true, line: `${JSON.stringify(status)}\n` });
104
+ this.#statusPending++;
105
+ }
106
+ }
107
+ }
108
+ catch {
109
+ /* Untrusted diagnostic getters must not escape into service execution. */
110
+ }
111
+ }
112
+ if (!this.#worker || this.#pending >= 128)
78
113
  return;
79
114
  try {
80
115
  if (!["info", "warn", "error"].includes(level) || !/^[a-z][a-z0-9_.-]{0,63}$/.test(event))
81
116
  return;
82
117
  const safe = {};
83
- // 不做任意对象脱敏或正文截断:白名单之外的字段直接不读取、不序列化。
118
+ // Ignore unknown fields entirely instead of serializing or truncating arbitrary bodies.
84
119
  for (const key of strings) {
85
120
  const value = data?.[key];
86
121
  if (typeof value === "string" &&
@@ -105,7 +140,7 @@ export class RuntimeLogging {
105
140
  this.#pending++;
106
141
  }
107
142
  catch {
108
- /* 日志不能中断执行,包括恶意 getter 或已退出的 Worker。 */
143
+ /* Diagnostics cannot interrupt execution, including getter errors or an exited worker. */
109
144
  }
110
145
  }
111
146
  close() {
@@ -0,0 +1,11 @@
1
+ import type { RuntimeLogLevel } from "./runtime-log.js";
2
+ export interface ExtraStatusRecord {
3
+ time: string;
4
+ level: RuntimeLogLevel;
5
+ source: "extra";
6
+ extra_type: string;
7
+ event: string;
8
+ data: Record<string, string | number>;
9
+ }
10
+ /** Rebuild status records from a separate allowlist, including when reading persisted files. */
11
+ export declare function extraStatusRecord(extra: string, level: RuntimeLogLevel, event: string, data?: Readonly<Record<string, unknown>>, time?: string): ExtraStatusRecord | undefined;
@@ -0,0 +1,70 @@
1
+ const events = new Set([
2
+ "service.initializing",
3
+ "service.ready",
4
+ "service.closing",
5
+ "service.closed",
6
+ "service.failed",
7
+ "service.cleanup_incomplete",
8
+ "service.output_dropped",
9
+ "kernel.available",
10
+ "kernel.unavailable",
11
+ "channel.connecting",
12
+ "channel.connected",
13
+ "channel.disconnected",
14
+ "channel.connection_failed",
15
+ "channel.retry_started",
16
+ "channel.retry_scheduled",
17
+ "channel.stopped",
18
+ "channel.diagnostic"
19
+ ]);
20
+ const states = new Set([
21
+ "created",
22
+ "initializing",
23
+ "ready",
24
+ "closing",
25
+ "closed",
26
+ "failed",
27
+ "connecting",
28
+ "online",
29
+ "retrying",
30
+ "stopped",
31
+ "available",
32
+ "unavailable"
33
+ ]);
34
+ /** Rebuild status records from a separate allowlist, including when reading persisted files. */
35
+ export function extraStatusRecord(extra, level, event, data, time = new Date().toISOString()) {
36
+ if (!/^[a-z][a-z0-9-]{0,63}$/.test(extra) ||
37
+ !["info", "warn", "error"].includes(level) ||
38
+ !events.has(event))
39
+ return;
40
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(time) ||
41
+ !Number.isFinite(Date.parse(time)))
42
+ return;
43
+ if (event === "channel.diagnostic" && data?.code !== "IM_DISPOSE_FAILED")
44
+ return;
45
+ const safe = {};
46
+ for (const key of ["state", "code", "endpoint_id"]) {
47
+ const value = data?.[key];
48
+ if (typeof value !== "string")
49
+ continue;
50
+ if (key === "state"
51
+ ? states.has(value)
52
+ : key === "endpoint_id"
53
+ ? /^[a-f0-9]{64}$/.test(value)
54
+ : /^[A-Z][A-Z0-9_]{0,95}$/.test(value))
55
+ safe[key] = value;
56
+ }
57
+ for (const key of ["attempt", "delay_ms", "dropped_count"]) {
58
+ const value = data?.[key];
59
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0)
60
+ safe[key] = value;
61
+ }
62
+ return Object.freeze({
63
+ time,
64
+ level,
65
+ source: "extra",
66
+ extra_type: extra,
67
+ event,
68
+ data: Object.freeze(safe)
69
+ });
70
+ }
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./dist/index.js",
8
- "./process-cleanup": "./dist/process-cleanup.js"
8
+ "./process-cleanup": "./dist/process-cleanup.js",
9
+ "./module-manifest": "./dist/module-manifest.js"
9
10
  },
10
11
  "dependencies": {
11
- "@mininglamp-oss/octo-runtime-protocol": "1.1.0"
12
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
13
+ "import-meta-resolve": "4.2.0"
12
14
  },
13
15
  "types": "./dist/index.d.ts",
14
16
  "files": [
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@mininglamp-oss/octo-runtime-adapter-zcode-gui",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
7
7
  "dependencies": {
8
- "@mininglamp-oss/octo-runtime-protocol": "1.1.0",
9
- "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.0"
8
+ "@mininglamp-oss/octo-runtime-protocol": "1.1.2",
9
+ "@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.2"
10
10
  },
11
11
  "types": "./dist/index.d.ts",
12
12
  "files": [
@@ -1,5 +1,5 @@
1
1
  {
2
- "commit": "d064cfe78f6818d3c451ecf803a280245f4b0496",
2
+ "commit": "5c1921dced4b0852e41426f1c04582159082f482",
3
3
  "dirty": false,
4
- "buildTime": "2026-10-21T06:46:27.212Z"
4
+ "buildTime": "2026-10-22T12:44:46.791Z"
5
5
  }
@@ -1,6 +1,8 @@
1
- import { type ExtraDescriptor, type StoredExtra } from "@mininglamp-oss/octo-runtime-host-sdk";
1
+ import { type ExtraRegistration, type StoredExtra } from "@mininglamp-oss/octo-runtime-host-sdk";
2
2
  import { type RuntimePaths } from "./state.js";
3
+ import { type ModuleManifest } from "@mininglamp-oss/octo-runtime-adapter-sdk/module-manifest";
3
4
  /** Generic full replacement: no platform-specific CLI fields or validation. */
4
5
  export declare function setExtra(paths: RuntimePaths, name: string, input: NodeJS.ReadableStream): Promise<unknown>;
5
- export declare function readExtra(paths: RuntimePaths, name: string): Promise<ExtraDescriptor>;
6
+ /** CLI 将模块目录与业务配置装配;仅 load 时解析/import,禁用项及未启动项不执行模块。 */
7
+ export declare function readExtra(paths: RuntimePaths, name: string, manifest: ModuleManifest): Promise<ExtraRegistration>;
6
8
  export declare function getExtra(paths: RuntimePaths, name: string): Promise<StoredExtra>;
@@ -1,6 +1,7 @@
1
1
  import { join } from "node:path";
2
- import { assertExtraName, assertStoredExtra, readExtraDirectory } from "@mininglamp-oss/octo-runtime-host-sdk";
2
+ import { assertExtraName, assertStoredExtra, readStoredExtra } from "@mininglamp-oss/octo-runtime-host-sdk";
3
3
  import { withSetupLock, writeJsonAtomic } from "./state.js";
4
+ import { resolveModuleSpecifier } from "@mininglamp-oss/octo-runtime-adapter-sdk/module-manifest";
4
5
  /** Generic full replacement: no platform-specific CLI fields or validation. */
5
6
  export async function setExtra(paths, name, input) {
6
7
  assertExtraName(name);
@@ -29,33 +30,31 @@ export async function setExtra(paths, name, input) {
29
30
  return { saved: true, name, file, reload_required: true };
30
31
  });
31
32
  }
32
- export async function readExtra(paths, name) {
33
+ /** CLI 将模块目录与业务配置装配;仅 load 时解析/import,禁用项及未启动项不执行模块。 */
34
+ export async function readExtra(paths, name, manifest) {
33
35
  assertExtraName(name);
34
- const entries = await readExtraDirectory(join(paths.home, "extras"));
35
- const entry = entries.find((item) => item.name === name);
36
+ const stored = await getExtra(paths, name);
37
+ const entry = manifest.extras.find((item) => item.name === name);
36
38
  if (!entry)
37
- throw new Error("EXTRA_NOT_REGISTERED");
38
- // Invalid stored declarations carry a controlled read error through their loader.
39
- if (!entry.module)
40
- await entry.load();
39
+ throw new Error("EXTRA_MANIFEST_DECLARATION_REQUIRED");
40
+ if (stored.module !== undefined && stored.module !== entry.module)
41
+ throw new Error("EXTRA_MODULE_MIGRATION_REQUIRED");
41
42
  return {
42
43
  name,
43
44
  module: entry.module,
44
- config: entry.config,
45
- ...(entry.enabled === undefined ? {} : { enabled: entry.enabled })
45
+ config: stored.config,
46
+ enabled: stored.enabled,
47
+ load: () => import(resolveModuleSpecifier(entry.module, entry.sourceManifest))
46
48
  };
47
49
  }
48
50
  export async function getExtra(paths, name) {
49
51
  assertExtraName(name);
50
- const entries = await readExtraDirectory(join(paths.home, "extras"));
51
- const entry = entries.find((item) => item.name === name);
52
- if (!entry)
53
- throw new Error("EXTRA_NOT_REGISTERED");
54
- if (!entry.module)
55
- await entry.load();
56
- return {
57
- module: entry.module,
58
- ...(entry.enabled === undefined ? {} : { enabled: entry.enabled }),
59
- config: entry.config
60
- };
52
+ try {
53
+ return await readStoredExtra(join(paths.home, "extras"), name);
54
+ }
55
+ catch (error) {
56
+ if (error.code === "ENOENT")
57
+ throw new Error("EXTRA_NOT_REGISTERED", { cause: error });
58
+ throw error;
59
+ }
61
60
  }