tldr-experts 0.32.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,12 +6,11 @@ import {
6
6
  WAVES_FILE,
7
7
  asRunBudget,
8
8
  buildProgress,
9
- nowRfc3339,
10
9
  spentBasis,
11
10
  storyDependsOn,
12
11
  tallyOf,
13
12
  validateRunBudget
14
- } from "./chunk-5at77jx8.js";
13
+ } from "./chunk-dw8gggv9.js";
15
14
  import {
16
15
  EventLog,
17
16
  OUTCOME_NOT_RECORDED,
@@ -22,14 +21,15 @@ import {
22
21
  isAttendedByHost,
23
22
  isFinished,
24
23
  isTerminal,
24
+ nowRfc3339,
25
25
  stageAt,
26
26
  validateRunFile
27
- } from "./chunk-akemhezh.js";
27
+ } from "./chunk-4d22xm3c.js";
28
28
  import {
29
29
  cursorStage,
30
30
  isAttendedByHostView,
31
31
  openRunViews
32
- } from "./chunk-8ds2ret8.js";
32
+ } from "./chunk-57s4mdhy.js";
33
33
  import {
34
34
  backupPathFor,
35
35
  isAlive,
@@ -38,13 +38,13 @@ import {
38
38
  workspaceRootOfRunDir,
39
39
  writeAtomic,
40
40
  yamlScalar
41
- } from "./chunk-5kv2vtha.js";
41
+ } from "./chunk-7ypyp8xk.js";
42
42
  import {
43
43
  isAdvisory,
44
44
  noteDeprecations,
45
45
  openBlocks,
46
46
  parseQuestions
47
- } from "./chunk-x1f4dxwk.js";
47
+ } from "./chunk-sjykymar.js";
48
48
  import {
49
49
  FRAMEWORK_ROOT,
50
50
  MAX_ITEM_CHARS,
@@ -55,7 +55,7 @@ import {
55
55
  parseYaml,
56
56
  parseYamlRepairing,
57
57
  withoutSrcToken
58
- } from "./chunk-9bd6b3xf.js";
58
+ } from "./chunk-0a3b8w1c.js";
59
59
 
60
60
  // src/core/statusline/runSnapshot.ts
61
61
  import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
@@ -163,6 +163,9 @@ function stage(s) {
163
163
  ];
164
164
  if (s.stale === true)
165
165
  lines.push(" stale: true");
