@codyswann/lisa 2.265.0 → 2.266.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/lisa-plugin-selection.d.ts +11 -0
- package/dist/core/lisa-plugin-selection.d.ts.map +1 -1
- package/dist/core/lisa-plugin-selection.js +11 -1
- package/dist/core/lisa-plugin-selection.js.map +1 -1
- package/dist/core/lisa.d.ts +0 -41
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +23 -104
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/template-ownership.d.ts +46 -0
- package/dist/core/template-ownership.d.ts.map +1 -0
- package/dist/core/template-ownership.js +123 -0
- package/dist/core/template-ownership.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +20 -1
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/health/deadline.d.ts +25 -0
- package/dist/health/deadline.d.ts.map +1 -0
- package/dist/health/deadline.js +50 -0
- package/dist/health/deadline.js.map +1 -0
- package/dist/health/deterministic.d.ts +34 -0
- package/dist/health/deterministic.d.ts.map +1 -0
- package/dist/health/deterministic.js +206 -0
- package/dist/health/deterministic.js.map +1 -0
- package/dist/health/finding-utils.d.ts +17 -0
- package/dist/health/finding-utils.d.ts.map +1 -0
- package/dist/health/finding-utils.js +25 -0
- package/dist/health/finding-utils.js.map +1 -0
- package/dist/health/governance-probes.d.ts +51 -0
- package/dist/health/governance-probes.d.ts.map +1 -0
- package/dist/health/governance-probes.js +94 -0
- package/dist/health/governance-probes.js.map +1 -0
- package/dist/health/hook-inspection.d.ts +35 -0
- package/dist/health/hook-inspection.d.ts.map +1 -0
- package/dist/health/hook-inspection.js +123 -0
- package/dist/health/hook-inspection.js.map +1 -0
- package/dist/health/index.d.ts +1 -0
- package/dist/health/index.d.ts.map +1 -1
- package/dist/health/index.js +1 -0
- package/dist/health/index.js.map +1 -1
- package/dist/health/plugin-inspection.d.ts +37 -0
- package/dist/health/plugin-inspection.d.ts.map +1 -0
- package/dist/health/plugin-inspection.js +128 -0
- package/dist/health/plugin-inspection.js.map +1 -0
- package/dist/health/project-probes.d.ts +34 -0
- package/dist/health/project-probes.d.ts.map +1 -0
- package/dist/health/project-probes.js +104 -0
- package/dist/health/project-probes.js.map +1 -0
- package/dist/health/read-only-fs.d.ts +54 -0
- package/dist/health/read-only-fs.d.ts.map +1 -0
- package/dist/health/read-only-fs.js +165 -0
- package/dist/health/read-only-fs.js.map +1 -0
- package/dist/health/ruleset-inspection.d.ts +57 -0
- package/dist/health/ruleset-inspection.d.ts.map +1 -0
- package/dist/health/ruleset-inspection.js +315 -0
- package/dist/health/ruleset-inspection.js.map +1 -0
- package/dist/health/template-inspection.d.ts +67 -0
- package/dist/health/template-inspection.d.ts.map +1 -0
- package/dist/health/template-inspection.js +469 -0
- package/dist/health/template-inspection.js.map +1 -0
- package/dist/strategies/copy-contents.d.ts +7 -25
- package/dist/strategies/copy-contents.d.ts.map +1 -1
- package/dist/strategies/copy-contents.js +32 -63
- package/dist/strategies/copy-contents.js.map +1 -1
- package/dist/strategies/merge.d.ts +7 -0
- package/dist/strategies/merge.d.ts.map +1 -1
- package/dist/strategies/merge.js +10 -1
- package/dist/strategies/merge.js.map +1 -1
- package/dist/strategies/package-lisa.d.ts +10 -1
- package/dist/strategies/package-lisa.d.ts.map +1 -1
- package/dist/strategies/package-lisa.js +18 -20
- package/dist/strategies/package-lisa.js.map +1 -1
- package/dist/strategies/tagged-merge.d.ts +7 -0
- package/dist/strategies/tagged-merge.d.ts.map +1 -1
- package/dist/strategies/tagged-merge.js +10 -1
- package/dist/strategies/tagged-merge.js.map +1 -1
- package/dist/sync/config-sync.d.ts +7 -0
- package/dist/sync/config-sync.d.ts.map +1 -1
- package/dist/sync/config-sync.js +23 -16
- package/dist/sync/config-sync.js.map +1 -1
- package/dist/utils/ignore-patterns.d.ts +18 -0
- package/dist/utils/ignore-patterns.d.ts.map +1 -1
- package/dist/utils/ignore-patterns.js +2 -2
- package/dist/utils/ignore-patterns.js.map +1 -1
- package/package.json +3 -2
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- 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-cursor/.claude-plugin/plugin.json +1 -1
- 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/scripts/detect-stale-workflow-inputs.mjs +21 -148
- package/scripts/lib/reusable-workflow-contract.d.mts +24 -0
- package/scripts/lib/reusable-workflow-contract.mjs +123 -0
- package/scripts/verify-health-deterministic-built.mjs +499 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/** Installed and executable Git-hook inspection without running hooks. */
|
|
2
|
+
/* eslint-disable jsdoc/require-param-description, jsdoc/require-returns -- typed hook readers are self-describing */
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { projectPathKind, readProjectFile, readProjectText, } from "./read-only-fs.js";
|
|
6
|
+
const GIT_TIMEOUT_MS = 10_000;
|
|
7
|
+
const MAX_GIT_OUTPUT_BYTES = 16 * 1024;
|
|
8
|
+
const HUSKY_HOOKS = [
|
|
9
|
+
"commit-msg",
|
|
10
|
+
"post-checkout",
|
|
11
|
+
"pre-commit",
|
|
12
|
+
"pre-push",
|
|
13
|
+
"prepare-commit-msg",
|
|
14
|
+
];
|
|
15
|
+
const LEFTHOOK_HOOKS = [
|
|
16
|
+
"commit-msg",
|
|
17
|
+
"pre-commit",
|
|
18
|
+
"pre-push",
|
|
19
|
+
"prepare-commit-msg",
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Default fixed-argv local git-config reader.
|
|
23
|
+
* @param projectRoot
|
|
24
|
+
* @param timeoutMs
|
|
25
|
+
* @param signal
|
|
26
|
+
*/
|
|
27
|
+
export const readCoreHooksPath = async (projectRoot, timeoutMs, signal) => new Promise((resolve, reject) => {
|
|
28
|
+
execFile(
|
|
29
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path -- fixed user-installed git executable
|
|
30
|
+
"git", ["config", "--local", "--get", "core.hooksPath"], {
|
|
31
|
+
cwd: projectRoot,
|
|
32
|
+
encoding: "utf8",
|
|
33
|
+
maxBuffer: MAX_GIT_OUTPUT_BYTES,
|
|
34
|
+
signal,
|
|
35
|
+
killSignal: "SIGKILL",
|
|
36
|
+
timeout: Math.max(1, Math.min(timeoutMs, GIT_TIMEOUT_MS)),
|
|
37
|
+
}, (error, stdout) => {
|
|
38
|
+
if (error === null) {
|
|
39
|
+
resolve(stdout.trim() || undefined);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (error.code === 1) {
|
|
43
|
+
resolve(undefined);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
reject(error);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Check executable regular files under one project-relative prefix.
|
|
51
|
+
* @param projectRoot
|
|
52
|
+
* @param prefix
|
|
53
|
+
* @param names
|
|
54
|
+
*/
|
|
55
|
+
async function executableDrift(projectRoot, prefix, names) {
|
|
56
|
+
const checks = await Promise.all(names.map(async (name) => {
|
|
57
|
+
const relative = path.join(prefix, name);
|
|
58
|
+
const file = await readProjectFile(projectRoot, relative);
|
|
59
|
+
return file !== undefined && (file.mode & 0o100) !== 0
|
|
60
|
+
? undefined
|
|
61
|
+
: relative.split(path.sep).join("/");
|
|
62
|
+
}));
|
|
63
|
+
return checks.filter((item) => item !== undefined);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Inspect Lefthook wrappers when the git directory is locally readable.
|
|
67
|
+
* @param projectRoot
|
|
68
|
+
*/
|
|
69
|
+
async function inspectLefthook(projectRoot) {
|
|
70
|
+
const gitKind = await projectPathKind(projectRoot, ".git");
|
|
71
|
+
if (gitKind !== "directory") {
|
|
72
|
+
return { status: "warn", drift: ["lefthook installation unavailable"] };
|
|
73
|
+
}
|
|
74
|
+
const modeDrift = await executableDrift(projectRoot, path.join(".git", "hooks"), LEFTHOOK_HOOKS);
|
|
75
|
+
const contentDrift = (await Promise.all(LEFTHOOK_HOOKS.map(async (name) => {
|
|
76
|
+
const relative = path.join(".git", "hooks", name);
|
|
77
|
+
const content = await readProjectText(projectRoot, relative);
|
|
78
|
+
return content !== undefined &&
|
|
79
|
+
!content.toLowerCase().includes("lefthook")
|
|
80
|
+
? relative.split(path.sep).join("/")
|
|
81
|
+
: undefined;
|
|
82
|
+
}))).filter((item) => item !== undefined);
|
|
83
|
+
const drift = [...new Set([...modeDrift, ...contentDrift])].sort((left, right) => left.localeCompare(right));
|
|
84
|
+
return drift.length === 0
|
|
85
|
+
? { status: "pass", drift: [] }
|
|
86
|
+
: { status: "fail", drift };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Inspect actual installed hook state for applicable stacks.
|
|
90
|
+
* @param projectRoot - Canonical host root
|
|
91
|
+
* @param types - Safely detected project types
|
|
92
|
+
* @param reader - core.hooksPath reader
|
|
93
|
+
* @param timeoutMs - Remaining shared deadline
|
|
94
|
+
* @param signal - Shared cancellation signal
|
|
95
|
+
* @returns Hook installation status
|
|
96
|
+
*/
|
|
97
|
+
export async function inspectHookInstallation(projectRoot, types, reader, timeoutMs, signal) {
|
|
98
|
+
if (types.includes("rails"))
|
|
99
|
+
return inspectLefthook(projectRoot);
|
|
100
|
+
if (!types.includes("typescript")) {
|
|
101
|
+
return { status: "warn", drift: ["unsupported hook stack"] };
|
|
102
|
+
}
|
|
103
|
+
const modeDrift = [
|
|
104
|
+
...(await executableDrift(projectRoot, ".husky", HUSKY_HOOKS)),
|
|
105
|
+
];
|
|
106
|
+
const hooksPath = await reader(projectRoot, timeoutMs, signal).catch(() => null);
|
|
107
|
+
if (hooksPath === null) {
|
|
108
|
+
return modeDrift.length === 0
|
|
109
|
+
? { status: "warn", drift: ["core.hooksPath unavailable"] }
|
|
110
|
+
: { status: "fail", drift: modeDrift };
|
|
111
|
+
}
|
|
112
|
+
const drift = [
|
|
113
|
+
...modeDrift,
|
|
114
|
+
...(hooksPath === ".husky" || hooksPath === ".husky/_"
|
|
115
|
+
? []
|
|
116
|
+
: ["core.hooksPath"]),
|
|
117
|
+
];
|
|
118
|
+
return drift.length === 0
|
|
119
|
+
? { status: "pass", drift: [] }
|
|
120
|
+
: { status: "fail", drift };
|
|
121
|
+
}
|
|
122
|
+
/* eslint-enable jsdoc/require-param-description, jsdoc/require-returns -- restore repository documentation defaults */
|
|
123
|
+
//# sourceMappingURL=hook-inspection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-inspection.js","sourceRoot":"","sources":["../../src/health/hook-inspection.ts"],"names":[],"mappings":"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"}
|
package/dist/health/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/health/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/health/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC"}
|
package/dist/health/index.js
CHANGED
package/dist/health/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/health/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/health/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ProjectType } from "../core/config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Injectable fixed-argv reader for actual project plugin installation.
|
|
4
|
+
* Implementations must honor `signal` and release any owned handles before
|
|
5
|
+
* settling.
|
|
6
|
+
*/
|
|
7
|
+
export type InstalledPluginReader = (projectRoot: string, timeoutMs: number, signal: AbortSignal) => Promise<readonly string[]>;
|
|
8
|
+
/** Structured plugin inspection outcome. */
|
|
9
|
+
export type PluginInspection = {
|
|
10
|
+
readonly status: "pass";
|
|
11
|
+
readonly drift: readonly string[];
|
|
12
|
+
} | {
|
|
13
|
+
readonly status: "warn";
|
|
14
|
+
readonly drift: readonly string[];
|
|
15
|
+
} | {
|
|
16
|
+
readonly status: "fail";
|
|
17
|
+
readonly drift: readonly string[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Default fixed-argv Claude installed-plugin reader.
|
|
21
|
+
* @param projectRoot
|
|
22
|
+
* @param timeoutMs
|
|
23
|
+
* @param signal
|
|
24
|
+
*/
|
|
25
|
+
export declare const readInstalledClaudePlugins: InstalledPluginReader;
|
|
26
|
+
/**
|
|
27
|
+
* Inspect settings, marker, and actual installed plugin state.
|
|
28
|
+
* @param projectRoot - Canonical host root
|
|
29
|
+
* @param config - Safe project config
|
|
30
|
+
* @param types - Safely detected project types
|
|
31
|
+
* @param reader - Actual installed-plugin reader
|
|
32
|
+
* @param timeoutMs - Remaining shared deadline
|
|
33
|
+
* @param signal - Shared cancellation signal
|
|
34
|
+
* @returns Pass, fail, or optional-harness warning
|
|
35
|
+
*/
|
|
36
|
+
export declare function inspectPlugins(projectRoot: string, config: Readonly<Record<string, unknown>>, types: readonly ProjectType[], reader: InstalledPluginReader, timeoutMs: number, signal: AbortSignal): Promise<PluginInspection>;
|
|
37
|
+
//# sourceMappingURL=plugin-inspection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-inspection.d.ts","sourceRoot":"","sources":["../../src/health/plugin-inspection.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAa3B;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;AAEhC,4CAA4C;AAC5C,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,qBA4CrC,CAAC;AAwBL;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,gBAAgB,CAAC,CA0D3B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/** Bounded actual plugin-installation inspection for deterministic health. */
|
|
2
|
+
/* eslint-disable jsdoc/require-param-description, jsdoc/require-returns -- typed plugin readers are self-describing */
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { DEFAULT_HARNESS, harnessIncludesAgent, } from "../core/config.js";
|
|
6
|
+
import { selectProjectLisaPluginsFromState } from "../core/lisa-plugin-selection.js";
|
|
7
|
+
import { getPackageVersion } from "../cli/version.js";
|
|
8
|
+
import { projectPathKind, readProjectJsonObject, readProjectText, } from "./read-only-fs.js";
|
|
9
|
+
const MAX_PLUGIN_OUTPUT_BYTES = 256 * 1024;
|
|
10
|
+
const MAX_INSTALLED_PLUGINS = 512;
|
|
11
|
+
const PLUGIN_TIMEOUT_MS = 15_000;
|
|
12
|
+
/**
|
|
13
|
+
* Default fixed-argv Claude installed-plugin reader.
|
|
14
|
+
* @param projectRoot
|
|
15
|
+
* @param timeoutMs
|
|
16
|
+
* @param signal
|
|
17
|
+
*/
|
|
18
|
+
export const readInstalledClaudePlugins = async (projectRoot, timeoutMs, signal) => new Promise((resolve, reject) => {
|
|
19
|
+
execFile(
|
|
20
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path -- fixed user-installed Claude executable
|
|
21
|
+
"claude", ["plugin", "list", "--json"], {
|
|
22
|
+
cwd: projectRoot,
|
|
23
|
+
encoding: "utf8",
|
|
24
|
+
maxBuffer: MAX_PLUGIN_OUTPUT_BYTES,
|
|
25
|
+
signal,
|
|
26
|
+
killSignal: "SIGKILL",
|
|
27
|
+
timeout: Math.max(1, Math.min(timeoutMs, PLUGIN_TIMEOUT_MS)),
|
|
28
|
+
}, (error, stdout) => {
|
|
29
|
+
if (error !== null) {
|
|
30
|
+
reject(error);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(stdout);
|
|
35
|
+
if (!Array.isArray(parsed) || parsed.length > MAX_INSTALLED_PLUGINS) {
|
|
36
|
+
throw new Error("Installed plugin response exceeded its contract");
|
|
37
|
+
}
|
|
38
|
+
const ids = parsed.flatMap(entry => {
|
|
39
|
+
if (entry === null || typeof entry !== "object")
|
|
40
|
+
return [];
|
|
41
|
+
const id = Reflect.get(entry, "id");
|
|
42
|
+
const projectPath = Reflect.get(entry, "projectPath");
|
|
43
|
+
return typeof id === "string" && projectPath === projectRoot
|
|
44
|
+
? [id]
|
|
45
|
+
: [];
|
|
46
|
+
});
|
|
47
|
+
resolve([...new Set(ids)].sort((left, right) => left.localeCompare(right)));
|
|
48
|
+
}
|
|
49
|
+
catch (parseError) {
|
|
50
|
+
reject(parseError);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* Resolve configured harness without accepting invalid strings.
|
|
56
|
+
* @param config
|
|
57
|
+
*/
|
|
58
|
+
function configuredHarness(config) {
|
|
59
|
+
const harness = config.harness ?? DEFAULT_HARNESS;
|
|
60
|
+
return typeof harness === "string" &&
|
|
61
|
+
[
|
|
62
|
+
"claude",
|
|
63
|
+
"codex",
|
|
64
|
+
"cursor",
|
|
65
|
+
"agy",
|
|
66
|
+
"copilot",
|
|
67
|
+
"opencode",
|
|
68
|
+
"fleet",
|
|
69
|
+
].includes(harness)
|
|
70
|
+
? harness
|
|
71
|
+
: undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Inspect settings, marker, and actual installed plugin state.
|
|
75
|
+
* @param projectRoot - Canonical host root
|
|
76
|
+
* @param config - Safe project config
|
|
77
|
+
* @param types - Safely detected project types
|
|
78
|
+
* @param reader - Actual installed-plugin reader
|
|
79
|
+
* @param timeoutMs - Remaining shared deadline
|
|
80
|
+
* @param signal - Shared cancellation signal
|
|
81
|
+
* @returns Pass, fail, or optional-harness warning
|
|
82
|
+
*/
|
|
83
|
+
export async function inspectPlugins(projectRoot, config, types, reader, timeoutMs, signal) {
|
|
84
|
+
const harness = configuredHarness(config);
|
|
85
|
+
if (harness === undefined || !harnessIncludesAgent(harness, "claude")) {
|
|
86
|
+
return { status: "warn", drift: ["unsupported harness"] };
|
|
87
|
+
}
|
|
88
|
+
const settings = await readProjectJsonObject(projectRoot, path.join(".claude", "settings.json"));
|
|
89
|
+
if (settings === undefined) {
|
|
90
|
+
return { status: "fail", drift: [".claude/settings.json"] };
|
|
91
|
+
}
|
|
92
|
+
const enabled = settings.enabledPlugins;
|
|
93
|
+
if (enabled === null ||
|
|
94
|
+
typeof enabled !== "object" ||
|
|
95
|
+
Array.isArray(enabled)) {
|
|
96
|
+
return { status: "fail", drift: ["plugin settings"] };
|
|
97
|
+
}
|
|
98
|
+
const hasWiki = (await projectPathKind(projectRoot, path.join("wiki", "lisa-wiki.config.json"))) === "file";
|
|
99
|
+
const expected = [
|
|
100
|
+
...selectProjectLisaPluginsFromState(config, types, hasWiki),
|
|
101
|
+
]
|
|
102
|
+
.map(plugin => `${plugin}@lisa`)
|
|
103
|
+
.sort((left, right) => left.localeCompare(right));
|
|
104
|
+
const settingsDrift = expected.filter(plugin => Reflect.get(enabled, plugin) !== true);
|
|
105
|
+
const marker = await readProjectText(projectRoot, path.join(".claude", ".lisa-plugins-synced"));
|
|
106
|
+
const drift = [
|
|
107
|
+
...settingsDrift,
|
|
108
|
+
...(marker?.trim() === getPackageVersion()
|
|
109
|
+
? []
|
|
110
|
+
: ["plugin version marker"]),
|
|
111
|
+
];
|
|
112
|
+
if (drift.length > 0)
|
|
113
|
+
return { status: "fail", drift };
|
|
114
|
+
const installed = await reader(projectRoot, timeoutMs, signal).catch(() => undefined);
|
|
115
|
+
if (installed === undefined) {
|
|
116
|
+
return {
|
|
117
|
+
status: "warn",
|
|
118
|
+
drift: ["actual plugin installation unavailable"],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const installedSet = new Set(installed);
|
|
122
|
+
const missing = expected.filter(plugin => !installedSet.has(plugin));
|
|
123
|
+
return missing.length === 0
|
|
124
|
+
? { status: "pass", drift: [] }
|
|
125
|
+
: { status: "fail", drift: missing };
|
|
126
|
+
}
|
|
127
|
+
/* eslint-enable jsdoc/require-param-description, jsdoc/require-returns -- restore repository documentation defaults */
|
|
128
|
+
//# sourceMappingURL=plugin-inspection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-inspection.js","sourceRoot":"","sources":["../../src/health/plugin-inspection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { SyncReport } from "../sync/config-sync.js";
|
|
2
|
+
import type { HealthFinding } from "./contract.js";
|
|
3
|
+
import type { HealthProjectShape } from "./template-inspection.js";
|
|
4
|
+
/** Result of safely loading committed project configuration. */
|
|
5
|
+
export interface HealthConfigState {
|
|
6
|
+
readonly config: Readonly<Record<string, unknown>>;
|
|
7
|
+
readonly present: boolean;
|
|
8
|
+
readonly readable: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Project and legacy overlay check derived from doctor without mutation.
|
|
12
|
+
* @param projectRoot
|
|
13
|
+
* @param configState
|
|
14
|
+
* @param shape
|
|
15
|
+
*/
|
|
16
|
+
export declare function projectStateFinding(projectRoot: string, configState: HealthConfigState, shape: HealthProjectShape | undefined): Promise<HealthFinding>;
|
|
17
|
+
/**
|
|
18
|
+
* Local wiki contract check derived from doctor without network or writes.
|
|
19
|
+
* @param projectRoot
|
|
20
|
+
*/
|
|
21
|
+
export declare function wikiFinding(projectRoot: string): Promise<HealthFinding>;
|
|
22
|
+
/** Offline representation of doctor's network-only starter check. */
|
|
23
|
+
export declare function starterFinding(): HealthFinding;
|
|
24
|
+
/**
|
|
25
|
+
* Read-only canonical instruction check.
|
|
26
|
+
* @param projectRoot
|
|
27
|
+
*/
|
|
28
|
+
export declare function instructionFinding(projectRoot: string): Promise<HealthFinding>;
|
|
29
|
+
/**
|
|
30
|
+
* Convert one dry-run sync report into required-key and sync findings.
|
|
31
|
+
* @param report
|
|
32
|
+
*/
|
|
33
|
+
export declare function configFindings(report: SyncReport): readonly [HealthFinding, HealthFinding];
|
|
34
|
+
//# sourceMappingURL=project-probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-probes.d.ts","sourceRoot":"","sources":["../../src/health/project-probes.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAKnE,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,iBAAiB,EAC9B,KAAK,EAAE,kBAAkB,GAAG,SAAS,GACpC,OAAO,CAAC,aAAa,CAAC,CAqCxB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAyC7E;AAED,qEAAqE;AACrE,wBAAgB,cAAc,IAAI,aAAa,CAM9C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC,CA0BxB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,GACjB,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC,CA2BzC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Safe local project/doctor-derived deterministic health probes. */
|
|
2
|
+
/* eslint-disable jsdoc/require-param-description, jsdoc/require-returns -- typed doctor projections are self-describing */
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { CLAUDE_MD_AGENTS_IMPORT } from "../claude/claude-md-installer.js";
|
|
5
|
+
import { LISA_HOOKS_SUBDIR, LISA_RULES_SUBDIR, } from "../codex/hooks-installer.js";
|
|
6
|
+
import { LISA_SKILLS_SUBDIR } from "../codex/skills-installer.js";
|
|
7
|
+
import { LISA_RULES_END_MARKER, LISA_RULES_START_MARKER, } from "../core/instruction-files-migration.js";
|
|
8
|
+
import { deterministicFinding, namedReason } from "./finding-utils.js";
|
|
9
|
+
import { projectPathKind, readProjectText } from "./read-only-fs.js";
|
|
10
|
+
const PROJECT_STATE_CHECK = "project.state";
|
|
11
|
+
const PROJECT_WIKI_CHECK = "project.wiki";
|
|
12
|
+
/**
|
|
13
|
+
* Project and legacy overlay check derived from doctor without mutation.
|
|
14
|
+
* @param projectRoot
|
|
15
|
+
* @param configState
|
|
16
|
+
* @param shape
|
|
17
|
+
*/
|
|
18
|
+
export async function projectStateFinding(projectRoot, configState, shape) {
|
|
19
|
+
if (!configState.present || !configState.readable || shape === undefined) {
|
|
20
|
+
return deterministicFinding(PROJECT_STATE_CHECK, "fail", "Project config or project shape is missing, malformed, or unsafe.");
|
|
21
|
+
}
|
|
22
|
+
if (shape.types.length === 0) {
|
|
23
|
+
return deterministicFinding(PROJECT_STATE_CHECK, "warn", "No supported Lisa project type was safely detected.");
|
|
24
|
+
}
|
|
25
|
+
const legacy = await Promise.all([LISA_HOOKS_SUBDIR, LISA_RULES_SUBDIR, LISA_SKILLS_SUBDIR].map(async (subdir) => {
|
|
26
|
+
const relative = path.join(".codex", subdir);
|
|
27
|
+
return (await projectPathKind(projectRoot, relative)) === "directory"
|
|
28
|
+
? relative.split(path.sep).join("/")
|
|
29
|
+
: undefined;
|
|
30
|
+
}));
|
|
31
|
+
const present = legacy.filter((item) => item !== undefined);
|
|
32
|
+
return present.length === 0
|
|
33
|
+
? deterministicFinding(PROJECT_STATE_CHECK, "pass", "Project config, type, and local doctor state are readable.")
|
|
34
|
+
: deterministicFinding(PROJECT_STATE_CHECK, "warn", namedReason("Legacy Codex overlay paths", present));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Local wiki contract check derived from doctor without network or writes.
|
|
38
|
+
* @param projectRoot
|
|
39
|
+
*/
|
|
40
|
+
export async function wikiFinding(projectRoot) {
|
|
41
|
+
const wiki = await projectPathKind(projectRoot, "wiki");
|
|
42
|
+
if (wiki === "missing") {
|
|
43
|
+
return deterministicFinding(PROJECT_WIKI_CHECK, "pass", "No local wiki contract is present.");
|
|
44
|
+
}
|
|
45
|
+
if (wiki !== "directory") {
|
|
46
|
+
return deterministicFinding(PROJECT_WIKI_CHECK, "fail", "The local wiki path is unsafe or not a directory.");
|
|
47
|
+
}
|
|
48
|
+
const required = [
|
|
49
|
+
"wiki/lisa-wiki.config.json",
|
|
50
|
+
"wiki/schema/llm-wiki-contract.md",
|
|
51
|
+
"wiki/index.md",
|
|
52
|
+
];
|
|
53
|
+
const missing = (await Promise.all(required.map(async (relative) => (await projectPathKind(projectRoot, relative)) === "file"
|
|
54
|
+
? undefined
|
|
55
|
+
: relative))).filter((item) => item !== undefined);
|
|
56
|
+
return missing.length === 0
|
|
57
|
+
? deterministicFinding(PROJECT_WIKI_CHECK, "pass", "Local wiki contract files are present.")
|
|
58
|
+
: deterministicFinding(PROJECT_WIKI_CHECK, "fail", namedReason("Missing wiki contract files", missing));
|
|
59
|
+
}
|
|
60
|
+
/** Offline representation of doctor's network-only starter check. */
|
|
61
|
+
export function starterFinding() {
|
|
62
|
+
return deterministicFinding("starters.remote", "warn", "Starter repository reachability is unavailable in the offline deterministic path.");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Read-only canonical instruction check.
|
|
66
|
+
* @param projectRoot
|
|
67
|
+
*/
|
|
68
|
+
export async function instructionFinding(projectRoot) {
|
|
69
|
+
const [agents, claude] = await Promise.all([
|
|
70
|
+
readProjectText(projectRoot, "AGENTS.md"),
|
|
71
|
+
readProjectText(projectRoot, "CLAUDE.md"),
|
|
72
|
+
]);
|
|
73
|
+
const drift = [
|
|
74
|
+
...(agents === undefined ? ["AGENTS.md"] : []),
|
|
75
|
+
...(agents?.includes(LISA_RULES_START_MARKER) === true ||
|
|
76
|
+
agents?.includes(LISA_RULES_END_MARKER) === true
|
|
77
|
+
? ["AGENTS.md legacy managed block"]
|
|
78
|
+
: []),
|
|
79
|
+
...(claude === undefined || !claude.includes(CLAUDE_MD_AGENTS_IMPORT)
|
|
80
|
+
? ["CLAUDE.md"]
|
|
81
|
+
: []),
|
|
82
|
+
];
|
|
83
|
+
return drift.length === 0
|
|
84
|
+
? deterministicFinding("instructions.canonical", "pass", "Instruction files are canonical.")
|
|
85
|
+
: deterministicFinding("instructions.canonical", "fail", namedReason("Instruction file drift", drift));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Convert one dry-run sync report into required-key and sync findings.
|
|
89
|
+
* @param report
|
|
90
|
+
*/
|
|
91
|
+
export function configFindings(report) {
|
|
92
|
+
const keys = report.missingRequired.map(item => item.key);
|
|
93
|
+
const actions = report.actions.map(action => action.key);
|
|
94
|
+
return [
|
|
95
|
+
keys.length === 0
|
|
96
|
+
? deterministicFinding("config.required", "pass", "Required config keys are populated.")
|
|
97
|
+
: deterministicFinding("config.required", "fail", namedReason("Missing required config keys", keys)),
|
|
98
|
+
actions.length === 0
|
|
99
|
+
? deterministicFinding("config.sync", "pass", "Config and mirrored artifacts are synchronized.")
|
|
100
|
+
: deterministicFinding("config.sync", "fail", namedReason("Config sync drift", actions)),
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
/* eslint-enable jsdoc/require-param-description, jsdoc/require-returns -- restore repository documentation defaults */
|
|
104
|
+
//# sourceMappingURL=project-probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-probes.js","sourceRoot":"","sources":["../../src/health/project-probes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Stable metadata and bytes captured from one confined regular file. */
|
|
2
|
+
export interface ProjectFileSnapshot {
|
|
3
|
+
readonly bytes: Buffer;
|
|
4
|
+
readonly mode: number;
|
|
5
|
+
}
|
|
6
|
+
/** Safe path kinds understood by deterministic health. */
|
|
7
|
+
export type ProjectPathKind = "missing" | "file" | "directory";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a project-relative path without permitting traversal.
|
|
10
|
+
* @param root - Canonical project root
|
|
11
|
+
* @param relativePath - Project-relative path
|
|
12
|
+
* @returns Confined absolute path
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveProjectPath(root: string, relativePath: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Read one stable regular file without following a target outside the project.
|
|
17
|
+
* @param root - Canonical project root
|
|
18
|
+
* @param relativePath - Project-relative path
|
|
19
|
+
* @param maximumBytes - Maximum permitted file size
|
|
20
|
+
* @returns File bytes, or undefined when absent
|
|
21
|
+
*/
|
|
22
|
+
export declare function readProjectFile(root: string, relativePath: string, maximumBytes?: number): Promise<ProjectFileSnapshot | undefined>;
|
|
23
|
+
/**
|
|
24
|
+
* Read just the bytes from one confined stable regular file.
|
|
25
|
+
* @param root - Canonical project root
|
|
26
|
+
* @param relativePath - Project-relative path
|
|
27
|
+
* @param maximumBytes - Maximum permitted file size
|
|
28
|
+
* @returns File bytes, or undefined when absent
|
|
29
|
+
*/
|
|
30
|
+
export declare function readProjectBytes(root: string, relativePath: string, maximumBytes?: number): Promise<Buffer | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Classify a confined path without following symbolic links or accepting
|
|
33
|
+
* special files such as FIFOs and devices.
|
|
34
|
+
* @param root - Canonical project root
|
|
35
|
+
* @param relativePath - Project-relative path
|
|
36
|
+
* @returns Safe path kind
|
|
37
|
+
*/
|
|
38
|
+
export declare function projectPathKind(root: string, relativePath: string): Promise<ProjectPathKind>;
|
|
39
|
+
/**
|
|
40
|
+
* Read strict UTF-8 text from a confined project file.
|
|
41
|
+
* @param root - Canonical project root
|
|
42
|
+
* @param relativePath - Project-relative path
|
|
43
|
+
* @param maximumBytes - Maximum permitted file size
|
|
44
|
+
* @returns Text, or undefined when absent
|
|
45
|
+
*/
|
|
46
|
+
export declare function readProjectText(root: string, relativePath: string, maximumBytes?: number): Promise<string | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Read a JSON object without exposing its values in failures.
|
|
49
|
+
* @param root - Canonical project root
|
|
50
|
+
* @param relativePath - Project-relative JSON path
|
|
51
|
+
* @returns Parsed object, or undefined when absent
|
|
52
|
+
*/
|
|
53
|
+
export declare function readProjectJsonObject(root: string, relativePath: string): Promise<Readonly<Record<string, unknown>> | undefined>;
|
|
54
|
+
//# sourceMappingURL=read-only-fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-only-fs.d.ts","sourceRoot":"","sources":["../../src/health/read-only-fs.ts"],"names":[],"mappings":"AAQA,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAS7E;AAsCD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,YAAY,SAAoB,GAC/B,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAmC1C;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,YAAY,SAAoB,GAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE7B;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC,CAiB1B;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,YAAY,SAAoB,GAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAK7B;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAQxD"}
|