@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
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,
|
|
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
|
|
61
|
-
console.log(" lisa --validate .
|
|
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
|
|
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));
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
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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"}
|