@triflux/remote 10.50.0 → 10.50.2

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/cto/status.mjs CHANGED
@@ -1,9 +1,14 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
- import { homedir } from "node:os";
3
2
  import { join } from "node:path";
4
3
 
5
4
  import { compactHygieneCounts, projectCtoHygiene } from "./hygiene.mjs";
6
- import { resolveLakeRootDir } from "./lake-root.mjs";
5
+ import {
6
+ normalizeLiveSession,
7
+ pathLabel,
8
+ readSynapseSnapshot,
9
+ resolveLakeRootDir,
10
+ shortHash,
11
+ } from "./lake-root.mjs";
7
12
 
8
13
  const SCHEMA_VERSION = "cto-lake.v1";
9
14
  const SYNAPSE_TIMEOUT_MS = 1500;
@@ -20,36 +25,6 @@ function readJson(filePath) {
20
25
  return JSON.parse(readFileSync(filePath, "utf8"));
21
26
  }
22
27
 
23
- function firstExisting(paths) {
24
- return paths.filter(Boolean).find((path) => existsSync(path)) || null;
25
- }
26
-
27
- function toIsoTime(value) {
28
- if (typeof value === "string" && value.trim()) return value;
29
- if (typeof value === "number" && Number.isFinite(value)) {
30
- return new Date(value).toISOString();
31
- }
32
- return null;
33
- }
34
-
35
- // Non-cryptographic djb2-style hash used only to produce stable redacted
36
- // labels for local paths. Do not use this as a trust boundary or secret token.
37
- function shortHash(value) {
38
- const str = String(value ?? "");
39
- let h = 5381;
40
- for (let i = 0; i < str.length; i++) {
41
- h = (h * 33) ^ str.charCodeAt(i);
42
- }
43
- return (h >>> 0).toString(36);
44
- }
45
-
46
- function pathLabel(value) {
47
- const str = String(value ?? "").replace(/[/\\]+$/u, "");
48
- if (!str) return "";
49
- const segments = str.split(/[/\\]+/u);
50
- return segments[segments.length - 1] || "";
51
- }
52
-
53
28
  export function deriveRepoRootFromCwd(cwd) {
54
29
  if (typeof cwd !== "string" || !cwd) return "";
55
30
  if (cwd.includes("\\") || /^[A-Za-z]:/u.test(cwd)) return cwd;
@@ -98,30 +73,6 @@ function redactedCwdFields(cwd) {
98
73
  };
99
74
  }
100
75
 
