volute 0.51.0 → 0.52.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 (50) hide show
  1. package/dist/{auth-X6EMNEGB.js → auth-KRDSM55Q.js} +3 -1
  2. package/dist/{chunk-VAEZCIJC.js → chunk-724DVYHU.js} +8 -8
  3. package/dist/{chunk-HKP6OAJP.js → chunk-7LT3YZUR.js} +12 -0
  4. package/dist/{chunk-ICL6T4SN.js → chunk-AXFLY5GU.js} +11 -2
  5. package/dist/{chunk-DN3LKLYR.js → chunk-CW7BQKF6.js} +3 -3
  6. package/dist/{chunk-AI47FDGL.js → chunk-ITK6HV47.js} +1 -1
  7. package/dist/{chunk-VSBMLB2W.js → chunk-K2F237KS.js} +2 -2
  8. package/dist/{chunk-QT4D5XCI.js → chunk-RPPTGPYF.js} +1 -1
  9. package/dist/{chunk-7HN63Q7J.js → chunk-RU74YG46.js} +5 -5
  10. package/dist/{chunk-Q7XQLKZB.js → chunk-SW2U6HRB.js} +2 -2
  11. package/dist/{chunk-BSHZ23MS.js → chunk-XRWUQPCA.js} +2 -2
  12. package/dist/{chunk-CDKQJWGK.js → chunk-YVR6EHWL.js} +2 -2
  13. package/dist/{chunk-VP5PFNZO.js → chunk-ZEZQNP2G.js} +35 -19
  14. package/dist/cli.js +6 -6
  15. package/dist/{cloud-sync-GPXYPTIC.js → cloud-sync-H7EWZASD.js} +9 -9
  16. package/dist/{daemon-restart-2EWBRTN5.js → daemon-restart-4FWUA5JF.js} +1 -1
  17. package/dist/daemon.js +321 -186
  18. package/dist/{delete-O7PEFQDF.js → delete-CYVZUAV2.js} +4 -0
  19. package/dist/{delivery-manager-HGVZSEES.js → delivery-manager-VYXVKUMP.js} +4 -4
  20. package/dist/{echo-text-6ANI5HHN.js → echo-text-PEEV7FQU.js} +10 -10
  21. package/dist/{extensions-NY6WST33.js → extensions-N6L5NYTK.js} +9 -9
  22. package/dist/{join-PYA36HEC.js → join-KLRU72JJ.js} +10 -2
  23. package/dist/{message-delivery-JHMAJ2GU.js → message-delivery-7URC52ME.js} +9 -9
  24. package/dist/{mind-WF6QIXWV.js → mind-NEXGT3KE.js} +4 -4
  25. package/dist/{mind-service-DZCUUC7J.js → mind-service-E26ZQXDS.js} +9 -9
  26. package/dist/{package-B6O5APCZ.js → package-2W2XKSIP.js} +2 -2
  27. package/dist/{scheduler-TNBN54ZK.js → scheduler-JTTWZDYU.js} +4 -4
  28. package/dist/{seed-K2LYODIH.js → seed-64XEHRUP.js} +1 -1
  29. package/dist/{seed-cmd-2EWBTR6P.js → seed-cmd-UEL2QB3Q.js} +2 -2
  30. package/dist/{seed-create-VGTLU5FD.js → seed-create-4JRQDPGA.js} +1 -1
  31. package/dist/{seed-sprout-PILHJ3YS.js → seed-sprout-NIDIOJXT.js} +2 -2
  32. package/dist/{setup-MDPSK2XG.js → setup-4IX6PCD3.js} +1 -1
  33. package/dist/skills/volute-mind/references/variants.md +1 -1
  34. package/dist/{skills-NH2GQKAF.js → skills-MPUALV3S.js} +1 -1
  35. package/dist/{sleep-manager-7JXEQQ2P.js → sleep-manager-OFP2GFXF.js} +9 -9
  36. package/dist/{spirit-25JVAL3M.js → spirit-4ECYIVGE.js} +2 -2
  37. package/dist/{spirit-availability-PJDWZJ3J.js → spirit-availability-Y54Y3675.js} +10 -10
  38. package/dist/{sprout-EXUZMIOR.js → sprout-GJMZFRGZ.js} +1 -1
  39. package/dist/{system-events-ZPSH63QX.js → system-events-V43HDA3T.js} +3 -1
  40. package/dist/{turn-tracker-TAT2HGK6.js → turn-tracker-C5PVIC3B.js} +1 -1
  41. package/dist/{up-J7XCAH7P.js → up-H6LJZDRK.js} +1 -1
  42. package/dist/{variant-cleanup-YXN25ZVW.js → variant-cleanup-STC6B5HR.js} +4 -4
  43. package/dist/{version-notify-EN3KJ7HH.js → version-notify-LBVHH5YV.js} +1 -1
  44. package/dist/web-assets/assets/index-B_eYTa3R.js +97 -0
  45. package/dist/web-assets/assets/{index-BOyJ4Gqs.css → index-DhZrzddW.css} +1 -1
  46. package/dist/web-assets/index.html +2 -2
  47. package/package.json +2 -2
  48. package/templates/_base/src/lib/auto-commit.ts +49 -11
  49. package/dist/web-assets/assets/index-CrxBwnzp.js +0 -95
  50. /package/dist/{chunk-IWAVIJO2.js → chunk-VPOMJMV6.js} +0 -0
@@ -8,8 +8,8 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com" />
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
10
  <link href="https://fonts.googleapis.com/css2?family=Averia+Serif+Libre:wght@300;400;700&family=Fira+Code:wght@300;400;500;600&family=Averia+Sans+Libre:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap" rel="stylesheet" />
