@wrongstack/core 0.306.4 → 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 (103) 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 +6011 -5894
  14. package/dist/coordination/mail-tools.d.ts +1 -1
  15. package/dist/coordination/mailbox-http-actor-query.d.ts +16 -0
  16. package/dist/coordination/mailbox-http-router.d.ts +0 -48
  17. package/dist/coordination/mailbox-http-sse.d.ts +12 -0
  18. package/dist/coordination/mailbox-message-types.d.ts +71 -0
  19. package/dist/coordination/mailbox-predicates.d.ts +13 -0
  20. package/dist/coordination/mailbox-project-server.js +1 -1
  21. package/dist/coordination/mailbox-session-sync.d.ts +8 -0
  22. package/dist/coordination/mailbox-types.d.ts +6 -793
  23. package/dist/core/agent-loop-context.d.ts +28 -0
  24. package/dist/core/agent-loop-detector.d.ts +25 -0
  25. package/dist/core/fallback-doctor.d.ts +72 -0
  26. package/dist/core/index.d.ts +1 -0
  27. package/dist/core/index.js +1159 -888
  28. package/dist/defaults/index.js +3579 -3545
  29. package/dist/execution/autonomy-brain-llm.d.ts +55 -0
  30. package/dist/execution/autonomy-brain.d.ts +3 -156
  31. package/dist/execution/compaction-budget.d.ts +38 -0
  32. package/dist/execution/compaction-core.d.ts +3 -170
  33. package/dist/execution/compaction-elision.d.ts +58 -0
  34. package/dist/execution/council-orchestrator-helpers.d.ts +39 -0
  35. package/dist/execution/council-orchestrator.d.ts +3 -42
  36. package/dist/execution/council-response-parser.d.ts +56 -0
  37. package/dist/execution/index.js +2415 -2443
  38. package/dist/execution/prompt-enhancer.js +11 -3
  39. package/dist/execution/tool-executor-guard.d.ts +18 -0
  40. package/dist/execution/tool-executor-runner.d.ts +12 -0
  41. package/dist/execution/tool-executor.d.ts +0 -75
  42. package/dist/goal/index.js +19 -6
  43. package/dist/hq/index.js +8 -2
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +7813 -7292
  46. package/dist/infrastructure/index.js +3 -1
  47. package/dist/kernel/events/agent-events.d.ts +2 -0
  48. package/dist/kernel/events/provider-events.d.ts +13 -0
  49. package/dist/plugin/index.js +2590 -2561
  50. package/dist/plugins/auto-review-config.d.ts +53 -0
  51. package/dist/plugins/auto-review-git.d.ts +19 -0
  52. package/dist/plugins/auto-review-plugin.d.ts +2 -140
  53. package/dist/plugins/review-finding-verification.d.ts +7 -0
  54. package/dist/prompts/index.d.ts +1 -0
  55. package/dist/prompts/prompt-journal.d.ts +94 -0
  56. package/dist/security/index.js +627 -652
  57. package/dist/security/permission-explain.d.ts +19 -0
  58. package/dist/security/permission-policy.d.ts +0 -101
  59. package/dist/security/yolo-risk.d.ts +5 -4
  60. package/dist/session-catalog/index.js +220 -212
  61. package/dist/session-catalog/project-server.js +227 -219
  62. package/dist/session-catalog/store-rebuild.d.ts +9 -0
  63. package/dist/session-catalog/store-schema.d.ts +48 -0
  64. package/dist/session-catalog/store.d.ts +0 -17
  65. package/dist/storage/director-state.d.ts +6 -0
  66. package/dist/storage/file-session-writer.d.ts +2 -58
  67. package/dist/storage/index.d.ts +2 -1
  68. package/dist/storage/index.js +2057 -1925
  69. package/dist/storage/orphan-lock-cleaner.d.ts +15 -0
  70. package/dist/storage/session-recovery.d.ts +9 -0
  71. package/dist/storage/session-store/rename-session.d.ts +16 -0
  72. package/dist/storage/session-store/resume-session.d.ts +26 -0
  73. package/dist/storage/session-store/session-store-clear.d.ts +11 -0
  74. package/dist/storage/session-store/session-store-index.d.ts +13 -0
  75. package/dist/storage/session-store.d.ts +1 -129
  76. package/dist/storage/session-summary-tracker.d.ts +39 -0
  77. package/dist/storage/session-write-buffer.d.ts +43 -0
  78. package/dist/storage/session-writer/session-writer-flush.d.ts +4 -0
  79. package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +28 -0
  80. package/dist/tools/fallback-agent-model-assign-tool.d.ts +18 -0
  81. package/dist/tools/fallback-leader-model-set-tool.d.ts +18 -0
  82. package/dist/tools/fallback-manage-tools.d.ts +8 -45
  83. package/dist/tools/fallback-profile-manage-tool.d.ts +16 -0
  84. package/dist/tools/fallback-provider-key-set-tool.d.ts +17 -0
  85. package/dist/tools/fallback-provider-manage-tool.d.ts +26 -0
  86. package/dist/tools/index.js +5070 -5071
  87. package/dist/types/config/root.d.ts +7 -2
  88. package/dist/types/default-config.d.ts +1 -1
  89. package/dist/types/index.d.ts +54 -55
  90. package/dist/types/index.js +953 -932
  91. package/dist/types/runtime-capability-manifest.d.ts +5 -5
  92. package/dist/types/session-markers.d.ts +12 -0
  93. package/dist/types/session-markers.js +19 -0
  94. package/dist/worktree/worktree-manager.d.ts +1 -1
  95. package/instructions/coordination/subagent-baseline.md +2 -2
  96. package/instructions/llm/prompt-enhancer.md +2 -1
  97. package/instructions/sections/tool/common-patterns.md +21 -0
  98. package/instructions/sections/tool/delegation-compact.md +3 -1
  99. package/instructions/sections/tool/delegation-full.md +5 -1
  100. package/instructions/system-lite.md +28 -3
  101. package/instructions/system-pro.md +37 -8
  102. package/instructions/system.md +4 -2
  103. 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;