101
- function normalizeLiveSession(session) {
102
- const cwd = typeof session?.cwd === "string" ? session.cwd : "";
103
- return {
104
- sessionId: String(session?.sessionId || ""),
105
- host: typeof session?.host === "string" ? session.host : "local",
106
- agent_id:
107
- typeof session?.agent_id === "string"
108
- ? session.agent_id
109
- : typeof session?.agentId === "string"
110
- ? session.agentId
111
- : null,
112
- phase:
113
- typeof session?.phase === "string"
114
- ? session.phase
115
- : typeof session?.status === "string"
116
- ? session.status
117
- : "active",
118
- started_at: toIsoTime(
119
- session?.started_at ?? session?.startedAt ?? session?.lastHeartbeat,
120
- ),
121
- ...redactedCwdFields(cwd),
122
- };
123
- }
124
-
125
76
  function normalizeActiveShard(shard) {
126
77
  return {
127
78
  shard_name:
@@ -162,7 +113,11 @@ function normalizeSynapseOverlay(value) {
162
113
 
163
114
  return {
164
115
  live_sessions: sessions
165
- .map(normalizeLiveSession)
116
+ .map((session) => ({
117
+ ...normalizeLiveSession(session),
118
+ host: typeof session?.host === "string" ? session.host : "local",
119
+ ...redactedCwdFields(session?.cwd),
120
+ }))
166
121
  .filter((session) => session.sessionId),
167
122
  active_shards: activeShards.map(normalizeActiveShard),
168
123
  };
@@ -182,27 +137,9 @@ function withTimeout(promise, timeoutMs = SYNAPSE_TIMEOUT_MS) {
182
137
  });
183
138
  }
184
139
 
185
- async function readSynapseWithRegistry(opts = {}) {
186
- const rootDir = opts.rootDir || process.cwd();
187
- const persistPath = firstExisting([
188
- opts.synapsePersistPath,
189
- join(rootDir, ".triflux", "synapse-registry.json"),
190
- join(rootDir, ".triflux", "synapse", "registry.json"),
191
- join(homedir(), ".claude", "cache", "tfx-hub", "synapse-sessions.json"),
192
- join(homedir(), ".claude", "cache", "tfx-hub", "synapse-registry.json"),
193
- ]);
194
- if (!persistPath) return { sessions: [], active_shards: [] };
195
-
196
- const { createSynapseRegistry } = await import(
197
- "../hub/team/synapse-registry.mjs"
198
- );
199
- const registry = createSynapseRegistry({ persistPath });
200
- return { sessions: registry.getActive(), active_shards: [] };
201
- }
202
-
203
140
  async function readSynapseOverlay(opts) {
204
141
  try {
205
- const reader = opts.synapseReader || readSynapseWithRegistry;
142
+ const reader = opts.synapseReader || readSynapseSnapshot;
206
143
  const raw = await withTimeout(
207
144
  reader({
208
145
  rootDir: opts.rootDir,
@@ -300,13 +237,29 @@ function formatLedgerEntry(entry) {
300
237
  return `${ts} ${event}${summary}`;
301
238
  }
302
239
 
303
- function renderHumanStatus(status) {
240
+ function formatSnapshotAge(generatedAt, now) {
241
+ const ageMs = new Date(now).getTime() - Date.parse(generatedAt);
242
+ if (!Number.isFinite(ageMs)) return "unknown age";
243
+ if (ageMs < 0) return "in the future";
244
+ for (const [unit, ms] of [
245
+ ["d", 86400000],
246
+ ["h", 3600000],
247
+ ["m", 60000],
248
+ ["s", 1000],
249
+ ]) {
250
+ if (ageMs >= ms || unit === "s")
251
+ return `${Math.floor(ageMs / ms)}${unit} ago`;
252
+ }
253
+ }
254
+
255
+ function renderHumanStatus(status, now) {
304
256
  const { available, total } = countAvailableSources(status.sources);
305
257
  const activeGoals = countActiveGoals(status);
306
258
  const recent = Array.isArray(status.ledger_tail)
307
259
  ? status.ledger_tail.slice(-2)
308
260
  : [];
309
261
  const lines = [
262
+ `generated_at: ${status.generated_at || "unknown"} (${formatSnapshotAge(status.generated_at, now)})`,
310
263
  `repo: ${formatRepo(status.repo)}`,
311
264
  `sources: ${available}/${total} available`,
312
265
  `active: ${status.live_sessions.length} sessions, ${status.active_shards.length} shards, ${activeGoals} goals`,
@@ -347,7 +300,7 @@ export async function runStatus(args = [], opts = {}) {
347
300
  const status = projectStatus(current, overlay);
348
301
 
349
302
  if (jsonOut) writeJson(stdout, status);
350
- else stdout.write(renderHumanStatus(status));
303
+ else stdout.write(renderHumanStatus(status, opts.now ?? Date.now()));
351
304
 
352
305
  return status;
353
306
  }
@@ -135,7 +135,7 @@ function attachAdaptiveRuleStore(store) {
135
135
  return statements.pruneRules.run(cutoff, minConfidence).changes;
136
136
  };
137
137
 
138
- // listAdaptiveRules: decayRules/getActiveAdaptiveRules에서 사용
138
+ // listAdaptiveRules: decayRules에서 사용
139
139
  const listStmt = store.db.prepare(
140
140
  "SELECT * FROM adaptive_rules WHERE project_slug = ? ORDER BY confidence DESC",
141
141
  );
@@ -19,7 +19,7 @@ import {
19
19
  import { homedir } from "node:os";
20
20
  import { dirname, join } from "node:path";
21
21
  import { createRegistry } from "@triflux/core/mesh/mesh-registry.mjs";
22
- import { resolveNestedCodexAgentProfile } from "../../scripts/lib/cli-codex.mjs";
22
+ import { resolveNestedCodexAgentProfile } from "../../scripts/lib/agent-route-policy.mjs";
23
23
  import { codexProfileConfigOverrides } from "../../scripts/lib/codex-profile-config.mjs";
24
24
  import {
25
25
  buildDisabledCliError,
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { dirname, resolve as pathResolve } from "node:path";
5
- import { resolveNestedCodexAgentProfile } from "../../scripts/lib/cli-codex.mjs";
5
+ import { resolveNestedCodexAgentProfile } from "../../scripts/lib/agent-route-policy.mjs";
6
6
  import { codexProfileConfigOverrides } from "../../scripts/lib/codex-profile-config.mjs";
7
7
  import {
8
8
  resolveGeminiModel,
@@ -20,7 +20,7 @@ import net from "node:net";
20
20
  import { tmpdir } from "node:os";
21
21
  import { dirname, join, resolve } from "node:path";
22
22
  import { fileURLToPath } from "node:url";
23
- import { resolveNestedCodexAgentProfile } from "../../scripts/lib/cli-codex.mjs";
23
+ import { resolveNestedCodexAgentProfile } from "../../scripts/lib/agent-route-policy.mjs";
24
24
  import { requestJson } from "@triflux/core/hub/bridge.mjs";
25
25
  import { escapePwshSingleQuoted } from "@triflux/core/hub/cli-adapter-base.mjs";
26
26
  import { getMaxSpawnPerSec } from "@triflux/core/hub/lib/spawn-trace.mjs";