@idleware/ringi 0.7.2 → 0.8.1

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 (201) hide show
  1. package/README.md +18 -11
  2. package/package.json +1 -1
  3. package/src/main/resources/skill/ringi/SKILL.md +3 -4
  4. package/target/dts/adapters/{transport-git → store-git}/branches.d.ts +1 -3
  5. package/target/dts/adapters/{transport-git → store-git}/index.d.ts +0 -1
  6. package/target/dts/adapters/store-git/marks.d.ts +21 -0
  7. package/target/dts/adapters/{transport-git → store-git}/remote/push.d.ts +0 -1
  8. package/target/dts/adapters/store-git/remote/stream-check.d.ts +12 -0
  9. package/target/dts/adapters/store-git/remote/stream-control.d.ts +8 -0
  10. package/target/dts/adapters/store-git/remote/stream-facts.d.ts +4 -0
  11. package/target/dts/adapters/store-git/remote/streams.d.ts +31 -0
  12. package/target/dts/adapters/store-git/remote/sync-streams.d.ts +2 -0
  13. package/target/dts/adapters/{transport-git → store-git}/remote/types.d.ts +5 -4
  14. package/target/dts/adapters/{transport-git → store-git}/remote.d.ts +1 -4
  15. package/target/dts/adapters/{transport-git → store-git}/repo.d.ts +3 -2
  16. package/target/dts/adapters/{transport-git → store-git}/signing.d.ts +0 -1
  17. package/target/dts/clients/cli/operator/hub-commands.d.ts +0 -2
  18. package/target/dts/clients/cli/operator/index.d.ts +1 -1
  19. package/target/dts/clients/cli/operator/sessions.d.ts +0 -1
  20. package/target/dts/clients/cli/operator/where-format.d.ts +1 -1
  21. package/target/dts/clients/cli/shared/index.d.ts +2 -2
  22. package/target/dts/clients/cli/shared/messages.d.ts +0 -1
  23. package/target/dts/clients/cli/shared/profile.d.ts +0 -1
  24. package/target/dts/clients/cli/skill/index.d.ts +2 -1
  25. package/target/dts/core/agents/overview.d.ts +4 -7
  26. package/target/dts/core/agents/sessions/index.d.ts +0 -1
  27. package/target/dts/core/agents/sessions/join.d.ts +1 -2
  28. package/target/dts/core/hub/history/index.d.ts +1 -10
  29. package/target/dts/core/hub/ports/store.d.ts +35 -23
  30. package/target/dts/core/hub/rooms/address.d.ts +6 -0
  31. package/target/dts/core/hub/rooms/adoption.d.ts +7 -0
  32. package/target/dts/core/hub/rooms/compat.d.ts +3 -1
  33. package/target/dts/core/hub/rooms/contracts.d.ts +16 -0
  34. package/target/dts/core/hub/rooms/hubs.d.ts +3 -3
  35. package/target/dts/core/hub/rooms/index.d.ts +5 -6
  36. package/target/dts/core/hub/rooms/room-catalogue.d.ts +9 -0
  37. package/target/dts/core/hub/rooms/room-life.d.ts +10 -0
  38. package/target/dts/core/hub/rooms/room-view.d.ts +3 -0
  39. package/target/dts/core/hub/rooms/rooms.d.ts +4 -2
  40. package/target/dts/core/hub/signals/check.d.ts +2 -2
  41. package/target/dts/core/hub/signals/model.d.ts +2 -10
  42. package/target/dts/core/hub/signals/pins.d.ts +2 -2
  43. package/target/dts/core/hub/usecases/config.d.ts +0 -1
  44. package/target/dts/core/hub/usecases/context.d.ts +1 -2
  45. package/target/dts/core/hub/usecases/hubs.d.ts +1 -8
  46. package/target/dts/core/hub/usecases/invite.d.ts +12 -0
  47. package/target/dts/core/hub/usecases/room.d.ts +0 -1
  48. package/target/dts/core/hub/usecases/rooms.d.ts +9 -7
  49. package/target/dts/core/hub/usecases/roster.d.ts +1 -2
  50. package/target/dts/core/hub/work/index.d.ts +0 -1
  51. package/target/dts/index.d.ts +1 -1
  52. package/target/esm/adapters/{tool-claude → agent-claude}/index.js +2 -2
  53. package/target/esm/adapters/{tool-codex → agent-codex}/index.js +2 -2
  54. package/target/esm/adapters/{tool-cursor → agent-cursor}/index.js +1 -1
  55. package/target/esm/adapters/{tool-traces → agent-traces}/index.js +1 -1
  56. package/target/esm/adapters/state-fs/index.js +2 -2
  57. package/target/esm/adapters/{transport-git → store-git}/branches.js +21 -27
  58. package/target/esm/adapters/{transport-git → store-git}/index.js +10 -28
  59. package/target/esm/adapters/store-git/marks.js +86 -0
  60. package/target/esm/adapters/{transport-git → store-git}/remote/commits.js +3 -1
  61. package/target/esm/adapters/{transport-git → store-git}/remote/git.js +8 -1
  62. package/target/esm/adapters/{transport-git → store-git}/remote/keys.js +8 -3
  63. package/target/esm/adapters/{transport-git → store-git}/remote/push-retry.js +24 -6
  64. package/target/esm/adapters/store-git/remote/push-validate.js +19 -0
  65. package/target/esm/adapters/{transport-git → store-git}/remote/push.js +13 -14
  66. package/target/esm/adapters/store-git/remote/stream-check.js +44 -0
  67. package/target/esm/adapters/store-git/remote/stream-control.js +33 -0
  68. package/target/esm/adapters/store-git/remote/stream-facts.js +40 -0
  69. package/target/esm/adapters/store-git/remote/streams.js +76 -0
  70. package/target/esm/adapters/store-git/remote/sync-streams.js +28 -0
  71. package/target/esm/adapters/store-git/remote/sync.js +59 -0
  72. package/target/esm/adapters/{transport-git → store-git}/remote/types.js +0 -3
  73. package/target/esm/adapters/{transport-git → store-git}/remote.js +1 -4
  74. package/target/esm/adapters/{transport-git → store-git}/repo.js +42 -4
  75. package/target/esm/adapters/{transport-git → store-git}/signing.js +1 -9
  76. package/target/esm/adapters/store-git/transport.js +60 -0
  77. package/target/esm/clients/cli/agent/index.js +1 -1
  78. package/target/esm/clients/cli/agent/session.js +10 -10
  79. package/target/esm/clients/cli/commands.js +5 -5
  80. package/target/esm/clients/cli/context.js +1 -1
  81. package/target/esm/clients/cli/help.js +15 -21
  82. package/target/esm/clients/cli/operator/heartbeat-format.js +1 -1
  83. package/target/esm/clients/cli/operator/heartbeat.js +1 -2
  84. package/target/esm/clients/cli/operator/hub-commands.js +6 -19
  85. package/target/esm/clients/cli/operator/hub.js +2 -2
  86. package/target/esm/clients/cli/operator/index.js +2 -2
  87. package/target/esm/clients/cli/operator/room.js +25 -32
  88. package/target/esm/clients/cli/operator/sessions.js +4 -22
  89. package/target/esm/clients/cli/operator/where-format.js +2 -1
  90. package/target/esm/clients/cli/operator/where.js +5 -7
  91. package/target/esm/clients/cli/shared/index.js +2 -2
  92. package/target/esm/clients/cli/shared/messages.js +2 -12
  93. package/target/esm/clients/cli/shared/profile.js +1 -6
  94. package/target/esm/clients/cli/skill/index.js +14 -19
  95. package/target/esm/composition/index.js +4 -4
  96. package/target/esm/core/agents/heartbeat/pulse.js +4 -4
  97. package/target/esm/core/agents/overview.js +13 -25
  98. package/target/esm/core/agents/sessions/binding.js +1 -1
  99. package/target/esm/core/agents/sessions/index.js +3 -2
  100. package/target/esm/core/agents/sessions/join.js +17 -9
  101. package/target/esm/core/agents/sessions/resume.js +3 -6
  102. package/target/esm/core/hub/capabilities.js +1 -4
  103. package/target/esm/core/hub/history/index.js +23 -13
  104. package/target/esm/core/hub/ports/store.js +2 -2
  105. package/target/esm/core/hub/rooms/address.js +18 -0
  106. package/target/esm/core/hub/rooms/adoption.js +32 -0
  107. package/target/esm/core/hub/rooms/compat.js +39 -14
  108. package/target/esm/core/hub/rooms/contracts.js +62 -0
  109. package/target/esm/core/hub/rooms/hubs.js +33 -56
  110. package/target/esm/core/hub/rooms/index.js +2 -2
  111. package/target/esm/core/hub/rooms/messages.js +6 -6
  112. package/target/esm/core/hub/rooms/room-catalogue.js +31 -0
  113. package/target/esm/core/hub/rooms/room-life.js +59 -0
  114. package/target/esm/core/hub/rooms/room-view.js +39 -0
  115. package/target/esm/core/hub/rooms/rooms.js +26 -37
  116. package/target/esm/core/hub/signals/check.js +21 -26
  117. package/target/esm/core/hub/signals/index.js +10 -10
  118. package/target/esm/core/hub/signals/model.js +0 -2
  119. package/target/esm/core/hub/signals/pins.js +44 -16
  120. package/target/esm/core/hub/signals/write.js +8 -10
  121. package/target/esm/core/hub/usecases/actor.js +1 -1
  122. package/target/esm/core/hub/usecases/config.js +2 -2
  123. package/target/esm/core/hub/usecases/context.js +5 -8
  124. package/target/esm/core/hub/usecases/hubs.js +16 -33
  125. package/target/esm/core/hub/usecases/invite.js +26 -0
  126. package/target/esm/core/hub/usecases/room.js +4 -5
  127. package/target/esm/core/hub/usecases/rooms.js +40 -35
  128. package/target/esm/core/hub/usecases/roster.js +12 -21
  129. package/target/esm/core/hub/usecases/send.js +10 -6
  130. package/target/esm/core/hub/work/parse.js +1 -1
  131. package/target/esm/lib/fail.js +2 -2
  132. package/target/dts/adapters/transport-git/marks.d.ts +0 -20
  133. package/target/dts/adapters/transport-git/remote/bootstrap.d.ts +0 -7
  134. package/target/dts/adapters/transport-git/remote/heartbeat-name.d.ts +0 -6
  135. package/target/dts/adapters/transport-git/remote/heartbeat-object.d.ts +0 -10
  136. package/target/dts/adapters/transport-git/remote/heartbeat-push.d.ts +0 -2
  137. package/target/dts/adapters/transport-git/remote/heartbeat.d.ts +0 -7
  138. package/target/dts/adapters/transport-git/remote/signals.d.ts +0 -15
  139. package/target/dts/adapters/transport-git/remote/sync-heartbeat.d.ts +0 -2
  140. package/target/dts/adapters/transport-git/remote/sync-rooms.d.ts +0 -6
  141. package/target/dts/adapters/transport-git/remote/sync-tags.d.ts +0 -8
  142. package/target/dts/adapters/transport-git/tags.d.ts +0 -15
  143. package/target/dts/clients/cli/skill/targets.d.ts +0 -3
  144. package/target/dts/core/hub/usecases/staging.d.ts +0 -8
  145. package/target/esm/adapters/transport-git/marks.js +0 -82
  146. package/target/esm/adapters/transport-git/remote/bootstrap.js +0 -47
  147. package/target/esm/adapters/transport-git/remote/heartbeat-name.js +0 -19
  148. package/target/esm/adapters/transport-git/remote/heartbeat-object.js +0 -40
  149. package/target/esm/adapters/transport-git/remote/heartbeat-push.js +0 -44
  150. package/target/esm/adapters/transport-git/remote/heartbeat.js +0 -44
  151. package/target/esm/adapters/transport-git/remote/push-validate.js +0 -39
  152. package/target/esm/adapters/transport-git/remote/signals.js +0 -63
  153. package/target/esm/adapters/transport-git/remote/sync-heartbeat.js +0 -26
  154. package/target/esm/adapters/transport-git/remote/sync-rooms.js +0 -38
  155. package/target/esm/adapters/transport-git/remote/sync-tags.js +0 -48
  156. package/target/esm/adapters/transport-git/remote/sync.js +0 -38
  157. package/target/esm/adapters/transport-git/tags.js +0 -21
  158. package/target/esm/adapters/transport-git/transport.js +0 -29
  159. package/target/esm/clients/cli/skill/targets.js +0 -20
  160. package/target/esm/core/hub/usecases/staging.js +0 -60
  161. /package/target/dts/adapters/{tool-claude → agent-claude}/index.d.ts +0 -0
  162. /package/target/dts/adapters/{tool-codex → agent-codex}/index.d.ts +0 -0
  163. /package/target/dts/adapters/{tool-cursor → agent-cursor}/index.d.ts +0 -0
  164. /package/target/dts/adapters/{tool-traces → agent-traces}/index.d.ts +0 -0
  165. /package/target/dts/adapters/{transport-git → store-git}/files.d.ts +0 -0
  166. /package/target/dts/adapters/{transport-git → store-git}/remote/admit.d.ts +0 -0
  167. /package/target/dts/adapters/{transport-git → store-git}/remote/alarms.d.ts +0 -0
  168. /package/target/dts/adapters/{transport-git → store-git}/remote/branch-commit.d.ts +0 -0
  169. /package/target/dts/adapters/{transport-git → store-git}/remote/branch-control.d.ts +0 -0
  170. /package/target/dts/adapters/{transport-git → store-git}/remote/branch-scan.d.ts +0 -0
  171. /package/target/dts/adapters/{transport-git → store-git}/remote/branch.d.ts +0 -0
  172. /package/target/dts/adapters/{transport-git → store-git}/remote/cache.d.ts +0 -0
  173. /package/target/dts/adapters/{transport-git → store-git}/remote/commits.d.ts +0 -0
  174. /package/target/dts/adapters/{transport-git → store-git}/remote/forget.d.ts +0 -0
  175. /package/target/dts/adapters/{transport-git → store-git}/remote/git.d.ts +0 -0
  176. /package/target/dts/adapters/{transport-git → store-git}/remote/heartbeat-facts.d.ts +0 -0
  177. /package/target/dts/adapters/{transport-git → store-git}/remote/keys.d.ts +0 -0
  178. /package/target/dts/adapters/{transport-git → store-git}/remote/main.d.ts +0 -0
  179. /package/target/dts/adapters/{transport-git → store-git}/remote/process.d.ts +0 -0
  180. /package/target/dts/adapters/{transport-git → store-git}/remote/push-retry.d.ts +0 -0
  181. /package/target/dts/adapters/{transport-git → store-git}/remote/push-validate.d.ts +0 -0
  182. /package/target/dts/adapters/{transport-git → store-git}/remote/roster.d.ts +0 -0
  183. /package/target/dts/adapters/{transport-git → store-git}/remote/signature.d.ts +0 -0
  184. /package/target/dts/adapters/{transport-git → store-git}/remote/sync.d.ts +0 -0
  185. /package/target/dts/adapters/{transport-git → store-git}/run.d.ts +0 -0
  186. /package/target/dts/adapters/{transport-git → store-git}/transport.d.ts +0 -0
  187. /package/target/esm/adapters/{transport-git → store-git}/files.js +0 -0
  188. /package/target/esm/adapters/{transport-git → store-git}/remote/admit.js +0 -0
  189. /package/target/esm/adapters/{transport-git → store-git}/remote/alarms.js +0 -0
  190. /package/target/esm/adapters/{transport-git → store-git}/remote/branch-commit.js +0 -0
  191. /package/target/esm/adapters/{transport-git → store-git}/remote/branch-control.js +0 -0
  192. /package/target/esm/adapters/{transport-git → store-git}/remote/branch-scan.js +0 -0
  193. /package/target/esm/adapters/{transport-git → store-git}/remote/branch.js +0 -0
  194. /package/target/esm/adapters/{transport-git → store-git}/remote/cache.js +0 -0
  195. /package/target/esm/adapters/{transport-git → store-git}/remote/forget.js +0 -0
  196. /package/target/esm/adapters/{transport-git → store-git}/remote/heartbeat-facts.js +0 -0
  197. /package/target/esm/adapters/{transport-git → store-git}/remote/main.js +0 -0
  198. /package/target/esm/adapters/{transport-git → store-git}/remote/process.js +0 -0
  199. /package/target/esm/adapters/{transport-git → store-git}/remote/roster.js +0 -0
  200. /package/target/esm/adapters/{transport-git → store-git}/remote/signature.js +0 -0
  201. /package/target/esm/adapters/{transport-git → store-git}/run.js +0 -0
