@wrongstack/core 0.306.3 → 0.307.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.
Files changed (114) hide show
  1. package/dist/chronicle/index.js +957 -953
  2. package/dist/chronicle/metrics-ingest.d.ts +55 -0
  3. package/dist/chronicle/metrics-schema.d.ts +86 -0
  4. package/dist/chronicle/metrics-store.d.ts +5 -120
  5. package/dist/chronicle/project-server.js +1083 -1084
  6. package/dist/chronicle/sqlite-journal-quota.d.ts +39 -0
  7. package/dist/chronicle/sqlite-journal-schema.d.ts +25 -0
  8. package/dist/chronicle/sqlite-journal.d.ts +12 -177
  9. package/dist/coordination/agents/index.js +1738 -1690
  10. package/dist/coordination/agents/project-agent-capture.d.ts +48 -0
  11. package/dist/coordination/agents/project-agent-identity.d.ts +3 -129
  12. package/dist/coordination/agents/project-agent-roster.d.ts +17 -0
  13. package/dist/coordination/index.js +6103 -5890
  14. package/dist/coordination/mailbox-http-actor-query.d.ts +16 -0
  15. package/dist/coordination/mailbox-http-router.d.ts +0 -48
  16. package/dist/coordination/mailbox-http-sse.d.ts +12 -0
  17. package/dist/coordination/mailbox-message-types.d.ts +71 -0
  18. package/dist/coordination/mailbox-predicates.d.ts +13 -0
  19. package/dist/coordination/mailbox-project-server.js +1 -1
  20. package/dist/coordination/mailbox-session-sync.d.ts +8 -0
  21. package/dist/coordination/mailbox-types.d.ts +6 -793
  22. package/dist/core/agent-loop-context.d.ts +28 -0
  23. package/dist/core/agent-loop-detector.d.ts +25 -0
  24. package/dist/core/conversation-state.d.ts +1 -2
  25. package/dist/core/fallback-doctor.d.ts +72 -0
  26. package/dist/core/fallback-model.d.ts +19 -1
  27. package/dist/core/fallback-profile-manager.d.ts +21 -3
  28. package/dist/core/index.d.ts +2 -1
  29. package/dist/core/index.js +1143 -766
  30. package/dist/defaults/index.js +3833 -3595
  31. package/dist/execution/auto-compaction-middleware.d.ts +64 -0
  32. package/dist/execution/autonomy-brain-llm.d.ts +55 -0
  33. package/dist/execution/autonomy-brain.d.ts +3 -156
  34. package/dist/execution/compaction-budget.d.ts +38 -0
  35. package/dist/execution/compaction-core.d.ts +3 -166
  36. package/dist/execution/compaction-elision.d.ts +58 -0
  37. package/dist/execution/council-orchestrator-helpers.d.ts +39 -0
  38. package/dist/execution/council-orchestrator.d.ts +3 -42
  39. package/dist/execution/council-response-parser.d.ts +56 -0
  40. package/dist/execution/index.d.ts +1 -1
  41. package/dist/execution/index.js +10016 -9903
  42. package/dist/execution/prompt-enhancer.js +11 -3
  43. package/dist/execution/retry-policy.d.ts +27 -0
  44. package/dist/execution/tool-executor-guard.d.ts +18 -0
  45. package/dist/execution/tool-executor-runner.d.ts +12 -0
  46. package/dist/execution/tool-executor.d.ts +0 -75
  47. package/dist/goal/index.js +19 -6
  48. package/dist/hq/index.js +58 -17
  49. package/dist/index.d.ts +2 -1
  50. package/dist/index.js +8731 -7756
  51. package/dist/infrastructure/index.js +24 -1
  52. package/dist/kernel/events/agent-events.d.ts +2 -0
  53. package/dist/kernel/events/provider-events.d.ts +13 -0
  54. package/dist/plugin/index.js +2123 -1918
  55. package/dist/plugins/auto-review-config.d.ts +53 -0
  56. package/dist/plugins/auto-review-git.d.ts +19 -0
  57. package/dist/plugins/auto-review-plugin.d.ts +2 -140
  58. package/dist/plugins/review-finding-verification.d.ts +7 -0
  59. package/dist/prompts/index.d.ts +1 -0
  60. package/dist/prompts/prompt-journal.d.ts +94 -0
  61. package/dist/security/index.js +677 -667
  62. package/dist/security/permission-explain.d.ts +19 -0
  63. package/dist/security/permission-policy.d.ts +0 -101
  64. package/dist/security/yolo-risk.d.ts +5 -4
  65. package/dist/session-catalog/index.js +270 -227
  66. package/dist/session-catalog/project-server.js +277 -234
  67. package/dist/session-catalog/store-rebuild.d.ts +9 -0
  68. package/dist/session-catalog/store-schema.d.ts +48 -0
  69. package/dist/session-catalog/store.d.ts +0 -17
  70. package/dist/storage/cloud-config-sync/sanitize.d.ts +18 -0
  71. package/dist/storage/cloud-config-sync.d.ts +1 -1
  72. package/dist/storage/director-state.d.ts +6 -0
  73. package/dist/storage/file-session-writer.d.ts +2 -58
  74. package/dist/storage/index.d.ts +2 -1
  75. package/dist/storage/index.js +2121 -1736
  76. package/dist/storage/orphan-lock-cleaner.d.ts +15 -0
  77. package/dist/storage/provider-config-watcher.d.ts +9 -0
  78. package/dist/storage/session-recovery.d.ts +9 -0
  79. package/dist/storage/session-store/rename-session.d.ts +16 -0
  80. package/dist/storage/session-store/resume-session.d.ts +26 -0
  81. package/dist/storage/session-store/session-store-clear.d.ts +11 -0
  82. package/dist/storage/session-store/session-store-index.d.ts +13 -0
  83. package/dist/storage/session-store/strict-empty-check.d.ts +7 -0
  84. package/dist/storage/session-store.d.ts +2 -129
  85. package/dist/storage/session-summary-tracker.d.ts +39 -0
  86. package/dist/storage/session-write-buffer.d.ts +43 -0
  87. package/dist/storage/session-writer/session-writer-flush.d.ts +4 -0
  88. package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +28 -0
  89. package/dist/tools/fallback-agent-model-assign-tool.d.ts +18 -0
  90. package/dist/tools/fallback-leader-model-set-tool.d.ts +18 -0
  91. package/dist/tools/fallback-manage-tools.d.ts +8 -45
  92. package/dist/tools/fallback-profile-manage-tool.d.ts +16 -0
  93. package/dist/tools/fallback-provider-key-set-tool.d.ts +17 -0
  94. package/dist/tools/fallback-provider-manage-tool.d.ts +26 -0
  95. package/dist/tools/index.d.ts +1 -1
  96. package/dist/tools/index.js +5150 -5090
  97. package/dist/types/config/root.d.ts +21 -2
  98. package/dist/types/default-config.d.ts +1 -1
  99. package/dist/types/index.d.ts +54 -55
  100. package/dist/types/index.js +953 -932
  101. package/dist/types/runtime-capability-manifest.d.ts +5 -5
  102. package/dist/types/session-markers.d.ts +12 -0
  103. package/dist/types/session-markers.js +19 -0
  104. package/dist/types/session.d.ts +7 -0
  105. package/dist/worktree/worktree-manager.d.ts +1 -1
  106. package/instructions/coordination/subagent-baseline.md +2 -2
  107. package/instructions/llm/prompt-enhancer.md +2 -1
  108. package/instructions/sections/tool/common-patterns.md +21 -0
  109. package/instructions/sections/tool/delegation-compact.md +3 -1
  110. package/instructions/sections/tool/delegation-full.md +5 -1
  111. package/instructions/system-lite.md +28 -3
  112. package/instructions/system-pro.md +37 -8
  113. package/instructions/system.md +4 -2
  114. package/package.json +5 -5
