@dotobokuri/fleet-cli 1.5.0 → 1.5.1

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.
@@ -25,7 +25,6 @@ Confirm each readiness check below before the Workflow. Work through them in ord
25
25
  - [ ] **Common** — objective stated (Mission Anchor), mode-fit holds (Mode Gate), Standing Orders binding. → report `common: ready`
26
26
  - [ ] **Impact radius** — flag public-surface or API impact, irreversibility, and any security-sensitive surface. → report `impact: <…>`
27
27
  - [ ] **Rollback** — identify a rollback-safe checkpoint and any Admiral of the Navy approval point before execution begins. → report `rollback: <…>`
28
- - [ ] **Isolation** — confirm a working branch or worktree isolates the change; no direct work on the default branch. → report `isolation: <branch>`
29
28
  - [ ] **Carrier availability** — confirm the intended carriers are actually exposed and available this session. → report `carriers: <…>`
30
29
  - [ ] **Ownership** — pre-sketch each carrier's file or responsibility boundary. → report `ownership: <…>`
31
30
  - [ ] **Shared resources** — flag shared mutable resources (same files, lock files, or a singleton test environment). → report `shared: <…|none>`
@@ -26,7 +26,6 @@ Confirm each readiness check below before the Workflow. Work through them in ord
26
26
  - [ ] **Doctrine** — enumerate the applicable AGENTS.md files to load for the affected scope. → report `doctrine: <…>`
27
27
  - [ ] **Impact radius** — flag public-surface or API impact, irreversibility, and any security-sensitive surface. → report `impact: <…>`
28
28
  - [ ] **Rollback** — identify a rollback-safe checkpoint and any Admiral of the Navy approval point before execution begins. → report `rollback: <…>`
29
- - [ ] **Isolation** — confirm a working branch or worktree isolates the change; no direct work on the default branch. → report `isolation: <branch>`
30
29
  - [ ] **Escalation** — if multiple carriers or parallel ownership boundaries are required, re-classify under frontline. → report `escalation: clear`
31
30
 
32
31
  ## Workflow
package/dist/index.js CHANGED
@@ -71608,6 +71608,10 @@ function writeAggregateObserverEvents(req, res, workspaces, store22, resolveWork
71608
71608
  }
