volute 0.28.0 → 0.30.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 (134) hide show
  1. package/README.md +127 -18
  2. package/dist/{accept-666DIZX2.js → accept-E3PAH3QJ.js} +2 -2
  3. package/dist/{activity-events-BBIEA2F4.js → activity-events-BKBPPUBP.js} +2 -2
  4. package/dist/ai-service-VAJT5UBS.js +29 -0
  5. package/dist/api.d.ts +586 -529
  6. package/dist/{archive-UA4BDFXQ.js → archive-WWDBWYN2.js} +2 -2
  7. package/dist/{bridge-FQHZL3MC.js → bridge-RO37CUFM.js} +2 -2
  8. package/dist/{chat-M4SX42JD.js → chat-TCUNPFGO.js} +8 -8
  9. package/dist/{chunk-IAYBDWVG.js → chunk-2C2VXEBB.js} +147 -2
  10. package/dist/chunk-2NDZC3S7.js +1330 -0
  11. package/dist/{chunk-IKRVFPWU.js → chunk-7D47T4RB.js} +3 -2
  12. package/dist/chunk-A6TUJJ3L.js +19 -0
  13. package/dist/{chunk-AW7PFDVN.js → chunk-CVH6Y2YG.js} +1 -1
  14. package/dist/{chunk-XBLSAVJF.js → chunk-DTC6EH5I.js} +1 -1
  15. package/dist/chunk-EFP3PE6C.js +232 -0
  16. package/dist/{chunk-JGFVMROS.js → chunk-EFVHR7KH.js} +1 -1
  17. package/dist/{chunk-K5NAC55T.js → chunk-FSM45XD5.js} +2 -2
  18. package/dist/{chunk-LAC664WU.js → chunk-FXHXHI2A.js} +42 -24
  19. package/dist/{chunk-RKQEHRBB.js → chunk-G3GBKZGG.js} +1 -1
  20. package/dist/{chunk-H7OZRFJB.js → chunk-HHTXM4JT.js} +0 -49
  21. package/dist/{chunk-J4IBNXGJ.js → chunk-IKHDUZRH.js} +4 -3
  22. package/dist/{chunk-MD4C26II.js → chunk-JGFRDMR6.js} +1 -1
  23. package/dist/{chunk-POSXWWTA.js → chunk-LIRWLNAK.js} +26 -12
  24. package/dist/{chunk-NI5FFCCS.js → chunk-MDPCSXZ4.js} +35 -11
  25. package/dist/chunk-NSBFETWP.js +188 -0
  26. package/dist/{chunk-VIVMW2H2.js → chunk-P27RV5WM.js} +1 -1
  27. package/dist/{chunk-EHYDTZTF.js → chunk-P7VFDSSG.js} +2 -2
  28. package/dist/{chunk-AAPXKR5V.js → chunk-QVAQ5454.js} +181 -544
  29. package/dist/{chunk-HDN7MNGD.js → chunk-S5LR3XYJ.js} +1 -1
  30. package/dist/{chunk-2YP2TVDT.js → chunk-UPA6COHU.js} +5 -5
  31. package/dist/{chunk-AKPFNL7L.js → chunk-VGWJSNHS.js} +1 -1
  32. package/dist/{chunk-SGVNFZHW.js → chunk-W5OOPLNP.js} +3 -3
  33. package/dist/{chunk-2WPW7OT6.js → chunk-ZWKTUQEL.js} +1 -1
  34. package/dist/cli.js +25 -26
  35. package/dist/clock-G3ALCMLJ.js +263 -0
  36. package/dist/{cloud-sync-HDL6PHZI.js → cloud-sync-JV4LJOK3.js} +14 -12
  37. package/dist/connectors/discord-bridge.js +1 -1
  38. package/dist/connectors/slack-bridge.js +1 -1
  39. package/dist/connectors/telegram-bridge.js +1 -1
  40. package/dist/{conversations-M2K4253F.js → conversations-7KVQV7EZ.js} +9 -3
  41. package/dist/create-JTLS7GX3.js +70 -0
  42. package/dist/{create-QWV73WXD.js → create-VQSQHJQW.js} +1 -1
  43. package/dist/{daemon-client-I42FK2BF.js → daemon-client-BCTFGVCZ.js} +2 -2
  44. package/dist/{daemon-restart-G4B2OYAB.js → daemon-restart-4JGBHEJ4.js} +7 -7
  45. package/dist/daemon.js +1474 -1124
  46. package/dist/{db-IC4J52XQ.js → db-HMFPIRO2.js} +1 -1
  47. package/dist/{delete-4JYGD4VN.js → delete-JESHKE7F.js} +1 -1
  48. package/dist/down-NGBMGORS.js +14 -0
  49. package/dist/{env-YJMUMFIY.js → env-CLXXT7M2.js} +2 -2
  50. package/dist/{export-BOJQWBMA.js → export-EGA5M5PB.js} +3 -3
  51. package/dist/extension-WZ4SUPJB.js +174 -0
  52. package/dist/extensions-ECO4RPFQ.js +27 -0
  53. package/dist/{files-M546TKVN.js → files-4VEJDASH.js} +3 -3
  54. package/dist/{history-ALPTNB3I.js → history-EJMMLXDO.js} +17 -2
  55. package/dist/{import-SRTQXBGH.js → import-YCGPMBSI.js} +3 -3
  56. package/dist/{join-J4QU42DL.js → join-2GBJKZEN.js} +1 -1
  57. package/dist/{list-R73GENNL.js → list-Q6O7FGAN.js} +2 -2
  58. package/dist/{login-3QZNR2DF.js → login-RET5WESK.js} +2 -2
  59. package/dist/{login-BKP3AFWN.js → login-RL6AU2SM.js} +3 -3
  60. package/dist/{logout-T53VKCPU.js → logout-CGAGJN3L.js} +2 -2
  61. package/dist/{logout-IQK7FNEK.js → logout-JRPBEMMR.js} +3 -3
  62. package/dist/message-delivery-6YMVNOEC.js +28 -0
  63. package/dist/{migrate-registry-to-db-XC7T5B7P.js → migrate-registry-to-db-FK35IPEH.js} +1 -1
  64. package/dist/{mind-S5V6CK5W.js → mind-LUWRQUQ5.js} +17 -17
  65. package/dist/{mind-activity-tracker-EN6XNXPF.js → mind-activity-tracker-VYN2ZZ2M.js} +3 -3
  66. package/dist/{mind-list-UPJ75GPI.js → mind-list-V5WW5DUA.js} +2 -2
  67. package/dist/{mind-manager-S6ILZVX3.js → mind-manager-YFCOIAAX.js} +6 -6
  68. package/dist/{mind-sleep-BTSWQNAC.js → mind-sleep-R6PTNNW4.js} +2 -2
  69. package/dist/{mind-status-TK5AETEM.js → mind-status-I4ISFJ6I.js} +2 -2
  70. package/dist/{mind-wake-SBAKIDVP.js → mind-wake-67ZQEWAV.js} +2 -2
  71. package/dist/{package-CG4RWUGP.js → package-S2OAA5ZA.js} +11 -5
  72. package/dist/pages-watcher-Z3PKNROC.js +21 -0
  73. package/dist/{read-36UFXN3G.js → read-WQMPTSN2.js} +2 -2
  74. package/dist/{register-CHREOMJ3.js → register-NZDSTLP3.js} +3 -3
  75. package/dist/{registry-NDNOOYG4.js → registry-ODSALQQL.js} +1 -1
  76. package/dist/{reject-LXIZFJ4Q.js → reject-2HZOJEIJ.js} +2 -2
  77. package/dist/{restart-6ESL3NBO.js → restart-QHS3NT64.js} +2 -2
  78. package/dist/{sandbox-5BW5HPXM.js → sandbox-O5FUSF43.js} +3 -3
  79. package/dist/{seed-SSUCYYDF.js → seed-WUQMPLDM.js} +1 -1
  80. package/dist/{send-TAOEZ4NH.js → send-OAN3RYYY.js} +20 -6
  81. package/dist/{setup-JHL5ZEST.js → setup-QMDK5RZX.js} +2 -2
  82. package/dist/{setup-RXYVGGT7.js → setup-XJH3E7YM.js} +45 -14
  83. package/dist/{skill-AUAQTSP5.js → skill-FZIN4W4Q.js} +65 -3
  84. package/dist/skills/dreaming/references/INSTALL.md +3 -17
  85. package/dist/skills/volute-mind/SKILL.md +45 -27
  86. package/dist/sleep-manager-O7YQFCV5.js +30 -0
  87. package/dist/{split-TKJ5OT3P.js → split-EXYGGGQN.js} +1 -1
  88. package/dist/{sprout-UNT7LKKE.js → sprout-AXQ6H5DB.js} +8 -7
  89. package/dist/{start-EUJSS5R4.js → start-MTOVL6SY.js} +2 -2
  90. package/dist/{status-NQJYR4BG.js → status-ZRO37MWR.js} +5 -5
  91. package/dist/{stop-3XAITBBF.js → stop-OK5WEPVC.js} +2 -2
  92. package/dist/{systems-SMEFSHTA.js → systems-W3BBMSOZ.js} +5 -5
  93. package/dist/{tailscale-NY5MUMY3.js → tailscale-BM72RXCJ.js} +1 -1
  94. package/dist/{template-hash-BIMA4ILT.js → template-hash-3HOR4UAJ.js} +1 -1
  95. package/dist/up-BXUAIDXB.js +17 -0
  96. package/dist/{update-PTSH22AZ.js → update-PLPHMMZ2.js} +5 -5
  97. package/dist/{update-check-64FWC4Y2.js → update-check-CVCN7MF6.js} +2 -2
  98. package/dist/{upgrade-HA47CS4C.js → upgrade-I6NPCYUU.js} +1 -1
  99. package/dist/{version-notify-JDUF4HQJ.js → version-notify-2NTWVEHL.js} +18 -16
  100. package/dist/web-assets/assets/index--kREqKl9.js +72 -0
  101. package/dist/web-assets/assets/index-BXYTG0nJ.css +1 -0
  102. package/dist/web-assets/ext-theme.css +111 -0
  103. package/dist/web-assets/index.html +2 -2
  104. package/package.json +11 -5
  105. package/packages/extensions/notes/dist/ui/assets/index-DgawVO5g.css +1 -0
  106. package/packages/extensions/notes/dist/ui/assets/index-qUWoeC4c.js +2 -0
  107. package/packages/extensions/notes/dist/ui/index.html +14 -0
  108. package/packages/extensions/notes/skills/notes/SKILL.md +62 -0
  109. package/packages/extensions/notes/skills/notes/scripts/notes.mjs +185 -0
  110. package/packages/extensions/pages/dist/ui/assets/index-D0HyS-xQ.css +1 -0
  111. package/packages/extensions/pages/dist/ui/assets/index-tLTROSk5.js +2 -0
  112. package/packages/extensions/pages/dist/ui/index.html +14 -0
  113. package/packages/extensions/pages/skills/pages/SKILL.md +58 -0
  114. package/templates/_base/home/VOLUTE.md +1 -1
  115. package/templates/_base/src/lib/logger.ts +10 -49
  116. package/templates/_base/src/lib/router.ts +1 -9
  117. package/templates/claude/src/lib/stream-consumer.ts +1 -4
  118. package/templates/pi/src/lib/event-handler.ts +1 -14
  119. package/dist/chunk-P72MVS4R.js +0 -188
  120. package/dist/chunk-T6HKBWXZ.js +0 -23
  121. package/dist/chunk-ZYGKG6VC.js +0 -22
  122. package/dist/create-D7J73A6H.js +0 -45
  123. package/dist/down-LVBXEULC.js +0 -14
  124. package/dist/message-delivery-HV3S6HZV.js +0 -24
  125. package/dist/notes-XCER3I7M.js +0 -220
  126. package/dist/pages-KJDJX4TA.js +0 -36
  127. package/dist/publish-ZZB33WP4.js +0 -86
  128. package/dist/schedule-QTJMFATP.js +0 -154
  129. package/dist/skills/notes/SKILL.md +0 -34
  130. package/dist/sleep-manager-WMVG2VCL.js +0 -28
  131. package/dist/status-S7UUPNRW.js +0 -38
  132. package/dist/up-GM2JOH2Y.js +0 -17
  133. package/dist/web-assets/assets/index-BZGvToHi.css +0 -1
  134. package/dist/web-assets/assets/index-Cz4TrpzB.js +0 -75