11
- <script type="module" crossorigin src="/assets/index-CrxBwnzp.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-BOyJ4Gqs.css">
11
+ <script type="module" crossorigin src="/assets/index-B_eYTa3R.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-DhZrzddW.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volute",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "description": "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "dependencies": {
69
69
  "@anthropic-ai/sandbox-runtime": "^0.0.65",
70
- "@earendil-works/pi-ai": "^0.80.6",
70
+ "@earendil-works/pi-ai": "0.80.6",
71
71
  "@hono/node-server": "^2.0.8",
72
72
  "@hono/zod-validator": "^0.8.0",
73
73
  "@libsql/client": "^0.17.4",
@@ -1,6 +1,6 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { resolve } from "node:path";
3
- import { log } from "./logger.js";
3
+ import { log, warn } from "./logger.js";
4
4
 
5
5
  function gitArgs(args: string[]): string[] {
6
6
  return process.env.VOLUTE_ISOLATION === "user" ? ["-c", "safe.directory=*", ...args] : args;
@@ -63,15 +63,37 @@ export function flushFileChanges(cwd?: string): Promise<void> {
63
63
  const effectiveCwd = cwd ?? process.cwd();
64
64
 
65
65
  pending = pending.then(async () => {
66
- // Commit mind's own files
66
+ // Commit mind's own files. Only files that actually staged go into the commit
67
+ // message — a file `git add` couldn't stage (typically because it's gitignored)
68
+ // must never be named alongside files that really did commit, or the mind is
69
+ // told its work is safe when it isn't (#656).
67
70
  if (filesToCommit.length > 0) {
71
+ const staged: string[] = [];
72
+ const blocked: string[] = [];
68
73
  for (const f of filesToCommit) {
69
- if ((await exec("git", ["add", f], effectiveCwd)).code !== 0) {
70
- log("auto-commit", `git add failed for ${f}`);
74
+ if ((await exec("git", ["add", f], effectiveCwd)).code === 0) {
75
+ staged.push(f);
76
+ } else {
77
+ blocked.push(f);
71
78
  }
72
79
  }
73
- if ((await exec("git", ["diff", "--cached", "--quiet"], effectiveCwd)).code !== 0) {
74
- const names = filesToCommit.map((f) => f.replace(/^.*\//, "")).join(", ");
80
+ if (blocked.length > 0) {
81
+ const pronoun = blocked.length === 1 ? "it" : "they";
82
+ warn(
83
+ "auto-commit",
84
+ `git add failed for ${blocked.join(", ")} — likely gitignored, so ` +
85
+ `${pronoun} will NOT be committed or survive a variant join`,
86
+ );
87
+ }
88
+ // staged.length check guards against committing under a blank "Update "
89
+ // message when every file in this batch was blocked — `diff --cached` can
90
+ // still be non-empty from unrelated content already in the index (e.g. the
91
+ // mind ran `git add` itself), which isn't this batch's to name or claim.
92
+ if (
93
+ staged.length > 0 &&
94
+ (await exec("git", ["diff", "--cached", "--quiet"], effectiveCwd)).code !== 0
95
+ ) {
96
+ const names = staged.map((f) => f.replace(/^.*\//, "")).join(", ");
75
97
  const message = `Update ${names}`;
76
98
  if ((await exec("git", ["commit", "-m", message], effectiveCwd)).code === 0) {
77
99
  log("auto-commit", message);
@@ -89,20 +111,36 @@ export function flushFileChanges(cwd?: string): Promise<void> {
89
111
  }
90
112
  }
91
113
 
92
- // Commit collaborative pages worktree files
114
+ // Commit collaborative pages worktree files. Same rule as the mind's own
115
+ // files above: only what actually staged gets named in the commit message.
93
116
  if (sharedToCommit.length > 0) {
94
117
  const sharedCwd = resolve(effectiveCwd, "pages", "_system");
95
118
  const sharedPrefix = "pages/_system/";
96
119
  const mindName = process.env.VOLUTE_MIND ?? "unknown";
97
120
 
121
+ const sharedStaged: string[] = [];
122
+ const sharedBlocked: string[] = [];
98
123
  for (const f of sharedToCommit) {
99
124
  const sharedRelative = f.slice(sharedPrefix.length);
100
- if ((await exec("git", gitArgs(["add", sharedRelative]), sharedCwd)).code !== 0) {
101
- log("auto-commit", `git add failed for pages/_system/${sharedRelative}`);
125
+ if ((await exec("git", gitArgs(["add", sharedRelative]), sharedCwd)).code === 0) {
126
+ sharedStaged.push(f);
127
+ } else {
128
+ sharedBlocked.push(f);
102
129
  }
103
130
  }
104
- if ((await exec("git", gitArgs(["diff", "--cached", "--quiet"]), sharedCwd)).code !== 0) {
105
- const names = sharedToCommit
131
+ if (sharedBlocked.length > 0) {
132
+ const pronoun = sharedBlocked.length === 1 ? "it" : "they";
133
+ warn(
134
+ "auto-commit",
135
+ `git add failed for ${sharedBlocked.join(", ")} — likely gitignored, so ` +
136
+ `${pronoun} will NOT be committed`,
137
+ );
138
+ }
139
+ if (
140
+ sharedStaged.length > 0 &&
141
+ (await exec("git", gitArgs(["diff", "--cached", "--quiet"]), sharedCwd)).code !== 0
142
+ ) {
143
+ const names = sharedStaged
106
144
  .map((f) => f.slice(sharedPrefix.length).replace(/^.*\//, ""))
107
145
  .join(", ");
108
146
  const message = `Update ${names}`;