@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
@@ -0,0 +1,76 @@
1
+ /**
2
+ * What a Rebase Cloud token may do, named the way a person asks for it.
3
+ *
4
+ * A token is a personal API key on the control plane: it acts as the account
5
+ * that created it, and holds only the scopes it was given. Nobody should have
6
+ * to know that `rebase cloud deploy` reads the `deployments` collection, uploads
7
+ * through the `deploy` function and needs `project:deploy` on one project — so
8
+ * `rebase cloud tokens create --can deploy` and the console's token screen both
9
+ * ask for a capability, and this module turns capabilities into scopes.
10
+ *
11
+ * One map, read by the CLI and by the console. Each capability covers exactly
12
+ * the control-plane calls its commands make, traced from the commands
13
+ * themselves and held there by `token-capabilities.test.ts`, which runs them
14
+ * against a stand-in control plane that refuses everything a token does not
15
+ * hold:
16
+ *
17
+ * - `deploy` — `rebase cloud deploy` (bundle and source paths, uploads, the
18
+ * build follow) and `rebase cloud deployments`.
19
+ * - `logs` — `rebase cloud logs` (build, `--follow`, `--runtime`),
20
+ * `rebase cloud metrics` and `rebase cloud cron` — whose
21
+ * `runtime-token` call is how a token reads the app's own
22
+ * cron history.
23
+ * - `env` — `rebase cloud env list|set|unset|reveal|pull`.
24
+ * - `database` — `rebase cloud db list|info|connect`.
25
+ * - `backups` — `rebase cloud db backup list|create|status|download` and
26
+ * `db pitr status`. Restoring takes `project:restore`, which no
27
+ * capability grants: putting old data over a live database is
28
+ * for a signed-in person.
29
+ *
30
+ * Every project-level scope is narrowed to the one project the token is for
31
+ * (`project:deploy:<projectId>`). The data and function scopes cannot be: they
32
+ * name a collection or a function, not a row, and the control plane's
33
+ * row-level security keeps the token to what its owner can see.
34
+ *
35
+ * Deliberately free of imports, so the control plane's console can read the
36
+ * same file.
37
+ *
38
+ * @module
39
+ */
40
+ /** A capability a token can be given. */
41
+ export type TokenCapability = "deploy" | "logs" | "env" | "database" | "backups";
42
+ /** Every capability, in the order they are offered. */
43
+ export declare const TOKEN_CAPABILITY_NAMES: readonly TokenCapability[];
44
+ /**
45
+ * Scopes every token holds, whatever it was created for: resolving a project
46
+ * by its slug, reading the deployment a command follows, the organization a
47
+ * project belongs to, and the control plane's public description of itself.
48
+ */
49
+ export declare const ALWAYS_SCOPES: string[];
50
+ /** Each capability: what it lets a token do, and the scopes that does on one project. */
51
+ export declare const TOKEN_CAPABILITIES: Record<TokenCapability, {
52
+ label: string;
53
+ scopes: (projectId: string) => string[];
54
+ }>;
55
+ /** Whether a word names a capability. */
56
+ export declare function isTokenCapability(value: string): value is TokenCapability;
57
+ /**
58
+ * The scopes a token for `capabilities` on one project holds: {@link ALWAYS_SCOPES}
59
+ * first, then each capability's, each scope once.
60
+ *
61
+ * Throws on a project id a scope cannot carry — empty, or with whitespace — and
62
+ * on an unknown capability, both of which are a caller's mistake rather than
63
+ * something to mint a token from.
64
+ */
65
+ export declare function scopesForCapabilities(projectId: string, capabilities: readonly TokenCapability[]): string[];
66
+ /**
67
+ * Read a token's scopes back as capabilities: the projects its project scopes
68
+ * name, and, for each, the capabilities it holds every scope of.
69
+ *
70
+ * For showing a token — `rebase cloud tokens list`, `rebase cloud whoami` — so
71
+ * a list of fifteen scope strings reads as "deploy, logs on <project>".
72
+ */
73
+ export declare function capabilitiesInScopes(scopes: readonly string[]): Array<{
74
+ projectId: string;
75
+ capabilities: TokenCapability[];
76
+ }>;
@@ -0,0 +1,23 @@
1
+ import { type TokenCapability } from "./token-capabilities.js";
2
+ /** Every action the group dispatches. */
3
+ export declare const TOKENS_ACTIONS: readonly ["list", "create", "revoke"];
4
+ /** What `rebase cloud tokens create` parses, beside the global flags (`--project` among them). */
5
+ export declare const CREATE_TOKEN_FLAGS: {
6
+ "--can": [StringConstructor];
7
+ "--name": StringConstructor;
8
+ "--expires-in": StringConstructor;
9
+ };
10
+ export declare function tokensCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
11
+ /**
12
+ * The capabilities `--can` names, comma-separated or repeated, each once.
13
+ *
14
+ * Exported so its tests can drive it without a session.
15
+ */
16
+ export declare function parseCapabilities(values: readonly string[] | undefined): TokenCapability[];
17
+ /**
18
+ * `--expires-in <days>` as an ISO timestamp, or null for a token that does not
19
+ * expire.
20
+ *
21
+ * Exported so its tests can drive it without a session.
22
+ */
23
+ export declare function resolveTokenExpiry(value: string | undefined, now?: Date): string | null;
@@ -17,6 +17,20 @@ import { type DevDatabase } from "../dev-db/resolve.js";
17
17
  * it open.
