@codyswann/lisa 4.4.0 → 4.4.2
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/dist/codex/mcp-installer.d.ts.map +1 -1
- package/dist/codex/mcp-installer.js +55 -10
- package/dist/codex/mcp-installer.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +15 -13
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +130 -26
- package/plugins/lisa/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +130 -26
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +130 -26
- 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/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +130 -26
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +130 -26
- 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/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +130 -26
- package/scripts/check-delivery-deletion-conflicts.mjs +2 -2
- package/scripts/check-derived-artifacts.mjs +24 -5
- package/scripts/check-orphan-test-processes.mjs +2 -2
- package/scripts/check-security-floors.mjs +20 -9
- package/scripts/check-template-workflow-refs.mjs +23 -8
- package/scripts/check-workflow-package-paths.mjs +12 -8
- package/scripts/generate-lisa-owned-hash-ledger.mjs +12 -4
- package/scripts/generate-upstream-evidence-manifest.mjs +4 -4
- package/scripts/verify-health-agentic-built.mjs +4 -3
- package/scripts/verify-health-consumer-built.mjs +3 -2
- package/scripts/verify-health-contract-built.mjs +3 -2
- package/scripts/verify-health-deterministic-built.mjs +5 -4
|
@@ -77,7 +77,6 @@
|
|
|
77
77
|
*
|
|
78
78
|
* @module scripts/check-workflow-package-paths
|
|
79
79
|
*/
|
|
80
|
-
import { execFileSync } from "node:child_process";
|
|
81
80
|
import {
|
|
82
81
|
existsSync,
|
|
83
82
|
mkdirSync,
|
|
@@ -89,6 +88,7 @@ import { mkdtempSync } from "node:fs";
|
|
|
89
88
|
import { tmpdir } from "node:os";
|
|
90
89
|
import path from "node:path";
|
|
91
90
|
|
|
91
|
+
import { boundedExecFileSync } from "./lib/bounded-spawn.mjs";
|
|
92
92
|
import { invokedAsScript } from "./lib/invoked-as-script.mjs";
|
|
93
93
|
|
|
94
94
|
/** The package whose released layout a workflow may make claims about. */
|
|
@@ -179,7 +179,7 @@ function parseArgs(argv) {
|
|
|
179
179
|
* @returns {readonly string[]} Repo-relative workflow paths
|
|
180
180
|
*/
|
|
181
181
|
function trackedWorkflows(root) {
|
|
182
|
-
const output =
|
|
182
|
+
const output = boundedExecFileSync(
|
|
183
183
|
"git",
|
|
184
184
|
["-C", root, "ls-files", ".github/workflows"],
|
|
185
185
|
{ encoding: "utf8" }
|
|
@@ -285,7 +285,7 @@ export function collectClaims(root) {
|
|
|
285
285
|
*/
|
|
286
286
|
function publishedVersions() {
|
|
287
287
|
const versions = JSON.parse(
|
|
288
|
-
|
|
288
|
+
boundedExecFileSync("npm", ["view", PACKAGE_NAME, "versions", "--json"], {
|
|
289
289
|
encoding: "utf8",
|
|
290
290
|
stdio: ["ignore", "pipe", "pipe"],
|
|
291
291
|
maxBuffer: 16 * 1024 * 1024,
|
|
@@ -357,7 +357,7 @@ function fetchReleaseListings(chosen, cacheDir) {
|
|
|
357
357
|
continue;
|
|
358
358
|
}
|
|
359
359
|
const staging = mkdtempSync(path.join(tmpdir(), "lisa-release-"));
|
|
360
|
-
|
|
360
|
+
boundedExecFileSync(
|
|
361
361
|
"npm",
|
|
362
362
|
["pack", `${PACKAGE_NAME}@${version}`, "--pack-destination", staging],
|
|
363
363
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -366,10 +366,14 @@ function fetchReleaseListings(chosen, cacheDir) {
|
|
|
366
366
|
if (tarball === undefined) {
|
|
367
367
|
throw new Error(`npm pack produced no tarball for ${version}`);
|
|
368
368
|
}
|
|
369
|
-
const entries =
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
369
|
+
const entries = boundedExecFileSync(
|
|
370
|
+
"tar",
|
|
371
|
+
["-tzf", path.join(staging, tarball)],
|
|
372
|
+
{
|
|
373
|
+
encoding: "utf8",
|
|
374
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
375
|
+
}
|
|
376
|
+
)
|
|
373
377
|
.split("\n")
|
|
374
378
|
.filter(Boolean);
|
|
375
379
|
listings[version] = entries;
|
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
* legitimately stale file as host-modified and stop refreshing it — failing
|
|
20
20
|
* safe, but permanently.
|
|
21
21
|
*/
|
|
22
|
-
import { execFileSync } from "node:child_process";
|
|
23
22
|
import { createHash } from "node:crypto";
|
|
24
23
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
25
24
|
import path from "node:path";
|
|
26
25
|
|
|
26
|
+
import { boundedExecFileSync, isChildTimeout } from "./lib/bounded-spawn.mjs";
|
|
27
|
+
|
|
27
28
|
const repoRoot = path.resolve(import.meta.dirname, "..");
|
|
28
29
|
const outputPath = path.join(repoRoot, "src/core/lisa-owned-hash-ledger.ts");
|
|
29
30
|
const COPY_OVERWRITE = "copy-overwrite";
|
|
@@ -35,18 +36,25 @@ const ENFORCEMENT_TREE = "scripts/";
|
|
|
35
36
|
*
|
|
36
37
|
* Blobs are read as `binary` so arbitrary bytes survive the round trip into the
|
|
37
38
|
* Buffer that gets hashed; decoding as UTF-8 would corrupt any non-text file.
|
|
39
|
+
* A KILLED child re-raises. Every caller reads this as content, and an empty
|
|
40
|
+
* string is a perfectly well-formed answer meaning "no files" — so a timeout
|
|
41
|
+
* on the `ls-files` call would build a ledger that vouches for NOTHING and
|
|
42
|
+
* report it as a complete one. A ledger's whole job is to vouch for bytes; one
|
|
43
|
+
* assembled from silence is worse than none, because it looks authoritative.
|
|
38
44
|
* @param {readonly string[]} args - Arguments passed to git
|
|
39
|
-
* @returns {string} Command stdout, or an empty string when git
|
|
45
|
+
* @returns {string} Command stdout, or an empty string when git said nothing
|
|
46
|
+
* @throws {Error} When the child was killed at its deadline
|
|
40
47
|
*/
|
|
41
48
|
function git(args) {
|
|
42
49
|
try {
|
|
43
|
-
return
|
|
50
|
+
return boundedExecFileSync("git", args, {
|
|
44
51
|
cwd: repoRoot,
|
|
45
52
|
encoding: "buffer",
|
|
46
53
|
maxBuffer: 64 * 1024 * 1024,
|
|
47
54
|
stdio: ["ignore", "pipe", "ignore"],
|
|
48
55
|
}).toString("binary");
|
|
49
|
-
} catch {
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (isChildTimeout(error)) throw error;
|
|
50
58
|
return "";
|
|
51
59
|
}
|
|
52
60
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Generate the exact hash-pinned allowlist for public upstream evidence. */
|
|
3
|
-
import { execFileSync } from "node:child_process";
|
|
4
3
|
import { createHash } from "node:crypto";
|
|
5
4
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
5
|
import path from "node:path";
|
|
7
6
|
|
|
7
|
+
import { boundedExecFileSync } from "./lib/bounded-spawn.mjs";
|
|
8
8
|
import {
|
|
9
9
|
describeStaleManifest,
|
|
10
10
|
diagnoseStaleManifest,
|
|
@@ -86,7 +86,7 @@ function repositoryPath(url) {
|
|
|
86
86
|
// comparison is by path: `url.<base>.insteadOf` rewrites what `git remote
|
|
87
87
|
// get-url` returns, so it answers "how do I reach this" rather than "what is
|
|
88
88
|
// this". Falls back to the resolved URL only if no value is configured.
|
|
89
|
-
const originUrl =
|
|
89
|
+
const originUrl = boundedExecFileSync(
|
|
90
90
|
"git",
|
|
91
91
|
["config", "--get", "remote.origin.url"],
|
|
92
92
|
{ cwd: repoRoot, encoding: "utf8" }
|
|
@@ -100,7 +100,7 @@ if (repositoryPath(originUrl) !== canonicalRepository.toLowerCase()) {
|
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const tracked =
|
|
103
|
+
const tracked = boundedExecFileSync("git", ["ls-files", "-z"], {
|
|
104
104
|
cwd: repoRoot,
|
|
105
105
|
encoding: "utf8",
|
|
106
106
|
})
|
|
@@ -135,7 +135,7 @@ const existingPublicCommits = [
|
|
|
135
135
|
.filter(Boolean);
|
|
136
136
|
const refreshPublicCommits = process.argv.includes("--refresh-public-commits");
|
|
137
137
|
const discoveredPublicCommits = refreshPublicCommits
|
|
138
|
-
?
|
|
138
|
+
? boundedExecFileSync("git", ["rev-list", "--remotes=origin"], {
|
|
139
139
|
cwd: repoRoot,
|
|
140
140
|
encoding: "utf8",
|
|
141
141
|
})
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Empirical proof for the shipped optional agentic Health composition API. */
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
|
-
import { execFileSync } from "node:child_process";
|
|
5
4
|
import { createHash } from "node:crypto";
|
|
6
5
|
import {
|
|
7
6
|
lstat,
|
|
@@ -17,6 +16,8 @@ import {
|
|
|
17
16
|
import { tmpdir } from "node:os";
|
|
18
17
|
import path from "node:path";
|
|
19
18
|
|
|
19
|
+
import { boundedExecFileSync } from "./lib/bounded-spawn.mjs";
|
|
20
|
+
|
|
20
21
|
// Literals named once — each was repeated enough times that a typo in one
|
|
21
22
|
// copy would diverge silently.
|
|
22
23
|
const TEMPLATES_MANAGED = "templates.managed";
|
|
@@ -62,14 +63,14 @@ const root = process.cwd();
|
|
|
62
63
|
const workspace = await mkdtemp(path.join(tmpdir(), "lisa-health-agentic-"));
|
|
63
64
|
const project = path.join(workspace, "host");
|
|
64
65
|
const isolatedBin = path.join(workspace, "bin");
|
|
65
|
-
const gitExecutable =
|
|
66
|
+
const gitExecutable = boundedExecFileSync("which", ["git"], {
|
|
66
67
|
encoding: "utf8",
|
|
67
68
|
}).trim();
|
|
68
69
|
const healthFile = path.join(project, ".lisa", "health", "latest.json");
|
|
69
70
|
const startedAt = Date.now();
|
|
70
71
|
|
|
71
72
|
const run = (executable, argv, options = {}) =>
|
|
72
|
-
|
|
73
|
+
boundedExecFileSync(executable, argv, {
|
|
73
74
|
cwd: project,
|
|
74
75
|
encoding: "utf8",
|
|
75
76
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Built-package proof for the real two-phase Health CLI consumer. */
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
|
-
import { execFileSync } from "node:child_process";
|
|
5
4
|
import {
|
|
6
5
|
lstat,
|
|
7
6
|
mkdir,
|
|
@@ -14,6 +13,8 @@ import {
|
|
|
14
13
|
import { tmpdir } from "node:os";
|
|
15
14
|
import path from "node:path";
|
|
16
15
|
|
|
16
|
+
import { boundedExecFileSync } from "./lib/bounded-spawn.mjs";
|
|
17
|
+
|
|
17
18
|
// Literals named once — each was repeated enough times that a typo in one
|
|
18
19
|
// copy would diverge silently.
|
|
19
20
|
const LATEST_JSON = "latest.json";
|
|
@@ -53,7 +54,7 @@ async function createProject(name) {
|
|
|
53
54
|
|
|
54
55
|
/** Run the compiled CLI and capture its exact standard-output bytes. */
|
|
55
56
|
function runCli(project, argv, input) {
|
|
56
|
-
return
|
|
57
|
+
return boundedExecFileSync(
|
|
57
58
|
process.execPath,
|
|
58
59
|
[cli, "--no-update-check", "health", ...argv, project],
|
|
59
60
|
{
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Empirical proof for the shipped Health v1 contract and real built CLI. */
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
|
-
import { execFileSync } from "node:child_process";
|
|
5
4
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
6
5
|
import { tmpdir } from "node:os";
|
|
7
6
|
import path from "node:path";
|
|
8
7
|
|
|
8
|
+
import { boundedExecFileSync } from "./lib/bounded-spawn.mjs";
|
|
9
|
+
|
|
9
10
|
let assertions = 0;
|
|
10
11
|
const check = (condition, message) => {
|
|
11
12
|
assertions += 1;
|
|
@@ -23,7 +24,7 @@ try {
|
|
|
23
24
|
path.join(project, ".lisa.config.json"),
|
|
24
25
|
`${JSON.stringify({ tracker: "github", github: { org: "acme", repo: "app" } }, null, 2)}\n`
|
|
25
26
|
);
|
|
26
|
-
|
|
27
|
+
boundedExecFileSync(
|
|
27
28
|
process.execPath,
|
|
28
29
|
[path.join(root, "dist/index.js"), "sync", project, "--json"],
|
|
29
30
|
{
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/** Empirical proof for the shipped deterministic Health fast path. */
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
|
-
import { execFileSync } from "node:child_process";
|
|
5
4
|
import { createHash } from "node:crypto";
|
|
6
5
|
import {
|
|
7
6
|
chmod,
|
|
@@ -18,6 +17,8 @@ import {
|
|
|
18
17
|
import { tmpdir } from "node:os";
|
|
19
18
|
import path from "node:path";
|
|
20
19
|
|
|
20
|
+
import { boundedExecFileSync } from "./lib/bounded-spawn.mjs";
|
|
21
|
+
|
|
21
22
|
// Literals named once — each was repeated enough times that a typo in one
|
|
22
23
|
// copy would diverge silently.
|
|
23
24
|
const PACKAGE_JSON = "package.json";
|
|
@@ -40,14 +41,14 @@ const root = process.cwd();
|
|
|
40
41
|
const workspace = await mkdtemp(path.join(tmpdir(), "lisa-health-fast-path-"));
|
|
41
42
|
const project = path.join(workspace, "host");
|
|
42
43
|
const isolatedBin = path.join(workspace, "bin");
|
|
43
|
-
const gitExecutable =
|
|
44
|
+
const gitExecutable = boundedExecFileSync("which", ["git"], {
|
|
44
45
|
encoding: "utf8",
|
|
45
46
|
}).trim();
|
|
46
47
|
const healthFile = path.join(project, ".lisa", "health", "latest.json");
|
|
47
48
|
const startedAt = Date.now();
|
|
48
49
|
|
|
49
50
|
const run = (executable, argv, options = {}) =>
|
|
50
|
-
|
|
51
|
+
boundedExecFileSync(executable, argv, {
|
|
51
52
|
cwd: project,
|
|
52
53
|
encoding: "utf8",
|
|
53
54
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -466,7 +467,7 @@ try {
|
|
|
466
467
|
path.join(unsafeProject, LISA_CONFIG_JSON),
|
|
467
468
|
'{"tracker":"github","harness":"codex"}\n'
|
|
468
469
|
);
|
|
469
|
-
|
|
470
|
+
boundedExecFileSync("mkfifo", [path.join(unsafeProject, PACKAGE_JSON)]);
|
|
470
471
|
const unsafeStarted = Date.now();
|
|
471
472
|
const unsafe = await health.runDeterministicHealth(unsafeProject, {
|
|
472
473
|
lisaRoot: root,
|