dsh-cliworker-now 0.0.0-stage → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.en.md +364 -0
- package/README.md +368 -2
- package/cordis.patch.yml +3 -0
- package/lib/account-models.mjs +262 -0
- package/lib/client.js +22139 -0
- package/lib/client.js.map +1 -0
- package/lib/grok-catalog.mjs +145 -0
- package/lib/hermes-native-entry.py +96 -0
- package/lib/hermes-nous-refresh.py +331 -0
- package/lib/index.js +14544 -0
- package/lib/index.js.map +1 -0
- package/lib/native-launch.mjs +234 -0
- package/lib/native-spawn.mjs +32 -0
- package/lib/own-account-lease.mjs +105 -0
- package/lib/pi-installation.mjs +87 -0
- package/lib/pi-login.mjs +80 -0
- package/lib/pi-native-catalog.mjs +417 -0
- package/lib/pi-omp-bridge.mjs +602 -0
- package/lib/pi-omp-environment.mjs +15 -0
- package/lib/pi-omp-refresh.mjs +324 -0
- package/lib/private-launch.mjs +23 -0
- package/lib/terminal-bridge.mjs +18 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +1430 -0
- package/lib/typert.remote-client.d.ts +72 -0
- package/lib/typert.remote-client.d.ts.map +1 -0
- package/lib/typert.remote-client.js +1256 -0
- package/lib/types/client/account-query-queue.d.ts +16 -0
- package/lib/types/client/account-query-queue.js +61 -0
- package/lib/types/client/account-query-queue.js.map +1 -0
- package/lib/types/client/account-terminal-css.d.ts +1 -0
- package/lib/types/client/account-terminal-css.js +3 -0
- package/lib/types/client/account-terminal-css.js.map +1 -0
- package/lib/types/client/account-terminal.d.ts +17 -0
- package/lib/types/client/account-terminal.js +525 -0
- package/lib/types/client/account-terminal.js.map +1 -0
- package/lib/types/client/assets/antigravity.png +0 -0
- package/lib/types/client/assets/claude-code.png +0 -0
- package/lib/types/client/assets/cliworker-now-logo.png +0 -0
- package/lib/types/client/assets/codex.png +0 -0
- package/lib/types/client/assets/grok.png +0 -0
- package/lib/types/client/assets/hermes.png +0 -0
- package/lib/types/client/assets/kimi-dark.png +0 -0
- package/lib/types/client/assets/kimi-light.png +0 -0
- package/lib/types/client/assets/mimo-code.png +0 -0
- package/lib/types/client/assets/omp.png +0 -0
- package/lib/types/client/assets/opencode.png +0 -0
- package/lib/types/client/assets/pi.png +0 -0
- package/lib/types/client/assets/zcode.png +0 -0
- package/lib/types/client/composer-keymap.d.ts +18 -0
- package/lib/types/client/composer-keymap.js +49 -0
- package/lib/types/client/composer-keymap.js.map +1 -0
- package/lib/types/client/conversation-timeline.d.ts +6 -0
- package/lib/types/client/conversation-timeline.js +65 -0
- package/lib/types/client/conversation-timeline.js.map +1 -0
- package/lib/types/client/copy-text.d.ts +5 -0
- package/lib/types/client/copy-text.js +45 -0
- package/lib/types/client/copy-text.js.map +1 -0
- package/lib/types/client/icons.d.ts +21 -0
- package/lib/types/client/icons.js +68 -0
- package/lib/types/client/icons.js.map +1 -0
- package/lib/types/client/index.d.ts +3 -0
- package/lib/types/client/index.js +124 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/client/management-styles.d.ts +1 -0
- package/lib/types/client/management-styles.js +17 -0
- package/lib/types/client/management-styles.js.map +1 -0
- package/lib/types/client/name-copy.d.ts +5 -0
- package/lib/types/client/name-copy.js +107 -0
- package/lib/types/client/name-copy.js.map +1 -0
- package/lib/types/client/native-job-overlay.d.ts +11 -0
- package/lib/types/client/native-job-overlay.js +129 -0
- package/lib/types/client/native-job-overlay.js.map +1 -0
- package/lib/types/client/operation-error.d.ts +2 -0
- package/lib/types/client/operation-error.js +12 -0
- package/lib/types/client/operation-error.js.map +1 -0
- package/lib/types/client/panel.d.ts +8 -0
- package/lib/types/client/panel.js +310 -0
- package/lib/types/client/panel.js.map +1 -0
- package/lib/types/client/rename-copy-styles.d.ts +1 -0
- package/lib/types/client/rename-copy-styles.js +21 -0
- package/lib/types/client/rename-copy-styles.js.map +1 -0
- package/lib/types/client/rename-worker.d.ts +9 -0
- package/lib/types/client/rename-worker.js +53 -0
- package/lib/types/client/rename-worker.js.map +1 -0
- package/lib/types/client/role-presets.d.ts +6 -0
- package/lib/types/client/role-presets.js +111 -0
- package/lib/types/client/role-presets.js.map +1 -0
- package/lib/types/client/settings-dialog.d.ts +13 -0
- package/lib/types/client/settings-dialog.js +442 -0
- package/lib/types/client/settings-dialog.js.map +1 -0
- package/lib/types/client/stat-popover.d.ts +10 -0
- package/lib/types/client/stat-popover.js +32 -0
- package/lib/types/client/stat-popover.js.map +1 -0
- package/lib/types/client/styles.d.ts +9 -0
- package/lib/types/client/styles.js +221 -0
- package/lib/types/client/styles.js.map +1 -0
- package/lib/types/client/telemetry.d.ts +11 -0
- package/lib/types/client/telemetry.js +24 -0
- package/lib/types/client/telemetry.js.map +1 -0
- package/lib/types/client/worker-card.d.ts +10 -0
- package/lib/types/client/worker-card.js +75 -0
- package/lib/types/client/worker-card.js.map +1 -0
- package/lib/types/client/worker-model-menu.d.ts +9 -0
- package/lib/types/client/worker-model-menu.js +136 -0
- package/lib/types/client/worker-model-menu.js.map +1 -0
- package/lib/types/client/workers.d.ts +21 -0
- package/lib/types/client/workers.js +59 -0
- package/lib/types/client/workers.js.map +1 -0
- package/lib/types/client/zcode-login-link-provider.d.ts +9 -0
- package/lib/types/client/zcode-login-link-provider.js +105 -0
- package/lib/types/client/zcode-login-link-provider.js.map +1 -0
- package/lib/types/client/zcode-login-link.d.ts +16 -0
- package/lib/types/client/zcode-login-link.js +194 -0
- package/lib/types/client/zcode-login-link.js.map +1 -0
- package/lib/types/host/account-identity.d.ts +16 -0
- package/lib/types/host/account-identity.js +126 -0
- package/lib/types/host/account-identity.js.map +1 -0
- package/lib/types/host/account-login.d.ts +10 -0
- package/lib/types/host/account-login.js +126 -0
- package/lib/types/host/account-login.js.map +1 -0
- package/lib/types/host/account-models.d.mts +21 -0
- package/lib/types/host/account-models.mjs +262 -0
- package/lib/types/host/accounts.d.ts +42 -0
- package/lib/types/host/accounts.js +945 -0
- package/lib/types/host/accounts.js.map +1 -0
- package/lib/types/host/adapters.d.ts +24 -0
- package/lib/types/host/adapters.js +380 -0
- package/lib/types/host/adapters.js.map +1 -0
- package/lib/types/host/agy-context.d.ts +8 -0
- package/lib/types/host/agy-context.js +122 -0
- package/lib/types/host/agy-context.js.map +1 -0
- package/lib/types/host/agy-models.d.ts +5 -0
- package/lib/types/host/agy-models.js +37 -0
- package/lib/types/host/agy-models.js.map +1 -0
- package/lib/types/host/agy-windows-account.d.ts +14 -0
- package/lib/types/host/agy-windows-account.js +104 -0
- package/lib/types/host/agy-windows-account.js.map +1 -0
- package/lib/types/host/authorized-catalog.d.ts +14 -0
- package/lib/types/host/authorized-catalog.js +35 -0
- package/lib/types/host/authorized-catalog.js.map +1 -0
- package/lib/types/host/bridge-protocol.d.ts +15 -0
- package/lib/types/host/bridge-protocol.js +80 -0
- package/lib/types/host/bridge-protocol.js.map +1 -0
- package/lib/types/host/claude-native-oauth.d.ts +17 -0
- package/lib/types/host/claude-native-oauth.js +272 -0
- package/lib/types/host/claude-native-oauth.js.map +1 -0
- package/lib/types/host/claude-own-route.d.ts +33 -0
- package/lib/types/host/claude-own-route.js +250 -0
- package/lib/types/host/claude-own-route.js.map +1 -0
- package/lib/types/host/cli-account-binding.d.ts +33 -0
- package/lib/types/host/cli-account-binding.js +540 -0
- package/lib/types/host/cli-account-binding.js.map +1 -0
- package/lib/types/host/cli-protocol.d.ts +27 -0
- package/lib/types/host/cli-protocol.js +212 -0
- package/lib/types/host/cli-protocol.js.map +1 -0
- package/lib/types/host/codex-account.d.ts +8 -0
- package/lib/types/host/codex-account.js +143 -0
- package/lib/types/host/codex-account.js.map +1 -0
- package/lib/types/host/codex-models.d.ts +6 -0
- package/lib/types/host/codex-models.js +169 -0
- package/lib/types/host/codex-models.js.map +1 -0
- package/lib/types/host/extended-adapters.d.ts +44 -0
- package/lib/types/host/extended-adapters.js +207 -0
- package/lib/types/host/extended-adapters.js.map +1 -0
- package/lib/types/host/first-party-account-context.d.ts +26 -0
- package/lib/types/host/first-party-account-context.js +55 -0
- package/lib/types/host/first-party-account-context.js.map +1 -0
- package/lib/types/host/first-party-models.d.ts +29 -0
- package/lib/types/host/first-party-models.js +459 -0
- package/lib/types/host/first-party-models.js.map +1 -0
- package/lib/types/host/grok-adapter.d.ts +44 -0
- package/lib/types/host/grok-adapter.js +293 -0
- package/lib/types/host/grok-adapter.js.map +1 -0
- package/lib/types/host/grok-models.d.ts +47 -0
- package/lib/types/host/grok-models.js +320 -0
- package/lib/types/host/grok-models.js.map +1 -0
- package/lib/types/host/harness-opencode-accounts.d.ts +17 -0
- package/lib/types/host/harness-opencode-accounts.js +80 -0
- package/lib/types/host/harness-opencode-accounts.js.map +1 -0
- package/lib/types/host/hermes-account-context.d.ts +8 -0
- package/lib/types/host/hermes-account-context.js +99 -0
- package/lib/types/host/hermes-account-context.js.map +1 -0
- package/lib/types/host/hermes-accounts.d.ts +19 -0
- package/lib/types/host/hermes-accounts.js +356 -0
- package/lib/types/host/hermes-accounts.js.map +1 -0
- package/lib/types/host/hermes-adapter.d.ts +93 -0
- package/lib/types/host/hermes-adapter.js +455 -0
- package/lib/types/host/hermes-adapter.js.map +1 -0
- package/lib/types/host/hermes-env.d.ts +4 -0
- package/lib/types/host/hermes-env.js +22 -0
- package/lib/types/host/hermes-env.js.map +1 -0
- package/lib/types/host/hermes-installation.d.ts +10 -0
- package/lib/types/host/hermes-installation.js +181 -0
- package/lib/types/host/hermes-installation.js.map +1 -0
- package/lib/types/host/hermes-models.d.ts +26 -0
- package/lib/types/host/hermes-models.js +328 -0
- package/lib/types/host/hermes-models.js.map +1 -0
- package/lib/types/host/hermes-native-entry.py +96 -0
- package/lib/types/host/hermes-nous-refresh.py +331 -0
- package/lib/types/host/hermes-nous.d.ts +53 -0
- package/lib/types/host/hermes-nous.js +343 -0
- package/lib/types/host/hermes-nous.js.map +1 -0
- package/lib/types/host/hermes-renewal.d.ts +27 -0
- package/lib/types/host/hermes-renewal.js +292 -0
- package/lib/types/host/hermes-renewal.js.map +1 -0
- package/lib/types/host/hermes-suppression.d.ts +7 -0
- package/lib/types/host/hermes-suppression.js +69 -0
- package/lib/types/host/hermes-suppression.js.map +1 -0
- package/lib/types/host/hermes-windows-installation.d.ts +5 -0
- package/lib/types/host/hermes-windows-installation.js +91 -0
- package/lib/types/host/hermes-windows-installation.js.map +1 -0
- package/lib/types/host/index.d.ts +140 -0
- package/lib/types/host/index.js +947 -0
- package/lib/types/host/index.js.map +1 -0
- package/lib/types/host/kimi-accounts.d.ts +17 -0
- package/lib/types/host/kimi-accounts.js +220 -0
- package/lib/types/host/kimi-accounts.js.map +1 -0
- package/lib/types/host/kimi-oauth-models.d.ts +14 -0
- package/lib/types/host/kimi-oauth-models.js +246 -0
- package/lib/types/host/kimi-oauth-models.js.map +1 -0
- package/lib/types/host/managed-agent.d.ts +4 -0
- package/lib/types/host/managed-agent.js +127 -0
- package/lib/types/host/managed-agent.js.map +1 -0
- package/lib/types/host/mimo-configuration.d.ts +22 -0
- package/lib/types/host/mimo-configuration.js +258 -0
- package/lib/types/host/mimo-configuration.js.map +1 -0
- package/lib/types/host/mimo-metadata-cache.d.ts +22 -0
- package/lib/types/host/mimo-metadata-cache.js +121 -0
- package/lib/types/host/mimo-metadata-cache.js.map +1 -0
- package/lib/types/host/native-capability-cache.d.ts +11 -0
- package/lib/types/host/native-capability-cache.js +94 -0
- package/lib/types/host/native-capability-cache.js.map +1 -0
- package/lib/types/host/native-launch.d.mts +2 -0
- package/lib/types/host/native-launch.mjs +234 -0
- package/lib/types/host/native-process.d.ts +5 -0
- package/lib/types/host/native-process.js +41 -0
- package/lib/types/host/native-process.js.map +1 -0
- package/lib/types/host/native-spawn.mjs +32 -0
- package/lib/types/host/opencode-adapter.d.ts +94 -0
- package/lib/types/host/opencode-adapter.js +507 -0
- package/lib/types/host/opencode-adapter.js.map +1 -0
- package/lib/types/host/opencode-native.d.ts +27 -0
- package/lib/types/host/opencode-native.js +403 -0
- package/lib/types/host/opencode-native.js.map +1 -0
- package/lib/types/host/own-account-lease.d.mts +5 -0
- package/lib/types/host/own-account-lease.mjs +105 -0
- package/lib/types/host/pi-installation.d.mts +7 -0
- package/lib/types/host/pi-installation.mjs +87 -0
- package/lib/types/host/pi-omp-accounts.d.ts +28 -0
- package/lib/types/host/pi-omp-accounts.js +175 -0
- package/lib/types/host/pi-omp-accounts.js.map +1 -0
- package/lib/types/host/pi-omp-adapter.d.ts +32 -0
- package/lib/types/host/pi-omp-adapter.js +190 -0
- package/lib/types/host/pi-omp-adapter.js.map +1 -0
- package/lib/types/host/pi-omp-environment.d.mts +1 -0
- package/lib/types/host/pi-omp-environment.mjs +15 -0
- package/lib/types/host/pi-omp-identity.d.ts +2 -0
- package/lib/types/host/pi-omp-identity.js +142 -0
- package/lib/types/host/pi-omp-identity.js.map +1 -0
- package/lib/types/host/pi-omp-logout.d.ts +3 -0
- package/lib/types/host/pi-omp-logout.js +152 -0
- package/lib/types/host/pi-omp-logout.js.map +1 -0
- package/lib/types/host/pi-omp-native.d.ts +71 -0
- package/lib/types/host/pi-omp-native.js +753 -0
- package/lib/types/host/pi-omp-native.js.map +1 -0
- package/lib/types/host/pi-omp-refresh.d.mts +7 -0
- package/lib/types/host/pi-omp-refresh.mjs +324 -0
- package/lib/types/host/private-launch.mjs +23 -0
- package/lib/types/host/process.d.ts +43 -0
- package/lib/types/host/process.js +134 -0
- package/lib/types/host/process.js.map +1 -0
- package/lib/types/host/protocol.d.ts +23 -0
- package/lib/types/host/protocol.js +112 -0
- package/lib/types/host/protocol.js.map +1 -0
- package/lib/types/host/roles.d.ts +34 -0
- package/lib/types/host/roles.js +80 -0
- package/lib/types/host/roles.js.map +1 -0
- package/lib/types/host/routing.d.ts +31 -0
- package/lib/types/host/routing.js +248 -0
- package/lib/types/host/routing.js.map +1 -0
- package/lib/types/host/runtime.d.ts +60 -0
- package/lib/types/host/runtime.js +598 -0
- package/lib/types/host/runtime.js.map +1 -0
- package/lib/types/host/storage.d.ts +48 -0
- package/lib/types/host/storage.js +449 -0
- package/lib/types/host/storage.js.map +1 -0
- package/lib/types/host/telemetry.d.ts +17 -0
- package/lib/types/host/telemetry.js +158 -0
- package/lib/types/host/telemetry.js.map +1 -0
- package/lib/types/host/windows-account-bootstrap.ps1 +44 -0
- package/lib/types/host/windows-account-launch.mjs +47 -0
- package/lib/types/host/windows-account-owner.ps1 +137 -0
- package/lib/types/host/windows-account-stdio.mjs +19 -0
- package/lib/types/host/windows-account-terminal.d.ts +17 -0
- package/lib/types/host/windows-account-terminal.js +208 -0
- package/lib/types/host/windows-account-terminal.js.map +1 -0
- package/lib/types/host/windows-agy-account.ps1 +81 -0
- package/lib/types/host/windows-cli-installation.d.ts +31 -0
- package/lib/types/host/windows-cli-installation.js +157 -0
- package/lib/types/host/windows-cli-installation.js.map +1 -0
- package/lib/types/host/windows-hidden-launch.mjs +49 -0
- package/lib/types/host/windows-hidden-process.d.ts +12 -0
- package/lib/types/host/windows-hidden-process.js +116 -0
- package/lib/types/host/windows-hidden-process.js.map +1 -0
- package/lib/types/host/zcode-account-models.d.ts +16 -0
- package/lib/types/host/zcode-account-models.js +114 -0
- package/lib/types/host/zcode-account-models.js.map +1 -0
- package/lib/types/host/zcode-adapter.d.ts +93 -0
- package/lib/types/host/zcode-adapter.js +808 -0
- package/lib/types/host/zcode-adapter.js.map +1 -0
- package/lib/types/host/zcode-grok-accounts.d.ts +30 -0
- package/lib/types/host/zcode-grok-accounts.js +408 -0
- package/lib/types/host/zcode-grok-accounts.js.map +1 -0
- package/lib/types/shared/accounts.d.ts +47 -0
- package/lib/types/shared/accounts.js +2 -0
- package/lib/types/shared/accounts.js.map +1 -0
- package/lib/types/shared/builtin-presets.d.ts +2 -0
- package/lib/types/shared/builtin-presets.js +231 -0
- package/lib/types/shared/builtin-presets.js.map +1 -0
- package/lib/types/shared/cli-settings.d.ts +5 -0
- package/lib/types/shared/cli-settings.js +2 -0
- package/lib/types/shared/cli-settings.js.map +1 -0
- package/lib/types/shared/model-presentation.d.ts +10 -0
- package/lib/types/shared/model-presentation.js +95 -0
- package/lib/types/shared/model-presentation.js.map +1 -0
- package/lib/types/shared/models.d.ts +7 -0
- package/lib/types/shared/models.js +35 -0
- package/lib/types/shared/models.js.map +1 -0
- package/lib/types/shared/telemetry.d.ts +18 -0
- package/lib/types/shared/telemetry.js +16 -0
- package/lib/types/shared/telemetry.js.map +1 -0
- package/lib/types/shared/types.d.ts +127 -0
- package/lib/types/shared/types.js +147 -0
- package/lib/types/shared/types.js.map +1 -0
- package/lib/windows-account-bootstrap.ps1 +44 -0
- package/lib/windows-account-launch.mjs +47 -0
- package/lib/windows-account-owner.ps1 +137 -0
- package/lib/windows-account-stdio.mjs +19 -0
- package/lib/windows-agy-account.ps1 +81 -0
- package/lib/windows-hidden-launch.mjs +49 -0
- package/lib/zcode-resume.mjs +423 -0
- package/package.json +109 -4
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { lstat, mkdir, open, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { dirname, join, resolve, relative, isAbsolute } from 'node:path';
|
|
6
|
+
import { safePiOmpAncestors } from "./pi-omp-native.js";
|
|
7
|
+
import { authenticatedAccountLogins, providerLogin, usableNativeApiKey } from "./account-login.js";
|
|
8
|
+
const object = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
9
|
+
const text = (value) => typeof value === 'string' && !!value.trim();
|
|
10
|
+
export const OPENCODE_OAUTH_UNSUPPORTED = 'OpenCode OAuth 暂无法安全续期,请使用该 CLI 自身 API 配置';
|
|
11
|
+
/** JSONC comments/trailing commas, without changing quoted model IDs or URLs. */
|
|
12
|
+
function jsonc(raw) {
|
|
13
|
+
let result = '', quoted = false, escaped = false;
|
|
14
|
+
for (let i = 0; i < raw.length; i++) {
|
|
15
|
+
const ch = raw[i];
|
|
16
|
+
if (quoted) {
|
|
17
|
+
result += ch;
|
|
18
|
+
if (escaped)
|
|
19
|
+
escaped = false;
|
|
20
|
+
else if (ch === '\\')
|
|
21
|
+
escaped = true;
|
|
22
|
+
else if (ch === '"')
|
|
23
|
+
quoted = false;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (ch === '"') {
|
|
27
|
+
quoted = true;
|
|
28
|
+
result += ch;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (ch === '/' && raw[i + 1] === '/') {
|
|
32
|
+
while (i + 1 < raw.length && raw[i + 1] !== '\n')
|
|
33
|
+
i++;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (ch === '/' && raw[i + 1] === '*') {
|
|
37
|
+
const end = raw.indexOf('*/', i + 2);
|
|
38
|
+
if (end < 0)
|
|
39
|
+
throw new Error('Invalid native JSONC');
|
|
40
|
+
i = end + 1;
|
|
41
|
+
result += ' ';
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (ch === ',') {
|
|
45
|
+
let next = i + 1;
|
|
46
|
+
while (next < raw.length) {
|
|
47
|
+
if (/\s/.test(raw[next])) {
|
|
48
|
+
next++;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (raw.slice(next, next + 2) === '//') {
|
|
52
|
+
const line = raw.indexOf('\n', next + 2);
|
|
53
|
+
next = line < 0 ? raw.length : line + 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (raw.slice(next, next + 2) === '/*') {
|
|
57
|
+
const end = raw.indexOf('*/', next + 2);
|
|
58
|
+
if (end < 0)
|
|
59
|
+
throw new Error('Invalid native JSONC');
|
|
60
|
+
next = end + 2;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (raw[next] === '}' || raw[next] === ']')
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
result += ch;
|
|
69
|
+
}
|
|
70
|
+
return JSON.parse(result);
|
|
71
|
+
}
|
|
72
|
+
export { jsonc as parseNativeJsonc };
|
|
73
|
+
async function ownEnvironment(roots, options, sourceIds) {
|
|
74
|
+
const result = {};
|
|
75
|
+
for (const root of roots) {
|
|
76
|
+
let handle;
|
|
77
|
+
try {
|
|
78
|
+
options.signal?.throwIfAborted();
|
|
79
|
+
await safePiOmpAncestors(root);
|
|
80
|
+
handle = await open(join(root, '.env'), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
81
|
+
const info = await handle.stat();
|
|
82
|
+
if (!info.isFile() || info.nlink !== 1 || info.size > 65536)
|
|
83
|
+
throw new Error();
|
|
84
|
+
const bytes = Buffer.alloc(65537);
|
|
85
|
+
try {
|
|
86
|
+
const { bytesRead } = await handle.read(bytes, 0, bytes.length, 0);
|
|
87
|
+
if (bytesRead > 65536)
|
|
88
|
+
throw new Error();
|
|
89
|
+
for (const line of bytes.subarray(0, bytesRead).toString('utf8').split(/\r?\n/)) {
|
|
90
|
+
if (!line.trim() || line.trimStart().startsWith('#'))
|
|
91
|
+
continue;
|
|
92
|
+
const match = /^(?:export\s+)?([A-Z][A-Z0-9_]*)\s*=\s*(.*)$/.exec(line.trim());
|
|
93
|
+
if (!match)
|
|
94
|
+
throw new Error();
|
|
95
|
+
let value = match[2];
|
|
96
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
97
|
+
(value.startsWith("'") && value.endsWith("'")))
|
|
98
|
+
value = value.slice(1, -1);
|
|
99
|
+
if (/`|\$\(|\x00/.test(value))
|
|
100
|
+
throw new Error();
|
|
101
|
+
result[match[1]] = value;
|
|
102
|
+
sourceIds.add(resolve(root));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
bytes.fill(0);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error.code !== 'ENOENT')
|
|
111
|
+
throw new Error('OpenCode 自身环境配置无法安全读取');
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
await handle?.close();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
async function resolveReferences(value, options, scope, depth = 0) {
|
|
120
|
+
if (depth > 48)
|
|
121
|
+
throw new Error('OpenCode 原生配置过深');
|
|
122
|
+
if (Array.isArray(value))
|
|
123
|
+
return Promise.all(value.map((entry) => resolveReferences(entry, options, scope, depth + 1)));
|
|
124
|
+
if (object(value))
|
|
125
|
+
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, entry]) => [
|
|
126
|
+
key,
|
|
127
|
+
await resolveReferences(entry, options, scope, depth + 1),
|
|
128
|
+
])));
|
|
129
|
+
if (typeof value !== 'string')
|
|
130
|
+
return value;
|
|
131
|
+
let result = value.replace(/\{env:([^}]+)\}/g, (_, name) => scope.env[name] ?? '');
|
|
132
|
+
for (const match of [...result.matchAll(/\{file:([^}]+)\}/g)]) {
|
|
133
|
+
const path = match[1].startsWith('~/')
|
|
134
|
+
? join(options.nativeHome ?? homedir(), match[1].slice(2))
|
|
135
|
+
: match[1];
|
|
136
|
+
if (!isAbsolute(path) ||
|
|
137
|
+
!scope.roots.some((root) => {
|
|
138
|
+
const rel = relative(resolve(root), resolve(path));
|
|
139
|
+
return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);
|
|
140
|
+
}))
|
|
141
|
+
throw new Error('OpenCode 只允许引用自身账号目录中的凭据文件');
|
|
142
|
+
await safePiOmpAncestors(dirname(path));
|
|
143
|
+
let file;
|
|
144
|
+
const bytes = Buffer.alloc(65537);
|
|
145
|
+
try {
|
|
146
|
+
options.signal?.throwIfAborted();
|
|
147
|
+
const parent = await lstat(dirname(path));
|
|
148
|
+
if (!parent.isDirectory() || parent.isSymbolicLink())
|
|
149
|
+
throw new Error('Unsafe credential reference');
|
|
150
|
+
file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
151
|
+
const info = await file.stat();
|
|
152
|
+
if (!info.isFile() || info.nlink !== 1 || info.size > 65536)
|
|
153
|
+
throw new Error('Unsafe credential reference');
|
|
154
|
+
const { bytesRead } = await file.read(bytes, 0, bytes.length, 0);
|
|
155
|
+
if (bytesRead > 65536)
|
|
156
|
+
throw new Error('Oversized credential reference');
|
|
157
|
+
result = result.replace(match[0], bytes.subarray(0, bytesRead).toString('utf8').trim());
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
throw new Error('OpenCode 原生凭据引用无法安全读取');
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
bytes.fill(0);
|
|
164
|
+
await file?.close();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
function merge(base, next) {
|
|
170
|
+
return Object.fromEntries([...new Set([...Object.keys(base), ...Object.keys(next)])].map((key) => [
|
|
171
|
+
key,
|
|
172
|
+
object(base[key]) && object(next[key])
|
|
173
|
+
? merge(base[key], next[key])
|
|
174
|
+
: next[key] === undefined
|
|
175
|
+
? base[key]
|
|
176
|
+
: next[key],
|
|
177
|
+
]));
|
|
178
|
+
}
|
|
179
|
+
async function readDocument(path, optional, options, comments = false, limit = 4 * 1024 * 1024) {
|
|
180
|
+
let file;
|
|
181
|
+
const bytes = Buffer.alloc(limit + 1);
|
|
182
|
+
try {
|
|
183
|
+
options.signal?.throwIfAborted();
|
|
184
|
+
const parent = await lstat(dirname(path));
|
|
185
|
+
if (!parent.isDirectory() || parent.isSymbolicLink())
|
|
186
|
+
throw new Error('Unsafe native account directory');
|
|
187
|
+
file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
188
|
+
const before = await file.stat();
|
|
189
|
+
if (!before.isFile() || before.nlink !== 1 || before.size >= bytes.length)
|
|
190
|
+
throw new Error('Unsafe native account file');
|
|
191
|
+
let length = 0;
|
|
192
|
+
while (length < bytes.length) {
|
|
193
|
+
options.signal?.throwIfAborted();
|
|
194
|
+
const part = await file.read(bytes, length, bytes.length - length, null);
|
|
195
|
+
if (!part.bytesRead)
|
|
196
|
+
break;
|
|
197
|
+
length += part.bytesRead;
|
|
198
|
+
}
|
|
199
|
+
const after = await file.stat();
|
|
200
|
+
if (length >= bytes.length || before.size !== after.size || before.mtimeMs !== after.mtimeMs)
|
|
201
|
+
throw new Error('Native account changed during read');
|
|
202
|
+
const value = comments
|
|
203
|
+
? jsonc(bytes.subarray(0, length).toString('utf8'))
|
|
204
|
+
: JSON.parse(bytes.subarray(0, length).toString('utf8'));
|
|
205
|
+
if (!object(value))
|
|
206
|
+
throw new Error('Invalid native account data');
|
|
207
|
+
return value;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
options.signal?.throwIfAborted();
|
|
211
|
+
if (optional && error.code === 'ENOENT')
|
|
212
|
+
return undefined;
|
|
213
|
+
throw new Error('OpenCode 原生账号或模型配置无法安全读取,请检查配置');
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
bytes.fill(0);
|
|
217
|
+
await file?.close();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
export const activeOpenCodeCredential = (value) => object(value) &&
|
|
221
|
+
(value.type === 'api'
|
|
222
|
+
? text(value.key)
|
|
223
|
+
: value.type === 'oauth' &&
|
|
224
|
+
text(value.access) &&
|
|
225
|
+
typeof value.expires === 'number' &&
|
|
226
|
+
value.expires > Date.now() + 30000);
|
|
227
|
+
/** A native account terminal may load remote well-known config before provider filters. */
|
|
228
|
+
export async function assertOpenCodeManagedAuth(authDirectory, signal) {
|
|
229
|
+
await safePiOmpAncestors(join(authDirectory, 'opencode'));
|
|
230
|
+
const auth = (await readDocument(join(authDirectory, 'opencode/auth.json'), true, { signal })) ?? {};
|
|
231
|
+
if (Object.values(auth).some((entry) => !object(entry) || !['api', 'oauth'].includes(entry.type)))
|
|
232
|
+
throw new Error('OpenCode 原生账号包含不支持的远程认证配置');
|
|
233
|
+
}
|
|
234
|
+
/** The same native+plugin sources supply metadata queries and worker execution. */
|
|
235
|
+
export async function readOpenCodeProfile(authDirectory, options = {}) {
|
|
236
|
+
const home = options.nativeHome ?? homedir();
|
|
237
|
+
const data = options.nativeHome
|
|
238
|
+
? join(home, '.local/share')
|
|
239
|
+
: process.env.XDG_DATA_HOME || join(home, '.local/share');
|
|
240
|
+
const config = options.nativeHome
|
|
241
|
+
? join(home, '.config')
|
|
242
|
+
: process.env.XDG_CONFIG_HOME || join(home, '.config');
|
|
243
|
+
const ownRoots = [
|
|
244
|
+
join(config, 'opencode'),
|
|
245
|
+
join(data, 'opencode'),
|
|
246
|
+
join(dirname(authDirectory), 'config', 'opencode'),
|
|
247
|
+
join(authDirectory, 'opencode'),
|
|
248
|
+
];
|
|
249
|
+
const sourceIds = new Set();
|
|
250
|
+
const ownEnv = await ownEnvironment(ownRoots, options, sourceIds);
|
|
251
|
+
const globalAuth = (await readDocument(join(data, 'opencode/auth.json'), true, options)) ?? {};
|
|
252
|
+
const localAuth = (await readDocument(join(authDirectory, 'opencode/auth.json'), true, options)) ?? {};
|
|
253
|
+
if (Object.keys(globalAuth).length)
|
|
254
|
+
sourceIds.add(resolve(data, 'opencode'));
|
|
255
|
+
if (Object.keys(localAuth).length)
|
|
256
|
+
sourceIds.add(resolve(authDirectory, 'opencode'));
|
|
257
|
+
let settings = {};
|
|
258
|
+
const paths = [
|
|
259
|
+
...['config.json', 'opencode.json', 'opencode.jsonc'].map((name) => join(config, 'opencode', name)),
|
|
260
|
+
...['opencode.json', 'opencode.jsonc'].map((name) => join(dirname(authDirectory), 'config', 'opencode', name)),
|
|
261
|
+
];
|
|
262
|
+
for (const path of new Set(paths)) {
|
|
263
|
+
const document = (await readDocument(path, true, options, true)) ?? {};
|
|
264
|
+
settings = merge(settings, document);
|
|
265
|
+
if (Object.keys(document.provider ?? {}).length)
|
|
266
|
+
sourceIds.add(resolve(dirname(path)));
|
|
267
|
+
}
|
|
268
|
+
const providers = await resolveReferences(settings.provider ?? {}, options, {
|
|
269
|
+
roots: ownRoots,
|
|
270
|
+
env: ownEnv,
|
|
271
|
+
});
|
|
272
|
+
if (!object(providers))
|
|
273
|
+
throw new Error('OpenCode 原生提供商配置无效');
|
|
274
|
+
const auth = { ...globalAuth, ...localAuth };
|
|
275
|
+
for (const [id, provider] of Object.entries(providers)) {
|
|
276
|
+
if (!object(provider))
|
|
277
|
+
throw new Error('OpenCode 原生提供商配置无效');
|
|
278
|
+
const key = provider.options?.apiKey;
|
|
279
|
+
if (typeof key === 'string' && key.trim()) {
|
|
280
|
+
if (key.trimStart().startsWith('!'))
|
|
281
|
+
throw new Error('OpenCode 不执行凭据命令');
|
|
282
|
+
// Keep the explicit API source identical in metadata and the private runtime auth store.
|
|
283
|
+
auth[id] = { type: 'api', key };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const disabled = settings.disabled_providers ?? [], enabled = settings.enabled_providers;
|
|
287
|
+
if (!Array.isArray(disabled) ||
|
|
288
|
+
!disabled.every(text) ||
|
|
289
|
+
(enabled !== undefined && (!Array.isArray(enabled) || !enabled.every(text))))
|
|
290
|
+
throw new Error('OpenCode 原生提供商开关配置无效');
|
|
291
|
+
const cache = options.modelsPath ??
|
|
292
|
+
(options.nativeHome
|
|
293
|
+
? join(home, '.cache/opencode/models.json')
|
|
294
|
+
: process.env.OPENCODE_MODELS_PATH || join(home, '.cache/opencode/models.json'));
|
|
295
|
+
return {
|
|
296
|
+
sourceIds: [...sourceIds].sort(),
|
|
297
|
+
auth,
|
|
298
|
+
providers,
|
|
299
|
+
disabled,
|
|
300
|
+
enabled,
|
|
301
|
+
modelsPath: cache,
|
|
302
|
+
// The installed public multi-provider cache is 4.4 MB; scoped CLI output
|
|
303
|
+
// remains capped at 4 MB. This larger cap does not apply to credential files.
|
|
304
|
+
catalog: (await readDocument(cache, true, options, false, 8 * 1024 * 1024)) ?? {},
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/** Rebuild a private copy from current own sources; never restore an old worker account. */
|
|
308
|
+
export async function snapshotOpenCodeAuth(authDirectory, auth, providers, signal) {
|
|
309
|
+
// Native Auth.set has no cross-process CAS. Copying OAuth loses rotated tokens;
|
|
310
|
+
// writing directly can resurrect a concurrent logout. Neither mode is safe.
|
|
311
|
+
if (providers.some((id) => auth[id]?.type === 'oauth'))
|
|
312
|
+
throw new Error(OPENCODE_OAUTH_UNSUPPORTED);
|
|
313
|
+
const chosen = Object.fromEntries(providers
|
|
314
|
+
.filter((id) => auth[id]?.type === 'api' && activeOpenCodeCredential(auth[id]))
|
|
315
|
+
.map((id) => [id, auth[id]]));
|
|
316
|
+
const digest = createHash('sha256').update(JSON.stringify(chosen)).digest('hex');
|
|
317
|
+
const root = join(authDirectory, 'cliworker-snapshots', 'own-v2-' + digest);
|
|
318
|
+
for (const path of [
|
|
319
|
+
authDirectory,
|
|
320
|
+
join(authDirectory, 'cliworker-snapshots'),
|
|
321
|
+
root,
|
|
322
|
+
join(root, 'opencode'),
|
|
323
|
+
]) {
|
|
324
|
+
signal?.throwIfAborted();
|
|
325
|
+
await safePiOmpAncestors(path);
|
|
326
|
+
await mkdir(path, { recursive: true, mode: 0o700 });
|
|
327
|
+
const info = await lstat(path);
|
|
328
|
+
if (!info.isDirectory() || info.isSymbolicLink() || (process.platform !== 'win32' && (info.mode & 0o077)))
|
|
329
|
+
throw new Error('OpenCode 私有账号快照目录不安全');
|
|
330
|
+
}
|
|
331
|
+
const path = join(root, 'opencode/auth.json');
|
|
332
|
+
try {
|
|
333
|
+
const info = await lstat(path);
|
|
334
|
+
if (!info.isFile() || info.isSymbolicLink() || info.nlink !== 1 || (process.platform !== 'win32' && (info.mode & 0o077)))
|
|
335
|
+
throw new Error('OpenCode 私有账号快照文件不安全');
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
if (error.code !== 'ENOENT')
|
|
339
|
+
throw error;
|
|
340
|
+
}
|
|
341
|
+
const temporary = join(root, 'opencode', `.auth-${randomUUID()}.tmp`);
|
|
342
|
+
try {
|
|
343
|
+
signal?.throwIfAborted();
|
|
344
|
+
await writeFile(temporary, JSON.stringify(chosen), { mode: 0o600, flag: 'wx' });
|
|
345
|
+
signal?.throwIfAborted();
|
|
346
|
+
await rename(temporary, path);
|
|
347
|
+
}
|
|
348
|
+
finally {
|
|
349
|
+
await rm(temporary, { force: true });
|
|
350
|
+
}
|
|
351
|
+
signal?.throwIfAborted();
|
|
352
|
+
return root;
|
|
353
|
+
}
|
|
354
|
+
export async function inspectOpenCodeProfile(authDirectory, options = {}) {
|
|
355
|
+
try {
|
|
356
|
+
const profile = await readOpenCodeProfile(authDirectory, options);
|
|
357
|
+
const logins = [];
|
|
358
|
+
let expired = false;
|
|
359
|
+
for (const [id, auth] of Object.entries(profile.auth)) {
|
|
360
|
+
if (!object(auth))
|
|
361
|
+
continue;
|
|
362
|
+
const api = auth.type === 'api' && usableNativeApiKey(auth.key);
|
|
363
|
+
const oauthShape = auth.type === 'oauth' &&
|
|
364
|
+
usableNativeApiKey(auth.access) &&
|
|
365
|
+
typeof auth.expires === 'number' &&
|
|
366
|
+
Number.isFinite(auth.expires) &&
|
|
367
|
+
(auth.refresh === undefined || typeof auth.refresh === 'string');
|
|
368
|
+
const oauth = oauthShape && (auth.expires > Date.now() || usableNativeApiKey(auth.refresh));
|
|
369
|
+
if (oauthShape && !oauth)
|
|
370
|
+
expired = true;
|
|
371
|
+
if (api || oauth) {
|
|
372
|
+
const config = profile.providers[id];
|
|
373
|
+
logins.push(providerLogin(id, api ? 'api' : 'oauth', {
|
|
374
|
+
baseUrl: config?.options?.baseURL,
|
|
375
|
+
name: config?.name,
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (logins.length)
|
|
380
|
+
return authenticatedAccountLogins(logins);
|
|
381
|
+
if (expired)
|
|
382
|
+
return {
|
|
383
|
+
state: 'unauthenticated',
|
|
384
|
+
verification: 'local',
|
|
385
|
+
summary: '登录已过期,请重新登录',
|
|
386
|
+
};
|
|
387
|
+
if (Object.values(profile.auth).some((auth) => object(auth) && auth.type === 'api') ||
|
|
388
|
+
(!Object.keys(profile.auth).length && Object.keys(profile.providers).length))
|
|
389
|
+
return { state: 'configured', verification: 'local', summary: '尚未配置有效凭据' };
|
|
390
|
+
return Object.keys(profile.auth).length
|
|
391
|
+
? { state: 'unknown', verification: 'local', summary: '账号配置格式未知' }
|
|
392
|
+
: { state: 'unconfigured', verification: 'local', summary: '尚未配置 OpenCode 账号' };
|
|
393
|
+
}
|
|
394
|
+
catch {
|
|
395
|
+
options.signal?.throwIfAborted();
|
|
396
|
+
return {
|
|
397
|
+
state: 'unavailable',
|
|
398
|
+
verification: 'local',
|
|
399
|
+
summary: '账号配置读取失败,请检查配置',
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
//# sourceMappingURL=opencode-native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-native.js","sourceRoot":"","sources":["../../../src/host/opencode-native.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const OWN_ACCOUNT_BUSY: string
|
|
2
|
+
export function assertOwnAccountLeaseIdle(root: string): Promise<void>
|
|
3
|
+
export function acquireOwnAccountLease(root: string, nonce: string): Promise<void>
|
|
4
|
+
export function ownsOwnAccountLease(root: string, nonce: string): Promise<boolean>
|
|
5
|
+
export function releaseOwnAccountLease(root: string, nonce: string): Promise<void>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { constants } from 'node:fs'
|
|
2
|
+
import { lstat, mkdir, open, realpath, rename, rm, writeFile } from 'node:fs/promises'
|
|
3
|
+
import { join, resolve } from 'node:path'
|
|
4
|
+
|
|
5
|
+
export const OWN_ACCOUNT_BUSY = '账号正被使用,请稍后刷新'
|
|
6
|
+
const nonceValid = (value) => typeof value === 'string' && /^[a-f0-9-]{36}$/.test(value)
|
|
7
|
+
async function privateRoot(root) {
|
|
8
|
+
const info = await lstat(root)
|
|
9
|
+
if (
|
|
10
|
+
!info.isDirectory() ||
|
|
11
|
+
info.isSymbolicLink() ||
|
|
12
|
+
(process.platform !== 'win32' && (info.mode & 0o077)) ||
|
|
13
|
+
(await realpath(root)) !== resolve(root)
|
|
14
|
+
)
|
|
15
|
+
throw new Error('账号运行目录无法安全使用')
|
|
16
|
+
}
|
|
17
|
+
/** A lease is not stolen after PID death: its descendants may still be alive.
|
|
18
|
+
* Only Host cleanup after confirmed process-range exit may release it. */
|
|
19
|
+
export async function assertOwnAccountLeaseIdle(root) {
|
|
20
|
+
await privateRoot(root)
|
|
21
|
+
try {
|
|
22
|
+
await lstat(join(root, '.lease'))
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (error?.code === 'ENOENT') return
|
|
25
|
+
throw error
|
|
26
|
+
}
|
|
27
|
+
throw new Error(OWN_ACCOUNT_BUSY)
|
|
28
|
+
}
|
|
29
|
+
export async function acquireOwnAccountLease(root, nonce) {
|
|
30
|
+
if (!nonceValid(nonce)) throw new Error('Invalid account lease')
|
|
31
|
+
await privateRoot(root)
|
|
32
|
+
const lock = join(root, '.lease')
|
|
33
|
+
const pending = join(root, `.lease-${nonce}.pending`)
|
|
34
|
+
await assertOwnAccountLeaseIdle(root)
|
|
35
|
+
await mkdir(pending, { mode: 0o700 })
|
|
36
|
+
try {
|
|
37
|
+
await writeFile(join(pending, 'owner.json'), JSON.stringify({ nonce, pid: process.pid }), {
|
|
38
|
+
flag: 'wx',
|
|
39
|
+
mode: 0o600,
|
|
40
|
+
})
|
|
41
|
+
// Publish a complete, nonempty owner directory in one filesystem operation.
|
|
42
|
+
// A killed initializer leaves only its nonce-specific pending directory.
|
|
43
|
+
await rename(pending, lock)
|
|
44
|
+
} catch (error) {
|
|
45
|
+
await rm(pending, { recursive: true, force: true })
|
|
46
|
+
if (error?.code === 'EEXIST' || error?.code === 'ENOTEMPTY') throw new Error(OWN_ACCOUNT_BUSY)
|
|
47
|
+
throw error
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export async function ownsOwnAccountLease(root, nonce) {
|
|
51
|
+
if (!nonceValid(nonce)) throw new Error('Invalid account lease')
|
|
52
|
+
await privateRoot(root)
|
|
53
|
+
let handle
|
|
54
|
+
try {
|
|
55
|
+
const lock = await lstat(join(root, '.lease'))
|
|
56
|
+
if (!lock.isDirectory() || lock.isSymbolicLink() || (process.platform !== 'win32' && (lock.mode & 0o077)))
|
|
57
|
+
throw new Error('账号使用状态无法确认')
|
|
58
|
+
handle = await open(
|
|
59
|
+
join(root, '.lease/owner.json'),
|
|
60
|
+
constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,
|
|
61
|
+
)
|
|
62
|
+
const info = await handle.stat()
|
|
63
|
+
if (!info.isFile() || info.nlink !== 1 || (process.platform !== 'win32' && (info.mode & 0o077)) || info.size > 1024)
|
|
64
|
+
throw new Error('账号使用状态无法确认')
|
|
65
|
+
return JSON.parse(await handle.readFile('utf8')).nonce === nonce
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error?.code === 'ENOENT') return false
|
|
68
|
+
throw error
|
|
69
|
+
} finally {
|
|
70
|
+
await handle?.close()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function releaseOwnAccountLease(root, nonce) {
|
|
74
|
+
if (!nonceValid(nonce)) throw new Error('Invalid account lease')
|
|
75
|
+
await privateRoot(root)
|
|
76
|
+
// Safe only at this API's contract boundary: Host confirmed this nonce's whole
|
|
77
|
+
// process range exited, including an initializer killed before publication.
|
|
78
|
+
await rm(join(root, `.lease-${nonce}.pending`), { recursive: true, force: true })
|
|
79
|
+
const lock = join(root, '.lease')
|
|
80
|
+
let handle
|
|
81
|
+
try {
|
|
82
|
+
const directory = await lstat(lock)
|
|
83
|
+
if (!directory.isDirectory() || directory.isSymbolicLink() || (process.platform !== 'win32' && (directory.mode & 0o077)))
|
|
84
|
+
throw new Error('账号使用状态无法安全清理')
|
|
85
|
+
handle = await open(
|
|
86
|
+
join(lock, 'owner.json'),
|
|
87
|
+
constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,
|
|
88
|
+
)
|
|
89
|
+
const info = await handle.stat()
|
|
90
|
+
if (!info.isFile() || info.nlink !== 1 || (process.platform !== 'win32' && (info.mode & 0o077)) || info.size > 1024)
|
|
91
|
+
throw new Error('账号使用状态无法安全清理')
|
|
92
|
+
const owner = JSON.parse(await handle.readFile('utf8'))
|
|
93
|
+
if (owner.nonce !== nonce) return
|
|
94
|
+
const current = await lstat(lock)
|
|
95
|
+
if (current.dev !== directory.dev || current.ino !== directory.ino || current.isSymbolicLink())
|
|
96
|
+
throw new Error('账号使用状态在清理前改变')
|
|
97
|
+
await handle.close()
|
|
98
|
+
handle = undefined
|
|
99
|
+
await rm(lock, { recursive: true })
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error?.code !== 'ENOENT') throw error
|
|
102
|
+
} finally {
|
|
103
|
+
await handle?.close()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// One verified Pi package for the Host, account UI, native catalog and RPC entry.
|
|
2
|
+
// Resolve installation metadata only; never execute an arbitrary shell launcher.
|
|
3
|
+
import { readFileSync, realpathSync, statSync } from 'node:fs'
|
|
4
|
+
import { createHash } from 'node:crypto'
|
|
5
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'
|
|
6
|
+
import { resolveNativeEntry } from './native-launch.mjs'
|
|
7
|
+
|
|
8
|
+
const versions = new Set(['1.0.2', '1.0.4', '1.1.0'])
|
|
9
|
+
const failure = () =>
|
|
10
|
+
Object.assign(
|
|
11
|
+
new Error('Pi 安装身份或原生接口不匹配;需要 Pi Coding Agent 1.0.2、1.0.4 或 1.1.0,不能使用 OMP 入口'),
|
|
12
|
+
{ code: 'CLI_IDENTITY_MISMATCH' },
|
|
13
|
+
)
|
|
14
|
+
function metadata(path) {
|
|
15
|
+
const info = statSync(path)
|
|
16
|
+
if (!info.isFile() || info.size > 128 * 1024) throw failure()
|
|
17
|
+
return readFileSync(path, 'utf8')
|
|
18
|
+
}
|
|
19
|
+
// Exact official Windows managed launcher inspected from Pi 1.1.0. It is read as
|
|
20
|
+
// installation metadata, never evaluated. Unknown bootstrap code fails closed.
|
|
21
|
+
const managedWindowsLauncherSHA256 = '3d8b27bb3f5c07543303b0ee774ce215e4d6ae2b0ae43311c4acf51f517ffd13'
|
|
22
|
+
function windowsManagedEntry(launcher) {
|
|
23
|
+
const source = metadata(launcher).trim().replace(/\r\n/g, '\n')
|
|
24
|
+
if (createHash('sha256').update(source).digest('hex') !== managedWindowsLauncherSHA256) throw failure()
|
|
25
|
+
const install = join(dirname(dirname(launcher)), 'install')
|
|
26
|
+
const version = metadata(join(install, 'current-version')).trim()
|
|
27
|
+
if (!versions.has(version)) throw failure()
|
|
28
|
+
const directory = resolve(install, 'releases', version, 'node_modules/@earendil-works/pi-coding-agent')
|
|
29
|
+
// A version pointer/package symlink must not select code outside this release.
|
|
30
|
+
if (realpathSync(directory) !== directory) throw failure()
|
|
31
|
+
const manifest = JSON.parse(metadata(join(directory, 'package.json')))
|
|
32
|
+
const bin = typeof manifest.bin === 'string' ? manifest.bin : manifest.bin?.pi
|
|
33
|
+
if (manifest.name !== '@earendil-works/pi-coding-agent' || manifest.version !== version ||
|
|
34
|
+
!['dist/cli.js', 'dist/bundle/cli.js'].includes(bin)) throw failure()
|
|
35
|
+
const entry = realpathSync(resolve(directory, bin))
|
|
36
|
+
const inside = relative(directory, entry)
|
|
37
|
+
if (!inside || inside === '..' || inside.startsWith('..' + sep) || isAbsolute(inside)) throw failure()
|
|
38
|
+
return entry
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function inspectPiInstallation(entry) {
|
|
42
|
+
try {
|
|
43
|
+
let executable = realpathSync(entry)
|
|
44
|
+
if (
|
|
45
|
+
['pi', 'pi.cmd', 'pi.bat'].includes(basename(executable).toLowerCase()) &&
|
|
46
|
+
basename(dirname(executable)) === 'bin'
|
|
47
|
+
) {
|
|
48
|
+
const launcher = metadata(executable)
|
|
49
|
+
if (launcher.includes('PI_MANAGED_INSTALL_ROOT=') && launcher.includes('install/current-version')) {
|
|
50
|
+
const install = join(dirname(dirname(executable)), 'install')
|
|
51
|
+
const version = metadata(join(install, 'current-version')).trim()
|
|
52
|
+
if (!versions.has(version)) throw failure()
|
|
53
|
+
executable = realpathSync(
|
|
54
|
+
join(install, 'releases', version, 'node_modules/@earendil-works/pi-coding-agent/dist/cli.js'),
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
executable = realpathSync(resolveNativeEntry(executable))
|
|
59
|
+
if (basename(executable).toLowerCase() === 'pi-launcher.js' && basename(dirname(executable)) === 'bin')
|
|
60
|
+
executable = windowsManagedEntry(executable)
|
|
61
|
+
let directory = dirname(executable)
|
|
62
|
+
for (let depth = 0; depth < 5; depth++, directory = dirname(directory)) {
|
|
63
|
+
let manifest
|
|
64
|
+
try {
|
|
65
|
+
manifest = JSON.parse(metadata(join(directory, 'package.json')))
|
|
66
|
+
} catch {
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
if (manifest.name !== '@earendil-works/pi-coding-agent' || !versions.has(manifest.version))
|
|
70
|
+
throw failure()
|
|
71
|
+
const dist = join(directory, 'dist')
|
|
72
|
+
if (![join(dist, 'cli.js'), join(dist, 'bundle/cli.js')].includes(executable)) throw failure()
|
|
73
|
+
for (const relative of ['cli.js', 'index.js', 'core/model-runtime.js', 'core/auth-storage.js']) {
|
|
74
|
+
if (!statSync(join(dist, relative)).isFile()) throw failure()
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
root: directory,
|
|
78
|
+
dist,
|
|
79
|
+
version: manifest.version,
|
|
80
|
+
executable: realpathSync(join(dist, 'cli.js')),
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
throw failure()
|
|
85
|
+
}
|
|
86
|
+
throw failure()
|
|
87
|
+
}
|