@codyswann/lisa 1.94.0 → 1.96.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 (104) 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-agent.md +21 -8
  51. package/plugins/lisa/agents/jira-build-intake.md +58 -0
  52. package/plugins/lisa/agents/notion-prd-intake.md +57 -0
  53. package/plugins/lisa/commands/jira/build-intake.md +7 -0
  54. package/plugins/lisa/commands/jira/source-artifacts.md +6 -0
  55. package/plugins/lisa/commands/jira/validate-ticket.md +7 -0
  56. package/plugins/lisa/commands/notion-prd-intake.md +7 -0
  57. package/plugins/lisa/commands/prd-ticket-coverage.md +7 -0
  58. package/plugins/lisa/commands/product-walkthrough.md +7 -0
  59. package/plugins/lisa/rules/base-rules.md +9 -1
  60. package/plugins/lisa/skills/jira-build-intake/SKILL.md +134 -0
  61. package/plugins/lisa/skills/jira-create/SKILL.md +53 -30
  62. package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +107 -0
  63. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +224 -0
  64. package/plugins/lisa/skills/jira-verify/SKILL.md +15 -35
  65. package/plugins/lisa/skills/jira-write-ticket/SKILL.md +72 -19
  66. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +169 -0
  67. package/plugins/lisa/skills/notion-to-jira/SKILL.md +137 -95
  68. package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +137 -0
  69. package/plugins/lisa/skills/product-walkthrough/SKILL.md +129 -0
  70. package/plugins/lisa/skills/ticket-triage/SKILL.md +19 -2
  71. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-expo/skills/jira-create/SKILL.md +60 -28
  74. package/plugins/lisa-expo/skills/jira-verify/SKILL.md +14 -34
  75. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-rails/skills/jira-create/SKILL.md +59 -28
  78. package/plugins/lisa-rails/skills/jira-verify/SKILL.md +13 -16
  79. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  80. package/plugins/src/base/agents/jira-agent.md +21 -8
  81. package/plugins/src/base/agents/jira-build-intake.md +58 -0
  82. package/plugins/src/base/agents/notion-prd-intake.md +57 -0
  83. package/plugins/src/base/commands/jira/build-intake.md +7 -0
  84. package/plugins/src/base/commands/jira/source-artifacts.md +6 -0
  85. package/plugins/src/base/commands/jira/validate-ticket.md +7 -0
  86. package/plugins/src/base/commands/notion-prd-intake.md +7 -0
  87. package/plugins/src/base/commands/prd-ticket-coverage.md +7 -0
  88. package/plugins/src/base/commands/product-walkthrough.md +7 -0
  89. package/plugins/src/base/rules/base-rules.md +9 -1
  90. package/plugins/src/base/skills/jira-build-intake/SKILL.md +134 -0
  91. package/plugins/src/base/skills/jira-create/SKILL.md +53 -30
  92. package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +107 -0
  93. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +224 -0
  94. package/plugins/src/base/skills/jira-verify/SKILL.md +15 -35
  95. package/plugins/src/base/skills/jira-write-ticket/SKILL.md +72 -19
  96. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +169 -0
  97. package/plugins/src/base/skills/notion-to-jira/SKILL.md +137 -95
  98. package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +137 -0
  99. package/plugins/src/base/skills/product-walkthrough/SKILL.md +129 -0
  100. package/plugins/src/base/skills/ticket-triage/SKILL.md +19 -2
  101. package/plugins/src/expo/skills/jira-create/SKILL.md +60 -28
  102. package/plugins/src/expo/skills/jira-verify/SKILL.md +14 -34
  103. package/plugins/src/rails/skills/jira-create/SKILL.md +59 -28
  104. package/plugins/src/rails/skills/jira-verify/SKILL.md +13 -16
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Install Lisa-bundled skills into a host project's `.codex/skills/lisa/`.
3
+ *
4
+ * Skills are the open Agent Skills format (SKILL.md + optional siblings).
5
+ * Codex discovers them from the project config folder (`<destDir>/.codex/`)
6
+ * via the loader at `codex-rs/core-skills/src/loader.rs`.
7
+ *
8
+ * What this installs:
9
+ * 1. Lisa-bundled skill folders from `plugins/<p>/skills/<n>/` are copied
10
+ * verbatim to `.codex/skills/lisa/<n>/`.
11
+ * 2. Lisa commands (e.g., `plugins/lisa/commands/fix.md`) are converted
12
+ * to skills since Codex has no first-class slash-command extension
13
+ * point. A command at `commands/jira/create.md` becomes a skill named
14
+ * `lisa-jira-create` invocable via `$lisa-jira-create`.
15
+ *
16
+ * The lisa-namespace prefix ensures Lisa's commands-as-skills don't collide
17
+ * with same-named skills (e.g., Lisa's `fix.md` command + Lisa's existing
18
+ * `fix` skill if one ever existed).
19
+ * @module codex/skills-installer
20
+ */
21
+ import * as fse from "fs-extra";
22
+ import yaml from "js-yaml";
23
+ import { copyFile, mkdir, readFile, readdir, rm, stat, writeFile, } from "node:fs/promises";
24
+ import * as path from "node:path";
25
+ /** Subdirectory inside `.codex/skills/` where Lisa-owned skills live */
26
+ export const LISA_SKILLS_SUBDIR = path.join("skills", "lisa");
27
+ /** Prefix applied to Lisa command-as-skill names */
28
+ export const LISA_COMMAND_SKILL_PREFIX = "lisa-";
29
+ /** Filename of the skill manifest at the root of every skill folder */
30
+ const SKILL_MD_FILENAME = "SKILL.md";
31
+ /**
32
+ * Install all Lisa-bundled skills + command-derived skills.
33
+ *
34
+ * Stale skills (in the previous manifest but no longer in Lisa's catalog)
35
+ * are deleted from `.codex/skills/lisa/` so renames in the source tree
36
+ * don't leave orphan directories behind.
37
+ * @param lisaDir - Absolute path to the Lisa repo root
38
+ * @param destDir - Absolute path to the host project root
39
+ * @param previousManagedFiles - Files Lisa managed on the previous run
40
+ * (relative to `.codex/`); used to detect stale skill directories
41
+ * @returns Result describing installed skills + managed files + deletions
42
+ */
43
+ export async function installSkills(lisaDir, destDir, previousManagedFiles) {
44
+ const skillsDir = path.join(destDir, ".codex", LISA_SKILLS_SUBDIR);
45
+ await fse.ensureDir(skillsDir);
46
+ // Step 1: bundled skills
47
+ const bundled = await discoverBundledSkills(lisaDir);
48
+ const bundledInstalls = await Promise.all(bundled.map(source => copyBundledSkill(source, skillsDir)));
49
+ const bundledFiles = bundled.flatMap(source => source.files.map(file => path.join(LISA_SKILLS_SUBDIR, source.skillName, file)));
50
+ // Step 2: command-as-skill conversions
51
+ const commandSkills = await discoverLisaCommands(lisaDir);
52
+ const commandInstalls = await Promise.all(commandSkills.map(cmd => emitCommandAsSkill(cmd, skillsDir)));
53
+ const commandFiles = commandInstalls.map(install => path.join(LISA_SKILLS_SUBDIR, install.name, SKILL_MD_FILENAME));
54
+ const installed = [
55
+ ...bundledInstalls,
56
+ ...commandInstalls,
57
+ ];
58
+ // Step 3: delete stale skill directories
59
+ const deleted = await deleteStaleSkills(previousManagedFiles, new Set(installed.map(s => s.name)), destDir);
60
+ return {
61
+ installed: Object.freeze(installed),
62
+ managedFiles: Object.freeze([...bundledFiles, ...commandFiles]),
63
+ deleted: Object.freeze(deleted),
64
+ };
65
+ }
66
+ /**
67
+ * Delete skill directories that were Lisa-managed last run but aren't
68
+ * shipped this run. Identifies skill names from the previous manifest by
69
+ * looking for paths inside `.codex/skills/lisa/<name>/...`.
70
+ *
71
+ * Whole directories are removed (not individual files) so siblings the host
72
+ * accidentally added inside a Lisa skill folder also disappear — Lisa owns
73
+ * the directory boundary, not just specific files.
74
+ * @param previousManagedFiles - Files Lisa managed on the previous run
75
+ * (relative to `.codex/`)
76
+ * @param currentSkillNames - Skill names Lisa is shipping this run
77
+ * @param destDir - Absolute path to the host project root
78
+ * @returns Sorted list of stale skill names that were deleted
79
+ */
80
+ async function deleteStaleSkills(previousManagedFiles, currentSkillNames, destDir) {
81
+ const lisaSkillsPrefix = `${LISA_SKILLS_SUBDIR}${path.sep}`;
82
+ const previousSkillNames = extractPreviousSkillNames(previousManagedFiles, lisaSkillsPrefix);
83
+ const stale = previousSkillNames.filter(name => !currentSkillNames.has(name));
84
+ await Promise.all(stale.map(async (name) => {
85
+ const absPath = path.join(destDir, ".codex", LISA_SKILLS_SUBDIR, name);
86
+ if (await fse.pathExists(absPath)) {
87
+ await rm(absPath, { recursive: true, force: true });
88
+ }
89
+ }));
90
+ return Object.freeze([...stale].sort((a, b) => a.localeCompare(b)));
91
+ }
92
+ /**
93
+ * Pick the unique skill-folder names out of the previous manifest's file
94
+ * list — every path inside `.codex/skills/lisa/<name>/...` contributes
95
+ * `<name>` to the result.
96
+ * @param previousManagedFiles - Files Lisa managed on the previous run
97
+ * @param lisaSkillsPrefix - The path prefix that identifies Lisa skill files
98
+ * @returns Unique skill names extracted from those paths
99
+ */
100
+ function extractPreviousSkillNames(previousManagedFiles, lisaSkillsPrefix) {
101
+ const names = previousManagedFiles
102
+ .filter(file => file.startsWith(lisaSkillsPrefix))
103
+ .map(file => file.slice(lisaSkillsPrefix.length).split(path.sep)[0])
104
+ .filter((name) => Boolean(name));
105
+ return Array.from(new Set(names));
106
+ }
107
+ /**
108
+ * Walk `plugins/<plugin>/skills/<name>/` discovering each skill folder.
109
+ * De-duplicates by skill name with last-wins semantics: the base `lisa`
110
+ * plugin is always processed first, then remaining plugins in alphabetical
111
+ * order, so any stack-specific or third-party plugin overrides the base
112
+ * regardless of how the name sorts.
113
+ * @param lisaDir - Absolute path to the Lisa repo / installed package
114
+ * @returns De-duplicated bundled-skill sources, sorted by skill name
115
+ */
116
+ async function discoverBundledSkills(lisaDir) {
117
+ const pluginsDir = path.join(lisaDir, "plugins");
118
+ if (!(await fse.pathExists(pluginsDir))) {
119
+ return [];
120
+ }
121
+ // Put the base "lisa" plugin first so it is always overridable by any
122
+ // other plugin via last-wins Map dedup below. Remaining plugins are
123
+ // sorted for deterministic ordering across machines.
124
+ const all = (await readdir(pluginsDir)).filter(name => name !== "src");
125
+ const plugins = [
126
+ ...all.filter(n => n === "lisa"),
127
+ ...all.filter(n => n !== "lisa").sort((a, b) => a.localeCompare(b)),
128
+ ];
129
+ const candidatesByPlugin = await Promise.all(plugins.map(pluginName => discoverSkillsInPlugin(pluginsDir, pluginName)));
130
+ // Base-first iteration order + last-wins Map → stack-specific (and any
131
+ // other non-base plugin) overrides base for duplicate skill names.
132
+ const flat = candidatesByPlugin.flat();
133
+ const deduped = Array.from(new Map(flat.map(source => [source.skillName, source])).values());
134
+ return Object.freeze([...deduped].sort((a, b) => a.skillName.localeCompare(b.skillName)));
135
+ }
136
+ /**
137
+ * Discover every skill directory under one plugin's `skills/` folder. Skips
138
+ * any non-directory entries (defensive against stray .DS_Store and similar).
139
+ * @param pluginsDir - Absolute path to `<lisaDir>/plugins`
140
+ * @param pluginName - Plugin directory name (e.g. "lisa", "lisa-rails")
141
+ * @returns Bundled-skill sources discovered in this plugin (file order)
142
+ */
143
+ async function discoverSkillsInPlugin(pluginsDir, pluginName) {
144
+ const skillsDir = path.join(pluginsDir, pluginName, "skills");
145
+ if (!(await fse.pathExists(skillsDir))) {
146
+ return [];
147
+ }
148
+ const skillNames = await readdir(skillsDir);
149
+ const candidates = await Promise.all(skillNames.map(async (skillName) => {
150
+ const sourceDir = path.join(skillsDir, skillName);
151
+ const dirStat = await stat(sourceDir);
152
+ if (!dirStat.isDirectory()) {
153
+ return undefined;
154
+ }
155
+ const files = await listFilesRecursive(sourceDir);
156
+ return { skillName, sourceDir, files };
157
+ }));
158
+ return candidates.filter((entry) => entry !== undefined);
159
+ }
160
+ /**
161
+ * Recursively list all file paths under `root` as relative paths. Pure
162
+ * recursion (no mutable accumulator) so the result is referentially clean.
163
+ * @param root - Absolute path to the directory to walk
164
+ * @returns Relative paths of every regular file under `root`
165
+ */
166
+ async function listFilesRecursive(root) {
167
+ return walkDir(root, "");
168
+ }
169
+ /**
170
+ * Recursive helper for listFilesRecursive. The relative path is threaded
171
+ * down so nested files come back as `subdir/file.ext` etc.
172
+ * @param root - Absolute path to the directory to walk
173
+ * @param rel - Path under `root` we're currently visiting (relative)
174
+ * @returns Relative paths of every regular file at or below `root/rel`
175
+ */
176
+ async function walkDir(root, rel) {
177
+ const abs = path.join(root, rel);
178
+ const entries = await readdir(abs, { withFileTypes: true });
179
+ const childResults = await Promise.all(entries.map(entry => {
180
+ const childRel = path.join(rel, entry.name);
181
+ if (entry.isDirectory()) {
182
+ return walkDir(root, childRel);
183
+ }
184
+ if (entry.isFile()) {
185
+ return Promise.resolve([childRel]);
186
+ }
187
+ return Promise.resolve([]);
188
+ }));
189
+ return childResults.flat();
190
+ }
191
+ /**
192
+ * Copy one bundled skill folder verbatim into the host's `.codex/skills/lisa/`.
193
+ * @param source - Bundled-skill source to copy
194
+ * @param skillsDir - Absolute path to `<destDir>/.codex/skills/lisa/`
195
+ * @returns Result describing the installed skill
196
+ */
197
+ async function copyBundledSkill(source, skillsDir) {
198
+ const destSkillDir = path.join(skillsDir, source.skillName);
199
+ await fse.ensureDir(destSkillDir);
200
+ await Promise.all(source.files.map(async (file) => {
201
+ const srcPath = path.join(source.sourceDir, file);
202
+ const destPath = path.join(destSkillDir, file);
203
+ await mkdir(path.dirname(destPath), { recursive: true });
204
+ await copyFile(srcPath, destPath);
205
+ }));
206
+ return {
207
+ name: source.skillName,
208
+ source: "bundled",
209
+ relativePath: path.join(LISA_SKILLS_SUBDIR, source.skillName),
210
+ };
211
+ }
212
+ /**
213
+ * Walk `plugins/<plugin>/commands/**\/*.md` discovering each command file.
214
+ * Nested directories produce dash-joined skill names: `commands/git/commit.md`
215
+ * → `lisa-git-commit`.
216
+ *
217
+ * De-duplicates by final skill name with last-wins semantics: the base `lisa`
218
+ * plugin is always processed first, then remaining plugins in alphabetical
219
+ * order, so any stack-specific or third-party plugin overrides the base
220
+ * regardless of how the name sorts.
221
+ * @param lisaDir - Absolute path to the Lisa repo / installed package
222
+ * @returns De-duplicated command-derived skill sources, sorted by skill name
223
+ */
224
+ async function discoverLisaCommands(lisaDir) {
225
+ const pluginsDir = path.join(lisaDir, "plugins");
226
+ if (!(await fse.pathExists(pluginsDir))) {
227
+ return [];
228
+ }
229
+ // Put the base "lisa" plugin first so it is always overridable by any
230
+ // other plugin via last-wins Map dedup below. Remaining plugins are
231
+ // sorted for deterministic ordering across machines.
232
+ const all = (await readdir(pluginsDir)).filter(name => name !== "src");
233
+ const plugins = [
234
+ ...all.filter(n => n === "lisa"),
235
+ ...all.filter(n => n !== "lisa").sort((a, b) => a.localeCompare(b)),
236
+ ];
237
+ const candidatesByPlugin = await Promise.all(plugins.map(pluginName => discoverCommandsInPlugin(pluginsDir, pluginName)));
238
+ // Base-first iteration order + last-wins Map → stack-specific (and any
239
+ // other non-base plugin) overrides base for duplicate command names.
240
+ const flat = candidatesByPlugin.flat();
241
+ const deduped = Array.from(new Map(flat.map(source => [source.skillName, source])).values());
242
+ return Object.freeze([...deduped].sort((a, b) => a.skillName.localeCompare(b.skillName)));
243
+ }
244
+ /**
245
+ * Discover every Markdown command file under one plugin's `commands/`
246
+ * folder, turning each into a LisaCommandSource. Returns [] if the plugin
247
+ * has no commands directory.
248
+ * @param pluginsDir - Absolute path to `<lisaDir>/plugins`
249
+ * @param pluginName - Plugin directory name
250
+ * @returns Command sources discovered in this plugin (file order)
251
+ */
252
+ async function discoverCommandsInPlugin(pluginsDir, pluginName) {
253
+ const commandsRoot = path.join(pluginsDir, pluginName, "commands");
254
+ if (!(await fse.pathExists(commandsRoot))) {
255
+ return [];
256
+ }
257
+ const files = await listFilesRecursive(commandsRoot);
258
+ return files
259
+ .filter(relFile => relFile.endsWith(".md"))
260
+ .map(relFile => {
261
+ // commands/git/commit.md → ["git", "commit"]
262
+ const segments = relFile.replace(/\.md$/, "").split(path.sep);
263
+ const skillName = `${LISA_COMMAND_SKILL_PREFIX}${segments.join("-")}`;
264
+ return {
265
+ skillName,
266
+ sourcePath: path.join(commandsRoot, relFile),
267
+ displayName: `lisa:${segments.join(":")}`,
268
+ };
269
+ });
270
+ }
271
+ /**
272
+ * Convert a Lisa command Markdown file into a Codex skill.
273
+ *
274
+ * The command's frontmatter (description) becomes the skill description.
275
+ * The command body becomes the skill body, with `$ARGUMENTS` removed since
276
+ * skills don't have CLI argument substitution — the user's natural-language
277
+ * input flows in via the surrounding conversation.
278
+ * @param cmd - Discovered command source
279
+ * @param skillsDir - Absolute path to `<destDir>/.codex/skills/lisa/`
280
+ * @returns Result describing the installed (command-derived) skill
281
+ */
282
+ async function emitCommandAsSkill(cmd, skillsDir) {
283
+ const sourceContent = await readFile(cmd.sourcePath, "utf8");
284
+ const skillContent = convertCommandToSkill(sourceContent, cmd.skillName, cmd.displayName);
285
+ const destSkillDir = path.join(skillsDir, cmd.skillName);
286
+ await fse.ensureDir(destSkillDir);
287
+ await writeFile(path.join(destSkillDir, SKILL_MD_FILENAME), skillContent, "utf8");
288
+ return {
289
+ name: cmd.skillName,
290
+ source: "command",
291
+ relativePath: path.join(LISA_SKILLS_SUBDIR, cmd.skillName),
292
+ };
293
+ }
294
+ /**
295
+ * Pure transform: convert a Lisa command markdown to a Codex skill markdown.
296
+ *
297
+ * Preserves the description from the command's frontmatter; strips the
298
+ * `argument-hint` field (no analog in skills); strips `$ARGUMENTS`
299
+ * substitution markers from the body.
300
+ * @param commandSource - Raw contents of the command .md file
301
+ * @param skillName - Target skill name (already includes the `lisa-` prefix)
302
+ * @param displayName - Human-readable name used as a fallback description
303
+ * @returns The Codex skill SKILL.md content as a string
304
+ */
305
+ export function convertCommandToSkill(commandSource, skillName, displayName) {
306
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(commandSource);
307
+ if (match === null || match[1] === undefined || match[2] === undefined) {
308
+ throw new Error(`Command source is missing YAML frontmatter for ${displayName}`);
309
+ }
310
+ const rawFrontmatter = match[1];
311
+ const rawBody = match[2];
312
+ // Parse the frontmatter properly so we get YAML-correct value extraction
313
+ // (handles quoting, escapes, multiline forms — all of which a hand-rolled
314
+ // regex would get wrong on adversarial input).
315
+ const parsedFrontmatter = yaml.load(rawFrontmatter);
316
+ const description = extractDescription(parsedFrontmatter, displayName);
317
+ const body = rawBody
318
+ .trimStart()
319
+ .replace(/\$ARGUMENTS\s*/g, "")
320
+ .trimEnd();
321
+ const frontmatter = [
322
+ "---",
323
+ `name: ${skillName}`,
324
+ `description: ${JSON.stringify(description)}`,
325
+ "---",
326
+ "",
327
+ ].join("\n");
328
+ return `${frontmatter}${body}\n`;
329
+ }
330
+ /**
331
+ * Pull the `description` field out of a parsed YAML frontmatter mapping,
332
+ * falling back to `displayName` if it's missing or not a string.
333
+ * @param parsed - Output of `yaml.load(rawFrontmatter)` (untrusted shape)
334
+ * @param displayName - Fallback used when no description is available
335
+ * @returns The description string to embed in the skill frontmatter
336
+ */
337
+ function extractDescription(parsed, displayName) {
338
+ if (parsed === null || typeof parsed !== "object") {
339
+ return displayName;
340
+ }
341
+ const value = parsed.description;
342
+ return typeof value === "string" && value.length > 0 ? value : displayName;
343
+ }
344
+ //# sourceMappingURL=skills-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-installer.js","sourceRoot":"","sources":["../../src/codex/skills-installer.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,23 @@ export declare const PROJECT_TYPE_ORDER: readonly ProjectType[];
18
18
  * All available copy strategies in processing order
