@akagilnc/pi-workflow-roles 0.1.2120 → 0.1.2124
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/README.md +2 -4
- package/README.zh-CN.md +2 -4
- package/dist/public-cli/main.js +214 -165
- package/package.json +1 -1
- package/src/public-cli/invocation.ts +18 -28
- package/src/public-cli/option-definitions.ts +35 -62
- package/src/public-cli/taishi-run.ts +41 -52
- package/src/taishi-cohort.ts +4 -0
- package/src/taishi-entry.ts +111 -49
- package/src/taishi-index.ts +39 -20
- package/src/taishi-ledger.ts +90 -45
- package/src/taishi-page.ts +64 -8
package/dist/public-cli/main.js
CHANGED
|
@@ -15597,7 +15597,6 @@ function resolveTaishiMode(presentOptionIds) {
|
|
|
15597
15597
|
}
|
|
15598
15598
|
if (selected.size === 0) return TAISHI_DEFAULT_MODE;
|
|
15599
15599
|
if (selected.has("cohort")) return "cohort";
|
|
15600
|
-
if (selected.has("model-groups")) return "model-groups";
|
|
15601
15600
|
if (selected.has("sweep")) return "sweep";
|
|
15602
15601
|
if (selected.has("issue")) return "issue";
|
|
15603
15602
|
return TAISHI_DEFAULT_MODE;
|
|
@@ -15653,12 +15652,6 @@ function evaluateTaishiModeOptionContract(mode, counts) {
|
|
|
15653
15652
|
message: "usage: ak-role taishi --cohort --group-a-label <L> --group-a-issues <N[,N...]> --group-b-label <L> --group-b-issues <N[,N...]"
|
|
15654
15653
|
};
|
|
15655
15654
|
}
|
|
15656
|
-
if (mode === "model-groups") {
|
|
15657
|
-
return {
|
|
15658
|
-
ok: false,
|
|
15659
|
-
message: "usage: ak-role taishi --model-groups --project-root <P> [--project-root <P> ...]"
|
|
15660
|
-
};
|
|
15661
|
-
}
|
|
15662
15655
|
return {
|
|
15663
15656
|
ok: false,
|
|
15664
15657
|
message: `usage: ak-role taishi ${mode} requires ${missingRequired.map((def) => def.canonical).join(" ")}`
|
|
@@ -15671,7 +15664,7 @@ function evaluateTaishiModeOptionContract(mode, counts) {
|
|
|
15671
15664
|
if (mode === "issue") {
|
|
15672
15665
|
return {
|
|
15673
15666
|
ok: false,
|
|
15674
|
-
message: "usage: ak-role taishi (
|
|
15667
|
+
message: "usage: ak-role taishi ([--ticket <N>] | [sweep] --attach <sweep.json> | --cohort ...)"
|
|
15675
15668
|
};
|
|
15676
15669
|
}
|
|
15677
15670
|
const flags = rule.optionIds.map((id) => byId.get(id)?.canonical ?? id).join(" | ");
|
|
@@ -15850,9 +15843,7 @@ var init_option_definitions = __esm({
|
|
|
15850
15843
|
"src/public-cli/option-definitions.ts"() {
|
|
15851
15844
|
"use strict";
|
|
15852
15845
|
init_cli_errors();
|
|
15853
|
-
TAISHI_REQUIRE_ANY_OF = [
|
|
15854
|
-
{ mode: "issue", optionIds: ["ticket", "project-root"] }
|
|
15855
|
-
];
|
|
15846
|
+
TAISHI_REQUIRE_ANY_OF = [];
|
|
15856
15847
|
TAISHI_DEFAULT_MODE = "issue";
|
|
15857
15848
|
REJECTED_PUBLIC_SPELLINGS = [
|
|
15858
15849
|
{
|
|
@@ -15870,6 +15861,22 @@ var init_option_definitions = __esm({
|
|
|
15870
15861
|
en: "Merger input packet is assembled internally; not a public flag.",
|
|
15871
15862
|
zh: "\u6821\u4E66\u90CE input packet \u7531\u5185\u90E8\u88C5\u914D\uFF0C\u4E0D\u662F\u516C\u5F00\u65D7\u6807\u3002"
|
|
15872
15863
|
}
|
|
15864
|
+
},
|
|
15865
|
+
{
|
|
15866
|
+
owner: "taishi",
|
|
15867
|
+
spellings: ["--project-root"],
|
|
15868
|
+
reason: {
|
|
15869
|
+
en: "Deleted (#399). taishi no longer accepts --project-root; use bare call for whole book or --ticket N (cwd git common-dir selects the book).",
|
|
15870
|
+
zh: "\u5DF2\u5220\u9664\uFF08#399\uFF09\u3002taishi \u4E0D\u518D\u63A5\u53D7 --project-root\uFF1B\u88F8\u8C03\u7528=\u6574\u7C3F\uFF0C\u6216 --ticket N\uFF08cwd git common-dir \u5B9A\u7C3F\uFF09\u3002"
|
|
15871
|
+
}
|
|
15872
|
+
},
|
|
15873
|
+
{
|
|
15874
|
+
owner: "taishi",
|
|
15875
|
+
spellings: ["--model-groups"],
|
|
15876
|
+
reason: {
|
|
15877
|
+
en: "Public CLI face disabled (#399). Input face is being redesigned for multi-issue comparison (see follow-up ticket). Library kernel retained.",
|
|
15878
|
+
zh: "\u516C\u5F00 CLI \u9762\u5DF2\u505C\u7528\uFF08#399\uFF09\u3002\u8F93\u5165\u9762\u6309\u591A issue \u91CD\u8BBE\u8BA1\u4E2D\uFF08\u89C1\u540E\u7EED\u7968\uFF09\u3002\u805A\u5408\u5185\u6838\u4FDD\u7559\u3002"
|
|
15879
|
+
}
|
|
15873
15880
|
}
|
|
15874
15881
|
];
|
|
15875
15882
|
GLOBAL_OPTIONS = [
|
|
@@ -16159,23 +16166,6 @@ var init_option_definitions = __esm({
|
|
|
16159
16166
|
zh: "\u53EF\u9009 sweep \u6A21\u5F0F\u8BCD\u5143\uFF08\u81F3\u591A\u4E00\u6B21\uFF1B\u4E0D\u5F97\u5939\u5E26\u5176\u4ED6 positional\uFF09\u3002"
|
|
16160
16167
|
}
|
|
16161
16168
|
},
|
|
16162
|
-
{
|
|
16163
|
-
id: "project-root",
|
|
16164
|
-
owner: "taishi",
|
|
16165
|
-
canonical: "--project-root",
|
|
16166
|
-
aliases: [],
|
|
16167
|
-
valueMetavar: "path",
|
|
16168
|
-
required: false,
|
|
16169
|
-
repeatable: true,
|
|
16170
|
-
form: "option",
|
|
16171
|
-
modes: ["issue", "model-groups"],
|
|
16172
|
-
requiredInModes: ["model-groups"],
|
|
16173
|
-
maxCountByMode: { issue: 1 },
|
|
16174
|
-
description: {
|
|
16175
|
-
en: "Project-root scope key. Issue: at most one (with --ticket at least one of the two). Model-groups: one or more required.",
|
|
16176
|
-
zh: "projectRoot \u8303\u56F4\u952E\u3002issue\uFF1A\u81F3\u591A\u4E00\u4E2A\uFF08\u4E0E --ticket \u81F3\u5C11\u5C45\u5176\u4E00\uFF09\u3002model-groups\uFF1A\u4E00\u4E2A\u6216\u591A\u4E2A\u4E14\u5FC5\u586B\u3002"
|
|
16177
|
-
}
|
|
16178
|
-
},
|
|
16179
16169
|
{
|
|
16180
16170
|
id: "ticket",
|
|
16181
16171
|
owner: "taishi",
|
|
@@ -16187,8 +16177,8 @@ var init_option_definitions = __esm({
|
|
|
16187
16177
|
form: "option",
|
|
16188
16178
|
modes: ["issue"],
|
|
16189
16179
|
description: {
|
|
16190
|
-
en: "Ticket/issue number
|
|
16191
|
-
zh: "
|
|
16180
|
+
en: "Ticket/issue number; live filter by invocation.ticketNumber inside the cwd book (git common-dir). Bare call = whole book. No library-index bootstrap.",
|
|
16181
|
+
zh: "\u7968\u53F7\uFF1B\u5728 cwd \u5019\u7C3F\uFF08git common-dir\uFF09\u5185\u6309 invocation.ticketNumber \u73B0\u53D6\u73B0\u7B97\u3002\u88F8\u8C03\u7528=\u6574\u7C3F\u3002\u4E0D\u4F9D\u8D56 library-index \u81EA\u4E3E\u3002"
|
|
16192
16182
|
}
|
|
16193
16183
|
},
|
|
16194
16184
|
{
|
|
@@ -16219,28 +16209,10 @@ var init_option_definitions = __esm({
|
|
|
16219
16209
|
repeatable: false,
|
|
16220
16210
|
form: "option",
|
|
16221
16211
|
modes: ["cohort"],
|
|
16222
|
-
exclusiveWith: ["model-groups"],
|
|
16223
16212
|
selectsMode: "cohort",
|
|
16224
16213
|
description: {
|
|
16225
|
-
en: "Select cohort mode
|
|
16226
|
-
zh: "\u9009\u62E9 cohort \u6A21\u5F0F\
|
|
16227
|
-
}
|
|
16228
|
-
},
|
|
16229
|
-
{
|
|
16230
|
-
id: "model-groups",
|
|
16231
|
-
owner: "taishi",
|
|
16232
|
-
canonical: "--model-groups",
|
|
16233
|
-
aliases: [],
|
|
16234
|
-
valueMetavar: null,
|
|
16235
|
-
required: false,
|
|
16236
|
-
repeatable: false,
|
|
16237
|
-
form: "option",
|
|
16238
|
-
modes: ["model-groups"],
|
|
16239
|
-
exclusiveWith: ["cohort"],
|
|
16240
|
-
selectsMode: "model-groups",
|
|
16241
|
-
description: {
|
|
16242
|
-
en: "Select model-groups mode (mutually exclusive with --cohort).",
|
|
16243
|
-
zh: "\u9009\u62E9 model-groups \u6A21\u5F0F\uFF08\u4E0E --cohort \u4E92\u65A5\uFF09\u3002"
|
|
16214
|
+
en: "Select cohort mode.",
|
|
16215
|
+
zh: "\u9009\u62E9 cohort \u6A21\u5F0F\u3002"
|
|
16244
16216
|
}
|
|
16245
16217
|
},
|
|
16246
16218
|
{
|
|
@@ -16395,14 +16367,14 @@ var init_option_definitions = __esm({
|
|
|
16395
16367
|
},
|
|
16396
16368
|
taishi: {
|
|
16397
16369
|
command: "taishi",
|
|
16398
|
-
summary: "Deterministic analysis seat (issue / sweep / cohort
|
|
16370
|
+
summary: "Deterministic analysis seat (issue / sweep / cohort).",
|
|
16399
16371
|
usage: [
|
|
16400
|
-
"ak-role taishi
|
|
16372
|
+
"ak-role taishi [--ticket <N>]",
|
|
16401
16373
|
"ak-role taishi [sweep] --attach <path>",
|
|
16402
|
-
"ak-role taishi --cohort --group-a-label <L> --group-a-issues <N[,N...]> --group-b-label <L> --group-b-issues <N[,N...]>"
|
|
16403
|
-
"ak-role taishi --model-groups --project-root <P> [--project-root <P> ...]"
|
|
16374
|
+
"ak-role taishi --cohort --group-a-label <L> --group-a-issues <N[,N...]> --group-b-label <L> --group-b-issues <N[,N...]>"
|
|
16404
16375
|
],
|
|
16405
16376
|
examples: [
|
|
16377
|
+
"ak-role taishi",
|
|
16406
16378
|
"ak-role taishi --ticket 125",
|
|
16407
16379
|
"ak-role taishi sweep --attach ./sweep.json"
|
|
16408
16380
|
]
|
|
@@ -17877,13 +17849,6 @@ function parseTaishiArgv(args) {
|
|
|
17877
17849
|
pushValue("ticket", taken.value);
|
|
17878
17850
|
continue;
|
|
17879
17851
|
}
|
|
17880
|
-
if (taken.def.id === "project-root") {
|
|
17881
|
-
pushValue(
|
|
17882
|
-
"project-root",
|
|
17883
|
-
requireOptionPath(taken.def.canonical, taken.value)
|
|
17884
|
-
);
|
|
17885
|
-
continue;
|
|
17886
|
-
}
|
|
17887
17852
|
if (taken.def.id === "attach") {
|
|
17888
17853
|
pushValue(
|
|
17889
17854
|
"attach",
|
|
@@ -17912,6 +17877,19 @@ function parseTaishiArgv(args) {
|
|
|
17912
17877
|
throw new CliUsageError(`unknown taishi option: ${taken.def.canonical}`);
|
|
17913
17878
|
}
|
|
17914
17879
|
const token = tokens.shift();
|
|
17880
|
+
if (isRejectedPublicSpelling("taishi", token)) {
|
|
17881
|
+
if (token === "--project-root" || token.startsWith("--project-root=")) {
|
|
17882
|
+
throw new CliUsageError(
|
|
17883
|
+
"taishi no longer accepts --project-root (deleted); use bare call for whole book or --ticket N (cwd git common-dir selects the book)"
|
|
17884
|
+
);
|
|
17885
|
+
}
|
|
17886
|
+
if (token === "--model-groups" || token.startsWith("--model-groups=")) {
|
|
17887
|
+
throw new CliUsageError(
|
|
17888
|
+
"taishi --model-groups public CLI face is disabled; input face is being redesigned for multi-issue comparison (see follow-up ticket)"
|
|
17889
|
+
);
|
|
17890
|
+
}
|
|
17891
|
+
throw new CliUsageError(`unknown taishi option: ${token}`);
|
|
17892
|
+
}
|
|
17915
17893
|
if (token.startsWith("-") && token !== "-") {
|
|
17916
17894
|
throw new CliUsageError(`unknown taishi option: ${token}`);
|
|
17917
17895
|
}
|
|
@@ -17951,12 +17929,6 @@ function parseTaishiArgv(args) {
|
|
|
17951
17929
|
]
|
|
17952
17930
|
};
|
|
17953
17931
|
}
|
|
17954
|
-
if (mode === "model-groups") {
|
|
17955
|
-
return {
|
|
17956
|
-
query: "model-groups",
|
|
17957
|
-
projectRoots: valueLists.get("project-root") ?? []
|
|
17958
|
-
};
|
|
17959
|
-
}
|
|
17960
17932
|
if (mode === "sweep") {
|
|
17961
17933
|
return {
|
|
17962
17934
|
query: "sweep",
|
|
@@ -17964,11 +17936,9 @@ function parseTaishiArgv(args) {
|
|
|
17964
17936
|
};
|
|
17965
17937
|
}
|
|
17966
17938
|
const ticketRaw = valueLists.get("ticket")?.[0];
|
|
17967
|
-
const projectRoot = valueLists.get("project-root")?.[0];
|
|
17968
17939
|
return {
|
|
17969
17940
|
query: "issue",
|
|
17970
|
-
...ticketRaw === void 0 ? {} : { ticket: parseTaishiTicketNumber(ticketRaw) }
|
|
17971
|
-
...projectRoot === void 0 ? {} : { projectRoot }
|
|
17941
|
+
...ticketRaw === void 0 ? {} : { ticket: parseTaishiTicketNumber(ticketRaw) }
|
|
17972
17942
|
};
|
|
17973
17943
|
}
|
|
17974
17944
|
var MergerEnvelopeDerivationError, DOCTOR_ISSUE_NUMBER_PATTERN, DOCTOR_CASE_RUNS_PATH_PATTERN, TAISHI_TICKET_NUMBER_PATTERN;
|
|
@@ -25064,6 +25034,7 @@ function taishiLibraryIndexPath(ledgerHome) {
|
|
|
25064
25034
|
}
|
|
25065
25035
|
function rowFromIssueMetricsPage(page) {
|
|
25066
25036
|
return {
|
|
25037
|
+
bookKey: page.bookKey,
|
|
25067
25038
|
projectRoot: page.projectRoot,
|
|
25068
25039
|
// exactOptionalPropertyTypes: only materialize when page carries it.
|
|
25069
25040
|
...page.issueNumber === void 0 ? {} : { issueNumber: page.issueNumber },
|
|
@@ -25075,6 +25046,8 @@ function rowFromIssueMetricsPage(page) {
|
|
|
25075
25046
|
}
|
|
25076
25047
|
function sortRows(rows) {
|
|
25077
25048
|
return [...rows].sort((a, b) => {
|
|
25049
|
+
const byBook = a.bookKey.localeCompare(b.bookKey);
|
|
25050
|
+
if (byBook !== 0) return byBook;
|
|
25078
25051
|
const byRoot = a.projectRoot.localeCompare(b.projectRoot);
|
|
25079
25052
|
if (byRoot !== 0) return byRoot;
|
|
25080
25053
|
const aNum = a.issueNumber;
|
|
@@ -25095,23 +25068,31 @@ function findTaishiLibraryIndexRow(index, issueNumber) {
|
|
|
25095
25068
|
if (index === void 0) return void 0;
|
|
25096
25069
|
return index.rows.find((row) => row.issueNumber === issueNumber);
|
|
25097
25070
|
}
|
|
25071
|
+
function indexRowKey(row) {
|
|
25072
|
+
return `${row.bookKey}\0${row.projectRoot}`;
|
|
25073
|
+
}
|
|
25074
|
+
function issueBookKey(bookKey, issueNumber) {
|
|
25075
|
+
return `${bookKey}\0${issueNumber}`;
|
|
25076
|
+
}
|
|
25098
25077
|
function upsertTaishiLibraryIndexRows(existing, upserts) {
|
|
25099
|
-
const
|
|
25100
|
-
const
|
|
25078
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
25079
|
+
const keyByIssue = /* @__PURE__ */ new Map();
|
|
25101
25080
|
const ingest = (row) => {
|
|
25081
|
+
const key = indexRowKey(row);
|
|
25102
25082
|
if (row.issueNumber !== void 0) {
|
|
25103
|
-
const
|
|
25104
|
-
|
|
25105
|
-
|
|
25083
|
+
const issueKey = issueBookKey(row.bookKey, row.issueNumber);
|
|
25084
|
+
const priorKey = keyByIssue.get(issueKey);
|
|
25085
|
+
if (priorKey !== void 0 && priorKey !== key) {
|
|
25086
|
+
byKey.delete(priorKey);
|
|
25106
25087
|
}
|
|
25107
25088
|
}
|
|
25108
|
-
const prior =
|
|
25089
|
+
const prior = byKey.get(key);
|
|
25109
25090
|
if (prior !== void 0 && prior.issueNumber !== void 0 && prior.issueNumber !== row.issueNumber) {
|
|
25110
|
-
|
|
25091
|
+
keyByIssue.delete(issueBookKey(prior.bookKey, prior.issueNumber));
|
|
25111
25092
|
}
|
|
25112
|
-
|
|
25093
|
+
byKey.set(key, row);
|
|
25113
25094
|
if (row.issueNumber !== void 0) {
|
|
25114
|
-
|
|
25095
|
+
keyByIssue.set(issueBookKey(row.bookKey, row.issueNumber), key);
|
|
25115
25096
|
}
|
|
25116
25097
|
};
|
|
25117
25098
|
if (existing !== void 0) {
|
|
@@ -25122,7 +25103,7 @@ function upsertTaishiLibraryIndexRows(existing, upserts) {
|
|
|
25122
25103
|
for (const row of upserts) {
|
|
25123
25104
|
ingest(row);
|
|
25124
25105
|
}
|
|
25125
|
-
return buildTaishiLibraryIndexPage([...
|
|
25106
|
+
return buildTaishiLibraryIndexPage([...byKey.values()]);
|
|
25126
25107
|
}
|
|
25127
25108
|
async function readTaishiLibraryIndexPage(ledgerHome) {
|
|
25128
25109
|
const path = taishiLibraryIndexPath(ledgerHome);
|
|
@@ -25233,11 +25214,13 @@ async function aggregateGroup(index, input, ensureIssuePage) {
|
|
|
25233
25214
|
}
|
|
25234
25215
|
const page = await ensureIssuePage({
|
|
25235
25216
|
projectRoot: row.projectRoot,
|
|
25236
|
-
issueNumber
|
|
25217
|
+
issueNumber,
|
|
25218
|
+
bookKey: row.bookKey
|
|
25237
25219
|
});
|
|
25238
25220
|
issueEntries.push({
|
|
25239
25221
|
issueNumber,
|
|
25240
25222
|
status: "present",
|
|
25223
|
+
bookKey: row.bookKey,
|
|
25241
25224
|
projectRoot: row.projectRoot
|
|
25242
25225
|
});
|
|
25243
25226
|
const acceptance = page.acceptanceSuccessRework;
|
|
@@ -25612,6 +25595,22 @@ function parseRunDirectoryName(name) {
|
|
|
25612
25595
|
if (at <= 0 || at === name.length - 1) return void 0;
|
|
25613
25596
|
return { runId: name.slice(0, at), role: name.slice(at + 1) };
|
|
25614
25597
|
}
|
|
25598
|
+
function tryResolveBookKeyFromProjectRoot(projectRoot) {
|
|
25599
|
+
try {
|
|
25600
|
+
return resolveBookKeyFromGit(projectRoot);
|
|
25601
|
+
} catch {
|
|
25602
|
+
return void 0;
|
|
25603
|
+
}
|
|
25604
|
+
}
|
|
25605
|
+
async function listLedgerBookNames(booksRoot) {
|
|
25606
|
+
try {
|
|
25607
|
+
const entries = await readdir5(booksRoot, { withFileTypes: true });
|
|
25608
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
25609
|
+
} catch (error) {
|
|
25610
|
+
if (isMissingPathError4(error)) return [];
|
|
25611
|
+
throw error;
|
|
25612
|
+
}
|
|
25613
|
+
}
|
|
25615
25614
|
async function readInvocationScopeFields(runDirectory) {
|
|
25616
25615
|
let raw;
|
|
25617
25616
|
try {
|
|
@@ -25632,14 +25631,18 @@ async function readInvocationScopeFields(runDirectory) {
|
|
|
25632
25631
|
return { projectRoot };
|
|
25633
25632
|
}
|
|
25634
25633
|
function decideIssueScope(input) {
|
|
25635
|
-
|
|
25636
|
-
|
|
25637
|
-
|
|
25638
|
-
|
|
25639
|
-
}
|
|
25640
|
-
|
|
25634
|
+
if (input.scopeTicketNumber !== void 0) {
|
|
25635
|
+
return { inScope: input.runTicketNumber === input.scopeTicketNumber };
|
|
25636
|
+
}
|
|
25637
|
+
if (input.wholeBook) {
|
|
25638
|
+
return { inScope: true };
|
|
25639
|
+
}
|
|
25640
|
+
if (input.scopeRootIdentity !== void 0) {
|
|
25641
|
+
return {
|
|
25642
|
+
inScope: input.runProjectRootIdentity === input.scopeRootIdentity
|
|
25643
|
+
};
|
|
25641
25644
|
}
|
|
25642
|
-
return { inScope:
|
|
25645
|
+
return { inScope: true };
|
|
25643
25646
|
}
|
|
25644
25647
|
async function resolveSessionFile(runDirectory) {
|
|
25645
25648
|
try {
|
|
@@ -25774,18 +25777,29 @@ async function classifyScopedRun(input) {
|
|
|
25774
25777
|
}
|
|
25775
25778
|
async function scanTaishiIssueRuns(input) {
|
|
25776
25779
|
const ledgerHome = resolveActivationLedgerHome();
|
|
25777
|
-
const scopeIdentity = physicalPathIdentity(input.projectRoot);
|
|
25778
25780
|
const scopeTicketNumber = input.ticketNumber;
|
|
25779
25781
|
const booksRoot = join22(ledgerHome, "books");
|
|
25782
|
+
let wholeBook = false;
|
|
25783
|
+
let scopeRootIdentity;
|
|
25780
25784
|
let bookNames;
|
|
25781
|
-
|
|
25782
|
-
|
|
25783
|
-
|
|
25784
|
-
}
|
|
25785
|
-
|
|
25786
|
-
|
|
25785
|
+
if (input.bookKey !== void 0 && input.bookKey.trim() !== "") {
|
|
25786
|
+
bookNames = [input.bookKey];
|
|
25787
|
+
wholeBook = true;
|
|
25788
|
+
} else if (input.projectRoot !== void 0) {
|
|
25789
|
+
const resolved = tryResolveBookKeyFromProjectRoot(input.projectRoot);
|
|
25790
|
+
if (resolved !== void 0) {
|
|
25791
|
+
bookNames = [resolved];
|
|
25792
|
+
wholeBook = true;
|
|
25793
|
+
} else {
|
|
25794
|
+
bookNames = await listLedgerBookNames(booksRoot);
|
|
25795
|
+
scopeRootIdentity = physicalPathIdentity(input.projectRoot);
|
|
25787
25796
|
}
|
|
25788
|
-
|
|
25797
|
+
} else {
|
|
25798
|
+
bookNames = await listLedgerBookNames(booksRoot);
|
|
25799
|
+
wholeBook = true;
|
|
25800
|
+
}
|
|
25801
|
+
if (bookNames.length === 0) {
|
|
25802
|
+
return { runs: [], unreadable: [], scopeConflicts: [] };
|
|
25789
25803
|
}
|
|
25790
25804
|
const runs = [];
|
|
25791
25805
|
const unreadable = [];
|
|
@@ -25814,20 +25828,13 @@ async function scanTaishiIssueRuns(input) {
|
|
|
25814
25828
|
if (scopeFields === void 0) continue;
|
|
25815
25829
|
const runProjectRootIdentity = physicalPathIdentity(scopeFields.projectRoot);
|
|
25816
25830
|
const decision = decideIssueScope({
|
|
25817
|
-
scopeProjectRootIdentity: scopeIdentity,
|
|
25818
25831
|
scopeTicketNumber,
|
|
25832
|
+
wholeBook,
|
|
25833
|
+
scopeRootIdentity,
|
|
25819
25834
|
runProjectRootIdentity,
|
|
25820
25835
|
runTicketNumber: scopeFields.ticketNumber
|
|
25821
25836
|
});
|
|
25822
25837
|
if (!decision.inScope) continue;
|
|
25823
|
-
if (decision.conflict) {
|
|
25824
|
-
scopeConflicts.push({
|
|
25825
|
-
runId: parsed.runId,
|
|
25826
|
-
ticketNumber: scopeFields.ticketNumber,
|
|
25827
|
-
projectRoot: runProjectRootIdentity,
|
|
25828
|
-
fact: "typed-ticketNumber-over-projectRoot"
|
|
25829
|
-
});
|
|
25830
|
-
}
|
|
25831
25838
|
const classified = await classifyScopedRun({
|
|
25832
25839
|
book,
|
|
25833
25840
|
runId: parsed.runId,
|
|
@@ -25848,6 +25855,7 @@ var LIVE_RUN_STATES;
|
|
|
25848
25855
|
var init_taishi_ledger = __esm({
|
|
25849
25856
|
"src/taishi-ledger.ts"() {
|
|
25850
25857
|
"use strict";
|
|
25858
|
+
init_activation_ledger_git();
|
|
25851
25859
|
init_activation_ledger_topology();
|
|
25852
25860
|
init_ledger_session_read();
|
|
25853
25861
|
init_run_terminal_artifacts();
|
|
@@ -26583,12 +26591,24 @@ var init_taishi_metric_family = __esm({
|
|
|
26583
26591
|
// src/taishi-page.ts
|
|
26584
26592
|
import { createHash as createHash4 } from "node:crypto";
|
|
26585
26593
|
import { dirname as dirname10, join as join23 } from "node:path";
|
|
26586
|
-
function taishiIssuePageKey(
|
|
26587
|
-
const
|
|
26588
|
-
|
|
26594
|
+
function taishiIssuePageKey(address) {
|
|
26595
|
+
const parts = ["book", address.bookKey];
|
|
26596
|
+
if (address.issueNumber !== void 0) {
|
|
26597
|
+
parts.push("ticket", String(address.issueNumber));
|
|
26598
|
+
} else if (address.scopeRootIdentity !== void 0) {
|
|
26599
|
+
parts.push("root", physicalPathIdentity(address.scopeRootIdentity));
|
|
26600
|
+
}
|
|
26601
|
+
return createHash4("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
|
|
26589
26602
|
}
|
|
26590
|
-
function taishiIssuePagePath(ledgerHome,
|
|
26591
|
-
return join23(ledgerHome, "taishi", "issues", `${taishiIssuePageKey(
|
|
26603
|
+
function taishiIssuePagePath(ledgerHome, address) {
|
|
26604
|
+
return join23(ledgerHome, "taishi", "issues", `${taishiIssuePageKey(address)}.json`);
|
|
26605
|
+
}
|
|
26606
|
+
function taishiIssuePageAddressFromPage(page) {
|
|
26607
|
+
return {
|
|
26608
|
+
bookKey: page.bookKey,
|
|
26609
|
+
...page.issueNumber === void 0 ? {} : { issueNumber: page.issueNumber },
|
|
26610
|
+
...page.scopeRootIdentity === void 0 ? {} : { scopeRootIdentity: page.scopeRootIdentity }
|
|
26611
|
+
};
|
|
26592
26612
|
}
|
|
26593
26613
|
function sortLegs(legs) {
|
|
26594
26614
|
return [...legs].sort((a, b) => {
|
|
@@ -26677,9 +26697,11 @@ async function buildTaishiIssueMetricsPage(input) {
|
|
|
26677
26697
|
const envelope = {
|
|
26678
26698
|
kind: "taishi-issue-metrics",
|
|
26679
26699
|
mode: "issue",
|
|
26700
|
+
bookKey: input.bookKey,
|
|
26680
26701
|
projectRoot,
|
|
26681
26702
|
// exactOptionalPropertyTypes: only materialize when caller supplied it.
|
|
26682
26703
|
...input.issueNumber === void 0 ? {} : { issueNumber: input.issueNumber },
|
|
26704
|
+
...input.scopeRootIdentity === void 0 ? {} : { scopeRootIdentity: physicalPathIdentity(input.scopeRootIdentity) },
|
|
26683
26705
|
legs,
|
|
26684
26706
|
unreadable,
|
|
26685
26707
|
unreadableCount: unreadable.length,
|
|
@@ -26697,7 +26719,7 @@ async function buildTaishiIssueMetricsPage(input) {
|
|
|
26697
26719
|
return { ...envelope, ...sections };
|
|
26698
26720
|
}
|
|
26699
26721
|
async function writeTaishiIssueMetricsPage(ledgerHome, page) {
|
|
26700
|
-
const path = taishiIssuePagePath(ledgerHome, page
|
|
26722
|
+
const path = taishiIssuePagePath(ledgerHome, taishiIssuePageAddressFromPage(page));
|
|
26701
26723
|
ensureRealDirectoryTree(ledgerHome, dirname10(path));
|
|
26702
26724
|
assertLedgerFileInsideHome(path, ledgerHome);
|
|
26703
26725
|
await writeFileAtomically(path, `${JSON.stringify(page, null, 2)}
|
|
@@ -26720,27 +26742,51 @@ function isMissingPathError5(error) {
|
|
|
26720
26742
|
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
26721
26743
|
}
|
|
26722
26744
|
function cachedPageMatchesRequestedScope(page, input) {
|
|
26745
|
+
if (page.bookKey !== input.bookKey) return false;
|
|
26723
26746
|
const requestedTicket = input.ticketNumber ?? input.issueNumber;
|
|
26724
26747
|
if (requestedTicket === void 0) {
|
|
26725
26748
|
return page.issueNumber === void 0;
|
|
26726
26749
|
}
|
|
26727
26750
|
return page.issueNumber === requestedTicket;
|
|
26728
26751
|
}
|
|
26752
|
+
function tryResolveBookKey(projectRoot) {
|
|
26753
|
+
try {
|
|
26754
|
+
return resolveBookKeyFromGit(projectRoot);
|
|
26755
|
+
} catch {
|
|
26756
|
+
return void 0;
|
|
26757
|
+
}
|
|
26758
|
+
}
|
|
26759
|
+
function resolveIssueBookKey(input) {
|
|
26760
|
+
if (input.bookKey !== void 0 && input.bookKey.trim() !== "") {
|
|
26761
|
+
return input.bookKey;
|
|
26762
|
+
}
|
|
26763
|
+
const fromGit = tryResolveBookKey(input.projectRoot);
|
|
26764
|
+
if (fromGit !== void 0) return fromGit;
|
|
26765
|
+
return `root:${physicalPathIdentity(input.projectRoot)}`;
|
|
26766
|
+
}
|
|
26729
26767
|
async function readOrComputeTaishiIssuePage(input) {
|
|
26730
26768
|
const ledgerHome = resolveActivationLedgerHome();
|
|
26731
26769
|
const projectRoot = physicalPathIdentity(input.projectRoot);
|
|
26732
|
-
const
|
|
26770
|
+
const bookKey = resolveIssueBookKey(input);
|
|
26771
|
+
const issueNumber = input.ticketNumber ?? input.issueNumber;
|
|
26772
|
+
const pagePath = taishiIssuePagePath(ledgerHome, {
|
|
26773
|
+
bookKey,
|
|
26774
|
+
...issueNumber === void 0 ? {} : { issueNumber },
|
|
26775
|
+
// Sweep/legacy path-narrow pages (no ticket, no explicit CLI book-only scope).
|
|
26776
|
+
...issueNumber === void 0 && input.bookKey === void 0 ? { scopeRootIdentity: projectRoot } : {}
|
|
26777
|
+
});
|
|
26733
26778
|
try {
|
|
26734
26779
|
const raw = await readFile14(pagePath, "utf8");
|
|
26735
26780
|
const page = JSON.parse(raw);
|
|
26736
|
-
if (cachedPageMatchesRequestedScope(page, input)) {
|
|
26781
|
+
if (cachedPageMatchesRequestedScope(page, { bookKey, ...input })) {
|
|
26737
26782
|
return { mode: "issue", page, pagePath };
|
|
26738
26783
|
}
|
|
26739
26784
|
} catch (error) {
|
|
26740
26785
|
if (!isMissingPathError5(error)) {
|
|
26741
26786
|
throw new TaishiIssueComputeError({
|
|
26787
|
+
bookKey,
|
|
26742
26788
|
projectRoot,
|
|
26743
|
-
...
|
|
26789
|
+
...issueNumber === void 0 ? {} : { issueNumber },
|
|
26744
26790
|
cause: error
|
|
26745
26791
|
});
|
|
26746
26792
|
}
|
|
@@ -26750,8 +26796,9 @@ async function readOrComputeTaishiIssuePage(input) {
|
|
|
26750
26796
|
} catch (error) {
|
|
26751
26797
|
if (error instanceof TaishiIssueComputeError) throw error;
|
|
26752
26798
|
throw new TaishiIssueComputeError({
|
|
26799
|
+
bookKey,
|
|
26753
26800
|
projectRoot,
|
|
26754
|
-
...
|
|
26801
|
+
...issueNumber === void 0 ? {} : { issueNumber },
|
|
26755
26802
|
cause: error
|
|
26756
26803
|
});
|
|
26757
26804
|
}
|
|
@@ -26761,28 +26808,26 @@ async function runTaishiIssueMode(input, precomputedScan) {
|
|
|
26761
26808
|
const ledgerHome = resolveActivationLedgerHome();
|
|
26762
26809
|
const projectRoot = input.projectRoot;
|
|
26763
26810
|
const ticketNumber = "ticketNumber" in input ? input.ticketNumber : void 0;
|
|
26764
|
-
const
|
|
26811
|
+
const inputBookKey = "bookKey" in input && typeof input.bookKey === "string" && input.bookKey.trim() !== "" ? input.bookKey : void 0;
|
|
26812
|
+
const scan = precomputedScan ?? (inputBookKey !== void 0 ? await scanTaishiIssueRuns({
|
|
26813
|
+
bookKey: inputBookKey,
|
|
26814
|
+
...ticketNumber === void 0 ? {} : { ticketNumber }
|
|
26815
|
+
}) : ticketNumber === void 0 ? await scanTaishiIssueRuns({ projectRoot }) : await scanTaishiIssueRuns({ projectRoot, ticketNumber }));
|
|
26765
26816
|
const issueNumber = "issueNumber" in input ? input.issueNumber : void 0;
|
|
26766
|
-
const
|
|
26767
|
-
|
|
26768
|
-
|
|
26769
|
-
|
|
26770
|
-
|
|
26771
|
-
if (losingRoot !== winningRoot) {
|
|
26772
|
-
scopeConflicts.push({
|
|
26773
|
-
ticketNumber,
|
|
26774
|
-
projectRoot: losingRoot,
|
|
26775
|
-
fact: "typed-ticketNumber-over-projectRoot"
|
|
26776
|
-
});
|
|
26777
|
-
}
|
|
26778
|
-
}
|
|
26817
|
+
const bookKey = resolveIssueBookKey({
|
|
26818
|
+
...inputBookKey === void 0 ? {} : { bookKey: inputBookKey },
|
|
26819
|
+
projectRoot
|
|
26820
|
+
});
|
|
26821
|
+
const scopeRootIdentity = inputBookKey === void 0 && ticketNumber === void 0 && issueNumber === void 0 ? physicalPathIdentity(projectRoot) : void 0;
|
|
26779
26822
|
const page = await buildTaishiIssueMetricsPage({
|
|
26823
|
+
bookKey,
|
|
26780
26824
|
projectRoot,
|
|
26781
26825
|
runs: scan.runs,
|
|
26782
26826
|
unreadable: scan.unreadable,
|
|
26783
|
-
scopeConflicts,
|
|
26827
|
+
scopeConflicts: scan.scopeConflicts,
|
|
26784
26828
|
...input.changedLines === void 0 ? {} : { changedLines: input.changedLines },
|
|
26785
|
-
...issueNumber === void 0 ? {} : { issueNumber }
|
|
26829
|
+
...issueNumber === void 0 ? {} : { issueNumber },
|
|
26830
|
+
...scopeRootIdentity === void 0 ? {} : { scopeRootIdentity }
|
|
26786
26831
|
});
|
|
26787
26832
|
const pagePath = await writeTaishiIssueMetricsPage(ledgerHome, page);
|
|
26788
26833
|
if (issueNumber !== void 0) {
|
|
@@ -26818,19 +26863,23 @@ async function runTaishiModelGroupsMode(input) {
|
|
|
26818
26863
|
const scan = await scanTaishiIssueRuns({ projectRoot });
|
|
26819
26864
|
runs.push(...scan.runs);
|
|
26820
26865
|
unreadable.push(...scan.unreadable);
|
|
26821
|
-
const
|
|
26866
|
+
const bookKey = resolveIssueBookKey({ projectRoot });
|
|
26867
|
+
const pagePath = taishiIssuePagePath(ledgerHome, {
|
|
26868
|
+
bookKey,
|
|
26869
|
+
scopeRootIdentity: projectRoot
|
|
26870
|
+
});
|
|
26822
26871
|
try {
|
|
26823
26872
|
const raw = await readFile14(pagePath, "utf8");
|
|
26824
26873
|
JSON.parse(raw);
|
|
26825
26874
|
} catch (error) {
|
|
26826
26875
|
if (!isMissingPathError5(error)) {
|
|
26827
|
-
throw new TaishiIssueComputeError({ projectRoot, cause: error });
|
|
26876
|
+
throw new TaishiIssueComputeError({ bookKey, projectRoot, cause: error });
|
|
26828
26877
|
}
|
|
26829
26878
|
try {
|
|
26830
26879
|
await runTaishiIssueMode({ mode: "issue", projectRoot }, scan);
|
|
26831
26880
|
} catch (computeError) {
|
|
26832
26881
|
if (computeError instanceof TaishiIssueComputeError) throw computeError;
|
|
26833
|
-
throw new TaishiIssueComputeError({ projectRoot, cause: computeError });
|
|
26882
|
+
throw new TaishiIssueComputeError({ bookKey, projectRoot, cause: computeError });
|
|
26834
26883
|
}
|
|
26835
26884
|
}
|
|
26836
26885
|
}
|
|
@@ -26848,11 +26897,13 @@ async function runTaishi(input) {
|
|
|
26848
26897
|
}
|
|
26849
26898
|
if (input.mode === "cohort") {
|
|
26850
26899
|
const ledgerHome = resolveActivationLedgerHome();
|
|
26851
|
-
return runTaishiCohortMode(ledgerHome, input, async ({ projectRoot, issueNumber }) => {
|
|
26900
|
+
return runTaishiCohortMode(ledgerHome, input, async ({ projectRoot, issueNumber, bookKey }) => {
|
|
26901
|
+
const realBookKey = bookKey !== void 0 && !bookKey.startsWith("root:") ? bookKey : void 0;
|
|
26852
26902
|
const ensured = await readOrComputeTaishiIssuePage({
|
|
26853
26903
|
mode: "issue",
|
|
26854
26904
|
projectRoot,
|
|
26855
|
-
issueNumber
|
|
26905
|
+
issueNumber,
|
|
26906
|
+
...realBookKey === void 0 ? {} : { bookKey: realBookKey }
|
|
26856
26907
|
});
|
|
26857
26908
|
return ensured.page;
|
|
26858
26909
|
});
|
|
@@ -26872,19 +26923,22 @@ var init_taishi_entry = __esm({
|
|
|
26872
26923
|
init_taishi_ledger();
|
|
26873
26924
|
init_taishi_index();
|
|
26874
26925
|
init_taishi_model_groups();
|
|
26926
|
+
init_activation_ledger_git();
|
|
26875
26927
|
init_taishi_page();
|
|
26876
26928
|
TaishiIssueComputeError = class extends Error {
|
|
26877
26929
|
code = "taishi-issue-compute-failed";
|
|
26930
|
+
bookKey;
|
|
26878
26931
|
projectRoot;
|
|
26879
26932
|
issueNumber;
|
|
26880
26933
|
constructor(input) {
|
|
26881
26934
|
const root = physicalPathIdentity(input.projectRoot);
|
|
26882
26935
|
const causeText = input.cause instanceof Error ? input.cause.message || input.cause.name : String(input.cause);
|
|
26883
|
-
const issueFace = input.issueNumber === void 0 ? `projectRoot ${root}` : `issue ${input.issueNumber} (projectRoot ${root})`;
|
|
26936
|
+
const issueFace = input.issueNumber === void 0 ? `book ${input.bookKey} (projectRoot ${root})` : `issue ${input.issueNumber} book ${input.bookKey} (projectRoot ${root})`;
|
|
26884
26937
|
super(`taishi compute failed for ${issueFace}: ${causeText}`, {
|
|
26885
26938
|
cause: input.cause
|
|
26886
26939
|
});
|
|
26887
26940
|
this.name = "TaishiIssueComputeError";
|
|
26941
|
+
this.bookKey = input.bookKey;
|
|
26888
26942
|
this.projectRoot = root;
|
|
26889
26943
|
if (input.issueNumber !== void 0) {
|
|
26890
26944
|
this.issueNumber = input.issueNumber;
|
|
@@ -26915,34 +26969,37 @@ var init_taishi_entry = __esm({
|
|
|
26915
26969
|
// src/public-cli/taishi-run.ts
|
|
26916
26970
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
26917
26971
|
import { isAbsolute as isAbsolute5, resolve as resolve7 } from "node:path";
|
|
26918
|
-
|
|
26972
|
+
function resolveTaishiIssueBookKeyFromCwd(cwd = process.cwd()) {
|
|
26973
|
+
try {
|
|
26974
|
+
return resolveBookKeyFromGit(cwd);
|
|
26975
|
+
} catch (error) {
|
|
26976
|
+
if (error instanceof ActivationGitRepositoryRequiredError) {
|
|
26977
|
+
throw new CliUsageError(
|
|
26978
|
+
"taishi issue query requires a git repository cwd (book = git common-dir); run inside a repository (bare = whole book, or --ticket N)",
|
|
26979
|
+
{ cause: error }
|
|
26980
|
+
);
|
|
26981
|
+
}
|
|
26982
|
+
throw error;
|
|
26983
|
+
}
|
|
26984
|
+
}
|
|
26985
|
+
async function buildTaishiIssueModeInputFromPublicArgv(parsed, _ledgerHome) {
|
|
26986
|
+
const cwd = process.cwd();
|
|
26987
|
+
const bookKey = resolveTaishiIssueBookKeyFromCwd(cwd);
|
|
26988
|
+
const projectRoot = physicalPathIdentity(cwd);
|
|
26919
26989
|
const ticket = parsed.ticket;
|
|
26920
|
-
const directRoot = parsed.projectRoot;
|
|
26921
26990
|
if (ticket === void 0) {
|
|
26922
26991
|
return {
|
|
26923
26992
|
mode: "issue",
|
|
26924
|
-
|
|
26993
|
+
bookKey,
|
|
26994
|
+
projectRoot
|
|
26925
26995
|
};
|
|
26926
26996
|
}
|
|
26927
|
-
const index = await readTaishiLibraryIndexPage(ledgerHome);
|
|
26928
|
-
const row = findTaishiLibraryIndexRow(index, ticket);
|
|
26929
|
-
let projectRoot;
|
|
26930
|
-
if (row !== void 0) {
|
|
26931
|
-
projectRoot = row.projectRoot;
|
|
26932
|
-
} else if (directRoot !== void 0) {
|
|
26933
|
-
projectRoot = directRoot;
|
|
26934
|
-
} else {
|
|
26935
|
-
throw new CliUsageError(
|
|
26936
|
-
`taishi library index has no row for ticket ${ticket}`
|
|
26937
|
-
);
|
|
26938
|
-
}
|
|
26939
|
-
const dualParamConflict = row !== void 0 && directRoot !== void 0 && physicalPathIdentity(directRoot) !== physicalPathIdentity(projectRoot);
|
|
26940
26997
|
return {
|
|
26941
26998
|
mode: "issue",
|
|
26999
|
+
bookKey,
|
|
26942
27000
|
projectRoot,
|
|
26943
27001
|
ticketNumber: ticket,
|
|
26944
|
-
issueNumber: ticket
|
|
26945
|
-
...dualParamConflict ? { conflictingProjectRoot: directRoot } : {}
|
|
27002
|
+
issueNumber: ticket
|
|
26946
27003
|
};
|
|
26947
27004
|
}
|
|
26948
27005
|
function parseTaishiSweepModeInputFromJsonValue(value) {
|
|
@@ -27007,15 +27064,6 @@ async function runPublicTaishi(argv, _env, io, parseTaishiArgv2) {
|
|
|
27007
27064
|
groups: parsed.groups
|
|
27008
27065
|
});
|
|
27009
27066
|
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
27010
|
-
`);
|
|
27011
|
-
return { exitCode: 0 };
|
|
27012
|
-
}
|
|
27013
|
-
if (parsed.query === "model-groups") {
|
|
27014
|
-
const result3 = await runTaishi({
|
|
27015
|
-
mode: "model-groups",
|
|
27016
|
-
projectRoots: parsed.projectRoots
|
|
27017
|
-
});
|
|
27018
|
-
io.stdout(`${JSON.stringify(result3, null, 2)}
|
|
27019
27067
|
`);
|
|
27020
27068
|
return { exitCode: 0 };
|
|
27021
27069
|
}
|
|
@@ -27037,6 +27085,7 @@ async function runPublicTaishi(argv, _env, io, parseTaishiArgv2) {
|
|
|
27037
27085
|
...code === void 0 ? {} : { identity: { code } },
|
|
27038
27086
|
details: {
|
|
27039
27087
|
code: error.code,
|
|
27088
|
+
bookKey: error.bookKey,
|
|
27040
27089
|
projectRoot: error.projectRoot,
|
|
27041
27090
|
...error.issueNumber === void 0 ? {} : { issueNumber: error.issueNumber }
|
|
27042
27091
|
}
|
|
@@ -27050,9 +27099,9 @@ var init_taishi_run = __esm({
|
|
|
27050
27099
|
"src/public-cli/taishi-run.ts"() {
|
|
27051
27100
|
"use strict";
|
|
27052
27101
|
init_value2();
|
|
27102
|
+
init_activation_ledger_git();
|
|
27053
27103
|
init_activation_ledger_topology();
|
|
27054
27104
|
init_exact_utf8();
|
|
27055
|
-
init_taishi_index();
|
|
27056
27105
|
init_taishi_entry();
|
|
27057
27106
|
init_cli_errors();
|
|
27058
27107
|
init_settlement();
|