@ran-sh/dsh-crew 2.2.4 → 2.2.6
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.
|
@@ -80,6 +80,7 @@ const T = {
|
|
|
80
80
|
openDiag: "打开诊断",
|
|
81
81
|
crew: "Crew",
|
|
82
82
|
enabled: "启用子 Agent",
|
|
83
|
+
frontendAutostart: "登录时启动 3080 前端(不打开浏览器)",
|
|
83
84
|
flash: "Worker / Flash",
|
|
84
85
|
pro: "Reviewer / Pro",
|
|
85
86
|
addModel: "+ 添加模型",
|
|
@@ -107,6 +108,7 @@ const T = {
|
|
|
107
108
|
openDiag: "Open diagnostics",
|
|
108
109
|
crew: "Crew",
|
|
109
110
|
enabled: "Enable sub-agents",
|
|
111
|
+
frontendAutostart: "Start the 3080 frontend at login (no browser)",
|
|
110
112
|
flash: "Worker / Flash",
|
|
111
113
|
pro: "Reviewer / Pro",
|
|
112
114
|
addModel: "+ Add model",
|
|
@@ -439,19 +441,32 @@ function QuickPanel({ ctx }) {
|
|
|
439
441
|
}),
|
|
440
442
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
441
443
|
className: "crew-quick-row crew-quick-master",
|
|
442
|
-
children: [
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
447
|
-
type: "checkbox",
|
|
448
|
-
disabled: busy,
|
|
449
|
-
checked: config.subagents_enabled !== false,
|
|
450
|
-
onChange: (e) => toggle("subagents_enabled", e.target.checked)
|
|
444
|
+
children: [
|
|
445
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
446
|
+
className: "crew-quick-section",
|
|
447
|
+
children: t.crew
|
|
451
448
|
}),
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
449
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
|
|
450
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
451
|
+
type: "checkbox",
|
|
452
|
+
disabled: busy,
|
|
453
|
+
checked: config.subagents_enabled !== false,
|
|
454
|
+
onChange: (e) => toggle("subagents_enabled", e.target.checked)
|
|
455
|
+
}),
|
|
456
|
+
" ",
|
|
457
|
+
t.enabled
|
|
458
|
+
] }),
|
|
459
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
|
|
460
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
461
|
+
type: "checkbox",
|
|
462
|
+
disabled: busy,
|
|
463
|
+
checked: config.frontend_autostart === true,
|
|
464
|
+
onChange: (e) => toggle("frontend_autostart", e.target.checked)
|
|
465
|
+
}),
|
|
466
|
+
" ",
|
|
467
|
+
t.frontendAutostart
|
|
468
|
+
] })
|
|
469
|
+
]
|
|
455
470
|
}),
|
|
456
471
|
modelList("flash_model_priority", t.flash),
|
|
457
472
|
modelList("pro_model_priority", t.pro),
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ const FULL = 'http://127.0.0.1:3210/_dsh/dsh-crew/control-plane';
|
|
|
19
19
|
type ModelEntry = { provider: string; model: string };
|
|
20
20
|
type QuickConfig = {
|
|
21
21
|
subagents_enabled?: boolean;
|
|
22
|
+
frontend_autostart?: boolean;
|
|
22
23
|
flash_model_priority?: ModelEntry[];
|
|
23
24
|
pro_model_priority?: ModelEntry[];
|
|
24
25
|
};
|
|
@@ -41,6 +42,7 @@ const T = {
|
|
|
41
42
|
openDiag: '打开诊断',
|
|
42
43
|
crew: 'Crew',
|
|
43
44
|
enabled: '启用子 Agent',
|
|
45
|
+
frontendAutostart: '登录时启动 3080 前端(不打开浏览器)',
|
|
44
46
|
flash: 'Worker / Flash',
|
|
45
47
|
pro: 'Reviewer / Pro',
|
|
46
48
|
addModel: '+ 添加模型',
|
|
@@ -66,6 +68,7 @@ const T = {
|
|
|
66
68
|
openDiag: 'Open diagnostics',
|
|
67
69
|
crew: 'Crew',
|
|
68
70
|
enabled: 'Enable sub-agents',
|
|
71
|
+
frontendAutostart: 'Start the 3080 frontend at login (no browser)',
|
|
69
72
|
flash: 'Worker / Flash',
|
|
70
73
|
pro: 'Reviewer / Pro',
|
|
71
74
|
addModel: '+ Add model',
|
|
@@ -157,7 +160,7 @@ export function QuickPanel({ ctx }: { ctx: any }) {
|
|
|
157
160
|
} finally { setBusy(false); }
|
|
158
161
|
}, [t]);
|
|
159
162
|
|
|
160
|
-
const toggle = (key: 'subagents_enabled', value: boolean) => {
|
|
163
|
+
const toggle = (key: 'subagents_enabled' | 'frontend_autostart', value: boolean) => {
|
|
161
164
|
setConfig((c) => ({ ...(c ?? {}), [key]: value }));
|
|
162
165
|
void patch({ [key]: value } as QuickConfig);
|
|
163
166
|
};
|
|
@@ -251,6 +254,8 @@ export function QuickPanel({ ctx }: { ctx: any }) {
|
|
|
251
254
|
<span className="crew-quick-section">{t.crew}</span>
|
|
252
255
|
<label><input type="checkbox" disabled={busy} checked={config.subagents_enabled !== false}
|
|
253
256
|
onChange={(e) => toggle('subagents_enabled', e.target.checked)} /> {t.enabled}</label>
|
|
257
|
+
<label><input type="checkbox" disabled={busy} checked={config.frontend_autostart === true}
|
|
258
|
+
onChange={(e) => toggle('frontend_autostart', e.target.checked)} /> {t.frontendAutostart}</label>
|
|
254
259
|
</div>
|
|
255
260
|
{modelList('flash_model_priority', t.flash)}
|
|
256
261
|
{modelList('pro_model_priority', t.pro)}
|
package/src/hub/index.mjs
CHANGED
|
@@ -114,6 +114,7 @@ const ROUTE_BASE = '/_dsh/dsh-crew';
|
|
|
114
114
|
// canonical authority; quick-config is a projection, never a second store.
|
|
115
115
|
export const QUICK_CONFIG_KEYS = Object.freeze([
|
|
116
116
|
'subagents_enabled',
|
|
117
|
+
'frontend_autostart',
|
|
117
118
|
'flash_model_priority',
|
|
118
119
|
'pro_model_priority',
|
|
119
120
|
]);
|
|
@@ -14,6 +14,15 @@ function plan(home, root) {
|
|
|
14
14
|
['official-web-bridge/lib/client.js', readFileSync(join(bridge, 'lib', 'client.js'))],
|
|
15
15
|
['src/local-request-guard.mjs', readFileSync(join(root, 'src', 'local-request-guard.mjs'))],
|
|
16
16
|
]);
|
|
17
|
+
// The snapshot is a canonical artifact: these sources are text that either line
|
|
18
|
+
// ending serves, so its bytes and its revision both normalize to LF. Otherwise a
|
|
19
|
+
// `core.autocrlf=true` checkout hashes to a different revision than the npm
|
|
20
|
+
// payload it installs, which made readiness look for a snapshot that does not
|
|
21
|
+
// exist and reported "needs repair" on a correct install (and made every payload
|
|
22
|
+
// update look like a stale desktop revision).
|
|
23
|
+
const canonicalBytes = (bytes) => (bytes.includes(0) ? bytes
|
|
24
|
+
: Buffer.from(bytes.toString('utf8').replace(/\r\n/g, '\n'), 'utf8'));
|
|
25
|
+
for (const [name, bytes] of files) files.set(name, canonicalBytes(bytes));
|
|
17
26
|
const hash = createHash('sha256').update(JSON.stringify(metadata));
|
|
18
27
|
for (const [name, bytes] of files) hash.update(name).update(bytes);
|
|
19
28
|
const revision = hash.digest('hex');
|
|
@@ -30,17 +39,29 @@ function plan(home, root) {
|
|
|
30
39
|
return { frontendRoot, snapshotRoot, revision, overlayFile, overlay, files };
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
// Git checks a `core.autocrlf=true` Windows tree out as CRLF while the installed
|
|
43
|
+
// snapshot was written from the npm payload (LF). The bridge sources are text that
|
|
44
|
+
// either line ending serves, so a CRLF checkout must not read as a drifted snapshot;
|
|
45
|
+
// bytes are still compared first, and the tolerant path only applies to text.
|
|
46
|
+
function sameTextContent(installed, expected) {
|
|
47
|
+
if (installed.equals(expected)) return true;
|
|
48
|
+
if (installed.includes(0) || expected.includes(0)) return false;
|
|
49
|
+
const normalize = (buffer) => buffer.toString('utf8').replace(/\r\n/g, '\n');
|
|
50
|
+
return normalize(installed) === normalize(expected);
|
|
51
|
+
}
|
|
52
|
+
|
|
33
53
|
function matches(p) {
|
|
34
54
|
try { return [...p.files].every(([name, bytes]) => {
|
|
35
55
|
const file = join(p.snapshotRoot, name);
|
|
36
|
-
return lstatSync(file).isFile() && !lstatSync(file).isSymbolicLink() && readFileSync(file)
|
|
56
|
+
return lstatSync(file).isFile() && !lstatSync(file).isSymbolicLink() && sameTextContent(readFileSync(file), bytes);
|
|
37
57
|
}); } catch { return false; }
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
export function officialFrontendAssetsReady({ home = homedir(), root } = {}) {
|
|
41
61
|
try {
|
|
42
62
|
const p = plan(home, root);
|
|
43
|
-
|
|
63
|
+
const overlay = readFileSync(p.overlayFile, 'utf8');
|
|
64
|
+
return matches(p) && (overlay === p.overlay || overlay.replace(/\r\n/g, '\n') === p.overlay.replace(/\r\n/g, '\n'));
|
|
44
65
|
} catch { return false; }
|
|
45
66
|
}
|
|
46
67
|
|
package/src/runtime-identity.mjs
CHANGED
|
@@ -36,7 +36,7 @@ export {
|
|
|
36
36
|
// included in the identity contract.
|
|
37
37
|
const RUNTIME_ID = randomUUID();
|
|
38
38
|
|
|
39
|
-
export const RUNTIME_VERSION = '2.2.
|
|
39
|
+
export const RUNTIME_VERSION = '2.2.6';
|
|
40
40
|
export const HUB_PROTOCOL_VERSION = 1;
|
|
41
41
|
|
|
42
42
|
export const HUB_CAPABILITIES = Object.freeze([
|