18
18
  */
19
19
  export declare function databaseUrlOf(prepared: Pick<PreparedDatabase, "env" | "database">, envFile: Record<string, string>): string | undefined;
20
+ /**
21
+ * The flags whose value is a local path, on every line the CLI relays.
22
+ *
23
+ * All three spellings of the destination, because the driver accepts all
24
+ * three: `backup-cli.ts` maps `--output` and `-o` onto `--out`, and `rebase db
25
+ * backup --help` advertises `--output` as an alias. Only `--out` and `-o` were
26
+ * absolutised once, so the one spelling the help page names was the one that
27
+ * landed in `backend/` — and the success line still echoed the path as typed.
28
+ *
29
+ * And `--collections`, which was not absolutised at all: from the project root,
30
+ * `rebase schema generate --collections ./config/collections` was "not found",
31
+ * while the same spelling worked for `generate-sdk`. See `utils/path-flags.ts`.
32
+ */
33
+ export declare const LOCAL_PATH_FLAGS: readonly string[];
20
34
  /**
21
35
  * Rewrite local path arguments so they mean what the user typed.
22
36
  *
@@ -31,7 +45,7 @@ export declare function databaseUrlOf(prepared: Pick<PreparedDatabase, "env" | "
31
45
  * Absolutising here rather than inside the plugin keeps the fix where the cwd
32
46
  * is actually changed, and leaves the plugin usable on its own terms.
33
47
  */
34
- export declare function absolutizeLocalPathArgs(args: string[], cwd: string): string[];
48
+ export declare function absolutizeLocalPathArgs(args: string[], cwd: string, pathFlags?: readonly string[]): string[];
35
49
  /**
36
50
  * A managed-database refusal, raised so the caller decides what it costs.
37
51
  *
@@ -157,6 +171,8 @@ export declare function runDriverDbCommand(rawArgs: string[], options?: {
157
171
  quiet?: boolean;
158
172
  }): Promise<void>;
159
173
  export declare function dbCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
174
+ /** Every subcommand the family dispatches — the help table's keys. */
175
+ export declare const DB_SUBCOMMANDS: string[];
160
176
  /**
161
177
  * The examples, which are not the same on the managed development database.
162
178
  *
@@ -1,3 +1,4 @@
1
+ import { type AppAddress, type RebaseProjectManifest } from "@rebasepro/types";
1
2
  import { type PreparedDatabase } from "../dev-db/prepare.js";
2
3
  /**
3
4
  * The line the watcher prints when it is about to run the entry again.
@@ -65,15 +66,40 @@ export declare function portMovedNotice(line: string): {
65
66
  *
66
67
  * @param projectRoot Absolute path the relative entries are resolved against.
67
68
  * @param paths The `REBASE_DEV_*` map from {@link devRuntimeEnv}.
68
- * @param includeConfig Whether `config/` is watched here. It is only when
69
- * auto-generation is off; with `--generate` a dedicated
70
- * watcher already regenerates the schema and SDK, and tsx
71
- * restarts on the files that produces.
72
69
  */