166
+ if (s.attempt_started_at !== undefined && s.attempt_started_at !== null) {
167
+ lines.push(` attempt_started_at: ${yamlScalar(s.attempt_started_at)}`);
168
+ }
166
169
  if (s.tasks.length === 0) {
167
170
  lines.push(" tasks: []");
168
171
  } else {
@@ -795,6 +798,7 @@ function statusWithOutcome(status, outcome) {
795
798
  // src/core/run/autoGate.ts
796
799
  var AUTO_GATE_ACTOR = "auto";
797
800
  var RATE_LIMIT_RESUME_NOTE_PREFIX = "run auto resumed this stage: its auto gate was held by an unfinished " + "story a rate-limit warning parked, and the provider's own clock has since cleared it.";
801
+ var BUDGET_RESUME_NOTE_PREFIX = "run auto resumed this stage: its auto gate was held by an unfinished " + "story a budget shortfall parked, and the phase can now afford it.";
798
802
  var RETRYABLE_CONDITIONS = new Set(["checks", "claim-sources"]);
799
803
  var AUTO_GATE_REFUSED_PREFIX = "auto-gate refused — held by: ";
800
804
  var HELD_SEPARATOR = " · ";
@@ -1350,6 +1354,48 @@ function currentRateLimitPark(runDir, stageId) {
1350
1354
  return park;
1351
1355
  }
1352
1356
 
1357
+ // src/core/run/budgetPark.ts
1358
+ function currentBudgetPark(runDir, stageId) {
1359
+ let events;
1360
+ try {
1361
+ events = EventLog.forRun(runDir).readAll().events;
1362
+ } catch {
1363
+ return null;
1364
+ }
1365
+ let stageStartIndex = -1;
1366
+ for (let index = events.length - 1;index >= 0; index -= 1) {
1367
+ const event = events[index];
1368
+ if (event !== undefined && event.stage === stageId && event.type === "stage.started") {
1369
+ stageStartIndex = index;
1370
+ break;
1371
+ }
1372
+ }
1373
+ if (stageStartIndex === -1)
1374
+ return null;
1375
+ let park = null;
1376
+ for (let index = events.length - 1;index >= stageStartIndex; index -= 1) {
1377
+ const event = events[index];
1378
+ if (event === undefined || event.type !== "budget.parked" || event.stage !== stageId)
1379
+ continue;
1380
+ const payload = event.payload;
1381
+ const parked = payload.parked;
1382
+ if (typeof parked !== "string" || parked === "")
1383
+ continue;
1384
+ if (typeof payload.remainder_usd !== "number" || typeof payload.floor_usd !== "number")
1385
+ continue;
1386
+ park = { remainderUsd: payload.remainder_usd, floorUsd: payload.floor_usd, parked };
1387
+ break;
1388
+ }
1389
+ if (park === null)
1390
+ return null;
1391
+ const view = storiesView(runDir);
1392
+ if (view === null || view.unfinished.length === 0)
1393
+ return null;
1394
+ if (view.unfinished.some((story) => story.status !== "todo"))
1395
+ return null;
1396
+ return park;
1397
+ }
1398
+
1353
1399
  // src/core/run/waiting.ts
1354
1400
  var MOVABLE_KINDS = [
1355
1401
  "gate",
@@ -1408,6 +1454,14 @@ function waitingFor(run, runDir) {
1408
1454
  questions: open
1409
1455
  };
1410
1456
  }
1457
+ const budgetPark = currentBudgetPark(runDir, entry.stage.id);
1458
+ if (budgetPark !== null) {
1459
+ return {
1460
+ kind: "gate",
1461
+ message: `gate on ${entry.phase.id}/${entry.stage.id} — parked by a budget shortfall ` + `($${budgetPark.remainderUsd.toFixed(2)} left, $${budgetPark.floorUsd.toFixed(2)} needed) ` + "— resumes automatically once the phase can afford it (`tldrx budget raise`, " + "or `run auto --rebalance-finished`)",
1462
+ questions: open
1463
+ };
1464
+ }
1411
1465
  }
1412
1466
  return {
1413
1467
  kind: "gate",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  toolInput
3
- } from "./chunk-27v2rwa9.js";
3
+ } from "./chunk-d3jrf6yy.js";
4
4
 
5
5
  // src/hooks/lib/wouldBe.ts
6
6
  import { existsSync, readFileSync } from "node:fs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PROJECT_FRAMEWORK_DIR,
3
3
  PROJECT_WORK_DIR
4
- } from "./chunk-9bd6b3xf.js";
4
+ } from "./chunk-0a3b8w1c.js";
5
5
 
6
6
  // src/core/lock/workspaceLock.ts
7
7
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, openSync, readFileSync as readFileSync2, rmSync as rmSync2, writeSync, closeSync } from "node:fs";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  findDuplicate
3
- } from "./chunk-f9d2efhb.js";
3
+ } from "./chunk-bfvcebn6.js";
4
4
  import {
5
5
  evidencePath,
6
6
  gateEvidencePath,
7
7
  parseEvidence
8
- } from "./chunk-akemhezh.js";
8
+ } from "./chunk-4d22xm3c.js";
9
9
  import {
10
10
  openBlocks,
11
11
  parseQuestions
12
- } from "./chunk-x1f4dxwk.js";
12
+ } from "./chunk-sjykymar.js";
13
13
 
14
14
  // src/core/distill/distill.ts
15
15
  var CONFLICT_THRESHOLD = 0.6;
