svamp-cli 0.1.75 → 0.1.76

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.
@@ -1,5 +1,5 @@
1
1
  import os__default from 'os';
2
- import fs from 'fs';
2
+ import fs__default from 'fs';
3
3
  import { join, resolve, relative } from 'path';
4
4
 
5
5
  const SKILLS_SERVER = process.env.HYPHA_SKILLS_SERVER || "https://hypha.aicell.io";
@@ -128,8 +128,8 @@ function normalizeSkill(item) {
128
128
  const SVAMP_HOME = process.env.SVAMP_HOME || join(os__default.homedir(), ".svamp");
129
129
  const ENV_FILE = join(SVAMP_HOME, ".env");
130
130
  function loadDotEnv() {
131
- if (!fs.existsSync(ENV_FILE)) return;
132
- const lines = fs.readFileSync(ENV_FILE, "utf-8").split("\n");
131
+ if (!fs__default.existsSync(ENV_FILE)) return;
132
+ const lines = fs__default.readFileSync(ENV_FILE, "utf-8").split("\n");
133
133
  for (const line of lines) {
134
134
  const trimmed = line.trim();
135
135
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -143,7 +143,7 @@ function loadDotEnv() {
143
143
  }
144
144
  }
145
145
  function ensureSkillsDir() {
146
- fs.mkdirSync(SKILLS_DIR, { recursive: true });
146
+ fs__default.mkdirSync(SKILLS_DIR, { recursive: true });
147
147
  }
148
148
  function formatTable(rows, widths) {
149
149
  if (rows.length === 0) return "";
@@ -190,7 +190,7 @@ async function skillsInstall(skillName, opts) {
190
190
  process.exit(1);
191
191
  }
192
192
  const targetDir = join(SKILLS_DIR, skillName);
193
- if (fs.existsSync(targetDir) && !opts?.force) {
193
+ if (fs__default.existsSync(targetDir) && !opts?.force) {
194
194
  console.error(`Skill "${skillName}" is already installed at ${targetDir}`);
195
195
  console.error("Use --force to overwrite.");
196
196
  process.exit(1);
@@ -223,10 +223,10 @@ async function skillsInstall(skillName, opts) {
223
223
  process.exit(1);
224
224
  }
225
225
  ensureSkillsDir();
226
- if (fs.existsSync(targetDir) && opts?.force) {
227
- fs.rmSync(targetDir, { recursive: true, force: true });
226
+ if (fs__default.existsSync(targetDir) && opts?.force) {
227
+ fs__default.rmSync(targetDir, { recursive: true, force: true });
228
228
  }
229
- fs.mkdirSync(targetDir, { recursive: true });
229
+ fs__default.mkdirSync(targetDir, { recursive: true });
230
230
  let downloaded = 0;
231
231
  const errors = [];
232
232
  for (const filePath of files) {
@@ -237,23 +237,23 @@ async function skillsInstall(skillName, opts) {
237
237
  errors.push(` ${filePath}: path outside skill directory (blocked)`);
238
238
  continue;
239
239
  }
240
- fs.mkdirSync(join(localPath, ".."), { recursive: true });
241
- fs.writeFileSync(localPath, content, "utf-8");
240
+ fs__default.mkdirSync(join(localPath, ".."), { recursive: true });
241
+ fs__default.writeFileSync(localPath, content, "utf-8");
242
242
  downloaded++;
243
243
  } catch (err) {
244
244
  errors.push(` ${filePath}: ${err.message}`);
245
245
  }
246
246
  }
247
247
  if (errors.length > 0) {
248
- fs.rmSync(targetDir, { recursive: true, force: true });
248
+ fs__default.rmSync(targetDir, { recursive: true, force: true });
249
249
  console.error(`Installation failed \u2014 ${errors.length} file(s) could not be downloaded:`);
250
250
  errors.forEach((e) => console.error(e));
251
251
  console.error("Partial installation cleaned up. Run the command again to retry.");
252
252
  process.exit(1);
253
253
  }
254
254
  const skillMdPath = join(targetDir, "SKILL.md");
255
- if (fs.existsSync(skillMdPath)) {
256
- const content = fs.readFileSync(skillMdPath, "utf-8");
255
+ if (fs__default.existsSync(skillMdPath)) {
256
+ const content = fs__default.readFileSync(skillMdPath, "utf-8");
257
257
  const fm = parseFrontmatter(content);
258
258
  if (!fm) {
259
259
  console.error("Warning: Installed SKILL.md has invalid or missing frontmatter (name/description).");
@@ -280,7 +280,7 @@ async function collectAllFiles(skillAlias, dir = "") {
280
280
  }
281
281
  async function skillsList() {
282
282
  ensureSkillsDir();
283
- const entries = fs.readdirSync(SKILLS_DIR, { withFileTypes: true }).filter((e) => e.isDirectory());
283
+ const entries = fs__default.readdirSync(SKILLS_DIR, { withFileTypes: true }).filter((e) => e.isDirectory());
284
284
  if (entries.length === 0) {
285
285
  console.log("No skills installed.");
286
286
  console.log(`Install one with: svamp skills install <name>`);
@@ -293,11 +293,11 @@ async function skillsList() {
293
293
  const skillMd = join(skillDir, "SKILL.md");
294
294
  let description = "-";
295
295
  let status = "ok";
296
- if (!fs.existsSync(skillMd)) {
296
+ if (!fs__default.existsSync(skillMd)) {
297
297
  status = "missing SKILL.md";
298
298
  } else {
299
299
  try {
300
- const content = fs.readFileSync(skillMd, "utf-8");
300
+ const content = fs__default.readFileSync(skillMd, "utf-8");
301
301
  const fm = parseFrontmatter(content);
302
302
  if (fm) {
303
303
  description = fm.description.length > 45 ? fm.description.slice(0, 42) + "..." : fm.description;
@@ -318,34 +318,34 @@ async function skillsRemove(name) {
318
318
  process.exit(1);
319
319
  }
320
320
  const targetDir = join(SKILLS_DIR, name);
321
- if (!fs.existsSync(targetDir)) {
321
+ if (!fs__default.existsSync(targetDir)) {
322
322
  console.error(`Skill "${name}" is not installed.`);
323
323
  process.exit(1);
324
324
  }
325
- if (!fs.statSync(targetDir).isDirectory()) {
325
+ if (!fs__default.statSync(targetDir).isDirectory()) {
326
326
  console.error(`"${name}" is not a skill directory.`);
327
327
  process.exit(1);
328
328
  }
329
- fs.rmSync(targetDir, { recursive: true, force: true });
329
+ fs__default.rmSync(targetDir, { recursive: true, force: true });
330
330
  console.log(`Removed skill "${name}" from ${targetDir}`);
331
331
  }
332
332
  async function skillsPublish(skillPath, opts) {
333
333
  const absPath = resolve(skillPath);
334
- if (!fs.existsSync(absPath)) {
334
+ if (!fs__default.existsSync(absPath)) {
335
335
  console.error(`Path does not exist: ${absPath}`);
336
336
  process.exit(1);
337
337
  }
338
- if (!fs.statSync(absPath).isDirectory()) {
338
+ if (!fs__default.statSync(absPath).isDirectory()) {
339
339
  console.error(`Not a directory: ${absPath}`);
340
340
  process.exit(1);
341
341
  }
342
342
  const skillMdPath = join(absPath, "SKILL.md");
343
- if (!fs.existsSync(skillMdPath)) {
343
+ if (!fs__default.existsSync(skillMdPath)) {
344
344
  console.error(`No SKILL.md found in ${absPath}`);
345
345
  console.error("A valid skill must contain a SKILL.md file with name and description frontmatter.");
346
346
  process.exit(1);
347
347
  }
348
- const skillMdContent = fs.readFileSync(skillMdPath, "utf-8");
348
+ const skillMdContent = fs__default.readFileSync(skillMdPath, "utf-8");
349
349
  const manifest = parseFrontmatter(skillMdContent);
350
350
  if (!manifest) {
351
351
  console.error('SKILL.md must have YAML frontmatter with "name" and "description" fields.');
@@ -455,7 +455,7 @@ async function skillsPublish(skillPath, opts) {
455
455
  for (const relPath of filesToUpload) {
456
456
  try {
457
457
  const fullPath = join(absPath, relPath);
458
- const content = fs.readFileSync(fullPath);
458
+ const content = fs__default.readFileSync(fullPath);
459
459
  const putUrl = await am.put_file({
460
460
  artifact_id: artifactId,
461
461
  file_path: relPath,
@@ -515,7 +515,7 @@ async function skillsPublish(skillPath, opts) {
515
515
  function collectLocalFiles(dir, base) {
516
516
  const root = base || dir;
517
517
  const result = [];
518
- const entries = fs.readdirSync(dir, { withFileTypes: true });
518
+ const entries = fs__default.readdirSync(dir, { withFileTypes: true });
519
519
  for (const entry of entries) {
520
520
  const fullPath = join(dir, entry.name);
521
521
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
@@ -2,7 +2,7 @@ import { existsSync, readFileSync } from 'node:fs';
2
2
  import { execSync } from 'node:child_process';
3
3
  import { resolve, join } from 'node:path';
4
4
  import os from 'node:os';
5
- import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-lhAjX4NB.mjs';
5
+ import { l as loadSecurityContextConfig, e as resolveSecurityContext, f as buildSecurityContextFromFlags, m as mergeSecurityContexts, c as connectToHypha } from './run-BnFGIK0c.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -1706,78 +1706,150 @@ async function sessionRalphStatus(sessionIdPartial, machineId) {
1706
1706
  await server.disconnect();
1707
1707
  }
1708
1708
  }
1709
- async function sessionQueueAdd(sessionIdPartial, message, machineId) {
1709
+ async function sessionInboxSend(sessionIdPartial, body, machineId, opts) {
1710
1710
  const { server, machine } = await connectAndGetMachine(machineId);
1711
1711
  try {
1712
1712
  const sessions = await machine.listSessions();
1713
1713
  const match = resolveSessionId(sessions, sessionIdPartial);
1714
1714
  const fullId = match.sessionId;
1715
1715
  const svc = await server.getService(`svamp-session-${fullId}`);
1716
- const { metadata, version } = await svc.getMetadata();
1717
- const existingQueue = metadata?.messageQueue || [];
1718
- const newMsg = {
1719
- id: `cli-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
1720
- text: message,
1721
- createdAt: Date.now()
1716
+ const { randomUUID } = await import('node:crypto');
1717
+ const message = {
1718
+ messageId: randomUUID(),
1719
+ body,
1720
+ timestamp: Date.now(),
1721
+ read: false,
1722
+ from: `cli:${os.userInfo().username}`,
1723
+ to: fullId,
1724
+ subject: opts?.subject,
1725
+ urgency: opts?.urgency || "normal",
1726
+ replyTo: opts?.replyTo,
1727
+ threadId: opts?.threadId
1722
1728
  };
1723
- const updatedQueue = [...existingQueue, newMsg];
1724
- const updatedMetadata = { ...metadata, messageQueue: updatedQueue };
1725
- const result = await svc.updateMetadata(updatedMetadata, version);
1726
- if (result.result !== "success") {
1727
- console.error(`Failed to add to queue: ${result.result}`);
1728
- process.exit(1);
1729
+ const result = await svc.sendInboxMessage(message);
1730
+ if (opts?.json) {
1731
+ console.log(formatJson({ sessionId: fullId, messageId: result.messageId, sent: true }));
1732
+ } else {
1733
+ console.log(`Inbox message sent to session ${fullId.slice(0, 8)} (id: ${result.messageId.slice(0, 8)})`);
1729
1734
  }
1730
- console.log(`Message queued on session ${fullId.slice(0, 8)} (${updatedQueue.length} total)`);
1731
1735
  } finally {
1732
1736
  await server.disconnect();
1733
1737
  }
1734
1738
  }
1735
- async function sessionQueueList(sessionIdPartial, machineId) {
1739
+ async function sessionInboxList(sessionIdPartial, machineId, opts) {
1736
1740
  const { server, machine } = await connectAndGetMachine(machineId);
1737
1741
  try {
1738
1742
  const sessions = await machine.listSessions();
1739
1743
  const match = resolveSessionId(sessions, sessionIdPartial);
1740
1744
  const fullId = match.sessionId;
1741
1745
  const svc = await server.getService(`svamp-session-${fullId}`);
1742
- const { metadata } = await svc.getMetadata();
1743
- const queue = metadata?.messageQueue || [];
1744
- if (queue.length === 0) {
1745
- console.log("Queue is empty.");
1746
+ const result = await svc.getInbox({ unread: opts?.unread, limit: opts?.limit });
1747
+ const messages = result.messages;
1748
+ if (opts?.json) {
1749
+ console.log(formatJson({ sessionId: fullId, messages }));
1746
1750
  return;
1747
1751
  }
1748
- console.log(`Queue for session ${fullId.slice(0, 8)} (${queue.length} messages):`);
1749
- for (let i = 0; i < queue.length; i++) {
1750
- const msg = queue[i];
1751
- const time = new Date(msg.createdAt).toLocaleTimeString();
1752
- console.log(` ${i + 1}. [${time}] ${msg.text.slice(0, 80)}${msg.text.length > 80 ? "..." : ""}`);
1752
+ if (messages.length === 0) {
1753
+ console.log(`Inbox for session ${fullId.slice(0, 8)} is empty.`);
1754
+ return;
1755
+ }
1756
+ const unreadCount = messages.filter((m) => !m.read).length;
1757
+ console.log(`Inbox for session ${fullId.slice(0, 8)} (${messages.length} message(s), ${unreadCount} unread):
1758
+ `);
1759
+ for (const msg of messages) {
1760
+ const status = msg.read ? " " : "\u25CF";
1761
+ const from = msg.from ? ` from ${msg.from}` : "";
1762
+ const subject = msg.subject ? ` \u2014 ${msg.subject}` : "";
1763
+ const urgencyTag = msg.urgency === "urgent" ? " [URGENT]" : "";
1764
+ const date = new Date(msg.timestamp).toLocaleString();
1765
+ const preview = msg.body.length > 100 ? msg.body.slice(0, 97) + "..." : msg.body;
1766
+ console.log(` ${status} ${msg.messageId.slice(0, 8)}${urgencyTag}${from}${subject}`);
1767
+ console.log(` ${date}`);
1768
+ console.log(` ${preview}
1769
+ `);
1753
1770
  }
1754
1771
  } finally {
1755
1772
  await server.disconnect();
1756
1773
  }
1757
1774
  }
1758
- async function sessionQueueClear(sessionIdPartial, machineId) {
1775
+ async function sessionInboxRead(sessionIdPartial, messageId, machineId) {
1759
1776
  const { server, machine } = await connectAndGetMachine(machineId);
1760
1777
  try {
1761
1778
  const sessions = await machine.listSessions();
1762
1779
  const match = resolveSessionId(sessions, sessionIdPartial);
1763
1780
  const fullId = match.sessionId;
1764
1781
  const svc = await server.getService(`svamp-session-${fullId}`);
1765
- const { metadata, version } = await svc.getMetadata();
1766
- const count = (metadata?.messageQueue || []).length;
1767
- if (count === 0) {
1768
- console.log("Queue is already empty.");
1769
- return;
1782
+ const result = await svc.getInbox();
1783
+ const msg = result.messages.find((m) => m.messageId === messageId || m.messageId.startsWith(messageId));
1784
+ if (!msg) {
1785
+ console.error(`Message ${messageId} not found in inbox.`);
1786
+ process.exit(1);
1787
+ }
1788
+ if (!msg.read) {
1789
+ await svc.markInboxRead(msg.messageId);
1790
+ }
1791
+ console.log(`From: ${msg.from || "(unknown)"}`);
1792
+ if (msg.subject) console.log(`Subject: ${msg.subject}`);
1793
+ console.log(`Date: ${new Date(msg.timestamp).toLocaleString()}`);
1794
+ if (msg.urgency === "urgent") console.log("Urgency: URGENT");
1795
+ if (msg.replyTo) console.log(`Reply-To: ${msg.replyTo.slice(0, 8)}`);
1796
+ if (msg.threadId) console.log(`Thread: ${msg.threadId.slice(0, 8)}`);
1797
+ console.log(`
1798
+ ${msg.body}`);
1799
+ } finally {
1800
+ await server.disconnect();
1801
+ }
1802
+ }
1803
+ async function sessionInboxReply(sessionIdPartial, messageId, body, machineId) {
1804
+ const { server, machine } = await connectAndGetMachine(machineId);
1805
+ try {
1806
+ const sessions = await machine.listSessions();
1807
+ const match = resolveSessionId(sessions, sessionIdPartial);
1808
+ const fullId = match.sessionId;
1809
+ const svc = await server.getService(`svamp-session-${fullId}`);
1810
+ const result = await svc.getInbox();
1811
+ const original = result.messages.find((m) => m.messageId === messageId || m.messageId.startsWith(messageId));
1812
+ if (!original) {
1813
+ console.error(`Message ${messageId} not found in inbox.`);
1814
+ process.exit(1);
1770
1815
  }
1771
- const updatedMetadata = { ...metadata, messageQueue: void 0 };
1772
- const result = await svc.updateMetadata(updatedMetadata, version);
1773
- if (result.result !== "success") {
1774
- console.error(`Failed to clear queue: ${result.result}`);
1816
+ if (!original.fromSession) {
1817
+ console.error("Cannot reply: original message has no fromSession.");
1775
1818
  process.exit(1);
1776
1819
  }
1777
- console.log(`Cleared ${count} message(s) from queue on session ${fullId.slice(0, 8)}`);
1820
+ const targetSvc = await server.getService(`svamp-session-${original.fromSession}`);
1821
+ const { randomUUID } = await import('node:crypto');
1822
+ const reply = {
1823
+ messageId: randomUUID(),
1824
+ body,
1825
+ timestamp: Date.now(),
1826
+ read: false,
1827
+ from: `session:${fullId}`,
1828
+ fromSession: fullId,
1829
+ to: original.fromSession,
1830
+ subject: original.subject ? `Re: ${original.subject}` : void 0,
1831
+ urgency: "normal",
1832
+ replyTo: original.messageId,
1833
+ threadId: original.threadId || original.messageId
1834
+ };
1835
+ const sendResult = await targetSvc.sendInboxMessage(reply);
1836
+ console.log(`Reply sent to session ${original.fromSession.slice(0, 8)} (id: ${sendResult.messageId.slice(0, 8)})`);
1837
+ } finally {
1838
+ await server.disconnect();
1839
+ }
1840
+ }
1841
+ async function sessionInboxClear(sessionIdPartial, machineId, opts) {
1842
+ const { server, machine } = await connectAndGetMachine(machineId);
1843
+ try {
1844
+ const sessions = await machine.listSessions();
1845
+ const match = resolveSessionId(sessions, sessionIdPartial);
1846
+ const fullId = match.sessionId;
1847
+ const svc = await server.getService(`svamp-session-${fullId}`);
1848
+ const result = await svc.clearInbox({ all: opts?.all });
1849
+ console.log(`Cleared ${result.removed} message(s) from inbox on session ${fullId.slice(0, 8)}`);
1778
1850
  } finally {
1779
1851
  await server.disconnect();
1780
1852
  }
1781
1853
  }
1782
1854
 
1783
- export { connectAndGetMachine, createWorktree, generateWorktreeName, machineExec, machineInfo, machineLs, machineShare, parseShareArg, renderMessage, resolveSessionId, sessionApprove, sessionAttach, sessionDeny, sessionInfo, sessionList, sessionMachines, sessionMessages, sessionQueueAdd, sessionQueueClear, sessionQueueList, sessionRalphCancel, sessionRalphStart, sessionRalphStatus, sessionSend, sessionShare, sessionSpawn, sessionStop, sessionWait };
1855
+ export { connectAndGetMachine, createWorktree, generateWorktreeName, machineExec, machineInfo, machineLs, machineShare, parseShareArg, renderMessage, resolveSessionId, sessionApprove, sessionAttach, sessionDeny, sessionInboxClear, sessionInboxList, sessionInboxRead, sessionInboxReply, sessionInboxSend, sessionInfo, sessionList, sessionMachines, sessionMessages, sessionRalphCancel, sessionRalphStart, sessionRalphStatus, sessionSend, sessionShare, sessionSpawn, sessionStop, sessionWait };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-lhAjX4NB.mjs';
1
+ export { c as connectToHypha, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, a as registerSessionService, s as startDaemon, b as stopDaemon } from './run-BnFGIK0c.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -1,5 +1,5 @@
1
1
  var name = "svamp-cli";
2
- var version = "0.1.75";
2
+ var version = "0.1.76";
3
3
  var description = "Svamp CLI — AI workspace daemon on Hypha Cloud";
4
4
  var author = "Amun AI AB";
5
5
  var license = "SEE LICENSE IN LICENSE";
@@ -19,7 +19,7 @@ var exports$1 = {
19
19
  var scripts = {
20
20
  build: "rm -rf dist && tsc --noEmit && pkgroll",
21
21
  typecheck: "tsc --noEmit",
22
- test: "npx tsx test/test-authorize.mjs && npx tsx test/test-session-helpers.mjs && npx tsx test/test-cli-routing.mjs && npx tsx test/test-security-context.mjs && npx tsx test/test-ralph-loop.mjs && npx tsx test/test-message-helpers.mjs && npx tsx test/test-agent-config.mjs && npx tsx test/test-wrap-command.mjs && npx tsx test/test-credential-staging.mjs && npx tsx test/test-output-formatters.mjs && npx tsx test/test-agent-types.mjs && npx tsx test/test-transport.mjs && npx tsx test/test-session-update-handlers.mjs && npx tsx test/test-session-scanner.mjs && npx tsx test/test-hypha-client.mjs && npx tsx test/test-hook-settings.mjs && npx tsx test/test-session-service-logic.mjs && npx tsx test/test-daemon-persistence.mjs && npx tsx test/test-detect-isolation.mjs && npx tsx test/test-machine-service-logic.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-codex-backend.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.mjs && npx tsx test/test-hook-server.mjs && npx tsx test/test-session-commands.mjs && npx tsx test/test-interactive-console.mjs && npx tsx test/test-session-messages.mjs && npx tsx test/test-skills.mjs && npx tsx test/test-agent-grouping.mjs && npx tsx test/test-ralph-loop-integration.mjs && npx tsx test/test-ralph-loop-modes.mjs && npx tsx test/test-machine-list-directory.mjs && npx tsx test/test-service-commands.mjs && npx tsx test/test-supervisor.mjs && npx tsx test/test-clear-detection.mjs && npx tsx test/test-session-consolidation.mjs",
22
+ test: "npx tsx test/test-authorize.mjs && npx tsx test/test-session-helpers.mjs && npx tsx test/test-cli-routing.mjs && npx tsx test/test-security-context.mjs && npx tsx test/test-ralph-loop.mjs && npx tsx test/test-message-helpers.mjs && npx tsx test/test-agent-config.mjs && npx tsx test/test-wrap-command.mjs && npx tsx test/test-credential-staging.mjs && npx tsx test/test-output-formatters.mjs && npx tsx test/test-agent-types.mjs && npx tsx test/test-transport.mjs && npx tsx test/test-session-update-handlers.mjs && npx tsx test/test-session-scanner.mjs && npx tsx test/test-hypha-client.mjs && npx tsx test/test-hook-settings.mjs && npx tsx test/test-session-service-logic.mjs && npx tsx test/test-daemon-persistence.mjs && npx tsx test/test-detect-isolation.mjs && npx tsx test/test-machine-service-logic.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-codex-backend.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.mjs && npx tsx test/test-hook-server.mjs && npx tsx test/test-session-commands.mjs && npx tsx test/test-interactive-console.mjs && npx tsx test/test-session-messages.mjs && npx tsx test/test-skills.mjs && npx tsx test/test-agent-grouping.mjs && npx tsx test/test-ralph-loop-integration.mjs && npx tsx test/test-ralph-loop-modes.mjs && npx tsx test/test-machine-list-directory.mjs && npx tsx test/test-service-commands.mjs && npx tsx test/test-supervisor.mjs && npx tsx test/test-clear-detection.mjs && npx tsx test/test-session-consolidation.mjs && npx tsx test/test-inbox.mjs",
23
23
  "test:hypha": "node --no-warnings test/test-hypha-service.mjs",
24
24
  dev: "tsx src/cli.ts",
25
25
  "dev:daemon": "tsx src/cli.ts daemon start-sync",
@@ -28,7 +28,7 @@ var scripts = {
28
28
  var dependencies = {
29
29
  "@agentclientprotocol/sdk": "^0.14.1",
30
30
  "@modelcontextprotocol/sdk": "^1.25.3",
31
- "hypha-rpc": "0.21.29",
31
+ "hypha-rpc": "0.21.34",
32
32
  "node-pty": "^1.1.0",
33
33
  ws: "^8.18.0",
34
34
  yaml: "^2.8.2",
@@ -2,7 +2,7 @@ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(im
2
2
  import os from 'node:os';
3
3
  import { join, resolve } from 'node:path';
4
4
  import { mkdirSync, writeFileSync, existsSync, unlinkSync, readFileSync, watch } from 'node:fs';
5
- import { c as connectToHypha, a as registerSessionService } from './run-lhAjX4NB.mjs';
5
+ import { c as connectToHypha, a as registerSessionService } from './run-BnFGIK0c.mjs';
6
6
  import { createServer } from 'node:http';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { createInterface } from 'node:readline';