@@ -228,6 +228,11 @@ function isValidEnglishRefinement(text) {
228
228
  const scores = languageScores(trimmed);
229
229
  return scores.nonEnglish === 0 && scores.english > 0;
230
230
  }
231
+ var VIBE_TAG_PATTERN = /\[vibe\]/iu;
232
+ function preserveVibeTag(original, candidate) {
233
+ if (!VIBE_TAG_PATTERN.test(original) || VIBE_TAG_PATTERN.test(candidate)) return candidate;
234
+ return `[VIBE] ${candidate}`;
235
+ }
231
236
  function latestMessageLanguage(text) {
232
237
  const scores = languageScores(text);
233
238
  if (scores.nonEnglish > scores.english) return "non_english";
@@ -240,9 +245,12 @@ function parseBilingualEnhancement(raw, original) {
240
245
  if (matches.length !== 1) return null;
241
246
  const [match] = matches;
242
247
  if (!match) return null;
243
- const refined = raw.slice(0, match.index).trim();
244
- const english = raw.slice(match.index + match[0].length).trim();
245
- if (!refined || !english || !isValidEnglishRefinement(english)) return null;
248
+ const rawRefined = raw.slice(0, match.index).trim();
249
+ const rawEnglish = raw.slice(match.index + match[0].length).trim();
250
+ if (!rawRefined || !rawEnglish) return null;
251
+ const refined = preserveVibeTag(original, rawRefined);
252
+ const english = preserveVibeTag(original, rawEnglish);
253
+ if (!isValidEnglishRefinement(english)) return null;
246
254
  const inputLanguage = latestMessageLanguage(original);
247
255
  const refinedLanguage = latestMessageLanguage(refined);
248
256
  if (inputLanguage === "non_english" && refinedLanguage === "english") return null;
@@ -1,5 +1,32 @@
1
1
  import { ProviderError } from '../types/provider.js';
2
2
  import type { RetryPolicy } from '../types/retry-policy.js';
3
+ /**
4
+ * Retries a single model gets before the turn moves on to the next entry in
5
+ * the fallback chain.
6
+ *
7
+ * One number for every recoverable failure kind, on purpose. The per-kind
8
+ * budgets used to range from 2 (timeout, network, stream_hang) to 5
9
+ * (rate_limit), which made "how long until we try another model?" depend on
10
+ * which error came back: a rate-limited model could spend five backoff waits —
11
+ * each honouring a `Retry-After` up to 60s — before the cross-model fallback
12
+ * engine, which only engages once in-place retries are exhausted, got its
13
+ * turn, while a timeout gave up after two. The contract is now uniform and
14
+ * predictable across every surface that runs the agent loop (leader, host
15
+ * subagents, Chimera reviewers, SDD workers — they all resolve this one
16
+ * policy from the container): try the model {@link MODEL_RETRIES} times, then
17
+ * fail over.
18
+ *
19
+ * Exhaustive by construction (`Record<ProviderErrorKind, …>`) — adding a new
20
+ * kind refuses to compile until it gets an attempt budget.
21
+ *
22
+ * Zero means "do not replay this request against this model":
23
+ * - request-shaped failures (auth / invalid_request / context_overflow /
24
+ * content_filter) would fail identically on every attempt;
25
+ * - `quota_exhausted` is a depleted account or plan, not a transient burst, so
26
+ * the route is done until it resets — retrying only delays the hop, and the
27
+ * kind IS fallback-worthy, so another provider gets tried immediately.
28
+ */
29
+ export declare const MODEL_RETRIES = 3;
3
30
  export declare class DefaultRetryPolicy implements RetryPolicy {
4
31
  shouldRetry(err: Error | ProviderError, attempt: number): boolean;
5
32
  maxAttempts(err: Error | ProviderError): number;
@@ -0,0 +1,18 @@
1
+ import type { Context } from '../core/context.js';
2
+ import { evaluateToolKanbanBoundary } from '../security/kanban-boundary.js';
3
+ import type { ToolResultBlock, ToolUseBlock } from '../types/blocks.js';
4
+ import type { Tool } from '../types/tool.js';
5
+ import type { ToolExecutorOptions } from '../types/tool-executor.js';
6
+ export type KanbanBoundaryResult = Awaited<ReturnType<typeof evaluateToolKanbanBoundary>>;
7
+ export interface PreExecutionValidationResult {
8
+ ok: boolean;
9
+ use: ToolUseBlock;
10
+ errorResult?: ToolResultBlock | undefined;
11
+ preToolContext?: {
12
+ text: string;
13
+ contextAs: 'inline' | 'separate';
14
+ } | undefined;
15
+ boundary?: KanbanBoundaryResult | undefined;
16
+ }
17
+ export declare function validateToolInputAndHooks(tool: Tool, use0: ToolUseBlock, ctx: Context, opts: ToolExecutorOptions): Promise<PreExecutionValidationResult>;
18
+ //# sourceMappingURL=tool-executor-guard.d.ts.map
@@ -0,0 +1,12 @@
1
+ import type { Context } from '../core/context.js';
2
+ import type { Tool } from '../types/tool.js';
3
+ import type { ToolExecutorOptions } from '../types/tool-executor.js';
4
+ export declare function runToolCleanup(tool: Tool, input: unknown, ctx: Context): Promise<void>;
5
+ export declare function runToolWithTimeout(tool: Tool, input: unknown, parentSignal: AbortSignal, ctx: Context, opts: ToolExecutorOptions, config: {
6
+ iterationTimeoutMs: number;
7
+ maxToolTimeoutMs: number;
8
+ progressEmitIntervalMs: number;
9
+ progressTailChars: number;
10
+ progressHeadChars: number;
11
+ }, toolUseId?: string | undefined): Promise<unknown>;
12
+ //# sourceMappingURL=tool-executor-runner.d.ts.map
@@ -20,53 +20,13 @@ export declare class ToolExecutor {
20
20
  get(name: string): Tool | undefined;
21
21
  list(): Tool[];
22
22
  }, opts: ToolExecutorOptions);
23
- /**
24
- * Clear the interactive confirm awaiter so the executor returns
25
- * `ToolConfirmPendingResult` instead of blocking on stdin. Used by
26
- * the CLI to switch from inline prompts (REPL) to event-driven
27
- * confirmation (TUI) at runtime.
28
- */
29
23
  clearConfirmAwaiter(): void;
30
- /**
31
- * Push the tool's per-tool result-render mode into the renderer as the
32
- * next-result render mode. The config key is `tools.resultRenderMode[name]`
33
- * — independent of the LLM-side `descriptionMode` so the two can be
34
- * toggled separately (`/tool read desc simple` vs `/tool read result
35
- * simple`). Defaults to `extend` when no entry is set.
36
- *
37
- * The hint is one-shot: the renderer consumes it on the next
38
- * `writeToolResult` call so an unset follow-up doesn't inherit a
39
- * previous tool's mode. Safe no-op when the renderer doesn't implement
40
- * `setResultRenderMode` (e.g. headless/test renderers).
41
- */
42
24
  private hintRenderMode;
43
25
  private logToolSuccess;
44
26
  private logToolFailure;
45
- /**
46
- * Execute a batch of tool uses using the configured strategy.
47
- * Returns the execution results and the remaining output budget.
48
- */
49
27
  executeBatch(toolUses: ToolUseBlock[], ctx: Context, strategy: ToolExecutorStrategy): Promise<ToolBatchResult>;
50
- /**
51
- * Internal batch implementation. Nested meta-tool calls enter here through
52
- * the governed bridge so they traverse the same validation, hooks,
53
- * permission/capability, timeout, scrubbing, and audit path without
54
- * replacing the bridge that is already active for the outer call.
55
- */
56
28
  private executeBatchInternal;
57
- /**
58
- * Install the executor-owned bridge used by meta-tools for nested calls.
59
- * The bridge deliberately returns the governed, scrubbed ToolResultBlock
60
- * content rather than the raw tool value. This prevents a meta-tool from
61
- * bypassing output controls while preserving structured success/failure.
62
- */
63
29
  private withGovernedExecutionBridge;
64
- /**
65
- * Execute a single tool with timeout and output capping after its permission
66
- * decision has already been resolved by executeBatch/the confirmation flow.
67
- * Also installs the governed bridge because confirmed tools are re-run
68
- * through this method after a pending confirmation.
69
- */
70
30
  executeTool(tool: Tool, use: ToolUseBlock, ctx: Context, budget: number, preToolContext?: {
71
31
  text: string;
72
32
  contextAs: 'inline' | 'separate';
@@ -74,44 +34,9 @@ export declare class ToolExecutor {
74
34
  block: ToolResultBlock;
75
35
  bytes: number;
76
36
  }>;
77
- /**
78
- * Async "produce" phase: run the tool, serialize, scrub, and spill an
79
- * oversized output to a disk artifact. Returns the pre-cap text. This is
80
- * the long-running, concurrency-safe part — it touches NO shared budget
81
- * state, so multiple invocations can run in parallel without racing.
82
- *
83
- * The `budgetHint` only gates the disk-spill threshold (a heuristic for
84
- * "is this output large enough to persist"); it is NOT the output cap.
85
- * The authoritative cap is applied synchronously in settleToolOutput()
86
- * against the live budget.
87
- */
88
37
  private produceToolOutput;
89
- /**
90
- * Synchronous "settle" phase: enforce the output cap against the CURRENT
91
- * budget, render, and build the result block. This MUST stay synchronous
92
- * (no awaits) so that, in the parallel/smart strategies, two tools settling
93
- * one after another against the shared closure budget can't interleave a
94
- * stale read with a write. The first to settle consumes its bytes; the next
95
- * settles against the reduced budget; once the budget hits 0, enforceCap
96
- * truncates — making the per-iteration cap genuinely CUMULATIVE across
97
- * parallel tools instead of degrading into a per-tool cap.
98
- */
99
38
  private settleToolOutput;
100
39
  private runWithTimeout;
101
- /** Best-effort tool cleanup; never let it mask the original error. */
102
- private runToolCleanup;
103
- private runStreamedTool;
104
- /**
105
- * Subtract a string-content result's UTF-8 byte length from the
106
- * iteration output budget. Used for synthesized results (unknown tool,
107
- * validation error, blocked, threw) where the content is a small
108
- * string built in the executor. The success path no longer goes
109
- * through here — `executeTool` carries the exact byte count it spent
110
- * in its return value, derived from `enforceCap`'s `newBudget`.
111
- *
112
- * Floors the result at 0 to match the pre-fix `decrementBudget`
113
- * semantics (over-budget spends don't underflow the running total).
114
- */
115
40
  private budgetForString;
116
41
  }
117
42
  //# sourceMappingURL=tool-executor.d.ts.map
@@ -1113,7 +1113,7 @@ function getReadyPhases(graph) {
1113
1113
  if (phase.status !== "pending") continue;
1114
1114
  const depsDone = phase.dependsOn.every((depId) => {
1115
1115
  const dep = graph.phases.get(depId);
1116
- return dep?.status === "completed" || dep?.status === "skipped" || dep?.status === "failed";
1116
+ return dep?.status === "completed" || dep?.status === "skipped";
1117
1117
  });
1118
1118
  if (depsDone) {
1119
1119
  ready.push(phase);
@@ -1143,9 +1143,7 @@ function getCompletedTaskCount(trackerFor, phase) {
1143
1143
  }
1144
1144
  function isGraphComplete(graph) {
1145
1145
  const allPhases = Array.from(graph.phases.values());
1146
- return allPhases.every(
1147
- (p) => p.status === "completed" || p.status === "skipped" || p.status === "failed"
1148
- );
1146
+ return allPhases.every((p) => p.status === "completed" || p.status === "skipped");
1149
1147
  }
1150
1148
  function getProgress(graph, trackerFor) {
1151
1149
  const phases = Array.from(graph.phases.values());
@@ -1243,6 +1241,7 @@ async function failPhaseAfterTasks(int, phase, error) {
1243
1241
  phase.actualDurationMs = Date.now() - (phase.startedAt ?? Date.now());
1244
1242
  int.runningPhases.delete(phase.id);
1245
1243
  int.graph.activePhaseIds = int.graph.activePhaseIds.filter((id) => id !== phase.id);
1244
+ if (!int.graph.failedPhaseIds.includes(phase.id)) int.graph.failedPhaseIds.push(phase.id);
1246
1245
  int.emit("phase.failed", { phaseId: phase.id, name: phase.name, error });
1247
1246
  int.ctx.onPhaseFail?.(phase, new Error(error));
1248
1247
  await keepWorktreeForReview(int, phase);
@@ -1454,7 +1453,10 @@ var PhaseOrchestrator = class {
1454
1453
  maxVerifyAttempts: opts.maxVerifyAttempts ?? 2,
1455
1454
  autonomous: opts.autonomous ?? true,
1456
1455
  phaseDelayMs: opts.phaseDelayMs ?? 0,
1457
- stopOnFailure: opts.stopOnFailure ?? false,
1456
+ // Autonomous goals must fail closed. Continuing after a terminal task or
1457
+ // gate failure can make dependent phases look complete without their
1458
+ // required evidence.
1459
+ stopOnFailure: opts.stopOnFailure ?? true,
1458
1460
  taskTimeoutMs: opts.taskTimeoutMs ?? 6e5,
1459
1461
  events: this.events
1460
1462
  };
@@ -1594,6 +1596,13 @@ var PhaseOrchestrator = class {
1594
1596
  }
1595
1597
  this.emit("phase.started", { phaseId: phase.id, name: phase.name });
1596
1598
  try {
1599
+ if (phase.taskGraph.nodes.size === 0) {
1600
+ await this.failPhaseAfterTasks(
1601
+ phase,
1602
+ "Phase has no executable tasks. Add task evidence before starting this phase."
1603
+ );
1604
+ return;
1605
+ }
1597
1606
  await this.executePhaseTasks(phase);
1598
1607
  const failedTasks = this.getFailedTaskCount(phase);
1599
1608
  const completedTasks = this.getCompletedTaskCount(phase);
@@ -2248,8 +2257,12 @@ ${ctx}
2248
2257
  for (const entry of data) {
2249
2258
  const result = this.coercePhase(entry);
2250
2259
  if (result) {
2251
- phases.push(result.phase);
2252
2260
  warnings.push(...result.warnings);
2261
+ if (result.phase.taskTemplates?.length) {
2262
+ phases.push(result.phase);
2263
+ } else {
2264
+ warnings.push(`Phase "${result.phase.name}" has no executable tasks and was rejected.`);
2265
+ }
2253
2266
  }
2254
2267
  }
2255
2268
  return { phases, warnings };
package/dist/hq/index.js CHANGED
@@ -671,10 +671,28 @@ var HQ_TRANSCRIPT_TEXT_CAP = 16e3;
671
671
  import { randomUUID } from "node:crypto";
672
672
  import * as v8 from "node:v8";
673
673
 
674
- // src/coordination/mailbox-types.ts
674
+ // src/coordination/mailbox-predicates.ts
675
675
  var SESSION_RECIPIENT_PREFIX = "@session:";
676
676
 
677
677
  // src/security/secret-scrubber.ts
678
+ var JSON_CREDENTIAL_KEY_ANCHORS = [
679
+ 'Key"',
680
+ 'key"',
681
+ 'KEY"',
682
+ 'token"',
683
+ 'Token"',
684
+ 'TOKEN"',
685
+ 'secret"',
686
+ 'Secret"',
687
+ 'SECRET"',
688
+ 'password"',
689
+ 'Password"',
690
+ 'PASSWORD"',
691
+ 'authorization"',
692
+ 'Authorization"',
693
+ 'bearer"',
694
+ 'Bearer"'
695
+ ];
678
696
  var PATTERNS = [
679
697
  // Anchored at the start where possible so partial matches inside larger
680
698
  // strings don't trigger false positives.
@@ -777,6 +795,30 @@ var PATTERNS = [
777
795
  regex: /(^|\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?(?=\s|$)/g,
778
796
  anchor: ["KEY", "TOKEN", "SECRET", "PASSWORD", "PWD"]
779
797
  },
798
+ {
799
+ type: "json_credential_key",
800
+ // The JSON counterpart to `high_entropy_env`, and the pattern that the
801
+ // now-deleted `JSON_KEY_ANCHORS` list was written for. Without it those
802
+ // anchors only widened the cheap pre-scan — `hasCredentialAnchors` said
803
+ // "this text may hold a secret", every pattern then declined to match, and
804
+ // the value went out verbatim. `high_entropy_env` cannot cover these: it
805
+ // requires an UPPERCASE unquoted key (`API_KEY=…`), so `{"apiKey":"…"}`
806
+ // never matched.
807
+ //
808
+ // Tool results are routinely serialised as JSON, and a credential with no
809
+ // recognisable prefix (Azure, self-hosted gateways, Anthropic/Codex OAuth)
810
+ // has no other pattern that can catch it — this is the only thing standing
811
+ // between such a value and the session JSONL, chronicle, HQ broadcast and
812
+ // the model's own context.
813
+ //
814
+ // The key may carry a prefix (`"anthropicApiKey"`), but the credential word
815
+ // must END the key: `"tokenCount"` and `"maxTokens"` do not match, because
816
+ // the closing quote has to follow the word immediately.
817
+ // Value floor of 8 chars keeps enum-ish values (`"authorization":"none"`)
818
+ // out. Capture groups: 1=key + punctuation, 2=value, 3=closing quote.
819
+ regex: /("[A-Za-z0-9_]*(?:apiKey|api_key|token|secret|password|authorization|bearer|private_key|access_token|refresh_token|client_secret)"\s*:\s*")([^"\\]{8,512})(")/gi,
820
+ anchor: JSON_CREDENTIAL_KEY_ANCHORS
821
+ },
780
822
  // ── Ported from packages/plugins credential-patterns.ts (WS-034) ─────────
781
823
  // The plugin runtime carried 37 patterns while this scrubber — the one that
782
824
  // guards session JSONL, chronicle, HQ broadcast, WebUI events and the auth
@@ -859,9 +901,12 @@ var PATTERNS = [
859
901
  anchor: "GOCSPX-"
860
902
  }
861
903
  ];
862
- var SIMPLE_PATTERNS = PATTERNS.filter((p) => p.type !== "high_entropy_env");
904
+ var SIMPLE_PATTERNS = PATTERNS.filter(
905
+ (p) => p.type !== "high_entropy_env" && p.type !== "json_credential_key"
906
+ );
863
907
  var COMBINED_REGEX = new RegExp(SIMPLE_PATTERNS.map((p) => `(${p.regex.source})`).join("|"), "g");
864
908
  var HIGH_ENTROPY_REGEX = PATTERNS.find((p) => p.type === "high_entropy_env").regex;
909
+ var JSON_CREDENTIAL_REGEX = PATTERNS.find((p) => p.type === "json_credential_key").regex;
865
910
  var COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);
866
911
  var SCRUB_CHUNK_BYTES = 64 * 1024;
867
912
  var SCRUB_OVERLAP_BYTES = 1024;
@@ -872,20 +917,7 @@ var PATTERN_ANCHORS = [
872
917
  )
873
918
  )
874
919
  ];
875
- var JSON_KEY_ANCHORS = [
876
- '"apiKey"',
877
- '"api_key"',
878
- '"token"',
879
- '"secret"',
880
- '"password"',
881
- '"authorization"',
882
- '"bearer"',
883
- '"private_key"',
884
- '"access_token"',
885
- '"refresh_token"',
886
- '"client_secret"'
887
- ];
888
- var ALL_ANCHORS = [...PATTERN_ANCHORS, ...JSON_KEY_ANCHORS];
920
+ var ALL_ANCHORS = PATTERN_ANCHORS;
889
921
  function hasCredentialAnchors(text) {
890
922
  for (const anchor of ALL_ANCHORS) {
891
923
  if (text.includes(anchor)) return true;
@@ -934,6 +966,9 @@ var DefaultSecretScrubber = class {
934
966
  out = out.replace(HIGH_ENTROPY_REGEX, (_match, lead, key, _value) => {
935
967
  return `${lead}${key}=[REDACTED:high_entropy_env]`;
936
968
  });
969
+ out = out.replace(JSON_CREDENTIAL_REGEX, (_match, keyPrefix, _value, closingQuote) => {
970
+ return `${keyPrefix}[REDACTED:json_credential_key]${closingQuote}`;
971
+ });
937
972
  return out;
938
973
  }
939
974
  /**
@@ -3019,6 +3054,8 @@ var VALID_AGENT_STATUS = /* @__PURE__ */ new Set([
3019
3054
  ]);
3020
3055
  var MAX_TRANSCRIPT_BATCH_ENTRIES = 32;
3021
3056
  var MAX_TRANSCRIPT_BATCH_BYTES = 512 * 1024;
3057
+ var HQ_STALE_SNAPSHOT_WINDOW_MS = 5 * 6e4;
3058
+ var KEEPALIVE_REPUBLISH_MS = Math.floor(HQ_STALE_SNAPSHOT_WINDOW_MS * 0.8);
3022
3059
  function toAgentSummary(a) {
3023
3060
  const status = VALID_AGENT_STATUS.has(a.status) ? a.status : "idle";
3024
3061
  return {
@@ -3060,6 +3097,7 @@ function startSessionTelemetryBridge(opts) {
3060
3097
  startedAt
3061
3098
  );
3062
3099
  let lastSnapshotHash = "";
3100
+ let lastPublishedAtMs = Date.now();
3063
3101
  let disposed = false;
3064
3102
  function buildSnapshot() {
3065
3103
  return {
@@ -3087,6 +3125,7 @@ function startSessionTelemetryBridge(opts) {
3087
3125
  lastSnapshotHash = hash;
3088
3126
  try {
3089
3127
  publisher.publishSessionSnapshot(snap);
3128
+ lastPublishedAtMs = Date.now();
3090
3129
  } catch {
3091
3130
  }
3092
3131
  }
@@ -3149,7 +3188,9 @@ function startSessionTelemetryBridge(opts) {
3149
3188
  let seqEmitted = 0;
3150
3189
  let watcher = null;
3151
3190
  let tailTimer = null;
3152
- const snapshotTimer = setInterval(() => publishSnapshot(true), opts.snapshotIntervalMs ?? 2500);
3191
+ const snapshotTimer = setInterval(() => {
3192
+ publishSnapshot(Date.now() - lastPublishedAtMs >= KEEPALIVE_REPUBLISH_MS);
3193
+ }, opts.snapshotIntervalMs ?? 2500);
3153
3194
  snapshotTimer.unref?.();
3154
3195
  if (!opts.writer?.setOnAppend) {
3155
3196
  let setupWatcher2 = function() {
package/dist/index.d.ts CHANGED
@@ -48,7 +48,7 @@ export { Context, type ContextInit, type ProviderMemoryEvidence, type RunOptions
48
48
  export { type ContinuationInput, type ContinuationSource, detectContinueIntent, type ResolvedContinuation, resolveContinuation, } from './core/continue-intent.js';
49
49
  export { type ContinueDirective, makeContinueToNextIterationTool, parseContinueDirective, } from './core/continue-to-next-iteration.js';
50
50
  export { ConversationState, type ReadonlyConversationState, type StateChange, type StateChangeHandler, wrapAsState, } from './core/conversation-state.js';
51
- export { createFallbackModelExtension, effectiveFallbackChain, type FallbackModelDeps, fallbackProfileChain, formatModelRef, normalizeModelRef, parseModelRef, smartDefaultFallbackChain, } from './core/fallback-model.js';
51
+ export { createFallbackModelExtension, effectiveFallbackChain, type FallbackModelDeps, fallbackProfileChain, formatModelRef, normalizeModelRef, parseModelRef, runtimeFallbackChain, smartDefaultFallbackChain, } from './core/fallback-model.js';
52
52
  export type { FallbackChain, FallbackChainEntry, ProviderHealth, } from './core/fallback-profile-manager.js';
53
53
  export { FallbackProfileManager } from './core/fallback-profile-manager.js';
54
54
  export { InputBuilder, type InputBuilderEvent, type InputBuilderOptions, } from './core/input-builder.js';
@@ -151,4 +151,5 @@ export { readBundledInstructionText, renderInstructionTemplate, } from './utils/
151
151
  export { safeParse, safeStringify, sanitizeJsonString, stripCodeFences, } from './utils/safe-json.js';
152
152
  export { getTermSize, isInteractive, isStdinTTY, isStdoutTTY, type OutputLineGuard, onResize, setOutputLineGuard, setRawMode, writeErr, writeOut, } from './utils/term.js';
153
153
  export { type AllocateOpts, assertSafePath, type MergeOpts, type MergeResult, type WorktreeHandle, WorktreeManager, type WorktreeManagerOptions, type WorktreeRunResult, type WorktreeStatus, } from './worktree/index.js';
154
+ export { ensureGitignore, getPromptJournalEntries, recordPromptJournalEntry, type PromptCategory, type PromptJournalEntry, type PromptJournalFilter, type RecordPromptOptions, } from './prompts/index.js';
154
155
  //# sourceMappingURL=index.d.ts.map