volute 0.2.0 → 0.3.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 (65) hide show
  1. package/README.md +46 -0
  2. package/dist/agent-manager-2LU6KULR.js +15 -0
  3. package/dist/{channel-2WJRM7PE.js → channel-H7N4SGR2.js} +7 -7
  4. package/dist/{chunk-XZN4WPNC.js → chunk-5SKQ6J7T.js} +9 -1
  5. package/dist/chunk-DEUAVGSA.js +81 -0
  6. package/dist/{chunk-L3BQEZ4Z.js → chunk-IPIPLGME.js} +74 -13
  7. package/dist/chunk-K3NQKI34.js +10 -0
  8. package/dist/chunk-NETNFBA5.js +28 -0
  9. package/dist/{chunk-6UCG6MIX.js → chunk-RALYNMHR.js} +1 -6
  10. package/dist/chunk-VRVVQIYY.js +15 -0
  11. package/dist/{chunk-4YXYAMFT.js → chunk-VVD3XO3E.js} +7 -6
  12. package/dist/{chunk-KFNNHQK7.js → chunk-YEIHRP2J.js} +1 -1
  13. package/dist/cli.js +56 -51
  14. package/dist/connector-6LWB5PRU.js +96 -0
  15. package/dist/connectors/discord.js +22 -1
  16. package/dist/{create-23AM7H5B.js → create-RSWWMGKT.js} +22 -5
  17. package/dist/daemon-client-27KMQQKX.js +9 -0
  18. package/dist/daemon.js +162 -132
  19. package/dist/{delete-GDMSOW3U.js → delete-4ERL2QHH.js} +7 -2
  20. package/dist/{down-WTF73FE7.js → down-HRC4MQCT.js} +10 -3
  21. package/dist/{env-YKUJOFHE.js → env-DBWDTIP6.js} +3 -2
  22. package/dist/{history-7WVVKMUY.js → history-W7BD2H74.js} +9 -8
  23. package/dist/{import-42DOLBDT.js → import-6HTSSDFW.js} +143 -36
  24. package/dist/{logs-SYRQOL6B.js → logs-NHWGHNBF.js} +8 -7
  25. package/dist/{schedule-J37XQM6E.js → schedule-DKZ2E2CL.js} +41 -41
  26. package/dist/{send-PLOYEYER.js → send-5LEJXPYV.js} +3 -2
  27. package/dist/service-SA4TTMDU.js +195 -0
  28. package/dist/setup-ZMNTOJAV.js +148 -0
  29. package/dist/{start-AG7QLULK.js → start-2BSXX6BS.js} +3 -2
  30. package/dist/{status-GCNU4M3K.js → status-N23CV27T.js} +3 -2
  31. package/dist/{stop-IL5Q6NER.js → stop-DSKBIJ2D.js} +3 -2
  32. package/dist/{up-AMAP7JG7.js → up-4UGID4DM.js} +16 -33
  33. package/dist/{upgrade-DD5TNJWU.js → upgrade-BGFVRCVP.js} +4 -3
  34. package/dist/{merge-CSAVLSLY.js → variant-JPLJTS2P.js} +179 -10
  35. package/dist/web-assets/assets/index-BC5eSqbY.js +296 -0
  36. package/dist/web-assets/index.html +1 -1
  37. package/drizzle/0000_flaky_mariko_yashida.sql +34 -0
  38. package/drizzle/0001_careless_warpath.sql +12 -0
  39. package/drizzle/0002_wealthy_the_call.sql +6 -0
  40. package/drizzle/meta/0000_snapshot.json +227 -0
  41. package/drizzle/meta/0001_snapshot.json +298 -0
  42. package/drizzle/meta/0002_snapshot.json +339 -0
  43. package/drizzle/meta/_journal.json +27 -0
  44. package/package.json +5 -1
  45. package/templates/_base/.init/SOUL.md +5 -1
  46. package/templates/_base/_skills/memory/SKILL.md +2 -2
  47. package/templates/_base/_skills/volute-agent/SKILL.md +28 -11
  48. package/templates/_base/home/VOLUTE.md +4 -2
  49. package/templates/_base/src/lib/auto-commit.ts +8 -3
  50. package/templates/_base/src/lib/types.ts +6 -2
  51. package/templates/_base/src/lib/volute-server.ts +5 -0
  52. package/templates/agent-sdk/.init/CLAUDE.md +15 -13
  53. package/templates/agent-sdk/package.json.tmpl +1 -1
  54. package/templates/agent-sdk/src/agent.ts +12 -1
  55. package/templates/agent-sdk/src/lib/agent-sessions.ts +28 -4
  56. package/templates/pi/.init/AGENTS.md +11 -9
  57. package/templates/pi/src/agent.ts +16 -3
  58. package/templates/pi/src/lib/agent-sessions.ts +26 -4
  59. package/dist/agent-manager-SSJUZWOV.js +0 -13
  60. package/dist/connect-X5V5IMRW.js +0 -48
  61. package/dist/daemon-client-VN24HM5T.js +0 -10
  62. package/dist/disconnect-5JWFZ6RV.js +0 -30
  63. package/dist/fork-GRSVMBKI.js +0 -119
  64. package/dist/variants-QQIEKT6M.js +0 -60
  65. package/dist/web-assets/assets/index-DNNPoxMn.js +0 -158
