wp-typia 0.19.0 → 0.20.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.
Files changed (43) hide show
  1. package/README.md +4 -2
  2. package/dist-bunli/.bunli/commands.gen.js +2117 -1465
  3. package/dist-bunli/.bunli/commands.gen.js.map +42 -35
  4. package/dist-bunli/cli-03j0axbt.js +163 -0
  5. package/dist-bunli/cli-03j0axbt.js.map +11 -0
  6. package/dist-bunli/{cli-yw0mq0wq.js → cli-93wd227r.js} +108 -3
  7. package/dist-bunli/cli-93wd227r.js.map +10 -0
  8. package/dist-bunli/{cli-kan7a6db.js → cli-a6dwqnhq.js} +24 -2
  9. package/dist-bunli/cli-a6dwqnhq.js.map +11 -0
  10. package/dist-bunli/{cli-add-j2c81sh1.js → cli-add-gcwww85p.js} +263 -250
  11. package/dist-bunli/cli-add-gcwww85p.js.map +18 -0
  12. package/dist-bunli/{cli-7svz19s1.js → cli-cfx3gm1r.js} +417 -129
  13. package/dist-bunli/{cli-7svz19s1.js.map → cli-cfx3gm1r.js.map} +18 -15
  14. package/dist-bunli/{cli-diagnostics-c65hhyhx.js → cli-diagnostics-e5gxeprp.js} +8 -4
  15. package/dist-bunli/{cli-diagnostics-c65hhyhx.js.map → cli-diagnostics-e5gxeprp.js.map} +1 -1
  16. package/dist-bunli/{cli-doctor-hft0wr0e.js → cli-doctor-qk6fwpds.js} +14 -13
  17. package/dist-bunli/{cli-doctor-hft0wr0e.js.map → cli-doctor-qk6fwpds.js.map} +3 -3
  18. package/dist-bunli/{cli-572d6g4m.js → cli-hv2yedw2.js} +2 -157
  19. package/dist-bunli/{cli-572d6g4m.js.map → cli-hv2yedw2.js.map} +4 -6
  20. package/dist-bunli/cli-mgh3f3k5.js +427 -0
  21. package/dist-bunli/cli-mgh3f3k5.js.map +12 -0
  22. package/dist-bunli/{cli-scaffold-vcg6wem5.js → cli-scaffold-f1bdt68d.js} +9 -7
  23. package/dist-bunli/cli-scaffold-f1bdt68d.js.map +10 -0
  24. package/dist-bunli/cli-t73q5aqz.js +103 -0
  25. package/dist-bunli/cli-t73q5aqz.js.map +10 -0
  26. package/dist-bunli/{cli-templates-4qxszbmc.js → cli-templates-j65r4k9v.js} +1 -1
  27. package/dist-bunli/{cli-wtrvnce5.js → cli-w4r0rr8a.js} +8 -8
  28. package/dist-bunli/cli-w4r0rr8a.js.map +10 -0
  29. package/dist-bunli/cli.js +127 -2863
  30. package/dist-bunli/cli.js.map +5 -56
  31. package/dist-bunli/command-list-66cqt7y8.js +2485 -0
  32. package/dist-bunli/command-list-66cqt7y8.js.map +58 -0
  33. package/dist-bunli/node-cli.js +432 -323
  34. package/dist-bunli/node-cli.js.map +11 -10
  35. package/dist-bunli/{sync-x91y9jtv.js → sync-k2k8svyc.js} +3 -2
  36. package/dist-bunli/{sync-x91y9jtv.js.map → sync-k2k8svyc.js.map} +1 -1
  37. package/package.json +6 -3
  38. package/dist-bunli/cli-add-j2c81sh1.js.map +0 -16
  39. package/dist-bunli/cli-kan7a6db.js.map +0 -11
  40. package/dist-bunli/cli-scaffold-vcg6wem5.js.map +0 -10
  41. package/dist-bunli/cli-wtrvnce5.js.map +0 -10
  42. package/dist-bunli/cli-yw0mq0wq.js.map +0 -10
  43. /package/dist-bunli/{cli-templates-4qxszbmc.js.map → cli-templates-j65r4k9v.js.map} +0 -0
