super-dsh 0.3.0-e → 0.3.0-g

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 (41) hide show
  1. package/README.md +13 -55
  2. package/client/index.js +141 -10
  3. package/cordis.patch.yml +6 -3
  4. package/package.json +12 -5
  5. package/remote/file-worker.js +341 -0
  6. package/remote/plugin.d.ts +523 -0
  7. package/remote/plugin.js +4979 -0
  8. package/remote/provenance.json +64 -0
  9. package/superd-hub/dist/a2a-row.d.ts +18 -2
  10. package/superd-hub/dist/a2a-row.js +11 -69
  11. package/superd-hub/dist/bundle-setup.d.ts +16 -6
  12. package/superd-hub/dist/bundle-setup.js +84 -148
  13. package/superd-hub/dist/client/companion-api.d.ts +5 -0
  14. package/superd-hub/dist/client/companion-api.js +30 -0
  15. package/superd-hub/dist/companion-contract.d.ts +9 -0
  16. package/superd-hub/dist/companion-contract.js +1 -0
  17. package/superd-hub/dist/companions.d.ts +30 -0
  18. package/superd-hub/dist/companions.js +209 -0
  19. package/superd-hub/dist/exec-pty-framing.d.ts +3 -1
  20. package/superd-hub/dist/exec-pty-framing.js +12 -4
  21. package/superd-hub/dist/exec-pty-session.d.ts +2 -0
  22. package/superd-hub/dist/exec-pty-session.js +7 -13
  23. package/superd-hub/dist/exec.d.ts +5 -2
  24. package/superd-hub/dist/exec.js +34 -54
  25. package/superd-hub/dist/fusion-transport.js +1 -0
  26. package/superd-hub/dist/gateway.js +24 -11
  27. package/superd-hub/dist/hub-tool.d.ts +3 -0
  28. package/superd-hub/dist/hub-tool.js +13 -5
  29. package/superd-hub/dist/remote-file-rpc.d.ts +20 -0
  30. package/superd-hub/dist/remote-file-rpc.js +574 -0
  31. package/superd-hub/dist/remote-job-client.d.ts +3 -0
  32. package/superd-hub/dist/remote-job-client.js +197 -0
  33. package/superd-hub/dist/remote-job-rpc.d.ts +21 -0
  34. package/superd-hub/dist/remote-job-rpc.js +155 -0
  35. package/superd-hub/dist/remote-provider.d.ts +13 -0
  36. package/superd-hub/dist/remote-provider.js +151 -0
  37. package/superd-hub/dist/remote-row.d.ts +6 -0
  38. package/superd-hub/dist/remote-row.js +13 -0
  39. package/superd-hub/lib/client/index.js +141 -10
  40. package/superd-hub/package.json +1 -2
  41. package/superd-hub/scripts/register-companion.mjs +0 -100
@@ -190,7 +190,7 @@ const DESCRIPTION = 'SuperD Hub — agent-to-agent messaging across the Super D
190
190
  ' {action:"send", agent?, conversationId?, title?, message, delivery?} → open-or-resume: omit conversationId to OPEN (then agent = the recipient, REQUIRED; title optional; message is the first turn); pass conversationId to RESUME (agent optional — the hub derives the route; a wrong agent is refused). Receipt {outcome: delivered|accepted|failed, messageId, conversationId, sessionId, created, error?, note?}: `delivered` = end-to-end complete; `accepted` = the hub took it and the SAME in-flight request keeps running (its `delivered`/`undelivered` outcome arrives as a notice — do not resend); `failed` = immediate rejection.\n' +
191
191
  ' {action:"read"} → sweep messages buffered for this session while it was not live.\n' +
192
192
  ' {action:"stop", conversationId, agent?, scope?} → cancel the conversation\'s ACTIVE turn (the session owner is derived from the conversation id; agent is optional). `stopped:true` means this call cancelled a live turn; a turn that finished on its own is IDLE, never `stopped` — so stop answers stopped:false with a note when nothing was running.\n' +
