@wrongstack/core 0.89.3 → 0.107.2

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 (51) hide show
  1. package/dist/{agent-bridge-DbVe1dHT.d.ts → agent-bridge-mOxbpFcg.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-C6eqID1t.d.ts → agent-subagent-runner-DukQLUcS.d.ts} +5 -5
  3. package/dist/{brain-s9DyD_Vf.d.ts → brain-Dfv4Y82E.d.ts} +1 -1
  4. package/dist/{config-84VaZpH6.d.ts → config-BSU-6vah.d.ts} +1 -1
  5. package/dist/coordination/index.d.ts +9 -9
  6. package/dist/coordination/index.js +103 -0
  7. package/dist/coordination/index.js.map +1 -1
  8. package/dist/defaults/index.d.ts +18 -17
  9. package/dist/defaults/index.js +276 -12
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/execution/index.d.ts +61 -365
  12. package/dist/execution/index.js +423 -8
  13. package/dist/execution/index.js.map +1 -1
  14. package/dist/extension/index.d.ts +4 -4
  15. package/dist/goal-preamble-CI8lxeY1.d.ts +378 -0
  16. package/dist/{goal-store-DvWLNu52.d.ts → goal-store-ht0VmR1A.d.ts} +63 -21
  17. package/dist/{index-CqrroYcU.d.ts → index-BWRN6wOb.d.ts} +5 -5
  18. package/dist/{index-D3Nax3YU.d.ts → index-DIKEcfgC.d.ts} +3 -3
  19. package/dist/index.d.ts +31 -29
  20. package/dist/index.js +530 -53
  21. package/dist/index.js.map +1 -1
  22. package/dist/infrastructure/index.d.ts +4 -4
  23. package/dist/kernel/index.d.ts +6 -6
  24. package/dist/{mcp-servers-D3E5ixAR.d.ts → mcp-servers-CXCsANdY.d.ts} +1 -1
  25. package/dist/{multi-agent-coordinator-DHNrjPaA.d.ts → multi-agent-coordinator-51LvnXkD.d.ts} +1 -1
  26. package/dist/{null-fleet-bus-BzzciAc4.d.ts → null-fleet-bus-D09hMzFQ.d.ts} +5 -5
  27. package/dist/observability/index.d.ts +1 -1
  28. package/dist/{parallel-eternal-engine-CTpcrb9O.d.ts → parallel-eternal-engine-CUtmM_0V.d.ts} +24 -5
  29. package/dist/{path-resolver-B7hgMAVe.d.ts → path-resolver-DDJiMAtX.d.ts} +1 -1
  30. package/dist/{pipeline-C1Ad9OjI.d.ts → pipeline-BqiA_UMr.d.ts} +2 -2
  31. package/dist/{plan-templates-CNphsz0n.d.ts → plan-templates-BdDxl9cI.d.ts} +2 -2
  32. package/dist/{provider-runner-cqvlB_oS.d.ts → provider-runner-BUunikwY.d.ts} +1 -1
  33. package/dist/sdd/index.d.ts +11 -6
  34. package/dist/sdd/index.js +124 -5
  35. package/dist/sdd/index.js.map +1 -1
  36. package/dist/{session-event-bridge-IVzs2GpE.d.ts → session-event-bridge-BpJ5trO9.d.ts} +1 -1
  37. package/dist/{skill-BJxzIyyN.d.ts → skill-Bj6Ezqb8.d.ts} +1 -1
  38. package/dist/skills/index.d.ts +1 -1
  39. package/dist/spec-TBi3Jr6T.d.ts +78 -0
  40. package/dist/storage/index.d.ts +21 -9
  41. package/dist/storage/index.js +157 -14
  42. package/dist/storage/index.js.map +1 -1
  43. package/dist/task-format-vGOIftmK.d.ts +23 -0
  44. package/dist/task-graph-u1q9Jkyk.d.ts +84 -0
  45. package/dist/types/index.d.ts +15 -14
  46. package/dist/utils/index.d.ts +3 -1
  47. package/dist/utils/index.js +110 -1
  48. package/dist/utils/index.js.map +1 -1
  49. package/package.json +1 -1
  50. package/skills/tech-stack/SKILL.md +177 -0
  51. package/dist/task-graph-DJBqO0EY.d.ts +0 -161
@@ -2173,12 +2173,225 @@ function appendJournal(goal, entry) {
2173
2173
  journal: trimmed
2174
2174
  };
