@rebasepro/cli 0.22.0 → 0.24.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.
Files changed (80) hide show
  1. package/README.md +19 -3
  2. package/bin/rebase.js +1 -1
  3. package/dist/{branch-pointer-dBiClJ0p.js → branch-pointer-kk9F5FBO.js} +2 -2
  4. package/dist/{branch-pointer-dBiClJ0p.js.map → branch-pointer-kk9F5FBO.js.map} +1 -1
  5. package/dist/bundle.d.ts +16 -2
  6. package/dist/cli.d.ts +39 -0
  7. package/dist/commands/__test_support__/parser-specs.d.ts +13 -0
  8. package/dist/commands/agent-setup.d.ts +116 -0
  9. package/dist/commands/api-keys.d.ts +85 -22
  10. package/dist/commands/apps.d.ts +19 -0
  11. package/dist/commands/auth.d.ts +19 -0
  12. package/dist/commands/build.d.ts +13 -1
  13. package/dist/commands/cloud/auth.d.ts +4 -3
  14. package/dist/commands/cloud/bundle-deploy.d.ts +79 -5
  15. package/dist/commands/cloud/context.d.ts +87 -5
  16. package/dist/commands/cloud/cron.d.ts +53 -0
  17. package/dist/commands/cloud/db-connect.d.ts +15 -0
  18. package/dist/commands/cloud/debug.d.ts +134 -0
  19. package/dist/commands/cloud/deploy.d.ts +55 -2
  20. package/dist/commands/cloud/domains.d.ts +2 -2
  21. package/dist/commands/cloud/env.d.ts +14 -0
  22. package/dist/commands/cloud/index.d.ts +89 -12
  23. package/dist/commands/cloud/rebuild-source.d.ts +24 -2
  24. package/dist/commands/cloud/token-capabilities.d.ts +76 -0
  25. package/dist/commands/cloud/tokens.d.ts +23 -0
  26. package/dist/commands/db.d.ts +17 -1
  27. package/dist/commands/dev.d.ts +78 -7
  28. package/dist/commands/doctor.d.ts +5 -0
  29. package/dist/commands/generate_sdk.d.ts +3 -2
  30. package/dist/commands/init.d.ts +57 -14
  31. package/dist/commands/schema.d.ts +8 -0
  32. package/dist/commands/skills.d.ts +111 -5
  33. package/dist/commands/start.d.ts +29 -0
  34. package/dist/commands/telemetry.d.ts +10 -0
  35. package/dist/{daemon-DR9Tk0La.js → daemon-C8p32i-n.js} +5 -3
  36. package/dist/daemon-C8p32i-n.js.map +1 -0
  37. package/dist/dev-db/daemon.d.ts +10 -0
  38. package/dist/dev-db/prepare.d.ts +10 -0
  39. package/dist/dev-db/pull.d.ts +31 -2
  40. package/dist/dev-db/resolve.d.ts +2 -4
  41. package/dist/fold-static.d.ts +28 -3
  42. package/dist/index.es.js +13360 -9756
  43. package/dist/index.es.js.map +1 -1
  44. package/dist/manifest.d.ts +41 -1
  45. package/dist/package-manager-CXQevsE1.js +193 -0
  46. package/dist/package-manager-CXQevsE1.js.map +1 -0
  47. package/dist/{project-3WCbrrfW.js → project-DmaGLmH2.js} +4 -183
  48. package/dist/project-DmaGLmH2.js.map +1 -0
  49. package/dist/{pull-Bj0XnH5s.js → pull-Dywm5FWP.js} +41 -5
  50. package/dist/{pull-Bj0XnH5s.js.map → pull-Dywm5FWP.js.map} +1 -1
  51. package/dist/{resolve-Y56osuQH.js → resolve-BAeRUBhg.js} +2 -2
  52. package/dist/resolve-BAeRUBhg.js.map +1 -0
  53. package/dist/upgrade.d.ts +24 -3
  54. package/dist/utils/path-flags.d.ts +18 -0
  55. package/dist/utils/tool-stdio.d.ts +11 -0
  56. package/dist/version-DsgBmP22.js +58 -0
  57. package/dist/version-DsgBmP22.js.map +1 -0
  58. package/package.json +8 -8
  59. package/templates/eject/backend/src/index.ts +14 -1
  60. package/templates/overlays/baas/ai-instructions.md +1 -1
  61. package/templates/overlays/baas/config/storage.ts +5 -3
  62. package/templates/template/.cursorrules +1 -1
  63. package/templates/template/.env.example +10 -6
  64. package/templates/template/.github/copilot-instructions.md +1 -1
  65. package/templates/template/.mcp.json +2 -2
  66. package/templates/template/.windsurfrules +1 -1
  67. package/templates/template/AGENTS.md +1 -1
  68. package/templates/template/CLAUDE.md +1 -1
  69. package/templates/template/README.md +10 -11
  70. package/templates/template/ai-instructions.md +3 -3
  71. package/templates/template/backend/functions/hello.ts +8 -0
  72. package/templates/template/backend/package.json +1 -1
  73. package/templates/template/config/storage.ts +5 -3
  74. package/templates/template/docker-compose.yml +6 -6
  75. package/templates/template/gitignore +6 -1
  76. package/templates/template/package.json +4 -3
  77. package/templates/template/scripts/example.ts +4 -3
  78. package/dist/daemon-DR9Tk0La.js.map +0 -1
  79. package/dist/project-3WCbrrfW.js.map +0 -1
  80. package/dist/resolve-Y56osuQH.js.map +0 -1