@@ -1,188 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- logger_default
4
- } from "./chunk-YUIHSKR6.js";
5
- import {
6
- gitExec
7
- } from "./chunk-AW7PFDVN.js";
8
- import {
9
- isIsolationEnabled,
10
- mindUserName
11
- } from "./chunk-RKQEHRBB.js";
12
- import {
13
- voluteHome
14
- } from "./chunk-H7OZRFJB.js";
15
-
16
- // src/lib/shared.ts
17
- import { execFileSync } from "child_process";
18
- import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
19
- import { resolve } from "path";
20
- function readWorktreeGitDir(worktreePath) {
21
- const dotGit = resolve(worktreePath, ".git");
22
- if (!existsSync(dotGit)) return null;
23
- try {
24
- const content = readFileSync(dotGit, "utf-8").trim();
25
- const match = content.match(/^gitdir:\s*(.+)$/);
26
- return match ? match[1] : null;
27
- } catch {
28
- return null;
29
- }
30
- }
31
- function sharedDir() {
32
- return resolve(voluteHome(), "shared");
33
- }
34
- async function ensureSharedRepo() {
35
- const dir = sharedDir();
36
- mkdirSync(dir, { recursive: true });
37
- if (existsSync(resolve(dir, ".git"))) {
38
- try {
39
- await gitExec(["rev-parse", "HEAD"], { cwd: dir });
40
- return;
41
- } catch (err) {
42
- const msg = err instanceof Error ? err.message : String(err);
43
- if (msg.includes("unknown revision") || msg.includes("bad default revision")) {
44
- logger_default.warn("shared repo has no commits, re-initializing");
45
- rmSync(resolve(dir, ".git"), { recursive: true, force: true });
46
- } else {
47
- throw err;
48
- }
49
- }
50
- }
51
- const initArgs = isIsolationEnabled() ? ["init", "--shared=group"] : ["init"];
52
- await gitExec(initArgs, { cwd: dir });
53
- await gitExec(["checkout", "-b", "main"], { cwd: dir });
54
- const pagesDir = resolve(dir, "pages");
55
- mkdirSync(pagesDir, { recursive: true });
56
- writeFileSync(resolve(pagesDir, ".gitkeep"), "");
57
- await gitExec(["add", "-A"], { cwd: dir });
58
- await gitExec(["commit", "-m", "init shared repo"], { cwd: dir });
59
- if (isIsolationEnabled()) {
60
- try {
61
- execFileSync("chgrp", ["-R", "volute", dir], { stdio: "ignore" });
62
- } catch (err) {
63
- logger_default.warn("failed to chgrp shared repo to volute group", logger_default.errorData(err));
64
- }
65
- chmodSync(dir, 1533);
66
- }
67
- }
68
- async function addSharedWorktree(mindName, mindDir) {
69
- const dir = sharedDir();
70
- if (!existsSync(resolve(dir, ".git"))) return;
71
- const worktreePath = resolve(mindDir, "home", "shared");
72
- if (existsSync(worktreePath)) return;
73
- let branchExists = false;
74
- try {
75
- await gitExec(["rev-parse", "--verify", mindName], { cwd: dir });
76
- branchExists = true;
77
- } catch {
78
- }
79
- if (branchExists) {
80
- await gitExec(["worktree", "add", worktreePath, mindName], { cwd: dir });
81
- } else {
82
- await gitExec(["worktree", "add", "-b", mindName, worktreePath], { cwd: dir });
83
- }
84
- if (isIsolationEnabled()) {
85
- const worktreeGitDir = readWorktreeGitDir(worktreePath);
86
- if (worktreeGitDir) {
87
- try {
88
- const user = mindUserName(mindName);
89
- execFileSync("chown", ["-R", `${user}:volute`, worktreeGitDir], { stdio: "ignore" });
90
- } catch (err) {
91
- logger_default.warn(`failed to chown worktree git dir for ${mindName}`, logger_default.errorData(err));
92
- }
93
- }
94
- }
95
- }
96
- async function removeSharedWorktree(mindName, mindDir) {
97
- const dir = sharedDir();
98
- if (!existsSync(resolve(dir, ".git"))) return;
99
- const worktreePath = resolve(mindDir, "home", "shared");
100
- if (existsSync(worktreePath)) {
101
- try {
102
- await gitExec(["worktree", "remove", "--force", worktreePath], { cwd: dir });
103
- } catch (err) {
104
- logger_default.debug(`worktree remove failed for ${mindName}`, logger_default.errorData(err));
105
- }
106
- }
107
- try {
108
- await gitExec(["worktree", "prune"], { cwd: dir });
109
- } catch (err) {
110
- logger_default.debug(`worktree prune failed for ${mindName}`, logger_default.errorData(err));
111
- }
112
- try {
113
- await gitExec(["branch", "-D", mindName], { cwd: dir });
114
- } catch {
115
- }
116
- }
117
- var sharedLock = Promise.resolve();
118
- function rechownWorktree(worktreePath, mindName) {
119
- if (!isIsolationEnabled()) return;
120
- try {
121
- const user = mindUserName(mindName);
122
- execFileSync("chown", ["-R", `${user}:volute`, worktreePath], { stdio: "ignore" });
123
- } catch (err) {
124
- logger_default.warn(`failed to rechown worktree for ${mindName}`, logger_default.errorData(err));
125
- }
126
- }
127
- async function withSharedLock(fn) {
128
- const prev = sharedLock;
129
- let resolve_;
130
- sharedLock = new Promise((r) => {
131
- resolve_ = r;
132
- });
133
- await prev;
134
- try {
135
- return await fn();
136
- } finally {
137
- resolve_();
138
- }
139
- }
140
- async function sharedMerge(mindName, mindDir, message) {
141
- return withSharedLock(async () => {
142
- const dir = sharedDir();
143
- const worktreePath = resolve(mindDir, "home", "shared");
144
- const status = (await gitExec(["status", "--porcelain"], { cwd: worktreePath })).trim();
145
- if (status) {
146
- await gitExec(["add", "-A"], { cwd: worktreePath });
147
- await gitExec(
148
- ["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", `wip: ${mindName}`],
149
- { cwd: worktreePath }
150
- );
151
- }
152
- const diff = (await gitExec(["diff", `main...${mindName}`, "--stat"], { cwd: dir })).trim();
153
- if (!diff) {
154
- return { ok: true, message: "Nothing to merge" };
155
- }
156
- try {
157
- await gitExec(["merge", "--squash", mindName], { cwd: dir });
158
- } catch {
159
- try {
160
- await gitExec(["reset", "--hard", "HEAD"], { cwd: dir });
161
- } catch (resetErr) {
162
- logger_default.error("reset after squash conflict failed in shared repo", logger_default.errorData(resetErr));
163
- }
164
- return { ok: false, conflicts: true, message: "Merge conflicts detected" };
165
- }
166
- await gitExec(["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", message], {
167
- cwd: dir
168
- });
169
- try {
170
- await gitExec(["reset", "--hard", "main"], { cwd: worktreePath });
171
- } catch {
172
- return {
173
- ok: true,
174
- message: "Merged to main, but branch reset failed \u2014 run 'volute shared pull' to sync"
175
- };
176
- }
177
- rechownWorktree(worktreePath, mindName);
178
- return { ok: true };
179
- });
180
- }
181
-
182
- export {
183
- sharedDir,
184
- ensureSharedRepo,
185
- addSharedWorktree,
186
- removeSharedWorktree,
187
- sharedMerge
188
- };
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/lib/slugify.ts
4
- function slugify(text) {
5
- return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
6
- }
7
- function buildVoluteSlug(opts) {
8
- if (opts.convType === "channel" && opts.convName) {
9
- return `volute:#${opts.convName}`;
10
- }
11
- const isDM = opts.participants.length === 2;
12
- if (isDM) {
13
- const other = opts.participants.find((p) => p.username !== opts.mindUsername);
14
- const otherSlug = other ? slugify(other.username) : "";
15
- return otherSlug ? `volute:@${otherSlug}` : `volute:${opts.conversationId}`;
16
- }
17
- return opts.convTitle ? `volute:${slugify(opts.convTitle)}` : `volute:${opts.conversationId}`;
18
- }
19
-
20
- export {
21
- slugify,
22
- buildVoluteSlug
23
- };
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/lib/read-stdin.ts
4
- import { isatty } from "tty";
5
- async function readStdin() {
6
- if (isatty(0)) return void 0;
7
- const chunks = [];
8
- try {
9
- for await (const chunk of process.stdin) {
10
- chunks.push(chunk);
11
- }
12
- } catch (err) {
13
- console.error(`Failed to read from stdin: ${err instanceof Error ? err.message : String(err)}`);
14
- process.exit(1);
15
- }
16
- const text = Buffer.concat(chunks).toString().replace(/\r?\n$/, "");
17
- return text || void 0;
18
- }
19
-
20
- export {
21
- readStdin
22
- };
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- resolveMindName
4
- } from "./chunk-NAOW2CLO.js";
5
- import {
6
- daemonFetch
7
- } from "./chunk-JGFVMROS.js";
8
- import {
9
- parseArgs
10
- } from "./chunk-D424ZQGI.js";
11
- import "./chunk-H7OZRFJB.js";
12
- import "./chunk-K3NQKI34.js";
13
-
14
- // src/commands/chat/create.ts
15
- async function run(args) {
16
- const { flags } = parseArgs(args, {
17
- mind: { type: "string" },
18
- participants: { type: "string" },
19
- name: { type: "string" }
20
- });
21
- if (!flags.participants) {
22
- console.error('Usage: volute chat create --participants u1,u2 [--name "..."] [--mind <name>]');
23
- process.exit(1);
24
- }
25
- const mindName = resolveMindName(flags);
26
- const participants = flags.participants.split(",").map((p) => p.trim());
27
- const res = await daemonFetch(`/api/minds/${encodeURIComponent(mindName)}/conversations`, {
28
- method: "POST",
29
- headers: { "Content-Type": "application/json" },
30
- body: JSON.stringify({
31
- participantNames: participants,
32
- title: flags.name
33
- })
34
- });
35
- if (!res.ok) {
36
- const data = await res.json().catch(() => ({}));
37
- console.error(data.error ?? `Failed to create conversation: ${res.status}`);
38
- process.exit(1);
39
- }
40
- const conv = await res.json();
41
- console.log(`Created conversation: ${conv.id}`);
42
- }
43
- export {
44
- run
45
- };
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- run,
4
- stopDaemon
5
- } from "./chunk-EHYDTZTF.js";
6
- import "./chunk-LAC664WU.js";
7
- import "./chunk-AW7PFDVN.js";
8
- import "./chunk-RKQEHRBB.js";
9
- import "./chunk-H7OZRFJB.js";
10
- import "./chunk-K3NQKI34.js";
11
- export {
12
- run,
13
- stopDaemon
14
- };
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- deliverMessage,
4
- extractTextContent,
5
- recordInbound
6
- } from "./chunk-AAPXKR5V.js";
7
- import "./chunk-IAYBDWVG.js";
8
- import "./chunk-K5NAC55T.js";
9
- import "./chunk-VIVMW2H2.js";
10
- import "./chunk-POSXWWTA.js";
11
- import "./chunk-J4IBNXGJ.js";
12
- import "./chunk-2WPW7OT6.js";
13
- import "./chunk-YUIHSKR6.js";
14
- import "./chunk-AW7PFDVN.js";
15
- import "./chunk-RKQEHRBB.js";
16
- import "./chunk-IKRVFPWU.js";
17
- import "./chunk-T6HKBWXZ.js";
18
- import "./chunk-H7OZRFJB.js";
19
- import "./chunk-K3NQKI34.js";
20
- export {
21
- deliverMessage,
22
- extractTextContent,
23
- recordInbound
24
- };
@@ -1,220 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- readStdin
4
- } from "./chunk-ZYGKG6VC.js";
5
- import {
6
- daemonFetch
7
- } from "./chunk-JGFVMROS.js";
8
- import {
9
- parseArgs
10
- } from "./chunk-D424ZQGI.js";
11
- import "./chunk-H7OZRFJB.js";
12
- import "./chunk-K3NQKI34.js";
13
-
14
- // src/commands/notes.ts
15
- function apiUrl(path) {
16
- return `/api/notes${path}`;
17
- }
18
- async function list(args) {
19
- const { flags } = parseArgs(args, {
20
- author: { type: "string" },
21
- limit: { type: "number" }
22
- });
23
- const params = new URLSearchParams();
24
- if (flags.author) params.set("author", flags.author);
25
- if (flags.limit) params.set("limit", String(flags.limit));
26
- const res = await daemonFetch(`${apiUrl("")}?${params}`);
27
- if (!res.ok) {
28
- const data = await res.json().catch(() => ({ error: "Unknown error" }));
29
- console.error(data.error);
30
- process.exit(1);
31
- }
32
- const notes = await res.json();
33
- if (notes.length === 0) {
34
- console.log("No notes yet.");
35
- return;
36
- }
37
- for (const note of notes) {
38
- const date = new Date(note.created_at).toLocaleDateString();
39
- const comments = note.comment_count > 0 ? ` (${note.comment_count} comments)` : "";
40
- const replyIndicator = note.reply_to ? ` \u21A9 ${note.reply_to.author_username}/${note.reply_to.slug}` : "";
41
- const reactions = note.reactions && note.reactions.length > 0 ? ` ${note.reactions.map((r) => `${r.emoji} ${r.count}`).join(" ")}` : "";
42
- console.log(
43
- ` ${note.author_username}/${note.slug} ${note.title} ${date}${comments}${replyIndicator}${reactions}`
44
- );
45
- }
46
- }
47
- async function write(args) {
48
- const { flags } = parseArgs(args, {
49
- title: { type: "string" },
50
- content: { type: "string" },
51
- "reply-to": { type: "string" }
52
- });
53
- if (!flags.title) {
54
- console.error(
55
- 'Usage: volute notes write --title "..." [--content "..." | stdin] [--reply-to <author>/<slug>]'
56
- );
57
- process.exit(1);
58
- }
59
- const content = flags.content ?? await readStdin();
60
- if (!content) {
61
- console.error("Content required via --content or stdin");
62
- process.exit(1);
63
- }
64
- const body = { title: flags.title, content };
65
- if (flags["reply-to"]) body.reply_to = flags["reply-to"];
66
- const res = await daemonFetch(apiUrl(""), {
67
- method: "POST",
68
- headers: { "Content-Type": "application/json" },
69
- body: JSON.stringify(body)
70
- });
71
- if (!res.ok) {
72
- const data = await res.json().catch(() => ({ error: "Unknown error" }));
73
- console.error(data.error);
74
- process.exit(1);
75
- }
76
- const note = await res.json();
77
- console.log(`Published: ${note.author_username}/${note.slug}`);
78
- }
79
- async function read(args) {
80
- const { positional } = parseArgs(args, {});
81
- const ref = positional[0];
82
- if (!ref || !ref.includes("/")) {
83
- console.error("Usage: volute notes read <author>/<slug>");
84
- process.exit(1);
85
- }
86
- const [author, slug] = ref.split("/", 2);
87
- const res = await daemonFetch(apiUrl(`/${author}/${slug}`));
88
- if (!res.ok) {
89
- const data = await res.json().catch(() => ({ error: "Unknown error" }));
90
- console.error(data.error);
91
- process.exit(1);
92
- }
93
- const note = await res.json();
94
- console.log(`
95
- ${note.title}`);
96
- console.log(` by ${note.author_username} \xB7 ${new Date(note.created_at).toLocaleDateString()}`);
97
- if (note.reply_to) {
98
- console.log(
99
- ` In reply to: ${note.reply_to.author_username}/${note.reply_to.slug} \u2014 ${note.reply_to.title}`
100
- );
101
- }
102
- console.log("");
103
- console.log(note.content);
104
- if (note.reactions && note.reactions.length > 0) {
105
- console.log(`
106
- ${note.reactions.map((r) => `${r.emoji} ${r.count}`).join(" ")}`);
107
- }
108
- if (note.comments && note.comments.length > 0) {
109
- console.log(`
110
- --- Comments (${note.comments.length}) ---
111
- `);
112
- for (const c of note.comments) {
113
- const date = new Date(c.created_at).toLocaleDateString();
114
- console.log(` ${c.author_username} (${date}):`);
115
- console.log(` ${c.content}
116
- `);
117
- }
118
- }
119
- if (note.replies && note.replies.length > 0) {
120
- console.log(`
121
- --- Replies (${note.replies.length}) ---
122
- `);
123
- for (const r of note.replies) {
124
- const date = new Date(r.created_at).toLocaleDateString();
125
- console.log(` ${r.author_username}/${r.slug} ${r.title} ${date}`);
126
- }
127
- }
128
- }
129
- async function react(args) {
130
- const { positional } = parseArgs(args, {});
131
- const ref = positional[0];
132
- const emoji = positional[1];
133
- if (!ref || !ref.includes("/") || !emoji) {
134
- console.error("Usage: volute notes react <author>/<slug> <emoji>");
135
- process.exit(1);
136
- }
137
- const [author, slug] = ref.split("/", 2);
138
- const res = await daemonFetch(apiUrl(`/${author}/${slug}/reactions`), {
139
- method: "POST",
140
- headers: { "Content-Type": "application/json" },
141
- body: JSON.stringify({ emoji })
142
- });
143
- if (!res.ok) {
144
- const data = await res.json().catch(() => ({ error: "Unknown error" }));
145
- console.error(data.error);
146
- process.exit(1);
147
- }
148
- const result = await res.json();
149
- console.log(result.added ? `Reacted with ${emoji}` : `Removed ${emoji} reaction`);
150
- }
151
- async function comment(args) {
152
- const { positional } = parseArgs(args, {});
153
- const ref = positional[0];
154
- const text = positional[1] ?? await readStdin();
155
- if (!ref || !ref.includes("/") || !text) {
156
- console.error('Usage: volute notes comment <author>/<slug> "comment text"');
157
- process.exit(1);
158
- }
159
- const [author, slug] = ref.split("/", 2);
160
- const res = await daemonFetch(apiUrl(`/${author}/${slug}/comments`), {
161
- method: "POST",
162
- headers: { "Content-Type": "application/json" },
163
- body: JSON.stringify({ content: text })
164
- });
165
- if (!res.ok) {
166
- const data = await res.json().catch(() => ({ error: "Unknown error" }));
167
- console.error(data.error);
168
- process.exit(1);
169
- }
170
- console.log("Comment added.");
171
- }
172
- async function del(args) {
173
- const { positional } = parseArgs(args, {});
174
- const ref = positional[0];
175
- if (!ref || !ref.includes("/")) {
176
- console.error("Usage: volute notes delete <author>/<slug>");
177
- process.exit(1);
178
- }
179
- const [author, slug] = ref.split("/", 2);
180
- const res = await daemonFetch(apiUrl(`/${author}/${slug}`), {
181
- method: "DELETE"
182
- });
183
- if (!res.ok) {
184
- const data = await res.json().catch(() => ({ error: "Unknown error" }));
185
- console.error(data.error);
186
- process.exit(1);
187
- }
188
- console.log("Note deleted.");
189
- }
190
- async function run(args) {
191
- const subcommand = args[0];
192
- const rest = args.slice(1);
193
- switch (subcommand) {
194
- case "list":
195
- return list(rest);
196
- case "write":
197
- return write(rest);
198
- case "read":
199
- return read(rest);
200
- case "react":
201
- return react(rest);
202
- case "comment":
203
- return comment(rest);
204
- case "delete":
205
- return del(rest);
206
- default:
207
- console.log(`volute notes \u2014 read and write notes
208
-
209
- list [--author <name>] [--limit N] List notes
210
- write --title "..." [--content "..."] [--reply-to ref] Write a note (content from --content or stdin)
211
- read <author>/<slug> Read a note
212
- react <author>/<slug> <emoji> Toggle a reaction on a note
213
- comment <author>/<slug> "text" Comment on a note
214
- delete <author>/<slug> Delete a note`);
215
- if (subcommand && subcommand !== "--help" && subcommand !== "-h") process.exit(1);
216
- }
217
- }
218
- export {
219
- run
220
- };
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./chunk-K3NQKI34.js";
3
-
4
- // src/commands/pages.ts
5
- async function run(args) {
6
- const subcommand = args[0];
7
- switch (subcommand) {
8
- case "publish":
9
- await import("./publish-ZZB33WP4.js").then((m) => m.run(args.slice(1)));
10
- break;
11
- case "status":
12
- await import("./status-S7UUPNRW.js").then((m) => m.run(args.slice(1)));
13
- break;
14
- case "--help":
15
- case "-h":
16
- case void 0:
17
- printUsage();
18
- break;
19
- default:
20
- printUsage();
21
- process.exit(1);
22
- }
23
- }
24
- function printUsage() {
25
- console.log(`Usage:
26
- volute pages publish [--mind <name>] Publish mind's pages/ directory
27
- volute pages status [--mind <name>] Show publish status
28
-
29
- Account commands:
30
- volute systems register [--name <name>]
31
- volute systems login [--key <key>]
32
- volute systems logout`);
33
- }
34
- export {
35
- run
36
- };
@@ -1,86 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- resolveMindName
4
- } from "./chunk-NAOW2CLO.js";
5
- import {
6
- daemonFetch
7
- } from "./chunk-JGFVMROS.js";
8
- import {
9
- sharedDir
10
- } from "./chunk-P72MVS4R.js";
11
- import "./chunk-YUIHSKR6.js";
12
- import "./chunk-AW7PFDVN.js";
13
- import "./chunk-RKQEHRBB.js";
14
- import {
15
- parseArgs
16
- } from "./chunk-D424ZQGI.js";
17
- import {
18
- mindDir
19
- } from "./chunk-H7OZRFJB.js";
20
- import "./chunk-K3NQKI34.js";
21
-
22
- // src/commands/pages/publish.ts
23
- import { existsSync, lstatSync, readdirSync, readFileSync } from "fs";
24
- import { relative, resolve } from "path";
25
- async function run(args) {
26
- const { flags } = parseArgs(args, {
27
- mind: { type: "string" },
28
- system: { type: "boolean" }
29
- });
30
- let mindName;
31
- let pagesDir;
32
- if (flags.system) {
33
- mindName = "system";
34
- pagesDir = resolve(sharedDir(), "pages");
35
- } else if (flags.mind || process.env.VOLUTE_MIND) {
36
- mindName = resolveMindName(flags);
37
- pagesDir = resolve(mindDir(mindName), "home", "public", "pages");
38
- } else {
39
- mindName = "system";
40
- pagesDir = resolve(sharedDir(), "pages");
41
- }
42
- if (!existsSync(pagesDir)) {
43
- console.error(`No pages/ directory found at ${pagesDir}`);
44
- process.exit(1);
45
- }
46
- const files = collectFiles(pagesDir);
47
- if (Object.keys(files).length === 0) {
48
- console.error("pages/ directory is empty.");
49
- process.exit(1);
50
- }
51
- console.log(`Publishing ${Object.keys(files).length} file(s) for ${mindName}...`);
52
- const res = await daemonFetch(`/api/system/pages/publish/${mindName}`, {
53
- method: "PUT",
54
- headers: { "Content-Type": "application/json" },
55
- body: JSON.stringify({ files })
56
- });
57
- if (!res.ok) {
58
- const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
59
- console.error(`Publish failed: ${body.error}`);
60
- process.exit(1);
61
- }
62
- const { url, fileCount } = await res.json();
63
- console.log(`Published ${fileCount} file(s) to ${url}`);
64
- }
65
- function collectFiles(dir) {
66
- const files = {};
67
- function walk(current) {
68
- for (const entry of readdirSync(current)) {
69
- const full = resolve(current, entry);
70
- const stat = lstatSync(full);
71
- if (stat.isSymbolicLink()) continue;
72
- if (stat.isDirectory()) {
73
- walk(full);
74
- } else if (stat.isFile()) {
75
- const rel = relative(dir, full);
76
- files[rel] = readFileSync(full).toString("base64");
77
- }
78
- }
79
- }
80
- walk(dir);
81
- return files;
82
- }
83
- export {
84
- collectFiles,
85
- run
86
- };