193
- ' {action:"exec", cmd, machine?, cwd?, timeoutSec?, mode?} → run one shell command on a machine (default: this machine). mode "oneshot" (default): {exit, stdout (last 30k), stderr, durationMs, truncated, timedOut, outcome}; cwd sets its working directory. mode "pty": a PERSISTENT shell per (your session, machine) — the shell OWNS its cwd and env and they SURVIVE across dispatches (cd once inside the command, then keep working); {output (tail 30k), exit, cwd, timedOut, reconnected, durationMs}. cwd is oneshot-only: passing it with mode "pty" is refused (use `cd <dir> && …` inside the command). Prefer oneshot for independent commands; pty when shell state matters.\n' +
193
+ ' {action:"exec", cmd, machine?, cwd?, stdin?, timeoutSec?, mode?} → run one shell command on a remote machine (machine required; self/local execution disabled unless localExec is explicitly enabled). mode "oneshot" (default): {exit, stdout (last 30k), stderr, durationMs, truncated, timedOut, outcome}; cwd sets its working directory. String stdin is piped and closed in oneshot; in PTY it is written immediately after cmd (REPL input, not script mode). Hub oneshot hard retention is 4MiB bytes per stream, PTY is 4,000,000 UTF-16 code units. outputStats reports real total/retained/dropped/returned and units; discarded head cannot be recovered by restarting. mode "pty": a PERSISTENT shell per (your session, machine) — the shell OWNS its cwd and env and they SURVIVE across dispatches (cd once inside the command, then keep working); {output (tail 30k), exit, cwd, timedOut, reconnected, durationMs}. cwd is oneshot-only: passing it with mode "pty" is refused (use `cd <dir> && …` inside the command). Prefer oneshot for independent commands; pty when shell state matters.\n' +
194
194
  'Addresses are "<m4>-<a6>" (machine-agent); call agents first to list valid ids. delivery: "queue" (default) is injected into the peer\'s session as a waking turn — it never interrupts an active turn, it queues behind it; "steer" submits steering for the peer\'s nearest step boundary — use it only when urgency demands. NEVER poll for a reply: the peer\'s reply arrives in this conversation as a new message WHEN THE PEER SENDS one (peers that never use the channel get their last output at turn end delivered as their reply instead, form=transcript); a turn that ends with no channel artifact yields one notice whose reason= distinguishes peer-silent (ended, said nothing) / peer-error (stream died or turn aborted) / stopped-by-initiator (you stopped it). read only sweeps what was buffered while this session was down. stop is a hard stop of the peer\'s active turn (the UI stop button); scope "session" degrades to turn-only — no session-close exists upstream — and the conversation stays resumable: send again to resume it. agent_status reads a cache refreshed by the 5-minute sweep (collectedAt says when); the window is alive-first, ≤5 rows, newest first, and not being in it implies nothing; a `note` says why when the window has no collection behind it (the last collection failed, or none has happened yet). MESSAGING HAS NO STATUS QUERY: to check whether a peer is idle or running, call agent_status (a 5-minute cache — never a delivery receipt); if that is not enough and you cannot wait, send another message.';
