@deessejs/cli 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Deessejs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,38 +1,38 @@
1
- # @deessejs/cli
2
-
3
- CLI for the DeesseJS template registry.
4
-
5
- ## Install (V1)
6
-
7
- ```bash
8
- npx deessejs@latest <command>
9
- ```
10
-
11
- Future (V1.1+, when pro templates need auth): `npm i -g @deessejs/cli`.
12
-
13
- ## Commands
14
-
15
- | Command | Role |
16
- |---|---|
17
- | `deessejs init <slug>` | Clone a template repo + install dependencies |
18
- | `deessejs list` | List available templates |
19
- | `deessejs info <slug>` | Show details for one template |
20
-
21
- ## Examples
22
-
23
- ```bash
24
- deessejs list
25
- deessejs list --category saas --json
26
- deessejs info saas-starter --json
27
- deessejs init saas-starter
28
- deessejs init saas-starter --ref develop --no-install
29
- ```
30
-
31
- ## Global flags
32
-
33
- - `--api-url <url>` — override the templates endpoint (default: `https://deessejs.com/api/templates`)
34
- - `--json` — JSON output for scripting
35
-
36
- ## License
37
-
1
+ # @deessejs/cli
2
+
3
+ CLI for the DeesseJS template registry.
4
+
5
+ ## Install (V1)
6
+
7
+ ```bash
8
+ npx deessejs@latest <command>
9
+ ```
10
+
11
+ Future (V1.1+, when pro templates need auth): `npm i -g @deessejs/cli`.
12
+
13
+ ## Commands
14
+
15
+ | Command | Role |
16
+ |---|---|
17
+ | `deessejs init <slug>` | Clone a template repo + install dependencies |
18
+ | `deessejs list` | List available templates |
19
+ | `deessejs info <slug>` | Show details for one template |
20
+
21
+ ## Examples
22
+
23
+ ```bash
24
+ deessejs list
25
+ deessejs list --category saas --json
26
+ deessejs info saas-starter --json
27
+ deessejs init saas-starter
28
+ deessejs init saas-starter --ref develop --no-install
29
+ ```
30
+
31
+ ## Global flags
32
+
33
+ - `--api-url <url>` — override the templates endpoint (default: `https://deessejs.com/api/templates`)
34
+ - `--json` — JSON output for scripting
35
+
36
+ ## License
37
+
38
38
  UNLICENSED for V1 (private). License TBD before npm publish.
package/dist/index.js CHANGED
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import pc2 from 'picocolors';
4
- import { existsSync, readFileSync } from 'fs';
5
- import { resolve, join } from 'path';
4
+ import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'fs';
5
+ import { join, resolve } from 'path';
6
6
  import ora from 'ora';
7
+ import { TemplatesListResponseV1 } from '@workspace/contracts/v1';
8
+ import { homedir } from 'os';
7
9
  import { spawn as spawn$1 } from 'child_process';
8
10
 
9
11
  // src/constants.ts
10
- var DEFAULT_API_URL = "https://app.deessejs.com/api/templates";
12
+ var DEFAULT_API_URL = "https://app.deessejs.com/api/v1/templates";
11
13
  var USER_AGENT = "deessejs-cli/0.1.0 (https://deessejs.com)";
12
14
  var EXIT_ERROR = 1;
13
15
 
@@ -54,47 +56,207 @@ var parseError = (detail) => new CliError(
54
56
  detail
55
57
  );
56
58
  var internal = (detail) => new CliError("internal", "unexpected internal error", detail);
59
+ var CACHE_DIR = join(homedir(), ".deessejs");
60
+ var ensureDir = () => {
61
+ if (!existsSync(CACHE_DIR)) {
62
+ mkdirSync(CACHE_DIR, { recursive: true });
63
+ }
64
+ };
65
+ var cachePath = (name) => join(CACHE_DIR, name);
66
+ var readDiskCache = (name) => {
67
+ const path = cachePath(name);
68
+ if (!existsSync(path)) return null;
69
+ try {
70
+ const raw = readFileSync(path, "utf8");
71
+ return JSON.parse(raw);
72
+ } catch {
73
+ return null;
74
+ }
75
+ };
76
+ var writeDiskCache = (name, body, etag) => {
77
+ ensureDir();
78
+ const entry = {
79
+ etag,
80
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
81
+ body
82
+ };
83
+ const target = cachePath(name);
84
+ const tmp = `${target}.tmp`;
85
+ writeFileSync(tmp, JSON.stringify(entry), "utf8");
86
+ try {
87
+ renameSync(tmp, target);
88
+ } catch {
89
+ writeFileSync(target, JSON.stringify(entry), "utf8");
90
+ }
91
+ };
92
+
93
+ // src/fetch-with-retry.ts
94
+ var BASE_DELAYS_MS = [250, 750, 2e3];
95
+ var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
96
+ var jitter = (base) => base + Math.floor(Math.random() * 100);
97
+ var fetchWithRetry = async (opts) => {
98
+ const maxAttempts = opts.maxAttempts ?? 3;
99
+ const headers = {
100
+ "user-agent": USER_AGENT,
101
+ accept: "application/json",
102
+ ...opts.headers ?? {}
103
+ };
104
+ let lastNetworkError;
105
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
106
+ let res;
107
+ try {
108
+ res = await fetch(opts.apiUrl, { headers });
109
+ } catch (e) {
110
+ lastNetworkError = e;
111
+ if (attempt < maxAttempts - 1) {
112
+ await sleep(jitter(BASE_DELAYS_MS[attempt] ?? 2e3));
113
+ continue;
114
+ }
115
+ throw e;
116
+ }
117
+ if (res.status === 429) {
118
+ const resetHeader = res.headers.get("X-RateLimit-Reset");
119
+ const resetSec = resetHeader ? Number(resetHeader.split(",")[0]) : NaN;
120
+ const waitMs = Number.isFinite(resetSec) && resetSec > 0 ? Math.min(resetSec * 1e3, 3e4) : jitter(BASE_DELAYS_MS[attempt] ?? 2e3);
121
+ if (attempt < maxAttempts - 1) {
122
+ await sleep(waitMs);
123
+ continue;
124
+ }
125
+ }
126
+ if (res.status >= 500 && attempt < maxAttempts - 1) {
127
+ await sleep(jitter(BASE_DELAYS_MS[attempt] ?? 2e3));
128
+ continue;
129
+ }
130
+ const bodyText = await res.text();
131
+ return {
132
+ status: res.status,
133
+ bodyText,
134
+ etag: res.headers.get("ETag")
135
+ };
136
+ }
137
+ throw lastNetworkError ?? new Error("fetchWithRetry: exhausted attempts");
138
+ };
139
+
140
+ // src/cli-self-version.ts
141
+ var CLI_PACKAGE_VERSION = "1.1.0";
142
+ var readPackageVersion = () => CLI_PACKAGE_VERSION;
143
+
144
+ // src/version-check.ts
145
+ var SEMVER_RE = /^\d+\.\d+\.\d+$/;
146
+ var parseSemver = (v) => {
147
+ if (!SEMVER_RE.test(v)) return null;
148
+ const [major, minor, patch] = v.split(".").map(Number);
149
+ return [major ?? 0, minor ?? 0, patch ?? 0];
150
+ };
151
+ var compareSemver = (a, b) => {
152
+ const pa = parseSemver(a);
153
+ const pb = parseSemver(b);
154
+ if (!pa || !pb) return 0;
155
+ if (pa[0] !== pb[0]) return pa[0] - pb[0];
156
+ if (pa[1] !== pb[1]) return pa[1] - pb[1];
157
+ return pa[2] - pb[2];
158
+ };
159
+ var maybeWarnAboutOutdatedCli = async (apiUrl) => {
160
+ let bodyText;
161
+ try {
162
+ const res = await fetchWithRetry({
163
+ apiUrl: apiUrl.replace(/\/templates$/, "/cli-version")
164
+ });
165
+ if (res.status !== 200) return;
166
+ bodyText = res.bodyText;
167
+ } catch {
168
+ return;
169
+ }
170
+ let parsed;
171
+ try {
172
+ parsed = JSON.parse(bodyText);
173
+ } catch {
174
+ return;
175
+ }
176
+ if (typeof parsed.version !== "string" || typeof parsed.minSupported !== "string") {
177
+ return;
178
+ }
179
+ const localVersion = readPackageVersion();
180
+ if (compareSemver(localVersion, parsed.minSupported) < 0) {
181
+ process.stderr.write(
182
+ `
183
+ \u26A0 deessejs-cli ${localVersion} is below the minimum supported version (${parsed.minSupported}).
184
+ Upgrade: pnpm dlx @deessejs/cli@latest
185
+
186
+ `
187
+ );
188
+ }
189
+ };
57
190
 
58
191
  // src/api.ts
