@codyswann/lisa 1.95.0 → 2.0.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 (200) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +41 -5
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/codex/agent-installer.d.ts +56 -0
  5. package/dist/codex/agent-installer.d.ts.map +1 -0
  6. package/dist/codex/agent-installer.js +201 -0
  7. package/dist/codex/agent-installer.js.map +1 -0
  8. package/dist/codex/agent-transformer.d.ts +53 -0
  9. package/dist/codex/agent-transformer.d.ts.map +1 -0
  10. package/dist/codex/agent-transformer.js +181 -0
  11. package/dist/codex/agent-transformer.js.map +1 -0
  12. package/dist/codex/agents-md-installer.d.ts +24 -0
  13. package/dist/codex/agents-md-installer.d.ts.map +1 -0
  14. package/dist/codex/agents-md-installer.js +63 -0
  15. package/dist/codex/agents-md-installer.js.map +1 -0
  16. package/dist/codex/hooks-installer.d.ts +24 -0
  17. package/dist/codex/hooks-installer.d.ts.map +1 -0
  18. package/dist/codex/hooks-installer.js +206 -0
  19. package/dist/codex/hooks-installer.js.map +1 -0
  20. package/dist/codex/hooks-merger.d.ts +82 -0
  21. package/dist/codex/hooks-merger.d.ts.map +1 -0
  22. package/dist/codex/hooks-merger.js +127 -0
  23. package/dist/codex/hooks-merger.js.map +1 -0
  24. package/dist/codex/manifest.d.ts +32 -0
  25. package/dist/codex/manifest.d.ts.map +1 -0
  26. package/dist/codex/manifest.js +86 -0
  27. package/dist/codex/manifest.js.map +1 -0
  28. package/dist/codex/settings-installer.d.ts +48 -0
  29. package/dist/codex/settings-installer.d.ts.map +1 -0
  30. package/dist/codex/settings-installer.js +276 -0
  31. package/dist/codex/settings-installer.js.map +1 -0
  32. package/dist/codex/skills-installer.d.ts +46 -0
  33. package/dist/codex/skills-installer.d.ts.map +1 -0
  34. package/dist/codex/skills-installer.js +344 -0
  35. package/dist/codex/skills-installer.js.map +1 -0
  36. package/dist/core/config.d.ts +19 -0
  37. package/dist/core/config.d.ts.map +1 -1
  38. package/dist/core/config.js +13 -0
  39. package/dist/core/config.js.map +1 -1
  40. package/dist/core/lisa.d.ts +12 -0
  41. package/dist/core/lisa.d.ts.map +1 -1
  42. package/dist/core/lisa.js +48 -0
  43. package/dist/core/lisa.js.map +1 -1
  44. package/dist/core/project-config.d.ts +49 -0
  45. package/dist/core/project-config.d.ts.map +1 -0
  46. package/dist/core/project-config.js +119 -0
  47. package/dist/core/project-config.js.map +1 -0
  48. package/package.json +3 -1
  49. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa/agents/jira-build-intake.md +58 -0
  51. package/plugins/lisa/agents/notion-prd-intake.md +57 -0
  52. package/plugins/lisa/commands/{plan/fix-linter-error.md → fix/linter-error.md} +1 -1
  53. package/plugins/lisa/commands/implement.md +6 -0
  54. package/plugins/{src/base/commands/plan/lower-code-complexity.md → lisa/commands/improve/code-complexity.md} +1 -1
  55. package/plugins/lisa/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +1 -1
  56. package/plugins/lisa/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +1 -1
  57. package/plugins/lisa/commands/{plan/improve-tests.md → improve/tests.md} +1 -1
  58. package/plugins/lisa/commands/plan.md +15 -3
  59. package/plugins/lisa/commands/product-walkthrough.md +7 -0
  60. package/plugins/{src/base/commands/plan/local-code-review.md → lisa/commands/review/local.md} +1 -1
  61. package/plugins/{src/base/skills/plan-fix-linter-error → lisa/skills/fix-linter-error}/SKILL.md +2 -2
  62. package/plugins/lisa/skills/{plan-execute → implement}/SKILL.md +1 -1
  63. package/plugins/lisa/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
  64. package/plugins/lisa/skills/{plan-reduce-max-lines → improve-max-lines}/SKILL.md +2 -2
  65. package/plugins/{src/base/skills/plan-reduce-max-lines-per-function → lisa/skills/improve-max-lines-per-function}/SKILL.md +2 -2
  66. package/plugins/lisa/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
  67. package/plugins/{src/base/skills/plan-improve-tests → lisa/skills/improve-tests}/SKILL.md +2 -2
  68. package/plugins/lisa/skills/jira-build-intake/SKILL.md +134 -0
  69. package/plugins/lisa/skills/jira-create/SKILL.md +53 -30
  70. package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +107 -0
  71. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +224 -0
  72. package/plugins/lisa/skills/jira-verify/SKILL.md +15 -91
  73. package/plugins/lisa/skills/jira-write-ticket/SKILL.md +20 -15
  74. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +169 -0
  75. package/plugins/lisa/skills/notion-to-jira/SKILL.md +137 -95
  76. package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +137 -0
  77. package/plugins/lisa/skills/product-walkthrough/SKILL.md +129 -0
  78. package/plugins/lisa/skills/{plan-local-code-review → review-local}/SKILL.md +1 -1
  79. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-expo/skills/jira-create/SKILL.md +60 -28
  82. package/plugins/lisa-expo/skills/jira-verify/SKILL.md +14 -34
  83. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-rails/skills/{plan-fix-linter-error → fix-linter-error}/SKILL.md +2 -2
  86. package/plugins/lisa-rails/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
  87. package/plugins/{src/rails/skills/plan-reduce-max-lines → lisa-rails/skills/improve-max-lines}/SKILL.md +2 -2
  88. package/plugins/{src/rails/skills/plan-reduce-max-lines-per-function → lisa-rails/skills/improve-max-lines-per-function}/SKILL.md +2 -2
  89. package/plugins/lisa-rails/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
  90. package/plugins/lisa-rails/skills/jira-create/SKILL.md +59 -28
  91. package/plugins/lisa-rails/skills/jira-verify/SKILL.md +13 -16
  92. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  93. package/plugins/src/base/agents/jira-build-intake.md +58 -0
  94. package/plugins/src/base/agents/notion-prd-intake.md +57 -0
  95. package/plugins/src/base/commands/{plan/fix-linter-error.md → fix/linter-error.md} +1 -1
  96. package/plugins/src/base/commands/implement.md +6 -0
  97. package/plugins/{lisa/commands/plan/lower-code-complexity.md → src/base/commands/improve/code-complexity.md} +1 -1
  98. package/plugins/src/base/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +1 -1
  99. package/plugins/src/base/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +1 -1
  100. package/plugins/src/base/commands/{plan/improve-tests.md → improve/tests.md} +1 -1
  101. package/plugins/src/base/commands/plan.md +15 -3
  102. package/plugins/src/base/commands/product-walkthrough.md +7 -0
  103. package/plugins/{lisa/commands/plan/local-code-review.md → src/base/commands/review/local.md} +1 -1
  104. package/plugins/{lisa/skills/plan-fix-linter-error → src/base/skills/fix-linter-error}/SKILL.md +2 -2
  105. package/plugins/src/base/skills/{plan-execute → implement}/SKILL.md +1 -1
  106. package/plugins/src/base/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
  107. package/plugins/src/base/skills/{plan-reduce-max-lines → improve-max-lines}/SKILL.md +2 -2
  108. package/plugins/{lisa/skills/plan-reduce-max-lines-per-function → src/base/skills/improve-max-lines-per-function}/SKILL.md +2 -2
  109. package/plugins/src/base/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
  110. package/plugins/{lisa/skills/plan-improve-tests → src/base/skills/improve-tests}/SKILL.md +2 -2
  111. package/plugins/src/base/skills/jira-build-intake/SKILL.md +134 -0
  112. package/plugins/src/base/skills/jira-create/SKILL.md +53 -30
  113. package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +107 -0
  114. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +224 -0
  115. package/plugins/src/base/skills/jira-verify/SKILL.md +15 -91
  116. package/plugins/src/base/skills/jira-write-ticket/SKILL.md +20 -15
  117. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +169 -0
  118. package/plugins/src/base/skills/notion-to-jira/SKILL.md +137 -95
  119. package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +137 -0
  120. package/plugins/src/base/skills/product-walkthrough/SKILL.md +129 -0
  121. package/plugins/src/base/skills/{plan-local-code-review → review-local}/SKILL.md +1 -1
  122. package/plugins/src/expo/skills/jira-create/SKILL.md +60 -28
  123. package/plugins/src/expo/skills/jira-verify/SKILL.md +14 -34
  124. package/plugins/src/rails/skills/{plan-fix-linter-error → fix-linter-error}/SKILL.md +2 -2
  125. package/plugins/src/rails/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
  126. package/plugins/{lisa-rails/skills/plan-reduce-max-lines → src/rails/skills/improve-max-lines}/SKILL.md +2 -2
  127. package/plugins/{lisa-rails/skills/plan-reduce-max-lines-per-function → src/rails/skills/improve-max-lines-per-function}/SKILL.md +2 -2
  128. package/plugins/src/rails/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
  129. package/plugins/src/rails/skills/jira-create/SKILL.md +59 -28
  130. package/plugins/src/rails/skills/jira-verify/SKILL.md +13 -16
  131. package/plugins/lisa/commands/build.md +0 -12
  132. package/plugins/lisa/commands/fix.md +0 -12
  133. package/plugins/lisa/commands/improve.md +0 -18
  134. package/plugins/lisa/commands/investigate.md +0 -10
  135. package/plugins/lisa/commands/jira/add-journey.md +0 -7
  136. package/plugins/lisa/commands/jira/create.md +0 -7
  137. package/plugins/lisa/commands/jira/evidence.md +0 -7
  138. package/plugins/lisa/commands/jira/journey.md +0 -7
  139. package/plugins/lisa/commands/jira/read-ticket.md +0 -7
  140. package/plugins/lisa/commands/jira/sync.md +0 -7
  141. package/plugins/lisa/commands/jira/triage.md +0 -7
  142. package/plugins/lisa/commands/jira/verify.md +0 -7
  143. package/plugins/lisa/commands/jira/write-ticket.md +0 -7
  144. package/plugins/lisa/commands/plan/create.md +0 -8
  145. package/plugins/lisa/commands/plan/execute.md +0 -6
  146. package/plugins/lisa/commands/review/implementation.md +0 -7
  147. package/plugins/lisa/commands/review.md +0 -10
  148. package/plugins/lisa/commands/ship.md +0 -8
  149. package/plugins/lisa/commands/spec-conformance.md +0 -7
  150. package/plugins/lisa-expo/commands/jira/add-journey.md +0 -7
  151. package/plugins/lisa-expo/commands/jira/create.md +0 -7
  152. package/plugins/lisa-expo/commands/jira/evidence.md +0 -7
  153. package/plugins/lisa-expo/commands/jira/journey.md +0 -7
  154. package/plugins/lisa-expo/commands/jira/verify.md +0 -7
  155. package/plugins/lisa-rails/commands/jira/add-journey.md +0 -7
  156. package/plugins/lisa-rails/commands/jira/create.md +0 -7
  157. package/plugins/lisa-rails/commands/jira/evidence.md +0 -7
  158. package/plugins/lisa-rails/commands/jira/journey.md +0 -7
  159. package/plugins/lisa-rails/commands/jira/verify.md +0 -7
  160. package/plugins/src/base/commands/build.md +0 -12
  161. package/plugins/src/base/commands/fix.md +0 -12
  162. package/plugins/src/base/commands/improve.md +0 -18
  163. package/plugins/src/base/commands/investigate.md +0 -10
  164. package/plugins/src/base/commands/jira/add-journey.md +0 -7
  165. package/plugins/src/base/commands/jira/create.md +0 -7
  166. package/plugins/src/base/commands/jira/evidence.md +0 -7
  167. package/plugins/src/base/commands/jira/journey.md +0 -7
  168. package/plugins/src/base/commands/jira/read-ticket.md +0 -7
  169. package/plugins/src/base/commands/jira/sync.md +0 -7
  170. package/plugins/src/base/commands/jira/triage.md +0 -7
  171. package/plugins/src/base/commands/jira/verify.md +0 -7
  172. package/plugins/src/base/commands/jira/write-ticket.md +0 -7
  173. package/plugins/src/base/commands/plan/create.md +0 -8
  174. package/plugins/src/base/commands/plan/execute.md +0 -6
  175. package/plugins/src/base/commands/review/implementation.md +0 -7
  176. package/plugins/src/base/commands/review.md +0 -10
  177. package/plugins/src/base/commands/ship.md +0 -8
  178. package/plugins/src/base/commands/spec-conformance.md +0 -7
  179. package/plugins/src/expo/commands/jira/add-journey.md +0 -7
  180. package/plugins/src/expo/commands/jira/create.md +0 -7
  181. package/plugins/src/expo/commands/jira/evidence.md +0 -7
  182. package/plugins/src/expo/commands/jira/journey.md +0 -7
  183. package/plugins/src/expo/commands/jira/verify.md +0 -7
  184. package/plugins/src/rails/commands/jira/add-journey.md +0 -7
  185. package/plugins/src/rails/commands/jira/create.md +0 -7
  186. package/plugins/src/rails/commands/jira/evidence.md +0 -7
  187. package/plugins/src/rails/commands/jira/journey.md +0 -7
  188. package/plugins/src/rails/commands/jira/verify.md +0 -7
  189. /package/plugins/lisa/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
  190. /package/plugins/lisa-rails/commands/{plan/fix-linter-error.md → fix/linter-error.md} +0 -0
  191. /package/plugins/lisa-rails/commands/{plan/lower-code-complexity.md → improve/code-complexity.md} +0 -0
  192. /package/plugins/lisa-rails/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +0 -0
  193. /package/plugins/lisa-rails/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
  194. /package/plugins/lisa-rails/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +0 -0
  195. /package/plugins/src/base/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
  196. /package/plugins/src/rails/commands/{plan/fix-linter-error.md → fix/linter-error.md} +0 -0
  197. /package/plugins/src/rails/commands/{plan/lower-code-complexity.md → improve/code-complexity.md} +0 -0
  198. /package/plugins/src/rails/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +0 -0
  199. /package/plugins/src/rails/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
  200. /package/plugins/src/rails/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +0 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Tracking manifest for Lisa-managed Codex artifacts.
