@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.
Files changed (98) 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/jira/build-intake.md +7 -0
  53. package/plugins/lisa/commands/jira/source-artifacts.md +6 -0
  54. package/plugins/lisa/commands/jira/validate-ticket.md +7 -0
  55. package/plugins/lisa/commands/notion-prd-intake.md +7 -0
  56. package/plugins/lisa/commands/prd-ticket-coverage.md +7 -0
  57. package/plugins/lisa/commands/product-walkthrough.md +7 -0
  58. package/plugins/lisa/skills/jira-build-intake/SKILL.md +134 -0
  59. package/plugins/lisa/skills/jira-create/SKILL.md +53 -30
  60. package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +107 -0
  61. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +224 -0
  62. package/plugins/lisa/skills/jira-verify/SKILL.md +15 -91
  63. package/plugins/lisa/skills/jira-write-ticket/SKILL.md +20 -15
  64. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +169 -0
  65. package/plugins/lisa/skills/notion-to-jira/SKILL.md +137 -95
  66. package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +137 -0
  67. package/plugins/lisa/skills/product-walkthrough/SKILL.md +129 -0
  68. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-expo/skills/jira-create/SKILL.md +60 -28
  71. package/plugins/lisa-expo/skills/jira-verify/SKILL.md +14 -34
  72. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-rails/skills/jira-create/SKILL.md +59 -28
  75. package/plugins/lisa-rails/skills/jira-verify/SKILL.md +13 -16
  76. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  77. package/plugins/src/base/agents/jira-build-intake.md +58 -0
  78. package/plugins/src/base/agents/notion-prd-intake.md +57 -0
  79. package/plugins/src/base/commands/jira/build-intake.md +7 -0
  80. package/plugins/src/base/commands/jira/source-artifacts.md +6 -0
  81. package/plugins/src/base/commands/jira/validate-ticket.md +7 -0
  82. package/plugins/src/base/commands/notion-prd-intake.md +7 -0
  83. package/plugins/src/base/commands/prd-ticket-coverage.md +7 -0
  84. package/plugins/src/base/commands/product-walkthrough.md +7 -0
  85. package/plugins/src/base/skills/jira-build-intake/SKILL.md +134 -0
  86. package/plugins/src/base/skills/jira-create/SKILL.md +53 -30
  87. package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +107 -0
  88. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +224 -0
  89. package/plugins/src/base/skills/jira-verify/SKILL.md +15 -91
  90. package/plugins/src/base/skills/jira-write-ticket/SKILL.md +20 -15
  91. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +169 -0
  92. package/plugins/src/base/skills/notion-to-jira/SKILL.md +137 -95
  93. package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +137 -0
  94. package/plugins/src/base/skills/product-walkthrough/SKILL.md +129 -0
  95. package/plugins/src/expo/skills/jira-create/SKILL.md +60 -28
  96. package/plugins/src/expo/skills/jira-verify/SKILL.md +14 -34
  97. package/plugins/src/rails/skills/jira-create/SKILL.md +59 -28
  98. package/plugins/src/rails/skills/jira-verify/SKILL.md +13 -16
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CA4BvC;AAgHD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;AAiD1D;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAiCvC;AA+ID,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/dist/cli/index.js CHANGED
@@ -1,8 +1,10 @@
1
- import { Command } from "commander";
1
+ import { Command, InvalidArgumentError } from "commander";
2
2
  import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { HARNESS_VALUES } from "../core/config.js";
4
5
  import { GitService } from "../core/git-service.js";
5
6
  import { Lisa } from "../core/lisa.js";
7
+ import { isHarness, readProjectConfig, resolveHarness, writeProjectConfig, } from "../core/project-config.js";
6
8
  import { DetectorRegistry } from "../detection/index.js";
7
9
  import { ConsoleLogger } from "../logging/index.js";
8
10
  import { MigrationRegistry } from "../migrations/index.js";
@@ -19,6 +21,20 @@ function getLisaDir() {
19
21
  // Go up from dist/cli to project root
20
22
  return path.resolve(__dirname, "..", "..");
21
23
  }