19
19
  */
20
20
  export declare const COPY_STRATEGIES: readonly CopyStrategy[];
21
+ /**
22
+ * Target harness(es) for emitted artifacts.
23
+ *
24
+ * - "claude": emit Claude Code artifacts (.claude/, .claude-plugin/, etc.)
25
+ * - "codex": emit OpenAI Codex CLI artifacts (.codex/, .codex-plugin/, .agents/, AGENTS.md)
26
+ * - "both": emit both, so a project can use either harness
27
+ */
28
+ export type Harness = "claude" | "codex" | "both";
29
+ /**
30
+ * All valid harness values, in canonical order
31
+ */
32
+ export declare const HARNESS_VALUES: readonly Harness[];
33
+ /**
34
+ * Default harness when none is configured (backward compatibility — existing
35
+ * host projects predate Codex support and have always emitted .claude/ artifacts)
36
+ */
37
+ export declare const DEFAULT_HARNESS: Harness;
21
38
  /**
22
39
  * Runtime configuration for Lisa operations
23
40
  */
@@ -34,6 +51,8 @@ export interface LisaConfig {
34
51
  readonly validateOnly: boolean;
35
52
  /** If true, skip the dirty git working directory check (for postinstall use) */
36
53
  readonly skipGitCheck: boolean;
54
+ /** Target harness(es) for emitted artifacts (claude | codex | both) */
55
+ readonly harness: Harness;
37
56
  }
