@triflux/remote 10.51.0 → 10.53.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 (62) hide show
  1. package/cto/brief.mjs +0 -8
  2. package/cto/collect.mjs +1 -127
  3. package/cto/current.schema.json +2 -19
  4. package/cto/hygiene.mjs +2 -61
  5. package/cto/lake-root.mjs +0 -56
  6. package/cto/status.mjs +5 -139
  7. package/hub/index.mjs +0 -9
  8. package/hub/team/agents-row-attach.py +120 -0
  9. package/hub/team/agents-row.mjs +200 -0
  10. package/hub/team/claude-daemon-control.mjs +1 -2
  11. package/hub/team/claude-session-projection.mjs +5 -73
  12. package/hub/team/claude-transcript.mjs +19 -0
  13. package/hub/team/cli/commands/debug.mjs +1 -2
  14. package/hub/team/cli/commands/start/index.mjs +2 -1
  15. package/hub/team/cli/commands/start/start-headless.mjs +2 -0
  16. package/hub/team/cli/commands/start/start-mux.mjs +2 -4
  17. package/hub/team/cli/services/state-store.mjs +5 -20
  18. package/hub/team/headless.mjs +132 -551
  19. package/hub/team/psmux.mjs +3 -33
  20. package/hub/team/results-index.mjs +92 -0
  21. package/hub/team/session-context.mjs +1 -1
  22. package/hub/team/tui-viewer.mjs +9 -56
  23. package/hub/team/tui.mjs +0 -37
  24. package/hub/team/uds-orchestrator.mjs +20 -599
  25. package/hub/workers/factory.mjs +6 -51
  26. package/hub/workers/interface.mjs +1 -7
  27. package/hub/workers/lib/jsonrpc-core.mjs +11 -0
  28. package/hub/workers/lib/jsonrpc-ws-uds.mjs +5 -6
  29. package/package.json +3 -8
  30. package/scripts/lib/agent-route-policy.mjs +0 -67
  31. package/scripts/lib/cli-claude.mjs +0 -12
  32. package/scripts/lib/env-probe.mjs +0 -70
  33. package/scripts/lib/legacy-mcp-cleanup.mjs +283 -0
  34. package/scripts/lib/mcp-guard-engine.mjs +42 -101
  35. package/hub/hub-lifecycle.mjs +0 -248
  36. package/hub/pipe.mjs +0 -825
  37. package/hub/promote-penalties.mjs +0 -138
  38. package/hub/public/dashboard.html +0 -416
  39. package/hub/schema.sql +0 -209
  40. package/hub/server.mjs +0 -3048
  41. package/hub/store-adapter.mjs +0 -182
  42. package/hub/store.mjs +0 -1736
  43. package/hub/team/cli/services/hub-client.mjs +0 -178
  44. package/hub/team/conductor-registry.mjs +0 -121
  45. package/hub/team/cto-auto-collect.mjs +0 -115
  46. package/hub/team/lead-control.mjs +0 -191
  47. package/hub/team/session-sync.mjs +0 -316
  48. package/hub/team/swarm-intent.mjs +0 -18
  49. package/hub/team/synapse-cli.mjs +0 -458
  50. package/hub/team/synapse-http.mjs +0 -311
  51. package/hub/team/synapse-registry.mjs +0 -618
  52. package/hub/team/tui-synapse.mjs +0 -223
  53. package/hub/team/worker-sandbox.mjs +0 -125
  54. package/hub/tools.mjs +0 -900
  55. package/hub/workers/codex-app-server-worker.mjs +0 -1067
  56. package/hub/workers/delegator-mcp.mjs +0 -1098
  57. package/hub/workers/lib/jsonrpc-stdio.mjs +0 -204
  58. package/scripts/lib/claudemd-scanner.mjs +0 -26
  59. package/scripts/lib/context.mjs +0 -51
  60. package/scripts/lib/handoff.mjs +0 -187
  61. package/scripts/lib/logger.mjs +0 -122
  62. package/scripts/lib/stealth-fetch.mjs +0 -176
package/cto/brief.mjs CHANGED
@@ -12,11 +12,6 @@ function oneLine(value, fallback = "n/a") {
12
12
  return String(text).replace(/\s+/g, " ").trim() || fallback;
13
13
  }
14
14
 
