deployai 0.1.0-beta.5 → 0.1.0-beta.7
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/index.js +137 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ Node 20 or newer. No other setup: the CLI talks to https://deployai.co.il.
|
|
|
38
38
|
|
|
39
39
|
| Command | What it does |
|
|
40
40
|
|---------|--------------|
|
|
41
|
-
| `deployai init` | Creates `DEPLOYAI.md` (rules for the AI agent) and `.deployai/project.json`. Never edits your code and does not link a project (use `link`). `--force` overwrites `DEPLOYAI.md
|
|
41
|
+
| `deployai init` | Creates `DEPLOYAI.md` (rules for the AI agent: the stack to build with, what to avoid, how to keep existing data), adds one line pointing to it in `AGENTS.md` and `CLAUDE.md`, and `.deployai/project.json`. Run it first in a new project, even an empty folder. Never edits your code and does not link a project (use `link`). `--force` overwrites `DEPLOYAI.md`, `--no-agent-files` leaves `AGENTS.md` and `CLAUDE.md` alone. |
|
|
42
42
|
| `deployai inspect` | Shows framework, package manager, language, database, storage and the number of env files (values are never read). `--json` for machine output. |
|
|
43
43
|
| `deployai check` | Lists blockers and warnings with file and line. It answers only whether the project can run on DeployAI. More below. |
|
|
44
44
|
| `deployai login` | Logs in through the browser (device code). The token lasts 30 days and is stored in `~/.deployai/config.json` with the API address that issued it; it is never sent to another address. |
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,9 @@ import { Command } from "commander";
|
|
|
12
12
|
// src/api.ts
|
|
13
13
|
import { arch, platform } from "os";
|
|
14
14
|
|
|
15
|
+
// ../shared/src/plans.ts
|
|
16
|
+
var VAT_RATE = 0.18;
|
|
17
|
+
|
|
15
18
|
// ../shared/src/blockers.ts
|
|
16
19
|
var ISSUES = [
|
|
17
20
|
// Blockers
|
|
@@ -20939,7 +20942,15 @@ var StatusResponse = external_exports.object({
|
|
|
20939
20942
|
project: Project,
|
|
20940
20943
|
queue: external_exports.object({ position: external_exports.number(), running: external_exports.boolean() }),
|
|
20941
20944
|
/** The newest version, with the error and the end of the build log when it failed. */
|
|
20942
|
-
latest: external_exports.object({
|
|
20945
|
+
latest: external_exports.object({
|
|
20946
|
+
number: external_exports.number(),
|
|
20947
|
+
status: VersionStatus,
|
|
20948
|
+
error: external_exports.string().nullable(),
|
|
20949
|
+
logTail: external_exports.string().nullable(),
|
|
20950
|
+
migrationStatus: MigrationStatus.nullable().optional(),
|
|
20951
|
+
/** A ready version that is not live: its preview, for the owner to look at before promote (D-505). */
|
|
20952
|
+
preview: external_exports.string().nullable().optional()
|
|
20953
|
+
}).nullable().optional()
|
|
20943
20954
|
});
|
|
20944
20955
|
var ApiError = external_exports.object({
|
|
20945
20956
|
error: external_exports.string(),
|
|
@@ -21127,17 +21138,17 @@ var ARCH_NODES = [
|
|
|
21127
21138
|
{ id: "board-watcher", kind: "actor", zone: "outside", label: "Board watcher", summary: "\u05E8\u05E5 \u05D0\u05E6\u05DC \u05D4\u05D1\u05E2\u05DC\u05D9\u05DD (pnpm board:watch): \u05DC\u05D5\u05E7\u05D7 \u05DB\u05E8\u05D8\u05D9\u05E1 \u05DE\u05DC\u05D5\u05D7 \u05D4\u05E2\u05D1\u05D5\u05D3\u05D4 (\u05E8\u05E7 \u05DB\u05E9\u05D4\u05DE\u05EA\u05D2 \u05E9\u05DC\u05D5 \u05D1\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05E4\u05D5\u05E2\u05DC), \u05DE\u05E8\u05D9\u05E5 Claude Code \u05DC\u05E7\u05E8\u05D9\u05D0\u05D4 \u05D1\u05DC\u05D1\u05D3 \u05D5\u05DE\u05D7\u05D6\u05D9\u05E8 \u05EA\u05D5\u05DB\u05E0\u05D9\u05EA. \u05DB\u05E8\u05D8\u05D9\u05E1 \u05E2\u05DD \u05D1\u05E0\u05D9\u05D9\u05D4 \u05D0\u05D5\u05D8\u05D5\u05DE\u05D8\u05D9\u05EA \u05E9\u05D0\u05D5\u05E9\u05E8 \u05E0\u05D1\u05E0\u05D4 \u05D1\u05EA\u05D9\u05E7\u05D9\u05D9\u05EA \u05D4\u05E4\u05E8\u05D5\u05D9\u05E7\u05D8, \u05D0\u05D7\u05D3 \u05D1\u05DB\u05DC \u05E4\u05E2\u05DD. \u05D4\u05D5\u05D0 \u05D2\u05DD \u05DB\u05D5\u05EA\u05D1 \u05D2\u05E8\u05E1\u05D0\u05D5\u05EA \u05D7\u05D3\u05E9\u05D5\u05EA \u05DC\u05E1\u05E4\u05E8\u05D9\u05D9\u05EA \u05D4\u05E4\u05E8\u05D5\u05DE\u05E4\u05D8\u05D9\u05DD \u05DC\u05E4\u05D9 \u05D4\u05E2\u05E8\u05D5\u05EA \u05D4\u05D1\u05E2\u05DC\u05D9\u05DD, \u05DC\u05D1\u05D3\u05D9\u05E7\u05D4 \u05D5\u05E4\u05E8\u05E1\u05D5\u05DD.", summaryEn: "Runs on the owner computer (pnpm board:watch): claims a work board ticket (only while its settings switch is on), runs Claude Code read only and posts a plan back. An approved auto build ticket is built in the project folder, one at a time. It also writes new versions of prompt library prompts from the owner notes, for review and publishing.", code: ["scripts/board-watch.ts", "scripts/prompts-sync.ts"], env: ["BOARD_RUNNER_TOKEN", "BOARD_URL"], decisions: ["D-110", "D-127", "D-182", "D-250"] },
|
|
21128
21139
|
{ id: "visitor", kind: "actor", zone: "outside", label: "\u05DE\u05D1\u05E7\u05E8 \u05D1\u05D0\u05EA\u05E8", labelEn: "Site visitor", summary: "\u05DE\u05D1\u05E7\u05E8 \u05D1\u05D0\u05EA\u05E8 \u05E9\u05DC \u05DC\u05E7\u05D5\u05D7 \u05D1\u05DB\u05EA\u05D5\u05D1\u05EA <slug>.<\u05D3\u05D5\u05DE\u05D9\u05D9\u05DF \u05D0\u05EA\u05E8\u05D9\u05DD> (\u05DB\u05DE\u05D5 deploy-net.com \u05D0\u05D5 freesite.click) \u05D0\u05D5 \u05D1\u05D3\u05D5\u05DE\u05D9\u05D9\u05DF \u05DE\u05E9\u05DC\u05D5.", summaryEn: "A visitor on a customer site at <slug>.<a sites domain> (like deploy-net.com or freesite.click) or on their own domain." },
|
|
21129
21140
|
// Platform
|
|
21130
|
-
{ id: "web", kind: "app", zone: "platform", label: "Web app (Next.js)", summary: "\u05D0\u05EA\u05E8 \u05D4\u05E9\u05D9\u05D5\u05D5\u05E7, \u05DC\u05D5\u05D7 \u05D4\u05D1\u05E7\u05E8\u05D4, \u05D4\u05D0\u05D3\u05DE\u05D9\u05DF \u05D5\u05D4\u05BEAPI \u05E9\u05DC \u05D4\u05BECLI. \u05DE\u05DB\u05E0\u05D9\u05E1 \u05E2\u05D1\u05D5\u05D3\u05D5\u05EA \u05DC\u05EA\u05D5\u05E8.", summaryEn: "The marketing site, the dashboard, the admin and the CLI API. Puts jobs in the queue.", code: ["apps/web/src/app", "apps/web/src/server"], env: ["DEPLOYAI_SPACE", "BETTER_AUTH_SECRET", "NEXT_PUBLIC_SUPPORT_WHATSAPP", "DEV_SUPERADMIN_PASSWORD"], portability: "Our app (site, dashboard, API, builds)", docs: ["docs/04-architecture.md"], decisions: ["D-020", "D-057", "D-104", "D-149", "D-238", "D-293"] },
|
|
21141
|
+
{ id: "web", kind: "app", zone: "platform", label: "Web app (Next.js)", summary: "\u05D0\u05EA\u05E8 \u05D4\u05E9\u05D9\u05D5\u05D5\u05E7, \u05DC\u05D5\u05D7 \u05D4\u05D1\u05E7\u05E8\u05D4, \u05D4\u05D0\u05D3\u05DE\u05D9\u05DF \u05D5\u05D4\u05BEAPI \u05E9\u05DC \u05D4\u05BECLI. \u05DE\u05DB\u05E0\u05D9\u05E1 \u05E2\u05D1\u05D5\u05D3\u05D5\u05EA \u05DC\u05EA\u05D5\u05E8.", summaryEn: "The marketing site, the dashboard, the admin and the CLI API. Puts jobs in the queue.", code: ["apps/web/src/app", "apps/web/src/server"], env: ["DEPLOYAI_SPACE", "BETTER_AUTH_SECRET", "NEXT_PUBLIC_SUPPORT_WHATSAPP", "DEV_SUPERADMIN_PASSWORD", "OPENAI_APPS_CHALLENGE"], portability: "Our app (site, dashboard, API, builds)", docs: ["docs/04-architecture.md"], decisions: ["D-020", "D-057", "D-104", "D-149", "D-238", "D-293"] },
|
|
21131
21142
|
{ id: "queue", kind: "db", zone: "platform", label: "pg-boss queue", summary: "\u05DB\u05DC \u05DE\u05D4 \u05E9\u05D0\u05D9\u05D8\u05D9 \u05D0\u05D5 \u05E0\u05D5\u05D2\u05E2 \u05D1\u05BECloudflare \u05E8\u05E5 \u05DB\u05E2\u05D1\u05D5\u05D3\u05D4 \u05D1\u05EA\u05D5\u05E8.", summaryEn: "Everything slow or that touches Cloudflare runs as a job in the queue.", code: ["apps/web/src/server/queue.ts"], portability: "Job queue", decisions: ["D-058"] },
|
|
21132
21143
|
{ id: "worker", kind: "app", zone: "platform", label: "Job worker", summary: "\u05EA\u05D4\u05DC\u05D9\u05DA \u05E0\u05E4\u05E8\u05D3 \u05E9\u05DE\u05E8\u05D9\u05E5 \u05D0\u05EA \u05D4\u05E2\u05D1\u05D5\u05D3\u05D5\u05EA \u05DE\u05D4\u05EA\u05D5\u05E8: \u05D1\u05E0\u05D9\u05D9\u05D4, \u05D4\u05E2\u05DC\u05D0\u05D4, \u05E0\u05D9\u05EA\u05D5\u05D1, \u05D1\u05D9\u05E7\u05D5\u05E8\u05D9\u05DD, \u05E2\u05DC\u05D5\u05D9\u05D5\u05EA \u05D5\u05DE\u05D9\u05D9\u05DC\u05D9\u05DD \u05DC\u05DE\u05E9\u05E4\u05DA (pnpm worker, \u05D0\u05D5 pnpm worker:public \u05DE\u05D0\u05D7\u05D5\u05E8\u05D9 \u05D4\u05BEtunnel).", summaryEn: "A separate process that runs the queued jobs: build, upload, routing, visits, costs and lifecycle emails (pnpm worker, or pnpm worker:public behind the tunnel).", code: ["apps/web/src/server/worker.ts", "apps/web/src/server/jobs.ts", "apps/web/src/server/site-data.ts", "apps/web/src/server/lifecycle", "apps/web/src/server/host-report.ts"], env: ["BUILD_SLOTS", "LIFECYCLE_NOW", "A11Y_RENDER", "DOCKER_HOST", "HOST_REPORT_PATH"], decisions: ["D-058", "D-148", "D-180", "D-340"] },
|
|
21133
21144
|
{ id: "build", kind: "app", zone: "platform", label: "Build service (Docker)", summary: "\u05E7\u05D5\u05E0\u05D8\u05D9\u05D9\u05E0\u05E8 \u05D7\u05D3\u05E9 \u05DC\u05DB\u05DC \u05E9\u05DC\u05D1, \u05D1\u05DC\u05D9 \u05E1\u05D5\u05D3\u05D5\u05EA. \u05D1\u05D5\u05E0\u05D4 \u05D0\u05EA \u05D4\u05E7\u05D5\u05D3 \u05E9\u05DC \u05D4\u05DC\u05E7\u05D5\u05D7 \u05DC\u05E7\u05D5\u05D1\u05E5 Worker.", summaryEn: "A fresh container for every step, with no secrets. Builds the customer's code into a Worker file.", code: ["apps/web/src/server/build.ts"], env: ["BUILD_MODE"] },
|
|
21134
21145
|
{ id: "postgres", kind: "db", zone: "platform", label: "Postgres", summary: "\u05DE\u05E1\u05D3 \u05D4\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD \u05E9\u05DC\u05E0\u05D5: \u05DE\u05E9\u05EA\u05DE\u05E9\u05D9\u05DD, \u05D0\u05EA\u05E8\u05D9\u05DD, \u05D2\u05E8\u05E1\u05D0\u05D5\u05EA, \u05EA\u05E9\u05DC\u05D5\u05DE\u05D9\u05DD, \u05D1\u05D9\u05E7\u05D5\u05E8\u05D9\u05DD \u05D5\u05D9\u05D5\u05DE\u05DF. \u05D1\u05D9\u05D9\u05E6\u05D5\u05E8 \u05D2\u05D9\u05D1\u05D5\u05D9 pg_dump \u05DC\u05D9\u05DC\u05D9 \u05DC\u05D3\u05DC\u05D9 R2 \u05E0\u05E4\u05E8\u05D3 (14 \u05D9\u05D5\u05DE\u05D9\u05D9\u05DD, 4 \u05E9\u05D1\u05D5\u05E2\u05D9\u05D9\u05DD), \u05DE\u05D5\u05E6\u05E4\u05DF \u05D1\u05BEage, \u05D5\u05DE\u05D2\u05D1\u05D9\u05DD \u05D2\u05DD \u05D9\u05D3\u05E0\u05D9\u05EA \u05DE\u05D0\u05D3\u05DE\u05D9\u05DF, \u05E9\u05E8\u05EA, \u05D2\u05D9\u05D1\u05D5\u05D9\u05D9\u05DD.", summaryEn: "Our database: users, sites, versions, payments, visits and the audit log. In production a nightly pg_dump goes to its own R2 bucket (14 daily, 4 weekly), encrypted with age, plus manual copies from Admin, Server, Backups.", code: ["apps/web/src/server/db/schema.ts", "scripts/backup-db.sh", "apps/web/src/server/backups.ts"], env: ["DATABASE_URL", "BACKUP_S3_ACCESS_KEY_ID", "BACKUP_S3_SECRET_ACCESS_KEY", "BACKUP_AGE_RECIPIENT"], portability: "Our database", docs: ["docs/04-architecture.md", "docs/22-go-live.md", "docs/23-server.md"], decisions: ["D-336", "D-340"] },
|
|
21135
|
-
{ id: "files", kind: "storage", zone: "platform", label: "Version files", summary: "\u05D0\u05E8\u05DB\u05D9\u05D5\u05E0\u05D9 \u05DE\u05E7\u05D5\u05E8 \u05D5\u05EA\u05D5\u05E6\u05E8\u05D9 \u05D1\u05E0\u05D9\u05D9\u05D4 \u05E9\u05DC \u05DB\u05DC \u05D2\u05E8\u05E1\u05D4, \u05D3\u05E8\u05DA storage.ts \u05D1\u05DC\u05D1\u05D3. \u05D3\u05DC\u05D9 R2 \u05DC\u05DB\u05DC \u05E1\u05D1\u05D9\u05D1\u05D4, \u05D5\u05E0\u05D9\u05E7\u05D5\u05D9 \u05DC\u05D9\u05DC\u05D9 \u05E9\u05DC \u05E7\u05D1\u05E6\u05D9\u05DD \u05E9\u05D0\u05E3 \u05D2\u05E8\u05E1\u05D4 \u05DC\u05D0 \u05DE\u05E9\u05EA\u05DE\u05E9\u05EA \u05D1\u05D4\u05DD.", summaryEn: "Source archives and build output of every version, through storage.ts only. One R2 bucket per place, and a nightly sweep of files no version uses.", code: ["apps/web/src/server/storage.ts", "apps/web/src/server/storage-sweep.ts"], env: ["STORAGE_DIR", "S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY"], portability: "Version files (uploads and build output)", docs: ["docs/17-portability.md"], decisions: ["D-095", "D-096", "D-316"] },
|
|
21146
|
+
{ id: "files", kind: "storage", zone: "platform", label: "Version files", summary: "\u05D0\u05E8\u05DB\u05D9\u05D5\u05E0\u05D9 \u05DE\u05E7\u05D5\u05E8 \u05D5\u05EA\u05D5\u05E6\u05E8\u05D9 \u05D1\u05E0\u05D9\u05D9\u05D4 \u05E9\u05DC \u05DB\u05DC \u05D2\u05E8\u05E1\u05D4, \u05D3\u05E8\u05DA storage.ts \u05D1\u05DC\u05D1\u05D3. \u05D3\u05DC\u05D9 R2 \u05DC\u05DB\u05DC \u05E1\u05D1\u05D9\u05D1\u05D4, \u05D5\u05E0\u05D9\u05E7\u05D5\u05D9 \u05DC\u05D9\u05DC\u05D9 \u05E9\u05DC \u05E7\u05D1\u05E6\u05D9\u05DD \u05E9\u05D0\u05E3 \u05D2\u05E8\u05E1\u05D4 \u05DC\u05D0 \u05DE\u05E9\u05EA\u05DE\u05E9\u05EA \u05D1\u05D4\u05DD. \u05D1\u05D9\u05D9\u05E6\u05D5\u05E8 \u05E9\u05D9\u05E7\u05D5\u05E3 \u05DC\u05D9\u05DC\u05D9 \u05DC\u05D3\u05DC\u05D9 \u05D4\u05D2\u05D9\u05D1\u05D5\u05D9\u05D9\u05DD, \u05EA\u05D7\u05EA files/ (D-473).", summaryEn: "Source archives and build output of every version, through storage.ts only. One R2 bucket per place, and a nightly sweep of files no version uses. In prod a nightly mirror into the backups bucket, under files/ (D-473).", code: ["apps/web/src/server/storage.ts", "apps/web/src/server/storage-sweep.ts", "scripts/mirror-files.sh"], env: ["STORAGE_DIR", "S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY"], portability: "Version files (uploads and build output)", docs: ["docs/17-portability.md"], decisions: ["D-095", "D-096", "D-316", "D-473"] },
|
|
21136
21147
|
// Services
|
|
21137
21148
|
{ id: "email-sending", kind: "external", zone: "services", label: "CF Email Sending", summary: "\u05E9\u05DC\u05D9\u05D7\u05EA \u05DE\u05D9\u05D9\u05DC\u05D9\u05DD \u05D3\u05E8\u05DA Cloudflare Email Sending. \u05D1\u05DC\u05D9 \u05D8\u05D5\u05E7\u05DF \u05D4\u05DE\u05D9\u05D9\u05DC \u05DE\u05D5\u05D3\u05E4\u05E1 \u05D1\u05DC\u05D5\u05D2.", summaryEn: "Sends email through Cloudflare Email Sending. Without a token, the email is printed to the log.", code: ["apps/web/src/server/email.ts"], portability: "Emails" },
|
|
21138
21149
|
{ id: "oauth", kind: "external", zone: "services", label: "Google / GitHub OAuth", summary: "\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA \u05E2\u05DD Google \u05D0\u05D5 GitHub \u05D3\u05E8\u05DA Better Auth.", summaryEn: "Log in with Google or GitHub through Better Auth.", code: ["apps/web/src/server/auth.ts"], env: ["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET"], decisions: ["D-020"] },
|
|
21139
21150
|
{ id: "payments", kind: "external", zone: "services", label: "Payment provider (Cardcom)", summary: "\u05E7\u05D0\u05E8\u05D3\u05E7\u05D5\u05DD \u05DB\u05D1\u05E8\u05D9\u05E8\u05EA \u05DE\u05D7\u05D3\u05DC, \u05D5\u05E0\u05D1\u05D7\u05E8 \u05D1\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05D4\u05D0\u05D3\u05DE\u05D9\u05DF (\u05D0\u05D5 \u05DE\u05D3\u05D5\u05DE\u05D4 \u05DC\u05D1\u05D3\u05D9\u05E7\u05D5\u05EA). \u05D4\u05DB\u05E8\u05D8\u05D9\u05E1 \u05DE\u05D5\u05E7\u05DC\u05D3 \u05D1\u05D3\u05E3 \u05D4\u05DE\u05D0\u05D5\u05D1\u05D8\u05D7 \u05E9\u05DC \u05E7\u05D0\u05E8\u05D3\u05E7\u05D5\u05DD \u05D5\u05E0\u05E9\u05DE\u05E8 \u05DB\u05D8\u05D5\u05E7\u05DF \u05DE\u05D5\u05E6\u05E4\u05DF, \u05DB\u05DC \u05D7\u05D9\u05D5\u05D1 \u05E2\u05DD \u05DE\u05E4\u05EA\u05D7 \u05D0\u05D9\u05D3\u05DE\u05E4\u05D5\u05D8\u05E0\u05D8\u05D9\u05D5\u05EA, \u05D5\u05E7\u05D0\u05E8\u05D3\u05E7\u05D5\u05DD \u05DE\u05E4\u05D9\u05E7\u05D4 \u05D7\u05E9\u05D1\u05D5\u05E0\u05D9\u05EA \u05DE\u05E1 \u05DC\u05DB\u05DC \u05D7\u05D9\u05D5\u05D1 \u05D5\u05D7\u05E9\u05D1\u05D5\u05E0\u05D9\u05EA \u05D6\u05D9\u05DB\u05D5\u05D9 \u05DC\u05DB\u05DC \u05D4\u05D7\u05D6\u05E8.", summaryEn: "Cardcom by default, chosen in admin settings (or simulated for tests). The card is typed on the secure Cardcom page and saved as a sealed token, every charge carries an idempotency key, and Cardcom issues a tax invoice per charge and a credit invoice per refund.", code: ["apps/web/src/server/billing/provider.ts", "apps/web/src/server/billing/cardcom.ts", "apps/web/src/server/billing/card-pages.ts", "apps/web/src/app/api/billing/card"], env: ["BILLING_PROVIDER", "BILLING_MOCK_FAIL", "CARDCOM_TERMINAL", "CARDCOM_API_NAME", "CARDCOM_API_PASSWORD", "CARDCOM_INVOICES", "CARDCOM_CSS_URL", "CARDCOM_TOKEN_KEY", "CARDCOM_DEPARTMENT_ID"], portability: "Payments", decisions: ["D-175", "D-292"] },
|
|
21140
|
-
{ id: "registrar", kind: "external", zone: "services", label: "Domain registrars (Cloudflare, LiveDNS)", summary: "\u05E7\u05E0\u05D9\u05D9\u05EA \u05D3\u05D5\u05DE\u05D9\u05D9\u05E0\u05D9\u05DD \u05DC\u05D0\u05EA\u05E8: \u05DB\u05DC \u05E9\u05DD \u05D4\u05D5\u05DC\u05DA \u05DC\u05E8\u05E9\u05DD \u05D4\u05D6\u05D5\u05DC \u05D1\u05D9\u05D5\u05EA\u05E8 \u05E9\u05E4\u05D5\u05E2\u05DC (Cloudflare \u05D1\u05D3\u05D5\u05DC\u05E8\u05D9\u05DD
|
|
21151
|
+
{ id: "registrar", kind: "external", zone: "services", label: "Domain registrars (Cloudflare, LiveDNS)", summary: "\u05E7\u05E0\u05D9\u05D9\u05EA \u05D3\u05D5\u05DE\u05D9\u05D9\u05E0\u05D9\u05DD \u05DC\u05D0\u05EA\u05E8: \u05DB\u05DC \u05E9\u05DD \u05D4\u05D5\u05DC\u05DA \u05DC\u05E8\u05E9\u05DD \u05D4\u05D6\u05D5\u05DC \u05D1\u05D9\u05D5\u05EA\u05E8 \u05E9\u05E4\u05D5\u05E2\u05DC, \u05DB\u05DC \u05E8\u05E9\u05DD \u05D1\u05E2\u05DC\u05D5\u05EA \u05D5\u05D1\u05E2\u05DE\u05DC\u05D4 \u05DE\u05E9\u05DC\u05D5 (Cloudflare \u05D1\u05D3\u05D5\u05DC\u05E8\u05D9\u05DD \u05DC\u05DB\u05DC \u05E9\u05DD, LiveDNS \u05DE\u05E0\u05E7\u05D5\u05D3\u05D5\u05EA \u05E7\u05E8\u05D3\u05D9\u05D8 \u05DC\u05E4\u05D9 \u05D4\u05DE\u05D7\u05D9\u05E8\u05D5\u05DF \u05E9\u05E0\u05E7\u05E8\u05D0 \u05DB\u05DC \u05D9\u05D5\u05DD, \u05D0\u05D5 \u05D9\u05D3\u05E0\u05D9 \u05DE\u05EA\u05D5\u05E8 \u05D4\u05E6\u05D5\u05D5\u05EA), \u05DE\u05D7\u05D9\u05E8 \u05DB\u05DC \u05E1\u05D9\u05D5\u05DE\u05EA \u05E0\u05D1\u05D3\u05E7 \u05DB\u05DC \u05D9\u05D5\u05DD (\u05D5\u05D0\u05E4\u05E9\u05E8 \u05DC\u05DB\u05D1\u05D5\u05EA \u05E1\u05D9\u05D5\u05DE\u05D5\u05EA), \u05E8\u05D9\u05E9\u05D5\u05DD \u05D0\u05D7\u05D3 \u05DC\u05DB\u05DC \u05D4\u05D6\u05DE\u05E0\u05D4, \u05D9\u05D5\u05DE\u05DF \u05E7\u05E8\u05D9\u05D0\u05D5\u05EA \u05DC\u05DB\u05DC \u05D4\u05D6\u05DE\u05E0\u05D4, \u05D5\u05D7\u05D9\u05D3\u05D5\u05E9 \u05E9\u05E0\u05EA\u05D9 \u05D0\u05E6\u05DC \u05D0\u05D5\u05EA\u05D5 \u05E8\u05E9\u05DD. \u05DC\u05D3\u05D5\u05DE\u05D9\u05D9\u05DF \u05E9\u05E0\u05E7\u05E0\u05D4: \u05D3\u05D5\u05D0\u05E8 \u05D3\u05E8\u05DA Cloudflare Email Routing.", summaryEn: "Buying domains for a site: each name goes to the cheapest registrar that is on, each with its own cost and fee (Cloudflare in dollars per name, LiveDNS from credit points priced by its list, read daily, or by hand from the team queue), the price of every extension checked daily (some can be turned off), one registration per order, a call log per order, yearly renewal at the same registrar. For a bought domain: email through Cloudflare Email Routing.", code: ["apps/web/src/server/registrar.ts", "apps/web/src/server/registrar-livedns.ts", "apps/web/src/server/registrar-log.ts", "apps/web/src/server/domain-sales.ts", "apps/web/src/server/domain-extensions.ts", "apps/web/src/server/domain-email.ts", "apps/web/src/server/billing/services.ts"], env: ["CF_REGISTRAR_TOKEN", "LIVEDNS_USER", "LIVEDNS_PASSWORD"], decisions: ["D-299", "D-300", "D-301", "D-458", "D-486", "D-489", "D-491"] },
|
|
21141
21152
|
{ id: "mcp", kind: "external", zone: "services", label: "MCP for AI tools (/api/mcp)", summary: "ChatGPT \u05D5\u05BEClaude \u05DE\u05EA\u05D7\u05D1\u05E8\u05D9\u05DD \u05D1\u05DC\u05D9 \u05D8\u05E8\u05DE\u05D9\u05E0\u05DC: OAuth \u05E2\u05DD \u05D0\u05D9\u05E9\u05D5\u05E8 \u05D1\u05D3\u05E4\u05D3\u05E4\u05DF, \u05D5\u05D0\u05D6 \u05DB\u05DC\u05D9\u05DD \u05DC\u05E8\u05E9\u05D9\u05DE\u05EA \u05D4\u05D0\u05EA\u05E8\u05D9\u05DD, \u05D1\u05D3\u05D9\u05E7\u05D4, \u05D4\u05E2\u05DC\u05D0\u05EA \u05D2\u05E8\u05E1\u05D4 \u05DC\u05EA\u05E6\u05D5\u05D2\u05D4 \u05DE\u05E7\u05D3\u05D9\u05DE\u05D4, \u05D4\u05E8\u05E6\u05EA \u05EA\u05D5\u05E1\u05E4\u05D9\u05DD \u05E9\u05D4\u05D0\u05EA\u05E8 \u05E7\u05E0\u05D4 (\u05D4\u05E7\u05E0\u05D9\u05D9\u05D4 \u05E8\u05E7 \u05D1\u05D0\u05EA\u05E8), \u05D5\u05D4\u05E2\u05DC\u05D0\u05D4 \u05DC\u05D0\u05D5\u05D5\u05D9\u05E8 \u05E8\u05E7 \u05E2\u05DD \u05D4\u05E8\u05E9\u05D0\u05D4 \u05D5\u05D0\u05D9\u05E9\u05D5\u05E8.", summaryEn: "ChatGPT and Claude connect without a terminal: OAuth with a browser consent, then tools to list sites, check, upload a version to a preview, run add-ons the site owns (buying stays on the site), and go live only with the permission and a yes.", code: ["apps/web/src/app/api/mcp/route.ts", "apps/web/src/server/mcp-tools.ts", "apps/web/src/server/auth.ts"], decisions: ["D-302"] },
|
|
21142
21153
|
{ id: "npm", kind: "external", zone: "services", label: "npm registry", summary: "\u05DE\u05E4\u05D9\u05E5 \u05D0\u05EA \u05D4\u05BECLI, \u05D5\u05DE\u05DE\u05E0\u05D5 \u05D4\u05D1\u05E0\u05D9\u05D9\u05D4 \u05DE\u05EA\u05E7\u05D9\u05E0\u05D4 \u05EA\u05DC\u05D5\u05D9\u05D5\u05EA.", summaryEn: "Distributes the CLI, and the build installs dependencies from it." },
|
|
21143
21154
|
{ id: "pagespeed", kind: "external", zone: "services", label: "Google PageSpeed Insights", summary: "\u05D1\u05D3\u05D9\u05E7\u05D5\u05EA \u05D4\u05DE\u05D4\u05D9\u05E8\u05D5\u05EA, \u05D4\u05E0\u05D2\u05D9\u05E9\u05D5\u05EA \u05D5\u05D4\u05BESEO \u05D4\u05D7\u05D9\u05E0\u05DE\u05D9\u05D5\u05EA: Lighthouse \u05D1\u05DE\u05E2\u05D1\u05D3\u05D4 \u05E9\u05DC \u05D2\u05D5\u05D2\u05DC (\u05DB\u05D5\u05DC\u05DC \u05E1\u05D5\u05DB\u05E0\u05D9 AI) \u05D5\u05E0\u05EA\u05D5\u05E0\u05D9 \u05DE\u05D1\u05E7\u05E8\u05D9\u05DD \u05D0\u05DE\u05D9\u05EA\u05D9\u05D9\u05DD.", summaryEn: "The free speed, accessibility and SEO tests: Lighthouse run at Google (AI agents included) plus real visitor data.", env: ["PAGESPEED_API_KEY"], decisions: ["D-199", "D-222"] },
|
|
@@ -21354,7 +21365,7 @@ var CLI_MAP_NODES = [
|
|
|
21354
21365
|
n("cmd-start", "cli", "start <id>", "\u05DE\u05DB\u05D9\u05DF \u05D0\u05EA \u05D4\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4 \u05DC\u05E4\u05D9 \u05DB\u05DC \u05D4\u05D1\u05D7\u05D9\u05E8\u05D5\u05EA: \u05EA\u05D9\u05E7\u05D9\u05D9\u05D4, \u05D3\u05D5\u05D2\u05DE\u05D4 \u05D5\u05D4\u05EA\u05E7\u05E0\u05D4, \u05E7\u05D5\u05D1\u05E5 \u05D4\u05E4\u05E8\u05D8\u05D9\u05DD \u05D5\u05D7\u05D9\u05D1\u05D5\u05E8 \u05DC\u05D0\u05EA\u05E8. \u05DE\u05D3\u05E4\u05D9\u05E1 \u05DC\u05E1\u05D5\u05DB\u05DF \u05D0\u05EA \u05D4\u05D8\u05E7\u05E1\u05D8 \u05D5\u05D0\u05EA \u05D4\u05E4\u05E7\u05D5\u05D3\u05D5\u05EA.", "Prepares the folder with every choice: folder, sample and install, the details file and the site link. Prints the text and the commands for the agent."),
|
|
21355
21366
|
n("cmd-samples", "cli", "samples [key]", "\u05E8\u05E9\u05D9\u05DE\u05EA \u05D4\u05D3\u05D5\u05D2\u05DE\u05D0\u05D5\u05EA, \u05D0\u05D5 \u05D4\u05D5\u05E8\u05D3\u05D4 \u05E9\u05DC \u05D0\u05D7\u05EA.", "Lists the samples, or downloads one."),
|
|
21356
21367
|
n("cmd-check", "cli", "check", "\u05D4\u05D0\u05DD \u05D4\u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D9\u05DB\u05D5\u05DC \u05DC\u05E8\u05D5\u05E5 \u05D0\u05E6\u05DC\u05E0\u05D5: \u05D7\u05D5\u05E1\u05DE\u05D9\u05DD \u05D5\u05D0\u05D6\u05D4\u05E8\u05D5\u05EA, \u05E2\u05DD \u05E4\u05E8\u05D5\u05DE\u05E4\u05D8 \u05EA\u05D9\u05E7\u05D5\u05DF.", "Can the project run on our hosting: blockers and warnings, with a fix prompt."),
|
|
21357
|
-
n("cmd-init", "cli", "init", "\u05D9\u05D5\u05E6\u05E8 DEPLOYAI.md \u05D5 .deployai/project.json.", "Creates DEPLOYAI.md and .deployai/project.json."),
|
|
21368
|
+
n("cmd-init", "cli", "init", "\u05D9\u05D5\u05E6\u05E8 DEPLOYAI.md \u05E2\u05DD \u05D4\u05DB\u05DC\u05DC\u05D9\u05DD \u05DC\u05E1\u05D5\u05DB\u05DF, \u05E9\u05D5\u05E8\u05D4 \u05D0\u05DC\u05D9\u05D5 \u05D1 AGENTS.md \u05D5 CLAUDE.md, \u05D5 .deployai/project.json. \u05E8\u05D0\u05E9\u05D5\u05DF \u05D1\u05E4\u05E8\u05D5\u05D9\u05E7\u05D8 \u05D7\u05D3\u05E9.", "Creates DEPLOYAI.md with the agent rules, a line to it in AGENTS.md and CLAUDE.md, and .deployai/project.json. First in a new project."),
|
|
21358
21369
|
n("cmd-inspect", "cli", "inspect", "\u05DE\u05D4 \u05D6\u05D5\u05D4\u05D4 \u05D1\u05E4\u05E8\u05D5\u05D9\u05E7\u05D8: \u05DE\u05E1\u05D2\u05E8\u05EA, \u05E9\u05E4\u05D4, \u05DE\u05E1\u05D3 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD.", "What the project is: framework, language, database."),
|
|
21359
21370
|
n("cmd-login", "cli", "login", "\u05DB\u05E0\u05D9\u05E1\u05D4 \u05D1\u05D3\u05E4\u05D3\u05E4\u05DF, \u05D1\u05E2\u05DC \u05D4\u05D0\u05EA\u05E8 \u05DE\u05D0\u05E9\u05E8.", "Login in the browser, the owner approves."),
|
|
21360
21371
|
n("cmd-logout", "cli", "logout", "\u05DE\u05D1\u05D8\u05DC \u05D0\u05EA \u05D4\u05D8\u05D5\u05E7\u05DF \u05D5\u05D9\u05D5\u05E6\u05D0 \u05DE\u05D4\u05D7\u05E9\u05D1\u05D5\u05DF \u05D1\u05DE\u05D7\u05E9\u05D1 \u05D4\u05D6\u05D4.", "Cancels the token and logs out on this computer."),
|
|
@@ -21489,6 +21500,13 @@ function neverUploadedFile(rel) {
|
|
|
21489
21500
|
|
|
21490
21501
|
// ../shared/src/domain-sales.ts
|
|
21491
21502
|
var IL_TLDS = ["co.il", "org.il", "net.il"];
|
|
21503
|
+
var DEFAULT_LIVEDNS_POINTS = { 5: 9100, 10: 8900, 20: 8700, 50: 8500, 100: 8200 };
|
|
21504
|
+
var pointCost = (points, pack) => Math.round(points[pack] / (1 + VAT_RATE));
|
|
21505
|
+
var DEFAULT_DOMAIN_REGISTRARS = {
|
|
21506
|
+
cloudflare: { enabled: true, feeRate: 0.03, maxUsdCentsPerDay: 1e4 },
|
|
21507
|
+
livedns: { enabled: true, feeRate: 0.01, pack: 5, costAgorot: pointCost(DEFAULT_LIVEDNS_POINTS, 5) },
|
|
21508
|
+
manual: { enabled: true, feeRate: 0.01, costAgorot: 7500 }
|
|
21509
|
+
};
|
|
21492
21510
|
var LIVEDNS_TLDS = [...IL_TLDS, "com", "net", "org"];
|
|
21493
21511
|
|
|
21494
21512
|
// ../shared/src/env-scopes.ts
|
|
@@ -21498,6 +21516,7 @@ var ENV_KEYS = {
|
|
|
21498
21516
|
BETTER_AUTH_SECRET: { scope: "own", section: "app", required: ["server"], sample: { local: "change-me-to-a-long-random-string", server: "" }, about: "Signs login sessions and our own links; changing it logs everyone out. 32 characters or more in production: openssl rand -base64 48" },
|
|
21499
21517
|
DEV_SUPERADMIN_PASSWORD: { scope: "local", section: "app", about: "The superadmin password after every local wipe. Without it the one in apps/web/local-logins.md is kept (D-100)." },
|
|
21500
21518
|
NEXT_PUBLIC_SUPPORT_WHATSAPP: { scope: "same", section: "app", about: "The WhatsApp number people reach us on, digits with the country code (972...). Empty shows only the email (D-237)." },
|
|
21519
|
+
OPENAI_APPS_CHALLENGE: { scope: "server", section: "app", about: "The domain check token from the OpenAI platform portal (Plugins, domain verification), served as plain text at /.well-known/openai-apps-challenge (D-474). Unset: that page is a 404." },
|
|
21501
21520
|
TUNNEL_ORIGIN_CERT: { scope: "local", section: "app", about: "The cloudflared login certificate pnpm dev:public checks. Default ~/.cloudflared/cert.pem." },
|
|
21502
21521
|
CF_API_TOKEN: { scope: "own", section: "cloudflare", required: ["server"], about: "Cloudflare token (pnpm cf:token-link): sites, KV, D1, R2, routes, custom hostnames and our emails. Each machine its own. Without it everything Cloudflare is a dry run." },
|
|
21503
21522
|
CF_REGISTRAR_TOKEN: { scope: "server", section: "cloudflare", about: "Buys real domains (D-300): a Cloudflare token with Registrar edit only. Server only." },
|
|
@@ -21624,6 +21643,26 @@ var SPACES = {
|
|
|
21624
21643
|
test: build("test", { ...CLOUDFLARE_SPACES.prod, kvNamespaceId: "", sitesZoneId: null, backupBucket: null, toolsWorkerUrl: "" }, { ...SPACE_ADDRESSES.prod, appUrl: "http://localhost:3000", siteUrl: "http://localhost:3000", trustedOrigins: [], storage: "local" })
|
|
21625
21644
|
};
|
|
21626
21645
|
|
|
21646
|
+
// ../shared/src/agent-rules.ts
|
|
21647
|
+
var BUILD_WITH = [
|
|
21648
|
+
`Frameworks: ${SUPPORTED_FRAMEWORKS.map((f) => f.name).join(", ")}. In beta: ${BETA_FRAMEWORKS.map((f) => f.name).join(", ")} (Next.js through the OpenNext Cloudflare adapter).`,
|
|
21649
|
+
"Database: Cloudflare D1 (SQLite), through Drizzle with drizzle-orm/d1 or Prisma with the D1 adapter.",
|
|
21650
|
+
"Uploaded files and images: Cloudflare R2 (object storage), never the local disk.",
|
|
21651
|
+
"Settings and secrets: environment variables, set with: npx deployai@latest env set <key>",
|
|
21652
|
+
"Images: resize at build time or serve them as they are; no native image modules at runtime.",
|
|
21653
|
+
"Passwords: bcryptjs or Web Crypto, never native bcrypt.",
|
|
21654
|
+
"Server code runs per request: no long-running processes, background servers or child processes."
|
|
21655
|
+
];
|
|
21656
|
+
var KEEP_DATA_RULES = [
|
|
21657
|
+
"Moving to DeployAI changes where data lives. It never moves the data by itself. Before you switch any of these, save a copy inside the project and tell the user, in simple words, what was saved and where:",
|
|
21658
|
+
"- Database (Postgres, MySQL, MongoDB, a SQLite file): export it to a file (pg_dump, mysqldump, mongoexport, sqlite3 .dump), so it can be imported into D1 later.",
|
|
21659
|
+
"- Uploaded files and images on the local disk or another storage service: keep them in a folder (download them first if they are on another service), so they can be uploaded to R2 later.",
|
|
21660
|
+
"- User accounts and passwords: keep existing password hashes working (bcryptjs reads bcrypt hashes), so no one has to reset.",
|
|
21661
|
+
"- Sessions and cache (Redis, memory): these can be lost, and users may have to log in again. Say so.",
|
|
21662
|
+
"Never delete the old database, files or storage service."
|
|
21663
|
+
];
|
|
21664
|
+
var AGENT_POINTER = "Read DEPLOYAI.md before you write code, change the plan or add a dependency: this project is published with DeployAI.";
|
|
21665
|
+
|
|
21627
21666
|
// src/config.ts
|
|
21628
21667
|
import { randomUUID } from "crypto";
|
|
21629
21668
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -21771,6 +21810,7 @@ var M = {
|
|
|
21771
21810
|
startInstalled: "Installed its packages (npm install).",
|
|
21772
21811
|
startBrief: "Wrote the owner's details to {file} (kept out of git and never uploaded).",
|
|
21773
21812
|
startLinked: 'Linked this folder to the site "{name}".',
|
|
21813
|
+
startRules: "Wrote the rules for your agent to DEPLOYAI.md (never uploaded).",
|
|
21774
21814
|
startRelinked: 'Linked this folder to the site "{name}" instead of the site it was linked to.',
|
|
21775
21815
|
statusLine: "Status: {s}",
|
|
21776
21816
|
ready: "ready",
|
|
@@ -21784,6 +21824,7 @@ var M = {
|
|
|
21784
21824
|
pasteFix: " Paste the prompt below into your AI editor, then run: npx deployai@latest check",
|
|
21785
21825
|
copied: " (copied to clipboard)",
|
|
21786
21826
|
runDeploy: ' Run: npx deployai@latest deploy -m "<message>"',
|
|
21827
|
+
initHint: " So your agent follows the DeployAI rules, run: npx deployai@latest init",
|
|
21787
21828
|
deployTitle: "DeployAI deploy",
|
|
21788
21829
|
guestTitle: "DeployAI deploy (no account)",
|
|
21789
21830
|
uploading: "Uploading...",
|
|
@@ -21826,20 +21867,22 @@ var M = {
|
|
|
21826
21867
|
liveVersion: "Live version",
|
|
21827
21868
|
newestVersion: "Newest version",
|
|
21828
21869
|
promoteReady: " After the owner approves the preview: npx deployai@latest promote v{n} (to put it live)",
|
|
21870
|
+
askOwner: ' Version {n} is ready and not live. Ask the owner: "Version {n} is ready. Do you want to put it live?"',
|
|
21871
|
+
showPreview: " Send them the preview first: {url}",
|
|
21829
21872
|
notPublished: "not published yet",
|
|
21830
21873
|
none: "none",
|
|
21831
21874
|
buildingNow: "building now",
|
|
21832
21875
|
idle: "idle",
|
|
21833
21876
|
envListTitle: "Variables",
|
|
21834
|
-
envNone: "This site has no variables yet. Add one: npx deployai@latest env set <
|
|
21877
|
+
envNone: "This site has no variables yet. Add one: npx deployai@latest env set <KEY> <value>",
|
|
21835
21878
|
envSecret: "secret",
|
|
21836
21879
|
envPlain: "plain",
|
|
21837
|
-
envNeedValue: 'Give the value after the key, or pipe it in: echo "<value>" | npx deployai@latest env set <
|
|
21880
|
+
envNeedValue: 'Give the value after the key, or pipe it in: echo "<value>" | npx deployai@latest env set <KEY>',
|
|
21838
21881
|
envSavedSecret: "Saved {key} as a secret on the live site. Its value is not stored and is never shown again.",
|
|
21839
21882
|
envSavedPlain: "Saved {key}. The live site gets it in about a minute.",
|
|
21840
21883
|
envRemoved: "Removed {key}. The live site loses it in about a minute.",
|
|
21841
21884
|
guestNoEnv: "A temporary site has no environment variables. Keep it in an account first: npx deployai@latest claim",
|
|
21842
|
-
envInvalidKey: "A variable name is English letters, digits and _,
|
|
21885
|
+
envInvalidKey: "A variable name is capital English letters, digits and _, starts with a letter, up to 64 characters, like STRIPE_KEY.",
|
|
21843
21886
|
envTooLong: "The value is over 5 KB, too long for a variable.",
|
|
21844
21887
|
envSendFailed: "The secret did not reach the site. Try again in a minute.",
|
|
21845
21888
|
envNoKey: "This site has no variable with that name. See them: npx deployai@latest env list",
|
|
@@ -21938,6 +21981,7 @@ var M = {
|
|
|
21938
21981
|
startInstalled: "\u05D4\u05D7\u05D1\u05D9\u05DC\u05D5\u05EA \u05E9\u05DC\u05D4 \u05D4\u05D5\u05EA\u05E7\u05E0\u05D5 (npm install).",
|
|
21939
21982
|
startBrief: "\u05D4\u05E4\u05E8\u05D8\u05D9\u05DD \u05E9\u05DC \u05D1\u05E2\u05DC \u05D4\u05D0\u05EA\u05E8 \u05E0\u05DB\u05EA\u05D1\u05D5 \u05DC {file} (\u05DC\u05D0 \u05E0\u05DB\u05E0\u05E1\u05D9\u05DD \u05DC\u05BEgit \u05D5\u05DC\u05D0 \u05E2\u05D5\u05DC\u05D9\u05DD \u05DC\u05D0\u05EA\u05E8).",
|
|
21940
21983
|
startLinked: '\u05D4\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4 \u05D7\u05D5\u05D1\u05E8\u05D4 \u05DC\u05D0\u05EA\u05E8 "{name}".',
|
|
21984
|
+
startRules: "\u05D4\u05DB\u05DC\u05DC\u05D9\u05DD \u05DC\u05E1\u05D5\u05DB\u05DF \u05E0\u05DB\u05EA\u05D1\u05D5 \u05DC DEPLOYAI.md (\u05DC\u05D0 \u05E2\u05D5\u05DC\u05D9\u05DD \u05DC\u05D0\u05EA\u05E8).",
|
|
21941
21985
|
startRelinked: '\u05D4\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4 \u05D7\u05D5\u05D1\u05E8\u05D4 \u05DC\u05D0\u05EA\u05E8 "{name}" \u05D1\u05DE\u05E7\u05D5\u05DD \u05D4\u05D0\u05EA\u05E8 \u05E9\u05D4\u05D9\u05D9\u05EA\u05D4 \u05DE\u05D7\u05D5\u05D1\u05E8\u05EA \u05D0\u05DC\u05D9\u05D5.',
|
|
21942
21986
|
statusLine: "\u05DE\u05E6\u05D1: {s}",
|
|
21943
21987
|
ready: "\u05DE\u05D5\u05DB\u05DF \u05DC\u05E2\u05DC\u05D5\u05EA",
|
|
@@ -21951,6 +21995,7 @@ var M = {
|
|
|
21951
21995
|
pasteFix: " \u05D4\u05D3\u05D1\u05D9\u05E7\u05D5 \u05D0\u05EA \u05D4\u05E4\u05E8\u05D5\u05DE\u05E4\u05D8 \u05E9\u05DC\u05DE\u05D8\u05D4 \u05DC\u05E1\u05D5\u05DB\u05DF, \u05D5\u05D0\u05D6 \u05D4\u05E8\u05D9\u05E6\u05D5: npx deployai@latest check",
|
|
21952
21996
|
copied: " (\u05D4\u05D5\u05E2\u05EA\u05E7)",
|
|
21953
21997
|
runDeploy: ' \u05D4\u05E8\u05D9\u05E6\u05D5: npx deployai@latest deploy -m "<message>"',
|
|
21998
|
+
initHint: " \u05DB\u05D3\u05D9 \u05E9\u05D4\u05E1\u05D5\u05DB\u05DF \u05D9\u05E2\u05D1\u05D5\u05D3 \u05DC\u05E4\u05D9 \u05D4\u05DB\u05DC\u05DC\u05D9\u05DD \u05E9\u05DC DeployAI, \u05D4\u05E8\u05D9\u05E6\u05D5: npx deployai@latest init",
|
|
21954
21999
|
deployTitle: "DeployAI deploy",
|
|
21955
22000
|
guestTitle: "DeployAI deploy (\u05D1\u05DC\u05D9 \u05D7\u05E9\u05D1\u05D5\u05DF)",
|
|
21956
22001
|
uploading: "\u05DE\u05E2\u05DC\u05D9\u05DD...",
|
|
@@ -21993,20 +22038,22 @@ var M = {
|
|
|
21993
22038
|
liveVersion: "\u05D2\u05E8\u05E1\u05D4 \u05D7\u05D9\u05D4",
|
|
21994
22039
|
newestVersion: "\u05D2\u05E8\u05E1\u05D4 \u05D0\u05D7\u05E8\u05D5\u05E0\u05D4",
|
|
21995
22040
|
promoteReady: " \u05D0\u05D7\u05E8\u05D9 \u05E9\u05D1\u05E2\u05DC \u05D4\u05D0\u05EA\u05E8 \u05D0\u05D9\u05E9\u05E8 \u05D0\u05EA \u05D4\u05EA\u05E6\u05D5\u05D2\u05D4 \u05D4\u05DE\u05E7\u05D3\u05D9\u05DE\u05D4: npx deployai@latest promote v{n} (\u05DB\u05D3\u05D9 \u05DC\u05D4\u05E2\u05DC\u05D5\u05EA \u05D0\u05D5\u05EA\u05D4 \u05DC\u05D0\u05D5\u05D5\u05D9\u05E8)",
|
|
22041
|
+
askOwner: ' \u05D2\u05E8\u05E1\u05D4 {n} \u05DE\u05D5\u05DB\u05E0\u05D4 \u05D5\u05E2\u05D5\u05D3 \u05DC\u05D0 \u05D1\u05D0\u05D5\u05D5\u05D9\u05E8. \u05E9\u05D0\u05DC\u05D5 \u05D0\u05EA \u05D1\u05E2\u05DC \u05D4\u05D0\u05EA\u05E8: "\u05D2\u05E8\u05E1\u05D4 {n} \u05DE\u05D5\u05DB\u05E0\u05D4. \u05DC\u05D4\u05E2\u05DC\u05D5\u05EA \u05D0\u05D5\u05EA\u05D4 \u05DC\u05D0\u05D5\u05D5\u05D9\u05E8?"',
|
|
22042
|
+
showPreview: " \u05E9\u05DC\u05D7\u05D5 \u05E7\u05D5\u05D3\u05DD \u05D0\u05EA \u05D4\u05EA\u05E6\u05D5\u05D2\u05D4 \u05D4\u05DE\u05E7\u05D3\u05D9\u05DE\u05D4: {url}",
|
|
21996
22043
|
notPublished: "\u05E2\u05D3\u05D9\u05D9\u05DF \u05DC\u05D0 \u05D1\u05D0\u05D5\u05D5\u05D9\u05E8",
|
|
21997
22044
|
none: "\u05D0\u05D9\u05DF",
|
|
21998
22045
|
buildingNow: "\u05D1\u05D5\u05E0\u05D9\u05DD \u05E2\u05DB\u05E9\u05D9\u05D5",
|
|
21999
22046
|
idle: "\u05E4\u05E0\u05D5\u05D9",
|
|
22000
22047
|
envListTitle: "\u05DE\u05E9\u05EA\u05E0\u05D9\u05DD",
|
|
22001
|
-
envNone: "\u05DC\u05D0\u05EA\u05E8 \u05D4\u05D6\u05D4 \u05E2\u05D5\u05D3 \u05D0\u05D9\u05DF \u05DE\u05E9\u05EA\u05E0\u05D9\u05DD. \u05D4\u05D5\u05E1\u05D9\u05E4\u05D5 \u05D0\u05D7\u05D3: npx deployai@latest env set <
|
|
22048
|
+
envNone: "\u05DC\u05D0\u05EA\u05E8 \u05D4\u05D6\u05D4 \u05E2\u05D5\u05D3 \u05D0\u05D9\u05DF \u05DE\u05E9\u05EA\u05E0\u05D9\u05DD. \u05D4\u05D5\u05E1\u05D9\u05E4\u05D5 \u05D0\u05D7\u05D3: npx deployai@latest env set <KEY> <value>",
|
|
22002
22049
|
envSecret: "\u05E1\u05D5\u05D3",
|
|
22003
22050
|
envPlain: "\u05D2\u05DC\u05D5\u05D9",
|
|
22004
|
-
envNeedValue: '\u05DB\u05EA\u05D1\u05D5 \u05D0\u05EA \u05D4\u05E2\u05E8\u05DA \u05D0\u05D7\u05E8\u05D9 \u05D4\u05E9\u05DD, \u05D0\u05D5 \u05D4\u05E2\u05D1\u05D9\u05E8\u05D5 \u05D0\u05D5\u05EA\u05D5 \u05D1\u05E6\u05D9\u05E0\u05D5\u05E8: echo "<value>" | npx deployai@latest env set <
|
|
22051
|
+
envNeedValue: '\u05DB\u05EA\u05D1\u05D5 \u05D0\u05EA \u05D4\u05E2\u05E8\u05DA \u05D0\u05D7\u05E8\u05D9 \u05D4\u05E9\u05DD, \u05D0\u05D5 \u05D4\u05E2\u05D1\u05D9\u05E8\u05D5 \u05D0\u05D5\u05EA\u05D5 \u05D1\u05E6\u05D9\u05E0\u05D5\u05E8: echo "<value>" | npx deployai@latest env set <KEY>',
|
|
22005
22052
|
envSavedSecret: "\u05E9\u05DE\u05E8\u05E0\u05D5 \u05D0\u05EA {key} \u05DB\u05E1\u05D5\u05D3 \u05D1\u05D0\u05EA\u05E8 \u05D4\u05D7\u05D9. \u05D4\u05E2\u05E8\u05DA \u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8 \u05D0\u05E6\u05DC\u05E0\u05D5 \u05D5\u05DC\u05D0 \u05D9\u05D5\u05E6\u05D2 \u05E9\u05D5\u05D1.",
|
|
22006
22053
|
envSavedPlain: "\u05E9\u05DE\u05E8\u05E0\u05D5 \u05D0\u05EA {key}. \u05D4\u05D0\u05EA\u05E8 \u05D4\u05D7\u05D9 \u05D9\u05E7\u05D1\u05DC \u05D0\u05D5\u05EA\u05D5 \u05EA\u05D5\u05DA \u05DB\u05D3\u05E7\u05D4.",
|
|
22007
22054
|
envRemoved: "\u05D4\u05E1\u05E8\u05E0\u05D5 \u05D0\u05EA {key}. \u05D4\u05D5\u05D0 \u05D9\u05D9\u05E2\u05DC\u05DD \u05DE\u05D4\u05D0\u05EA\u05E8 \u05D4\u05D7\u05D9 \u05EA\u05D5\u05DA \u05DB\u05D3\u05E7\u05D4.",
|
|
22008
22055
|
guestNoEnv: "\u05DC\u05D0\u05EA\u05E8 \u05D6\u05DE\u05E0\u05D9 \u05D0\u05D9\u05DF \u05DE\u05E9\u05EA\u05E0\u05D9 \u05E1\u05D1\u05D9\u05D1\u05D4. \u05E9\u05DE\u05E8\u05D5 \u05D0\u05D5\u05EA\u05D5 \u05DC\u05D7\u05E9\u05D1\u05D5\u05DF \u05E7\u05D5\u05D3\u05DD: npx deployai@latest claim",
|
|
22009
|
-
envInvalidKey: "\u05E9\u05DD \u05DE\u05E9\u05EA\u05E0\u05D4: \u05D0\u05D5\u05EA\u05D9\u05D5\u05EA \u05D1\u05D0\u05E0\u05D2\u05DC\u05D9\u05EA, \u05E1\u05E4\u05E8\u05D5\u05EA \u05D5-_, \
|
|
22056
|
+
envInvalidKey: "\u05E9\u05DD \u05DE\u05E9\u05EA\u05E0\u05D4: \u05D0\u05D5\u05EA\u05D9\u05D5\u05EA \u05D2\u05D3\u05D5\u05DC\u05D5\u05EA \u05D1\u05D0\u05E0\u05D2\u05DC\u05D9\u05EA, \u05E1\u05E4\u05E8\u05D5\u05EA \u05D5-_, \u05DE\u05EA\u05D7\u05D9\u05DC \u05D1\u05D0\u05D5\u05EA, \u05E2\u05D3 64 \u05EA\u05D5\u05D5\u05D9\u05DD, \u05DB\u05DE\u05D5 STRIPE_KEY.",
|
|
22010
22057
|
envTooLong: "\u05D4\u05E2\u05E8\u05DA \u05D2\u05D3\u05D5\u05DC \u05DE\u05BE5KB, \u05D0\u05E8\u05D5\u05DA \u05DE\u05D3\u05D9 \u05DC\u05DE\u05E9\u05EA\u05E0\u05D4.",
|
|
22011
22058
|
envSendFailed: "\u05D4\u05E1\u05D5\u05D3 \u05DC\u05D0 \u05D4\u05D2\u05D9\u05E2 \u05DC\u05D0\u05EA\u05E8. \u05E0\u05E1\u05D5 \u05E9\u05D5\u05D1 \u05D1\u05E2\u05D5\u05D3 \u05D3\u05E7\u05D4.",
|
|
22012
22059
|
envNoKey: "\u05DC\u05D0\u05EA\u05E8 \u05D0\u05D9\u05DF \u05DE\u05E9\u05EA\u05E0\u05D4 \u05D1\u05E9\u05DD \u05D4\u05D6\u05D4. \u05DC\u05E8\u05E9\u05D9\u05DE\u05D4: npx deployai@latest env list",
|
|
@@ -22109,7 +22156,7 @@ function messages(root) {
|
|
|
22109
22156
|
}
|
|
22110
22157
|
|
|
22111
22158
|
// src/version.ts
|
|
22112
|
-
var CLI_VERSION = "0.1.0-beta.
|
|
22159
|
+
var CLI_VERSION = "0.1.0-beta.7";
|
|
22113
22160
|
|
|
22114
22161
|
// src/api.ts
|
|
22115
22162
|
function apiContext(apiFlag) {
|
|
@@ -22338,7 +22385,7 @@ async function sendTelemetryEvent(ctx, event) {
|
|
|
22338
22385
|
}
|
|
22339
22386
|
|
|
22340
22387
|
// src/commands/init.ts
|
|
22341
|
-
import { existsSync as existsSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
22388
|
+
import { appendFileSync, existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
22342
22389
|
import { join as join5 } from "path";
|
|
22343
22390
|
|
|
22344
22391
|
// src/analyze.ts
|
|
@@ -22506,6 +22553,7 @@ function planUpload(root) {
|
|
|
22506
22553
|
}
|
|
22507
22554
|
|
|
22508
22555
|
// src/analyze.ts
|
|
22556
|
+
var INIT_FILES = /* @__PURE__ */ new Set(["DEPLOYAI.md", "AGENTS.md", "CLAUDE.md"]);
|
|
22509
22557
|
var CODE_EXT = /\.(js|jsx|ts|tsx|mjs|cjs|mts|cts|vue|svelte|astro)$/;
|
|
22510
22558
|
var SECRET_SCAN_EXT = /\.(js|jsx|ts|tsx|mjs|cjs|mts|cts|vue|svelte|astro|json|ya?ml|toml|html|prisma)$/;
|
|
22511
22559
|
var LOCKFILES = /* @__PURE__ */ new Set(["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"]);
|
|
@@ -22863,7 +22911,7 @@ function analyzeProject(root) {
|
|
|
22863
22911
|
}
|
|
22864
22912
|
const otherStack = detectOtherStack(files.map((f) => f.rel));
|
|
22865
22913
|
if (otherStack) add({ code: "other_stack", severity: "blocker", detail: ` ${otherStack.name}` });
|
|
22866
|
-
const empty = !files.some((f) => !f.rel.startsWith(".deployai/") && f.rel
|
|
22914
|
+
const empty = !files.some((f) => !f.rel.startsWith(".deployai/") && !INIT_FILES.has(f.rel) && !isEnvFile(f.rel.split("/").pop() ?? ""));
|
|
22867
22915
|
if (empty) add({ code: "no_files", severity: "blocker" });
|
|
22868
22916
|
if (framework.id === "unknown" && !otherStack && !empty) {
|
|
22869
22917
|
add({ code: "unknown_framework", severity: "warning", detail: framework.flavor ? ` (looks like ${framework.flavor})` : "" });
|
|
@@ -22961,13 +23009,28 @@ This project is published with DeployAI.
|
|
|
22961
23009
|
|
|
22962
23010
|
Always explain to the user in simple words, in the language they write to you in. The user may not read English.
|
|
22963
23011
|
|
|
22964
|
-
|
|
23012
|
+
Before you write code or change the plan, compare it with these rules. If something in it does not fit, say what and propose the change.
|
|
23013
|
+
|
|
23014
|
+
## Build with
|
|
23015
|
+
|
|
23016
|
+
${BUILD_WITH.map((l) => `- ${l}`).join("\n")}
|
|
23017
|
+
|
|
23018
|
+
To start from working code, see the samples: npx deployai@latest samples
|
|
23019
|
+
|
|
23020
|
+
## Do not add
|
|
23021
|
+
|
|
22965
23022
|
- local file system writes
|
|
22966
23023
|
- database drivers DeployAI does not support (see: npx deployai@latest inspect)
|
|
22967
23024
|
- long-running processes or background servers
|
|
22968
23025
|
- native binary modules
|
|
22969
23026
|
- DeployAI or any cloud credentials in source code
|
|
22970
23027
|
|
|
23028
|
+
## Keep existing data
|
|
23029
|
+
|
|
23030
|
+
${KEEP_DATA_RULES.join("\n")}
|
|
23031
|
+
|
|
23032
|
+
## Check
|
|
23033
|
+
|
|
22971
23034
|
Before adding a dependency or a new server feature, run: npx deployai@latest check
|
|
22972
23035
|
Ask the developer before removing any existing functionality.
|
|
22973
23036
|
|
|
@@ -22975,9 +23038,11 @@ Files:
|
|
|
22975
23038
|
- .deployai/project.json: project id and settings (safe to commit)
|
|
22976
23039
|
- .deployai/last-check.json: latest check result (not committed)
|
|
22977
23040
|
`;
|
|
23041
|
+
var AGENT_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
22978
23042
|
function runInit(root, opts = {}) {
|
|
22979
23043
|
const created = [];
|
|
22980
23044
|
const kept = [];
|
|
23045
|
+
const updated = [];
|
|
22981
23046
|
const md = join5(root, "DEPLOYAI.md");
|
|
22982
23047
|
if (existsSync5(md) && !opts.force) {
|
|
22983
23048
|
kept.push("DEPLOYAI.md");
|
|
@@ -22985,20 +23050,35 @@ function runInit(root, opts = {}) {
|
|
|
22985
23050
|
writeFileSync3(md, DEPLOYAI_MD);
|
|
22986
23051
|
created.push("DEPLOYAI.md");
|
|
22987
23052
|
}
|
|
23053
|
+
if (opts.agentFiles !== false) {
|
|
23054
|
+
for (const name of AGENT_FILES) {
|
|
23055
|
+
const file2 = join5(root, name);
|
|
23056
|
+
const text = existsSync5(file2) ? readFileSync5(file2, "utf8") : null;
|
|
23057
|
+
if (text === null) {
|
|
23058
|
+
writeFileSync3(file2, `${AGENT_POINTER}
|
|
23059
|
+
`);
|
|
23060
|
+
created.push(name);
|
|
23061
|
+
} else if (text.includes("DEPLOYAI.md")) {
|
|
23062
|
+
kept.push(name);
|
|
23063
|
+
} else {
|
|
23064
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
23065
|
+
const gap = !text.trim() ? "" : text.endsWith("\n") ? eol : eol + eol;
|
|
23066
|
+
appendFileSync(file2, `${gap}${AGENT_POINTER}${eol}`);
|
|
23067
|
+
updated.push(name);
|
|
23068
|
+
}
|
|
23069
|
+
}
|
|
23070
|
+
}
|
|
22988
23071
|
ensureDeployaiDir(root);
|
|
22989
23072
|
const existing = readProject(root);
|
|
23073
|
+
const framework = existing?.framework ?? analyzeProject(root).inspect.framework.id;
|
|
22990
23074
|
if (existing) {
|
|
22991
23075
|
kept.push(".deployai/project.json");
|
|
22992
23076
|
} else {
|
|
22993
|
-
|
|
22994
|
-
writeProject(root, {
|
|
22995
|
-
projectId: null,
|
|
22996
|
-
framework: analysis.inspect.framework.id,
|
|
22997
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22998
|
-
});
|
|
23077
|
+
writeProject(root, { projectId: null, framework, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
22999
23078
|
created.push(".deployai/project.json");
|
|
23000
23079
|
}
|
|
23001
|
-
|
|
23080
|
+
const hasCode = existsSync5(join5(root, "package.json")) || framework !== "unknown";
|
|
23081
|
+
return { created, kept, updated, hasCode };
|
|
23002
23082
|
}
|
|
23003
23083
|
function initCommand(root, opts) {
|
|
23004
23084
|
const res = runInit(root, opts);
|
|
@@ -23008,6 +23088,7 @@ function initCommand(root, opts) {
|
|
|
23008
23088
|
out(
|
|
23009
23089
|
rows([
|
|
23010
23090
|
...res.created.map((f) => ["Created", f]),
|
|
23091
|
+
...res.updated.map((f) => ["Added a line", `${f} (read DEPLOYAI.md)`]),
|
|
23011
23092
|
...res.kept.map((f) => ["Kept", f]),
|
|
23012
23093
|
["Guard", ".deployai/last-check.json (git ignored)"],
|
|
23013
23094
|
["Linked project", project?.projectId ?? "none yet"]
|
|
@@ -23015,12 +23096,18 @@ function initCommand(root, opts) {
|
|
|
23015
23096
|
);
|
|
23016
23097
|
out();
|
|
23017
23098
|
out("Next step");
|
|
23018
|
-
|
|
23099
|
+
if (res.hasCode) {
|
|
23100
|
+
out(" Run: npx deployai@latest check");
|
|
23101
|
+
} else {
|
|
23102
|
+
out(" Start from a sample: npx deployai@latest samples");
|
|
23103
|
+
out(" Or tell your agent what to build, or to review your plan. It follows DEPLOYAI.md.");
|
|
23104
|
+
}
|
|
23019
23105
|
if (!project?.projectId) out(" Then: npx deployai@latest login, npx deployai@latest link");
|
|
23020
23106
|
}
|
|
23021
23107
|
|
|
23022
23108
|
// src/commands/check.ts
|
|
23023
|
-
import { writeFileSync as writeFileSync4 } from "fs";
|
|
23109
|
+
import { existsSync as existsSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
23110
|
+
import { join as join6 } from "path";
|
|
23024
23111
|
|
|
23025
23112
|
// src/prompt.ts
|
|
23026
23113
|
var PROMPT_RULES = [
|
|
@@ -23030,8 +23117,10 @@ var PROMPT_RULES = [
|
|
|
23030
23117
|
"Keep the project runnable outside DeployAI.",
|
|
23031
23118
|
"Never add credentials to source code.",
|
|
23032
23119
|
"Explain every step to the user in simple words, in the language they write to you in.",
|
|
23033
|
-
"For the database, use D1 as shown in the DeployAI CRUD sample."
|
|
23120
|
+
"For the database, use D1 as shown in the DeployAI CRUD sample.",
|
|
23121
|
+
"Follow DEPLOYAI.md for every future change. If it is missing, run: npx deployai@latest init"
|
|
23034
23122
|
];
|
|
23123
|
+
var DATA_CODES = /* @__PURE__ */ new Set(["fs_write", "unsupported_db_postgres", "unsupported_db_mysql", "unsupported_db_mongodb", "unsupported_db_sqlite_file", "native_module_bcrypt"]);
|
|
23035
23124
|
var MAX_LOCATIONS = 3;
|
|
23036
23125
|
function locList(items) {
|
|
23037
23126
|
const locs = [...new Set(items.map(locationOf).filter(Boolean))];
|
|
@@ -23070,6 +23159,11 @@ function buildPrompt(analysis) {
|
|
|
23070
23159
|
if (def) lines.push(`- ${def.fixForAgent}`);
|
|
23071
23160
|
}
|
|
23072
23161
|
lines.push("");
|
|
23162
|
+
if (blockerGroups.some((g) => DATA_CODES.has(g.code))) {
|
|
23163
|
+
lines.push("Keep existing data:");
|
|
23164
|
+
lines.push(...KEEP_DATA_RULES);
|
|
23165
|
+
lines.push("");
|
|
23166
|
+
}
|
|
23073
23167
|
lines.push("Rules:");
|
|
23074
23168
|
for (const r of PROMPT_RULES) lines.push(`- ${r}`);
|
|
23075
23169
|
lines.push("");
|
|
@@ -23219,6 +23313,7 @@ async function runCheck(root, ctx, opts = {}) {
|
|
|
23219
23313
|
} else {
|
|
23220
23314
|
out(t("runDeploy"));
|
|
23221
23315
|
}
|
|
23316
|
+
if (!existsSync6(join6(root, "DEPLOYAI.md"))) out(t("initHint"));
|
|
23222
23317
|
}
|
|
23223
23318
|
await telemetry;
|
|
23224
23319
|
return a;
|
|
@@ -23432,7 +23527,7 @@ async function linkCommand(root, ctx, target, opts) {
|
|
|
23432
23527
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
23433
23528
|
|
|
23434
23529
|
// src/tar.ts
|
|
23435
|
-
import { readFileSync as
|
|
23530
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
23436
23531
|
import { gzipSync } from "zlib";
|
|
23437
23532
|
var BLOCK = 512;
|
|
23438
23533
|
function writeString(buf, offset, length, value) {
|
|
@@ -23516,7 +23611,7 @@ function packFiles(files) {
|
|
|
23516
23611
|
return createTarGz(
|
|
23517
23612
|
files.map((f) => ({
|
|
23518
23613
|
name: f.rel,
|
|
23519
|
-
data:
|
|
23614
|
+
data: readFileSync6(f.abs),
|
|
23520
23615
|
mtimeMs: f.mtimeMs,
|
|
23521
23616
|
mode: f.mode & 64 ? 493 : 420
|
|
23522
23617
|
}))
|
|
@@ -23719,8 +23814,8 @@ async function claimCommand(root, ctx, opts) {
|
|
|
23719
23814
|
|
|
23720
23815
|
// src/commands/samples.ts
|
|
23721
23816
|
import { createInterface as createInterface3 } from "readline/promises";
|
|
23722
|
-
import { existsSync as
|
|
23723
|
-
import { dirname, join as
|
|
23817
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
23818
|
+
import { dirname, join as join7, relative, resolve, sep } from "path";
|
|
23724
23819
|
import { gunzipSync } from "zlib";
|
|
23725
23820
|
var SAMPLES = [
|
|
23726
23821
|
{ key: "landing", title: "Landing page: a full one-page site with WhatsApp sign-up", stack: "static HTML and CSS" },
|
|
@@ -23731,7 +23826,7 @@ var SAMPLES = [
|
|
|
23731
23826
|
{ key: "admin", title: "Back office with login: dashboard, orders, stock, customers", stack: "Astro on Workers, D1" }
|
|
23732
23827
|
];
|
|
23733
23828
|
var MAX_BYTES = 20 * 1024 * 1024;
|
|
23734
|
-
var IGNORED = /* @__PURE__ */ new Set([".git", ".DS_Store", "Thumbs.db", ".deployai"]);
|
|
23829
|
+
var IGNORED = /* @__PURE__ */ new Set([".git", ".DS_Store", "Thumbs.db", ".deployai", "DEPLOYAI.md", "AGENTS.md", "CLAUDE.md"]);
|
|
23735
23830
|
function listSamples(apiUrl) {
|
|
23736
23831
|
out("DeployAI samples");
|
|
23737
23832
|
out("");
|
|
@@ -23741,7 +23836,7 @@ function listSamples(apiUrl) {
|
|
|
23741
23836
|
out(`See them live: ${apiUrl}/samples`);
|
|
23742
23837
|
}
|
|
23743
23838
|
function filesIn(dir) {
|
|
23744
|
-
return
|
|
23839
|
+
return existsSync7(dir) ? readdirSync3(dir).filter((f) => !IGNORED.has(f)) : [];
|
|
23745
23840
|
}
|
|
23746
23841
|
function freeFolder(cwd, key) {
|
|
23747
23842
|
for (let n2 = 1; ; n2++) {
|
|
@@ -23824,7 +23919,7 @@ async function samplesCommand(cwd, ctx, key, opts = {}) {
|
|
|
23824
23919
|
}
|
|
23825
23920
|
const written = await downloadSample(ctx, sample.key, root);
|
|
23826
23921
|
const base = resolve(root);
|
|
23827
|
-
const hasPackage =
|
|
23922
|
+
const hasPackage = existsSync7(join7(base, "package.json"));
|
|
23828
23923
|
out(base === resolve(cwd) ? `Downloaded the ${sample.key} sample: ${written} files.` : `Downloaded the ${sample.key} sample into the new folder ${relative(cwd, base)}: ${written} files. Work in that folder from now on.`);
|
|
23829
23924
|
out("");
|
|
23830
23925
|
const t = messages(base);
|
|
@@ -23946,6 +24041,8 @@ async function statusCommand(root, ctx) {
|
|
|
23946
24041
|
if (newer?.status === "ready") {
|
|
23947
24042
|
out();
|
|
23948
24043
|
out(t("nextStep"));
|
|
24044
|
+
out(t("askOwner", { n: newer.number }));
|
|
24045
|
+
if (s.latest?.preview) out(t("showPreview", { url: s.latest.preview }));
|
|
23949
24046
|
out(t("promoteReady", { n: newer.number }));
|
|
23950
24047
|
}
|
|
23951
24048
|
if (s.latest?.migrationStatus === "waiting") {
|
|
@@ -23967,8 +24064,8 @@ async function statusCommand(root, ctx) {
|
|
|
23967
24064
|
|
|
23968
24065
|
// src/commands/start.ts
|
|
23969
24066
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
23970
|
-
import { existsSync as
|
|
23971
|
-
import { join as
|
|
24067
|
+
import { existsSync as existsSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
24068
|
+
import { join as join8, relative as relative2, resolve as resolve2 } from "path";
|
|
23972
24069
|
var REASONS = { start_not_found: "startNotFound", start_expired: "startExpired", start_used_up: "startUsedUp" };
|
|
23973
24070
|
var reason = (code) => messages(process.cwd())(REASONS[code] ?? "startNotFound");
|
|
23974
24071
|
async function fetchStart(ctx, id) {
|
|
@@ -24006,19 +24103,20 @@ async function startCommand(cwd, ctx, id, opts = {}) {
|
|
|
24006
24103
|
if (sample && !sameSite) {
|
|
24007
24104
|
const written = await downloadSample(ctx, sample.key, root);
|
|
24008
24105
|
done.push(t("startDownloaded", { key: sample.key, n: written }));
|
|
24009
|
-
if (
|
|
24106
|
+
if (existsSync8(join8(root, "package.json"))) {
|
|
24010
24107
|
if (opts.install !== false && install(root)) done.push(t("startInstalled"));
|
|
24011
24108
|
else steps.unshift({ cmd: "npm install", say: "Installs the sample's packages." });
|
|
24012
24109
|
}
|
|
24013
24110
|
}
|
|
24014
24111
|
if (choices.brief) {
|
|
24015
24112
|
ensureDeployaiDir(root);
|
|
24016
|
-
writeFileSync6(
|
|
24113
|
+
writeFileSync6(join8(root, BRIEF_FILE), `# The owner's details
|
|
24017
24114
|
|
|
24018
24115
|
${choices.brief}
|
|
24019
24116
|
`);
|
|
24020
24117
|
done.push(t("startBrief", { file: BRIEF_FILE }));
|
|
24021
24118
|
}
|
|
24119
|
+
if (runInit(root).created.includes("DEPLOYAI.md")) done.push(t("startRules"));
|
|
24022
24120
|
if (choices.projectId) {
|
|
24023
24121
|
const before = readProject(root);
|
|
24024
24122
|
writeProject(root, { ...before ?? {}, projectId: choices.projectId, name: choices.name ?? void 0, slug: choices.slug ?? void 0, createdAt: before?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString() });
|
|
@@ -24044,7 +24142,7 @@ ${choices.brief}
|
|
|
24044
24142
|
}
|
|
24045
24143
|
|
|
24046
24144
|
// src/commands/addon.ts
|
|
24047
|
-
import { readFileSync as
|
|
24145
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
24048
24146
|
import { resolve as resolve3 } from "path";
|
|
24049
24147
|
function linkedProjectId2(root) {
|
|
24050
24148
|
const id = readProject(root)?.projectId;
|
|
@@ -24125,7 +24223,7 @@ async function addonDoneCommand(root, ctx, runId, opts) {
|
|
|
24125
24223
|
let report;
|
|
24126
24224
|
if (opts.report) {
|
|
24127
24225
|
try {
|
|
24128
|
-
report = JSON.parse(
|
|
24226
|
+
report = JSON.parse(readFileSync7(resolve3(root, opts.report), "utf8"));
|
|
24129
24227
|
} catch {
|
|
24130
24228
|
throw new CliError(`Cannot read the report file ${opts.report} as JSON.`, 1, "usage");
|
|
24131
24229
|
}
|
|
@@ -24221,7 +24319,7 @@ function buildProgram() {
|
|
|
24221
24319
|
const g = (cmd) => cmd.optsWithGlobals();
|
|
24222
24320
|
const root = (cmd) => resolve4(g(cmd).dir ?? process.cwd());
|
|
24223
24321
|
const ctx = (cmd) => apiContext(g(cmd).api);
|
|
24224
|
-
program.command("init").description("create DEPLOYAI.md and .deployai/ guard files").option("--force", "overwrite DEPLOYAI.md").action((opts, cmd) => initCommand(root(cmd), opts));
|
|
24322
|
+
program.command("init").description("create DEPLOYAI.md and .deployai/ guard files").option("--force", "overwrite DEPLOYAI.md").option("--no-agent-files", "do not add the DEPLOYAI.md line to AGENTS.md and CLAUDE.md").action((opts, cmd) => initCommand(root(cmd), opts));
|
|
24225
24323
|
program.command("inspect").description("show framework, package manager, language, database, storage").option("--json", "machine readable output").action((opts, cmd) => inspectCommand(root(cmd), opts));
|
|
24226
24324
|
program.command("check").description("can this project run on DeployAI: blockers and warnings, with the AI prompt").option("--json", "machine readable output").option("--no-clipboard", "do not copy the prompt to the clipboard").action(async (opts, cmd) => {
|
|
24227
24325
|
const a = await runCheck(root(cmd), ctx(cmd), opts);
|