procdeck 0.5.0 → 1.0.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/dist/cli.js CHANGED
@@ -45501,7 +45501,11 @@ var resolveSpec = (spec, assigned, internal) => {
45501
45501
  ...spec,
45502
45502
  ...spec.shell === void 0 ? {} : { shell: bind6(spec.shell) },
45503
45503
  ...spec.cmd === void 0 ? {} : { cmd: spec.cmd.map(bind6) },
45504
- ...spec.env === void 0 ? {} : { env: Object.fromEntries(Object.entries(spec.env).map(([key, value3]) => [key, bind6(value3)])) },
45504
+ ...spec.env === void 0 ? {} : {
45505
+ env: Object.fromEntries(
45506
+ Object.entries(spec.env).map(([key, value3]) => [key, bind6(value3)])
45507
+ )
45508
+ },
45505
45509
  ...spec.url === void 0 ? {} : { url: publicOnly(spec.url) }
45506
45510
  };
45507
45511
  };
@@ -46120,7 +46124,7 @@ var selfLogs = (follow) => Effect_exports.gen(function* () {
46120
46124
  }),
46121
46125
  (onChange) => Effect_exports.sync(() => unwatchFile(file6, onChange))
46122
46126
  );
46123
- yield* Effect_exports.never;
46127
+ return yield* Effect_exports.never;
46124
46128
  }).pipe(Effect_exports.scoped);
