@remixmate/cli 0.9.71 → 0.9.73

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 (181) hide show
  1. package/LICENSE +45 -21
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/dist/argv.js +1 -51
  5. package/dist/auth/auth-lock.js +1 -100
  6. package/dist/auth/auto-login.js +7 -75
  7. package/dist/auth/commands.js +40 -290
  8. package/dist/auth/credential-store.js +1 -143
  9. package/dist/auth/device-flow-runner.js +13 -110
  10. package/dist/auth/device-flow.js +1 -132
  11. package/dist/auth/ensure.js +1 -62
  12. package/dist/auth/environment.js +1 -69
  13. package/dist/auth/pending-store.js +1 -45
  14. package/dist/auth/resolve.js +1 -44
  15. package/dist/billing.js +3 -76
  16. package/dist/capabilities.js +1 -75
  17. package/dist/cli.js +39 -211
  18. package/dist/diagnostics.js +2 -70
  19. package/dist/doctor.js +9 -188
  20. package/dist/errors.js +1 -33
  21. package/dist/exec.js +4 -47
  22. package/dist/handlers/gen-digital-human.js +33 -264
  23. package/dist/handlers/gen-image.js +9 -113
  24. package/dist/handlers/gen-post.js +15 -188
  25. package/dist/handlers/gen-video.js +7 -185
  26. package/dist/handlers/gen-voice.js +19 -133
  27. package/dist/handlers/index.js +1 -20
  28. package/dist/handlers/shared.js +1 -66
  29. package/dist/handlers/template-init.js +1 -21
  30. package/dist/http.js +3 -155
  31. package/dist/index.js +1 -8
  32. package/dist/install.js +40 -448
  33. package/dist/manifest.json +53 -13
  34. package/dist/progress.js +2 -15
  35. package/dist/project/commands.js +34 -156
  36. package/dist/project/host.js +1 -151
  37. package/dist/project/resolve.js +1 -65
  38. package/dist/project/store.js +2 -97
  39. package/dist/project/take.js +1 -106
  40. package/dist/project/trace.js +5 -278
  41. package/dist/registry.js +3 -70
  42. package/dist/runner.js +7 -225
  43. package/dist/skill-schema.js +1 -194
  44. package/dist/template/args.js +1 -69
  45. package/dist/template/check.js +2 -30
  46. package/dist/template/commands.js +34 -163
  47. package/dist/template/constants.js +1 -46
  48. package/dist/template/init.js +5 -133
  49. package/dist/template/list.js +1 -46
  50. package/dist/template/preview.js +7 -318
  51. package/dist/template/proc.js +1 -43
  52. package/dist/template/project.js +6 -161
  53. package/dist/template/publish.js +5 -185
  54. package/dist/template/render-client.js +2 -79
  55. package/dist/template/upgrade.js +4 -123
  56. package/dist/text.js +1 -15
  57. package/package.json +2 -35
  58. package/skills/doc-parse/scripts/extract_via_render.py +32 -32
  59. package/skills/export-jianying/scripts/gen_jianying_draft.py +188 -188
  60. package/skills/gen-post/SKILL.md +23 -13
  61. package/skills/gen-post/skill.json +9 -10
  62. package/skills/gen-script/SKILL.md +23 -1
  63. package/skills/gen-script/scripts/gen_script.py +644 -551
  64. package/skills/gen-script/skill.json +12 -0
  65. package/skills/gen-script/version.json +1 -1
  66. package/skills/prepare-video-assets/scripts/prepare_video_assets.py +21 -21
  67. package/skills/render-video/scripts/_chrome_vendor.py +17 -17
  68. package/skills/render-video/scripts/_digital_human_segments.py +34 -34
  69. package/skills/render-video/scripts/_video_probe.py +33 -33
  70. package/skills/render-video/scripts/_vod_polling.py +13 -13
  71. package/skills/render-video/scripts/remote_renderer_client.py +42 -42
  72. package/skills/render-video/scripts/render_video.py +639 -639
  73. package/skills/render-video/scripts/required_props.py +37 -37
  74. package/skills/render-video/scripts/upload_video.py +35 -35
  75. package/skills/render-video/version.json +1 -1
  76. package/skills/template-registry/SKILL.md +16 -0
  77. package/skills/template-registry/scripts/countdown_spec.py +92 -92
  78. package/skills/template-registry/scripts/doc_extract.py +40 -40
  79. package/skills/template-registry/scripts/list_templates.py +303 -191
  80. package/skills/template-registry/scripts/log_diagnostics.py +1 -1
  81. package/skills/template-registry/scripts/match_template.py +87 -87
  82. package/skills/template-registry/scripts/payload_hydrator.py +89 -89
  83. package/skills/template-registry/scripts/registry_loader.py +159 -159
  84. package/skills/template-registry/scripts/render_job_client.py +75 -75
  85. package/skills/template-registry/scripts/showcase_loader.py +44 -44
  86. package/skills/template-registry/skill.json +4 -1
  87. package/skills/template-registry/version.json +1 -1
  88. package/skills/template-registry/video_dsl/runtime/__init__.py +8 -8
  89. package/skills/template-registry/video_dsl/runtime/dsl_validator.py +329 -329
  90. package/skills/template-registry/video_dsl/runtime/narration_budget.py +36 -36
  91. package/skills/template-registry/video_dsl/runtime/payload_contract.py +7 -7
  92. package/skills/template-registry/video_dsl/runtime/prompt_enhancer.py +98 -98
  93. package/skills/template-registry/video_dsl/runtime/timeline_compiler.py +127 -127
  94. package/skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json +14 -1
  95. package/skills/video-parser/scripts/analyze_video.py +173 -173
  96. package/skills/video-parser/scripts/deconstruct_video.py +91 -91
  97. package/skills/video-parser/scripts/parse_via_render.py +21 -21
  98. package/skills/web-screenshot/scripts/_media_screenshot/__init__.py +4 -4
  99. package/skills/web-screenshot/scripts/_media_screenshot/bootstrap.py +7 -7
  100. package/skills/web-screenshot/scripts/_media_screenshot/browser.py +4 -4
  101. package/skills/web-screenshot/scripts/_media_screenshot/cli_args.py +4 -4
  102. package/skills/web-screenshot/scripts/_media_screenshot/js_loader.py +2 -2
  103. package/skills/web-screenshot/scripts/_media_screenshot/overlay.py +1 -1
  104. package/skills/web-screenshot/scripts/_media_screenshot/reader.py +40 -40
  105. package/skills/web-screenshot/scripts/_media_screenshot/recording.py +11 -11
  106. package/skills/web-screenshot/scripts/_media_screenshot/scenes/__init__.py +8 -8
  107. package/skills/web-screenshot/scripts/_media_screenshot/scenes/arrow.py +2 -2
  108. package/skills/web-screenshot/scripts/_media_screenshot/scenes/caption.py +1 -1
  109. package/skills/web-screenshot/scripts/_media_screenshot/scenes/click.py +1 -1
  110. package/skills/web-screenshot/scripts/_media_screenshot/scenes/code_lines.py +5 -5
  111. package/skills/web-screenshot/scripts/_media_screenshot/scenes/focus.py +1 -1
  112. package/skills/web-screenshot/scripts/_media_screenshot/scenes/highlight.py +3 -3
  113. package/skills/web-screenshot/scripts/_media_screenshot/scenes/hover.py +1 -1
  114. package/skills/web-screenshot/scripts/_media_screenshot/scenes/redact.py +1 -1
  115. package/skills/web-screenshot/scripts/_media_screenshot/scenes/scroll.py +1 -1
  116. package/skills/web-screenshot/scripts/_media_screenshot/scenes/sequence.py +1 -1
  117. package/skills/web-screenshot/scripts/_media_screenshot/scenes/title_card.py +1 -1
  118. package/skills/web-screenshot/scripts/_media_screenshot/scenes/type.py +1 -1
  119. package/skills/web-screenshot/scripts/_media_screenshot/scenes/wait.py +1 -1
  120. package/skills/web-screenshot/scripts/_media_screenshot/scenes/zoom.py +2 -2
  121. package/skills/web-screenshot/scripts/_media_screenshot/screenshot.py +15 -15
  122. package/skills/web-screenshot/scripts/_media_screenshot/storyboard.py +2 -2
  123. package/skills/web-screenshot/scripts/_media_screenshot/template.py +11 -11
  124. package/skills/web-screenshot/scripts/_media_screenshot/trim.py +10 -10
  125. package/skills/web-screenshot/scripts/_media_screenshot/urlguard.py +22 -22
  126. package/skills/web-screenshot/scripts/_media_upload.py +33 -33
  127. package/skills/web-screenshot/scripts/read_page.py +15 -15
  128. package/skills/web-screenshot/scripts/record.py +26 -26
  129. package/skills/web-screenshot/scripts/screenshot.py +5 -5
  130. package/dist/argv.d.ts +0 -15
  131. package/dist/auth/auth-lock.d.ts +0 -26
  132. package/dist/auth/auto-login.d.ts +0 -20
  133. package/dist/auth/commands.d.ts +0 -8
  134. package/dist/auth/credential-store.d.ts +0 -60
  135. package/dist/auth/device-flow-runner.d.ts +0 -58
  136. package/dist/auth/device-flow.d.ts +0 -52
  137. package/dist/auth/ensure.d.ts +0 -55
  138. package/dist/auth/environment.d.ts +0 -38
  139. package/dist/auth/pending-store.d.ts +0 -33
  140. package/dist/auth/resolve.d.ts +0 -30
  141. package/dist/billing.d.ts +0 -44
  142. package/dist/capabilities.d.ts +0 -63
  143. package/dist/cli.d.ts +0 -13
  144. package/dist/diagnostics.d.ts +0 -24
  145. package/dist/doctor.d.ts +0 -22
  146. package/dist/errors.d.ts +0 -29
  147. package/dist/exec.d.ts +0 -18
  148. package/dist/handlers/gen-digital-human.d.ts +0 -17
  149. package/dist/handlers/gen-image.d.ts +0 -20
  150. package/dist/handlers/gen-post.d.ts +0 -21
  151. package/dist/handlers/gen-video.d.ts +0 -19
  152. package/dist/handlers/gen-voice.d.ts +0 -26
  153. package/dist/handlers/index.d.ts +0 -20
  154. package/dist/handlers/shared.d.ts +0 -26
  155. package/dist/handlers/template-init.d.ts +0 -10
  156. package/dist/http.d.ts +0 -72
  157. package/dist/index.d.ts +0 -9
  158. package/dist/install.d.ts +0 -71
  159. package/dist/progress.d.ts +0 -23
  160. package/dist/project/commands.d.ts +0 -19
  161. package/dist/project/host.d.ts +0 -91
  162. package/dist/project/resolve.d.ts +0 -43
  163. package/dist/project/store.d.ts +0 -31
  164. package/dist/project/take.d.ts +0 -50
  165. package/dist/project/trace.d.ts +0 -98
  166. package/dist/registry.d.ts +0 -30
  167. package/dist/runner.d.ts +0 -39
  168. package/dist/skill-schema.d.ts +0 -138
  169. package/dist/template/args.d.ts +0 -25
  170. package/dist/template/check.d.ts +0 -23
  171. package/dist/template/commands.d.ts +0 -25
  172. package/dist/template/constants.d.ts +0 -39
  173. package/dist/template/init.d.ts +0 -28
  174. package/dist/template/list.d.ts +0 -23
  175. package/dist/template/preview.d.ts +0 -60
  176. package/dist/template/proc.d.ts +0 -26
  177. package/dist/template/project.d.ts +0 -47
  178. package/dist/template/publish.d.ts +0 -43
  179. package/dist/template/render-client.d.ts +0 -39
  180. package/dist/template/upgrade.d.ts +0 -44
  181. package/dist/text.d.ts +0 -8
