@wrongstack/core 0.260.0 → 0.265.1

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 (99) hide show
  1. package/dist/{agent-bridge-BbskZ7HH.d.ts → agent-bridge-DrkBxszZ.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-BNIGZx18.d.ts → agent-subagent-runner-DM2pP-B6.d.ts} +116 -12
  3. package/dist/{brain-C2yDd7Lw.d.ts → brain-BXd_61kQ.d.ts} +32 -3
  4. package/dist/{compactor-t0R_AIt_.d.ts → compactor-B8pOf45Y.d.ts} +1 -1
  5. package/dist/{config-FG6As4H5.d.ts → config-BMCj_XDs.d.ts} +86 -12
  6. package/dist/{context-JFOVvu6z.d.ts → context-MRk5PhNv.d.ts} +26 -1
  7. package/dist/coordination/index.d.ts +1737 -15
  8. package/dist/coordination/index.js +3152 -494
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/{default-config-CXsDvOmP.d.ts → default-config-B0cj-Hry.d.ts} +11 -1
  11. package/dist/defaults/index.d.ts +28 -28
  12. package/dist/defaults/index.js +1804 -1363
  13. package/dist/defaults/index.js.map +1 -1
  14. package/dist/dispatcher-types.d-BBeXBQgS.d.ts +66 -0
  15. package/dist/execution/index.d.ts +16 -16
  16. package/dist/execution/index.js +933 -672
  17. package/dist/execution/index.js.map +1 -1
  18. package/dist/execution/prompt-enhancer.d.ts +1 -1
  19. package/dist/execution/prompt-enhancer.js +7 -1
  20. package/dist/execution/prompt-enhancer.js.map +1 -1
  21. package/dist/extension/index.d.ts +6 -6
  22. package/dist/extension/index.js.map +1 -1
  23. package/dist/{goal-preamble-B1IXJtLX.d.ts → goal-preamble-DvHDSKSe.d.ts} +26 -10
  24. package/dist/{goal-store-CPXz6Mml.d.ts → goal-store-DtLMySNb.d.ts} +1 -1
  25. package/dist/{index-CebbJB94.d.ts → index-B-ch8K9C.d.ts} +8 -8
  26. package/dist/{index-BPcg4N3M.d.ts → index-CEDeNodM.d.ts} +5 -5
  27. package/dist/index.d.ts +189 -104
  28. package/dist/index.js +24693 -21162
  29. package/dist/index.js.map +1 -1
  30. package/dist/infrastructure/index.d.ts +6 -6
  31. package/dist/infrastructure/index.js +12 -8
  32. package/dist/infrastructure/index.js.map +1 -1
  33. package/dist/kernel/index.d.ts +9 -9
  34. package/dist/kernel/index.js +7 -2
  35. package/dist/kernel/index.js.map +1 -1
  36. package/dist/{llm-selector-DXxI2tlu.d.ts → llm-selector-C0tfTCUe.d.ts} +14 -2
  37. package/dist/{mcp-servers-OwNHo43-.d.ts → mcp-servers-2x4w6Jn9.d.ts} +3 -3
  38. package/dist/models/index.d.ts +5 -5
  39. package/dist/models/index.js +80 -31
  40. package/dist/models/index.js.map +1 -1
  41. package/dist/{models-registry-Djlmq4uB.d.ts → models-registry-DmJlKuNp.d.ts} +1 -1
  42. package/dist/{multi-agent-coordinator-CEmrSCMJ.d.ts → multi-agent-coordinator-DyCkCZnU.d.ts} +2 -2
  43. package/dist/{null-fleet-bus-DT92xqgJ.d.ts → null-fleet-bus-CG9QY2aP.d.ts} +6 -6
  44. package/dist/observability/index.d.ts +2 -2
  45. package/dist/observability/index.js +8 -3
  46. package/dist/observability/index.js.map +1 -1
  47. package/dist/{parallel-eternal-engine-0SItuq5r.d.ts → parallel-eternal-engine-Jw9uhEoT.d.ts} +9 -9
  48. package/dist/{path-resolver-DKBh6Jlo.d.ts → path-resolver-Dy2ej-gE.d.ts} +3 -3
  49. package/dist/{permission-BJ7eO9Vl.d.ts → permission-B9SB45lp.d.ts} +1 -1
  50. package/dist/{permission-policy-DEXOfnpm.d.ts → permission-policy-CkjSXabK.d.ts} +2 -2
  51. package/dist/{pipeline-zflkI2dp.d.ts → pipeline-DPDxH_7m.d.ts} +59 -4
  52. package/dist/{plan-templates-BFXyRkEK.d.ts → plan-templates-CzD9GnAU.d.ts} +32 -8
  53. package/dist/{provider-runner-BC-uywtT.d.ts → provider-runner-DMa70ODu.d.ts} +3 -3
  54. package/dist/{retry-policy-Cavrzmtk.d.ts → retry-policy-CN0khdlj.d.ts} +1 -1
  55. package/dist/sdd/index.d.ts +8 -8
  56. package/dist/sdd/index.js +313 -122
  57. package/dist/sdd/index.js.map +1 -1
  58. package/dist/{secret-vault-CDvDYXWX.d.ts → secret-vault-B2yw84VT.d.ts} +43 -4
  59. package/dist/secret-vault-BAKpgFw_.d.ts +57 -0
  60. package/dist/security/index.d.ts +5 -5
  61. package/dist/security/index.js +411 -225
  62. package/dist/security/index.js.map +1 -1
  63. package/dist/{selector-B7AivHsu.d.ts → selector-CzHh_igB.d.ts} +1 -1
  64. package/dist/{session-event-bridge-BmIDxdJd.d.ts → session-event-bridge-BUI6Jf-4.d.ts} +8 -2
  65. package/dist/{session-reader-DtofsB-2.d.ts → session-reader-CMgdMSRP.d.ts} +1 -1
  66. package/dist/skills/index.js +67 -64
  67. package/dist/skills/index.js.map +1 -1
  68. package/dist/storage/index.d.ts +132 -16
  69. package/dist/storage/index.js +851 -432
  70. package/dist/storage/index.js.map +1 -1
  71. package/dist/tools/index.d.ts +57 -0
  72. package/dist/tools/index.js +411 -0
  73. package/dist/tools/index.js.map +1 -0
  74. package/dist/types/index.d.ts +21 -21
  75. package/dist/types/index.js +928 -711
  76. package/dist/types/index.js.map +1 -1
  77. package/dist/utils/error.d.ts +7 -0
  78. package/dist/utils/error.js +8 -0
  79. package/dist/utils/error.js.map +1 -0
  80. package/dist/utils/index.d.ts +8 -68
  81. package/dist/utils/index.js +20 -10
  82. package/dist/utils/index.js.map +1 -1
  83. package/dist/{wstack-paths-CJjEwPXn.d.ts → wstack-paths-hOpNLmvf.d.ts} +2 -0
  84. package/package.json +5 -1
  85. package/skills/api-design/SKILL.md +1 -1
  86. package/skills/audit-log/SKILL.md +6 -6
  87. package/skills/bug-hunter/SKILL.md +5 -5
  88. package/skills/chimera/SKILL.md +4 -4
  89. package/skills/docker-deploy/SKILL.md +1 -1
  90. package/skills/git-flow/SKILL.md +3 -3
  91. package/skills/multi-agent/SKILL.md +3 -3
  92. package/skills/node-modern/SKILL.md +1 -0
  93. package/skills/observability/SKILL.md +2 -2
  94. package/skills/output-standards/SKILL.md +51 -28
  95. package/skills/refactor-planner/SKILL.md +3 -3
  96. package/skills/security-scanner/SKILL.md +4 -3
  97. package/skills/tech-stack/SKILL.md +1 -2
  98. package/dist/package-outdated-watcher-C70ag2G9.d.ts +0 -581
  99. package/dist/secret-vault-BJDY28ev.d.ts +0 -25
