ai-ops-cli 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/index.js CHANGED
@@ -20,7 +20,8 @@ import {
20
20
  computeSourceHash,
21
21
  resolveManifestPath,
22
22
  writeManifest,
23
- wrapWithHeader
23
+ wrapWithHeader,
24
+ TOOL_OUTPUT_MAP
24
25
  } from "ai-ops-compiler";
25
26
 
26
27
  // src/lib/paths.ts
@@ -143,13 +144,12 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules) => {
143
144
  return { workspace: workspaceName, preset, finalRules: excludeRules(presetRules, excludeIds) };
144
145
  };
145
146
  var installHierarchicalMonorepo = (toolId, mappings, basePath, meta) => {
146
- const rootFileName = toolId === "codex" ? "AGENTS.md" : "GEMINI.md";
147
- const domainFileName = toolId === "codex" ? "AGENTS.override.md" : "GEMINI.md";
147
+ const config = TOOL_OUTPUT_MAP[toolId];
148
148
  const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));
149
149
  const { global } = partitionRules(allRules);
150
150
  if (global.length > 0) {
151
151
  const rootAction = {
152
- relativePath: rootFileName,
152
+ relativePath: join3(config.dir, config.rootFileName),
153
153
  content: wrapWithHeader(renderRulesToMarkdown(global), meta)
154
154
  };
155
155
  installFiles(basePath, [rootAction]);
@@ -158,7 +158,7 @@ var installHierarchicalMonorepo = (toolId, mappings, basePath, meta) => {
158
158
  const { domain } = partitionRules(mapping.finalRules);
159
159
  if (domain.length === 0) continue;
160
160
  const domainAction = {
161
- relativePath: join3(mapping.workspace, domainFileName),
161
+ relativePath: join3(mapping.workspace, config.dir, config.domainFileName),
162
162
  content: wrapWithHeader(renderRulesToMarkdown(domain), meta)
163
163
  };
164
164
  installFiles(basePath, [domainAction]);
@@ -166,7 +166,11 @@ var installHierarchicalMonorepo = (toolId, mappings, basePath, meta) => {
166
166
  };
167
167
  var installClaudeCodeMonorepo = (mappings, basePath, meta) => {
168
168
  const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));
169
- const renderResult = renderForTool("claude-code", allRules);
169
+ const workspaceMappings = mappings.map((m) => ({
170
+ path: m.workspace,
171
+ ruleIds: m.finalRules.map((r) => r.id)
172
+ }));
173
+ const renderResult = renderForTool("claude-code", allRules, workspaceMappings);
170
174
  const actions = buildInstallPlan({ toolId: "claude-code", renderResult, meta });
171
175
  installFiles(basePath, actions);
172
176
  };
@@ -276,7 +280,8 @@ import {
276
280
  computeDiff,
277
281
  partitionRules as partitionRules2,
278
282
  renderRulesToMarkdown as renderRulesToMarkdown2,
279
- wrapWithHeader as wrapWithHeader2
283
+ wrapWithHeader as wrapWithHeader2,
284
+ TOOL_OUTPUT_MAP as TOOL_OUTPUT_MAP2
280
285
  } from "ai-ops-compiler";
281
286
  import { join as join4 } from "path";
282
287
  var updateCommand = async (opts) => {
@@ -311,18 +316,21 @@ var updateCommand = async (opts) => {
311
316
  if (toolId === "claude-code") {
312
317
  const allInstalledRuleSet = new Set(manifest.installed_rules);
313
318
  const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));
314
- const renderResult = renderForTool2("claude-code", rulesToInstall);
319
+ const workspaceMappings = Object.entries(manifest.workspaces).map(([path, entry]) => ({
320
+ path,
321
+ ruleIds: entry.rules
322
+ }));
323
+ const renderResult = renderForTool2("claude-code", rulesToInstall, workspaceMappings);
315
324
  const actions = buildInstallPlan2({ toolId: "claude-code", renderResult, meta });
316
325
  installFiles(basePath, actions);
317
326
  } else {
318
- const rootFileName = toolId === "codex" ? "AGENTS.md" : "GEMINI.md";
319
- const domainFileName = toolId === "codex" ? "AGENTS.override.md" : "GEMINI.md";
327
+ const config = TOOL_OUTPUT_MAP2[toolId];
320
328
  const allInstalledRuleSet = new Set(manifest.installed_rules);
321
329
  const allRulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));
322
330
  const { global } = partitionRules2(allRulesToInstall);