24
+ /**
25
+ * Validate the --harness CLI argument. Commander invokes this with the raw
26
+ * user-supplied string and expects either the parsed value or a thrown
27
+ * InvalidArgumentError.
28
+ * @param value - Raw argument value
29
+ * @returns The validated harness
30
+ */
31
+ function parseHarnessArg(value) {
32
+ if (!isHarness(value)) {
33
+ const allowed = HARNESS_VALUES.join(" | ");
34
+ throw new InvalidArgumentError(`expected ${allowed}, got ${JSON.stringify(value)}`);
35
+ }
36
+ return value;
37
+ }
22
38
  /**
23
39
  * Create and configure the CLI program
24
40
  * @returns Configured Commander program
@@ -27,13 +43,14 @@ export function createProgram() {
27
43
  const program = new Command();
28
44
  program
29
45
  .name("lisa")
30
- .description("Claude Code governance framework - apply guardrails and guidance to projects")
46
+ .description("Claude Code / Codex CLI governance framework - apply guardrails and guidance to projects")
31
47
  .version("1.0.0")
32
48
  .argument("[destination]", "Path to the project directory")
33
49
  .option("-n, --dry-run", "Show what would be done without making changes")
34
50
  .option("-y, --yes", "Non-interactive mode (auto-accept defaults, overwrite on conflict)")
35
51
  .option("-v, --validate", "Validate project compatibility without applying changes")
36
52
  .option("--skip-git-check", "Skip dirty git working directory check (for postinstall use)")
53
+ .option("--harness <harness>", `Target harness for emitted artifacts: ${HARNESS_VALUES.join(" | ")} (default: claude, or value from .lisa.config.json)`, parseHarnessArg)
37
54
  .action(async (destination, options) => {
38
55
  await runLisa(destination, options);
39
56
  });
@@ -52,13 +69,16 @@ function printUsageAndExit() {
52
69
  console.log(" -y, --yes Non-interactive mode (auto-accept defaults, overwrite on conflict)");
53
70
  console.log(" -v, --validate Validate project compatibility without applying changes");
54
71
  console.log(" --skip-git-check Skip dirty git working directory check (for postinstall use)");
72
+ console.log(` --harness <h> Target harness for emitted artifacts: ${HARNESS_VALUES.join(" | ")} (persisted in .lisa.config.json)`);
55
73
  console.log(" -h, --help Show this help message");
56
74
  console.log("");
57
75
  console.log("Examples:");
58
76
  console.log(" lisa /path/to/my-project");
59
77
  console.log(" lisa --dry-run .");
60
- console.log(" lisa --yes /path/to/project # CI/CD pipeline usage");
61
- console.log(" lisa --validate . # Check compatibility only");
78
+ console.log(" lisa --yes /path/to/project # CI/CD pipeline usage");
79
+ console.log(" lisa --validate . # Check compatibility only");
80
+ console.log(" lisa --harness=codex . # Emit Codex artifacts");
81
+ console.log(" lisa --harness=both . # Emit both Claude and Codex artifacts");
62
82
  process.exit(1);
63
83
  }
64
84
  /**
@@ -93,13 +113,18 @@ async function runLisa(destination, options) {
93
113
  }
94
114
  const dryRun = options.dryRun ?? options.validate ?? false;
95
115
  const yesMode = options.yes ?? false;
116
+ const destDir = toAbsolutePath(destination);
117
+ // Resolve harness with precedence: CLI flag > .lisa.config.json > default
118
+ const projectConfig = await readProjectConfig(destDir);
119
+ const harness = resolveHarness(options.harness, projectConfig);
96
120
  const config = {
97
121
  lisaDir: getLisaDir(),
98
- destDir: toAbsolutePath(destination),
122
+ destDir,
99
123
  dryRun,
100
124
  yesMode,
101
125
  validateOnly: options.validate ?? false,
102
126
  skipGitCheck: options.skipGitCheck ?? false,
127
+ harness,
103
128
  };
104
129
  const logger = new ConsoleLogger();
105
130
  const deps = createDependencies(dryRun, yesMode, logger);
@@ -112,6 +137,17 @@ async function runLisa(destination, options) {
112
137
  result.errors.forEach(error => logger.error(error));
113
138
  process.exit(1);
114
139
  }
140
+ // Persist resolved harness on apply (not validate, not dry-run) so the
141
+ // choice survives to the next run without requiring the flag every time.
142
+ // Only write when the user actually supplied --harness, so existing
143
+ // host projects don't gain a brand-new .lisa.config.json with the
144
+ // default value just by running `lisa` once.
145
+ if (!options.validate &&
146
+ !dryRun &&
147
+ options.harness !== undefined &&
148
+ projectConfig.harness !== harness) {
149
+ await writeProjectConfig(destDir, { harness });
150
+ }
115
151
  }
116
152
  catch (error) {
117
153
  logger.error(error instanceof Error ? error.message : String(error));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /** Subdirectory inside `.codex/agents/` where Lisa-owned agents live */
