@dashai/cli 0.24.0 → 0.25.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/README.md +1 -1
- package/dist/bin.js +231 -38
- package/dist/bin.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
package/dist/bin.js
CHANGED
|
@@ -112,6 +112,12 @@ function resolveApiUrl() {
|
|
|
112
112
|
if (cfg?.apiUrl) return cfg.apiUrl.replace(/\/+$/, "");
|
|
113
113
|
return DEFAULT_API_URL;
|
|
114
114
|
}
|
|
115
|
+
function resolveExplicitApiUrl() {
|
|
116
|
+
const fromEnv = process.env.DASHWISE_API_URL?.trim();
|
|
117
|
+
if (fromEnv) return fromEnv.replace(/\/+$/, "");
|
|
118
|
+
const cfg = safeReadConfig();
|
|
119
|
+
return cfg?.apiUrl ? cfg.apiUrl.replace(/\/+$/, "") : null;
|
|
120
|
+
}
|
|
115
121
|
function readSavedToken() {
|
|
116
122
|
const cfg = safeReadConfig();
|
|
117
123
|
return cfg?.token ?? null;
|
|
@@ -1634,7 +1640,7 @@ var init_simple = __esm({
|
|
|
1634
1640
|
typescript: "^5.5.0"
|
|
1635
1641
|
},
|
|
1636
1642
|
engines: {
|
|
1637
|
-
node: "22.x"
|
|
1643
|
+
node: "22.x || 24.x"
|
|
1638
1644
|
}
|
|
1639
1645
|
},
|
|
1640
1646
|
"node_modules/@dashai/sdk": {
|
|
@@ -2679,7 +2685,7 @@ var init_custom = __esm({
|
|
|
2679
2685
|
typescript: "^5.5.0"
|
|
2680
2686
|
},
|
|
2681
2687
|
engines: {
|
|
2682
|
-
node: "22.x"
|
|
2688
|
+
node: "22.x || 24.x"
|
|
2683
2689
|
}
|
|
2684
2690
|
},
|
|
2685
2691
|
"node_modules/@alloc/quick-lru": {
|
|
@@ -10017,9 +10023,10 @@ function packageJson(opts) {
|
|
|
10017
10023
|
version: "0.0.1",
|
|
10018
10024
|
private: true,
|
|
10019
10025
|
type: "module",
|
|
10020
|
-
engines: { node:
|
|
10026
|
+
engines: { node: NODE_ENGINES },
|
|
10021
10027
|
scripts: {
|
|
10022
|
-
dev: "dashwise
|
|
10028
|
+
dev: "dashwise dev",
|
|
10029
|
+
"dev:watch": "dashwise module dev",
|
|
10023
10030
|
"dev:next": "next dev",
|
|
10024
10031
|
"dashwise:generate": "dashwise module generate",
|
|
10025
10032
|
typecheck: "tsc --noEmit",
|
|
@@ -10235,7 +10242,7 @@ function appPageTsx(opts) {
|
|
|
10235
10242
|
Module slug: <code>${escapeHtml(opts.slug)}</code>
|
|
10236
10243
|
</p>
|
|
10237
10244
|
<p style={{ marginTop: 24, color: '#64748b', fontSize: 14 }}>
|
|
10238
|
-
Run <code>
|
|
10245
|
+
Run <code>npm run dev</code> to start the app and the watch loop.
|
|
10239
10246
|
<br />
|
|
10240
10247
|
Edit <code>module.json</code> to add tables; regenerated types
|
|
10241
10248
|
land in <code>@dashai/generated</code>.
|
|
@@ -10269,7 +10276,7 @@ debugger to Next), use the legacy two-terminal flow:
|
|
|
10269
10276
|
|
|
10270
10277
|
\`\`\`bash
|
|
10271
10278
|
dashwise module generate # produces node_modules/@dashai/generated/
|
|
10272
|
-
|
|
10279
|
+
npm run dev:watch # watch module.json + auto-regenerate
|
|
10273
10280
|
npm run dev:next # plain Next.js dev server (in another terminal)
|
|
10274
10281
|
\`\`\`
|
|
10275
10282
|
|
|
@@ -10314,7 +10321,7 @@ debugger to Next), use the legacy two-terminal flow:
|
|
|
10314
10321
|
|
|
10315
10322
|
\`\`\`bash
|
|
10316
10323
|
dashwise module generate # produces node_modules/@dashai/generated/
|
|
10317
|
-
|
|
10324
|
+
npm run dev:watch # watch + regen on module.json save (terminal 1)
|
|
10318
10325
|
npm run dev:next # next dev on :3000 (terminal 2)
|
|
10319
10326
|
\`\`\`
|
|
10320
10327
|
|
|
@@ -11119,9 +11126,10 @@ function packageJsonCustom(opts) {
|
|
|
11119
11126
|
version: "0.0.1",
|
|
11120
11127
|
private: true,
|
|
11121
11128
|
type: "module",
|
|
11122
|
-
engines: { node:
|
|
11129
|
+
engines: { node: NODE_ENGINES },
|
|
11123
11130
|
scripts: {
|
|
11124
|
-
dev: "dashwise
|
|
11131
|
+
dev: "dashwise dev",
|
|
11132
|
+
"dev:watch": "dashwise module dev",
|
|
11125
11133
|
"dev:next": "next dev",
|
|
11126
11134
|
"dashwise:generate": "dashwise module generate",
|
|
11127
11135
|
typecheck: "tsc --noEmit",
|
|
@@ -12208,7 +12216,7 @@ in this Dashwise module. Read this before making changes.
|
|
|
12208
12216
|
|
|
12209
12217
|
Every table declares exactly one primary field (the row's name everywhere in Dashwise).
|
|
12210
12218
|
|
|
12211
|
-
${opts.cloudReady === false ? "" : cloudAgentInstructions()}
|
|
12219
|
+
${opts.cloudReady === false ? "" : cloudAgentInstructions() + "\n" + claudeCloudNote(opts.apiUrl)}
|
|
12212
12220
|
## What this module is
|
|
12213
12221
|
|
|
12214
12222
|
A Dashwise ${isCustom ? "**custom Next.js** module (full app runtime, machine-class)" : "**hand-authored simple** module (isolate runtime)"} authored against \`@dashai/sdk\`.
|
|
@@ -12745,15 +12753,145 @@ primary_region = "iad"
|
|
|
12745
12753
|
`;
|
|
12746
12754
|
}
|
|
12747
12755
|
function cloudAgentInstructions() {
|
|
12748
|
-
return `##
|
|
12756
|
+
return `## Default way of working
|
|
12757
|
+
|
|
12758
|
+
These are defaults. When the person you work for says otherwise (in the chat,
|
|
12759
|
+
or in their own \`CLAUDE.md\` / \`AGENTS.md\`), follow them instead.
|
|
12760
|
+
|
|
12761
|
+
- Assume the person is not a developer. Before and after each step, say in one
|
|
12762
|
+
or two plain sentences what you are doing and why, for example "I'm saving
|
|
12763
|
+
your changes so Dashwise can see them." When a term like branch or pull
|
|
12764
|
+
request is unavoidable, explain it in a few words.
|
|
12765
|
+
- You handle git. Get the finished work onto the repository's default branch
|
|
12766
|
+
(usually \`main\`) yourself, so the person, Dashwise and the next agent all
|
|
12767
|
+
see the latest version. The person needs no git, branch or pull request
|
|
12768
|
+
knowledge:
|
|
12769
|
+
- Working locally on the person's computer: commit on the default branch and push it.
|
|
12770
|
+
- Working in the cloud (Codex cloud, Claude Code on the web): if your tool
|
|
12771
|
+
lets you push to the default branch or merge your own pull request, do it
|
|
12772
|
+
once the checks pass. If it only lets you push a branch, push it and tell the
|
|
12773
|
+
person in plain words that the changes are saved and that Release in
|
|
12774
|
+
Dashwise includes them. Don't ask them to merge anything.
|
|
12775
|
+
- Never force-push and never rewrite the default branch's history.
|
|
12776
|
+
- The person only confirms Release and Take live in Dashwise. When the work is
|
|
12777
|
+
pushed, tell them it is ready: in Dashwise open the module, click Release,
|
|
12778
|
+
then Take live.
|
|
12779
|
+
|
|
12780
|
+
## Cloud workflow
|
|
12749
12781
|
|
|
12750
12782
|
- Read \`module.json\`, the task and \`spec.md\` first. Preserve module identity and permission checks.
|
|
12751
|
-
- Use Node 22
|
|
12783
|
+
- Use Node 22 or 24 (\`.nvmrc\` prefers 22; Codex's default 24 works too). From the repository root run \`bash scripts/cloud-setup.sh\`.
|
|
12752
12784
|
- After edits run \`npm run typecheck\`, \`npm test\`, \`npm run build\`, then \`npm run smoke:production\`. Add behavior tests for your changes. A dev server does not prove production readiness.
|
|
12753
12785
|
- Update \`spec.md\` for behavior changes and \`agent-log.md\` in the same commit. Read \`CLAUDE.md\` for SDK, authorization and UI conventions.
|
|
12754
|
-
-
|
|
12755
|
-
-
|
|
12786
|
+
- \`npm run smoke:production\` starts the built app on a local loopback port. If a cloud sandbox refuses that port, rerun the command with the network permission; never skip the check.
|
|
12787
|
+
- Report what you changed, the pushed SHA and the checks you ran, including failures, in plain words.
|
|
12788
|
+
- Never print, persist or commit secrets. Repository code delivery needs no Dashwise token. Do not log in or access company data for setup or checks; see "Dashwise login" for full development.
|
|
12756
12789
|
- Never automatically release, publish, deploy or take an installation live. Release and Live require an explicit human action.
|
|
12790
|
+
- Even when the person says you may release, you can't do it for them: tell them in one sentence where to click (in Dashwise open the module, click Release, then Take live). Never ask for a \`dashwise login\` or a token just to release.
|
|
12791
|
+
|
|
12792
|
+
## If you can't see the repository
|
|
12793
|
+
|
|
12794
|
+
Connecting GitHub in the AI tool is not enough for a private repository. Tell
|
|
12795
|
+
the person, in plain words, to also install the tool's GitHub app on the GitHub
|
|
12796
|
+
organisation that owns this repository and give it access to this repository
|
|
12797
|
+
(an organisation owner may have to approve it), then start the task again:
|
|
12798
|
+
|
|
12799
|
+
- Claude: the Claude GitHub app, https://github.com/apps/claude
|
|
12800
|
+
- Codex: the ChatGPT Codex Connector, https://github.com/apps/chatgpt-codex-connector
|
|
12801
|
+
|
|
12802
|
+
## Dashwise login (only for full development)
|
|
12803
|
+
|
|
12804
|
+
The checks (\`npm run typecheck\`, \`npm test\`, \`npm run build\`,
|
|
12805
|
+
\`npm run smoke:production\`) need no login. Full Dashwise development does:
|
|
12806
|
+
\`npm run dev\` (\`dashwise dev\`: the app plus the watcher), \`dashwise module
|
|
12807
|
+
generate\` and the schema commands. When the task needs them:
|
|
12808
|
+
|
|
12809
|
+
- If \`dashwise\` is not installed, run \`npm install -g @dashai/cli@latest\`.
|
|
12810
|
+
- Ask the person once, in plain words, for example: "To run your module
|
|
12811
|
+
against Dashwise I need to sign in as you. I'll show you a code and a link;
|
|
12812
|
+
open the link and approve." Then run \`dashwise login --no-prompt\` and show
|
|
12813
|
+
them the code and link it prints. The login acts with the person's own rights.
|
|
12814
|
+
- Keep the login outside the repository. In the cloud, run CLI commands with
|
|
12815
|
+
\`XDG_CONFIG_HOME=/tmp/dashwise-config\` so the saved login lands in
|
|
12816
|
+
\`/tmp\`, never in the checkout.
|
|
12817
|
+
- Never write a token into a script, a file in the repository, a commit, an
|
|
12818
|
+
environment setup script or snapshot, or a log.
|
|
12819
|
+
- In the cloud, run CLI commands with \`NODE_USE_ENV_PROXY=1\` so the CLI
|
|
12820
|
+
uses the environment's network proxy (newer CLI versions do this on their own).
|
|
12821
|
+
- A cloud environment forgets the login when it restarts; ask again only when
|
|
12822
|
+
a command reports that the login is missing.
|
|
12823
|
+
`;
|
|
12824
|
+
}
|
|
12825
|
+
function companyApiHost(apiUrl) {
|
|
12826
|
+
if (!apiUrl) return null;
|
|
12827
|
+
try {
|
|
12828
|
+
const host = new URL(apiUrl).host;
|
|
12829
|
+
return host in HOSTED_API_HOSTS ? host : null;
|
|
12830
|
+
} catch {
|
|
12831
|
+
return null;
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
function apiHostLine(apiUrl) {
|
|
12835
|
+
const host = companyApiHost(apiUrl);
|
|
12836
|
+
return host ? `\`${host}\` (this company's Dashwise API; the company uses Dashwise at ${HOSTED_API_HOSTS[host]})` : "the company's Dashwise API host: `api.dashwise.net` if the person opens Dashwise at app.dashwise.net, `api.dashwise.dev` if at app.dashwise.dev. If you can't tell, ask them which address they use";
|
|
12837
|
+
}
|
|
12838
|
+
function codexEnvironmentInstructions(apiUrl) {
|
|
12839
|
+
const host = companyApiHost(apiUrl);
|
|
12840
|
+
const apiUrlValue = host ? `https://${host}` : "https://<the company API host above>";
|
|
12841
|
+
return `## Codex cloud environment
|
|
12842
|
+
|
|
12843
|
+
When the person asks you to set up the Codex cloud environment for this
|
|
12844
|
+
repository, use exactly these settings. Show each one to the person and say in
|
|
12845
|
+
one sentence what it is for.
|
|
12846
|
+
|
|
12847
|
+
| Setting | Value |
|
|
12848
|
+
|---|---|
|
|
12849
|
+
| Node.js | 22 or 24 (24 is Codex's default and works; \`.nvmrc\` prefers 22) |
|
|
12850
|
+
| Setup script | \`if [ -f scripts/cloud-setup.sh ]; then bash scripts/cloud-setup.sh; else echo "No Dashwise template yet, setup skipped"; fi\` |
|
|
12851
|
+
| Agent internet access | On: keep the "package managers" preset and add only the company's Dashwise API host (below) |
|
|
12852
|
+
| Environment variables | \`DASHWISE_API_URL=${apiUrlValue}\`, \`NODE_USE_ENV_PROXY=1\` |
|
|
12853
|
+
| Secrets | none |
|
|
12854
|
+
|
|
12855
|
+
Set the network access before you start the setup, so the first run can
|
|
12856
|
+
already install packages. The preset covers npm and GitHub; the one added
|
|
12857
|
+
domain is:
|
|
12858
|
+
|
|
12859
|
+
- ${apiHostLine(apiUrl)}
|
|
12860
|
+
|
|
12861
|
+
The module and the CLI talk to the company's Dashwise API. Do not add other
|
|
12862
|
+
Dashwise hosts. If the environment offers no preset, allow exactly
|
|
12863
|
+
${CLOUD_ALLOWED_HOSTS.map((h) => `\`${h}\``).join(", ")} plus that host.
|
|
12864
|
+
|
|
12865
|
+
The setup script checks Node 22 or 24 and installs the exact dependencies with
|
|
12866
|
+
\`npm ci\`. The guard lets a first run pass while the repository holds only a
|
|
12867
|
+
README.
|
|
12868
|
+
|
|
12869
|
+
Never add secrets: no \`dwk_\` module key, no \`dwc_\` CLI token and no password,
|
|
12870
|
+
and never put a \`dashwise login\` into the setup script. Delivering code needs
|
|
12871
|
+
none of them; for full development see "Dashwise login".
|
|
12872
|
+
|
|
12873
|
+
To check the environment, run \`npm run typecheck\`, \`npm test\`,
|
|
12874
|
+
\`npm run build\` and \`npm run smoke:production\`. If one fails because of a
|
|
12875
|
+
setting, fix the setting; otherwise report the failure in plain words.
|
|
12876
|
+
|
|
12877
|
+
If the repository has no \`package.json\` yet (only a README), skip these
|
|
12878
|
+
checks: the setup script already skipped installing, and the first task adds
|
|
12879
|
+
the template. Tell the person the settings are ready.
|
|
12880
|
+
|
|
12881
|
+
When the checks pass, or were skipped for a README-only repository, tell the
|
|
12882
|
+
person: "The environment works. Click Publish to save it for your next tasks."
|
|
12883
|
+
Publishing is their click.
|
|
12884
|
+
`;
|
|
12885
|
+
}
|
|
12886
|
+
function claudeCloudNote(apiUrl) {
|
|
12887
|
+
const host = companyApiHost(apiUrl);
|
|
12888
|
+
return `## Claude cloud
|
|
12889
|
+
|
|
12890
|
+
Claude Code on the web has no environment setup chat. It reads this repository
|
|
12891
|
+
and \`CLAUDE.md\`, and \`.claude/settings.json\` runs \`scripts/cloud-setup.sh\`
|
|
12892
|
+
when a cloud session starts. Node 22 or 24 both work. If
|
|
12893
|
+
the environment has a network setting, allow the same domains as for Codex:
|
|
12894
|
+
${CLOUD_ALLOWED_HOSTS.map((h) => `\`${h}\``).join(", ")} and ${host ? `\`${host}\`` : "the company's Dashwise API host (`api.dashwise.net` for app.dashwise.net, `api.dashwise.dev` for app.dashwise.dev)"}. No secrets.
|
|
12757
12895
|
`;
|
|
12758
12896
|
}
|
|
12759
12897
|
function agentsMd(opts) {
|
|
@@ -12761,7 +12899,7 @@ function agentsMd(opts) {
|
|
|
12761
12899
|
|
|
12762
12900
|
Every table declares exactly one primary field (the row's name everywhere in Dashwise).
|
|
12763
12901
|
|
|
12764
|
-
` + cloudAgentInstructions();
|
|
12902
|
+
` + cloudAgentInstructions() + "\n" + codexEnvironmentInstructions(opts.apiUrl) + "\n" + claudeCloudNote(opts.apiUrl);
|
|
12765
12903
|
}
|
|
12766
12904
|
function nodeVersion() {
|
|
12767
12905
|
return "22\n";
|
|
@@ -12783,9 +12921,12 @@ fi
|
|
|
12783
12921
|
repo_root="$(cd -- "$(dirname -- "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
12784
12922
|
cd "$repo_root"
|
|
12785
12923
|
fail() { printf 'cloud-setup: %s\\n' "$1" >&2; exit 1; }
|
|
12786
|
-
command -v node >/dev/null 2>&1 || fail 'Node 22 is required. Select Node 22 in your cloud environment, then retry.'
|
|
12787
|
-
|
|
12788
|
-
|
|
12924
|
+
command -v node >/dev/null 2>&1 || fail 'Node 22 or 24 is required. Select Node 22 or 24 in your cloud environment, then retry.'
|
|
12925
|
+
case "$(node -p 'process.versions.node.split(".")[0]')" in
|
|
12926
|
+
22|24) ;;
|
|
12927
|
+
*) fail 'Node 22 or 24 is required. Select Node 22 or 24 in your cloud environment, then retry. A subshell-only runtime change will not persist into agent commands.' ;;
|
|
12928
|
+
esac
|
|
12929
|
+
command -v npm >/dev/null 2>&1 || fail 'npm is required with Node 22 or 24.'
|
|
12789
12930
|
[[ -f package-lock.json && -f package.json ]] || fail 'Missing package.json or committed package-lock.json. Run this from a complete repository checkout.'
|
|
12790
12931
|
|
|
12791
12932
|
# Only the Claude startup/resume path reuses an unchanged install. Explicit
|
|
@@ -12793,15 +12934,21 @@ command -v npm >/dev/null 2>&1 || fail 'npm is required with Node 22.'
|
|
|
12793
12934
|
stamp="$(node --input-type=module -e 'import {createHash} from "node:crypto"; import {readFileSync} from "node:fs"; const hash=createHash("sha256"); for (const path of ["package.json", "package-lock.json", "scripts/cloud-setup.sh"]) hash.update(readFileSync(path)); hash.update(process.version); hash.update(process.platform); hash.update(process.arch); process.stdout.write(hash.digest("hex"));')"
|
|
12794
12935
|
stamp_file="node_modules/.dashwise-cloud-setup"
|
|
12795
12936
|
if [[ "\${1:-}" == "--claude" && -f "$stamp_file" && "$(cat "$stamp_file")" == "$stamp" && -x node_modules/.bin/next && -x node_modules/.bin/tsc && -f node_modules/@dashai/sdk/package.json ]]; then
|
|
12796
|
-
printf 'cloud-setup: dependencies already match Node
|
|
12937
|
+
printf 'cloud-setup: dependencies already match this Node version and the lockfile.\\n'
|
|
12797
12938
|
exit 0
|
|
12798
12939
|
fi
|
|
12799
12940
|
# Keep install output out of session logs: third-party lifecycle scripts may
|
|
12800
12941
|
# echo environment variables. npm's own detailed logs stay in its local cache.
|
|
12801
12942
|
rm -f "$stamp_file"
|
|
12802
|
-
|
|
12943
|
+
# Some sandboxes mount HOME read-only; npm then cannot write its cache.
|
|
12944
|
+
npm_cache="\${npm_config_cache:-\${HOME:-}/.npm}"
|
|
12945
|
+
if ! { mkdir -p "$npm_cache" 2>/dev/null && [[ -w "$npm_cache" ]]; }; then
|
|
12946
|
+
export npm_config_cache="\${TMPDIR:-/tmp}/npm-cache"
|
|
12947
|
+
printf 'cloud-setup: %s is not writable, using %s for the npm cache.\\n' "$npm_cache" "$npm_config_cache"
|
|
12948
|
+
fi
|
|
12949
|
+
npm ci --include=dev --no-audit --no-fund > /dev/null 2>&1 || fail 'npm ci failed. Check the committed lockfile, Node 22 or 24 and network access to registry.npmjs.org. Review npm logs privately; never paste credentials.'
|
|
12803
12950
|
printf '%s' "$stamp" > "$stamp_file"
|
|
12804
|
-
printf 'cloud-setup: dependencies installed with Node
|
|
12951
|
+
printf 'cloud-setup: dependencies installed with Node %s.\\n' "$(node -p 'process.versions.node')"
|
|
12805
12952
|
`;
|
|
12806
12953
|
}
|
|
12807
12954
|
function claudeSettingsJson() {
|
|
@@ -12957,7 +13104,7 @@ function cloudReadme() {
|
|
|
12957
13104
|
return `
|
|
12958
13105
|
## Cloud builders
|
|
12959
13106
|
|
|
12960
|
-
Use Node 22 (the root runtime pins) and run \`bash scripts/cloud-setup.sh\`.
|
|
13107
|
+
Use Node 22 (the root runtime pins; 24 also works) and run \`bash scripts/cloud-setup.sh\`.
|
|
12961
13108
|
Commit \`package-lock.json\` after any dependency change; setup uses \`npm ci\`.
|
|
12962
13109
|
Checks: \`npm run typecheck\`, \`npm test\`, \`npm run build\`, \`npm run smoke:production\`.
|
|
12963
13110
|
The smoke command starts the built server, probes anonymous API denial and stops
|
|
@@ -12966,33 +13113,49 @@ The example uses \`lib/items.ts\` directly against the SDK, so a fresh checkout
|
|
|
12966
13113
|
can build without authenticated code generation. Keep it aligned with the
|
|
12967
13114
|
example table, or replace it when you author your schema.
|
|
12968
13115
|
|
|
12969
|
-
Codex:
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
13116
|
+
Codex: \`AGENTS.md\` \u2192 "Codex cloud environment" lists the exact settings
|
|
13117
|
+
(Node 22 or 24, setup script, network, \`DASHWISE_API_URL\`, no secrets);
|
|
13118
|
+
Codex's environment setup chat can follow it, then you click Publish. GitHub
|
|
13119
|
+
authorization is configured in the provider: install the ChatGPT Codex
|
|
13120
|
+
Connector on your GitHub organisation so Codex can see a private repository.
|
|
12973
13121
|
|
|
12974
13122
|
Claude Code web: \`.claude/settings.json\` ships a cloud-only SessionStart
|
|
12975
13123
|
hook for startup/resume. It calls \`bash "$CLAUDE_PROJECT_DIR"/scripts/cloud-setup.sh --claude\`;
|
|
12976
13124
|
local sessions skip installation and unchanged cloud installs reuse dependencies.
|
|
12977
|
-
Select Node 22 in the environment; do not rely on a setup subshell changing the
|
|
13125
|
+
Select Node 22 or 24 in the environment; do not rely on a setup subshell changing the
|
|
12978
13126
|
runtime of later agent commands. The same script can be used in the environment
|
|
12979
13127
|
setup field. Allow \`registry.npmjs.org\` for installs (Claude's Trusted list).
|
|
12980
13128
|
The [official hook recipe](https://code.claude.com/docs/en/cloud-environments#install-dependencies-with-a-sessionstart-hook)
|
|
12981
13129
|
explains startup and cache behavior.
|
|
12982
13130
|
|
|
12983
|
-
Read \`AGENTS.md\` / \`CLAUDE.md
|
|
12984
|
-
|
|
13131
|
+
Read \`AGENTS.md\` / \`CLAUDE.md\`. By default agents get the work onto the
|
|
13132
|
+
default branch themselves and explain each step in plain words; Release in
|
|
13133
|
+
Dashwise includes work an agent could only push to a branch. Release and Live
|
|
13134
|
+
remain human actions. No Dashwise token is needed for
|
|
13135
|
+
repository code delivery.
|
|
12985
13136
|
`;
|
|
12986
13137
|
}
|
|
12987
|
-
var DEPLOY_TARGETS, SCAFFOLD_DEFAULT_API_URL, MODULE_SLUG_REGEX;
|
|
13138
|
+
var NODE_ENGINES, DEPLOY_TARGETS, SCAFFOLD_DEFAULT_API_URL, MODULE_SLUG_REGEX, CLOUD_ALLOWED_HOSTS, HOSTED_API_HOSTS;
|
|
12988
13139
|
var init_scaffold = __esm({
|
|
12989
13140
|
"src/lib/scaffold.ts"() {
|
|
12990
13141
|
init_sdk_version();
|
|
12991
13142
|
init_simple();
|
|
12992
13143
|
init_custom();
|
|
13144
|
+
NODE_ENGINES = "22.x || 24.x";
|
|
12993
13145
|
DEPLOY_TARGETS = ["railway", "vercel", "fly"];
|
|
12994
13146
|
SCAFFOLD_DEFAULT_API_URL = "http://localhost:3000";
|
|
12995
13147
|
MODULE_SLUG_REGEX = /^[a-z]([a-z0-9-]*[a-z0-9])?$/;
|
|
13148
|
+
CLOUD_ALLOWED_HOSTS = [
|
|
13149
|
+
"registry.npmjs.org",
|
|
13150
|
+
"github.com",
|
|
13151
|
+
"api.github.com",
|
|
13152
|
+
"raw.githubusercontent.com",
|
|
13153
|
+
"codeload.github.com"
|
|
13154
|
+
];
|
|
13155
|
+
HOSTED_API_HOSTS = {
|
|
13156
|
+
"api.dashwise.dev": "app.dashwise.dev",
|
|
13157
|
+
"api.dashwise.net": "app.dashwise.net"
|
|
13158
|
+
};
|
|
12996
13159
|
}
|
|
12997
13160
|
});
|
|
12998
13161
|
function isFreshCloneEntry(name) {
|
|
@@ -13070,7 +13233,7 @@ function canAdoptCloudFiles(dir, templatePackage) {
|
|
|
13070
13233
|
if (lock.lockfileVersion !== 2 && lock.lockfileVersion !== 3 || !root) {
|
|
13071
13234
|
return false;
|
|
13072
13235
|
}
|
|
13073
|
-
if (pkg.engines?.node !== "22.x" || !pkg.scripts || !expected.scripts) {
|
|
13236
|
+
if (pkg.engines?.node !== "22.x" && pkg.engines?.node !== expected.engines?.node || !pkg.scripts || !expected.scripts) {
|
|
13074
13237
|
return false;
|
|
13075
13238
|
}
|
|
13076
13239
|
for (const script of ["typecheck", "test", "build", "start", "smoke:production"]) {
|
|
@@ -13173,12 +13336,14 @@ async function moduleInitCommand(slugArg, options) {
|
|
|
13173
13336
|
const templatePackage = (kind === "custom" ? packageJsonCustom : packageJson)({
|
|
13174
13337
|
slug});
|
|
13175
13338
|
const cloudReady = writeMode === "all" || canAdoptCloudFiles(dir, templatePackage);
|
|
13339
|
+
const companyApiUrl = resolveExplicitApiUrl();
|
|
13176
13340
|
const scaffoldOpts = {
|
|
13177
13341
|
cloudReady,
|
|
13178
13342
|
slug,
|
|
13179
13343
|
name,
|
|
13180
13344
|
kind,
|
|
13181
|
-
...options.git !== void 0 ? { repositoryUrl: options.git } : {}
|
|
13345
|
+
...options.git !== void 0 ? { repositoryUrl: options.git } : {},
|
|
13346
|
+
...companyApiUrl !== null ? { apiUrl: companyApiUrl } : {}
|
|
13182
13347
|
};
|
|
13183
13348
|
const scaffoldApiUrl = resolveApiUrl();
|
|
13184
13349
|
const files = [
|
|
@@ -13376,7 +13541,7 @@ async function moduleInitCommand(slugArg, options) {
|
|
|
13376
13541
|
|
|
13377
13542
|
${dim(" (or, for the two-terminal flow:")}
|
|
13378
13543
|
${dim(" dashwise module generate")} ${dim("# materialize typed wrappers")}
|
|
13379
|
-
${dim("
|
|
13544
|
+
${dim(" npm run dev:watch")} ${dim("# watch + auto-regenerate")}
|
|
13380
13545
|
${dim(" npm run dev:next # next dev on :3000)")}
|
|
13381
13546
|
${devInstall ? `
|
|
13382
13547
|
${dim(`Dev installation id=${devInstall.installation.id}; API key expires ${devInstall.api_key_expires_at}.`)}
|
|
@@ -14721,6 +14886,26 @@ var init_set_type = __esm({
|
|
|
14721
14886
|
}
|
|
14722
14887
|
});
|
|
14723
14888
|
|
|
14889
|
+
// src/lib/env-proxy.ts
|
|
14890
|
+
var PROXY_VARS = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"];
|
|
14891
|
+
function hasProxyEnv(env = process.env) {
|
|
14892
|
+
return PROXY_VARS.some((name) => Boolean(env[name]?.trim()));
|
|
14893
|
+
}
|
|
14894
|
+
async function installEnvProxy(env = process.env) {
|
|
14895
|
+
if (!hasProxyEnv(env)) return false;
|
|
14896
|
+
const undici = await import('undici');
|
|
14897
|
+
undici.setGlobalDispatcher(new undici.EnvHttpProxyAgent());
|
|
14898
|
+
Object.assign(globalThis, {
|
|
14899
|
+
fetch: undici.fetch,
|
|
14900
|
+
FormData: undici.FormData,
|
|
14901
|
+
Headers: undici.Headers,
|
|
14902
|
+
Request: undici.Request,
|
|
14903
|
+
Response: undici.Response
|
|
14904
|
+
});
|
|
14905
|
+
env.NODE_USE_ENV_PROXY ??= "1";
|
|
14906
|
+
return true;
|
|
14907
|
+
}
|
|
14908
|
+
|
|
14724
14909
|
// src/lib/excess-args.ts
|
|
14725
14910
|
init_output();
|
|
14726
14911
|
var SMART_DASH_RE = /^[‒–—―−]/;
|
|
@@ -15128,7 +15313,7 @@ init_api_client();
|
|
|
15128
15313
|
init_config();
|
|
15129
15314
|
init_output();
|
|
15130
15315
|
init_sdk_version();
|
|
15131
|
-
var
|
|
15316
|
+
var MIN_NODE = [20, 18, 1];
|
|
15132
15317
|
var CLOUD_FILES = [
|
|
15133
15318
|
"scripts/cloud-setup.sh",
|
|
15134
15319
|
".claude/settings.json",
|
|
@@ -15348,13 +15533,20 @@ function unreachable(apiUrl) {
|
|
|
15348
15533
|
};
|
|
15349
15534
|
}
|
|
15350
15535
|
function nodeCheck(version) {
|
|
15351
|
-
const
|
|
15352
|
-
|
|
15536
|
+
const parts = version.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
|
|
15537
|
+
let supported = parts.length === 3 && parts.every(Number.isFinite);
|
|
15538
|
+
for (let i = 0; supported && i < 3; i++) {
|
|
15539
|
+
if (parts[i] !== MIN_NODE[i]) {
|
|
15540
|
+
supported = parts[i] > MIN_NODE[i];
|
|
15541
|
+
break;
|
|
15542
|
+
}
|
|
15543
|
+
}
|
|
15544
|
+
return supported ? { id: "node", label: "Node", status: "ok", detail: version } : {
|
|
15353
15545
|
id: "node",
|
|
15354
15546
|
label: "Node",
|
|
15355
15547
|
status: "fail",
|
|
15356
15548
|
detail: `${version} is too old`,
|
|
15357
|
-
fix: `Install Node ${
|
|
15549
|
+
fix: `Install Node ${MIN_NODE.join(".")} or newer (the template pins Node 22).`
|
|
15358
15550
|
};
|
|
15359
15551
|
}
|
|
15360
15552
|
async function versionCheck(id, label, installed, latest, fix) {
|
|
@@ -25000,7 +25192,7 @@ fieldCmd.command("set-type <table-slug> <field-slug> <new-type>").description(
|
|
|
25000
25192
|
}
|
|
25001
25193
|
);
|
|
25002
25194
|
function getVersion() {
|
|
25003
|
-
return "0.
|
|
25195
|
+
return "0.25.0";
|
|
25004
25196
|
}
|
|
25005
25197
|
function parseIntOption(value) {
|
|
25006
25198
|
const n = Number.parseInt(value, 10);
|
|
@@ -25016,6 +25208,7 @@ function collectRepeated(value, previous) {
|
|
|
25016
25208
|
// src/bin.ts
|
|
25017
25209
|
(async () => {
|
|
25018
25210
|
try {
|
|
25211
|
+
await installEnvProxy();
|
|
25019
25212
|
await program.parseAsync(process.argv);
|
|
25020
25213
|
} catch (err) {
|
|
25021
25214
|
if (err instanceof ExcessArgumentsError) {
|