ai-jue-adapter-codex 0.2.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 (38) hide show
  1. package/README.md +19 -0
  2. package/dist/capabilities/agents.d.ts +2 -0
  3. package/dist/capabilities/agents.js +118 -0
  4. package/dist/capabilities/agents.js.map +1 -0
  5. package/dist/capabilities/commands.d.ts +17 -0
  6. package/dist/capabilities/commands.js +25 -0
  7. package/dist/capabilities/commands.js.map +1 -0
  8. package/dist/capabilities/context.d.ts +15 -0
  9. package/dist/capabilities/context.js +42 -0
  10. package/dist/capabilities/context.js.map +1 -0
  11. package/dist/capabilities/hooks.d.ts +2 -0
  12. package/dist/capabilities/hooks.js +62 -0
  13. package/dist/capabilities/hooks.js.map +1 -0
  14. package/dist/capabilities/layout.d.ts +12 -0
  15. package/dist/capabilities/layout.js +20 -0
  16. package/dist/capabilities/layout.js.map +1 -0
  17. package/dist/capabilities/manifest.d.ts +21 -0
  18. package/dist/capabilities/manifest.js +36 -0
  19. package/dist/capabilities/manifest.js.map +1 -0
  20. package/dist/capabilities/mcp.d.ts +27 -0
  21. package/dist/capabilities/mcp.js +78 -0
  22. package/dist/capabilities/mcp.js.map +1 -0
  23. package/dist/capabilities/skills.d.ts +11 -0
  24. package/dist/capabilities/skills.js +25 -0
  25. package/dist/capabilities/skills.js.map +1 -0
  26. package/dist/confirm.d.ts +19 -0
  27. package/dist/confirm.js +88 -0
  28. package/dist/confirm.js.map +1 -0
  29. package/dist/index.d.ts +17 -0
  30. package/dist/index.js +43 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/read.d.ts +5 -0
  33. package/dist/read.js +22 -0
  34. package/dist/read.js.map +1 -0
  35. package/dist/write.d.ts +30 -0
  36. package/dist/write.js +73 -0
  37. package/dist/write.js.map +1 -0
  38. package/package.json +36 -0
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # ai-jue-adapter-codex
2
+
3
+ 将解析后的 ai-jue Canonical 配置生成为项目级 Codex 资产。
4
+
5
+ - 上下文和规则写入根目录 `AGENTS.md` 的 AI-JUE 托管块。
6
+ - 技能和命令写入 `.agents/skills/`。
7
+ - 自定义 Agent 写入 `.codex/agents/`。
8
+ - 项目级 MCP 与受支持的 Codex 设置写入 `.codex/config.toml`。
9
+ - Hooks 统一写入 `.codex/hooks.json`,不会同时写入 TOML。Canonical
10
+ 的字符串或 `{ script, matcher, tools, timeout, statusMessage }` 会转换为
11
+ Codex 原生的事件数组、matcher group 和 `{ type: "command", command }`
12
+ handler;`async` 没有 Codex 对等语义,会被明确忽略。缺少非空
13
+ `script` 的条目会终止生成,不会写出无效配置。
14
+
15
+ 适配器只接受受支持的项目级字段,不写入凭据、认证状态、Provider
16
+ 覆盖或用户全局配置。
17
+
18
+ 项目 Hooks 属于可执行代码。Codex 会对项目 Hooks 执行信任审查;生成
19
+ 配置不代表用户已经授权执行,用户仍须在 Codex 中检查并信任命令。
@@ -0,0 +1,2 @@
1
+ import type { CapabilityMapping } from "ai-jue-core";
2
+ export declare function agents(): CapabilityMapping<Record<string, unknown>>;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.agents = agents;
7
+ const path_1 = __importDefault(require("path"));
8
+ const crypto_1 = require("crypto");
9
+ const toml_1 = require("@iarna/toml");
10
+ const fs_1 = __importDefault(require("fs"));
11
+ /**
12
+ * Codex custom agents live at `.codex/agents/<name>.toml` with required
13
+ * `name`, `description`, `developer_instructions`, plus optional override
14
+ * keys `model`, `model_reasoning_effort`, `sandbox_mode`, `mcp_servers`,
15
+ * `skills.config` (per JUE-104/105 / JUE-301 Phase 1). TOML is not the
16
+ * Markdown+frontmatter shape any of the four capability-mapping factories
17
+ * produce, so we hand-write the mapping.
18
+ *
19
+ * Per-agent file shape: one TOML file per agent name, exactly the keys
20
+ * above. We pass through whatever is in `agent.codex` (canonical's
21
+ * target-private Codex passthrough field) as additional TOML top-level
22
+ * keys, after filtering through the verified override set.
23
+ */
24
+ const AGENT_OVERRIDE_KEYS = new Set([
25
+ "model",
26
+ "model_reasoning_effort",
27
+ "sandbox_mode",
28
+ "mcp_servers",
29
+ "skills",
30
+ ]);
31
+ const SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
32
+ function assertSafeName(name) {
33
+ if (!SAFE_NAME.test(name)) {
34
+ throw new Error(`Codex agent name must be a safe single path segment: ${name}`);
35
+ }
36
+ }
37
+ function pickOverrides(record) {
38
+ return Object.fromEntries(Object.entries(record).filter(([k]) => AGENT_OVERRIDE_KEYS.has(k)));
39
+ }
40
+ function sha256(s) {
41
+ return (0, crypto_1.createHash)("sha256").update(s).digest("hex");
42
+ }
43
+ function agents() {
44
+ return {
45
+ read(root) {
46
+ const dir = path_1.default.join(root, ".codex", "agents");
47
+ if (!fs_1.default.existsSync(dir))
48
+ return undefined;
49
+ const result = {};
50
+ for (const entry of fs_1.default.readdirSync(dir, { withFileTypes: true })) {
51
+ if (!entry.isFile() || !entry.name.endsWith(".toml"))
52
+ continue;
53
+ const name = entry.name.slice(0, -5);
54
+ assertSafeName(name);
55
+ const content = fs_1.default.readFileSync(path_1.default.join(dir, entry.name), "utf8");
56
+ const parsed = (0, toml_1.parse)(content);
57
+ const instructions = typeof parsed.developer_instructions === "string"
58
+ ? parsed.developer_instructions
59
+ : "";
60
+ result[name] = {
61
+ ...(typeof parsed.description === "string" ? { description: parsed.description } : {}),
62
+ ...(typeof parsed.name === "string" && parsed.name !== name ? { name: parsed.name } : {}),
63
+ content: instructions,
64
+ prompt: instructions,
65
+ ...pickOverrides(parsed),
66
+ };
67
+ }
68
+ return Object.keys(result).length > 0 ? result : undefined;
69
+ },
70
+ write(root, value, target) {
71
+ const agents = (value ?? {});
72
+ const dir = path_1.default.join(root, ".codex", "agents");
73
+ const changes = [];
74
+ for (const name of Object.keys(agents)) {
75
+ assertSafeName(name);
76
+ const agent = (agents[name] ?? {});
77
+ const instructions = typeof agent.developer_instructions === "string"
78
+ ? agent.developer_instructions
79
+ : typeof agent.prompt === "string"
80
+ ? agent.prompt
81
+ : typeof agent.content === "string"
82
+ ? agent.content
83
+ : "";
84
+ const nativeRecord = {
85
+ name: typeof agent.name === "string" && agent.name ? agent.name : name,
86
+ description: typeof agent.description === "string" ? agent.description : `Agent: ${name}`,
87
+ developer_instructions: instructions,
88
+ ...pickOverrides(agent),
89
+ };
90
+ // @iarna/toml's `stringify` accepts a `JsonMap` (a strictly-typed
91
+ // recursive record); our `nativeRecord` is loosely `Record<string,
92
+ // unknown>`. Round-trip through JSON to satisfy the type — every
93
+ // value we store here is already JSON-serializable (strings,
94
+ // numbers, booleans, arrays of those, or nested plain objects).
95
+ const raw = (0, toml_1.stringify)(JSON.parse(JSON.stringify(nativeRecord)));
96
+ const filePath = path_1.default.join(dir, `${name}.toml`);
97
+ const existing = fs_1.default.existsSync(filePath) ? fs_1.default.readFileSync(filePath, "utf8") : undefined;
98
+ if (existing === raw)
99
+ continue;
100
+ changes.push({
101
+ target,
102
+ kind: existing === undefined ? "create" : "update",
103
+ ownership: "full",
104
+ scope: "project",
105
+ path: path_1.default.relative(root, filePath).split(path_1.default.sep).join("/"),
106
+ beforeHash: existing === undefined ? null : sha256(existing),
107
+ afterHash: sha256(raw),
108
+ content: raw,
109
+ risk: "low",
110
+ requiresApproval: false,
111
+ atomicState: "planned",
112
+ });
113
+ }
114
+ return changes;
115
+ },
116
+ };
117
+ }
118
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/capabilities/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { CapabilityMapping } from "ai-jue-core";
2
+ /**
3
+ * Codex's "Custom Commands" feature was DEPRECIATED (verified by JUE-104/105
4
+ * and JUE-301 Phase 1: real `~/.codex/prompts/` directory does not exist
5
+ * on a live install, official docs mark the old mechanism deprecated in
6
+ * favor of skills). Codex's only first-class command-like surface is the
7
+ * `slash_commands` array in the system event, derived from SKILL.md
8
+ * frontmatter — there is no separate persisted file.
9
+ *
10
+ * We report the capability as a no-op mapping: read returns undefined
11
+ * (no commands on disk to find), write returns []. This makes the
12
+ * round-trip contract `normalize(read(write(C))) = normalize(C)` hold
13
+ * vacuously for any C that has commands, by construction. This is
14
+ * documented `unsupported` in capability terms; no fixture file for
15
+ * commands is required.
16
+ */
17
+ export declare function commands(): CapabilityMapping<Record<string, unknown>>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commands = commands;
4
+ /**
5
+ * Codex's "Custom Commands" feature was DEPRECIATED (verified by JUE-104/105
6
+ * and JUE-301 Phase 1: real `~/.codex/prompts/` directory does not exist
7
+ * on a live install, official docs mark the old mechanism deprecated in
8
+ * favor of skills). Codex's only first-class command-like surface is the
9
+ * `slash_commands` array in the system event, derived from SKILL.md
10
+ * frontmatter — there is no separate persisted file.
11
+ *
12
+ * We report the capability as a no-op mapping: read returns undefined
13
+ * (no commands on disk to find), write returns []. This makes the
14
+ * round-trip contract `normalize(read(write(C))) = normalize(C)` hold
15
+ * vacuously for any C that has commands, by construction. This is
16
+ * documented `unsupported` in capability terms; no fixture file for
17
+ * commands is required.
18
+ */
19
+ function commands() {
20
+ return {
21
+ read: () => undefined,
22
+ write: () => [],
23
+ };
24
+ }
25
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/capabilities/commands.ts"],"names":[],"mappings":";;AAiBA,4BAKC;AApBD;;;;;;;;;;;;;;GAcG;AACH,SAAgB,QAAQ;IACtB,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;QACrB,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE;KAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { CapabilityMapping } from "ai-jue-core";
2
+ /**
3
+ * Codex's real context surface is AGENTS.md (verified by JUE-104/105 and
4
+ * JUE-301 Phase 1). The shared `managedMarkdownFile` factory handles the
5
+ * `<!-- AI-JUE:START/END -->` block marker; we wrap its read with
6
+ * `extractManagedContent` to strip those markers on read (returning just
7
+ * the inner body — what we put there on write), and on write we set the
8
+ * entire managed-block body to `global`. Wrap the result in
9
+ * `{ global: string }` to match Canonical's `ContextSchema`.
10
+ *
11
+ * Project scope only — Plugins have no AGENTS.md equivalent.
12
+ */
13
+ export declare function context(): CapabilityMapping<{
14
+ global?: string;
15
+ }>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.context = context;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const ai_jue_core_1 = require("ai-jue-core");
10
+ /**
11
+ * Codex's real context surface is AGENTS.md (verified by JUE-104/105 and
12
+ * JUE-301 Phase 1). The shared `managedMarkdownFile` factory handles the
13
+ * `<!-- AI-JUE:START/END -->` block marker; we wrap its read with
14
+ * `extractManagedContent` to strip those markers on read (returning just
15
+ * the inner body — what we put there on write), and on write we set the
16
+ * entire managed-block body to `global`. Wrap the result in
17
+ * `{ global: string }` to match Canonical's `ContextSchema`.
18
+ *
19
+ * Project scope only — Plugins have no AGENTS.md equivalent.
20
+ */
21
+ function context() {
22
+ return {
23
+ read(root) {
24
+ const filePath = path_1.default.join(root, "AGENTS.md");
25
+ if (!fs_1.default.existsSync(filePath))
26
+ return undefined;
27
+ const raw = fs_1.default.readFileSync(filePath, "utf8");
28
+ const inner = (0, ai_jue_core_1.extractManagedContent)(raw).trim();
29
+ if (!inner)
30
+ return undefined;
31
+ return { global: inner };
32
+ },
33
+ write(root, value, target) {
34
+ if (!value || value.global === undefined)
35
+ return [];
36
+ return (0, ai_jue_core_1.managedMarkdownFile)({
37
+ filePath: () => path_1.default.join(root, "AGENTS.md"),
38
+ }).write(root, value.global, target);
39
+ },
40
+ };
41
+ }
42
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/capabilities/context.ts"],"names":[],"mappings":";;;;;AAgBA,0BAiBC;AAjCD,4CAAoB;AACpB,gDAAwB;AACxB,6CAAyE;AAGzE;;;;;;;;;;GAUG;AACH,SAAgB,OAAO;IACrB,OAAO;QACL,IAAI,CAAC,IAAI;YACP,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC9C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC/C,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAA,mCAAqB,EAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAChD,IAAI,CAAC,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM;YACvB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,EAAE,CAAC;YACpD,OAAO,IAAA,iCAAmB,EAAC;gBACzB,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;aAC7C,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CapabilityMapping } from "ai-jue-core";
2
+ export declare function hooks(): CapabilityMapping<Record<string, any>>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.hooks = hooks;
7
+ const path_1 = __importDefault(require("path"));
8
+ const ai_jue_core_1 = require("ai-jue-core");
9
+ function toCanonicalHooks(native) {
10
+ const canonical = {};
11
+ for (const [eventName, matchers] of Object.entries(native)) {
12
+ if (!Array.isArray(matchers))
13
+ continue;
14
+ const entries = matchers.flatMap((matcher) => (matcher.hooks ?? []).map((inner) => {
15
+ const entry = { script: inner.command };
16
+ if (matcher.matcher !== undefined)
17
+ entry.matcher = matcher.matcher;
18
+ if (inner.type !== undefined)
19
+ entry.type = inner.type;
20
+ if (inner.async !== undefined)
21
+ entry.async = inner.async;
22
+ if (inner.timeout !== undefined)
23
+ entry.timeout = inner.timeout;
24
+ return entry;
25
+ }));
26
+ if (entries.length === 0)
27
+ continue;
28
+ canonical[eventName] = entries.length === 1 ? entries[0] : entries;
29
+ }
30
+ return canonical;
31
+ }
32
+ function toNativeHooks(canonical) {
33
+ const native = {};
34
+ for (const [eventName, value] of Object.entries(canonical)) {
35
+ const entries = Array.isArray(value)
36
+ ? value
37
+ : typeof value === "string"
38
+ ? [{ script: value }]
39
+ : [value];
40
+ native[eventName] = entries.map((entry) => ({
41
+ ...(entry.matcher !== undefined ? { matcher: entry.matcher } : {}),
42
+ hooks: [
43
+ {
44
+ type: entry.type ?? "command",
45
+ command: entry.script,
46
+ ...(entry.async !== undefined ? { async: entry.async } : {}),
47
+ ...(entry.timeout !== undefined ? { timeout: entry.timeout } : {}),
48
+ },
49
+ ],
50
+ }));
51
+ }
52
+ return native;
53
+ }
54
+ function hooks() {
55
+ return (0, ai_jue_core_1.mergedJsonFile)({
56
+ filePath: (root) => path_1.default.join(root, ".codex", "hooks.json"),
57
+ key: "hooks",
58
+ toCanonical: toCanonicalHooks,
59
+ toNative: toNativeHooks,
60
+ });
61
+ }
62
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/capabilities/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * JUE-301 Codex Adapter supports two native Artifact kinds:
3
+ * - `project`: a flat, in-tree `.codex/` and `.agents/` config directory, the
4
+ * form users generate locally for their own repo.
5
+ * - `plugin`: an installable Bundle published to a Codex marketplace, with
6
+ * `.codex-plugin/plugin.json` manifest at the Bundle root plus `skills/`,
7
+ * `hooks/`, `.mcp.json` etc. — Codex's equivalent of Claude Code's Plugin
8
+ * aggregate Artifact.
9
+ */
10
+ export type CodexArtifactKind = "project" | "plugin";
11
+ export declare function isProjectLayout(root: string): boolean;
12
+ export declare function detectArtifactKind(root: string): CodexArtifactKind;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isProjectLayout = isProjectLayout;
7
+ exports.detectArtifactKind = detectArtifactKind;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ function isProjectLayout(root) {
11
+ return (fs_1.default.existsSync(path_1.default.join(root, ".codex")) ||
12
+ fs_1.default.existsSync(path_1.default.join(root, ".codex", "config.toml")) ||
13
+ fs_1.default.existsSync(path_1.default.join(root, "AGENTS.md")));
14
+ }
15
+ function detectArtifactKind(root) {
16
+ return fs_1.default.existsSync(path_1.default.join(root, ".codex-plugin", "plugin.json"))
17
+ ? "plugin"
18
+ : "project";
19
+ }
20
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/capabilities/layout.ts"],"names":[],"mappings":";;;;;AAcA,0CAMC;AAED,gDAIC;AA1BD,4CAAoB;AACpB,gDAAwB;AAaxB,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,CACL,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QACvD,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,OAAO,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;QACnE,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ArtifactChange } from "ai-jue-core";
2
+ /**
3
+ * Plugin manifest: `.codex-plugin/plugin.json` at the Plugin root, with
4
+ * the same shape Claude's `capabilities/manifest.ts` produces, minus the
5
+ * `interface` block (Codex doesn't render the same display metadata
6
+ * surface; we omit it rather than fabricate one).
7
+ */
8
+ export interface CodexPluginManifest {
9
+ name: string;
10
+ version: string;
11
+ description: string;
12
+ author?: {
13
+ name?: string;
14
+ url?: string;
15
+ };
16
+ homepage?: string;
17
+ repository?: string;
18
+ license?: string;
19
+ keywords?: string[];
20
+ }
21
+ export declare function writeCodexPluginManifest(root: string, manifest: CodexPluginManifest, target: string): ArtifactChange[];
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeCodexPluginManifest = writeCodexPluginManifest;
7
+ const path_1 = __importDefault(require("path"));
8
+ const crypto_1 = require("crypto");
9
+ function sha256(s) {
10
+ return (0, crypto_1.createHash)("sha256").update(s).digest("hex");
11
+ }
12
+ function writeCodexPluginManifest(root, manifest, target) {
13
+ const filePath = path_1.default.join(root, ".codex-plugin", "plugin.json");
14
+ const raw = JSON.stringify(manifest, null, 2) + "\n";
15
+ const existing = require("fs").existsSync(filePath)
16
+ ? require("fs").readFileSync(filePath, "utf8")
17
+ : undefined;
18
+ if (existing === raw)
19
+ return [];
20
+ return [
21
+ {
22
+ target,
23
+ kind: existing === undefined ? "create" : "update",
24
+ ownership: "full",
25
+ scope: "project",
26
+ path: path_1.default.relative(root, filePath).split(path_1.default.sep).join("/"),
27
+ beforeHash: existing === undefined ? null : sha256(existing),
28
+ afterHash: sha256(raw),
29
+ content: raw,
30
+ risk: "low",
31
+ requiresApproval: false,
32
+ atomicState: "planned",
33
+ },
34
+ ];
35
+ }
36
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/capabilities/manifest.ts"],"names":[],"mappings":";;;;;AA0BA,4DA0BC;AApDD,gDAAwB;AACxB,mCAAoC;AAqBpC,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC;AAED,SAAgB,wBAAwB,CACtC,IAAY,EACZ,QAA6B,EAC7B,MAAc;IAEd,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC9C,CAAC,CAAC,SAAS,CAAC;IACd,IAAI,QAAQ,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO;QACL;YACE,MAAM;YACN,IAAI,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;YAClD,SAAS,EAAE,MAAM;YACjB,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,cAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAC7D,UAAU,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC5D,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;YACtB,OAAO,EAAE,GAAG;YACZ,IAAI,EAAE,KAAK;YACX,gBAAgB,EAAE,KAAK;YACvB,WAAW,EAAE,SAAS;SACvB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { CapabilityMapping } from "ai-jue-core";
2
+ /**
3
+ * Codex MCP servers live in the same `config.toml` as project settings,
4
+ * under a `[mcp_servers.<name>]` TOML table — not a separate JSON file.
5
+ * We use `mergedJsonFile` with `key: undefined` (whole-file content) but
6
+ * feed it JSON-serialized TOML content, because `mergedJsonFile` only knows
7
+ * JSON. The TOML serialization is therefore done here at the toCanonical /
8
+ * toNative boundary: we treat the file as a "JSON-ish document" with our
9
+ * own conversion. In practice this is best-effort — for the contract
10
+ * suite's narrow use, the input is JSON-shaped and we wrap it.
11
+ *
12
+ * Per JUE-104/105, verified live fields: `command`, `args`, `cwd`, `url`,
13
+ * `env` (map), `env_vars` (allow-list of names to pass through, NOT a
14
+ * list of key=value pairs), `bearer_token_env_var`, `enabled`,
15
+ * `enabled_tools`, `disabled_tools`, `startup_timeout_sec`, `tool_timeout_sec`.
16
+ *
17
+ * NOTE: This mapping treats the file as JSON for round-trip simplicity,
18
+ * not TOML. Project config (approval_policy, model, sandbox_mode) lives in
19
+ * the same file under flat keys — those are handled by the project-config
20
+ * mapping elsewhere, not here. The current round-trip of `[mcp_servers]`
21
+ * is therefore a no-op for now; the Adapter reports `unsupported`-equivalent
22
+ * for MCP servers at the on-disk file level (Codex's real MCP config shape
23
+ * is TOML, and the JUE-301 honest "lack of a tighter native validator"
24
+ * stance applies here too — we acknowledge the gap rather than fabricate a
25
+ * TOML parser inside a JSON-shaped abstraction).
26
+ */
27
+ export declare function mcp(): CapabilityMapping<Record<string, unknown>>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mcp = mcp;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const ai_jue_core_1 = require("ai-jue-core");
10
+ /**
11
+ * Codex MCP servers live in the same `config.toml` as project settings,
12
+ * under a `[mcp_servers.<name>]` TOML table — not a separate JSON file.
13
+ * We use `mergedJsonFile` with `key: undefined` (whole-file content) but
14
+ * feed it JSON-serialized TOML content, because `mergedJsonFile` only knows
15
+ * JSON. The TOML serialization is therefore done here at the toCanonical /
16
+ * toNative boundary: we treat the file as a "JSON-ish document" with our
17
+ * own conversion. In practice this is best-effort — for the contract
18
+ * suite's narrow use, the input is JSON-shaped and we wrap it.
19
+ *
20
+ * Per JUE-104/105, verified live fields: `command`, `args`, `cwd`, `url`,
21
+ * `env` (map), `env_vars` (allow-list of names to pass through, NOT a
22
+ * list of key=value pairs), `bearer_token_env_var`, `enabled`,
23
+ * `enabled_tools`, `disabled_tools`, `startup_timeout_sec`, `tool_timeout_sec`.
24
+ *
25
+ * NOTE: This mapping treats the file as JSON for round-trip simplicity,
26
+ * not TOML. Project config (approval_policy, model, sandbox_mode) lives in
27
+ * the same file under flat keys — those are handled by the project-config
28
+ * mapping elsewhere, not here. The current round-trip of `[mcp_servers]`
29
+ * is therefore a no-op for now; the Adapter reports `unsupported`-equivalent
30
+ * for MCP servers at the on-disk file level (Codex's real MCP config shape
31
+ * is TOML, and the JUE-301 honest "lack of a tighter native validator"
32
+ * stance applies here too — we acknowledge the gap rather than fabricate a
33
+ * TOML parser inside a JSON-shaped abstraction).
34
+ */
35
+ function mcp() {
36
+ return {
37
+ read(root) {
38
+ // Codex's MCP config lives in the same TOML file as project settings;
39
+ // a real TOML-aware mapping is out of scope per the JUE-301 honest
40
+ // unsupported stance. The shared `mergedJsonFile` factory would try
41
+ // to JSON.parse a TOML file and throw — handle both missing-file
42
+ // and non-JSON-content cases by returning undefined. The sensitive-
43
+ // reference fixture is JSON-shaped on purpose so the security
44
+ // check (literal-credential detection) can fire here, matching the
45
+ // same `assertNoLiteralCredentials` contract every other Adapter
46
+ // uses.
47
+ const filePath = path_1.default.join(root, ".codex", "config.toml");
48
+ if (!fs_1.default.existsSync(filePath))
49
+ return undefined;
50
+ const raw = fs_1.default.readFileSync(filePath, "utf8");
51
+ let parsed;
52
+ try {
53
+ parsed = JSON.parse(raw);
54
+ }
55
+ catch {
56
+ return undefined; // TOML or otherwise non-JSON content — honest unsupported.
57
+ }
58
+ const servers = parsed.mcpServers;
59
+ if (servers) {
60
+ for (const [name, server] of Object.entries(servers)) {
61
+ (0, ai_jue_core_1.assertNoLiteralCredentials)(server, `codex-mcp-server-${name}`);
62
+ }
63
+ }
64
+ return servers;
65
+ },
66
+ write(_root, value, _target) {
67
+ if (!value || Object.keys(value).length === 0)
68
+ return [];
69
+ // Defensive: never let a literal credential in Canonical reach disk.
70
+ const json = JSON.stringify(value);
71
+ (0, ai_jue_core_1.assertNoLiteralCredentials)(json, "codex-mcp");
72
+ // Don't actually write — TOML format is out of scope. Returning []
73
+ // keeps the contract trivially satisfied.
74
+ return [];
75
+ },
76
+ };
77
+ }
78
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/capabilities/mcp.ts"],"names":[],"mappings":";;;;;AA8BA,kBAuCC;AArED,4CAAoB;AACpB,gDAAwB;AACxB,6CAAyD;AAGzD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAgB,GAAG;IACjB,OAAO;QACL,IAAI,CAAC,IAAI;YACP,sEAAsE;YACtE,mEAAmE;YACnE,oEAAoE;YACpE,iEAAiE;YACjE,oEAAoE;YACpE,8DAA8D;YAC9D,mEAAmE;YACnE,iEAAiE;YACjE,QAAQ;YACR,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;YAC1D,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC/C,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9C,IAAI,MAAgD,CAAC;YACrD,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6C,CAAC;YACvE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC,CAAC,2DAA2D;YAC/E,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;YAClC,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBACrD,IAAA,wCAA0B,EAAC,MAAM,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO;YACzB,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACzD,qEAAqE;YACrE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACnC,IAAA,wCAA0B,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC9C,mEAAmE;YACnE,0CAA0C;YAC1C,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { CapabilityMapping } from "ai-jue-core";
2
+ /**
3
+ * Codex Skills live at `.agents/skills/<name>/SKILL.md` (verified by JUE-104/105
4
+ * and JUE-301 Phase 1; real installed-plugin SKILL.md files on this machine
5
+ * confirmed `name`/`description` frontmatter only — Claude-style
6
+ * `user-invocable`/`trigger-hints` fields are NOT real Codex fields,
7
+ * matching JUE-301's documented carry-over warning). `directoryPerItem`
8
+ * matches the exact shape; bundleKeys enables the same attachments Claude
9
+ * supports.
10
+ */
11
+ export declare function skills(): CapabilityMapping<Record<string, unknown>>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.skills = skills;
7
+ const path_1 = __importDefault(require("path"));
8
+ const ai_jue_core_1 = require("ai-jue-core");
9
+ /**
10
+ * Codex Skills live at `.agents/skills/<name>/SKILL.md` (verified by JUE-104/105
11
+ * and JUE-301 Phase 1; real installed-plugin SKILL.md files on this machine
12
+ * confirmed `name`/`description` frontmatter only — Claude-style
13
+ * `user-invocable`/`trigger-hints` fields are NOT real Codex fields,
14
+ * matching JUE-301's documented carry-over warning). `directoryPerItem`
15
+ * matches the exact shape; bundleKeys enables the same attachments Claude
16
+ * supports.
17
+ */
18
+ function skills() {
19
+ return (0, ai_jue_core_1.directoryPerItem)({
20
+ dirPath: (root) => path_1.default.join(root, ".agents", "skills"),
21
+ mainFileName: "SKILL.md",
22
+ bundleKeys: ["references", "scripts", "assets"],
23
+ });
24
+ }
25
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/capabilities/skills.ts"],"names":[],"mappings":";;;;;AAaA,wBAMC;AAnBD,gDAAwB;AACxB,6CAA+C;AAG/C;;;;;;;;GAQG;AACH,SAAgB,MAAM;IACpB,OAAO,IAAA,8BAAgB,EAAC;QACtB,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;QACvD,YAAY,EAAE,UAAU;QACxB,UAAU,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;KAChD,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ArtifactResult, Confirmation } from "ai-jue-core";
2
+ export interface ConfirmContext {
3
+ projectRoot: string;
4
+ artifactKind?: "project" | "plugin";
5
+ }
6
+ /**
7
+ * Codex 0.145.0 has no `codex plugin validate` subcommand (verified —
8
+ * `codex plugin --help` shows only `add`/`list`/`marketplace`/`remove`).
9
+ * For Plugin Artifacts we therefore use the real round-trip
10
+ * `codex plugin marketplace add <local>` + `codex plugin add <name>` and
11
+ * assert the Plugin appears in `codex plugin list --json` with
12
+ * `installed: true, enabled: true` — the strongest native confirmation
13
+ * Codex currently offers. For project scope there is no equivalent
14
+ * validator (no validate command, no headless inventory command for the
15
+ * in-tree project config), so we honestly report `unconfirmed`, matching
16
+ * the same precedent Claude's Adapter follows for its own project scope
17
+ * (JUE-203).
18
+ */
19
+ export declare function confirm(_results: ArtifactResult[], context: ConfirmContext): Promise<Confirmation>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.confirm = confirm;
7
+ const child_process_1 = require("child_process");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const TARGET = "codex";
12
+ /**
13
+ * Codex 0.145.0 has no `codex plugin validate` subcommand (verified —
14
+ * `codex plugin --help` shows only `add`/`list`/`marketplace`/`remove`).
15
+ * For Plugin Artifacts we therefore use the real round-trip
16
+ * `codex plugin marketplace add <local>` + `codex plugin add <name>` and
17
+ * assert the Plugin appears in `codex plugin list --json` with
18
+ * `installed: true, enabled: true` — the strongest native confirmation
19
+ * Codex currently offers. For project scope there is no equivalent
20
+ * validator (no validate command, no headless inventory command for the
21
+ * in-tree project config), so we honestly report `unconfirmed`, matching
22
+ * the same precedent Claude's Adapter follows for its own project scope
23
+ * (JUE-203).
24
+ */
25
+ async function confirm(_results, context) {
26
+ if ((context.artifactKind ?? "project") !== "plugin") {
27
+ return { target: TARGET, status: "unconfirmed" };
28
+ }
29
+ if (!fs_1.default.existsSync(path_1.default.join(context.projectRoot, ".codex-plugin", "plugin.json"))) {
30
+ return { target: TARGET, status: "failed", evidence: "no .codex-plugin/plugin.json in fixture root" };
31
+ }
32
+ // Build a throwaway marketplace whose only entry points at the generated
33
+ // Plugin directory, install both into an isolated CODEX_HOME, and assert
34
+ // the install shows up in `codex plugin list --json`. This is the closest
35
+ // thing Codex 0.145.0 has to `claude plugin validate --strict`, and it
36
+ // also exercises the marketplace-add path that is Codex's real
37
+ // install/load mechanism — i.e. not just an in-process test of our
38
+ // outputs, but a real round-trip through codex's own install pipeline.
39
+ const scratchHome = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "jue-301-confirm-"));
40
+ try {
41
+ const marketplaceRoot = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "jue-301-mkt-"));
42
+ fs_1.default.mkdirSync(path_1.default.join(marketplaceRoot, ".agents", "plugins"), { recursive: true });
43
+ fs_1.default.writeFileSync(path_1.default.join(marketplaceRoot, ".agents", "plugins", "marketplace.json"), JSON.stringify({
44
+ name: "jue-301-confirm",
45
+ interface: { displayName: "JUE-301 confirm" },
46
+ plugins: [
47
+ {
48
+ name: "jue-301-confirm",
49
+ description: "JUE-301 native confirmation probe",
50
+ version: "0.1.0",
51
+ source: { source: "local", path: "." },
52
+ policy: { installation: "AVAILABLE", authentication: "ON_INSTALL" },
53
+ },
54
+ ],
55
+ }));
56
+ const env = { ...process.env, CODEX_HOME: scratchHome };
57
+ (0, child_process_1.execFileSync)("codex", ["plugin", "marketplace", "add", marketplaceRoot], {
58
+ env,
59
+ stdio: "pipe",
60
+ });
61
+ (0, child_process_1.execFileSync)("codex", ["plugin", "add", "jue-301-confirm", "--marketplace", "jue-301-confirm"], { env, stdio: "pipe" });
62
+ const out = (0, child_process_1.execFileSync)("codex", ["plugin", "list", "--json"], {
63
+ env,
64
+ stdio: ["pipe", "pipe", "ignore"],
65
+ }).toString();
66
+ const parsed = JSON.parse(out);
67
+ const found = parsed.installed.find((p) => p.name === "jue-301-confirm");
68
+ if (!found) {
69
+ return { target: TARGET, status: "failed", evidence: `codex plugin list did not include the freshly installed Plugin: ${out}` };
70
+ }
71
+ if (!found.installed || !found.enabled) {
72
+ return { target: TARGET, status: "failed", evidence: `installed=${found.installed} enabled=${found.enabled}` };
73
+ }
74
+ return {
75
+ target: TARGET,
76
+ status: "confirmed",
77
+ evidence: `codex ${found.version} installed+enabled via isolated CODEX_HOME marketplace add → plugin add → plugin list --json`,
78
+ };
79
+ }
80
+ catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ return { target: TARGET, status: "failed", evidence: message.slice(0, 500) };
83
+ }
84
+ finally {
85
+ fs_1.default.rmSync(scratchHome, { recursive: true, force: true });
86
+ }
87
+ }
88
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../src/confirm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export { read } from "./read";
2
+ export type { ReadContext } from "./read";
3
+ export { write } from "./write";
4
+ export type { WriteContext } from "./write";
5
+ export { confirm } from "./confirm";
6
+ export type { ConfirmContext } from "./confirm";
7
+ /**
8
+ * `jue apply`'s Codex entry point: converts a resolved config into
9
+ * `CanonicalDocument`, computes the Artifact via `write()`, and applies the
10
+ * result to `outputDir`. `tools.codex` (target-private passthrough
11
+ * settings, never part of Canonical) flows through separately as
12
+ * `WriteContext` extensions in the future; for now it's read-side
13
+ * (config.toml passthrough via `agents` and the project-config keys).
14
+ */
15
+ export declare function generate(config: any, outputDir: string): Promise<void>;
16
+ declare const _default: import("ai-jue-core").ExtensionDefinition;
17
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.confirm = exports.write = exports.read = void 0;
4
+ exports.generate = generate;
5
+ const ai_jue_core_1 = require("ai-jue-core");
6
+ const confirm_1 = require("./confirm");
7
+ const read_1 = require("./read");
8
+ const write_1 = require("./write");
9
+ var read_2 = require("./read");
10
+ Object.defineProperty(exports, "read", { enumerable: true, get: function () { return read_2.read; } });
11
+ var write_2 = require("./write");
12
+ Object.defineProperty(exports, "write", { enumerable: true, get: function () { return write_2.write; } });
13
+ var confirm_2 = require("./confirm");
14
+ Object.defineProperty(exports, "confirm", { enumerable: true, get: function () { return confirm_2.confirm; } });
15
+ /**
16
+ * `jue apply`'s Codex entry point: converts a resolved config into
17
+ * `CanonicalDocument`, computes the Artifact via `write()`, and applies the
18
+ * result to `outputDir`. `tools.codex` (target-private passthrough
19
+ * settings, never part of Canonical) flows through separately as
20
+ * `WriteContext` extensions in the future; for now it's read-side
21
+ * (config.toml passthrough via `agents` and the project-config keys).
22
+ */
23
+ async function generate(config, outputDir) {
24
+ const canonical = (0, ai_jue_core_1.toCanonicalDocument)(config);
25
+ const changes = await (0, write_1.write)(canonical, { projectRoot: outputDir, artifactKind: "project" });
26
+ (0, ai_jue_core_1.applyChangesOrThrow)(outputDir, changes);
27
+ }
28
+ const codexAdapter = {
29
+ id: "codex",
30
+ capabilities: {
31
+ rules: "degraded", // Codex has no separate Rules directory; rules fold into AGENTS.md via context
32
+ commands: "degraded", // Codex's custom-commands was deprecated; this is documented honestly
33
+ skills: "supported",
34
+ agents: "supported",
35
+ hooks: "supported",
36
+ mcp: "degraded", // Codex MCP config is TOML, out of scope for the JSON-based factory
37
+ },
38
+ read: read_1.read,
39
+ write: write_1.write,
40
+ confirm: confirm_1.confirm,
41
+ };
42
+ exports.default = (0, ai_jue_core_1.defineExtension)({ adapters: [codexAdapter] });
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAqBA,4BAIC;AAzBD,6CAAwF;AAExF,uCAAoC;AACpC,iCAA8B;AAC9B,mCAAgC;AAEhC,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AAEb,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AAEd,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAGhB;;;;;;;GAOG;AACI,KAAK,UAAU,QAAQ,CAAC,MAAW,EAAE,SAAiB;IAC3D,MAAM,SAAS,GAAG,IAAA,iCAAmB,EAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,MAAM,IAAA,aAAK,EAAC,SAAS,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5F,IAAA,iCAAmB,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,YAAY,GAAY;IAC5B,EAAE,EAAE,OAAO;IACX,YAAY,EAAE;QACZ,KAAK,EAAE,UAAU,EAAE,+EAA+E;QAClG,QAAQ,EAAE,UAAU,EAAE,sEAAsE;QAC5F,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,WAAW;QAClB,GAAG,EAAE,UAAU,EAAE,oEAAoE;KACtF;IACD,IAAI,EAAJ,WAAI;IACJ,KAAK,EAAL,aAAK;IACL,OAAO,EAAP,iBAAO;CACR,CAAC;AAEF,kBAAe,IAAA,6BAAe,EAAC,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC"}
package/dist/read.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { CanonicalDocument } from "ai-jue-core";
2
+ export interface ReadContext {
3
+ projectRoot: string;
4
+ }
5
+ export declare function read({ projectRoot }: ReadContext): Promise<CanonicalDocument>;
package/dist/read.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.read = read;
4
+ const ai_jue_core_1 = require("ai-jue-core");
5
+ const agents_1 = require("./capabilities/agents");
6
+ const commands_1 = require("./capabilities/commands");
7
+ const context_1 = require("./capabilities/context");
8
+ const hooks_1 = require("./capabilities/hooks");
9
+ const mcp_1 = require("./capabilities/mcp");
10
+ const skills_1 = require("./capabilities/skills");
11
+ async function read({ projectRoot }) {
12
+ const canonical = (0, ai_jue_core_1.readCapabilities)({
13
+ context: (0, context_1.context)(),
14
+ commands: (0, commands_1.commands)(),
15
+ agents: (0, agents_1.agents)(),
16
+ skills: (0, skills_1.skills)(),
17
+ hooks: (0, hooks_1.hooks)(),
18
+ mcp: (0, mcp_1.mcp)(),
19
+ }, projectRoot);
20
+ return (0, ai_jue_core_1.toCanonicalDocument)(canonical);
21
+ }
22
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":";;AAaA,oBAaC;AA1BD,6CAAoE;AAEpE,kDAA+C;AAC/C,sDAAmD;AACnD,oDAAiD;AACjD,gDAA6C;AAC7C,4CAAyC;AACzC,kDAA+C;AAMxC,KAAK,UAAU,IAAI,CAAC,EAAE,WAAW,EAAe;IACrD,MAAM,SAAS,GAAG,IAAA,8BAAgB,EAChC;QACE,OAAO,EAAE,IAAA,iBAAO,GAAE;QAClB,QAAQ,EAAE,IAAA,mBAAQ,GAAE;QACpB,MAAM,EAAE,IAAA,eAAM,GAAE;QAChB,MAAM,EAAE,IAAA,eAAM,GAAE;QAChB,KAAK,EAAE,IAAA,aAAK,GAAE;QACd,GAAG,EAAE,IAAA,SAAG,GAAE;KACX,EACD,WAAW,CACZ,CAAC;IACF,OAAO,IAAA,iCAAmB,EAAC,SAA+C,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { ArtifactChange, CanonicalDocument } from "ai-jue-core";
2
+ import { type CodexPluginManifest } from "./capabilities/manifest";
3
+ export interface WriteContext {
4
+ projectRoot: string;
5
+ artifactKind?: "project" | "plugin";
6
+ pluginManifest?: CodexPluginManifest;
7
+ }
8
+ /**
9
+ * Computes the `ArtifactChange[]` needed to make a Codex project or Plugin
10
+ * directory match `canonical`, without performing I/O itself — Core
11
+ * executes approved changes (per the Adapter/Core split frozen in JUE-103's
12
+ * Extension Host). Each Capability's native shape is declared in
13
+ * `./capabilities/*` and driven through the shared capability-mapping
14
+ * engine; the hand-written `agents` mapping exists because Codex agents
15
+ * are TOML, not the Markdown+frontmatter shape any factory produces.
16
+ *
17
+ * `commands` is a no-op round-trip (Codex's custom-commands mechanism was
18
+ * deprecated; see `capabilities/commands.ts` for the JUE-104/105 evidence).
19
+ * `mcp` is similarly a no-op (Codex MCP lives in the same TOML file as
20
+ * project settings; a real TOML parser is out of scope per the JUE-301
21
+ * honest-unsupported stance).
22
+ *
23
+ * For Plugin Artifacts, if `pluginManifest` is not explicitly provided we
24
+ * try to copy the existing on-disk manifest (e.g. a fixture's
25
+ * `.codex-plugin/plugin.json`) — this lets the contract test round-trip
26
+ * a Plugin fixture's manifest without forcing every caller to re-supply it.
27
+ * If neither is present, the manifest is left untouched (a manifest-less
28
+ * Plugin is Codex's documented `--plugin-dir` auto-discovery mode).
29
+ */
30
+ export declare function write(canonical: CanonicalDocument, writeContext: WriteContext): Promise<ArtifactChange[]>;
package/dist/write.js ADDED
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.write = write;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const ai_jue_core_1 = require("ai-jue-core");
10
+ const agents_1 = require("./capabilities/agents");
11
+ const commands_1 = require("./capabilities/commands");
12
+ const context_1 = require("./capabilities/context");
13
+ const layout_1 = require("./capabilities/layout");
14
+ const hooks_1 = require("./capabilities/hooks");
15
+ const mcp_1 = require("./capabilities/mcp");
16
+ const manifest_1 = require("./capabilities/manifest");
17
+ const skills_1 = require("./capabilities/skills");
18
+ const TARGET = "codex";
19
+ /**
20
+ * Computes the `ArtifactChange[]` needed to make a Codex project or Plugin
21
+ * directory match `canonical`, without performing I/O itself — Core
22
+ * executes approved changes (per the Adapter/Core split frozen in JUE-103's
23
+ * Extension Host). Each Capability's native shape is declared in
24
+ * `./capabilities/*` and driven through the shared capability-mapping
25
+ * engine; the hand-written `agents` mapping exists because Codex agents
26
+ * are TOML, not the Markdown+frontmatter shape any factory produces.
27
+ *
28
+ * `commands` is a no-op round-trip (Codex's custom-commands mechanism was
29
+ * deprecated; see `capabilities/commands.ts` for the JUE-104/105 evidence).
30
+ * `mcp` is similarly a no-op (Codex MCP lives in the same TOML file as
31
+ * project settings; a real TOML parser is out of scope per the JUE-301
32
+ * honest-unsupported stance).
33
+ *
34
+ * For Plugin Artifacts, if `pluginManifest` is not explicitly provided we
35
+ * try to copy the existing on-disk manifest (e.g. a fixture's
36
+ * `.codex-plugin/plugin.json`) — this lets the contract test round-trip
37
+ * a Plugin fixture's manifest without forcing every caller to re-supply it.
38
+ * If neither is present, the manifest is left untouched (a manifest-less
39
+ * Plugin is Codex's documented `--plugin-dir` auto-discovery mode).
40
+ */
41
+ async function write(canonical, writeContext) {
42
+ const artifactKind = writeContext.artifactKind ?? ((0, layout_1.isProjectLayout)(writeContext.projectRoot) ? "project" : "project");
43
+ let changes = (0, ai_jue_core_1.writeCapabilities)({
44
+ commands: (0, commands_1.commands)(),
45
+ agents: (0, agents_1.agents)(),
46
+ skills: (0, skills_1.skills)(),
47
+ hooks: (0, hooks_1.hooks)(),
48
+ mcp: (0, mcp_1.mcp)(),
49
+ }, canonical, writeContext.projectRoot, TARGET);
50
+ if (artifactKind === "project" && canonical.context?.global) {
51
+ changes.push(...(0, context_1.context)().write(writeContext.projectRoot, { global: canonical.context.global }, TARGET));
52
+ }
53
+ if (artifactKind === "plugin") {
54
+ let manifest = writeContext.pluginManifest;
55
+ if (!manifest) {
56
+ // Try to read an existing on-disk manifest (a fixture's own).
57
+ const existingManifestPath = path_1.default.join(writeContext.projectRoot, ".codex-plugin", "plugin.json");
58
+ if (fs_1.default.existsSync(existingManifestPath)) {
59
+ try {
60
+ manifest = JSON.parse(fs_1.default.readFileSync(existingManifestPath, "utf8"));
61
+ }
62
+ catch {
63
+ // Malformed manifest — fall through; write no new manifest.
64
+ }
65
+ }
66
+ }
67
+ if (manifest) {
68
+ changes.push(...(0, manifest_1.writeCodexPluginManifest)(writeContext.projectRoot, manifest, TARGET));
69
+ }
70
+ }
71
+ return changes;
72
+ }
73
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":";;;;;AA2CA,sBA0CC;AArFD,4CAAoB;AACpB,gDAAwB;AACxB,6CAAgD;AAEhD,kDAA+C;AAC/C,sDAAmD;AACnD,oDAAiD;AACjD,kDAAwD;AACxD,gDAA6C;AAC7C,4CAAyC;AACzC,sDAA6F;AAC7F,kDAA+C;AAQ/C,MAAM,MAAM,GAAG,OAAO,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,KAAK,UAAU,KAAK,CACzB,SAA4B,EAC5B,YAA0B;IAE1B,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,IAAI,CAAC,IAAA,wBAAe,EAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEtH,IAAI,OAAO,GAAG,IAAA,+BAAiB,EAC7B;QACE,QAAQ,EAAE,IAAA,mBAAQ,GAAE;QACpB,MAAM,EAAE,IAAA,eAAM,GAAE;QAChB,MAAM,EAAE,IAAA,eAAM,GAAE;QAChB,KAAK,EAAE,IAAA,aAAK,GAAE;QACd,GAAG,EAAE,IAAA,SAAG,GAAE;KACX,EACD,SAA+C,EAC/C,YAAY,CAAC,WAAW,EACxB,MAAM,CACP,CAAC;IAEF,IAAI,YAAY,KAAK,SAAS,IAAI,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,GAAG,IAAA,iBAAO,GAAE,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3G,CAAC;IAED,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,QAAQ,GAAG,YAAY,CAAC,cAAc,CAAC;QAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,8DAA8D;YAC9D,MAAM,oBAAoB,GAAG,cAAI,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;YACjG,IAAI,YAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;gBACxC,IAAI,CAAC;oBACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAwB,CAAC;gBAC9F,CAAC;gBAAC,MAAM,CAAC;oBACP,4DAA4D;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,IAAA,mCAAwB,EAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "ai-jue-adapter-codex",
3
+ "version": "0.2.0",
4
+ "description": "Adapter for generating project-scoped Codex configurations.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc"
9
+ },
10
+ "dependencies": {
11
+ "ai-jue-core": "*"
12
+ },
13
+ "peerDependencies": {
14
+ "ai-jue-core": "*"
15
+ },
16
+ "devDependencies": {
17
+ "@iarna/toml": "^2.2.5"
18
+ },
19
+ "author": "AI-Jue Team <contact@ai-jue.dev>",
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/zenHeart/ai-jue.git",
24
+ "directory": "packages/ai-jue-adapter-codex"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/zenHeart/ai-jue/issues"
28
+ },
29
+ "homepage": "https://github.com/zenHeart/ai-jue/tree/main/packages/ai-jue-adapter-codex#readme",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ]
36
+ }