@codyswann/lisa 2.279.2 → 2.281.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 (112) hide show
  1. package/dist/cli/doctor-readiness-audit-allowlist.d.ts +7 -0
  2. package/dist/cli/doctor-readiness-audit-allowlist.d.ts.map +1 -0
  3. package/dist/cli/doctor-readiness-audit-allowlist.js +177 -0
  4. package/dist/cli/doctor-readiness-audit-allowlist.js.map +1 -0
  5. package/dist/cli/doctor-readiness-capabilities.d.ts +33 -0
  6. package/dist/cli/doctor-readiness-capabilities.d.ts.map +1 -0
  7. package/dist/cli/doctor-readiness-capabilities.js +26 -0
  8. package/dist/cli/doctor-readiness-capabilities.js.map +1 -0
  9. package/dist/cli/doctor-readiness-context-claims.d.ts +14 -0
  10. package/dist/cli/doctor-readiness-context-claims.d.ts.map +1 -0
  11. package/dist/cli/doctor-readiness-context-claims.js +117 -0
  12. package/dist/cli/doctor-readiness-context-claims.js.map +1 -0
  13. package/dist/cli/doctor-readiness-context-mechanisms.d.ts +46 -0
  14. package/dist/cli/doctor-readiness-context-mechanisms.d.ts.map +1 -0
  15. package/dist/cli/doctor-readiness-context-mechanisms.js +116 -0
  16. package/dist/cli/doctor-readiness-context-mechanisms.js.map +1 -0
  17. package/dist/cli/doctor-readiness-context.d.ts +16 -0
  18. package/dist/cli/doctor-readiness-context.d.ts.map +1 -0
  19. package/dist/cli/doctor-readiness-context.js +244 -0
  20. package/dist/cli/doctor-readiness-context.js.map +1 -0
  21. package/dist/cli/doctor-readiness-delivery.d.ts.map +1 -1
  22. package/dist/cli/doctor-readiness-delivery.js +1 -10
  23. package/dist/cli/doctor-readiness-delivery.js.map +1 -1
  24. package/dist/cli/doctor-readiness-domain.d.ts +17 -0
  25. package/dist/cli/doctor-readiness-domain.d.ts.map +1 -0
  26. package/dist/cli/doctor-readiness-domain.js +197 -0
  27. package/dist/cli/doctor-readiness-domain.js.map +1 -0
  28. package/dist/cli/doctor-readiness-guardrails.d.ts +15 -0
  29. package/dist/cli/doctor-readiness-guardrails.d.ts.map +1 -0
  30. package/dist/cli/doctor-readiness-guardrails.js +219 -0
  31. package/dist/cli/doctor-readiness-guardrails.js.map +1 -0
  32. package/dist/cli/doctor-readiness-operations.d.ts +103 -0
  33. package/dist/cli/doctor-readiness-operations.d.ts.map +1 -0
  34. package/dist/cli/doctor-readiness-operations.js +207 -0
  35. package/dist/cli/doctor-readiness-operations.js.map +1 -0
  36. package/dist/cli/doctor-readiness-shared.d.ts +47 -0
  37. package/dist/cli/doctor-readiness-shared.d.ts.map +1 -0
  38. package/dist/cli/doctor-readiness-shared.js +88 -0
  39. package/dist/cli/doctor-readiness-shared.js.map +1 -0
  40. package/dist/cli/doctor-readiness-supply-chain-scan.d.ts +67 -0
  41. package/dist/cli/doctor-readiness-supply-chain-scan.d.ts.map +1 -0
  42. package/dist/cli/doctor-readiness-supply-chain-scan.js +316 -0
  43. package/dist/cli/doctor-readiness-supply-chain-scan.js.map +1 -0
  44. package/dist/cli/doctor-readiness-supply-chain.d.ts +14 -0
  45. package/dist/cli/doctor-readiness-supply-chain.d.ts.map +1 -0
  46. package/dist/cli/doctor-readiness-supply-chain.js +231 -0
  47. package/dist/cli/doctor-readiness-supply-chain.js.map +1 -0
  48. package/dist/cli/doctor-readiness-workflows.d.ts +20 -0
  49. package/dist/cli/doctor-readiness-workflows.d.ts.map +1 -1
  50. package/dist/cli/doctor-readiness-workflows.js +29 -7
  51. package/dist/cli/doctor-readiness-workflows.js.map +1 -1
  52. package/dist/cli/doctor-readiness-workspaces.d.ts +22 -0
  53. package/dist/cli/doctor-readiness-workspaces.d.ts.map +1 -0
  54. package/dist/cli/doctor-readiness-workspaces.js +98 -0
  55. package/dist/cli/doctor-readiness-workspaces.js.map +1 -0
  56. package/dist/cli/doctor-readiness.d.ts.map +1 -1
  57. package/dist/cli/doctor-readiness.js +23 -13
  58. package/dist/cli/doctor-readiness.js.map +1 -1
  59. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  60. package/dist/core/upstream-evidence-manifest.js +23 -0
  61. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  62. package/package.json +1 -1
  63. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  65. package/plugins/lisa-agy/plugin.json +1 -1
  66. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  68. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  69. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  75. package/plugins/lisa-expo-agy/plugin.json +1 -1
  76. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  81. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  86. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  91. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  96. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  100. package/plugins/lisa-rails-agy/plugin.json +1 -1
  101. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  106. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  110. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  111. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Helpers shared by every readiness producer (PRD #1739, #1896).
3
+ *
4
+ * Three things were being re-implemented per producer: reading a repository file
5
+ * without letting a missing file throw, asking whether a repository path exists,
6
+ * and wrapping a non-blocking observation as a finding. The last one is the
7
+ * load-bearing case — an observation finding must carry NO `blocker` key,
8
+ * because the blocker engine stands a blocker up on any finding that names an id
9
+ * and carries evidence regardless of the finding's status. One definition means
10
+ * that rule cannot drift apart across producers.
11
+ * @module cli/doctor-readiness-shared
12
+ */
13
+ import { readdir, readFile } from "node:fs/promises";
14
+ import * as path from "node:path";
15
+ /**
16
+ * Read a repository-relative file, returning null when it cannot be read.
17
+ *
18
+ * Reading is best-effort by design: a file that cannot be read establishes
19
+ * nothing, and a readiness producer must never turn "could not look" into
20
+ * either a violation or a clean bill of health.
21
+ * @param root - Repository root
22
+ * @param relativePath - Repo-relative path (forward slashes)
23
+ * @returns File contents, or null
24
+ */
25
+ export async function readFileOrNull(root, relativePath) {
26
+ try {
27
+ return await readFile(path.join(root, ...relativePath.split("/")), "utf8");
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Whether a repository-relative directory exists.
35
+ * @param root - Repository root
36
+ * @param relativePath - Repo-relative directory path
37
+ * @returns True when the directory could be listed
38
+ */
39
+ export async function directoryExists(root, relativePath) {
40
+ try {
41
+ await readdir(path.join(root, ...relativePath.split("/")));
42
+ return true;
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }
48
+ /**
49
+ * Whether a repository-relative path exists, as a file or a directory.
50
+ * @param root - Repository root
51
+ * @param relativePath - Repo-relative path
52
+ * @returns True when something is present at that path
53
+ */
54
+ export async function pathExists(root, relativePath) {
55
+ return ((await readFileOrNull(root, relativePath)) !== null ||
56
+ (await directoryExists(root, relativePath)));
57
+ }
58
+ /**
59
+ * Strip leading and trailing slashes from a repo-relative path fragment.
60
+ * Written without a regex quantifier so it cannot backtrack on hostile input.
61
+ * @param value - The path fragment
62
+ * @returns The fragment with empty segments removed
63
+ */
64
+ export function trimSlashes(value) {
65
+ return value
66
+ .split("/")
67
+ .filter(segment => segment !== "")
68
+ .join("/");
69
+ }
70
+ /**
71
+ * Whether a value is a plain JSON object.
72
+ * @param value - Candidate value
73
+ * @returns True when the value is a non-null, non-array object
74
+ */
75
+ export function isRecord(value) {
76
+ return typeof value === "object" && value !== null && !Array.isArray(value);
77
+ }
78
+ /**
79
+ * Wrap non-blocking observations as findings. They deliberately carry no
80
+ * `blocker` key: naming one would stand a blocker up — and flip the whole
81
+ * repository to `NOT_READY` — on an observation that was never decidable.
82
+ * @param notes - Informational lines
83
+ * @returns Findings, one per note
84
+ */
85
+ export function informationalFindings(notes) {
86
+ return notes.map(note => ({ observation: note, blocking: false }));
87
+ }
88
+ //# sourceMappingURL=doctor-readiness-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-readiness-shared.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,YAAoB;IAEpB,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,YAAoB;IAEpB,OAAO,CACL,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,KAAK,IAAI;QACnD,CAAC,MAAM,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC;SACjC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAwB;IAExB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Every lockfile spelling a JavaScript package manager writes. One of these
3
+ * being committed is what makes two installs resolve to the same tree.
4
+ */
5
+ export declare const LOCKFILES: readonly string[];
6
+ /**
7
+ * Whether a dependency spec resolves to whatever is newest at install time
8
+ * rather than to a version something was validated against.
9
+ *
10
+ * Four families are recognized, and the narrowness of each is deliberate — every
11
+ * over-eager rule here fails a correctly configured repository:
12
+ *
13
+ * - **Local protocols** resolve inside the repository and never float.
14
+ * - **Registry aliases** (`npm:left-pad@latest`) hide the real spec behind the
15
+ * alias, so the part after the version separator is re-tested.
16
+ * - **Repository clones** (`github:acme/widget`, `git+https://…/x.git`) float
17
+ * unless anchored to a `#<sha|tag>` revision, because the branch tip moves
18
+ * under the install. An archive URL (`…/widget-1.2.3.tgz`) is NOT a clone: it
19
+ * names one built artifact and is treated as pinned.
20
+ * - **Plain ranges** float only when they name no version at all. A `>=` floor
21
+ * in `overrides` is the recommended way to force a patched transitive
22
+ * dependency, so ranges are otherwise left alone.
23
+ * @param spec - The declared spec text
24
+ * @returns True when the spec floats
25
+ */
26
+ export declare function isFloatingSpec(spec: string): boolean;
27
+ /** What reading the manifest established. */
28
+ export type ManifestOutcome = {
29
+ readonly kind: "ok";
30
+ readonly manifest: Record<string, unknown>;
31
+ } | {
32
+ readonly kind: "unassessable";
33
+ readonly reason: string;
34
+ };
35
+ /**
36
+ * Read and parse `package.json`, distinguishing "absent" from "unparseable" so
37
+ * the SKIP reason can say which one happened.
38
+ * @param root - Repository root
39
+ * @returns The parsed manifest, or the reason it cannot be assessed
40
+ */
41
+ export declare function readManifest(root: string): Promise<ManifestOutcome>;
42
+ /** One declared dependency spec, flattened out of the manifest blocks. */
43
+ export interface DependencySpec {
44
+ readonly block: string;
45
+ readonly name: string;
46
+ readonly spec: string;
47
+ }
48
+ /**
49
+ * Flatten every versioned manifest block into one list of specs.
50
+ * @param manifest - Parsed `package.json`
51
+ * @returns Every declared spec across the versioned blocks
52
+ */
53
+ export declare function collectSpecs(manifest: Record<string, unknown>): readonly DependencySpec[];
54
+ /**
55
+ * Find the committed lockfile, if any.
56
+ * @param root - Repository root
57
+ * @returns The lockfile name, or null when none is committed
58
+ */
59
+ export declare function findLockfile(root: string): Promise<string | null>;
60
+ /**
61
+ * Find where the repository audits its dependency tree: a CI job, a git hook, a
62
+ * lefthook declaration, or an update bot.
63
+ * @param root - Repository root
64
+ * @returns The repo-relative path of the first gate found, or null
65
+ */
66
+ export declare function findAuditGate(root: string): Promise<string | null>;
67
+ //# sourceMappingURL=doctor-readiness-supply-chain-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-readiness-supply-chain-scan.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-supply-chain-scan.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAOtC,CAAC;AAoFF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAepD;AAyCD,6CAA6C;AAC7C,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAsC/D;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA2BzE;AAED,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA4BD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,SAAS,cAAc,EAAE,CAI3B;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOvE;AAkBD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxE"}
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Offline supply-chain scanning for the dependencies/supply-chain readiness
3
+ * producer (B5, PRD #1739, #1896).
4
+ *
5
+ * The B5 question — does belief that the owned surface still works rest on more
6
+ * than hope — is answered from four repository facts: a committed lockfile, the
7
+ * dependency specs the manifest names, whether anything anywhere audits the
8
+ * tree, and whether each audit exception carries the decision behind it. This
9
+ * module gathers those facts; its sibling turns them into the rubric-shaped
10
+ * dimension record. Splitting them keeps each file inside the repository's
11
+ * file-size budget and keeps the gathering independently testable.
12
+ *
13
+ * Reading is offline and best-effort by construction: an unreadable file
14
+ * establishes nothing and is passed over, never reported as a violation.
15
+ * @module cli/doctor-readiness-supply-chain-scan
16
+ */
17
+ import { readdir } from "node:fs/promises";
18
+ import * as path from "node:path";
19
+ import { isRecord, readFileOrNull } from "./doctor-readiness-shared.js";
20
+ /**
21
+ * Every lockfile spelling a JavaScript package manager writes. One of these
22
+ * being committed is what makes two installs resolve to the same tree.
23
+ */
24
+ export const LOCKFILES = [
25
+ "bun.lock",
26
+ "bun.lockb",
27
+ "package-lock.json",
28
+ "npm-shrinkwrap.json",
29
+ "yarn.lock",
30
+ "pnpm-lock.yaml",
31
+ ];
32
+ /**
33
+ * Manifest blocks whose specs must name a version. `peerDependencies` is
34
+ * deliberately excluded: `*` there is the conventional way to say "any host
35
+ * version works", not a floating install.
36
+ */
37
+ const VERSIONED_BLOCKS = [
38
+ "dependencies",
39
+ "devDependencies",
40
+ "optionalDependencies",
41
+ "overrides",
42
+ "resolutions",
43
+ ];
44
+ /**
45
+ * Specs that resolve to whatever is newest at install time. Deliberately narrow:
46
+ * a `>=` floor in `overrides` is the recommended way to force a patched
47
+ * transitive dependency, so treating ranges as floating would fault the very
48
+ * remediation the audit gate asks for.
49
+ */
50
+ const FLOATING_SPECS = new Set([
51
+ "",
52
+ "*",
53
+ "x",
54
+ "X",
55
+ "*.*",
56
+ "*.*.*",
57
+ "latest",
58
+ "next",
59
+ "*.x",
60
+ ]);
61
+ /**
62
+ * Protocols that resolve to something inside this repository rather than to a
63
+ * published version, so there is nothing to pin and nothing to drift.
64
+ */
65
+ const LOCAL_PROTOCOLS = [
66
+ "workspace:",
67
+ "file:",
68
+ "link:",
69
+ "portal:",
70
+ ];
71
+ /**
72
+ * Protocols that clone a source tree. Without a ref these resolve to whatever
73
+ * the default branch holds at install time, which is the drift B5 cares about.
74
+ * Each alternative ends in `:` or `+` on purpose — a colonless `bitbucket`
75
+ * alternative would match the ordinary registry package `bitbucket-client`.
76
+ */
77
+ const GIT_FETCH_PROTOCOL = /^(github:|gitlab:|bitbucket:|git\+|git:)/i;
78
+ /** An `http(s)` spec, which may clone a repository or download an archive. */
79
+ const HTTP_SPEC = /^https?:\/\//i;
80
+ /**
81
+ * Whether a source-fetch spec is anchored to one revision by a `#<sha|tag>`
82
+ * suffix. Written without a regex so it cannot backtrack on a hostile spec.
83
+ * @param spec - The declared spec text
84
+ * @returns True when a non-empty ref follows a `#`
85
+ */
86
+ function hasImmutableRef(spec) {
87
+ const marker = spec.indexOf("#");
88
+ return marker >= 0 && spec.slice(marker + 1).trim() !== "";
89
+ }
90
+ /**
91
+ * Whether a spec clones a git repository.
92
+ *
93
+ * The distinction this draws is the whole point: `git+https://…/widget.git`
94
+ * tracks a moving branch tip, but `https://…/widget-1.2.3.tgz` names one built
95
+ * archive that cannot become something newer tomorrow. Demanding a `#ref` of an
96
+ * archive URL would fault a repository that is already perfectly pinned.
97
+ * @param spec - The declared spec text
98
+ * @returns True when the spec resolves by cloning a repository
99
+ */
100
+ function clonesRepository(spec) {
101
+ const beforeRef = spec.split("#")[0] ?? "";
102
+ return (GIT_FETCH_PROTOCOL.test(spec) ||
103
+ (HTTP_SPEC.test(spec) && beforeRef.toLowerCase().endsWith(".git")));
104
+ }
105
+ /**
106
+ * Whether a dependency spec resolves to whatever is newest at install time
107
+ * rather than to a version something was validated against.
108
+ *
109
+ * Four families are recognized, and the narrowness of each is deliberate — every
110
+ * over-eager rule here fails a correctly configured repository:
111
+ *
112
+ * - **Local protocols** resolve inside the repository and never float.
113
+ * - **Registry aliases** (`npm:left-pad@latest`) hide the real spec behind the
114
+ * alias, so the part after the version separator is re-tested.
115
+ * - **Repository clones** (`github:acme/widget`, `git+https://…/x.git`) float
116
+ * unless anchored to a `#<sha|tag>` revision, because the branch tip moves
117
+ * under the install. An archive URL (`…/widget-1.2.3.tgz`) is NOT a clone: it
118
+ * names one built artifact and is treated as pinned.
119
+ * - **Plain ranges** float only when they name no version at all. A `>=` floor
120
+ * in `overrides` is the recommended way to force a patched transitive
121
+ * dependency, so ranges are otherwise left alone.
122
+ * @param spec - The declared spec text
123
+ * @returns True when the spec floats
124
+ */
125
+ export function isFloatingSpec(spec) {
126
+ const trimmed = spec.trim();
127
+ if (LOCAL_PROTOCOLS.some(protocol => trimmed.startsWith(protocol))) {
128
+ return false;
129
+ }
130
+ if (/^npm:/i.test(trimmed)) {
131
+ const separator = trimmed.lastIndexOf("@");
132
+ return separator > "npm:".length
133
+ ? isFloatingSpec(trimmed.slice(separator + 1))
134
+ : true;
135
+ }
136
+ if (clonesRepository(trimmed)) {
137
+ return !hasImmutableRef(trimmed);
138
+ }
139
+ return FLOATING_SPECS.has(trimmed.toLowerCase());
140
+ }
141
+ /**
142
+ * Commands and actions that actually audit the DEPENDENCY tree. A job merely
143
+ * titled "Security Scan" is deliberately not enough: a secret scanner proves
144
+ * nothing about the dependency tree, and counting it would be a false green —
145
+ * the worst direction to err for a confidence model.
146
+ */
147
+ const AUDIT_GATE_PATTERN = /\b(npm|bun|yarn|pnpm)\s+audit\b|audit-ci|osv-scanner|dependency-review-action|\bsnyk\b|\btrivy\b|\bgrype\b/i;
148
+ /**
149
+ * An update bot covering the JavaScript dependency tree. A `dependabot.yml`
150
+ * that only watches `github-actions` never looks at `package.json`, so its mere
151
+ * presence is not a confidence model for the dependencies.
152
+ */
153
+ const JS_ECOSYSTEM_PATTERN = /package-ecosystem:\s*["']?(npm|bun|yarn|pnpm)\b/i;
154
+ /** Files that may declare an audit gate in their text. */
155
+ const GATE_DIRECTORIES = [
156
+ path.join(".github", "workflows"),
157
+ ".husky",
158
+ ];
159
+ /** Single-file gate declarations checked by text match. */
160
+ const GATE_FILES = [
161
+ "lefthook.yml",
162
+ "lefthook.yaml",
163
+ ".lefthook.yml",
164
+ ];
165
+ /** Update bots whose mere presence is a standing confidence model. */
166
+ const UPDATE_BOT_FILES = [
167
+ path.join(".github", "dependabot.yml"),
168
+ path.join(".github", "dependabot.yaml"),
169
+ path.join(".github", "renovate.json"),
170
+ "renovate.json",
171
+ ".renovaterc",
172
+ ".renovaterc.json",
173
+ ];
174
+ /**
175
+ * Whether a repository-relative path exists.
176
+ * @param root - Repository root
177
+ * @param relativePath - Repo-relative path
178
+ * @returns True when the file could be read
179
+ */
180
+ async function fileExists(root, relativePath) {
181
+ return (await readFileOrNull(root, relativePath)) !== null;
182
+ }
183
+ /**
184
+ * List the files directly inside a repository-relative directory.
185
+ * @param root - Repository root
186
+ * @param relativeDir - Repo-relative directory
187
+ * @returns Repo-relative file paths (empty when the directory is absent)
188
+ */
189
+ async function listDirectory(root, relativeDir) {
190
+ try {
191
+ const entries = await readdir(path.join(root, relativeDir), {
192
+ withFileTypes: true,
193
+ });
194
+ return entries
195
+ .filter(entry => entry.isFile())
196
+ .map(entry => path.join(relativeDir, entry.name))
197
+ .sort((a, b) => a.localeCompare(b));
198
+ }
199
+ catch {
200
+ return [];
201
+ }
202
+ }
203
+ /**
204
+ * Read and parse `package.json`, distinguishing "absent" from "unparseable" so
205
+ * the SKIP reason can say which one happened.
206
+ * @param root - Repository root
207
+ * @returns The parsed manifest, or the reason it cannot be assessed
208
+ */
209
+ export async function readManifest(root) {
210
+ const source = await readFileOrNull(root, "package.json");
211
+ if (source === null) {
212
+ return {
213
+ kind: "unassessable",
214
+ reason: "no `package.json` was found, so this repository declares no " +
215
+ "JavaScript dependency surface to build a confidence model for; " +
216
+ "supply-chain confidence is not established either way",
217
+ };
218
+ }
219
+ try {
220
+ const parsed = JSON.parse(source);
221
+ if (!isRecord(parsed)) {
222
+ throw new Error("manifest is not a JSON object");
223
+ }
224
+ return { kind: "ok", manifest: parsed };
225
+ }
226
+ catch (error) {
227
+ return {
228
+ kind: "unassessable",
229
+ reason: "`package.json` could not be parsed, so its dependency specs were " +
230
+ `never read and nothing about them is established: ${error instanceof Error ? error.message : String(error)}`,
231
+ };
232
+ }
233
+ }
234
+ /**
235
+ * Flatten one manifest block into `name → spec` pairs. `overrides` nests, so a
236
+ * nested map is walked rather than skipped — a floating spec one level down
237
+ * installs exactly as loosely as one at the top.
238
+ * @param block - Block name, e.g. `dependencies`
239
+ * @param value - The block's raw value
240
+ * @param prefix - Accumulated name path for nested overrides
241
+ * @returns Flattened specs
242
+ */
243
+ function flattenBlock(block, value, prefix = "") {
244
+ if (!isRecord(value)) {
245
+ return [];
246
+ }
247
+ return Object.entries(value).flatMap(([name, spec]) => {
248
+ const qualified = prefix === "" ? name : `${prefix}.${name}`;
249
+ if (typeof spec === "string") {
250
+ return [{ block, name: qualified, spec }];
251
+ }
252
+ return flattenBlock(block, spec, qualified);
253
+ });
254
+ }
255
+ /**
256
+ * Flatten every versioned manifest block into one list of specs.
257
+ * @param manifest - Parsed `package.json`
258
+ * @returns Every declared spec across the versioned blocks
259
+ */
260
+ export function collectSpecs(manifest) {
261
+ return VERSIONED_BLOCKS.flatMap(block => flattenBlock(block, manifest[block]));
262
+ }
263
+ /**
264
+ * Find the committed lockfile, if any.
265
+ * @param root - Repository root
266
+ * @returns The lockfile name, or null when none is committed
267
+ */
268
+ export async function findLockfile(root) {
269
+ for (const candidate of LOCKFILES) {
270
+ if (await fileExists(root, candidate)) {
271
+ return candidate;
272
+ }
273
+ }
274
+ return null;
275
+ }
276
+ /**
277
+ * Whether an update-bot config actually watches the JavaScript dependency tree.
278
+ * Dependabot declares an ecosystem per entry, so a config covering only
279
+ * `github-actions` is not a confidence model for `package.json`. Renovate has no
280
+ * such per-file declaration and defaults to every manager it detects, so its
281
+ * presence is taken at face value.
282
+ * @param botFile - Repo-relative bot config path
283
+ * @param source - The config's text
284
+ * @returns True when the bot covers the JavaScript dependencies
285
+ */
286
+ function coversJavaScriptTree(botFile, source) {
287
+ return botFile.includes("dependabot")
288
+ ? JS_ECOSYSTEM_PATTERN.test(source)
289
+ : true;
290
+ }
291
+ /**
292
+ * Find where the repository audits its dependency tree: a CI job, a git hook, a
293
+ * lefthook declaration, or an update bot.
294
+ * @param root - Repository root
295
+ * @returns The repo-relative path of the first gate found, or null
296
+ */
297
+ export async function findAuditGate(root) {
298
+ for (const botFile of UPDATE_BOT_FILES) {
299
+ const source = await readFileOrNull(root, botFile);
300
+ if (source !== null && coversJavaScriptTree(botFile, source)) {
301
+ return botFile.split(path.sep).join("/");
302
+ }
303
+ }
304
+ const scanned = [
305
+ ...(await Promise.all(GATE_DIRECTORIES.map(dir => listDirectory(root, dir)))).flat(),
306
+ ...GATE_FILES,
307
+ ];
308
+ for (const file of scanned) {
309
+ const source = await readFileOrNull(root, file);
310
+ if (source !== null && AUDIT_GATE_PATTERN.test(source)) {
311
+ return file.split(path.sep).join("/");
312
+ }
313
+ }
314
+ return null;
315
+ }
316
+ //# sourceMappingURL=doctor-readiness-supply-chain-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-readiness-supply-chain-scan.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-supply-chain-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ReadinessDimensionRecord } from "./doctor-readiness-types.js";
2
+ /** The dependencies/supply-chain readiness dimension id (readiness-rubric). */
3
+ export declare const DEPENDENCIES_SUPPLY_CHAIN_DIMENSION_ID = "dependencies-supply-chain";
4
+ /**
5
+ * Assess the dependencies/supply-chain dimension: B5, "an owned compatibility or
6
+ * security surface has no confidence model". Offline by construction — it reads
7
+ * only the repository's manifest, lockfiles, CI declarations, git hooks, and
8
+ * audit allowlists, and degrades to a stated-reason SKIP wherever those files
9
+ * cannot settle the question.
10
+ * @param root - Project root to assess
11
+ * @returns The dependencies/supply-chain dimension record
12
+ */
13
+ export declare function assessDependenciesSupplyChainDimension(root: string): Promise<ReadinessDimensionRecord>;
14
+ //# sourceMappingURL=doctor-readiness-supply-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-readiness-supply-chain.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-supply-chain.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE5E,+EAA+E;AAC/E,eAAO,MAAM,sCAAsC,8BACtB,CAAC;AAsL9B;;;;;;;;GAQG;AACH,wBAAsB,sCAAsC,CAC1D,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,wBAAwB,CAAC,CA8CnC"}