volute 0.20.0 → 0.21.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 (92) hide show
  1. package/README.md +7 -7
  2. package/dist/{activity-events-OMXKXD5N.js → activity-events-3WHHCOBB.js} +3 -4
  3. package/dist/{archive-ZCFOSTKB.js → archive-4ZQYK5MN.js} +4 -2
  4. package/dist/auth-HM2RSPY7.js +37 -0
  5. package/dist/{channel-PUQKGSQM.js → channel-BOOMFULW.js} +2 -2
  6. package/dist/{chunk-IKMY5X76.js → chunk-5462YKWP.js} +12 -9
  7. package/dist/{chunk-PUVXOZ6T.js → chunk-7LPTHFIL.js} +63 -64
  8. package/dist/{chunk-UU7A7KLB.js → chunk-A4S7H6G6.js} +5 -7
  9. package/dist/chunk-AKPFNL7L.js +148 -0
  10. package/dist/{chunk-EBGCNDMM.js → chunk-B2CPS4QU.js} +128 -114
  11. package/dist/{chunk-FCDU5BFX.js → chunk-HFCBO2GL.js} +2 -2
  12. package/dist/{chunk-GZ7DW4YL.js → chunk-HGCDWKSP.js} +2 -2
  13. package/dist/{chunk-DYZGP3EW.js → chunk-IPJXU366.js} +1 -1
  14. package/dist/{chunk-7UFKREVW.js → chunk-J5A3DF2U.js} +2 -2
  15. package/dist/{chunk-WC6ZHVRL.js → chunk-KFI7TQJ6.js} +2 -2
  16. package/dist/{chunk-AW7P4EVV.js → chunk-KTJGZ7M7.js} +55 -7
  17. package/dist/{chunk-TIWH32HP.js → chunk-L3LHXZD7.js} +3 -3
  18. package/dist/{chunk-OGXOMR65.js → chunk-NWPT4ASZ.js} +1 -1
  19. package/dist/{chunk-FGSYHIS3.js → chunk-OGZYB5GL.js} +252 -296
  20. package/dist/{chunk-SCUDS4US.js → chunk-ON3FF5JA.js} +1 -1
  21. package/dist/{chunk-O6ASDHFO.js → chunk-PC6R6UUW.js} +4 -4
  22. package/dist/{chunk-VDWCHYTS.js → chunk-PHU4DEAJ.js} +1 -1
  23. package/dist/{chunk-7NO7EV5Z.js → chunk-Q7AITQ44.js} +2 -2
  24. package/dist/{chunk-32VR2EOH.js → chunk-QUJUKM4U.js} +2 -2
  25. package/dist/{chunk-NSE7VJQA.js → chunk-SGPEZ32F.js} +29 -1
  26. package/dist/{chunk-RHEGSQFJ.js → chunk-WSLPZF72.js} +1 -1
  27. package/dist/cli.js +57 -119
  28. package/dist/{connector-JBVNZ7VK.js → connector-PYT5UOTZ.js} +6 -6
  29. package/dist/connectors/discord.js +2 -2
  30. package/dist/connectors/slack.js +2 -2
  31. package/dist/connectors/telegram.js +2 -2
  32. package/dist/{create-HP4OVVHF.js → create-WIDA3M4C.js} +1 -1
  33. package/dist/{daemon-client-ITWUCNFO.js → daemon-client-ZHCDL4RS.js} +2 -2
  34. package/dist/{daemon-restart-KPSWNYTH.js → daemon-restart-BH67ZOTE.js} +6 -6
  35. package/dist/daemon.js +1538 -687
  36. package/dist/{delete-BSU7K3RY.js → delete-LOIANQGD.js} +1 -1
  37. package/dist/down-LIOQ5JDH.js +14 -0
  38. package/dist/{env-A3LMO777.js → env-4PHIHTF4.js} +2 -2
  39. package/dist/{export-6QBUOQGC.js → export-XD6PJBQP.js} +19 -8
  40. package/dist/{file-C57SK5DK.js → file-X4L5TTOL.js} +2 -2
  41. package/dist/{history-WNK3DFUM.js → history-HTEKRNID.js} +2 -2
  42. package/dist/{import-XEC34Y4Z.js → import-E433B4KG.js} +3 -3
  43. package/dist/{log-PPPZDVEF.js → log-SRO5Q6AD.js} +2 -2
  44. package/dist/{login-HNH3EUQV.js → login-UO6AOVEA.js} +4 -4
  45. package/dist/{logout-I5CB5UZS.js → logout-UKD5LA37.js} +2 -2
  46. package/dist/{logs-SF2IMJN4.js → logs-HNTNNBDW.js} +2 -2
  47. package/dist/{merge-33C237A4.js → merge-B6SYTGI7.js} +2 -2
  48. package/dist/{mind-Z7CKD6DG.js → mind-BIDOF65R.js} +27 -11
  49. package/dist/{mind-activity-tracker-624QLQLC.js → mind-activity-tracker-PGC3DBJ7.js} +4 -5
  50. package/dist/{mind-manager-3DMYKZPB.js → mind-manager-3V2NXX4I.js} +5 -6
  51. package/dist/{package-4NHAVUUI.js → package-HQR52XSG.js} +1 -1
  52. package/dist/{pages-4DGQT7ZA.js → pages-KQBR5TAZ.js} +6 -6
  53. package/dist/{publish-TAJUET4I.js → publish-OJ4QMXVZ.js} +6 -6
  54. package/dist/{pull-XAEWQJ47.js → pull-GRQAXM2E.js} +2 -2
  55. package/dist/{register-VSPCMHKX.js → register-U2UO6TC4.js} +5 -5
  56. package/dist/registry-D2BSQ2X5.js +42 -0
  57. package/dist/{restart-IQKMCK5M.js → restart-CIDAKGG2.js} +3 -6
  58. package/dist/{schedule-FFZG23IW.js → schedule-NLR3LZLY.js} +2 -2
  59. package/dist/{seed-J43YDKXG.js → seed-3H2MRREW.js} +2 -2
  60. package/dist/{send-KVIZIGCE.js → send-RP2TA7SG.js} +132 -36
  61. package/dist/{service-LUR7WDO7.js → service-TVNEORO7.js} +31 -13
  62. package/dist/{setup-52YRV7VP.js → setup-OZDYCKDI.js} +9 -34
  63. package/dist/{shared-KO35ZM44.js → shared-DCQ2UXOM.js} +4 -4
  64. package/dist/{skill-BCVNI6TV.js → skill-Q2Y6PQ3L.js} +2 -2
  65. package/dist/skills/orientation/SKILL.md +2 -2
  66. package/dist/skills/volute-mind/SKILL.md +5 -5
  67. package/dist/{sprout-QN7Y4VVO.js → sprout-6Z6C42YM.js} +34 -30
  68. package/dist/{start-I5JYB65M.js → start-JR6CUUWF.js} +3 -6
  69. package/dist/{status-D7E5HHBV.js → status-5XDGYHKP.js} +2 -2
  70. package/dist/{status-FU2PFVVF.js → status-LV34BG6G.js} +3 -3
  71. package/dist/{status-4ESFLGH4.js → status-Z7NAFMBI.js} +5 -5
  72. package/dist/{stop-NBVKEFQQ.js → stop-VKPGK25U.js} +2 -5
  73. package/dist/template-hash-BIMA4ILT.js +8 -0
  74. package/dist/{up-FS7CKM6V.js → up-7BGDMFRT.js} +5 -5
  75. package/dist/{update-FJIHDJKM.js → update-4WT7VWHW.js} +5 -5
  76. package/dist/{update-check-MWE5AH4U.js → update-check-F5Z3ALXX.js} +2 -2
  77. package/dist/{upgrade-AIT24B5I.js → upgrade-ZEC2GGFO.js} +1 -1
  78. package/dist/{variant-63ZWO2W7.js → variant-A4I7PHXS.js} +16 -24
  79. package/dist/version-notify-TFS2U5CF.js +173 -0
  80. package/dist/web-assets/assets/index-BR3gtK3E.css +1 -0
  81. package/dist/web-assets/assets/index-CWmrZRQd.js +64 -0
  82. package/dist/web-assets/index.html +2 -2
  83. package/package.json +1 -1
  84. package/dist/chunk-5XNT2472.js +0 -36
  85. package/dist/chunk-UJ6GHNR7.js +0 -675
  86. package/dist/db-C2CJ46ZU.js +0 -10
  87. package/dist/delivery-manager-CSG7LXA4.js +0 -16
  88. package/dist/down-ZY35KMHR.js +0 -14
  89. package/dist/schema-GFH6RV3W.js +0 -26
  90. package/dist/variants-JAGWGBXG.js +0 -26
  91. package/dist/web-assets/assets/index-CUZTZzaW.js +0 -64
  92. package/dist/web-assets/assets/index-adVuCkqy.css +0 -1
