@proxysoul/soulforge 1.3.7 → 1.4.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 (2) hide show
  1. package/dist/index.js +113 -66
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -57809,6 +57809,100 @@ var init_providers = __esm(() => {
57809
57809
  providerMap = new Map(allProviders.map((p) => [p.id, p]));
57810
57810
  });
57811
57811
 
57812
+ // package.json
57813
+ var package_default;
57814
+ var init_package = __esm(() => {
57815
+ package_default = {
57816
+ name: "@proxysoul/soulforge",
57817
+ version: "1.4.0",
57818
+ description: "Graph-powered code intelligence \u2014 multi-agent coding with codebase-aware AI",
57819
+ repository: {
57820
+ type: "git",
57821
+ url: "https://github.com/proxysoul/soulforge.git"
57822
+ },
57823
+ publishConfig: {
57824
+ registry: "https://registry.npmjs.org",
57825
+ access: "public"
57826
+ },
57827
+ module: "src/boot.tsx",
57828
+ type: "module",
57829
+ license: "BUSL-1.1",
57830
+ author: "proxySoul",
57831
+ bin: {
57832
+ soulforge: "./dist/bin.sh",
57833
+ sf: "./dist/bin.sh"
57834
+ },
57835
+ engines: {
57836
+ bun: ">=1.2.0"
57837
+ },
57838
+ files: [
57839
+ "dist",
57840
+ "THIRD_PARTY_LICENSES.md"
57841
+ ],
57842
+ scripts: {
57843
+ dev: "bun run src/boot.tsx",
57844
+ build: "bun scripts/build.ts",
57845
+ "build:no-compiler": 'bun build src/boot.tsx --outdir dist --target bun --external react-devtools-core --entry-naming "[dir]/index.[ext]"',
57846
+ "build:binary": "bun build src/boot.tsx --compile --external react-devtools-core --outfile bin/soulforge",
57847
+ bundle: "bash scripts/bundle.sh arm64 darwin",
57848
+ "bundle:x64": "bash scripts/bundle.sh x64 darwin",
57849
+ "bundle:linux": "bash scripts/bundle.sh x64 linux",
57850
+ "bundle:linux-arm64": "bash scripts/bundle.sh arm64 linux",
57851
+ lint: "biome check src/",
57852
+ "lint:fix": "biome check --write src/",
57853
+ format: "biome format --write src/",
57854
+ test: "bun test",
57855
+ "test:coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage",
57856
+ "test:coverage:html": "bun run test:coverage && genhtml coverage/lcov.info --output-directory coverage/html --dark-mode && open coverage/html/index.html",
57857
+ typecheck: "tsc --noEmit",
57858
+ prepublishOnly: "bun run lint && bun run typecheck && bun run build",
57859
+ release: "bun run build && npm publish",
57860
+ "release:patch": "bash scripts/release.sh patch",
57861
+ "release:minor": "bash scripts/release.sh minor",
57862
+ "release:major": "bash scripts/release.sh major",
57863
+ "release:dry": "bash scripts/release.sh patch --dry-run"
57864
+ },
57865
+ devDependencies: {
57866
+ "@babel/core": "7.29.0",
57867
+ "@biomejs/biome": "2.4.9",
57868
+ "@types/babel__core": "7.20.5",
57869
+ "@types/bun": "1.3.11",
57870
+ "@types/linkify-it": "5.0.0",
57871
+ "@types/node": "25.5.0",
57872
+ "@types/react": "19.2.14",
57873
+ "babel-plugin-react-compiler": "1.0.0",
57874
+ "bun-types": "1.3.11",
57875
+ typescript: "6.0.2"
57876
+ },
57877
+ dependencies: {
57878
+ "@ai-sdk/anthropic": "3.0.64",
57879
+ "@ai-sdk/google": "3.0.53",
57880
+ "@ai-sdk/openai": "3.0.48",
57881
+ "@ai-sdk/xai": "3.0.74",
57882
+ "@anthropic-ai/sdk": "0.80.0",
57883
+ "@llmgateway/ai-sdk-provider": "3.5.0",
57884
+ "@mozilla/readability": "0.6.0",
57885
+ "@openrouter/ai-sdk-provider": "2.3.3",
57886
+ "@opentui/react": "0.1.90",
57887
+ ai: "6.0.138",
57888
+ "ghostty-opentui": "1.4.10",
57889
+ isbinaryfile: "6.0.0",
57890
+ linkedom: "0.18.12",
57891
+ "linkify-it": "5.0.0",
57892
+ marked: "17.0.5",
57893
+ neovim: "5.4.0",
57894
+ react: "19.2.4",
57895
+ shiki: "4.0.2",
57896
+ "strip-ansi": "7.2.0",
57897
+ "tree-sitter-wasms": "0.1.13",
57898
+ "ts-morph": "27.0.2",
57899
+ "web-tree-sitter": "0.25.10",
57900
+ zod: "4.3.6",
57901
+ zustand: "5.0.12"
57902
+ }
57903
+ };
57904
+ });
57905
+
57812
57906
  // src/core/version.ts