59
- var fetchTemplates = async (apiUrl) => {
192
+ var TEMPLATES_CACHE_FILE = "templates.json";
193
+ var buildHeaders = (etag) => {
194
+ const headers = {
195
+ "user-agent": USER_AGENT,
196
+ accept: "application/json"
197
+ };
198
+ if (etag) headers["If-None-Match"] = etag;
199
+ return headers;
200
+ };
201
+ var fetchTemplates = async (apiUrl, options = {}) => {
202
+ if (!options.skipVersionCheck) {
203
+ await maybeWarnAboutOutdatedCli(apiUrl);
204
+ }
205
+ const cached = readDiskCache(TEMPLATES_CACHE_FILE);
206
+ if (options.offline) {
207
+ if (!cached) {
208
+ throw networkError(
209
+ "no cached registry available. Run without --offline first to populate the cache."
210
+ );
211
+ }
212
+ return cached.body.templates;
213
+ }
60
214
  let res;
61
215
  try {
62
- res = await fetch(apiUrl, {
63
- headers: { "user-agent": USER_AGENT, accept: "application/json" }
216
+ res = await fetchWithRetry({
217
+ apiUrl,
218
+ headers: buildHeaders(cached?.etag ?? null)
64
219
  });
65
220
  } catch (e) {
221
+ if (cached) {
222
+ process.stderr.write(
223
+ "\u26A0 Using cached registry (offline \u2014 backend unreachable)\n"
224
+ );
225
+ return cached.body.templates;
226
+ }
66
227
  throw networkError(
67
228
  `fetch failed: ${e instanceof Error ? e.message : String(e)}`
68
229
  );
69
230
  }
70
- if (!res.ok) {
71
- throw networkError(
72
- `endpoint returned HTTP ${res.status} ${res.statusText}`
73
- );
231
+ if (res.status === 304 && cached) {
232
+ return cached.body.templates;
233
+ }
234
+ if (res.status < 200 || res.status >= 300) {
235
+ if (cached) {
236
+ process.stderr.write(
237
+ `\u26A0 Using cached registry (offline \u2014 server returned HTTP ${res.status})
238
+ `
239
+ );
240
+ return cached.body.templates;
241
+ }
242
+ throw networkError(`endpoint returned HTTP ${res.status}`);
74
243
  }
75
244
  let body;
76
245
  try {
77
- body = await res.json();
246
+ body = JSON.parse(res.bodyText);
78
247
  } catch (e) {
79
248
  throw parseError(
80
249
  `endpoint returned non-JSON body: ${e instanceof Error ? e.message : String(e)}`
81
250
  );
82
251
  }
83
- if (!isApiResponse(body)) {
84
- throw parseError('response is missing "templates" array');
252
+ const result = TemplatesListResponseV1.safeParse(body);
253
+ if (!result.success) {
254
+ throw parseError(
255
+ `response shape mismatch: ${result.error.issues.map((i) => `${i.path.join(".")} (${i.code})`).join(", ")}`
256
+ );
85
257
  }
86
- return body.templates;
87
- };
88
- var isApiResponse = (value) => {
89
- if (typeof value !== "object" || value === null) return false;
90
- const obj = value;
91
- if (!Array.isArray(obj.templates)) return false;
92
- return obj.templates.every(isTemplate);
93
- };
94
- var isTemplate = (value) => {
95
- if (typeof value !== "object" || value === null) return false;
96
- const obj = value;
97
- return typeof obj.slug === "string" && typeof obj.name === "string" && typeof obj.description === "string" && typeof obj.owner === "string" && typeof obj.repo === "string" && typeof obj.license === "string" && typeof obj.category === "string" && Array.isArray(obj.labels) && obj.labels.every((l) => typeof l === "string") && (obj.cloneUrl === void 0 || typeof obj.cloneUrl === "string");
258
+ writeDiskCache(TEMPLATES_CACHE_FILE, result.data, res.etag);
259
+ return result.data.templates;
98
260
  };
99
261
  var printJson = (value) => {
100
262
  process.stdout.write(JSON.stringify(value, null, 2) + "\n");
@@ -244,9 +406,11 @@ var parsePackageManagerField = (raw) => {
244
406
  var initCommand = new Command("init").description("Clone a template repo + install dependencies").argument("<slug>", "template slug (use `deessejs list` to see options)").option("--pm <name>", "override detected package manager (pnpm|npm|yarn|bun)").option("--dir <path>", "target directory (default: ./<slug>)").option("--ref <branch>", "git ref to clone (default: tries main, falls back to master)").option("--no-install", "skip the install step").option("--force", "overwrite target directory if it exists").option("--json", "JSON output for scripting").action(
245
407
  async (slug, opts) => {
246
408
  const apiUrl = initCommand.parent?.getOptionValue("apiUrl");
409
+ const offline = initCommand.parent?.getOptionValue("offline");
247
410
  try {
248
411
  const templates = await fetchTemplates(
249
- apiUrl ?? process.env.DEESSEJS_API_URL ?? "https://deessejs.com/api/templates"
412
+ apiUrl ?? process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL,
413
+ { offline: Boolean(offline) }
250
414
  );
251
415
  const template = templates.find((t) => t.slug === slug);
252
416
  if (!template) {
@@ -352,10 +516,12 @@ Next: cd ${dir} && <your package manager> install
352
516
  var listCommand = new Command("list").description("List available templates").option("--category <name>", "filter to a single category").option("--json", "JSON output for scripting").action(
353
517
  async (opts, command) => {
354
518
  const apiUrl = command.parent?.getOptionValue("apiUrl");
355
- const spinner = opts.json ? null : ora("Fetching templates...").start();
519
+ const offline = command.parent?.getOptionValue("offline");
520
+ const spinner = opts.json ? null : ora(offline ? "Reading cached templates..." : "Fetching templates...").start();
356
521
  try {
357
522
  const all = await fetchTemplates(
358
- apiUrl ?? process.env.DEESSEJS_API_URL ?? "https://deessejs.com/api/templates"
523
+ apiUrl ?? process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL,
524
+ { offline: Boolean(offline) }
359
525
  );
360
526
  const filtered = opts.category ? all.filter((t) => t.category === opts.category) : all;
361
527
  spinner?.stop();
@@ -395,10 +561,12 @@ var listCommand = new Command("list").description("List available templates").op
395
561
  var infoCommand = new Command("info").description("Show details for one template").argument("<slug>", "template slug").option("--json", "JSON output for scripting").action(
396
562
  async (slug, opts, command) => {
397
563
  const apiUrl = command.parent?.getOptionValue("apiUrl");
398
- const spinner = opts.json ? null : ora("Fetching template...").start();
564
+ const offline = command.parent?.getOptionValue("offline");
565
+ const spinner = opts.json ? null : ora(offline ? "Reading cached template..." : "Fetching template...").start();
399
566
  try {
400
567
  const all = await fetchTemplates(
401
- apiUrl ?? process.env.DEESSEJS_API_URL ?? "https://deessejs.com/api/templates"
568
+ apiUrl ?? process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL,
569
+ { offline: Boolean(offline) }
402
570
  );
403
571
  const template = all.find((t) => t.slug === slug);
404
572
  spinner?.stop();
@@ -436,7 +604,7 @@ var infoCommand = new Command("info").description("Show details for one template
436
604
 
437
605
  // src/index.ts
438
606
  var program = new Command();
439
- program.name("deessejs").description("CLI for the DeesseJS template registry").version("0.1.0").option("--api-url <url>", "templates endpoint URL", process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL);
607
+ program.name("deessejs").description("CLI for the DeesseJS template registry").version("0.1.0").option("--api-url <url>", "templates endpoint URL", process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL).option("--offline", "skip the network, serve the on-disk cache (~/.deessejs/templates.json)");
440
608
  program.addCommand(listCommand);
441
609
  program.addCommand(infoCommand);
442
610
  program.addCommand(initCommand);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/api.ts","../src/output.ts","../src/utils/spawn.ts","../src/utils/git.ts","../src/utils/detect-pm.ts","../src/commands/init.ts","../src/commands/list.ts","../src/commands/info.ts","../src/index.ts"],"names":["pc","resolve","nodeSpawn","existsSync","Command","ora"],"mappings":"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","file":"index.js","sourcesContent":["export const DEFAULT_API_URL = \"https://app.deessejs.com/api/templates\"\r\n\r\nexport const USER_AGENT = \"deessejs-cli/0.1.0 (https://deessejs.com)\"\r\n\r\nexport const EXIT_SUCCESS = 0\r\nexport const EXIT_ERROR = 1","import { EXIT_ERROR } from \"./constants.js\"\r\n\r\nexport type CliErrorCode =\r\n | \"not_found\"\r\n | \"network_error\"\r\n | \"git_not_installed\"\r\n | \"target_exists\"\r\n | \"install_failed\"\r\n | \"parse_error\"\r\n | \"internal\"\r\n\r\nexport class CliError extends Error {\r\n public readonly code: CliErrorCode\r\n public readonly hint: string | undefined\r\n\r\n constructor(code: CliErrorCode, message: string, hint?: string) {\r\n super(message)\r\n this.name = \"CliError\"\r\n this.code = code\r\n this.hint = hint\r\n }\r\n\r\n public exitCode = (): number => EXIT_ERROR\r\n}\r\n\r\nexport const notFound = (slug: string, available: string[]): CliError =>\r\n new CliError(\r\n \"not_found\",\r\n `template \"${slug}\" not found`,\r\n `available templates: ${available.join(\", \")}`,\r\n )\r\n\r\nexport const networkError = (detail: string): CliError =>\r\n new CliError(\r\n \"network_error\",\r\n `could not reach the templates endpoint`,\r\n detail,\r\n )\r\n\r\nexport const gitNotInstalled = (): CliError =>\r\n new CliError(\r\n \"git_not_installed\",\r\n \"`git` is not installed or not on PATH\",\r\n \"install git from https://git-scm.com and try again\",\r\n )\r\n\r\nexport const targetExists = (dir: string): CliError =>\r\n new CliError(\r\n \"target_exists\",\r\n `target directory \"${dir}\" already exists`,\r\n \"remove the directory or pass --force to overwrite\",\r\n )\r\n\r\nexport const installFailed = (\r\n pm: string,\r\n code: number | null,\r\n): CliError =>\r\n new CliError(\r\n \"install_failed\",\r\n `${pm} install exited with code ${code ?? \"unknown\"}`,\r\n \"check the output above, then run the install command manually inside the cloned directory\",\r\n )\r\n\r\nexport const parseError = (detail: string): CliError =>\r\n new CliError(\r\n \"parse_error\",\r\n \"templates endpoint returned malformed data\",\r\n detail,\r\n )\r\n\r\nexport const internal = (detail: string): CliError =>\r\n new CliError(\"internal\", \"unexpected internal error\", detail)","import { USER_AGENT } from \"./constants.js\"\r\nimport { networkError, parseError } from \"./errors.js\"\r\n\r\nexport type Template = {\r\n slug: string\r\n name: string\r\n description: string\r\n owner: string\r\n repo: string\r\n license: string\r\n category: string\r\n labels: string[]\r\n image?: string\r\n /** Optional override for the clone URL. Falls back to `https://github.com/<owner>/<repo>`. */\r\n cloneUrl?: string\r\n}\r\n\r\nexport type ApiResponse = { templates: Template[] }\r\n\r\nexport const fetchTemplates = async (\r\n apiUrl: string,\r\n): Promise<Template[]> => {\r\n let res: Response\r\n try {\r\n res = await fetch(apiUrl, {\r\n headers: { \"user-agent\": USER_AGENT, accept: \"application/json\" },\r\n })\r\n } catch (e) {\r\n throw networkError(\r\n `fetch failed: ${e instanceof Error ? e.message : String(e)}`,\r\n )\r\n }\r\n\r\n if (!res.ok) {\r\n throw networkError(\r\n `endpoint returned HTTP ${res.status} ${res.statusText}`,\r\n )\r\n }\r\n\r\n let body: unknown\r\n try {\r\n body = await res.json()\r\n } catch (e) {\r\n throw parseError(\r\n `endpoint returned non-JSON body: ${e instanceof Error ? e.message : String(e)}`,\r\n )\r\n }\r\n\r\n if (!isApiResponse(body)) {\r\n throw parseError('response is missing \"templates\" array')\r\n }\r\n\r\n return body.templates\r\n}\r\n\r\nconst isApiResponse = (value: unknown): value is ApiResponse => {\r\n if (typeof value !== \"object\" || value === null) return false\r\n const obj = value as Record<string, unknown>\r\n if (!Array.isArray(obj.templates)) return false\r\n return obj.templates.every(isTemplate)\r\n}\r\n\r\nconst isTemplate = (value: unknown): value is Template => {\r\n if (typeof value !== \"object\" || value === null) return false\r\n const obj = value as Record<string, unknown>\r\n return (\r\n typeof obj.slug === \"string\" &&\r\n typeof obj.name === \"string\" &&\r\n typeof obj.description === \"string\" &&\r\n typeof obj.owner === \"string\" &&\r\n typeof obj.repo === \"string\" &&\r\n typeof obj.license === \"string\" &&\r\n typeof obj.category === \"string\" &&\r\n Array.isArray(obj.labels) &&\r\n obj.labels.every((l) => typeof l === \"string\") &&\r\n (obj.cloneUrl === undefined || typeof obj.cloneUrl === \"string\")\r\n )\r\n}","import pc from \"picocolors\"\r\nimport type { CliError } from \"./errors.js\"\r\nimport type { Template } from \"./api.js\"\r\n\r\nexport const printJson = (value: unknown): void => {\r\n process.stdout.write(JSON.stringify(value, null, 2) + \"\\n\")\r\n}\r\n\r\nexport const printError = (err: CliError): void => {\r\n process.stderr.write(\r\n `${pc.red(\"Error\")}: ${err.message}\\n` +\r\n (err.hint ? `${pc.dim(\"Hint\")}: ${err.hint}\\n` : \"\") +\r\n `${pc.dim(\"Code\")}: ${err.code}\\n`,\r\n )\r\n}\r\n\r\nexport const printTemplatesTable = (templates: Template[]): void => {\r\n if (templates.length === 0) {\r\n process.stdout.write(pc.dim(\"No templates available.\\n\"))\r\n return\r\n }\r\n const headers = [\"slug\", \"name\", \"category\", \"license\"]\r\n const rows = templates.map((t) => [\r\n t.slug,\r\n t.name,\r\n t.category,\r\n t.license,\r\n ])\r\n printAlignedTable([headers, ...rows])\r\n}\r\n\r\nexport const printTemplateInfo = (t: Template): void => {\r\n const lines: Array<[string, string]> = [\r\n [\"slug\", t.slug],\r\n [\"name\", t.name],\r\n [\"description\", t.description],\r\n [\"category\", t.category],\r\n [\"license\", t.license],\r\n [\"repo\", `${t.owner}/${t.repo}`],\r\n [\"labels\", t.labels.join(\", \") || pc.dim(\"(none)\")],\r\n ]\r\n if (t.image) lines.push([\"image\", t.image])\r\n\r\n const labelWidth = Math.max(...lines.map(([l]) => l.length))\r\n for (const [label, value] of lines) {\r\n process.stdout.write(\r\n `${pc.dim(label.padEnd(labelWidth))} ${value}\\n`,\r\n )\r\n }\r\n}\r\n\r\nconst printAlignedTable = (rows: string[][]): void => {\r\n const firstRow = rows[0]\r\n if (!firstRow) return\r\n const widths = firstRow.map((_, col) =>\r\n Math.max(...rows.map((row) => row[col]?.length ?? 0)),\r\n )\r\n for (const row of rows) {\r\n process.stdout.write(\r\n row.map((cell, i) => cell.padEnd(widths[i] ?? 0)).join(\" \") + \"\\n\",\r\n )\r\n }\r\n}","import { spawn as nodeSpawn } from \"node:child_process\"\r\n\r\nexport type SpawnOptions = {\r\n cwd?: string\r\n env?: NodeJS.ProcessEnv\r\n stdio?: \"inherit\" | \"pipe\" | \"ignore\"\r\n /** If true, do not throw on non-zero exit codes. Default is `true` (no throw). */\r\n reject?: boolean\r\n}\r\n\r\n/**\r\n * Run a command and resolve with its exit code. Never throws on non-zero by\r\n * default; pass `reject: true` to opt into throwing.\r\n */\r\nexport const spawn = (\r\n command: string,\r\n args: string[],\r\n options: SpawnOptions = {},\r\n): Promise<number> => {\r\n const { cwd, env, stdio = \"inherit\", reject = false } = options\r\n return new Promise((resolve, rejectFn) => {\r\n const child = nodeSpawn(command, args, {\r\n cwd,\r\n env: env ?? process.env,\r\n stdio,\r\n shell: false,\r\n })\r\n child.on(\"error\", (err) => rejectFn(err))\r\n child.on(\"exit\", (code) => {\r\n const exit = code ?? 1\r\n if (reject && exit !== 0) {\r\n rejectFn(new Error(`${command} exited with code ${exit}`))\r\n } else {\r\n resolve(exit)\r\n }\r\n })\r\n })\r\n}","import { spawn } from \"./spawn.js\"\r\nimport { gitNotInstalled } from \"../errors.js\"\r\n\r\nexport type CloneResult = {\r\n ref: string\r\n attempts: string[]\r\n}\r\n\r\n/**\r\n * Clone a git repo to `dir`. Tries `main` first, then falls back to `master`.\r\n * Caller can pass an explicit `--ref` to override.\r\n */\r\nexport const cloneRepo = async (\r\n url: string,\r\n dir: string,\r\n requestedRef?: string,\r\n): Promise<CloneResult> => {\r\n const refs = requestedRef ? [requestedRef] : [\"main\", \"master\"]\r\n const attempts: string[] = []\r\n\r\n for (const ref of refs) {\r\n attempts.push(ref)\r\n const code = await spawn(\r\n \"git\",\r\n [\"clone\", \"--depth\", \"1\", \"--branch\", ref, url, dir],\r\n { stdio: \"inherit\", reject: false },\r\n )\r\n if (code === 0) {\r\n return { ref, attempts }\r\n }\r\n }\r\n\r\n // All attempts failed. Probe whether git is even installed.\r\n const probe = await spawn(\"git\", [\"--version\"], {\r\n stdio: \"ignore\",\r\n reject: false,\r\n })\r\n if (probe !== 0) {\r\n throw gitNotInstalled()\r\n }\r\n\r\n // Git works but neither ref matched. Re-throw with attempts context.\r\n throw new Error(\r\n `git clone failed for refs: ${refs.join(\", \")}. Tried: ${attempts.join(\", \")}.`,\r\n )\r\n}","import { existsSync, readFileSync } from \"node:fs\"\r\nimport { join } from \"node:path\"\r\n\r\nexport type PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\"\r\n\r\nexport type PackageManagerInfo = {\r\n pm: PackageManager\r\n /** Raw value from packageManager field, e.g. \"pnpm@9.0.0\". May include version. */\r\n raw?: string\r\n}\r\n\r\n/**\r\n * Detect the package manager for a directory, in priority order:\r\n * 1. `packageManager` field in package.json (Corepack convention)\r\n * 2. Lockfile presence\r\n * 3. Returns null if nothing matches (caller decides whether to fail)\r\n */\r\nexport const detectPackageManager = (\r\n cwd: string,\r\n): PackageManagerInfo | null => {\r\n const pkg = readPackageJson(cwd)\r\n if (pkg?.packageManager) {\r\n const pm = parsePackageManagerField(pkg.packageManager)\r\n if (pm) return pm\r\n }\r\n\r\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return { pm: \"pnpm\" }\r\n if (existsSync(join(cwd, \"bun.lockb\"))) return { pm: \"bun\" }\r\n if (existsSync(join(cwd, \"yarn.lock\"))) return { pm: \"yarn\" }\r\n if (existsSync(join(cwd, \"package-lock.json\"))) return { pm: \"npm\" }\r\n\r\n return null\r\n}\r\n\r\nexport const getInstallCommand = (info: PackageManagerInfo): string => {\r\n switch (info.pm) {\r\n case \"pnpm\":\r\n return \"pnpm install\"\r\n case \"npm\":\r\n return \"npm install\"\r\n case \"yarn\":\r\n return \"yarn install\"\r\n case \"bun\":\r\n return \"bun install\"\r\n }\r\n}\r\n\r\nconst readPackageJson = (\r\n cwd: string,\r\n): { packageManager?: string } | null => {\r\n const path = join(cwd, \"package.json\")\r\n if (!existsSync(path)) return null\r\n try {\r\n return JSON.parse(readFileSync(path, \"utf8\")) as {\r\n packageManager?: string\r\n }\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport const parsePackageManagerField = (\r\n raw: string,\r\n): PackageManagerInfo | null => {\r\n // Format: \"<name>@<version>\" or just \"<name>\". Common names: pnpm, npm, yarn, bun.\r\n const name = raw.split(\"@\")[0]?.trim().toLowerCase()\r\n if (name === \"pnpm\" || name === \"npm\" || name === \"yarn\" || name === \"bun\") {\r\n return { pm: name, raw }\r\n }\r\n return null\r\n}","import { existsSync } from \"node:fs\"\r\nimport { resolve } from \"node:path\"\r\nimport { Command } from \"commander\"\r\nimport ora from \"ora\"\r\nimport pc from \"picocolors\"\r\nimport { fetchTemplates } from \"../api.js\"\r\nimport {\r\n installFailed,\r\n internal,\r\n notFound,\r\n targetExists,\r\n} from \"../errors.js\"\r\nimport { printError, printJson } from \"../output.js\"\r\nimport { cloneRepo } from \"../utils/git.js\"\r\nimport {\r\n detectPackageManager,\r\n getInstallCommand,\r\n type PackageManagerInfo,\r\n} from \"../utils/detect-pm.js\"\r\nimport { spawn } from \"../utils/spawn.js\"\r\n\r\nexport const initCommand = new Command(\"init\")\r\n .description(\"Clone a template repo + install dependencies\")\r\n .argument(\"<slug>\", \"template slug (use `deessejs list` to see options)\")\r\n .option(\"--pm <name>\", \"override detected package manager (pnpm|npm|yarn|bun)\")\r\n .option(\"--dir <path>\", \"target directory (default: ./<slug>)\")\r\n .option(\"--ref <branch>\", \"git ref to clone (default: tries main, falls back to master)\")\r\n .option(\"--no-install\", \"skip the install step\")\r\n .option(\"--force\", \"overwrite target directory if it exists\")\r\n .option(\"--json\", \"JSON output for scripting\")\r\n .action(\r\n async (\r\n slug: string,\r\n opts: {\r\n pm?: string\r\n dir?: string\r\n ref?: string\r\n install: boolean\r\n force?: boolean\r\n json?: boolean\r\n },\r\n ) => {\r\n const apiUrl = initCommand.parent?.getOptionValue(\"apiUrl\") as\r\n | string\r\n | undefined\r\n\r\n try {\r\n const templates = await fetchTemplates(\r\n apiUrl ?? process.env.DEESSEJS_API_URL ?? \"https://deessejs.com/api/templates\",\r\n )\r\n const template = templates.find((t) => t.slug === slug)\r\n if (!template) {\r\n throw notFound(\r\n slug,\r\n templates.map((t) => t.slug),\r\n )\r\n }\r\n\r\n const dir = resolve(process.cwd(), opts.dir ?? `./${slug}`)\r\n if (existsSync(dir) && !opts.force) {\r\n throw targetExists(dir)\r\n }\r\n\r\n const repoUrl =\r\n template.cloneUrl ?? `https://github.com/${template.owner}/${template.repo}`\r\n\r\n const cloneSpinner = ora(`Cloning ${pc.cyan(template.owner + \"/\" + template.repo)}...`).start()\r\n let cloneResult\r\n try {\r\n cloneResult = await cloneRepo(repoUrl, dir, opts.ref)\r\n cloneSpinner.succeed(`Cloned into ${pc.cyan(dir)} (ref: ${cloneResult.ref})`)\r\n } catch (err) {\r\n cloneSpinner.fail(\"Clone failed\")\r\n throw err\r\n }\r\n\r\n if (!opts.install) {\r\n if (opts.json) {\r\n printJson({\r\n ok: true,\r\n slug: template.slug,\r\n dir,\r\n ref: cloneResult.ref,\r\n installed: false,\r\n })\r\n } else {\r\n console.log(pc.dim(`\\nNext: cd ${dir} && <your package manager> install\\n`))\r\n }\r\n return\r\n }\r\n\r\n const VALID_PMS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const\r\n type ValidPm = (typeof VALID_PMS)[number]\r\n const pmInfo: PackageManagerInfo | null =\r\n opts.pm && (VALID_PMS as readonly string[]).includes(opts.pm)\r\n ? { pm: opts.pm as ValidPm }\r\n : detectPackageManager(dir)\r\n\r\n if (!pmInfo) {\r\n console.log(\r\n pc.yellow(\r\n \"\\nNo package manager detected (no packageManager field, no lockfile).\",\r\n ),\r\n )\r\n console.log(\r\n pc.dim(\"Skipping install. Run your install command manually inside the directory.\\n\"),\r\n )\r\n } else {\r\n const installSpinner = ora(\r\n `Installing dependencies via ${pc.cyan(pmInfo.pm)}...`,\r\n ).start()\r\n const cmd = getInstallCommand(pmInfo)\r\n const cmdParts = cmd.split(\" \")\r\n const bin = cmdParts[0] ?? \"npm\"\r\n const args = cmdParts.slice(1)\r\n const code = await spawn(bin, args, { cwd: dir, stdio: \"inherit\", reject: false })\r\n if (code !== 0) {\r\n installSpinner.fail(`${pmInfo.pm} install failed`)\r\n throw installFailed(pmInfo.pm, code)\r\n }\r\n installSpinner.succeed(\"Dependencies installed\")\r\n }\r\n\r\n if (opts.json) {\r\n printJson({\r\n ok: true,\r\n slug: template.slug,\r\n dir,\r\n ref: cloneResult.ref,\r\n installed: pmInfo !== null,\r\n packageManager: pmInfo?.pm ?? null,\r\n })\r\n } else {\r\n console.log()\r\n console.log(pc.green(\"✓ Template ready\"))\r\n console.log(pc.dim(` cd ${dir}`))\r\n console.log(\r\n pc.dim(\r\n pmInfo\r\n ? ` ${getInstallCommand(pmInfo).split(\" \")[0]} dev`\r\n : ` install deps, then start`,\r\n ),\r\n )\r\n console.log()\r\n }\r\n } catch (err) {\r\n if (err instanceof Error && err.name === \"CliError\") {\r\n if (opts.json) {\r\n printJson({\r\n ok: false,\r\n code: (err as { code?: string }).code,\r\n message: err.message,\r\n hint: (err as { hint?: string }).hint,\r\n })\r\n } else {\r\n printError(err as Parameters<typeof printError>[0])\r\n }\r\n process.exit((err as { exitCode?: () => number }).exitCode?.() ?? 1)\r\n }\r\n throw internal(err instanceof Error ? err.message : String(err))\r\n }\r\n },\r\n )","import { Command } from \"commander\"\r\nimport ora from \"ora\"\r\nimport pc from \"picocolors\"\r\nimport { fetchTemplates } from \"../api.js\"\r\nimport { internal } from \"../errors.js\"\r\nimport { printError, printJson, printTemplatesTable } from \"../output.js\"\r\n\r\nexport const listCommand = new Command(\"list\")\r\n .description(\"List available templates\")\r\n .option(\"--category <name>\", \"filter to a single category\")\r\n .option(\"--json\", \"JSON output for scripting\")\r\n .action(\r\n async (\r\n opts: { category?: string; json?: boolean },\r\n command: Command,\r\n ) => {\r\n const apiUrl = command.parent?.getOptionValue(\"apiUrl\") as\r\n | string\r\n | undefined\r\n\r\n const spinner = opts.json\r\n ? null\r\n : ora(\"Fetching templates...\").start()\r\n\r\n try {\r\n const all = await fetchTemplates(\r\n apiUrl ?? process.env.DEESSEJS_API_URL ?? \"https://deessejs.com/api/templates\",\r\n )\r\n const filtered = opts.category\r\n ? all.filter((t) => t.category === opts.category)\r\n : all\r\n\r\n spinner?.stop()\r\n\r\n if (opts.json) {\r\n printJson({ templates: filtered })\r\n } else {\r\n if (opts.category) {\r\n console.log(pc.dim(`Category: ${opts.category}`))\r\n }\r\n printTemplatesTable(filtered)\r\n console.log()\r\n console.log(\r\n pc.dim(\r\n `${filtered.length} template${filtered.length === 1 ? \"\" : \"s\"}.` +\r\n (opts.category\r\n ? \"\"\r\n : \" Use --category <name> to filter, --json for scripting.\"),\r\n ),\r\n )\r\n }\r\n } catch (err) {\r\n spinner?.fail(\"Failed to fetch templates\")\r\n if (err instanceof Error && err.name === \"CliError\") {\r\n if (opts.json) {\r\n printJson({\r\n ok: false,\r\n code: (err as { code?: string }).code,\r\n message: err.message,\r\n hint: (err as { hint?: string }).hint,\r\n })\r\n } else {\r\n printError(err as Parameters<typeof printError>[0])\r\n }\r\n process.exit(1)\r\n }\r\n throw internal(err instanceof Error ? err.message : String(err))\r\n }\r\n },\r\n )","import { Command } from \"commander\"\r\nimport ora from \"ora\"\r\nimport { fetchTemplates } from \"../api.js\"\r\nimport { internal, notFound } from \"../errors.js\"\r\nimport { printError, printJson, printTemplateInfo } from \"../output.js\"\r\n\r\nexport const infoCommand = new Command(\"info\")\r\n .description(\"Show details for one template\")\r\n .argument(\"<slug>\", \"template slug\")\r\n .option(\"--json\", \"JSON output for scripting\")\r\n .action(\r\n async (slug: string, opts: { json?: boolean }, command: Command) => {\r\n const apiUrl = command.parent?.getOptionValue(\"apiUrl\") as\r\n | string\r\n | undefined\r\n\r\n const spinner = opts.json ? null : ora(\"Fetching template...\").start()\r\n\r\n try {\r\n const all = await fetchTemplates(\r\n apiUrl ?? process.env.DEESSEJS_API_URL ?? \"https://deessejs.com/api/templates\",\r\n )\r\n const template = all.find((t) => t.slug === slug)\r\n spinner?.stop()\r\n\r\n if (!template) {\r\n throw notFound(slug, all.map((t) => t.slug))\r\n }\r\n\r\n if (opts.json) {\r\n printJson({ template })\r\n } else {\r\n printTemplateInfo(template)\r\n console.log()\r\n console.log(\r\n `Install: ${`deessejs init ${template.slug}`}`,\r\n )\r\n }\r\n } catch (err) {\r\n spinner?.fail(\"Failed to fetch template\")\r\n if (err instanceof Error && err.name === \"CliError\") {\r\n if (opts.json) {\r\n printJson({\r\n ok: false,\r\n code: (err as { code?: string }).code,\r\n message: err.message,\r\n hint: (err as { hint?: string }).hint,\r\n })\r\n } else {\r\n printError(err as Parameters<typeof printError>[0])\r\n }\r\n process.exit(1)\r\n }\r\n throw internal(err instanceof Error ? err.message : String(err))\r\n }\r\n },\r\n )","import { Command } from \"commander\"\r\nimport pc from \"picocolors\"\r\nimport { DEFAULT_API_URL, USER_AGENT } from \"./constants.js\"\r\nimport { initCommand } from \"./commands/init.js\"\r\nimport { listCommand } from \"./commands/list.js\"\r\nimport { infoCommand } from \"./commands/info.js\"\r\n\r\nconst program = new Command()\r\n\r\nprogram\r\n .name(\"deessejs\")\r\n .description(\"CLI for the DeesseJS template registry\")\r\n .version(\"0.1.0\")\r\n .option(\"--api-url <url>\", \"templates endpoint URL\", process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL)\r\n\r\nprogram.addCommand(listCommand)\r\nprogram.addCommand(infoCommand)\r\nprogram.addCommand(initCommand)\r\n\r\nprogram.parseAsync(process.argv).catch((err) => {\r\n // Last-resort error handler. Per-command handlers catch CliError and exit\r\n // cleanly with the right code. Anything that lands here is an uncaught bug.\r\n process.stderr.write(\r\n `${pc.red(\"Internal error\")}: ${err instanceof Error ? err.message : String(err)}\\n`,\r\n )\r\n if (process.env.DEESSEJS_DEBUG) {\r\n process.stderr.write(`\\n${err instanceof Error && err.stack ? err.stack : \"\"}\\n`)\r\n }\r\n process.exit(1)\r\n})\r\n\r\nvoid USER_AGENT // re-exported for downstream consumers if needed"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/cache.ts","../src/fetch-with-retry.ts","../src/cli-self-version.ts","../src/version-check.ts","../src/api.ts","../src/output.ts","../src/utils/spawn.ts","../src/utils/git.ts","../src/utils/detect-pm.ts","../src/commands/init.ts","../src/commands/list.ts","../src/commands/info.ts","../src/index.ts"],"names":["resolve","pc","nodeSpawn","existsSync","join","readFileSync","Command","ora"],"mappings":"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","file":"index.js","sourcesContent":["export const DEFAULT_API_URL = \"https://app.deessejs.com/api/v1/templates\"\n\nexport const USER_AGENT = \"deessejs-cli/0.1.0 (https://deessejs.com)\"\n\nexport const EXIT_SUCCESS = 0\nexport const EXIT_ERROR = 1\n","import { EXIT_ERROR } from \"./constants.js\"\n\nexport type CliErrorCode =\n | \"not_found\"\n | \"network_error\"\n | \"git_not_installed\"\n | \"target_exists\"\n | \"install_failed\"\n | \"parse_error\"\n | \"internal\"\n\nexport class CliError extends Error {\n public readonly code: CliErrorCode\n public readonly hint: string | undefined\n\n constructor(code: CliErrorCode, message: string, hint?: string) {\n super(message)\n this.name = \"CliError\"\n this.code = code\n this.hint = hint\n }\n\n public exitCode = (): number => EXIT_ERROR\n}\n\nexport const notFound = (slug: string, available: string[]): CliError =>\n new CliError(\n \"not_found\",\n `template \"${slug}\" not found`,\n `available templates: ${available.join(\", \")}`,\n )\n\nexport const networkError = (detail: string): CliError =>\n new CliError(\n \"network_error\",\n `could not reach the templates endpoint`,\n detail,\n )\n\nexport const gitNotInstalled = (): CliError =>\n new CliError(\n \"git_not_installed\",\n \"`git` is not installed or not on PATH\",\n \"install git from https://git-scm.com and try again\",\n )\n\nexport const targetExists = (dir: string): CliError =>\n new CliError(\n \"target_exists\",\n `target directory \"${dir}\" already exists`,\n \"remove the directory or pass --force to overwrite\",\n )\n\nexport const installFailed = (\n pm: string,\n code: number | null,\n): CliError =>\n new CliError(\n \"install_failed\",\n `${pm} install exited with code ${code ?? \"unknown\"}`,\n \"check the output above, then run the install command manually inside the cloned directory\",\n )\n\nexport const parseError = (detail: string): CliError =>\n new CliError(\n \"parse_error\",\n \"templates endpoint returned malformed data\",\n detail,\n )\n\nexport const internal = (detail: string): CliError =>\n new CliError(\"internal\", \"unexpected internal error\", detail)","import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport { join } from \"node:path\"\n\n/**\n * On-disk response cache for the CLI.\n *\n * Layout: one file per endpoint under ~/.deessejs/. Each file holds the\n * raw response body plus the ETag the server returned, so we can reissue\n * If-None-Match on the next call and serve the cached body on a 304.\n *\n * No TTL: the server is the source of truth for freshness. A cache entry\n * is \"valid\" if either (a) we can revalidate it against the server and\n * the server says 304, or (b) we're in --offline mode and any prior\n * response is better than nothing.\n *\n * Corruption policy: a malformed file is treated as cache-miss. We do\n * not auto-overwrite it — if the user manually edited a cache file, we\n * surface that as a warning and let them decide. The next successful\n * network call will overwrite the file normally.\n */\nexport type CacheEntry<T = unknown> = {\n etag: string | null\n fetchedAt: string\n body: T\n}\n\nexport const CACHE_DIR = join(homedir(), \".deessejs\")\n\nconst ensureDir = (): void => {\n if (!existsSync(CACHE_DIR)) {\n mkdirSync(CACHE_DIR, { recursive: true })\n }\n}\n\nconst cachePath = (name: string): string => join(CACHE_DIR, name)\n\nexport const readDiskCache = <T>(name: string): CacheEntry<T> | null => {\n const path = cachePath(name)\n if (!existsSync(path)) return null\n try {\n const raw = readFileSync(path, \"utf8\")\n return JSON.parse(raw) as CacheEntry<T>\n } catch {\n // Corrupt or unreadable. Caller logs a warning; we don't overwrite.\n return null\n }\n}\n\nexport const writeDiskCache = <T>(\n name: string,\n body: T,\n etag: string | null,\n): void => {\n ensureDir()\n const entry: CacheEntry<T> = {\n etag,\n fetchedAt: new Date().toISOString(),\n body,\n }\n // Write atomically via a temp file + rename to avoid torn writes\n // if the process is killed mid-write. tmp + rename is atomic on\n // POSIX; on Windows it's \"atomic if the destination exists\", which\n // is good enough for our use case.\n const target = cachePath(name)\n const tmp = `${target}.tmp`\n writeFileSync(tmp, JSON.stringify(entry), \"utf8\")\n // Best-effort rename. If it fails (rare on Windows), fall back to direct write.\n try {\n renameSync(tmp, target)\n } catch {\n writeFileSync(target, JSON.stringify(entry), \"utf8\")\n }\n}\n","import { USER_AGENT } from \"./constants.js\"\n\nexport type FetchRetryOptions = {\n apiUrl: string\n headers?: Record<string, string>\n /** Maximum number of attempts. Default 3. */\n maxAttempts?: number\n}\n\nexport type FetchRetryResult = {\n status: number\n bodyText: string\n etag: string | null\n}\n\nconst BASE_DELAYS_MS = [250, 750, 2000]\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms))\n\nconst jitter = (base: number): number =>\n base + Math.floor(Math.random() * 100)\n\n/**\n * Fetch with retry on transient failures.\n *\n * Retries on:\n * - network errors (the `fetch` itself throws)\n * - HTTP 5xx\n * - HTTP 429 (rate-limited): honors the X-RateLimit-Reset header\n * instead of the static backoff, so we don't sleep longer than needed.\n *\n * Aborts (returns the failing response) on:\n * - HTTP 4xx other than 429. A 404 on /templates will still be a 404\n * in 3 seconds; the user gets a faster error.\n *\n * Returns the final response (success or terminal failure) and a\n * `bodyText` ready to JSON.parse. The caller is responsible for parsing\n * — we don't presume the schema here.\n */\nexport const fetchWithRetry = async (\n opts: FetchRetryOptions,\n): Promise<FetchRetryResult> => {\n const maxAttempts = opts.maxAttempts ?? 3\n const headers: Record<string, string> = {\n \"user-agent\": USER_AGENT,\n accept: \"application/json\",\n ...(opts.headers ?? {}),\n }\n\n let lastNetworkError: unknown\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n let res: Response\n try {\n res = await fetch(opts.apiUrl, { headers })\n } catch (e) {\n lastNetworkError = e\n if (attempt < maxAttempts - 1) {\n await sleep(jitter(BASE_DELAYS_MS[attempt] ?? 2000))\n continue\n }\n throw e\n }\n\n if (res.status === 429) {\n // Honor X-RateLimit-Reset if the server provides it. Header is in\n // seconds; we read the first value if it's a comma list.\n const resetHeader = res.headers.get(\"X-RateLimit-Reset\")\n const resetSec = resetHeader ? Number(resetHeader.split(\",\")[0]) : NaN\n const waitMs = Number.isFinite(resetSec) && resetSec > 0\n ? Math.min(resetSec * 1000, 30_000) // cap at 30s\n : jitter(BASE_DELAYS_MS[attempt] ?? 2000)\n if (attempt < maxAttempts - 1) {\n await sleep(waitMs)\n continue\n }\n }\n\n if (res.status >= 500 && attempt < maxAttempts - 1) {\n await sleep(jitter(BASE_DELAYS_MS[attempt] ?? 2000))\n continue\n }\n\n const bodyText = await res.text()\n return {\n status: res.status,\n bodyText,\n etag: res.headers.get(\"ETag\"),\n }\n }\n\n // Unreachable in practice (the loop always either returns or throws).\n throw lastNetworkError ?? new Error(\"fetchWithRetry: exhausted attempts\")\n}\n","/**\n * The CLI's own version, read from the package metadata at build time.\n *\n * The CLI is bundled by tsup into a single `dist/index.js`, so a\n * runtime `import.meta.url` resolution back to package.json is\n * fragile (paths differ between `npx`, global install, and direct\n * invocation). We bake the version into the bundle as a constant.\n *\n * Update this when bumping apps/cli/package.json.\n */\nexport const CLI_PACKAGE_VERSION = \"1.1.0\"\n\nexport const readPackageVersion = (): string => CLI_PACKAGE_VERSION\n","import { readPackageVersion } from \"./cli-self-version.js\"\nimport { fetchWithRetry } from \"./fetch-with-retry.js\"\n\nexport type CliVersionResponse = {\n version: string\n minSupported: string\n}\n\nconst SEMVER_RE = /^\\d+\\.\\d+\\.\\d+$/\n\nconst parseSemver = (v: string): [number, number, number] | null => {\n if (!SEMVER_RE.test(v)) return null\n const [major, minor, patch] = v.split(\".\").map(Number)\n return [major ?? 0, minor ?? 0, patch ?? 0]\n}\n\nconst compareSemver = (a: string, b: string): number => {\n const pa = parseSemver(a)\n const pb = parseSemver(b)\n if (!pa || !pb) return 0 // unknown: don't warn\n if (pa[0] !== pb[0]) return pa[0] - pb[0]\n if (pa[1] !== pb[1]) return pa[1] - pb[1]\n return pa[2] - pb[2]\n}\n\n/**\n * Non-blocking version probe.\n *\n * Calls /api/v1/cli-version. If the local CLI version is strictly\n * below minSupported, prints a warning to stderr. The caller does NOT\n * abort — the user might have a workflow that depends on the old\n * version. The warning is loud (yellow, separate line) but not\n * authoritative.\n *\n * Failures (network, parse, server error) are swallowed silently: the\n * version check is best-effort, never the reason a command fails.\n */\nexport const maybeWarnAboutOutdatedCli = async (apiUrl: string): Promise<void> => {\n let bodyText: string\n try {\n const res = await fetchWithRetry({\n apiUrl: apiUrl.replace(/\\/templates$/, \"/cli-version\"),\n })\n if (res.status !== 200) return\n bodyText = res.bodyText\n } catch {\n return\n }\n\n let parsed: CliVersionResponse\n try {\n parsed = JSON.parse(bodyText) as CliVersionResponse\n } catch {\n return\n }\n if (\n typeof parsed.version !== \"string\" ||\n typeof parsed.minSupported !== \"string\"\n ) {\n return\n }\n\n const localVersion = readPackageVersion()\n if (compareSemver(localVersion, parsed.minSupported) < 0) {\n process.stderr.write(\n `\\n⚠ deessejs-cli ${localVersion} is below the minimum supported version (${parsed.minSupported}).\\n` +\n ` Upgrade: pnpm dlx @deessejs/cli@latest\\n\\n`,\n )\n }\n}\n","import { TemplatesListResponseV1 } from \"@workspace/contracts/v1\"\nimport { USER_AGENT } from \"./constants.js\"\nimport { networkError, parseError } from \"./errors.js\"\nimport { readDiskCache, writeDiskCache } from \"./cache.js\"\nimport { fetchWithRetry } from \"./fetch-with-retry.js\"\nimport { maybeWarnAboutOutdatedCli } from \"./version-check.js\"\n\nexport type Template = TemplatesListResponseV1[\"templates\"][number]\n\nexport type FetchOptions = {\n /** Skip network entirely, serve cache only. Errors if no cache exists. */\n offline?: boolean\n /** Skip the version probe. Used by tests and by the version probe itself. */\n skipVersionCheck?: boolean\n}\n\nconst TEMPLATES_CACHE_FILE = \"templates.json\"\n\nconst buildHeaders = (etag: string | null): Record<string, string> => {\n const headers: Record<string, string> = {\n \"user-agent\": USER_AGENT,\n accept: \"application/json\",\n }\n if (etag) headers[\"If-None-Match\"] = etag\n return headers\n}\n\n/**\n * Fetch the templates registry, with disk cache + retry + offline support.\n *\n * Flow:\n * 1. (If not skipVersionCheck) probe /cli-version and warn if outdated.\n * Failure here is silent — version check is best-effort.\n * 2. If --offline, return the cached body or fail with network_error.\n * 3. Network fetch with retry (250ms / 750ms / 2s backoff, honors 429\n * X-RateLimit-Reset). ETag is sent on every call when we have a cache.\n * 4. On 304, return the cached body.\n * 5. On 200, parse, write cache, return.\n * 6. On terminal failure, fall back to cache if we have one and the\n * body is still parsable. Otherwise surface the network_error.\n */\nexport const fetchTemplates = async (\n apiUrl: string,\n options: FetchOptions = {},\n): Promise<Template[]> => {\n if (!options.skipVersionCheck) {\n await maybeWarnAboutOutdatedCli(apiUrl)\n }\n\n const cached = readDiskCache<TemplatesListResponseV1>(TEMPLATES_CACHE_FILE)\n\n if (options.offline) {\n if (!cached) {\n throw networkError(\n \"no cached registry available. Run without --offline first to populate the cache.\",\n )\n }\n return cached.body.templates\n }\n\n let res: Awaited<ReturnType<typeof fetchWithRetry>>\n try {\n res = await fetchWithRetry({\n apiUrl,\n headers: buildHeaders(cached?.etag ?? null),\n })\n } catch (e) {\n // All retries exhausted on a network error. Fall back to cache.\n if (cached) {\n process.stderr.write(\n \"⚠ Using cached registry (offline — backend unreachable)\\n\",\n )\n return cached.body.templates\n }\n throw networkError(\n `fetch failed: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n\n if (res.status === 304 && cached) {\n return cached.body.templates\n }\n\n if (res.status < 200 || res.status >= 300) {\n // Non-retryable failure (4xx other than 429, or 5xx after all retries).\n if (cached) {\n process.stderr.write(\n `⚠ Using cached registry (offline — server returned HTTP ${res.status})\\n`,\n )\n return cached.body.templates\n }\n throw networkError(`endpoint returned HTTP ${res.status}`)\n }\n\n let body: unknown\n try {\n body = JSON.parse(res.bodyText)\n } catch (e) {\n throw parseError(\n `endpoint returned non-JSON body: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n\n const result = TemplatesListResponseV1.safeParse(body)\n if (!result.success) {\n throw parseError(\n `response shape mismatch: ${result.error.issues.map((i) => `${i.path.join(\".\")} (${i.code})`).join(\", \")}`,\n )\n }\n\n writeDiskCache(TEMPLATES_CACHE_FILE, result.data, res.etag)\n return result.data.templates\n}\n","import pc from \"picocolors\"\nimport type { CliError } from \"./errors.js\"\nimport type { Template } from \"./api.js\"\n\nexport const printJson = (value: unknown): void => {\n process.stdout.write(JSON.stringify(value, null, 2) + \"\\n\")\n}\n\nexport const printError = (err: CliError): void => {\n process.stderr.write(\n `${pc.red(\"Error\")}: ${err.message}\\n` +\n (err.hint ? `${pc.dim(\"Hint\")}: ${err.hint}\\n` : \"\") +\n `${pc.dim(\"Code\")}: ${err.code}\\n`,\n )\n}\n\nexport const printTemplatesTable = (templates: Template[]): void => {\n if (templates.length === 0) {\n process.stdout.write(pc.dim(\"No templates available.\\n\"))\n return\n }\n const headers = [\"slug\", \"name\", \"category\", \"license\"]\n const rows = templates.map((t) => [\n t.slug,\n t.name,\n t.category,\n t.license,\n ])\n printAlignedTable([headers, ...rows])\n}\n\nexport const printTemplateInfo = (t: Template): void => {\n const lines: Array<[string, string]> = [\n [\"slug\", t.slug],\n [\"name\", t.name],\n [\"description\", t.description],\n [\"category\", t.category],\n [\"license\", t.license],\n [\"repo\", `${t.owner}/${t.repo}`],\n [\"labels\", t.labels.join(\", \") || pc.dim(\"(none)\")],\n ]\n if (t.image) lines.push([\"image\", t.image])\n\n const labelWidth = Math.max(...lines.map(([l]) => l.length))\n for (const [label, value] of lines) {\n process.stdout.write(\n `${pc.dim(label.padEnd(labelWidth))} ${value}\\n`,\n )\n }\n}\n\nconst printAlignedTable = (rows: string[][]): void => {\n const firstRow = rows[0]\n if (!firstRow) return\n const widths = firstRow.map((_, col) =>\n Math.max(...rows.map((row) => row[col]?.length ?? 0)),\n )\n for (const row of rows) {\n process.stdout.write(\n row.map((cell, i) => cell.padEnd(widths[i] ?? 0)).join(\" \") + \"\\n\",\n )\n }\n}","import { spawn as nodeSpawn } from \"node:child_process\"\n\nexport type SpawnOptions = {\n cwd?: string\n env?: NodeJS.ProcessEnv\n stdio?: \"inherit\" | \"pipe\" | \"ignore\"\n /** If true, do not throw on non-zero exit codes. Default is `true` (no throw). */\n reject?: boolean\n}\n\n/**\n * Run a command and resolve with its exit code. Never throws on non-zero by\n * default; pass `reject: true` to opt into throwing.\n */\nexport const spawn = (\n command: string,\n args: string[],\n options: SpawnOptions = {},\n): Promise<number> => {\n const { cwd, env, stdio = \"inherit\", reject = false } = options\n return new Promise((resolve, rejectFn) => {\n const child = nodeSpawn(command, args, {\n cwd,\n env: env ?? process.env,\n stdio,\n shell: false,\n })\n child.on(\"error\", (err) => rejectFn(err))\n child.on(\"exit\", (code) => {\n const exit = code ?? 1\n if (reject && exit !== 0) {\n rejectFn(new Error(`${command} exited with code ${exit}`))\n } else {\n resolve(exit)\n }\n })\n })\n}","import { spawn } from \"./spawn.js\"\nimport { gitNotInstalled } from \"../errors.js\"\n\nexport type CloneResult = {\n ref: string\n attempts: string[]\n}\n\n/**\n * Clone a git repo to `dir`. Tries `main` first, then falls back to `master`.\n * Caller can pass an explicit `--ref` to override.\n */\nexport const cloneRepo = async (\n url: string,\n dir: string,\n requestedRef?: string,\n): Promise<CloneResult> => {\n const refs = requestedRef ? [requestedRef] : [\"main\", \"master\"]\n const attempts: string[] = []\n\n for (const ref of refs) {\n attempts.push(ref)\n const code = await spawn(\n \"git\",\n [\"clone\", \"--depth\", \"1\", \"--branch\", ref, url, dir],\n { stdio: \"inherit\", reject: false },\n )\n if (code === 0) {\n return { ref, attempts }\n }\n }\n\n // All attempts failed. Probe whether git is even installed.\n const probe = await spawn(\"git\", [\"--version\"], {\n stdio: \"ignore\",\n reject: false,\n })\n if (probe !== 0) {\n throw gitNotInstalled()\n }\n\n // Git works but neither ref matched. Re-throw with attempts context.\n throw new Error(\n `git clone failed for refs: ${refs.join(\", \")}. Tried: ${attempts.join(\", \")}.`,\n )\n}","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\nexport type PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\"\n\nexport type PackageManagerInfo = {\n pm: PackageManager\n /** Raw value from packageManager field, e.g. \"pnpm@9.0.0\". May include version. */\n raw?: string\n}\n\n/**\n * Detect the package manager for a directory, in priority order:\n * 1. `packageManager` field in package.json (Corepack convention)\n * 2. Lockfile presence\n * 3. Returns null if nothing matches (caller decides whether to fail)\n */\nexport const detectPackageManager = (\n cwd: string,\n): PackageManagerInfo | null => {\n const pkg = readPackageJson(cwd)\n if (pkg?.packageManager) {\n const pm = parsePackageManagerField(pkg.packageManager)\n if (pm) return pm\n }\n\n if (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return { pm: \"pnpm\" }\n if (existsSync(join(cwd, \"bun.lockb\"))) return { pm: \"bun\" }\n if (existsSync(join(cwd, \"yarn.lock\"))) return { pm: \"yarn\" }\n if (existsSync(join(cwd, \"package-lock.json\"))) return { pm: \"npm\" }\n\n return null\n}\n\nexport const getInstallCommand = (info: PackageManagerInfo): string => {\n switch (info.pm) {\n case \"pnpm\":\n return \"pnpm install\"\n case \"npm\":\n return \"npm install\"\n case \"yarn\":\n return \"yarn install\"\n case \"bun\":\n return \"bun install\"\n }\n}\n\nconst readPackageJson = (\n cwd: string,\n): { packageManager?: string } | null => {\n const path = join(cwd, \"package.json\")\n if (!existsSync(path)) return null\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as {\n packageManager?: string\n }\n } catch {\n return null\n }\n}\n\nexport const parsePackageManagerField = (\n raw: string,\n): PackageManagerInfo | null => {\n // Format: \"<name>@<version>\" or just \"<name>\". Common names: pnpm, npm, yarn, bun.\n const name = raw.split(\"@\")[0]?.trim().toLowerCase()\n if (name === \"pnpm\" || name === \"npm\" || name === \"yarn\" || name === \"bun\") {\n return { pm: name, raw }\n }\n return null\n}","import { existsSync } from \"node:fs\"\nimport { resolve } from \"node:path\"\nimport { Command } from \"commander\"\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { fetchTemplates } from \"../api.js\"\nimport { DEFAULT_API_URL } from \"../constants.js\"\nimport {\n installFailed,\n internal,\n notFound,\n targetExists,\n} from \"../errors.js\"\nimport { printError, printJson } from \"../output.js\"\nimport { cloneRepo } from \"../utils/git.js\"\nimport {\n detectPackageManager,\n getInstallCommand,\n type PackageManagerInfo,\n} from \"../utils/detect-pm.js\"\nimport { spawn } from \"../utils/spawn.js\"\n\nexport const initCommand = new Command(\"init\")\n .description(\"Clone a template repo + install dependencies\")\n .argument(\"<slug>\", \"template slug (use `deessejs list` to see options)\")\n .option(\"--pm <name>\", \"override detected package manager (pnpm|npm|yarn|bun)\")\n .option(\"--dir <path>\", \"target directory (default: ./<slug>)\")\n .option(\"--ref <branch>\", \"git ref to clone (default: tries main, falls back to master)\")\n .option(\"--no-install\", \"skip the install step\")\n .option(\"--force\", \"overwrite target directory if it exists\")\n .option(\"--json\", \"JSON output for scripting\")\n .action(\n async (\n slug: string,\n opts: {\n pm?: string\n dir?: string\n ref?: string\n install: boolean\n force?: boolean\n json?: boolean\n },\n ) => {\n const apiUrl = initCommand.parent?.getOptionValue(\"apiUrl\") as\n | string\n | undefined\n const offline = initCommand.parent?.getOptionValue(\"offline\") as\n | boolean\n | undefined\n\n try {\n const templates = await fetchTemplates(\n apiUrl ?? process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL,\n { offline: Boolean(offline) },\n )\n const template = templates.find((t) => t.slug === slug)\n if (!template) {\n throw notFound(\n slug,\n templates.map((t) => t.slug),\n )\n }\n\n const dir = resolve(process.cwd(), opts.dir ?? `./${slug}`)\n if (existsSync(dir) && !opts.force) {\n throw targetExists(dir)\n }\n\n const repoUrl =\n template.cloneUrl ?? `https://github.com/${template.owner}/${template.repo}`\n\n const cloneSpinner = ora(`Cloning ${pc.cyan(template.owner + \"/\" + template.repo)}...`).start()\n let cloneResult\n try {\n cloneResult = await cloneRepo(repoUrl, dir, opts.ref)\n cloneSpinner.succeed(`Cloned into ${pc.cyan(dir)} (ref: ${cloneResult.ref})`)\n } catch (err) {\n cloneSpinner.fail(\"Clone failed\")\n throw err\n }\n\n if (!opts.install) {\n if (opts.json) {\n printJson({\n ok: true,\n slug: template.slug,\n dir,\n ref: cloneResult.ref,\n installed: false,\n })\n } else {\n console.log(pc.dim(`\\nNext: cd ${dir} && <your package manager> install\\n`))\n }\n return\n }\n\n const VALID_PMS = [\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const\n type ValidPm = (typeof VALID_PMS)[number]\n const pmInfo: PackageManagerInfo | null =\n opts.pm && (VALID_PMS as readonly string[]).includes(opts.pm)\n ? { pm: opts.pm as ValidPm }\n : detectPackageManager(dir)\n\n if (!pmInfo) {\n console.log(\n pc.yellow(\n \"\\nNo package manager detected (no packageManager field, no lockfile).\",\n ),\n )\n console.log(\n pc.dim(\"Skipping install. Run your install command manually inside the directory.\\n\"),\n )\n } else {\n const installSpinner = ora(\n `Installing dependencies via ${pc.cyan(pmInfo.pm)}...`,\n ).start()\n const cmd = getInstallCommand(pmInfo)\n const cmdParts = cmd.split(\" \")\n const bin = cmdParts[0] ?? \"npm\"\n const args = cmdParts.slice(1)\n const code = await spawn(bin, args, { cwd: dir, stdio: \"inherit\", reject: false })\n if (code !== 0) {\n installSpinner.fail(`${pmInfo.pm} install failed`)\n throw installFailed(pmInfo.pm, code)\n }\n installSpinner.succeed(\"Dependencies installed\")\n }\n\n if (opts.json) {\n printJson({\n ok: true,\n slug: template.slug,\n dir,\n ref: cloneResult.ref,\n installed: pmInfo !== null,\n packageManager: pmInfo?.pm ?? null,\n })\n } else {\n console.log()\n console.log(pc.green(\"✓ Template ready\"))\n console.log(pc.dim(` cd ${dir}`))\n console.log(\n pc.dim(\n pmInfo\n ? ` ${getInstallCommand(pmInfo).split(\" \")[0]} dev`\n : ` install deps, then start`,\n ),\n )\n console.log()\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"CliError\") {\n if (opts.json) {\n printJson({\n ok: false,\n code: (err as { code?: string }).code,\n message: err.message,\n hint: (err as { hint?: string }).hint,\n })\n } else {\n printError(err as Parameters<typeof printError>[0])\n }\n process.exit((err as { exitCode?: () => number }).exitCode?.() ?? 1)\n }\n throw internal(err instanceof Error ? err.message : String(err))\n }\n },\n )","import { Command } from \"commander\"\nimport ora from \"ora\"\nimport pc from \"picocolors\"\nimport { fetchTemplates } from \"../api.js\"\nimport { DEFAULT_API_URL } from \"../constants.js\"\nimport { internal } from \"../errors.js\"\nimport { printError, printJson, printTemplatesTable } from \"../output.js\"\n\nexport const listCommand = new Command(\"list\")\n .description(\"List available templates\")\n .option(\"--category <name>\", \"filter to a single category\")\n .option(\"--json\", \"JSON output for scripting\")\n .action(\n async (\n opts: { category?: string; json?: boolean },\n command: Command,\n ) => {\n const apiUrl = command.parent?.getOptionValue(\"apiUrl\") as\n | string\n | undefined\n const offline = command.parent?.getOptionValue(\"offline\") as\n | boolean\n | undefined\n\n const spinner = opts.json\n ? null\n : ora(offline ? \"Reading cached templates...\" : \"Fetching templates...\").start()\n\n try {\n const all = await fetchTemplates(\n apiUrl ?? process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL,\n { offline: Boolean(offline) },\n )\n const filtered = opts.category\n ? all.filter((t) => t.category === opts.category)\n : all\n\n spinner?.stop()\n\n if (opts.json) {\n printJson({ templates: filtered })\n } else {\n if (opts.category) {\n console.log(pc.dim(`Category: ${opts.category}`))\n }\n printTemplatesTable(filtered)\n console.log()\n console.log(\n pc.dim(\n `${filtered.length} template${filtered.length === 1 ? \"\" : \"s\"}.` +\n (opts.category\n ? \"\"\n : \" Use --category <name> to filter, --json for scripting.\"),\n ),\n )\n }\n } catch (err) {\n spinner?.fail(\"Failed to fetch templates\")\n if (err instanceof Error && err.name === \"CliError\") {\n if (opts.json) {\n printJson({\n ok: false,\n code: (err as { code?: string }).code,\n message: err.message,\n hint: (err as { hint?: string }).hint,\n })\n } else {\n printError(err as Parameters<typeof printError>[0])\n }\n process.exit(1)\n }\n throw internal(err instanceof Error ? err.message : String(err))\n }\n },\n )","import { Command } from \"commander\"\nimport ora from \"ora\"\nimport { fetchTemplates } from \"../api.js\"\nimport { DEFAULT_API_URL } from \"../constants.js\"\nimport { internal, notFound } from \"../errors.js\"\nimport { printError, printJson, printTemplateInfo } from \"../output.js\"\n\nexport const infoCommand = new Command(\"info\")\n .description(\"Show details for one template\")\n .argument(\"<slug>\", \"template slug\")\n .option(\"--json\", \"JSON output for scripting\")\n .action(\n async (slug: string, opts: { json?: boolean }, command: Command) => {\n const apiUrl = command.parent?.getOptionValue(\"apiUrl\") as\n | string\n | undefined\n const offline = command.parent?.getOptionValue(\"offline\") as\n | boolean\n | undefined\n\n const spinner = opts.json\n ? null\n : ora(offline ? \"Reading cached template...\" : \"Fetching template...\").start()\n\n try {\n const all = await fetchTemplates(\n apiUrl ?? process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL,\n { offline: Boolean(offline) },\n )\n const template = all.find((t) => t.slug === slug)\n spinner?.stop()\n\n if (!template) {\n throw notFound(slug, all.map((t) => t.slug))\n }\n\n if (opts.json) {\n printJson({ template })\n } else {\n printTemplateInfo(template)\n console.log()\n console.log(\n `Install: ${`deessejs init ${template.slug}`}`,\n )\n }\n } catch (err) {\n spinner?.fail(\"Failed to fetch template\")\n if (err instanceof Error && err.name === \"CliError\") {\n if (opts.json) {\n printJson({\n ok: false,\n code: (err as { code?: string }).code,\n message: err.message,\n hint: (err as { hint?: string }).hint,\n })\n } else {\n printError(err as Parameters<typeof printError>[0])\n }\n process.exit(1)\n }\n throw internal(err instanceof Error ? err.message : String(err))\n }\n },\n )","import { Command } from \"commander\"\nimport pc from \"picocolors\"\nimport { DEFAULT_API_URL, USER_AGENT } from \"./constants.js\"\nimport { initCommand } from \"./commands/init.js\"\nimport { listCommand } from \"./commands/list.js\"\nimport { infoCommand } from \"./commands/info.js\"\n\nconst program = new Command()\n\nprogram\n .name(\"deessejs\")\n .description(\"CLI for the DeesseJS template registry\")\n .version(\"0.1.0\")\n .option(\"--api-url <url>\", \"templates endpoint URL\", process.env.DEESSEJS_API_URL ?? DEFAULT_API_URL)\n .option(\"--offline\", \"skip the network, serve the on-disk cache (~/.deessejs/templates.json)\")\n\nprogram.addCommand(listCommand)\nprogram.addCommand(infoCommand)\nprogram.addCommand(initCommand)\n\nprogram.parseAsync(process.argv).catch((err) => {\n // Last-resort error handler. Per-command handlers catch CliError and exit\n // cleanly with the right code. Anything that lands here is an uncaught bug.\n process.stderr.write(\n `${pc.red(\"Internal error\")}: ${err instanceof Error ? err.message : String(err)}\\n`,\n )\n if (process.env.DEESSEJS_DEBUG) {\n process.stderr.write(`\\n${err instanceof Error && err.stack ? err.stack : \"\"}\\n`)\n }\n process.exit(1)\n})\n\nvoid USER_AGENT // re-exported for downstream consumers if needed"]}
package/package.json CHANGED
@@ -1,65 +1,68 @@
1
- {
2
- "name": "@deessejs/cli",
3
- "version": "1.0.1",
4
- "description": "CLI for the DeesseJS template registry.",
5
- "type": "module",
6
- "license": "MIT",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/deessejs/deessejs.git"
10
- },
11
- "keywords": [
12
- "cli",
13
- "deessejs",
14
- "saas-template",
15
- "scaffolding"
16
- ],
17
- "private": false,
18
- "bin": {
19
- "deessejs": "./dist/index.js"
20
- },
21
- "main": "./dist/index.js",
22
- "module": "./dist/index.js",
23
- "types": "./dist/index.d.ts",
24
- "files": [
25
- "dist",
26
- "README.md",
27
- "../../LICENSE"
28
- ],
29
- "scripts": {
30
- "build": "tsup",
31
- "dev": "tsup --watch",
32
- "lint": "eslint",
33
- "format": "prettier --write \"**/*.{ts,tsx,json,md}\"",
34
- "typecheck": "tsc --noEmit",
35
- "pretest": "tsup",
36
- "test": "vitest run",
37
- "test:watch": "vitest",
38
- "start": "node ./dist/index.js"
39
- },
40
- "dependencies": {
41
- "@deessejs/errors": "^1.1.1",
42
- "@deessejs/fp": "^1.0.0",
43
- "commander": "^12.1.0",
44
- "ora": "^8.1.1",
45
- "picocolors": "^1.1.1"
46
- },
47
- "devDependencies": {
48
- "@types/node": "catalog:",
49
- "@workspace/eslint-config": "workspace:*",
50
- "@workspace/typescript-config": "workspace:*",
51
- "eslint": "^9",
52
- "prettier": "^3.9.4",
53
- "prettier-plugin-tailwindcss": "^0.8.0",
54
- "tsup": "^8.3.5",
55
- "typescript": "catalog:",
56
- "vitest": "^2.1.5"
57
- },
58
- "engines": {
59
- "node": ">=18.18.0"
60
- },
61
- "publishConfig": {
62
- "access": "public",
63
- "provenance": true
64
- }
1
+ {
2
+ "name": "@deessejs/cli",
3
+ "version": "1.1.1",
4
+ "description": "CLI for the DeesseJS template registry.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/deessejs/deessejs.git"
10
+ },
11
+ "keywords": [
12
+ "cli",
13
+ "deessejs",
14
+ "saas-template",
15
+ "scaffolding"
16
+ ],
17
+ "private": false,
18
+ "bin": {
19
+ "deessejs": "./dist/index.js"
20
+ },
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "../../LICENSE"
28
+ ],
29
+ "dependencies": {
30
+ "@deessejs/errors": "^1.1.1",
31
+ "@deessejs/fp": "^1.0.0",
32
+ "commander": "^12.1.0",
33
+ "ora": "^8.1.1",
34
+ "picocolors": "^1.1.1",
35
+ "@workspace/contracts": "0.0.1"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^24",
39
+ "eslint": "^9",
40
+ "prettier": "^3.9.4",
41
+ "prettier-plugin-tailwindcss": "^0.8.0",
42
+ "tsup": "^8.3.5",
43
+ "typescript": "^6.0.3",
44
+ "vitest": "^2.1.5",
45
+ "@workspace/typescript-config": "0.0.0",
46
+ "@workspace/eslint-config": "0.0.0"
47
+ },
48
+ "engines": {
49
+ "node": ">=18.18.0"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public",
53
+ "provenance": true
54
+ },
55
+ "scripts": {
56
+ "prebuild": "pnpm --filter @workspace/contracts build",
57
+ "build": "tsup",
58
+ "predev": "pnpm --filter @workspace/contracts build",
59
+ "dev": "tsup --watch",
60
+ "lint": "eslint",
61
+ "format": "prettier --write \"**/*.{ts,tsx,json,md}\"",
62
+ "typecheck": "tsc --noEmit",
63
+ "pretest": "pnpm --filter @workspace/contracts build && tsup",
64
+ "test": "vitest run",
65
+ "test:watch": "vitest",
66
+ "start": "node ./dist/index.js"
67
+ }
65
68
  }