ai-ops-cli 0.1.21 โ†’ 0.1.23

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/README.md CHANGED
@@ -4,53 +4,45 @@ CLI for managing AI tool rules and presets across projects.
4
4
 
5
5
  ## Why this exists
6
6
 
7
- `ai-ops-cli` was created to reduce configuration drift across AI coding tools in a team.
7
+ `ai-ops-cli` reduces configuration drift across AI coding tools.
8
8
 
9
- - Different tools (Claude Code, Codex, Gemini CLI) require different file locations and prompt layouts.
10
- - Tool conventions evolve over time, so manually maintained setup files become inconsistent quickly.
11
- - Teams need a single, repeatable way to install and maintain AI rule scaffolding.
9
+ - Different tools use different file layouts and loading models.
10
+ - Manual sync across tools is error-prone over time.
11
+ - Teams need a deterministic, repeatable setup for AI pair-programming rules.
12
12
 
13
- This project uses a centralized rule source (SSOT) and scaffolds tool-native files into the current project.
14
- For the full product background and architecture intent, see [`docs/plan.md`](../../docs/plan.md).
13
+ The CLI uses centralized YAML rules as SSOT and renders tool-native files into the current project.
15
14
 
16
- ### What this library provides
15
+ > **๐Ÿ“Œ Core Concept**
16
+ >
17
+ > Instead of directly managing platform-specific files, manage **abstract metadata** as SSOT and achieve **Asset Centralization** across multiple AI environments.
17
18
 
18
- - Interactive installation flow for supported AI tools (`ai-ops init`)
19
- - Managed updates based on installed manifest (`ai-ops update`)
20
- - Drift detection against current source hash (`ai-ops diff`)
21
- - Safe cleanup of installed managed files + manifest (`ai-ops uninstall`)
22
- - Project-local installation and management
19
+ ## What this CLI provides
23
20
 
24
- ### What this library does not provide
21
+ - Interactive installation (`ai-ops init`)
22
+ - Source drift checks (`ai-ops diff`)
23
+ - Deterministic re-apply (`ai-ops update`)
24
+ - Managed cleanup (`ai-ops uninstall`)
25
+ - Project-only operation (no global scope)
25
26
 
26
- - A hosted backend or remote state service
27
- - Rule authoring workflow inside the CLI itself
28
- - IDE-specific plugin management
27
+ ## What this CLI does not provide
29
28
 
30
- ## Supported AI tools and installation model
29
+ - Hosted backend or remote state
30
+ - In-CLI rule authoring UI
31
+ - IDE plugin management
31
32
 
32
- `ai-ops-cli` currently supports:
33
+ ## Supported tools and output layout
33
34
 
34
- - Claude Code (`claude-code`)
35
- - Codex (`codex`)
36
- - Gemini CLI (`gemini`)
35
+ | Tool | Single project output | Monorepo output |
36
+ | --- | --- | --- |
37
+ | Claude Code (`claude-code`) | `.claude/rules/<rule-id>.md` | Shared rules in `.claude/rules/*.md`, domain rules in `<workspace>/CLAUDE.md` |
38
+ | Codex (`codex`) | `AGENTS.md` and `AGENTS.override.md` | Root `AGENTS.md` and `<workspace>/AGENTS.override.md` |
39
+ | Gemini CLI (`gemini`) | `GEMINI.md` | Root `GEMINI.md` and `<workspace>/GEMINI.md` |
37
40
 
38
- ### Tool-specific installation layout
41
+ Optional settings files:
39
42
 
40
- | Tool | Single project | Monorepo | Why this layout (JIT rationale) |
41
- | ----------- | ------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
42
- | Claude Code | `.claude/rules/<rule-id>.md` per rule | Shared rules in `.claude/rules/*.md`, domain rules in `<workspace>/CLAUDE.md` | Keeps always-on rules stable while loading domain rules only for matching paths/workspaces. |
43
- | Codex | `AGENTS.md` + `AGENTS.override.md` | Root `AGENTS.md` + `<workspace>/AGENTS.override.md` | Uses root baseline + local override so only relevant workspace context is applied at execution time. |
44
- | Gemini CLI | `.gemini/GEMINI.md` | Root `.gemini/GEMINI.md` + `<workspace>/GEMINI.md` | Splits shared defaults and workspace-local context to reduce irrelevant prompt context. |
45
-
46
- Gemini CLI can also install optional runtime settings to `.gemini/settings.json`.
47
-
48
- ### Installation behavior details
49
-
50
- - Rules are split into shared and domain categories and rendered per tool with tool-native file shapes.
51
- - Existing managed files are replaced safely using ai-ops metadata headers.
52
- - Existing non-managed files are preserved and receive an `ai-ops` managed section block instead of full overwrite.
53
- - `update`, `diff`, and `uninstall` operate from the manifest to keep changes deterministic and idempotent.
43
+ - Claude Code: `.claude/settings.local.json`
44
+ - Gemini CLI: `.gemini/settings.json`
45
+ - Formatting protection section: `.prettierignore`
54
46
 
55
47
  ## Install
56
48
 
@@ -64,33 +56,84 @@ npm install -g ai-ops-cli
64
56
  # Initialize rules for the current project
65
57
  ai-ops init
66
58
 
67
- # Check for updates
59
+ # Check drift against current source hash
68
60
  ai-ops diff
69
61
 
70
- # Apply updates
62
+ # Re-apply installed rules (or force)
71
63
  ai-ops update
64
+ ai-ops update --force
72
65
 
73
- # Remove installed managed files and manifest
66
+ # Remove installed files and manifest
74
67
  ai-ops uninstall
75
68
  ```
76
69
 
77
- ## Options
70
+ ## CLI surface
78
71
 
79
- ```
80
- ai-ops [command] [options]
72
+ ```text
73
+ ai-ops [command]
81
74
 
82
75
  Commands:
83
- init Initialize AI tool rules for a project
84
- update Update installed rules
85
- diff Show diff between installed and current rules
86
- uninstall Remove installed rules and manifest
76
+ init Initialize AI tool rules for a project
77
+ update Update installed rules
78
+ diff Show diff between installed and current rules
79
+ uninstall Remove installed rules and manifest
87
80
 
88
81
  Options:
89
- --force Force update even when no changes detected
90
- -V, --version Output the version number
91
- -h, --help Display help
82
+ --force Force update even when no changes are detected (update only)
83
+ -V, --version Output version number
84
+ -h, --help Display help
85
+ ```
86
+
87
+ Notes:
88
+
89
+ - `--scope` is deprecated and explicitly rejected. The CLI is project-only.
90
+ - The installation state is tracked in `.ai-ops-manifest.json` at project root.
91
+
92
+ ## How install/update/uninstall behave
93
+
94
+ - Managed files are wrapped in an `ai-ops` section with metadata (`sourceHash`, `generatedAt`).
95
+ - If a file already has an `ai-ops` section, only that section is replaced.
96
+ - If a file has no managed section, generated content is appended and user content is preserved.
97
+ - `uninstall` removes only managed sections for appended files and keeps user-authored content.
98
+
99
+ ## Init flow summary
100
+
101
+ `ai-ops init` prompts for:
102
+
103
+ 1. Tool selection (`claude-code`, `codex`, `gemini`)
104
+ 2. Monorepo confirmation
105
+ 3. Preset selection per workspace
106
+ 4. Domain rule fine-tuning per workspace
107
+ 5. Optional settings installation
108
+
109
+ Preset and rules are loaded from:
110
+
111
+ - `apps/cli/data/presets.yaml`
112
+ - `apps/cli/data/rules/*.yaml`
113
+
114
+ ## Local development
115
+
116
+ From repo root:
117
+
118
+ ```bash
119
+ npm install
120
+ npm run build
121
+ npm run compile
122
+ npm test
92
123
  ```
93
124
 
125
+ From `apps/cli` workspace:
126
+
127
+ ```bash
128
+ npm run build --workspace=apps/cli
129
+ npm run test --workspace=apps/cli
130
+ ```
131
+
132
+ ## Related docs
133
+
134
+ - Master blueprint: [`docs/plan.md`](../../docs/plan.md)
135
+ - Implementation playbook: [`docs/implementation-playbook.md`](../../docs/implementation-playbook.md)
136
+
94
137
  ## License
95
138
 
96
139
  MIT
package/dist/bin/index.js CHANGED
@@ -182,9 +182,9 @@ var TOOL_OUTPUT_MAP = {
182
182
  },