@@ -0,0 +1,163 @@
1
+ // @bun
2
+ import {
3
+ renderFull
4
+ } from "./cli-hv2yedw2.js";
5
+ import {
6
+ builtinAgents,
7
+ detectAgents
8
+ } from "./cli-6v0pcxw6.js";
9
+
10
+ // ../../node_modules/.bun/@bunli+plugin-skills@0.1.0+44deef6f8e4a2f18/node_modules/@bunli/plugin-skills/src/sync.ts
11
+ import * as fs from "fs";
12
+ import * as fsp from "fs/promises";
13
+ import * as os from "os";
14
+ import * as path from "path";
15
+ import { createHash } from "crypto";
16
+
17
+ // ../../node_modules/.bun/@bunli+plugin-skills@0.1.0+44deef6f8e4a2f18/node_modules/@bunli/plugin-skills/src/generate.ts
18
+ function generateSkillFile(cliName, commands, options = {}) {
19
+ const { description } = options;
20
+ const slug = cliName.replace(/\s+/g, "-");
21
+ const frontmatter = renderFrontmatter({
22
+ name: slug,
23
+ ...description ? { description } : {}
24
+ });
25
+ const body = renderFull(cliName, commands, description);
26
+ return `${frontmatter}
27
+
28
+ ${body}
29
+ `;
30
+ }
31
+ function renderFrontmatter(fields) {
32
+ const lines = ["---"];
33
+ for (const [key, value] of Object.entries(fields)) {
34
+ lines.push(`${key}: ${formatFrontmatterValue(key, value)}`);
35
+ }
36
+ lines.push("---");
37
+ return lines.join(`
38
+ `);
39
+ }
40
+ function formatFrontmatterValue(key, value) {
41
+ if (key === "name" && /^[a-z0-9][a-z0-9-]*$/.test(value)) {
42
+ return value;
43
+ }
44
+ return JSON.stringify(value);
45
+ }
46
+
47
+ // ../../node_modules/.bun/@bunli+plugin-skills@0.1.0+44deef6f8e4a2f18/node_modules/@bunli/plugin-skills/src/sync.ts
48
+ var defaultSyncRuntime = {
49
+ homeDir: () => os.homedir(),
50
+ dataHome: () => process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local", "share")
51
+ };
52
+ async function syncSkills(cliName, commands, options = {}, runtime = defaultSyncRuntime) {
53
+ const {
54
+ global: isGlobal = true,
55
+ force = false,
56
+ description,
57
+ cwd = process.cwd()
58
+ } = options;
59
+ const canonicalBase = path.join(isGlobal ? runtime.homeDir() : cwd, ".agents", "skills");
60
+ const cacheKey = stalenessCacheKey(cliName, isGlobal, cwd, canonicalBase);
61
+ const skillName = cliName.replace(/\s+/g, "-");
62
+ const canonicalDir = path.join(canonicalBase, skillName);
63
+ const detected = options.agents ?? detectAgents(builtinAgents);
64
+ const agentKey = computeAgentKey(detected, canonicalDir, skillName, isGlobal, cwd);
65
+ const content = generateSkillFile(cliName, commands, { description });
66
+ const hash = createHash("sha256").update(content).digest("hex").slice(0, 16);
67
+ const prevState = readState(cacheKey, runtime);
68
+ if (!force && prevState?.hash === hash && prevState.agentKey === agentKey) {
69
+ return { paths: [], agents: [], updated: false };
70
+ }
71
+ await fsp.mkdir(canonicalDir, { recursive: true });
72
+ await fsp.writeFile(path.join(canonicalDir, "SKILL.md"), content);
73
+ const paths = [canonicalDir];
74
+ const agentInstalls = [];
75
+ let hadInstallFailure = false;
76
+ for (const agent of detected) {
77
+ const agentSkillsDir = isGlobal ? agent.globalSkillsDir : path.join(cwd, agent.projectSkillsDir);
78
+ const agentDir = path.join(agentSkillsDir, skillName);
79
+ if (agentDir === canonicalDir)
80
+ continue;
81
+ try {
82
+ rmForce(agentDir);
83
+ fs.mkdirSync(path.dirname(agentDir), { recursive: true });
84
+ const realLinkDir = resolveParent(path.dirname(agentDir));
85
+ const realTarget = resolveParent(canonicalDir);
86
+ const rel = path.relative(realLinkDir, realTarget);
87
+ fs.symlinkSync(rel, agentDir);
88
+ agentInstalls.push({ agent: agent.name, path: agentDir, mode: "symlink" });
89
+ } catch {
90
+ try {
91
+ fs.cpSync(canonicalDir, agentDir, { recursive: true });
92
+ agentInstalls.push({ agent: agent.name, path: agentDir, mode: "copy" });
93
+ } catch {
94
+ hadInstallFailure = true;
95
+ }
96
+ }
97
+ }
98
+ if (!hadInstallFailure) {
99
+ writeState(cacheKey, { hash, agentKey }, runtime);
100
+ }
101
+ return { paths, agents: agentInstalls, updated: true };
102
+ }
103
+ function stalenessCacheKey(name, isGlobal, cwd, canonicalBase) {
104
+ const scope = isGlobal ? `global:${path.resolve(canonicalBase)}` : `local:${path.resolve(cwd)}`;
105
+ const scopeHash = createHash("sha256").update(scope).digest("hex").slice(0, 8);
106
+ return `${name}-${scopeHash}`;
107
+ }
108
+ function hashPath(cacheKey, runtime) {
109
+ const dir = runtime.dataHome();
110
+ return path.join(dir, "bunli", `${cacheKey}-skills.json`);
111
+ }
112
+ function computeAgentKey(agents, canonicalDir, skillName, isGlobal, cwd) {
113
+ const targets = agents.map((agent) => isGlobal ? path.join(agent.globalSkillsDir, skillName) : path.join(cwd, agent.projectSkillsDir, skillName)).filter((target) => target !== canonicalDir).sort();
114
+ return createHash("sha256").update(JSON.stringify(targets)).digest("hex").slice(0, 16);
115
+ }
116
+ function writeState(cacheKey, state, runtime = defaultSyncRuntime) {
117
+ const file = hashPath(cacheKey, runtime);
118
+ const dir = path.dirname(file);
119
+ if (!fs.existsSync(dir))
120
+ fs.mkdirSync(dir, { recursive: true });
121
+ fs.writeFileSync(file, JSON.stringify({ ...state, at: new Date().toISOString() }) + `
122
+ `);
123
+ }
124
+ function readState(cacheKey, runtime = defaultSyncRuntime) {
125
+ try {
126
+ const data = JSON.parse(fs.readFileSync(hashPath(cacheKey, runtime), "utf-8"));
127
+ if (typeof data?.hash !== "string")
128
+ return;
129
+ return {
130
+ hash: data.hash,
131
+ agentKey: typeof data.agentKey === "string" ? data.agentKey : undefined
132
+ };
133
+ } catch {
134
+ return;
135
+ }
136
+ }
137
+ function rmForce(target) {
138
+ try {
139
+ const stat = fs.lstatSync(target);
140
+ if (stat.isSymbolicLink())
141
+ fs.unlinkSync(target);
142
+ else
143
+ fs.rmSync(target, { recursive: true, force: true });
144
+ } catch {}
145
+ }
146
+ function resolveParent(dir) {
147
+ try {
148
+ return fs.realpathSync(dir);
149
+ } catch {
150
+ const parent = path.dirname(dir);
151
+ if (parent === dir)
152
+ return dir;
153
+ try {
154
+ return path.join(fs.realpathSync(parent), path.relative(parent, dir));
155
+ } catch {
156
+ return dir;
157
+ }
158
+ }
159
+ }
160
+
161
+ export { syncSkills };
162
+
163
+ //# debugId=04AAAF4D97379D9D64756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../node_modules/.bun/@bunli+plugin-skills@0.1.0+44deef6f8e4a2f18/node_modules/@bunli/plugin-skills/src/sync.ts", "../../../node_modules/.bun/@bunli+plugin-skills@0.1.0+44deef6f8e4a2f18/node_modules/@bunli/plugin-skills/src/generate.ts"],
4
+ "sourcesContent": [
5
+ "import * as fs from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { createHash } from 'node:crypto'\nimport type { Command } from '@bunli/core'\nimport type { Agent } from './agents.js'\nimport { detectAgents, builtinAgents } from './agents.js'\nimport { generateSkillFile } from './generate.js'\n\nexport interface SyncOptions {\n /** Working directory. Defaults to process.cwd(). */\n cwd?: string\n /** Install globally (~/.agents/skills/) instead of project-local. Defaults to true. */\n global?: boolean\n /** Regenerate and reinstall even when content hash matches. */\n force?: boolean\n /** CLI description for the skill. */\n description?: string\n /** Override detected agents. */\n agents?: Agent[]\n}\n\nexport interface SyncResult {\n /** Canonical install paths. */\n paths: string[]\n /** Per-agent install details. */\n agents: AgentInstall[]\n /** Whether the skill was updated (false if hash matched). */\n updated: boolean\n}\n\nexport interface AgentInstall {\n agent: string\n path: string\n mode: 'symlink' | 'copy'\n}\n\ninterface SyncRuntime {\n homeDir(): string\n dataHome(): string\n}\n\ninterface SyncState {\n hash: string\n agentKey?: string\n}\n\nconst defaultSyncRuntime: SyncRuntime = {\n homeDir: () => os.homedir(),\n dataHome: () => process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share')\n}\n\n/**\n * Generates SKILL.md and installs to canonical + agent directories.\n * Skips if the hash matches a previous install.\n */\nexport async function syncSkills(\n cliName: string,\n commands: Map<string, Command<any, any>>,\n options: SyncOptions = {},\n runtime: SyncRuntime = defaultSyncRuntime\n): Promise<SyncResult> {\n const {\n global: isGlobal = true,\n force = false,\n description,\n cwd = process.cwd()\n } = options\n const canonicalBase = path.join(isGlobal ? runtime.homeDir() : cwd, '.agents', 'skills')\n const cacheKey = stalenessCacheKey(cliName, isGlobal, cwd, canonicalBase)\n const skillName = cliName.replace(/\\s+/g, '-')\n const canonicalDir = path.join(canonicalBase, skillName)\n const detected = options.agents ?? detectAgents(builtinAgents)\n const agentKey = computeAgentKey(detected, canonicalDir, skillName, isGlobal, cwd)\n\n // Generate content and hash\n const content = generateSkillFile(cliName, commands, { description })\n const hash = createHash('sha256').update(content).digest('hex').slice(0, 16)\n\n // Check staleness\n const prevState = readState(cacheKey, runtime)\n if (!force && prevState?.hash === hash && prevState.agentKey === agentKey) {\n return { paths: [], agents: [], updated: false }\n }\n\n // Write to canonical location\n await fsp.mkdir(canonicalDir, { recursive: true })\n await fsp.writeFile(path.join(canonicalDir, 'SKILL.md'), content)\n const paths = [canonicalDir]\n\n // Create symlinks for non-universal agents\n const agentInstalls: AgentInstall[] = []\n let hadInstallFailure = false\n\n for (const agent of detected) {\n const agentSkillsDir = isGlobal\n ? agent.globalSkillsDir\n : path.join(cwd, agent.projectSkillsDir)\n const agentDir = path.join(agentSkillsDir, skillName)\n\n if (agentDir === canonicalDir) continue\n\n try {\n rmForce(agentDir)\n fs.mkdirSync(path.dirname(agentDir), { recursive: true })\n const realLinkDir = resolveParent(path.dirname(agentDir))\n const realTarget = resolveParent(canonicalDir)\n const rel = path.relative(realLinkDir, realTarget)\n fs.symlinkSync(rel, agentDir)\n agentInstalls.push({ agent: agent.name, path: agentDir, mode: 'symlink' })\n } catch {\n // Fallback to copy\n try {\n fs.cpSync(canonicalDir, agentDir, { recursive: true })\n agentInstalls.push({ agent: agent.name, path: agentDir, mode: 'copy' })\n } catch {\n hadInstallFailure = true\n }\n }\n }\n\n // Do not persist staleness state for partial installs, so failed agent targets retry.\n if (!hadInstallFailure) {\n writeState(cacheKey, { hash, agentKey }, runtime)\n }\n\n return { paths, agents: agentInstalls, updated: true }\n}\n\nfunction stalenessCacheKey(\n name: string,\n isGlobal: boolean,\n cwd: string,\n canonicalBase: string\n): string {\n const scope = isGlobal\n ? `global:${path.resolve(canonicalBase)}`\n : `local:${path.resolve(cwd)}`\n const scopeHash = createHash('sha256').update(scope).digest('hex').slice(0, 8)\n return `${name}-${scopeHash}`\n}\n\n/** Returns the hash file path for a sync target. */\nfunction hashPath(cacheKey: string, runtime: SyncRuntime): string {\n const dir = runtime.dataHome()\n return path.join(dir, 'bunli', `${cacheKey}-skills.json`)\n}\n\nfunction computeAgentKey(\n agents: Agent[],\n canonicalDir: string,\n skillName: string,\n isGlobal: boolean,\n cwd: string\n): string {\n const targets = agents\n .map((agent) => isGlobal ? path.join(agent.globalSkillsDir, skillName) : path.join(cwd, agent.projectSkillsDir, skillName))\n .filter((target) => target !== canonicalDir)\n .sort()\n return createHash('sha256').update(JSON.stringify(targets)).digest('hex').slice(0, 16)\n}\n\nfunction writeState(\n cacheKey: string,\n state: SyncState,\n runtime: SyncRuntime = defaultSyncRuntime\n) {\n const file = hashPath(cacheKey, runtime)\n const dir = path.dirname(file)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(file, JSON.stringify({ ...state, at: new Date().toISOString() }) + '\\n')\n}\n\nfunction readState(cacheKey: string, runtime: SyncRuntime = defaultSyncRuntime): SyncState | undefined {\n try {\n const data = JSON.parse(fs.readFileSync(hashPath(cacheKey, runtime), 'utf-8'))\n if (typeof data?.hash !== 'string') return undefined\n return {\n hash: data.hash,\n agentKey: typeof data.agentKey === 'string' ? data.agentKey : undefined\n }\n } catch {\n return undefined\n }\n}\n\nfunction rmForce(target: string) {\n try {\n const stat = fs.lstatSync(target)\n if (stat.isSymbolicLink()) fs.unlinkSync(target)\n else fs.rmSync(target, { recursive: true, force: true })\n } catch { /* does not exist */ }\n}\n\nfunction resolveParent(dir: string): string {\n try {\n return fs.realpathSync(dir)\n } catch {\n const parent = path.dirname(dir)\n if (parent === dir) return dir\n try {\n return path.join(fs.realpathSync(parent), path.relative(parent, dir))\n } catch {\n return dir\n }\n }\n}\n",
6
+ "import type { Command, CLIOption } from '@bunli/core'\nimport { renderManifestFull, toJsonSchema, resolveTypeName } from '@bunli/core'\n\n/**\n * Generates a SKILL.md file with frontmatter and command body.\n */\nexport function generateSkillFile(\n cliName: string,\n commands: Map<string, Command<any, any>>,\n options: GenerateOptions = {}\n): string {\n const { description } = options\n const slug = cliName.replace(/\\s+/g, '-')\n\n const frontmatter = renderFrontmatter({\n name: slug,\n ...(description ? { description } : {})\n })\n\n // Build body using manifest renderer\n const body = renderManifestFull(cliName, commands, description)\n\n return `${frontmatter}\\n\\n${body}\\n`\n}\n\n/**\n * Generates a compact SKILL.md for a single command.\n */\nexport function generateCommandSkill(\n cliName: string,\n cmdName: string,\n cmd: Command<any, any>\n): string {\n const fullName = `${cliName} ${cmdName}`\n const slug = fullName.replace(/\\s+/g, '-')\n\n const frontmatter = renderFrontmatter({\n name: slug,\n ...(cmd.description ? { description: cmd.description } : {})\n })\n\n const sections: string[] = [`# ${fullName}`]\n if (cmd.description) sections.push('', cmd.description)\n\n // Options table\n if (cmd.options && Object.keys(cmd.options).length > 0) {\n const rows: string[] = []\n for (const [key, opt] of Object.entries(cmd.options)) {\n const option = opt as CLIOption<any>\n const jsonSchema = toJsonSchema(option.schema)\n const type = resolveTypeName(jsonSchema)\n const def = jsonSchema && jsonSchema.default !== undefined ? String(jsonSchema.default) : ''\n const flag = option.short ? `--${key}, -${option.short}` : `--${key}`\n const desc = option.description ?? ''\n rows.push(`| \\`${flag}\\` | \\`${type}\\` | ${def ? `\\`${def}\\`` : ''} | ${desc} |`)\n }\n sections.push(\n '',\n '## Options',\n '',\n '| Flag | Type | Default | Description |',\n '|------|------|---------|-------------|',\n ...rows\n )\n }\n\n return `${frontmatter}\\n\\n${sections.join('\\n')}\\n`\n}\n\nexport interface GenerateOptions {\n /** CLI description for the skill frontmatter. */\n description?: string\n}\n\nfunction renderFrontmatter(fields: Record<string, string>): string {\n const lines = ['---']\n\n for (const [key, value] of Object.entries(fields)) {\n lines.push(`${key}: ${formatFrontmatterValue(key, value)}`)\n }\n\n lines.push('---')\n return lines.join('\\n')\n}\n\nfunction formatFrontmatterValue(key: string, value: string): string {\n if (key === 'name' && /^[a-z0-9][a-z0-9-]*$/.test(value)) {\n return value\n }\n\n return JSON.stringify(value)\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "04AAAF4D97379D9D64756E2164756E21",
10
+ "names": []
11
+ }
@@ -1,10 +1,25 @@
1
1
  // @bun
