@codyswann/lisa 3.4.1 → 3.5.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 (176) hide show
  1. package/README.md +22 -0
  2. package/all/copy-contents/gitignore +7 -0
  3. package/all/copy-overwrite/scripts/lisa-command-envelope.mjs +44 -4
  4. package/all/copy-overwrite/scripts/lisa-schema-validate.mjs +125 -47
  5. package/cdk/merge/.oxlintrc.json +1 -1
  6. package/dist/cli/apply.d.ts.map +1 -1
  7. package/dist/cli/apply.js +48 -13
  8. package/dist/cli/apply.js.map +1 -1
  9. package/dist/cli/doctor-apply-freshness.d.ts +29 -0
  10. package/dist/cli/doctor-apply-freshness.d.ts.map +1 -0
  11. package/dist/cli/doctor-apply-freshness.js +194 -0
  12. package/dist/cli/doctor-apply-freshness.js.map +1 -0
  13. package/dist/cli/doctor-learnings-merge-driver.d.ts +23 -0
  14. package/dist/cli/doctor-learnings-merge-driver.d.ts.map +1 -0
  15. package/dist/cli/doctor-learnings-merge-driver.js +73 -0
  16. package/dist/cli/doctor-learnings-merge-driver.js.map +1 -0
  17. package/dist/cli/doctor-readiness-workflows.js +2 -2
  18. package/dist/cli/doctor-readiness-workflows.js.map +1 -1
  19. package/dist/cli/doctor.d.ts.map +1 -1
  20. package/dist/cli/doctor.js +13 -0
  21. package/dist/cli/doctor.js.map +1 -1
  22. package/dist/cli/ui-ci-quality-jobs-parse.js +2 -2
  23. package/dist/cli/ui-ci-quality-jobs-parse.js.map +1 -1
  24. package/dist/cli/ui-deploy-pipeline-model.d.ts +4 -0
  25. package/dist/cli/ui-deploy-pipeline-model.d.ts.map +1 -1
  26. package/dist/cli/ui-deploy-pipeline-model.js +2 -2
  27. package/dist/cli/ui-deploy-pipeline-model.js.map +1 -1
  28. package/dist/codex/agent-transformer.js +2 -2
  29. package/dist/codex/agent-transformer.js.map +1 -1
  30. package/dist/codex/command-skill-transformer.js +3 -3
  31. package/dist/codex/command-skill-transformer.js.map +1 -1
  32. package/dist/core/apply-receipt.d.ts +68 -0
  33. package/dist/core/apply-receipt.d.ts.map +1 -0
  34. package/dist/core/apply-receipt.js +107 -0
  35. package/dist/core/apply-receipt.js.map +1 -0
  36. package/dist/core/learnings-merge-driver-install.d.ts +34 -0
  37. package/dist/core/learnings-merge-driver-install.d.ts.map +1 -1
  38. package/dist/core/learnings-merge-driver-install.js +36 -0
  39. package/dist/core/learnings-merge-driver-install.js.map +1 -1
  40. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  41. package/dist/core/upstream-evidence-manifest.js +53 -31
  42. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  43. package/dist/migrations/ensure-lisa-postinstall.d.ts +33 -0
  44. package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -1
  45. package/dist/migrations/ensure-lisa-postinstall.js +47 -5
  46. package/dist/migrations/ensure-lisa-postinstall.js.map +1 -1
  47. package/dist/migrations/ensure-oxlint-base-configs.d.ts +42 -0
  48. package/dist/migrations/ensure-oxlint-base-configs.d.ts.map +1 -0
  49. package/dist/migrations/ensure-oxlint-base-configs.js +212 -0
  50. package/dist/migrations/ensure-oxlint-base-configs.js.map +1 -0
  51. package/dist/migrations/index.d.ts +1 -0
  52. package/dist/migrations/index.d.ts.map +1 -1
  53. package/dist/migrations/index.js +3 -0
  54. package/dist/migrations/index.js.map +1 -1
  55. package/dist/opencode/command-transformer.js +3 -3
  56. package/dist/opencode/command-transformer.js.map +1 -1
  57. package/dist/utils/yaml.d.ts +54 -0
  58. package/dist/utils/yaml.d.ts.map +1 -0
  59. package/dist/utils/yaml.js +124 -0
  60. package/dist/utils/yaml.js.map +1 -0
  61. package/expo/copy-overwrite/scripts/bdd/baseline.mjs +104 -19
  62. package/expo/copy-overwrite/scripts/bdd/contract.mjs +20 -1
  63. package/expo/copy-overwrite/scripts/bdd/discover.mjs +53 -10
  64. package/expo/copy-overwrite/scripts/bdd/parse.mjs +25 -3
  65. package/expo/copy-overwrite/scripts/bdd/render.mjs +2 -1
  66. package/expo/copy-overwrite/scripts/bdd/report.mjs +26 -12
  67. package/expo/copy-overwrite/scripts/bdd/validate.mjs +2 -2
  68. package/expo/copy-overwrite/scripts/bdd/waivers.mjs +19 -4
  69. package/expo/copy-overwrite/scripts/bdd-matrix.mjs +2 -2
  70. package/expo/copy-overwrite/scripts/check-bdd-coverage.mjs +58 -16
  71. package/expo/create-only/.github/required-checks.json +10 -4
  72. package/expo/merge/.oxlintrc.json +1 -1
  73. package/harper-fabric/merge/.oxlintrc.json +1 -1
  74. package/nestjs/create-only/.github/required-checks.json +57 -0
  75. package/nestjs/merge/.oxlintrc.json +1 -1
  76. package/package.json +1 -1
  77. package/phaser/merge/.oxlintrc.json +1 -1
  78. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa/.codex-plugin/skills/lisa-atlassian-access/SKILL.md +7 -0
  81. package/plugins/lisa/.codex-plugin/skills/lisa-jam-access/SKILL.md +37 -2
  82. package/plugins/lisa/.codex-plugin/skills/lisa-notion-access/SKILL.md +7 -0
  83. package/plugins/lisa/.codex-plugin/skills/lisa-posthog-access/SKILL.md +40 -3
  84. package/plugins/lisa/.codex-plugin/skills/lisa-sentry-access/SKILL.md +44 -3
  85. package/plugins/lisa/.codex-plugin/skills/lisa-sonarcloud-access/SKILL.md +56 -0
  86. package/plugins/lisa/rules/eager/credential-substrate-precedence.md +3 -1
  87. package/plugins/lisa/rules/reference/credential-substrate-precedence.md +20 -0
  88. package/plugins/lisa/skills/lisa-atlassian-access/SKILL.md +7 -0
  89. package/plugins/lisa/skills/lisa-jam-access/SKILL.md +37 -2
  90. package/plugins/lisa/skills/lisa-notion-access/SKILL.md +7 -0
  91. package/plugins/lisa/skills/lisa-posthog-access/SKILL.md +40 -3
  92. package/plugins/lisa/skills/lisa-sentry-access/SKILL.md +44 -3
  93. package/plugins/lisa/skills/lisa-sonarcloud-access/SKILL.md +56 -0
  94. package/plugins/lisa-agy/plugin.json +1 -1
  95. package/plugins/lisa-agy/skills/lisa-atlassian-access/SKILL.md +7 -0
  96. package/plugins/lisa-agy/skills/lisa-jam-access/SKILL.md +37 -2
  97. package/plugins/lisa-agy/skills/lisa-notion-access/SKILL.md +7 -0
  98. package/plugins/lisa-agy/skills/lisa-posthog-access/SKILL.md +40 -3
  99. package/plugins/lisa-agy/skills/lisa-sentry-access/SKILL.md +44 -3
  100. package/plugins/lisa-agy/skills/lisa-sonarcloud-access/SKILL.md +56 -0
  101. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  103. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  104. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  105. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-copilot/rules/eager/credential-substrate-precedence.md +3 -1
  108. package/plugins/lisa-copilot/rules/reference/credential-substrate-precedence.md +20 -0
  109. package/plugins/lisa-copilot/skills/lisa-atlassian-access/SKILL.md +7 -0
  110. package/plugins/lisa-copilot/skills/lisa-jam-access/SKILL.md +37 -2
  111. package/plugins/lisa-copilot/skills/lisa-notion-access/SKILL.md +7 -0
  112. package/plugins/lisa-copilot/skills/lisa-posthog-access/SKILL.md +40 -3
  113. package/plugins/lisa-copilot/skills/lisa-sentry-access/SKILL.md +44 -3
  114. package/plugins/lisa-copilot/skills/lisa-sonarcloud-access/SKILL.md +56 -0
  115. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  116. package/plugins/lisa-cursor/rules/credential-substrate-precedence-reference.mdc +20 -0
  117. package/plugins/lisa-cursor/rules/credential-substrate-precedence.mdc +3 -1
  118. package/plugins/lisa-cursor/skills/lisa-atlassian-access/SKILL.md +7 -0
  119. package/plugins/lisa-cursor/skills/lisa-jam-access/SKILL.md +37 -2
  120. package/plugins/lisa-cursor/skills/lisa-notion-access/SKILL.md +7 -0
  121. package/plugins/lisa-cursor/skills/lisa-posthog-access/SKILL.md +40 -3
  122. package/plugins/lisa-cursor/skills/lisa-sentry-access/SKILL.md +44 -3
  123. package/plugins/lisa-cursor/skills/lisa-sonarcloud-access/SKILL.md +56 -0
  124. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  125. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  126. package/plugins/lisa-expo-agy/plugin.json +1 -1
  127. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  128. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  129. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  130. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  131. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  132. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  133. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  134. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  135. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  136. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  137. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  138. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  139. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  140. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  141. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  142. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  143. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  144. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  145. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  146. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  147. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  148. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  149. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  150. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  151. package/plugins/lisa-rails-agy/plugin.json +1 -1
  152. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  153. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  154. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  155. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  156. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  157. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  158. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  159. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  160. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  161. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  162. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  163. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  164. package/plugins/src/base/rules/eager/credential-substrate-precedence.md +3 -1
  165. package/plugins/src/base/rules/reference/credential-substrate-precedence.md +20 -0
  166. package/plugins/src/base/skills/lisa-atlassian-access/SKILL.md +7 -0
  167. package/plugins/src/base/skills/lisa-jam-access/SKILL.md +37 -2
  168. package/plugins/src/base/skills/lisa-notion-access/SKILL.md +7 -0
  169. package/plugins/src/base/skills/lisa-posthog-access/SKILL.md +40 -3
  170. package/plugins/src/base/skills/lisa-sentry-access/SKILL.md +44 -3
  171. package/plugins/src/base/skills/lisa-sonarcloud-access/SKILL.md +56 -0
  172. package/scripts/install-claude-plugins.sh +5 -1
  173. package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +298 -26
  174. package/typescript/create-only/.github/required-checks.json +11 -6
  175. package/typescript/create-only/.github/workflows/required-checks-drift.yml +84 -0
  176. package/typescript/merge/.oxlintrc.json +1 -1