323
331
  if (global.length > 0) {
324
332
  const rootAction = {
325
- relativePath: rootFileName,
333
+ relativePath: join4(config.dir, config.rootFileName),
326
334
  content: wrapWithHeader2(renderRulesToMarkdown2(global), meta)
327
335
  };
328
336
  installFiles(basePath, [rootAction]);
@@ -333,7 +341,7 @@ var updateCommand = async (opts) => {
333
341
  const { domain } = partitionRules2(wsRules);
334
342
  if (domain.length === 0) continue;
335
343
  const domainAction = {
336
- relativePath: join4(ws, domainFileName),
344
+ relativePath: join4(ws, config.dir, config.domainFileName),
337
345
  content: wrapWithHeader2(renderRulesToMarkdown2(domain), meta)
338
346
  };
339
347
  installFiles(basePath, [domainAction]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/index.ts","../../src/commands/init.ts","../../src/lib/paths.ts","../../src/lib/workspace.ts","../../src/lib/install.ts","../../src/commands/update.ts","../../src/commands/diff.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 type { Scope } from '../lib/paths.js';\n\nconst program = new Command();\n\nprogram.name('ai-ops').description('AI 에이전트 규칙 스캐폴더').version('0.1.0');\n\nprogram\n .command('init')\n .description('AI 규칙 초기 설치')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => initCommand(opts));\n\nprogram\n .command('update')\n .description('기존 manifest 기반 규칙 갱신')\n .option('--scope <scope>', 'project | global', 'project')\n .option('--force', '변경 없어도 강제 재설치', false)\n .action((opts: { scope: Scope; force: boolean }) => updateCommand(opts));\n\nprogram\n .command('diff')\n .description('설치된 규칙과 최신 소스 비교')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => diffCommand(opts));\n\nprogram.parse();\n","import * as p from '@clack/prompts';\nimport { join } from 'node:path';\nimport type { Rule, Preset, ToolId } from 'ai-ops-compiler';\nimport {\n loadAllRules,\n loadPresets,\n resolvePresetRules,\n excludeRules,\n isGlobalRule,\n partitionRules,\n renderForTool,\n renderRulesToMarkdown,\n buildInstallPlan,\n buildManifest,\n computeSourceHash,\n resolveManifestPath,\n writeManifest,\n wrapWithHeader,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir, resolvePresetsPath } from '../lib/paths.js';\nimport { listWorkspaceCandidates } from '../lib/workspace.js';\nimport { installFiles } from '../lib/install.js';\n\ntype WorkspacePresetMapping = {\n workspace: string;\n preset: Preset;\n finalRules: Rule[];\n};\n\nconst TOOL_OPTIONS = [\n { value: 'claude-code' as ToolId, label: 'Claude Code' },\n { value: 'codex' as ToolId, label: 'Codex' },\n { value: 'gemini' as ToolId, label: 'Gemini CLI' },\n];\n\nconst deduplicateRules = (rules: readonly Rule[]): Rule[] => {\n const seen = new Set<string>();\n return rules.filter((r) => {\n if (seen.has(r.id)) return false;\n seen.add(r.id);\n return true;\n });\n};\n\nconst selectPresetAndFineTune = async (\n workspaceName: string,\n presets: readonly Preset[],\n allRules: readonly Rule[],\n): Promise<WorkspacePresetMapping | null> => {\n const preset = await p.select<Preset>({\n message: `[${workspaceName}] 프리셋을 선택하세요`,\n options: presets.map((pr) => ({\n value: pr,\n label: pr.id,\n hint: pr.description,\n })),\n });\n if (p.isCancel(preset)) return null;\n\n const presetRules = resolvePresetRules(preset, allRules);\n const globalRules = presetRules.filter(isGlobalRule);\n const domainRules = presetRules.filter((r) => !isGlobalRule(r));\n\n // Global rules: locked (항상 포함)\n if (globalRules.length > 0) {\n p.note(globalRules.map((r) => ` ✓ ${r.id}`).join('\\n'), `[${workspaceName}] 기본 규칙 (잠금)`);\n }\n\n if (domainRules.length === 0) {\n return { workspace: workspaceName, preset, finalRules: presetRules };\n }\n\n // Domain rules: 제외 가능\n const selectedDomain = await p.multiselect<string>({\n message: `[${workspaceName}] 도메인 규칙 선택 (해제하여 제외)`,\n options: domainRules.map((r) => ({ value: r.id, label: r.id })),\n initialValues: domainRules.map((r) => r.id),\n required: false,\n });\n if (p.isCancel(selectedDomain)) return null;\n\n const excludeIds = domainRules.map((r) => r.id).filter((id) => !(selectedDomain as string[]).includes(id));\n\n return { workspace: workspaceName, preset, finalRules: excludeRules(presetRules, excludeIds) };\n};\n\nconst installHierarchicalMonorepo = (\n toolId: 'codex' | 'gemini',\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): void => {\n const rootFileName = toolId === 'codex' ? 'AGENTS.md' : 'GEMINI.md';\n const domainFileName = toolId === 'codex' ? 'AGENTS.override.md' : 'GEMINI.md';\n\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const { global } = partitionRules(allRules);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: rootFileName,\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n installFiles(basePath, [rootAction]);\n }\n\n for (const mapping of mappings) {\n const { domain } = partitionRules(mapping.finalRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(mapping.workspace, domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n installFiles(basePath, [domainAction]);\n }\n};\n\nconst installClaudeCodeMonorepo = (\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): void => {\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const renderResult = renderForTool('claude-code', allRules);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n installFiles(basePath, actions);\n};\n\nexport const initCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const rulesDir = resolveRulesDir();\n\n p.intro('ai-ops init');\n\n // 1. AI 도구 다중 선택\n const selectedTools = await p.multiselect<ToolId>({\n message: 'AI 도구를 선택하세요',\n options: TOOL_OPTIONS,\n required: true,\n });\n if (p.isCancel(selectedTools)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 2. 모노레포 여부\n const isMonorepo = await p.confirm({\n message: '모노레포 프로젝트입니까?',\n initialValue: false,\n });\n if (p.isCancel(isMonorepo)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 3. 데이터 로드\n const allRules = loadAllRules(rulesDir);\n const presets = loadPresets(resolvePresetsPath());\n const sourceHash = computeSourceHash(rulesDir);\n\n // 4. 워크스페이스별 preset 선택 + fine-tune\n const mappings: WorkspacePresetMapping[] = [];\n\n if (!isMonorepo) {\n const mapping = await selectPresetAndFineTune('.', presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n } else {\n const candidates = listWorkspaceCandidates(basePath);\n const selectedWorkspaces = await p.multiselect<string>({\n message: '워크스페이스를 선택하세요',\n options: candidates.map((c) => ({ value: c, label: c })),\n required: true,\n });\n if (p.isCancel(selectedWorkspaces)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n for (const ws of selectedWorkspaces as string[]) {\n const mapping = await selectPresetAndFineTune(ws, presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n }\n }\n\n // 5. 설치\n const s = p.spinner();\n s.start('규칙 설치 중...');\n\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n const allSkipped: string[] = [];\n\n for (const toolId of selectedTools as ToolId[]) {\n if (isMonorepo) {\n if (toolId === 'claude-code') {\n installClaudeCodeMonorepo(mappings, basePath, meta);\n } else {\n installHierarchicalMonorepo(toolId, mappings, basePath, meta);\n }\n } else {\n const renderResult = renderForTool(toolId, mappings[0].finalRules);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n const result = installFiles(basePath, actions);\n allSkipped.push(...result.skipped);\n }\n }\n\n s.stop('규칙 설치 완료');\n\n // 6. Manifest 저장\n const allInstalledRuleIds = deduplicateRules(mappings.flatMap((m) => m.finalRules)).map((r) => r.id);\n\n const workspacesRecord = isMonorepo\n ? Object.fromEntries(\n mappings.map((m) => [m.workspace, { preset: m.preset.id, rules: m.finalRules.map((r) => r.id) }]),\n )\n : undefined;\n\n const manifest = buildManifest({\n tools: selectedTools as string[],\n scope: opts.scope,\n preset: !isMonorepo ? mappings[0].preset.id : undefined,\n workspaces: workspacesRecord,\n installedRules: allInstalledRuleIds,\n sourceHash,\n });\n writeManifest(resolveManifestPath(basePath), manifest);\n\n // 7. 결과 요약\n if (allSkipped.length > 0) {\n p.log.warn(`충돌(non-managed) 파일 건너뜀:\\n${allSkipped.map((f) => ` ${f}`).join('\\n')}`);\n }\n p.log.success(`설치된 규칙: ${allInstalledRuleIds.length}개`);\n p.outro('ai-ops init 완료');\n};\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { COMPILER_DATA_DIR } from 'ai-ops-compiler';\n\nexport type Scope = 'project' | 'global';\n\nexport const resolveCompilerDataDir = (): string => COMPILER_DATA_DIR;\n\nexport const resolveRulesDir = (): string => join(COMPILER_DATA_DIR, 'rules');\n\nexport const resolvePresetsPath = (): string => join(COMPILER_DATA_DIR, 'presets.yaml');\n\n// scope에 따른 설치 기준 디렉토리\nexport const resolveBasePath = (scope: Scope): string =>\n scope === 'global' ? resolve(homedir(), '.ai-ops') : process.cwd();\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nconst EXCLUDE_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.turbo', '.cache', 'coverage']);\n\nconst isVisibleDir = (basePath: string, name: string): boolean => {\n if (name.startsWith('.') || EXCLUDE_DIRS.has(name)) return false;\n return statSync(resolve(basePath, name)).isDirectory();\n};\n\n// Project manifest files that indicate a workspace root\nconst PROJECT_MANIFESTS = [\n 'package.json', // Node.js / JS / TS\n 'pubspec.yaml', // Flutter / Dart\n 'pyproject.toml', // Python (modern)\n 'setup.py', // Python (legacy)\n 'Cargo.toml', // Rust\n 'go.mod', // Go\n];\n\nconst isWorkspaceRoot = (dirPath: string): boolean => PROJECT_MANIFESTS.some((f) => existsSync(join(dirPath, f)));\n\n// 프로젝트 매니페스트 파일 존재 여부로 워크스페이스 판별:\n// 1. top-level dir에 매니페스트 → 그 자체가 워크스페이스 (e.g. backend-ts, mobile, web)\n// 2. top-level dir에 매니페스트 없고 자식에 있음 → 자식을 후보로 (e.g. apps/web, packages/ui)\n// 3. 매니페스트 없는 경우 → 1-depth 그대로\nexport const listWorkspaceCandidates = (basePath: string): string[] => {\n const topLevel = readdirSync(basePath).filter((name) => isVisibleDir(basePath, name));\n\n const candidates: string[] = [];\n for (const dir of topLevel) {\n const subPath = resolve(basePath, dir);\n if (isWorkspaceRoot(subPath)) {\n candidates.push(dir);\n } else {\n const children = readdirSync(subPath).filter((name) => isVisibleDir(subPath, name));\n const wsChildren = children.filter((name) => isWorkspaceRoot(resolve(subPath, name)));\n if (wsChildren.length > 0) {\n for (const child of wsChildren) {\n candidates.push(join(dir, child));\n }\n } else {\n candidates.push(dir);\n }\n }\n }\n\n return candidates.sort();\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { isManagedFile } from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\n\nexport type InstallResult = {\n written: string[];\n skipped: string[]; // 기존 파일이 managed가 아닌 경우 (사용자 파일 보호)\n};\n\nexport const installFiles = (basePath: string, actions: readonly FileAction[]): InstallResult => {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const action of actions) {\n const absPath = resolve(basePath, action.relativePath);\n\n if (existsSync(absPath)) {\n const existing = readFileSync(absPath, 'utf-8');\n if (!isManagedFile(existing)) {\n skipped.push(action.relativePath);\n continue;\n }\n }\n\n mkdirSync(dirname(absPath), { recursive: true });\n writeFileSync(absPath, action.content, 'utf-8');\n written.push(action.relativePath);\n }\n\n return { written, skipped };\n};\n","import * as p from '@clack/prompts';\nimport type { ToolId } from 'ai-ops-compiler';\nimport {\n readManifest,\n resolveManifestPath,\n loadAllRules,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n writeManifest,\n computeSourceHash,\n computeDiff,\n partitionRules,\n renderRulesToMarkdown,\n wrapWithHeader,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport { join } from 'node:path';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\nimport { installFiles } from '../lib/install.js';\n\nexport const updateCommand = async (opts: { scope: Scope; force: boolean }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const manifestPath = resolveManifestPath(basePath);\n\n p.intro('ai-ops update');\n\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const rulesDir = resolveRulesDir();\n const sourceHash = computeSourceHash(rulesDir);\n\n const diffResult = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (diffResult.status === 'up-to-date' && !opts.force) {\n p.log.info('변경 사항이 없습니다.');\n p.outro('ai-ops update 완료');\n return;\n }\n\n const s = p.spinner();\n s.start('규칙 갱신 중...');\n\n const allRules = loadAllRules(rulesDir);\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n\n if (manifest.workspaces) {\n // 모노레포: workspaces 기반 재설치\n const workspaceEntries = Object.entries(manifest.workspaces);\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n\n if (toolId === 'claude-code') {\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const renderResult = renderForTool('claude-code', rulesToInstall);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n installFiles(basePath, actions);\n } else {\n // codex/gemini: global → 루트, domain → 워크스페이스별\n const rootFileName = toolId === 'codex' ? 'AGENTS.md' : 'GEMINI.md';\n const domainFileName = toolId === 'codex' ? 'AGENTS.override.md' : 'GEMINI.md';\n\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const allRulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const { global } = partitionRules(allRulesToInstall);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: rootFileName,\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n installFiles(basePath, [rootAction]);\n }\n\n for (const [ws, entry] of workspaceEntries) {\n const wsRuleSet = new Set(entry.rules);\n const wsRules = allRules.filter((r) => wsRuleSet.has(r.id));\n const { domain } = partitionRules(wsRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(ws, domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n installFiles(basePath, [domainAction]);\n }\n }\n }\n } else {\n // 단일 프로젝트: installed_rules 기반 재설치\n const installedRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => installedRuleSet.has(r.id));\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n const renderResult = renderForTool(toolId, rulesToInstall);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n installFiles(basePath, actions);\n }\n }\n\n const newManifest = buildManifest({\n tools: manifest.tools,\n scope: manifest.scope,\n preset: manifest.preset,\n workspaces: manifest.workspaces,\n installedRules: manifest.installed_rules,\n sourceHash,\n });\n writeManifest(manifestPath, newManifest);\n\n s.stop('규칙 갱신 완료');\n p.outro('ai-ops update 완료');\n};\n","import * as p from '@clack/prompts';\nimport { readManifest, resolveManifestPath, computeSourceHash, computeDiff } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\n\nexport const diffCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n\n p.intro('ai-ops diff');\n\n const manifest = readManifest(resolveManifestPath(basePath));\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const sourceHash = computeSourceHash(resolveRulesDir());\n\n const result = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (result.status === 'up-to-date') {\n p.log.success('변경 사항 없음. 최신 상태입니다.');\n } else {\n if (result.sourceChanged) {\n p.log.warn(`소스 변경 감지: ${manifest.sourceHash} → ${sourceHash}`);\n }\n if (result.added.length > 0) {\n p.log.info(`추가된 규칙: ${result.added.join(', ')}`);\n }\n if (result.removed.length > 0) {\n p.log.info(`제거된 규칙: ${result.removed.join(', ')}`);\n }\n }\n\n p.outro('ai-ops diff 완료');\n};\n"],"mappings":"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","names":["join","join","resolve","existsSync","resolve","join","p","resolveManifestPath","loadAllRules","renderForTool","buildInstallPlan","buildManifest","writeManifest","computeSourceHash","partitionRules","renderRulesToMarkdown","wrapWithHeader","join","resolveManifestPath","computeSourceHash","loadAllRules","renderForTool","buildInstallPlan","partitionRules","wrapWithHeader","renderRulesToMarkdown","join","buildManifest","writeManifest","p","readManifest","resolveManifestPath","computeSourceHash","computeDiff","readManifest","resolveManifestPath","computeSourceHash","computeDiff"]}
1
+ {"version":3,"sources":["../../src/bin/index.ts","../../src/commands/init.ts","../../src/lib/paths.ts","../../src/lib/workspace.ts","../../src/lib/install.ts","../../src/commands/update.ts","../../src/commands/diff.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 type { Scope } from '../lib/paths.js';\n\nconst program = new Command();\n\nprogram.name('ai-ops').description('AI 에이전트 규칙 스캐폴더').version('0.1.0');\n\nprogram\n .command('init')\n .description('AI 규칙 초기 설치')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => initCommand(opts));\n\nprogram\n .command('update')\n .description('기존 manifest 기반 규칙 갱신')\n .option('--scope <scope>', 'project | global', 'project')\n .option('--force', '변경 없어도 강제 재설치', false)\n .action((opts: { scope: Scope; force: boolean }) => updateCommand(opts));\n\nprogram\n .command('diff')\n .description('설치된 규칙과 최신 소스 비교')\n .option('--scope <scope>', 'project | global', 'project')\n .action((opts: { scope: Scope }) => diffCommand(opts));\n\nprogram.parse();\n","import * as p from '@clack/prompts';\nimport { join } from 'node:path';\nimport type { Rule, Preset, ToolId, WorkspaceMapping } from 'ai-ops-compiler';\nimport {\n loadAllRules,\n loadPresets,\n resolvePresetRules,\n excludeRules,\n isGlobalRule,\n partitionRules,\n renderForTool,\n renderRulesToMarkdown,\n buildInstallPlan,\n buildManifest,\n computeSourceHash,\n resolveManifestPath,\n writeManifest,\n wrapWithHeader,\n TOOL_OUTPUT_MAP,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir, resolvePresetsPath } from '../lib/paths.js';\nimport { listWorkspaceCandidates } from '../lib/workspace.js';\nimport { installFiles } from '../lib/install.js';\n\ntype WorkspacePresetMapping = {\n workspace: string;\n preset: Preset;\n finalRules: Rule[];\n};\n\nconst TOOL_OPTIONS = [\n { value: 'claude-code' as ToolId, label: 'Claude Code' },\n { value: 'codex' as ToolId, label: 'Codex' },\n { value: 'gemini' as ToolId, label: 'Gemini CLI' },\n];\n\nconst deduplicateRules = (rules: readonly Rule[]): Rule[] => {\n const seen = new Set<string>();\n return rules.filter((r) => {\n if (seen.has(r.id)) return false;\n seen.add(r.id);\n return true;\n });\n};\n\nconst selectPresetAndFineTune = async (\n workspaceName: string,\n presets: readonly Preset[],\n allRules: readonly Rule[],\n): Promise<WorkspacePresetMapping | null> => {\n const preset = await p.select<Preset>({\n message: `[${workspaceName}] 프리셋을 선택하세요`,\n options: presets.map((pr) => ({\n value: pr,\n label: pr.id,\n hint: pr.description,\n })),\n });\n if (p.isCancel(preset)) return null;\n\n const presetRules = resolvePresetRules(preset, allRules);\n const globalRules = presetRules.filter(isGlobalRule);\n const domainRules = presetRules.filter((r) => !isGlobalRule(r));\n\n // Global rules: locked (항상 포함)\n if (globalRules.length > 0) {\n p.note(globalRules.map((r) => ` ✓ ${r.id}`).join('\\n'), `[${workspaceName}] 기본 규칙 (잠금)`);\n }\n\n if (domainRules.length === 0) {\n return { workspace: workspaceName, preset, finalRules: presetRules };\n }\n\n // Domain rules: 제외 가능\n const selectedDomain = await p.multiselect<string>({\n message: `[${workspaceName}] 도메인 규칙 선택 (해제하여 제외)`,\n options: domainRules.map((r) => ({ value: r.id, label: r.id })),\n initialValues: domainRules.map((r) => r.id),\n required: false,\n });\n if (p.isCancel(selectedDomain)) return null;\n\n const excludeIds = domainRules.map((r) => r.id).filter((id) => !(selectedDomain as string[]).includes(id));\n\n return { workspace: workspaceName, preset, finalRules: excludeRules(presetRules, excludeIds) };\n};\n\nconst installHierarchicalMonorepo = (\n toolId: 'codex' | 'gemini',\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): void => {\n const config = TOOL_OUTPUT_MAP[toolId];\n\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const { global } = partitionRules(allRules);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n installFiles(basePath, [rootAction]);\n }\n\n for (const mapping of mappings) {\n const { domain } = partitionRules(mapping.finalRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(mapping.workspace, config.dir, config.domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n installFiles(basePath, [domainAction]);\n }\n};\n\nconst installClaudeCodeMonorepo = (\n mappings: readonly WorkspacePresetMapping[],\n basePath: string,\n meta: { sourceHash: string; generatedAt: string },\n): void => {\n const allRules = deduplicateRules(mappings.flatMap((m) => m.finalRules));\n const workspaceMappings: WorkspaceMapping[] = mappings.map((m) => ({\n path: m.workspace,\n ruleIds: m.finalRules.map((r) => r.id),\n }));\n const renderResult = renderForTool('claude-code', allRules, workspaceMappings);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n installFiles(basePath, actions);\n};\n\nexport const initCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const rulesDir = resolveRulesDir();\n\n p.intro('ai-ops init');\n\n // 1. AI 도구 다중 선택\n const selectedTools = await p.multiselect<ToolId>({\n message: 'AI 도구를 선택하세요',\n options: TOOL_OPTIONS,\n required: true,\n });\n if (p.isCancel(selectedTools)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 2. 모노레포 여부\n const isMonorepo = await p.confirm({\n message: '모노레포 프로젝트입니까?',\n initialValue: false,\n });\n if (p.isCancel(isMonorepo)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n // 3. 데이터 로드\n const allRules = loadAllRules(rulesDir);\n const presets = loadPresets(resolvePresetsPath());\n const sourceHash = computeSourceHash(rulesDir);\n\n // 4. 워크스페이스별 preset 선택 + fine-tune\n const mappings: WorkspacePresetMapping[] = [];\n\n if (!isMonorepo) {\n const mapping = await selectPresetAndFineTune('.', presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n } else {\n const candidates = listWorkspaceCandidates(basePath);\n const selectedWorkspaces = await p.multiselect<string>({\n message: '워크스페이스를 선택하세요',\n options: candidates.map((c) => ({ value: c, label: c })),\n required: true,\n });\n if (p.isCancel(selectedWorkspaces)) {\n p.cancel('취소됨');\n process.exit(0);\n }\n\n for (const ws of selectedWorkspaces as string[]) {\n const mapping = await selectPresetAndFineTune(ws, presets, allRules);\n if (!mapping) {\n p.cancel('취소됨');\n process.exit(0);\n }\n mappings.push(mapping);\n }\n }\n\n // 5. 설치\n const s = p.spinner();\n s.start('규칙 설치 중...');\n\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n const allSkipped: string[] = [];\n\n for (const toolId of selectedTools as ToolId[]) {\n if (isMonorepo) {\n if (toolId === 'claude-code') {\n installClaudeCodeMonorepo(mappings, basePath, meta);\n } else {\n installHierarchicalMonorepo(toolId, mappings, basePath, meta);\n }\n } else {\n const renderResult = renderForTool(toolId, mappings[0].finalRules);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n const result = installFiles(basePath, actions);\n allSkipped.push(...result.skipped);\n }\n }\n\n s.stop('규칙 설치 완료');\n\n // 6. Manifest 저장\n const allInstalledRuleIds = deduplicateRules(mappings.flatMap((m) => m.finalRules)).map((r) => r.id);\n\n const workspacesRecord = isMonorepo\n ? Object.fromEntries(\n mappings.map((m) => [m.workspace, { preset: m.preset.id, rules: m.finalRules.map((r) => r.id) }]),\n )\n : undefined;\n\n const manifest = buildManifest({\n tools: selectedTools as string[],\n scope: opts.scope,\n preset: !isMonorepo ? mappings[0].preset.id : undefined,\n workspaces: workspacesRecord,\n installedRules: allInstalledRuleIds,\n sourceHash,\n });\n writeManifest(resolveManifestPath(basePath), manifest);\n\n // 7. 결과 요약\n if (allSkipped.length > 0) {\n p.log.warn(`충돌(non-managed) 파일 건너뜀:\\n${allSkipped.map((f) => ` ${f}`).join('\\n')}`);\n }\n p.log.success(`설치된 규칙: ${allInstalledRuleIds.length}개`);\n p.outro('ai-ops init 완료');\n};\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { COMPILER_DATA_DIR } from 'ai-ops-compiler';\n\nexport type Scope = 'project' | 'global';\n\nexport const resolveCompilerDataDir = (): string => COMPILER_DATA_DIR;\n\nexport const resolveRulesDir = (): string => join(COMPILER_DATA_DIR, 'rules');\n\nexport const resolvePresetsPath = (): string => join(COMPILER_DATA_DIR, 'presets.yaml');\n\n// scope에 따른 설치 기준 디렉토리\nexport const resolveBasePath = (scope: Scope): string =>\n scope === 'global' ? resolve(homedir(), '.ai-ops') : process.cwd();\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nconst EXCLUDE_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.turbo', '.cache', 'coverage']);\n\nconst isVisibleDir = (basePath: string, name: string): boolean => {\n if (name.startsWith('.') || EXCLUDE_DIRS.has(name)) return false;\n return statSync(resolve(basePath, name)).isDirectory();\n};\n\n// Project manifest files that indicate a workspace root\nconst PROJECT_MANIFESTS = [\n 'package.json', // Node.js / JS / TS\n 'pubspec.yaml', // Flutter / Dart\n 'pyproject.toml', // Python (modern)\n 'setup.py', // Python (legacy)\n 'Cargo.toml', // Rust\n 'go.mod', // Go\n];\n\nconst isWorkspaceRoot = (dirPath: string): boolean => PROJECT_MANIFESTS.some((f) => existsSync(join(dirPath, f)));\n\n// 프로젝트 매니페스트 파일 존재 여부로 워크스페이스 판별:\n// 1. top-level dir에 매니페스트 → 그 자체가 워크스페이스 (e.g. backend-ts, mobile, web)\n// 2. top-level dir에 매니페스트 없고 자식에 있음 → 자식을 후보로 (e.g. apps/web, packages/ui)\n// 3. 매니페스트 없는 경우 → 1-depth 그대로\nexport const listWorkspaceCandidates = (basePath: string): string[] => {\n const topLevel = readdirSync(basePath).filter((name) => isVisibleDir(basePath, name));\n\n const candidates: string[] = [];\n for (const dir of topLevel) {\n const subPath = resolve(basePath, dir);\n if (isWorkspaceRoot(subPath)) {\n candidates.push(dir);\n } else {\n const children = readdirSync(subPath).filter((name) => isVisibleDir(subPath, name));\n const wsChildren = children.filter((name) => isWorkspaceRoot(resolve(subPath, name)));\n if (wsChildren.length > 0) {\n for (const child of wsChildren) {\n candidates.push(join(dir, child));\n }\n } else {\n candidates.push(dir);\n }\n }\n }\n\n return candidates.sort();\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { isManagedFile } from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\n\nexport type InstallResult = {\n written: string[];\n skipped: string[]; // 기존 파일이 managed가 아닌 경우 (사용자 파일 보호)\n};\n\nexport const installFiles = (basePath: string, actions: readonly FileAction[]): InstallResult => {\n const written: string[] = [];\n const skipped: string[] = [];\n\n for (const action of actions) {\n const absPath = resolve(basePath, action.relativePath);\n\n if (existsSync(absPath)) {\n const existing = readFileSync(absPath, 'utf-8');\n if (!isManagedFile(existing)) {\n skipped.push(action.relativePath);\n continue;\n }\n }\n\n mkdirSync(dirname(absPath), { recursive: true });\n writeFileSync(absPath, action.content, 'utf-8');\n written.push(action.relativePath);\n }\n\n return { written, skipped };\n};\n","import * as p from '@clack/prompts';\nimport type { ToolId } from 'ai-ops-compiler';\nimport {\n readManifest,\n resolveManifestPath,\n loadAllRules,\n renderForTool,\n buildInstallPlan,\n buildManifest,\n writeManifest,\n computeSourceHash,\n computeDiff,\n partitionRules,\n renderRulesToMarkdown,\n wrapWithHeader,\n TOOL_OUTPUT_MAP,\n} from 'ai-ops-compiler';\nimport type { FileAction } from 'ai-ops-compiler';\nimport { join } from 'node:path';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\nimport { installFiles } from '../lib/install.js';\n\nexport const updateCommand = async (opts: { scope: Scope; force: boolean }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n const manifestPath = resolveManifestPath(basePath);\n\n p.intro('ai-ops update');\n\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const rulesDir = resolveRulesDir();\n const sourceHash = computeSourceHash(rulesDir);\n\n const diffResult = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (diffResult.status === 'up-to-date' && !opts.force) {\n p.log.info('변경 사항이 없습니다.');\n p.outro('ai-ops update 완료');\n return;\n }\n\n const s = p.spinner();\n s.start('규칙 갱신 중...');\n\n const allRules = loadAllRules(rulesDir);\n const meta = { sourceHash, generatedAt: new Date().toISOString() };\n\n if (manifest.workspaces) {\n // 모노레포: workspaces 기반 재설치\n const workspaceEntries = Object.entries(manifest.workspaces);\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n\n if (toolId === 'claude-code') {\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const workspaceMappings = Object.entries(manifest.workspaces!).map(([path, entry]) => ({\n path,\n ruleIds: entry.rules,\n }));\n const renderResult = renderForTool('claude-code', rulesToInstall, workspaceMappings);\n const actions = buildInstallPlan({ toolId: 'claude-code', renderResult, meta });\n installFiles(basePath, actions);\n } else {\n // codex/gemini: global → 루트, domain → 워크스페이스별\n const config = TOOL_OUTPUT_MAP[toolId];\n\n const allInstalledRuleSet = new Set(manifest.installed_rules);\n const allRulesToInstall = allRules.filter((r) => allInstalledRuleSet.has(r.id));\n const { global } = partitionRules(allRulesToInstall);\n\n if (global.length > 0) {\n const rootAction: FileAction = {\n relativePath: join(config.dir, config.rootFileName),\n content: wrapWithHeader(renderRulesToMarkdown(global), meta),\n };\n installFiles(basePath, [rootAction]);\n }\n\n for (const [ws, entry] of workspaceEntries) {\n const wsRuleSet = new Set(entry.rules);\n const wsRules = allRules.filter((r) => wsRuleSet.has(r.id));\n const { domain } = partitionRules(wsRules);\n if (domain.length === 0) continue;\n\n const domainAction: FileAction = {\n relativePath: join(ws, config.dir, config.domainFileName),\n content: wrapWithHeader(renderRulesToMarkdown(domain), meta),\n };\n installFiles(basePath, [domainAction]);\n }\n }\n }\n } else {\n // 단일 프로젝트: installed_rules 기반 재설치\n const installedRuleSet = new Set(manifest.installed_rules);\n const rulesToInstall = allRules.filter((r) => installedRuleSet.has(r.id));\n\n for (const toolIdStr of manifest.tools) {\n const toolId = toolIdStr as ToolId;\n const renderResult = renderForTool(toolId, rulesToInstall);\n const actions = buildInstallPlan({ toolId, renderResult, meta });\n installFiles(basePath, actions);\n }\n }\n\n const newManifest = buildManifest({\n tools: manifest.tools,\n scope: manifest.scope,\n preset: manifest.preset,\n workspaces: manifest.workspaces,\n installedRules: manifest.installed_rules,\n sourceHash,\n });\n writeManifest(manifestPath, newManifest);\n\n s.stop('규칙 갱신 완료');\n p.outro('ai-ops update 완료');\n};\n","import * as p from '@clack/prompts';\nimport { readManifest, resolveManifestPath, computeSourceHash, computeDiff } from 'ai-ops-compiler';\nimport type { Scope } from '../lib/paths.js';\nimport { resolveBasePath, resolveRulesDir } from '../lib/paths.js';\n\nexport const diffCommand = async (opts: { scope: Scope }): Promise<void> => {\n const basePath = resolveBasePath(opts.scope);\n\n p.intro('ai-ops diff');\n\n const manifest = readManifest(resolveManifestPath(basePath));\n if (!manifest) {\n p.log.error('manifest가 없습니다. 먼저 ai-ops init을 실행하세요.');\n process.exit(1);\n }\n\n const sourceHash = computeSourceHash(resolveRulesDir());\n\n const result = computeDiff({\n previous: manifest,\n currentRules: manifest.installed_rules,\n currentSourceHash: sourceHash,\n });\n\n if (result.status === 'up-to-date') {\n p.log.success('변경 사항 없음. 최신 상태입니다.');\n } else {\n if (result.sourceChanged) {\n p.log.warn(`소스 변경 감지: ${manifest.sourceHash} → ${sourceHash}`);\n }\n if (result.added.length > 0) {\n p.log.info(`추가된 규칙: ${result.added.join(', ')}`);\n }\n if (result.removed.length > 0) {\n p.log.info(`제거된 규칙: ${result.removed.join(', ')}`);\n }\n }\n\n p.outro('ai-ops diff 완료');\n};\n"],"mappings":"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","names":["join","join","resolve","existsSync","resolve","join","p","resolveManifestPath","loadAllRules","renderForTool","buildInstallPlan","buildManifest","writeManifest","computeSourceHash","partitionRules","renderRulesToMarkdown","wrapWithHeader","TOOL_OUTPUT_MAP","join","resolveManifestPath","computeSourceHash","loadAllRules","renderForTool","buildInstallPlan","TOOL_OUTPUT_MAP","partitionRules","join","wrapWithHeader","renderRulesToMarkdown","buildManifest","writeManifest","p","readManifest","resolveManifestPath","computeSourceHash","computeDiff","readManifest","resolveManifestPath","computeSourceHash","computeDiff"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-ops-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "CLI for ai-ops scaffolding — manage AI tool rules and presets",
5
5
  "license": "MIT",
6
6
  "type": "module",