2175
2175
  }
2176
+ function parseProgressFromText(text) {
2177
+ const re = /\[progress:\s*(\d{1,3})%\]\s*(?:[—\-]\s*(.+))?/i;
2178
+ const m = text.match(re);
2179
+ if (!m) return null;
2180
+ const progress = Math.min(100, Math.max(0, Number.parseInt(m[1], 10)));
2181
+ const note = m[2]?.trim() || void 0;
2182
+ return { progress, note };
2183
+ }
2184
+ function recordProgress(goal, progress, note) {
2185
+ const clamped = Math.min(100, Math.max(0, progress));
2186
+ const history = [...goal.progressHistory ?? [], { at: (/* @__PURE__ */ new Date()).toISOString(), progress: clamped, note }];
2187
+ const trimmed = history.length > 200 ? history.slice(-200) : history;
2188
+ return {
2189
+ ...goal,
2190
+ progress: clamped,
2191
+ progressNote: note ?? `${clamped}% complete`,
2192
+ progressHistory: trimmed,
2193
+ progressTrend: computeTrend(trimmed)
2194
+ };
2195
+ }
2196
+ function computeTrend(history) {
2197
+ if (history.length < 3) return void 0;
2198
+ const recent = history.slice(-5);
2199
+ const deltas = [];
2200
+ for (let i = 1; i < recent.length; i++) {
2201
+ deltas.push(recent[i].progress - recent[i - 1].progress);
2202
+ }
2203
+ if (deltas.length < 2) return void 0;
2204
+ const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;
2205
+ if (avgDelta > 2) return "accelerating";
2206
+ if (avgDelta < -1) return "stalling";
2207
+ return "steady";
2208
+ }
2176
2209
 
2177
2210
  // src/utils/sleep.ts
2178
2211
  function sleep(ms) {
2179
2212
  return new Promise((resolve2) => setTimeout(resolve2, ms));
2180
2213
  }
2181
2214
 
