openship 0.4.7 → 0.5.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 (42) hide show
  1. package/README.md +1 -0
  2. package/dist/{bare-2HYDXQEH.js → bare-VRGE5MXH.js} +7 -7
  3. package/dist/{chunk-TGIINPVM.js → chunk-6LKHXB6T.js} +22 -7
  4. package/dist/{chunk-R5BHFFAV.js → chunk-6PIYRG5I.js} +56 -17
  5. package/dist/{chunk-IMBD5PZ5.js → chunk-BS2AXYZX.js} +430 -86
  6. package/dist/{chunk-SJIFLLX4.js → chunk-CUJXGK7R.js} +321 -85
  7. package/dist/{chunk-VFINNTUL.js → chunk-EAAGSQXN.js} +23 -8
  8. package/dist/{chunk-4Z5QO7N6.js → chunk-I6PSTQIR.js} +2 -2
  9. package/dist/{chunk-XFCDYZUQ.js → chunk-JLKKYUZA.js} +31 -49
  10. package/dist/{chunk-4TJC4JZQ.js → chunk-K2RPVGPN.js} +23 -4
  11. package/dist/{chunk-MZ2WEHHY.js → chunk-KNTJ7PSF.js} +1 -1
  12. package/dist/{chunk-L2VOGB2X.js → chunk-KZOBYJUW.js} +1 -1
  13. package/dist/{chunk-IPYPMI3S.js → chunk-NNPEG6HM.js} +1 -1
  14. package/dist/{chunk-UXWAVM4C.js → chunk-NXFIRK2Z.js} +398 -112
  15. package/dist/{chunk-FXTBHTWY.js → chunk-RB35YN3J.js} +271 -35
  16. package/dist/{chunk-6APULWSU.js → chunk-UMQP7SYT.js} +429 -66
  17. package/dist/{chunk-V6AN6XLZ.js → chunk-V7BZMGOT.js} +123 -45
  18. package/dist/{chunk-VDMQJHPI.js → chunk-YWMODKWL.js} +67 -4
  19. package/dist/{chunk-OXWDY22G.js → chunk-ZCOQJCZO.js} +1 -1
  20. package/dist/{cloud-2KXREXMO.js → cloud-3M2WZ624.js} +12 -12
  21. package/dist/{detect-2XSCFFTF.js → detect-BAJMY6KM.js} +7 -5
  22. package/dist/{docker-LODK5Y2S.js → docker-2NGBRJFJ.js} +9 -7
  23. package/dist/{docker-edge-executor-VHW3JPJS.js → docker-edge-executor-5I4M5QT7.js} +1 -1
  24. package/dist/{edge-import-ZQ4Y5HEA.js → edge-import-RIWNEIXQ.js} +21 -19
  25. package/dist/{ensure-container-edge-ED25XL3Z.js → ensure-container-edge-3NSYKHRX.js} +6 -6
  26. package/dist/{executor-YPT6RH6O.js → executor-LOYMPU67.js} +3 -3
  27. package/dist/index.js +309 -338
  28. package/dist/{nginx-XWJAOGS4.js → nginx-QE4DOM5J.js} +4 -4
  29. package/dist/{openresty-lua-4WLGDSER.js → openresty-lua-BTAKECCF.js} +2 -2
  30. package/dist/server/index.js +51705 -45369
  31. package/dist/server/migrations/0073_project_volumes_object_storage.sql +3 -0
  32. package/dist/server/migrations/0074_project_compose_path.sql +1 -0
  33. package/dist/server/migrations/0075_service_command_argv.sql +1 -0
  34. package/dist/server/migrations/0076_rollback_retention.sql +17 -0
  35. package/dist/server/migrations/0077_domain_redirect.sql +13 -0
  36. package/dist/server/migrations/0078_grant_source_scope.sql +30 -0
  37. package/dist/server/migrations/0079_project_readiness.sql +18 -0
  38. package/dist/server/migrations/0080_deployment_error_classification.sql +26 -0
  39. package/dist/server/migrations/0081_project_readiness_repair.sql +34 -0
  40. package/dist/server/migrations/meta/_journal.json +63 -0
  41. package/dist/{setup-2DMFIA74.js → setup-KELALK7H.js} +7 -7
  42. package/package.json +1 -1
