dsh-model 0.0.1 → 0.14.0
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.en.md +123 -0
- package/README.md +92 -43
- package/bin/dsh-model.js +8 -0
- package/dist/bridge/aggregate.js +91 -0
- package/dist/bridge/login.js +127 -0
- package/dist/bridge/runtime.js +136 -0
- package/dist/bridge/server.js +178 -0
- package/dist/bridge/workbuddy/_compat.js +52 -0
- package/dist/bridge/workbuddy/app-version.js +141 -0
- package/dist/bridge/workbuddy/auth.js +548 -0
- package/dist/bridge/workbuddy/catalog.js +154 -0
- package/dist/bridge/workbuddy/client-identity.js +234 -0
- package/dist/bridge/workbuddy/desktop-credential-protection.js +992 -0
- package/dist/bridge/workbuddy/loopback.js +52 -0
- package/dist/bridge/workbuddy/probe.js +153 -0
- package/dist/bridge/workbuddy/status-paths.js +49 -0
- package/dist/bridge/workbuddy/upstream.js +1180 -0
- package/dist/bridge/workbuddy/variants.js +101 -0
- package/dist/cli.js +207 -0
- package/dist/commands/bridge.js +68 -0
- package/dist/commands/connect.js +67 -0
- package/dist/commands/engine.js +122 -0
- package/dist/commands/key.js +75 -0
- package/dist/commands/login.js +113 -0
- package/dist/commands/logs.js +19 -0
- package/dist/commands/opencode.js +77 -0
- package/dist/commands/remote.js +129 -0
- package/dist/commands/service.js +72 -0
- package/dist/commands/setup.js +216 -0
- package/dist/commands/sources.js +196 -0
- package/dist/commands/status.js +216 -0
- package/dist/commands/uninstall.js +97 -0
- package/dist/commands/workbuddy.js +117 -0
- package/dist/context.js +86 -0
- package/dist/daemon/client.js +27 -0
- package/dist/daemon/core.js +790 -0
- package/dist/daemon/service.js +33 -0
- package/dist/daemon/stats.js +126 -0
- package/dist/daemon/usage.js +213 -0
- package/dist/dsh/cli.js +72 -0
- package/dist/dsh/connect.js +257 -0
- package/dist/dsh/credentials.js +55 -0
- package/dist/dsh/locate.js +129 -0
- package/dist/dsh/patch.js +106 -0
- package/dist/dsh/pick.js +59 -0
- package/dist/engine/auth.js +40 -0
- package/dist/engine/client.js +104 -0
- package/dist/engine/compat.js +94 -0
- package/dist/engine/config.js +47 -0
- package/dist/engine/install.js +118 -0
- package/dist/engine/mgmt.js +99 -0
- package/dist/engine/sourcemap.js +48 -0
- package/dist/errors.js +14 -0
- package/dist/i18n.js +39 -0
- package/dist/integrations/dshplugin.js +42 -0
- package/dist/integrations/opencode.js +101 -0
- package/dist/integrations/workbuddy.js +114 -0
- package/dist/keys.js +54 -0
- package/dist/ops.js +178 -0
- package/dist/remote/public.js +109 -0
- package/dist/secrets.js +13 -0
- package/dist/service/index.js +46 -0
- package/dist/service/launchd.js +89 -0
- package/dist/service/systemd.js +83 -0
- package/dist/sources.js +36 -0
- package/dist/state.js +90 -0
- package/dist/upstreams.js +23 -0
- package/dist/util/diff.js +30 -0
- package/dist/util/exec.js +42 -0
- package/dist/util/fs.js +107 -0
- package/dist/util/output.js +50 -0
- package/dist/util/pkg.js +13 -0
- package/dist/util/port.js +16 -0
- package/dist/util/prompt.js +40 -0
- package/dist/util/proxy.js +73 -0
- package/dist/util/redact.js +7 -0
- package/engine-manifest.json +28 -0
- package/package.json +77 -7
- package/plugin/client.js +549 -0
- package/plugin/cordis.patch.yml +4 -0
- package/plugin/index.js +177 -0
- package/docs/DESIGN.md +0 -610
package/dist/context.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// context.ts — 运行模式与所有路径
|
|
2
|
+
//
|
|
3
|
+
// local:普通用户在 Mac / Linux 上自用,状态在 ~/.dsh-model,服务是用户级的
|
|
4
|
+
// vps :检测到 dsh-vps(/opt/dsh-vps),需要 root;引擎以 dsh 用户运行,状态在 /home/dsh/.dsh-model
|
|
5
|
+
//
|
|
6
|
+
// 测试与特殊场景可用环境变量覆盖:DSH_MODEL_MODE、DSH_MODEL_HOME、DSH_HOME、DSH_MODEL_SERVICE=none
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { homedir } from 'node:os';
|
|
9
|
+
import { join, resolve } from 'node:path';
|
|
10
|
+
import { DshModelError } from './errors.js';
|
|
11
|
+
import { L } from './i18n.js';
|
|
12
|
+
import { run } from './util/exec.js';
|
|
13
|
+
export const VPS_ROOT = '/opt/dsh-vps';
|
|
14
|
+
export const VPS_USER = 'dsh';
|
|
15
|
+
export const VPS_USER_HOME = '/home/dsh';
|
|
16
|
+
export function detectMode(env = process.env, platform = process.platform) {
|
|
17
|
+
const forced = env.DSH_MODEL_MODE;
|
|
18
|
+
if (forced === 'local' || forced === 'vps')
|
|
19
|
+
return forced;
|
|
20
|
+
return platform === 'linux' && existsSync(VPS_ROOT) ? 'vps' : 'local';
|
|
21
|
+
}
|
|
22
|
+
export function makePaths(home) {
|
|
23
|
+
const engineDir = join(home, 'engine');
|
|
24
|
+
const auth = join(home, 'auth');
|
|
25
|
+
return {
|
|
26
|
+
home,
|
|
27
|
+
config: join(home, 'config.json'),
|
|
28
|
+
state: join(home, 'state.json'),
|
|
29
|
+
keys: join(home, 'keys.json'),
|
|
30
|
+
engineYaml: join(home, 'engine.yaml'),
|
|
31
|
+
engineDir,
|
|
32
|
+
versionsDir: join(engineDir, 'versions'),
|
|
33
|
+
current: join(engineDir, 'current'),
|
|
34
|
+
auth,
|
|
35
|
+
replaced: join(auth, '.replaced'),
|
|
36
|
+
backups: join(home, 'backups'),
|
|
37
|
+
logs: join(auth, 'logs'), // 引擎把日志写在 auth-dir/logs 下(实测 v8.0.13)
|
|
38
|
+
tmp: join(home, 'tmp'),
|
|
39
|
+
lock: join(home, '.lock'),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function createContext(env = process.env) {
|
|
43
|
+
const platform = process.platform;
|
|
44
|
+
if (platform !== 'darwin' && platform !== 'linux') {
|
|
45
|
+
throw new DshModelError('unsupported_platform', L(`暂不支持这个平台:${platform}(只支持 macOS 和 Linux)`, `Unsupported platform: ${platform} (macOS and Linux only)`));
|
|
46
|
+
}
|
|
47
|
+
const mode = detectMode(env, platform);
|
|
48
|
+
const isRoot = typeof process.getuid === 'function' && process.getuid() === 0;
|
|
49
|
+
const serviceDisabled = env.DSH_MODEL_SERVICE === 'none';
|
|
50
|
+
if (mode === 'vps') {
|
|
51
|
+
const home = env.DSH_MODEL_HOME ? resolve(env.DSH_MODEL_HOME) : join(VPS_USER_HOME, '.dsh-model');
|
|
52
|
+
return {
|
|
53
|
+
mode,
|
|
54
|
+
platform,
|
|
55
|
+
paths: makePaths(home),
|
|
56
|
+
owner: await lookupOwner(VPS_USER),
|
|
57
|
+
runAs: VPS_USER,
|
|
58
|
+
dshHome: env.DSH_HOME ? resolve(env.DSH_HOME) : join(VPS_USER_HOME, '.dsh'),
|
|
59
|
+
isRoot,
|
|
60
|
+
serviceDisabled,
|
|
61
|
+
env,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const home = env.DSH_MODEL_HOME ? resolve(env.DSH_MODEL_HOME) : join(homedir(), '.dsh-model');
|
|
65
|
+
return {
|
|
66
|
+
mode,
|
|
67
|
+
platform,
|
|
68
|
+
paths: makePaths(home),
|
|
69
|
+
dshHome: env.DSH_HOME ? resolve(env.DSH_HOME) : join(homedir(), '.dsh'),
|
|
70
|
+
isRoot,
|
|
71
|
+
serviceDisabled,
|
|
72
|
+
env,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** vps 模式下要改系统服务 / Caddy,必须 root */
|
|
76
|
+
export function requireRootInVps(ctx) {
|
|
77
|
+
if (ctx.mode === 'vps' && !ctx.isRoot && !ctx.serviceDisabled) {
|
|
78
|
+
throw new DshModelError('need_root', L('检测到 dsh-vps,这台机器按 VPS 模式运行,需要 root。', 'dsh-vps detected: running in VPS mode, which needs root.'), L('请用 sudo 重新执行,例如:sudo dsh-model setup', 'Re-run with sudo, e.g. sudo dsh-model setup'));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function lookupOwner(user) {
|
|
82
|
+
const [u, g] = await Promise.all([run('id', ['-u', user]), run('id', ['-g', user])]);
|
|
83
|
+
if (u.code !== 0 || g.code !== 0)
|
|
84
|
+
return undefined;
|
|
85
|
+
return { uid: Number(u.stdout.trim()), gid: Number(g.stdout.trim()) };
|
|
86
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// daemon/client.ts — 调守护进程 /control/*(CLI 用;dsh 插件宿主端也照这个格式调)
|
|
2
|
+
import { loadBridgeConfig } from '../bridge/runtime.js';
|
|
3
|
+
import { DshModelError } from '../errors.js';
|
|
4
|
+
import { L } from '../i18n.js';
|
|
5
|
+
export async function control(ctx, method, path, body, timeoutMs = 60_000) {
|
|
6
|
+
const cfg = await loadBridgeConfig(ctx.paths.home);
|
|
7
|
+
if (!cfg)
|
|
8
|
+
throw new DshModelError('daemon_not_configured', L('守护进程未配置(dsh-model setup)', 'Daemon not configured (dsh-model setup)'));
|
|
9
|
+
let res;
|
|
10
|
+
try {
|
|
11
|
+
res = await fetch(`http://127.0.0.1:${cfg.port}/control${path}`, {
|
|
12
|
+
method,
|
|
13
|
+
headers: { Authorization: `Bearer ${cfg.secret}`, ...(body !== undefined ? { 'Content-Type': 'application/json' } : {}) },
|
|
14
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
15
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new DshModelError('daemon_unreachable', L(`守护进程没在 127.0.0.1:${cfg.port} 上运行`, `Daemon is not running on 127.0.0.1:${cfg.port}`), L('执行 dsh-model repair', 'Run dsh-model repair'));
|
|
20
|
+
}
|
|
21
|
+
const data = (await res.json().catch(() => ({})));
|
|
22
|
+
if (!res.ok || data.error) {
|
|
23
|
+
const e = data.error ?? { code: 'daemon_error', message: `HTTP ${res.status}` };
|
|
24
|
+
throw new DshModelError(e.code, e.message, e.hint);
|
|
25
|
+
}
|
|
26
|
+
return data;
|
|
27
|
+
}
|