@cimplify/cli 0.2.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-7N2EZR6W.mjs → add-ZJNXWN2B.mjs} +10 -10
- package/dist/assets-DMK2QOPD.mjs +208 -0
- package/dist/chunk-5IAYN7AJ.mjs +259 -0
- package/dist/{chunk-4SBJVRGM.mjs → chunk-C4M3DXKC.mjs} +3 -1
- package/dist/{chunk-NC3GKHDD.mjs → chunk-D7WMSGKK.mjs} +1 -1
- package/dist/{chunk-NZ4RG62Z.mjs → chunk-I3XQSSOT.mjs} +4 -1
- package/dist/{chunk-JJYWETGA.mjs → chunk-LS2VTSMQ.mjs} +8 -2
- package/dist/{chunk-G2P6KHM5.mjs → chunk-MHK4WVNF.mjs} +2392 -596
- package/dist/{chunk-JOUXICGV.mjs → chunk-MOZQODQS.mjs} +1 -1
- package/dist/{chunk-KPGRCXQY.mjs → chunk-QGBXGDA5.mjs} +5 -5
- package/dist/chunk-RRY3NEZZ.mjs +79 -0
- package/dist/{chunk-L6474RPL.mjs → chunk-RZQTHTXX.mjs} +1 -1
- package/dist/{chunk-4YSOZ6LY.mjs → chunk-YI7UMMM7.mjs} +1 -1
- package/dist/{chunk-52GZ5B77.mjs → chunk-YQVMG62Z.mjs} +3 -3
- package/dist/{deploy-6KVOROT3.mjs → deploy-UKOOPJAE.mjs} +8 -82
- package/dist/{dev-AQP6TMYK.mjs → dev-FD4PM3UD.mjs} +5 -5
- package/dist/dispatcher.mjs +34 -22
- package/dist/doctor-5LBLYT7M.mjs +314 -0
- package/dist/{domains-2ZQ7AG27.mjs → domains-JQMV6GAP.mjs} +5 -5
- package/dist/{env-FDBPGU3W.mjs → env-EVMYQUIK.mjs} +6 -6
- package/dist/explain-3KBMWL6M.mjs +223 -0
- package/dist/introspect-PFBI3JHO.mjs +8 -0
- package/dist/{link-P4K2HRXY.mjs → link-X3E4UZBF.mjs} +4 -4
- package/dist/{list-FL6JZ6A4.mjs → list-TE54SJIB.mjs} +3 -3
- package/dist/{login-RSKGT6GU.mjs → login-WSAW4BEA.mjs} +4 -4
- package/dist/{logout-ZFZLSJ32.mjs → logout-DJDINVDF.mjs} +2 -2
- package/dist/{logs-E2AGTDCF.mjs → logs-KUKGEXR2.mjs} +4 -4
- package/dist/{projects-5CJOZ3MT.mjs → projects-364HGWHO.mjs} +13 -11
- package/dist/repo-26N2CHF6.mjs +8 -0
- package/dist/{rollback-36O4NOEL.mjs → rollback-5YALPQXL.mjs} +5 -5
- package/dist/{status-6AT4HF63.mjs → status-W4HW3CX3.mjs} +4 -4
- package/dist/{unlink-5ABCT7B6.mjs → unlink-HIIW57OO.mjs} +2 -2
- package/dist/{update-LFTHO6Q5.mjs → update-5MRKRVZC.mjs} +7 -7
- package/dist/{whoami-DIJZYZIN.mjs → whoami-LACWBSNL.mjs} +3 -3
- package/package.json +3 -3
- package/templates/storefront-auto/.claude/skills/cimplify-storefront/SKILL.md +145 -0
- package/templates/storefront-auto/.cursor/rules/cimplify-storefront.mdc +25 -0
- package/templates/storefront-auto/.env.example +22 -0
- package/templates/storefront-auto/AGENTS.md +95 -0
- package/templates/storefront-auto/CLAUDE.md +22 -0
- package/templates/storefront-auto/README.md +48 -0
- package/templates/storefront-auto/__tests__/brand.test.ts +4 -0
- package/templates/storefront-auto/__tests__/cart-flow.test.ts +4 -0
- package/templates/storefront-auto/__tests__/contract.test.ts +4 -0
- package/templates/storefront-auto/app/.well-known/ucp/route.ts +65 -0
- package/templates/storefront-auto/app/about/page.tsx +41 -0
- package/templates/storefront-auto/app/accessibility/page.tsx +11 -0
- package/templates/storefront-auto/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-auto/app/account/orders/page.tsx +21 -0
- package/templates/storefront-auto/app/account/page.tsx +22 -0
- package/templates/storefront-auto/app/account/settings/page.tsx +21 -0
- package/templates/storefront-auto/app/cart/page.tsx +9 -0
- package/templates/storefront-auto/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-auto/app/categories/[slug]/page.tsx +130 -0
- package/templates/storefront-auto/app/checkout/page.tsx +17 -0
- package/templates/storefront-auto/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-auto/app/collections/[slug]/page.tsx +130 -0
- package/templates/storefront-auto/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-auto/app/contact/page.tsx +54 -0
- package/templates/storefront-auto/app/error.tsx +61 -0
- package/templates/storefront-auto/app/faq/page.tsx +46 -0
- package/templates/storefront-auto/app/globals.css +47 -0
- package/templates/storefront-auto/app/layout.tsx +77 -0
- package/templates/storefront-auto/app/llms.txt/route.ts +94 -0
- package/templates/storefront-auto/app/login/page.tsx +17 -0
- package/templates/storefront-auto/app/not-found.tsx +39 -0
- package/templates/storefront-auto/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-auto/app/orders/[id]/page.tsx +24 -0
- package/templates/storefront-auto/app/page.tsx +94 -0
- package/templates/storefront-auto/app/privacy/page.tsx +44 -0
- package/templates/storefront-auto/app/products/[slug]/page.tsx +165 -0
- package/templates/storefront-auto/app/products/[slug]/product-detail.tsx +70 -0
- package/templates/storefront-auto/app/returns/page.tsx +11 -0
- package/templates/storefront-auto/app/robots.ts +18 -0
- package/templates/storefront-auto/app/search/page.tsx +38 -0
- package/templates/storefront-auto/app/search/search-client.tsx +7 -0
- package/templates/storefront-auto/app/shipping/page.tsx +16 -0
- package/templates/storefront-auto/app/shop/page.tsx +63 -0
- package/templates/storefront-auto/app/shop/shop-client.tsx +32 -0
- package/templates/storefront-auto/app/signup/page.tsx +17 -0
- package/templates/storefront-auto/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-auto/app/sitemap.ts +59 -0
- package/templates/storefront-auto/app/terms/page.tsx +44 -0
- package/templates/storefront-auto/app/track-order/page.tsx +24 -0
- package/templates/storefront-auto/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-auto/components/account-iframe.tsx +13 -0
- package/templates/storefront-auto/components/auto-hero.tsx +85 -0
- package/templates/storefront-auto/components/brand-marquee.tsx +27 -0
- package/templates/storefront-auto/components/cart-drawer.tsx +14 -0
- package/templates/storefront-auto/components/cart-pill.tsx +36 -0
- package/templates/storefront-auto/components/category-grid.tsx +28 -0
- package/templates/storefront-auto/components/category-tiles.tsx +104 -0
- package/templates/storefront-auto/components/collection-strip.tsx +45 -0
- package/templates/storefront-auto/components/feature-hero.tsx +84 -0
- package/templates/storefront-auto/components/fitment-finder.tsx +184 -0
- package/templates/storefront-auto/components/footer.tsx +153 -0
- package/templates/storefront-auto/components/header.tsx +45 -0
- package/templates/storefront-auto/components/hero.tsx +28 -0
- package/templates/storefront-auto/components/nav-link.tsx +20 -0
- package/templates/storefront-auto/components/newsletter.tsx +50 -0
- package/templates/storefront-auto/components/policy-page.tsx +49 -0
- package/templates/storefront-auto/components/promo-banner.tsx +41 -0
- package/templates/storefront-auto/components/providers.tsx +35 -0
- package/templates/storefront-auto/components/section-heading.tsx +37 -0
- package/templates/storefront-auto/components/service-brief.tsx +65 -0
- package/templates/storefront-auto/components/store-product-card.tsx +88 -0
- package/templates/storefront-auto/components/trade-in-cta.tsx +54 -0
- package/templates/storefront-auto/components/trust-bar.tsx +66 -0
- package/templates/storefront-auto/lib/brand.ts +744 -0
- package/templates/storefront-auto/lib/cart.ts +12 -0
- package/templates/storefront-auto/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-auto/next.config.ts +45 -0
- package/templates/storefront-auto/package.json +35 -0
- package/templates/storefront-auto/postcss.config.mjs +7 -0
- package/templates/storefront-auto/tsconfig.json +23 -0
- package/templates/storefront-auto/vitest.config.ts +9 -0
- package/templates/storefront-bakery/.env.example +2 -2
- package/templates/storefront-bakery/README.md +1 -1
- package/templates/storefront-bakery/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-bakery/next.config.ts +3 -0
- package/templates/storefront-bakery/package.json +1 -1
- package/templates/storefront-fashion/.env.example +2 -2
- package/templates/storefront-fashion/README.md +1 -1
- package/templates/storefront-fashion/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-fashion/next.config.ts +3 -0
- package/templates/storefront-fashion/package.json +1 -1
- package/templates/storefront-grocery/.env.example +2 -2
- package/templates/storefront-grocery/README.md +1 -1
- package/templates/storefront-grocery/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-grocery/next.config.ts +3 -0
- package/templates/storefront-grocery/package.json +1 -1
- package/templates/storefront-pharmacy/.claude/skills/cimplify-storefront/SKILL.md +145 -0
- package/templates/storefront-pharmacy/.cursor/rules/cimplify-storefront.mdc +25 -0
- package/templates/storefront-pharmacy/.env.example +22 -0
- package/templates/storefront-pharmacy/AGENTS.md +118 -0
- package/templates/storefront-pharmacy/CLAUDE.md +22 -0
- package/templates/storefront-pharmacy/README.md +87 -0
- package/templates/storefront-pharmacy/__tests__/brand.test.ts +4 -0
- package/templates/storefront-pharmacy/__tests__/cart-flow.test.ts +4 -0
- package/templates/storefront-pharmacy/__tests__/contract.test.ts +4 -0
- package/templates/storefront-pharmacy/app/.well-known/ucp/route.ts +65 -0
- package/templates/storefront-pharmacy/app/about/page.tsx +41 -0
- package/templates/storefront-pharmacy/app/accessibility/page.tsx +11 -0
- package/templates/storefront-pharmacy/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-pharmacy/app/account/orders/page.tsx +21 -0
- package/templates/storefront-pharmacy/app/account/page.tsx +22 -0
- package/templates/storefront-pharmacy/app/account/settings/page.tsx +21 -0
- package/templates/storefront-pharmacy/app/cart/page.tsx +9 -0
- package/templates/storefront-pharmacy/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-pharmacy/app/categories/[slug]/page.tsx +130 -0
- package/templates/storefront-pharmacy/app/checkout/page.tsx +17 -0
- package/templates/storefront-pharmacy/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-pharmacy/app/collections/[slug]/page.tsx +130 -0
- package/templates/storefront-pharmacy/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-pharmacy/app/contact/page.tsx +54 -0
- package/templates/storefront-pharmacy/app/error.tsx +61 -0
- package/templates/storefront-pharmacy/app/faq/page.tsx +46 -0
- package/templates/storefront-pharmacy/app/globals.css +47 -0
- package/templates/storefront-pharmacy/app/layout.tsx +77 -0
- package/templates/storefront-pharmacy/app/llms.txt/route.ts +94 -0
- package/templates/storefront-pharmacy/app/login/page.tsx +17 -0
- package/templates/storefront-pharmacy/app/not-found.tsx +39 -0
- package/templates/storefront-pharmacy/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-pharmacy/app/orders/[id]/page.tsx +24 -0
- package/templates/storefront-pharmacy/app/page.tsx +78 -0
- package/templates/storefront-pharmacy/app/privacy/page.tsx +44 -0
- package/templates/storefront-pharmacy/app/products/[slug]/page.tsx +165 -0
- package/templates/storefront-pharmacy/app/products/[slug]/product-detail.tsx +70 -0
- package/templates/storefront-pharmacy/app/returns/page.tsx +11 -0
- package/templates/storefront-pharmacy/app/robots.ts +18 -0
- package/templates/storefront-pharmacy/app/search/page.tsx +38 -0
- package/templates/storefront-pharmacy/app/search/search-client.tsx +7 -0
- package/templates/storefront-pharmacy/app/shipping/page.tsx +16 -0
- package/templates/storefront-pharmacy/app/shop/page.tsx +63 -0
- package/templates/storefront-pharmacy/app/shop/shop-client.tsx +32 -0
- package/templates/storefront-pharmacy/app/signup/page.tsx +17 -0
- package/templates/storefront-pharmacy/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-pharmacy/app/sitemap.ts +59 -0
- package/templates/storefront-pharmacy/app/terms/page.tsx +44 -0
- package/templates/storefront-pharmacy/app/track-order/page.tsx +24 -0
- package/templates/storefront-pharmacy/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-pharmacy/components/account-iframe.tsx +13 -0
- package/templates/storefront-pharmacy/components/brand-marquee.tsx +27 -0
- package/templates/storefront-pharmacy/components/cart-drawer.tsx +14 -0
- package/templates/storefront-pharmacy/components/cart-pill.tsx +36 -0
- package/templates/storefront-pharmacy/components/category-grid.tsx +28 -0
- package/templates/storefront-pharmacy/components/category-tiles.tsx +104 -0
- package/templates/storefront-pharmacy/components/collection-strip.tsx +45 -0
- package/templates/storefront-pharmacy/components/feature-hero.tsx +84 -0
- package/templates/storefront-pharmacy/components/footer.tsx +153 -0
- package/templates/storefront-pharmacy/components/header.tsx +45 -0
- package/templates/storefront-pharmacy/components/health-brief.tsx +65 -0
- package/templates/storefront-pharmacy/components/hero.tsx +28 -0
- package/templates/storefront-pharmacy/components/nav-link.tsx +20 -0
- package/templates/storefront-pharmacy/components/newsletter.tsx +50 -0
- package/templates/storefront-pharmacy/components/pharmacy-hero.tsx +95 -0
- package/templates/storefront-pharmacy/components/policy-page.tsx +49 -0
- package/templates/storefront-pharmacy/components/promo-banner.tsx +41 -0
- package/templates/storefront-pharmacy/components/providers.tsx +35 -0
- package/templates/storefront-pharmacy/components/section-heading.tsx +37 -0
- package/templates/storefront-pharmacy/components/store-product-card.tsx +88 -0
- package/templates/storefront-pharmacy/components/symptom-finder.tsx +108 -0
- package/templates/storefront-pharmacy/components/trade-in-cta.tsx +54 -0
- package/templates/storefront-pharmacy/components/trust-bar.tsx +66 -0
- package/templates/storefront-pharmacy/components/urgent-ctas.tsx +117 -0
- package/templates/storefront-pharmacy/lib/brand.ts +790 -0
- package/templates/storefront-pharmacy/lib/cart.ts +12 -0
- package/templates/storefront-pharmacy/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-pharmacy/next.config.ts +45 -0
- package/templates/storefront-pharmacy/package.json +35 -0
- package/templates/storefront-pharmacy/postcss.config.mjs +7 -0
- package/templates/storefront-pharmacy/tsconfig.json +23 -0
- package/templates/storefront-pharmacy/vitest.config.ts +9 -0
- package/templates/storefront-restaurant/.env.example +2 -2
- package/templates/storefront-restaurant/README.md +1 -1
- package/templates/storefront-restaurant/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-restaurant/next.config.ts +3 -0
- package/templates/storefront-restaurant/package.json +1 -1
- package/templates/storefront-retail/.env.example +2 -2
- package/templates/storefront-retail/README.md +1 -1
- package/templates/storefront-retail/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-retail/next.config.ts +3 -0
- package/templates/storefront-retail/package.json +1 -1
- package/templates/storefront-services/.env.example +2 -2
- package/templates/storefront-services/README.md +1 -1
- package/templates/storefront-services/lib/cimplify-loader.ts +19 -0
- package/templates/storefront-services/next.config.ts +3 -0
- package/templates/storefront-services/package.json +1 -1
- package/dist/repo-E6SBKVDG.mjs +0 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { TERMINAL_DEPLOYMENT_STATUSES, DEPLOYMENT_STATUS } from './chunk-MXYUAJEW.mjs';
|
|
3
|
-
import { dim, CliError, CLI_ERROR_CODE, failure, success, isJsonMode } from './chunk-
|
|
3
|
+
import { dim, CliError, CLI_ERROR_CODE, failure, success, isJsonMode } from './chunk-I3XQSSOT.mjs';
|
|
4
4
|
|
|
5
5
|
// src/progress.ts
|
|
6
6
|
var POLL_INTERVAL_MS = 1e3;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { promptYesNo } from './chunk-
|
|
2
|
+
import { promptYesNo } from './chunk-RZQTHTXX.mjs';
|
|
3
3
|
import { TOKEN_PURPOSE, REPO_PROVIDER, REPO_PROVIDER_VALUES } from './chunk-MXYUAJEW.mjs';
|
|
4
|
-
import { parseArgs, flagString, flagBool } from './chunk-
|
|
5
|
-
import { ApiClient } from './chunk-
|
|
6
|
-
import { readAuth, readProjectLink } from './chunk-
|
|
7
|
-
import { CliError, CLI_ERROR_CODE, isJsonMode, result, dim, success, info, bold } from './chunk-
|
|
4
|
+
import { parseArgs, flagString, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
5
|
+
import { ApiClient } from './chunk-D7WMSGKK.mjs';
|
|
6
|
+
import { readAuth, readProjectLink } from './chunk-LS2VTSMQ.mjs';
|
|
7
|
+
import { CliError, CLI_ERROR_CODE, isJsonMode, result, dim, success, info, bold } from './chunk-I3XQSSOT.mjs';
|
|
8
8
|
|
|
9
9
|
// src/commands/repo.ts
|
|
10
10
|
var SUB_PROVISION = "provision";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { CliError, CLI_ERROR_CODE } from './chunk-I3XQSSOT.mjs';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
|
|
5
|
+
var GIT_BINARY = "git";
|
|
6
|
+
var ENCODING_UTF8 = "utf8";
|
|
7
|
+
var REMOTE_DEFAULT = "origin";
|
|
8
|
+
var ARGS_STATUS_PORCELAIN = ["status", "--porcelain=v1"];
|
|
9
|
+
var ARGS_REV_PARSE_HEAD = ["rev-parse", "HEAD"];
|
|
10
|
+
var ARGS_REV_PARSE_ABBREV_REF = ["rev-parse", "--abbrev-ref", "HEAD"];
|
|
11
|
+
var ARGS_REV_PARSE_SHOW_TOPLEVEL = ["rev-parse", "--show-toplevel"];
|
|
12
|
+
var ARGS_REMOTE_GET_URL = ["remote", "get-url"];
|
|
13
|
+
var ARGS_PUSH = ["push"];
|
|
14
|
+
async function runGit(args, cwd) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const child = spawn(GIT_BINARY, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
17
|
+
const stdoutChunks = [];
|
|
18
|
+
const stderrChunks = [];
|
|
19
|
+
child.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
|
|
20
|
+
child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
21
|
+
child.on("error", (err) => {
|
|
22
|
+
reject(new CliError(CLI_ERROR_CODE.GIT_ERROR, `git not found: ${err.message}`));
|
|
23
|
+
});
|
|
24
|
+
child.on("close", (code) => {
|
|
25
|
+
resolve({
|
|
26
|
+
code: code ?? -1,
|
|
27
|
+
stdout: Buffer.concat(stdoutChunks).toString(ENCODING_UTF8),
|
|
28
|
+
stderr: Buffer.concat(stderrChunks).toString(ENCODING_UTF8)
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async function runGitOk(args, cwd) {
|
|
34
|
+
const { code, stdout, stderr } = await runGit(args, cwd);
|
|
35
|
+
if (code !== 0) {
|
|
36
|
+
throw new CliError(
|
|
37
|
+
CLI_ERROR_CODE.GIT_ERROR,
|
|
38
|
+
`git ${args.join(" ")} failed: ${stderr.trim() || stdout.trim() || `exit ${code}`}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return stdout.trimEnd();
|
|
42
|
+
}
|
|
43
|
+
async function gitStatusPorcelain(cwd) {
|
|
44
|
+
return runGitOk(ARGS_STATUS_PORCELAIN, cwd);
|
|
45
|
+
}
|
|
46
|
+
async function gitCurrentSha(cwd) {
|
|
47
|
+
return runGitOk(ARGS_REV_PARSE_HEAD, cwd);
|
|
48
|
+
}
|
|
49
|
+
async function gitCurrentBranch(cwd) {
|
|
50
|
+
return runGitOk(ARGS_REV_PARSE_ABBREV_REF, cwd);
|
|
51
|
+
}
|
|
52
|
+
async function gitDetectRoot(cwd) {
|
|
53
|
+
const { code, stdout } = await runGit(ARGS_REV_PARSE_SHOW_TOPLEVEL, cwd);
|
|
54
|
+
if (code !== 0) return null;
|
|
55
|
+
return stdout.trimEnd() || null;
|
|
56
|
+
}
|
|
57
|
+
async function gitGetRemoteUrl(cwd, name = REMOTE_DEFAULT) {
|
|
58
|
+
const { code, stdout } = await runGit([...ARGS_REMOTE_GET_URL, name], cwd);
|
|
59
|
+
if (code !== 0) return null;
|
|
60
|
+
return stdout.trimEnd() || null;
|
|
61
|
+
}
|
|
62
|
+
async function gitPush(cwd, branch) {
|
|
63
|
+
const args = branch ? [...ARGS_PUSH, REMOTE_DEFAULT, branch] : [...ARGS_PUSH];
|
|
64
|
+
await runGitOk(args, cwd);
|
|
65
|
+
}
|
|
66
|
+
async function gitPushToUrl(cwd, url, branch) {
|
|
67
|
+
await runGitOk([...ARGS_PUSH, url, branch], cwd);
|
|
68
|
+
}
|
|
69
|
+
var FREESTYLE_GIT_HOST = "git.freestyle.sh";
|
|
70
|
+
function isFreestyleRemote(url) {
|
|
71
|
+
if (!url) return false;
|
|
72
|
+
try {
|
|
73
|
+
return new URL(url).hostname === FREESTYLE_GIT_HOST;
|
|
74
|
+
} catch {
|
|
75
|
+
return url.includes(FREESTYLE_GIT_HOST);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { gitCurrentBranch, gitCurrentSha, gitDetectRoot, gitGetRemoteUrl, gitPush, gitPushToUrl, gitStatusPorcelain, isFreestyleRemote };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { isAutoYes, isInteractive, CliError, CLI_ERROR_CODE } from './chunk-
|
|
2
|
+
import { isAutoYes, isInteractive, CliError, CLI_ERROR_CODE } from './chunk-I3XQSSOT.mjs';
|
|
3
3
|
import readline from 'readline';
|
|
4
4
|
|
|
5
5
|
async function promptLine(question) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@cimplify/cli",
|
|
5
|
-
version: "0.
|
|
5
|
+
version: "0.3.0",
|
|
6
6
|
description: "Cimplify CLI \u2014 deploy, manage env vars, link projects, and scaffold storefronts",
|
|
7
7
|
keywords: [
|
|
8
8
|
"cimplify",
|
|
@@ -19,7 +19,7 @@ var package_default = {
|
|
|
19
19
|
"templates"
|
|
20
20
|
],
|
|
21
21
|
scripts: {
|
|
22
|
-
"bundle-assets": "bun scripts/bundle-assets.ts",
|
|
22
|
+
"bundle-assets": "bun scripts/bundle-assets.ts && bun scripts/bundle-docs.ts",
|
|
23
23
|
prebuild: "bun run bundle-assets",
|
|
24
24
|
build: "tsup",
|
|
25
25
|
"build:binary": "bun run bundle-assets && bun scripts/build-binaries.ts",
|
|
@@ -29,7 +29,7 @@ var package_default = {
|
|
|
29
29
|
prepublishOnly: "bun scripts/sync-template-pins.ts && bun run build",
|
|
30
30
|
dev: "bun run bundle-assets && tsup --watch",
|
|
31
31
|
typecheck: "bun run bundle-assets && tsgo --noEmit -p tsconfig.json",
|
|
32
|
-
clean: "rm -rf dist bin src/embedded-assets.ts",
|
|
32
|
+
clean: "rm -rf dist bin src/embedded-assets.ts src/embedded-docs.ts",
|
|
33
33
|
"lint:ox": "oxlint --fix .",
|
|
34
34
|
format: "oxfmt . --write",
|
|
35
35
|
"format:check": "oxfmt . --check",
|
|
@@ -1,87 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { pollDeployment } from './chunk-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { pollDeployment } from './chunk-MOZQODQS.mjs';
|
|
3
|
+
import { gitDetectRoot, gitStatusPorcelain, gitCurrentBranch, gitCurrentSha, gitGetRemoteUrl, isFreestyleRemote, gitPushToUrl, gitPush } from './chunk-RRY3NEZZ.mjs';
|
|
4
|
+
import { fetchCloneToken } from './chunk-QGBXGDA5.mjs';
|
|
5
|
+
import { promptYesNo } from './chunk-RZQTHTXX.mjs';
|
|
5
6
|
import { TOKEN_PURPOSE, ENV_SCOPE, DEPLOY_TRIGGER, DEPLOYMENT_STATUS } from './chunk-MXYUAJEW.mjs';
|
|
6
|
-
import { parseArgs, flagBool, flagString } from './chunk-
|
|
7
|
-
import { ApiClient } from './chunk-
|
|
8
|
-
import { readAuth, readProjectLink, writeProjectState } from './chunk-
|
|
9
|
-
import { CliError, CLI_ERROR_CODE, step, info, dim, success, result, EXIT_CODE } from './chunk-
|
|
10
|
-
import { spawn } from 'child_process';
|
|
11
|
-
|
|
12
|
-
var GIT_BINARY = "git";
|
|
13
|
-
var ENCODING_UTF8 = "utf8";
|
|
14
|
-
var REMOTE_DEFAULT = "origin";
|
|
15
|
-
var ARGS_STATUS_PORCELAIN = ["status", "--porcelain=v1"];
|
|
16
|
-
var ARGS_REV_PARSE_HEAD = ["rev-parse", "HEAD"];
|
|
17
|
-
var ARGS_REV_PARSE_ABBREV_REF = ["rev-parse", "--abbrev-ref", "HEAD"];
|
|
18
|
-
var ARGS_REV_PARSE_SHOW_TOPLEVEL = ["rev-parse", "--show-toplevel"];
|
|
19
|
-
var ARGS_REMOTE_GET_URL = ["remote", "get-url"];
|
|
20
|
-
var ARGS_PUSH = ["push"];
|
|
21
|
-
async function runGit(args, cwd) {
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
const child = spawn(GIT_BINARY, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
24
|
-
const stdoutChunks = [];
|
|
25
|
-
const stderrChunks = [];
|
|
26
|
-
child.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
|
|
27
|
-
child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
28
|
-
child.on("error", (err) => {
|
|
29
|
-
reject(new CliError(CLI_ERROR_CODE.GIT_ERROR, `git not found: ${err.message}`));
|
|
30
|
-
});
|
|
31
|
-
child.on("close", (code) => {
|
|
32
|
-
resolve({
|
|
33
|
-
code: code ?? -1,
|
|
34
|
-
stdout: Buffer.concat(stdoutChunks).toString(ENCODING_UTF8),
|
|
35
|
-
stderr: Buffer.concat(stderrChunks).toString(ENCODING_UTF8)
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
async function runGitOk(args, cwd) {
|
|
41
|
-
const { code, stdout, stderr } = await runGit(args, cwd);
|
|
42
|
-
if (code !== 0) {
|
|
43
|
-
throw new CliError(
|
|
44
|
-
CLI_ERROR_CODE.GIT_ERROR,
|
|
45
|
-
`git ${args.join(" ")} failed: ${stderr.trim() || stdout.trim() || `exit ${code}`}`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
return stdout.trimEnd();
|
|
49
|
-
}
|
|
50
|
-
async function gitStatusPorcelain(cwd) {
|
|
51
|
-
return runGitOk(ARGS_STATUS_PORCELAIN, cwd);
|
|
52
|
-
}
|
|
53
|
-
async function gitCurrentSha(cwd) {
|
|
54
|
-
return runGitOk(ARGS_REV_PARSE_HEAD, cwd);
|
|
55
|
-
}
|
|
56
|
-
async function gitCurrentBranch(cwd) {
|
|
57
|
-
return runGitOk(ARGS_REV_PARSE_ABBREV_REF, cwd);
|
|
58
|
-
}
|
|
59
|
-
async function gitDetectRoot(cwd) {
|
|
60
|
-
const { code, stdout } = await runGit(ARGS_REV_PARSE_SHOW_TOPLEVEL, cwd);
|
|
61
|
-
if (code !== 0) return null;
|
|
62
|
-
return stdout.trimEnd() || null;
|
|
63
|
-
}
|
|
64
|
-
async function gitGetRemoteUrl(cwd, name = REMOTE_DEFAULT) {
|
|
65
|
-
const { code, stdout } = await runGit([...ARGS_REMOTE_GET_URL, name], cwd);
|
|
66
|
-
if (code !== 0) return null;
|
|
67
|
-
return stdout.trimEnd() || null;
|
|
68
|
-
}
|
|
69
|
-
async function gitPush(cwd, branch) {
|
|
70
|
-
const args = branch ? [...ARGS_PUSH, REMOTE_DEFAULT, branch] : [...ARGS_PUSH];
|
|
71
|
-
await runGitOk(args, cwd);
|
|
72
|
-
}
|
|
73
|
-
async function gitPushToUrl(cwd, url, branch) {
|
|
74
|
-
await runGitOk([...ARGS_PUSH, url, branch], cwd);
|
|
75
|
-
}
|
|
76
|
-
var FREESTYLE_GIT_HOST = "git.freestyle.sh";
|
|
77
|
-
function isFreestyleRemote(url) {
|
|
78
|
-
if (!url) return false;
|
|
79
|
-
try {
|
|
80
|
-
return new URL(url).hostname === FREESTYLE_GIT_HOST;
|
|
81
|
-
} catch {
|
|
82
|
-
return url.includes(FREESTYLE_GIT_HOST);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
7
|
+
import { parseArgs, flagBool, flagString } from './chunk-C4M3DXKC.mjs';
|
|
8
|
+
import { ApiClient } from './chunk-D7WMSGKK.mjs';
|
|
9
|
+
import { readAuth, readProjectLink, writeProjectState } from './chunk-LS2VTSMQ.mjs';
|
|
10
|
+
import { CliError, CLI_ERROR_CODE, step, info, dim, success, result, EXIT_CODE } from './chunk-I3XQSSOT.mjs';
|
|
85
11
|
|
|
86
12
|
// src/commands/deploy.ts
|
|
87
13
|
var FLAG_PROD = "prod";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { parseEnvFile, formatEnvFile } from './chunk-
|
|
2
|
+
import { parseEnvFile, formatEnvFile } from './chunk-YI7UMMM7.mjs';
|
|
3
3
|
import { ENV_SCOPE, PUBLIC_ENV_PREFIX } from './chunk-MXYUAJEW.mjs';
|
|
4
|
-
import { parseArgs, flagBool } from './chunk-
|
|
5
|
-
import { ApiClient } from './chunk-
|
|
6
|
-
import { readAuth, readProjectLink } from './chunk-
|
|
7
|
-
import { info, CliError, CLI_ERROR_CODE, dim } from './chunk-
|
|
4
|
+
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
5
|
+
import { ApiClient } from './chunk-D7WMSGKK.mjs';
|
|
6
|
+
import { readAuth, readProjectLink } from './chunk-LS2VTSMQ.mjs';
|
|
7
|
+
import { info, CliError, CLI_ERROR_CODE, dim } from './chunk-I3XQSSOT.mjs';
|
|
8
8
|
import { spawn } from 'child_process';
|
|
9
9
|
import { promises } from 'fs';
|
|
10
10
|
import path from 'path';
|
package/dist/dispatcher.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { TEMPLATES } from './chunk-MHK4WVNF.mjs';
|
|
3
|
+
import { package_default } from './chunk-YQVMG62Z.mjs';
|
|
4
4
|
|
|
5
5
|
// src/dispatcher.ts
|
|
6
6
|
var VERSION = package_default.version ?? "unknown";
|
|
@@ -18,6 +18,12 @@ Project:
|
|
|
18
18
|
cimplify projects create <name> Create a Next.js project
|
|
19
19
|
cimplify link <project-id> Link CWD to a Cimplify project (writes .cimplify/project.json)
|
|
20
20
|
cimplify unlink Remove the local project link
|
|
21
|
+
cimplify introspect Snapshot the current storefront: auth, link, brand, mock, env, git
|
|
22
|
+
cimplify doctor [--offline] Run pre-flight checks; verdicts + fix hints (exit 1 on any fail)
|
|
23
|
+
cimplify explain [topic] Print canonical guidance on cart, products, bundles, errors, \u2026
|
|
24
|
+
cimplify assets upload <dir> Upload storefront brand assets to the Cimplify CDN
|
|
25
|
+
cimplify assets ls List uploaded assets from cimplify-assets.json
|
|
26
|
+
cimplify assets rm <key> Remove an asset entry from the manifest (remote blob stays)
|
|
21
27
|
|
|
22
28
|
Deploy:
|
|
23
29
|
cimplify deploy [flags] Push current SHA + trigger a build
|
|
@@ -82,7 +88,7 @@ Misc:
|
|
|
82
88
|
cimplify --version, -v Show CLI version
|
|
83
89
|
|
|
84
90
|
Init flags:
|
|
85
|
-
--template <name>, -t bakery (default) | restaurant | retail | services | grocery | fashion
|
|
91
|
+
--template <name>, -t bakery (default) | restaurant | retail | services | grocery | fashion | pharmacy | auto
|
|
86
92
|
Picks the storefront design.
|
|
87
93
|
|
|
88
94
|
Login flags:
|
|
@@ -115,24 +121,28 @@ Need the mock storefront server? It ships with @cimplify/sdk:
|
|
|
115
121
|
bunx @cimplify/sdk mock [flags] Boot the local Cimplify API mock
|
|
116
122
|
`;
|
|
117
123
|
var COMMANDS = {
|
|
118
|
-
login: () => import('./login-
|
|
119
|
-
logout: () => import('./logout-
|
|
120
|
-
whoami: () => import('./whoami-
|
|
121
|
-
projects: () => import('./projects-
|
|
122
|
-
link: () => import('./link-
|
|
123
|
-
unlink: () => import('./unlink-
|
|
124
|
-
deploy: () => import('./deploy-
|
|
125
|
-
rollback: () => import('./rollback-
|
|
126
|
-
env: () => import('./env-
|
|
127
|
-
domains: () => import('./domains-
|
|
128
|
-
logs: () => import('./logs-
|
|
129
|
-
status: () => import('./status-
|
|
130
|
-
dev: () => import('./dev-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
124
|
+
login: () => import('./login-WSAW4BEA.mjs'),
|
|
125
|
+
logout: () => import('./logout-DJDINVDF.mjs'),
|
|
126
|
+
whoami: () => import('./whoami-LACWBSNL.mjs'),
|
|
127
|
+
projects: () => import('./projects-364HGWHO.mjs'),
|
|
128
|
+
link: () => import('./link-X3E4UZBF.mjs'),
|
|
129
|
+
unlink: () => import('./unlink-HIIW57OO.mjs'),
|
|
130
|
+
deploy: () => import('./deploy-UKOOPJAE.mjs'),
|
|
131
|
+
rollback: () => import('./rollback-5YALPQXL.mjs'),
|
|
132
|
+
env: () => import('./env-EVMYQUIK.mjs'),
|
|
133
|
+
domains: () => import('./domains-JQMV6GAP.mjs'),
|
|
134
|
+
logs: () => import('./logs-KUKGEXR2.mjs'),
|
|
135
|
+
status: () => import('./status-W4HW3CX3.mjs'),
|
|
136
|
+
dev: () => import('./dev-FD4PM3UD.mjs'),
|
|
137
|
+
introspect: () => import('./introspect-PFBI3JHO.mjs'),
|
|
138
|
+
doctor: () => import('./doctor-5LBLYT7M.mjs'),
|
|
139
|
+
explain: () => import('./explain-3KBMWL6M.mjs'),
|
|
140
|
+
assets: () => import('./assets-DMK2QOPD.mjs'),
|
|
141
|
+
repo: () => import('./repo-26N2CHF6.mjs'),
|
|
142
|
+
list: () => import('./list-TE54SJIB.mjs'),
|
|
143
|
+
add: () => import('./add-ZJNXWN2B.mjs'),
|
|
144
|
+
update: () => import('./update-5MRKRVZC.mjs'),
|
|
145
|
+
upgrade: () => import('./update-5MRKRVZC.mjs')
|
|
136
146
|
};
|
|
137
147
|
var GLOBAL_FLAGS = /* @__PURE__ */ new Set(["--json", "--yes", "-y"]);
|
|
138
148
|
function extractGlobalFlags(argv) {
|
|
@@ -201,7 +211,9 @@ async function runInit(args) {
|
|
|
201
211
|
"retail",
|
|
202
212
|
"services",
|
|
203
213
|
"grocery",
|
|
204
|
-
"fashion"
|
|
214
|
+
"fashion",
|
|
215
|
+
"pharmacy",
|
|
216
|
+
"auto"
|
|
205
217
|
]);
|
|
206
218
|
let template = "bakery";
|
|
207
219
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { gatherIntrospection } from './chunk-5IAYN7AJ.mjs';
|
|
3
|
+
import './chunk-RRY3NEZZ.mjs';
|
|
4
|
+
import './chunk-YI7UMMM7.mjs';
|
|
5
|
+
import './chunk-YQVMG62Z.mjs';
|
|
6
|
+
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
7
|
+
import { ApiClient } from './chunk-D7WMSGKK.mjs';
|
|
8
|
+
import { readAuthOrNull } from './chunk-LS2VTSMQ.mjs';
|
|
9
|
+
import { bold, dim, info, result, isCliError, CLI_ERROR_CODE, red, yellow, green } from './chunk-I3XQSSOT.mjs';
|
|
10
|
+
import { promises } from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
|
|
13
|
+
var ENDPOINT_AUTH_ME = "/v1/auth/me";
|
|
14
|
+
var NON_BUN_LOCKFILES = ["package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
|
|
15
|
+
var BUN_LOCKFILES = ["bun.lock", "bun.lockb"];
|
|
16
|
+
function ok(name, message) {
|
|
17
|
+
return { name, level: "ok", message };
|
|
18
|
+
}
|
|
19
|
+
function warn(name, message, fix) {
|
|
20
|
+
return { name, level: "warn", message, fix };
|
|
21
|
+
}
|
|
22
|
+
function fail(name, message, fix) {
|
|
23
|
+
return { name, level: "fail", message, fix };
|
|
24
|
+
}
|
|
25
|
+
function skip(name, message) {
|
|
26
|
+
return { name, level: "skip", message };
|
|
27
|
+
}
|
|
28
|
+
async function pathExists(abs) {
|
|
29
|
+
try {
|
|
30
|
+
await promises.stat(abs);
|
|
31
|
+
return true;
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function detectLockfile(cwd) {
|
|
37
|
+
let bun = null;
|
|
38
|
+
for (const name of BUN_LOCKFILES) {
|
|
39
|
+
if (await pathExists(path.join(cwd, name))) {
|
|
40
|
+
bun = name;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let other = null;
|
|
45
|
+
for (const name of NON_BUN_LOCKFILES) {
|
|
46
|
+
if (await pathExists(path.join(cwd, name))) {
|
|
47
|
+
other = name;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { bun, other };
|
|
52
|
+
}
|
|
53
|
+
function deriveLocalChecks(snapshot, extras) {
|
|
54
|
+
const checks = [];
|
|
55
|
+
checks.push(ok("cli", snapshot.cli.version));
|
|
56
|
+
if (!snapshot.package.found) {
|
|
57
|
+
checks.push(
|
|
58
|
+
fail("package_json", "no package.json in this directory", "run from a Cimplify project root")
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
checks.push(ok("package_json", snapshot.package.name ?? "(unnamed)"));
|
|
62
|
+
if (!extras.nodeModules) {
|
|
63
|
+
checks.push(fail("node_modules", "missing \u2014 dependencies not installed", "run `bun install`"));
|
|
64
|
+
} else {
|
|
65
|
+
checks.push(ok("node_modules", "installed"));
|
|
66
|
+
}
|
|
67
|
+
if (extras.lockfile.bun) {
|
|
68
|
+
checks.push(ok("lockfile", extras.lockfile.bun));
|
|
69
|
+
} else if (extras.lockfile.other) {
|
|
70
|
+
checks.push(
|
|
71
|
+
warn(
|
|
72
|
+
"lockfile",
|
|
73
|
+
`${extras.lockfile.other} present \u2014 Cimplify expects bun`,
|
|
74
|
+
`delete ${extras.lockfile.other} and run \`bun install\``
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
} else {
|
|
78
|
+
checks.push(fail("lockfile", "no lockfile found", "run `bun install`"));
|
|
79
|
+
}
|
|
80
|
+
const pin = snapshot.package.sdk_pin;
|
|
81
|
+
if (!pin) {
|
|
82
|
+
checks.push(
|
|
83
|
+
fail(
|
|
84
|
+
"sdk_pin",
|
|
85
|
+
"@cimplify/sdk not in dependencies",
|
|
86
|
+
"run `bun add @cimplify/sdk`"
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
} else if (pin === "*" || pin === "latest") {
|
|
90
|
+
checks.push(
|
|
91
|
+
warn(
|
|
92
|
+
"sdk_pin",
|
|
93
|
+
`@cimplify/sdk pinned to '${pin}' \u2014 unpredictable`,
|
|
94
|
+
"pin to a specific minor (e.g. ^0.45.0)"
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
checks.push(ok("sdk_pin", `@cimplify/sdk ${pin}`));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (snapshot.brand.found) {
|
|
102
|
+
checks.push(ok("brand_file", `${snapshot.brand.path} \xB7 ${snapshot.brand.name ?? "(no name)"}`));
|
|
103
|
+
} else if (snapshot.package.found) {
|
|
104
|
+
checks.push(
|
|
105
|
+
warn(
|
|
106
|
+
"brand_file",
|
|
107
|
+
"no lib/brand.ts \u2014 content is not centralized",
|
|
108
|
+
"scaffold one via `cimplify init` or copy from a template"
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
} else {
|
|
112
|
+
checks.push(skip("brand_file", "no package.json \u2014 not a project root"));
|
|
113
|
+
}
|
|
114
|
+
if (snapshot.next_config.path === null) {
|
|
115
|
+
checks.push(skip("next_config", "no next.config \u2014 non-Next project?"));
|
|
116
|
+
} else if (snapshot.next_config.cache_components === true) {
|
|
117
|
+
checks.push(ok("next_config", "cacheComponents: true"));
|
|
118
|
+
} else if (snapshot.next_config.cache_components === false) {
|
|
119
|
+
checks.push(
|
|
120
|
+
fail(
|
|
121
|
+
"next_config",
|
|
122
|
+
"cacheComponents is explicitly false",
|
|
123
|
+
"set `cacheComponents: true` in next.config.ts \u2014 Cimplify templates rely on Next 16 cache primitives"
|
|
124
|
+
)
|
|
125
|
+
);
|
|
126
|
+
} else {
|
|
127
|
+
checks.push(
|
|
128
|
+
warn(
|
|
129
|
+
"next_config",
|
|
130
|
+
"cacheComponents not set",
|
|
131
|
+
"add `cacheComponents: true` to enable `'use cache'` + `cacheTag`"
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
if (snapshot.theme.globals_css_path === null) {
|
|
136
|
+
checks.push(skip("globals_css", "no app/globals.css"));
|
|
137
|
+
} else if (snapshot.theme.has_theme_block) {
|
|
138
|
+
checks.push(ok("globals_css", `${snapshot.theme.globals_css_path} \xB7 @theme block present`));
|
|
139
|
+
} else {
|
|
140
|
+
checks.push(
|
|
141
|
+
warn(
|
|
142
|
+
"globals_css",
|
|
143
|
+
`${snapshot.theme.globals_css_path} has no @theme block`,
|
|
144
|
+
"add an @theme block to customize tokens (Tailwind v4)"
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
if (snapshot.mock.seed) {
|
|
149
|
+
checks.push(ok("mock_seed", `seed: ${snapshot.mock.seed}`));
|
|
150
|
+
} else if (snapshot.package.found) {
|
|
151
|
+
checks.push(
|
|
152
|
+
warn(
|
|
153
|
+
"mock_seed",
|
|
154
|
+
"no `cimplify-mock --seed <industry>` in dev script",
|
|
155
|
+
"add `cimplify-mock --seed retail` to `scripts.dev`"
|
|
156
|
+
)
|
|
157
|
+
);
|
|
158
|
+
} else {
|
|
159
|
+
checks.push(skip("mock_seed", "no package.json"));
|
|
160
|
+
}
|
|
161
|
+
if (!snapshot.git) {
|
|
162
|
+
checks.push(skip("git", "not a git repo"));
|
|
163
|
+
} else if (snapshot.git.dirty) {
|
|
164
|
+
checks.push(
|
|
165
|
+
warn(
|
|
166
|
+
"git",
|
|
167
|
+
`working tree dirty on ${snapshot.git.branch ?? "(no branch)"}`,
|
|
168
|
+
"commit before `cimplify deploy` (or pass --allow-dirty)"
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
} else {
|
|
172
|
+
checks.push(ok("git", `${snapshot.git.branch ?? "(no branch)"} \xB7 clean`));
|
|
173
|
+
}
|
|
174
|
+
if (snapshot.auth.logged_in) {
|
|
175
|
+
checks.push(ok("auth_present", snapshot.auth.email ?? snapshot.auth.account_id ?? "logged in"));
|
|
176
|
+
} else {
|
|
177
|
+
checks.push(fail("auth_present", "not logged in", "run `cimplify login`"));
|
|
178
|
+
}
|
|
179
|
+
if (snapshot.project.linked) {
|
|
180
|
+
checks.push(ok("project_linked", snapshot.project.id ?? ""));
|
|
181
|
+
} else {
|
|
182
|
+
checks.push(
|
|
183
|
+
fail(
|
|
184
|
+
"project_linked",
|
|
185
|
+
".cimplify/project.json not present",
|
|
186
|
+
"run `cimplify link <project-id>` (or `cimplify projects create`)"
|
|
187
|
+
)
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
return checks;
|
|
191
|
+
}
|
|
192
|
+
async function runRemoteChecks(snapshot, auth) {
|
|
193
|
+
if (!auth) {
|
|
194
|
+
return {
|
|
195
|
+
authValid: skip("auth_valid", "not logged in"),
|
|
196
|
+
projectResolves: skip("project_resolves", "not logged in")
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const client = ApiClient.fromAuth(auth);
|
|
200
|
+
let authValid;
|
|
201
|
+
try {
|
|
202
|
+
const me = await client.get(ENDPOINT_AUTH_ME);
|
|
203
|
+
const env = auth.apiKey.startsWith("dk_test_") || auth.apiKey.startsWith("sk_test_") ? "test" : "live";
|
|
204
|
+
authValid = ok("auth_valid", `${env} token \xB7 business ${me.business_id}`);
|
|
205
|
+
} catch (err) {
|
|
206
|
+
if (isCliError(err) && err.code === CLI_ERROR_CODE.AUTH_FAILED) {
|
|
207
|
+
authValid = fail("auth_valid", "token rejected (401)", "run `cimplify login` again");
|
|
208
|
+
} else if (isCliError(err) && err.code === CLI_ERROR_CODE.NETWORK_ERROR) {
|
|
209
|
+
authValid = fail(
|
|
210
|
+
"auth_valid",
|
|
211
|
+
`cannot reach ${auth.apiBaseUrl}`,
|
|
212
|
+
"check connectivity or set CIMPLIFY_API_URL"
|
|
213
|
+
);
|
|
214
|
+
} else {
|
|
215
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
216
|
+
authValid = fail("auth_valid", msg);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
let projectResolves;
|
|
220
|
+
if (!snapshot.project.linked) {
|
|
221
|
+
projectResolves = skip("project_resolves", "no linked project");
|
|
222
|
+
} else if (authValid.level !== "ok") {
|
|
223
|
+
projectResolves = skip("project_resolves", "auth failed \u2014 cannot check");
|
|
224
|
+
} else {
|
|
225
|
+
const bid = encodeURIComponent(auth.businessId);
|
|
226
|
+
const pid = encodeURIComponent(snapshot.project.id ?? "");
|
|
227
|
+
try {
|
|
228
|
+
const p = await client.get(`/v1/businesses/${bid}/projects/${pid}`);
|
|
229
|
+
projectResolves = ok("project_resolves", `${p.name ?? p.id}`);
|
|
230
|
+
} catch (err) {
|
|
231
|
+
if (isCliError(err) && err.code === CLI_ERROR_CODE.NOT_FOUND) {
|
|
232
|
+
projectResolves = fail(
|
|
233
|
+
"project_resolves",
|
|
234
|
+
"project not found on server",
|
|
235
|
+
"run `cimplify projects ls` to see available projects, then `cimplify link <id>`"
|
|
236
|
+
);
|
|
237
|
+
} else {
|
|
238
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
239
|
+
projectResolves = fail("project_resolves", msg);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return { authValid, projectResolves };
|
|
244
|
+
}
|
|
245
|
+
function summarize(checks) {
|
|
246
|
+
const s = { total: checks.length, ok: 0, warn: 0, fail: 0, skip: 0 };
|
|
247
|
+
for (const c of checks) s[c.level]++;
|
|
248
|
+
return s;
|
|
249
|
+
}
|
|
250
|
+
async function gatherDoctorReport(opts = {}) {
|
|
251
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
252
|
+
const snapshot = await gatherIntrospection(cwd);
|
|
253
|
+
const [nodeModules, lockfile, auth] = await Promise.all([
|
|
254
|
+
pathExists(path.join(cwd, "node_modules")),
|
|
255
|
+
detectLockfile(cwd),
|
|
256
|
+
readAuthOrNull()
|
|
257
|
+
]);
|
|
258
|
+
const local = deriveLocalChecks(snapshot, { nodeModules, lockfile });
|
|
259
|
+
let checks;
|
|
260
|
+
if (opts.offline) {
|
|
261
|
+
checks = [
|
|
262
|
+
...local,
|
|
263
|
+
skip("auth_valid", "skipped (--offline)"),
|
|
264
|
+
skip("project_resolves", "skipped (--offline)")
|
|
265
|
+
];
|
|
266
|
+
} else {
|
|
267
|
+
const remote = await runRemoteChecks(snapshot, auth);
|
|
268
|
+
checks = [...local, remote.authValid, remote.projectResolves];
|
|
269
|
+
}
|
|
270
|
+
return { summary: summarize(checks), checks };
|
|
271
|
+
}
|
|
272
|
+
var LABEL_WIDTH = 18;
|
|
273
|
+
function levelGlyph(level) {
|
|
274
|
+
switch (level) {
|
|
275
|
+
case "ok":
|
|
276
|
+
return green("\u2713");
|
|
277
|
+
case "warn":
|
|
278
|
+
return yellow("!");
|
|
279
|
+
case "fail":
|
|
280
|
+
return red("\u2717");
|
|
281
|
+
case "skip":
|
|
282
|
+
return dim("-");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function renderDoctor(report) {
|
|
286
|
+
const out = [];
|
|
287
|
+
out.push(bold("Cimplify doctor"));
|
|
288
|
+
out.push("");
|
|
289
|
+
for (const c of report.checks) {
|
|
290
|
+
const name = bold(c.name.padEnd(LABEL_WIDTH));
|
|
291
|
+
out.push(` ${levelGlyph(c.level)} ${name}${c.message}`);
|
|
292
|
+
if (c.fix) {
|
|
293
|
+
out.push(` ${" ".repeat(LABEL_WIDTH + 2)}${dim(`\u2192 ${c.fix}`)}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
out.push("");
|
|
297
|
+
const s = report.summary;
|
|
298
|
+
const parts = [`${s.total} checks`, `${s.ok} ok`];
|
|
299
|
+
if (s.warn > 0) parts.push(`${s.warn} warn`);
|
|
300
|
+
if (s.fail > 0) parts.push(`${s.fail} fail`);
|
|
301
|
+
if (s.skip > 0) parts.push(`${s.skip} skip`);
|
|
302
|
+
out.push(dim(parts.join(" \xB7 ")));
|
|
303
|
+
return out;
|
|
304
|
+
}
|
|
305
|
+
async function run(argv) {
|
|
306
|
+
const args = parseArgs(argv);
|
|
307
|
+
const offline = flagBool(args, "offline");
|
|
308
|
+
const report = await gatherDoctorReport({ offline });
|
|
309
|
+
for (const line of renderDoctor(report)) info(line);
|
|
310
|
+
result(report);
|
|
311
|
+
if (report.summary.fail > 0) process.exit(1);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export { run as default, deriveLocalChecks, gatherDoctorReport, renderDoctor };
|