73
70
  export declare function devWatchIncludes(projectRoot: string, paths: {
74
71
  REBASE_DEV_FUNCTIONS?: string;
75
72
  REBASE_DEV_CRONS?: string;
76
- }, includeConfig: boolean): string[];
73
+ }): string[];
74
+ /**
75
+ * The file dev writes to restart the backend, or `null` when tsx would not see it.
76
+ *
77
+ * Outside the project, so nothing appears in the developer's tree, and keyed by
78
+ * the project so two `rebase dev`s never restart each other. tsx ignores every
79
+ * path with a dot-named segment (its built-in `**\/.*\/**`), so a trigger under
80
+ * `.rebase/` — or under a TMPDIR inside a dot directory — would never fire; in
81
+ * that case there is no trigger and {@link devWatchArgs} leaves the
82
+ * collections to tsx, as before.
83
+ */
84
+ export declare function devRestartTrigger(projectRoot: string): string | null;
85
+ /**
86
+ * The `tsx watch` argument list for the backend (unquoted).
87
+ *
88
+ * One save of a collection file must restart the backend once. The runtime
89
+ * `import()`s the collections, so tsx tracks them as dependencies and used to
90
+ * restart the moment a file was saved — before dev had regenerated
91
+ * `schema.generated.ts`. That boot warned "schema.generated.ts no longer
92
+ * describes the database … Run `rebase schema generate`", telling the reader to
93
+ * run what dev was running at that moment, and the regeneration then rewrote
94
+ * the file and restarted the backend a second time. So tsx is told to leave the
95
+ * collections directory alone (`--exclude` wins over its dependency tracking),
96
+ * and dev restarts the backend itself, once, after the regeneration — through
97
+ * `restartTrigger`, which tsx watches.
98
+ */
99
+ export declare function devWatchArgs(projectRoot: string, paths: {
100
+ REBASE_DEV_FUNCTIONS?: string;
101
+ REBASE_DEV_CRONS?: string;
102
+ }, entryTarget: string, restartTrigger: string | null): string[];
77
103
  /** Well-known filename the backend writes its actual port to. */
78
104
  export declare const DEV_PORT_FILENAME = ".rebase-dev-port";
79
105
  /**
@@ -138,6 +164,53 @@ export declare function resolveStartPort(projectRoot: string, explicitPort?: num
138
164
  * Exported for its test.
139
165
  */
140
166
  export declare function databaseEndpoint(url: string | null | undefined): string | null;