@@ -1,23 +1,122 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/lib/variants.ts
4
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
5
- import { resolve as resolve2 } from "path";
6
-
7
3
  // src/lib/registry.ts
8
- import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
4
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "fs";
9
5
  import { homedir } from "os";
10
- import { dirname, resolve } from "path";
6
+ import { dirname, resolve as resolve2 } from "path";
11
7
  import { fileURLToPath } from "url";
8
+
9
+ // src/lib/variants.ts
10
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
11
+ import { resolve } from "path";
12
+ function variantsPath() {
13
+ return resolve(voluteHome(), "variants.json");
14
+ }
15
+ function readAllVariants() {
16
+ const path = variantsPath();
17
+ if (!existsSync(path)) return {};
18
+ try {
19
+ return JSON.parse(readFileSync(path, "utf-8"));
20
+ } catch {
21
+ return {};
22
+ }
23
+ }
24
+ function writeAllVariants(all) {
25
+ mkdirSync(voluteHome(), { recursive: true });
26
+ writeFileSync(variantsPath(), `${JSON.stringify(all, null, 2)}
27
+ `);
28
+ }
29
+ function readVariants(mindName) {
30
+ return readAllVariants()[mindName] ?? [];
31
+ }
32
+ function writeVariants(mindName, variants) {
33
+ const all = readAllVariants();
34
+ if (variants.length === 0) {
35
+ delete all[mindName];
36
+ } else {
37
+ all[mindName] = variants;
38
+ }
39
+ writeAllVariants(all);
40
+ }
41
+ function addVariant(mindName, variant) {
42
+ const variants = readVariants(mindName);
43
+ const filtered = variants.filter((v) => v.name !== variant.name);
44
+ filtered.push(variant);
45
+ writeVariants(mindName, filtered);
46
+ }
47
+ function removeVariant(mindName, name) {
48
+ const variants = readVariants(mindName);
49
+ writeVariants(
50
+ mindName,
51
+ variants.filter((v) => v.name !== name)
52
+ );
53
+ }
54
+ function findVariant(mindName, name) {
55
+ return readVariants(mindName).find((v) => v.name === name);
56
+ }
57
+ function setVariantRunning(mindName, variantName, running) {
58
+ const all = readAllVariants();
59
+ const variants = all[mindName] ?? [];
60
+ const variant = variants.find((v) => v.name === variantName);
61
+ if (variant) {
62
+ variant.running = running;
63
+ all[mindName] = variants;
64
+ writeAllVariants(all);
65
+ }
66
+ }
67
+ function getAllRunningVariants() {
68
+ const all = readAllVariants();
69
+ const result = [];
70
+ for (const [mindName, variants] of Object.entries(all)) {
71
+ for (const variant of variants) {
72
+ if (variant.running) {
73
+ result.push({ mindName, variant });
74
+ }
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ function removeAllVariants(mindName) {
80
+ const all = readAllVariants();
81
+ delete all[mindName];
82
+ writeAllVariants(all);
83
+ }
84
+ async function checkHealth(port) {
85
+ try {
86
+ const res = await fetch(`http://127.0.0.1:${port}/health`, {
87
+ signal: AbortSignal.timeout(2e3)
88
+ });
89
+ if (!res.ok) return { ok: false };
90
+ const data = await res.json();
91
+ return { ok: true, name: data.name };
92
+ } catch {
93
+ return { ok: false };
94
+ }
95
+ }
96
+ var SAFE_BRANCH_RE = /^[a-zA-Z0-9._\-/]+$/;
97
+ function validateBranchName(branch) {
98
+ if (!SAFE_BRANCH_RE.test(branch)) {
99
+ return `Invalid branch name: ${branch}. Only alphanumeric, '.', '_', '-', '/' allowed.`;
100
+ }
101
+ if (branch.includes("..")) {
102
+ return `Invalid branch name: ${branch}. '..' not allowed.`;
103
+ }
104
+ return null;
105
+ }
106
+
107
+ // src/lib/registry.ts
12
108
  var registryCache = null;
13
109
  function initRegistryCache() {
14
110
  registryCache = readRegistryFromDisk();
15
111
  }
112
+ function getRegistryCache() {
113
+ return registryCache;
114
+ }
16
115
  function readRegistryFromDisk() {
17
- const registryPath = resolve(voluteHome(), "minds.json");
18
- if (!existsSync(registryPath)) return [];
116
+ const registryPath = resolve2(voluteHome(), "minds.json");
117
+ if (!existsSync2(registryPath)) return [];
19
118
  try {
20
- const entries = JSON.parse(readFileSync(registryPath, "utf-8"));
119
+ const entries = JSON.parse(readFileSync2(registryPath, "utf-8"));
21
120
  return entries.map((e) => ({
22
121
  ...e,
23
122
  running: e.running ?? false,
@@ -35,11 +134,11 @@ function voluteHome() {
35
134
  'VOLUTE_HOME must be set when running from source. For tests, run via "npm test" or add "--import ./test/setup.ts".'
36
135
  );
37
136
  }
38
- return resolve(homedir(), ".volute");
137
+ return resolve2(homedir(), ".volute");
39
138
  }
40
139
  function ensureVoluteHome() {
41
- const mindsBase = process.env.VOLUTE_MINDS_DIR ?? resolve(voluteHome(), "minds");
42
- mkdirSync(mindsBase, { recursive: true });
140
+ const mindsBase = process.env.VOLUTE_MINDS_DIR ?? resolve2(voluteHome(), "minds");
141
+ mkdirSync2(mindsBase, { recursive: true });
43
142
  }
44
143
  function readRegistry() {
45
144
  if (registryCache) return registryCache;
@@ -48,9 +147,9 @@ function readRegistry() {
48
147
  function writeRegistry(entries) {
49
148
  if (registryCache) registryCache = entries;
50
149
  ensureVoluteHome();
51
- const registryPath = resolve(voluteHome(), "minds.json");
150
+ const registryPath = resolve2(voluteHome(), "minds.json");
52
151
  const tmpPath = `${registryPath}.tmp`;
53
- writeFileSync(tmpPath, `${JSON.stringify(entries, null, 2)}
152
+ writeFileSync2(tmpPath, `${JSON.stringify(entries, null, 2)}
54
153
  `);
55
154
  renameSync(tmpPath, registryPath);
56
155
  }
@@ -92,17 +191,25 @@ function setMindStage(name, stage) {
92
191
  writeRegistry(entries);
93
192
  }
94
193
  }
194
+ function setMindTemplateHash(name, hash) {
195
+ const entries = readRegistry();
196
+ const entry = entries.find((e) => e.name === name);
197
+ if (entry) {
198
+ entry.templateHash = hash;
199
+ writeRegistry(entries);
200
+ }
201
+ }
95
202
  function findMind(name) {
96
203
  return readRegistry().find((e) => e.name === name);
97
204
  }
98
205
  function mindDir(name) {
99
206
  if (process.env.VOLUTE_MINDS_DIR) {
100
- return resolve(process.env.VOLUTE_MINDS_DIR, name);
207
+ return resolve2(process.env.VOLUTE_MINDS_DIR, name);
101
208
  }
102
- return resolve(voluteHome(), "minds", name);
209
+ return resolve2(voluteHome(), "minds", name);
103
210
  }
104
211
  function stateDir(name) {
105
- return resolve(voluteHome(), "state", name);
212
+ return resolve2(voluteHome(), "state", name);
106
213
  }
107
214
  function nextPort() {
108
215
  const entries = readRegistry();
@@ -131,7 +238,7 @@ function resolveMind(name) {
131
238
  throw new Error(`Unknown mind: ${baseName}`);
132
239
  }
133
240
  const dir = mindDir(baseName);
134
- if (!existsSync(dir)) {
241
+ if (!existsSync2(dir)) {
135
242
  throw new Error(`Mind directory missing: ${dir}`);
136
243
  }
137
244
  if (variantName) {
@@ -144,102 +251,6 @@ function resolveMind(name) {
144
251
  return { entry, dir };
145
252
  }
146
253
 
147
- // src/lib/variants.ts
148
- function variantsPath() {
149
- return resolve2(voluteHome(), "variants.json");
150
- }
151
- function readAllVariants() {
152
- const path = variantsPath();
153
- if (!existsSync2(path)) return {};
154
- try {
155
- return JSON.parse(readFileSync2(path, "utf-8"));
156
- } catch {
157
- return {};
158
- }
159
- }
160
- function writeAllVariants(all) {
161
- mkdirSync2(voluteHome(), { recursive: true });
162
- writeFileSync2(variantsPath(), `${JSON.stringify(all, null, 2)}
163
- `);
164
- }
165
- function readVariants(mindName) {
166
- return readAllVariants()[mindName] ?? [];
167
- }
168
- function writeVariants(mindName, variants) {
169
- const all = readAllVariants();
170
- if (variants.length === 0) {
171
- delete all[mindName];
172
- } else {
173
- all[mindName] = variants;
174
- }
175
- writeAllVariants(all);
176
- }
177
- function addVariant(mindName, variant) {
178
- const variants = readVariants(mindName);
179
- const filtered = variants.filter((v) => v.name !== variant.name);
180
- filtered.push(variant);
181
- writeVariants(mindName, filtered);
182
- }
183
- function removeVariant(mindName, name) {
184
- const variants = readVariants(mindName);
185
- writeVariants(
186
- mindName,
187
- variants.filter((v) => v.name !== name)
188
- );
189
- }
190
- function findVariant(mindName, name) {
191
- return readVariants(mindName).find((v) => v.name === name);
192
- }
193
- function setVariantRunning(mindName, variantName, running) {
194
- const all = readAllVariants();
195
- const variants = all[mindName] ?? [];
196
- const variant = variants.find((v) => v.name === variantName);
197
- if (variant) {
198
- variant.running = running;
199
- all[mindName] = variants;
200
- writeAllVariants(all);
201
- }
202
- }
203
- function getAllRunningVariants() {
204
- const all = readAllVariants();
205
- const result = [];
206
- for (const [mindName, variants] of Object.entries(all)) {
207
- for (const variant of variants) {
208
- if (variant.running) {
209
- result.push({ mindName, variant });
210
- }
211
- }
212
- }
213
- return result;
214
- }
215
- function removeAllVariants(mindName) {
216
- const all = readAllVariants();
217
- delete all[mindName];
218
- writeAllVariants(all);
219
- }
220
- async function checkHealth(port) {
221
- try {
222
- const res = await fetch(`http://127.0.0.1:${port}/health`, {
223
- signal: AbortSignal.timeout(2e3)
224
- });
225
- if (!res.ok) return { ok: false };
226
- const data = await res.json();
227
- return { ok: true, name: data.name };
228
- } catch {
229
- return { ok: false };
230
- }
231
- }
232
- var SAFE_BRANCH_RE = /^[a-zA-Z0-9._\-/]+$/;
233
- function validateBranchName(branch) {
234
- if (!SAFE_BRANCH_RE.test(branch)) {
235
- return `Invalid branch name: ${branch}. Only alphanumeric, '.', '_', '-', '/' allowed.`;
236
- }
237
- if (branch.includes("..")) {
238
- return `Invalid branch name: ${branch}. '..' not allowed.`;
239
- }
240
- return null;
241
- }
242
-
243
254
  export {
244
255
  readVariants,
245
256
  writeVariants,
@@ -252,14 +263,17 @@ export {
252
263
  checkHealth,
253
264
  validateBranchName,
254
265
  initRegistryCache,
266
+ getRegistryCache,
255
267
  voluteHome,
256
268
  ensureVoluteHome,
257
269
  readRegistry,
270
+ writeRegistry,
258
271
  validateMindName,
259
272
  addMind,
260
273
  removeMind,
261
274
  setMindRunning,
262
275
  setMindStage,
276
+ setMindTemplateHash,
263
277
  findMind,
264
278
  mindDir,
265
279
  stateDir,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteHome
4
- } from "./chunk-EBGCNDMM.js";
4
+ } from "./chunk-B2CPS4QU.js";
5
5
 
6
6
  // src/lib/systems-config.ts
7
7
  import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
@@ -18,7 +18,7 @@ function readSystemsConfig() {
18
18
  try {
19
19
  data = JSON.parse(raw);
20
20
  } catch {
21
- console.error(`Warning: ${path} contains invalid JSON. Run "volute logout" and re-login.`);
21
+ console.error(`Warning: ${path} contains invalid JSON. Run "volute auth logout" and re-login.`);
22
22
  return null;
23
23
  }
24
24
  if (!data.apiKey || !data.system) return null;
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  publish
4
- } from "./chunk-UU7A7KLB.js";
4
+ } from "./chunk-A4S7H6G6.js";
5
5
  import {
6
6
  logger_default
7
7
  } from "./chunk-YUIHSKR6.js";
8
8
 
9
- // src/lib/mind-activity-tracker.ts
9
+ // src/lib/events/mind-activity-tracker.ts
10
10
  var IDLE_TIMEOUT_MS = 2 * 60 * 1e3;
11
11
  var minds = /* @__PURE__ */ new Map();
12
12
  function getState(mind) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  wrapForIsolation
4
- } from "./chunk-OGXOMR65.js";
4
+ } from "./chunk-NWPT4ASZ.js";
5
5
 
6
6
  // src/lib/exec.ts
7
7
  import { execFile as execFileCb, execFileSync, spawn } from "child_process";
@@ -4,13 +4,13 @@ import {
4
4
  modeLabel,
5
5
  pollHealth,
6
6
  startService
7
- } from "./chunk-32VR2EOH.js";
7
+ } from "./chunk-QUJUKM4U.js";
8
8
  import {
9
9
  parseArgs
10
10
  } from "./chunk-D424ZQGI.js";
11
11
  import {
12
12
  voluteHome
13
- } from "./chunk-EBGCNDMM.js";
13
+ } from "./chunk-B2CPS4QU.js";
14
14
 
15
15
  // src/commands/up.ts
16
16
  import { spawn } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  voluteHome
4
- } from "./chunk-EBGCNDMM.js";
4
+ } from "./chunk-B2CPS4QU.js";
5
5
 