183
183
  gemini: {
184
184
  mode: "multi-file",
185
- dir: ".gemini",
185
+ dir: "",
186
186
  rootFileName: "GEMINI.md",
187
- // global ๋ฃฐ
187
+ // global ๋ฃฐ (๋ฃจํŠธ)
188
188
  domainFileName: "GEMINI.md",
189
189
  // domain ๋ฃฐ (ํ•˜์œ„ ํด๋”)
190
190
  contextStrategy: "hierarchical"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/index.ts","../../src/commands/init.ts","../../src/core/schemas/rule.schema.ts","../../src/core/schemas/preset.schema.ts","../../src/core/schemas/manifest.schema.ts","../../src/core/loader.ts","../../src/core/renderer.ts","../../src/core/tool-output.ts","../../src/core/source-hash.ts","../../src/core/managed-header.ts","../../src/core/manifest-io.ts","../../src/core/diff.ts","../../src/core/install-plan.ts","../../src/core/uninstall-plan.ts","../../src/core/paths.ts","../../src/lib/paths.ts","../../src/lib/workspace.ts","../../src/lib/install.ts","../../src/lib/gemini-settings.ts","../../src/lib/deep-merge.util.ts","../../src/lib/claude-settings.ts","../../src/lib/prettier-ignore.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';\n\nconst program = new Command();\n\nconst ensureNoDeprecatedScopeFlag = (argv: readonly string[]): void => {\n if (argv.some((arg) => arg === '--scope' || arg.startsWith('--scope='))) {\n console.error('`--scope` is no longer supported. ai-ops is now project-only.');\n process.exit(1);\n }\n};\n\nprogram.name('ai-ops').description('AI ์—์ด์ „ํŠธ ๊ทœ์น™ ์Šค์บํด๋”').version('0.1.0');\n\nprogram\n .command('init')\n .description('AI ๊ทœ์น™ ์ดˆ๊ธฐ ์„ค์น˜')\n .action(() => initCommand());\n\nprogram\n .command('update')\n .description('๊ธฐ์กด manifest ๊ธฐ๋ฐ˜ ๊ทœ์น™ ๊ฐฑ์‹ ')\n .option('--force', '๋ณ€๊ฒฝ ์—†์–ด๋„ ๊ฐ•์ œ ์žฌ์„ค์น˜', false)\n .action((opts: { force: boolean }) => updateCommand(opts));\n\nprogram\n .command('diff')\n .description('์„ค์น˜๋œ ๊ทœ์น™๊ณผ ์ตœ์‹  ์†Œ์Šค ๋น„๊ต')\n .action(() => diffCommand());\n\nprogram\n .command('uninstall')\n .description('์„ค์น˜๋œ ๊ทœ์น™ ํŒŒ์ผ ๋ฐ manifest ์ œ๊ฑฐ')\n .action(() => uninstallCommand());\n\nensureNoDeprecatedScopeFlag(process.argv);\nprogram.parse();\n","import * as p from '@clack/prompts';\nimport type { Rule, Preset, ToolId, WorkspaceMapping } from '@/core/index.js';\nimport {\n loadAllRules,\n loadPresets,\n resolvePresetRules,\n resolvePresetRuleGroups,\n isGlobalRule,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n computeSourceHash,\n getCliVersion,\n resolveManifestPath,\n writeManifest,\n} from '@/core/index.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';\nimport { promptClaudeSettings, installClaudeSettings } from '../lib/claude-settings.js';\nimport { promptPrettierIgnore, installPrettierIgnore } from '../lib/prettier-ignore.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 presetRuleGroups = resolvePresetRuleGroups(preset, allRules);\n const globalGroups = presetRuleGroups.filter((group) => group.rules.every(isGlobalRule));\n const domainGroups = presetRuleGroups.filter((group) => !group.rules.every(isGlobalRule));\n const globalGroupIds = globalGroups.map((group) => group.id);\n const globalRules =\n globalGroupIds.length > 0 ? resolvePresetRules({ ...preset, rules: globalGroupIds }, allRules) : [];\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 (domainGroups.length === 0) {\n return { workspace: workspaceName, preset, finalRules: resolvePresetRules(preset, allRules) };\n }\n\n // Domain rules: ์ œ์™ธ ๊ฐ€๋Šฅ\n const selectedDomain = await p.multiselect<string>({\n message: `[${workspaceName}] ๋„๋ฉ”์ธ ๊ทœ์น™ ์„ ํƒ (ํ•ด์ œํ•˜์—ฌ ์ œ์™ธ)`,\n options: domainGroups.map((group) => ({ value: group.id, label: group.id })),\n initialValues: domainGroups.map((group) => group.id),\n required: false,\n });\n if (p.isCancel(selectedDomain)) return null;\n\n const selectedLogicalRuleIds = [...globalGroupIds, ...(selectedDomain as string[])];\n return {\n workspace: workspaceName,\n preset,\n finalRules: resolvePresetRules({ ...preset, rules: selectedLogicalRuleIds }, allRules),\n };\n};\n\nexport const initCommand = async (): Promise<void> => {\n const basePath = resolveBasePath();\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 // 4.6. Claude ์„ค์ • (claude-code ์„ ํƒ ์‹œ)\n const claudeSettingValues: readonly string[] | null = (selectedTools as ToolId[]).includes('claude-code')\n ? await promptClaudeSettings()\n : null;\n\n // 4.7. .prettierignore ์„ค์น˜ ์—ฌ๋ถ€\n const wantPrettierIgnore = await promptPrettierIgnore();\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 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(toolId, allRules, workspaceMappings);\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 } 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 }\n\n if (claudeSettingValues && claudeSettingValues.length > 0) {\n installClaudeSettings(basePath, claudeSettingValues);\n }\n\n if (wantPrettierIgnore) {\n installPrettierIgnore(basePath);\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: 'project',\n preset: !isMonorepo ? mappings[0].preset.id : undefined,\n workspaces: workspacesRecord,\n installedRules: allInstalledRuleIds,\n installedFiles: allInstalledFiles,\n appendedFiles: allAppended,\n settings:\n claudeSettingValues || geminiSettingValues || wantPrettierIgnore\n ? {\n claude: claudeSettingValues ? [...claudeSettingValues] : undefined,\n gemini: geminiSettingValues ? [...geminiSettingValues] : undefined,\n prettierignore: wantPrettierIgnore || undefined,\n }\n : undefined,\n cliVersion: getCliVersion(),\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","/**\n * Rule = SSOT์˜ ์ตœ์†Œ ์ง€์‹ ๋‹จ์œ„. ํ•˜๋‚˜์˜ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜/์•„ํ‚คํ…์ฒ˜ ๊ทœ์น™์„ YAML๋กœ ๊ตฌ์กฐํ™”ํ•œ ๊ฒƒ.\n */\nimport { z } from 'zod';\n\nexport const DecisionTableEntrySchema = z\n .object({\n when: z.string().min(1),\n then: z.string().min(1),\n /** ์กฐ๊ฑด๋ถ€ ๊ทœ์น™์—์„œ ํšŒํ”ผํ•ด์•ผ ํ•  ํŒจํ„ด */\n avoid: z.string().min(1).optional(),\n })\n .strict();\n\nexport const RuleContentSchema = z\n .object({\n /** Anti-pattern ๊ทœ์น™ ('ํ•˜์ง€ ๋งˆ๋ผ'). guidelines๋ณด๋‹ค ํ•ญ์ƒ ์ƒ๋‹จ ๋ Œ๋”๋ง */\n constraints: z.array(z.string().min(1)),\n /** Positive ๊ทœ์น™ ('ํ•ด๋ผ') */\n guidelines: z.array(z.string().min(1)),\n /** ์กฐ๊ฑด๋ถ€ ๊ทœ์น™. whenโ†’thenโ†’avoid ๊ตฌ์กฐ */\n decision_table: z.array(DecisionTableEntrySchema).optional(),\n })\n .strict();\n\nexport const RuleSchema = z\n .object({\n id: z.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, 'id must be kebab-case'),\n category: z.string().min(1),\n tags: z.array(z.string().min(1)),\n /** 0-100. ๋†’์„์ˆ˜๋ก ์ƒ์„ฑ ํŒŒ์ผ ์ƒ๋‹จ ๋ฐฐ์น˜ (U-shaped attention ์ตœ์ ํ™”) */\n priority: z.number().int().min(0).max(100),\n content: RuleContentSchema,\n })\n .strict();\n\nexport type DecisionTableEntry = z.infer<typeof DecisionTableEntrySchema>;\nexport type RuleContent = z.infer<typeof RuleContentSchema>;\nexport type Rule = z.infer<typeof RuleSchema>;\n","import { z } from 'zod';\n\nexport const PresetSchema = z\n .object({\n id: z\n .string()\n .regex(/^[a-z][a-z0-9-]*$/)\n .min(1),\n description: z.string().min(1),\n rules: z.array(z.string().min(1)).min(1),\n })\n .strict();\n\nexport type Preset = z.infer<typeof PresetSchema>;\n","/**\n * Manifest = ์„ค์น˜ ์ถ”์  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ. CLI๊ฐ€ ์ด์ „ ์„ค์น˜ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜๊ธฐ ์œ„ํ•œ JSON.\n */\nimport { z } from 'zod';\n\nexport const SCOPES = {\n PROJECT: 'project',\n} as const;\n\n/** init/update ์‹œ ์„ ํƒ๋œ settings ํ•ญ๋ชฉ ์ถ”์  */\nconst SettingsConfigSchema = z\n .object({\n claude: z.array(z.string().min(1)).optional(),\n gemini: z.array(z.string().min(1)).optional(),\n prettierignore: z.boolean().optional(),\n })\n .strict();\n\nexport type SettingsConfig = z.infer<typeof SettingsConfigSchema>;\n\n/** ๋ชจ๋…ธ๋ ˆํฌ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ณ„ preset + rules ์ถ”์  */\nconst WorkspaceEntrySchema = z\n .object({\n preset: z.string().min(1),\n rules: z.array(z.string().min(1)),\n })\n .strict();\n\nexport type WorkspaceEntry = z.infer<typeof WorkspaceEntrySchema>;\n\nexport const ManifestSchema = z\n .object({\n tools: z.array(z.string().min(1)).min(1),\n scope: z.literal('project'),\n /** ๋น„๋ชจ๋…ธ๋ ˆํฌ ๋‹จ์ผ preset */\n preset: z.string().min(1).optional(),\n /** ๋ชจ๋…ธ๋ ˆํฌ: workspace path โ†’ { preset, rules } */\n workspaces: z.record(z.string(), WorkspaceEntrySchema).optional(),\n installed_rules: z.array(z.string().min(1)),\n /** ์‹ค์ œ ๋””์Šคํฌ์— ์“ฐ์—ฌ์ง„ ํŒŒ์ผ ์ƒ๋Œ€ ๊ฒฝ๋กœ ๋ชฉ๋ก (uninstall์šฉ). ๊ธฐ์กด manifest ํ˜ธํ™˜์„ฑ ์œ„ํ•ด optional */\n installed_files: z.array(z.string().min(1)).optional(),\n /** non-managed ํŒŒ์ผ์— ์„น์…˜์„ appendํ•œ ๊ฒฝ์šฐ ์ถ”์  (uninstall ์‹œ ์„น์…˜๋งŒ ์ œ๊ฑฐ) */\n appended_files: z.array(z.string().min(1)).optional(),\n /** init ์‹œ ์„ ํƒ๋œ settings ํ•ญ๋ชฉ โ€” update ์‹œ ์žฌ์ƒ์„ฑ์— ์‚ฌ์šฉ */\n settings: SettingsConfigSchema.optional(),\n /** init/update ์‹คํ–‰ ์‹œ์ ์˜ CLI ํŒจํ‚ค์ง€ ๋ฒ„์ „ โ€” ๋ฒ„์ „ ๋ณ€๊ฒฝ ๊ฐ์ง€์— ์‚ฌ์šฉ */\n cliVersion: z.string().optional(),\n /** SSOT ๋ฐ์ดํ„ฐ ํŒŒ์ผ๋“ค์˜ deterministic SHA-256 ํ•ด์‹œ (6์ž๋ฆฌ hex). diff/update ํŒ๋‹จ ๊ธฐ์ค€ */\n sourceHash: z.string().regex(/^[a-f0-9]{6}$/, 'sourceHash must be 6 lowercase hex chars'),\n generatedAt: z.string().datetime({ offset: true }),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof ManifestSchema>;\n","import { readFileSync, readdirSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { parse } from 'yaml';\nimport { RuleSchema, PresetSchema } from './schemas/index.js';\nimport type { Rule, Preset } from './schemas/index.js';\n\ntype PresetRuleBundles = Readonly<Record<string, Readonly<Record<string, readonly string[]>>>>;\n\nexport const PRESET_RULE_BUNDLES: PresetRuleBundles = {\n 'frontend-web': {\n graphql: ['graphql-core', 'graphql-client-web'],\n },\n 'frontend-app': {\n graphql: ['graphql-core', 'graphql-client-app'],\n },\n 'backend-ts': {\n graphql: ['graphql-core', 'graphql-server'],\n },\n} as const;\n\nexport type PresetRuleGroup = {\n id: string;\n rules: Rule[];\n};\n\n// priority ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ (๋†’์„์ˆ˜๋ก ์ƒ๋‹จ โ†’ U-shaped attention)\nexport const sortRulesByPriority = (rules: readonly Rule[]): Rule[] =>\n [...rules].sort((a, b) => b.priority - a.priority);\n\nconst deduplicateRulesById = (rules: readonly Rule[]): Rule[] => {\n const seen = new Set<string>();\n return rules.filter((rule) => {\n if (seen.has(rule.id)) return false;\n seen.add(rule.id);\n return true;\n });\n};\n\nconst resolveBundledRuleIds = (presetId: string, logicalRuleId: string): readonly string[] => {\n const presetBundles = PRESET_RULE_BUNDLES[presetId];\n if (!presetBundles) return [logicalRuleId];\n return presetBundles[logicalRuleId] ?? [logicalRuleId];\n};\n\nconst resolveRuleById = (ruleId: string, allRules: readonly Rule[], context?: string): Rule => {\n const found = allRules.find((rule) => rule.id === ruleId);\n if (!found) {\n const suffix = context ? ` (from ${context})` : '';\n throw new Error(`Rule not found: ${ruleId}${suffix}`);\n }\n return found;\n};\n\n// presets.yaml์˜ Record<id, {description, rules}> โ†’ Preset[] ๋ณ€ํ™˜\nexport const parseRawPresets = (raw: Record<string, { description: string; rules: string[] }>): Preset[] =>\n Object.entries(raw).map(([id, value]) => PresetSchema.parse({ id, ...value }));\n\nexport const resolvePresetRuleGroups = (preset: Preset, allRules: readonly Rule[]): PresetRuleGroup[] =>\n preset.rules.map((logicalRuleId) => {\n const bundledRuleIds = resolveBundledRuleIds(preset.id, logicalRuleId);\n const rules = bundledRuleIds.map((ruleId) => resolveRuleById(ruleId, allRules, `${preset.id}:${logicalRuleId}`));\n return { id: logicalRuleId, rules };\n });\n\n// TUI ์„ธ๋ถ€์กฐ์ •: ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด์ œํ•œ rule ID ๋ชฉ๋ก์„ ์ œ์™ธ (์ˆœ์„œ ์œ ์ง€)\nexport const excludeRules = (rules: readonly Rule[], excludeIds: readonly string[]): Rule[] => {\n const excludeSet = new Set(excludeIds);\n return rules.filter((r) => !excludeSet.has(r.id));\n};\n\n// preset.rules(๋…ผ๋ฆฌ ID ํฌํ•จ) ๋ชฉ๋ก์„ ์‹ค์ œ rule๋กœ ํ™•์žฅ + priority ์ •๋ ฌ, ๋ˆ„๋ฝ ์‹œ throw\nexport const resolvePresetRules = (preset: Preset, allRules: readonly Rule[]): Rule[] => {\n const groups = resolvePresetRuleGroups(preset, allRules);\n const resolved = deduplicateRulesById(groups.flatMap((group) => group.rules));\n return sortRulesByPriority(resolved);\n};\n\nexport const loadRuleFile = (filePath: string): Rule => {\n const raw = readFileSync(filePath, 'utf-8');\n return RuleSchema.parse(parse(raw));\n};\n\n// readdirSync + .yaml ํ•„ํ„ฐ + ํŒŒ์ผ๋ช… sort(๊ฒฐ์ •์  ๋กœ๋”ฉ) โ†’ priority ๋‚ด๋ฆผ์ฐจ์ˆœ\nexport const loadAllRules = (rulesDir: string): Rule[] => {\n const files = readdirSync(rulesDir)\n .filter((f) => f.endsWith('.yaml'))\n .sort();\n const rules = files.map((f) => loadRuleFile(resolve(rulesDir, f)));\n return sortRulesByPriority(rules);\n};\n\nexport const loadPresets = (presetsPath: string): Preset[] => {\n const raw = readFileSync(presetsPath, 'utf-8');\n const data = parse(raw) as Record<string, { description: string; rules: string[] }>;\n return parseRawPresets(data);\n};\n","import { join } from 'node:path';\nimport type { Rule, DecisionTableEntry } from './schemas/index.js';\nimport { GLOBAL_CATEGORIES, CLAUDE_CODE_PATH_GLOBS, TOOL_OUTPUT_MAP } from './tool-output.js';\nimport type { ToolId } from './tool-output.js';\n\n// \"react-typescript\" โ†’ \"React Typescript\"\nexport const ruleIdToTitle = (id: string): string =>\n id\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n// DecisionTableEntry[] โ†’ Markdown ํ…Œ์ด๋ธ” (pipe ๋ฌธ์ž &#124; escape)\nexport const renderDecisionTable = (entries: readonly DecisionTableEntry[]): string => {\n const escape = (s: string) => s.replace(/\\|/g, '&#124;');\n const hasAvoid = entries.some((e) => e.avoid !== undefined);\n\n const header = hasAvoid ? '| When | Then | Avoid |\\n|------|------|-------|' : '| When | Then |\\n|------|------|';\n\n const rows = entries.map((e) => {\n const when = escape(e.when);\n const then = escape(e.then);\n if (hasAvoid) {\n const avoid = e.avoid ? escape(e.avoid) : '';\n return `| ${when} | ${then} | ${avoid} |`;\n }\n return `| ${when} | ${then} |`;\n });\n\n return [header, ...rows].join('\\n');\n};\n\n// ๋‹จ์ผ Rule โ†’ Markdown (๋นˆ ์„น์…˜ ์ƒ๋žต)\nexport const renderRuleToMarkdown = (rule: Rule): string => {\n const sections: string[] = [`# ${ruleIdToTitle(rule.id)}`];\n\n if (rule.content.constraints.length > 0) {\n sections.push('## Constraints');\n sections.push(rule.content.constraints.map((c) => `- ${c}`).join('\\n'));\n }\n\n if (rule.content.guidelines.length > 0) {\n sections.push('## Guidelines');\n sections.push(rule.content.guidelines.map((g) => `- ${g}`).join('\\n'));\n }\n\n if (rule.content.decision_table && rule.content.decision_table.length > 0) {\n sections.push('## Decision Table');\n sections.push(renderDecisionTable(rule.content.decision_table));\n }\n\n return sections.join('\\n\\n');\n};\n\n// Rule[] โ†’ ๋‹จ์ผ Markdown (--- separator, single-file ๋ชจ๋“œ์šฉ)\nexport const renderRulesToMarkdown = (rules: readonly Rule[]): string =>\n rules.map(renderRuleToMarkdown).join('\\n\\n---\\n\\n');\n\n// Rule์ด global ์นดํ…Œ๊ณ ๋ฆฌ์— ์†ํ•˜๋Š”์ง€ ํŒ๋ณ„\nexport const isGlobalRule = (rule: Rule): boolean => (GLOBAL_CATEGORIES as readonly string[]).includes(rule.category);\n\n// Rule[] โ†’ { global, domain } ๋ถ„๋ฆฌ\nexport const partitionRules = (rules: readonly Rule[]): { global: Rule[]; domain: Rule[] } => {\n const global: Rule[] = [];\n const domain: Rule[] = [];\n for (const rule of rules) {\n if (isGlobalRule(rule)) {\n global.push(rule);\n } else {\n domain.push(rule);\n }\n }\n return { global, domain };\n};\n\n// glob ๋ฐฐ์—ด โ†’ YAML frontmatter ๋ธ”๋ก\nexport const renderFrontmatter = (paths: readonly string[]): string => {\n const lines = paths.map((p) => ` - \"${p}\"`).join('\\n');\n return `---\\npaths:\\n${lines}\\n---`;\n};\n\nexport type WorkspaceMapping = {\n path: string;\n ruleIds: readonly string[];\n};\n\n// ๋‹จ์ผ Rule โ†’ Claude Code์šฉ Markdown\n// domain ๋ฃฐ์ด๋ฉด์„œ glob ๋งคํ•‘์ด ์žˆ์œผ๋ฉด paths: frontmatter ์ถ”๊ฐ€ (๋‹จ์ผ ํ”„๋กœ์ ํŠธ ์ „์šฉ)\n// global ๋ฃฐ ๋˜๋Š” ๋งคํ•‘ ์—†๋Š” domain ๋ฃฐ โ†’ frontmatter ์—†์Œ\nexport const renderClaudeCodeRule = (rule: Rule): string => {\n const globs = CLAUDE_CODE_PATH_GLOBS[rule.id];\n if (!isGlobalRule(rule) && globs !== undefined) {\n return `${renderFrontmatter(globs)}\\n\\n${renderRuleToMarkdown(rule)}`;\n }\n return renderRuleToMarkdown(rule);\n};\n\n// ๋„๊ตฌ๋ณ„ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ ํƒ€์ž… (tagged union)\nexport type ClaudeCodeRenderResult = {\n tool: 'claude-code';\n files: { relativePath: string; content: string }[];\n};\n\nexport type CodexRenderResult = {\n tool: 'codex';\n rootContent: string;\n domainFiles: { workspacePath: string; content: string }[];\n};\n\nexport type GeminiRenderResult = {\n tool: 'gemini';\n rootContent: string;\n domainFiles: { workspacePath: string; content: string }[];\n};\n\nexport type ToolRenderResult = ClaudeCodeRenderResult | CodexRenderResult | GeminiRenderResult;\n\n// CLI ์ง„์ž…์ : toolId + rules โ†’ ๋„๊ตฌ๋ณ„ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ\nexport const renderForTool = (\n toolId: ToolId,\n rules: readonly Rule[],\n workspaceMappings?: readonly WorkspaceMapping[],\n): ToolRenderResult => {\n const config = TOOL_OUTPUT_MAP[toolId];\n\n if (toolId === 'claude-code') {\n const { rulesDir, fileExtension } = config as (typeof TOOL_OUTPUT_MAP)['claude-code'];\n\n if (!workspaceMappings || workspaceMappings.length === 0) {\n // ๋‹จ์ผ ํ”„๋กœ์ ํŠธ: domain ๋ฃฐ์— paths: frontmatter (path-scoped)\n const files = rules.map((rule) => ({\n relativePath: join(rulesDir, `${rule.id}${fileExtension}`),\n content: renderClaudeCodeRule(rule),\n }));\n return { tool: 'claude-code', files };\n }\n\n // ๋ชจ๋…ธ๋ ˆํฌ: global โ†’ .claude/rules/, domain โ†’ {workspace}/CLAUDE.md (์ง„์งœ ์ง€์—ฐ ๋กœ๋”ฉ)\n const { global, domain } = partitionRules(rules);\n\n const globalFiles = global.map((rule) => ({\n relativePath: join(rulesDir, `${rule.id}${fileExtension}`),\n content: renderRuleToMarkdown(rule), // global์€ frontmatter ๋ถˆํ•„์š”\n }));\n\n const workspaceFiles: { relativePath: string; content: string }[] = [];\n for (const ws of workspaceMappings) {\n const wsRules = domain.filter((r) => ws.ruleIds.includes(r.id));\n if (wsRules.length === 0) continue;\n workspaceFiles.push({\n relativePath: join(ws.path, 'CLAUDE.md'),\n content: renderRulesToMarkdown(wsRules),\n });\n }\n\n return { tool: 'claude-code', files: [...globalFiles, ...workspaceFiles] };\n }\n\n if (!workspaceMappings || workspaceMappings.length === 0) {\n // ๋‹จ์ผ ํ”„๋กœ์ ํŠธ: ๋ชจ๋“  ๋ฃฐ(global + domain)์„ rootContent ํ•˜๋‚˜๋กœ ํ•ฉ์นจ\n const rootContent = renderRulesToMarkdown(rules);\n const domainFiles: { workspacePath: string; content: string }[] = [];\n\n if (toolId === 'codex') return { tool: 'codex', rootContent, domainFiles };\n return { tool: 'gemini', rootContent, domainFiles };\n }\n\n // ๋ชจ๋…ธ๋ ˆํฌ: global โ†’ rootContent, domain โ†’ workspace๋ณ„ ํŒŒ์ผ\n const { global, domain } = partitionRules(rules);\n const rootContent = renderRulesToMarkdown(global);\n const domainFiles: { workspacePath: string; content: string }[] = [];\n for (const ws of workspaceMappings) {\n const wsRules = domain.filter((r) => ws.ruleIds.includes(r.id));\n if (wsRules.length === 0) continue;\n domainFiles.push({ workspacePath: ws.path, content: renderRulesToMarkdown(wsRules) });\n }\n\n if (toolId === 'codex') {\n return { tool: 'codex', rootContent, domainFiles };\n }\n\n // gemini\n return { tool: 'gemini', rootContent, domainFiles };\n};\n","// Global ์„ฑ๊ฒฉ์˜ category (ํ•ญ์ƒ ๋กœ๋”ฉ, frontmatter ์—†์Œ)\nexport const GLOBAL_CATEGORIES = ['persona', 'communication', 'philosophy', 'convention', 'standard'] as const;\n\n// Claude Code paths: frontmatter์šฉ Rule ID โ†’ glob ๋งคํ•‘\n// src/ ์—†์ด ๋ฃจํŠธ๋ฅผ src์ฒ˜๋Ÿผ ์“ฐ๋Š” React/Next.js ํ”„๋กœ์ ํŠธ ๊ณ ๋ ค\n// ๋งคํ•‘์— ์—†๋Š” domain ๋ฃฐ โ†’ frontmatter ์—†์ด ํ•ญ์ƒ ๋กœ๋”ฉ (์•ˆ์ „ fallback)\nexport const CLAUDE_CODE_PATH_GLOBS: Readonly<Record<string, readonly string[]>> = {\n typescript: ['**/*.ts', '**/*.tsx'],\n 'react-typescript': ['**/*.tsx', '**/*.jsx'],\n nextjs: ['**/app/**', 'next.config.*', '**/middleware.ts'],\n nestjs: ['**/*.module.ts', '**/*.controller.ts', '**/*.service.ts'],\n 'nestjs-graphql': ['**/*.resolver.ts'],\n 'graphql-core': ['**/*.graphql', '**/*.gql'],\n 'graphql-client-web': ['**/*.graphql', '**/*.gql', '**/*.tsx', '**/*.ts'],\n 'graphql-client-app': ['**/*.graphql', '**/*.gql', 'lib/**/*.dart'],\n 'graphql-server': ['**/*.graphql', '**/*.gql', '**/*.resolver.ts'],\n 'prisma-postgresql': ['prisma/**', '**/*.prisma'],\n 'shadcn-ui': ['**/components/ui/**'],\n flutter: ['lib/**/*.dart'],\n python: ['**/*.py'],\n fastapi: ['**/routers/**', '**/main.py'],\n sqlalchemy: ['**/models/**/*.py', 'alembic/**'],\n 'data-pipeline-python': ['**/pipelines/**', '**/etl/**'],\n 'ai-llm-python': ['**/agents/**', '**/chains/**'],\n 'libs-frontend-web': ['**/*.tsx', '**/*.ts'],\n 'libs-frontend-app': ['lib/**/*.dart'],\n 'libs-backend-ts': ['**/*.ts'],\n 'libs-backend-python': ['**/*.py'],\n};\n\nexport const TOOL_OUTPUT_MAP = {\n 'claude-code': {\n mode: 'multi-file' as const,\n rulesDir: '.claude/rules',\n fileExtension: '.md',\n // single: path-scoped (paths: frontmatter) / monorepo: hierarchical ({workspace}/CLAUDE.md)\n contextStrategy: 'hybrid' as const,\n },\n codex: {\n mode: 'multi-file' as const,\n dir: '',\n rootFileName: 'AGENTS.md', // global ๋ฃฐ\n domainFileName: 'AGENTS.override.md', // domain ๋ฃฐ (ํ•˜์œ„ ํด๋”)\n contextStrategy: 'hierarchical' as const, // ๋ฃจํŠธ + ํ•˜์œ„ ํด๋” JIT\n },\n gemini: {\n mode: 'multi-file' as const,\n dir: '.gemini',\n rootFileName: 'GEMINI.md', // global ๋ฃฐ\n domainFileName: 'GEMINI.md', // domain ๋ฃฐ (ํ•˜์œ„ ํด๋”)\n contextStrategy: 'hierarchical' as const, // ๋ฃจํŠธ + ํ•˜์œ„ ํด๋” JIT\n },\n} as const;\n\nexport type ToolId = keyof typeof TOOL_OUTPUT_MAP;\n","import { createHash } from 'node:crypto';\nimport { readFileSync, readdirSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { ManifestSchema } from './schemas/index.js';\nimport type { Manifest } from './schemas/index.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// dist/bin/index.js(bundle) ๊ธฐ์ค€: ../../package.json = apps/cli/package.json\nexport const getCliVersion = (): string => {\n try {\n const pkgPath = resolve(__dirname, '..', '..', 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as { version: string };\n return pkg.version;\n } catch {\n return 'unknown';\n }\n};\n\n// ๋ฌธ์ž์—ด ๋ฐฐ์—ด โ†’ SHA-256 โ†’ 6-hex (caller๊ฐ€ ์ •๋ ฌ ์ฑ…์ž„)\nexport const computeHash = (contents: readonly string[]): string =>\n createHash('sha256').update(contents.join('')).digest('hex').slice(0, 6);\n\n// rulesDir ๋‚ด YAML ํŒŒ์ผ๋“ค์„ alphabetical ์ •๋ ฌ ํ›„ ํ•ด์‹ฑ\nexport const computeSourceHash = (rulesDir: string): string => {\n const files = readdirSync(rulesDir)\n .filter((f) => f.endsWith('.yaml'))\n .sort();\n const contents = files.map((f) => readFileSync(resolve(rulesDir, f), 'utf-8'));\n return computeHash(contents);\n};\n\n// Manifest Builder (Pure, ๋‹จ generatedAt์— ํ˜„์žฌ ์‹œ๊ฐ ์‚ฌ์šฉ)\nexport const buildManifest = (params: {\n tools: readonly string[];\n scope: 'project';\n preset?: string;\n workspaces?: Record<string, { preset: string; rules: string[] }>;\n installedRules: readonly string[];\n installedFiles?: readonly string[];\n appendedFiles?: readonly string[];\n settings?: { claude?: readonly string[]; gemini?: readonly string[]; prettierignore?: boolean };\n cliVersion?: string;\n sourceHash: string;\n}): Manifest =>\n ManifestSchema.parse({\n tools: [...params.tools],\n scope: params.scope,\n preset: params.preset,\n workspaces: params.workspaces,\n installed_rules: [...params.installedRules],\n installed_files: params.installedFiles ? [...params.installedFiles] : undefined,\n appended_files: params.appendedFiles && params.appendedFiles.length > 0 ? [...params.appendedFiles] : undefined,\n settings: params.settings\n ? {\n claude: params.settings.claude ? [...params.settings.claude] : undefined,\n gemini: params.settings.gemini ? [...params.settings.gemini] : undefined,\n }\n : undefined,\n cliVersion: params.cliVersion,\n sourceHash: params.sourceHash,\n generatedAt: new Date().toISOString(),\n });\n","const MANAGED_MARKER = '<!-- managed by ai-ops -->';\nconst META_PATTERN = /^<!-- sourceHash: ([a-f0-9]{6}) \\| generatedAt: (.+) -->$/;\n\nconst SECTION_START = '<!-- ai-ops:start -->';\nconst SECTION_END = '<!-- ai-ops:end -->';\n\nexport const hasLegacyHeader = (content: string): boolean => content.includes(MANAGED_MARKER);\n\nexport const wrapWithSection = (content: string, meta: { sourceHash: string; generatedAt: string }): string => {\n const metaLine = `<!-- sourceHash: ${meta.sourceHash} | generatedAt: ${meta.generatedAt} -->`;\n return `${SECTION_START}\\n${metaLine}\\n\\n${content}\\n${SECTION_END}`;\n};\n\nexport const hasAiOpsSection = (content: string): boolean =>\n content.includes(SECTION_START) && content.includes(SECTION_END);\n\nexport const stripAiOpsSection = (content: string): string => {\n const startIdx = content.indexOf(SECTION_START);\n const endIdx = content.indexOf(SECTION_END);\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + SECTION_END.length).trimStart();\n return before + (after ? '\\n\\n' + after : '') + '\\n';\n};\n\nexport const replaceAiOpsSection = (existing: string, newSection: string): string => {\n const startIdx = existing.indexOf(SECTION_START);\n const endIdx = existing.indexOf(SECTION_END);\n if (startIdx === -1 || endIdx === -1) return existing;\n\n const before = existing.slice(0, startIdx).trimEnd();\n const after = existing.slice(endIdx + SECTION_END.length).trimStart();\n\n // filter(Boolean)์œผ๋กœ ๋นˆ before/after ์ œ๊ฑฐ โ†’ ๋ถˆํ•„์š”ํ•œ ์„ ํ–‰ \\n\\n ๋ฐฉ์ง€\n return [before, newSection, after].filter(Boolean).join('\\n\\n') + '\\n';\n};\n\nexport const parseAiOpsMeta = (content: string): { sourceHash: string; generatedAt: string } | null => {\n const startIdx = content.indexOf(SECTION_START);\n if (startIdx === -1) return null;\n\n const lines = content.slice(startIdx).split('\\n');\n // lines[0] = '<!-- ai-ops:start -->', lines[1] = meta line\n const metaLine = lines[1] ?? '';\n const match = META_PATTERN.exec(metaLine);\n if (!match) return null;\n\n return { sourceHash: match[1], generatedAt: match[2] };\n};\n","import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { ManifestSchema } from './schemas/index.js';\nimport type { Manifest } from './schemas/index.js';\n\nexport const MANIFEST_FILENAME = '.ai-ops-manifest.json';\n\n// Pure\nexport const parseManifest = (json: string): Manifest => ManifestSchema.parse(JSON.parse(json));\n\nexport const serializeManifest = (manifest: Manifest): string => JSON.stringify(manifest, null, 2) + '\\n';\n\n// I/O\nexport const resolveManifestPath = (basePath: string): string => join(basePath, MANIFEST_FILENAME);\n\nexport const readManifest = (manifestPath: string): Manifest | null => {\n let raw: string;\n try {\n raw = readFileSync(manifestPath, 'utf-8');\n } catch {\n return null;\n }\n return parseManifest(raw);\n};\n\nexport const writeManifest = (manifestPath: string, manifest: Manifest): void => {\n mkdirSync(dirname(manifestPath), { recursive: true });\n writeFileSync(manifestPath, serializeManifest(manifest), 'utf-8');\n};\n","import type { Manifest } from './schemas/index.js';\n\nexport type DiffResult = {\n status: 'up-to-date' | 'changed';\n added: readonly string[];\n removed: readonly string[];\n sourceChanged: boolean;\n versionChanged: boolean;\n};\n\nexport const computeDiff = (params: {\n previous: Manifest;\n currentRules: readonly string[];\n currentSourceHash: string;\n currentCliVersion?: string;\n}): DiffResult => {\n const { previous, currentRules, currentSourceHash, currentCliVersion } = params;\n\n const previousSet = new Set(previous.installed_rules);\n const currentSet = new Set(currentRules);\n\n const added = currentRules.filter((id) => !previousSet.has(id));\n const removed = previous.installed_rules.filter((id) => !currentSet.has(id));\n const sourceChanged = previous.sourceHash !== currentSourceHash;\n // previous.cliVersion์ด ์—†๋Š” ๋ ˆ๊ฑฐ์‹œ manifest๋Š” ๋ฒ„์ „ ๋ณ€๊ฒฝ์œผ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š์Œ\n const versionChanged =\n previous.cliVersion !== undefined &&\n currentCliVersion !== undefined &&\n previous.cliVersion !== currentCliVersion;\n\n const status =\n added.length > 0 || removed.length > 0 || sourceChanged || versionChanged ? 'changed' : 'up-to-date';\n\n return { status, added, removed, sourceChanged, versionChanged };\n};\n","import { join } from 'node:path';\nimport { wrapWithSection } from './managed-header.js';\nimport { TOOL_OUTPUT_MAP } from './tool-output.js';\nimport type { ToolId } from './tool-output.js';\nimport type { ToolRenderResult } from './renderer.js';\n\n// Codex has no settings.json โ€” plan directory convention must live in AGENTS.md\nconst CODEX_PLAN_BODY =\n '## Plan Snapshot (Plan mode only)\\n\\n' +\n '- This rule applies only when `collaboration_mode=Plan`.\\n' +\n '- Before implementation (file edits/creates, installs, commits), save the latest plan content to `.codex/plans/YYYYMMDD_<topic>.md`.\\n' +\n '- In `Default` mode, do not automatically create or update plan files.';\n\nexport type FileAction = {\n relativePath: string;\n content: string;\n};\n\nexport const buildInstallPlan = (params: {\n toolId: ToolId;\n renderResult: ToolRenderResult;\n meta: { sourceHash: string; generatedAt: string };\n}): readonly FileAction[] => {\n const { toolId, renderResult, meta } = params;\n\n if (toolId === 'claude-code' && renderResult.tool === 'claude-code') {\n return renderResult.files.map(({ relativePath, content }) => ({\n relativePath,\n content: wrapWithSection(content, meta),\n }));\n }\n\n if (toolId === 'codex' && renderResult.tool === 'codex') {\n const config = TOOL_OUTPUT_MAP['codex'];\n const actions: FileAction[] = [];\n\n // CODEX_PLAN_BODY is always written to root AGENTS.md regardless of whether global rules exist\n const rootContent = renderResult.rootContent\n ? renderResult.rootContent + '\\n\\n---\\n\\n' + CODEX_PLAN_BODY\n : CODEX_PLAN_BODY;\n\n actions.push({\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithSection(rootContent, meta),\n });\n\n for (const df of renderResult.domainFiles) {\n actions.push({\n relativePath: join(df.workspacePath, config.domainFileName),\n content: wrapWithSection(df.content, meta),\n });\n }\n\n return actions;\n }\n\n if (toolId === 'gemini' && renderResult.tool === 'gemini') {\n const config = TOOL_OUTPUT_MAP['gemini'];\n const actions: FileAction[] = [];\n\n if (renderResult.rootContent) {\n actions.push({\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithSection(renderResult.rootContent, meta),\n });\n }\n\n for (const df of renderResult.domainFiles) {\n actions.push({\n relativePath: join(df.workspacePath, config.domainFileName),\n content: wrapWithSection(df.content, meta),\n });\n }\n\n return actions;\n }\n\n return [];\n};\n","import { join } from 'node:path';\nimport { TOOL_OUTPUT_MAP } from './tool-output.js';\nimport type { Manifest } from './schemas/index.js';\n\n/**\n * manifest์— installed_files๊ฐ€ ์—†๋Š” ๊ตฌ๋ฒ„์ „ manifest๋ฅผ ์œ„ํ•œ fallback.\n * manifest์˜ tools/workspaces/installed_rules ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ\n * ์‹ค์ œ ์„ค์น˜๋์„ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์—ญ์‚ฐํ•œ๋‹ค.\n */\nexport const inferInstalledFiles = (manifest: Manifest): string[] => {\n const files: string[] = [];\n const isMonorepo = manifest.workspaces !== undefined;\n\n for (const toolId of manifest.tools) {\n if (toolId === 'claude-code') {\n // claude-code: .claude/rules/{ruleId}.md\n const config = TOOL_OUTPUT_MAP['claude-code'];\n for (const ruleId of manifest.installed_rules) {\n files.push(join(config.rulesDir, `${ruleId}${config.fileExtension}`));\n }\n } else if (toolId === 'codex') {\n const config = TOOL_OUTPUT_MAP['codex'];\n if (!isMonorepo) {\n // ๋น„๋ชจ๋…ธ: .codex/AGENTS.md + .codex/AGENTS.override.md (domain ์žˆ์œผ๋ฉด)\n files.push(join(config.dir, config.rootFileName));\n files.push(join(config.dir, config.domainFileName));\n } else {\n // ๋ชจ๋…ธ: .codex/AGENTS.md (global) + {workspace}/AGENTS.override.md (domain)\n files.push(join(config.dir, config.rootFileName));\n for (const ws of Object.keys(manifest.workspaces ?? {})) {\n files.push(join(ws, config.domainFileName));\n }\n }\n } else if (toolId === 'gemini') {\n const config = TOOL_OUTPUT_MAP['gemini'];\n if (!isMonorepo) {\n // ๋น„๋ชจ๋…ธ: .gemini/GEMINI.md\n files.push(join(config.dir, config.rootFileName));\n } else {\n // ๋ชจ๋…ธ: .gemini/GEMINI.md (global) + {workspace}/GEMINI.md (domain)\n files.push(join(config.dir, config.rootFileName));\n for (const ws of Object.keys(manifest.workspaces ?? {})) {\n files.push(join(ws, config.domainFileName));\n }\n }\n }\n }\n\n // ์ค‘๋ณต ์ œ๊ฑฐ (codex ๋น„๋ชจ๋…ธ์—์„œ rootFileName === domainFileName์ธ ๊ฒฝ์šฐ ๋Œ€๋น„)\n return [...new Set(files)];\n};\n","import { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n// src/core/* ๋˜๋Š” dist/bin/index.js ๊ธฐ์ค€์—์„œ๋„ ๊ณตํ†ต์œผ๋กœ ํŒจํ‚ค์ง€ ๋ฃจํŠธ/data๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๊ณ„์‚ฐ\n// src/core/paths.ts โ†’ ../../data = apps/cli/data\n// dist/bin/index.js (bundle) โ†’ ../../data = apps/cli/data\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const COMPILER_DATA_DIR = resolve(__dirname, '..', '..', 'data');\n","import { join } from 'node:path';\nimport { COMPILER_DATA_DIR } from '@/core/index.js';\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// project-only ์„ค์น˜ ๊ธฐ์ค€ ๋””๋ ‰ํ† ๋ฆฌ\nexport const resolveBasePath = (): string => 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 hasAiOpsSection,\n replaceAiOpsSection,\n stripAiOpsSection,\n hasLegacyHeader,\n} from '@/core/index.js';\nimport type { FileAction } from '@/core/index.js';\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 mkdirSync(dirname(absPath), { recursive: true });\n writeFileSync(absPath, action.content + '\\n', 'utf-8');\n written.push(action.relativePath);\n } else {\n const existing = readFileSync(absPath, 'utf-8');\n\n if (hasAiOpsSection(existing)) {\n // ๊ธฐ์กด ๋ธ”๋ก ๊ต์ฒด (์‚ฌ์šฉ์ž ์ฝ˜ํ…์ธ  ์ž๋™ ๋ณด์กด)\n const updated = replaceAiOpsSection(existing, action.content);\n writeFileSync(absPath, updated, 'utf-8');\n const stripped = stripAiOpsSection(existing);\n (stripped.trim().length > 0 ? appended : written).push(action.relativePath);\n } else if (hasLegacyHeader(existing)) {\n // ๋ ˆ๊ฑฐ์‹œ โ†’ ์ƒˆ ํ˜•์‹์œผ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ (update ์‹œ ์ž๋™ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜)\n writeFileSync(absPath, action.content + '\\n', 'utf-8');\n written.push(action.relativePath);\n } else {\n // ์ˆœ์ˆ˜ ์‚ฌ์šฉ์ž ํŒŒ์ผ โ†’ ์ตœ์ดˆ append\n const updated = existing.trimEnd() + '\\n\\n' + action.content + '\\n';\n writeFileSync(absPath, updated, 'utf-8');\n appended.push(action.relativePath);\n }\n }\n }\n\n return { written, appended, skipped };\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { deepMerge, deepRemoveKeys } from './deep-merge.util.js';\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\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\nexport type SettingsUninstallStatus = 'deleted' | 'cleaned' | 'notFound';\n\nexport const uninstallGeminiSettings = (basePath: string, selectedValues: readonly string[]): SettingsUninstallStatus => {\n const settingsPath = join(basePath, '.gemini', 'settings.json');\n\n if (!existsSync(settingsPath)) return 'notFound';\n\n let existing: GeminiSettings = {};\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as GeminiSettings;\n } catch {\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n let result: GeminiSettings = existing;\n for (const val of selectedValues) {\n const group = SETTING_GROUPS.find((g) => g.value === val);\n if (!group) continue;\n result = deepRemoveKeys(result as Record<string, unknown>, group.patch as Record<string, unknown>) as GeminiSettings;\n }\n\n if (Object.keys(result).length === 0) {\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n writeFileSync(settingsPath, JSON.stringify(result, null, 2) + '\\n', 'utf-8');\n return 'cleaned';\n};\n","export const 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 !Array.isArray(result[key])\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\nexport const deepRemoveKeys = (\n base: Record<string, unknown>,\n patch: Record<string, unknown>,\n): Record<string, unknown> => {\n const result = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n if (!(key in result)) continue;\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n typeof result[key] === 'object' &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n const nested = deepRemoveKeys(result[key] as Record<string, unknown>, value as Record<string, unknown>);\n if (Object.keys(nested).length === 0) {\n delete result[key];\n } else {\n result[key] = nested;\n }\n } else {\n delete result[key];\n }\n }\n return result;\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { deepMerge, deepRemoveKeys } from './deep-merge.util.js';\n\ntype ClaudeSettings = Record<string, unknown>;\n\ntype SettingGroup = {\n value: string;\n label: string;\n hint: string;\n patch: ClaudeSettings;\n};\n\nconst SETTING_GROUPS: readonly SettingGroup[] = [\n {\n value: 'model',\n label: 'Model โ€” Plan ๋ชจ๋“œ ๋ชจ๋ธ',\n hint: 'model: opusplan โ€” Plan ๋ชจ๋“œ์—์„œ Opus ๋ชจ๋ธ ์‚ฌ์šฉ',\n patch: { model: 'opusplan' },\n },\n {\n value: 'plansDirectory',\n label: 'Plans Directory โ€” ๊ณ„ํš ํŒŒ์ผ ์ €์žฅ ๊ฒฝ๋กœ',\n hint: 'plansDirectory: ./.claude/plans โ€” ๊ณ„ํš ํŒŒ์ผ์„ .claude/plans์— ์ €์žฅ',\n patch: { plansDirectory: './.claude/plans' },\n },\n] as const;\n\n// null โ†’ ๊ฑด๋„ˆ๋œ€ (์ทจ์†Œ ๋˜๋Š” \"No\"), string[] โ†’ ์„ ํƒ๋œ ํ•ญ๋ชฉ\nexport const promptClaudeSettings = async (): Promise<readonly string[] | null> => {\n const wantSettings = await p.confirm({\n message: 'Claude Code ์„ค์ • ํŒŒ์ผ(.claude/settings.local.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 installClaudeSettings = (basePath: string, selectedValues: readonly string[]): void => {\n if (selectedValues.length === 0) return;\n\n const settingsDir = join(basePath, '.claude');\n const settingsPath = join(settingsDir, 'settings.local.json');\n\n let existing: ClaudeSettings = {};\n if (existsSync(settingsPath)) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as ClaudeSettings;\n } catch {\n // parse ์‹คํŒจ ์‹œ ๋ฎ์–ด์“ฐ๊ธฐ\n }\n }\n\n let merged: ClaudeSettings = 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, group.patch);\n }\n\n mkdirSync(settingsDir, { recursive: true });\n writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n};\n\nexport type SettingsUninstallStatus = 'deleted' | 'cleaned' | 'notFound';\n\nexport const uninstallClaudeSettings = (basePath: string, selectedValues: readonly string[]): SettingsUninstallStatus => {\n const settingsPath = join(basePath, '.claude', 'settings.local.json');\n\n if (!existsSync(settingsPath)) return 'notFound';\n\n let existing: ClaudeSettings = {};\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as ClaudeSettings;\n } catch {\n // parse ์‹คํŒจ ์‹œ ์‚ญ์ œ๋กœ ์ฒ˜๋ฆฌ\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n let result: ClaudeSettings = existing;\n for (const val of selectedValues) {\n const group = SETTING_GROUPS.find((g) => g.value === val);\n if (!group) continue;\n result = deepRemoveKeys(result as Record<string, unknown>, group.patch as Record<string, unknown>) as ClaudeSettings;\n }\n\n if (Object.keys(result).length === 0) {\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n writeFileSync(settingsPath, JSON.stringify(result, null, 2) + '\\n', 'utf-8');\n return 'cleaned';\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst PRETTIER_IGNORE_CONTENT = `# CLAUDE\n.claude/rules/\n**/CLAUDE.md\n\n# GEMINI\n**/GEMINI.md\n\n# CODEX\n**/AGENTS.md\n**/AGENTS.override.md\n\n.ai-ops-manifest.json`;\n\nconst SECTION_START = '# ai-ops:start';\nconst SECTION_END = '# ai-ops:end';\n\nconst wrapSection = (content: string): string => `${SECTION_START}\\n${content}\\n${SECTION_END}`;\n\nconst hasAiOpsSection = (content: string): boolean =>\n content.includes(SECTION_START) && content.includes(SECTION_END);\n\nconst replaceSection = (content: string, newContent: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inside = false;\n let replaced = false;\n\n for (const line of lines) {\n if (line.trim() === SECTION_START) {\n inside = true;\n result.push(wrapSection(newContent));\n replaced = true;\n continue;\n }\n if (line.trim() === SECTION_END) {\n inside = false;\n continue;\n }\n if (!inside) result.push(line);\n }\n\n if (!replaced) result.push(wrapSection(newContent));\n return result.join('\\n');\n};\n\nconst stripAiOpsSection = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inside = false;\n\n for (const line of lines) {\n if (line.trim() === SECTION_START) {\n inside = true;\n continue;\n }\n if (line.trim() === SECTION_END) {\n inside = false;\n continue;\n }\n if (!inside) result.push(line);\n }\n\n return result.join('\\n');\n};\n\nexport const promptPrettierIgnore = async (): Promise<boolean> => {\n const want = await p.confirm({\n message: '.prettierignore๋ฅผ ์„ค์น˜ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? (VSCode Prettier ์ž๋™ ํฌ๋งท์œผ๋กœ๋ถ€ํ„ฐ AI ๊ทœ์น™ ํŒŒ์ผ ๋ณดํ˜ธ)',\n initialValue: false,\n });\n if (p.isCancel(want)) return false;\n return want;\n};\n\nexport const installPrettierIgnore = (basePath: string): void => {\n const filePath = join(basePath, '.prettierignore');\n const section = wrapSection(PRETTIER_IGNORE_CONTENT);\n\n if (!existsSync(filePath)) {\n writeFileSync(filePath, section + '\\n', 'utf-8');\n return;\n }\n\n const existing = readFileSync(filePath, 'utf-8');\n\n if (hasAiOpsSection(existing)) {\n writeFileSync(filePath, replaceSection(existing, PRETTIER_IGNORE_CONTENT), 'utf-8');\n return;\n }\n\n const separator = existing.endsWith('\\n') ? '\\n' : '\\n\\n';\n writeFileSync(filePath, existing + separator + section + '\\n', 'utf-8');\n};\n\nexport type PrettierIgnoreUninstallStatus = 'deleted' | 'cleaned' | 'notFound';\n\nexport const uninstallPrettierIgnore = (basePath: string): PrettierIgnoreUninstallStatus => {\n const filePath = join(basePath, '.prettierignore');\n if (!existsSync(filePath)) return 'notFound';\n\n const existing = readFileSync(filePath, 'utf-8');\n if (!hasAiOpsSection(existing)) return 'notFound';\n\n const stripped = stripAiOpsSection(existing).trim();\n if (stripped.length === 0) {\n rmSync(filePath, { force: true });\n return 'deleted';\n }\n\n writeFileSync(filePath, stripped + '\\n', 'utf-8');\n return 'cleaned';\n};\n","import * as p from '@clack/prompts';\nimport type { ToolId } from '@/core/index.js';\nimport {\n readManifest,\n resolveManifestPath,\n loadAllRules,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n writeManifest,\n computeSourceHash,\n computeDiff,\n getCliVersion,\n} from '@/core/index.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\nimport { installFiles } from '../lib/install.js';\nimport { installClaudeSettings } from '../lib/claude-settings.js';\nimport { installGeminiSettings } from '../lib/gemini-settings.js';\nimport { installPrettierIgnore } from '../lib/prettier-ignore.js';\n\nexport const updateCommand = async (opts: { force: boolean }): Promise<void> => {\n const basePath = resolveBasePath();\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 const cliVersion = getCliVersion();\n\n const diffResult = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n currentCliVersion: cliVersion,\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 const allInstalledRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const workspaceMappings = workspaceEntries.map(([path, entry]) => ({\n path,\n ruleIds: entry.rules,\n }));\n const renderResult = renderForTool(toolId, rulesToInstall, workspaceMappings);\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 } 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 if (manifest.settings?.claude) {\n installClaudeSettings(basePath, manifest.settings.claude);\n }\n\n if (manifest.settings?.gemini) {\n installGeminiSettings(basePath, manifest.settings.gemini);\n }\n\n if (manifest.settings?.prettierignore) {\n installPrettierIgnore(basePath);\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 settings: manifest.settings\n ? {\n claude: manifest.settings.claude,\n gemini: manifest.settings.gemini,\n prettierignore: manifest.settings.prettierignore,\n }\n : undefined,\n cliVersion,\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 '@/core/index.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\n\nexport const diffCommand = async (): Promise<void> => {\n const basePath = resolveBasePath();\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 '@/core/index.js';\nimport { resolveBasePath } from '../lib/paths.js';\nimport { removeFiles, cleanEmptyDirs, collectManagedDirs } from '../lib/uninstall.js';\nimport { uninstallClaudeSettings } from '../lib/claude-settings.js';\nimport { uninstallGeminiSettings } from '../lib/gemini-settings.js';\nimport { uninstallPrettierIgnore } from '../lib/prettier-ignore.js';\n\nconst SETTINGS_PATHS = new Set(['.claude/settings.local.json', '.gemini/settings.json']);\n\nexport const uninstallCommand = async (): Promise<void> => {\n const basePath = resolveBasePath();\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๋œ ํŒŒ์ผ, settings ํŒŒ์ผ ์ œ์™ธ)\n const targetFiles = [\n ...(manifest.installed_files ?? inferInstalledFiles(manifest)),\n ...(manifest.appended_files ?? []),\n ].filter((f) => !SETTINGS_PATHS.has(f));\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. settings ํŒŒ์ผ ๋ณ„๋„ ์ฒ˜๋ฆฌ\n const settingsMessages: string[] = [];\n if (manifest.settings?.claude) {\n const status = uninstallClaudeSettings(basePath, manifest.settings.claude);\n if (status === 'deleted') settingsMessages.push('์‚ญ์ œ: .claude/settings.local.json');\n else if (status === 'cleaned') settingsMessages.push('ai-ops ํ‚ค ์ œ๊ฑฐ (์‚ฌ์šฉ์ž ์„ค์ • ๋ณด์กด): .claude/settings.local.json');\n }\n if (manifest.settings?.gemini) {\n const status = uninstallGeminiSettings(basePath, manifest.settings.gemini);\n if (status === 'deleted') settingsMessages.push('์‚ญ์ œ: .gemini/settings.json');\n else if (status === 'cleaned') settingsMessages.push('ai-ops ํ‚ค ์ œ๊ฑฐ (์‚ฌ์šฉ์ž ์„ค์ • ๋ณด์กด): .gemini/settings.json');\n }\n const prettierStatus = uninstallPrettierIgnore(basePath);\n if (prettierStatus === 'deleted') settingsMessages.push('์‚ญ์ œ: .prettierignore');\n else if (prettierStatus === 'cleaned') settingsMessages.push('ai-ops ์„น์…˜ ์ œ๊ฑฐ (์‚ฌ์šฉ์ž ๋‚ด์šฉ ๋ณด์กด): .prettierignore');\n\n // 6. ํŒŒ์ผ ์‚ญ์ œ\n const result = removeFiles(basePath, targetFiles);\n\n // 7. ๋นˆ ๋””๋ ‰ํ† ๋ฆฌ ์ •๋ฆฌ\n const dirs = collectManagedDirs(targetFiles);\n const removedDirs = cleanEmptyDirs(basePath, dirs);\n\n // 8. manifest ์‚ญ์ œ\n rmSync(manifestPath, { force: true });\n\n // 9. ๊ฒฐ๊ณผ ์š”์•ฝ\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 if (settingsMessages.length > 0) {\n p.log.success(`์„ค์ • ํŒŒ์ผ ์ฒ˜๋ฆฌ:\\n${settingsMessages.map((m) => ` ${m}`).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 { hasAiOpsSection, stripAiOpsSection, hasLegacyHeader } from '@/core/index.js';\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 (hasAiOpsSection(content)) {\n const stripped = stripAiOpsSection(content);\n if (stripped.trim().length === 0) {\n rmSync(absPath);\n deleted.push(rel);\n } else {\n writeFileSync(absPath, stripped, 'utf-8');\n cleaned.push(rel);\n }\n } else if (hasLegacyHeader(content)) {\n rmSync(absPath);\n deleted.push(rel);\n } else {\n skipped.push(rel);\n }\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":"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","names":["p","z","z","z","p","global","domain","rootContent","domainFiles","readFileSync","readdirSync","resolve","resolve","readFileSync","readdirSync","readFileSync","dirname","join","join","readFileSync","dirname","join","join","join","join","dirname","resolve","fileURLToPath","__dirname","join","join","readdirSync","join","resolve","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","resolve","resolve","existsSync","mkdirSync","dirname","writeFileSync","readFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","p","existsSync","mkdirSync","readFileSync","rmSync","writeFileSync","join","SETTING_GROUPS","join","existsSync","readFileSync","mkdirSync","writeFileSync","rmSync","p","existsSync","readFileSync","rmSync","writeFileSync","join","SECTION_START","SECTION_END","hasAiOpsSection","stripAiOpsSection","allRules","p","r","p","p","rmSync","existsSync","readFileSync","rmSync","readdirSync","writeFileSync","resolve","dirname","resolve","existsSync","readFileSync","rmSync","writeFileSync","readdirSync","dirname","rmSync"]}
1
+ {"version":3,"sources":["../../src/bin/index.ts","../../src/commands/init.ts","../../src/core/schemas/rule.schema.ts","../../src/core/schemas/preset.schema.ts","../../src/core/schemas/manifest.schema.ts","../../src/core/loader.ts","../../src/core/renderer.ts","../../src/core/tool-output.ts","../../src/core/source-hash.ts","../../src/core/managed-header.ts","../../src/core/manifest-io.ts","../../src/core/diff.ts","../../src/core/install-plan.ts","../../src/core/uninstall-plan.ts","../../src/core/paths.ts","../../src/lib/paths.ts","../../src/lib/workspace.ts","../../src/lib/install.ts","../../src/lib/gemini-settings.ts","../../src/lib/deep-merge.util.ts","../../src/lib/claude-settings.ts","../../src/lib/prettier-ignore.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';\n\nconst program = new Command();\n\nconst ensureNoDeprecatedScopeFlag = (argv: readonly string[]): void => {\n if (argv.some((arg) => arg === '--scope' || arg.startsWith('--scope='))) {\n console.error('`--scope` is no longer supported. ai-ops is now project-only.');\n process.exit(1);\n }\n};\n\nprogram.name('ai-ops').description('AI ์—์ด์ „ํŠธ ๊ทœ์น™ ์Šค์บํด๋”').version('0.1.0');\n\nprogram\n .command('init')\n .description('AI ๊ทœ์น™ ์ดˆ๊ธฐ ์„ค์น˜')\n .action(() => initCommand());\n\nprogram\n .command('update')\n .description('๊ธฐ์กด manifest ๊ธฐ๋ฐ˜ ๊ทœ์น™ ๊ฐฑ์‹ ')\n .option('--force', '๋ณ€๊ฒฝ ์—†์–ด๋„ ๊ฐ•์ œ ์žฌ์„ค์น˜', false)\n .action((opts: { force: boolean }) => updateCommand(opts));\n\nprogram\n .command('diff')\n .description('์„ค์น˜๋œ ๊ทœ์น™๊ณผ ์ตœ์‹  ์†Œ์Šค ๋น„๊ต')\n .action(() => diffCommand());\n\nprogram\n .command('uninstall')\n .description('์„ค์น˜๋œ ๊ทœ์น™ ํŒŒ์ผ ๋ฐ manifest ์ œ๊ฑฐ')\n .action(() => uninstallCommand());\n\nensureNoDeprecatedScopeFlag(process.argv);\nprogram.parse();\n","import * as p from '@clack/prompts';\nimport type { Rule, Preset, ToolId, WorkspaceMapping } from '@/core/index.js';\nimport {\n loadAllRules,\n loadPresets,\n resolvePresetRules,\n resolvePresetRuleGroups,\n isGlobalRule,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n computeSourceHash,\n getCliVersion,\n resolveManifestPath,\n writeManifest,\n} from '@/core/index.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';\nimport { promptClaudeSettings, installClaudeSettings } from '../lib/claude-settings.js';\nimport { promptPrettierIgnore, installPrettierIgnore } from '../lib/prettier-ignore.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 presetRuleGroups = resolvePresetRuleGroups(preset, allRules);\n const globalGroups = presetRuleGroups.filter((group) => group.rules.every(isGlobalRule));\n const domainGroups = presetRuleGroups.filter((group) => !group.rules.every(isGlobalRule));\n const globalGroupIds = globalGroups.map((group) => group.id);\n const globalRules =\n globalGroupIds.length > 0 ? resolvePresetRules({ ...preset, rules: globalGroupIds }, allRules) : [];\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 (domainGroups.length === 0) {\n return { workspace: workspaceName, preset, finalRules: resolvePresetRules(preset, allRules) };\n }\n\n // Domain rules: ์ œ์™ธ ๊ฐ€๋Šฅ\n const selectedDomain = await p.multiselect<string>({\n message: `[${workspaceName}] ๋„๋ฉ”์ธ ๊ทœ์น™ ์„ ํƒ (ํ•ด์ œํ•˜์—ฌ ์ œ์™ธ)`,\n options: domainGroups.map((group) => ({ value: group.id, label: group.id })),\n initialValues: domainGroups.map((group) => group.id),\n required: false,\n });\n if (p.isCancel(selectedDomain)) return null;\n\n const selectedLogicalRuleIds = [...globalGroupIds, ...(selectedDomain as string[])];\n return {\n workspace: workspaceName,\n preset,\n finalRules: resolvePresetRules({ ...preset, rules: selectedLogicalRuleIds }, allRules),\n };\n};\n\nexport const initCommand = async (): Promise<void> => {\n const basePath = resolveBasePath();\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 // 4.6. Claude ์„ค์ • (claude-code ์„ ํƒ ์‹œ)\n const claudeSettingValues: readonly string[] | null = (selectedTools as ToolId[]).includes('claude-code')\n ? await promptClaudeSettings()\n : null;\n\n // 4.7. .prettierignore ์„ค์น˜ ์—ฌ๋ถ€\n const wantPrettierIgnore = await promptPrettierIgnore();\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 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(toolId, allRules, workspaceMappings);\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 } 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 }\n\n if (claudeSettingValues && claudeSettingValues.length > 0) {\n installClaudeSettings(basePath, claudeSettingValues);\n }\n\n if (wantPrettierIgnore) {\n installPrettierIgnore(basePath);\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: 'project',\n preset: !isMonorepo ? mappings[0].preset.id : undefined,\n workspaces: workspacesRecord,\n installedRules: allInstalledRuleIds,\n installedFiles: allInstalledFiles,\n appendedFiles: allAppended,\n settings:\n claudeSettingValues || geminiSettingValues || wantPrettierIgnore\n ? {\n claude: claudeSettingValues ? [...claudeSettingValues] : undefined,\n gemini: geminiSettingValues ? [...geminiSettingValues] : undefined,\n prettierignore: wantPrettierIgnore || undefined,\n }\n : undefined,\n cliVersion: getCliVersion(),\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","/**\n * Rule = SSOT์˜ ์ตœ์†Œ ์ง€์‹ ๋‹จ์œ„. ํ•˜๋‚˜์˜ ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜/์•„ํ‚คํ…์ฒ˜ ๊ทœ์น™์„ YAML๋กœ ๊ตฌ์กฐํ™”ํ•œ ๊ฒƒ.\n */\nimport { z } from 'zod';\n\nexport const DecisionTableEntrySchema = z\n .object({\n when: z.string().min(1),\n then: z.string().min(1),\n /** ์กฐ๊ฑด๋ถ€ ๊ทœ์น™์—์„œ ํšŒํ”ผํ•ด์•ผ ํ•  ํŒจํ„ด */\n avoid: z.string().min(1).optional(),\n })\n .strict();\n\nexport const RuleContentSchema = z\n .object({\n /** Anti-pattern ๊ทœ์น™ ('ํ•˜์ง€ ๋งˆ๋ผ'). guidelines๋ณด๋‹ค ํ•ญ์ƒ ์ƒ๋‹จ ๋ Œ๋”๋ง */\n constraints: z.array(z.string().min(1)),\n /** Positive ๊ทœ์น™ ('ํ•ด๋ผ') */\n guidelines: z.array(z.string().min(1)),\n /** ์กฐ๊ฑด๋ถ€ ๊ทœ์น™. whenโ†’thenโ†’avoid ๊ตฌ์กฐ */\n decision_table: z.array(DecisionTableEntrySchema).optional(),\n })\n .strict();\n\nexport const RuleSchema = z\n .object({\n id: z.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, 'id must be kebab-case'),\n category: z.string().min(1),\n tags: z.array(z.string().min(1)),\n /** 0-100. ๋†’์„์ˆ˜๋ก ์ƒ์„ฑ ํŒŒ์ผ ์ƒ๋‹จ ๋ฐฐ์น˜ (U-shaped attention ์ตœ์ ํ™”) */\n priority: z.number().int().min(0).max(100),\n content: RuleContentSchema,\n })\n .strict();\n\nexport type DecisionTableEntry = z.infer<typeof DecisionTableEntrySchema>;\nexport type RuleContent = z.infer<typeof RuleContentSchema>;\nexport type Rule = z.infer<typeof RuleSchema>;\n","import { z } from 'zod';\n\nexport const PresetSchema = z\n .object({\n id: z\n .string()\n .regex(/^[a-z][a-z0-9-]*$/)\n .min(1),\n description: z.string().min(1),\n rules: z.array(z.string().min(1)).min(1),\n })\n .strict();\n\nexport type Preset = z.infer<typeof PresetSchema>;\n","/**\n * Manifest = ์„ค์น˜ ์ถ”์  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ. CLI๊ฐ€ ์ด์ „ ์„ค์น˜ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜๊ธฐ ์œ„ํ•œ JSON.\n */\nimport { z } from 'zod';\n\nexport const SCOPES = {\n PROJECT: 'project',\n} as const;\n\n/** init/update ์‹œ ์„ ํƒ๋œ settings ํ•ญ๋ชฉ ์ถ”์  */\nconst SettingsConfigSchema = z\n .object({\n claude: z.array(z.string().min(1)).optional(),\n gemini: z.array(z.string().min(1)).optional(),\n prettierignore: z.boolean().optional(),\n })\n .strict();\n\nexport type SettingsConfig = z.infer<typeof SettingsConfigSchema>;\n\n/** ๋ชจ๋…ธ๋ ˆํฌ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ณ„ preset + rules ์ถ”์  */\nconst WorkspaceEntrySchema = z\n .object({\n preset: z.string().min(1),\n rules: z.array(z.string().min(1)),\n })\n .strict();\n\nexport type WorkspaceEntry = z.infer<typeof WorkspaceEntrySchema>;\n\nexport const ManifestSchema = z\n .object({\n tools: z.array(z.string().min(1)).min(1),\n scope: z.literal('project'),\n /** ๋น„๋ชจ๋…ธ๋ ˆํฌ ๋‹จ์ผ preset */\n preset: z.string().min(1).optional(),\n /** ๋ชจ๋…ธ๋ ˆํฌ: workspace path โ†’ { preset, rules } */\n workspaces: z.record(z.string(), WorkspaceEntrySchema).optional(),\n installed_rules: z.array(z.string().min(1)),\n /** ์‹ค์ œ ๋””์Šคํฌ์— ์“ฐ์—ฌ์ง„ ํŒŒ์ผ ์ƒ๋Œ€ ๊ฒฝ๋กœ ๋ชฉ๋ก (uninstall์šฉ). ๊ธฐ์กด manifest ํ˜ธํ™˜์„ฑ ์œ„ํ•ด optional */\n installed_files: z.array(z.string().min(1)).optional(),\n /** non-managed ํŒŒ์ผ์— ์„น์…˜์„ appendํ•œ ๊ฒฝ์šฐ ์ถ”์  (uninstall ์‹œ ์„น์…˜๋งŒ ์ œ๊ฑฐ) */\n appended_files: z.array(z.string().min(1)).optional(),\n /** init ์‹œ ์„ ํƒ๋œ settings ํ•ญ๋ชฉ โ€” update ์‹œ ์žฌ์ƒ์„ฑ์— ์‚ฌ์šฉ */\n settings: SettingsConfigSchema.optional(),\n /** init/update ์‹คํ–‰ ์‹œ์ ์˜ CLI ํŒจํ‚ค์ง€ ๋ฒ„์ „ โ€” ๋ฒ„์ „ ๋ณ€๊ฒฝ ๊ฐ์ง€์— ์‚ฌ์šฉ */\n cliVersion: z.string().optional(),\n /** SSOT ๋ฐ์ดํ„ฐ ํŒŒ์ผ๋“ค์˜ deterministic SHA-256 ํ•ด์‹œ (6์ž๋ฆฌ hex). diff/update ํŒ๋‹จ ๊ธฐ์ค€ */\n sourceHash: z.string().regex(/^[a-f0-9]{6}$/, 'sourceHash must be 6 lowercase hex chars'),\n generatedAt: z.string().datetime({ offset: true }),\n })\n .strict();\n\nexport type Manifest = z.infer<typeof ManifestSchema>;\n","import { readFileSync, readdirSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { parse } from 'yaml';\nimport { RuleSchema, PresetSchema } from './schemas/index.js';\nimport type { Rule, Preset } from './schemas/index.js';\n\ntype PresetRuleBundles = Readonly<Record<string, Readonly<Record<string, readonly string[]>>>>;\n\nexport const PRESET_RULE_BUNDLES: PresetRuleBundles = {\n 'frontend-web': {\n graphql: ['graphql-core', 'graphql-client-web'],\n },\n 'frontend-app': {\n graphql: ['graphql-core', 'graphql-client-app'],\n },\n 'backend-ts': {\n graphql: ['graphql-core', 'graphql-server'],\n },\n} as const;\n\nexport type PresetRuleGroup = {\n id: string;\n rules: Rule[];\n};\n\n// priority ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ (๋†’์„์ˆ˜๋ก ์ƒ๋‹จ โ†’ U-shaped attention)\nexport const sortRulesByPriority = (rules: readonly Rule[]): Rule[] =>\n [...rules].sort((a, b) => b.priority - a.priority);\n\nconst deduplicateRulesById = (rules: readonly Rule[]): Rule[] => {\n const seen = new Set<string>();\n return rules.filter((rule) => {\n if (seen.has(rule.id)) return false;\n seen.add(rule.id);\n return true;\n });\n};\n\nconst resolveBundledRuleIds = (presetId: string, logicalRuleId: string): readonly string[] => {\n const presetBundles = PRESET_RULE_BUNDLES[presetId];\n if (!presetBundles) return [logicalRuleId];\n return presetBundles[logicalRuleId] ?? [logicalRuleId];\n};\n\nconst resolveRuleById = (ruleId: string, allRules: readonly Rule[], context?: string): Rule => {\n const found = allRules.find((rule) => rule.id === ruleId);\n if (!found) {\n const suffix = context ? ` (from ${context})` : '';\n throw new Error(`Rule not found: ${ruleId}${suffix}`);\n }\n return found;\n};\n\n// presets.yaml์˜ Record<id, {description, rules}> โ†’ Preset[] ๋ณ€ํ™˜\nexport const parseRawPresets = (raw: Record<string, { description: string; rules: string[] }>): Preset[] =>\n Object.entries(raw).map(([id, value]) => PresetSchema.parse({ id, ...value }));\n\nexport const resolvePresetRuleGroups = (preset: Preset, allRules: readonly Rule[]): PresetRuleGroup[] =>\n preset.rules.map((logicalRuleId) => {\n const bundledRuleIds = resolveBundledRuleIds(preset.id, logicalRuleId);\n const rules = bundledRuleIds.map((ruleId) => resolveRuleById(ruleId, allRules, `${preset.id}:${logicalRuleId}`));\n return { id: logicalRuleId, rules };\n });\n\n// TUI ์„ธ๋ถ€์กฐ์ •: ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด์ œํ•œ rule ID ๋ชฉ๋ก์„ ์ œ์™ธ (์ˆœ์„œ ์œ ์ง€)\nexport const excludeRules = (rules: readonly Rule[], excludeIds: readonly string[]): Rule[] => {\n const excludeSet = new Set(excludeIds);\n return rules.filter((r) => !excludeSet.has(r.id));\n};\n\n// preset.rules(๋…ผ๋ฆฌ ID ํฌํ•จ) ๋ชฉ๋ก์„ ์‹ค์ œ rule๋กœ ํ™•์žฅ + priority ์ •๋ ฌ, ๋ˆ„๋ฝ ์‹œ throw\nexport const resolvePresetRules = (preset: Preset, allRules: readonly Rule[]): Rule[] => {\n const groups = resolvePresetRuleGroups(preset, allRules);\n const resolved = deduplicateRulesById(groups.flatMap((group) => group.rules));\n return sortRulesByPriority(resolved);\n};\n\nexport const loadRuleFile = (filePath: string): Rule => {\n const raw = readFileSync(filePath, 'utf-8');\n return RuleSchema.parse(parse(raw));\n};\n\n// readdirSync + .yaml ํ•„ํ„ฐ + ํŒŒ์ผ๋ช… sort(๊ฒฐ์ •์  ๋กœ๋”ฉ) โ†’ priority ๋‚ด๋ฆผ์ฐจ์ˆœ\nexport const loadAllRules = (rulesDir: string): Rule[] => {\n const files = readdirSync(rulesDir)\n .filter((f) => f.endsWith('.yaml'))\n .sort();\n const rules = files.map((f) => loadRuleFile(resolve(rulesDir, f)));\n return sortRulesByPriority(rules);\n};\n\nexport const loadPresets = (presetsPath: string): Preset[] => {\n const raw = readFileSync(presetsPath, 'utf-8');\n const data = parse(raw) as Record<string, { description: string; rules: string[] }>;\n return parseRawPresets(data);\n};\n","import { join } from 'node:path';\nimport type { Rule, DecisionTableEntry } from './schemas/index.js';\nimport { GLOBAL_CATEGORIES, CLAUDE_CODE_PATH_GLOBS, TOOL_OUTPUT_MAP } from './tool-output.js';\nimport type { ToolId } from './tool-output.js';\n\n// \"react-typescript\" โ†’ \"React Typescript\"\nexport const ruleIdToTitle = (id: string): string =>\n id\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n// DecisionTableEntry[] โ†’ Markdown ํ…Œ์ด๋ธ” (pipe ๋ฌธ์ž &#124; escape)\nexport const renderDecisionTable = (entries: readonly DecisionTableEntry[]): string => {\n const escape = (s: string) => s.replace(/\\|/g, '&#124;');\n const hasAvoid = entries.some((e) => e.avoid !== undefined);\n\n const header = hasAvoid ? '| When | Then | Avoid |\\n|------|------|-------|' : '| When | Then |\\n|------|------|';\n\n const rows = entries.map((e) => {\n const when = escape(e.when);\n const then = escape(e.then);\n if (hasAvoid) {\n const avoid = e.avoid ? escape(e.avoid) : '';\n return `| ${when} | ${then} | ${avoid} |`;\n }\n return `| ${when} | ${then} |`;\n });\n\n return [header, ...rows].join('\\n');\n};\n\n// ๋‹จ์ผ Rule โ†’ Markdown (๋นˆ ์„น์…˜ ์ƒ๋žต)\nexport const renderRuleToMarkdown = (rule: Rule): string => {\n const sections: string[] = [`# ${ruleIdToTitle(rule.id)}`];\n\n if (rule.content.constraints.length > 0) {\n sections.push('## Constraints');\n sections.push(rule.content.constraints.map((c) => `- ${c}`).join('\\n'));\n }\n\n if (rule.content.guidelines.length > 0) {\n sections.push('## Guidelines');\n sections.push(rule.content.guidelines.map((g) => `- ${g}`).join('\\n'));\n }\n\n if (rule.content.decision_table && rule.content.decision_table.length > 0) {\n sections.push('## Decision Table');\n sections.push(renderDecisionTable(rule.content.decision_table));\n }\n\n return sections.join('\\n\\n');\n};\n\n// Rule[] โ†’ ๋‹จ์ผ Markdown (--- separator, single-file ๋ชจ๋“œ์šฉ)\nexport const renderRulesToMarkdown = (rules: readonly Rule[]): string =>\n rules.map(renderRuleToMarkdown).join('\\n\\n---\\n\\n');\n\n// Rule์ด global ์นดํ…Œ๊ณ ๋ฆฌ์— ์†ํ•˜๋Š”์ง€ ํŒ๋ณ„\nexport const isGlobalRule = (rule: Rule): boolean => (GLOBAL_CATEGORIES as readonly string[]).includes(rule.category);\n\n// Rule[] โ†’ { global, domain } ๋ถ„๋ฆฌ\nexport const partitionRules = (rules: readonly Rule[]): { global: Rule[]; domain: Rule[] } => {\n const global: Rule[] = [];\n const domain: Rule[] = [];\n for (const rule of rules) {\n if (isGlobalRule(rule)) {\n global.push(rule);\n } else {\n domain.push(rule);\n }\n }\n return { global, domain };\n};\n\n// glob ๋ฐฐ์—ด โ†’ YAML frontmatter ๋ธ”๋ก\nexport const renderFrontmatter = (paths: readonly string[]): string => {\n const lines = paths.map((p) => ` - \"${p}\"`).join('\\n');\n return `---\\npaths:\\n${lines}\\n---`;\n};\n\nexport type WorkspaceMapping = {\n path: string;\n ruleIds: readonly string[];\n};\n\n// ๋‹จ์ผ Rule โ†’ Claude Code์šฉ Markdown\n// domain ๋ฃฐ์ด๋ฉด์„œ glob ๋งคํ•‘์ด ์žˆ์œผ๋ฉด paths: frontmatter ์ถ”๊ฐ€ (๋‹จ์ผ ํ”„๋กœ์ ํŠธ ์ „์šฉ)\n// global ๋ฃฐ ๋˜๋Š” ๋งคํ•‘ ์—†๋Š” domain ๋ฃฐ โ†’ frontmatter ์—†์Œ\nexport const renderClaudeCodeRule = (rule: Rule): string => {\n const globs = CLAUDE_CODE_PATH_GLOBS[rule.id];\n if (!isGlobalRule(rule) && globs !== undefined) {\n return `${renderFrontmatter(globs)}\\n\\n${renderRuleToMarkdown(rule)}`;\n }\n return renderRuleToMarkdown(rule);\n};\n\n// ๋„๊ตฌ๋ณ„ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ ํƒ€์ž… (tagged union)\nexport type ClaudeCodeRenderResult = {\n tool: 'claude-code';\n files: { relativePath: string; content: string }[];\n};\n\nexport type CodexRenderResult = {\n tool: 'codex';\n rootContent: string;\n domainFiles: { workspacePath: string; content: string }[];\n};\n\nexport type GeminiRenderResult = {\n tool: 'gemini';\n rootContent: string;\n domainFiles: { workspacePath: string; content: string }[];\n};\n\nexport type ToolRenderResult = ClaudeCodeRenderResult | CodexRenderResult | GeminiRenderResult;\n\n// CLI ์ง„์ž…์ : toolId + rules โ†’ ๋„๊ตฌ๋ณ„ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ\nexport const renderForTool = (\n toolId: ToolId,\n rules: readonly Rule[],\n workspaceMappings?: readonly WorkspaceMapping[],\n): ToolRenderResult => {\n const config = TOOL_OUTPUT_MAP[toolId];\n\n if (toolId === 'claude-code') {\n const { rulesDir, fileExtension } = config as (typeof TOOL_OUTPUT_MAP)['claude-code'];\n\n if (!workspaceMappings || workspaceMappings.length === 0) {\n // ๋‹จ์ผ ํ”„๋กœ์ ํŠธ: domain ๋ฃฐ์— paths: frontmatter (path-scoped)\n const files = rules.map((rule) => ({\n relativePath: join(rulesDir, `${rule.id}${fileExtension}`),\n content: renderClaudeCodeRule(rule),\n }));\n return { tool: 'claude-code', files };\n }\n\n // ๋ชจ๋…ธ๋ ˆํฌ: global โ†’ .claude/rules/, domain โ†’ {workspace}/CLAUDE.md (์ง„์งœ ์ง€์—ฐ ๋กœ๋”ฉ)\n const { global, domain } = partitionRules(rules);\n\n const globalFiles = global.map((rule) => ({\n relativePath: join(rulesDir, `${rule.id}${fileExtension}`),\n content: renderRuleToMarkdown(rule), // global์€ frontmatter ๋ถˆํ•„์š”\n }));\n\n const workspaceFiles: { relativePath: string; content: string }[] = [];\n for (const ws of workspaceMappings) {\n const wsRules = domain.filter((r) => ws.ruleIds.includes(r.id));\n if (wsRules.length === 0) continue;\n workspaceFiles.push({\n relativePath: join(ws.path, 'CLAUDE.md'),\n content: renderRulesToMarkdown(wsRules),\n });\n }\n\n return { tool: 'claude-code', files: [...globalFiles, ...workspaceFiles] };\n }\n\n if (!workspaceMappings || workspaceMappings.length === 0) {\n // ๋‹จ์ผ ํ”„๋กœ์ ํŠธ: ๋ชจ๋“  ๋ฃฐ(global + domain)์„ rootContent ํ•˜๋‚˜๋กœ ํ•ฉ์นจ\n const rootContent = renderRulesToMarkdown(rules);\n const domainFiles: { workspacePath: string; content: string }[] = [];\n\n if (toolId === 'codex') return { tool: 'codex', rootContent, domainFiles };\n return { tool: 'gemini', rootContent, domainFiles };\n }\n\n // ๋ชจ๋…ธ๋ ˆํฌ: global โ†’ rootContent, domain โ†’ workspace๋ณ„ ํŒŒ์ผ\n const { global, domain } = partitionRules(rules);\n const rootContent = renderRulesToMarkdown(global);\n const domainFiles: { workspacePath: string; content: string }[] = [];\n for (const ws of workspaceMappings) {\n const wsRules = domain.filter((r) => ws.ruleIds.includes(r.id));\n if (wsRules.length === 0) continue;\n domainFiles.push({ workspacePath: ws.path, content: renderRulesToMarkdown(wsRules) });\n }\n\n if (toolId === 'codex') {\n return { tool: 'codex', rootContent, domainFiles };\n }\n\n // gemini\n return { tool: 'gemini', rootContent, domainFiles };\n};\n","// Global ์„ฑ๊ฒฉ์˜ category (ํ•ญ์ƒ ๋กœ๋”ฉ, frontmatter ์—†์Œ)\nexport const GLOBAL_CATEGORIES = ['persona', 'communication', 'philosophy', 'convention', 'standard'] as const;\n\n// Claude Code paths: frontmatter์šฉ Rule ID โ†’ glob ๋งคํ•‘\n// src/ ์—†์ด ๋ฃจํŠธ๋ฅผ src์ฒ˜๋Ÿผ ์“ฐ๋Š” React/Next.js ํ”„๋กœ์ ํŠธ ๊ณ ๋ ค\n// ๋งคํ•‘์— ์—†๋Š” domain ๋ฃฐ โ†’ frontmatter ์—†์ด ํ•ญ์ƒ ๋กœ๋”ฉ (์•ˆ์ „ fallback)\nexport const CLAUDE_CODE_PATH_GLOBS: Readonly<Record<string, readonly string[]>> = {\n typescript: ['**/*.ts', '**/*.tsx'],\n 'react-typescript': ['**/*.tsx', '**/*.jsx'],\n nextjs: ['**/app/**', 'next.config.*', '**/middleware.ts'],\n nestjs: ['**/*.module.ts', '**/*.controller.ts', '**/*.service.ts'],\n 'nestjs-graphql': ['**/*.resolver.ts'],\n 'graphql-core': ['**/*.graphql', '**/*.gql'],\n 'graphql-client-web': ['**/*.graphql', '**/*.gql', '**/*.tsx', '**/*.ts'],\n 'graphql-client-app': ['**/*.graphql', '**/*.gql', 'lib/**/*.dart'],\n 'graphql-server': ['**/*.graphql', '**/*.gql', '**/*.resolver.ts'],\n 'prisma-postgresql': ['prisma/**', '**/*.prisma'],\n 'shadcn-ui': ['**/components/ui/**'],\n flutter: ['lib/**/*.dart'],\n python: ['**/*.py'],\n fastapi: ['**/routers/**', '**/main.py'],\n sqlalchemy: ['**/models/**/*.py', 'alembic/**'],\n 'data-pipeline-python': ['**/pipelines/**', '**/etl/**'],\n 'ai-llm-python': ['**/agents/**', '**/chains/**'],\n 'libs-frontend-web': ['**/*.tsx', '**/*.ts'],\n 'libs-frontend-app': ['lib/**/*.dart'],\n 'libs-backend-ts': ['**/*.ts'],\n 'libs-backend-python': ['**/*.py'],\n};\n\nexport const TOOL_OUTPUT_MAP = {\n 'claude-code': {\n mode: 'multi-file' as const,\n rulesDir: '.claude/rules',\n fileExtension: '.md',\n // single: path-scoped (paths: frontmatter) / monorepo: hierarchical ({workspace}/CLAUDE.md)\n contextStrategy: 'hybrid' as const,\n },\n codex: {\n mode: 'multi-file' as const,\n dir: '',\n rootFileName: 'AGENTS.md', // global ๋ฃฐ\n domainFileName: 'AGENTS.override.md', // domain ๋ฃฐ (ํ•˜์œ„ ํด๋”)\n contextStrategy: 'hierarchical' as const, // ๋ฃจํŠธ + ํ•˜์œ„ ํด๋” JIT\n },\n gemini: {\n mode: 'multi-file' as const,\n dir: '',\n rootFileName: 'GEMINI.md', // global ๋ฃฐ (๋ฃจํŠธ)\n domainFileName: 'GEMINI.md', // domain ๋ฃฐ (ํ•˜์œ„ ํด๋”)\n contextStrategy: 'hierarchical' as const, // ๋ฃจํŠธ + ํ•˜์œ„ ํด๋” JIT\n },\n} as const;\n\nexport type ToolId = keyof typeof TOOL_OUTPUT_MAP;\n","import { createHash } from 'node:crypto';\nimport { readFileSync, readdirSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { ManifestSchema } from './schemas/index.js';\nimport type { Manifest } from './schemas/index.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// dist/bin/index.js(bundle) ๊ธฐ์ค€: ../../package.json = apps/cli/package.json\nexport const getCliVersion = (): string => {\n try {\n const pkgPath = resolve(__dirname, '..', '..', 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as { version: string };\n return pkg.version;\n } catch {\n return 'unknown';\n }\n};\n\n// ๋ฌธ์ž์—ด ๋ฐฐ์—ด โ†’ SHA-256 โ†’ 6-hex (caller๊ฐ€ ์ •๋ ฌ ์ฑ…์ž„)\nexport const computeHash = (contents: readonly string[]): string =>\n createHash('sha256').update(contents.join('')).digest('hex').slice(0, 6);\n\n// rulesDir ๋‚ด YAML ํŒŒ์ผ๋“ค์„ alphabetical ์ •๋ ฌ ํ›„ ํ•ด์‹ฑ\nexport const computeSourceHash = (rulesDir: string): string => {\n const files = readdirSync(rulesDir)\n .filter((f) => f.endsWith('.yaml'))\n .sort();\n const contents = files.map((f) => readFileSync(resolve(rulesDir, f), 'utf-8'));\n return computeHash(contents);\n};\n\n// Manifest Builder (Pure, ๋‹จ generatedAt์— ํ˜„์žฌ ์‹œ๊ฐ ์‚ฌ์šฉ)\nexport const buildManifest = (params: {\n tools: readonly string[];\n scope: 'project';\n preset?: string;\n workspaces?: Record<string, { preset: string; rules: string[] }>;\n installedRules: readonly string[];\n installedFiles?: readonly string[];\n appendedFiles?: readonly string[];\n settings?: { claude?: readonly string[]; gemini?: readonly string[]; prettierignore?: boolean };\n cliVersion?: string;\n sourceHash: string;\n}): Manifest =>\n ManifestSchema.parse({\n tools: [...params.tools],\n scope: params.scope,\n preset: params.preset,\n workspaces: params.workspaces,\n installed_rules: [...params.installedRules],\n installed_files: params.installedFiles ? [...params.installedFiles] : undefined,\n appended_files: params.appendedFiles && params.appendedFiles.length > 0 ? [...params.appendedFiles] : undefined,\n settings: params.settings\n ? {\n claude: params.settings.claude ? [...params.settings.claude] : undefined,\n gemini: params.settings.gemini ? [...params.settings.gemini] : undefined,\n }\n : undefined,\n cliVersion: params.cliVersion,\n sourceHash: params.sourceHash,\n generatedAt: new Date().toISOString(),\n });\n","const MANAGED_MARKER = '<!-- managed by ai-ops -->';\nconst META_PATTERN = /^<!-- sourceHash: ([a-f0-9]{6}) \\| generatedAt: (.+) -->$/;\n\nconst SECTION_START = '<!-- ai-ops:start -->';\nconst SECTION_END = '<!-- ai-ops:end -->';\n\nexport const hasLegacyHeader = (content: string): boolean => content.includes(MANAGED_MARKER);\n\nexport const wrapWithSection = (content: string, meta: { sourceHash: string; generatedAt: string }): string => {\n const metaLine = `<!-- sourceHash: ${meta.sourceHash} | generatedAt: ${meta.generatedAt} -->`;\n return `${SECTION_START}\\n${metaLine}\\n\\n${content}\\n${SECTION_END}`;\n};\n\nexport const hasAiOpsSection = (content: string): boolean =>\n content.includes(SECTION_START) && content.includes(SECTION_END);\n\nexport const stripAiOpsSection = (content: string): string => {\n const startIdx = content.indexOf(SECTION_START);\n const endIdx = content.indexOf(SECTION_END);\n if (startIdx === -1 || endIdx === -1) return content;\n\n const before = content.slice(0, startIdx).trimEnd();\n const after = content.slice(endIdx + SECTION_END.length).trimStart();\n return before + (after ? '\\n\\n' + after : '') + '\\n';\n};\n\nexport const replaceAiOpsSection = (existing: string, newSection: string): string => {\n const startIdx = existing.indexOf(SECTION_START);\n const endIdx = existing.indexOf(SECTION_END);\n if (startIdx === -1 || endIdx === -1) return existing;\n\n const before = existing.slice(0, startIdx).trimEnd();\n const after = existing.slice(endIdx + SECTION_END.length).trimStart();\n\n // filter(Boolean)์œผ๋กœ ๋นˆ before/after ์ œ๊ฑฐ โ†’ ๋ถˆํ•„์š”ํ•œ ์„ ํ–‰ \\n\\n ๋ฐฉ์ง€\n return [before, newSection, after].filter(Boolean).join('\\n\\n') + '\\n';\n};\n\nexport const parseAiOpsMeta = (content: string): { sourceHash: string; generatedAt: string } | null => {\n const startIdx = content.indexOf(SECTION_START);\n if (startIdx === -1) return null;\n\n const lines = content.slice(startIdx).split('\\n');\n // lines[0] = '<!-- ai-ops:start -->', lines[1] = meta line\n const metaLine = lines[1] ?? '';\n const match = META_PATTERN.exec(metaLine);\n if (!match) return null;\n\n return { sourceHash: match[1], generatedAt: match[2] };\n};\n","import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { ManifestSchema } from './schemas/index.js';\nimport type { Manifest } from './schemas/index.js';\n\nexport const MANIFEST_FILENAME = '.ai-ops-manifest.json';\n\n// Pure\nexport const parseManifest = (json: string): Manifest => ManifestSchema.parse(JSON.parse(json));\n\nexport const serializeManifest = (manifest: Manifest): string => JSON.stringify(manifest, null, 2) + '\\n';\n\n// I/O\nexport const resolveManifestPath = (basePath: string): string => join(basePath, MANIFEST_FILENAME);\n\nexport const readManifest = (manifestPath: string): Manifest | null => {\n let raw: string;\n try {\n raw = readFileSync(manifestPath, 'utf-8');\n } catch {\n return null;\n }\n return parseManifest(raw);\n};\n\nexport const writeManifest = (manifestPath: string, manifest: Manifest): void => {\n mkdirSync(dirname(manifestPath), { recursive: true });\n writeFileSync(manifestPath, serializeManifest(manifest), 'utf-8');\n};\n","import type { Manifest } from './schemas/index.js';\n\nexport type DiffResult = {\n status: 'up-to-date' | 'changed';\n added: readonly string[];\n removed: readonly string[];\n sourceChanged: boolean;\n versionChanged: boolean;\n};\n\nexport const computeDiff = (params: {\n previous: Manifest;\n currentRules: readonly string[];\n currentSourceHash: string;\n currentCliVersion?: string;\n}): DiffResult => {\n const { previous, currentRules, currentSourceHash, currentCliVersion } = params;\n\n const previousSet = new Set(previous.installed_rules);\n const currentSet = new Set(currentRules);\n\n const added = currentRules.filter((id) => !previousSet.has(id));\n const removed = previous.installed_rules.filter((id) => !currentSet.has(id));\n const sourceChanged = previous.sourceHash !== currentSourceHash;\n // previous.cliVersion์ด ์—†๋Š” ๋ ˆ๊ฑฐ์‹œ manifest๋Š” ๋ฒ„์ „ ๋ณ€๊ฒฝ์œผ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š์Œ\n const versionChanged =\n previous.cliVersion !== undefined &&\n currentCliVersion !== undefined &&\n previous.cliVersion !== currentCliVersion;\n\n const status =\n added.length > 0 || removed.length > 0 || sourceChanged || versionChanged ? 'changed' : 'up-to-date';\n\n return { status, added, removed, sourceChanged, versionChanged };\n};\n","import { join } from 'node:path';\nimport { wrapWithSection } from './managed-header.js';\nimport { TOOL_OUTPUT_MAP } from './tool-output.js';\nimport type { ToolId } from './tool-output.js';\nimport type { ToolRenderResult } from './renderer.js';\n\n// Codex has no settings.json โ€” plan directory convention must live in AGENTS.md\nconst CODEX_PLAN_BODY =\n '## Plan Snapshot (Plan mode only)\\n\\n' +\n '- This rule applies only when `collaboration_mode=Plan`.\\n' +\n '- Before implementation (file edits/creates, installs, commits), save the latest plan content to `.codex/plans/YYYYMMDD_<topic>.md`.\\n' +\n '- In `Default` mode, do not automatically create or update plan files.';\n\nexport type FileAction = {\n relativePath: string;\n content: string;\n};\n\nexport const buildInstallPlan = (params: {\n toolId: ToolId;\n renderResult: ToolRenderResult;\n meta: { sourceHash: string; generatedAt: string };\n}): readonly FileAction[] => {\n const { toolId, renderResult, meta } = params;\n\n if (toolId === 'claude-code' && renderResult.tool === 'claude-code') {\n return renderResult.files.map(({ relativePath, content }) => ({\n relativePath,\n content: wrapWithSection(content, meta),\n }));\n }\n\n if (toolId === 'codex' && renderResult.tool === 'codex') {\n const config = TOOL_OUTPUT_MAP['codex'];\n const actions: FileAction[] = [];\n\n // CODEX_PLAN_BODY is always written to root AGENTS.md regardless of whether global rules exist\n const rootContent = renderResult.rootContent\n ? renderResult.rootContent + '\\n\\n---\\n\\n' + CODEX_PLAN_BODY\n : CODEX_PLAN_BODY;\n\n actions.push({\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithSection(rootContent, meta),\n });\n\n for (const df of renderResult.domainFiles) {\n actions.push({\n relativePath: join(df.workspacePath, config.domainFileName),\n content: wrapWithSection(df.content, meta),\n });\n }\n\n return actions;\n }\n\n if (toolId === 'gemini' && renderResult.tool === 'gemini') {\n const config = TOOL_OUTPUT_MAP['gemini'];\n const actions: FileAction[] = [];\n\n if (renderResult.rootContent) {\n actions.push({\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithSection(renderResult.rootContent, meta),\n });\n }\n\n for (const df of renderResult.domainFiles) {\n actions.push({\n relativePath: join(df.workspacePath, config.domainFileName),\n content: wrapWithSection(df.content, meta),\n });\n }\n\n return actions;\n }\n\n return [];\n};\n","import { join } from 'node:path';\nimport { TOOL_OUTPUT_MAP } from './tool-output.js';\nimport type { Manifest } from './schemas/index.js';\n\n/**\n * manifest์— installed_files๊ฐ€ ์—†๋Š” ๊ตฌ๋ฒ„์ „ manifest๋ฅผ ์œ„ํ•œ fallback.\n * manifest์˜ tools/workspaces/installed_rules ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ\n * ์‹ค์ œ ์„ค์น˜๋์„ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์—ญ์‚ฐํ•œ๋‹ค.\n */\nexport const inferInstalledFiles = (manifest: Manifest): string[] => {\n const files: string[] = [];\n const isMonorepo = manifest.workspaces !== undefined;\n\n for (const toolId of manifest.tools) {\n if (toolId === 'claude-code') {\n // claude-code: .claude/rules/{ruleId}.md\n const config = TOOL_OUTPUT_MAP['claude-code'];\n for (const ruleId of manifest.installed_rules) {\n files.push(join(config.rulesDir, `${ruleId}${config.fileExtension}`));\n }\n } else if (toolId === 'codex') {\n const config = TOOL_OUTPUT_MAP['codex'];\n if (!isMonorepo) {\n // ๋น„๋ชจ๋…ธ: .codex/AGENTS.md + .codex/AGENTS.override.md (domain ์žˆ์œผ๋ฉด)\n files.push(join(config.dir, config.rootFileName));\n files.push(join(config.dir, config.domainFileName));\n } else {\n // ๋ชจ๋…ธ: .codex/AGENTS.md (global) + {workspace}/AGENTS.override.md (domain)\n files.push(join(config.dir, config.rootFileName));\n for (const ws of Object.keys(manifest.workspaces ?? {})) {\n files.push(join(ws, config.domainFileName));\n }\n }\n } else if (toolId === 'gemini') {\n const config = TOOL_OUTPUT_MAP['gemini'];\n if (!isMonorepo) {\n // ๋น„๋ชจ๋…ธ: .gemini/GEMINI.md\n files.push(join(config.dir, config.rootFileName));\n } else {\n // ๋ชจ๋…ธ: .gemini/GEMINI.md (global) + {workspace}/GEMINI.md (domain)\n files.push(join(config.dir, config.rootFileName));\n for (const ws of Object.keys(manifest.workspaces ?? {})) {\n files.push(join(ws, config.domainFileName));\n }\n }\n }\n }\n\n // ์ค‘๋ณต ์ œ๊ฑฐ (codex ๋น„๋ชจ๋…ธ์—์„œ rootFileName === domainFileName์ธ ๊ฒฝ์šฐ ๋Œ€๋น„)\n return [...new Set(files)];\n};\n","import { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n// src/core/* ๋˜๋Š” dist/bin/index.js ๊ธฐ์ค€์—์„œ๋„ ๊ณตํ†ต์œผ๋กœ ํŒจํ‚ค์ง€ ๋ฃจํŠธ/data๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๊ณ„์‚ฐ\n// src/core/paths.ts โ†’ ../../data = apps/cli/data\n// dist/bin/index.js (bundle) โ†’ ../../data = apps/cli/data\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const COMPILER_DATA_DIR = resolve(__dirname, '..', '..', 'data');\n","import { join } from 'node:path';\nimport { COMPILER_DATA_DIR } from '@/core/index.js';\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// project-only ์„ค์น˜ ๊ธฐ์ค€ ๋””๋ ‰ํ† ๋ฆฌ\nexport const resolveBasePath = (): string => 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 hasAiOpsSection,\n replaceAiOpsSection,\n stripAiOpsSection,\n hasLegacyHeader,\n} from '@/core/index.js';\nimport type { FileAction } from '@/core/index.js';\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 mkdirSync(dirname(absPath), { recursive: true });\n writeFileSync(absPath, action.content + '\\n', 'utf-8');\n written.push(action.relativePath);\n } else {\n const existing = readFileSync(absPath, 'utf-8');\n\n if (hasAiOpsSection(existing)) {\n // ๊ธฐ์กด ๋ธ”๋ก ๊ต์ฒด (์‚ฌ์šฉ์ž ์ฝ˜ํ…์ธ  ์ž๋™ ๋ณด์กด)\n const updated = replaceAiOpsSection(existing, action.content);\n writeFileSync(absPath, updated, 'utf-8');\n const stripped = stripAiOpsSection(existing);\n (stripped.trim().length > 0 ? appended : written).push(action.relativePath);\n } else if (hasLegacyHeader(existing)) {\n // ๋ ˆ๊ฑฐ์‹œ โ†’ ์ƒˆ ํ˜•์‹์œผ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ (update ์‹œ ์ž๋™ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜)\n writeFileSync(absPath, action.content + '\\n', 'utf-8');\n written.push(action.relativePath);\n } else {\n // ์ˆœ์ˆ˜ ์‚ฌ์šฉ์ž ํŒŒ์ผ โ†’ ์ตœ์ดˆ append\n const updated = existing.trimEnd() + '\\n\\n' + action.content + '\\n';\n writeFileSync(absPath, updated, 'utf-8');\n appended.push(action.relativePath);\n }\n }\n }\n\n return { written, appended, skipped };\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { deepMerge, deepRemoveKeys } from './deep-merge.util.js';\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\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\nexport type SettingsUninstallStatus = 'deleted' | 'cleaned' | 'notFound';\n\nexport const uninstallGeminiSettings = (basePath: string, selectedValues: readonly string[]): SettingsUninstallStatus => {\n const settingsPath = join(basePath, '.gemini', 'settings.json');\n\n if (!existsSync(settingsPath)) return 'notFound';\n\n let existing: GeminiSettings = {};\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as GeminiSettings;\n } catch {\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n let result: GeminiSettings = existing;\n for (const val of selectedValues) {\n const group = SETTING_GROUPS.find((g) => g.value === val);\n if (!group) continue;\n result = deepRemoveKeys(result as Record<string, unknown>, group.patch as Record<string, unknown>) as GeminiSettings;\n }\n\n if (Object.keys(result).length === 0) {\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n writeFileSync(settingsPath, JSON.stringify(result, null, 2) + '\\n', 'utf-8');\n return 'cleaned';\n};\n","export const 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 !Array.isArray(result[key])\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\nexport const deepRemoveKeys = (\n base: Record<string, unknown>,\n patch: Record<string, unknown>,\n): Record<string, unknown> => {\n const result = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n if (!(key in result)) continue;\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n typeof result[key] === 'object' &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n const nested = deepRemoveKeys(result[key] as Record<string, unknown>, value as Record<string, unknown>);\n if (Object.keys(nested).length === 0) {\n delete result[key];\n } else {\n result[key] = nested;\n }\n } else {\n delete result[key];\n }\n }\n return result;\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { deepMerge, deepRemoveKeys } from './deep-merge.util.js';\n\ntype ClaudeSettings = Record<string, unknown>;\n\ntype SettingGroup = {\n value: string;\n label: string;\n hint: string;\n patch: ClaudeSettings;\n};\n\nconst SETTING_GROUPS: readonly SettingGroup[] = [\n {\n value: 'model',\n label: 'Model โ€” Plan ๋ชจ๋“œ ๋ชจ๋ธ',\n hint: 'model: opusplan โ€” Plan ๋ชจ๋“œ์—์„œ Opus ๋ชจ๋ธ ์‚ฌ์šฉ',\n patch: { model: 'opusplan' },\n },\n {\n value: 'plansDirectory',\n label: 'Plans Directory โ€” ๊ณ„ํš ํŒŒ์ผ ์ €์žฅ ๊ฒฝ๋กœ',\n hint: 'plansDirectory: ./.claude/plans โ€” ๊ณ„ํš ํŒŒ์ผ์„ .claude/plans์— ์ €์žฅ',\n patch: { plansDirectory: './.claude/plans' },\n },\n] as const;\n\n// null โ†’ ๊ฑด๋„ˆ๋œ€ (์ทจ์†Œ ๋˜๋Š” \"No\"), string[] โ†’ ์„ ํƒ๋œ ํ•ญ๋ชฉ\nexport const promptClaudeSettings = async (): Promise<readonly string[] | null> => {\n const wantSettings = await p.confirm({\n message: 'Claude Code ์„ค์ • ํŒŒ์ผ(.claude/settings.local.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 installClaudeSettings = (basePath: string, selectedValues: readonly string[]): void => {\n if (selectedValues.length === 0) return;\n\n const settingsDir = join(basePath, '.claude');\n const settingsPath = join(settingsDir, 'settings.local.json');\n\n let existing: ClaudeSettings = {};\n if (existsSync(settingsPath)) {\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as ClaudeSettings;\n } catch {\n // parse ์‹คํŒจ ์‹œ ๋ฎ์–ด์“ฐ๊ธฐ\n }\n }\n\n let merged: ClaudeSettings = 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, group.patch);\n }\n\n mkdirSync(settingsDir, { recursive: true });\n writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\\n', 'utf-8');\n};\n\nexport type SettingsUninstallStatus = 'deleted' | 'cleaned' | 'notFound';\n\nexport const uninstallClaudeSettings = (basePath: string, selectedValues: readonly string[]): SettingsUninstallStatus => {\n const settingsPath = join(basePath, '.claude', 'settings.local.json');\n\n if (!existsSync(settingsPath)) return 'notFound';\n\n let existing: ClaudeSettings = {};\n try {\n existing = JSON.parse(readFileSync(settingsPath, 'utf-8')) as ClaudeSettings;\n } catch {\n // parse ์‹คํŒจ ์‹œ ์‚ญ์ œ๋กœ ์ฒ˜๋ฆฌ\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n let result: ClaudeSettings = existing;\n for (const val of selectedValues) {\n const group = SETTING_GROUPS.find((g) => g.value === val);\n if (!group) continue;\n result = deepRemoveKeys(result as Record<string, unknown>, group.patch as Record<string, unknown>) as ClaudeSettings;\n }\n\n if (Object.keys(result).length === 0) {\n rmSync(settingsPath, { force: true });\n return 'deleted';\n }\n\n writeFileSync(settingsPath, JSON.stringify(result, null, 2) + '\\n', 'utf-8');\n return 'cleaned';\n};\n","import * as p from '@clack/prompts';\nimport { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst PRETTIER_IGNORE_CONTENT = `# CLAUDE\n.claude/rules/\n**/CLAUDE.md\n\n# GEMINI\n**/GEMINI.md\n\n# CODEX\n**/AGENTS.md\n**/AGENTS.override.md\n\n.ai-ops-manifest.json`;\n\nconst SECTION_START = '# ai-ops:start';\nconst SECTION_END = '# ai-ops:end';\n\nconst wrapSection = (content: string): string => `${SECTION_START}\\n${content}\\n${SECTION_END}`;\n\nconst hasAiOpsSection = (content: string): boolean =>\n content.includes(SECTION_START) && content.includes(SECTION_END);\n\nconst replaceSection = (content: string, newContent: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inside = false;\n let replaced = false;\n\n for (const line of lines) {\n if (line.trim() === SECTION_START) {\n inside = true;\n result.push(wrapSection(newContent));\n replaced = true;\n continue;\n }\n if (line.trim() === SECTION_END) {\n inside = false;\n continue;\n }\n if (!inside) result.push(line);\n }\n\n if (!replaced) result.push(wrapSection(newContent));\n return result.join('\\n');\n};\n\nconst stripAiOpsSection = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inside = false;\n\n for (const line of lines) {\n if (line.trim() === SECTION_START) {\n inside = true;\n continue;\n }\n if (line.trim() === SECTION_END) {\n inside = false;\n continue;\n }\n if (!inside) result.push(line);\n }\n\n return result.join('\\n');\n};\n\nexport const promptPrettierIgnore = async (): Promise<boolean> => {\n const want = await p.confirm({\n message: '.prettierignore๋ฅผ ์„ค์น˜ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? (VSCode Prettier ์ž๋™ ํฌ๋งท์œผ๋กœ๋ถ€ํ„ฐ AI ๊ทœ์น™ ํŒŒ์ผ ๋ณดํ˜ธ)',\n initialValue: false,\n });\n if (p.isCancel(want)) return false;\n return want;\n};\n\nexport const installPrettierIgnore = (basePath: string): void => {\n const filePath = join(basePath, '.prettierignore');\n const section = wrapSection(PRETTIER_IGNORE_CONTENT);\n\n if (!existsSync(filePath)) {\n writeFileSync(filePath, section + '\\n', 'utf-8');\n return;\n }\n\n const existing = readFileSync(filePath, 'utf-8');\n\n if (hasAiOpsSection(existing)) {\n writeFileSync(filePath, replaceSection(existing, PRETTIER_IGNORE_CONTENT), 'utf-8');\n return;\n }\n\n const separator = existing.endsWith('\\n') ? '\\n' : '\\n\\n';\n writeFileSync(filePath, existing + separator + section + '\\n', 'utf-8');\n};\n\nexport type PrettierIgnoreUninstallStatus = 'deleted' | 'cleaned' | 'notFound';\n\nexport const uninstallPrettierIgnore = (basePath: string): PrettierIgnoreUninstallStatus => {\n const filePath = join(basePath, '.prettierignore');\n if (!existsSync(filePath)) return 'notFound';\n\n const existing = readFileSync(filePath, 'utf-8');\n if (!hasAiOpsSection(existing)) return 'notFound';\n\n const stripped = stripAiOpsSection(existing).trim();\n if (stripped.length === 0) {\n rmSync(filePath, { force: true });\n return 'deleted';\n }\n\n writeFileSync(filePath, stripped + '\\n', 'utf-8');\n return 'cleaned';\n};\n","import * as p from '@clack/prompts';\nimport type { ToolId } from '@/core/index.js';\nimport {\n readManifest,\n resolveManifestPath,\n loadAllRules,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n writeManifest,\n computeSourceHash,\n computeDiff,\n getCliVersion,\n} from '@/core/index.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\nimport { installFiles } from '../lib/install.js';\nimport { installClaudeSettings } from '../lib/claude-settings.js';\nimport { installGeminiSettings } from '../lib/gemini-settings.js';\nimport { installPrettierIgnore } from '../lib/prettier-ignore.js';\n\nexport const updateCommand = async (opts: { force: boolean }): Promise<void> => {\n const basePath = resolveBasePath();\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 const cliVersion = getCliVersion();\n\n const diffResult = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n currentCliVersion: cliVersion,\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 const allInstalledRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const workspaceMappings = workspaceEntries.map(([path, entry]) => ({\n path,\n ruleIds: entry.rules,\n }));\n const renderResult = renderForTool(toolId, rulesToInstall, workspaceMappings);\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 } 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 if (manifest.settings?.claude) {\n installClaudeSettings(basePath, manifest.settings.claude);\n }\n\n if (manifest.settings?.gemini) {\n installGeminiSettings(basePath, manifest.settings.gemini);\n }\n\n if (manifest.settings?.prettierignore) {\n installPrettierIgnore(basePath);\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 settings: manifest.settings\n ? {\n claude: manifest.settings.claude,\n gemini: manifest.settings.gemini,\n prettierignore: manifest.settings.prettierignore,\n }\n : undefined,\n cliVersion,\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 '@/core/index.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\n\nexport const diffCommand = async (): Promise<void> => {\n const basePath = resolveBasePath();\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 '@/core/index.js';\nimport { resolveBasePath } from '../lib/paths.js';\nimport { removeFiles, cleanEmptyDirs, collectManagedDirs } from '../lib/uninstall.js';\nimport { uninstallClaudeSettings } from '../lib/claude-settings.js';\nimport { uninstallGeminiSettings } from '../lib/gemini-settings.js';\nimport { uninstallPrettierIgnore } from '../lib/prettier-ignore.js';\n\nconst SETTINGS_PATHS = new Set(['.claude/settings.local.json', '.gemini/settings.json']);\n\nexport const uninstallCommand = async (): Promise<void> => {\n const basePath = resolveBasePath();\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๋œ ํŒŒ์ผ, settings ํŒŒ์ผ ์ œ์™ธ)\n const targetFiles = [\n ...(manifest.installed_files ?? inferInstalledFiles(manifest)),\n ...(manifest.appended_files ?? []),\n ].filter((f) => !SETTINGS_PATHS.has(f));\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. settings ํŒŒ์ผ ๋ณ„๋„ ์ฒ˜๋ฆฌ\n const settingsMessages: string[] = [];\n if (manifest.settings?.claude) {\n const status = uninstallClaudeSettings(basePath, manifest.settings.claude);\n if (status === 'deleted') settingsMessages.push('์‚ญ์ œ: .claude/settings.local.json');\n else if (status === 'cleaned') settingsMessages.push('ai-ops ํ‚ค ์ œ๊ฑฐ (์‚ฌ์šฉ์ž ์„ค์ • ๋ณด์กด): .claude/settings.local.json');\n }\n if (manifest.settings?.gemini) {\n const status = uninstallGeminiSettings(basePath, manifest.settings.gemini);\n if (status === 'deleted') settingsMessages.push('์‚ญ์ œ: .gemini/settings.json');\n else if (status === 'cleaned') settingsMessages.push('ai-ops ํ‚ค ์ œ๊ฑฐ (์‚ฌ์šฉ์ž ์„ค์ • ๋ณด์กด): .gemini/settings.json');\n }\n const prettierStatus = uninstallPrettierIgnore(basePath);\n if (prettierStatus === 'deleted') settingsMessages.push('์‚ญ์ œ: .prettierignore');\n else if (prettierStatus === 'cleaned') settingsMessages.push('ai-ops ์„น์…˜ ์ œ๊ฑฐ (์‚ฌ์šฉ์ž ๋‚ด์šฉ ๋ณด์กด): .prettierignore');\n\n // 6. ํŒŒ์ผ ์‚ญ์ œ\n const result = removeFiles(basePath, targetFiles);\n\n // 7. ๋นˆ ๋””๋ ‰ํ† ๋ฆฌ ์ •๋ฆฌ\n const dirs = collectManagedDirs(targetFiles);\n const removedDirs = cleanEmptyDirs(basePath, dirs);\n\n // 8. manifest ์‚ญ์ œ\n rmSync(manifestPath, { force: true });\n\n // 9. ๊ฒฐ๊ณผ ์š”์•ฝ\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 if (settingsMessages.length > 0) {\n p.log.success(`์„ค์ • ํŒŒ์ผ ์ฒ˜๋ฆฌ:\\n${settingsMessages.map((m) => ` ${m}`).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 { hasAiOpsSection, stripAiOpsSection, hasLegacyHeader } from '@/core/index.js';\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 (hasAiOpsSection(content)) {\n const stripped = stripAiOpsSection(content);\n if (stripped.trim().length === 0) {\n rmSync(absPath);\n deleted.push(rel);\n } else {\n writeFileSync(absPath, stripped, 'utf-8');\n cleaned.push(rel);\n }\n } else if (hasLegacyHeader(content)) {\n rmSync(absPath);\n deleted.push(rel);\n } else {\n skipped.push(rel);\n }\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":"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","names":["p","z","z","z","p","global","domain","rootContent","domainFiles","readFileSync","readdirSync","resolve","resolve","readFileSync","readdirSync","readFileSync","dirname","join","join","readFileSync","dirname","join","join","join","join","dirname","resolve","fileURLToPath","__dirname","join","join","readdirSync","join","resolve","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","resolve","resolve","existsSync","mkdirSync","dirname","writeFileSync","readFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","p","existsSync","mkdirSync","readFileSync","rmSync","writeFileSync","join","SETTING_GROUPS","join","existsSync","readFileSync","mkdirSync","writeFileSync","rmSync","p","existsSync","readFileSync","rmSync","writeFileSync","join","SECTION_START","SECTION_END","hasAiOpsSection","stripAiOpsSection","allRules","p","r","p","p","rmSync","existsSync","readFileSync","rmSync","readdirSync","writeFileSync","resolve","dirname","resolve","existsSync","readFileSync","rmSync","writeFileSync","readdirSync","dirname","rmSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-ops-cli",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "CLI for ai-ops scaffolding โ€” manage AI tool rules and presets",
5
5
  "license": "MIT",
6
6
  "repository": {