71609
71609
  const unsubscribers = options2.subscribeAll ? [
71610
71610
  store22.subscribeAll((event) => {
71611
+ if (isSessionUpdatedEvent(event)) {
71612
+ writeEvent(res, 0, event.type, { session: event.session });
71613
+ return;
71614
+ }
71611
71615
  writeEvent(res, event.id, event.type, { tenant: resolvedWorkspaceSnapshot(resolveWorkspace, event.tenantId), event });
71612
71616
  })
71613
71617
  ] : workspaces.map(
@@ -71630,6 +71634,9 @@ function writeEvent(res, id, event, data) {
71630
71634
 
71631
71635
  `);
71632
71636
  }
71637
+ function isSessionUpdatedEvent(event) {
71638
+ return event.type === "session:updated" && "session" in event;
71639
+ }
71633
71640
  function workspaceSnapshot(workspace) {
71634
71641
  return {
71635
71642
  tenantId: workspace.tenantId,
@@ -71665,6 +71672,7 @@ function createConsoleObservabilityStore(deps = {}) {
71665
71672
  const truncationByTenant = /* @__PURE__ */ new Map();
71666
71673
  const jobsByTenant = /* @__PURE__ */ new Map();
71667
71674
  const terminalSessionsById = /* @__PURE__ */ new Map();
71675
+ const terminalSequenceByTheater = /* @__PURE__ */ new Map();
71668
71676
  const listenersByTenant = /* @__PURE__ */ new Map();
71669
71677
  const allListeners = /* @__PURE__ */ new Set();
71670
71678
  let nextObservedId = 1;
@@ -71828,13 +71836,18 @@ function createConsoleObservabilityStore(deps = {}) {
71828
71836
  function createPendingTerminalSession(input) {
71829
71837
  if (!path9__default.isAbsolute(input.cwd)) throw new Error("Terminal session cwd must be absolute");
71830
71838
  const createdAt = input.createdAt ?? now();
71839
+ const canonicalCwd = canonicalizeTheaterPathSync(input.cwd);
71840
+ const theaterId = workspaceHash(canonicalCwd);
71841
+ const sequence = (terminalSequenceByTheater.get(theaterId) ?? 0) + 1;
71842
+ terminalSequenceByTheater.set(theaterId, sequence);
71831
71843
  const state = {
71832
71844
  sessionId: input.sessionId,
71833
71845
  cwd: input.cwd,
71834
- canonicalCwd: canonicalizeTheaterPathSync(input.cwd),
71846
+ canonicalCwd,
71835
71847
  cwdLabel: path9__default.basename(input.cwd) || input.cwd,
71848
+ sequence,
71836
71849
  createdAt,
71837
- theaterId: workspaceHash(canonicalizeTheaterPathSync(input.cwd)),
71850
+ theaterId,
71838
71851
  terminalSessionId: input.sessionId,
71839
71852
  status: "starting"
71840
71853
  };
@@ -71850,6 +71863,21 @@ function createConsoleObservabilityStore(deps = {}) {
71850
71863
  session.status = status;
71851
71864
  return toTerminalSessionInfo(session);
71852
71865
  }
71866
+ function renameTerminalSession(sessionId, rawLabel) {
71867
+ const session = terminalSessionsById.get(sessionId);
71868
+ if (!session) return null;
71869
+ const label = rawLabel.trim().slice(0, 200);
71870
+ if (label.length === 0) {
71871
+ delete session.label;
71872
+ } else {
71873
+ session.label = label;
71874
+ }
71875
+ return toTerminalSessionInfo(session);
71876
+ }
71877
+ function notifySessionUpdated(session) {
71878
+ const event = { type: "session:updated", session };
71879
+ for (const listener of allListeners) listener(event);
71880
+ }
71853
71881
  function removeTerminalSession(sessionId) {
71854
71882
  return terminalSessionsById.delete(sessionId);
71855
71883
  }
@@ -71861,6 +71889,7 @@ function createConsoleObservabilityStore(deps = {}) {
71861
71889
  truncationByTenant.clear();
71862
71890
  jobsByTenant.clear();
71863
71891
  terminalSessionsById.clear();
71892
+ terminalSequenceByTheater.clear();
71864
71893
  listenersByTenant.clear();
71865
71894
  allListeners.clear();
71866
71895
  }
@@ -71880,6 +71909,8 @@ function createConsoleObservabilityStore(deps = {}) {
71880
71909
  pushEvents,
71881
71910
  register,
71882
71911
  createPendingTerminalSession,
71912
+ notifySessionUpdated,
71913
+ renameTerminalSession,
71883
71914
  subscribe,
71884
71915
  subscribeAll,
71885
71916
  updateTerminalSessionStatus,
@@ -71961,6 +71992,8 @@ function toTerminalSessionInfo(state) {
71961
71992
  sessionId: state.sessionId,
71962
71993
  terminalSessionId: state.terminalSessionId,
71963
71994
  cwdLabel: state.cwdLabel,
71995
+ sequence: state.sequence,
71996
+ label: state.label,
71964
71997
  status: state.status,
71965
71998
  createdAt: state.createdAt,
71966
71999
  theaterId: state.theaterId,
@@ -72367,15 +72400,11 @@ function buildShellLaunchEnv(env) {
72367
72400
  }
72368
72401
  var DEFAULT_COLS = 80;
72369
72402
  var DEFAULT_ROWS2 = 24;
72370
- var DEFAULT_GRACE_MS = 18e4;
72371
72403
  var DEFAULT_SCROLLBACK_LIMIT = 512;
72372
72404
  var WS_OPEN_STATE = 1;
72373
72405
  function createTerminalSessionManager(deps) {
72374
72406
  const startShell2 = deps.startShell ?? startTerminalShell;
72375
- const graceMs = deps.graceMs ?? DEFAULT_GRACE_MS;
72376
72407
  const scrollbackLimit = deps.scrollbackLimit ?? DEFAULT_SCROLLBACK_LIMIT;
72377
- const setTimeoutImpl = deps.setTimeout ?? setTimeout;
72378
- const clearTimeoutImpl = deps.clearTimeout ?? clearTimeout;
72379
72408
  const sessions = /* @__PURE__ */ new Map();
72380
72409
  function canAttach() {
72381
72410
  return true;
@@ -72385,10 +72414,6 @@ function createTerminalSessionManager(deps) {
72385
72414
  if (session.activeSocket && session.activeSocket !== socket) {
72386
72415
  session.activeSocket.close(4e3, "terminal_replaced");
72387
72416
  }
72388
- if (session.graceTimer) {
72389
- clearTimeoutImpl(session.graceTimer);
72390
- session.graceTimer = null;
72391
- }
72392
72417
  session.activeSocket = socket;
72393
72418
  session.pty.resize(session.cols, session.rows);
72394
72419
  replayScrollback(session, socket);
@@ -72420,7 +72445,6 @@ function createTerminalSessionManager(deps) {
72420
72445
  disposables: [],
72421
72446
  scrollback: [],
72422
72447
  activeSocket: null,
72423
- graceTimer: null,
72424
72448
  cols: DEFAULT_COLS,
72425
72449
  rows: DEFAULT_ROWS2
72426
72450
  };
@@ -72460,7 +72484,6 @@ function createTerminalSessionManager(deps) {
72460
72484
  function detachSocket(session, socket) {
72461
72485
  if (session.activeSocket !== socket) return;
72462
72486
  session.activeSocket = null;
72463
- session.graceTimer = setTimeoutImpl(() => removeSession(session), graceMs);
72464
72487
  }
72465
72488
  function replayScrollback(session, socket) {
72466
72489
  for (const chunk of session.scrollback) {
@@ -72476,10 +72499,6 @@ function createTerminalSessionManager(deps) {
72476
72499
  }
72477
72500
  function killSession(session, options2 = {}) {
72478
72501
  const killPty = options2.killPty ?? true;
72479
- if (session.graceTimer) {
72480
- clearTimeoutImpl(session.graceTimer);
72481
- session.graceTimer = null;
72482
- }
72483
72502
  session.activeSocket?.close(4001, "terminal_closed");
72484
72503
  session.activeSocket = null;
72485
72504
  for (const disposable of session.disposables) disposable.dispose();
@@ -72619,7 +72638,7 @@ var MAX_BODY_BYTES = 1024 * 1024;
72619
72638
  function createConsoleServer(deps = {}) {
72620
72639
  const host = deps.host ?? DEFAULT_HOST2;
72621
72640
  const port = deps.port ?? DEFAULT_PORT2;
72622
- const version22 = deps.version ?? (typeof __PKG_VERSION__ === "string" ? __PKG_VERSION__ : "0.0.0-dev");
72641
+ const version22 = deps.version ?? readFleetConsoleRelease().version;
72623
72642
  const channel = readConsoleChannel();
72624
72643
  const carrierRegistry = createCarrierRegistry2();
72625
72644
  registerDefaultCarriers2(carrierRegistry);
@@ -72639,7 +72658,6 @@ function createConsoleServer(deps = {}) {
72639
72658
  const terminalSessions = createTerminalSessionManager({
72640
72659
  launch: deps.terminalLaunch ?? createDefaultTerminalLaunchResolver(),
72641
72660
  startShell: deps.terminalStartShell,
72642
- graceMs: deps.terminalGraceMs,
72643
72661
  maxSessions: deps.maxTerminalSessions,
72644
72662
  // PTY가 종료되면(예: fleet-cli 종료) 콘솔 세션 목록에서도 제거해 잔존/재실행을 막는다.
72645
72663
  onSessionExit: (sessionId) => observability.removeTerminalSession(sessionId)
@@ -72700,7 +72718,7 @@ function createConsoleServer(deps = {}) {
72700
72718
  }
72701
72719
  const terminalSessionItemMatch = pathname.match(/^\/terminal\/sessions\/([^/]+)$/);
72702
72720
  if (terminalSessionItemMatch) {
72703
- handleTerminalSessionItem(req, res, decodeURIComponent(terminalSessionItemMatch[1] ?? ""));
72721
+ runAsyncHandler(handleTerminalSessionItem(req, res, decodeURIComponent(terminalSessionItemMatch[1] ?? "")), res);
72704
72722
  return;
72705
72723
  }
72706
72724
  if (pathname === "/observer/theaters") {
@@ -72896,8 +72914,8 @@ function createConsoleServer(deps = {}) {
72896
72914
  }
72897
72915
  await createTerminalSessionForCwd(cwd, res);
72898
72916
  }
72899
- function handleTerminalSessionItem(req, res, sessionId) {
72900
- if (req.method !== "DELETE") {
72917
+ async function handleTerminalSessionItem(req, res, sessionId) {
72918
+ if (req.method !== "DELETE" && req.method !== "PATCH") {
72901
72919
  writeJson(res, 405, { error: "Method not allowed" });
72902
72920
  return;
72903
72921
  }
@@ -72905,6 +72923,21 @@ function createConsoleServer(deps = {}) {
72905
72923
  writeJson(res, 401, { error: "unauthorized" });
72906
72924
  return;
72907
72925
  }
72926
+ if (req.method === "PATCH") {
72927
+ const body = await readJsonBody(req);
72928
+ if (!body || body.label !== void 0 && typeof body.label !== "string") {
72929
+ writeJson(res, 400, { error: "invalid_session_label" });
72930
+ return;
72931
+ }
72932
+ const updated = observability.renameTerminalSession(sessionId, body.label ?? "");
72933
+ if (!updated) {
72934
+ writeJson(res, 404, { error: "session_not_found" });
72935
+ return;
72936
+ }
72937
+ observability.notifySessionUpdated(updated);
72938
+ writeJson(res, 200, updated);
72939
+ return;
72940
+ }
72908
72941
  terminalSessions.terminate(sessionId);
72909
72942
  observability.removeTerminalSession(sessionId);
72910
72943
  writeJson(res, 200, { ok: true });