everything-dev 1.26.0 → 1.27.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 (121) hide show
  1. package/dist/api-contract.cjs.map +1 -1
  2. package/dist/api-contract.mjs.map +1 -1
  3. package/dist/cli/catalog.cjs.map +1 -1
  4. package/dist/cli/catalog.mjs.map +1 -1
  5. package/dist/cli/framework-version.cjs.map +1 -1
  6. package/dist/cli/framework-version.mjs.map +1 -1
  7. package/dist/cli/infra.cjs.map +1 -1
  8. package/dist/cli/infra.mjs.map +1 -1
  9. package/dist/cli/init.cjs +127 -114
  10. package/dist/cli/init.cjs.map +1 -1
  11. package/dist/cli/init.d.cts +7 -6
  12. package/dist/cli/init.d.cts.map +1 -1
  13. package/dist/cli/init.d.mts +7 -6
  14. package/dist/cli/init.d.mts.map +1 -1
  15. package/dist/cli/init.mjs +124 -114
  16. package/dist/cli/init.mjs.map +1 -1
  17. package/dist/cli/parse.cjs.map +1 -1
  18. package/dist/cli/parse.mjs.map +1 -1
  19. package/dist/cli/prompts.cjs +3 -3
  20. package/dist/cli/prompts.cjs.map +1 -1
  21. package/dist/cli/prompts.mjs +2 -2
  22. package/dist/cli/prompts.mjs.map +1 -1
  23. package/dist/cli/status.cjs.map +1 -1
  24. package/dist/cli/status.mjs.map +1 -1
  25. package/dist/cli/sync.cjs +42 -92
  26. package/dist/cli/sync.cjs.map +1 -1
  27. package/dist/cli/sync.mjs +45 -95
  28. package/dist/cli/sync.mjs.map +1 -1
  29. package/dist/cli/timing.cjs.map +1 -1
  30. package/dist/cli/timing.mjs.map +1 -1
  31. package/dist/cli/upgrade.cjs +43 -22
  32. package/dist/cli/upgrade.cjs.map +1 -1
  33. package/dist/cli/upgrade.mjs +44 -23
  34. package/dist/cli/upgrade.mjs.map +1 -1
  35. package/dist/cli.cjs +1 -1
  36. package/dist/cli.cjs.map +1 -1
  37. package/dist/cli.mjs +1 -1
  38. package/dist/cli.mjs.map +1 -1
  39. package/dist/components/dev-view.cjs.map +1 -1
  40. package/dist/components/dev-view.mjs.map +1 -1
  41. package/dist/components/streaming-view.cjs.map +1 -1
  42. package/dist/components/streaming-view.mjs.map +1 -1
  43. package/dist/config.cjs.map +1 -1
  44. package/dist/config.mjs.map +1 -1
  45. package/dist/contract.cjs +174 -173
  46. package/dist/contract.cjs.map +1 -1
  47. package/dist/contract.d.cts +3 -3
  48. package/dist/contract.d.cts.map +1 -1
  49. package/dist/contract.d.mts +3 -3
  50. package/dist/contract.d.mts.map +1 -1
  51. package/dist/contract.meta.cjs +1 -1
  52. package/dist/contract.meta.cjs.map +1 -1
  53. package/dist/contract.meta.d.cts +1 -1
  54. package/dist/contract.meta.d.mts +1 -1
  55. package/dist/contract.meta.mjs +1 -1
  56. package/dist/contract.meta.mjs.map +1 -1
  57. package/dist/contract.mjs +2 -1
  58. package/dist/contract.mjs.map +1 -1
  59. package/dist/dev-logs.cjs.map +1 -1
  60. package/dist/dev-logs.mjs.map +1 -1
  61. package/dist/fastkv.cjs.map +1 -1
  62. package/dist/fastkv.mjs.map +1 -1
  63. package/dist/index.cjs +3 -3
  64. package/dist/index.d.cts +1 -1
  65. package/dist/index.d.mts +1 -1
  66. package/dist/index.mjs +1 -1
  67. package/dist/integrity.cjs.map +1 -1
  68. package/dist/integrity.mjs.map +1 -1
  69. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  70. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  71. package/dist/merge.cjs.map +1 -1
  72. package/dist/merge.mjs.map +1 -1
  73. package/dist/near-cli.cjs.map +1 -1
  74. package/dist/near-cli.mjs.map +1 -1
  75. package/dist/orchestrator.cjs.map +1 -1
  76. package/dist/orchestrator.mjs.map +1 -1
  77. package/dist/plugin.cjs +72 -50
  78. package/dist/plugin.cjs.map +1 -1
  79. package/dist/plugin.d.cts +2 -2
  80. package/dist/plugin.d.cts.map +1 -1
  81. package/dist/plugin.d.mts +2 -2
  82. package/dist/plugin.d.mts.map +1 -1
  83. package/dist/plugin.mjs +53 -32
  84. package/dist/plugin.mjs.map +1 -1
  85. package/dist/sdk.cjs +2 -2
  86. package/dist/sdk.d.cts +1 -1
  87. package/dist/sdk.d.mts +1 -1
  88. package/dist/sdk.mjs +1 -1
  89. package/dist/shared.cjs.map +1 -1
  90. package/dist/shared.mjs.map +1 -1
  91. package/dist/types.cjs +184 -184
  92. package/dist/types.cjs.map +1 -1
  93. package/dist/types.d.cts +3 -3
  94. package/dist/types.d.mts +3 -3
  95. package/dist/types.mjs +1 -1
  96. package/dist/types.mjs.map +1 -1
  97. package/dist/ui/types.d.cts +1 -0
  98. package/dist/ui/types.d.cts.map +1 -1
  99. package/dist/ui/types.d.mts +1 -0
  100. package/dist/ui/types.d.mts.map +1 -1
  101. package/dist/utils/banner.cjs.map +1 -1
  102. package/dist/utils/banner.mjs.map +1 -1
  103. package/dist/utils/run.cjs.map +1 -1
  104. package/dist/utils/run.mjs.map +1 -1
  105. package/package.json +2 -2
  106. package/skills/init-upgrade/SKILL.md +22 -16
  107. package/skills/publish-sync/SKILL.md +7 -18
  108. package/src/cli/init.ts +149 -195
  109. package/src/cli/prompts.ts +1 -1
  110. package/src/cli/sync.ts +48 -137
  111. package/src/cli/upgrade.ts +66 -25
  112. package/src/contract.meta.ts +1 -1
  113. package/src/contract.ts +2 -1
  114. package/src/plugin.ts +69 -34
  115. package/src/sdk.ts +1 -1
  116. package/src/types.ts +1 -1
  117. package/src/ui/types.ts +1 -0
  118. package/dist/utils/path-match.cjs +0 -18
  119. package/dist/utils/path-match.cjs.map +0 -1
  120. package/dist/utils/path-match.mjs +0 -17
  121. package/dist/utils/path-match.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"parse.cjs","names":[],"sources":["../../src/cli/parse.ts"],"sourcesContent":["import type { CommandDescriptor } from \"./catalog\";\n\ntype SchemaLike = {\n _def?: {\n type?: string;\n innerType?: SchemaLike;\n shape?: Record<string, SchemaLike>;\n values?: Record<string, string> | string[];\n };\n parse: (value: unknown) => unknown;\n};\n\nfunction unwrap(schema: SchemaLike): SchemaLike {\n let current = schema;\n while (true) {\n const type = current._def?.type;\n if (type === \"default\" || type === \"optional\" || type === \"nullable\" || type === \"nullish\") {\n const inner = current._def?.innerType;\n if (!inner) break;\n current = inner;\n continue;\n }\n return current;\n }\n return current;\n}\n\nfunction isBooleanSchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"boolean\";\n}\n\nfunction isArraySchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"array\";\n}\n\nfunction coerceValue(raw: string, schema: SchemaLike): unknown {\n const inner = unwrap(schema);\n switch (inner._def?.type) {\n case \"boolean\":\n return raw === \"true\" || raw === \"1\" || raw === \"yes\";\n case \"number\": {\n const value = Number(raw);\n if (Number.isNaN(value)) throw new Error(`Invalid number: ${raw}`);\n return value;\n }\n case \"enum\":\n return raw;\n default:\n return raw;\n }\n}\n\nfunction toFlagName(field: string): string {\n return `--${field.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase()}`;\n}\n\nfunction getShape(schema: SchemaLike): Record<string, SchemaLike> {\n const inner = unwrap(schema);\n const shape = inner._def?.shape;\n if (!shape) return {};\n return shape;\n}\n\nexport function parseCommandInput(descriptor: CommandDescriptor, argv: string[]): unknown {\n const schema = (descriptor.procedure as any)[\"~orpc\"]?.inputSchema as SchemaLike | undefined;\n if (!schema) return {};\n\n const shape = getShape(schema);\n const fields = Object.entries(shape);\n const fieldByFlag = new Map<string, string>();\n const positionalFields: string[] = [];\n\n for (const [fieldName] of fields) {\n fieldByFlag.set(toFlagName(fieldName), fieldName);\n if (descriptor.meta.fields?.[fieldName]?.positional) {\n positionalFields.push(fieldName);\n }\n }\n\n const input: Record<string, unknown> = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i += 1) {\n const token = argv[i];\n if (!token) continue;\n\n if (token.startsWith(\"--no-\")) {\n const flagName = `--${token.slice(5)}`;\n const fieldName = fieldByFlag.get(flagName);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n input[fieldName] = false;\n continue;\n }\n\n if (token.startsWith(\"--\")) {\n const [flag, inline] = token.split(\"=\", 2);\n const fieldName = fieldByFlag.get(flag);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n\n const fieldSchema = shape[fieldName];\n if (isBooleanSchema(fieldSchema)) {\n input[fieldName] = inline ? coerceValue(inline, fieldSchema) : true;\n continue;\n }\n\n const next = inline ?? argv[i + 1];\n\n if (isArraySchema(fieldSchema)) {\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = next\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(Boolean);\n if (!inline) i += 1;\n continue;\n }\n\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = coerceValue(next, fieldSchema);\n if (!inline) i += 1;\n continue;\n }\n\n positionals.push(token);\n }\n\n if (positionalFields.length > 0) {\n positionalFields.forEach((fieldName, index) => {\n const raw = positionals[index];\n if (raw !== undefined) {\n input[fieldName] = coerceValue(raw, shape[fieldName]);\n }\n });\n } else if (positionals.length > 0) {\n const candidate = fields.find(([, fieldSchema]) => !isBooleanSchema(fieldSchema));\n if (candidate) {\n const [fieldName, fieldSchema] = candidate;\n input[fieldName] = coerceValue(positionals[0], fieldSchema);\n }\n }\n\n return schema.parse(input);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"parse.cjs","names":[],"sources":["../../src/cli/parse.ts"],"sourcesContent":["import type { CommandDescriptor } from \"./catalog\";\n\ntype SchemaLike = {\n _def?: {\n type?: string;\n innerType?: SchemaLike;\n shape?: Record<string, SchemaLike>;\n values?: Record<string, string> | string[];\n };\n parse: (value: unknown) => unknown;\n};\n\nfunction unwrap(schema: SchemaLike): SchemaLike {\n let current = schema;\n while (true) {\n const type = current._def?.type;\n if (type === \"default\" || type === \"optional\" || type === \"nullable\" || type === \"nullish\") {\n const inner = current._def?.innerType;\n if (!inner) break;\n current = inner;\n continue;\n }\n return current;\n }\n return current;\n}\n\nfunction isBooleanSchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"boolean\";\n}\n\nfunction isArraySchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"array\";\n}\n\nfunction coerceValue(raw: string, schema: SchemaLike): unknown {\n const inner = unwrap(schema);\n switch (inner._def?.type) {\n case \"boolean\":\n return raw === \"true\" || raw === \"1\" || raw === \"yes\";\n case \"number\": {\n const value = Number(raw);\n if (Number.isNaN(value)) throw new Error(`Invalid number: ${raw}`);\n return value;\n }\n case \"enum\":\n return raw;\n default:\n return raw;\n }\n}\n\nfunction toFlagName(field: string): string {\n return `--${field.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase()}`;\n}\n\nfunction getShape(schema: SchemaLike): Record<string, SchemaLike> {\n const inner = unwrap(schema);\n const shape = inner._def?.shape;\n if (!shape) return {};\n return shape;\n}\n\nexport function parseCommandInput(descriptor: CommandDescriptor, argv: string[]): unknown {\n const schema = (descriptor.procedure as any)[\"~orpc\"]?.inputSchema as SchemaLike | undefined;\n if (!schema) return {};\n\n const shape = getShape(schema);\n const fields = Object.entries(shape);\n const fieldByFlag = new Map<string, string>();\n const positionalFields: string[] = [];\n\n for (const [fieldName] of fields) {\n fieldByFlag.set(toFlagName(fieldName), fieldName);\n if (descriptor.meta.fields?.[fieldName]?.positional) {\n positionalFields.push(fieldName);\n }\n }\n\n const input: Record<string, unknown> = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i += 1) {\n const token = argv[i];\n if (!token) continue;\n\n if (token.startsWith(\"--no-\")) {\n const flagName = `--${token.slice(5)}`;\n const fieldName = fieldByFlag.get(flagName);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n input[fieldName] = false;\n continue;\n }\n\n if (token.startsWith(\"--\")) {\n const [flag, inline] = token.split(\"=\", 2);\n const fieldName = fieldByFlag.get(flag);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n\n const fieldSchema = shape[fieldName];\n if (isBooleanSchema(fieldSchema)) {\n input[fieldName] = inline ? coerceValue(inline, fieldSchema) : true;\n continue;\n }\n\n const next = inline ?? argv[i + 1];\n\n if (isArraySchema(fieldSchema)) {\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = next\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(Boolean);\n if (!inline) i += 1;\n continue;\n }\n\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = coerceValue(next, fieldSchema);\n if (!inline) i += 1;\n continue;\n }\n\n positionals.push(token);\n }\n\n if (positionalFields.length > 0) {\n positionalFields.forEach((fieldName, index) => {\n const raw = positionals[index];\n if (raw !== undefined) {\n input[fieldName] = coerceValue(raw, shape[fieldName]);\n }\n });\n } else if (positionals.length > 0) {\n const candidate = fields.find(([, fieldSchema]) => !isBooleanSchema(fieldSchema));\n if (candidate) {\n const [fieldName, fieldSchema] = candidate;\n input[fieldName] = coerceValue(positionals[0], fieldSchema);\n }\n }\n\n return schema.parse(input);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse.mjs","names":[],"sources":["../../src/cli/parse.ts"],"sourcesContent":["import type { CommandDescriptor } from \"./catalog\";\n\ntype SchemaLike = {\n _def?: {\n type?: string;\n innerType?: SchemaLike;\n shape?: Record<string, SchemaLike>;\n values?: Record<string, string> | string[];\n };\n parse: (value: unknown) => unknown;\n};\n\nfunction unwrap(schema: SchemaLike): SchemaLike {\n let current = schema;\n while (true) {\n const type = current._def?.type;\n if (type === \"default\" || type === \"optional\" || type === \"nullable\" || type === \"nullish\") {\n const inner = current._def?.innerType;\n if (!inner) break;\n current = inner;\n continue;\n }\n return current;\n }\n return current;\n}\n\nfunction isBooleanSchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"boolean\";\n}\n\nfunction isArraySchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"array\";\n}\n\nfunction coerceValue(raw: string, schema: SchemaLike): unknown {\n const inner = unwrap(schema);\n switch (inner._def?.type) {\n case \"boolean\":\n return raw === \"true\" || raw === \"1\" || raw === \"yes\";\n case \"number\": {\n const value = Number(raw);\n if (Number.isNaN(value)) throw new Error(`Invalid number: ${raw}`);\n return value;\n }\n case \"enum\":\n return raw;\n default:\n return raw;\n }\n}\n\nfunction toFlagName(field: string): string {\n return `--${field.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase()}`;\n}\n\nfunction getShape(schema: SchemaLike): Record<string, SchemaLike> {\n const inner = unwrap(schema);\n const shape = inner._def?.shape;\n if (!shape) return {};\n return shape;\n}\n\nexport function parseCommandInput(descriptor: CommandDescriptor, argv: string[]): unknown {\n const schema = (descriptor.procedure as any)[\"~orpc\"]?.inputSchema as SchemaLike | undefined;\n if (!schema) return {};\n\n const shape = getShape(schema);\n const fields = Object.entries(shape);\n const fieldByFlag = new Map<string, string>();\n const positionalFields: string[] = [];\n\n for (const [fieldName] of fields) {\n fieldByFlag.set(toFlagName(fieldName), fieldName);\n if (descriptor.meta.fields?.[fieldName]?.positional) {\n positionalFields.push(fieldName);\n }\n }\n\n const input: Record<string, unknown> = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i += 1) {\n const token = argv[i];\n if (!token) continue;\n\n if (token.startsWith(\"--no-\")) {\n const flagName = `--${token.slice(5)}`;\n const fieldName = fieldByFlag.get(flagName);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n input[fieldName] = false;\n continue;\n }\n\n if (token.startsWith(\"--\")) {\n const [flag, inline] = token.split(\"=\", 2);\n const fieldName = fieldByFlag.get(flag);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n\n const fieldSchema = shape[fieldName];\n if (isBooleanSchema(fieldSchema)) {\n input[fieldName] = inline ? coerceValue(inline, fieldSchema) : true;\n continue;\n }\n\n const next = inline ?? argv[i + 1];\n\n if (isArraySchema(fieldSchema)) {\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = next\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(Boolean);\n if (!inline) i += 1;\n continue;\n }\n\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = coerceValue(next, fieldSchema);\n if (!inline) i += 1;\n continue;\n }\n\n positionals.push(token);\n }\n\n if (positionalFields.length > 0) {\n positionalFields.forEach((fieldName, index) => {\n const raw = positionals[index];\n if (raw !== undefined) {\n input[fieldName] = coerceValue(raw, shape[fieldName]);\n }\n });\n } else if (positionals.length > 0) {\n const candidate = fields.find(([, fieldSchema]) => !isBooleanSchema(fieldSchema));\n if (candidate) {\n const [fieldName, fieldSchema] = candidate;\n input[fieldName] = coerceValue(positionals[0], fieldSchema);\n }\n }\n\n return schema.parse(input);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"parse.mjs","names":[],"sources":["../../src/cli/parse.ts"],"sourcesContent":["import type { CommandDescriptor } from \"./catalog\";\n\ntype SchemaLike = {\n _def?: {\n type?: string;\n innerType?: SchemaLike;\n shape?: Record<string, SchemaLike>;\n values?: Record<string, string> | string[];\n };\n parse: (value: unknown) => unknown;\n};\n\nfunction unwrap(schema: SchemaLike): SchemaLike {\n let current = schema;\n while (true) {\n const type = current._def?.type;\n if (type === \"default\" || type === \"optional\" || type === \"nullable\" || type === \"nullish\") {\n const inner = current._def?.innerType;\n if (!inner) break;\n current = inner;\n continue;\n }\n return current;\n }\n return current;\n}\n\nfunction isBooleanSchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"boolean\";\n}\n\nfunction isArraySchema(schema: SchemaLike): boolean {\n return unwrap(schema)._def?.type === \"array\";\n}\n\nfunction coerceValue(raw: string, schema: SchemaLike): unknown {\n const inner = unwrap(schema);\n switch (inner._def?.type) {\n case \"boolean\":\n return raw === \"true\" || raw === \"1\" || raw === \"yes\";\n case \"number\": {\n const value = Number(raw);\n if (Number.isNaN(value)) throw new Error(`Invalid number: ${raw}`);\n return value;\n }\n case \"enum\":\n return raw;\n default:\n return raw;\n }\n}\n\nfunction toFlagName(field: string): string {\n return `--${field.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase()}`;\n}\n\nfunction getShape(schema: SchemaLike): Record<string, SchemaLike> {\n const inner = unwrap(schema);\n const shape = inner._def?.shape;\n if (!shape) return {};\n return shape;\n}\n\nexport function parseCommandInput(descriptor: CommandDescriptor, argv: string[]): unknown {\n const schema = (descriptor.procedure as any)[\"~orpc\"]?.inputSchema as SchemaLike | undefined;\n if (!schema) return {};\n\n const shape = getShape(schema);\n const fields = Object.entries(shape);\n const fieldByFlag = new Map<string, string>();\n const positionalFields: string[] = [];\n\n for (const [fieldName] of fields) {\n fieldByFlag.set(toFlagName(fieldName), fieldName);\n if (descriptor.meta.fields?.[fieldName]?.positional) {\n positionalFields.push(fieldName);\n }\n }\n\n const input: Record<string, unknown> = {};\n const positionals: string[] = [];\n\n for (let i = 0; i < argv.length; i += 1) {\n const token = argv[i];\n if (!token) continue;\n\n if (token.startsWith(\"--no-\")) {\n const flagName = `--${token.slice(5)}`;\n const fieldName = fieldByFlag.get(flagName);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n input[fieldName] = false;\n continue;\n }\n\n if (token.startsWith(\"--\")) {\n const [flag, inline] = token.split(\"=\", 2);\n const fieldName = fieldByFlag.get(flag);\n if (!fieldName) throw new Error(`Unknown flag: ${token}`);\n\n const fieldSchema = shape[fieldName];\n if (isBooleanSchema(fieldSchema)) {\n input[fieldName] = inline ? coerceValue(inline, fieldSchema) : true;\n continue;\n }\n\n const next = inline ?? argv[i + 1];\n\n if (isArraySchema(fieldSchema)) {\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = next\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(Boolean);\n if (!inline) i += 1;\n continue;\n }\n\n if (next === undefined || next.startsWith(\"--\")) {\n throw new Error(`Missing value for ${flag}`);\n }\n input[fieldName] = coerceValue(next, fieldSchema);\n if (!inline) i += 1;\n continue;\n }\n\n positionals.push(token);\n }\n\n if (positionalFields.length > 0) {\n positionalFields.forEach((fieldName, index) => {\n const raw = positionals[index];\n if (raw !== undefined) {\n input[fieldName] = coerceValue(raw, shape[fieldName]);\n }\n });\n } else if (positionals.length > 0) {\n const candidate = fields.find(([, fieldSchema]) => !isBooleanSchema(fieldSchema));\n if (candidate) {\n const [fieldName, fieldSchema] = candidate;\n input[fieldName] = coerceValue(positionals[0], fieldSchema);\n }\n }\n\n return schema.parse(input);\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
2
- let _clack_prompts = require("@clack/prompts");
3
- _clack_prompts = require_runtime.__toESM(_clack_prompts, 1);
4
2
  let node_process = require("node:process");
5
3
  node_process = require_runtime.__toESM(node_process, 1);
4
+ let _clack_prompts = require("@clack/prompts");
5
+ _clack_prompts = require_runtime.__toESM(_clack_prompts, 1);
6
6
 
7
7
  //#region src/cli/prompts.ts
8
8
  function parseExtendsRef(ref) {
@@ -70,7 +70,7 @@ async function promptInitOptions(input) {
70
70
  if (_clack_prompts.isCancel(account)) node_process.default.exit(0);
71
71
  const directory = input.directory || domain || extendsGateway;
72
72
  const overrides = input.overrides ?? await _clack_prompts.multiselect({
73
- message: "Which sections to override locally?",
73
+ message: "What do you want to customize?",
74
74
  options: OVERRIDE_OPTIONS,
75
75
  initialValues: ["ui", "api"],
76
76
  required: false
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.cjs","names":["p"],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport type { OverrideSection } from \"../contract\";\n\nfunction parseExtendsRef(ref: string): { account: string; gateway: string } | null {\n const normalized = ref.startsWith(\"bos://\") ? ref : `bos://${ref}`;\n const match = normalized.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match) return null;\n return { account: match[1], gateway: match[2] };\n}\n\nfunction deriveAccountFromExtends(domain: string, extendsAccount: string): string {\n const firstSegment = domain.split(\".\")[0];\n if (!firstSegment) return \"\";\n const suffix = extendsAccount.includes(\".\")\n ? extendsAccount.substring(extendsAccount.indexOf(\".\") + 1)\n : extendsAccount;\n return `${firstSegment}.${suffix}`;\n}\n\nconst OVERRIDE_OPTIONS: { value: OverrideSection; label: string; hint: string }[] = [\n { value: \"ui\", label: \"ui\", hint: \"Override UI with local source\" },\n { value: \"api\", label: \"api\", hint: \"Override API with local source\" },\n { value: \"host\", label: \"host\", hint: \"Override host with local source\" },\n { value: \"plugins\", label: \"plugins\", hint: \"Override selected plugins with local source\" },\n];\n\nexport async function promptInitOptions(input: {\n extends?: string;\n directory?: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n overrides?: OverrideSection[];\n parentPluginKeys?: string[];\n}): Promise<{\n extendsAccount: string;\n extendsGateway: string;\n directory: string;\n account?: string;\n domain?: string;\n plugins: string[];\n overrides: OverrideSection[];\n}> {\n p.intro(\"Let's build an app...\");\n\n const extendsInput =\n input.extends ??\n ((await p.text({\n message: \"Extending an existing app?\",\n placeholder: \"bos://dev.everything.near/everything.dev\",\n })) as string);\n\n if (p.isCancel(extendsInput)) process.exit(0);\n\n let extendsAccount = \"dev.everything.near\";\n let extendsGateway = \"everything.dev\";\n\n if (extendsInput) {\n const parsed = parseExtendsRef(extendsInput);\n if (parsed) {\n extendsAccount = parsed.account;\n extendsGateway = parsed.gateway;\n }\n }\n\n const domain =\n input.domain ??\n ((await p.text({\n message: \"Starting with a domain?\",\n placeholder: \"no\",\n })) as string);\n\n if (p.isCancel(domain)) process.exit(0);\n\n const accountDefault = domain ? deriveAccountFromExtends(domain, extendsAccount) : \"\";\n const account =\n input.account ??\n ((await p.text({\n message: \"What NEAR account will you publish from?\",\n placeholder: accountDefault || \"skip\",\n defaultValue: accountDefault,\n })) as string);\n\n if (p.isCancel(account)) process.exit(0);\n\n const directory = input.directory || domain || extendsGateway;\n\n const overrides =\n input.overrides ??\n ((await p.multiselect({\n message: \"Which sections to override locally?\",\n options: OVERRIDE_OPTIONS,\n initialValues: [\"ui\", \"api\"] as OverrideSection[],\n required: false,\n })) as OverrideSection[]);\n\n if (p.isCancel(overrides)) process.exit(0);\n\n let plugins: string[] = [];\n if (overrides.includes(\"plugins\")) {\n const parentPlugins = input.parentPluginKeys ?? [];\n const pluginOptions =\n parentPlugins.length > 0 ? parentPlugins.map((key) => ({ value: key, label: key })) : [];\n\n plugins =\n input.plugins ??\n (pluginOptions.length > 0\n ? ((await p.multiselect({\n message: \"Select plugins to include:\",\n options: pluginOptions,\n required: false,\n })) as string[])\n : []);\n\n if (p.isCancel(plugins)) process.exit(0);\n }\n\n const go = await p.confirm({\n message: \"GO!\",\n initialValue: true,\n });\n\n if (p.isCancel(go) || !go) process.exit(0);\n\n return {\n extendsAccount,\n extendsGateway,\n directory,\n account: account || undefined,\n domain: domain || undefined,\n plugins,\n overrides,\n };\n}\n"],"mappings":";;;;;;;AAIA,SAAS,gBAAgB,KAA0D;CAEjF,MAAM,SADa,IAAI,WAAW,SAAS,GAAG,MAAM,SAAS,OACpC,MAAM,0BAA0B;AACzD,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EAAE,SAAS,MAAM;EAAI,SAAS,MAAM;EAAI;;AAGjD,SAAS,yBAAyB,QAAgB,gBAAgC;CAChF,MAAM,eAAe,OAAO,MAAM,IAAI,CAAC;AACvC,KAAI,CAAC,aAAc,QAAO;AAI1B,QAAO,GAAG,aAAa,GAHR,eAAe,SAAS,IAAI,GACvC,eAAe,UAAU,eAAe,QAAQ,IAAI,GAAG,EAAE,GACzD;;AAIN,MAAM,mBAA8E;CAClF;EAAE,OAAO;EAAM,OAAO;EAAM,MAAM;EAAiC;CACnE;EAAE,OAAO;EAAO,OAAO;EAAO,MAAM;EAAkC;CACtE;EAAE,OAAO;EAAQ,OAAO;EAAQ,MAAM;EAAmC;CACzE;EAAE,OAAO;EAAW,OAAO;EAAW,MAAM;EAA+C;CAC5F;AAED,eAAsB,kBAAkB,OAgBrC;AACD,gBAAE,MAAM,wBAAwB;CAEhC,MAAM,eACJ,MAAM,WACJ,MAAMA,eAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAIA,eAAE,SAAS,aAAa,CAAE,sBAAQ,KAAK,EAAE;CAE7C,IAAI,iBAAiB;CACrB,IAAI,iBAAiB;AAErB,KAAI,cAAc;EAChB,MAAM,SAAS,gBAAgB,aAAa;AAC5C,MAAI,QAAQ;AACV,oBAAiB,OAAO;AACxB,oBAAiB,OAAO;;;CAI5B,MAAM,SACJ,MAAM,UACJ,MAAMA,eAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAIA,eAAE,SAAS,OAAO,CAAE,sBAAQ,KAAK,EAAE;CAEvC,MAAM,iBAAiB,SAAS,yBAAyB,QAAQ,eAAe,GAAG;CACnF,MAAM,UACJ,MAAM,WACJ,MAAMA,eAAE,KAAK;EACb,SAAS;EACT,aAAa,kBAAkB;EAC/B,cAAc;EACf,CAAC;AAEJ,KAAIA,eAAE,SAAS,QAAQ,CAAE,sBAAQ,KAAK,EAAE;CAExC,MAAM,YAAY,MAAM,aAAa,UAAU;CAE/C,MAAM,YACJ,MAAM,aACJ,MAAMA,eAAE,YAAY;EACpB,SAAS;EACT,SAAS;EACT,eAAe,CAAC,MAAM,MAAM;EAC5B,UAAU;EACX,CAAC;AAEJ,KAAIA,eAAE,SAAS,UAAU,CAAE,sBAAQ,KAAK,EAAE;CAE1C,IAAI,UAAoB,EAAE;AAC1B,KAAI,UAAU,SAAS,UAAU,EAAE;EACjC,MAAM,gBAAgB,MAAM,oBAAoB,EAAE;EAClD,MAAM,gBACJ,cAAc,SAAS,IAAI,cAAc,KAAK,SAAS;GAAE,OAAO;GAAK,OAAO;GAAK,EAAE,GAAG,EAAE;AAE1F,YACE,MAAM,YACL,cAAc,SAAS,IAClB,MAAMA,eAAE,YAAY;GACpB,SAAS;GACT,SAAS;GACT,UAAU;GACX,CAAC,GACF,EAAE;AAER,MAAIA,eAAE,SAAS,QAAQ,CAAE,sBAAQ,KAAK,EAAE;;CAG1C,MAAM,KAAK,MAAMA,eAAE,QAAQ;EACzB,SAAS;EACT,cAAc;EACf,CAAC;AAEF,KAAIA,eAAE,SAAS,GAAG,IAAI,CAAC,GAAI,sBAAQ,KAAK,EAAE;AAE1C,QAAO;EACL;EACA;EACA;EACA,SAAS,WAAW;EACpB,QAAQ,UAAU;EAClB;EACA;EACD"}
1
+ {"version":3,"file":"prompts.cjs","names":["p"],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport type { OverrideSection } from \"../contract\";\n\nfunction parseExtendsRef(ref: string): { account: string; gateway: string } | null {\n const normalized = ref.startsWith(\"bos://\") ? ref : `bos://${ref}`;\n const match = normalized.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match) return null;\n return { account: match[1], gateway: match[2] };\n}\n\nfunction deriveAccountFromExtends(domain: string, extendsAccount: string): string {\n const firstSegment = domain.split(\".\")[0];\n if (!firstSegment) return \"\";\n const suffix = extendsAccount.includes(\".\")\n ? extendsAccount.substring(extendsAccount.indexOf(\".\") + 1)\n : extendsAccount;\n return `${firstSegment}.${suffix}`;\n}\n\nconst OVERRIDE_OPTIONS: { value: OverrideSection; label: string; hint: string }[] = [\n { value: \"ui\", label: \"ui\", hint: \"Override UI with local source\" },\n { value: \"api\", label: \"api\", hint: \"Override API with local source\" },\n { value: \"host\", label: \"host\", hint: \"Override host with local source\" },\n { value: \"plugins\", label: \"plugins\", hint: \"Override selected plugins with local source\" },\n];\n\nexport async function promptInitOptions(input: {\n extends?: string;\n directory?: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n overrides?: OverrideSection[];\n parentPluginKeys?: string[];\n}): Promise<{\n extendsAccount: string;\n extendsGateway: string;\n directory: string;\n account?: string;\n domain?: string;\n plugins: string[];\n overrides: OverrideSection[];\n}> {\n p.intro(\"Let's build an app...\");\n\n const extendsInput =\n input.extends ??\n ((await p.text({\n message: \"Extending an existing app?\",\n placeholder: \"bos://dev.everything.near/everything.dev\",\n })) as string);\n\n if (p.isCancel(extendsInput)) process.exit(0);\n\n let extendsAccount = \"dev.everything.near\";\n let extendsGateway = \"everything.dev\";\n\n if (extendsInput) {\n const parsed = parseExtendsRef(extendsInput);\n if (parsed) {\n extendsAccount = parsed.account;\n extendsGateway = parsed.gateway;\n }\n }\n\n const domain =\n input.domain ??\n ((await p.text({\n message: \"Starting with a domain?\",\n placeholder: \"no\",\n })) as string);\n\n if (p.isCancel(domain)) process.exit(0);\n\n const accountDefault = domain ? deriveAccountFromExtends(domain, extendsAccount) : \"\";\n const account =\n input.account ??\n ((await p.text({\n message: \"What NEAR account will you publish from?\",\n placeholder: accountDefault || \"skip\",\n defaultValue: accountDefault,\n })) as string);\n\n if (p.isCancel(account)) process.exit(0);\n\n const directory = input.directory || domain || extendsGateway;\n\n const overrides =\n input.overrides ??\n ((await p.multiselect({\n message: \"What do you want to customize?\",\n options: OVERRIDE_OPTIONS,\n initialValues: [\"ui\", \"api\"] as OverrideSection[],\n required: false,\n })) as OverrideSection[]);\n\n if (p.isCancel(overrides)) process.exit(0);\n\n let plugins: string[] = [];\n if (overrides.includes(\"plugins\")) {\n const parentPlugins = input.parentPluginKeys ?? [];\n const pluginOptions =\n parentPlugins.length > 0 ? parentPlugins.map((key) => ({ value: key, label: key })) : [];\n\n plugins =\n input.plugins ??\n (pluginOptions.length > 0\n ? ((await p.multiselect({\n message: \"Select plugins to include:\",\n options: pluginOptions,\n required: false,\n })) as string[])\n : []);\n\n if (p.isCancel(plugins)) process.exit(0);\n }\n\n const go = await p.confirm({\n message: \"GO!\",\n initialValue: true,\n });\n\n if (p.isCancel(go) || !go) process.exit(0);\n\n return {\n extendsAccount,\n extendsGateway,\n directory,\n account: account || undefined,\n domain: domain || undefined,\n plugins,\n overrides,\n };\n}\n"],"mappings":";;;;;;;AAIA,SAAS,gBAAgB,KAA0D;CAEjF,MAAM,SADa,IAAI,WAAW,SAAS,GAAG,MAAM,SAAS,OACpC,MAAM,0BAA0B;AACzD,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EAAE,SAAS,MAAM;EAAI,SAAS,MAAM;EAAI;;AAGjD,SAAS,yBAAyB,QAAgB,gBAAgC;CAChF,MAAM,eAAe,OAAO,MAAM,IAAI,CAAC;AACvC,KAAI,CAAC,aAAc,QAAO;AAI1B,QAAO,GAAG,aAAa,GAHR,eAAe,SAAS,IAAI,GACvC,eAAe,UAAU,eAAe,QAAQ,IAAI,GAAG,EAAE,GACzD;;AAIN,MAAM,mBAA8E;CAClF;EAAE,OAAO;EAAM,OAAO;EAAM,MAAM;EAAiC;CACnE;EAAE,OAAO;EAAO,OAAO;EAAO,MAAM;EAAkC;CACtE;EAAE,OAAO;EAAQ,OAAO;EAAQ,MAAM;EAAmC;CACzE;EAAE,OAAO;EAAW,OAAO;EAAW,MAAM;EAA+C;CAC5F;AAED,eAAsB,kBAAkB,OAgBrC;AACD,gBAAE,MAAM,wBAAwB;CAEhC,MAAM,eACJ,MAAM,WACJ,MAAMA,eAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAIA,eAAE,SAAS,aAAa,CAAE,sBAAQ,KAAK,EAAE;CAE7C,IAAI,iBAAiB;CACrB,IAAI,iBAAiB;AAErB,KAAI,cAAc;EAChB,MAAM,SAAS,gBAAgB,aAAa;AAC5C,MAAI,QAAQ;AACV,oBAAiB,OAAO;AACxB,oBAAiB,OAAO;;;CAI5B,MAAM,SACJ,MAAM,UACJ,MAAMA,eAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAIA,eAAE,SAAS,OAAO,CAAE,sBAAQ,KAAK,EAAE;CAEvC,MAAM,iBAAiB,SAAS,yBAAyB,QAAQ,eAAe,GAAG;CACnF,MAAM,UACJ,MAAM,WACJ,MAAMA,eAAE,KAAK;EACb,SAAS;EACT,aAAa,kBAAkB;EAC/B,cAAc;EACf,CAAC;AAEJ,KAAIA,eAAE,SAAS,QAAQ,CAAE,sBAAQ,KAAK,EAAE;CAExC,MAAM,YAAY,MAAM,aAAa,UAAU;CAE/C,MAAM,YACJ,MAAM,aACJ,MAAMA,eAAE,YAAY;EACpB,SAAS;EACT,SAAS;EACT,eAAe,CAAC,MAAM,MAAM;EAC5B,UAAU;EACX,CAAC;AAEJ,KAAIA,eAAE,SAAS,UAAU,CAAE,sBAAQ,KAAK,EAAE;CAE1C,IAAI,UAAoB,EAAE;AAC1B,KAAI,UAAU,SAAS,UAAU,EAAE;EACjC,MAAM,gBAAgB,MAAM,oBAAoB,EAAE;EAClD,MAAM,gBACJ,cAAc,SAAS,IAAI,cAAc,KAAK,SAAS;GAAE,OAAO;GAAK,OAAO;GAAK,EAAE,GAAG,EAAE;AAE1F,YACE,MAAM,YACL,cAAc,SAAS,IAClB,MAAMA,eAAE,YAAY;GACpB,SAAS;GACT,SAAS;GACT,UAAU;GACX,CAAC,GACF,EAAE;AAER,MAAIA,eAAE,SAAS,QAAQ,CAAE,sBAAQ,KAAK,EAAE;;CAG1C,MAAM,KAAK,MAAMA,eAAE,QAAQ;EACzB,SAAS;EACT,cAAc;EACf,CAAC;AAEF,KAAIA,eAAE,SAAS,GAAG,IAAI,CAAC,GAAI,sBAAQ,KAAK,EAAE;AAE1C,QAAO;EACL;EACA;EACA;EACA,SAAS,WAAW;EACpB,QAAQ,UAAU;EAClB;EACA;EACD"}
@@ -1,5 +1,5 @@
1
- import * as p from "@clack/prompts";
2
1
  import process from "node:process";
2
+ import * as p from "@clack/prompts";
3
3
 
4
4
  //#region src/cli/prompts.ts
5
5
  function parseExtendsRef(ref) {
@@ -67,7 +67,7 @@ async function promptInitOptions(input) {
67
67
  if (p.isCancel(account)) process.exit(0);
68
68
  const directory = input.directory || domain || extendsGateway;
69
69
  const overrides = input.overrides ?? await p.multiselect({
70
- message: "Which sections to override locally?",
70
+ message: "What do you want to customize?",
71
71
  options: OVERRIDE_OPTIONS,
72
72
  initialValues: ["ui", "api"],
73
73
  required: false
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport type { OverrideSection } from \"../contract\";\n\nfunction parseExtendsRef(ref: string): { account: string; gateway: string } | null {\n const normalized = ref.startsWith(\"bos://\") ? ref : `bos://${ref}`;\n const match = normalized.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match) return null;\n return { account: match[1], gateway: match[2] };\n}\n\nfunction deriveAccountFromExtends(domain: string, extendsAccount: string): string {\n const firstSegment = domain.split(\".\")[0];\n if (!firstSegment) return \"\";\n const suffix = extendsAccount.includes(\".\")\n ? extendsAccount.substring(extendsAccount.indexOf(\".\") + 1)\n : extendsAccount;\n return `${firstSegment}.${suffix}`;\n}\n\nconst OVERRIDE_OPTIONS: { value: OverrideSection; label: string; hint: string }[] = [\n { value: \"ui\", label: \"ui\", hint: \"Override UI with local source\" },\n { value: \"api\", label: \"api\", hint: \"Override API with local source\" },\n { value: \"host\", label: \"host\", hint: \"Override host with local source\" },\n { value: \"plugins\", label: \"plugins\", hint: \"Override selected plugins with local source\" },\n];\n\nexport async function promptInitOptions(input: {\n extends?: string;\n directory?: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n overrides?: OverrideSection[];\n parentPluginKeys?: string[];\n}): Promise<{\n extendsAccount: string;\n extendsGateway: string;\n directory: string;\n account?: string;\n domain?: string;\n plugins: string[];\n overrides: OverrideSection[];\n}> {\n p.intro(\"Let's build an app...\");\n\n const extendsInput =\n input.extends ??\n ((await p.text({\n message: \"Extending an existing app?\",\n placeholder: \"bos://dev.everything.near/everything.dev\",\n })) as string);\n\n if (p.isCancel(extendsInput)) process.exit(0);\n\n let extendsAccount = \"dev.everything.near\";\n let extendsGateway = \"everything.dev\";\n\n if (extendsInput) {\n const parsed = parseExtendsRef(extendsInput);\n if (parsed) {\n extendsAccount = parsed.account;\n extendsGateway = parsed.gateway;\n }\n }\n\n const domain =\n input.domain ??\n ((await p.text({\n message: \"Starting with a domain?\",\n placeholder: \"no\",\n })) as string);\n\n if (p.isCancel(domain)) process.exit(0);\n\n const accountDefault = domain ? deriveAccountFromExtends(domain, extendsAccount) : \"\";\n const account =\n input.account ??\n ((await p.text({\n message: \"What NEAR account will you publish from?\",\n placeholder: accountDefault || \"skip\",\n defaultValue: accountDefault,\n })) as string);\n\n if (p.isCancel(account)) process.exit(0);\n\n const directory = input.directory || domain || extendsGateway;\n\n const overrides =\n input.overrides ??\n ((await p.multiselect({\n message: \"Which sections to override locally?\",\n options: OVERRIDE_OPTIONS,\n initialValues: [\"ui\", \"api\"] as OverrideSection[],\n required: false,\n })) as OverrideSection[]);\n\n if (p.isCancel(overrides)) process.exit(0);\n\n let plugins: string[] = [];\n if (overrides.includes(\"plugins\")) {\n const parentPlugins = input.parentPluginKeys ?? [];\n const pluginOptions =\n parentPlugins.length > 0 ? parentPlugins.map((key) => ({ value: key, label: key })) : [];\n\n plugins =\n input.plugins ??\n (pluginOptions.length > 0\n ? ((await p.multiselect({\n message: \"Select plugins to include:\",\n options: pluginOptions,\n required: false,\n })) as string[])\n : []);\n\n if (p.isCancel(plugins)) process.exit(0);\n }\n\n const go = await p.confirm({\n message: \"GO!\",\n initialValue: true,\n });\n\n if (p.isCancel(go) || !go) process.exit(0);\n\n return {\n extendsAccount,\n extendsGateway,\n directory,\n account: account || undefined,\n domain: domain || undefined,\n plugins,\n overrides,\n };\n}\n"],"mappings":";;;;AAIA,SAAS,gBAAgB,KAA0D;CAEjF,MAAM,SADa,IAAI,WAAW,SAAS,GAAG,MAAM,SAAS,OACpC,MAAM,0BAA0B;AACzD,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EAAE,SAAS,MAAM;EAAI,SAAS,MAAM;EAAI;;AAGjD,SAAS,yBAAyB,QAAgB,gBAAgC;CAChF,MAAM,eAAe,OAAO,MAAM,IAAI,CAAC;AACvC,KAAI,CAAC,aAAc,QAAO;AAI1B,QAAO,GAAG,aAAa,GAHR,eAAe,SAAS,IAAI,GACvC,eAAe,UAAU,eAAe,QAAQ,IAAI,GAAG,EAAE,GACzD;;AAIN,MAAM,mBAA8E;CAClF;EAAE,OAAO;EAAM,OAAO;EAAM,MAAM;EAAiC;CACnE;EAAE,OAAO;EAAO,OAAO;EAAO,MAAM;EAAkC;CACtE;EAAE,OAAO;EAAQ,OAAO;EAAQ,MAAM;EAAmC;CACzE;EAAE,OAAO;EAAW,OAAO;EAAW,MAAM;EAA+C;CAC5F;AAED,eAAsB,kBAAkB,OAgBrC;AACD,GAAE,MAAM,wBAAwB;CAEhC,MAAM,eACJ,MAAM,WACJ,MAAM,EAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAI,EAAE,SAAS,aAAa,CAAE,SAAQ,KAAK,EAAE;CAE7C,IAAI,iBAAiB;CACrB,IAAI,iBAAiB;AAErB,KAAI,cAAc;EAChB,MAAM,SAAS,gBAAgB,aAAa;AAC5C,MAAI,QAAQ;AACV,oBAAiB,OAAO;AACxB,oBAAiB,OAAO;;;CAI5B,MAAM,SACJ,MAAM,UACJ,MAAM,EAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAI,EAAE,SAAS,OAAO,CAAE,SAAQ,KAAK,EAAE;CAEvC,MAAM,iBAAiB,SAAS,yBAAyB,QAAQ,eAAe,GAAG;CACnF,MAAM,UACJ,MAAM,WACJ,MAAM,EAAE,KAAK;EACb,SAAS;EACT,aAAa,kBAAkB;EAC/B,cAAc;EACf,CAAC;AAEJ,KAAI,EAAE,SAAS,QAAQ,CAAE,SAAQ,KAAK,EAAE;CAExC,MAAM,YAAY,MAAM,aAAa,UAAU;CAE/C,MAAM,YACJ,MAAM,aACJ,MAAM,EAAE,YAAY;EACpB,SAAS;EACT,SAAS;EACT,eAAe,CAAC,MAAM,MAAM;EAC5B,UAAU;EACX,CAAC;AAEJ,KAAI,EAAE,SAAS,UAAU,CAAE,SAAQ,KAAK,EAAE;CAE1C,IAAI,UAAoB,EAAE;AAC1B,KAAI,UAAU,SAAS,UAAU,EAAE;EACjC,MAAM,gBAAgB,MAAM,oBAAoB,EAAE;EAClD,MAAM,gBACJ,cAAc,SAAS,IAAI,cAAc,KAAK,SAAS;GAAE,OAAO;GAAK,OAAO;GAAK,EAAE,GAAG,EAAE;AAE1F,YACE,MAAM,YACL,cAAc,SAAS,IAClB,MAAM,EAAE,YAAY;GACpB,SAAS;GACT,SAAS;GACT,UAAU;GACX,CAAC,GACF,EAAE;AAER,MAAI,EAAE,SAAS,QAAQ,CAAE,SAAQ,KAAK,EAAE;;CAG1C,MAAM,KAAK,MAAM,EAAE,QAAQ;EACzB,SAAS;EACT,cAAc;EACf,CAAC;AAEF,KAAI,EAAE,SAAS,GAAG,IAAI,CAAC,GAAI,SAAQ,KAAK,EAAE;AAE1C,QAAO;EACL;EACA;EACA;EACA,SAAS,WAAW;EACpB,QAAQ,UAAU;EAClB;EACA;EACD"}
1
+ {"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport type { OverrideSection } from \"../contract\";\n\nfunction parseExtendsRef(ref: string): { account: string; gateway: string } | null {\n const normalized = ref.startsWith(\"bos://\") ? ref : `bos://${ref}`;\n const match = normalized.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match) return null;\n return { account: match[1], gateway: match[2] };\n}\n\nfunction deriveAccountFromExtends(domain: string, extendsAccount: string): string {\n const firstSegment = domain.split(\".\")[0];\n if (!firstSegment) return \"\";\n const suffix = extendsAccount.includes(\".\")\n ? extendsAccount.substring(extendsAccount.indexOf(\".\") + 1)\n : extendsAccount;\n return `${firstSegment}.${suffix}`;\n}\n\nconst OVERRIDE_OPTIONS: { value: OverrideSection; label: string; hint: string }[] = [\n { value: \"ui\", label: \"ui\", hint: \"Override UI with local source\" },\n { value: \"api\", label: \"api\", hint: \"Override API with local source\" },\n { value: \"host\", label: \"host\", hint: \"Override host with local source\" },\n { value: \"plugins\", label: \"plugins\", hint: \"Override selected plugins with local source\" },\n];\n\nexport async function promptInitOptions(input: {\n extends?: string;\n directory?: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n overrides?: OverrideSection[];\n parentPluginKeys?: string[];\n}): Promise<{\n extendsAccount: string;\n extendsGateway: string;\n directory: string;\n account?: string;\n domain?: string;\n plugins: string[];\n overrides: OverrideSection[];\n}> {\n p.intro(\"Let's build an app...\");\n\n const extendsInput =\n input.extends ??\n ((await p.text({\n message: \"Extending an existing app?\",\n placeholder: \"bos://dev.everything.near/everything.dev\",\n })) as string);\n\n if (p.isCancel(extendsInput)) process.exit(0);\n\n let extendsAccount = \"dev.everything.near\";\n let extendsGateway = \"everything.dev\";\n\n if (extendsInput) {\n const parsed = parseExtendsRef(extendsInput);\n if (parsed) {\n extendsAccount = parsed.account;\n extendsGateway = parsed.gateway;\n }\n }\n\n const domain =\n input.domain ??\n ((await p.text({\n message: \"Starting with a domain?\",\n placeholder: \"no\",\n })) as string);\n\n if (p.isCancel(domain)) process.exit(0);\n\n const accountDefault = domain ? deriveAccountFromExtends(domain, extendsAccount) : \"\";\n const account =\n input.account ??\n ((await p.text({\n message: \"What NEAR account will you publish from?\",\n placeholder: accountDefault || \"skip\",\n defaultValue: accountDefault,\n })) as string);\n\n if (p.isCancel(account)) process.exit(0);\n\n const directory = input.directory || domain || extendsGateway;\n\n const overrides =\n input.overrides ??\n ((await p.multiselect({\n message: \"What do you want to customize?\",\n options: OVERRIDE_OPTIONS,\n initialValues: [\"ui\", \"api\"] as OverrideSection[],\n required: false,\n })) as OverrideSection[]);\n\n if (p.isCancel(overrides)) process.exit(0);\n\n let plugins: string[] = [];\n if (overrides.includes(\"plugins\")) {\n const parentPlugins = input.parentPluginKeys ?? [];\n const pluginOptions =\n parentPlugins.length > 0 ? parentPlugins.map((key) => ({ value: key, label: key })) : [];\n\n plugins =\n input.plugins ??\n (pluginOptions.length > 0\n ? ((await p.multiselect({\n message: \"Select plugins to include:\",\n options: pluginOptions,\n required: false,\n })) as string[])\n : []);\n\n if (p.isCancel(plugins)) process.exit(0);\n }\n\n const go = await p.confirm({\n message: \"GO!\",\n initialValue: true,\n });\n\n if (p.isCancel(go) || !go) process.exit(0);\n\n return {\n extendsAccount,\n extendsGateway,\n directory,\n account: account || undefined,\n domain: domain || undefined,\n plugins,\n overrides,\n };\n}\n"],"mappings":";;;;AAIA,SAAS,gBAAgB,KAA0D;CAEjF,MAAM,SADa,IAAI,WAAW,SAAS,GAAG,MAAM,SAAS,OACpC,MAAM,0BAA0B;AACzD,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EAAE,SAAS,MAAM;EAAI,SAAS,MAAM;EAAI;;AAGjD,SAAS,yBAAyB,QAAgB,gBAAgC;CAChF,MAAM,eAAe,OAAO,MAAM,IAAI,CAAC;AACvC,KAAI,CAAC,aAAc,QAAO;AAI1B,QAAO,GAAG,aAAa,GAHR,eAAe,SAAS,IAAI,GACvC,eAAe,UAAU,eAAe,QAAQ,IAAI,GAAG,EAAE,GACzD;;AAIN,MAAM,mBAA8E;CAClF;EAAE,OAAO;EAAM,OAAO;EAAM,MAAM;EAAiC;CACnE;EAAE,OAAO;EAAO,OAAO;EAAO,MAAM;EAAkC;CACtE;EAAE,OAAO;EAAQ,OAAO;EAAQ,MAAM;EAAmC;CACzE;EAAE,OAAO;EAAW,OAAO;EAAW,MAAM;EAA+C;CAC5F;AAED,eAAsB,kBAAkB,OAgBrC;AACD,GAAE,MAAM,wBAAwB;CAEhC,MAAM,eACJ,MAAM,WACJ,MAAM,EAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAI,EAAE,SAAS,aAAa,CAAE,SAAQ,KAAK,EAAE;CAE7C,IAAI,iBAAiB;CACrB,IAAI,iBAAiB;AAErB,KAAI,cAAc;EAChB,MAAM,SAAS,gBAAgB,aAAa;AAC5C,MAAI,QAAQ;AACV,oBAAiB,OAAO;AACxB,oBAAiB,OAAO;;;CAI5B,MAAM,SACJ,MAAM,UACJ,MAAM,EAAE,KAAK;EACb,SAAS;EACT,aAAa;EACd,CAAC;AAEJ,KAAI,EAAE,SAAS,OAAO,CAAE,SAAQ,KAAK,EAAE;CAEvC,MAAM,iBAAiB,SAAS,yBAAyB,QAAQ,eAAe,GAAG;CACnF,MAAM,UACJ,MAAM,WACJ,MAAM,EAAE,KAAK;EACb,SAAS;EACT,aAAa,kBAAkB;EAC/B,cAAc;EACf,CAAC;AAEJ,KAAI,EAAE,SAAS,QAAQ,CAAE,SAAQ,KAAK,EAAE;CAExC,MAAM,YAAY,MAAM,aAAa,UAAU;CAE/C,MAAM,YACJ,MAAM,aACJ,MAAM,EAAE,YAAY;EACpB,SAAS;EACT,SAAS;EACT,eAAe,CAAC,MAAM,MAAM;EAC5B,UAAU;EACX,CAAC;AAEJ,KAAI,EAAE,SAAS,UAAU,CAAE,SAAQ,KAAK,EAAE;CAE1C,IAAI,UAAoB,EAAE;AAC1B,KAAI,UAAU,SAAS,UAAU,EAAE;EACjC,MAAM,gBAAgB,MAAM,oBAAoB,EAAE;EAClD,MAAM,gBACJ,cAAc,SAAS,IAAI,cAAc,KAAK,SAAS;GAAE,OAAO;GAAK,OAAO;GAAK,EAAE,GAAG,EAAE;AAE1F,YACE,MAAM,YACL,cAAc,SAAS,IAClB,MAAM,EAAE,YAAY;GACpB,SAAS;GACT,SAAS;GACT,UAAU;GACX,CAAC,GACF,EAAE;AAER,MAAI,EAAE,SAAS,QAAQ,CAAE,SAAQ,KAAK,EAAE;;CAG1C,MAAM,KAAK,MAAM,EAAE,QAAQ;EACzB,SAAS;EACT,cAAc;EACf,CAAC;AAEF,KAAI,EAAE,SAAS,GAAG,IAAI,CAAC,GAAI,SAAQ,KAAK,EAAE;AAE1C,QAAO;EACL;EACA;EACA;EACA,SAAS,WAAW;EACpB,QAAQ,UAAU;EAClB;EACA;EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.cjs","names":["readInstalledFrameworkVersion","fetchBosConfigFromFastKv","readSnapshot"],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const data = (await response.json()) as { version: string };\n return data.version;\n } catch {\n return null;\n }\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return {\n status: \"error\",\n error: \"No bos.config.json found in current directory\",\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n const packages = [];\n for (const name of FRAMEWORK_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n for (const name of CATALOG_TOOL_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n if (!installed) continue;\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":";;;;;;;;AAOA,MAAM,qBAAqB,CAAC,kBAAkB,eAAe;AAE7D,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,eAAe,sBAAsB,aAA6C;AAChF,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,8BAA8B,YAAY,UAAU;GAC/E,SAAS,EAAE,QAAQ,oBAAoB;GACvC,QAAQ,YAAY,QAAQ,IAAO;GACpC,CAAC;AACF,MAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UADc,MAAM,SAAS,MAAM,EACvB;SACN;AACN,SAAO;;;AAIX,SAAS,qBAAqB,YAAoB,aAAyC;AACzF,QAAOA,wDAA8B,YAAY,YAAY;;AAG/D,SAAS,aAAa,YAA0D;AAC9E,iDAAoB,YAAY,OAAO,CAAC,CAAE,QAAO;AACjD,iDAAoB,YAAY,eAAe,CAAC,CAAE,QAAO;AACzD,QAAO;;AAGT,eAAe,qBAAqB,YAA8D;AAChG,KAAI,CAAC,YAAY,WAAW,SAAS,CAAE,QAAO;AAC9C,KAAI;AAEF,SADe,MAAMC,wCAAyB,WAAW,KACvC;SACZ;AACN,SAAO;;;AAIX,eAAsB,UAAU,YAA2C;CACzE,MAAM,iCAAkB,YAAY,kBAAkB;AACtD,KAAI,yBAAY,WAAW,CACzB,QAAO;EACL,QAAQ;EACR,OAAO;EACP,UAAU,EAAE;EACZ,SAAS;EACV;CAGH,MAAM,SAAS,KAAK,gCAAmB,YAAY,QAAQ,CAAC;CAE5D,MAAM,WAAW,EAAE;AACnB,MAAK,MAAM,QAAQ,oBAAoB;EACrC,MAAM,YAAY,qBAAqB,YAAY,KAAK;EACxD,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;AAGjE,MAAK,MAAM,QAAQ,uBAAuB;EACxC,MAAM,YAAY,qBAAqB,YAAY,KAAK;AACxD,MAAI,CAAC,UAAW;EAChB,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;CAGjE,MAAM,WAAW,MAAMC,8BAAa,WAAW;CAE/C,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAAkB,MAAM,qBAAqB,WAAW;AAE9D,QAAO;EACL,QAAQ;EACR,SAAS;EACT,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf;EACA,UAAU,UAAU;EACpB,SAAS,aAAa,WAAW;EACjC;EACD"}
1
+ {"version":3,"file":"status.cjs","names":["readInstalledFrameworkVersion","fetchBosConfigFromFastKv","readSnapshot"],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const data = (await response.json()) as { version: string };\n return data.version;\n } catch {\n return null;\n }\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return {\n status: \"error\",\n error: \"No bos.config.json found in current directory\",\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n const packages = [];\n for (const name of FRAMEWORK_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n for (const name of CATALOG_TOOL_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n if (!installed) continue;\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":";;;;;;;;AAOA,MAAM,qBAAqB,CAAC,kBAAkB,eAAe;AAE7D,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,eAAe,sBAAsB,aAA6C;AAChF,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,8BAA8B,YAAY,UAAU;GAC/E,SAAS,EAAE,QAAQ,oBAAoB;GACvC,QAAQ,YAAY,QAAQ,IAAO;GACpC,CAAC;AACF,MAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UAAO,MADa,SAAS,MAAM,EACvB;SACN;AACN,SAAO;;;AAIX,SAAS,qBAAqB,YAAoB,aAAyC;AACzF,QAAOA,wDAA8B,YAAY,YAAY;;AAG/D,SAAS,aAAa,YAA0D;AAC9E,iDAAoB,YAAY,OAAO,CAAC,CAAE,QAAO;AACjD,iDAAoB,YAAY,eAAe,CAAC,CAAE,QAAO;AACzD,QAAO;;AAGT,eAAe,qBAAqB,YAA8D;AAChG,KAAI,CAAC,YAAY,WAAW,SAAS,CAAE,QAAO;AAC9C,KAAI;AAEF,SAAO,MADcC,wCAAyB,WAAW,KACvC;SACZ;AACN,SAAO;;;AAIX,eAAsB,UAAU,YAA2C;CACzE,MAAM,iCAAkB,YAAY,kBAAkB;AACtD,KAAI,yBAAY,WAAW,CACzB,QAAO;EACL,QAAQ;EACR,OAAO;EACP,UAAU,EAAE;EACZ,SAAS;EACV;CAGH,MAAM,SAAS,KAAK,gCAAmB,YAAY,QAAQ,CAAC;CAE5D,MAAM,WAAW,EAAE;AACnB,MAAK,MAAM,QAAQ,oBAAoB;EACrC,MAAM,YAAY,qBAAqB,YAAY,KAAK;EACxD,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;AAGjE,MAAK,MAAM,QAAQ,uBAAuB;EACxC,MAAM,YAAY,qBAAqB,YAAY,KAAK;AACxD,MAAI,CAAC,UAAW;EAChB,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;CAGjE,MAAM,WAAW,MAAMC,8BAAa,WAAW;CAE/C,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAAkB,MAAM,qBAAqB,WAAW;AAE9D,QAAO;EACL,QAAQ;EACR,SAAS;EACT,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf;EACA,UAAU,UAAU;EACpB,SAAS,aAAa,WAAW;EACjC;EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.mjs","names":[],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const data = (await response.json()) as { version: string };\n return data.version;\n } catch {\n return null;\n }\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return {\n status: \"error\",\n error: \"No bos.config.json found in current directory\",\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n const packages = [];\n for (const name of FRAMEWORK_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n for (const name of CATALOG_TOOL_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n if (!installed) continue;\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":";;;;;;;AAOA,MAAM,qBAAqB,CAAC,kBAAkB,eAAe;AAE7D,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,eAAe,sBAAsB,aAA6C;AAChF,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,8BAA8B,YAAY,UAAU;GAC/E,SAAS,EAAE,QAAQ,oBAAoB;GACvC,QAAQ,YAAY,QAAQ,IAAO;GACpC,CAAC;AACF,MAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UADc,MAAM,SAAS,MAAM,EACvB;SACN;AACN,SAAO;;;AAIX,SAAS,qBAAqB,YAAoB,aAAyC;AACzF,QAAO,8BAA8B,YAAY,YAAY;;AAG/D,SAAS,aAAa,YAA0D;AAC9E,KAAI,WAAW,KAAK,YAAY,OAAO,CAAC,CAAE,QAAO;AACjD,KAAI,WAAW,KAAK,YAAY,eAAe,CAAC,CAAE,QAAO;AACzD,QAAO;;AAGT,eAAe,qBAAqB,YAA8D;AAChG,KAAI,CAAC,YAAY,WAAW,SAAS,CAAE,QAAO;AAC9C,KAAI;AAEF,SADe,MAAM,yBAAyB,WAAW,KACvC;SACZ;AACN,SAAO;;;AAIX,eAAsB,UAAU,YAA2C;CACzE,MAAM,aAAa,KAAK,YAAY,kBAAkB;AACtD,KAAI,CAAC,WAAW,WAAW,CACzB,QAAO;EACL,QAAQ;EACR,OAAO;EACP,UAAU,EAAE;EACZ,SAAS;EACV;CAGH,MAAM,SAAS,KAAK,MAAM,aAAa,YAAY,QAAQ,CAAC;CAE5D,MAAM,WAAW,EAAE;AACnB,MAAK,MAAM,QAAQ,oBAAoB;EACrC,MAAM,YAAY,qBAAqB,YAAY,KAAK;EACxD,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;AAGjE,MAAK,MAAM,QAAQ,uBAAuB;EACxC,MAAM,YAAY,qBAAqB,YAAY,KAAK;AACxD,MAAI,CAAC,UAAW;EAChB,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;CAGjE,MAAM,WAAW,MAAM,aAAa,WAAW;CAE/C,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAAkB,MAAM,qBAAqB,WAAW;AAE9D,QAAO;EACL,QAAQ;EACR,SAAS;EACT,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf;EACA,UAAU,UAAU;EACpB,SAAS,aAAa,WAAW;EACjC;EACD"}
1
+ {"version":3,"file":"status.mjs","names":[],"sources":["../../src/cli/status.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { StatusResult } from \"../contract\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { readSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const data = (await response.json()) as { version: string };\n return data.version;\n } catch {\n return null;\n }\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction checkEnvFile(projectDir: string): \"found\" | \"missing\" | \"example-only\" {\n if (existsSync(join(projectDir, \".env\"))) return \"found\";\n if (existsSync(join(projectDir, \".env.example\"))) return \"example-only\";\n return \"missing\";\n}\n\nasync function checkParentReachable(extendsRef: string | undefined): Promise<boolean | undefined> {\n if (!extendsRef?.startsWith(\"bos://\")) return undefined;\n try {\n const config = await fetchBosConfigFromFastKv(extendsRef);\n return config !== null;\n } catch {\n return false;\n }\n}\n\nexport async function getStatus(projectDir: string): Promise<StatusResult> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return {\n status: \"error\",\n error: \"No bos.config.json found in current directory\",\n packages: [],\n envFile: \"missing\",\n };\n }\n\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n const packages = [];\n for (const name of FRAMEWORK_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n for (const name of CATALOG_TOOL_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n if (!installed) continue;\n const latest = await fetchLatestNpmVersion(name);\n packages.push({ name, installed, latest: latest ?? undefined });\n }\n\n const snapshot = await readSnapshot(projectDir);\n\n const extendsRef = config.extends as string | undefined;\n const parentReachable = await checkParentReachable(extendsRef);\n\n return {\n status: \"ok\",\n extends: extendsRef,\n account: config.account as string | undefined,\n domain: config.domain as string | undefined,\n packages,\n lastSync: snapshot?.timestamp,\n envFile: checkEnvFile(projectDir),\n parentReachable,\n };\n}\n"],"mappings":";;;;;;;AAOA,MAAM,qBAAqB,CAAC,kBAAkB,eAAe;AAE7D,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,eAAe,sBAAsB,aAA6C;AAChF,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,8BAA8B,YAAY,UAAU;GAC/E,SAAS,EAAE,QAAQ,oBAAoB;GACvC,QAAQ,YAAY,QAAQ,IAAO;GACpC,CAAC;AACF,MAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UAAO,MADa,SAAS,MAAM,EACvB;SACN;AACN,SAAO;;;AAIX,SAAS,qBAAqB,YAAoB,aAAyC;AACzF,QAAO,8BAA8B,YAAY,YAAY;;AAG/D,SAAS,aAAa,YAA0D;AAC9E,KAAI,WAAW,KAAK,YAAY,OAAO,CAAC,CAAE,QAAO;AACjD,KAAI,WAAW,KAAK,YAAY,eAAe,CAAC,CAAE,QAAO;AACzD,QAAO;;AAGT,eAAe,qBAAqB,YAA8D;AAChG,KAAI,CAAC,YAAY,WAAW,SAAS,CAAE,QAAO;AAC9C,KAAI;AAEF,SAAO,MADc,yBAAyB,WAAW,KACvC;SACZ;AACN,SAAO;;;AAIX,eAAsB,UAAU,YAA2C;CACzE,MAAM,aAAa,KAAK,YAAY,kBAAkB;AACtD,KAAI,CAAC,WAAW,WAAW,CACzB,QAAO;EACL,QAAQ;EACR,OAAO;EACP,UAAU,EAAE;EACZ,SAAS;EACV;CAGH,MAAM,SAAS,KAAK,MAAM,aAAa,YAAY,QAAQ,CAAC;CAE5D,MAAM,WAAW,EAAE;AACnB,MAAK,MAAM,QAAQ,oBAAoB;EACrC,MAAM,YAAY,qBAAqB,YAAY,KAAK;EACxD,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;AAGjE,MAAK,MAAM,QAAQ,uBAAuB;EACxC,MAAM,YAAY,qBAAqB,YAAY,KAAK;AACxD,MAAI,CAAC,UAAW;EAChB,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAChD,WAAS,KAAK;GAAE;GAAM;GAAW,QAAQ,UAAU;GAAW,CAAC;;CAGjE,MAAM,WAAW,MAAM,aAAa,WAAW;CAE/C,MAAM,aAAa,OAAO;CAC1B,MAAM,kBAAkB,MAAM,qBAAqB,WAAW;AAE9D,QAAO;EACL,QAAQ;EACR,SAAS;EACT,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf;EACA,UAAU,UAAU;EACpB,SAAS,aAAa,WAAW;EACjC;EACD"}
package/dist/cli/sync.cjs CHANGED
@@ -2,30 +2,35 @@ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
2
2
  const require_merge = require('../merge.cjs');
3
3
  const require_config = require('../config.cjs');
4
4
  const require_infra = require('./infra.cjs');
5
- const require_path_match = require('../utils/path-match.cjs');
6
5
  const require_snapshot = require('./snapshot.cjs');
7
6
  const require_cli_init = require('./init.cjs');
8
7
  let node_fs = require("node:fs");
9
8
  let node_path = require("node:path");
10
9
  let node_crypto = require("node:crypto");
11
- let glob = require("glob");
12
10
 
13
11
  //#region src/cli/sync.ts
14
12
  const FRAMEWORK_OWNED_SYNC_FILES = new Set([
15
13
  ".env.example",
16
14
  ".gitignore",
15
+ "AGENTS.md",
17
16
  "biome.json",
18
17
  "bos.config.json",
18
+ "bunfig.toml",
19
+ "CONTRIBUTING.md",
19
20
  "package.json",
21
+ ".changeset/config.json",
22
+ ".changeset/README.md",
20
23
  "docker-compose.yml",
21
24
  ".github/renovate.json",
22
25
  ".github/workflows/ci.yml",
23
26
  ".github/workflows/release-sync.yml",
27
+ ".opencode/skills/everything-dev/SKILL.md",
24
28
  "ui/package.json",
25
29
  "ui/postcss.config.mjs",
26
30
  "ui/rsbuild.config.ts",
27
31
  "ui/tsconfig.json",
28
32
  "ui/src/app.ts",
33
+ "ui/src/globals.d.ts",
29
34
  "ui/src/hydrate.tsx",
30
35
  "ui/src/lib/api.ts",
31
36
  "ui/src/lib/auth.ts",
@@ -39,19 +44,6 @@ const FRAMEWORK_OWNED_SYNC_FILES = new Set([
39
44
  "api/tsconfig.json",
40
45
  "api/src/lib/auth.ts"
41
46
  ]);
42
- function isFrameworkOwnedSyncFile(filePath) {
43
- return FRAMEWORK_OWNED_SYNC_FILES.has(filePath);
44
- }
45
- function readExcludeFile(filePath) {
46
- if (!(0, node_fs.existsSync)(filePath)) return [];
47
- return (0, node_fs.readFileSync)(filePath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
48
- }
49
- async function readTemplatesyncExclude(sourceDir) {
50
- return readExcludeFile((0, node_path.join)(sourceDir, ".templatesync-exclude"));
51
- }
52
- function readLocalSyncExcludes(projectDir) {
53
- return readExcludeFile((0, node_path.join)(projectDir, ".bos", "sync-local-exclude"));
54
- }
55
47
  function computeLocalHash(projectDir, filePath) {
56
48
  const fullPath = (0, node_path.join)(projectDir, filePath);
57
49
  if (!(0, node_fs.existsSync)(fullPath)) return null;
@@ -137,7 +129,15 @@ function mergePackageJson(filePath, local, template) {
137
129
  return merged;
138
130
  }
139
131
  function toDestPath(filePath) {
140
- return filePath.startsWith(".github/templates/") ? filePath.replace(/^\.github\/templates\//, ".github/") : filePath;
132
+ return require_cli_init.sourcePathToDestinationPath(filePath);
133
+ }
134
+ function toSourcePath(sourceDir, destPath) {
135
+ if ((0, node_fs.existsSync)((0, node_path.join)(sourceDir, destPath))) return destPath;
136
+ if (destPath.startsWith(".github/")) {
137
+ const templatePath = destPath.replace(/^\.github\//, ".github/templates/");
138
+ if ((0, node_fs.existsSync)((0, node_path.join)(sourceDir, templatePath))) return templatePath;
139
+ }
140
+ return null;
141
141
  }
142
142
  function writeSyncedFile(sourceDir, projectDir, filePath) {
143
143
  const src = (0, node_path.join)(sourceDir, filePath);
@@ -191,60 +191,25 @@ async function syncTemplate(projectDir, options) {
191
191
  extendsGateway
192
192
  });
193
193
  try {
194
- const patterns = await require_cli_init.readTemplatekeep(sourceDir);
195
- if (patterns.length === 0) return {
196
- status: "error",
197
- updated: [],
198
- skipped: [],
199
- added: [],
200
- error: "No .templatekeep found in template source"
201
- };
202
- const parentExcludes = await readTemplatesyncExclude(sourceDir);
203
- const localExcludes = readLocalSyncExcludes(projectDir);
204
- const excludePatterns = [...parentExcludes, ...localExcludes];
205
- const allTemplateFiles = /* @__PURE__ */ new Set();
206
- for (const pattern of patterns) {
207
- const matches = await (0, glob.glob)(pattern, {
208
- cwd: sourceDir,
209
- nodir: true,
210
- dot: true,
211
- absolute: false
212
- });
213
- for (const match of matches) allTemplateFiles.add(match);
214
- }
215
194
  const childPlugins = localConfig.plugins && typeof localConfig.plugins === "object" ? Object.keys(localConfig.plugins) : [];
216
- const pluginRoutes = {};
217
- const parentRuntime = await require_config.loadConfig({ cwd: sourceDir });
218
- for (const [key, plugin] of Object.entries(parentRuntime?.runtime.plugins ?? {})) if (plugin.routes && plugin.routes.length > 0) pluginRoutes[key] = plugin.routes;
219
- const excludedRoutePatterns = [];
220
- for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) if (!childPlugins.includes(pluginKey)) excludedRoutePatterns.push(...routePatterns);
195
+ const withUi = (0, node_fs.existsSync)((0, node_path.join)(projectDir, "ui", "package.json"));
196
+ const withApi = (0, node_fs.existsSync)((0, node_path.join)(projectDir, "api", "package.json"));
197
+ const withHost = (0, node_fs.existsSync)((0, node_path.join)(projectDir, "host", "package.json"));
221
198
  const filteredFiles = /* @__PURE__ */ new Set();
222
- for (const filePath of allTemplateFiles) {
223
- const pluginMatch = filePath.match(/^plugins\/([^/]+)/);
224
- if (pluginMatch && !childPlugins.includes(pluginMatch[1])) continue;
225
- if (require_path_match.isPathExcluded(filePath, excludedRoutePatterns)) continue;
226
- filteredFiles.add(filePath);
227
- }
228
- for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) {
229
- if (!childPlugins.includes(pluginKey)) continue;
230
- for (const rp of routePatterns) {
231
- const matches = await (0, glob.glob)(rp, {
232
- cwd: sourceDir,
233
- nodir: true,
234
- dot: true,
235
- absolute: false
236
- });
237
- for (const match of matches) if (!require_path_match.isPathExcluded(match, excludedRoutePatterns)) filteredFiles.add(match);
238
- }
199
+ const destToSource = /* @__PURE__ */ new Map();
200
+ for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {
201
+ if (destPath.startsWith("ui/") && !withUi) continue;
202
+ if (destPath.startsWith("api/") && !withApi) continue;
203
+ if (destPath.startsWith("host/") && !withHost) continue;
204
+ const sourcePath = toSourcePath(sourceDir, destPath);
205
+ if (!sourcePath) continue;
206
+ filteredFiles.add(sourcePath);
207
+ destToSource.set(destPath, sourcePath);
239
208
  }
240
- const snapshot = await require_snapshot.readSnapshot(projectDir);
241
209
  const updated = [];
242
210
  const skipped = [];
243
211
  const added = [];
244
- for (const filePath of filteredFiles) {
245
- const destPath = toDestPath(filePath);
246
- const frameworkOwned = isFrameworkOwnedSyncFile(destPath);
247
- if (require_path_match.isPathExcluded(destPath, excludePatterns) && !frameworkOwned) continue;
212
+ for (const [destPath, filePath] of destToSource.entries()) {
248
213
  const localHash = computeLocalHash(projectDir, destPath);
249
214
  const sourceContent = (0, node_fs.readFileSync)((0, node_path.join)(sourceDir, filePath));
250
215
  const sourceHash = (0, node_crypto.createHash)("sha256").update(sourceContent).digest("hex").substring(0, 16);
@@ -252,19 +217,7 @@ async function syncTemplate(projectDir, options) {
252
217
  added.push(destPath);
253
218
  continue;
254
219
  }
255
- if (localHash === sourceHash) continue;
256
- if (frameworkOwned) {
257
- updated.push(destPath);
258
- continue;
259
- }
260
- const snapshotHash = snapshot?.files[destPath];
261
- if (snapshotHash === void 0) {
262
- updated.push(destPath);
263
- continue;
264
- }
265
- if (localHash === snapshotHash) updated.push(destPath);
266
- else if (options.force) updated.push(destPath);
267
- else skipped.push(destPath);
220
+ if (localHash !== sourceHash) updated.push(destPath);
268
221
  }
269
222
  if (options.dryRun) return {
270
223
  status: "dry-run",
@@ -272,37 +225,34 @@ async function syncTemplate(projectDir, options) {
272
225
  skipped,
273
226
  added
274
227
  };
275
- const filesToWrite = [...updated, ...added].filter((f) => isFrameworkOwnedSyncFile(f) || !require_path_match.isPathExcluded(f, excludePatterns));
276
- const destToSource = /* @__PURE__ */ new Map();
277
- for (const filePath of filteredFiles) destToSource.set(toDestPath(filePath), filePath);
228
+ const filesToWrite = [...updated, ...added];
278
229
  if (filesToWrite.length > 0) {
279
230
  backupFiles(projectDir, filesToWrite);
280
231
  for (const destPath of filesToWrite) writeSyncedFile(sourceDir, projectDir, destToSource.get(destPath) ?? destPath);
281
232
  }
282
233
  const newSnapshotFiles = {};
283
234
  for (const filePath of filteredFiles) {
284
- const src = (0, node_path.join)(sourceDir, filePath);
285
- if (!(0, node_fs.lstatSync)(src).isFile()) continue;
286
- const content = (0, node_fs.readFileSync)(src);
235
+ const content = (0, node_fs.readFileSync)((0, node_path.join)(sourceDir, filePath));
287
236
  newSnapshotFiles[toDestPath(filePath)] = (0, node_crypto.createHash)("sha256").update(content).digest("hex").substring(0, 16);
288
237
  }
289
238
  await require_snapshot.writeSnapshot(projectDir, {
290
239
  parentRef: `bos://${extendsAccount}/${extendsGateway}`,
291
240
  files: newSnapshotFiles
292
241
  });
242
+ const account = localConfig.account || extendsAccount;
243
+ const domain = localConfig.domain || extendsGateway;
244
+ const overrides = [];
245
+ if (withUi) overrides.push("ui");
246
+ if (withApi) overrides.push("api");
247
+ if (withHost) overrides.push("host");
248
+ if (childPlugins.length > 0) overrides.push("plugins");
293
249
  await require_cli_init.personalizeConfig(projectDir, {
294
250
  extendsAccount,
295
251
  extendsGateway,
296
- account: localConfig.account || extendsAccount,
297
- domain: localConfig.domain || extendsGateway,
252
+ account,
253
+ domain,
254
+ overrides,
298
255
  plugins: childPlugins,
299
- pluginRoutes,
300
- overrides: [
301
- "ui",
302
- "api",
303
- "host",
304
- "plugins"
305
- ],
306
256
  workspaceOpts: { sourceDir },
307
257
  mode: "sync"
308
258
  });
@@ -1 +1 @@
1
- {"version":3,"file":"sync.cjs","names":["mergeBosConfigWithTemplate","isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","readTemplatekeep","loadConfig","isPathExcluded","readSnapshot","writeSnapshot","personalizeConfig","runBunInstall","runTypesGen"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n copyFileSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { glob } from \"glob\";\nimport { loadConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { isPathExcluded } from \"../utils/path-match\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n personalizeConfig,\n readTemplatekeep,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n} from \"./init\";\nimport { readSnapshot, writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"package.json\",\n \"docker-compose.yml\",\n \".github/renovate.json\",\n \".github/workflows/ci.yml\",\n \".github/workflows/release-sync.yml\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/rsbuild.config.ts\",\n \"ui/tsconfig.json\",\n \"ui/src/app.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/lib/api.ts\",\n \"ui/src/lib/auth.ts\",\n \"ui/src/router.server.tsx\",\n \"ui/src/router.tsx\",\n \"ui/src/routes/__root.tsx\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.contract.json\",\n \"api/tsconfig.json\",\n \"api/src/lib/auth.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n return FRAMEWORK_OWNED_SYNC_FILES.has(filePath);\n}\n\nfunction readExcludeFile(filePath: string): string[] {\n if (!existsSync(filePath)) return [];\n const content = readFileSync(filePath, \"utf-8\");\n return content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nexport async function readTemplatesyncExclude(sourceDir: string): Promise<string[]> {\n return readExcludeFile(join(sourceDir, \".templatesync-exclude\"));\n}\n\nexport function readLocalSyncExcludes(projectDir: string): string[] {\n return readExcludeFile(join(projectDir, \".bos\", \"sync-local-exclude\"));\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n const fullPath = join(projectDir, filePath);\n if (!existsSync(fullPath)) return null;\n try {\n const content = readFileSync(fullPath);\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n } catch {\n return null;\n }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n if (filesToBackup.length === 0) return null;\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n for (const filePath of filesToBackup) {\n const src = join(projectDir, filePath);\n const dest = join(backupDir, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n copyFileSync(src, dest);\n }\n\n return backupDir;\n}\n\nfunction mergeStringMaps(\n local: Record<string, string> | undefined,\n template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!local && !template) return undefined;\n\n const merged: Record<string, string> = { ...(local ?? {}) };\n for (const [name, value] of Object.entries(template ?? {})) {\n merged[name] = value;\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n const localPackages = Array.isArray(local) ? local : [];\n const templatePackages = Array.isArray(template) ? template : [];\n if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n const ordered = new Set<string>();\n for (const entry of templatePackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n for (const entry of localPackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n\n return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n filePath: string,\n local: PackageJson,\n template: PackageJson,\n): PackageJson {\n const merged: PackageJson = { ...local, ...template };\n\n if (filePath === \"package.json\") {\n for (const key of [\"name\", \"private\", \"version\"] as const) {\n if (key in local) {\n merged[key] = local[key];\n }\n }\n } else if (\"version\" in local) {\n merged.version = local.version;\n }\n\n for (const depField of [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"overrides\",\n ] as const) {\n const localDeps = local[depField] as Record<string, string> | undefined;\n const templateDeps = template[depField] as Record<string, string> | undefined;\n\n const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n if (mergedDeps) {\n merged[depField] = mergedDeps;\n } else {\n delete merged[depField];\n }\n }\n\n if (\n (local.scripts && typeof local.scripts === \"object\") ||\n (template.scripts && typeof template.scripts === \"object\")\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n template.scripts as Record<string, string> | undefined,\n );\n if (mergedScripts) {\n merged.scripts = mergedScripts;\n } else {\n delete merged.scripts;\n }\n }\n\n if (\n (local.workspaces && typeof local.workspaces === \"object\") ||\n (template.workspaces && typeof template.workspaces === \"object\")\n ) {\n const localWorkspaces = (local.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n const templateWorkspaces = (template.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n ...localWorkspaces,\n ...templateWorkspaces,\n };\n\n const mergedPackages = mergeWorkspacePackages(\n localWorkspaces.packages,\n templateWorkspaces.packages,\n );\n if (mergedPackages) {\n mergedWorkspaces.packages = mergedPackages;\n } else {\n delete mergedWorkspaces.packages;\n }\n\n const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n if (mergedCatalog) {\n mergedWorkspaces.catalog = mergedCatalog;\n } else {\n delete mergedWorkspaces.catalog;\n }\n\n if (Object.keys(mergedWorkspaces).length > 0) {\n merged.workspaces = mergedWorkspaces;\n } else {\n delete merged.workspaces;\n }\n }\n\n return merged;\n}\n\nfunction toDestPath(filePath: string): string {\n return filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n}\n\nfunction writeSyncedFile(sourceDir: string, projectDir: string, filePath: string): void {\n const src = join(sourceDir, filePath);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(projectDir, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n\n if (filePath.endsWith(\"bos.config.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergeBosConfigWithTemplate(local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n if (filePath.endsWith(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergePackageJson(destPath, local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n writeFileSync(dest, readFileSync(src));\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the raw bos.config.json (not the resolved config) because it needs\n // the user's explicit local settings: their extends ref, selected plugins, etc.\n // The resolved config is the merged result and would include inherited parent\n // values that the user didn't explicitly choose, which would break sync filtering.\n const localConfig = JSON.parse(\n readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"),\n ) as Record<string, unknown>;\n\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n if (!extendsRef?.startsWith(\"bos://\")) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: \"No extends field found in bos.config.json — cannot determine parent\",\n };\n }\n\n const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!extendsMatch) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n });\n\n try {\n const patterns = await readTemplatekeep(sourceDir);\n if (patterns.length === 0) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: \"No .templatekeep found in template source\",\n };\n }\n\n const parentExcludes = await readTemplatesyncExclude(sourceDir);\n const localExcludes = readLocalSyncExcludes(projectDir);\n const excludePatterns = [...parentExcludes, ...localExcludes];\n\n const allTemplateFiles = new Set<string>();\n for (const pattern of patterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n allTemplateFiles.add(match);\n }\n }\n\n const childPlugins =\n localConfig.plugins && typeof localConfig.plugins === \"object\"\n ? Object.keys(localConfig.plugins as Record<string, unknown>)\n : [];\n\n const pluginRoutes: Record<string, string[]> = {};\n const parentRuntime = await loadConfig({ cwd: sourceDir });\n for (const [key, plugin] of Object.entries(parentRuntime?.runtime.plugins ?? {})) {\n if (plugin.routes && plugin.routes.length > 0) {\n pluginRoutes[key] = plugin.routes;\n }\n }\n\n const excludedRoutePatterns: string[] = [];\n for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) {\n if (!childPlugins.includes(pluginKey)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n\n const filteredFiles = new Set<string>();\n for (const filePath of allTemplateFiles) {\n const pluginMatch = filePath.match(/^plugins\\/([^/]+)/);\n if (pluginMatch && !childPlugins.includes(pluginMatch[1])) continue;\n if (isPathExcluded(filePath, excludedRoutePatterns)) continue;\n filteredFiles.add(filePath);\n }\n\n for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) {\n if (!childPlugins.includes(pluginKey)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isPathExcluded(match, excludedRoutePatterns)) {\n filteredFiles.add(match);\n }\n }\n }\n }\n\n const snapshot = await readSnapshot(projectDir);\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n\n for (const filePath of filteredFiles) {\n const destPath = toDestPath(filePath);\n const frameworkOwned = isFrameworkOwnedSyncFile(destPath);\n if (isPathExcluded(destPath, excludePatterns) && !frameworkOwned) continue;\n\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceContent = readFileSync(join(sourceDir, filePath));\n const sourceHash = createHash(\"sha256\").update(sourceContent).digest(\"hex\").substring(0, 16);\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash === sourceHash) continue;\n\n if (frameworkOwned) {\n updated.push(destPath);\n continue;\n }\n\n const snapshotHash = snapshot?.files[destPath];\n\n if (snapshotHash === undefined) {\n updated.push(destPath);\n continue;\n }\n\n if (localHash === snapshotHash) {\n updated.push(destPath);\n } else {\n if (options.force) {\n updated.push(destPath);\n } else {\n skipped.push(destPath);\n }\n }\n }\n\n if (options.dryRun) {\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n };\n }\n\n const filesToWrite = [...updated, ...added].filter(\n (f) => isFrameworkOwnedSyncFile(f) || !isPathExcluded(f, excludePatterns),\n );\n\n const destToSource = new Map<string, string>();\n for (const filePath of filteredFiles) {\n destToSource.set(toDestPath(filePath), filePath);\n }\n\n if (filesToWrite.length > 0) {\n backupFiles(projectDir, filesToWrite);\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath);\n }\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const filePath of filteredFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n const content = readFileSync(src);\n newSnapshotFiles[toDestPath(filePath)] = createHash(\"sha256\")\n .update(content)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\n });\n\n const account = (localConfig.account as string) || extendsAccount;\n const domain = (localConfig.domain as string) || extendsGateway;\n\n await personalizeConfig(projectDir, {\n extendsAccount,\n extendsGateway,\n account,\n domain,\n plugins: childPlugins,\n pluginRoutes,\n overrides: [\"ui\", \"api\", \"host\", \"plugins\"],\n workspaceOpts: { sourceDir },\n mode: \"sync\",\n });\n\n const syncedConfig = await loadConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(projectDir, syncedConfig.runtime);\n }\n\n if (!options.noInstall) {\n await runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sync.cjs","names":["sourcePathToDestinationPath","mergeBosConfigWithTemplate","isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","writeSnapshot","personalizeConfig","loadConfig","runBunInstall","runTypesGen"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { loadConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n personalizeConfig,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n sourcePathToDestinationPath,\n} from \"./init\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"AGENTS.md\",\n \"biome.json\",\n \"bos.config.json\",\n \"bunfig.toml\",\n \"CONTRIBUTING.md\",\n \"package.json\",\n \".changeset/config.json\",\n \".changeset/README.md\",\n \"docker-compose.yml\",\n \".github/renovate.json\",\n \".github/workflows/ci.yml\",\n \".github/workflows/release-sync.yml\",\n \".opencode/skills/everything-dev/SKILL.md\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/rsbuild.config.ts\",\n \"ui/tsconfig.json\",\n \"ui/src/app.ts\",\n \"ui/src/globals.d.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/lib/api.ts\",\n \"ui/src/lib/auth.ts\",\n \"ui/src/router.server.tsx\",\n \"ui/src/router.tsx\",\n \"ui/src/routes/__root.tsx\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.contract.json\",\n \"api/tsconfig.json\",\n \"api/src/lib/auth.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n return FRAMEWORK_OWNED_SYNC_FILES.has(filePath);\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n const fullPath = join(projectDir, filePath);\n if (!existsSync(fullPath)) return null;\n try {\n const content = readFileSync(fullPath);\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n } catch {\n return null;\n }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n if (filesToBackup.length === 0) return null;\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n for (const filePath of filesToBackup) {\n const src = join(projectDir, filePath);\n const dest = join(backupDir, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n copyFileSync(src, dest);\n }\n\n return backupDir;\n}\n\nfunction mergeStringMaps(\n local: Record<string, string> | undefined,\n template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!local && !template) return undefined;\n\n const merged: Record<string, string> = { ...(local ?? {}) };\n for (const [name, value] of Object.entries(template ?? {})) {\n merged[name] = value;\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n const localPackages = Array.isArray(local) ? local : [];\n const templatePackages = Array.isArray(template) ? template : [];\n if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n const ordered = new Set<string>();\n for (const entry of templatePackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n for (const entry of localPackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n\n return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n filePath: string,\n local: PackageJson,\n template: PackageJson,\n): PackageJson {\n const merged: PackageJson = { ...local, ...template };\n\n if (filePath === \"package.json\") {\n for (const key of [\"name\", \"private\", \"version\"] as const) {\n if (key in local) {\n merged[key] = local[key];\n }\n }\n } else if (\"version\" in local) {\n merged.version = local.version;\n }\n\n for (const depField of [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"overrides\",\n ] as const) {\n const localDeps = local[depField] as Record<string, string> | undefined;\n const templateDeps = template[depField] as Record<string, string> | undefined;\n\n const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n if (mergedDeps) {\n merged[depField] = mergedDeps;\n } else {\n delete merged[depField];\n }\n }\n\n if (\n (local.scripts && typeof local.scripts === \"object\") ||\n (template.scripts && typeof template.scripts === \"object\")\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n template.scripts as Record<string, string> | undefined,\n );\n if (mergedScripts) {\n merged.scripts = mergedScripts;\n } else {\n delete merged.scripts;\n }\n }\n\n if (\n (local.workspaces && typeof local.workspaces === \"object\") ||\n (template.workspaces && typeof template.workspaces === \"object\")\n ) {\n const localWorkspaces = (local.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n const templateWorkspaces = (template.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n ...localWorkspaces,\n ...templateWorkspaces,\n };\n\n const mergedPackages = mergeWorkspacePackages(\n localWorkspaces.packages,\n templateWorkspaces.packages,\n );\n if (mergedPackages) {\n mergedWorkspaces.packages = mergedPackages;\n } else {\n delete mergedWorkspaces.packages;\n }\n\n const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n if (mergedCatalog) {\n mergedWorkspaces.catalog = mergedCatalog;\n } else {\n delete mergedWorkspaces.catalog;\n }\n\n if (Object.keys(mergedWorkspaces).length > 0) {\n merged.workspaces = mergedWorkspaces;\n } else {\n delete merged.workspaces;\n }\n }\n\n return merged;\n}\n\nfunction toDestPath(filePath: string): string {\n return sourcePathToDestinationPath(filePath);\n}\n\nfunction toSourcePath(sourceDir: string, destPath: string): string | null {\n const directPath = join(sourceDir, destPath);\n if (existsSync(directPath)) {\n return destPath;\n }\n\n if (destPath.startsWith(\".github/\")) {\n const templatePath = destPath.replace(/^\\.github\\//, \".github/templates/\");\n if (existsSync(join(sourceDir, templatePath))) {\n return templatePath;\n }\n }\n\n return null;\n}\n\nfunction writeSyncedFile(sourceDir: string, projectDir: string, filePath: string): void {\n const src = join(sourceDir, filePath);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(projectDir, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n\n if (filePath.endsWith(\"bos.config.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergeBosConfigWithTemplate(local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n if (filePath.endsWith(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergePackageJson(destPath, local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n writeFileSync(dest, readFileSync(src));\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the raw bos.config.json (not the resolved config) because it needs\n // the user's explicit local settings: their extends ref, selected plugins, etc.\n // The resolved config is the merged result and would include inherited parent\n // values that the user didn't explicitly choose, which would break sync filtering.\n const localConfig = JSON.parse(\n readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"),\n ) as Record<string, unknown>;\n\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n if (!extendsRef?.startsWith(\"bos://\")) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: \"No extends field found in bos.config.json — cannot determine parent\",\n };\n }\n\n const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!extendsMatch) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n });\n\n try {\n const childPlugins =\n localConfig.plugins && typeof localConfig.plugins === \"object\"\n ? Object.keys(localConfig.plugins as Record<string, unknown>)\n : [];\n const withUi = existsSync(join(projectDir, \"ui\", \"package.json\"));\n const withApi = existsSync(join(projectDir, \"api\", \"package.json\"));\n const withHost = existsSync(join(projectDir, \"host\", \"package.json\"));\n\n const filteredFiles = new Set<string>();\n const destToSource = new Map<string, string>();\n for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\n if (destPath.startsWith(\"ui/\") && !withUi) continue;\n if (destPath.startsWith(\"api/\") && !withApi) continue;\n if (destPath.startsWith(\"host/\") && !withHost) continue;\n const sourcePath = toSourcePath(sourceDir, destPath);\n if (!sourcePath) continue;\n filteredFiles.add(sourcePath);\n destToSource.set(destPath, sourcePath);\n }\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n\n for (const [destPath, filePath] of destToSource.entries()) {\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceContent = readFileSync(join(sourceDir, filePath));\n const sourceHash = createHash(\"sha256\").update(sourceContent).digest(\"hex\").substring(0, 16);\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash !== sourceHash) {\n updated.push(destPath);\n }\n }\n\n if (options.dryRun) {\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n };\n }\n\n const filesToWrite = [...updated, ...added];\n\n if (filesToWrite.length > 0) {\n backupFiles(projectDir, filesToWrite);\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath);\n }\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const filePath of filteredFiles) {\n const src = join(sourceDir, filePath);\n const content = readFileSync(src);\n newSnapshotFiles[toDestPath(filePath)] = createHash(\"sha256\")\n .update(content)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\n });\n\n const account = (localConfig.account as string) || extendsAccount;\n const domain = (localConfig.domain as string) || extendsGateway;\n const overrides: Array<\"ui\" | \"api\" | \"host\" | \"plugins\"> = [];\n if (withUi) overrides.push(\"ui\");\n if (withApi) overrides.push(\"api\");\n if (withHost) overrides.push(\"host\");\n if (childPlugins.length > 0) overrides.push(\"plugins\");\n\n await personalizeConfig(projectDir, {\n extendsAccount,\n extendsGateway,\n account,\n domain,\n overrides,\n plugins: childPlugins,\n workspaceOpts: { sourceDir },\n mode: \"sync\",\n });\n\n const syncedConfig = await loadConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(projectDir, syncedConfig.runtime);\n }\n\n if (!options.noInstall) {\n await runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}