2215
+ // src/execution/autonomy-brain.ts
2216
+ var RISK_LEVELS = {
2217
+ low: 0,
2218
+ medium: 1,
2219
+ high: 2,
2220
+ critical: 3
2221
+ };
2222
+ function createAutonomyBrain(opts) {
2223
+ const maxRisk = opts.maxAutoRisk ?? "high";
2224
+ const maxRiskLevel = RISK_LEVELS[maxRisk] ?? 2;
2225
+ const timeoutMs = opts.decisionTimeoutMs ?? 15e3;
2226
+ return {
2227
+ async decide(request) {
2228
+ const requestLevel = RISK_LEVELS[request.risk] ?? 2;
2229
+ if (requestLevel > maxRiskLevel) {
2230
+ const reason = `Auto-denied: risk "${request.risk}" exceeds max "${maxRisk}"`;
2231
+ const decision = { type: "deny", reason };
2232
+ opts.onDecision?.(
2233
+ `\u{1F9E0} Brain: DENIED \u2014 ${request.question.slice(0, 80)} (risk: ${request.risk} > ${maxRisk})`,
2234
+ decision,
2235
+ request
2236
+ );
2237
+ return decision;
2238
+ }
2239
+ const heuristic = quickDecide(request);
2240
+ if (heuristic) {
2241
+ opts.onDecision?.(formatDecisionSummary(heuristic, request), heuristic, request);
2242
+ return heuristic;
2243
+ }
2244
+ const llmDecision = await llmDecide(request, opts.provider, opts.model, timeoutMs);
2245
+ opts.onDecision?.(formatDecisionSummary(llmDecision, request), llmDecision, request);
2246
+ return llmDecision;
2247
+ }
2248
+ };
2249
+ }
2250
+ function formatDecisionSummary(decision, request) {
2251
+ const question = request.question.length > 80 ? request.question.slice(0, 77) + "\u2026" : request.question;
2252
+ if (decision.type === "deny") {
2253
+ return `\u{1F9E0} Brain: DENIED \u2014 "${question}" \u2192 ${decision.reason}`;
2254
+ }
2255
+ if (decision.type === "answer") {
2256
+ const action = decision.optionId ? `chose [${decision.optionId}]` : decision.text.length > 60 ? decision.text.slice(0, 57) + "\u2026" : decision.text;
2257
+ return `\u{1F9E0} Brain: DECIDED \u2014 "${question}" \u2192 ${action}`;
2258
+ }
2259
+ return `\u{1F9E0} Brain: ASKED HUMAN \u2014 "${question}"`;
2260
+ }
2261
+ function quickDecide(request) {
2262
+ const q = request.question.toLowerCase();
2263
+ const ctx = request.context?.toLowerCase() ?? "";
2264
+ if (q.includes("deadlock") && ctx.includes("failed")) {
2265
+ return {
2266
+ type: "answer",
2267
+ text: "Skip deadlocked tasks and continue with remaining work. Failed tasks will be reported in the final summary.",
2268
+ rationale: "Heuristic: deadlocked tasks blocked by failed dependencies \u2014 skipping unblocks remaining work."
2269
+ };
2270
+ }
2271
+ if ((q.includes("failed") || q.includes("retry")) && (ctx.includes("3") || ctx.includes("exhausted"))) {
2272
+ return {
2273
+ type: "answer",
2274
+ text: "Mark as failed and move on. Note the failure for the final report.",
2275
+ rationale: "Heuristic: retries exhausted \u2014 continuing would waste resources."
2276
+ };
2277
+ }
2278
+ if (q.includes("goal complete") || q.includes("mission complete")) {
2279
+ return null;
2280
+ }
2281
+ if (q.includes("continue") || q.includes("proceed")) {
2282
+ return {
2283
+ type: "answer",
2284
+ text: "Continue execution. Do not stop.",
2285
+ rationale: "Heuristic: autonomy mode \u2014 continue until all work is complete."
2286
+ };
2287
+ }
2288
+ return null;
2289
+ }
2290
+ async function llmDecide(request, provider, model, timeoutMs) {
2291
+ const optionsText = request.options?.length ? "\nOptions:\n" + request.options.map(
2292
+ (o) => ` [${o.id}] ${o.label}${o.consequence ? ` \u2014 ${o.consequence}` : ""}${o.recommended ? " \u2605 recommended" : ""}`
2293
+ ).join("\n") : "";
2294
+ const systemPrompt = [
2295
+ "IDENTITY:",
2296
+ "You are the Autonomy Brain \u2014 a dedicated decision engine inside an",
2297
+ "autonomous AI coding agent called WrongStack. Your SOLE purpose is to",
2298
+ "evaluate situations where the autonomous workflow is blocked, stuck, or",
2299
+ "uncertain, and decide the best course of action to keep the system",
2300
+ "running and making progress toward its goal.",
2301
+ "",
2302
+ "WHAT YOU DO:",
2303
+ "- You receive a question + context from an autonomy subsystem (goal",
2304
+ " engine, phase orchestrator, task decomposer).",
2305
+ "- You evaluate whether the system should continue, pivot, retry, skip,",
2306
+ " or stop.",
2307
+ "- You output exactly ONE decision. No preamble, no markdown, no",
2308
+ " elaboration beyond what is needed to justify the decision.",
2309
+ "",
2310
+ "HOW YOU DECIDE:",
2311
+ '1. PREFER CONTINUATION. The default answer is always "continue" unless',
2312
+ " there is clear evidence that stopping is safer or more productive.",
2313
+ "2. BE SPECIFIC. If options are provided, pick one by its [id]. If not,",
2314
+ " describe the exact action in 1-2 sentences.",
2315
+ "3. VERIFY COMPLETION. If the question is about whether the goal is done,",
2316
+ " check deliverables and progress before saying yes. A progress bar at",
2317
+ " 80% with open deliverables means NOT done.",
2318
+ "4. AVOID WASTE. If a task has failed 3+ times with the same approach,",
2319
+ " recommend a different approach or skipping it \u2014 do not recommend",
2320
+ " retrying the same thing.",
2321
+ "5. CONSIDER COST. If the question mentions spent budget or token counts,",
2322
+ " factor that into your decision. A goal that has already spent $50",
2323
+ " with 90% progress is worth finishing; one at 15% with $100 spent",
2324
+ " may need re-evaluation.",
2325
+ "",
2326
+ "OUTPUT FORMAT:",
2327
+ "- With options: output the option [id] and a 1-sentence justification.",
2328
+ ' Example: "[resolve] \u2014 conflict is in test files only, safe to auto-resolve."',
2329
+ "- Without options: output the decision as a 1-2 sentence action.",
2330
+ ' Example: "Continue execution. Progress is steady at 60% with 3/5',
2331
+ ' deliverables done. No reason to stop."',
2332
+ "",
2333
+ "CRITICAL RULE:",
2334
+ "You are NOT the main agent. Do not suggest code changes, tool calls,",
2335
+ "or implementation details. Your output is a DECISION, not a plan."
2336
+ ].join("\n");
2337
+ const userMessage = [
2338
+ `Question: ${request.question}`,
2339
+ request.context ? `
2340
+ Context:
2341
+ ${request.context}` : "",
2342
+ optionsText
2343
+ ].filter(Boolean).join("\n");
2344
+ try {
2345
+ const signal = AbortSignal.timeout(timeoutMs);
2346
+ const response = await provider.complete(
2347
+ {
2348
+ model,
2349
+ system: [{ type: "text", text: systemPrompt }],
2350
+ messages: [{ role: "user", content: userMessage || "Decide." }],
2351
+ maxTokens: 200
2352
+ },
2353
+ { signal }
2354
+ );
2355
+ const text = extractText(response).trim();
2356
+ if (request.options?.length) {
2357
+ for (const opt of request.options) {
2358
+ if (text.toLowerCase().includes(opt.id.toLowerCase())) {
2359
+ return {
2360
+ type: "answer",
2361
+ optionId: opt.id,
2362
+ text: opt.label,
2363
+ rationale: text
2364
+ };
2365
+ }
2366
+ }
2367
+ }
2368
+ return {
2369
+ type: "answer",
2370
+ text: text || (request.fallback === "continue" ? "Continue execution." : "Denied by autonomy policy."),
2371
+ rationale: text || void 0
2372
+ };
2373
+ } catch {
2374
+ if (request.fallback === "continue") {
2375
+ return {
2376
+ type: "answer",
2377
+ text: "Continue (Autonomy Brain LLM unavailable \u2014 using fallback)."
2378
+ };
2379
+ }
2380
+ return { type: "deny", reason: "Autonomy Brain LLM unavailable for decision." };
2381
+ }
2382
+ }
2383
+ function extractText(result) {
2384
+ if (!result || typeof result !== "object") return "";
2385
+ const r = result;
2386
+ if (Array.isArray(r.content)) {
2387
+ return r.content.filter((b) => b.type === "text").map((b) => b.text ?? "").join("");
2388
+ }
2389
+ if (Array.isArray(r.choices)) {
2390
+ return r.choices[0]?.message?.content ?? "";
2391
+ }
2392
+ return typeof r.text === "string" ? r.text : "";
2393
+ }
2394
+
2182
2395
  // src/execution/eternal-autonomy.ts