15
- function compactDetail(value) {
16
- const text = oneLine(value);
17
- return text.length > 140 ? `${text.slice(0, 137)}...` : text;
18
- }
19
-
20
15
  function formatGoal(goal) {
21
16
  const id = oneLine(goal?.id, "goal");
22
17
  const status = oneLine(goal?.status, "unknown");
@@ -50,7 +45,6 @@ function enforceCap(text) {
50
45
  export function renderBrief(current) {
51
46
  const repo = current?.repo || {};
52
47
  const summary = current?.summary || {};
53
- const hub = current?.sources?.tfx_hub || {};
54
48
  const activeGoals = Array.isArray(summary.active_goals)
55
49
  ? summary.active_goals.slice(0, 3)
56
50
  : [];
@@ -65,8 +59,6 @@ export function renderBrief(current) {
65
59
  `summary: ${oneLine(summary.repo_state, "no repo summary")}`,
66
60
  "active_goals",
67
61
  ...(activeGoals.length > 0 ? activeGoals.map(formatGoal) : ["- none"]),
68
- "hub_status",
69
- `status: ${oneLine(hub.status, "unknown")} available: ${hub.available === true} detail: ${compactDetail(hub.detail)}`,
70
62
  "recent_events",
71
63
  ...(recentEvents.length > 0 ? recentEvents.map(formatEvent) : ["- none"]),
72
64
  "generated_at",
package/cto/collect.mjs CHANGED
@@ -6,14 +6,12 @@ import {
6
6
  readFileSync,
7
7
  statSync,
8
8
  } from "node:fs";
9
- import { homedir } from "node:os";
10
9
  import { join, relative } from "node:path";
11
10
  import { fileURLToPath } from "node:url";
12
11
 
13
12
  import { renderBrief } from "./brief.mjs";
14
13
  import { appendCtoEvent } from "./events.mjs";
15
14
  import {
16
- firstExisting,
17
15
  readJsonLines,
18
16
  resolveLakeRootDir,
19
17
  writeAtomic,
@@ -27,24 +25,6 @@ const SOURCE_REGISTRY = [
27
25
  probe: "git rev-parse, git branch, git status",
28
26
  enabled: true,
29
27
  },
30
- {
31
- id: "tfx_hub",
32
- kind: "triflux-runtime-artifact",
33
- probe: ".triflux/hub/status.json or host tfx-hub cache",
34
- enabled: true,
35
- },
36
- {
37
- id: "tfx_team",
38
- kind: "triflux-runtime-artifact",
39
- probe: ".triflux/team-state.json or host tfx-hub team cache",
40
- enabled: true,
41
- },
42
- {
43
- id: "tfx_synapse",
44
- kind: "triflux-runtime-artifact",
45
- probe: ".triflux/synapse registry or host tfx-hub synapse cache",
46
- enabled: true,
47
- },
48
28
  {
49
29
  id: "ultragoal_omx",
50
30
  kind: "durable-goal-artifact",
@@ -121,14 +101,6 @@ function listDirFiles(dirPath, rootDir, limit = 10) {
121
101
  }
122
102
  }
123
103
 
124
- function safeSummary(value) {
125
- if (value === null || value === undefined) return null;
126
- if (Array.isArray(value)) return { type: "array", count: value.length };
127
- if (typeof value === "object")
128
- return { type: "object", keys: Object.keys(value).slice(0, 20) };
129
- return String(value).slice(0, 200);
130
- }
131
-
132
104
  function execGit(args, rootDir, execFileSyncFn) {
133
105
  return execFileSyncFn("git", args, {
134
106
  cwd: rootDir,
@@ -183,45 +155,6 @@ function collectGit(rootDir, collectedAt, execFileSyncFn) {
183
155
  }
184
156
  }
185
157
 
186
- function collectJsonArtifact(
187
- id,
188
- candidates,
189
- rootDir,
190
- collectedAt,
191
- summarize = safeSummary,
192
- ) {
193
- const filePath = firstExisting(candidates);
194
- if (!filePath) {
195
- return missingSource(
196
- "no_shell_readable_artifact",
197
- "no durable artifact found",
198
- collectedAt,
199
- );
200
- }
201
- try {
202
- const parsed = readJson(filePath);
203
- return sourceState(
204
- true,
205
- "ok",
206
- {
207
- path: relPath(rootDir, filePath),
208
- summary: summarize(parsed),
209
- },
210
- collectedAt,
211
- );
212
- } catch (error) {
213
- return sourceState(
214
- true,
215
- "read_error",
216
- {
217
- path: relPath(rootDir, filePath),
218
- error: error?.message || `${id} artifact read failed`,
219
- },
220
- collectedAt,
221
- );
222
- }
223
- }
224
-
225
158
  function normalizeGoals(parsed) {
226
159
  const rawGoals = Array.isArray(parsed?.goals)
227
160
  ? parsed.goals
@@ -329,7 +262,6 @@ function buildSummary(current) {
329
262
  return {
330
263
  repo_state: `branch ${repo.branch || "unknown"} at ${repo.head || "unknown"} is ${repo.dirty ? "dirty" : "clean"}`,
331
264
  active_goals: [...omxGoals, ...omcGoals].slice(0, 5),
332
- hub_status: current.sources.tfx_hub.status,
333
265
  available_sources: availableSources,
334
266
  missing_sources: SOURCE_IDS.length - availableSources,
335
267
  };
@@ -467,67 +399,10 @@ function validateCurrent(current) {
467
399
  }
468
400
  }
469
401
 
470
- function collectSources(rootDir, collectedAt, execFileSyncFn, opts = {}) {
471
- const home = homedir();
472
- const hostArtifactCandidates =
473
- opts.includeHostArtifacts === false
474
- ? {
475
- hub: [],
476
- team: [],
477
- synapse: [],
478
- }
479
- : {
480
- hub: [
481
- join(home, ".claude", "cache", "tfx-hub", "hub.pid"),
482
- join(home, ".claude", "cache", "tfx-hub", "hub-state.json"),
483
- ],
484
- team: [
485
- join(
486
- home,
487
- ".claude",
488
- "cache",
489
- "tfx-hub",
490
- `team-state-${process.env.CLAUDE_SESSION_ID || ""}.json`,
491
- ),
492
- join(home, ".claude", "cache", "tfx-hub", "team-state.json"),
493
- ],
494
- synapse: [
495
- join(home, ".claude", "cache", "tfx-hub", "synapse-registry.json"),
496
- join(home, ".claude", "cache", "tfx-hub", "synapse-sessions.json"),
497
- ],
498
- };
402
+ function collectSources(rootDir, collectedAt, execFileSyncFn) {
499
403
  const git = collectGit(rootDir, collectedAt, execFileSyncFn);
500
404
  const sources = {
501
405
  git: git.source,
502
- tfx_hub: collectJsonArtifact(
503
- "tfx_hub",
504
- [
505
- join(rootDir, ".triflux", "hub", "status.json"),
506
- join(rootDir, ".triflux", "hub-state.json"),
507
- ...hostArtifactCandidates.hub,
508
- ],
509
- rootDir,
510
- collectedAt,
511
- ),
512
- tfx_team: collectJsonArtifact(
513
- "tfx_team",
514
- [
515
- join(rootDir, ".triflux", "team-state.json"),
516
- ...hostArtifactCandidates.team,
517
- ],
518
- rootDir,
519
- collectedAt,
520
- ),
521
- tfx_synapse: collectJsonArtifact(
522
- "tfx_synapse",
523
- [
524
- join(rootDir, ".triflux", "synapse-registry.json"),
525
- join(rootDir, ".triflux", "synapse", "registry.json"),
526
- ...hostArtifactCandidates.synapse,
527
- ],
528
- rootDir,
529
- collectedAt,
530
- ),
531
406
  ultragoal_omx: collectUltragoal(
532
407
  join(rootDir, ".omx", "ultragoal"),
533
408
  rootDir,
@@ -568,7 +443,6 @@ export async function runCollect(args = [], opts = {}) {
568
443
  rootDir,
569
444
  generatedAt,
570
445
  execFileSyncFn,
571
- opts,
572
446
  );
573
447
  const current = {
574
448
  schema_version: SCHEMA_VERSION,
@@ -46,28 +46,11 @@
46
46
  "type": "object",
47
47
  "description": "Durable artifact source states only. A source reports available:false when no shell-readable durable artifact exists.",
48
48
  "additionalProperties": false,
49
- "required": [
50
- "git",
51
- "tfx_hub",
52
- "tfx_team",
53
- "tfx_synapse",
54
- "ultragoal_omx",
55
- "ultragoal_omc",
56
- "handoffs"
57
- ],
49
+ "required": ["git", "ultragoal_omx", "ultragoal_omc", "handoffs"],
58
50
  "properties": {
59
51
  "git": {
60
52
  "$ref": "#/$defs/sourceState"
61
53
  },
62
- "tfx_hub": {
63
- "$ref": "#/$defs/sourceState"
64
- },
65
- "tfx_team": {
66
- "$ref": "#/$defs/sourceState"
67
- },
68
- "tfx_synapse": {
69
- "$ref": "#/$defs/sourceState"
70
- },
71
54
  "ultragoal_omx": {
72
55
  "$ref": "#/$defs/sourceState"
73
56
  },
@@ -81,7 +64,7 @@
81
64
  },
82
65
  "summary": {
83
66
  "type": "object",
84
- "description": "Human-oriented synthesized authority summary derived from durable artifacts and live Triflux synapse session status. Phase 1 may add source-derived fields here without changing the top-level contract.",
67
+ "description": "Human-oriented synthesized authority summary derived from durable artifacts. Phase 1 may add source-derived fields here without changing the top-level contract.",
85
68
  "additionalProperties": true
86
69
  },
87
70
  "ledger_tail": {
package/cto/hygiene.mjs CHANGED
@@ -1,11 +1,6 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import {
4
- normalizeLiveSession,
5
- readJsonLines,
6
- readSynapseSnapshot,
7
- resolveLakeRootDir,
8
- } from "./lake-root.mjs";
3
+ import { readJsonLines, resolveLakeRootDir } from "./lake-root.mjs";
9
4
 
10
5
  const COUNT_KEYS = [
11
6
  "active_tasks",
@@ -28,37 +23,6 @@ function readJson(filePath) {
28
23
  return JSON.parse(readFileSync(filePath, "utf8"));
29
24
  }
30
25
 
31
- function normalizeOverlay(value) {
32
- const sessions = Array.isArray(value)
33
- ? value
34
- : Array.isArray(value?.sessions)
35
- ? value.sessions
36
- : Array.isArray(value?.live_sessions)
37
- ? value.live_sessions
38
- : [];
39
- return {
40
- live_sessions: sessions
41
- .map(normalizeLiveSession)
42
- .filter((session) => session.sessionId),
43
- };
44
- }
45
-
46
- async function readLiveOverlay(opts = {}) {
47
- if (opts.overlay) return normalizeOverlay(opts.overlay);
48
- try {
49
- const reader = opts.synapseReader || readSynapseSnapshot;
50
- return normalizeOverlay(
51
- await reader({
52
- rootDir: opts.rootDir,
53
- lakeRoot: opts.lakeRoot,
54
- synapsePersistPath: opts.synapsePersistPath,
55
- }),
56
- );
57
- } catch {
58
- return { live_sessions: [] };
59
- }
60
- }
61
-
62
26
  function eventTime(entry) {
63
27
  return typeof entry?.ts === "string" ? entry.ts : "";
64
28
  }
@@ -157,11 +121,7 @@ export function compactHygieneCounts(projection) {
157
121
  return Object.fromEntries(COUNT_KEYS.map((key) => [key, counts[key] || 0]));
158
122
  }
159
123
 
160
- export function projectCtoHygiene({
161
- current = {},
162
- ledger = null,
163
- overlay = {},
164
- } = {}) {
124
+ export function projectCtoHygiene({ current = {}, ledger = null } = {}) {
165
125
  const events = Array.isArray(ledger)
166
126
  ? ledger
167
127
  : Array.isArray(current?.ledger_tail)
@@ -270,23 +230,6 @@ export function projectCtoHygiene({
270
230
  );
271
231
  }
272
232
 
273
- for (const session of overlay?.live_sessions || []) {
274
- const phase = String(session?.phase || session?.status || "").toLowerCase();
275
- if (phase !== "stale") continue;
276
- const sessionId = String(
277
- session?.sessionId || session?.session_id || "",
278
- ).trim();
279
- if (!sessionId || staleSessions.has(sessionId)) continue;
280
- rows.push({
281
- kind: "session",
282
- id: sessionId,
283
- status: "stale",
284
- last_event_at: session?.started_at || null,
285
- action: "archive_or_resume_session",
286
- owner: session?.agent_id ? undefined : "unknown",
287
- });
288
- }
289
-
290
233
  for (const [key, item] of worktrees) {
291
234
  if (item.entry?.event === "worktree_removed") continue;
292
235
  const status = statusOf(item.ref, "active");
@@ -363,11 +306,9 @@ export async function runHygiene(args = [], opts = {}) {
363
306
  const currentPath = join(lakeRoot, "current.json");
364
307
  const current = existsSync(currentPath) ? readJson(currentPath) : {};
365
308
  const ledger = readJsonLines(join(lakeRoot, "ledger.jsonl"));
366
- const overlay = await readLiveOverlay({ ...opts, rootDir, lakeRoot });
367
309
  const projection = projectCtoHygiene({
368
310
  current,
369
311
  ledger: ledger.length ? ledger : null,
370
- overlay,
371
312
  });
372
313
  if (opts.json === true || hasFlag(args, "--json"))
373
314
  writeJson(stdout, projection);
package/cto/lake-root.mjs CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  renameSync,
7
7
  writeFileSync,
8
8
  } from "node:fs";
9
- import { homedir } from "node:os";
10
9
  import { basename, dirname, join, parse } from "node:path";
11
10
 
12
11
  const MAX_DEPTH = 64;
@@ -77,10 +76,6 @@ export function resolveLakeRootDir(cwd, opts = {}) {
77
76
  return cwd;
78
77
  }
79
78
 
80
- export function firstExisting(paths) {
81
- return paths.filter(Boolean).find((path) => defaultExistsSync(path)) || null;
82
- }
83
-
84
79
  export function toIsoTime(value) {
85
80
  if (typeof value === "string" && value.trim()) return value;
86
81
  if (value instanceof Date) return value.toISOString();
@@ -106,57 +101,6 @@ export function pathLabel(value) {
106
101
  return segments[segments.length - 1] || "";
107
102
  }
108
103
 
109
- export function normalizeLiveSession(session) {
110
- return {
111
- sessionId: String(session?.sessionId || session?.session_id || ""),
112
- agent_id:
113
- typeof session?.agent_id === "string"
114
- ? session.agent_id
115
- : typeof session?.agentId === "string"
116
- ? session.agentId
117
- : null,
118
- phase:
119
- typeof session?.phase === "string"
120
- ? session.phase
121
- : typeof session?.status === "string"
122
- ? session.status
123
- : "active",
124
- started_at: toIsoTime(
125
- session?.started_at ?? session?.startedAt ?? session?.lastHeartbeat,
126
- ),
127
- };
128
- }
129
-
130
- export async function readSynapseSnapshot(opts = {}) {
131
- const rootDir = opts.rootDir || process.cwd();
132
- const persistPath = firstExisting([
133
- opts.synapsePersistPath,
134
- join(rootDir, ".triflux", "synapse-registry.json"),
135
- join(rootDir, ".triflux", "synapse", "registry.json"),
136
- join(homedir(), ".claude", "cache", "tfx-hub", "synapse-sessions.json"),
137
- join(homedir(), ".claude", "cache", "tfx-hub", "synapse-registry.json"),
138
- ]);
139
- if (!persistPath) return { sessions: [], active_shards: [] };
140
- const data = JSON.parse(readFileSync(persistPath, "utf8"));
141
- // 상태 전이는 hub 소유이며 조회는 저장된 live 상태만 읽는다.
142
- const sessions = Object.entries(data).flatMap(([key, session]) => {
143
- const sessionId = String(session?.sessionId ?? key).trim();
144
- if (!sessionId || ["stale", "expired"].includes(session?.status)) return [];
145
- return [
146
- {
147
- ...session,
148
- sessionId,
149
- status: session?.status === "idle" ? "idle" : "active",
150
- lastHeartbeat:
151
- typeof session?.lastHeartbeat === "number"
152
- ? session.lastHeartbeat
153
- : Date.now(),
154
- },
155
- ];
156
- });
157
- return { sessions, active_shards: [] };
158
- }
159
-
160
104
  export function readJsonLines(filePath, limit = Infinity) {
161
105
  if (!defaultExistsSync(filePath)) return [];
162
106
  const lines = readFileSync(filePath, "utf8")
package/cto/status.mjs CHANGED
@@ -2,16 +2,9 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
4
  import { compactHygieneCounts, projectCtoHygiene } from "./hygiene.mjs";
5
- import {
6
- normalizeLiveSession,
7
- pathLabel,
8
- readSynapseSnapshot,
9
- resolveLakeRootDir,
10
- shortHash,
11
- } from "./lake-root.mjs";
5
+ import { resolveLakeRootDir } from "./lake-root.mjs";
12
6
 
13
7
  const SCHEMA_VERSION = "cto-lake.v1";
14
- const SYNAPSE_TIMEOUT_MS = 1500;
15
8
 
16
9
  function hasFlag(args, flag) {
17
10
  return Array.isArray(args) && args.includes(flag);
@@ -25,126 +18,7 @@ function readJson(filePath) {
25
18
  return JSON.parse(readFileSync(filePath, "utf8"));
26
19
  }
27
20
 
28
- export function deriveRepoRootFromCwd(cwd) {
29
- if (typeof cwd !== "string" || !cwd) return "";
30
- if (cwd.includes("\\") || /^[A-Za-z]:/u.test(cwd)) return cwd;
31
-
32
- const normalized = cwd.replace(/\/+$/u, "");
33
- const gitWorktreeMarker = "/.worktrees/";
34
- const gitWorktreeIndex = normalized.indexOf(gitWorktreeMarker);
35
- if (gitWorktreeIndex > 0) {
36
- const suffix = normalized.slice(
37
- gitWorktreeIndex + gitWorktreeMarker.length,
38
- );
39
- if (/^[^/]+(?:\/|$)/u.test(suffix)) {
40
- return normalized.slice(0, gitWorktreeIndex);
41
- }
42
- }
43
-
44
- const claudeMarker = "/.claude/worktrees/";
45
- const claudeIndex = normalized.indexOf(claudeMarker);
46
- if (claudeIndex > 0) {
47
- const suffix = normalized.slice(claudeIndex + claudeMarker.length);
48
- if (/^[^/]+(?:\/|$)/u.test(suffix)) {
49
- return normalized.slice(0, claudeIndex);
50
- }
51
- }
52
-
53
- const codexMarker = "/.codex-swarm/";
54
- const codexIndex = normalized.indexOf(codexMarker);
55
- if (codexIndex > 0) {
56
- const suffix = normalized.slice(codexIndex + codexMarker.length);
57
- if (/^wt-[^/]+(?:\/|$)/u.test(suffix)) {
58
- return normalized.slice(0, codexIndex);
59
- }
60
- }
61
-
62
- return cwd;
63
- }
64
-
65
- function redactedCwdFields(cwd) {
66
- if (typeof cwd !== "string" || !cwd) return {};
67
- const repoRoot = deriveRepoRootFromCwd(cwd);
68
- return {
69
- cwdLabel: pathLabel(cwd),
70
- cwdHash: shortHash(cwd),
71
- repoRootLabel: pathLabel(repoRoot),
72
- repoRootHash: shortHash(repoRoot),
73
- };
74
- }
75
-
76
- function normalizeSynapseOverlay(value) {
77
- const sessions = Array.isArray(value)
78
- ? value
79
- : Array.isArray(value?.sessions)
80
- ? value.sessions
81
- : Array.isArray(value?.live_sessions)
82
- ? value.live_sessions
83
- : [];
84
-
85
- return {
86
- live_sessions: sessions
87
- .map((session) => ({
88
- ...normalizeLiveSession(session),
89
- host: typeof session?.host === "string" ? session.host : "local",
90
- ...redactedCwdFields(session?.cwd),
91
- }))
92
- .filter((session) => session.sessionId),
93
- };
94
- }
95
-
96
- function withTimeout(promise, timeoutMs = SYNAPSE_TIMEOUT_MS) {
97
- let timer = null;
98
- const timeout = new Promise((_, reject) => {
99
- timer = setTimeout(
100
- () => reject(new Error("synapse read timeout")),
101
- timeoutMs,
102
- );
103
- if (typeof timer.unref === "function") timer.unref();
104
- });
105
- return Promise.race([Promise.resolve(promise), timeout]).finally(() => {
106
- if (timer) clearTimeout(timer);
107
- });
108
- }
109
-
110
- async function readSynapseOverlay(opts) {
111
- try {
112
- const reader = opts.synapseReader || readSynapseSnapshot;
113
- const raw = await withTimeout(
114
- reader({
115
- rootDir: opts.rootDir,
116
- lakeRoot: opts.lakeRoot,
117
- synapsePersistPath: opts.synapsePersistPath,
118
- }),
119
- opts.synapseTimeoutMs || SYNAPSE_TIMEOUT_MS,
120
- );
121
- return normalizeSynapseOverlay(raw);
122
- } catch {
123
- return { live_sessions: [] };
124
- }
125
- }
126
-
127
- function deriveLiveSessionGroups(liveSessions) {
128
- const groups = new Map();
129
- for (const session of liveSessions || []) {
130
- if (!session?.repoRootHash) continue;
131
- if (!groups.has(session.repoRootHash)) {
132
- groups.set(session.repoRootHash, {
133
- repoRootLabel: session.repoRootLabel || "",
134
- repoRootHash: session.repoRootHash,
135
- session_count: 0,
136
- sessions: [],
137
- });
138
- }
139
- const group = groups.get(session.repoRootHash);
140
- group.session_count += 1;
141
- group.sessions.push(session.sessionId);
142
- }
143
- return [...groups.values()];
144
- }
145
-
146
- function projectStatus(current, overlay) {
147
- const liveSessions = overlay.live_sessions;
21
+ function projectStatus(current) {
148
22
  return {
149
23
  schema_version: current?.schema_version || SCHEMA_VERSION,
150
24
  generated_at: current?.generated_at || null,
@@ -152,10 +26,7 @@ function projectStatus(current, overlay) {
152
26
  sources: current?.sources || {},
153
27
  summary: current?.summary || {},
154
28
  ledger_tail: Array.isArray(current?.ledger_tail) ? current.ledger_tail : [],
155
- live_sessions: liveSessions,
156
- live_session_groups: deriveLiveSessionGroups(liveSessions),
157
- active_shards: [],
158
- hygiene: compactHygieneCounts(projectCtoHygiene({ current, overlay })),
29
+ hygiene: compactHygieneCounts(projectCtoHygiene({ current })),
159
30
  };
160
31
  }
161
32
 
@@ -214,7 +85,7 @@ function renderHumanStatus(status, now) {
214
85
  `generated_at: ${status.generated_at || "unknown"} (${formatSnapshotAge(status.generated_at, now)})`,
215
86
  `repo: ${formatRepo(status.repo)}`,
216
87
  `sources: ${available}/${total} available`,
217
- `active: ${status.live_sessions.length} sessions, ${status.active_shards.length} shards, ${activeGoals} goals`,
88
+ `active: ${activeGoals} goals`,
218
89
  ];
219
90
  if (recent.length) {
220
91
  lines.push("ledger:");
@@ -244,12 +115,7 @@ export async function runStatus(args = [], opts = {}) {
244
115
  }
245
116
 
246
117
  const current = readJson(currentPath);
247
- const overlay = await readSynapseOverlay({
248
- ...opts,
249
- rootDir,
250
- lakeRoot,
251
- });
252
- const status = projectStatus(current, overlay);
118
+ const status = projectStatus(current);
253
119
 
254
120
  if (jsonOut) writeJson(stdout, status);
255
121
  else stdout.write(renderHumanStatus(status, opts.now ?? Date.now()));
package/hub/index.mjs CHANGED
@@ -1,13 +1,4 @@
1
1
  // @triflux/remote — barrel export (auto-generated by pack.mjs)
2
- // Server
3
- export { startHub, getHubInfo, getOrCreateServer } from './server.mjs';
4
-
5
- // Store
6
- export { createStoreAdapter } from './store-adapter.mjs';
7
-
8
- // Pipe
9
- export { createPipeServer, getPipePath } from './pipe.mjs';
10
-
11
2
  // Team
12
3
  export { orchestrate, decomposeTask, buildLeadPrompt, buildPrompt } from './team/orchestrator.mjs';
13
4
  export { createPsmuxSession, startCapture } from './team/psmux.mjs';