wp-typia 0.19.0 → 0.20.0

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 (42) hide show
  1. package/README.md +4 -2
  2. package/dist-bunli/.bunli/commands.gen.js +1843 -1216
  3. package/dist-bunli/.bunli/commands.gen.js.map +36 -33
  4. package/dist-bunli/cli-03j0axbt.js +163 -0
  5. package/dist-bunli/cli-03j0axbt.js.map +11 -0
  6. package/dist-bunli/{cli-7svz19s1.js → cli-2ybmc22r.js} +370 -86
  7. package/dist-bunli/{cli-7svz19s1.js.map → cli-2ybmc22r.js.map} +15 -14
  8. package/dist-bunli/cli-7yg38ht2.js +427 -0
  9. package/dist-bunli/cli-7yg38ht2.js.map +12 -0
  10. package/dist-bunli/{cli-yw0mq0wq.js → cli-93wd227r.js} +108 -3
  11. package/dist-bunli/cli-93wd227r.js.map +10 -0
  12. package/dist-bunli/{cli-kan7a6db.js → cli-a6dwqnhq.js} +24 -2
  13. package/dist-bunli/cli-a6dwqnhq.js.map +11 -0
  14. package/dist-bunli/{cli-add-j2c81sh1.js → cli-add-pq6wm87p.js} +16 -9
  15. package/dist-bunli/{cli-add-j2c81sh1.js.map → cli-add-pq6wm87p.js.map} +3 -3
  16. package/dist-bunli/{cli-diagnostics-c65hhyhx.js → cli-diagnostics-e5gxeprp.js} +8 -4
  17. package/dist-bunli/{cli-diagnostics-c65hhyhx.js.map → cli-diagnostics-e5gxeprp.js.map} +1 -1
  18. package/dist-bunli/{cli-doctor-hft0wr0e.js → cli-doctor-qk6fwpds.js} +14 -13
  19. package/dist-bunli/{cli-doctor-hft0wr0e.js.map → cli-doctor-qk6fwpds.js.map} +3 -3
  20. package/dist-bunli/{cli-572d6g4m.js → cli-hv2yedw2.js} +2 -157
  21. package/dist-bunli/{cli-572d6g4m.js.map → cli-hv2yedw2.js.map} +4 -6
  22. package/dist-bunli/{cli-scaffold-vcg6wem5.js → cli-scaffold-s3nhwe7x.js} +9 -7
  23. package/dist-bunli/cli-scaffold-s3nhwe7x.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-37n1za5q.js +2485 -0
  32. package/dist-bunli/command-list-37n1za5q.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-kan7a6db.js.map +0 -11
  39. package/dist-bunli/cli-scaffold-vcg6wem5.js.map +0 -10
  40. package/dist-bunli/cli-wtrvnce5.js.map +0 -10
  41. package/dist-bunli/cli-yw0mq0wq.js.map +0 -10
  42. /package/dist-bunli/{cli-templates-4qxszbmc.js.map → cli-templates-j65r4k9v.js.map} +0 -0
package/dist-bunli/cli.js CHANGED
@@ -1,38 +1,42 @@
1
1
  // @bun
2
+ import {
3
+ ADD_OPTION_METADATA,
4
+ CREATE_OPTION_METADATA,
5
+ GLOBAL_OPTION_METADATA,
6
+ MIGRATE_OPTION_METADATA,
7
+ TEMPLATES_OPTION_METADATA,
8
+ WP_TYPIA_CONFIG_SOURCES,
9
+ buildCommandOptionParser,
10
+ collectOptionNamesByType,
11
+ createPlugin,
12
+ loadWpTypiaUserConfig,
13
+ loadWpTypiaUserConfigFromSource,
14
+ mergeWpTypiaUserConfig,
15
+ package_default
16
+ } from "./cli-7yg38ht2.js";
17
+ import"./cli-03j0axbt.js";
2
18
  import {
3
19
  GLOBAL_FLAGS,
4
20
  Result,
5
21
  TaggedError,
6
22
  createCLI,
7
- createKeyMatcher,
8
23
  deepMerge,
9
24
  defineCommand,
10
25
  defineConfig,
11
26
  defineGroup,
12
- exports_external,
13
- option,
14
- require_jsx_dev_runtime,
15
- require_react,
16
- useKeyboard,
17
- useRuntime
18
- } from "./cli-572d6g4m.js";
27
+ exports_external
28
+ } from "./cli-hv2yedw2.js";
19
29
  import"./cli-ac2ebaf8.js";
20
30
  import"./cli-6v0pcxw6.js";
21
31
  import {
22
- formatPackageExecCommand
23
- } from "./cli-1b5jx6j9.js";
24
- import {
25
- __require,
26
- __toESM
32
+ __require
27
33
  } from "./cli-xnn9xjcy.js";
28
34
 
29
35
  // src/cli.ts
30
- import fs6 from "fs";
31
- import { fileURLToPath as fileURLToPath2 } from "url";
32
- // ../../node_modules/.bun/@bunli+core@0.9.0+44deef6f8e4a2f18/node_modules/@bunli/core/src/plugin/create.ts
33
- function createPlugin(input) {
34
- return input;
35
- }
36
+ import fs from "fs";
37
+ import path2 from "path";
38
+ import { fileURLToPath } from "url";
39
+
36
40
  // ../../node_modules/.bun/@bunli+plugin-ai-detect@0.6.4+44deef6f8e4a2f18/node_modules/@bunli/plugin-ai-detect/src/index.ts
