harnery 0.37.0 → 0.38.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.
- package/dist/commander.d.ts +9 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +7 -2
- package/dist/commands/admission.d.ts +21 -0
- package/dist/commands/admission.d.ts.map +1 -0
- package/dist/commands/admission.js +565 -0
- package/dist/commands/agents.d.ts +7 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +61 -1
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +48 -2
- package/dist/commands/browse-ai.d.ts +2 -2
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +6 -4
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +349 -21
- package/dist/commands/fetch.js +1 -0
- package/dist/commands/qa-record.d.ts +144 -0
- package/dist/commands/qa-record.d.ts.map +1 -0
- package/dist/commands/qa-record.js +0 -0
- package/dist/commands/qa-run.d.ts +7 -3
- package/dist/commands/qa-run.d.ts.map +1 -1
- package/dist/commands/qa-run.js +268 -13
- package/dist/commands/qa-status.d.ts +71 -0
- package/dist/commands/qa-status.d.ts.map +1 -0
- package/dist/commands/qa-status.js +490 -0
- package/dist/commands/qa-verify.d.ts +40 -0
- package/dist/commands/qa-verify.d.ts.map +1 -0
- package/dist/commands/qa-verify.js +180 -0
- package/dist/commands/review-pack.d.ts +4 -0
- package/dist/commands/review-pack.d.ts.map +1 -0
- package/dist/commands/review-pack.js +1001 -0
- package/dist/core/agents/qa-signal.d.ts +111 -0
- package/dist/core/agents/qa-signal.d.ts.map +1 -0
- package/dist/core/agents/qa-signal.js +231 -0
- package/dist/core/agents/session-name-display.d.ts +20 -5
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +67 -7
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +11 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +17 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +5 -0
- package/dist/core/artifacts/constants.d.ts +1 -1
- package/dist/core/artifacts/constants.js +1 -1
- package/dist/core/artifacts/index.d.ts +57 -6
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +265 -10
- package/dist/core/config.d.ts +8 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +16 -0
- package/dist/core/diagnostics/bundle.d.ts +16 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +101 -7
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +10 -0
- package/dist/core/events/v3/coordination-view.d.ts +3 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +69 -8
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +9 -2
- package/dist/core/events/v3/producers/recorder.d.ts +23 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +264 -18
- package/dist/core/hooks/cli.js +120 -27
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +10 -3
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +4 -1
- package/dist/core/qa-artifacts.d.ts +20 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -0
- package/dist/core/qa-artifacts.js +110 -0
- package/dist/core/resources/contract.d.ts +6 -0
- package/dist/core/resources/contract.d.ts.map +1 -1
- package/dist/core/resources/sampler.d.ts +7 -0
- package/dist/core/resources/sampler.d.ts.map +1 -1
- package/dist/core/resources/sampler.js +106 -5
- package/dist/lib/admission.d.ts +71 -0
- package/dist/lib/admission.d.ts.map +1 -0
- package/dist/lib/admission.js +264 -0
- package/dist/lib/agent-browser/client.d.ts +1 -1
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +1 -5
- package/dist/lib/browser/capture-fidelity.d.ts +39 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -0
- package/dist/lib/browser/capture-fidelity.js +84 -0
- package/dist/lib/browser/client.d.ts +41 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +167 -9
- package/dist/lib/browser/critique.d.ts +38 -1
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +34 -6
- package/dist/lib/browser/index.d.ts +4 -2
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/browser/page-review-judge.d.ts +64 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -0
- package/dist/lib/browser/page-review-judge.js +270 -0
- package/dist/lib/browser/page-review-pack.d.ts +613 -0
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -0
- package/dist/lib/browser/page-review-pack.js +1751 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +214 -10
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run-contracts.js +136 -1
- package/dist/lib/browser/qa-run.d.ts +100 -10
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +768 -169
- package/dist/lib/browser/request-diagnostics.d.ts +13 -0
- package/dist/lib/browser/request-diagnostics.d.ts.map +1 -0
- package/dist/lib/browser/request-diagnostics.js +18 -0
- package/dist/lib/browser/tiling.d.ts +19 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +28 -0
- package/dist/lib/cookies/client.d.ts +9 -0
- package/dist/lib/cookies/client.d.ts.map +1 -1
- package/dist/lib/cookies/client.js +197 -44
- package/dist/lib/cookies/extra.d.ts +18 -0
- package/dist/lib/cookies/extra.d.ts.map +1 -0
- package/dist/lib/cookies/extra.js +14 -0
- package/dist/lib/cookies/index.d.ts +2 -1
- package/dist/lib/cookies/index.d.ts.map +1 -1
- package/dist/lib/cookies/index.js +2 -1
- package/dist/lib/durable-job.d.ts +124 -0
- package/dist/lib/durable-job.d.ts.map +1 -0
- package/dist/lib/durable-job.js +296 -0
- package/dist/lib/http/client.d.ts +7 -1
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +2 -0
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +5 -2
- package/package.json +8 -2
- package/src/commander.ts +50 -2
- package/src/commands/admission.ts +699 -0
- package/src/commands/agents.ts +87 -1
- package/src/commands/artifacts.ts +97 -21
- package/src/commands/browse-ai.ts +10 -5
- package/src/commands/browse.ts +481 -20
- package/src/commands/fetch.ts +1 -0
- package/src/commands/qa-record.ts +682 -0
- package/src/commands/qa-run.ts +335 -16
- package/src/commands/qa-status.ts +608 -0
- package/src/commands/qa-verify.ts +238 -0
- package/src/commands/review-pack.ts +1281 -0
- package/src/core/agents/qa-signal.ts +261 -0
- package/src/core/agents/session-name-display.ts +78 -7
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +23 -0
- package/src/core/agents/state/live-coordination-view.ts +1 -0
- package/src/core/agents/state/live-coordination-writer.ts +5 -0
- package/src/core/artifacts/constants.ts +1 -1
- package/src/core/artifacts/index.ts +370 -21
- package/src/core/config.ts +23 -0
- package/src/core/diagnostics/bundle.ts +119 -11
- package/src/core/events/v3/bootstrap.ts +10 -0
- package/src/core/events/v3/coordination-view.ts +100 -11
- package/src/core/events/v3/producers/intake.ts +9 -2
- package/src/core/events/v3/producers/recorder.ts +312 -18
- package/src/core/hooks/cli.ts +140 -32
- package/src/core/hooks/resolve/transcript.ts +10 -3
- package/src/core/hooks/session-name-presence.ts +6 -1
- package/src/core/qa-artifacts.ts +126 -0
- package/src/core/resources/contract.ts +7 -0
- package/src/core/resources/sampler.ts +138 -6
- package/src/lib/admission.ts +347 -0
- package/src/lib/agent-browser/client.ts +2 -10
- package/src/lib/browser/capture-fidelity.ts +98 -0
- package/src/lib/browser/client.ts +206 -10
- package/src/lib/browser/critique.ts +62 -7
- package/src/lib/browser/index.ts +36 -0
- package/src/lib/browser/page-review-judge.ts +360 -0
- package/src/lib/browser/page-review-pack.ts +2384 -0
- package/src/lib/browser/qa-run-contracts.ts +366 -3
- package/src/lib/browser/qa-run.ts +868 -190
- package/src/lib/browser/request-diagnostics.ts +27 -0
- package/src/lib/browser/tiling.ts +32 -0
- package/src/lib/cookies/client.ts +228 -42
- package/src/lib/cookies/extra.ts +28 -0
- package/src/lib/cookies/index.ts +2 -0
- package/src/lib/durable-job.ts +407 -0
- package/src/lib/http/client.ts +13 -1
- package/src/lib/instructions/templates.ts +5 -2
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*
|
|
22
22
|
* Never throws: coordination telemetry must not take down a hook.
|
|
23
23
|
*/
|
|
24
|
+
import { sessionNameDisplayAcceptedNames } from "../agents/session-name-display.js";
|
|
24
25
|
import { stampSessionNameSeen } from "../agents/state/heartbeat-writer.js";
|
|
25
26
|
import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
|
|
26
27
|
export function sessionNamePresence(coordRoot, instanceId, scanAssistantText) {
|
|
@@ -32,7 +33,9 @@ export function sessionNamePresence(coordRoot, instanceId, scanAssistantText) {
|
|
|
32
33
|
if (row?.session_name_seen_for === name) {
|
|
33
34
|
return { session_name_present: true, session_name_present_for: name };
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
+
// A display of the title Harnery last asked for counts here too, so Stop
|
|
37
|
+
// and the PreToolUse gate cannot disagree about the same reply.
|
|
38
|
+
const present = sessionNameDisplayAcceptedNames(row).some((candidate) => scanAssistantText(candidate));
|
|
36
39
|
if (present)
|
|
37
40
|
stampSessionNameSeen(coordRoot, instanceId, name);
|
|
38
41
|
return { session_name_present: present, session_name_present_for: name };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed output workspaces for page-QA commands.
|
|
3
|
+
*
|
|
4
|
+
* An implicit qa-run/qa-record output is working evidence, not project source.
|
|
5
|
+
* Keep it in the bounded artifact store. Callers that pass --out-dir retain
|
|
6
|
+
* full control of that explicit destination.
|
|
7
|
+
*/
|
|
8
|
+
import type { HarneryProgramContext } from "../commander.js";
|
|
9
|
+
export type QaArtifactKind = "qa-run" | "qa-record" | "review-pack";
|
|
10
|
+
export declare function resolveQaRepoRoot(context?: HarneryProgramContext): string;
|
|
11
|
+
export declare function createManagedQaOutParent(repoRoot: string, kind: QaArtifactKind, opts?: {
|
|
12
|
+
retentionMinutes?: number;
|
|
13
|
+
}): string;
|
|
14
|
+
/**
|
|
15
|
+
* Find the newest run in a valid managed QA workspace. This keeps no-path
|
|
16
|
+
* `qa-status` useful even though every implicit invocation gets an isolated
|
|
17
|
+
* artifact workspace instead of sharing one root-level `.qa-run` directory.
|
|
18
|
+
*/
|
|
19
|
+
export declare function latestManagedQaRun(repoRoot: string): string | null;
|
|
20
|
+
//# sourceMappingURL=qa-artifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-artifacts.d.ts","sourceRoot":"","sources":["../../src/core/qa-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAW7D,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;AAEpE,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAEzE;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,MAAM,CAcR;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuClE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed output workspaces for page-QA commands.
|
|
3
|
+
*
|
|
4
|
+
* An implicit qa-run/qa-record output is working evidence, not project source.
|
|
5
|
+
* Keep it in the bounded artifact store. Callers that pass --out-dir retain
|
|
6
|
+
* full control of that explicit destination.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
9
|
+
import { join, resolve } from "node:path";
|
|
10
|
+
import { monorepoRoot } from "./agents/index.js";
|
|
11
|
+
import { ARTIFACT_MANIFEST, artifactsRoot, configuredArtifactRetentionDays, createArtifact, parseArtifactManifest, } from "./artifacts/index.js";
|
|
12
|
+
export function resolveQaRepoRoot(context) {
|
|
13
|
+
return resolve(context?.repoRoot ?? monorepoRoot() ?? process.cwd());
|
|
14
|
+
}
|
|
15
|
+
export function createManagedQaOutParent(repoRoot, kind, opts = {}) {
|
|
16
|
+
return createArtifact(repoRoot, {
|
|
17
|
+
slug: kind,
|
|
18
|
+
purpose: kind === "qa-run"
|
|
19
|
+
? "Page QA run evidence"
|
|
20
|
+
: kind === "review-pack"
|
|
21
|
+
? "Page review pack"
|
|
22
|
+
: "Hand-recorded page QA evidence",
|
|
23
|
+
retentionDays: configuredArtifactRetentionDays(repoRoot),
|
|
24
|
+
// A standalone review-pack workspace IS the pack, so the artifact store's
|
|
25
|
+
// own expiry follows the pack's (90 minutes by default, ruled 2026-09-02).
|
|
26
|
+
...(opts.retentionMinutes !== undefined ? { retentionMinutes: opts.retentionMinutes } : {}),
|
|
27
|
+
}).path;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Find the newest run in a valid managed QA workspace. This keeps no-path
|
|
31
|
+
* `qa-status` useful even though every implicit invocation gets an isolated
|
|
32
|
+
* artifact workspace instead of sharing one root-level `.qa-run` directory.
|
|
33
|
+
*/
|
|
34
|
+
export function latestManagedQaRun(repoRoot) {
|
|
35
|
+
const root = artifactsRoot(repoRoot);
|
|
36
|
+
if (!existsSync(root))
|
|
37
|
+
return null;
|
|
38
|
+
let workspaceNames;
|
|
39
|
+
try {
|
|
40
|
+
workspaceNames = readdirSync(root).sort();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
let latest = null;
|
|
46
|
+
for (const workspaceName of workspaceNames) {
|
|
47
|
+
const workspace = join(root, workspaceName);
|
|
48
|
+
const manifest = readQaManifest(join(workspace, ARTIFACT_MANIFEST));
|
|
49
|
+
if (!manifest)
|
|
50
|
+
continue;
|
|
51
|
+
let runNames;
|
|
52
|
+
try {
|
|
53
|
+
runNames = readdirSync(workspace)
|
|
54
|
+
.filter((name) => name.startsWith("run-"))
|
|
55
|
+
.sort();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
for (const runName of runNames) {
|
|
61
|
+
const runDir = join(workspace, runName);
|
|
62
|
+
const startedAtMs = readStartedAtMs(runDir);
|
|
63
|
+
if (startedAtMs === null)
|
|
64
|
+
continue;
|
|
65
|
+
if (latest === null ||
|
|
66
|
+
startedAtMs > latest.startedAtMs ||
|
|
67
|
+
(startedAtMs === latest.startedAtMs && runDir > latest.path)) {
|
|
68
|
+
latest = { path: runDir, startedAtMs };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return latest?.path ?? null;
|
|
73
|
+
}
|
|
74
|
+
function readQaManifest(path) {
|
|
75
|
+
try {
|
|
76
|
+
const parsed = parseArtifactManifest(JSON.parse(readFileSync(path, "utf8")));
|
|
77
|
+
if (!parsed.ok)
|
|
78
|
+
return null;
|
|
79
|
+
if (parsed.manifest.slug !== "qa-run" && parsed.manifest.slug !== "qa-record")
|
|
80
|
+
return null;
|
|
81
|
+
return parsed.manifest;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function readStartedAtMs(runDir) {
|
|
88
|
+
for (const file of ["run-status.json", "page-qa-result.json"]) {
|
|
89
|
+
try {
|
|
90
|
+
const value = JSON.parse(readFileSync(join(runDir, file), "utf8"));
|
|
91
|
+
const run = value.run;
|
|
92
|
+
const startedAt = typeof value.started_at === "string"
|
|
93
|
+
? value.started_at
|
|
94
|
+
: run &&
|
|
95
|
+
typeof run === "object" &&
|
|
96
|
+
typeof run.started_at === "string"
|
|
97
|
+
? run.started_at
|
|
98
|
+
: null;
|
|
99
|
+
if (!startedAt)
|
|
100
|
+
continue;
|
|
101
|
+
const parsed = Date.parse(startedAt);
|
|
102
|
+
if (!Number.isNaN(parsed))
|
|
103
|
+
return parsed;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Try the other authoritative run document.
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
@@ -14,6 +14,7 @@ export interface ResourceProcessSample {
|
|
|
14
14
|
owner_kind: "agent" | "service" | "unattributed";
|
|
15
15
|
owner_id: string | null;
|
|
16
16
|
owner_root_pid: number | null;
|
|
17
|
+
owner_source?: "pid-map" | "session-environment" | "service";
|
|
17
18
|
}
|
|
18
19
|
export interface ResourceProcessGroup {
|
|
19
20
|
kind: ResourceProcessSample["owner_kind"];
|
|
@@ -82,6 +83,11 @@ export interface ResourceSamplerState {
|
|
|
82
83
|
cpu_total_ticks: number;
|
|
83
84
|
cpu_idle_ticks: number;
|
|
84
85
|
process_ticks: Map<string, number>;
|
|
86
|
+
process_owners: Map<string, ResourceProcessOwnerProof>;
|
|
87
|
+
}
|
|
88
|
+
export interface ResourceProcessOwnerProof {
|
|
89
|
+
session_id: string;
|
|
90
|
+
instance_id: string;
|
|
85
91
|
}
|
|
86
92
|
export interface ResourceSampleResult {
|
|
87
93
|
snapshot: ResourceSnapshot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/core/resources/contract.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,eAAO,MAAM,sCAAsC,IAAI,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;AAErF,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,GAAG,SAAS,GAAG,cAAc,CAAC;IACjD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/core/resources/contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,10 +8,17 @@ interface ResourceSamplerOptions {
|
|
|
8
8
|
pid: number;
|
|
9
9
|
id: string;
|
|
10
10
|
}[];
|
|
11
|
+
sessionOwners?: readonly SessionOwner[];
|
|
11
12
|
unattributedCpuFloor?: number;
|
|
12
13
|
unattributedRssFloor?: number;
|
|
13
14
|
maxProcesses?: number;
|
|
14
15
|
}
|
|
16
|
+
interface SessionOwner {
|
|
17
|
+
nativeSessionId: string;
|
|
18
|
+
instanceId: string;
|
|
19
|
+
platform: string;
|
|
20
|
+
kind: string;
|
|
21
|
+
}
|
|
15
22
|
export declare function sampleResources(coordRoot: string, previous?: ResourceSamplerState, options?: ResourceSamplerOptions): ResourceSampleResult;
|
|
16
23
|
export declare function parseLinuxProcessStat(line: string): {
|
|
17
24
|
pid: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampler.d.ts","sourceRoot":"","sources":["../../../src/core/resources/sampler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sampler.d.ts","sourceRoot":"","sources":["../../../src/core/resources/sampler.ts"],"names":[],"mappings":"AAQA,OAAO,EAKL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAE1B,MAAM,eAAe,CAAC;AA0BvB,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClD,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,YAAY;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,OAAO,GAAE,sBAA2B,GACnC,oBAAoB,CAmJtB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CA0BP;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAuB7D"}
|
|
@@ -3,6 +3,7 @@ import { existsSync, readdirSync, readFileSync, readlinkSync } from "node:fs";
|
|
|
3
3
|
import { cpus, loadavg, platform, release } from "node:os";
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { performance } from "node:perf_hooks";
|
|
6
|
+
import { readLiveCoordinationRows } from "../agents/state/live-coordination-view.js";
|
|
6
7
|
import { parsePidmapRow } from "../agents/state/pidmap.js";
|
|
7
8
|
import { checkPidToken } from "../agents/state/proc-start.js";
|
|
8
9
|
import { RESOURCE_SNAPSHOT_SCHEMA_VERSION, } from "./contract.js";
|
|
@@ -36,7 +37,15 @@ export function sampleResources(coordRoot, previous, options = {}) {
|
|
|
36
37
|
const cpu = parseLinuxCpu(readFileSync(join(procRoot, "stat"), "utf8"));
|
|
37
38
|
const memory = parseMeminfo(readFileSync(join(procRoot, "meminfo"), "utf8"));
|
|
38
39
|
const readings = readLinuxProcesses(procRoot, clockTicks, pageSize, uptimeSeconds);
|
|
39
|
-
const
|
|
40
|
+
const liveSessionOwners = uniqueLiveCodexSessionOwners(options.sessionOwners ??
|
|
41
|
+
readLiveCoordinationRows(coordRoot).map((row) => ({
|
|
42
|
+
nativeSessionId: row.native_session_id ?? "",
|
|
43
|
+
instanceId: row.instance_id,
|
|
44
|
+
platform: row.platform ?? "",
|
|
45
|
+
kind: row.kind ?? "",
|
|
46
|
+
})));
|
|
47
|
+
const ownership = readOwnershipAnchors(coordRoot, procRoot, readings, options.services ?? [], liveSessionOwners, previous?.process_owners);
|
|
48
|
+
const anchors = ownership.anchors;
|
|
40
49
|
const byPid = new Map(readings.map((reading) => [reading.pid, reading]));
|
|
41
50
|
const processTicks = new Map();
|
|
42
51
|
const intervalMs = previous ? Math.max(0, nowMs - previous.sampled_at_ms) : null;
|
|
@@ -64,6 +73,7 @@ export function sampleResources(coordRoot, previous, options = {}) {
|
|
|
64
73
|
owner_kind: ownership?.kind ?? "unattributed",
|
|
65
74
|
owner_id: ownership?.id ?? null,
|
|
66
75
|
owner_root_pid: ownership?.rootPid ?? null,
|
|
76
|
+
...(ownership ? { owner_source: ownership.source } : {}),
|
|
67
77
|
};
|
|
68
78
|
});
|
|
69
79
|
const visible = processes
|
|
@@ -121,6 +131,7 @@ export function sampleResources(coordRoot, previous, options = {}) {
|
|
|
121
131
|
cpu_total_ticks: cpu.total,
|
|
122
132
|
cpu_idle_ticks: cpu.idle,
|
|
123
133
|
process_ticks: processTicks,
|
|
134
|
+
process_owners: ownership.processOwners,
|
|
124
135
|
},
|
|
125
136
|
};
|
|
126
137
|
}
|
|
@@ -212,7 +223,7 @@ function readLinuxProcesses(procRoot, clockTicks, pageSize, uptimeSeconds) {
|
|
|
212
223
|
}
|
|
213
224
|
return rows;
|
|
214
225
|
}
|
|
215
|
-
function readOwnershipAnchors(coordRoot, readings, services) {
|
|
226
|
+
function readOwnershipAnchors(coordRoot, procRoot, readings, services, liveSessionOwners, previousOwners) {
|
|
216
227
|
const byPid = new Set(readings.map((row) => row.pid));
|
|
217
228
|
const directory = join(coordRoot, ".harnery", "pid-map");
|
|
218
229
|
const anchors = new Map();
|
|
@@ -227,19 +238,109 @@ function readOwnershipAnchors(coordRoot, readings, services) {
|
|
|
227
238
|
const row = parsePidmapRow(readFileSync(join(directory, entry), "utf8"));
|
|
228
239
|
if (!row.instanceId || checkPidToken(pid, row.startToken) === "mismatch")
|
|
229
240
|
continue;
|
|
230
|
-
anchors.set(pid, { kind: "agent", id: row.instanceId });
|
|
241
|
+
anchors.set(pid, { kind: "agent", id: row.instanceId, source: "pid-map" });
|
|
231
242
|
}
|
|
232
243
|
catch {
|
|
233
244
|
// An unreadable or racing row cannot prove ownership.
|
|
234
245
|
}
|
|
235
246
|
}
|
|
236
247
|
}
|
|
248
|
+
const processOwners = readBridgeProcessOwners(procRoot, readings, liveSessionOwners, previousOwners);
|
|
249
|
+
const byReadingPid = new Map(readings.map((row) => [row.pid, row]));
|
|
250
|
+
for (const reading of readings) {
|
|
251
|
+
const identity = `${reading.pid}:${reading.startTicks}`;
|
|
252
|
+
const owner = processOwners.get(identity);
|
|
253
|
+
if (!owner || anchors.has(reading.pid))
|
|
254
|
+
continue;
|
|
255
|
+
const parent = byReadingPid.get(reading.ppid);
|
|
256
|
+
const parentOwner = parent
|
|
257
|
+
? processOwners.get(`${parent.pid}:${parent.startTicks}`)
|
|
258
|
+
: undefined;
|
|
259
|
+
if (parentOwner?.instance_id === owner.instance_id)
|
|
260
|
+
continue;
|
|
261
|
+
anchors.set(reading.pid, {
|
|
262
|
+
kind: "agent",
|
|
263
|
+
id: owner.instance_id,
|
|
264
|
+
source: "session-environment",
|
|
265
|
+
});
|
|
266
|
+
}
|
|
237
267
|
for (const service of services) {
|
|
238
268
|
if (byPid.has(service.pid) && service.id.trim()) {
|
|
239
|
-
anchors.set(service.pid, { kind: "service", id: service.id.trim() });
|
|
269
|
+
anchors.set(service.pid, { kind: "service", id: service.id.trim(), source: "service" });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return { anchors, processOwners };
|
|
273
|
+
}
|
|
274
|
+
function uniqueLiveCodexSessionOwners(rows) {
|
|
275
|
+
const candidates = new Map();
|
|
276
|
+
for (const row of rows) {
|
|
277
|
+
const sessionId = row.nativeSessionId.trim();
|
|
278
|
+
const instanceId = row.instanceId.trim();
|
|
279
|
+
if (row.platform !== "codex" || row.kind !== "session" || !sessionId || !instanceId)
|
|
280
|
+
continue;
|
|
281
|
+
const owners = candidates.get(sessionId) ?? new Set();
|
|
282
|
+
owners.add(instanceId);
|
|
283
|
+
candidates.set(sessionId, owners);
|
|
284
|
+
}
|
|
285
|
+
const result = new Map();
|
|
286
|
+
for (const [sessionId, owners] of candidates) {
|
|
287
|
+
if (owners.size === 1)
|
|
288
|
+
result.set(sessionId, [...owners][0]);
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
function readBridgeProcessOwners(procRoot, readings, liveSessionOwners, previousOwners) {
|
|
293
|
+
const result = new Map();
|
|
294
|
+
if (liveSessionOwners.size === 0)
|
|
295
|
+
return result;
|
|
296
|
+
for (const reading of readings) {
|
|
297
|
+
const identity = `${reading.pid}:${reading.startTicks}`;
|
|
298
|
+
const previous = previousOwners?.get(identity);
|
|
299
|
+
if (previous && liveSessionOwners.get(previous.session_id) === previous.instance_id) {
|
|
300
|
+
result.set(identity, previous);
|
|
301
|
+
continue;
|
|
240
302
|
}
|
|
303
|
+
const sessionId = readCodexWslBridgeSessionId(procRoot, reading.pid);
|
|
304
|
+
if (!sessionId)
|
|
305
|
+
continue;
|
|
306
|
+
const instanceId = liveSessionOwners.get(sessionId);
|
|
307
|
+
if (instanceId)
|
|
308
|
+
result.set(identity, { session_id: sessionId, instance_id: instanceId });
|
|
241
309
|
}
|
|
242
|
-
return
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
function readCodexWslBridgeSessionId(procRoot, pid) {
|
|
313
|
+
try {
|
|
314
|
+
const entries = readFileSync(join(procRoot, String(pid), "environ"), "utf8").split("\0");
|
|
315
|
+
let bridge;
|
|
316
|
+
let platform;
|
|
317
|
+
let coordinationSessionId;
|
|
318
|
+
let codexThreadId;
|
|
319
|
+
for (const entry of entries) {
|
|
320
|
+
if (entry.startsWith("HARNERY_AGENT_COORD_BRIDGE=")) {
|
|
321
|
+
bridge = entry.slice("HARNERY_AGENT_COORD_BRIDGE=".length);
|
|
322
|
+
}
|
|
323
|
+
else if (entry.startsWith("HARNERY_AGENT_COORD_PLATFORM=")) {
|
|
324
|
+
platform = entry.slice("HARNERY_AGENT_COORD_PLATFORM=".length);
|
|
325
|
+
}
|
|
326
|
+
else if (entry.startsWith("HARNERY_AGENT_COORD_SESSION_ID=")) {
|
|
327
|
+
coordinationSessionId = entry.slice("HARNERY_AGENT_COORD_SESSION_ID=".length);
|
|
328
|
+
}
|
|
329
|
+
else if (entry.startsWith("CODEX_THREAD_ID=")) {
|
|
330
|
+
codexThreadId = entry.slice("CODEX_THREAD_ID=".length);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (bridge === "codex-wsl" &&
|
|
334
|
+
platform === "codex" &&
|
|
335
|
+
coordinationSessionId &&
|
|
336
|
+
coordinationSessionId === codexThreadId) {
|
|
337
|
+
return coordinationSessionId;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
// An unreadable or racing environment cannot prove ownership.
|
|
342
|
+
}
|
|
343
|
+
return undefined;
|
|
243
344
|
}
|
|
244
345
|
function resolveOwnership(pid, byPid, anchors) {
|
|
245
346
|
const seen = new Set();
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface AdmissionConfig {
|
|
2
|
+
/** Base directory holding one subdirectory per resource. */
|
|
3
|
+
dir: string;
|
|
4
|
+
/** Resource name, e.g. "browser-qa" or "build". */
|
|
5
|
+
resource: string;
|
|
6
|
+
/** Maximum concurrent holders. */
|
|
7
|
+
capacity: number;
|
|
8
|
+
/** Poll interval while waiting (default 500ms). */
|
|
9
|
+
pollMs?: number;
|
|
10
|
+
/** Entries older than this are pruned regardless of PID (default 6h). */
|
|
11
|
+
ttlMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface AdmissionEntry {
|
|
14
|
+
pid: number;
|
|
15
|
+
label: string;
|
|
16
|
+
created_at: string;
|
|
17
|
+
/** Set on holders once admitted. */
|
|
18
|
+
acquired_at?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AdmissionWaitInfo {
|
|
21
|
+
/** 1-based position in the ticket queue. */
|
|
22
|
+
position: number;
|
|
23
|
+
holders: AdmissionEntry[];
|
|
24
|
+
}
|
|
25
|
+
export interface AdmissionAcquireOptions {
|
|
26
|
+
/** Human-readable holder description shown in status listings. */
|
|
27
|
+
label: string;
|
|
28
|
+
/** Maximum wait before AdmissionTimeoutError (default 20 minutes). */
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
/** Progress callback, invoked at most once per poll while waiting. */
|
|
31
|
+
onWait?: (info: AdmissionWaitInfo) => void;
|
|
32
|
+
}
|
|
33
|
+
export interface AdmissionHandle {
|
|
34
|
+
/** The held entry's filename (diagnostics). */
|
|
35
|
+
entry: string;
|
|
36
|
+
/** Milliseconds spent waiting in the queue. */
|
|
37
|
+
waitedMs: number;
|
|
38
|
+
/** Give the slot back. Safe to call more than once. */
|
|
39
|
+
release: () => void;
|
|
40
|
+
}
|
|
41
|
+
export declare class AdmissionTimeoutError extends Error {
|
|
42
|
+
readonly holders: AdmissionEntry[];
|
|
43
|
+
constructor(resource: string, timeoutMs: number, holders: AdmissionEntry[]);
|
|
44
|
+
}
|
|
45
|
+
/** Is a PID alive on this machine? EPERM counts as alive; only ESRCH counts
|
|
46
|
+
* as dead (fail toward respecting holders rather than stealing slots). */
|
|
47
|
+
export declare function pidAlive(pid: number): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Join the FIFO queue for one resource and resolve once a slot is held.
|
|
50
|
+
* Throws AdmissionTimeoutError (with the holders snapshot) when no slot
|
|
51
|
+
* frees within the timeout — the caller decides whether that is fatal.
|
|
52
|
+
*/
|
|
53
|
+
export declare function acquireAdmission(config: AdmissionConfig, options: AdmissionAcquireOptions): Promise<AdmissionHandle>;
|
|
54
|
+
export interface AdmissionStatus {
|
|
55
|
+
resource: string;
|
|
56
|
+
capacity?: number;
|
|
57
|
+
holders: AdmissionEntry[];
|
|
58
|
+
waiters: AdmissionEntry[];
|
|
59
|
+
}
|
|
60
|
+
/** Snapshot the queue for one resource, pruning dead entries on the way. */
|
|
61
|
+
export declare function admissionStatus(config: Pick<AdmissionConfig, "dir" | "resource" | "ttlMs">): AdmissionStatus;
|
|
62
|
+
/**
|
|
63
|
+
* Base directory for admission queue state. tmpdir clears on reboot, which
|
|
64
|
+
* is correct — stale queue state must not outlive the boot. Override with
|
|
65
|
+
* HARNERY_ADMISSION_DIR. Host CLIs and harn commands must share this helper
|
|
66
|
+
* so they join the same machine-wide queues.
|
|
67
|
+
*/
|
|
68
|
+
export declare function admissionBaseDir(): string;
|
|
69
|
+
/** Resources present under an admission base directory. */
|
|
70
|
+
export declare function listAdmissionResources(dir: string): string[];
|
|
71
|
+
//# sourceMappingURL=admission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admission.d.ts","sourceRoot":"","sources":["../../src/lib/admission.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;gBACvB,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE;CAW3E;AASD;0EAC0E;AAC1E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAY7C;AA2FD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,eAAe,CAAC,CAyF1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,UAAU,GAAG,OAAO,CAAC,GAC1D,eAAe,CAQjB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAS5D"}
|