tianshu-harness 3.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +189 -0
- package/README.en.md +1066 -0
- package/README.ja.md +1214 -0
- package/README.ko.md +1216 -0
- package/README.md +309 -0
- package/completions/rivet.bash +118 -0
- package/completions/rivet.fish +110 -0
- package/completions/rivet.ps1 +230 -0
- package/completions/rivet.zsh +187 -0
- package/dist/account-OAEKORZE.js +47 -0
- package/dist/account-login-V6FOLHJR.js +65 -0
- package/dist/account-status-KHNPPAFL.js +23 -0
- package/dist/agent/worker-process/child.js +407 -0
- package/dist/browser-cli-FLNY5ZHI.js +19 -0
- package/dist/browser-readiness-LWVGSBD5.js +12 -0
- package/dist/build-backends-5KXKR2S4.js +13 -0
- package/dist/build-options-66Y4ZE7C.js +9 -0
- package/dist/bundled-skills/brainstorming/SKILL.md +139 -0
- package/dist/bundled-skills/visual-acceptance/SKILL.md +64 -0
- package/dist/chain-7MAMFXZ3.js +10 -0
- package/dist/checkpoint-MND4DUIX.js +33 -0
- package/dist/chunk-2E6CK2RC.js +392 -0
- package/dist/chunk-2EBWGAXD.js +51 -0
- package/dist/chunk-2HDP7RMR.js +119 -0
- package/dist/chunk-2HKD2UFM.js +1000 -0
- package/dist/chunk-2VYRLULP.js +51 -0
- package/dist/chunk-2XN7PM4N.js +125 -0
- package/dist/chunk-35H7GVNR.js +66 -0
- package/dist/chunk-3C3R7JXY.js +77 -0
- package/dist/chunk-3VGD2FXB.js +118 -0
- package/dist/chunk-424AP7FM.js +534 -0
- package/dist/chunk-4J5TZGOE.js +3707 -0
- package/dist/chunk-4QJ3Y5JM.js +898 -0
- package/dist/chunk-4U2ET7ZY.js +1326 -0
- package/dist/chunk-4XPFLICE.js +876 -0
- package/dist/chunk-5B2OCU5P.js +31707 -0
- package/dist/chunk-5GGOGLSN.js +73 -0
- package/dist/chunk-5JRZPLI6.js +251 -0
- package/dist/chunk-5TQ3JYBU.js +397 -0
- package/dist/chunk-66JPZSGX.js +55 -0
- package/dist/chunk-6HSVXHCZ.js +764 -0
- package/dist/chunk-6S5FPUS7.js +21 -0
- package/dist/chunk-722LQO64.js +131 -0
- package/dist/chunk-73NJ7IT7.js +354 -0
- package/dist/chunk-7FW3I7WC.js +95 -0
- package/dist/chunk-7KUCBNLB.js +173 -0
- package/dist/chunk-7RDOV3DF.js +201 -0
- package/dist/chunk-A5MNH4ER.js +79 -0
- package/dist/chunk-ADIVZ2D5.js +15 -0
- package/dist/chunk-AE3P3F6W.js +366 -0
- package/dist/chunk-AERM3VGP.js +280 -0
- package/dist/chunk-AEWHC4WM.js +246 -0
- package/dist/chunk-AOVQ7VIF.js +169 -0
- package/dist/chunk-AOYHP3WI.js +12411 -0
- package/dist/chunk-B3YEBABJ.js +7160 -0
- package/dist/chunk-BCQXEZPJ.js +154 -0
- package/dist/chunk-BKTQAYO2.js +418 -0
- package/dist/chunk-BSECIPAQ.js +80 -0
- package/dist/chunk-BUIMGNDD.js +52 -0
- package/dist/chunk-BXHV3GSB.js +10320 -0
- package/dist/chunk-C6ZVZCPP.js +139 -0
- package/dist/chunk-CEZNQVWM.js +82 -0
- package/dist/chunk-CGFZGR7G.js +1492 -0
- package/dist/chunk-CGOADM2X.js +337 -0
- package/dist/chunk-CI4R6P2B.js +24 -0
- package/dist/chunk-D2TCGRSX.js +73 -0
- package/dist/chunk-D4PTYFOG.js +154 -0
- package/dist/chunk-D54ZWG4T.js +717 -0
- package/dist/chunk-DEBI37QB.js +145 -0
- package/dist/chunk-DWROHPXP.js +1051 -0
- package/dist/chunk-DZ6UOJ5D.js +92 -0
- package/dist/chunk-EBJTVRQN.js +81 -0
- package/dist/chunk-EGEI2RQA.js +1167 -0
- package/dist/chunk-EHHUASO5.js +1305 -0
- package/dist/chunk-EPKTIOED.js +41 -0
- package/dist/chunk-ER5JW2QZ.js +5681 -0
- package/dist/chunk-ETHFACAB.js +315 -0
- package/dist/chunk-EXUE5W2F.js +112 -0
- package/dist/chunk-EXXICUIW.js +73 -0
- package/dist/chunk-FFQSZJOO.js +169 -0
- package/dist/chunk-FHFKPGDO.js +85 -0
- package/dist/chunk-FW3QKMFX.js +158 -0
- package/dist/chunk-GD4ZNZ7W.js +30 -0
- package/dist/chunk-GHVMWF2I.js +581 -0
- package/dist/chunk-GMKAXSYQ.js +297 -0
- package/dist/chunk-HBVF6BWO.js +325 -0
- package/dist/chunk-HV4YGVMS.js +379 -0
- package/dist/chunk-ILBCKAV6.js +89 -0
- package/dist/chunk-J4U4AW46.js +440 -0
- package/dist/chunk-J6ESSM47.js +1791 -0
- package/dist/chunk-JBZHIC6T.js +2309 -0
- package/dist/chunk-JCFWOULR.js +245 -0
- package/dist/chunk-JRF5L6OD.js +131 -0
- package/dist/chunk-JSS75KCG.js +2014 -0
- package/dist/chunk-JSXWIWWJ.js +225 -0
- package/dist/chunk-JYV7I2QH.js +98 -0
- package/dist/chunk-KIOXTQQL.js +1596 -0
- package/dist/chunk-KWVTXT5B.js +89 -0
- package/dist/chunk-KX22RD6R.js +33 -0
- package/dist/chunk-LA6IPTGH.js +709 -0
- package/dist/chunk-LH5VCGLB.js +1796 -0
- package/dist/chunk-LQQ6XJ2Y.js +269 -0
- package/dist/chunk-MJQ55WZZ.js +65 -0
- package/dist/chunk-ML3UKMH3.js +40 -0
- package/dist/chunk-MOZPLHSU.js +5526 -0
- package/dist/chunk-NGEWJ4DF.js +89 -0
- package/dist/chunk-NH6VIOAR.js +211 -0
- package/dist/chunk-O5VZQKCB.js +26106 -0
- package/dist/chunk-OHSV42QB.js +748 -0
- package/dist/chunk-OO3TAHO5.js +4070 -0
- package/dist/chunk-OTNHSAGN.js +38282 -0
- package/dist/chunk-OUWAC7AQ.js +442 -0
- package/dist/chunk-OXMIV4WE.js +270 -0
- package/dist/chunk-P5KJURUR.js +229 -0
- package/dist/chunk-P6GJOVO6.js +307 -0
- package/dist/chunk-QARAGUXX.js +23 -0
- package/dist/chunk-R43HJCDX.js +2711 -0
- package/dist/chunk-RAXBAWRN.js +210 -0
- package/dist/chunk-RK3JHWPT.js +39 -0
- package/dist/chunk-RWA23GMM.js +24 -0
- package/dist/chunk-S4K4L6IM.js +179 -0
- package/dist/chunk-SAXK6LVF.js +124 -0
- package/dist/chunk-SEPGEJNK.js +1607 -0
- package/dist/chunk-SUJERP5I.js +285 -0
- package/dist/chunk-T3ED6BY2.js +913 -0
- package/dist/chunk-THKDVSEC.js +90 -0
- package/dist/chunk-TI4GSEL5.js +52 -0
- package/dist/chunk-TPI73L57.js +164 -0
- package/dist/chunk-TVHW77C7.js +338 -0
- package/dist/chunk-TWNHOSDT.js +1073 -0
- package/dist/chunk-UFMN76QD.js +347 -0
- package/dist/chunk-UHGLFRZE.js +205 -0
- package/dist/chunk-UTZYPKBF.js +15231 -0
- package/dist/chunk-UXNLELW6.js +25 -0
- package/dist/chunk-UXXS53EA.js +166 -0
- package/dist/chunk-V5DHFGI7.js +171 -0
- package/dist/chunk-V5YIPMHV.js +2353 -0
- package/dist/chunk-WMUWEO2C.js +754 -0
- package/dist/chunk-WOE3D7JM.js +945 -0
- package/dist/chunk-X2IK5LVR.js +2592 -0
- package/dist/chunk-XU2YXCDL.js +459 -0
- package/dist/chunk-YJG5HIX5.js +203 -0
- package/dist/chunk-Z3QE7TZM.js +72 -0
- package/dist/chunk-Z5Z3JHJY.js +64 -0
- package/dist/chunk-ZDIFBJFT.js +168 -0
- package/dist/chunk-ZGGCEXDC.js +176 -0
- package/dist/chunk-ZMZCZNKU.js +263 -0
- package/dist/chunk-ZNC5T65N.js +17 -0
- package/dist/chunk-ZO3I3A7O.js +308 -0
- package/dist/chunk-ZQKXBUB7.js +217 -0
- package/dist/chunk-ZTRINFM2.js +78 -0
- package/dist/chunk-ZU7JZCVP.js +193 -0
- package/dist/chunk-ZZAWNALS.js +350 -0
- package/dist/cli/entry.js +54 -0
- package/dist/connector-L5QQTR6Y.js +26 -0
- package/dist/context-62DC6EC3.js +31 -0
- package/dist/council-convene-NJWPNBDU.js +46 -0
- package/dist/create-agent-config-ODSQWNVC.js +55 -0
- package/dist/default-registry-2PU3BTAU.js +68 -0
- package/dist/deliver-task-KONV4C4M.js +57 -0
- package/dist/delivery-gate-v2-F2YVMVGK.js +27 -0
- package/dist/domain-knowledge-store-DDZ3F4J7.js +11 -0
- package/dist/fetch-core-ZPPYDSZH.js +14 -0
- package/dist/galaxy-K72BBDQN.js +91 -0
- package/dist/goal-criteria-SCALAU2D.js +141 -0
- package/dist/goal-persist-XWY2GDQX.js +19 -0
- package/dist/goal-tracker-FXMJ2GVK.js +11 -0
- package/dist/headless-LSB6I7PT.js +162 -0
- package/dist/headless-coordinator-VDPDMVUT.js +90 -0
- package/dist/inject-U55SMB6A.js +39 -0
- package/dist/login-flow-CD4ZGXOC.js +59 -0
- package/dist/logs-cli-SQVYFMMN.js +283 -0
- package/dist/loop-ULZYBDA3.js +76 -0
- package/dist/main.js +4064 -0
- package/dist/manager-ROZBCWPA.js +171 -0
- package/dist/manager-Z7XFFUOM.js +10670 -0
- package/dist/meridian-indexer-ZIW363L7.js +21 -0
- package/dist/native-resolver-PN34UIVV.js +13 -0
- package/dist/node_modules/better-sqlite3/lib/database.js +90 -0
- package/dist/node_modules/better-sqlite3/lib/index.js +3 -0
- package/dist/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
- package/dist/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
- package/dist/node_modules/better-sqlite3/lib/methods/function.js +31 -0
- package/dist/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
- package/dist/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
- package/dist/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
- package/dist/node_modules/better-sqlite3/lib/methods/table.js +189 -0
- package/dist/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
- package/dist/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
- package/dist/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
- package/dist/node_modules/better-sqlite3/lib/util.js +12 -0
- package/dist/node_modules/better-sqlite3/package.json +59 -0
- package/dist/ownership-ledger-E3WIEKPL.js +9 -0
- package/dist/package.json +3 -0
- package/dist/path-grants-XRRXHXG7.js +40 -0
- package/dist/paths-LVV5IMQN.js +49 -0
- package/dist/plan-fact-anchors-LMVQZCW5.js +13 -0
- package/dist/plan-store-ODLTTPFB.js +17 -0
- package/dist/plan-templates-5FPFBOL6.js +109 -0
- package/dist/plugin-loader-ZZKX7ZE6.js +22 -0
- package/dist/prefix-budget-62OV5HQC.js +13 -0
- package/dist/project-trust-5WS5MOMU.js +31 -0
- package/dist/provider-cli-ALDQXIT7.js +37 -0
- package/dist/providers-XQYTAVPK.js +11 -0
- package/dist/proxy-resolver-V2Y6534D.js +15 -0
- package/dist/recovery-cli-KPGY6FY3.js +106 -0
- package/dist/review-discipline-MNSYCST5.js +55 -0
- package/dist/review-router-BVQZW3MX.js +18 -0
- package/dist/seed-capsules/seed-capsule-attack-methodology.md +62 -0
- package/dist/seed-capsules/seed-capsule-changgeng.md +31 -0
- package/dist/seed-capsules/seed-capsule-design-aesthetics.md +38 -0
- package/dist/seed-capsules/seed-capsule-diagnostic-ladder.md +54 -0
- package/dist/seed-capsules/seed-capsule-fu.md +39 -0
- package/dist/seed-capsules/seed-capsule-huagai.md +73 -0
- package/dist/seed-capsules/seed-capsule-kaiyang.md +65 -0
- package/dist/seed-capsules/seed-capsule-knowledge-work.md +40 -0
- package/dist/seed-capsules/seed-capsule-tanlang.md +47 -0
- package/dist/seed-capsules/seed-capsule-tianfu.md +23 -0
- package/dist/seed-capsules/seed-capsule-tianliang.md +63 -0
- package/dist/seed-capsules/seed-capsule-tianquan.md +32 -0
- package/dist/seed-capsules/seed-capsule-tianxuan-ccr.md +22 -0
- package/dist/seed-capsules/seed-capsule-tianxuan.md +64 -0
- package/dist/seed-capsules/seed-capsule-yaoguang.md +87 -0
- package/dist/serve-X2R2UTLF.js +170 -0
- package/dist/serve-agent-KHSU6RVV.js +965 -0
- package/dist/session-persist-HUUC772H.js +37 -0
- package/dist/session-registry-6XUD5C4Y.js +15 -0
- package/dist/skill-loader-CK3RMO47.js +48 -0
- package/dist/skills/cli-harness-sop.md +207 -0
- package/dist/spawn-git-4HFU65AH.js +29 -0
- package/dist/sse-EYUTBWUK.js +512 -0
- package/dist/starflow-NOFBMPFU.js +30 -0
- package/dist/streamableHttp-V67CNJMO.js +447 -0
- package/dist/task-contract-6XHBNJQK.js +32 -0
- package/dist/task-ledger-3K4TJIER.js +9 -0
- package/dist/team-orchestrate-S6NHZP7X.js +64 -0
- package/dist/title-extract-QX4XGCYN.js +50 -0
- package/dist/todo-QDXGRZZP.js +31 -0
- package/dist/todo-store-V3TTO5AH.js +12 -0
- package/dist/tool-preset-LU5BYEDZ.js +23 -0
- package/dist/tool-tiers-GD742YBN.js +23 -0
- package/dist/turndown.es-OI55K6C3.js +17373 -0
- package/dist/verification-attribution-EKG4CNUV.js +13 -0
- package/dist/volatile-git-MBTST7RA.js +15 -0
- package/dist/wave-checkpoint-XLIIHXQA.js +30 -0
- package/dist/web-cli-DUG4I35O.js +233 -0
- package/dist/web-search-3IK542AA.js +34 -0
- package/dist/workers/cpu-worker.js +45 -0
- package/dist/workflow-runner-HX7UBAYG.js +297 -0
- package/dist/worktree-baseline-O5NCU6M2.js +9 -0
- package/package.json +122 -0
- package/scripts/check-mobile-env.mjs +76 -0
- package/scripts/fetch-native-sqlite.js +392 -0
- package/scripts/prune-installed-wasms.js +45 -0
- package/scripts/tree-sitter-wasm-keep.js +40 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
|
|
2
|
+
import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
normalizeFrontmatterSource
|
|
5
|
+
} from "./chunk-ADIVZ2D5.js";
|
|
6
|
+
import {
|
|
7
|
+
STAR_DOMAINS
|
|
8
|
+
} from "./chunk-WMUWEO2C.js";
|
|
9
|
+
import {
|
|
10
|
+
init_esm_shims
|
|
11
|
+
} from "./chunk-5GGOGLSN.js";
|
|
12
|
+
|
|
13
|
+
// src/agent/star-domain-registry.ts
|
|
14
|
+
init_esm_shims();
|
|
15
|
+
|
|
16
|
+
// src/agent/star-domain.ts
|
|
17
|
+
init_esm_shims();
|
|
18
|
+
function matchDomain(taskDescription, pool) {
|
|
19
|
+
return starDomainRegistry.matchDomain(taskDescription, pool);
|
|
20
|
+
}
|
|
21
|
+
var DELEGATION_FALLBACK_AUTHORITY = "tianliang";
|
|
22
|
+
var MAX_AUTHORITY_KEYWORDS = 3;
|
|
23
|
+
var MAX_AUTHORITY_REASON_LEN = 60;
|
|
24
|
+
function deriveAuthority(objective) {
|
|
25
|
+
const detail = starDomainRegistry.matchDomainDetailed(objective);
|
|
26
|
+
if (detail.verdict === "hit" && detail.id) {
|
|
27
|
+
const kws = detail.matchedKeywords.slice(0, MAX_AUTHORITY_KEYWORDS);
|
|
28
|
+
const hit = kws.length > 0 ? `\u547D\u4E2D: ${kws.join("+")}` : `\u547D\u4E2D: ${detail.id}`;
|
|
29
|
+
return {
|
|
30
|
+
authority: detail.id,
|
|
31
|
+
reasons: [truncateReason(hit)],
|
|
32
|
+
detail
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (detail.verdict === "tie") {
|
|
36
|
+
const tied = (detail.tiedIds ?? []).map(labelDomain).join("/");
|
|
37
|
+
return {
|
|
38
|
+
authority: DELEGATION_FALLBACK_AUTHORITY,
|
|
39
|
+
reasons: [truncateReason(`\u5E73\u624B(${tied})\u2192\u5929\u6881\u515C\u5E95`)],
|
|
40
|
+
detail
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
authority: DELEGATION_FALLBACK_AUTHORITY,
|
|
45
|
+
reasons: [truncateReason("\u65E0\u5173\u952E\u8BCD\u547D\u4E2D\u2192\u5929\u6881\u515C\u5E95")],
|
|
46
|
+
detail
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function resolveAuthorityReason(objective, authority) {
|
|
50
|
+
if (!authority) return void 0;
|
|
51
|
+
const derived = deriveAuthority(objective);
|
|
52
|
+
if (authority === derived.authority && derived.detail.verdict === "hit") {
|
|
53
|
+
return derived.reasons[0];
|
|
54
|
+
}
|
|
55
|
+
return "\u663E\u5F0F\u6307\u5B9A";
|
|
56
|
+
}
|
|
57
|
+
function labelDomain(id) {
|
|
58
|
+
return starDomainRegistry.get(id)?.name ?? id;
|
|
59
|
+
}
|
|
60
|
+
function truncateReason(text) {
|
|
61
|
+
if (text.length <= MAX_AUTHORITY_REASON_LEN) return text;
|
|
62
|
+
return text.slice(0, MAX_AUTHORITY_REASON_LEN - 1) + "\u2026";
|
|
63
|
+
}
|
|
64
|
+
var DEFAULT_DOMAIN = "tianquan";
|
|
65
|
+
var DOMAIN_AUTO_POOL = ["tianquan", "kaiyang", "yaoguang", "tianliang"];
|
|
66
|
+
function resolveActiveDomain(taskDescription, opts) {
|
|
67
|
+
const keywordRouting = opts?.keywordRouting !== false;
|
|
68
|
+
const pool = [
|
|
69
|
+
...DOMAIN_AUTO_POOL,
|
|
70
|
+
...starDomainRegistry.list().filter((d) => d.isCustom).map((d) => d.id)
|
|
71
|
+
];
|
|
72
|
+
const detail = keywordRouting ? starDomainRegistry.matchDomainDetailed(taskDescription, pool) : null;
|
|
73
|
+
let matchedId = null;
|
|
74
|
+
let matchedKeywords = [];
|
|
75
|
+
if (detail?.verdict === "hit" && typeof detail.id === "string") {
|
|
76
|
+
matchedId = detail.id;
|
|
77
|
+
matchedKeywords = detail.matchedKeywords.slice(0, 3);
|
|
78
|
+
}
|
|
79
|
+
const id = matchedId ?? DEFAULT_DOMAIN;
|
|
80
|
+
const definition = starDomainRegistry.get(id) ?? STAR_DOMAINS[DEFAULT_DOMAIN];
|
|
81
|
+
return {
|
|
82
|
+
domain: {
|
|
83
|
+
id,
|
|
84
|
+
name: definition.name,
|
|
85
|
+
volatileBlock: definition.volatileBlock,
|
|
86
|
+
motto: definition.motto,
|
|
87
|
+
courageThreshold: definition.courageThreshold
|
|
88
|
+
},
|
|
89
|
+
matchedKeywords,
|
|
90
|
+
reason: matchedId ? "keyword" : "fallback"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/agent/star-domain-registry.ts
|
|
95
|
+
var MAX_STRING_FIELD_LENGTH = 2e3;
|
|
96
|
+
var MAX_ARRAY_ITEMS = 50;
|
|
97
|
+
var DOMAIN_ID_RE = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
98
|
+
var StarDomainRegistry = class {
|
|
99
|
+
domains = /* @__PURE__ */ new Map();
|
|
100
|
+
initialized = false;
|
|
101
|
+
constructor() {
|
|
102
|
+
}
|
|
103
|
+
/** Ensure built-in domains are loaded (lazy init breaks circular dep) */
|
|
104
|
+
ensureInit() {
|
|
105
|
+
if (this.initialized) return;
|
|
106
|
+
for (const domain of Object.values(STAR_DOMAINS)) {
|
|
107
|
+
this.domains.set(domain.id, domain);
|
|
108
|
+
}
|
|
109
|
+
this.initialized = true;
|
|
110
|
+
}
|
|
111
|
+
/** Load user domains from .rivet/domains/ directory.
|
|
112
|
+
* Each subdirectory is a domain card: <id>/card.md */
|
|
113
|
+
async loadFromDirectory(dir) {
|
|
114
|
+
this.ensureInit();
|
|
115
|
+
const loaded = [];
|
|
116
|
+
const errors = [];
|
|
117
|
+
try {
|
|
118
|
+
const { readdirSync } = await import("fs");
|
|
119
|
+
const { join } = await import("path");
|
|
120
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
if (!entry.isDirectory()) continue;
|
|
123
|
+
try {
|
|
124
|
+
const cardPath = join(dir, entry.name, "card.md");
|
|
125
|
+
const { readFileSync } = await import("fs");
|
|
126
|
+
const content = readFileSync(cardPath, "utf-8");
|
|
127
|
+
const def = parseDomainCard(content, entry.name);
|
|
128
|
+
if (this.domains.has(def.id) && this.domains.get(def.id).isCustom === false) {
|
|
129
|
+
errors.push(`${entry.name}: cannot override built-in domain "${def.id}"`);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (this.domains.has(def.id) && this.domains.get(def.id).isCustom === true) {
|
|
133
|
+
errors.push(`${entry.name}: duplicate custom domain id "${def.id}"`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
this.domains.set(def.id, def);
|
|
137
|
+
loaded.push(def.id);
|
|
138
|
+
} catch (e) {
|
|
139
|
+
errors.push(`${entry.name}: ${e instanceof Error ? e.message : String(e)}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
return { loaded, errors };
|
|
145
|
+
}
|
|
146
|
+
/** Get a domain definition by id */
|
|
147
|
+
get(id) {
|
|
148
|
+
this.ensureInit();
|
|
149
|
+
return this.domains.get(id);
|
|
150
|
+
}
|
|
151
|
+
/** Get all registered domain ids */
|
|
152
|
+
getDomainIds() {
|
|
153
|
+
this.ensureInit();
|
|
154
|
+
return [...this.domains.keys()];
|
|
155
|
+
}
|
|
156
|
+
/** Get all registered domains */
|
|
157
|
+
list() {
|
|
158
|
+
this.ensureInit();
|
|
159
|
+
return [...this.domains.values()];
|
|
160
|
+
}
|
|
161
|
+
/** Check if a domain id is registered */
|
|
162
|
+
has(id) {
|
|
163
|
+
this.ensureInit();
|
|
164
|
+
return this.domains.has(id);
|
|
165
|
+
}
|
|
166
|
+
/** Match a task description to the best domain by keyword scoring.
|
|
167
|
+
* Returns null if no domain matches (all scores = 0 or tie).
|
|
168
|
+
* `pool` 限定参与计分的域 id 集合(缺省 = 全集)——auto 路由收窄用。 */
|
|
169
|
+
matchDomain(taskDescription, pool) {
|
|
170
|
+
return this.matchDomainDetailed(taskDescription, pool).id;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Keyword-score match with audit detail: which keywords hit, hit/tie/no-match
|
|
174
|
+
* verdict, and optional runner-up. `matchDomain` is a thin `.id` projection —
|
|
175
|
+
* same inputs must keep returning the same id (or null).
|
|
176
|
+
*/
|
|
177
|
+
matchDomainDetailed(taskDescription, pool) {
|
|
178
|
+
this.ensureInit();
|
|
179
|
+
const lower = taskDescription.slice(0, MAX_MATCH_CHARS).toLowerCase();
|
|
180
|
+
const scores = /* @__PURE__ */ new Map();
|
|
181
|
+
const keywordsByDomain = /* @__PURE__ */ new Map();
|
|
182
|
+
for (const domain of this.domains.values()) {
|
|
183
|
+
if (pool !== void 0 && !pool.includes(domain.id)) continue;
|
|
184
|
+
let score = 0;
|
|
185
|
+
const matched = [];
|
|
186
|
+
for (const keyword of domain.keywords) {
|
|
187
|
+
if (lower.includes(keyword.toLowerCase())) {
|
|
188
|
+
score++;
|
|
189
|
+
matched.push(keyword);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (score > 0) {
|
|
193
|
+
scores.set(domain.id, score);
|
|
194
|
+
keywordsByDomain.set(domain.id, matched);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (scores.size === 0) {
|
|
198
|
+
return { id: null, matchedKeywords: [], verdict: "no-match" };
|
|
199
|
+
}
|
|
200
|
+
let max = 0;
|
|
201
|
+
for (const s of scores.values()) {
|
|
202
|
+
if (s > max) max = s;
|
|
203
|
+
}
|
|
204
|
+
const winners = [...scores.entries()].filter(([, s]) => s === max);
|
|
205
|
+
if (winners.length > 1) {
|
|
206
|
+
const tiedIds = winners.map(([id]) => id).sort();
|
|
207
|
+
return {
|
|
208
|
+
id: null,
|
|
209
|
+
matchedKeywords: [],
|
|
210
|
+
verdict: "tie",
|
|
211
|
+
tiedIds,
|
|
212
|
+
runnerUp: tiedIds[1]
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const winnerId = winners[0][0];
|
|
216
|
+
let runnerUp;
|
|
217
|
+
let runnerScore = 0;
|
|
218
|
+
for (const [id, s] of scores) {
|
|
219
|
+
if (id === winnerId) continue;
|
|
220
|
+
if (s > runnerScore) {
|
|
221
|
+
runnerScore = s;
|
|
222
|
+
runnerUp = id;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
id: winnerId,
|
|
227
|
+
matchedKeywords: keywordsByDomain.get(winnerId) ?? [],
|
|
228
|
+
verdict: "hit",
|
|
229
|
+
runnerUp
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
var MAX_MATCH_CHARS = 500;
|
|
234
|
+
function clamp(value, min, max) {
|
|
235
|
+
return Math.max(min, Math.min(max, value));
|
|
236
|
+
}
|
|
237
|
+
function validateDomainId(id) {
|
|
238
|
+
if (!DOMAIN_ID_RE.test(id)) {
|
|
239
|
+
throw new Error(`Invalid domain id "${id}": must be 1-32 lowercase alphanumeric/underscore/hyphen chars, starting with a letter`);
|
|
240
|
+
}
|
|
241
|
+
return id;
|
|
242
|
+
}
|
|
243
|
+
function sanitizeString(value, _fieldName) {
|
|
244
|
+
if (typeof value !== "string") return "";
|
|
245
|
+
return value.slice(0, MAX_STRING_FIELD_LENGTH).trim();
|
|
246
|
+
}
|
|
247
|
+
function sanitizeStringArray(value, _fieldName) {
|
|
248
|
+
if (!Array.isArray(value)) return [];
|
|
249
|
+
return value.filter((v) => typeof v === "string").slice(0, MAX_ARRAY_ITEMS).map((v) => v.trim()).filter((v) => v.length > 0);
|
|
250
|
+
}
|
|
251
|
+
function parseDomainCard(content, fallbackId) {
|
|
252
|
+
content = normalizeFrontmatterSource(content);
|
|
253
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
254
|
+
if (!fmMatch) {
|
|
255
|
+
throw new Error("Missing YAML frontmatter (--- delimiters)");
|
|
256
|
+
}
|
|
257
|
+
const raw = fmMatch[1];
|
|
258
|
+
const body = sanitizeString(fmMatch[2]?.trim(), "systemPromptSuffix");
|
|
259
|
+
const fm = {};
|
|
260
|
+
for (const line of raw.split("\n")) {
|
|
261
|
+
const m = line.match(/^(\w+):\s*(.*)$/);
|
|
262
|
+
if (m) {
|
|
263
|
+
const key = m[1];
|
|
264
|
+
const val = m[2].trim();
|
|
265
|
+
if (val.startsWith("[")) {
|
|
266
|
+
try {
|
|
267
|
+
fm[key] = JSON.parse(val.replace(/'/g, '"'));
|
|
268
|
+
} catch {
|
|
269
|
+
throw new Error(`Failed to parse array for field "${key}": "${val}"`);
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
fm[key] = val;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (typeof fm.name !== "string" || !fm.name.trim()) {
|
|
277
|
+
throw new Error("Missing required field: name");
|
|
278
|
+
}
|
|
279
|
+
const rawId = typeof fm.id === "string" && fm.id ? fm.id : fallbackId;
|
|
280
|
+
const id = validateDomainId(rawId);
|
|
281
|
+
const decisionStyle = fm.decisionStyle;
|
|
282
|
+
if (decisionStyle && !["bold", "cautious", "methodical"].includes(decisionStyle)) {
|
|
283
|
+
throw new Error(`Invalid decisionStyle "${decisionStyle}". Must be: bold, cautious, methodical`);
|
|
284
|
+
}
|
|
285
|
+
const accent = fm.accent;
|
|
286
|
+
const VALID_ACCENTS = ["primary", "secondary", "success", "warning", "error"];
|
|
287
|
+
if (accent && !VALID_ACCENTS.includes(accent)) {
|
|
288
|
+
throw new Error(`Invalid accent "${accent}". Must be: ${VALID_ACCENTS.join(", ")}`);
|
|
289
|
+
}
|
|
290
|
+
const separator = fm.separator;
|
|
291
|
+
const VALID_SEPARATORS = ["thin", "thick", "dots"];
|
|
292
|
+
if (separator && !VALID_SEPARATORS.includes(separator)) {
|
|
293
|
+
throw new Error(`Invalid separator "${separator}". Must be: ${VALID_SEPARATORS.join(", ")}`);
|
|
294
|
+
}
|
|
295
|
+
const keywords = sanitizeStringArray(fm.keywords, "keywords").filter(Boolean);
|
|
296
|
+
const toolWhitelist = sanitizeStringArray(fm.toolWhitelist, "toolWhitelist").filter(Boolean);
|
|
297
|
+
if (keywords.length === 0) {
|
|
298
|
+
throw new Error("keywords must contain at least one non-empty string value");
|
|
299
|
+
}
|
|
300
|
+
if (toolWhitelist.length === 0) {
|
|
301
|
+
throw new Error("toolWhitelist must contain at least one non-empty string value");
|
|
302
|
+
}
|
|
303
|
+
const name = sanitizeString(fm.name, "name");
|
|
304
|
+
const motto = sanitizeString(fm.motto, "motto");
|
|
305
|
+
const volatileBlock = sanitizeString(fm.volatileBlock, "volatileBlock");
|
|
306
|
+
return {
|
|
307
|
+
id,
|
|
308
|
+
name,
|
|
309
|
+
motto,
|
|
310
|
+
volatileBlock,
|
|
311
|
+
decisionStyle: decisionStyle ?? "methodical",
|
|
312
|
+
courageThreshold: clamp(
|
|
313
|
+
typeof fm.courageThreshold === "number" ? fm.courageThreshold : typeof fm.courageThreshold === "string" ? Number(fm.courageThreshold) || 0.5 : 0.5,
|
|
314
|
+
0,
|
|
315
|
+
1
|
|
316
|
+
),
|
|
317
|
+
keywords,
|
|
318
|
+
isCustom: true,
|
|
319
|
+
toolWhitelist,
|
|
320
|
+
systemPromptSuffix: body,
|
|
321
|
+
uiPersona: {
|
|
322
|
+
separator: separator ?? "dots",
|
|
323
|
+
accent: accent ?? "secondary",
|
|
324
|
+
glyph: typeof fm.glyph === "string" ? fm.glyph.slice(0, 4) : "\u25C6"
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
var starDomainRegistry = new StarDomainRegistry();
|
|
329
|
+
|
|
330
|
+
export {
|
|
331
|
+
starDomainRegistry,
|
|
332
|
+
matchDomain,
|
|
333
|
+
deriveAuthority,
|
|
334
|
+
resolveAuthorityReason,
|
|
335
|
+
DOMAIN_AUTO_POOL,
|
|
336
|
+
resolveActiveDomain
|
|
337
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
|
|
2
|
+
import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
init_esm_shims
|
|
5
|
+
} from "./chunk-5GGOGLSN.js";
|
|
6
|
+
|
|
7
|
+
// src/utils/debug.ts
|
|
8
|
+
init_esm_shims();
|
|
9
|
+
var isDebugEnabled = () => {
|
|
10
|
+
const flag = process.env.RIVET_DEBUG?.toLowerCase();
|
|
11
|
+
return flag === "1" || flag === "true";
|
|
12
|
+
};
|
|
13
|
+
var debugLog = (...args) => {
|
|
14
|
+
if (isDebugEnabled()) {
|
|
15
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
16
|
+
console.warn(`[${ts}]`, ...args);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var debugEnabled = () => isDebugEnabled();
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
debugLog,
|
|
23
|
+
debugEnabled
|
|
24
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
|
|
2
|
+
import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
init_esm_shims
|
|
5
|
+
} from "./chunk-5GGOGLSN.js";
|
|
6
|
+
|
|
7
|
+
// src/agent/worktree-baseline.ts
|
|
8
|
+
init_esm_shims();
|
|
9
|
+
import { createHash } from "crypto";
|
|
10
|
+
function createWorktreeBaseline(snapshot) {
|
|
11
|
+
const externalSet = /* @__PURE__ */ new Set([
|
|
12
|
+
...snapshot.preExistingDirty,
|
|
13
|
+
...snapshot.preExistingUntracked
|
|
14
|
+
]);
|
|
15
|
+
let _baselineHash = null;
|
|
16
|
+
function computeBaselineHash() {
|
|
17
|
+
const canonical = JSON.stringify({
|
|
18
|
+
branch: snapshot.branch,
|
|
19
|
+
head: snapshot.head,
|
|
20
|
+
preExistingDirty: [...snapshot.preExistingDirty].sort(),
|
|
21
|
+
preExistingUntracked: [...snapshot.preExistingUntracked].sort()
|
|
22
|
+
});
|
|
23
|
+
return createHash("sha256").update(canonical).digest("hex");
|
|
24
|
+
}
|
|
25
|
+
function getBaselineHash() {
|
|
26
|
+
if (!_baselineHash) {
|
|
27
|
+
_baselineHash = computeBaselineHash();
|
|
28
|
+
}
|
|
29
|
+
return _baselineHash;
|
|
30
|
+
}
|
|
31
|
+
function isExternal(filePath) {
|
|
32
|
+
if (!filePath) return false;
|
|
33
|
+
return externalSet.has(filePath);
|
|
34
|
+
}
|
|
35
|
+
function getExternalFiles() {
|
|
36
|
+
return [...externalSet].sort();
|
|
37
|
+
}
|
|
38
|
+
function getExternalDirtyCount() {
|
|
39
|
+
return snapshot.preExistingDirty.length;
|
|
40
|
+
}
|
|
41
|
+
function getExternalUntrackedCount() {
|
|
42
|
+
return snapshot.preExistingUntracked.length;
|
|
43
|
+
}
|
|
44
|
+
function getBranch() {
|
|
45
|
+
return snapshot.branch;
|
|
46
|
+
}
|
|
47
|
+
function getHead() {
|
|
48
|
+
return snapshot.head;
|
|
49
|
+
}
|
|
50
|
+
function toSnapshot() {
|
|
51
|
+
return {
|
|
52
|
+
branch: snapshot.branch,
|
|
53
|
+
head: snapshot.head,
|
|
54
|
+
preExistingDirty: [...snapshot.preExistingDirty],
|
|
55
|
+
preExistingUntracked: [...snapshot.preExistingUntracked],
|
|
56
|
+
capturedAt: snapshot.capturedAt
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
getBranch,
|
|
61
|
+
getHead,
|
|
62
|
+
isExternal,
|
|
63
|
+
getExternalFiles,
|
|
64
|
+
getExternalDirtyCount,
|
|
65
|
+
getExternalUntrackedCount,
|
|
66
|
+
getBaselineHash,
|
|
67
|
+
toSnapshot
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export {
|
|
72
|
+
createWorktreeBaseline
|
|
73
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
|
|
2
|
+
import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
profileRegistry
|
|
5
|
+
} from "./chunk-6HSVXHCZ.js";
|
|
6
|
+
import {
|
|
7
|
+
spawnGitSync
|
|
8
|
+
} from "./chunk-THKDVSEC.js";
|
|
9
|
+
import {
|
|
10
|
+
init_esm_shims
|
|
11
|
+
} from "./chunk-5GGOGLSN.js";
|
|
12
|
+
|
|
13
|
+
// src/agent/budget-shape.ts
|
|
14
|
+
init_esm_shims();
|
|
15
|
+
var WRITE_DEFAULT_MAX_TURNS = 48;
|
|
16
|
+
var SHAPE_MAX_TURNS_CEIL = 100;
|
|
17
|
+
var SHAPE_TIMEOUT_CEIL_MS = 18e5;
|
|
18
|
+
var TURNS_PER_EXTRA_FILE = 6;
|
|
19
|
+
var MS_PER_EXTRA_FILE = 45e3;
|
|
20
|
+
function shapeBudgetEnabled() {
|
|
21
|
+
return process.env.RIVET_WORKER_BUDGET_SHAPE !== "0";
|
|
22
|
+
}
|
|
23
|
+
function shapeWriteBudget(input) {
|
|
24
|
+
const baseTurns = input.baseMaxTurns ?? WRITE_DEFAULT_MAX_TURNS;
|
|
25
|
+
const extra = Math.max(0, (input.files?.length ?? 0) - 1);
|
|
26
|
+
return {
|
|
27
|
+
maxTurns: Math.min(SHAPE_MAX_TURNS_CEIL, baseTurns + TURNS_PER_EXTRA_FILE * extra),
|
|
28
|
+
timeoutMs: Math.min(SHAPE_TIMEOUT_CEIL_MS, input.baseTimeoutMs + MS_PER_EXTRA_FILE * extra)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function shapeWriteBudgetForProfile(files, profile) {
|
|
32
|
+
if (!shapeBudgetEnabled() || !profile) return void 0;
|
|
33
|
+
if ((files?.length ?? 0) <= 1) return void 0;
|
|
34
|
+
if (!profileRegistry.listWriteProfiles().includes(profile)) return void 0;
|
|
35
|
+
const baseTimeoutMs = profileRegistry.get(profile)?.defaultTimeoutMs ?? 48e4;
|
|
36
|
+
return shapeWriteBudget({ files, baseTimeoutMs });
|
|
37
|
+
}
|
|
38
|
+
function mergeBudgetOverride(explicit, shape) {
|
|
39
|
+
if (!shape) return explicit;
|
|
40
|
+
if (!explicit) return shape;
|
|
41
|
+
return {
|
|
42
|
+
...explicit,
|
|
43
|
+
...explicit.maxTurns === void 0 ? { maxTurns: shape.maxTurns } : {},
|
|
44
|
+
...explicit.timeoutMs === void 0 ? { timeoutMs: shape.timeoutMs } : {}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function historyBudgetEnabled() {
|
|
48
|
+
return process.env.RIVET_WORKER_BUDGET_HISTORY !== "0";
|
|
49
|
+
}
|
|
50
|
+
var HISTORY_SAMPLE_LIMIT = 5;
|
|
51
|
+
var NEAR_MISS_RATIO = 0.8;
|
|
52
|
+
var TURNS_FROM_TOOL_USES = 1.15;
|
|
53
|
+
var EXHAUSTION_HEADROOM = 1.3;
|
|
54
|
+
var HISTORY_LIFT_CAP = 3;
|
|
55
|
+
function historyBudgetFloor(samples, current) {
|
|
56
|
+
const valid = samples.filter((s) => Boolean(s) && ((s.toolUses ?? 0) > 0 || (s.durationMs ?? 0) > 0));
|
|
57
|
+
if (valid.length === 0) return void 0;
|
|
58
|
+
const triggered = valid.some((s) => s.exhausted === true || s.toolUses > 0 && s.toolUses >= NEAR_MISS_RATIO * (s.budget?.maxTurns ?? current.maxTurns));
|
|
59
|
+
if (!triggered) return void 0;
|
|
60
|
+
const maxToolUses = Math.max(...valid.map((s) => s.toolUses));
|
|
61
|
+
const maxDuration = Math.max(...valid.map((s) => s.durationMs));
|
|
62
|
+
const priorTurns = Math.ceil(maxToolUses * TURNS_FROM_TOOL_USES * EXHAUSTION_HEADROOM);
|
|
63
|
+
const priorTimeout = Math.ceil(maxDuration * EXHAUSTION_HEADROOM);
|
|
64
|
+
const lift = {
|
|
65
|
+
maxTurns: Math.min(
|
|
66
|
+
SHAPE_MAX_TURNS_CEIL,
|
|
67
|
+
Math.max(current.maxTurns, priorTurns),
|
|
68
|
+
current.maxTurns * HISTORY_LIFT_CAP
|
|
69
|
+
),
|
|
70
|
+
timeoutMs: Math.min(
|
|
71
|
+
SHAPE_TIMEOUT_CEIL_MS,
|
|
72
|
+
Math.max(current.timeoutMs, priorTimeout),
|
|
73
|
+
current.timeoutMs * HISTORY_LIFT_CAP
|
|
74
|
+
)
|
|
75
|
+
};
|
|
76
|
+
if (lift.maxTurns <= current.maxTurns && lift.timeoutMs <= current.timeoutMs) return void 0;
|
|
77
|
+
return lift;
|
|
78
|
+
}
|
|
79
|
+
function parseWorkerActualRows(rows, objectiveHash) {
|
|
80
|
+
const prefix = `worker_actual:${objectiveHash}:`;
|
|
81
|
+
const samples = [];
|
|
82
|
+
for (const row of rows ?? []) {
|
|
83
|
+
if (!row?.kind?.startsWith(prefix)) continue;
|
|
84
|
+
try {
|
|
85
|
+
const parsed = JSON.parse(row.json);
|
|
86
|
+
if (typeof parsed.toolUses !== "number" && typeof parsed.durationMs !== "number") continue;
|
|
87
|
+
samples.push({
|
|
88
|
+
toolUses: typeof parsed.toolUses === "number" ? parsed.toolUses : 0,
|
|
89
|
+
durationMs: typeof parsed.durationMs === "number" ? parsed.durationMs : 0,
|
|
90
|
+
...parsed.exhausted === true ? { exhausted: true } : {},
|
|
91
|
+
...parsed.budget && typeof parsed.budget === "object" ? { budget: parsed.budget } : {}
|
|
92
|
+
});
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return samples.slice(0, HISTORY_SAMPLE_LIMIT);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/agent/diff-collector.ts
|
|
100
|
+
init_esm_shims();
|
|
101
|
+
function git(cwd, args) {
|
|
102
|
+
const result = spawnGitSync(["-c", "core.quotePath=false", ...args], {
|
|
103
|
+
cwd,
|
|
104
|
+
encoding: "utf-8",
|
|
105
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
ok: result.status === 0,
|
|
109
|
+
stdout: typeof result.stdout === "string" ? result.stdout : ""
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function collectDiff(_baseCwd, workerCwd, baseBranch, excludePaths = []) {
|
|
113
|
+
const parts = [];
|
|
114
|
+
const pathspec = excludePaths.length > 0 ? ["--", ".", ...excludePaths.map((p) => `:(exclude)${p}`)] : [];
|
|
115
|
+
const committed = git(workerCwd, ["diff", `${baseBranch}...HEAD`, ...pathspec]);
|
|
116
|
+
if (committed.ok && committed.stdout.trim()) {
|
|
117
|
+
parts.push(committed.stdout);
|
|
118
|
+
}
|
|
119
|
+
git(workerCwd, ["add", "-A", ...pathspec]);
|
|
120
|
+
const staged = git(workerCwd, ["diff", "--cached", "HEAD", ...pathspec]);
|
|
121
|
+
if (staged.ok && staged.stdout.trim()) {
|
|
122
|
+
parts.push(staged.stdout);
|
|
123
|
+
}
|
|
124
|
+
return parts.join("");
|
|
125
|
+
}
|
|
126
|
+
function formatDiffArtifact(diff, _profile) {
|
|
127
|
+
const files = extractChangedFiles(diff);
|
|
128
|
+
return {
|
|
129
|
+
kind: "diff",
|
|
130
|
+
title: files.length > 0 ? `Patch: ${files.join(", ")}` : "Patch (empty)",
|
|
131
|
+
content: diff.length > 0 ? diff : "(empty diff)"
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function extractChangedFiles(diff) {
|
|
135
|
+
const re = /^\+\+\+ b\/(.+)$/gm;
|
|
136
|
+
const files = [];
|
|
137
|
+
let m;
|
|
138
|
+
while ((m = re.exec(diff)) !== null) {
|
|
139
|
+
files.push(m[1]);
|
|
140
|
+
}
|
|
141
|
+
return files;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export {
|
|
145
|
+
WRITE_DEFAULT_MAX_TURNS,
|
|
146
|
+
shapeWriteBudgetForProfile,
|
|
147
|
+
mergeBudgetOverride,
|
|
148
|
+
historyBudgetEnabled,
|
|
149
|
+
historyBudgetFloor,
|
|
150
|
+
parseWorkerActualRows,
|
|
151
|
+
collectDiff,
|
|
152
|
+
formatDiffArtifact,
|
|
153
|
+
extractChangedFiles
|
|
154
|
+
};
|