package/README.md CHANGED
@@ -172,6 +172,28 @@ bun add --dev --trust @codyswann/lisa
172
172
 
173
173
  Lisa's dependency `postinstall` runs `lisa apply` for that project. A later
174
174
  `bun update @codyswann/lisa` reapplies the updated project-scoped artifacts.
175
+
176
+ That bootstrap is **loud but non-fatal**: a failed apply prints the real error
177
+ plus a warning naming the consequence, and still exits 0, because a postinstall
178
+ that aborts would break `bun install` in every environment where apply
179
+ legitimately cannot run. The durable signal is
180
+ `lisa doctor` — a successful apply writes `.lisa/apply-receipt.json`, and doctor
181
+ reports any repo whose receipt is missing or older than the installed Lisa
182
+ ("this repo has not successfully applied templates since `<version>`"). Run it
183
+ whenever a project seems to have stopped tracking upstream changes; a repo can
184
+ otherwise sit silently stale for months.
185
+
186
+ The same check covers a second, quieter gap. A package install runs apply in
187
+ **postinstall-safe** mode (`--skip-git-check`), which deliberately skips every
188
+ agent emit — Codex, Claude, agy, Copilot, OpenCode — and the Sonar integration,
189
+ because those rewrite host-owned files. So no `bun install` at any version can
190
+ reconcile `.codex/config.toml`; only a full `lisa apply .` does. Doctor now says
191
+ so instead of reporting such a repo as current.
192
+
193
+ Lisa drives `js-yaml` through one interop shim and works with the 3.x, 4.x, and
194
+ 5.x lines, so a host `overrides`/`resolutions` pin that collapses Lisa's own
195
+ copy is fine. A pin Lisa genuinely cannot drive is reported by `lisa doctor` as
196
+ a named incompatibility rather than a crash.
175
197
  Lisa does not register user-wide Codex plugins, skills, hooks, rules, MCP