2183
2396
  var execFileP = promisify(execFile);
2184
2397
  var BRAINSTORM_DONE = /* @__PURE__ */ Symbol("brainstorm-done");
@@ -2248,7 +2461,7 @@ var EternalAutonomyEngine = class {
2248
2461
  this.consecutiveFailures = 0;
2249
2462
  }
2250
2463
  if (this.stopRequested) break;
2251
- await sleep(this.opts.cycleGapMs ?? 1e3);
2464
+ await sleep(this.opts.cycleGapMs ?? 0);
2252
2465
  }
2253
2466
  } finally {
2254
2467
  this.state = "stopped";
@@ -2418,6 +2631,18 @@ var EternalAutonomyEngine = class {
2418
2631
  this.stopRequested = true;
2419
2632
  return true;
2420
2633
  }
2634
+ const parsed = parseProgressFromText(finalText);
2635
+ if (parsed) {
2636
+ await this.updateProgress(parsed.progress, parsed.note);
2637
+ if (parsed.progress >= 100) {
2638
+ await this.markGoalCompleted(
2639
+ { source: action.source, task: action.task, directive: action.directive },
2640
+ `progress reached 100%: ${parsed.note ?? "goal complete"}`
2641
+ );
2642
+ this.stopRequested = true;
2643
+ return true;
2644
+ }
2645
+ }
2421
2646
  this.iterationsSinceCompact++;
2422
2647
  await this.maybeCompact().catch((err) => {
2423
2648
  this.opts.onError?.(
@@ -2504,11 +2729,16 @@ var EternalAutonomyEngine = class {
2504
2729
  this.consecutiveBrainstormDone++;
2505
2730
  const threshold = this.opts.brainstormDoneStopThreshold ?? 3;
2506
2731
  if (this.consecutiveBrainstormDone >= threshold) {
2507
- await this.markGoalCompleted(
2508
- { source: "brainstorm", task: "no further work", directive: "" },
2509
- `brainstorm returned DONE ${this.consecutiveBrainstormDone}x in a row`
2510
- );
2511
- this.stopRequested = true;
2732
+ const shouldStop = await this.consultBrainForDone(goal);
2733
+ if (shouldStop) {
2734
+ await this.markGoalCompleted(
2735
+ { source: "brainstorm", task: "no further work", directive: "" },
2736
+ `brainstorm returned DONE ${this.consecutiveBrainstormDone}x in a row${this.opts.brain ? ", brain confirmed" : ""}`
2737
+ );
2738
+ this.stopRequested = true;
2739
+ } else {
2740
+ this.consecutiveBrainstormDone = 0;
2741
+ }
2512
2742
  }
2513
2743
  return null;
2514
2744
  }
@@ -2742,6 +2972,69 @@ ${recentJournal}` : "No prior iterations.",
2742
2972
  async appendFailure(task, note) {
2743
2973
  await this.appendIterationEntry({ source: "manual", task, status: "failure", note });
2744
2974
  }
2975
+ /**
2976
+ * Consult the brain on whether the goal is truly complete.
2977
+ * Without a brain, always returns true (use heuristic: DONE threshold met = done).
2978
+ */
2979
+ async consultBrainForDone(goal) {
2980
+ if (!this.opts.brain) return true;
2981
+ const deliverablesStatus = goal.deliverables?.length ? `
2982
+ Deliverables: ${goal.deliverables.length} total, progress ${goal.progress ?? "unknown"}%` : "";
2983
+ const recentJournal = goal.journal.slice(-5).map(
2984
+ (e) => ` #${e.iteration} [${e.status}] ${e.task}`
2985
+ ).join("\n");
2986
+ try {
2987
+ const decision = await this.opts.brain.decide({
2988
+ id: `goal-done-${goal.iterations}`,
2989
+ source: "system",
2990
+ question: `Brainstorm returned DONE ${this.consecutiveBrainstormDone}x. Is the goal truly complete?`,
2991
+ context: [
2992
+ `Goal: ${goal.goal}`,
2993
+ `Iterations: ${goal.iterations}`,
2994
+ `Progress: ${goal.progress ?? "unknown"}%`,
2995
+ deliverablesStatus,
2996
+ recentJournal ? `
2997
+ Recent work:
2998
+ ${recentJournal}` : ""
2999
+ ].join("\n"),
3000
+ risk: "high",
3001
+ fallback: "continue"
3002
+ });
3003
+ const summary = formatDecisionSummary(decision, {
3004
+ id: `goal-done-${goal.iterations}`,
3005
+ source: "system",
3006
+ question: "Is the goal complete?",
3007
+ risk: "high",
3008
+ fallback: "continue"
3009
+ });
3010
+ const rationale = "rationale" in decision ? decision.rationale : void 0;
3011
+ await this.appendIterationEntry({
3012
+ source: "brainstorm",
3013
+ task: summary,
3014
+ status: "success",
3015
+ note: rationale
3016
+ });
3017
+ if (decision.type === "deny") {
3018
+ return false;
3019
+ }
3020
+ if (decision.type === "answer") {
3021
+ const text = decision.text.toLowerCase();
3022
+ return text.includes("complete") || text.includes("done") || text.includes("yes");
3023
+ }
3024
+ return true;
3025
+ } catch {
3026
+ return true;
3027
+ }
3028
+ }
3029
+ /**
3030
+ * Persist a progress update from the agent's [PROGRESS: N%] output.
3031
+ */
3032
+ async updateProgress(progress, note) {
3033
+ const current = await loadGoal(this.goalPath);
3034
+ if (!current) return;
3035
+ const updated = recordProgress(current, progress, note);
3036
+ await saveGoal(this.goalPath, updated);
3037
+ }
2745
3038
  async persistEngineState(state) {
2746
3039
  const current = await loadGoal(this.goalPath);
2747
3040
  if (!current) return;
@@ -5395,6 +5688,109 @@ Working rules:
5395
5688
  "cloud cost"
5396
5689
  ]
5397
5690
  }
5691
+ },
5692
+ {
5693
+ config: {
5694
+ id: "tech-stack",
5695
+ name: "Tech Stack Validator",
5696
+ role: "tech-stack",
5697
+ tools: ["search", "fetch", "read", "grep", "glob", "outdated", "audit", "json"],
5698
+ prompt: `You are the Tech Stack Validator \u2014 a single-shot validation agent that fires
5699
+ before any package, library, or framework choice is committed.
5700
+
5701
+ Your ONLY job: verify that a technology choice is current, real, and not obsolete.
5702
+ You are the "this isn't code, this is 10-year-old technology" agent. Intervene
5703
+ hard when the LLM hallucinates a version number or suggests dead tech.
5704
+
5705
+ ## Critical rules
5706
+
5707
+ 1. **Verify existence.** Search npm registry (fetch https://registry.npmjs.org/<pkg>/latest)
5708
+ or web search. A package that doesn't exist = hallucination.
5709
+
5710
+ 2. **Check latest version.** Never trust any version number from the model. Always
5711
+ fetch the actual latest stable version from npm or the project's release page.
5712
+
5713
+ 3. **Reject dead packages.** No release in >2 years + unresolved critical issues =
5714
+ dead. Suggest a maintained replacement.
5715
+
5716
+ 4. **Reject prehistoric tech.** Any package/pattern superseded \u22655 years ago is
5717
+ REJECTED. Key blocklist:
5718
+ - axios / node-fetch / got / request \u2192 native fetch (Node 18+)
5719
+ - moment \u2192 date-fns / luxon / Temporal
5720
+ - jQuery (new projects) \u2192 vanilla DOM / React
5721
+ - Gulp / Grunt \u2192 tsup / esbuild / vite
5722
+ - CoffeeScript / Flow \u2192 TypeScript
5723
+ - Bluebird \u2192 native Promises
5724
+ - crypto-js \u2192 node:crypto / Web Crypto
5725
+ - Bower \u2192 npm/pnpm
5726
+ - underscore \u2192 lodash or native ES2020+
5727
+
5728
+ 5. **The intervention phrase.** When rejecting on age grounds, you MUST output
5729
+ exactly: "This isn't code, this is X-year-old technology." where X =
5730
+ current year \u2212 the year the technology was made obsolete. Follow with
5731
+ what replaced it and a one-step migration path.
5732
+
5733
+ 6. **Prefer built-in over third-party.** Check Node 22+ native APIs first:
5734
+ node:test, node:sqlite, fetch, WebSocket, Web Crypto \u2014 all built-in.
5735
+
5736
+ ## Workflow (single-shot \u2014 do NOT loop)
5737
+
5738
+ 1. Receive the proposed package + version
5739
+ 2. Search npm registry or web for the latest version
5740
+ 3. Check age, maintenance status, deprecation
5741
+ 4. Output verdict: APPROVED (with exact version) or REJECTED (with replacement)
5742
+
5743
+ ## Output format
5744
+
5745
+ ### Tech Stack Validation \u2014 <package>
5746
+
5747
+ **Status**: APPROVED | REJECTED
5748
+
5749
+ **Package**: <name>@<version>
5750
+ **Source**: <URL you checked \u2014 npm registry, GitHub, web search>
5751
+ **Age**: <first release> \u2014 <last release date>
5752
+ **Verdict**: 1\u20132 sentence explanation.
5753
+
5754
+ When REJECTED on age:
5755
+ **"This isn't code, this is X-year-old technology."**
5756
+ **Replaced by**: <modern alternative>
5757
+ **Migration**: <one concrete step>
5758
+
5759
+ When APPROVED:
5760
+ **Install**: pnpm add <name>@^<major>.<minor>.0`
5761
+ },
5762
+ budget: {
5763
+ timeoutMs: 6e4,
5764
+ maxIterations: 5,
5765
+ maxToolCalls: 20,
5766
+ maxTokens: 4e4,
5767
+ maxCostUsd: 0.1
5768
+ },
5769
+ capability: {
5770
+ phase: "meta",
5771
+ summary: "Single-shot tech stack validator: checks npm for latest versions, rejects dead/obsolete packages, enforces modern alternatives.",
5772
+ keywords: [
5773
+ "tech stack",
5774
+ "version",
5775
+ "package",
5776
+ "library",
5777
+ "framework",
5778
+ "dependency",
5779
+ "install",
5780
+ "upgrade",
5781
+ "latest",
5782
+ "npm",
5783
+ "pnpm add",
5784
+ "outdated",
5785
+ "obsolete",
5786
+ "deprecated",
5787
+ "what version",
5788
+ "which package",
5789
+ "check version",
5790
+ "verify version",
5791
+ "is this current"
5792
+ ]
5793
+ }
5398
5794
  }