2
2
  // ../wp-typia-project-tools/src/runtime/cli-diagnostics.ts
3
+ var CLI_DIAGNOSTIC_CODES = {
4
+ COMMAND_EXECUTION: "command-execution",
5
+ CONFIGURATION_MISSING: "configuration-missing",
6
+ DEPENDENCIES_NOT_INSTALLED: "dependencies-not-installed",
7
+ DOCTOR_CHECK_FAILED: "doctor-check-failed",
8
+ INVALID_ARGUMENT: "invalid-argument",
9
+ INVALID_COMMAND: "invalid-command",
10
+ MISSING_ARGUMENT: "missing-argument",
11
+ MISSING_BUILD_ARTIFACT: "missing-build-artifact",
12
+ OUTSIDE_PROJECT_ROOT: "outside-project-root",
13
+ UNSUPPORTED_COMMAND: "unsupported-command"
14
+ };
3
15
  var DEFAULT_CLI_FAILURE_SUMMARIES = {
4
16
  add: "Unable to complete the requested add workflow.",
5
17
  create: "Unable to complete the requested create workflow.",
6
18
  doctor: "One or more doctor checks failed.",
7
- migrate: "Unable to complete the requested migration command."
19
+ mcp: "Unable to inspect or sync MCP metadata.",
20
+ migrate: "Unable to complete the requested migration command.",
21
+ sync: "Unable to complete the requested sync workflow.",
22
+ templates: "Unable to inspect scaffold templates."
8
23
  };
