oh-my-design-cli 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +3 -2
- package/README.md +3 -2
- package/dist/bin/oh-my-design.js +5 -5
- package/dist/bin/oh-my-design.js.map +1 -1
- package/dist/{init-STACB7E5.js → init-UMM4XIV5.js} +42 -2
- package/dist/init-UMM4XIV5.js.map +1 -0
- package/dist/{sync-P7X4S2DK.js → sync-FDYRKNFE.js} +16 -3
- package/dist/sync-FDYRKNFE.js.map +1 -0
- package/package.json +3 -3
- package/dist/init-STACB7E5.js.map +0 -1
- package/dist/sync-P7X4S2DK.js.map +0 -1
- package/references/Claude-Design-Sys-Prompt.txt +0 -421
- package/references/airbnb/README.md +0 -23
- package/references/airbnb/preview-dark.html +0 -234
- package/references/airbnb/preview.html +0 -233
- package/references/airtable/README.md +0 -23
- package/references/airtable/preview-dark.html +0 -165
- package/references/airtable/preview.html +0 -164
- package/references/apple/README.md +0 -24
- package/references/apple/preview-dark.html +0 -420
- package/references/apple/preview.html +0 -414
- package/references/baemin/README.md +0 -19
- package/references/bmw/README.md +0 -23
- package/references/bmw/preview-dark.html +0 -211
- package/references/bmw/preview.html +0 -210
- package/references/cal/README.md +0 -23
- package/references/cal/preview-dark.html +0 -449
- package/references/cal/preview.html +0 -575
- package/references/claude/README.md +0 -24
- package/references/claude/preview-dark.html +0 -803
- package/references/claude/preview.html +0 -826
- package/references/clay/README.md +0 -23
- package/references/clay/preview-dark.html +0 -316
- package/references/clay/preview.html +0 -315
- package/references/clickhouse/README.md +0 -24
- package/references/clickhouse/preview-dark.html +0 -834
- package/references/clickhouse/preview.html +0 -786
- package/references/cohere/README.md +0 -24
- package/references/cohere/preview-dark.html +0 -803
- package/references/cohere/preview.html +0 -807
- package/references/coinbase/README.md +0 -23
- package/references/coinbase/preview-dark.html +0 -164
- package/references/coinbase/preview.html +0 -163
- package/references/composio/README.md +0 -24
- package/references/composio/preview-dark.html +0 -958
- package/references/composio/preview.html +0 -933
- package/references/cursor/README.md +0 -24
- package/references/cursor/preview-dark.html +0 -393
- package/references/cursor/preview.html +0 -383
- package/references/dcard/README.md +0 -12
- package/references/dcard/_research/forum-1440px.png +0 -0
- package/references/dcard/_research.md +0 -77
- package/references/elevenlabs/README.md +0 -23
- package/references/elevenlabs/preview-dark.html +0 -252
- package/references/elevenlabs/preview.html +0 -251
- package/references/expo/README.md +0 -24
- package/references/expo/preview-dark.html +0 -533
- package/references/expo/preview.html +0 -533
- package/references/ferrari/README.md +0 -23
- package/references/ferrari/preview-dark.html +0 -1162
- package/references/ferrari/preview.html +0 -1122
- package/references/figma/README.md +0 -24
- package/references/figma/preview-dark.html +0 -822
- package/references/figma/preview.html +0 -832
- package/references/framer/README.md +0 -23
- package/references/framer/preview-dark.html +0 -902
- package/references/framer/preview.html +0 -883
- package/references/freee/README.md +0 -12
- package/references/freee/_research/vibes-storybook-1440px.png +0 -0
- package/references/freee/_research.md +0 -77
- package/references/hashicorp/README.md +0 -24
- package/references/hashicorp/preview-dark.html +0 -1202
- package/references/hashicorp/preview.html +0 -1193
- package/references/ibm/README.md +0 -24
- package/references/ibm/preview-dark.html +0 -443
- package/references/ibm/preview.html +0 -428
- package/references/intercom/README.md +0 -23
- package/references/intercom/preview-dark.html +0 -185
- package/references/intercom/preview.html +0 -184
- package/references/kakao/README.md +0 -18
- package/references/karrot/README.md +0 -18
- package/references/kraken/README.md +0 -23
- package/references/kraken/preview-dark.html +0 -169
- package/references/kraken/preview.html +0 -168
- package/references/lamborghini/README.md +0 -23
- package/references/lamborghini/preview-dark.html +0 -303
- package/references/lamborghini/preview.html +0 -381
- package/references/line/README.md +0 -12
- package/references/line/_research/home-1440px.png +0 -0
- package/references/line/_research.md +0 -65
- package/references/linear.app/README.md +0 -24
- package/references/linear.app/preview-dark.html +0 -383
- package/references/linear.app/preview.html +0 -373
- package/references/lovable/README.md +0 -24
- package/references/lovable/preview-dark.html +0 -349
- package/references/lovable/preview.html +0 -348
- package/references/mercari/README.md +0 -12
- package/references/mercari/_research/home-1440px.png +0 -0
- package/references/mercari/_research.md +0 -77
- package/references/minimax/README.md +0 -24
- package/references/minimax/preview-dark.html +0 -1262
- package/references/minimax/preview.html +0 -1248
- package/references/mintlify/README.md +0 -24
- package/references/mintlify/preview-dark.html +0 -409
- package/references/mintlify/preview.html +0 -398
- package/references/miro/README.md +0 -23
- package/references/miro/preview-dark.html +0 -174
- package/references/miro/preview.html +0 -173
- package/references/mistral.ai/README.md +0 -24
- package/references/mistral.ai/preview-dark.html +0 -806
- package/references/mistral.ai/preview.html +0 -805
- package/references/mongodb/README.md +0 -23
- package/references/mongodb/preview-dark.html +0 -260
- package/references/mongodb/preview.html +0 -259
- package/references/notion/README.md +0 -24
- package/references/notion/preview-dark.html +0 -372
- package/references/notion/preview.html +0 -364
- package/references/nvidia/README.md +0 -24
- package/references/nvidia/preview-dark.html +0 -374
- package/references/nvidia/preview.html +0 -366
- package/references/ollama/README.md +0 -24
- package/references/ollama/preview-dark.html +0 -678
- package/references/ollama/preview.html +0 -678
- package/references/opencode.ai/README.md +0 -24
- package/references/opencode.ai/preview-dark.html +0 -366
- package/references/opencode.ai/preview.html +0 -357
- package/references/pinkoi/README.md +0 -12
- package/references/pinkoi/_research/browse-1440px.png +0 -0
- package/references/pinkoi/_research.md +0 -115
- package/references/pinterest/README.md +0 -23
- package/references/pinterest/preview-dark.html +0 -233
- package/references/pinterest/preview.html +0 -232
- package/references/posthog/README.md +0 -23
- package/references/posthog/preview-dark.html +0 -699
- package/references/posthog/preview.html +0 -749
- package/references/raycast/README.md +0 -23
- package/references/raycast/preview-dark.html +0 -606
- package/references/raycast/preview.html +0 -688
- package/references/renault/README.md +0 -23
- package/references/renault/preview-dark.html +0 -406
- package/references/renault/preview.html +0 -606
- package/references/replicate/README.md +0 -24
- package/references/replicate/preview-dark.html +0 -828
- package/references/replicate/preview.html +0 -831
- package/references/resend/README.md +0 -23
- package/references/resend/preview-dark.html +0 -355
- package/references/resend/preview.html +0 -354
- package/references/revolut/README.md +0 -23
- package/references/revolut/preview-dark.html +0 -234
- package/references/revolut/preview.html +0 -233
- package/references/runwayml/README.md +0 -24
- package/references/runwayml/preview-dark.html +0 -664
- package/references/runwayml/preview.html +0 -665
- package/references/sanity/README.md +0 -24
- package/references/sanity/preview-dark.html +0 -990
- package/references/sanity/preview.html +0 -1135
- package/references/sentry/README.md +0 -24
- package/references/sentry/preview-dark.html +0 -626
- package/references/sentry/preview.html +0 -951
- package/references/spacex/README.md +0 -23
- package/references/spacex/preview-dark.html +0 -221
- package/references/spacex/preview.html +0 -220
- package/references/spotify/README.md +0 -23
- package/references/spotify/preview-dark.html +0 -231
- package/references/spotify/preview.html +0 -230
- package/references/stripe/README.md +0 -24
- package/references/stripe/preview-dark.html +0 -428
- package/references/stripe/preview.html +0 -419
- package/references/supabase/README.md +0 -24
- package/references/supabase/preview-dark.html +0 -977
- package/references/supabase/preview.html +0 -955
- package/references/superhuman/README.md +0 -23
- package/references/superhuman/preview-dark.html +0 -973
- package/references/superhuman/preview.html +0 -951
- package/references/tesla/README.md +0 -23
- package/references/tesla/preview-dark.html +0 -947
- package/references/tesla/preview.html +0 -925
- package/references/together.ai/README.md +0 -24
- package/references/together.ai/preview-dark.html +0 -892
- package/references/together.ai/preview.html +0 -897
- package/references/toss/README.md +0 -19
- package/references/uber/README.md +0 -24
- package/references/uber/preview-dark.html +0 -1120
- package/references/uber/preview.html +0 -1119
- package/references/vercel/README.md +0 -24
- package/references/vercel/preview-dark.html +0 -368
- package/references/vercel/preview.html +0 -367
- package/references/voltagent/README.md +0 -24
- package/references/voltagent/preview-dark.html +0 -487
- package/references/voltagent/preview.html +0 -766
- package/references/warp/README.md +0 -23
- package/references/warp/preview-dark.html +0 -500
- package/references/warp/preview.html +0 -533
- package/references/webflow/README.md +0 -23
- package/references/webflow/preview-dark.html +0 -147
- package/references/webflow/preview.html +0 -146
- package/references/wise/README.md +0 -23
- package/references/wise/preview-dark.html +0 -230
- package/references/wise/preview.html +0 -229
- package/references/x.ai/README.md +0 -24
- package/references/x.ai/preview-dark.html +0 -356
- package/references/x.ai/preview.html +0 -407
- package/references/zapier/README.md +0 -24
- package/references/zapier/preview-dark.html +0 -380
- package/references/zapier/preview.html +0 -372
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/sync.ts","../src/core/shims.ts","../src/core/sync-lock.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { existsSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport {\n ALL_SHIMS,\n inspectShim,\n writeShim,\n refreshDesignMdHash,\n type Shim,\n type InspectResult,\n type WriteShimResult,\n} from '../core/shims.js';\n\nconst DESIGN_MD_NAME = 'DESIGN.md';\nconst DEPRECATED_MD_NAME = 'DESIGN_DEPRECATED.md';\nconst INIT_CONTEXT_PATH = '.omd/init-context.json';\n\nexport interface SyncOptions {\n dir?: string;\n force?: boolean;\n check?: boolean;\n}\n\nconst STATUS_LABEL: Record<InspectResult['status'], string> = {\n missing: pc.yellow('missing'),\n clean: pc.green('clean'),\n drifted: pc.red('drifted'),\n 'out-of-date': pc.cyan('out-of-date'),\n};\n\nconst WRITE_LABEL: Record<WriteShimResult['status'], string> = {\n created: pc.green('created'),\n updated: pc.cyan('updated'),\n unchanged: pc.dim('unchanged'),\n 'skipped-drift': pc.yellow('skipped'),\n};\n\nfunction printDiff(label: string, current: string, proposed: string): void {\n p.log.message(pc.bold('─── current (' + label + ') ───'));\n p.log.message(current || pc.dim('(empty)'));\n p.log.message(pc.bold('─── proposed ───'));\n p.log.message(proposed);\n}\n\ntype DriftChoice = 'overwrite' | 'skip' | 'show' | 'quit';\n\nasync function promptDrift(shim: Shim, inspection: InspectResult): Promise<DriftChoice> {\n while (true) {\n const choice = await p.select<DriftChoice>({\n message: `${pc.bold(shim.relPath)} has drift — choose:`,\n options: [\n { value: 'overwrite', label: 'Overwrite with rendered content' },\n { value: 'skip', label: 'Skip (keep user edits)' },\n { value: 'show', label: 'Show diff' },\n { value: 'quit', label: 'Quit sync' },\n ],\n });\n\n if (p.isCancel(choice)) return 'quit';\n if (choice !== 'show') return choice;\n\n printDiff(\n shim.relPath,\n inspection.existing ?? '',\n inspection.rendered\n );\n }\n}\n\nexport async function runSync(opts: SyncOptions = {}): Promise<number> {\n const projectRoot = opts.dir ?? process.cwd();\n const relRoot = relative(process.cwd(), projectRoot) || '.';\n\n p.intro(pc.bold('omd sync') + pc.dim(` (${relRoot})`));\n\n const inspections = ALL_SHIMS.map((shim) => ({\n shim,\n result: inspectShim(projectRoot, shim),\n }));\n\n p.log.message(pc.bold('Status:'));\n for (const { result } of inspections) {\n const rel = relative(projectRoot, result.path);\n p.log.message(` ${STATUS_LABEL[result.status]} ${rel}`);\n }\n\n // Mid-flow detection: shims may be clean while DESIGN.md is mid-init\n // (after `omd init prepare` renamed the old one but before the agent\n // wrote the new one). Surface this as a soft warning so users don't\n // mistake \"All clean\" for \"fully done\".\n const designMdMissing = !existsSync(join(projectRoot, DESIGN_MD_NAME));\n const initContextExists = existsSync(join(projectRoot, INIT_CONTEXT_PATH));\n const deprecatedExists = existsSync(join(projectRoot, DEPRECATED_MD_NAME));\n const midInitFlow =\n designMdMissing && (initContextExists || deprecatedExists);\n\n if (opts.check) {\n const unsynced = inspections.filter(\n (i) => i.result.status !== 'clean'\n );\n if (unsynced.length > 0) {\n p.outro(\n pc.red(\n `${unsynced.length} not in sync — rerun without --check to resolve.`\n )\n );\n return 1;\n }\n if (designMdMissing) {\n p.log.warn(\n midInitFlow\n ? 'DESIGN.md is missing but init-context is staged — your agent still needs to run the `omd:init` skill to write DESIGN.md.'\n : 'DESIGN.md is missing — run `npx oh-my-design-cli init recommend \"<description>\"` to bootstrap, or have your agent run the `omd:init` skill.'\n );\n }\n p.outro(pc.green('Shims clean.'));\n return 0;\n }\n\n const results: WriteShimResult[] = [];\n\n for (const { shim, result } of inspections) {\n if (result.status === 'clean') {\n results.push({\n id: shim.id,\n path: result.path,\n hash: '',\n status: 'unchanged',\n });\n continue;\n }\n\n if (result.status === 'drifted' && !opts.force) {\n const choice = await promptDrift(shim, result);\n if (choice === 'quit') {\n p.outro(pc.yellow('Aborted by user.'));\n return 1;\n }\n if (choice === 'skip') {\n results.push(\n writeShim(projectRoot, shim, { onDrift: 'skip' })\n );\n continue;\n }\n // overwrite\n results.push(\n writeShim(projectRoot, shim, { onDrift: 'overwrite' })\n );\n continue;\n }\n\n // missing / out-of-date / (drifted with --force)\n const onDrift = opts.force ? 'overwrite' : 'error';\n results.push(writeShim(projectRoot, shim, { onDrift }));\n }\n\n refreshDesignMdHash(projectRoot);\n\n p.log.message(pc.bold('\\nResults:'));\n for (const r of results) {\n const rel = relative(projectRoot, r.path);\n p.log.message(` ${WRITE_LABEL[r.status]} ${rel}`);\n }\n\n const drifted = results.filter((r) => r.status === 'skipped-drift').length;\n const changed = results.filter(\n (r) => r.status === 'created' || r.status === 'updated'\n ).length;\n\n p.outro(\n drifted > 0\n ? pc.yellow(`${changed} written, ${drifted} skipped (drift).`)\n : pc.green(`${changed} written.`)\n );\n\n return 0;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport {\n parseBlock,\n writeBlock,\n hashContent,\n hasDrift,\n} from './sync-marker.js';\nimport { updateTarget, updateDesignMdHash } from './sync-lock.js';\n\nexport const MANAGED_BLOCK_VERSION = 1;\n\nexport type ShimId = 'claude' | 'agents' | 'cursor';\n\nexport type ShimMode = 'block' | 'whole';\n\nexport interface Shim {\n id: ShimId;\n relPath: string;\n mode: ShimMode;\n render(): string;\n}\n\nconst CLAUDE_BODY = `# Design System (oh-my-design)\n\nThe authoritative brand & UI spec is **@./DESIGN.md**.\nRead before any UI/styling/microcopy/motion work.\n\nPreference log (pending corrections): @./.omd/preferences.md\n\nPrecedence: DESIGN.md > preferences.md > your defaults.`;\n\nconst AGENTS_BODY = `## Design System (oh-my-design)\n\n**Before any UI, styling, copy, or motion change, open and read \\`./DESIGN.md\\` in full.** It is the authoritative brand/design spec. Treat its tokens, voice, and component rules as binding unless the user overrides in chat.\n\nIf present, read \\`./.omd/preferences.md\\` — pending corrections not yet folded into DESIGN.md. Apply them; flag conflicts.`;\n\nconst CURSOR_FRONTMATTER = `---\ndescription: Authoritative brand & UI design system. Read DESIGN.md before UI work.\nglobs:\n - \"**/*.tsx\"\n - \"**/*.jsx\"\n - \"**/*.vue\"\n - \"**/*.svelte\"\n - \"**/*.css\"\n - \"**/*.scss\"\n - \"**/tailwind.config.*\"\n - \"**/components/**\"\n - \"**/app/**/page.*\"\nalwaysApply: false\n---`;\n\nconst CURSOR_BODY = `The authoritative design spec lives at \\`@DESIGN.md\\` (repo root). Open and read before generating/modifying UI.\n\nPending preference corrections: \\`@.omd/preferences.md\\`.\n\nPrecedence: DESIGN.md > preferences.md > framework defaults.`;\n\nexport const CLAUDE_SHIM: Shim = {\n id: 'claude',\n relPath: 'CLAUDE.md',\n mode: 'block',\n render: () => CLAUDE_BODY,\n};\n\nexport const AGENTS_SHIM: Shim = {\n id: 'agents',\n relPath: 'AGENTS.md',\n mode: 'block',\n render: () => AGENTS_BODY,\n};\n\nexport const CURSOR_SHIM: Shim = {\n id: 'cursor',\n relPath: '.cursor/rules/omd-design.mdc',\n mode: 'whole',\n render: () => {\n const hash = hashContent(CURSOR_BODY);\n return `${CURSOR_FRONTMATTER}\\n\\n<!-- omd:start v=${MANAGED_BLOCK_VERSION} hash=${hash} -->\\n${CURSOR_BODY}\\n<!-- omd:end -->\\n`;\n },\n};\n\nexport const ALL_SHIMS: readonly Shim[] = [\n CLAUDE_SHIM,\n AGENTS_SHIM,\n CURSOR_SHIM,\n] as const;\n\nexport type DriftAction = 'overwrite' | 'skip' | 'error';\n\nexport interface WriteShimResult {\n id: ShimId;\n path: string;\n hash: string;\n status: 'created' | 'updated' | 'unchanged' | 'skipped-drift';\n}\n\nexport interface WriteShimsOptions {\n onDrift?: DriftAction;\n}\n\nfunction resolvePath(projectRoot: string, relPath: string): string {\n return join(projectRoot, relPath);\n}\n\nfunction readFileOrEmpty(path: string): string {\n return existsSync(path) ? readFileSync(path, 'utf8') : '';\n}\n\nfunction ensureDir(path: string): void {\n mkdirSync(dirname(path), { recursive: true });\n}\n\nexport type InspectStatus =\n | 'missing'\n | 'clean'\n | 'drifted'\n | 'out-of-date';\n\nexport interface InspectResult {\n id: ShimId;\n path: string;\n status: InspectStatus;\n existing?: string;\n rendered: string;\n}\n\nexport function inspectShim(projectRoot: string, shim: Shim): InspectResult {\n const abs = resolvePath(projectRoot, shim.relPath);\n const existing = readFileOrEmpty(abs);\n const fileExists = existing !== '';\n\n if (shim.mode === 'whole') {\n const rendered = shim.render();\n if (!fileExists) {\n return { id: shim.id, path: abs, status: 'missing', rendered };\n }\n if (existing === rendered) {\n return { id: shim.id, path: abs, status: 'clean', existing, rendered };\n }\n return { id: shim.id, path: abs, status: 'drifted', existing, rendered };\n }\n\n const managed = shim.render();\n const block = parseBlock(existing);\n\n if (!block) {\n return {\n id: shim.id,\n path: abs,\n status: 'missing',\n existing: fileExists ? existing : undefined,\n rendered: managed,\n };\n }\n\n if (hasDrift(block)) {\n return {\n id: shim.id,\n path: abs,\n status: 'drifted',\n existing: block.content,\n rendered: managed,\n };\n }\n\n if (block.content === managed) {\n return {\n id: shim.id,\n path: abs,\n status: 'clean',\n existing: block.content,\n rendered: managed,\n };\n }\n\n return {\n id: shim.id,\n path: abs,\n status: 'out-of-date',\n existing: block.content,\n rendered: managed,\n };\n}\n\nexport function inspectAllShims(projectRoot: string): InspectResult[] {\n return ALL_SHIMS.map((s) => inspectShim(projectRoot, s));\n}\n\nexport function writeShim(\n projectRoot: string,\n shim: Shim,\n opts: WriteShimsOptions = {}\n): WriteShimResult {\n const onDrift = opts.onDrift ?? 'error';\n const abs = resolvePath(projectRoot, shim.relPath);\n const existing = readFileOrEmpty(abs);\n const fileExists = existing !== '';\n\n if (shim.mode === 'whole') {\n const rendered = shim.render();\n const newHash = hashContent(rendered);\n\n if (fileExists && existing !== rendered) {\n const existingHash = hashContent(existing);\n if (onDrift === 'error') {\n throw new Error(\n `drift detected in ${shim.relPath} (existing hash ${existingHash} != rendered ${newHash}); rerun with onDrift=overwrite to force`\n );\n }\n if (onDrift === 'skip') {\n updateTarget(projectRoot, shim.relPath, existingHash);\n return {\n id: shim.id,\n path: abs,\n hash: existingHash,\n status: 'skipped-drift',\n };\n }\n }\n\n if (fileExists && existing === rendered) {\n updateTarget(projectRoot, shim.relPath, newHash);\n return { id: shim.id, path: abs, hash: newHash, status: 'unchanged' };\n }\n\n ensureDir(abs);\n writeFileSync(abs, rendered, 'utf8');\n updateTarget(projectRoot, shim.relPath, newHash);\n return {\n id: shim.id,\n path: abs,\n hash: newHash,\n status: fileExists ? 'updated' : 'created',\n };\n }\n\n const managed = shim.render();\n const existingBlock = parseBlock(existing);\n\n if (existingBlock && hasDrift(existingBlock)) {\n if (onDrift === 'error') {\n throw new Error(\n `managed block in ${shim.relPath} was hand-edited; rerun with onDrift=overwrite to force`\n );\n }\n if (onDrift === 'skip') {\n updateTarget(projectRoot, shim.relPath, existingBlock.hash);\n return {\n id: shim.id,\n path: abs,\n hash: existingBlock.hash,\n status: 'skipped-drift',\n };\n }\n }\n\n if (existingBlock && existingBlock.content === managed && !hasDrift(existingBlock)) {\n updateTarget(projectRoot, shim.relPath, existingBlock.hash);\n return {\n id: shim.id,\n path: abs,\n hash: existingBlock.hash,\n status: 'unchanged',\n };\n }\n\n const { updated, hash } = writeBlock(existing, managed, MANAGED_BLOCK_VERSION);\n ensureDir(abs);\n writeFileSync(abs, updated, 'utf8');\n updateTarget(projectRoot, shim.relPath, hash);\n return {\n id: shim.id,\n path: abs,\n hash,\n status: existingBlock ? 'updated' : 'created',\n };\n}\n\nexport function writeAllShims(\n projectRoot: string,\n opts: WriteShimsOptions = {}\n): WriteShimResult[] {\n const results = ALL_SHIMS.map((shim) => writeShim(projectRoot, shim, opts));\n refreshDesignMdHash(projectRoot);\n return results;\n}\n\nexport function refreshDesignMdHash(projectRoot: string): string | null {\n const designMdPath = join(projectRoot, 'DESIGN.md');\n if (!existsSync(designMdPath)) return null;\n const hash = hashContent(readFileSync(designMdPath, 'utf8'));\n updateDesignMdHash(projectRoot, hash);\n return hash;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { z } from 'zod';\n\nexport const SYNC_LOCK_VERSION = 1;\nexport const SYNC_LOCK_PATH = '.omd/sync.lock.json';\n\nconst TargetSchema = z.object({\n managed_hash: z.string(),\n last_synced: z.string(),\n});\n\nconst SyncLockSchema = z.object({\n version: z.number().int().positive(),\n design_md_hash: z.string(),\n targets: z.record(z.string(), TargetSchema),\n});\n\nexport type SyncTarget = z.infer<typeof TargetSchema>;\nexport type SyncLock = z.infer<typeof SyncLockSchema>;\n\nfunction lockPath(projectRoot: string): string {\n return join(projectRoot, SYNC_LOCK_PATH);\n}\n\nexport function readLock(projectRoot: string): SyncLock | null {\n const path = lockPath(projectRoot);\n if (!existsSync(path)) return null;\n const raw = readFileSync(path, 'utf8');\n const parsed = JSON.parse(raw);\n return SyncLockSchema.parse(parsed);\n}\n\nexport function writeLock(projectRoot: string, lock: SyncLock): void {\n const validated = SyncLockSchema.parse(lock);\n const path = lockPath(projectRoot);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(validated, null, 2) + '\\n', 'utf8');\n}\n\nexport function createLock(designMdHash: string): SyncLock {\n return {\n version: SYNC_LOCK_VERSION,\n design_md_hash: designMdHash,\n targets: {},\n };\n}\n\nexport function updateTarget(\n projectRoot: string,\n target: string,\n managedHash: string\n): SyncLock {\n const existing = readLock(projectRoot) ?? createLock('');\n const next: SyncLock = {\n ...existing,\n targets: {\n ...existing.targets,\n [target]: {\n managed_hash: managedHash,\n last_synced: new Date().toISOString(),\n },\n },\n };\n writeLock(projectRoot, next);\n return next;\n}\n\nexport function updateDesignMdHash(\n projectRoot: string,\n designMdHash: string\n): SyncLock {\n const existing = readLock(projectRoot) ?? createLock(designMdHash);\n const next: SyncLock = { ...existing, design_md_hash: designMdHash };\n writeLock(projectRoot, next);\n return next;\n}\n"],"mappings":"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","names":["existsSync","join","readFileSync","writeFileSync","mkdirSync","existsSync","dirname","join","join","existsSync","readFileSync","mkdirSync","dirname","writeFileSync","join","existsSync","readFileSync","existsSync","join"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-design-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Interactive CLI to generate DESIGN.md files for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
20
|
"templates",
|
|
21
|
-
"references",
|
|
22
21
|
"skills",
|
|
23
|
-
"data"
|
|
22
|
+
"data",
|
|
23
|
+
"references/**/DESIGN.md"
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "tsup && cp -r src/templates dist/templates",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/init.ts","../src/core/vocabulary.ts","../src/core/recommend.ts","../src/core/init-deprecate.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport {\n writeFileSync,\n readFileSync,\n mkdirSync,\n existsSync,\n} from 'node:fs';\nimport { join, relative, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { buildDeltaSet } from '../core/vocabulary.js';\nimport { recommend } from '../core/recommend.js';\nimport { deprecateDesignMd } from '../core/init-deprecate.js';\n\nexport interface InitRecommendOptions {\n description: string;\n topK?: number;\n json?: boolean;\n}\n\nexport interface InitPrepareOptions {\n dir?: string;\n ref: string;\n description: string;\n reason?: string;\n json?: boolean;\n}\n\nexport function runInitRecommend(opts: InitRecommendOptions): number {\n const hits = recommend(opts.description, { topK: opts.topK ?? 5 });\n const delta = buildDeltaSet(opts.description);\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n description: opts.description,\n recommendations: hits,\n delta_set: delta,\n },\n null,\n 2\n )\n );\n process.stdout.write('\\n');\n return 0;\n }\n\n p.intro(pc.bold('omd init — recommend'));\n p.log.message(pc.dim(`Query: \"${opts.description}\"\\n`));\n\n if (delta.matchedKeywords.length > 0) {\n p.log.message(\n pc.bold('Matched keywords: ') +\n delta.matchedKeywords\n .map((k) => pc.cyan(k.keyword) + pc.dim(` (${k.modifier.toFixed(2)})`))\n .join(', ')\n );\n }\n if (delta.warnings.length > 0) {\n for (const w of delta.warnings) p.log.warn(w);\n }\n\n p.log.message(pc.bold('\\nTop references:'));\n for (const [i, hit] of hits.entries()) {\n const scoreStr = pc.dim(`[${hit.score.toFixed(2)}]`);\n const matched = hit.matchedKeywords.length > 0\n ? pc.green(hit.matchedKeywords.join(', '))\n : pc.dim('(no direct tag match)');\n p.log.message(\n ` ${i + 1}. ${pc.bold(hit.id.padEnd(14))} ${scoreStr} ${pc.dim(hit.category.padEnd(14))} ${matched}`\n );\n }\n\n p.outro(\n pc.dim('Next: `omd init prepare --ref <id> --description \"...\"` to stage.')\n );\n return 0;\n}\n\nexport function runInitPrepare(opts: InitPrepareOptions): number {\n const projectRoot = opts.dir ?? process.cwd();\n const relRoot = relative(process.cwd(), projectRoot) || '.';\n\n const refPath = findReferencePath(opts.ref);\n if (!refPath) {\n console.error(pc.red(`omd init prepare: reference not found: ${opts.ref}`));\n return 1;\n }\n\n const referenceMd = readFileSync(refPath, 'utf8');\n const delta = buildDeltaSet(opts.description);\n\n // Handle existing DESIGN.md\n const deprecate = deprecateDesignMd({\n projectRoot,\n newReference: opts.ref,\n reason: opts.reason ?? 'user-initiated omd init',\n });\n\n // Write init-context.json that the omd:init skill consumes.\n // Note: we deliberately do NOT persist reference_path (absolute paths are\n // fragile across machines / npm reinstalls). The skill reads reference_md\n // directly from this command's --json output, and can re-fetch reference\n // content via `omd reference show <id>` if needed.\n const contextPath = join(projectRoot, '.omd', 'init-context.json');\n mkdirSync(join(projectRoot, '.omd'), { recursive: true });\n const context = {\n schema: 'omd.init-context/v1',\n created_at: new Date().toISOString(),\n reference_id: opts.ref,\n description: opts.description,\n delta_set: delta,\n deprecated_from: deprecate.renamed ? deprecate.to : null,\n };\n writeFileSync(contextPath, JSON.stringify(context, null, 2) + '\\n', 'utf8');\n\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n {\n project_root: projectRoot,\n reference_path: refPath,\n context_path: contextPath,\n deprecated_from: deprecate.renamed ? deprecate.to : null,\n reference_md: referenceMd,\n delta_set: delta,\n },\n null,\n 2\n )\n );\n process.stdout.write('\\n');\n return 0;\n }\n\n p.intro(pc.bold('omd init — prepare') + pc.dim(` (${relRoot})`));\n p.log.message(`Reference: ${pc.cyan(opts.ref)}`);\n p.log.message(`Description: ${pc.dim(opts.description)}`);\n if (deprecate.renamed) {\n p.log.warn(\n `Existing DESIGN.md renamed → ${relative(projectRoot, deprecate.to)}`\n );\n }\n p.log.success(\n `Context staged → ${relative(projectRoot, contextPath)}`\n );\n p.outro(\n pc.dim(\n 'Next: have your agent (Claude Code / Codex / OpenCode) run the `omd:init` skill to generate DESIGN.md from this context.'\n )\n );\n return 0;\n}\n\nfunction findReferencePath(refId: string): string | null {\n const root = findRepoRoot();\n if (!root) return null;\n const path = join(root, 'references', refId, 'DESIGN.md');\n return existsSync(path) ? path : null;\n}\n\nfunction findRepoRoot(): string | null {\n let cur = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 8; i++) {\n if (existsSync(join(cur, 'references'))) return cur;\n const parent = dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n return null;\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nexport interface AxisSpec {\n type: 'int' | 'float' | 'enum';\n domain: [number, number];\n unit?: string;\n step?: number;\n}\n\nexport interface KeywordAxes {\n [axis: string]: { delta: number; range: [number, number] };\n}\n\nexport interface KeywordSpec {\n group: 'tone' | 'density' | 'formality' | 'domain';\n axes: KeywordAxes;\n conflicts_with: string[];\n voice_hints: string[];\n coupled_axes?: string[];\n sources?: string[];\n}\n\nexport interface Vocabulary {\n version: number;\n generated_at: string;\n axis_registry: Record<string, AxisSpec>;\n modifiers: Record<string, number>;\n keywords: Record<string, KeywordSpec>;\n}\n\nexport interface SynonymsFile {\n version: number;\n map: Record<string, string>;\n}\n\nlet cachedVocab: Vocabulary | null = null;\nlet cachedSynonyms: SynonymsFile | null = null;\n\nfunction dataDir(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n // When built (dist/) we are at dist/*.js → data/ is ../data\n // When running from src/ via tsx we are at src/core/ → data/ is ../../data\n const candidates = [\n join(here, '..', 'data'),\n join(here, '..', '..', 'data'),\n ];\n for (const c of candidates) {\n try {\n readFileSync(join(c, 'vocabulary.json'), 'utf8');\n return c;\n } catch {\n // continue\n }\n }\n throw new Error('data/vocabulary.json not found relative to ' + here);\n}\n\nexport function loadVocabulary(): Vocabulary {\n if (cachedVocab) return cachedVocab;\n const path = join(dataDir(), 'vocabulary.json');\n cachedVocab = JSON.parse(readFileSync(path, 'utf8')) as Vocabulary;\n return cachedVocab;\n}\n\nexport function loadSynonyms(): SynonymsFile {\n if (cachedSynonyms) return cachedSynonyms;\n const path = join(dataDir(), 'synonyms.json');\n cachedSynonyms = JSON.parse(readFileSync(path, 'utf8')) as SynonymsFile;\n return cachedSynonyms;\n}\n\nexport interface ResolvedKeyword {\n keyword: string;\n modifier: number;\n matchedAs: 'direct' | 'synonym';\n synonymSource?: string;\n}\n\nconst MODIFIER_RE = /\\b(primarily|mostly|slightly|very|not)\\s+([a-z][a-z-]*)/gi;\n\nexport function tokenize(description: string): string[] {\n return description\n .toLowerCase()\n .split(/[^a-z-]+/)\n .filter(Boolean);\n}\n\nexport function extractKeywords(description: string): ResolvedKeyword[] {\n const vocab = loadVocabulary();\n const { map: synonyms } = loadSynonyms();\n\n const lower = description.toLowerCase();\n const modifierOverrides = new Map<string, number>();\n let match: RegExpExecArray | null;\n const modRe = new RegExp(MODIFIER_RE.source, MODIFIER_RE.flags);\n while ((match = modRe.exec(lower)) !== null) {\n const modName = match[1];\n const target = match[2];\n const value = vocab.modifiers[modName];\n if (value !== undefined) modifierOverrides.set(target, value);\n }\n\n const tokens = tokenize(description);\n const seen = new Set<string>();\n const results: ResolvedKeyword[] = [];\n\n for (const token of tokens) {\n if (seen.has(token)) continue;\n seen.add(token);\n\n if (vocab.keywords[token]) {\n results.push({\n keyword: token,\n modifier: modifierOverrides.get(token) ?? 1.0,\n matchedAs: 'direct',\n });\n continue;\n }\n\n const syn = synonyms[token];\n if (syn && vocab.keywords[syn]) {\n results.push({\n keyword: syn,\n modifier: modifierOverrides.get(token) ?? 1.0,\n matchedAs: 'synonym',\n synonymSource: token,\n });\n }\n }\n\n return results;\n}\n\nexport interface ConflictResolution {\n kept: ResolvedKeyword[];\n dropped: Array<{ keyword: string; reason: string }>;\n warnings: string[];\n}\n\nexport function resolveConflicts(\n keywords: ResolvedKeyword[]\n): ConflictResolution {\n const vocab = loadVocabulary();\n const kept: ResolvedKeyword[] = [];\n const dropped: Array<{ keyword: string; reason: string }> = [];\n\n // Classify each keyword: kept if strictly higher modifier than any conflicter, else dropped.\n for (const kw of keywords) {\n const spec = vocab.keywords[kw.keyword];\n if (!spec) continue;\n\n const conflictingHere = keywords.filter(\n (other) =>\n other.keyword !== kw.keyword &&\n spec.conflicts_with.includes(other.keyword)\n );\n\n if (conflictingHere.length === 0) {\n kept.push(kw);\n continue;\n }\n\n const strictlyHigherThanAll = conflictingHere.every(\n (c) => kw.modifier > c.modifier + 1e-9\n );\n if (strictlyHigherThanAll) {\n kept.push(kw);\n continue;\n }\n\n dropped.push({\n keyword: kw.keyword,\n reason: `conflicts with ${conflictingHere.map((c) => c.keyword).join(',')}`,\n });\n }\n\n // Emit warnings ONLY for conflict groups where no member was kept\n // (genuine tie — user should disambiguate).\n const warnings: string[] = [];\n const keptSet = new Set(kept.map((k) => k.keyword));\n const warned = new Set<string>();\n for (const kw of keywords) {\n const spec = vocab.keywords[kw.keyword];\n if (!spec) continue;\n const conflictingHere = keywords.filter(\n (other) =>\n other.keyword !== kw.keyword &&\n spec.conflicts_with.includes(other.keyword)\n );\n if (conflictingHere.length === 0) continue;\n const groupKeys = [kw.keyword, ...conflictingHere.map((c) => c.keyword)];\n const groupHasWinner = groupKeys.some((k) => keptSet.has(k));\n if (groupHasWinner) continue;\n const pairKey = [...new Set(groupKeys)].sort().join(',');\n if (warned.has(pairKey)) continue;\n warned.add(pairKey);\n warnings.push(\n `${kw.keyword} ↔ ${conflictingHere.map((c) => c.keyword).join(',')}: use \"primarily <kw>\" or \"very <kw>\" to pick a winner`\n );\n }\n\n return { kept, dropped, warnings };\n}\n\nexport interface DeltaSet {\n axes: Record<string, { value: number; rangeUnion: [number, number]; sources: string[] }>;\n voiceHints: string[];\n unresolved: string[];\n warnings: string[];\n droppedKeywords: Array<{ keyword: string; reason: string }>;\n matchedKeywords: ResolvedKeyword[];\n}\n\nfunction clamp(value: number, lo: number, hi: number): number {\n return Math.max(lo, Math.min(hi, value));\n}\n\nfunction snap(value: number, spec: AxisSpec): number {\n if (spec.type === 'int') return Math.round(value);\n if (spec.type === 'enum') {\n const [lo, hi] = spec.domain;\n return Math.abs(value - lo) < Math.abs(value - hi) ? lo : hi;\n }\n return Number(value.toFixed(3));\n}\n\nexport function buildDeltaSet(description: string): DeltaSet {\n const vocab = loadVocabulary();\n const matched = extractKeywords(description);\n const { kept, dropped, warnings } = resolveConflicts(matched);\n\n const axes: DeltaSet['axes'] = {};\n const voiceHintSet = new Set<string>();\n\n for (const kw of kept) {\n const spec = vocab.keywords[kw.keyword];\n const multiplier = kw.modifier;\n\n for (const hint of spec.voice_hints) voiceHintSet.add(hint);\n\n for (const [axisName, axisDelta] of Object.entries(spec.axes)) {\n const bucket = axes[axisName] ?? {\n value: 0,\n rangeUnion: [axisDelta.range[0], axisDelta.range[1]] as [number, number],\n sources: [] as string[],\n };\n bucket.value += axisDelta.delta * multiplier;\n bucket.rangeUnion = [\n Math.min(bucket.rangeUnion[0], axisDelta.range[0]),\n Math.max(bucket.rangeUnion[1], axisDelta.range[1]),\n ];\n bucket.sources.push(kw.keyword);\n axes[axisName] = bucket;\n }\n }\n\n for (const [axisName, bucket] of Object.entries(axes)) {\n const registry = vocab.axis_registry[axisName];\n if (!registry) continue;\n let v = clamp(bucket.value, bucket.rangeUnion[0], bucket.rangeUnion[1]);\n v = clamp(v, registry.domain[0], registry.domain[1]);\n bucket.value = snap(v, registry);\n bucket.sources.sort();\n }\n\n return {\n axes,\n voiceHints: [...voiceHintSet],\n unresolved: [],\n warnings,\n droppedKeywords: dropped,\n matchedKeywords: kept,\n };\n}\n\nexport function listKeywords(): string[] {\n return Object.keys(loadVocabulary().keywords).sort();\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { tokenize } from './vocabulary.js';\n\nexport interface ReferenceTag {\n id: string;\n color: string;\n category: string;\n keywords: string[];\n}\n\nexport interface RecommendHit {\n id: string;\n category: string;\n color: string;\n keywords: string[];\n score: number;\n matchedKeywords: string[];\n matchedCategories: string[];\n}\n\nconst CATEGORY_HINTS: Record<string, string[]> = {\n Consumer: [\n 'marketplace',\n 'shopping',\n 'ecommerce',\n 'consumer',\n 'b2c',\n 'retail',\n 'subscription',\n 'family',\n 'families',\n 'meal',\n 'meals',\n 'meal-kit',\n 'food',\n 'travel',\n 'social',\n 'community',\n 'buyer',\n 'seller',\n 'parents',\n 'kids',\n 'lifestyle',\n 'recipe',\n 'recipes',\n ],\n Fintech: [\n 'fintech',\n 'banking',\n 'bank',\n 'payment',\n 'payments',\n 'crypto',\n 'trading',\n 'wallet',\n 'invest',\n 'investing',\n 'money',\n 'finance',\n 'financial',\n 'lending',\n 'remittance',\n 'tax',\n ],\n 'Developer Tools': [\n 'developer',\n 'devtool',\n 'devtools',\n 'dev-tool',\n 'deploy',\n 'deployment',\n 'build',\n 'ci',\n 'cd',\n 'cli',\n 'sdk',\n 'editor',\n 'ide',\n 'engineering',\n 'compiler',\n 'runtime',\n ],\n AI: [\n 'ai',\n 'ml',\n 'llm',\n 'agent',\n 'agents',\n 'model',\n 'models',\n 'inference',\n 'gpt',\n 'chatbot',\n 'rag',\n 'embedding',\n 'embeddings',\n 'mcp',\n ],\n 'Design Tools': [\n 'design',\n 'design-tool',\n 'whiteboard',\n 'prototype',\n 'prototyping',\n 'wireframe',\n 'wireframes',\n 'mockup',\n 'mockups',\n 'figma-like',\n 'illustration',\n 'canvas',\n ],\n Productivity: [\n 'saas',\n 'workspace',\n 'team',\n 'teams',\n 'project-management',\n 'enterprise',\n 'b2b',\n 'crm',\n 'docs',\n 'wiki',\n 'collaboration',\n 'kanban',\n 'scheduling',\n 'meetings',\n ],\n Backend: [\n 'backend',\n 'database',\n 'db',\n 'api',\n 'apis',\n 'observability',\n 'monitoring',\n 'logging',\n 'analytics',\n 'pipeline',\n 'data-pipeline',\n 'streaming',\n 'queue',\n 'cache',\n ],\n Automotive: [\n 'car',\n 'cars',\n 'vehicle',\n 'vehicles',\n 'auto',\n 'automotive',\n 'driving',\n 'ev',\n 'electric-vehicle',\n ],\n Marketing: [\n 'marketing',\n 'seo',\n 'campaign',\n 'campaigns',\n 'newsletter',\n 'email-marketing',\n 'attribution',\n ],\n};\n\nfunction matchedCategoriesFor(\n queryTokens: Set<string>,\n queryStems: Set<string>\n): Set<string> {\n const out = new Set<string>();\n for (const [category, hints] of Object.entries(CATEGORY_HINTS)) {\n for (const hint of hints) {\n if (queryTokens.has(hint) || queryStems.has(stem(hint))) {\n out.add(category);\n break;\n }\n }\n }\n return out;\n}\n\nlet cachedTags: ReferenceTag[] | null = null;\n\nfunction stem(s: string): string {\n // Minimal English suffix stripping for recall across -ing/-ed/-s variants.\n // Preserves stems of length ≥3 so we don't collapse short words.\n let out = s;\n for (const suffix of ['ing', 'ed', 'ly', 'es', 's']) {\n if (out.length - suffix.length >= 3 && out.endsWith(suffix)) {\n out = out.slice(0, -suffix.length);\n break;\n }\n }\n return out;\n}\n\nfunction tagsFilePath(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, '..', 'data', 'reference-tags.md'),\n join(here, '..', '..', 'data', 'reference-tags.md'),\n ];\n for (const c of candidates) {\n try {\n readFileSync(c, 'utf8');\n return c;\n } catch {\n // continue\n }\n }\n throw new Error('data/reference-tags.md not found');\n}\n\nconst ROW_RE = /^\\|\\s*([a-z0-9._-]+)\\s*\\|\\s*([^|]*?)\\s*\\|\\s*([^|]*?)\\s*\\|\\s*([^|]*?)\\s*\\|$/i;\n\nexport function loadReferenceTags(): ReferenceTag[] {\n if (cachedTags) return cachedTags;\n const raw = readFileSync(tagsFilePath(), 'utf8');\n const rows: ReferenceTag[] = [];\n for (const line of raw.split('\\n')) {\n const m = ROW_RE.exec(line);\n if (!m) continue;\n const [, id, color, category, keywordsRaw] = m;\n if (id === 'id') continue; // header\n if (id.startsWith('---')) continue;\n rows.push({\n id: id.trim(),\n color: color.trim(),\n category: category.trim(),\n keywords: keywordsRaw\n .split(',')\n .map((k) => k.trim().toLowerCase())\n .filter(Boolean),\n });\n }\n cachedTags = rows;\n return rows;\n}\n\nexport interface RecommendOptions {\n topK?: number;\n diversityByCategory?: boolean;\n}\n\nexport function recommend(\n description: string,\n opts: RecommendOptions = {}\n): RecommendHit[] {\n const topK = opts.topK ?? 5;\n const diversityByCategory = opts.diversityByCategory ?? true;\n\n const tags = loadReferenceTags();\n const rawTokens = [\n ...tokenize(description),\n ...description\n .toLowerCase()\n .split(/[^a-z0-9-]+/)\n .filter(Boolean),\n ];\n const queryTokens = new Set(rawTokens);\n const queryStems = new Set(rawTokens.map(stem));\n const matchedCategories = matchedCategoriesFor(queryTokens, queryStems);\n\n // First pass: tag matches per ref, to know whether to gate category bonus.\n const tagMatchByRef = tags.map((t) =>\n t.keywords.filter(\n (kw) => queryTokens.has(kw) || queryStems.has(stem(kw))\n )\n );\n const totalTagMatches = tagMatchByRef.reduce((a, m) => a + m.length, 0);\n\n const scored: Array<RecommendHit & { _ratio: number }> = tags.map((t, i) => {\n const matched = tagMatchByRef[i];\n const tagScore = matched.length;\n const categoryHit = matchedCategories.has(t.category);\n // Category bonus normally requires ≥1 tag match (prevents flooding).\n // But when the description produces zero tag matches anywhere, we\n // fall back to category-only scoring so users still get a useful\n // top-K instead of an alphabetical no-op.\n const categoryBonus =\n categoryHit && (tagScore > 0 || totalTagMatches === 0) ? 0.5 : 0;\n const score = tagScore + categoryBonus;\n const ratio = matched.length / Math.max(1, t.keywords.length);\n return {\n id: t.id,\n category: t.category,\n color: t.color,\n keywords: t.keywords,\n score,\n matchedKeywords: matched,\n matchedCategories: categoryHit ? [t.category] : [],\n _ratio: ratio,\n };\n });\n\n scored.sort(\n (a, b) =>\n b.score - a.score || b._ratio - a._ratio || a.id.localeCompare(b.id)\n );\n\n const stripRatio = (s: typeof scored): RecommendHit[] =>\n s.map(({ _ratio, ...rest }) => {\n void _ratio;\n return rest;\n });\n\n if (!diversityByCategory) return stripRatio(scored.slice(0, topK));\n\n // Category-bucketed diversity: one top hit per category, fill with next best.\n const picked = stripRatio(scored).slice(0, 0);\n const pickedSet = new Set<string>();\n const usedCategories = new Set<string>();\n const allHits = stripRatio(scored);\n for (const hit of allHits) {\n if (picked.length >= topK) break;\n if (usedCategories.has(hit.category)) continue;\n picked.push(hit);\n pickedSet.add(hit.id);\n usedCategories.add(hit.category);\n }\n for (const hit of allHits) {\n if (picked.length >= topK) break;\n if (pickedSet.has(hit.id)) continue;\n picked.push(hit);\n pickedSet.add(hit.id);\n }\n return picked;\n}\n","import {\n existsSync,\n readFileSync,\n writeFileSync,\n unlinkSync,\n mkdirSync,\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nexport interface DeprecateOptions {\n projectRoot: string;\n previousReference?: string;\n newReference: string;\n preferencesReplayed?: number;\n preferencesOrphaned?: number;\n orphanFile?: string;\n reason: string;\n now?: Date;\n}\n\nexport interface DeprecateResult {\n renamed: boolean;\n from: string;\n to: string;\n}\n\nfunction deprecationHeader(opts: DeprecateOptions): string {\n const now = (opts.now ?? new Date()).toISOString();\n const lines = [\n '<!--',\n 'omd:deprecated',\n ` deprecated_at: ${now}`,\n ];\n if (opts.previousReference)\n lines.push(` previous_reference: ${opts.previousReference}`);\n lines.push(` new_reference: ${opts.newReference}`);\n if (opts.preferencesReplayed !== undefined)\n lines.push(` preferences_replayed: ${opts.preferencesReplayed}`);\n if (opts.preferencesOrphaned !== undefined)\n lines.push(` preferences_orphaned: ${opts.preferencesOrphaned}`);\n if (opts.orphanFile) lines.push(` orphan_file: ${opts.orphanFile}`);\n lines.push(` reason: ${opts.reason}`);\n lines.push('-->', '', '');\n return lines.join('\\n');\n}\n\nexport function deprecateDesignMd(opts: DeprecateOptions): DeprecateResult {\n const from = join(opts.projectRoot, 'DESIGN.md');\n const baseTo = join(opts.projectRoot, 'DESIGN_DEPRECATED.md');\n\n if (!existsSync(from)) {\n return { renamed: false, from, to: baseTo };\n }\n\n let target = baseTo;\n if (existsSync(baseTo)) {\n const ts = (opts.now ?? new Date()).toISOString().replace(/[:.]/g, '-');\n target = join(opts.projectRoot, `DESIGN_DEPRECATED.${ts}.md`);\n }\n\n mkdirSync(dirname(target), { recursive: true });\n const prior = readFileSync(from, 'utf8');\n writeFileSync(target, deprecationHeader(opts) + prior, 'utf8');\n unlinkSync(from);\n\n return { renamed: true, from, to: target };\n}\n"],"mappings":"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A;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,mBAAmB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,gBAAgB;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAA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","names":["writeFileSync","readFileSync","mkdirSync","existsSync","join","dirname","fileURLToPath","readFileSync","fileURLToPath","dirname","join","dirname","fileURLToPath","join","readFileSync","readFileSync","dirname","join","readFileSync","join","mkdirSync","writeFileSync","existsSync","dirname","fileURLToPath"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/sync.ts","../src/core/shims.ts","../src/core/sync-lock.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { relative } from 'node:path';\nimport {\n ALL_SHIMS,\n inspectShim,\n writeShim,\n refreshDesignMdHash,\n type Shim,\n type InspectResult,\n type WriteShimResult,\n} from '../core/shims.js';\n\nexport interface SyncOptions {\n dir?: string;\n force?: boolean;\n check?: boolean;\n}\n\nconst STATUS_LABEL: Record<InspectResult['status'], string> = {\n missing: pc.yellow('missing'),\n clean: pc.green('clean'),\n drifted: pc.red('drifted'),\n 'out-of-date': pc.cyan('out-of-date'),\n};\n\nconst WRITE_LABEL: Record<WriteShimResult['status'], string> = {\n created: pc.green('created'),\n updated: pc.cyan('updated'),\n unchanged: pc.dim('unchanged'),\n 'skipped-drift': pc.yellow('skipped'),\n};\n\nfunction printDiff(label: string, current: string, proposed: string): void {\n p.log.message(pc.bold('─── current (' + label + ') ───'));\n p.log.message(current || pc.dim('(empty)'));\n p.log.message(pc.bold('─── proposed ───'));\n p.log.message(proposed);\n}\n\ntype DriftChoice = 'overwrite' | 'skip' | 'show' | 'quit';\n\nasync function promptDrift(shim: Shim, inspection: InspectResult): Promise<DriftChoice> {\n while (true) {\n const choice = await p.select<DriftChoice>({\n message: `${pc.bold(shim.relPath)} has drift — choose:`,\n options: [\n { value: 'overwrite', label: 'Overwrite with rendered content' },\n { value: 'skip', label: 'Skip (keep user edits)' },\n { value: 'show', label: 'Show diff' },\n { value: 'quit', label: 'Quit sync' },\n ],\n });\n\n if (p.isCancel(choice)) return 'quit';\n if (choice !== 'show') return choice;\n\n printDiff(\n shim.relPath,\n inspection.existing ?? '',\n inspection.rendered\n );\n }\n}\n\nexport async function runSync(opts: SyncOptions = {}): Promise<number> {\n const projectRoot = opts.dir ?? process.cwd();\n const relRoot = relative(process.cwd(), projectRoot) || '.';\n\n p.intro(pc.bold('omd sync') + pc.dim(` (${relRoot})`));\n\n const inspections = ALL_SHIMS.map((shim) => ({\n shim,\n result: inspectShim(projectRoot, shim),\n }));\n\n p.log.message(pc.bold('Status:'));\n for (const { result } of inspections) {\n const rel = relative(projectRoot, result.path);\n p.log.message(` ${STATUS_LABEL[result.status]} ${rel}`);\n }\n\n if (opts.check) {\n const unsynced = inspections.filter(\n (i) => i.result.status !== 'clean'\n );\n if (unsynced.length > 0) {\n p.outro(\n pc.red(\n `${unsynced.length} not in sync — rerun without --check to resolve.`\n )\n );\n return 1;\n }\n p.outro(pc.green('All clean.'));\n return 0;\n }\n\n const results: WriteShimResult[] = [];\n\n for (const { shim, result } of inspections) {\n if (result.status === 'clean') {\n results.push({\n id: shim.id,\n path: result.path,\n hash: '',\n status: 'unchanged',\n });\n continue;\n }\n\n if (result.status === 'drifted' && !opts.force) {\n const choice = await promptDrift(shim, result);\n if (choice === 'quit') {\n p.outro(pc.yellow('Aborted by user.'));\n return 1;\n }\n if (choice === 'skip') {\n results.push(\n writeShim(projectRoot, shim, { onDrift: 'skip' })\n );\n continue;\n }\n // overwrite\n results.push(\n writeShim(projectRoot, shim, { onDrift: 'overwrite' })\n );\n continue;\n }\n\n // missing / out-of-date / (drifted with --force)\n const onDrift = opts.force ? 'overwrite' : 'error';\n results.push(writeShim(projectRoot, shim, { onDrift }));\n }\n\n refreshDesignMdHash(projectRoot);\n\n p.log.message(pc.bold('\\nResults:'));\n for (const r of results) {\n const rel = relative(projectRoot, r.path);\n p.log.message(` ${WRITE_LABEL[r.status]} ${rel}`);\n }\n\n const drifted = results.filter((r) => r.status === 'skipped-drift').length;\n const changed = results.filter(\n (r) => r.status === 'created' || r.status === 'updated'\n ).length;\n\n p.outro(\n drifted > 0\n ? pc.yellow(`${changed} written, ${drifted} skipped (drift).`)\n : pc.green(`${changed} written.`)\n );\n\n return 0;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport {\n parseBlock,\n writeBlock,\n hashContent,\n hasDrift,\n} from './sync-marker.js';\nimport { updateTarget, updateDesignMdHash } from './sync-lock.js';\n\nexport const MANAGED_BLOCK_VERSION = 1;\n\nexport type ShimId = 'claude' | 'agents' | 'cursor';\n\nexport type ShimMode = 'block' | 'whole';\n\nexport interface Shim {\n id: ShimId;\n relPath: string;\n mode: ShimMode;\n render(): string;\n}\n\nconst CLAUDE_BODY = `# Design System (oh-my-design)\n\nThe authoritative brand & UI spec is **@./DESIGN.md**.\nRead before any UI/styling/microcopy/motion work.\n\nPreference log (pending corrections): @./.omd/preferences.md\n\nPrecedence: DESIGN.md > preferences.md > your defaults.`;\n\nconst AGENTS_BODY = `## Design System (oh-my-design)\n\n**Before any UI, styling, copy, or motion change, open and read \\`./DESIGN.md\\` in full.** It is the authoritative brand/design spec. Treat its tokens, voice, and component rules as binding unless the user overrides in chat.\n\nIf present, read \\`./.omd/preferences.md\\` — pending corrections not yet folded into DESIGN.md. Apply them; flag conflicts.`;\n\nconst CURSOR_FRONTMATTER = `---\ndescription: Authoritative brand & UI design system. Read DESIGN.md before UI work.\nglobs:\n - \"**/*.tsx\"\n - \"**/*.jsx\"\n - \"**/*.vue\"\n - \"**/*.svelte\"\n - \"**/*.css\"\n - \"**/*.scss\"\n - \"**/tailwind.config.*\"\n - \"**/components/**\"\n - \"**/app/**/page.*\"\nalwaysApply: false\n---`;\n\nconst CURSOR_BODY = `The authoritative design spec lives at \\`@DESIGN.md\\` (repo root). Open and read before generating/modifying UI.\n\nPending preference corrections: \\`@.omd/preferences.md\\`.\n\nPrecedence: DESIGN.md > preferences.md > framework defaults.`;\n\nexport const CLAUDE_SHIM: Shim = {\n id: 'claude',\n relPath: 'CLAUDE.md',\n mode: 'block',\n render: () => CLAUDE_BODY,\n};\n\nexport const AGENTS_SHIM: Shim = {\n id: 'agents',\n relPath: 'AGENTS.md',\n mode: 'block',\n render: () => AGENTS_BODY,\n};\n\nexport const CURSOR_SHIM: Shim = {\n id: 'cursor',\n relPath: '.cursor/rules/omd-design.mdc',\n mode: 'whole',\n render: () => {\n const hash = hashContent(CURSOR_BODY);\n return `${CURSOR_FRONTMATTER}\\n\\n<!-- omd:start v=${MANAGED_BLOCK_VERSION} hash=${hash} -->\\n${CURSOR_BODY}\\n<!-- omd:end -->\\n`;\n },\n};\n\nexport const ALL_SHIMS: readonly Shim[] = [\n CLAUDE_SHIM,\n AGENTS_SHIM,\n CURSOR_SHIM,\n] as const;\n\nexport type DriftAction = 'overwrite' | 'skip' | 'error';\n\nexport interface WriteShimResult {\n id: ShimId;\n path: string;\n hash: string;\n status: 'created' | 'updated' | 'unchanged' | 'skipped-drift';\n}\n\nexport interface WriteShimsOptions {\n onDrift?: DriftAction;\n}\n\nfunction resolvePath(projectRoot: string, relPath: string): string {\n return join(projectRoot, relPath);\n}\n\nfunction readFileOrEmpty(path: string): string {\n return existsSync(path) ? readFileSync(path, 'utf8') : '';\n}\n\nfunction ensureDir(path: string): void {\n mkdirSync(dirname(path), { recursive: true });\n}\n\nexport type InspectStatus =\n | 'missing'\n | 'clean'\n | 'drifted'\n | 'out-of-date';\n\nexport interface InspectResult {\n id: ShimId;\n path: string;\n status: InspectStatus;\n existing?: string;\n rendered: string;\n}\n\nexport function inspectShim(projectRoot: string, shim: Shim): InspectResult {\n const abs = resolvePath(projectRoot, shim.relPath);\n const existing = readFileOrEmpty(abs);\n const fileExists = existing !== '';\n\n if (shim.mode === 'whole') {\n const rendered = shim.render();\n if (!fileExists) {\n return { id: shim.id, path: abs, status: 'missing', rendered };\n }\n if (existing === rendered) {\n return { id: shim.id, path: abs, status: 'clean', existing, rendered };\n }\n return { id: shim.id, path: abs, status: 'drifted', existing, rendered };\n }\n\n const managed = shim.render();\n const block = parseBlock(existing);\n\n if (!block) {\n return {\n id: shim.id,\n path: abs,\n status: 'missing',\n existing: fileExists ? existing : undefined,\n rendered: managed,\n };\n }\n\n if (hasDrift(block)) {\n return {\n id: shim.id,\n path: abs,\n status: 'drifted',\n existing: block.content,\n rendered: managed,\n };\n }\n\n if (block.content === managed) {\n return {\n id: shim.id,\n path: abs,\n status: 'clean',\n existing: block.content,\n rendered: managed,\n };\n }\n\n return {\n id: shim.id,\n path: abs,\n status: 'out-of-date',\n existing: block.content,\n rendered: managed,\n };\n}\n\nexport function inspectAllShims(projectRoot: string): InspectResult[] {\n return ALL_SHIMS.map((s) => inspectShim(projectRoot, s));\n}\n\nexport function writeShim(\n projectRoot: string,\n shim: Shim,\n opts: WriteShimsOptions = {}\n): WriteShimResult {\n const onDrift = opts.onDrift ?? 'error';\n const abs = resolvePath(projectRoot, shim.relPath);\n const existing = readFileOrEmpty(abs);\n const fileExists = existing !== '';\n\n if (shim.mode === 'whole') {\n const rendered = shim.render();\n const newHash = hashContent(rendered);\n\n if (fileExists && existing !== rendered) {\n const existingHash = hashContent(existing);\n if (onDrift === 'error') {\n throw new Error(\n `drift detected in ${shim.relPath} (existing hash ${existingHash} != rendered ${newHash}); rerun with onDrift=overwrite to force`\n );\n }\n if (onDrift === 'skip') {\n updateTarget(projectRoot, shim.relPath, existingHash);\n return {\n id: shim.id,\n path: abs,\n hash: existingHash,\n status: 'skipped-drift',\n };\n }\n }\n\n if (fileExists && existing === rendered) {\n updateTarget(projectRoot, shim.relPath, newHash);\n return { id: shim.id, path: abs, hash: newHash, status: 'unchanged' };\n }\n\n ensureDir(abs);\n writeFileSync(abs, rendered, 'utf8');\n updateTarget(projectRoot, shim.relPath, newHash);\n return {\n id: shim.id,\n path: abs,\n hash: newHash,\n status: fileExists ? 'updated' : 'created',\n };\n }\n\n const managed = shim.render();\n const existingBlock = parseBlock(existing);\n\n if (existingBlock && hasDrift(existingBlock)) {\n if (onDrift === 'error') {\n throw new Error(\n `managed block in ${shim.relPath} was hand-edited; rerun with onDrift=overwrite to force`\n );\n }\n if (onDrift === 'skip') {\n updateTarget(projectRoot, shim.relPath, existingBlock.hash);\n return {\n id: shim.id,\n path: abs,\n hash: existingBlock.hash,\n status: 'skipped-drift',\n };\n }\n }\n\n if (existingBlock && existingBlock.content === managed && !hasDrift(existingBlock)) {\n updateTarget(projectRoot, shim.relPath, existingBlock.hash);\n return {\n id: shim.id,\n path: abs,\n hash: existingBlock.hash,\n status: 'unchanged',\n };\n }\n\n const { updated, hash } = writeBlock(existing, managed, MANAGED_BLOCK_VERSION);\n ensureDir(abs);\n writeFileSync(abs, updated, 'utf8');\n updateTarget(projectRoot, shim.relPath, hash);\n return {\n id: shim.id,\n path: abs,\n hash,\n status: existingBlock ? 'updated' : 'created',\n };\n}\n\nexport function writeAllShims(\n projectRoot: string,\n opts: WriteShimsOptions = {}\n): WriteShimResult[] {\n const results = ALL_SHIMS.map((shim) => writeShim(projectRoot, shim, opts));\n refreshDesignMdHash(projectRoot);\n return results;\n}\n\nexport function refreshDesignMdHash(projectRoot: string): string | null {\n const designMdPath = join(projectRoot, 'DESIGN.md');\n if (!existsSync(designMdPath)) return null;\n const hash = hashContent(readFileSync(designMdPath, 'utf8'));\n updateDesignMdHash(projectRoot, hash);\n return hash;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { z } from 'zod';\n\nexport const SYNC_LOCK_VERSION = 1;\nexport const SYNC_LOCK_PATH = '.omd/sync.lock.json';\n\nconst TargetSchema = z.object({\n managed_hash: z.string(),\n last_synced: z.string(),\n});\n\nconst SyncLockSchema = z.object({\n version: z.number().int().positive(),\n design_md_hash: z.string(),\n targets: z.record(z.string(), TargetSchema),\n});\n\nexport type SyncTarget = z.infer<typeof TargetSchema>;\nexport type SyncLock = z.infer<typeof SyncLockSchema>;\n\nfunction lockPath(projectRoot: string): string {\n return join(projectRoot, SYNC_LOCK_PATH);\n}\n\nexport function readLock(projectRoot: string): SyncLock | null {\n const path = lockPath(projectRoot);\n if (!existsSync(path)) return null;\n const raw = readFileSync(path, 'utf8');\n const parsed = JSON.parse(raw);\n return SyncLockSchema.parse(parsed);\n}\n\nexport function writeLock(projectRoot: string, lock: SyncLock): void {\n const validated = SyncLockSchema.parse(lock);\n const path = lockPath(projectRoot);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(validated, null, 2) + '\\n', 'utf8');\n}\n\nexport function createLock(designMdHash: string): SyncLock {\n return {\n version: SYNC_LOCK_VERSION,\n design_md_hash: designMdHash,\n targets: {},\n };\n}\n\nexport function updateTarget(\n projectRoot: string,\n target: string,\n managedHash: string\n): SyncLock {\n const existing = readLock(projectRoot) ?? createLock('');\n const next: SyncLock = {\n ...existing,\n targets: {\n ...existing.targets,\n [target]: {\n managed_hash: managedHash,\n last_synced: new Date().toISOString(),\n },\n },\n };\n writeLock(projectRoot, next);\n return next;\n}\n\nexport function updateDesignMdHash(\n projectRoot: string,\n designMdHash: string\n): SyncLock {\n const existing = readLock(projectRoot) ?? createLock(designMdHash);\n const next: SyncLock = { ...existing, design_md_hash: designMdHash };\n writeLock(projectRoot, next);\n return next;\n}\n"],"mappings":";;;;;;;;;AAAA,YAAY,OAAO;AACnB,OAAO,QAAQ;AACf,SAAS,gBAAgB;;;ACFzB,SAAS,gBAAAA,eAAc,iBAAAC,gBAAe,aAAAC,YAAW,cAAAC,mBAAkB;AACnE,SAAS,WAAAC,UAAS,QAAAC,aAAY;;;ACD9B,SAAS,cAAc,eAAe,WAAW,kBAAkB;AACnE,SAAS,SAAS,YAAY;AAC9B,SAAS,SAAS;AAEX,IAAM,oBAAoB;AAC1B,IAAM,iBAAiB;AAE9B,IAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,cAAc,EAAE,OAAO;AAAA,EACvB,aAAa,EAAE,OAAO;AACxB,CAAC;AAED,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACnC,gBAAgB,EAAE,OAAO;AAAA,EACzB,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY;AAC5C,CAAC;AAKD,SAAS,SAAS,aAA6B;AAC7C,SAAO,KAAK,aAAa,cAAc;AACzC;AAEO,SAAS,SAAS,aAAsC;AAC7D,QAAM,OAAO,SAAS,WAAW;AACjC,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,QAAM,MAAM,aAAa,MAAM,MAAM;AACrC,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,SAAO,eAAe,MAAM,MAAM;AACpC;AAEO,SAAS,UAAU,aAAqB,MAAsB;AACnE,QAAM,YAAY,eAAe,MAAM,IAAI;AAC3C,QAAM,OAAO,SAAS,WAAW;AACjC,YAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,gBAAc,MAAM,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI,MAAM,MAAM;AACvE;AAEO,SAAS,WAAW,cAAgC;AACzD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,SAAS,CAAC;AAAA,EACZ;AACF;AAEO,SAAS,aACd,aACA,QACA,aACU;AACV,QAAM,WAAW,SAAS,WAAW,KAAK,WAAW,EAAE;AACvD,QAAM,OAAiB;AAAA,IACrB,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,SAAS;AAAA,MACZ,CAAC,MAAM,GAAG;AAAA,QACR,cAAc;AAAA,QACd,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,YAAU,aAAa,IAAI;AAC3B,SAAO;AACT;AAEO,SAAS,mBACd,aACA,cACU;AACV,QAAM,WAAW,SAAS,WAAW,KAAK,WAAW,YAAY;AACjE,QAAM,OAAiB,EAAE,GAAG,UAAU,gBAAgB,aAAa;AACnE,YAAU,aAAa,IAAI;AAC3B,SAAO;AACT;;;ADlEO,IAAM,wBAAwB;AAarC,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAMpB,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAe3B,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAMb,IAAM,cAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ,MAAM;AAChB;AAEO,IAAM,cAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ,MAAM;AAChB;AAEO,IAAM,cAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ,MAAM;AACZ,UAAM,OAAO,YAAY,WAAW;AACpC,WAAO,GAAG,kBAAkB;AAAA;AAAA,mBAAwB,qBAAqB,SAAS,IAAI;AAAA,EAAS,WAAW;AAAA;AAAA;AAAA,EAC5G;AACF;AAEO,IAAM,YAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACF;AAeA,SAAS,YAAY,aAAqB,SAAyB;AACjE,SAAOC,MAAK,aAAa,OAAO;AAClC;AAEA,SAAS,gBAAgB,MAAsB;AAC7C,SAAOC,YAAW,IAAI,IAAIC,cAAa,MAAM,MAAM,IAAI;AACzD;AAEA,SAAS,UAAU,MAAoB;AACrC,EAAAC,WAAUC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C;AAgBO,SAAS,YAAY,aAAqB,MAA2B;AAC1E,QAAM,MAAM,YAAY,aAAa,KAAK,OAAO;AACjD,QAAM,WAAW,gBAAgB,GAAG;AACpC,QAAM,aAAa,aAAa;AAEhC,MAAI,KAAK,SAAS,SAAS;AACzB,UAAM,WAAW,KAAK,OAAO;AAC7B,QAAI,CAAC,YAAY;AACf,aAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,QAAQ,WAAW,SAAS;AAAA,IAC/D;AACA,QAAI,aAAa,UAAU;AACzB,aAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,QAAQ,SAAS,UAAU,SAAS;AAAA,IACvE;AACA,WAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,QAAQ,WAAW,UAAU,SAAS;AAAA,EACzE;AAEA,QAAM,UAAU,KAAK,OAAO;AAC5B,QAAM,QAAQ,WAAW,QAAQ;AAEjC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU,aAAa,WAAW;AAAA,MAClC,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,SAAS,KAAK,GAAG;AACnB,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU,MAAM;AAAA,MAChB,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,MAAM,YAAY,SAAS;AAC7B,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU,MAAM;AAAA,MAChB,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UAAU,MAAM;AAAA,IAChB,UAAU;AAAA,EACZ;AACF;AAMO,SAAS,UACd,aACA,MACA,OAA0B,CAAC,GACV;AACjB,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,MAAM,YAAY,aAAa,KAAK,OAAO;AACjD,QAAM,WAAW,gBAAgB,GAAG;AACpC,QAAM,aAAa,aAAa;AAEhC,MAAI,KAAK,SAAS,SAAS;AACzB,UAAM,WAAW,KAAK,OAAO;AAC7B,UAAM,UAAU,YAAY,QAAQ;AAEpC,QAAI,cAAc,aAAa,UAAU;AACvC,YAAM,eAAe,YAAY,QAAQ;AACzC,UAAI,YAAY,SAAS;AACvB,cAAM,IAAI;AAAA,UACR,qBAAqB,KAAK,OAAO,mBAAmB,YAAY,gBAAgB,OAAO;AAAA,QACzF;AAAA,MACF;AACA,UAAI,YAAY,QAAQ;AACtB,qBAAa,aAAa,KAAK,SAAS,YAAY;AACpD,eAAO;AAAA,UACL,IAAI,KAAK;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,QAAI,cAAc,aAAa,UAAU;AACvC,mBAAa,aAAa,KAAK,SAAS,OAAO;AAC/C,aAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,SAAS,QAAQ,YAAY;AAAA,IACtE;AAEA,cAAU,GAAG;AACb,IAAAC,eAAc,KAAK,UAAU,MAAM;AACnC,iBAAa,aAAa,KAAK,SAAS,OAAO;AAC/C,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ,aAAa,YAAY;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,UAAU,KAAK,OAAO;AAC5B,QAAM,gBAAgB,WAAW,QAAQ;AAEzC,MAAI,iBAAiB,SAAS,aAAa,GAAG;AAC5C,QAAI,YAAY,SAAS;AACvB,YAAM,IAAI;AAAA,QACR,oBAAoB,KAAK,OAAO;AAAA,MAClC;AAAA,IACF;AACA,QAAI,YAAY,QAAQ;AACtB,mBAAa,aAAa,KAAK,SAAS,cAAc,IAAI;AAC1D,aAAO;AAAA,QACL,IAAI,KAAK;AAAA,QACT,MAAM;AAAA,QACN,MAAM,cAAc;AAAA,QACpB,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI,iBAAiB,cAAc,YAAY,WAAW,CAAC,SAAS,aAAa,GAAG;AAClF,iBAAa,aAAa,KAAK,SAAS,cAAc,IAAI;AAC1D,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM;AAAA,MACN,MAAM,cAAc;AAAA,MACpB,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,EAAE,SAAS,KAAK,IAAI,WAAW,UAAU,SAAS,qBAAqB;AAC7E,YAAU,GAAG;AACb,EAAAA,eAAc,KAAK,SAAS,MAAM;AAClC,eAAa,aAAa,KAAK,SAAS,IAAI;AAC5C,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,gBAAgB,YAAY;AAAA,EACtC;AACF;AAWO,SAAS,oBAAoB,aAAoC;AACtE,QAAM,eAAeC,MAAK,aAAa,WAAW;AAClD,MAAI,CAACC,YAAW,YAAY,EAAG,QAAO;AACtC,QAAM,OAAO,YAAYC,cAAa,cAAc,MAAM,CAAC;AAC3D,qBAAmB,aAAa,IAAI;AACpC,SAAO;AACT;;;ADpRA,IAAM,eAAwD;AAAA,EAC5D,SAAS,GAAG,OAAO,SAAS;AAAA,EAC5B,OAAO,GAAG,MAAM,OAAO;AAAA,EACvB,SAAS,GAAG,IAAI,SAAS;AAAA,EACzB,eAAe,GAAG,KAAK,aAAa;AACtC;AAEA,IAAM,cAAyD;AAAA,EAC7D,SAAS,GAAG,MAAM,SAAS;AAAA,EAC3B,SAAS,GAAG,KAAK,SAAS;AAAA,EAC1B,WAAW,GAAG,IAAI,WAAW;AAAA,EAC7B,iBAAiB,GAAG,OAAO,SAAS;AACtC;AAEA,SAAS,UAAU,OAAe,SAAiB,UAAwB;AACzE,EAAE,MAAI,QAAQ,GAAG,KAAK,iCAAkB,QAAQ,sBAAO,CAAC;AACxD,EAAE,MAAI,QAAQ,WAAW,GAAG,IAAI,SAAS,CAAC;AAC1C,EAAE,MAAI,QAAQ,GAAG,KAAK,gDAAkB,CAAC;AACzC,EAAE,MAAI,QAAQ,QAAQ;AACxB;AAIA,eAAe,YAAY,MAAY,YAAiD;AACtF,SAAO,MAAM;AACX,UAAM,SAAS,MAAQ,SAAoB;AAAA,MACzC,SAAS,GAAG,GAAG,KAAK,KAAK,OAAO,CAAC;AAAA,MACjC,SAAS;AAAA,QACP,EAAE,OAAO,aAAa,OAAO,kCAAkC;AAAA,QAC/D,EAAE,OAAO,QAAQ,OAAO,yBAAyB;AAAA,QACjD,EAAE,OAAO,QAAQ,OAAO,YAAY;AAAA,QACpC,EAAE,OAAO,QAAQ,OAAO,YAAY;AAAA,MACtC;AAAA,IACF,CAAC;AAED,QAAM,WAAS,MAAM,EAAG,QAAO;AAC/B,QAAI,WAAW,OAAQ,QAAO;AAE9B;AAAA,MACE,KAAK;AAAA,MACL,WAAW,YAAY;AAAA,MACvB,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAEA,eAAsB,QAAQ,OAAoB,CAAC,GAAoB;AACrE,QAAM,cAAc,KAAK,OAAO,QAAQ,IAAI;AAC5C,QAAM,UAAU,SAAS,QAAQ,IAAI,GAAG,WAAW,KAAK;AAExD,EAAE,QAAM,GAAG,KAAK,UAAU,IAAI,GAAG,IAAI,MAAM,OAAO,GAAG,CAAC;AAEtD,QAAM,cAAc,UAAU,IAAI,CAAC,UAAU;AAAA,IAC3C;AAAA,IACA,QAAQ,YAAY,aAAa,IAAI;AAAA,EACvC,EAAE;AAEF,EAAE,MAAI,QAAQ,GAAG,KAAK,SAAS,CAAC;AAChC,aAAW,EAAE,OAAO,KAAK,aAAa;AACpC,UAAM,MAAM,SAAS,aAAa,OAAO,IAAI;AAC7C,IAAE,MAAI,QAAQ,KAAK,aAAa,OAAO,MAAM,CAAC,KAAK,GAAG,EAAE;AAAA,EAC1D;AAEA,MAAI,KAAK,OAAO;AACd,UAAM,WAAW,YAAY;AAAA,MAC3B,CAAC,MAAM,EAAE,OAAO,WAAW;AAAA,IAC7B;AACA,QAAI,SAAS,SAAS,GAAG;AACvB,MAAE;AAAA,QACA,GAAG;AAAA,UACD,GAAG,SAAS,MAAM;AAAA,QACpB;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,IAAE,QAAM,GAAG,MAAM,YAAY,CAAC;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,UAA6B,CAAC;AAEpC,aAAW,EAAE,MAAM,OAAO,KAAK,aAAa;AAC1C,QAAI,OAAO,WAAW,SAAS;AAC7B,cAAQ,KAAK;AAAA,QACX,IAAI,KAAK;AAAA,QACT,MAAM,OAAO;AAAA,QACb,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AACD;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,aAAa,CAAC,KAAK,OAAO;AAC9C,YAAM,SAAS,MAAM,YAAY,MAAM,MAAM;AAC7C,UAAI,WAAW,QAAQ;AACrB,QAAE,QAAM,GAAG,OAAO,kBAAkB,CAAC;AACrC,eAAO;AAAA,MACT;AACA,UAAI,WAAW,QAAQ;AACrB,gBAAQ;AAAA,UACN,UAAU,aAAa,MAAM,EAAE,SAAS,OAAO,CAAC;AAAA,QAClD;AACA;AAAA,MACF;AAEA,cAAQ;AAAA,QACN,UAAU,aAAa,MAAM,EAAE,SAAS,YAAY,CAAC;AAAA,MACvD;AACA;AAAA,IACF;AAGA,UAAM,UAAU,KAAK,QAAQ,cAAc;AAC3C,YAAQ,KAAK,UAAU,aAAa,MAAM,EAAE,QAAQ,CAAC,CAAC;AAAA,EACxD;AAEA,sBAAoB,WAAW;AAE/B,EAAE,MAAI,QAAQ,GAAG,KAAK,YAAY,CAAC;AACnC,aAAW,KAAK,SAAS;AACvB,UAAM,MAAM,SAAS,aAAa,EAAE,IAAI;AACxC,IAAE,MAAI,QAAQ,KAAK,YAAY,EAAE,MAAM,CAAC,KAAK,GAAG,EAAE;AAAA,EACpD;AAEA,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,eAAe,EAAE;AACpE,QAAM,UAAU,QAAQ;AAAA,IACtB,CAAC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW;AAAA,EAChD,EAAE;AAEF,EAAE;AAAA,IACA,UAAU,IACN,GAAG,OAAO,GAAG,OAAO,aAAa,OAAO,mBAAmB,IAC3D,GAAG,MAAM,GAAG,OAAO,WAAW;AAAA,EACpC;AAEA,SAAO;AACT;","names":["readFileSync","writeFileSync","mkdirSync","existsSync","dirname","join","join","existsSync","readFileSync","mkdirSync","dirname","writeFileSync","join","existsSync","readFileSync"]}
|