@@ -3,7 +3,7 @@ import {
3
3
  withWorkspaceLock,
4
4
  workspaceRootOfFactsPath,
5
5
  writeAtomic
6
- } from "./chunk-5kv2vtha.js";
6
+ } from "./chunk-7ypyp8xk.js";
7
7
  import {
8
8
  FACT_CONFIDENCES,
9
9
  FACT_DECIDERS,
@@ -15,7 +15,7 @@ import {
15
15
  isLive,
16
16
  isRetired,
17
17
  noteDeprecations
18
- } from "./chunk-x1f4dxwk.js";
18
+ } from "./chunk-sjykymar.js";
19
19
  import {
20
20
  SRC_PATTERNS,
21
21
  asDocument,
@@ -28,7 +28,7 @@ import {
28
28
  requireString,
29
29
  requireVersion,
30
30
  result
31
- } from "./chunk-9bd6b3xf.js";
31
+ } from "./chunk-0a3b8w1c.js";
32
32
 
33
33
  // src/core/facts/FactsStore.ts
34
34
  import { existsSync, readFileSync } from "node:fs";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  parseHookInput,
3
3
  readStdin
4
- } from "./chunk-zyz0fbz5.js";
4
+ } from "./chunk-jfaarcb1.js";
5
5
 
6
6
  // src/hooks/lib/decide.ts
7
7
  function deny(reason) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  STAGE_TUNING_DEFAULTS
3
- } from "./chunk-yyhwf3bp.js";
3
+ } from "./chunk-kcrphpwc.js";
4
4
  import {
5
5
  MAX_PLAN_STORIES,
6
6
  MAX_STORIES_PER_WAVE,
@@ -26,16 +26,7 @@ import {
26
26
  requireVersion,
27
27
  requireVersion1,
28
28
  result
29
- } from "./chunk-9bd6b3xf.js";
30
-
31
- // src/hooks/lib/actor.ts
32
- function currentActor() {
33
- const user = process.env.USER ?? process.env.USERNAME ?? "";
34
- return user.trim() === "" ? "unknown" : user.trim();
35
- }
36
- function nowRfc3339() {
37
- return `${new Date().toISOString().slice(0, 19)}Z`;
38
- }
29
+ } from "./chunk-0a3b8w1c.js";
39
30
 
40
31
  // src/core/budget/spentFigure.ts
41
32
  var SPENT_BASES = ["lower-bound", "complete"];
@@ -229,6 +220,9 @@ var REVIEWER_SHARE = STAGE_TUNING_DEFAULTS.reviewerShare;
229
220
  var REVIEWER_FLOOR_USD = 2;
230
221
  var STORY_CAP_MULTIPLIER = STAGE_TUNING_DEFAULTS.storyCapMultiplier;
231
222
  var STORY_CAP_FLOOR_USD = STAGE_TUNING_DEFAULTS.storyCapFloorUsd;
223
+ function round2(n) {
224
+ return Math.round(n * 100) / 100;
225
+ }
232
226
  function shortBy(estimate, remaining) {
233
227
  return Math.max(0.01, Math.ceil((estimate - remaining) * 100) / 100);
234
228
  }
@@ -1214,9 +1208,6 @@ function reviewEventErrored(payload) {
1214
1208
  return false;
1215
1209
  return typeof payload.detail === "string" && looksLikeReviewerError(payload.detail);
1216
1210
  }
1217
- function round2(n) {
1218
- return Math.round(n * 100) / 100;
1219
- }
1220
1211
 
1221
1212
  // src/core/budget/wouldExceed.ts
