openship 0.5.0 → 0.6.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 (103) hide show
  1. package/README.md +26 -1
  2. package/dist/bare-FSUAM5V5.js +23 -0
  3. package/dist/{bowser-O3AEA6AN.js → bowser-HNOTPGJO.js} +2 -2
  4. package/dist/{chunk-5MZ624VX.js → chunk-2GWYYHOR.js} +1 -1
  5. package/dist/chunk-3FYIXVX5.js +8051 -0
  6. package/dist/{chunk-ILFETZOM.js → chunk-3LDWWY7U.js} +21 -1
  7. package/dist/{chunk-W73X43R7.js → chunk-3NQQXMDR.js} +3 -3
  8. package/dist/{chunk-OWED2GRM.js → chunk-42WQABXM.js} +2 -2
  9. package/dist/{chunk-TYVME3XD.js → chunk-6FH4AXVY.js} +20 -3
  10. package/dist/{chunk-ZCOQJCZO.js → chunk-6ODUBKUB.js} +3 -3
  11. package/dist/{chunk-DYPH4HCI.js → chunk-AO252K7Z.js} +1 -1
  12. package/dist/{chunk-K2RPVGPN.js → chunk-B3CE2OMR.js} +14 -12
  13. package/dist/{chunk-IXCHURVK.js → chunk-DOD2BXHQ.js} +4 -4
  14. package/dist/{chunk-VWPEKOH6.js → chunk-DRK3MEDS.js} +3 -3
  15. package/dist/{chunk-V7BZMGOT.js → chunk-EMXI4UCU.js} +5 -5
  16. package/dist/{chunk-NNPEG6HM.js → chunk-EP2TNALB.js} +2 -2
  17. package/dist/{chunk-NXFIRK2Z.js → chunk-GUQ3QCJ7.js} +573 -459
  18. package/dist/chunk-I3DPMTSF.js +29 -0
  19. package/dist/{chunk-KZOBYJUW.js → chunk-IW2UKBVF.js} +3 -3
  20. package/dist/{chunk-YWMODKWL.js → chunk-IXM5245F.js} +165 -13
  21. package/dist/{chunk-KNTJ7PSF.js → chunk-JIMUYEKN.js} +4 -4
  22. package/dist/chunk-OGY63DGD.js +705 -0
  23. package/dist/{chunk-O6ZZF52V.js → chunk-ONKEYSMY.js} +2 -2
  24. package/dist/{chunk-UMQP7SYT.js → chunk-OTLSJYAC.js} +1316 -53
  25. package/dist/{chunk-EI575GHN.js → chunk-PDW4L3NV.js} +3 -3
  26. package/dist/{chunk-JLKKYUZA.js → chunk-PSZSKEPA.js} +7 -7
  27. package/dist/{chunk-KI2EY3WB.js → chunk-PXKCZB2I.js} +1 -1
  28. package/dist/{chunk-RB35YN3J.js → chunk-QEH4QUBX.js} +391 -63
  29. package/dist/{chunk-6APIPIJY.js → chunk-QWHBRY2K.js} +5 -5
  30. package/dist/{chunk-6B5YCFFV.js → chunk-RVER2EOO.js} +5 -5
  31. package/dist/{chunk-Q2CIRAOK.js → chunk-RXQBD4ZY.js} +1 -1
  32. package/dist/{chunk-6LKHXB6T.js → chunk-TWJCLD4W.js} +48 -13
  33. package/dist/{chunk-I6PSTQIR.js → chunk-VDDMADOF.js} +3 -3
  34. package/dist/{chunk-BS2AXYZX.js → chunk-VE2YOK4I.js} +626 -214
  35. package/dist/{chunk-6PIYRG5I.js → chunk-VZ2ZHPS2.js} +52 -42
  36. package/dist/{chunk-AVIB7CT7.js → chunk-WNWQBB7F.js} +2 -2
  37. package/dist/{chunk-FRNAR33O.js → chunk-XZYFZ6A5.js} +3 -3
  38. package/dist/{chunk-RPHRPFEH.js → chunk-ZCFVHA25.js} +1 -1
  39. package/dist/{chunk-FPRHYBY2.js → chunk-ZFJXPCQP.js} +1 -1
  40. package/dist/{chunk-JYGD5WSN.js → chunk-ZWLDLTJP.js} +1 -1
  41. package/dist/cloud-E5M6VMCG.js +31 -0
  42. package/dist/{cloud-7QYOGF7F.js → cloud-KRTZ2IL5.js} +3 -3
  43. package/dist/{detect-BAJMY6KM.js → detect-ALF4GXRX.js} +7 -8
  44. package/dist/{dist-IQJ6H6UZ.js → dist-BM6NPWIH.js} +3 -3
  45. package/dist/{dist-es-X3B5QYKB.js → dist-es-2YRDXMUU.js} +6 -6
  46. package/dist/{dist-es-OSNJBLXB.js → dist-es-CCVZEFRZ.js} +5 -5
  47. package/dist/{dist-es-VNKHQVIB.js → dist-es-IOH6G4GM.js} +4 -4
  48. package/dist/{dist-es-RYHIPOTN.js → dist-es-JGBPABJI.js} +14 -14
  49. package/dist/{dist-es-JSTDUS7Q.js → dist-es-KWSMDPIP.js} +6 -6
  50. package/dist/{dist-es-5DY7K32L.js → dist-es-UYDDOVZ3.js} +6 -6
  51. package/dist/{dist-es-WV4AMOII.js → dist-es-XUOR4NQN.js} +8 -8
  52. package/dist/docker-QECQJ5P4.js +32 -0
  53. package/dist/docker-edge-executor-62N64MGS.js +17 -0
  54. package/dist/edge-import-CQWHN2Q3.js +48 -0
  55. package/dist/ensure-container-edge-MJVXJQG5.js +32 -0
  56. package/dist/{event-streams-EHRAKL75.js → event-streams-TR4GAC53.js} +4 -4
  57. package/dist/{executor-LOYMPU67.js → executor-JELARVKC.js} +8 -8
  58. package/dist/index.js +1170 -459
  59. package/dist/{loadSso-46FQRIZS.js → loadSso-UGF4JMRK.js} +10 -10
  60. package/dist/{local-executor-V7U5VOZW.js → local-executor-WOFZD72X.js} +4 -4
  61. package/dist/nginx-AXGNWRKZ.js +31 -0
  62. package/dist/node-entry.js +4 -0
  63. package/dist/{noop-FMMFG2EZ.js → noop-NJ72F46T.js} +3 -3
  64. package/dist/openresty-lua-IE4P5YQX.js +81 -0
  65. package/dist/server/index.js +23172 -7994
  66. package/dist/server/lua/geo_country.lua +31 -6
  67. package/dist/server/lua/maxminddb.lua +403 -0
  68. package/dist/server/lua/mgmt_api.lua +431 -68
  69. package/dist/server/lua/pipe_log.lua +10 -4
  70. package/dist/server/lua/site_logger.lua +220 -12
  71. package/dist/server/migrations/0082_edge_target_verification.sql +39 -0
  72. package/dist/server/migrations/0083_service_incident.sql +84 -0
  73. package/dist/server/migrations/0084_analytics_daily_rollup.sql +72 -0
  74. package/dist/server/migrations/0085_resource_usage.sql +68 -0
  75. package/dist/server/migrations/0086_remote_infra_updates.sql +41 -0
  76. package/dist/server/migrations/0087_server_container_version_columns.sql +17 -0
  77. package/dist/server/migrations/0088_audit_source_and_settings.sql +27 -0
  78. package/dist/server/migrations/0089_auto_scan_infra.sql +7 -0
  79. package/dist/server/migrations/0090_project_collect_paths.sql +18 -0
  80. package/dist/server/migrations/0091_project_server_id.sql +26 -0
  81. package/dist/server/migrations/0092_project_internal_alias.sql +13 -0
  82. package/dist/server/migrations/0093_service_incident_org_index.sql +13 -0
  83. package/dist/server/migrations/0094_backup_restore_meta.sql +15 -0
  84. package/dist/server/migrations/0095_backup_restore_cancel.sql +19 -0
  85. package/dist/server/migrations/0096_backup_policy_retention_defaults.sql +20 -0
  86. package/dist/server/migrations/0097_update_status_upstream_only.sql +35 -0
  87. package/dist/server/migrations/meta/_journal.json +112 -0
  88. package/dist/setup-FA4PW4NU.js +21 -0
  89. package/dist/{signin-ITOPKKUB.js → signin-3M3UPB6K.js} +10 -10
  90. package/dist/{sso-oidc-NON2PD7Y.js → sso-oidc-3VDIYOEJ.js} +10 -10
  91. package/dist/{sts-HHFFSAY2.js → sts-B3WIYLXR.js} +9 -9
  92. package/package.json +6 -3
  93. package/dist/bare-VRGE5MXH.js +0 -23
  94. package/dist/chunk-CUJXGK7R.js +0 -3167
  95. package/dist/chunk-EAAGSQXN.js +0 -377
  96. package/dist/cloud-3M2WZ624.js +0 -30
  97. package/dist/docker-2NGBRJFJ.js +0 -18
  98. package/dist/docker-edge-executor-5I4M5QT7.js +0 -13
  99. package/dist/edge-import-RIWNEIXQ.js +0 -47
  100. package/dist/ensure-container-edge-3NSYKHRX.js +0 -31
  101. package/dist/nginx-QE4DOM5J.js +0 -24
  102. package/dist/openresty-lua-BTAKECCF.js +0 -42
  103. package/dist/setup-KELALK7H.js +0 -20
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env sh
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
+ import { createRequire as __ospCreateRequire } from "node:module";
4
+ const require = __ospCreateRequire(import.meta.url);
5
+
6
+ // ../../packages/adapters/src/system/edge-exec-error.ts
7
+ var EDGE_DOWN_MARKER = "the edge container is not running";
8
+ function isEdgeDownFailure(text) {
9
+ return /is restarting, wait until the container is running/i.test(text) || /container .* is not running/i.test(text) || /\bis not running\b/i.test(text) || /No such container/i.test(text) || /container .* is paused/i.test(text) || /invalid PID number/i.test(text);
10
+ }
11
+ function explainEdgeDown(opts) {
12
+ const { container, status, reason } = opts;
13
+ const state = status?.trim() ? ` (${status.trim()})` : "";
14
+ const crashLooping = status?.trim() === "restarting";
15
+ const consequence = crashLooping ? `it is crash-looping, so nothing that runs through the edge on this server can work \u2014 certificate issuance, config reloads and route changes all go through it` : `nothing that runs through the edge on this server can work until it is up \u2014 certificate issuance, config reloads and route changes all go through it`;
16
+ const cause = reason?.trim() ? `OpenResty is refusing to start: ${reason.trim().replace(/\s+/g, " ")}. Fix that, then \`docker start ${container}\` and retry.` : `Run \`docker logs --tail 40 ${container}\` on the server for the reason, then retry.`;
17
+ return `${EDGE_DOWN_MARKER} ("${container}")${state} \u2014 ${consequence}. ${cause}`;
18
+ }
19
+ function edgeDownExplanation(text) {
20
+ if (!text) return null;
21
+ const line = text.split("\n").map((l) => l.trim()).find((l) => l.includes(EDGE_DOWN_MARKER));
22
+ return line || null;
23
+ }
24
+
25
+ export {
26
+ isEdgeDownFailure,
27
+ explainEdgeDown,
28
+ edgeDownExplanation
29
+ };
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  formatDuration,
7
7
  isRemoteConnectionError,