@@ -0,0 +1,3 @@
1
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "volumes" jsonb;
2
+ --> statement-breakpoint
3
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "object_storage" jsonb;
@@ -0,0 +1 @@
1
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "compose_path" text;
@@ -0,0 +1 @@
1
+ ALTER TABLE "service" ADD COLUMN IF NOT EXISTS "command_argv" jsonb;
@@ -0,0 +1,17 @@
1
+ -- Rollback retention: auto-sized window inputs on the project, and the removal
2
+ -- of a per-service artifact flag that was never written or read.
3
+ --
4
+ -- `rollback_window` keeps its existing meaning with one addition: NULL now means
5
+ -- "auto" — resolve to `rollback_window_computed` (measured from the deploy host's
6
+ -- free disk and this project's average snapshot size), falling back to
7
+ -- instance_settings.default_rollback_window when nothing was measured yet. A
8
+ -- non-null `rollback_window` is still an explicit operator override.
9
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "snapshot_size_bytes" bigint;
10
+ --> statement-breakpoint
11
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "rollback_window_computed" integer;
12
+ --> statement-breakpoint
13
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "capacity_measured_at" timestamp;
14
+ --> statement-breakpoint
15
+ -- Dead since it was introduced: the deployment-level `artifact_retained_at` is
16
+ -- the only retention flag any code path writes or reads.
17
+ ALTER TABLE "service_deployment" DROP COLUMN IF EXISTS "artifact_retained_at";
@@ -0,0 +1,13 @@
1
+ -- Per-domain canonical redirect: this hostname answers with a redirect to another
2
+ -- of the project's hostnames instead of serving the app.
3
+ --
4
+ -- Lives on `domain` rather than in a routing blob because the domain table IS the
5
+ -- store for a project's public endpoints (deriveProjectRouteState builds
6
+ -- publicEndpoints FROM these rows), and a redirect is a property of one hostname.
7
+ --
8
+ -- `redirect_to` NULL = serve the app (every existing row, unchanged).
9
+ -- `redirect_status` NULL = 301. Kept nullable rather than DEFAULT 301 so "no
10
+ -- redirect" is one state, not a status attached to a row that doesn't redirect.
11
+ ALTER TABLE "domain" ADD COLUMN IF NOT EXISTS "redirect_to" text;
12
+ --> statement-breakpoint
13
+ ALTER TABLE "domain" ADD COLUMN IF NOT EXISTS "redirect_status" integer;
@@ -0,0 +1,30 @@
1
+ -- Per-repo source access scope on every grant-bearing table.
2
+ --
3
+ -- A grant already carries a VERB in `permissions_json` (read / write / admin).
4
+ -- This column adds the SURFACE: may the holder read file CONTENT, and under which
5
+ -- paths. The two do not overlap, and the absence of a scope is meaningful:
6
+ --
7
+ -- read + scope_json NULL -> metadata only (branches,
8
+ -- detect, deploy). THE DEFAULT.
9
+ -- read + {"v":1,"read":{"paths":["src/**"]}} -> file content under src only
10
+ -- write + {"v":1,"write":{"paths":[...]}} -> content writes under those paths
11
+ --
12
+ -- So a repo grant no longer implies the right to crawl the repository. NULL is the
13
+ -- restrictive state, which is why this is nullable with no default and no backfill:
14
+ -- every existing row correctly reads as metadata-only.
15
+ --
16
+ -- Encoded as JSON text (not jsonb, not text[]) to match `permissions_json` — the
17
+ -- column types have to behave identically across PGlite and Postgres without
18
+ -- driver-specific casting, and the repos already own (de)serialisation.
19
+ --
20
+ -- Shape + matching semantics: packages/core/src/source-access.ts. Malformed JSON,
21
+ -- an unknown "v", or an unparseable pattern all resolve to NO access rather than
22
+ -- unrestricted access.
23
+ ALTER TABLE "resource_grant" ADD COLUMN IF NOT EXISTS "scope_json" text;
24
+ --> statement-breakpoint
25
+ ALTER TABLE "personal_access_token_grant" ADD COLUMN IF NOT EXISTS "scope_json" text;
26
+ --> statement-breakpoint
27
+ -- Pending invite grants carry the scope through acceptance; without it, a
28
+ -- restricted invitee would materialise into a metadata-only grant and silently
29
+ -- lose the content access the inviter picked.
30
+ ALTER TABLE "invitation_pending_grant" ADD COLUMN IF NOT EXISTS "scope_json" text;
@@ -0,0 +1,18 @@
1
+ -- Deploy-time readiness gate, per project.
2
+ --
3
+ -- Named `readiness`, NOT `health_check`, on purpose: a compose service already
4
+ -- carries a `healthcheck` (the Docker HEALTHCHECK directive, stored in
5
+ -- `service.advanced`) which the daemon runs and which has nothing to do with
6
+ -- whether a DEPLOY is allowed to finish. Two fields one capital letter apart in
7
+ -- the same openship.json would be a footgun.
8
+ --
9
+ -- Nullable with NO default, and no backfill: NULL means "off", so every existing
10
+ -- project moves to the new off-by-default behaviour. Previously the 15s
11
+ -- stabilization watch and the 45s TCP probe were hardcoded on every deploy and
12
+ -- could fail (and then force-remove) a container that was running fine. Opting
13
+ -- in is now explicit.
14
+ --
15
+ -- Shape (all fields optional, all defaults off) — see OpenshipReadiness:
16
+ -- { enabled, path, port, timeoutSeconds,
17
+ -- stabilization, stabilizationSeconds, onFailure: "warn" | "fail" }
18
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "readiness" jsonb;
@@ -0,0 +1,26 @@
1
+ -- Durable failure classification for a deployment.
2
+ --
3
+ -- The pipeline already classifies failures precisely: a port conflict throws
4
+ -- DeployError(msg, "PORT_IN_USE", {port, pid, command, systemdUnit,
5
+ -- isManagedDeployment, …}) and that reaches onFailure intact. It was then split,
6
+ -- and only half of it was kept: `error_message` went to this table while
7
+ -- `errorCode`/`errorDetails` went ONLY to the in-memory SSE session. Once that
8
+ -- session was evicted (or the API restarted) all that survived a port conflict
9
+ -- was an English sentence, so nothing could offer the operator — or an MCP agent
10
+ -- — a way forward.
11
+ --
12
+ -- The one attempt to recover the code was inverted: build-status re-derived it
13
+ -- with error_message.includes("PORT_IN_USE"), and none of the coded messages
14
+ -- contain that token (they read "Port 3000 is already in use by …"). So the
15
+ -- failures we DID classify lost their code and the ones we didn't got it guessed.
16
+ --
17
+ -- `error_code` is free text with no check constraint, matching `status` on this
18
+ -- table: codes come from DeployError call sites across packages/adapters and must
19
+ -- be extendable without a migration. `error_details` is the DeployError details
20
+ -- bag verbatim (never contains secrets — it is process/port metadata).
21
+ --
22
+ -- Both nullable with no backfill: NULL means "not classified", which is exactly
23
+ -- true of every pre-existing row.
24
+ ALTER TABLE "deployment" ADD COLUMN IF NOT EXISTS "error_code" text;
25
+ --> statement-breakpoint
26
+ ALTER TABLE "deployment" ADD COLUMN IF NOT EXISTS "error_details" jsonb;
@@ -0,0 +1,34 @@
1
+ -- Repair: create `project.readiness` on a database that skipped 0079.
2
+ --
3
+ -- WHY THIS EXISTS (and why it is not just "0079 again"):
4
+ --
5
+ -- 0079 was originally `0079_project_health_check` (adding `project.health_check`)
6
+ -- and was replaced in place by `0079_project_readiness` (adding
7
+ -- `project.readiness`) before either shipped. Both journal entries carry the SAME
8
+ -- `when` — 1785882107324 — because the second reused the first's slot.
9
+ --
10
+ -- drizzle's migrator reads only the single most recent applied row and applies a
11
+ -- migration when `lastDbMigration.created_at < migration.folderMillis`
12
+ -- (pg-core/dialect.js). That comparison is STRICT, so on any database that had
13
+ -- already run the old 0079, the new one is equal, not greater — it is skipped
14
+ -- without a word. 0080 carried a later stamp and applied normally, which is why
15
+ -- such a database ends up with 0080's columns, an orphan `health_check`, and no
16
+ -- `readiness` at all. Every query selecting the project row then dies with
17
+ -- `column "readiness" does not exist` (42703).
18
+ --
19
+ -- Bumping 0079's `when` would NOT fix it: the max applied stamp is now 0080's, so
20
+ -- anything ordered before 0080 still compares as already-applied. The repair has
21
+ -- to sort AFTER 0080, which is what this file is.
22
+ --
23
+ -- Idempotent on purpose. A fresh database creates the column at 0079 and this is
24
+ -- a no-op; a database that skipped 0079 creates it here. Either way the end state
25
+ -- is identical, so this is safe to leave in history permanently rather than being
26
+ -- a one-off someone has to remember to delete.
27
+ ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "readiness" jsonb;--> statement-breakpoint
28
+
29
+ -- Drop the column the replaced migration left behind. `health_check` was only
30
+ -- ever created by 0079_project_health_check, which never shipped in a release and
31
+ -- is referenced by no schema, query, or type in the codebase — so on the
32
+ -- databases that have it, it is dead weight with a confusingly similar name to
33
+ -- the compose service `healthcheck`. Guarded, so this is a no-op everywhere else.
34
+ ALTER TABLE "project" DROP COLUMN IF EXISTS "health_check";
@@ -512,6 +512,69 @@
512
512
  "when": 1785358400651,