1222
1213
  function totalSpent(budget) {
@@ -1451,4 +1442,4 @@ function round6(n) {
1451
1442
  return Math.round(n * 100) / 100;
1452
1443
  }
1453
1444
 
1454
- export { currentActor, nowRfc3339, spentBasis, tallyOf, DEFAULT_ON_HOST_TOKENS_EXCEED, DEFAULT_ON_GRANT_EXCEED, DEFAULT_ECONOMY, economyFor, isHostTokens, validateRunBudget, asRunBudget, expertsDir, loadExperts, readExpertDomain, pathsIntersect, stackExpertNames, WAVES_FILE, BUILD_PHASE2 as BUILD_PHASE, buildProgress, storyDependsOn, shortBy, remainingWork, wouldExceed, wouldExceedHostTokens, raiseGrantVerdict, REBALANCE_SOURCE, planRebalance, applyRebalance, describeRebalance, raiseCommand };
1445
+ export { spentBasis, tallyOf, DEFAULT_ON_HOST_TOKENS_EXCEED, DEFAULT_ON_GRANT_EXCEED, DEFAULT_ECONOMY, economyFor, isHostTokens, validateRunBudget, asRunBudget, expertsDir, loadExperts, readExpertDomain, pathsIntersect, stackExpertNames, WAVES_FILE, BUILD_PHASE2 as BUILD_PHASE, buildProgress, storyDependsOn, shortBy, remainingWork, wouldExceed, wouldExceedHostTokens, raiseGrantVerdict, REBALANCE_SOURCE, planRebalance, applyRebalance, describeRebalance, raiseCommand };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runtime
3
- } from "./chunk-9bd6b3xf.js";
3
+ } from "./chunk-0a3b8w1c.js";
4
4
 
5
5
  // src/core/hooks/passthrough.ts
6
6
  async function readStdin() {
@@ -6,7 +6,7 @@ import {
6
6
  isRecord,
7
7
  loadWorkspace,
8
8
  parseYaml
9
- } from "./chunk-9bd6b3xf.js";
9
+ } from "./chunk-0a3b8w1c.js";
10
10
 
11
11
  // src/core/run/workflowPreset.ts
12
12
  import { existsSync, readFileSync } from "node:fs";
@@ -122,13 +122,14 @@ var PHASE_IDS = ["01-what", "02-how", "03-plan", "04-build", "05-watch"];
122
122
  var PHASE_SEGMENT_RE = /^0[1-5]-[a-z]+$/;
123
123
  var DEFAULT_TIMEOUT_S = 7200;
124
124
  function buildStageDefaults(root, scope, stageId) {
125
- const fallback = { attempts: STAGE_TUNING_DEFAULTS.attempts, timeoutS: DEFAULT_TIMEOUT_S };
125
+ const fallback = { ...STAGE_TUNING_DEFAULTS, timeoutS: DEFAULT_TIMEOUT_S };
126
126
  try {
127
127
  const preset = loadWorkflowPreset(root, scope);
128
128
  const stage = (stageId === undefined ? undefined : preset.stages.find((s) => s.id === stageId)) ?? preset.stages.find((s) => s.phase === PHASE_IDS[3]);
129
129
  if (stage === undefined)
130
130
  return fallback;
131
- return { attempts: stage.attempts, timeoutS: stage.timeout_s };
131
+ const doc = existsSync(stage.source) ? parseYaml(readFileSync(stage.source, "utf8")) : null;
132
+ return { ...readStageTuning(doc), timeoutS: stage.timeout_s };
132
133
  } catch {
133
134
  return fallback;
134
135
  }
@@ -3,7 +3,7 @@ import {
3
3
  parseSrcToken,
4
4
  srcToken,
5
5
  withoutSrcToken
6
- } from "./chunk-9bd6b3xf.js";
6
+ } from "./chunk-0a3b8w1c.js";
7
7
 
8
8
  // src/core/text/questions.ts
9
9
  var REQUIRED_METADATA_KEYS = ["id", "status", "area", "asked_by", "asked_at"];
@@ -3,7 +3,7 @@ import {
3
3
  EMPTY_SECTION_RULE,
4
4
  noneBullet,
5
5
  srcRule
6
- } from "./chunk-9bd6b3xf.js";
6
+ } from "./chunk-0a3b8w1c.js";
7
7
 
8
8
  // src/hooks/lib/messages.ts
9
9
  var GRAMMAR = "[src: <repo:path:line> | https://… | Q<n> | F<n> | $ <cmd> → exit <n> | graph:<node> | absent:<path>]";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wouldBeContent