167
+ /**
168
+ * What the start banner needs to know about a project's static apps.
169
+ *
170
+ * `rebase dev` runs one frontend: Vite in `frontend/`, at the root of its own
171
+ * localhost port, whatever path or hostname the manifest declares for it. So an
172
+ * app's local address and its deployed one are different things, and for an app
173
+ * with a hostname of its own they share nothing at all — appending its address
174
+ * to the local URL would print `http://localhost:5173https://admin.example.com`.
175
+ */
176
+ export interface DevStaticShape {
177
+ declaresStaticApp: boolean;
178
+ /** The declared app whose `root` is the `frontend/` that `rebase dev` runs, if one is. */
179
+ served?: {
180
+ appName: string;
181
+ address: AppAddress;
182
+ };
183
+ /** Where the CMS is, when an app declares one. */
184
+ cms?: {
185
+ appName: string;
186
+ /** Always a path. */
187
+ path: string;
188
+ /** The serving app's hostname, when its `path` names one. */
189
+ host?: string;
190
+ /** Whether the app serving it is the one `rebase dev` runs, so it has a local address. */
191
+ servedLocally: boolean;
192
+ };
193
+ }
194
+ /**
195
+ * Read {@link DevStaticShape} out of a loaded manifest. Exported for its test.
196
+ *
197
+ * Which declared app is running is decided by its `root` being `frontend/`,
198
+ * because that directory is what `startFrontend` launches and nothing else is.
199
+ * When no declared app has that root, which app serves the CMS cannot be told,
200
+ * and it is read as the frontend that does run — what the banner has always
201
+ * assumed, and right for every project `rebase init` scaffolds.
202
+ */
203
+ export declare function devStaticShape(manifest: RebaseProjectManifest, projectRoot: string, frontendDir: string | null): DevStaticShape;
204
+ /**
205
+ * The banner's lines for a project with a frontend. Exported for its test.
206
+ *
207
+ * Every address is printed whole, once: the local one Vite answers on, and —
208
+ * for an app with a hostname — the https URL it answers on once deployed, on a
209
+ * line of its own beneath it. A CMS in an app `rebase dev` does not run gets its
210
+ * deployed address and a note saying so, rather than a localhost URL that the
211
+ * running frontend's SPA fallback would answer with the wrong app.
212
+ */
213
+ export declare function appBannerLines(frontendUrl: string, api: string, shape: DevStaticShape): Array<[string, string]>;
141
214
  /**
142
215
  * The `↳ Database =` line: which database, why it was chosen, and where it is.
143
216
  *
@@ -206,7 +279,6 @@ export declare const DEV_FLAGS: {
206
279
  readonly "--backend-only": BooleanConstructor;
207
280
  readonly "--frontend-only": BooleanConstructor;
208
281
  readonly "--port": NumberConstructor;
209
- readonly "--generate": BooleanConstructor;
210
282
  /**
211
283
  * Point this run at a database of your own, ahead of everything else.
212
284
  *
@@ -220,7 +292,6 @@ export declare const DEV_FLAGS: {
220
292
  readonly "-b": "--backend-only";
221
293
  readonly "-f": "--frontend-only";
222
294
  readonly "-P": "--port";
223
- readonly "-g": "--generate";
224
295
  readonly "--no-db": BooleanConstructor;
225
296
  };
226
297
  /**
@@ -57,4 +57,9 @@ export declare const DOCTOR_FLAGS: {
57
57
  readonly "--sdk": StringConstructor;
58
58
  readonly "-k": "--sdk";
59
59
  };
60
+ /**
61
+ * The line handed to the driver, every path on it resolved from where the
62
+ * command was run — the driver runs in `backend/`. See `utils/path-flags.ts`.
63
+ */
64
+ export declare function doctorDriverArgs(rawArgs: string[], cwd: string): string[];
60
65
  export declare function doctorCommand(rawArgs: string[]): Promise<void>;
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * CLI command: generate-sdk
3
3
  *
4
- * Reads collection definitions from a specified directory (default: ./config/collections),
5
- * generates a typed TypeScript SDK, and writes it to the output directory (default: ./generated/sdk).
4
+ * Reads every collection file in a directory (default: ./config/collections) —
5
+ * the files the backend serves, not the barrel's list — generates a typed
6
+ * TypeScript SDK, and writes it to the output directory (default: ./generated/sdk).
6
7
  *
7
8
  * Uses jiti for dynamic TypeScript import of collection files.
8
9
  */
@@ -1,4 +1,5 @@
1
1
  import type { PackageManager, PMCommands } from "../utils/package-manager.js";
2
+ import { type AgentKey } from "./skills.js";
2
3
  /**
3
4
  * Every scaffolded file that carries a `{{PLACEHOLDER}}`.
4
5
  *
@@ -42,6 +43,10 @@ export interface InitOptions {
42
43
  setupKey?: string;
43
44
  /** Control-plane URL the setup key is redeemed against. */
44
45
  cloudUrl?: string;
46
+ /** AI coding agents to install skills and the MCP server for. */
47
+ agents: AgentKey[];
48
+ /** Whoever reads the closing steps can answer a prompt (a TTY, not --yes). */
49
+ interactive?: boolean;
45
50
  }