@@ -18,7 +18,26 @@ export declare function setContextOrg(url: string, org: string | undefined): voi
18
18
  export declare function getContextOrg(url: string): string | undefined;
19
19
  /** Mark a host as the active context (called on login). */
20
20
  export declare function setCurrentContext(url: string): void;
21
+ /**
22
+ * Where the control-plane URL came from. `link` is the one a repository chose
23
+ * rather than the user — see {@link isKnownControlPlane}.
24
+ */
25
+ export type CloudUrlSource = "flag" | "env" | "link" | "context" | "default";
21
26
  export declare function resolveCloudUrl(rawArgs: string[]): string;
27
+ /** The control-plane URL, and which rung of the ladder above supplied it. */
28
+ export declare function resolveCloudTarget(rawArgs: string[]): {
29
+ url: string;
30
+ source: CloudUrlSource;
31
+ };
32
+ /**
33
+ * Whether a control-plane host is one the user chose: the platform's own, or a
34
+ * host already in their credentials file because they signed in to it.
35
+ *
36
+ * A link file is part of the repository, and a cloned repository is not the
37
+ * user's to trust with their password. `login` asks before sending one to a
38
+ * linked host that is neither.
39
+ */
40
+ export declare function isKnownControlPlane(url: string): boolean;
22
41
  /**
23
42
  * Refuse to run a control-plane command in a directory linked straight at a
24
43
  * backend.
@@ -41,14 +60,75 @@ export type CloudClient = ReturnType<typeof createRebaseClient>;
41
60
  */
42
61
  export declare function createCloudClient(url: string): CloudClient;
43
62
  /**
44
- * Return an authenticated client for the resolved host, refreshing the access
45
- * token if it is close to expiry. Exits with a helpful message when there is no
46
- * usable session (never logged in, or the refresh token was revoked).
63
+ * The environment variable that authenticates the cloud family with a token
64
+ * instead of a `cloud login` session — for CI and agents, which have no
65
+ * terminal to log in at and should not hold a person's password.
66
+ */
67
+ export declare const TOKEN_ENV = "REBASE_TOKEN";
68
+ /** `REBASE_TOKEN`, trimmed, or undefined when it is unset or blank. */
69
+ export declare function envToken(): string | undefined;
70
+ /**
71
+ * A client that sends `token` as its bearer and nothing else.
72
+ *
73
+ * No session: the token is not refreshed, and the credentials file is neither
74
+ * read nor written — a CI job's token must not become, or replace, the login
75
+ * of whoever owns the machine. A 401 is answered by {@link explainRefusedToken}
76
+ * rather than by the SDK's session refresh, because there is no session to
77
+ * refresh and "log in again" is the wrong remedy for a token.
78
+ */
79
+ export declare function createTokenClient(url: string, token: string): CloudClient;
80
+ /** The half of a client that holds its session — all {@link freshAccessToken} reads. */
81
+ export interface SessionHolder {
82
+ auth: {
83
+ getSession(): {
84
+ accessToken: string;
85
+ expiresAt: number;
86
+ } | null;
87
+ refreshSession(): Promise<{
88
+ accessToken: string;
89
+ }>;
90
+ };
91
+ }
92
+ /**
93
+ * An access token with time left on it, refreshed first if it is close to
94
+ * expiry. Rejects when there is no session, or it cannot be refreshed.
95
+ *
96
+ * For the requests the SDK does not make itself. Its own calls refresh and
97
+ * retry on a 401; a raw `fetch` or a tunnel handshake presents whatever token
98
+ * it was handed, and `createCloudClient` never refreshes in the background. A
99
+ * token read once at the start of a command that runs for longer than it
100
+ * lives — a deploy's build, a `db connect` left open — is refused by the time
101
+ * it is used, so it is read here at the moment it is sent.
102
+ *
103
+ * A client built from `REBASE_TOKEN` has no session; its token is returned
104
+ * as it is, since there is nothing to refresh it with.
105
+ */
106
+ export declare function freshAccessToken(client: SessionHolder): Promise<string>;
107
+ /**
108
+ * Return an authenticated client for the resolved host.
109
+ *
110
+ * With `REBASE_TOKEN` set, that token is the credential for every request and
111
+ * the stored login is not consulted at all. Otherwise it is the `cloud login`
112
+ * session — see {@link requireSessionClient}.
47
113
  */