3
+ *
4
+ * When Lisa emits files into a host project's `.codex/` directory, it needs
5
+ * a way to identify those files on the next run so:
6
+ * 1. Stale files (agents/hooks Lisa stopped shipping) can be cleaned up
7
+ * 2. Host-authored files (siblings in `.codex/agents/`, custom hook entries)
8
+ * are never accidentally overwritten or deleted
9
+ *
10
+ * For agent files specifically we cannot embed marker fields *inside* the
11
+ * TOML itself (Codex's `RawAgentRoleFileToml` deserializer is configured with
12
+ * `#[serde(deny_unknown_fields)]` — a `_lisa_managed` key would cause Codex
13
+ * to reject the file at load time). The manifest is the workaround.
14
+ *
15
+ * The manifest lives at `.codex/.lisa-managed.json` in the destination
16
+ * project. It is checked into the host repo so the cleanup behavior is
17
+ * deterministic across machines.
18
+ * @module codex/manifest
19
+ */
20
+ import * as fse from "fs-extra";
21
+ import { readFile, writeFile } from "node:fs/promises";
22
+ import * as path from "node:path";
23
+ /** Filename of the Lisa-managed manifest, relative to `.codex/` */
24
+ export const LISA_MANAGED_MANIFEST_FILENAME = ".lisa-managed.json";
25
+ /**
26
+ * Read the Lisa-managed manifest from `<destDir>/.codex/.lisa-managed.json`.
27
+ * Returns an empty manifest if the file doesn't exist.
28
+ * @param destDir - Absolute path to the destination project root
29
+ * @returns Parsed manifest (with empty file list if absent)
30
+ */
31
+ export async function readManagedManifest(destDir) {
32
+ const manifestPath = path.join(destDir, ".codex", LISA_MANAGED_MANIFEST_FILENAME);
33
+ if (!(await fse.pathExists(manifestPath))) {
34
+ return { files: [] };
35
+ }
36
+ const raw = await readFile(manifestPath, "utf8");
37
+ const parsed = JSON.parse(raw);
38
+ return validateManifest(parsed, manifestPath);
39
+ }
40
+ /**
41
+ * Write the Lisa-managed manifest to disk, replacing any existing content.
42
+ * @param destDir - Absolute path to the destination project root
43
+ * @param files - Sorted list of relative-to-`.codex/` file paths Lisa shipped
44
+ */
45
+ export async function writeManagedManifest(destDir, files) {
46
+ const codexDir = path.join(destDir, ".codex");
47
+ await fse.ensureDir(codexDir);
48
+ const manifestPath = path.join(codexDir, LISA_MANAGED_MANIFEST_FILENAME);
49
+ const manifest = {
50
+ files: [...files].sort((a, b) => a.localeCompare(b)),
51
+ };
52
+ await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
53
+ }
54
+ /**
55
+ * Compute the set of stale files: in the previous manifest but not in the
56
+ * new shipment. These are candidates for deletion.
57
+ * @param previous - Manifest from the prior run
58
+ * @param current - File list Lisa is shipping this run (relative to `.codex/`)
59
+ * @returns Files that should be removed from the host project
60
+ */
61
+ export function diffManifests(previous, current) {
62
+ const currentSet = new Set(current);
63
+ return previous.files.filter(file => !currentSet.has(file));
64
+ }
65
+ /**
66
+ * Type-guard validator. Throws on shape errors so a corrupted manifest is
67
+ * surfaced rather than silently producing data loss.
68
+ * @param parsed - Untrusted JSON value
69
+ * @param manifestPath - Path used in error messages
70
+ * @returns Validated manifest
71
+ */
72
+ function validateManifest(parsed, manifestPath) {
73
+ if (parsed === null || typeof parsed !== "object") {
74
+ throw new Error(`Invalid Lisa-managed manifest at ${manifestPath}: expected JSON object`);
75
+ }
76
+ const obj = parsed;
77
+ if (!Array.isArray(obj.files)) {
78
+ throw new Error(`Invalid Lisa-managed manifest at ${manifestPath}: expected "files" array`);
79
+ }
80
+ const files = obj.files.filter((file) => typeof file === "string");
81
+ if (files.length !== obj.files.length) {
82
+ throw new Error(`Invalid Lisa-managed manifest at ${manifestPath}: "files" must contain only strings`);
83
+ }
84
+ return { files: Object.freeze(files) };
85
+ }
86
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/codex/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /** Filename of the Codex config file inside `.codex/` */
2
+ export declare const CONFIG_FILENAME = "config.toml";
3
+ /**
4
+ * Lisa-required settings to merge into `.codex/config.toml`. Host wins on
5
+ * conflict for any key NOT in this list; for these keys, Lisa wins.
6
+ *
7
+ * Why these specific keys:
8
+ * - `project_doc_max_bytes`: Codex truncates AGENTS.md / project doc walks
9
+ * at 32 KiB by default; Lisa's bundled rules can exceed that, so bump to
10
+ * 64 KiB. Hosts can override upward if they need more headroom.
11
+ */
12
+ export declare const LISA_REQUIRED_SETTINGS: Readonly<Record<string, unknown>>;
13
+ /** Result of a settings install pass */
14
+ export interface SettingsInstallResult {
15
+ /** Files written, relative to `.codex/`. Used to update the manifest. */
16
+ readonly managedFiles: readonly string[];
17
+ /** Whether the config file was newly created (vs. patched in place) */
18
+ readonly created: boolean;
19
+ }
20
+ /**
21
+ * Install or update Lisa's required settings in `.codex/config.toml`.
22
+ *
23
+ * Uses `patch` semantics: only keys that differ are written; everything else
24
+ * (comments, blank lines, key order, host-authored keys) is preserved
25
+ * byte-for-byte.
26
+ * @param destDir - Absolute path to the host project root
27
+ * @returns Result describing what was written
28
+ */
29
+ export declare function installSettings(destDir: string): Promise<SettingsInstallResult>;
30
+ /**
31
+ * Merge Lisa-required settings into a TOML document. Pure function for
32
+ * testability; the installer above is the I/O wrapper.
33
+ *
34
+ * If the existing content is empty, we synthesize a minimal TOML document
35
+ * containing only Lisa's required keys.
36
+ *
37
+ * Subtle TOML correctness note: `toml-patch.patch()` appends new root-level
38
+ * keys at the end of the document, which in TOML semantically attaches them
39
+ * to the last `[section]` header — a bug for our use case. To work around
40
+ * this, root keys that aren't already present are PREPENDED above the first
41
+ * section header instead of going through `patch()`. Existing keys that
42
+ * differ in value are still patched in place, preserving surrounding
43
+ * comments and key order.
44
+ * @param existingToml - Current contents of `.codex/config.toml` (or "")
45
+ * @returns Merged TOML string with comments/format preserved
46
+ */
47
+ export declare function mergeSettings(existingToml: string): string;
48
+ //# sourceMappingURL=settings-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-installer.d.ts","sourceRoot":"","sources":["../../src/codex/settings-installer.ts"],"names":[],"mappings":"AAsBA,yDAAyD;AACzD,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEpE,CAAC;AAEF,wCAAwC;AACxC,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,CAAC,CAchC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAc1D"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Manage Lisa-required settings in `.codex/config.toml`.
3
+ *
4
+ * Codex configuration is TOML, layered system → user → project; Lisa writes
5
+ * only the project-level file (`<destDir>/.codex/config.toml`). The merge
6
+ * preserves any host-authored keys, comments, blank lines, and key ordering
7
+ * by using `@decimalturn/toml-patch` — the only Node TOML library that
8
+ * round-trips comments correctly (verified during round-3 research).
9
+ *
10
+ * Lisa-managed keys (currently a small set; expand as needs arise):
11
+ * - `project_doc_max_bytes`: bumped to 65536 so AGENTS.md content beyond
12
+ * Codex's 32 KiB default isn't truncated.
13
+ * @module codex/settings-installer
14
+ */
15
+ import * as fse from "fs-extra";
16
+ import { readFile, writeFile } from "node:fs/promises";
17
+ import * as path from "node:path";
18
+ import { parse as parseToml, patch as patchToml, } from "@decimalturn/toml-patch";
19
+ /** Filename of the Codex config file inside `.codex/` */
20
+ export const CONFIG_FILENAME = "config.toml";
21
+ /**
22
+ * Lisa-required settings to merge into `.codex/config.toml`. Host wins on
23
+ * conflict for any key NOT in this list; for these keys, Lisa wins.
24
+ *
25
+ * Why these specific keys:
26
+ * - `project_doc_max_bytes`: Codex truncates AGENTS.md / project doc walks
27
+ * at 32 KiB by default; Lisa's bundled rules can exceed that, so bump to
28
+ * 64 KiB. Hosts can override upward if they need more headroom.
29
+ */
30
+ export const LISA_REQUIRED_SETTINGS = {
31
+ project_doc_max_bytes: 65536,
32
+ };
33
+ /**
34
+ * Install or update Lisa's required settings in `.codex/config.toml`.
35
+ *
36
+ * Uses `patch` semantics: only keys that differ are written; everything else
37
+ * (comments, blank lines, key order, host-authored keys) is preserved
38
+ * byte-for-byte.
39
+ * @param destDir - Absolute path to the host project root
40
+ * @returns Result describing what was written
41
+ */
42
+ export async function installSettings(destDir) {
43
+ const codexDir = path.join(destDir, ".codex");
44
+ await fse.ensureDir(codexDir);
45
+ const configPath = path.join(codexDir, CONFIG_FILENAME);
46
+ const exists = await fse.pathExists(configPath);
47
+ const existingContent = exists ? await readFile(configPath, "utf8") : "";
48
+ const merged = mergeSettings(existingContent);
49
+ await writeFile(configPath, merged, "utf8");
50
+ return {
51
+ managedFiles: Object.freeze([CONFIG_FILENAME]),
52
+ created: !exists,
53
+ };
54
+ }
55
+ /**
56
+ * Merge Lisa-required settings into a TOML document. Pure function for
57
+ * testability; the installer above is the I/O wrapper.
58
+ *
59
+ * If the existing content is empty, we synthesize a minimal TOML document
60
+ * containing only Lisa's required keys.
61
+ *
62
+ * Subtle TOML correctness note: `toml-patch.patch()` appends new root-level
63
+ * keys at the end of the document, which in TOML semantically attaches them
64
+ * to the last `[section]` header — a bug for our use case. To work around
65
+ * this, root keys that aren't already present are PREPENDED above the first
66
+ * section header instead of going through `patch()`. Existing keys that
67
+ * differ in value are still patched in place, preserving surrounding
68
+ * comments and key order.
69
+ * @param existingToml - Current contents of `.codex/config.toml` (or "")
70
+ * @returns Merged TOML string with comments/format preserved
71
+ */
72
+ export function mergeSettings(existingToml) {
73
+ if (existingToml.trim().length === 0) {
74
+ // Nothing to preserve — emit a clean Lisa-managed file
75
+ return `${formatLisaSettings()}\n`;
76
+ }
77
+ const parsed = parseToml(existingToml);
78
+ const partitioned = partitionRequiredKeys(parsed);
79
+ const afterUpdates = applyUpdatedKeys(existingToml, parsed, partitioned.updated);
80
+ const afterPrepend = applyNewKeys(afterUpdates, partitioned.added);
81
+ return afterPrepend.endsWith("\n") ? afterPrepend : `${afterPrepend}\n`;
82
+ }
83
+ /**
84
+ * Split Lisa's required settings into "already-present-but-different" (which
85
+ * we update in place via toml-patch to preserve comments) and "wholly new"
86
+ * (which need careful insertion above the first table to avoid TOML's
87
+ * "attach to last section" semantics).
88
+ * @param parsed - Existing TOML parsed as a JS object
89
+ * @returns Two records: keys to update, keys to add
90
+ */
91
+ function partitionRequiredKeys(parsed) {
92
+ const entries = Object.entries(LISA_REQUIRED_SETTINGS);
93
+ const updated = Object.fromEntries(entries.filter(([key, value]) => key in parsed && parsed[key] !== value));
94
+ const added = Object.fromEntries(entries.filter(([key]) => !(key in parsed)));
95
+ return { updated, added };
96
+ }
97
+ /**
98
+ * Patch in-place updates via `toml-patch` so surrounding comments, blank
99
+ * lines, and key order survive untouched. No-op when nothing to update.
100
+ * @param toml - Existing TOML source
101
+ * @param parsed - Existing TOML parsed as a JS object
102
+ * @param updated - Keys whose values should change
103
+ * @returns Patched TOML, or `toml` unchanged if no updates were needed
104
+ */
105
+ function applyUpdatedKeys(toml, parsed, updated) {
106
+ if (Object.keys(updated).length === 0) {
107
+ return toml;
108
+ }
109
+ return patchToml(toml, { ...parsed, ...updated });
110
+ }
111
+ /**
112
+ * Add wholly new root keys ABOVE the first table header, sidestepping
113
+ * `toml-patch`'s default behavior of appending at the end (which would
114
+ * silently nest the new keys under the trailing section).
115
+ * @param toml - TOML source after in-place updates were applied
116
+ * @param added - Keys to insert
117
+ * @returns TOML with the new keys prepended (or unchanged if `added` is empty)
118
+ */
119
+ function applyNewKeys(toml, added) {
120
+ if (Object.keys(added).length === 0) {
121
+ return toml;
122
+ }
123
+ return prependRootKeys(toml, added);
124
+ }
125
+ /**
126
+ * Insert root-level key=value lines above the first `[section]` header in
127
+ * the provided TOML string. If no section header exists, append at the end.
128
+ *
129
+ * Required because TOML attaches every key to the most-recent table header,
130
+ * so naively appending a root key at the end of a document with sections
131
+ * silently nests it under the last section.
132
+ *
133
+ * Quote-state-aware: a line whose first non-whitespace char is `[` does
134
+ * NOT count as a section header if it sits inside an open multi-line string
135
+ * (`"""..."""` or `'''...'''`). Without this guard, a host config like
136
+ * `notes = """\n[release-notes]\nv1\n"""` would have Lisa keys spliced into
137
+ * the middle of the string, corrupting the file.
138
+ * @param toml - The TOML source to mutate
139
+ * @param keys - Root-level keys to insert
140
+ * @returns The TOML source with the new keys placed above any sections
141
+ */
142
+ function prependRootKeys(toml, keys) {
143
+ const block = Object.entries(keys)
144
+ .map(([key, value]) => `${key} = ${formatTomlValue(value)}`)
145
+ .join("\n");
146
+ const lines = toml.split("\n");
147
+ const sectionIndex = findFirstSectionHeaderIndex(lines);
148
+ if (sectionIndex === -1) {
149
+ // No sections — safe to append at the end
150
+ return `${stripTrailingNewlines(toml)}\n${block}\n`;
151
+ }
152
+ const before = stripTrailingNewlines(lines.slice(0, sectionIndex).join("\n"));
153
+ const after = lines.slice(sectionIndex).join("\n");
154
+ const beforePart = before.length > 0 ? `${before}\n` : "";
155
+ return `${beforePart}${block}\n\n${after}`;
156
+ }
157
+ /**
158
+ * Find the line index of the first real `[section]` header, skipping any
159
+ * `[`-prefixed lines that sit inside an open multi-line TOML string.
160
+ *
161
+ * Tracks a single "currently-open multi-line delimiter" (either `"""` or
162
+ * `'''`). Per TOML grammar these can't be nested, so a string token is
163
+ * sufficient state.
164
+ * @param lines - The TOML source split on `\n`
165
+ * @returns The 0-based line index, or -1 if no section header exists
166
+ */
167
+ function findFirstSectionHeaderIndex(lines) {
168
+ return lines.reduce((acc, line, idx) => {
169
+ if (acc.index !== -1) {
170
+ return acc;
171
+ }
172
+ const nextDelim = updateMultilineState(line, acc.openDelim);
173
+ // A `[` line only counts when we're NOT currently inside a multi-line
174
+ // string AND the line didn't open one this iteration.
175
+ if (acc.openDelim === undefined &&
176
+ nextDelim === undefined &&
177
+ /^[ \t]*\[/.test(line)) {
178
+ return { index: idx, openDelim: nextDelim };
179
+ }
180
+ return { index: -1, openDelim: nextDelim };
181
+ }, { index: -1, openDelim: undefined }).index;
182
+ }
183
+ /**
184
+ * Compute the new "currently-open multi-line delimiter" state for a line.
185
+ *
186
+ * Counts `"""` and `'''` occurrences on the line (each pair toggles).
187
+ * When entering, `openDelim` becomes the delimiter type; an odd count
188
+ * within the same line toggles state; an even count leaves it unchanged.
189
+ * @param line - One line of TOML source
190
+ * @param openDelim - Currently open delimiter (`"""` / `'''` / undefined)
191
+ * @returns The state after consuming this line
192
+ */
193
+ function updateMultilineState(line, openDelim) {
194
+ if (openDelim !== undefined) {
195
+ const occurrences = countOccurrences(line, openDelim);
196
+ return occurrences % 2 === 1 ? undefined : openDelim;
197
+ }
198
+ const tripleDouble = countOccurrences(line, '"""');
199
+ const tripleSingle = countOccurrences(line, "'''");
200
+ if (tripleDouble % 2 === 1) {
201
+ return '"""';
202
+ }
203
+ if (tripleSingle % 2 === 1) {
204
+ return "'''";
205
+ }
206
+ return undefined;
207
+ }
208
+ /**
209
+ * Count non-overlapping occurrences of `needle` in `haystack`.
210
+ * @param haystack - String to search within
211
+ * @param needle - Substring to count
212
+ * @returns Non-negative integer
213
+ */
214
+ function countOccurrences(haystack, needle) {
215
+ if (needle.length === 0) {
216
+ return 0;
217
+ }
218
+ // Splitting on the needle gives N+1 segments for N occurrences.
219
+ return haystack.split(needle).length - 1;
220
+ }
221
+ /**
222
+ * Strip a run of trailing `\n` characters from a string without using a
223
+ * regex (Sonar flags `\n+$` as potentially-backtracking, even though it
224
+ * isn't). Other trailing whitespace (spaces, tabs) is preserved because
225
+ * TOML doesn't care and we want minimal change.
226
+ * @param value - String to strip
227
+ * @returns The same string with any trailing newlines removed
228
+ */
229
+ function stripTrailingNewlines(value) {
230
+ const lastNonNewline = lastNonNewlineIndex(value);
231
+ return value.slice(0, lastNonNewline + 1);
232
+ }
233
+ /**
234
+ * Find the index of the last character in `value` that isn't `\n`. Returns
235
+ * -1 if the string is empty or all newlines.
236
+ * @param value - String to scan
237
+ * @returns The 0-based index of the last non-newline character, or -1
238
+ */
239
+ function lastNonNewlineIndex(value) {
240
+ return Array.from(value)
241
+ .map((char, idx) => ({ char, idx }))
242
+ .filter(({ char }) => char !== "\n")
243
+ .reduce((_, { idx }) => idx, -1);
244
+ }
245
+ /**
246
+ * Render Lisa's required settings as a fresh TOML block. Used when no
247
+ * host config file exists yet.
248
+ * @returns The starter TOML content (without trailing newline)
249
+ */
250
+ function formatLisaSettings() {
251
+ const header = [
252
+ "# This file is partly managed by Lisa.",
253
+ "# The keys Lisa owns are listed below; other keys you add are preserved on update.",
254
+ ];
255
+ const settings = Object.entries(LISA_REQUIRED_SETTINGS).map(([key, value]) => `${key} = ${formatTomlValue(value)}`);
256
+ return [...header, ...settings].join("\n");
257
+ }
258
+ /**
259
+ * Minimal TOML value formatter for the small set of value shapes we emit
260
+ * in fresh-file mode (numbers, strings, booleans).
261
+ * @param value - A value drawn from LISA_REQUIRED_SETTINGS
262
+ * @returns The TOML literal representation
263
+ */
264
+ function formatTomlValue(value) {
265
+ if (typeof value === "number") {
266
+ return String(value);
267
+ }
268
+ if (typeof value === "boolean") {
269
+ return value ? "true" : "false";
270
+ }
271
+ if (typeof value === "string") {
272
+ return JSON.stringify(value);
273
+ }
274
+ throw new Error(`Unsupported settings value type ${typeof value}: ${String(value)}`);
275
+ }
276
+ //# sourceMappingURL=settings-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-installer.js","sourceRoot":"","sources":["../../src/codex/settings-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,KAAK,IAAI,SAAS,EAClB,KAAK,IAAI,SAAS,GACnB,MAAM,yBAAyB,CAAC;AAEjC,yDAAyD;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsC;IACvE,qBAAqB,EAAE,KAAK;CAC7B,CAAC;AAUF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe;IAEf,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEzE,MAAM,MAAM,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,MAAM,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAE5C,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;QAC9C,OAAO,EAAE,CAAC,MAAM;KACjB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAAC,YAAoB;IAChD,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,uDAAuD;QACvD,OAAO,GAAG,kBAAkB,EAAE,IAAI,CAAC;IACrC,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAA4B,CAAC;IAClE,MAAM,WAAW,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,gBAAgB,CACnC,YAAY,EACZ,MAAM,EACN,WAAW,CAAC,OAAO,CACpB,CAAC;IACF,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IACnE,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,qBAAqB,CAAC,MAA+B;IAI5D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CACzE,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gBAAgB,CACvB,IAAY,EACZ,MAA+B,EAC/B,OAAgC;IAEhC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,IAAY,EAAE,KAA8B;IAChE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,eAAe,CAAC,IAAY,EAAE,IAA6B;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;SAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;SAC3D,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,YAAY,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAExD,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;QACxB,0CAA0C;QAC1C,OAAO,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,OAAO,GAAG,UAAU,GAAG,KAAK,OAAO,KAAK,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,2BAA2B,CAAC,KAAwB;IAC3D,OAAO,KAAK,CAAC,MAAM,CAIjB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QACjB,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5D,sEAAsE;QACtE,sDAAsD;QACtD,IACE,GAAG,CAAC,SAAS,KAAK,SAAS;YAC3B,SAAS,KAAK,SAAS;YACvB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EACtB,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAC7C,CAAC,EACD,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,SAA+B,EAAE,CAC1D,CAAC,KAAK,CAAC;AACV,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAC3B,IAAY,EACZ,SAA6B;IAE7B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtD,OAAO,WAAW,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnD,IAAI,YAAY,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,YAAY,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,QAAgB,EAAE,MAAc;IACxD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,gEAAgE;IAChE,OAAO,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,qBAAqB,CAAC,KAAa;IAC1C,MAAM,cAAc,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;SACnC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;SACnC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB;IACzB,MAAM,MAAM,GAAG;QACb,wCAAwC;QACxC,oFAAoF;KACrF,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,CACzD,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,CACvD,CAAC;IACF,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,IAAI,KAAK,CACb,mCAAmC,OAAO,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CACpE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ /** Subdirectory inside `.codex/skills/` where Lisa-owned skills live */
2
+ export declare const LISA_SKILLS_SUBDIR: string;
3
+ /** Prefix applied to Lisa command-as-skill names */
4
+ export declare const LISA_COMMAND_SKILL_PREFIX = "lisa-";
5
+ /** Result of one skill copy */
6
+ export interface InstalledSkill {
7
+ /** Skill name (matches the SKILL.md `name` frontmatter) */
8
+ readonly name: string;
9
+ /** Source kind: bundled skill folder or generated from command */
10
+ readonly source: "bundled" | "command";
11
+ /** Path written, relative to `.codex/` */
12
+ readonly relativePath: string;
13
+ }
14
+ /** Aggregated result */
15
+ export interface SkillsInstallResult {
16
+ readonly installed: readonly InstalledSkill[];
17
+ readonly managedFiles: readonly string[];
18
+ /** Skill directories deleted because Lisa stopped shipping them */
19
+ readonly deleted: readonly string[];
20
+ }
21
+ /**
22
+ * Install all Lisa-bundled skills + command-derived skills.
23
+ *
24
+ * Stale skills (in the previous manifest but no longer in Lisa's catalog)
25
+ * are deleted from `.codex/skills/lisa/` so renames in the source tree
26
+ * don't leave orphan directories behind.
27
+ * @param lisaDir - Absolute path to the Lisa repo root
28
+ * @param destDir - Absolute path to the host project root
29
+ * @param previousManagedFiles - Files Lisa managed on the previous run
30
+ * (relative to `.codex/`); used to detect stale skill directories
31
+ * @returns Result describing installed skills + managed files + deletions
32
+ */
33
+ export declare function installSkills(lisaDir: string, destDir: string, previousManagedFiles: readonly string[]): Promise<SkillsInstallResult>;
34
+ /**
35
+ * Pure transform: convert a Lisa command markdown to a Codex skill markdown.
36
+ *
37
+ * Preserves the description from the command's frontmatter; strips the
38
+ * `argument-hint` field (no analog in skills); strips `$ARGUMENTS`
39
+ * substitution markers from the body.
40
+ * @param commandSource - Raw contents of the command .md file
41
+ * @param skillName - Target skill name (already includes the `lisa-` prefix)
42
+ * @param displayName - Human-readable name used as a fallback description
43
+ * @returns The Codex skill SKILL.md content as a string
44
+ */
45
+ export declare function convertCommandToSkill(commandSource: string, skillName: string, displayName: string): string;
46
+ //# sourceMappingURL=skills-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-installer.d.ts","sourceRoot":"","sources":["../../src/codex/skills-installer.ts"],"names":[],"mappings":"AAiCA,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAE9D,oDAAoD;AACpD,eAAO,MAAM,yBAAyB,UAAU,CAAC;AAKjD,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IACvC,0CAA0C;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAwB;AACxB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,oBAAoB,EAAE,SAAS,MAAM,EAAE,GACtC,OAAO,CAAC,mBAAmB,CAAC,CAyC9B;AAuTD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,MAAM,CAgCR"}