57813
57907
  import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
57814
57908
  import { homedir as homedir6 } from "os";
@@ -58099,19 +58193,14 @@ async function checkForUpdate() {
58099
58193
  };
58100
58194
  }
58101
58195
  }
58102
- var PKG_NAME = "@proxysoul/soulforge", CONFIG_DIR2, VERSION_CACHE_FILE, CACHE_TTL, DISMISSED_FILE, _currentVersion = "0.0.0", CURRENT_VERSION;
58196
+ var PKG_NAME = "@proxysoul/soulforge", CONFIG_DIR2, VERSION_CACHE_FILE, CACHE_TTL, DISMISSED_FILE, _currentVersion, CURRENT_VERSION;
58103
58197
  var init_version = __esm(() => {
58198
+ init_package();
58104
58199
  CONFIG_DIR2 = join6(homedir6(), ".soulforge");
58105
58200
  VERSION_CACHE_FILE = join6(CONFIG_DIR2, "version-cache.json");
58106
58201
  CACHE_TTL = 30 * 60 * 1000;
58107
58202
  DISMISSED_FILE = join6(CONFIG_DIR2, "update-dismissed.json");
58108
- try {
58109
- const pkgPath = join6(import.meta.dir, "..", "..", "package.json");
58110
- if (existsSync6(pkgPath)) {
58111
- const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
58112
- _currentVersion = pkg.version ?? "0.0.0";
58113
- }
58114
- } catch {}
58203
+ _currentVersion = package_default.version ?? "0.0.0";
58115
58204
  CURRENT_VERSION = _currentVersion;
58116
58205
  });
58117
58206
 