176
198
  servers, or configuration. Other harnesses retain their existing delivery
177
199
  behavior. For a new project, run the CLI ephemerally with
@@ -238,6 +238,13 @@ expo-env.d.ts
238
238
  # /lisa:automation-status. Runbooks are project knowledge; run records are not.
239
239
  .lisa/automations/runs/
240
240
 
241
+ # Proof that `lisa apply` completed in THIS checkout, read by `lisa doctor` to
242
+ # report a repo that has silently stopped receiving templates. Machine-local by
243
+ # construction: committing it would churn on every version bump, conflict
244
+ # between developers on different Lisa versions, and lie about a fresh clone
245
+ # that has never installed.
246
+ .lisa/apply-receipt.json
247
+
241
248
  # Remote-dispatch ledger. Records the sessions this machine started so a later
242
249
  # run can find them. Per developer by construction — each fires their own
243
250
  # routine under their own account — so committing it would collide on every
@@ -33,10 +33,41 @@ const SCHEMA_PATH = path.join(
33
33
  "lisa-command-envelope.v1.schema.json"
34
34
  );
35
35
 
36
- /** The published envelope schema, read from the shipped JSON document. */
37
- export const COMMAND_ENVELOPE_SCHEMA = JSON.parse(
38
- fs.readFileSync(SCHEMA_PATH, "utf8")
39
- );
36
+ /**
37
+ * Read the shipped schema document, or explain why it could not be read.
38
+ *
39
+ * A throw at module scope happens before any handler runs, so an adopter with a
40
+ * partially-copied `scripts/` directory got a raw ENOENT stack from an import
41
+ * they never made directly — and any caller that merely wanted to VALIDATE
42
+ * something died on load. Reading it into a nullable value instead turns that
43
+ * into a first-class, fail-closed validation error with the missing path named
44
+ * in it.
45
+ * @returns {{schema: object|null, error: string|null}} The schema or the reason.
46
+ */
47
+ function readSchemaDocument() {
48
+ try {
49
+ return {
50
+ schema: JSON.parse(fs.readFileSync(SCHEMA_PATH, "utf8")),
51
+ error: null,
52
+ };
53
+ } catch (error) {
54
+ return {
55
+ schema: null,
56
+ error: `the published envelope schema is not readable at ${SCHEMA_PATH} (${error.message}); scripts/schemas/ must be copied alongside scripts/`,
57
+ };
58
+ }
59
+ }
60
+
61
+ const SCHEMA_DOCUMENT = readSchemaDocument();
62
+
63
+ /**
64
+ * The published envelope schema, read from the shipped JSON document.
65
+ *
66
+ * `null` when the document is missing — see {@link readSchemaDocument}. Every
67
+ * consumer must treat that as a validation FAILURE, never as "no schema to
68
+ * check against".
69
+ */
70
+ export const COMMAND_ENVELOPE_SCHEMA = SCHEMA_DOCUMENT.schema;
40
71
 
