@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/collect.mjs +16 -174
- package/cto/current.schema.json +4 -16
- package/cto/events.mjs +13 -294
- package/cto/hygiene.mjs +26 -346
- package/cto/lake-root.mjs +114 -16
- package/cto/status.mjs +31 -78
- package/hub/store-adapter.mjs +1 -1
- package/hub/team/conductor.mjs +1 -1
- package/hub/team/execution-mode.mjs +1 -1
- package/hub/team/headless.mjs +1 -1
- package/hub/team/psmux.mjs +16 -402
- package/hub/team/session.mjs +1 -28
- package/hub/team/terminal-opener.mjs +11 -35
- package/package.json +1 -1
- package/scripts/lib/gemini-profiles.mjs +1 -1
- package/scripts/lib/legacy-mcp-cleanup.mjs +14 -3
- package/scripts/lib/psmux-info.mjs +18 -49
- package/scripts/lib/skill-template.mjs +0 -26
- package/cto/hygiene-actions.mjs +0 -355
- package/cto/hygiene-notify.mjs +0 -170
- package/hub/workers/gemini-worker.mjs +0 -217
- package/scripts/lib/agent-json.mjs +0 -27
- package/scripts/lib/async.mjs +0 -174
- package/scripts/lib/cli-agy.mjs +0 -85
- package/scripts/lib/cli-codex.mjs +0 -62
- package/scripts/lib/cli-gemini.mjs +0 -37
- package/scripts/lib/env.mjs +0 -14
- package/scripts/lib/hub.mjs +0 -48
- package/scripts/lib/pid.mjs +0 -63
- package/scripts/lib/quota.mjs +0 -47
- package/scripts/lib/skill-state.mjs +0 -220
- package/scripts/lib/team.mjs +0 -75
- package/scripts/lib/timeout.mjs +0 -66
- package/scripts/lib/tmp.mjs +0 -26
- package/scripts/lib/toml.mjs +0 -132
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 {
|
|
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(
|
|
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 ||
|
|
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
|
|
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
|
}
|
package/hub/store-adapter.mjs
CHANGED
|
@@ -135,7 +135,7 @@ function attachAdaptiveRuleStore(store) {
|
|
|
135
135
|
return statements.pruneRules.run(cutoff, minConfidence).changes;
|
|
136
136
|
};
|
|
137
137
|
|
|
138
|
-
// listAdaptiveRules: decayRules
|
|
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
|
);
|
package/hub/team/conductor.mjs
CHANGED
|
@@ -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/
|
|
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/
|
|
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,
|
package/hub/team/headless.mjs
CHANGED
|
@@ -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/
|
|
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";
|