@idleware/ringi 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/target/dts/adapters/fs/index.d.ts +2 -0
- package/target/dts/adapters/fs/lock.d.ts +1 -0
- package/target/dts/adapters/fs/write.d.ts +5 -0
- package/target/dts/adapters/host-posix/group-state.d.ts +7 -0
- package/target/dts/adapters/host-posix/groups.d.ts +1 -0
- package/target/dts/adapters/host-posix/index.d.ts +2 -0
- package/target/dts/adapters/host-posix/launch.d.ts +7 -0
- package/target/dts/adapters/host-posix/probes.d.ts +5 -0
- package/target/dts/adapters/host-posix/stats.d.ts +9 -0
- package/target/dts/adapters/keys-file/index.d.ts +2 -0
- package/target/dts/adapters/state-fs/index.d.ts +5 -0
- package/target/dts/adapters/tool-claude/index.d.ts +2 -0
- package/target/dts/adapters/tool-codex/index.d.ts +2 -0
- package/target/dts/adapters/tool-cursor/index.d.ts +2 -0
- package/target/dts/adapters/tool-traces/index.d.ts +3 -0
- package/target/dts/adapters/transport-git/branches.d.ts +43 -0
- package/target/dts/adapters/transport-git/files.d.ts +2 -0
- package/target/dts/adapters/transport-git/index.d.ts +32 -0
- package/target/dts/adapters/transport-git/marks.d.ts +20 -0
- package/target/dts/adapters/transport-git/remote/admit.d.ts +7 -0
- package/target/dts/adapters/transport-git/remote/alarms.d.ts +3 -0
- package/target/dts/adapters/transport-git/remote/bootstrap.d.ts +7 -0
- package/target/dts/adapters/transport-git/remote/branch-commit.d.ts +3 -0
- package/target/dts/adapters/transport-git/remote/branch-control.d.ts +15 -0
- package/target/dts/adapters/transport-git/remote/branch-scan.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/branch.d.ts +5 -0
- package/target/dts/adapters/transport-git/remote/cache.d.ts +3 -0
- package/target/dts/adapters/transport-git/remote/commits.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/forget.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/git.d.ts +26 -0
- package/target/dts/adapters/transport-git/remote/heartbeat-facts.d.ts +1 -0
- package/target/dts/adapters/transport-git/remote/heartbeat-name.d.ts +6 -0
- package/target/dts/adapters/transport-git/remote/heartbeat-object.d.ts +10 -0
- package/target/dts/adapters/transport-git/remote/heartbeat-push.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/heartbeat.d.ts +7 -0
- package/target/dts/adapters/transport-git/remote/keys.d.ts +13 -0
- package/target/dts/adapters/transport-git/remote/main.d.ts +11 -0
- package/target/dts/adapters/transport-git/remote/process.d.ts +20 -0
- package/target/dts/adapters/transport-git/remote/push-retry.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/push-validate.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/push.d.ts +16 -0
- package/target/dts/adapters/transport-git/remote/roster.d.ts +7 -0
- package/target/dts/adapters/transport-git/remote/signals.d.ts +15 -0
- package/target/dts/adapters/transport-git/remote/signature.d.ts +5 -0
- package/target/dts/adapters/transport-git/remote/sync-heartbeat.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/sync-rooms.d.ts +6 -0
- package/target/dts/adapters/transport-git/remote/sync-tags.d.ts +8 -0
- package/target/dts/adapters/transport-git/remote/sync.d.ts +2 -0
- package/target/dts/adapters/transport-git/remote/types.d.ts +64 -0
- package/target/dts/adapters/transport-git/remote.d.ts +17 -0
- package/target/dts/adapters/transport-git/repo.d.ts +31 -0
- package/target/dts/adapters/transport-git/run.d.ts +21 -0
- package/target/dts/adapters/transport-git/signing.d.ts +4 -0
- package/target/dts/adapters/transport-git/tags.d.ts +15 -0
- package/target/dts/adapters/transport-git/transport.d.ts +7 -0
- package/target/dts/adapters/transport-kafka/index.d.ts +2 -0
- package/target/dts/adapters/transport-temporal/index.d.ts +2 -0
- package/target/dts/cli.d.ts +2 -1
- package/target/dts/{cli/agent.d.ts → clients/cli/agent/index.d.ts} +3 -3
- package/target/dts/{cli → clients/cli/agent}/session.d.ts +2 -2
- package/target/dts/clients/cli/arg-parse.d.ts +2 -0
- package/target/dts/{cli → clients/cli}/args.d.ts +2 -2
- package/target/dts/clients/cli/commands.d.ts +2 -0
- package/target/dts/clients/cli/context.d.ts +4 -0
- package/target/dts/{cli/index.d.ts → clients/cli/help.d.ts} +1 -3
- package/target/dts/clients/cli/index.d.ts +4 -0
- package/target/dts/clients/cli/operator/heartbeat-format.d.ts +5 -0
- package/target/dts/clients/cli/operator/heartbeat.d.ts +3 -0
- package/target/dts/clients/cli/operator/hub-commands.d.ts +6 -0
- package/target/dts/clients/cli/operator/hub.d.ts +2 -0
- package/target/dts/clients/cli/operator/index.d.ts +5 -0
- package/target/dts/clients/cli/operator/room-lifecycle.d.ts +5 -0
- package/target/dts/clients/cli/operator/room-list.d.ts +5 -0
- package/target/dts/clients/cli/operator/room-members.d.ts +4 -0
- package/target/dts/clients/cli/operator/room.d.ts +2 -0
- package/target/dts/clients/cli/operator/sessions.d.ts +5 -0
- package/target/dts/clients/cli/operator/watch.d.ts +2 -0
- package/target/dts/clients/cli/operator/where-format.d.ts +7 -0
- package/target/dts/clients/cli/operator/where.d.ts +2 -0
- package/target/dts/clients/cli/shared/budget.d.ts +7 -0
- package/target/dts/clients/cli/shared/files.d.ts +4 -0
- package/target/dts/clients/cli/shared/index.d.ts +7 -0
- package/target/dts/clients/cli/shared/messages.d.ts +7 -0
- package/target/dts/clients/cli/shared/profile.d.ts +4 -0
- package/target/dts/clients/cli/shared/session.d.ts +6 -0
- package/target/dts/clients/cli/shared/signals.d.ts +3 -0
- package/target/dts/clients/cli/shared/work.d.ts +6 -0
- package/target/dts/clients/cli/skill/index.d.ts +3 -0
- package/target/dts/{cli/skill.d.ts → clients/cli/skill/targets.d.ts} +1 -2
- package/target/dts/composition/index.d.ts +2 -0
- package/target/dts/{heartbeat → core/agents/heartbeat}/index.d.ts +2 -4
- package/target/dts/{app/heartbeat.d.ts → core/agents/heartbeat/pulse.d.ts} +5 -6
- package/target/dts/core/agents/heartbeat/singleton.d.ts +3 -0
- package/target/dts/core/agents/heartbeat/tools.d.ts +6 -0
- package/target/dts/{app → core/agents}/overview.d.ts +12 -6
- package/target/dts/core/agents/ports/host.d.ts +47 -0
- package/target/dts/core/agents/ports/index.d.ts +9 -0
- package/target/dts/core/agents/ports/tools.d.ts +18 -0
- package/target/dts/core/agents/sessions/agent.d.ts +70 -0
- package/target/dts/core/agents/sessions/binding.d.ts +9 -0
- package/target/dts/core/agents/sessions/context.d.ts +8 -0
- package/target/dts/{runtime/session.d.ts → core/agents/sessions/index.d.ts} +2 -9
- package/target/dts/core/agents/sessions/join.d.ts +20 -0
- package/target/dts/core/agents/sessions/resume.d.ts +2 -0
- package/target/dts/core/agents/sessions/session.d.ts +46 -0
- package/target/dts/core/agents/sessions/wait.d.ts +38 -0
- package/target/dts/core/agents/turns/budgets.d.ts +5 -0
- package/target/dts/core/agents/turns/dispatch.d.ts +9 -0
- package/target/dts/core/agents/turns/exhaustion.d.ts +11 -0
- package/target/dts/core/agents/turns/grants.d.ts +4 -0
- package/target/dts/core/agents/turns/index.d.ts +4 -0
- package/target/dts/core/agents/turns/limits.d.ts +2 -0
- package/target/dts/core/agents/turns/messages.d.ts +10 -0
- package/target/dts/core/agents/turns/pings.d.ts +5 -0
- package/target/dts/core/agents/turns/plan.d.ts +3 -0
- package/target/dts/core/agents/turns/poll.d.ts +8 -0
- package/target/dts/core/agents/turns/results.d.ts +3 -0
- package/target/dts/core/agents/turns/seat.d.ts +2 -0
- package/target/dts/core/agents/turns/types.d.ts +59 -0
- package/target/dts/core/hub/decisions/budget.d.ts +15 -0
- package/target/dts/core/hub/decisions/check.d.ts +6 -0
- package/target/dts/core/hub/decisions/index.d.ts +5 -0
- package/target/dts/core/hub/decisions/proposal.d.ts +38 -0
- package/target/dts/core/hub/decisions/usage.d.ts +12 -0
- package/target/dts/{runtime/reader.d.ts → core/hub/history/index.d.ts} +12 -6
- package/target/dts/core/hub/ports/index.d.ts +16 -0
- package/target/dts/core/hub/ports/state.d.ts +12 -0
- package/target/dts/{store/index.d.ts → core/hub/ports/store.d.ts} +48 -18
- package/target/dts/core/hub/protocol/index.d.ts +5 -0
- package/target/dts/{protocol/index.d.ts → core/hub/protocol/model.d.ts} +0 -25
- package/target/dts/core/hub/protocol/order.d.ts +2 -0
- package/target/dts/core/hub/protocol/reading.d.ts +8 -0
- package/target/dts/core/hub/protocol/text.d.ts +11 -0
- package/target/dts/core/hub/protocol/threads.d.ts +5 -0
- package/target/dts/core/hub/rooms/compat.d.ts +5 -0
- package/target/dts/core/hub/rooms/hubs.d.ts +14 -0
- package/target/dts/core/hub/rooms/index.d.ts +53 -0
- package/target/dts/core/hub/rooms/messages.d.ts +8 -0
- package/target/dts/core/hub/rooms/rooms.d.ts +10 -0
- package/target/dts/core/hub/signals/check.d.ts +3 -0
- package/target/dts/core/hub/signals/effective.d.ts +3 -0
- package/target/dts/core/hub/signals/index.d.ts +5 -0
- package/target/dts/core/hub/signals/marks.d.ts +4 -0
- package/target/dts/core/hub/signals/model.d.ts +28 -0
- package/target/dts/core/hub/signals/pins.d.ts +5 -0
- package/target/dts/{hub/signals.d.ts → core/hub/signals/write.d.ts} +1 -1
- package/target/dts/core/hub/usecases/actor.d.ts +6 -0
- package/target/dts/{app → core/hub/usecases}/budget.d.ts +5 -18
- package/target/dts/core/hub/usecases/config.d.ts +6 -0
- package/target/dts/{app → core/hub/usecases}/context.d.ts +3 -8
- package/target/dts/{app → core/hub/usecases}/hubs.d.ts +1 -1
- package/target/dts/core/hub/usecases/propose.d.ts +17 -0
- package/target/dts/{app → core/hub/usecases}/room.d.ts +8 -34
- package/target/dts/{app → core/hub/usecases}/rooms.d.ts +2 -6
- package/target/dts/core/hub/usecases/roster.d.ts +5 -0
- package/target/dts/core/hub/usecases/send.d.ts +21 -0
- package/target/dts/core/hub/usecases/staging.d.ts +8 -0
- package/target/dts/{app → core/hub/usecases}/view.d.ts +4 -4
- package/target/dts/{domain/profiles.d.ts → core/hub/work/index.d.ts} +3 -7
- package/target/dts/core/hub/work/parse.d.ts +2 -0
- package/target/dts/core/hub/work/task.d.ts +6 -0
- package/target/dts/core/signing/index.d.ts +35 -0
- package/target/dts/index.d.ts +8 -8
- package/target/dts/lib/fail.d.ts +8 -0
- package/target/dts/lib/index.d.ts +3 -11
- package/target/dts/lib/json.d.ts +1 -0
- package/target/esm/adapters/fs/index.js +5 -0
- package/target/esm/adapters/fs/lock.js +83 -0
- package/target/esm/adapters/fs/write.js +25 -0
- package/target/esm/adapters/host-posix/group-state.js +24 -0
- package/target/esm/adapters/host-posix/groups.js +43 -0
- package/target/esm/adapters/host-posix/index.js +35 -0
- package/target/esm/adapters/host-posix/launch.js +80 -0
- package/target/esm/adapters/host-posix/probes.js +66 -0
- package/target/esm/adapters/host-posix/stats.js +27 -0
- package/target/esm/adapters/keys-file/index.js +68 -0
- package/target/esm/adapters/state-fs/index.js +79 -0
- package/target/esm/adapters/tool-claude/index.js +32 -0
- package/target/esm/adapters/tool-codex/index.js +38 -0
- package/target/esm/adapters/tool-cursor/index.js +8 -0
- package/target/esm/adapters/tool-traces/index.js +18 -0
- package/target/esm/adapters/transport-git/branches.js +155 -0
- package/target/esm/adapters/transport-git/files.js +48 -0
- package/target/esm/adapters/transport-git/index.js +128 -0
- package/target/esm/adapters/transport-git/marks.js +88 -0
- package/target/esm/adapters/transport-git/remote/admit.js +71 -0
- package/target/esm/adapters/transport-git/remote/alarms.js +30 -0
- package/target/esm/adapters/transport-git/remote/bootstrap.js +47 -0
- package/target/esm/adapters/transport-git/remote/branch-commit.js +36 -0
- package/target/esm/adapters/transport-git/remote/branch-control.js +37 -0
- package/target/esm/adapters/transport-git/remote/branch-scan.js +28 -0
- package/target/esm/adapters/transport-git/remote/branch.js +37 -0
- package/target/esm/adapters/transport-git/remote/cache.js +23 -0
- package/target/esm/adapters/transport-git/remote/commits.js +25 -0
- package/target/esm/adapters/transport-git/remote/forget.js +35 -0
- package/target/esm/adapters/transport-git/remote/git.js +58 -0
- package/target/esm/adapters/transport-git/remote/heartbeat-facts.js +35 -0
- package/target/esm/adapters/transport-git/remote/heartbeat-name.js +19 -0
- package/target/esm/adapters/transport-git/remote/heartbeat-object.js +40 -0
- package/target/esm/adapters/transport-git/remote/heartbeat-push.js +44 -0
- package/target/esm/adapters/transport-git/remote/heartbeat.js +44 -0
- package/target/esm/adapters/transport-git/remote/keys.js +75 -0
- package/target/esm/adapters/transport-git/remote/main.js +41 -0
- package/target/esm/adapters/transport-git/remote/process.js +37 -0
- package/target/esm/adapters/transport-git/remote/push-retry.js +46 -0
- package/target/esm/adapters/transport-git/remote/push-validate.js +39 -0
- package/target/esm/adapters/transport-git/remote/push.js +62 -0
- package/target/esm/adapters/transport-git/remote/roster.js +48 -0
- package/target/esm/adapters/transport-git/remote/signals.js +63 -0
- package/target/esm/adapters/transport-git/remote/signature.js +56 -0
- package/target/esm/adapters/transport-git/remote/sync-heartbeat.js +26 -0
- package/target/esm/adapters/transport-git/remote/sync-rooms.js +38 -0
- package/target/esm/adapters/transport-git/remote/sync-tags.js +48 -0
- package/target/esm/adapters/transport-git/remote/sync.js +38 -0
- package/target/esm/adapters/transport-git/remote/types.js +10 -0
- package/target/esm/adapters/transport-git/remote.js +17 -0
- package/target/esm/adapters/transport-git/repo.js +115 -0
- package/target/esm/adapters/transport-git/run.js +57 -0
- package/target/esm/adapters/transport-git/signing.js +44 -0
- package/target/esm/adapters/transport-git/tags.js +21 -0
- package/target/esm/adapters/transport-git/transport.js +29 -0
- package/target/esm/adapters/transport-kafka/index.js +4 -0
- package/target/esm/adapters/transport-temporal/index.js +4 -0
- package/target/esm/cli.js +5 -4
- package/target/esm/{cli/agent.js → clients/cli/agent/index.js} +8 -7
- package/target/esm/{cli → clients/cli/agent}/session.js +7 -7
- package/target/esm/clients/cli/arg-parse.js +41 -0
- package/target/esm/{cli → clients/cli}/args.js +3 -36
- package/target/esm/clients/cli/commands.js +45 -0
- package/target/esm/clients/cli/context.js +6 -0
- package/target/esm/{cli/index.js → clients/cli/help.js} +4 -77
- package/target/esm/clients/cli/index.js +27 -0
- package/target/esm/clients/cli/operator/heartbeat-format.js +8 -0
- package/target/esm/clients/cli/operator/heartbeat.js +35 -0
- package/target/esm/clients/cli/operator/hub-commands.js +37 -0
- package/target/esm/clients/cli/operator/hub.js +10 -0
- package/target/esm/clients/cli/operator/index.js +8 -0
- package/target/esm/clients/cli/operator/room-lifecycle.js +23 -0
- package/target/esm/clients/cli/operator/room-list.js +27 -0
- package/target/esm/clients/cli/operator/room-members.js +15 -0
- package/target/esm/clients/cli/operator/room.js +15 -0
- package/target/esm/clients/cli/operator/sessions.js +32 -0
- package/target/esm/clients/cli/operator/watch.js +15 -0
- package/target/esm/clients/cli/operator/where-format.js +24 -0
- package/target/esm/clients/cli/operator/where.js +32 -0
- package/target/esm/clients/cli/shared/budget.js +50 -0
- package/target/esm/clients/cli/shared/files.js +26 -0
- package/target/esm/clients/cli/shared/index.js +10 -0
- package/target/esm/clients/cli/shared/messages.js +41 -0
- package/target/esm/clients/cli/shared/profile.js +17 -0
- package/target/esm/clients/cli/shared/session.js +8 -0
- package/target/esm/clients/cli/shared/signals.js +21 -0
- package/target/esm/clients/cli/shared/work.js +26 -0
- package/target/esm/clients/cli/skill/index.js +40 -0
- package/target/esm/clients/cli/skill/targets.js +20 -0
- package/target/esm/composition/index.js +34 -0
- package/target/esm/{heartbeat → core/agents/heartbeat}/index.js +14 -12
- package/target/esm/{app/heartbeat.js → core/agents/heartbeat/pulse.js} +31 -55
- package/target/esm/core/agents/heartbeat/singleton.js +38 -0
- package/target/esm/core/agents/heartbeat/tools.js +24 -0
- package/target/esm/{app → core/agents}/overview.js +15 -9
- package/target/esm/core/agents/ports/host.js +4 -0
- package/target/esm/core/agents/ports/index.js +7 -0
- package/target/esm/core/agents/ports/tools.js +5 -0
- package/target/esm/{app → core/agents/sessions}/agent.js +11 -43
- package/target/esm/core/agents/sessions/binding.js +43 -0
- package/target/esm/core/agents/sessions/context.js +11 -0
- package/target/esm/core/agents/sessions/index.js +59 -0
- package/target/esm/core/agents/sessions/join.js +55 -0
- package/target/esm/core/agents/sessions/resume.js +54 -0
- package/target/esm/core/agents/sessions/session.js +28 -0
- package/target/esm/core/agents/sessions/wait.js +47 -0
- package/target/esm/core/agents/turns/budgets.js +48 -0
- package/target/esm/core/agents/turns/dispatch.js +40 -0
- package/target/esm/core/agents/turns/exhaustion.js +16 -0
- package/target/esm/core/agents/turns/grants.js +36 -0
- package/target/esm/core/agents/turns/index.js +33 -0
- package/target/esm/core/agents/turns/limits.js +11 -0
- package/target/esm/core/agents/turns/messages.js +32 -0
- package/target/esm/core/agents/turns/pings.js +30 -0
- package/target/esm/core/agents/turns/plan.js +29 -0
- package/target/esm/core/agents/turns/poll.js +48 -0
- package/target/esm/core/agents/turns/results.js +40 -0
- package/target/esm/core/agents/turns/seat.js +44 -0
- package/target/esm/core/agents/turns/types.js +3 -0
- package/target/esm/{domain/index.js → core/hub/capabilities.js} +3 -3
- package/target/esm/core/hub/decisions/budget.js +40 -0
- package/target/esm/core/hub/decisions/check.js +43 -0
- package/target/esm/core/hub/decisions/index.js +10 -0
- package/target/esm/core/hub/decisions/proposal.js +73 -0
- package/target/esm/core/hub/decisions/usage.js +39 -0
- package/target/esm/core/hub/history/index.js +90 -0
- package/target/esm/core/hub/ports/index.js +10 -0
- package/target/esm/core/hub/ports/state.js +5 -0
- package/target/esm/core/hub/ports/store.js +10 -0
- package/target/esm/{protocol → core/hub/protocol}/files.js +4 -2
- package/target/esm/core/hub/protocol/index.js +9 -0
- package/target/esm/core/hub/protocol/model.js +15 -0
- package/target/esm/core/hub/protocol/order.js +39 -0
- package/target/esm/core/hub/protocol/reading.js +29 -0
- package/target/esm/core/hub/protocol/text.js +95 -0
- package/target/esm/core/hub/protocol/threads.js +52 -0
- package/target/esm/core/hub/rooms/compat.js +42 -0
- package/target/esm/core/hub/rooms/hubs.js +92 -0
- package/target/esm/core/hub/rooms/index.js +23 -0
- package/target/esm/core/hub/rooms/messages.js +47 -0
- package/target/esm/core/hub/rooms/rooms.js +84 -0
- package/target/esm/core/hub/signals/check.js +33 -0
- package/target/esm/core/hub/signals/effective.js +31 -0
- package/target/esm/core/hub/signals/index.js +23 -0
- package/target/esm/core/hub/signals/marks.js +30 -0
- package/target/esm/core/hub/signals/model.js +5 -0
- package/target/esm/core/hub/signals/pins.js +21 -0
- package/target/esm/{hub/signals.js → core/hub/signals/write.js} +4 -4
- package/target/esm/core/hub/usecases/actor.js +3 -0
- package/target/esm/core/hub/usecases/budget.js +78 -0
- package/target/esm/core/hub/usecases/config.js +5 -0
- package/target/esm/core/hub/usecases/context.js +13 -0
- package/target/esm/core/hub/usecases/hubs.js +95 -0
- package/target/esm/core/hub/usecases/propose.js +39 -0
- package/target/esm/core/hub/usecases/room.js +82 -0
- package/target/esm/{app → core/hub/usecases}/rooms.js +11 -63
- package/target/esm/core/hub/usecases/roster.js +47 -0
- package/target/esm/core/hub/usecases/send.js +78 -0
- package/target/esm/core/hub/usecases/staging.js +60 -0
- package/target/esm/{app → core/hub/usecases}/view.js +33 -33
- package/target/esm/core/hub/work/index.js +13 -0
- package/target/esm/core/hub/work/parse.js +37 -0
- package/target/esm/core/hub/work/task.js +68 -0
- package/target/esm/core/signing/index.js +4 -0
- package/target/esm/index.js +7 -6
- package/target/esm/lib/fail.js +18 -0
- package/target/esm/lib/index.js +20 -195
- package/target/esm/lib/json.js +81 -0
- package/target/dts/app/agent.d.ts +0 -109
- package/target/dts/app/session.d.ts +0 -65
- package/target/dts/cli/context.d.ts +0 -6
- package/target/dts/cli/operator.d.ts +0 -10
- package/target/dts/cli/shared.d.ts +0 -27
- package/target/dts/domain/decisions.d.ts +0 -65
- package/target/dts/domain/signals.d.ts +0 -37
- package/target/dts/heartbeat/platform.d.ts +0 -15
- package/target/dts/heartbeat/tools.d.ts +0 -11
- package/target/dts/home/index.d.ts +0 -21
- package/target/dts/hub/index.d.ts +0 -72
- package/target/dts/runtime/watch.d.ts +0 -17
- package/target/dts/store/git/index.d.ts +0 -92
- package/target/dts/store/git/remote.d.ts +0 -95
- package/target/dts/store/kafka/index.d.ts +0 -2
- package/target/dts/store/temporal/index.d.ts +0 -2
- package/target/esm/app/budget.js +0 -95
- package/target/esm/app/context.js +0 -16
- package/target/esm/app/hubs.js +0 -76
- package/target/esm/app/room.js +0 -181
- package/target/esm/app/session.js +0 -99
- package/target/esm/cli/context.js +0 -8
- package/target/esm/cli/operator.js +0 -185
- package/target/esm/cli/shared.js +0 -159
- package/target/esm/cli/skill.js +0 -54
- package/target/esm/domain/decisions.js +0 -178
- package/target/esm/domain/profiles.js +0 -96
- package/target/esm/domain/signals.js +0 -134
- package/target/esm/heartbeat/platform.js +0 -83
- package/target/esm/heartbeat/tools.js +0 -68
- package/target/esm/home/index.js +0 -88
- package/target/esm/hub/index.js +0 -224
- package/target/esm/protocol/index.js +0 -219
- package/target/esm/runtime/reader.js +0 -65
- package/target/esm/runtime/session.js +0 -116
- package/target/esm/runtime/watch.js +0 -321
- package/target/esm/store/git/index.js +0 -719
- package/target/esm/store/git/remote.js +0 -928
- package/target/esm/store/index.js +0 -15
- package/target/esm/store/kafka/index.js +0 -3
- package/target/esm/store/temporal/index.js +0 -3
- /package/target/dts/{domain/index.d.ts → core/hub/capabilities.d.ts} +0 -0
- /package/target/dts/{protocol → core/hub/protocol}/files.d.ts +0 -0
package/target/esm/app/hubs.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
// hubs: the operator's hubs on this machine: list, create, switch, add a signed replica, amend the shared contract.
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { DEFAULT_PROFILE, PROFILES_CAPABILITY, parseProfile } from '../domain/profiles.js';
|
|
5
|
-
import { HOME, OPERATOR, config, ensureHome, setConfig } from '../home/index.js';
|
|
6
|
-
import { createHub, hubNames, openHub, roomNames } from '../hub/index.js';
|
|
7
|
-
import { fail, strictJson, words } from '../lib/index.js';
|
|
8
|
-
import { ID_RE, compose } from '../protocol/index.js';
|
|
9
|
-
import * as Remote from '../store/git/remote.js';
|
|
10
|
-
// The operator's terminal context picks the hub unless one is named.
|
|
11
|
-
export const hubOf = (name) => openHub(name ?? config().hub);
|
|
12
|
-
export const hubs = () => {
|
|
13
|
-
ensureHome();
|
|
14
|
-
if (!hubNames().length)
|
|
15
|
-
openHub('local');
|
|
16
|
-
const cur = config().hub;
|
|
17
|
-
return hubNames().map(n => {
|
|
18
|
-
const H = openHub(n);
|
|
19
|
-
return { name: H.name, current: H.name === cur, store: H.d.store.type, trust: H.contract.trust, contract: H.contract.version,
|
|
20
|
-
rooms: roomNames(H).length, remote: H.d.store.remote ?? null, dir: H.dir };
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
// A new hub; a signed one makes its root key here and returns what other machines need to pin it.
|
|
24
|
-
export const create = (name, { signed = false, url } = {}) => {
|
|
25
|
-
if (!ID_RE.test(name))
|
|
26
|
-
fail('usage: ringi hub create <name> [--signed [--url <git url>]]');
|
|
27
|
-
createHub(name, { signed, url });
|
|
28
|
-
const H = openHub(name);
|
|
29
|
-
return { H, rootKey: H.signed ? path.join(HOME, 'keys', name, OPERATOR) : null,
|
|
30
|
-
add: H.signed ? `ringi hub add ${name} ${H.d.store.remote ?? '<url>'} --root '${H.d.root}' --genesis ${H.d.genesis}` : null };
|
|
31
|
-
};
|
|
32
|
-
export const use = (name) => {
|
|
33
|
-
openHub(name);
|
|
34
|
-
setConfig({ hub: name, room: null });
|
|
35
|
-
};
|
|
36
|
-
// A replica of a signed hub. The root key comes from the operator, out of band: a key the hub advertises proves nothing.
|
|
37
|
-
export const add = (name, url, { root, genesis }) => {
|
|
38
|
-
if (!ID_RE.test(name) || !url)
|
|
39
|
-
fail('usage: ringi hub add <name> <git url> --root <public key|file> [--genesis <sha>]');
|
|
40
|
-
ensureHome();
|
|
41
|
-
Remote.hubAdd({ home: HOME, name, url, root, genesis });
|
|
42
|
-
return openHub(name);
|
|
43
|
-
};
|
|
44
|
-
// A new version of the shared contract on `main`. Rooms keep their base until moved (rooms.rebase).
|
|
45
|
-
export const amend = (H, x) => {
|
|
46
|
-
const name = H.store.contractFile(H.main, 'contract.json') !== null ? 'contract.json' : 'hub.json';
|
|
47
|
-
const contract = strictJson(H.store.contractFile(H.main, name), name);
|
|
48
|
-
for (const kv of x.set ?? []) {
|
|
49
|
-
const [k, v] = kv.split(/=(.*)/s);
|
|
50
|
-
if (!['version', 'capabilities', 'protocol', 'profile'].includes(k))
|
|
51
|
-
fail(`contract keys that can be set: version, capabilities, protocol, profile (not ${k})`);
|
|
52
|
-
contract[k] = k === 'capabilities' ? words(v) : k === 'protocol' ? Number(v) : v;
|
|
53
|
-
}
|
|
54
|
-
const files = { [name]: JSON.stringify(contract, null, 2) + '\n' };
|
|
55
|
-
if (x.authority)
|
|
56
|
-
files['authority.json'] = JSON.stringify(strictJson(fs.readFileSync(x.authority, 'utf8'), x.authority), null, 2) + '\n';
|
|
57
|
-
for (const f of x.files ?? []) {
|
|
58
|
-
// A profile is checked before it reaches the contract.
|
|
59
|
-
if (/^profiles\/[^/]+\.json$/.test(f.path))
|
|
60
|
-
parseProfile(f.content.toString('utf8'), f.path);
|
|
61
|
-
files[f.path] = f.content;
|
|
62
|
-
}
|
|
63
|
-
if (typeof contract.profile === 'string' && contract.profile !== DEFAULT_PROFILE && !files[`profiles/${contract.profile}.json`] && H.store.contractFile(H.main, `profiles/${contract.profile}.json`) === null) {
|
|
64
|
-
fail(`the default profile ${contract.profile} is not in the hub; attach it: --attach <file>:profiles/${contract.profile}.json`);
|
|
65
|
-
}
|
|
66
|
-
// Profiles other than the built-in A2A rules need clients that read them: the contract says so.
|
|
67
|
-
if (Object.keys(files).some(f => f.startsWith('profiles/')) || (x.set ?? []).some(kv => kv.startsWith('profile='))) {
|
|
68
|
-
const caps = Array.isArray(contract.capabilities) ? contract.capabilities : [];
|
|
69
|
-
if (!caps.includes(PROFILES_CAPABILITY))
|
|
70
|
-
contract.capabilities = [...caps, PROFILES_CAPABILITY];
|
|
71
|
-
files[name] = JSON.stringify(contract, null, 2) + '\n';
|
|
72
|
-
}
|
|
73
|
-
H.store.amendContract(OPERATOR, compose(x.text, [['To', '*'], ['Kind', 'hub']]), files);
|
|
74
|
-
return { version: String(contract.version) };
|
|
75
|
-
};
|
|
76
|
-
//# sourceMappingURL=hubs.js.map
|
package/target/esm/app/room.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
// room: what any participant (the operator or an agent) does in a room: write messages and read them, follow work,
|
|
2
|
-
// check signals. Each operation takes who acts and typed input, and returns data; interfaces print it.
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import * as D from '../domain/decisions.js';
|
|
5
|
-
import { isOpen, tasksIn } from '../domain/profiles.js';
|
|
6
|
-
import * as Signals from '../domain/signals.js';
|
|
7
|
-
import { OPERATOR } from '../home/index.js';
|
|
8
|
-
import { HIDDEN, append } from '../hub/index.js';
|
|
9
|
-
import * as HubSignals from '../hub/signals.js';
|
|
10
|
-
import { fail, note, short } from '../lib/index.js';
|
|
11
|
-
import { checkCollisions } from '../protocol/files.js';
|
|
12
|
-
import { ID_RE, TOKEN_RE, checkOutgoing, compose, link, lookup, ordered, rootOf, under } from '../protocol/index.js';
|
|
13
|
-
import { linked, loadRoomUnlocked, loadState, readerLock, saveState } from '../runtime/reader.js';
|
|
14
|
-
import { taskView } from './view.js';
|
|
15
|
-
export const isRef = (R) => (x) => R.hub.store.isRef(x);
|
|
16
|
-
// Staging, like git's index: add takes a file's content into the store now, and the actor's next message carries it,
|
|
17
|
-
// whatever happens to the file meanwhile. Results and state travel only so, never through a shared directory. The store
|
|
18
|
-
// keeps staged contents reachable (`retain`); it grows before the list does and shrinks after, so a crash in between
|
|
19
|
-
// leaks an object rather than loses one.
|
|
20
|
-
export const FILE_MAX = 64 << 20;
|
|
21
|
-
const tooBig = (path, size) => size > FILE_MAX && fail(`${path} is ${Math.ceil(size / (1 << 20))} MiB; an attachment is at most ${FILE_MAX >> 20} MiB`);
|
|
22
|
-
// What retain keeps: each staged content once, named by its id, so two snapshots of one path both stay.
|
|
23
|
-
const kept = (all) => [...new Set(all.map(s => s.blob))].map(blob => ({ path: blob, blob, mode: '100644' }));
|
|
24
|
-
export const staged = ({ R, me }) => loadState(R, me).staged ?? [];
|
|
25
|
-
export const stage = ({ R, me }, files) => {
|
|
26
|
-
const taken = files.map(e => {
|
|
27
|
-
if (!e.file)
|
|
28
|
-
fail(`${e.path}: add takes files`);
|
|
29
|
-
tooBig(e.path, fs.statSync(e.file).size);
|
|
30
|
-
const b = R.hub.store.blob(e.file);
|
|
31
|
-
tooBig(e.path, b.size);
|
|
32
|
-
return { path: e.path, blob: b.id, mode: e.mode, size: b.size };
|
|
33
|
-
});
|
|
34
|
-
return readerLock(R, me, () => {
|
|
35
|
-
const st = loadState(R, me);
|
|
36
|
-
const next = new Map((st.staged ?? []).map(s => [s.path, s]));
|
|
37
|
-
for (const s of taken)
|
|
38
|
-
next.set(s.path, s);
|
|
39
|
-
const all = [...next.values()];
|
|
40
|
-
checkCollisions(all.map(s => s.path));
|
|
41
|
-
R.hub.store.retain(R.s, me, kept([...all, ...st.staged ?? []]));
|
|
42
|
-
saveState(R, me, { ...st, staged: all });
|
|
43
|
-
R.hub.store.retain(R.s, me, kept(all));
|
|
44
|
-
return all;
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
const shrink = ({ R, me }, keep) => {
|
|
48
|
-
const st = loadState(R, me);
|
|
49
|
-
const left = (st.staged ?? []).filter(keep);
|
|
50
|
-
saveState(R, me, { ...st, staged: left });
|
|
51
|
-
R.hub.store.retain(R.s, me, kept(left));
|
|
52
|
-
return left;
|
|
53
|
-
};
|
|
54
|
-
// Unstages the given paths, or everything.
|
|
55
|
-
export const unstage = (a, paths) => readerLock(a.R, a.me, () => {
|
|
56
|
-
const missing = (paths ?? []).filter(p => !staged(a).some(s => s.path === p));
|
|
57
|
-
if (missing.length)
|
|
58
|
-
fail(`not staged: ${missing.join(', ')}`);
|
|
59
|
-
return shrink(a, s => paths !== null && !paths.includes(s.path));
|
|
60
|
-
});
|
|
61
|
-
// A message from the actor. The operator may omit `to`: the room, or the assignees when there are any.
|
|
62
|
-
export const send = ({ R, me }, x) => {
|
|
63
|
-
const P = R.profile;
|
|
64
|
-
const { all } = linked(R, me);
|
|
65
|
-
const re = x.re ? lookup(all, x.re) : null;
|
|
66
|
-
let to = [...new Set(x.to ?? [])];
|
|
67
|
-
const assign = x.assign ? [...new Set(x.assign)] : null;
|
|
68
|
-
if (!to.length && x.reply && re)
|
|
69
|
-
to = re.from === me ? re.to : [re.from, ...(x.all ? re.to.filter(t => t !== me) : [])];
|
|
70
|
-
if (!to.length && assign)
|
|
71
|
-
to = assign;
|
|
72
|
-
if (!to.length && me === OPERATOR)
|
|
73
|
-
to = ['*'];
|
|
74
|
-
if (!to.length)
|
|
75
|
-
fail('--to is required: agent ids, comma-separated, or *');
|
|
76
|
-
for (const t of to)
|
|
77
|
-
if (t !== '*' && !ID_RE.test(t))
|
|
78
|
-
fail(`bad recipient ${t}`);
|
|
79
|
-
if (x.state && !P.states.includes(x.state))
|
|
80
|
-
fail(`--state must be one of profile ${P.name}: ${P.states.join(', ')}`);
|
|
81
|
-
if (x.state && !re)
|
|
82
|
-
fail('--state belongs to a reply inside a piece of work; pass --re <message>');
|
|
83
|
-
for (const a of assign ?? [])
|
|
84
|
-
if (!ID_RE.test(a))
|
|
85
|
-
fail(`bad assignee ${a}`);
|
|
86
|
-
if (x.roles && !x.roles.split(',').every(r => {
|
|
87
|
-
const parts = r.split('=').map(v => v.trim());
|
|
88
|
-
return parts.length === 2 && ID_RE.test(parts[0]) && TOKEN_RE.test(parts[1]);
|
|
89
|
-
}))
|
|
90
|
-
fail('--roles takes "<id>=<label>, …"; labels mean what the room profile says');
|
|
91
|
-
let grant = null;
|
|
92
|
-
if (x.grant) {
|
|
93
|
-
const d = lookup(all, x.grant);
|
|
94
|
-
const g = D.grantOf(all, R.authorityAt, d.id) ?? fail(`${short(d.id)} is not an approved decision with a budget`);
|
|
95
|
-
if (g.revoked)
|
|
96
|
-
fail(`grant ${short(g.id)} was revoked`);
|
|
97
|
-
grant = g.id;
|
|
98
|
-
}
|
|
99
|
-
// What the actor staged goes along, an explicit attachment of the same path in its place.
|
|
100
|
-
const stagedNow = staged({ R, me }), explicit = x.files ?? [];
|
|
101
|
-
for (const e of explicit)
|
|
102
|
-
if (e.file)
|
|
103
|
-
tooBig(e.path, fs.statSync(e.file).size);
|
|
104
|
-
const named = new Set(explicit.map(e => e.path));
|
|
105
|
-
const entries = [...stagedNow.filter(s => !named.has(s.path)).map(s => ({ path: s.path, blob: s.blob, mode: s.mode })), ...explicit];
|
|
106
|
-
checkCollisions(entries.map(e => e.path));
|
|
107
|
-
const text = compose(x.text, [
|
|
108
|
-
['To', to.join(', ')], ['Re', re?.id], ['Kind', x.task && P.opens], ['State', x.state], ['Assign', assign?.join(', ')],
|
|
109
|
-
['Roles', x.roles], ['Grant', grant], ['Hop', re && String(re.hopEff + 1)],
|
|
110
|
-
]);
|
|
111
|
-
checkOutgoing(text, isRef(R));
|
|
112
|
-
const id = append(R, me, text, entries);
|
|
113
|
-
if (stagedNow.length)
|
|
114
|
-
readerLock(R, me, () => shrink({ R, me }, s => !stagedNow.some(t => t.path === s.path && t.blob === s.blob)));
|
|
115
|
-
if (to.length === 1 && to[0] === '*')
|
|
116
|
-
note(`addressed to the whole room: this ${x.task ? P.opens : 'message'} wakes nobody; name recipients (--to or --assign) to start work`);
|
|
117
|
-
return { id, to, files: entries.length };
|
|
118
|
-
};
|
|
119
|
-
// --- reading ---
|
|
120
|
-
// Who marked a message how (read, taken), from the marks that pass their check.
|
|
121
|
-
export const marks = (R, all) => Signals.marksOn(Signals.check(R, all, R.hub.store.signals(R.s)));
|
|
122
|
-
export const message = ({ R, me }, ref) => {
|
|
123
|
-
const { all } = linked(R, me);
|
|
124
|
-
const m = lookup(all, ref);
|
|
125
|
-
return { all, m, replies: [...all.values()].filter(x => x.reId === m.id), marks: marks(R, all).get(m.id) };
|
|
126
|
-
};
|
|
127
|
-
export const thread = ({ R, me }, ref) => {
|
|
128
|
-
const { all } = linked(R, me);
|
|
129
|
-
return { all, msgs: under(all, rootOf(all, lookup(all, ref))) };
|
|
130
|
-
};
|
|
131
|
-
// Open work that concerns the actor (the operator: all open work); with `all`, every piece of work.
|
|
132
|
-
export const tasks = ({ R, me }, { all: everything = false } = {}) => {
|
|
133
|
-
const P = R.profile;
|
|
134
|
-
const { all } = linked(R, me);
|
|
135
|
-
let ts = tasksIn(all, P);
|
|
136
|
-
if (!everything)
|
|
137
|
-
ts = ts.filter(t => isOpen(t, P) && (me === OPERATOR || t.requester === me || t.assignees.includes(me) || (!t.assignees.length && (t.root.to.includes(me) || t.root.to.includes('*')))));
|
|
138
|
-
ts.sort((a, b) => a.at - b.at);
|
|
139
|
-
const m = marks(R, all);
|
|
140
|
-
return { tasks: ts, views: ts.map(t => taskView(t, m.get(t.root.id)?.taken ?? [])) };
|
|
141
|
-
};
|
|
142
|
-
export const log = ({ R, me }, { agent, all: everything = false, n = 20 } = {}) => {
|
|
143
|
-
const { all } = linked(R, me);
|
|
144
|
-
return ordered([...all.values()].filter(m => (!agent || m.from === agent) && (everything || !(m.kind && HIDDEN.has(m.kind))))).slice(-n);
|
|
145
|
-
};
|
|
146
|
-
// The files of a message: one named path, or all of them.
|
|
147
|
-
export const files = ({ R, me }, ref, path) => {
|
|
148
|
-
const { all } = linked(R, me);
|
|
149
|
-
const m = lookup(all, ref);
|
|
150
|
-
if (path && !m.files.some(f => f.path === path))
|
|
151
|
-
fail(`no ${path} in ${short(m.id)}`);
|
|
152
|
-
return { m, files: m.files.filter(f => !path || f.path === path).map(f => ({ path: f.path, content: R.hub.store.file(m.id, f.path) })) };
|
|
153
|
-
};
|
|
154
|
-
export const members = ({ R, me }) => {
|
|
155
|
-
const { logs, all } = linked(R, me);
|
|
156
|
-
const cards = new Map(ordered([...all.values()].filter(m => m.kind === 'card' && !m.bad)).map(m => [m.from, m]));
|
|
157
|
-
return Object.entries(R.members).map(([id, info]) => ({ id, role: info.role ?? 'member',
|
|
158
|
-
messages: (logs.get(id) ?? []).filter(m => !(m.kind && HIDDEN.has(m.kind))).length, card: cards.get(id)?.subject ?? null }));
|
|
159
|
-
};
|
|
160
|
-
// --- signals ---
|
|
161
|
-
// The room's signals, each checked against its message and against what this reader accepted before; `repair` first
|
|
162
|
-
// restores the missing signals of the actor's own messages.
|
|
163
|
-
export const signals = ({ R, me }, { repair = false } = {}) => readerLock(R, me, () => {
|
|
164
|
-
const { logs, st } = loadRoomUnlocked(R, me);
|
|
165
|
-
const all = link(logs);
|
|
166
|
-
let repaired = null;
|
|
167
|
-
if (repair) {
|
|
168
|
-
repaired = 0;
|
|
169
|
-
for (const m of logs.get(me) ?? [])
|
|
170
|
-
repaired += HubSignals.emit(R, me, all, m);
|
|
171
|
-
}
|
|
172
|
-
const records = R.hub.store.signals(R.s);
|
|
173
|
-
const checked = Signals.check(R, all, records);
|
|
174
|
-
const p = Signals.pins(records, checked, st.signals);
|
|
175
|
-
saveState(R, me, { ...loadState(R, me), signals: p.accepted });
|
|
176
|
-
return { all, checked, alarms: [...p.alarms, ...checked.filter(c => !c.ok).map(c => `signal ${c.ref}: ${c.why}`)], repaired };
|
|
177
|
-
});
|
|
178
|
-
// What interfaces need to show and store a message's files: their sizes, and a path safe to write under.
|
|
179
|
-
export { withSizes } from '../hub/index.js';
|
|
180
|
-
export { checkPath } from '../protocol/files.js';
|
|
181
|
-
//# sourceMappingURL=room.js.map
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// Session use cases preserve the operator's identity, seat and delegated scope.
|
|
2
|
-
import { OPERATOR, ensureHome, locked } from '../home/index.js';
|
|
3
|
-
import { controlChange, openHub, room as roomOf, start } from '../hub/index.js';
|
|
4
|
-
import { AGENT_RE } from '../protocol/index.js';
|
|
5
|
-
import { allSessions, bound, dropSession, liveness, ownSession, parseSelector, pidAlive, readSession, saveSession, seatHolder, whoAmI } from '../runtime/session.js';
|
|
6
|
-
import { fail, note, stamp } from '../lib/index.js';
|
|
7
|
-
import { inbox } from './agent.js';
|
|
8
|
-
import { tasks } from './room.js';
|
|
9
|
-
export { bound } from '../runtime/session.js';
|
|
10
|
-
// A room still waiting for its agents is not read: nothing is marked seen before its work starts.
|
|
11
|
-
export const briefing = (s) => {
|
|
12
|
-
const actor = bound();
|
|
13
|
-
const st = start(actor.R);
|
|
14
|
-
return { session: s, actor, start: st, tasks: st.started ? tasks(actor).views : [], inbox: st.started ? inbox(actor) : null };
|
|
15
|
-
};
|
|
16
|
-
export const join = ({ hub, room, agent: id, scope }) => {
|
|
17
|
-
const me = whoAmI();
|
|
18
|
-
const agent = id ?? me.product ?? fail('--as <id> is required: this session\'s product is unknown');
|
|
19
|
-
if (!AGENT_RE.test(agent) || agent === OPERATOR)
|
|
20
|
-
fail(`bad agent id ${agent}: lowercase letters, digits, - and _, no dot`);
|
|
21
|
-
const H = openHub(hub), R = roomOf(H, room);
|
|
22
|
-
if (R.archived)
|
|
23
|
-
fail(`${room} is archived`);
|
|
24
|
-
if (H.signed) {
|
|
25
|
-
if (!H.store.joinKey)
|
|
26
|
-
fail(`hub ${H.name}: its store cannot make keys`);
|
|
27
|
-
const key = H.store.joinKey(R.s, agent);
|
|
28
|
-
if (!key.admitted)
|
|
29
|
-
return { agent, hub: H.name, room: R.name, session: null, key };
|
|
30
|
-
}
|
|
31
|
-
locked('sessions', () => {
|
|
32
|
-
const holder = seatHolder(H.name, R.genesis, agent, me.handle);
|
|
33
|
-
if (holder)
|
|
34
|
-
fail(`${room}/${agent} is held by another session (${holder.handle}, ${liveness(holder)}). A seat ends only with leave, or the operator's takeover: "continue ${room}/${agent}" in this chat`);
|
|
35
|
-
const mine = ownSession(me.handle);
|
|
36
|
-
if (mine?.product === 'watch' && mine.pid && pidAlive(mine.pid))
|
|
37
|
-
fail('this chat handed its seat to a live watcher; stop or leave it before joining another room');
|
|
38
|
-
if (mine && mine.handle !== me.handle)
|
|
39
|
-
dropSession(mine.handle);
|
|
40
|
-
const same = !!mine && mine.hub === H.name && mine.genesis === R.genesis && mine.agent === agent;
|
|
41
|
-
if (!R.members[agent]) {
|
|
42
|
-
if (H.signed)
|
|
43
|
-
fail(`${agent} is not in the roster of ${room}; the root admits its key first`);
|
|
44
|
-
controlChange(R, OPERATOR, `join ${agent}`, m => { m[agent] = { role: 'member', since: stamp() }; });
|
|
45
|
-
}
|
|
46
|
-
if (mine && !same)
|
|
47
|
-
note(`left ${mine.hub}/${mine.room} as ${mine.agent}: one room per session`);
|
|
48
|
-
saveSession({ handle: me.handle, product: me.product, hub: H.name, room: R.name, genesis: R.genesis, agent,
|
|
49
|
-
scope: scope ?? (same ? mine.scope : null), state: 'active', since: same ? mine.since : stamp(), lastSeen: stamp(), pid: me.pid });
|
|
50
|
-
});
|
|
51
|
-
return { agent, hub: H.name, room: R.name, session: readSession(me.handle), key: null };
|
|
52
|
-
};
|
|
53
|
-
export const resume = (selector) => {
|
|
54
|
-
const me = whoAmI();
|
|
55
|
-
ensureHome();
|
|
56
|
-
return locked('sessions', () => {
|
|
57
|
-
let target;
|
|
58
|
-
if (!selector) {
|
|
59
|
-
const mine = ownSession(me.handle);
|
|
60
|
-
if (!mine) {
|
|
61
|
-
const cands = allSessions().filter(s => liveness(s) !== 'active').sort((a, b) => Number(b.product === me.product) - Number(a.product === me.product));
|
|
62
|
-
if (!cands.length)
|
|
63
|
-
fail('nothing to continue: this chat was never joined, and no paused or gone session waits. The operator says "join <room> as <id>"');
|
|
64
|
-
fail(`this chat has no binding of its own. Say which one to take over:\n${cands.map(s => ` ringi continue ${s.hub}:${s.room}/${s.agent} (${liveness(s)}, ${s.product ?? '?'}, ${s.handle}${s.scope ? `, scope: ${s.scope}` : ''})`).join('\n')}`);
|
|
65
|
-
}
|
|
66
|
-
target = mine;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
const sel = parseSelector(selector);
|
|
70
|
-
const hits = allSessions().filter(s => s.room === sel.room && s.agent === sel.agent && (!sel.hub || s.hub === sel.hub));
|
|
71
|
-
if (hits.length > 1)
|
|
72
|
-
fail(`several hubs have ${sel.room}/${sel.agent}; name one: <hub>:${sel.room}/${sel.agent}`);
|
|
73
|
-
target = hits[0] ?? fail(`no session holds ${selector}; the operator joins this chat with ringi join`);
|
|
74
|
-
}
|
|
75
|
-
if (target.handle !== me.handle) {
|
|
76
|
-
if (liveness(target) === 'active' || (target.product === 'watch' && target.pid && pidAlive(target.pid)))
|
|
77
|
-
fail(`${target.room}/${target.agent} is held by a live session (${target.handle}); it is not taken over`);
|
|
78
|
-
dropSession(target.handle);
|
|
79
|
-
note(`took over ${target.hub}/${target.room}/${target.agent} from ${target.handle}`);
|
|
80
|
-
}
|
|
81
|
-
const session = { ...target, handle: me.handle, product: target.handle === me.handle ? target.product : me.product, state: 'active',
|
|
82
|
-
since: target.handle === me.handle ? target.since : stamp(), lastSeen: stamp(), pid: me.pid ?? (target.handle === me.handle ? target.pid : null),
|
|
83
|
-
takenFrom: target.handle === me.handle ? target.takenFrom : undefined };
|
|
84
|
-
saveSession(session);
|
|
85
|
-
return session;
|
|
86
|
-
});
|
|
87
|
-
};
|
|
88
|
-
export const stop = () => locked('sessions', () => {
|
|
89
|
-
const s = ownSession(whoAmI().handle) ?? fail('this session is in no room');
|
|
90
|
-
const stopped = { ...s, state: 'stopped', lastSeen: stamp() };
|
|
91
|
-
saveSession(stopped);
|
|
92
|
-
return stopped;
|
|
93
|
-
});
|
|
94
|
-
export const leave = () => locked('sessions', () => {
|
|
95
|
-
const s = ownSession(whoAmI().handle) ?? fail('this session is in no room');
|
|
96
|
-
dropSession(s.handle);
|
|
97
|
-
return s;
|
|
98
|
-
});
|
|
99
|
-
//# sourceMappingURL=session.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// context: who runs a command and in which room, from the command line.
|
|
2
|
-
import * as Context from '../app/context.js';
|
|
3
|
-
import { words } from '../lib/index.js';
|
|
4
|
-
import { opt } from './args.js';
|
|
5
|
-
export { isRef } from '../app/room.js';
|
|
6
|
-
export const parseTo = (v) => [...new Set(words(v))];
|
|
7
|
-
export const operatorCtx = (o) => Context.operator({ hub: opt(o, 'hub'), room: opt(o, 'room') });
|
|
8
|
-
//# sourceMappingURL=context.js.map
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
// operator: what the human runs in a terminal: where things stand, sessions, hubs and rooms. Each command parses its
|
|
2
|
-
// arguments, calls app operations and prints the result.
|
|
3
|
-
import fs from 'node:fs';
|
|
4
|
-
import * as Hubs from '../app/hubs.js';
|
|
5
|
-
import * as Heartbeat from '../app/heartbeat.js';
|
|
6
|
-
import * as Overview from '../app/overview.js';
|
|
7
|
-
import * as Rooms from '../app/rooms.js';
|
|
8
|
-
import { oneLine, render } from '../app/view.js';
|
|
9
|
-
import { config } from '../app/context.js';
|
|
10
|
-
import { withSizes } from '../app/room.js';
|
|
11
|
-
import { fail, short, sleep } from '../lib/index.js';
|
|
12
|
-
import { attachments, dump, flag, list, opt, out, textOf } from './args.js';
|
|
13
|
-
import { taskLine } from './shared.js';
|
|
14
|
-
// --- where things stand, sessions, forget ---
|
|
15
|
-
export const sessionLine = (s) => `${s.agent.padEnd(12)} ${s.liveness.padEnd(8)} ${(s.product ?? '?').padEnd(7)} ${s.handle}${s.scope ? ` scope: ${s.scope}` : ''}`;
|
|
16
|
-
export const where = async (o) => {
|
|
17
|
-
const H = Hubs.hubOf(opt(o, 'hub'));
|
|
18
|
-
const w = Overview.where(H, opt(o, 'room') ?? config().room);
|
|
19
|
-
out(`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(' ')}` : ''}`);
|
|
20
|
-
const R = w.room;
|
|
21
|
-
if (!R)
|
|
22
|
-
return out('no current room: ringi room create <id> | ringi room switch <id>');
|
|
23
|
-
const agents = Object.values(R.members).filter(m => m.role !== 'root').length;
|
|
24
|
-
out(`room ${R.name}${R.archived ? ' (archived, read-only)' : ''}, genesis ${short(R.genesis)}, profile ${R.profile.name}; members: ${Object.entries(R.members).map(([id, i]) => i.role === 'root' ? `${id} (root)` : id).join(', ')}`
|
|
25
|
-
+ (R.quorum === null ? '' : agents >= R.quorum ? `; started at its quorum of ${R.quorum} agents` : `; waiting for a quorum of ${R.quorum} agents, has ${agents}`));
|
|
26
|
-
out(w.sessions.length ? `sessions:\n${w.sessions.map(s => ` ${sessionLine(s)}`).join('\n')}` : 'sessions: none joined');
|
|
27
|
-
out(w.work.length ? `open work:\n${w.work.map(t => ` ${taskLine(t)}`).join('\n')}` : 'open work: none');
|
|
28
|
-
if (w.proposals.length)
|
|
29
|
-
out(`open proposals:\n${w.proposals.map(x => ` ${short(x.proposal.id)} ${x.state} → ${x.decider} ${x.proposal.subject}`).join('\n')}`);
|
|
30
|
-
const n = Number(opt(o, 'n') ?? (flag(o, 'short') ? 10 : 5));
|
|
31
|
-
out(`last ${Math.min(n, w.messages.length)} of ${w.messages.length} messages:`);
|
|
32
|
-
const show = (all, m) => out(flag(o, 'short') ? ` ${oneLine(m)}` : `\n${render(all, m, { max: 2000, files: () => withSizes(R, m) })}`);
|
|
33
|
-
for (const m of w.messages.slice(-n))
|
|
34
|
-
show(w.all, m);
|
|
35
|
-
if (!flag(o, 'follow'))
|
|
36
|
-
return;
|
|
37
|
-
out('following; new messages appear as they land (Ctrl-C to stop)');
|
|
38
|
-
const seen = new Set(w.all.keys());
|
|
39
|
-
for (;;) {
|
|
40
|
-
await sleep(Number(opt(o, 'interval') ?? 2) * 1000);
|
|
41
|
-
const now = Overview.arrived(H, R, seen);
|
|
42
|
-
for (const m of now.messages)
|
|
43
|
-
show(now.all, m);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
// Each session's pulse on this machine, judged without the model.
|
|
47
|
-
export const heartbeats = async (o) => {
|
|
48
|
-
if (flag(o, 'published')) {
|
|
49
|
-
const R = Rooms.roomIn(Hubs.hubOf(opt(o, 'hub')), opt(o, 'room'));
|
|
50
|
-
const hs = Heartbeat.published(R);
|
|
51
|
-
if (flag(o, 'json'))
|
|
52
|
-
return dump(hs);
|
|
53
|
-
if (!hs.length)
|
|
54
|
-
return out(`no heartbeats in ${R.name}`);
|
|
55
|
-
for (const h of hs)
|
|
56
|
-
out(`${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)}`);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const ps = await Heartbeat.heartbeats();
|
|
60
|
-
if (flag(o, 'json'))
|
|
61
|
-
return dump(ps);
|
|
62
|
-
if (!ps.length)
|
|
63
|
-
return out('no sessions');
|
|
64
|
-
for (const { session: s, tool, beat: b } of ps) {
|
|
65
|
-
const state = b.waits ? `${b.state} (${b.waits})` : b.state;
|
|
66
|
-
out(`${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${b.cpu === null ? '' : ` cpu ${b.cpu.toFixed(1)}s`} ${tool} ${s.handle}`);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
// The process that beats for every session here; `join` and `continue` start it.
|
|
70
|
-
export const pulse = async (o) => {
|
|
71
|
-
process.exitCode = await Heartbeat.pulse({ every: Number(opt(o, 'beat') ?? 30), once: flag(o, 'once'), log: s => process.stderr.write(`ringi: ${s}\n`) });
|
|
72
|
-
};
|
|
73
|
-
export const sessions = (o) => {
|
|
74
|
-
if (o._[0] === 'forget') {
|
|
75
|
-
const handle = o._[1] ?? fail('usage: ringi sessions forget <handle>');
|
|
76
|
-
Overview.forgetSession(handle);
|
|
77
|
-
return out(`forgot session ${handle}; its seat is free`);
|
|
78
|
-
}
|
|
79
|
-
const ss = Overview.sessions();
|
|
80
|
-
if (flag(o, 'json'))
|
|
81
|
-
return dump(ss);
|
|
82
|
-
if (!ss.length)
|
|
83
|
-
return out('no sessions');
|
|
84
|
-
for (const s of ss)
|
|
85
|
-
out(`${s.hub}/${s.room} ${sessionLine(s)}`);
|
|
86
|
-
};
|
|
87
|
-
export const forget = (o) => {
|
|
88
|
-
const [name, id] = (o._[0] ?? '').split('/');
|
|
89
|
-
if (!name || !id)
|
|
90
|
-
fail('usage: ringi forget <room>/<log>');
|
|
91
|
-
const H = Hubs.hubOf(opt(o, 'hub'));
|
|
92
|
-
const n = Rooms.forgetLog(H, Rooms.roomIn(H, name), id);
|
|
93
|
-
out(`forgot the accepted history of ${name}/${id} for ${n} reader(s); the next read accepts what is there now`);
|
|
94
|
-
};
|
|
95
|
-
// --- hubs and rooms ---
|
|
96
|
-
export const hub = (o) => {
|
|
97
|
-
const [sub, arg] = o._;
|
|
98
|
-
if (!sub || sub === 'list') {
|
|
99
|
-
for (const h of Hubs.hubs())
|
|
100
|
-
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}`);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (sub === 'create') {
|
|
104
|
-
const r = Hubs.create(arg ?? '', { signed: flag(o, 'signed'), url: opt(o, 'url') });
|
|
105
|
-
if (!r.add)
|
|
106
|
-
return out(`created hub ${arg} (${r.H.dir})`);
|
|
107
|
-
return out(`created signed hub ${arg}${r.H.d.store.remote ? `, published to ${r.H.d.store.remote}` : ''}. Its root key stays on this machine (${r.rootKey}).
|
|
108
|
-
Give every machine that joins it, out of band:
|
|
109
|
-
${r.add}`);
|
|
110
|
-
}
|
|
111
|
-
if (sub === 'switch') {
|
|
112
|
-
Hubs.use(arg ?? fail('usage: ringi hub switch <name>'));
|
|
113
|
-
return out(`current hub: ${arg}; agents keep their own rooms`);
|
|
114
|
-
}
|
|
115
|
-
if (sub === 'add') {
|
|
116
|
-
const H = Hubs.add(arg ?? '', o._[2] ?? '', { root: opt(o, 'root'), genesis: opt(o, 'genesis') });
|
|
117
|
-
return out(`added signed hub ${arg} from ${o._[2]}: contract ${H.contract.version}, ${Rooms.rooms(H).length} room(s), root pinned`);
|
|
118
|
-
}
|
|
119
|
-
if (sub === 'amend') {
|
|
120
|
-
const H = Hubs.hubOf(opt(o, 'hub'));
|
|
121
|
-
const files = list(o, 'attach').flatMap(attachments).map(e => ({ path: e.path, content: fs.readFileSync(e.file) }));
|
|
122
|
-
const r = Hubs.amend(H, { text: textOf(o), set: list(o, 'set'), authority: opt(o, 'authority'), files });
|
|
123
|
-
return out(`amended hub ${H.name}: contract ${r.version}; rooms keep their base until ringi room rebase-contract <room>`);
|
|
124
|
-
}
|
|
125
|
-
fail(`unknown: hub ${sub}`);
|
|
126
|
-
};
|
|
127
|
-
export const roomCmd = (o) => {
|
|
128
|
-
const [sub, arg] = o._;
|
|
129
|
-
const H = Hubs.hubOf(opt(o, 'hub'));
|
|
130
|
-
if (!sub || sub === 'list') {
|
|
131
|
-
const rs = Rooms.rooms(H, { archived: flag(o, 'archived') });
|
|
132
|
-
for (const r of rs.filter(r => !r.archived))
|
|
133
|
-
out(`${r.current ? '*' : ' '} ${r.name.padEnd(16)} ${r.members} member(s), ${r.active} active session(s), profile ${r.profile} genesis ${short(r.genesis)}`);
|
|
134
|
-
for (const r of rs.filter(r => r.archived))
|
|
135
|
-
out(` ${r.name.padEnd(16)} archived, read-only`);
|
|
136
|
-
if (!rs.length && !flag(o, 'archived'))
|
|
137
|
-
out(`no rooms in hub ${H.name}: ringi room create <id>`);
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (sub === 'create') {
|
|
141
|
-
const quorum = opt(o, 'quorum');
|
|
142
|
-
const r = Rooms.create(H, arg ?? '', { profile: opt(o, 'profile'), quorum: quorum === undefined ? undefined : Number(quorum) });
|
|
143
|
-
if (quorum !== undefined)
|
|
144
|
-
return out(`created room ${arg} in hub ${H.name} with profile ${r.profile}; it is the current room. Its work starts by itself at a quorum of ${quorum} agent(s): in each chat that should take part, say "join ${arg} as <id>"`);
|
|
145
|
-
return out(`created room ${arg} in hub ${H.name} with profile ${r.profile}; it is the current room. In each chat that should take part, say: "join ${arg} as <id>; <what to accept>"`);
|
|
146
|
-
}
|
|
147
|
-
if (sub === 'migrate') {
|
|
148
|
-
const rev = Rooms.migrate(H, arg ?? fail('usage: ringi room migrate <id>'));
|
|
149
|
-
return out(`room ${arg} uses one branch; its genesis, message ids and session bindings are kept (${short(rev)})`);
|
|
150
|
-
}
|
|
151
|
-
if (sub === 'switch') {
|
|
152
|
-
const R = Rooms.use(H, arg ?? fail('usage: ringi room switch <id>'));
|
|
153
|
-
return out(`current room: ${H.name}/${R.name}; agents keep their own rooms`);
|
|
154
|
-
}
|
|
155
|
-
if (sub === 'admit') {
|
|
156
|
-
const R = Rooms.roomIn(H, opt(o, 'room'));
|
|
157
|
-
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>'));
|
|
158
|
-
return out(`admitted ${arg} to ${H.name}/${R.name}: its signed messages are accepted from now on; it can join`);
|
|
159
|
-
}
|
|
160
|
-
if (sub === 'remove') {
|
|
161
|
-
const R = Rooms.roomIn(H, opt(o, 'room'));
|
|
162
|
-
Rooms.remove(H, R, arg ?? fail('usage: ringi room remove <agent>'));
|
|
163
|
-
return out(`removed ${arg} from ${R.name}: it can no longer write or be woken there; returning needs a fresh join`);
|
|
164
|
-
}
|
|
165
|
-
if (sub === 'archive') {
|
|
166
|
-
// Without an id, the room of the current context.
|
|
167
|
-
const R = Rooms.roomIn(H, arg ?? opt(o, 'room'));
|
|
168
|
-
const name = Rooms.archive(H, R);
|
|
169
|
-
return out(`archived ${R.name} as ${name}: read-only, wakes nobody; its sessions end. Read it with --room ${name}`);
|
|
170
|
-
}
|
|
171
|
-
if (sub === 'delete') {
|
|
172
|
-
const R = Rooms.roomIn(H, arg ?? opt(o, 'room'));
|
|
173
|
-
if (!flag(o, 'yes'))
|
|
174
|
-
fail(`deleting ${R.name} in hub ${H.name} erases it and everything kept for it, for good. Run again with --yes, or archive it instead`);
|
|
175
|
-
Rooms.erase(H, R);
|
|
176
|
-
return out(`deleted room ${R.name}: its branch, signals, pins, evidence and readers' state. Sessions bound to it leave it on their next turn`);
|
|
177
|
-
}
|
|
178
|
-
if (sub === 'rebase-contract') {
|
|
179
|
-
const R = Rooms.roomIn(H, arg ?? fail('usage: ringi room rebase-contract <id>'));
|
|
180
|
-
Rooms.rebase(H, R);
|
|
181
|
-
return out(`room ${R.name} now follows the hub contract at ${short(H.main)} (${H.contract.version})`);
|
|
182
|
-
}
|
|
183
|
-
fail(`unknown: room ${sub}`);
|
|
184
|
-
};
|
|
185
|
-
//# sourceMappingURL=operator.js.map
|