38
57
  /**
39
58
  * Operation mode for Lisa execution
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,eAAe,GACf,aAAa,GACb,OAAO,GACP,cAAc,GACd,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,KAAK,GACL,aAAa,GACb,OAAO,CAAC;AAEZ;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,CAQ/B,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,WAAW,EAO3C,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAOzC,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,gFAAgF;IAChF,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EACX,QAAQ,GACR,SAAS,GACT,aAAa,GACb,UAAU,GACV,QAAQ,GACR,SAAS,CAAC;IACd,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,oEAAoE;IACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,iBAAiB,CAYzD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,eAAe,GACf,aAAa,GACb,OAAO,GACP,cAAc,GACd,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,KAAK,GACL,aAAa,GACb,OAAO,CAAC;AAEZ;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,CAQ/B,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,WAAW,EAO3C,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAOzC,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,OAAO,EAInC,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,OAAkB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,gFAAgF;IAChF,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAE/B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EACX,QAAQ,GACR,SAAS,GACT,aAAa,GACb,UAAU,GACV,QAAQ,GACR,SAAS,CAAC;IACd,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,oEAAoE;IACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,iBAAiB,CAYzD"}
@@ -31,6 +31,19 @@ export const COPY_STRATEGIES = [
31
31
  "tagged-merge",
32
32
  "package-lisa",
33
33
  ];
34
+ /**
35
+ * All valid harness values, in canonical order
36
+ */
37
+ export const HARNESS_VALUES = [
38
+ "claude",
39
+ "codex",
40
+ "both",
41
+ ];
42
+ /**
43
+ * Default harness when none is configured (backward compatibility — existing
44
+ * host projects predate Codex support and have always emitted .claude/ artifacts)
45
+ */
46
+ export const DEFAULT_HARNESS = "claude";
34
47
  /**
35
48
  * Create initial operation counters with all values at zero
36
49
  * @returns Operation counters initialized to zero
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAE/B;IACF,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,YAAY;IACpB,GAAG,EAAE,YAAY;IACjB,aAAa,EAAE,YAAY;IAC3B,UAAU,EAAE,SAAS;IACrB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,YAAY;IACZ,aAAa;IACb,MAAM;IACN,QAAQ;IACR,KAAK;IACL,OAAO;CACC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAA4B;IACtD,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,OAAO;IACP,cAAc;IACd,cAAc;CACN,CAAC;AAkFX;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;KACrB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAE/B;IACF,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,YAAY;IACpB,GAAG,EAAE,YAAY;IACjB,aAAa,EAAE,YAAY;IAC3B,UAAU,EAAE,SAAS;IACrB,KAAK,EAAE,SAAS;CACR,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,YAAY;IACZ,aAAa;IACb,MAAM;IACN,QAAQ;IACR,KAAK;IACL,OAAO;CACC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAA4B;IACtD,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,OAAO;IACP,cAAc;IACd,cAAc;CACN,CAAC;AAWX;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAuB;IAChD,QAAQ;IACR,OAAO;IACP,MAAM;CACE,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY,QAAQ,CAAC;AAqFjD;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,CAAC;QACd,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;KACrB,CAAC;AACJ,CAAC"}
@@ -140,6 +140,18 @@ export declare class Lisa {
140
140
  * @returns Result of the apply operation
141
141
  */
