@sduck/sduck-cli 0.1.0 → 0.1.1
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/cli.js +19 -11
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/sduck-assets/agent-rules/claude-code.md +1 -0
- package/sduck-assets/agent-rules/codex.md +3 -1
- package/sduck-assets/agent-rules/core.md +2 -0
- package/sduck-assets/agent-rules/gemini-cli.md +2 -0
- package/sduck-assets/agent-rules/opencode.md +3 -1
package/dist/cli.js
CHANGED
|
@@ -51,8 +51,8 @@ var SUPPORTED_AGENTS = [
|
|
|
51
51
|
];
|
|
52
52
|
var AGENT_RULE_TARGETS = [
|
|
53
53
|
{ agentId: "claude-code", outputPath: "CLAUDE.md", kind: "root-file" },
|
|
54
|
-
{ agentId: "codex", outputPath: "
|
|
55
|
-
{ agentId: "opencode", outputPath: "
|
|
54
|
+
{ agentId: "codex", outputPath: "AGENT.md", kind: "root-file" },
|
|
55
|
+
{ agentId: "opencode", outputPath: "AGENT.md", kind: "root-file" },
|
|
56
56
|
{ agentId: "gemini-cli", outputPath: "GEMINI.md", kind: "root-file" },
|
|
57
57
|
{
|
|
58
58
|
agentId: "cursor",
|
|
@@ -523,18 +523,26 @@ function formatResult(result) {
|
|
|
523
523
|
}
|
|
524
524
|
return lines.join("\n");
|
|
525
525
|
}
|
|
526
|
+
function normalizeSelectedAgents(agentIds) {
|
|
527
|
+
const selectedAgentSet = new Set(agentIds);
|
|
528
|
+
return SUPPORTED_AGENTS.map((agent) => agent.id).filter(
|
|
529
|
+
(agentId) => selectedAgentSet.has(agentId)
|
|
530
|
+
);
|
|
531
|
+
}
|
|
526
532
|
async function resolveSelectedAgents(options) {
|
|
527
533
|
const parsedAgents = parseAgentsOption(options.agents);
|
|
528
534
|
if (parsedAgents.length > 0 || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
529
|
-
return parsedAgents;
|
|
530
|
-
}
|
|
531
|
-
return
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
535
|
+
return normalizeSelectedAgents(parsedAgents);
|
|
536
|
+
}
|
|
537
|
+
return normalizeSelectedAgents(
|
|
538
|
+
await checkbox({
|
|
539
|
+
message: "Select AI agents to generate repository rule files for",
|
|
540
|
+
choices: SUPPORTED_AGENTS.map((agent) => ({
|
|
541
|
+
name: agent.label,
|
|
542
|
+
value: agent.id
|
|
543
|
+
}))
|
|
544
|
+
})
|
|
545
|
+
);
|
|
538
546
|
}
|
|
539
547
|
async function runInitCommand(options, projectRoot) {
|
|
540
548
|
try {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/core/agent-rules.ts","../src/core/fs.ts","../src/core/init.ts","../src/core/assets.ts","../src/commands/plan-approve.ts","../src/core/plan-approve.ts","../src/core/workspace.ts","../src/utils/utc-date.ts","../src/commands/spec-approve.ts","../src/core/spec-approve.ts","../src/core/start.ts","../src/commands/start.ts","../src/core/command-metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\n\nimport { runInitCommand } from './commands/init.js';\nimport { runPlanApproveCommand } from './commands/plan-approve.js';\nimport { runSpecApproveCommand } from './commands/spec-approve.js';\nimport { runStartCommand } from './commands/start.js';\nimport {\n CLI_DESCRIPTION,\n CLI_NAME,\n PLACEHOLDER_MESSAGE,\n normalizeCommandName,\n} from './core/command-metadata.js';\n\nconst program = new Command();\n\nprogram.name(CLI_NAME).description(CLI_DESCRIPTION).version('0.1.0');\n\nprogram\n .command('init')\n .description('Initialize the current repository for the SDD workflow')\n .option('--force', 'Regenerate the bundled assets in sduck-assets')\n .option(\n '--agents <agents>',\n 'Comma-separated agents (claude-code,codex,opencode,gemini-cli,cursor,antigravity)',\n )\n .action(async (options: { agents?: string; force?: boolean }) => {\n const initOptions =\n options.agents === undefined\n ? { force: options.force ?? false }\n : { agents: options.agents, force: options.force ?? false };\n const result = await runInitCommand(initOptions, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('preview <name>')\n .description('Print the normalized command name for bootstrap verification')\n .action((name: string) => {\n console.log(normalizeCommandName(name));\n });\n\nprogram\n .command('start <type> <slug>')\n .description('Create a new task workspace from a type template')\n .action(async (type: string, slug: string) => {\n const result = await runStartCommand(type, slug, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('spec')\n .description('Manage spec workflow state')\n .command('approve [target]')\n .description('Approve a task spec and move it to plan writing')\n .action(async (target?: string) => {\n const input = target === undefined ? {} : { target };\n const result = await runSpecApproveCommand(input, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('plan')\n .description('Manage plan workflow state')\n .command('approve [target]')\n .description('Approve a task plan and move it to implementation')\n .action(async (target?: string) => {\n const input = target === undefined ? {} : { target };\n const result = await runPlanApproveCommand(input, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('roadmap')\n .description('Show the current bootstrap status')\n .action(() => {\n console.log(PLACEHOLDER_MESSAGE);\n });\n\nawait program.parseAsync(process.argv);\n","import { checkbox } from '@inquirer/prompts';\n\nimport { SUPPORTED_AGENTS, parseAgentsOption, type SupportedAgentId } from '../core/agent-rules.js';\nimport {\n type InitCommandOptions,\n type InitExecutionResult,\n type InitSummaryRow,\n initProject,\n} from '../core/init.js';\n\nexport interface CommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nexport interface InitCliOptions {\n agents?: string;\n force: boolean;\n}\n\nfunction padCell(value: string, width: number): string {\n return value.padEnd(width, ' ');\n}\n\nfunction buildSummaryTable(rows: InitSummaryRow[]): string {\n const statusWidth = Math.max('Status'.length, ...rows.map((row) => row.status.length));\n const pathWidth = Math.max('Path'.length, ...rows.map((row) => row.path.length));\n\n const border = `+-${'-'.repeat(statusWidth)}-+-${'-'.repeat(pathWidth)}-+`;\n const header = `| ${padCell('Status', statusWidth)} | ${padCell('Path', pathWidth)} |`;\n const body = rows.map(\n (row) => `| ${padCell(row.status, statusWidth)} | ${padCell(row.path, pathWidth)} |`,\n );\n\n return [border, header, border, ...body, border].join('\\n');\n}\n\nfunction formatResult(result: InitExecutionResult): string {\n const lines = [\n result.didChange ? 'sduck init completed.' : 'sduck init completed with no file changes.',\n ];\n\n if (result.agents.length > 0) {\n lines.push(`Selected agents: ${result.agents.join(', ')}`);\n }\n\n lines.push('', buildSummaryTable(result.summary.rows));\n\n if (result.summary.warnings.length > 0) {\n lines.push('', 'Warnings:');\n lines.push(...result.summary.warnings.map((warning) => `- ${warning}`));\n }\n\n return lines.join('\\n');\n}\n\nasync function resolveSelectedAgents(options: InitCliOptions): Promise<SupportedAgentId[]> {\n const parsedAgents = parseAgentsOption(options.agents);\n\n if (parsedAgents.length > 0 || !process.stdin.isTTY || !process.stdout.isTTY) {\n return parsedAgents;\n }\n\n return await checkbox<SupportedAgentId>({\n message: 'Select AI agents to generate repository rule files for',\n choices: SUPPORTED_AGENTS.map((agent) => ({\n name: agent.label,\n value: agent.id,\n })),\n });\n}\n\nexport async function runInitCommand(\n options: InitCliOptions,\n projectRoot: string,\n): Promise<CommandResult> {\n try {\n const resolvedOptions: InitCommandOptions = {\n force: options.force,\n agents: await resolveSelectedAgents(options),\n };\n const result = await initProject(resolvedOptions, projectRoot);\n\n return {\n exitCode: 0,\n stderr: '',\n stdout: formatResult(result),\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown init failure.';\n\n return {\n exitCode: 1,\n stderr: message,\n stdout: '',\n };\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { getFsEntryKind, type FsEntryKind } from './fs.js';\n\nexport type SupportedAgentId =\n | 'claude-code'\n | 'codex'\n | 'opencode'\n | 'gemini-cli'\n | 'cursor'\n | 'antigravity';\n\nexport type AgentRuleTargetKind = 'root-file' | 'managed-file';\n\nexport interface AgentRuleTarget {\n agentId: SupportedAgentId;\n outputPath: string;\n kind: AgentRuleTargetKind;\n}\n\nexport type AgentRuleMergeMode = 'create' | 'prepend' | 'keep' | 'replace-block' | 'overwrite';\n\nexport interface PlannedAgentRuleAction {\n agentId: SupportedAgentId;\n outputPath: string;\n kind: AgentRuleTargetKind;\n mergeMode: AgentRuleMergeMode;\n currentKind: FsEntryKind;\n}\n\nexport const SDD_RULES_BEGIN = '<!-- sduck:begin -->';\nexport const SDD_RULES_END = '<!-- sduck:end -->';\n\nexport const SUPPORTED_AGENTS: readonly { id: SupportedAgentId; label: string }[] = [\n { id: 'claude-code', label: 'Claude Code' },\n { id: 'codex', label: 'Codex' },\n { id: 'opencode', label: 'OpenCode' },\n { id: 'gemini-cli', label: 'Gemini CLI' },\n { id: 'cursor', label: 'Cursor' },\n { id: 'antigravity', label: 'Antigravity' },\n];\n\nconst AGENT_RULE_TARGETS: readonly AgentRuleTarget[] = [\n { agentId: 'claude-code', outputPath: 'CLAUDE.md', kind: 'root-file' },\n { agentId: 'codex', outputPath: 'AGENTS.md', kind: 'root-file' },\n { agentId: 'opencode', outputPath: 'AGENTS.md', kind: 'root-file' },\n { agentId: 'gemini-cli', outputPath: 'GEMINI.md', kind: 'root-file' },\n {\n agentId: 'cursor',\n outputPath: join('.cursor', 'rules', 'sduck-core.mdc'),\n kind: 'managed-file',\n },\n {\n agentId: 'antigravity',\n outputPath: join('.agents', 'rules', 'sduck-core.md'),\n kind: 'managed-file',\n },\n];\n\nconst AGENT_TEMPLATE_FILES: Record<SupportedAgentId, string> = {\n 'claude-code': 'claude-code.md',\n codex: 'codex.md',\n opencode: 'opencode.md',\n 'gemini-cli': 'gemini-cli.md',\n cursor: 'cursor.mdc',\n antigravity: 'antigravity.md',\n};\n\nfunction unique<T>(values: readonly T[]): T[] {\n return [...new Set(values)];\n}\n\nexport function parseAgentsOption(rawAgents: string | undefined): SupportedAgentId[] {\n if (rawAgents === undefined || rawAgents.trim() === '') {\n return [];\n }\n\n const requestedAgents = unique(\n rawAgents\n .split(',')\n .map((value) => value.trim())\n .filter((value) => value !== ''),\n );\n\n const validAgents = new Set(SUPPORTED_AGENTS.map((agent) => agent.id));\n const invalidAgent = requestedAgents.find((agent) => !validAgents.has(agent as SupportedAgentId));\n\n if (invalidAgent !== undefined) {\n throw new Error(`Unsupported agent: ${invalidAgent}`);\n }\n\n return requestedAgents as SupportedAgentId[];\n}\n\nexport function listAgentRuleTargets(selectedAgents: SupportedAgentId[]): AgentRuleTarget[] {\n const selectedAgentSet = new Set(selectedAgents);\n\n return AGENT_RULE_TARGETS.filter((target) => selectedAgentSet.has(target.agentId)).filter(\n (target, index, allTargets) =>\n index === allTargets.findIndex((candidate) => candidate.outputPath === target.outputPath),\n );\n}\n\nexport function hasManagedBlock(content: string): boolean {\n return content.includes(SDD_RULES_BEGIN) && content.includes(SDD_RULES_END);\n}\n\nexport function prependManagedBlock(existingContent: string, blockContent: string): string {\n const normalizedExistingContent = existingContent.trimStart();\n\n if (normalizedExistingContent === '') {\n return `${blockContent}\\n`;\n }\n\n return `${blockContent}\\n\\n${normalizedExistingContent}`;\n}\n\nexport function replaceManagedBlock(existingContent: string, blockContent: string): string {\n const blockPattern = new RegExp(`${SDD_RULES_BEGIN}[\\\\s\\\\S]*?${SDD_RULES_END}`);\n\n if (!blockPattern.test(existingContent)) {\n return prependManagedBlock(existingContent, blockContent);\n }\n\n return existingContent.replace(blockPattern, blockContent);\n}\n\nfunction renderManagedBlock(lines: string[]): string {\n return [SDD_RULES_BEGIN, ...lines, SDD_RULES_END].join('\\n');\n}\n\nasync function getAgentRulesAssetRoot(): Promise<string> {\n const currentDirectoryPath = dirname(fileURLToPath(import.meta.url));\n const candidatePaths = [\n join(currentDirectoryPath, '..', '..', 'sduck-assets', 'agent-rules'),\n join(currentDirectoryPath, '..', 'sduck-assets', 'agent-rules'),\n ];\n\n for (const candidatePath of candidatePaths) {\n if ((await getFsEntryKind(candidatePath)) === 'directory') {\n return candidatePath;\n }\n }\n\n throw new Error('Unable to locate bundled sduck agent rule assets.');\n}\n\nasync function readAssetFile(assetRoot: string, fileName: string): Promise<string> {\n return await readFile(join(assetRoot, fileName), 'utf8');\n}\n\nfunction buildRootFileLines(\n agentIds: SupportedAgentId[],\n agentSpecificContent: string[],\n): string[] {\n const labels = SUPPORTED_AGENTS.filter((agent) => agentIds.includes(agent.id)).map(\n (agent) => agent.label,\n );\n\n return [\n '# sduck managed rules',\n '',\n `Selected agents: ${labels.join(', ')}`,\n '',\n ...agentSpecificContent,\n ];\n}\n\nexport async function renderAgentRuleContent(\n target: AgentRuleTarget,\n selectedAgents: SupportedAgentId[],\n): Promise<string> {\n const assetRoot = await getAgentRulesAssetRoot();\n const coreContent = await readAssetFile(assetRoot, 'core.md');\n\n if (target.kind === 'managed-file') {\n const templateFileName = AGENT_TEMPLATE_FILES[target.agentId];\n const specificContent = await readAssetFile(assetRoot, templateFileName);\n\n return `${specificContent.trim()}\\n\\n${coreContent.trim()}\\n`;\n }\n\n const relatedAgents = AGENT_RULE_TARGETS.filter(\n (candidate) =>\n candidate.outputPath === target.outputPath && selectedAgents.includes(candidate.agentId),\n ).map((candidate) => candidate.agentId);\n\n const specificSections: string[] = [];\n\n for (const agentId of relatedAgents) {\n const templateFileName = AGENT_TEMPLATE_FILES[agentId];\n specificSections.push((await readAssetFile(assetRoot, templateFileName)).trim());\n }\n\n const lines = buildRootFileLines(relatedAgents, [...specificSections, coreContent.trim()]);\n\n return `${renderManagedBlock(lines)}\\n`;\n}\n\nexport function planAgentRuleActions(\n mode: 'safe' | 'force',\n targets: readonly AgentRuleTarget[],\n existingEntries: Map<string, FsEntryKind>,\n existingContents: Map<string, string>,\n): PlannedAgentRuleAction[] {\n return targets.map((target) => {\n const currentKind = existingEntries.get(target.outputPath) ?? 'missing';\n\n if (currentKind === 'missing') {\n return { ...target, mergeMode: 'create', currentKind };\n }\n\n if (currentKind !== 'file') {\n return { ...target, mergeMode: 'overwrite', currentKind };\n }\n\n if (target.kind === 'managed-file') {\n return { ...target, mergeMode: mode === 'force' ? 'overwrite' : 'keep', currentKind };\n }\n\n const content = existingContents.get(target.outputPath) ?? '';\n\n if (mode === 'safe') {\n return { ...target, mergeMode: hasManagedBlock(content) ? 'keep' : 'prepend', currentKind };\n }\n\n return {\n ...target,\n mergeMode: hasManagedBlock(content) ? 'replace-block' : 'prepend',\n currentKind,\n };\n });\n}\n","import { constants } from 'node:fs';\nimport { access, copyFile, mkdir, stat } from 'node:fs/promises';\n\nexport type FsEntryKind = 'missing' | 'file' | 'directory';\n\nexport async function getFsEntryKind(targetPath: string): Promise<FsEntryKind> {\n try {\n const stats = await stat(targetPath);\n\n if (stats.isDirectory()) {\n return 'directory';\n }\n\n if (stats.isFile()) {\n return 'file';\n }\n\n return 'file';\n } catch {\n return 'missing';\n }\n}\n\nexport async function ensureDirectory(targetPath: string): Promise<void> {\n await mkdir(targetPath, { recursive: true });\n}\n\nexport async function ensureReadableFile(targetPath: string): Promise<void> {\n await access(targetPath, constants.R_OK);\n}\n\nexport async function copyFileIntoPlace(sourcePath: string, targetPath: string): Promise<void> {\n await copyFile(sourcePath, targetPath);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nimport {\n type AgentRuleTarget,\n listAgentRuleTargets,\n planAgentRuleActions,\n prependManagedBlock,\n renderAgentRuleContent,\n replaceManagedBlock,\n type PlannedAgentRuleAction,\n type SupportedAgentId,\n} from './agent-rules.js';\nimport { EVAL_ASSET_RELATIVE_PATHS, getBundledAssetsRoot } from './assets.js';\nimport {\n copyFileIntoPlace,\n ensureDirectory,\n ensureReadableFile,\n getFsEntryKind,\n type FsEntryKind,\n} from './fs.js';\n\nimport type { InitCommandOptions, InitMode, ResolvedInitOptions } from './init-types.js';\n\nexport type { FsEntryKind } from './fs.js';\nexport type { InitCommandOptions, InitMode, ResolvedInitOptions } from './init-types.js';\n\nexport type AssetTemplateKey =\n | 'eval-spec'\n | 'eval-plan'\n | 'type-build'\n | 'type-feature'\n | 'type-fix'\n | 'type-refactor'\n | 'type-chore';\n\nexport interface AssetTemplateDefinition {\n key: AssetTemplateKey;\n relativePath: string;\n}\n\nexport type AssetTemplateMap = Record<AssetTemplateKey, AssetTemplateDefinition>;\n\nexport type AssetActionKind = 'create' | 'keep' | 'overwrite' | 'error';\n\nexport type AssetCollisionKind =\n | 'none'\n | 'file-directory-mismatch'\n | 'directory-file-mismatch'\n | 'unknown';\n\nexport interface PlannedAssetAction {\n key: AssetTemplateKey;\n targetPath: string;\n currentKind: FsEntryKind;\n action: AssetActionKind;\n collision: AssetCollisionKind;\n}\n\nexport type InitWarningCode =\n | 'kept-existing-asset'\n | 'kept-existing-rule'\n | 'type-conflict'\n | 'force-recommended';\n\nexport type InitErrorCode =\n | 'asset-root-conflict'\n | 'workspace-root-conflict'\n | 'asset-write-failed'\n | 'unknown-fs-error';\n\nexport interface InitSummaryRow {\n path: string;\n status: 'created' | 'prepended' | 'kept' | 'overwritten';\n}\n\nexport interface InitExecutionSummary {\n created: string[];\n prepended: string[];\n kept: string[];\n overwritten: string[];\n warnings: string[];\n errors: string[];\n rows: InitSummaryRow[];\n}\n\nexport interface InitExecutionResult {\n mode: InitMode;\n agents: string[];\n summary: InitExecutionSummary;\n didChange: boolean;\n}\n\nconst ASSET_TEMPLATE_DEFINITIONS = [\n {\n key: 'eval-spec',\n relativePath: join('sduck-assets', EVAL_ASSET_RELATIVE_PATHS.spec),\n },\n {\n key: 'eval-plan',\n relativePath: join('sduck-assets', EVAL_ASSET_RELATIVE_PATHS.plan),\n },\n {\n key: 'type-build',\n relativePath: join('sduck-assets', 'types', 'build.md'),\n },\n {\n key: 'type-feature',\n relativePath: join('sduck-assets', 'types', 'feature.md'),\n },\n { key: 'type-fix', relativePath: join('sduck-assets', 'types', 'fix.md') },\n {\n key: 'type-refactor',\n relativePath: join('sduck-assets', 'types', 'refactor.md'),\n },\n {\n key: 'type-chore',\n relativePath: join('sduck-assets', 'types', 'chore.md'),\n },\n] as const satisfies readonly AssetTemplateDefinition[];\n\nexport const ASSET_TEMPLATE_MAP = Object.fromEntries(\n ASSET_TEMPLATE_DEFINITIONS.map((definition) => [definition.key, definition]),\n) as AssetTemplateMap;\n\nexport function planInitActions(\n mode: InitMode,\n existingEntries: Map<string, FsEntryKind>,\n): PlannedAssetAction[] {\n return ASSET_TEMPLATE_DEFINITIONS.map((definition) => {\n const currentKind = existingEntries.get(definition.relativePath) ?? 'missing';\n\n if (currentKind === 'missing') {\n return {\n key: definition.key,\n targetPath: definition.relativePath,\n currentKind,\n action: 'create',\n collision: 'none',\n } satisfies PlannedAssetAction;\n }\n\n if (currentKind === 'file') {\n return {\n key: definition.key,\n targetPath: definition.relativePath,\n currentKind,\n action: mode === 'force' ? 'overwrite' : 'keep',\n collision: 'none',\n } satisfies PlannedAssetAction;\n }\n\n return {\n key: definition.key,\n targetPath: definition.relativePath,\n currentKind,\n action: 'error',\n collision: 'directory-file-mismatch',\n } satisfies PlannedAssetAction;\n });\n}\n\nexport function summarizeInitActions(actions: PlannedAssetAction[]): InitExecutionSummary {\n const summary: InitExecutionSummary = {\n created: [],\n prepended: [],\n kept: [],\n overwritten: [],\n warnings: [],\n errors: [],\n rows: [],\n };\n\n for (const action of actions) {\n if (action.action === 'create') {\n summary.created.push(action.targetPath);\n summary.rows.push({ path: action.targetPath, status: 'created' });\n continue;\n }\n\n if (action.action === 'keep') {\n summary.kept.push(action.targetPath);\n summary.rows.push({ path: action.targetPath, status: 'kept' });\n summary.warnings.push(`Kept existing asset: ${action.targetPath}`);\n continue;\n }\n\n if (action.action === 'overwrite') {\n summary.overwritten.push(action.targetPath);\n summary.rows.push({ path: action.targetPath, status: 'overwritten' });\n continue;\n }\n\n summary.errors.push(`Path conflict for ${action.targetPath}: ${action.collision}`);\n }\n\n if (summary.kept.length > 0) {\n summary.warnings.push('Run `sduck init --force` if you want to regenerate bundled assets.');\n }\n\n return summary;\n}\n\nfunction getInitMode(options: InitCommandOptions): InitMode {\n return options.force ? 'force' : 'safe';\n}\n\nfunction resolveInitOptions(options: InitCommandOptions): ResolvedInitOptions {\n return {\n mode: getInitMode(options),\n agents: [...new Set(options.agents)],\n };\n}\n\nasync function collectExistingEntries(projectRoot: string): Promise<Map<string, FsEntryKind>> {\n const existingEntries = new Map<string, FsEntryKind>();\n\n for (const definition of ASSET_TEMPLATE_DEFINITIONS) {\n existingEntries.set(\n definition.relativePath,\n await getFsEntryKind(join(projectRoot, definition.relativePath)),\n );\n }\n\n return existingEntries;\n}\n\nasync function collectExistingFileContents(\n projectRoot: string,\n targets: readonly AgentRuleTarget[],\n): Promise<Map<string, string>> {\n const contents = new Map<string, string>();\n\n for (const target of targets) {\n const targetPath = join(projectRoot, target.outputPath);\n\n if ((await getFsEntryKind(targetPath)) === 'file') {\n contents.set(target.outputPath, await readFile(targetPath, 'utf8'));\n }\n }\n\n return contents;\n}\n\nasync function ensureRootDirectory(\n targetPath: string,\n errorCode: InitErrorCode,\n): Promise<'created' | 'kept' | 'overwritten'> {\n const kind = await getFsEntryKind(targetPath);\n\n if (kind === 'missing') {\n await ensureDirectory(targetPath);\n return 'created';\n }\n\n if (kind === 'directory') {\n return 'kept';\n }\n\n throw new Error(`${errorCode}: expected a directory at ${targetPath}.`);\n}\n\nexport async function initProject(\n options: InitCommandOptions,\n projectRoot: string,\n): Promise<InitExecutionResult> {\n const resolvedOptions = resolveInitOptions(options);\n const { mode } = resolvedOptions;\n const assetSourceRoot = await getBundledAssetsRoot();\n const assetsRoot = join(projectRoot, 'sduck-assets');\n const workspaceRoot = join(projectRoot, 'sduck-workspace');\n\n const summary: InitExecutionSummary = {\n created: [],\n prepended: [],\n kept: [],\n overwritten: [],\n warnings: [],\n errors: [],\n rows: [],\n };\n\n const assetsRootStatus = await ensureRootDirectory(assetsRoot, 'asset-root-conflict');\n summary[assetsRootStatus].push('sduck-assets/');\n summary.rows.push({ path: 'sduck-assets/', status: assetsRootStatus });\n\n const workspaceRootStatus = await ensureRootDirectory(workspaceRoot, 'workspace-root-conflict');\n summary[workspaceRootStatus].push('sduck-workspace/');\n summary.rows.push({ path: 'sduck-workspace/', status: workspaceRootStatus });\n\n const actions = planInitActions(mode, await collectExistingEntries(projectRoot));\n const actionSummary = summarizeInitActions(actions);\n\n summary.created.push(...actionSummary.created);\n summary.kept.push(...actionSummary.kept);\n summary.overwritten.push(...actionSummary.overwritten);\n summary.warnings.push(...actionSummary.warnings);\n summary.errors.push(...actionSummary.errors);\n summary.rows.push(...actionSummary.rows);\n\n const conflict = actions.find((action) => action.action === 'error');\n\n if (conflict !== undefined) {\n throw new Error(\n `type-conflict: expected a file but found a directory at ${conflict.targetPath}. ` +\n 'Resolve it manually or move the conflicting path before retrying.',\n );\n }\n\n for (const action of actions) {\n if (action.action === 'keep') {\n continue;\n }\n\n const definition = ASSET_TEMPLATE_MAP[action.key];\n const sourcePath = join(\n assetSourceRoot,\n definition.relativePath.replace(/^sduck-assets[\\\\/]/, ''),\n );\n const targetPath = join(projectRoot, definition.relativePath);\n\n await ensureReadableFile(sourcePath);\n await mkdir(dirname(targetPath), { recursive: true });\n await copyFileIntoPlace(sourcePath, targetPath);\n }\n\n const agentTargets = listAgentRuleTargets(resolvedOptions.agents);\n const agentEntryKinds = new Map<string, FsEntryKind>();\n\n for (const target of agentTargets) {\n agentEntryKinds.set(\n target.outputPath,\n await getFsEntryKind(join(projectRoot, target.outputPath)),\n );\n }\n\n const existingContents = await collectExistingFileContents(projectRoot, agentTargets);\n const agentActions = planAgentRuleActions(mode, agentTargets, agentEntryKinds, existingContents);\n\n await applyAgentRuleActions(\n projectRoot,\n agentActions,\n existingContents,\n summary,\n resolvedOptions.agents,\n );\n\n return {\n mode,\n agents: resolvedOptions.agents,\n summary,\n didChange:\n summary.created.length > 0 || summary.prepended.length > 0 || summary.overwritten.length > 0,\n };\n}\n\nasync function applyAgentRuleActions(\n projectRoot: string,\n actions: readonly PlannedAgentRuleAction[],\n existingContents: Map<string, string>,\n summary: InitExecutionSummary,\n selectedAgents: SupportedAgentId[],\n): Promise<void> {\n for (const action of actions) {\n const targetPath = join(projectRoot, action.outputPath);\n const content = await renderAgentRuleContent(action, selectedAgents);\n\n if (action.mergeMode === 'create') {\n await mkdir(dirname(targetPath), { recursive: true });\n await writeFile(targetPath, content, 'utf8');\n summary.created.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'created' });\n continue;\n }\n\n if (action.mergeMode === 'keep') {\n summary.kept.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'kept' });\n summary.warnings.push(`Kept existing rule file: ${action.outputPath}`);\n continue;\n }\n\n await mkdir(dirname(targetPath), { recursive: true });\n\n if (action.mergeMode === 'prepend') {\n const currentContent = existingContents.get(action.outputPath) ?? '';\n await writeFile(targetPath, prependManagedBlock(currentContent, content.trimEnd()), 'utf8');\n summary.prepended.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'prepended' });\n continue;\n }\n\n if (action.mergeMode === 'replace-block') {\n const currentContent = existingContents.get(action.outputPath) ?? '';\n await writeFile(targetPath, replaceManagedBlock(currentContent, content.trimEnd()), 'utf8');\n summary.overwritten.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'overwritten' });\n continue;\n }\n\n await writeFile(targetPath, content, 'utf8');\n summary.overwritten.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'overwritten' });\n }\n\n if (summary.kept.some((path) => path.endsWith('.md') || path.endsWith('.mdc'))) {\n summary.warnings.push(\n 'Run `sduck init --force` to refresh managed rule content for selected agents.',\n );\n }\n}\n","import { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { getFsEntryKind } from './fs.js';\n\nexport type SupportedTaskType = 'build' | 'feature' | 'fix' | 'refactor' | 'chore';\n\nexport const SUPPORTED_TASK_TYPES: readonly SupportedTaskType[] = [\n 'build',\n 'feature',\n 'fix',\n 'refactor',\n 'chore',\n];\n\nexport const EVAL_ASSET_RELATIVE_PATHS = {\n plan: join('eval', 'plan.yml'),\n spec: join('eval', 'spec.yml'),\n} as const;\n\nexport const SPEC_TEMPLATE_RELATIVE_PATHS: Record<SupportedTaskType, string> = {\n build: join('types', 'build.md'),\n feature: join('types', 'feature.md'),\n fix: join('types', 'fix.md'),\n refactor: join('types', 'refactor.md'),\n chore: join('types', 'chore.md'),\n};\n\nexport const INIT_ASSET_RELATIVE_PATHS = [\n EVAL_ASSET_RELATIVE_PATHS.spec,\n EVAL_ASSET_RELATIVE_PATHS.plan,\n ...Object.values(SPEC_TEMPLATE_RELATIVE_PATHS),\n] as const;\n\nexport async function getBundledAssetsRoot(): Promise<string> {\n const currentDirectoryPath = dirname(fileURLToPath(import.meta.url));\n const candidatePaths = [\n join(currentDirectoryPath, '..', '..', 'sduck-assets'),\n join(currentDirectoryPath, '..', 'sduck-assets'),\n ];\n\n for (const candidatePath of candidatePaths) {\n if ((await getFsEntryKind(candidatePath)) === 'directory') {\n return candidatePath;\n }\n }\n\n throw new Error('Unable to locate bundled sduck-assets directory.');\n}\n\nexport function isSupportedTaskType(value: string): value is SupportedTaskType {\n return SUPPORTED_TASK_TYPES.includes(value as SupportedTaskType);\n}\n\nexport function resolveSpecTemplateRelativePath(type: SupportedTaskType): string {\n return SPEC_TEMPLATE_RELATIVE_PATHS[type];\n}\n","import { checkbox } from '@inquirer/prompts';\n\nimport {\n approvePlans,\n createPlanApprovedAt,\n loadPlanApprovalCandidates,\n type PlanApproveCommandInput,\n type PlanApproveResult,\n type PlanApproveTarget,\n} from '../core/plan-approve.js';\n\nexport interface PlanApproveCommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nfunction padCell(value: string, width: number): string {\n return value.padEnd(width, ' ');\n}\n\nfunction buildResultTable(result: PlanApproveResult): string {\n const rows = [\n ...result.succeeded.map((row) => ({\n note: row.note,\n result: 'success',\n steps: String(row.steps),\n task: row.taskId,\n })),\n ...result.failed.map((row) => ({\n note: row.note,\n result: 'failed',\n steps: '-',\n task: row.taskId,\n })),\n ];\n\n const resultWidth = Math.max('Result'.length, ...rows.map((row) => row.result.length));\n const taskWidth = Math.max('Task'.length, ...rows.map((row) => row.task.length));\n const stepsWidth = Math.max('Steps'.length, ...rows.map((row) => row.steps.length));\n const noteWidth = Math.max('Note'.length, ...rows.map((row) => row.note.length));\n\n const border = `+-${'-'.repeat(resultWidth)}-+-${'-'.repeat(taskWidth)}-+-${'-'.repeat(stepsWidth)}-+-${'-'.repeat(noteWidth)}-+`;\n const header = `| ${padCell('Result', resultWidth)} | ${padCell('Task', taskWidth)} | ${padCell('Steps', stepsWidth)} | ${padCell('Note', noteWidth)} |`;\n const body = rows.map(\n (row) =>\n `| ${padCell(row.result, resultWidth)} | ${padCell(row.task, taskWidth)} | ${padCell(row.steps, stepsWidth)} | ${padCell(row.note, noteWidth)} |`,\n );\n\n return [border, header, border, ...body, border].join('\\n');\n}\n\nfunction formatTaskLabel(task: PlanApproveTarget): string {\n return `${task.id} (${task.status})`;\n}\n\nfunction formatSuccess(result: PlanApproveResult): string {\n const lines = [buildResultTable(result)];\n\n if (result.succeeded.length > 0) {\n lines.push('', '상태: IN_PROGRESS → 작업을 시작합니다.');\n }\n\n return lines.join('\\n');\n}\n\nasync function selectTargets(tasks: readonly PlanApproveTarget[]): Promise<PlanApproveTarget[]> {\n if (tasks.length <= 1 || !process.stdin.isTTY || !process.stdout.isTTY) {\n return [...tasks];\n }\n\n const selectedIds = await checkbox<string>({\n message: 'Select tasks to approve plan for',\n choices: tasks.map((task) => ({ checked: true, name: formatTaskLabel(task), value: task.id })),\n });\n\n return tasks.filter((task) => selectedIds.includes(task.id));\n}\n\nexport async function runPlanApproveCommand(\n input: PlanApproveCommandInput,\n projectRoot: string,\n): Promise<PlanApproveCommandResult> {\n try {\n const candidates = await loadPlanApprovalCandidates(projectRoot, input);\n\n if (candidates.length === 0) {\n throw new Error('No matching tasks awaiting plan approval.');\n }\n\n if (\n input.target !== undefined &&\n candidates.length > 1 &&\n (!process.stdin.isTTY || !process.stdout.isTTY)\n ) {\n throw new Error(\n 'Multiple matching tasks found; rerun interactively to choose approval targets.',\n );\n }\n\n const selectedTasks = await selectTargets(candidates);\n\n if (selectedTasks.length === 0) {\n throw new Error('No tasks selected for plan approval.');\n }\n\n const result = await approvePlans(projectRoot, selectedTasks, createPlanApprovedAt());\n\n if (result.succeeded.length === 0) {\n return {\n exitCode: 1,\n stderr: buildResultTable(result),\n stdout: '',\n };\n }\n\n return {\n exitCode: result.failed.length > 0 ? 1 : 0,\n stderr: result.failed.length > 0 ? '' : '',\n stdout: formatSuccess(result),\n };\n } catch (error) {\n return {\n exitCode: 1,\n stderr: error instanceof Error ? error.message : 'Unknown plan approval failure.',\n stdout: '',\n };\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getFsEntryKind } from './fs.js';\nimport { listWorkspaceTasks, type WorkspaceTaskSummary } from './workspace.js';\nimport { formatUtcTimestamp } from '../utils/utc-date.js';\n\nexport interface PlanApproveCommandInput {\n target?: string;\n}\n\nexport interface PlanApproveTarget {\n createdAt?: string;\n id: string;\n path: string;\n slug?: string;\n status: string;\n}\n\nexport interface PlanApproveSuccessRow {\n note: string;\n steps: number;\n taskId: string;\n}\n\nexport interface PlanApproveFailureRow {\n note: string;\n taskId: string;\n}\n\nexport interface PlanApproveResult {\n approvedAt: string;\n failed: PlanApproveFailureRow[];\n nextStatus: 'IN_PROGRESS';\n succeeded: PlanApproveSuccessRow[];\n}\n\nexport function filterPlanApprovalCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n): PlanApproveTarget[] {\n return tasks.filter((task) => task.status === 'SPEC_APPROVED');\n}\n\nexport function resolvePlanApprovalCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n target: string | undefined,\n): PlanApproveTarget[] {\n const candidates = filterPlanApprovalCandidates(tasks);\n\n if (target === undefined || target.trim() === '') {\n return candidates;\n }\n\n const trimmedTarget = target.trim();\n\n return candidates.filter(\n (task) =>\n task.id === trimmedTarget || task.slug === trimmedTarget || task.id.endsWith(trimmedTarget),\n );\n}\n\nexport function countPlanSteps(planContent: string): number {\n const matches = planContent.match(/^## Step \\d+\\. .+$/gm);\n return matches?.length ?? 0;\n}\n\nexport function validatePlanHasSteps(planContent: string): void {\n if (countPlanSteps(planContent) === 0) {\n throw new Error('Plan does not contain any valid `## Step N. 제목` headers.');\n }\n}\n\nfunction updatePlanApprovalBlock(\n metaContent: string,\n approvedAt: string,\n totalSteps: number,\n): string {\n const withStatus = metaContent.replace(/^status:\\s+.+$/m, 'status: IN_PROGRESS');\n const withPlan = withStatus.replace(\n /plan:\\n {2}approved:\\s+false\\n {2}approved_at:\\s+null/m,\n `plan:\\n approved: true\\n approved_at: ${approvedAt}`,\n );\n\n return withPlan.replace(\n /steps:\\n {2}total:\\s+null\\n {2}completed:\\s+\\[\\]/m,\n `steps:\\n total: ${String(totalSteps)}\\n completed: []`,\n );\n}\n\nexport async function approvePlans(\n projectRoot: string,\n tasks: readonly PlanApproveTarget[],\n approvedAt: string,\n): Promise<PlanApproveResult> {\n const succeeded: PlanApproveSuccessRow[] = [];\n const failed: PlanApproveFailureRow[] = [];\n\n for (const task of tasks) {\n if (task.status !== 'SPEC_APPROVED') {\n failed.push({\n note: `task is not awaiting plan approval (${task.status})`,\n taskId: task.id,\n });\n continue;\n }\n\n const metaPath = join(projectRoot, task.path, 'meta.yml');\n const planPath = join(projectRoot, task.path, 'plan.md');\n\n if ((await getFsEntryKind(metaPath)) !== 'file') {\n failed.push({ note: 'missing meta.yml', taskId: task.id });\n continue;\n }\n\n if ((await getFsEntryKind(planPath)) !== 'file') {\n failed.push({ note: 'missing plan.md', taskId: task.id });\n continue;\n }\n\n const planContent = await readFile(planPath, 'utf8');\n const totalSteps = countPlanSteps(planContent);\n\n if (totalSteps === 0) {\n failed.push({ note: 'missing valid Step headers', taskId: task.id });\n continue;\n }\n\n const updatedMeta = updatePlanApprovalBlock(\n await readFile(metaPath, 'utf8'),\n approvedAt,\n totalSteps,\n );\n await writeFile(metaPath, updatedMeta, 'utf8');\n\n succeeded.push({ note: 'moved to IN_PROGRESS', steps: totalSteps, taskId: task.id });\n }\n\n return {\n approvedAt,\n failed,\n nextStatus: 'IN_PROGRESS',\n succeeded,\n };\n}\n\nexport async function loadPlanApprovalCandidates(\n projectRoot: string,\n input: PlanApproveCommandInput,\n): Promise<PlanApproveTarget[]> {\n const tasks = await listWorkspaceTasks(projectRoot);\n return resolvePlanApprovalCandidates(tasks, input.target);\n}\n\nexport function createPlanApprovedAt(date = new Date()): string {\n return formatUtcTimestamp(date);\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getFsEntryKind } from './fs.js';\n\nexport interface ActiveTaskSummary {\n id: string;\n path: string;\n status: string;\n}\n\nexport interface WorkspaceTaskSummary {\n createdAt?: string;\n id: string;\n path: string;\n slug?: string;\n status: string;\n}\n\nconst ACTIVE_STATUSES = new Set(['IN_PROGRESS', 'PENDING_SPEC_APPROVAL', 'PENDING_PLAN_APPROVAL']);\n\ninterface ParsedMeta {\n createdAt?: string;\n id?: string;\n slug?: string;\n status?: string;\n}\n\nfunction parseMetaText(content: string): ParsedMeta {\n const createdAtMatch = /^created_at:\\s+(.+)$/m.exec(content);\n const idMatch = /^id:\\s+(.+)$/m.exec(content);\n const slugMatch = /^slug:\\s+(.+)$/m.exec(content);\n const statusMatch = /^status:\\s+(.+)$/m.exec(content);\n const parsedMeta: ParsedMeta = {};\n\n if (createdAtMatch?.[1] !== undefined) {\n parsedMeta.createdAt = createdAtMatch[1].trim();\n }\n\n if (idMatch?.[1] !== undefined) {\n parsedMeta.id = idMatch[1].trim();\n }\n\n if (slugMatch?.[1] !== undefined) {\n parsedMeta.slug = slugMatch[1].trim();\n }\n\n if (statusMatch?.[1] !== undefined) {\n parsedMeta.status = statusMatch[1].trim();\n }\n\n return parsedMeta;\n}\n\nexport function sortTasksByRecency(tasks: readonly WorkspaceTaskSummary[]): WorkspaceTaskSummary[] {\n return [...tasks].sort((left, right) => {\n const leftValue = left.createdAt ?? '';\n const rightValue = right.createdAt ?? '';\n\n return rightValue.localeCompare(leftValue);\n });\n}\n\nexport async function listWorkspaceTasks(projectRoot: string): Promise<WorkspaceTaskSummary[]> {\n const workspaceRoot = join(projectRoot, 'sduck-workspace');\n\n if ((await getFsEntryKind(workspaceRoot)) !== 'directory') {\n return [];\n }\n\n const { readdir } = await import('node:fs/promises');\n const entries = await readdir(workspaceRoot, { withFileTypes: true });\n const tasks: WorkspaceTaskSummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n const relativePath = join('sduck-workspace', entry.name);\n const metaPath = join(projectRoot, relativePath, 'meta.yml');\n\n if ((await getFsEntryKind(metaPath)) !== 'file') {\n continue;\n }\n\n const parsedMeta = parseMetaText(await readFile(metaPath, 'utf8'));\n\n if (parsedMeta.id !== undefined && parsedMeta.status !== undefined) {\n const task: WorkspaceTaskSummary = {\n id: parsedMeta.id,\n path: relativePath,\n status: parsedMeta.status,\n };\n\n if (parsedMeta.createdAt !== undefined) {\n task.createdAt = parsedMeta.createdAt;\n }\n\n if (parsedMeta.slug !== undefined) {\n task.slug = parsedMeta.slug;\n }\n\n tasks.push(task);\n }\n }\n\n return sortTasksByRecency(tasks);\n}\n\nexport async function findActiveTask(projectRoot: string): Promise<ActiveTaskSummary | null> {\n const tasks = await listWorkspaceTasks(projectRoot);\n\n for (const task of tasks) {\n if (ACTIVE_STATUSES.has(task.status)) {\n return {\n id: task.id,\n path: task.path,\n status: task.status,\n };\n }\n }\n\n return null;\n}\n","function pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport function formatUtcDate(date: Date): string {\n const year = String(date.getUTCFullYear());\n const month = pad2(date.getUTCMonth() + 1);\n const day = pad2(date.getUTCDate());\n\n return `${year}-${month}-${day}`;\n}\n\nexport function formatUtcTimestamp(date: Date): string {\n const year = String(date.getUTCFullYear());\n const month = pad2(date.getUTCMonth() + 1);\n const day = pad2(date.getUTCDate());\n const hour = pad2(date.getUTCHours());\n const minute = pad2(date.getUTCMinutes());\n const second = pad2(date.getUTCSeconds());\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}Z`;\n}\n","import { checkbox } from '@inquirer/prompts';\n\nimport {\n approveSpecs,\n createSpecApprovedAt,\n loadSpecApprovalCandidates,\n type SpecApproveCommandInput,\n type SpecApproveResult,\n type SpecApproveTarget,\n} from '../core/spec-approve.js';\n\nexport interface SpecApproveCommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nfunction formatTaskLabel(task: SpecApproveTarget): string {\n return `${task.id} (${task.status})`;\n}\n\nfunction formatSuccess(result: SpecApproveResult, tasks: readonly SpecApproveTarget[]): string {\n const lines = ['스펙 승인됨'];\n\n for (const task of tasks) {\n lines.push(`- ${task.path} -> ${result.nextStatus}`);\n }\n\n lines.push('상태: SPEC_APPROVED → 플랜 작성을 시작합니다.');\n\n return lines.join('\\n');\n}\n\nasync function selectTargets(tasks: readonly SpecApproveTarget[]): Promise<SpecApproveTarget[]> {\n if (tasks.length <= 1 || !process.stdin.isTTY || !process.stdout.isTTY) {\n return [...tasks];\n }\n\n const selectedIds = await checkbox<string>({\n message: 'Select tasks to approve',\n choices: tasks.map((task) => ({\n checked: true,\n name: formatTaskLabel(task),\n value: task.id,\n })),\n });\n\n return tasks.filter((task) => selectedIds.includes(task.id));\n}\n\nexport async function runSpecApproveCommand(\n input: SpecApproveCommandInput,\n projectRoot: string,\n): Promise<SpecApproveCommandResult> {\n try {\n const candidates = await loadSpecApprovalCandidates(projectRoot, input);\n\n if (candidates.length === 0) {\n throw new Error('No matching tasks awaiting spec approval.');\n }\n\n if (\n input.target !== undefined &&\n candidates.length > 1 &&\n (!process.stdin.isTTY || !process.stdout.isTTY)\n ) {\n throw new Error(\n 'Multiple matching tasks found; rerun interactively to choose approval targets.',\n );\n }\n\n const selectedTasks = await selectTargets(candidates);\n\n if (selectedTasks.length === 0) {\n throw new Error('No tasks selected for spec approval.');\n }\n\n const result = await approveSpecs(projectRoot, selectedTasks, createSpecApprovedAt());\n\n return {\n exitCode: 0,\n stderr: '',\n stdout: formatSuccess(result, selectedTasks),\n };\n } catch (error) {\n return {\n exitCode: 1,\n stderr: error instanceof Error ? error.message : 'Unknown spec approval failure.',\n stdout: '',\n };\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getFsEntryKind } from './fs.js';\nimport { listWorkspaceTasks, type WorkspaceTaskSummary } from './workspace.js';\nimport { formatUtcTimestamp } from '../utils/utc-date.js';\n\nexport interface SpecApproveCommandInput {\n target?: string;\n}\n\nexport interface SpecApproveTarget {\n createdAt?: string;\n id: string;\n path: string;\n slug?: string;\n status: string;\n}\n\nexport interface SpecApproveResult {\n approvedAt: string;\n approvedTaskIds: string[];\n nextStatus: 'SPEC_APPROVED';\n}\n\nexport function filterApprovalCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n): SpecApproveTarget[] {\n return tasks.filter((task) => task.status === 'PENDING_SPEC_APPROVAL');\n}\n\nexport function resolveTargetCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n target: string | undefined,\n): SpecApproveTarget[] {\n const candidates = filterApprovalCandidates(tasks);\n\n if (target === undefined || target.trim() === '') {\n return candidates;\n }\n\n const trimmedTarget = target.trim();\n\n return candidates.filter(\n (task) =>\n task.id === trimmedTarget || task.slug === trimmedTarget || task.id.endsWith(trimmedTarget),\n );\n}\n\nexport function validateSpecApprovalTargets(tasks: readonly SpecApproveTarget[]): void {\n if (tasks.length === 0) {\n throw new Error('No approvable spec tasks found.');\n }\n\n const invalidTask = tasks.find((task) => task.status !== 'PENDING_SPEC_APPROVAL');\n\n if (invalidTask !== undefined) {\n throw new Error(\n `Task ${invalidTask.id} is not awaiting spec approval (${invalidTask.status}).`,\n );\n }\n}\n\nfunction updateSpecApprovalBlock(metaContent: string, approvedAt: string): string {\n const withStatus = metaContent.replace(/^status:\\s+.+$/m, 'status: SPEC_APPROVED');\n\n return withStatus.replace(\n /spec:\\n {2}approved:\\s+false\\n {2}approved_at:\\s+null/m,\n `spec:\\n approved: true\\n approved_at: ${approvedAt}`,\n );\n}\n\nexport async function approveSpecs(\n projectRoot: string,\n tasks: readonly SpecApproveTarget[],\n approvedAt: string,\n): Promise<SpecApproveResult> {\n validateSpecApprovalTargets(tasks);\n\n for (const task of tasks) {\n const metaPath = join(projectRoot, task.path, 'meta.yml');\n\n if ((await getFsEntryKind(metaPath)) !== 'file') {\n throw new Error(`Missing meta.yml for task ${task.id}.`);\n }\n\n const updatedContent = updateSpecApprovalBlock(await readFile(metaPath, 'utf8'), approvedAt);\n await writeFile(metaPath, updatedContent, 'utf8');\n }\n\n return {\n approvedAt,\n approvedTaskIds: tasks.map((task) => task.id),\n nextStatus: 'SPEC_APPROVED',\n };\n}\n\nexport async function loadSpecApprovalCandidates(\n projectRoot: string,\n input: SpecApproveCommandInput,\n): Promise<SpecApproveTarget[]> {\n const tasks = await listWorkspaceTasks(projectRoot);\n return resolveTargetCandidates(tasks, input.target);\n}\n\nexport function createSpecApprovedAt(date = new Date()): string {\n return formatUtcTimestamp(date);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport {\n getBundledAssetsRoot,\n isSupportedTaskType,\n resolveSpecTemplateRelativePath,\n type SupportedTaskType,\n} from './assets.js';\nimport { getFsEntryKind } from './fs.js';\nimport { findActiveTask, type ActiveTaskSummary } from './workspace.js';\nimport { formatUtcDate, formatUtcTimestamp } from '../utils/utc-date.js';\n\nexport interface StartCommandInput {\n type: SupportedTaskType;\n slug: string;\n}\n\nexport interface StartExecutionResult {\n workspaceId: string;\n workspacePath: string;\n status: 'PENDING_SPEC_APPROVAL';\n}\n\nexport function normalizeSlug(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[_\\s]+/g, '-')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\nexport function validateSlug(slug: string): void {\n if (slug === '') {\n throw new Error('Invalid slug: slug cannot be empty after normalization.');\n }\n\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)) {\n throw new Error('Invalid slug: use lowercase kebab-case only.');\n }\n}\n\nexport function createWorkspaceId(date: Date, type: SupportedTaskType, slug: string): string {\n const year = String(date.getUTCFullYear());\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const day = String(date.getUTCDate()).padStart(2, '0');\n const hour = String(date.getUTCHours()).padStart(2, '0');\n const minute = String(date.getUTCMinutes()).padStart(2, '0');\n\n return `${year}${month}${day}-${hour}${minute}-${type}-${slug}`;\n}\n\nexport function renderInitialMeta(input: {\n createdAt: string;\n id: string;\n slug: string;\n type: SupportedTaskType;\n}): string {\n return [\n `id: ${input.id}`,\n `type: ${input.type}`,\n `slug: ${input.slug}`,\n `created_at: ${input.createdAt}`,\n '',\n 'status: PENDING_SPEC_APPROVAL',\n '',\n 'spec:',\n ' approved: false',\n ' approved_at: null',\n '',\n 'plan:',\n ' approved: false',\n ' approved_at: null',\n '',\n 'steps:',\n ' total: null',\n ' completed: []',\n '',\n 'completed_at: null',\n '',\n ].join('\\n');\n}\n\nexport async function resolveSpecTemplatePath(type: SupportedTaskType): Promise<string> {\n const assetsRoot = await getBundledAssetsRoot();\n return join(assetsRoot, resolveSpecTemplateRelativePath(type));\n}\n\nfunction applyTemplateDefaults(\n template: string,\n type: SupportedTaskType,\n slug: string,\n currentDate: Date,\n): string {\n const displayName = slug.replace(/-/g, ' ');\n\n return template\n .replace(/\\{기능명\\}/g, displayName)\n .replace(/\\{버그 요약 한 줄\\}/g, displayName)\n .replace(/YYYY-MM-DD/g, formatUtcDate(currentDate))\n .replace(/> \\*\\*작성자:\\*\\*\\s*$/m, '> **작성자:** taehee')\n .replace(/> \\*\\*연관 티켓:\\*\\*\\s*$/m, '> **연관 티켓:** -')\n .replace(/^# \\[(feature|fix|refactor|chore|build)\\] .*/m, `# [${type}] ${displayName}`);\n}\n\nexport async function startTask(\n rawType: string,\n rawSlug: string,\n projectRoot: string,\n currentDate = new Date(),\n): Promise<StartExecutionResult> {\n if (!isSupportedTaskType(rawType)) {\n throw new Error(`Unsupported type: ${rawType}`);\n }\n\n const slug = normalizeSlug(rawSlug);\n validateSlug(slug);\n\n const activeTask = await findActiveTask(projectRoot);\n\n if (activeTask !== null) {\n throw new Error(\n `Active task exists: ${activeTask.id} (${activeTask.status}) at ${activeTask.path}. Finish or approve it before starting a new task.`,\n );\n }\n\n const workspaceId = createWorkspaceId(currentDate, rawType, slug);\n const workspacePath = join('sduck-workspace', workspaceId);\n const absoluteWorkspacePath = join(projectRoot, workspacePath);\n\n if ((await getFsEntryKind(absoluteWorkspacePath)) !== 'missing') {\n throw new Error(`Workspace already exists: ${workspacePath}`);\n }\n\n const workspaceRoot = join(projectRoot, 'sduck-workspace');\n await mkdir(workspaceRoot, { recursive: true });\n await mkdir(absoluteWorkspacePath, { recursive: false });\n\n const templatePath = await resolveSpecTemplatePath(rawType);\n if ((await getFsEntryKind(templatePath)) !== 'file') {\n throw new Error(`Missing spec template for type '${rawType}' at ${templatePath}`);\n }\n\n const specTemplate = await readFile(templatePath, 'utf8');\n const specContent = applyTemplateDefaults(specTemplate, rawType, slug, currentDate);\n const metaContent = renderInitialMeta({\n createdAt: formatUtcTimestamp(currentDate),\n id: workspaceId,\n slug,\n type: rawType,\n });\n\n await writeFile(join(absoluteWorkspacePath, 'meta.yml'), metaContent, 'utf8');\n await writeFile(join(absoluteWorkspacePath, 'spec.md'), specContent, 'utf8');\n await writeFile(join(absoluteWorkspacePath, 'plan.md'), '', 'utf8');\n\n return {\n workspaceId,\n workspacePath,\n status: 'PENDING_SPEC_APPROVAL',\n };\n}\n\nexport type { ActiveTaskSummary };\n","import { startTask } from '../core/start.js';\n\nexport interface StartCommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nexport async function runStartCommand(\n type: string,\n slug: string,\n projectRoot: string,\n): Promise<StartCommandResult> {\n try {\n const result = await startTask(type, slug, projectRoot);\n\n return {\n exitCode: 0,\n stderr: '',\n stdout: [\n '작업 디렉토리 생성됨',\n `경로: ${result.workspacePath}/`,\n `상태: ${result.status}`,\n ].join('\\n'),\n };\n } catch (error) {\n return {\n exitCode: 1,\n stderr: error instanceof Error ? error.message : 'Unknown start failure.',\n stdout: '',\n };\n }\n}\n","export const CLI_NAME = 'sduck';\n\nexport const CLI_DESCRIPTION = 'Spec-Driven Development workflow bootstrap CLI';\n\nexport const PLACEHOLDER_MESSAGE =\n 'Core workflow commands are planned but not implemented in this bootstrap yet.';\n\nexport function normalizeCommandName(input: string): string {\n return input.trim().toLowerCase().replace(/\\s+/g, '-');\n}\n"],"mappings":"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","names":["mkdir","readFile","dirname","join","dirname","join","fileURLToPath","join","dirname","fileURLToPath","join","readFile","mkdir","dirname","checkbox","readFile","writeFile","join","readFile","join","join","readFile","join","readFile","writeFile","padCell","checkbox","checkbox","readFile","writeFile","join","join","readFile","writeFile","formatTaskLabel","formatSuccess","selectTargets","checkbox","mkdir","readFile","writeFile","join","join","mkdir","readFile","writeFile"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/core/agent-rules.ts","../src/core/fs.ts","../src/core/init.ts","../src/core/assets.ts","../src/commands/plan-approve.ts","../src/core/plan-approve.ts","../src/core/workspace.ts","../src/utils/utc-date.ts","../src/commands/spec-approve.ts","../src/core/spec-approve.ts","../src/core/start.ts","../src/commands/start.ts","../src/core/command-metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\n\nimport { runInitCommand } from './commands/init.js';\nimport { runPlanApproveCommand } from './commands/plan-approve.js';\nimport { runSpecApproveCommand } from './commands/spec-approve.js';\nimport { runStartCommand } from './commands/start.js';\nimport {\n CLI_DESCRIPTION,\n CLI_NAME,\n PLACEHOLDER_MESSAGE,\n normalizeCommandName,\n} from './core/command-metadata.js';\n\nconst program = new Command();\n\nprogram.name(CLI_NAME).description(CLI_DESCRIPTION).version('0.1.0');\n\nprogram\n .command('init')\n .description('Initialize the current repository for the SDD workflow')\n .option('--force', 'Regenerate the bundled assets in sduck-assets')\n .option(\n '--agents <agents>',\n 'Comma-separated agents (claude-code,codex,opencode,gemini-cli,cursor,antigravity)',\n )\n .action(async (options: { agents?: string; force?: boolean }) => {\n const initOptions =\n options.agents === undefined\n ? { force: options.force ?? false }\n : { agents: options.agents, force: options.force ?? false };\n const result = await runInitCommand(initOptions, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('preview <name>')\n .description('Print the normalized command name for bootstrap verification')\n .action((name: string) => {\n console.log(normalizeCommandName(name));\n });\n\nprogram\n .command('start <type> <slug>')\n .description('Create a new task workspace from a type template')\n .action(async (type: string, slug: string) => {\n const result = await runStartCommand(type, slug, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('spec')\n .description('Manage spec workflow state')\n .command('approve [target]')\n .description('Approve a task spec and move it to plan writing')\n .action(async (target?: string) => {\n const input = target === undefined ? {} : { target };\n const result = await runSpecApproveCommand(input, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('plan')\n .description('Manage plan workflow state')\n .command('approve [target]')\n .description('Approve a task plan and move it to implementation')\n .action(async (target?: string) => {\n const input = target === undefined ? {} : { target };\n const result = await runPlanApproveCommand(input, process.cwd());\n\n if (result.stdout !== '') {\n console.log(result.stdout);\n }\n\n if (result.stderr !== '') {\n console.error(result.stderr);\n }\n\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n });\n\nprogram\n .command('roadmap')\n .description('Show the current bootstrap status')\n .action(() => {\n console.log(PLACEHOLDER_MESSAGE);\n });\n\nawait program.parseAsync(process.argv);\n","import { checkbox } from '@inquirer/prompts';\n\nimport { SUPPORTED_AGENTS, parseAgentsOption, type SupportedAgentId } from '../core/agent-rules.js';\nimport {\n type InitCommandOptions,\n type InitExecutionResult,\n type InitSummaryRow,\n initProject,\n} from '../core/init.js';\n\nexport interface CommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nexport interface InitCliOptions {\n agents?: string;\n force: boolean;\n}\n\nfunction padCell(value: string, width: number): string {\n return value.padEnd(width, ' ');\n}\n\nfunction buildSummaryTable(rows: InitSummaryRow[]): string {\n const statusWidth = Math.max('Status'.length, ...rows.map((row) => row.status.length));\n const pathWidth = Math.max('Path'.length, ...rows.map((row) => row.path.length));\n\n const border = `+-${'-'.repeat(statusWidth)}-+-${'-'.repeat(pathWidth)}-+`;\n const header = `| ${padCell('Status', statusWidth)} | ${padCell('Path', pathWidth)} |`;\n const body = rows.map(\n (row) => `| ${padCell(row.status, statusWidth)} | ${padCell(row.path, pathWidth)} |`,\n );\n\n return [border, header, border, ...body, border].join('\\n');\n}\n\nfunction formatResult(result: InitExecutionResult): string {\n const lines = [\n result.didChange ? 'sduck init completed.' : 'sduck init completed with no file changes.',\n ];\n\n if (result.agents.length > 0) {\n lines.push(`Selected agents: ${result.agents.join(', ')}`);\n }\n\n lines.push('', buildSummaryTable(result.summary.rows));\n\n if (result.summary.warnings.length > 0) {\n lines.push('', 'Warnings:');\n lines.push(...result.summary.warnings.map((warning) => `- ${warning}`));\n }\n\n return lines.join('\\n');\n}\n\nfunction normalizeSelectedAgents(agentIds: readonly SupportedAgentId[]): SupportedAgentId[] {\n const selectedAgentSet = new Set(agentIds);\n\n return SUPPORTED_AGENTS.map((agent) => agent.id).filter((agentId) =>\n selectedAgentSet.has(agentId),\n );\n}\n\nasync function resolveSelectedAgents(options: InitCliOptions): Promise<SupportedAgentId[]> {\n const parsedAgents = parseAgentsOption(options.agents);\n\n if (parsedAgents.length > 0 || !process.stdin.isTTY || !process.stdout.isTTY) {\n return normalizeSelectedAgents(parsedAgents);\n }\n\n return normalizeSelectedAgents(\n await checkbox<SupportedAgentId>({\n message: 'Select AI agents to generate repository rule files for',\n choices: SUPPORTED_AGENTS.map((agent) => ({\n name: agent.label,\n value: agent.id,\n })),\n }),\n );\n}\n\nexport async function runInitCommand(\n options: InitCliOptions,\n projectRoot: string,\n): Promise<CommandResult> {\n try {\n const resolvedOptions: InitCommandOptions = {\n force: options.force,\n agents: await resolveSelectedAgents(options),\n };\n const result = await initProject(resolvedOptions, projectRoot);\n\n return {\n exitCode: 0,\n stderr: '',\n stdout: formatResult(result),\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown init failure.';\n\n return {\n exitCode: 1,\n stderr: message,\n stdout: '',\n };\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { getFsEntryKind, type FsEntryKind } from './fs.js';\n\nexport type SupportedAgentId =\n | 'claude-code'\n | 'codex'\n | 'opencode'\n | 'gemini-cli'\n | 'cursor'\n | 'antigravity';\n\nexport type AgentRuleTargetKind = 'root-file' | 'managed-file';\n\nexport interface AgentRuleTarget {\n agentId: SupportedAgentId;\n outputPath: string;\n kind: AgentRuleTargetKind;\n}\n\nexport type AgentRuleMergeMode = 'create' | 'prepend' | 'keep' | 'replace-block' | 'overwrite';\n\nexport interface PlannedAgentRuleAction {\n agentId: SupportedAgentId;\n outputPath: string;\n kind: AgentRuleTargetKind;\n mergeMode: AgentRuleMergeMode;\n currentKind: FsEntryKind;\n}\n\nexport const SDD_RULES_BEGIN = '<!-- sduck:begin -->';\nexport const SDD_RULES_END = '<!-- sduck:end -->';\n\nexport const SUPPORTED_AGENTS: readonly { id: SupportedAgentId; label: string }[] = [\n { id: 'claude-code', label: 'Claude Code' },\n { id: 'codex', label: 'Codex' },\n { id: 'opencode', label: 'OpenCode' },\n { id: 'gemini-cli', label: 'Gemini CLI' },\n { id: 'cursor', label: 'Cursor' },\n { id: 'antigravity', label: 'Antigravity' },\n];\n\nconst AGENT_RULE_TARGETS: readonly AgentRuleTarget[] = [\n { agentId: 'claude-code', outputPath: 'CLAUDE.md', kind: 'root-file' },\n { agentId: 'codex', outputPath: 'AGENT.md', kind: 'root-file' },\n { agentId: 'opencode', outputPath: 'AGENT.md', kind: 'root-file' },\n { agentId: 'gemini-cli', outputPath: 'GEMINI.md', kind: 'root-file' },\n {\n agentId: 'cursor',\n outputPath: join('.cursor', 'rules', 'sduck-core.mdc'),\n kind: 'managed-file',\n },\n {\n agentId: 'antigravity',\n outputPath: join('.agents', 'rules', 'sduck-core.md'),\n kind: 'managed-file',\n },\n];\n\nconst AGENT_TEMPLATE_FILES: Record<SupportedAgentId, string> = {\n 'claude-code': 'claude-code.md',\n codex: 'codex.md',\n opencode: 'opencode.md',\n 'gemini-cli': 'gemini-cli.md',\n cursor: 'cursor.mdc',\n antigravity: 'antigravity.md',\n};\n\nfunction unique<T>(values: readonly T[]): T[] {\n return [...new Set(values)];\n}\n\nexport function parseAgentsOption(rawAgents: string | undefined): SupportedAgentId[] {\n if (rawAgents === undefined || rawAgents.trim() === '') {\n return [];\n }\n\n const requestedAgents = unique(\n rawAgents\n .split(',')\n .map((value) => value.trim())\n .filter((value) => value !== ''),\n );\n\n const validAgents = new Set(SUPPORTED_AGENTS.map((agent) => agent.id));\n const invalidAgent = requestedAgents.find((agent) => !validAgents.has(agent as SupportedAgentId));\n\n if (invalidAgent !== undefined) {\n throw new Error(`Unsupported agent: ${invalidAgent}`);\n }\n\n return requestedAgents as SupportedAgentId[];\n}\n\nexport function listAgentRuleTargets(selectedAgents: SupportedAgentId[]): AgentRuleTarget[] {\n const selectedAgentSet = new Set(selectedAgents);\n\n return AGENT_RULE_TARGETS.filter((target) => selectedAgentSet.has(target.agentId)).filter(\n (target, index, allTargets) =>\n index === allTargets.findIndex((candidate) => candidate.outputPath === target.outputPath),\n );\n}\n\nexport function hasManagedBlock(content: string): boolean {\n return content.includes(SDD_RULES_BEGIN) && content.includes(SDD_RULES_END);\n}\n\nexport function prependManagedBlock(existingContent: string, blockContent: string): string {\n const normalizedExistingContent = existingContent.trimStart();\n\n if (normalizedExistingContent === '') {\n return `${blockContent}\\n`;\n }\n\n return `${blockContent}\\n\\n${normalizedExistingContent}`;\n}\n\nexport function replaceManagedBlock(existingContent: string, blockContent: string): string {\n const blockPattern = new RegExp(`${SDD_RULES_BEGIN}[\\\\s\\\\S]*?${SDD_RULES_END}`);\n\n if (!blockPattern.test(existingContent)) {\n return prependManagedBlock(existingContent, blockContent);\n }\n\n return existingContent.replace(blockPattern, blockContent);\n}\n\nfunction renderManagedBlock(lines: string[]): string {\n return [SDD_RULES_BEGIN, ...lines, SDD_RULES_END].join('\\n');\n}\n\nasync function getAgentRulesAssetRoot(): Promise<string> {\n const currentDirectoryPath = dirname(fileURLToPath(import.meta.url));\n const candidatePaths = [\n join(currentDirectoryPath, '..', '..', 'sduck-assets', 'agent-rules'),\n join(currentDirectoryPath, '..', 'sduck-assets', 'agent-rules'),\n ];\n\n for (const candidatePath of candidatePaths) {\n if ((await getFsEntryKind(candidatePath)) === 'directory') {\n return candidatePath;\n }\n }\n\n throw new Error('Unable to locate bundled sduck agent rule assets.');\n}\n\nasync function readAssetFile(assetRoot: string, fileName: string): Promise<string> {\n return await readFile(join(assetRoot, fileName), 'utf8');\n}\n\nfunction buildRootFileLines(\n agentIds: SupportedAgentId[],\n agentSpecificContent: string[],\n): string[] {\n const labels = SUPPORTED_AGENTS.filter((agent) => agentIds.includes(agent.id)).map(\n (agent) => agent.label,\n );\n\n return [\n '# sduck managed rules',\n '',\n `Selected agents: ${labels.join(', ')}`,\n '',\n ...agentSpecificContent,\n ];\n}\n\nexport async function renderAgentRuleContent(\n target: AgentRuleTarget,\n selectedAgents: SupportedAgentId[],\n): Promise<string> {\n const assetRoot = await getAgentRulesAssetRoot();\n const coreContent = await readAssetFile(assetRoot, 'core.md');\n\n if (target.kind === 'managed-file') {\n const templateFileName = AGENT_TEMPLATE_FILES[target.agentId];\n const specificContent = await readAssetFile(assetRoot, templateFileName);\n\n return `${specificContent.trim()}\\n\\n${coreContent.trim()}\\n`;\n }\n\n const relatedAgents = AGENT_RULE_TARGETS.filter(\n (candidate) =>\n candidate.outputPath === target.outputPath && selectedAgents.includes(candidate.agentId),\n ).map((candidate) => candidate.agentId);\n\n const specificSections: string[] = [];\n\n for (const agentId of relatedAgents) {\n const templateFileName = AGENT_TEMPLATE_FILES[agentId];\n specificSections.push((await readAssetFile(assetRoot, templateFileName)).trim());\n }\n\n const lines = buildRootFileLines(relatedAgents, [...specificSections, coreContent.trim()]);\n\n return `${renderManagedBlock(lines)}\\n`;\n}\n\nexport function planAgentRuleActions(\n mode: 'safe' | 'force',\n targets: readonly AgentRuleTarget[],\n existingEntries: Map<string, FsEntryKind>,\n existingContents: Map<string, string>,\n): PlannedAgentRuleAction[] {\n return targets.map((target) => {\n const currentKind = existingEntries.get(target.outputPath) ?? 'missing';\n\n if (currentKind === 'missing') {\n return { ...target, mergeMode: 'create', currentKind };\n }\n\n if (currentKind !== 'file') {\n return { ...target, mergeMode: 'overwrite', currentKind };\n }\n\n if (target.kind === 'managed-file') {\n return { ...target, mergeMode: mode === 'force' ? 'overwrite' : 'keep', currentKind };\n }\n\n const content = existingContents.get(target.outputPath) ?? '';\n\n if (mode === 'safe') {\n return { ...target, mergeMode: hasManagedBlock(content) ? 'keep' : 'prepend', currentKind };\n }\n\n return {\n ...target,\n mergeMode: hasManagedBlock(content) ? 'replace-block' : 'prepend',\n currentKind,\n };\n });\n}\n","import { constants } from 'node:fs';\nimport { access, copyFile, mkdir, stat } from 'node:fs/promises';\n\nexport type FsEntryKind = 'missing' | 'file' | 'directory';\n\nexport async function getFsEntryKind(targetPath: string): Promise<FsEntryKind> {\n try {\n const stats = await stat(targetPath);\n\n if (stats.isDirectory()) {\n return 'directory';\n }\n\n if (stats.isFile()) {\n return 'file';\n }\n\n return 'file';\n } catch {\n return 'missing';\n }\n}\n\nexport async function ensureDirectory(targetPath: string): Promise<void> {\n await mkdir(targetPath, { recursive: true });\n}\n\nexport async function ensureReadableFile(targetPath: string): Promise<void> {\n await access(targetPath, constants.R_OK);\n}\n\nexport async function copyFileIntoPlace(sourcePath: string, targetPath: string): Promise<void> {\n await copyFile(sourcePath, targetPath);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nimport {\n type AgentRuleTarget,\n listAgentRuleTargets,\n planAgentRuleActions,\n prependManagedBlock,\n renderAgentRuleContent,\n replaceManagedBlock,\n type PlannedAgentRuleAction,\n type SupportedAgentId,\n} from './agent-rules.js';\nimport { EVAL_ASSET_RELATIVE_PATHS, getBundledAssetsRoot } from './assets.js';\nimport {\n copyFileIntoPlace,\n ensureDirectory,\n ensureReadableFile,\n getFsEntryKind,\n type FsEntryKind,\n} from './fs.js';\n\nimport type { InitCommandOptions, InitMode, ResolvedInitOptions } from './init-types.js';\n\nexport type { FsEntryKind } from './fs.js';\nexport type { InitCommandOptions, InitMode, ResolvedInitOptions } from './init-types.js';\n\nexport type AssetTemplateKey =\n | 'eval-spec'\n | 'eval-plan'\n | 'type-build'\n | 'type-feature'\n | 'type-fix'\n | 'type-refactor'\n | 'type-chore';\n\nexport interface AssetTemplateDefinition {\n key: AssetTemplateKey;\n relativePath: string;\n}\n\nexport type AssetTemplateMap = Record<AssetTemplateKey, AssetTemplateDefinition>;\n\nexport type AssetActionKind = 'create' | 'keep' | 'overwrite' | 'error';\n\nexport type AssetCollisionKind =\n | 'none'\n | 'file-directory-mismatch'\n | 'directory-file-mismatch'\n | 'unknown';\n\nexport interface PlannedAssetAction {\n key: AssetTemplateKey;\n targetPath: string;\n currentKind: FsEntryKind;\n action: AssetActionKind;\n collision: AssetCollisionKind;\n}\n\nexport type InitWarningCode =\n | 'kept-existing-asset'\n | 'kept-existing-rule'\n | 'type-conflict'\n | 'force-recommended';\n\nexport type InitErrorCode =\n | 'asset-root-conflict'\n | 'workspace-root-conflict'\n | 'asset-write-failed'\n | 'unknown-fs-error';\n\nexport interface InitSummaryRow {\n path: string;\n status: 'created' | 'prepended' | 'kept' | 'overwritten';\n}\n\nexport interface InitExecutionSummary {\n created: string[];\n prepended: string[];\n kept: string[];\n overwritten: string[];\n warnings: string[];\n errors: string[];\n rows: InitSummaryRow[];\n}\n\nexport interface InitExecutionResult {\n mode: InitMode;\n agents: string[];\n summary: InitExecutionSummary;\n didChange: boolean;\n}\n\nconst ASSET_TEMPLATE_DEFINITIONS = [\n {\n key: 'eval-spec',\n relativePath: join('sduck-assets', EVAL_ASSET_RELATIVE_PATHS.spec),\n },\n {\n key: 'eval-plan',\n relativePath: join('sduck-assets', EVAL_ASSET_RELATIVE_PATHS.plan),\n },\n {\n key: 'type-build',\n relativePath: join('sduck-assets', 'types', 'build.md'),\n },\n {\n key: 'type-feature',\n relativePath: join('sduck-assets', 'types', 'feature.md'),\n },\n { key: 'type-fix', relativePath: join('sduck-assets', 'types', 'fix.md') },\n {\n key: 'type-refactor',\n relativePath: join('sduck-assets', 'types', 'refactor.md'),\n },\n {\n key: 'type-chore',\n relativePath: join('sduck-assets', 'types', 'chore.md'),\n },\n] as const satisfies readonly AssetTemplateDefinition[];\n\nexport const ASSET_TEMPLATE_MAP = Object.fromEntries(\n ASSET_TEMPLATE_DEFINITIONS.map((definition) => [definition.key, definition]),\n) as AssetTemplateMap;\n\nexport function planInitActions(\n mode: InitMode,\n existingEntries: Map<string, FsEntryKind>,\n): PlannedAssetAction[] {\n return ASSET_TEMPLATE_DEFINITIONS.map((definition) => {\n const currentKind = existingEntries.get(definition.relativePath) ?? 'missing';\n\n if (currentKind === 'missing') {\n return {\n key: definition.key,\n targetPath: definition.relativePath,\n currentKind,\n action: 'create',\n collision: 'none',\n } satisfies PlannedAssetAction;\n }\n\n if (currentKind === 'file') {\n return {\n key: definition.key,\n targetPath: definition.relativePath,\n currentKind,\n action: mode === 'force' ? 'overwrite' : 'keep',\n collision: 'none',\n } satisfies PlannedAssetAction;\n }\n\n return {\n key: definition.key,\n targetPath: definition.relativePath,\n currentKind,\n action: 'error',\n collision: 'directory-file-mismatch',\n } satisfies PlannedAssetAction;\n });\n}\n\nexport function summarizeInitActions(actions: PlannedAssetAction[]): InitExecutionSummary {\n const summary: InitExecutionSummary = {\n created: [],\n prepended: [],\n kept: [],\n overwritten: [],\n warnings: [],\n errors: [],\n rows: [],\n };\n\n for (const action of actions) {\n if (action.action === 'create') {\n summary.created.push(action.targetPath);\n summary.rows.push({ path: action.targetPath, status: 'created' });\n continue;\n }\n\n if (action.action === 'keep') {\n summary.kept.push(action.targetPath);\n summary.rows.push({ path: action.targetPath, status: 'kept' });\n summary.warnings.push(`Kept existing asset: ${action.targetPath}`);\n continue;\n }\n\n if (action.action === 'overwrite') {\n summary.overwritten.push(action.targetPath);\n summary.rows.push({ path: action.targetPath, status: 'overwritten' });\n continue;\n }\n\n summary.errors.push(`Path conflict for ${action.targetPath}: ${action.collision}`);\n }\n\n if (summary.kept.length > 0) {\n summary.warnings.push('Run `sduck init --force` if you want to regenerate bundled assets.');\n }\n\n return summary;\n}\n\nfunction getInitMode(options: InitCommandOptions): InitMode {\n return options.force ? 'force' : 'safe';\n}\n\nfunction resolveInitOptions(options: InitCommandOptions): ResolvedInitOptions {\n return {\n mode: getInitMode(options),\n agents: [...new Set(options.agents)],\n };\n}\n\nasync function collectExistingEntries(projectRoot: string): Promise<Map<string, FsEntryKind>> {\n const existingEntries = new Map<string, FsEntryKind>();\n\n for (const definition of ASSET_TEMPLATE_DEFINITIONS) {\n existingEntries.set(\n definition.relativePath,\n await getFsEntryKind(join(projectRoot, definition.relativePath)),\n );\n }\n\n return existingEntries;\n}\n\nasync function collectExistingFileContents(\n projectRoot: string,\n targets: readonly AgentRuleTarget[],\n): Promise<Map<string, string>> {\n const contents = new Map<string, string>();\n\n for (const target of targets) {\n const targetPath = join(projectRoot, target.outputPath);\n\n if ((await getFsEntryKind(targetPath)) === 'file') {\n contents.set(target.outputPath, await readFile(targetPath, 'utf8'));\n }\n }\n\n return contents;\n}\n\nasync function ensureRootDirectory(\n targetPath: string,\n errorCode: InitErrorCode,\n): Promise<'created' | 'kept' | 'overwritten'> {\n const kind = await getFsEntryKind(targetPath);\n\n if (kind === 'missing') {\n await ensureDirectory(targetPath);\n return 'created';\n }\n\n if (kind === 'directory') {\n return 'kept';\n }\n\n throw new Error(`${errorCode}: expected a directory at ${targetPath}.`);\n}\n\nexport async function initProject(\n options: InitCommandOptions,\n projectRoot: string,\n): Promise<InitExecutionResult> {\n const resolvedOptions = resolveInitOptions(options);\n const { mode } = resolvedOptions;\n const assetSourceRoot = await getBundledAssetsRoot();\n const assetsRoot = join(projectRoot, 'sduck-assets');\n const workspaceRoot = join(projectRoot, 'sduck-workspace');\n\n const summary: InitExecutionSummary = {\n created: [],\n prepended: [],\n kept: [],\n overwritten: [],\n warnings: [],\n errors: [],\n rows: [],\n };\n\n const assetsRootStatus = await ensureRootDirectory(assetsRoot, 'asset-root-conflict');\n summary[assetsRootStatus].push('sduck-assets/');\n summary.rows.push({ path: 'sduck-assets/', status: assetsRootStatus });\n\n const workspaceRootStatus = await ensureRootDirectory(workspaceRoot, 'workspace-root-conflict');\n summary[workspaceRootStatus].push('sduck-workspace/');\n summary.rows.push({ path: 'sduck-workspace/', status: workspaceRootStatus });\n\n const actions = planInitActions(mode, await collectExistingEntries(projectRoot));\n const actionSummary = summarizeInitActions(actions);\n\n summary.created.push(...actionSummary.created);\n summary.kept.push(...actionSummary.kept);\n summary.overwritten.push(...actionSummary.overwritten);\n summary.warnings.push(...actionSummary.warnings);\n summary.errors.push(...actionSummary.errors);\n summary.rows.push(...actionSummary.rows);\n\n const conflict = actions.find((action) => action.action === 'error');\n\n if (conflict !== undefined) {\n throw new Error(\n `type-conflict: expected a file but found a directory at ${conflict.targetPath}. ` +\n 'Resolve it manually or move the conflicting path before retrying.',\n );\n }\n\n for (const action of actions) {\n if (action.action === 'keep') {\n continue;\n }\n\n const definition = ASSET_TEMPLATE_MAP[action.key];\n const sourcePath = join(\n assetSourceRoot,\n definition.relativePath.replace(/^sduck-assets[\\\\/]/, ''),\n );\n const targetPath = join(projectRoot, definition.relativePath);\n\n await ensureReadableFile(sourcePath);\n await mkdir(dirname(targetPath), { recursive: true });\n await copyFileIntoPlace(sourcePath, targetPath);\n }\n\n const agentTargets = listAgentRuleTargets(resolvedOptions.agents);\n const agentEntryKinds = new Map<string, FsEntryKind>();\n\n for (const target of agentTargets) {\n agentEntryKinds.set(\n target.outputPath,\n await getFsEntryKind(join(projectRoot, target.outputPath)),\n );\n }\n\n const existingContents = await collectExistingFileContents(projectRoot, agentTargets);\n const agentActions = planAgentRuleActions(mode, agentTargets, agentEntryKinds, existingContents);\n\n await applyAgentRuleActions(\n projectRoot,\n agentActions,\n existingContents,\n summary,\n resolvedOptions.agents,\n );\n\n return {\n mode,\n agents: resolvedOptions.agents,\n summary,\n didChange:\n summary.created.length > 0 || summary.prepended.length > 0 || summary.overwritten.length > 0,\n };\n}\n\nasync function applyAgentRuleActions(\n projectRoot: string,\n actions: readonly PlannedAgentRuleAction[],\n existingContents: Map<string, string>,\n summary: InitExecutionSummary,\n selectedAgents: SupportedAgentId[],\n): Promise<void> {\n for (const action of actions) {\n const targetPath = join(projectRoot, action.outputPath);\n const content = await renderAgentRuleContent(action, selectedAgents);\n\n if (action.mergeMode === 'create') {\n await mkdir(dirname(targetPath), { recursive: true });\n await writeFile(targetPath, content, 'utf8');\n summary.created.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'created' });\n continue;\n }\n\n if (action.mergeMode === 'keep') {\n summary.kept.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'kept' });\n summary.warnings.push(`Kept existing rule file: ${action.outputPath}`);\n continue;\n }\n\n await mkdir(dirname(targetPath), { recursive: true });\n\n if (action.mergeMode === 'prepend') {\n const currentContent = existingContents.get(action.outputPath) ?? '';\n await writeFile(targetPath, prependManagedBlock(currentContent, content.trimEnd()), 'utf8');\n summary.prepended.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'prepended' });\n continue;\n }\n\n if (action.mergeMode === 'replace-block') {\n const currentContent = existingContents.get(action.outputPath) ?? '';\n await writeFile(targetPath, replaceManagedBlock(currentContent, content.trimEnd()), 'utf8');\n summary.overwritten.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'overwritten' });\n continue;\n }\n\n await writeFile(targetPath, content, 'utf8');\n summary.overwritten.push(action.outputPath);\n summary.rows.push({ path: action.outputPath, status: 'overwritten' });\n }\n\n if (summary.kept.some((path) => path.endsWith('.md') || path.endsWith('.mdc'))) {\n summary.warnings.push(\n 'Run `sduck init --force` to refresh managed rule content for selected agents.',\n );\n }\n}\n","import { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { getFsEntryKind } from './fs.js';\n\nexport type SupportedTaskType = 'build' | 'feature' | 'fix' | 'refactor' | 'chore';\n\nexport const SUPPORTED_TASK_TYPES: readonly SupportedTaskType[] = [\n 'build',\n 'feature',\n 'fix',\n 'refactor',\n 'chore',\n];\n\nexport const EVAL_ASSET_RELATIVE_PATHS = {\n plan: join('eval', 'plan.yml'),\n spec: join('eval', 'spec.yml'),\n} as const;\n\nexport const SPEC_TEMPLATE_RELATIVE_PATHS: Record<SupportedTaskType, string> = {\n build: join('types', 'build.md'),\n feature: join('types', 'feature.md'),\n fix: join('types', 'fix.md'),\n refactor: join('types', 'refactor.md'),\n chore: join('types', 'chore.md'),\n};\n\nexport const INIT_ASSET_RELATIVE_PATHS = [\n EVAL_ASSET_RELATIVE_PATHS.spec,\n EVAL_ASSET_RELATIVE_PATHS.plan,\n ...Object.values(SPEC_TEMPLATE_RELATIVE_PATHS),\n] as const;\n\nexport async function getBundledAssetsRoot(): Promise<string> {\n const currentDirectoryPath = dirname(fileURLToPath(import.meta.url));\n const candidatePaths = [\n join(currentDirectoryPath, '..', '..', 'sduck-assets'),\n join(currentDirectoryPath, '..', 'sduck-assets'),\n ];\n\n for (const candidatePath of candidatePaths) {\n if ((await getFsEntryKind(candidatePath)) === 'directory') {\n return candidatePath;\n }\n }\n\n throw new Error('Unable to locate bundled sduck-assets directory.');\n}\n\nexport function isSupportedTaskType(value: string): value is SupportedTaskType {\n return SUPPORTED_TASK_TYPES.includes(value as SupportedTaskType);\n}\n\nexport function resolveSpecTemplateRelativePath(type: SupportedTaskType): string {\n return SPEC_TEMPLATE_RELATIVE_PATHS[type];\n}\n","import { checkbox } from '@inquirer/prompts';\n\nimport {\n approvePlans,\n createPlanApprovedAt,\n loadPlanApprovalCandidates,\n type PlanApproveCommandInput,\n type PlanApproveResult,\n type PlanApproveTarget,\n} from '../core/plan-approve.js';\n\nexport interface PlanApproveCommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nfunction padCell(value: string, width: number): string {\n return value.padEnd(width, ' ');\n}\n\nfunction buildResultTable(result: PlanApproveResult): string {\n const rows = [\n ...result.succeeded.map((row) => ({\n note: row.note,\n result: 'success',\n steps: String(row.steps),\n task: row.taskId,\n })),\n ...result.failed.map((row) => ({\n note: row.note,\n result: 'failed',\n steps: '-',\n task: row.taskId,\n })),\n ];\n\n const resultWidth = Math.max('Result'.length, ...rows.map((row) => row.result.length));\n const taskWidth = Math.max('Task'.length, ...rows.map((row) => row.task.length));\n const stepsWidth = Math.max('Steps'.length, ...rows.map((row) => row.steps.length));\n const noteWidth = Math.max('Note'.length, ...rows.map((row) => row.note.length));\n\n const border = `+-${'-'.repeat(resultWidth)}-+-${'-'.repeat(taskWidth)}-+-${'-'.repeat(stepsWidth)}-+-${'-'.repeat(noteWidth)}-+`;\n const header = `| ${padCell('Result', resultWidth)} | ${padCell('Task', taskWidth)} | ${padCell('Steps', stepsWidth)} | ${padCell('Note', noteWidth)} |`;\n const body = rows.map(\n (row) =>\n `| ${padCell(row.result, resultWidth)} | ${padCell(row.task, taskWidth)} | ${padCell(row.steps, stepsWidth)} | ${padCell(row.note, noteWidth)} |`,\n );\n\n return [border, header, border, ...body, border].join('\\n');\n}\n\nfunction formatTaskLabel(task: PlanApproveTarget): string {\n return `${task.id} (${task.status})`;\n}\n\nfunction formatSuccess(result: PlanApproveResult): string {\n const lines = [buildResultTable(result)];\n\n if (result.succeeded.length > 0) {\n lines.push('', '상태: IN_PROGRESS → 작업을 시작합니다.');\n }\n\n return lines.join('\\n');\n}\n\nasync function selectTargets(tasks: readonly PlanApproveTarget[]): Promise<PlanApproveTarget[]> {\n if (tasks.length <= 1 || !process.stdin.isTTY || !process.stdout.isTTY) {\n return [...tasks];\n }\n\n const selectedIds = await checkbox<string>({\n message: 'Select tasks to approve plan for',\n choices: tasks.map((task) => ({ checked: true, name: formatTaskLabel(task), value: task.id })),\n });\n\n return tasks.filter((task) => selectedIds.includes(task.id));\n}\n\nexport async function runPlanApproveCommand(\n input: PlanApproveCommandInput,\n projectRoot: string,\n): Promise<PlanApproveCommandResult> {\n try {\n const candidates = await loadPlanApprovalCandidates(projectRoot, input);\n\n if (candidates.length === 0) {\n throw new Error('No matching tasks awaiting plan approval.');\n }\n\n if (\n input.target !== undefined &&\n candidates.length > 1 &&\n (!process.stdin.isTTY || !process.stdout.isTTY)\n ) {\n throw new Error(\n 'Multiple matching tasks found; rerun interactively to choose approval targets.',\n );\n }\n\n const selectedTasks = await selectTargets(candidates);\n\n if (selectedTasks.length === 0) {\n throw new Error('No tasks selected for plan approval.');\n }\n\n const result = await approvePlans(projectRoot, selectedTasks, createPlanApprovedAt());\n\n if (result.succeeded.length === 0) {\n return {\n exitCode: 1,\n stderr: buildResultTable(result),\n stdout: '',\n };\n }\n\n return {\n exitCode: result.failed.length > 0 ? 1 : 0,\n stderr: result.failed.length > 0 ? '' : '',\n stdout: formatSuccess(result),\n };\n } catch (error) {\n return {\n exitCode: 1,\n stderr: error instanceof Error ? error.message : 'Unknown plan approval failure.',\n stdout: '',\n };\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getFsEntryKind } from './fs.js';\nimport { listWorkspaceTasks, type WorkspaceTaskSummary } from './workspace.js';\nimport { formatUtcTimestamp } from '../utils/utc-date.js';\n\nexport interface PlanApproveCommandInput {\n target?: string;\n}\n\nexport interface PlanApproveTarget {\n createdAt?: string;\n id: string;\n path: string;\n slug?: string;\n status: string;\n}\n\nexport interface PlanApproveSuccessRow {\n note: string;\n steps: number;\n taskId: string;\n}\n\nexport interface PlanApproveFailureRow {\n note: string;\n taskId: string;\n}\n\nexport interface PlanApproveResult {\n approvedAt: string;\n failed: PlanApproveFailureRow[];\n nextStatus: 'IN_PROGRESS';\n succeeded: PlanApproveSuccessRow[];\n}\n\nexport function filterPlanApprovalCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n): PlanApproveTarget[] {\n return tasks.filter((task) => task.status === 'SPEC_APPROVED');\n}\n\nexport function resolvePlanApprovalCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n target: string | undefined,\n): PlanApproveTarget[] {\n const candidates = filterPlanApprovalCandidates(tasks);\n\n if (target === undefined || target.trim() === '') {\n return candidates;\n }\n\n const trimmedTarget = target.trim();\n\n return candidates.filter(\n (task) =>\n task.id === trimmedTarget || task.slug === trimmedTarget || task.id.endsWith(trimmedTarget),\n );\n}\n\nexport function countPlanSteps(planContent: string): number {\n const matches = planContent.match(/^## Step \\d+\\. .+$/gm);\n return matches?.length ?? 0;\n}\n\nexport function validatePlanHasSteps(planContent: string): void {\n if (countPlanSteps(planContent) === 0) {\n throw new Error('Plan does not contain any valid `## Step N. 제목` headers.');\n }\n}\n\nfunction updatePlanApprovalBlock(\n metaContent: string,\n approvedAt: string,\n totalSteps: number,\n): string {\n const withStatus = metaContent.replace(/^status:\\s+.+$/m, 'status: IN_PROGRESS');\n const withPlan = withStatus.replace(\n /plan:\\n {2}approved:\\s+false\\n {2}approved_at:\\s+null/m,\n `plan:\\n approved: true\\n approved_at: ${approvedAt}`,\n );\n\n return withPlan.replace(\n /steps:\\n {2}total:\\s+null\\n {2}completed:\\s+\\[\\]/m,\n `steps:\\n total: ${String(totalSteps)}\\n completed: []`,\n );\n}\n\nexport async function approvePlans(\n projectRoot: string,\n tasks: readonly PlanApproveTarget[],\n approvedAt: string,\n): Promise<PlanApproveResult> {\n const succeeded: PlanApproveSuccessRow[] = [];\n const failed: PlanApproveFailureRow[] = [];\n\n for (const task of tasks) {\n if (task.status !== 'SPEC_APPROVED') {\n failed.push({\n note: `task is not awaiting plan approval (${task.status})`,\n taskId: task.id,\n });\n continue;\n }\n\n const metaPath = join(projectRoot, task.path, 'meta.yml');\n const planPath = join(projectRoot, task.path, 'plan.md');\n\n if ((await getFsEntryKind(metaPath)) !== 'file') {\n failed.push({ note: 'missing meta.yml', taskId: task.id });\n continue;\n }\n\n if ((await getFsEntryKind(planPath)) !== 'file') {\n failed.push({ note: 'missing plan.md', taskId: task.id });\n continue;\n }\n\n const planContent = await readFile(planPath, 'utf8');\n const totalSteps = countPlanSteps(planContent);\n\n if (totalSteps === 0) {\n failed.push({ note: 'missing valid Step headers', taskId: task.id });\n continue;\n }\n\n const updatedMeta = updatePlanApprovalBlock(\n await readFile(metaPath, 'utf8'),\n approvedAt,\n totalSteps,\n );\n await writeFile(metaPath, updatedMeta, 'utf8');\n\n succeeded.push({ note: 'moved to IN_PROGRESS', steps: totalSteps, taskId: task.id });\n }\n\n return {\n approvedAt,\n failed,\n nextStatus: 'IN_PROGRESS',\n succeeded,\n };\n}\n\nexport async function loadPlanApprovalCandidates(\n projectRoot: string,\n input: PlanApproveCommandInput,\n): Promise<PlanApproveTarget[]> {\n const tasks = await listWorkspaceTasks(projectRoot);\n return resolvePlanApprovalCandidates(tasks, input.target);\n}\n\nexport function createPlanApprovedAt(date = new Date()): string {\n return formatUtcTimestamp(date);\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getFsEntryKind } from './fs.js';\n\nexport interface ActiveTaskSummary {\n id: string;\n path: string;\n status: string;\n}\n\nexport interface WorkspaceTaskSummary {\n createdAt?: string;\n id: string;\n path: string;\n slug?: string;\n status: string;\n}\n\nconst ACTIVE_STATUSES = new Set(['IN_PROGRESS', 'PENDING_SPEC_APPROVAL', 'PENDING_PLAN_APPROVAL']);\n\ninterface ParsedMeta {\n createdAt?: string;\n id?: string;\n slug?: string;\n status?: string;\n}\n\nfunction parseMetaText(content: string): ParsedMeta {\n const createdAtMatch = /^created_at:\\s+(.+)$/m.exec(content);\n const idMatch = /^id:\\s+(.+)$/m.exec(content);\n const slugMatch = /^slug:\\s+(.+)$/m.exec(content);\n const statusMatch = /^status:\\s+(.+)$/m.exec(content);\n const parsedMeta: ParsedMeta = {};\n\n if (createdAtMatch?.[1] !== undefined) {\n parsedMeta.createdAt = createdAtMatch[1].trim();\n }\n\n if (idMatch?.[1] !== undefined) {\n parsedMeta.id = idMatch[1].trim();\n }\n\n if (slugMatch?.[1] !== undefined) {\n parsedMeta.slug = slugMatch[1].trim();\n }\n\n if (statusMatch?.[1] !== undefined) {\n parsedMeta.status = statusMatch[1].trim();\n }\n\n return parsedMeta;\n}\n\nexport function sortTasksByRecency(tasks: readonly WorkspaceTaskSummary[]): WorkspaceTaskSummary[] {\n return [...tasks].sort((left, right) => {\n const leftValue = left.createdAt ?? '';\n const rightValue = right.createdAt ?? '';\n\n return rightValue.localeCompare(leftValue);\n });\n}\n\nexport async function listWorkspaceTasks(projectRoot: string): Promise<WorkspaceTaskSummary[]> {\n const workspaceRoot = join(projectRoot, 'sduck-workspace');\n\n if ((await getFsEntryKind(workspaceRoot)) !== 'directory') {\n return [];\n }\n\n const { readdir } = await import('node:fs/promises');\n const entries = await readdir(workspaceRoot, { withFileTypes: true });\n const tasks: WorkspaceTaskSummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n const relativePath = join('sduck-workspace', entry.name);\n const metaPath = join(projectRoot, relativePath, 'meta.yml');\n\n if ((await getFsEntryKind(metaPath)) !== 'file') {\n continue;\n }\n\n const parsedMeta = parseMetaText(await readFile(metaPath, 'utf8'));\n\n if (parsedMeta.id !== undefined && parsedMeta.status !== undefined) {\n const task: WorkspaceTaskSummary = {\n id: parsedMeta.id,\n path: relativePath,\n status: parsedMeta.status,\n };\n\n if (parsedMeta.createdAt !== undefined) {\n task.createdAt = parsedMeta.createdAt;\n }\n\n if (parsedMeta.slug !== undefined) {\n task.slug = parsedMeta.slug;\n }\n\n tasks.push(task);\n }\n }\n\n return sortTasksByRecency(tasks);\n}\n\nexport async function findActiveTask(projectRoot: string): Promise<ActiveTaskSummary | null> {\n const tasks = await listWorkspaceTasks(projectRoot);\n\n for (const task of tasks) {\n if (ACTIVE_STATUSES.has(task.status)) {\n return {\n id: task.id,\n path: task.path,\n status: task.status,\n };\n }\n }\n\n return null;\n}\n","function pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport function formatUtcDate(date: Date): string {\n const year = String(date.getUTCFullYear());\n const month = pad2(date.getUTCMonth() + 1);\n const day = pad2(date.getUTCDate());\n\n return `${year}-${month}-${day}`;\n}\n\nexport function formatUtcTimestamp(date: Date): string {\n const year = String(date.getUTCFullYear());\n const month = pad2(date.getUTCMonth() + 1);\n const day = pad2(date.getUTCDate());\n const hour = pad2(date.getUTCHours());\n const minute = pad2(date.getUTCMinutes());\n const second = pad2(date.getUTCSeconds());\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}Z`;\n}\n","import { checkbox } from '@inquirer/prompts';\n\nimport {\n approveSpecs,\n createSpecApprovedAt,\n loadSpecApprovalCandidates,\n type SpecApproveCommandInput,\n type SpecApproveResult,\n type SpecApproveTarget,\n} from '../core/spec-approve.js';\n\nexport interface SpecApproveCommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nfunction formatTaskLabel(task: SpecApproveTarget): string {\n return `${task.id} (${task.status})`;\n}\n\nfunction formatSuccess(result: SpecApproveResult, tasks: readonly SpecApproveTarget[]): string {\n const lines = ['스펙 승인됨'];\n\n for (const task of tasks) {\n lines.push(`- ${task.path} -> ${result.nextStatus}`);\n }\n\n lines.push('상태: SPEC_APPROVED → 플랜 작성을 시작합니다.');\n\n return lines.join('\\n');\n}\n\nasync function selectTargets(tasks: readonly SpecApproveTarget[]): Promise<SpecApproveTarget[]> {\n if (tasks.length <= 1 || !process.stdin.isTTY || !process.stdout.isTTY) {\n return [...tasks];\n }\n\n const selectedIds = await checkbox<string>({\n message: 'Select tasks to approve',\n choices: tasks.map((task) => ({\n checked: true,\n name: formatTaskLabel(task),\n value: task.id,\n })),\n });\n\n return tasks.filter((task) => selectedIds.includes(task.id));\n}\n\nexport async function runSpecApproveCommand(\n input: SpecApproveCommandInput,\n projectRoot: string,\n): Promise<SpecApproveCommandResult> {\n try {\n const candidates = await loadSpecApprovalCandidates(projectRoot, input);\n\n if (candidates.length === 0) {\n throw new Error('No matching tasks awaiting spec approval.');\n }\n\n if (\n input.target !== undefined &&\n candidates.length > 1 &&\n (!process.stdin.isTTY || !process.stdout.isTTY)\n ) {\n throw new Error(\n 'Multiple matching tasks found; rerun interactively to choose approval targets.',\n );\n }\n\n const selectedTasks = await selectTargets(candidates);\n\n if (selectedTasks.length === 0) {\n throw new Error('No tasks selected for spec approval.');\n }\n\n const result = await approveSpecs(projectRoot, selectedTasks, createSpecApprovedAt());\n\n return {\n exitCode: 0,\n stderr: '',\n stdout: formatSuccess(result, selectedTasks),\n };\n } catch (error) {\n return {\n exitCode: 1,\n stderr: error instanceof Error ? error.message : 'Unknown spec approval failure.',\n stdout: '',\n };\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { getFsEntryKind } from './fs.js';\nimport { listWorkspaceTasks, type WorkspaceTaskSummary } from './workspace.js';\nimport { formatUtcTimestamp } from '../utils/utc-date.js';\n\nexport interface SpecApproveCommandInput {\n target?: string;\n}\n\nexport interface SpecApproveTarget {\n createdAt?: string;\n id: string;\n path: string;\n slug?: string;\n status: string;\n}\n\nexport interface SpecApproveResult {\n approvedAt: string;\n approvedTaskIds: string[];\n nextStatus: 'SPEC_APPROVED';\n}\n\nexport function filterApprovalCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n): SpecApproveTarget[] {\n return tasks.filter((task) => task.status === 'PENDING_SPEC_APPROVAL');\n}\n\nexport function resolveTargetCandidates(\n tasks: readonly WorkspaceTaskSummary[],\n target: string | undefined,\n): SpecApproveTarget[] {\n const candidates = filterApprovalCandidates(tasks);\n\n if (target === undefined || target.trim() === '') {\n return candidates;\n }\n\n const trimmedTarget = target.trim();\n\n return candidates.filter(\n (task) =>\n task.id === trimmedTarget || task.slug === trimmedTarget || task.id.endsWith(trimmedTarget),\n );\n}\n\nexport function validateSpecApprovalTargets(tasks: readonly SpecApproveTarget[]): void {\n if (tasks.length === 0) {\n throw new Error('No approvable spec tasks found.');\n }\n\n const invalidTask = tasks.find((task) => task.status !== 'PENDING_SPEC_APPROVAL');\n\n if (invalidTask !== undefined) {\n throw new Error(\n `Task ${invalidTask.id} is not awaiting spec approval (${invalidTask.status}).`,\n );\n }\n}\n\nfunction updateSpecApprovalBlock(metaContent: string, approvedAt: string): string {\n const withStatus = metaContent.replace(/^status:\\s+.+$/m, 'status: SPEC_APPROVED');\n\n return withStatus.replace(\n /spec:\\n {2}approved:\\s+false\\n {2}approved_at:\\s+null/m,\n `spec:\\n approved: true\\n approved_at: ${approvedAt}`,\n );\n}\n\nexport async function approveSpecs(\n projectRoot: string,\n tasks: readonly SpecApproveTarget[],\n approvedAt: string,\n): Promise<SpecApproveResult> {\n validateSpecApprovalTargets(tasks);\n\n for (const task of tasks) {\n const metaPath = join(projectRoot, task.path, 'meta.yml');\n\n if ((await getFsEntryKind(metaPath)) !== 'file') {\n throw new Error(`Missing meta.yml for task ${task.id}.`);\n }\n\n const updatedContent = updateSpecApprovalBlock(await readFile(metaPath, 'utf8'), approvedAt);\n await writeFile(metaPath, updatedContent, 'utf8');\n }\n\n return {\n approvedAt,\n approvedTaskIds: tasks.map((task) => task.id),\n nextStatus: 'SPEC_APPROVED',\n };\n}\n\nexport async function loadSpecApprovalCandidates(\n projectRoot: string,\n input: SpecApproveCommandInput,\n): Promise<SpecApproveTarget[]> {\n const tasks = await listWorkspaceTasks(projectRoot);\n return resolveTargetCandidates(tasks, input.target);\n}\n\nexport function createSpecApprovedAt(date = new Date()): string {\n return formatUtcTimestamp(date);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport {\n getBundledAssetsRoot,\n isSupportedTaskType,\n resolveSpecTemplateRelativePath,\n type SupportedTaskType,\n} from './assets.js';\nimport { getFsEntryKind } from './fs.js';\nimport { findActiveTask, type ActiveTaskSummary } from './workspace.js';\nimport { formatUtcDate, formatUtcTimestamp } from '../utils/utc-date.js';\n\nexport interface StartCommandInput {\n type: SupportedTaskType;\n slug: string;\n}\n\nexport interface StartExecutionResult {\n workspaceId: string;\n workspacePath: string;\n status: 'PENDING_SPEC_APPROVAL';\n}\n\nexport function normalizeSlug(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[_\\s]+/g, '-')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\nexport function validateSlug(slug: string): void {\n if (slug === '') {\n throw new Error('Invalid slug: slug cannot be empty after normalization.');\n }\n\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)) {\n throw new Error('Invalid slug: use lowercase kebab-case only.');\n }\n}\n\nexport function createWorkspaceId(date: Date, type: SupportedTaskType, slug: string): string {\n const year = String(date.getUTCFullYear());\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const day = String(date.getUTCDate()).padStart(2, '0');\n const hour = String(date.getUTCHours()).padStart(2, '0');\n const minute = String(date.getUTCMinutes()).padStart(2, '0');\n\n return `${year}${month}${day}-${hour}${minute}-${type}-${slug}`;\n}\n\nexport function renderInitialMeta(input: {\n createdAt: string;\n id: string;\n slug: string;\n type: SupportedTaskType;\n}): string {\n return [\n `id: ${input.id}`,\n `type: ${input.type}`,\n `slug: ${input.slug}`,\n `created_at: ${input.createdAt}`,\n '',\n 'status: PENDING_SPEC_APPROVAL',\n '',\n 'spec:',\n ' approved: false',\n ' approved_at: null',\n '',\n 'plan:',\n ' approved: false',\n ' approved_at: null',\n '',\n 'steps:',\n ' total: null',\n ' completed: []',\n '',\n 'completed_at: null',\n '',\n ].join('\\n');\n}\n\nexport async function resolveSpecTemplatePath(type: SupportedTaskType): Promise<string> {\n const assetsRoot = await getBundledAssetsRoot();\n return join(assetsRoot, resolveSpecTemplateRelativePath(type));\n}\n\nfunction applyTemplateDefaults(\n template: string,\n type: SupportedTaskType,\n slug: string,\n currentDate: Date,\n): string {\n const displayName = slug.replace(/-/g, ' ');\n\n return template\n .replace(/\\{기능명\\}/g, displayName)\n .replace(/\\{버그 요약 한 줄\\}/g, displayName)\n .replace(/YYYY-MM-DD/g, formatUtcDate(currentDate))\n .replace(/> \\*\\*작성자:\\*\\*\\s*$/m, '> **작성자:** taehee')\n .replace(/> \\*\\*연관 티켓:\\*\\*\\s*$/m, '> **연관 티켓:** -')\n .replace(/^# \\[(feature|fix|refactor|chore|build)\\] .*/m, `# [${type}] ${displayName}`);\n}\n\nexport async function startTask(\n rawType: string,\n rawSlug: string,\n projectRoot: string,\n currentDate = new Date(),\n): Promise<StartExecutionResult> {\n if (!isSupportedTaskType(rawType)) {\n throw new Error(`Unsupported type: ${rawType}`);\n }\n\n const slug = normalizeSlug(rawSlug);\n validateSlug(slug);\n\n const activeTask = await findActiveTask(projectRoot);\n\n if (activeTask !== null) {\n throw new Error(\n `Active task exists: ${activeTask.id} (${activeTask.status}) at ${activeTask.path}. Finish or approve it before starting a new task.`,\n );\n }\n\n const workspaceId = createWorkspaceId(currentDate, rawType, slug);\n const workspacePath = join('sduck-workspace', workspaceId);\n const absoluteWorkspacePath = join(projectRoot, workspacePath);\n\n if ((await getFsEntryKind(absoluteWorkspacePath)) !== 'missing') {\n throw new Error(`Workspace already exists: ${workspacePath}`);\n }\n\n const workspaceRoot = join(projectRoot, 'sduck-workspace');\n await mkdir(workspaceRoot, { recursive: true });\n await mkdir(absoluteWorkspacePath, { recursive: false });\n\n const templatePath = await resolveSpecTemplatePath(rawType);\n if ((await getFsEntryKind(templatePath)) !== 'file') {\n throw new Error(`Missing spec template for type '${rawType}' at ${templatePath}`);\n }\n\n const specTemplate = await readFile(templatePath, 'utf8');\n const specContent = applyTemplateDefaults(specTemplate, rawType, slug, currentDate);\n const metaContent = renderInitialMeta({\n createdAt: formatUtcTimestamp(currentDate),\n id: workspaceId,\n slug,\n type: rawType,\n });\n\n await writeFile(join(absoluteWorkspacePath, 'meta.yml'), metaContent, 'utf8');\n await writeFile(join(absoluteWorkspacePath, 'spec.md'), specContent, 'utf8');\n await writeFile(join(absoluteWorkspacePath, 'plan.md'), '', 'utf8');\n\n return {\n workspaceId,\n workspacePath,\n status: 'PENDING_SPEC_APPROVAL',\n };\n}\n\nexport type { ActiveTaskSummary };\n","import { startTask } from '../core/start.js';\n\nexport interface StartCommandResult {\n exitCode: number;\n stderr: string;\n stdout: string;\n}\n\nexport async function runStartCommand(\n type: string,\n slug: string,\n projectRoot: string,\n): Promise<StartCommandResult> {\n try {\n const result = await startTask(type, slug, projectRoot);\n\n return {\n exitCode: 0,\n stderr: '',\n stdout: [\n '작업 디렉토리 생성됨',\n `경로: ${result.workspacePath}/`,\n `상태: ${result.status}`,\n ].join('\\n'),\n };\n } catch (error) {\n return {\n exitCode: 1,\n stderr: error instanceof Error ? error.message : 'Unknown start failure.',\n stdout: '',\n };\n }\n}\n","export const CLI_NAME = 'sduck';\n\nexport const CLI_DESCRIPTION = 'Spec-Driven Development workflow bootstrap CLI';\n\nexport const PLACEHOLDER_MESSAGE =\n 'Core workflow commands are planned but not implemented in this bootstrap yet.';\n\nexport function normalizeCommandName(input: string): string {\n return input.trim().toLowerCase().replace(/\\s+/g, '-');\n}\n"],"mappings":"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","names":["mkdir","readFile","dirname","join","dirname","join","fileURLToPath","join","dirname","fileURLToPath","join","readFile","mkdir","dirname","checkbox","readFile","writeFile","join","readFile","join","join","readFile","join","readFile","writeFile","padCell","checkbox","checkbox","readFile","writeFile","join","join","readFile","writeFile","formatTaskLabel","formatSuccess","selectTargets","checkbox","mkdir","readFile","writeFile","join","join","mkdir","readFile","writeFile"]}
|
package/package.json
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
## Codex Instructions
|
|
2
2
|
|
|
3
3
|
- Follow the repository SDD workflow exactly.
|
|
4
|
-
- Use `
|
|
4
|
+
- Use `AGENT.md` as project-level instruction context.
|
|
5
|
+
- Use the shipped CLI commands `sduck init`, `sduck start <type> <slug>`, `sduck spec approve [target]`, and `sduck plan approve [target]`.
|
|
6
|
+
- Keep plans highly detailed: list exact file paths, likely functions or sections to edit, concrete change intent, and verification commands.
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# SDD Workflow Rules
|
|
2
2
|
|
|
3
|
+
- Use the shipped CLI commands for workflow operations: `sduck init`, `sduck start <type> <slug>`, `sduck spec approve [target]`, and `sduck plan approve [target]`.
|
|
3
4
|
- Start each session by checking `sduck-workspace/` and any active task `meta.yml`.
|
|
4
5
|
- Do not write implementation code before spec approval.
|
|
5
6
|
- Do not start implementation before plan approval.
|
|
6
7
|
- Follow the workflow order: `spec -> approval -> plan -> approval -> implementation`.
|
|
7
8
|
- Respect `meta.yml` state transitions and update step completion immediately.
|
|
8
9
|
- Read and apply user memo text appended with `<-` in `spec.md` and `plan.md`.
|
|
10
|
+
- Write `plan.md` in detailed implementation units: include target files, the functions/sections or rough line ranges to inspect, the exact change intent for each file, and the tests or commands to verify the step.
|
|
9
11
|
- Use `sduck-assets/eval/spec.yml`, `sduck-assets/eval/plan.yml`, and `sduck-assets/eval/task.yml` when evaluating spec, plan, and completed task quality.
|
|
10
12
|
- After implementation is complete, run task evaluation, show the results, and only then move to `task done` or final completion processing.
|
|
11
13
|
- Do not mark a task `DONE` until all completion criteria are satisfied.
|
|
@@ -2,3 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
- Follow the repository SDD workflow exactly.
|
|
4
4
|
- Use `GEMINI.md` as project-level instruction context.
|
|
5
|
+
- Use the shipped CLI commands `sduck init`, `sduck start <type> <slug>`, `sduck spec approve [target]`, and `sduck plan approve [target]`.
|
|
6
|
+
- Keep plans highly detailed: list exact file paths, likely functions or sections to edit, concrete change intent, and verification commands.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
## OpenCode Instructions
|
|
2
2
|
|
|
3
3
|
- Follow the repository SDD workflow exactly.
|
|
4
|
-
- Use `
|
|
4
|
+
- Use `AGENT.md` as project-level instruction context.
|
|
5
|
+
- Use the shipped CLI commands `sduck init`, `sduck start <type> <slug>`, `sduck spec approve [target]`, and `sduck plan approve [target]`.
|
|
6
|
+
- Keep plans highly detailed: list exact file paths, likely functions or sections to edit, concrete change intent, and verification commands.
|