4
- } from "./chunk-72et1xzx.js";
4
+ } from "./chunk-6jd4dnyg.js";
5
5
  import {
6
6
  claimSourcesDeny,
7
7
  claimSourcesEmptySectionDeny,
8
8
  claimSourcesMalformedDeny,
9
9
  claimSourcesUnresolvedDeny
10
- } from "./chunk-q1ge3nex.js";
10
+ } from "./chunk-vhn2vz83.js";
11
11
  import {
12
12
  allow,
13
13
  deny,
@@ -16,8 +16,8 @@ import {
16
16
  postContext,
17
17
  readPayload,
18
18
  runHook
19
- } from "./chunk-27v2rwa9.js";
20
- import"./chunk-zyz0fbz5.js";
19
+ } from "./chunk-d3jrf6yy.js";
20
+ import"./chunk-jfaarcb1.js";
21
21
  import {
22
22
  isHandoff,
23
23
  loadWorkspace,
@@ -25,7 +25,7 @@ import {
25
25
  toSrcContext,
26
26
  validateCitations,
27
27
  validateHandoff
28
- } from "./chunk-9bd6b3xf.js";
28
+ } from "./chunk-0a3b8w1c.js";
29
29
 
30
30
  // src/hooks/claim-sources.ts
31
31
  await runHook("claim-sources", async () => {
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wouldBeContent
4
- } from "./chunk-72et1xzx.js";
4
+ } from "./chunk-6jd4dnyg.js";
5
5
  import {
6
6
  dodGateDeny,
7
7
  dodGateInternalErrorDeny,
8
8
  dodGateMissingBlockDeny,
9
9
  dodGateRefusedCommandDeny
10
- } from "./chunk-q1ge3nex.js";
10
+ } from "./chunk-vhn2vz83.js";
11
11
  import {
12
12
  allow,
13
13
  deny,
@@ -15,15 +15,15 @@ import {
15
15
  filePathOf,
16
16
  isWriteOrEdit,
17
17
  readPayload
18
- } from "./chunk-27v2rwa9.js";
19
- import"./chunk-zyz0fbz5.js";
18
+ } from "./chunk-d3jrf6yy.js";
19
+ import"./chunk-jfaarcb1.js";
20
20
  import {
21
21
  loadRunView
22
- } from "./chunk-8ds2ret8.js";
22
+ } from "./chunk-57s4mdhy.js";
23
23
  import {
24
24
  DEFAULT_TIMEOUT_S,
25
25
  buildStageDefaults
26
- } from "./chunk-yyhwf3bp.js";
26
+ } from "./chunk-kcrphpwc.js";
27
27
  import {
28
28
  DodCommandRefused,
29
29
  loadWorkspace,
@@ -31,7 +31,7 @@ import {
31
31
  readStory,
32
32
  repoPath,
33
33
  runDodCommand
34
- } from "./chunk-9bd6b3xf.js";
34
+ } from "./chunk-0a3b8w1c.js";
35
35
 
36
36
  // src/hooks/dod-gate.ts
37
37
  import { basename, join } from "node:path";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wouldBeContent
4
- } from "./chunk-72et1xzx.js";
4
+ } from "./chunk-6jd4dnyg.js";
5
5
  import {
6
6
  noReAskDeny
7
- } from "./chunk-q1ge3nex.js";
7
+ } from "./chunk-vhn2vz83.js";
8
8
  import {
9
9
  FactsStore
10
- } from "./chunk-f9d2efhb.js";
10
+ } from "./chunk-bfvcebn6.js";
11
11
  import {
12
12
  allow,
13
13
  deny,
@@ -15,17 +15,17 @@ import {
15
15
  isWriteOrEdit,
16
16
  readPayload,
17
17
  runHook
18
- } from "./chunk-27v2rwa9.js";
19
- import"./chunk-zyz0fbz5.js";
20
- import"./chunk-5kv2vtha.js";
18
+ } from "./chunk-d3jrf6yy.js";
19
+ import"./chunk-jfaarcb1.js";
20
+ import"./chunk-7ypyp8xk.js";
21
21
  import {
22
22
  openBlocks,
23
23
  parseQuestions
24
- } from "./chunk-x1f4dxwk.js";
24
+ } from "./chunk-sjykymar.js";
25
25
  import {
26
26
  factsPath,
27
27
  locateWork
28
- } from "./chunk-9bd6b3xf.js";
28
+ } from "./chunk-0a3b8w1c.js";
29
29
 
