@akagilnc/pi-workflow-roles 0.1.1941 → 0.1.2004
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/public-cli/main.js +2448 -75
- package/package.json +1 -1
- package/src/atomic-write.ts +26 -0
- package/src/ledger-session-read.ts +260 -0
- package/src/public-cli/cli.ts +24 -0
- package/src/public-cli/invocation.ts +352 -1
- package/src/public-cli/main.ts +21 -2
- package/src/public-cli/registry.ts +18 -1
- package/src/public-cli/settlement.ts +9 -0
- package/src/public-cli/taishi-run.ts +235 -0
- package/src/run-terminal-artifacts.ts +231 -0
- package/src/taishi-cohort.ts +232 -0
- package/src/taishi-entry.ts +429 -0
- package/src/taishi-index.ts +269 -0
- package/src/taishi-ledger.ts +466 -0
- package/src/taishi-median.ts +15 -0
- package/src/taishi-metric-families/acceptance-success-rework.ts +346 -0
- package/src/taishi-metric-families/b2-frame-buckets-actions.ts +274 -0
- package/src/taishi-metric-families/leg-wall-clock.ts +90 -0
- package/src/taishi-metric-families/round-timeline.ts +201 -0
- package/src/taishi-metric-families.ts +36 -0
- package/src/taishi-metric-family.ts +41 -0
- package/src/taishi-model-groups.ts +198 -0
- package/src/taishi-page.ts +320 -0
- package/src/ticket-trajectory.ts +9 -62
package/dist/public-cli/main.js
CHANGED
|
@@ -14273,7 +14273,13 @@ function listHelpCapabilities() {
|
|
|
14273
14273
|
defaultPhase
|
|
14274
14274
|
};
|
|
14275
14275
|
});
|
|
14276
|
-
|
|
14276
|
+
const deterministic = PUBLIC_DETERMINISTIC_COMMANDS.map(
|
|
14277
|
+
(name) => ({
|
|
14278
|
+
kind: "deterministic",
|
|
14279
|
+
name
|
|
14280
|
+
})
|
|
14281
|
+
);
|
|
14282
|
+
return [...support, ...roles, ...deterministic];
|
|
14277
14283
|
}
|
|
14278
14284
|
function isPublicConfigurableSeat(value) {
|
|
14279
14285
|
return PUBLIC_CONFIGURABLE_SEATS.includes(value);
|
|
@@ -14281,7 +14287,7 @@ function isPublicConfigurableSeat(value) {
|
|
|
14281
14287
|
function isPublicCliSupportCommand(value) {
|
|
14282
14288
|
return PUBLIC_CLI_SUPPORT_COMMANDS.includes(value);
|
|
14283
14289
|
}
|
|
14284
|
-
var INTERNAL_ROLE_ENTRYPOINT_RELATIVE, PUBLIC_CALLABLE_ROLES, AUTOMATIC_NAVIGATOR_SEAT, PUBLIC_CONFIGURABLE_SEATS, PUBLIC_CLI_SUPPORT_COMMANDS, STARTUP_CANDIDATES;
|
|
14290
|
+
var INTERNAL_ROLE_ENTRYPOINT_RELATIVE, PUBLIC_CALLABLE_ROLES, AUTOMATIC_NAVIGATOR_SEAT, PUBLIC_CONFIGURABLE_SEATS, PUBLIC_CLI_SUPPORT_COMMANDS, STARTUP_CANDIDATES, PUBLIC_DETERMINISTIC_COMMANDS;
|
|
14285
14291
|
var init_registry2 = __esm({
|
|
14286
14292
|
"src/public-cli/registry.ts"() {
|
|
14287
14293
|
"use strict";
|
|
@@ -14335,6 +14341,7 @@ var init_registry2 = __esm({
|
|
|
14335
14341
|
{ provider: "xai", model: "grok-4.5", thinking: "high" }
|
|
14336
14342
|
]
|
|
14337
14343
|
};
|
|
14344
|
+
PUBLIC_DETERMINISTIC_COMMANDS = ["taishi"];
|
|
14338
14345
|
}
|
|
14339
14346
|
});
|
|
14340
14347
|
|
|
@@ -14767,6 +14774,26 @@ function ensureRealDirectoryTree(root, targetDir) {
|
|
|
14767
14774
|
);
|
|
14768
14775
|
}
|
|
14769
14776
|
}
|
|
14777
|
+
function assertLedgerFileInsideHome(ledgerPath, ledgerHome) {
|
|
14778
|
+
if (!isAbsolute(ledgerHome)) {
|
|
14779
|
+
throw new ActivationLedgerError(`activation ledger home must be absolute: ${ledgerHome}`);
|
|
14780
|
+
}
|
|
14781
|
+
const resolvedLedger = resolve(ledgerPath);
|
|
14782
|
+
try {
|
|
14783
|
+
if (!lstatSync2(resolvedLedger).isSymbolicLink()) return;
|
|
14784
|
+
throw new ActivationLedgerError(
|
|
14785
|
+
`activation ledger file is a symbolic link: ${resolvedLedger}`
|
|
14786
|
+
);
|
|
14787
|
+
} catch (error) {
|
|
14788
|
+
if (errnoCode(error) !== "ENOENT") {
|
|
14789
|
+
if (error instanceof ActivationLedgerError) throw error;
|
|
14790
|
+
throw new ActivationLedgerError(
|
|
14791
|
+
`activation ledger failed to stat ledger file (${resolvedLedger}): ${errorText(error)}`,
|
|
14792
|
+
{ cause: error }
|
|
14793
|
+
);
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
14796
|
+
}
|
|
14770
14797
|
var ActivationLedgerError;
|
|
14771
14798
|
var init_activation_ledger_topology = __esm({
|
|
14772
14799
|
"src/activation-ledger-topology.ts"() {
|
|
@@ -16769,7 +16796,260 @@ function buildMergerTransportPrompt(admitted) {
|
|
|
16769
16796
|
}
|
|
16770
16797
|
return lines.join("\n");
|
|
16771
16798
|
}
|
|
16772
|
-
|
|
16799
|
+
function parseTaishiTicketNumber(raw, flag = "--ticket") {
|
|
16800
|
+
const trimmed = raw.trim();
|
|
16801
|
+
if (!TAISHI_TICKET_NUMBER_PATTERN.test(trimmed)) {
|
|
16802
|
+
throw new CliUsageError(
|
|
16803
|
+
`taishi ${flag} must be a positive integer, got ${raw}`
|
|
16804
|
+
);
|
|
16805
|
+
}
|
|
16806
|
+
const value = Number(trimmed);
|
|
16807
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
16808
|
+
throw new CliUsageError(
|
|
16809
|
+
`taishi ${flag} must be a positive integer, got ${raw}`
|
|
16810
|
+
);
|
|
16811
|
+
}
|
|
16812
|
+
return value;
|
|
16813
|
+
}
|
|
16814
|
+
function parseTaishiIssueNumberList(raw, flag) {
|
|
16815
|
+
const trimmed = raw.trim();
|
|
16816
|
+
if (trimmed === "") {
|
|
16817
|
+
throw new CliUsageError(`${flag} requires a comma-separated positive integer list`);
|
|
16818
|
+
}
|
|
16819
|
+
const parts = trimmed.split(",").map((part) => part.trim());
|
|
16820
|
+
if (parts.some((part) => part === "")) {
|
|
16821
|
+
throw new CliUsageError(`${flag} requires a comma-separated positive integer list`);
|
|
16822
|
+
}
|
|
16823
|
+
return parts.map((part) => parseTaishiTicketNumber(part, flag));
|
|
16824
|
+
}
|
|
16825
|
+
function requireOptionValue(flag, value, what) {
|
|
16826
|
+
if (value === void 0 || value.trim() === "") {
|
|
16827
|
+
throw new CliUsageError(`${flag} requires ${what}`);
|
|
16828
|
+
}
|
|
16829
|
+
return value;
|
|
16830
|
+
}
|
|
16831
|
+
function parseTaishiArgv(args) {
|
|
16832
|
+
let query = "issue";
|
|
16833
|
+
let ticketRaw;
|
|
16834
|
+
const projectRoots = [];
|
|
16835
|
+
let groupALabel;
|
|
16836
|
+
let groupAIssuesRaw;
|
|
16837
|
+
let groupBLabel;
|
|
16838
|
+
let groupBIssuesRaw;
|
|
16839
|
+
let sweepToken = false;
|
|
16840
|
+
const attachmentPaths = [];
|
|
16841
|
+
const tokens = [...args];
|
|
16842
|
+
while (tokens.length > 0) {
|
|
16843
|
+
const token = tokens.shift();
|
|
16844
|
+
if (token === "--") {
|
|
16845
|
+
if (tokens.length > 0) {
|
|
16846
|
+
throw new CliUsageError(`unexpected taishi argument: ${tokens[0]}`);
|
|
16847
|
+
}
|
|
16848
|
+
break;
|
|
16849
|
+
}
|
|
16850
|
+
if (token === "--cohort") {
|
|
16851
|
+
if (query !== "issue") {
|
|
16852
|
+
throw new CliUsageError("taishi accepts only one of --cohort / --model-groups");
|
|
16853
|
+
}
|
|
16854
|
+
query = "cohort";
|
|
16855
|
+
continue;
|
|
16856
|
+
}
|
|
16857
|
+
if (token === "--model-groups") {
|
|
16858
|
+
if (query !== "issue") {
|
|
16859
|
+
throw new CliUsageError("taishi accepts only one of --cohort / --model-groups");
|
|
16860
|
+
}
|
|
16861
|
+
query = "model-groups";
|
|
16862
|
+
continue;
|
|
16863
|
+
}
|
|
16864
|
+
if (token === "--ticket") {
|
|
16865
|
+
const value = tokens.shift();
|
|
16866
|
+
if (value === void 0 || value.trim() === "") {
|
|
16867
|
+
throw new CliUsageError("taishi --ticket requires a positive integer");
|
|
16868
|
+
}
|
|
16869
|
+
ticketRaw = value;
|
|
16870
|
+
continue;
|
|
16871
|
+
}
|
|
16872
|
+
if (token.startsWith("--ticket=")) {
|
|
16873
|
+
ticketRaw = token.slice("--ticket=".length);
|
|
16874
|
+
if (ticketRaw.trim() === "") {
|
|
16875
|
+
throw new CliUsageError("taishi --ticket requires a positive integer");
|
|
16876
|
+
}
|
|
16877
|
+
continue;
|
|
16878
|
+
}
|
|
16879
|
+
if (token === "--project-root") {
|
|
16880
|
+
projectRoots.push(requireOptionPath("--project-root", tokens.shift()));
|
|
16881
|
+
continue;
|
|
16882
|
+
}
|
|
16883
|
+
if (token.startsWith("--project-root=")) {
|
|
16884
|
+
projectRoots.push(
|
|
16885
|
+
requireOptionPath("--project-root", token.slice("--project-root=".length))
|
|
16886
|
+
);
|
|
16887
|
+
continue;
|
|
16888
|
+
}
|
|
16889
|
+
if (token === "--group-a-label") {
|
|
16890
|
+
groupALabel = requireOptionValue("--group-a-label", tokens.shift(), "a label");
|
|
16891
|
+
continue;
|
|
16892
|
+
}
|
|
16893
|
+
if (token.startsWith("--group-a-label=")) {
|
|
16894
|
+
groupALabel = requireOptionValue(
|
|
16895
|
+
"--group-a-label",
|
|
16896
|
+
token.slice("--group-a-label=".length),
|
|
16897
|
+
"a label"
|
|
16898
|
+
);
|
|
16899
|
+
continue;
|
|
16900
|
+
}
|
|
16901
|
+
if (token === "--group-a-issues") {
|
|
16902
|
+
groupAIssuesRaw = requireOptionValue(
|
|
16903
|
+
"--group-a-issues",
|
|
16904
|
+
tokens.shift(),
|
|
16905
|
+
"a comma-separated positive integer list"
|
|
16906
|
+
);
|
|
16907
|
+
continue;
|
|
16908
|
+
}
|
|
16909
|
+
if (token.startsWith("--group-a-issues=")) {
|
|
16910
|
+
groupAIssuesRaw = requireOptionValue(
|
|
16911
|
+
"--group-a-issues",
|
|
16912
|
+
token.slice("--group-a-issues=".length),
|
|
16913
|
+
"a comma-separated positive integer list"
|
|
16914
|
+
);
|
|
16915
|
+
continue;
|
|
16916
|
+
}
|
|
16917
|
+
if (token === "--group-b-label") {
|
|
16918
|
+
groupBLabel = requireOptionValue("--group-b-label", tokens.shift(), "a label");
|
|
16919
|
+
continue;
|
|
16920
|
+
}
|
|
16921
|
+
if (token.startsWith("--group-b-label=")) {
|
|
16922
|
+
groupBLabel = requireOptionValue(
|
|
16923
|
+
"--group-b-label",
|
|
16924
|
+
token.slice("--group-b-label=".length),
|
|
16925
|
+
"a label"
|
|
16926
|
+
);
|
|
16927
|
+
continue;
|
|
16928
|
+
}
|
|
16929
|
+
if (token === "--group-b-issues") {
|
|
16930
|
+
groupBIssuesRaw = requireOptionValue(
|
|
16931
|
+
"--group-b-issues",
|
|
16932
|
+
tokens.shift(),
|
|
16933
|
+
"a comma-separated positive integer list"
|
|
16934
|
+
);
|
|
16935
|
+
continue;
|
|
16936
|
+
}
|
|
16937
|
+
if (token.startsWith("--group-b-issues=")) {
|
|
16938
|
+
groupBIssuesRaw = requireOptionValue(
|
|
16939
|
+
"--group-b-issues",
|
|
16940
|
+
token.slice("--group-b-issues=".length),
|
|
16941
|
+
"a comma-separated positive integer list"
|
|
16942
|
+
);
|
|
16943
|
+
continue;
|
|
16944
|
+
}
|
|
16945
|
+
if (token === "--attach") {
|
|
16946
|
+
attachmentPaths.push(requireOptionPath("--attach", tokens.shift()));
|
|
16947
|
+
continue;
|
|
16948
|
+
}
|
|
16949
|
+
if (token.startsWith("--attach=")) {
|
|
16950
|
+
attachmentPaths.push(
|
|
16951
|
+
requireOptionPath("--attach", token.slice("--attach=".length))
|
|
16952
|
+
);
|
|
16953
|
+
continue;
|
|
16954
|
+
}
|
|
16955
|
+
if (token.startsWith("-") && token !== "-") {
|
|
16956
|
+
throw new CliUsageError(`unknown taishi option: ${token}`);
|
|
16957
|
+
}
|
|
16958
|
+
if (token === "sweep") {
|
|
16959
|
+
if (sweepToken) {
|
|
16960
|
+
throw new CliUsageError("unexpected taishi argument: sweep");
|
|
16961
|
+
}
|
|
16962
|
+
sweepToken = true;
|
|
16963
|
+
continue;
|
|
16964
|
+
}
|
|
16965
|
+
throw new CliUsageError(`unexpected taishi argument: ${token}`);
|
|
16966
|
+
}
|
|
16967
|
+
const hasSweepFace = sweepToken || attachmentPaths.length > 0;
|
|
16968
|
+
const hasCohortFlags = groupALabel !== void 0 || groupAIssuesRaw !== void 0 || groupBLabel !== void 0 || groupBIssuesRaw !== void 0;
|
|
16969
|
+
if (query === "cohort") {
|
|
16970
|
+
if (groupALabel === void 0 || groupAIssuesRaw === void 0 || groupBLabel === void 0 || groupBIssuesRaw === void 0) {
|
|
16971
|
+
throw new CliUsageError(
|
|
16972
|
+
"usage: ak-role taishi --cohort --group-a-label <L> --group-a-issues <N[,N...]> --group-b-label <L> --group-b-issues <N[,N...]>"
|
|
16973
|
+
);
|
|
16974
|
+
}
|
|
16975
|
+
if (ticketRaw !== void 0 || projectRoots.length > 0) {
|
|
16976
|
+
throw new CliUsageError(
|
|
16977
|
+
"taishi --cohort does not accept --ticket or --project-root"
|
|
16978
|
+
);
|
|
16979
|
+
}
|
|
16980
|
+
if (hasSweepFace) {
|
|
16981
|
+
throw new CliUsageError(
|
|
16982
|
+
"taishi --cohort does not accept sweep --attach"
|
|
16983
|
+
);
|
|
16984
|
+
}
|
|
16985
|
+
return {
|
|
16986
|
+
query: "cohort",
|
|
16987
|
+
groups: [
|
|
16988
|
+
{
|
|
16989
|
+
groupLabel: groupALabel,
|
|
16990
|
+
issues: parseTaishiIssueNumberList(groupAIssuesRaw, "--group-a-issues")
|
|
16991
|
+
},
|
|
16992
|
+
{
|
|
16993
|
+
groupLabel: groupBLabel,
|
|
16994
|
+
issues: parseTaishiIssueNumberList(groupBIssuesRaw, "--group-b-issues")
|
|
16995
|
+
}
|
|
16996
|
+
]
|
|
16997
|
+
};
|
|
16998
|
+
}
|
|
16999
|
+
if (query === "model-groups") {
|
|
17000
|
+
if (projectRoots.length === 0) {
|
|
17001
|
+
throw new CliUsageError(
|
|
17002
|
+
"usage: ak-role taishi --model-groups --project-root <P> [--project-root <P> ...]"
|
|
17003
|
+
);
|
|
17004
|
+
}
|
|
17005
|
+
if (ticketRaw !== void 0) {
|
|
17006
|
+
throw new CliUsageError("taishi --model-groups does not accept --ticket");
|
|
17007
|
+
}
|
|
17008
|
+
if (hasCohortFlags) {
|
|
17009
|
+
throw new CliUsageError("taishi --model-groups does not accept cohort group flags");
|
|
17010
|
+
}
|
|
17011
|
+
if (hasSweepFace) {
|
|
17012
|
+
throw new CliUsageError(
|
|
17013
|
+
"taishi --model-groups does not accept sweep --attach"
|
|
17014
|
+
);
|
|
17015
|
+
}
|
|
17016
|
+
return {
|
|
17017
|
+
query: "model-groups",
|
|
17018
|
+
projectRoots
|
|
17019
|
+
};
|
|
17020
|
+
}
|
|
17021
|
+
if (hasCohortFlags) {
|
|
17022
|
+
throw new CliUsageError("taishi issue query does not accept cohort group flags");
|
|
17023
|
+
}
|
|
17024
|
+
if (hasSweepFace) {
|
|
17025
|
+
if (ticketRaw !== void 0 || projectRoots.length > 0) {
|
|
17026
|
+
throw new CliUsageError(
|
|
17027
|
+
"taishi sweep --attach cannot combine with --ticket or --project-root"
|
|
17028
|
+
);
|
|
17029
|
+
}
|
|
17030
|
+
return {
|
|
17031
|
+
query: "sweep",
|
|
17032
|
+
attachmentPaths
|
|
17033
|
+
};
|
|
17034
|
+
}
|
|
17035
|
+
if (projectRoots.length > 1) {
|
|
17036
|
+
throw new CliUsageError(
|
|
17037
|
+
"taishi issue query accepts at most one --project-root (use --model-groups for many)"
|
|
17038
|
+
);
|
|
17039
|
+
}
|
|
17040
|
+
const projectRoot = projectRoots[0];
|
|
17041
|
+
if (ticketRaw === void 0 && projectRoot === void 0) {
|
|
17042
|
+
throw new CliUsageError(
|
|
17043
|
+
"usage: ak-role taishi ((--ticket <N> | --project-root <P>) | [sweep] --attach <sweep.json> | --cohort ... | --model-groups ...)"
|
|
17044
|
+
);
|
|
17045
|
+
}
|
|
17046
|
+
return {
|
|
17047
|
+
query: "issue",
|
|
17048
|
+
...ticketRaw === void 0 ? {} : { ticket: parseTaishiTicketNumber(ticketRaw) },
|
|
17049
|
+
...projectRoot === void 0 ? {} : { projectRoot }
|
|
17050
|
+
};
|
|
17051
|
+
}
|
|
17052
|
+
var MergerEnvelopeDerivationError, DOCTOR_ISSUE_NUMBER_PATTERN, DOCTOR_CASE_RUNS_PATH_PATTERN, TAISHI_TICKET_NUMBER_PATTERN;
|
|
16773
17053
|
var init_invocation = __esm({
|
|
16774
17054
|
"src/public-cli/invocation.ts"() {
|
|
16775
17055
|
"use strict";
|
|
@@ -16796,6 +17076,7 @@ var init_invocation = __esm({
|
|
|
16796
17076
|
};
|
|
16797
17077
|
DOCTOR_ISSUE_NUMBER_PATTERN = /^[1-9]\d*$/;
|
|
16798
17078
|
DOCTOR_CASE_RUNS_PATH_PATTERN = /\/\.ak-roles\/books\/[^/]+\/issues\/([1-9]\d*)\/runs$/;
|
|
17079
|
+
TAISHI_TICKET_NUMBER_PATTERN = /^[1-9]\d*$/;
|
|
16799
17080
|
}
|
|
16800
17081
|
});
|
|
16801
17082
|
|
|
@@ -18735,6 +19016,11 @@ function formatFailureStderrDiagnostic(failure) {
|
|
|
18735
19016
|
function presentStructuralRejection(error, io) {
|
|
18736
19017
|
io.stderr(formatCliDiagnostic(error.message));
|
|
18737
19018
|
}
|
|
19019
|
+
function presentControlledFailure(failure, io) {
|
|
19020
|
+
io.stdout(`${JSON.stringify(failure, null, 2)}
|
|
19021
|
+
`);
|
|
19022
|
+
io.stderr(formatFailureStderrDiagnostic(failure));
|
|
19023
|
+
}
|
|
18738
19024
|
async function inspectJudgeSession(sessionFile) {
|
|
18739
19025
|
try {
|
|
18740
19026
|
await readFile9(sessionFile, "utf8");
|
|
@@ -21385,7 +21671,7 @@ function buildCoderResumeActivationExtraArgs(admitted, options) {
|
|
|
21385
21671
|
RESUME_TRANSPORT_ENVELOPE
|
|
21386
21672
|
];
|
|
21387
21673
|
}
|
|
21388
|
-
async function
|
|
21674
|
+
async function presentControlledFailure2(admitted, failureInput, io) {
|
|
21389
21675
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
21390
21676
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
21391
21677
|
runDirectory: admitted.runDirectory,
|
|
@@ -21441,7 +21727,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21441
21727
|
env.credentials
|
|
21442
21728
|
);
|
|
21443
21729
|
if (missingCredential !== void 0) {
|
|
21444
|
-
return await
|
|
21730
|
+
return await presentControlledFailure2(
|
|
21445
21731
|
admitted,
|
|
21446
21732
|
missingCredential,
|
|
21447
21733
|
io
|
|
@@ -21472,7 +21758,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21472
21758
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
21473
21759
|
});
|
|
21474
21760
|
} catch (error) {
|
|
21475
|
-
return await
|
|
21761
|
+
return await presentControlledFailure2(
|
|
21476
21762
|
admitted,
|
|
21477
21763
|
{
|
|
21478
21764
|
timedOut: false,
|
|
@@ -21497,7 +21783,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21497
21783
|
...methodProvenance === void 0 ? {} : { methodProvenance }
|
|
21498
21784
|
});
|
|
21499
21785
|
} catch (error) {
|
|
21500
|
-
return await
|
|
21786
|
+
return await presentControlledFailure2(
|
|
21501
21787
|
admitted,
|
|
21502
21788
|
{
|
|
21503
21789
|
timedOut: false,
|
|
@@ -21528,7 +21814,7 @@ async function dispatchAdmittedCoder(input) {
|
|
|
21528
21814
|
credential: credentialFailure,
|
|
21529
21815
|
runDirectory: admitted.runDirectory
|
|
21530
21816
|
});
|
|
21531
|
-
return await
|
|
21817
|
+
return await presentControlledFailure2(
|
|
21532
21818
|
admitted,
|
|
21533
21819
|
{
|
|
21534
21820
|
timedOut: result2.timedOut,
|
|
@@ -21583,7 +21869,7 @@ async function runPublicCoder(argv, env, io, parseCoderArgv2) {
|
|
|
21583
21869
|
methodProvenance = material.provenance;
|
|
21584
21870
|
} catch (error) {
|
|
21585
21871
|
await lease.release();
|
|
21586
|
-
return await
|
|
21872
|
+
return await presentControlledFailure2(
|
|
21587
21873
|
admitted,
|
|
21588
21874
|
{
|
|
21589
21875
|
timedOut: false,
|
|
@@ -21660,7 +21946,7 @@ async function runPublicCoderResume(argv, env, io) {
|
|
|
21660
21946
|
methodProvenance = material.provenance;
|
|
21661
21947
|
} catch (error) {
|
|
21662
21948
|
await lease.release();
|
|
21663
|
-
return await
|
|
21949
|
+
return await presentControlledFailure2(
|
|
21664
21950
|
admitted,
|
|
21665
21951
|
{
|
|
21666
21952
|
timedOut: false,
|
|
@@ -21743,7 +22029,7 @@ function buildCollectorActivationExtraArgs(admitted, options = {}) {
|
|
|
21743
22029
|
prompt
|
|
21744
22030
|
];
|
|
21745
22031
|
}
|
|
21746
|
-
async function
|
|
22032
|
+
async function presentControlledFailure3(admitted, failureInput, io) {
|
|
21747
22033
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
21748
22034
|
const session = !hasThrown && !failureInput.timedOut && failureInput.knownFailure === void 0 && failureInput.knownCause === void 0 ? await inspectJudgeSession(admitted.sessionFile) : void 0;
|
|
21749
22035
|
const failure = classifyPostAdmissionFailure({
|
|
@@ -21774,7 +22060,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21774
22060
|
env.credentials
|
|
21775
22061
|
);
|
|
21776
22062
|
if (missingCredential !== void 0) {
|
|
21777
|
-
return await
|
|
22063
|
+
return await presentControlledFailure3(
|
|
21778
22064
|
admitted,
|
|
21779
22065
|
missingCredential,
|
|
21780
22066
|
io
|
|
@@ -21805,7 +22091,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21805
22091
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
21806
22092
|
});
|
|
21807
22093
|
} catch (error) {
|
|
21808
|
-
return await
|
|
22094
|
+
return await presentControlledFailure3(
|
|
21809
22095
|
admitted,
|
|
21810
22096
|
{
|
|
21811
22097
|
timedOut: false,
|
|
@@ -21828,7 +22114,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21828
22114
|
try {
|
|
21829
22115
|
lawful = await trySettleCollectorTerminalResult(admitted);
|
|
21830
22116
|
} catch (error) {
|
|
21831
|
-
return await
|
|
22117
|
+
return await presentControlledFailure3(
|
|
21832
22118
|
admitted,
|
|
21833
22119
|
{
|
|
21834
22120
|
timedOut: false,
|
|
@@ -21866,7 +22152,7 @@ async function dispatchAdmittedCollector(input) {
|
|
|
21866
22152
|
credential: credentialFailure,
|
|
21867
22153
|
runDirectory: admitted.runDirectory
|
|
21868
22154
|
});
|
|
21869
|
-
return await
|
|
22155
|
+
return await presentControlledFailure3(
|
|
21870
22156
|
admitted,
|
|
21871
22157
|
{
|
|
21872
22158
|
timedOut: result2.timedOut,
|
|
@@ -21977,7 +22263,7 @@ function buildDoctorActivationExtraArgs(admitted, options = {}) {
|
|
|
21977
22263
|
prompt
|
|
21978
22264
|
];
|
|
21979
22265
|
}
|
|
21980
|
-
async function
|
|
22266
|
+
async function presentControlledFailure4(admitted, failureInput, io) {
|
|
21981
22267
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
21982
22268
|
const session = !hasThrown && !failureInput.timedOut && failureInput.knownFailure === void 0 ? await inspectJudgeSession(admitted.sessionFile) : void 0;
|
|
21983
22269
|
const failure = classifyPostAdmissionFailure({
|
|
@@ -22005,7 +22291,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
22005
22291
|
env.credentials
|
|
22006
22292
|
);
|
|
22007
22293
|
if (missingCredential !== void 0) {
|
|
22008
|
-
return await
|
|
22294
|
+
return await presentControlledFailure4(
|
|
22009
22295
|
admitted,
|
|
22010
22296
|
missingCredential,
|
|
22011
22297
|
io
|
|
@@ -22035,7 +22321,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
22035
22321
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
22036
22322
|
});
|
|
22037
22323
|
} catch (error) {
|
|
22038
|
-
return await
|
|
22324
|
+
return await presentControlledFailure4(
|
|
22039
22325
|
admitted,
|
|
22040
22326
|
{
|
|
22041
22327
|
timedOut: false,
|
|
@@ -22058,7 +22344,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
22058
22344
|
try {
|
|
22059
22345
|
lawful = await trySettleDoctorTerminalResult(admitted);
|
|
22060
22346
|
} catch (error) {
|
|
22061
|
-
return await
|
|
22347
|
+
return await presentControlledFailure4(
|
|
22062
22348
|
admitted,
|
|
22063
22349
|
{
|
|
22064
22350
|
timedOut: false,
|
|
@@ -22103,7 +22389,7 @@ async function dispatchAdmittedDoctor(input) {
|
|
|
22103
22389
|
credential: credentialFailure,
|
|
22104
22390
|
runDirectory: admitted.runDirectory
|
|
22105
22391
|
});
|
|
22106
|
-
return await
|
|
22392
|
+
return await presentControlledFailure4(
|
|
22107
22393
|
admitted,
|
|
22108
22394
|
{
|
|
22109
22395
|
timedOut: result2.timedOut,
|
|
@@ -22257,7 +22543,7 @@ function buildFixerResumeActivationExtraArgs(admitted, options) {
|
|
|
22257
22543
|
RESUME_TRANSPORT_ENVELOPE
|
|
22258
22544
|
];
|
|
22259
22545
|
}
|
|
22260
|
-
async function
|
|
22546
|
+
async function presentControlledFailure5(admitted, failureInput, io) {
|
|
22261
22547
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
22262
22548
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
22263
22549
|
runDirectory: admitted.runDirectory,
|
|
@@ -22310,7 +22596,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22310
22596
|
env.credentials
|
|
22311
22597
|
);
|
|
22312
22598
|
if (missingCredential !== void 0) {
|
|
22313
|
-
return await
|
|
22599
|
+
return await presentControlledFailure5(
|
|
22314
22600
|
admitted,
|
|
22315
22601
|
missingCredential,
|
|
22316
22602
|
io
|
|
@@ -22341,7 +22627,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22341
22627
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
22342
22628
|
});
|
|
22343
22629
|
} catch (error) {
|
|
22344
|
-
return await
|
|
22630
|
+
return await presentControlledFailure5(
|
|
22345
22631
|
admitted,
|
|
22346
22632
|
{
|
|
22347
22633
|
timedOut: false,
|
|
@@ -22371,7 +22657,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22371
22657
|
)
|
|
22372
22658
|
});
|
|
22373
22659
|
} catch (error) {
|
|
22374
|
-
return await
|
|
22660
|
+
return await presentControlledFailure5(
|
|
22375
22661
|
admitted,
|
|
22376
22662
|
{
|
|
22377
22663
|
timedOut: false,
|
|
@@ -22416,7 +22702,7 @@ async function dispatchAdmittedFixer(input) {
|
|
|
22416
22702
|
credential: credentialFailure,
|
|
22417
22703
|
runDirectory: admitted.runDirectory
|
|
22418
22704
|
});
|
|
22419
|
-
return await
|
|
22705
|
+
return await presentControlledFailure5(
|
|
22420
22706
|
admitted,
|
|
22421
22707
|
{
|
|
22422
22708
|
timedOut: result2.timedOut,
|
|
@@ -22470,7 +22756,7 @@ async function runPublicFixer(argv, env, io, parseFixerArgv2) {
|
|
|
22470
22756
|
methodMaterial = await loadFixerMethodMaterial(env.packageRoot);
|
|
22471
22757
|
} catch (error) {
|
|
22472
22758
|
await lease.release();
|
|
22473
|
-
return await
|
|
22759
|
+
return await presentControlledFailure5(
|
|
22474
22760
|
admitted,
|
|
22475
22761
|
{
|
|
22476
22762
|
timedOut: false,
|
|
@@ -22540,7 +22826,7 @@ async function runPublicFixerResume(argv, env, io) {
|
|
|
22540
22826
|
methodMaterial = await loadFixerMethodMaterial(env.packageRoot);
|
|
22541
22827
|
} catch (error) {
|
|
22542
22828
|
await lease.release();
|
|
22543
|
-
return await
|
|
22829
|
+
return await presentControlledFailure5(
|
|
22544
22830
|
admitted,
|
|
22545
22831
|
{
|
|
22546
22832
|
timedOut: false,
|
|
@@ -22636,7 +22922,7 @@ function buildJudgeResumeActivationExtraArgs(admitted, options = {}) {
|
|
|
22636
22922
|
RESUME_TRANSPORT_ENVELOPE
|
|
22637
22923
|
];
|
|
22638
22924
|
}
|
|
22639
|
-
async function
|
|
22925
|
+
async function presentControlledFailure6(admitted, failureInput, io) {
|
|
22640
22926
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
22641
22927
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
22642
22928
|
runDirectory: admitted.runDirectory,
|
|
@@ -22689,7 +22975,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22689
22975
|
env.credentials
|
|
22690
22976
|
);
|
|
22691
22977
|
if (missingCredential !== void 0) {
|
|
22692
|
-
return await
|
|
22978
|
+
return await presentControlledFailure6(
|
|
22693
22979
|
admitted,
|
|
22694
22980
|
missingCredential,
|
|
22695
22981
|
io
|
|
@@ -22722,7 +23008,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22722
23008
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
22723
23009
|
});
|
|
22724
23010
|
} catch (error) {
|
|
22725
|
-
return await
|
|
23011
|
+
return await presentControlledFailure6(
|
|
22726
23012
|
admitted,
|
|
22727
23013
|
{
|
|
22728
23014
|
timedOut: false,
|
|
@@ -22745,7 +23031,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22745
23031
|
try {
|
|
22746
23032
|
lawful = await trySettleJudgeTerminalResult(admitted);
|
|
22747
23033
|
} catch (error) {
|
|
22748
|
-
return await
|
|
23034
|
+
return await presentControlledFailure6(
|
|
22749
23035
|
admitted,
|
|
22750
23036
|
{
|
|
22751
23037
|
timedOut: false,
|
|
@@ -22790,7 +23076,7 @@ async function dispatchAdmittedJudge(input) {
|
|
|
22790
23076
|
credential: credentialFailure,
|
|
22791
23077
|
runDirectory: admitted.runDirectory
|
|
22792
23078
|
});
|
|
22793
|
-
return await
|
|
23079
|
+
return await presentControlledFailure6(
|
|
22794
23080
|
admitted,
|
|
22795
23081
|
{
|
|
22796
23082
|
timedOut: result2.timedOut,
|
|
@@ -22983,7 +23269,7 @@ function buildMergerResumeActivationExtraArgs(admitted, options) {
|
|
|
22983
23269
|
RESUME_TRANSPORT_ENVELOPE
|
|
22984
23270
|
];
|
|
22985
23271
|
}
|
|
22986
|
-
async function
|
|
23272
|
+
async function presentControlledFailure7(admitted, failureInput, io) {
|
|
22987
23273
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
22988
23274
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
22989
23275
|
runDirectory: admitted.runDirectory,
|
|
@@ -23039,7 +23325,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23039
23325
|
env.credentials
|
|
23040
23326
|
);
|
|
23041
23327
|
if (missingCredential !== void 0) {
|
|
23042
|
-
return await
|
|
23328
|
+
return await presentControlledFailure7(
|
|
23043
23329
|
admitted,
|
|
23044
23330
|
missingCredential,
|
|
23045
23331
|
io
|
|
@@ -23070,7 +23356,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23070
23356
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
23071
23357
|
});
|
|
23072
23358
|
} catch (error) {
|
|
23073
|
-
return await
|
|
23359
|
+
return await presentControlledFailure7(
|
|
23074
23360
|
admitted,
|
|
23075
23361
|
{
|
|
23076
23362
|
timedOut: false,
|
|
@@ -23100,7 +23386,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23100
23386
|
)
|
|
23101
23387
|
});
|
|
23102
23388
|
} catch (error) {
|
|
23103
|
-
return await
|
|
23389
|
+
return await presentControlledFailure7(
|
|
23104
23390
|
admitted,
|
|
23105
23391
|
{
|
|
23106
23392
|
timedOut: false,
|
|
@@ -23131,7 +23417,7 @@ async function dispatchAdmittedMerger(input) {
|
|
|
23131
23417
|
credential: credentialFailure,
|
|
23132
23418
|
runDirectory: admitted.runDirectory
|
|
23133
23419
|
});
|
|
23134
|
-
return await
|
|
23420
|
+
return await presentControlledFailure7(
|
|
23135
23421
|
admitted,
|
|
23136
23422
|
{
|
|
23137
23423
|
timedOut: result2.timedOut,
|
|
@@ -23237,7 +23523,7 @@ async function runPublicMerger(argv, env, io, parseMergerArgv2) {
|
|
|
23237
23523
|
...env.createRunId === void 0 ? {} : { createRunId: env.createRunId }
|
|
23238
23524
|
});
|
|
23239
23525
|
await markRunAdmitted(shell);
|
|
23240
|
-
return await
|
|
23526
|
+
return await presentControlledFailure7(
|
|
23241
23527
|
shell,
|
|
23242
23528
|
{
|
|
23243
23529
|
timedOut: false,
|
|
@@ -23268,7 +23554,7 @@ async function runPublicMerger(argv, env, io, parseMergerArgv2) {
|
|
|
23268
23554
|
methodMaterial = await loadMergerMethodMaterial(env.packageRoot);
|
|
23269
23555
|
} catch (error) {
|
|
23270
23556
|
await lease.release();
|
|
23271
|
-
return await
|
|
23557
|
+
return await presentControlledFailure7(
|
|
23272
23558
|
admitted,
|
|
23273
23559
|
{
|
|
23274
23560
|
timedOut: false,
|
|
@@ -23339,7 +23625,7 @@ async function runPublicMergerResume(argv, env, io) {
|
|
|
23339
23625
|
methodMaterial = await loadMergerMethodMaterial(env.packageRoot);
|
|
23340
23626
|
} catch (error) {
|
|
23341
23627
|
await lease.release();
|
|
23342
|
-
return await
|
|
23628
|
+
return await presentControlledFailure7(
|
|
23343
23629
|
admitted,
|
|
23344
23630
|
{
|
|
23345
23631
|
timedOut: false,
|
|
@@ -23458,7 +23744,7 @@ function buildReviewerResumeActivationExtraArgs(admitted, options) {
|
|
|
23458
23744
|
RESUME_TRANSPORT_ENVELOPE
|
|
23459
23745
|
];
|
|
23460
23746
|
}
|
|
23461
|
-
async function
|
|
23747
|
+
async function presentControlledFailure8(admitted, failureInput, io) {
|
|
23462
23748
|
const hasThrown = Object.hasOwn(failureInput, "thrown");
|
|
23463
23749
|
const resumeObservation = await resolveControlledFailureResumeObservation({
|
|
23464
23750
|
runDirectory: admitted.runDirectory,
|
|
@@ -23511,7 +23797,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23511
23797
|
env.credentials
|
|
23512
23798
|
);
|
|
23513
23799
|
if (missingCredential !== void 0) {
|
|
23514
|
-
return await
|
|
23800
|
+
return await presentControlledFailure8(
|
|
23515
23801
|
admitted,
|
|
23516
23802
|
missingCredential,
|
|
23517
23803
|
io
|
|
@@ -23543,7 +23829,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23543
23829
|
...env.piRunner === void 0 ? {} : { runner: env.piRunner }
|
|
23544
23830
|
});
|
|
23545
23831
|
} catch (error) {
|
|
23546
|
-
return await
|
|
23832
|
+
return await presentControlledFailure8(
|
|
23547
23833
|
admitted,
|
|
23548
23834
|
{
|
|
23549
23835
|
timedOut: false,
|
|
@@ -23573,7 +23859,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23573
23859
|
)
|
|
23574
23860
|
});
|
|
23575
23861
|
} catch (error) {
|
|
23576
|
-
return await
|
|
23862
|
+
return await presentControlledFailure8(
|
|
23577
23863
|
admitted,
|
|
23578
23864
|
{
|
|
23579
23865
|
timedOut: false,
|
|
@@ -23618,7 +23904,7 @@ async function dispatchAdmittedReviewer(input) {
|
|
|
23618
23904
|
credential: credentialFailure,
|
|
23619
23905
|
runDirectory: admitted.runDirectory
|
|
23620
23906
|
});
|
|
23621
|
-
return await
|
|
23907
|
+
return await presentControlledFailure8(
|
|
23622
23908
|
admitted,
|
|
23623
23909
|
{
|
|
23624
23910
|
timedOut: result2.timedOut,
|
|
@@ -23672,7 +23958,7 @@ async function runPublicReviewer(argv, env, io, parseReviewerArgv2) {
|
|
|
23672
23958
|
methodMaterial = await loadReviewerMethodMaterial(env.packageRoot);
|
|
23673
23959
|
} catch (error) {
|
|
23674
23960
|
await lease.release();
|
|
23675
|
-
return await
|
|
23961
|
+
return await presentControlledFailure8(
|
|
23676
23962
|
admitted,
|
|
23677
23963
|
{
|
|
23678
23964
|
timedOut: false,
|
|
@@ -23742,7 +24028,7 @@ async function runPublicReviewerResume(argv, env, io) {
|
|
|
23742
24028
|
methodMaterial = await loadReviewerMethodMaterial(env.packageRoot);
|
|
23743
24029
|
} catch (error) {
|
|
23744
24030
|
await lease.release();
|
|
23745
|
-
return await
|
|
24031
|
+
return await presentControlledFailure8(
|
|
23746
24032
|
admitted,
|
|
23747
24033
|
{
|
|
23748
24034
|
timedOut: false,
|
|
@@ -23784,31 +24070,2089 @@ var init_reviewer_run = __esm({
|
|
|
23784
24070
|
}
|
|
23785
24071
|
});
|
|
23786
24072
|
|
|
23787
|
-
// src/
|
|
23788
|
-
|
|
23789
|
-
|
|
23790
|
-
|
|
23791
|
-
|
|
23792
|
-
|
|
23793
|
-
|
|
23794
|
-
|
|
23795
|
-
|
|
23796
|
-
|
|
23797
|
-
|
|
23798
|
-
|
|
23799
|
-
|
|
23800
|
-
function takePublicGlobalFlag(argv, index) {
|
|
23801
|
-
const token = argv[index];
|
|
23802
|
-
if (token === void 0) return void 0;
|
|
23803
|
-
if (token === "--help" || token === "-h") {
|
|
23804
|
-
return { flag: "help", consume: 1 };
|
|
24073
|
+
// src/atomic-write.ts
|
|
24074
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
24075
|
+
import { rename, rm, writeFile as writeFile13 } from "node:fs/promises";
|
|
24076
|
+
import { dirname as dirname7, join as join18 } from "node:path";
|
|
24077
|
+
async function writeFileAtomically(destination, contents) {
|
|
24078
|
+
const parent = dirname7(destination);
|
|
24079
|
+
const temporary = join18(parent, `.atomic-write-${randomUUID2()}.tmp`);
|
|
24080
|
+
try {
|
|
24081
|
+
await writeFile13(temporary, contents);
|
|
24082
|
+
await rename(temporary, destination);
|
|
24083
|
+
} catch (error) {
|
|
24084
|
+
await rm(temporary, { force: true }).catch(() => void 0);
|
|
24085
|
+
throw error;
|
|
23805
24086
|
}
|
|
23806
|
-
|
|
23807
|
-
|
|
23808
|
-
|
|
23809
|
-
|
|
24087
|
+
}
|
|
24088
|
+
var init_atomic_write = __esm({
|
|
24089
|
+
"src/atomic-write.ts"() {
|
|
24090
|
+
"use strict";
|
|
24091
|
+
}
|
|
24092
|
+
});
|
|
24093
|
+
|
|
24094
|
+
// src/taishi-index.ts
|
|
24095
|
+
import { open as open3, readFile as readFile10, unlink as unlink4 } from "node:fs/promises";
|
|
24096
|
+
import { dirname as dirname8, join as join19 } from "node:path";
|
|
24097
|
+
function sleep(ms) {
|
|
24098
|
+
return new Promise((resolve9) => {
|
|
24099
|
+
setTimeout(resolve9, ms);
|
|
24100
|
+
});
|
|
24101
|
+
}
|
|
24102
|
+
async function withTaishiLibraryIndexLock(ledgerHome, fn) {
|
|
24103
|
+
const indexPath = taishiLibraryIndexPath(ledgerHome);
|
|
24104
|
+
ensureRealDirectoryTree(ledgerHome, dirname8(indexPath));
|
|
24105
|
+
const lockPath = join19(dirname8(indexPath), LIBRARY_INDEX_LOCK_NAME);
|
|
24106
|
+
assertLedgerFileInsideHome(lockPath, ledgerHome);
|
|
24107
|
+
const startedAt = Date.now();
|
|
24108
|
+
while (true) {
|
|
24109
|
+
try {
|
|
24110
|
+
const handle = await open3(lockPath, "wx");
|
|
24111
|
+
try {
|
|
24112
|
+
await handle.writeFile(`${process.pid}
|
|
24113
|
+
`, "utf8");
|
|
24114
|
+
return await fn();
|
|
24115
|
+
} finally {
|
|
24116
|
+
await handle.close().catch(() => void 0);
|
|
24117
|
+
await unlink4(lockPath).catch(() => void 0);
|
|
24118
|
+
}
|
|
24119
|
+
} catch (error) {
|
|
24120
|
+
const code = error instanceof Error && "code" in error ? error.code : void 0;
|
|
24121
|
+
if (code !== "EEXIST") throw error;
|
|
24122
|
+
if (Date.now() - startedAt > LIBRARY_INDEX_LOCK_TIMEOUT_MS) {
|
|
24123
|
+
throw new Error(
|
|
24124
|
+
`taishi library-index lock timeout after ${LIBRARY_INDEX_LOCK_TIMEOUT_MS}ms: ${lockPath}`
|
|
24125
|
+
);
|
|
24126
|
+
}
|
|
24127
|
+
await sleep(LIBRARY_INDEX_LOCK_RETRY_MS);
|
|
23810
24128
|
}
|
|
23811
|
-
|
|
24129
|
+
}
|
|
24130
|
+
}
|
|
24131
|
+
function taishiLibraryIndexPath(ledgerHome) {
|
|
24132
|
+
return join19(ledgerHome, "taishi", "library-index.json");
|
|
24133
|
+
}
|
|
24134
|
+
function rowFromIssueMetricsPage(page) {
|
|
24135
|
+
return {
|
|
24136
|
+
projectRoot: page.projectRoot,
|
|
24137
|
+
// exactOptionalPropertyTypes: only materialize when page carries it.
|
|
24138
|
+
...page.issueNumber === void 0 ? {} : { issueNumber: page.issueNumber },
|
|
24139
|
+
totalElapsedMs: page.totalElapsedMs,
|
|
24140
|
+
changedLines: page.changedLines,
|
|
24141
|
+
msPerKLines: page.msPerKLines,
|
|
24142
|
+
lastActivityAt: page.lastActivityAt
|
|
24143
|
+
};
|
|
24144
|
+
}
|
|
24145
|
+
function sortRows(rows) {
|
|
24146
|
+
return [...rows].sort((a, b) => {
|
|
24147
|
+
const byRoot = a.projectRoot.localeCompare(b.projectRoot);
|
|
24148
|
+
if (byRoot !== 0) return byRoot;
|
|
24149
|
+
const aNum = a.issueNumber;
|
|
24150
|
+
const bNum = b.issueNumber;
|
|
24151
|
+
if (aNum === void 0 && bNum === void 0) return 0;
|
|
24152
|
+
if (aNum === void 0) return 1;
|
|
24153
|
+
if (bNum === void 0) return -1;
|
|
24154
|
+
return aNum - bNum;
|
|
24155
|
+
});
|
|
24156
|
+
}
|
|
24157
|
+
function buildTaishiLibraryIndexPage(rows) {
|
|
24158
|
+
return {
|
|
24159
|
+
kind: "taishi-library-index",
|
|
24160
|
+
rows: sortRows(rows)
|
|
24161
|
+
};
|
|
24162
|
+
}
|
|
24163
|
+
function findTaishiLibraryIndexRow(index, issueNumber) {
|
|
24164
|
+
if (index === void 0) return void 0;
|
|
24165
|
+
return index.rows.find((row) => row.issueNumber === issueNumber);
|
|
24166
|
+
}
|
|
24167
|
+
function upsertTaishiLibraryIndexRows(existing, upserts) {
|
|
24168
|
+
const byRoot = /* @__PURE__ */ new Map();
|
|
24169
|
+
const rootByIssue = /* @__PURE__ */ new Map();
|
|
24170
|
+
const ingest = (row) => {
|
|
24171
|
+
if (row.issueNumber !== void 0) {
|
|
24172
|
+
const priorRoot = rootByIssue.get(row.issueNumber);
|
|
24173
|
+
if (priorRoot !== void 0 && priorRoot !== row.projectRoot) {
|
|
24174
|
+
byRoot.delete(priorRoot);
|
|
24175
|
+
}
|
|
24176
|
+
}
|
|
24177
|
+
const prior = byRoot.get(row.projectRoot);
|
|
24178
|
+
if (prior !== void 0 && prior.issueNumber !== void 0 && prior.issueNumber !== row.issueNumber) {
|
|
24179
|
+
rootByIssue.delete(prior.issueNumber);
|
|
24180
|
+
}
|
|
24181
|
+
byRoot.set(row.projectRoot, row);
|
|
24182
|
+
if (row.issueNumber !== void 0) {
|
|
24183
|
+
rootByIssue.set(row.issueNumber, row.projectRoot);
|
|
24184
|
+
}
|
|
24185
|
+
};
|
|
24186
|
+
if (existing !== void 0) {
|
|
24187
|
+
for (const row of existing.rows) {
|
|
24188
|
+
ingest(row);
|
|
24189
|
+
}
|
|
24190
|
+
}
|
|
24191
|
+
for (const row of upserts) {
|
|
24192
|
+
ingest(row);
|
|
24193
|
+
}
|
|
24194
|
+
return buildTaishiLibraryIndexPage([...byRoot.values()]);
|
|
24195
|
+
}
|
|
24196
|
+
async function readTaishiLibraryIndexPage(ledgerHome) {
|
|
24197
|
+
const path = taishiLibraryIndexPath(ledgerHome);
|
|
24198
|
+
let raw;
|
|
24199
|
+
try {
|
|
24200
|
+
raw = await readFile10(path, "utf8");
|
|
24201
|
+
} catch (error) {
|
|
24202
|
+
if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
24203
|
+
return void 0;
|
|
24204
|
+
}
|
|
24205
|
+
throw error;
|
|
24206
|
+
}
|
|
24207
|
+
return JSON.parse(raw);
|
|
24208
|
+
}
|
|
24209
|
+
async function writeTaishiLibraryIndexPage(ledgerHome, page) {
|
|
24210
|
+
const path = taishiLibraryIndexPath(ledgerHome);
|
|
24211
|
+
ensureRealDirectoryTree(ledgerHome, dirname8(path));
|
|
24212
|
+
assertLedgerFileInsideHome(path, ledgerHome);
|
|
24213
|
+
await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
|
|
24214
|
+
`);
|
|
24215
|
+
return path;
|
|
24216
|
+
}
|
|
24217
|
+
async function mergeTaishiLibraryIndexRows(ledgerHome, upserts) {
|
|
24218
|
+
return withTaishiLibraryIndexLock(ledgerHome, async () => {
|
|
24219
|
+
const existing = await readTaishiLibraryIndexPage(ledgerHome);
|
|
24220
|
+
const index = upsertTaishiLibraryIndexRows(existing, upserts);
|
|
24221
|
+
const indexPath = await writeTaishiLibraryIndexPage(ledgerHome, index);
|
|
24222
|
+
return { index, indexPath };
|
|
24223
|
+
});
|
|
24224
|
+
}
|
|
24225
|
+
var LIBRARY_INDEX_LOCK_NAME, LIBRARY_INDEX_LOCK_TIMEOUT_MS, LIBRARY_INDEX_LOCK_RETRY_MS;
|
|
24226
|
+
var init_taishi_index = __esm({
|
|
24227
|
+
"src/taishi-index.ts"() {
|
|
24228
|
+
"use strict";
|
|
24229
|
+
init_atomic_write();
|
|
24230
|
+
init_activation_ledger_topology();
|
|
24231
|
+
LIBRARY_INDEX_LOCK_NAME = ".library-index.lock";
|
|
24232
|
+
LIBRARY_INDEX_LOCK_TIMEOUT_MS = 3e4;
|
|
24233
|
+
LIBRARY_INDEX_LOCK_RETRY_MS = 15;
|
|
24234
|
+
}
|
|
24235
|
+
});
|
|
24236
|
+
|
|
24237
|
+
// src/taishi-median.ts
|
|
24238
|
+
function medianNumber(values) {
|
|
24239
|
+
if (values.length === 0) return void 0;
|
|
24240
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
24241
|
+
const mid = Math.floor(sorted.length / 2);
|
|
24242
|
+
if (sorted.length % 2 === 1) {
|
|
24243
|
+
return sorted[mid];
|
|
24244
|
+
}
|
|
24245
|
+
return (sorted[mid - 1] + sorted[mid]) / 2;
|
|
24246
|
+
}
|
|
24247
|
+
var init_taishi_median = __esm({
|
|
24248
|
+
"src/taishi-median.ts"() {
|
|
24249
|
+
"use strict";
|
|
24250
|
+
}
|
|
24251
|
+
});
|
|
24252
|
+
|
|
24253
|
+
// src/taishi-cohort.ts
|
|
24254
|
+
function presentMetric(value) {
|
|
24255
|
+
return { status: "present", value };
|
|
24256
|
+
}
|
|
24257
|
+
function rateMetric(numerator, denominator) {
|
|
24258
|
+
if (denominator === 0) return ABSENT;
|
|
24259
|
+
return presentMetric(numerator / denominator);
|
|
24260
|
+
}
|
|
24261
|
+
function optionalMedian(values) {
|
|
24262
|
+
const median = medianNumber(values);
|
|
24263
|
+
return median === void 0 ? ABSENT : presentMetric(median);
|
|
24264
|
+
}
|
|
24265
|
+
function emptyRoleAccum() {
|
|
24266
|
+
return {
|
|
24267
|
+
convergenceRounds: [],
|
|
24268
|
+
firstPassLaneCount: 0,
|
|
24269
|
+
appearanceLaneCount: 0,
|
|
24270
|
+
successCount: 0,
|
|
24271
|
+
successEligibleCount: 0
|
|
24272
|
+
};
|
|
24273
|
+
}
|
|
24274
|
+
function absorbRole(accum, stats) {
|
|
24275
|
+
accum.convergenceRounds.push(...stats.convergenceRounds);
|
|
24276
|
+
accum.firstPassLaneCount += stats.firstPassLaneCount;
|
|
24277
|
+
accum.appearanceLaneCount += stats.appearanceLaneCount;
|
|
24278
|
+
accum.successCount += stats.successCount;
|
|
24279
|
+
accum.successEligibleCount += stats.successEligibleCount;
|
|
24280
|
+
}
|
|
24281
|
+
function finishRole(role, accum) {
|
|
24282
|
+
return {
|
|
24283
|
+
role,
|
|
24284
|
+
convergenceRounds: accum.convergenceRounds,
|
|
24285
|
+
convergenceRoundsMedian: optionalMedian(accum.convergenceRounds),
|
|
24286
|
+
firstPassRate: rateMetric(accum.firstPassLaneCount, accum.appearanceLaneCount),
|
|
24287
|
+
successRate: rateMetric(accum.successCount, accum.successEligibleCount)
|
|
24288
|
+
};
|
|
24289
|
+
}
|
|
24290
|
+
async function aggregateGroup(index, input, ensureIssuePage) {
|
|
24291
|
+
const issueEntries = [];
|
|
24292
|
+
const roleAccums = /* @__PURE__ */ new Map();
|
|
24293
|
+
let reworkWallMs = 0;
|
|
24294
|
+
let totalWallMs = 0;
|
|
24295
|
+
let hasReworkSample = false;
|
|
24296
|
+
const legWalls = [];
|
|
24297
|
+
for (const issueNumber of input.issues) {
|
|
24298
|
+
const row = findTaishiLibraryIndexRow(index, issueNumber);
|
|
24299
|
+
if (row === void 0) {
|
|
24300
|
+
issueEntries.push({ issueNumber, status: "absent" });
|
|
24301
|
+
continue;
|
|
24302
|
+
}
|
|
24303
|
+
const page = await ensureIssuePage({
|
|
24304
|
+
projectRoot: row.projectRoot,
|
|
24305
|
+
issueNumber
|
|
24306
|
+
});
|
|
24307
|
+
issueEntries.push({
|
|
24308
|
+
issueNumber,
|
|
24309
|
+
status: "present",
|
|
24310
|
+
projectRoot: row.projectRoot
|
|
24311
|
+
});
|
|
24312
|
+
const acceptance = page.acceptanceSuccessRework;
|
|
24313
|
+
if (acceptance !== void 0) {
|
|
24314
|
+
for (const roleStats of acceptance.byRole) {
|
|
24315
|
+
const accum = roleAccums.get(roleStats.role) ?? emptyRoleAccum();
|
|
24316
|
+
absorbRole(accum, roleStats);
|
|
24317
|
+
roleAccums.set(roleStats.role, accum);
|
|
24318
|
+
}
|
|
24319
|
+
reworkWallMs += acceptance.rework.reworkWallMs;
|
|
24320
|
+
totalWallMs += acceptance.rework.totalWallMs;
|
|
24321
|
+
hasReworkSample = true;
|
|
24322
|
+
}
|
|
24323
|
+
const legWallClock = page.legWallClock;
|
|
24324
|
+
if (legWallClock !== void 0) {
|
|
24325
|
+
for (const leg of legWallClock.ranking) {
|
|
24326
|
+
legWalls.push(leg.wallMs);
|
|
24327
|
+
}
|
|
24328
|
+
}
|
|
24329
|
+
}
|
|
24330
|
+
const byRole = [...roleAccums.keys()].sort((a, b) => a.localeCompare(b)).map((role) => finishRole(role, roleAccums.get(role)));
|
|
24331
|
+
return {
|
|
24332
|
+
groupLabel: input.groupLabel,
|
|
24333
|
+
issues: issueEntries,
|
|
24334
|
+
byRole,
|
|
24335
|
+
reworkRatio: hasReworkSample ? rateMetric(reworkWallMs, totalWallMs) : ABSENT,
|
|
24336
|
+
medianWallMs: optionalMedian(legWalls)
|
|
24337
|
+
};
|
|
24338
|
+
}
|
|
24339
|
+
async function runTaishiCohortMode(ledgerHome, input, ensureIssuePage) {
|
|
24340
|
+
const index = await readTaishiLibraryIndexPage(ledgerHome);
|
|
24341
|
+
const group0 = await aggregateGroup(index, input.groups[0], ensureIssuePage);
|
|
24342
|
+
const group1 = await aggregateGroup(index, input.groups[1], ensureIssuePage);
|
|
24343
|
+
return {
|
|
24344
|
+
mode: "cohort",
|
|
24345
|
+
groups: [group0, group1]
|
|
24346
|
+
};
|
|
24347
|
+
}
|
|
24348
|
+
var ABSENT;
|
|
24349
|
+
var init_taishi_cohort = __esm({
|
|
24350
|
+
"src/taishi-cohort.ts"() {
|
|
24351
|
+
"use strict";
|
|
24352
|
+
init_taishi_index();
|
|
24353
|
+
init_taishi_median();
|
|
24354
|
+
ABSENT = { status: "absent" };
|
|
24355
|
+
}
|
|
24356
|
+
});
|
|
24357
|
+
|
|
24358
|
+
// src/ledger-session-read.ts
|
|
24359
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
24360
|
+
function isRecord6(value) {
|
|
24361
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24362
|
+
}
|
|
24363
|
+
async function readLedgerSessionJsonl(path) {
|
|
24364
|
+
const text = await readFile11(path, "utf8");
|
|
24365
|
+
const lines = text.split("\n");
|
|
24366
|
+
const rows = [];
|
|
24367
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
24368
|
+
const line2 = lines[index];
|
|
24369
|
+
if (!line2.trim()) continue;
|
|
24370
|
+
let row;
|
|
24371
|
+
try {
|
|
24372
|
+
row = JSON.parse(line2);
|
|
24373
|
+
} catch (error) {
|
|
24374
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
24375
|
+
const completedByTerminator = index < lines.length - 1;
|
|
24376
|
+
if (completedByTerminator) {
|
|
24377
|
+
throw new LedgerSessionJsonlError(
|
|
24378
|
+
`malformed JSONL record in ${path} at line ${index + 1}: ${error.message}`,
|
|
24379
|
+
{ path, line: index + 1, prefixRows: rows }
|
|
24380
|
+
);
|
|
24381
|
+
}
|
|
24382
|
+
break;
|
|
24383
|
+
}
|
|
24384
|
+
if (!isRecord6(row)) {
|
|
24385
|
+
const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
|
|
24386
|
+
throw new LedgerSessionJsonlError(
|
|
24387
|
+
`complete non-object JSONL record in ${path} at line ${index + 1}: expected object, got ${kind}`,
|
|
24388
|
+
{ path, line: index + 1, prefixRows: rows }
|
|
24389
|
+
);
|
|
24390
|
+
}
|
|
24391
|
+
rows.push(row);
|
|
24392
|
+
}
|
|
24393
|
+
return rows;
|
|
24394
|
+
}
|
|
24395
|
+
function extractSessionTimestampSpan(rows) {
|
|
24396
|
+
let startedAt;
|
|
24397
|
+
let endedAt;
|
|
24398
|
+
for (const row of rows) {
|
|
24399
|
+
if (typeof row.timestamp !== "string" || !row.timestamp) continue;
|
|
24400
|
+
if (startedAt === void 0) startedAt = row.timestamp;
|
|
24401
|
+
endedAt = row.timestamp;
|
|
24402
|
+
}
|
|
24403
|
+
return {
|
|
24404
|
+
...startedAt !== void 0 ? { startedAt } : {},
|
|
24405
|
+
...endedAt !== void 0 ? { endedAt } : {}
|
|
24406
|
+
};
|
|
24407
|
+
}
|
|
24408
|
+
function extractSessionModelSequence(rows) {
|
|
24409
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24410
|
+
const ordered = [];
|
|
24411
|
+
const push = (raw) => {
|
|
24412
|
+
const model = raw.trim();
|
|
24413
|
+
if (model === "" || seen.has(model)) return;
|
|
24414
|
+
seen.add(model);
|
|
24415
|
+
ordered.push(model);
|
|
24416
|
+
};
|
|
24417
|
+
for (const row of rows) {
|
|
24418
|
+
if (row.type === "model_change" && typeof row.modelId === "string") {
|
|
24419
|
+
push(row.modelId);
|
|
24420
|
+
}
|
|
24421
|
+
const message = isRecord6(row.message) ? row.message : void 0;
|
|
24422
|
+
if (message?.role === "assistant" && typeof message.model === "string") {
|
|
24423
|
+
push(message.model);
|
|
24424
|
+
}
|
|
24425
|
+
}
|
|
24426
|
+
return ordered;
|
|
24427
|
+
}
|
|
24428
|
+
function bashCommandFirstLine(command) {
|
|
24429
|
+
const match = /^[^\r\n]*/.exec(command);
|
|
24430
|
+
return match?.[0] ?? "";
|
|
24431
|
+
}
|
|
24432
|
+
function extractSessionToolIntervals(rows) {
|
|
24433
|
+
const order = [];
|
|
24434
|
+
const openById = /* @__PURE__ */ new Map();
|
|
24435
|
+
for (const row of rows) {
|
|
24436
|
+
const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
|
|
24437
|
+
const message = isRecord6(row.message) ? row.message : void 0;
|
|
24438
|
+
if (message?.role === "assistant" && Array.isArray(message.content)) {
|
|
24439
|
+
const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
|
|
24440
|
+
for (const part of message.content) {
|
|
24441
|
+
if (!isRecord6(part) || part.type !== "toolCall") continue;
|
|
24442
|
+
if (typeof part.id !== "string" || part.id.length === 0) {
|
|
24443
|
+
throw new Error("toolCall frame missing string id");
|
|
24444
|
+
}
|
|
24445
|
+
if (typeof part.name !== "string" || part.name.length === 0) {
|
|
24446
|
+
throw new Error(`toolCall ${part.id} missing string name`);
|
|
24447
|
+
}
|
|
24448
|
+
if (callTimestamp === void 0 || callTimestamp.length === 0) {
|
|
24449
|
+
throw new Error(`toolCall ${part.id} missing timestamp`);
|
|
24450
|
+
}
|
|
24451
|
+
if (openById.has(part.id)) {
|
|
24452
|
+
throw new Error(`duplicate toolCall id ${part.id}`);
|
|
24453
|
+
}
|
|
24454
|
+
const args = isRecord6(part.arguments) ? part.arguments : void 0;
|
|
24455
|
+
const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
|
|
24456
|
+
const interval = {
|
|
24457
|
+
toolCallId: part.id,
|
|
24458
|
+
toolName: part.name,
|
|
24459
|
+
startedAt: callTimestamp,
|
|
24460
|
+
...command !== void 0 ? { command } : {}
|
|
24461
|
+
};
|
|
24462
|
+
order.push(interval);
|
|
24463
|
+
openById.set(part.id, interval);
|
|
24464
|
+
}
|
|
24465
|
+
}
|
|
24466
|
+
if (message?.role === "toolResult") {
|
|
24467
|
+
if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) {
|
|
24468
|
+
throw new Error("toolResult frame missing string toolCallId");
|
|
24469
|
+
}
|
|
24470
|
+
const resultTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
|
|
24471
|
+
if (resultTimestamp === void 0 || resultTimestamp.length === 0) {
|
|
24472
|
+
throw new Error(`toolResult ${message.toolCallId} missing timestamp`);
|
|
24473
|
+
}
|
|
24474
|
+
const open4 = openById.get(message.toolCallId);
|
|
24475
|
+
if (open4 === void 0) {
|
|
24476
|
+
const toolName = typeof message.toolName === "string" && message.toolName.length > 0 ? message.toolName : "unknown";
|
|
24477
|
+
order.push({
|
|
24478
|
+
toolCallId: message.toolCallId,
|
|
24479
|
+
toolName,
|
|
24480
|
+
startedAt: resultTimestamp,
|
|
24481
|
+
endedAt: resultTimestamp
|
|
24482
|
+
});
|
|
24483
|
+
continue;
|
|
24484
|
+
}
|
|
24485
|
+
if (open4.endedAt !== void 0) {
|
|
24486
|
+
throw new Error(`duplicate toolResult for toolCallId ${message.toolCallId}`);
|
|
24487
|
+
}
|
|
24488
|
+
open4.endedAt = resultTimestamp;
|
|
24489
|
+
}
|
|
24490
|
+
}
|
|
24491
|
+
return order.map((interval) => {
|
|
24492
|
+
const base = {
|
|
24493
|
+
toolCallId: interval.toolCallId,
|
|
24494
|
+
toolName: interval.toolName,
|
|
24495
|
+
startedAt: interval.startedAt,
|
|
24496
|
+
...interval.command !== void 0 ? { command: interval.command } : {}
|
|
24497
|
+
};
|
|
24498
|
+
return interval.endedAt === void 0 ? base : { ...base, endedAt: interval.endedAt };
|
|
24499
|
+
});
|
|
24500
|
+
}
|
|
24501
|
+
var LedgerSessionJsonlError;
|
|
24502
|
+
var init_ledger_session_read = __esm({
|
|
24503
|
+
"src/ledger-session-read.ts"() {
|
|
24504
|
+
"use strict";
|
|
24505
|
+
LedgerSessionJsonlError = class extends Error {
|
|
24506
|
+
path;
|
|
24507
|
+
line;
|
|
24508
|
+
prefixRows;
|
|
24509
|
+
constructor(message, init) {
|
|
24510
|
+
super(message);
|
|
24511
|
+
this.name = "LedgerSessionJsonlError";
|
|
24512
|
+
this.path = init.path;
|
|
24513
|
+
this.line = init.line;
|
|
24514
|
+
this.prefixRows = init.prefixRows;
|
|
24515
|
+
}
|
|
24516
|
+
};
|
|
24517
|
+
}
|
|
24518
|
+
});
|
|
24519
|
+
|
|
24520
|
+
// src/run-terminal-artifacts.ts
|
|
24521
|
+
import { readdir as readdir4, readFile as readFile12 } from "node:fs/promises";
|
|
24522
|
+
import { basename as basename4, dirname as dirname9, join as join20 } from "node:path";
|
|
24523
|
+
function isMissingPathError3(error) {
|
|
24524
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
24525
|
+
}
|
|
24526
|
+
function errorText2(error) {
|
|
24527
|
+
return error instanceof Error ? error.message : String(error);
|
|
24528
|
+
}
|
|
24529
|
+
function isRecord7(value) {
|
|
24530
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24531
|
+
}
|
|
24532
|
+
function readUsableTerminalArtifactBody(body) {
|
|
24533
|
+
if (body === null) {
|
|
24534
|
+
return { ok: false, reason: "terminal artifact JSON value is null" };
|
|
24535
|
+
}
|
|
24536
|
+
if (!isRecord7(body)) {
|
|
24537
|
+
return {
|
|
24538
|
+
ok: false,
|
|
24539
|
+
reason: `terminal artifact JSON value is not a typed object (${Array.isArray(body) ? "array" : typeof body})`
|
|
24540
|
+
};
|
|
24541
|
+
}
|
|
24542
|
+
if (typeof body.role !== "string" || body.role.trim() === "") {
|
|
24543
|
+
return {
|
|
24544
|
+
ok: false,
|
|
24545
|
+
reason: "terminal artifact missing nonblank producer-owned role field"
|
|
24546
|
+
};
|
|
24547
|
+
}
|
|
24548
|
+
return { ok: true, body };
|
|
24549
|
+
}
|
|
24550
|
+
async function readTerminalArtifactAtPath(path, file) {
|
|
24551
|
+
let raw;
|
|
24552
|
+
try {
|
|
24553
|
+
raw = await readFile12(path, "utf8");
|
|
24554
|
+
} catch (error) {
|
|
24555
|
+
if (isMissingPathError3(error)) return void 0;
|
|
24556
|
+
return {
|
|
24557
|
+
status: "unreadable",
|
|
24558
|
+
file,
|
|
24559
|
+
path,
|
|
24560
|
+
reason: errorText2(error)
|
|
24561
|
+
};
|
|
24562
|
+
}
|
|
24563
|
+
let parsed;
|
|
24564
|
+
try {
|
|
24565
|
+
parsed = JSON.parse(raw);
|
|
24566
|
+
} catch (error) {
|
|
24567
|
+
return {
|
|
24568
|
+
status: "unreadable",
|
|
24569
|
+
file,
|
|
24570
|
+
path,
|
|
24571
|
+
reason: error instanceof Error ? error.message : `terminal artifact JSON parse failed: ${String(error)}`
|
|
24572
|
+
};
|
|
24573
|
+
}
|
|
24574
|
+
const usable = readUsableTerminalArtifactBody(parsed);
|
|
24575
|
+
if (!usable.ok) {
|
|
24576
|
+
return {
|
|
24577
|
+
status: "unreadable",
|
|
24578
|
+
file,
|
|
24579
|
+
path,
|
|
24580
|
+
reason: usable.reason
|
|
24581
|
+
};
|
|
24582
|
+
}
|
|
24583
|
+
return { status: "present", file, path, body: usable.body };
|
|
24584
|
+
}
|
|
24585
|
+
async function listUniqueErrorFallbackPaths(directories) {
|
|
24586
|
+
const found = [];
|
|
24587
|
+
for (const dir of directories) {
|
|
24588
|
+
let names;
|
|
24589
|
+
try {
|
|
24590
|
+
names = await readdir4(dir);
|
|
24591
|
+
} catch (error) {
|
|
24592
|
+
if (isMissingPathError3(error)) continue;
|
|
24593
|
+
throw error;
|
|
24594
|
+
}
|
|
24595
|
+
for (const name of names.sort((a, b) => a.localeCompare(b))) {
|
|
24596
|
+
if (!UNIQUE_ERROR_FALLBACK_NAME.test(name)) continue;
|
|
24597
|
+
found.push(join20(dir, name));
|
|
24598
|
+
}
|
|
24599
|
+
}
|
|
24600
|
+
return found;
|
|
24601
|
+
}
|
|
24602
|
+
function runIdFromRunDirectory(runDirectory) {
|
|
24603
|
+
const name = basename4(runDirectory);
|
|
24604
|
+
const at = name.lastIndexOf("@");
|
|
24605
|
+
if (at <= 0 || at === name.length - 1) return void 0;
|
|
24606
|
+
return name.slice(0, at);
|
|
24607
|
+
}
|
|
24608
|
+
function presentUniqueFallbackBoundToRun(body, expectedRunId) {
|
|
24609
|
+
if (expectedRunId === void 0) return false;
|
|
24610
|
+
return typeof body.runId === "string" && body.runId === expectedRunId;
|
|
24611
|
+
}
|
|
24612
|
+
async function readRunTerminalArtifact(runDirectory) {
|
|
24613
|
+
const artifactsDir = join20(runDirectory, "artifacts");
|
|
24614
|
+
for (const file of RUN_TERMINAL_ARTIFACT_FILES) {
|
|
24615
|
+
const path = join20(artifactsDir, file);
|
|
24616
|
+
const read3 = await readTerminalArtifactAtPath(path, file);
|
|
24617
|
+
if (read3 !== void 0) return read3;
|
|
24618
|
+
}
|
|
24619
|
+
for (const relative3 of RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS) {
|
|
24620
|
+
const path = join20(runDirectory, relative3);
|
|
24621
|
+
const read3 = await readTerminalArtifactAtPath(path, "error.json");
|
|
24622
|
+
if (read3 !== void 0) return read3;
|
|
24623
|
+
}
|
|
24624
|
+
for (const path of await listUniqueErrorFallbackPaths([artifactsDir, runDirectory])) {
|
|
24625
|
+
const read3 = await readTerminalArtifactAtPath(path, "error.json");
|
|
24626
|
+
if (read3 !== void 0) return read3;
|
|
24627
|
+
}
|
|
24628
|
+
const expectedRunId = runIdFromRunDirectory(runDirectory);
|
|
24629
|
+
for (const path of await listUniqueErrorFallbackPaths([dirname9(runDirectory)])) {
|
|
24630
|
+
const read3 = await readTerminalArtifactAtPath(path, "error.json");
|
|
24631
|
+
if (read3 === void 0) continue;
|
|
24632
|
+
if (read3.status === "present") {
|
|
24633
|
+
if (!presentUniqueFallbackBoundToRun(read3.body, expectedRunId)) continue;
|
|
24634
|
+
return read3;
|
|
24635
|
+
}
|
|
24636
|
+
}
|
|
24637
|
+
return { status: "absent" };
|
|
24638
|
+
}
|
|
24639
|
+
var RUN_TERMINAL_ARTIFACT_FILES, RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS, UNIQUE_ERROR_FALLBACK_NAME;
|
|
24640
|
+
var init_run_terminal_artifacts = __esm({
|
|
24641
|
+
"src/run-terminal-artifacts.ts"() {
|
|
24642
|
+
"use strict";
|
|
24643
|
+
RUN_TERMINAL_ARTIFACT_FILES = [
|
|
24644
|
+
"report.json",
|
|
24645
|
+
"error.json",
|
|
24646
|
+
"audit-incomplete.json"
|
|
24647
|
+
];
|
|
24648
|
+
RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS = [
|
|
24649
|
+
"artifacts/error.settlement.json",
|
|
24650
|
+
"error.settlement.json"
|
|
24651
|
+
];
|
|
24652
|
+
UNIQUE_ERROR_FALLBACK_NAME = /^error\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.json$/i;
|
|
24653
|
+
}
|
|
24654
|
+
});
|
|
24655
|
+
|
|
24656
|
+
// src/taishi-ledger.ts
|
|
24657
|
+
import { readdir as readdir5, readFile as readFile13 } from "node:fs/promises";
|
|
24658
|
+
import { join as join21 } from "node:path";
|
|
24659
|
+
function isMissingPathError4(error) {
|
|
24660
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
24661
|
+
}
|
|
24662
|
+
function errorText3(error) {
|
|
24663
|
+
return error instanceof Error ? error.message : String(error);
|
|
24664
|
+
}
|
|
24665
|
+
function isRecord8(value) {
|
|
24666
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24667
|
+
}
|
|
24668
|
+
async function readExistingRunLifecycleState(runDirectory) {
|
|
24669
|
+
try {
|
|
24670
|
+
const raw = JSON.parse(
|
|
24671
|
+
await readFile13(join21(runDirectory, "run-state.json"), "utf8")
|
|
24672
|
+
);
|
|
24673
|
+
if (!isRecord8(raw) || typeof raw.state !== "string") return void 0;
|
|
24674
|
+
return raw.state;
|
|
24675
|
+
} catch {
|
|
24676
|
+
return void 0;
|
|
24677
|
+
}
|
|
24678
|
+
}
|
|
24679
|
+
function parseRunDirectoryName(name) {
|
|
24680
|
+
const at = name.lastIndexOf("@");
|
|
24681
|
+
if (at <= 0 || at === name.length - 1) return void 0;
|
|
24682
|
+
return { runId: name.slice(0, at), role: name.slice(at + 1) };
|
|
24683
|
+
}
|
|
24684
|
+
async function readInvocationScopeFields(runDirectory) {
|
|
24685
|
+
let raw;
|
|
24686
|
+
try {
|
|
24687
|
+
raw = await readFile13(join21(runDirectory, "invocation.json"), "utf8");
|
|
24688
|
+
} catch (error) {
|
|
24689
|
+
if (isMissingPathError4(error)) return void 0;
|
|
24690
|
+
throw error;
|
|
24691
|
+
}
|
|
24692
|
+
const parsed = JSON.parse(raw);
|
|
24693
|
+
if (!isRecord8(parsed)) return void 0;
|
|
24694
|
+
if (typeof parsed.projectRoot !== "string" || parsed.projectRoot.trim() === "") {
|
|
24695
|
+
return void 0;
|
|
24696
|
+
}
|
|
24697
|
+
const projectRoot = parsed.projectRoot;
|
|
24698
|
+
if (typeof parsed.ticketNumber === "number" && Number.isInteger(parsed.ticketNumber) && parsed.ticketNumber >= 1) {
|
|
24699
|
+
return { projectRoot, ticketNumber: parsed.ticketNumber };
|
|
24700
|
+
}
|
|
24701
|
+
return { projectRoot };
|
|
24702
|
+
}
|
|
24703
|
+
function decideIssueScope(input) {
|
|
24704
|
+
const projectRootMatch = input.runProjectRootIdentity === input.scopeProjectRootIdentity;
|
|
24705
|
+
if (input.scopeTicketNumber !== void 0 && input.runTicketNumber !== void 0) {
|
|
24706
|
+
if (input.runTicketNumber === input.scopeTicketNumber) {
|
|
24707
|
+
return { inScope: true, conflict: !projectRootMatch };
|
|
24708
|
+
}
|
|
24709
|
+
return { inScope: false, conflict: false };
|
|
24710
|
+
}
|
|
24711
|
+
return { inScope: projectRootMatch, conflict: false };
|
|
24712
|
+
}
|
|
24713
|
+
async function resolveSessionFile(runDirectory) {
|
|
24714
|
+
try {
|
|
24715
|
+
const raw = await readFile13(join21(runDirectory, "invocation.json"), "utf8");
|
|
24716
|
+
const parsed = JSON.parse(raw);
|
|
24717
|
+
if (isRecord8(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
|
|
24718
|
+
return parsed.sessionFile;
|
|
24719
|
+
}
|
|
24720
|
+
} catch (error) {
|
|
24721
|
+
if (!isMissingPathError4(error)) throw error;
|
|
24722
|
+
}
|
|
24723
|
+
return join21(runDirectory, "session", "session.jsonl");
|
|
24724
|
+
}
|
|
24725
|
+
async function classifyScopedRun(input) {
|
|
24726
|
+
const missingSources = [];
|
|
24727
|
+
const reasons = [];
|
|
24728
|
+
let frameSpan;
|
|
24729
|
+
let toolIntervals;
|
|
24730
|
+
let terminal;
|
|
24731
|
+
let models = [];
|
|
24732
|
+
let partialFirstFrameAt = { status: "absent" };
|
|
24733
|
+
let partialLastFrameAt = { status: "absent" };
|
|
24734
|
+
const sessionFile = await resolveSessionFile(input.runDirectory);
|
|
24735
|
+
let rows;
|
|
24736
|
+
try {
|
|
24737
|
+
rows = await readLedgerSessionJsonl(sessionFile);
|
|
24738
|
+
models = extractSessionModelSequence(rows);
|
|
24739
|
+
const span = extractSessionTimestampSpan(rows);
|
|
24740
|
+
if (span.startedAt === void 0 || span.endedAt === void 0) {
|
|
24741
|
+
missingSources.push("session-timeline");
|
|
24742
|
+
reasons.push("session timeline has no usable timestamps");
|
|
24743
|
+
if (span.startedAt !== void 0) {
|
|
24744
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24745
|
+
}
|
|
24746
|
+
if (span.endedAt !== void 0) {
|
|
24747
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24748
|
+
}
|
|
24749
|
+
} else {
|
|
24750
|
+
const startedMs = Date.parse(span.startedAt);
|
|
24751
|
+
const endedMs = Date.parse(span.endedAt);
|
|
24752
|
+
if (!Number.isFinite(startedMs) || !Number.isFinite(endedMs)) {
|
|
24753
|
+
missingSources.push("session-timeline");
|
|
24754
|
+
reasons.push("session timeline timestamps are not parseable instants");
|
|
24755
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24756
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24757
|
+
} else if (endedMs < startedMs) {
|
|
24758
|
+
missingSources.push("session-timeline");
|
|
24759
|
+
reasons.push("session timeline end is earlier than start");
|
|
24760
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24761
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24762
|
+
} else {
|
|
24763
|
+
frameSpan = { startedAt: span.startedAt, endedAt: span.endedAt };
|
|
24764
|
+
}
|
|
24765
|
+
}
|
|
24766
|
+
} catch (error) {
|
|
24767
|
+
missingSources.push("session-timeline");
|
|
24768
|
+
reasons.push(errorText3(error));
|
|
24769
|
+
if (error instanceof LedgerSessionJsonlError) {
|
|
24770
|
+
const span = extractSessionTimestampSpan(error.prefixRows);
|
|
24771
|
+
if (span.startedAt !== void 0) {
|
|
24772
|
+
partialFirstFrameAt = { status: "present", at: span.startedAt };
|
|
24773
|
+
}
|
|
24774
|
+
if (span.endedAt !== void 0) {
|
|
24775
|
+
partialLastFrameAt = { status: "present", at: span.endedAt };
|
|
24776
|
+
}
|
|
24777
|
+
models = extractSessionModelSequence(error.prefixRows);
|
|
24778
|
+
}
|
|
24779
|
+
}
|
|
24780
|
+
if (rows !== void 0 && !missingSources.includes("session-timeline")) {
|
|
24781
|
+
try {
|
|
24782
|
+
toolIntervals = extractSessionToolIntervals(rows);
|
|
24783
|
+
} catch (error) {
|
|
24784
|
+
missingSources.push("tool-association");
|
|
24785
|
+
reasons.push(errorText3(error));
|
|
24786
|
+
}
|
|
24787
|
+
}
|
|
24788
|
+
try {
|
|
24789
|
+
const artifact = await readRunTerminalArtifact(input.runDirectory);
|
|
24790
|
+
if (artifact.status === "unreadable") {
|
|
24791
|
+
missingSources.push("terminal-artifact");
|
|
24792
|
+
reasons.push(`${artifact.file}: ${artifact.reason}`);
|
|
24793
|
+
} else if (artifact.status === "absent") {
|
|
24794
|
+
const lifecycle = await readExistingRunLifecycleState(input.runDirectory);
|
|
24795
|
+
if (lifecycle !== void 0 && LIVE_RUN_STATES.has(lifecycle)) {
|
|
24796
|
+
return { kind: "live" };
|
|
24797
|
+
}
|
|
24798
|
+
terminal = { status: "absent" };
|
|
24799
|
+
} else {
|
|
24800
|
+
terminal = {
|
|
24801
|
+
status: "present",
|
|
24802
|
+
file: artifact.file,
|
|
24803
|
+
body: artifact.body,
|
|
24804
|
+
role: artifact.body.role
|
|
24805
|
+
};
|
|
24806
|
+
}
|
|
24807
|
+
} catch (error) {
|
|
24808
|
+
missingSources.push("terminal-artifact");
|
|
24809
|
+
reasons.push(errorText3(error));
|
|
24810
|
+
}
|
|
24811
|
+
if (missingSources.length > 0) {
|
|
24812
|
+
const firstFrameAt = frameSpan !== void 0 ? { status: "present", at: frameSpan.startedAt } : partialFirstFrameAt;
|
|
24813
|
+
const lastFrameAt = frameSpan !== void 0 ? { status: "present", at: frameSpan.endedAt } : partialLastFrameAt;
|
|
24814
|
+
return {
|
|
24815
|
+
kind: "unreadable",
|
|
24816
|
+
entry: {
|
|
24817
|
+
runId: input.runId,
|
|
24818
|
+
book: input.book,
|
|
24819
|
+
missingSources,
|
|
24820
|
+
reason: reasons.join("; "),
|
|
24821
|
+
firstFrameAt,
|
|
24822
|
+
lastFrameAt
|
|
24823
|
+
}
|
|
24824
|
+
};
|
|
24825
|
+
}
|
|
24826
|
+
if (frameSpan === void 0 || toolIntervals === void 0 || terminal === void 0) {
|
|
24827
|
+
throw new Error(
|
|
24828
|
+
`classifyScopedRun internal invariant: missing retained facts for ${input.runId}`
|
|
24829
|
+
);
|
|
24830
|
+
}
|
|
24831
|
+
return {
|
|
24832
|
+
kind: "readable",
|
|
24833
|
+
facts: {
|
|
24834
|
+
runId: input.runId,
|
|
24835
|
+
book: input.book,
|
|
24836
|
+
role: input.role,
|
|
24837
|
+
frameSpan,
|
|
24838
|
+
toolIntervals,
|
|
24839
|
+
terminal,
|
|
24840
|
+
models
|
|
24841
|
+
}
|
|
24842
|
+
};
|
|
24843
|
+
}
|
|
24844
|
+
async function scanTaishiIssueRuns(input) {
|
|
24845
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
24846
|
+
const scopeIdentity = physicalPathIdentity(input.projectRoot);
|
|
24847
|
+
const scopeTicketNumber = input.ticketNumber;
|
|
24848
|
+
const booksRoot = join21(ledgerHome, "books");
|
|
24849
|
+
let bookNames;
|
|
24850
|
+
try {
|
|
24851
|
+
const entries = await readdir5(booksRoot, { withFileTypes: true });
|
|
24852
|
+
bookNames = entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
24853
|
+
} catch (error) {
|
|
24854
|
+
if (isMissingPathError4(error)) {
|
|
24855
|
+
return { runs: [], unreadable: [], scopeConflicts: [] };
|
|
24856
|
+
}
|
|
24857
|
+
throw error;
|
|
24858
|
+
}
|
|
24859
|
+
const runs = [];
|
|
24860
|
+
const unreadable = [];
|
|
24861
|
+
const scopeConflicts = [];
|
|
24862
|
+
for (const book of bookNames) {
|
|
24863
|
+
const runsDir = join21(booksRoot, book, "runs");
|
|
24864
|
+
let runNames;
|
|
24865
|
+
try {
|
|
24866
|
+
const entries = await readdir5(runsDir, { withFileTypes: true });
|
|
24867
|
+
runNames = entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
24868
|
+
} catch (error) {
|
|
24869
|
+
if (isMissingPathError4(error)) continue;
|
|
24870
|
+
throw error;
|
|
24871
|
+
}
|
|
24872
|
+
for (const runName of runNames) {
|
|
24873
|
+
const parsed = parseRunDirectoryName(runName);
|
|
24874
|
+
if (parsed === void 0) continue;
|
|
24875
|
+
const runDirectory = join21(runsDir, runName);
|
|
24876
|
+
let scopeFields;
|
|
24877
|
+
try {
|
|
24878
|
+
scopeFields = await readInvocationScopeFields(runDirectory);
|
|
24879
|
+
} catch (error) {
|
|
24880
|
+
if (error instanceof SyntaxError) continue;
|
|
24881
|
+
throw error;
|
|
24882
|
+
}
|
|
24883
|
+
if (scopeFields === void 0) continue;
|
|
24884
|
+
const runProjectRootIdentity = physicalPathIdentity(scopeFields.projectRoot);
|
|
24885
|
+
const decision = decideIssueScope({
|
|
24886
|
+
scopeProjectRootIdentity: scopeIdentity,
|
|
24887
|
+
scopeTicketNumber,
|
|
24888
|
+
runProjectRootIdentity,
|
|
24889
|
+
runTicketNumber: scopeFields.ticketNumber
|
|
24890
|
+
});
|
|
24891
|
+
if (!decision.inScope) continue;
|
|
24892
|
+
if (decision.conflict) {
|
|
24893
|
+
scopeConflicts.push({
|
|
24894
|
+
runId: parsed.runId,
|
|
24895
|
+
ticketNumber: scopeFields.ticketNumber,
|
|
24896
|
+
projectRoot: runProjectRootIdentity,
|
|
24897
|
+
fact: "typed-ticketNumber-over-projectRoot"
|
|
24898
|
+
});
|
|
24899
|
+
}
|
|
24900
|
+
const classified = await classifyScopedRun({
|
|
24901
|
+
book,
|
|
24902
|
+
runId: parsed.runId,
|
|
24903
|
+
role: parsed.role,
|
|
24904
|
+
runDirectory
|
|
24905
|
+
});
|
|
24906
|
+
if (classified.kind === "readable") runs.push(classified.facts);
|
|
24907
|
+
else if (classified.kind === "unreadable") unreadable.push(classified.entry);
|
|
24908
|
+
}
|
|
24909
|
+
}
|
|
24910
|
+
return {
|
|
24911
|
+
runs,
|
|
24912
|
+
unreadable,
|
|
24913
|
+
scopeConflicts
|
|
24914
|
+
};
|
|
24915
|
+
}
|
|
24916
|
+
var LIVE_RUN_STATES;
|
|
24917
|
+
var init_taishi_ledger = __esm({
|
|
24918
|
+
"src/taishi-ledger.ts"() {
|
|
24919
|
+
"use strict";
|
|
24920
|
+
init_activation_ledger_topology();
|
|
24921
|
+
init_ledger_session_read();
|
|
24922
|
+
init_run_terminal_artifacts();
|
|
24923
|
+
LIVE_RUN_STATES = /* @__PURE__ */ new Set(["admitted", "running", "resumable"]);
|
|
24924
|
+
}
|
|
24925
|
+
});
|
|
24926
|
+
|
|
24927
|
+
// src/taishi-metric-families/acceptance-success-rework.ts
|
|
24928
|
+
function isRecord9(value) {
|
|
24929
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24930
|
+
}
|
|
24931
|
+
function wallMsFromSpan(span) {
|
|
24932
|
+
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
24933
|
+
}
|
|
24934
|
+
function findCollectorGroups(body) {
|
|
24935
|
+
if (Array.isArray(body.groups)) return body.groups;
|
|
24936
|
+
const receipt = body.receipt;
|
|
24937
|
+
if (isRecord9(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
|
|
24938
|
+
const outcome = body.outcome;
|
|
24939
|
+
if (isRecord9(outcome)) {
|
|
24940
|
+
const facts = outcome.decisiveFacts;
|
|
24941
|
+
if (isRecord9(facts) && Array.isArray(facts.groups)) return facts.groups;
|
|
24942
|
+
}
|
|
24943
|
+
return void 0;
|
|
24944
|
+
}
|
|
24945
|
+
function extractStatus(body) {
|
|
24946
|
+
const outcome = body.outcome;
|
|
24947
|
+
if (isRecord9(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
|
|
24948
|
+
return outcome.status;
|
|
24949
|
+
}
|
|
24950
|
+
const receipt = body.receipt;
|
|
24951
|
+
if (isRecord9(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
|
|
24952
|
+
return receipt.status;
|
|
24953
|
+
}
|
|
24954
|
+
if (typeof body.status === "string" && body.status.trim() !== "") {
|
|
24955
|
+
return body.status;
|
|
24956
|
+
}
|
|
24957
|
+
return void 0;
|
|
24958
|
+
}
|
|
24959
|
+
function mapTerminal(role, terminal) {
|
|
24960
|
+
if (terminal.status === "absent") {
|
|
24961
|
+
return {
|
|
24962
|
+
terminalLabel: "no-receipt",
|
|
24963
|
+
accepted: false,
|
|
24964
|
+
success: false,
|
|
24965
|
+
successEligible: false,
|
|
24966
|
+
noReceipt: true
|
|
24967
|
+
};
|
|
24968
|
+
}
|
|
24969
|
+
const body = terminal.body;
|
|
24970
|
+
if (role === "collector") {
|
|
24971
|
+
const groups = findCollectorGroups(body);
|
|
24972
|
+
if (Array.isArray(groups)) {
|
|
24973
|
+
return {
|
|
24974
|
+
terminalLabel: "groups",
|
|
24975
|
+
accepted: true,
|
|
24976
|
+
success: true,
|
|
24977
|
+
successEligible: true,
|
|
24978
|
+
noReceipt: false
|
|
24979
|
+
};
|
|
24980
|
+
}
|
|
24981
|
+
return {
|
|
24982
|
+
terminalLabel: "non-accepted",
|
|
24983
|
+
accepted: false,
|
|
24984
|
+
success: false,
|
|
24985
|
+
successEligible: false,
|
|
24986
|
+
noReceipt: false
|
|
24987
|
+
};
|
|
24988
|
+
}
|
|
24989
|
+
const status = extractStatus(body);
|
|
24990
|
+
if (status === void 0) {
|
|
24991
|
+
return {
|
|
24992
|
+
terminalLabel: "non-accepted",
|
|
24993
|
+
accepted: false,
|
|
24994
|
+
success: false,
|
|
24995
|
+
successEligible: false,
|
|
24996
|
+
noReceipt: false
|
|
24997
|
+
};
|
|
24998
|
+
}
|
|
24999
|
+
const acceptedSet = ACCEPTED_STATUS[role];
|
|
25000
|
+
if (acceptedSet === void 0 || !acceptedSet.has(status)) {
|
|
25001
|
+
return {
|
|
25002
|
+
terminalLabel: status,
|
|
25003
|
+
accepted: false,
|
|
25004
|
+
success: false,
|
|
25005
|
+
successEligible: false,
|
|
25006
|
+
noReceipt: false
|
|
25007
|
+
};
|
|
25008
|
+
}
|
|
25009
|
+
const plannedDuty = WORKER_ROLES.has(role) && status === "planned";
|
|
25010
|
+
const successSet = SUCCESS_STATUS[role] ?? /* @__PURE__ */ new Set();
|
|
25011
|
+
const success = !plannedDuty && successSet.has(status);
|
|
25012
|
+
const successEligible = !plannedDuty;
|
|
25013
|
+
return {
|
|
25014
|
+
terminalLabel: status,
|
|
25015
|
+
accepted: true,
|
|
25016
|
+
success,
|
|
25017
|
+
successEligible,
|
|
25018
|
+
noReceipt: false
|
|
25019
|
+
};
|
|
25020
|
+
}
|
|
25021
|
+
function projectLegs(runs) {
|
|
25022
|
+
const sorted = [...runs].sort((a, b) => {
|
|
25023
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25024
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25025
|
+
if (a.frameSpan.startedAt !== b.frameSpan.startedAt) {
|
|
25026
|
+
return a.frameSpan.startedAt.localeCompare(b.frameSpan.startedAt);
|
|
25027
|
+
}
|
|
25028
|
+
return a.runId.localeCompare(b.runId);
|
|
25029
|
+
});
|
|
25030
|
+
const ordinalByKey = /* @__PURE__ */ new Map();
|
|
25031
|
+
const legs = [];
|
|
25032
|
+
for (const run of sorted) {
|
|
25033
|
+
const key = `${run.book}\0${run.role}`;
|
|
25034
|
+
const ordinal = (ordinalByKey.get(key) ?? 0) + 1;
|
|
25035
|
+
ordinalByKey.set(key, ordinal);
|
|
25036
|
+
const mapped = mapTerminal(run.role, run.terminal);
|
|
25037
|
+
legs.push({
|
|
25038
|
+
runId: run.runId,
|
|
25039
|
+
book: run.book,
|
|
25040
|
+
role: run.role,
|
|
25041
|
+
startedAt: run.frameSpan.startedAt,
|
|
25042
|
+
wallMs: wallMsFromSpan(run.frameSpan),
|
|
25043
|
+
terminalLabel: mapped.terminalLabel,
|
|
25044
|
+
accepted: mapped.accepted,
|
|
25045
|
+
success: mapped.success,
|
|
25046
|
+
successEligible: mapped.successEligible,
|
|
25047
|
+
noReceipt: mapped.noReceipt,
|
|
25048
|
+
ordinalInLaneRole: ordinal,
|
|
25049
|
+
rework: ordinal >= 2
|
|
25050
|
+
});
|
|
25051
|
+
}
|
|
25052
|
+
return legs.sort((a, b) => {
|
|
25053
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25054
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25055
|
+
return a.runId.localeCompare(b.runId);
|
|
25056
|
+
});
|
|
25057
|
+
}
|
|
25058
|
+
function aggregateByRole(legs) {
|
|
25059
|
+
const roles = [...new Set(legs.map((leg) => leg.role))].sort((a, b) => a.localeCompare(b));
|
|
25060
|
+
return roles.map((role) => {
|
|
25061
|
+
const roleLegs = legs.filter((leg) => leg.role === role);
|
|
25062
|
+
const acceptedCount = roleLegs.filter((leg) => leg.accepted).length;
|
|
25063
|
+
const successEligibleCount = roleLegs.filter((leg) => leg.successEligible).length;
|
|
25064
|
+
const successCount = roleLegs.filter((leg) => leg.success).length;
|
|
25065
|
+
const noReceiptCount = roleLegs.filter((leg) => leg.noReceipt).length;
|
|
25066
|
+
const byBook = /* @__PURE__ */ new Map();
|
|
25067
|
+
for (const leg of roleLegs) {
|
|
25068
|
+
const list = byBook.get(leg.book) ?? [];
|
|
25069
|
+
list.push(leg);
|
|
25070
|
+
byBook.set(leg.book, list);
|
|
25071
|
+
}
|
|
25072
|
+
const books = [...byBook.keys()].sort((a, b) => a.localeCompare(b));
|
|
25073
|
+
const convergenceRounds = [];
|
|
25074
|
+
let firstPassLaneCount = 0;
|
|
25075
|
+
for (const book of books) {
|
|
25076
|
+
const laneLegs = [...byBook.get(book)].sort((a, b) => {
|
|
25077
|
+
if (a.startedAt !== b.startedAt) return a.startedAt.localeCompare(b.startedAt);
|
|
25078
|
+
return a.runId.localeCompare(b.runId);
|
|
25079
|
+
});
|
|
25080
|
+
convergenceRounds.push(laneLegs.length);
|
|
25081
|
+
const first = laneLegs[0];
|
|
25082
|
+
if (first.accepted) firstPassLaneCount += 1;
|
|
25083
|
+
}
|
|
25084
|
+
const appearanceLaneCount = books.length;
|
|
25085
|
+
return {
|
|
25086
|
+
role,
|
|
25087
|
+
acceptedCount,
|
|
25088
|
+
successEligibleCount,
|
|
25089
|
+
successCount,
|
|
25090
|
+
noReceiptCount,
|
|
25091
|
+
successRate: successEligibleCount === 0 ? void 0 : successCount / successEligibleCount,
|
|
25092
|
+
appearanceLaneCount,
|
|
25093
|
+
firstPassLaneCount,
|
|
25094
|
+
firstPassRate: appearanceLaneCount === 0 ? void 0 : firstPassLaneCount / appearanceLaneCount,
|
|
25095
|
+
convergenceRounds,
|
|
25096
|
+
convergenceRoundsMedian: medianNumber(convergenceRounds)
|
|
25097
|
+
};
|
|
25098
|
+
});
|
|
25099
|
+
}
|
|
25100
|
+
function reworkLens(legs) {
|
|
25101
|
+
let reworkWallMs = 0;
|
|
25102
|
+
let totalWallMs = 0;
|
|
25103
|
+
let reworkLegCount = 0;
|
|
25104
|
+
for (const leg of legs) {
|
|
25105
|
+
totalWallMs += leg.wallMs;
|
|
25106
|
+
if (leg.rework) {
|
|
25107
|
+
reworkWallMs += leg.wallMs;
|
|
25108
|
+
reworkLegCount += 1;
|
|
25109
|
+
}
|
|
25110
|
+
}
|
|
25111
|
+
return {
|
|
25112
|
+
reworkWallMs,
|
|
25113
|
+
totalWallMs,
|
|
25114
|
+
reworkRatio: totalWallMs === 0 ? void 0 : reworkWallMs / totalWallMs,
|
|
25115
|
+
reworkLegCount,
|
|
25116
|
+
totalLegCount: legs.length
|
|
25117
|
+
};
|
|
25118
|
+
}
|
|
25119
|
+
function buildAcceptanceSuccessReworkSection(runs) {
|
|
25120
|
+
if (runs.length === 0) return void 0;
|
|
25121
|
+
const legs = projectLegs(runs);
|
|
25122
|
+
return {
|
|
25123
|
+
kind: "taishi-acceptance-success-rework",
|
|
25124
|
+
legs,
|
|
25125
|
+
byRole: aggregateByRole(legs),
|
|
25126
|
+
rework: reworkLens(legs)
|
|
25127
|
+
};
|
|
25128
|
+
}
|
|
25129
|
+
var WORKER_ROLES, ACCEPTED_STATUS, SUCCESS_STATUS, acceptanceSuccessReworkFamily, acceptance_success_rework_default;
|
|
25130
|
+
var init_acceptance_success_rework = __esm({
|
|
25131
|
+
"src/taishi-metric-families/acceptance-success-rework.ts"() {
|
|
25132
|
+
"use strict";
|
|
25133
|
+
init_taishi_median();
|
|
25134
|
+
WORKER_ROLES = /* @__PURE__ */ new Set(["coder", "fixer"]);
|
|
25135
|
+
ACCEPTED_STATUS = {
|
|
25136
|
+
coder: /* @__PURE__ */ new Set(["completed", "refused", "partially_completed", "unfinished", "planned"]),
|
|
25137
|
+
fixer: /* @__PURE__ */ new Set(["completed", "refused", "partially_completed", "unfinished", "planned"]),
|
|
25138
|
+
judge: /* @__PURE__ */ new Set(["converged", "continue", "escalate"]),
|
|
25139
|
+
reviewer: /* @__PURE__ */ new Set(["completed", "refused"]),
|
|
25140
|
+
doctor: /* @__PURE__ */ new Set(["completed", "refused"]),
|
|
25141
|
+
merger: /* @__PURE__ */ new Set(["completed", "escalate"])
|
|
25142
|
+
};
|
|
25143
|
+
SUCCESS_STATUS = {
|
|
25144
|
+
coder: /* @__PURE__ */ new Set(["completed"]),
|
|
25145
|
+
fixer: /* @__PURE__ */ new Set(["completed"]),
|
|
25146
|
+
// Judge: producing any of the three verdicts completes the duty.
|
|
25147
|
+
judge: /* @__PURE__ */ new Set(["converged", "continue", "escalate"]),
|
|
25148
|
+
reviewer: /* @__PURE__ */ new Set(["completed"]),
|
|
25149
|
+
doctor: /* @__PURE__ */ new Set(["completed"]),
|
|
25150
|
+
merger: /* @__PURE__ */ new Set(["completed"])
|
|
25151
|
+
};
|
|
25152
|
+
acceptanceSuccessReworkFamily = {
|
|
25153
|
+
id: "acceptance-success-rework",
|
|
25154
|
+
contribute(input) {
|
|
25155
|
+
const section = buildAcceptanceSuccessReworkSection(input.runs);
|
|
25156
|
+
if (section === void 0) return void 0;
|
|
25157
|
+
return { acceptanceSuccessRework: section };
|
|
25158
|
+
}
|
|
25159
|
+
};
|
|
25160
|
+
acceptance_success_rework_default = acceptanceSuccessReworkFamily;
|
|
25161
|
+
}
|
|
25162
|
+
});
|
|
25163
|
+
|
|
25164
|
+
// src/taishi-model-groups.ts
|
|
25165
|
+
function taishiModelGroupKey(models) {
|
|
25166
|
+
if (models.length === 0) return void 0;
|
|
25167
|
+
if (models.length === 1) return models[0];
|
|
25168
|
+
return `mixed:${models.join("+")}`;
|
|
25169
|
+
}
|
|
25170
|
+
function rate(numerator, denominator) {
|
|
25171
|
+
if (denominator === 0) return void 0;
|
|
25172
|
+
return numerator / denominator;
|
|
25173
|
+
}
|
|
25174
|
+
function displayNameFor(rawGroupKey, combinationMapping) {
|
|
25175
|
+
if (combinationMapping === void 0) return rawGroupKey;
|
|
25176
|
+
const aliased = combinationMapping[rawGroupKey];
|
|
25177
|
+
return aliased === void 0 ? rawGroupKey : aliased;
|
|
25178
|
+
}
|
|
25179
|
+
function sortUnreadable(unreadable) {
|
|
25180
|
+
return [...unreadable].sort((a, b) => {
|
|
25181
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25182
|
+
return a.runId.localeCompare(b.runId);
|
|
25183
|
+
});
|
|
25184
|
+
}
|
|
25185
|
+
function modelIdentityAbsentEntry(run) {
|
|
25186
|
+
return {
|
|
25187
|
+
runId: run.runId,
|
|
25188
|
+
book: run.book,
|
|
25189
|
+
missingSources: ["session-model"],
|
|
25190
|
+
reason: "session has no usable model identity",
|
|
25191
|
+
firstFrameAt: { status: "present", at: run.frameSpan.startedAt },
|
|
25192
|
+
// Readable legs already admitted a full span — retain end edge for lastActivityAt.
|
|
25193
|
+
lastFrameAt: { status: "present", at: run.frameSpan.endedAt }
|
|
25194
|
+
};
|
|
25195
|
+
}
|
|
25196
|
+
function buildTaishiModelGroupsPage(input) {
|
|
25197
|
+
const groupedRuns = [];
|
|
25198
|
+
const modelAbsent = [];
|
|
25199
|
+
for (const run of input.runs) {
|
|
25200
|
+
const rawGroupKey = taishiModelGroupKey(run.models);
|
|
25201
|
+
if (rawGroupKey === void 0) {
|
|
25202
|
+
modelAbsent.push(modelIdentityAbsentEntry(run));
|
|
25203
|
+
} else {
|
|
25204
|
+
groupedRuns.push({ run, rawGroupKey });
|
|
25205
|
+
}
|
|
25206
|
+
}
|
|
25207
|
+
const acceptance = buildAcceptanceSuccessReworkSection(
|
|
25208
|
+
groupedRuns.map(({ run }) => run)
|
|
25209
|
+
);
|
|
25210
|
+
const legByRunId = new Map(
|
|
25211
|
+
(acceptance?.legs ?? []).map((leg) => [leg.runId, leg])
|
|
25212
|
+
);
|
|
25213
|
+
const byRaw = /* @__PURE__ */ new Map();
|
|
25214
|
+
for (const { run, rawGroupKey } of groupedRuns) {
|
|
25215
|
+
const leg = legByRunId.get(run.runId);
|
|
25216
|
+
if (leg === void 0) {
|
|
25217
|
+
throw new Error(
|
|
25218
|
+
`taishi model-groups: missing acceptance projection for run ${run.runId}`
|
|
25219
|
+
);
|
|
25220
|
+
}
|
|
25221
|
+
let acc = byRaw.get(rawGroupKey);
|
|
25222
|
+
if (acc === void 0) {
|
|
25223
|
+
acc = {
|
|
25224
|
+
acceptedCount: 0,
|
|
25225
|
+
successCount: 0,
|
|
25226
|
+
successEligibleCount: 0,
|
|
25227
|
+
noReceiptCount: 0,
|
|
25228
|
+
walls: []
|
|
25229
|
+
};
|
|
25230
|
+
byRaw.set(rawGroupKey, acc);
|
|
25231
|
+
}
|
|
25232
|
+
if (leg.accepted) acc.acceptedCount += 1;
|
|
25233
|
+
if (leg.success) acc.successCount += 1;
|
|
25234
|
+
if (leg.successEligible) acc.successEligibleCount += 1;
|
|
25235
|
+
if (leg.noReceipt) acc.noReceiptCount += 1;
|
|
25236
|
+
acc.walls.push(leg.wallMs);
|
|
25237
|
+
}
|
|
25238
|
+
const rawKeys = [...byRaw.keys()].sort((a, b) => a.localeCompare(b));
|
|
25239
|
+
const groups = rawKeys.map((rawGroupKey) => {
|
|
25240
|
+
const acc = byRaw.get(rawGroupKey);
|
|
25241
|
+
const legCount = acc.walls.length;
|
|
25242
|
+
return {
|
|
25243
|
+
rawGroupKey,
|
|
25244
|
+
displayName: displayNameFor(rawGroupKey, input.combinationMapping),
|
|
25245
|
+
legCount,
|
|
25246
|
+
acceptedCount: acc.acceptedCount,
|
|
25247
|
+
acceptanceRate: rate(acc.acceptedCount, legCount),
|
|
25248
|
+
successCount: acc.successCount,
|
|
25249
|
+
successEligibleCount: acc.successEligibleCount,
|
|
25250
|
+
successRate: rate(acc.successCount, acc.successEligibleCount),
|
|
25251
|
+
noReceiptCount: acc.noReceiptCount,
|
|
25252
|
+
noReceiptRate: rate(acc.noReceiptCount, legCount),
|
|
25253
|
+
wallClockMedianMs: medianNumber(acc.walls)
|
|
25254
|
+
};
|
|
25255
|
+
});
|
|
25256
|
+
const unreadable = sortUnreadable([...input.unreadable, ...modelAbsent]);
|
|
25257
|
+
return {
|
|
25258
|
+
kind: "taishi-model-groups",
|
|
25259
|
+
mode: "model-groups",
|
|
25260
|
+
projectRoots: [...input.projectRoots].sort((a, b) => a.localeCompare(b)),
|
|
25261
|
+
groups,
|
|
25262
|
+
legCount: groupedRuns.length,
|
|
25263
|
+
unreadableCount: unreadable.length,
|
|
25264
|
+
unreadable
|
|
25265
|
+
};
|
|
25266
|
+
}
|
|
25267
|
+
var init_taishi_model_groups = __esm({
|
|
25268
|
+
"src/taishi-model-groups.ts"() {
|
|
25269
|
+
"use strict";
|
|
25270
|
+
init_acceptance_success_rework();
|
|
25271
|
+
init_taishi_median();
|
|
25272
|
+
}
|
|
25273
|
+
});
|
|
25274
|
+
|
|
25275
|
+
// src/taishi-metric-families/b2-frame-buckets-actions.ts
|
|
25276
|
+
function timestampMs(iso) {
|
|
25277
|
+
const ms = Date.parse(iso);
|
|
25278
|
+
if (!Number.isFinite(ms)) {
|
|
25279
|
+
throw new Error(`unparseable timestamp: ${iso}`);
|
|
25280
|
+
}
|
|
25281
|
+
return ms;
|
|
25282
|
+
}
|
|
25283
|
+
function toIso(ms) {
|
|
25284
|
+
return new Date(ms).toISOString();
|
|
25285
|
+
}
|
|
25286
|
+
function closedTools(intervals) {
|
|
25287
|
+
const out = [];
|
|
25288
|
+
for (const interval of intervals) {
|
|
25289
|
+
if (interval.endedAt === void 0) continue;
|
|
25290
|
+
const startMs = timestampMs(interval.startedAt);
|
|
25291
|
+
const endMs = timestampMs(interval.endedAt);
|
|
25292
|
+
if (endMs <= startMs) continue;
|
|
25293
|
+
out.push({
|
|
25294
|
+
toolCallId: interval.toolCallId,
|
|
25295
|
+
toolName: interval.toolName,
|
|
25296
|
+
startedAt: interval.startedAt,
|
|
25297
|
+
endedAt: interval.endedAt,
|
|
25298
|
+
startMs,
|
|
25299
|
+
endMs,
|
|
25300
|
+
...interval.command !== void 0 ? { command: interval.command } : {}
|
|
25301
|
+
});
|
|
25302
|
+
}
|
|
25303
|
+
return out;
|
|
25304
|
+
}
|
|
25305
|
+
function clipToolsToFrame(tools, frameStartMs, frameEndMs) {
|
|
25306
|
+
if (frameEndMs <= frameStartMs) return [];
|
|
25307
|
+
const out = [];
|
|
25308
|
+
for (const tool2 of tools) {
|
|
25309
|
+
const startMs = Math.max(tool2.startMs, frameStartMs);
|
|
25310
|
+
const endMs = Math.min(tool2.endMs, frameEndMs);
|
|
25311
|
+
if (endMs <= startMs) continue;
|
|
25312
|
+
out.push({
|
|
25313
|
+
toolCallId: tool2.toolCallId,
|
|
25314
|
+
toolName: tool2.toolName,
|
|
25315
|
+
startMs,
|
|
25316
|
+
endMs,
|
|
25317
|
+
startedAt: startMs === tool2.startMs ? tool2.startedAt : toIso(startMs),
|
|
25318
|
+
endedAt: endMs === tool2.endMs ? tool2.endedAt : toIso(endMs),
|
|
25319
|
+
...tool2.command !== void 0 ? { command: tool2.command } : {}
|
|
25320
|
+
});
|
|
25321
|
+
}
|
|
25322
|
+
return out;
|
|
25323
|
+
}
|
|
25324
|
+
function mergeUnion(intervals) {
|
|
25325
|
+
if (intervals.length === 0) return [];
|
|
25326
|
+
const sorted = [...intervals].sort(
|
|
25327
|
+
(a, b) => a.startMs - b.startMs || a.endMs - b.endMs
|
|
25328
|
+
);
|
|
25329
|
+
const merged = [
|
|
25330
|
+
{ startMs: sorted[0].startMs, endMs: sorted[0].endMs }
|
|
25331
|
+
];
|
|
25332
|
+
for (let i = 1; i < sorted.length; i += 1) {
|
|
25333
|
+
const cur = sorted[i];
|
|
25334
|
+
const last = merged[merged.length - 1];
|
|
25335
|
+
if (cur.startMs <= last.endMs) {
|
|
25336
|
+
last.endMs = Math.max(last.endMs, cur.endMs);
|
|
25337
|
+
} else {
|
|
25338
|
+
merged.push({ startMs: cur.startMs, endMs: cur.endMs });
|
|
25339
|
+
}
|
|
25340
|
+
}
|
|
25341
|
+
return merged;
|
|
25342
|
+
}
|
|
25343
|
+
function modelMaximalIntervals(frameStartMs, frameEndMs, toolUnion) {
|
|
25344
|
+
if (frameEndMs <= frameStartMs) return [];
|
|
25345
|
+
const gaps = [];
|
|
25346
|
+
let cursor = frameStartMs;
|
|
25347
|
+
for (const interval of toolUnion) {
|
|
25348
|
+
if (interval.startMs > cursor) {
|
|
25349
|
+
gaps.push({ startMs: cursor, endMs: interval.startMs });
|
|
25350
|
+
}
|
|
25351
|
+
cursor = Math.max(cursor, interval.endMs);
|
|
25352
|
+
}
|
|
25353
|
+
if (cursor < frameEndMs) {
|
|
25354
|
+
gaps.push({ startMs: cursor, endMs: frameEndMs });
|
|
25355
|
+
}
|
|
25356
|
+
return gaps;
|
|
25357
|
+
}
|
|
25358
|
+
function toolAction(tool2) {
|
|
25359
|
+
const action = {
|
|
25360
|
+
kind: "tool",
|
|
25361
|
+
toolCallId: tool2.toolCallId,
|
|
25362
|
+
toolName: tool2.toolName,
|
|
25363
|
+
durationMs: tool2.endMs - tool2.startMs,
|
|
25364
|
+
startedAt: tool2.startedAt,
|
|
25365
|
+
endedAt: tool2.endedAt
|
|
25366
|
+
};
|
|
25367
|
+
if (tool2.toolName === "bash" && tool2.command !== void 0) {
|
|
25368
|
+
return {
|
|
25369
|
+
...action,
|
|
25370
|
+
commandSummary: tool2.command
|
|
25371
|
+
};
|
|
25372
|
+
}
|
|
25373
|
+
return action;
|
|
25374
|
+
}
|
|
25375
|
+
function modelAction(gap) {
|
|
25376
|
+
return {
|
|
25377
|
+
kind: "model",
|
|
25378
|
+
durationMs: gap.endMs - gap.startMs,
|
|
25379
|
+
startedAt: toIso(gap.startMs),
|
|
25380
|
+
endedAt: toIso(gap.endMs)
|
|
25381
|
+
};
|
|
25382
|
+
}
|
|
25383
|
+
function sortActionsDescending(actions) {
|
|
25384
|
+
return [...actions].sort((a, b) => {
|
|
25385
|
+
if (b.durationMs !== a.durationMs) return b.durationMs - a.durationMs;
|
|
25386
|
+
if (a.startedAt !== b.startedAt) return a.startedAt.localeCompare(b.startedAt);
|
|
25387
|
+
if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);
|
|
25388
|
+
if (a.kind === "tool" && b.kind === "tool") {
|
|
25389
|
+
return a.toolCallId.localeCompare(b.toolCallId);
|
|
25390
|
+
}
|
|
25391
|
+
return 0;
|
|
25392
|
+
});
|
|
25393
|
+
}
|
|
25394
|
+
function computeTaishiB2RunMetrics(facts) {
|
|
25395
|
+
const frameStartMs = timestampMs(facts.frameSpan.startedAt);
|
|
25396
|
+
const frameEndMs = timestampMs(facts.frameSpan.endedAt);
|
|
25397
|
+
const wallMs = Math.max(0, frameEndMs - frameStartMs);
|
|
25398
|
+
const tools = clipToolsToFrame(closedTools(facts.toolIntervals), frameStartMs, frameEndMs);
|
|
25399
|
+
const toolUnion = mergeUnion(tools);
|
|
25400
|
+
const toolBucketMs = toolUnion.reduce(
|
|
25401
|
+
(sum, interval) => sum + (interval.endMs - interval.startMs),
|
|
25402
|
+
0
|
|
25403
|
+
);
|
|
25404
|
+
const modelBucketMs = wallMs - toolBucketMs;
|
|
25405
|
+
const modelGaps = modelMaximalIntervals(frameStartMs, frameEndMs, toolUnion);
|
|
25406
|
+
const actions = sortActionsDescending([
|
|
25407
|
+
...tools.map(toolAction),
|
|
25408
|
+
...modelGaps.map(modelAction)
|
|
25409
|
+
]);
|
|
25410
|
+
const actionDurationMedianMs = medianNumber(actions.map((action) => action.durationMs));
|
|
25411
|
+
return {
|
|
25412
|
+
runId: facts.runId,
|
|
25413
|
+
book: facts.book,
|
|
25414
|
+
role: facts.role,
|
|
25415
|
+
wallMs,
|
|
25416
|
+
toolBucketMs,
|
|
25417
|
+
modelBucketMs,
|
|
25418
|
+
actions,
|
|
25419
|
+
actionDurationMedianMs
|
|
25420
|
+
};
|
|
25421
|
+
}
|
|
25422
|
+
var b2FrameBucketsActionsFamily, b2_frame_buckets_actions_default;
|
|
25423
|
+
var init_b2_frame_buckets_actions = __esm({
|
|
25424
|
+
"src/taishi-metric-families/b2-frame-buckets-actions.ts"() {
|
|
25425
|
+
"use strict";
|
|
25426
|
+
init_taishi_median();
|
|
25427
|
+
b2FrameBucketsActionsFamily = {
|
|
25428
|
+
id: "b2-frame-buckets-actions",
|
|
25429
|
+
contribute(input) {
|
|
25430
|
+
if (input.runs.length === 0) return void 0;
|
|
25431
|
+
const runs = [...input.runs].map(computeTaishiB2RunMetrics).sort((a, b) => {
|
|
25432
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25433
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25434
|
+
return a.runId.localeCompare(b.runId);
|
|
25435
|
+
});
|
|
25436
|
+
const section = {
|
|
25437
|
+
kind: "taishi-b2-frame-buckets-actions",
|
|
25438
|
+
runs
|
|
25439
|
+
};
|
|
25440
|
+
return { b2FrameBucketsActions: section };
|
|
25441
|
+
}
|
|
25442
|
+
};
|
|
25443
|
+
b2_frame_buckets_actions_default = b2FrameBucketsActionsFamily;
|
|
25444
|
+
}
|
|
25445
|
+
});
|
|
25446
|
+
|
|
25447
|
+
// src/taishi-metric-families/leg-wall-clock.ts
|
|
25448
|
+
function frameSpanWallMs(span) {
|
|
25449
|
+
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
25450
|
+
}
|
|
25451
|
+
function projectEntry(facts) {
|
|
25452
|
+
return {
|
|
25453
|
+
runId: facts.runId,
|
|
25454
|
+
book: facts.book,
|
|
25455
|
+
role: facts.role,
|
|
25456
|
+
wallMs: frameSpanWallMs(facts.frameSpan)
|
|
25457
|
+
};
|
|
25458
|
+
}
|
|
25459
|
+
function compareRankingDesc(a, b) {
|
|
25460
|
+
if (b.wallMs !== a.wallMs) return b.wallMs - a.wallMs;
|
|
25461
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25462
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25463
|
+
return a.runId.localeCompare(b.runId);
|
|
25464
|
+
}
|
|
25465
|
+
var legWallClockFamily, leg_wall_clock_default;
|
|
25466
|
+
var init_leg_wall_clock = __esm({
|
|
25467
|
+
"src/taishi-metric-families/leg-wall-clock.ts"() {
|
|
25468
|
+
"use strict";
|
|
25469
|
+
init_taishi_median();
|
|
25470
|
+
legWallClockFamily = {
|
|
25471
|
+
id: "leg-wall-clock",
|
|
25472
|
+
contribute(input) {
|
|
25473
|
+
if (input.runs.length === 0) {
|
|
25474
|
+
return void 0;
|
|
25475
|
+
}
|
|
25476
|
+
const ranking = input.runs.map(projectEntry).sort(compareRankingDesc);
|
|
25477
|
+
const walls = ranking.map((leg) => leg.wallMs);
|
|
25478
|
+
const medianWallMs = medianNumber(walls);
|
|
25479
|
+
if (medianWallMs === void 0) {
|
|
25480
|
+
return void 0;
|
|
25481
|
+
}
|
|
25482
|
+
let totalElapsedMs = 0;
|
|
25483
|
+
for (const wallMs of walls) totalElapsedMs += wallMs;
|
|
25484
|
+
const section = {
|
|
25485
|
+
kind: "taishi-leg-wall-clock",
|
|
25486
|
+
ranking,
|
|
25487
|
+
medianWallMs,
|
|
25488
|
+
totalElapsedMs
|
|
25489
|
+
};
|
|
25490
|
+
return { legWallClock: section };
|
|
25491
|
+
}
|
|
25492
|
+
};
|
|
25493
|
+
leg_wall_clock_default = legWallClockFamily;
|
|
25494
|
+
}
|
|
25495
|
+
});
|
|
25496
|
+
|
|
25497
|
+
// src/taishi-metric-families/round-timeline.ts
|
|
25498
|
+
function isRecord10(value) {
|
|
25499
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25500
|
+
}
|
|
25501
|
+
function wallMsFromSpan2(startedAt, endedAt) {
|
|
25502
|
+
return Date.parse(endedAt) - Date.parse(startedAt);
|
|
25503
|
+
}
|
|
25504
|
+
function readOutcomeStatus(body) {
|
|
25505
|
+
if (!isRecord10(body.outcome)) return void 0;
|
|
25506
|
+
const status = body.outcome.status;
|
|
25507
|
+
if (typeof status !== "string" || status.trim() === "") return void 0;
|
|
25508
|
+
return status;
|
|
25509
|
+
}
|
|
25510
|
+
function readClassCount(body) {
|
|
25511
|
+
if (!isRecord10(body.outcome)) return void 0;
|
|
25512
|
+
if (!isRecord10(body.outcome.decisiveFacts)) return void 0;
|
|
25513
|
+
const classCount = body.outcome.decisiveFacts.classCount;
|
|
25514
|
+
if (typeof classCount !== "number" || !Number.isFinite(classCount)) {
|
|
25515
|
+
return void 0;
|
|
25516
|
+
}
|
|
25517
|
+
return classCount;
|
|
25518
|
+
}
|
|
25519
|
+
function projectTerminal(facts) {
|
|
25520
|
+
if (facts.terminal.status === "absent") {
|
|
25521
|
+
return { kind: "death", channel: "no-receipt" };
|
|
25522
|
+
}
|
|
25523
|
+
if (facts.terminal.file === "error.json") {
|
|
25524
|
+
return { kind: "death", channel: "error" };
|
|
25525
|
+
}
|
|
25526
|
+
if (facts.terminal.file === "audit-incomplete.json") {
|
|
25527
|
+
return { kind: "death", channel: "audit-incomplete" };
|
|
25528
|
+
}
|
|
25529
|
+
const status = readOutcomeStatus(facts.terminal.body);
|
|
25530
|
+
const classCount = readClassCount(facts.terminal.body);
|
|
25531
|
+
const receiptStatus = status ?? "unparsed";
|
|
25532
|
+
if (classCount === void 0) {
|
|
25533
|
+
return { kind: "receipt", status: receiptStatus };
|
|
25534
|
+
}
|
|
25535
|
+
return { kind: "receipt", status: receiptStatus, classCount };
|
|
25536
|
+
}
|
|
25537
|
+
function projectRunRow(facts) {
|
|
25538
|
+
const { startedAt, endedAt } = facts.frameSpan;
|
|
25539
|
+
return {
|
|
25540
|
+
kind: "run",
|
|
25541
|
+
runId: facts.runId,
|
|
25542
|
+
book: facts.book,
|
|
25543
|
+
role: facts.role,
|
|
25544
|
+
startedAt,
|
|
25545
|
+
endedAt,
|
|
25546
|
+
wallMs: wallMsFromSpan2(startedAt, endedAt),
|
|
25547
|
+
terminal: projectTerminal(facts)
|
|
25548
|
+
};
|
|
25549
|
+
}
|
|
25550
|
+
function projectUnreadableRow(entry) {
|
|
25551
|
+
return {
|
|
25552
|
+
kind: "unreadable",
|
|
25553
|
+
runId: entry.runId,
|
|
25554
|
+
book: entry.book,
|
|
25555
|
+
missingSources: entry.missingSources,
|
|
25556
|
+
reason: entry.reason,
|
|
25557
|
+
firstFrameAt: entry.firstFrameAt
|
|
25558
|
+
};
|
|
25559
|
+
}
|
|
25560
|
+
function rowSortStartedAt(row) {
|
|
25561
|
+
if (row.kind === "run") return row.startedAt;
|
|
25562
|
+
if (row.firstFrameAt.status === "present") return row.firstFrameAt.at;
|
|
25563
|
+
return void 0;
|
|
25564
|
+
}
|
|
25565
|
+
function compareRows(a, b) {
|
|
25566
|
+
const aStart = rowSortStartedAt(a);
|
|
25567
|
+
const bStart = rowSortStartedAt(b);
|
|
25568
|
+
if (aStart === void 0 && bStart === void 0) {
|
|
25569
|
+
return a.runId.localeCompare(b.runId);
|
|
25570
|
+
}
|
|
25571
|
+
if (aStart === void 0) return 1;
|
|
25572
|
+
if (bStart === void 0) return -1;
|
|
25573
|
+
if (aStart !== bStart) return aStart.localeCompare(bStart);
|
|
25574
|
+
return a.runId.localeCompare(b.runId);
|
|
25575
|
+
}
|
|
25576
|
+
function buildLanes(runs, unreadable) {
|
|
25577
|
+
const byLane = /* @__PURE__ */ new Map();
|
|
25578
|
+
const push = (lane, row) => {
|
|
25579
|
+
const list = byLane.get(lane);
|
|
25580
|
+
if (list === void 0) byLane.set(lane, [row]);
|
|
25581
|
+
else list.push(row);
|
|
25582
|
+
};
|
|
25583
|
+
for (const facts of runs) {
|
|
25584
|
+
push(facts.book, projectRunRow(facts));
|
|
25585
|
+
}
|
|
25586
|
+
for (const entry of unreadable) {
|
|
25587
|
+
push(entry.book, projectUnreadableRow(entry));
|
|
25588
|
+
}
|
|
25589
|
+
return [...byLane.keys()].sort((a, b) => a.localeCompare(b)).map((lane) => ({
|
|
25590
|
+
lane,
|
|
25591
|
+
rows: [...byLane.get(lane) ?? []].sort(compareRows)
|
|
25592
|
+
}));
|
|
25593
|
+
}
|
|
25594
|
+
var roundTimelineFamily, round_timeline_default;
|
|
25595
|
+
var init_round_timeline = __esm({
|
|
25596
|
+
"src/taishi-metric-families/round-timeline.ts"() {
|
|
25597
|
+
"use strict";
|
|
25598
|
+
roundTimelineFamily = {
|
|
25599
|
+
id: "round-timeline",
|
|
25600
|
+
contribute(input) {
|
|
25601
|
+
if (input.runs.length === 0 && input.unreadable.length === 0) {
|
|
25602
|
+
return void 0;
|
|
25603
|
+
}
|
|
25604
|
+
const section = {
|
|
25605
|
+
kind: "taishi-round-timeline",
|
|
25606
|
+
lanes: buildLanes(input.runs, input.unreadable)
|
|
25607
|
+
};
|
|
25608
|
+
return { roundTimeline: section };
|
|
25609
|
+
}
|
|
25610
|
+
};
|
|
25611
|
+
round_timeline_default = roundTimelineFamily;
|
|
25612
|
+
}
|
|
25613
|
+
});
|
|
25614
|
+
|
|
25615
|
+
// src/taishi-metric-families.ts
|
|
25616
|
+
async function loadTaishiIssueMetricFamilies() {
|
|
25617
|
+
return ISSUE_METRIC_FAMILIES;
|
|
25618
|
+
}
|
|
25619
|
+
var ISSUE_METRIC_FAMILIES;
|
|
25620
|
+
var init_taishi_metric_families = __esm({
|
|
25621
|
+
"src/taishi-metric-families.ts"() {
|
|
25622
|
+
"use strict";
|
|
25623
|
+
init_acceptance_success_rework();
|
|
25624
|
+
init_b2_frame_buckets_actions();
|
|
25625
|
+
init_leg_wall_clock();
|
|
25626
|
+
init_round_timeline();
|
|
25627
|
+
ISSUE_METRIC_FAMILIES = [
|
|
25628
|
+
acceptance_success_rework_default,
|
|
25629
|
+
b2_frame_buckets_actions_default,
|
|
25630
|
+
leg_wall_clock_default,
|
|
25631
|
+
round_timeline_default
|
|
25632
|
+
].sort((a, b) => a.id.localeCompare(b.id));
|
|
25633
|
+
}
|
|
25634
|
+
});
|
|
25635
|
+
|
|
25636
|
+
// src/taishi-metric-family.ts
|
|
25637
|
+
function composeTaishiMetricFamilySections(families, input) {
|
|
25638
|
+
const sections = {};
|
|
25639
|
+
for (const family of families) {
|
|
25640
|
+
const piece = family.contribute(input);
|
|
25641
|
+
if (piece === void 0) continue;
|
|
25642
|
+
Object.assign(sections, piece);
|
|
25643
|
+
}
|
|
25644
|
+
return sections;
|
|
25645
|
+
}
|
|
25646
|
+
var init_taishi_metric_family = __esm({
|
|
25647
|
+
"src/taishi-metric-family.ts"() {
|
|
25648
|
+
"use strict";
|
|
25649
|
+
}
|
|
25650
|
+
});
|
|
25651
|
+
|
|
25652
|
+
// src/taishi-page.ts
|
|
25653
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
25654
|
+
import { dirname as dirname10, join as join22 } from "node:path";
|
|
25655
|
+
function taishiIssuePageKey(projectRoot) {
|
|
25656
|
+
const identity = physicalPathIdentity(projectRoot);
|
|
25657
|
+
return createHash4("sha256").update(identity).digest("hex").slice(0, 32);
|
|
25658
|
+
}
|
|
25659
|
+
function taishiIssuePagePath(ledgerHome, projectRoot) {
|
|
25660
|
+
return join22(ledgerHome, "taishi", "issues", `${taishiIssuePageKey(projectRoot)}.json`);
|
|
25661
|
+
}
|
|
25662
|
+
function sortLegs(legs) {
|
|
25663
|
+
return [...legs].sort((a, b) => {
|
|
25664
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25665
|
+
if (a.role !== b.role) return a.role.localeCompare(b.role);
|
|
25666
|
+
return a.runId.localeCompare(b.runId);
|
|
25667
|
+
});
|
|
25668
|
+
}
|
|
25669
|
+
function sortUnreadable2(unreadable) {
|
|
25670
|
+
return [...unreadable].sort((a, b) => {
|
|
25671
|
+
if (a.book !== b.book) return a.book.localeCompare(b.book);
|
|
25672
|
+
return a.runId.localeCompare(b.runId);
|
|
25673
|
+
});
|
|
25674
|
+
}
|
|
25675
|
+
function sortScopeConflicts(conflicts) {
|
|
25676
|
+
return [...conflicts].sort((a, b) => {
|
|
25677
|
+
const aRun = a.runId ?? "";
|
|
25678
|
+
const bRun = b.runId ?? "";
|
|
25679
|
+
if (aRun !== bRun) return aRun.localeCompare(bRun);
|
|
25680
|
+
return a.projectRoot.localeCompare(b.projectRoot);
|
|
25681
|
+
});
|
|
25682
|
+
}
|
|
25683
|
+
function assertTaishiChangedLinesInput(changedLines) {
|
|
25684
|
+
if (changedLines === void 0) return;
|
|
25685
|
+
if (typeof changedLines !== "number" || !Number.isFinite(changedLines) || changedLines < 0) {
|
|
25686
|
+
throw new Error(
|
|
25687
|
+
`taishi changedLines must be a finite non-negative number, got ${String(changedLines)}`
|
|
25688
|
+
);
|
|
25689
|
+
}
|
|
25690
|
+
}
|
|
25691
|
+
function normalizeTaishiChangedLines(changedLines) {
|
|
25692
|
+
assertTaishiChangedLinesInput(changedLines);
|
|
25693
|
+
if (changedLines === void 0 || changedLines === 0) {
|
|
25694
|
+
return { status: "absent" };
|
|
25695
|
+
}
|
|
25696
|
+
return { status: "present", value: changedLines };
|
|
25697
|
+
}
|
|
25698
|
+
function computeTaishiMsPerKLines(totalElapsedMs, changedLines) {
|
|
25699
|
+
if (changedLines.status === "absent") return { status: "absent" };
|
|
25700
|
+
return {
|
|
25701
|
+
status: "present",
|
|
25702
|
+
value: totalElapsedMs / (changedLines.value / 1e3)
|
|
25703
|
+
};
|
|
25704
|
+
}
|
|
25705
|
+
function frameSpanWallMs2(span) {
|
|
25706
|
+
return Date.parse(span.endedAt) - Date.parse(span.startedAt);
|
|
25707
|
+
}
|
|
25708
|
+
function summarizeTaishiRunEfficiency(runs, unreadable = []) {
|
|
25709
|
+
let totalElapsedMs = 0;
|
|
25710
|
+
let latestEndedAt;
|
|
25711
|
+
for (const run of runs) {
|
|
25712
|
+
totalElapsedMs += frameSpanWallMs2(run.frameSpan);
|
|
25713
|
+
const endedAt = run.frameSpan.endedAt;
|
|
25714
|
+
if (latestEndedAt === void 0 || endedAt > latestEndedAt) {
|
|
25715
|
+
latestEndedAt = endedAt;
|
|
25716
|
+
}
|
|
25717
|
+
}
|
|
25718
|
+
for (const entry of unreadable) {
|
|
25719
|
+
if (entry.lastFrameAt.status !== "present") continue;
|
|
25720
|
+
const endedAt = entry.lastFrameAt.at;
|
|
25721
|
+
if (latestEndedAt === void 0 || endedAt > latestEndedAt) {
|
|
25722
|
+
latestEndedAt = endedAt;
|
|
25723
|
+
}
|
|
25724
|
+
}
|
|
25725
|
+
const lastActivityAt = latestEndedAt === void 0 ? { status: "absent" } : { status: "present", at: latestEndedAt };
|
|
25726
|
+
return { totalElapsedMs, lastActivityAt };
|
|
25727
|
+
}
|
|
25728
|
+
async function buildTaishiIssueMetricsPage(input) {
|
|
25729
|
+
const families = await loadTaishiIssueMetricFamilies();
|
|
25730
|
+
const legs = sortLegs(
|
|
25731
|
+
input.runs.map((run) => ({
|
|
25732
|
+
runId: run.runId,
|
|
25733
|
+
book: run.book,
|
|
25734
|
+
role: run.role
|
|
25735
|
+
}))
|
|
25736
|
+
);
|
|
25737
|
+
const unreadable = sortUnreadable2(input.unreadable);
|
|
25738
|
+
const scopeConflicts = sortScopeConflicts(input.scopeConflicts ?? []);
|
|
25739
|
+
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
25740
|
+
const { totalElapsedMs, lastActivityAt } = summarizeTaishiRunEfficiency(
|
|
25741
|
+
input.runs,
|
|
25742
|
+
unreadable
|
|
25743
|
+
);
|
|
25744
|
+
const changedLines = normalizeTaishiChangedLines(input.changedLines);
|
|
25745
|
+
const msPerKLines = computeTaishiMsPerKLines(totalElapsedMs, changedLines);
|
|
25746
|
+
const envelope = {
|
|
25747
|
+
kind: "taishi-issue-metrics",
|
|
25748
|
+
mode: "issue",
|
|
25749
|
+
projectRoot,
|
|
25750
|
+
// exactOptionalPropertyTypes: only materialize when caller supplied it.
|
|
25751
|
+
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
25752
|
+
legs,
|
|
25753
|
+
unreadable,
|
|
25754
|
+
unreadableCount: unreadable.length,
|
|
25755
|
+
scopeConflicts,
|
|
25756
|
+
totalElapsedMs,
|
|
25757
|
+
changedLines,
|
|
25758
|
+
msPerKLines,
|
|
25759
|
+
lastActivityAt
|
|
25760
|
+
};
|
|
25761
|
+
const sections = composeTaishiMetricFamilySections(families, {
|
|
25762
|
+
projectRoot,
|
|
25763
|
+
runs: input.runs,
|
|
25764
|
+
unreadable
|
|
25765
|
+
});
|
|
25766
|
+
return { ...envelope, ...sections };
|
|
25767
|
+
}
|
|
25768
|
+
async function writeTaishiIssueMetricsPage(ledgerHome, page) {
|
|
25769
|
+
const path = taishiIssuePagePath(ledgerHome, page.projectRoot);
|
|
25770
|
+
ensureRealDirectoryTree(ledgerHome, dirname10(path));
|
|
25771
|
+
assertLedgerFileInsideHome(path, ledgerHome);
|
|
25772
|
+
await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
|
|
25773
|
+
`);
|
|
25774
|
+
return path;
|
|
25775
|
+
}
|
|
25776
|
+
var init_taishi_page = __esm({
|
|
25777
|
+
"src/taishi-page.ts"() {
|
|
25778
|
+
"use strict";
|
|
25779
|
+
init_atomic_write();
|
|
25780
|
+
init_activation_ledger_topology();
|
|
25781
|
+
init_taishi_metric_families();
|
|
25782
|
+
init_taishi_metric_family();
|
|
25783
|
+
}
|
|
25784
|
+
});
|
|
25785
|
+
|
|
25786
|
+
// src/taishi-entry.ts
|
|
25787
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
25788
|
+
function isMissingPathError5(error) {
|
|
25789
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
25790
|
+
}
|
|
25791
|
+
function cachedPageMatchesRequestedScope(page, input) {
|
|
25792
|
+
const requestedTicket = input.ticketNumber ?? input.issueNumber;
|
|
25793
|
+
if (requestedTicket === void 0) {
|
|
25794
|
+
return page.issueNumber === void 0;
|
|
25795
|
+
}
|
|
25796
|
+
return page.issueNumber === requestedTicket;
|
|
25797
|
+
}
|
|
25798
|
+
async function readOrComputeTaishiIssuePage(input) {
|
|
25799
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25800
|
+
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
25801
|
+
const pagePath = taishiIssuePagePath(ledgerHome, projectRoot);
|
|
25802
|
+
try {
|
|
25803
|
+
const raw = await readFile14(pagePath, "utf8");
|
|
25804
|
+
const page = JSON.parse(raw);
|
|
25805
|
+
if (cachedPageMatchesRequestedScope(page, input)) {
|
|
25806
|
+
return { mode: "issue", page, pagePath };
|
|
25807
|
+
}
|
|
25808
|
+
} catch (error) {
|
|
25809
|
+
if (!isMissingPathError5(error)) {
|
|
25810
|
+
throw new TaishiIssueComputeError({
|
|
25811
|
+
projectRoot,
|
|
25812
|
+
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
25813
|
+
cause: error
|
|
25814
|
+
});
|
|
25815
|
+
}
|
|
25816
|
+
}
|
|
25817
|
+
try {
|
|
25818
|
+
return await runTaishiIssueMode(input);
|
|
25819
|
+
} catch (error) {
|
|
25820
|
+
if (error instanceof TaishiIssueComputeError) throw error;
|
|
25821
|
+
throw new TaishiIssueComputeError({
|
|
25822
|
+
projectRoot,
|
|
25823
|
+
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
25824
|
+
cause: error
|
|
25825
|
+
});
|
|
25826
|
+
}
|
|
25827
|
+
}
|
|
25828
|
+
async function runTaishiIssueMode(input, precomputedScan) {
|
|
25829
|
+
assertTaishiChangedLinesInput(input.changedLines);
|
|
25830
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25831
|
+
const projectRoot = input.projectRoot;
|
|
25832
|
+
const ticketNumber = "ticketNumber" in input ? input.ticketNumber : void 0;
|
|
25833
|
+
const scan = precomputedScan ?? (ticketNumber === void 0 ? await scanTaishiIssueRuns({ projectRoot }) : await scanTaishiIssueRuns({ projectRoot, ticketNumber }));
|
|
25834
|
+
const issueNumber = "issueNumber" in input ? input.issueNumber : void 0;
|
|
25835
|
+
const conflictingProjectRoot = "conflictingProjectRoot" in input ? input.conflictingProjectRoot : void 0;
|
|
25836
|
+
const scopeConflicts = [...scan.scopeConflicts];
|
|
25837
|
+
if (conflictingProjectRoot !== void 0 && ticketNumber !== void 0) {
|
|
25838
|
+
const losingRoot = physicalPathIdentity(conflictingProjectRoot);
|
|
25839
|
+
const winningRoot = physicalPathIdentity(projectRoot);
|
|
25840
|
+
if (losingRoot !== winningRoot) {
|
|
25841
|
+
scopeConflicts.push({
|
|
25842
|
+
ticketNumber,
|
|
25843
|
+
projectRoot: losingRoot,
|
|
25844
|
+
fact: "typed-ticketNumber-over-projectRoot"
|
|
25845
|
+
});
|
|
25846
|
+
}
|
|
25847
|
+
}
|
|
25848
|
+
const page = await buildTaishiIssueMetricsPage({
|
|
25849
|
+
projectRoot,
|
|
25850
|
+
runs: scan.runs,
|
|
25851
|
+
unreadable: scan.unreadable,
|
|
25852
|
+
scopeConflicts,
|
|
25853
|
+
...input.changedLines === void 0 ? {} : { changedLines: input.changedLines },
|
|
25854
|
+
...issueNumber === void 0 ? {} : { issueNumber }
|
|
25855
|
+
});
|
|
25856
|
+
const pagePath = await writeTaishiIssueMetricsPage(ledgerHome, page);
|
|
25857
|
+
if (issueNumber !== void 0) {
|
|
25858
|
+
await mergeTaishiLibraryIndexRows(ledgerHome, [
|
|
25859
|
+
rowFromIssueMetricsPage(page)
|
|
25860
|
+
]);
|
|
25861
|
+
}
|
|
25862
|
+
return { mode: "issue", page, pagePath };
|
|
25863
|
+
}
|
|
25864
|
+
async function runTaishiSweepMode(input) {
|
|
25865
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25866
|
+
const issuePages = [];
|
|
25867
|
+
for (const entry of input.mergedPullRequests) {
|
|
25868
|
+
issuePages.push(await runTaishiIssueMode(entry));
|
|
25869
|
+
}
|
|
25870
|
+
const upserts = issuePages.map((result2) => rowFromIssueMetricsPage(result2.page));
|
|
25871
|
+
const { index, indexPath } = await mergeTaishiLibraryIndexRows(ledgerHome, upserts);
|
|
25872
|
+
return { mode: "sweep", issuePages, index, indexPath };
|
|
25873
|
+
}
|
|
25874
|
+
async function runTaishiModelGroupsMode(input) {
|
|
25875
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25876
|
+
const runs = [];
|
|
25877
|
+
const unreadable = [];
|
|
25878
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25879
|
+
const projectRoots = [];
|
|
25880
|
+
for (const root of input.projectRoots) {
|
|
25881
|
+
const identity = physicalPathIdentity(root);
|
|
25882
|
+
if (seen.has(identity)) continue;
|
|
25883
|
+
seen.add(identity);
|
|
25884
|
+
projectRoots.push(identity);
|
|
25885
|
+
}
|
|
25886
|
+
for (const projectRoot of projectRoots) {
|
|
25887
|
+
const scan = await scanTaishiIssueRuns({ projectRoot });
|
|
25888
|
+
runs.push(...scan.runs);
|
|
25889
|
+
unreadable.push(...scan.unreadable);
|
|
25890
|
+
const pagePath = taishiIssuePagePath(ledgerHome, projectRoot);
|
|
25891
|
+
try {
|
|
25892
|
+
const raw = await readFile14(pagePath, "utf8");
|
|
25893
|
+
JSON.parse(raw);
|
|
25894
|
+
} catch (error) {
|
|
25895
|
+
if (!isMissingPathError5(error)) {
|
|
25896
|
+
throw new TaishiIssueComputeError({ projectRoot, cause: error });
|
|
25897
|
+
}
|
|
25898
|
+
try {
|
|
25899
|
+
await runTaishiIssueMode({ mode: "issue", projectRoot }, scan);
|
|
25900
|
+
} catch (computeError) {
|
|
25901
|
+
if (computeError instanceof TaishiIssueComputeError) throw computeError;
|
|
25902
|
+
throw new TaishiIssueComputeError({ projectRoot, cause: computeError });
|
|
25903
|
+
}
|
|
25904
|
+
}
|
|
25905
|
+
}
|
|
25906
|
+
const page = input.combinationMapping === void 0 ? buildTaishiModelGroupsPage({ projectRoots, runs, unreadable }) : buildTaishiModelGroupsPage({
|
|
25907
|
+
projectRoots,
|
|
25908
|
+
runs,
|
|
25909
|
+
unreadable,
|
|
25910
|
+
combinationMapping: input.combinationMapping
|
|
25911
|
+
});
|
|
25912
|
+
return { mode: "model-groups", page };
|
|
25913
|
+
}
|
|
25914
|
+
async function runTaishi(input) {
|
|
25915
|
+
if (input.mode === "sweep") {
|
|
25916
|
+
return runTaishiSweepMode(input);
|
|
25917
|
+
}
|
|
25918
|
+
if (input.mode === "cohort") {
|
|
25919
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
25920
|
+
return runTaishiCohortMode(ledgerHome, input, async ({ projectRoot, issueNumber }) => {
|
|
25921
|
+
const ensured = await readOrComputeTaishiIssuePage({
|
|
25922
|
+
mode: "issue",
|
|
25923
|
+
projectRoot,
|
|
25924
|
+
issueNumber
|
|
25925
|
+
});
|
|
25926
|
+
return ensured.page;
|
|
25927
|
+
});
|
|
25928
|
+
}
|
|
25929
|
+
if (input.mode === "model-groups") {
|
|
25930
|
+
return runTaishiModelGroupsMode(input);
|
|
25931
|
+
}
|
|
25932
|
+
return runTaishiIssueMode(input);
|
|
25933
|
+
}
|
|
25934
|
+
var TaishiIssueComputeError, taishiSweepModeInputSchema;
|
|
25935
|
+
var init_taishi_entry = __esm({
|
|
25936
|
+
"src/taishi-entry.ts"() {
|
|
25937
|
+
"use strict";
|
|
25938
|
+
init_build();
|
|
25939
|
+
init_activation_ledger_topology();
|
|
25940
|
+
init_taishi_cohort();
|
|
25941
|
+
init_taishi_ledger();
|
|
25942
|
+
init_taishi_index();
|
|
25943
|
+
init_taishi_model_groups();
|
|
25944
|
+
init_taishi_page();
|
|
25945
|
+
TaishiIssueComputeError = class extends Error {
|
|
25946
|
+
code = "taishi-issue-compute-failed";
|
|
25947
|
+
projectRoot;
|
|
25948
|
+
issueNumber;
|
|
25949
|
+
constructor(input) {
|
|
25950
|
+
const root = physicalPathIdentity(input.projectRoot);
|
|
25951
|
+
const causeText = input.cause instanceof Error ? input.cause.message || input.cause.name : String(input.cause);
|
|
25952
|
+
const issueFace = input.issueNumber === void 0 ? `projectRoot ${root}` : `issue ${input.issueNumber} (projectRoot ${root})`;
|
|
25953
|
+
super(`taishi compute failed for ${issueFace}: ${causeText}`, {
|
|
25954
|
+
cause: input.cause
|
|
25955
|
+
});
|
|
25956
|
+
this.name = "TaishiIssueComputeError";
|
|
25957
|
+
this.projectRoot = root;
|
|
25958
|
+
if (input.issueNumber !== void 0) {
|
|
25959
|
+
this.issueNumber = input.issueNumber;
|
|
25960
|
+
}
|
|
25961
|
+
}
|
|
25962
|
+
};
|
|
25963
|
+
taishiSweepModeInputSchema = typebox_exports.Object(
|
|
25964
|
+
{
|
|
25965
|
+
mode: typebox_exports.Literal("sweep"),
|
|
25966
|
+
mergedPullRequests: typebox_exports.Array(
|
|
25967
|
+
typebox_exports.Object(
|
|
25968
|
+
{
|
|
25969
|
+
projectRoot: typebox_exports.String(),
|
|
25970
|
+
/** 排除后改动行数 — omit or 0 → typed 空缺; finite ≥ 0 only. */
|
|
25971
|
+
changedLines: typebox_exports.Optional(
|
|
25972
|
+
typebox_exports.Number({ minimum: 0, maximum: Number.MAX_VALUE })
|
|
25973
|
+
)
|
|
25974
|
+
},
|
|
25975
|
+
{ additionalProperties: false }
|
|
25976
|
+
)
|
|
25977
|
+
)
|
|
25978
|
+
},
|
|
25979
|
+
{ additionalProperties: false }
|
|
25980
|
+
);
|
|
25981
|
+
}
|
|
25982
|
+
});
|
|
25983
|
+
|
|
25984
|
+
// src/public-cli/taishi-run.ts
|
|
25985
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
25986
|
+
import { isAbsolute as isAbsolute5, resolve as resolve8 } from "node:path";
|
|
25987
|
+
async function buildTaishiIssueModeInputFromPublicArgv(parsed, ledgerHome) {
|
|
25988
|
+
const ticket = parsed.ticket;
|
|
25989
|
+
const directRoot = parsed.projectRoot;
|
|
25990
|
+
if (ticket === void 0) {
|
|
25991
|
+
return {
|
|
25992
|
+
mode: "issue",
|
|
25993
|
+
projectRoot: directRoot
|
|
25994
|
+
};
|
|
25995
|
+
}
|
|
25996
|
+
const index = await readTaishiLibraryIndexPage(ledgerHome);
|
|
25997
|
+
const row = findTaishiLibraryIndexRow(index, ticket);
|
|
25998
|
+
let projectRoot;
|
|
25999
|
+
if (row !== void 0) {
|
|
26000
|
+
projectRoot = row.projectRoot;
|
|
26001
|
+
} else if (directRoot !== void 0) {
|
|
26002
|
+
projectRoot = directRoot;
|
|
26003
|
+
} else {
|
|
26004
|
+
throw new CliUsageError(
|
|
26005
|
+
`taishi library index has no row for ticket ${ticket}`
|
|
26006
|
+
);
|
|
26007
|
+
}
|
|
26008
|
+
const dualParamConflict = row !== void 0 && directRoot !== void 0 && physicalPathIdentity(directRoot) !== physicalPathIdentity(projectRoot);
|
|
26009
|
+
return {
|
|
26010
|
+
mode: "issue",
|
|
26011
|
+
projectRoot,
|
|
26012
|
+
ticketNumber: ticket,
|
|
26013
|
+
issueNumber: ticket,
|
|
26014
|
+
...dualParamConflict ? { conflictingProjectRoot: directRoot } : {}
|
|
26015
|
+
};
|
|
26016
|
+
}
|
|
26017
|
+
function parseTaishiSweepModeInputFromJsonValue(value) {
|
|
26018
|
+
if (!value_exports.Check(taishiSweepModeInputSchema, value)) {
|
|
26019
|
+
throw new CliUsageError(
|
|
26020
|
+
"taishi sweep attachment must match TaishiSweepModeInput"
|
|
26021
|
+
);
|
|
26022
|
+
}
|
|
26023
|
+
return value;
|
|
26024
|
+
}
|
|
26025
|
+
async function buildTaishiSweepModeInputFromAttachmentPaths(attachmentPaths) {
|
|
26026
|
+
if (attachmentPaths.length !== 1) {
|
|
26027
|
+
throw new CliUsageError(
|
|
26028
|
+
"taishi sweep requires exactly one --attach typed JSON attachment"
|
|
26029
|
+
);
|
|
26030
|
+
}
|
|
26031
|
+
const sourcePath = attachmentPaths[0];
|
|
26032
|
+
const absolute = isAbsolute5(sourcePath) ? sourcePath : resolve8(sourcePath);
|
|
26033
|
+
let bytes;
|
|
26034
|
+
try {
|
|
26035
|
+
bytes = await readFile15(absolute);
|
|
26036
|
+
} catch (error) {
|
|
26037
|
+
throw new CliUsageError(
|
|
26038
|
+
`taishi sweep attachment is not a readable regular file: ${sourcePath}`,
|
|
26039
|
+
{ cause: error }
|
|
26040
|
+
);
|
|
26041
|
+
}
|
|
26042
|
+
let text;
|
|
26043
|
+
try {
|
|
26044
|
+
text = exactUtf8(bytes, "taishi sweep attachment");
|
|
26045
|
+
} catch (error) {
|
|
26046
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
26047
|
+
throw new CliUsageError(detail, { cause: error });
|
|
26048
|
+
}
|
|
26049
|
+
let parsed;
|
|
26050
|
+
try {
|
|
26051
|
+
parsed = JSON.parse(text);
|
|
26052
|
+
} catch (error) {
|
|
26053
|
+
throw new CliUsageError(
|
|
26054
|
+
"taishi sweep attachment is not valid JSON",
|
|
26055
|
+
{ cause: error }
|
|
26056
|
+
);
|
|
26057
|
+
}
|
|
26058
|
+
return parseTaishiSweepModeInputFromJsonValue(parsed);
|
|
26059
|
+
}
|
|
26060
|
+
async function runPublicTaishi(argv, _env, io, parseTaishiArgv2) {
|
|
26061
|
+
try {
|
|
26062
|
+
const parsed = parseTaishiArgv2(argv);
|
|
26063
|
+
const ledgerHome = resolveActivationLedgerHome();
|
|
26064
|
+
if (parsed.query === "sweep") {
|
|
26065
|
+
const input2 = await buildTaishiSweepModeInputFromAttachmentPaths(
|
|
26066
|
+
parsed.attachmentPaths
|
|
26067
|
+
);
|
|
26068
|
+
const result3 = await runTaishi(input2);
|
|
26069
|
+
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
26070
|
+
`);
|
|
26071
|
+
return { exitCode: 0 };
|
|
26072
|
+
}
|
|
26073
|
+
if (parsed.query === "cohort") {
|
|
26074
|
+
const result3 = await runTaishi({
|
|
26075
|
+
mode: "cohort",
|
|
26076
|
+
groups: parsed.groups
|
|
26077
|
+
});
|
|
26078
|
+
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
26079
|
+
`);
|
|
26080
|
+
return { exitCode: 0 };
|
|
26081
|
+
}
|
|
26082
|
+
if (parsed.query === "model-groups") {
|
|
26083
|
+
const result3 = await runTaishi({
|
|
26084
|
+
mode: "model-groups",
|
|
26085
|
+
projectRoots: parsed.projectRoots
|
|
26086
|
+
});
|
|
26087
|
+
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
26088
|
+
`);
|
|
26089
|
+
return { exitCode: 0 };
|
|
26090
|
+
}
|
|
26091
|
+
const input = await buildTaishiIssueModeInputFromPublicArgv(parsed, ledgerHome);
|
|
26092
|
+
const result2 = await readOrComputeTaishiIssuePage(input);
|
|
26093
|
+
io.stdout(`${JSON.stringify(result2, null, 2)}
|
|
26094
|
+
`);
|
|
26095
|
+
return { exitCode: 0 };
|
|
26096
|
+
} catch (error) {
|
|
26097
|
+
if (error instanceof CliUsageError) {
|
|
26098
|
+
presentStructuralRejection(error, io);
|
|
26099
|
+
return { exitCode: 2 };
|
|
26100
|
+
}
|
|
26101
|
+
if (error instanceof TaishiIssueComputeError) {
|
|
26102
|
+
const code = errnoCode(error.cause);
|
|
26103
|
+
presentControlledFailure({
|
|
26104
|
+
cause: "output",
|
|
26105
|
+
diagnostic: error.message,
|
|
26106
|
+
...code === void 0 ? {} : { identity: { code } },
|
|
26107
|
+
details: {
|
|
26108
|
+
code: error.code,
|
|
26109
|
+
projectRoot: error.projectRoot,
|
|
26110
|
+
...error.issueNumber === void 0 ? {} : { issueNumber: error.issueNumber }
|
|
26111
|
+
}
|
|
26112
|
+
}, io);
|
|
26113
|
+
return { exitCode: 1 };
|
|
26114
|
+
}
|
|
26115
|
+
throw error;
|
|
26116
|
+
}
|
|
26117
|
+
}
|
|
26118
|
+
var init_taishi_run = __esm({
|
|
26119
|
+
"src/public-cli/taishi-run.ts"() {
|
|
26120
|
+
"use strict";
|
|
26121
|
+
init_value2();
|
|
26122
|
+
init_activation_ledger_topology();
|
|
26123
|
+
init_exact_utf8();
|
|
26124
|
+
init_taishi_index();
|
|
26125
|
+
init_taishi_entry();
|
|
26126
|
+
init_cli_errors();
|
|
26127
|
+
init_settlement();
|
|
26128
|
+
}
|
|
26129
|
+
});
|
|
26130
|
+
|
|
26131
|
+
// src/public-cli/cli.ts
|
|
26132
|
+
var cli_exports = {};
|
|
26133
|
+
__export(cli_exports, {
|
|
26134
|
+
CliUsageError: () => CliUsageError,
|
|
26135
|
+
PUBLIC_ROLE_ARGV: () => PUBLIC_ROLE_ARGV,
|
|
26136
|
+
buildExplicitInternalActivationArgs: () => buildExplicitInternalActivationArgs,
|
|
26137
|
+
helpDocument: () => helpDocument,
|
|
26138
|
+
resolveInternalRoleEntrypoint: () => resolveInternalRoleEntrypoint,
|
|
26139
|
+
runAkRole: () => runAkRole
|
|
26140
|
+
});
|
|
26141
|
+
import { realpath as realpath5 } from "node:fs/promises";
|
|
26142
|
+
import { homedir as homedir3 } from "node:os";
|
|
26143
|
+
import { join as join23 } from "node:path";
|
|
26144
|
+
function takePublicGlobalFlag(argv, index) {
|
|
26145
|
+
const token = argv[index];
|
|
26146
|
+
if (token === void 0) return void 0;
|
|
26147
|
+
if (token === "--help" || token === "-h") {
|
|
26148
|
+
return { flag: "help", consume: 1 };
|
|
26149
|
+
}
|
|
26150
|
+
if (token === "--model") {
|
|
26151
|
+
const value = argv[index + 1];
|
|
26152
|
+
if (value === void 0) {
|
|
26153
|
+
return { flag: "model", consume: 1, value: void 0 };
|
|
26154
|
+
}
|
|
26155
|
+
return { flag: "model", consume: 2, value };
|
|
23812
26156
|
}
|
|
23813
26157
|
if (token.startsWith("--model=")) {
|
|
23814
26158
|
return {
|
|
@@ -23847,7 +26191,7 @@ function resolveHome(env) {
|
|
|
23847
26191
|
return env.home ?? process.env.HOME ?? homedir3();
|
|
23848
26192
|
}
|
|
23849
26193
|
function resolveAgentDir(env, home) {
|
|
23850
|
-
return env.agentDir ?? process.env.PI_CODING_AGENT_DIR ??
|
|
26194
|
+
return env.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join23(home, ".pi", "agent");
|
|
23851
26195
|
}
|
|
23852
26196
|
function parseThinking(value) {
|
|
23853
26197
|
if (!THINKING_LEVELS2.has(value)) {
|
|
@@ -23933,6 +26277,12 @@ function renderHelp() {
|
|
|
23933
26277
|
lines.push(` ${cap.name} \u2014 ${phaseText}`);
|
|
23934
26278
|
}
|
|
23935
26279
|
}
|
|
26280
|
+
lines.push("", "Deterministic commands:");
|
|
26281
|
+
for (const cap of doc.capabilities) {
|
|
26282
|
+
if (cap.kind === "deterministic") {
|
|
26283
|
+
lines.push(` ${cap.name}`);
|
|
26284
|
+
}
|
|
26285
|
+
}
|
|
23936
26286
|
lines.push(
|
|
23937
26287
|
"",
|
|
23938
26288
|
"Global options: --model provider/model --thinking level",
|
|
@@ -24030,6 +26380,9 @@ async function runAkRole(argv, env) {
|
|
|
24030
26380
|
}
|
|
24031
26381
|
if (match.kind === "support") {
|
|
24032
26382
|
io.stdout(`command ${match.name} kind support
|
|
26383
|
+
`);
|
|
26384
|
+
} else if (match.kind === "deterministic") {
|
|
26385
|
+
io.stdout(`command ${match.name} kind deterministic
|
|
24033
26386
|
`);
|
|
24034
26387
|
} else {
|
|
24035
26388
|
io.stdout(
|
|
@@ -24433,6 +26786,15 @@ async function runAkRole(argv, env) {
|
|
|
24433
26786
|
...result2.terminal === void 0 ? {} : { terminal: result2.terminal }
|
|
24434
26787
|
};
|
|
24435
26788
|
}
|
|
26789
|
+
if (parsed.command === "taishi") {
|
|
26790
|
+
const result2 = await runPublicTaishi(
|
|
26791
|
+
parsed.args,
|
|
26792
|
+
{ home },
|
|
26793
|
+
io,
|
|
26794
|
+
PUBLIC_ROLE_ARGV.taishi.parse
|
|
26795
|
+
);
|
|
26796
|
+
return { exitCode: result2.exitCode };
|
|
26797
|
+
}
|
|
24436
26798
|
throw new CliUsageError(`unknown command: ${parsed.command}`);
|
|
24437
26799
|
} catch (error) {
|
|
24438
26800
|
if (error instanceof CliUsageError) {
|
|
@@ -24463,6 +26825,7 @@ var init_cli = __esm({
|
|
|
24463
26825
|
init_judge_run();
|
|
24464
26826
|
init_merger_run();
|
|
24465
26827
|
init_reviewer_run();
|
|
26828
|
+
init_taishi_run();
|
|
24466
26829
|
init_run_lifecycle();
|
|
24467
26830
|
init_registry2();
|
|
24468
26831
|
init_settlement();
|
|
@@ -24475,7 +26838,9 @@ var init_cli = __esm({
|
|
|
24475
26838
|
collector: { parse: parseCollectorArgv },
|
|
24476
26839
|
doctor: { parse: parseDoctorArgv },
|
|
24477
26840
|
merger: { parse: parseMergerArgv },
|
|
24478
|
-
reviewer: { parse: parseReviewerArgv }
|
|
26841
|
+
reviewer: { parse: parseReviewerArgv },
|
|
26842
|
+
/** Deterministic analysis seat (#336) — argv parse only; no LLM admission. */
|
|
26843
|
+
taishi: { parse: parseTaishiArgv }
|
|
24479
26844
|
};
|
|
24480
26845
|
THINKING_LEVELS2 = /* @__PURE__ */ new Set([
|
|
24481
26846
|
"off",
|
|
@@ -24490,7 +26855,8 @@ var init_cli = __esm({
|
|
|
24490
26855
|
});
|
|
24491
26856
|
|
|
24492
26857
|
// src/public-cli/main.ts
|
|
24493
|
-
import {
|
|
26858
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
26859
|
+
import { dirname as dirname11, join as join24 } from "node:path";
|
|
24494
26860
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
24495
26861
|
|
|
24496
26862
|
// src/public-cli/host-pi-runtime.ts
|
|
@@ -24577,8 +26943,15 @@ function linkPackage(packageRoot2, name, targetDir) {
|
|
|
24577
26943
|
}
|
|
24578
26944
|
|
|
24579
26945
|
// src/public-cli/main.ts
|
|
24580
|
-
var here =
|
|
24581
|
-
|
|
26946
|
+
var here = dirname11(fileURLToPath2(import.meta.url));
|
|
26947
|
+
function resolvePackageRoot(binDir) {
|
|
26948
|
+
const canonical = join24(binDir, "..", "..");
|
|
26949
|
+
if (existsSync2(join24(canonical, "package.json"))) {
|
|
26950
|
+
return canonical;
|
|
26951
|
+
}
|
|
26952
|
+
return binDir;
|
|
26953
|
+
}
|
|
26954
|
+
var packageRoot = resolvePackageRoot(here);
|
|
24582
26955
|
ensureHostPiRuntimeResolvable(packageRoot);
|
|
24583
26956
|
var { runAkRole: runAkRole2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
|
|
24584
26957
|
var result = await runAkRole2(process.argv.slice(2), { packageRoot });
|