8
8
  systemDebug
9
- } from "./chunk-RPHRPFEH.js";
9
+ } from "./chunk-ZCFVHA25.js";
10
10
  import {
11
11
  safeErrorMessage
12
- } from "./chunk-UMQP7SYT.js";
12
+ } from "./chunk-OTLSJYAC.js";
13
13
 
14
14
  // ../../packages/adapters/src/system/environment.ts
15
15
  var profileCache = /* @__PURE__ */ new WeakMap();
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
@@ -7,10 +7,10 @@ import {
7
7
  resolveProjectDir,
8
8
  resolveStaticOutputPath,
9
9
  runLocalBuild
10
- } from "./chunk-KNTJ7PSF.js";
10
+ } from "./chunk-JIMUYEKN.js";
11
11
  import {
12
12
  resolveEnvironment
13
- } from "./chunk-KZOBYJUW.js";
13
+ } from "./chunk-IW2UKBVF.js";
14
14
  import {
15
15
  BuildCancelledError,
16
16
  BuildLogger,
@@ -19,23 +19,23 @@ import {
19
19
  runBuildPipeline,
20
20
  sq,
21
21
  transferLocalDirectory
22
- } from "./chunk-I6PSTQIR.js";
22
+ } from "./chunk-VDDMADOF.js";
23
23
  import {
24
24
  formatDuration,
25
25
  isRemoteConnectionError,
26
26
  isRetryableRemoteConnectionError,
27
27
  systemDebug
28
- } from "./chunk-RPHRPFEH.js";
28
+ } from "./chunk-ZCFVHA25.js";
29
29
  import {
30
30
  LocalExecutor
31
- } from "./chunk-TYVME3XD.js";
31
+ } from "./chunk-6FH4AXVY.js";
32
+ import {
33
+ probeListeningPort
34
+ } from "./chunk-3LDWWY7U.js";
32
35
  import {
33
36
  sq as sq2,
34
37
  wrapLocalBuildCommand
35
- } from "./chunk-FPRHYBY2.js";
36
- import {
37
- probeListeningPort
38
- } from "./chunk-ILFETZOM.js";
38
+ } from "./chunk-ZFJXPCQP.js";
39
39
  import {
40
40
  DeployError,
41
41
  LANGUAGES,
@@ -45,7 +45,7 @@ import {
45
45
  missingOutputDirectoryMessage,
46
46
  packageManagerEnsureCommand,
47
47
  safeErrorMessage
48
- } from "./chunk-UMQP7SYT.js";
48
+ } from "./chunk-OTLSJYAC.js";
49
49
 