@@ -5,19 +5,30 @@ import {
5
5
  import {
6
6
  exec,
7
7
  execInherit
8
- } from "./chunk-XZN4WPNC.js";
8
+ } from "./chunk-5SKQ6J7T.js";
9
+ import {
10
+ daemonFetch
11
+ } from "./chunk-VVD3XO3E.js";
12
+ import {
13
+ resolveAgentName
14
+ } from "./chunk-VRVVQIYY.js";
9
15
  import {
10
16
  parseArgs
11
17
  } from "./chunk-D424ZQGI.js";
12
18
  import {
19
+ addVariant,
13
20
  checkHealth,
14
21
  findVariant,
22
+ nextPort,
23
+ readVariants,
15
24
  removeVariant,
16
25
  resolveAgent,
17
- validateBranchName
18
- } from "./chunk-6UCG6MIX.js";
26
+ validateBranchName,
27
+ writeVariants
28
+ } from "./chunk-RALYNMHR.js";
29
+ import "./chunk-K3NQKI34.js";
19
30
 
20
- // src/commands/merge.ts
31
+ // src/commands/variant.ts
21
32
  import { existsSync, mkdirSync, writeFileSync } from "fs";
22
33
  import { resolve } from "path";
23
34
 
@@ -82,19 +93,178 @@ async function verify(port) {
82
93
  }
83
94
  }
84
95
 