37
41
  var AI_AGENTS = [
38
42
  {
@@ -1025,8 +1029,8 @@ class Command {
1025
1029
  aliasStr = undefined;
1026
1030
  isBoolean = true;
1027
1031
  }
1028
- const option2 = new Option(this, value, description, handler, aliasStr, isBoolean);
1029
- this.options.set(value, option2);
1032
+ const option = new Option(this, value, description, handler, aliasStr, isBoolean);
1033
+ this.options.set(value, option);
1030
1034
  return this;
1031
1035
  }
1032
1036
  argument(name, handler, variadic = false) {
@@ -1063,9 +1067,9 @@ class RootCommand extends Command {
1063
1067
  isBoolean = rootOption.isBoolean ?? false;
1064
1068
  } else {
1065
1069
  for (const [, command] of this.commands) {
1066
- const option2 = this.findOption(command, arg);
1067
- if (option2) {
1068
- isBoolean = option2.isBoolean ?? false;
1070
+ const option = this.findOption(command, arg);
1071
+ if (option) {
1072
+ isBoolean = option.isBoolean ?? false;
1069
1073
  break;
1070
1074
  }
1071
1075
  }
@@ -1103,15 +1107,15 @@ class RootCommand extends Command {
1103
1107
  return true;
1104
1108
  }
1105
1109
  if (lastPrevArg?.startsWith("-")) {
1106
- let option2 = this.findOption(this, lastPrevArg);
1107
- if (!option2) {
1110
+ let option = this.findOption(this, lastPrevArg);
1111
+ if (!option) {
1108
1112
  for (const [, command] of this.commands) {
1109
- option2 = this.findOption(command, lastPrevArg);
1110
- if (option2)
1113
+ option = this.findOption(command, lastPrevArg);
1114
+ if (option)
1111
1115
  break;
1112
1116
  }
1113
1117
  }
1114
- if (option2 && option2.isBoolean) {
1118
+ if (option && option.isBoolean) {
1115
1119
  return false;
1116
1120
  }
1117
1121
  return true;
@@ -1127,16 +1131,16 @@ class RootCommand extends Command {
1127
1131
  const [flag] = toComplete.split("=");
1128
1132
  optionName = flag;
1129
1133
  } else if (lastPrevArg?.startsWith("-")) {
1130
- const option2 = this.findOption(command, lastPrevArg);
1131
- if (option2 && !option2.isBoolean) {
1134
+ const option = this.findOption(command, lastPrevArg);
1135
+ if (option && !option.isBoolean) {
1132
1136
  optionName = lastPrevArg;
1133
1137
  }
1134
1138
  }
1135
1139
  if (optionName) {
1136
- const option2 = this.findOption(command, optionName);
1137
- if (option2?.handler) {
1140
+ const option = this.findOption(command, optionName);
1141
+ if (option?.handler) {
1138
1142
  const suggestions = [];
1139
- option2.handler.call(option2, (value, description) => suggestions.push({ value, description }), command.options);
1143
+ option.handler.call(option, (value, description) => suggestions.push({ value, description }), command.options);
1140
1144
  this.completions = suggestions;
1141
1145
  }
1142
1146
  return;
@@ -1144,16 +1148,16 @@ class RootCommand extends Command {
1144
1148
  if (toComplete.startsWith("-")) {
1145
1149
  const isShortFlag = toComplete.startsWith("-") && !toComplete.startsWith("--");
1146
1150
  const cleanToComplete = toComplete.replace(/^-+/, "");
1147
- for (const [name, option2] of command.options) {
1148
- if (isShortFlag && option2.alias && `-${option2.alias}`.startsWith(toComplete)) {
1151
+ for (const [name, option] of command.options) {
1152
+ if (isShortFlag && option.alias && `-${option.alias}`.startsWith(toComplete)) {
1149
1153
  this.completions.push({
1150
- value: `-${option2.alias}`,
1151
- description: option2.description
1154
+ value: `-${option.alias}`,
1155
+ description: option.description
1152
1156
  });
1153
1157
  } else if (!isShortFlag && name.startsWith(cleanToComplete)) {
1154
1158
  this.completions.push({
1155
1159
  value: `--${name}`,
1156
- description: option2.description
1160
+ description: option.description
1157
1161
  });
1158
1162
  }
1159
1163
  }
@@ -1161,12 +1165,12 @@ class RootCommand extends Command {
1161
1165
  }
1162
1166
  findOption(command, optionName) {
1163
1167
  const normalized = this.normalizeOptionToken(optionName);
1164
- let option2 = command.options.get(optionName);
1165
- if (option2)
1166
- return option2;
1167
- option2 = command.options.get(normalized);
1168
- if (option2)
1169
- return option2;
1168
+ let option = command.options.get(optionName);
1169
+ if (option)
1170
+ return option;
1171
+ option = command.options.get(normalized);
1172
+ if (option)
1173
+ return option;
1170
1174
  for (const [_name, opt] of command.options) {
1171
1175
  if (opt.alias === normalized) {
1172
1176
  return opt;
@@ -1251,15 +1255,15 @@ class RootCommand extends Command {
1251
1255
  this.handleFlagCompletion(matchedCommand, previousArgs, toComplete, lastPrevArg);
1252
1256
  } else {
1253
1257
  if (lastPrevArg?.startsWith("-") && toComplete === "" && endsWithSpace) {
1254
- let option2 = this.findOption(this, lastPrevArg);
1255
- if (!option2) {
1258
+ let option = this.findOption(this, lastPrevArg);
1259
+ if (!option) {
1256
1260
  for (const [, command] of this.commands) {
1257
- option2 = this.findOption(command, lastPrevArg);
1258
- if (option2)
1261
+ option = this.findOption(command, lastPrevArg);
1262
+ if (option)
1259
1263
  break;
1260
1264
  }
1261
1265
  }
1262
- if (option2 && option2.isBoolean) {
1266
+ if (option && option.isBoolean) {
1263
1267
  this.complete(toComplete);
1264
1268
  return;
1265
1269
  }
@@ -2149,7 +2153,7 @@ var skillsPlugin = createPlugin((options = {}) => ({
2149
2153
  },
2150
2154
  async handler({ flags, colors, output }) {
2151
2155
  const typedFlags = flags;
2152
- const { syncSkills } = await import("./sync-x91y9jtv.js");
2156
+ const { syncSkills } = await import("./sync-k2k8svyc.js");
2153
2157
  const { detectAgents, builtinAgents } = await import("./agents-91fpdyyt.js");
2154
2158
  const allAgents = options.agents ? [...builtinAgents, ...options.agents] : builtinAgents;
2155
2159
  const detected = detectAgents(allAgents);
@@ -2219,95 +2223,6 @@ var skillsPlugin = createPlugin((options = {}) => ({
2219
2223
  context.registerCommand(skillsGroup);
2220
2224
  }
2221
2225
  }));
2222
- // package.json
2223
- var package_default = {
2224
- name: "wp-typia",
2225
- version: "0.19.0",
2226
- description: "Canonical CLI package for wp-typia scaffolding and project workflows",
2227
- packageManager: "bun@1.3.11",
2228
- type: "module",
2229
- bin: {
2230
- "wp-typia": "bin/wp-typia.js"
2231
- },
2232
- files: [
2233
- "bin/",
2234
- "dist-bunli/",
2235
- "README.md",
2236
- "package.json"
2237
- ],
2238
- scripts: {
2239
- generate: "bun scripts/generate-bunli-metadata.ts",
2240
- build: "bun run generate && bun scripts/build-bunli-runtime.ts",
2241
- "bunli:generate": "bun run generate",
2242
- "bunli:build": "bun run build",
2243
- "bunli:dev": "bun src/cli.ts",
2244
- "bunli:test": "bun test tests/*.test.ts",
2245
- dev: "bun run build && node bin/wp-typia.js",
2246
- test: "cd ../wp-typia-project-tools && bun run build && cd ../wp-typia && bun run build && bun test tests/*.test.ts",
2247
- "test:coverage": "cd ../wp-typia-project-tools && bun run build && cd ../wp-typia && bun run build && bun test tests/*.test.ts --coverage --coverage-reporter=lcov --coverage-dir=coverage",
2248
- clean: "rm -rf .bunli dist-bunli",
2249
- prepack: "bun run build"
2250
- },
2251
- keywords: [
2252
- "wordpress",
2253
- "gutenberg",
2254
- "typia",
2255
- "cli",
2256
- "scaffold",
2257
- "templates"
2258
- ],
2259
- author: "imjlk",
2260
- license: "GPL-2.0-or-later",
2261
- repository: {
2262
- type: "git",
2263
- url: "git+https://github.com/imjlk/wp-typia.git",
2264
- directory: "packages/wp-typia"
2265
- },
2266
- bugs: {
2267
- url: "https://github.com/imjlk/wp-typia/issues"
2268
- },
2269
- homepage: "https://github.com/imjlk/wp-typia/tree/main/packages/wp-typia#readme",
2270
- publishConfig: {
2271
- access: "public"
2272
- },
2273
- engines: {
2274
- bun: ">=1.3.11",
2275
- node: ">=20.0.0",
2276
- npm: ">=10.0.0"
2277
- },
2278
- dependencies: {
2279
- "@bunli/core": "0.9.0",
2280
- "@bunli/plugin-ai-detect": "0.6.4",
2281
- "@bunli/plugin-completions": "0.3.5",
2282
- "@bunli/plugin-config": "0.4.4",
2283
- "@bunli/plugin-mcp": "0.2.5",
2284
- "@bunli/plugin-skills": "0.1.0",
2285
- "@bunli/runtime": "0.3.1",
2286
- "@bunli/tui": "0.6.0",
2287
- "@bunli/utils": "0.6.0",
2288
- "@wp-typia/api-client": "^0.4.5",
2289
- "@wp-typia/project-tools": "0.19.0",
2290
- "better-result": "^2.7.0",
2291
- react: "^19.2.5",
2292
- "react-dom": "^19.2.5",
2293
- zod: "4.3.6"
2294
- },
2295
- devDependencies: {
2296
- "@bunli/generator": "0.6.5",
2297
- "@bunli/test": "0.6.0",
2298
- bunli: "0.9.0",
2299
- typescript: "^5.9.2"
2300
- },
2301
- optionalDependencies: {
2302
- "@opentui/core-darwin-arm64": "0.1.97",
2303
- "@opentui/core-darwin-x64": "0.1.97",
2304
- "@opentui/core-linux-arm64": "0.1.97",
2305
- "@opentui/core-linux-x64": "0.1.97",
2306
- "@opentui/core-win32-arm64": "0.1.97",
2307
- "@opentui/core-win32-x64": "0.1.97"
2308
- }
2309
- };
2310
-
2311
2226
  // bunli.config.ts
2312
2227
  var bunliConfig = defineConfig({
2313
2228
  name: package_default.name,
@@ -2337,231 +2252,6 @@ var bunliConfig = defineConfig({
2337
2252
 
2338
2253
  // src/command-contract.ts
2339
2254
  import path from "path";
2340
-
2341
- // src/command-option-metadata.ts
2342
- var CREATE_OPTION_METADATA = {
2343
- "alternate-render-targets": {
2344
- description: "Comma-separated alternate render targets for dynamic block scaffolds (email,mjml,plain-text).",
2345
- type: "string"
2346
- },
2347
- "data-storage": {
2348
- description: "Persistence storage mode for persistence-capable templates.",
2349
- type: "string"
2350
- },
2351
- "dry-run": {
2352
- argumentKind: "flag",
2353
- description: "Preview scaffold output without writing files to the target directory.",
2354
- type: "boolean"
2355
- },
2356
- "external-layer-id": {
2357
- description: "Explicit layer id when an external layer package exposes multiple selectable layers.",
2358
- type: "string"
2359
- },
2360
- "external-layer-source": {
2361
- description: "Local path, GitHub locator, or npm package that exposes wp-typia.layers.json for built-in templates.",
2362
- type: "string"
2363
- },
2364
- "inner-blocks-preset": {
2365
- description: "Compound-only InnerBlocks preset (freeform, ordered, horizontal, locked-structure).",
2366
- type: "string"
2367
- },
2368
- namespace: {
2369
- description: "Override the default block namespace.",
2370
- type: "string"
2371
- },
2372
- "no-install": {
2373
- argumentKind: "flag",
2374
- description: "Skip dependency installation after scaffold.",
2375
- type: "boolean"
2376
- },
2377
- "package-manager": {
2378
- description: "Package manager to use for install and scripts.",
2379
- short: "p",
2380
- type: "string"
2381
- },
2382
- "persistence-policy": {
2383
- description: "Authenticated or public write policy for persistence-capable templates.",
2384
- type: "string"
2385
- },
2386
- "php-prefix": {
2387
- description: "Custom PHP symbol prefix.",
2388
- type: "string"
2389
- },
2390
- "query-post-type": {
2391
- description: "Default post type assigned to Query Loop variation scaffolds.",
2392
- type: "string"
2393
- },
2394
- template: {
2395
- description: "Template id or external template package.",
2396
- short: "t",
2397
- type: "string"
2398
- },
2399
- "text-domain": {
2400
- description: "Custom text domain for the generated project.",
2401
- type: "string"
2402
- },
2403
- variant: {
2404
- description: "Optional template variant identifier.",
2405
- type: "string"
2406
- },
2407
- "with-migration-ui": {
2408
- argumentKind: "flag",
2409
- description: "Enable migration UI support when the template supports it.",
2410
- type: "boolean"
2411
- },
2412
- "with-test-preset": {
2413
- argumentKind: "flag",
2414
- description: "Include the Playwright smoke-test preset.",
2415
- type: "boolean"
2416
- },
2417
- "with-wp-env": {
2418
- argumentKind: "flag",
2419
- description: "Include a local wp-env preset.",
2420
- type: "boolean"
2421
- },
2422
- yes: {
2423
- argumentKind: "flag",
2424
- description: "Accept defaults without prompt fallbacks.",
2425
- short: "y",
2426
- type: "boolean"
2427
- }
2428
- };
2429
- var ADD_OPTION_METADATA = {
2430
- "alternate-render-targets": {
2431
- description: "Comma-separated alternate render targets for dynamic block scaffolds (email,mjml,plain-text).",
2432
- type: "string"
2433
- },
2434
- anchor: {
2435
- description: "Anchor block name for hooked-block workflows.",
2436
- type: "string"
2437
- },
2438
- block: {
2439
- description: "Target block slug for variation workflows.",
2440
- type: "string"
2441
- },
2442
- "data-storage": {
2443
- description: "Persistence storage mode for persistence-capable templates.",
2444
- type: "string"
2445
- },
2446
- "dry-run": {
2447
- argumentKind: "flag",
2448
- description: "Preview workspace file updates without writing them.",
2449
- type: "boolean"
2450
- },
2451
- "external-layer-id": {
2452
- description: "Explicit layer id when an external layer package exposes multiple selectable layers.",
2453
- type: "string"
2454
- },
2455
- "external-layer-source": {
2456
- description: "Local path, GitHub locator, or npm package that exposes wp-typia.layers.json for built-in block templates.",
2457
- type: "string"
2458
- },
2459
- "inner-blocks-preset": {
2460
- description: "Compound-only InnerBlocks preset (freeform, ordered, horizontal, locked-structure).",
2461
- type: "string"
2462
- },
2463
- methods: {
2464
- description: "Comma-separated REST resource methods for rest-resource workflows.",
2465
- type: "string"
2466
- },
2467
- namespace: {
2468
- description: "REST namespace for rest-resource workflows.",
2469
- type: "string"
2470
- },
2471
- "persistence-policy": {
2472
- description: "Persistence write policy for persistence-capable templates.",
2473
- type: "string"
2474
- },
2475
- position: {
2476
- description: "Hook position for hooked-block workflows.",
2477
- type: "string"
2478
- },
2479
- slot: {
2480
- description: "Document editor shell slot for editor-plugin workflows.",
2481
- type: "string"
2482
- },
2483
- template: {
2484
- description: "Built-in block family for the new block.",
2485
- type: "string"
2486
- }
2487
- };
2488
- var MIGRATE_OPTION_METADATA = {
2489
- all: {
2490
- argumentKind: "flag",
2491
- description: "Run across every configured migration version and block target.",
2492
- type: "boolean"
2493
- },
2494
- "current-migration-version": {
2495
- description: "Current migration version label for `migrate init`.",
2496
- type: "string"
2497
- },
2498
- force: {
2499
- argumentKind: "flag",
2500
- description: "Force overwrite behavior where supported.",
2501
- type: "boolean"
2502
- },
2503
- "from-migration-version": {
2504
- description: "Source migration version label.",
2505
- type: "string"
2506
- },
2507
- iterations: {
2508
- description: "Iteration count for `migrate fuzz`.",
2509
- type: "string"
2510
- },
2511
- "migration-version": {
2512
- description: "Version label to capture with `migrate snapshot`.",
2513
- type: "string"
2514
- },
2515
- seed: {
2516
- description: "Deterministic fuzz seed.",
2517
- type: "string"
2518
- },
2519
- "to-migration-version": {
2520
- description: "Target migration version label.",
2521
- type: "string"
2522
- }
2523
- };
2524
- var TEMPLATES_OPTION_METADATA = {
2525
- id: {
2526
- description: "Template id for `templates inspect`.",
2527
- type: "string"
2528
- }
2529
- };
2530
- var GLOBAL_OPTION_METADATA = {
2531
- config: {
2532
- description: "Config override file path.",
2533
- short: "c",
2534
- type: "string"
2535
- },
2536
- format: {
2537
- description: "Output format for supported commands.",
2538
- type: "string"
2539
- },
2540
- id: {
2541
- description: "Template id for top-level `templates inspect` convenience.",
2542
- type: "string"
2543
- },
2544
- "output-dir": {
2545
- description: "Output directory for generated MCP metadata.",
2546
- type: "string"
2547
- }
2548
- };
2549
- function buildCommandOptions(metadata) {
2550
- return Object.fromEntries(Object.entries(metadata).map(([name, option2]) => [
2551
- name,
2552
- {
2553
- ...option2.argumentKind ? { argumentKind: option2.argumentKind } : {},
2554
- description: option2.description,
2555
- schema: option2.type === "boolean" ? exports_external.boolean().default(false) : exports_external.string().optional(),
2556
- ...option2.short ? { short: option2.short } : {}
2557
- }
2558
- ]));
2559
- }
2560
- function collectOptionNamesByType(metadata, type) {
2561
- return Object.entries(metadata).filter(([, option2]) => option2.type === type).map(([name]) => name);
2562
- }
2563
-
2564
- // src/command-contract.ts
2565
2255
  var WP_TYPIA_CANONICAL_CREATE_USAGE = "wp-typia create <project-dir>";
2566
2256
  var WP_TYPIA_RESERVED_TOP_LEVEL_COMMAND_NAMES = [
2567
2257
  "create",
@@ -2577,6 +2267,7 @@ var WP_TYPIA_RESERVED_TOP_LEVEL_COMMAND_NAMES = [
2577
2267
  "completions",
2578
2268
  "complete"
2579
2269
  ];
2270
+ var SHARED_OPTION_PARSER = buildCommandOptionParser(ADD_OPTION_METADATA, GLOBAL_OPTION_METADATA, CREATE_OPTION_METADATA, MIGRATE_OPTION_METADATA, TEMPLATES_OPTION_METADATA);
2580
2271
  var STRING_OPTION_NAMES_BY_COMMAND = {
2581
2272
  add: new Set(collectOptionNamesByType(ADD_OPTION_METADATA, "string")),
2582
2273
  create: new Set(collectOptionNamesByType(CREATE_OPTION_METADATA, "string")),
@@ -2584,13 +2275,7 @@ var STRING_OPTION_NAMES_BY_COMMAND = {
2584
2275
  templates: new Set(collectOptionNamesByType(TEMPLATES_OPTION_METADATA, "string"))
2585
2276
  };
2586
2277
  var GLOBAL_STRING_OPTION_NAMES = new Set(collectOptionNamesByType(GLOBAL_OPTION_METADATA, "string"));
2587
- var SHORT_OPTION_NAMES_WITH_VALUES = new Set(Object.values({
2588
- ...ADD_OPTION_METADATA,
2589
- ...GLOBAL_OPTION_METADATA,
2590
- ...CREATE_OPTION_METADATA,
2591
- ...MIGRATE_OPTION_METADATA,
2592
- ...TEMPLATES_OPTION_METADATA
2593
- }).filter((option2) => option2.type === "string").flatMap((option2) => ("short" in option2) && typeof option2.short === "string" ? [option2.short] : []));
2278
+ var SHORT_OPTION_NAMES_WITH_VALUES = new Set([...SHARED_OPTION_PARSER.shortFlagMap.entries()].filter(([, option]) => option.type === "string").map(([short]) => short));
2594
2279
  function isLongOptionValueConsumer(optionName) {
2595
2280
  if (GLOBAL_STRING_OPTION_NAMES.has(optionName)) {
2596
2281
  return true;
@@ -2730,2513 +2415,90 @@ function normalizeWpTypiaArgv(argv) {
2730
2415
  return normalizedArgv;
2731
2416
  }
2732
2417
 
2733
- // src/commands/add.ts
2734
- var import_react34 = __toESM(require_react(), 1);
2735
-
2736
- // src/config.ts
2737
- import fs from "fs/promises";
2738
- import os from "os";
2739
- import path2 from "path";
2740
- import { isPlainObject as isRecord } from "@wp-typia/api-client/runtime-primitives";
2741
- var WP_TYPIA_CONFIG_SOURCES = [
2742
- "~/.config/wp-typia/config.json",
2743
- ".wp-typiarc",
2744
- ".wp-typiarc.json"
2745
- ];
2746
- function deepMerge2(base, incoming) {
2747
- const merged = { ...base };
2748
- for (const [key, value] of Object.entries(incoming)) {
2749
- if (Array.isArray(value)) {
2750
- merged[key] = value.slice();
2751
- continue;
2752
- }
2753
- if (isRecord(value) && isRecord(merged[key])) {
2754
- merged[key] = deepMerge2(merged[key], value);
2418
+ // src/config-override.ts
2419
+ function extractWpTypiaConfigOverride(argv) {
2420
+ const nextArgv = [];
2421
+ let configOverridePath;
2422
+ for (let index = 0;index < argv.length; index += 1) {
2423
+ const arg = argv[index];
2424
+ if (!arg) {
2755
2425
  continue;
2756
2426
  }
2757
- merged[key] = value;
2758
- }
2759
- return merged;
2760
- }
2761
- async function readJsonFile(filePath) {
2762
- try {
2763
- const source = await fs.readFile(filePath, "utf8");
2764
- const parsed = JSON.parse(source);
2765
- return isRecord(parsed) ? parsed : null;
2766
- } catch (error) {
2767
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
2768
- return null;
2769
- }
2770
- throw error;
2771
- }
2772
- }
2773
- function resolveConfigPath(cwd, source) {
2774
- if (source.startsWith("~/")) {
2775
- return path2.join(os.homedir(), source.slice(2));
2776
- }
2777
- return path2.resolve(cwd, source);
2778
- }
2779
- function mergeWpTypiaUserConfig(base, incoming) {
2780
- return deepMerge2(base, incoming);
2781
- }
2782
- async function loadWpTypiaUserConfigFromSource(cwd, source) {
2783
- const config = await readJsonFile(resolveConfigPath(cwd, source));
2784
- return config ?? {};
2785
- }
2786
- async function loadWpTypiaUserConfig(cwd) {
2787
- let merged = {};
2788
- for (const source of WP_TYPIA_CONFIG_SOURCES) {
2789
- const configPath = resolveConfigPath(cwd, source);
2790
- const config = await readJsonFile(configPath);
2791
- if (config) {
2792
- merged = deepMerge2(merged, config);
2793
- }
2794
- }
2795
- const packageJson = await readJsonFile(path2.join(cwd, "package.json"));
2796
- if (packageJson && isRecord(packageJson["wp-typia"])) {
2797
- merged = deepMerge2(merged, packageJson["wp-typia"]);
2798
- }
2799
- return merged;
2800
- }
2801
- function getCreateDefaults(config) {
2802
- return config.create ?? {};
2803
- }
2804
- function getAddBlockDefaults(config) {
2805
- return config.add?.block ?? {};
2806
- }
2807
- function getMcpSchemaSources(config) {
2808
- return config.mcp?.schemaSources ?? [];
2809
- }
2810
-
2811
- // src/render-loader.ts
2812
- import fs2 from "fs";
2813
- import { fileURLToPath } from "url";
2814
- function resolveBundledModuleHref(baseUrl, candidates) {
2815
- for (const candidate of candidates) {
2816
- const url = new URL(candidate, baseUrl);
2817
- if (fs2.existsSync(fileURLToPath(url))) {
2818
- return url.href;
2427
+ if (arg === "--") {
2428
+ nextArgv.push(...argv.slice(index));
2429
+ break;
2819
2430
  }
2820
- }
2821
- return new URL(candidates[0], baseUrl).href;
2822
- }
2823
-
2824
- // src/runtime-bridge-add-dry-run.ts
2825
- import fs3 from "fs";
2826
- import { promises as fsp } from "fs";
2827
- import os2 from "os";
2828
- import path3 from "path";
2829
- var SKIPPED_COPY_ROOT_ENTRIES = new Set([".git", "node_modules"]);
2830
- var SKIPPED_COMPARE_ROOT_ENTRIES = new Set([
2831
- ".git",
2832
- ".pnp.cjs",
2833
- ".pnp.loader.mjs",
2834
- "node_modules"
2835
- ]);
2836
- async function copyWorkspaceProject(sourceDir, targetDir) {
2837
- await fsp.cp(sourceDir, targetDir, {
2838
- filter: (sourcePath) => {
2839
- const relativePath = path3.relative(sourceDir, sourcePath);
2840
- if (relativePath === "") {
2841
- return true;
2431
+ if (arg === "--config" || arg === "-c") {
2432
+ const next = argv[index + 1];
2433
+ if (!next || next.startsWith("-")) {
2434
+ throw new Error(`\`${arg}\` requires a value.`);
2842
2435
  }
2843
- const [rootEntry] = relativePath.split(path3.sep);
2844
- return !SKIPPED_COPY_ROOT_ENTRIES.has(rootEntry ?? "");
2845
- },
2846
- recursive: true
2847
- });
2848
- }
2849
- function ensureWorkspaceInstallMarkers(sourceDir, targetDir) {
2850
- const sourceNodeModules = path3.join(sourceDir, "node_modules");
2851
- if (fs3.existsSync(sourceNodeModules)) {
2852
- fs3.symlinkSync(sourceNodeModules, path3.join(targetDir, "node_modules"), "junction");
2853
- }
2854
- for (const marker of [".pnp.cjs", ".pnp.loader.mjs"]) {
2855
- const sourceMarker = path3.join(sourceDir, marker);
2856
- if (!fs3.existsSync(sourceMarker)) {
2436
+ configOverridePath = next;
2437
+ index += 1;
2857
2438
  continue;
2858
2439
  }
2859
- const targetMarker = path3.join(targetDir, marker);
2860
- try {
2861
- fs3.symlinkSync(sourceMarker, targetMarker);
2862
- } catch {
2863
- try {
2864
- fs3.linkSync(sourceMarker, targetMarker);
2865
- } catch {
2866
- fs3.copyFileSync(sourceMarker, targetMarker);
2867
- }
2868
- }
2869
- }
2870
- }
2871
- async function listWorkspaceFiles(rootDir) {
2872
- const files = new Map;
2873
- async function visit(currentDir) {
2874
- const entries = await fsp.readdir(currentDir, { withFileTypes: true });
2875
- for (const entry of entries) {
2876
- const absolutePath = path3.join(currentDir, entry.name);
2877
- const relativePath = path3.relative(rootDir, absolutePath);
2878
- const [rootEntry] = relativePath.split(path3.sep);
2879
- if (SKIPPED_COMPARE_ROOT_ENTRIES.has(rootEntry ?? "")) {
2880
- continue;
2881
- }
2882
- if (entry.isDirectory()) {
2883
- await visit(absolutePath);
2884
- continue;
2885
- }
2886
- if (!entry.isFile()) {
2887
- continue;
2440
+ if (arg.startsWith("--config=")) {
2441
+ const inlineValue = arg.slice("--config=".length);
2442
+ if (!inlineValue) {
2443
+ throw new Error("`--config` requires a value.");
2888
2444
  }
2889
- files.set(relativePath.replace(path3.sep === "\\" ? /\\/gu : /\//gu, "/"), await fsp.readFile(absolutePath));
2890
- }
2891
- }
2892
- await visit(rootDir);
2893
- return files;
2894
- }
2895
- function compareStrings(left, right) {
2896
- if (left < right) {
2897
- return -1;
2898
- }
2899
- if (left > right) {
2900
- return 1;
2901
- }
2902
- return 0;
2903
- }
2904
- async function collectWorkspaceFileOperations(sourceDir, simulatedDir) {
2905
- const [sourceFiles, simulatedFiles] = await Promise.all([
2906
- listWorkspaceFiles(sourceDir),
2907
- listWorkspaceFiles(simulatedDir)
2908
- ]);
2909
- const operations = [];
2910
- for (const [relativePath, simulatedSource] of simulatedFiles) {
2911
- const originalSource = sourceFiles.get(relativePath);
2912
- if (originalSource === undefined) {
2913
- operations.push(`write ${relativePath}`);
2445
+ configOverridePath = inlineValue;
2914
2446
  continue;
2915
2447
  }
2916
- if (!originalSource.equals(simulatedSource)) {
2917
- operations.push(`update ${relativePath}`);
2918
- }
2919
- }
2920
- for (const relativePath of sourceFiles.keys()) {
2921
- if (!simulatedFiles.has(relativePath)) {
2922
- operations.push(`delete ${relativePath}`);
2923
- }
2924
- }
2925
- return operations.sort(compareStrings);
2926
- }
2927
- async function simulateWorkspaceAddDryRun({
2928
- cwd,
2929
- execute
2930
- }) {
2931
- const { resolveWorkspaceProject } = await import("./workspace-project-gxb499cp.js");
2932
- const workspace = resolveWorkspaceProject(cwd);
2933
- const relativeCwd = path3.relative(workspace.projectDir, path3.resolve(cwd));
2934
- const tempRoot = await fsp.mkdtemp(path3.join(os2.tmpdir(), "wp-typia-add-plan-"));
2935
- const simulatedProjectDir = path3.join(tempRoot, "workspace");
2936
- try {
2937
- await copyWorkspaceProject(workspace.projectDir, simulatedProjectDir);
2938
- ensureWorkspaceInstallMarkers(workspace.projectDir, simulatedProjectDir);
2939
- const simulatedCwd = relativeCwd.length > 0 ? path3.join(simulatedProjectDir, relativeCwd) : simulatedProjectDir;
2940
- const result = await execute(simulatedCwd);
2941
- const fileOperations = await collectWorkspaceFileOperations(workspace.projectDir, simulatedProjectDir);
2942
- return {
2943
- fileOperations,
2944
- result
2945
- };
2946
- } finally {
2947
- await fsp.rm(tempRoot, { force: true, recursive: true });
2948
- }
2949
- }
2950
-
2951
- // src/runtime-bridge-output.ts
2952
- function printCompletionPayload(payload, options = {}) {
2953
- const printLine = options.printLine ?? console.log;
2954
- const warnLine = options.warnLine ?? printLine;
2955
- for (const line of payload.preambleLines ?? []) {
2956
- printLine(line);
2957
- }
2958
- for (const warning of payload.warningLines ?? []) {
2959
- warnLine(`\u26A0\uFE0F ${warning}`);
2960
- }
2961
- const hasDetails = (payload.summaryLines?.length ?? 0) > 0 || (payload.nextSteps?.length ?? 0) > 0 || (payload.optionalLines?.length ?? 0) > 0 || Boolean(payload.optionalNote);
2962
- const hasLeadingContext = (payload.preambleLines?.length ?? 0) > 0 || (payload.warningLines?.length ?? 0) > 0;
2963
- printLine(hasLeadingContext && hasDetails ? `
2964
- ${payload.title}` : payload.title);
2965
- for (const line of payload.summaryLines ?? []) {
2966
- printLine(line);
2967
- }
2968
- if ((payload.nextSteps?.length ?? 0) > 0) {
2969
- printLine("Next steps:");
2970
- for (const step of payload.nextSteps ?? []) {
2971
- printLine(` ${step}`);
2972
- }
2973
- }
2974
- if ((payload.optionalLines?.length ?? 0) > 0) {
2975
- printLine(`
2976
- ${payload.optionalTitle ?? "Optional:"}`);
2977
- for (const step of payload.optionalLines ?? []) {
2978
- printLine(` ${step}`);
2979
- }
2980
- }
2981
- if (payload.optionalNote) {
2982
- printLine(`Note: ${payload.optionalNote}`);
2983
- }
2984
- }
2985
- function formatCreateProgressLine(payload) {
2986
- return `\u23F3 ${payload.title}: ${payload.detail}`;
2987
- }
2988
- function buildCreateCompletionPayload(flow) {
2989
- const verificationSteps = [
2990
- formatPackageExecCommand(flow.packageManager, `wp-typia@${package_default.version}`, "doctor"),
2991
- ...flow.optionalOnboarding.steps
2992
- ];
2993
- return {
2994
- nextSteps: flow.nextSteps,
2995
- optionalLines: verificationSteps,
2996
- optionalNote: flow.optionalOnboarding.note,
2997
- optionalTitle: "Verify and sync (optional):",
2998
- preambleLines: flow.result.selectedVariant ? [`Template variant: ${flow.result.selectedVariant}`] : undefined,
2999
- summaryLines: [`Project directory: ${flow.projectDir}`],
3000
- title: `\u2705 Created ${flow.result.variables.title} in ${flow.projectDir}`,
3001
- warningLines: flow.result.warnings
3002
- };
3003
- }
3004
- function buildCreateDryRunPayload(flow) {
3005
- let dependencyInstallLine;
3006
- switch (flow.plan.dependencyInstall) {
3007
- case "skipped-by-flag":
3008
- dependencyInstallLine = "Dependency install: already skipped via --no-install";
3009
- break;
3010
- case "would-install":
3011
- dependencyInstallLine = "Dependency install: would run during a real scaffold";
3012
- break;
2448
+ nextArgv.push(arg);
3013
2449
  }
3014
2450
  return {
3015
- optionalLines: flow.plan.files.map((relativePath) => `write ${relativePath}`),
3016
- optionalNote: "No files were written because --dry-run was enabled. Re-run without --dry-run to materialize this scaffold.",
3017
- optionalTitle: `Planned files (${flow.plan.files.length}):`,
3018
- preambleLines: flow.result.selectedVariant ? [`Template variant: ${flow.result.selectedVariant}`] : undefined,
3019
- summaryLines: [
3020
- `Project directory: ${flow.projectDir}`,
3021
- `Template: ${flow.result.templateId}`,
3022
- `Package manager: ${flow.packageManager}`,
3023
- dependencyInstallLine
3024
- ],
3025
- title: `\uD83E\uDDEA Dry run for ${flow.result.variables.title} at ${flow.projectDir}`,
3026
- warningLines: flow.result.warnings
3027
- };
3028
- }
3029
- function buildMigrationCompletionPayload(options) {
3030
- const summaryLines = options.lines.filter((line) => line.trim().length > 0);
3031
- return {
3032
- summaryLines,
3033
- title: `\u2705 Completed wp-typia migrate ${options.command}`
2451
+ argv: nextArgv,
2452
+ configOverridePath
3034
2453
  };
3035
2454
  }
3036
- function buildAddCompletionPayload(options) {
3037
- switch (options.kind) {
3038
- case "variation":
3039
- return {
3040
- summaryLines: [
3041
- `Variation: ${options.values.variationSlug}`,
3042
- `Target block: ${options.values.blockSlug}`,
3043
- `Project directory: ${options.projectDir}`
3044
- ],
3045
- title: "\u2705 Added workspace variation"
3046
- };
3047
- case "pattern":
3048
- return {
3049
- summaryLines: [
3050
- `Pattern: ${options.values.patternSlug}`,
3051
- `Project directory: ${options.projectDir}`
3052
- ],
3053
- title: "\u2705 Added workspace pattern"
3054
- };
3055
- case "binding-source":
3056
- return {
3057
- summaryLines: [
3058
- `Binding source: ${options.values.bindingSourceSlug}`,
3059
- `Project directory: ${options.projectDir}`
3060
- ],
3061
- title: "\u2705 Added binding source"
3062
- };
3063
- case "rest-resource":
3064
- return {
3065
- summaryLines: [
3066
- `REST resource: ${options.values.restResourceSlug}`,
3067
- `Namespace: ${options.values.namespace}`,
3068
- `Methods: ${options.values.methods}`,
3069
- `Project directory: ${options.projectDir}`
3070
- ],
3071
- title: "\u2705 Added plugin-level REST resource"
3072
- };
3073
- case "editor-plugin":
3074
- return {
3075
- summaryLines: [
3076
- `Editor plugin: ${options.values.editorPluginSlug}`,
3077
- `Slot: ${options.values.slot}`,
3078
- `Project directory: ${options.projectDir}`
3079
- ],
3080
- title: "\u2705 Added editor plugin"
3081
- };
3082
- case "hooked-block":
3083
- return {
3084
- summaryLines: [
3085
- `Block: ${options.values.blockSlug}`,
3086
- `Anchor: ${options.values.anchorBlockName}`,
3087
- `Position: ${options.values.position}`,
3088
- `Project directory: ${options.projectDir}`
3089
- ],
3090
- title: "\u2705 Added blockHooks metadata"
3091
- };
3092
- default:
3093
- return {
3094
- summaryLines: [
3095
- `Blocks: ${options.values.blockSlugs}`,
3096
- `Template family: ${options.values.templateId}`,
3097
- `Project directory: ${options.projectDir}`
3098
- ],
3099
- title: "\u2705 Added workspace block",
3100
- warningLines: options.warnings
3101
- };
3102
- }
3103
- }
3104
- function buildAddDryRunPayload(options) {
3105
- const normalizedTitle = options.completion.title.replace(/^\u2705\s*Added\s*/u, "");
2455
+
2456
+ // src/plugins/wp-typia-skills.ts
2457
+ function createWpTypiaSkillsMetadataPlugin(commands) {
3106
2458
  return {
3107
- optionalLines: options.fileOperations,
3108
- optionalNote: "No workspace files were changed because --dry-run was enabled. Re-run without --dry-run to apply this add command.",
3109
- optionalTitle: `Planned workspace updates (${options.fileOperations.length}):`,
3110
- preambleLines: options.completion.preambleLines,
3111
- summaryLines: options.completion.summaryLines,
3112
- title: `\uD83E\uDDEA Dry run for ${normalizedTitle || "workspace add command"}`,
3113
- warningLines: options.completion.warningLines
2459
+ name: "wp-typia-skills-metadata",
2460
+ setup(context) {
2461
+ context.store.set("_skillsCommands", new Map(commands.map((command) => [command.name, command])));
2462
+ context.store.set("_skillsCliName", "wp-typia");
2463
+ }
3114
2464
  };
3115
2465
  }
3116
- function printBlock(lines, printLine) {
3117
- for (const line of lines) {
3118
- printLine(line);
3119
- }
3120
- }
3121
- function formatExternalLayerSelectHint(option2) {
3122
- const details = [
3123
- option2.description,
3124
- option2.extends.length > 0 ? `extends ${option2.extends.join(", ")}` : undefined
3125
- ].filter((value) => typeof value === "string" && value.length > 0);
3126
- return details.length > 0 ? details.join(" \xB7 ") : undefined;
3127
- }
3128
- function toExternalLayerPromptOptions(options) {
3129
- return options.map((option2) => ({
3130
- hint: formatExternalLayerSelectHint(option2),
3131
- label: option2.id,
3132
- value: option2.id
3133
- }));
3134
- }
3135
- // src/runtime-bridge-sync.ts
3136
- import { spawnSync } from "child_process";
3137
- import fs4 from "fs";
3138
- import path4 from "path";
3139
- var SYNC_INSTALL_MARKERS = ["node_modules", ".pnp.cjs", ".pnp.loader.mjs"];
3140
- var LOCAL_SYNC_TOOL_PATTERN = /(^|[\s;&|()])(?:tsx|wp-scripts)(?=($|[\s;&|()]))/u;
3141
- function formatRunScript(packageManagerId, scriptName, extraArgs = "") {
3142
- const args = extraArgs.trim();
3143
- if (packageManagerId === "bun") {
3144
- return args ? `bun run ${scriptName} ${args}` : `bun run ${scriptName}`;
3145
- }
3146
- if (packageManagerId === "npm") {
3147
- return args ? `npm run ${scriptName} -- ${args}` : `npm run ${scriptName}`;
3148
- }
3149
- if (packageManagerId === "pnpm") {
3150
- return args ? `pnpm run ${scriptName} ${args}` : `pnpm run ${scriptName}`;
3151
- }
3152
- return args ? `yarn run ${scriptName} ${args}` : `yarn run ${scriptName}`;
3153
- }
3154
- function formatInstallCommand(packageManagerId) {
3155
- switch (packageManagerId) {
3156
- case "bun":
3157
- return "bun install";
3158
- case "pnpm":
3159
- return "pnpm install";
3160
- case "yarn":
3161
- return "yarn install";
3162
- default:
3163
- return "npm install";
3164
- }
3165
- }
3166
- function getSyncRootError(cwd) {
3167
- return new Error(`No generated wp-typia project root was found at ${cwd}. Run \`wp-typia sync\` from a scaffolded project or official workspace root.`);
3168
- }
3169
- function inferSyncPackageManager(cwd, packageManagerField) {
3170
- const field = String(packageManagerField ?? "");
3171
- if (field.startsWith("bun@"))
3172
- return "bun";
3173
- if (field.startsWith("npm@"))
3174
- return "npm";
3175
- if (field.startsWith("pnpm@"))
3176
- return "pnpm";
3177
- if (field.startsWith("yarn@"))
3178
- return "yarn";
3179
- if (fs4.existsSync(path4.join(cwd, "bun.lock")) || fs4.existsSync(path4.join(cwd, "bun.lockb"))) {
3180
- return "bun";
3181
- }
3182
- if (fs4.existsSync(path4.join(cwd, "pnpm-lock.yaml"))) {
3183
- return "pnpm";
3184
- }
3185
- if (fs4.existsSync(path4.join(cwd, "yarn.lock")) || fs4.existsSync(path4.join(cwd, ".pnp.cjs")) || fs4.existsSync(path4.join(cwd, ".pnp.loader.mjs")) || fs4.existsSync(path4.join(cwd, ".yarnrc.yml"))) {
3186
- return "yarn";
3187
- }
3188
- if (fs4.existsSync(path4.join(cwd, "package-lock.json")) || fs4.existsSync(path4.join(cwd, "npm-shrinkwrap.json"))) {
3189
- return "npm";
3190
- }
3191
- return "npm";
3192
- }
3193
- function resolveSyncProjectContext(cwd) {
3194
- const packageJsonPath = path4.join(cwd, "package.json");
3195
- if (!fs4.existsSync(packageJsonPath)) {
3196
- throw getSyncRootError(cwd);
3197
- }
3198
- const packageJson = JSON.parse(fs4.readFileSync(packageJsonPath, "utf8"));
3199
- const scripts = packageJson.scripts ?? {};
3200
- const syncScripts = {
3201
- sync: typeof scripts.sync === "string" ? scripts.sync : undefined,
3202
- "sync-rest": typeof scripts["sync-rest"] === "string" ? scripts["sync-rest"] : undefined,
3203
- "sync-types": typeof scripts["sync-types"] === "string" ? scripts["sync-types"] : undefined
3204
- };
3205
- if (!syncScripts.sync && !syncScripts["sync-types"]) {
3206
- throw new Error(`Expected ${packageJsonPath} to define either a \`sync\` or \`sync-types\` script.`);
3207
- }
2466
+
2467
+ // src/plugins/wp-typia-user-config.ts
2468
+ var wpTypiaUserConfigPlugin = createPlugin((options = {}) => {
2469
+ let resolvedConfig = {};
3208
2470
  return {
3209
- cwd,
3210
- packageJsonPath,
3211
- packageManager: inferSyncPackageManager(cwd, packageJson.packageManager),
3212
- scripts: syncScripts
3213
- };
3214
- }
3215
- function findInstalledDependencyMarkerDir(projectDir) {
3216
- let currentDir = path4.resolve(projectDir);
3217
- while (true) {
3218
- if (SYNC_INSTALL_MARKERS.some((marker) => fs4.existsSync(path4.join(currentDir, marker)))) {
3219
- return currentDir;
3220
- }
3221
- const parentDir = path4.dirname(currentDir);
3222
- if (parentDir === currentDir) {
3223
- return null;
2471
+ name: "wp-typia-user-config",
2472
+ async setup(context) {
2473
+ resolvedConfig = await loadWpTypiaUserConfig(context.paths.cwd);
2474
+ if (options.overrideSource) {
2475
+ const overrideConfig = await loadWpTypiaUserConfigFromSource(context.paths.cwd, options.overrideSource);
2476
+ resolvedConfig = mergeWpTypiaUserConfig(resolvedConfig, overrideConfig);
2477
+ }
2478
+ },
2479
+ beforeCommand(context) {
2480
+ context.store.wpTypiaUserConfig = resolvedConfig;
3224
2481
  }
3225
- currentDir = parentDir;
3226
- }
3227
- }
3228
- function scriptsLikelyNeedInstalledDependencies(project) {
3229
- const candidateScripts = project.scripts.sync ? [project.scripts.sync] : [project.scripts["sync-types"], project.scripts["sync-rest"]];
3230
- return candidateScripts.some((script) => typeof script === "string" && LOCAL_SYNC_TOOL_PATTERN.test(script));
3231
- }
3232
- function assertSyncDependenciesInstalled(project) {
3233
- if (!scriptsLikelyNeedInstalledDependencies(project)) {
3234
- return;
3235
- }
3236
- const markerDir = findInstalledDependencyMarkerDir(project.cwd);
3237
- if (markerDir) {
2482
+ };
2483
+ });
2484
+
2485
+ // src/cli.ts
2486
+ function applyStandaloneSupportLayoutEnv() {
2487
+ if (process.env.WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT) {
3238
2488
  return;
3239
2489
  }
3240
- throw new Error(`Project dependencies have not been installed yet. Run \`${formatInstallCommand(project.packageManager)}\` from the project root before \`wp-typia sync\`. The generated sync scripts rely on local tools such as \`tsx\`.`);
3241
- }
3242
- function getPackageManagerRunInvocation(packageManager, scriptName, extraArgs) {
3243
- switch (packageManager) {
3244
- case "bun":
3245
- return { args: ["run", scriptName, ...extraArgs], command: "bun" };
3246
- case "npm":
3247
- return {
3248
- args: ["run", scriptName, ...extraArgs.length > 0 ? ["--", ...extraArgs] : []],
3249
- command: "npm"
3250
- };
3251
- case "pnpm":
3252
- return { args: ["run", scriptName, ...extraArgs], command: "pnpm" };
3253
- case "yarn":
3254
- return { args: ["run", scriptName, ...extraArgs], command: "yarn" };
2490
+ const executableDir = path2.dirname(process.execPath);
2491
+ const candidateRoots = [
2492
+ path2.join(executableDir, ".wp-typia", "share", "wp-typia-project-tools"),
2493
+ path2.resolve(executableDir, "..", ".wp-typia", "share", "wp-typia-project-tools")
2494
+ ];
2495
+ for (const candidateRoot of candidateRoots) {
2496
+ if (fs.existsSync(path2.join(candidateRoot, "package.json"))) {
2497
+ process.env.WP_TYPIA_PROJECT_TOOLS_PACKAGE_ROOT = candidateRoot;
2498
+ return;
2499
+ }
3255
2500
  }
3256
2501
  }
3257
- function runProjectScript(project, scriptName, extraArgs) {
3258
- const script = project.scripts[scriptName];
3259
- if (!script) {
3260
- return;
3261
- }
3262
- const invocation = getPackageManagerRunInvocation(project.packageManager, scriptName, extraArgs);
3263
- const result = spawnSync(invocation.command, invocation.args, {
3264
- cwd: project.cwd,
3265
- shell: process.platform === "win32",
3266
- stdio: "inherit"
3267
- });
3268
- if (result.error || result.status !== 0) {
3269
- throw new Error(`\`${formatRunScript(project.packageManager, scriptName, extraArgs.join(" "))}\` failed.`, {
3270
- cause: result.error
3271
- });
3272
- }
3273
- }
3274
- async function executeSyncCommand({
3275
- check = false,
3276
- cwd
3277
- }) {
3278
- const project = resolveSyncProjectContext(cwd);
3279
- assertSyncDependenciesInstalled(project);
3280
- const extraArgs = check ? ["--check"] : [];
3281
- if (project.scripts.sync) {
3282
- runProjectScript(project, "sync", extraArgs);
3283
- return;
3284
- }
3285
- runProjectScript(project, "sync-types", extraArgs);
3286
- if (project.scripts["sync-rest"]) {
3287
- runProjectScript(project, "sync-rest", extraArgs);
3288
- }
3289
- }
3290
-
3291
- // src/runtime-bridge.ts
3292
- var loadCliAddRuntime = () => import("./cli-add-j2c81sh1.js");
3293
- var loadCliDiagnosticsRuntime = () => import("./cli-diagnostics-c65hhyhx.js");
3294
- var loadCliDoctorRuntime = () => import("./cli-doctor-hft0wr0e.js");
3295
- var loadCliPromptRuntime = () => import("./cli-prompt-614tq57c.js");
3296
- var loadCliScaffoldRuntime = () => import("./cli-scaffold-vcg6wem5.js");
3297
- var loadCliTemplatesRuntime = () => import("./cli-templates-4qxszbmc.js");
3298
- var loadMigrationsRuntime = () => import("./migrations-7jre4mw0.js");
3299
- async function wrapCliCommandError(command, error) {
3300
- const { createCliCommandError } = await loadCliDiagnosticsRuntime();
3301
- return createCliCommandError({ command, error });
3302
- }
3303
- function shouldWrapCliCommandError(options) {
3304
- if (options.emitOutput === false) {
3305
- return false;
3306
- }
3307
- if (options.renderLine) {
3308
- return false;
3309
- }
3310
- return true;
3311
- }
3312
- function readOptionalStringFlag(flags, name) {
3313
- const value = flags[name];
3314
- if (value === undefined || value === null) {
3315
- return;
3316
- }
3317
- if (typeof value !== "string" || value.trim().length === 0) {
3318
- throw new Error(`\`--${name}\` requires a value.`);
3319
- }
3320
- return value;
3321
- }
3322
- function readOptionalLooseStringFlag(flags, name) {
3323
- const value = flags[name];
3324
- if (value === undefined || value === null) {
3325
- return;
3326
- }
3327
- if (typeof value !== "string") {
3328
- throw new Error(`\`--${name}\` requires a value.`);
3329
- }
3330
- const trimmed = value.trim();
3331
- return trimmed.length > 0 ? trimmed : undefined;
3332
- }
3333
- function pushFlag(argv, name, value) {
3334
- if (value === undefined || value === null || value === false) {
3335
- return;
3336
- }
3337
- if (value === true) {
3338
- argv.push(`--${name}`);
3339
- return;
3340
- }
3341
- argv.push(`--${name}`, String(value));
3342
- }
3343
- var PACKAGE_MANAGER_PROMPT_OPTIONS = [
3344
- { label: "npm", value: "npm", hint: "Use npm" },
3345
- { label: "pnpm", value: "pnpm", hint: "Use pnpm" },
3346
- { label: "yarn", value: "yarn", hint: "Use yarn" },
3347
- { label: "bun", value: "bun", hint: "Use bun" }
3348
- ];
3349
- var DATA_STORAGE_PROMPT_OPTIONS = [
3350
- { label: "custom-table", value: "custom-table", hint: "Dedicated custom table storage" },
3351
- { label: "post-meta", value: "post-meta", hint: "Persist through post meta" }
3352
- ];
3353
- var PERSISTENCE_POLICY_PROMPT_OPTIONS = [
3354
- { label: "authenticated", value: "authenticated", hint: "Authenticated write policy" },
3355
- { label: "public", value: "public", hint: "Public token policy" }
3356
- ];
3357
- var BOOLEAN_PROMPT_OPTIONS = [
3358
- { label: "Yes", value: "yes", hint: "Enable this option" },
3359
- { label: "No", value: "no", hint: "Keep the default disabled state" }
3360
- ];
3361
- function emitCompletion(payload, options) {
3362
- if (options.emitOutput) {
3363
- printCompletionPayload(payload, {
3364
- printLine: options.printLine,
3365
- warnLine: options.warnLine
3366
- });
3367
- }
3368
- return payload;
3369
- }
3370
- async function executeCreateCommand({
3371
- projectDir,
3372
- cwd,
3373
- emitOutput = true,
3374
- flags,
3375
- interactive,
3376
- onProgress,
3377
- printLine = console.log,
3378
- prompt,
3379
- warnLine = console.warn
3380
- }) {
3381
- const [
3382
- { createReadlinePrompt },
3383
- { runScaffoldFlow },
3384
- { getTemplateSelectOptions }
3385
- ] = await Promise.all([
3386
- loadCliPromptRuntime(),
3387
- loadCliScaffoldRuntime(),
3388
- loadCliTemplatesRuntime()
3389
- ]);
3390
- const shouldPrompt = interactive ?? (!Boolean(flags.yes) && Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY));
3391
- const activePrompt = shouldPrompt ? prompt ?? createReadlinePrompt() : undefined;
3392
- const shouldPromptForExternalLayerSelection = Boolean(activePrompt) && activePrompt !== prompt;
3393
- const effectiveYes = Boolean(flags.yes) || Boolean(flags["dry-run"]) && !Boolean(activePrompt);
3394
- try {
3395
- const flow = await runScaffoldFlow({
3396
- alternateRenderTargets: readOptionalLooseStringFlag(flags, "alternate-render-targets"),
3397
- cwd,
3398
- dataStorageMode: readOptionalLooseStringFlag(flags, "data-storage"),
3399
- dryRun: Boolean(flags["dry-run"]),
3400
- externalLayerId: readOptionalLooseStringFlag(flags, "external-layer-id"),
3401
- externalLayerSource: readOptionalLooseStringFlag(flags, "external-layer-source"),
3402
- innerBlocksPreset: readOptionalLooseStringFlag(flags, "inner-blocks-preset"),
3403
- isInteractive: Boolean(activePrompt),
3404
- namespace: readOptionalLooseStringFlag(flags, "namespace"),
3405
- noInstall: Boolean(flags["no-install"]),
3406
- packageManager: readOptionalLooseStringFlag(flags, "package-manager"),
3407
- persistencePolicy: readOptionalLooseStringFlag(flags, "persistence-policy"),
3408
- phpPrefix: readOptionalLooseStringFlag(flags, "php-prefix"),
3409
- projectInput: projectDir,
3410
- onProgress: async (progress) => {
3411
- const payload2 = {
3412
- detail: progress.detail,
3413
- title: progress.title
3414
- };
3415
- onProgress?.(payload2);
3416
- if (emitOutput) {
3417
- printLine(formatCreateProgressLine(payload2));
3418
- }
3419
- },
3420
- promptText: activePrompt ? (message, defaultValue, validate) => activePrompt.text(message, defaultValue, validate) : undefined,
3421
- queryPostType: readOptionalLooseStringFlag(flags, "query-post-type"),
3422
- selectDataStorage: activePrompt ? () => activePrompt.select("Select a data storage mode", [...DATA_STORAGE_PROMPT_OPTIONS], 1) : undefined,
3423
- selectExternalLayerId: shouldPromptForExternalLayerSelection && activePrompt ? (options) => activePrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
3424
- selectPackageManager: activePrompt ? () => activePrompt.select("Select a package manager", [...PACKAGE_MANAGER_PROMPT_OPTIONS], 1) : undefined,
3425
- selectPersistencePolicy: activePrompt ? () => activePrompt.select("Select a persistence policy", [...PERSISTENCE_POLICY_PROMPT_OPTIONS], 1) : undefined,
3426
- selectTemplate: activePrompt ? () => activePrompt.select("Select a template", getTemplateSelectOptions(), 1) : undefined,
3427
- selectWithMigrationUi: activePrompt ? async () => await activePrompt.select("Enable migration UI support?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
3428
- selectWithTestPreset: activePrompt ? async () => await activePrompt.select("Include the Playwright test preset?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
3429
- selectWithWpEnv: activePrompt ? async () => await activePrompt.select("Include a local wp-env preset?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
3430
- templateId: readOptionalLooseStringFlag(flags, "template"),
3431
- textDomain: readOptionalLooseStringFlag(flags, "text-domain"),
3432
- variant: readOptionalLooseStringFlag(flags, "variant"),
3433
- withMigrationUi: flags["with-migration-ui"],
3434
- withTestPreset: flags["with-test-preset"],
3435
- withWpEnv: flags["with-wp-env"],
3436
- yes: effectiveYes
3437
- });
3438
- const payload = flow.dryRun && flow.plan ? buildCreateDryRunPayload({
3439
- packageManager: flow.packageManager,
3440
- plan: flow.plan,
3441
- projectDir: flow.projectDir,
3442
- result: flow.result
3443
- }) : buildCreateCompletionPayload(flow);
3444
- return emitCompletion(payload, { emitOutput, printLine, warnLine });
3445
- } catch (error) {
3446
- if (!shouldWrapCliCommandError({ emitOutput })) {
3447
- throw error;
3448
- }
3449
- throw await wrapCliCommandError("create", error);
3450
- } finally {
3451
- if (activePrompt && activePrompt !== prompt) {
3452
- activePrompt.close();
3453
- }
3454
- }
3455
- }
3456
- async function executeAddCommand({
3457
- cwd,
3458
- emitOutput = true,
3459
- flags,
3460
- interactive,
3461
- kind,
3462
- name,
3463
- printLine = console.log,
3464
- prompt,
3465
- warnLine = console.warn
3466
- }) {
3467
- if (!kind) {
3468
- const { formatAddHelpText } = await loadCliAddRuntime();
3469
- printLine(formatAddHelpText());
3470
- return;
3471
- }
3472
- const addRuntime = await loadCliAddRuntime();
3473
- let activePrompt;
3474
- const dryRun = Boolean(flags["dry-run"]);
3475
- try {
3476
- if (kind === "variation") {
3477
- if (!name) {
3478
- throw new Error("`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
3479
- }
3480
- const blockSlug = readOptionalStringFlag(flags, "block");
3481
- if (!blockSlug) {
3482
- throw new Error("`wp-typia add variation` requires --block <block-slug>.");
3483
- }
3484
- const simulated2 = dryRun ? await simulateWorkspaceAddDryRun({
3485
- cwd,
3486
- execute: (simulatedCwd) => addRuntime.runAddVariationCommand({
3487
- blockName: blockSlug,
3488
- cwd: simulatedCwd,
3489
- variationName: name
3490
- })
3491
- }) : null;
3492
- const result2 = simulated2?.result ?? await addRuntime.runAddVariationCommand({
3493
- blockName: blockSlug,
3494
- cwd,
3495
- variationName: name
3496
- });
3497
- const completion2 = buildAddCompletionPayload({
3498
- kind: "variation",
3499
- projectDir: result2.projectDir,
3500
- values: {
3501
- blockSlug: result2.blockSlug,
3502
- variationSlug: result2.variationSlug
3503
- }
3504
- });
3505
- if (!dryRun) {
3506
- return emitCompletion(completion2, { emitOutput, printLine });
3507
- }
3508
- return emitCompletion(buildAddDryRunPayload({
3509
- completion: completion2,
3510
- fileOperations: simulated2.fileOperations
3511
- }), { emitOutput, printLine });
3512
- }
3513
- if (kind === "pattern") {
3514
- if (!name) {
3515
- throw new Error("`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>.");
3516
- }
3517
- const simulated2 = dryRun ? await simulateWorkspaceAddDryRun({
3518
- cwd,
3519
- execute: (simulatedCwd) => addRuntime.runAddPatternCommand({
3520
- cwd: simulatedCwd,
3521
- patternName: name
3522
- })
3523
- }) : null;
3524
- const result2 = simulated2?.result ?? await addRuntime.runAddPatternCommand({
3525
- cwd,
3526
- patternName: name
3527
- });
3528
- const completion2 = buildAddCompletionPayload({
3529
- kind: "pattern",
3530
- projectDir: result2.projectDir,
3531
- values: {
3532
- patternSlug: result2.patternSlug
3533
- }
3534
- });
3535
- if (!dryRun) {
3536
- return emitCompletion(completion2, { emitOutput, printLine });
3537
- }
3538
- return emitCompletion(buildAddDryRunPayload({
3539
- completion: completion2,
3540
- fileOperations: simulated2.fileOperations
3541
- }), { emitOutput, printLine });
3542
- }
3543
- if (kind === "binding-source") {
3544
- if (!name) {
3545
- throw new Error("`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name>.");
3546
- }
3547
- const simulated2 = dryRun ? await simulateWorkspaceAddDryRun({
3548
- cwd,
3549
- execute: (simulatedCwd) => addRuntime.runAddBindingSourceCommand({
3550
- bindingSourceName: name,
3551
- cwd: simulatedCwd
3552
- })
3553
- }) : null;
3554
- const result2 = simulated2?.result ?? await addRuntime.runAddBindingSourceCommand({
3555
- bindingSourceName: name,
3556
- cwd
3557
- });
3558
- const completion2 = buildAddCompletionPayload({
3559
- kind: "binding-source",
3560
- projectDir: result2.projectDir,
3561
- values: {
3562
- bindingSourceSlug: result2.bindingSourceSlug
3563
- }
3564
- });
3565
- if (!dryRun) {
3566
- return emitCompletion(completion2, { emitOutput, printLine });
3567
- }
3568
- return emitCompletion(buildAddDryRunPayload({
3569
- completion: completion2,
3570
- fileOperations: simulated2.fileOperations
3571
- }), { emitOutput, printLine });
3572
- }
3573
- if (kind === "rest-resource") {
3574
- if (!name) {
3575
- throw new Error("`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].");
3576
- }
3577
- const methods = readOptionalStringFlag(flags, "methods");
3578
- const namespace = readOptionalStringFlag(flags, "namespace");
3579
- const simulated2 = dryRun ? await simulateWorkspaceAddDryRun({
3580
- cwd,
3581
- execute: (simulatedCwd) => addRuntime.runAddRestResourceCommand({
3582
- cwd: simulatedCwd,
3583
- methods,
3584
- namespace,
3585
- restResourceName: name
3586
- })
3587
- }) : null;
3588
- const result2 = simulated2?.result ?? await addRuntime.runAddRestResourceCommand({
3589
- cwd,
3590
- methods,
3591
- namespace,
3592
- restResourceName: name
3593
- });
3594
- const completion2 = buildAddCompletionPayload({
3595
- kind: "rest-resource",
3596
- projectDir: result2.projectDir,
3597
- values: {
3598
- methods: result2.methods.join(", "),
3599
- namespace: result2.namespace,
3600
- restResourceSlug: result2.restResourceSlug
3601
- }
3602
- });
3603
- if (!dryRun) {
3604
- return emitCompletion(completion2, { emitOutput, printLine });
3605
- }
3606
- return emitCompletion(buildAddDryRunPayload({
3607
- completion: completion2,
3608
- fileOperations: simulated2.fileOperations
3609
- }), { emitOutput, printLine });
3610
- }
3611
- if (kind === "editor-plugin") {
3612
- if (!name) {
3613
- throw new Error("`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <PluginSidebar>].");
3614
- }
3615
- const slot = readOptionalStringFlag(flags, "slot");
3616
- const simulated2 = dryRun ? await simulateWorkspaceAddDryRun({
3617
- cwd,
3618
- execute: (simulatedCwd) => addRuntime.runAddEditorPluginCommand({
3619
- cwd: simulatedCwd,
3620
- editorPluginName: name,
3621
- slot
3622
- })
3623
- }) : null;
3624
- const result2 = simulated2?.result ?? await addRuntime.runAddEditorPluginCommand({
3625
- cwd,
3626
- editorPluginName: name,
3627
- slot
3628
- });
3629
- const completion2 = buildAddCompletionPayload({
3630
- kind: "editor-plugin",
3631
- projectDir: result2.projectDir,
3632
- values: {
3633
- editorPluginSlug: result2.editorPluginSlug,
3634
- slot: result2.slot
3635
- }
3636
- });
3637
- if (!dryRun) {
3638
- return emitCompletion(completion2, { emitOutput, printLine });
3639
- }
3640
- return emitCompletion(buildAddDryRunPayload({
3641
- completion: completion2,
3642
- fileOperations: simulated2.fileOperations
3643
- }), { emitOutput, printLine });
3644
- }
3645
- if (kind === "hooked-block") {
3646
- if (!name) {
3647
- throw new Error("`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.");
3648
- }
3649
- const anchorBlockName = readOptionalStringFlag(flags, "anchor");
3650
- if (!anchorBlockName) {
3651
- throw new Error("`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
3652
- }
3653
- const position = readOptionalStringFlag(flags, "position");
3654
- if (!position) {
3655
- throw new Error("`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
3656
- }
3657
- const simulated2 = dryRun ? await simulateWorkspaceAddDryRun({
3658
- cwd,
3659
- execute: (simulatedCwd) => addRuntime.runAddHookedBlockCommand({
3660
- anchorBlockName,
3661
- blockName: name,
3662
- cwd: simulatedCwd,
3663
- position
3664
- })
3665
- }) : null;
3666
- const result2 = simulated2?.result ?? await addRuntime.runAddHookedBlockCommand({
3667
- anchorBlockName,
3668
- blockName: name,
3669
- cwd,
3670
- position
3671
- });
3672
- const completion2 = buildAddCompletionPayload({
3673
- kind: "hooked-block",
3674
- projectDir: result2.projectDir,
3675
- values: {
3676
- anchorBlockName: result2.anchorBlockName,
3677
- blockSlug: result2.blockSlug,
3678
- position: result2.position
3679
- }
3680
- });
3681
- if (!dryRun) {
3682
- return emitCompletion(completion2, { emitOutput, printLine });
3683
- }
3684
- return emitCompletion(buildAddDryRunPayload({
3685
- completion: completion2,
3686
- fileOperations: simulated2.fileOperations
3687
- }), { emitOutput, printLine });
3688
- }
3689
- if (kind !== "block") {
3690
- throw new Error(`Unknown add kind "${kind}". Expected one of: block, variation, pattern, binding-source, rest-resource, editor-plugin, hooked-block.`);
3691
- }
3692
- if (!name) {
3693
- throw new Error("`wp-typia add block` requires <name>. Usage: wp-typia add block <name> --template <basic|interactivity|persistence|compound>");
3694
- }
3695
- if (!flags.template) {
3696
- throw new Error("`wp-typia add block` requires --template <basic|interactivity|persistence|compound>.");
3697
- }
3698
- const externalLayerId = readOptionalStringFlag(flags, "external-layer-id");
3699
- const externalLayerSource = readOptionalStringFlag(flags, "external-layer-source");
3700
- const shouldPromptForLayerSelection = Boolean(externalLayerSource) && !Boolean(externalLayerId) && (interactive ?? (Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY)));
3701
- const promptRuntime = shouldPromptForLayerSelection ? await loadCliPromptRuntime() : undefined;
3702
- activePrompt = shouldPromptForLayerSelection ? prompt ?? promptRuntime?.createReadlinePrompt() : undefined;
3703
- const selectPrompt = activePrompt;
3704
- const alternateRenderTargets = readOptionalStringFlag(flags, "alternate-render-targets");
3705
- const dataStorageMode = readOptionalStringFlag(flags, "data-storage");
3706
- const innerBlocksPreset = readOptionalStringFlag(flags, "inner-blocks-preset");
3707
- const persistencePolicy = readOptionalStringFlag(flags, "persistence-policy");
3708
- const resolvedTemplateId = readOptionalStringFlag(flags, "template");
3709
- const simulated = dryRun ? await simulateWorkspaceAddDryRun({
3710
- cwd,
3711
- execute: (simulatedCwd) => addRuntime.runAddBlockCommand({
3712
- alternateRenderTargets,
3713
- blockName: name,
3714
- cwd: simulatedCwd,
3715
- dataStorageMode,
3716
- externalLayerId,
3717
- externalLayerSource,
3718
- innerBlocksPreset,
3719
- persistencePolicy,
3720
- selectExternalLayerId: selectPrompt ? (options) => selectPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
3721
- templateId: resolvedTemplateId
3722
- })
3723
- }) : null;
3724
- const result = simulated?.result ?? await addRuntime.runAddBlockCommand({
3725
- alternateRenderTargets,
3726
- blockName: name,
3727
- cwd,
3728
- dataStorageMode,
3729
- externalLayerId,
3730
- externalLayerSource,
3731
- innerBlocksPreset,
3732
- persistencePolicy,
3733
- selectExternalLayerId: selectPrompt ? (options) => selectPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
3734
- templateId: resolvedTemplateId
3735
- });
3736
- const completion = buildAddCompletionPayload({
3737
- kind: "block",
3738
- projectDir: result.projectDir,
3739
- values: {
3740
- blockSlugs: result.blockSlugs.join(", "),
3741
- templateId: result.templateId
3742
- },
3743
- warnings: result.warnings
3744
- });
3745
- if (!dryRun) {
3746
- return emitCompletion(completion, { emitOutput, printLine, warnLine });
3747
- }
3748
- return emitCompletion(buildAddDryRunPayload({
3749
- completion,
3750
- fileOperations: simulated.fileOperations
3751
- }), { emitOutput, printLine, warnLine });
3752
- } catch (error) {
3753
- if (!shouldWrapCliCommandError({ emitOutput })) {
3754
- throw error;
3755
- }
3756
- throw await wrapCliCommandError("add", error);
3757
- } finally {
3758
- if (activePrompt && activePrompt !== prompt) {
3759
- activePrompt.close();
3760
- }
3761
- }
3762
- }
3763
- async function executeTemplatesCommand({ flags }, printLine = console.log) {
3764
- const {
3765
- formatTemplateDetails,
3766
- formatTemplateFeatures,
3767
- formatTemplateSummary,
3768
- getTemplateById,
3769
- listTemplates
3770
- } = await loadCliTemplatesRuntime();
3771
- const subcommand = flags.subcommand ?? "list";
3772
- if (subcommand === "list") {
3773
- for (const template of listTemplates()) {
3774
- printBlock([formatTemplateSummary(template), formatTemplateFeatures(template)], printLine);
3775
- }
3776
- return;
3777
- }
3778
- if (subcommand === "inspect") {
3779
- if (!flags.id) {
3780
- throw new Error("`wp-typia templates inspect` requires <template-id>.");
3781
- }
3782
- const template = getTemplateById(flags.id);
3783
- if (!template) {
3784
- throw new Error(`Unknown template "${flags.id}".`);
3785
- }
3786
- printBlock([
3787
- formatTemplateSummary(template),
3788
- formatTemplateFeatures(template),
3789
- formatTemplateDetails(template)
3790
- ], printLine);
3791
- return;
3792
- }
3793
- throw new Error(`Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
3794
- }
3795
- async function executeDoctorCommand(cwd) {
3796
- try {
3797
- const { runDoctor } = await loadCliDoctorRuntime();
3798
- await runDoctor(cwd);
3799
- } catch (error) {
3800
- throw await wrapCliCommandError("doctor", error);
3801
- }
3802
- }
3803
- async function executeMigrateCommand({
3804
- command,
3805
- cwd,
3806
- flags,
3807
- prompt,
3808
- renderLine
3809
- }) {
3810
- const { formatMigrationHelpText, parseMigrationArgs, runMigrationCommand } = await loadMigrationsRuntime();
3811
- if (!command) {
3812
- console.log(formatMigrationHelpText());
3813
- return;
3814
- }
3815
- try {
3816
- const argv = [command];
3817
- pushFlag(argv, "all", flags.all);
3818
- pushFlag(argv, "force", flags.force);
3819
- pushFlag(argv, "current-migration-version", readOptionalLooseStringFlag(flags, "current-migration-version"));
3820
- pushFlag(argv, "migration-version", readOptionalLooseStringFlag(flags, "migration-version"));
3821
- pushFlag(argv, "from-migration-version", readOptionalLooseStringFlag(flags, "from-migration-version"));
3822
- pushFlag(argv, "to-migration-version", readOptionalLooseStringFlag(flags, "to-migration-version"));
3823
- pushFlag(argv, "iterations", readOptionalLooseStringFlag(flags, "iterations"));
3824
- pushFlag(argv, "seed", readOptionalLooseStringFlag(flags, "seed"));
3825
- const parsed = parseMigrationArgs(argv);
3826
- const lines = renderLine ? [] : null;
3827
- const captureLine = (line) => {
3828
- lines?.push(line);
3829
- if (renderLine) {
3830
- renderLine(line);
3831
- return;
3832
- }
3833
- console.log(line);
3834
- };
3835
- const result = await runMigrationCommand(parsed, cwd, {
3836
- prompt,
3837
- renderLine: captureLine
3838
- });
3839
- if (renderLine) {
3840
- return result && typeof result === "object" && "cancelled" in result && result.cancelled === true ? undefined : buildMigrationCompletionPayload({
3841
- command: parsed.command ?? "plan",
3842
- lines: lines ?? []
3843
- });
3844
- }
3845
- if (result && typeof result === "object" && "cancelled" in result && result.cancelled === true) {
3846
- return;
3847
- }
3848
- } catch (error) {
3849
- if (!shouldWrapCliCommandError({ renderLine })) {
3850
- throw error;
3851
- }
3852
- throw await wrapCliCommandError("migrate", error);
3853
- }
3854
- }
3855
- async function listTemplatesForRuntime() {
3856
- const { listTemplates } = await loadCliTemplatesRuntime();
3857
- return listTemplates();
3858
- }
3859
-
3860
- // src/ui/lazy-flow.tsx
3861
- var import_react33 = __toESM(require_react(), 1);
3862
-
3863
- // src/ui/alternate-buffer-lifecycle.ts
3864
- var import_react32 = __toESM(require_react(), 1);
3865
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/utils/format.ts
3866
- var KEYWORDS = new Set([
3867
- "const",
3868
- "let",
3869
- "var",
3870
- "function",
3871
- "class",
3872
- "return",
3873
- "if",
3874
- "else",
3875
- "for",
3876
- "while",
3877
- "import",
3878
- "export",
3879
- "from",
3880
- "async",
3881
- "await",
3882
- "try",
3883
- "catch",
3884
- "throw",
3885
- "new",
3886
- "typeof",
3887
- "interface",
3888
- "type",
3889
- "enum",
3890
- "extends",
3891
- "implements",
3892
- "public",
3893
- "private",
3894
- "protected",
3895
- "def",
3896
- "fn",
3897
- "pub",
3898
- "use",
3899
- "mod",
3900
- "struct",
3901
- "impl",
3902
- "trait"
3903
- ]);
3904
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/form.tsx
3905
- var import_react2 = __toESM(require_react(), 1);
3906
-
3907
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/form-context.tsx
3908
- var import_react = __toESM(require_react(), 1);
3909
- var FormContext = import_react.createContext(null);
3910
-
3911
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/form.tsx
3912
- var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
3913
- var formKeymap = createKeyMatcher({
3914
- cancel: ["escape"],
3915
- nextField: ["tab"],
3916
- previousField: ["shift+tab"],
3917
- submitShortcut: ["ctrl+s"],
3918
- resetShortcut: ["ctrl+r"],
3919
- nextError: ["f8"],
3920
- previousError: ["shift+f8"],
3921
- submit: ["enter"]
3922
- });
3923
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/form-field.tsx
3924
- var import_react3 = __toESM(require_react(), 1);
3925
- var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
3926
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/select-field.tsx
3927
- var import_react4 = __toESM(require_react(), 1);
3928
- var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
3929
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/multi-select-field.tsx
3930
- var import_react5 = __toESM(require_react(), 1);
3931
- var jsx_dev_runtime4 = __toESM(require_jsx_dev_runtime(), 1);
3932
- var multiSelectKeymap = createKeyMatcher({
3933
- up: ["up", "k"],
3934
- down: ["down", "j"],
3935
- toggle: ["space"],
3936
- submit: ["enter"]
3937
- });
3938
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/number-field.tsx
3939
- var import_react6 = __toESM(require_react(), 1);
3940
- var jsx_dev_runtime5 = __toESM(require_jsx_dev_runtime(), 1);
3941
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/password-field.tsx
3942
- var import_react7 = __toESM(require_react(), 1);
3943
- var jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
3944
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/textarea-field.tsx
3945
- var import_react8 = __toESM(require_react(), 1);
3946
- var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
3947
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/checkbox-field.tsx
3948
- var import_react9 = __toESM(require_react(), 1);
3949
- var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
3950
- var checkboxKeymap = createKeyMatcher({
3951
- toggle: ["space", "enter"]
3952
- });
3953
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/schema-form.tsx
3954
- var import_react10 = __toESM(require_react(), 1);
3955
- var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
3956
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/progress-bar.tsx
3957
- var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
3958
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/stack.tsx
3959
- var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
3960
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/panel.tsx
3961
- var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
3962
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/scroll-panel.tsx
3963
- var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
3964
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/card.tsx
3965
- var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
3966
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/alert.tsx
3967
- var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
3968
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/badge.tsx
3969
- var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
3970
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/divider.tsx
3971
- var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
3972
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/key-value-list.tsx
3973
- var import_react11 = __toESM(require_react(), 1);
3974
- var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
3975
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/stat.tsx
3976
- var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
3977
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/container.tsx
3978
- var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
3979
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/grid.tsx
3980
- var import_react12 = __toESM(require_react(), 1);
3981
- var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
3982
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/section-header.tsx
3983
- var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
3984
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/empty-state.tsx
3985
- var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
3986
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/toast.tsx
3987
- var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
3988
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/modal.tsx
3989
- var import_react13 = __toESM(require_react(), 1);
3990
- var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
3991
- var modalKeymap = createKeyMatcher({
3992
- close: ["escape", "ctrl+c"],
3993
- trap: ["tab", "shift+tab"]
3994
- });
3995
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/tabs.tsx
3996
- var import_react15 = __toESM(require_react(), 1);
3997
- var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
3998
- var tabsKeymap = createKeyMatcher({
3999
- previous: ["left", "h"],
4000
- next: ["right", "l"]
4001
- });
4002
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/confirm.tsx
4003
- var import_react16 = __toESM(require_react(), 1);
4004
- var jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
4005
- var confirmKeymap = createKeyMatcher({
4006
- toggle: ["left", "right", "h", "l", "tab"],
4007
- affirm: ["y"],
4008
- negate: ["n", "q"],
4009
- submit: ["enter"],
4010
- abort: ["escape"]
4011
- });
4012
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/menu.tsx
4013
- var import_react17 = __toESM(require_react(), 1);
4014
- var jsx_dev_runtime28 = __toESM(require_jsx_dev_runtime(), 1);
4015
- var menuKeymap = createKeyMatcher({
4016
- up: ["up", "k"],
4017
- down: ["down", "j"],
4018
- select: ["enter"]
4019
- });
4020
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/nav-list.tsx
4021
- var import_react18 = __toESM(require_react(), 1);
4022
- var jsx_dev_runtime29 = __toESM(require_jsx_dev_runtime(), 1);
4023
- var navKeymap = createKeyMatcher({
4024
- up: ["up", "k"],
4025
- down: ["down", "j"],
4026
- select: ["enter"]
4027
- });
4028
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/command-palette.tsx
4029
- var import_react19 = __toESM(require_react(), 1);
4030
- var jsx_dev_runtime30 = __toESM(require_jsx_dev_runtime(), 1);
4031
- var paletteKeymap = createKeyMatcher({
4032
- up: ["up", "k"],
4033
- down: ["down", "j"],
4034
- select: ["enter"]
4035
- });
4036
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/filter.tsx
4037
- var import_react20 = __toESM(require_react(), 1);
4038
- var jsx_dev_runtime31 = __toESM(require_jsx_dev_runtime(), 1);
4039
- var filterKeymap = createKeyMatcher({
4040
- up: ["up"],
4041
- down: ["down"],
4042
- toggle: ["tab"],
4043
- selectAll: ["ctrl+a"],
4044
- submit: ["enter"],
4045
- abort: ["escape"]
4046
- });
4047
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/data-table.tsx
4048
- var import_react21 = __toESM(require_react(), 1);
4049
- var jsx_dev_runtime32 = __toESM(require_jsx_dev_runtime(), 1);
4050
- var dataTableKeymap = createKeyMatcher({
4051
- sortPrevious: ["left", "h"],
4052
- sortNext: ["right", "l"],
4053
- rowPrevious: ["up", "k"],
4054
- rowNext: ["down", "j"],
4055
- select: ["enter"]
4056
- });
4057
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/sidebar-layout.tsx
4058
- var import_react22 = __toESM(require_react(), 1);
4059
- var jsx_dev_runtime33 = __toESM(require_jsx_dev_runtime(), 1);
4060
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/spinner.tsx
4061
- var import_react24 = __toESM(require_react(), 1);
4062
- var jsx_dev_runtime34 = __toESM(require_jsx_dev_runtime(), 1);
4063
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/pager.tsx
4064
- var import_react25 = __toESM(require_react(), 1);
4065
- var jsx_dev_runtime35 = __toESM(require_jsx_dev_runtime(), 1);
4066
- var pagerKeymap = createKeyMatcher({
4067
- scrollDown: ["down", "j"],
4068
- scrollUp: ["up", "k"],
4069
- halfPageDown: ["d"],
4070
- halfPageUp: ["u"],
4071
- top: ["g", "home"],
4072
- bottom: ["end"],
4073
- search: ["/"],
4074
- nextMatch: ["n"],
4075
- prevMatch: ["shift+n"],
4076
- quit: ["q", "escape"]
4077
- });
4078
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/choose.tsx
4079
- var import_react26 = __toESM(require_react(), 1);
4080
- var jsx_dev_runtime36 = __toESM(require_jsx_dev_runtime(), 1);
4081
- var chooseKeymap = createKeyMatcher({
4082
- up: ["up", "k"],
4083
- down: ["down", "j"],
4084
- pageUp: ["left", "h"],
4085
- pageDown: ["right", "l"],
4086
- home: ["g", "home"],
4087
- end: ["end", "G"],
4088
- toggle: ["space", "tab", "x"],
4089
- selectAll: ["a"],
4090
- submit: ["enter"],
4091
- abort: ["escape"]
4092
- });
4093
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/components/file-picker.tsx
4094
- var import_react27 = __toESM(require_react(), 1);
4095
- var jsx_dev_runtime37 = __toESM(require_jsx_dev_runtime(), 1);
4096
- var filePickerKeymap = createKeyMatcher({
4097
- up: ["up", "k"],
4098
- down: ["down", "j"],
4099
- enter: ["enter", "right", "l"],
4100
- back: ["backspace", "left", "h"],
4101
- toggleHidden: ["."],
4102
- quit: ["q", "escape"]
4103
- });
4104
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/interactive/index.tsx
4105
- var jsx_dev_runtime38 = __toESM(require_jsx_dev_runtime(), 1);
4106
- // ../../node_modules/.bun/@bunli+tui@0.6.0+df522c502ed1ba91/node_modules/@bunli/tui/src/charts/index.tsx
4107
- var import_react30 = __toESM(require_react(), 1);
4108
- var jsx_dev_runtime39 = __toESM(require_jsx_dev_runtime(), 1);
4109
- // src/ui/alternate-buffer-lifecycle.ts
4110
- function describeAlternateBufferFailure(context, error) {
4111
- const message = error instanceof Error ? error.message : String(error);
4112
- return `${context}: ${message}`;
4113
- }
4114
- function isAlternateBufferExitKey(key) {
4115
- return key.name === "q" || key.ctrl === true && key.name === "c";
4116
- }
4117
- function isAlternateBufferCompletionKey(key) {
4118
- return key.name === "enter" || key.sequence === "\r" || key.sequence === `
4119
- `;
4120
- }
4121
- function reportAlternateBufferFailure({
4122
- context,
4123
- error,
4124
- exit,
4125
- log = console.error
4126
- }) {
4127
- const message = describeAlternateBufferFailure(context, error);
4128
- exit();
4129
- log(message);
4130
- }
4131
- async function resolveLazyFlowComponent({
4132
- loader,
4133
- onLoaded,
4134
- onFailure,
4135
- isDisposed
4136
- }) {
4137
- try {
4138
- const module = await loader();
4139
- if (!isDisposed()) {
4140
- onLoaded(module.default);
4141
- }
4142
- } catch (error) {
4143
- if (!isDisposed()) {
4144
- onFailure(error);
4145
- }
4146
- }
4147
- }
4148
- function useAlternateBufferExitKeys(options = {}) {
4149
- const runtime = useRuntime();
4150
- const exit = options.exit ?? (() => runtime.exit());
4151
- const enabled = options.enabled ?? true;
4152
- useKeyboard((key) => {
4153
- if (!enabled) {
4154
- return;
4155
- }
4156
- if (isAlternateBufferExitKey(key)) {
4157
- exit();
4158
- }
4159
- });
4160
- }
4161
- function useAlternateBufferCompletionKeys(options = {}) {
4162
- const runtime = useRuntime();
4163
- const exit = options.exit ?? (() => runtime.exit());
4164
- const enabled = options.enabled ?? false;
4165
- useKeyboard((key) => {
4166
- if (!enabled) {
4167
- return;
4168
- }
4169
- if (isAlternateBufferCompletionKey(key) || isAlternateBufferExitKey(key)) {
4170
- exit();
4171
- }
4172
- });
4173
- }
4174
- function isAlternateBufferCompletionPayload(value) {
4175
- if (!value || typeof value !== "object" || Array.isArray(value)) {
4176
- return false;
4177
- }
4178
- const candidate = value;
4179
- return typeof candidate.title === "string" && candidate.title.trim().length > 0;
4180
- }
4181
- function useAlternateBufferLifecycle(context, options = {}) {
4182
- const runtime = useRuntime();
4183
- const [completion, setCompletion] = import_react32.useState(null);
4184
- const [progress, setProgress] = import_react32.useState(null);
4185
- const [status, setStatus] = import_react32.useState("editing");
4186
- const exit = import_react32.useCallback(() => {
4187
- runtime.exit();
4188
- }, [runtime]);
4189
- useAlternateBufferExitKeys({
4190
- enabled: (options.enableExitKeys ?? true) && status !== "completed",
4191
- exit
4192
- });
4193
- useAlternateBufferCompletionKeys({
4194
- enabled: status === "completed",
4195
- exit
4196
- });
4197
- const handleCancel = import_react32.useCallback(() => {
4198
- setCompletion(null);
4199
- setProgress(null);
4200
- setStatus("editing");
4201
- exit();
4202
- }, [exit]);
4203
- const handleFailure = import_react32.useCallback((error) => {
4204
- setCompletion(null);
4205
- setProgress(null);
4206
- setStatus("editing");
4207
- reportAlternateBufferFailure({
4208
- context,
4209
- error,
4210
- exit
4211
- });
4212
- }, [context, exit]);
4213
- const handleSubmit = import_react32.useCallback(async (action) => {
4214
- setCompletion(null);
4215
- setProgress(null);
4216
- setStatus("submitting");
4217
- try {
4218
- const result = await action();
4219
- if (isAlternateBufferCompletionPayload(result)) {
4220
- setCompletion(result);
4221
- setProgress(null);
4222
- setStatus("completed");
4223
- return;
4224
- }
4225
- exit();
4226
- } catch (error) {
4227
- setCompletion(null);
4228
- setProgress(null);
4229
- setStatus("editing");
4230
- reportAlternateBufferFailure({
4231
- context,
4232
- error,
4233
- exit
4234
- });
4235
- }
4236
- }, [context, exit]);
4237
- const reportProgress = import_react32.useCallback((payload) => {
4238
- setProgress(payload);
4239
- }, []);
4240
- return {
4241
- completion,
4242
- handleCancel,
4243
- handleFailure,
4244
- handleSubmit,
4245
- progress,
4246
- reportProgress,
4247
- status
4248
- };
4249
- }
4250
-
4251
- // src/ui/lazy-flow.tsx
4252
- function LazyFlow({ loader, props }) {
4253
- const [Component, setComponent] = import_react33.useState(null);
4254
- const { handleFailure } = useAlternateBufferLifecycle("wp-typia TUI flow failed", {
4255
- enableExitKeys: false
4256
- });
4257
- useAlternateBufferExitKeys({
4258
- enabled: Component === null
4259
- });
4260
- import_react33.useEffect(() => {
4261
- let disposed = false;
4262
- resolveLazyFlowComponent({
4263
- isDisposed: () => disposed,
4264
- loader,
4265
- onFailure: handleFailure,
4266
- onLoaded: (component) => {
4267
- setComponent(() => component);
4268
- }
4269
- });
4270
- return () => {
4271
- disposed = true;
4272
- };
4273
- }, [handleFailure, loader]);
4274
- if (!Component) {
4275
- return null;
4276
- }
4277
- return import_react33.createElement(Component, props);
4278
- }
4279
-
4280
- // src/commands/add.ts
4281
- var supportsInteractiveTui = typeof Bun !== "undefined";
4282
- function loadAddFlow() {
4283
- return import(resolveBundledModuleHref(import.meta.url, [
4284
- "./ui/add-flow.js",
4285
- "../ui/add-flow.js",
4286
- "../ui/add-flow.tsx"
4287
- ])).then((module) => ({ default: module.AddFlow }));
4288
- }
4289
- var addOptions = buildCommandOptions(ADD_OPTION_METADATA);
4290
- var addCommand = defineCommand({
4291
- defaultFormat: "toon",
4292
- description: "Extend an official wp-typia workspace with blocks, variations, patterns, binding sources, plugin-level REST resources, editor plugins, or hooked blocks.",
4293
- handler: async (args) => {
4294
- await executeAddCommand({
4295
- cwd: args.cwd,
4296
- flags: args.flags,
4297
- kind: args.positional[0],
4298
- name: args.positional[1]
4299
- });
4300
- },
4301
- name: "add",
4302
- options: addOptions,
4303
- ...supportsInteractiveTui ? {
4304
- render: (args) => {
4305
- const config = args.context?.store?.wpTypiaUserConfig && typeof args.context.store.wpTypiaUserConfig === "object" ? getAddBlockDefaults(args.context.store.wpTypiaUserConfig) : {};
4306
- return import_react34.createElement(LazyFlow, {
4307
- loader: loadAddFlow,
4308
- props: {
4309
- cwd: args.cwd,
4310
- initialValues: {
4311
- "alternate-render-targets": args.flags["alternate-render-targets"] ?? config["alternate-render-targets"],
4312
- "data-storage": args.flags["data-storage"] ?? config["data-storage"],
4313
- "external-layer-id": args.flags["external-layer-id"] ?? config["external-layer-id"],
4314
- "external-layer-source": args.flags["external-layer-source"] ?? config["external-layer-source"],
4315
- anchor: args.flags.anchor ?? "",
4316
- block: args.flags.block ?? "",
4317
- kind: args.positional[0] ?? "block",
4318
- methods: args.flags.methods ?? "",
4319
- name: args.positional[1] ?? "",
4320
- namespace: args.flags.namespace ?? "",
4321
- "persistence-policy": args.flags["persistence-policy"] ?? config["persistence-policy"],
4322
- position: args.flags.position ?? "after",
4323
- slot: args.flags.slot ?? "PluginSidebar",
4324
- template: args.flags.template ?? config.template
4325
- }
4326
- }
4327
- });
4328
- },
4329
- tui: {
4330
- renderer: {
4331
- bufferMode: "alternate"
4332
- }
4333
- }
4334
- } : {}
4335
- });
4336
-
4337
- // src/commands/create.ts
4338
- var import_react35 = __toESM(require_react(), 1);
4339
- var supportsInteractiveTui2 = typeof Bun !== "undefined";
4340
- function loadCreateFlow() {
4341
- return import(resolveBundledModuleHref(import.meta.url, [
4342
- "./ui/create-flow.js",
4343
- "../ui/create-flow.js",
4344
- "../ui/create-flow.tsx"
4345
- ])).then((module) => ({ default: module.CreateFlow }));
4346
- }
4347
- var createOptions = buildCommandOptions(CREATE_OPTION_METADATA);
4348
- var createCommand = defineCommand({
4349
- defaultFormat: "toon",
4350
- description: "Scaffold a new wp-typia project.",
4351
- handler: async (args) => {
4352
- const projectDir = args.positional[0];
4353
- if (!projectDir) {
4354
- const { createCliCommandError } = await import("./cli-diagnostics-c65hhyhx.js");
4355
- throw createCliCommandError({
4356
- command: "create",
4357
- detailLines: ["`wp-typia create` requires <project-dir>."]
4358
- });
4359
- }
4360
- await executeCreateCommand({
4361
- cwd: args.cwd,
4362
- flags: args.flags,
4363
- projectDir
4364
- });
4365
- },
4366
- name: "create",
4367
- options: createOptions,
4368
- ...supportsInteractiveTui2 ? {
4369
- render: (args) => {
4370
- const config = args.context?.store?.wpTypiaUserConfig && typeof args.context.store.wpTypiaUserConfig === "object" ? getCreateDefaults(args.context.store.wpTypiaUserConfig) : {};
4371
- return import_react35.createElement(LazyFlow, {
4372
- loader: loadCreateFlow,
4373
- props: {
4374
- cwd: args.cwd,
4375
- initialValues: {
4376
- "alternate-render-targets": args.flags["alternate-render-targets"] ?? config["alternate-render-targets"],
4377
- "data-storage": args.flags["data-storage"] ?? config["data-storage"],
4378
- "dry-run": Boolean(args.flags["dry-run"] ?? config["dry-run"] ?? false),
4379
- "external-layer-id": args.flags["external-layer-id"] ?? config["external-layer-id"],
4380
- "external-layer-source": args.flags["external-layer-source"] ?? config["external-layer-source"],
4381
- namespace: args.flags.namespace ?? config.namespace,
4382
- "no-install": Boolean(args.flags["no-install"] ?? config["no-install"] ?? false),
4383
- "package-manager": args.flags["package-manager"] ?? config["package-manager"],
4384
- "persistence-policy": args.flags["persistence-policy"] ?? config["persistence-policy"],
4385
- "php-prefix": args.flags["php-prefix"] ?? config["php-prefix"],
4386
- "query-post-type": args.flags["query-post-type"] ?? config["query-post-type"],
4387
- "project-dir": args.positional[0] ?? "",
4388
- template: args.flags.template ?? config.template,
4389
- "text-domain": args.flags["text-domain"] ?? config["text-domain"],
4390
- variant: args.flags.variant ?? config.variant,
4391
- "with-migration-ui": Boolean(args.flags["with-migration-ui"] ?? config["with-migration-ui"] ?? false),
4392
- "with-test-preset": Boolean(args.flags["with-test-preset"] ?? config["with-test-preset"] ?? false),
4393
- "with-wp-env": Boolean(args.flags["with-wp-env"] ?? config["with-wp-env"] ?? false),
4394
- yes: Boolean(args.flags.yes ?? config.yes ?? false)
4395
- }
4396
- }
4397
- });
4398
- },
4399
- tui: {
4400
- renderer: {
4401
- bufferMode: "alternate"
4402
- }
4403
- }
4404
- } : {}
4405
- });
4406
-
4407
- // src/commands/doctor.ts
4408
- var doctorCommand = defineCommand({
4409
- defaultFormat: "toon",
4410
- description: "Run repository and project diagnostics.",
4411
- handler: async (args) => {
4412
- const prefersStructuredOutput = args.formatExplicit && args.format !== "toon" || Boolean(args.context?.store?.isAIAgent);
4413
- if (prefersStructuredOutput) {
4414
- const [{ getDoctorChecks }, { createCliCommandError, getDoctorFailureDetailLines }] = await Promise.all([
4415
- import("./cli-doctor-hft0wr0e.js"),
4416
- import("./cli-diagnostics-c65hhyhx.js")
4417
- ]);
4418
- const checks = await getDoctorChecks(args.cwd);
4419
- args.output({ checks });
4420
- if (checks.some((check) => check.status === "fail")) {
4421
- throw createCliCommandError({
4422
- command: "doctor",
4423
- detailLines: getDoctorFailureDetailLines(checks),
4424
- summary: "One or more doctor checks failed."
4425
- });
4426
- }
4427
- return;
4428
- }
4429
- await executeDoctorCommand(args.cwd);
4430
- },
4431
- name: "doctor"
4432
- });
4433
-
4434
- // src/mcp.ts
4435
- import fs5 from "fs/promises";
4436
- import path5 from "path";
4437
-
4438
- // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/errors.ts
4439
- class SchemaConversionError extends TaggedError("SchemaConversionError")() {
4440
- }
4441
-
4442
- class ConvertToolsError extends TaggedError("ConvertToolsError")() {
4443
- }
4444
-
4445
- class GenerateMCPTypesError extends TaggedError("GenerateMCPTypesError")() {
4446
- }
4447
-
4448
- class McpToolsProviderError extends TaggedError("McpToolsProviderError")() {
4449
- }
4450
-
4451
- // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/schema-to-zod.ts
4452
- function jsonSchemaToZodSchema(schema, options = {}) {
4453
- return convertSchema(schema, options, "$");
4454
- }
4455
- function convertSchema(schema, options, path5) {
4456
- const { coerce = true } = options;
4457
- if (!schema || typeof schema !== "object") {
4458
- return Result.ok(exports_external.unknown());
4459
- }
4460
- if (schema.const !== undefined) {
4461
- return Result.ok(exports_external.literal(schema.const));
4462
- }
4463
- if (schema.enum && schema.enum.length > 0) {
4464
- const enumValues = schema.enum.filter((v) => v !== null);
4465
- if (enumValues.length > 0) {
4466
- if (enumValues.every((v) => typeof v === "string")) {
4467
- return Result.ok(exports_external.enum(enumValues));
4468
- }
4469
- const literals = enumValues.map((v) => exports_external.literal(v));
4470
- return unionFromSchemas(literals, path5);
4471
- }
4472
- }
4473
- if (schema.anyOf && schema.anyOf.length > 0) {
4474
- const schemas = mapSchemas(schema.anyOf, options, `${path5}.anyOf`);
4475
- if (Result.isError(schemas)) {
4476
- return schemas;
4477
- }
4478
- return unionFromSchemas(schemas.value, `${path5}.anyOf`);
4479
- }
4480
- if (schema.oneOf && schema.oneOf.length > 0) {
4481
- const schemas = mapSchemas(schema.oneOf, options, `${path5}.oneOf`);
4482
- if (Result.isError(schemas)) {
4483
- return schemas;
4484
- }
4485
- return unionFromSchemas(schemas.value, `${path5}.oneOf`);
4486
- }
4487
- const schemaType = Array.isArray(schema.type) ? schema.type[0] : schema.type;
4488
- switch (schemaType) {
4489
- case "string":
4490
- return buildStringSchema(schema, path5);
4491
- case "number":
4492
- case "integer":
4493
- return Result.ok(buildNumberSchema(schema, coerce));
4494
- case "boolean":
4495
- return Result.ok(buildBooleanSchema());
4496
- case "array":
4497
- return buildArraySchema(schema, options, path5);
4498
- case "object":
4499
- return buildObjectSchema(schema, options, path5);
4500
- case "null":
4501
- return Result.ok(exports_external.null());
4502
- default:
4503
- if (schema.properties) {
4504
- return buildObjectSchema(schema, options, path5);
4505
- }
4506
- if (schema.items) {
4507
- return buildArraySchema(schema, options, path5);
4508
- }
4509
- return Result.ok(exports_external.unknown());
4510
- }
4511
- }
4512
- function buildStringSchema(schema, path5) {
4513
- let zodSchema = exports_external.string();
4514
- if (schema.minLength !== undefined) {
4515
- zodSchema = zodSchema.min(schema.minLength);
4516
- }
4517
- if (schema.maxLength !== undefined) {
4518
- zodSchema = zodSchema.max(schema.maxLength);
4519
- }
4520
- if (schema.pattern) {
4521
- const pattern = schema.pattern;
4522
- const regexResult = Result.try({
4523
- try: () => new RegExp(pattern),
4524
- catch: (cause) => new SchemaConversionError({
4525
- path: path5,
4526
- message: `Invalid regex pattern "${pattern}"`,
4527
- cause
4528
- })
4529
- });
4530
- if (Result.isError(regexResult)) {
4531
- return regexResult;
4532
- }
4533
- zodSchema = zodSchema.regex(regexResult.value);
4534
- }
4535
- if (schema.format) {
4536
- switch (schema.format) {
4537
- case "email":
4538
- zodSchema = zodSchema.email();
4539
- break;
4540
- case "uri":
4541
- case "url":
4542
- zodSchema = zodSchema.url();
4543
- break;
4544
- case "uuid":
4545
- zodSchema = zodSchema.uuid();
4546
- break;
4547
- case "date-time":
4548
- zodSchema = zodSchema.datetime();
4549
- break;
4550
- case "date":
4551
- zodSchema = zodSchema.date();
4552
- break;
4553
- }
4554
- }
4555
- return Result.ok(zodSchema);
4556
- }
4557
- function buildNumberSchema(schema, coerce) {
4558
- let zodSchema = coerce ? exports_external.coerce.number() : exports_external.number();
4559
- if (schema.type === "integer" || Array.isArray(schema.type) && schema.type.includes("integer")) {
4560
- zodSchema = zodSchema.int();
4561
- }
4562
- if (schema.minimum !== undefined) {
4563
- zodSchema = zodSchema.min(schema.minimum);
4564
- }
4565
- if (schema.maximum !== undefined) {
4566
- zodSchema = zodSchema.max(schema.maximum);
4567
- }
4568
- if (schema.exclusiveMinimum !== undefined) {
4569
- zodSchema = zodSchema.gt(schema.exclusiveMinimum);
4570
- }
4571
- if (schema.exclusiveMaximum !== undefined) {
4572
- zodSchema = zodSchema.lt(schema.exclusiveMaximum);
4573
- }
4574
- if (schema.multipleOf !== undefined) {
4575
- zodSchema = zodSchema.multipleOf(schema.multipleOf);
4576
- }
4577
- return zodSchema;
4578
- }
4579
- function buildBooleanSchema() {
4580
- return exports_external.boolean();
4581
- }
4582
- function buildArraySchema(schema, options, path5) {
4583
- let itemSchema = exports_external.unknown();
4584
- if (schema.items) {
4585
- if (Array.isArray(schema.items)) {
4586
- if (schema.items.length > 0) {
4587
- const itemResult = convertSchema(schema.items[0], options, `${path5}.items[0]`);
4588
- if (Result.isError(itemResult)) {
4589
- return itemResult;
4590
- }
4591
- itemSchema = itemResult.value;
4592
- }
4593
- } else {
4594
- const itemResult = convertSchema(schema.items, options, `${path5}.items`);
4595
- if (Result.isError(itemResult)) {
4596
- return itemResult;
4597
- }
4598
- itemSchema = itemResult.value;
4599
- }
4600
- }
4601
- let zodSchema = exports_external.array(itemSchema);
4602
- if (schema.minItems !== undefined) {
4603
- zodSchema = zodSchema.min(schema.minItems);
4604
- }
4605
- if (schema.maxItems !== undefined) {
4606
- zodSchema = zodSchema.max(schema.maxItems);
4607
- }
4608
- return Result.ok(zodSchema);
4609
- }
4610
- function buildObjectSchema(schema, options, path5) {
4611
- if (!schema.properties) {
4612
- return Result.ok(exports_external.record(exports_external.string(), exports_external.unknown()));
4613
- }
4614
- const shape = {};
4615
- const requiredFields = new Set(schema.required || []);
4616
- for (const [propName, propSchema] of Object.entries(schema.properties)) {
4617
- const propResult = convertSchema(propSchema, options, `${path5}.properties.${propName}`);
4618
- if (Result.isError(propResult)) {
4619
- return propResult;
4620
- }
4621
- let propZodSchema = propResult.value;
4622
- if (propSchema.default !== undefined) {
4623
- propZodSchema = propZodSchema.default(propSchema.default);
4624
- }
4625
- if (!requiredFields.has(propName)) {
4626
- propZodSchema = propZodSchema.optional();
4627
- }
4628
- shape[propName] = propZodSchema;
4629
- }
4630
- return Result.ok(exports_external.object(shape));
4631
- }
4632
- function mapSchemas(schemas, options, path5) {
4633
- const zodSchemas = [];
4634
- for (let index = 0;index < schemas.length; index += 1) {
4635
- const converted = convertSchema(schemas[index], options, `${path5}[${index}]`);
4636
- if (Result.isError(converted)) {
4637
- return converted;
4638
- }
4639
- zodSchemas.push(converted.value);
4640
- }
4641
- return Result.ok(zodSchemas);
4642
- }
4643
- function unionFromSchemas(schemas, path5) {
4644
- if (schemas.length === 0) {
4645
- return Result.err(new SchemaConversionError({
4646
- path: path5,
4647
- message: `Cannot create union from an empty schema set at ${path5}`,
4648
- cause: new Error("Empty schema union")
4649
- }));
4650
- }
4651
- if (schemas.length === 1) {
4652
- return Result.ok(schemas[0]);
4653
- }
4654
- let unionSchema = exports_external.union([schemas[0], schemas[1]]);
4655
- for (let index = 2;index < schemas.length; index += 1) {
4656
- unionSchema = exports_external.union([unionSchema, schemas[index]]);
4657
- }
4658
- return Result.ok(unionSchema);
4659
- }
4660
-
4661
- // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/utils.ts
4662
- function toKebabCase(str) {
4663
- return str.replace(/_/g, "-").replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
4664
- }
4665
- function toCommandName(toolName, namespace) {
4666
- const kebabName = toKebabCase(toolName);
4667
- return namespace ? `${namespace}:${kebabName}` : kebabName;
4668
- }
4669
- function toFlagName(propName) {
4670
- return toKebabCase(propName);
4671
- }
4672
- function toPascalCase(str) {
4673
- return str.split(/[-:_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
4674
- }
4675
- function escapeString(str) {
4676
- return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
4677
- }
4678
-
4679
- // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/converter.ts
4680
- function createCommandsFromMCPTools(tools, options) {
4681
- const commands = [];
4682
- for (const tool of tools) {
4683
- const converted = convertToolToCommand(tool, options);
4684
- if (Result.isError(converted)) {
4685
- return converted;
4686
- }
4687
- commands.push(converted.value);
4688
- }
4689
- return Result.ok(commands);
4690
- }
4691
- function convertToolToCommand(tool, options) {
4692
- const {
4693
- namespace,
4694
- createHandler,
4695
- commandName: customCommandName,
4696
- flagName: customFlagName
4697
- } = options;
4698
- const commandName = customCommandName ? customCommandName(tool.name) : toCommandName(tool.name, namespace);
4699
- const bunliOptionsResult = convertInputSchemaToOptions(tool.name, tool.inputSchema, customFlagName || toFlagName);
4700
- if (Result.isError(bunliOptionsResult)) {
4701
- return bunliOptionsResult;
4702
- }
4703
- const command = {
4704
- name: commandName,
4705
- description: tool.description || `Invoke MCP tool: ${tool.name}`,
4706
- options: bunliOptionsResult.value,
4707
- handler: createHandler(tool.name)
4708
- };
4709
- return Result.ok(command);
4710
- }
4711
- function convertInputSchemaToOptions(toolName, inputSchema, flagNameTransform) {
4712
- const bunliOptions = {};
4713
- if (!inputSchema?.properties) {
4714
- return Result.ok(bunliOptions);
4715
- }
4716
- const requiredFields = new Set(inputSchema.required || []);
4717
- for (const [propName, propSchema] of Object.entries(inputSchema.properties)) {
4718
- const schemaResult = jsonSchemaToZodSchema(propSchema, { coerce: true });
4719
- if (Result.isError(schemaResult)) {
4720
- return Result.err(new ConvertToolsError({
4721
- toolName,
4722
- message: `Failed to convert input schema field "${propName}" for tool "${toolName}"`,
4723
- cause: schemaResult.error
4724
- }));
4725
- }
4726
- let zodSchema = schemaResult.value;
4727
- if (propSchema.default !== undefined) {
4728
- zodSchema = zodSchema.default(propSchema.default);
4729
- }
4730
- if (!requiredFields.has(propName)) {
4731
- zodSchema = zodSchema.optional();
4732
- }
4733
- const flagName = flagNameTransform(propName);
4734
- const shortMatch = propSchema.description?.match(/^\[-([a-zA-Z])\]\s*/);
4735
- const short = shortMatch ? shortMatch[1] : undefined;
4736
- const description = shortMatch ? propSchema.description?.slice(shortMatch[0].length) : propSchema.description;
4737
- bunliOptions[flagName] = option(zodSchema, {
4738
- description,
4739
- short
4740
- });
4741
- }
4742
- return Result.ok(bunliOptions);
4743
- }
4744
- function extractCommandMetadata(tool, namespace, flagNameTransform = toFlagName) {
4745
- const commandName = toCommandName(tool.name, namespace);
4746
- const optionsMeta = {};
4747
- if (tool.inputSchema?.properties) {
4748
- const requiredFields = new Set(tool.inputSchema.required || []);
4749
- for (const [propName, propSchema] of Object.entries(tool.inputSchema.properties)) {
4750
- const flagName = flagNameTransform(propName);
4751
- const schemaType = Array.isArray(propSchema.type) ? propSchema.type[0] : propSchema.type;
4752
- const shortMatch = propSchema.description?.match(/^\[-([a-zA-Z])\]\s*/);
4753
- const short = shortMatch ? shortMatch[1] : undefined;
4754
- const description = shortMatch ? propSchema.description?.slice(shortMatch[0].length) : propSchema.description;
4755
- optionsMeta[flagName] = {
4756
- type: schemaType || "unknown",
4757
- required: requiredFields.has(propName) && propSchema.default === undefined,
4758
- description,
4759
- short,
4760
- hasDefault: propSchema.default !== undefined,
4761
- default: propSchema.default
4762
- };
4763
- if (propSchema.enum) {
4764
- optionsMeta[flagName].enumValues = propSchema.enum.filter((v) => typeof v === "string" || typeof v === "number");
4765
- }
4766
- if (propSchema.minimum !== undefined) {
4767
- optionsMeta[flagName].minimum = propSchema.minimum;
4768
- }
4769
- if (propSchema.maximum !== undefined) {
4770
- optionsMeta[flagName].maximum = propSchema.maximum;
4771
- }
4772
- }
4773
- }
4774
- return {
4775
- name: commandName,
4776
- toolName: tool.name,
4777
- namespace,
4778
- description: tool.description,
4779
- options: optionsMeta
4780
- };
4781
- }
4782
- // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/codegen.ts
4783
- import { mkdir, writeFile } from "fs/promises";
4784
- import { join as join2 } from "path";
4785
- async function generateMCPTypes(options) {
4786
- const { tools, outputDir } = options;
4787
- return await Result.tryPromise({
4788
- try: async () => {
4789
- await mkdir(outputDir, { recursive: true });
4790
- for (const { namespace, tools: toolList } of tools) {
4791
- if (!toolList || toolList.length === 0)
4792
- continue;
4793
- const content = generateNamespaceTypes(namespace, toolList);
4794
- const fileName = `mcp-${namespace}.gen.ts`;
4795
- const filePath = join2(outputDir, fileName);
4796
- await writeFile(filePath, content, "utf-8");
4797
- }
4798
- const indexContent = generateIndexFile(tools);
4799
- await writeFile(join2(outputDir, "mcp-index.gen.ts"), indexContent, "utf-8");
4800
- },
4801
- catch: (cause) => new GenerateMCPTypesError({
4802
- outputDir,
4803
- message: `Failed to generate MCP types in ${outputDir}`,
4804
- cause
4805
- })
4806
- });
4807
- }
4808
- function generateNamespaceTypes(namespace, tools) {
4809
- const lines = [];
4810
- lines.push(`// This file was automatically generated by @bunli/plugin-mcp`);
4811
- lines.push(`// DO NOT EDIT - changes will be overwritten`);
4812
- lines.push(``);
4813
- lines.push(`import type { Command, Options, CLIOption } from '@bunli/core'`);
4814
- lines.push(`import { option } from '@bunli/core'`);
4815
- lines.push(`import { z } from 'zod'`);
4816
- lines.push(``);
4817
- const metadata = tools.map((tool) => extractCommandMetadata(tool, namespace));
4818
- for (const cmd of metadata) {
4819
- lines.push(generateCommandSchema(cmd));
4820
- lines.push(``);
4821
- }
4822
- lines.push(generateModuleAugmentation(namespace, metadata));
4823
- return lines.join(`
4824
- `);
4825
- }
4826
- function generateCommandSchema(cmd) {
4827
- const lines = [];
4828
- const baseName = toPascalCase(cmd.name);
4829
- lines.push(`// ${cmd.description || cmd.toolName}`);
4830
- lines.push(`export const ${baseName}Options = {`);
4831
- for (const [flagName, opt] of Object.entries(cmd.options)) {
4832
- const zodSchema = generateZodSchemaString(opt);
4833
- const metadata = [];
4834
- if (opt.description) {
4835
- metadata.push(`description: '${escapeString(opt.description)}'`);
4836
- }
4837
- if (opt.short) {
4838
- metadata.push(`short: '${opt.short}'`);
4839
- }
4840
- const metadataStr = metadata.length > 0 ? `, { ${metadata.join(", ")} }` : "";
4841
- lines.push(` '${flagName}': option(${zodSchema}${metadataStr}),`);
4842
- }
4843
- lines.push(`} as const`);
4844
- lines.push(``);
4845
- lines.push(`export type ${baseName}Flags = {`);
4846
- for (const [flagName, opt] of Object.entries(cmd.options)) {
4847
- const tsType = jsonSchemaTypeToTS(opt.type, opt.enumValues);
4848
- const optional = !opt.required ? "?" : "";
4849
- lines.push(` '${flagName}'${optional}: ${tsType}`);
4850
- }
4851
- lines.push(`}`);
4852
- return lines.join(`
4853
- `);
4854
- }
4855
- function generateZodSchemaString(opt) {
4856
- let schema;
4857
- if (opt.enumValues && opt.enumValues.length > 0) {
4858
- if (opt.enumValues.every((v) => typeof v === "string")) {
4859
- const values = opt.enumValues.map((v) => `'${escapeString(v)}'`).join(", ");
4860
- schema = `z.enum([${values}])`;
4861
- } else {
4862
- const literals = opt.enumValues.map((v) => typeof v === "string" ? `z.literal('${escapeString(v)}')` : `z.literal(${v})`).join(", ");
4863
- schema = `z.union([${literals}])`;
4864
- }
4865
- } else {
4866
- switch (opt.type) {
4867
- case "string":
4868
- schema = "z.string()";
4869
- break;
4870
- case "number":
4871
- schema = "z.coerce.number()";
4872
- break;
4873
- case "integer":
4874
- schema = "z.coerce.number().int()";
4875
- break;
4876
- case "boolean":
4877
- schema = "z.boolean()";
4878
- break;
4879
- case "array":
4880
- schema = "z.array(z.unknown())";
4881
- break;
4882
- case "object":
4883
- schema = "z.record(z.unknown())";
4884
- break;
4885
- default:
4886
- schema = "z.unknown()";
4887
- }
4888
- }
4889
- if (opt.minimum !== undefined) {
4890
- schema += `.min(${opt.minimum})`;
4891
- }
4892
- if (opt.maximum !== undefined) {
4893
- schema += `.max(${opt.maximum})`;
4894
- }
4895
- if (opt.hasDefault && opt.default !== undefined) {
4896
- const defaultVal = typeof opt.default === "string" ? `'${escapeString(opt.default)}'` : JSON.stringify(opt.default);
4897
- schema += `.default(${defaultVal})`;
4898
- }
4899
- if (!opt.required && !opt.hasDefault) {
4900
- schema += ".optional()";
4901
- }
4902
- return schema;
4903
- }
4904
- function jsonSchemaTypeToTS(type, enumValues) {
4905
- if (enumValues && enumValues.length > 0) {
4906
- return enumValues.map((v) => typeof v === "string" ? `'${escapeString(v)}'` : String(v)).join(" | ");
4907
- }
4908
- switch (type) {
4909
- case "string":
4910
- return "string";
4911
- case "number":
4912
- case "integer":
4913
- return "number";
4914
- case "boolean":
4915
- return "boolean";
4916
- case "array":
4917
- return "unknown[]";
4918
- case "object":
4919
- return "Record<string, unknown>";
4920
- case "null":
4921
- return "null";
4922
- default:
4923
- return "unknown";
4924
- }
4925
- }
4926
- function generateModuleAugmentation(namespace, metadata) {
4927
- const lines = [];
4928
- lines.push(`// Module augmentation for type-safe execute()`);
4929
- lines.push(`declare module '@bunli/core' {`);
4930
- lines.push(` interface RegisteredCommands {`);
4931
- for (const cmd of metadata) {
4932
- const baseName = toPascalCase(cmd.name);
4933
- lines.push(` '${cmd.name}': Command<typeof ${baseName}Options>`);
4934
- }
4935
- lines.push(` }`);
4936
- lines.push(`}`);
4937
- return lines.join(`
4938
- `);
4939
- }
4940
- function generateIndexFile(toolGroups) {
4941
- const lines = [];
4942
- lines.push(`// This file was automatically generated by @bunli/plugin-mcp`);
4943
- lines.push(`// DO NOT EDIT - changes will be overwritten`);
4944
- lines.push(``);
4945
- for (const { namespace } of toolGroups) {
4946
- if (!namespace)
4947
- continue;
4948
- lines.push(`export * from './mcp-${namespace}.gen.js'`);
4949
- }
4950
- return lines.join(`
4951
- `);
4952
- }
4953
- // src/mcp.ts
4954
- function isObject(value) {
4955
- return typeof value === "object" && value !== null && !Array.isArray(value);
4956
- }
4957
- function isTool(value) {
4958
- return isObject(value) && typeof value.name === "string" && (value.description === undefined || typeof value.description === "string");
4959
- }
4960
- function isToolGroup(value) {
4961
- return isObject(value) && typeof value.namespace === "string" && Array.isArray(value.tools) && value.tools.every(isTool);
4962
- }
4963
- async function readSchemaSource(cwd, source) {
4964
- const schemaPath = path5.resolve(cwd, source.path);
4965
- const raw = await fs5.readFile(schemaPath, "utf8");
4966
- const parsed = JSON.parse(raw);
4967
- if (isToolGroup(parsed)) {
4968
- return parsed;
4969
- }
4970
- if (Array.isArray(parsed) && parsed.every(isTool)) {
4971
- return {
4972
- namespace: source.namespace,
4973
- tools: parsed
4974
- };
4975
- }
4976
- throw new Error(`Schema source "${source.path}" must contain either one MCPToolGroup object or an array of MCP tools.`);
4977
- }
4978
- async function loadMcpToolGroups(cwd, schemaSources) {
4979
- return Promise.all(schemaSources.map((source) => readSchemaSource(cwd, source)));
4980
- }
4981
- async function syncMcpSchemas(cwd, schemaSources, outputDir = path5.join(cwd, ".bunli", "mcp")) {
4982
- const groups = await loadMcpToolGroups(cwd, schemaSources);
4983
- const result = await generateMCPTypes({
4984
- outputDir,
4985
- tools: groups
4986
- });
4987
- if (Result.isError(result)) {
4988
- throw result.error;
4989
- }
4990
- const registry = groups.map((group) => ({
4991
- namespace: group.namespace,
4992
- tools: group.tools.map((tool) => extractCommandMetadata(tool, group.namespace))
4993
- }));
4994
- for (const group of groups) {
4995
- const convert = createCommandsFromMCPTools(group.tools, {
4996
- createHandler: () => async () => {},
4997
- namespace: group.namespace
4998
- });
4999
- if (Result.isError(convert)) {
5000
- throw convert.error;
5001
- }
5002
- }
5003
- await fs5.mkdir(outputDir, { recursive: true });
5004
- await fs5.writeFile(path5.join(outputDir, "registry.json"), `${JSON.stringify(registry, null, 2)}
5005
- `, "utf8");
5006
- return {
5007
- commandCount: registry.reduce((count, group) => count + group.tools.length, 0),
5008
- groups,
5009
- outputDir
5010
- };
5011
- }
5012
-
5013
- // src/commands/mcp.ts
5014
- var mcpCommand = defineCommand({
5015
- defaultFormat: "json",
5016
- description: "Inspect or sync schema-driven MCP metadata for wp-typia.",
5017
- handler: async (args) => {
5018
- const subcommand = args.positional[0] ?? "list";
5019
- const userConfig = args.context?.store?.wpTypiaUserConfig && typeof args.context.store.wpTypiaUserConfig === "object" ? args.context.store.wpTypiaUserConfig : {};
5020
- const schemaSources = getMcpSchemaSources(userConfig);
5021
- if (schemaSources.length === 0) {
5022
- throw new Error("No MCP schema sources are configured. Add `mcp.schemaSources` in ~/.config/wp-typia/config.json, .wp-typiarc(.json), or package.json#wp-typia.");
5023
- }
5024
- if (subcommand === "list") {
5025
- const groups = await loadMcpToolGroups(args.cwd, schemaSources);
5026
- const summary = groups.map((group) => ({
5027
- namespace: group.namespace,
5028
- toolCount: group.tools.length,
5029
- tools: group.tools.map((tool) => tool.name)
5030
- }));
5031
- const prefersStructuredOutput = args.formatExplicit && args.format !== "toon" || args.agent || Boolean(args.context?.store?.isAIAgent);
5032
- if (prefersStructuredOutput) {
5033
- args.output({ groups: summary });
5034
- return;
5035
- }
5036
- for (const group of summary) {
5037
- console.log(`${group.namespace} (${group.toolCount})`);
5038
- for (const tool of group.tools) {
5039
- console.log(` - ${tool}`);
5040
- }
5041
- }
5042
- return;
5043
- }
5044
- if (subcommand === "sync") {
5045
- const outputDir = args.flags["output-dir"] ?? `${args.cwd}/.bunli/mcp`;
5046
- const result = await syncMcpSchemas(args.cwd, schemaSources, outputDir);
5047
- console.log(`Synced ${result.commandCount} MCP tools across ${result.groups.length} namespaces into ${result.outputDir}.`);
5048
- return;
5049
- }
5050
- throw new Error(`Unknown mcp subcommand "${subcommand}". Expected list or sync.`);
5051
- },
5052
- name: "mcp",
5053
- options: {
5054
- "output-dir": {
5055
- description: "Output directory for generated MCP metadata during `mcp sync`.",
5056
- schema: exports_external.string().optional()
5057
- }
5058
- }
5059
- });
5060
-
5061
- // src/commands/migrate.ts
5062
- var import_react36 = __toESM(require_react(), 1);
5063
- var supportsInteractiveTui3 = typeof Bun !== "undefined";
5064
- function loadMigrateFlow() {
5065
- return import(resolveBundledModuleHref(import.meta.url, [
5066
- "./ui/migrate-flow.js",
5067
- "../ui/migrate-flow.js",
5068
- "../ui/migrate-flow.tsx"
5069
- ])).then((module) => ({ default: module.MigrateFlow }));
5070
- }
5071
- var migrateOptions = buildCommandOptions(MIGRATE_OPTION_METADATA);
5072
- var migrateCommand = defineCommand({
5073
- defaultFormat: "toon",
5074
- description: "Run migration workflows for migration-capable wp-typia projects.",
5075
- handler: async (args) => {
5076
- await executeMigrateCommand({
5077
- command: args.positional[0],
5078
- cwd: args.cwd,
5079
- flags: args.flags
5080
- });
5081
- },
5082
- name: "migrate",
5083
- options: migrateOptions,
5084
- ...supportsInteractiveTui3 ? {
5085
- render: (args) => import_react36.createElement(LazyFlow, {
5086
- loader: loadMigrateFlow,
5087
- props: {
5088
- cwd: args.cwd,
5089
- initialValues: {
5090
- all: Boolean(args.flags.all ?? false),
5091
- command: args.positional[0] ?? "plan",
5092
- "current-migration-version": args.flags["current-migration-version"],
5093
- force: Boolean(args.flags.force ?? false),
5094
- "from-migration-version": args.flags["from-migration-version"],
5095
- iterations: args.flags.iterations,
5096
- "migration-version": args.flags["migration-version"],
5097
- seed: args.flags.seed,
5098
- "to-migration-version": args.flags["to-migration-version"] ?? "current"
5099
- }
5100
- }
5101
- }),
5102
- tui: {
5103
- renderer: {
5104
- bufferMode: "alternate"
5105
- }
5106
- }
5107
- } : {}
5108
- });
5109
-
5110
- // src/commands/sync.ts
5111
- var syncCommand = defineCommand({
5112
- description: "Run the common generated-project sync workflow.",
5113
- handler: async (args) => {
5114
- await executeSyncCommand({
5115
- check: Boolean(args.flags.check),
5116
- cwd: args.cwd
5117
- });
5118
- },
5119
- name: "sync",
5120
- options: {
5121
- check: {
5122
- argumentKind: "flag",
5123
- description: "Check generated artifacts without writing changes. Advanced sync-types-only flags stay on sync-types.",
5124
- schema: exports_external.boolean().default(false)
5125
- }
5126
- }
5127
- });
5128
-
5129
- // src/commands/templates.ts
5130
- var templatesCommand = defineCommand({
5131
- defaultFormat: "json",
5132
- description: "Inspect built-in and external scaffold templates.",
5133
- handler: async (args) => {
5134
- const subcommand = args.positional[0] ?? "list";
5135
- const id = args.positional[1] ?? args.flags.id;
5136
- const effectiveSubcommand = subcommand === "list" && typeof id === "string" && id.length > 0 ? "inspect" : subcommand;
5137
- const prefersStructuredOutput = args.formatExplicit && args.format !== "toon" || args.agent || Boolean(args.context?.store?.isAIAgent);
5138
- if (prefersStructuredOutput) {
5139
- const templates = await listTemplatesForRuntime();
5140
- if (effectiveSubcommand === "list") {
5141
- args.output({ templates });
5142
- return;
5143
- }
5144
- if (effectiveSubcommand === "inspect" && id) {
5145
- const template = templates.find((entry) => entry.id === id);
5146
- if (!template) {
5147
- throw new Error(`Unknown template "${id}".`);
5148
- }
5149
- args.output({ template });
5150
- return;
5151
- }
5152
- }
5153
- await executeTemplatesCommand({
5154
- flags: { id, subcommand: effectiveSubcommand }
5155
- });
5156
- },
5157
- name: "templates",
5158
- options: buildCommandOptions(TEMPLATES_OPTION_METADATA)
5159
- });
5160
-
5161
- // src/command-list.ts
5162
- var wpTypiaCommands = [
5163
- createCommand,
5164
- syncCommand,
5165
- addCommand,
5166
- migrateCommand,
5167
- templatesCommand,
5168
- doctorCommand,
5169
- mcpCommand
5170
- ];
5171
-
5172
- // src/config-override.ts
5173
- function extractWpTypiaConfigOverride(argv) {
5174
- const nextArgv = [];
5175
- let configOverridePath;
5176
- for (let index = 0;index < argv.length; index += 1) {
5177
- const arg = argv[index];
5178
- if (!arg) {
5179
- continue;
5180
- }
5181
- if (arg === "--") {
5182
- nextArgv.push(...argv.slice(index));
5183
- break;
5184
- }
5185
- if (arg === "--config" || arg === "-c") {
5186
- const next = argv[index + 1];
5187
- if (!next || next.startsWith("-")) {
5188
- throw new Error(`\`${arg}\` requires a value.`);
5189
- }
5190
- configOverridePath = next;
5191
- index += 1;
5192
- continue;
5193
- }
5194
- if (arg.startsWith("--config=")) {
5195
- const inlineValue = arg.slice("--config=".length);
5196
- if (!inlineValue) {
5197
- throw new Error("`--config` requires a value.");
5198
- }
5199
- configOverridePath = inlineValue;
5200
- continue;
5201
- }
5202
- nextArgv.push(arg);
5203
- }
5204
- return {
5205
- argv: nextArgv,
5206
- configOverridePath
5207
- };
5208
- }
5209
-
5210
- // src/plugins/wp-typia-skills.ts
5211
- function createWpTypiaSkillsMetadataPlugin(commands) {
5212
- return {
5213
- name: "wp-typia-skills-metadata",
5214
- setup(context) {
5215
- context.store.set("_skillsCommands", new Map(commands.map((command) => [command.name, command])));
5216
- context.store.set("_skillsCliName", "wp-typia");
5217
- }
5218
- };
5219
- }
5220
-
5221
- // src/plugins/wp-typia-user-config.ts
5222
- var wpTypiaUserConfigPlugin = createPlugin((options = {}) => {
5223
- let resolvedConfig = {};
5224
- return {
5225
- name: "wp-typia-user-config",
5226
- async setup(context) {
5227
- resolvedConfig = await loadWpTypiaUserConfig(context.paths.cwd);
5228
- if (options.overrideSource) {
5229
- const overrideConfig = await loadWpTypiaUserConfigFromSource(context.paths.cwd, options.overrideSource);
5230
- resolvedConfig = mergeWpTypiaUserConfig(resolvedConfig, overrideConfig);
5231
- }
5232
- },
5233
- beforeCommand(context) {
5234
- context.store.wpTypiaUserConfig = resolvedConfig;
5235
- }
5236
- };
5237
- });
5238
-
5239
- // src/cli.ts
5240
2502
  function resolveGeneratedMetadataPath(moduleUrl) {
5241
2503
  const candidates = [
5242
2504
  new URL("./.bunli/commands.gen.js", moduleUrl),
@@ -5244,22 +2506,24 @@ function resolveGeneratedMetadataPath(moduleUrl) {
5244
2506
  new URL("../.bunli/commands.gen.ts", moduleUrl)
5245
2507
  ];
5246
2508
  for (const candidate of candidates) {
5247
- const candidatePath = fileURLToPath2(candidate);
5248
- if (fs6.existsSync(candidatePath)) {
2509
+ const candidatePath = fileURLToPath(candidate);
2510
+ if (fs.existsSync(candidatePath)) {
5249
2511
  return candidatePath;
5250
2512
  }
5251
2513
  }
5252
- return fileURLToPath2(new URL("../.bunli/commands.gen.ts", moduleUrl));
2514
+ return fileURLToPath(new URL("../.bunli/commands.gen.ts", moduleUrl));
5253
2515
  }
5254
2516
  async function formatCliError(error) {
5255
2517
  try {
5256
- const { formatCliDiagnosticError } = await import("./cli-diagnostics-c65hhyhx.js");
2518
+ const { formatCliDiagnosticError } = await import("./cli-diagnostics-e5gxeprp.js");
5257
2519
  return formatCliDiagnosticError(error);
5258
2520
  } catch {
5259
2521
  return error instanceof Error ? error.message : String(error);
5260
2522
  }
5261
2523
  }
5262
2524
  async function createWpTypiaCli(options = {}) {
2525
+ applyStandaloneSupportLayoutEnv();
2526
+ const { wpTypiaCommands } = await import("./command-list-37n1za5q.js");
5263
2527
  const cli = await createCLI({
5264
2528
  ...bunliConfig,
5265
2529
  description: package_default.description,
@@ -5301,7 +2565,7 @@ async function runCliEntrypoint(argv = process.argv.slice(2)) {
5301
2565
  await main(argv);
5302
2566
  } catch (error) {
5303
2567
  console.error(`Error: ${await formatCliError(error)}`);
5304
- process.exit(1);
2568
+ process.exitCode = 1;
5305
2569
  }
5306
2570
  }
5307
2571
  if (import.meta.main) {
@@ -5315,4 +2579,4 @@ export {
5315
2579
  createWpTypiaCli
5316
2580
  };
5317
2581
 
5318
- //# debugId=55AB25074B8174E464756E2164756E21
2582
+ //# debugId=0C9C19F6722BBE6B64756E2164756E21