513
513
  "tag": "0072_gh_device_token_method",
514
514
  "breakpoints": true
515
+ },
516
+ {
517
+ "idx": 73,
518
+ "version": "7",
519
+ "when": 1785358401651,
520
+ "tag": "0073_project_volumes_object_storage",
521
+ "breakpoints": true
522
+ },
523
+ {
524
+ "idx": 74,
525
+ "version": "7",
526
+ "when": 1785450107324,
527
+ "tag": "0074_project_compose_path",
528
+ "breakpoints": true
529
+ },
530
+ {
531
+ "idx": 75,
532
+ "version": "7",
533
+ "when": 1785536507324,
534
+ "tag": "0075_service_command_argv",
535
+ "breakpoints": true
536
+ },
537
+ {
538
+ "idx": 76,
539
+ "version": "7",
540
+ "when": 1785622907324,
541
+ "tag": "0076_rollback_retention",
542
+ "breakpoints": true
543
+ },
544
+ {
545
+ "idx": 77,
546
+ "version": "7",
547
+ "when": 1785709307324,
548
+ "tag": "0077_domain_redirect",
549
+ "breakpoints": true
550
+ },
551
+ {
552
+ "idx": 78,
553
+ "version": "7",
554
+ "when": 1785795707324,
555
+ "tag": "0078_grant_source_scope",
556
+ "breakpoints": true
557
+ },
558
+ {
559
+ "idx": 79,
560
+ "version": "7",
561
+ "when": 1785882107324,
562
+ "tag": "0079_project_readiness",
563
+ "breakpoints": true
564
+ },
565
+ {
566
+ "idx": 80,
567
+ "version": "7",
568
+ "when": 1785968507324,
569
+ "tag": "0080_deployment_error_classification",
570
+ "breakpoints": true
571
+ },
572
+ {
573
+ "idx": 81,
574
+ "version": "7",
575
+ "when": 1786054907324,
576
+ "tag": "0081_project_readiness_repair",
577
+ "breakpoints": true
515
578
  }