@@ -8,8 +8,8 @@ import { scopeLine, taskLine, waiting } from '../shared/index.js';
8
8
  export const briefing = (s) => {
9
9
  const r = Session.briefing(s);
10
10
  const auto = r.start.quorum !== null;
11
- out(`${s.agent} in ${s.hub}/${s.room}; scope: ${scopeLine(s, auto)}`);
12
- out('agent commands: ringi agent inbox | reply <id> … | send … | tasks | proposals | whoami. A turn: inbox, your part, replies, end the turn. Never block on a peer.');
11
+ out(`${s.agent} in ${s.room}; scope: ${scopeLine(s, auto)}`);
12
+ out('agent commands: ringi agent inbox | reply <id> … | send … | tasks | whoami. A turn: inbox, your part, replies, end the turn. Never block on a peer.');
13
13
  if (!r.start.started)
14
14
  return out(waiting(s.room, r.start));
15
15
  if (auto)
@@ -21,16 +21,16 @@ export const briefing = (s) => {
21
21
  showInbox(r.actor, r.inbox, { _: [] });
22
22
  };
23
23
  export const join = (o) => {
24
- const [hub, room] = o._;
25
- if (!hub || !room)
26
- fail('usage: ringi join <hub> <room> [--as <id>] [--scope "<what the operator delegates>"]');
27
- const r = Session.join({ hub, room, agent: opt(o, 'as'), scope: opt(o, 'scope') });
24
+ const [room] = o._;
25
+ if (!room)
26
+ fail('usage: ringi join <room or its invitation> [--as <id>] [--scope "<what the operator delegates>"]');
27
+ const r = Session.join({ room, agent: opt(o, 'as'), scope: opt(o, 'scope') });
28
28
  if (r.key) {
29
- out(`${r.agent}'s key on this machine (${r.key.fingerprint}). Ask the root to admit it, then join again:\n ringi room admit ${r.agent} '${r.key.publicKey}' --hub ${r.hub} --room ${r.room}`);
29
+ out(`${r.agent}'s key on this machine (${r.key.fingerprint}). Ask the root to admit it, then join again:\n ringi room admit ${r.agent} '${r.key.publicKey}' --room ${r.room}`);
30
30
  process.exitCode = 3;
31
31
  return;
32
32
  }
33
- out(`joined ${r.hub}/${r.room} as ${r.agent}`);
33
+ out(`joined ${r.room} as ${r.agent}`);
34
34
  Heartbeat.ensurePulse(process.argv[1]);
35
35
  briefing(r.session);
36
36
  };
@@ -41,10 +41,10 @@ export const resume = (o) => {
41
41
  };
42
42
  export const stop = () => {
43
43
  const s = Session.stop();
44
- out(`stopped: ${s.agent} keeps its seat in ${s.hub}/${s.room} and reacts to nothing until the operator says "continue"`);
44
+ out(`stopped: ${s.agent} keeps its seat in ${s.room} and reacts to nothing until the operator says "continue"`);
45
45
  };
46
46
  export const leave = () => {
47
47
  const s = Session.leave();
48
- out(`left ${s.hub}/${s.room}: the seat of ${s.agent} is free; ${s.agent} stays a member until the operator removes it`);
48
+ out(`left ${s.room}: the seat of ${s.agent} is free; ${s.agent} stays a member until the operator removes it`);
49
49
  };
50
50
  //# sourceMappingURL=session.js.map
@@ -7,12 +7,12 @@ import { inbox, take, wait, whoami } from './agent/index.js';
7
7
  import { flag, out, parseArgs } from './args.js';
8
8
  import { operatorCtx } from './context.js';
9
9
  import { helpMarkdown, helpText } from './help.js';
10
- import { forget, heartbeats, hub, pulse, roomCmd, sessions, where } from './operator/index.js';
10
+ import { forget, heartbeats, hub, pulse, roomCmd, where } from './operator/index.js';
11
11
  import { join, leave, resume, stop } from './agent/session.js';
12
- import { add, cat, get, log, profileCmd, read, reply, send, signals, tasks, thread, who } from './shared/index.js';
12
+ import { cat, get, log, profileCmd, read, reply, send, signals, tasks, thread } from './shared/index.js';
13
13
  import { skill } from './skill/index.js';
14
- const SHARED = { add, send, reply, read, thread, tasks, log, cat, get, who, signals, profile: profileCmd };
15
- const AGENT = { ...SHARED, inbox, whoami, status: whoami, wait, take };
14
+ const SHARED = { send, reply, read, thread, tasks, log, cat, get, signals, profile: profileCmd };
15
+ const AGENT = { ...SHARED, inbox, whoami, wait, take };
16
16
  const agentCommand = (_, rest) => {
17
17
  const [sub = 'whoami', ...more] = rest;
18
18
  const fn = AGENT[sub] ?? fail(`unknown: ringi agent ${sub}; see ringi help`);
@@ -26,7 +26,7 @@ const help = (o) => flag(o, 'md') ? void process.stdout.write(helpMarkdown()) :
26
26
  const DIRECT = new Map([
27
27
  ['--version', version], ['-v', version], ['version', version],
28
28
  ['help', help], ['--help', help], ['-h', help], ['skill', skill], ['agent', agentCommand],
29
- ['hub', hub], ['room', roomCmd], ['where', where], ['sessions', sessions], ['heartbeats', heartbeats],
29
+ ['hub', hub], ['room', roomCmd], ['where', where], ['heartbeats', heartbeats],
30
30
  ['pulse', pulse], ['forget', forget], ['join', join], ['continue', resume], ['stop', stop], ['leave', leave]
31
31
  ]);
32
32
  const unknown = (cmd) => {
@@ -2,5 +2,5 @@
2
2
  import * as Context from '../../core/hub/usecases/context.js';
3
3
  import { opt } from './args.js';
4
4
  export { isRef } from '../../core/hub/usecases/room.js';
5
- export const operatorCtx = (o) => Context.operator({ hub: opt(o, 'hub'), room: opt(o, 'room') });
5
+ export const operatorCtx = (o) => Context.operator({ room: opt(o, 'room') });
6
6
  //# sourceMappingURL=context.js.map
@@ -3,42 +3,36 @@ import { about } from '../../core/hub/usecases/context.js';
3
3
  // --- commands ---
4
4
  // [command, who runs it, what it does]: the one table behind `ringi help` and COMMANDS.md.
5
5
  export const TABLE = [
6
- ['hub [list]', 'operator', 'the hubs; `local` exists by default; * marks the current one'],
7
- ['hub create <name> [--signed [--url <git url>]]', 'operator', 'another hub: asserted senders, or signed with a root key made on this machine; --url publishes it'],
8
- ['hub add <name> <git url> --root <public key|file> [--genesis <sha>]', 'operator', 'a replica of a signed hub; the root key comes from you, out of band, never from the hub'],
9
- ['hub switch <name>', 'operator', 'change the terminal\'s current hub; agents stay where they are'],
10
- ['hub amend -m <subject> [--set <key>=<value>]... [--attach <file>:profiles/<name>.json]...', 'operator', 'refine the shared contract: version, capabilities, default profile, profiles'],
11
- ['room list', 'operator', 'rooms of the current hub'],
12
- ['room create <id> [--profile <name>] [--quorum <agents>]', 'operator', 'a room for one piece of work, following a profile; becomes the current room; --quorum: its work starts by itself once that many agents joined (1: at once)'],
6
+ ['hub [list]', 'operator', 'the hubs; `local` exists by default'],
7
+ ['hub create <name> [--signed [--url <address>]]', 'operator', 'another hub: asserted senders, or signed with a root key made on this machine; --url publishes its contract (an address names its store: git+ssh://…, git+https://…, git+file://…)'],
8
+ ['hub amend [--hub <name>] -m <subject> [--set <key>=<value>]... [--attach <file>:profiles/<name>.json]...', 'operator', 'refine the shared contract (of hub local unless named): version, capabilities, default profile, profiles; rooms made from then on follow it'],
9
+ ['room list', 'operator', 'the rooms on this machine; a room\'s name is unique here, whatever hub keeps it'],
10
+ ['room create <id> [--hub <name>] [--profile <name>] [--quorum <agents>] [--url <address>]', 'operator', 'a room for one piece of work, in its own repository (in hub local unless named), following a profile; becomes the current room; --quorum: its work starts by itself once that many agents joined (1: at once); --url: a signed hub publishes the room there and prints the join line for agents elsewhere'],
13
11
  ['room switch <id>', 'operator', 'change the terminal\'s current room; agents stay where they are'],
14
12
  ['room admit <agent> <public key|file>', 'operator', 'signed hubs: admit the key an agent made on its own machine'],
15
- ['room remove <agent>', 'operator', 'local hubs: take an agent out of the current room'],
16
- ['room delete [<id>] --yes', 'operator', 'local hubs: erase a room (default: the current one) and everything kept for it; its sessions leave on their own'],
17
- ['room rebase-contract <id>', 'operator', 'move a room onto the hub\'s current contract'],
18
- ['where [-n n] [--short] [--follow]', 'operator', 'hub, room, sessions (active, stopped, gone), open work, latest messages'],
13
+ ['room delete [<id>] --yes', 'operator', 'erase a room\'s store on this machine (default: the current room) and everything kept for it; its sessions leave on their own'],
14
+ ['where [-n n] [--short] [--follow]', 'operator', 'the room, its hub and contract, sessions (active, stopped, gone), open work, latest messages'],
19
15
  ['send -m <subject> [-m <body>]... [--to <ids>] [--task] [--re <msg>] [--state <s>] [--assign <ids>] [--roles <id>=<label>,...] [--attach <src>[:<dest>]]...', 'operator', 'a message as operator; without --to it goes to the room and wakes nobody; --task opens work of the room\'s profile'],
20
- ['add <src>[:<dest>]... | add [--drop <path>]... [--clear]', 'both', 'stage files for your next message, like git add: their content is taken now; results and state travel only as attachments'],
21
- ['tasks [--all] | log [-n n] | read <msg> | thread <msg> | cat <msg> [<path>] | get <msg> [-o <dir>] | who', 'both', 'reading the room (agents: ringi agent …)'],
16
+ ['tasks [--all] | log [-n n] | read <msg> | thread <msg> | cat <msg> [<path>] | get <msg> [-o <dir>]', 'both', 'reading the room (agents: ringi agent …)'],
22
17
  ['signals [--all] [--repair]', 'both', 'what happened (signals) and where attention is (read and taken marks), each checked; --repair restores your missing signals'],
23
18
  ['profile', 'both', 'the room\'s profile: what a piece of work is, its states, who may move it'],
24
- ['sessions | sessions forget <handle>', 'operator', 'the chats the CLI remembers; drop a stale one'],
25
- ['heartbeats [--json] | heartbeats --published [--room <id>]', 'operator', 'each session\'s pulse on this machine, from its process and its tool\'s trace, without the model: working, waiting (for what) or gone; --published: the room\'s heartbeat tags as an orchestrator reads them'],
26
- ['pulse [--beat <s>] [--once]', 'operator', 'beat for every session here: sync its hub, put its heartbeat tag on the last pulled commit of its room; join and continue start it (RINGI_PULSE=off: not)'],
19
+ ['heartbeats [--json] | heartbeats --published [--room <id>]', 'operator', 'each session\'s pulse on this machine, from its process and its tool\'s trace, without the model: working, waiting (for what) or gone; --published: the room\'s telemetry as an orchestrator reads it'],
20
+ ['pulse [--beat <s>] [--once]', 'operator', 'beat for every session here: sync its room, append its telemetry, naming the last pulled message of its room; join and continue start it (RINGI_PULSE=off: not)'],
27
21
  ['forget <room>/<log>', 'operator', 'after a changed-history alarm: accept a new baseline for that log'],
28
- ['skill install [--project] | uninstall | status | show', 'operator', 'the skill for Claude Code, Codex and Cursor'],
29
- ['join <hub> <room> [--as <id>] [--scope <text>]', 'session', 'bind this chat to a room as an agent, with what the operator delegates'],
30
- ['continue [[<hub>:]<room>/<agent>]', 'session', 'resume this chat\'s binding, also after a restart; naming one takes over a paused or gone one'],
22
+ ['skill install | uninstall', 'operator', 'the skill for Claude Code, Codex and Cursor'],
23
+ ['join <room> [--as <id>] [--scope <text>]', 'session', 'bind this chat to a room as an agent, with what the operator delegates; <room>: its name on this machine, or the operator\'s invitation (ringi:…) to one elsewhere'],
24
+ ['continue [<room>/<agent>]', 'session', 'resume this chat\'s binding, also after a restart; naming one takes over a paused or gone one'],
31
25
  ['stop', 'session', 'pause: keep the seat, react to nothing'],
32
26
  ['leave', 'session', 'release the seat'],
33
27
  ['agent whoami', 'agent', 'identity, room, profile, scope'],
34
28
  ['agent inbox [--peek] [--limit n]', 'agent', 'what is new for you; marks it seen and leaves a read mark on each (--peek: neither)'],
35
29
  ['agent take <work>', 'agent', 'a taken mark: you are on it; others see it in tasks and read. It changes no state'],
36
30
  ['agent send … | reply <msg> -m … [--state <s>] [--assign <ids>] [--roles …] [--attach …] [--all]', 'agent', 'write; answer the message you act on'],
37
- ['agent tasks | log | read | thread | cat | get | who | signals | profile', 'agent', 'reading, as the joined agent'],
31
+ ['agent tasks | log | read | thread | cat | get | signals | profile', 'agent', 'reading, as the joined agent'],
38
32
  ['agent wait [--max <s>]', 'agent', 'hold the line only when the operator asks'],
39
33
  ];
40
34
  export const helpText = () => {
41
- const groups = [['operator', 'operator: in a terminal, in the current hub and room'], ['session', 'session: in a chat, on the operator\'s words'], ['agent', 'agent: during a turn, in the session\'s own room'], ['both', 'operator in a terminal, or an agent as ringi agent …']];
35
+ const groups = [['operator', 'operator: in a terminal, in the current room'], ['session', 'session: in a chat, on the operator\'s words'], ['agent', 'agent: during a turn, in the session\'s own room'], ['both', 'operator in a terminal, or an agent as ringi agent …']];
42
36
  const width = 56;
43
37
  const line = ([cmd, , what]) => cmd.length > width ? ` ringi ${cmd}\n ${' '.repeat(width + 6)} ${what}` : ` ringi ${cmd.padEnd(width)} ${what}`;
44
38
  return [`ringi ${about().version}: distributed agent coordinator. Home: ${about().home} (RINGI_HOME).`,
@@ -3,6 +3,6 @@ import { short } from '../../../lib/index.js';
3
3
  export const publishedLine = (h) => `${h.agent.padEnd(12)} ${(h.waits ? `${h.state} (${h.waits})` : h.state).padEnd(22)} ${h.age}s ago${h.overdue ? ', overdue' : ''} on ${short(h.target)}`;
4
4
  export const pulseLine = ({ session: s, tool, beat: b }) => {
5
5
  const state = b.waits ? `${b.state} (${b.waits})` : b.state;
6
- return `${s.agent.padEnd(12)} ${`${s.hub}/${s.room}`.padEnd(24)} ${state.padEnd(22)} alive ${b.alive === null ? '?' : b.alive ? 'yes' : 'no'} quiet ${b.quiet}s ${tool} ${s.handle}`;
6
+ return `${s.agent.padEnd(12)} ${`${s.room}`.padEnd(24)} ${state.padEnd(22)} alive ${b.alive === null ? '?' : b.alive ? 'yes' : 'no'} quiet ${b.quiet}s ${tool} ${s.handle}`;
7
7
  };
8
8
  //# sourceMappingURL=heartbeat-format.js.map
@@ -1,11 +1,10 @@
1
1
  // heartbeat: `ringi heartbeats` (this machine's sessions, or what a room publishes) and `ringi pulse`.
2
2
  import * as Heartbeat from '../../../core/agents/heartbeat/pulse.js';
3
- import * as Hubs from '../../../core/hub/usecases/hubs.js';
4
3
  import * as Rooms from '../../../core/hub/usecases/rooms.js';
5
4
  import { dump, flag, opt, out } from '../args.js';
6
5
  import { publishedLine, pulseLine } from './heartbeat-format.js';
7
6
  const published = (o) => {
8
- const R = Rooms.roomIn(Hubs.hubOf(opt(o, 'hub')), opt(o, 'room'));
7
+ const R = Rooms.roomNamed(opt(o, 'room'));
9
8
  const hs = Heartbeat.published(R);
10
9
  if (flag(o, 'json'))
11
10
  return dump(hs);
@@ -1,37 +1,24 @@
1
- // hub-commands: `ringi hub list | create | switch | add | amend`.
1
+ // hub-commands: `ringi hub list | create | amend`.
2
2
  import fs from 'node:fs';
3
3
  import * as Hubs from '../../../core/hub/usecases/hubs.js';
4
- import * as Rooms from '../../../core/hub/usecases/rooms.js';
5
- import { fail } from '../../../lib/index.js';
6
4
  import { attachments, flag, list, opt, out, textOf } from '../args.js';
7
5
  export const listHub = (_) => {
8
6
  for (const h of Hubs.hubs())
9
- out(`${h.current ? '*' : ' '} ${h.name.padEnd(12)} ${h.store}, ${h.trust}, contract ${h.contract}, ${h.rooms} room(s)${h.remote ? ` remote ${h.remote}` : ''} ${h.dir}`);
7
+ out(`${h.name.padEnd(12)} ${h.store}, ${h.trust}, ${h.contract ? `contract ${h.contract}` : 'contract only in its rooms'}, ${h.rooms} room(s)${h.remote ? ` remote ${h.remote}` : ''} ${h.dir}`);
10
8
  return;
11
9
  };
12
10
  export const createHub = (o) => {
13
11
  const [, arg] = o._;
14
12
  const r = Hubs.create(arg ?? '', { signed: flag(o, 'signed'), url: opt(o, 'url') });
15
- if (!r.add)
13
+ if (!r.H.signed)
16
14
  return out(`created hub ${arg} (${r.H.dir})`);
17
- return out(`created signed hub ${arg}${r.remote ? `, published to ${r.remote}` : ''}. Its root key stays on this machine (${r.rootKey}).
18
- Give every machine that joins it, out of band:
19
- ${r.add}`);
20
- };
21
- export const switchHub = (o) => {
22
- const [, arg] = o._;
23
- Hubs.use(arg ?? fail('usage: ringi hub switch <name>'));
24
- return out(`current hub: ${arg}; agents keep their own rooms`);
25
- };
26
- export const addHub = (o) => {
27
- const [, arg] = o._;
28
- const H = Hubs.add(arg ?? '', o._[2] ?? '', { root: opt(o, 'root'), genesis: opt(o, 'genesis') });
29
- return out(`added signed hub ${arg} from ${o._[2]}: contract ${H.contract.version}, ${Rooms.rooms(H).length} room(s), root pinned`);
15
+ return out(`created signed hub ${arg}${r.remote ? `, its contract published to ${r.remote}` : ''}. Its root key stays on this machine (${r.rootKey}).
16
+ A room made with --url prints the invitation its agents join by, elsewhere.`);
30
17
  };
31
18
  export const amendHub = (o) => {
32
19
  const H = Hubs.hubOf(opt(o, 'hub'));
33
20
  const files = list(o, 'attach').flatMap(attachments).map(e => ({ path: e.path, content: fs.readFileSync(e.file) }));
34
21
  const r = Hubs.amend(H, { text: textOf(o), set: list(o, 'set'), files });
35
- return out(`amended hub ${H.name}: contract ${r.version}; rooms keep their base until ringi room rebase-contract <room>`);
22
+ return out(`amended hub ${H.name}: contract ${r.version}; rooms made from now on follow it, existing ones keep the contract they were made with`);
36
23
  };
37
24
  //# sourceMappingURL=hub-commands.js.map
@@ -1,7 +1,7 @@
1
1
  // hub: `ringi hub <subcommand>`, by its table (hub-commands.ts).
2
2
  import { fail } from '../../../lib/index.js';
3
- import { addHub, amendHub, createHub, listHub, switchHub } from './hub-commands.js';
4
- const COMMANDS = new Map([['list', listHub], ['create', createHub], ['switch', switchHub], ['add', addHub], ['amend', amendHub]]);
3
+ import { amendHub, createHub, listHub } from './hub-commands.js';
4
+ const COMMANDS = new Map([['list', listHub], ['create', createHub], ['amend', amendHub]]);
5
5
  export const hub = (o) => {
6
6
  const [sub] = o._;
7
7
  const run = COMMANDS.get(sub || 'list') ?? fail(`unknown: hub ${sub}`);
@@ -1,8 +1,8 @@
1
1
  // operator: the commands only the operator runs, as the operator of this machine in its terminal context: hubs, rooms,
2
- // where things stand, sessions, heartbeats and the pulse.
2
+ // where things stand, heartbeats and the pulse.
3
3
  export { heartbeats, pulse } from './heartbeat.js';
4
4
  export { hub } from './hub.js';
5
5
  export { roomCmd } from './room.js';
6
- export { forget, sessionLine, sessions } from './sessions.js';
6
+ export { forget, sessionLine } from './sessions.js';
7
7
  export { where } from './where.js';
8
8
  //# sourceMappingURL=index.js.map
@@ -1,54 +1,47 @@
1
- // room: `ringi room list | create | switch | admit | remove | delete | rebase-contract`.
1
+ // room: `ringi room list | create | switch | admit | delete`, the rooms of this machine by name, whatever hub keeps them.
2
2
  import { roomsActive } from '../../../core/agents/overview.js';
3
3
  import * as Hubs from '../../../core/hub/usecases/hubs.js';
4
4
  import * as Rooms from '../../../core/hub/usecases/rooms.js';
5
5
  import { fail, short } from '../../../lib/index.js';
6
6
  import { flag, opt, out } from '../args.js';
7
- const list = H => {
8
- const rs = roomsActive(H);
7
+ const list = () => {
8
+ const rs = roomsActive();
9
9
  for (const r of rs)
10
- out(`${r.current ? '*' : ' '} ${r.name.padEnd(16)} ${r.members} member(s), ${r.active} active session(s), profile ${r.profile} genesis ${short(r.genesis)}`);
10
+ out(`${r.current ? '*' : ' '} ${r.name.padEnd(16)} ${r.members} member(s), ${r.active} active session(s), profile ${r.profile}, hub ${r.hub} genesis ${short(r.genesis)}`);
11
11
  if (!rs.length)
12
- out(`no rooms in hub ${H.name}: ringi room create <id>`);
12
+ out('no rooms on this machine: ringi room create <id>');
13
13
  };
14
- const create = (H, arg, o) => {
14
+ // In hub `local` unless --hub names another.
15
+ const create = (arg, o) => {
16
+ const H = Hubs.hubOf(opt(o, 'hub'));
15
17
  const quorum = opt(o, 'quorum');
16
- const r = Rooms.create(H, arg ?? '', { profile: opt(o, 'profile'), quorum: quorum === undefined ? undefined : Number(quorum) });
18
+ const r = Rooms.create(H, arg ?? '', { profile: opt(o, 'profile'), quorum: quorum === undefined ? undefined : Number(quorum), url: opt(o, 'url') });
17
19
  const start = quorum === undefined ? '' : ` Its work starts by itself at a quorum of ${quorum} agent(s).`;
18
20
  out(`created room ${arg} in hub ${H.name} with profile ${r.profile}; it is the current room.${start} In each chat that should take part, say "join ${arg} as <id>"`);
21
+ if (r.join)
22
+ out(`Its invitation: in an agent's chat on another machine, the operator says "join <invitation> as <id>", which runs:\n ${r.join}`);
19
23
  };
20
- const use = (H, arg) => {
21
- const R = Rooms.use(H, arg ?? fail('usage: ringi room switch <id>'));
22
- out(`current room: ${H.name}/${R.name}; agents keep their own rooms`);
23
- };
24
- const admit = (H, arg, o) => {
25
- const R = Rooms.roomIn(H, opt(o, 'room'));
26
- Rooms.admit(H, R, arg ?? fail('usage: ringi room admit <agent> <public key|file>'), o._[2] ?? fail('usage: ringi room admit <agent> <public key|file>'));
27
- out(`admitted ${arg} to ${H.name}/${R.name}: its signed messages are accepted from now on; it can join`);
24
+ const use = arg => {
25
+ const R = Rooms.use(arg ?? fail('usage: ringi room switch <id>'));
26
+ out(`current room: ${R.name}; agents keep their own rooms`);
28
27
  };
29
- const remove = (H, arg, o) => {
30
- const R = Rooms.roomIn(H, opt(o, 'room'));
31
- Rooms.remove(H, R, arg ?? fail('usage: ringi room remove <agent>'));
32
- out(`removed ${arg} from ${R.name}: it can no longer write or be woken there; returning needs a fresh join`);
28
+ const admit = (arg, o) => {
29
+ const R = Rooms.roomNamed(opt(o, 'room'));
30
+ Rooms.admit(R.hub, R, arg ?? fail('usage: ringi room admit <agent> <public key|file>'), o._[2] ?? fail('usage: ringi room admit <agent> <public key|file>'));
31
+ out(`admitted ${arg} to ${R.name}: its signed messages are accepted from now on; it can join`);
33
32
  };
34
33
  // Without an id, the room of the current context.
35
- const erase = (H, arg, o) => {
36
- const R = Rooms.roomIn(H, arg ?? opt(o, 'room'));
34
+ const erase = (arg, o) => {
35
+ const R = Rooms.roomNamed(arg ?? opt(o, 'room'));
37
36
  if (!flag(o, 'yes'))
38
- fail(`deleting ${R.name} in hub ${H.name} erases it and everything kept for it, for good. Run again with --yes`);
39
- Rooms.erase(H, R);
40
- out(`deleted room ${R.name}: its branch, signals, pins, evidence and readers' state. Sessions bound to it leave it on their next turn`);
37
+ fail(`deleting ${R.name} erases its store on this machine and everything kept for it, for good. Run again with --yes`);
38
+ Rooms.erase(R);
39
+ out(`deleted room ${R.name}: its repository, signals, pins, evidence and readers' state on this machine. Sessions bound to it leave it on their next turn`);
41
40
  };
42
- const rebase = (H, arg) => {
43
- const R = Rooms.roomIn(H, arg ?? fail('usage: ringi room rebase-contract <id>'));
44
- Rooms.rebase(H, R);
45
- out(`room ${R.name} now follows the hub contract at ${short(H.main)} (${H.contract.version})`);
46
- };
47
- const COMMANDS = new Map([['list', list], ['create', create], ['switch', use], ['admit', admit], ['remove', remove], ['delete', erase], ['rebase-contract', rebase]]);
41
+ const COMMANDS = new Map([['list', list], ['create', create], ['switch', use], ['admit', admit], ['delete', erase]]);
48
42
  export const roomCmd = (o) => {
49
43
  const [sub, arg] = o._;
50
- const H = Hubs.hubOf(opt(o, 'hub'));
51
44
  const run = COMMANDS.get(sub || 'list') ?? fail(`unknown: room ${sub}`);
52
- run(H, arg, o);
45
+ run(arg, o);
53
46
  };
54
47
  //# sourceMappingURL=room.js.map
@@ -1,32 +1,14 @@
1
- // sessions: `ringi sessions` (the seats this machine holds; `forget <handle>` frees one) and `ringi forget <room>/<log>`
2
- // (a new baseline for a log after an alarm).
3
- import * as Hubs from '../../../core/hub/usecases/hubs.js';
4
- import * as Overview from '../../../core/agents/overview.js';
1
+ // sessions: how a session shows in where, and `ringi forget <room>/<log>` (a new baseline for a log after an alarm).
5
2
  import * as Rooms from '../../../core/hub/usecases/rooms.js';
6
3
  import { fail } from '../../../lib/index.js';
7
- import { dump, flag, opt, out } from '../args.js';
8
- // --- where things stand, sessions, forget ---
4
+ import { out } from '../args.js';
9
5
  export const sessionLine = (s) => `${s.agent.padEnd(12)} ${s.liveness.padEnd(8)} ${(s.product ?? '?').padEnd(7)} ${s.handle}${s.scope ? ` scope: ${s.scope}` : ''}`;
10
- export const sessions = (o) => {
11
- if (o._[0] === 'forget') {
12
- const handle = o._[1] ?? fail('usage: ringi sessions forget <handle>');
13
- Overview.forgetSession(handle);
14
- return out(`forgot session ${handle}; its seat is free`);
15
- }
16
- const ss = Overview.sessions();
17
- if (flag(o, 'json'))
18
- return dump(ss);
19
- if (!ss.length)
20
- return out('no sessions');
21
- for (const s of ss)
22
- out(`${s.hub}/${s.room} ${sessionLine(s)}`);
23
- };
24
6
  export const forget = (o) => {
25
7
  const [name, id] = (o._[0] ?? '').split('/');
26
8
  if (!name || !id)
27
9
  fail('usage: ringi forget <room>/<log>');
28
- const H = Hubs.hubOf(opt(o, 'hub'));
29
- const n = Rooms.forgetLog(H, Rooms.roomIn(H, name), id);
10
+ const R = Rooms.roomNamed(name);
11
+ const n = Rooms.forgetLog(R.hub, R, id);
30
12
  out(`forgot the accepted history of ${name}/${id} for ${n} reader(s); the next read accepts what is there now`);
31
13
  };
32
14
  //# sourceMappingURL=sessions.js.map
@@ -5,7 +5,8 @@ import { short } from '../../../lib/index.js';
5
5
  import { flag, out } from '../args.js';
6
6
  import { taskLine } from '../shared/index.js';
7
7
  import { sessionLine } from './sessions.js';
8
- export const hubLine = (H) => `hub ${H.name}: ${H.d.store.type} store, ${H.contract.trust} senders, contract ${H.contract.version}, protocol ${H.contract.protocol}${H.contract.capabilities?.length ? `, ${H.contract.capabilities.join(' ')}` : ''}`;
8
+ // The room's hub and the contract the room follows: a room carries its own copy (hub-2).
9
+ export const hubLine = (R) => `hub ${R.hub.name}: ${R.hub.d.store.type} store, ${R.hub.d.trust} senders, contract ${R.contract.version}, protocol ${R.contract.protocol}${R.contract.capabilities?.length ? `, ${R.contract.capabilities.join(' ')}` : ''}`;
9
10
  const quorumLine = (R) => {
10
11
  if (R.quorum === null)
11
12
  return '';
@@ -1,32 +1,30 @@
1
1
  // where: `ringi where`, where things stand for the operator, and `--follow` for what lands next.
2
2
  import { config } from '../../../core/hub/usecases/context.js';
3
- import * as Hubs from '../../../core/hub/usecases/hubs.js';
4
3
  import * as Overview from '../../../core/agents/overview.js';
5
4
  import { sleep } from '../../../lib/index.js';
6
5
  import { flag, opt, out } from '../args.js';
7
6
  import { hubLine, printOverview, showMessage } from './where-format.js';
8
- const follow = async (H, R, o, seen) => {
7
+ const follow = async (R, o, seen) => {
9
8
  out('following; new messages appear as they land (Ctrl-C to stop)');
10
9
  for (;;) {
11
10
  await sleep(Number(opt(o, 'interval') ?? 2) * 1000);
12
- const now = Overview.arrived(H, R, seen);
11
+ const now = Overview.arrived(R, seen);
13
12
  for (const m of now.messages)
14
13
  showMessage(R, o, now.all, m);
15
14
  }
16
15
  };
17
16
  export const where = async (o) => {
18
- const H = Hubs.hubOf(opt(o, 'hub'));
19
- const w = Overview.where(H, opt(o, 'room') ?? config().room);
20
- out(hubLine(H));
17
+ const w = Overview.where(opt(o, 'room') ?? config().room);
21
18
  const R = w.room;
22
19
  if (!R)
23
20
  return out('no current room: ringi room create <id> | ringi room switch <id>');
21
+ out(hubLine(R));
24
22
  printOverview(w, R);
25
23
  const n = Number(opt(o, 'n') ?? (flag(o, 'short') ? 10 : 5));
26
24
  out(`last ${Math.min(n, w.messages.length)} of ${w.messages.length} messages:`);
27
25
  for (const m of w.messages.slice(-n))
28
26
  showMessage(R, o, w.all, m);
29
27
  if (flag(o, 'follow'))
30
- await follow(H, R, o, new Set(w.all.keys()));
28
+ await follow(R, o, new Set(w.all.keys()));
31
29
  };
32
30
  //# sourceMappingURL=where.js.map
@@ -1,8 +1,8 @@
1
1
  // shared: the commands both run: `ringi send` acts as the operator, `ringi agent send` as the agent its session is
2
2
  // bound to; messages, files, work and signals.
3
3
  export { cat, get } from './files.js';
4
- export { add, read, reply, send, thread } from './messages.js';
5
- export { profileCmd, who } from './profile.js';
4
+ export { read, reply, send, thread } from './messages.js';
5
+ export { profileCmd } from './profile.js';
6
6
  export { scopeLine, waiting } from './session.js';
7
7
  export { signals } from './signals.js';
8
8
  export { log, taskLine, tasks } from './work.js';
@@ -1,8 +1,8 @@
1
- // messages: `add` (staging), `send`, `reply`, `read`, `thread`.
1
+ // messages: `send`, `reply`, `read`, `thread`.
2
2
  import * as Room from '../../../core/hub/usecases/room.js';
3
3
  import { withSizes } from '../../../core/hub/usecases/room.js';
4
4
  import { asJson, render } from '../../../core/hub/usecases/view.js';
5
- import { bytes, fail, short, words } from '../../../lib/index.js';
5
+ import { fail, short, words } from '../../../lib/index.js';
6
6
  import { attachments, dump, flag, list, opt, out, textOf } from '../args.js';
7
7
  const sendInput = (o) => ({
8
8
  text: textOf(o), to: words(opt(o, 'to')), all: flag(o, 'all'), task: flag(o, 'task'),
@@ -10,16 +10,6 @@ const sendInput = (o) => ({
10
10
  files: list(o, 'attach').flatMap(attachments)
11
11
  });
12
12
  const sent = (r) => out(`sent ${short(r.id)} to ${r.to.join(', ')}${r.files ? ` with ${r.files} file(s)` : ''}`);
13
- // Stages files for the actor's next message, like git add: their content is taken into the hub now. Without files it
14
- // lists what is staged; --drop <path> and --clear take files back out.
15
- export const add = (a, o) => {
16
- if (flag(o, 'clear'))
17
- Room.unstage(a, null);
18
- else if (list(o, 'drop').length)
19
- Room.unstage(a, list(o, 'drop'));
20
- const staged = o._.length ? Room.stage(a, o._.flatMap(attachments)) : Room.staged(a);
21
- out(staged.length ? `staged for your next message:\n${staged.map(s => ` ${s.path} (${bytes(s.size)})`).join('\n')}` : 'nothing staged');
22
- };
23
13
  export const send = (a, o) => sent(Room.send(a, { ...sendInput(o), re: opt(o, 're') }));
24
14
  export const reply = (a, o) => sent(Room.send(a, { ...sendInput(o), re: o._[0] ?? fail('usage: reply <msg> -m <text> …'), reply: true }));
25
15
  export const read = (a, o) => {
@@ -1,5 +1,4 @@
1
- // profile: `profile` (what work is in the room) and `who` (its members).
2
- import * as Room from '../../../core/hub/usecases/room.js';
1
+ // profile: `profile`, what work is in the room.
3
2
  import { dump, flag, out } from '../args.js';
4
3
  export const profileCmd = ({ R }, o) => {
5
4
  if (flag(o, 'json'))
@@ -10,8 +9,4 @@ export const profileCmd = ({ R }, o) => {
10
9
  for (const [k, v] of Object.entries(P.rules))
11
10
  out(` ${k.padEnd(18)} ${(v ?? []).join(', ')}`);
12
11
  };
13
- export const who = (a) => {
14
- for (const x of Room.members(a))
15
- out(`${x.id.padEnd(12)} ${x.role.padEnd(7)} ${String(x.messages).padStart(4)} msg`);
16
- };
17
12
  //# sourceMappingURL=profile.js.map
@@ -1,15 +1,17 @@
1
1
  // skill: the agents' manual for this same command line (src/main/resources/skill/), installed where each agent tool
2
- // reads skills (targets.ts), checked and removed again.
2
+ // reads skills, and removed again.
3
3
  import fs from 'node:fs';
4
+ import os from 'node:os';
4
5
  import path from 'node:path';
5
6
  import { about } from '../../../core/hub/usecases/context.js';
6
- import { sandboxHints } from '../../../core/agents/sessions/context.js';
7
+ import { sandboxHints, skillDirs } from '../../../core/agents/sessions/context.js';
7
8
  import { fail } from '../../../lib/index.js';
8
- import { flag, out } from '../args.js';
9
- import { SKILL, sameSkill, skillTargets } from './targets.js';
10
- export { SKILL, skillTargets } from './targets.js';
11
- const install = (o) => {
12
- for (const dir of skillTargets(flag(o, 'project'))) {
9
+ import { out } from '../args.js';
10
+ export const SKILL = path.join(about().resources, 'skill', 'ringi');
11
+ // Each agent tool's skill directory under the user's home; nothing is written into projects.
12
+ export const skillTargets = () => skillDirs(os.homedir());
13
+ const install = () => {
14
+ for (const dir of skillTargets()) {
13
15
  fs.mkdirSync(dir, { recursive: true });
14
16
  fs.cpSync(SKILL, dir, { recursive: true });
15
17
  out(`installed ${dir}`);
@@ -17,24 +19,17 @@ const install = (o) => {
17
19
  out([`ringi's home is ${about().home}. A sandboxed agent must be allowed to write it.`, ...sandboxHints(about().home).map(h => ` ${h}`),
18
20
  'Otherwise agents re-run ringi commands with sandbox escalation, which you approve.'].join('\n'));
19
21
  };
20
- const status = () => {
21
- for (const dir of [...skillTargets(false), ...skillTargets(true)]) {
22
- const state = sameSkill(dir) ? 'ok ' : fs.existsSync(dir) ? 'outdated' : 'missing ';
23
- out(`${state} ${dir}`);
24
- }
25
- };
26
- const uninstall = (o) => {
27
- for (const dir of skillTargets(flag(o, 'project'))) {
22
+ const uninstall = () => {
23
+ for (const dir of skillTargets()) {
28
24
  if (!fs.existsSync(dir))
29
25
  continue;
30
26
  fs.rmSync(dir, { recursive: true });
31
27
  out(`removed ${dir}`);
32
28
  }
33
29
  };
34
- const show = () => { process.stdout.write(fs.readFileSync(path.join(SKILL, 'SKILL.md'), 'utf8')); };
35
- const COMMANDS = new Map([['install', install], ['status', status], ['uninstall', uninstall], ['show', show]]);
30
+ const COMMANDS = new Map([['install', install], ['uninstall', uninstall]]);
36
31
  export const skill = (o) => {
37
- const run = COMMANDS.get(o._[0]) ?? fail('usage: ringi skill install [--project] | uninstall [--project] | status | show');
38
- run(o);
32
+ const run = COMMANDS.get(o._[0]) ?? fail('usage: ringi skill install | uninstall');
33
+ run();
39
34
  };
40
35
  //# sourceMappingURL=index.js.map
@@ -9,12 +9,12 @@ import { notesTo } from '../lib/index.js';
9
9
  import { wireHub } from '../core/hub/ports/index.js';
10
10
  import { wireAgents } from '../core/agents/ports/index.js';
11
11
  import { stateFs } from '../adapters/state-fs/index.js';
12
- import { claude } from '../adapters/tool-claude/index.js';
13
- import { codex } from '../adapters/tool-codex/index.js';
14
- import { cursor } from '../adapters/tool-cursor/index.js';
12
+ import { claude } from '../adapters/agent-claude/index.js';
13
+ import { codex } from '../adapters/agent-codex/index.js';
14
+ import { cursor } from '../adapters/agent-cursor/index.js';
15
15
  import { hostPosix } from '../adapters/host-posix/index.js';
16
16
  import { keysFile } from '../adapters/keys-file/index.js';
17
- import { gitTransport } from '../adapters/transport-git/transport.js';
17
+ import { gitTransport } from '../adapters/store-git/transport.js';
18
18
  // The package this file belongs to, run from its source (src/main/ts) or its build (target/esm).
19
19
  const packageOf = (dir) => fs.existsSync(path.join(dir, 'package.json')) ? dir : packageOf(path.dirname(dir));
20
20
  const PACKAGE = packageOf(path.dirname(fileURLToPath(import.meta.url)));
@@ -24,10 +24,10 @@ const beatAll = (next) => allSessions().flatMap((s) => {
24
24
  const H = openHub(s.hub);
25
25
  const R = openRoom(H, s.room, { quiet: true });
26
26
  // A gone room: the session leaves it on its own; nothing to beat for.
27
- if (!R || R.genesis !== s.genesis || !H.store.heartbeat)
27
+ if (!R || R.genesis !== s.genesis || !R.store.heartbeat)
28
28
  return [];
29
29
  const b = HB.judge(HB.probe(s, start(R).started ? null : 'quorum'), { next });
30
- H.store.heartbeat(R.s, s.agent, R.s.tip, HB.body(b));
30
+ R.store.heartbeat(R.s, s.agent, R.s.tip, HB.body(b));
31
31
  return [{ session: s, beat: b }];
32
32
  }
33
33
  catch (e) {
@@ -40,7 +40,7 @@ const beatLoop = async (every, once, log) => {
40
40
  const beats = beatAll(every);
41
41
  for (const b of beats)
42
42
  if (b.error)
43
- log(`pulse: ${b.session.agent} in ${b.session.hub}/${b.session.room}: ${b.error}`);
43
+ log(`pulse: ${b.session.agent} in ${b.session.room}: ${b.error}`);
44
44
  idle = beats.length ? 0 : idle + 1;
45
45
  if (once || !hubPorts().state.present())
46
46
  return;
@@ -63,7 +63,7 @@ export const pulse = async ({ every = 30, once = false, log }) => {
63
63
  return 0;
64
64
  };
65
65
  // What the room's published heartbeats say, as an orchestrator would read them: whose, how old, overdue or not.
66
- export const published = (R) => (R.hub.store.heartbeats?.(R.s) ?? []).map(h => {
66
+ export const published = (R) => (R.store.heartbeats?.(R.s) ?? []).map(h => {
67
67
  const next = Number(/^Next: (\d+)$/m.exec(h.text)?.[1] ?? NaN);
68
68
  const age = Math.max(0, Math.round(Date.now() / 1000 - h.time));
69
69
  return { ...h, state: /^State: (\w+)$/m.exec(h.text)?.[1] ?? '?', waits: /^Waits: (.+)$/m.exec(h.text)?.[1] ?? null, age, overdue: Number.isFinite(next) && age > next * 2 };