85
- // src/commands/merge.ts
96
+ // src/commands/variant.ts
86
97
  async function run(args) {
98
+ const subcommand = args[0];
99
+ switch (subcommand) {
100
+ case "create":
101
+ await createVariant(args.slice(1));
102
+ break;
103
+ case "list":
104
+ await listVariants(args.slice(1));
105
+ break;
106
+ case "merge":
107
+ await mergeVariant(args.slice(1));
108
+ break;
109
+ default:
110
+ printUsage();
111
+ process.exit(subcommand ? 1 : 0);
112
+ }
113
+ }
114
+ function printUsage() {
115
+ console.error(`Usage:
116
+ volute variant create <variant> [--agent <name>] [--soul "..."] [--port N] [--no-start] [--json]
117
+ volute variant list [--agent <name>] [--json]
118
+ volute variant merge <variant> [--agent <name>] [--summary "..." --memory "..."] [--skip-verify]`);
119
+ }
120
+ async function createVariant(args) {
121
+ const { positional, flags } = parseArgs(args, {
122
+ agent: { type: "string" },
123
+ soul: { type: "string" },
124
+ port: { type: "number" },
125
+ "no-start": { type: "boolean" },
126
+ json: { type: "boolean" }
127
+ });
128
+ const agentName = resolveAgentName(flags);
129
+ const variantName = positional[0];
130
+ const { soul, port, json } = flags;
131
+ const noStart = flags["no-start"];
132
+ if (!variantName) {
133
+ console.error(
134
+ 'Usage: volute variant create <variant> [--agent <name>] [--soul "..."] [--port N] [--no-start] [--json]'
135
+ );
136
+ process.exit(1);
137
+ }
138
+ const err = validateBranchName(variantName);
139
+ if (err) {
140
+ console.error(err);
141
+ process.exit(1);
142
+ }
143
+ const { dir: projectRoot } = resolveAgent(agentName);
144
+ const variantDir = resolve(projectRoot, ".variants", variantName);
145
+ if (existsSync(variantDir)) {
146
+ console.error(`Variant directory already exists: ${variantDir}`);
147
+ process.exit(1);
148
+ }
149
+ mkdirSync(resolve(projectRoot, ".variants"), { recursive: true });
150
+ try {
151
+ await exec("git", ["worktree", "add", "-b", variantName, variantDir], { cwd: projectRoot });
152
+ } catch (e) {
153
+ const msg = e instanceof Error ? e.message : String(e);
154
+ console.error(`Failed to create worktree: ${msg}`);
155
+ process.exit(1);
156
+ }
157
+ if (!json) console.log("Installing dependencies...");
158
+ try {
159
+ if (json) {
160
+ await exec("npm", ["install"], { cwd: variantDir });
161
+ } else {
162
+ await execInherit("npm", ["install"], { cwd: variantDir });
163
+ }
164
+ } catch (e) {
165
+ const msg = e instanceof Error ? e.message : String(e);
166
+ console.error(`npm install failed: ${msg}`);
167
+ process.exit(1);
168
+ }
169
+ if (soul) {
170
+ writeFileSync(resolve(variantDir, "home/SOUL.md"), soul);
171
+ }
172
+ const variantPort = port ?? nextPort();
173
+ const variant = {
174
+ name: variantName,
175
+ branch: variantName,
176
+ path: variantDir,
177
+ port: variantPort,
178
+ created: (/* @__PURE__ */ new Date()).toISOString()
179
+ };
180
+ addVariant(agentName, variant);
181
+ if (!noStart) {
182
+ if (!json) console.log("Starting variant via daemon...");
183
+ try {
184
+ const res = await daemonFetch(
185
+ `/api/agents/${encodeURIComponent(`${agentName}@${variantName}`)}/start`,
186
+ {
187
+ method: "POST"
188
+ }
189
+ );
190
+ if (!res.ok) {
191
+ const data = await res.json();
192
+ console.error(data.error ?? "Failed to start variant");
193
+ process.exit(1);
194
+ }
195
+ } catch {
196
+ console.error("Failed to start variant. Is the daemon running? (volute up)");
197
+ console.error(
198
+ `The variant was created but not started. Use: volute start ${agentName}@${variantName}`
199
+ );
200
+ process.exit(1);
201
+ }
202
+ }
203
+ if (json) {
204
+ console.log(JSON.stringify(variant, null, 2));
205
+ } else {
206
+ console.log(`
207
+ Variant created: ${variantName}`);
208
+ console.log(` Branch: ${variant.branch}`);
209
+ console.log(` Path: ${variant.path}`);
210
+ console.log(` Port: ${variantPort}`);
211
+ }
212
+ }
213
+ async function listVariants(args) {
214
+ const { flags } = parseArgs(args, {
215
+ agent: { type: "string" },
216
+ json: { type: "boolean" }
217
+ });
218
+ const agentName = resolveAgentName(flags);
219
+ const { json } = flags;
220
+ resolveAgent(agentName);
221
+ const variants = readVariants(agentName);
222
+ if (variants.length === 0) {
223
+ if (json) {
224
+ console.log("[]");
225
+ } else {
226
+ console.log("No variants.");
227
+ }
228
+ return;
229
+ }
230
+ const results = await Promise.all(
231
+ variants.map(async (v) => {
232
+ if (!v.port) return { ...v, status: "no-server" };
233
+ const health = await checkHealth(v.port);
234
+ return { ...v, status: health.ok ? "running" : "dead" };
235
+ })
236
+ );
237
+ const updated = results.map(({ status, ...v }) => ({
238
+ ...v,
239
+ running: status === "running"
240
+ }));
241
+ writeVariants(agentName, updated);
242
+ if (json) {
243
+ console.log(JSON.stringify(results, null, 2));
244
+ return;
245
+ }
246
+ const nameW = Math.max(4, ...results.map((r) => r.name.length));
247
+ const portW = Math.max(4, ...results.map((r) => String(r.port || "-").length));
248
+ console.log(`${"NAME".padEnd(nameW)} ${"PORT".padEnd(portW)} ${"STATUS".padEnd(10)} BRANCH`);
249
+ for (const r of results) {
250
+ console.log(
251
+ `${r.name.padEnd(nameW)} ${String(r.port || "-").padEnd(portW)} ${r.status.padEnd(10)} ${r.branch}`
252
+ );
253
+ }
254
+ }
255
+ async function mergeVariant(args) {
87
256
  const { positional, flags } = parseArgs(args, {
257
+ agent: { type: "string" },
88
258
  summary: { type: "string" },
89
259
  justification: { type: "string" },
90
260
  memory: { type: "string" },
91
261
  "skip-verify": { type: "boolean" }
92
262
  });
93
- const agentName = positional[0];
94
- const variantName = positional[1];
95
- if (!agentName || !variantName) {
263
+ const agentName = resolveAgentName(flags);
264
+ const variantName = positional[0];
265
+ if (!variantName) {
96
266
  console.error(
97
- "Usage: volute merge <agent> <variant> [--summary '...'] [--justification '...'] [--memory '...'] [--skip-verify]"
267
+ "Usage: volute variant merge <variant> [--agent <name>] [--summary '...'] [--justification '...'] [--memory '...'] [--skip-verify]"
98
268
  );
99
269
  process.exit(1);
100
270
  }
@@ -196,7 +366,6 @@ async function run(args) {
196
366
  );
197
367
  if (process.env.VOLUTE_SUPERVISOR) return;
198
368
  try {
199
- const { daemonFetch } = await import("./daemon-client-VN24HM5T.js");
200
369
  console.log("Restarting agent via daemon...");
201
370
  const res = await daemonFetch(`/api/agents/${encodeURIComponent(agentName)}/restart`, {
202
371
  method: "POST"