46125
46129
  var logsQuery = (options) => Effect_exports.gen(function* () {
46126
46130
  let sinceMs;
@@ -46299,7 +46303,9 @@ var errors2 = Command_exports.make(
46299
46303
  const render = (group2) => {
46300
46304
  const head = `[${group2.proc}] ${group2.count}\xD7 \xB7 last ${ago(group2.lastTs)}${group2.count > 1 ? ` \xB7 first ${ago(group2.firstTs)}` : ""}`;
46301
46305
  const sample = group2.sample.slice(0, SAMPLE_SHOWN).map((line) => ` ${line}`);
46302
- const more = group2.sample.length > SAMPLE_SHOWN ? [` \u2026 +${group2.sample.length - SAMPLE_SHOWN} more lines (\`procdeck logs ${group2.proc}\`)`] : [];
46306
+ const more = group2.sample.length > SAMPLE_SHOWN ? [
46307
+ ` \u2026 +${group2.sample.length - SAMPLE_SHOWN} more lines (\`procdeck logs ${group2.proc}\`)`
46308
+ ] : [];
46303
46309
  return [head, ...sample, ...more].join("\n");
46304
46310
  };
46305
46311
  yield* Console_exports.log(groups.map(render).join("\n\n"));
@@ -46317,9 +46323,10 @@ var agents = Command_exports.make(
46317
46323
  const root = path11.dirname(configPath);
46318
46324
  const actions = setupAgents(root);
46319
46325
  yield* Console_exports.log(
46320
- ["procdeck: introducing the deck to coding agents", ...actions.map((line) => ` ${line}`)].join(
46321
- "\n"
46322
- )
46326
+ [
46327
+ "procdeck: introducing the deck to coding agents",
46328
+ ...actions.map((line) => ` ${line}`)
46329
+ ].join("\n")
46323
46330
  );
46324
46331
  yield* Console_exports.log(
46325
46332
  "tip: `claude mcp add procdeck -- procdeck mcp` adds the MCP tools in every procdeck project at once"
@@ -46334,9 +46341,7 @@ var mcp = Command_exports.make(
46334
46341
  "mcp",
46335
46342
  {
46336
46343
  mutations: Flag_exports.boolean("mutations").pipe(
46337
- Flag_exports.withDescription(
46338
- "also expose restart_proc / stop_proc / start_proc (default: read-only)"
46339
- )
46344
+ Flag_exports.withDescription("also expose restart_proc / stop_proc / start_proc (default: read-only)")
46340
46345
  )
46341
46346
  },
46342
46347
  // The server owns stdout from here on: no Console.log in this branch,
@@ -46782,7 +46787,9 @@ var planInit = (root) => {
46782
46787
  );
46783
46788
  }
46784
46789
  const globs = workspaceGlobs(root);
46785
- const dirs = [...new Set(globs.filter((g) => !g.startsWith("!")).flatMap((g) => expandGlob(root, g)))];
46790
+ const dirs = [
46791
+ ...new Set(globs.filter((g) => !g.startsWith("!")).flatMap((g) => expandGlob(root, g)))
46792
+ ];
46786
46793
  const fromWorkspaces = [];
46787
46794
  const workspaceNotes = [];
46788
46795
  for (const dir2 of dirs) {
@@ -46812,7 +46819,9 @@ var planInit = (root) => {
46812
46819
  }
46813
46820
  return done4(
46814
46821
  [{ id: "app", shell: "echo 'edit procdeck.config.json'; sleep 1000" }],
46815
- ["nothing recognisable here (package.json scripts, Procfile, Django/Go/Rust/Rails/compose) \u2014 wrote a template to edit"],
46822
+ [
46823
+ "nothing recognisable here (package.json scripts, Procfile, Django/Go/Rust/Rails/compose) \u2014 wrote a template to edit"
46824
+ ],
46816
46825
  "template"
46817
46826
  );
46818
46827
  };
@@ -47325,7 +47334,10 @@ var make63 = Effect_exports.fn("procdeck.supervisor")(function* (loaded) {
47325
47334
  const resolved2 = resolveSpec(spec, assigned, internal);
47326
47335
  runtimes.set(spec.id, {
47327
47336
  spec,
47328
- resolved: assignedPort === void 0 ? resolved2 : { ...resolved2, env: { PORT: String(internalPort ?? assignedPort), ...resolved2.env } },
47337
+ resolved: assignedPort === void 0 ? resolved2 : (
47338
+ // The PaaS contract: the port to bind also arrives as `PORT`.
47339
+ { ...resolved2, env: { PORT: String(internalPort ?? assignedPort), ...resolved2.env } }
47340
+ ),
47329
47341
  assignedPort,
47330
47342
  internalPort,
47331
47343
  status: { id: spec.id, state: "stopped" },
@@ -47385,9 +47397,7 @@ var make63 = Effect_exports.fn("procdeck.supervisor")(function* (loaded) {
47385
47397
  return Stream_exports.concat(
47386
47398
  Stream_exports.fromIterable(backlog),
47387
47399
  Stream_exports.fromSubscription(subscription).pipe(
47388
- Stream_exports.filter(
47389
- (event) => event.type !== "log" || event.seq >= (seen.get(event.id) ?? 0)
47390
- )
47400
+ Stream_exports.filter((event) => event.type !== "log" || event.seq >= (seen.get(event.id) ?? 0))
47391
47401
  )
47392
47402
  );
47393
47403
  })
@@ -47840,6 +47850,7 @@ var routes = (supervisor, deck, hooks) => HttpRouter_exports.addAll([
47840
47850
  root: instance.root,
47841
47851
  port: instance.port,
47842
47852
  startedAt: instance.startedAt,
47853
+ version: instance.version,
47843
47854
  self: instance.root === deck.root
47844
47855
  }))
47845
47856
  )
@@ -48078,7 +48089,7 @@ var runServer = (loaded, configPath) => Effect_exports.gen(function* () {
48078
48089
  yield* Effect_exports.log(
48079
48090
  `procdeck ${VERSION} "${loaded.name}" listening on http://localhost:${port}${host === DEFAULT_UI_HOST ? "" : ` (bound to ${host})`} (pid ${process.pid}, ${mode})`
48080
48091
  );
48081
- yield* Effect_exports.never;
48092
+ return yield* Effect_exports.never;
48082
48093
  }).pipe(Effect_exports.scoped);
48083
48094
  var fgFlag = Flag_exports.boolean("fg").pipe(
48084
48095
  Flag_exports.withDescription("run in the foreground \u2014 Ctrl-C stops the deck")
@@ -48100,6 +48111,7 @@ var upHandler = ({
48100
48111
  yield* Console_exports.log(
48101
48112
  `procdeck: "${running.name}" is already up \u2192 ${deckUrl(running)} (pid ${running.pid})`
48102
48113
  );
48114
+ yield* versionNotice(running);
48103
48115
  if (open5) openBrowser(deckUrl(running));
48104
48116
  return;
48105
48117
  }
@@ -48122,6 +48134,9 @@ var upHandler = ({
48122
48134
  yield* Console_exports.log(" procdeck down \xB7 status \xB7 logs -f \xB7 open");
48123
48135
  if (open5) openBrowser(deckUrl(instance));
48124
48136
  });
48137
+ var versionNotice = (instance) => instance.version === VERSION ? Effect_exports.void : Console_exports.log(
48138
+ `procdeck: deck runs v${instance.version}, CLI is v${VERSION} \u2014 \`procdeck restart\` picks up the new version`
48139
+ );
48125
48140
  var downHandler = ({ config }) => Effect_exports.gen(function* () {
48126
48141
  const root = yield* resolveRoot(config);
48127
48142
  const instance = findInstance(root);
@@ -48133,7 +48148,11 @@ var downHandler = ({ config }) => Effect_exports.gen(function* () {
48133
48148
  const outcome = yield* Effect_exports.promise(() => shutdown3(instance));
48134
48149
  yield* Console_exports.log(outcome === "stopped" ? "down" : "did not stop in time, killed");
48135
48150
  });
48136
- var up = Command_exports.make("up", { config: configArgument, fg: fgFlag, open: openFlag }, upHandler).pipe(
48151
+ var up = Command_exports.make(
48152
+ "up",
48153
+ { config: configArgument, fg: fgFlag, open: openFlag },
48154
+ upHandler
48155
+ ).pipe(
48137
48156
  Command_exports.withDescription(
48138
48157
  "Start the deck and open its UI. Detaches by default: the deck keeps running after the terminal closes (`procdeck down` stops it). Idempotent \u2014 an already-running deck is just opened."
48139
48158
  )
@@ -48141,6 +48160,34 @@ var up = Command_exports.make("up", { config: configArgument, fg: fgFlag, open:
48141
48160
  var down = Command_exports.make("down", { config: configArgument }, downHandler).pipe(
48142
48161
  Command_exports.withDescription("Stop the deck: every process tree is terminated, then procdeck exits.")
48143
48162
  );
48163
+ var restartAllHandler = Effect_exports.gen(function* () {
48164
+ const instances = listInstances();
48165
+ if (instances.length === 0) return yield* Console_exports.log("procdeck: no decks are up");
48166
+ let failures = 0;
48167
+ for (const instance of instances) {
48168
+ if (instance.mode === "foreground") {
48169
+ yield* Console_exports.log(
48170
+ `procdeck: skipping "${instance.name}" (${pretty2(instance.root)}) \u2014 foreground deck, restart it in its own terminal`
48171
+ );
48172
+ continue;
48173
+ }
48174
+ process.stdout.write(`procdeck: restarting "${instance.name}" (${pretty2(instance.root)})\u2026 `);
48175
+ yield* Effect_exports.promise(() => shutdown3(instance));
48176
+ const outcome = yield* Effect_exports.promise(async () => {
48177
+ try {
48178
+ const fresh2 = await detach(process.argv[1], instance.config, instance.root);
48179
+ return `up \u2192 ${deckUrl(fresh2)} (v${fresh2.version})`;
48180
+ } catch (cause) {
48181
+ failures += 1;
48182
+ return `failed: ${cause.message}`;
48183
+ }
48184
+ });
48185
+ yield* Console_exports.log(outcome);
48186
+ }
48187
+ if (failures > 0) {
48188
+ return yield* fail11(`${failures} deck${failures === 1 ? "" : "s"} did not come back \u2014 see above`);
48189
+ }
48190
+ });
48144
48191
  var restart = Command_exports.make(
48145
48192
  "restart",
48146
48193
  {
@@ -48148,10 +48195,13 @@ var restart = Command_exports.make(
48148
48195
  Argument_exports.optional,
48149
48196
  Argument_exports.withDescription("proc id \u2014 restart just this process (default: the whole deck)")
48150
48197
  ),
48198
+ all: Flag_exports.boolean("all").pipe(
48199
+ Flag_exports.withDescription("restart every deck on this machine (e.g. after updating procdeck)")
48200
+ ),
48151
48201
  fg: fgFlag,
48152
48202
  open: openFlag
48153
48203
  },
48154
- ({ fg, open: open5, proc }) => Option_exports.isSome(proc) ? Effect_exports.gen(function* () {
48204
+ ({ all: all4, fg, open: open5, proc }) => all4 ? Option_exports.isSome(proc) ? fail11(`--all restarts every deck \u2014 drop "${proc.value}"`) : restartAllHandler : Option_exports.isSome(proc) ? Effect_exports.gen(function* () {
48155
48205
  const instance = yield* requireInstance(Option_exports.none());
48156
48206
  const procs = yield* callApi(() => apiGet(instance, "/procs"));
48157
48207
  if (!procs.some((info2) => info2.id === proc.value)) {
@@ -48170,7 +48220,7 @@ var restart = Command_exports.make(
48170
48220
  )
48171
48221
  ).pipe(
48172
48222
  Command_exports.withDescription(
48173
- "Restart one proc (`restart api`), or the whole deck (`restart`) \u2014 the latter after updating procdeck or editing the config."
48223
+ "Restart one proc (`restart api`), the whole deck (`restart`), or every deck on this machine (`restart --all`) \u2014 the deck-wide forms after updating procdeck or editing the config."
48174
48224
  )
48175
48225
  );
48176
48226
  var status = Command_exports.make(
@@ -48192,8 +48242,9 @@ var status = Command_exports.make(
48192
48242
  }
48193
48243
  const procs = yield* fetchProcs2(instance);
48194
48244
  yield* Console_exports.log(
48195
- `${instance.name} \xB7 ${deckUrl(instance)} \xB7 up ${describeUptime(instance.startedAt)} \xB7 pid ${instance.pid} \xB7 ${countRunning(procs)}${instance.mode === "foreground" ? " \xB7 foreground" : ""}`
48245
+ `${instance.name} \xB7 ${deckUrl(instance)} \xB7 up ${describeUptime(instance.startedAt)} \xB7 pid ${instance.pid} \xB7 ${countRunning(procs)} \xB7 v${instance.version}${instance.mode === "foreground" ? " \xB7 foreground" : ""}`
48196
48246
  );
48247
+ yield* versionNotice(instance);
48197
48248
  if (procs === void 0 || procs.length === 0) return;
48198
48249
  yield* Console_exports.log(
48199
48250
  table2(
@@ -48225,10 +48276,16 @@ var ls = Command_exports.make(
48225
48276
  `:${instance.port}`,
48226
48277
  `up ${describeUptime(instance.startedAt)}`,
48227
48278
  countRunning(procs[i]),
48279
+ `v${instance.version}`,
48228
48280
  pretty2(instance.root)
48229
48281
  ])
48230
48282
  )
48231
48283
  );
48284
+ if (instances.some((instance) => instance.version !== VERSION)) {
48285
+ yield* Console_exports.log(
48286
+ `procdeck: some decks run a different procdeck than the CLI (v${VERSION}) \u2014 \`procdeck restart --all\` brings them over`
48287
+ );
48288
+ }
48232
48289
  })
48233
48290
  ).pipe(Command_exports.withDescription("Every running deck on this machine."));
48234
48291
  var open4 = Command_exports.make(
@@ -48318,12 +48375,7 @@ var NodeLayer = layer2.pipe(
48318
48375
  layer5,
48319
48376
  layer6,
48320
48377
  CliConfig_exports.layer({
48321
- builtIns: [
48322
- GlobalFlag_exports.Help,
48323
- GlobalFlag_exports.Version,
48324
- GlobalFlag_exports.Completions,
48325
- GlobalFlag_exports.LogLevel
48326
- ]
48378
+ builtIns: [GlobalFlag_exports.Help, GlobalFlag_exports.Version, GlobalFlag_exports.Completions, GlobalFlag_exports.LogLevel]
48327
48379
  })
48328
48380
  )
48329
48381
  )
@@ -48333,9 +48385,11 @@ procdeck.pipe(
48333
48385
  Effect_exports.catchTag(
48334
48386
  "CliFailure",
48335
48387
  (failure) => Console_exports.error(`procdeck: ${failure.message}`).pipe(
48336
- Effect_exports.andThen(Effect_exports.sync(() => {
48337
- process.exitCode = failure.code ?? 1;
48338
- }))
48388
+ Effect_exports.andThen(
48389
+ Effect_exports.sync(() => {
48390
+ process.exitCode = failure.code ?? 1;
48391
+ })
48392
+ )
48339
48393
  )
48340
48394
  ),
48341
48395
  Effect_exports.provide(NodeLayer),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "procdeck",
3
- "version": "0.5.0",
3
+ "version": "1.0.0",
4
4
  "description": "Interactive dev-process multiplexer with a web UI: terminal panes in a browser tab, declarative dependencies, assigned ports and a *.localhost reverse proxy.",
5
5
  "keywords": [
6
6
  "cli",
@@ -24,18 +24,15 @@
24
24
  "url": "https://github.com/kondaurovDev/procdeck",
25
25
  "directory": "packages/procdeck"
26
26
  },
27
- "type": "module",
28
- "engines": {
29
- "node": ">=22"
27
+ "bin": {
28
+ "procdeck": "./dist/cli.js"
30
29
  },
31
30
  "files": [
32
31
  "dist",
33
32
  "schema.json",
34
33
  "ui/dist"
35
34
  ],
36
- "bin": {
37
- "procdeck": "./dist/cli.js"
38
- },
35
+ "type": "module",
39
36
  "exports": {
40
37
  ".": {
41
38
  "types": "./dist/public.d.ts",
@@ -63,6 +60,9 @@
63
60
  "vite": "^6.2.0",
64
61
  "vitest": "^3.2.4"
65
62
  },
63
+ "engines": {
64
+ "node": ">=22"
65
+ },
66
66
  "scripts": {
67
67
  "ui:dev": "vite ui",
68
68
  "build": "pnpm run build:meta && pnpm run build:schema && pnpm run build:ui && pnpm run build:js && pnpm run build:types",