6
6
  // src/lib/daemon-client.ts
7
7
  import { existsSync, readFileSync } from "fs";
@@ -11,7 +11,7 @@ function readDaemonConfig() {
11
11
  if (!existsSync(configPath)) {
12
12
  if (existsSync("/etc/systemd/system/volute.service") && !process.env.VOLUTE_HOME) {
13
13
  console.error("Volute is running as a system service but VOLUTE_HOME is not set.");
14
- console.error("Re-run setup to update the CLI wrapper: sudo volute setup");
14
+ console.error("Re-run setup to update the CLI wrapper: sudo volute service install --system");
15
15
  console.error("Then start a new shell or run: source /etc/profile.d/volute.sh");
16
16
  } else {
17
17
  console.error("Volute is not running. Start with: volute up");
@@ -2,9 +2,10 @@
2
2
  import {
3
3
  mindDir,
4
4
  stateDir
5
- } from "./chunk-EBGCNDMM.js";
5
+ } from "./chunk-B2CPS4QU.js";
6
6
 
7
7
  // src/lib/archive.ts
8
+ import { execFileSync } from "child_process";
8
9
  import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
9
10
  import { join, relative, resolve } from "path";
10
11
  import AdmZip from "adm-zip";
@@ -26,10 +27,32 @@ function walkDir(dir, base, skipSessions) {
26
27
  }
27
28
  return results;
28
29
  }
30
+ function gitListFiles(dir) {
31
+ try {
32
+ const tracked = execFileSync("git", ["ls-files"], { cwd: dir, encoding: "utf-8" });
33
+ const untracked = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
34
+ cwd: dir,
35
+ encoding: "utf-8"
36
+ });
37
+ const files = [...tracked.trim().split("\n"), ...untracked.trim().split("\n")].filter(Boolean);
38
+ return [...new Set(files)];
39
+ } catch (err) {
40
+ const msg = err instanceof Error ? err.message : String(err);
41
+ if (!msg.includes("not a git repository")) {
42
+ console.error(`Warning: git ls-files failed, .gitignore rules will not apply: ${msg}`);
43
+ }
44
+ return null;
45
+ }
46
+ }
47
+ function isHomeOnlyArchive(manifest) {
48
+ return manifest.format === "home-only";
49
+ }
29
50
  function createExportArchive(options) {
30
51
  const {
31
52
  name,
32
53
  template,
54
+ stage,
55
+ includeSrc = false,
33
56
  includeEnv = false,
34
57
  includeIdentity = false,
35
58
  includeConnectors = false,
@@ -39,12 +62,34 @@ function createExportArchive(options) {
39
62
  const dir = mindDir(name);
40
63
  const state = stateDir(name);
41
64
  const zip = new AdmZip();
42
- const files = walkDir(dir, void 0, includeSessions);
43
- for (const relPath of files) {
44
- if (!includeIdentity && relPath.startsWith(join(".mind", "identity"))) continue;
45
- if (!includeConnectors && relPath.startsWith(join(".mind", "connectors"))) continue;
46
- const fullPath = resolve(dir, relPath);
47
- zip.addFile(`mind/${relPath}`, readFileSync(fullPath));
65
+ const format = includeSrc ? "full" : "home-only";
66
+ if (includeSrc) {
67
+ const files = walkDir(dir, void 0, includeSessions);
68
+ for (const relPath of files) {
69
+ if (!includeIdentity && relPath.startsWith(join(".mind", "identity"))) continue;
70
+ if (!includeConnectors && relPath.startsWith(join(".mind", "connectors"))) continue;
71
+ const fullPath = resolve(dir, relPath);
72
+ zip.addFile(`mind/${relPath}`, readFileSync(fullPath));
73
+ }
74
+ } else {
75
+ const gitFiles = gitListFiles(dir);
76
+ const homeFiles = gitFiles ? gitFiles.filter((f) => f.startsWith("home/") || f.startsWith("home\\")) : walkDir(resolve(dir, "home"), dir);
77
+ for (const relPath of homeFiles) {
78
+ const fullPath = resolve(dir, relPath);
79
+ if (existsSync(fullPath)) {
80
+ zip.addFile(`mind/${relPath}`, readFileSync(fullPath));
81
+ }
82
+ }
83
+ const mindInternalDir = resolve(dir, ".mind");
84
+ if (existsSync(mindInternalDir)) {
85
+ const mindFiles = walkDir(mindInternalDir, dir, includeSessions);
86
+ for (const relPath of mindFiles) {
87
+ if (!includeIdentity && relPath.startsWith(join(".mind", "identity"))) continue;
88
+ if (!includeConnectors && relPath.startsWith(join(".mind", "connectors"))) continue;
89
+ const fullPath = resolve(dir, relPath);
90
+ zip.addFile(`mind/${relPath}`, readFileSync(fullPath));
91
+ }
92
+ }
48
93
  }
49
94
  if (existsSync(state)) {
50
95
  const channelsPath = resolve(state, "channels.json");
@@ -81,6 +126,8 @@ function createExportArchive(options) {
81
126
  template,
82
127
  voluteVersion,
83
128
  exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
129
+ format,
130
+ stage,
84
131
  includes: {
85
132
  env: includeEnv,
86
133
  identity: includeIdentity,
@@ -152,6 +199,7 @@ function extractArchive(archivePath, destDir) {
152
199
  }
153
200
 
154
201
  export {
202
+ isHomeOnlyArchive,
155
203
  createExportArchive,
156
204
  addHistoryToArchive,
157
205
  readManifest,
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-YUIHSKR6.js";
5
5
  import {
6
6
  gitExec
7
- } from "./chunk-DYZGP3EW.js";
7
+ } from "./chunk-IPJXU366.js";
8
8
  import {
9
9
  isIsolationEnabled,
10
10
  mindUserName
11
- } from "./chunk-OGXOMR65.js";
11
+ } from "./chunk-NWPT4ASZ.js";
12
12
  import {
13
13
  voluteHome
14
- } from "./chunk-EBGCNDMM.js";
14
+ } from "./chunk-B2CPS4QU.js";
15
15
 
16
16
  // src/lib/shared.ts
17
17
  import { execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  validateMindName
4
- } from "./chunk-EBGCNDMM.js";
4
+ } from "./chunk-B2CPS4QU.js";
5
5
 
6
6
  // src/lib/isolation.ts
7
7
  import { execFileSync } from "child_process";