@oalo-ai/cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/help.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * same reason typegen reads the manifest instead of hardcoding a schema.
5
5
  */
6
6
 
7
- export const TAGLINE = "wire a local app into your OALO workspace";
7
+ export const TAGLINE = "wire a local app into your Oalo workspace";
8
8
 
9
9
  export const TOKENS = [
10
10
  {
@@ -74,12 +74,12 @@ export const COMMANDS = [
74
74
  { flag: "--app <slug>", desc: "The app that deploy, env, logs, secrets and dockerfile use when you don't pass --app (`oalo apps` lists them). `oalo deploy --new` sets it." },
75
75
  { flag: "--env dev|prod", desc: "Which schema later commands touch. Default dev." },
76
76
  { flag: "--status", desc: "Show the current link and re-check reachability." },
77
- { flag: "--no-skill", desc: "Don't install or refresh the OALO skill for coding agents (see `oalo skill`)." },
77
+ { flag: "--no-skill", desc: "Don't install or refresh the Oalo skill for coding agents (see `oalo skill`)." },
78
78
  ],
79
79
  notes: [
80
80
  "Every token is verified against the thing it is for BEFORE anything is saved, so a bad or mixed-up token fails here rather than later.",
81
81
  "Writes .oalo/config.json (safe to commit) and ~/.oalo/credentials.json (mode 0600, never in the project). OALO_HOME relocates the credential store.",
82
- "Also installs the OALO skill for coding agents (.claude/skills/oalo/SKILL.md), or refreshes it, from this CLI version; an AGENTS.md section from `oalo skill --agents` is refreshed too.",
82
+ "Also installs the Oalo skill for coding agents (.claude/skills/oalo/SKILL.md), or refreshes it, from this CLI version; an AGENTS.md section from `oalo skill --agents` is refreshed too.",
83
83
  ],
84
84
  exits: { 0: "linked", 1: "verification failed", 2: "missing or invalid arguments" },
85
85
  },
@@ -245,18 +245,35 @@ export const COMMANDS = [
245
245
  },
246
246
  {
247
247
  name: "db",
248
- summary: "All of an env's data as plain SQL (every app's own tables and the Oalo models), to keep a copy or take it anywhere.",
249
- usage: ["oalo db dump [--env dev|prod] [--out <file.sql>] [--force]"],
248
+ summary: "All of an env's data as plain SQL (every app's own tables and the Oalo models), to keep a copy or take it anywhere. Or load an existing Postgres database into an env.",
249
+ usage: [
250
+ "oalo db dump [--env dev|prod] [--out <file.sql>] [--force]",
251
+ "oalo db restore <file> --env dev|prod [--schema <name>] [--check] [--yes]",
252
+ "oalo db restore --from-env <VAR> --env dev|prod [--schema <name>] [--check] [--yes]",
253
+ ],
250
254
  flags: [
251
- { flag: "--env dev|prod", desc: "Which env's data. Default prod." },
255
+ { flag: "--env dev|prod", desc: "dump: which env's data. Default prod. restore: which env the data goes into, always on the command line." },
252
256
  { flag: "--out <file.sql>", desc: "Where to write it. Default <workspace>-<env>-<date>.sql here." },
253
257
  { flag: "--force", desc: "Replace the file if it exists." },
258
+ { flag: "--from-env <VAR>", desc: "restore: copy from a running database instead of a file. VAR is the environment variable that holds its postgres:// or postgresql:// URL. Only its host is ever shown." },
259
+ { flag: "--schema <name>", desc: "restore: the source schema to load. Default public, or the only one when there's just one." },
260
+ { flag: "--check", desc: "restore: do everything but the write, and report what would happen. Nothing is written, so it never asks." },
261
+ { flag: "--yes", desc: "restore: go ahead with prod without asking. Needed for prod when there's no terminal to ask at." },
254
262
  ],
255
263
  notes: [
256
264
  "Workspace admins only: it holds every member's data. Restore it into any Postgres with psql -f.",
257
265
  "Your code is in git (oalo deploy --pull); this is the data. Together they are everything you need to run your apps elsewhere.",
266
+ "restore loads a dump file made by pg_dump (like Heroku's latest.dump), up to 10 GB, or copies from a database URL. Admins only, and one restore at a time per Base.",
267
+ "The tables land in the env's schema, owned by the app's database login, so its Procfile `release:` migrations can alter them. Your app reads them at DATABASE_URL.",
268
+ "It's refused if a table name already exists there, and the names are listed. A failed restore leaves the env as it was.",
269
+ "The URL is never a flag value, since that stays in your shell history. Put it in a variable and pass --from-env VAR.",
270
+ "Run it with --check first. prod asks before it writes; without a terminal it needs --yes. Stop writes to the old database before the copy: writes made after it starts are lost.",
258
271
  ],
259
- exits: { 0: "a whole dump was written", 1: "refused, unreachable, or cut off (the partial file is removed)", 2: "bad arguments, the file exists, or no CLI token" },
272
+ exits: {
273
+ 0: "a whole dump was written, or the restore (or check) passed",
274
+ 1: "refused, unreachable, cut off (a partial dump is removed), or the restore failed or was declined",
275
+ 2: "bad arguments, the file exists or is missing, or no CLI token",
276
+ },
260
277
  },
261
278
  {
262
279
  name: "metrics",
@@ -500,7 +517,7 @@ export const COMMANDS = [
500
517
  },
501
518
  {
502
519
  name: "docs",
503
- summary: "Read the OALO platform docs from your workspace: list, search, or print a page as markdown.",
520
+ summary: "Read the Oalo platform docs from your workspace: list, search, or print a page as markdown.",
504
521
  usage: ["oalo docs [--audience developer|trainer] [--json]", "oalo docs <slug> [--json]", "oalo docs --search \"<words>\" [--json]"],
505
522
  flags: [
506
523
  { flag: "--search <words>", desc: "Pages ranked for the words, each with the line that matched." },
@@ -509,7 +526,7 @@ export const COMMANDS = [
509
526
  ],
510
527
  notes: [
511
528
  "Served by your workspace's own server (its Base), so the pages match the version it runs.",
512
- "Good starting pages for building on OALO: bring-your-repo and connect-your-own-frontend for your own code, app-environment, tokens-and-credentials, data-models, sync-rest-api, triggers-and-chaining.",
529
+ "Good starting pages for building on Oalo: bring-your-repo and connect-your-own-frontend for your own code, app-environment, tokens-and-credentials, data-models, sync-rest-api, triggers-and-chaining.",
513
530
  "A page goes to stdout as markdown, so `oalo docs data-models > notes.md` saves it. Related pages are listed on stderr.",
514
531
  ],
515
532
  exits: { 0: "done", 1: "no such page, or the workspace failed", 2: "no CLI token" },
@@ -542,7 +559,7 @@ export const COMMANDS = [
542
559
  { flag: "--from <https url>", desc: "With --new: make the app from a Git repository at this address instead of this folder (no local checkout needed). The Base clones one branch with its whole history (https to a public host only, up to 200 MB, 5 minutes), then makes the app as --new does. The name defaults to the repository's. Nothing is linked here." },
543
560
  { flag: "--branch <name>", desc: "With --from: the branch to import. Default: the repository's default branch." },
544
561
  { flag: "--token-env <VAR>", desc: "With --from: for a private repository, the environment variable holding an access token that can read it (a GitHub, GitLab, Bitbucket or Forgejo personal access token). Without it, at a terminal, you're asked for the token, hidden, when the host wants one. It is used for that one clone: never stored, logged or kept in the app's repo." },
545
- { flag: "--pull", desc: "Fetch the app's code as OALO has it into oalo/<slug>, to merge changes made there (by the builder agent or a teammate)." },
562
+ { flag: "--pull", desc: "Fetch the app's code as Oalo has it into oalo/<slug>, to merge changes made there (by the builder agent or a teammate)." },
546
563
  { flag: "--replace", desc: "Make this branch the app's code even though the histories differ. The app's current code is tagged first so it can be recovered." },
547
564
  { flag: "--allow-dirty", desc: "Deploy the last commit even though there are uncommitted changes (which are not sent)." },
548
565
  { flag: "--history", desc: "The live releases the app has had, newest first." },
@@ -560,9 +577,32 @@ export const COMMANDS = [
560
577
  ],
561
578
  exits: { 0: "deployed", 1: "refused or failed", 2: "bad arguments, no CLI token, or not in a git repo" },
562
579
  },
580
+ {
581
+ name: "migrate",
582
+ summary: "Move an app from Heroku, Railway, Render, Fly.io or Primcloud: its Procfile, sizes, health path and variables, worked out from its files and that platform's CLI.",
583
+ usage: [
584
+ "oalo migrate <heroku|railway|render|fly|primcloud> [--from-app <name>] [--env-file <file>] [--json]",
585
+ "oalo migrate <platform> --apply [--app <slug>]",
586
+ ],
587
+ flags: [
588
+ { flag: "--from-app <name>", desc: "The app or service on the old platform (a Heroku or Fly app, a Railway or Render service). Default: what that platform's CLI is linked to here, or fly.toml's app." },
589
+ { flag: "--env-file <file>", desc: "More variables, from a .env file (NAME=value lines). They win over what the platform's CLI reported. For Primcloud, and for Fly secrets, which can't be read back." },
590
+ { flag: "--apply", desc: "Write the Procfile and .oalo/app.json (never over an existing Procfile; app.json only gains keys it lacks), and set the variables on the app's prod env. Without it, nothing changes." },
591
+ { flag: "--no-cli", desc: "Don't run the old platform's CLI; read only the files here and --env-file." },
592
+ { flag: "--app <slug>", desc: "The Oalo app the variables go to. Default: the app this folder is linked to (oalo deploy --new links it)." },
593
+ { flag: "--json", desc: "The plan as JSON: names only, never a value." },
594
+ ],
595
+ notes: [
596
+ "Run it in the app's repo. It reads fly.toml, railway.json or railway.toml, render.yaml, app.json and the Procfile, and asks the platform's CLI for variables (heroku, railway), secret names (fly) and dyno sizes (heroku) when it's installed and signed in.",
597
+ "Variables: PORT and each platform's own (HEROKU_*, RAILWAY_*, RENDER_*, FLY_*) are left out, and DATABASE_URL becomes EXTERNAL_DATABASE_URL, since DATABASE_URL on Oalo is the Base's own Postgres. Values are never printed or written to a file; --apply sends them to prod without restarting the app.",
598
+ "It says what doesn't carry over: cron jobs, volumes and disks, private addresses (*.railway.internal, *.flycast), extra replicas, build commands, an Aptfile, a VM bigger than large.",
599
+ "The order: oalo migrate <platform> (read the plan), --apply, commit, oalo deploy --new, oalo migrate <platform> --apply again (now the app exists, it sets the variables), then the data (oalo db restore) and oalo deploy --env prod. `oalo docs migrating-from-<platform>` walks through it.",
600
+ ],
601
+ exits: { 0: "the plan was shown, or applied", 1: "a config file couldn't be read, or the variables couldn't be set", 2: "bad arguments, an unknown platform, or no CLI token" },
602
+ },
563
603
  {
564
604
  name: "env",
565
- summary: "An app's environment variables on OALO (API keys, settings), per env: list, set, unset, rotate-token.",
605
+ summary: "An app's environment variables on Oalo (API keys, settings), per env: list, set, unset, rotate-token.",
566
606
  usage: [
567
607
  "oalo env [--app <slug>] [--env dev|prod] [--json]",
568
608
  "oalo env set NAME=value [NAME=value ...] [--secret | --public] [--no-restart]",
@@ -583,7 +623,7 @@ export const COMMANDS = [
583
623
  "A variable is secret unless its name starts with VITE_, EXPO_PUBLIC_, NEXT_PUBLIC_, PUBLIC_ or REACT_APP_, or it's set with --public.",
584
624
  "Server apps get every variable, in the preview and live. Static apps (React, Expo, Flutter) only get public ones, because whatever their build sees ends up in the browser.",
585
625
  "Names Oalo sets itself can't be set: any starting with OALO_, PORT, DATABASE_URL, APP_SCHEMA, APP_SLUG, CONTAINER_HOST (and their VITE_/EXPO_PUBLIC_ forms), and the process basics (PATH, HOME, LANG, TZ, the Mix, Hex and Flutter homes). `oalo env set` refuses one by name.",
586
- "A server app gets OALO_URL and OALO_SYNC_TOKEN: a Sync API token for its own env's data that can also send events, call workflows and start chat sessions, so it needs no token of its own. It also signs OALO's calls to the app's endpoints (.oalo/app.json tools). The preview's token can't touch live data, and its events and workflow calls are test runs. `rotate-token` replaces it at once and restarts the app on the new one.",
626
+ "A server app gets OALO_URL and OALO_SYNC_TOKEN: a Sync API token for its own env's data that can also send events, call workflows and start chat sessions, so it needs no token of its own. It also signs Oalo's calls to the app's endpoints (.oalo/app.json tools). The preview's token can't touch live data, and its events and workflow calls are test runs. `rotate-token` replaces it at once and restarts the app on the new one.",
587
627
  "A dev change restarts the preview. A prod change relaunches the live app at the commit it already runs (a build; no new code goes out). --no-restart skips that, to batch several changes: the last one without it relaunches.",
588
628
  "Admins and members with Developer access only.",
589
629
  ],
@@ -611,12 +651,12 @@ export const COMMANDS = [
611
651
  usage: ["oalo dockerfile [--app <slug>] [--json]", "oalo dockerfile --write [--force] [--app <slug>]"],
612
652
  flags: [
613
653
  { flag: "--app <slug>", desc: "The app (`oalo apps` lists them). Default: the app saved with `oalo link --app`." },
614
- { flag: "--write", desc: "Save OALO's Dockerfile as ./Dockerfile, to change. Once committed, the repo's copy is used." },
654
+ { flag: "--write", desc: "Save Oalo's Dockerfile as ./Dockerfile, to change. Once committed, the repo's copy is used." },
615
655
  { flag: "--force", desc: "With --write, replace an existing ./Dockerfile." },
616
656
  { flag: "--json", desc: "method, source (repo or oalo), runtime and the Dockerfile's text." },
617
657
  ],
618
658
  notes: [
619
- "The first that fits: the repo's own Dockerfile; OALO's for the runtime, for the languages buildpacks can't build; buildpacks for the rest. `oalo docs live-server-apps` lists which language gets which.",
659
+ "The first that fits: the repo's own Dockerfile; Oalo's for the runtime, for the languages buildpacks can't build; buildpacks for the rest. `oalo docs live-server-apps` lists which language gets which.",
620
660
  "Every image runs as uid 1000 with a read-only filesystem (/tmp is writable) and must serve $PORT. A Procfile's lines still name the processes: web runs the image's own command when the Procfile has no web line.",
621
661
  ],
622
662
  exits: { 0: "done", 1: "refused or failed", 2: "bad arguments or no CLI token" },
@@ -628,14 +668,14 @@ export const COMMANDS = [
628
668
  flags: [
629
669
  { flag: "--app <slug>", desc: "The app (`oalo apps` lists them). Default: the app saved with `oalo link --app`." },
630
670
  { flag: "--env dev|prod", desc: "dev is the preview, prod the live app. Default dev." },
631
- { flag: "--process <name>", desc: "Only this process: web, a Procfile worker's name, release, build (a live build's output, with --env prod), or oalo (OALO's own notes)." },
671
+ { flag: "--process <name>", desc: "Only this process: web, a Procfile worker's name, release, build (a live build's output, with --env prod), or oalo (Oalo's own notes)." },
632
672
  { flag: "--limit N", desc: "How many recent lines (default 200, at most 2000)." },
633
673
  { flag: "--follow", desc: "Keep printing new lines as they come, until Ctrl-C." },
634
674
  { flag: "--json", desc: "One JSON object per line: at, process, line." },
635
675
  ],
636
676
  notes: [
637
677
  "The workspace keeps the last 2,000 lines per env in memory; restarting the workspace empties them.",
638
- "Lines from `oalo` are OALO's own: which command started, and when a process exited and with what status.",
678
+ "Lines from `oalo` are Oalo's own: which command started, and when a process exited and with what status.",
639
679
  "Admins and members with Developer access only: an app can print secrets or customers' details.",
640
680
  ],
641
681
  exits: { 0: "done", 1: "refused or failed", 2: "bad arguments or no CLI token" },
@@ -790,7 +830,7 @@ export const COMMANDS = [
790
830
  },
791
831
  {
792
832
  name: "skill",
793
- summary: "Teach this project's coding agent how to work on OALO.",
833
+ summary: "Teach this project's coding agent how to work on Oalo.",
794
834
  usage: ["oalo skill [--agents]", "oalo skill --print"],
795
835
  flags: [
796
836
  { flag: "--agents", desc: "Also write the rules into AGENTS.md (between oalo markers), for agents other than Claude Code." },
package/src/index.js CHANGED
@@ -32,6 +32,7 @@ import { channels } from "./commands/channels.js";
32
32
  import { products } from "./commands/products.js";
33
33
  import { metrics, dashboards } from "./commands/metrics.js";
34
34
  import { db } from "./commands/db.js";
35
+ import { migrate } from "./commands/migrate.js";
35
36
  import { overview, commandHelp, helpJson, COMMANDS } from "./help.js";
36
37
  import { parse } from "./args.js";
37
38
 
@@ -169,6 +170,9 @@ async function dispatch(cmd) {
169
170
  case "db":
170
171
  await db(flags, rest);
171
172
  break;
173
+ case "migrate":
174
+ await migrate(flags, rest);
175
+ break;
172
176
  case "secrets":
173
177
  await secrets(flags, rest);
174
178
  break;