@@ -4,7 +4,6 @@ import { join } from "@std/path";
44import type { DaemonCliCommandContext } from "./context.ts" ;
55import { isStatusSnapshotStale } from "@kato/runtime" ;
66import { CLI_APP_VERSION } from "../version.ts" ;
7- import type { RegisteredWorkspace } from "@kato/runtime" ;
87import {
98 loadWorkspaceConfigOverrides ,
109 readWorkspaceConfigWorkspaceId ,
@@ -15,6 +14,14 @@ import {
1514 resolveStatusErrorCursorPath ,
1615 saveSuppressedRecentErrorKeys ,
1716} from "./status_error_cursor.ts" ;
17+ import {
18+ loadWorkspaceStatusSummary ,
19+ type WorkspaceStatusSummary ,
20+ } from "./status_workspace.ts" ;
21+ export type {
22+ WorkspaceStatusRow ,
23+ WorkspaceStatusSummary ,
24+ } from "./status_workspace.ts" ;
1825
1926const LIVE_REFRESH_MS = 2_000 ;
2027const LIVE_SESSION_CAP = 5 ;
@@ -43,22 +50,6 @@ const ANSI_CSI_PATTERN = new RegExp(
4350 "g" ,
4451) ;
4552
46- export interface WorkspaceStatusRow {
47- workspaceId : string ;
48- alias : string ;
49- workspaceRoot : string ;
50- configPath : string ;
51- valid : boolean ;
52- invalidReason ?: string ;
53- }
54-
55- export interface WorkspaceStatusSummary {
56- activeCount : number ;
57- invalidCount : number ;
58- rows : WorkspaceStatusRow [ ] ;
59- unavailableReason ?: string ;
60- }
61-
6253export interface StatusRecentError {
6354 timestamp : string ;
6455 level : "warn" | "error" ;
@@ -171,92 +162,6 @@ function resolveTerminalWidth(): number {
171162 }
172163}
173164
174- function formatWorkspaceValidationError ( error : unknown ) : string {
175- if ( error instanceof Deno . errors . NotFound ) {
176- return "config file not found" ;
177- }
178- if ( error instanceof Deno . errors . PermissionDenied ) {
179- return "permission denied while reading config" ;
180- }
181- if ( error instanceof Error && error . message . trim ( ) . length > 0 ) {
182- return sanitizeInlineText ( error . message ) ;
183- }
184- return sanitizeInlineText ( String ( error ) ) ;
185- }
186-
187- function toWorkspaceStatusRow (
188- entry : RegisteredWorkspace ,
189- opts : { valid : boolean ; invalidReason ?: string } ,
190- ) : WorkspaceStatusRow {
191- return {
192- workspaceId : entry . workspaceId ,
193- alias : entry . alias ,
194- workspaceRoot : entry . workspaceRoot ,
195- configPath : entry . configPath ,
196- valid : opts . valid ,
197- ...( opts . invalidReason ? { invalidReason : opts . invalidReason } : { } ) ,
198- } ;
199- }
200-
201- async function validateWorkspaceEntry (
202- entry : RegisteredWorkspace ,
203- ) : Promise < WorkspaceStatusRow > {
204- try {
205- await loadWorkspaceConfigOverrides ( entry . configPath ) ;
206- const configuredWorkspaceId = await readWorkspaceConfigWorkspaceId (
207- entry . configPath ,
208- { allowMissing : true } ,
209- ) ;
210- if (
211- configuredWorkspaceId &&
212- configuredWorkspaceId !== entry . workspaceId
213- ) {
214- return toWorkspaceStatusRow ( entry , {
215- valid : false ,
216- invalidReason :
217- `workspaceId mismatch (registry=${ entry . workspaceId } , config=${ configuredWorkspaceId } )` ,
218- } ) ;
219- }
220- return toWorkspaceStatusRow ( entry , { valid : true } ) ;
221- } catch ( error ) {
222- return toWorkspaceStatusRow ( entry , {
223- valid : false ,
224- invalidReason : formatWorkspaceValidationError ( error ) ,
225- } ) ;
226- }
227- }
228-
229- async function loadWorkspaceStatusSummary (
230- ctx : DaemonCliCommandContext ,
231- ) : Promise < WorkspaceStatusSummary > {
232- let entries : RegisteredWorkspace [ ] ;
233- try {
234- entries = await resolveWorkspaceRegistryStore ( ctx ) . load ( ) ;
235- } catch ( error ) {
236- return {
237- activeCount : 0 ,
238- invalidCount : 0 ,
239- rows : [ ] ,
240- unavailableReason : formatWorkspaceValidationError ( error ) ,
241- } ;
242- }
243-
244- const rows = await Promise . all (
245- entries . map ( ( entry ) => validateWorkspaceEntry ( entry ) ) ,
246- ) ;
247- rows . sort ( ( a , b ) =>
248- a . alias . localeCompare ( b . alias ) ||
249- a . workspaceId . localeCompare ( b . workspaceId )
250- ) ;
251-
252- const activeCount = rows . filter ( ( row ) => row . valid ) . length ;
253- return {
254- activeCount,
255- invalidCount : rows . length - activeCount ,
256- rows,
257- } ;
258- }
259-
260165async function readTailText (
261166 filePath : string ,
262167 maxBytes : number ,
@@ -1003,7 +908,13 @@ async function runLiveMode(
1003908 now ,
1004909 ) ;
1005910 const [ workspaceStatus , recentErrors ] = await Promise . all ( [
1006- loadWorkspaceStatusSummary ( ctx ) ,
911+ loadWorkspaceStatusSummary (
912+ ( ) => resolveWorkspaceRegistryStore ( ctx ) . load ( ) ,
913+ {
914+ loadWorkspaceConfigOverrides,
915+ readWorkspaceConfigWorkspaceId,
916+ } ,
917+ ) ,
1007918 loadRecentStatusErrors ( ctx ) ,
1008919 ] ) ;
1009920 const stale = isStatusSnapshotStale ( snapshot , now ) ;
@@ -1090,9 +1001,13 @@ export async function runStatusCommand(
10901001 const statusErrorCursorPath = resolveStatusErrorCursorPath (
10911002 ctx . runtime . runtimeDir ,
10921003 ) ;
1093- const workspaceStatus = asJson
1094- ? undefined
1095- : await loadWorkspaceStatusSummary ( ctx ) ;
1004+ const workspaceStatus = asJson ? undefined : await loadWorkspaceStatusSummary (
1005+ ( ) => resolveWorkspaceRegistryStore ( ctx ) . load ( ) ,
1006+ {
1007+ loadWorkspaceConfigOverrides,
1008+ readWorkspaceConfigWorkspaceId,
1009+ } ,
1010+ ) ;
10961011 const stale = isStatusSnapshotStale ( snapshot , now ) ;
10971012 const recentErrors = asJson ? undefined : await loadRecentStatusErrors ( ctx ) ;
10981013 const suppressedRecentErrorKeys = asJson
0 commit comments