ai-ops-cli 0.1.5 → 0.1.8
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/bin/index.js +88 -33
- package/dist/bin/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/index.js
CHANGED
|
@@ -80,24 +80,42 @@ var listWorkspaceCandidates = (basePath) => {
|
|
|
80
80
|
// src/lib/install.ts
|
|
81
81
|
import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
82
82
|
import { dirname, resolve as resolve3 } from "path";
|
|
83
|
-
import {
|
|
84
|
-
|
|
83
|
+
import {
|
|
84
|
+
isManagedFile,
|
|
85
|
+
hasAiOpsSection,
|
|
86
|
+
wrapWithSection,
|
|
87
|
+
replaceAiOpsSection,
|
|
88
|
+
stripManagedHeader
|
|
89
|
+
} from "ai-ops-compiler";
|
|
90
|
+
var installFiles = (basePath, actions, meta) => {
|
|
85
91
|
const written = [];
|
|
92
|
+
const appended = [];
|
|
86
93
|
const skipped = [];
|
|
87
94
|
for (const action of actions) {
|
|
88
95
|
const absPath = resolve3(basePath, action.relativePath);
|
|
89
96
|
if (existsSync2(absPath)) {
|
|
90
97
|
const existing = readFileSync(absPath, "utf-8");
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
if (isManagedFile(existing)) {
|
|
99
|
+
writeFileSync(absPath, action.content, "utf-8");
|
|
100
|
+
written.push(action.relativePath);
|
|
101
|
+
} else if (hasAiOpsSection(existing)) {
|
|
102
|
+
const sectionContent = wrapWithSection(stripManagedHeader(action.content), meta);
|
|
103
|
+
const updated = replaceAiOpsSection(existing, sectionContent);
|
|
104
|
+
writeFileSync(absPath, updated, "utf-8");
|
|
105
|
+
appended.push(action.relativePath);
|
|
106
|
+
} else {
|
|
107
|
+
const sectionContent = wrapWithSection(stripManagedHeader(action.content), meta);
|
|
108
|
+
const updated = existing.trimEnd() + "\n\n" + sectionContent + "\n";
|
|
109
|
+
writeFileSync(absPath, updated, "utf-8");
|
|
110
|
+
appended.push(action.relativePath);
|
|
94
111
|
}
|
|
112
|
+
} else {
|
|
113
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
114
|
+
writeFileSync(absPath, action.content, "utf-8");
|
|
115
|
+
written.push(action.relativePath);
|
|
95
116
|
}
|
|
96
|
-
mkdirSync(dirname(absPath), { recursive: true });
|
|
97
|
-
writeFileSync(absPath, action.content, "utf-8");
|
|
98
|
-
written.push(action.relativePath);
|
|
99
117
|
}
|
|
100
|
-
return { written, skipped };
|
|
118
|
+
return { written, appended, skipped };
|
|
101
119
|
};
|
|
102
120
|
|
|
103
121
|
// src/lib/gemini-settings.ts
|
|
@@ -227,6 +245,7 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules) => {
|
|
|
227
245
|
var installHierarchicalMonorepo = (toolId, mappings, basePath, meta) => {
|
|
228
246
|
const config = TOOL_OUTPUT_MAP[toolId];
|
|
229
247
|
const written = [];
|
|
248
|
+
const appended = [];
|
|
230
249
|
const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));
|
|
231
250
|
const { global } = partitionRules(allRules);
|
|
232
251
|
if (global.length > 0) {
|
|
@@ -234,7 +253,9 @@ var installHierarchicalMonorepo = (toolId, mappings, basePath, meta) => {
|
|
|
234
253
|
relativePath: join4(config.dir, config.rootFileName),
|
|
235
254
|
content: wrapWithHeader(renderRulesToMarkdown(global), meta)
|
|
236
255
|
};
|
|
237
|
-
|
|
256
|
+
const r = installFiles(basePath, [rootAction], meta);
|
|
257
|
+
written.push(...r.written);
|
|
258
|
+
appended.push(...r.appended);
|
|
238
259
|
}
|
|
239
260
|
for (const mapping of mappings) {
|
|
240
261
|
const { domain } = partitionRules(mapping.finalRules);
|
|
@@ -243,19 +264,22 @@ var installHierarchicalMonorepo = (toolId, mappings, basePath, meta) => {
|
|
|
243
264
|
relativePath: join4(mapping.workspace, config.domainFileName),
|
|
244
265
|
content: wrapWithHeader(renderRulesToMarkdown(domain), meta)
|
|
245
266
|
};
|
|
246
|
-
|
|
267
|
+
const r = installFiles(basePath, [domainAction], meta);
|
|
268
|
+
written.push(...r.written);
|
|
269
|
+
appended.push(...r.appended);
|
|
247
270
|
}
|
|
248
|
-
return written;
|
|
271
|
+
return { written, appended };
|
|
249
272
|
};
|
|
250
273
|
var installClaudeCodeMonorepo = (mappings, basePath, meta) => {
|
|
251
274
|
const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));
|
|
252
275
|
const workspaceMappings = mappings.map((m) => ({
|
|
253
276
|
path: m.workspace,
|
|
254
|
-
ruleIds: m.finalRules.map((
|
|
277
|
+
ruleIds: m.finalRules.map((r2) => r2.id)
|
|
255
278
|
}));
|
|
256
279
|
const renderResult = renderForTool("claude-code", allRules, workspaceMappings);
|
|
257
280
|
const actions = buildInstallPlan({ toolId: "claude-code", renderResult, meta });
|
|
258
|
-
|
|
281
|
+
const r = installFiles(basePath, actions, meta);
|
|
282
|
+
return { written: r.written, appended: r.appended };
|
|
259
283
|
};
|
|
260
284
|
var initCommand = async (opts) => {
|
|
261
285
|
const basePath = resolveBasePath(opts.scope);
|
|
@@ -313,21 +337,25 @@ var initCommand = async (opts) => {
|
|
|
313
337
|
const s = p2.spinner();
|
|
314
338
|
s.start("\uADDC\uCE59 \uC124\uCE58 \uC911...");
|
|
315
339
|
const meta = { sourceHash, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
316
|
-
const allSkipped = [];
|
|
317
340
|
const allInstalledFiles = [];
|
|
341
|
+
const allAppended = [];
|
|
318
342
|
for (const toolId of selectedTools) {
|
|
319
343
|
if (isMonorepo) {
|
|
320
344
|
if (toolId === "claude-code") {
|
|
321
|
-
|
|
345
|
+
const stats = installClaudeCodeMonorepo(mappings, basePath, meta);
|
|
346
|
+
allInstalledFiles.push(...stats.written);
|
|
347
|
+
allAppended.push(...stats.appended);
|
|
322
348
|
} else {
|
|
323
|
-
|
|
349
|
+
const stats = installHierarchicalMonorepo(toolId, mappings, basePath, meta);
|
|
350
|
+
allInstalledFiles.push(...stats.written);
|
|
351
|
+
allAppended.push(...stats.appended);
|
|
324
352
|
}
|
|
325
353
|
} else {
|
|
326
354
|
const renderResult = renderForTool(toolId, mappings[0].finalRules);
|
|
327
355
|
const actions = buildInstallPlan({ toolId, renderResult, meta });
|
|
328
|
-
const result = installFiles(basePath, actions);
|
|
329
|
-
allSkipped.push(...result.skipped);
|
|
356
|
+
const result = installFiles(basePath, actions, meta);
|
|
330
357
|
allInstalledFiles.push(...result.written);
|
|
358
|
+
allAppended.push(...result.appended);
|
|
331
359
|
}
|
|
332
360
|
}
|
|
333
361
|
if (geminiSettingValues && geminiSettingValues.length > 0) {
|
|
@@ -346,12 +374,13 @@ var initCommand = async (opts) => {
|
|
|
346
374
|
workspaces: workspacesRecord,
|
|
347
375
|
installedRules: allInstalledRuleIds,
|
|
348
376
|
installedFiles: allInstalledFiles,
|
|
377
|
+
appendedFiles: allAppended,
|
|
349
378
|
sourceHash
|
|
350
379
|
});
|
|
351
380
|
writeManifest(resolveManifestPath(basePath), manifest);
|
|
352
|
-
if (
|
|
353
|
-
p2.log.
|
|
354
|
-
${
|
|
381
|
+
if (allAppended.length > 0) {
|
|
382
|
+
p2.log.info(`\uAE30\uC874 \uD30C\uC77C\uC5D0 \uC139\uC158 \uCD94\uAC00\uB428 (\uB0B4\uC6A9 \uBCF4\uC874):
|
|
383
|
+
${allAppended.map((f) => ` ${f}`).join("\n")}`);
|
|
355
384
|
}
|
|
356
385
|
p2.log.success(`\uC124\uCE58\uB41C \uADDC\uCE59: ${allInstalledRuleIds.length}\uAC1C`);
|
|
357
386
|
p2.outro("ai-ops init \uC644\uB8CC");
|
|
@@ -401,20 +430,23 @@ var updateCommand = async (opts) => {
|
|
|
401
430
|
const allRules = loadAllRules2(rulesDir);
|
|
402
431
|
const meta = { sourceHash, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
403
432
|
const allInstalledFiles = [];
|
|
433
|
+
const allAppended = [];
|
|
404
434
|
if (manifest.workspaces) {
|
|
405
435
|
const workspaceEntries = Object.entries(manifest.workspaces);
|
|
406
436
|
for (const toolIdStr of manifest.tools) {
|
|
407
437
|
const toolId = toolIdStr;
|
|
408
438
|
if (toolId === "claude-code") {
|
|
409
439
|
const allInstalledRuleSet = new Set(manifest.installed_rules);
|
|
410
|
-
const rulesToInstall = allRules.filter((
|
|
440
|
+
const rulesToInstall = allRules.filter((r2) => allInstalledRuleSet.has(r2.id));
|
|
411
441
|
const workspaceMappings = Object.entries(manifest.workspaces).map(([path, entry]) => ({
|
|
412
442
|
path,
|
|
413
443
|
ruleIds: entry.rules
|
|
414
444
|
}));
|
|
415
445
|
const renderResult = renderForTool2("claude-code", rulesToInstall, workspaceMappings);
|
|
416
446
|
const actions = buildInstallPlan2({ toolId: "claude-code", renderResult, meta });
|
|
417
|
-
|
|
447
|
+
const r = installFiles(basePath, actions, meta);
|
|
448
|
+
allInstalledFiles.push(...r.written);
|
|
449
|
+
allAppended.push(...r.appended);
|
|
418
450
|
} else {
|
|
419
451
|
const config = TOOL_OUTPUT_MAP2[toolId];
|
|
420
452
|
const allInstalledRuleSet = new Set(manifest.installed_rules);
|
|
@@ -425,18 +457,22 @@ var updateCommand = async (opts) => {
|
|
|
425
457
|
relativePath: join5(config.dir, config.rootFileName),
|
|
426
458
|
content: wrapWithHeader2(renderRulesToMarkdown2(global), meta)
|
|
427
459
|
};
|
|
428
|
-
|
|
460
|
+
const r = installFiles(basePath, [rootAction], meta);
|
|
461
|
+
allInstalledFiles.push(...r.written);
|
|
462
|
+
allAppended.push(...r.appended);
|
|
429
463
|
}
|
|
430
464
|
for (const [ws, entry] of workspaceEntries) {
|
|
431
465
|
const wsRuleSet = new Set(entry.rules);
|
|
432
|
-
const wsRules = allRules.filter((
|
|
466
|
+
const wsRules = allRules.filter((r2) => wsRuleSet.has(r2.id));
|
|
433
467
|
const { domain } = partitionRules2(wsRules);
|
|
434
468
|
if (domain.length === 0) continue;
|
|
435
469
|
const domainAction = {
|
|
436
470
|
relativePath: join5(ws, config.domainFileName),
|
|
437
471
|
content: wrapWithHeader2(renderRulesToMarkdown2(domain), meta)
|
|
438
472
|
};
|
|
439
|
-
|
|
473
|
+
const r = installFiles(basePath, [domainAction], meta);
|
|
474
|
+
allInstalledFiles.push(...r.written);
|
|
475
|
+
allAppended.push(...r.appended);
|
|
440
476
|
}
|
|
441
477
|
}
|
|
442
478
|
}
|
|
@@ -447,7 +483,9 @@ var updateCommand = async (opts) => {
|
|
|
447
483
|
const toolId = toolIdStr;
|
|
448
484
|
const renderResult = renderForTool2(toolId, rulesToInstall);
|
|
449
485
|
const actions = buildInstallPlan2({ toolId, renderResult, meta });
|
|
450
|
-
|
|
486
|
+
const r = installFiles(basePath, actions, meta);
|
|
487
|
+
allInstalledFiles.push(...r.written);
|
|
488
|
+
allAppended.push(...r.appended);
|
|
451
489
|
}
|
|
452
490
|
}
|
|
453
491
|
const newManifest = buildManifest2({
|
|
@@ -457,6 +495,7 @@ var updateCommand = async (opts) => {
|
|
|
457
495
|
workspaces: manifest.workspaces,
|
|
458
496
|
installedRules: manifest.installed_rules,
|
|
459
497
|
installedFiles: allInstalledFiles.length > 0 ? allInstalledFiles : manifest.installed_files,
|
|
498
|
+
appendedFiles: allAppended.length > 0 ? allAppended : manifest.appended_files,
|
|
460
499
|
sourceHash
|
|
461
500
|
});
|
|
462
501
|
writeManifest2(manifestPath, newManifest);
|
|
@@ -503,11 +542,12 @@ import { rmSync as rmSync2 } from "fs";
|
|
|
503
542
|
import { readManifest as readManifest3, resolveManifestPath as resolveManifestPath4, inferInstalledFiles, MANIFEST_FILENAME } from "ai-ops-compiler";
|
|
504
543
|
|
|
505
544
|
// src/lib/uninstall.ts
|
|
506
|
-
import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, readdirSync as readdirSync2 } from "fs";
|
|
545
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
507
546
|
import { resolve as resolve4, dirname as dirname2 } from "path";
|
|
508
|
-
import { isManagedFile as isManagedFile2 } from "ai-ops-compiler";
|
|
547
|
+
import { isManagedFile as isManagedFile2, hasAiOpsSection as hasAiOpsSection2, stripAiOpsSection } from "ai-ops-compiler";
|
|
509
548
|
var removeFiles = (basePath, relativePaths) => {
|
|
510
549
|
const deleted = [];
|
|
550
|
+
const cleaned = [];
|
|
511
551
|
const skipped = [];
|
|
512
552
|
const notFound = [];
|
|
513
553
|
for (const rel of relativePaths) {
|
|
@@ -518,13 +558,19 @@ var removeFiles = (basePath, relativePaths) => {
|
|
|
518
558
|
}
|
|
519
559
|
const content = readFileSync3(absPath, "utf-8");
|
|
520
560
|
if (!isManagedFile2(content)) {
|
|
521
|
-
|
|
561
|
+
if (hasAiOpsSection2(content)) {
|
|
562
|
+
const stripped = stripAiOpsSection(content);
|
|
563
|
+
writeFileSync3(absPath, stripped, "utf-8");
|
|
564
|
+
cleaned.push(rel);
|
|
565
|
+
} else {
|
|
566
|
+
skipped.push(rel);
|
|
567
|
+
}
|
|
522
568
|
continue;
|
|
523
569
|
}
|
|
524
570
|
rmSync(absPath);
|
|
525
571
|
deleted.push(rel);
|
|
526
572
|
}
|
|
527
|
-
return { deleted, skipped, notFound };
|
|
573
|
+
return { deleted, cleaned, skipped, notFound };
|
|
528
574
|
};
|
|
529
575
|
var cleanEmptyDirs = (basePath, dirs) => {
|
|
530
576
|
const removed = [];
|
|
@@ -563,7 +609,10 @@ var uninstallCommand = async (opts) => {
|
|
|
563
609
|
p5.log.error("manifest\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 ai-ops init\uC744 \uC2E4\uD589\uD558\uC138\uC694.");
|
|
564
610
|
process.exit(1);
|
|
565
611
|
}
|
|
566
|
-
const targetFiles =
|
|
612
|
+
const targetFiles = [
|
|
613
|
+
...manifest.installed_files ?? inferInstalledFiles(manifest),
|
|
614
|
+
...manifest.appended_files ?? []
|
|
615
|
+
];
|
|
567
616
|
if (targetFiles.length === 0) {
|
|
568
617
|
p5.log.warn("\uC0AD\uC81C\uD560 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
569
618
|
p5.outro("ai-ops uninstall \uC644\uB8CC");
|
|
@@ -587,6 +636,12 @@ ${targetFiles.map((f) => ` ${f}`).join("\n")}`);
|
|
|
587
636
|
p5.log.success(`\uC0AD\uC81C \uC644\uB8CC (${result.deleted.length}\uAC1C):
|
|
588
637
|
${result.deleted.map((f) => ` ${f}`).join("\n")}`);
|
|
589
638
|
}
|
|
639
|
+
if (result.cleaned.length > 0) {
|
|
640
|
+
p5.log.success(
|
|
641
|
+
`\uC139\uC158 \uC81C\uAC70 \uC644\uB8CC (\uC0AC\uC6A9\uC790 \uB0B4\uC6A9 \uBCF4\uC874, ${result.cleaned.length}\uAC1C):
|
|
642
|
+
${result.cleaned.map((f) => ` ${f}`).join("\n")}`
|
|
643
|
+
);
|
|
644
|
+
}
|
|
590
645
|
if (result.skipped.length > 0) {
|
|
591
646
|
p5.log.warn(
|
|
592
647
|
`\uAC74\uB108\uB700 (non-managed \uD30C\uC77C \uBCF4\uD638, ${result.skipped.length}\uAC1C):
|
package/dist/bin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/index.ts","../../src/commands/init.ts","../../src/lib/paths.ts","../../src/lib/workspace.ts","../../src/lib/install.ts","../../src/lib/gemini-settings.ts","../../src/commands/update.ts","../../src/commands/diff.ts","../../src/commands/uninstall.ts","../../src/lib/uninstall.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { initCommand } from '../commands/init.js';\nimport { updateCommand } from '../commands/update.js';\nimport { diffCommand } from '../commands/diff.js';\nimport { uninstallCommand } from '../commands/uninstall.js';\nimport type { Scope } from '../lib/paths.js';\n\nconst program = new Command();\n\nprogram.name('ai-ops').description('AI 에이전트 규칙 스캐폴더').version('0.1.0');\n\nprogram\n .command('init')\n .description('AI 규칙 초기 설치')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => initCommand(opts));\n\nprogram\n .command('update')\n .description('기존 manifest 기반 규칙 갱신')\n .option('--scope <scope>', 'project | global', 'project')\n .option('--force', '변경 없어도 강제 재설치', false)\n .action((opts: { scope: Scope; force: boolean }) => updateCommand(opts));\n\nprogram\n .command('diff')\n .description('설치된 규칙과 최신 소스 비교')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => diffCommand(opts));\n\nprogram\n .command('uninstall')\n .description('설치된 규칙 파일 및 manifest 제거')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => uninstallCommand(opts));\n\nprogram.parse();\n","import * as p from '@clack/prompts';\nimport { join } from 'node:path';\nimport type { Rule, Preset, ToolId, WorkspaceMapping } from 'ai-ops-compiler';\nimport {\n loadAllRules,\n loadPresets,\n resolvePresetRules,\n excludeRules,\n isGlobalRule,\n partitionRules,\n renderForTool,\n renderRulesToMarkdown,\n buildInstallPlan,\n buildManifest,\n computeSourceHash,\n resolveManifestPath,\n writeManifest,\n wrapWithHeader,\n TOOL_OUTPUT_MAP,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir, resolvePresetsPath } from '../lib/paths.js';\nimport { listWorkspaceCandidates } from '../lib/workspace.js';\nimport { installFiles } from '../lib/install.js';\nimport { promptGeminiSettings, installGeminiSettings } from '../lib/gemini-settings.js';\n\ntype WorkspacePresetMapping = {\n workspace: string;\n preset: Preset;\n finalRules: Rule[];\n};\n\nconst TOOL_OPTIONS = [\n { value: 'claude-code' as ToolId, label: 'Claude Code' },\n { value: 'codex' as ToolId, label: 'Codex' },\n { value: 'gemini' as ToolId, label: 'Gemini CLI' },\n];\n\nconst deduplicateRules = (rules: readonly Rule[]): Rule[] => {\n const seen = new Set<string>();\n return rules.filter((r) => {\n if (seen.has(r.id)) return false;\n seen.add(r.id);\n return true;\n });\n};\n\nconst selectPresetAndFineTune = async (\n workspaceName: string,\n presets: readonly Preset[],\n allRules: readonly Rule[],\n): Promise<WorkspacePresetMapping | null> => {\n const preset = await p.select<Preset>({\n message: `[${workspaceName}] 프리셋을 선택하세요`,\n options: presets.map((pr) => ({\n value: pr,\n label: pr.id,\n hint: pr.description,\n })),\n });\n if (p.isCancel(preset)) return null;\n\n const presetRules = resolvePresetRules(preset, allRules);\n const globalRules = presetRules.filter(isGlobalRule);\n const domainRules = presetRules.filter((r) => !isGlobalRule(r));\n\n // Global rules: locked (항상 포함)\n if (globalRules.length > 0) {\n p.note(globalRules.map((r) => ` ✓ ${r.id}`).join('\\n'), `[${workspaceName}] 기본 규칙 (잠금)`);\n }\n\n if (domainRules.length === 0) {\n return { workspace: workspaceName, preset, finalRules: presetRules };\n }\n\n // Domain rules: 제외 가능\n const selectedDomain = await p.multiselect<string>({\n message: `[${workspaceName}] 도메인 규칙 선택 (해제하여 제외)`,\n options: domainRules.map((r) => ({ value: r.id, label: r.id })),\n initialValues: domainRules.map((r) => r.id),\n required: false,\n });\n if (p.isCancel(selectedDomain)) return null;\n\n const excludeIds = domainRules.map((r) => r.id).filter((id) => !(selectedDomain as string[]).includes(id));\n\n return { workspace: workspaceName, preset, finalRules: excludeRules(presetRules, excludeIds) };\n};\n\nconst installHierarchicalMonorepo = (\n toolId: 'codex' | 'gemini',\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): string[] => {\n const config = TOOL_OUTPUT_MAP[toolId];\n const written: string[] = [];\n\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const { global } = partitionRules(allRules);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n written.push(...installFiles(basePath, [rootAction]).written);\n }\n\n for (const mapping of mappings) {\n const { domain } = partitionRules(mapping.finalRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(mapping.workspace, config.domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n written.push(...installFiles(basePath, [domainAction]).written);\n }\n\n return written;\n};\n\nconst installClaudeCodeMonorepo = (\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): string[] => {\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const workspaceMappings: WorkspaceMapping[] = mappings.map((m) => ({\n path: m.workspace,\n ruleIds: m.finalRules.map((r) => r.id),\n }));\n const renderResult = renderForTool('claude-code', allRules, workspaceMappings);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n return installFiles(basePath, actions).written;\n};\n\nexport const initCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const rulesDir = resolveRulesDir();\n\n p.intro('ai-ops init');\n\n // 1. AI 도구 다중 선택\n const selectedTools = await p.multiselect<ToolId>({\n message: 'AI 도구를 선택하세요',\n options: TOOL_OPTIONS,\n required: true,\n });\n if (p.isCancel(selectedTools)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 2. 모노레포 여부\n const isMonorepo = await p.confirm({\n message: '모노레포 프로젝트입니까?',\n initialValue: false,\n });\n if (p.isCancel(isMonorepo)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 3. 데이터 로드\n const allRules = loadAllRules(rulesDir);\n const presets = loadPresets(resolvePresetsPath());\n const sourceHash = computeSourceHash(rulesDir);\n\n // 4. 워크스페이스별 preset 선택 + fine-tune\n const mappings: WorkspacePresetMapping[] = [];\n\n if (!isMonorepo) {\n const mapping = await selectPresetAndFineTune('.', presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n } else {\n const candidates = listWorkspaceCandidates(basePath);\n const selectedWorkspaces = await p.multiselect<string>({\n message: '워크스페이스를 선택하세요',\n options: candidates.map((c) => ({ value: c, label: c })),\n required: true,\n });\n if (p.isCancel(selectedWorkspaces)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n for (const ws of selectedWorkspaces as string[]) {\n const mapping = await selectPresetAndFineTune(ws, presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n }\n }\n\n // 4.5. Gemini 설정 (gemini 선택 시)\n const geminiSettingValues: readonly string[] | null = (selectedTools as ToolId[]).includes('gemini')\n ? await promptGeminiSettings()\n : null;\n\n // 5. 설치\n const s = p.spinner();\n s.start('규칙 설치 중...');\n\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n const allSkipped: string[] = [];\n const allInstalledFiles: string[] = [];\n\n for (const toolId of selectedTools as ToolId[]) {\n if (isMonorepo) {\n if (toolId === 'claude-code') {\n allInstalledFiles.push(...installClaudeCodeMonorepo(mappings, basePath, meta));\n } else {\n allInstalledFiles.push(...installHierarchicalMonorepo(toolId, mappings, basePath, meta));\n }\n } else {\n const renderResult = renderForTool(toolId, mappings[0].finalRules);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n const result = installFiles(basePath, actions);\n allSkipped.push(...result.skipped);\n allInstalledFiles.push(...result.written);\n }\n }\n\n if (geminiSettingValues && geminiSettingValues.length > 0) {\n installGeminiSettings(basePath, geminiSettingValues);\n allInstalledFiles.push('.gemini/settings.json');\n }\n\n s.stop('규칙 설치 완료');\n\n // 6. Manifest 저장\n const allInstalledRuleIds = deduplicateRules(mappings.flatMap((m) => m.finalRules)).map((r) => r.id);\n\n const workspacesRecord = isMonorepo\n ? Object.fromEntries(\n mappings.map((m) => [m.workspace, { preset: m.preset.id, rules: m.finalRules.map((r) => r.id) }]),\n )\n : undefined;\n\n const manifest = buildManifest({\n tools: selectedTools as string[],\n scope: opts.scope,\n preset: !isMonorepo ? mappings[0].preset.id : undefined,\n workspaces: workspacesRecord,\n installedRules: allInstalledRuleIds,\n installedFiles: allInstalledFiles,\n sourceHash,\n });\n writeManifest(resolveManifestPath(basePath), manifest);\n\n // 7. 결과 요약\n if (allSkipped.length > 0) {\n p.log.warn(`충돌(non-managed) 파일 건너뜀:\\n${allSkipped.map((f) => ` ${f}`).join('\\n')}`);\n }\n p.log.success(`설치된 규칙: ${allInstalledRuleIds.length}개`);\n p.outro('ai-ops init 완료');\n};\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { COMPILER_DATA_DIR } from 'ai-ops-compiler';\n\nexport type Scope = 'project' | 'global';\n\nexport const resolveCompilerDataDir = (): string => COMPILER_DATA_DIR;\n\nexport const resolveRulesDir = (): string => join(COMPILER_DATA_DIR, 'rules');\n\nexport const resolvePresetsPath = (): string => join(COMPILER_DATA_DIR, 'presets.yaml');\n\n// scope에 따른 설치 기준 디렉토리\nexport const resolveBasePath = (scope: Scope): string =>\n scope === 'global' ? resolve(homedir(), '.ai-ops') : process.cwd();\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nconst EXCLUDE_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.turbo', '.cache', 'coverage']);\n\nconst isVisibleDir = (basePath: string, name: string): boolean => {\n if (name.startsWith('.') || EXCLUDE_DIRS.has(name)) return false;\n return statSync(resolve(basePath, name)).isDirectory();\n};\n\n// Project manifest files that indicate a workspace root\nconst PROJECT_MANIFESTS = [\n 'package.json', // Node.js / JS / TS\n 'pubspec.yaml', // Flutter / Dart\n 'pyproject.toml', // Python (modern)\n 'setup.py', // Python (legacy)\n 'Cargo.toml', // Rust\n 'go.mod', // Go\n];\n\nconst isWorkspaceRoot = (dirPath: string): boolean => PROJECT_MANIFESTS.some((f) => existsSync(join(dirPath, f)));\n\n// 프로젝트 매니페스트 파일 존재 여부로 워크스페이스 판별:\n// 1. top-level dir에 매니페스트 → 그 자체가 워크스페이스 (e.g. backend-ts, mobile, web)\n// 2. top-level dir에 매니페스트 없고 자식에 있음 → 자식을 후보로 (e.g. apps/web, packages/ui)\n// 3. 매니페스트 없는 경우 → 1-depth 그대로\nexport const listWorkspaceCandidates = (basePath: string): string[] => {\n const topLevel = readdirSync(basePath).filter((name) => isVisibleDir(basePath, name));\n\n const candidates: string[] = [];\n for (const dir of topLevel) {\n const subPath = resolve(basePath, dir);\n if (isWorkspaceRoot(subPath)) {\n candidates.push(dir);\n } else {\n const children = readdirSync(subPath).filter((name) => isVisibleDir(subPath, name));\n const wsChildren = children.filter((name) => isWorkspaceRoot(resolve(subPath, name)));\n if (wsChildren.length > 0) {\n for (const child of wsChildren) {\n candidates.push(join(dir, child));\n }\n } else {\n candidates.push(dir);\n }\n }\n }\n\n return candidates.sort();\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { isManagedFile } from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\n\nexport type InstallResult = {\n written: string[];\n skipped: string[]; // 기존 파일이 managed가 아닌 경우 (사용자 파일 보호)\n};\n\nexport const installFiles = (basePath: string, actions: readonly FileAction[]): InstallResult => {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const action of actions) {\n const absPath = resolve(basePath, action.relativePath);\n\n if (existsSync(absPath)) {\n const existing = readFileSync(absPath, 'utf-8');\n if (!isManagedFile(existing)) {\n skipped.push(action.relativePath);\n continue;\n }\n }\n\n mkdirSync(dirname(absPath), { recursive: true });\n writeFileSync(absPath, action.content, 'utf-8');\n written.push(action.relativePath);\n }\n\n return { written, skipped };\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\ntype GeminiSettings = {\n ui?: { showLineNumbers?: boolean };\n general?: {\n plan?: { directory?: string; modelRouting?: boolean };\n sessionRetention?: { maxAge?: string };\n };\n experimental?: { jitContext?: boolean; plan?: boolean };\n};\n\ntype SettingGroup = {\n value: string;\n label: string;\n hint: string;\n patch: GeminiSettings;\n};\n\nconst SETTING_GROUPS: readonly SettingGroup[] = [\n {\n value: 'ui',\n label: 'UI — 줄 번호 숨기기',\n hint: 'ui.showLineNumbers: false — 코드 복사 시 줄 번호가 포함되지 않도록 비활성화',\n patch: { ui: { showLineNumbers: false } },\n },\n {\n value: 'plan',\n label: 'Plan — 계획 파일 저장 및 모델 라우팅',\n hint: 'general.plan.directory: .gemini/plans, modelRouting: true — AI 계획을 파일로 저장하고 태스크별 최적 모델 자동 선택',\n patch: { general: { plan: { directory: '.gemini/plans', modelRouting: true } } },\n },\n {\n value: 'sessionRetention',\n label: 'Session Retention — 세션 30일 보존',\n hint: 'general.sessionRetention.maxAge: 30d — 이전 대화 컨텍스트를 30일간 유지',\n patch: { general: { sessionRetention: { maxAge: '30d' } } },\n },\n {\n value: 'experimental',\n label: 'Experimental — JIT 컨텍스트 + Plan 기능',\n hint: 'experimental.jitContext: true, plan: true — 서브디렉토리 컨텍스트 지연 로딩 및 계획 기능 실험적 활성화',\n patch: { experimental: { jitContext: true, plan: true } },\n },\n];\n\nconst deepMerge = (base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown> => {\n const result = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n typeof result[key] === 'object' &&\n result[key] !== null\n ) {\n result[key] = deepMerge(result[key] as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n};\n\n// null → 건너뜀 (취소 또는 \"No\"), string[] → 선택된 항목\nexport const promptGeminiSettings = async (): Promise<readonly string[] | null> => {\n const wantSettings = await p.confirm({\n message: 'Gemini CLI 설정 파일(.gemini/settings.json)을 설치하시겠습니까?',\n initialValue: true,\n });\n if (p.isCancel(wantSettings) || !wantSettings) return null;\n\n const selected = await p.multiselect<string>({\n message: '설치할 설정 항목을 선택하세요 (스페이스로 토글)',\n options: SETTING_GROUPS.map((g) => ({\n value: g.value,\n label: g.label,\n hint: g.hint,\n })),\n initialValues: SETTING_GROUPS.map((g) => g.value),\n required: false,\n });\n if (p.isCancel(selected)) return null;\n return selected as string[];\n};\n\nexport const installGeminiSettings = (basePath: string, selectedValues: readonly string[]): void => {\n if (selectedValues.length === 0) return;\n\n const settingsDir = join(basePath, '.gemini');\n const settingsPath = join(settingsDir, 'settings.json');\n\n let existing: GeminiSettings = {};\n if (existsSync(settingsPath)) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as GeminiSettings;\n } catch {\n // parse 실패 시 덮어쓰기\n }\n }\n\n let merged: GeminiSettings = existing;\n for (const val of selectedValues) {\n const group = SETTING_GROUPS.find((g) => g.value === val);\n if (!group) continue;\n merged = deepMerge(merged as Record<string, unknown>, group.patch as Record<string, unknown>) as GeminiSettings;\n }\n\n mkdirSync(settingsDir, { recursive: true });\n writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n};\n","import * as p from '@clack/prompts';\nimport type { ToolId } from 'ai-ops-compiler';\nimport {\n readManifest,\n resolveManifestPath,\n loadAllRules,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n writeManifest,\n computeSourceHash,\n computeDiff,\n partitionRules,\n renderRulesToMarkdown,\n wrapWithHeader,\n TOOL_OUTPUT_MAP,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport { join } from 'node:path';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\nimport { installFiles } from '../lib/install.js';\n\nexport const updateCommand = async (opts: { scope: Scope; force: boolean }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const manifestPath = resolveManifestPath(basePath);\n\n p.intro('ai-ops update');\n\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const rulesDir = resolveRulesDir();\n const sourceHash = computeSourceHash(rulesDir);\n\n const diffResult = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (diffResult.status === 'up-to-date' && !opts.force) {\n p.log.info('변경 사항이 없습니다.');\n p.outro('ai-ops update 완료');\n return;\n }\n\n const s = p.spinner();\n s.start('규칙 갱신 중...');\n\n const allRules = loadAllRules(rulesDir);\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n const allInstalledFiles: string[] = [];\n\n if (manifest.workspaces) {\n // 모노레포: workspaces 기반 재설치\n const workspaceEntries = Object.entries(manifest.workspaces);\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n\n if (toolId === 'claude-code') {\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const workspaceMappings = Object.entries(manifest.workspaces!).map(([path, entry]) => ({\n path,\n ruleIds: entry.rules,\n }));\n const renderResult = renderForTool('claude-code', rulesToInstall, workspaceMappings);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n allInstalledFiles.push(...installFiles(basePath, actions).written);\n } else {\n // codex/gemini: global → 루트, domain → 워크스페이스별\n const config = TOOL_OUTPUT_MAP[toolId];\n\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const allRulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const { global } = partitionRules(allRulesToInstall);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n allInstalledFiles.push(...installFiles(basePath, [rootAction]).written);\n }\n\n for (const [ws, entry] of workspaceEntries) {\n const wsRuleSet = new Set(entry.rules);\n const wsRules = allRules.filter((r) => wsRuleSet.has(r.id));\n const { domain } = partitionRules(wsRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(ws, config.domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n allInstalledFiles.push(...installFiles(basePath, [domainAction]).written);\n }\n }\n }\n } else {\n // 단일 프로젝트: installed_rules 기반 재설치\n const installedRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => installedRuleSet.has(r.id));\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n const renderResult = renderForTool(toolId, rulesToInstall);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n allInstalledFiles.push(...installFiles(basePath, actions).written);\n }\n }\n\n const newManifest = buildManifest({\n tools: manifest.tools,\n scope: manifest.scope,\n preset: manifest.preset,\n workspaces: manifest.workspaces,\n installedRules: manifest.installed_rules,\n installedFiles: allInstalledFiles.length > 0 ? allInstalledFiles : manifest.installed_files,\n sourceHash,\n });\n writeManifest(manifestPath, newManifest);\n\n s.stop('규칙 갱신 완료');\n p.outro('ai-ops update 완료');\n};\n","import * as p from '@clack/prompts';\nimport { readManifest, resolveManifestPath, computeSourceHash, computeDiff } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\n\nexport const diffCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n\n p.intro('ai-ops diff');\n\n const manifest = readManifest(resolveManifestPath(basePath));\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const sourceHash = computeSourceHash(resolveRulesDir());\n\n const result = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (result.status === 'up-to-date') {\n p.log.success('변경 사항 없음. 최신 상태입니다.');\n } else {\n if (result.sourceChanged) {\n p.log.warn(`소스 변경 감지: ${manifest.sourceHash} → ${sourceHash}`);\n }\n if (result.added.length > 0) {\n p.log.info(`추가된 규칙: ${result.added.join(', ')}`);\n }\n if (result.removed.length > 0) {\n p.log.info(`제거된 규칙: ${result.removed.join(', ')}`);\n }\n }\n\n p.outro('ai-ops diff 완료');\n};\n","import * as p from '@clack/prompts';\nimport { rmSync } from 'node:fs';\nimport { readManifest, resolveManifestPath, inferInstalledFiles, MANIFEST_FILENAME } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath } from '../lib/paths.js';\nimport { removeFiles, cleanEmptyDirs, collectManagedDirs } from '../lib/uninstall.js';\n\nexport const uninstallCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const manifestPath = resolveManifestPath(basePath);\n\n p.intro('ai-ops uninstall');\n\n // 1. manifest 읽기\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n // 2. 삭제 대상 결정\n const targetFiles = manifest.installed_files ?? inferInstalledFiles(manifest);\n\n if (targetFiles.length === 0) {\n p.log.warn('삭제할 파일이 없습니다.');\n p.outro('ai-ops uninstall 완료');\n return;\n }\n\n // 3. 삭제 대상 목록 출력\n p.log.info(`삭제 대상 파일 (${targetFiles.length}개):\\n${targetFiles.map((f) => ` ${f}`).join('\\n')}`);\n\n // 4. confirm\n const confirmed = await p.confirm({\n message: '위 파일과 manifest를 모두 삭제하시겠습니까?',\n initialValue: false,\n });\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 5. 파일 삭제\n const result = removeFiles(basePath, targetFiles);\n\n // 6. 빈 디렉토리 정리\n const dirs = collectManagedDirs(targetFiles);\n const removedDirs = cleanEmptyDirs(basePath, dirs);\n\n // 7. manifest 삭제\n rmSync(manifestPath, { force: true });\n\n // 8. 결과 요약\n if (result.deleted.length > 0) {\n p.log.success(`삭제 완료 (${result.deleted.length}개):\\n${result.deleted.map((f) => ` ${f}`).join('\\n')}`);\n }\n if (result.skipped.length > 0) {\n p.log.warn(\n `건너뜀 (non-managed 파일 보호, ${result.skipped.length}개):\\n${result.skipped.map((f) => ` ${f}`).join('\\n')}`,\n );\n }\n if (result.notFound.length > 0) {\n p.log.info(`이미 없음 (${result.notFound.length}개):\\n${result.notFound.map((f) => ` ${f}`).join('\\n')}`);\n }\n if (removedDirs.length > 0) {\n p.log.info(`빈 디렉토리 정리 (${removedDirs.length}개):\\n${removedDirs.map((d) => ` ${d}`).join('\\n')}`);\n }\n\n p.log.success(`manifest 삭제: ${MANIFEST_FILENAME}`);\n p.outro('ai-ops uninstall 완료');\n};\n","import { existsSync, readFileSync, rmSync, readdirSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport { isManagedFile } from 'ai-ops-compiler';\n\nexport type UninstallResult = {\n deleted: string[];\n skipped: string[]; // non-managed 파일 (사용자 파일 보호)\n notFound: string[]; // 이미 삭제됨\n};\n\nexport const removeFiles = (basePath: string, relativePaths: readonly string[]): UninstallResult => {\n const deleted: string[] = [];\n const skipped: string[] = [];\n const notFound: string[] = [];\n\n for (const rel of relativePaths) {\n const absPath = resolve(basePath, rel);\n\n if (!existsSync(absPath)) {\n notFound.push(rel);\n continue;\n }\n\n const content = readFileSync(absPath, 'utf-8');\n if (!isManagedFile(content)) {\n skipped.push(rel);\n continue;\n }\n\n rmSync(absPath);\n deleted.push(rel);\n }\n\n return { deleted, skipped, notFound };\n};\n\n/** 대상 디렉토리가 비어 있으면 삭제하고, 삭제한 경로 배열 반환 */\nexport const cleanEmptyDirs = (basePath: string, dirs: readonly string[]): string[] => {\n const removed: string[] = [];\n\n for (const dir of dirs) {\n const absDir = resolve(basePath, dir);\n if (!existsSync(absDir)) continue;\n\n try {\n const entries = readdirSync(absDir);\n if (entries.length === 0) {\n rmSync(absDir, { recursive: true });\n removed.push(dir);\n }\n } catch {\n // 삭제 실패는 무시\n }\n }\n\n return removed;\n};\n\n/** manifest의 installed_files에서 정리 대상 디렉토리 목록 추출 */\nexport const collectManagedDirs = (relativePaths: readonly string[]): string[] => {\n const dirs = new Set<string>();\n for (const rel of relativePaths) {\n const dir = dirname(rel);\n if (dir !== '.') {\n dirs.add(dir);\n }\n }\n return [...dirs];\n};\n"],"mappings":"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","names":["p","join","join","resolve","existsSync","resolve","existsSync","mkdirSync","readFileSync","writeFileSync","join","join","p","resolveManifestPath","loadAllRules","renderForTool","buildInstallPlan","buildManifest","writeManifest","computeSourceHash","partitionRules","renderRulesToMarkdown","wrapWithHeader","TOOL_OUTPUT_MAP","join","resolveManifestPath","computeSourceHash","loadAllRules","renderForTool","buildInstallPlan","TOOL_OUTPUT_MAP","partitionRules","join","wrapWithHeader","renderRulesToMarkdown","buildManifest","writeManifest","p","readManifest","resolveManifestPath","computeSourceHash","computeDiff","readManifest","resolveManifestPath","computeSourceHash","computeDiff","p","rmSync","readManifest","resolveManifestPath","existsSync","readFileSync","readdirSync","resolve","dirname","isManagedFile","resolveManifestPath","readManifest","rmSync"]}
|
|
1
|
+
{"version":3,"sources":["../../src/bin/index.ts","../../src/commands/init.ts","../../src/lib/paths.ts","../../src/lib/workspace.ts","../../src/lib/install.ts","../../src/lib/gemini-settings.ts","../../src/commands/update.ts","../../src/commands/diff.ts","../../src/commands/uninstall.ts","../../src/lib/uninstall.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { initCommand } from '../commands/init.js';\nimport { updateCommand } from '../commands/update.js';\nimport { diffCommand } from '../commands/diff.js';\nimport { uninstallCommand } from '../commands/uninstall.js';\nimport type { Scope } from '../lib/paths.js';\n\nconst program = new Command();\n\nprogram.name('ai-ops').description('AI 에이전트 규칙 스캐폴더').version('0.1.0');\n\nprogram\n .command('init')\n .description('AI 규칙 초기 설치')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => initCommand(opts));\n\nprogram\n .command('update')\n .description('기존 manifest 기반 규칙 갱신')\n .option('--scope <scope>', 'project | global', 'project')\n .option('--force', '변경 없어도 강제 재설치', false)\n .action((opts: { scope: Scope; force: boolean }) => updateCommand(opts));\n\nprogram\n .command('diff')\n .description('설치된 규칙과 최신 소스 비교')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => diffCommand(opts));\n\nprogram\n .command('uninstall')\n .description('설치된 규칙 파일 및 manifest 제거')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => uninstallCommand(opts));\n\nprogram.parse();\n","import * as p from '@clack/prompts';\nimport { join } from 'node:path';\nimport type { Rule, Preset, ToolId, WorkspaceMapping } from 'ai-ops-compiler';\nimport {\n loadAllRules,\n loadPresets,\n resolvePresetRules,\n excludeRules,\n isGlobalRule,\n partitionRules,\n renderForTool,\n renderRulesToMarkdown,\n buildInstallPlan,\n buildManifest,\n computeSourceHash,\n resolveManifestPath,\n writeManifest,\n wrapWithHeader,\n TOOL_OUTPUT_MAP,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir, resolvePresetsPath } from '../lib/paths.js';\nimport { listWorkspaceCandidates } from '../lib/workspace.js';\nimport { installFiles } from '../lib/install.js';\nimport { promptGeminiSettings, installGeminiSettings } from '../lib/gemini-settings.js';\n\ntype WorkspacePresetMapping = {\n workspace: string;\n preset: Preset;\n finalRules: Rule[];\n};\n\ntype InstallStats = { written: string[]; appended: string[] };\n\nconst TOOL_OPTIONS = [\n { value: 'claude-code' as ToolId, label: 'Claude Code' },\n { value: 'codex' as ToolId, label: 'Codex' },\n { value: 'gemini' as ToolId, label: 'Gemini CLI' },\n];\n\nconst deduplicateRules = (rules: readonly Rule[]): Rule[] => {\n const seen = new Set<string>();\n return rules.filter((r) => {\n if (seen.has(r.id)) return false;\n seen.add(r.id);\n return true;\n });\n};\n\nconst selectPresetAndFineTune = async (\n workspaceName: string,\n presets: readonly Preset[],\n allRules: readonly Rule[],\n): Promise<WorkspacePresetMapping | null> => {\n const preset = await p.select<Preset>({\n message: `[${workspaceName}] 프리셋을 선택하세요`,\n options: presets.map((pr) => ({\n value: pr,\n label: pr.id,\n hint: pr.description,\n })),\n });\n if (p.isCancel(preset)) return null;\n\n const presetRules = resolvePresetRules(preset, allRules);\n const globalRules = presetRules.filter(isGlobalRule);\n const domainRules = presetRules.filter((r) => !isGlobalRule(r));\n\n // Global rules: locked (항상 포함)\n if (globalRules.length > 0) {\n p.note(globalRules.map((r) => ` ✓ ${r.id}`).join('\\n'), `[${workspaceName}] 기본 규칙 (잠금)`);\n }\n\n if (domainRules.length === 0) {\n return { workspace: workspaceName, preset, finalRules: presetRules };\n }\n\n // Domain rules: 제외 가능\n const selectedDomain = await p.multiselect<string>({\n message: `[${workspaceName}] 도메인 규칙 선택 (해제하여 제외)`,\n options: domainRules.map((r) => ({ value: r.id, label: r.id })),\n initialValues: domainRules.map((r) => r.id),\n required: false,\n });\n if (p.isCancel(selectedDomain)) return null;\n\n const excludeIds = domainRules.map((r) => r.id).filter((id) => !(selectedDomain as string[]).includes(id));\n\n return { workspace: workspaceName, preset, finalRules: excludeRules(presetRules, excludeIds) };\n};\n\nconst installHierarchicalMonorepo = (\n toolId: 'codex' | 'gemini',\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): InstallStats => {\n const config = TOOL_OUTPUT_MAP[toolId];\n const written: string[] = [];\n const appended: string[] = [];\n\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const { global } = partitionRules(allRules);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n const r = installFiles(basePath, [rootAction], meta);\n written.push(...r.written);\n appended.push(...r.appended);\n }\n\n for (const mapping of mappings) {\n const { domain } = partitionRules(mapping.finalRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(mapping.workspace, config.domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n const r = installFiles(basePath, [domainAction], meta);\n written.push(...r.written);\n appended.push(...r.appended);\n }\n\n return { written, appended };\n};\n\nconst installClaudeCodeMonorepo = (\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): InstallStats => {\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const workspaceMappings: WorkspaceMapping[] = mappings.map((m) => ({\n path: m.workspace,\n ruleIds: m.finalRules.map((r) => r.id),\n }));\n const renderResult = renderForTool('claude-code', allRules, workspaceMappings);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n const r = installFiles(basePath, actions, meta);\n return { written: r.written, appended: r.appended };\n};\n\nexport const initCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const rulesDir = resolveRulesDir();\n\n p.intro('ai-ops init');\n\n // 1. AI 도구 다중 선택\n const selectedTools = await p.multiselect<ToolId>({\n message: 'AI 도구를 선택하세요',\n options: TOOL_OPTIONS,\n required: true,\n });\n if (p.isCancel(selectedTools)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 2. 모노레포 여부\n const isMonorepo = await p.confirm({\n message: '모노레포 프로젝트입니까?',\n initialValue: false,\n });\n if (p.isCancel(isMonorepo)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 3. 데이터 로드\n const allRules = loadAllRules(rulesDir);\n const presets = loadPresets(resolvePresetsPath());\n const sourceHash = computeSourceHash(rulesDir);\n\n // 4. 워크스페이스별 preset 선택 + fine-tune\n const mappings: WorkspacePresetMapping[] = [];\n\n if (!isMonorepo) {\n const mapping = await selectPresetAndFineTune('.', presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n } else {\n const candidates = listWorkspaceCandidates(basePath);\n const selectedWorkspaces = await p.multiselect<string>({\n message: '워크스페이스를 선택하세요',\n options: candidates.map((c) => ({ value: c, label: c })),\n required: true,\n });\n if (p.isCancel(selectedWorkspaces)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n for (const ws of selectedWorkspaces as string[]) {\n const mapping = await selectPresetAndFineTune(ws, presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n }\n }\n\n // 4.5. Gemini 설정 (gemini 선택 시)\n const geminiSettingValues: readonly string[] | null = (selectedTools as ToolId[]).includes('gemini')\n ? await promptGeminiSettings()\n : null;\n\n // 5. 설치\n const s = p.spinner();\n s.start('규칙 설치 중...');\n\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n const allInstalledFiles: string[] = [];\n const allAppended: string[] = [];\n\n for (const toolId of selectedTools as ToolId[]) {\n if (isMonorepo) {\n if (toolId === 'claude-code') {\n const stats = installClaudeCodeMonorepo(mappings, basePath, meta);\n allInstalledFiles.push(...stats.written);\n allAppended.push(...stats.appended);\n } else {\n const stats = installHierarchicalMonorepo(toolId, mappings, basePath, meta);\n allInstalledFiles.push(...stats.written);\n allAppended.push(...stats.appended);\n }\n } else {\n const renderResult = renderForTool(toolId, mappings[0].finalRules);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n const result = installFiles(basePath, actions, meta);\n allInstalledFiles.push(...result.written);\n allAppended.push(...result.appended);\n }\n }\n\n if (geminiSettingValues && geminiSettingValues.length > 0) {\n installGeminiSettings(basePath, geminiSettingValues);\n allInstalledFiles.push('.gemini/settings.json');\n }\n\n s.stop('규칙 설치 완료');\n\n // 6. Manifest 저장\n const allInstalledRuleIds = deduplicateRules(mappings.flatMap((m) => m.finalRules)).map((r) => r.id);\n\n const workspacesRecord = isMonorepo\n ? Object.fromEntries(\n mappings.map((m) => [m.workspace, { preset: m.preset.id, rules: m.finalRules.map((r) => r.id) }]),\n )\n : undefined;\n\n const manifest = buildManifest({\n tools: selectedTools as string[],\n scope: opts.scope,\n preset: !isMonorepo ? mappings[0].preset.id : undefined,\n workspaces: workspacesRecord,\n installedRules: allInstalledRuleIds,\n installedFiles: allInstalledFiles,\n appendedFiles: allAppended,\n sourceHash,\n });\n writeManifest(resolveManifestPath(basePath), manifest);\n\n // 7. 결과 요약\n if (allAppended.length > 0) {\n p.log.info(`기존 파일에 섹션 추가됨 (내용 보존):\\n${allAppended.map((f) => ` ${f}`).join('\\n')}`);\n }\n p.log.success(`설치된 규칙: ${allInstalledRuleIds.length}개`);\n p.outro('ai-ops init 완료');\n};\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { COMPILER_DATA_DIR } from 'ai-ops-compiler';\n\nexport type Scope = 'project' | 'global';\n\nexport const resolveCompilerDataDir = (): string => COMPILER_DATA_DIR;\n\nexport const resolveRulesDir = (): string => join(COMPILER_DATA_DIR, 'rules');\n\nexport const resolvePresetsPath = (): string => join(COMPILER_DATA_DIR, 'presets.yaml');\n\n// scope에 따른 설치 기준 디렉토리\nexport const resolveBasePath = (scope: Scope): string =>\n scope === 'global' ? resolve(homedir(), '.ai-ops') : process.cwd();\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nconst EXCLUDE_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.turbo', '.cache', 'coverage']);\n\nconst isVisibleDir = (basePath: string, name: string): boolean => {\n if (name.startsWith('.') || EXCLUDE_DIRS.has(name)) return false;\n return statSync(resolve(basePath, name)).isDirectory();\n};\n\n// Project manifest files that indicate a workspace root\nconst PROJECT_MANIFESTS = [\n 'package.json', // Node.js / JS / TS\n 'pubspec.yaml', // Flutter / Dart\n 'pyproject.toml', // Python (modern)\n 'setup.py', // Python (legacy)\n 'Cargo.toml', // Rust\n 'go.mod', // Go\n];\n\nconst isWorkspaceRoot = (dirPath: string): boolean => PROJECT_MANIFESTS.some((f) => existsSync(join(dirPath, f)));\n\n// 프로젝트 매니페스트 파일 존재 여부로 워크스페이스 판별:\n// 1. top-level dir에 매니페스트 → 그 자체가 워크스페이스 (e.g. backend-ts, mobile, web)\n// 2. top-level dir에 매니페스트 없고 자식에 있음 → 자식을 후보로 (e.g. apps/web, packages/ui)\n// 3. 매니페스트 없는 경우 → 1-depth 그대로\nexport const listWorkspaceCandidates = (basePath: string): string[] => {\n const topLevel = readdirSync(basePath).filter((name) => isVisibleDir(basePath, name));\n\n const candidates: string[] = [];\n for (const dir of topLevel) {\n const subPath = resolve(basePath, dir);\n if (isWorkspaceRoot(subPath)) {\n candidates.push(dir);\n } else {\n const children = readdirSync(subPath).filter((name) => isVisibleDir(subPath, name));\n const wsChildren = children.filter((name) => isWorkspaceRoot(resolve(subPath, name)));\n if (wsChildren.length > 0) {\n for (const child of wsChildren) {\n candidates.push(join(dir, child));\n }\n } else {\n candidates.push(dir);\n }\n }\n }\n\n return candidates.sort();\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport {\n isManagedFile,\n hasAiOpsSection,\n wrapWithSection,\n replaceAiOpsSection,\n stripManagedHeader,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\n\nexport type InstallResult = {\n written: string[];\n appended: string[]; // 기존 non-managed 파일에 섹션 추가됨\n skipped: string[]; // 더 이상 발생하지 않음 (하위 호환용)\n};\n\nexport const installFiles = (\n basePath: string,\n actions: readonly FileAction[],\n meta: { sourceHash: string; generatedAt: string },\n): InstallResult => {\n const written: string[] = [];\n const appended: string[] = [];\n const skipped: string[] = [];\n\n for (const action of actions) {\n const absPath = resolve(basePath, action.relativePath);\n\n if (existsSync(absPath)) {\n const existing = readFileSync(absPath, 'utf-8');\n\n if (isManagedFile(existing)) {\n writeFileSync(absPath, action.content, 'utf-8');\n written.push(action.relativePath);\n } else if (hasAiOpsSection(existing)) {\n // 이전에 append된 파일 → 섹션만 교체\n const sectionContent = wrapWithSection(stripManagedHeader(action.content), meta);\n const updated = replaceAiOpsSection(existing, sectionContent);\n writeFileSync(absPath, updated, 'utf-8');\n appended.push(action.relativePath);\n } else {\n // non-managed, 섹션 없음 → 최초 append\n const sectionContent = wrapWithSection(stripManagedHeader(action.content), meta);\n const updated = existing.trimEnd() + '\\n\\n' + sectionContent + '\\n';\n writeFileSync(absPath, updated, 'utf-8');\n appended.push(action.relativePath);\n }\n } else {\n mkdirSync(dirname(absPath), { recursive: true });\n writeFileSync(absPath, action.content, 'utf-8');\n written.push(action.relativePath);\n }\n }\n\n return { written, appended, skipped };\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\ntype GeminiSettings = {\n ui?: { showLineNumbers?: boolean };\n general?: {\n plan?: { directory?: string; modelRouting?: boolean };\n sessionRetention?: { maxAge?: string };\n };\n experimental?: { jitContext?: boolean; plan?: boolean };\n};\n\ntype SettingGroup = {\n value: string;\n label: string;\n hint: string;\n patch: GeminiSettings;\n};\n\nconst SETTING_GROUPS: readonly SettingGroup[] = [\n {\n value: 'ui',\n label: 'UI — 줄 번호 숨기기',\n hint: 'ui.showLineNumbers: false — 코드 복사 시 줄 번호가 포함되지 않도록 비활성화',\n patch: { ui: { showLineNumbers: false } },\n },\n {\n value: 'plan',\n label: 'Plan — 계획 파일 저장 및 모델 라우팅',\n hint: 'general.plan.directory: .gemini/plans, modelRouting: true — AI 계획을 파일로 저장하고 태스크별 최적 모델 자동 선택',\n patch: { general: { plan: { directory: '.gemini/plans', modelRouting: true } } },\n },\n {\n value: 'sessionRetention',\n label: 'Session Retention — 세션 30일 보존',\n hint: 'general.sessionRetention.maxAge: 30d — 이전 대화 컨텍스트를 30일간 유지',\n patch: { general: { sessionRetention: { maxAge: '30d' } } },\n },\n {\n value: 'experimental',\n label: 'Experimental — JIT 컨텍스트 + Plan 기능',\n hint: 'experimental.jitContext: true, plan: true — 서브디렉토리 컨텍스트 지연 로딩 및 계획 기능 실험적 활성화',\n patch: { experimental: { jitContext: true, plan: true } },\n },\n];\n\nconst deepMerge = (base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown> => {\n const result = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n typeof result[key] === 'object' &&\n result[key] !== null\n ) {\n result[key] = deepMerge(result[key] as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n};\n\n// null → 건너뜀 (취소 또는 \"No\"), string[] → 선택된 항목\nexport const promptGeminiSettings = async (): Promise<readonly string[] | null> => {\n const wantSettings = await p.confirm({\n message: 'Gemini CLI 설정 파일(.gemini/settings.json)을 설치하시겠습니까?',\n initialValue: true,\n });\n if (p.isCancel(wantSettings) || !wantSettings) return null;\n\n const selected = await p.multiselect<string>({\n message: '설치할 설정 항목을 선택하세요 (스페이스로 토글)',\n options: SETTING_GROUPS.map((g) => ({\n value: g.value,\n label: g.label,\n hint: g.hint,\n })),\n initialValues: SETTING_GROUPS.map((g) => g.value),\n required: false,\n });\n if (p.isCancel(selected)) return null;\n return selected as string[];\n};\n\nexport const installGeminiSettings = (basePath: string, selectedValues: readonly string[]): void => {\n if (selectedValues.length === 0) return;\n\n const settingsDir = join(basePath, '.gemini');\n const settingsPath = join(settingsDir, 'settings.json');\n\n let existing: GeminiSettings = {};\n if (existsSync(settingsPath)) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as GeminiSettings;\n } catch {\n // parse 실패 시 덮어쓰기\n }\n }\n\n let merged: GeminiSettings = existing;\n for (const val of selectedValues) {\n const group = SETTING_GROUPS.find((g) => g.value === val);\n if (!group) continue;\n merged = deepMerge(merged as Record<string, unknown>, group.patch as Record<string, unknown>) as GeminiSettings;\n }\n\n mkdirSync(settingsDir, { recursive: true });\n writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n};\n","import * as p from '@clack/prompts';\nimport type { ToolId } from 'ai-ops-compiler';\nimport {\n readManifest,\n resolveManifestPath,\n loadAllRules,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n writeManifest,\n computeSourceHash,\n computeDiff,\n partitionRules,\n renderRulesToMarkdown,\n wrapWithHeader,\n TOOL_OUTPUT_MAP,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport { join } from 'node:path';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\nimport { installFiles } from '../lib/install.js';\n\nexport const updateCommand = async (opts: { scope: Scope; force: boolean }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const manifestPath = resolveManifestPath(basePath);\n\n p.intro('ai-ops update');\n\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const rulesDir = resolveRulesDir();\n const sourceHash = computeSourceHash(rulesDir);\n\n const diffResult = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (diffResult.status === 'up-to-date' && !opts.force) {\n p.log.info('변경 사항이 없습니다.');\n p.outro('ai-ops update 완료');\n return;\n }\n\n const s = p.spinner();\n s.start('규칙 갱신 중...');\n\n const allRules = loadAllRules(rulesDir);\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n const allInstalledFiles: string[] = [];\n const allAppended: string[] = [];\n\n if (manifest.workspaces) {\n // 모노레포: workspaces 기반 재설치\n const workspaceEntries = Object.entries(manifest.workspaces);\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n\n if (toolId === 'claude-code') {\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const workspaceMappings = Object.entries(manifest.workspaces!).map(([path, entry]) => ({\n path,\n ruleIds: entry.rules,\n }));\n const renderResult = renderForTool('claude-code', rulesToInstall, workspaceMappings);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n const r = installFiles(basePath, actions, meta);\n allInstalledFiles.push(...r.written);\n allAppended.push(...r.appended);\n } else {\n // codex/gemini: global → 루트, domain → 워크스페이스별\n const config = TOOL_OUTPUT_MAP[toolId];\n\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const allRulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const { global } = partitionRules(allRulesToInstall);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n const r = installFiles(basePath, [rootAction], meta);\n allInstalledFiles.push(...r.written);\n allAppended.push(...r.appended);\n }\n\n for (const [ws, entry] of workspaceEntries) {\n const wsRuleSet = new Set(entry.rules);\n const wsRules = allRules.filter((r) => wsRuleSet.has(r.id));\n const { domain } = partitionRules(wsRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(ws, config.domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n const r = installFiles(basePath, [domainAction], meta);\n allInstalledFiles.push(...r.written);\n allAppended.push(...r.appended);\n }\n }\n }\n } else {\n // 단일 프로젝트: installed_rules 기반 재설치\n const installedRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => installedRuleSet.has(r.id));\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n const renderResult = renderForTool(toolId, rulesToInstall);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n const r = installFiles(basePath, actions, meta);\n allInstalledFiles.push(...r.written);\n allAppended.push(...r.appended);\n }\n }\n\n const newManifest = buildManifest({\n tools: manifest.tools,\n scope: manifest.scope,\n preset: manifest.preset,\n workspaces: manifest.workspaces,\n installedRules: manifest.installed_rules,\n installedFiles: allInstalledFiles.length > 0 ? allInstalledFiles : manifest.installed_files,\n appendedFiles: allAppended.length > 0 ? allAppended : manifest.appended_files,\n sourceHash,\n });\n writeManifest(manifestPath, newManifest);\n\n s.stop('규칙 갱신 완료');\n p.outro('ai-ops update 완료');\n};\n","import * as p from '@clack/prompts';\nimport { readManifest, resolveManifestPath, computeSourceHash, computeDiff } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\n\nexport const diffCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n\n p.intro('ai-ops diff');\n\n const manifest = readManifest(resolveManifestPath(basePath));\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const sourceHash = computeSourceHash(resolveRulesDir());\n\n const result = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (result.status === 'up-to-date') {\n p.log.success('변경 사항 없음. 최신 상태입니다.');\n } else {\n if (result.sourceChanged) {\n p.log.warn(`소스 변경 감지: ${manifest.sourceHash} → ${sourceHash}`);\n }\n if (result.added.length > 0) {\n p.log.info(`추가된 규칙: ${result.added.join(', ')}`);\n }\n if (result.removed.length > 0) {\n p.log.info(`제거된 규칙: ${result.removed.join(', ')}`);\n }\n }\n\n p.outro('ai-ops diff 완료');\n};\n","import * as p from '@clack/prompts';\nimport { rmSync } from 'node:fs';\nimport { readManifest, resolveManifestPath, inferInstalledFiles, MANIFEST_FILENAME } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath } from '../lib/paths.js';\nimport { removeFiles, cleanEmptyDirs, collectManagedDirs } from '../lib/uninstall.js';\n\nexport const uninstallCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const manifestPath = resolveManifestPath(basePath);\n\n p.intro('ai-ops uninstall');\n\n // 1. manifest 읽기\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n // 2. 삭제 대상 결정 (managed 파일 + append된 파일)\n const targetFiles = [\n ...(manifest.installed_files ?? inferInstalledFiles(manifest)),\n ...(manifest.appended_files ?? []),\n ];\n\n if (targetFiles.length === 0) {\n p.log.warn('삭제할 파일이 없습니다.');\n p.outro('ai-ops uninstall 완료');\n return;\n }\n\n // 3. 삭제 대상 목록 출력\n p.log.info(`삭제 대상 파일 (${targetFiles.length}개):\\n${targetFiles.map((f) => ` ${f}`).join('\\n')}`);\n\n // 4. confirm\n const confirmed = await p.confirm({\n message: '위 파일과 manifest를 모두 삭제하시겠습니까?',\n initialValue: false,\n });\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 5. 파일 삭제\n const result = removeFiles(basePath, targetFiles);\n\n // 6. 빈 디렉토리 정리\n const dirs = collectManagedDirs(targetFiles);\n const removedDirs = cleanEmptyDirs(basePath, dirs);\n\n // 7. manifest 삭제\n rmSync(manifestPath, { force: true });\n\n // 8. 결과 요약\n if (result.deleted.length > 0) {\n p.log.success(`삭제 완료 (${result.deleted.length}개):\\n${result.deleted.map((f) => ` ${f}`).join('\\n')}`);\n }\n if (result.cleaned.length > 0) {\n p.log.success(\n `섹션 제거 완료 (사용자 내용 보존, ${result.cleaned.length}개):\\n${result.cleaned.map((f) => ` ${f}`).join('\\n')}`,\n );\n }\n if (result.skipped.length > 0) {\n p.log.warn(\n `건너뜀 (non-managed 파일 보호, ${result.skipped.length}개):\\n${result.skipped.map((f) => ` ${f}`).join('\\n')}`,\n );\n }\n if (result.notFound.length > 0) {\n p.log.info(`이미 없음 (${result.notFound.length}개):\\n${result.notFound.map((f) => ` ${f}`).join('\\n')}`);\n }\n if (removedDirs.length > 0) {\n p.log.info(`빈 디렉토리 정리 (${removedDirs.length}개):\\n${removedDirs.map((d) => ` ${d}`).join('\\n')}`);\n }\n\n p.log.success(`manifest 삭제: ${MANIFEST_FILENAME}`);\n p.outro('ai-ops uninstall 완료');\n};\n","import { existsSync, readFileSync, rmSync, readdirSync, writeFileSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport { isManagedFile, hasAiOpsSection, stripAiOpsSection } from 'ai-ops-compiler';\n\nexport type UninstallResult = {\n deleted: string[];\n cleaned: string[]; // 섹션만 제거된 파일 (append 되었던 파일)\n skipped: string[]; // non-managed 파일 (사용자 파일 보호)\n notFound: string[]; // 이미 삭제됨\n};\n\nexport const removeFiles = (basePath: string, relativePaths: readonly string[]): UninstallResult => {\n const deleted: string[] = [];\n const cleaned: string[] = [];\n const skipped: string[] = [];\n const notFound: string[] = [];\n\n for (const rel of relativePaths) {\n const absPath = resolve(basePath, rel);\n\n if (!existsSync(absPath)) {\n notFound.push(rel);\n continue;\n }\n\n const content = readFileSync(absPath, 'utf-8');\n\n if (!isManagedFile(content)) {\n if (hasAiOpsSection(content)) {\n // append된 파일 → 섹션만 제거, 사용자 콘텐츠 보존\n const stripped = stripAiOpsSection(content);\n writeFileSync(absPath, stripped, 'utf-8');\n cleaned.push(rel);\n } else {\n skipped.push(rel);\n }\n continue;\n }\n\n rmSync(absPath);\n deleted.push(rel);\n }\n\n return { deleted, cleaned, skipped, notFound };\n};\n\n/** 대상 디렉토리가 비어 있으면 삭제하고, 삭제한 경로 배열 반환 */\nexport const cleanEmptyDirs = (basePath: string, dirs: readonly string[]): string[] => {\n const removed: string[] = [];\n\n for (const dir of dirs) {\n const absDir = resolve(basePath, dir);\n if (!existsSync(absDir)) continue;\n\n try {\n const entries = readdirSync(absDir);\n if (entries.length === 0) {\n rmSync(absDir, { recursive: true });\n removed.push(dir);\n }\n } catch {\n // 삭제 실패는 무시\n }\n }\n\n return removed;\n};\n\n/** manifest의 installed_files에서 정리 대상 디렉토리 목록 추출 */\nexport const collectManagedDirs = (relativePaths: readonly string[]): string[] => {\n const dirs = new Set<string>();\n for (const rel of relativePaths) {\n const dir = dirname(rel);\n if (dir !== '.') {\n dirs.add(dir);\n }\n }\n return [...dirs];\n};\n"],"mappings":";;;AAAA,SAAS,eAAe;;;ACAxB,YAAYA,QAAO;AACnB,SAAS,QAAAC,aAAY;AAErB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACnBP,SAAS,MAAM,eAAe;AAC9B,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAM3B,IAAM,kBAAkB,MAAc,KAAK,mBAAmB,OAAO;AAErE,IAAM,qBAAqB,MAAc,KAAK,mBAAmB,cAAc;AAG/E,IAAM,kBAAkB,CAAC,UAC9B,UAAU,WAAW,QAAQ,QAAQ,GAAG,SAAS,IAAI,QAAQ,IAAI;;;ACdnE,SAAS,YAAY,aAAa,gBAAgB;AAClD,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAE9B,IAAM,eAAe,oBAAI,IAAI,CAAC,gBAAgB,QAAQ,QAAQ,SAAS,SAAS,UAAU,UAAU,UAAU,CAAC;AAE/G,IAAM,eAAe,CAAC,UAAkB,SAA0B;AAChE,MAAI,KAAK,WAAW,GAAG,KAAK,aAAa,IAAI,IAAI,EAAG,QAAO;AAC3D,SAAO,SAASA,SAAQ,UAAU,IAAI,CAAC,EAAE,YAAY;AACvD;AAGA,IAAM,oBAAoB;AAAA,EACxB;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAEA,IAAM,kBAAkB,CAAC,YAA6B,kBAAkB,KAAK,CAAC,MAAM,WAAWD,MAAK,SAAS,CAAC,CAAC,CAAC;AAMzG,IAAM,0BAA0B,CAAC,aAA+B;AACrE,QAAM,WAAW,YAAY,QAAQ,EAAE,OAAO,CAAC,SAAS,aAAa,UAAU,IAAI,CAAC;AAEpF,QAAM,aAAuB,CAAC;AAC9B,aAAW,OAAO,UAAU;AAC1B,UAAM,UAAUC,SAAQ,UAAU,GAAG;AACrC,QAAI,gBAAgB,OAAO,GAAG;AAC5B,iBAAW,KAAK,GAAG;AAAA,IACrB,OAAO;AACL,YAAM,WAAW,YAAY,OAAO,EAAE,OAAO,CAAC,SAAS,aAAa,SAAS,IAAI,CAAC;AAClF,YAAM,aAAa,SAAS,OAAO,CAAC,SAAS,gBAAgBA,SAAQ,SAAS,IAAI,CAAC,CAAC;AACpF,UAAI,WAAW,SAAS,GAAG;AACzB,mBAAW,SAAS,YAAY;AAC9B,qBAAW,KAAKD,MAAK,KAAK,KAAK,CAAC;AAAA,QAClC;AAAA,MACF,OAAO;AACL,mBAAW,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO,WAAW,KAAK;AACzB;;;AChDA,SAAS,cAAAE,aAAY,WAAW,cAAc,qBAAqB;AACnE,SAAS,SAAS,WAAAC,gBAAe;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASA,IAAM,eAAe,CAC1B,UACA,SACA,SACkB;AAClB,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAoB,CAAC;AAE3B,aAAW,UAAU,SAAS;AAC5B,UAAM,UAAUA,SAAQ,UAAU,OAAO,YAAY;AAErD,QAAID,YAAW,OAAO,GAAG;AACvB,YAAM,WAAW,aAAa,SAAS,OAAO;AAE9C,UAAI,cAAc,QAAQ,GAAG;AAC3B,sBAAc,SAAS,OAAO,SAAS,OAAO;AAC9C,gBAAQ,KAAK,OAAO,YAAY;AAAA,MAClC,WAAW,gBAAgB,QAAQ,GAAG;AAEpC,cAAM,iBAAiB,gBAAgB,mBAAmB,OAAO,OAAO,GAAG,IAAI;AAC/E,cAAM,UAAU,oBAAoB,UAAU,cAAc;AAC5D,sBAAc,SAAS,SAAS,OAAO;AACvC,iBAAS,KAAK,OAAO,YAAY;AAAA,MACnC,OAAO;AAEL,cAAM,iBAAiB,gBAAgB,mBAAmB,OAAO,OAAO,GAAG,IAAI;AAC/E,cAAM,UAAU,SAAS,QAAQ,IAAI,SAAS,iBAAiB;AAC/D,sBAAc,SAAS,SAAS,OAAO;AACvC,iBAAS,KAAK,OAAO,YAAY;AAAA,MACnC;AAAA,IACF,OAAO;AACL,gBAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/C,oBAAc,SAAS,OAAO,SAAS,OAAO;AAC9C,cAAQ,KAAK,OAAO,YAAY;AAAA,IAClC;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,UAAU,QAAQ;AACtC;;;ACxDA,YAAY,OAAO;AACnB,SAAS,cAAAE,aAAY,aAAAC,YAAW,gBAAAC,eAAc,iBAAAC,sBAAqB;AACnE,SAAS,QAAAC,aAAY;AAkBrB,IAAM,iBAA0C;AAAA,EAC9C;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO,EAAE,IAAI,EAAE,iBAAiB,MAAM,EAAE;AAAA,EAC1C;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,iBAAiB,cAAc,KAAK,EAAE,EAAE;AAAA,EACjF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,MAAM,EAAE,EAAE;AAAA,EAC5D;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO,EAAE,cAAc,EAAE,YAAY,MAAM,MAAM,KAAK,EAAE;AAAA,EAC1D;AACF;AAEA,IAAM,YAAY,CAAC,MAA+B,UAA4D;AAC5G,QAAM,SAAS,EAAE,GAAG,KAAK;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QACE,UAAU,QACV,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,OAAO,GAAG,MAAM,YACvB,OAAO,GAAG,MAAM,MAChB;AACA,aAAO,GAAG,IAAI,UAAU,OAAO,GAAG,GAA8B,KAAgC;AAAA,IAClG,OAAO;AACL,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAGO,IAAM,uBAAuB,YAA+C;AACjF,QAAM,eAAe,MAAQ,UAAQ;AAAA,IACnC,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AACD,MAAM,WAAS,YAAY,KAAK,CAAC,aAAc,QAAO;AAEtD,QAAM,WAAW,MAAQ,cAAoB;AAAA,IAC3C,SAAS;AAAA,IACT,SAAS,eAAe,IAAI,CAAC,OAAO;AAAA,MAClC,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,MACT,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,IACF,eAAe,eAAe,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,IAChD,UAAU;AAAA,EACZ,CAAC;AACD,MAAM,WAAS,QAAQ,EAAG,QAAO;AACjC,SAAO;AACT;AAEO,IAAM,wBAAwB,CAAC,UAAkB,mBAA4C;AAClG,MAAI,eAAe,WAAW,EAAG;AAEjC,QAAM,cAAcA,MAAK,UAAU,SAAS;AAC5C,QAAM,eAAeA,MAAK,aAAa,eAAe;AAEtD,MAAI,WAA2B,CAAC;AAChC,MAAIJ,YAAW,YAAY,GAAG;AAC5B,QAAI;AACF,iBAAW,KAAK,MAAME,cAAa,cAAc,OAAO,CAAC;AAAA,IAC3D,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI,SAAyB;AAC7B,aAAW,OAAO,gBAAgB;AAChC,UAAM,QAAQ,eAAe,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG;AACxD,QAAI,CAAC,MAAO;AACZ,aAAS,UAAU,QAAmC,MAAM,KAAgC;AAAA,EAC9F;AAEA,EAAAD,WAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAC1C,EAAAE,eAAc,cAAc,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,OAAO;AAC7E;;;AJ5EA,IAAM,eAAe;AAAA,EACnB,EAAE,OAAO,eAAyB,OAAO,cAAc;AAAA,EACvD,EAAE,OAAO,SAAmB,OAAO,QAAQ;AAAA,EAC3C,EAAE,OAAO,UAAoB,OAAO,aAAa;AACnD;AAEA,IAAM,mBAAmB,CAAC,UAAmC;AAC3D,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,MAAM,OAAO,CAAC,MAAM;AACzB,QAAI,KAAK,IAAI,EAAE,EAAE,EAAG,QAAO;AAC3B,SAAK,IAAI,EAAE,EAAE;AACb,WAAO;AAAA,EACT,CAAC;AACH;AAEA,IAAM,0BAA0B,OAC9B,eACA,SACA,aAC2C;AAC3C,QAAM,SAAS,MAAQ,UAAe;AAAA,IACpC,SAAS,IAAI,aAAa;AAAA,IAC1B,SAAS,QAAQ,IAAI,CAAC,QAAQ;AAAA,MAC5B,OAAO;AAAA,MACP,OAAO,GAAG;AAAA,MACV,MAAM,GAAG;AAAA,IACX,EAAE;AAAA,EACJ,CAAC;AACD,MAAM,YAAS,MAAM,EAAG,QAAO;AAE/B,QAAM,cAAc,mBAAmB,QAAQ,QAAQ;AACvD,QAAM,cAAc,YAAY,OAAO,YAAY;AACnD,QAAM,cAAc,YAAY,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AAG9D,MAAI,YAAY,SAAS,GAAG;AAC1B,IAAE,QAAK,YAAY,IAAI,CAAC,MAAM,YAAO,EAAE,EAAE,EAAE,EAAE,KAAK,IAAI,GAAG,IAAI,aAAa,4CAAc;AAAA,EAC1F;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,EAAE,WAAW,eAAe,QAAQ,YAAY,YAAY;AAAA,EACrE;AAGA,QAAM,iBAAiB,MAAQ,eAAoB;AAAA,IACjD,SAAS,IAAI,aAAa;AAAA,IAC1B,SAAS,YAAY,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,GAAG,EAAE;AAAA,IAC9D,eAAe,YAAY,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,IAC1C,UAAU;AAAA,EACZ,CAAC;AACD,MAAM,YAAS,cAAc,EAAG,QAAO;AAEvC,QAAM,aAAa,YAAY,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAE,eAA4B,SAAS,EAAE,CAAC;AAEzG,SAAO,EAAE,WAAW,eAAe,QAAQ,YAAY,aAAa,aAAa,UAAU,EAAE;AAC/F;AAEA,IAAM,8BAA8B,CAClC,QACA,UACA,UACA,SACiB;AACjB,QAAM,SAAS,gBAAgB,MAAM;AACrC,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAqB,CAAC;AAE5B,QAAM,WAAW,iBAAiB,SAAS,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;AACvE,QAAM,EAAE,OAAO,IAAI,eAAe,QAAQ;AAE1C,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,aAAyB;AAAA,MAC7B,cAAcE,MAAK,OAAO,KAAK,OAAO,YAAY;AAAA,MAClD,SAAS,eAAe,sBAAsB,MAAM,GAAG,IAAI;AAAA,IAC7D;AACA,UAAM,IAAI,aAAa,UAAU,CAAC,UAAU,GAAG,IAAI;AACnD,YAAQ,KAAK,GAAG,EAAE,OAAO;AACzB,aAAS,KAAK,GAAG,EAAE,QAAQ;AAAA,EAC7B;AAEA,aAAW,WAAW,UAAU;AAC9B,UAAM,EAAE,OAAO,IAAI,eAAe,QAAQ,UAAU;AACpD,QAAI,OAAO,WAAW,EAAG;AAEzB,UAAM,eAA2B;AAAA,MAC/B,cAAcA,MAAK,QAAQ,WAAW,OAAO,cAAc;AAAA,MAC3D,SAAS,eAAe,sBAAsB,MAAM,GAAG,IAAI;AAAA,IAC7D;AACA,UAAM,IAAI,aAAa,UAAU,CAAC,YAAY,GAAG,IAAI;AACrD,YAAQ,KAAK,GAAG,EAAE,OAAO;AACzB,aAAS,KAAK,GAAG,EAAE,QAAQ;AAAA,EAC7B;AAEA,SAAO,EAAE,SAAS,SAAS;AAC7B;AAEA,IAAM,4BAA4B,CAChC,UACA,UACA,SACiB;AACjB,QAAM,WAAW,iBAAiB,SAAS,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;AACvE,QAAM,oBAAwC,SAAS,IAAI,CAAC,OAAO;AAAA,IACjE,MAAM,EAAE;AAAA,IACR,SAAS,EAAE,WAAW,IAAI,CAACC,OAAMA,GAAE,EAAE;AAAA,EACvC,EAAE;AACF,QAAM,eAAe,cAAc,eAAe,UAAU,iBAAiB;AAC7E,QAAM,UAAU,iBAAiB,EAAE,QAAQ,eAAe,cAAc,KAAK,CAAC;AAC9E,QAAM,IAAI,aAAa,UAAU,SAAS,IAAI;AAC9C,SAAO,EAAE,SAAS,EAAE,SAAS,UAAU,EAAE,SAAS;AACpD;AAEO,IAAM,cAAc,OAAO,SAA0C;AAC1E,QAAM,WAAW,gBAAgB,KAAK,KAAK;AAC3C,QAAM,WAAW,gBAAgB;AAEjC,EAAE,SAAM,aAAa;AAGrB,QAAM,gBAAgB,MAAQ,eAAoB;AAAA,IAChD,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,EACZ,CAAC;AACD,MAAM,YAAS,aAAa,GAAG;AAC7B,IAAE,UAAO,oBAAK;AACd,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,aAAa,MAAQ,WAAQ;AAAA,IACjC,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AACD,MAAM,YAAS,UAAU,GAAG;AAC1B,IAAE,UAAO,oBAAK;AACd,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,aAAa,QAAQ;AACtC,QAAM,UAAU,YAAY,mBAAmB,CAAC;AAChD,QAAM,aAAa,kBAAkB,QAAQ;AAG7C,QAAM,WAAqC,CAAC;AAE5C,MAAI,CAAC,YAAY;AACf,UAAM,UAAU,MAAM,wBAAwB,KAAK,SAAS,QAAQ;AACpE,QAAI,CAAC,SAAS;AACZ,MAAE,UAAO,oBAAK;AACd,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,aAAS,KAAK,OAAO;AAAA,EACvB,OAAO;AACL,UAAM,aAAa,wBAAwB,QAAQ;AACnD,UAAM,qBAAqB,MAAQ,eAAoB;AAAA,MACrD,SAAS;AAAA,MACT,SAAS,WAAW,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE;AAAA,MACvD,UAAU;AAAA,IACZ,CAAC;AACD,QAAM,YAAS,kBAAkB,GAAG;AAClC,MAAE,UAAO,oBAAK;AACd,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,eAAW,MAAM,oBAAgC;AAC/C,YAAM,UAAU,MAAM,wBAAwB,IAAI,SAAS,QAAQ;AACnE,UAAI,CAAC,SAAS;AACZ,QAAE,UAAO,oBAAK;AACd,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,eAAS,KAAK,OAAO;AAAA,IACvB;AAAA,EACF;AAGA,QAAM,sBAAiD,cAA2B,SAAS,QAAQ,IAC/F,MAAM,qBAAqB,IAC3B;AAGJ,QAAM,IAAM,WAAQ;AACpB,IAAE,MAAM,qCAAY;AAEpB,QAAM,OAAO,EAAE,YAAY,cAAa,oBAAI,KAAK,GAAE,YAAY,EAAE;AACjE,QAAM,oBAA8B,CAAC;AACrC,QAAM,cAAwB,CAAC;AAE/B,aAAW,UAAU,eAA2B;AAC9C,QAAI,YAAY;AACd,UAAI,WAAW,eAAe;AAC5B,cAAM,QAAQ,0BAA0B,UAAU,UAAU,IAAI;AAChE,0BAAkB,KAAK,GAAG,MAAM,OAAO;AACvC,oBAAY,KAAK,GAAG,MAAM,QAAQ;AAAA,MACpC,OAAO;AACL,cAAM,QAAQ,4BAA4B,QAAQ,UAAU,UAAU,IAAI;AAC1E,0BAAkB,KAAK,GAAG,MAAM,OAAO;AACvC,oBAAY,KAAK,GAAG,MAAM,QAAQ;AAAA,MACpC;AAAA,IACF,OAAO;AACL,YAAM,eAAe,cAAc,QAAQ,SAAS,CAAC,EAAE,UAAU;AACjE,YAAM,UAAU,iBAAiB,EAAE,QAAQ,cAAc,KAAK,CAAC;AAC/D,YAAM,SAAS,aAAa,UAAU,SAAS,IAAI;AACnD,wBAAkB,KAAK,GAAG,OAAO,OAAO;AACxC,kBAAY,KAAK,GAAG,OAAO,QAAQ;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,uBAAuB,oBAAoB,SAAS,GAAG;AACzD,0BAAsB,UAAU,mBAAmB;AACnD,sBAAkB,KAAK,uBAAuB;AAAA,EAChD;AAEA,IAAE,KAAK,wCAAU;AAGjB,QAAM,sBAAsB,iBAAiB,SAAS,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAEnG,QAAM,mBAAmB,aACrB,OAAO;AAAA,IACL,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,IAAI,OAAO,EAAE,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAAA,EAClG,IACA;AAEJ,QAAM,WAAW,cAAc;AAAA,IAC7B,OAAO;AAAA,IACP,OAAO,KAAK;AAAA,IACZ,QAAQ,CAAC,aAAa,SAAS,CAAC,EAAE,OAAO,KAAK;AAAA,IAC9C,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf;AAAA,EACF,CAAC;AACD,gBAAc,oBAAoB,QAAQ,GAAG,QAAQ;AAGrD,MAAI,YAAY,SAAS,GAAG;AAC1B,IAAE,OAAI,KAAK;AAAA,EAA2B,YAAY,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACrF;AACA,EAAE,OAAI,QAAQ,oCAAW,oBAAoB,MAAM,QAAG;AACtD,EAAE,SAAM,0BAAgB;AAC1B;;;AKtRA,YAAYC,QAAO;AAEnB;AAAA,EACE;AAAA,EACA,uBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,EACA,kBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,mBAAAC;AAAA,OACK;AAEP,SAAS,QAAAC,aAAY;AAKd,IAAM,gBAAgB,OAAO,SAA0D;AAC5F,QAAM,WAAW,gBAAgB,KAAK,KAAK;AAC3C,QAAM,eAAeC,qBAAoB,QAAQ;AAEjD,EAAE,SAAM,eAAe;AAEvB,QAAM,WAAW,aAAa,YAAY;AAC1C,MAAI,CAAC,UAAU;AACb,IAAE,OAAI,MAAM,yGAAwC;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,gBAAgB;AACjC,QAAM,aAAaC,mBAAkB,QAAQ;AAE7C,QAAM,aAAa,YAAY;AAAA,IAC7B,UAAU;AAAA,IACV,cAAc,SAAS;AAAA,IACvB,mBAAmB;AAAA,EACrB,CAAC;AAED,MAAI,WAAW,WAAW,gBAAgB,CAAC,KAAK,OAAO;AACrD,IAAE,OAAI,KAAK,2DAAc;AACzB,IAAE,SAAM,4BAAkB;AAC1B;AAAA,EACF;AAEA,QAAM,IAAM,WAAQ;AACpB,IAAE,MAAM,qCAAY;AAEpB,QAAM,WAAWC,cAAa,QAAQ;AACtC,QAAM,OAAO,EAAE,YAAY,cAAa,oBAAI,KAAK,GAAE,YAAY,EAAE;AACjE,QAAM,oBAA8B,CAAC;AACrC,QAAM,cAAwB,CAAC;AAE/B,MAAI,SAAS,YAAY;AAEvB,UAAM,mBAAmB,OAAO,QAAQ,SAAS,UAAU;AAE3D,eAAW,aAAa,SAAS,OAAO;AACtC,YAAM,SAAS;AAEf,UAAI,WAAW,eAAe;AAC5B,cAAM,sBAAsB,IAAI,IAAI,SAAS,eAAe;AAC5D,cAAM,iBAAiB,SAAS,OAAO,CAACC,OAAM,oBAAoB,IAAIA,GAAE,EAAE,CAAC;AAC3E,cAAM,oBAAoB,OAAO,QAAQ,SAAS,UAAW,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,UACrF;AAAA,UACA,SAAS,MAAM;AAAA,QACjB,EAAE;AACF,cAAM,eAAeC,eAAc,eAAe,gBAAgB,iBAAiB;AACnF,cAAM,UAAUC,kBAAiB,EAAE,QAAQ,eAAe,cAAc,KAAK,CAAC;AAC9E,cAAM,IAAI,aAAa,UAAU,SAAS,IAAI;AAC9C,0BAAkB,KAAK,GAAG,EAAE,OAAO;AACnC,oBAAY,KAAK,GAAG,EAAE,QAAQ;AAAA,MAChC,OAAO;AAEL,cAAM,SAASC,iBAAgB,MAAM;AAErC,cAAM,sBAAsB,IAAI,IAAI,SAAS,eAAe;AAC5D,cAAM,oBAAoB,SAAS,OAAO,CAAC,MAAM,oBAAoB,IAAI,EAAE,EAAE,CAAC;AAC9E,cAAM,EAAE,OAAO,IAAIC,gBAAe,iBAAiB;AAEnD,YAAI,OAAO,SAAS,GAAG;AACrB,gBAAM,aAAyB;AAAA,YAC7B,cAAcC,MAAK,OAAO,KAAK,OAAO,YAAY;AAAA,YAClD,SAASC,gBAAeC,uBAAsB,MAAM,GAAG,IAAI;AAAA,UAC7D;AACA,gBAAM,IAAI,aAAa,UAAU,CAAC,UAAU,GAAG,IAAI;AACnD,4BAAkB,KAAK,GAAG,EAAE,OAAO;AACnC,sBAAY,KAAK,GAAG,EAAE,QAAQ;AAAA,QAChC;AAEA,mBAAW,CAAC,IAAI,KAAK,KAAK,kBAAkB;AAC1C,gBAAM,YAAY,IAAI,IAAI,MAAM,KAAK;AACrC,gBAAM,UAAU,SAAS,OAAO,CAACP,OAAM,UAAU,IAAIA,GAAE,EAAE,CAAC;AAC1D,gBAAM,EAAE,OAAO,IAAII,gBAAe,OAAO;AACzC,cAAI,OAAO,WAAW,EAAG;AAEzB,gBAAM,eAA2B;AAAA,YAC/B,cAAcC,MAAK,IAAI,OAAO,cAAc;AAAA,YAC5C,SAASC,gBAAeC,uBAAsB,MAAM,GAAG,IAAI;AAAA,UAC7D;AACA,gBAAM,IAAI,aAAa,UAAU,CAAC,YAAY,GAAG,IAAI;AACrD,4BAAkB,KAAK,GAAG,EAAE,OAAO;AACnC,sBAAY,KAAK,GAAG,EAAE,QAAQ;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AAEL,UAAM,mBAAmB,IAAI,IAAI,SAAS,eAAe;AACzD,UAAM,iBAAiB,SAAS,OAAO,CAAC,MAAM,iBAAiB,IAAI,EAAE,EAAE,CAAC;AAExE,eAAW,aAAa,SAAS,OAAO;AACtC,YAAM,SAAS;AACf,YAAM,eAAeN,eAAc,QAAQ,cAAc;AACzD,YAAM,UAAUC,kBAAiB,EAAE,QAAQ,cAAc,KAAK,CAAC;AAC/D,YAAM,IAAI,aAAa,UAAU,SAAS,IAAI;AAC9C,wBAAkB,KAAK,GAAG,EAAE,OAAO;AACnC,kBAAY,KAAK,GAAG,EAAE,QAAQ;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,cAAcM,eAAc;AAAA,IAChC,OAAO,SAAS;AAAA,IAChB,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB,gBAAgB,SAAS;AAAA,IACzB,gBAAgB,kBAAkB,SAAS,IAAI,oBAAoB,SAAS;AAAA,IAC5E,eAAe,YAAY,SAAS,IAAI,cAAc,SAAS;AAAA,IAC/D;AAAA,EACF,CAAC;AACD,EAAAC,eAAc,cAAc,WAAW;AAEvC,IAAE,KAAK,wCAAU;AACjB,EAAE,SAAM,4BAAkB;AAC5B;;;AC5IA,YAAYC,QAAO;AACnB,SAAS,gBAAAC,eAAc,uBAAAC,sBAAqB,qBAAAC,oBAAmB,eAAAC,oBAAmB;AAI3E,IAAM,cAAc,OAAO,SAA0C;AAC1E,QAAM,WAAW,gBAAgB,KAAK,KAAK;AAE3C,EAAE,SAAM,aAAa;AAErB,QAAM,WAAWC,cAAaC,qBAAoB,QAAQ,CAAC;AAC3D,MAAI,CAAC,UAAU;AACb,IAAE,OAAI,MAAM,yGAAwC;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAaC,mBAAkB,gBAAgB,CAAC;AAEtD,QAAM,SAASC,aAAY;AAAA,IACzB,UAAU;AAAA,IACV,cAAc,SAAS;AAAA,IACvB,mBAAmB;AAAA,EACrB,CAAC;AAED,MAAI,OAAO,WAAW,cAAc;AAClC,IAAE,OAAI,QAAQ,sFAAqB;AAAA,EACrC,OAAO;AACL,QAAI,OAAO,eAAe;AACxB,MAAE,OAAI,KAAK,2CAAa,SAAS,UAAU,WAAM,UAAU,EAAE;AAAA,IAC/D;AACA,QAAI,OAAO,MAAM,SAAS,GAAG;AAC3B,MAAE,OAAI,KAAK,oCAAW,OAAO,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,IACjD;AACA,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,MAAE,OAAI,KAAK,oCAAW,OAAO,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IACnD;AAAA,EACF;AAEA,EAAE,SAAM,0BAAgB;AAC1B;;;ACvCA,YAAYC,QAAO;AACnB,SAAS,UAAAC,eAAc;AACvB,SAAS,gBAAAC,eAAc,uBAAAC,sBAAqB,qBAAqB,yBAAyB;;;ACF1F,SAAS,cAAAC,aAAY,gBAAAC,eAAc,QAAQ,eAAAC,cAAa,iBAAAC,sBAAqB;AAC7E,SAAS,WAAAC,UAAS,WAAAC,gBAAe;AACjC,SAAS,iBAAAC,gBAAe,mBAAAC,kBAAiB,yBAAyB;AAS3D,IAAM,cAAc,CAAC,UAAkB,kBAAsD;AAClG,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAqB,CAAC;AAE5B,aAAW,OAAO,eAAe;AAC/B,UAAM,UAAUH,SAAQ,UAAU,GAAG;AAErC,QAAI,CAACJ,YAAW,OAAO,GAAG;AACxB,eAAS,KAAK,GAAG;AACjB;AAAA,IACF;AAEA,UAAM,UAAUC,cAAa,SAAS,OAAO;AAE7C,QAAI,CAACK,eAAc,OAAO,GAAG;AAC3B,UAAIC,iBAAgB,OAAO,GAAG;AAE5B,cAAM,WAAW,kBAAkB,OAAO;AAC1C,QAAAJ,eAAc,SAAS,UAAU,OAAO;AACxC,gBAAQ,KAAK,GAAG;AAAA,MAClB,OAAO;AACL,gBAAQ,KAAK,GAAG;AAAA,MAClB;AACA;AAAA,IACF;AAEA,WAAO,OAAO;AACd,YAAQ,KAAK,GAAG;AAAA,EAClB;AAEA,SAAO,EAAE,SAAS,SAAS,SAAS,SAAS;AAC/C;AAGO,IAAM,iBAAiB,CAAC,UAAkB,SAAsC;AACrF,QAAM,UAAoB,CAAC;AAE3B,aAAW,OAAO,MAAM;AACtB,UAAM,SAASC,SAAQ,UAAU,GAAG;AACpC,QAAI,CAACJ,YAAW,MAAM,EAAG;AAEzB,QAAI;AACF,YAAM,UAAUE,aAAY,MAAM;AAClC,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO,QAAQ,EAAE,WAAW,KAAK,CAAC;AAClC,gBAAQ,KAAK,GAAG;AAAA,MAClB;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;AAGO,IAAM,qBAAqB,CAAC,kBAA+C;AAChF,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,eAAe;AAC/B,UAAM,MAAMG,SAAQ,GAAG;AACvB,QAAI,QAAQ,KAAK;AACf,WAAK,IAAI,GAAG;AAAA,IACd;AAAA,EACF;AACA,SAAO,CAAC,GAAG,IAAI;AACjB;;;ADvEO,IAAM,mBAAmB,OAAO,SAA0C;AAC/E,QAAM,WAAW,gBAAgB,KAAK,KAAK;AAC3C,QAAM,eAAeG,qBAAoB,QAAQ;AAEjD,EAAE,SAAM,kBAAkB;AAG1B,QAAM,WAAWC,cAAa,YAAY;AAC1C,MAAI,CAAC,UAAU;AACb,IAAE,OAAI,MAAM,yGAAwC;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,cAAc;AAAA,IAClB,GAAI,SAAS,mBAAmB,oBAAoB,QAAQ;AAAA,IAC5D,GAAI,SAAS,kBAAkB,CAAC;AAAA,EAClC;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,IAAE,OAAI,KAAK,iEAAe;AAC1B,IAAE,SAAM,+BAAqB;AAC7B;AAAA,EACF;AAGA,EAAE,OAAI,KAAK,2CAAa,YAAY,MAAM;AAAA,EAAQ,YAAY,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAG/F,QAAM,YAAY,MAAQ,WAAQ;AAAA,IAChC,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AACD,MAAM,YAAS,SAAS,KAAK,CAAC,WAAW;AACvC,IAAE,UAAO,oBAAK;AACd,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,SAAS,YAAY,UAAU,WAAW;AAGhD,QAAM,OAAO,mBAAmB,WAAW;AAC3C,QAAM,cAAc,eAAe,UAAU,IAAI;AAGjD,EAAAC,QAAO,cAAc,EAAE,OAAO,KAAK,CAAC;AAGpC,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,IAAE,OAAI,QAAQ,8BAAU,OAAO,QAAQ,MAAM;AAAA,EAAQ,OAAO,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACvG;AACA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,IAAE,OAAI;AAAA,MACJ,yFAAwB,OAAO,QAAQ,MAAM;AAAA,EAAQ,OAAO,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IACrG;AAAA,EACF;AACA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,IAAE,OAAI;AAAA,MACJ,8DAA2B,OAAO,QAAQ,MAAM;AAAA,EAAQ,OAAO,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IACxG;AAAA,EACF;AACA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,IAAE,OAAI,KAAK,8BAAU,OAAO,SAAS,MAAM;AAAA,EAAQ,OAAO,SAAS,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACtG;AACA,MAAI,YAAY,SAAS,GAAG;AAC1B,IAAE,OAAI,KAAK,iDAAc,YAAY,MAAM;AAAA,EAAQ,YAAY,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAClG;AAEA,EAAE,OAAI,QAAQ,0BAAgB,iBAAiB,EAAE;AACjD,EAAE,SAAM,+BAAqB;AAC/B;;;ARvEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QAAQ,KAAK,QAAQ,EAAE,YAAY,mEAAiB,EAAE,QAAQ,OAAO;AAErE,QACG,QAAQ,MAAM,EACd,YAAY,2CAAa,EACzB,OAAO,mBAAmB,oBAAoB,SAAS,EACvD,OAAO,CAAC,SAA2B,YAAY,IAAI,CAAC;AAEvD,QACG,QAAQ,QAAQ,EAChB,YAAY,8DAAsB,EAClC,OAAO,mBAAmB,oBAAoB,SAAS,EACvD,OAAO,WAAW,mEAAiB,KAAK,EACxC,OAAO,CAAC,SAA2C,cAAc,IAAI,CAAC;AAEzE,QACG,QAAQ,MAAM,EACd,YAAY,8EAAkB,EAC9B,OAAO,mBAAmB,oBAAoB,SAAS,EACvD,OAAO,CAAC,SAA2B,YAAY,IAAI,CAAC;AAEvD,QACG,QAAQ,WAAW,EACnB,YAAY,2EAAyB,EACrC,OAAO,mBAAmB,oBAAoB,SAAS,EACvD,OAAO,CAAC,SAA2B,iBAAiB,IAAI,CAAC;AAE5D,QAAQ,MAAM;","names":["p","join","join","resolve","existsSync","resolve","existsSync","mkdirSync","readFileSync","writeFileSync","join","join","r","p","resolveManifestPath","loadAllRules","renderForTool","buildInstallPlan","buildManifest","writeManifest","computeSourceHash","partitionRules","renderRulesToMarkdown","wrapWithHeader","TOOL_OUTPUT_MAP","join","resolveManifestPath","computeSourceHash","loadAllRules","r","renderForTool","buildInstallPlan","TOOL_OUTPUT_MAP","partitionRules","join","wrapWithHeader","renderRulesToMarkdown","buildManifest","writeManifest","p","readManifest","resolveManifestPath","computeSourceHash","computeDiff","readManifest","resolveManifestPath","computeSourceHash","computeDiff","p","rmSync","readManifest","resolveManifestPath","existsSync","readFileSync","readdirSync","writeFileSync","resolve","dirname","isManagedFile","hasAiOpsSection","resolveManifestPath","readManifest","rmSync"]}
|