@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.
Files changed (138) hide show
  1. package/dist/core/lisa-plugin-selection.d.ts +11 -0
  2. package/dist/core/lisa-plugin-selection.d.ts.map +1 -1
  3. package/dist/core/lisa-plugin-selection.js +11 -1
  4. package/dist/core/lisa-plugin-selection.js.map +1 -1
  5. package/dist/core/lisa.d.ts +0 -41
  6. package/dist/core/lisa.d.ts.map +1 -1
  7. package/dist/core/lisa.js +23 -104
  8. package/dist/core/lisa.js.map +1 -1
  9. package/dist/core/template-ownership.d.ts +46 -0
  10. package/dist/core/template-ownership.d.ts.map +1 -0
  11. package/dist/core/template-ownership.js +123 -0
  12. package/dist/core/template-ownership.js.map +1 -0
  13. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  14. package/dist/core/upstream-evidence-manifest.js +20 -1
  15. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  16. package/dist/health/deadline.d.ts +25 -0
  17. package/dist/health/deadline.d.ts.map +1 -0
  18. package/dist/health/deadline.js +50 -0
  19. package/dist/health/deadline.js.map +1 -0
  20. package/dist/health/deterministic.d.ts +34 -0
  21. package/dist/health/deterministic.d.ts.map +1 -0
  22. package/dist/health/deterministic.js +206 -0
  23. package/dist/health/deterministic.js.map +1 -0
  24. package/dist/health/finding-utils.d.ts +17 -0
  25. package/dist/health/finding-utils.d.ts.map +1 -0
  26. package/dist/health/finding-utils.js +25 -0
  27. package/dist/health/finding-utils.js.map +1 -0
  28. package/dist/health/governance-probes.d.ts +51 -0
  29. package/dist/health/governance-probes.d.ts.map +1 -0
  30. package/dist/health/governance-probes.js +94 -0
  31. package/dist/health/governance-probes.js.map +1 -0
  32. package/dist/health/hook-inspection.d.ts +35 -0
  33. package/dist/health/hook-inspection.d.ts.map +1 -0
  34. package/dist/health/hook-inspection.js +123 -0
  35. package/dist/health/hook-inspection.js.map +1 -0
  36. package/dist/health/index.d.ts +1 -0
  37. package/dist/health/index.d.ts.map +1 -1
  38. package/dist/health/index.js +1 -0
  39. package/dist/health/index.js.map +1 -1
  40. package/dist/health/plugin-inspection.d.ts +37 -0
  41. package/dist/health/plugin-inspection.d.ts.map +1 -0
  42. package/dist/health/plugin-inspection.js +128 -0
  43. package/dist/health/plugin-inspection.js.map +1 -0
  44. package/dist/health/project-probes.d.ts +34 -0
  45. package/dist/health/project-probes.d.ts.map +1 -0
  46. package/dist/health/project-probes.js +104 -0
  47. package/dist/health/project-probes.js.map +1 -0
  48. package/dist/health/read-only-fs.d.ts +54 -0
  49. package/dist/health/read-only-fs.d.ts.map +1 -0
  50. package/dist/health/read-only-fs.js +165 -0
  51. package/dist/health/read-only-fs.js.map +1 -0
  52. package/dist/health/ruleset-inspection.d.ts +57 -0
  53. package/dist/health/ruleset-inspection.d.ts.map +1 -0
  54. package/dist/health/ruleset-inspection.js +315 -0
  55. package/dist/health/ruleset-inspection.js.map +1 -0
  56. package/dist/health/template-inspection.d.ts +67 -0
  57. package/dist/health/template-inspection.d.ts.map +1 -0
  58. package/dist/health/template-inspection.js +469 -0
  59. package/dist/health/template-inspection.js.map +1 -0
  60. package/dist/strategies/copy-contents.d.ts +7 -25
  61. package/dist/strategies/copy-contents.d.ts.map +1 -1
  62. package/dist/strategies/copy-contents.js +32 -63
  63. package/dist/strategies/copy-contents.js.map +1 -1
  64. package/dist/strategies/merge.d.ts +7 -0
  65. package/dist/strategies/merge.d.ts.map +1 -1
  66. package/dist/strategies/merge.js +10 -1
  67. package/dist/strategies/merge.js.map +1 -1
  68. package/dist/strategies/package-lisa.d.ts +10 -1
  69. package/dist/strategies/package-lisa.d.ts.map +1 -1
  70. package/dist/strategies/package-lisa.js +18 -20
  71. package/dist/strategies/package-lisa.js.map +1 -1
  72. package/dist/strategies/tagged-merge.d.ts +7 -0
  73. package/dist/strategies/tagged-merge.d.ts.map +1 -1
  74. package/dist/strategies/tagged-merge.js +10 -1
  75. package/dist/strategies/tagged-merge.js.map +1 -1
  76. package/dist/sync/config-sync.d.ts +7 -0
  77. package/dist/sync/config-sync.d.ts.map +1 -1
  78. package/dist/sync/config-sync.js +23 -16
  79. package/dist/sync/config-sync.js.map +1 -1
  80. package/dist/utils/ignore-patterns.d.ts +18 -0
  81. package/dist/utils/ignore-patterns.d.ts.map +1 -1
  82. package/dist/utils/ignore-patterns.js +2 -2
  83. package/dist/utils/ignore-patterns.js.map +1 -1
  84. package/package.json +3 -2
  85. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  87. package/plugins/lisa-agy/plugin.json +1 -1
  88. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  91. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  97. package/plugins/lisa-expo-agy/plugin.json +1 -1
  98. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  100. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  102. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  103. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  105. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  107. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  108. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  110. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  111. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  112. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  113. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  115. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  116. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  117. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  118. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  119. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  120. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  121. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  122. package/plugins/lisa-rails-agy/plugin.json +1 -1
  123. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  124. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  125. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  126. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  127. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  128. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  129. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  130. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  131. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  132. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  133. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  134. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  135. package/scripts/detect-stale-workflow-inputs.mjs +21 -148
  136. package/scripts/lib/reusable-workflow-contract.d.mts +24 -0
  137. package/scripts/lib/reusable-workflow-contract.mjs +123 -0
  138. package/scripts/verify-health-deterministic-built.mjs +499 -0