46
51
  export interface BuildQuestionsParams {
47
52
  nameArg?: string;
@@ -105,21 +110,59 @@ export declare function printInitHelp(): void;
105
110
  export declare function createRebaseApp(rawArgs: string[]): Promise<void>;
106
111
  /** The flags `rebase init` takes. */
107
112
  export declare const INIT_FLAGS: {
108
- readonly "--git": BooleanConstructor;
109
- readonly "--install": BooleanConstructor;
110
- readonly "--no-install": BooleanConstructor;
111
- readonly "--database-url": StringConstructor;
112
- readonly "--introspect": BooleanConstructor;
113
- readonly "--template": StringConstructor;
114
- readonly "--headless": BooleanConstructor;
115
- readonly "--project": StringConstructor;
116
- readonly "--setup-key": StringConstructor;
117
- readonly "--yes": BooleanConstructor;
118
- readonly "-g": "--git";
119
- readonly "-i": "--install";
120
- readonly "-t": "--template";
121
- readonly "-y": "--yes";
113
+ "--git": BooleanConstructor;
114
+ "--install": BooleanConstructor;
115
+ "--no-install": BooleanConstructor;
116
+ "--database-url": StringConstructor;
117
+ "--introspect": BooleanConstructor;
118
+ "--template": StringConstructor;
119
+ "--headless": BooleanConstructor;
120
+ "--project": StringConstructor;
121
+ "--setup-key": StringConstructor;
122
+ "--agent": [StringConstructor];
123
+ "--yes": BooleanConstructor;
124
+ "-a": string;
125
+ "-g": string;
126
+ "-i": string;
127
+ "-t": string;
128
+ "-y": string;
122
129
  };
130
+ /**
131
+ * The closing "AI Agent Skills" lines, each command one its reader can run.
132
+ *
133
+ * `rebase skills install` with no `--agent` prompts, and refuses without a
134
+ * TTY — so printing it bare at the end of `rebase init --yes`, the agent and
135
+ * CI path, told that reader to run a command that answers "Cannot prompt".
136
+ * Named agents are spelled out (a refresh must not depend on detection, which
137
+ * never finds Copilot); otherwise a TTY reader gets the prompt, anyone else
138
+ * the `--agent` form.
139
+ */
140
+ export declare function agentNextSteps(agents: readonly AgentKey[], interactive: boolean, pm: PMCommands): string[];
141
+ /**
142
+ * What a directory may already hold for `rebase init` to scaffold into it.
143
+ *
144
+ * `git clone` of an empty repository, or `git init`, leaves exactly `.git` —
145
+ * and `rebase init . --yes --git` is the help's own example. Counting every
146
+ * entry as "not empty" refused the one directory that example is most likely
147
+ * to be typed in. The entries here are a repository's metadata, the files
148
+ * operating systems drop into any folder, and a licence: none of them is
149
+ * something the scaffold writes (`init.test.ts` holds the template to that),
150
+ * so tolerating them can never overwrite anything. Everything else is a
151
+ * conflict and is named, never merged into.
152
+ */
153
+ export declare const SCAFFOLD_TOLERATED_ENTRIES: ReadonlySet<string>;
154
+ /** Entries in `dir` the scaffold would overwrite or mix with — `[]` when it may proceed. */
155
+ export declare function scaffoldDirectoryConflicts(dir: string): string[];
156
+ /** The refusal for a directory that already holds files, with the two ways forward. */
157
+ export declare function scaffoldConflictMessage(projectName: string, displayPath: string, conflicts: string[]): string[];
158
+ /**
159
+ * `git init`, or nothing when the directory is already a repository.
160
+ *
161
+ * A cloned repository keeps its branch, its remote and its history: the
162
+ * scaffold is committed on top of what is there. Only a repository this
163
+ * function created is pointed at `main`.
164
+ */
165
+ export declare function initGitRepository(targetDirectory: string): Promise<boolean>;
123
166
  /**
124
167
  * Whether `port` is free — on the wildcard address *and* on both loopback addresses.
125
168
  *
@@ -1 +1,9 @@
1
+ /**
2
+ * The line handed to the driver, its paths resolved from where the command was
3
+ * run (the driver runs in `backend/`). `--schema` is left alone: on
4
+ * `introspect` it names a Postgres schema, not a file.
5
+ */
6
+ export declare function schemaDriverArgs(rawArgs: string[], cwd: string): string[];
1
7
  export declare function schemaCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
8
+ /** Every subcommand the family dispatches — the help table's keys. */
9
+ export declare const SCHEMA_SUBCOMMANDS: string[];
@@ -18,14 +18,32 @@
18
18
  * A subdirectory layout has no such problem: the rule file already sits beside
19
19
  * its own assets, so `references/x.md` resolves as written and nothing is
20
20
  * loaded until it is opened.
21
+ *
22
+ * `homeMarkers` are the directories under `~` that say the assistant is
23
+ * installed on this machine. They answer a different question from
24
+ * `detectDir`: a fresh scaffold has no `.claude/` of its own, so `rebase init`
25
+ * asks the machine which assistants the developer has and pre-selects those.
26
+ *
27
+ * `mcp` is where the assistant reads a *project-level* MCP server list, and in
28
+ * which shape — see `agent-setup.ts`. `projectDir` is what `REBASE_PROJECT_DIR`
29
+ * is set to: `"."` where the server is spawned in the project, the editor's own
30
+ * workspace variable where it may not be. `null` means there is no project
31
+ * file to write: Windsurf reads only a user-level config, and one entry there
32
+ * cannot name every project on the machine.
21
33
  */
22
- declare const AGENTS: {
34
+ export declare const AGENTS: {
23
35
  readonly cursor: {
24
36
  readonly label: "Cursor";
25
37
  readonly detectDir: ".cursor";
38
+ readonly homeMarkers: readonly [".cursor"];
26
39
  readonly targetDir: ".cursor/rules";
27
40
  readonly flatLayout: true;
28
41
  readonly indexFile: "rebase.mdc";
42
+ readonly mcp: {
43
+ readonly file: ".cursor/mcp.json";
44
+ readonly format: "mcpServers";
45
+ readonly projectDir: "${workspaceFolder}";
46
+ };
29
47
  /** The body is not a rule file here — `indexFile` is. */
30
48
  readonly transformFile: (skillName: string, content: string) => {
31
49
  fileName: string;
@@ -35,8 +53,14 @@ declare const AGENTS: {
35
53
  readonly claude: {
36
54
  readonly label: "Claude Code";
37
55
  readonly detectDir: ".claude";
56
+ readonly homeMarkers: readonly [".claude"];
38
57
  readonly targetDir: ".claude/skills";
39
58
  readonly flatLayout: false;
59
+ readonly mcp: {
60
+ readonly file: ".mcp.json";
61
+ readonly format: "mcpServers";
62
+ readonly projectDir: ".";
63
+ };
40
64
  /** Claude Code uses the standard SKILL.md format in subdirectories. */
41
65
  readonly transformFile: (skillName: string, content: string) => {
42
66
  fileName: string;
@@ -46,9 +70,11 @@ declare const AGENTS: {
46
70
  readonly windsurf: {
47
71
  readonly label: "Windsurf";
48
72
  readonly detectDir: ".windsurf";
73
+ readonly homeMarkers: readonly [".codeium/windsurf", ".windsurf"];
49
74
  readonly targetDir: ".windsurf/rules";
50
75
  readonly flatLayout: true;
51
76
  readonly indexFile: "rebase.md";
77
+ readonly mcp: null;
52
78
  /** The body is not a rule file here — `indexFile` is. */
53
79
  readonly transformFile: (skillName: string, content: string) => {
54
80
  fileName: string;
@@ -58,8 +84,14 @@ declare const AGENTS: {
58
84
  readonly gemini: {
59
85
  readonly label: "Gemini CLI / Antigravity";
60
86
  readonly detectDir: ".agents";
87
+ readonly homeMarkers: readonly [".gemini"];
61
88
  readonly targetDir: ".agents/skills";
62
89
  readonly flatLayout: false;
90
+ readonly mcp: {
91
+ readonly file: ".gemini/settings.json";
92
+ readonly format: "mcpServers";
93
+ readonly projectDir: ".";
94
+ };
63
95
  /** Gemini uses the standard SKILL.md format in subdirectories. */
64
96
  readonly transformFile: (skillName: string, content: string) => {
65
97
  fileName: string;
@@ -69,9 +101,15 @@ declare const AGENTS: {
69
101
  readonly codex: {
70
102
  readonly label: "Codex CLI";
71
103
  readonly detectDir: ".codex";
72
- readonly targetDir: ".codex/skills";
104
+ readonly homeMarkers: readonly [".codex"];
105
+ readonly targetDir: ".agents/skills";
73
106
  readonly flatLayout: false;
74
- /** Codex reads AGENTS.md; the skills sit beside its own config. */
107
+ readonly mcp: {
108
+ readonly file: ".codex/config.toml";
109
+ readonly format: "codexToml";
110
+ readonly projectDir: ".";
111
+ };
112
+ /** Codex uses the standard SKILL.md format in subdirectories. */
75
113
  readonly transformFile: (skillName: string, content: string) => {
76
114
  fileName: string;
77
115
  content: string;
@@ -80,9 +118,15 @@ declare const AGENTS: {
80
118
  readonly kiro: {
81
119
  readonly label: "Kiro";
82
120
  readonly detectDir: ".kiro";
121
+ readonly homeMarkers: readonly [".kiro"];
83
122
  readonly targetDir: ".kiro/steering";
84
123
  readonly flatLayout: true;
85
124
  readonly indexFile: "rebase.md";
125
+ readonly mcp: {
126
+ readonly file: ".kiro/settings/mcp.json";
127
+ readonly format: "mcpServers";
128
+ readonly projectDir: ".";
129
+ };
86
130
  /** The body is not a rule file here — `indexFile` is. */
87
131
  readonly transformFile: (skillName: string, content: string) => {
88
132
  fileName: string;
@@ -92,9 +136,15 @@ declare const AGENTS: {
92
136
  readonly copilot: {
93
137
  readonly label: "GitHub Copilot";
94
138
  readonly detectDir: null;
139
+ readonly homeMarkers: readonly [];
95
140
  readonly targetDir: ".github/instructions";
96
141
  readonly flatLayout: true;
97
142
  readonly indexFile: "rebase.instructions.md";
143
+ readonly mcp: {
144
+ readonly file: ".vscode/mcp.json";
145
+ readonly format: "vscode";
146
+ readonly projectDir: "${workspaceFolder}";
147
+ };
98
148
  /** The body is not a rule file here — `indexFile` is. */
99
149
  readonly transformFile: (skillName: string, content: string) => {
100
150
  fileName: string;
@@ -102,7 +152,11 @@ declare const AGENTS: {
102
152
  };
103
153
  };
104
154
  };
105
- type AgentKey = keyof typeof AGENTS;
155
+ export type AgentKey = keyof typeof AGENTS;
156
+ /** Narrows a string to an agent name, by the table's own keys. */
157
+ export declare function isAgentKey(value: string): value is AgentKey;
158
+ /** Every agent, in table order. */
159
+ export declare const AGENT_KEYS: AgentKey[];
106
160
  export interface LoadedSkill {
107
161
  name: string;
108
162
  /** Absolute path of the skill's source directory. */
@@ -113,6 +167,13 @@ export interface LoadedSkill {
113
167
  }
114
168
  /** Read all skill directories and return their names, content and assets. */
115
169
  export declare function loadSkills(skillsDir: string): LoadedSkill[];
170
+ /**
171
+ * The skills this CLI ships, from its own `@rebasepro/agent-skills`.
172
+ *
173
+ * Throws rather than exiting, so `rebase init` can report a missing bundle as a
174
+ * warning and still finish the scaffold.
175
+ */
176
+ export declare function loadBundledSkills(): LoadedSkill[];
116
177
  /**
117
178
  * The one always-on rule a flat-layout agent gets, in place of every skill.
118
179
  *
@@ -136,11 +197,45 @@ export declare function renderSkillIndex(skills: LoadedSkill[], agentKey: AgentK
136
197
  * guessing, because the wrong guess installs 21 files and reports success.
137
198
  */
138
199
  export declare function detectAgents(projectDir: string): AgentKey[];
200
+ /** What `detectInstalledAgents` found for one assistant. */
201
+ export interface InstalledAgent {
202
+ key: AgentKey;
203
+ label: string;
204
+ /** The home directory checked, as `~/…` — the one found, else the first. */
205
+ marker: string | null;
206
+ found: boolean;
207
+ }
208
+ /**
209
+ * Which assistants are installed on this machine, from their home directories.
210
+ *
211
+ * The question `rebase init` needs answered, and one `detectAgents` cannot: a
212
+ * project that does not exist yet has no `.claude/` in it. What the machine has
213
+ * is only a default — the developer confirms it — so a false positive costs an
214
+ * unticked box, not 21 files nobody asked for.
215
+ */
216
+ export declare function detectInstalledAgents(home?: string): InstalledAgent[];
139
217
  /** Install skills for a specific agent into the project directory. */
140
218
  export declare function installForAgent(agentKey: AgentKey, skills: LoadedSkill[], projectDir: string): {
141
219
  skills: number;
142
220
  assets: number;
143
221
  };
222
+ /** What `installSkills` did for one agent. */
223
+ export interface SkillsInstallResult {
224
+ agent: AgentKey;
225
+ skills: number;
226
+ assets: number;
227
+ /** An earlier agent in the same run that already wrote this directory. */
228
+ sharedWith?: AgentKey;
229
+ }
230
+ /**
231
+ * Install for several agents, writing each target directory once.
232
+ *
233
+ * Gemini and Codex both read `.agents/skills`; installing twice would write the
234
+ * same 21 files twice and report two installs of one directory.
235
+ */
236
+ export declare function installSkills(agents: readonly AgentKey[], skills: LoadedSkill[], projectDir: string): SkillsInstallResult[];
237
+ /** Everything the switch below dispatches, for the did-you-mean. */
238
+ export declare const SKILLS_SUBCOMMANDS: readonly ["install"];
144
239
  export declare function skillsCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
145
240
  /**
146
241
  * Agents named explicitly on the command line, e.g. `--agent claude --agent cursor`
@@ -148,4 +243,15 @@ export declare function skillsCommand(subcommand: string | undefined, rawArgs: s
148
243
  * given.
149
244
  */
150
245
  export declare function parseAgentFlags(rawArgs: string[]): AgentKey[] | null;
151
- export {};
246
+ /** `rebase skills install`'s whole line: the agents it names, and `--mcp`. */
247
+ export declare function parseSkillsInstallLine(rawArgs: string[]): {
248
+ agents: AgentKey[] | null;
249
+ mcp: boolean;
250
+ };
251
+ /**
252
+ * The agents a list of `--agent` values names, or null when it names none.
253
+ *
254
+ * Shared by `rebase skills install` and `rebase init`, so both accept the same
255
+ * spellings. Throws a UsageError on a name that is not an agent.
256
+ */
257
+ export declare function resolveAgentNames(values: readonly string[]): AgentKey[] | null;
@@ -1 +1,30 @@
1
+ import type { RebaseBundleStatic } from "@rebasepro/types";
2
+ /** The NODE_ENV the runtime will see, and where it comes from. */
3
+ export interface StartNodeEnv {
4
+ value: string | undefined;
5
+ source: "shell" | ".env" | "unset";
6
+ }
7
+ /**
8
+ * What NODE_ENV the server will boot in. The shell wins — dotenv never
9
+ * overrides a variable that is already set — then `.env`.
10
+ */
11
+ export declare function startNodeEnv(projectRoot: string): StartNodeEnv;
12
+ /**
13
+ * The banner for a `rebase start` that is not a production server, or `null`.
14
+ *
15
+ * Not forced to production: the scaffold's `.env` points at a loopback
16
+ * database, which a production boot refuses, so forcing it would break the
17
+ * documented local run. What must not happen is the silence — a command the
18
+ * help called "(production)" booting with the first-registration window open.
19
+ */
20
+ export declare function nonProductionWarning(nodeEnv: StartNodeEnv): string[] | null;
21
+ /**
22
+ * What to say about the apps a bundle serves only on their own hostname.
23
+ *
24
+ * The runtime prints "Server running at http://localhost:<port>", and an app
25
+ * whose `path` names a hostname answers only requests carrying that `Host` —
26
+ * so opening the printed URL showed a 404 for an app that was running fine,
27
+ * and nothing said why. One line per such app, with a command that reaches it.
28
+ */
29
+ export declare function hostRoutedNotice(staticApps: readonly RebaseBundleStatic[], port: string | undefined): string[];
1
30
  export declare function startCommand(rawArgs?: string[]): Promise<void>;
@@ -1 +1,11 @@
1
+ /**
2
+ * `rebase telemetry` — the command that makes the rest of it inspectable.
3
+ *
4
+ * The whole subsystem asks for trust it cannot otherwise earn, and the cheapest
5
+ * way to earn it is to stop describing the payload and print it. `show` runs
6
+ * the same builder the sender uses, so what appears here is what would go, not
7
+ * a documentation comment that quietly fell out of date two releases ago.
8
+ */
9
+ /** Everything the switch below dispatches, for the did-you-mean. */
10
+ export declare const TELEMETRY_SUBCOMMANDS: readonly ["status", "show", "enable", "disable"];
1
11
  export declare function telemetryCommand(rawArgs: string[]): Promise<void>;