@@ -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,7 +671,7 @@ 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
@@ -3054,6 +3054,8 @@ var VALID_AGENT_STATUS = /* @__PURE__ */ new Set([
3054
3054
  ]);
3055
3055
  var MAX_TRANSCRIPT_BATCH_ENTRIES = 32;
3056
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);
3057
3059
  function toAgentSummary(a) {
3058
3060
  const status = VALID_AGENT_STATUS.has(a.status) ? a.status : "idle";
3059
3061
  return {
@@ -3095,6 +3097,7 @@ function startSessionTelemetryBridge(opts) {
3095
3097
  startedAt
3096
3098
  );
3097
3099
  let lastSnapshotHash = "";
3100
+ let lastPublishedAtMs = Date.now();
3098
3101
  let disposed = false;
3099
3102
  function buildSnapshot() {
3100
3103
  return {
@@ -3122,6 +3125,7 @@ function startSessionTelemetryBridge(opts) {
3122
3125
  lastSnapshotHash = hash;
3123
3126
  try {
3124
3127
  publisher.publishSessionSnapshot(snap);
3128
+ lastPublishedAtMs = Date.now();
3125
3129
  } catch {
3126
3130
  }
3127
3131
  }
@@ -3184,7 +3188,9 @@ function startSessionTelemetryBridge(opts) {
3184
3188
  let seqEmitted = 0;
3185
3189
  let watcher = null;
3186
3190
  let tailTimer = null;
3187
- const snapshotTimer = setInterval(() => publishSnapshot(true), opts.snapshotIntervalMs ?? 2500);
3191
+ const snapshotTimer = setInterval(() => {
3192
+ publishSnapshot(Date.now() - lastPublishedAtMs >= KEEPALIVE_REPUBLISH_MS);
3193
+ }, opts.snapshotIntervalMs ?? 2500);
3188
3194
  snapshotTimer.unref?.();
3189
3195
  if (!opts.writer?.setOnAppend) {
3190
3196
  let setupWatcher2 = function() {
package/dist/index.d.ts CHANGED
@@ -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