48
114
  export declare function requireClient(rawArgs: string[]): Promise<{
49
115
  client: CloudClient;
50
116
  url: string;
51
117
  }>;
118
+ /**
119
+ * Return a client holding the `cloud login` session for the resolved host,
120
+ * refreshing the access token if it is close to expiry, whether or not
121
+ * `REBASE_TOKEN` is set. Exits with a helpful message when there is no usable
122
+ * session (never logged in, or the refresh token was revoked).
123
+ *
124
+ * For the commands a token cannot run — minting and revoking tokens: a key that
125
+ * could mint keys could mint its own successor, so the control plane refuses
126
+ * every key on those routes.
127
+ */
128
+ export declare function requireSessionClient(rawArgs: string[]): Promise<{
129
+ client: CloudClient;
130
+ url: string;
131
+ }>;
52
132
  /** One place a deploy can actually land, as the control plane describes it. */
53
133
  export interface DeployTarget {
54
134
  clusterId?: string | null;
@@ -149,8 +229,10 @@ export declare function removeLink(cwd?: string): boolean;
149
229
  * positional.
150
230
  *
151
231
  * Only genuinely global flags belong here. Group-specific ones (`--bucket`,
152
- * `--region`, …) are declared by the handler that owns them and always follow
153
- * the group, so they cannot shift the group or action.
232
+ * `--region`, …) are declared by the handler that owns them. They can still
233
+ * precede the action — or stand in for it, on a group with a default — so the
234
+ * dispatcher also declares every one that takes a value: `CLOUD_VALUE_FLAGS`
235
+ * in `index.ts`.
154
236
  *
155
237
  * `-p` is `--project` in eighteen places and `--password` in `login`. That
156
238
  * ambiguity does not matter to the one caller that reads this spec: it resolves
@@ -0,0 +1,53 @@
1
+ import { type CloudClient } from "./context.js";
2
+ /** The control-plane function that mints runtime tokens. */
3
+ export declare const RUNTIME_TOKEN_FUNCTION = "runtime-token";
4
+ /** The one scope these commands ask the platform for. */
5
+ export declare const CRON_READ_SCOPE = "cron:read";
6
+ /** What `runtime-token` answers. */
7
+ export interface RuntimeTokenResponse {
8
+ /** `rpt_…` — the bearer the runtime accepts. */
9
+ token: string;
10
+ /** ISO timestamp; past it the runtime refuses the token. */
11
+ expiresAt?: string;
12
+ /** What the token was granted, which may be narrower than what was asked. */
13
+ scopes?: string[];
14
+ }
15
+ /**
16
+ * A 404 that is about the route, not the project: the JSON envelope a Rebase
17
+ * backend answers for an unmatched path, or the bare one a router answers
18
+ * before that handler exists.
19
+ */
20
+ export declare function isMissingRoute(message: string | undefined): boolean;
21
+ /**
22
+ * Ask the control plane for a token the project's runtime will accept.
23
+ *
24
+ * A missing route means this control plane has no `runtime-token` function
25
+ * yet, which is a different fix from "no such project" and is said so.
26
+ */
27
+ export declare function mintRuntimeToken(client: CloudClient, projectId: string, scopes: string[]): Promise<RuntimeTokenResponse>;
28
+ /**
29
+ * GET a path on the runtime with a platform token, and refuse — with what it
30
+ * means for this command — anything but a 2xx.
31
+ *
32
+ * `notFound` words the 404, which means different things per route: no cron
33
+ * surface at all on the list, no such job on its logs.
34
+ */
35
+ export declare function runtimeGet<T>(origin: string, path: string, token: string, notFound: {
36
+ message: string;
37
+ hint?: string;
38
+ code: string;
39
+ }): Promise<T>;
40
+ /** `2026-10-05T10:31:00.000Z` → `2026-10-05 10:31:00Z`, or `—`. */
41
+ export declare function shortTime(iso: string | undefined): string;
42
+ /** Milliseconds as `850ms`, `2.4s` or `3m 10s`. */
43
+ export declare function shortDuration(ms: number | undefined): string;
44
+ /** The flags `cron list` parses — the help page lists exactly these. */
45
+ export declare const CRON_LIST_FLAGS: {
46
+ "--host": StringConstructor;
47
+ };
48
+ /** The flags `cron logs` parses — the help page lists exactly these. */
49
+ export declare const CRON_LOGS_FLAGS: {
50
+ "--limit": NumberConstructor;
51
+ "--host": StringConstructor;
52
+ };
53
+ export declare function cronCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
@@ -32,6 +32,7 @@
32
32
  * unreachable from a browser too.
33
33
  */
34
34
  import net from "node:net";