@@ -1,194 +1 @@
1
- /**
2
- * Single source of truth for skill.json shape + validation.
3
- *
4
- * Imported directly by `registry.ts` (runtime loader) and — via the compiled
5
- * `dist/skill-schema.js` — by `scripts/build-manifest.mjs` and `scripts/smoke.mjs`.
6
- * Previously each of those reimplemented `normalizeEntry` and its own subset of
7
- * field checks, so "valid at build" ≠ "loadable at runtime". Centralizing here
8
- * means one definition of a well-formed skill.
9
- *
10
- * Error policy is the caller's choice: `validateSkillJson` returns a list of
11
- * human-readable problems (empty = OK). The runtime loader skips + warns;
12
- * the build treats them as fatal.
13
- */
14
- export const CATEGORY_VALUES = ['authoring', 'consuming', 'asset', 'meta'];
15
- export const AUTH_VALUES = ['required', 'optional', 'none'];
16
- /**
17
- * Resolve a skill's auth mode, defaulting for records that predate the field.
18
- *
19
- * The default is derived from `envVars` rather than hardcoded to `'required'`:
20
- * a skill that never declared PRIV_TOKEN cannot possibly need a credential, and
21
- * defaulting it to `required` would make a purely local skill (web-screenshot)
22
- * pop a browser. Every skill shipped in this package declares `auth` explicitly,
23
- * so this only covers externally supplied skill dirs (SKILL_BASE_DIR).
24
- */
25
- export function resolveAuthMode(raw) {
26
- if (raw.auth)
27
- return raw.auth;
28
- return raw.envVars?.includes('PRIV_TOKEN') ? 'required' : 'none';
29
- }
30
- export const TIER_VALUES = ['atomic', 'orchestration', 'tool'];
31
- export const REQUIRED_SKILL_JSON_FIELDS = ['name', 'tier', 'title', 'description'];
32
- /**
33
- * Resolve the dispatcher entry. A missing `entry` falls back to the legacy
34
- * top-level `scriptPath`, treated as `{ type: 'python', scriptPath }` so older
35
- * skills keep working untouched. Returns null when neither is present.
36
- */
37
- export function normalizeEntry(raw) {
38
- if (raw.entry)
39
- return raw.entry;
40
- if (raw.scriptPath)
41
- return { type: 'python', scriptPath: raw.scriptPath };
42
- return null;
43
- }
44
- /** `parameters.properties` 的键;非对象 / 无 properties 时返回空数组。 */
45
- function parameterKeys(parameters) {
46
- if (!parameters || typeof parameters !== 'object')
47
- return [];
48
- const props = parameters.properties;
49
- if (!props || typeof props !== 'object')
50
- return [];
51
- return Object.keys(props);
52
- }
53
- /** `parameters.required`;缺失或格式不对时返回空数组。 */
54
- function requiredKeys(parameters) {
55
- if (!parameters || typeof parameters !== 'object')
56
- return [];
57
- const req = parameters.required;
58
- return Array.isArray(req) ? req.filter((k) => typeof k === 'string') : [];
59
- }
60
- /**
61
- * 把 `ui` 声明补全成三个互斥的完整分桶。没声明 `ui` 时按 required 推导。
62
- *
63
- * **未提及的字段一律落进 advanced**:新增参数时最坏是多折一层,而不是消失。
64
- * 返回 null 表示这个 skill 没有可填的参数(不该弹表单)。
65
- */
66
- export function resolveUiHints(raw) {
67
- const keys = parameterKeys(raw.parameters);
68
- if (keys.length === 0)
69
- return null;
70
- if (!raw.ui) {
71
- const required = new Set(requiredKeys(raw.parameters));
72
- return {
73
- primary: keys.filter((k) => required.has(k)),
74
- advanced: keys.filter((k) => !required.has(k)),
75
- hidden: [],
76
- };
77
- }
78
- const declared = raw.ui;
79
- const keySet = new Set(keys);
80
- // 只保留真实存在的字段:schema 删了某个参数但 ui 忘了同步时,
81
- // 不至于让下游渲染出一个没有定义的表单项。
82
- const keep = (list) => (list ?? []).filter((k) => keySet.has(k));
83
- const primary = keep(declared.primary);
84
- const advanced = keep(declared.advanced);
85
- const hidden = keep(declared.hidden);
86
- const mentioned = new Set([...primary, ...advanced, ...hidden]);
87
- return {
88
- primary,
89
- advanced: [...advanced, ...keys.filter((k) => !mentioned.has(k))],
90
- hidden,
91
- };
92
- }
93
- /**
94
- * `ui` 分级的自检。三条规则,每条都对应一种"表单看起来正常但填不出东西"的坏状态。
95
- */
96
- function validateUiHints(raw) {
97
- if (raw.ui == null)
98
- return [];
99
- const errors = [];
100
- if (typeof raw.ui !== 'object' || Array.isArray(raw.ui)) {
101
- return ['skill.json.ui must be an object with primary / advanced / hidden arrays'];
102
- }
103
- const keys = new Set(parameterKeys(raw.parameters));
104
- const seen = new Map(); // 字段 → 首次出现的桶
105
- for (const bucket of ['primary', 'advanced', 'hidden']) {
106
- const list = raw.ui[bucket];
107
- if (list == null)
108
- continue;
109
- if (!Array.isArray(list) || list.some((k) => typeof k !== 'string' || k === '')) {
110
- errors.push(`skill.json.ui.${bucket} must be an array of non-empty parameter names`);
111
- continue;
112
- }
113
- for (const key of list) {
114
- // 引用了不存在的参数:多半是 schema 改名后 ui 没跟着改。
115
- if (!keys.has(key)) {
116
- errors.push(`skill.json.ui.${bucket} references unknown parameter '${key}'`);
117
- }
118
- const first = seen.get(key);
119
- if (first) {
120
- errors.push(`skill.json.ui lists '${key}' in both '${first}' and '${bucket}'`);
121
- }
122
- else {
123
- seen.set(key, bucket);
124
- }
125
- }
126
- }
127
- // 必填字段被藏起来 = 表单永远填不完整,且没有任何提示。
128
- for (const key of requiredKeys(raw.parameters)) {
129
- if (raw.ui.hidden?.includes(key)) {
130
- errors.push(`skill.json.ui.hidden contains required parameter '${key}' — it could never be filled`);
131
- }
132
- }
133
- return errors;
134
- }
135
- /**
136
- * Validate a parsed skill.json against the directory it lives in. Returns an
137
- * array of problem strings; an empty array means the record is well-formed.
138
- */
139
- export function validateSkillJson(raw, skillId) {
140
- const errors = [];
141
- for (const field of REQUIRED_SKILL_JSON_FIELDS) {
142
- const value = raw[field];
143
- if (value == null || value === '')
144
- errors.push(`skill.json missing required field '${field}'`);
145
- }
146
- if (raw.tier != null && !TIER_VALUES.includes(raw.tier)) {
147
- errors.push(`skill.json.tier must be one of ${TIER_VALUES.join(' | ')}, got '${raw.tier}'`);
148
- }
149
- if (raw.category != null && !CATEGORY_VALUES.includes(raw.category)) {
150
- errors.push(`skill.json.category must be one of ${CATEGORY_VALUES.join(' | ')}, got '${raw.category}'`);
151
- }
152
- if (raw.auth != null && !AUTH_VALUES.includes(raw.auth)) {
153
- errors.push(`skill.json.auth must be one of ${AUTH_VALUES.join(' | ')}, got '${raw.auth}'`);
154
- }
155
- if (raw.createsTake != null && typeof raw.createsTake !== 'boolean') {
156
- errors.push(`skill.json.createsTake must be a boolean, got '${String(raw.createsTake)}'`);
157
- }
158
- if (raw.joinsTake != null && typeof raw.joinsTake !== 'boolean') {
159
- errors.push(`skill.json.joinsTake must be a boolean, got '${String(raw.joinsTake)}'`);
160
- }
161
- if (raw.createsTakeUnless != null) {
162
- if (!Array.isArray(raw.createsTakeUnless) ||
163
- raw.createsTakeUnless.some((f) => typeof f !== 'string' || f === '')) {
164
- errors.push("skill.json.createsTakeUnless must be an array of non-empty argv keys");
165
- }
166
- else if (raw.createsTake !== true) {
167
- // It only ever downgrades createsTake; on any other skill it would read as
168
- // working while doing nothing.
169
- errors.push("skill.json.createsTakeUnless requires createsTake=true");
170
- }
171
- else if (raw.createsTakeUnless.some((f) => f.includes('-'))) {
172
- // argv.ts hands the dispatcher snake_case keys, so `--resolve-only`
173
- // arrives as `resolve_only`. A kebab entry would silently never match.
174
- errors.push("skill.json.createsTakeUnless entries must be snake_case argv keys (e.g. 'resolve_only', not 'resolve-only')");
175
- }
176
- }
177
- if (raw.createsTake === true && raw.joinsTake === true) {
178
- errors.push("skill.json cannot set both 'createsTake' and 'joinsTake' — createsTake already implies joining");
179
- }
180
- // Attribution means calling ab-api as a specific user. An `auth: none` skill
181
- // never touches the backend and produces no server-side file, so there is
182
- // nothing to attribute — the flag would be dead config that reads as working.
183
- if ((raw.createsTake === true || raw.joinsTake === true) && resolveAuthMode(raw) === 'none') {
184
- errors.push("skill.json declares createsTake/joinsTake but auth='none' — a purely local skill has nothing to attribute");
185
- }
186
- errors.push(...validateUiHints(raw));
187
- if (raw.name && raw.name !== skillId) {
188
- errors.push(`skill.json.name='${raw.name}' does not match directory name '${skillId}'`);
189
- }
190
- if (!normalizeEntry(raw)) {
191
- errors.push("skill.json missing 'entry' (or legacy 'scriptPath')");
192
- }
193
- return errors;
194
- }
1
+ var m=Object.defineProperty;var r=(e,n)=>m(e,"name",{value:n,configurable:!0});const f=["authoring","consuming","asset","meta"],p=["required","optional","none"];function j(e){return e.auth?e.auth:e.envVars?.includes("PRIV_TOKEN")?"required":"none"}r(j,"resolveAuthMode");const k=["atomic","orchestration","tool"],T=["name","tier","title","description"];function g(e){return e.entry?e.entry:e.scriptPath?{type:"python",scriptPath:e.scriptPath}:null}r(g,"normalizeEntry");function d(e){if(!e||typeof e!="object")return[];const n=e.properties;return!n||typeof n!="object"?[]:Object.keys(n)}r(d,"parameterKeys");function y(e){if(!e||typeof e!="object")return[];const n=e.required;return Array.isArray(n)?n.filter(t=>typeof t=="string"):[]}r(y,"requiredKeys");function v(e){const n=d(e.parameters);if(n.length===0)return null;if(!e.ui){const u=new Set(y(e.parameters));return{primary:n.filter(c=>u.has(c)),advanced:n.filter(c=>!u.has(c)),hidden:[]}}const t=e.ui,i=new Set(n),s=r(u=>(u??[]).filter(c=>i.has(c)),"keep"),l=s(t.primary),o=s(t.advanced),a=s(t.hidden),h=new Set([...l,...o,...a]);return{primary:l,advanced:[...o,...n.filter(u=>!h.has(u))],hidden:a}}r(v,"resolveUiHints");function b(e){if(e.ui==null)return[];const n=[];if(typeof e.ui!="object"||Array.isArray(e.ui))return["skill.json.ui must be an object with primary / advanced / hidden arrays"];const t=new Set(d(e.parameters)),i=new Map;for(const s of["primary","advanced","hidden"]){const l=e.ui[s];if(l!=null){if(!Array.isArray(l)||l.some(o=>typeof o!="string"||o==="")){n.push(`skill.json.ui.${s} must be an array of non-empty parameter names`);continue}for(const o of l){t.has(o)||n.push(`skill.json.ui.${s} references unknown parameter '${o}'`);const a=i.get(o);a?n.push(`skill.json.ui lists '${o}' in both '${a}' and '${s}'`):i.set(o,s)}}}for(const s of y(e.parameters))e.ui.hidden?.includes(s)&&n.push(`skill.json.ui.hidden contains required parameter '${s}' — it could never be filled`);return n}r(b,"validateUiHints");function A(e,n){const t=[];for(const i of T){const s=e[i];(s==null||s==="")&&t.push(`skill.json missing required field '${i}'`)}return e.tier!=null&&!k.includes(e.tier)&&t.push(`skill.json.tier must be one of ${k.join(" | ")}, got '${e.tier}'`),e.category!=null&&!f.includes(e.category)&&t.push(`skill.json.category must be one of ${f.join(" | ")}, got '${e.category}'`),e.auth!=null&&!p.includes(e.auth)&&t.push(`skill.json.auth must be one of ${p.join(" | ")}, got '${e.auth}'`),e.createsTake!=null&&typeof e.createsTake!="boolean"&&t.push(`skill.json.createsTake must be a boolean, got '${String(e.createsTake)}'`),e.joinsTake!=null&&typeof e.joinsTake!="boolean"&&t.push(`skill.json.joinsTake must be a boolean, got '${String(e.joinsTake)}'`),e.createsTakeUnless!=null&&(!Array.isArray(e.createsTakeUnless)||e.createsTakeUnless.some(i=>typeof i!="string"||i==="")?t.push("skill.json.createsTakeUnless must be an array of non-empty argv keys"):e.createsTake!==!0?t.push("skill.json.createsTakeUnless requires createsTake=true"):e.createsTakeUnless.some(i=>i.includes("-"))&&t.push("skill.json.createsTakeUnless entries must be snake_case argv keys (e.g. 'resolve_only', not 'resolve-only')")),e.createsTake===!0&&e.joinsTake===!0&&t.push("skill.json cannot set both 'createsTake' and 'joinsTake' — createsTake already implies joining"),(e.createsTake===!0||e.joinsTake===!0)&&j(e)==="none"&&t.push("skill.json declares createsTake/joinsTake but auth='none' — a purely local skill has nothing to attribute"),t.push(...b(e)),e.name&&e.name!==n&&t.push(`skill.json.name='${e.name}' does not match directory name '${n}'`),g(e)||t.push("skill.json missing 'entry' (or legacy 'scriptPath')"),t}r(A,"validateSkillJson");export{p as AUTH_VALUES,f as CATEGORY_VALUES,T as REQUIRED_SKILL_JSON_FIELDS,k as TIER_VALUES,g as normalizeEntry,j as resolveAuthMode,v as resolveUiHints,A as validateSkillJson};
@@ -1,69 +1 @@
1
- /**
2
- * Strict argv parser for `remixmate template <sub>`.
3
- *
4
- * Unlike src/argv.ts (which is permissive because skill flags are forwarded to
5
- * Python), these subcommands own their whole surface, so an unknown flag or a
6
- * stray positional is a usage error (exit 2) rather than something silently
7
- * ignored — `publish --nmae X` must not publish under the default name.
8
- */
9
- import { EXIT, SkillError } from '../errors.js';
10
- /** Flags every subcommand accepts. */
11
- export const COMMON_FLAGS = {
12
- json: 'bool',
13
- help: 'bool',
14
- token: 'string',
15
- 'api-base-url': 'string',
16
- };
17
- export function usageError(message) {
18
- return new SkillError(`❌ ${message}`, EXIT.USAGE);
19
- }
20
- export function parseTemplateArgs(argv, spec, opts) {
21
- const all = { ...COMMON_FLAGS, ...spec };
22
- const positionals = [];
23
- const flags = {};
24
- for (let i = 0; i < argv.length; i++) {
25
- const token = argv[i];
26
- if (token === '-h') {
27
- flags.help = true;
28
- continue;
29
- }
30
- if (!token.startsWith('--')) {
31
- positionals.push(token);
32
- continue;
33
- }
34
- const eq = token.indexOf('=');
35
- const name = token.slice(2, eq > 0 ? eq : undefined);
36
- const kind = all[name];
37
- if (!kind)
38
- throw usageError(`未知参数: --${name}`);
39
- if (kind === 'bool') {
40
- if (eq > 0)
41
- throw usageError(`--${name} 不接受取值`);
42
- flags[name] = true;
43
- continue;
44
- }
45
- const value = eq > 0 ? token.slice(eq + 1) : argv[++i];
46
- if (value === undefined || (eq < 0 && value.startsWith('--'))) {
47
- throw usageError(`--${name} 需要一个取值`);
48
- }
49
- flags[name] = value;
50
- }
51
- if (!flags.help && positionals.length > opts.maxPositionals) {
52
- throw usageError(`多余的参数: ${positionals.slice(opts.maxPositionals).join(' ')}`);
53
- }
54
- return { positionals, flags };
55
- }
56
- export function flagString(flags, name) {
57
- const v = flags[name];
58
- return typeof v === 'string' ? v : undefined;
59
- }
60
- /** Parse a positive number flag; usage error on anything else. */
61
- export function flagNumber(flags, name) {
62
- const raw = flagString(flags, name);
63
- if (raw === undefined)
64
- return undefined;
65
- const n = Number(raw);
66
- if (!Number.isFinite(n) || n <= 0)
67
- throw usageError(`--${name} 必须是正数,收到 '${raw}'`);
68
- return n;
69
- }
1
+ var d=Object.defineProperty;var f=(n,e)=>d(n,"name",{value:e,configurable:!0});import{EXIT as g,SkillError as m}from"../errors.js";const x={json:"bool",help:"bool",token:"string","api-base-url":"string"};function l(n){return new m(`❌ ${n}`,g.USAGE)}f(l,"usageError");function k(n,e,t){const s={...x,...e},c=[],u={};for(let a=0;a<n.length;a++){const o=n[a];if(o==="-h"){u.help=!0;continue}if(!o.startsWith("--")){c.push(o);continue}const i=o.indexOf("="),r=o.slice(2,i>0?i:void 0),p=s[r];if(!p)throw l(`未知参数: --${r}`);if(p==="bool"){if(i>0)throw l(`--${r} 不接受取值`);u[r]=!0;continue}const h=i>0?o.slice(i+1):n[++a];if(h===void 0||i<0&&h.startsWith("--"))throw l(`--${r} 需要一个取值`);u[r]=h}if(!u.help&&c.length>t.maxPositionals)throw l(`多余的参数: ${c.slice(t.maxPositionals).join(" ")}`);return{positionals:c,flags:u}}f(k,"parseTemplateArgs");function b(n,e){const t=n[e];return typeof t=="string"?t:void 0}f(b,"flagString");function E(n,e){const t=b(n,e);if(t===void 0)return;const s=Number(t);if(!Number.isFinite(s)||s<=0)throw l(`--${e} 必须是正数,收到 '${t}'`);return s}f(E,"flagNumber");export{x as COMMON_FLAGS,E as flagNumber,b as flagString,k as parseTemplateArgs,l as usageError};
@@ -1,30 +1,2 @@
1
- /**
2
- * `remixmate template check [name] [--json] [--no-write]`
3
- *
4
- * Pure orchestration: the validation itself lives in the starter
5
- * (`.remixmate/check/index.mjs`, K3), synced from the same schema / security
6
- * policy sources the platform uses. The cli never carries its own copy — that
7
- * would be the drift requirement 5.2 exists to prevent.
8
- */
9
- import path from 'node:path';
10
- import { CHECK_ENTRY } from './constants.js';
11
- import { requireProjectRoot, staleRulesHint } from './project.js';
12
- import { runProcess } from './proc.js';
13
- /** Run the starter's check script; resolves to its exit code (0 ok / 1 issues / 2 usage). */
14
- export async function runCheck(opts = {}) {
15
- const root = requireProjectRoot(opts.cwd);
16
- // 规则比 cli 对应的 starter 旧:提示 upgrade(stderr,不影响 --json 的最后一行)。
17
- // 只提示不阻断 —— 服务端渲染前还会再扫一遍,旧规则最多让问题晚一点暴露。
18
- const hint = staleRulesHint(root);
19
- if (hint)
20
- process.stderr.write(hint + '\n');
21
- const args = [path.join(root, CHECK_ENTRY)];
22
- if (opts.name)
23
- args.push(opts.name);
24
- if (opts.json)
25
- args.push('--json');
26
- if (opts.noWrite)
27
- args.push('--no-write');
28
- const res = await runProcess(process.execPath, args, { cwd: root, stdio: opts.stdio ?? 'inherit' });
29
- return res.code;
30
- }
1
+ var n=Object.defineProperty;var i=(r,o)=>n(r,"name",{value:o,configurable:!0});import s from"node:path";import{CHECK_ENTRY as c}from"./constants.js";import{requireProjectRoot as m,staleRulesHint as a}from"./project.js";import{runProcess as f}from"./proc.js";async function C(r={}){const o=m(r.cwd),t=a(o);t&&process.stderr.write(t+`
2
+ `);const e=[s.join(o,c)];return r.name&&e.push(r.name),r.json&&e.push("--json"),r.noWrite&&e.push("--no-write"),(await f(process.execPath,e,{cwd:o,stdio:r.stdio??"inherit"})).code}i(C,"runCheck");export{C as runCheck};
@@ -1,163 +1,34 @@
1
- /**
2
- * `remixmate template <init|check|preview|publish|list>` dispatcher.
3
- *
4
- * Exit codes follow the cli contract (errors.ts): 2 usage, 4 credentials,
5
- * 5 backend unreachable; `check` propagates the starter script's own code.
6
- * With --json a failure also ends stdout with `{"ok":false,...}` so hosts
7
- * parsing the last line always get an object.
8
- */
9
- import { cleanDiagnosticText } from '../diagnostics.js';
10
- import { EXIT, SkillError } from '../errors.js';
11
- import { flagNumber, flagString, parseTemplateArgs, usageError } from './args.js';
12
- import { runCheck } from './check.js';
13
- import { runUpgrade } from './upgrade.js';
14
- import { STARTER_PACKAGE, STARTER_VERSION } from './constants.js';
15
- import { runInit } from './init.js';
16
- import { runList } from './list.js';
17
- import { runPreview } from './preview.js';
18
- import { runPublish } from './publish.js';
19
- export const TEMPLATE_VERB = 'template';
20
- export const TEMPLATE_SUBCOMMANDS = ['init', 'check', 'preview', 'publish', 'list', 'upgrade'];
21
- export const SUB_SPECS = {
22
- init: {
23
- flags: { force: 'bool', 'skip-install': 'bool' },
24
- maxPositionals: 1,
25
- usage: 'remixmate template init <dir> [--force] [--skip-install] [--json]\n' +
26
- ` 从 ${STARTER_PACKAGE}@${STARTER_VERSION} 创建模板工程并安装依赖(无需登录)。\n` +
27
- ' 目标目录非空时拒绝,除非 --force。--skip-install 只解压不执行 npm install。\n',
28
- },
29
- check: {
30
- flags: { 'no-write': 'bool' },
31
- maxPositionals: 1,
32
- usage: 'remixmate template check [name] [--json] [--no-write]\n' +
33
- ' 在模板工程内运行本地校验(类型、schema、安全策略、props 契约、core 导出)。\n' +
34
- ' 不传 name 校验 templates/ 下全部模板;默认刷新 coreVersion/coreExports,--no-write 只检查。\n',
35
- },
36
- preview: {
37
- flags: { 'props-json': 'string', 'duration-sec': 'string', 'composition-id': 'string', 'timeout-sec': 'string' },
38
- maxPositionals: 1,
39
- usage: 'remixmate template preview <name> [--props-json JSON] [--duration-sec N] [--composition-id ID] [--timeout-sec N] [--json]\n' +
40
- ' 先 check,再把模板提交到远程渲染器出预览 mp4(需登录)。\n' +
41
- ' 样例数据取自模板的 dsl-example.json,可用 --props-json 覆盖(传数组 = 每个元素一页)。\n' +
42
- ' 预览上限:长边 1280、短边 720、总时长 60 秒。\n',
43
- },
44
- publish: {
45
- flags: { name: 'string', 'dry-run': 'bool' },
46
- maxPositionals: 1,
47
- usage: 'remixmate template publish <name> [--name <displayName>] [--dry-run] [--json]\n' +
48
- ' 先 check 与 core 预检,再发布为你的私有模板(需登录)。\n' +
49
- ' 首次发布生成 templateKey 并写入 templates/<name>/.remixmate.json,之后重复发布即更新。\n',
50
- },
51
- list: {
52
- flags: {},
53
- maxPositionals: 0,
54
- usage: 'remixmate template list [--json]\n 列出你发布的私有模板(需登录)。\n',
55
- },
56
- upgrade: {
57
- flags: { 'dry-run': 'bool', 'with-docs': 'bool', force: 'bool' },
58
- maxPositionals: 0,
59
- usage: 'remixmate template upgrade [--dry-run] [--with-docs] [--force] [--json]\n' +
60
- ` 把工程的本地校验规则(.remixmate/)更新到 ${STARTER_PACKAGE}@${STARTER_VERSION}(无需登录)。\n` +
61
- ' 不改动 templates/、src/、examples/、package.json;--with-docs 同时刷新 AGENTS.md / CLAUDE.md(旧文件存为 *.orig)。\n',
62
- },
63
- };
64
- export function templateUsage() {
65
- return ('Usage: remixmate template <command> [options]\n\n' +
66
- 'Commands:\n' +
67
- ' init <dir> 创建模板工程(无需登录)\n' +
68
- ' check [name] 本地校验(无需登录)\n' +
69
- ' preview <name> 远程渲染预览 mp4\n' +
70
- ' publish <name> 发布为私有模板\n' +
71
- ' list 列出我的私有模板\n' +
72
- ' upgrade 更新工程的本地校验规则(无需登录)\n\n' +
73
- 'Common options: --json --token <PrivToken> --api-base-url <url>\n' +
74
- '环境变量:AB_RENDER_URL(渲染服务地址)、REMIXMATE_STARTER_TARBALL(init 使用本地 starter 包)\n' +
75
- '运行 remixmate template <command> --help 查看子命令说明。\n');
76
- }
77
- export function parseTemplateCommand(argv) {
78
- const [sub, ...rest] = argv;
79
- if (!sub || sub === '--help' || sub === '-h' || sub === 'help') {
80
- return { sub: 'help', args: { positionals: [], flags: {} } };
81
- }
82
- if (!TEMPLATE_SUBCOMMANDS.includes(sub)) {
83
- throw usageError(`未知子命令: template ${sub}(可选:${TEMPLATE_SUBCOMMANDS.join(' | ')})`);
84
- }
85
- const spec = SUB_SPECS[sub];
86
- return { sub: sub, args: parseTemplateArgs(rest, spec.flags, { maxPositionals: spec.maxPositionals }) };
87
- }
88
- async function dispatch(sub, args) {
89
- const { flags, positionals } = args;
90
- const json = flags.json === true;
91
- const token = flagString(flags, 'token');
92
- const apiBaseUrl = flagString(flags, 'api-base-url');
93
- switch (sub) {
94
- case 'init':
95
- if (!positionals[0])
96
- throw usageError('缺少目标目录:remixmate template init <dir>');
97
- await runInit({ dir: positionals[0], force: flags.force === true, json, skipInstall: flags['skip-install'] === true });
98
- return EXIT.OK;
99
- case 'check':
100
- return runCheck({ name: positionals[0], json, noWrite: flags['no-write'] === true });
101
- case 'preview':
102
- await runPreview({
103
- name: positionals[0],
104
- propsJson: flagString(flags, 'props-json'),
105
- durationSec: flagNumber(flags, 'duration-sec'),
106
- compositionId: flagString(flags, 'composition-id'),
107
- timeoutSec: flagNumber(flags, 'timeout-sec'),
108
- json,
109
- token,
110
- apiBaseUrl,
111
- });
112
- return EXIT.OK;
113
- case 'publish':
114
- await runPublish({
115
- name: positionals[0],
116
- displayName: flagString(flags, 'name'),
117
- dryRun: flags['dry-run'] === true,
118
- json,
119
- token,
120
- apiBaseUrl,
121
- });
122
- return EXIT.OK;
123
- case 'list':
124
- await runList({ json, token, apiBaseUrl });
125
- return EXIT.OK;
126
- case 'upgrade':
127
- await runUpgrade({
128
- dryRun: flags['dry-run'] === true,
129
- withDocs: flags['with-docs'] === true,
130
- force: flags.force === true,
131
- json,
132
- });
133
- return EXIT.OK;
134
- }
135
- }
136
- export async function runTemplateCommand(argv) {
137
- const json = argv.includes('--json');
138
- let sub;
139
- try {
140
- const parsed = parseTemplateCommand(argv);
141
- sub = parsed.sub;
142
- if (sub === 'help') {
143
- process.stdout.write(templateUsage());
144
- return EXIT.OK;
145
- }
146
- if (parsed.args.flags.help) {
147
- process.stdout.write('Usage: ' + SUB_SPECS[sub].usage);
148
- return EXIT.OK;
149
- }
150
- return await dispatch(sub, parsed.args);
151
- }
152
- catch (err) {
153
- const code = err instanceof SkillError ? err.exitCode : EXIT.ERROR;
154
- const message = err instanceof SkillError ? err.message : `❌ unexpected error: ${err.stack ?? String(err)}`;
155
- process.stderr.write(cleanDiagnosticText(message, 8192) + '\n');
156
- if (code === EXIT.USAGE && sub && sub !== 'help')
157
- process.stderr.write('Usage: ' + SUB_SPECS[sub].usage);
158
- if (json) {
159
- process.stdout.write(JSON.stringify({ ok: false, exitCode: code, error: cleanDiagnosticText(message.replace(/^❌\s*/, ''), 2048) }) + '\n');
160
- }
161
- return code;
162
- }
163
- }
1
+ var w=Object.defineProperty;var a=(o,r)=>w(o,"name",{value:r,configurable:!0});import{cleanDiagnosticText as l}from"../diagnostics.js";import{EXIT as n,SkillError as u}from"../errors.js";import{flagNumber as d,flagString as m,parseTemplateArgs as E,usageError as g}from"./args.js";import{runCheck as b}from"./check.js";import{runUpgrade as k}from"./upgrade.js";import{STARTER_PACKAGE as f,STARTER_VERSION as h}from"./constants.js";import{runInit as j}from"./init.js";import{runList as T}from"./list.js";import{runPreview as R}from"./preview.js";import{runPublish as S}from"./publish.js";const D="template",x=["init","check","preview","publish","list","upgrade"],c={init:{flags:{force:"bool","skip-install":"bool"},maxPositionals:1,usage:`remixmate template init <dir> [--force] [--skip-install] [--json]
2
+ 从 ${f}@${h} 创建模板工程并安装依赖(无需登录)。
3
+ 目标目录非空时拒绝,除非 --force。--skip-install 只解压不执行 npm install。
4
+ `},check:{flags:{"no-write":"bool"},maxPositionals:1,usage:`remixmate template check [name] [--json] [--no-write]
5
+ 在模板工程内运行本地校验(类型、schema、安全策略、props 契约、core 导出)。
6
+ 不传 name 校验 templates/ 下全部模板;默认刷新 coreVersion/coreExports,--no-write 只检查。
7
+ `},preview:{flags:{"props-json":"string","duration-sec":"string","composition-id":"string","timeout-sec":"string"},maxPositionals:1,usage:`remixmate template preview <name> [--props-json JSON] [--duration-sec N] [--composition-id ID] [--timeout-sec N] [--json]
8
+ 先 check,再把模板提交到远程渲染器出预览 mp4(需登录)。
9
+ 样例数据取自模板的 dsl-example.json,可用 --props-json 覆盖(传数组 = 每个元素一页)。
10
+ 预览上限:长边 1280、短边 720、总时长 60 秒。
11
+ `},publish:{flags:{name:"string","dry-run":"bool"},maxPositionals:1,usage:`remixmate template publish <name> [--name <displayName>] [--dry-run] [--json]
12
+ 先 check 与 core 预检,再发布为你的私有模板(需登录)。
13
+ 首次发布生成 templateKey 并写入 templates/<name>/.remixmate.json,之后重复发布即更新。
14
+ `},list:{flags:{},maxPositionals:0,usage:`remixmate template list [--json]
15
+ 列出你发布的私有模板(需登录)。
16
+ `},upgrade:{flags:{"dry-run":"bool","with-docs":"bool",force:"bool"},maxPositionals:0,usage:`remixmate template upgrade [--dry-run] [--with-docs] [--force] [--json]
17
+ 把工程的本地校验规则(.remixmate/)更新到 ${f}@${h}(无需登录)。
18
+ 不改动 templates/、src/、examples/、package.json;--with-docs 同时刷新 AGENTS.md / CLAUDE.md(旧文件存为 *.orig)。
19
+ `}};function A(){return`Usage: remixmate template <command> [options]
20
+
21
+ Commands:
22
+ init <dir> 创建模板工程(无需登录)
23
+ check [name] 本地校验(无需登录)
24
+ preview <name> 远程渲染预览 mp4
25
+ publish <name> 发布为私有模板
26
+ list 列出我的私有模板
27
+ upgrade 更新工程的本地校验规则(无需登录)
28
+
29
+ Common options: --json --token <PrivToken> --api-base-url <url>
30
+ 环境变量:AB_RENDER_URL(渲染服务地址)、REMIXMATE_STARTER_TARBALL(init 使用本地 starter 包)
31
+ 运行 remixmate template <command> --help 查看子命令说明。
32
+ `}a(A,"templateUsage");function y(o){const[r,...e]=o;if(!r||r==="--help"||r==="-h"||r==="help")return{sub:"help",args:{positionals:[],flags:{}}};if(!x.includes(r))throw g(`未知子命令: template ${r}(可选:${x.join(" | ")})`);const t=c[r];return{sub:r,args:E(e,t.flags,{maxPositionals:t.maxPositionals})}}a(y,"parseTemplateCommand");async function P(o,r){const{flags:e,positionals:t}=r,s=e.json===!0,i=m(e,"token"),p=m(e,"api-base-url");switch(o){case"init":if(!t[0])throw g("缺少目标目录:remixmate template init <dir>");return await j({dir:t[0],force:e.force===!0,json:s,skipInstall:e["skip-install"]===!0}),n.OK;case"check":return b({name:t[0],json:s,noWrite:e["no-write"]===!0});case"preview":return await R({name:t[0],propsJson:m(e,"props-json"),durationSec:d(e,"duration-sec"),compositionId:m(e,"composition-id"),timeoutSec:d(e,"timeout-sec"),json:s,token:i,apiBaseUrl:p}),n.OK;case"publish":return await S({name:t[0],displayName:m(e,"name"),dryRun:e["dry-run"]===!0,json:s,token:i,apiBaseUrl:p}),n.OK;case"list":return await T({json:s,token:i,apiBaseUrl:p}),n.OK;case"upgrade":return await k({dryRun:e["dry-run"]===!0,withDocs:e["with-docs"]===!0,force:e.force===!0,json:s}),n.OK}}a(P,"dispatch");async function M(o){const r=o.includes("--json");let e;try{const t=y(o);return e=t.sub,e==="help"?(process.stdout.write(A()),n.OK):t.args.flags.help?(process.stdout.write("Usage: "+c[e].usage),n.OK):await P(e,t.args)}catch(t){const s=t instanceof u?t.exitCode:n.ERROR,i=t instanceof u?t.message:`❌ unexpected error: ${t.stack??String(t)}`;return process.stderr.write(l(i,8192)+`
33
+ `),s===n.USAGE&&e&&e!=="help"&&process.stderr.write("Usage: "+c[e].usage),r&&process.stdout.write(JSON.stringify({ok:!1,exitCode:s,error:l(i.replace(/^❌\s*/,""),2048)})+`
34
+ `),s}}a(M,"runTemplateCommand");export{c as SUB_SPECS,x as TEMPLATE_SUBCOMMANDS,D as TEMPLATE_VERB,y as parseTemplateCommand,M as runTemplateCommand,A as templateUsage};
@@ -1,46 +1 @@
1
- /**
2
- * Contract constants for `remixmate template` (design §11 K1 / K5 / K6).
3
- *
4
- * STARTER_VERSION pins the exact starter release this cli was tested against.
5
- * Bumping it is a deliberate cli release, never a range — `init` must produce
6
- * the same project on every machine for a given cli version.
7
- */
8
- export const STARTER_PACKAGE = '@remixmate/template-starter';
9
- /**
10
- * 一个 starter 版本 = 一套本地校验规则版本(.remixmate/)。规则更新的发布顺序:
11
- * template-library `pnpm publish:sdk --publish` 发新 starter → 改这里 → cli 发版。
12
- * publish:sdk 会比对这个常量,对不上就拒发。
13
- */
14
- export const STARTER_VERSION = '0.2.0';
15
- /**
16
- * 工程里记录规则版本的文件(starter ≥0.2.0 构建时写入;`template upgrade` 也会写)。
17
- * 0.1.0 工程没有它,回落读 package.json 的 version(init 时整份复制自 starter)。
18
- */
19
- export const RULES_VERSION_FILE = '.remixmate/version.json';
20
- /** `template upgrade` 只替换这个目录;用户的 templates/、src/ 等一律不动。 */
21
- export const RULES_DIR = '.remixmate';
22
- /** `template upgrade --with-docs` 额外刷新的 agent 指南(旧文件备份为 *.orig)。 */
23
- export const DOC_FILES = ['AGENTS.md', 'CLAUDE.md'];
24
- /** Local tarball override (testing a starter before it is published). */
25
- export const STARTER_TARBALL_ENV = 'REMIXMATE_STARTER_TARBALL';
26
- /** Marker file that identifies a starter project root (K3). */
27
- export const CHECK_ENTRY = '.remixmate/check/index.mjs';
28
- /** Per-template identity file written by publish (K4). */
29
- export const IDENTITY_FILE = '.remixmate.json';
30
- export const DEFAULT_RENDER_BASE_URL = 'https://api-render.remixmate.ai';
31
- /** Draft preview limits enforced by ab-render /renderDraft (K5). */
32
- export const PREVIEW_MAX_LONG_EDGE = 1280;
33
- export const PREVIEW_MAX_SHORT_EDGE = 720;
34
- export const PREVIEW_MAX_SECONDS = 60;
35
- /**
36
- * Same list as template-library `publish-private.mjs` TAR_EXCLUDES. `dsl-example.json`
37
- * is deliberately kept: it is the reference DSL the registry ships with the template.
38
- */
39
- export const TAR_EXCLUDES = [
40
- '__pycache__',
41
- 'node_modules',
42
- 'dist',
43
- '.DS_Store',
44
- '*.test.*',
45
- '*.spec.*',
46
- ];
1
+ const t="@remixmate/template-starter",e="0.2.0",E=".remixmate/version.json",o=".remixmate",_=["AGENTS.md","CLAUDE.md"],r="REMIXMATE_STARTER_TARBALL",R=".remixmate/check/index.mjs",s=".remixmate.json",x="https://api-render.remixmate.ai",n=1280,A=720,c=60,p=["__pycache__","node_modules","dist",".DS_Store","*.test.*","*.spec.*"];export{R as CHECK_ENTRY,x as DEFAULT_RENDER_BASE_URL,_ as DOC_FILES,s as IDENTITY_FILE,n as PREVIEW_MAX_LONG_EDGE,c as PREVIEW_MAX_SECONDS,A as PREVIEW_MAX_SHORT_EDGE,o as RULES_DIR,E as RULES_VERSION_FILE,t as STARTER_PACKAGE,r as STARTER_TARBALL_ENV,e as STARTER_VERSION,p as TAR_EXCLUDES};