50
50
  // ../../packages/adapters/src/system/remote-journal.ts
51
51
  var OPSH_RUN_VERSION = 1;
@@ -997,6 +997,101 @@ async function installTools(executor, toolNames, onLog, requiredVersions) {
997
997
  return results;
998
998
  }
999
999
 
1000
+ // ../../packages/adapters/src/runtime/supervisor/usage.ts
1001
+ var SAMPLE_MS = 250;
1002
+ var ZERO_USAGE = {
1003
+ cpuPercent: 0,
1004
+ memoryMb: 0,
1005
+ diskMb: 0,
1006
+ networkRxBytes: 0,
1007
+ networkTxBytes: 0
1008
+ };
1009
+ function buildProbe(pid, cgroupCandidates) {
1010
+ const p = sq(String(pid));
1011
+ const cgList = cgroupCandidates.map(sq).join(" ");
1012
+ return [
1013
+ `P=${p}`,
1014
+ // Locate a readable cgroup v2 dir for this unit, if any.
1015
+ `CG=""`,
1016
+ `for c in ${cgList}; do if [ -r "$c/cpu.stat" ]; then CG="$c"; break; fi; done`,
1017
+ // ── cgroup v2 ──
1018
+ `if [ -n "$CG" ]; then`,
1019
+ ` C1=$(awk '/^usage_usec/{print $2}' "$CG/cpu.stat" 2>/dev/null)`,
1020
+ ` sleep ${(SAMPLE_MS / 1e3).toFixed(3)}`,
1021
+ ` C2=$(awk '/^usage_usec/{print $2}' "$CG/cpu.stat" 2>/dev/null)`,
1022
+ ` M=$(cat "$CG/memory.current" 2>/dev/null)`,
1023
+ // io.stat is "<maj:min> rbytes=N wbytes=N rios=N wios=N" per device — summed
1024
+ // across devices. Read and write are kept apart so the parser adds each once.
1025
+ ` R=$(awk '{for(i=1;i<=NF;i++){split($i,kv,"=");if(kv[1]=="rbytes")r+=kv[2]}}END{print r+0}' "$CG/io.stat" 2>/dev/null)`,
1026
+ ` W=$(awk '{for(i=1;i<=NF;i++){split($i,kv,"=");if(kv[1]=="wbytes")w+=kv[2]}}END{print w+0}' "$CG/io.stat" 2>/dev/null)`,
1027
+ ` echo "cgroup \${C1:-0} \${C2:-0} \${M:-0} \${R:-0} \${W:-0}"`,
1028
+ // ── /proc/<pid> ──
1029
+ `elif [ -r "/proc/$P/stat" ]; then`,
1030
+ // utime (14) + stime (15) in clock ticks. comm can contain spaces, so cut
1031
+ // everything up to the closing paren before counting fields.
1032
+ ` T=$(getconf CLK_TCK 2>/dev/null || echo 100)`,
1033
+ ` C1=$(sed 's/.*) //' "/proc/$P/stat" 2>/dev/null | awk -v t="$T" '{print int((($12+$13)/t)*1000000)}')`,
1034
+ ` sleep ${(SAMPLE_MS / 1e3).toFixed(3)}`,
1035
+ ` C2=$(sed 's/.*) //' "/proc/$P/stat" 2>/dev/null | awk -v t="$T" '{print int((($12+$13)/t)*1000000)}')`,
1036
+ ` M=$(awk '/^VmRSS:/{print $2*1024}' "/proc/$P/status" 2>/dev/null)`,
1037
+ ` R=$(awk '/^read_bytes:/{print $2}' "/proc/$P/io" 2>/dev/null)`,
1038
+ ` W=$(awk '/^write_bytes:/{print $2}' "/proc/$P/io" 2>/dev/null)`,
1039
+ ` echo "proc \${C1:-0} \${C2:-0} \${M:-0} \${R:-0} \${W:-0}"`,
1040
+ // ── ps (macOS / no procfs) ──
1041
+ `else`,
1042
+ // ps %cpu is a LIFETIME average, not a rate — reported as-is and flagged by the
1043
+ // `ps` source so the parser doesn't pretend it's an instantaneous sample.
1044
+ ` X=$(ps -o rss=,%cpu= -p "$P" 2>/dev/null | awk '{print ($1*1024)" "$2}')`,
1045
+ ` echo "ps \${X:-0 0}"`,
1046
+ `fi`
1047
+ ].join("; ");
1048
+ }
1049
+ function parseProbe(out) {
1050
+ const parts = out.trim().split(/\s+/);
1051
+ const source = parts[0];
1052
+ const n = (i) => {
1053
+ const v = Number(parts[i]);
1054
+ return Number.isFinite(v) && v >= 0 ? v : 0;
1055
+ };
1056
+ let cpuPercent;
1057
+ let memoryMb;
1058
+ let diskMb = 0;
1059
+ if (source === "ps") {
1060
+ if (parts.length < 3) return { ...ZERO_USAGE, source: "none" };
1061
+ memoryMb = n(1) / (1024 * 1024);
1062
+ cpuPercent = n(2);
1063
+ } else if (source === "cgroup" || source === "proc") {
1064
+ if (parts.length < 6) return { ...ZERO_USAGE, source: "none" };
1065
+ const deltaUsec = Math.max(0, n(2) - n(1));
1066
+ cpuPercent = deltaUsec / (SAMPLE_MS * 1e3) * 100;
1067
+ memoryMb = n(3) / (1024 * 1024);
1068
+ diskMb = (n(4) + n(5)) / (1024 * 1024);
1069
+ } else {
1070
+ return { ...ZERO_USAGE, source: "none" };
1071
+ }
1072
+ return {
1073
+ cpuPercent: Math.round(cpuPercent * 100) / 100,
1074
+ memoryMb: Math.round(memoryMb * 100) / 100,
1075
+ diskMb: Math.round(diskMb * 100) / 100,
1076
+ // Per-process network accounting needs eBPF or a per-unit netns, neither of
1077
+ // which a bare deploy has. Zero here means "not measured", and the dashboard
1078
+ // shows network only for container runtimes.
1079
+ networkRxBytes: 0,
1080
+ networkTxBytes: 0,
1081
+ source
1082
+ };
1083
+ }
1084
+ async function sampleBareUsage(executor, pid, cgroupCandidates = []) {
1085
+ if (!Number.isInteger(pid) || pid <= 0) return { ...ZERO_USAGE };
1086
+ try {
1087
+ const out = await executor.exec(buildProbe(pid, cgroupCandidates));
1088
+ const { source: _source, ...usage } = parseProbe(out);
1089
+ return usage;
1090
+ } catch {
1091
+ return { ...ZERO_USAGE };
1092
+ }
1093
+ }
1094
+
1000
1095
  // ../../packages/adapters/src/runtime/supervisor/systemd.ts