2
+ export declare const LISA_AGENTS_SUBDIR: string;
3
+ /** Subdirectory inside `.codex/agents/` where host overrides live */
4
+ export declare const HOST_OVERRIDES_SUBDIR: string;
5
+ /** Discovered Lisa agent source */
6
+ export interface AgentSource {
7
+ /** Stable identifier matching the source filename without extension */
8
+ readonly id: string;
9
+ /** Absolute path to the source `.md` file */
10
+ readonly sourcePath: string;
11
+ /** Plugin name the agent ships from (for diagnostics) */
12
+ readonly pluginName: string;
13
+ }
14
+ /** Result of installing one agent */
15
+ export interface InstalledAgent {
16
+ /** Agent id (filename basename) */
17
+ readonly id: string;
18
+ /** Path written, relative to the destination project's `.codex/` directory */
19
+ readonly relativePath: string;
20
+ /** Whether a host override file was applied */
21
+ readonly overrideApplied: boolean;
22
+ }
23
+ /** Aggregated result of an install pass */
24
+ export interface AgentInstallResult {
25
+ readonly installed: readonly InstalledAgent[];
26
+ /** Stale agent files deleted from `.codex/agents/lisa/` (relative to `.codex/`) */
27
+ readonly deleted: readonly string[];
28
+ /** Files written, relative to `.codex/`. Used to update the manifest. */
29
+ readonly managedFiles: readonly string[];
30
+ }
31
+ /**
32
+ * Discover every agent shipped by every Lisa plugin under `lisaDir`.
33
+ *
34
+ * Looks at `<lisaDir>/plugins/<plugin>/agents/*.md`. Skips the
35
+ * `plugins/src/` source tree (which is the build input — we want the built
36
+ * output). De-duplicates by agent id with last-wins semantics: the base `lisa`
37
+ * plugin is always processed first, then remaining plugins in alphabetical
38
+ * order, so any stack-specific plugin (e.g. `lisa-rails`) or third-party
39
+ * plugin overrides the base regardless of how the name sorts.
40
+ * @param lisaDir - Absolute path to the Lisa repo root
41
+ * @returns De-duplicated agent sources, sorted by id
42
+ */
43
+ export declare function discoverLisaAgents(lisaDir: string): Promise<readonly AgentSource[]>;
44
+ /**
45
+ * Install all discovered agents into `<destDir>/.codex/agents/lisa/`.
46
+ *
47
+ * Returns a result describing what was written and what stale files were
48
+ * deleted, so the caller can update the Lisa-managed manifest.
49
+ * @param sources - Agent sources from discoverLisaAgents
50
+ * @param destDir - Absolute path to the destination project root
51
+ * @param previousManagedFiles - Files Lisa managed on the previous run
52
+ * (relative to `.codex/`); used to detect stale agents to delete
53
+ * @returns Result describing installed/deleted/managedFiles
54
+ */
55
+ export declare function installAgents(sources: readonly AgentSource[], destDir: string, previousManagedFiles: readonly string[]): Promise<AgentInstallResult>;
56
+ //# sourceMappingURL=agent-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-installer.d.ts","sourceRoot":"","sources":["../../src/codex/agent-installer.ts"],"names":[],"mappings":"AAuBA,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAE9D,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,QAAwC,CAAC;AAE3E,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AAED,2CAA2C;AAC3C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAuBjC;AAyBD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE,MAAM,EACf,oBAAoB,EAAE,SAAS,MAAM,EAAE,GACtC,OAAO,CAAC,kBAAkB,CAAC,CA2B7B"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Install Lisa-bundled agents into a host project's
3
+ * `.codex/agents/lisa/<name>.toml`.
4
+ *
5
+ * Pipeline per agent:
6
+ * 1. Read the source `.md` from the Lisa plugin
7
+ * 2. Transform Markdown + YAML frontmatter → Codex agent TOML
8
+ * 3. Apply optional host override file from
9
+ * `.codex/agents/host-overrides/<name>.toml` (deep-merge, host wins on
10
+ * key conflicts to satisfy the customization use case)
11
+ * 4. Write the result to `.codex/agents/lisa/<name>.toml`
12
+ *
13
+ * Stale agents (in the previous manifest but no longer shipped by Lisa) are
14
+ * deleted from `.codex/agents/lisa/` so renames in the source tree don't
15
+ * leave orphans behind.
16
+ * @module codex/agent-installer
17
+ */
18
+ import * as fse from "fs-extra";
19
+ import { readFile, readdir, unlink, writeFile } from "node:fs/promises";
20
+ import * as path from "node:path";
21
+ import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
22
+ import { transformAgentMarkdownToToml } from "./agent-transformer.js";
23
+ /** Subdirectory inside `.codex/agents/` where Lisa-owned agents live */
24
+ export const LISA_AGENTS_SUBDIR = path.join("agents", "lisa");
25
+ /** Subdirectory inside `.codex/agents/` where host overrides live */
26
+ export const HOST_OVERRIDES_SUBDIR = path.join("agents", "host-overrides");
27
+ /**
28
+ * Discover every agent shipped by every Lisa plugin under `lisaDir`.
29
+ *
30
+ * Looks at `<lisaDir>/plugins/<plugin>/agents/*.md`. Skips the
31
+ * `plugins/src/` source tree (which is the build input — we want the built
32
+ * output). De-duplicates by agent id with last-wins semantics: the base `lisa`
33
+ * plugin is always processed first, then remaining plugins in alphabetical
34
+ * order, so any stack-specific plugin (e.g. `lisa-rails`) or third-party
35
+ * plugin overrides the base regardless of how the name sorts.
36
+ * @param lisaDir - Absolute path to the Lisa repo root
37
+ * @returns De-duplicated agent sources, sorted by id
38
+ */
39
+ export async function discoverLisaAgents(lisaDir) {
40
+ const pluginsDir = path.join(lisaDir, "plugins");
41
+ if (!(await fse.pathExists(pluginsDir))) {
42
+ return [];
43
+ }
44
+ // Put the base "lisa" plugin first so it is always overridable by any
45
+ // other plugin via last-wins Map dedup below. Remaining plugins are
46
+ // sorted for deterministic ordering across machines.
47
+ const all = (await readdir(pluginsDir)).filter(name => name !== "src");
48
+ const plugins = [
49
+ ...all.filter(n => n === "lisa"),
50
+ ...all.filter(n => n !== "lisa").sort((a, b) => a.localeCompare(b)),
51
+ ];
52
+ const candidatesByPlugin = await Promise.all(plugins.map(pluginName => discoverAgentsInPlugin(pluginsDir, pluginName)));
53
+ // Base-first iteration order + last-wins Map → stack-specific (and any
54
+ // other non-base plugin) overrides base for duplicate agent ids.
55
+ const flat = candidatesByPlugin.flat();
56
+ const deduped = Array.from(new Map(flat.map(source => [source.id, source])).values());
57
+ return Object.freeze([...deduped].sort((a, b) => a.id.localeCompare(b.id)));
58
+ }
59
+ /**
60
+ * List every `.md` file under one plugin's `agents/` directory and turn each
61
+ * into an AgentSource. Returns [] if the plugin has no agents directory.
62
+ * @param pluginsDir - Absolute path to `<lisaDir>/plugins`
63
+ * @param pluginName - Plugin directory name (e.g. "lisa", "lisa-rails")
64
+ * @returns Agent sources discovered in this plugin (file order)
65
+ */
66
+ async function discoverAgentsInPlugin(pluginsDir, pluginName) {
67
+ const agentsDir = path.join(pluginsDir, pluginName, "agents");
68
+ if (!(await fse.pathExists(agentsDir))) {
69
+ return [];
70
+ }
71
+ const files = (await readdir(agentsDir)).filter(f => f.endsWith(".md"));
72
+ return files.map(file => ({
73
+ id: file.replace(/\.md$/, ""),
74
+ sourcePath: path.join(agentsDir, file),
75
+ pluginName,
76
+ }));
77
+ }
78
+ /**
79
+ * Install all discovered agents into `<destDir>/.codex/agents/lisa/`.
80
+ *
81
+ * Returns a result describing what was written and what stale files were
82
+ * deleted, so the caller can update the Lisa-managed manifest.
83
+ * @param sources - Agent sources from discoverLisaAgents
84
+ * @param destDir - Absolute path to the destination project root
85
+ * @param previousManagedFiles - Files Lisa managed on the previous run
86
+ * (relative to `.codex/`); used to detect stale agents to delete
87
+ * @returns Result describing installed/deleted/managedFiles
88
+ */
89
+ export async function installAgents(sources, destDir, previousManagedFiles) {
90
+ const lisaAgentsDir = path.join(destDir, ".codex", LISA_AGENTS_SUBDIR);
91
+ const overridesDir = path.join(destDir, ".codex", HOST_OVERRIDES_SUBDIR);
92
+ await fse.ensureDir(lisaAgentsDir);
93
+ // Each install is independent — run them sequentially to keep filesystem
94
+ // ordering deterministic for snapshot tests, but build the result list
95
+ // immutably via map (no .push).
96
+ const installed = await sequentialMap(sources, source => installSingleAgent(source, lisaAgentsDir, overridesDir));
97
+ const managedFiles = installed.map(agent => agent.relativePath);
98
+ const deleted = await deleteStaleAgents(previousManagedFiles, managedFiles, destDir);
99
+ return {
100
+ installed: Object.freeze(installed),
101
+ deleted: Object.freeze(deleted),
102
+ managedFiles: Object.freeze(managedFiles),
103
+ };
104
+ }
105
+ /**
106
+ * Map an async function over an array sequentially (one at a time), so
107
+ * filesystem operations don't race. Equivalent to a for-await loop that
108
+ * returns the accumulated results without mutating an interim array.
109
+ * @param items - Input items
110
+ * @param fn - Async transform applied to each item in turn
111
+ * @returns The transformed values in input order
112
+ */
113
+ async function sequentialMap(items, fn) {
114
+ return items.reduce(async (accPromise, item) => [...(await accPromise), await fn(item)], Promise.resolve([]));
115
+ }
116
+ /**
117
+ * Transform + (optionally) merge override + write a single agent file.
118
+ * @param source - Discovered agent source (id, plugin, source path)
119
+ * @param lisaAgentsDir - Absolute path to `.codex/agents/lisa/` in the host
120
+ * @param overridesDir - Absolute path to `.codex/agents/host-overrides/`
121
+ * @returns Result describing the installed file (path, override applied?)
122
+ */
123
+ async function installSingleAgent(source, lisaAgentsDir, overridesDir) {
124
+ const sourceContent = await readFile(source.sourcePath, "utf8");
125
+ const baseToml = transformAgentMarkdownToToml(sourceContent);
126
+ const overridePath = path.join(overridesDir, `${source.id}.toml`);
127
+ const hasOverride = await fse.pathExists(overridePath);
128
+ const finalToml = hasOverride
129
+ ? await mergeOverride(baseToml, overridePath)
130
+ : baseToml;
131
+ const destFile = path.join(lisaAgentsDir, `${source.id}.toml`);
132
+ await writeFile(destFile, finalToml, "utf8");
133
+ return {
134
+ id: source.id,
135
+ relativePath: path.join(LISA_AGENTS_SUBDIR, `${source.id}.toml`),
136
+ overrideApplied: hasOverride,
137
+ };
138
+ }
139
+ /**
140
+ * Deep-merge a host override TOML on top of Lisa's generated TOML.
141
+ *
142
+ * Host wins on key conflicts. Used so a host can swap `sandbox_mode`,
143
+ * tweak `description`, or extend `nickname_candidates` for a Lisa agent
144
+ * without forking the agent definition.
145
+ * @param baseToml - Lisa-generated TOML to use as the base
146
+ * @param overridePath - Absolute path to the host's override TOML file
147
+ * @returns The merged TOML serialized back to a string
148
+ */
149
+ async function mergeOverride(baseToml, overridePath) {
150
+ const overrideContent = await readFile(overridePath, "utf8");
151
+ const base = parseToml(baseToml);
152
+ const override = parseToml(overrideContent);
153
+ const merged = deepMerge(base, override);
154
+ return `${stringifyToml(merged)}\n`;
155
+ }
156
+ /**
157
+ * Recursive object merge with override-wins semantics. Arrays are replaced
158
+ * (not concatenated) to keep behavior predictable.
159
+ * @param base - Lower-precedence object (Lisa-generated TOML, parsed)
160
+ * @param override - Higher-precedence object (host override, parsed)
161
+ * @returns A new merged record (input objects are not modified)
162
+ */
163
+ function deepMerge(base, override) {
164
+ return Object.entries(override).reduce((acc, [key, value]) => {
165
+ const baseValue = acc[key];
166
+ const bothMergeableObjects = value !== null &&
167
+ typeof value === "object" &&
168
+ !Array.isArray(value) &&
169
+ baseValue !== null &&
170
+ typeof baseValue === "object" &&
171
+ !Array.isArray(baseValue);
172
+ const nextValue = bothMergeableObjects
173
+ ? deepMerge(baseValue, value)
174
+ : value;
175
+ return { ...acc, [key]: nextValue };
176
+ }, { ...base });
177
+ }
178
+ /**
179
+ * Delete files that were Lisa-managed last run but aren't shipped this run.
180
+ * Only deletes files inside `.codex/agents/lisa/` to avoid touching anything
181
+ * the host might be relying on.
182
+ * @param previousManagedFiles - Files Lisa managed on the previous run
183
+ * (relative to `.codex/`)
184
+ * @param currentManagedFiles - Files Lisa is shipping this run (relative
185
+ * to `.codex/`)
186
+ * @param destDir - Absolute path to the host project root
187
+ * @returns The list of relative paths that were deleted
188
+ */
189
+ async function deleteStaleAgents(previousManagedFiles, currentManagedFiles, destDir) {
190
+ const currentSet = new Set(currentManagedFiles);
191
+ const lisaAgentsPrefix = `${LISA_AGENTS_SUBDIR}${path.sep}`;
192
+ const stale = previousManagedFiles.filter(file => !currentSet.has(file) && file.startsWith(lisaAgentsPrefix));
193
+ await Promise.all(stale.map(async (file) => {
194
+ const absPath = path.join(destDir, ".codex", file);
195
+ if (await fse.pathExists(absPath)) {
196
+ await unlink(absPath);
197
+ }
198
+ }));
199
+ return Object.freeze(stale);
200
+ }
201
+ //# sourceMappingURL=agent-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-installer.js","sourceRoot":"","sources":["../../src/codex/agent-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Prefix applied to every Lisa-owned Codex agent name. Provides
3
+ * defense-in-depth on top of the directory-based ownership boundary
4
+ * (`.codex/agents/lisa/`); makes it unambiguous in transcripts/logs which
5
+ * agents Lisa manages.
6
+ */
7
+ export declare const LISA_AGENT_NAME_PREFIX = "lisa-";
8
+ /** Keys recognized in Lisa agent YAML frontmatter */
9
+ interface AgentFrontmatter {
10
+ readonly name: string;
11
+ readonly description: string;
12
+ readonly tools?: string;
13
+ readonly model?: string;
14
+ readonly skills?: readonly string[];
15
+ }
16
+ /** Result of parsing a Lisa agent Markdown file */
17
+ export interface ParsedAgent {
18
+ readonly frontmatter: AgentFrontmatter;
19
+ readonly body: string;
20
+ }
21
+ /** Options controlling TOML emission */
22
+ export interface AgentTransformOptions {
23
+ /**
24
+ * Whether to apply the `lisa-` name prefix. Defaults to true; set false for
25
+ * tests or for agents the consumer wants to expose without a Lisa namespace.
26
+ */
27
+ readonly applyNamePrefix?: boolean;
28
+ }
29
+ /**
30
+ * Parse a Lisa agent Markdown source string into frontmatter + body.
31
+ *
32
+ * Throws on missing/malformed frontmatter or missing required fields, since
33
+ * these would silently produce broken Codex agent files otherwise.
34
+ * @param source - Raw contents of an agent .md file
35
+ * @returns Parsed frontmatter and body
36
+ */
37
+ export declare function parseAgentMarkdown(source: string): ParsedAgent;
38
+ /**
39
+ * Transform a parsed agent into the Codex TOML representation as a string.
40
+ * @param parsed - Output of parseAgentMarkdown
41
+ * @param options - Transform options
42
+ * @returns Serialized TOML matching Codex's `RawAgentRoleFileToml` schema
43
+ */
44
+ export declare function transformAgentToToml(parsed: ParsedAgent, options?: AgentTransformOptions): string;
45
+ /**
46
+ * One-shot helper: parse + transform.
47
+ * @param source - Raw contents of an agent .md file
48
+ * @param options - Transform options
49
+ * @returns Serialized Codex agent TOML
50
+ */
51
+ export declare function transformAgentMarkdownToToml(source: string, options?: AgentTransformOptions): string;
52
+ export {};
53
+ //# sourceMappingURL=agent-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-transformer.d.ts","sourceRoot":"","sources":["../../src/codex/agent-transformer.ts"],"names":[],"mappings":"AAiCA;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C,qDAAqD;AACrD,UAAU,gBAAgB;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAY9D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAcR;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAER"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Transform a Claude Code-style agent definition (Markdown with YAML
3
+ * frontmatter) into a Codex CLI agent role TOML file.
4
+ *
5
+ * Claude Code agent shape:
6
+ * ```
7
+ * ---
8
+ * name: bug-fixer
9
+ * description: ...
10
+ * tools: Read, Bash # optional; ignored on the Codex side
11
+ * model: sonnet # optional; mapped if present
12
+ * skills: [skill-a, skill-b] # optional; preserved in body as context
13
+ * ---
14
+ * # Body becomes developer_instructions
15
+ * ```
16
+ *
17
+ * Codex agent shape (per `RawAgentRoleFileToml`, see
18
+ * https://github.com/openai/codex/blob/main/codex-rs/core/src/config/agent_roles.rs):
19
+ * ```toml
20
+ * name = "lisa-bug-fixer"
21
+ * description = "..."
22
+ * developer_instructions = """
23
+ * # Body...
24
+ * """
25
+ * ```
26
+ *
27
+ * The Codex deserializer rejects unknown top-level fields
28
+ * (`#[serde(deny_unknown_fields)]`), so this transformer emits ONLY keys that
29
+ * Codex's loader accepts.
30
+ * @module codex/agent-transformer
31
+ */
32
+ import yaml from "js-yaml";
33
+ /**
34
+ * Prefix applied to every Lisa-owned Codex agent name. Provides
35
+ * defense-in-depth on top of the directory-based ownership boundary
36
+ * (`.codex/agents/lisa/`); makes it unambiguous in transcripts/logs which
37
+ * agents Lisa manages.
38
+ */
39
+ export const LISA_AGENT_NAME_PREFIX = "lisa-";
40
+ /**
41
+ * Parse a Lisa agent Markdown source string into frontmatter + body.
42
+ *
43
+ * Throws on missing/malformed frontmatter or missing required fields, since
44
+ * these would silently produce broken Codex agent files otherwise.
45
+ * @param source - Raw contents of an agent .md file
46
+ * @returns Parsed frontmatter and body
47
+ */
48
+ export function parseAgentMarkdown(source) {
49
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(source);
50
+ if (match === null || match[1] === undefined || match[2] === undefined) {
51
+ throw new Error("Agent markdown is missing YAML frontmatter (expected leading --- block)");
52
+ }
53
+ const rawFrontmatter = match[1];
54
+ const rawBody = match[2];
55
+ const parsed = yaml.load(rawFrontmatter);
56
+ const frontmatter = validateFrontmatter(parsed);
57
+ return { frontmatter, body: rawBody.trimStart() };
58
+ }
59
+ /**
60
+ * Transform a parsed agent into the Codex TOML representation as a string.
61
+ * @param parsed - Output of parseAgentMarkdown
62
+ * @param options - Transform options
63
+ * @returns Serialized TOML matching Codex's `RawAgentRoleFileToml` schema
64
+ */
65
+ export function transformAgentToToml(parsed, options = {}) {
66
+ const applyPrefix = options.applyNamePrefix ?? true;
67
+ const baseName = parsed.frontmatter.name;
68
+ const codexName = applyPrefix
69
+ ? `${LISA_AGENT_NAME_PREFIX}${baseName}`
70
+ : baseName;
71
+ const developerInstructions = composeDeveloperInstructions(parsed);
72
+ const lines = [
73
+ `name = ${tomlString(codexName)}`,
74
+ `description = ${tomlString(parsed.frontmatter.description)}`,
75
+ `developer_instructions = ${tomlMultilineString(developerInstructions)}`,
76
+ ];
77
+ return `${lines.join("\n")}\n`;
78
+ }
79
+ /**
80
+ * One-shot helper: parse + transform.
81
+ * @param source - Raw contents of an agent .md file
82
+ * @param options - Transform options
83
+ * @returns Serialized Codex agent TOML
84
+ */
85
+ export function transformAgentMarkdownToToml(source, options = {}) {
86
+ return transformAgentToToml(parseAgentMarkdown(source), options);
87
+ }
88
+ /**
89
+ * Build the `developer_instructions` body. Claude Code agents sometimes
90
+ * carry `skills:` in frontmatter that act as soft guidance; we surface that
91
+ * as a header in the instructions so the Codex agent has the same context.
92
+ * @param parsed - Output of parseAgentMarkdown for the source agent file
93
+ * @returns The composed body to write into `developer_instructions`
94
+ */
95
+ function composeDeveloperInstructions(parsed) {
96
+ const skills = parsed.frontmatter.skills;
97
+ if (skills === undefined || skills.length === 0) {
98
+ return parsed.body.trimEnd();
99
+ }
100
+ const skillsBlock = [
101
+ "## Available Lisa Skills",
102
+ "",
103
+ "This agent operates in a Lisa-managed Codex environment with access to the following skills:",
104
+ "",
105
+ ...skills.map(s => `- ${s}`),
106
+ "",
107
+ ].join("\n");
108
+ return `${skillsBlock}\n${parsed.body.trimEnd()}`;
109
+ }
110
+ /**
111
+ * Validate frontmatter shape, throwing on missing required fields or wrong
112
+ * types. Unknown fields are ignored to allow Lisa agents to carry harness-
113
+ * specific keys without breaking the transformer.
114
+ * @param parsed - Untrusted YAML mapping parsed from the agent's frontmatter
115
+ * @returns The validated frontmatter with only the keys we recognize
116
+ */
117
+ function validateFrontmatter(parsed) {
118
+ if (parsed === null || typeof parsed !== "object") {
119
+ throw new Error("Agent frontmatter must be a YAML mapping");
120
+ }
121
+ const obj = parsed;
122
+ if (typeof obj.name !== "string" || obj.name.trim().length === 0) {
123
+ throw new Error('Agent frontmatter is missing required "name" field');
124
+ }
125
+ if (typeof obj.description !== "string" ||
126
+ obj.description.trim().length === 0) {
127
+ throw new Error('Agent frontmatter is missing required "description" field');
128
+ }
129
+ const skills = parseSkills(obj.skills);
130
+ return {
131
+ name: obj.name,
132
+ description: obj.description,
133
+ ...(typeof obj.tools === "string" ? { tools: obj.tools } : {}),
134
+ ...(typeof obj.model === "string" ? { model: obj.model } : {}),
135
+ ...(skills !== undefined ? { skills } : {}),
136
+ };
137
+ }
138
+ /**
139
+ * Coerce the `skills` frontmatter field into a string array, or undefined.
140
+ * @param raw - Untrusted value from the `skills` key (may be missing/wrong type)
141
+ * @returns A frozen string array, or undefined if absent/empty
142
+ */
143
+ function parseSkills(raw) {
144
+ if (!Array.isArray(raw)) {
145
+ return undefined;
146
+ }
147
+ const filtered = raw.filter((entry) => typeof entry === "string" && entry.length > 0);
148
+ return filtered.length > 0 ? Object.freeze(filtered) : undefined;
149
+ }
150
+ /**
151
+ * Emit a TOML basic string with proper escaping. Uses double-quoted form so
152
+ * we can rely on standard escape sequences without worrying about literal
153
+ * (single-quoted) string limitations.
154
+ * @param value - The raw string to encode as a TOML basic string
155
+ * @returns The encoded string including surrounding double quotes
156
+ */
157
+ function tomlString(value) {
158
+ const escaped = value
159
+ .replaceAll("\\", "\\\\")
160
+ .replaceAll('"', '\\"')
161
+ .replaceAll("\n", "\\n")
162
+ .replaceAll("\r", "\\r")
163
+ .replaceAll("\t", "\\t");
164
+ return `"${escaped}"`;
165
+ }
166
+ /**
167
+ * Emit a TOML multi-line basic string, preserving newlines verbatim. The
168
+ * leading newline after `"""` is part of TOML grammar — it is stripped by
169
+ * the parser so authoring stays clean.
170
+ *
171
+ * Edge case: Markdown bodies sometimes contain literal `"""` (e.g., Python
172
+ * docstring examples). We escape any closing triple-quote sequence by
173
+ * inserting a backslash before the third quote.
174
+ * @param value - The raw multi-line content to encode
175
+ * @returns The encoded TOML multi-line string including surrounding triple-quotes
176
+ */
177
+ function tomlMultilineString(value) {
178
+ const escaped = value.replaceAll("\\", "\\\\").replaceAll('"""', '""\\"');
179
+ return `"""\n${escaped}\n"""`;
180
+ }
181
+ //# sourceMappingURL=agent-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-transformer.js","sourceRoot":"","sources":["../../src/codex/agent-transformer.ts"],"names":[],"mappings":"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"}