35
+ import { type SessionHolder } from "./context.js";
35
36
  /** Documented in `action-help.ts`, and paired with it by `action-help.test.ts`. */
36
37
  export declare const DB_CONNECT_FLAGS: {
37
38
  readonly "--port": NumberConstructor;
@@ -53,6 +54,20 @@ export declare function localDsn(opts: {
53
54
  password?: string;
54
55
  }): string;
55
56
  export declare function dbConnect(rawArgs: string[]): Promise<void>;
57
+ /**
58
+ * The local listener: each connection it accepts gets its own tunnel, signed in
59
+ * with a token that is current when the connection arrives.
60
+ *
61
+ * The command is left running for as long as the developer works, and the
62
+ * access token it started with lapses within the hour. Every connection is
63
+ * authenticated on its own, so each one reads the token then, refreshing it
64
+ * first when it is close to expiry — rather than the one read at startup, which
65
+ * the control plane refuses for every connection opened after it expires.
66
+ *
67
+ * The socket is paused while the token is read, so a client's first bytes wait
68
+ * for the tunnel exactly as they do once it is being established.
69
+ */
70
+ export declare function tunnelListener(client: SessionHolder, endpoint: string): net.Server;
56
71
  /**
57
72
  * One accepted connection, carried over one WebSocket.
58
73
  *
@@ -1,3 +1,4 @@
1
+ import { type CloudClient } from "./context.js";
1
2
  /** How a probe's outcome should be read. */
2
3
  export type Verdict =
3
4
  /** Behaving as a healthy deployment should. */
@@ -114,5 +115,138 @@ export declare function formatDuration(seconds: number): string;
114
115
  * into seconds. Returns null when it is not a duration.
115
116
  */
116
117
  export declare function parseSince(input: string | undefined): number | null;
118
+ /** One pod's entry in a `runtime-logs` answer. */
119
+ export interface RuntimeLogsPod {
120
+ pod: string;
121
+ state: string;
122
+ /** Lines this pod returned. */
123
+ lines: number;
124
+ message: string | null;
125
+ hint: string | null;
126
+ /** The server's per-pod BYTE budget cut this pod's output. Says nothing about the line limit. */
127
+ truncated?: boolean;
128
+ }
129
+ export interface RuntimeLogsResponse {
130
+ logs?: string;
131
+ pods?: RuntimeLogsPod[];
132
+ ordering?: string;
133
+ /** A byte budget or the pod-count ceiling cut the result. Says nothing about the line limit. */
134
+ truncated?: boolean;
135
+ state?: string;
136
+ message?: string | null;
137
+ }
138
+ /**
139
+ * The most lines `runtime-logs` returns per pod.
140
+ *
141
+ * The control plane enforces this (`MAX_TAIL_LINES` in
142
+ * `saas/backend/functions/runtime-logs.ts`) by clamping a larger `tailLines`
143
+ * without saying so: its answer names neither the limit nor the value it used.
144
+ * `--tail 200000` therefore came back as 2000 lines reported as untruncated.
145
+ * The CLI clamps first, with the same number, so the lowering is something it
146
+ * can print rather than something that happened out of sight.
147
+ */
148
+ export declare const SERVER_MAX_TAIL_LINES = 2000;
149
+ /** How many lines per pod a read asks for, and why that may be less than requested. */
150
+ export interface TailLimit {
151
+ /** What `--tail` asked for, or the view's default. */
152
+ requested: number;
153
+ /** What is sent: `requested`, lowered to {@link SERVER_MAX_TAIL_LINES}. */
154
+ applied: number;
155
+ /** Whether `--tail` was given, so a message can name the flag or the default. */
156
+ explicit: boolean;
157
+ /** Set when `applied < requested`: the sentence that says so. */
158
+ note: string | null;
159
+ }
160
+ export declare function resolveTail(requested: number, explicit: boolean): TailLimit;
161
+ /** What one pod's lines actually cover. */
162
+ export interface PodCoverage extends RuntimeLogsPod {
163
+ /** Earliest and latest timestamps among the lines this pod returned. */
164
+ firstTimestamp: string | null;
165
+ lastTimestamp: string | null;
166
+ /** A limit cut what this pod would otherwise have returned for the window. */
167
+ truncated: boolean;
168
+ /** Which limit: the per-pod line limit, or the server's byte budget. */
169
+ truncatedBy: "tail" | "bytes" | null;
170
+ /** The plain explanation, when truncated. */
171
+ truncatedReason: string | null;
172
+ /**
173
+ * Every line this pod holds in the window came back. With no window (read
174
+ * from the start), its first line is the start of its log.
175
+ */
176
+ complete: boolean;
177
+ }
178
+ /** The window asked for against the window delivered. */
179
+ export interface LogCoverage {
180
+ /** Start of the window asked for, ISO. Null when reading each pod from its start. */
181
+ requestedFrom: string | null;
182
+ /** Earliest and latest timestamps across every line returned. */
183
+ firstTimestamp: string | null;
184
+ lastTimestamp: string | null;
185
+ pods: PodCoverage[];
186
+ truncated: boolean;
187
+ truncatedReasons: string[];
188
+ }
189
+ /** A span of milliseconds as `29d 23h`, `2h 5m`, `35m`, `40s`. */
190
+ export declare function formatSpan(ms: number): string;
191
+ /**
192
+ * Compare what a read covered with what it asked for.
193
+ *
194
+ * The server's `truncated` describes only its byte budgets and pod ceiling, so
195
+ * a pod that filled the line limit came back marked complete however much of
196
+ * the window it left unread. The line limit is the cut that matters most, and
197
+ * it is detected here: a pod that returned as many lines as the limit, whose
198
+ * earliest line is later than the start of the window, was cut by it.
199
+ *
200
+ * Filling the limit is the half that separates a cut from a young pod. A pod
201
+ * that started an hour ago also has no line older than an hour; it returned
202
+ * fewer lines than the limit, so what came back is its whole log, and nothing
203
+ * was cut.
204
+ */
205
+ export declare function assessCoverage(opts: {
206
+ res: RuntimeLogsResponse;
207
+ lines: ParsedLogLine[];
208
+ /** The window asked for. Null reads each pod from its start. */
209
+ sinceSeconds: number | null;
210
+ tail: TailLimit;
211
+ now: number;
212
+ }): LogCoverage;
213
+ /**
214
+ * Resolve the public origin a project is served at — or `--host`, when given.
215
+ *
216
+ * Shared with `rebase cloud cron`, which reads the runtime at the same address
217
+ * `debug health` probes.
218
+ */
219
+ export declare function resolveOrigin(rawArgs: string[], client: CloudClient, url: string, projectId: string): Promise<string>;
220
+ /** What `debug logs`, `errors` and `boot` parse. Their help pairs against this. */
221
+ export declare const LOG_VIEW_FLAGS: {
222
+ readonly "--since": StringConstructor;
223
+ readonly "--tail": NumberConstructor;
224
+ readonly "--previous": BooleanConstructor;
225
+ };
226
+ /** What `debug requests` parses. */
227
+ export declare const REQUESTS_FLAGS: {
228
+ readonly "--since": StringConstructor;
229
+ readonly "--tail": NumberConstructor;
230
+ };
231
+ /** What `debug health` parses. */
232
+ export declare const HEALTH_FLAGS: {
233
+ readonly "--collection": StringConstructor;
234
+ readonly "--function": StringConstructor;
235
+ readonly "--host": StringConstructor;
236
+ };
237
+ /**
238
+ * Whether a boot read reached each pod's start, which is where its startup
239
+ * lines are. A pod whose read was cut has not been looked at there, so finding
240
+ * no startup lines in it means nothing — and a line from later in its life
241
+ * that happens to mention `storage` is not its startup.
242
+ *
243
+ * Under `--since` a pod is never counted as reached: a complete read of the
244
+ * window starts at the pod's first line only if the pod started inside it, and
245
+ * nothing in the answer says whether it did.
246
+ */
247
+ export declare function bootReach(pods: PodCoverage[], sinceSeconds: number | null): {
248
+ reachedStart: boolean;
249
+ unreached: string[];
250
+ };
117
251
  export declare function debugCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
118
252
  export declare function printDebugHelp(): void;
@@ -59,8 +59,22 @@ export declare function timeAgo(value: string | Date | undefined, now: Date): st
59
59
  * path.
60
60
  */
61
61
  export declare function isManagedProject(project: DeployProjectRow | undefined, latest: DeploySourceRow | undefined): boolean;
62
- /** What a `deploy` with nothing attached will build, in the words to print. */
63
- export declare function planBareDeploy(project: DeployProjectRow | undefined, latest: DeploySourceRow | undefined, now: Date): BareDeployPlan;
62
+ /**
63
+ * The deployment whose uploaded archive a bare deploy rebuilds, if any.
64
+ *
65
+ * The control plane's own rule (`reusableSourceRef`, over the newest 25 rows):
66
+ * the newest row, by its own `createdAt`, carrying a build-context ref. Not the
67
+ * newest row — a rollback or a bundle deploy carries none, and the upload
68
+ * rebuilt then is the one before it.
69
+ */
70
+ export declare function snapshotDeployment(recent: readonly DeploySourceRow[]): DeploySourceRow | undefined;
71
+ /**
72
+ * What a `deploy` with nothing attached will build, in the words to print.
73
+ *
74
+ * `recent` is the project's newest deployments, newest first — the same page
75
+ * the control plane reads to choose an archive.
76
+ */
77
+ export declare function planBareDeploy(project: DeployProjectRow | undefined, recent: readonly DeploySourceRow[], now: Date): BareDeployPlan;
64
78
  /**
65
79
  * A warning attached to a deploy: printed for the human, carried in the JSON.
66
80
  *
@@ -186,6 +200,8 @@ export declare const DEPLOY_FLAGS: {
186
200
  readonly "--bundle": BooleanConstructor;
187
201
  readonly "--bundle-dir": StringConstructor;
188
202
  readonly "--skip-type-check": BooleanConstructor;
203
+ readonly "--no-static": BooleanConstructor;
204
+ readonly "--skip-schema": BooleanConstructor;
189
205
  readonly "--eject": BooleanConstructor;
190
206
  readonly "--no-source": BooleanConstructor;
191
207
  readonly "--allow-downgrade": BooleanConstructor;
@@ -223,6 +239,8 @@ export declare function resolveDeployArgs(rawArgs: string[]): {
223
239
  readonly "--bundle": BooleanConstructor;
224
240
  readonly "--bundle-dir": StringConstructor;
225
241
  readonly "--skip-type-check": BooleanConstructor;
242
+ readonly "--no-static": BooleanConstructor;
243
+ readonly "--skip-schema": BooleanConstructor;
226
244
  readonly "--eject": BooleanConstructor;
227
245
  readonly "--no-source": BooleanConstructor;
228
246
  readonly "--allow-downgrade": BooleanConstructor;
@@ -290,6 +308,41 @@ export declare function deployedUrl(client: CloudClient, opts: {
290
308
  projectId?: string;
291
309
  url?: string;
292
310
  }): Promise<string | undefined>;
311
+ /**
312
+ * The line an in-progress build keeps rewriting at the end of its log, to prove
313
+ * to the control plane that it is still alive.
314
+ *
315
+ * The control plane's own format — `HEARTBEAT_MARKER` and `heartbeatSuffix` in
316
+ * its `functions/deploy.ts` — which appends `\n<marker><ISO time>\n` to the log
317
+ * on every write and every 30 seconds, and drops it on the terminal write.
318
+ */
319
+ export declare const BUILD_HEARTBEAT_MARKER = "\u23F3 Build in progress \u2014 control-plane heartbeat ";
320
+ /**
321
+ * A deployment's log without its trailing heartbeat line: the build log itself.
322
+ *
323
+ * Only a heartbeat that is the last line is one. The same text anywhere else is
324
+ * the build quoting it.
325
+ */
326
+ export declare function withoutHeartbeat(logs: string): string;
327
+ /**
328
+ * What to print of a deployment's log, given everything printed so far.
329
+ *
330
+ * The `logs` column is not append-only. Its heartbeat line is rewritten at the
331
+ * end on every write, and a failed static deploy replaces its whole log with
332
+ * one line. Diffing the raw column by length therefore cut the start off every
333
+ * new chunk — as many characters as the heartbeat that had been there — and
334
+ * printed heartbeat fragments in their place: a failed managed deploy lost the
335
+ * first half of its reason.
336
+ *
337
+ * So the heartbeat is stripped first, and the log printed so far is compared
338
+ * with the log now. When it has only grown, the new text is printed. When it
339
+ * was rewritten, printing resumes from the start of the first line that
340
+ * differs, on a line of its own.
341
+ */
342
+ export declare function nextLogChunk(printed: string, rowLogs: string): {
343
+ chunk: string;
344
+ printed: string;
345
+ };
293
346
  /** What `rebase cloud logs` parses. Its page pairs against this. */
294
347
  export declare const LOGS_FLAGS: {
295
348
  readonly "--runtime": BooleanConstructor;
@@ -1,11 +1,11 @@
1
1
  export declare function domainsCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
2
2
  /**
3
- * The domain `domains add` was asked to register.
3
+ * The domain an action was given, or undefined.
4
4
  *
5
5
  * Exported so its tests drive the real parser. Under the old operand filter
6
6
  * `rebase cloud domains add -p acme` registered a domain called "acme" — the
7
7
  * project slug, read out of `--project`'s own value — and a registered domain
8
8
  * is a project-record write, not a no-op.
9
9
  */
10
- export declare function resolveDomainArg(rawArgs: string[]): string | undefined;
10
+ export declare function resolveDomainArg(rawArgs: string[], action?: string): string | undefined;
11
11
  export declare function printDomainsHelp(): void;
@@ -57,4 +57,18 @@ export declare function resolveEnvSetArgs(rawArgs: string[]): {
57
57
  * count of command words is the same for all of them.
58
58
  */
59
59
  export declare function resolveEnvKeyArg(rawArgs: string[], action: string): string | undefined;
60
+ /**
61
+ * One `KEY=value` line that dotenv reads back as exactly `value`, or null when
62
+ * no quoting can carry it.
63
+ *
64
+ * dotenv's quoting is not JSON's, and `JSON.stringify` was what this used: a
65
+ * double-quoted value has only `\n` and `\r` unescaped, so every other
66
+ * backslash stayed and `{"a":1}` came back as `{\"a\":1}`. Single quotes and
67
+ * backticks are literal — nothing inside is unescaped, and either may span
68
+ * lines — so they carry any value without their own quote character. Double
69
+ * quotes come last: they cannot hold a `"` or a literal backslash-n, and they
70
+ * are the only way to carry a carriage return, which dotenv folds into a
71
+ * newline everywhere else.
72
+ */
73
+ export declare function dotenvLine(key: string, value: string): string | null;
60
74
  export declare function printEnvHelp(): void;
@@ -1,19 +1,96 @@
1
1
  import { type HelpAction } from "./context.js";
2
+ /**
3
+ * Every flag in the `rebase cloud` family that takes a value, and the short
4
+ * spellings of them — the globals aside, which `GLOBAL_CLOUD_FLAGS` declares.
5
+ *
6
+ * {@link positionals} needs them for one reason: `arg` only consumes a flag's
7
+ * value when the flag is declared, and an undeclared one leaves its value
8
+ * behind as a bare word in the action's position. `rebase cloud deployments
9
+ * --limit 5` dispatched to an action called "5", `rebase cloud debug --host
10
+ * staging.example.com` to one called "staging.example.com", and `rebase cloud
11
+ * projects --name shop create` to one called "shop" — each refused as an unknown
12
+ * command, for a line the command's own help offers.
13
+ *
14
+ * Every value is `String` whatever the command reads it as: only consumption
15
+ * matters here, and the command parses the value itself. One list for the whole
16
+ * family works because no flag takes a value in one command and none in
17
+ * another; `value-flags.test.ts` holds that, and holds this list to the specs
18
+ * the commands declare in both directions, so a new value flag fails a test
19
+ * until it is added here.
20
+ */
21
+ export declare const CLOUD_VALUE_FLAGS: {
22
+ readonly "--access-key-id": StringConstructor;
23
+ readonly "--autoscale-cpu-target": StringConstructor;
24
+ readonly "--autoscale-max": StringConstructor;
25
+ readonly "--backup-access-key-id": StringConstructor;
26
+ readonly "--backup-bucket": StringConstructor;
27
+ readonly "--backup-endpoint": StringConstructor;
28
+ readonly "--backup-secret-access-key": StringConstructor;
29
+ readonly "--base-domain": StringConstructor;
30
+ readonly "--branch": StringConstructor;
31
+ readonly "--bucket": StringConstructor;
32
+ readonly "--bundle-dir": StringConstructor;
33
+ readonly "--can": StringConstructor;
34
+ readonly "--collection": StringConstructor;
35
+ readonly "--connection-string": StringConstructor;
36
+ readonly "--cpu": StringConstructor;
37
+ readonly "--db": StringConstructor;
38
+ readonly "--db-cpu": StringConstructor;
39
+ readonly "--db-instances": StringConstructor;
40
+ readonly "--db-memory": StringConstructor;
41
+ readonly "--email": StringConstructor;
42
+ readonly "--endpoint": StringConstructor;
43
+ readonly "--events": StringConstructor;
44
+ readonly "--expires-in": StringConstructor;
45
+ readonly "--function": StringConstructor;
46
+ readonly "--host": StringConstructor;
47
+ readonly "--ingress-address": StringConstructor;
48
+ readonly "--kubeconfig": StringConstructor;
49
+ readonly "--limit": StringConstructor;
50
+ readonly "--memory": StringConstructor;
51
+ readonly "--message": StringConstructor;
52
+ readonly "--name": StringConstructor;
53
+ readonly "--org": StringConstructor;
54
+ readonly "--output": StringConstructor;
55
+ readonly "--password": StringConstructor;
56
+ readonly "--platform-rebuilds": StringConstructor;
57
+ readonly "--port": StringConstructor;
58
+ readonly "--provider": StringConstructor;
59
+ readonly "--region": StringConstructor;
60
+ readonly "--replicas": StringConstructor;
61
+ readonly "--repo": StringConstructor;
62
+ readonly "--scale-to-zero": StringConstructor;
63
+ readonly "--secret-access-key": StringConstructor;
64
+ readonly "--since": StringConstructor;
65
+ readonly "--slug": StringConstructor;
66
+ readonly "--source": StringConstructor;
67
+ readonly "--spot": StringConstructor;
68
+ readonly "--storage": StringConstructor;
69
+ readonly "--subdomain": StringConstructor;
70
+ readonly "--table": StringConstructor;
71
+ readonly "--tail": StringConstructor;
72
+ readonly "--target": StringConstructor;
73
+ readonly "--timeout": StringConstructor;
74
+ readonly "--type": StringConstructor;
75
+ readonly "--out": "--output";
76
+ readonly "-e": "--email";
77
+ readonly "-m": "--message";
78
+ readonly "-n": "--name";
79
+ };
2
80
  /**
3
81
  * Positional tokens after `rebase cloud` (group, action, …).
4
82
  *
5
- * Two things stop a flag being mistaken for the group. `GLOBAL_CLOUD_FLAGS` is
6
- * declared so `arg` *consumes* the flags that may precede it — critically
7
- * together with their values, which is the half that filtering cannot do. The
8
- * leading-`-` skip then covers a flag nobody declared, so an unrecognised
9
- * boolean shifts nothing.
10
- *
11
- * Only leading tokens are skipped: past the group and action, an undeclared
12
- * flag and its value are somebody else's positionals and none of our business.
13
- * A flag this file has never heard of, that takes a value, placed before the
14
- * group, is the one shape still unresolvable here — there is no way to know
15
- * whether the token after it is its value or the group, and guessing either way
16
- * is worse than the handler reporting an unknown group.
83
+ * Two things stop a flag being mistaken for the group or the action.
84
+ * `GLOBAL_CLOUD_FLAGS` and {@link CLOUD_VALUE_FLAGS} are declared so `arg`
85
+ * *consumes* every flag of the family that takes a value — critically together
86
+ * with its value, which is the half that filtering cannot do. The leading-`-`
87
+ * skip then covers a flag nobody declared, so an unrecognised boolean shifts
88
+ * nothing.
89
+ *
90
+ * A flag this family has never heard of, that takes a value, is the one shape
91
+ * still unresolvable here — there is no way to know whether the token after it
92
+ * is its value or the action. The command's own strict parse refuses that flag
93
+ * anyway, so the only cost is which refusal the caller reads.
17
94
  *
18
95
  * Exported so its tests can drive the real thing. The dispatch test used to
19
96
  * re-implement it locally as `slice(3).filter(a => !a.startsWith("-"))` — which
@@ -14,6 +14,12 @@ export declare const MAX_SOURCE_UPLOAD_BYTES: number;
14
14
  * bundles are never source. Every `.env` and `.env.*` is excluded except the
15
15
  * three template names, and so is direnv's `.envrc`, which is the same thing
16
16
  * under another name.
17
+ *
18
+ * So is what the CLI keeps on this machine: `.rebase/`, which holds the
19
+ * development database, and the `.rebase-dev-*` files beside it, one of which
20
+ * is the development signing secrets. And so is a `*.dump`, which is what
21
+ * `rebase db backup` writes: every row of the database, `rebase.users`
22
+ * password hashes included.
17
23
  */
18
24
  export declare function neverUploaded(relativePath: string): boolean;
19
25
  export interface SourceListing {
@@ -45,6 +51,21 @@ export type GitRunner = (cwd: string, args: string[]) => string;
45
51
  * archive with `../`.
46
52
  */
47
53
  export declare function listSourceFiles(projectRoot: string, git?: GitRunner): SourceListing;
54
+ /**
55
+ * The files of a `--source` build context: `dir` and what is under it, relative
56
+ * to it, POSIX, sorted.
57
+ *
58
+ * The same rules as the rebuild source — git decides, and {@link neverUploaded}
59
+ * after it — restricted to `dir`, which is the context's root, so a Dockerfile
60
+ * in it still reads its paths from there. A `dir` that is a subfolder of a
61
+ * repository is held to that repository's `.gitignore`, which is where a
62
+ * monorepo keeps it.
63
+ *
64
+ * `.rebaseignore` in `dir` leaves out more, read with `.gitignore` syntax and
65
+ * anchored at `dir`. It needs git to be read, like `.gitignore` outside a
66
+ * repository; without git, a context that has one is refused.
67
+ */
68
+ export declare function listContextFiles(dir: string, git?: GitRunner): string[];
48
69
  /**
49
70
  * Pack a listing into a gzipped tarball at `outPath`.
50
71
  *
@@ -54,7 +75,7 @@ export declare function listSourceFiles(projectRoot: string, git?: GitRunner): S
54
75
  * archive, as `packBundle` does; GNU tar accepts both. Every path handed to tar
55
76
  * is absolute, because GNU tar resolves a `-T` file after it has applied `-C`.
56
77
  */
57
- export declare function packSource(listing: SourceListing, outPath: string): Promise<void>;
78
+ export declare function packSource(listing: Pick<SourceListing, "root" | "files">, outPath: string): Promise<void>;
58
79
  /** Upload a source archive; returns the control plane's id for it. */
59
80
  export declare function uploadRebuildSource(url: string, token: string, projectId: string, tarPath: string): Promise<string>;
60
81
  /**
@@ -100,7 +121,8 @@ export interface RebuildSourceSteps {
100
121
  export declare function prepareRebuildSource(opts: {
101
122
  projectRoot: string;
102
123
  url: string;
103
- token: string;
124
+ /** The access token, read when the upload is sent rather than before the packing. */
125
+ token: () => Promise<string>;
104
126
  projectId: string;
105
127
  manifest?: RebaseProjectManifest;
106
128
  progress: (line: string) => void;