@dsh-enhanced/lark-channel 0.1.48 → 0.1.53
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.md +20 -8
- package/docs/rsi-setup.md +145 -12
- package/docs/setup.md +29 -14
- package/docs/supervised-growth.md +2 -0
- package/lib/adapter.d.ts +6 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +79 -8
- package/lib/adapter.js.map +1 -1
- package/lib/business-cli-install.d.ts +9 -0
- package/lib/business-cli-install.d.ts.map +1 -0
- package/lib/business-cli-install.js +367 -0
- package/lib/business-cli-install.js.map +1 -0
- package/lib/business-environment.d.ts +2 -0
- package/lib/business-environment.d.ts.map +1 -0
- package/lib/business-environment.js +16 -0
- package/lib/business-environment.js.map +1 -0
- package/lib/business-skill.d.ts +32 -0
- package/lib/business-skill.d.ts.map +1 -0
- package/lib/business-skill.js +202 -0
- package/lib/business-skill.js.map +1 -0
- package/lib/launchd-control.d.ts +24 -0
- package/lib/launchd-control.d.ts.map +1 -0
- package/lib/launchd-control.js +68 -0
- package/lib/launchd-control.js.map +1 -0
- package/lib/launchd-identity.d.ts +34 -0
- package/lib/launchd-identity.d.ts.map +1 -0
- package/lib/launchd-identity.js +184 -0
- package/lib/launchd-identity.js.map +1 -0
- package/lib/launchd-target-lock.d.ts +6 -0
- package/lib/launchd-target-lock.d.ts.map +1 -0
- package/lib/launchd-target-lock.js +48 -0
- package/lib/launchd-target-lock.js.map +1 -0
- package/lib/launchd.d.ts +18 -0
- package/lib/launchd.d.ts.map +1 -1
- package/lib/launchd.js +211 -54
- package/lib/launchd.js.map +1 -1
- package/lib/rsi-authority-config.d.ts +29 -0
- package/lib/rsi-authority-config.d.ts.map +1 -0
- package/lib/rsi-authority-config.js +233 -0
- package/lib/rsi-authority-config.js.map +1 -0
- package/lib/rsi-authority-resources.d.ts +36 -0
- package/lib/rsi-authority-resources.d.ts.map +1 -0
- package/lib/rsi-authority-resources.js +139 -0
- package/lib/rsi-authority-resources.js.map +1 -0
- package/lib/rsi-authority-runtime.d.ts +50 -0
- package/lib/rsi-authority-runtime.d.ts.map +1 -0
- package/lib/rsi-authority-runtime.js +393 -0
- package/lib/rsi-authority-runtime.js.map +1 -0
- package/lib/rsi-bootstrap-manifest.d.ts +39 -0
- package/lib/rsi-bootstrap-manifest.d.ts.map +1 -0
- package/lib/rsi-bootstrap-manifest.js +345 -0
- package/lib/rsi-bootstrap-manifest.js.map +1 -0
- package/lib/rsi-bootstrap.d.ts +30 -0
- package/lib/rsi-bootstrap.d.ts.map +1 -0
- package/lib/rsi-bootstrap.js +363 -0
- package/lib/rsi-bootstrap.js.map +1 -0
- package/lib/rsi-build.d.ts +54 -0
- package/lib/rsi-build.d.ts.map +1 -0
- package/lib/rsi-build.js +478 -0
- package/lib/rsi-build.js.map +1 -0
- package/lib/rsi-creation-build.d.ts +48 -0
- package/lib/rsi-creation-build.d.ts.map +1 -0
- package/lib/rsi-creation-build.js +363 -0
- package/lib/rsi-creation-build.js.map +1 -0
- package/lib/rsi-host-authorities.d.ts +18 -0
- package/lib/rsi-host-authorities.d.ts.map +1 -0
- package/lib/rsi-host-authorities.js +129 -0
- package/lib/rsi-host-authorities.js.map +1 -0
- package/lib/rsi-host-update.d.ts +113 -0
- package/lib/rsi-host-update.d.ts.map +1 -0
- package/lib/rsi-host-update.js +316 -0
- package/lib/rsi-host-update.js.map +1 -0
- package/lib/rsi-install-inputs.d.ts +43 -0
- package/lib/rsi-install-inputs.d.ts.map +1 -0
- package/lib/rsi-install-inputs.js +342 -0
- package/lib/rsi-install-inputs.js.map +1 -0
- package/lib/rsi-install.d.ts +54 -0
- package/lib/rsi-install.d.ts.map +1 -0
- package/lib/rsi-install.js +404 -0
- package/lib/rsi-install.js.map +1 -0
- package/lib/rsi-local-activation.d.ts +78 -0
- package/lib/rsi-local-activation.d.ts.map +1 -0
- package/lib/rsi-local-activation.js +485 -0
- package/lib/rsi-local-activation.js.map +1 -0
- package/lib/rsi-local-cohort.d.ts +70 -0
- package/lib/rsi-local-cohort.d.ts.map +1 -0
- package/lib/rsi-local-cohort.js +781 -0
- package/lib/rsi-local-cohort.js.map +1 -0
- package/lib/rsi-local-install.d.ts +68 -0
- package/lib/rsi-local-install.d.ts.map +1 -0
- package/lib/rsi-local-install.js +322 -0
- package/lib/rsi-local-install.js.map +1 -0
- package/lib/rsi-local-pair-install.d.ts +38 -0
- package/lib/rsi-local-pair-install.d.ts.map +1 -0
- package/lib/rsi-local-pair-install.js +200 -0
- package/lib/rsi-local-pair-install.js.map +1 -0
- package/lib/rsi-local-profile-update.d.ts +25 -0
- package/lib/rsi-local-profile-update.d.ts.map +1 -0
- package/lib/rsi-local-profile-update.js +226 -0
- package/lib/rsi-local-profile-update.js.map +1 -0
- package/lib/rsi-local-resources.d.ts +37 -0
- package/lib/rsi-local-resources.d.ts.map +1 -0
- package/lib/rsi-local-resources.js +184 -0
- package/lib/rsi-local-resources.js.map +1 -0
- package/lib/rsi-local-roots-extension.d.ts +11 -0
- package/lib/rsi-local-roots-extension.d.ts.map +1 -0
- package/lib/rsi-local-roots-extension.js +31 -0
- package/lib/rsi-local-roots-extension.js.map +1 -0
- package/lib/rsi-local-update-build.d.ts +18 -0
- package/lib/rsi-local-update-build.d.ts.map +1 -0
- package/lib/rsi-local-update-build.js +37 -0
- package/lib/rsi-local-update-build.js.map +1 -0
- package/lib/rsi-local-update.d.ts +39 -0
- package/lib/rsi-local-update.d.ts.map +1 -0
- package/lib/rsi-local-update.js +205 -0
- package/lib/rsi-local-update.js.map +1 -0
- package/lib/rsi-memory-learning.d.ts +30 -0
- package/lib/rsi-memory-learning.d.ts.map +1 -0
- package/lib/rsi-memory-learning.js +104 -0
- package/lib/rsi-memory-learning.js.map +1 -0
- package/lib/rsi-native-install.d.ts +38 -0
- package/lib/rsi-native-install.d.ts.map +1 -0
- package/lib/rsi-native-install.js +254 -0
- package/lib/rsi-native-install.js.map +1 -0
- package/lib/rsi-native-launchd.d.ts +7 -0
- package/lib/rsi-native-launchd.d.ts.map +1 -0
- package/lib/rsi-native-launchd.js +49 -0
- package/lib/rsi-native-launchd.js.map +1 -0
- package/lib/rsi-native-profile.d.ts +64 -0
- package/lib/rsi-native-profile.d.ts.map +1 -0
- package/lib/rsi-native-profile.js +283 -0
- package/lib/rsi-native-profile.js.map +1 -0
- package/lib/rsi-native-runtime-bootstrap.d.ts +35 -0
- package/lib/rsi-native-runtime-bootstrap.d.ts.map +1 -0
- package/lib/rsi-native-runtime-bootstrap.js +385 -0
- package/lib/rsi-native-runtime-bootstrap.js.map +1 -0
- package/lib/rsi-owner-profile.d.ts +37 -0
- package/lib/rsi-owner-profile.d.ts.map +1 -0
- package/lib/rsi-owner-profile.js +178 -0
- package/lib/rsi-owner-profile.js.map +1 -0
- package/lib/rsi-plugin-creation.d.ts +32 -0
- package/lib/rsi-plugin-creation.d.ts.map +1 -0
- package/lib/rsi-plugin-creation.js +189 -0
- package/lib/rsi-plugin-creation.js.map +1 -0
- package/lib/rsi-profile.d.ts +23 -0
- package/lib/rsi-profile.d.ts.map +1 -1
- package/lib/rsi-profile.js +154 -43
- package/lib/rsi-profile.js.map +1 -1
- package/lib/rsi-release-build.d.ts +41 -0
- package/lib/rsi-release-build.d.ts.map +1 -0
- package/lib/rsi-release-build.js +223 -0
- package/lib/rsi-release-build.js.map +1 -0
- package/lib/rsi-service-environment.d.ts +6 -0
- package/lib/rsi-service-environment.d.ts.map +1 -0
- package/lib/rsi-service-environment.js +113 -0
- package/lib/rsi-service-environment.js.map +1 -0
- package/lib/rsi-service-setup.d.ts +10 -0
- package/lib/rsi-service-setup.d.ts.map +1 -0
- package/lib/rsi-service-setup.js +34 -0
- package/lib/rsi-service-setup.js.map +1 -0
- package/lib/rsi-setup.d.ts +35 -2
- package/lib/rsi-setup.d.ts.map +1 -1
- package/lib/rsi-setup.js +475 -32
- package/lib/rsi-setup.js.map +1 -1
- package/lib/rsi-source-maintenance.d.ts +25 -0
- package/lib/rsi-source-maintenance.d.ts.map +1 -0
- package/lib/rsi-source-maintenance.js +348 -0
- package/lib/rsi-source-maintenance.js.map +1 -0
- package/lib/rsi-source-update.d.ts +26 -0
- package/lib/rsi-source-update.d.ts.map +1 -0
- package/lib/rsi-source-update.js +276 -0
- package/lib/rsi-source-update.js.map +1 -0
- package/lib/rsi-source.d.ts +34 -0
- package/lib/rsi-source.d.ts.map +1 -0
- package/lib/rsi-source.js +487 -0
- package/lib/rsi-source.js.map +1 -0
- package/lib/rsi-systemd-bootstrap.d.ts +46 -0
- package/lib/rsi-systemd-bootstrap.d.ts.map +1 -0
- package/lib/rsi-systemd-bootstrap.js +271 -0
- package/lib/rsi-systemd-bootstrap.js.map +1 -0
- package/lib/sdk.d.ts.map +1 -1
- package/lib/sdk.js +26 -1
- package/lib/sdk.js.map +1 -1
- package/lib/setup-business.d.ts +49 -0
- package/lib/setup-business.d.ts.map +1 -0
- package/lib/setup-business.js +335 -0
- package/lib/setup-business.js.map +1 -0
- package/lib/setup-profile.d.ts +1 -1
- package/lib/setup-profile.d.ts.map +1 -1
- package/lib/setup-profile.js +25 -2
- package/lib/setup-profile.js.map +1 -1
- package/lib/setup.d.ts +12 -1
- package/lib/setup.d.ts.map +1 -1
- package/lib/setup.js +265 -48
- package/lib/setup.js.map +1 -1
- package/lib/systemd.d.ts +10 -0
- package/lib/systemd.d.ts.map +1 -1
- package/lib/systemd.js +23 -6
- package/lib/systemd.js.map +1 -1
- package/lib/types.d.ts +7 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +33 -20
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { lstat, mkdir, readFile, readdir, rename, unlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { isAbsolute, join, parse, relative, resolve, sep, win32 } from 'node:path';
|
|
4
|
+
import { parse as parseYaml, stringify } from 'yaml';
|
|
5
|
+
import { LARK_BUSINESS_CLEARED_ENV } from './business-environment.js';
|
|
6
|
+
const identifierPattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
7
|
+
const ownerPattern = /^ou_[A-Za-z0-9_-]{1,124}$/u;
|
|
8
|
+
const appIdPattern = /^cli_[0-9a-fA-F]{16}$/u;
|
|
9
|
+
const markerPrefix = '<!-- managed-by:@dsh-enhanced/lark-channel/business-skill:v1 ';
|
|
10
|
+
function hasControlCharacter(value) {
|
|
11
|
+
return Array.from(value).some(char => {
|
|
12
|
+
const code = char.codePointAt(0) ?? 0;
|
|
13
|
+
return code < 32 || code === 127;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function requireIdentifier(value, field) {
|
|
17
|
+
if (typeof value !== 'string' || !identifierPattern.test(value)) {
|
|
18
|
+
throw new Error(`lark business skill: invalid ${field}`);
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function requireBinding(input) {
|
|
23
|
+
const profile = requireIdentifier(input.profile, 'profile');
|
|
24
|
+
const account = requireIdentifier(input.account, 'account');
|
|
25
|
+
if (typeof input.ownerUserId !== 'string' || !ownerPattern.test(input.ownerUserId)) {
|
|
26
|
+
throw new Error('lark business skill: invalid ownerUserId');
|
|
27
|
+
}
|
|
28
|
+
if (typeof input.appId !== 'string' || !appIdPattern.test(input.appId)) {
|
|
29
|
+
throw new Error('lark business skill: invalid appId');
|
|
30
|
+
}
|
|
31
|
+
return { profile, account, appId: input.appId, ownerUserId: input.ownerUserId };
|
|
32
|
+
}
|
|
33
|
+
function requireAbsolutePath(value, field, platform) {
|
|
34
|
+
if (typeof value !== 'string' || hasControlCharacter(value)
|
|
35
|
+
|| !(isAbsolute(value) || (platform === 'win32' && win32.isAbsolute(value)))) {
|
|
36
|
+
throw new Error(`lark business skill: ${field} must be an absolute path without control characters`);
|
|
37
|
+
}
|
|
38
|
+
return platform === 'win32' && win32.isAbsolute(value) && !isAbsolute(value)
|
|
39
|
+
? win32.normalize(value) : resolve(value);
|
|
40
|
+
}
|
|
41
|
+
function validate(input) {
|
|
42
|
+
const platform = input.platform ?? process.platform;
|
|
43
|
+
const binding = requireBinding(input);
|
|
44
|
+
const cliProfile = requireIdentifier(input.cliProfile, 'cliProfile');
|
|
45
|
+
return {
|
|
46
|
+
dshHome: requireAbsolutePath(input.dshHome, 'dshHome', platform),
|
|
47
|
+
...binding,
|
|
48
|
+
cliCommand: requireAbsolutePath(input.cliCommand, 'cliCommand', platform),
|
|
49
|
+
cliProfile,
|
|
50
|
+
cliConfigDir: requireAbsolutePath(input.cliConfigDir, 'cliConfigDir', platform),
|
|
51
|
+
cliDataDir: requireAbsolutePath(input.cliDataDir, 'cliDataDir', platform),
|
|
52
|
+
platform,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function shellQuote(value) {
|
|
56
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
57
|
+
}
|
|
58
|
+
function powershellQuote(value) {
|
|
59
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
60
|
+
}
|
|
61
|
+
function skillName(input) {
|
|
62
|
+
const hash = createHash('sha256').update(input.profile).update('\0').update(input.account).digest('hex').slice(0, 16);
|
|
63
|
+
return `lark-business-${hash}`;
|
|
64
|
+
}
|
|
65
|
+
export function renderLarkBusinessSkill(input) {
|
|
66
|
+
const checked = validate(input);
|
|
67
|
+
const name = skillName(checked);
|
|
68
|
+
const marker = `${markerPrefix}${name} -->`;
|
|
69
|
+
const cli = checked.platform === 'win32'
|
|
70
|
+
? `${LARK_BUSINESS_CLEARED_ENV.map(name => `Remove-Item Env:${name} -ErrorAction SilentlyContinue;`).join(' ')} $env:LARKSUITE_CLI_CONFIG_DIR=${powershellQuote(checked.cliConfigDir)}; $env:LARKSUITE_CLI_DATA_DIR=${powershellQuote(checked.cliDataDir)}; $env:LARKSUITE_CLI_NO_UPDATE_NOTIFIER='1'; $env:LARKSUITE_CLI_NO_SKILLS_NOTIFIER='1'; & ${powershellQuote(checked.cliCommand)} --profile ${powershellQuote(checked.cliProfile)}`
|
|
71
|
+
: `env ${LARK_BUSINESS_CLEARED_ENV.map(name => `-u ${name}`).join(' ')} LARKSUITE_CLI_CONFIG_DIR=${shellQuote(checked.cliConfigDir)} LARKSUITE_CLI_DATA_DIR=${shellQuote(checked.cliDataDir)} LARKSUITE_CLI_NO_UPDATE_NOTIFIER=1 LARKSUITE_CLI_NO_SKILLS_NOTIFIER=1 ${shellQuote(checked.cliCommand)} --profile ${shellQuote(checked.cliProfile)}`;
|
|
72
|
+
const frontmatter = stringify({
|
|
73
|
+
name,
|
|
74
|
+
description: `Use the configured Lark CLI for owner-authorized documents, sheets, Base, calendar, tasks, mail, meetings, contacts, and approvals. Only for DSH profile ${checked.profile}, Lark account ${checked.account}, app ${checked.appId}, and owner ${checked.ownerUserId}; read current embedded official skills and schemas before acting.`,
|
|
75
|
+
metadata: { appId: checked.appId, ownerUserId: checked.ownerUserId,
|
|
76
|
+
profile: checked.profile, account: checked.account },
|
|
77
|
+
}).trimEnd();
|
|
78
|
+
const content = `---\n${frontmatter}\n---\n${marker}\n# Lark business operations\n\nThis skill belongs to DSH profile **${checked.profile}**, Lark account **${checked.account}**, application **${checked.appId}**, and owner open ID **${checked.ownerUserId}**. Use it only when the current DSH profile, channel account, application, and owner all match this binding. If any value differs, stop using this skill and rerun channel setup. These values identify this installation; they are not credentials. Never print tokens, secrets, or configuration contents.\n\nUse the native skill and shell tools for this task (${checked.platform === 'win32' ? 'PowerShell on Windows' : 'a POSIX shell on this platform'}). Do not start another Agent loop. Every CLI invocation must use the exact command prefix below, including its explicit profile and private configuration directory. Linux uses the private data directory for CLI token files; on macOS and Windows the CLI may use a system keychain shared by the OS account. Do not use an unbound CLI command or the machine's default CLI profile/configuration.\n\n ${cli} skills list\n ${cli} skills read lark-shared\n\nBefore each business operation, discover the current embedded official instructions with \`skills list\`, then \`skills read <relevant-skill>\`. Read its referenced files on demand with \`skills list <skill>/references\` and \`skills read <skill> <reference-path>\`. The embedded instructions and command schemas are the source of truth; do not rely on a copied catalogue. For example, a document task can start with:\n\n ${cli} skills read lark-doc\n\nUse the operation's \`--help\` and \`schema <service.resource.method>\` when the exact arguments or risk level are unclear. Keep the same isolated prefix for these calls and for every subsequent business command. Select \`--as user\` for the owner's personal resources; use \`--as bot\` only for application/bot resources. The bot identity may not see the owner's resources.\n\nThe owner's current request authorizes the operations necessary to complete that task; do not ask again for an already authorized action. If a CLI command exits with code 10, add \`--yes\` only when the specific operation is already authorized by that request, then retry that command once. Otherwise request the missing authorization. Authentication, scope, and network failures are not approval gates: diagnose them, never turn them into a successful retry.\n\nKeep all subsequent examples and real invocations bound to this exact prefix, including explicit \`--profile\`. Do not disclose credentials in replies or logs.\n`;
|
|
79
|
+
return { name, content };
|
|
80
|
+
}
|
|
81
|
+
async function existingKind(path) {
|
|
82
|
+
try {
|
|
83
|
+
const stat = await lstat(path);
|
|
84
|
+
if (stat.isSymbolicLink())
|
|
85
|
+
return 'symlink';
|
|
86
|
+
if (stat.isDirectory())
|
|
87
|
+
return 'directory';
|
|
88
|
+
if (stat.isFile())
|
|
89
|
+
return 'file';
|
|
90
|
+
return 'other';
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error.code === 'ENOENT')
|
|
94
|
+
return 'missing';
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function ensureRealDirectory(path) {
|
|
99
|
+
const absolute = resolve(path);
|
|
100
|
+
const root = parse(absolute).root;
|
|
101
|
+
let current = root;
|
|
102
|
+
for (const segment of relative(root, absolute).split(sep).filter(Boolean)) {
|
|
103
|
+
current = join(current, segment);
|
|
104
|
+
const kind = await existingKind(current);
|
|
105
|
+
if (kind === 'missing')
|
|
106
|
+
await mkdir(current, { mode: 0o700 });
|
|
107
|
+
else if (kind !== 'directory')
|
|
108
|
+
throw new Error(`lark business skill: directory path is ${kind}: ${current}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function hasExistingRealDirectory(path) {
|
|
112
|
+
const absolute = resolve(path);
|
|
113
|
+
const root = parse(absolute).root;
|
|
114
|
+
let current = root;
|
|
115
|
+
for (const segment of relative(root, absolute).split(sep).filter(Boolean)) {
|
|
116
|
+
current = join(current, segment);
|
|
117
|
+
const kind = await existingKind(current);
|
|
118
|
+
if (kind === 'missing')
|
|
119
|
+
return false;
|
|
120
|
+
if (kind !== 'directory')
|
|
121
|
+
throw new Error(`lark business skill: directory path is ${kind}: ${current}`);
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
function metadataBinding(content, name) {
|
|
126
|
+
const marker = `${markerPrefix}${name} -->`;
|
|
127
|
+
const separator = `\n---\n${marker}\n`;
|
|
128
|
+
const end = content.startsWith('---\n') ? content.indexOf(separator, 4) : -1;
|
|
129
|
+
if (end < 0)
|
|
130
|
+
throw new Error('lark business skill: existing SKILL.md is not managed by this installer');
|
|
131
|
+
try {
|
|
132
|
+
const document = parseYaml(content.slice(4, end));
|
|
133
|
+
if (typeof document !== 'object' || document === null || Array.isArray(document))
|
|
134
|
+
return undefined;
|
|
135
|
+
const metadata = document.metadata;
|
|
136
|
+
return typeof metadata === 'object' && metadata !== null && !Array.isArray(metadata)
|
|
137
|
+
? metadata : undefined;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Remove a stale managed skill after owner/app rotation or explicit opt-out. */
|
|
144
|
+
export async function reconcileLarkBusinessSkill(input) {
|
|
145
|
+
const binding = requireBinding(input);
|
|
146
|
+
if (typeof input.enabled !== 'boolean')
|
|
147
|
+
throw new Error('lark business skill: invalid enabled flag');
|
|
148
|
+
const dshHome = requireAbsolutePath(input.dshHome, 'dshHome', process.platform);
|
|
149
|
+
const previousAccount = input.previousAccount === undefined
|
|
150
|
+
? undefined : requireIdentifier(input.previousAccount, 'previousAccount');
|
|
151
|
+
const reconcileName = async (name, removeRegardlessOfBinding) => {
|
|
152
|
+
const skillDir = join(dshHome, 'skills', name);
|
|
153
|
+
if (!await hasExistingRealDirectory(skillDir))
|
|
154
|
+
return;
|
|
155
|
+
const path = join(skillDir, 'SKILL.md');
|
|
156
|
+
const kind = await existingKind(path);
|
|
157
|
+
if (kind === 'missing')
|
|
158
|
+
return;
|
|
159
|
+
if (kind !== 'file')
|
|
160
|
+
throw new Error(`lark business skill: existing SKILL.md is ${kind}; refusing to replace it`);
|
|
161
|
+
const metadata = metadataBinding(await readFile(path, 'utf8'), name);
|
|
162
|
+
if (removeRegardlessOfBinding || !input.enabled || metadata?.appId !== binding.appId || metadata?.ownerUserId !== binding.ownerUserId
|
|
163
|
+
|| metadata?.profile !== binding.profile || metadata?.account !== binding.account) {
|
|
164
|
+
await unlink(path);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
if (previousAccount !== undefined && previousAccount !== binding.account) {
|
|
168
|
+
await reconcileName(skillName({ profile: binding.profile, account: previousAccount }), true);
|
|
169
|
+
}
|
|
170
|
+
await reconcileName(skillName(binding), false);
|
|
171
|
+
}
|
|
172
|
+
export async function installLarkBusinessSkill(input) {
|
|
173
|
+
const { name, content } = renderLarkBusinessSkill(input);
|
|
174
|
+
const dshHome = requireAbsolutePath(input.dshHome, 'dshHome', input.platform ?? process.platform);
|
|
175
|
+
const skillDir = join(dshHome, 'skills', name);
|
|
176
|
+
const path = join(skillDir, 'SKILL.md');
|
|
177
|
+
await ensureRealDirectory(skillDir);
|
|
178
|
+
const kind = await existingKind(path);
|
|
179
|
+
if (kind !== 'missing' && kind !== 'file') {
|
|
180
|
+
throw new Error(`lark business skill: existing SKILL.md is ${kind}; refusing to replace it`);
|
|
181
|
+
}
|
|
182
|
+
if (kind === 'file') {
|
|
183
|
+
const previous = await readFile(path, 'utf8');
|
|
184
|
+
metadataBinding(previous, name);
|
|
185
|
+
if (previous === content)
|
|
186
|
+
return { path, name };
|
|
187
|
+
}
|
|
188
|
+
else if ((await readdir(skillDir)).length !== 0) {
|
|
189
|
+
throw new Error('lark business skill: existing skill directory is not managed by this installer');
|
|
190
|
+
}
|
|
191
|
+
const temporary = join(skillDir, `.SKILL.md.${randomUUID()}.tmp`);
|
|
192
|
+
try {
|
|
193
|
+
await writeFile(temporary, content, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
|
|
194
|
+
await rename(temporary, path);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
await unlink(temporary).catch(() => undefined);
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
return { path, name };
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=business-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"business-skill.js","sourceRoot":"","sources":["../src/business-skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7F,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAClF,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAA;AAyBrE,MAAM,iBAAiB,GAAG,oCAAoC,CAAA;AAC9D,MAAM,YAAY,GAAG,4BAA4B,CAAA;AACjD,MAAM,YAAY,GAAG,wBAAwB,CAAA;AAC7C,MAAM,YAAY,GAAG,+DAA+D,CAAA;AAEpF,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACrC,OAAO,IAAI,GAAG,EAAE,IAAI,IAAI,KAAK,GAAG,CAAA;IAClC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa,EAAE,KAAa;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAA;IAC1D,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,cAAc,CAAC,KAAoF;IAG1G,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IAC3D,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IACvD,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAA;AACjF,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa,EAAE,KAAa,EAAE,QAAyB;IAClF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,mBAAmB,CAAC,KAAK,CAAC;WACtD,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,sDAAsD,CAAC,CAAA;IACtG,CAAC;IACD,OAAO,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAC1E,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7C,CAAC;AAED,SAAS,QAAQ,CAAC,KAA6B;IAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IACnD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACrC,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;IACpE,OAAO;QACL,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;QAChE,GAAG,OAAO;QACV,UAAU,EAAE,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC;QACzE,UAAU;QACV,YAAY,EAAE,mBAAmB,CAAC,KAAK,CAAC,YAAY,EAAE,cAAc,EAAE,QAAQ,CAAC;QAC/E,UAAU,EAAE,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC;QACzE,QAAQ;KACT,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAA;AAC9C,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAA;AAC3C,CAAC;AAED,SAAS,SAAS,CAAC,KAA0D;IAC3E,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACrH,OAAO,iBAAiB,IAAI,EAAE,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAA6B;IACnE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,GAAG,YAAY,GAAG,IAAI,MAAM,CAAA;IAC3C,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO;QACtC,CAAC,CAAC,GAAG,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,IAAI,iCAAiC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,kCAAkC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,iCAAiC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,6FAA6F,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;QAC5a,CAAC,CAAC,OAAO,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,2BAA2B,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,0EAA0E,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAA;IACpV,MAAM,WAAW,GAAG,SAAS,CAAC;QAC5B,IAAI;QACJ,WAAW,EAAE,4JAA4J,OAAO,CAAC,OAAO,kBAAkB,OAAO,CAAC,OAAO,SAAS,OAAO,CAAC,KAAK,eAAe,OAAO,CAAC,WAAW,oEAAoE;QACrV,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW;YAChE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;KACvD,CAAC,CAAC,OAAO,EAAE,CAAA;IACZ,MAAM,OAAO,GAAG,QAAQ,WAAW,UAAU,MAAM,uEAAuE,OAAO,CAAC,OAAO,sBAAsB,OAAO,CAAC,OAAO,qBAAqB,OAAO,CAAC,KAAK,2BAA2B,OAAO,CAAC,WAAW,wWAAwW,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,gCAAgC,kZAAkZ,GAAG,qBAAqB,GAAG,wcAAwc,GAAG,qgCAAqgC,CAAA;IAC5jF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,IAAY;IACtC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAA;QAC9B,IAAI,IAAI,CAAC,cAAc,EAAE;YAAE,OAAO,SAAS,CAAA;QAC3C,IAAI,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO,WAAW,CAAA;QAC1C,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,MAAM,CAAA;QAChC,OAAO,OAAO,CAAA;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAA;QACxE,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAY;IAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAA;IACjC,IAAI,OAAO,GAAG,IAAI,CAAA;IAClB,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1E,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;QACxC,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;aACxD,IAAI,IAAI,KAAK,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,KAAK,OAAO,EAAE,CAAC,CAAA;IAC9G,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAA;IACjC,IAAI,OAAO,GAAG,IAAI,CAAA;IAClB,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1E,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;QACxC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACpC,IAAI,IAAI,KAAK,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,KAAK,OAAO,EAAE,CAAC,CAAA;IACzG,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,IAAY;IACpD,MAAM,MAAM,GAAG,GAAG,YAAY,GAAG,IAAI,MAAM,CAAA;IAC3C,MAAM,SAAS,GAAG,UAAU,MAAM,IAAI,CAAA;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5E,IAAI,GAAG,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAA;IACvG,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAY,CAAA;QAC5D,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,SAAS,CAAA;QAClG,MAAM,QAAQ,GAAI,QAAoC,CAAC,QAAQ,CAAA;QAC/D,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAClF,CAAC,CAAC,QAAmC,CAAC,CAAC,CAAC,SAAS,CAAA;IACrD,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAA;IAAC,CAAC;AAC9B,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAsC;IACrF,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACrC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;IACpG,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/E,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,KAAK,SAAS;QACzD,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAA;IAC3E,MAAM,aAAa,GAAG,KAAK,EAAE,IAAY,EAAE,yBAAkC,EAAiB,EAAE;QAC9F,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC9C,IAAI,CAAC,MAAM,wBAAwB,CAAC,QAAQ,CAAC;YAAE,OAAM;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAM;QAC9B,IAAI,IAAI,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,0BAA0B,CAAC,CAAA;QACjH,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAA;QACpE,IAAI,yBAAyB,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,QAAQ,EAAE,KAAK,KAAK,OAAO,CAAC,KAAK,IAAI,QAAQ,EAAE,WAAW,KAAK,OAAO,CAAC,WAAW;eAChI,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YACpF,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC,CAAA;IACD,IAAI,eAAe,KAAK,SAAS,IAAI,eAAe,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;QACzE,MAAM,aAAa,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;IAC9F,CAAC;IACD,MAAM,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,KAA6B;IAC1E,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAA;IACxD,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjG,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACvC,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,0BAA0B,CAAC,CAAA;IAC9F,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC7C,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC/B,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IACjD,CAAC;SAAM,IAAI,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAA;IACnG,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,UAAU,EAAE,MAAM,CAAC,CAAA;IACjE,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAClF,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QAC9C,MAAM,KAAK,CAAA;IACb,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { inspectDshLaunchAgent } from './launchd.js';
|
|
2
|
+
type ServiceInput = {
|
|
3
|
+
dshHome: string;
|
|
4
|
+
profile: string;
|
|
5
|
+
};
|
|
6
|
+
type ServiceState = Awaited<ReturnType<typeof inspectDshLaunchAgent>>;
|
|
7
|
+
export type LaunchAgentAction = 'registered' | 'running' | 'restart' | 'restart-if-loaded';
|
|
8
|
+
export interface LaunchAgentControlOptions {
|
|
9
|
+
platform?: NodeJS.Platform;
|
|
10
|
+
inspect?: (input: ServiceInput) => Promise<ServiceState>;
|
|
11
|
+
run?: (command: string, args: string[]) => {
|
|
12
|
+
status: number | null;
|
|
13
|
+
stderr?: string;
|
|
14
|
+
};
|
|
15
|
+
lock?: <T>(input: ServiceInput, operation: () => Promise<T>) => Promise<T>;
|
|
16
|
+
wait?: (milliseconds: number) => Promise<void>;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
/** Service-only operations never install a plist or run onboarding. */
|
|
20
|
+
export declare function controlDshLaunchAgent(input: ServiceInput, action: LaunchAgentAction, options?: LaunchAgentControlOptions): Promise<boolean>;
|
|
21
|
+
/** Internal installer dispatch, loaded through the selected Host's resolver. */
|
|
22
|
+
export declare function runLaunchdControl(args: string[]): Promise<void>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=launchd-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd-control.d.ts","sourceRoot":"","sources":["../src/launchd-control.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGpD,KAAK,YAAY,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AACxD,KAAK,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAA;AACrE,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,mBAAmB,CAAA;AAC1F,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAA;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACxD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACrF,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC1E,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,uEAAuE;AACvE,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EACxF,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,OAAO,CAAC,CAoC3D;AAED,gFAAgF;AAChF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAarE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { isAbsolute } from 'node:path';
|
|
3
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
4
|
+
import { inspectDshLaunchAgent } from './launchd.js';
|
|
5
|
+
import { withLaunchAgentTargetLock } from './launchd-target-lock.js';
|
|
6
|
+
/** Service-only operations never install a plist or run onboarding. */
|
|
7
|
+
export async function controlDshLaunchAgent(input, action, options = {}) {
|
|
8
|
+
if ((options.platform ?? process.platform) !== 'darwin')
|
|
9
|
+
throw new Error('launchd service control requires macOS');
|
|
10
|
+
if (!isAbsolute(input.dshHome) || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(input.profile)) {
|
|
11
|
+
throw new Error('invalid launchd service identity');
|
|
12
|
+
}
|
|
13
|
+
const inspect = options.inspect ?? inspectDshLaunchAgent;
|
|
14
|
+
if (action === 'registered' || action === 'running') {
|
|
15
|
+
const state = await inspect(input);
|
|
16
|
+
return state.registered && (action === 'registered' || state.running);
|
|
17
|
+
}
|
|
18
|
+
const run = options.run ?? ((command, args) => spawnSync(command, args, {
|
|
19
|
+
encoding: 'utf8', timeout: 10_000, maxBuffer: 262_144,
|
|
20
|
+
env: { PATH: '/usr/bin:/bin:/usr/sbin:/sbin' }, stdio: ['ignore', 'ignore', 'pipe'],
|
|
21
|
+
}));
|
|
22
|
+
const timeoutMs = options.timeoutMs ?? 30_000;
|
|
23
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 60_000)
|
|
24
|
+
throw new Error('invalid launchd restart deadline');
|
|
25
|
+
return (options.lock ?? withLaunchAgentTargetLock)(input, async () => {
|
|
26
|
+
const before = await inspect(input);
|
|
27
|
+
if (!before.registered) {
|
|
28
|
+
if (action === 'restart-if-loaded')
|
|
29
|
+
return false;
|
|
30
|
+
throw new Error('launchd service is not registered for this DSH_HOME');
|
|
31
|
+
}
|
|
32
|
+
const result = run('/bin/launchctl', ['kickstart', '-k', before.target]);
|
|
33
|
+
if (result.status !== 0)
|
|
34
|
+
throw new Error(`launchd restart failed: ${result.stderr?.trim() || `exit ${result.status}`}`);
|
|
35
|
+
const deadline = Date.now() + timeoutMs;
|
|
36
|
+
for (;;) {
|
|
37
|
+
const current = await inspect(input);
|
|
38
|
+
if (current.target !== before.target || current.plistPath !== before.plistPath
|
|
39
|
+
|| (current.registered && JSON.stringify(current.identity) !== JSON.stringify(before.identity))) {
|
|
40
|
+
throw new Error('launchd service identity changed during restart');
|
|
41
|
+
}
|
|
42
|
+
if (current.registered && current.running && current.pid !== before.pid)
|
|
43
|
+
return true;
|
|
44
|
+
if (Date.now() >= deadline)
|
|
45
|
+
throw new Error('launchd restart did not produce a new running Host');
|
|
46
|
+
await (options.wait ?? delay)(Math.min(100, deadline - Date.now()));
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** Internal installer dispatch, loaded through the selected Host's resolver. */
|
|
51
|
+
export async function runLaunchdControl(args) {
|
|
52
|
+
const values = {};
|
|
53
|
+
for (let index = 0; index < args.length; index += 2) {
|
|
54
|
+
const name = args[index], value = args[index + 1];
|
|
55
|
+
if (!name || !['--profile', '--dsh-home', '--action'].includes(name) || values[name] !== undefined
|
|
56
|
+
|| !value || value.startsWith('--'))
|
|
57
|
+
throw new Error('invalid launchd service control arguments');
|
|
58
|
+
values[name] = value;
|
|
59
|
+
}
|
|
60
|
+
const action = values['--action'];
|
|
61
|
+
if (!action || !['registered', 'running', 'restart', 'restart-if-loaded'].includes(action)
|
|
62
|
+
|| !values['--profile'] || !values['--dsh-home'])
|
|
63
|
+
throw new Error('missing launchd service control arguments');
|
|
64
|
+
const present = await controlDshLaunchAgent({ dshHome: values['--dsh-home'], profile: values['--profile'] }, action);
|
|
65
|
+
if (!present && action !== 'restart-if-loaded')
|
|
66
|
+
process.exitCode = 3;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=launchd-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd-control.js","sourceRoot":"","sources":["../src/launchd-control.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface NativeLaunchdIdentity {
|
|
2
|
+
dshHome: string;
|
|
3
|
+
profile: string;
|
|
4
|
+
home?: string;
|
|
5
|
+
uid?: number;
|
|
6
|
+
nodePath?: string;
|
|
7
|
+
dshPath?: string;
|
|
8
|
+
dshSha256?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface NativeLaunchdState {
|
|
11
|
+
registered: boolean;
|
|
12
|
+
pid: number;
|
|
13
|
+
}
|
|
14
|
+
export interface NativeLaunchdDetail extends NativeLaunchdState {
|
|
15
|
+
running: boolean;
|
|
16
|
+
state: string | null;
|
|
17
|
+
lastExitCode: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface NativeLaunchdCommandResult {
|
|
20
|
+
status: number | null;
|
|
21
|
+
stdout: string;
|
|
22
|
+
stderr: string;
|
|
23
|
+
}
|
|
24
|
+
export type NativeLaunchdCommand = (command: string, args: string[]) => NativeLaunchdCommandResult;
|
|
25
|
+
/** A missing job is distinct from a failed launchctl query. Never stop a job
|
|
26
|
+
* belonging to another Home just because its profile label is the same. */
|
|
27
|
+
export declare function inspectNativeLaunchdDetail(input: NativeLaunchdIdentity, command?: NativeLaunchdCommand): NativeLaunchdDetail;
|
|
28
|
+
export declare function inspectNativeLaunchd(input: NativeLaunchdIdentity, command?: NativeLaunchdCommand): NativeLaunchdState;
|
|
29
|
+
/** Validate an existing plist before recording it for rollback. The loaded job
|
|
30
|
+
* is independently checked by inspectNativeLaunchd. */
|
|
31
|
+
export declare function assertNativeLaunchdPlist(bytes: string, input: NativeLaunchdIdentity, command?: NativeLaunchdCommand): void;
|
|
32
|
+
export declare function stopNativeLaunchd(input: NativeLaunchdIdentity, signal: AbortSignal, command?: NativeLaunchdCommand): Promise<void>;
|
|
33
|
+
export declare function startNativeLaunchd(input: NativeLaunchdIdentity, signal: AbortSignal, command?: NativeLaunchdCommand): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=launchd-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd-identity.d.ts","sourceRoot":"","sources":["../src/launchd-identity.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CACxD;AACD,MAAM,WAAW,kBAAkB;IAAG,UAAU,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AACxE,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CACpE;AACD,MAAM,WAAW,0BAA0B;IAAG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACrG,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,0BAA0B,CAAA;AA0DlG;2EAC2E;AAC3E,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,GAAE,oBAA0B,GAAG,mBAAmB,CAqBjI;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,GAAE,oBAA0B,GAAG,kBAAkB,CAG1H;AAED;uDACuD;AACvD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAClF,OAAO,GAAE,oBAA0B,GAAG,IAAI,CA4B3C;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,WAAW,EACvF,OAAO,GAAE,oBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBpD;AACD,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,EAAE,MAAM,EAAE,WAAW,EACxF,OAAO,GAAE,oBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpD"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
4
|
+
import { isAbsolute, join } from 'node:path';
|
|
5
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
6
|
+
import { launchAgentPaths } from './launchd.js';
|
|
7
|
+
const run = (command, args) => {
|
|
8
|
+
const result = spawnSync(command, args, { encoding: 'utf8', timeout: 10_000, maxBuffer: 262_144,
|
|
9
|
+
env: { PATH: '/usr/bin:/bin:/usr/sbin:/sbin' }, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
10
|
+
return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
|
|
11
|
+
};
|
|
12
|
+
function fail(message) { throw new Error(`rsi native launchd: ${message}`); }
|
|
13
|
+
function identity(input) {
|
|
14
|
+
const uid = input.uid ?? process.getuid?.();
|
|
15
|
+
if (!Number.isSafeInteger(uid) || uid === undefined || uid < 1)
|
|
16
|
+
fail('a non-root GUI user is required');
|
|
17
|
+
const paths = launchAgentPaths(input), domain = `gui/${uid}`;
|
|
18
|
+
return { ...paths, domain, target: `${domain}/${paths.label}`, cwd: join(input.dshHome, 'profiles', input.profile) };
|
|
19
|
+
}
|
|
20
|
+
function scalar(text, key, separator = ' = ') {
|
|
21
|
+
const prefix = `${key}${separator}`;
|
|
22
|
+
const matches = text.split('\n').map(line => line.trim()).filter(line => line.startsWith(prefix));
|
|
23
|
+
if (matches.length !== 1)
|
|
24
|
+
return undefined;
|
|
25
|
+
return matches[0].slice(prefix.length);
|
|
26
|
+
}
|
|
27
|
+
function rootScalar(text, target, key) {
|
|
28
|
+
const lines = text.split('\n'), values = [];
|
|
29
|
+
let depth = 0, rootDepth = 0, first = true, wrapped = false;
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
const value = line.trim();
|
|
32
|
+
if (value === '')
|
|
33
|
+
continue;
|
|
34
|
+
if (first) {
|
|
35
|
+
first = false;
|
|
36
|
+
if (value.endsWith(' = {')) {
|
|
37
|
+
if (value !== `${target} = {`)
|
|
38
|
+
return undefined;
|
|
39
|
+
depth = 1;
|
|
40
|
+
rootDepth = 1;
|
|
41
|
+
wrapped = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (wrapped && depth === 0)
|
|
46
|
+
return undefined;
|
|
47
|
+
if (value === '}') {
|
|
48
|
+
if (depth === 0)
|
|
49
|
+
return undefined;
|
|
50
|
+
depth -= 1;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const prefix = `${key} = `;
|
|
54
|
+
if (depth === rootDepth && value.startsWith(prefix))
|
|
55
|
+
values.push(value.slice(prefix.length));
|
|
56
|
+
if (value.endsWith(' = {'))
|
|
57
|
+
depth += 1;
|
|
58
|
+
}
|
|
59
|
+
return depth === 0 && values.length === 1 ? values[0] : undefined;
|
|
60
|
+
}
|
|
61
|
+
function assertArguments(args, input) {
|
|
62
|
+
if (!input.nodePath || !input.dshPath || !input.dshSha256 || !Array.isArray(args)
|
|
63
|
+
|| !args.every(arg => typeof arg === 'string'))
|
|
64
|
+
fail('service executable identity is missing');
|
|
65
|
+
const offset = args[1] === '--disable-warning=ExperimentalWarning' ? 2 : 1;
|
|
66
|
+
const node = args[0], dsh = args[offset];
|
|
67
|
+
if (args.length !== offset + 4 || typeof node !== 'string' || typeof dsh !== 'string' || !isAbsolute(node) || !isAbsolute(dsh)
|
|
68
|
+
|| realpathSync(node) !== input.nodePath || realpathSync(dsh) !== input.dshPath
|
|
69
|
+
|| args[offset + 1] !== '--profile' || args[offset + 2] !== input.profile || args[offset + 3] !== '--no-open'
|
|
70
|
+
|| createHash('sha256').update(readFileSync(input.dshPath)).digest('hex') !== input.dshSha256) {
|
|
71
|
+
fail('service command differs from the selected Node and DSH installation');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** A missing job is distinct from a failed launchctl query. Never stop a job
|
|
75
|
+
* belonging to another Home just because its profile label is the same. */
|
|
76
|
+
export function inspectNativeLaunchdDetail(input, command = run) {
|
|
77
|
+
const expected = identity(input), result = command('/bin/launchctl', ['print', expected.target]);
|
|
78
|
+
if (result.status !== 0) {
|
|
79
|
+
if (result.status === 113 && /Could not find service/iu.test(result.stderr)) {
|
|
80
|
+
return { registered: false, pid: 0, running: false, state: null, lastExitCode: null };
|
|
81
|
+
}
|
|
82
|
+
fail('cannot inspect the user service');
|
|
83
|
+
}
|
|
84
|
+
if (scalar(result.stdout, 'path') !== expected.plistPath || scalar(result.stdout, 'working directory') !== expected.cwd
|
|
85
|
+
|| scalar(result.stdout, 'DSH_HOME', ' => ') !== input.dshHome)
|
|
86
|
+
fail('loaded service belongs to another installation');
|
|
87
|
+
if (/^\s*(?:NODE_OPTIONS|NODE_PATH|DYLD_[A-Z_]+|LD_PRELOAD|LD_LIBRARY_PATH) =>/mu.test(result.stdout)) {
|
|
88
|
+
fail('loaded service has an unexpected execution environment');
|
|
89
|
+
}
|
|
90
|
+
const argumentsBlock = /^\s*arguments = \{\n([\s\S]*?)^\s*\}/mu.exec(result.stdout);
|
|
91
|
+
assertArguments(argumentsBlock?.[1]?.split('\n').map(line => line.trim()).filter(Boolean), input);
|
|
92
|
+
if (realpathSync(scalar(result.stdout, 'program') ?? '') !== input.nodePath)
|
|
93
|
+
fail('loaded service program differs');
|
|
94
|
+
const raw = scalar(result.stdout, 'pid'), pid = raw === undefined ? 0 : Number(raw);
|
|
95
|
+
if (!Number.isSafeInteger(pid) || pid < 0 || pid === 1)
|
|
96
|
+
fail('invalid service process identity');
|
|
97
|
+
const state = rootScalar(result.stdout, expected.target, 'state') ?? null;
|
|
98
|
+
return { registered: true, pid, running: state === 'running' && pid > 1, state,
|
|
99
|
+
lastExitCode: rootScalar(result.stdout, expected.target, 'last exit code') ?? null };
|
|
100
|
+
}
|
|
101
|
+
export function inspectNativeLaunchd(input, command = run) {
|
|
102
|
+
const { registered, pid } = inspectNativeLaunchdDetail(input, command);
|
|
103
|
+
return { registered, pid };
|
|
104
|
+
}
|
|
105
|
+
/** Validate an existing plist before recording it for rollback. The loaded job
|
|
106
|
+
* is independently checked by inspectNativeLaunchd. */
|
|
107
|
+
export function assertNativeLaunchdPlist(bytes, input, command = run) {
|
|
108
|
+
// plutil receives the already-read bytes via an argument-free stdin call in
|
|
109
|
+
// production; tests may supply a parsed response without executing launchd.
|
|
110
|
+
const result = command === run ? (() => {
|
|
111
|
+
const child = spawnSync('/usr/bin/plutil', ['-convert', 'json', '-o', '-', '--', '-'], { input: bytes, encoding: 'utf8', timeout: 10_000, maxBuffer: 262_144, env: { PATH: '/usr/bin:/bin' } });
|
|
112
|
+
return { status: child.status, stdout: child.stdout ?? '', stderr: child.stderr ?? '' };
|
|
113
|
+
})() : command('/usr/bin/plutil', ['-convert', 'json', '-o', '-', '--', '-']);
|
|
114
|
+
if (result.status !== 0)
|
|
115
|
+
fail('invalid LaunchAgent plist');
|
|
116
|
+
const value = JSON.parse(result.stdout), expected = identity(input);
|
|
117
|
+
const fields = new Set(['Label', 'ProgramArguments', 'EnvironmentVariables', 'WorkingDirectory',
|
|
118
|
+
'StandardOutPath', 'StandardErrorPath', 'LimitLoadToSessionType', 'ProcessType', 'RunAtLoad',
|
|
119
|
+
'KeepAlive', 'ThrottleInterval', 'ExitTimeOut', 'Umask']);
|
|
120
|
+
// Program overrides argv[0]; other launchd keys can change the executable's
|
|
121
|
+
// filesystem or inherited authority. Only our generated execution shape is
|
|
122
|
+
// safe to record as a rollback target.
|
|
123
|
+
if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).some(key => !fields.has(key))
|
|
124
|
+
|| !value.EnvironmentVariables || typeof value.EnvironmentVariables !== 'object'
|
|
125
|
+
|| Object.keys(value.EnvironmentVariables).sort().join(',') !== 'DSH_HOME,PATH'
|
|
126
|
+
|| typeof value.EnvironmentVariables.PATH !== 'string'
|
|
127
|
+
|| !value.EnvironmentVariables.PATH.split(':').every((path) => isAbsolute(path) && !/[\p{Cc}]/u.test(path))
|
|
128
|
+
|| value.StandardOutPath !== expected.stdoutPath || value.StandardErrorPath !== expected.stderrPath
|
|
129
|
+
|| value.LimitLoadToSessionType !== 'Aqua' || value.ProcessType !== 'Background'
|
|
130
|
+
|| value.RunAtLoad !== true || value.KeepAlive !== true || value.ThrottleInterval !== 10
|
|
131
|
+
|| value.ExitTimeOut !== 30 || value.Umask !== 63)
|
|
132
|
+
fail('plist execution settings differ from the managed LaunchAgent');
|
|
133
|
+
if (value.Label !== expected.label || value.WorkingDirectory !== expected.cwd
|
|
134
|
+
|| value.EnvironmentVariables?.DSH_HOME !== input.dshHome)
|
|
135
|
+
fail('plist belongs to another installation');
|
|
136
|
+
assertArguments(value.ProgramArguments, input);
|
|
137
|
+
}
|
|
138
|
+
export async function stopNativeLaunchd(input, signal, command = run) {
|
|
139
|
+
const expected = identity(input);
|
|
140
|
+
const initial = inspectNativeLaunchd(input, command);
|
|
141
|
+
if (!initial.registered)
|
|
142
|
+
return;
|
|
143
|
+
const stopped = command('/bin/launchctl', ['bootout', expected.target]);
|
|
144
|
+
// bootout can report a racing removal, but the job must actually disappear.
|
|
145
|
+
for (let attempt = 0; attempt < 400; attempt++) {
|
|
146
|
+
signal.throwIfAborted();
|
|
147
|
+
if (!inspectNativeLaunchd(input, command).registered) {
|
|
148
|
+
// Registry removal alone is insufficient: launchd may still be waiting
|
|
149
|
+
// for the old process to exit. A reused PID conservatively blocks setup.
|
|
150
|
+
if (initial.pid === 0)
|
|
151
|
+
return;
|
|
152
|
+
try {
|
|
153
|
+
process.kill(initial.pid, 0);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
if (error.code === 'ESRCH')
|
|
157
|
+
return;
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (stopped.status !== 0)
|
|
162
|
+
fail('service did not stop');
|
|
163
|
+
await delay(100, undefined, { signal });
|
|
164
|
+
}
|
|
165
|
+
fail('service remained registered after bootout');
|
|
166
|
+
}
|
|
167
|
+
export async function startNativeLaunchd(input, signal, command = run) {
|
|
168
|
+
const expected = identity(input);
|
|
169
|
+
if (inspectNativeLaunchd(input, command).registered)
|
|
170
|
+
fail('service is still registered before bootstrap');
|
|
171
|
+
if (command('/bin/launchctl', ['enable', expected.target]).status !== 0)
|
|
172
|
+
fail('cannot enable user service');
|
|
173
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
174
|
+
signal.throwIfAborted();
|
|
175
|
+
const result = command('/bin/launchctl', ['bootstrap', expected.domain, expected.plistPath]);
|
|
176
|
+
if (result.status !== 0 && result.status !== 5)
|
|
177
|
+
fail('cannot bootstrap user service');
|
|
178
|
+
if (inspectNativeLaunchd(input, command).registered)
|
|
179
|
+
return;
|
|
180
|
+
await delay(250, undefined, { signal });
|
|
181
|
+
}
|
|
182
|
+
fail('bootstrap did not register the service');
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=launchd-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd-identity.js","sourceRoot":"","sources":["../src/launchd-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd-target-lock.d.ts","sourceRoot":"","sources":["../src/launchd-target-lock.ts"],"names":[],"mappings":"AAMA,uEAAuE;AACvE,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACpE,OAAO,CAAC,CAAC,CAAC,CAuCZ"}
|