1001
1096
  var UNIT_PREFIX = "openship";
1002
1097
  function escapeSystemdEnvValue(value) {
@@ -1147,6 +1242,33 @@ ${hint}` : "Process exited immediately after start (no output captured)";
1147
1242
  return false;
1148
1243
  }
1149
1244
  }
1245
+ /**
1246
+ * Usage for the unit. Prefers the unit's cgroup, which accounts for the whole
1247
+ * process tree — a `npm start` that forks the real server would otherwise report
1248
+ * only the wrapper's near-zero usage.
1249
+ *
1250
+ * `MainPID` is fetched as the fallback identity (and as the liveness check) for a
1251
+ * host without a readable cgroup; the probe picks the tier itself. `--value` is
1252
+ * used so a stopped unit yields "0" rather than a `MainPID=0` line to parse.
1253
+ */
1254
+ async getUsage(deploymentId) {
1255
+ const unitName = this.unitName(deploymentId);
1256
+ try {
1257
+ const out = await this.executor.exec(
1258
+ `systemctl show ${sq(unitName)} -p MainPID --value 2>/dev/null || true`
1259
+ );
1260
+ const pid = Number.parseInt(out.trim(), 10);
1261
+ if (!Number.isFinite(pid) || pid <= 0) return { ...ZERO_USAGE };
1262
+ return sampleBareUsage(this.executor, pid, [
1263
+ // Where systemd places a unit started from /etc/systemd/system. The delegate
1264
+ // path appears when the unit sets Delegate=yes; harmless to probe either way.
1265
+ `/sys/fs/cgroup/system.slice/${unitName}`,
1266
+ `/sys/fs/cgroup/system.slice/${unitName}/init.scope`
1267
+ ]);
1268
+ } catch {
1269
+ return { ...ZERO_USAGE };
1270
+ }
1271
+ }
1150
1272
  async getLogs(deploymentId, tail) {
1151
1273
  const unitName = this.unitName(deploymentId);
1152
1274
  const tailArg = tail ? `-n ${tail}` : `-n 200`;
@@ -1326,6 +1448,19 @@ ${hint}` : "Process exited immediately after spawn (no output captured)";
1326
1448
  if (!pid) return false;
1327
1449
  return this.isAlive(pid);
1328
1450
  }