195
195
  /**
196
196
  * Build the one SuperD Hub tool.
@@ -235,7 +235,7 @@ export function createSuperdHubTool(deps) {
235
235
  },
236
236
  machine: {
237
237
  type: 'string',
238
- description: 'exec target: an m4 machine id (defaults to this machine). The initiator-side registry row may disable exec per machine (execEnabled).',
238
+ description: 'exec target: a remote m4 machine id (required; self disabled unless localExec is enabled). The initiator-side registry row may disable exec per machine (execEnabled).',
239
239
  },
240
240
  cmd: {
241
241
  type: 'string',
@@ -245,6 +245,7 @@ export function createSuperdHubTool(deps) {
245
245
  type: 'string',
246
246
  description: 'exec oneshot: optional absolute working directory. Not accepted with mode "pty" (the persistent shell keeps its own session cwd — pass `cd <dir> && …` in the command).',
247
247
  },
248
+ stdin: { type: 'string', description: 'exec input: oneshot pipes this string then closes stdin; PTY writes it immediately after cmd. This is not a script carrier; use remote script for local files.' },
248
249
  timeoutSec: {
249
250
  type: 'integer',
250
251
  description: 'exec: timeout in seconds, 1–600 (default 120). SIGTERM then SIGKILL to the process group.',
@@ -286,11 +287,14 @@ export function createSuperdHubTool(deps) {
286
287
  stdout: { type: 'json', description: 'exec: the last 30k of stdout' },
287
288
  stderr: { type: 'json', description: 'exec: the last 30k of stderr' },
288
289
  durationMs: { type: 'integer', description: 'exec: wall-clock duration' },
290
+ outputStats: { type: 'json', description: 'exec per-stream counters with explicit bytes/utf16 units; total, retained, dropped head, returned payload (excludes banners), retentionLimit. Absent on older peers: exact metrics unavailable.' },
289
291
  truncated: { type: 'boolean', description: 'exec: a stream\'s total output exceeded the returned tail window' },
290
292
  timedOut: { type: 'boolean', description: 'exec: the timeout fired (SIGTERM→SIGKILL to the group)' },
291
293
  },
292
294
  },
293
- render: (_args, value) => [{ type: 'text', text: JSON.stringify(value) }],
295
+ render: (_args, value) => [{ type: 'text', text: JSON.stringify(value.action === 'exec' && value.outputStats === undefined
296
+ ? { ...value, note: 'Peer output metrics omitted: exact total/retained/dropped unavailable; returned tail only.' }
297
+ : value) }],
294
298
  },
295
299
  async execute(args, exec) {
296
300
  // One uniform gate first: every leg is session-bound A2A (D9 — replies
@@ -403,6 +407,8 @@ export function createSuperdHubTool(deps) {
403
407
  };
404
408
  }
405
409
  case 'exec': {
410
+ if (!deps.localExec && (!args.machine || args.machine === deps.exec.selfM4()))
411
+ throw new Error('[E_LOCAL_EXEC_DISABLED] superd-hub: select a remote machine from agents; local execution is disabled (localExec=false)');
406
412
  if (args.mode === 'pty') {
407
413
  if (typeof args.cmd !== 'string' || args.cmd.trim() === '')
408
414
  throw new Error('[E_BAD_EXEC] superd-hub: exec: cmd must be a non-empty string');
@@ -415,13 +421,14 @@ export function createSuperdHubTool(deps) {
415
421
  const sessionKey = initiatorOfExec(deps, exec).sessionId;
416
422
  const machine = args.machine ?? deps.exec.selfM4();
417
423
  try {
418
- const r = await deps.exec.pty(sessionKey, machine, args.cmd, { ...(args.timeoutSec === undefined ? {} : { timeoutSec: args.timeoutSec }) });
419
- const out = tailWindow(r.output, EXEC_TAIL_WINDOW);
424
+ const r = await deps.exec.pty(sessionKey, machine, args.cmd, { ...(args.timeoutSec === undefined ? {} : { timeoutSec: args.timeoutSec }), ...(args.stdin === undefined ? {} : { stdin: args.stdin }) });
425
+ const out = tailWindow(r.output, EXEC_TAIL_WINDOW, r.outputStats?.stdout);
420
426
  return {
421
427
  action,
422
428
  mode: 'pty',
423
429
  machine,
424
430
  output: out.text,
431
+ ...(out.stats ? { outputStats: { stdout: out.stats } } : {}),
425
432
  exit: r.exit,
426
433
  cwd: r.cwd,
427
434
  timedOut: r.timedOut,
@@ -436,6 +443,7 @@ export function createSuperdHubTool(deps) {
436
443
  }
437
444
  const parsed = parseOneShotExecBody({
438
445
  cmd: args.cmd,
446
+ ...(args.stdin === undefined ? {} : { stdin: args.stdin }),
439
447
  ...(args.cwd === undefined ? {} : { cwd: args.cwd }),
440
448
  ...(args.timeoutSec === undefined ? {} : { timeoutSec: args.timeoutSec }),
441
449
  });
@@ -0,0 +1,20 @@
1
+ import { type BinaryFileEndpoint } from '../../remote/plugin.js';
2
+ import type { PtyExecutorOptions } from './exec-pty-rpc.js';
3
+ export declare const FILE_IDLE_MS = 6000;
4
+ export declare const FILE_SOCKET_CLOSE_MS = 1000;
5
+ export declare const FILE_CLEANUP_MS: number;
6
+ export declare const FILE_LEASE_PROTOCOL = 1;
7
+ export declare const REMOTE_FILE_PATH = "/api/superd/file";
8
+ export declare function registerRemoteFileRpc(real: {
9
+ registerUpgrade(route: {
10
+ path: string;
11
+ handler: (req: unknown, socket: unknown, head: Buffer) => void;
12
+ }): unknown;
13
+ }, opts: PtyExecutorOptions): Promise<() => Promise<void>>;
14
+ interface Connection {
15
+ origin: string;
16
+ cookie: string;
17
+ }
18
+ /** Completion owns lease cleanup, local socket closure and (for import) the supplied source FD. */
19
+ export declare function createRemoteFileEndpoint(connection: () => Connection, providerSignal?: AbortSignal, track?: (done: Promise<void>) => void): BinaryFileEndpoint;
20
+ export {};