@@ -62154,7 +62243,6 @@ function markToolWrite(filePath) {
62154
62243
  async function readBufferContent(filePath) {
62155
62244
  const toolWriteTime = recentToolWrites.get(filePath);
62156
62245
  if (toolWriteTime && Date.now() - toolWriteTime < TOOL_WRITE_FRESHNESS_MS) {
62157
- recentToolWrites.delete(filePath);
62158
62246
  return readFile3(filePath, "utf-8");
62159
62247
  }
62160
62248
  inflight++;
@@ -317464,7 +317552,7 @@ function buildRichEditError(content, oldStr, lineHint) {
317464
317552
  const escapeHint = backslashDensity > 0.05 ? `
317465
317553
  [Escape-heavy content detected \u2014 use lineStart for line-based replacement, or use editor(action: edit, startLine, endLine, replacement)]` : "";
317466
317554
  return {
317467
- output: `old_string not found in file (re-read performed \u2014 content below is current):
317555
+ output: `old_string not found in file. Current content at that region:
317468
317556
  ${snippet}${escapeHint}`
317469
317557
  };
317470
317558
  }
@@ -317624,7 +317712,7 @@ var init_edit_file = __esm(() => {
317624
317712
  init_file_events();
317625
317713
  editFileTool = {
317626
317714
  name: "edit_file",
317627
- description: "[TIER-1] Edit a file by replacing content. Read first, then provide path, oldString, newString. " + "Always provide lineStart (1-indexed from read_file output) \u2014 the range is derived from oldString line count. " + "Empty oldString creates a new file. Use multi_edit for multiple changes to the same file. Edits are applied immediately.",
317715
+ description: "[TIER-1] Edit a file by replacing content. Read first, then provide path, oldString, newString. " + "Provide lineStart (1-indexed from read_file output) for reliable line-anchored matching \u2014 " + "the range is derived from oldString line count. Without lineStart, falls back to string matching (fails if ambiguous). Empty oldString creates a new file. Use multi_edit for multiple changes to the same file. Edits are applied immediately.",
317628
317716
  execute: async (args2) => {
317629
317717
  try {
317630
317718
  const filePath = resolve13(args2.path);
@@ -334548,7 +334636,7 @@ var init_multi_edit = __esm(() => {
334548
334636
  init_file_events();
334549
334637
  multiEditTool = {
334550
334638
  name: "multi_edit",
334551
- description: "Apply multiple edits to a single file atomically. All-or-nothing validation. " + "Each edit's oldString and lineStart reference the ORIGINAL file \u2014 the tool handles offset tracking internally. " + "Always provide lineStart (1-indexed). The range is derived from oldString line count.",
334639
+ description: "Apply multiple edits to a single file atomically. All-or-nothing: if any edit fails, ZERO edits are applied. " + "lineStart values reference the ORIGINAL file (pre-edit) \u2014 the tool tracks cumulative line offsets internally. " + "Provide lineStart (1-indexed) for reliable line-anchored matching. Without it, falls back to string matching against evolved content. " + "The range is derived from oldString line count.",
334552
334640
  execute: async (args2) => {
334553
334641
  try {
334554
334642
  const filePath = resolve19(args2.path);
@@ -334592,7 +334680,6 @@ var init_multi_edit = __esm(() => {
334592
334680
  return a.lineStart - b.lineStart;
334593
334681
  });
334594
334682
  let lineOffset = 0;
334595
- const warnings = [];
334596
334683
  for (let i2 = 0;i2 < sortedEdits.length; i2++) {
334597
334684
  const edit = sortedEdits[i2];
334598
334685
  if (!edit)
@@ -334639,21 +334726,21 @@ var init_multi_edit = __esm(() => {
334639
334726
  `);
334640
334727
  return {
334641
334728
  success: false,
334642
- output: `Edit ${String(i2 + 1)}: oldString does not match lines ${String(edit.lineStart)}-${String((edit.lineStart ?? 0) + oldLineCount - 1)}. Actual content:
334729
+ output: `Edit ${String(i2 + 1)}/${String(args2.edits.length)} failed: oldString does not match lines ${String(edit.lineStart)}-${String((edit.lineStart ?? 0) + oldLineCount - 1)}. NO edits were applied (atomic rollback). Actual content at that range:
334643
334730
  ${rangeSnippet}
334644
- Re-read the file and retry with the correct content.`,
334645
- error: `edit ${String(i2 + 1)}: oldString mismatch at line range`
334731
+ Re-read the file and retry ALL edits.`,
334732
+ error: `edit ${String(i2 + 1)}: oldString mismatch at line range (0 edits applied)`
334646
334733
  };
334647
334734
  }
334648
334735
  }
334649
334736
  if (content.includes(edit.oldString)) {
334650
334737
  const occurrences = content.split(edit.oldString).length - 1;
334651
334738
  if (occurrences > 1) {
334652
- const msg = `${label}: found ${String(occurrences)} matches. Provide lineStart to disambiguate.`;
334739
+ const msg = `${label}: found ${String(occurrences)} matches. Provide lineStart to disambiguate. NO edits were applied (atomic rollback).`;
334653
334740
  return {
334654
334741
  success: false,
334655
334742
  output: msg,
334656
- error: msg
334743
+ error: `${label}: ambiguous match (0 edits applied)`
334657
334744
  };
334658
334745
  }
334659
334746
  const idx = content.indexOf(edit.oldString);
@@ -334678,8 +334765,9 @@ Re-read the file and retry with the correct content.`,
334678
334765
  const err2 = buildRichEditError(content, edit.oldString, adjustedLineStart);
334679
334766
  return {
334680
334767
  success: false,
334681
- output: `${label} failed: ${err2.output}`,
334682
- error: `edit ${String(i2 + 1)} failed`
334768
+ output: `${label} failed: ${err2.output}
334769
+ NO edits were applied (atomic rollback). Re-read the file and retry ALL edits.`,
334770
+ error: `edit ${String(i2 + 1)} failed (0 edits applied)`
334683
334771
  };
334684
334772
  }
334685
334773
  const beforeMetrics = analyzeFile(originalContent);
@@ -334705,11 +334793,11 @@ Re-read the file and retry with the correct content.`,
334705
334793
  }).catch(() => null);