@@ -65,6 +65,11 @@ async function renameWithRetry(from, to) {
65
65
  throw lastErr;
66
66
  }
67
67
 
68
+ // src/utils/error.ts
69
+ function toErrorMessage(err) {
70
+ return err instanceof Error ? err.message : String(err);
71
+ }
72
+
68
73
  // src/utils/merge-models-payload.ts
69
74
  function mergeModelsPayload(base, overlay) {
70
75
  const out = {};
@@ -224,7 +229,7 @@ var DefaultModelsRegistry = class {
224
229
  }
225
230
  if (overlayAvailable) {
226
231
  console.warn(
227
- `ModelsRegistry: models.dev unavailable (${err instanceof Error ? err.message : String(err)}); serving curated overlay only.`
232
+ `ModelsRegistry: models.dev unavailable (${toErrorMessage(err)}); serving curated overlay only.`
228
233
  );
229
234
  return {};
230
235
  }
@@ -837,12 +842,9 @@ function getCachedEstimate(key, compute) {
837
842
  const existing = ESTIMATE_CACHE.get(key);
838
843
  if (existing !== void 0) return existing;
839
844
  if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
840
- let evicted = 0;
841
- const maxEvict = Math.floor(ESTIMATE_CACHE_MAX_SIZE / 4);
842
845
  for (const k of ESTIMATE_CACHE.keys()) {
843
- if (evicted >= maxEvict) break;
846
+ if (ESTIMATE_CACHE.size <= Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) break;
844
847
  ESTIMATE_CACHE.delete(k);
845
- evicted++;
846
848
  }
847
849
  }
848
850
  const estimate = compute(key);
@@ -914,9 +916,9 @@ Rules:
914
916
  - If unsure, keep rather than collapse (errors are more costly than waste)
915
917
 
916
918
  Return ONLY the JSON object, no markdown, no explanation outside the JSON.`;
917
- function formatMessages(messages, maxChars = 8e3) {
919
+ function formatMessages(messages, maxTokens = 2048) {
918
920
  const lines = [];
919
- let used = 0;
921
+ let usedTokens = 0;
920
922
  for (let i = 0; i < messages.length; i++) {
921
923
  const m = expectDefined(messages[i]);
922
924
  const role = m.role.padEnd(10, " ");
@@ -928,13 +930,14 @@ function formatMessages(messages, maxChars = 8e3) {
928
930
  text = content.filter(isTextBlock).map((b) => b.text).join(" ");
929
931
  const toolUses = content.filter((b) => b.type === "tool_use");
930
932
  if (toolUses.length > 0) {
931
- text += ` [tools: ${toolUses.map((b) => b.name).join(", ")}]`;
933
+ text += ` [tools: ${toolUses.map((b) => b.name).filter(Boolean).join(", ")}]`;
932
934
  }
933
935
  }
934
936
  const line = `[${i}][${role}]: ${text}`;
935
- if (used + line.length > maxChars) break;
937
+ const lineTokens = estimateTextTokens(line);
938
+ if (usedTokens + lineTokens > maxTokens) break;
936
939
  lines.push(line);
937
- used += line.length;
940
+ usedTokens += lineTokens;
938
941
  }
939
942
  return lines.join("\n");
940
943
  }
@@ -943,20 +946,29 @@ var LLMSelector = class {
943
946
  model;
944
947
  maxContextTokens;
945
948
  systemPrompt;
949
+ maxOutputTokens;
946
950
  constructor(opts) {
947
951
  this.provider = opts.provider;
948
952
  this.model = opts.model ?? "unknown";
953
+ if (this.model === "unknown" && (process.env["NODE_ENV"] === "development" || process.env["WRONGSTACK_DEBUG"] === "1")) {
954
+ console.warn(
955
+ "[LLMSelector] model not set \u2014 selector will use the provider default. Set `model` explicitly in LLMSelectorOptions to silence this warning."
956
+ );
957
+ }
949
958
  this.maxContextTokens = opts.maxContextTokens ?? 4e4;
950
959
  this.systemPrompt = opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
960
+ this.maxOutputTokens = opts.maxOutputTokens ?? 1024;
951
961
  }
952
962
  async select(messages, maxToKeep) {
953
963
  const effectiveBudget = Math.min(maxToKeep, this.maxContextTokens);
954
- const historyText = formatMessages(messages);
955
964
  const totalTokens = estimateMessageTokens(messages);
956
965
  const systemText = `${this.systemPrompt}
957
966
 
958
967
  Conversation (${messages.length} messages, ~${totalTokens} tokens, budget: ${effectiveBudget}):
959
968
  `;
969
+ const systemTokens = estimateTextTokens(systemText);
970
+ const historyBudget = Math.max(512, effectiveBudget - systemTokens - this.maxOutputTokens);
971
+ const historyText = formatMessages(messages, historyBudget);
960
972
  const budgetInstruction = totalTokens > effectiveBudget ? `
961
973
 
962
974
  IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiveBudget}). You MUST collapse enough to fit. Prefer collapsing older/lower-importance ranges.` : "";
@@ -964,18 +976,26 @@ IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiv
964
976
  model: this.model,
965
977
  system: [{ type: "text", text: systemText + budgetInstruction }],
966
978
  messages: [{ role: "user", content: historyText }],
967
- maxTokens: 1024
979
+ maxTokens: this.maxOutputTokens
968
980
  };
969
981
  let raw;
982
+ const ac = new AbortController();
970
983
  try {
971
- const ac = new AbortController();
972
- const res = await this.provider.complete(req, { signal: ac.signal });
984
+ const timeoutSignal = AbortSignal.timeout(3e4);
985
+ const res = await this.provider.complete(req, {
986
+ signal: AbortSignal.any([ac.signal, timeoutSignal])
987
+ });
973
988
  const textBlocks = res.content.filter(isTextBlock);
974
989
  raw = textBlocks.map((b) => b.text).join("\n").trim();
975
- } catch (_err) {
990
+ } catch (err) {
991
+ if (err instanceof Error) {
992
+ console.warn("[LLMSelector] selector call failed, using recency fallback:", err.message);
993
+ }
976
994
  return this.fallbackSelect(messages, effectiveBudget);
995
+ } finally {
996
+ ac.abort();
977
997
  }
978
- return this.parseSelectorOutput(raw, messages.length);
998
+ return this.parseSelectorOutput(raw, messages);
979
999
  }
980
1000
  fallbackSelect(messages, budget) {
981
1001
  const toKeep = [];
@@ -1002,34 +1022,63 @@ IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiv
1002
1022
  reasoning: `Fallback: kept last ${messages.length - startIdx} messages within ${budget} token budget`
1003
1023
  };
1004
1024
  }
1005
- parseSelectorOutput(raw, messageCount) {
1025
+ /**
1026
+ * Parse and validate the raw LLM output into a SelectorResult.
1027
+ * Falls back to recency-based selection if the LLM output is malformed,
1028
+ * out-of-bounds, or internally inconsistent.
1029
+ */
1030
+ parseSelectorOutput(raw, messages) {
1031
+ const messageCount = messages.length;
1032
+ if (messageCount === 0) {
1033
+ return { kept: [], collapsed: [], reasoning: "empty session" };
1034
+ }
1006
1035
  const jsonStart = raw.indexOf("{");
1007
1036
  const jsonEnd = raw.lastIndexOf("}");
1008
1037
  if (jsonStart === -1 || jsonEnd === -1) {
1009
- return this.fallbackSelect(
1010
- Array.from({ length: messageCount }, () => ({ role: "user", content: "" })),
1011
- this.maxContextTokens
1012
- );
1038
+ return this.fallbackSelect(messages, this.maxContextTokens);
1013
1039
  }
1014
1040
  let parsed;
1015
1041
  try {
1016
1042
  parsed = JSON.parse(raw.slice(jsonStart, jsonEnd + 1));
1017
1043
  } catch {
1018
- return this.fallbackSelect(
1019
- Array.from({ length: messageCount }, () => ({ role: "user", content: "" })),
1020
- this.maxContextTokens
1021
- );
1044
+ return this.fallbackSelect(messages, this.maxContextTokens);
1022
1045
  }
1023
1046
  const obj = parsed;
1024
- const kept = obj.kept ?? [];
1025
- const collapsed = obj.collapsed ?? [];
1026
- return {
1027
- kept: kept.map((k) => ({
1047
+ const keptRaw = obj.kept ?? [];
1048
+ const collapsedRaw = obj.collapsed ?? [];
1049
+ const kept = [];
1050
+ for (const k of keptRaw) {
1051
+ if (typeof k.from !== "number" || typeof k.to !== "number" || k.from < 0 || k.to >= messageCount || k.from > k.to) {
1052
+ return this.fallbackSelect(messages, this.maxContextTokens);
1053
+ }
1054
+ kept.push({
1028
1055
  from: k.from,
1029
1056
  to: k.to,
1030
1057
  importance: k.importance ?? "medium"
1031
- })),
1032
- collapsed: collapsed.map((c) => ({ from: c.from, to: c.to, summary: c.summary })),
1058
+ });
1059
+ }
1060
+ const collapsed = [];
1061
+ for (const c of collapsedRaw) {
1062
+ if (typeof c.from !== "number" || typeof c.to !== "number" || c.from < 0 || c.to >= messageCount || c.from > c.to) {
1063
+ return this.fallbackSelect(messages, this.maxContextTokens);
1064
+ }
1065
+ collapsed.push({ from: c.from, to: c.to, summary: c.summary });
1066
+ }
1067
+ const allRanges = [...kept, ...collapsed];
1068
+ for (let i = 0; i < allRanges.length; i++) {
1069
+ const a = allRanges[i];
1070
+ if (!a) continue;
1071
+ for (let j = i + 1; j < allRanges.length; j++) {
1072
+ const b = allRanges[j];
1073
+ if (!b) continue;
1074
+ if (a.from <= b.to && a.to >= b.from) {
1075
+ return this.fallbackSelect(messages, this.maxContextTokens);
1076
+ }
1077
+ }
1078
+ }
1079
+ return {
1080
+ kept,
1081
+ collapsed,
1033
1082
  reasoning: typeof obj.reasoning === "string" ? obj.reasoning : ""
1034
1083
  };
1035
1084
  }