@cellapp/cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/packages/cli/src/data.js +4 -2
- package/dist/packages/cli/src/data.js.map +1 -1
- package/dist/packages/cli/src/deploy.js +20 -8
- package/dist/packages/cli/src/deploy.js.map +1 -1
- package/dist/packages/cli/src/main.js +16 -10
- package/dist/packages/cli/src/main.js.map +1 -1
- package/dist/packages/cli/src/origin.js +2 -1
- package/dist/packages/cli/src/origin.js.map +1 -1
- package/dist/packages/cli/src/update.js +57 -0
- package/dist/packages/cli/src/update.js.map +1 -0
- package/dist/packages/cli/src/version.js +2 -0
- package/dist/packages/cli/src/version.js.map +1 -0
- package/package.json +1 -1
- package/skills/cellapp-deploy/SKILL.md +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Cellapp CLI and Agent Skill
|
|
2
2
|
|
|
3
|
-
Cellapp publishes static HTML applications from a local project. The CLI builds and uploads only the chosen static output directory. The Agent Skill guides an AI agent through the same process.
|
|
3
|
+
Cellapp publishes static HTML applications from a local project. The CLI builds and uploads only the chosen static output directory. The Agent Skill guides an AI agent through the same process. The default control origin is `https://console.cellapp.ai`; use `--origin` or `CELLAPP_ORIGIN` for another service.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -17,17 +17,19 @@ Install the Agent Skill separately from this public GitHub repository:
|
|
|
17
17
|
npx skills add cellapp-ai/skills
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
The installable Skill lives at [`skills/cellapp-deploy/SKILL.md`](skills/cellapp-deploy/SKILL.md). Installing the Skill does not install the CLI.
|
|
20
|
+
The installable Skill lives at [`skills/cellapp-deploy/SKILL.md`](skills/cellapp-deploy/SKILL.md). Installing the Skill does not install the CLI. Contributors can use `npm ci`, `npm run build`, and `npm run cli -- --help` from this repository.
|
|
21
|
+
|
|
22
|
+
The CLI checks for a newer stable npm release on its first run each local day. If one is available, it prints an upgrade hint to stderr. To upgrade, run `npm install -g @cellapp/cli@latest`. The check sends no credentials or project data, times out after two seconds, and does not stop a command when offline. Its last-attempt date is stored in `~/.config/cellapp/update-check.json` (or under `--config-dir`).
|
|
21
23
|
|
|
22
24
|
## Deploy
|
|
23
25
|
|
|
24
26
|
```sh
|
|
25
|
-
cellapp login
|
|
26
|
-
cellapp deploy --project /absolute/project --output dist --build 'npm run build'
|
|
27
|
-
cellapp apps
|
|
27
|
+
cellapp login
|
|
28
|
+
cellapp deploy --project /absolute/project --output dist --build 'npm run build'
|
|
29
|
+
cellapp apps
|
|
28
30
|
```
|
|
29
31
|
|
|
30
|
-
Plain HTML directories do not need `--build`. Use `--spa` only if the site has client-side routes. The first deployment returns
|
|
32
|
+
Plain HTML directories do not need `--build`. Use `--spa` only if the site has client-side routes. The first deployment returns a `{app-slug}-{user-slug}.<apps-domain>` URL and an access key once; keep the key private. Add `--namespace <user-slug> --slug <app-slug>` on first deployment to choose it. The user slug must have at least three lowercase characters, digits or hyphens; reserved platform names are unavailable, and the combined host label must fit 63 characters. The owner console can change both slugs later; old addresses remain bound to the original application. Display names may repeat. Visitors first sign in with Cellapp. Restricted applications then require owner approval or access-key redemption; public applications admit any signed-in user. Rotating a key stops new redemptions and preserves existing user grants. `cellapp.json` stores the app association and pending deployment metadata without secrets. Credentials are stored in `~/.config/cellapp/` with private file permissions.
|
|
31
33
|
|
|
32
34
|
## Application data
|
|
33
35
|
|
|
@@ -12,8 +12,8 @@ function plan(value) {
|
|
|
12
12
|
return data;
|
|
13
13
|
}
|
|
14
14
|
export async function runData(client, action, projectPath, project, explicitAppID, manifestPath, allowDestructive = false) {
|
|
15
|
-
if (!['plan', 'apply', 'status', 'verify'].includes(action ?? ''))
|
|
16
|
-
throw new Error('Use data plan, apply, status, or
|
|
15
|
+
if (!['plan', 'apply', 'status', 'verify', 'reconcile'].includes(action ?? ''))
|
|
16
|
+
throw new Error('Use data plan, apply, status, verify, or reconcile');
|
|
17
17
|
const operation = action;
|
|
18
18
|
const appID = explicitAppID ?? project?.appId;
|
|
19
19
|
if (!appID || !/^[a-f0-9]{32}$/.test(appID))
|
|
@@ -21,6 +21,8 @@ export async function runData(client, action, projectPath, project, explicitAppI
|
|
|
21
21
|
const path = `/apps/${appID}/data`;
|
|
22
22
|
if (operation === 'status')
|
|
23
23
|
return { appId: appID, status: await client.request(path) };
|
|
24
|
+
if (operation === 'reconcile')
|
|
25
|
+
return { appId: appID, reconciliation: await client.request(`${path}/reconcile`, 'POST', {}) };
|
|
24
26
|
if (operation === 'verify')
|
|
25
27
|
return { appId: appID, verification: await client.request(`${path}/verify`, 'POST') };
|
|
26
28
|
const input = await readJSON(resolve(projectPath, manifestPath ?? 'cellapp.data.json'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../../packages/cli/src/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAU,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAK7D,SAAS,IAAI,CAAC,KAAc;IAC1B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClH,MAAM,IAAI,GAAG,KAAgC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7G,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;QACzF,OAAO,IAAI,CAAC,mBAAmB,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAChJ,OAAO,IAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,MAA0B,EAAE,WAAmB,EAAE,OAA4B,EACzH,aAAsB,EAAE,YAAqB,EAAE,gBAAgB,GAAG,KAAK;IACvE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../../packages/cli/src/data.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { lstat, readdir, readFile, realpath } from 'node:fs/promises';
|
|
1
|
+
import { lstat, readdir, readFile, realpath, unlink } from 'node:fs/promises';
|
|
2
2
|
import { resolve, relative, join, isAbsolute } from 'node:path';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { manifest, sha256, validPath } from '../../shared/src/artifacts.js';
|
|
5
5
|
import { AppError, ensure } from '../../shared/src/errors.js';
|
|
6
|
-
import { randomKey, requestID, saveJSON } from './client.js';
|
|
6
|
+
import { randomKey, requestID, saveJSON, readJSON } from './client.js';
|
|
7
7
|
import { readProject } from './project.js';
|
|
8
8
|
export async function build(command, project) {
|
|
9
9
|
if (!command)
|
|
@@ -45,7 +45,7 @@ export async function deploy(client, directory, options, notify) {
|
|
|
45
45
|
if (project && project.origin !== client.origin)
|
|
46
46
|
throw new Error('Project belongs to another control origin');
|
|
47
47
|
if (project?.appId && (options.namespace !== undefined || options.slug !== undefined)) {
|
|
48
|
-
throw new Error('
|
|
48
|
+
throw new Error('CLI slugs are set only when creating an application; change existing slugs in the owner console');
|
|
49
49
|
}
|
|
50
50
|
const output = options.output ?? project?.output;
|
|
51
51
|
ensure(output, 400, 'output_required', 'Specify --output with the static build directory');
|
|
@@ -61,11 +61,14 @@ export async function deploy(client, directory, options, notify) {
|
|
|
61
61
|
const limits = await client.request('/limits');
|
|
62
62
|
const files = await collect(outPath, limits);
|
|
63
63
|
project = { ...project, origin: client.origin, name: options.name ?? project?.name ?? 'My app', namespace: options.namespace ?? project?.namespace, slug: options.slug ?? project?.slug, output, build: command, spa: options.spa ?? project?.spa ?? false, createRequestId: project?.createRequestId ?? requestID() };
|
|
64
|
-
|
|
64
|
+
const keyPath = `${client.credentialFile}.create-${project.createRequestId}`;
|
|
65
|
+
let initialKey = (await readJSON(keyPath))?.key;
|
|
66
|
+
if (initialKey)
|
|
67
|
+
ensure(/^[a-f0-9]{64}$/.test(initialKey), 400, 'invalid_state', 'Pending application key is invalid');
|
|
65
68
|
if (!project.appId) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
initialKey ??= randomKey();
|
|
70
|
+
await saveJSON(keyPath, { key: initialKey }, true);
|
|
71
|
+
await saveJSON(configPath, project);
|
|
69
72
|
const body = { name: project.name, key: initialKey, requestId: project.createRequestId,
|
|
70
73
|
...(project.namespace ? { namespace: project.namespace } : {}), ...(project.slug ? { slug: project.slug } : {}) };
|
|
71
74
|
const create = () => client.request('/apps', 'POST', body);
|
|
@@ -74,8 +77,13 @@ export async function deploy(client, directory, options, notify) {
|
|
|
74
77
|
app = await create();
|
|
75
78
|
}
|
|
76
79
|
catch (e) {
|
|
77
|
-
if (e instanceof AppError)
|
|
80
|
+
if (e instanceof AppError) {
|
|
81
|
+
if (e.code === 'app_data_not_ready' && typeof e.details?.appId === 'string' && /^[a-f0-9]{32}$/.test(e.details.appId)) {
|
|
82
|
+
project.appId = e.details.appId;
|
|
83
|
+
await saveJSON(configPath, project);
|
|
84
|
+
}
|
|
78
85
|
throw e;
|
|
86
|
+
}
|
|
79
87
|
app = await create();
|
|
80
88
|
}
|
|
81
89
|
project.appId = app.id;
|
|
@@ -84,6 +92,8 @@ export async function deploy(client, directory, options, notify) {
|
|
|
84
92
|
const apps = await client.request('/apps');
|
|
85
93
|
const app = apps.find(a => a.id === project.appId);
|
|
86
94
|
ensure(app, 404, 'app_not_found', 'Linked app was deleted or belongs to another owner');
|
|
95
|
+
if (app.dataState !== 'ready')
|
|
96
|
+
await client.request(`/apps/${app.id}/data/reconcile`, 'POST', {});
|
|
87
97
|
const fingerprint = sha256(JSON.stringify({ files, spa: project.spa }));
|
|
88
98
|
if (project.pending && project.pending.fingerprint !== fingerprint)
|
|
89
99
|
project.pending = undefined;
|
|
@@ -106,6 +116,8 @@ export async function deploy(client, directory, options, notify) {
|
|
|
106
116
|
const result = await client.request(`${base}/${d.id}/publish`, 'POST', {});
|
|
107
117
|
delete project.pending;
|
|
108
118
|
await saveJSON(configPath, project);
|
|
119
|
+
if (initialKey)
|
|
120
|
+
await unlink(keyPath);
|
|
109
121
|
notify('静态应用已发布。');
|
|
110
122
|
return { ...result, namespace: app.namespace, slug: app.slug, aliasUrl: app.aliasUrl,
|
|
111
123
|
...(initialKey ? { accessKey: initialKey } : { keyUnchanged: true }) };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../../packages/cli/src/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../../packages/cli/src/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseArgs } from 'node:util';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
|
-
import { Client, randomKey, readJSON, saveJSON } from './client.js';
|
|
4
|
+
import { Client, randomKey, requestID, readJSON, saveJSON } from './client.js';
|
|
5
5
|
import { deploy } from './deploy.js';
|
|
6
6
|
import { AppError } from '../../shared/src/errors.js';
|
|
7
7
|
import { readProject } from './project.js';
|
|
8
8
|
import { selectOrigin } from './origin.js';
|
|
9
9
|
import { runData } from './data.js';
|
|
10
|
+
import { checkForUpdates } from './update.js';
|
|
10
11
|
const { values, positionals } = parseArgs({ allowPositionals: true, options: {
|
|
11
12
|
origin: { type: 'string' }, project: { type: 'string', default: '.' }, output: { type: 'string' },
|
|
12
13
|
build: { type: 'string' }, name: { type: 'string' }, namespace: { type: 'string' }, slug: { type: 'string' }, spa: { type: 'boolean' }, help: { type: 'boolean' },
|
|
@@ -16,16 +17,15 @@ const { values, positionals } = parseArgs({ allowPositionals: true, options: {
|
|
|
16
17
|
const [command, appId, dataAppId] = positionals;
|
|
17
18
|
const notify = (s) => process.stderr.write(s + '\n');
|
|
18
19
|
try {
|
|
20
|
+
await checkForUpdates(values['config-dir'], notify);
|
|
19
21
|
if (values.help || !command) {
|
|
20
|
-
process.stdout.write('cellapp <login|logout|deploy|apps|link|reset-key|delete|data> [app-id] --origin https://
|
|
22
|
+
process.stdout.write('cellapp <login|logout|deploy|apps|link|reset-key|delete|data> [app-id] [--origin https://console.cellapp.ai]\nDeploy: --project . --output dist [--build "npm run build"] [--namespace user-slug] [--slug app-slug] [--spa]\nLink: link <app-id> --project . --output dist\nData: data <plan|apply|status|verify|reconcile> [app-id] --project . [--manifest cellapp.data.json] [--allow-destructive]\nDefault origin: https://console.cellapp.ai\n');
|
|
21
23
|
}
|
|
22
24
|
else {
|
|
23
25
|
const projectPath = resolve(values.project);
|
|
24
26
|
const newProject = await readJSON(join(projectPath, 'cellapp.json'));
|
|
25
27
|
const legacyProject = await readJSON(join(projectPath, 'ohmyapp.json'));
|
|
26
28
|
const origin = selectOrigin(values.origin, newProject, legacyProject, process.env);
|
|
27
|
-
if (!origin)
|
|
28
|
-
throw new Error('Specify --origin or CELLAPP_ORIGIN');
|
|
29
29
|
const project = await readProject(projectPath);
|
|
30
30
|
const client = new Client(origin, values['config-dir']);
|
|
31
31
|
await client.load();
|
|
@@ -58,14 +58,20 @@ try {
|
|
|
58
58
|
else if (command === 'delete')
|
|
59
59
|
result = await client.request(`/apps/${appId}`, 'DELETE');
|
|
60
60
|
else if (command === 'link') {
|
|
61
|
+
if (project && project.origin !== client.origin)
|
|
62
|
+
throw new Error('Project belongs to another control origin');
|
|
61
63
|
const apps = await client.request('/apps');
|
|
62
|
-
|
|
64
|
+
const app = apps.find(a => a.id === appId);
|
|
65
|
+
if (!app)
|
|
63
66
|
throw new Error('Application not owned by this credential');
|
|
64
|
-
if (
|
|
65
|
-
throw new Error('
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
if (project?.appId && project.appId !== appId)
|
|
68
|
+
throw new Error('Project is already linked to another application');
|
|
69
|
+
const output = values.output ?? project?.output;
|
|
70
|
+
if (!output)
|
|
71
|
+
throw new Error('Specify --output to link a new project');
|
|
72
|
+
const linked = { ...project, origin: client.origin, appId, name: project?.name ?? app.name, namespace: app.namespace, slug: app.slug, output, spa: project?.spa ?? false, createRequestId: project?.createRequestId ?? requestID() };
|
|
73
|
+
delete linked.pending;
|
|
74
|
+
await saveJSON(join(projectPath, 'cellapp.json'), linked);
|
|
69
75
|
result = { linked: appId };
|
|
70
76
|
}
|
|
71
77
|
else
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../packages/cli/src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../packages/cli/src/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
export const DEFAULT_ORIGIN = 'https://console.cellapp.ai';
|
|
1
2
|
export function selectOrigin(explicit, current, legacy, environment) {
|
|
2
|
-
return explicit ?? current?.origin ?? environment.CELLAPP_ORIGIN ?? legacy?.origin ?? environment.OHMYAPP_ORIGIN;
|
|
3
|
+
return explicit ?? current?.origin ?? (environment.CELLAPP_ORIGIN || undefined) ?? legacy?.origin ?? (environment.OHMYAPP_ORIGIN || undefined) ?? DEFAULT_ORIGIN;
|
|
3
4
|
}
|
|
4
5
|
//# sourceMappingURL=origin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"origin.js","sourceRoot":"","sources":["../../../../packages/cli/src/origin.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,QAA4B,EAAE,OAA4B,EAAE,MAA2B,EAAE,WAA8B;IAClJ,OAAO,QAAQ,IAAI,OAAO,EAAE,MAAM,IAAI,WAAW,CAAC,cAAc,IAAI,MAAM,EAAE,MAAM,IAAI,WAAW,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"origin.js","sourceRoot":"","sources":["../../../../packages/cli/src/origin.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAE3D,MAAM,UAAU,YAAY,CAAC,QAA4B,EAAE,OAA4B,EAAE,MAA2B,EAAE,WAA8B;IAClJ,OAAO,QAAQ,IAAI,OAAO,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,IAAI,SAAS,CAAC,IAAI,MAAM,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,IAAI,SAAS,CAAC,IAAI,cAAc,CAAC;AACnK,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readJSON, saveJSON } from './client.js';
|
|
4
|
+
import { CLI_VERSION } from './version.js';
|
|
5
|
+
const REGISTRY_URL = 'https://registry.npmjs.org/@cellapp%2Fcli/latest';
|
|
6
|
+
function localDate(now) {
|
|
7
|
+
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
|
8
|
+
}
|
|
9
|
+
function stableVersion(value) {
|
|
10
|
+
if (typeof value !== 'string' || !/^\d+\.\d+\.\d+$/.test(value))
|
|
11
|
+
return undefined;
|
|
12
|
+
const parts = value.split('.').map(Number);
|
|
13
|
+
return parts.every(Number.isSafeInteger) ? parts : undefined;
|
|
14
|
+
}
|
|
15
|
+
export function isNewerVersion(latest, current) {
|
|
16
|
+
const next = stableVersion(latest);
|
|
17
|
+
const installed = stableVersion(current);
|
|
18
|
+
if (!next || !installed)
|
|
19
|
+
return false;
|
|
20
|
+
for (let i = 0; i < 3; i++) {
|
|
21
|
+
if (next[i] > installed[i])
|
|
22
|
+
return true;
|
|
23
|
+
if (next[i] < installed[i])
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
export async function checkForUpdates(configDirectory, notify, now = new Date(), fetcher = fetch) {
|
|
29
|
+
const statePath = join(configDirectory ?? join(homedir(), '.config', 'cellapp'), 'update-check.json');
|
|
30
|
+
const date = localDate(now);
|
|
31
|
+
try {
|
|
32
|
+
let state;
|
|
33
|
+
try {
|
|
34
|
+
state = await readJSON(statePath);
|
|
35
|
+
}
|
|
36
|
+
catch { /* Replace invalid local state. */ }
|
|
37
|
+
if (state && typeof state === 'object' && 'date' in state && state.date === date)
|
|
38
|
+
return;
|
|
39
|
+
// Record the attempt first so an offline machine does not retry on every command.
|
|
40
|
+
await saveJSON(statePath, { date }, true);
|
|
41
|
+
const response = await fetcher(REGISTRY_URL, {
|
|
42
|
+
headers: { Accept: 'application/json' },
|
|
43
|
+
redirect: 'error',
|
|
44
|
+
signal: AbortSignal.timeout(2_000),
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok)
|
|
47
|
+
return;
|
|
48
|
+
const metadata = await response.json();
|
|
49
|
+
if (!metadata || typeof metadata !== 'object' || !('version' in metadata))
|
|
50
|
+
return;
|
|
51
|
+
if (isNewerVersion(metadata.version, CLI_VERSION)) {
|
|
52
|
+
notify(`发现新版 @cellapp/cli ${metadata.version}(当前 ${CLI_VERSION})。运行 npm install -g @cellapp/cli@latest 更新。`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch { /* Update checks never change the requested command's result. */ }
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../../packages/cli/src/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../../packages/cli/src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ description: Build and publish a static Cellapp frontend, manage its PostgreSQL
|
|
|
5
5
|
|
|
6
6
|
# Develop and deploy a Cellapp application
|
|
7
7
|
|
|
8
|
-
Use the installed `cellapp` CLI. Installing this Skill does not install the CLI; if it is unavailable, direct the user to the public repository README. Use the
|
|
8
|
+
Use the installed `cellapp` CLI. Installing this Skill does not install the CLI; if it is unavailable, direct the user to the public repository README. Use an origin supplied by the user, existing project configuration, or `CELLAPP_ORIGIN` when present; otherwise the CLI defaults to `https://console.cellapp.ai`. Preserve `ohmyapp.json` and `OHMYAPP_ORIGIN` migration behavior. Do not invent another origin or store a credential in the project.
|
|
9
9
|
|
|
10
10
|
## Inspect
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ Read `cellapp.json`, the existing build command, static output directory, and `c
|
|
|
13
13
|
|
|
14
14
|
## Choose an application reference
|
|
15
15
|
|
|
16
|
-
The display name may repeat. Every owner has one public namespace, and
|
|
16
|
+
The display name may repeat. Every owner has one public user slug (`namespace` in the API and CLI), and application slugs are unique inside it. On the first deployment a new owner may choose `--namespace <user-slug>`; each new app may choose `--slug <app-slug>`. Both use lowercase ASCII letters, digits and hyphens and start with a letter. The user slug needs at least three characters, reserved names such as `accounts`, `cloud`, `login` and `app` are unavailable, and `{app-slug}-{user-slug}` must fit one 63-character DNS label. Without choices, Cellapp assigns a privacy-preserving user slug and an application slug derived from the display name, adding a suffix on collision. Existing owners must reuse their established user slug for CLI creation. The console can update either slug after creation. The returned URL uses `{app-slug}-{user-slug}.<apps-domain>`; prior addresses remain assigned to the original app. The `@user-slug/app-slug` share link redirects to the current host. Never treat a slug or display name as an authorization identity; app access and tables remain bound to the immutable app ID.
|
|
17
17
|
|
|
18
18
|
## Plan, apply, and verify tables
|
|
19
19
|
|
|
@@ -44,4 +44,4 @@ Run `cellapp deploy --project <project> --output <output-directory> --build <exi
|
|
|
44
44
|
|
|
45
45
|
The first deployment returns an access key once. Give it only to the requesting owner; never put it in a URL, repository, issue or project state. Old keys can be redeemed only after platform login. `cellapp reset-key <app-id>` rotates future redemption; existing user grants remain active. Revoke an individual grant in the owner console. Use reset or delete only when requested. A lost initial key can be explicitly rotated.
|
|
46
46
|
|
|
47
|
-
On transient upload/network failure, retry the same deploy command once: pending project metadata reuses the operation. Stop after another failure and report the error. A release version conflict needs review. For data errors use `data status` and `data verify`; do not claim a table-dependent frontend is ready while its data API is unready. Browser local-only state does not synchronize between devices; managed table data does.
|
|
47
|
+
On transient upload/network failure, retry the same deploy command once: pending project metadata reuses the operation. Stop after another failure and report the error. A release version conflict needs review. If creation reports `app_data_not_ready`, keep `cellapp.json`, inspect `cellapp data status --project <project>` and retry `cellapp data reconcile --project <project>` after the platform data service is healthy; then retry deploy. Do not switch slugs or delete the app to work around this error. For an app created by an older CLI without `cellapp.json`, run `cellapp link <app-id> --project <project> --output <output-directory>` using an ID verified in `cellapp apps`. The CLI keeps the initial access key only in its private credential directory until publication; never copy it into project files. For data errors use `data status` and `data verify`; do not claim a table-dependent frontend is ready while its data API is unready. Browser local-only state does not synchronize between devices; managed table data does.
|