9
24
  var MIN_CLI_WRAP_COLUMNS = 32;
10
25
  function parseCliColumns(value) {
@@ -98,11 +113,13 @@ function normalizeDetailLines(detailLines) {
98
113
  }
99
114
 
100
115
  class CliDiagnosticError extends Error {
116
+ code;
101
117
  command;
102
118
  detailLines;
103
119
  summary;
104
120
  constructor(message, options) {
105
121
  super(formatCliDiagnosticBlock(message), options);
122
+ this.code = message.code;
106
123
  this.command = message.command;
107
124
  this.detailLines = [...message.detailLines];
108
125
  this.name = "CliDiagnosticError";
@@ -112,13 +129,70 @@ class CliDiagnosticError extends Error {
112
129
  function isCliDiagnosticError(error) {
113
130
  return error instanceof CliDiagnosticError;
114
131
  }
132
+ function isCliDiagnosticCode(value) {
133
+ return Object.values(CLI_DIAGNOSTIC_CODES).includes(value);
134
+ }
135
+ function readCliDiagnosticCode(error) {
136
+ if (isCliDiagnosticError(error)) {
137
+ return error.code;
138
+ }
139
+ if (typeof error === "object" && error !== null && "code" in error) {
140
+ const { code } = error;
141
+ if (isCliDiagnosticCode(code)) {
142
+ return code;
143
+ }
144
+ }
145
+ return null;
146
+ }
147
+ function inferCliDiagnosticCode(options) {
148
+ const inheritedCode = readCliDiagnosticCode(options.error);
149
+ if (inheritedCode) {
150
+ return inheritedCode;
151
+ }
152
+ const haystack = normalizeDetailLines([
153
+ ...options.detailLines,
154
+ options.error === undefined ? undefined : getErrorMessage(options.error)
155
+ ]).join(`
156
+ `);
157
+ if (/No MCP schema sources are configured\./u.test(haystack)) {
158
+ return CLI_DIAGNOSTIC_CODES.CONFIGURATION_MISSING;
159
+ }
160
+ if (/Missing bundled build artifacts/u.test(haystack)) {
161
+ return CLI_DIAGNOSTIC_CODES.MISSING_BUILD_ARTIFACT;
162
+ }
163
+ if (/No generated wp-typia project root was found/u.test(haystack)) {
164
+ return CLI_DIAGNOSTIC_CODES.OUTSIDE_PROJECT_ROOT;
165
+ }
166
+ if (/dependencies have not been installed yet/u.test(haystack)) {
167
+ return CLI_DIAGNOSTIC_CODES.DEPENDENCIES_NOT_INSTALLED;
168
+ }
169
+ if (options.command === "doctor") {
170
+ return CLI_DIAGNOSTIC_CODES.DOCTOR_CHECK_FAILED;
171
+ }
172
+ if (/requires <|requires --/u.test(haystack)) {
173
+ return CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT;
174
+ }
175
+ if (/Unknown .*subcommand|Unknown add kind|Unknown template|removed in favor|does not support|The Bun-free fallback runtime does not support|The positional alias only accepts/u.test(haystack)) {
176
+ return haystack.includes("does not support") || haystack.includes("The Bun-free fallback runtime does not support") ? CLI_DIAGNOSTIC_CODES.UNSUPPORTED_COMMAND : CLI_DIAGNOSTIC_CODES.INVALID_COMMAND;
177
+ }
178
+ if (/Invalid |must start with|cannot hook|cannot nest|cannot use|cannot be|already defines|already exists|Expected one of/u.test(haystack)) {
179
+ return CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT;
180
+ }
181
+ return CLI_DIAGNOSTIC_CODES.COMMAND_EXECUTION;
182
+ }
115
183
  function createCliCommandError(options) {
116
184
  if (isCliDiagnosticError(options.error)) {
117
185
  return options.error;
118
186
  }
119
187
  const summary = options.summary ?? DEFAULT_CLI_FAILURE_SUMMARIES[options.command] ?? "Command failed.";
120
188
  const detailLines = normalizeDetailLines(options.detailLines ?? [options.error === undefined ? undefined : getErrorMessage(options.error)]);
189
+ const code = options.code ?? inferCliDiagnosticCode({
190
+ command: options.command,
191
+ detailLines,
192
+ error: options.error
193
+ });
121
194
  return new CliDiagnosticError({
195
+ code,
122
196
  command: options.command,
123
197
  detailLines,
124
198
  summary
@@ -129,11 +203,42 @@ function formatCliDiagnosticError(error) {
129
203
  return getErrorMessage(error);
130
204
  }
131
205
  return formatCliDiagnosticBlock({
206
+ code: error.code,
132
207
  command: error.command,
133
208
  detailLines: error.detailLines,
134
209
  summary: error.summary
135
210
  });
136
211
  }
212
+ function serializeCliDiagnosticError(error) {
213
+ if (isCliDiagnosticError(error)) {
214
+ return {
215
+ code: error.code,
216
+ command: error.command,
217
+ detailLines: [...error.detailLines],
218
+ kind: "command-execution",
219
+ message: formatCliDiagnosticBlock({
220
+ code: error.code,
221
+ command: error.command,
222
+ detailLines: error.detailLines,
223
+ summary: error.summary
224
+ }),
225
+ name: error.name,
226
+ summary: error.summary,
227
+ tag: "CommandExecutionError"
228
+ };
229
+ }
230
+ return {
231
+ code: inferCliDiagnosticCode({
232
+ command: "unknown",
233
+ detailLines: [],
234
+ error
235
+ }),
236
+ kind: "command-execution",
237
+ message: getErrorMessage(error),
238
+ name: error instanceof Error ? error.name : "Error",
239
+ tag: "CommandExecutionError"
240
+ };
241
+ }
137
242
  function formatDoctorCheckLine(check) {
138
243
  return formatWrappedPrefixedLine(`${check.status === "pass" ? "PASS" : "FAIL"} ${check.label}: `, check.detail, resolveCliWrapColumns(process.stdout.columns)).join(`
139
244
  `);
@@ -150,6 +255,6 @@ function getDoctorFailureDetailLines(checks) {
150
255
  return getFailingDoctorChecks(checks).map((check) => `${check.label}: ${check.detail}`);
151
256
  }
152
257
 
153
- export { CliDiagnosticError, isCliDiagnosticError, createCliCommandError, formatCliDiagnosticError, formatDoctorCheckLine, getFailingDoctorChecks, formatDoctorSummaryLine, getDoctorFailureDetailLines };
258
+ export { CLI_DIAGNOSTIC_CODES, CliDiagnosticError, isCliDiagnosticError, createCliCommandError, formatCliDiagnosticError, serializeCliDiagnosticError, formatDoctorCheckLine, getFailingDoctorChecks, formatDoctorSummaryLine, getDoctorFailureDetailLines };
154
259
 
155
- //# debugId=859D9B42A7C024F764756E2164756E21
260
+ //# debugId=FAC56547BE07902964756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../wp-typia-project-tools/src/runtime/cli-diagnostics.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Shared human-readable diagnostics for non-interactive `wp-typia` CLI flows.\n */\nexport interface CliDiagnosticMessage {\n\tcode: CliDiagnosticCode;\n\tcommand: string;\n\tdetailLines: string[];\n\tsummary: string;\n}\n\nexport const CLI_DIAGNOSTIC_CODES = {\n\tCOMMAND_EXECUTION: \"command-execution\",\n\tCONFIGURATION_MISSING: \"configuration-missing\",\n\tDEPENDENCIES_NOT_INSTALLED: \"dependencies-not-installed\",\n\tDOCTOR_CHECK_FAILED: \"doctor-check-failed\",\n\tINVALID_ARGUMENT: \"invalid-argument\",\n\tINVALID_COMMAND: \"invalid-command\",\n\tMISSING_ARGUMENT: \"missing-argument\",\n\tMISSING_BUILD_ARTIFACT: \"missing-build-artifact\",\n\tOUTSIDE_PROJECT_ROOT: \"outside-project-root\",\n\tUNSUPPORTED_COMMAND: \"unsupported-command\",\n} as const;\n\nexport type CliDiagnosticCode =\n\t(typeof CLI_DIAGNOSTIC_CODES)[keyof typeof CLI_DIAGNOSTIC_CODES];\n\ntype DoctorCheckLike = {\n\tdetail: string;\n\tlabel: string;\n\tstatus: \"pass\" | \"fail\";\n};\n\nconst DEFAULT_CLI_FAILURE_SUMMARIES: Record<string, string> = {\n\tadd: \"Unable to complete the requested add workflow.\",\n\tcreate: \"Unable to complete the requested create workflow.\",\n\tdoctor: \"One or more doctor checks failed.\",\n\tmcp: \"Unable to inspect or sync MCP metadata.\",\n\tmigrate: \"Unable to complete the requested migration command.\",\n\tsync: \"Unable to complete the requested sync workflow.\",\n\ttemplates: \"Unable to inspect scaffold templates.\",\n};\n\nconst MIN_CLI_WRAP_COLUMNS = 32;\n\nfunction parseCliColumns(value: string | undefined): number | null {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\treturn null;\n\t}\n\n\tconst parsed = Number.parseInt(value, 10);\n\treturn Number.isFinite(parsed) && parsed >= MIN_CLI_WRAP_COLUMNS ? parsed : null;\n}\n\nfunction resolveCliWrapColumns(streamColumns: number | undefined): number | null {\n\treturn parseCliColumns(process.env.COLUMNS) ??\n\t\t(typeof streamColumns === \"number\" && streamColumns >= MIN_CLI_WRAP_COLUMNS\n\t\t\t? streamColumns\n\t\t\t: null);\n}\n\nfunction wrapCliText(text: string, maxWidth: number): string[] {\n\tconst words = text.trim().split(/\\s+/u).filter((word) => word.length > 0);\n\n\tif (words.length === 0) {\n\t\treturn [\"\"];\n\t}\n\n\tconst lines: string[] = [];\n\tlet currentLine = words[0] ?? \"\";\n\n\tfor (const word of words.slice(1)) {\n\t\tconst nextLine = `${currentLine} ${word}`;\n\t\tif (nextLine.length <= maxWidth) {\n\t\t\tcurrentLine = nextLine;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlines.push(currentLine);\n\t\tcurrentLine = word;\n\t}\n\n\tlines.push(currentLine);\n\treturn lines;\n}\n\nfunction formatWrappedPrefixedLine(\n\tprefix: string,\n\ttext: string,\n\tcolumns: number | null,\n\tcontinuationIndent = \" \",\n): string[] {\n\tconst singleLine = `${prefix}${text}`;\n\tif (columns === null || singleLine.length <= columns) {\n\t\treturn [singleLine];\n\t}\n\n\tconst words = text.trim().split(/\\s+/u).filter((word) => word.length > 0);\n\tif (words.length === 0) {\n\t\treturn [prefix.trimEnd()];\n\t}\n\n\tconst continuationWidth = Math.max(1, columns - continuationIndent.length);\n\tconst firstLineWidth = columns - prefix.length;\n\tif (firstLineWidth <= 0 || (words[0]?.length ?? 0) > firstLineWidth) {\n\t\treturn [\n\t\t\tprefix.trimEnd(),\n\t\t\t...wrapCliText(text, continuationWidth).map((line) => `${continuationIndent}${line}`),\n\t\t];\n\t}\n\n\tconst lines: string[] = [];\n\tlet currentPrefix = prefix;\n\tlet currentWidth = Math.max(1, columns - currentPrefix.length);\n\tlet currentLine = words[0] ?? \"\";\n\n\tfor (const word of words.slice(1)) {\n\t\tconst nextLine = `${currentLine} ${word}`;\n\t\tif (nextLine.length <= currentWidth) {\n\t\t\tcurrentLine = nextLine;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlines.push(`${currentPrefix}${currentLine}`);\n\t\tcurrentPrefix = continuationIndent;\n\t\tcurrentWidth = continuationWidth;\n\t\tcurrentLine = word;\n\t}\n\n\tlines.push(`${currentPrefix}${currentLine}`);\n\treturn lines;\n}\n\nfunction formatCliDiagnosticBlock(message: CliDiagnosticMessage): string {\n\tconst columns = resolveCliWrapColumns(process.stderr.columns);\n\tconst lines = [\n\t\t`wp-typia ${message.command} failed`,\n\t\t...formatWrappedPrefixedLine(\"Summary: \", message.summary, columns),\n\t];\n\n\tif (message.detailLines.length > 0) {\n\t\tlines.push(\"Details:\");\n\t\tfor (const detailLine of message.detailLines) {\n\t\t\tlines.push(...formatWrappedPrefixedLine(\"- \", detailLine, columns));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction getErrorMessage(error: unknown): string {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\n\treturn String(error);\n}\n\nfunction normalizeDetailLines(detailLines: Array<string | null | undefined>): string[] {\n\treturn detailLines\n\t\t.flatMap((detailLine) =>\n\t\t\ttypeof detailLine === \"string\" ? detailLine.split(\"\\n\") : [],\n\t\t)\n\t\t.map((detailLine) => detailLine.trim())\n\t\t.filter((detailLine) => detailLine.length > 0);\n}\n\n/**\n * Structured CLI failure carrying a stable summary/detail layout.\n */\nexport class CliDiagnosticError extends Error {\n\treadonly code: CliDiagnosticCode;\n\treadonly command: string;\n\treadonly detailLines: string[];\n\treadonly summary: string;\n\n\tconstructor(message: CliDiagnosticMessage, options?: ErrorOptions) {\n\t\tsuper(formatCliDiagnosticBlock(message), options);\n\t\tthis.code = message.code;\n\t\tthis.command = message.command;\n\t\tthis.detailLines = [...message.detailLines];\n\t\tthis.name = \"CliDiagnosticError\";\n\t\tthis.summary = message.summary;\n\t}\n}\n\n/**\n * Narrow an unknown error to the shared CLI diagnostic error shape.\n */\nexport function isCliDiagnosticError(error: unknown): error is CliDiagnosticError {\n\treturn error instanceof CliDiagnosticError;\n}\n\nfunction isCliDiagnosticCode(value: unknown): value is CliDiagnosticCode {\n\treturn Object.values(CLI_DIAGNOSTIC_CODES).includes(value as CliDiagnosticCode);\n}\n\nfunction readCliDiagnosticCode(error: unknown): CliDiagnosticCode | null {\n\tif (isCliDiagnosticError(error)) {\n\t\treturn error.code;\n\t}\n\n\tif (typeof error === \"object\" && error !== null && \"code\" in error) {\n\t\tconst { code } = error as { code?: unknown };\n\t\tif (isCliDiagnosticCode(code)) {\n\t\t\treturn code;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction inferCliDiagnosticCode(options: {\n\tcommand: string;\n\tdetailLines: string[];\n\terror?: unknown;\n}): CliDiagnosticCode {\n\tconst inheritedCode = readCliDiagnosticCode(options.error);\n\tif (inheritedCode) {\n\t\treturn inheritedCode;\n\t}\n\n\tconst haystack = normalizeDetailLines([\n\t\t...options.detailLines,\n\t\toptions.error === undefined ? undefined : getErrorMessage(options.error),\n\t]).join(\"\\n\");\n\n\tif (/No MCP schema sources are configured\\./u.test(haystack)) {\n\t\treturn CLI_DIAGNOSTIC_CODES.CONFIGURATION_MISSING;\n\t}\n\tif (/Missing bundled build artifacts/u.test(haystack)) {\n\t\treturn CLI_DIAGNOSTIC_CODES.MISSING_BUILD_ARTIFACT;\n\t}\n\tif (/No generated wp-typia project root was found/u.test(haystack)) {\n\t\treturn CLI_DIAGNOSTIC_CODES.OUTSIDE_PROJECT_ROOT;\n\t}\n\tif (/dependencies have not been installed yet/u.test(haystack)) {\n\t\treturn CLI_DIAGNOSTIC_CODES.DEPENDENCIES_NOT_INSTALLED;\n\t}\n\tif (options.command === \"doctor\") {\n\t\treturn CLI_DIAGNOSTIC_CODES.DOCTOR_CHECK_FAILED;\n\t}\n\tif (/requires <|requires --/u.test(haystack)) {\n\t\treturn CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT;\n\t}\n\tif (\n\t\t/Unknown .*subcommand|Unknown add kind|Unknown template|removed in favor|does not support|The Bun-free fallback runtime does not support|The positional alias only accepts/u.test(\n\t\t\thaystack,\n\t\t)\n\t) {\n\t\treturn haystack.includes(\"does not support\") ||\n\t\t\thaystack.includes(\"The Bun-free fallback runtime does not support\")\n\t\t\t? CLI_DIAGNOSTIC_CODES.UNSUPPORTED_COMMAND\n\t\t\t: CLI_DIAGNOSTIC_CODES.INVALID_COMMAND;\n\t}\n\tif (\n\t\t/Invalid |must start with|cannot hook|cannot nest|cannot use|cannot be|already defines|already exists|Expected one of/u.test(\n\t\t\thaystack,\n\t\t)\n\t) {\n\t\treturn CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT;\n\t}\n\n\treturn CLI_DIAGNOSTIC_CODES.COMMAND_EXECUTION;\n}\n\n/**\n * Build a shared diagnostic error for one CLI command failure.\n */\nexport function createCliCommandError(options: {\n\tcommand: string;\n\tcode?: CliDiagnosticCode;\n\tdetailLines?: string[];\n\terror?: unknown;\n\tsummary?: string;\n}): CliDiagnosticError {\n\tif (isCliDiagnosticError(options.error)) {\n\t\treturn options.error;\n\t}\n\n\tconst summary =\n\t\toptions.summary ?? DEFAULT_CLI_FAILURE_SUMMARIES[options.command] ?? \"Command failed.\";\n\tconst detailLines = normalizeDetailLines(\n\t\toptions.detailLines ?? [options.error === undefined ? undefined : getErrorMessage(options.error)],\n\t);\n\tconst code =\n\t\toptions.code ??\n\t\tinferCliDiagnosticCode({\n\t\t\tcommand: options.command,\n\t\t\tdetailLines,\n\t\t\terror: options.error,\n\t\t});\n\n\treturn new CliDiagnosticError(\n\t\t{\n\t\t\tcode,\n\t\t\tcommand: options.command,\n\t\t\tdetailLines,\n\t\t\tsummary,\n\t\t},\n\t\toptions.error instanceof Error ? { cause: options.error } : undefined,\n\t);\n}\n\n/**\n * Render a CLI diagnostic block. Non-diagnostic errors fall back to their\n * plain message so existing non-command failures keep working.\n */\nexport function formatCliDiagnosticError(error: unknown): string {\n\tif (!isCliDiagnosticError(error)) {\n\t\treturn getErrorMessage(error);\n\t}\n\n\treturn formatCliDiagnosticBlock({\n\t\tcode: error.code,\n\t\tcommand: error.command,\n\t\tdetailLines: error.detailLines,\n\t\tsummary: error.summary,\n\t});\n}\n\nexport function serializeCliDiagnosticError(error: unknown): {\n\tcode: CliDiagnosticCode;\n\tcommand?: string;\n\tdetailLines?: string[];\n\tkind: \"command-execution\";\n\tmessage: string;\n\tname: string;\n\tsummary?: string;\n\ttag: \"CommandExecutionError\";\n} {\n\tif (isCliDiagnosticError(error)) {\n\t\treturn {\n\t\t\tcode: error.code,\n\t\t\tcommand: error.command,\n\t\t\tdetailLines: [...error.detailLines],\n\t\t\tkind: \"command-execution\",\n\t\t\tmessage: formatCliDiagnosticBlock({\n\t\t\t\tcode: error.code,\n\t\t\t\tcommand: error.command,\n\t\t\t\tdetailLines: error.detailLines,\n\t\t\t\tsummary: error.summary,\n\t\t\t}),\n\t\t\tname: error.name,\n\t\t\tsummary: error.summary,\n\t\t\ttag: \"CommandExecutionError\",\n\t\t};\n\t}\n\n\treturn {\n\t\tcode: inferCliDiagnosticCode({\n\t\t\tcommand: \"unknown\",\n\t\t\tdetailLines: [],\n\t\t\terror,\n\t\t}),\n\t\tkind: \"command-execution\",\n\t\tmessage: getErrorMessage(error),\n\t\tname: error instanceof Error ? error.name : \"Error\",\n\t\ttag: \"CommandExecutionError\",\n\t};\n}\n\n/**\n * Format one human-readable doctor check row.\n */\nexport function formatDoctorCheckLine(check: DoctorCheckLike): string {\n\treturn formatWrappedPrefixedLine(\n\t\t`${check.status === \"pass\" ? \"PASS\" : \"FAIL\"} ${check.label}: `,\n\t\tcheck.detail,\n\t\tresolveCliWrapColumns(process.stdout.columns),\n\t).join(\"\\n\");\n}\n\n/**\n * Return the failing doctor checks from one doctor run.\n */\nexport function getFailingDoctorChecks<TCheck extends DoctorCheckLike>(\n\tchecks: readonly TCheck[],\n): TCheck[] {\n\treturn checks.filter((check) => check.status === \"fail\");\n}\n\n/**\n * Format the final doctor summary row.\n */\nexport function formatDoctorSummaryLine(checks: readonly DoctorCheckLike[]): string {\n\tconst failedChecks = getFailingDoctorChecks(checks);\n\treturn formatWrappedPrefixedLine(\n\t\t`${failedChecks.length === 0 ? \"PASS\" : \"FAIL\"} wp-typia doctor summary: `,\n\t\t`${checks.length - failedChecks.length}/${checks.length} checks passed`,\n\t\tresolveCliWrapColumns(process.stdout.columns),\n\t).join(\"\\n\");\n}\n\n/**\n * Build detail lines for doctor failures so the non-interactive formatter can\n * restate the failed checks after the streaming rows.\n */\nexport function getDoctorFailureDetailLines(checks: readonly DoctorCheckLike[]): string[] {\n\treturn getFailingDoctorChecks(checks).map((check) => `${check.label}: ${check.detail}`);\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "FAC56547BE07902964756E2164756E21",
9
+ "names": []
10
+ }
@@ -45,14 +45,36 @@ function getRemovedBuiltInTemplateMessage(templateId) {
45
45
 
46
46
  // ../wp-typia-project-tools/src/runtime/template-registry.ts
47
47
  var __dirname2 = path.dirname(fileURLToPath(import.meta.url));
48
+ var PROJECT_TOOLS_PACKAGE_ROOT_ENV = "WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT";
49
+ var PROJECT_TOOLS_PACKAGE_NAME = "@wp-typia/project-tools";
50
+ function resolveValidProjectToolsPackageRoot(candidateRoot) {
51
+ const packageJsonPath = path.join(candidateRoot, "package.json");
52
+ if (!fs.existsSync(packageJsonPath)) {
53
+ return;
54
+ }
55
+ try {
56
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
57
+ return packageJson.name === PROJECT_TOOLS_PACKAGE_NAME ? candidateRoot : undefined;
58
+ } catch {
59
+ return;
60
+ }
61
+ }
48
62
  function resolvePackageRoot(startDir) {
63
+ const overriddenPackageRoot = process.env[PROJECT_TOOLS_PACKAGE_ROOT_ENV]?.trim();
64
+ if (overriddenPackageRoot) {
65
+ const resolvedOverride = path.resolve(overriddenPackageRoot);
66
+ const validOverride = resolveValidProjectToolsPackageRoot(resolvedOverride);
67
+ if (validOverride) {
68
+ return validOverride;
69
+ }
70
+ }
49
71
  let currentDir = startDir;
50
72
  while (true) {
51
73
  const packageJsonPath = path.join(currentDir, "package.json");
52
74
  if (fs.existsSync(packageJsonPath)) {
53
75
  try {
54
76
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
55
- if (packageJson.name === "@wp-typia/project-tools") {
77
+ if (packageJson.name === PROJECT_TOOLS_PACKAGE_NAME) {
56
78
  return currentDir;
57
79
  }
58
80
  } catch {}
@@ -155,4 +177,4 @@ function getTemplateSelectOptions() {
155
177
 
156
178
  export { BUILTIN_BLOCK_METADATA_VERSION, COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS, getBuiltInTemplateMetadataDefaults, isRemovedBuiltInTemplateId, getRemovedBuiltInTemplateMessage, PROJECT_TOOLS_PACKAGE_ROOT, SHARED_BASE_TEMPLATE_ROOT, SHARED_COMPOUND_TEMPLATE_ROOT, SHARED_PERSISTENCE_TEMPLATE_ROOT, SHARED_PRESET_TEMPLATE_ROOT, SHARED_REST_HELPER_TEMPLATE_ROOT, SHARED_MIGRATION_UI_TEMPLATE_ROOT, SHARED_WORKSPACE_TEMPLATE_ROOT, SHARED_TEST_PRESET_TEMPLATE_ROOT, SHARED_WP_ENV_PRESET_TEMPLATE_ROOT, BUILTIN_TEMPLATE_IDS, OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, TEMPLATE_IDS, isBuiltInTemplateId, listTemplates, getTemplateById, getTemplateSelectOptions };
157
179
 
158
- //# debugId=047835176EC811BA64756E2164756E21
180
+ //# debugId=4B25E5AE2392289964756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../wp-typia-project-tools/src/runtime/template-registry.ts", "../../wp-typia-project-tools/src/runtime/template-defaults.ts"],
4
+ "sourcesContent": [
5
+ "import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { getBuiltInTemplateMetadataDefaults } from \"./template-defaults.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst PROJECT_TOOLS_PACKAGE_ROOT_ENV = \"WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT\";\nconst PROJECT_TOOLS_PACKAGE_NAME = \"@wp-typia/project-tools\";\n\nfunction resolveValidProjectToolsPackageRoot(\n\tcandidateRoot: string,\n): string | undefined {\n\tconst packageJsonPath = path.join(candidateRoot, \"package.json\");\n\tif (!fs.existsSync(packageJsonPath)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\")) as {\n\t\t\tname?: string;\n\t\t};\n\t\treturn packageJson.name === PROJECT_TOOLS_PACKAGE_NAME\n\t\t\t? candidateRoot\n\t\t\t: undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Resolve the canonical `@wp-typia/project-tools` package root.\n *\n * When `WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT` is set, the override is only\n * accepted if it points at a readable package manifest whose `name` matches\n * `@wp-typia/project-tools`. Invalid or stale overrides are ignored and normal\n * upward package-root discovery continues.\n */\nexport function resolvePackageRoot(startDir: string): string {\n\tconst overriddenPackageRoot = process.env[PROJECT_TOOLS_PACKAGE_ROOT_ENV]?.trim();\n\tif (overriddenPackageRoot) {\n\t\tconst resolvedOverride = path.resolve(overriddenPackageRoot);\n\t\tconst validOverride = resolveValidProjectToolsPackageRoot(resolvedOverride);\n\t\tif (validOverride) {\n\t\t\treturn validOverride;\n\t\t}\n\t}\n\n\tlet currentDir = startDir;\n\n\twhile (true) {\n\t\tconst packageJsonPath = path.join(currentDir, \"package.json\");\n\t\tif (fs.existsSync(packageJsonPath)) {\n\t\t\ttry {\n\t\t\t\tconst packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\")) as { name?: string };\n\t\t\t\tif (packageJson.name === PROJECT_TOOLS_PACKAGE_NAME) {\n\t\t\t\t\treturn currentDir;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore malformed package.json while walking upward.\n\t\t\t}\n\t\t}\n\n\t\tconst parentDir = path.dirname(currentDir);\n\t\tif (parentDir === currentDir) {\n\t\t\tthrow new Error(\"Unable to resolve the @wp-typia/project-tools package root.\");\n\t\t}\n\t\tcurrentDir = parentDir;\n\t}\n}\n\nexport const PROJECT_TOOLS_PACKAGE_ROOT = resolvePackageRoot(__dirname);\nexport const TEMPLATE_ROOT = path.join(PROJECT_TOOLS_PACKAGE_ROOT, \"templates\");\nexport const SHARED_TEMPLATE_ROOT = path.join(TEMPLATE_ROOT, \"_shared\");\nexport const SHARED_BASE_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"base\");\nexport const SHARED_COMPOUND_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"compound\");\nexport const SHARED_PERSISTENCE_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"persistence\");\nexport const SHARED_PRESET_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"presets\");\nexport const SHARED_REST_HELPER_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"rest-helpers\");\nexport const SHARED_MIGRATION_UI_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"migration-ui\");\n/**\n * Shared workspace template overlay root used by workspace scaffolding flows.\n */\nexport const SHARED_WORKSPACE_TEMPLATE_ROOT = path.join(SHARED_TEMPLATE_ROOT, \"workspace\");\nexport const SHARED_TEST_PRESET_TEMPLATE_ROOT = path.join(SHARED_PRESET_TEMPLATE_ROOT, \"test-preset\");\nexport const SHARED_WP_ENV_PRESET_TEMPLATE_ROOT = path.join(SHARED_PRESET_TEMPLATE_ROOT, \"wp-env\");\nexport const BUILTIN_TEMPLATE_IDS = [\n\t\"basic\",\n\t\"interactivity\",\n\t\"persistence\",\n\t\"compound\",\n\t\"query-loop\",\n] as const;\nexport const OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE = \"@wp-typia/create-workspace-template\";\nexport type BuiltInTemplateId = (typeof BUILTIN_TEMPLATE_IDS)[number];\nexport type PersistencePolicy = \"authenticated\" | \"public\";\n\nexport interface TemplateDefinition {\n\tid: string;\n\tdescription: string;\n\tdefaultCategory: string;\n\tfeatures: string[];\n\ttemplateDir: string;\n}\n\nexport const TEMPLATE_REGISTRY = Object.freeze<TemplateDefinition[]>([\n\t{\n\t\tid: \"basic\",\n\t\tdescription: \"A lightweight WordPress block with Typia validation\",\n\t\tdefaultCategory: getBuiltInTemplateMetadataDefaults(\"basic\").category,\n\t\tfeatures: [\"Type-safe attributes\", \"Runtime validation\", \"Minimal setup\"],\n\t\ttemplateDir: path.join(TEMPLATE_ROOT, \"basic\"),\n\t},\n\t{\n\t\tid: \"interactivity\",\n\t\tdescription: \"An interactive WordPress block with Typia validation and Interactivity API\",\n\t\tdefaultCategory: getBuiltInTemplateMetadataDefaults(\"interactivity\").category,\n\t\tfeatures: [\"Interactivity API\", \"Client-side state\", \"Event handling\"],\n\t\ttemplateDir: path.join(TEMPLATE_ROOT, \"interactivity\"),\n\t},\n\t{\n\t\tid: \"persistence\",\n\t\tdescription: \"A persistence-aware WordPress block with Typia validation, typed REST contracts, and selectable public or authenticated write policies\",\n\t\tdefaultCategory: getBuiltInTemplateMetadataDefaults(\"persistence\").category,\n\t\tfeatures: [\"Interactivity API\", \"Typed REST client\", \"Schema sync\", \"Persistence policies\"],\n\t\ttemplateDir: path.join(TEMPLATE_ROOT, \"persistence\"),\n\t},\n\t{\n\t\tid: \"compound\",\n\t\tdescription: \"A parent-and-child WordPress block scaffold with InnerBlocks, optional persistence wiring, and hidden implementation child blocks\",\n\t\tdefaultCategory: getBuiltInTemplateMetadataDefaults(\"compound\").category,\n\t\tfeatures: [\"InnerBlocks\", \"Hidden child blocks\", \"Optional persistence layer\"],\n\t\ttemplateDir: path.join(TEMPLATE_ROOT, \"compound\"),\n\t},\n\t{\n\t\tid: \"query-loop\",\n\t\tdescription: \"A Query Loop block variation scaffold with stable namespace-based identity, inline starter layout, connected pattern presets, custom query seams, and runtime parity hooks\",\n\t\tdefaultCategory: getBuiltInTemplateMetadataDefaults(\"query-loop\").category,\n\t\tfeatures: [\"core/query variation\", \"Default innerBlocks\", \"Connected patterns\", \"Custom query hooks\", \"Runtime parity hooks\", \"Allowed controls\"],\n\t\ttemplateDir: path.join(TEMPLATE_ROOT, \"query-loop\"),\n\t},\n\t{\n\t\tid: OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE,\n\t\tdescription: \"The official empty workspace template that powers `wp-typia add ...` workflows\",\n\t\tdefaultCategory: \"workspace\",\n\t\tfeatures: [\"Workspace inventory\", \"Add block workflows\", \"Workspace doctor and migrate\"],\n\t\ttemplateDir: path.resolve(PROJECT_TOOLS_PACKAGE_ROOT, \"..\", \"create-workspace-template\"),\n\t},\n]);\n\nexport const TEMPLATE_IDS = [...BUILTIN_TEMPLATE_IDS] as BuiltInTemplateId[];\n\nexport function isBuiltInTemplateId(templateId: string): templateId is BuiltInTemplateId {\n\treturn (BUILTIN_TEMPLATE_IDS as readonly string[]).includes(templateId);\n}\n\nexport function listTemplates(): readonly TemplateDefinition[] {\n\treturn TEMPLATE_REGISTRY;\n}\n\nexport function getTemplateById(templateId: string): TemplateDefinition {\n\tconst template = TEMPLATE_REGISTRY.find((entry) => entry.id === templateId);\n\tif (!template) {\n\t\tthrow new Error(\n\t\t\t`Unknown template \"${templateId}\". Expected one of: ${[\n\t\t\t\t...TEMPLATE_IDS,\n\t\t\t\tOFFICIAL_WORKSPACE_TEMPLATE_PACKAGE,\n\t\t\t].join(\", \")}`,\n\t\t);\n\t}\n\treturn template;\n}\n\nexport function getTemplateSelectOptions(): Array<{\n\tlabel: string;\n\tvalue: TemplateDefinition[\"id\"];\n\thint: string;\n}> {\n\treturn TEMPLATE_REGISTRY.map((template) => ({\n\t\tlabel: template.id,\n\t\tvalue: template.id,\n\t\thint: template.features.join(\", \"),\n\t}));\n}\n",
6
+ "/**\n * Internal built-in template metadata defaults used by scaffold rendering.\n */\nexport const BUILTIN_BLOCK_METADATA_VERSION = \"0.1.0\";\n\n/**\n * Built-in parent block metadata defaults keyed by template id.\n */\nexport const BUILTIN_TEMPLATE_METADATA_DEFAULTS = Object.freeze({\n\tbasic: Object.freeze({\n\t\tcategory: \"text\",\n\t\ticon: \"smiley\",\n\t}),\n\tinteractivity: Object.freeze({\n\t\tcategory: \"widgets\",\n\t\ticon: \"smiley\",\n\t}),\n\tpersistence: Object.freeze({\n\t\tcategory: \"widgets\",\n\t\ticon: \"database\",\n\t}),\n\tcompound: Object.freeze({\n\t\tcategory: \"widgets\",\n\t\ticon: \"screenoptions\",\n\t}),\n\t\"query-loop\": Object.freeze({\n\t\tcategory: \"widgets\",\n\t\ticon: \"query-pagination\",\n\t}),\n});\n\n/**\n * Shared hidden child block metadata defaults for compound scaffolds.\n */\nexport const COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS = Object.freeze({\n\tcategory: \"widgets\",\n\ticon: \"excerpt-view\",\n});\n\n/**\n * Legacy built-in template ids that were removed in favor of persistence modes.\n */\nexport const REMOVED_BUILTIN_TEMPLATE_IDS = [\"data\", \"persisted\"] as const;\n/**\n * Union of removed built-in template ids accepted by compatibility checks.\n */\nexport type RemovedBuiltInTemplateId = (typeof REMOVED_BUILTIN_TEMPLATE_IDS)[number];\n\n/**\n * Returns the metadata defaults for a built-in scaffold template id.\n *\n * @param templateId Built-in template id whose metadata defaults should be read.\n * @returns The stable category/icon defaults used by scaffold rendering.\n */\nexport function getBuiltInTemplateMetadataDefaults(\n\ttemplateId: keyof typeof BUILTIN_TEMPLATE_METADATA_DEFAULTS,\n) {\n\treturn BUILTIN_TEMPLATE_METADATA_DEFAULTS[templateId];\n}\n\n/**\n * Checks whether a template id points at a removed built-in scaffold.\n *\n * @param templateId Template id supplied to scaffold resolution.\n * @returns True when the template id is one of the removed legacy built-ins.\n */\nexport function isRemovedBuiltInTemplateId(\n\ttemplateId: string,\n): templateId is RemovedBuiltInTemplateId {\n\treturn (REMOVED_BUILTIN_TEMPLATE_IDS as readonly string[]).includes(templateId);\n}\n\n/**\n * Builds the stable recovery guidance shown for removed built-in template ids.\n *\n * @param templateId Removed template id, where `data` maps to the public policy and\n * `persisted` maps to the authenticated policy.\n * @returns A user-facing error string in the form\n * `Built-in template \"<id>\" was removed. Use --template persistence --persistence-policy <policy> instead.`\n */\nexport function getRemovedBuiltInTemplateMessage(templateId: RemovedBuiltInTemplateId): string {\n\treturn `Built-in template \"${templateId}\" was removed. Use --template persistence --persistence-policy ${\n\t\ttemplateId === \"data\" ? \"public\" : \"authenticated\"\n\t} instead.`;\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "4B25E5AE2392289964756E2164756E21",
10
+ "names": []
11
+ }