@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.
- package/README.md +4 -2
- package/apps/cli/README.md +3 -1
- package/apps/cli/dist/build-info.json +2 -2
- package/apps/cli/dist/extras.d.ts +4 -2
- package/apps/cli/dist/extras.js +20 -21
- package/apps/cli/dist/help.js +3 -0
- package/apps/cli/dist/logs.d.ts +10 -0
- package/apps/cli/dist/logs.js +186 -0
- package/apps/cli/dist/main.d.ts +1 -0
- package/apps/cli/dist/main.js +94 -19
- package/apps/cli/dist/{default_adapters.json → manifest.json} +10 -0
- package/apps/cli/dist/module-manifest.d.ts +3 -0
- package/apps/cli/dist/module-manifest.js +11 -0
- package/apps/cli/dist/openclaw.js +30 -6
- package/apps/cli/dist/output.js +3 -0
- package/apps/cli/dist/playboard.js +10 -8
- package/apps/cli/dist/status-output.d.ts +10 -0
- package/apps/cli/dist/status-output.js +65 -0
- package/apps/cli/dist/worker.d.ts +1 -0
- package/apps/cli/dist/worker.js +18 -0
- package/dist/public/host.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-acp-client/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-acp/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-antigravity/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-claude-code/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-codebuddy/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-codex/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.d.ts +54 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/adapter.js +399 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.d.ts +14 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/client.js +156 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.d.ts +29 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/index.js +273 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.d.ts +27 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/dist/interactions.js +161 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-grok-build/package.json +17 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-hermes/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-kimi-code/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-mcode/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.d.ts +24 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/compatibility.js +181 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.d.ts +9 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/gateway.js +24 -8
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/dist/index.js +229 -225
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-openclaw/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-opencode/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-qodercli/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-qoderclicn/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.d.ts +4 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/approval.js +5 -6
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/index.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/index.js +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/module-manifest.d.ts +33 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/module-manifest.js +118 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/runtime-log-worker.js +7 -5
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/runtime-log.d.ts +3 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/runtime-log.js +45 -10
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/service-status.d.ts +11 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/dist/service-status.js +70 -0
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-sdk/package.json +5 -3
- package/node_modules/@mininglamp-oss/octo-runtime-adapter-zcode-gui/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/build-info.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/extras.d.ts +4 -2
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/extras.js +20 -21
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/help.js +3 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/logs.d.ts +10 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/logs.js +186 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/main.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/main.js +94 -19
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/{default_adapters.json → manifest.json} +10 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/module-manifest.d.ts +3 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/module-manifest.js +11 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/openclaw.js +30 -6
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/output.js +3 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/playboard.js +10 -8
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/status-output.d.ts +10 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/status-output.js +65 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/worker.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/dist/worker.js +18 -0
- package/node_modules/@mininglamp-oss/octo-runtime-cli/package.json +23 -9
- package/node_modules/@mininglamp-oss/octo-runtime-cross-service/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.d.ts +1 -1
- package/node_modules/@mininglamp-oss/octo-runtime-executor-core/dist/model-input.js +13 -9
- package/node_modules/@mininglamp-oss/octo-runtime-executor-core/package.json +3 -3
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/heartbeat.d.ts +16 -0
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/heartbeat.js +59 -0
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/invocation-manifest.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/invocation-manifest.js +4 -1
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/manifest-adapters.d.ts +6 -0
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/manifest-adapters.js +88 -0
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/module-specifier.d.ts +1 -2
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/module-specifier.js +2 -9
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/process.d.ts +7 -2
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/process.js +138 -9
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/runner.js +3 -92
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/serve.js +36 -12
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/server.d.ts +4 -1
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/server.js +14 -6
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/service.js +2 -1
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/supervisor.d.ts +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/dist/supervisor.js +57 -34
- package/node_modules/@mininglamp-oss/octo-runtime-executor-kernel/package.json +8 -16
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/config-schema.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/application/im-channel.js +18 -18
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/contracts.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/execution/dispatcher.js +24 -0
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/contexts.js +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.d.ts +5 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/mentions.js +19 -5
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/dist/transport/normalize.js +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-gateway/package.json +6 -6
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/config-schema.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-channel-wecom/package.json +5 -5
- package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/config-schema.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/dist/index.js +1 -1
- package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/dist/store.d.ts +4 -1
- package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/dist/store.js +54 -4
- package/node_modules/@mininglamp-oss/octo-runtime-extra-webui/package.json +2 -2
- package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/extra-config.d.ts +8 -1
- package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/extra-config.js +27 -12
- package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/extra-service.js +39 -2
- package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/dist/index.d.ts +1 -0
- package/node_modules/@mininglamp-oss/octo-runtime-host-sdk/package.json +4 -4
- package/node_modules/@mininglamp-oss/octo-runtime-protocol/package.json +1 -1
- package/node_modules/import-meta-resolve/index.d.ts +19 -0
- package/node_modules/import-meta-resolve/index.d.ts.map +1 -0
- package/node_modules/import-meta-resolve/index.js +47 -0
- package/node_modules/import-meta-resolve/lib/errors.d.ts +24 -0
- package/node_modules/import-meta-resolve/lib/errors.d.ts.map +1 -0
- package/node_modules/import-meta-resolve/lib/errors.js +504 -0
- package/node_modules/import-meta-resolve/lib/get-format.d.ts +13 -0
- package/node_modules/import-meta-resolve/lib/get-format.d.ts.map +1 -0
- package/node_modules/import-meta-resolve/lib/get-format.js +159 -0
- package/node_modules/import-meta-resolve/lib/package-json-reader.d.ts +31 -0
- package/node_modules/import-meta-resolve/lib/package-json-reader.d.ts.map +1 -0
- package/node_modules/import-meta-resolve/lib/package-json-reader.js +177 -0
- package/node_modules/import-meta-resolve/lib/resolve.d.ts +29 -0
- package/node_modules/import-meta-resolve/lib/resolve.d.ts.map +1 -0
- package/node_modules/import-meta-resolve/lib/resolve.js +1301 -0
- package/node_modules/import-meta-resolve/lib/utils.d.ts +6 -0
- package/node_modules/import-meta-resolve/lib/utils.d.ts.map +1 -0
- package/node_modules/import-meta-resolve/lib/utils.js +47 -0
- package/node_modules/import-meta-resolve/license +74 -0
- package/node_modules/import-meta-resolve/package.json +78 -0
- package/node_modules/import-meta-resolve/readme.md +252 -0
- package/package.json +30 -26
- package/packages/octo-runtime-extra-channel-gateway/config-schema.json +2 -2
- package/packages/octo-runtime-extra-channel-wecom/config-schema.json +2 -2
- 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.
|
|
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.
|
|
9
|
-
"@mininglamp-oss/octo-runtime-adapter-acp": "1.1.
|
|
10
|
-
"@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 &&
|
|
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:
|
|
94
|
-
...(
|
|
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 (
|
|
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
|
|
17
|
-
|
|
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(
|
|
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
|
-
/**
|
|
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 === "
|
|
56
|
-
|
|
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.#
|
|
70
|
+
this.#worker = undefined;
|
|
62
71
|
this.#done?.();
|
|
63
72
|
});
|
|
64
73
|
this.#worker.on("exit", () => {
|
|
65
|
-
this.#
|
|
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 (
|
|
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
|
-
/*
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
9
|
-
"@mininglamp-oss/octo-runtime-adapter-sdk": "1.1.
|
|
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,6 +1,8 @@
|
|
|
1
|
-
import { type
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
33
|
+
/** CLI 将模块目录与业务配置装配;仅 load 时解析/import,禁用项及未启动项不执行模块。 */
|
|
34
|
+
export async function readExtra(paths, name, manifest) {
|
|
33
35
|
assertExtraName(name);
|
|
34
|
-
const
|
|
35
|
-
const entry =
|
|
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("
|
|
38
|
-
|
|
39
|
-
|
|
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:
|
|
45
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
}
|