pi-crew 0.9.28 → 0.9.29
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/build-meta.json +158 -91
- package/dist/index.mjs +893 -507
- package/dist/index.mjs.map +4 -4
- package/docs/REVIEW-FINDINGS-2026-07-CORE.md +139 -0
- package/docs/REVIEW-FINDINGS-2026-07.md +125 -0
- package/docs/bugs/bug-quota-display-truncation.md +223 -0
- package/docs/stories/README.md +3 -1
- package/docs/stories/US-DEPS-major-upgrade.md +62 -0
- package/package.json +4 -4
- package/src/config/config.ts +4 -0
- package/src/extension/crew-vibes/config.ts +1 -1
- package/src/extension/crew-vibes/footer.ts +292 -0
- package/src/extension/crew-vibes/index.ts +67 -52
- package/src/prompt/prompt-runtime.ts +1 -1
- package/src/runtime/child-pi.ts +52 -43
- package/src/runtime/cross-extension-rpc.ts +1 -1
- package/src/runtime/post-exit-stdio-guard.ts +22 -4
- package/src/runtime/stale-reconciler.ts +9 -4
- package/src/runtime/team-runner.ts +11 -16
- package/src/state/atomic-write.ts +46 -19
- package/src/state/event-log.ts +77 -24
- package/src/state/mailbox.ts +6 -3
- package/src/ui/pi-ui-compat.ts +11 -0
- package/src/utils/conflict-detect.ts +9 -3
- package/src/utils/paths.ts +7 -1
- package/src/worktree/cleanup.ts +19 -0
- package/src/worktree/worktree-manager.ts +145 -34
package/dist/index.mjs
CHANGED
|
@@ -1810,7 +1810,7 @@ var init_iterator2 = __esm({
|
|
|
1810
1810
|
function RequiredArray(properties) {
|
|
1811
1811
|
return globalThis.Object.keys(properties).filter((key) => !IsOptional(properties[key]));
|
|
1812
1812
|
}
|
|
1813
|
-
function
|
|
1813
|
+
function _Object_(properties, options) {
|
|
1814
1814
|
const required = RequiredArray(properties);
|
|
1815
1815
|
const schema = required.length > 0 ? { [Kind]: "Object", type: "object", required, properties } : { [Kind]: "Object", type: "object", properties };
|
|
1816
1816
|
return CreateType(schema, options);
|
|
@@ -1821,7 +1821,7 @@ var init_object = __esm({
|
|
|
1821
1821
|
init_type2();
|
|
1822
1822
|
init_symbols2();
|
|
1823
1823
|
init_kind();
|
|
1824
|
-
Object2 =
|
|
1824
|
+
Object2 = _Object_;
|
|
1825
1825
|
}
|
|
1826
1826
|
});
|
|
1827
1827
|
|
|
@@ -4435,6 +4435,12 @@ var init_esm = __esm({
|
|
|
4435
4435
|
}
|
|
4436
4436
|
});
|
|
4437
4437
|
|
|
4438
|
+
// node_modules/@sinclair/typebox/build/esm/system/evaluate.mjs
|
|
4439
|
+
var init_evaluate = __esm({
|
|
4440
|
+
"node_modules/@sinclair/typebox/build/esm/system/evaluate.mjs"() {
|
|
4441
|
+
}
|
|
4442
|
+
});
|
|
4443
|
+
|
|
4438
4444
|
// node_modules/@sinclair/typebox/build/esm/system/system.mjs
|
|
4439
4445
|
var TypeSystemDuplicateTypeKind, TypeSystemDuplicateFormat, TypeSystem;
|
|
4440
4446
|
var init_system = __esm({
|
|
@@ -4475,6 +4481,7 @@ var init_system = __esm({
|
|
|
4475
4481
|
// node_modules/@sinclair/typebox/build/esm/system/index.mjs
|
|
4476
4482
|
var init_system2 = __esm({
|
|
4477
4483
|
"node_modules/@sinclair/typebox/build/esm/system/index.mjs"() {
|
|
4484
|
+
init_evaluate();
|
|
4478
4485
|
init_policy();
|
|
4479
4486
|
init_system();
|
|
4480
4487
|
}
|
|
@@ -8522,8 +8529,8 @@ function sleepSync(ms) {
|
|
|
8522
8529
|
}
|
|
8523
8530
|
function sleep(ms, signal) {
|
|
8524
8531
|
if (signal?.aborted) return Promise.reject(new Error("aborted"));
|
|
8525
|
-
return new Promise((
|
|
8526
|
-
const timer = setTimeout(
|
|
8532
|
+
return new Promise((resolve22, reject) => {
|
|
8533
|
+
const timer = setTimeout(resolve22, ms);
|
|
8527
8534
|
signal?.addEventListener(
|
|
8528
8535
|
"abort",
|
|
8529
8536
|
() => {
|
|
@@ -8567,9 +8574,9 @@ function getWorker() {
|
|
|
8567
8574
|
return worker;
|
|
8568
8575
|
}
|
|
8569
8576
|
function dispatch(kind, payload) {
|
|
8570
|
-
return new Promise((
|
|
8577
|
+
return new Promise((resolve22, reject) => {
|
|
8571
8578
|
const id = nextRequestId++;
|
|
8572
|
-
pending.set(id, { resolve:
|
|
8579
|
+
pending.set(id, { resolve: resolve22, reject });
|
|
8573
8580
|
try {
|
|
8574
8581
|
getWorker().postMessage({ kind, id, ...payload });
|
|
8575
8582
|
} catch (error) {
|
|
@@ -8802,7 +8809,7 @@ function isSymlinkSafeDirCached(filePath) {
|
|
|
8802
8809
|
return verdict;
|
|
8803
8810
|
}
|
|
8804
8811
|
function sleep2(ms) {
|
|
8805
|
-
return new Promise((
|
|
8812
|
+
return new Promise((resolve22) => setTimeout(resolve22, ms));
|
|
8806
8813
|
}
|
|
8807
8814
|
function isRetryableRenameError(error) {
|
|
8808
8815
|
return Boolean(
|
|
@@ -8819,16 +8826,25 @@ function renameWithLinkSync(tempPath, filePath, retries = 8) {
|
|
|
8819
8826
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
8820
8827
|
try {
|
|
8821
8828
|
if (process.platform === "win32") {
|
|
8822
|
-
try {
|
|
8823
|
-
fs2.unlinkSync(filePath);
|
|
8824
|
-
} catch {
|
|
8825
|
-
}
|
|
8826
8829
|
try {
|
|
8827
8830
|
fs2.renameSync(tempPath, filePath);
|
|
8828
8831
|
return;
|
|
8829
8832
|
} catch (renameError) {
|
|
8830
8833
|
lastError = renameError;
|
|
8831
|
-
if (
|
|
8834
|
+
if (isRetryableLinkError(renameError) && attempt !== retries) {
|
|
8835
|
+
} else {
|
|
8836
|
+
try {
|
|
8837
|
+
fs2.unlinkSync(filePath);
|
|
8838
|
+
} catch {
|
|
8839
|
+
}
|
|
8840
|
+
try {
|
|
8841
|
+
fs2.renameSync(tempPath, filePath);
|
|
8842
|
+
return;
|
|
8843
|
+
} catch (renameError2) {
|
|
8844
|
+
lastError = renameError2;
|
|
8845
|
+
if (!isRetryableLinkError(renameError2) || attempt === retries) break;
|
|
8846
|
+
}
|
|
8847
|
+
}
|
|
8832
8848
|
}
|
|
8833
8849
|
} else {
|
|
8834
8850
|
try {
|
|
@@ -8854,16 +8870,25 @@ async function renameWithLinkAsync(tempPath, filePath, retries = 8) {
|
|
|
8854
8870
|
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
8855
8871
|
try {
|
|
8856
8872
|
if (process.platform === "win32") {
|
|
8857
|
-
try {
|
|
8858
|
-
await fs2.promises.unlink(filePath);
|
|
8859
|
-
} catch {
|
|
8860
|
-
}
|
|
8861
8873
|
try {
|
|
8862
8874
|
await fs2.promises.rename(tempPath, filePath);
|
|
8863
8875
|
return;
|
|
8864
8876
|
} catch (renameError) {
|
|
8865
8877
|
lastError = renameError;
|
|
8866
|
-
if (
|
|
8878
|
+
if (isRetryableLinkError(renameError) && attempt !== retries) {
|
|
8879
|
+
} else {
|
|
8880
|
+
try {
|
|
8881
|
+
await fs2.promises.unlink(filePath);
|
|
8882
|
+
} catch {
|
|
8883
|
+
}
|
|
8884
|
+
try {
|
|
8885
|
+
await fs2.promises.rename(tempPath, filePath);
|
|
8886
|
+
return;
|
|
8887
|
+
} catch (renameError2) {
|
|
8888
|
+
lastError = renameError2;
|
|
8889
|
+
if (!isRetryableLinkError(renameError2) || attempt === retries) break;
|
|
8890
|
+
}
|
|
8891
|
+
}
|
|
8867
8892
|
}
|
|
8868
8893
|
} else {
|
|
8869
8894
|
try {
|
|
@@ -9400,7 +9425,7 @@ function acquireLockWithRetry(filePath, staleMs, kind = "file") {
|
|
|
9400
9425
|
}
|
|
9401
9426
|
}
|
|
9402
9427
|
function sleep3(ms) {
|
|
9403
|
-
return new Promise((
|
|
9428
|
+
return new Promise((resolve22) => setTimeout(resolve22, ms));
|
|
9404
9429
|
}
|
|
9405
9430
|
async function acquireLockWithRetryAsync(filePath, staleMs, kind = "file") {
|
|
9406
9431
|
let attempt = 0;
|
|
@@ -9533,7 +9558,8 @@ function packageRoot() {
|
|
|
9533
9558
|
return path4.resolve(path4.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
9534
9559
|
}
|
|
9535
9560
|
function userPiRoot() {
|
|
9536
|
-
const
|
|
9561
|
+
const rawHome = process.env.PI_TEAMS_HOME?.trim();
|
|
9562
|
+
const home = rawHome && rawHome !== "undefined" ? rawHome : os2.homedir();
|
|
9537
9563
|
const resolved = path4.join(home, ".pi", "agent");
|
|
9538
9564
|
let isSymlink2 = false;
|
|
9539
9565
|
try {
|
|
@@ -10254,7 +10280,11 @@ function parseWorktreeConfig(value) {
|
|
|
10254
10280
|
const worktree = {
|
|
10255
10281
|
setupHook: setupHook ? setupHook : void 0,
|
|
10256
10282
|
setupHookTimeoutMs: parsePositiveInteger(obj.setupHookTimeoutMs, 3e5),
|
|
10257
|
-
linkNodeModules: parseWithSchema(Type.Boolean(), obj.linkNodeModules)
|
|
10283
|
+
linkNodeModules: parseWithSchema(Type.Boolean(), obj.linkNodeModules),
|
|
10284
|
+
// C6: seedPaths was declared in the type + schema but never parsed here, so
|
|
10285
|
+
// loadedConfig.config.worktree?.seedPaths was always undefined -> the global
|
|
10286
|
+
// worktree seed overlay (worktree-manager.ts) silently never applied.
|
|
10287
|
+
seedPaths: parseStringList(obj.seedPaths)
|
|
10258
10288
|
};
|
|
10259
10289
|
return Object.values(worktree).some((entry) => entry !== void 0) ? worktree : void 0;
|
|
10260
10290
|
}
|
|
@@ -11300,7 +11330,7 @@ function redactInlineSecrets(value) {
|
|
|
11300
11330
|
if (keyLen > 0 && j < value.length && (value[j] === "=" || value[j] === ":")) {
|
|
11301
11331
|
const key = value.substring(i2, j);
|
|
11302
11332
|
if (isSecretKey(key)) {
|
|
11303
|
-
const
|
|
11333
|
+
const sep10 = value[j];
|
|
11304
11334
|
let k = j + 1;
|
|
11305
11335
|
let valLen = 0;
|
|
11306
11336
|
while (k < value.length && valLen < 500 && value[k] !== " " && value[k] !== "," && value[k] !== ";" && value[k] !== '"' && value[k] !== "\r" && value[k] !== "\n") {
|
|
@@ -11309,7 +11339,7 @@ function redactInlineSecrets(value) {
|
|
|
11309
11339
|
}
|
|
11310
11340
|
if (valLen > 0) {
|
|
11311
11341
|
result4.push(key);
|
|
11312
|
-
result4.push(
|
|
11342
|
+
result4.push(sep10);
|
|
11313
11343
|
result4.push("***");
|
|
11314
11344
|
i2 = k;
|
|
11315
11345
|
redacted = true;
|
|
@@ -11676,6 +11706,19 @@ function persistSequence(eventsPath, seq) {
|
|
|
11676
11706
|
logInternalError("event-log.persist-sequence-file", error, `eventsPath=${eventsPath}`);
|
|
11677
11707
|
}
|
|
11678
11708
|
}
|
|
11709
|
+
function reserveSequence(eventsPath) {
|
|
11710
|
+
let last = seqCounters.get(eventsPath);
|
|
11711
|
+
if (last === void 0) {
|
|
11712
|
+
last = nextSequence(eventsPath) - 1;
|
|
11713
|
+
}
|
|
11714
|
+
const next = last + 1;
|
|
11715
|
+
seqCounters.set(eventsPath, next);
|
|
11716
|
+
return next;
|
|
11717
|
+
}
|
|
11718
|
+
function advanceSequenceCounter(eventsPath, seq) {
|
|
11719
|
+
const last = seqCounters.get(eventsPath);
|
|
11720
|
+
if (last === void 0 || seq > last) seqCounters.set(eventsPath, seq);
|
|
11721
|
+
}
|
|
11679
11722
|
function computeEventFingerprint(event) {
|
|
11680
11723
|
return createHash2("sha256").update(
|
|
11681
11724
|
JSON.stringify({
|
|
@@ -11717,11 +11760,14 @@ async function withEventLogLockAsync(eventsPath, fn) {
|
|
|
11717
11760
|
try {
|
|
11718
11761
|
await next;
|
|
11719
11762
|
} finally {
|
|
11720
|
-
asyncLocks.
|
|
11763
|
+
if (asyncLocks.get(queueKey) === next) {
|
|
11764
|
+
asyncLocks.delete(queueKey);
|
|
11765
|
+
}
|
|
11721
11766
|
}
|
|
11722
11767
|
}
|
|
11723
11768
|
function resetEventLogMode() {
|
|
11724
11769
|
asyncQueues.clear();
|
|
11770
|
+
seqCounters.clear();
|
|
11725
11771
|
}
|
|
11726
11772
|
async function appendEventAsync(eventsPath, event) {
|
|
11727
11773
|
const queueKey = eventsPath;
|
|
@@ -11732,8 +11778,9 @@ async function appendEventAsync(eventsPath, event) {
|
|
|
11732
11778
|
let seq;
|
|
11733
11779
|
if (baseMetadata?.seq !== void 0) {
|
|
11734
11780
|
seq = baseMetadata.seq;
|
|
11781
|
+
advanceSequenceCounter(eventsPath, seq);
|
|
11735
11782
|
} else {
|
|
11736
|
-
seq =
|
|
11783
|
+
seq = reserveSequence(eventsPath);
|
|
11737
11784
|
}
|
|
11738
11785
|
let metadata = {
|
|
11739
11786
|
seq,
|
|
@@ -11857,21 +11904,21 @@ async function appendEventAsync(eventsPath, event) {
|
|
|
11857
11904
|
}
|
|
11858
11905
|
return fullEvent;
|
|
11859
11906
|
});
|
|
11860
|
-
|
|
11861
|
-
|
|
11862
|
-
|
|
11863
|
-
() => {
|
|
11907
|
+
const tail = next.then(
|
|
11908
|
+
() => {
|
|
11909
|
+
if (asyncQueues.get(queueKey) === tail) {
|
|
11864
11910
|
asyncQueues.delete(queueKey);
|
|
11865
|
-
},
|
|
11866
|
-
(error) => {
|
|
11867
|
-
try {
|
|
11868
|
-
logInternalError("event-log.async-queue", error, eventsPath);
|
|
11869
|
-
} catch {
|
|
11870
|
-
}
|
|
11871
|
-
asyncQueues.set(queueKey, Promise.resolve());
|
|
11872
11911
|
}
|
|
11873
|
-
|
|
11912
|
+
},
|
|
11913
|
+
(error) => {
|
|
11914
|
+
try {
|
|
11915
|
+
logInternalError("event-log.async-queue", error, eventsPath);
|
|
11916
|
+
} catch {
|
|
11917
|
+
}
|
|
11918
|
+
asyncQueues.set(queueKey, Promise.resolve());
|
|
11919
|
+
}
|
|
11874
11920
|
);
|
|
11921
|
+
asyncQueues.set(queueKey, tail);
|
|
11875
11922
|
return next;
|
|
11876
11923
|
}
|
|
11877
11924
|
async function appendEventBatchInsideLock(eventsPath, queue) {
|
|
@@ -11895,7 +11942,7 @@ async function appendEventBatchInsideLock(eventsPath, queue) {
|
|
|
11895
11942
|
} catch (error) {
|
|
11896
11943
|
logInternalError("event-log.batch-size-check", error, `eventsPath=${eventsPath}`);
|
|
11897
11944
|
}
|
|
11898
|
-
const startingSeq = queue[0]?.event.metadata?.seq ??
|
|
11945
|
+
const startingSeq = queue[0]?.event.metadata?.seq ?? reserveSequence(eventsPath);
|
|
11899
11946
|
let nextSeq = startingSeq;
|
|
11900
11947
|
const finalized = [];
|
|
11901
11948
|
let lastSeq = 0;
|
|
@@ -11931,6 +11978,7 @@ async function appendEventBatchInsideLock(eventsPath, queue) {
|
|
|
11931
11978
|
`, fullEvent });
|
|
11932
11979
|
lastSeq = seq;
|
|
11933
11980
|
}
|
|
11981
|
+
advanceSequenceCounter(eventsPath, lastSeq);
|
|
11934
11982
|
try {
|
|
11935
11983
|
if (fs8.existsSync(eventsPath) && fs8.statSync(eventsPath).size > MAX_EVENTS_BYTES) {
|
|
11936
11984
|
logInternalError(
|
|
@@ -11972,8 +12020,11 @@ async function appendEventBatchInsideLock(eventsPath, queue) {
|
|
|
11972
12020
|
function appendEventInsideLock(eventsPath, event) {
|
|
11973
12021
|
fs8.mkdirSync(path6.dirname(eventsPath), { recursive: true });
|
|
11974
12022
|
const baseMetadata = event.metadata;
|
|
12023
|
+
const explicitSeq = baseMetadata?.seq;
|
|
12024
|
+
const seq = explicitSeq ?? reserveSequence(eventsPath);
|
|
12025
|
+
if (explicitSeq !== void 0) advanceSequenceCounter(eventsPath, seq);
|
|
11975
12026
|
let metadata = {
|
|
11976
|
-
seq
|
|
12027
|
+
seq,
|
|
11977
12028
|
provenance: baseMetadata?.provenance ?? "team_runner",
|
|
11978
12029
|
...baseMetadata?.parentEventId ? { parentEventId: baseMetadata.parentEventId } : {},
|
|
11979
12030
|
...baseMetadata?.attemptId ? { attemptId: baseMetadata.attemptId } : {},
|
|
@@ -12028,7 +12079,6 @@ function appendEventInsideLock(eventsPath, event) {
|
|
|
12028
12079
|
} catch (error) {
|
|
12029
12080
|
logInternalError("event-log.size-check", error, `eventsPath=${eventsPath}`);
|
|
12030
12081
|
}
|
|
12031
|
-
const seq = fullEvent.metadata?.seq ?? 0;
|
|
12032
12082
|
if (!skippedDueToSize) {
|
|
12033
12083
|
fs8.appendFileSync(eventsPath, `${JSON.stringify(redactSecrets(fullEvent))}
|
|
12034
12084
|
`, "utf-8");
|
|
@@ -12080,9 +12130,9 @@ function appendEventBuffered(eventsPath, event, bufferMs = DEFAULT_BUFFER_MS) {
|
|
|
12080
12130
|
}
|
|
12081
12131
|
return Promise.resolve(appendEvent(eventsPath, event));
|
|
12082
12132
|
}
|
|
12083
|
-
return new Promise((
|
|
12133
|
+
return new Promise((resolve22, reject) => {
|
|
12084
12134
|
const queue = bufferedQueues.get(eventsPath) ?? [];
|
|
12085
|
-
queue.push({ event, resolve:
|
|
12135
|
+
queue.push({ event, resolve: resolve22, reject });
|
|
12086
12136
|
bufferedQueues.set(eventsPath, queue);
|
|
12087
12137
|
if (!bufferedTimers.has(eventsPath)) {
|
|
12088
12138
|
const timer = setTimeout(() => {
|
|
@@ -12195,7 +12245,7 @@ function dedupeTerminalEvents(events) {
|
|
|
12195
12245
|
}
|
|
12196
12246
|
return output;
|
|
12197
12247
|
}
|
|
12198
|
-
var TERMINAL_EVENT_TYPES, MAX_EVENTS_BYTES, sequenceCache, MAX_SEQUENCE_CACHE_ENTRIES, appendCounter, overflowCounter, MAX_SEQUENCE_CACHE_ENTRIES_VALUE, asyncQueues, asyncLocks, bufferedQueues, bufferedTimers, DEFAULT_BUFFER_MS;
|
|
12248
|
+
var TERMINAL_EVENT_TYPES, MAX_EVENTS_BYTES, sequenceCache, MAX_SEQUENCE_CACHE_ENTRIES, appendCounter, overflowCounter, MAX_SEQUENCE_CACHE_ENTRIES_VALUE, seqCounters, asyncQueues, asyncLocks, bufferedQueues, bufferedTimers, DEFAULT_BUFFER_MS;
|
|
12199
12249
|
var init_event_log = __esm({
|
|
12200
12250
|
"src/state/event-log.ts"() {
|
|
12201
12251
|
"use strict";
|
|
@@ -12216,6 +12266,7 @@ var init_event_log = __esm({
|
|
|
12216
12266
|
appendCounter = 0;
|
|
12217
12267
|
overflowCounter = 0;
|
|
12218
12268
|
MAX_SEQUENCE_CACHE_ENTRIES_VALUE = MAX_SEQUENCE_CACHE_ENTRIES;
|
|
12269
|
+
seqCounters = /* @__PURE__ */ new Map();
|
|
12219
12270
|
asyncQueues = /* @__PURE__ */ new Map();
|
|
12220
12271
|
asyncLocks = /* @__PURE__ */ new Map();
|
|
12221
12272
|
bufferedQueues = /* @__PURE__ */ new Map();
|
|
@@ -12428,8 +12479,8 @@ function resolveContainedPath(baseDir, targetPath2) {
|
|
|
12428
12479
|
const resolved = path7.isAbsolute(targetPath2) ? path7.resolve(targetPath2) : path7.resolve(base, targetPath2);
|
|
12429
12480
|
const baseNorm = resolveCanonicalPath(base);
|
|
12430
12481
|
const resolvedNorm = resolveCanonicalPath(resolved);
|
|
12431
|
-
const
|
|
12432
|
-
if (
|
|
12482
|
+
const relative9 = process.platform === "win32" ? path7.relative(baseNorm.toLowerCase(), resolvedNorm.toLowerCase()) : path7.relative(baseNorm, resolvedNorm);
|
|
12483
|
+
if (relative9.startsWith("..") || path7.isAbsolute(relative9)) throw new Error(`Path is outside ${baseDir}: ${targetPath2}`);
|
|
12433
12484
|
return resolved;
|
|
12434
12485
|
}
|
|
12435
12486
|
function resolveCanonicalPath(p) {
|
|
@@ -12611,8 +12662,8 @@ function resolveRealContainedPath(baseDir, targetPath2) {
|
|
|
12611
12662
|
throw new Error(`Path is outside ${baseDir}: ${targetPath2}`);
|
|
12612
12663
|
}
|
|
12613
12664
|
} else {
|
|
12614
|
-
const
|
|
12615
|
-
if (
|
|
12665
|
+
const relative9 = path7.relative(realBase, realTarget);
|
|
12666
|
+
if (relative9.startsWith("..") || path7.isAbsolute(relative9)) throw new Error(`Path is outside ${baseDir}: ${targetPath2}`);
|
|
12616
12667
|
}
|
|
12617
12668
|
return realTarget;
|
|
12618
12669
|
}
|
|
@@ -14562,7 +14613,7 @@ async function respondAsBackground(targetAgentId, fromId, message, opts) {
|
|
|
14562
14613
|
return awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, opts?.signal);
|
|
14563
14614
|
}
|
|
14564
14615
|
function awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, signal) {
|
|
14565
|
-
return new Promise((
|
|
14616
|
+
return new Promise((resolve22) => {
|
|
14566
14617
|
const deadline = Date.now() + timeoutMs;
|
|
14567
14618
|
let settled = false;
|
|
14568
14619
|
let timer;
|
|
@@ -14576,7 +14627,7 @@ function awaitPendingReply(corrId, targetAgentId, fromId, timeoutMs, signal) {
|
|
|
14576
14627
|
const set2 = pendingRepliesByTarget.get(targetAgentId);
|
|
14577
14628
|
set2?.delete(corrId);
|
|
14578
14629
|
if (set2 && set2.size === 0) pendingRepliesByTarget.delete(targetAgentId);
|
|
14579
|
-
|
|
14630
|
+
resolve22(result4);
|
|
14580
14631
|
};
|
|
14581
14632
|
timer = setTimeout(() => finish({ ok: false, corrId, timedOut: true }), timeoutMs);
|
|
14582
14633
|
if (signal) {
|
|
@@ -14748,7 +14799,9 @@ function checkResultFile(manifest, tasks) {
|
|
|
14748
14799
|
(t2) => t2.status === "completed" || t2.status === "failed" || t2.status === "cancelled" || t2.status === "skipped" || t2.status === "needs_attention"
|
|
14749
14800
|
);
|
|
14750
14801
|
if (allTerminal) {
|
|
14751
|
-
|
|
14802
|
+
const hasFailed = tasks.some((t2) => t2.status === "failed");
|
|
14803
|
+
const onlyCancelledOrSkipped = tasks.every((t2) => t2.status === "cancelled" || t2.status === "skipped");
|
|
14804
|
+
manifest.status = hasFailed ? "failed" : onlyCancelledOrSkipped ? "cancelled" : "completed";
|
|
14752
14805
|
saveRunManifest(manifest);
|
|
14753
14806
|
for (const task of tasks) {
|
|
14754
14807
|
try {
|
|
@@ -14994,14 +15047,14 @@ function reconcileOrphanedTempWorkspaces(now = Date.now(), options) {
|
|
|
14994
15047
|
const tasks = JSON.parse(fs16.readFileSync(tasksPath, "utf-8"));
|
|
14995
15048
|
const result4 = reconcileStaleRun(manifest, tasks, now);
|
|
14996
15049
|
if (result4.repaired && result4.repairedTasks) {
|
|
14997
|
-
|
|
15050
|
+
atomicWriteJson(tasksPath, result4.repairedTasks);
|
|
14998
15051
|
const updated = {
|
|
14999
15052
|
...manifest,
|
|
15000
15053
|
status: "cancelled",
|
|
15001
15054
|
updatedAt: new Date(now).toISOString(),
|
|
15002
15055
|
summary: `Stale run reconciled: ${result4.detail}`
|
|
15003
15056
|
};
|
|
15004
|
-
|
|
15057
|
+
atomicWriteJson(manifestPath, updated);
|
|
15005
15058
|
for (const task of result4.repairedTasks) {
|
|
15006
15059
|
try {
|
|
15007
15060
|
upsertCrewAgent(updated, recordFromTask(updated, task, "scaffold"));
|
|
@@ -15152,6 +15205,7 @@ var init_stale_reconciler = __esm({
|
|
|
15152
15205
|
"src/runtime/stale-reconciler.ts"() {
|
|
15153
15206
|
"use strict";
|
|
15154
15207
|
init_errors3();
|
|
15208
|
+
init_atomic_write();
|
|
15155
15209
|
init_state_store();
|
|
15156
15210
|
init_crew_agent_records();
|
|
15157
15211
|
init_process_status();
|
|
@@ -17307,7 +17361,7 @@ var init_subagent_manager = __esm({
|
|
|
17307
17361
|
await record.promise.catch((error) => {
|
|
17308
17362
|
logInternalError("subagent-manager.waitForRecord", error, `id=${id}`);
|
|
17309
17363
|
});
|
|
17310
|
-
else await new Promise((
|
|
17364
|
+
else await new Promise((resolve22) => setTimeout(resolve22, 100));
|
|
17311
17365
|
}
|
|
17312
17366
|
}
|
|
17313
17367
|
setMaxConcurrent(value) {
|
|
@@ -17405,7 +17459,7 @@ var init_subagent_manager = __esm({
|
|
|
17405
17459
|
while (record.runId && (record.status === "running" || record.status === "blocked")) {
|
|
17406
17460
|
const loaded = loadRunManifestById(cwd, record.runId);
|
|
17407
17461
|
if (!loaded) {
|
|
17408
|
-
await new Promise((
|
|
17462
|
+
await new Promise((resolve22) => setTimeout(resolve22, this.pollIntervalMs));
|
|
17409
17463
|
continue;
|
|
17410
17464
|
}
|
|
17411
17465
|
if (loaded.manifest.status === "completed") {
|
|
@@ -17438,7 +17492,7 @@ var init_subagent_manager = __esm({
|
|
|
17438
17492
|
savePersistedSubagentRecord(cwd, record);
|
|
17439
17493
|
return;
|
|
17440
17494
|
}
|
|
17441
|
-
await new Promise((
|
|
17495
|
+
await new Promise((resolve22) => setTimeout(resolve22, this.pollIntervalMs));
|
|
17442
17496
|
}
|
|
17443
17497
|
}
|
|
17444
17498
|
scheduleBlockedTerminalPoll(cwd, record) {
|
|
@@ -17786,8 +17840,8 @@ var init_deduplicate_stage = __esm({
|
|
|
17786
17840
|
const cur = lines[i2];
|
|
17787
17841
|
if (cur !== out[out.length - 1]) out.push(cur);
|
|
17788
17842
|
}
|
|
17789
|
-
const
|
|
17790
|
-
return out.join(
|
|
17843
|
+
const sep10 = text.includes("\r\n") ? "\r\n" : "\n";
|
|
17844
|
+
return out.join(sep10);
|
|
17791
17845
|
}
|
|
17792
17846
|
};
|
|
17793
17847
|
DEDUPLICATE_STAGE = new DeduplicateStage();
|
|
@@ -18257,13 +18311,20 @@ function attachPostExitStdioGuard(child, options) {
|
|
|
18257
18311
|
stderrEnded = true;
|
|
18258
18312
|
if (stdoutEnded && stderrEnded) clearTimers();
|
|
18259
18313
|
});
|
|
18260
|
-
|
|
18261
|
-
exited = true;
|
|
18262
|
-
armIdleTimer();
|
|
18314
|
+
const armHardTimer = () => {
|
|
18263
18315
|
if (hardTimer) return;
|
|
18264
18316
|
hardTimer = setTimeout(destroyUnendedStdio, hardMs);
|
|
18265
18317
|
hardTimer.unref();
|
|
18266
|
-
}
|
|
18318
|
+
};
|
|
18319
|
+
const onExit = () => {
|
|
18320
|
+
exited = true;
|
|
18321
|
+
armIdleTimer();
|
|
18322
|
+
armHardTimer();
|
|
18323
|
+
};
|
|
18324
|
+
if (child.exitCode != null || child.signalCode != null) {
|
|
18325
|
+
onExit();
|
|
18326
|
+
}
|
|
18327
|
+
child.on("exit", onExit);
|
|
18267
18328
|
child.on("close", clearTimers);
|
|
18268
18329
|
child.on("error", clearTimers);
|
|
18269
18330
|
return clearTimers;
|
|
@@ -18295,14 +18356,20 @@ function clearHardKillTimer(pid) {
|
|
|
18295
18356
|
clearTimeout(timer);
|
|
18296
18357
|
childHardKillTimers.delete(pid);
|
|
18297
18358
|
}
|
|
18359
|
+
function spawnTaskkillSafe(pid) {
|
|
18360
|
+
const taskkillChild = spawn("taskkill", ["/pid", String(pid), "/t", "/f"], {
|
|
18361
|
+
stdio: "ignore",
|
|
18362
|
+
windowsHide: true
|
|
18363
|
+
});
|
|
18364
|
+
taskkillChild.on("error", (err2) => {
|
|
18365
|
+
logInternalError("child-pi.taskkill-spawn-error", err2 instanceof Error ? err2 : new Error(String(err2)), `pid=${pid}`);
|
|
18366
|
+
});
|
|
18367
|
+
}
|
|
18298
18368
|
function killProcessPid(pid) {
|
|
18299
18369
|
if (!Number.isInteger(pid) || pid <= 0) return;
|
|
18300
18370
|
try {
|
|
18301
18371
|
if (process.platform === "win32") {
|
|
18302
|
-
|
|
18303
|
-
stdio: "ignore",
|
|
18304
|
-
windowsHide: true
|
|
18305
|
-
});
|
|
18372
|
+
spawnTaskkillSafe(pid);
|
|
18306
18373
|
const verifyTimer = setTimeout(() => {
|
|
18307
18374
|
try {
|
|
18308
18375
|
process.kill(pid, 0);
|
|
@@ -18312,10 +18379,7 @@ function killProcessPid(pid) {
|
|
|
18312
18379
|
`pid=${pid}`
|
|
18313
18380
|
);
|
|
18314
18381
|
try {
|
|
18315
|
-
|
|
18316
|
-
stdio: "ignore",
|
|
18317
|
-
windowsHide: true
|
|
18318
|
-
});
|
|
18382
|
+
spawnTaskkillSafe(pid);
|
|
18319
18383
|
} catch {
|
|
18320
18384
|
}
|
|
18321
18385
|
} catch {
|
|
@@ -18716,9 +18780,18 @@ ${JSON.stringify({ type: "message_end", usage: { input: 10, output: 5, cost: 1e-
|
|
|
18716
18780
|
role: input.role
|
|
18717
18781
|
});
|
|
18718
18782
|
if (input.steeringFile) built.env.PI_CREW_STEERING_FILE = input.steeringFile;
|
|
18783
|
+
if (input.signal?.aborted) {
|
|
18784
|
+
return {
|
|
18785
|
+
exitCode: null,
|
|
18786
|
+
stdout: "",
|
|
18787
|
+
stderr: "",
|
|
18788
|
+
error: "Aborted before spawn (parent AbortSignal already aborted)",
|
|
18789
|
+
aborted: true
|
|
18790
|
+
};
|
|
18791
|
+
}
|
|
18719
18792
|
const spawnSpec = getPiSpawnCommand(built.args);
|
|
18720
18793
|
try {
|
|
18721
|
-
return await new Promise((
|
|
18794
|
+
return await new Promise((resolve22) => {
|
|
18722
18795
|
for (const key of Object.keys(built.env)) {
|
|
18723
18796
|
if (!key.startsWith("PI_CREW_") && !key.startsWith("PI_TEAMS_")) {
|
|
18724
18797
|
throw new Error(
|
|
@@ -18889,29 +18962,23 @@ ${JSON.stringify({ type: "message_end", usage: { input: 10, output: 5, cost: 1e-
|
|
|
18889
18962
|
turnCount += 1;
|
|
18890
18963
|
if (maxTurns !== void 0 && !softLimitReached && turnCount >= maxTurns) {
|
|
18891
18964
|
softLimitReached = true;
|
|
18892
|
-
if (
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
|
|
18897
|
-
|
|
18898
|
-
|
|
18965
|
+
if (input.steeringFile) {
|
|
18966
|
+
try {
|
|
18967
|
+
fs27.appendFileSync(
|
|
18968
|
+
input.steeringFile,
|
|
18969
|
+
JSON.stringify({
|
|
18970
|
+
type: "steer",
|
|
18971
|
+
message: "You have reached your turn limit. Wrap up immediately \u2014 provide your final answer now."
|
|
18972
|
+
}) + "\n",
|
|
18973
|
+
"utf-8"
|
|
18974
|
+
);
|
|
18975
|
+
} catch (err2) {
|
|
18899
18976
|
logInternalError(
|
|
18900
|
-
"child-pi.steer-
|
|
18901
|
-
new Error(
|
|
18902
|
-
"stdin write returned false (normal backpressure); steer buffered, worker NOT killed"
|
|
18903
|
-
),
|
|
18977
|
+
"child-pi.steer-write-failed",
|
|
18978
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
18904
18979
|
`pid=${child.pid}`
|
|
18905
18980
|
);
|
|
18906
18981
|
}
|
|
18907
|
-
} else {
|
|
18908
|
-
logInternalError(
|
|
18909
|
-
"child-pi.steer-not-writable",
|
|
18910
|
-
new Error(
|
|
18911
|
-
"stdin not writable when attempting steer injection (worker may be done); worker NOT killed"
|
|
18912
|
-
),
|
|
18913
|
-
`pid=${child.pid}`
|
|
18914
|
-
);
|
|
18915
18982
|
}
|
|
18916
18983
|
} else if (maxTurns !== void 0 && softLimitReached && turnCount >= maxTurns + (graceTurns ?? 5)) {
|
|
18917
18984
|
try {
|
|
@@ -19042,7 +19109,7 @@ ${JSON.stringify({ type: "message_end", usage: { input: 10, output: 5, cost: 1e-
|
|
|
19042
19109
|
cleanupErrors.push(error instanceof Error ? error.message : String(error));
|
|
19043
19110
|
}
|
|
19044
19111
|
try {
|
|
19045
|
-
|
|
19112
|
+
resolve22({
|
|
19046
19113
|
...result4,
|
|
19047
19114
|
rawFinalText: lineObserver.getRawFinalText(),
|
|
19048
19115
|
intermediateFindings: lineObserver.getIntermediateFindings(),
|
|
@@ -19556,6 +19623,12 @@ function setExtensionWidget(ctx, key, content, options) {
|
|
|
19556
19623
|
const { persist: _persist, ...widgetOptions } = options ?? {};
|
|
19557
19624
|
ctx.ui.setWidget(key, content, widgetOptions);
|
|
19558
19625
|
}
|
|
19626
|
+
function setFooter(ctx, factory) {
|
|
19627
|
+
if (!ctx) return;
|
|
19628
|
+
const record = maybeRecord(ctx.ui);
|
|
19629
|
+
const fn = record?.setFooter;
|
|
19630
|
+
if (typeof fn === "function") fn.call(ctx.ui, factory);
|
|
19631
|
+
}
|
|
19559
19632
|
function showCustom(ctx, factory, options) {
|
|
19560
19633
|
const custom = ctx.ui.custom;
|
|
19561
19634
|
return custom(factory, options);
|
|
@@ -19695,7 +19768,7 @@ var init_cancellation_token = __esm({
|
|
|
19695
19768
|
wait(ms) {
|
|
19696
19769
|
this.throwIfCancelled();
|
|
19697
19770
|
if (ms <= 0) return Promise.resolve();
|
|
19698
|
-
return new Promise((
|
|
19771
|
+
return new Promise((resolve22, reject) => {
|
|
19699
19772
|
let timeout;
|
|
19700
19773
|
const cleanup = () => {
|
|
19701
19774
|
if (timeout) clearTimeout(timeout);
|
|
@@ -19707,7 +19780,7 @@ var init_cancellation_token = __esm({
|
|
|
19707
19780
|
};
|
|
19708
19781
|
timeout = setTimeout(() => {
|
|
19709
19782
|
cleanup();
|
|
19710
|
-
|
|
19783
|
+
resolve22();
|
|
19711
19784
|
}, ms);
|
|
19712
19785
|
this.signal.addEventListener("abort", onAbort, { once: true });
|
|
19713
19786
|
});
|
|
@@ -23641,8 +23714,8 @@ function taskMailboxDir(manifest, taskId, create = false) {
|
|
|
23641
23714
|
const tasksRoot = safeMailboxTasksRoot(manifest, create);
|
|
23642
23715
|
const normalizedTaskId = safeTaskId(taskId);
|
|
23643
23716
|
const resolved = path32.resolve(tasksRoot, normalizedTaskId);
|
|
23644
|
-
const
|
|
23645
|
-
if (
|
|
23717
|
+
const relative9 = path32.relative(tasksRoot, resolved);
|
|
23718
|
+
if (relative9.startsWith("..") || path32.isAbsolute(relative9)) throw new Error(`Invalid mailbox task id: ${taskId}`);
|
|
23646
23719
|
if (create) fs37.mkdirSync(resolved, { recursive: true });
|
|
23647
23720
|
if (fs37.existsSync(resolved) && fs37.lstatSync(resolved).isSymbolicLink()) throw new Error(`Invalid mailbox task directory: ${resolved}`);
|
|
23648
23721
|
return resolved;
|
|
@@ -23876,8 +23949,8 @@ function appendMailboxMessage(manifest, message) {
|
|
|
23876
23949
|
`,
|
|
23877
23950
|
"utf-8"
|
|
23878
23951
|
);
|
|
23952
|
+
rotateMailboxFileIfNeeded(mailboxFile(manifest, complete.direction, complete.taskId));
|
|
23879
23953
|
});
|
|
23880
|
-
rotateMailboxFileIfNeeded(mailboxFile(manifest, complete.direction, complete.taskId));
|
|
23881
23954
|
withFileLockSync(deliveryFile(manifest, true), () => {
|
|
23882
23955
|
const delivery = readDeliveryState(manifest);
|
|
23883
23956
|
delivery.messages[complete.id] = complete.status;
|
|
@@ -26087,9 +26160,9 @@ async function isLiveSessionRuntimeAvailable(timeoutMs = 1500, env = process.env
|
|
|
26087
26160
|
try {
|
|
26088
26161
|
return await Promise.race([
|
|
26089
26162
|
probe(),
|
|
26090
|
-
new Promise((
|
|
26163
|
+
new Promise((resolve22) => {
|
|
26091
26164
|
timer = setTimeout(
|
|
26092
|
-
() =>
|
|
26165
|
+
() => resolve22({
|
|
26093
26166
|
available: false,
|
|
26094
26167
|
reason: `Timed out probing optional Pi SDK live-session runtime after ${timeoutMs}ms.`
|
|
26095
26168
|
}),
|
|
@@ -28632,9 +28705,9 @@ var require_stringifyNumber = __commonJS({
|
|
|
28632
28705
|
function stringifyNumber({ format: format2, minFractionDigits, tag, value }) {
|
|
28633
28706
|
if (typeof value === "bigint")
|
|
28634
28707
|
return String(value);
|
|
28635
|
-
const
|
|
28636
|
-
if (!isFinite(
|
|
28637
|
-
return isNaN(
|
|
28708
|
+
const num2 = typeof value === "number" ? value : Number(value);
|
|
28709
|
+
if (!isFinite(num2))
|
|
28710
|
+
return isNaN(num2) ? ".nan" : num2 < 0 ? "-.inf" : ".inf";
|
|
28638
28711
|
let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
|
|
28639
28712
|
if (!format2 && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
|
|
28640
28713
|
let i2 = n.indexOf(".");
|
|
@@ -28674,8 +28747,8 @@ var require_float = __commonJS({
|
|
|
28674
28747
|
test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
|
|
28675
28748
|
resolve: (str) => parseFloat(str),
|
|
28676
28749
|
stringify(node) {
|
|
28677
|
-
const
|
|
28678
|
-
return isFinite(
|
|
28750
|
+
const num2 = Number(node.value);
|
|
28751
|
+
return isFinite(num2) ? num2.toExponential() : stringifyNumber.stringifyNumber(node);
|
|
28679
28752
|
}
|
|
28680
28753
|
};
|
|
28681
28754
|
var float = {
|
|
@@ -29114,8 +29187,8 @@ var require_float2 = __commonJS({
|
|
|
29114
29187
|
test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
|
|
29115
29188
|
resolve: (str) => parseFloat(str.replace(/_/g, "")),
|
|
29116
29189
|
stringify(node) {
|
|
29117
|
-
const
|
|
29118
|
-
return isFinite(
|
|
29190
|
+
const num2 = Number(node.value);
|
|
29191
|
+
return isFinite(num2) ? num2.toExponential() : stringifyNumber.stringifyNumber(node);
|
|
29119
29192
|
}
|
|
29120
29193
|
};
|
|
29121
29194
|
var float = {
|
|
@@ -29317,23 +29390,23 @@ var require_timestamp = __commonJS({
|
|
|
29317
29390
|
function parseSexagesimal(str, asBigInt) {
|
|
29318
29391
|
const sign = str[0];
|
|
29319
29392
|
const parts = sign === "-" || sign === "+" ? str.substring(1) : str;
|
|
29320
|
-
const
|
|
29321
|
-
const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 *
|
|
29322
|
-
return sign === "-" ?
|
|
29393
|
+
const num2 = (n) => asBigInt ? BigInt(n) : Number(n);
|
|
29394
|
+
const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num2(60) + num2(p), num2(0));
|
|
29395
|
+
return sign === "-" ? num2(-1) * res : res;
|
|
29323
29396
|
}
|
|
29324
29397
|
function stringifySexagesimal(node) {
|
|
29325
29398
|
let { value } = node;
|
|
29326
|
-
let
|
|
29399
|
+
let num2 = (n) => n;
|
|
29327
29400
|
if (typeof value === "bigint")
|
|
29328
|
-
|
|
29401
|
+
num2 = (n) => BigInt(n);
|
|
29329
29402
|
else if (isNaN(value) || !isFinite(value))
|
|
29330
29403
|
return stringifyNumber.stringifyNumber(node);
|
|
29331
29404
|
let sign = "";
|
|
29332
29405
|
if (value < 0) {
|
|
29333
29406
|
sign = "-";
|
|
29334
|
-
value *=
|
|
29407
|
+
value *= num2(-1);
|
|
29335
29408
|
}
|
|
29336
|
-
const _60 =
|
|
29409
|
+
const _60 = num2(60);
|
|
29337
29410
|
const parts = [value % _60];
|
|
29338
29411
|
if (value < 60) {
|
|
29339
29412
|
parts.unshift(0);
|
|
@@ -30250,10 +30323,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
30250
30323
|
let offset2 = bm.offset;
|
|
30251
30324
|
let commentEnd = null;
|
|
30252
30325
|
for (const collItem of bm.items) {
|
|
30253
|
-
const { start, key, sep:
|
|
30326
|
+
const { start, key, sep: sep10, value } = collItem;
|
|
30254
30327
|
const keyProps = resolveProps.resolveProps(start, {
|
|
30255
30328
|
indicator: "explicit-key-ind",
|
|
30256
|
-
next: key ??
|
|
30329
|
+
next: key ?? sep10?.[0],
|
|
30257
30330
|
offset: offset2,
|
|
30258
30331
|
onError,
|
|
30259
30332
|
parentIndent: bm.indent,
|
|
@@ -30267,7 +30340,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
30267
30340
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
30268
30341
|
onError(offset2, "BAD_INDENT", startColMsg);
|
|
30269
30342
|
}
|
|
30270
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
30343
|
+
if (!keyProps.anchor && !keyProps.tag && !sep10) {
|
|
30271
30344
|
commentEnd = keyProps.end;
|
|
30272
30345
|
if (keyProps.comment) {
|
|
30273
30346
|
if (map3.comment)
|
|
@@ -30291,7 +30364,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
30291
30364
|
ctx.atKey = false;
|
|
30292
30365
|
if (utilMapIncludes.mapIncludes(ctx, map3.items, keyNode))
|
|
30293
30366
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
30294
|
-
const valueProps = resolveProps.resolveProps(
|
|
30367
|
+
const valueProps = resolveProps.resolveProps(sep10 ?? [], {
|
|
30295
30368
|
indicator: "map-value-ind",
|
|
30296
30369
|
next: value,
|
|
30297
30370
|
offset: keyNode.range[2],
|
|
@@ -30307,7 +30380,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
30307
30380
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
30308
30381
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
30309
30382
|
}
|
|
30310
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset2,
|
|
30383
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset2, sep10, null, valueProps, onError);
|
|
30311
30384
|
if (ctx.schema.compat)
|
|
30312
30385
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
30313
30386
|
offset2 = valueNode.range[2];
|
|
@@ -30398,7 +30471,7 @@ var require_resolve_end = __commonJS({
|
|
|
30398
30471
|
let comment = "";
|
|
30399
30472
|
if (end) {
|
|
30400
30473
|
let hasSpace = false;
|
|
30401
|
-
let
|
|
30474
|
+
let sep10 = "";
|
|
30402
30475
|
for (const token of end) {
|
|
30403
30476
|
const { source, type } = token;
|
|
30404
30477
|
switch (type) {
|
|
@@ -30412,13 +30485,13 @@ var require_resolve_end = __commonJS({
|
|
|
30412
30485
|
if (!comment)
|
|
30413
30486
|
comment = cb;
|
|
30414
30487
|
else
|
|
30415
|
-
comment +=
|
|
30416
|
-
|
|
30488
|
+
comment += sep10 + cb;
|
|
30489
|
+
sep10 = "";
|
|
30417
30490
|
break;
|
|
30418
30491
|
}
|
|
30419
30492
|
case "newline":
|
|
30420
30493
|
if (comment)
|
|
30421
|
-
|
|
30494
|
+
sep10 += source;
|
|
30422
30495
|
hasSpace = true;
|
|
30423
30496
|
break;
|
|
30424
30497
|
default:
|
|
@@ -30461,18 +30534,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
30461
30534
|
let offset2 = fc.offset + fc.start.source.length;
|
|
30462
30535
|
for (let i2 = 0; i2 < fc.items.length; ++i2) {
|
|
30463
30536
|
const collItem = fc.items[i2];
|
|
30464
|
-
const { start, key, sep:
|
|
30537
|
+
const { start, key, sep: sep10, value } = collItem;
|
|
30465
30538
|
const props = resolveProps.resolveProps(start, {
|
|
30466
30539
|
flow: fcName,
|
|
30467
30540
|
indicator: "explicit-key-ind",
|
|
30468
|
-
next: key ??
|
|
30541
|
+
next: key ?? sep10?.[0],
|
|
30469
30542
|
offset: offset2,
|
|
30470
30543
|
onError,
|
|
30471
30544
|
parentIndent: fc.indent,
|
|
30472
30545
|
startOnNewline: false
|
|
30473
30546
|
});
|
|
30474
30547
|
if (!props.found) {
|
|
30475
|
-
if (!props.anchor && !props.tag && !
|
|
30548
|
+
if (!props.anchor && !props.tag && !sep10 && !value) {
|
|
30476
30549
|
if (i2 === 0 && props.comma)
|
|
30477
30550
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
30478
30551
|
else if (i2 < fc.items.length - 1)
|
|
@@ -30526,8 +30599,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
30526
30599
|
}
|
|
30527
30600
|
}
|
|
30528
30601
|
}
|
|
30529
|
-
if (!isMap && !
|
|
30530
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
30602
|
+
if (!isMap && !sep10 && !props.found) {
|
|
30603
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep10, null, props, onError);
|
|
30531
30604
|
coll.items.push(valueNode);
|
|
30532
30605
|
offset2 = valueNode.range[2];
|
|
30533
30606
|
if (isBlock(value))
|
|
@@ -30539,7 +30612,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
30539
30612
|
if (isBlock(key))
|
|
30540
30613
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
30541
30614
|
ctx.atKey = false;
|
|
30542
|
-
const valueProps = resolveProps.resolveProps(
|
|
30615
|
+
const valueProps = resolveProps.resolveProps(sep10 ?? [], {
|
|
30543
30616
|
flow: fcName,
|
|
30544
30617
|
indicator: "map-value-ind",
|
|
30545
30618
|
next: value,
|
|
@@ -30550,8 +30623,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
30550
30623
|
});
|
|
30551
30624
|
if (valueProps.found) {
|
|
30552
30625
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
30553
|
-
if (
|
|
30554
|
-
for (const st of
|
|
30626
|
+
if (sep10)
|
|
30627
|
+
for (const st of sep10) {
|
|
30555
30628
|
if (st === valueProps.found)
|
|
30556
30629
|
break;
|
|
30557
30630
|
if (st.type === "newline") {
|
|
@@ -30568,7 +30641,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
30568
30641
|
else
|
|
30569
30642
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
30570
30643
|
}
|
|
30571
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
30644
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep10, null, valueProps, onError) : null;
|
|
30572
30645
|
if (valueNode) {
|
|
30573
30646
|
if (isBlock(value))
|
|
30574
30647
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -30748,7 +30821,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
30748
30821
|
chompStart = i2 + 1;
|
|
30749
30822
|
}
|
|
30750
30823
|
let value = "";
|
|
30751
|
-
let
|
|
30824
|
+
let sep10 = "";
|
|
30752
30825
|
let prevMoreIndented = false;
|
|
30753
30826
|
for (let i2 = 0; i2 < contentStart; ++i2)
|
|
30754
30827
|
value += lines[i2][0].slice(trimIndent) + "\n";
|
|
@@ -30765,24 +30838,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
30765
30838
|
indent = "";
|
|
30766
30839
|
}
|
|
30767
30840
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
30768
|
-
value +=
|
|
30769
|
-
|
|
30841
|
+
value += sep10 + indent.slice(trimIndent) + content;
|
|
30842
|
+
sep10 = "\n";
|
|
30770
30843
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
30771
|
-
if (
|
|
30772
|
-
|
|
30773
|
-
else if (!prevMoreIndented &&
|
|
30774
|
-
|
|
30775
|
-
value +=
|
|
30776
|
-
|
|
30844
|
+
if (sep10 === " ")
|
|
30845
|
+
sep10 = "\n";
|
|
30846
|
+
else if (!prevMoreIndented && sep10 === "\n")
|
|
30847
|
+
sep10 = "\n\n";
|
|
30848
|
+
value += sep10 + indent.slice(trimIndent) + content;
|
|
30849
|
+
sep10 = "\n";
|
|
30777
30850
|
prevMoreIndented = true;
|
|
30778
30851
|
} else if (content === "") {
|
|
30779
|
-
if (
|
|
30852
|
+
if (sep10 === "\n")
|
|
30780
30853
|
value += "\n";
|
|
30781
30854
|
else
|
|
30782
|
-
|
|
30855
|
+
sep10 = "\n";
|
|
30783
30856
|
} else {
|
|
30784
|
-
value +=
|
|
30785
|
-
|
|
30857
|
+
value += sep10 + content;
|
|
30858
|
+
sep10 = " ";
|
|
30786
30859
|
prevMoreIndented = false;
|
|
30787
30860
|
}
|
|
30788
30861
|
}
|
|
@@ -30964,25 +31037,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
30964
31037
|
if (!match)
|
|
30965
31038
|
return source;
|
|
30966
31039
|
let res = match[1];
|
|
30967
|
-
let
|
|
31040
|
+
let sep10 = " ";
|
|
30968
31041
|
let pos = first.lastIndex;
|
|
30969
31042
|
line4.lastIndex = pos;
|
|
30970
31043
|
while (match = line4.exec(source)) {
|
|
30971
31044
|
if (match[1] === "") {
|
|
30972
|
-
if (
|
|
30973
|
-
res +=
|
|
31045
|
+
if (sep10 === "\n")
|
|
31046
|
+
res += sep10;
|
|
30974
31047
|
else
|
|
30975
|
-
|
|
31048
|
+
sep10 = "\n";
|
|
30976
31049
|
} else {
|
|
30977
|
-
res +=
|
|
30978
|
-
|
|
31050
|
+
res += sep10 + match[1];
|
|
31051
|
+
sep10 = " ";
|
|
30979
31052
|
}
|
|
30980
31053
|
pos = line4.lastIndex;
|
|
30981
31054
|
}
|
|
30982
31055
|
const last = /[ \t]*(.*)/sy;
|
|
30983
31056
|
last.lastIndex = pos;
|
|
30984
31057
|
match = last.exec(source);
|
|
30985
|
-
return res +
|
|
31058
|
+
return res + sep10 + (match?.[1] ?? "");
|
|
30986
31059
|
}
|
|
30987
31060
|
function doubleQuotedValue(source, onError) {
|
|
30988
31061
|
let res = "";
|
|
@@ -31792,14 +31865,14 @@ var require_cst_stringify = __commonJS({
|
|
|
31792
31865
|
}
|
|
31793
31866
|
}
|
|
31794
31867
|
}
|
|
31795
|
-
function stringifyItem({ start, key, sep:
|
|
31868
|
+
function stringifyItem({ start, key, sep: sep10, value }) {
|
|
31796
31869
|
let res = "";
|
|
31797
31870
|
for (const st of start)
|
|
31798
31871
|
res += st.source;
|
|
31799
31872
|
if (key)
|
|
31800
31873
|
res += stringifyToken(key);
|
|
31801
|
-
if (
|
|
31802
|
-
for (const st of
|
|
31874
|
+
if (sep10)
|
|
31875
|
+
for (const st of sep10)
|
|
31803
31876
|
res += st.source;
|
|
31804
31877
|
if (value)
|
|
31805
31878
|
res += stringifyToken(value);
|
|
@@ -32966,18 +33039,18 @@ var require_parser = __commonJS({
|
|
|
32966
33039
|
if (this.type === "map-value-ind") {
|
|
32967
33040
|
const prev = getPrevProps(this.peek(2));
|
|
32968
33041
|
const start = getFirstKeyStartProps(prev);
|
|
32969
|
-
let
|
|
33042
|
+
let sep10;
|
|
32970
33043
|
if (scalar.end) {
|
|
32971
|
-
|
|
32972
|
-
|
|
33044
|
+
sep10 = scalar.end;
|
|
33045
|
+
sep10.push(this.sourceToken);
|
|
32973
33046
|
delete scalar.end;
|
|
32974
33047
|
} else
|
|
32975
|
-
|
|
33048
|
+
sep10 = [this.sourceToken];
|
|
32976
33049
|
const map3 = {
|
|
32977
33050
|
type: "block-map",
|
|
32978
33051
|
offset: scalar.offset,
|
|
32979
33052
|
indent: scalar.indent,
|
|
32980
|
-
items: [{ start, key: scalar, sep:
|
|
33053
|
+
items: [{ start, key: scalar, sep: sep10 }]
|
|
32981
33054
|
};
|
|
32982
33055
|
this.onKeyLine = true;
|
|
32983
33056
|
this.stack[this.stack.length - 1] = map3;
|
|
@@ -33130,15 +33203,15 @@ var require_parser = __commonJS({
|
|
|
33130
33203
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
33131
33204
|
const start2 = getFirstKeyStartProps(it.start);
|
|
33132
33205
|
const key = it.key;
|
|
33133
|
-
const
|
|
33134
|
-
|
|
33206
|
+
const sep10 = it.sep;
|
|
33207
|
+
sep10.push(this.sourceToken);
|
|
33135
33208
|
delete it.key;
|
|
33136
33209
|
delete it.sep;
|
|
33137
33210
|
this.stack.push({
|
|
33138
33211
|
type: "block-map",
|
|
33139
33212
|
offset: this.offset,
|
|
33140
33213
|
indent: this.indent,
|
|
33141
|
-
items: [{ start: start2, key, sep:
|
|
33214
|
+
items: [{ start: start2, key, sep: sep10 }]
|
|
33142
33215
|
});
|
|
33143
33216
|
} else if (start.length > 0) {
|
|
33144
33217
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -33332,13 +33405,13 @@ var require_parser = __commonJS({
|
|
|
33332
33405
|
const prev = getPrevProps(parent);
|
|
33333
33406
|
const start = getFirstKeyStartProps(prev);
|
|
33334
33407
|
fixFlowSeqItems(fc);
|
|
33335
|
-
const
|
|
33336
|
-
|
|
33408
|
+
const sep10 = fc.end.splice(1, fc.end.length);
|
|
33409
|
+
sep10.push(this.sourceToken);
|
|
33337
33410
|
const map3 = {
|
|
33338
33411
|
type: "block-map",
|
|
33339
33412
|
offset: fc.offset,
|
|
33340
33413
|
indent: fc.indent,
|
|
33341
|
-
items: [{ start, key: fc, sep:
|
|
33414
|
+
items: [{ start, key: fc, sep: sep10 }]
|
|
33342
33415
|
};
|
|
33343
33416
|
this.onKeyLine = true;
|
|
33344
33417
|
this.stack[this.stack.length - 1] = map3;
|
|
@@ -38245,7 +38318,7 @@ var require_compile = __commonJS({
|
|
|
38245
38318
|
const schOrFunc = root.refs[ref2];
|
|
38246
38319
|
if (schOrFunc)
|
|
38247
38320
|
return schOrFunc;
|
|
38248
|
-
let _sch =
|
|
38321
|
+
let _sch = resolve22.call(this, root, ref2);
|
|
38249
38322
|
if (_sch === void 0) {
|
|
38250
38323
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref2];
|
|
38251
38324
|
const { schemaId } = this.opts;
|
|
@@ -38272,7 +38345,7 @@ var require_compile = __commonJS({
|
|
|
38272
38345
|
function sameSchemaEnv(s1, s2) {
|
|
38273
38346
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
38274
38347
|
}
|
|
38275
|
-
function
|
|
38348
|
+
function resolve22(root, ref2) {
|
|
38276
38349
|
let sch;
|
|
38277
38350
|
while (typeof (sch = this.refs[ref2]) == "string")
|
|
38278
38351
|
ref2 = sch;
|
|
@@ -38903,55 +38976,55 @@ var require_fast_uri = __commonJS({
|
|
|
38903
38976
|
}
|
|
38904
38977
|
return uri;
|
|
38905
38978
|
}
|
|
38906
|
-
function
|
|
38979
|
+
function resolve22(baseURI, relativeURI, options) {
|
|
38907
38980
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
38908
38981
|
const resolved = resolveComponent(parse6(baseURI, schemelessOptions), parse6(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
38909
38982
|
schemelessOptions.skipEscape = true;
|
|
38910
38983
|
return serialize(resolved, schemelessOptions);
|
|
38911
38984
|
}
|
|
38912
|
-
function resolveComponent(base,
|
|
38985
|
+
function resolveComponent(base, relative9, options, skipNormalization) {
|
|
38913
38986
|
const target = {};
|
|
38914
38987
|
if (!skipNormalization) {
|
|
38915
38988
|
base = parse6(serialize(base, options), options);
|
|
38916
|
-
|
|
38989
|
+
relative9 = parse6(serialize(relative9, options), options);
|
|
38917
38990
|
}
|
|
38918
38991
|
options = options || {};
|
|
38919
|
-
if (!options.tolerant &&
|
|
38920
|
-
target.scheme =
|
|
38921
|
-
target.userinfo =
|
|
38922
|
-
target.host =
|
|
38923
|
-
target.port =
|
|
38924
|
-
target.path = removeDotSegments(
|
|
38925
|
-
target.query =
|
|
38992
|
+
if (!options.tolerant && relative9.scheme) {
|
|
38993
|
+
target.scheme = relative9.scheme;
|
|
38994
|
+
target.userinfo = relative9.userinfo;
|
|
38995
|
+
target.host = relative9.host;
|
|
38996
|
+
target.port = relative9.port;
|
|
38997
|
+
target.path = removeDotSegments(relative9.path || "");
|
|
38998
|
+
target.query = relative9.query;
|
|
38926
38999
|
} else {
|
|
38927
|
-
if (
|
|
38928
|
-
target.userinfo =
|
|
38929
|
-
target.host =
|
|
38930
|
-
target.port =
|
|
38931
|
-
target.path = removeDotSegments(
|
|
38932
|
-
target.query =
|
|
39000
|
+
if (relative9.userinfo !== void 0 || relative9.host !== void 0 || relative9.port !== void 0) {
|
|
39001
|
+
target.userinfo = relative9.userinfo;
|
|
39002
|
+
target.host = relative9.host;
|
|
39003
|
+
target.port = relative9.port;
|
|
39004
|
+
target.path = removeDotSegments(relative9.path || "");
|
|
39005
|
+
target.query = relative9.query;
|
|
38933
39006
|
} else {
|
|
38934
|
-
if (!
|
|
39007
|
+
if (!relative9.path) {
|
|
38935
39008
|
target.path = base.path;
|
|
38936
|
-
if (
|
|
38937
|
-
target.query =
|
|
39009
|
+
if (relative9.query !== void 0) {
|
|
39010
|
+
target.query = relative9.query;
|
|
38938
39011
|
} else {
|
|
38939
39012
|
target.query = base.query;
|
|
38940
39013
|
}
|
|
38941
39014
|
} else {
|
|
38942
|
-
if (
|
|
38943
|
-
target.path = removeDotSegments(
|
|
39015
|
+
if (relative9.path[0] === "/") {
|
|
39016
|
+
target.path = removeDotSegments(relative9.path);
|
|
38944
39017
|
} else {
|
|
38945
39018
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
38946
|
-
target.path = "/" +
|
|
39019
|
+
target.path = "/" + relative9.path;
|
|
38947
39020
|
} else if (!base.path) {
|
|
38948
|
-
target.path =
|
|
39021
|
+
target.path = relative9.path;
|
|
38949
39022
|
} else {
|
|
38950
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
39023
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative9.path;
|
|
38951
39024
|
}
|
|
38952
39025
|
target.path = removeDotSegments(target.path);
|
|
38953
39026
|
}
|
|
38954
|
-
target.query =
|
|
39027
|
+
target.query = relative9.query;
|
|
38955
39028
|
}
|
|
38956
39029
|
target.userinfo = base.userinfo;
|
|
38957
39030
|
target.host = base.host;
|
|
@@ -38959,7 +39032,7 @@ var require_fast_uri = __commonJS({
|
|
|
38959
39032
|
}
|
|
38960
39033
|
target.scheme = base.scheme;
|
|
38961
39034
|
}
|
|
38962
|
-
target.fragment =
|
|
39035
|
+
target.fragment = relative9.fragment;
|
|
38963
39036
|
return target;
|
|
38964
39037
|
}
|
|
38965
39038
|
function equal(uriA, uriB, options) {
|
|
@@ -39161,7 +39234,7 @@ var require_fast_uri = __commonJS({
|
|
|
39161
39234
|
var fastUri = {
|
|
39162
39235
|
SCHEMES,
|
|
39163
39236
|
normalize: normalize2,
|
|
39164
|
-
resolve:
|
|
39237
|
+
resolve: resolve22,
|
|
39165
39238
|
resolveComponent,
|
|
39166
39239
|
equal,
|
|
39167
39240
|
serialize,
|
|
@@ -42638,7 +42711,7 @@ ${input.prompt}` : input.prompt;
|
|
|
42638
42711
|
);
|
|
42639
42712
|
} catch {
|
|
42640
42713
|
}
|
|
42641
|
-
await new Promise((
|
|
42714
|
+
await new Promise((resolve22) => setTimeout(resolve22, DEFAULT_LIVE_SESSION.yieldPollIntervalMs));
|
|
42642
42715
|
if (customToolYieldResolved && customToolYieldResult) {
|
|
42643
42716
|
yieldResult = customToolYieldResult;
|
|
42644
42717
|
} else {
|
|
@@ -42682,7 +42755,7 @@ ${input.prompt}` : input.prompt;
|
|
|
42682
42755
|
}
|
|
42683
42756
|
}
|
|
42684
42757
|
const pollInterval = DEFAULT_LIVE_SESSION.yieldPollIntervalMs;
|
|
42685
|
-
await new Promise((
|
|
42758
|
+
await new Promise((resolve22) => setTimeout(resolve22, pollInterval));
|
|
42686
42759
|
if (customToolYieldResolved && customToolYieldResult) {
|
|
42687
42760
|
yieldResult = customToolYieldResult;
|
|
42688
42761
|
break;
|
|
@@ -44113,13 +44186,13 @@ var init_checkpoint = __esm({
|
|
|
44113
44186
|
import * as fs51 from "node:fs";
|
|
44114
44187
|
import * as path43 from "node:path";
|
|
44115
44188
|
function registerRunPromise(runId) {
|
|
44116
|
-
let
|
|
44189
|
+
let resolve22;
|
|
44117
44190
|
let reject;
|
|
44118
44191
|
const promise = new Promise((res, rej) => {
|
|
44119
|
-
|
|
44192
|
+
resolve22 = res;
|
|
44120
44193
|
reject = rej;
|
|
44121
44194
|
});
|
|
44122
|
-
const entry = { promise, resolve:
|
|
44195
|
+
const entry = { promise, resolve: resolve22, reject };
|
|
44123
44196
|
activeRunPromises.set(runId, entry);
|
|
44124
44197
|
return entry;
|
|
44125
44198
|
}
|
|
@@ -44644,11 +44717,11 @@ function readSkillMarkdown(cwd, name) {
|
|
|
44644
44717
|
if (cached) skillReadCache.delete(cacheKey2);
|
|
44645
44718
|
for (const entry of candidateSkillDirs(cwd)) {
|
|
44646
44719
|
try {
|
|
44647
|
-
const
|
|
44648
|
-
const contained = resolveContainedPath(entry.root,
|
|
44720
|
+
const relative9 = path44.join(name, "SKILL.md");
|
|
44721
|
+
const contained = resolveContainedPath(entry.root, relative9);
|
|
44649
44722
|
if (!fs52.existsSync(contained)) continue;
|
|
44650
44723
|
if (fs52.lstatSync(contained).isSymbolicLink()) continue;
|
|
44651
|
-
const filePath = resolveRealContainedPath(entry.root,
|
|
44724
|
+
const filePath = resolveRealContainedPath(entry.root, relative9);
|
|
44652
44725
|
const stat2 = fs52.statSync(filePath);
|
|
44653
44726
|
return rememberSkill(cacheKey2, {
|
|
44654
44727
|
path: filePath,
|
|
@@ -47069,7 +47142,7 @@ function buildTeamDoctorReport(input) {
|
|
|
47069
47142
|
);
|
|
47070
47143
|
const sections = [
|
|
47071
47144
|
section("Runtime", () => {
|
|
47072
|
-
const
|
|
47145
|
+
const git4 = commandExists("git", ["--version"]);
|
|
47073
47146
|
const pi = piCommandExists();
|
|
47074
47147
|
return [
|
|
47075
47148
|
{ label: "cwd", ok: true, detail: input.cwd },
|
|
@@ -47079,7 +47152,7 @@ function buildTeamDoctorReport(input) {
|
|
|
47079
47152
|
detail: `${process.platform}/${process.arch} node=${process.version}`
|
|
47080
47153
|
},
|
|
47081
47154
|
{ label: "pi command", ok: pi.ok, detail: pi.detail },
|
|
47082
|
-
{ label: "git command", ok:
|
|
47155
|
+
{ label: "git command", ok: git4.ok, detail: git4.detail },
|
|
47083
47156
|
{
|
|
47084
47157
|
label: "config",
|
|
47085
47158
|
ok: input.configErrors.length === 0,
|
|
@@ -49314,6 +49387,21 @@ function cleanupRunWorktrees(manifest, options = {}) {
|
|
|
49314
49387
|
const branchName = `pi-crew/${manifest.runId}/${sanitizeBranchPart(entry.name)}`;
|
|
49315
49388
|
const safeBranchName = sanitizeBranchPart(entry.name);
|
|
49316
49389
|
if (dirty) {
|
|
49390
|
+
if (!options.force) {
|
|
49391
|
+
const safePreserveName = sanitizeFilename(entry.name);
|
|
49392
|
+
const artifact = writeArtifact(manifest.artifactsRoot, {
|
|
49393
|
+
kind: "diff",
|
|
49394
|
+
relativePath: `cleanup/${safePreserveName}.diff`,
|
|
49395
|
+
content: captureDiff(worktreePath),
|
|
49396
|
+
producer: "worktree-cleanup"
|
|
49397
|
+
});
|
|
49398
|
+
result4.artifactPaths.push(artifact.path);
|
|
49399
|
+
result4.preserved.push({
|
|
49400
|
+
path: worktreePath,
|
|
49401
|
+
reason: "dirty worktree preserved \u2014 pass force=true to auto-commit and remove"
|
|
49402
|
+
});
|
|
49403
|
+
continue;
|
|
49404
|
+
}
|
|
49317
49405
|
if (options.signal?.aborted) break;
|
|
49318
49406
|
try {
|
|
49319
49407
|
const statusBefore = git(worktreePath, ["status", "--porcelain"]);
|
|
@@ -54066,8 +54154,8 @@ function safeSharedName(name) {
|
|
|
54066
54154
|
function sharedPath(manifest, name) {
|
|
54067
54155
|
const sharedRoot = path61.resolve(manifest.artifactsRoot, "shared");
|
|
54068
54156
|
const resolved = path61.resolve(sharedRoot, safeSharedName(name));
|
|
54069
|
-
const
|
|
54070
|
-
if (
|
|
54157
|
+
const relative9 = path61.relative(sharedRoot, resolved);
|
|
54158
|
+
if (relative9.startsWith("..") || path61.isAbsolute(relative9)) throw new Error(`Invalid shared artifact name: ${name}`);
|
|
54071
54159
|
return resolved;
|
|
54072
54160
|
}
|
|
54073
54161
|
function tryParseJson(text) {
|
|
@@ -54082,8 +54170,8 @@ function listTaskArtifacts(manifest, taskId) {
|
|
|
54082
54170
|
const produced = manifest.artifacts.filter((a) => a.producer === taskId);
|
|
54083
54171
|
if (produced.length === 0) return void 0;
|
|
54084
54172
|
return produced.map((a) => {
|
|
54085
|
-
const
|
|
54086
|
-
return
|
|
54173
|
+
const relative9 = path61.relative(manifest.artifactsRoot, a.path);
|
|
54174
|
+
return relative9.startsWith("..") ? a.path : relative9;
|
|
54087
54175
|
});
|
|
54088
54176
|
}
|
|
54089
54177
|
function aggregateUsage2(task) {
|
|
@@ -55372,6 +55460,45 @@ import { randomBytes as randomBytes2 } from "node:crypto";
|
|
|
55372
55460
|
import * as fs75 from "node:fs";
|
|
55373
55461
|
import * as path63 from "node:path";
|
|
55374
55462
|
import { promisify } from "node:util";
|
|
55463
|
+
function git3(cwd, args) {
|
|
55464
|
+
return execFileSync6("git", args, {
|
|
55465
|
+
cwd,
|
|
55466
|
+
encoding: "utf-8",
|
|
55467
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
55468
|
+
env: {
|
|
55469
|
+
...sanitizeEnvSecrets(process.env, {
|
|
55470
|
+
allowList: [
|
|
55471
|
+
"PATH",
|
|
55472
|
+
"HOME",
|
|
55473
|
+
"USER",
|
|
55474
|
+
...WINDOWS_ESSENTIAL_ENV_VARS,
|
|
55475
|
+
"SHELL",
|
|
55476
|
+
"TERM",
|
|
55477
|
+
"LANG",
|
|
55478
|
+
"LC_ALL",
|
|
55479
|
+
"LC_COLLATE",
|
|
55480
|
+
"LC_CTYPE",
|
|
55481
|
+
"LC_MESSAGES",
|
|
55482
|
+
"XDG_CONFIG_HOME",
|
|
55483
|
+
"XDG_DATA_HOME",
|
|
55484
|
+
"XDG_CACHE_HOME",
|
|
55485
|
+
"NVM_BIN",
|
|
55486
|
+
"NVM_DIR",
|
|
55487
|
+
"NODE_PATH",
|
|
55488
|
+
"GIT_CONFIG_GLOBAL",
|
|
55489
|
+
"GIT_CONFIG_SYSTEM",
|
|
55490
|
+
"GIT_AUTHOR_NAME",
|
|
55491
|
+
"GIT_AUTHOR_EMAIL",
|
|
55492
|
+
"GIT_COMMITTER_NAME",
|
|
55493
|
+
"GIT_COMMITTER_EMAIL"
|
|
55494
|
+
]
|
|
55495
|
+
}),
|
|
55496
|
+
LANG: "en_US.UTF-8",
|
|
55497
|
+
LC_ALL: "en_US.UTF-8"
|
|
55498
|
+
},
|
|
55499
|
+
windowsHide: true
|
|
55500
|
+
}).trim();
|
|
55501
|
+
}
|
|
55375
55502
|
function gitEnv() {
|
|
55376
55503
|
return {
|
|
55377
55504
|
...sanitizeEnvSecrets(process.env, {
|
|
@@ -55458,9 +55585,9 @@ function linkNodeModulesIfPresent(repoRoot, worktreePath) {
|
|
|
55458
55585
|
}
|
|
55459
55586
|
function normalizeSyntheticPath(worktreePath, rawPath) {
|
|
55460
55587
|
const resolved = path63.resolve(worktreePath, rawPath);
|
|
55461
|
-
const
|
|
55462
|
-
if (!
|
|
55463
|
-
return path63.normalize(
|
|
55588
|
+
const relative9 = path63.relative(worktreePath, resolved);
|
|
55589
|
+
if (!relative9 || relative9.startsWith("..") || path63.isAbsolute(relative9)) throw new Error(`synthetic path escapes worktree: ${rawPath}`);
|
|
55590
|
+
return path63.normalize(relative9);
|
|
55464
55591
|
}
|
|
55465
55592
|
function isAllowedSetupHook(hookPath) {
|
|
55466
55593
|
if (!hookPath || hookPath.trim().length === 0) return false;
|
|
@@ -55690,6 +55817,64 @@ function overlaySeedPaths(repoRoot, worktreePath, seedPaths) {
|
|
|
55690
55817
|
});
|
|
55691
55818
|
}
|
|
55692
55819
|
}
|
|
55820
|
+
function snapshotDirtyWorktree(manifest, task, worktreePath, dirtyStatus) {
|
|
55821
|
+
try {
|
|
55822
|
+
const parts = [
|
|
55823
|
+
`# Worktree recovery snapshot`,
|
|
55824
|
+
`runId: ${manifest.runId} taskId: ${task.id} path: ${worktreePath}`,
|
|
55825
|
+
`capturedAt: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
55826
|
+
""
|
|
55827
|
+
];
|
|
55828
|
+
let trackedDiff = "";
|
|
55829
|
+
try {
|
|
55830
|
+
trackedDiff = git3(worktreePath, ["diff", "HEAD"]);
|
|
55831
|
+
} catch {
|
|
55832
|
+
trackedDiff = "";
|
|
55833
|
+
}
|
|
55834
|
+
if (trackedDiff.trim()) {
|
|
55835
|
+
parts.push("## Tracked changes (`git diff HEAD`)", "```diff", trackedDiff, "```", "");
|
|
55836
|
+
}
|
|
55837
|
+
for (const line4 of dirtyStatus.split("\n")) {
|
|
55838
|
+
if (!line4.startsWith("?? ")) continue;
|
|
55839
|
+
const rel = line4.slice(3).replace(/^"|"$/g, "");
|
|
55840
|
+
if (!rel) continue;
|
|
55841
|
+
try {
|
|
55842
|
+
const abs = path63.join(worktreePath, rel);
|
|
55843
|
+
if (!fs75.existsSync(abs) || fs75.statSync(abs).isDirectory()) continue;
|
|
55844
|
+
const content = fs75.readFileSync(abs, "utf-8");
|
|
55845
|
+
parts.push(`## Untracked file: ${rel}`, "```", content, "```", "");
|
|
55846
|
+
} catch {
|
|
55847
|
+
}
|
|
55848
|
+
}
|
|
55849
|
+
writeArtifact(manifest.artifactsRoot, {
|
|
55850
|
+
kind: "diff",
|
|
55851
|
+
relativePath: `worktree-recovery/${task.id}-${Date.now()}.md`,
|
|
55852
|
+
content: parts.join("\n"),
|
|
55853
|
+
producer: "worktree-manager.snapshotDirtyWorktree",
|
|
55854
|
+
retention: "run"
|
|
55855
|
+
});
|
|
55856
|
+
} catch (err2) {
|
|
55857
|
+
logInternalError(
|
|
55858
|
+
"worktree.recovery.snapshotFailed",
|
|
55859
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
55860
|
+
`runId=${manifest.runId}, taskId=${task.id}`
|
|
55861
|
+
);
|
|
55862
|
+
}
|
|
55863
|
+
}
|
|
55864
|
+
async function cleanupCreatedWorktreeAsync(repoRoot, worktreePath, branch) {
|
|
55865
|
+
try {
|
|
55866
|
+
await gitAsync(repoRoot, ["worktree", "remove", "--force", worktreePath]);
|
|
55867
|
+
} catch {
|
|
55868
|
+
try {
|
|
55869
|
+
if (fs75.existsSync(worktreePath)) fs75.rmSync(worktreePath, { recursive: true, force: true });
|
|
55870
|
+
} catch {
|
|
55871
|
+
}
|
|
55872
|
+
}
|
|
55873
|
+
try {
|
|
55874
|
+
await gitAsync(repoRoot, ["branch", "-D", branch]);
|
|
55875
|
+
} catch {
|
|
55876
|
+
}
|
|
55877
|
+
}
|
|
55693
55878
|
async function prepareTaskWorkspaceAsync(manifest, task, stepSeedPaths) {
|
|
55694
55879
|
if (manifest.workspaceMode !== "worktree") return { cwd: task.cwd };
|
|
55695
55880
|
const repoRoot = await findGitRootAsync(manifest.cwd);
|
|
@@ -55747,16 +55932,17 @@ async function prepareTaskWorkspaceAsync(manifest, task, stepSeedPaths) {
|
|
|
55747
55932
|
}
|
|
55748
55933
|
const dirtyStatus = await gitAsync(worktreePath, ["status", "--porcelain"]);
|
|
55749
55934
|
if (dirtyStatus.trim()) {
|
|
55935
|
+
snapshotDirtyWorktree(manifest, task, worktreePath, dirtyStatus);
|
|
55750
55936
|
logInternalError(
|
|
55751
55937
|
"worktree.reused.dirty",
|
|
55752
|
-
new Error(`Discarding uncommitted changes in reused worktree at ${worktreePath}`),
|
|
55938
|
+
new Error(`Discarding uncommitted changes in reused worktree at ${worktreePath} (snapshot saved to artifacts)`),
|
|
55753
55939
|
`runId=${manifest.runId}, taskId=${task.id}, dirtyStatus=${dirtyStatus.trim()}`
|
|
55754
55940
|
);
|
|
55755
55941
|
await gitAsync(worktreePath, ["checkout", "--", "."]);
|
|
55756
55942
|
await gitAsync(worktreePath, ["clean", "-fd"]);
|
|
55757
55943
|
}
|
|
55758
|
-
const
|
|
55759
|
-
const mergedReused = normalizeSeedPaths([...
|
|
55944
|
+
const globalSeedPaths = loadedConfig.config.worktree?.seedPaths ?? [];
|
|
55945
|
+
const mergedReused = normalizeSeedPaths([...globalSeedPaths, ...stepSeedPaths ?? []], repoRoot);
|
|
55760
55946
|
if (mergedReused.length > 0) {
|
|
55761
55947
|
overlaySeedPaths(repoRoot, worktreePath, mergedReused);
|
|
55762
55948
|
}
|
|
@@ -55796,21 +55982,26 @@ async function prepareTaskWorkspaceAsync(manifest, task, stepSeedPaths) {
|
|
|
55796
55982
|
}
|
|
55797
55983
|
throw error;
|
|
55798
55984
|
}
|
|
55799
|
-
|
|
55800
|
-
|
|
55801
|
-
|
|
55802
|
-
|
|
55803
|
-
|
|
55804
|
-
|
|
55985
|
+
try {
|
|
55986
|
+
const syntheticPaths = runSetupHook(manifest, task, repoRoot, worktreePath, branch);
|
|
55987
|
+
const nodeModulesLinked = loadedConfig.config.worktree?.linkNodeModules === true ? linkNodeModulesIfPresent(repoRoot, worktreePath) : false;
|
|
55988
|
+
const globalSeedPaths = loadedConfig.config.worktree?.seedPaths ?? [];
|
|
55989
|
+
const merged = normalizeSeedPaths([...globalSeedPaths, ...stepSeedPaths ?? []], repoRoot);
|
|
55990
|
+
if (merged.length > 0) {
|
|
55991
|
+
overlaySeedPaths(repoRoot, worktreePath, merged);
|
|
55992
|
+
}
|
|
55993
|
+
return {
|
|
55994
|
+
cwd: worktreePath,
|
|
55995
|
+
worktreePath,
|
|
55996
|
+
branch,
|
|
55997
|
+
reused: false,
|
|
55998
|
+
nodeModulesLinked,
|
|
55999
|
+
syntheticPaths
|
|
56000
|
+
};
|
|
56001
|
+
} catch (setupError) {
|
|
56002
|
+
await cleanupCreatedWorktreeAsync(repoRoot, worktreePath, branch);
|
|
56003
|
+
throw setupError;
|
|
55805
56004
|
}
|
|
55806
|
-
return {
|
|
55807
|
-
cwd: worktreePath,
|
|
55808
|
-
worktreePath,
|
|
55809
|
-
branch,
|
|
55810
|
-
reused: false,
|
|
55811
|
-
nodeModulesLinked,
|
|
55812
|
-
syntheticPaths
|
|
55813
|
-
};
|
|
55814
56005
|
}
|
|
55815
56006
|
async function captureWorktreeDiffStatAsync(worktreePath) {
|
|
55816
56007
|
try {
|
|
@@ -56870,7 +57061,7 @@ import * as fs79 from "node:fs";
|
|
|
56870
57061
|
import * as path67 from "node:path";
|
|
56871
57062
|
async function detectRipgrep() {
|
|
56872
57063
|
if (cachedRgCheck !== void 0) return cachedRgCheck;
|
|
56873
|
-
return await new Promise((
|
|
57064
|
+
return await new Promise((resolve22) => {
|
|
56874
57065
|
let settled = false;
|
|
56875
57066
|
try {
|
|
56876
57067
|
const child = spawn3("rg", ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -56882,7 +57073,7 @@ async function detectRipgrep() {
|
|
|
56882
57073
|
if (settled) return;
|
|
56883
57074
|
settled = true;
|
|
56884
57075
|
cachedRgCheck = { available: false };
|
|
56885
|
-
|
|
57076
|
+
resolve22(cachedRgCheck);
|
|
56886
57077
|
});
|
|
56887
57078
|
child.on("close", (code) => {
|
|
56888
57079
|
if (settled) return;
|
|
@@ -56892,13 +57083,13 @@ async function detectRipgrep() {
|
|
|
56892
57083
|
} else {
|
|
56893
57084
|
cachedRgCheck = { available: false };
|
|
56894
57085
|
}
|
|
56895
|
-
|
|
57086
|
+
resolve22(cachedRgCheck);
|
|
56896
57087
|
});
|
|
56897
57088
|
} catch {
|
|
56898
57089
|
if (settled) return;
|
|
56899
57090
|
settled = true;
|
|
56900
57091
|
cachedRgCheck = { available: false };
|
|
56901
|
-
|
|
57092
|
+
resolve22(cachedRgCheck);
|
|
56902
57093
|
}
|
|
56903
57094
|
});
|
|
56904
57095
|
}
|
|
@@ -56915,7 +57106,7 @@ function reasonFor(file, keywords2) {
|
|
|
56915
57106
|
return `keyword match: ${hits.join(", ")}`;
|
|
56916
57107
|
}
|
|
56917
57108
|
function runRipgrep(args, cwd) {
|
|
56918
|
-
return new Promise((
|
|
57109
|
+
return new Promise((resolve22, reject) => {
|
|
56919
57110
|
let settled = false;
|
|
56920
57111
|
let stdout = "";
|
|
56921
57112
|
let stderr = "";
|
|
@@ -56936,7 +57127,7 @@ function runRipgrep(args, cwd) {
|
|
|
56936
57127
|
if (settled) return;
|
|
56937
57128
|
settled = true;
|
|
56938
57129
|
if (code === 0 || code === 1) {
|
|
56939
|
-
|
|
57130
|
+
resolve22(stdout);
|
|
56940
57131
|
} else {
|
|
56941
57132
|
reject(new Error(`rg exited ${code}: ${stderr.slice(0, 200)}`));
|
|
56942
57133
|
}
|
|
@@ -57213,9 +57404,9 @@ function artifactReference(artifactsRoot, artifact) {
|
|
|
57213
57404
|
if (!artifact) return void 0;
|
|
57214
57405
|
const root = path68.resolve(artifactsRoot);
|
|
57215
57406
|
const target = path68.resolve(artifact.path);
|
|
57216
|
-
const
|
|
57217
|
-
if (!
|
|
57218
|
-
return
|
|
57407
|
+
const relative9 = path68.relative(root, target);
|
|
57408
|
+
if (!relative9 || relative9.startsWith("..") || path68.isAbsolute(relative9)) return void 0;
|
|
57409
|
+
return relative9.replaceAll("\\", "/");
|
|
57219
57410
|
}
|
|
57220
57411
|
function buildWorkerPromptPipeline(input) {
|
|
57221
57412
|
return {
|
|
@@ -57427,7 +57618,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
|
|
|
57427
57618
|
const start = Date.now();
|
|
57428
57619
|
let output = "";
|
|
57429
57620
|
let exitCode = null;
|
|
57430
|
-
return new Promise((
|
|
57621
|
+
return new Promise((resolve22) => {
|
|
57431
57622
|
const shell = spawn4("sh", ["-c", command], {
|
|
57432
57623
|
cwd,
|
|
57433
57624
|
timeout: timeoutMs,
|
|
@@ -57441,7 +57632,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
|
|
|
57441
57632
|
});
|
|
57442
57633
|
const timer = setTimeout(() => {
|
|
57443
57634
|
shell.kill("SIGKILL");
|
|
57444
|
-
|
|
57635
|
+
resolve22({
|
|
57445
57636
|
exitCode: -1,
|
|
57446
57637
|
output: output + "\n[TIMEOUT: Command exceeded limit]",
|
|
57447
57638
|
durationMs: Date.now() - start
|
|
@@ -57452,7 +57643,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
|
|
|
57452
57643
|
shell.on("close", (code) => {
|
|
57453
57644
|
clearTimer();
|
|
57454
57645
|
exitCode = code;
|
|
57455
|
-
|
|
57646
|
+
resolve22({
|
|
57456
57647
|
exitCode,
|
|
57457
57648
|
output: output.slice(-1e5),
|
|
57458
57649
|
// Cap at 100KB
|
|
@@ -57461,7 +57652,7 @@ async function executeCommand(command, cwd, timeoutMs = 12e4) {
|
|
|
57461
57652
|
});
|
|
57462
57653
|
shell.on("error", (err2) => {
|
|
57463
57654
|
clearTimer();
|
|
57464
|
-
|
|
57655
|
+
resolve22({
|
|
57465
57656
|
exitCode: -1,
|
|
57466
57657
|
output: `Execution error: ${err2.message}`,
|
|
57467
57658
|
durationMs: Date.now() - start
|
|
@@ -60200,8 +60391,9 @@ async function executeTeamRun(input) {
|
|
|
60200
60391
|
} catch (error) {
|
|
60201
60392
|
stopTeamHeartbeat();
|
|
60202
60393
|
const message = error instanceof Error ? error.message : String(error);
|
|
60203
|
-
const
|
|
60204
|
-
const
|
|
60394
|
+
const fresh = loadRunManifestById(manifest.cwd, manifest.runId);
|
|
60395
|
+
const freshManifest = fresh?.manifest ?? manifest;
|
|
60396
|
+
const freshTasks = refreshTaskGraphQueues(fresh?.tasks ?? input.tasks);
|
|
60205
60397
|
const failedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
60206
60398
|
const tasks = freshTasks.map(
|
|
60207
60399
|
(task) => task.status === "running" || task.status === "queued" || task.status === "waiting" ? {
|
|
@@ -61787,19 +61979,19 @@ function parseRoot(start) {
|
|
|
61787
61979
|
function safeJoin(...parts) {
|
|
61788
61980
|
const filtered = parts.filter(Boolean);
|
|
61789
61981
|
if (filtered.length === 0) return "";
|
|
61790
|
-
const
|
|
61982
|
+
const sep10 = filtered.some((p) => p.includes("\\")) ? "\\" : "/";
|
|
61791
61983
|
const firstPart = filtered[0];
|
|
61792
61984
|
let leading = "";
|
|
61793
|
-
if (
|
|
61985
|
+
if (sep10 === "\\") {
|
|
61794
61986
|
if (firstPart.startsWith("\\\\")) leading = "\\\\";
|
|
61795
61987
|
else if (firstPart.startsWith("\\")) leading = "\\";
|
|
61796
61988
|
} else if (firstPart.startsWith("/")) {
|
|
61797
61989
|
leading = "/";
|
|
61798
61990
|
}
|
|
61799
|
-
const firstPartStripped =
|
|
61991
|
+
const firstPartStripped = sep10 === "\\" ? firstPart.replace(/^\\{1,2}/, "") : firstPart.replace(/^\/+/, "");
|
|
61800
61992
|
const rest = filtered.slice(1);
|
|
61801
|
-
const joined = [firstPartStripped, ...rest].filter(Boolean).join(
|
|
61802
|
-
const collapsed = joined.replace(new RegExp(`${
|
|
61993
|
+
const joined = [firstPartStripped, ...rest].filter(Boolean).join(sep10);
|
|
61994
|
+
const collapsed = joined.replace(new RegExp(`${sep10 === "\\" ? "\\\\" : "/"}{2,}`, "g"), sep10);
|
|
61803
61995
|
return leading + collapsed;
|
|
61804
61996
|
}
|
|
61805
61997
|
function safeDirname(p) {
|
|
@@ -61956,12 +62148,12 @@ function tokenize(input) {
|
|
|
61956
62148
|
continue;
|
|
61957
62149
|
}
|
|
61958
62150
|
if (/[0-9]/.test(input[i2])) {
|
|
61959
|
-
let
|
|
62151
|
+
let num2 = "";
|
|
61960
62152
|
while (i2 < input.length && /[0-9]/.test(input[i2])) {
|
|
61961
|
-
|
|
62153
|
+
num2 += input[i2];
|
|
61962
62154
|
i2++;
|
|
61963
62155
|
}
|
|
61964
|
-
tokens.push({ type: "NUMBER", value:
|
|
62156
|
+
tokens.push({ type: "NUMBER", value: num2 });
|
|
61965
62157
|
continue;
|
|
61966
62158
|
}
|
|
61967
62159
|
if (/[a-zA-Z_]/.test(input[i2])) {
|
|
@@ -62027,8 +62219,8 @@ var init_chain_parser = __esm({
|
|
|
62027
62219
|
while (this.pos < this.tokens.length) {
|
|
62028
62220
|
if (this.peek("COLON")) {
|
|
62029
62221
|
this.consume("COLON");
|
|
62030
|
-
const
|
|
62031
|
-
step.loopCount = Number.parseInt(
|
|
62222
|
+
const num2 = this.consume("NUMBER");
|
|
62223
|
+
step.loopCount = Number.parseInt(num2.value, 10);
|
|
62032
62224
|
} else if (this.peek("FLAG", "with-context")) {
|
|
62033
62225
|
this.consume("FLAG");
|
|
62034
62226
|
step.withContext = true;
|
|
@@ -68932,7 +69124,7 @@ var init_deterministic_ast = __esm({
|
|
|
68932
69124
|
});
|
|
68933
69125
|
|
|
68934
69126
|
// src/runtime/dwf-state-store.ts
|
|
68935
|
-
import { existsSync as existsSync70, mkdirSync as mkdirSync42, readFileSync as
|
|
69127
|
+
import { existsSync as existsSync70, mkdirSync as mkdirSync42, readFileSync as readFileSync69, unlinkSync as unlinkSync11 } from "node:fs";
|
|
68936
69128
|
import { dirname as dirname37 } from "node:path";
|
|
68937
69129
|
var DwfStore;
|
|
68938
69130
|
var init_dwf_state_store = __esm({
|
|
@@ -68953,7 +69145,7 @@ var init_dwf_state_store = __esm({
|
|
|
68953
69145
|
const path81 = this.path;
|
|
68954
69146
|
try {
|
|
68955
69147
|
if (!existsSync70(path81)) return void 0;
|
|
68956
|
-
const raw =
|
|
69148
|
+
const raw = readFileSync69(path81, "utf-8");
|
|
68957
69149
|
const parsed = JSON.parse(raw);
|
|
68958
69150
|
if (!parsed || typeof parsed !== "object" || typeof parsed.runId !== "string") return void 0;
|
|
68959
69151
|
return parsed;
|
|
@@ -69164,14 +69356,14 @@ var init_semaphore = __esm({
|
|
|
69164
69356
|
if (this.#queue.length >= _Semaphore.MAX_QUEUE) {
|
|
69165
69357
|
throw new Error(`Semaphore queue full: ${this.#queue.length} waiters (max ${_Semaphore.MAX_QUEUE}); cannot acquire slot`);
|
|
69166
69358
|
}
|
|
69167
|
-
const { promise, resolve:
|
|
69359
|
+
const { promise, resolve: resolve22 } = (() => {
|
|
69168
69360
|
let res;
|
|
69169
69361
|
const p = new Promise((r) => {
|
|
69170
69362
|
res = r;
|
|
69171
69363
|
});
|
|
69172
69364
|
return { promise: p, resolve: res };
|
|
69173
69365
|
})();
|
|
69174
|
-
this.#queue.push(
|
|
69366
|
+
this.#queue.push(resolve22);
|
|
69175
69367
|
return promise;
|
|
69176
69368
|
}
|
|
69177
69369
|
release() {
|
|
@@ -69775,7 +69967,7 @@ var dynamic_workflow_runner_exports = {};
|
|
|
69775
69967
|
__export(dynamic_workflow_runner_exports, {
|
|
69776
69968
|
runDynamicWorkflow: () => runDynamicWorkflow
|
|
69777
69969
|
});
|
|
69778
|
-
import { readFileSync as
|
|
69970
|
+
import { readFileSync as readFileSync70 } from "node:fs";
|
|
69779
69971
|
import { join as join71 } from "node:path";
|
|
69780
69972
|
function assertStructuredCloneable(value, name) {
|
|
69781
69973
|
try {
|
|
@@ -69800,7 +69992,7 @@ function resolveScriptPath(workflow, cwd) {
|
|
|
69800
69992
|
);
|
|
69801
69993
|
}
|
|
69802
69994
|
async function loadWorkflowModule(scriptPath) {
|
|
69803
|
-
const scriptSource =
|
|
69995
|
+
const scriptSource = readFileSync70(scriptPath, "utf-8");
|
|
69804
69996
|
if (isDeterminismCheckEnabled()) {
|
|
69805
69997
|
assertDeterministicScript(scriptSource);
|
|
69806
69998
|
}
|
|
@@ -69923,7 +70115,7 @@ async function runDynamicWorkflow(input) {
|
|
|
69923
70115
|
}
|
|
69924
70116
|
function readFinalArtifact(artifactPath) {
|
|
69925
70117
|
try {
|
|
69926
|
-
return
|
|
70118
|
+
return readFileSync70(artifactPath, "utf-8");
|
|
69927
70119
|
} catch (error) {
|
|
69928
70120
|
logInternalError("dynamic-workflow-runner.readFinal", error, `artifactPath=${artifactPath}`);
|
|
69929
70121
|
return `(failed to read final artifact ${artifactPath})`;
|
|
@@ -73818,7 +74010,7 @@ var init_run_dashboard = __esm({
|
|
|
73818
74010
|
const borderFill = (count2) => new DynamicCrewBorder(this.theme).render(count2)[0];
|
|
73819
74011
|
const border2 = (left, right) => `${fg("border", left)}${borderFill(borderWidth)}${fg("border", right)}`;
|
|
73820
74012
|
const row = (text) => `\u2502 ${pad(truncate(text, innerWidth - 1), innerWidth - 1)}\u2502`;
|
|
73821
|
-
const
|
|
74013
|
+
const sep10 = () => border2("\u251C", "\u2524");
|
|
73822
74014
|
const lines = [];
|
|
73823
74015
|
if (this.showHelp) {
|
|
73824
74016
|
lines.push(...new HelpOverlay(this.theme).render(width));
|
|
@@ -73828,7 +74020,7 @@ var init_run_dashboard = __esm({
|
|
|
73828
74020
|
row(
|
|
73829
74021
|
`${fg("accent", "\u2590")} ${this.theme.bold("pi-crew")} \xB7 ${this.runs.length} runs ${fg("dim", "1-6 pane \xB7 \u2191\u2193 \xB7 Enter \xB7 ? help \xB7 Esc")}`
|
|
73830
74022
|
),
|
|
73831
|
-
|
|
74023
|
+
sep10()
|
|
73832
74024
|
);
|
|
73833
74025
|
if (this.runs.length === 0) {
|
|
73834
74026
|
lines.push(row(fg("dim", "No runs yet.")));
|
|
@@ -73876,7 +74068,7 @@ var init_run_dashboard = __esm({
|
|
|
73876
74068
|
const agents = snap?.agents ?? agentsFor2(selectedRun, this.options.snapshotCache);
|
|
73877
74069
|
const statusStr = isLikelyOrphanedActiveRun(r, agents) ? "stale" : r.status;
|
|
73878
74070
|
const selectedTasks = snap?.tasks ?? readRunTasks2(r, this.options.snapshotCache);
|
|
73879
|
-
lines.push(
|
|
74071
|
+
lines.push(sep10());
|
|
73880
74072
|
lines.push(row(`${fg("accent", "\u25B8")} ${truncate(sanitizeLine(r.goal), innerWidth - 6)}`));
|
|
73881
74073
|
const isTerminal = statusStr === "failed" || statusStr === "cancelled" || statusStr === "stopped";
|
|
73882
74074
|
const reason = isTerminal ? summarizeTerminalReason(r, selectedTasks, snap?.cancellationReason) : void 0;
|
|
@@ -75808,10 +76000,10 @@ var init_settings_overlay = __esm({
|
|
|
75808
76000
|
typeof current2 === "number" ? String(current2) : "",
|
|
75809
76001
|
this.theme,
|
|
75810
76002
|
(value) => {
|
|
75811
|
-
const
|
|
75812
|
-
if (
|
|
75813
|
-
this.changedValues.set(def.id,
|
|
75814
|
-
this.callbacks.onChange(def.id,
|
|
76003
|
+
const num2 = value === "" ? void 0 : Number(value);
|
|
76004
|
+
if (num2 !== void 0 && !Number.isNaN(num2)) {
|
|
76005
|
+
this.changedValues.set(def.id, num2);
|
|
76006
|
+
this.callbacks.onChange(def.id, num2);
|
|
75815
76007
|
} else if (value === "") {
|
|
75816
76008
|
this.changedValues.set(def.id, void 0);
|
|
75817
76009
|
this.callbacks.onChange(def.id, void 0);
|
|
@@ -81702,12 +81894,15 @@ function registerCrewShortcuts(pi) {
|
|
|
81702
81894
|
}
|
|
81703
81895
|
var CREW_SHORTCUT_KEYS = CREW_SHORTCUTS.map((s) => s.key);
|
|
81704
81896
|
|
|
81897
|
+
// src/extension/crew-vibes/index.ts
|
|
81898
|
+
init_pi_ui_compat();
|
|
81899
|
+
|
|
81705
81900
|
// src/extension/crew-vibes/config.ts
|
|
81706
|
-
import { existsSync as existsSync76, mkdirSync as mkdirSync45, readFileSync as
|
|
81901
|
+
import { existsSync as existsSync76, mkdirSync as mkdirSync45, readFileSync as readFileSync76, writeFileSync as writeFileSync33 } from "node:fs";
|
|
81707
81902
|
import { dirname as dirname39, join as join76 } from "node:path";
|
|
81708
81903
|
|
|
81709
81904
|
// src/extension/crew-vibes/font-detect.ts
|
|
81710
|
-
import { existsSync as existsSync75, readFileSync as
|
|
81905
|
+
import { existsSync as existsSync75, readFileSync as readFileSync75 } from "node:fs";
|
|
81711
81906
|
import { homedir as homedir11, platform } from "node:os";
|
|
81712
81907
|
import { join as join75 } from "node:path";
|
|
81713
81908
|
function fontPath() {
|
|
@@ -81734,10 +81929,10 @@ function isWebTerminal() {
|
|
|
81734
81929
|
try {
|
|
81735
81930
|
let pid = process.pid;
|
|
81736
81931
|
for (let i2 = 0; i2 < 6 && pid > 1; i2++) {
|
|
81737
|
-
const cgroup =
|
|
81932
|
+
const cgroup = readFileSync75(`/proc/${pid}/cgroup`, "utf8");
|
|
81738
81933
|
if (cgroup.includes("gotty") || cgroup.includes("wetty")) return true;
|
|
81739
81934
|
const match = cgroup.match(/\d+:.*:(.*)/);
|
|
81740
|
-
const status =
|
|
81935
|
+
const status = readFileSync75(`/proc/${pid}/status`, "utf8");
|
|
81741
81936
|
const ppid = status.match(/^PPid:\s+(\d+)/m);
|
|
81742
81937
|
pid = ppid ? Number.parseInt(ppid[1], 10) : 1;
|
|
81743
81938
|
}
|
|
@@ -81780,7 +81975,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
81780
81975
|
labels: ["Orbit", "Cruise", "Warp", "Black Hole", "Supernova", "Big Bang"],
|
|
81781
81976
|
icons: ["\uE710", "\uE711", "\uE712", "\uE713", "\uE714", "\uE715"],
|
|
81782
81977
|
providerUsage: true,
|
|
81783
|
-
providerRefreshMs:
|
|
81978
|
+
providerRefreshMs: 12e4
|
|
81784
81979
|
}
|
|
81785
81980
|
};
|
|
81786
81981
|
var FALLBACK_CAPACITY_ICONS = [
|
|
@@ -81869,7 +82064,7 @@ function loadConfig2() {
|
|
|
81869
82064
|
try {
|
|
81870
82065
|
const path81 = configPath2();
|
|
81871
82066
|
if (!existsSync76(path81)) return normalizeConfig(void 0);
|
|
81872
|
-
return normalizeConfig(JSON.parse(
|
|
82067
|
+
return normalizeConfig(JSON.parse(readFileSync76(path81, "utf8")));
|
|
81873
82068
|
} catch {
|
|
81874
82069
|
return normalizeConfig(void 0);
|
|
81875
82070
|
}
|
|
@@ -81881,8 +82076,379 @@ function saveConfig(config) {
|
|
|
81881
82076
|
`);
|
|
81882
82077
|
}
|
|
81883
82078
|
|
|
82079
|
+
// src/extension/crew-vibes/figures.ts
|
|
82080
|
+
var BRAILLE_FRAMES = [
|
|
82081
|
+
"\u280B ",
|
|
82082
|
+
// ⠋
|
|
82083
|
+
"\u2819 ",
|
|
82084
|
+
// ⠙
|
|
82085
|
+
"\u2839 ",
|
|
82086
|
+
// ⠹
|
|
82087
|
+
"\u2838 ",
|
|
82088
|
+
// ⠸
|
|
82089
|
+
"\u283C ",
|
|
82090
|
+
// ⠼
|
|
82091
|
+
"\u2834 ",
|
|
82092
|
+
// ⠴
|
|
82093
|
+
"\u2826 ",
|
|
82094
|
+
// ⠦
|
|
82095
|
+
"\u2827 ",
|
|
82096
|
+
// ⠧
|
|
82097
|
+
"\u2807 ",
|
|
82098
|
+
// ⠇
|
|
82099
|
+
"\u280F "
|
|
82100
|
+
// ⠏
|
|
82101
|
+
];
|
|
82102
|
+
var PUA_CREW_FRAMES = [
|
|
82103
|
+
"\uE700 ",
|
|
82104
|
+
"\uE701 ",
|
|
82105
|
+
"\uE702 ",
|
|
82106
|
+
"\uE703 ",
|
|
82107
|
+
"\uE704 ",
|
|
82108
|
+
"\uE705 ",
|
|
82109
|
+
"\uE706 ",
|
|
82110
|
+
"\uE707 ",
|
|
82111
|
+
"\uE708 ",
|
|
82112
|
+
"\uE709 ",
|
|
82113
|
+
"\uE70A ",
|
|
82114
|
+
"\uE70B ",
|
|
82115
|
+
"\uE70C ",
|
|
82116
|
+
"\uE70D ",
|
|
82117
|
+
"\uE70E ",
|
|
82118
|
+
"\uE70F "
|
|
82119
|
+
];
|
|
82120
|
+
function crewFrames(style = "pua") {
|
|
82121
|
+
if (style === "pua" && isWebTerminal()) return BRAILLE_FRAMES;
|
|
82122
|
+
return style === "pua" ? PUA_CREW_FRAMES : BRAILLE_FRAMES;
|
|
82123
|
+
}
|
|
82124
|
+
function intervalForSpeed(config, speed) {
|
|
82125
|
+
if (speed === null || !Number.isFinite(speed) || speed <= 0) return config.defaultIntervalMs;
|
|
82126
|
+
return Math.max(config.minIntervalMs, Math.min(config.maxIntervalMs, Math.round(config.scale / speed)));
|
|
82127
|
+
}
|
|
82128
|
+
function capacityIndex(percent, levels = 6) {
|
|
82129
|
+
if (percent === null || percent === void 0 || !Number.isFinite(percent)) return 0;
|
|
82130
|
+
return Math.max(0, Math.min(levels - 1, Math.floor(Math.max(0, Math.min(100, percent)) / 100 * levels)));
|
|
82131
|
+
}
|
|
82132
|
+
function isDangerStage(index, levels) {
|
|
82133
|
+
return index >= Math.max(0, levels - 2);
|
|
82134
|
+
}
|
|
82135
|
+
|
|
82136
|
+
// src/extension/crew-vibes/footer.ts
|
|
82137
|
+
init_pi_ui_compat();
|
|
82138
|
+
init_theme_adapter();
|
|
82139
|
+
init_visual();
|
|
82140
|
+
import { isAbsolute as isAbsolute10, relative as relative8, resolve as resolve20, sep as sep9 } from "node:path";
|
|
82141
|
+
|
|
82142
|
+
// src/extension/crew-vibes/render.ts
|
|
82143
|
+
function formatCount(value) {
|
|
82144
|
+
if (value < 1e3) return value.toString();
|
|
82145
|
+
if (value < 1e4) return `${(value / 1e3).toFixed(1)}k`;
|
|
82146
|
+
if (value < 1e6) return `${Math.round(value / 1e3)}k`;
|
|
82147
|
+
if (value < 1e7) return `${(value / 1e6).toFixed(1)}M`;
|
|
82148
|
+
return `${Math.round(value / 1e6)}M`;
|
|
82149
|
+
}
|
|
82150
|
+
function asCrewTheme2(theme) {
|
|
82151
|
+
if (theme && typeof theme === "object" && typeof theme.fg === "function") {
|
|
82152
|
+
return theme;
|
|
82153
|
+
}
|
|
82154
|
+
return void 0;
|
|
82155
|
+
}
|
|
82156
|
+
function getCapacityUsage(ctx) {
|
|
82157
|
+
const fn = ctx.getContextUsage;
|
|
82158
|
+
const usage = typeof fn === "function" ? fn.call(ctx) : null;
|
|
82159
|
+
return {
|
|
82160
|
+
tokens: typeof usage?.tokens === "number" && Number.isFinite(usage.tokens) ? usage.tokens : null,
|
|
82161
|
+
percent: typeof usage?.percent === "number" && Number.isFinite(usage.percent) ? usage.percent : null
|
|
82162
|
+
};
|
|
82163
|
+
}
|
|
82164
|
+
function formatSpeed(config, speed) {
|
|
82165
|
+
return speed === null ? `-- ${config.label}` : `${speed.toFixed(1)} ${config.label}`;
|
|
82166
|
+
}
|
|
82167
|
+
function renderSpeedFooter(theme, config, speed) {
|
|
82168
|
+
const value = speed === null ? "--" : speed.toFixed(1);
|
|
82169
|
+
const valueTone = speed === null ? "dim" : "accent";
|
|
82170
|
+
const styled = theme ? `${theme.fg(valueTone, value)} ${theme.fg("dim", config.label)}` : `${value} ${config.label}`;
|
|
82171
|
+
return styled;
|
|
82172
|
+
}
|
|
82173
|
+
function renderWorkingMessage(theme, config, speed) {
|
|
82174
|
+
const left = "Working";
|
|
82175
|
+
const speedText = theme ? `${theme.fg(speed === null ? "dim" : "accent", speed === null ? "--" : speed.toFixed(1))} ${theme.fg("dim", config.label)}` : `${speed === null ? "--" : speed.toFixed(1)} ${config.label}`;
|
|
82176
|
+
return theme ? `${theme.fg("muted", left)} ${speedText}` : `${left} ${speedText}`;
|
|
82177
|
+
}
|
|
82178
|
+
function crewIndicatorFrames(theme) {
|
|
82179
|
+
const frames = crewFrames();
|
|
82180
|
+
if (!theme) return [...frames];
|
|
82181
|
+
return frames.map((frame) => theme.fg("accent", frame));
|
|
82182
|
+
}
|
|
82183
|
+
function formatCapacityPrefix(config, usage) {
|
|
82184
|
+
const display = config.tokenDisplay;
|
|
82185
|
+
if (display === "off") return "";
|
|
82186
|
+
if (display === "percentage") {
|
|
82187
|
+
return `${usage.percent === null ? "?" : Math.round(Math.max(0, Math.min(999, usage.percent)))}% `;
|
|
82188
|
+
}
|
|
82189
|
+
return `${usage.tokens === null ? "?" : formatCount(usage.tokens)} `;
|
|
82190
|
+
}
|
|
82191
|
+
function colorStage(theme, index, levels, text) {
|
|
82192
|
+
if (!theme || text.length === 0) return text;
|
|
82193
|
+
return theme.fg(isDangerStage(index, levels) ? "error" : "success", text);
|
|
82194
|
+
}
|
|
82195
|
+
function renderCapacity(theme, config, usage) {
|
|
82196
|
+
const icons = capacityIcons();
|
|
82197
|
+
const levels = icons.length;
|
|
82198
|
+
const index = capacityIndex(usage.percent, levels);
|
|
82199
|
+
const icon = icons[index] ?? icons[0];
|
|
82200
|
+
const label = config.labels[index] ?? config.labels[0];
|
|
82201
|
+
const prefix = theme ? theme.fg("muted", formatCapacityPrefix(config, usage)) : formatCapacityPrefix(config, usage);
|
|
82202
|
+
const coloredIcon = colorStage(theme, index, levels, icon);
|
|
82203
|
+
const afterIcon = config.showLabel ? ` ${colorStage(theme, index, levels, label)}` : " ";
|
|
82204
|
+
return `${prefix}${coloredIcon}${afterIcon}`;
|
|
82205
|
+
}
|
|
82206
|
+
function setSpeedStatus(ctx, config, text) {
|
|
82207
|
+
if (!ctx?.hasUI) return;
|
|
82208
|
+
if (!config.enabled || !config.speed.enabled || !config.speed.footer) {
|
|
82209
|
+
ctx.ui.setStatus(SPEED_STATUS_ID, void 0);
|
|
82210
|
+
return;
|
|
82211
|
+
}
|
|
82212
|
+
ctx.ui.setStatus(SPEED_STATUS_ID, text);
|
|
82213
|
+
}
|
|
82214
|
+
function clearVibesStatus(ctx) {
|
|
82215
|
+
if (!ctx?.hasUI) return;
|
|
82216
|
+
ctx.ui.setStatus(SPEED_STATUS_ID, void 0);
|
|
82217
|
+
ctx.ui.setStatus(CAPACITY_STATUS_ID, void 0);
|
|
82218
|
+
ctx.ui.setStatus(PROVIDER_STATUS_ID, void 0);
|
|
82219
|
+
if (ctx.ui.setWorkingIndicator) ctx.ui.setWorkingIndicator();
|
|
82220
|
+
if (ctx.ui.setWorkingMessage) ctx.ui.setWorkingMessage();
|
|
82221
|
+
}
|
|
82222
|
+
function formatResetTimer(resetAt) {
|
|
82223
|
+
if (!resetAt) return null;
|
|
82224
|
+
const diffMs = new Date(resetAt).getTime() - Date.now();
|
|
82225
|
+
if (diffMs < 0) return null;
|
|
82226
|
+
const mins = Math.floor(diffMs / 6e4);
|
|
82227
|
+
if (mins < 60) return `${mins}m`;
|
|
82228
|
+
const hours = Math.floor(mins / 60);
|
|
82229
|
+
if (hours < 48) {
|
|
82230
|
+
const remMins = mins % 60;
|
|
82231
|
+
return remMins > 0 ? `${hours}h${remMins}m` : `${hours}h`;
|
|
82232
|
+
}
|
|
82233
|
+
const days = Math.floor(hours / 24);
|
|
82234
|
+
const remHours = hours % 24;
|
|
82235
|
+
return remHours > 0 ? `${days}d${remHours}h` : `${days}d`;
|
|
82236
|
+
}
|
|
82237
|
+
function renderBar(percent, width = 8) {
|
|
82238
|
+
const clamped = Math.max(0, Math.min(100, percent));
|
|
82239
|
+
const filled = Math.round(clamped / 100 * width);
|
|
82240
|
+
return `${"\u2501".repeat(filled)}${"\u2504".repeat(width - filled)}`;
|
|
82241
|
+
}
|
|
82242
|
+
function renderProviderUsage(theme, usage) {
|
|
82243
|
+
if (!usage) return void 0;
|
|
82244
|
+
const parts = [];
|
|
82245
|
+
if (usage.providerName) {
|
|
82246
|
+
const nameText = usage.providerName;
|
|
82247
|
+
parts.push(theme ? theme.fg("muted", nameText) : nameText);
|
|
82248
|
+
}
|
|
82249
|
+
const fiveHourBar = renderBar(usage.fiveHourPercent);
|
|
82250
|
+
const fiveHourRounded = Math.round(usage.fiveHourPercent);
|
|
82251
|
+
const fiveHourReset = formatResetTimer(usage.fiveHourResetAt);
|
|
82252
|
+
const fiveHourText = `5h ${fiveHourBar} ${fiveHourRounded}%${fiveHourReset ? " " + fiveHourReset : ""}`;
|
|
82253
|
+
const fiveHourColor = usage.fiveHourPercent >= 80 ? "error" : "accent";
|
|
82254
|
+
parts.push(theme ? theme.fg(fiveHourColor, fiveHourText) : fiveHourText);
|
|
82255
|
+
const weeklyBar = renderBar(usage.weeklyPercent);
|
|
82256
|
+
const weeklyRounded = Math.round(usage.weeklyPercent);
|
|
82257
|
+
const weeklyReset = formatResetTimer(usage.weeklyResetAt);
|
|
82258
|
+
const weeklyText = `Wk ${weeklyBar} ${weeklyRounded}%${weeklyReset ? " " + weeklyReset : ""}`;
|
|
82259
|
+
parts.push(theme ? theme.fg("dim", weeklyText) : weeklyText);
|
|
82260
|
+
if (typeof usage.copilotMonthlyPercent === "number" && Number.isFinite(usage.copilotMonthlyPercent)) {
|
|
82261
|
+
const monthlyRounded = Math.round(usage.copilotMonthlyPercent);
|
|
82262
|
+
const monthlyText = `Mo: ${monthlyRounded}%`;
|
|
82263
|
+
parts.push(theme ? theme.fg("dim", monthlyText) : monthlyText);
|
|
82264
|
+
}
|
|
82265
|
+
return parts.join(" ");
|
|
82266
|
+
}
|
|
82267
|
+
|
|
82268
|
+
// src/extension/crew-vibes/footer.ts
|
|
82269
|
+
function num(value) {
|
|
82270
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
82271
|
+
}
|
|
82272
|
+
function formatCwdForFooter(cwd, home) {
|
|
82273
|
+
if (!home) return cwd;
|
|
82274
|
+
const resolvedCwd = resolve20(cwd);
|
|
82275
|
+
const resolvedHome = resolve20(home);
|
|
82276
|
+
const rel = relative8(resolvedHome, resolvedCwd);
|
|
82277
|
+
const inside = rel === "" || rel !== ".." && !rel.startsWith(`..${sep9}`) && !isAbsolute10(rel);
|
|
82278
|
+
if (!inside) return cwd;
|
|
82279
|
+
return rel === "" ? "~" : `~${sep9}${rel}`;
|
|
82280
|
+
}
|
|
82281
|
+
function sanitizeStatusText(text) {
|
|
82282
|
+
return text.replace(/[\r\n\t]/g, " ").replace(/ +/g, " ").trim();
|
|
82283
|
+
}
|
|
82284
|
+
function asFooterData(value) {
|
|
82285
|
+
if (!value || typeof value !== "object") return void 0;
|
|
82286
|
+
const record = value;
|
|
82287
|
+
if (typeof record.getGitBranch !== "function" || typeof record.getExtensionStatuses !== "function" || typeof record.getAvailableProviderCount !== "function" || typeof record.onBranchChange !== "function") {
|
|
82288
|
+
return void 0;
|
|
82289
|
+
}
|
|
82290
|
+
return value;
|
|
82291
|
+
}
|
|
82292
|
+
function computeTotals(entries) {
|
|
82293
|
+
const totals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 };
|
|
82294
|
+
for (const entry of entries) {
|
|
82295
|
+
const rec = entry;
|
|
82296
|
+
if (rec?.type !== "message" || rec.message?.role !== "assistant") continue;
|
|
82297
|
+
const usage = rec.message.usage;
|
|
82298
|
+
if (!usage) continue;
|
|
82299
|
+
totals.input += num(usage.input);
|
|
82300
|
+
totals.output += num(usage.output);
|
|
82301
|
+
totals.cacheRead += num(usage.cacheRead);
|
|
82302
|
+
totals.cacheWrite += num(usage.cacheWrite);
|
|
82303
|
+
totals.cost += num(usage.cost?.total);
|
|
82304
|
+
}
|
|
82305
|
+
return totals;
|
|
82306
|
+
}
|
|
82307
|
+
var CrewVibesFooter = class {
|
|
82308
|
+
theme;
|
|
82309
|
+
footerData;
|
|
82310
|
+
ctx;
|
|
82311
|
+
source;
|
|
82312
|
+
tui;
|
|
82313
|
+
unsubscribeBranch;
|
|
82314
|
+
constructor(deps) {
|
|
82315
|
+
this.theme = asCrewTheme(deps.theme);
|
|
82316
|
+
this.footerData = asFooterData(deps.footerData);
|
|
82317
|
+
this.ctx = deps.ctx;
|
|
82318
|
+
this.source = deps.source;
|
|
82319
|
+
this.tui = deps.tui;
|
|
82320
|
+
this.unsubscribeBranch = this.footerData ? this.footerData.onBranchChange(() => requestRenderTarget(this.tui)) : () => {
|
|
82321
|
+
};
|
|
82322
|
+
}
|
|
82323
|
+
invalidate() {
|
|
82324
|
+
}
|
|
82325
|
+
dispose() {
|
|
82326
|
+
this.unsubscribeBranch();
|
|
82327
|
+
}
|
|
82328
|
+
buildPwdLine(width) {
|
|
82329
|
+
const sm = this.ctx.sessionManager;
|
|
82330
|
+
let pwd = formatCwdForFooter(sm.getCwd(), process.env.HOME || process.env.USERPROFILE);
|
|
82331
|
+
const branch = this.footerData?.getGitBranch();
|
|
82332
|
+
if (branch) pwd = `${pwd} (${branch})`;
|
|
82333
|
+
const sessionName = sm.getSessionName?.();
|
|
82334
|
+
if (sessionName) pwd = `${pwd} \u2022 ${sessionName}`;
|
|
82335
|
+
return truncateToWidth(this.theme.fg("dim", pwd), width, this.theme.fg("dim", "..."));
|
|
82336
|
+
}
|
|
82337
|
+
buildStatsLine(width) {
|
|
82338
|
+
const theme = this.theme;
|
|
82339
|
+
const model = this.ctx.model;
|
|
82340
|
+
const totals = computeTotals(this.ctx.sessionManager.getEntries());
|
|
82341
|
+
const contextUsage = this.ctx.getContextUsage?.();
|
|
82342
|
+
const contextWindow2 = contextUsage?.contextWindow ?? model?.contextWindow ?? 0;
|
|
82343
|
+
const percentValue = contextUsage?.percent ?? 0;
|
|
82344
|
+
const percentKnown = contextUsage?.percent !== null && contextUsage?.percent !== void 0;
|
|
82345
|
+
const statsParts = [];
|
|
82346
|
+
if (totals.input) statsParts.push(`\u2191${formatCount(totals.input)}`);
|
|
82347
|
+
if (totals.output) statsParts.push(`\u2193${formatCount(totals.output)}`);
|
|
82348
|
+
if (totals.cacheRead) statsParts.push(`R${formatCount(totals.cacheRead)}`);
|
|
82349
|
+
if (totals.cacheWrite) statsParts.push(`W${formatCount(totals.cacheWrite)}`);
|
|
82350
|
+
const usingSubscription = !!(model && this.ctx.modelRegistry?.isUsingOAuth?.(this.ctx.model));
|
|
82351
|
+
if (totals.cost || usingSubscription) {
|
|
82352
|
+
statsParts.push(`$${totals.cost.toFixed(3)}${usingSubscription ? " (sub)" : ""}`);
|
|
82353
|
+
}
|
|
82354
|
+
const autoIndicator = " (auto)";
|
|
82355
|
+
const contextDisplay = percentKnown ? `${percentValue.toFixed(1)}%/${formatCount(contextWindow2)}${autoIndicator}` : `?/${formatCount(contextWindow2)}${autoIndicator}`;
|
|
82356
|
+
const contextColored = percentValue > 90 ? theme.fg("error", contextDisplay) : percentValue > 70 ? theme.fg("warning", contextDisplay) : contextDisplay;
|
|
82357
|
+
statsParts.push(contextColored);
|
|
82358
|
+
let statsLeft = statsParts.join(" ");
|
|
82359
|
+
let statsLeftWidth = visibleWidth(statsLeft);
|
|
82360
|
+
if (statsLeftWidth > width) {
|
|
82361
|
+
statsLeft = truncateToWidth(statsLeft, width, "...");
|
|
82362
|
+
statsLeftWidth = visibleWidth(statsLeft);
|
|
82363
|
+
}
|
|
82364
|
+
const minPadding = 2;
|
|
82365
|
+
const modelName = model?.id || "no-model";
|
|
82366
|
+
let rightSideWithoutProvider = modelName;
|
|
82367
|
+
if (model?.reasoning) {
|
|
82368
|
+
let level = this.source.getThinkingLevel();
|
|
82369
|
+
try {
|
|
82370
|
+
const ctx = this.ctx.sessionManager;
|
|
82371
|
+
if (typeof ctx.buildSessionContext === "function") {
|
|
82372
|
+
const resolved = ctx.buildSessionContext()?.thinkingLevel;
|
|
82373
|
+
if (resolved) level = resolved;
|
|
82374
|
+
}
|
|
82375
|
+
} catch {
|
|
82376
|
+
}
|
|
82377
|
+
const finalLevel = level || "off";
|
|
82378
|
+
rightSideWithoutProvider = finalLevel === "off" ? `${modelName} \u2022 thinking off` : `${modelName} \u2022 ${finalLevel}`;
|
|
82379
|
+
}
|
|
82380
|
+
let rightSide = rightSideWithoutProvider;
|
|
82381
|
+
const providerCount = this.footerData?.getAvailableProviderCount() ?? 0;
|
|
82382
|
+
if (providerCount > 1 && model?.provider) {
|
|
82383
|
+
rightSide = `(${model.provider}) ${rightSideWithoutProvider}`;
|
|
82384
|
+
if (statsLeftWidth + minPadding + visibleWidth(rightSide) > width) rightSide = rightSideWithoutProvider;
|
|
82385
|
+
}
|
|
82386
|
+
const rightSideWidth = visibleWidth(rightSide);
|
|
82387
|
+
let statsLine;
|
|
82388
|
+
if (statsLeftWidth + minPadding + rightSideWidth <= width) {
|
|
82389
|
+
statsLine = statsLeft + " ".repeat(width - statsLeftWidth - rightSideWidth) + rightSide;
|
|
82390
|
+
} else {
|
|
82391
|
+
const availableForRight = width - statsLeftWidth - minPadding;
|
|
82392
|
+
if (availableForRight > 0) {
|
|
82393
|
+
const truncatedRight = truncateToWidth(rightSide, availableForRight, "");
|
|
82394
|
+
const padding = " ".repeat(Math.max(0, width - statsLeftWidth - visibleWidth(truncatedRight)));
|
|
82395
|
+
statsLine = statsLeft + padding + truncatedRight;
|
|
82396
|
+
} else {
|
|
82397
|
+
statsLine = statsLeft;
|
|
82398
|
+
}
|
|
82399
|
+
}
|
|
82400
|
+
const dimStatsLeft = theme.fg("dim", statsLeft);
|
|
82401
|
+
const dimRemainder = theme.fg("dim", statsLine.slice(statsLeft.length));
|
|
82402
|
+
return dimStatsLeft + dimRemainder;
|
|
82403
|
+
}
|
|
82404
|
+
buildStatusLine(width) {
|
|
82405
|
+
if (!this.footerData) return void 0;
|
|
82406
|
+
const statuses = this.footerData.getExtensionStatuses();
|
|
82407
|
+
if (statuses.size === 0) return void 0;
|
|
82408
|
+
const joined = Array.from(statuses.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, text]) => sanitizeStatusText(text)).join(" ");
|
|
82409
|
+
if (!joined) return void 0;
|
|
82410
|
+
return truncateToWidth(joined, width, this.theme.fg("dim", "..."));
|
|
82411
|
+
}
|
|
82412
|
+
rightAlign(text, width) {
|
|
82413
|
+
const w = visibleWidth(text);
|
|
82414
|
+
if (w >= width) return truncateToWidth(text, width, "\u2026");
|
|
82415
|
+
return " ".repeat(width - w) + text;
|
|
82416
|
+
}
|
|
82417
|
+
/** Capacity + provider quota. Uses the REAL render width, so the quota is
|
|
82418
|
+
* never chopped. When both do not fit on one line, wrap to two lines
|
|
82419
|
+
* (capacity above, quota right-aligned below) per the chosen behavior. */
|
|
82420
|
+
buildMeterLines(width) {
|
|
82421
|
+
const config = this.source.getConfig();
|
|
82422
|
+
if (!config.enabled) return [];
|
|
82423
|
+
const capText = config.capacity.enabled ? renderCapacity(this.theme, config.capacity, getCapacityUsage(this.ctx)) : void 0;
|
|
82424
|
+
const quotaText = config.capacity.providerUsage ? renderProviderUsage(this.theme, this.source.getQuotaUsage()) : void 0;
|
|
82425
|
+
if (!capText && !quotaText) return [];
|
|
82426
|
+
if (capText && !quotaText) return [truncateToWidth(capText, width, "\u2026")];
|
|
82427
|
+
if (!capText && quotaText) return [this.rightAlign(quotaText, width)];
|
|
82428
|
+
const cap = capText;
|
|
82429
|
+
const quota = quotaText;
|
|
82430
|
+
const capWidth = visibleWidth(cap);
|
|
82431
|
+
const quotaWidth = visibleWidth(quota);
|
|
82432
|
+
if (capWidth + 1 + quotaWidth <= width) {
|
|
82433
|
+
const pad2 = Math.max(1, width - capWidth - quotaWidth);
|
|
82434
|
+
return [cap + " ".repeat(pad2) + quota];
|
|
82435
|
+
}
|
|
82436
|
+
return [truncateToWidth(cap, width, "\u2026"), this.rightAlign(quota, width)];
|
|
82437
|
+
}
|
|
82438
|
+
render(width) {
|
|
82439
|
+
const lines = [this.buildPwdLine(width), this.buildStatsLine(width)];
|
|
82440
|
+
const statusLine = this.buildStatusLine(width);
|
|
82441
|
+
if (statusLine) lines.push(statusLine);
|
|
82442
|
+
lines.push(...this.buildMeterLines(width));
|
|
82443
|
+
return lines;
|
|
82444
|
+
}
|
|
82445
|
+
};
|
|
82446
|
+
function createCrewVibesFooter(deps) {
|
|
82447
|
+
return new CrewVibesFooter(deps);
|
|
82448
|
+
}
|
|
82449
|
+
|
|
81884
82450
|
// src/extension/crew-vibes/provider-usage.ts
|
|
81885
|
-
import { readFileSync as
|
|
82451
|
+
import { readFileSync as readFileSync77 } from "node:fs";
|
|
81886
82452
|
import { homedir as homedir12 } from "node:os";
|
|
81887
82453
|
import { join as join77 } from "node:path";
|
|
81888
82454
|
function withTimeout(ms, fn) {
|
|
@@ -81897,7 +82463,7 @@ function loadAnthropicToken() {
|
|
|
81897
82463
|
const envToken = process.env.ANTHROPIC_OAUTH_TOKEN?.trim();
|
|
81898
82464
|
if (envToken) return envToken;
|
|
81899
82465
|
try {
|
|
81900
|
-
const data2 = JSON.parse(
|
|
82466
|
+
const data2 = JSON.parse(readFileSync77(piAuthPath(), "utf8"));
|
|
81901
82467
|
const token = data2.anthropic?.access;
|
|
81902
82468
|
return typeof token === "string" && token.length > 0 ? token : void 0;
|
|
81903
82469
|
} catch {
|
|
@@ -81908,7 +82474,7 @@ function loadZaiToken() {
|
|
|
81908
82474
|
const envKey = process.env.ZAI_API_KEY?.trim() || process.env.Z_AI_API_KEY?.trim();
|
|
81909
82475
|
if (envKey) return envKey;
|
|
81910
82476
|
try {
|
|
81911
|
-
const data2 = JSON.parse(
|
|
82477
|
+
const data2 = JSON.parse(readFileSync77(piAuthPath(), "utf8"));
|
|
81912
82478
|
const key = data2["z-ai"]?.access || data2["z-ai"]?.key || data2.zai?.access || data2.zai?.key;
|
|
81913
82479
|
return typeof key === "string" && key.length > 0 ? key : void 0;
|
|
81914
82480
|
} catch {
|
|
@@ -81919,7 +82485,7 @@ function loadMinimaxToken() {
|
|
|
81919
82485
|
const envKey = process.env.MINIMAX_API_KEY?.trim();
|
|
81920
82486
|
if (envKey) return envKey;
|
|
81921
82487
|
try {
|
|
81922
|
-
const data2 = JSON.parse(
|
|
82488
|
+
const data2 = JSON.parse(readFileSync77(piAuthPath(), "utf8"));
|
|
81923
82489
|
const key = data2.minimax?.key;
|
|
81924
82490
|
return typeof key === "string" && key.length > 0 ? key : void 0;
|
|
81925
82491
|
} catch {
|
|
@@ -81940,7 +82506,7 @@ function loadLegacyCopilotToken() {
|
|
|
81940
82506
|
const candidates = [join77(configHome, "github-copilot", "hosts.json"), join77(homedir12(), ".github-copilot", "hosts.json")];
|
|
81941
82507
|
for (const hostsPath of candidates) {
|
|
81942
82508
|
try {
|
|
81943
|
-
const data2 = JSON.parse(
|
|
82509
|
+
const data2 = JSON.parse(readFileSync77(hostsPath, "utf8"));
|
|
81944
82510
|
if (!data2 || typeof data2 !== "object") continue;
|
|
81945
82511
|
const normalized = {};
|
|
81946
82512
|
for (const [host, entry] of Object.entries(data2)) {
|
|
@@ -81961,7 +82527,7 @@ function loadCopilotToken() {
|
|
|
81961
82527
|
const envToken = (process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN || "").trim();
|
|
81962
82528
|
if (envToken) return envToken;
|
|
81963
82529
|
try {
|
|
81964
|
-
const data2 = JSON.parse(
|
|
82530
|
+
const data2 = JSON.parse(readFileSync77(piAuthPath(), "utf8"));
|
|
81965
82531
|
const piToken = data2["github-copilot"]?.refresh || data2["github-copilot"]?.access;
|
|
81966
82532
|
if (typeof piToken === "string" && piToken.length > 0) return piToken;
|
|
81967
82533
|
} catch {
|
|
@@ -82135,197 +82701,6 @@ async function fetchProviderUsage(maxAgeMs = 3e5, provider) {
|
|
|
82135
82701
|
}
|
|
82136
82702
|
}
|
|
82137
82703
|
|
|
82138
|
-
// src/extension/crew-vibes/figures.ts
|
|
82139
|
-
var BRAILLE_FRAMES = [
|
|
82140
|
-
"\u280B ",
|
|
82141
|
-
// ⠋
|
|
82142
|
-
"\u2819 ",
|
|
82143
|
-
// ⠙
|
|
82144
|
-
"\u2839 ",
|
|
82145
|
-
// ⠹
|
|
82146
|
-
"\u2838 ",
|
|
82147
|
-
// ⠸
|
|
82148
|
-
"\u283C ",
|
|
82149
|
-
// ⠼
|
|
82150
|
-
"\u2834 ",
|
|
82151
|
-
// ⠴
|
|
82152
|
-
"\u2826 ",
|
|
82153
|
-
// ⠦
|
|
82154
|
-
"\u2827 ",
|
|
82155
|
-
// ⠧
|
|
82156
|
-
"\u2807 ",
|
|
82157
|
-
// ⠇
|
|
82158
|
-
"\u280F "
|
|
82159
|
-
// ⠏
|
|
82160
|
-
];
|
|
82161
|
-
var PUA_CREW_FRAMES = [
|
|
82162
|
-
"\uE700 ",
|
|
82163
|
-
"\uE701 ",
|
|
82164
|
-
"\uE702 ",
|
|
82165
|
-
"\uE703 ",
|
|
82166
|
-
"\uE704 ",
|
|
82167
|
-
"\uE705 ",
|
|
82168
|
-
"\uE706 ",
|
|
82169
|
-
"\uE707 ",
|
|
82170
|
-
"\uE708 ",
|
|
82171
|
-
"\uE709 ",
|
|
82172
|
-
"\uE70A ",
|
|
82173
|
-
"\uE70B ",
|
|
82174
|
-
"\uE70C ",
|
|
82175
|
-
"\uE70D ",
|
|
82176
|
-
"\uE70E ",
|
|
82177
|
-
"\uE70F "
|
|
82178
|
-
];
|
|
82179
|
-
function crewFrames(style = "pua") {
|
|
82180
|
-
if (style === "pua" && isWebTerminal()) return BRAILLE_FRAMES;
|
|
82181
|
-
return style === "pua" ? PUA_CREW_FRAMES : BRAILLE_FRAMES;
|
|
82182
|
-
}
|
|
82183
|
-
function intervalForSpeed(config, speed) {
|
|
82184
|
-
if (speed === null || !Number.isFinite(speed) || speed <= 0) return config.defaultIntervalMs;
|
|
82185
|
-
return Math.max(config.minIntervalMs, Math.min(config.maxIntervalMs, Math.round(config.scale / speed)));
|
|
82186
|
-
}
|
|
82187
|
-
function capacityIndex(percent, levels = 6) {
|
|
82188
|
-
if (percent === null || percent === void 0 || !Number.isFinite(percent)) return 0;
|
|
82189
|
-
return Math.max(0, Math.min(levels - 1, Math.floor(Math.max(0, Math.min(100, percent)) / 100 * levels)));
|
|
82190
|
-
}
|
|
82191
|
-
function isDangerStage(index, levels) {
|
|
82192
|
-
return index >= Math.max(0, levels - 2);
|
|
82193
|
-
}
|
|
82194
|
-
|
|
82195
|
-
// src/extension/crew-vibes/render.ts
|
|
82196
|
-
function formatCount(value) {
|
|
82197
|
-
if (value < 1e3) return value.toString();
|
|
82198
|
-
if (value < 1e4) return `${(value / 1e3).toFixed(1)}k`;
|
|
82199
|
-
if (value < 1e6) return `${Math.round(value / 1e3)}k`;
|
|
82200
|
-
if (value < 1e7) return `${(value / 1e6).toFixed(1)}M`;
|
|
82201
|
-
return `${Math.round(value / 1e6)}M`;
|
|
82202
|
-
}
|
|
82203
|
-
function asCrewTheme2(theme) {
|
|
82204
|
-
if (theme && typeof theme === "object" && typeof theme.fg === "function") {
|
|
82205
|
-
return theme;
|
|
82206
|
-
}
|
|
82207
|
-
return void 0;
|
|
82208
|
-
}
|
|
82209
|
-
function getCapacityUsage(ctx) {
|
|
82210
|
-
const fn = ctx.getContextUsage;
|
|
82211
|
-
const usage = typeof fn === "function" ? fn.call(ctx) : null;
|
|
82212
|
-
return {
|
|
82213
|
-
tokens: typeof usage?.tokens === "number" && Number.isFinite(usage.tokens) ? usage.tokens : null,
|
|
82214
|
-
percent: typeof usage?.percent === "number" && Number.isFinite(usage.percent) ? usage.percent : null
|
|
82215
|
-
};
|
|
82216
|
-
}
|
|
82217
|
-
function formatSpeed(config, speed) {
|
|
82218
|
-
return speed === null ? `-- ${config.label}` : `${speed.toFixed(1)} ${config.label}`;
|
|
82219
|
-
}
|
|
82220
|
-
function renderSpeedFooter(theme, config, speed) {
|
|
82221
|
-
const value = speed === null ? "--" : speed.toFixed(1);
|
|
82222
|
-
const valueTone = speed === null ? "dim" : "accent";
|
|
82223
|
-
const styled = theme ? `${theme.fg(valueTone, value)} ${theme.fg("dim", config.label)}` : `${value} ${config.label}`;
|
|
82224
|
-
return styled;
|
|
82225
|
-
}
|
|
82226
|
-
function renderWorkingMessage(theme, config, speed) {
|
|
82227
|
-
const left = "Working";
|
|
82228
|
-
const speedText = theme ? `${theme.fg(speed === null ? "dim" : "accent", speed === null ? "--" : speed.toFixed(1))} ${theme.fg("dim", config.label)}` : `${speed === null ? "--" : speed.toFixed(1)} ${config.label}`;
|
|
82229
|
-
return theme ? `${theme.fg("muted", left)} ${speedText}` : `${left} ${speedText}`;
|
|
82230
|
-
}
|
|
82231
|
-
function crewIndicatorFrames(theme) {
|
|
82232
|
-
const frames = crewFrames();
|
|
82233
|
-
if (!theme) return [...frames];
|
|
82234
|
-
return frames.map((frame) => theme.fg("accent", frame));
|
|
82235
|
-
}
|
|
82236
|
-
function formatCapacityPrefix(config, usage) {
|
|
82237
|
-
const display = config.tokenDisplay;
|
|
82238
|
-
if (display === "off") return "";
|
|
82239
|
-
if (display === "percentage") {
|
|
82240
|
-
return `${usage.percent === null ? "?" : Math.round(Math.max(0, Math.min(999, usage.percent)))}% `;
|
|
82241
|
-
}
|
|
82242
|
-
return `${usage.tokens === null ? "?" : formatCount(usage.tokens)} `;
|
|
82243
|
-
}
|
|
82244
|
-
function colorStage(theme, index, levels, text) {
|
|
82245
|
-
if (!theme || text.length === 0) return text;
|
|
82246
|
-
return theme.fg(isDangerStage(index, levels) ? "error" : "success", text);
|
|
82247
|
-
}
|
|
82248
|
-
function renderCapacity(theme, config, usage) {
|
|
82249
|
-
const icons = capacityIcons();
|
|
82250
|
-
const levels = icons.length;
|
|
82251
|
-
const index = capacityIndex(usage.percent, levels);
|
|
82252
|
-
const icon = icons[index] ?? icons[0];
|
|
82253
|
-
const label = config.labels[index] ?? config.labels[0];
|
|
82254
|
-
const prefix = theme ? theme.fg("muted", formatCapacityPrefix(config, usage)) : formatCapacityPrefix(config, usage);
|
|
82255
|
-
const coloredIcon = colorStage(theme, index, levels, icon);
|
|
82256
|
-
const afterIcon = config.showLabel ? ` ${colorStage(theme, index, levels, label)}` : " ";
|
|
82257
|
-
return `${prefix}${coloredIcon}${afterIcon}`;
|
|
82258
|
-
}
|
|
82259
|
-
function setSpeedStatus(ctx, config, text) {
|
|
82260
|
-
if (!ctx?.hasUI) return;
|
|
82261
|
-
if (!config.enabled || !config.speed.enabled || !config.speed.footer) {
|
|
82262
|
-
ctx.ui.setStatus(SPEED_STATUS_ID, void 0);
|
|
82263
|
-
return;
|
|
82264
|
-
}
|
|
82265
|
-
ctx.ui.setStatus(SPEED_STATUS_ID, text);
|
|
82266
|
-
}
|
|
82267
|
-
function setCapacityStatus(ctx, config, text) {
|
|
82268
|
-
if (!ctx?.hasUI) return;
|
|
82269
|
-
if (!config.enabled || !config.capacity.enabled) {
|
|
82270
|
-
ctx.ui.setStatus(CAPACITY_STATUS_ID, void 0);
|
|
82271
|
-
return;
|
|
82272
|
-
}
|
|
82273
|
-
ctx.ui.setStatus(CAPACITY_STATUS_ID, text);
|
|
82274
|
-
}
|
|
82275
|
-
function clearVibesStatus(ctx) {
|
|
82276
|
-
if (!ctx?.hasUI) return;
|
|
82277
|
-
ctx.ui.setStatus(SPEED_STATUS_ID, void 0);
|
|
82278
|
-
ctx.ui.setStatus(CAPACITY_STATUS_ID, void 0);
|
|
82279
|
-
ctx.ui.setStatus(PROVIDER_STATUS_ID, void 0);
|
|
82280
|
-
if (ctx.ui.setWorkingIndicator) ctx.ui.setWorkingIndicator();
|
|
82281
|
-
if (ctx.ui.setWorkingMessage) ctx.ui.setWorkingMessage();
|
|
82282
|
-
}
|
|
82283
|
-
function formatResetTimer(resetAt) {
|
|
82284
|
-
if (!resetAt) return null;
|
|
82285
|
-
const diffMs = new Date(resetAt).getTime() - Date.now();
|
|
82286
|
-
if (diffMs < 0) return null;
|
|
82287
|
-
const mins = Math.floor(diffMs / 6e4);
|
|
82288
|
-
if (mins < 60) return `${mins}m`;
|
|
82289
|
-
const hours = Math.floor(mins / 60);
|
|
82290
|
-
if (hours < 48) {
|
|
82291
|
-
const remMins = mins % 60;
|
|
82292
|
-
return remMins > 0 ? `${hours}h${remMins}m` : `${hours}h`;
|
|
82293
|
-
}
|
|
82294
|
-
const days = Math.floor(hours / 24);
|
|
82295
|
-
const remHours = hours % 24;
|
|
82296
|
-
return remHours > 0 ? `${days}d${remHours}h` : `${days}d`;
|
|
82297
|
-
}
|
|
82298
|
-
function renderBar(percent, width = 8) {
|
|
82299
|
-
const clamped = Math.max(0, Math.min(100, percent));
|
|
82300
|
-
const filled = Math.round(clamped / 100 * width);
|
|
82301
|
-
return `${"\u2501".repeat(filled)}${"\u2504".repeat(width - filled)}`;
|
|
82302
|
-
}
|
|
82303
|
-
function renderProviderUsage(theme, usage) {
|
|
82304
|
-
if (!usage) return void 0;
|
|
82305
|
-
const parts = [];
|
|
82306
|
-
if (usage.providerName) {
|
|
82307
|
-
const nameText = usage.providerName;
|
|
82308
|
-
parts.push(theme ? theme.fg("muted", nameText) : nameText);
|
|
82309
|
-
}
|
|
82310
|
-
const fiveHourBar = renderBar(usage.fiveHourPercent);
|
|
82311
|
-
const fiveHourRounded = Math.round(usage.fiveHourPercent);
|
|
82312
|
-
const fiveHourReset = formatResetTimer(usage.fiveHourResetAt);
|
|
82313
|
-
const fiveHourText = `5h ${fiveHourBar} ${fiveHourRounded}%${fiveHourReset ? " " + fiveHourReset : ""}`;
|
|
82314
|
-
const fiveHourColor = usage.fiveHourPercent >= 80 ? "error" : "accent";
|
|
82315
|
-
parts.push(theme ? theme.fg(fiveHourColor, fiveHourText) : fiveHourText);
|
|
82316
|
-
const weeklyBar = renderBar(usage.weeklyPercent);
|
|
82317
|
-
const weeklyRounded = Math.round(usage.weeklyPercent);
|
|
82318
|
-
const weeklyReset = formatResetTimer(usage.weeklyResetAt);
|
|
82319
|
-
const weeklyText = `Wk ${weeklyBar} ${weeklyRounded}%${weeklyReset ? " " + weeklyReset : ""}`;
|
|
82320
|
-
parts.push(theme ? theme.fg("dim", weeklyText) : weeklyText);
|
|
82321
|
-
if (typeof usage.copilotMonthlyPercent === "number" && Number.isFinite(usage.copilotMonthlyPercent)) {
|
|
82322
|
-
const monthlyRounded = Math.round(usage.copilotMonthlyPercent);
|
|
82323
|
-
const monthlyText = `Mo: ${monthlyRounded}%`;
|
|
82324
|
-
parts.push(theme ? theme.fg("dim", monthlyText) : monthlyText);
|
|
82325
|
-
}
|
|
82326
|
-
return parts.join(" ");
|
|
82327
|
-
}
|
|
82328
|
-
|
|
82329
82704
|
// src/extension/crew-vibes/speed.ts
|
|
82330
82705
|
var COMPACTION_THRESHOLD = 5e3;
|
|
82331
82706
|
function estimateTokensFromDelta(text) {
|
|
@@ -82564,28 +82939,31 @@ function registerCrewVibes(pi) {
|
|
|
82564
82939
|
let footerTimer;
|
|
82565
82940
|
let capacityTimer;
|
|
82566
82941
|
let providerTimer;
|
|
82567
|
-
let
|
|
82942
|
+
let lastProviderUsage = null;
|
|
82568
82943
|
let currentProvider;
|
|
82569
|
-
|
|
82570
|
-
return text.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
82571
|
-
}
|
|
82572
|
-
function spreadLine(left, right) {
|
|
82573
|
-
const cols = process.stdout.columns || 120;
|
|
82574
|
-
const padding = Math.max(2, cols - visibleLen(left) - visibleLen(right));
|
|
82575
|
-
return left + "\xA0".repeat(padding) + right;
|
|
82576
|
-
}
|
|
82944
|
+
let currentThinkingLevel;
|
|
82577
82945
|
function themeOf(ctx) {
|
|
82578
82946
|
return asCrewTheme2(ctx.hasUI ? ctx.ui.theme : void 0);
|
|
82579
82947
|
}
|
|
82580
|
-
|
|
82948
|
+
const footerSource = {
|
|
82949
|
+
getConfig: () => config,
|
|
82950
|
+
getQuotaUsage: () => lastProviderUsage,
|
|
82951
|
+
getThinkingLevel: () => currentThinkingLevel
|
|
82952
|
+
};
|
|
82953
|
+
function metersActive() {
|
|
82954
|
+
return config.enabled && (config.capacity.enabled || config.capacity.providerUsage);
|
|
82955
|
+
}
|
|
82956
|
+
function installFooter(ctx) {
|
|
82581
82957
|
if (!ctx?.hasUI) return;
|
|
82582
|
-
if (!
|
|
82583
|
-
|
|
82958
|
+
if (!metersActive()) {
|
|
82959
|
+
setFooter(ctx, void 0);
|
|
82584
82960
|
return;
|
|
82585
82961
|
}
|
|
82586
|
-
|
|
82587
|
-
|
|
82588
|
-
|
|
82962
|
+
setFooter(ctx, (tui, theme, footerData) => createCrewVibesFooter({ tui, theme, footerData, ctx, source: footerSource }));
|
|
82963
|
+
requestRender(ctx);
|
|
82964
|
+
}
|
|
82965
|
+
function refreshFooter(ctx) {
|
|
82966
|
+
if (ctx?.hasUI) requestRender(ctx);
|
|
82589
82967
|
}
|
|
82590
82968
|
function publishSpeedFooter(ctx, speed = footerAnimator.value()) {
|
|
82591
82969
|
if (!config.enabled || !config.speed.enabled || !config.speed.footer) {
|
|
@@ -82660,29 +83038,28 @@ function registerCrewVibes(pi) {
|
|
|
82660
83038
|
function startCapacityTimer(ctx) {
|
|
82661
83039
|
if (capacityTimer) return;
|
|
82662
83040
|
const interval = Math.max(250, config.capacity.refreshIntervalMs);
|
|
82663
|
-
capacityTimer = setInterval(() =>
|
|
83041
|
+
capacityTimer = setInterval(() => refreshFooter(ctx), interval);
|
|
82664
83042
|
capacityTimer.unref?.();
|
|
82665
83043
|
}
|
|
83044
|
+
async function fetchProviderAndRefresh(ctx) {
|
|
83045
|
+
if (!config.enabled || !config.capacity.providerUsage) {
|
|
83046
|
+
lastProviderUsage = null;
|
|
83047
|
+
refreshFooter(ctx);
|
|
83048
|
+
return;
|
|
83049
|
+
}
|
|
83050
|
+
try {
|
|
83051
|
+
lastProviderUsage = await fetchProviderUsage(config.capacity.providerRefreshMs, currentProvider);
|
|
83052
|
+
} catch {
|
|
83053
|
+
lastProviderUsage = null;
|
|
83054
|
+
}
|
|
83055
|
+
refreshFooter(ctx);
|
|
83056
|
+
}
|
|
82666
83057
|
function startProviderTimer(ctx) {
|
|
82667
83058
|
if (providerTimer) return;
|
|
82668
83059
|
if (!config.capacity.providerUsage) return;
|
|
82669
83060
|
const interval = Math.max(1e4, config.capacity.providerRefreshMs);
|
|
82670
|
-
|
|
82671
|
-
|
|
82672
|
-
stopProviderTimer();
|
|
82673
|
-
return;
|
|
82674
|
-
}
|
|
82675
|
-
try {
|
|
82676
|
-
const usage = await fetchProviderUsage(config.capacity.providerRefreshMs, currentProvider);
|
|
82677
|
-
lastProviderText = renderProviderUsage(themeOf(ctx), usage);
|
|
82678
|
-
publishCapacity(ctx);
|
|
82679
|
-
} catch {
|
|
82680
|
-
lastProviderText = void 0;
|
|
82681
|
-
publishCapacity(ctx);
|
|
82682
|
-
}
|
|
82683
|
-
}
|
|
82684
|
-
tick();
|
|
82685
|
-
providerTimer = setInterval(tick, interval);
|
|
83061
|
+
fetchProviderAndRefresh(ctx);
|
|
83062
|
+
providerTimer = setInterval(() => fetchProviderAndRefresh(ctx), interval);
|
|
82686
83063
|
providerTimer.unref?.();
|
|
82687
83064
|
}
|
|
82688
83065
|
function resetWorking(ctx) {
|
|
@@ -82698,11 +83075,13 @@ function registerCrewVibes(pi) {
|
|
|
82698
83075
|
stopFooterTimer();
|
|
82699
83076
|
stopCapacityTimer();
|
|
82700
83077
|
stopProviderTimer();
|
|
83078
|
+
setFooter(ctx, void 0);
|
|
82701
83079
|
clearVibesStatus(ctx);
|
|
82702
83080
|
return;
|
|
82703
83081
|
}
|
|
82704
|
-
|
|
83082
|
+
installFooter(ctx);
|
|
82705
83083
|
publishSpeedFooter(ctx);
|
|
83084
|
+
startCapacityTimer(ctx);
|
|
82706
83085
|
if (config.capacity.providerUsage) startProviderTimer(ctx);
|
|
82707
83086
|
}
|
|
82708
83087
|
pi.on("session_start", (_event, ctx) => {
|
|
@@ -82717,11 +83096,13 @@ function registerCrewVibes(pi) {
|
|
|
82717
83096
|
footerAnimator.reset(null);
|
|
82718
83097
|
clearProviderUsageCache();
|
|
82719
83098
|
currentProvider = ctx.model?.provider;
|
|
83099
|
+
currentThinkingLevel = void 0;
|
|
82720
83100
|
if (!config.enabled) {
|
|
83101
|
+
setFooter(ctx, void 0);
|
|
82721
83102
|
clearVibesStatus(ctx);
|
|
82722
83103
|
return;
|
|
82723
83104
|
}
|
|
82724
|
-
|
|
83105
|
+
installFooter(ctx);
|
|
82725
83106
|
publishSpeedFooter(ctx);
|
|
82726
83107
|
startCapacityTimer(ctx);
|
|
82727
83108
|
startProviderTimer(ctx);
|
|
@@ -82760,7 +83141,7 @@ function registerCrewVibes(pi) {
|
|
|
82760
83141
|
});
|
|
82761
83142
|
pi.on("message_end", (event, ctx) => {
|
|
82762
83143
|
if (!isAssistantMessage(event.message)) return;
|
|
82763
|
-
|
|
83144
|
+
refreshFooter(ctx);
|
|
82764
83145
|
if (!config.enabled || !config.speed.enabled || !speedTracker.isStreaming) return;
|
|
82765
83146
|
const completed = speedTracker.finishMessage(assistantUsageOutput(event.message) ?? 0, assistantStopReason(event.message));
|
|
82766
83147
|
if (!completed) return;
|
|
@@ -82784,15 +83165,20 @@ function registerCrewVibes(pi) {
|
|
|
82784
83165
|
pi.on("model_select", (event, ctx) => {
|
|
82785
83166
|
currentProvider = event.model?.provider;
|
|
82786
83167
|
clearProviderUsageCache();
|
|
82787
|
-
|
|
83168
|
+
fetchProviderAndRefresh(ctx);
|
|
83169
|
+
});
|
|
83170
|
+
pi.on("thinking_level_select", (event, ctx) => {
|
|
83171
|
+
currentThinkingLevel = event.level;
|
|
83172
|
+
refreshFooter(ctx);
|
|
82788
83173
|
});
|
|
82789
|
-
pi.on("session_compact", (_event, ctx) =>
|
|
82790
|
-
pi.on("session_tree", (_event, ctx) =>
|
|
83174
|
+
pi.on("session_compact", (_event, ctx) => refreshFooter(ctx));
|
|
83175
|
+
pi.on("session_tree", (_event, ctx) => refreshFooter(ctx));
|
|
82791
83176
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
82792
83177
|
stopLiveTimer();
|
|
82793
83178
|
stopFooterTimer();
|
|
82794
83179
|
stopCapacityTimer();
|
|
82795
83180
|
stopProviderTimer();
|
|
83181
|
+
setFooter(ctx, void 0);
|
|
82796
83182
|
clearVibesStatus(ctx);
|
|
82797
83183
|
});
|
|
82798
83184
|
async function handleCommand(args, ctx) {
|
|
@@ -83687,7 +84073,7 @@ function registerSubagentTools(pi, subagentManager, options = {}) {
|
|
|
83687
84073
|
savePersistedSubagentRecord(ctx.cwd, current2);
|
|
83688
84074
|
break;
|
|
83689
84075
|
}
|
|
83690
|
-
await new Promise((
|
|
84076
|
+
await new Promise((resolve22) => setTimeout(resolve22, 1e3));
|
|
83691
84077
|
current2 = refreshPersistedSubagentRecord(ctx, current2);
|
|
83692
84078
|
if (!current2.runId) break;
|
|
83693
84079
|
}
|
|
@@ -84329,7 +84715,7 @@ Subagent may need manual intervention.`
|
|
|
84329
84715
|
if (!loaded) return true;
|
|
84330
84716
|
return !loaded.tasks.some((t2) => t2.status === "running" || t2.status === "queued");
|
|
84331
84717
|
};
|
|
84332
|
-
while (!check()) await new Promise((
|
|
84718
|
+
while (!check()) await new Promise((resolve22) => setTimeout(resolve22, 500));
|
|
84333
84719
|
};
|
|
84334
84720
|
validatedRegistry.hasRunning = async (runId) => {
|
|
84335
84721
|
const manifest = manifestCacheForRegistry.get(runId);
|