@dsh-enhanced/lark-channel 0.1.3
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.md +342 -0
- package/bin/dsh-lark-setup.js +8 -0
- package/bin/dsh-supervised-growth-setup.js +8 -0
- package/cordis.patch.yml +21 -0
- package/lib/adapter.d.ts +135 -0
- package/lib/adapter.d.ts.map +1 -0
- package/lib/adapter.js +965 -0
- package/lib/adapter.js.map +1 -0
- package/lib/approval.d.ts +26 -0
- package/lib/approval.d.ts.map +1 -0
- package/lib/approval.js +104 -0
- package/lib/approval.js.map +1 -0
- package/lib/config.d.ts +21 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +56 -0
- package/lib/config.js.map +1 -0
- package/lib/group-thread.d.ts +11 -0
- package/lib/group-thread.d.ts.map +1 -0
- package/lib/group-thread.js +22 -0
- package/lib/group-thread.js.map +1 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +30 -0
- package/lib/index.js.map +1 -0
- package/lib/launchd.d.ts +44 -0
- package/lib/launchd.d.ts.map +1 -0
- package/lib/launchd.js +205 -0
- package/lib/launchd.js.map +1 -0
- package/lib/model-picker.d.ts +24 -0
- package/lib/model-picker.d.ts.map +1 -0
- package/lib/model-picker.js +95 -0
- package/lib/model-picker.js.map +1 -0
- package/lib/normalize.d.ts +12 -0
- package/lib/normalize.d.ts.map +1 -0
- package/lib/normalize.js +77 -0
- package/lib/normalize.js.map +1 -0
- package/lib/permission-picker.d.ts +29 -0
- package/lib/permission-picker.d.ts.map +1 -0
- package/lib/permission-picker.js +145 -0
- package/lib/permission-picker.js.map +1 -0
- package/lib/progress.d.ts +15 -0
- package/lib/progress.d.ts.map +1 -0
- package/lib/progress.js +137 -0
- package/lib/progress.js.map +1 -0
- package/lib/resident.d.ts +13 -0
- package/lib/resident.d.ts.map +1 -0
- package/lib/resident.js +41 -0
- package/lib/resident.js.map +1 -0
- package/lib/sdk.d.ts +131 -0
- package/lib/sdk.d.ts.map +1 -0
- package/lib/sdk.js +945 -0
- package/lib/sdk.js.map +1 -0
- package/lib/service.d.ts +30 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +157 -0
- package/lib/service.js.map +1 -0
- package/lib/setup-materialization.d.ts +15 -0
- package/lib/setup-materialization.d.ts.map +1 -0
- package/lib/setup-materialization.js +221 -0
- package/lib/setup-materialization.js.map +1 -0
- package/lib/setup-profile.d.ts +23 -0
- package/lib/setup-profile.d.ts.map +1 -0
- package/lib/setup-profile.js +1126 -0
- package/lib/setup-profile.js.map +1 -0
- package/lib/setup.d.ts +206 -0
- package/lib/setup.d.ts.map +1 -0
- package/lib/setup.js +2143 -0
- package/lib/setup.js.map +1 -0
- package/lib/supervised-growth-profile.d.ts +74 -0
- package/lib/supervised-growth-profile.d.ts.map +1 -0
- package/lib/supervised-growth-profile.js +485 -0
- package/lib/supervised-growth-profile.js.map +1 -0
- package/lib/supervised-growth-setup.d.ts +85 -0
- package/lib/supervised-growth-setup.d.ts.map +1 -0
- package/lib/supervised-growth-setup.js +371 -0
- package/lib/supervised-growth-setup.js.map +1 -0
- package/lib/systemd.d.ts +39 -0
- package/lib/systemd.d.ts.map +1 -0
- package/lib/systemd.js +142 -0
- package/lib/systemd.js.map +1 -0
- package/lib/tool-approval.d.ts +22 -0
- package/lib/tool-approval.d.ts.map +1 -0
- package/lib/tool-approval.js +107 -0
- package/lib/tool-approval.js.map +1 -0
- package/lib/types.d.ts +158 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +11 -0
- package/lib/types.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +2 -0
- package/lib/version.js.map +1 -0
- package/lib/windows-task.d.ts +39 -0
- package/lib/windows-task.d.ts.map +1 -0
- package/lib/windows-task.js +117 -0
- package/lib/windows-task.js.map +1 -0
- package/lib/ws-card-callback.d.ts +7 -0
- package/lib/ws-card-callback.d.ts.map +1 -0
- package/lib/ws-card-callback.js +51 -0
- package/lib/ws-card-callback.js.map +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { chmod, open, readFile, rename } from 'node:fs/promises';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
6
|
+
import { installDshResidentService, residentServiceKind } from './resident.js';
|
|
7
|
+
import { isMainEntry } from './setup.js';
|
|
8
|
+
import { assertEffectiveSupervisedGrowthConfig, configureSupervisedGrowthProfilePatch, supervisedGrowthDatabasePaths, supervisedGrowthBindingQuery, } from './supervised-growth-profile.js';
|
|
9
|
+
const keyPattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
10
|
+
function argumentValue(argv, index, option) {
|
|
11
|
+
const value = argv[index + 1];
|
|
12
|
+
if (value === undefined || value.startsWith('--'))
|
|
13
|
+
throw new Error(`supervised-growth setup: ${option} requires a value`);
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
export function parseSupervisedGrowthSetupArgs(argv) {
|
|
17
|
+
const result = {
|
|
18
|
+
profile: 'web', timeoutMs: 300_000, ackExistingAutomations: false, help: false,
|
|
19
|
+
};
|
|
20
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
21
|
+
const option = argv[index];
|
|
22
|
+
if (option === '--help' || option === '-h')
|
|
23
|
+
result.help = true;
|
|
24
|
+
else if (option === '--profile')
|
|
25
|
+
result.profile = argumentValue(argv, index++, option);
|
|
26
|
+
else if (option === '--timeout-ms')
|
|
27
|
+
result.timeoutMs = Number(argumentValue(argv, index++, option));
|
|
28
|
+
else if (option === '--ack-existing-automations')
|
|
29
|
+
result.ackExistingAutomations = true;
|
|
30
|
+
else
|
|
31
|
+
throw new Error(`supervised-growth setup: unknown option: ${option}`);
|
|
32
|
+
}
|
|
33
|
+
if (!keyPattern.test(result.profile))
|
|
34
|
+
throw new Error('supervised-growth setup: invalid profile');
|
|
35
|
+
if (!Number.isSafeInteger(result.timeoutMs) || result.timeoutMs < 30_000 || result.timeoutMs > 900_000) {
|
|
36
|
+
throw new Error('supervised-growth setup: timeout-ms must be an integer from 30000 to 900000');
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
export function assertSupervisedGrowthAutomationGuard(records, acknowledged) {
|
|
41
|
+
// Enabling the scheduler would start every durable active row. A legacy
|
|
42
|
+
// heartbeat is not intrinsically safe: it may carry broad tools or a
|
|
43
|
+
// different route. Keep the guard stricter than necessary until an exact
|
|
44
|
+
// managed-definition hash can prove a pre-existing row is this overlay.
|
|
45
|
+
const existing = records.filter(record => record.status === 'active');
|
|
46
|
+
if (existing.length > 0 && !acknowledged) {
|
|
47
|
+
throw new Error('supervised-growth setup: active automations already exist; rerun with --ack-existing-automations to leave them untouched');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function selectUniqueOwnerBinding(bindings) {
|
|
51
|
+
if (bindings.length === 0) {
|
|
52
|
+
throw new Error('supervised-growth setup: no matching owner DM binding; send the bot a new direct message, then retry');
|
|
53
|
+
}
|
|
54
|
+
if (bindings.length > 1) {
|
|
55
|
+
throw new Error('supervised-growth setup: multiple matching owner DM bindings found; revoke stale bindings before enabling growth');
|
|
56
|
+
}
|
|
57
|
+
return bindings[0];
|
|
58
|
+
}
|
|
59
|
+
/** Compare the complete durable route snapshot, including its optimistic version. */
|
|
60
|
+
export function sameSupervisedGrowthBinding(left, right) {
|
|
61
|
+
return left.id === right.id
|
|
62
|
+
&& left.conversation.channel === right.conversation.channel
|
|
63
|
+
&& left.conversation.account === right.conversation.account
|
|
64
|
+
&& left.conversation.tenant === right.conversation.tenant
|
|
65
|
+
&& left.conversation.kind === right.conversation.kind
|
|
66
|
+
&& left.conversation.chat === right.conversation.chat
|
|
67
|
+
&& left.conversation.thread === right.conversation.thread
|
|
68
|
+
&& left.principal.channel === right.principal.channel
|
|
69
|
+
&& left.principal.account === right.principal.account
|
|
70
|
+
&& left.principal.tenant === right.principal.tenant
|
|
71
|
+
&& left.principal.user === right.principal.user
|
|
72
|
+
&& left.workspace === right.workspace
|
|
73
|
+
&& left.agentPreset === right.agentPreset
|
|
74
|
+
&& left.sessionId === right.sessionId
|
|
75
|
+
&& left.generation === right.generation
|
|
76
|
+
&& left.policyRef === right.policyRef
|
|
77
|
+
&& left.status === right.status
|
|
78
|
+
&& left.createdAt === right.createdAt
|
|
79
|
+
&& left.updatedAt === right.updatedAt
|
|
80
|
+
&& left.version === right.version;
|
|
81
|
+
}
|
|
82
|
+
function help() {
|
|
83
|
+
return [
|
|
84
|
+
'Usage: dsh-supervised-growth-setup [options]',
|
|
85
|
+
'',
|
|
86
|
+
'Activates the bounded supervised-growth overlay only after one exact owner Lark DM binding is present.',
|
|
87
|
+
' --profile <name> DSH profile (default: web)',
|
|
88
|
+
' --timeout-ms <30000..900000> bounded wait for the owner DM (default: 300000)',
|
|
89
|
+
' --ack-existing-automations acknowledge active jobs may run when the scheduler is enabled',
|
|
90
|
+
].join('\n');
|
|
91
|
+
}
|
|
92
|
+
async function atomicWrite(path, value) {
|
|
93
|
+
const temporary = join(dirname(path), `.cordis.patch.yml.supervised-growth-${process.pid}`);
|
|
94
|
+
const file = await open(temporary, 'w', 0o600);
|
|
95
|
+
try {
|
|
96
|
+
await file.writeFile(value, 'utf8');
|
|
97
|
+
await file.sync();
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await file.close();
|
|
101
|
+
}
|
|
102
|
+
await rename(temporary, path);
|
|
103
|
+
await chmod(path, 0o600);
|
|
104
|
+
}
|
|
105
|
+
function dumpProfile(profile) {
|
|
106
|
+
const result = spawnSync('dsh', ['--profile', profile, '--dump-config'], {
|
|
107
|
+
encoding: 'utf8', maxBuffer: 4 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'],
|
|
108
|
+
});
|
|
109
|
+
if (result.status !== 0) {
|
|
110
|
+
const detail = typeof result.stderr === 'string' ? result.stderr.trim().slice(0, 2_000) : '';
|
|
111
|
+
throw new Error(`supervised-growth setup: DSH rejected the updated profile${detail === '' ? '' : `: ${detail}`}`);
|
|
112
|
+
}
|
|
113
|
+
return typeof result.stdout === 'string' ? result.stdout : String(result.stdout ?? '');
|
|
114
|
+
}
|
|
115
|
+
export async function commitSupervisedGrowthPatch(input) {
|
|
116
|
+
await atomicWrite(input.patchPath, input.updatedPatch);
|
|
117
|
+
try {
|
|
118
|
+
return input.validate();
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
await atomicWrite(input.patchPath, input.originalPatch);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Keep the post-write activation sequence transactional from the operator's
|
|
127
|
+
* point of view: a failed readiness, binding re-read, restart, or health check
|
|
128
|
+
* rewrites the original profile and asks the host to restore its old resident
|
|
129
|
+
* service before reporting failure.
|
|
130
|
+
*/
|
|
131
|
+
export async function activateSupervisedGrowthPatch(input) {
|
|
132
|
+
const effectiveConfig = await commitSupervisedGrowthPatch(input);
|
|
133
|
+
try {
|
|
134
|
+
await input.afterCommit(effectiveConfig);
|
|
135
|
+
return effectiveConfig;
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
await atomicWrite(input.patchPath, input.originalPatch);
|
|
139
|
+
try {
|
|
140
|
+
await input.restore();
|
|
141
|
+
}
|
|
142
|
+
catch (rollbackError) {
|
|
143
|
+
throw new Error(`supervised-growth setup: activation failed and rollback service restore also failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`, { cause: error });
|
|
144
|
+
}
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function delay(milliseconds) {
|
|
149
|
+
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
150
|
+
}
|
|
151
|
+
async function boundedAwait(input) {
|
|
152
|
+
let timeout;
|
|
153
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
154
|
+
timeout = setTimeout(() => {
|
|
155
|
+
input.onTimeout?.();
|
|
156
|
+
reject(new Error(`supervised-growth setup: ${input.label} timed out`));
|
|
157
|
+
}, input.timeoutMs);
|
|
158
|
+
});
|
|
159
|
+
try {
|
|
160
|
+
return await Promise.race([input.operation, deadline]);
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
if (timeout !== undefined)
|
|
164
|
+
clearTimeout(timeout);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Explicit installation-only control-plane probe. It calls the provider's
|
|
169
|
+
* named readiness API rather than listModels/resolveModel, which intentionally
|
|
170
|
+
* remain process-free because they do not carry a live loop session identity.
|
|
171
|
+
*/
|
|
172
|
+
export async function verifySupervisedGrowthTraexReadiness(input, dependencies = {}) {
|
|
173
|
+
if (!Number.isSafeInteger(input.timeoutMs) || input.timeoutMs < 1) {
|
|
174
|
+
throw new Error('supervised-growth setup: TraeX readiness timeout must be a positive integer');
|
|
175
|
+
}
|
|
176
|
+
if (input.traexConfig['enabled'] !== true) {
|
|
177
|
+
throw new Error('supervised-growth setup: TraeX readiness requires an enabled effective provider configuration');
|
|
178
|
+
}
|
|
179
|
+
const timeoutMs = Math.min(input.timeoutMs, 60_000);
|
|
180
|
+
const load = dependencies.load ?? (async () => {
|
|
181
|
+
const provider = await import('@dsh-enhanced/traex-acp-provider');
|
|
182
|
+
if (typeof provider.Config !== 'function' || typeof provider.probeTraexReadiness !== 'function') {
|
|
183
|
+
throw new Error('supervised-growth setup: installed TraeX provider lacks the required explicit readiness probe');
|
|
184
|
+
}
|
|
185
|
+
return provider;
|
|
186
|
+
});
|
|
187
|
+
const provider = await boundedAwait({
|
|
188
|
+
operation: load(), timeoutMs, label: 'loading the TraeX readiness provider',
|
|
189
|
+
});
|
|
190
|
+
const config = provider.Config({ ...input.traexConfig });
|
|
191
|
+
const controller = new AbortController();
|
|
192
|
+
try {
|
|
193
|
+
const catalog = await boundedAwait({
|
|
194
|
+
operation: provider.probeTraexReadiness(config, { timeoutMs, signal: controller.signal }),
|
|
195
|
+
timeoutMs,
|
|
196
|
+
label: 'TraeX login and model catalog readiness',
|
|
197
|
+
onTimeout: () => controller.abort(new Error('supervised-growth readiness timeout')),
|
|
198
|
+
});
|
|
199
|
+
if (!Array.isArray(catalog.models) || catalog.models.length === 0) {
|
|
200
|
+
throw new Error('supervised-growth setup: TraeX readiness returned no usable TraeX models');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
controller.abort();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function residentHealthCommand(command, args) {
|
|
208
|
+
const result = spawnSync(command, args, {
|
|
209
|
+
encoding: 'utf8', maxBuffer: 128 * 1024, stdio: ['ignore', 'pipe', 'pipe'],
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
status: result.status,
|
|
213
|
+
stdout: typeof result.stdout === 'string' ? result.stdout : String(result.stdout ?? ''),
|
|
214
|
+
stderr: typeof result.stderr === 'string' ? result.stderr : String(result.stderr ?? ''),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function residentHealthy(service, run) {
|
|
218
|
+
if (service.kind === 'systemd') {
|
|
219
|
+
return run('/usr/bin/systemctl', ['--user', 'is-active', '--quiet', service.target]).status === 0;
|
|
220
|
+
}
|
|
221
|
+
if (service.kind === 'launchd') {
|
|
222
|
+
const result = run('/bin/launchctl', ['print', service.target]);
|
|
223
|
+
return result.status === 0 && /(?:^|\n)\s*state = running\s*(?:\n|$)/u.test(result.stdout);
|
|
224
|
+
}
|
|
225
|
+
// schtasks' status text is localized and its successful Query does not prove
|
|
226
|
+
// the task process is alive. Do not report an unverifiable Windows task as
|
|
227
|
+
// a healthy unattended supervisor.
|
|
228
|
+
throw new Error('supervised-growth setup: Windows does not provide a verifiable resident health gate for this activation');
|
|
229
|
+
}
|
|
230
|
+
/** Bounded post-restart health check; registration alone is not sufficient. */
|
|
231
|
+
export async function verifySupervisedGrowthResidentService(service, dependencies = {}) {
|
|
232
|
+
const run = dependencies.run ?? residentHealthCommand;
|
|
233
|
+
const wait = dependencies.wait ?? delay;
|
|
234
|
+
const attempts = dependencies.attempts ?? 3;
|
|
235
|
+
const retryDelayMs = dependencies.retryDelayMs ?? 250;
|
|
236
|
+
if (!Number.isSafeInteger(attempts) || attempts < 1 || attempts > 5
|
|
237
|
+
|| !Number.isSafeInteger(retryDelayMs) || retryDelayMs < 0 || retryDelayMs > 5_000) {
|
|
238
|
+
throw new Error('supervised-growth setup: invalid resident health check bounds');
|
|
239
|
+
}
|
|
240
|
+
let lastFailure;
|
|
241
|
+
for (let index = 0; index < attempts; index += 1) {
|
|
242
|
+
try {
|
|
243
|
+
if (residentHealthy(service, run))
|
|
244
|
+
return;
|
|
245
|
+
lastFailure = new Error('resident service did not report a running state');
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
lastFailure = error;
|
|
249
|
+
}
|
|
250
|
+
if (index + 1 < attempts)
|
|
251
|
+
await wait(retryDelayMs);
|
|
252
|
+
}
|
|
253
|
+
throw new Error(`supervised-growth setup: resident service is not healthy after restart${lastFailure instanceof Error ? `: ${lastFailure.message}` : ''}`);
|
|
254
|
+
}
|
|
255
|
+
export async function restartAndVerifySupervisedGrowthResident(input) {
|
|
256
|
+
const service = await (input.install ?? installDshResidentService)({ dshHome: input.dshHome, profile: input.profile });
|
|
257
|
+
await (input.verify ?? verifySupervisedGrowthResidentService)(service);
|
|
258
|
+
return service;
|
|
259
|
+
}
|
|
260
|
+
async function awaitOwnerBinding(input) {
|
|
261
|
+
const { findActiveOwnerDmBindingsLocally } = await import('@dsh-enhanced/assistant-delivery');
|
|
262
|
+
const deadline = Date.now() + input.timeoutMs;
|
|
263
|
+
let prompted = false;
|
|
264
|
+
for (;;) {
|
|
265
|
+
const bindings = findActiveOwnerDmBindingsLocally({ databasePath: input.databasePath, ...input.query });
|
|
266
|
+
if (bindings.length > 1)
|
|
267
|
+
return selectUniqueOwnerBinding(bindings);
|
|
268
|
+
if (bindings.length === 1)
|
|
269
|
+
return selectUniqueOwnerBinding(bindings);
|
|
270
|
+
if (!prompted) {
|
|
271
|
+
prompted = true;
|
|
272
|
+
process.stdout.write('未找到与当前 profile 精确匹配的 owner 私聊绑定。请 owner 再给机器人发送一条普通私聊;等待期间不会修改配置。\n');
|
|
273
|
+
}
|
|
274
|
+
if (Date.now() >= deadline) {
|
|
275
|
+
throw new Error('supervised-growth setup: timed out waiting for an exact owner DM binding; profile was not changed');
|
|
276
|
+
}
|
|
277
|
+
await delay(Math.min(1_000, Math.max(1, deadline - Date.now())));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async function assertSelectedOwnerBindingCurrent(input) {
|
|
281
|
+
const { findActiveOwnerDmBindingsLocally } = await import('@dsh-enhanced/assistant-delivery');
|
|
282
|
+
const current = selectUniqueOwnerBinding(findActiveOwnerDmBindingsLocally({
|
|
283
|
+
databasePath: input.databasePath,
|
|
284
|
+
...input.query,
|
|
285
|
+
}));
|
|
286
|
+
if (!sameSupervisedGrowthBinding(current, input.selected)) {
|
|
287
|
+
throw new Error('supervised-growth setup: selected owner binding changed before activation; profile was not changed');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export async function runSupervisedGrowthSetup(argv = process.argv.slice(2)) {
|
|
291
|
+
const args = parseSupervisedGrowthSetupArgs(argv);
|
|
292
|
+
if (args.help) {
|
|
293
|
+
process.stdout.write(`${help()}\n`);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (residentServiceKind(process.platform) === 'windows-task-best-effort') {
|
|
297
|
+
throw new Error('supervised-growth setup: Windows has no verifiable resident health gate; profile was not changed');
|
|
298
|
+
}
|
|
299
|
+
const dshHome = process.env.DSH_HOME?.trim() || join(homedir(), '.dsh');
|
|
300
|
+
if (!isAbsolute(dshHome))
|
|
301
|
+
throw new Error('supervised-growth setup: DSH_HOME must be absolute');
|
|
302
|
+
const patchPath = join(dshHome, 'profiles', args.profile, 'cordis.patch.yml');
|
|
303
|
+
const originalPatch = await readFile(patchPath, 'utf8');
|
|
304
|
+
const effectiveBefore = dumpProfile(args.profile);
|
|
305
|
+
const query = supervisedGrowthBindingQuery(effectiveBefore, dshHome);
|
|
306
|
+
const databases = supervisedGrowthDatabasePaths(effectiveBefore, dshHome);
|
|
307
|
+
const binding = await awaitOwnerBinding({
|
|
308
|
+
databasePath: databases.deliveryDatabasePath, query, timeoutMs: args.timeoutMs,
|
|
309
|
+
});
|
|
310
|
+
const { listActiveAutomationsLocally } = await import('@dsh-enhanced/assistant-automations');
|
|
311
|
+
assertSupervisedGrowthAutomationGuard(listActiveAutomationsLocally(databases.automationsDatabasePath), args.ackExistingAutomations);
|
|
312
|
+
const updatedPatch = configureSupervisedGrowthProfilePatch({
|
|
313
|
+
profilePatch: originalPatch,
|
|
314
|
+
effectiveConfig: effectiveBefore,
|
|
315
|
+
dshHome,
|
|
316
|
+
binding,
|
|
317
|
+
});
|
|
318
|
+
await assertSelectedOwnerBindingCurrent({
|
|
319
|
+
databasePath: databases.deliveryDatabasePath,
|
|
320
|
+
query,
|
|
321
|
+
selected: binding,
|
|
322
|
+
});
|
|
323
|
+
let service;
|
|
324
|
+
await activateSupervisedGrowthPatch({
|
|
325
|
+
patchPath,
|
|
326
|
+
originalPatch,
|
|
327
|
+
updatedPatch,
|
|
328
|
+
validate: () => dumpProfile(args.profile),
|
|
329
|
+
afterCommit: async (effectiveConfig) => {
|
|
330
|
+
const verified = assertEffectiveSupervisedGrowthConfig({ effectiveConfig, dshHome, binding });
|
|
331
|
+
const effectiveDatabases = supervisedGrowthDatabasePaths(effectiveConfig, dshHome);
|
|
332
|
+
if (effectiveDatabases.deliveryDatabasePath !== databases.deliveryDatabasePath
|
|
333
|
+
|| effectiveDatabases.automationsDatabasePath !== databases.automationsDatabasePath) {
|
|
334
|
+
throw new Error('supervised-growth setup: a higher-priority profile layer changed a guarded local database path');
|
|
335
|
+
}
|
|
336
|
+
// The binding is re-read after the atomic write and again immediately
|
|
337
|
+
// before restart. A rotation/revocation/version change must never become
|
|
338
|
+
// a background delivery grant merely because its old snapshot was valid.
|
|
339
|
+
await assertSelectedOwnerBindingCurrent({
|
|
340
|
+
databasePath: databases.deliveryDatabasePath,
|
|
341
|
+
query,
|
|
342
|
+
selected: binding,
|
|
343
|
+
});
|
|
344
|
+
await verifySupervisedGrowthTraexReadiness({
|
|
345
|
+
traexConfig: verified.traexConfig,
|
|
346
|
+
timeoutMs: args.timeoutMs,
|
|
347
|
+
});
|
|
348
|
+
await assertSelectedOwnerBindingCurrent({
|
|
349
|
+
databasePath: databases.deliveryDatabasePath,
|
|
350
|
+
query,
|
|
351
|
+
selected: binding,
|
|
352
|
+
});
|
|
353
|
+
service = await restartAndVerifySupervisedGrowthResident({ dshHome, profile: args.profile });
|
|
354
|
+
},
|
|
355
|
+
restore: async () => {
|
|
356
|
+
dumpProfile(args.profile);
|
|
357
|
+
await restartAndVerifySupervisedGrowthResident({ dshHome, profile: args.profile });
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
if (service === undefined)
|
|
361
|
+
throw new Error('supervised-growth setup: resident restart did not return a service');
|
|
362
|
+
process.stdout.write(`supervised-growth 已启用:owner binding ${binding.id},每日运行次数上限 7;每轮最多 512 输出 token。\n`
|
|
363
|
+
+ `DSH Host 已由 ${service.kind} 重启并通过健康检查。状态:${service.statusCommand}\n日志:${service.logCommand}\n`);
|
|
364
|
+
}
|
|
365
|
+
if (process.argv[1] !== undefined && isMainEntry(import.meta.url, process.argv[1])) {
|
|
366
|
+
void runSupervisedGrowthSetup().catch(error => {
|
|
367
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
368
|
+
process.exitCode = 1;
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=supervised-growth-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervised-growth-setup.js","sourceRoot":"","sources":["../src/supervised-growth-setup.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAiC,MAAM,eAAe,CAAA;AAC7G,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,EACL,qCAAqC,EACrC,qCAAqC,EACrC,6BAA6B,EAC7B,4BAA4B,GAE7B,MAAM,gCAAgC,CAAA;AASvC,MAAM,UAAU,GAAG,oCAAoC,CAAA;AAEvD,SAAS,aAAa,CAAC,IAAuB,EAAE,KAAa,EAAE,MAAc;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;IAC7B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,mBAAmB,CAAC,CAAA;IACzH,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,IAAuB;IACpE,MAAM,MAAM,GAA8B;QACxC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;KAC/E,CAAA;IACD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAE,CAAA;QAC3B,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAA;aACzD,IAAI,MAAM,KAAK,WAAW;YAAE,MAAM,CAAC,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,CAAC,CAAA;aACjF,IAAI,MAAM,KAAK,cAAc;YAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC,CAAA;aAC9F,IAAI,MAAM,KAAK,4BAA4B;YAAE,MAAM,CAAC,sBAAsB,GAAG,IAAI,CAAA;;YACjF,MAAM,IAAI,KAAK,CAAC,4CAA4C,MAAM,EAAE,CAAC,CAAA;IAC5E,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IACjG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,OAAO,EAAE,CAAC;QACvG,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAA;IAChG,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAID,MAAM,UAAU,qCAAqC,CACnD,OAAyC,EACzC,YAAqB;IAErB,yEAAyE;IACzE,qEAAqE;IACrE,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAA;IACrE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,0HAA0H,CAAC,CAAA;IAC7I,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAoC,QAAsB;IAChG,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sGAAsG,CAAC,CAAA;IACzH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kHAAkH,CAAC,CAAA;IACrI,CAAC;IACD,OAAO,QAAQ,CAAC,CAAC,CAAE,CAAA;AACrB,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,2BAA2B,CACzC,IAA6B,EAC7B,KAA8B;IAE9B,OAAO,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE;WACtB,IAAI,CAAC,YAAY,CAAC,OAAO,KAAK,KAAK,CAAC,YAAY,CAAC,OAAO;WACxD,IAAI,CAAC,YAAY,CAAC,OAAO,KAAK,KAAK,CAAC,YAAY,CAAC,OAAO;WACxD,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC,MAAM;WACtD,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,KAAK,CAAC,YAAY,CAAC,IAAI;WAClD,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,KAAK,CAAC,YAAY,CAAC,IAAI;WAClD,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC,MAAM;WACtD,IAAI,CAAC,SAAS,CAAC,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC,OAAO;WAClD,IAAI,CAAC,SAAS,CAAC,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC,OAAO;WAClD,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC,MAAM;WAChD,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC,IAAI;WAC5C,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;WAClC,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW;WACtC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;WAClC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;WACpC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;WAClC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;WAC5B,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;WAClC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;WAClC,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAA;AACrC,CAAC;AAED,SAAS,IAAI;IACX,OAAO;QACL,8CAA8C;QAC9C,EAAE;QACF,wGAAwG;QACxG,gEAAgE;QAChE,qFAAqF;QACrF,mGAAmG;KACpG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,KAAa;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,uCAAuC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAC3F,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;IAC9C,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACnC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;IACpB,CAAC;IACD,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC7B,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,OAAe;IAClC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,eAAe,CAAC,EAAE;QACvE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAChF,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5F,MAAM,IAAI,KAAK,CAAC,4DAA4D,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE,CAAC,CAAA;IACnH,CAAC;IACD,OAAO,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;AACxF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAI,KAKpD;IACC,MAAM,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;IACtD,IAAI,CAAC;QACH,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAA;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;QACvD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAI,KAOtD;IACC,MAAM,eAAe,GAAG,MAAM,2BAA2B,CAAC,KAAK,CAAC,CAAA;IAChE,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC,CAAA;QACxC,OAAO,eAAe,CAAA;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;QACvD,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,OAAO,EAAE,CAAA;QACvB,CAAC;QAAC,OAAO,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,wFAAwF,aAAa,YAAY,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,EACxK,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAA;QACH,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,YAAoB;IACjC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAA;AAClE,CAAC;AA2BD,KAAK,UAAU,YAAY,CAAI,KAK9B;IACC,IAAI,OAAkD,CAAA;IACtD,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QACvD,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YACxB,KAAK,CAAC,SAAS,EAAE,EAAE,CAAA;YACnB,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,KAAK,YAAY,CAAC,CAAC,CAAA;QACxE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACrB,CAAC,CAAC,CAAA;IACF,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAA;IACxD,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,KAAK,SAAS;YAAE,YAAY,CAAC,OAAO,CAAC,CAAA;IAClD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAG1D,EAAE,eAA2D,EAAE;IAC9D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAA;IAChG,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAA;IAClH,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACnD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE;QAC5C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAA6D,CAAA;QAC7H,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,UAAU,IAAI,OAAO,QAAQ,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;YAChG,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAA;QAClH,CAAC;QACD,OAAO,QAAgD,CAAA;IACzD,CAAC,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC;QAClC,SAAS,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,sCAAsC;KAC5E,CAAC,CAAA;IACF,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;IACxD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IACxC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC;YACjC,SAAS,EAAE,QAAQ,CAAC,mBAAmB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;YACzF,SAAS;YACT,KAAK,EAAE,yCAAyC;YAChD,SAAS,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;SACpF,CAAC,CAAA;QACF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAA;QAC7F,CAAC;IACH,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,KAAK,EAAE,CAAA;IACpB,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe,EAAE,IAAuB;IACrE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE;QACtC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAC3E,CAAC,CAAA;IACF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;QACvF,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;KACxF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,OAAiC,EAAE,GAAmE;IAC7H,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,GAAG,CAAC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;IACnG,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAC/D,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,wCAAwC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5F,CAAC;IACD,6EAA6E;IAC7E,4EAA4E;IAC5E,mCAAmC;IACnC,MAAM,IAAI,KAAK,CAAC,yGAAyG,CAAC,CAAA;AAC5H,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,qCAAqC,CACzD,OAAiC,EACjC,eAA2D,EAAE;IAE7D,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,IAAI,qBAAqB,CAAA;IACrD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,IAAI,KAAK,CAAA;IACvC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,CAAC,CAAA;IAC3C,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,IAAI,GAAG,CAAA;IACrD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC;WAC9D,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,KAAK,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAA;IAClF,CAAC;IACD,IAAI,WAAoB,CAAA;IACxB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,QAAQ,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC;YACH,IAAI,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC;gBAAE,OAAM;YACzC,WAAW,GAAG,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;QAC5E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,GAAG,KAAK,CAAA;QACrB,CAAC;QACD,IAAI,KAAK,GAAG,CAAC,GAAG,QAAQ;YAAE,MAAM,IAAI,CAAC,YAAY,CAAC,CAAA;IACpD,CAAC;IACD,MAAM,IAAI,KAAK,CACb,yEAAyE,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1I,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAAC,KAK9D;IACC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,yBAAyB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IACtH,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,qCAAqC,CAAC,CAAC,OAAO,CAAC,CAAA;IACtE,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,KAIhC;IACC,MAAM,EAAE,gCAAgC,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAA;IAC7F,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAA;IAC7C,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,SAAS,CAAC;QACR,MAAM,QAAQ,GAAG,gCAAgC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;QACvG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAA;QACpE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAA;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAA;QAC7F,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAA;QACtH,CAAC;QACD,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAClE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iCAAiC,CAAC,KAIhD;IACC,MAAM,EAAE,gCAAgC,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAA;IAC7F,MAAM,OAAO,GAAG,wBAAwB,CAAC,gCAAgC,CAAC;QACxE,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,GAAG,KAAK,CAAC,KAAK;KACf,CAAC,CAAC,CAAA;IACH,IAAI,CAAC,2BAA2B,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAA;IACvH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAA0B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5F,MAAM,IAAI,GAAG,8BAA8B,CAAC,IAAI,CAAC,CAAA;IACjD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAA;QACnC,OAAM;IACR,CAAC;IACD,IAAI,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,0BAA0B,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAA;IACrH,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAA;IACvE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;IAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAA;IAC7E,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACvD,MAAM,eAAe,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,4BAA4B,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,6BAA6B,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;IACzE,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC;QACtC,YAAY,EAAE,SAAS,CAAC,oBAAoB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS;KAC/E,CAAC,CAAA;IACF,MAAM,EAAE,4BAA4B,EAAE,GAAG,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAA;IAC5F,qCAAqC,CACnC,4BAA4B,CAAC,SAAS,CAAC,uBAAuB,CAAC,EAC/D,IAAI,CAAC,sBAAsB,CAC5B,CAAA;IACD,MAAM,YAAY,GAAG,qCAAqC,CAAC;QACzD,YAAY,EAAE,aAAa;QAC3B,eAAe,EAAE,eAAe;QAChC,OAAO;QACP,OAAO;KACR,CAAC,CAAA;IACF,MAAM,iCAAiC,CAAC;QACtC,YAAY,EAAE,SAAS,CAAC,oBAAoB;QAC5C,KAAK;QACL,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAA;IACF,IAAI,OAA6C,CAAA;IACjD,MAAM,6BAA6B,CAAC;QAClC,SAAS;QACT,aAAa;QACb,YAAY;QACZ,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;QACzC,WAAW,EAAE,KAAK,EAAC,eAAe,EAAC,EAAE;YACnC,MAAM,QAAQ,GAAG,qCAAqC,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7F,MAAM,kBAAkB,GAAG,6BAA6B,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;YAClF,IAAI,kBAAkB,CAAC,oBAAoB,KAAK,SAAS,CAAC,oBAAoB;mBACzE,kBAAkB,CAAC,uBAAuB,KAAK,SAAS,CAAC,uBAAuB,EAAE,CAAC;gBACtF,MAAM,IAAI,KAAK,CAAC,gGAAgG,CAAC,CAAA;YACnH,CAAC;YACD,sEAAsE;YACtE,yEAAyE;YACzE,yEAAyE;YACzE,MAAM,iCAAiC,CAAC;gBACtC,YAAY,EAAE,SAAS,CAAC,oBAAoB;gBAC5C,KAAK;gBACL,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;YACF,MAAM,oCAAoC,CAAC;gBACzC,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAA;YACF,MAAM,iCAAiC,CAAC;gBACtC,YAAY,EAAE,SAAS,CAAC,oBAAoB;gBAC5C,KAAK;gBACL,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;YACF,OAAO,GAAG,MAAM,wCAAwC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAC9F,CAAC;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACzB,MAAM,wCAAwC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QACpF,CAAC;KACF,CAAC,CAAA;IACF,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;IAChH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,OAAO,CAAC,EAAE,kCAAkC;UACtG,eAAe,OAAO,CAAC,IAAI,iBAAiB,OAAO,CAAC,aAAa,QAAQ,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;AACpG,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,KAAK,wBAAwB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACnF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/lib/systemd.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface SystemdServicePathsInput {
|
|
2
|
+
home?: string;
|
|
3
|
+
dshHome: string;
|
|
4
|
+
profile: string;
|
|
5
|
+
}
|
|
6
|
+
export interface SystemdServicePaths {
|
|
7
|
+
unitName: string;
|
|
8
|
+
unitPath: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SystemdUnitInput extends SystemdServicePaths {
|
|
11
|
+
dshHome: string;
|
|
12
|
+
profile: string;
|
|
13
|
+
profileDirectory: string;
|
|
14
|
+
nodePath: string;
|
|
15
|
+
dshPath: string;
|
|
16
|
+
path: string;
|
|
17
|
+
}
|
|
18
|
+
export interface InstalledSystemdService extends SystemdServicePaths {
|
|
19
|
+
target: string;
|
|
20
|
+
logCommand: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SystemdInstallOptions {
|
|
23
|
+
home?: string;
|
|
24
|
+
platform?: NodeJS.Platform;
|
|
25
|
+
nodePath?: string;
|
|
26
|
+
dshPath?: string;
|
|
27
|
+
path?: string;
|
|
28
|
+
run?: (command: string, args: readonly string[]) => {
|
|
29
|
+
status: number | null;
|
|
30
|
+
stderr: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export declare function systemdServicePaths(input: SystemdServicePathsInput): SystemdServicePaths;
|
|
34
|
+
export declare function createSystemdUserUnit(input: SystemdUnitInput): string;
|
|
35
|
+
export declare function installDshSystemdService(input: {
|
|
36
|
+
dshHome: string;
|
|
37
|
+
profile: string;
|
|
38
|
+
}, options?: SystemdInstallOptions): Promise<InstalledSystemdService>;
|
|
39
|
+
//# sourceMappingURL=systemd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd.d.ts","sourceRoot":"","sources":["../src/systemd.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,uBAAwB,SAAQ,mBAAmB;IAClE,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9F;AAyCD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,CAMxF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CA2BrE;AA0BD,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC3C,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CAkClC"}
|
package/lib/systemd.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { accessSync, constants } from 'node:fs';
|
|
2
|
+
import { access, chmod, mkdir, open, rename } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { delimiter, dirname, isAbsolute, join } from 'node:path';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
const profilePattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
7
|
+
function requireAbsolute(value, label) {
|
|
8
|
+
if (!isAbsolute(value))
|
|
9
|
+
throw new Error(`lark-channel setup: ${label} must be absolute`);
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function unitQuote(value) {
|
|
13
|
+
if (value.includes('\0') || /[\r\n]/u.test(value))
|
|
14
|
+
throw new Error('lark-channel setup: invalid systemd value');
|
|
15
|
+
return `"${value.replace(/\\/gu, '\\\\').replace(/"/gu, '\\"')}"`;
|
|
16
|
+
}
|
|
17
|
+
function unitLiteralQuote(value) {
|
|
18
|
+
return unitQuote(value.replace(/%/gu, '%%'));
|
|
19
|
+
}
|
|
20
|
+
function unitWorkingDirectory(value) {
|
|
21
|
+
if (value.includes('\0') || /[\r\n]/u.test(value))
|
|
22
|
+
throw new Error('lark-channel setup: invalid systemd value');
|
|
23
|
+
// systemd 252 parses this directive as one raw path: quotes and C escapes would become literal path characters.
|
|
24
|
+
const escaped = value.replace(/%/gu, '%%');
|
|
25
|
+
return /[\t \\]$/u.test(escaped) ? `${escaped}/` : escaped;
|
|
26
|
+
}
|
|
27
|
+
function findExecutable(command, pathValue = process.env.PATH) {
|
|
28
|
+
for (const directory of (pathValue ?? '').split(delimiter)) {
|
|
29
|
+
if (directory === '' || !isAbsolute(directory))
|
|
30
|
+
continue;
|
|
31
|
+
const candidate = join(directory, command);
|
|
32
|
+
try {
|
|
33
|
+
accessSync(candidate, constants.X_OK);
|
|
34
|
+
return candidate;
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
37
|
+
}
|
|
38
|
+
throw new Error(`lark-channel setup: cannot find ${command} on PATH`);
|
|
39
|
+
}
|
|
40
|
+
function servicePath(nodePath, dshPath, currentPath) {
|
|
41
|
+
const values = [dirname(nodePath), dirname(dshPath), ...(currentPath ?? '').split(delimiter), '/usr/bin', '/bin']
|
|
42
|
+
.filter((value, index, all) => value !== '' && isAbsolute(value) && all.indexOf(value) === index);
|
|
43
|
+
return values.join(delimiter);
|
|
44
|
+
}
|
|
45
|
+
export function systemdServicePaths(input) {
|
|
46
|
+
if (!profilePattern.test(input.profile))
|
|
47
|
+
throw new Error('lark-channel setup: invalid profile');
|
|
48
|
+
const home = requireAbsolute(input.home ?? homedir(), 'home');
|
|
49
|
+
requireAbsolute(input.dshHome, 'DSH_HOME');
|
|
50
|
+
const unitName = `dsh-profile-${input.profile}.service`;
|
|
51
|
+
return { unitName, unitPath: join(home, '.config', 'systemd', 'user', unitName) };
|
|
52
|
+
}
|
|
53
|
+
export function createSystemdUserUnit(input) {
|
|
54
|
+
for (const [label, value] of Object.entries({
|
|
55
|
+
dshHome: input.dshHome,
|
|
56
|
+
profileDirectory: input.profileDirectory,
|
|
57
|
+
nodePath: input.nodePath,
|
|
58
|
+
dshPath: input.dshPath,
|
|
59
|
+
}))
|
|
60
|
+
requireAbsolute(value, label);
|
|
61
|
+
if (!profilePattern.test(input.profile))
|
|
62
|
+
throw new Error('lark-channel setup: invalid profile');
|
|
63
|
+
return `[Unit]
|
|
64
|
+
Description=DeepSeek Harness profile ${input.profile}
|
|
65
|
+
After=network-online.target
|
|
66
|
+
Wants=network-online.target
|
|
67
|
+
|
|
68
|
+
[Service]
|
|
69
|
+
Type=simple
|
|
70
|
+
WorkingDirectory=${unitWorkingDirectory(input.profileDirectory)}
|
|
71
|
+
Environment=${unitLiteralQuote(`DSH_HOME=${input.dshHome}`)}
|
|
72
|
+
Environment=${unitLiteralQuote(`PATH=${input.path}`)}
|
|
73
|
+
Environment=${unitQuote('DBUS_SESSION_BUS_ADDRESS=unix:path=%t/bus')}
|
|
74
|
+
Environment=${unitQuote('XDG_RUNTIME_DIR=%t')}
|
|
75
|
+
ExecStart=${unitLiteralQuote(input.nodePath)} --disable-warning=ExperimentalWarning ${unitLiteralQuote(input.dshPath)} --profile ${input.profile} --no-open
|
|
76
|
+
Restart=on-failure
|
|
77
|
+
RestartSec=2
|
|
78
|
+
|
|
79
|
+
[Install]
|
|
80
|
+
WantedBy=default.target
|
|
81
|
+
`;
|
|
82
|
+
}
|
|
83
|
+
async function atomicWrite(path, value) {
|
|
84
|
+
const temporary = `${path}.tmp-${process.pid}`;
|
|
85
|
+
const file = await open(temporary, 'w', 0o600);
|
|
86
|
+
try {
|
|
87
|
+
await file.writeFile(value, 'utf8');
|
|
88
|
+
await file.sync();
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
await file.close();
|
|
92
|
+
}
|
|
93
|
+
await rename(temporary, path);
|
|
94
|
+
await chmod(path, 0o600);
|
|
95
|
+
}
|
|
96
|
+
function defaultRun(command, args) {
|
|
97
|
+
const result = spawnSync(command, [...args], {
|
|
98
|
+
encoding: 'utf8', env: { PATH: '/usr/bin:/bin',
|
|
99
|
+
...(process.env.DBUS_SESSION_BUS_ADDRESS === undefined
|
|
100
|
+
? {} : { DBUS_SESSION_BUS_ADDRESS: process.env.DBUS_SESSION_BUS_ADDRESS }),
|
|
101
|
+
...(process.env.XDG_RUNTIME_DIR === undefined ? {} : { XDG_RUNTIME_DIR: process.env.XDG_RUNTIME_DIR }) },
|
|
102
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
103
|
+
});
|
|
104
|
+
return { status: result.status, stderr: typeof result.stderr === 'string' ? result.stderr : '' };
|
|
105
|
+
}
|
|
106
|
+
export async function installDshSystemdService(input, options = {}) {
|
|
107
|
+
if ((options.platform ?? process.platform) !== 'linux') {
|
|
108
|
+
throw new Error('lark-channel setup: systemd installer requires Linux');
|
|
109
|
+
}
|
|
110
|
+
const paths = systemdServicePaths({
|
|
111
|
+
...(options.home === undefined ? {} : { home: options.home }),
|
|
112
|
+
dshHome: input.dshHome,
|
|
113
|
+
profile: input.profile,
|
|
114
|
+
});
|
|
115
|
+
const profileDirectory = join(input.dshHome, 'profiles', input.profile);
|
|
116
|
+
await access(profileDirectory, constants.R_OK);
|
|
117
|
+
const nodePath = options.nodePath ?? findExecutable('node', options.path);
|
|
118
|
+
const dshPath = options.dshPath ?? findExecutable('dsh', options.path);
|
|
119
|
+
const path = servicePath(nodePath, dshPath, options.path ?? process.env.PATH);
|
|
120
|
+
const run = options.run ?? defaultRun;
|
|
121
|
+
await mkdir(dirname(paths.unitPath), { recursive: true, mode: 0o700 });
|
|
122
|
+
await atomicWrite(paths.unitPath, createSystemdUserUnit({
|
|
123
|
+
...paths, dshHome: input.dshHome, profile: input.profile, profileDirectory, nodePath, dshPath, path,
|
|
124
|
+
}));
|
|
125
|
+
const commands = [
|
|
126
|
+
['--user', 'daemon-reload'],
|
|
127
|
+
['--user', 'enable', paths.unitName],
|
|
128
|
+
['--user', 'restart', paths.unitName],
|
|
129
|
+
['--user', 'is-active', '--quiet', paths.unitName],
|
|
130
|
+
];
|
|
131
|
+
for (const args of commands) {
|
|
132
|
+
const result = run('/usr/bin/systemctl', args);
|
|
133
|
+
if (result.status !== 0)
|
|
134
|
+
throw new Error('lark-channel setup: systemd user service operation failed');
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
...paths,
|
|
138
|
+
target: paths.unitName,
|
|
139
|
+
logCommand: `journalctl --user -u ${paths.unitName} -f`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=systemd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd.js","sourceRoot":"","sources":["../src/systemd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface LarkToolApprovalActionPayload {
|
|
2
|
+
version: 1;
|
|
3
|
+
channel: string;
|
|
4
|
+
account: string;
|
|
5
|
+
tenant: string;
|
|
6
|
+
operationId: string;
|
|
7
|
+
bindingId: string;
|
|
8
|
+
chatId: string;
|
|
9
|
+
ownerUser: string;
|
|
10
|
+
actionHash: string;
|
|
11
|
+
toolName: string;
|
|
12
|
+
callId: string;
|
|
13
|
+
expiresAt: number;
|
|
14
|
+
decision: 'allowed-once' | 'rejected';
|
|
15
|
+
}
|
|
16
|
+
export declare class LarkToolApprovalError extends Error {
|
|
17
|
+
readonly code: 'expired' | 'invalid';
|
|
18
|
+
constructor(code: 'expired' | 'invalid', message: string);
|
|
19
|
+
}
|
|
20
|
+
export declare function signLarkToolApprovalAction(secret: string, input: LarkToolApprovalActionPayload): string;
|
|
21
|
+
export declare function verifyLarkToolApprovalAction(secret: string, token: string, now: number): LarkToolApprovalActionPayload;
|
|
22
|
+
//# sourceMappingURL=tool-approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-approval.d.ts","sourceRoot":"","sources":["../src/tool-approval.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,CAAC,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,cAAc,GAAG,UAAU,CAAA;CACtC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS;gBAA3B,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM;CAIlE;AAiED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,6BAA6B,GAAG,MAAM,CAQvG;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,6BAA6B,CAyB/B"}
|