334706
334794
  const currentOnDisk = await readFile13(filePath, "utf-8");
334707
334795
  if (currentOnDisk !== originalContent) {
334708
- const msg = "File was modified concurrently since last read. Re-read and retry.";
334796
+ const msg = "File was modified concurrently since last read. NO edits were applied (atomic rollback). Re-read and retry ALL edits.";
334709
334797
  return {
334710
334798
  success: false,
334711
334799
  output: msg,
334712
- error: "concurrent modification"
334800
+ error: "concurrent modification (0 edits applied)"
334713
334801
  };
334714
334802
  }
334715
334803
  pushEdit(filePath, originalContent, content, args2.tabId);
@@ -334729,10 +334817,6 @@ Re-read the file and retry with the correct content.`,
334729
334817
  deltas.push(`imports: ${String(beforeMetrics.importCount)}\u2192${String(afterMetrics.importCount)} (${sign}${String(importDelta)})`);
334730
334818
  }
334731
334819
  let output = `Applied ${String(args2.edits.length)} edits to ${args2.path}`;
334732
- if (warnings.length > 0)
334733
- output += `
334734
- \u26A0 ${warnings.join(`
334735
- \u26A0 `)}`;
334736
334820
  if (deltas.length > 0)
334737
334821
  output += ` (${deltas.join(", ")})`;
334738
334822
  const formatted = await autoFormatAfterEdit(filePath);
@@ -424666,7 +424750,7 @@ function createRoot(renderer) {
424666
424750
  }
424667
424751
  var import_react2, import_react3, import_react4, import_jsx_dev_runtime, import_react_reconciler, import_constants33, import_react5, import_constants34, textNodeKeys, SpanRenderable, TextModifierRenderable, BoldSpanRenderable, ItalicSpanRenderable, UnderlineSpanRenderable, LineBreakRenderable, LinkRenderable, baseComponents, componentCatalogue, AppContext, useAppContext = () => {
424668
424752
  return import_react2.useContext(AppContext);
424669
- }, ErrorBoundary, package_default, idCounter, currentUpdatePriority, hostConfig, reconciler, _r, flushSync, createPortal;
424753
+ }, ErrorBoundary, package_default2, idCounter, currentUpdatePriority, hostConfig, reconciler, _r, flushSync, createPortal;
424670
424754
  var init_chunk_tq1yd1rw = __esm(async () => {
424671
424755
  init_chunk_2mx7fq49();
424672
424756
  await __promiseAll([
@@ -424786,7 +424870,7 @@ var init_chunk_tq1yd1rw = __esm(async () => {
424786
424870
  return this.props.children;
424787
424871
  }
424788
424872
  };
424789
- package_default = {
424873
+ package_default2 = {
424790
424874
  name: "@opentui/react",
424791
424875
  version: "0.1.90",
424792
424876
  description: "React renderer for building terminal user interfaces using OpenTUI core",
@@ -425012,7 +425096,7 @@ var init_chunk_tq1yd1rw = __esm(async () => {
425012
425096
  return null;
425013
425097
  },
425014
425098
  rendererPackageName: "@opentui/react",
425015
- rendererVersion: package_default.version
425099
+ rendererVersion: package_default2.version
425016
425100
  };
425017
425101
  reconciler = import_react_reconciler.default(hostConfig);
425018
425102
  if (process.env["DEV"] === "true") {
@@ -474770,8 +474854,6 @@ var init_SkillSearch = __esm(async () => {
474770
474854
  SkillSearch = import_react115.memo(function SkillSearch2({
474771
474855
  visible,
474772
474856
  contextManager,
474773
- agentSkillsEnabled,
474774
- onToggleAgentSkills,
474775
474857
  onClose,
474776
474858
  onSystemMessage
474777
474859
  }) {
@@ -474951,10 +475033,6 @@ var init_SkillSearch = __esm(async () => {
474951
475033
  resetScroll();
474952
475034
  return;
474953
475035
  }
474954
- if (evt.name === "a" && !evt.ctrl && !evt.meta && !query2) {
474955
- onToggleAgentSkills();
474956
- return;
474957
- }
474958
475036
  if (evt.name === "space") {
474959
475037
  setQuery((prev_3) => `${prev_3} `);
474960
475038
  resetScroll();
@@ -475380,32 +475458,6 @@ var init_SkillSearch = __esm(async () => {
475380
475458
  children: ""
475381
475459
  }, undefined, false, undefined, this)
475382
475460
  }, undefined, false, undefined, this),
475383
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PopupRow, {
475384
- w: innerW,
475385
- children: [
475386
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
475387
- fg: t2.textMuted,
475388
- bg: POPUP_BG,
475389
- children: [
475390
- "Agent access:",
475391
- " "
475392
- ]
475393
- }, undefined, true, undefined, this),
475394
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
475395
- fg: agentSkillsEnabled ? t2.success : t2.error,
475396
- bg: POPUP_BG,
475397
- children: agentSkillsEnabled ? "on" : "off"
475398
- }, undefined, false, undefined, this),
475399
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
475400
- fg: t2.textDim,
475401
- bg: POPUP_BG,
475402
- children: [
475403
- " ",
475404
- "(a to toggle)"
475405
- ]
475406
- }, undefined, true, undefined, this)
475407
- ]
475408
- }, undefined, true, undefined, this),
475409
475461
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(PopupRow, {
475410
475462
  w: innerW,
475411
475463
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
@@ -476972,11 +477024,6 @@ function App({
476972
477024
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(SkillSearch, {
476973
477025
  visible: modalSkillSearch,
476974
477026
  contextManager: tabMgr.getActiveChat()?.contextManager ?? contextManager,
476975
- agentSkillsEnabled: !toolsState.disabledTools.has("skills"),
476976
- onToggleAgentSkills: () => {
476977
- toolsState.toggleTool("skills");
476978
- addSystemMessage(`Agent skills ${toolsState.disabledTools.has("skills") ? "enabled" : "disabled"}`);
476979
- },
476980
477027
  onClose: getCloser2("skillSearch"),
476981
477028
  onSystemMessage: addSystemMessage
476982
477029
  }, undefined, false, undefined, this),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proxysoul/soulforge",
3
- "version": "1.3.7",
3
+ "version": "1.4.0",
4
4
  "description": "Graph-powered code intelligence — multi-agent coding with codebase-aware AI",
5
5
  "repository": {
6
6
  "type": "git",