41
72
  /**
42
73
  * Statuses that may exit 0.
@@ -67,6 +98,9 @@ export function exitCodeForStatus(status) {
67
98
  * @returns {{ valid: boolean, errors: string[] }} Validation outcome
68
99
  */
69
100
  export function validateEnvelope(envelope) {
101
+ if (!COMMAND_ENVELOPE_SCHEMA) {
102
+ return { valid: false, errors: [SCHEMA_DOCUMENT.error] };
103
+ }
70
104
  const base = validateAgainstSchema(envelope, COMMAND_ENVELOPE_SCHEMA);
71
105
  if (!base.valid) {
72
106
  return base;
@@ -154,6 +188,12 @@ export function emitEnvelope(envelope, io = {}) {
154
188
  */
155
189
  export function main(argv) {
156
190
  if (argv.includes("--print-schema")) {
191
+ if (!COMMAND_ENVELOPE_SCHEMA) {
192
+ process.stderr.write(
193
+ `[command-envelope] FAIL: ${SCHEMA_DOCUMENT.error}\n`
194
+ );
195
+ return 1;
196
+ }
157
197
  process.stdout.write(
158
198
  `${JSON.stringify(COMMAND_ENVELOPE_SCHEMA, null, 2)}\n`
159
199
  );
@@ -9,7 +9,8 @@
9
9
  * keyword it does not implement**, so a schema can never silently validate less
10
10
  * than it claims: an unsupported keyword is a validator error, not a pass.
11
11
  *
12
- * Supported: `type`, `const`, `enum`, `required`, `properties`,
12
+ * Supported: `type` (a single name or an array of names), `const`, `enum`,
13
+ * `required`, `properties`,
13
14
  * `additionalProperties` (boolean), `items`, `minLength`, `minimum`, `pattern`,
14
15
  * `$ref` (local `#/$defs/<name>` only), `$defs`, plus the annotation-only
15
16
  * keywords `$schema`, `$id`, `title`, `description`.
@@ -79,15 +80,13 @@ function resolveRef(ref, root) {
79
80
  }
80
81
 
81
82
  /**
82
- * Validate one value against one subschema, appending human-readable errors.
83
- * @param {unknown} value - Value under validation
84
- * @param {object} schema - Subschema to apply
85
- * @param {object} root - Root schema document (for `$ref` resolution)
83
+ * Refuse any keyword this validator does not implement.
84
+ * @param {object} schema - Subschema to inspect
86
85
  * @param {string} instancePath - JSON-pointer-ish path for messages
87
- * @param {string[]} errors - Accumulator, mutated in place
88
86
  * @returns {void}
87
+ * @throws {Error} When the subschema uses an unimplemented keyword
89
88
  */
90
- function validateNode(value, schema, root, instancePath, errors) {
89
+ function assertSupportedKeywords(schema, instancePath) {
91
90
  for (const keyword of Object.keys(schema)) {
92
91
  if (!SUPPORTED_KEYWORDS.has(keyword) && !ANNOTATION_KEYWORDS.has(keyword)) {
93
92
  throw new Error(
@@ -95,43 +94,76 @@ function validateNode(value, schema, root, instancePath, errors) {
95
94
  );
96
95
  }
97
96
  }
97
+ }
98
98
 
99
- if (typeof schema.$ref === "string") {
100
- validateNode(
101
- value,
102
- resolveRef(schema.$ref, root),
103
- root,
104
- instancePath,
105
- errors
106
- );
107
- return;
108
- }
109
-
110
- const where = instancePath || "(root)";
111
- const actualType = jsonTypeOf(value);
99
+ /**
100
+ * Whether one declared type name accepts an observed JSON type.
101
+ * @param {string} declared - A JSON Schema type name
102
+ * @param {string} actualType - The observed type
103
+ * @returns {boolean} Whether it matches
104
+ */
105
+ function typeAccepts(declared, actualType) {
106
+ return (
107
+ declared === actualType ||
108
+ (declared === "number" && actualType === "integer")
109
+ );
110
+ }
112
111
 
113
- if (typeof schema.type === "string") {
114
- const ok =
115
- schema.type === actualType ||
116
- (schema.type === "number" && actualType === "integer");
117
- if (!ok) {
118
- errors.push(`${where}: expected type ${schema.type}, got ${actualType}`);
119
- return;
120
- }
112
+ /**
113
+ * The `type` mismatch message, or null when the value's type is acceptable.
114
+ *
115
+ * BOTH declared forms are handled. `type` may be a single name or an ARRAY of
116
+ * names (`["string", "null"]`), and the array form previously fell through the
117
+ * `typeof === "string"` test entirely: the keyword passed the allowlist, so the
118
+ * module's central promise — an unimplemented keyword is an error, never a
119
+ * silent pass — was broken for the one form nobody checked.
120
+ * @param {object} schema - Subschema to apply
121
+ * @param {string} actualType - The observed type
122
+ * @param {string} where - Location for the message
123
+ * @returns {string|null} The error, or null
124
+ */
125
+ function typeError(schema, actualType, where) {
126
+ const declared = schema.type;
127
+ if (typeof declared === "string") {
128
+ return typeAccepts(declared, actualType)
129
+ ? null
130
+ : `${where}: expected type ${declared}, got ${actualType}`;
121
131
  }
132
+ if (declared === undefined) return null;
133
+ if (
134
+ !Array.isArray(declared) ||
135
+ declared.length === 0 ||
136
+ !declared.every(entry => typeof entry === "string")
137
+ ) {
138
+ throw new Error(
139
+ `schema at ${where} declares a "type" that is neither a name nor an array of names`
140
+ );
141
+ }
142
+ return declared.some(entry => typeAccepts(entry, actualType))
143
+ ? null
144
+ : `${where}: expected type ${declared.join(" or ")}, got ${actualType}`;
145
+ }
122
146
 
147
+ /**
148
+ * Apply the value-level keywords: `const`, `enum`, and the string and number
149
+ * constraints.
150
+ * @param {unknown} value - Value under validation
151
+ * @param {object} schema - Subschema to apply
152
+ * @param {string} where - Location for messages
153
+ * @param {string[]} errors - Accumulator, mutated in place
154
+ * @returns {void}
155
+ */
156
+ function checkValueKeywords(value, schema, where, errors) {
123
157
  if ("const" in schema && value !== schema.const) {
124
158
  errors.push(
125
159
  `${where}: expected constant ${JSON.stringify(schema.const)}, got ${JSON.stringify(value)}`
126
160
  );
127
161
  }
128
-
129
162
  if (Array.isArray(schema.enum) && !schema.enum.includes(value)) {
130
163
  errors.push(
131
164
  `${where}: ${JSON.stringify(value)} is not one of ${schema.enum.map(entry => JSON.stringify(entry)).join(", ")}`
132
165
  );
133
166
  }
134
-
135
167
  if (typeof value === "string") {
136
168
  if (
137
169
  typeof schema.minLength === "number" &&
@@ -146,29 +178,32 @@ function validateNode(value, schema, root, instancePath, errors) {
146
178
  errors.push(`${where}: does not match pattern ${schema.pattern}`);
147
179
  }
148
180
  }
149
-
150
- if (typeof value === "number" && typeof schema.minimum === "number") {
151
- if (value < schema.minimum) {
152
- errors.push(`${where}: below minimum ${schema.minimum}`);
153
- }
154
- }
155
-
156
- if (actualType === "array" && schema.items) {
157
- value.forEach((entry, index) => {
158
- validateNode(entry, schema.items, root, `${where}[${index}]`, errors);
159
- });
160
- }
161
-
162
- if (actualType !== "object") {
163
- return;
181
+ if (
182
+ typeof value === "number" &&
183
+ typeof schema.minimum === "number" &&
184
+ value < schema.minimum
185
+ ) {
186
+ errors.push(`${where}: below minimum ${schema.minimum}`);
164
187
  }
188
+ }
165
189
 
190
+ /**
191
+ * Apply the object-level keywords: `required`, `properties`, and
192
+ * `additionalProperties`.
193
+ * @param {object} value - Object under validation
194
+ * @param {object} schema - Subschema to apply
195
+ * @param {object} root - Root schema document (for `$ref` resolution)
196
+ * @param {string} instancePath - JSON-pointer-ish path for messages
197
+ * @param {string[]} errors - Accumulator, mutated in place
198
+ * @returns {void}
199
+ */
200
+ function checkObjectKeywords(value, schema, root, instancePath, errors) {
201
+ const where = instancePath || "(root)";
166
202
  for (const key of schema.required ?? []) {
167
203
  if (!(key in value)) {
168
204
  errors.push(`${where}: missing required property "${key}"`);
169
205
  }
170
206
  }
171
-
172
207
  const properties = schema.properties ?? {};
173
208
  for (const [key, subschema] of Object.entries(properties)) {
174
209
  if (key in value) {
@@ -181,7 +216,6 @@ function validateNode(value, schema, root, instancePath, errors) {
181
216
  );
182
217
  }
183
218
  }
184
-
185
219
  if (schema.additionalProperties === false) {
186
220
  for (const key of Object.keys(value)) {
187
221
  if (!(key in properties)) {
@@ -191,6 +225,50 @@ function validateNode(value, schema, root, instancePath, errors) {
191
225
  }
192
226
  }
193
227
 
228
+ /**
229
+ * Validate one value against one subschema, appending human-readable errors.
230
+ * @param {unknown} value - Value under validation
231
+ * @param {object} schema - Subschema to apply
232
+ * @param {object} root - Root schema document (for `$ref` resolution)
233
+ * @param {string} instancePath - JSON-pointer-ish path for messages
234
+ * @param {string[]} errors - Accumulator, mutated in place
235
+ * @returns {void}
236
+ */
237
+ function validateNode(value, schema, root, instancePath, errors) {
238
+ assertSupportedKeywords(schema, instancePath);
239
+
240
+ if (typeof schema.$ref === "string") {
241
+ validateNode(
242
+ value,
243
+ resolveRef(schema.$ref, root),
244
+ root,
245
+ instancePath,
246
+ errors
247
+ );
248
+ return;
249
+ }
250
+
251
+ const where = instancePath || "(root)";
252
+ const actualType = jsonTypeOf(value);
253
+ const mismatch = typeError(schema, actualType, where);
254
+ if (mismatch) {
255
+ errors.push(mismatch);
256
+ return;
257
+ }
258
+
259
+ checkValueKeywords(value, schema, where, errors);
260
+
261
+ if (actualType === "array" && schema.items) {
262
+ value.forEach((entry, index) => {
263
+ validateNode(entry, schema.items, root, `${where}[${index}]`, errors);
264
+ });
265
+ }
266
+
267
+ if (actualType === "object") {
268
+ checkObjectKeywords(value, schema, root, instancePath, errors);
269
+ }
270
+ }
271
+
194
272
  /**
195
273
  * Validate a document against a schema.
196
274
  * @param {unknown} document - The value to validate
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./node_modules/oxlint/configuration_schema.json",
3
- "extends": ["./node_modules/@codyswann/lisa/oxlint/cdk.json"],
3
+ "extends": ["./.lisa/lisa-oxlint/cdk.json"],
4
4
  "ignorePatterns": [
5
5
  "build/**",
6
6
  "dist/**",
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,qBAAqB,CAAC;AA+J7B;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAqEf"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,qBAAqB,CAAC;AA0M7B;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAmEf"}
package/dist/cli/apply.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
+ import { recordSuccessfulApply } from "../core/apply-receipt.js";
3
4
  import { getBootstrapApplySkipNotice } from "../core/bootstrap-environment.js";
4
5
  import { ACCEPTED_HARNESS_INPUTS } from "../core/config.js";
5
6
  import { Lisa } from "../core/lisa.js";
@@ -8,6 +9,7 @@ import { ConsoleLogger } from "../logging/index.js";
8
9
  import { toAbsolutePath } from "../utils/path-utils.js";
9
10
  import { nudgeCrossPollinate } from "./cross-pollinate-nudge.js";
10
11
  import { createDependencies, parseRefreshTemplates, } from "./shared-options.js";
12
+ import { getPackageVersion } from "./version.js";
11
13
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
14
  /**
13
15
  * Get Lisa directory (where configs are stored)
@@ -108,6 +110,41 @@ function buildApplyConfig(parts) {
108
110
  ...(refreshTemplates === undefined ? {} : { refreshTemplates }),
109
111
  };
110
112
  }
113
+ /**
114
+ * Persist everything a completed, real (non-validate, non-dry-run) apply owes
115
+ * the project: its `.lisa.config.json`, any legacy harness migration, and the
116
+ * receipt proving the apply finished.
117
+ * @param parts - Resolved state for this invocation
118
+ * @param parts.destDir - Project directory that was applied to
119
+ * @param parts.logger - Logger for migration notices
120
+ * @param parts.config - The config this apply ran with
121
+ * @param parts.harness - Resolved harness for this invocation
122
+ * @param parts.persistence - Inputs deciding whether config must be written
123
+ */
124
+ async function finalizeSuccessfulApply(parts) {
125
+ const { destDir, logger, config, harness, persistence } = parts;
126
+ // Ensure every applied project carries a .lisa.config.json. A missing file is
127
+ // always backfilled with the resolved harness (the default when no --harness
128
+ // was passed) so no project is left config-less; an existing file is only
129
+ // rewritten when --harness actually changes the persisted value.
130
+ await persistProjectConfigIfNeeded(destDir, persistence);
131
+ // Rewrite retired legacy harness values (e.g. "both") in place so the
132
+ // committed config stops carrying a value newer Lisa versions reject.
133
+ await migrateLegacyHarnessIfNeeded(destDir, logger);
134
+ // Record that an apply actually completed here. The postinstall bootstrap is
135
+ // non-fatal by design, so absence of this receipt is the only reliable
136
+ // evidence that a repo has silently stopped receiving templates — which is
137
+ // what `lisa doctor` reports (CodySwannGT/lisa#2467).
138
+ await recordSuccessfulApply(destDir, {
139
+ lisaVersion: getPackageVersion(),
140
+ harness,
141
+ // `--skip-git-check` IS postinstall-safe mode: it skips every agent emit,
142
+ // so a bump alone can never reconcile `.codex/config.toml` and friends.
143
+ // Recording which mode ran is what lets doctor say that work is still
144
+ // outstanding rather than reporting the repo as current.
145
+ applyMode: config.skipGitCheck ? "postinstall-safe" : "full",
146
+ });
147
+ }
111
148
  /**
112
149
  * Apply Lisa to the given destination with the given options.
113
150
  *
@@ -154,21 +191,19 @@ export async function runApply(destination, options) {
154
191
  result.errors.forEach(error => logger.error(error));
155
192
  process.exit(1);
156
193
  }
157
- // Ensure every applied project carries a .lisa.config.json (not on
158
- // validate / dry-run). A missing file is always backfilled with the
159
- // resolved harness (the default when no --harness was passed) so no
160
- // project is left config-less; an existing file is only rewritten when
161
- // --harness actually changes the persisted value, avoiding churn.
162
194
  if (!options.validate && !dryRun) {
163
- await persistProjectConfigIfNeeded(destDir, {
164
- fileExists: configFileExists,
165
- flagHarness: options.harness,
166
- existingHarness: projectConfig.harness,
167
- resolvedHarness: harness,
195
+ await finalizeSuccessfulApply({
196
+ destDir,
197
+ logger,
198
+ config,
199
+ harness,
200
+ persistence: {
201
+ fileExists: configFileExists,
202
+ flagHarness: options.harness,
203
+ existingHarness: projectConfig.harness,
204
+ resolvedHarness: harness,
205
+ },
168
206
  });
169
- // Rewrite retired legacy harness values (e.g. "both") in place so the
170
- // committed config stops carrying a value newer Lisa versions reject.
171
- await migrateLegacyHarnessIfNeeded(destDir, logger);
172
207
  }
173
208
  // After a real apply, surface (read-only) whether any locally-authored
174
209
  // agent definitions need cross-pollinating to the project's other agents.
@@ -1 +1 @@
1
- {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/cli/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /** One doctor check result, structurally identical to `DoctorCheck`. */
2
+ interface FreshnessCheck {
3
+ name: string;
4
+ status: "ok" | "warn" | "fail";
5
+ detail: string;
6
+ }
7
+ /**
8
+ * Report whether template application is current for this checkout.
9
+ * @param targetPath - Project path to inspect
10
+ * @returns Doctor check result
11
+ */
12
+ export declare function checkApplyFreshness(targetPath: string): Promise<FreshnessCheck>;
13
+ /**
14
+ * Report whether the js-yaml this install resolved can actually be driven.
15
+ *
16
+ * Separate from the freshness check because it answers the follow-up question:
17
+ * *why* has nothing applied? A host `overrides`/`resolutions` entry collapses
18
+ * Lisa's own js-yaml onto the host's pin, and an incompatible pin used to kill
19
+ * the CLI at module-load time with a bare stack trace. Lisa now links against
20
+ * any js-yaml shape and reports the incompatibility in plain language here.
21
+ *
22
+ * `fail`, not `warn`: nothing that parses YAML works in this state — Codex and
23
+ * OpenCode artifact generation, CI workflow readiness, and the console's deploy
24
+ * pipeline all stop — and the remedy is a one-line manifest edit.
25
+ * @returns Doctor check result
26
+ */
27
+ export declare function checkYamlRuntime(): FreshnessCheck;
28
+ export {};
29
+ //# sourceMappingURL=doctor-apply-freshness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-apply-freshness.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-apply-freshness.ts"],"names":[],"mappings":"AAkDA,wEAAwE;AACxE,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAuHD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,CAAC,CA2BzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CASjD"}