@@ -0,0 +1,25 @@
1
+ /** Absolute monotonic deadline and cancellation signal. */
2
+ export declare class HealthDeadline {
3
+ readonly signal: AbortSignal;
4
+ private readonly controller;
5
+ private readonly expired;
6
+ private readonly expiresAt;
7
+ private readonly timer;
8
+ /**
9
+ * Start a deadline immediately, before any project setup or detection.
10
+ * @param requestedMs - Requested total budget
11
+ */
12
+ constructor(requestedMs: number);
13
+ /** Remaining whole milliseconds available to a bounded command. */
14
+ remainingMs(): number;
15
+ /**
16
+ * Race one collaborator against the shared absolute deadline.
17
+ * @param work - Lazy collaborator so expired work never starts
18
+ * @param fallback - Value returned on timeout or collaborator failure
19
+ * @returns Work result or fallback
20
+ */
21
+ run<T>(work: () => Promise<T>, fallback: T): Promise<T>;
22
+ /** Release the deadline timer after collection finishes. */
23
+ close(): void;
24
+ }
25
+ //# sourceMappingURL=deadline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadline.d.ts","sourceRoot":"","sources":["../../src/health/deadline.ts"],"names":[],"mappings":"AAMA,2DAA2D;AAC3D,qBAAa,cAAc;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IAEvC;;;OAGG;gBACS,WAAW,EAAE,MAAM;IAW/B,mEAAmE;IACnE,WAAW,IAAI,MAAM;IAIrB;;;;;OAKG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ7D,4DAA4D;IAC5D,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,50 @@
1
+ /** One absolute wall-clock deadline shared by every health collaborator. */
2
+ /* eslint-disable jsdoc/require-returns -- typed deadline helpers are self-describing */
3
+ import { performance } from "node:perf_hooks";
4
+ const MAX_DEADLINE_MS = 119_000;
5
+ /** Absolute monotonic deadline and cancellation signal. */
6
+ export class HealthDeadline {
7
+ signal;
8
+ controller = new AbortController();
9
+ expired;
10
+ expiresAt;
11
+ timer;
12
+ /**
13
+ * Start a deadline immediately, before any project setup or detection.
14
+ * @param requestedMs - Requested total budget
15
+ */
16
+ constructor(requestedMs) {
17
+ const duration = Math.max(1, Math.min(requestedMs, MAX_DEADLINE_MS));
18
+ this.signal = this.controller.signal;
19
+ this.expiresAt = performance.now() + duration;
20
+ this.expired = new Promise(resolve => {
21
+ this.signal.addEventListener("abort", () => resolve(), { once: true });
22
+ });
23
+ this.timer = setTimeout(() => this.controller.abort(), duration);
24
+ this.timer.unref();
25
+ }
26
+ /** Remaining whole milliseconds available to a bounded command. */
27
+ remainingMs() {
28
+ return Math.max(0, Math.floor(this.expiresAt - performance.now()));
29
+ }
30
+ /**
31
+ * Race one collaborator against the shared absolute deadline.
32
+ * @param work - Lazy collaborator so expired work never starts
33
+ * @param fallback - Value returned on timeout or collaborator failure
34
+ * @returns Work result or fallback
35
+ */
36
+ async run(work, fallback) {
37
+ if (this.signal.aborted || this.remainingMs() === 0)
38
+ return fallback;
39
+ return Promise.race([
40
+ work().catch(() => fallback),
41
+ this.expired.then(() => fallback),
42
+ ]);
43
+ }
44
+ /** Release the deadline timer after collection finishes. */
45
+ close() {
46
+ clearTimeout(this.timer);
47
+ }
48
+ }
49
+ /* eslint-enable jsdoc/require-returns -- restore repository documentation defaults */
50
+ //# sourceMappingURL=deadline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadline.js","sourceRoot":"","sources":["../../src/health/deadline.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wFAAwF;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,eAAe,GAAG,OAAO,CAAC;AAEhC,2DAA2D;AAC3D,MAAM,OAAO,cAAc;IAChB,MAAM,CAAc;IACZ,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,OAAO,CAAgB;IACvB,SAAS,CAAS;IAClB,KAAK,CAAiB;IAEvC;;;OAGG;IACH,YAAY,WAAmB;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YACnC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,mEAAmE;IACnE,WAAW;QACT,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAI,IAAsB,EAAE,QAAW;QAC9C,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QACrE,OAAO,OAAO,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAED,4DAA4D;IAC5D,KAAK;QACH,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF;AACD,sFAAsF"}
@@ -0,0 +1,34 @@
1
+ import { type HealthResult } from "./contract.js";
2
+ import { type HooksPathReader } from "./hook-inspection.js";
3
+ import { type InstalledPluginReader } from "./plugin-inspection.js";
4
+ import { readGithubRulesets, type RulesetReader } from "./ruleset-inspection.js";
5
+ /**
6
+ * Injectable deterministic-health collaborators. Reader overrides must honor
7
+ * their AbortSignal and release owned handles; the runner bounds its own return
8
+ * but cannot reclaim arbitrary handles created by caller-supplied JavaScript.
9
+ */
10
+ export interface DeterministicHealthOptions {
11
+ /** Lisa package root containing stack templates. */
12
+ readonly lisaRoot?: string;
13
+ /** Total wall-clock deadline, including root/config/type setup. */
14
+ readonly deadlineMs?: number;
15
+ /** Injectable timestamp clock for contract tests. */
16
+ readonly now?: () => Date;
17
+ /** Injectable bounded detailed ruleset reader. */
18
+ readonly readRulesets?: RulesetReader;
19
+ /** Injectable bounded actual installed-plugin reader. */
20
+ readonly readInstalledPlugins?: InstalledPluginReader;
21
+ /** Injectable bounded repository hooks-path reader. */
22
+ readonly readHooksPath?: HooksPathReader;
23
+ }
24
+ /**
25
+ * Collect deterministic Health v1 without persistence, repair, installation,
26
+ * update checks, process-exit mutation, or model calls.
27
+ * @param projectPath - Host project root
28
+ * @param options - Injectable roots, deadline, clock, and bounded readers
29
+ * @returns Validated immutable deterministic HealthResult
30
+ */
31
+ export declare function runDeterministicHealth(projectPath: string, options?: DeterministicHealthOptions): Promise<HealthResult>;
32
+ export { readGithubRulesets };
33
+ export type { RulesetReader };
34
+ //# sourceMappingURL=deterministic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deterministic.d.ts","sourceRoot":"","sources":["../../src/health/deterministic.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAchC,OAAO,EACL,kBAAkB,EAElB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAQjC;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;IACtC,yDAAyD;IACzD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IACtD,uDAAuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;CAC1C;AAqOD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,YAAY,CAAC,CA4CvB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,206 @@
1
+ /** Side-effect-free deterministic Health v1 collection. */
2
+ /* eslint-disable jsdoc/require-param-description, jsdoc/require-returns -- typed probe assembly helpers are self-describing */
3
+ import { lstat, realpath } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { runConfigSync, } from "../sync/config-sync.js";
7
+ import { summarizeHealthFindings, validateHealthResult, } from "./contract.js";
8
+ import { HealthDeadline } from "./deadline.js";
9
+ import { deterministicFinding } from "./finding-utils.js";
10
+ import { hookFinding, managedTemplateFinding, packageFinding, pluginFinding, workflowFinding, } from "./governance-probes.js";
11
+ import { readCoreHooksPath } from "./hook-inspection.js";
12
+ import { readInstalledClaudePlugins, } from "./plugin-inspection.js";
13
+ import { configFindings, instructionFinding, projectStateFinding, starterFinding, wikiFinding, } from "./project-probes.js";
14
+ import { projectPathKind, readProjectJsonObject, readProjectText, } from "./read-only-fs.js";
15
+ import { readGithubRulesets, rulesetFinding, } from "./ruleset-inspection.js";
16
+ import { detectHealthProjectShape, } from "./template-inspection.js";
17
+ const DEFAULT_DEADLINE_MS = 110_000;
18
+ const CHECKS = [
19
+ { check: "project.state", unavailable: "fail" },
20
+ { check: "project.wiki", unavailable: "fail" },
21
+ { check: "starters.remote", unavailable: "warn" },
22
+ { check: "config.required", unavailable: "fail" },
23
+ { check: "config.sync", unavailable: "fail" },
24
+ { check: "templates.managed", unavailable: "fail" },
25
+ { check: "package.conformance", unavailable: "fail" },
26
+ { check: "instructions.canonical", unavailable: "fail" },
27
+ { check: "hooks.managed", unavailable: "fail" },
28
+ { check: "plugins.current", unavailable: "warn" },
29
+ { check: "ci.workflows", unavailable: "fail" },
30
+ { check: "github.rulesets", unavailable: "warn" },
31
+ ];
32
+ /**
33
+ * Stable fallback when a check cannot complete inside the shared deadline.
34
+ * @param check
35
+ * @param status
36
+ */
37
+ function unavailableFinding(check, status) {
38
+ return deterministicFinding(check, status, `${check} could not be safely observed within the deterministic deadline.`);
39
+ }
40
+ /**
41
+ * Read config while preserving missing vs malformed state.
42
+ * @param projectRoot
43
+ */
44
+ async function loadConfigState(projectRoot) {
45
+ const kind = await projectPathKind(projectRoot, ".lisa.config.json");
46
+ if (kind === "missing") {
47
+ return { config: {}, present: false, readable: false };
48
+ }
49
+ if (kind !== "file") {
50
+ return { config: {}, present: true, readable: false };
51
+ }
52
+ try {
53
+ const config = await readProjectJsonObject(projectRoot, ".lisa.config.json");
54
+ return { config: config ?? {}, present: true, readable: true };
55
+ }
56
+ catch {
57
+ return { config: {}, present: true, readable: false };
58
+ }
59
+ }
60
+ /**
61
+ * Confined JSON/path readers for the shared sync planner.
62
+ * @param projectRoot
63
+ */
64
+ function safeSyncReads(projectRoot) {
65
+ return {
66
+ readJson: async (relativePath) => {
67
+ const text = await readProjectText(projectRoot, relativePath);
68
+ if (text === undefined)
69
+ return null;
70
+ try {
71
+ return JSON.parse(text);
72
+ }
73
+ catch (error) {
74
+ if (error instanceof SyntaxError)
75
+ return null;
76
+ throw error;
77
+ }
78
+ },
79
+ pathExists: async (relativePath) => (await projectPathKind(projectRoot, relativePath)) !== "missing",
80
+ };
81
+ }
82
+ /**
83
+ * Build a validated immutable HealthResult from ordered findings.
84
+ * @param started
85
+ * @param completed
86
+ * @param findings
87
+ */
88
+ function result(started, completed, findings) {
89
+ const safeCompleted = completed < started ? started : completed;
90
+ return validateHealthResult({
91
+ schemaVersion: 1,
92
+ runId: `health-${crypto.randomUUID()}`,
93
+ mode: "deterministic",
94
+ startedAt: started.toISOString(),
95
+ completedAt: safeCompleted.toISOString(),
96
+ findings,
97
+ summary: summarizeHealthFindings(findings),
98
+ });
99
+ }
100
+ /**
101
+ * Resolve canonical project and Lisa roots inside the shared deadline.
102
+ * @param projectPath
103
+ * @param lisaPath
104
+ */
105
+ async function resolveRoots(projectPath, lisaPath) {
106
+ const [projectRoot, lisaRoot] = await Promise.all([
107
+ realpath(path.resolve(projectPath)),
108
+ realpath(lisaPath),
109
+ ]);
110
+ if (!(await lstat(projectRoot)).isDirectory()) {
111
+ throw new Error("Health project root is not a directory");
112
+ }
113
+ return { projectRoot, lisaRoot };
114
+ }
115
+ /**
116
+ * Create the fixed-order probe registry from safely captured setup state.
117
+ * @param roots
118
+ * @param roots.projectRoot
119
+ * @param roots.lisaRoot
120
+ * @param configState
121
+ * @param shape
122
+ * @param deadline
123
+ * @param options
124
+ */
125
+ // eslint-disable-next-line max-lines-per-function -- fixed-order registry keeps the complete contract auditable
126
+ function probes(roots, configState, shape, deadline, options) {
127
+ const safeShape = shape ?? {
128
+ types: [],
129
+ packageJson: undefined,
130
+ };
131
+ const sync = runConfigSync(roots.projectRoot, {
132
+ dryRun: true,
133
+ reads: safeSyncReads(roots.projectRoot),
134
+ });
135
+ return [
136
+ {
137
+ ...CHECKS[0],
138
+ run: () => projectStateFinding(roots.projectRoot, configState, shape),
139
+ },
140
+ { ...CHECKS[1], run: () => wikiFinding(roots.projectRoot) },
141
+ { ...CHECKS[2], run: async () => starterFinding() },
142
+ { ...CHECKS[3], run: async () => (await configFindings(await sync))[0] },
143
+ { ...CHECKS[4], run: async () => (await configFindings(await sync))[1] },
144
+ {
145
+ ...CHECKS[5],
146
+ run: () => managedTemplateFinding(roots.lisaRoot, roots.projectRoot, safeShape, configState.config),
147
+ },
148
+ {
149
+ ...CHECKS[6],
150
+ run: () => packageFinding(roots.lisaRoot, roots.projectRoot, safeShape),
151
+ },
152
+ { ...CHECKS[7], run: () => instructionFinding(roots.projectRoot) },
153
+ {
154
+ ...CHECKS[8],
155
+ run: () => hookFinding(roots.lisaRoot, roots.projectRoot, safeShape.types, configState.config, options.readHooksPath ?? readCoreHooksPath, deadline.remainingMs(), deadline.signal),
156
+ },
157
+ {
158
+ ...CHECKS[9],
159
+ run: () => pluginFinding(roots.projectRoot, configState.config, safeShape.types, options.readInstalledPlugins ?? readInstalledClaudePlugins, deadline.remainingMs(), deadline.signal),
160
+ },
161
+ {
162
+ ...CHECKS[10],
163
+ run: () => workflowFinding(roots.lisaRoot, roots.projectRoot, safeShape.types, configState.config),
164
+ },
165
+ {
166
+ ...CHECKS[11],
167
+ run: () => rulesetFinding(roots.lisaRoot, roots.projectRoot, safeShape.types, configState.config, options.readRulesets ?? readGithubRulesets, deadline.remainingMs(), deadline.signal),
168
+ },
169
+ ];
170
+ }
171
+ /**
172
+ * Collect deterministic Health v1 without persistence, repair, installation,
173
+ * update checks, process-exit mutation, or model calls.
174
+ * @param projectPath - Host project root
175
+ * @param options - Injectable roots, deadline, clock, and bounded readers
176
+ * @returns Validated immutable deterministic HealthResult
177
+ */
178
+ export async function runDeterministicHealth(projectPath, options = {}) {
179
+ const now = options.now ?? (() => new Date());
180
+ const started = now();
181
+ const deadline = new HealthDeadline(options.deadlineMs ?? DEFAULT_DEADLINE_MS);
182
+ try {
183
+ const lisaPath = options.lisaRoot ??
184
+ path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
185
+ const roots = await deadline.run(() => resolveRoots(projectPath, lisaPath), undefined);
186
+ if (roots === undefined) {
187
+ return result(started, now(), CHECKS.map(spec => unavailableFinding(spec.check, spec.unavailable)));
188
+ }
189
+ const [configState, shape] = await Promise.all([
190
+ deadline.run(() => loadConfigState(roots.projectRoot), {
191
+ config: {},
192
+ present: false,
193
+ readable: false,
194
+ }),
195
+ deadline.run(() => detectHealthProjectShape(roots.projectRoot), undefined),
196
+ ]);
197
+ const findings = await Promise.all(probes(roots, configState, shape, deadline, options).map(probe => deadline.run(probe.run, unavailableFinding(probe.check, probe.unavailable))));
198
+ return result(started, now(), findings);
199
+ }
200
+ finally {
201
+ deadline.close();
202
+ }
203
+ }
204
+ export { readGithubRulesets };
205
+ /* eslint-enable jsdoc/require-param-description, jsdoc/require-returns -- restore repository documentation defaults */
206
+ //# sourceMappingURL=deterministic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deterministic.js","sourceRoot":"","sources":["../../src/health/deterministic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Stable, bounded deterministic health finding helpers. */
2
+ import type { HealthFinding, HealthStatus } from "./contract.js";
3
+ /**
4
+ * Create one deterministic finding.
5
+ * @param check
6
+ * @param status
7
+ * @param reason
8
+ */
9
+ export declare function deterministicFinding(check: string, status: HealthStatus, reason: string): HealthFinding;
10
+ /**
11
+ * Format a bounded sorted identifier list without exposing values.
12
+ * @param label - Stable human prefix
13
+ * @param names - Safe relative paths, keys, or public contract names
14
+ * @returns Bounded reason
15
+ */
16
+ export declare function namedReason(label: string, names: readonly string[]): string;
17
+ //# sourceMappingURL=finding-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-utils.d.ts","sourceRoot":"","sources":["../../src/health/finding-utils.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,aAAa,CAEf;AAGD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAU3E"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Create one deterministic finding.
3
+ * @param check
4
+ * @param status
5
+ * @param reason
6
+ */
7
+ export function deterministicFinding(check, status, reason) {
8
+ return { check, layer: "deterministic", status, reason };
9
+ }
10
+ /* eslint-enable jsdoc/require-param-description, jsdoc/require-returns -- restore repository documentation defaults */
11
+ /**
12
+ * Format a bounded sorted identifier list without exposing values.
13
+ * @param label - Stable human prefix
14
+ * @param names - Safe relative paths, keys, or public contract names
15
+ * @returns Bounded reason
16
+ */
17
+ export function namedReason(label, names) {
18
+ const sorted = [...new Set(names)].sort((left, right) => left.localeCompare(right));
19
+ const shown = sorted.slice(0, 12);
20
+ const suffix = sorted.length > shown.length
21
+ ? ` (+${sorted.length - shown.length} more)`
22
+ : "";
23
+ return `${label}: ${shown.join(", ")}${suffix}`;
24
+ }
25
+ //# sourceMappingURL=finding-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-utils.js","sourceRoot":"","sources":["../../src/health/finding-utils.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,MAAoB,EACpB,MAAc;IAEd,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC3D,CAAC;AACD,uHAAuH;AAEvH;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,KAAwB;IACjE,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACtD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAC1B,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QAC1B,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,QAAQ;QAC5C,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,51 @@
1
+ /** Template, package, hook, plugin, and CI deterministic health probes. */
2
+ import type { ProjectType } from "../core/config.js";
3
+ import type { HealthFinding } from "./contract.js";
4
+ import { type HooksPathReader } from "./hook-inspection.js";
5
+ import { type InstalledPluginReader } from "./plugin-inspection.js";
6
+ import { type HealthProjectShape } from "./template-inspection.js";
7
+ /**
8
+ * Managed template finding.
9
+ * @param lisaRoot
10
+ * @param projectRoot
11
+ * @param shape
12
+ * @param config
13
+ */
14
+ export declare function managedTemplateFinding(lisaRoot: string, projectRoot: string, shape: HealthProjectShape, config: Readonly<Record<string, unknown>>): Promise<HealthFinding>;
15
+ /**
16
+ * Package governance finding.
17
+ * @param lisaRoot
18
+ * @param projectRoot
19
+ * @param shape
20
+ */
21
+ export declare function packageFinding(lisaRoot: string, projectRoot: string, shape: HealthProjectShape): Promise<HealthFinding>;
22
+ /**
23
+ * Hook bytes, mode, and installed-state finding.
24
+ * @param lisaRoot
25
+ * @param projectRoot
26
+ * @param types
27
+ * @param config
28
+ * @param reader
29
+ * @param timeoutMs
30
+ * @param signal
31
+ */
32
+ export declare function hookFinding(lisaRoot: string, projectRoot: string, types: readonly ProjectType[], config: Readonly<Record<string, unknown>>, reader: HooksPathReader, timeoutMs: number, signal: AbortSignal): Promise<HealthFinding>;
33
+ /**
34
+ * Actual enabled and installed plugin finding.
35
+ * @param projectRoot
36
+ * @param config
37
+ * @param types
38
+ * @param reader
39
+ * @param timeoutMs
40
+ * @param signal
41
+ */
42
+ export declare function pluginFinding(projectRoot: string, config: Readonly<Record<string, unknown>>, types: readonly ProjectType[], reader: InstalledPluginReader, timeoutMs: number, signal: AbortSignal): Promise<HealthFinding>;
43
+ /**
44
+ * Workflow presence, managed bytes, and reusable-input contract finding.
45
+ * @param lisaRoot
46
+ * @param projectRoot
47
+ * @param types
48
+ * @param config
49
+ */
50
+ export declare function workflowFinding(lisaRoot: string, projectRoot: string, types: readonly ProjectType[], config: Readonly<Record<string, unknown>>): Promise<HealthFinding>;
51
+ //# sourceMappingURL=governance-probes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance-probes.d.ts","sourceRoot":"","sources":["../../src/health/governance-probes.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAMlC;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,aAAa,CAAC,CAkBxB;AACD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAwBxB;AACD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,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,aAAa,CAAC,CAwBxB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,OAAO,CAAC,aAAa,CAAC,CAyBxB"}
@@ -0,0 +1,94 @@
1
+ import { deterministicFinding, namedReason } from "./finding-utils.js";
2
+ import { inspectHookInstallation, } from "./hook-inspection.js";
3
+ import { inspectPlugins, } from "./plugin-inspection.js";
4
+ import { inspectCreateOnlyWorkflows, inspectManagedTemplates, inspectWorkflowInputs, packageJsonConforms, } from "./template-inspection.js";
5
+ const HOOK_CHECK = "hooks.managed";
6
+ const PLUGIN_CHECK = "plugins.current";
7
+ const WORKFLOW_CHECK = "ci.workflows";
8
+ /**
9
+ * Managed template finding.
10
+ * @param lisaRoot
11
+ * @param projectRoot
12
+ * @param shape
13
+ * @param config
14
+ */
15
+ export async function managedTemplateFinding(lisaRoot, projectRoot, shape, config) {
16
+ const drift = await inspectManagedTemplates(lisaRoot, projectRoot, shape.types, "managed", config);
17
+ return drift.length === 0
18
+ ? deterministicFinding("templates.managed", "pass", "Managed files match their ownership-aware templates.")
19
+ : deterministicFinding("templates.managed", "fail", namedReason("Managed files do not match templates", drift));
20
+ }
21
+ /**
22
+ * Package governance finding.
23
+ * @param lisaRoot
24
+ * @param projectRoot
25
+ * @param shape
26
+ */
27
+ export async function packageFinding(lisaRoot, projectRoot, shape) {
28
+ const conforms = await packageJsonConforms(lisaRoot, projectRoot, shape.types, shape.packageJson);
29
+ return conforms
30
+ ? deterministicFinding("package.conformance", "pass", "package.json conforms to Lisa governance.")
31
+ : deterministicFinding("package.conformance", "fail", "Package drift: package.json");
32
+ }
33
+ /**
34
+ * Hook bytes, mode, and installed-state finding.
35
+ * @param lisaRoot
36
+ * @param projectRoot
37
+ * @param types
38
+ * @param config
39
+ * @param reader
40
+ * @param timeoutMs
41
+ * @param signal
42
+ */
43
+ export async function hookFinding(lisaRoot, projectRoot, types, config, reader, timeoutMs, signal) {
44
+ const [templateDrift, installed] = await Promise.all([
45
+ inspectManagedTemplates(lisaRoot, projectRoot, types, "hooks", config),
46
+ inspectHookInstallation(projectRoot, types, reader, timeoutMs, signal),
47
+ ]);
48
+ const drift = [...templateDrift, ...installed.drift];
49
+ if (templateDrift.length > 0 || installed.status === "fail") {
50
+ return deterministicFinding(HOOK_CHECK, "fail", namedReason("Git hook drift", drift));
51
+ }
52
+ return installed.status === "warn"
53
+ ? deterministicFinding(HOOK_CHECK, "warn", namedReason("Git hook state unavailable", installed.drift))
54
+ : deterministicFinding(HOOK_CHECK, "pass", "Git hook bytes, modes, and installation are current.");
55
+ }
56
+ /**
57
+ * Actual enabled and installed plugin finding.
58
+ * @param projectRoot
59
+ * @param config
60
+ * @param types
61
+ * @param reader
62
+ * @param timeoutMs
63
+ * @param signal
64
+ */
65
+ export async function pluginFinding(projectRoot, config, types, reader, timeoutMs, signal) {
66
+ const inspected = await inspectPlugins(projectRoot, config, types, reader, timeoutMs, signal);
67
+ if (inspected.status === "pass") {
68
+ return deterministicFinding(PLUGIN_CHECK, "pass", "Lisa plugins are enabled, installed, and version-current.");
69
+ }
70
+ return deterministicFinding(PLUGIN_CHECK, inspected.status, namedReason(inspected.status === "warn" ? "Plugin state unavailable" : "Plugin drift", inspected.drift));
71
+ }
72
+ /**
73
+ * Workflow presence, managed bytes, and reusable-input contract finding.
74
+ * @param lisaRoot
75
+ * @param projectRoot
76
+ * @param types
77
+ * @param config
78
+ */
79
+ export async function workflowFinding(lisaRoot, projectRoot, types, config) {
80
+ const [managed, missing, inputs] = await Promise.all([
81
+ inspectManagedTemplates(lisaRoot, projectRoot, types, "workflows", config),
82
+ inspectCreateOnlyWorkflows(lisaRoot, projectRoot, types, config),
83
+ inspectWorkflowInputs(lisaRoot, projectRoot, types, config),
84
+ ]);
85
+ const drift = [...managed, ...missing, ...inputs.stale];
86
+ if (drift.length > 0) {
87
+ return deterministicFinding(WORKFLOW_CHECK, "fail", namedReason("CI workflow drift", drift));
88
+ }
89
+ return inputs.unknown.length > 0
90
+ ? deterministicFinding(WORKFLOW_CHECK, "warn", namedReason("Reusable workflow contracts unavailable", inputs.unknown))
91
+ : deterministicFinding(WORKFLOW_CHECK, "pass", "CI workflows are present and caller inputs match shipped contracts.");
92
+ }
93
+ /* eslint-enable jsdoc/require-param-description, jsdoc/require-returns -- restore repository documentation defaults */
94
+ //# sourceMappingURL=governance-probes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance-probes.js","sourceRoot":"","sources":["../../src/health/governance-probes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { ProjectType } from "../core/config.js";
2
+ /**
3
+ * Injectable reader for repository-local core.hooksPath. Implementations must
4
+ * honor `signal` and release any owned handles before settling.
5
+ */
6
+ export type HooksPathReader = (projectRoot: string, timeoutMs: number, signal: AbortSignal) => Promise<string | undefined>;
7
+ /** Hook installation outcome. */
8
+ export type HookInstallationInspection = {
9
+ readonly status: "pass";
10
+ readonly drift: readonly string[];
11
+ } | {
12
+ readonly status: "warn";
13
+ readonly drift: readonly string[];
14
+ } | {
15
+ readonly status: "fail";
16
+ readonly drift: readonly string[];
17
+ };
18
+ /**
19
+ * Default fixed-argv local git-config reader.
20
+ * @param projectRoot
21
+ * @param timeoutMs
22
+ * @param signal
23
+ */
24
+ export declare const readCoreHooksPath: HooksPathReader;
25
+ /**
26
+ * Inspect actual installed hook state for applicable stacks.
27
+ * @param projectRoot - Canonical host root
28
+ * @param types - Safely detected project types
29
+ * @param reader - core.hooksPath reader
30
+ * @param timeoutMs - Remaining shared deadline
31
+ * @param signal - Shared cancellation signal
32
+ * @returns Hook installation status
33
+ */
34
+ export declare function inspectHookInstallation(projectRoot: string, types: readonly ProjectType[], reader: HooksPathReader, timeoutMs: number, signal: AbortSignal): Promise<HookInstallationInspection>;
35
+ //# sourceMappingURL=hook-inspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-inspection.d.ts","sourceRoot":"","sources":["../../src/health/hook-inspection.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAuBrD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,KAChB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjC,iCAAiC;AACjC,MAAM,MAAM,0BAA0B,GAClC;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,iBAAiB,EAAE,eA8B5B,CAAC;AA4DL;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,0BAA0B,CAAC,CAyBrC"}