30
30
  // src/hooks/no-reask.ts
31
31
  import { existsSync, readFileSync } from "node:fs";
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  questionsCard
4
- } from "./chunk-04kpbhvk.js";
5
- import"./chunk-f9d2efhb.js";
4
+ } from "./chunk-9kzevq39.js";
5
+ import"./chunk-bfvcebn6.js";
6
6
  import {
7
7
  allow,
8
8
  readPayload,
9
9
  runHook,
10
10
  sessionContext
11
- } from "./chunk-27v2rwa9.js";
12
- import"./chunk-zyz0fbz5.js";
11
+ } from "./chunk-d3jrf6yy.js";
12
+ import"./chunk-jfaarcb1.js";
13
13
  import {
14
14
  RunStore,
15
15
  closedByMachine,
@@ -20,7 +20,7 @@ import {
20
20
  runSnapshot,
21
21
  statusWithOutcome,
22
22
  whatIsWaiting
23
- } from "./chunk-whvae1vw.js";
23
+ } from "./chunk-5q89ffsn.js";
24
24
  import"./chunk-ae6bkfs5.js";
25
25
  import {
26
26
  expertsDir,
@@ -28,19 +28,19 @@ import {
28
28
  pathsIntersect,
29
29
  readExpertDomain,
30
30
  stackExpertNames
31
- } from "./chunk-5at77jx8.js";
31
+ } from "./chunk-dw8gggv9.js";
32
32
  import {
33
33
  isFinished
34
- } from "./chunk-akemhezh.js";
34
+ } from "./chunk-4d22xm3c.js";
35
35
  import {
36
36
  openRunViews
37
- } from "./chunk-8ds2ret8.js";
38
- import"./chunk-yyhwf3bp.js";
39
- import"./chunk-5kv2vtha.js";
37
+ } from "./chunk-57s4mdhy.js";
38
+ import"./chunk-kcrphpwc.js";
39
+ import"./chunk-7ypyp8xk.js";
40
40
  import {
41
41
  openBlocks,
42
42
  parseQuestions
43
- } from "./chunk-x1f4dxwk.js";
43
+ } from "./chunk-sjykymar.js";
44
44
  import {
45
45
  PROJECT_FRAMEWORK_DIR,
46
46
  PROJECT_WORK_DIR,
@@ -50,7 +50,7 @@ import {
50
50
  isRecord,
51
51
  listRunDirs,
52
52
  parseYaml
53
- } from "./chunk-9bd6b3xf.js";
53
+ } from "./chunk-0a3b8w1c.js";
54
54
 
55
55
  // src/core/status/PendingItem.ts
56
56
  function isPending(item) {
@@ -2,18 +2,18 @@
2
2
  import {
3
3
  bar,
4
4
  runSnapshot
5
- } from "./chunk-whvae1vw.js";
5
+ } from "./chunk-5q89ffsn.js";
6
6
  import"./chunk-ae6bkfs5.js";
7
- import"./chunk-5at77jx8.js";
8
- import"./chunk-akemhezh.js";
9
- import"./chunk-8ds2ret8.js";
10
- import"./chunk-yyhwf3bp.js";
11
- import"./chunk-5kv2vtha.js";
12
- import"./chunk-x1f4dxwk.js";
7
+ import"./chunk-dw8gggv9.js";
8
+ import"./chunk-4d22xm3c.js";
9
+ import"./chunk-57s4mdhy.js";
10
+ import"./chunk-kcrphpwc.js";
11
+ import"./chunk-7ypyp8xk.js";
12
+ import"./chunk-sjykymar.js";
13
13
  import {
14
14
  findWorkspaceRoot,
15
15
  runtime
16
- } from "./chunk-9bd6b3xf.js";
16
+ } from "./chunk-0a3b8w1c.js";
17
17
 
18
18
  // src/core/statusline/renderStatusLine.ts
19
19
  var NO_SESSION_DATA = "[tldrx] no session data";