@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.
- package/README.md +18 -11
- package/package.json +1 -1
- package/src/main/resources/skill/ringi/SKILL.md +3 -4
- package/target/dts/adapters/{transport-git → store-git}/branches.d.ts +1 -3
- package/target/dts/adapters/{transport-git → store-git}/index.d.ts +0 -1
- package/target/dts/adapters/store-git/marks.d.ts +21 -0
- package/target/dts/adapters/{transport-git → store-git}/remote/push.d.ts +0 -1
- package/target/dts/adapters/store-git/remote/stream-check.d.ts +12 -0
- package/target/dts/adapters/store-git/remote/stream-control.d.ts +8 -0
- package/target/dts/adapters/store-git/remote/stream-facts.d.ts +4 -0
- package/target/dts/adapters/store-git/remote/streams.d.ts +31 -0
- package/target/dts/adapters/store-git/remote/sync-streams.d.ts +2 -0
- package/target/dts/adapters/{transport-git → store-git}/remote/types.d.ts +5 -4
- package/target/dts/adapters/{transport-git → store-git}/remote.d.ts +1 -4
- package/target/dts/adapters/{transport-git → store-git}/repo.d.ts +3 -2
- package/target/dts/adapters/{transport-git → store-git}/signing.d.ts +0 -1
- package/target/dts/clients/cli/operator/hub-commands.d.ts +0 -2
- package/target/dts/clients/cli/operator/index.d.ts +1 -1
- package/target/dts/clients/cli/operator/sessions.d.ts +0 -1
- package/target/dts/clients/cli/operator/where-format.d.ts +1 -1
- package/target/dts/clients/cli/shared/index.d.ts +2 -2
- package/target/dts/clients/cli/shared/messages.d.ts +0 -1
- package/target/dts/clients/cli/shared/profile.d.ts +0 -1
- package/target/dts/clients/cli/skill/index.d.ts +2 -1
- package/target/dts/core/agents/overview.d.ts +4 -7
- package/target/dts/core/agents/sessions/index.d.ts +0 -1
- package/target/dts/core/agents/sessions/join.d.ts +1 -2
- package/target/dts/core/hub/history/index.d.ts +1 -10
- package/target/dts/core/hub/ports/store.d.ts +35 -23
- package/target/dts/core/hub/rooms/address.d.ts +6 -0
- package/target/dts/core/hub/rooms/adoption.d.ts +7 -0
- package/target/dts/core/hub/rooms/compat.d.ts +3 -1
- package/target/dts/core/hub/rooms/contracts.d.ts +16 -0
- package/target/dts/core/hub/rooms/hubs.d.ts +3 -3
- package/target/dts/core/hub/rooms/index.d.ts +5 -6
- package/target/dts/core/hub/rooms/room-catalogue.d.ts +9 -0
- package/target/dts/core/hub/rooms/room-life.d.ts +10 -0
- package/target/dts/core/hub/rooms/room-view.d.ts +3 -0
- package/target/dts/core/hub/rooms/rooms.d.ts +4 -2
- package/target/dts/core/hub/signals/check.d.ts +2 -2
- package/target/dts/core/hub/signals/model.d.ts +2 -10
- package/target/dts/core/hub/signals/pins.d.ts +2 -2
- package/target/dts/core/hub/usecases/config.d.ts +0 -1
- package/target/dts/core/hub/usecases/context.d.ts +1 -2
- package/target/dts/core/hub/usecases/hubs.d.ts +1 -8
- package/target/dts/core/hub/usecases/invite.d.ts +12 -0
- package/target/dts/core/hub/usecases/room.d.ts +0 -1
- package/target/dts/core/hub/usecases/rooms.d.ts +9 -7
- package/target/dts/core/hub/usecases/roster.d.ts +1 -2
- package/target/dts/core/hub/work/index.d.ts +0 -1
- package/target/dts/index.d.ts +1 -1
- package/target/esm/adapters/{tool-claude → agent-claude}/index.js +2 -2
- package/target/esm/adapters/{tool-codex → agent-codex}/index.js +2 -2
- package/target/esm/adapters/{tool-cursor → agent-cursor}/index.js +1 -1
- package/target/esm/adapters/{tool-traces → agent-traces}/index.js +1 -1
- package/target/esm/adapters/state-fs/index.js +2 -2
- package/target/esm/adapters/{transport-git → store-git}/branches.js +21 -27
- package/target/esm/adapters/{transport-git → store-git}/index.js +10 -28
- package/target/esm/adapters/store-git/marks.js +86 -0
- package/target/esm/adapters/{transport-git → store-git}/remote/commits.js +3 -1
- package/target/esm/adapters/{transport-git → store-git}/remote/git.js +8 -1
- package/target/esm/adapters/{transport-git → store-git}/remote/keys.js +8 -3
- package/target/esm/adapters/{transport-git → store-git}/remote/push-retry.js +24 -6
- package/target/esm/adapters/store-git/remote/push-validate.js +19 -0
- package/target/esm/adapters/{transport-git → store-git}/remote/push.js +13 -14
- package/target/esm/adapters/store-git/remote/stream-check.js +44 -0
- package/target/esm/adapters/store-git/remote/stream-control.js +33 -0
- package/target/esm/adapters/store-git/remote/stream-facts.js +40 -0
- package/target/esm/adapters/store-git/remote/streams.js +76 -0
- package/target/esm/adapters/store-git/remote/sync-streams.js +28 -0
- package/target/esm/adapters/store-git/remote/sync.js +59 -0
- package/target/esm/adapters/{transport-git → store-git}/remote/types.js +0 -3
- package/target/esm/adapters/{transport-git → store-git}/remote.js +1 -4
- package/target/esm/adapters/{transport-git → store-git}/repo.js +42 -4
- package/target/esm/adapters/{transport-git → store-git}/signing.js +1 -9
- package/target/esm/adapters/store-git/transport.js +60 -0
- package/target/esm/clients/cli/agent/index.js +1 -1
- package/target/esm/clients/cli/agent/session.js +10 -10
- package/target/esm/clients/cli/commands.js +5 -5
- package/target/esm/clients/cli/context.js +1 -1
- package/target/esm/clients/cli/help.js +15 -21
- package/target/esm/clients/cli/operator/heartbeat-format.js +1 -1
- package/target/esm/clients/cli/operator/heartbeat.js +1 -2
- package/target/esm/clients/cli/operator/hub-commands.js +6 -19
- package/target/esm/clients/cli/operator/hub.js +2 -2
- package/target/esm/clients/cli/operator/index.js +2 -2
- package/target/esm/clients/cli/operator/room.js +25 -32
- package/target/esm/clients/cli/operator/sessions.js +4 -22
- package/target/esm/clients/cli/operator/where-format.js +2 -1
- package/target/esm/clients/cli/operator/where.js +5 -7
- package/target/esm/clients/cli/shared/index.js +2 -2
- package/target/esm/clients/cli/shared/messages.js +2 -12
- package/target/esm/clients/cli/shared/profile.js +1 -6
- package/target/esm/clients/cli/skill/index.js +14 -19
- package/target/esm/composition/index.js +4 -4
- package/target/esm/core/agents/heartbeat/pulse.js +4 -4
- package/target/esm/core/agents/overview.js +13 -25
- package/target/esm/core/agents/sessions/binding.js +1 -1
- package/target/esm/core/agents/sessions/index.js +3 -2
- package/target/esm/core/agents/sessions/join.js +17 -9
- package/target/esm/core/agents/sessions/resume.js +3 -6
- package/target/esm/core/hub/capabilities.js +1 -4
- package/target/esm/core/hub/history/index.js +23 -13
- package/target/esm/core/hub/ports/store.js +2 -2
- package/target/esm/core/hub/rooms/address.js +18 -0
- package/target/esm/core/hub/rooms/adoption.js +32 -0
- package/target/esm/core/hub/rooms/compat.js +39 -14
- package/target/esm/core/hub/rooms/contracts.js +62 -0
- package/target/esm/core/hub/rooms/hubs.js +33 -56
- package/target/esm/core/hub/rooms/index.js +2 -2
- package/target/esm/core/hub/rooms/messages.js +6 -6
- package/target/esm/core/hub/rooms/room-catalogue.js +31 -0
- package/target/esm/core/hub/rooms/room-life.js +59 -0
- package/target/esm/core/hub/rooms/room-view.js +39 -0
- package/target/esm/core/hub/rooms/rooms.js +26 -37
- package/target/esm/core/hub/signals/check.js +21 -26
- package/target/esm/core/hub/signals/index.js +10 -10
- package/target/esm/core/hub/signals/model.js +0 -2
- package/target/esm/core/hub/signals/pins.js +44 -16
- package/target/esm/core/hub/signals/write.js +8 -10
- package/target/esm/core/hub/usecases/actor.js +1 -1
- package/target/esm/core/hub/usecases/config.js +2 -2
- package/target/esm/core/hub/usecases/context.js +5 -8
- package/target/esm/core/hub/usecases/hubs.js +16 -33
- package/target/esm/core/hub/usecases/invite.js +26 -0
- package/target/esm/core/hub/usecases/room.js +4 -5
- package/target/esm/core/hub/usecases/rooms.js +40 -35
- package/target/esm/core/hub/usecases/roster.js +12 -21
- package/target/esm/core/hub/usecases/send.js +10 -6
- package/target/esm/core/hub/work/parse.js +1 -1
- package/target/esm/lib/fail.js +2 -2
- package/target/dts/adapters/transport-git/marks.d.ts +0 -20
- package/target/dts/adapters/transport-git/remote/bootstrap.d.ts +0 -7
- package/target/dts/adapters/transport-git/remote/heartbeat-name.d.ts +0 -6
- package/target/dts/adapters/transport-git/remote/heartbeat-object.d.ts +0 -10
- package/target/dts/adapters/transport-git/remote/heartbeat-push.d.ts +0 -2
- package/target/dts/adapters/transport-git/remote/heartbeat.d.ts +0 -7
- package/target/dts/adapters/transport-git/remote/signals.d.ts +0 -15
- package/target/dts/adapters/transport-git/remote/sync-heartbeat.d.ts +0 -2
- package/target/dts/adapters/transport-git/remote/sync-rooms.d.ts +0 -6
- package/target/dts/adapters/transport-git/remote/sync-tags.d.ts +0 -8
- package/target/dts/adapters/transport-git/tags.d.ts +0 -15
- package/target/dts/clients/cli/skill/targets.d.ts +0 -3
- package/target/dts/core/hub/usecases/staging.d.ts +0 -8
- package/target/esm/adapters/transport-git/marks.js +0 -82
- package/target/esm/adapters/transport-git/remote/bootstrap.js +0 -47
- package/target/esm/adapters/transport-git/remote/heartbeat-name.js +0 -19
- package/target/esm/adapters/transport-git/remote/heartbeat-object.js +0 -40
- package/target/esm/adapters/transport-git/remote/heartbeat-push.js +0 -44
- package/target/esm/adapters/transport-git/remote/heartbeat.js +0 -44
- package/target/esm/adapters/transport-git/remote/push-validate.js +0 -39
- package/target/esm/adapters/transport-git/remote/signals.js +0 -63
- package/target/esm/adapters/transport-git/remote/sync-heartbeat.js +0 -26
- package/target/esm/adapters/transport-git/remote/sync-rooms.js +0 -38
- package/target/esm/adapters/transport-git/remote/sync-tags.js +0 -48
- package/target/esm/adapters/transport-git/remote/sync.js +0 -38
- package/target/esm/adapters/transport-git/tags.js +0 -21
- package/target/esm/adapters/transport-git/transport.js +0 -29
- package/target/esm/clients/cli/skill/targets.js +0 -20
- package/target/esm/core/hub/usecases/staging.js +0 -60
- /package/target/dts/adapters/{tool-claude → agent-claude}/index.d.ts +0 -0
- /package/target/dts/adapters/{tool-codex → agent-codex}/index.d.ts +0 -0
- /package/target/dts/adapters/{tool-cursor → agent-cursor}/index.d.ts +0 -0
- /package/target/dts/adapters/{tool-traces → agent-traces}/index.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/files.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/admit.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/alarms.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/branch-commit.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/branch-control.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/branch-scan.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/branch.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/cache.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/commits.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/forget.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/git.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/heartbeat-facts.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/keys.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/main.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/process.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/push-retry.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/push-validate.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/roster.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/signature.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/remote/sync.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/run.d.ts +0 -0
- /package/target/dts/adapters/{transport-git → store-git}/transport.d.ts +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/files.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/admit.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/alarms.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/branch-commit.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/branch-control.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/branch-scan.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/branch.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/cache.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/forget.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/heartbeat-facts.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/main.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/process.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/roster.js +0 -0
- /package/target/esm/adapters/{transport-git → store-git}/remote/signature.js +0 -0
- /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.
|
|
12
|
-
out('agent commands: ringi agent inbox | reply <id> … | send … | tasks |
|
|
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 [
|
|
25
|
-
if (!
|
|
26
|
-
fail('usage: ringi join <
|
|
27
|
-
const r = Session.join({
|
|
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}' --
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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 {
|
|
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 = {
|
|
15
|
-
const AGENT = { ...SHARED, inbox, whoami,
|
|
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], ['
|
|
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({
|
|
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
|
|
7
|
-
['hub create <name> [--signed [--url <
|
|
8
|
-
['hub
|
|
9
|
-
['
|
|
10
|
-
['hub
|
|
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
|
|
16
|
-
['
|
|
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
|
-
['
|
|
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
|
-
['
|
|
25
|
-
['
|
|
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
|
|
29
|
-
['join <
|
|
30
|
-
['continue [
|
|
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 |
|
|
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
|
|
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.
|
|
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.
|
|
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 |
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
|
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 {
|
|
4
|
-
const COMMANDS = new Map([['list', listHub], ['create', createHub], ['
|
|
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,
|
|
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
|
|
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 |
|
|
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 =
|
|
8
|
-
const rs = roomsActive(
|
|
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(
|
|
12
|
+
out('no rooms on this machine: ringi room create <id>');
|
|
13
13
|
};
|
|
14
|
-
|
|
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 =
|
|
21
|
-
const R = Rooms.use(
|
|
22
|
-
out(`current room: ${
|
|
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
|
|
30
|
-
const R = Rooms.
|
|
31
|
-
Rooms.
|
|
32
|
-
out(`
|
|
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 = (
|
|
36
|
-
const R = Rooms.
|
|
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}
|
|
39
|
-
Rooms.erase(
|
|
40
|
-
out(`deleted room ${R.name}: its
|
|
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
|
|
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(
|
|
45
|
+
run(arg, o);
|
|
53
46
|
};
|
|
54
47
|
//# sourceMappingURL=room.js.map
|
|
@@ -1,32 +1,14 @@
|
|
|
1
|
-
// sessions:
|
|
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 {
|
|
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
|
|
29
|
-
const n = Rooms.forgetLog(
|
|
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
|
-
|
|
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 (
|
|
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(
|
|
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
|
|
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(
|
|
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 {
|
|
5
|
-
export { profileCmd
|
|
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: `
|
|
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 {
|
|
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
|
|
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
|
|
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 {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
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
|
|
21
|
-
for (const dir of
|
|
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
|
|
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
|
|
38
|
-
run(
|
|
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/
|
|
13
|
-
import { codex } from '../adapters/
|
|
14
|
-
import { cursor } from '../adapters/
|
|
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/
|
|
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 || !
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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 };
|