@codyswann/lisa 1.95.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.
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +41 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/codex/agent-installer.d.ts +56 -0
- package/dist/codex/agent-installer.d.ts.map +1 -0
- package/dist/codex/agent-installer.js +201 -0
- package/dist/codex/agent-installer.js.map +1 -0
- package/dist/codex/agent-transformer.d.ts +53 -0
- package/dist/codex/agent-transformer.d.ts.map +1 -0
- package/dist/codex/agent-transformer.js +181 -0
- package/dist/codex/agent-transformer.js.map +1 -0
- package/dist/codex/agents-md-installer.d.ts +24 -0
- package/dist/codex/agents-md-installer.d.ts.map +1 -0
- package/dist/codex/agents-md-installer.js +63 -0
- package/dist/codex/agents-md-installer.js.map +1 -0
- package/dist/codex/hooks-installer.d.ts +24 -0
- package/dist/codex/hooks-installer.d.ts.map +1 -0
- package/dist/codex/hooks-installer.js +206 -0
- package/dist/codex/hooks-installer.js.map +1 -0
- package/dist/codex/hooks-merger.d.ts +82 -0
- package/dist/codex/hooks-merger.d.ts.map +1 -0
- package/dist/codex/hooks-merger.js +127 -0
- package/dist/codex/hooks-merger.js.map +1 -0
- package/dist/codex/manifest.d.ts +32 -0
- package/dist/codex/manifest.d.ts.map +1 -0
- package/dist/codex/manifest.js +86 -0
- package/dist/codex/manifest.js.map +1 -0
- package/dist/codex/settings-installer.d.ts +48 -0
- package/dist/codex/settings-installer.d.ts.map +1 -0
- package/dist/codex/settings-installer.js +276 -0
- package/dist/codex/settings-installer.js.map +1 -0
- package/dist/codex/skills-installer.d.ts +46 -0
- package/dist/codex/skills-installer.d.ts.map +1 -0
- package/dist/codex/skills-installer.js +344 -0
- package/dist/codex/skills-installer.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +13 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa.d.ts +12 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +48 -0
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/project-config.d.ts +49 -0
- package/dist/core/project-config.d.ts.map +1 -0
- package/dist/core/project-config.js +119 -0
- package/dist/core/project-config.js.map +1 -0
- package/package.json +3 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/agents/jira-build-intake.md +58 -0
- package/plugins/lisa/agents/notion-prd-intake.md +57 -0
- package/plugins/lisa/commands/jira/build-intake.md +7 -0
- package/plugins/lisa/commands/jira/source-artifacts.md +6 -0
- package/plugins/lisa/commands/jira/validate-ticket.md +7 -0
- package/plugins/lisa/commands/notion-prd-intake.md +7 -0
- package/plugins/lisa/commands/prd-ticket-coverage.md +7 -0
- package/plugins/lisa/commands/product-walkthrough.md +7 -0
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +134 -0
- package/plugins/lisa/skills/jira-create/SKILL.md +53 -30
- package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +107 -0
- package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +224 -0
- package/plugins/lisa/skills/jira-verify/SKILL.md +15 -91
- package/plugins/lisa/skills/jira-write-ticket/SKILL.md +20 -15
- package/plugins/lisa/skills/notion-prd-intake/SKILL.md +169 -0
- package/plugins/lisa/skills/notion-to-jira/SKILL.md +137 -95
- package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +137 -0
- package/plugins/lisa/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/skills/jira-create/SKILL.md +60 -28
- package/plugins/lisa-expo/skills/jira-verify/SKILL.md +14 -34
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/skills/jira-create/SKILL.md +59 -28
- package/plugins/lisa-rails/skills/jira-verify/SKILL.md +13 -16
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/agents/jira-build-intake.md +58 -0
- package/plugins/src/base/agents/notion-prd-intake.md +57 -0
- package/plugins/src/base/commands/jira/build-intake.md +7 -0
- package/plugins/src/base/commands/jira/source-artifacts.md +6 -0
- package/plugins/src/base/commands/jira/validate-ticket.md +7 -0
- package/plugins/src/base/commands/notion-prd-intake.md +7 -0
- package/plugins/src/base/commands/prd-ticket-coverage.md +7 -0
- package/plugins/src/base/commands/product-walkthrough.md +7 -0
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +134 -0
- package/plugins/src/base/skills/jira-create/SKILL.md +53 -30
- package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +107 -0
- package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +224 -0
- package/plugins/src/base/skills/jira-verify/SKILL.md +15 -91
- package/plugins/src/base/skills/jira-write-ticket/SKILL.md +20 -15
- package/plugins/src/base/skills/notion-prd-intake/SKILL.md +169 -0
- package/plugins/src/base/skills/notion-to-jira/SKILL.md +137 -95
- package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +137 -0
- package/plugins/src/base/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/src/expo/skills/jira-create/SKILL.md +60 -28
- package/plugins/src/expo/skills/jira-verify/SKILL.md +14 -34
- package/plugins/src/rails/skills/jira-create/SKILL.md +59 -28
- 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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"}
|
package/dist/core/config.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/core/config.js
CHANGED
|
@@ -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
|
package/dist/core/config.js.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/core/lisa.d.ts
CHANGED
|
@@ -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
|
package/dist/core/lisa.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lisa.d.ts","sourceRoot":"","sources":["../../src/core/lisa.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
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
|