dsh-zen-remote 2.3.11 → 2.4.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/CHANGELOG.md +39 -78
- package/README.md +94 -84
- package/README.zh-CN.md +90 -81
- package/bin/zen-remote.mjs +5 -0
- package/docs/interface.md +6 -6
- package/docs/remote-access.en.md +6 -4
- package/docs/remote-access.md +6 -4
- package/dsh-push.mjs +96 -10
- package/lib/adapters/dsh-better-sidebar/index.js +7 -3
- package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
- package/lib/admin-routes.js +10 -2
- package/lib/admin-routes.js.map +1 -1
- package/lib/cli/args.js +251 -0
- package/lib/cli/args.js.map +1 -0
- package/lib/cli/bootstrap.js +449 -0
- package/lib/cli/bootstrap.js.map +1 -0
- package/lib/cli/command-setup.js +484 -0
- package/lib/cli/command-setup.js.map +1 -0
- package/lib/cli/commands-client.js +359 -0
- package/lib/cli/commands-client.js.map +1 -0
- package/lib/cli/commands-host.js +1108 -0
- package/lib/cli/commands-host.js.map +1 -0
- package/lib/cli/commands-status.js +279 -0
- package/lib/cli/commands-status.js.map +1 -0
- package/lib/cli/config-writer.js +334 -0
- package/lib/cli/config-writer.js.map +1 -0
- package/lib/cli/context.js +10 -0
- package/lib/cli/context.js.map +1 -0
- package/lib/cli/i18n.js +620 -0
- package/lib/cli/i18n.js.map +1 -0
- package/lib/cli/ipc-client.js +160 -0
- package/lib/cli/ipc-client.js.map +1 -0
- package/lib/cli/ipc-server.js +464 -0
- package/lib/cli/ipc-server.js.map +1 -0
- package/lib/cli/main.js +245 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/cli/qr-terminal.js +48 -0
- package/lib/cli/qr-terminal.js.map +1 -0
- package/lib/client-data/qr.js +286 -0
- package/lib/client-data/qr.js.map +1 -0
- package/lib/client-routes.js +308 -25
- package/lib/client-routes.js.map +1 -1
- package/lib/client.js +1013 -229
- package/lib/config.js +50 -12
- package/lib/config.js.map +1 -1
- package/lib/debug-report.js +28 -1
- package/lib/debug-report.js.map +1 -1
- package/lib/fetch-route-intercept.js +334 -26
- package/lib/fetch-route-intercept.js.map +1 -1
- package/lib/index.js +564 -363
- package/lib/index.js.map +1 -1
- package/lib/intercept.js +1833 -280
- package/lib/intercept.js.map +1 -1
- package/lib/lan-gate-server.cjs +36 -10
- package/lib/merge-streams.js +103 -11
- package/lib/merge-streams.js.map +1 -1
- package/lib/plugin-route-intercept.js +93 -63
- package/lib/plugin-route-intercept.js.map +1 -1
- package/lib/relay-access.js +8 -1
- package/lib/relay-access.js.map +1 -1
- package/lib/relay-client.js +133 -4
- package/lib/relay-client.js.map +1 -1
- package/lib/relay-pool.js +275 -0
- package/lib/relay-pool.js.map +1 -0
- package/lib/relay-server.js +269 -17
- package/lib/relay-server.js.map +1 -1
- package/lib/restart-fields.js +6 -4
- package/lib/restart-fields.js.map +1 -1
- package/lib/share-store.js +65 -27
- package/lib/share-store.js.map +1 -1
- package/lib/state-store.js +400 -0
- package/lib/state-store.js.map +1 -0
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts +3 -2
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
- package/lib/types/admin-routes.d.ts.map +1 -1
- package/lib/types/cli/args.d.ts +78 -0
- package/lib/types/cli/args.d.ts.map +1 -0
- package/lib/types/cli/bootstrap.d.ts +170 -0
- package/lib/types/cli/bootstrap.d.ts.map +1 -0
- package/lib/types/cli/command-setup.d.ts +72 -0
- package/lib/types/cli/command-setup.d.ts.map +1 -0
- package/lib/types/cli/commands-client.d.ts +36 -0
- package/lib/types/cli/commands-client.d.ts.map +1 -0
- package/lib/types/cli/commands-host.d.ts +82 -0
- package/lib/types/cli/commands-host.d.ts.map +1 -0
- package/lib/types/cli/commands-status.d.ts +46 -0
- package/lib/types/cli/commands-status.d.ts.map +1 -0
- package/lib/types/cli/config-writer.d.ts +92 -0
- package/lib/types/cli/config-writer.d.ts.map +1 -0
- package/lib/types/cli/context.d.ts +39 -0
- package/lib/types/cli/context.d.ts.map +1 -0
- package/lib/types/cli/i18n.d.ts +32 -0
- package/lib/types/cli/i18n.d.ts.map +1 -0
- package/lib/types/cli/ipc-client.d.ts +83 -0
- package/lib/types/cli/ipc-client.d.ts.map +1 -0
- package/lib/types/cli/ipc-server.d.ts +113 -0
- package/lib/types/cli/ipc-server.d.ts.map +1 -0
- package/lib/types/cli/main.d.ts +57 -0
- package/lib/types/cli/main.d.ts.map +1 -0
- package/lib/types/cli/qr-terminal.d.ts +17 -0
- package/lib/types/cli/qr-terminal.d.ts.map +1 -0
- package/lib/types/client/RemoteStatusIcon.d.ts.map +1 -1
- package/lib/types/client/current-session-report.d.ts +4 -0
- package/lib/types/client/current-session-report.d.ts.map +1 -1
- package/lib/types/client/effects/model-group-side.d.ts.map +1 -1
- package/lib/types/client/effects/remote-session.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +47 -3
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/settings/SettingsSection.d.ts.map +1 -1
- package/lib/types/client/settings/settings-css.d.ts +1 -1
- package/lib/types/client/settings/settings-css.d.ts.map +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts +1 -1
- package/lib/types/client/styles/remote-session.css.d.ts.map +1 -1
- package/lib/types/client/wizard/GatewayWizard.d.ts.map +1 -1
- package/lib/types/client/wizard/cards/ProxyCard.d.ts.map +1 -1
- package/lib/types/client/wizard/wizard-css.d.ts +1 -1
- package/lib/types/client/wizard/wizard-css.d.ts.map +1 -1
- package/lib/types/client-data/model-group-side.d.ts +23 -2
- package/lib/types/client-data/model-group-side.d.ts.map +1 -1
- package/lib/types/client-data/remote-status.d.ts +47 -1
- package/lib/types/client-data/remote-status.d.ts.map +1 -1
- package/lib/types/client-data/settings-form.d.ts +85 -1
- package/lib/types/client-data/settings-form.d.ts.map +1 -1
- package/lib/types/client-data/wizard.d.ts +56 -1
- package/lib/types/client-data/wizard.d.ts.map +1 -1
- package/lib/types/client-routes.d.ts +25 -1
- package/lib/types/client-routes.d.ts.map +1 -1
- package/lib/types/config.d.ts +40 -14
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/debug-report.d.ts.map +1 -1
- package/lib/types/fetch-route-intercept.d.ts +66 -8
- package/lib/types/fetch-route-intercept.d.ts.map +1 -1
- package/lib/types/index.d.ts +9 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/intercept.d.ts +72 -10
- package/lib/types/intercept.d.ts.map +1 -1
- package/lib/types/merge-streams.d.ts +79 -1
- package/lib/types/merge-streams.d.ts.map +1 -1
- package/lib/types/plugin-route-intercept.d.ts +25 -9
- package/lib/types/plugin-route-intercept.d.ts.map +1 -1
- package/lib/types/relay-access.d.ts +3 -1
- package/lib/types/relay-access.d.ts.map +1 -1
- package/lib/types/relay-client.d.ts +23 -2
- package/lib/types/relay-client.d.ts.map +1 -1
- package/lib/types/relay-pool.d.ts +148 -0
- package/lib/types/relay-pool.d.ts.map +1 -0
- package/lib/types/relay-server.d.ts +30 -3
- package/lib/types/relay-server.d.ts.map +1 -1
- package/lib/types/restart-fields.d.ts +5 -5
- package/lib/types/restart-fields.d.ts.map +1 -1
- package/lib/types/share-store.d.ts.map +1 -1
- package/lib/types/state-store.d.ts +179 -0
- package/lib/types/state-store.d.ts.map +1 -0
- package/lib/types/upload-limits.d.ts +15 -0
- package/lib/types/upload-limits.d.ts.map +1 -1
- package/lib/types/virtual-id.d.ts +21 -0
- package/lib/types/virtual-id.d.ts.map +1 -1
- package/lib/types/wizard/probe.d.ts.map +1 -1
- package/lib/types/wizard/proxy-snippets.d.ts +3 -0
- package/lib/types/wizard/proxy-snippets.d.ts.map +1 -1
- package/lib/types/wizard/routes.d.ts +1 -0
- package/lib/types/wizard/routes.d.ts.map +1 -1
- package/lib/types/wizard/status.d.ts +9 -0
- package/lib/types/wizard/status.d.ts.map +1 -1
- package/lib/types/wizard/verify.d.ts +3 -0
- package/lib/types/wizard/verify.d.ts.map +1 -1
- package/lib/upload-limits.js +15 -0
- package/lib/upload-limits.js.map +1 -1
- package/lib/virtual-id.js +60 -0
- package/lib/virtual-id.js.map +1 -1
- package/lib/wizard/probe.js +46 -1
- package/lib/wizard/probe.js.map +1 -1
- package/lib/wizard/proxy-snippets.js +14 -1
- package/lib/wizard/proxy-snippets.js.map +1 -1
- package/lib/wizard/routes.js +23 -4
- package/lib/wizard/routes.js.map +1 -1
- package/lib/wizard/status.js +21 -0
- package/lib/wizard/status.js.map +1 -1
- package/lib/wizard/verify.js +31 -8
- package/lib/wizard/verify.js.map +1 -1
- package/package.json +8 -4
- package/pwa/icons/badge-96.png +0 -0
- package/pwa/icons/badge.svg +1 -0
- package/pwa/manifest.json +2 -1
- package/pwa/sw.js +3 -1
- package/scripts/check-debug-report.mjs +41 -1
- package/scripts/check-settings-form.mjs +14 -3
- package/scripts/check-settings-view.mjs +247 -0
- package/scripts/check-wizard-ui.mjs +37 -0
- package/src/adapters/dsh-better-sidebar/index.ts +7 -3
- package/src/admin-routes.ts +10 -2
- package/src/cli/args.ts +289 -0
- package/src/cli/bootstrap.ts +569 -0
- package/src/cli/command-setup.ts +540 -0
- package/src/cli/commands-client.ts +369 -0
- package/src/cli/commands-host.ts +1127 -0
- package/src/cli/commands-status.ts +296 -0
- package/src/cli/config-writer.ts +354 -0
- package/src/cli/context.ts +38 -0
- package/src/cli/i18n.ts +645 -0
- package/src/cli/ipc-client.ts +216 -0
- package/src/cli/ipc-server.ts +531 -0
- package/src/cli/main.ts +285 -0
- package/src/cli/qr-terminal.ts +49 -0
- package/src/client/RemoteStatusIcon.tsx +4 -1
- package/src/client/current-session-report.ts +28 -4
- package/src/client/effects/model-group-side.ts +19 -5
- package/src/client/effects/remote-session.ts +26 -6
- package/src/client/locales.ts +96 -6
- package/src/client/settings/SettingsSection.tsx +287 -92
- package/src/client/settings/settings-css.ts +18 -0
- package/src/client/styles/remote-session.css.ts +15 -1
- package/src/client/wizard/GatewayWizard.tsx +470 -109
- package/src/client/wizard/cards/ProxyCard.tsx +2 -1
- package/src/client/wizard/wizard-css.ts +23 -0
- package/src/client-data/model-group-side.ts +37 -10
- package/src/client-data/remote-status.ts +112 -17
- package/src/client-data/settings-form.ts +164 -8
- package/src/client-data/wizard.ts +112 -2
- package/src/client-routes.ts +334 -26
- package/src/config.ts +62 -16
- package/src/debug-report.ts +27 -1
- package/src/fetch-route-intercept.ts +381 -32
- package/src/index.ts +566 -367
- package/src/intercept.ts +1866 -286
- package/src/merge-streams.ts +155 -10
- package/src/plugin-route-intercept.ts +120 -71
- package/src/relay-access.ts +14 -3
- package/src/relay-client.ts +163 -5
- package/src/relay-pool.ts +387 -0
- package/src/relay-server.ts +312 -16
- package/src/restart-fields.ts +6 -4
- package/src/share-store.ts +59 -26
- package/src/state-store.ts +428 -0
- package/src/upload-limits.ts +16 -0
- package/src/virtual-id.ts +57 -0
- package/src/wizard/probe.ts +54 -2
- package/src/wizard/proxy-snippets.ts +17 -2
- package/src/wizard/routes.ts +24 -5
- package/src/wizard/status.ts +28 -0
- package/src/wizard/verify.ts +33 -11
- package/AGENTS.md +0 -185
- package/docs/adr/0001-plugin-bridge-forwards-plugin-routes.md +0 -15
- package/docs/adr/0002-relay-emulates-websocket.md +0 -8
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CLI's anti-shadowing config writer (CLI-1).
|
|
3
|
+
*
|
|
4
|
+
* `resolveConfig` reads four layers in the order env > row > file > default
|
|
5
|
+
* (src/config.ts). A CLI write lands in the FILE layer
|
|
6
|
+
* (`<dshHome>/lan-gate.config.json`), so two layers can silently swallow it:
|
|
7
|
+
* an environment variable set at the top, and a value the loader put on the
|
|
8
|
+
* plugin row (persisted in the current profile's `cordis.patch.yml`). The
|
|
9
|
+
* writer refuses the first case with the exact variable name, and REMOVES the
|
|
10
|
+
* shadowing keys in the other two — the in-memory row object `apply()` still
|
|
11
|
+
* holds, and the `dsh-zen-remote` `config:` block of every profile patch file
|
|
12
|
+
* it can find — so the just-written file value is what the next
|
|
13
|
+
* `resolveConfig` answers. `onAfterWrite` then lets the caller (the IPC
|
|
14
|
+
* delegate in src/index.ts) trigger the restart watcher immediately, so a
|
|
15
|
+
* restart-required field reloads the row without waiting out the 2s poll.
|
|
16
|
+
*
|
|
17
|
+
* The file is read from `dshHome` DIRECTLY, not through `readFileConfig(env)`:
|
|
18
|
+
* the latter resolves `<env.DSH_HOME ?? ~/.dsh>` and would silently read the
|
|
19
|
+
* developer's real file when a test passes an explicit dshHome with an empty
|
|
20
|
+
* env — resolution and the write must never disagree about which file is the
|
|
21
|
+
* truth.
|
|
22
|
+
*
|
|
23
|
+
* The `cordis.patch.yml` edit is line-based on purpose: the files are
|
|
24
|
+
* user-owned YAML full of comments and hand-tuned formatting that a
|
|
25
|
+
* parse-serialize round trip would destroy, and the edit itself (delete a
|
|
26
|
+
* key line and its indented children from one plugin's config block) is a
|
|
27
|
+
* purely textual operation.
|
|
28
|
+
*/
|
|
29
|
+
import { chmodSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from 'node:fs';
|
|
30
|
+
import { join } from 'node:path';
|
|
31
|
+
import { resolveConfig } from '../config.js';
|
|
32
|
+
/**
|
|
33
|
+
* The env variable each config field answers to, for fields that HAVE one.
|
|
34
|
+
* Fields without an entry (role, serverName, idleHours, the wizard's ingress
|
|
35
|
+
* fields, pluginBridgeConsent — src/config.ts explains each absence) can
|
|
36
|
+
* never be env-shadowed, so they are deliberately missing: `writeCliConfig`
|
|
37
|
+
* falls back to the field name itself when asked for one.
|
|
38
|
+
*/
|
|
39
|
+
export const ENV_VAR_BY_FIELD = {
|
|
40
|
+
port: 'LAN_GATE_PORT',
|
|
41
|
+
host: 'LAN_GATE_HOST',
|
|
42
|
+
targetPort: 'LAN_GATE_TARGET_PORT',
|
|
43
|
+
rateLimit: 'LAN_GATE_RATE_LIMIT',
|
|
44
|
+
trustedProxies: 'LAN_GATE_TRUSTED_PROXIES',
|
|
45
|
+
vapidSubject: 'LAN_GATE_VAPID_SUBJECT',
|
|
46
|
+
lang: 'LAN_GATE_LANG',
|
|
47
|
+
pushEvents: 'DSH_PUSH_EVENTS',
|
|
48
|
+
pushDebounceMs: 'DSH_PUSH_DEBOUNCE_MS',
|
|
49
|
+
pushSummary: 'DSH_PUSH_SUMMARY',
|
|
50
|
+
pushTurnEnd: 'DSH_PUSH_TURN_END',
|
|
51
|
+
pushTool: 'DSH_PUSH_TOOL',
|
|
52
|
+
pushEnabled: 'DSH_PUSH_ENABLED',
|
|
53
|
+
pushSessionName: 'DSH_PUSH_SESSION_NAME',
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Keys that CLI explicitly wrote to `lan-gate.config.json` and unshadowed in
|
|
57
|
+
* `cordis.patch.yml` during this process lifetime, keyed by `dshHome`. When
|
|
58
|
+
* `fiber.restart()` reloads the plugin row, `cordis-plugin-loader` re-hydrates
|
|
59
|
+
* the new `config` object from its in-memory patch snapshot (without
|
|
60
|
+
* re-reading `cordis.patch.yml` from disk), which would otherwise re-shadow
|
|
61
|
+
* the file layer with stale `{ get() }` wrappers. `applyUnshadowedRowKeys`
|
|
62
|
+
* strips those stale wrappers on the reloaded `apply()`, and a subsequent
|
|
63
|
+
* Web UI save (`loader/volatile-update`) clears them via
|
|
64
|
+
* `clearUnshadowedRowKeys`.
|
|
65
|
+
*/
|
|
66
|
+
const unshadowedByHome = new Map();
|
|
67
|
+
export function applyUnshadowedRowKeys(dshHome, row) {
|
|
68
|
+
if (row === undefined || row === null || typeof row !== 'object')
|
|
69
|
+
return;
|
|
70
|
+
const keys = unshadowedByHome.get(dshHome);
|
|
71
|
+
if (keys === undefined)
|
|
72
|
+
return;
|
|
73
|
+
for (const key of keys) {
|
|
74
|
+
const val = row[key];
|
|
75
|
+
if (val !== null && typeof val === 'object' && typeof val.get === 'function') {
|
|
76
|
+
delete row[key];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export function clearUnshadowedRowKeys(dshHome, keys) {
|
|
81
|
+
const set = unshadowedByHome.get(dshHome);
|
|
82
|
+
if (set === undefined)
|
|
83
|
+
return;
|
|
84
|
+
for (const key of keys)
|
|
85
|
+
set.delete(key);
|
|
86
|
+
}
|
|
87
|
+
/** Read `<dshHome>/lan-gate.config.json` — `{}` when absent or unparsable,
|
|
88
|
+
* the same degrade-not-throw contract as src/config.ts's readFileConfig. */
|
|
89
|
+
function readFileAt(dshHome) {
|
|
90
|
+
try {
|
|
91
|
+
const parsed = JSON.parse(readFileSync(join(dshHome, 'lan-gate.config.json'), 'utf8'));
|
|
92
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
93
|
+
return {};
|
|
94
|
+
return parsed;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Atomic 0600 rewrite: tmp + explicit chmod + rename, so a crash mid-write
|
|
101
|
+
* can never leave a half file behind (the discipline of the wizard's
|
|
102
|
+
* trust-proxy persister). */
|
|
103
|
+
function writeJsonAtomic(dshHome, body) {
|
|
104
|
+
const file = join(dshHome, 'lan-gate.config.json');
|
|
105
|
+
try {
|
|
106
|
+
mkdirSync(dshHome, { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
catch { /* an existing directory or an unwritable one — the write below reports it */ }
|
|
109
|
+
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
110
|
+
writeFileSync(tmp, `${JSON.stringify(body, null, 2)}\n`, { mode: 0o600 });
|
|
111
|
+
chmodSync(tmp, 0o600);
|
|
112
|
+
renameSync(tmp, file);
|
|
113
|
+
}
|
|
114
|
+
/** The candidate `cordis.patch.yml` paths: the named profile first (when
|
|
115
|
+
* given), then every profile's patch file found on disk — deduplicated, and
|
|
116
|
+
* only files that actually exist (the editor never CREATES one). */
|
|
117
|
+
function patchFileCandidates(dshHome, profileName) {
|
|
118
|
+
const out = [];
|
|
119
|
+
const push = (candidate) => {
|
|
120
|
+
if (!out.includes(candidate) && existsQuiet(candidate))
|
|
121
|
+
out.push(candidate);
|
|
122
|
+
};
|
|
123
|
+
if (profileName !== undefined && profileName !== '') {
|
|
124
|
+
push(join(dshHome, 'profiles', profileName, 'cordis.patch.yml'));
|
|
125
|
+
}
|
|
126
|
+
const profilesDir = join(dshHome, 'profiles');
|
|
127
|
+
try {
|
|
128
|
+
for (const entry of readdirSync(profilesDir, { withFileTypes: true })) {
|
|
129
|
+
if (!entry.isDirectory())
|
|
130
|
+
continue;
|
|
131
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('.') || entry.name === 'desktop')
|
|
132
|
+
continue;
|
|
133
|
+
push(join(profilesDir, entry.name, 'cordis.patch.yml'));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch { /* no profiles directory — nothing to scan */ }
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
function existsQuiet(path) {
|
|
140
|
+
try {
|
|
141
|
+
statSync(path);
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function leadingSpaces(line) {
|
|
149
|
+
const match = /^[ \t]*/u.exec(line);
|
|
150
|
+
return match === null ? 0 : match[0].length;
|
|
151
|
+
}
|
|
152
|
+
function escapeRegExp(text) {
|
|
153
|
+
return text.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Remove `keys` from EVERY `- id: dsh-zen-remote` (or bare `id:`) entry's
|
|
157
|
+
* `config:` block, purely textually: a key line and its deeper-indented
|
|
158
|
+
* children disappear, every other line — comments, other plugins' blocks,
|
|
159
|
+
* formatting — survives byte for byte. A block emptied by the removal keeps
|
|
160
|
+
* a `config: {}` line (an entry with no config key at all changes loader
|
|
161
|
+
* semantics). No match, no change: the same string comes back.
|
|
162
|
+
*/
|
|
163
|
+
export function unshadowPatchYml(text, keys) {
|
|
164
|
+
if (keys.length === 0)
|
|
165
|
+
return text;
|
|
166
|
+
const lines = text.split('\n');
|
|
167
|
+
const toDelete = new Set();
|
|
168
|
+
const toReplace = new Map();
|
|
169
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
170
|
+
// The id line: an optional dash + `id: dsh-zen-remote`, trailing comment
|
|
171
|
+
// allowed (`- id: agent-default-model # magpie` shows the shape). The
|
|
172
|
+
// id KEY's column is the prefix length — `config:` sits at that column.
|
|
173
|
+
const idMatch = /^([ \t]*(?:-[ \t]+)?)(id):[ \t]*dsh-zen-remote[ \t]*(?:#.*)?$/u.exec(lines[i]);
|
|
174
|
+
if (idMatch === null)
|
|
175
|
+
continue;
|
|
176
|
+
const keyIndent = idMatch[1].length;
|
|
177
|
+
// The entry's `config:` line: the first `config:` at the id column
|
|
178
|
+
// before the entry ends (a shallower line starts the next entry).
|
|
179
|
+
let configLine = -1;
|
|
180
|
+
let configIndent = -1;
|
|
181
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
182
|
+
const line = lines[j];
|
|
183
|
+
if (line.trim() === '')
|
|
184
|
+
continue;
|
|
185
|
+
const indent = leadingSpaces(line);
|
|
186
|
+
if (indent < keyIndent)
|
|
187
|
+
break;
|
|
188
|
+
if (indent === keyIndent && /^[ \t]*config[ \t]*:(\s|$|#)/u.test(line)) {
|
|
189
|
+
configLine = j;
|
|
190
|
+
configIndent = indent;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (configLine === -1)
|
|
195
|
+
continue;
|
|
196
|
+
// The config block: every following line deeper than the config column
|
|
197
|
+
// (blank lines skipped — they belong to no key). The shallowest indent
|
|
198
|
+
// inside the block is where its top-level keys sit.
|
|
199
|
+
let blockEnd = configLine + 1;
|
|
200
|
+
let minIndent = Number.POSITIVE_INFINITY;
|
|
201
|
+
while (blockEnd < lines.length) {
|
|
202
|
+
const line = lines[blockEnd];
|
|
203
|
+
if (line.trim() === '') {
|
|
204
|
+
blockEnd += 1;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const indent = leadingSpaces(line);
|
|
208
|
+
if (indent <= configIndent)
|
|
209
|
+
break;
|
|
210
|
+
if (indent < minIndent)
|
|
211
|
+
minIndent = indent;
|
|
212
|
+
blockEnd += 1;
|
|
213
|
+
}
|
|
214
|
+
if (!Number.isFinite(minIndent))
|
|
215
|
+
continue;
|
|
216
|
+
for (const key of keys) {
|
|
217
|
+
const keyLine = new RegExp(`^([ \\t]*)${escapeRegExp(key)}[ \\t]*:(\\s|$|#)`, 'u');
|
|
218
|
+
for (let j = configLine + 1; j < blockEnd; j += 1) {
|
|
219
|
+
if (toDelete.has(j))
|
|
220
|
+
continue;
|
|
221
|
+
const line = lines[j];
|
|
222
|
+
if (line.trim() === '')
|
|
223
|
+
continue;
|
|
224
|
+
const indent = leadingSpaces(line);
|
|
225
|
+
if (indent !== minIndent || !keyLine.test(line))
|
|
226
|
+
continue;
|
|
227
|
+
toDelete.add(j);
|
|
228
|
+
// The key's children (deeper-indented lists/maps) go with it.
|
|
229
|
+
for (let q = j + 1; q < blockEnd; q += 1) {
|
|
230
|
+
const child = lines[q];
|
|
231
|
+
if (child.trim() === '')
|
|
232
|
+
continue;
|
|
233
|
+
if (leadingSpaces(child) <= indent)
|
|
234
|
+
break;
|
|
235
|
+
toDelete.add(q);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Emptied block → keep a `config: {}` line so the entry's shape survives.
|
|
240
|
+
let remains = false;
|
|
241
|
+
for (let j = configLine + 1; j < blockEnd; j += 1) {
|
|
242
|
+
if (!toDelete.has(j) && lines[j].trim() !== '') {
|
|
243
|
+
remains = true;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (!remains)
|
|
248
|
+
toReplace.set(configLine, `${' '.repeat(configIndent)}config: {}`);
|
|
249
|
+
}
|
|
250
|
+
if (toDelete.size === 0 && toReplace.size === 0)
|
|
251
|
+
return text;
|
|
252
|
+
const out = [];
|
|
253
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
254
|
+
const replacement = toReplace.get(i);
|
|
255
|
+
if (replacement !== undefined)
|
|
256
|
+
out.push(replacement);
|
|
257
|
+
else if (!toDelete.has(i))
|
|
258
|
+
out.push(lines[i]);
|
|
259
|
+
}
|
|
260
|
+
return out.join('\n');
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Write CLI config changes through the anti-shadowing pipeline. Returns the
|
|
264
|
+
* refused `env-shadowed` verdict (with the exact field and its variable
|
|
265
|
+
* name) WITHOUT touching any file, or the freshly resolved effective values
|
|
266
|
+
* after the write, the row-key deletions and the patch-file un-shadowing.
|
|
267
|
+
*/
|
|
268
|
+
export function writeCliConfig(options) {
|
|
269
|
+
const env = options.env ?? process.env;
|
|
270
|
+
const row = options.row ?? {};
|
|
271
|
+
const set = options.set ?? {};
|
|
272
|
+
const unset = options.unset ?? [];
|
|
273
|
+
const setKeys = Object.keys(set);
|
|
274
|
+
const targetKeys = [...setKeys, ...unset];
|
|
275
|
+
if (targetKeys.length > 0) {
|
|
276
|
+
// Step 1 — the env layer is untouchable from here: a field whose CURRENT
|
|
277
|
+
// effective source is `env` (a legal value lives in a LAN_GATE_* /
|
|
278
|
+
// DSH_PUSH_* variable) refuses the write outright, naming the variable.
|
|
279
|
+
const snapshot = resolveConfig(row, readFileAt(options.dshHome), env);
|
|
280
|
+
const sources = snapshot.sources;
|
|
281
|
+
for (const key of targetKeys) {
|
|
282
|
+
if (sources[key] !== 'env')
|
|
283
|
+
continue;
|
|
284
|
+
return { ok: false, code: 'env-shadowed', field: key, envVar: ENV_VAR_BY_FIELD[key] ?? key };
|
|
285
|
+
}
|
|
286
|
+
// Step 2 — the file layer: merge / delete the keys atomically (0600).
|
|
287
|
+
const merged = { ...readFileAt(options.dshHome) };
|
|
288
|
+
for (const key of setKeys)
|
|
289
|
+
merged[key] = set[key];
|
|
290
|
+
for (const key of unset)
|
|
291
|
+
delete merged[key];
|
|
292
|
+
writeJsonAtomic(options.dshHome, merged);
|
|
293
|
+
// Step 3a — the row layer: the loader wrapped the row's volatile fields
|
|
294
|
+
// in `{ get() }` references, but they are still plain own properties of
|
|
295
|
+
// the same object apply() holds — a delete makes the NEXT resolveConfig
|
|
296
|
+
// fall through this layer to the freshly written file. Record the keys
|
|
297
|
+
// for this `dshHome` so a subsequent `fiber.restart()` also strips the
|
|
298
|
+
// loader's re-hydrated in-memory `{ get() }` wrappers.
|
|
299
|
+
let remembered = unshadowedByHome.get(options.dshHome);
|
|
300
|
+
if (remembered === undefined) {
|
|
301
|
+
remembered = new Set();
|
|
302
|
+
unshadowedByHome.set(options.dshHome, remembered);
|
|
303
|
+
}
|
|
304
|
+
for (const key of targetKeys) {
|
|
305
|
+
remembered.add(key);
|
|
306
|
+
if (key in row)
|
|
307
|
+
delete row[key];
|
|
308
|
+
}
|
|
309
|
+
// Step 3b — the persisted row layer: the profile patch files the loader
|
|
310
|
+
// itself writes when a settings save pins a key on the plugin row.
|
|
311
|
+
for (const file of patchFileCandidates(options.dshHome, options.profileName)) {
|
|
312
|
+
try {
|
|
313
|
+
const before = readFileSync(file, 'utf8');
|
|
314
|
+
const after = unshadowPatchYml(before, targetKeys);
|
|
315
|
+
if (after === before)
|
|
316
|
+
continue;
|
|
317
|
+
let mode = 0o644;
|
|
318
|
+
try {
|
|
319
|
+
mode = statSync(file).mode & 0o777;
|
|
320
|
+
}
|
|
321
|
+
catch { /* keep the default */ }
|
|
322
|
+
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
323
|
+
writeFileSync(tmp, after, { mode });
|
|
324
|
+
renameSync(tmp, file);
|
|
325
|
+
}
|
|
326
|
+
catch { /* one unreadable profile never blocks the others */ }
|
|
327
|
+
}
|
|
328
|
+
options.onAfterWrite?.();
|
|
329
|
+
}
|
|
330
|
+
// Step 4 — the caller's reload hook fired; answer the values the layers
|
|
331
|
+
// resolve to NOW (the file layer just moved; the row keys just left).
|
|
332
|
+
return { ok: true, values: resolveConfig(row, readFileAt(options.dshHome), env).values };
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=config-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../src/cli/config-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI-3: the execution context every command function receives. One bag with
|
|
3
|
+
* everything a command needs but never constructs itself — the parsed
|
|
4
|
+
* grammar, the live IPC client, the translator, and the interactivity
|
|
5
|
+
* verdict — plus the seams tests inject (a clock, a poll interval, an
|
|
6
|
+
* alternate working directory). Pure types: the real builder is CLI-5's
|
|
7
|
+
* main.ts; the tests assemble the object literal directly.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|