142
142
  apply(): Promise<LisaResult>;
143
+ /**
144
+ * Emit Codex-targeted artifacts (agents, hooks, settings) when the host
145
+ * project's harness is `codex` or `both`. No-op for `claude` (default).
146
+ *
147
+ * Codex artifacts cannot be shipped via plugins (the Codex plugin manifest
148
+ * has no fields for hooks or agent roles, confirmed in
149
+ * `codex-rs/core-plugins/src/manifest.rs`). Lisa instead writes them
150
+ * directly into the host project's `.codex/` tree as part of `apply()`,
151
+ * tracking ownership via `.codex/.lisa-managed.json` so updates can clean
152
+ * up stale entries without touching host customizations.
153
+ */
154
+ private processCodexEmit;
143
155
  /**
144
156
  * Schedule a reconciliation re-run when Lisa is invoked as a package-manager
145
157
  * lifecycle script. Works around the fact that `bun add` (and similar
@@ -1 +1 @@
1
- {"version":3,"file":"lisa.d.ts","sourceRoot":"","sources":["../../src/core/lisa.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lisa.d.ts","sourceRoot":"","sources":["../../src/core/lisa.ts"],"names":[],"mappings":"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"}
package/dist/core/lisa.js CHANGED
@@ -3,6 +3,12 @@ import * as fse from "fs-extra";
3
3
  import { readFile, stat } from "node:fs/promises";
4
4
  import * as path from "node:path";
5
5
  import pc from "picocolors";
6
+ import { discoverLisaAgents, installAgents } from "../codex/agent-installer.js";
7
+ import { installHooks } from "../codex/hooks-installer.js";
8
+ import { readManagedManifest, writeManagedManifest, } from "../codex/manifest.js";
9
+ import { installAgentsMd } from "../codex/agents-md-installer.js";
10
+ import { installSettings } from "../codex/settings-installer.js";
11
+ import { installSkills } from "../codex/skills-installer.js";
6
12
  import { DestinationNotDirectoryError, DestinationNotFoundError, UserAbortedError, } from "../errors/index.js";
7
13
  import { listFilesRecursive } from "../utils/file-operations.js";
8
14
  import { loadIgnorePatterns, } from "../utils/ignore-patterns.js";
@@ -395,6 +401,7 @@ export class Lisa {
395
401
  await this.processConfigurations();
396
402
  await this.processDeletions();
397
403
  await this.processMigrations();
404
+ await this.processCodexEmit();
398
405
  await this.registerPlugins();
399
406
  await this.finalize();
400
407
  this.printSummary();
@@ -406,6 +413,47 @@ export class Lisa {
406
413
  return this.handleApplyError(error);
407
414
  }
408
415
  }
416
+ /**
417
+ * Emit Codex-targeted artifacts (agents, hooks, settings) when the host
418
+ * project's harness is `codex` or `both`. No-op for `claude` (default).
419
+ *
420
+ * Codex artifacts cannot be shipped via plugins (the Codex plugin manifest
421
+ * has no fields for hooks or agent roles, confirmed in
422
+ * `codex-rs/core-plugins/src/manifest.rs`). Lisa instead writes them
423
+ * directly into the host project's `.codex/` tree as part of `apply()`,
424
+ * tracking ownership via `.codex/.lisa-managed.json` so updates can clean
425
+ * up stale entries without touching host customizations.
426
+ */
427
+ async processCodexEmit() {
428
+ const { harness } = this.config;
429
+ if (harness !== "codex" && harness !== "both") {
430
+ return;
431
+ }
432
+ if (this.config.dryRun) {
433
+ this.deps.logger.info(pc.gray("Codex emit: skipped (dry-run mode)"));
434
+ return;
435
+ }
436
+ const previous = await readManagedManifest(this.config.destDir);
437
+ const agentSources = await discoverLisaAgents(this.config.lisaDir);
438
+ const agentResult = await installAgents(agentSources, this.config.destDir, previous.files);
439
+ const hooksResult = await installHooks(this.config.lisaDir, this.config.destDir, this.detectedTypes);
440
+ const settingsResult = await installSettings(this.config.destDir);
441
+ const skillsResult = await installSkills(this.config.lisaDir, this.config.destDir, previous.files);
442
+ // AGENTS.md is create-only — produced once and never managed by Lisa
443
+ // afterward, so it's not added to the manifest (Lisa doesn't own it).
444
+ await installAgentsMd(this.config.destDir);
445
+ const allManagedFiles = [
446
+ ...agentResult.managedFiles,
447
+ ...hooksResult.managedFiles,
448
+ ...settingsResult.managedFiles,
449
+ ...skillsResult.managedFiles,
450
+ ];
451
+ await writeManagedManifest(this.config.destDir, allManagedFiles);
452
+ const totalStale = agentResult.deleted.length + skillsResult.deleted.length;
453
+ this.deps.logger.info(pc.cyan(`Codex emit: ${agentResult.installed.length} agents, ${hooksResult.hookEntries} hooks, ${skillsResult.installed.length} skills, settings ${settingsResult.created ? "created" : "merged"}${totalStale > 0
454
+ ? ` (${agentResult.deleted.length} stale agents, ${skillsResult.deleted.length} stale skills removed)`
455
+ : ""}`));
456
+ }
409
457
  /**
410
458
  * Schedule a reconciliation re-run when Lisa is invoked as a package-manager
411
459
  * lifecycle script. Works around the fact that `bun add` (and similar