@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
|
|
71846
|
+
canonicalCwd,
|
|
71835
71847
|
cwdLabel: path9__default.basename(input.cwd) || input.cwd,
|
|
71848
|
+
sequence,
|
|
71836
71849
|
createdAt,
|
|
71837
|
-
theaterId
|
|
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 ?? (
|
|
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 });
|