516
579
  ]
517
580
  }
@@ -4,16 +4,16 @@ import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  SystemManager
7
- } from "./chunk-IPYPMI3S.js";
8
- import "./chunk-UXWAVM4C.js";
9
- import "./chunk-L2VOGB2X.js";
7
+ } from "./chunk-NNPEG6HM.js";
8
+ import "./chunk-NXFIRK2Z.js";
9
+ import "./chunk-KZOBYJUW.js";
10
10
  import "./chunk-RPHRPFEH.js";
11
- import "./chunk-FXTBHTWY.js";
11
+ import "./chunk-RB35YN3J.js";
12
12
  import "./chunk-FPRHYBY2.js";
13
- import "./chunk-R5BHFFAV.js";
13
+ import "./chunk-6PIYRG5I.js";
14
14
  import "./chunk-ILFETZOM.js";
15
- import "./chunk-VFINNTUL.js";
16
- import "./chunk-6APULWSU.js";
15
+ import "./chunk-EAAGSQXN.js";
16
+ import "./chunk-UMQP7SYT.js";
17
17
  import "./chunk-KI2EY3WB.js";
18
18
  export {
19
19
  SystemManager
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openship",
3
- "version": "0.4.7",
3
+ "version": "0.5.0",
4
4
  "description": "Openship CLI - deploy, manage, and open your Openship platform from the terminal",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {