@neobiotechlabs/neobiotech-dev-agent 0.1.39 → 0.1.41
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/dist/doctor.js +33 -3
- package/dist/doctor.js.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/setup-antigravity.js +38 -0
- package/dist/setup-antigravity.js.map +1 -0
- package/dist/setup-codex.js +87 -5
- package/dist/setup-codex.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { fileURLToPath as __f2p } from "node:url";
|
|
4
|
+
import { dirname as __dn } from "node:path";
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const __filename = __f2p(import.meta.url);
|
|
7
|
+
const __dirname = __dn(__filename);
|
|
8
|
+
|
|
9
|
+
// src/cli/setup-antigravity.ts
|
|
10
|
+
import { spawnSync } from "child_process";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
13
|
+
function runSetupAntigravityCli(installer = (command, args, options) => spawnSync(command, args, options)) {
|
|
14
|
+
const pluginRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
const result = installer("agy", ["plugin", "install", pluginRoot], { stdio: "inherit" });
|
|
16
|
+
if (result.error) {
|
|
17
|
+
process.stderr.write(`Antigravity plugin install failed: ${result.error.message}
|
|
18
|
+
`);
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
if (result.status !== 0) return result.status ?? 1;
|
|
22
|
+
process.stdout.write(
|
|
23
|
+
[
|
|
24
|
+
"Antigravity plugin installed: neobiotech-dev-agent",
|
|
25
|
+
"Required environment variables: JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN",
|
|
26
|
+
"Restart Antigravity, then verify /mcp and /agents.",
|
|
27
|
+
"Run /gate-parallel-review for a full Gate review."
|
|
28
|
+
].join("\n") + "\n"
|
|
29
|
+
);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
33
|
+
process.exitCode = runSetupAntigravityCli();
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
runSetupAntigravityCli
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=setup-antigravity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup-antigravity.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\ntype InstallerResult = {\n error?: Error;\n status: number | null;\n};\n\ntype Installer = (\n command: string,\n args: string[],\n options: { stdio: 'inherit' },\n) => InstallerResult;\n\nexport function runSetupAntigravityCli(\n installer: Installer = (command, args, options) => spawnSync(command, args, options),\n) {\n const pluginRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n const result = installer('agy', ['plugin', 'install', pluginRoot], { stdio: 'inherit' });\n if (result.error) {\n process.stderr.write(`Antigravity plugin install failed: ${result.error.message}\\n`);\n return 1;\n }\n if (result.status !== 0) return result.status ?? 1;\n process.stdout.write(\n [\n 'Antigravity plugin installed: neobiotech-dev-agent',\n 'Required environment variables: JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN',\n 'Restart Antigravity, then verify /mcp and /agents.',\n 'Run /gate-parallel-review for a full Gate review.',\n ].join('\\n') + '\\n',\n );\n return 0;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n process.exitCode = runSetupAntigravityCli();\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,iBAAiB;AAC1B,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAavB,SAAS,uBACd,YAAuB,CAAC,SAAS,MAAM,YAAY,UAAU,SAAS,MAAM,OAAO,GACnF;AACA,QAAM,aAAa,KAAK,QAAQ,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,IAAI;AAClF,QAAM,SAAS,UAAU,OAAO,CAAC,UAAU,WAAW,UAAU,GAAG,EAAE,OAAO,UAAU,CAAC;AACvF,MAAI,OAAO,OAAO;AAChB,YAAQ,OAAO,MAAM,sCAAsC,OAAO,MAAM,OAAO;AAAA,CAAI;AACnF,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,EAAG,QAAO,OAAO,UAAU;AACjD,UAAQ,OAAO;AAAA,IACb;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AAEA,IAAI,QAAQ,KAAK,CAAC,MAAM,cAAc,YAAY,GAAG,GAAG;AACtD,UAAQ,WAAW,uBAAuB;AAC5C;","names":[]}
|
package/dist/setup-codex.js
CHANGED
|
@@ -11,12 +11,20 @@ import path2 from "path";
|
|
|
11
11
|
import { fileURLToPath } from "url";
|
|
12
12
|
|
|
13
13
|
// src/cli/codex-project-config.ts
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
existsSync,
|
|
16
|
+
mkdirSync,
|
|
17
|
+
readFileSync,
|
|
18
|
+
readdirSync,
|
|
19
|
+
unlinkSync,
|
|
20
|
+
writeFileSync
|
|
21
|
+
} from "fs";
|
|
15
22
|
import path from "path";
|
|
16
23
|
var FALLBACK_KEY = "project_doc_fallback_filenames";
|
|
17
24
|
var MAX_BYTES_KEY = "project_doc_max_bytes";
|
|
18
25
|
var FALLBACK_LINE = `${FALLBACK_KEY} = ["CLAUDE.md"]`;
|
|
19
26
|
var MAX_BYTES_LINE = `${MAX_BYTES_KEY} = 65536`;
|
|
27
|
+
var GENERATED_AGENT_MARKER = "# Generated by neobiotech-dev-agent. Do not edit directly.";
|
|
20
28
|
function parseStringArray(value) {
|
|
21
29
|
try {
|
|
22
30
|
const parsed = JSON.parse(value);
|
|
@@ -116,7 +124,72 @@ function planCodexProjectSetup({
|
|
|
116
124
|
};
|
|
117
125
|
}
|
|
118
126
|
}
|
|
119
|
-
function
|
|
127
|
+
function syncCodexAgents({
|
|
128
|
+
projectDir,
|
|
129
|
+
templatesDir
|
|
130
|
+
}) {
|
|
131
|
+
const emptyReport = {
|
|
132
|
+
created: [],
|
|
133
|
+
updated: [],
|
|
134
|
+
unchanged: [],
|
|
135
|
+
removed: [],
|
|
136
|
+
conflicts: []
|
|
137
|
+
};
|
|
138
|
+
if (!templatesDir || !existsSync(templatesDir)) {
|
|
139
|
+
return {
|
|
140
|
+
...emptyReport,
|
|
141
|
+
status: "skip",
|
|
142
|
+
messages: ["Codex custom agent \uD15C\uD50C\uB9BF\uC744 \uCC3E\uC9C0 \uBABB\uD574 \uB3D9\uAE30\uD654\uB97C \uAC74\uB108\uB701\uB2C8\uB2E4."]
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const templateNames = readdirSync(templatesDir).filter((name) => name.endsWith(".toml")).sort();
|
|
146
|
+
const targetDir = path.join(projectDir, ".codex", "agents");
|
|
147
|
+
const report = {
|
|
148
|
+
...emptyReport,
|
|
149
|
+
status: "noop",
|
|
150
|
+
messages: []
|
|
151
|
+
};
|
|
152
|
+
for (const name of templateNames) {
|
|
153
|
+
const source = readFileSync(path.join(templatesDir, name), "utf8");
|
|
154
|
+
const targetPath = path.join(targetDir, name);
|
|
155
|
+
if (!existsSync(targetPath)) {
|
|
156
|
+
mkdirSync(targetDir, { recursive: true });
|
|
157
|
+
writeFileSync(targetPath, source);
|
|
158
|
+
report.created.push(name);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const current = readFileSync(targetPath, "utf8");
|
|
162
|
+
if (current === source) {
|
|
163
|
+
report.unchanged.push(name);
|
|
164
|
+
} else if (current.startsWith(GENERATED_AGENT_MARKER)) {
|
|
165
|
+
writeFileSync(targetPath, source);
|
|
166
|
+
report.updated.push(name);
|
|
167
|
+
} else {
|
|
168
|
+
report.conflicts.push(name);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (existsSync(targetDir)) {
|
|
172
|
+
for (const name of readdirSync(targetDir).filter((entry) => entry.endsWith(".toml")).sort()) {
|
|
173
|
+
if (templateNames.includes(name)) continue;
|
|
174
|
+
const targetPath = path.join(targetDir, name);
|
|
175
|
+
if (readFileSync(targetPath, "utf8").startsWith(GENERATED_AGENT_MARKER)) {
|
|
176
|
+
unlinkSync(targetPath);
|
|
177
|
+
report.removed.push(name);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (report.conflicts.length > 0) report.status = "conflict";
|
|
182
|
+
else if (report.updated.length > 0 || report.removed.length > 0) report.status = "update";
|
|
183
|
+
else if (report.created.length > 0) report.status = "create";
|
|
184
|
+
report.messages.push(
|
|
185
|
+
report.status === "conflict" ? `\uC0AC\uC6A9\uC790 \uAD00\uB9AC custom agent\uC640 \uCDA9\uB3CC\uD588\uC2B5\uB2C8\uB2E4: ${report.conflicts.join(", ")}` : `Codex custom agent \uB3D9\uAE30\uD654: \uC0DD\uC131 ${report.created.length}, \uAC31\uC2E0 ${report.updated.length}, \uC720\uC9C0 ${report.unchanged.length}, \uC81C\uAC70 ${report.removed.length}`
|
|
186
|
+
);
|
|
187
|
+
return report;
|
|
188
|
+
}
|
|
189
|
+
function setupCodexProject({
|
|
190
|
+
projectDir,
|
|
191
|
+
agentTemplatesDir
|
|
192
|
+
}) {
|
|
120
193
|
const claudePath = path.join(projectDir, "CLAUDE.md");
|
|
121
194
|
const agentsPath = path.join(projectDir, "AGENTS.md");
|
|
122
195
|
const configPath = path.join(projectDir, ".codex", "config.toml");
|
|
@@ -129,7 +202,10 @@ function setupCodexProject({ projectDir }) {
|
|
|
129
202
|
mkdirSync(path.dirname(configPath), { recursive: true });
|
|
130
203
|
writeFileSync(configPath, plan.configText);
|
|
131
204
|
}
|
|
132
|
-
return
|
|
205
|
+
return {
|
|
206
|
+
...plan,
|
|
207
|
+
agents: syncCodexAgents({ projectDir, templatesDir: agentTemplatesDir })
|
|
208
|
+
};
|
|
133
209
|
}
|
|
134
210
|
|
|
135
211
|
// src/cli/setup-codex.ts
|
|
@@ -141,10 +217,16 @@ function parseProjectPath(args) {
|
|
|
141
217
|
}
|
|
142
218
|
function runSetupCodexCli(args) {
|
|
143
219
|
const projectDir = parseProjectPath(args);
|
|
144
|
-
const
|
|
220
|
+
const pluginRoot = path2.resolve(path2.dirname(fileURLToPath(import.meta.url)), "..");
|
|
221
|
+
const result = setupCodexProject({
|
|
222
|
+
projectDir,
|
|
223
|
+
agentTemplatesDir: path2.join(pluginRoot, "codex-agents")
|
|
224
|
+
});
|
|
145
225
|
const output = [
|
|
146
226
|
`project instruction status: ${result.status}`,
|
|
147
227
|
...result.messages,
|
|
228
|
+
`custom agent status: ${result.agents?.status ?? "skip"}`,
|
|
229
|
+
...result.agents?.messages ?? [],
|
|
148
230
|
"Marketplace registration: codex plugin marketplace add <path-to-neobiotech-marketplace>",
|
|
149
231
|
"Plugin installation: install neobiotech-dev-agent from the NeoBiotech Marketplace.",
|
|
150
232
|
"Required environment variables: JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN",
|
|
@@ -153,7 +235,7 @@ function runSetupCodexCli(args) {
|
|
|
153
235
|
];
|
|
154
236
|
process.stdout.write(`${output.join("\n")}
|
|
155
237
|
`);
|
|
156
|
-
return result.status === "conflict" ? 2 : 0;
|
|
238
|
+
return result.status === "conflict" || result.agents?.status === "conflict" ? 2 : 0;
|
|
157
239
|
}
|
|
158
240
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
159
241
|
process.exitCode = runSetupCodexCli(process.argv.slice(2));
|
package/dist/setup-codex.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/setup-codex.ts","../src/cli/codex-project-config.ts"],"sourcesContent":["import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { setupCodexProject } from './codex-project-config.js';\n\nfunction parseProjectPath(args: string[]) {\n const index = args.indexOf('--project');\n if (index === -1) return process.cwd();\n if (!args[index + 1]) throw new Error('--project requires a path');\n return path.resolve(args[index + 1]);\n}\n\nexport function runSetupCodexCli(args: string[]) {\n const projectDir = parseProjectPath(args);\n const result = setupCodexProject({ projectDir });\n const output = [\n `project instruction status: ${result.status}`,\n ...result.messages,\n 'Marketplace registration: codex plugin marketplace add <path-to-neobiotech-marketplace>',\n 'Plugin installation: install neobiotech-dev-agent from the NeoBiotech Marketplace.',\n 'Required environment variables: JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN',\n 'Optional environment variables: XRAY_CLIENT_ID, XRAY_CLIENT_SECRET, RISK_PLUGIN_ENDPOINT, RISK_PLUGIN_AUTH_TOKEN, RISK_PLUGIN_AUTHOR',\n 'Restart Codex after Marketplace or environment changes.',\n ];\n process.stdout.write(`${output.join('\\n')}\\n`);\n return result.status === 'conflict' ? 2 : 0;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n process.exitCode = runSetupCodexCli(process.argv.slice(2));\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nconst FALLBACK_KEY = 'project_doc_fallback_filenames';\nconst MAX_BYTES_KEY = 'project_doc_max_bytes';\nconst FALLBACK_LINE = `${FALLBACK_KEY} = [\"CLAUDE.md\"]`;\nconst MAX_BYTES_LINE = `${MAX_BYTES_KEY} = 65536`;\n\nexport interface SetupInput {\n hasClaude: boolean;\n hasAgents: boolean;\n configText: string;\n}\n\nexport interface SetupPlan {\n status: 'create' | 'update' | 'noop' | 'conflict' | 'skip';\n messages: string[];\n configText?: string;\n}\n\nfunction parseStringArray(value: string): string[] | null {\n try {\n const parsed: unknown = JSON.parse(value);\n return Array.isArray(parsed) && parsed.every((item) => typeof item === 'string')\n ? parsed\n : null;\n } catch {\n return null;\n }\n}\n\nfunction formatStringArray(values: string[]) {\n return `[${values.map((value) => JSON.stringify(value)).join(', ')}]`;\n}\n\nexport function mergeCodexConfig(configText: string): { changed: boolean; content: string } {\n const newline = configText.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const hadTrailingNewline = configText.endsWith('\\n');\n const lines = configText ? configText.replace(/\\r\\n/g, '\\n').split('\\n') : [];\n if (hadTrailingNewline) lines.pop();\n\n let inSection = false;\n let fallbackIndex = -1;\n let maxBytesIndex = -1;\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index];\n if (/^\\s*\\[/.test(line)) inSection = true;\n if (inSection) continue;\n if (new RegExp(`^\\\\s*${FALLBACK_KEY}\\\\s*=`).test(line)) {\n if (fallbackIndex !== -1) throw new Error(`Duplicate ${FALLBACK_KEY}`);\n fallbackIndex = index;\n }\n if (new RegExp(`^\\\\s*${MAX_BYTES_KEY}\\\\s*=`).test(line)) {\n if (maxBytesIndex !== -1) throw new Error(`Duplicate ${MAX_BYTES_KEY}`);\n maxBytesIndex = index;\n }\n }\n\n if (fallbackIndex !== -1) {\n const match = lines[fallbackIndex].match(\n new RegExp(`^(\\\\s*)${FALLBACK_KEY}\\\\s*=\\\\s*(\\\\[[^#]*\\\\])(\\\\s+#.*)?$`),\n );\n if (!match) throw new Error(`Cannot safely parse ${FALLBACK_KEY}`);\n const values = parseStringArray(match[2]);\n if (!values) throw new Error(`Cannot safely parse ${FALLBACK_KEY}`);\n if (!values.includes('CLAUDE.md')) {\n lines[fallbackIndex] = `${match[1]}${FALLBACK_KEY} = ${formatStringArray([\n ...values,\n 'CLAUDE.md',\n ])}${match[3] ?? ''}`;\n }\n }\n\n if (maxBytesIndex !== -1) {\n const match = lines[maxBytesIndex].match(\n new RegExp(`^(\\\\s*)${MAX_BYTES_KEY}\\\\s*=\\\\s*(\\\\d+)(\\\\s+#.*)?$`),\n );\n if (!match) throw new Error(`Cannot safely parse ${MAX_BYTES_KEY}`);\n if (Number(match[2]) < 65536) {\n lines[maxBytesIndex] = `${match[1]}${MAX_BYTES_LINE}${match[3] ?? ''}`;\n }\n }\n\n const additions = [];\n if (fallbackIndex === -1) additions.push(FALLBACK_LINE);\n if (maxBytesIndex === -1) additions.push(MAX_BYTES_LINE);\n if (additions.length > 0) {\n if (lines.length > 0 && lines[0] !== '') additions.push('');\n lines.unshift(...additions);\n }\n\n const content = `${lines.join(newline)}${newline}`;\n const normalizedOriginal = configText\n ? `${configText\n .replace(/\\r\\n|\\r|\\n/g, '\\n')\n .replace(/\\n$/, '')\n .replace(/\\n/g, newline)}${newline}`\n : '';\n return { changed: content !== normalizedOriginal, content };\n}\n\nexport function planCodexProjectSetup({\n hasClaude,\n hasAgents,\n configText,\n}: SetupInput): SetupPlan {\n if (hasClaude && hasAgents) {\n return {\n status: 'conflict',\n messages: ['CLAUDE.md와 AGENTS.md가 동시에 존재합니다. 자동 변경하지 않습니다.'],\n };\n }\n if (hasAgents) return { status: 'skip', messages: ['기존 AGENTS.md를 유지합니다.'] };\n if (!hasClaude) {\n return { status: 'skip', messages: ['CLAUDE.md가 없어 fallback을 생성하지 않습니다.'] };\n }\n\n try {\n const merged = mergeCodexConfig(configText);\n return {\n status: configText ? (merged.changed ? 'update' : 'noop') : 'create',\n messages: [\n merged.changed\n ? 'Codex fallback 설정을 준비했습니다.'\n : 'Codex fallback 설정이 이미 최신입니다.',\n ],\n configText: merged.content,\n };\n } catch (error) {\n return {\n status: 'conflict',\n messages: [\n `기존 Codex 설정을 안전하게 병합할 수 없습니다: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ],\n };\n }\n}\n\nexport function setupCodexProject({ projectDir }: { projectDir: string }): SetupPlan {\n const claudePath = path.join(projectDir, 'CLAUDE.md');\n const agentsPath = path.join(projectDir, 'AGENTS.md');\n const configPath = path.join(projectDir, '.codex', 'config.toml');\n const plan = planCodexProjectSetup({\n hasClaude: existsSync(claudePath),\n hasAgents: existsSync(agentsPath),\n configText: existsSync(configPath) ? readFileSync(configPath, 'utf8') : '',\n });\n if ((plan.status === 'create' || plan.status === 'update') && plan.configText) {\n mkdirSync(path.dirname(configPath), { recursive: true });\n writeFileSync(configPath, plan.configText);\n }\n return plan;\n}\n"],"mappings":"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","names":["path","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/setup-codex.ts","../src/cli/codex-project-config.ts"],"sourcesContent":["import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { setupCodexProject } from './codex-project-config.js';\n\nfunction parseProjectPath(args: string[]) {\n const index = args.indexOf('--project');\n if (index === -1) return process.cwd();\n if (!args[index + 1]) throw new Error('--project requires a path');\n return path.resolve(args[index + 1]);\n}\n\nexport function runSetupCodexCli(args: string[]) {\n const projectDir = parseProjectPath(args);\n const pluginRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n const result = setupCodexProject({\n projectDir,\n agentTemplatesDir: path.join(pluginRoot, 'codex-agents'),\n });\n const output = [\n `project instruction status: ${result.status}`,\n ...result.messages,\n `custom agent status: ${result.agents?.status ?? 'skip'}`,\n ...(result.agents?.messages ?? []),\n 'Marketplace registration: codex plugin marketplace add <path-to-neobiotech-marketplace>',\n 'Plugin installation: install neobiotech-dev-agent from the NeoBiotech Marketplace.',\n 'Required environment variables: JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN',\n 'Optional environment variables: XRAY_CLIENT_ID, XRAY_CLIENT_SECRET, RISK_PLUGIN_ENDPOINT, RISK_PLUGIN_AUTH_TOKEN, RISK_PLUGIN_AUTHOR',\n 'Restart Codex after Marketplace or environment changes.',\n ];\n process.stdout.write(`${output.join('\\n')}\\n`);\n return result.status === 'conflict' || result.agents?.status === 'conflict' ? 2 : 0;\n}\n\nif (process.argv[1] === fileURLToPath(import.meta.url)) {\n process.exitCode = runSetupCodexCli(process.argv.slice(2));\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport path from 'node:path';\n\nconst FALLBACK_KEY = 'project_doc_fallback_filenames';\nconst MAX_BYTES_KEY = 'project_doc_max_bytes';\nconst FALLBACK_LINE = `${FALLBACK_KEY} = [\"CLAUDE.md\"]`;\nconst MAX_BYTES_LINE = `${MAX_BYTES_KEY} = 65536`;\nconst GENERATED_AGENT_MARKER = '# Generated by neobiotech-dev-agent. Do not edit directly.';\n\nexport interface SetupInput {\n hasClaude: boolean;\n hasAgents: boolean;\n configText: string;\n}\n\nexport interface SetupPlan {\n status: 'create' | 'update' | 'noop' | 'conflict' | 'skip';\n messages: string[];\n configText?: string;\n agents?: AgentSyncReport;\n}\n\nexport interface AgentSyncReport {\n status: 'create' | 'update' | 'noop' | 'conflict' | 'skip';\n created: string[];\n updated: string[];\n unchanged: string[];\n removed: string[];\n conflicts: string[];\n messages: string[];\n}\n\nfunction parseStringArray(value: string): string[] | null {\n try {\n const parsed: unknown = JSON.parse(value);\n return Array.isArray(parsed) && parsed.every((item) => typeof item === 'string')\n ? parsed\n : null;\n } catch {\n return null;\n }\n}\n\nfunction formatStringArray(values: string[]) {\n return `[${values.map((value) => JSON.stringify(value)).join(', ')}]`;\n}\n\nexport function mergeCodexConfig(configText: string): { changed: boolean; content: string } {\n const newline = configText.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const hadTrailingNewline = configText.endsWith('\\n');\n const lines = configText ? configText.replace(/\\r\\n/g, '\\n').split('\\n') : [];\n if (hadTrailingNewline) lines.pop();\n\n let inSection = false;\n let fallbackIndex = -1;\n let maxBytesIndex = -1;\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index];\n if (/^\\s*\\[/.test(line)) inSection = true;\n if (inSection) continue;\n if (new RegExp(`^\\\\s*${FALLBACK_KEY}\\\\s*=`).test(line)) {\n if (fallbackIndex !== -1) throw new Error(`Duplicate ${FALLBACK_KEY}`);\n fallbackIndex = index;\n }\n if (new RegExp(`^\\\\s*${MAX_BYTES_KEY}\\\\s*=`).test(line)) {\n if (maxBytesIndex !== -1) throw new Error(`Duplicate ${MAX_BYTES_KEY}`);\n maxBytesIndex = index;\n }\n }\n\n if (fallbackIndex !== -1) {\n const match = lines[fallbackIndex].match(\n new RegExp(`^(\\\\s*)${FALLBACK_KEY}\\\\s*=\\\\s*(\\\\[[^#]*\\\\])(\\\\s+#.*)?$`),\n );\n if (!match) throw new Error(`Cannot safely parse ${FALLBACK_KEY}`);\n const values = parseStringArray(match[2]);\n if (!values) throw new Error(`Cannot safely parse ${FALLBACK_KEY}`);\n if (!values.includes('CLAUDE.md')) {\n lines[fallbackIndex] = `${match[1]}${FALLBACK_KEY} = ${formatStringArray([\n ...values,\n 'CLAUDE.md',\n ])}${match[3] ?? ''}`;\n }\n }\n\n if (maxBytesIndex !== -1) {\n const match = lines[maxBytesIndex].match(\n new RegExp(`^(\\\\s*)${MAX_BYTES_KEY}\\\\s*=\\\\s*(\\\\d+)(\\\\s+#.*)?$`),\n );\n if (!match) throw new Error(`Cannot safely parse ${MAX_BYTES_KEY}`);\n if (Number(match[2]) < 65536) {\n lines[maxBytesIndex] = `${match[1]}${MAX_BYTES_LINE}${match[3] ?? ''}`;\n }\n }\n\n const additions = [];\n if (fallbackIndex === -1) additions.push(FALLBACK_LINE);\n if (maxBytesIndex === -1) additions.push(MAX_BYTES_LINE);\n if (additions.length > 0) {\n if (lines.length > 0 && lines[0] !== '') additions.push('');\n lines.unshift(...additions);\n }\n\n const content = `${lines.join(newline)}${newline}`;\n const normalizedOriginal = configText\n ? `${configText\n .replace(/\\r\\n|\\r|\\n/g, '\\n')\n .replace(/\\n$/, '')\n .replace(/\\n/g, newline)}${newline}`\n : '';\n return { changed: content !== normalizedOriginal, content };\n}\n\nexport function planCodexProjectSetup({\n hasClaude,\n hasAgents,\n configText,\n}: SetupInput): SetupPlan {\n if (hasClaude && hasAgents) {\n return {\n status: 'conflict',\n messages: ['CLAUDE.md와 AGENTS.md가 동시에 존재합니다. 자동 변경하지 않습니다.'],\n };\n }\n if (hasAgents) return { status: 'skip', messages: ['기존 AGENTS.md를 유지합니다.'] };\n if (!hasClaude) {\n return { status: 'skip', messages: ['CLAUDE.md가 없어 fallback을 생성하지 않습니다.'] };\n }\n\n try {\n const merged = mergeCodexConfig(configText);\n return {\n status: configText ? (merged.changed ? 'update' : 'noop') : 'create',\n messages: [\n merged.changed\n ? 'Codex fallback 설정을 준비했습니다.'\n : 'Codex fallback 설정이 이미 최신입니다.',\n ],\n configText: merged.content,\n };\n } catch (error) {\n return {\n status: 'conflict',\n messages: [\n `기존 Codex 설정을 안전하게 병합할 수 없습니다: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ],\n };\n }\n}\n\nexport function syncCodexAgents({\n projectDir,\n templatesDir,\n}: {\n projectDir: string;\n templatesDir?: string;\n}): AgentSyncReport {\n const emptyReport = {\n created: [],\n updated: [],\n unchanged: [],\n removed: [],\n conflicts: [],\n };\n if (!templatesDir || !existsSync(templatesDir)) {\n return {\n ...emptyReport,\n status: 'skip',\n messages: ['Codex custom agent 템플릿을 찾지 못해 동기화를 건너뜁니다.'],\n };\n }\n\n const templateNames = readdirSync(templatesDir)\n .filter((name) => name.endsWith('.toml'))\n .sort();\n const targetDir = path.join(projectDir, '.codex', 'agents');\n const report: AgentSyncReport = {\n ...emptyReport,\n status: 'noop',\n messages: [],\n };\n\n for (const name of templateNames) {\n const source = readFileSync(path.join(templatesDir, name), 'utf8');\n const targetPath = path.join(targetDir, name);\n if (!existsSync(targetPath)) {\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(targetPath, source);\n report.created.push(name);\n continue;\n }\n\n const current = readFileSync(targetPath, 'utf8');\n if (current === source) {\n report.unchanged.push(name);\n } else if (current.startsWith(GENERATED_AGENT_MARKER)) {\n writeFileSync(targetPath, source);\n report.updated.push(name);\n } else {\n report.conflicts.push(name);\n }\n }\n\n if (existsSync(targetDir)) {\n for (const name of readdirSync(targetDir).filter((entry) => entry.endsWith('.toml')).sort()) {\n if (templateNames.includes(name)) continue;\n const targetPath = path.join(targetDir, name);\n if (readFileSync(targetPath, 'utf8').startsWith(GENERATED_AGENT_MARKER)) {\n unlinkSync(targetPath);\n report.removed.push(name);\n }\n }\n }\n\n if (report.conflicts.length > 0) report.status = 'conflict';\n else if (report.updated.length > 0 || report.removed.length > 0) report.status = 'update';\n else if (report.created.length > 0) report.status = 'create';\n report.messages.push(\n report.status === 'conflict'\n ? `사용자 관리 custom agent와 충돌했습니다: ${report.conflicts.join(', ')}`\n : `Codex custom agent 동기화: 생성 ${report.created.length}, 갱신 ${report.updated.length}, 유지 ${report.unchanged.length}, 제거 ${report.removed.length}`,\n );\n return report;\n}\n\nexport function setupCodexProject({\n projectDir,\n agentTemplatesDir,\n}: {\n projectDir: string;\n agentTemplatesDir?: string;\n}): SetupPlan {\n const claudePath = path.join(projectDir, 'CLAUDE.md');\n const agentsPath = path.join(projectDir, 'AGENTS.md');\n const configPath = path.join(projectDir, '.codex', 'config.toml');\n const plan = planCodexProjectSetup({\n hasClaude: existsSync(claudePath),\n hasAgents: existsSync(agentsPath),\n configText: existsSync(configPath) ? readFileSync(configPath, 'utf8') : '',\n });\n if ((plan.status === 'create' || plan.status === 'update') && plan.configText) {\n mkdirSync(path.dirname(configPath), { recursive: true });\n writeFileSync(configPath, plan.configText);\n }\n return {\n ...plan,\n agents: syncCodexAgents({ projectDir, templatesDir: agentTemplatesDir }),\n };\n}\n"],"mappings":"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","names":["path","path"]}
|