1451
+ /**
1452
+ * Usage for the tracked process.
1453
+ *
1454
+ * No cgroup candidates: nohup does not create one (that's the documented
1455
+ * limitation above), so the probe uses /proc on Linux and `ps` on macOS. Both
1456
+ * measure the LEADER only — a start command that forks will under-report, which
1457
+ * is the same tradeoff as this supervisor's lack of restart and reboot handling.
1458
+ */
1459
+ async getUsage(deploymentId) {
1460
+ const pid = await this.readPid(deploymentId);
1461
+ if (!pid) return { ...ZERO_USAGE };
1462
+ return sampleBareUsage(this.executor, pid);
1463
+ }
1329
1464
  async getLogs(deploymentId, tail) {
1330
1465
  const logPath = this.logFile(deploymentId);
1331
1466
  try {
@@ -1404,6 +1539,12 @@ var BareRuntime = class {
1404
1539
  "destroy",
1405
1540
  "runtimeLogs",
1406
1541
  "streamLogs",
1542
+ // Real measurements now (cgroup → /proc → ps, via the supervisor), so this can
1543
+ // finally be declared. It was absent while getUsage returned a zeros stub — but
1544
+ // nothing checked, so callers rendered those zeros as data. Anything reading
1545
+ // usage should gate on supports("usage") rather than trust the numbers.
1546
+ // Network is the one gap: per-process rx/tx needs eBPF or a netns, so it stays 0.
1547
+ "usage",
1407
1548
  "containerIp",
1408
1549
  "rollback",
1409
1550
  // The release dir + supervisor unit survive a redeploy, so restoring a
@@ -1950,8 +2091,19 @@ var BareRuntime = class {
1950
2091
  const sv = await this.supervisor();
1951
2092
  return sv.streamLogs(containerId, onLog, opts);
1952
2093
  }
1953
- async getUsage(_containerId) {
1954
- return { cpuPercent: 0, memoryMb: 0, diskMb: 0, networkRxBytes: 0, networkTxBytes: 0 };
2094
+ /**
2095
+ * CPU / memory / disk-IO for the deployment's process.
2096
+ *
2097
+ * `containerId` is the DEPLOYMENT id here, not a docker container id — that's the
2098
+ * bare runtime's convention throughout (it's what the supervisor keys units and
2099
+ * PID files on).
2100
+ *
2101
+ * The supervisor owns the measurement because the identity differs: systemd has a
2102
+ * unit and a cgroup, nohup has a PID file. Both land on the same probe.
2103
+ */
2104
+ async getUsage(containerId) {
2105
+ const sv = await this.supervisor();
2106
+ return sv.getUsage(containerId);
1955
2107
  }
1956
2108
  // ── Network ────────────────────────────────────────────────────────────
1957
2109
  async getContainerIp(_containerId) {
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  detectBuildKillHint,
7
7
  runBuildPipeline,
8
8
  transferLocalDirectory
9
- } from "./chunk-I6PSTQIR.js";
9
+ } from "./chunk-VDDMADOF.js";
10
10
  import {
11
11
  LocalExecutor
12
- } from "./chunk-TYVME3XD.js";
12
+ } from "./chunk-6FH4AXVY.js";
13
13
  import {
14
14
  wrapLocalBuildCommand
15
- } from "./chunk-FPRHYBY2.js";
15
+ } from "./chunk-ZFJXPCQP.js";
16
16
 
17
17
  // ../../packages/adapters/src/runtime/local-build.ts
18
18
  var LOCAL_BUILD_DIR = "/tmp/openship/.builds";