5399
5795
  ];
5400
5796
 
@@ -7001,7 +7397,17 @@ ${journalTail.join("\n")}` : "Recent journal: (none \u2014 this is the first ite
7001
7397
  }
7002
7398
 
7003
7399
  // src/execution/goal-preamble.ts
7004
- function buildGoalPreamble(goal) {
7400
+ function buildGoalPreamble(goal, deliverables) {
7401
+ const deliverableBlock = deliverables && deliverables.length > 0 ? [
7402
+ "",
7403
+ "CONCRETE DELIVERABLES (check these off as you go):",
7404
+ ...deliverables.map((d, i) => ` ${i + 1}. ${d}`),
7405
+ "",
7406
+ "After EACH iteration, estimate your completion percentage (0\u2013100)",
7407
+ "against this deliverable list. Output it as:",
7408
+ " [PROGRESS: N%] \u2014 <1-sentence status>",
7409
+ "The eternal engine reads this to update the progress bar."
7410
+ ].join("\n") : "";
7005
7411
  return [
7006
7412
  "[GOAL \u2014 LOCKED IN. You will work on this until it is verifiably done.",
7007
7413
  "The user granted you full autonomy. Read these constraints once, then act.",
@@ -7010,6 +7416,7 @@ function buildGoalPreamble(goal) {
7010
7416
  "---",
7011
7417
  goal,
7012
7418
  "---",
7419
+ deliverableBlock,
7013
7420
  "",
7014
7421
  "AUTHORITY YOU HAVE:",
7015
7422
  "- Spawn as many subagents as the work needs (delegate / spawn_subagent).",
@@ -7031,6 +7438,7 @@ function buildGoalPreamble(goal) {
7031
7438
  "- You can tell the user HOW to verify it themselves in 10 seconds.",
7032
7439
  '- You have NOT hedged. None of: "looks like it should work", "I',
7033
7440
  ' believe this fixes it", "the changes appear correct".',
7441
+ `- Progress bar shows 100%. All deliverables checked off.`,
7034
7442
  "",
7035
7443
  "WHAT IS NOT DONE \u2014 never report any of these as completion:",
7036
7444
  "- An error message you didn't recover from.",
@@ -7045,6 +7453,13 @@ function buildGoalPreamble(goal) {
7045
7453
  " respond to with a fresh attempt (different role, different model,",
7046
7454
  " tighter prompt).",
7047
7455
  "",
7456
+ "PROGRESS REPORTING \u2014 MANDATORY every iteration:",
7457
+ "- End every response with exactly: [PROGRESS: N%] \u2014 <status note>",
7458
+ " where N is your honest estimate (0-100) of how much of the goal",
7459
+ " is done. The engine tracks this and shows a live progress bar.",
7460
+ "- Example: [PROGRESS: 45%] \u2014 Auth module refactored, 3/5 tests pass,",
7461
+ " remaining: test coverage + docs update.",
7462
+ "",
7048
7463
  "PERSISTENCE PROTOCOL:",
7049
7464
  "- If blocked, try at least 3 different angles before reporting the",
7050
7465
  " problem to the user. Different tool inputs, different subagent",
@@ -7320,6 +7735,6 @@ function parseDescription(raw) {
7320
7735
  return { trigger, scope };
7321
7736
  }
7322
7737
 
7323
- export { AutoCompactionMiddleware, AutonomousRunner, DefaultErrorHandler, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, ParallelEternalEngine, SelectiveCompactor, ToolExecutor, buildGoalPreamble, makeAutonomyPromptContributor };
7738
+ export { AutoCompactionMiddleware, AutonomousRunner, DefaultErrorHandler, DefaultRetryPolicy, DefaultSkillLoader, DoneConditionChecker, EternalAutonomyEngine, HybridCompactor, IntelligentCompactor, ParallelEternalEngine, SelectiveCompactor, ToolExecutor, buildGoalPreamble, createAutonomyBrain, formatDecisionSummary, makeAutonomyPromptContributor };
7324
7739
  //# sourceMappingURL=index.js.map
7325
7740
  //# sourceMappingURL=index.js.map