@codyswann/lisa 4.70.4 → 4.71.1
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/all/copy-overwrite/scripts/lib/automation-provenance-contract.mjs +174 -0
- package/all/copy-overwrite/scripts/lib/automation-provenance-local.mjs +279 -0
- package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +17 -7
- package/all/copy-overwrite/scripts/lib/github-attestation-provider.mjs +241 -0
- package/all/copy-overwrite/scripts/lib/github-attestation-recovery.mjs +283 -0
- package/all/copy-overwrite/scripts/lib/github-attestation-verifier.mjs +244 -0
- package/all/copy-overwrite/scripts/lib/npm-update-allocate.mjs +289 -0
- package/all/copy-overwrite/scripts/lib/npm-update-authorization.mjs +235 -0
- package/all/copy-overwrite/scripts/lib/npm-update-broker-client.mjs +92 -0
- package/all/copy-overwrite/scripts/lib/npm-update-checkpoint.mjs +241 -0
- package/all/copy-overwrite/scripts/lib/npm-update-contract.mjs +278 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-broker.mjs +234 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-factory.mjs +278 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-recipe.mjs +135 -0
- package/all/copy-overwrite/scripts/lib/npm-update-execution-adapter.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-hooks.mjs +214 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-install.mjs +267 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-proof.mjs +99 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate.mjs +300 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-dispatch.mjs +182 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-grants.mjs +156 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-requests.mjs +221 -0
- package/all/copy-overwrite/scripts/lib/npm-update-github.mjs +214 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper-graph.mjs +238 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper-inventory.mjs +126 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-installation.mjs +116 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-preload.mjs +153 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-provider.mjs +207 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-read-client.mjs +164 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hosted-gate.mjs +300 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hosted-hook.mjs +157 -0
- package/all/copy-overwrite/scripts/lib/npm-update-invariants.mjs +28 -0
- package/all/copy-overwrite/scripts/lib/npm-update-isolation.mjs +11 -0
- package/all/copy-overwrite/scripts/lib/npm-update-leaf-contract.mjs +171 -0
- package/all/copy-overwrite/scripts/lib/npm-update-leaf.mjs +194 -0
- package/all/copy-overwrite/scripts/lib/npm-update-native-process.mjs +155 -0
- package/all/copy-overwrite/scripts/lib/npm-update-npm.mjs +190 -0
- package/all/copy-overwrite/scripts/lib/npm-update-object.mjs +112 -0
- package/all/copy-overwrite/scripts/lib/npm-update-orchestrator.mjs +273 -0
- package/all/copy-overwrite/scripts/lib/npm-update-owner.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-prepare.mjs +263 -0
- package/all/copy-overwrite/scripts/lib/npm-update-process-core.mjs +179 -0
- package/all/copy-overwrite/scripts/lib/npm-update-process.mjs +16 -0
- package/all/copy-overwrite/scripts/lib/npm-update-publication.mjs +258 -0
- package/all/copy-overwrite/scripts/lib/npm-update-publish.mjs +254 -0
- package/all/copy-overwrite/scripts/lib/npm-update-quality.mjs +153 -0
- package/all/copy-overwrite/scripts/lib/npm-update-recovery.mjs +264 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-archive.mjs +204 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-graph.mjs +185 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-transport.mjs +221 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime.mjs +284 -0
- package/all/copy-overwrite/scripts/lib/npm-update-tool-launcher.mjs +287 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-environment.mjs +161 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-inspection.mjs +142 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-lifecycle.mjs +256 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-policy.mjs +266 -0
- package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +230 -36
- package/all/copy-overwrite/scripts/lisa-automation-provenance.mjs +161 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +89 -5
- package/all/copy-overwrite/scripts/lisa-npm-updater.mjs +204 -0
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +48 -123
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +107 -41
- package/all/copy-overwrite/scripts/npm-updater-gate-runtime.json +1 -0
- package/all/copy-overwrite/scripts/npm-updater-gate-supervisor.c +121 -0
- package/all/copy-overwrite/scripts/npm-updater-gate.Dockerfile +49 -0
- package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +1085 -0
- package/dist/codex/scripts/block-no-verify.sh +89 -5
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +604 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +159 -11
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/block-no-verify.sh +89 -5
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/lisa/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/src/base/hooks/block-no-verify.sh +89 -5
- package/scripts/check-shipped-surface-removals.mjs +96 -24
- package/scripts/generate-npm-updater-helper-graph.mjs +184 -0
- package/scripts/two-channel-couplings.json +31 -7
- package/typescript/copy-contents/.husky/commit-msg +18 -0
- package/typescript/copy-overwrite/.prettierignore +2 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
// Do not edit directly — durable changes belong upstream in Lisa.
|
|
3
|
+
|
|
4
|
+
/** One fixed source inventory is shared by the closed validator and reproducible generator. */
|
|
5
|
+
const COMMON = [
|
|
6
|
+
"lisa-work-item.mjs",
|
|
7
|
+
"lisa-automation-provenance.mjs",
|
|
8
|
+
"lisa-rails-prepush.mjs",
|
|
9
|
+
"lisa-history-secrets.mjs",
|
|
10
|
+
"lisa-gates.mjs",
|
|
11
|
+
"lisa-run-gates.mjs",
|
|
12
|
+
"lisa-commit-msg-gates.mjs",
|
|
13
|
+
"lisa-test-node.mjs",
|
|
14
|
+
"lib/invoked-as-script.mjs",
|
|
15
|
+
"lib/bounded-spawn.mjs",
|
|
16
|
+
"lib/process-tree-runner.mjs",
|
|
17
|
+
"lib/windows-process-job.mjs",
|
|
18
|
+
"lib/windows-process-job.ps1",
|
|
19
|
+
"lib/windows-process-job.cs",
|
|
20
|
+
"lib/kill-marks.mjs",
|
|
21
|
+
"lib/gate-failure-diagnosis.mjs",
|
|
22
|
+
"lib/worktree-dependencies.mjs",
|
|
23
|
+
"lib/history-secret-git.mjs",
|
|
24
|
+
"lib/history-secret-scanner.mjs",
|
|
25
|
+
"lib/history-secret-evidence.mjs",
|
|
26
|
+
"lib/history-secret-evidence-shape.mjs",
|
|
27
|
+
"lib/history-secret-policy.mjs",
|
|
28
|
+
"lib/github-attestation-verifier.mjs",
|
|
29
|
+
"lib/github-attestation-provider.mjs",
|
|
30
|
+
"lib/github-attestation-recovery.mjs",
|
|
31
|
+
"lib/automation-provenance-contract.mjs",
|
|
32
|
+
"lib/automation-provenance-local.mjs",
|
|
33
|
+
];
|
|
34
|
+
const RAILS = [
|
|
35
|
+
"lisa-clean-git-env.sh",
|
|
36
|
+
"lisa-scratch-run.sh",
|
|
37
|
+
"check-threshold-ratchet.mjs",
|
|
38
|
+
"threshold-ratchet-families.mjs",
|
|
39
|
+
"threshold-ratchet-compare.mjs",
|
|
40
|
+
];
|
|
41
|
+
const PRODUCER = [
|
|
42
|
+
"allocate",
|
|
43
|
+
"authorization",
|
|
44
|
+
"broker-client",
|
|
45
|
+
"checkpoint",
|
|
46
|
+
"contract",
|
|
47
|
+
"controller-broker",
|
|
48
|
+
"controller-factory",
|
|
49
|
+
"controller-recipe",
|
|
50
|
+
"execution-adapter",
|
|
51
|
+
"gate-hooks",
|
|
52
|
+
"gate-install",
|
|
53
|
+
"gate-proof",
|
|
54
|
+
"gate",
|
|
55
|
+
"gh-dispatch",
|
|
56
|
+
"gh-grants",
|
|
57
|
+
"gh-requests",
|
|
58
|
+
"github",
|
|
59
|
+
"helper",
|
|
60
|
+
"helper-graph",
|
|
61
|
+
"helper-inventory",
|
|
62
|
+
"hosted-gate",
|
|
63
|
+
"hosted-hook",
|
|
64
|
+
"hook-installation",
|
|
65
|
+
"hook-preload",
|
|
66
|
+
"hook-provider",
|
|
67
|
+
"hook-read-client",
|
|
68
|
+
"invariants",
|
|
69
|
+
"isolation",
|
|
70
|
+
"leaf",
|
|
71
|
+
"leaf-contract",
|
|
72
|
+
"npm",
|
|
73
|
+
"native-process",
|
|
74
|
+
"object",
|
|
75
|
+
"orchestrator",
|
|
76
|
+
"owner",
|
|
77
|
+
"prepare",
|
|
78
|
+
"process",
|
|
79
|
+
"process-core",
|
|
80
|
+
"publication",
|
|
81
|
+
"publish",
|
|
82
|
+
"quality",
|
|
83
|
+
"recovery",
|
|
84
|
+
"runtime-archive",
|
|
85
|
+
"runtime-graph",
|
|
86
|
+
"runtime-transport",
|
|
87
|
+
"runtime",
|
|
88
|
+
"tool-launcher",
|
|
89
|
+
"worker-environment",
|
|
90
|
+
"worker-inspection",
|
|
91
|
+
"worker-lifecycle",
|
|
92
|
+
"worker-policy",
|
|
93
|
+
];
|
|
94
|
+
export const HELPER_CONTROLS = [
|
|
95
|
+
"lib/npm-update-helper-graph.mjs",
|
|
96
|
+
"npm-updater-helper-graph.json",
|
|
97
|
+
];
|
|
98
|
+
export const CLASSIFIER_MEMBERS = [
|
|
99
|
+
"plugins/lisa/scripts/intake-blocker-reprobe.mjs",
|
|
100
|
+
"plugins/lisa/scripts/intake-prework-denominator.mjs",
|
|
101
|
+
];
|
|
102
|
+
export const OWNER_MEMBERS = [
|
|
103
|
+
"plugins/lisa/hooks/auto-update.mjs",
|
|
104
|
+
"plugins/lisa/hooks/auto-update.sh",
|
|
105
|
+
"plugins/lisa/.codex-plugin/hooks.json",
|
|
106
|
+
];
|
|
107
|
+
export const HELPER_PACKAGE_MEMBERS = CLASSIFIER_MEMBERS.map(
|
|
108
|
+
member => `package/${member}`
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
/** Only reviewed upstream templates and fixed classifier package members can enter the inventory. */
|
|
112
|
+
export function managedTemplateMembers() {
|
|
113
|
+
return new Map([
|
|
114
|
+
...[
|
|
115
|
+
...COMMON,
|
|
116
|
+
"lisa-npm-updater.mjs",
|
|
117
|
+
"npm-updater-helper-graph.json",
|
|
118
|
+
"npm-updater-gate-runtime.json",
|
|
119
|
+
"npm-updater-gate-supervisor.c",
|
|
120
|
+
"npm-updater-gate.Dockerfile",
|
|
121
|
+
...PRODUCER.map(name => `lib/npm-update-${name}.mjs`),
|
|
122
|
+
].map(member => [member, `all/copy-overwrite/scripts/${member}`]),
|
|
123
|
+
...RAILS.map(member => [member, `rails/copy-overwrite/scripts/${member}`]),
|
|
124
|
+
["lisa-mutation.sh", "rails/copy-contents/scripts/lisa-mutation.sh"],
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
// Do not edit directly — durable changes belong upstream in Lisa.
|
|
3
|
+
|
|
4
|
+
/** Independent Git or registry archive authority qualifies canonical helpers before import. */
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
+
import { existsSync, lstatSync, realpathSync } from "node:fs";
|
|
10
|
+
import { required, VERSION, OBJECT } from "./npm-update-contract.mjs";
|
|
11
|
+
import {
|
|
12
|
+
readBytes,
|
|
13
|
+
runProcess,
|
|
14
|
+
withPrivateRoot,
|
|
15
|
+
} from "./npm-update-process-core.mjs";
|
|
16
|
+
import {
|
|
17
|
+
runNpm,
|
|
18
|
+
archiveIntegrity,
|
|
19
|
+
findLisaPackageOwner,
|
|
20
|
+
} from "./npm-update-npm.mjs";
|
|
21
|
+
import {
|
|
22
|
+
CLASSIFIER_MEMBERS as MEMBERS,
|
|
23
|
+
OWNER_MEMBERS,
|
|
24
|
+
} from "./npm-update-helper-inventory.mjs";
|
|
25
|
+
import {
|
|
26
|
+
managedTemplateMembers,
|
|
27
|
+
helperManifest,
|
|
28
|
+
controllerMembers,
|
|
29
|
+
managedControllerSelection,
|
|
30
|
+
auditControllerClosure,
|
|
31
|
+
assertManagedSelection,
|
|
32
|
+
classifierGraphMatches,
|
|
33
|
+
} from "./npm-update-helper-graph.mjs";
|
|
34
|
+
|
|
35
|
+
const PACKAGE = "@codyswann/lisa";
|
|
36
|
+
|
|
37
|
+
/** Native package resolution supports both upstream and actual emitted managed layouts. */
|
|
38
|
+
export function helperOwner() {
|
|
39
|
+
const local = findLisaPackageOwner(fileURLToPath(import.meta.url));
|
|
40
|
+
if (local) return { ...local, source: existsSync(join(local.root, ".git")) };
|
|
41
|
+
let entry;
|
|
42
|
+
try {
|
|
43
|
+
entry = createRequire(import.meta.url).resolve(PACKAGE);
|
|
44
|
+
} catch {
|
|
45
|
+
throw new Error(
|
|
46
|
+
"npm updater: qualified installed Lisa helper is unavailable"
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const installed = findLisaPackageOwner(entry);
|
|
50
|
+
required(installed, "resolved helper has no canonical Lisa package owner");
|
|
51
|
+
return { ...installed, source: false };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** The fixed canonical import graph must stay inside its independently qualified package. */
|
|
55
|
+
function helperBytes(root, members) {
|
|
56
|
+
return members.map(relative => {
|
|
57
|
+
const file = join(root, relative);
|
|
58
|
+
required(
|
|
59
|
+
realpathSync(file) === file &&
|
|
60
|
+
lstatSync(file).isFile() &&
|
|
61
|
+
!lstatSync(file).isSymbolicLink(),
|
|
62
|
+
"canonical helper is aliased or absent"
|
|
63
|
+
);
|
|
64
|
+
return readBytes(file, 1_048_576, false);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Current committed Git identity supplies source-local authority; production pins the approved signer. */
|
|
69
|
+
async function sourceAuthority(owner, config, bytes, members) {
|
|
70
|
+
const env = {
|
|
71
|
+
PATH: process.env.PATH,
|
|
72
|
+
HOME: "/nonexistent",
|
|
73
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
74
|
+
};
|
|
75
|
+
const git = args =>
|
|
76
|
+
runProcess("git", args, { cwd: owner.root, env, maximum: 1_048_576 });
|
|
77
|
+
const head = (await git(["rev-parse", "HEAD"])).stdout.toString().trim();
|
|
78
|
+
const expected = config.automationProvenance?.signerDigest ?? head;
|
|
79
|
+
required(
|
|
80
|
+
typeof expected === "string" && OBJECT.test(expected),
|
|
81
|
+
"approved helper Git identity is unavailable"
|
|
82
|
+
);
|
|
83
|
+
const trusted = [];
|
|
84
|
+
for (let index = 0; index < members.length; index++) {
|
|
85
|
+
let blob;
|
|
86
|
+
try {
|
|
87
|
+
blob = (await git(["show", `${expected}:${members[index]}`])).stdout;
|
|
88
|
+
} catch (cause) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`npm updater: approved helper Git member unavailable: ${members[index]}`,
|
|
91
|
+
{ cause }
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (bytes)
|
|
95
|
+
required(
|
|
96
|
+
blob.equals(bytes[index]),
|
|
97
|
+
"canonical helper differs from approved Git blob"
|
|
98
|
+
);
|
|
99
|
+
trusted.push(blob);
|
|
100
|
+
}
|
|
101
|
+
return trusted;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Official release identity and integrity authenticate both fixed members without extracting files. */
|
|
105
|
+
async function releaseAuthority(owner, config, bytes, members) {
|
|
106
|
+
const digest = config.automationProvenance?.signerDigest;
|
|
107
|
+
required(
|
|
108
|
+
typeof digest === "string" &&
|
|
109
|
+
OBJECT.test(digest) &&
|
|
110
|
+
VERSION.test(owner.metadata.version),
|
|
111
|
+
"approved release identity is unavailable"
|
|
112
|
+
);
|
|
113
|
+
await withPrivateRoot(async (root, env) => {
|
|
114
|
+
const registry = JSON.parse(
|
|
115
|
+
(
|
|
116
|
+
await runNpm(
|
|
117
|
+
["view", `${PACKAGE}@${owner.metadata.version}`, "--json"],
|
|
118
|
+
{ env, maximum: 1_048_576 }
|
|
119
|
+
)
|
|
120
|
+
).stdout
|
|
121
|
+
);
|
|
122
|
+
required(
|
|
123
|
+
registry.name === PACKAGE &&
|
|
124
|
+
registry.version === owner.metadata.version &&
|
|
125
|
+
registry.gitHead === digest &&
|
|
126
|
+
typeof registry.dist?.integrity === "string",
|
|
127
|
+
"registry helper identity differs from approved source"
|
|
128
|
+
);
|
|
129
|
+
const packed = JSON.parse(
|
|
130
|
+
(
|
|
131
|
+
await runNpm(
|
|
132
|
+
[
|
|
133
|
+
"pack",
|
|
134
|
+
`${PACKAGE}@${owner.metadata.version}`,
|
|
135
|
+
"--ignore-scripts",
|
|
136
|
+
"--json",
|
|
137
|
+
"--pack-destination",
|
|
138
|
+
root,
|
|
139
|
+
],
|
|
140
|
+
{ cwd: root, env, timeout: 120_000, maximum: 1_048_576 }
|
|
141
|
+
)
|
|
142
|
+
).stdout
|
|
143
|
+
);
|
|
144
|
+
const filename = `codyswann-lisa-${owner.metadata.version}.tgz`;
|
|
145
|
+
required(
|
|
146
|
+
Array.isArray(packed) &&
|
|
147
|
+
packed.length === 1 &&
|
|
148
|
+
packed[0].filename === filename,
|
|
149
|
+
"registry archive selection differs"
|
|
150
|
+
);
|
|
151
|
+
const archive = join(root, filename);
|
|
152
|
+
required(
|
|
153
|
+
archiveIntegrity(archive) === registry.dist.integrity,
|
|
154
|
+
"actual helper archive registry integrity differs"
|
|
155
|
+
);
|
|
156
|
+
for (let index = 0; index < members.length; index++) {
|
|
157
|
+
const member = `package/${members[index]}`;
|
|
158
|
+
const listing = await runProcess("tar", ["-tzf", archive, "--", member], {
|
|
159
|
+
env,
|
|
160
|
+
maximum: 65_536,
|
|
161
|
+
});
|
|
162
|
+
required(
|
|
163
|
+
listing.stdout.toString() === `${member}\n`,
|
|
164
|
+
"canonical archive member is missing or ambiguous"
|
|
165
|
+
);
|
|
166
|
+
const result = await runProcess("tar", ["-xOf", archive, "--", member], {
|
|
167
|
+
env,
|
|
168
|
+
maximum: 1_048_576,
|
|
169
|
+
});
|
|
170
|
+
required(
|
|
171
|
+
result.stdout.equals(bytes[index]),
|
|
172
|
+
"installed canonical helper differs from authenticated archive"
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Only fixed canonical lifecycle files can be selected by trusted callers. */
|
|
179
|
+
export async function qualifiedHelperFiles(config, members) {
|
|
180
|
+
required(
|
|
181
|
+
Array.isArray(members) &&
|
|
182
|
+
members.length > 0 &&
|
|
183
|
+
members.length <= 5 &&
|
|
184
|
+
new Set(members).size === members.length &&
|
|
185
|
+
members.every(member => [...MEMBERS, ...OWNER_MEMBERS].includes(member)),
|
|
186
|
+
"unsupported canonical helper selection"
|
|
187
|
+
);
|
|
188
|
+
const owner = helperOwner();
|
|
189
|
+
const bytes = helperBytes(owner.root, members);
|
|
190
|
+
if (owner.source) await sourceAuthority(owner, config, bytes, members);
|
|
191
|
+
else await releaseAuthority(owner, config, bytes, members);
|
|
192
|
+
return {
|
|
193
|
+
...owner,
|
|
194
|
+
bytes: new Map(members.map((member, index) => [member, bytes[index]])),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Emitted hook bytes gain authority only from exact independently authenticated templates. */
|
|
199
|
+
export async function qualifiedManagedFiles(cwd, config, members) {
|
|
200
|
+
const inventory = managedTemplateMembers();
|
|
201
|
+
required(
|
|
202
|
+
Array.isArray(members) &&
|
|
203
|
+
members.length > 0 &&
|
|
204
|
+
members.length <= inventory.size &&
|
|
205
|
+
new Set(members).size === members.length &&
|
|
206
|
+
members.every(member => inventory.has(member)),
|
|
207
|
+
"unsupported managed helper selection"
|
|
208
|
+
);
|
|
209
|
+
required(
|
|
210
|
+
OBJECT.test(config.automationProvenance?.signerDigest ?? ""),
|
|
211
|
+
"immutable managed helper authority is missing"
|
|
212
|
+
);
|
|
213
|
+
required(
|
|
214
|
+
typeof cwd === "string" && cwd.startsWith("/") && realpathSync(cwd) === cwd,
|
|
215
|
+
"managed workspace is aliased or unavailable"
|
|
216
|
+
);
|
|
217
|
+
const owner = helperOwner();
|
|
218
|
+
const templates = members.map(member => inventory.get(member));
|
|
219
|
+
const bytes = owner.source
|
|
220
|
+
? await sourceAuthority(owner, config, null, templates)
|
|
221
|
+
: helperBytes(owner.root, templates);
|
|
222
|
+
if (!owner.source) await releaseAuthority(owner, config, bytes, templates);
|
|
223
|
+
const graph = {};
|
|
224
|
+
for (let index = 0; index < members.length; index++) {
|
|
225
|
+
const file = join(cwd, "scripts", members[index]);
|
|
226
|
+
required(
|
|
227
|
+
realpathSync(file) === file &&
|
|
228
|
+
!lstatSync(file).isSymbolicLink() &&
|
|
229
|
+
readBytes(file, 1_048_576, false).equals(bytes[index]),
|
|
230
|
+
"managed consumer helper differs from authenticated template"
|
|
231
|
+
);
|
|
232
|
+
graph[file] = createHash("sha256").update(bytes[index]).digest("hex");
|
|
233
|
+
}
|
|
234
|
+
return graph;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Authenticate one owner's control, manifest and complete byte graph before selecting controller entries. */
|
|
238
|
+
export async function qualifiedControllerGraph(cwd, config, entries) {
|
|
239
|
+
assertManagedSelection(entries);
|
|
240
|
+
const controls = [
|
|
241
|
+
"lib/npm-update-helper-graph.mjs",
|
|
242
|
+
"npm-updater-helper-graph.json",
|
|
243
|
+
];
|
|
244
|
+
const checked = await qualifiedManagedFiles(cwd, config, controls);
|
|
245
|
+
const manifest = helperManifest(
|
|
246
|
+
readBytes(join(cwd, "scripts", controls[1]), 262_144, false)
|
|
247
|
+
);
|
|
248
|
+
const members = controllerMembers(manifest);
|
|
249
|
+
const managed = members.filter(member => !member.startsWith("package/"));
|
|
250
|
+
Object.assign(checked, await qualifiedManagedFiles(cwd, config, managed));
|
|
251
|
+
const owner = await qualifiedHelperFiles(config, MEMBERS);
|
|
252
|
+
const authenticated = new Map();
|
|
253
|
+
const paths = new Map();
|
|
254
|
+
for (const member of members) {
|
|
255
|
+
const packaged = member.startsWith("package/");
|
|
256
|
+
const relative = packaged ? member.slice("package/".length) : member;
|
|
257
|
+
const file = join(packaged ? owner.root : join(cwd, "scripts"), relative);
|
|
258
|
+
const bytes = readBytes(file, 1_048_576, false);
|
|
259
|
+
required(
|
|
260
|
+
packaged
|
|
261
|
+
? bytes.equals(owner.bytes.get(relative))
|
|
262
|
+
: createHash("sha256").update(bytes).digest("hex") === checked[file],
|
|
263
|
+
"authenticated controller helper changed during selection"
|
|
264
|
+
);
|
|
265
|
+
authenticated.set(member, bytes);
|
|
266
|
+
paths.set(member, file);
|
|
267
|
+
}
|
|
268
|
+
// Audit every authenticated member, then select the actual complete entry closure.
|
|
269
|
+
auditControllerClosure(manifest, authenticated);
|
|
270
|
+
const selected = managedControllerSelection(manifest, authenticated, entries);
|
|
271
|
+
return Object.fromEntries(
|
|
272
|
+
[...selected].map(member => [
|
|
273
|
+
paths.get(member),
|
|
274
|
+
createHash("sha256").update(authenticated.get(member)).digest("hex"),
|
|
275
|
+
])
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** No canonical package code is imported until independent authority qualifies its fixed graph. */
|
|
280
|
+
export async function canonicalClassifier(config) {
|
|
281
|
+
const owner = await qualifiedHelperFiles(config, MEMBERS);
|
|
282
|
+
required(
|
|
283
|
+
classifierGraphMatches(MEMBERS.map(member => owner.bytes.get(member))),
|
|
284
|
+
"canonical helper import graph differs"
|
|
285
|
+
);
|
|
286
|
+
const module = await import(pathToFileURL(join(owner.root, MEMBERS[0])).href);
|
|
287
|
+
required(
|
|
288
|
+
typeof module.humanGateVerdict === "function",
|
|
289
|
+
"canonical hold classifier is unavailable"
|
|
290
|
+
);
|
|
291
|
+
return module.humanGateVerdict;
|
|
292
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
// Do not edit directly — durable changes belong upstream in Lisa.
|
|
3
|
+
|
|
4
|
+
/** Original manager readback preserves installed bytes; dispatch qualification is a separate obligation. */
|
|
5
|
+
import { lstatSync, realpathSync } from "node:fs";
|
|
6
|
+
import { join, resolve } from "node:path";
|
|
7
|
+
import { keys, required } from "./npm-update-contract.mjs";
|
|
8
|
+
import { readBytes } from "./npm-update-process.mjs";
|
|
9
|
+
import { sha256 } from "./github-attestation-verifier.mjs";
|
|
10
|
+
|
|
11
|
+
const HOOKS = ["pre-commit", "prepare-commit-msg", "commit-msg", "pre-push"];
|
|
12
|
+
const HEX = /^[a-f0-9]{64}$/;
|
|
13
|
+
|
|
14
|
+
/** Native Git resolves the real installation, including its configured path, without a configuration override. */
|
|
15
|
+
async function installedDirectory(cwd, command) {
|
|
16
|
+
const result = await command(["rev-parse", "--git-path", "hooks"]);
|
|
17
|
+
required(
|
|
18
|
+
Buffer.isBuffer(result.stdout) && result.stdout.length <= 4096,
|
|
19
|
+
"installed hook path readback is unbounded"
|
|
20
|
+
);
|
|
21
|
+
const text = new TextDecoder("utf8", { fatal: true }).decode(result.stdout);
|
|
22
|
+
required(
|
|
23
|
+
text.endsWith("\n") && !/[\n\r\0]/.test(text.slice(0, -1)),
|
|
24
|
+
"installed hook path is unsupported"
|
|
25
|
+
);
|
|
26
|
+
const directory = resolve(cwd, text.slice(0, -1));
|
|
27
|
+
required(
|
|
28
|
+
directory.startsWith(`${cwd}/`) &&
|
|
29
|
+
realpathSync(directory) === directory &&
|
|
30
|
+
lstatSync(directory).isDirectory() &&
|
|
31
|
+
!lstatSync(directory).isSymbolicLink(),
|
|
32
|
+
"installed hook directory escapes its checkout or is aliased"
|
|
33
|
+
);
|
|
34
|
+
return directory;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** A separately observed manager installation binds all hooks that an ordinary commit/push can execute. */
|
|
38
|
+
function checkedWrappers(directory, authority) {
|
|
39
|
+
keys(authority, ["manager", "wrappers"]);
|
|
40
|
+
required(
|
|
41
|
+
["husky", "lefthook"].includes(authority.manager),
|
|
42
|
+
"unsupported original hook manager"
|
|
43
|
+
);
|
|
44
|
+
keys(authority.wrappers, HOOKS);
|
|
45
|
+
for (const name of HOOKS) {
|
|
46
|
+
const file = join(directory, name);
|
|
47
|
+
const stat = lstatSync(file);
|
|
48
|
+
required(
|
|
49
|
+
stat.isFile() &&
|
|
50
|
+
!stat.isSymbolicLink() &&
|
|
51
|
+
realpathSync(file) === file &&
|
|
52
|
+
(stat.mode & 0o111) !== 0,
|
|
53
|
+
"original installed wrapper is missing, nonexecutable or aliased"
|
|
54
|
+
);
|
|
55
|
+
required(
|
|
56
|
+
HEX.test(authority.wrappers[name]) &&
|
|
57
|
+
sha256(readBytes(file, 65_536, false)) === authority.wrappers[name],
|
|
58
|
+
"original installed wrapper differs from qualified installation"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Committed manager configuration is unchanged; this hash does not bless application commands. */
|
|
64
|
+
async function sourceReadback(cwd, command, source) {
|
|
65
|
+
const bytes = readBytes(join(cwd, source), 1_048_576, false);
|
|
66
|
+
const committed = await command(["show", `HEAD:${source}`]);
|
|
67
|
+
required(
|
|
68
|
+
Buffer.isBuffer(committed.stdout) && bytes.equals(committed.stdout),
|
|
69
|
+
"original hook source differs from committed source"
|
|
70
|
+
);
|
|
71
|
+
return sha256(bytes);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Lefthook requires actual installation receipts; legacy Husky source readback retains its original contract. */
|
|
75
|
+
export async function originalHookInstallation(cwd, command, authority) {
|
|
76
|
+
required(realpathSync(cwd) === cwd, "original hook checkout is aliased");
|
|
77
|
+
const directory = await installedDirectory(cwd, command);
|
|
78
|
+
const husky = [join(cwd, ".husky"), join(cwd, ".husky/_")].includes(
|
|
79
|
+
directory
|
|
80
|
+
);
|
|
81
|
+
if (authority !== undefined) {
|
|
82
|
+
required(
|
|
83
|
+
authority.manager === (husky ? "husky" : "lefthook"),
|
|
84
|
+
"original hook manager differs"
|
|
85
|
+
);
|
|
86
|
+
checkedWrappers(directory, authority);
|
|
87
|
+
}
|
|
88
|
+
if (!husky) {
|
|
89
|
+
required(
|
|
90
|
+
authority !== undefined,
|
|
91
|
+
"original Lefthook installation qualification is absent"
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
const source = husky ? ".husky/pre-push" : "lefthook.yml";
|
|
95
|
+
const path = join(directory, "pre-push");
|
|
96
|
+
const stat = lstatSync(path);
|
|
97
|
+
required(
|
|
98
|
+
stat.isFile() &&
|
|
99
|
+
!stat.isSymbolicLink() &&
|
|
100
|
+
realpathSync(path) === path &&
|
|
101
|
+
(stat.mode & 0o111) !== 0,
|
|
102
|
+
"original pre-push installation is missing or aliased"
|
|
103
|
+
);
|
|
104
|
+
return {
|
|
105
|
+
manager: husky ? "husky" : "lefthook",
|
|
106
|
+
path,
|
|
107
|
+
source,
|
|
108
|
+
sourceSha256: await sourceReadback(cwd, command, source),
|
|
109
|
+
wrapperSha256: sha256(readBytes(path, 65_536, false)),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Compatibility export returns the same original executable path; no replacement gate is constructed. */
|
|
114
|
+
export async function originalPrePush(cwd, command, authority) {
|
|
115
|
+
return (await originalHookInstallation(cwd, command, authority)).path;
|
|
116
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
// Do not edit directly — durable changes belong upstream in Lisa.
|
|
3
|
+
|
|
4
|
+
/** Read-only provider routing instruments authenticated hook code, not arbitrary application Node programs. */
|
|
5
|
+
import childProcess from "node:child_process";
|
|
6
|
+
import { syncBuiltinESMExports } from "node:module";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
+
import {
|
|
10
|
+
hostedHookContext,
|
|
11
|
+
hookEntry,
|
|
12
|
+
hookReadSlot,
|
|
13
|
+
tokenFreeHookEnvironment,
|
|
14
|
+
} from "./npm-update-hosted-hook.mjs";
|
|
15
|
+
import { synchronousHookRead } from "./npm-update-hook-read-client.mjs";
|
|
16
|
+
import { required } from "./npm-update-contract.mjs";
|
|
17
|
+
|
|
18
|
+
const ENTRY = fileURLToPath(import.meta.url);
|
|
19
|
+
const original = {
|
|
20
|
+
spawn: childProcess.spawn,
|
|
21
|
+
spawnSync: childProcess.spawnSync,
|
|
22
|
+
execFile: childProcess.execFile,
|
|
23
|
+
execFileSync: childProcess.execFileSync,
|
|
24
|
+
};
|
|
25
|
+
const file = process.env.LISA_NPM_HOSTED_HOOK_CONTEXT;
|
|
26
|
+
|
|
27
|
+
function providerCall(context, entry, argv, command, args, options) {
|
|
28
|
+
if (command !== "gh" && command !== context.native.gh.path) return null;
|
|
29
|
+
const slot = hookReadSlot(entry, argv, process.env.LISA_NPM_HOOK_ROLE);
|
|
30
|
+
required(slot !== null, "hook caller has no provider read recipe");
|
|
31
|
+
return synchronousHookRead(
|
|
32
|
+
context,
|
|
33
|
+
slot,
|
|
34
|
+
args,
|
|
35
|
+
options,
|
|
36
|
+
original.spawnSync,
|
|
37
|
+
context.native.node.path
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Canonical children retain instrumentation; application processes receive neither token nor read-context channel. */
|
|
42
|
+
function nativeChild(context, command, args, options) {
|
|
43
|
+
const env = tokenFreeHookEnvironment(options.env ?? process.env);
|
|
44
|
+
delete env.LISA_NPM_HOSTED_HOOK_CONTEXT;
|
|
45
|
+
if (
|
|
46
|
+
command === "node" ||
|
|
47
|
+
command === process.execPath ||
|
|
48
|
+
command === context.native.node.path
|
|
49
|
+
) {
|
|
50
|
+
const cwd = resolve(options.cwd ?? process.cwd());
|
|
51
|
+
const entry = hookEntry(context, args, cwd);
|
|
52
|
+
if (entry) {
|
|
53
|
+
required(
|
|
54
|
+
!args.some(arg =>
|
|
55
|
+
/^(?:-r|--require|--import|--(?:experimental-)?loader)(?:=|$)/.test(
|
|
56
|
+
arg
|
|
57
|
+
)
|
|
58
|
+
),
|
|
59
|
+
"unqualified canonical hook loader"
|
|
60
|
+
);
|
|
61
|
+
env.LISA_NPM_HOSTED_HOOK_CONTEXT = context.file;
|
|
62
|
+
return {
|
|
63
|
+
command: context.native.node.path,
|
|
64
|
+
args: ["--import", pathToFileURL(ENTRY).href, ...args],
|
|
65
|
+
options: { ...options, env },
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { command, args, options: { ...options, env } };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Preserve Node's documented optional argv/options overloads, including native buffers and FDs. */
|
|
73
|
+
function invocationArguments(args, options) {
|
|
74
|
+
return Array.isArray(args)
|
|
75
|
+
? { args, options: options ?? {} }
|
|
76
|
+
: { args: [], options: args ?? {} };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function initialize() {
|
|
80
|
+
required(
|
|
81
|
+
typeof file === "string" && file.length > 0,
|
|
82
|
+
"hosted hook context is absent"
|
|
83
|
+
);
|
|
84
|
+
const context = hostedHookContext(file);
|
|
85
|
+
const argv = [...process.execArgv.slice(2), ...process.argv.slice(1)];
|
|
86
|
+
const entry = hookEntry(context, argv, process.cwd());
|
|
87
|
+
required(
|
|
88
|
+
entry !== null &&
|
|
89
|
+
process.execArgv[0] === "--import" &&
|
|
90
|
+
process.execArgv[1] === pathToFileURL(ENTRY).href &&
|
|
91
|
+
!process.env.GH_TOKEN &&
|
|
92
|
+
!process.env.GITHUB_TOKEN,
|
|
93
|
+
"hosted provider caller is unqualified or credentialed"
|
|
94
|
+
);
|
|
95
|
+
for (const method of ["spawn", "spawnSync", "execFileSync"])
|
|
96
|
+
childProcess[method] = (command, suppliedArgs, suppliedOptions) => {
|
|
97
|
+
const { args, options } = invocationArguments(
|
|
98
|
+
suppliedArgs,
|
|
99
|
+
suppliedOptions
|
|
100
|
+
);
|
|
101
|
+
if (command === "gh" || command === context.native.gh.path) {
|
|
102
|
+
required(
|
|
103
|
+
method === "spawnSync",
|
|
104
|
+
"hook provider requires synchronous native call"
|
|
105
|
+
);
|
|
106
|
+
return providerCall(context, entry, argv, command, args, options);
|
|
107
|
+
}
|
|
108
|
+
const selected = nativeChild(context, command, args, options);
|
|
109
|
+
return original[method](
|
|
110
|
+
selected.command,
|
|
111
|
+
selected.args,
|
|
112
|
+
selected.options
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
childProcess.execFile = (
|
|
116
|
+
command,
|
|
117
|
+
suppliedArgs,
|
|
118
|
+
suppliedOptions,
|
|
119
|
+
suppliedCallback
|
|
120
|
+
) => {
|
|
121
|
+
let args = suppliedArgs,
|
|
122
|
+
options = suppliedOptions,
|
|
123
|
+
callback = suppliedCallback;
|
|
124
|
+
if (typeof args === "function") {
|
|
125
|
+
callback = args;
|
|
126
|
+
args = [];
|
|
127
|
+
options = {};
|
|
128
|
+
} else if (typeof options === "function") {
|
|
129
|
+
callback = options;
|
|
130
|
+
options = {};
|
|
131
|
+
}
|
|
132
|
+
const normalized = invocationArguments(args, options);
|
|
133
|
+
required(
|
|
134
|
+
command !== "gh" && command !== context.native.gh.path,
|
|
135
|
+
"hook provider requires synchronous native call"
|
|
136
|
+
);
|
|
137
|
+
const selected = nativeChild(
|
|
138
|
+
context,
|
|
139
|
+
command,
|
|
140
|
+
normalized.args,
|
|
141
|
+
normalized.options
|
|
142
|
+
);
|
|
143
|
+
return original.execFile(
|
|
144
|
+
selected.command,
|
|
145
|
+
selected.args,
|
|
146
|
+
selected.options,
|
|
147
|
+
callback
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
syncBuiltinESMExports();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
initialize();
|