@idleware/ringi 0.4.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/README.md +1 -1
- package/package.json +5 -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/core/agents/heartbeat/index.d.ts +33 -0
- package/target/dts/core/agents/heartbeat/pulse.d.ts +32 -0
- 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} +58 -17
- 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 -33
- 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 +13 -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} +6 -73
- 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/core/agents/heartbeat/index.js +43 -0
- package/target/esm/core/agents/heartbeat/pulse.js +86 -0
- 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 -8
- 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/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 -79
- package/target/dts/store/git/remote.d.ts +0 -86
- 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 -163
- package/target/esm/app/session.js +0 -99
- package/target/esm/cli/context.js +0 -8
- package/target/esm/cli/operator.js +0 -157
- 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/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 -644
- package/target/esm/store/git/remote.js +0 -758
- 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
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
// view: how messages, work, proposals and grants are shown: as text framed for people and models, and as the JSON
|
|
2
2
|
// shapes every interface (the CLI's --json, a control panel) returns.
|
|
3
|
-
import { bytes, when } from '
|
|
3
|
+
import { bytes, when } from '../../../lib/index.js';
|
|
4
4
|
import { KNOWN } from '../protocol/index.js';
|
|
5
5
|
const id12 = (x) => x.slice(0, 12);
|
|
6
6
|
// Trailers a store writes about its own records (the git store's list of attached paths): shown as `Files:`, not again.
|
|
7
7
|
const STORED = new Set(['ringi-files']);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
lines.push(`Files: ${fl.map(f => `${f.path} (${bytes(f.size ?? 0)})`).join(', ')}`);
|
|
33
|
-
if (m.refused.length)
|
|
34
|
-
lines.push(`Refused: ${m.refused.map(f => `${f.path} (${f.why ?? `mode ${f.mode}`})`).join(', ')}`);
|
|
35
|
-
lines.push(`Subject: ${m.subject}`);
|
|
8
|
+
const reLines = (all, m) => {
|
|
9
|
+
if (!m.re && !m.trailers.re)
|
|
10
|
+
return [];
|
|
11
|
+
const p = m.reId ? all.get(m.reId) : undefined;
|
|
12
|
+
return [`Re: ${id12(m.reId ?? m.re ?? m.trailers.re[0])}${p ? ` (${p.from}) ${p.subject}` : ' (not available)'}`];
|
|
13
|
+
};
|
|
14
|
+
// What the message sets, in a fixed order, then the trailers ringi does not know, as written.
|
|
15
|
+
const trailerLines = (m) => {
|
|
16
|
+
const known = [
|
|
17
|
+
['Malformed', m.bad ? `${m.bad} (not delivered, not part of tasks)` : null],
|
|
18
|
+
['Kind', m.kind || null], ['State', m.state || null], ['Assign', m.assign ? m.assign.join(', ') : null],
|
|
19
|
+
['Roles', m.roles ? Object.entries(m.roles).map(([k, v]) => `${k}=${v}`).join(', ') : null],
|
|
20
|
+
['Hop', m.hopEff ? `${m.hop}${m.hopEff !== m.hop ? ` (effective ${m.hopEff})` : ''}` : null],
|
|
21
|
+
];
|
|
22
|
+
const other = Object.entries(m.trailers).filter(([k]) => !KNOWN.has(k) && !STORED.has(k))
|
|
23
|
+
.map(([k, v]) => [`${k[0].toUpperCase()}${k.slice(1)}`, v.join(', ')]);
|
|
24
|
+
return [...known, ...other].flatMap(([k, v]) => v === null ? [] : [`${k}: ${v}`]);
|
|
25
|
+
};
|
|
26
|
+
const fileLines = (m, fl) => [
|
|
27
|
+
...fl.length ? [`Files: ${fl.map(f => `${f.path} (${bytes(f.size ?? 0)})`).join(', ')}`] : [],
|
|
28
|
+
...m.refused.length ? [`Refused: ${m.refused.map(f => `${f.path} (${f.why ?? `mode ${f.mode}`})`).join(', ')}`] : [],
|
|
29
|
+
];
|
|
30
|
+
// The body, cut at `max` characters with a pointer to the whole.
|
|
31
|
+
const bodyLines = (m, max) => {
|
|
36
32
|
const body = max && m.body.length > max ? `${m.body.slice(0, max)}\n[… ${m.body.length - max} more chars: read ${id12(m.id)}]` : m.body;
|
|
37
|
-
|
|
38
|
-
lines.push('', body);
|
|
39
|
-
lines.push(`=== end ${id12(m.id)}`);
|
|
40
|
-
return lines.join('\n');
|
|
33
|
+
return body ? ['', body] : [];
|
|
41
34
|
};
|
|
35
|
+
// Frames a message for a model: sender and how it is known, id, addressing, hop; the body is the peer's content.
|
|
36
|
+
export const render = (all, m, { max = 0, files = () => m.files } = {}) => [
|
|
37
|
+
`=== ${id12(m.id)} · ${m.from} (${m.trust}) → ${m.to.join(', ') || '(nobody)'} · ${when(m.time)}`,
|
|
38
|
+
...reLines(all, m), ...trailerLines(m), ...fileLines(m, files()),
|
|
39
|
+
`Subject: ${m.subject}`, ...bodyLines(m, max),
|
|
40
|
+
`=== end ${id12(m.id)}`,
|
|
41
|
+
].join('\n');
|
|
42
42
|
export const oneLine = (m) => `${id12(m.id)} ${when(m.time).slice(5)} ${m.from} → ${m.to.join(',') || '-'} ${[m.kind, m.state].filter(Boolean).map(x => `[${x}] `).join('')}${m.subject}`;
|
|
43
43
|
export const asJson = (m) => ({ id: m.id, from: m.from, trust: m.trust, to: m.to, re: m.re, kind: m.kind, state: m.state,
|
|
44
44
|
assign: m.assign, roles: m.roles, hop: m.hop, hopEff: m.hopEff, bad: m.bad, time: new Date(m.time * 1000).toISOString(), subject: m.subject,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// profile: what a task is, as data. ringi is a point of coordination, not a methodology: the states of a piece of
|
|
2
|
+
// work, which of them end it, and who may move it, assign it or label people in it are declared by a profile
|
|
3
|
+
// that lives in the hub (`profiles/<name>.json` on main) and is chosen per room. The A2A task model is one such
|
|
4
|
+
// profile (resources/profiles/a2a-1.json); a team or a framework brings its own (architect, reviewer, tester, …).
|
|
5
|
+
// This file interprets any profile; it knows no state, role or rule by name.
|
|
6
|
+
export const PROFILE_SCHEMA = 'ringi-profile/1';
|
|
7
|
+
export const DEFAULT_PROFILE = 'a2a-1';
|
|
8
|
+
// A hub whose rooms may follow profiles other than the built-in A2A rules declares this capability, so that an older
|
|
9
|
+
// client, which knows only those rules, refuses it instead of misreading it.
|
|
10
|
+
export const PROFILES_CAPABILITY = 'profiles/1';
|
|
11
|
+
export * from './parse.js';
|
|
12
|
+
export * from './task.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// parse: a profile is refused, not guessed at, when it is not exactly what its schema describes.
|
|
2
|
+
import { ID_RE, TOKEN_RE } from '../protocol/index.js';
|
|
3
|
+
import { fail, strictJson } from '../../../lib/index.js';
|
|
4
|
+
import { PROFILE_SCHEMA } from './index.js';
|
|
5
|
+
const PRINCIPAL_RE = /^(?:requester|assignee|member|role:[a-z][a-z0-9-]*|agent:[a-z0-9]+(?:[._-][a-z0-9]+)*)$/;
|
|
6
|
+
const RULE_RE = /^(?:assign|roles|grant|state:(?:\*|[a-z][a-z0-9-]*))$/;
|
|
7
|
+
const distinctTokens = (xs) => Array.isArray(xs) && xs.length > 0 && xs.every(s => TOKEN_RE.test(s)) && new Set(xs).size === xs.length;
|
|
8
|
+
const principals = (v) => Array.isArray(v) && v.length <= 64 && v.every(x => PRINCIPAL_RE.test(x));
|
|
9
|
+
const waitingOk = (p) => p.waiting === undefined || (p.states.includes(p.waiting) && !p.terminal.includes(p.waiting));
|
|
10
|
+
// The profile's shape, checked in order: each check may rely on the ones before it.
|
|
11
|
+
const SHAPE = [
|
|
12
|
+
[p => p.schema === PROFILE_SCHEMA, p => `schema ${String(p.schema)} is not ${PROFILE_SCHEMA}; upgrade ringi or fix the profile`],
|
|
13
|
+
[p => ID_RE.test(p.name ?? ''), () => 'a profile needs a name like team-flow-1'],
|
|
14
|
+
[p => TOKEN_RE.test(p.opens ?? ''), () => '`opens` names the Kind that opens a piece of work'],
|
|
15
|
+
[p => distinctTokens(p.states), () => '`states` must be distinct tokens'],
|
|
16
|
+
[p => p.states.includes(p.initial), () => '`initial` must be one of the states'],
|
|
17
|
+
[p => Array.isArray(p.terminal) && p.terminal.every(s => p.states.includes(s)), () => '`terminal` must list states'],
|
|
18
|
+
[waitingOk, () => '`waiting` must be a state that does not end the work'],
|
|
19
|
+
[p => !!p.rules && typeof p.rules === 'object', () => '`rules` is required'],
|
|
20
|
+
];
|
|
21
|
+
// Why one rule is wrong, or null.
|
|
22
|
+
const ruleProblem = (p, k, v) => {
|
|
23
|
+
if (!RULE_RE.test(k))
|
|
24
|
+
return `unknown rule ${k}`;
|
|
25
|
+
if (k.startsWith('state:') && k !== 'state:*' && !p.states.includes(k.slice(6)))
|
|
26
|
+
return `rule ${k} names an unknown state`;
|
|
27
|
+
return principals(v) ? null : `rule ${k} must list principals: requester, assignee, member, role:<label>, agent:<id>`;
|
|
28
|
+
};
|
|
29
|
+
export const parseProfile = (text, label) => {
|
|
30
|
+
const p = strictJson(text, label);
|
|
31
|
+
const wrong = SHAPE.find(([ok]) => !ok(p));
|
|
32
|
+
const why = wrong ? wrong[1](p) : Object.entries(p.rules).map(([k, v]) => ruleProblem(p, k, v)).find(x => x);
|
|
33
|
+
if (why)
|
|
34
|
+
fail(`${label}: ${why}`);
|
|
35
|
+
return p;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// task: a piece of work folded over its messages in thread order, by the room's profile.
|
|
2
|
+
import { HEARTBEATS, one, ordered } from '../protocol/index.js';
|
|
3
|
+
// Who a principal of a rule is in a piece of work.
|
|
4
|
+
const PRINCIPALS = {
|
|
5
|
+
requester: (who, t) => who === t.requester,
|
|
6
|
+
assignee: (who, t) => t.assignees.includes(who),
|
|
7
|
+
member: () => true,
|
|
8
|
+
};
|
|
9
|
+
const holds = (p, who, t) => PRINCIPALS[p]?.(who, t) ?? (p.startsWith('role:') ? t.roles[who] === p.slice(5) : p === `agent:${who}`);
|
|
10
|
+
const allows = (rule, who, t) => !!rule?.some(p => holds(p, who, t));
|
|
11
|
+
const ruleFor = (profile, state) => profile.rules[`state:${state}`] ?? profile.rules['state:*'];
|
|
12
|
+
// A message belongs to the nearest work item on its Re chain, itself included.
|
|
13
|
+
export const taskFor = (all, m, profile) => {
|
|
14
|
+
for (let x = m, i = 0; x && i < 100000; x = x.reId ? all.get(x.reId) : undefined, i++)
|
|
15
|
+
if (x.kind === profile.opens && !x.bad)
|
|
16
|
+
return x;
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
const grant = (profile, t, b, m) => {
|
|
20
|
+
if (!one(m, 'grant') || !allows(profile.rules.grant, m.from, b))
|
|
21
|
+
return null;
|
|
22
|
+
t.grant = one(m, 'grant');
|
|
23
|
+
return 'grant';
|
|
24
|
+
};
|
|
25
|
+
const roles = (profile, t, b, m) => {
|
|
26
|
+
if (!m.roles || !allows(profile.rules.roles, m.from, b))
|
|
27
|
+
return null;
|
|
28
|
+
for (const [id, label] of Object.entries(m.roles))
|
|
29
|
+
label === 'none' ? delete t.roles[id] : t.roles[id] = label;
|
|
30
|
+
return 'roles';
|
|
31
|
+
};
|
|
32
|
+
const assign = (profile, t, b, m) => {
|
|
33
|
+
if (!m.assign || !allows(profile.rules.assign, m.from, b))
|
|
34
|
+
return null;
|
|
35
|
+
t.assignees = m.assign;
|
|
36
|
+
return 'assigned';
|
|
37
|
+
};
|
|
38
|
+
// The first terminal state is final.
|
|
39
|
+
const movable = (profile, t, s) => !!s && !profile.terminal.includes(t.state) && profile.states.includes(s);
|
|
40
|
+
const state = (profile, t, b, m) => {
|
|
41
|
+
if (!movable(profile, t, m.state) || !allows(ruleFor(profile, m.state), m.from, b))
|
|
42
|
+
return null;
|
|
43
|
+
Object.assign(t, { state: m.state, by: m.from, at: m.time });
|
|
44
|
+
return `state.${m.state}`;
|
|
45
|
+
};
|
|
46
|
+
const STEPS = [grant, roles, assign, state];
|
|
47
|
+
const opening = (root, profile, msgs) => ({ root, msgs, state: profile.initial, by: root.from, at: root.time,
|
|
48
|
+
requester: root.from, roles: { ...root.roles }, assignees: root.assign ?? (root.to.includes('*') ? [] : root.to.filter(x => x !== root.from)),
|
|
49
|
+
grant: one(root, 'grant'), effects: new Map([[root.id, ['opened', ...(root.assign ? ['assigned'] : [])]]]) });
|
|
50
|
+
// Heartbeats never take part in work (§6), whatever trailers they carry.
|
|
51
|
+
const partOf = (all, m, root, profile) => !m.bad && !(m.kind && HEARTBEATS.has(m.kind)) && taskFor(all, m, profile) === root;
|
|
52
|
+
// A work item folds over its messages in thread order. Every right is judged on the work as it was before the
|
|
53
|
+
// message, so a label given in a message authorizes nothing in that same message, while its holder may still hand it
|
|
54
|
+
// over and reassign in one reply. Opening sets the initial state and assignees (Assign, else To minus the opener; none
|
|
55
|
+
// for To: *). The first terminal state is final; assignment and labels may still change after it.
|
|
56
|
+
export const taskOf = (all, root, profile) => {
|
|
57
|
+
const t = opening(root, profile, ordered([...all.values()].filter(m => partOf(all, m, root, profile))));
|
|
58
|
+
for (const m of t.msgs.filter(m => m !== root)) {
|
|
59
|
+
const before = { ...t, roles: { ...t.roles }, assignees: [...t.assignees] };
|
|
60
|
+
const fx = STEPS.map(step => step(profile, t, before, m)).filter((x) => !!x);
|
|
61
|
+
if (fx.length)
|
|
62
|
+
t.effects.set(m.id, fx);
|
|
63
|
+
}
|
|
64
|
+
return t;
|
|
65
|
+
};
|
|
66
|
+
export const tasksIn = (all, profile) => [...all.values()].filter(m => m.kind === profile.opens && !m.bad).map(r => taskOf(all, r, profile));
|
|
67
|
+
export const isOpen = (t, profile) => !profile.terminal.includes(t.state);
|
|
68
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// signer: custody of a local key, independent of its storage, transport and object format. The resolver selects a
|
|
2
|
+
// key for a hub/principal; the signer sees exact bytes and an explicit interaction policy, never Git arguments.
|
|
3
|
+
export {};
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
package/target/esm/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// The library: the message protocol, profiles, decisions, signals and the Store port, for programs that coordinate
|
|
2
2
|
// through ringi without its command line (a framework's own runner, another store, another client).
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export *
|
|
6
|
-
export *
|
|
7
|
-
export
|
|
8
|
-
export
|
|
3
|
+
// Importing it wires this machine's defaults (composition/); a program that brings its own adapters calls wire().
|
|
4
|
+
import './composition/index.js';
|
|
5
|
+
export * from './core/hub/protocol/index.js';
|
|
6
|
+
export * from './core/hub/work/index.js';
|
|
7
|
+
export * as decide from './core/hub/decisions/index.js';
|
|
8
|
+
export * as signals from './core/hub/signals/index.js';
|
|
9
|
+
export { openHub, openRoom, createHub, contractAt } from './core/hub/rooms/index.js';
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// fail: a refusal ringi explains (Fail, shown as its message), apart from a bug (any other error, shown with its stack).
|
|
2
|
+
export class Fail extends Error {
|
|
3
|
+
}
|
|
4
|
+
export const fail = (msg) => { throw new Fail(msg); };
|
|
5
|
+
export const errno = (e) => e?.code;
|
|
6
|
+
// A write the host refused: what to do is the same for every host; a tool's own way (its sandbox settings) is added
|
|
7
|
+
// by the interface that knows the tools (cli.ts).
|
|
8
|
+
export class WriteDenied extends Fail {
|
|
9
|
+
where;
|
|
10
|
+
constructor(where, detail) {
|
|
11
|
+
super(`cannot write ${where}: ${detail}
|
|
12
|
+
An agent in a sandbox: re-run this same command with your host's sandbox escalation; the operator approves it.
|
|
13
|
+
The operator can instead add ${where} to the host's writable roots or point RINGI_HOME at a location the host
|
|
14
|
+
already allows.`);
|
|
15
|
+
this.where = where;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=fail.js.map
|
package/target/esm/lib/index.js
CHANGED
|
@@ -1,202 +1,27 @@
|
|
|
1
|
-
// lib: helpers that know nothing of ringi: failing, notes, formatting, strict JSON
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const
|
|
1
|
+
// lib: helpers that know nothing of ringi and touch no host: failing (fail.ts), notes, formatting, strict JSON
|
|
2
|
+
// (json.ts). Files and locks are the adapters' (adapters/fs).
|
|
3
|
+
// Notes and alarms go where the program sends them (composition/: stderr). Those written before it says where wait
|
|
4
|
+
// for it, so none is lost to the order modules load in.
|
|
5
|
+
const notes = [];
|
|
6
|
+
let sink = null;
|
|
7
|
+
export const notesTo = (fn) => {
|
|
8
|
+
sink = fn;
|
|
9
|
+
for (const line of notes.splice(0))
|
|
10
|
+
fn(line);
|
|
11
|
+
};
|
|
12
|
+
export const note = (s) => {
|
|
13
|
+
const line = `ringi: ${s}\n`;
|
|
14
|
+
if (sink)
|
|
15
|
+
sink(line);
|
|
16
|
+
else
|
|
17
|
+
notes.push(line);
|
|
18
|
+
};
|
|
8
19
|
export const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
9
20
|
export const when = (t) => `${new Date(t * 1000).toISOString().slice(0, 16).replace('T', ' ')}Z`;
|
|
10
21
|
export const bytes = (n) => n < 1024 ? `${n} B` : n < 1 << 20 ? `${(n / 1024).toFixed(1)} KB` : `${(n / (1 << 20)).toFixed(1)} MB`;
|
|
11
22
|
export const short = (id) => id.slice(0, 12);
|
|
12
23
|
export const stamp = () => new Date().toISOString().slice(0, 19) + 'Z';
|
|
13
24
|
export const words = (v) => v ? String(v).split(/[\s,]+/).filter(Boolean) : [];
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
export const writeJsonAtomic = (file, v) => {
|
|
17
|
-
const tmp = `${file}.${process.pid}`;
|
|
18
|
-
fs.writeFileSync(tmp, JSON.stringify(v, null, 2));
|
|
19
|
-
fs.renameSync(tmp, file);
|
|
20
|
-
};
|
|
21
|
-
// JSON.parse silently keeps the last of duplicate fields; for contracts and authority that hides a second value.
|
|
22
|
-
// This parser validates the structure first and refuses duplicates.
|
|
23
|
-
export const strictJson = (text, label = 'JSON') => {
|
|
24
|
-
let at = 0;
|
|
25
|
-
const ws = () => { while (at < text.length && /\s/.test(text[at]))
|
|
26
|
-
at++; };
|
|
27
|
-
const bad = () => fail(`${label}: malformed or duplicate JSON field at ${at}`);
|
|
28
|
-
const str = () => {
|
|
29
|
-
const start = at++;
|
|
30
|
-
while (at < text.length && text[at] !== '"')
|
|
31
|
-
at += text[at] === '\\' ? 2 : 1;
|
|
32
|
-
if (text[at++] !== '"')
|
|
33
|
-
bad();
|
|
34
|
-
try {
|
|
35
|
-
return JSON.parse(text.slice(start, at));
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return bad();
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
const value = () => {
|
|
42
|
-
ws();
|
|
43
|
-
const c = text[at];
|
|
44
|
-
if (c === '{') {
|
|
45
|
-
at++;
|
|
46
|
-
ws();
|
|
47
|
-
const keys = new Set();
|
|
48
|
-
if (text[at] === '}') {
|
|
49
|
-
at++;
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
for (;;) {
|
|
53
|
-
ws();
|
|
54
|
-
if (text[at] !== '"')
|
|
55
|
-
bad();
|
|
56
|
-
const k = str();
|
|
57
|
-
if (keys.has(k))
|
|
58
|
-
bad();
|
|
59
|
-
keys.add(k);
|
|
60
|
-
ws();
|
|
61
|
-
if (text[at++] !== ':')
|
|
62
|
-
bad();
|
|
63
|
-
value();
|
|
64
|
-
ws();
|
|
65
|
-
const n = text[at++];
|
|
66
|
-
if (n === '}')
|
|
67
|
-
return;
|
|
68
|
-
if (n !== ',')
|
|
69
|
-
bad();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (c === '[') {
|
|
73
|
-
at++;
|
|
74
|
-
ws();
|
|
75
|
-
if (text[at] === ']') {
|
|
76
|
-
at++;
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
for (;;) {
|
|
80
|
-
value();
|
|
81
|
-
ws();
|
|
82
|
-
const n = text[at++];
|
|
83
|
-
if (n === ']')
|
|
84
|
-
return;
|
|
85
|
-
if (n !== ',')
|
|
86
|
-
bad();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (c === '"') {
|
|
90
|
-
str();
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const m = /^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)/.exec(text.slice(at));
|
|
94
|
-
if (!m)
|
|
95
|
-
bad();
|
|
96
|
-
at += m[0].length;
|
|
97
|
-
};
|
|
98
|
-
value();
|
|
99
|
-
ws();
|
|
100
|
-
if (at !== text.length)
|
|
101
|
-
bad();
|
|
102
|
-
return JSON.parse(text);
|
|
103
|
-
};
|
|
104
|
-
// --- the lock ---
|
|
105
|
-
// A lock is a file holding its owner (pid and a random token), created by hard-linking a file already written: it
|
|
106
|
-
// never exists without its owner and never replaces another lock. All acquisitions and the recovery of a dead
|
|
107
|
-
// owner's lock pass one gate, so two contenders cannot both clear a lock just taken by a third. A lock is taken from
|
|
108
|
-
// someone else only when that owner's process is gone, never by age; an unreadable owner is never taken over; only
|
|
109
|
-
// the owner releases it. A gate abandoned by a dead process needs the operator: recovering the recoverer would need
|
|
110
|
-
// yet another gate.
|
|
111
|
-
const ownerAlive = (pid) => {
|
|
112
|
-
try {
|
|
113
|
-
process.kill(pid, 0);
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
117
|
-
return errno(e) !== 'ESRCH';
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
const ownerOf = (f) => {
|
|
121
|
-
try {
|
|
122
|
-
return fs.readFileSync(f, 'utf8');
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
const deadOwner = (t) => {
|
|
129
|
-
const pid = Number(String(t ?? '').split('.')[0]);
|
|
130
|
-
return Number.isInteger(pid) && pid > 0 && !ownerAlive(pid);
|
|
131
|
-
};
|
|
132
|
-
const claim = (f, token) => {
|
|
133
|
-
const tmp = `${f}.${token}.tmp`;
|
|
134
|
-
fs.writeFileSync(tmp, token, { flag: 'wx', mode: 0o600 });
|
|
135
|
-
try {
|
|
136
|
-
fs.linkSync(tmp, f);
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
catch (e) {
|
|
140
|
-
if (errno(e) === 'EEXIST')
|
|
141
|
-
return false;
|
|
142
|
-
throw e;
|
|
143
|
-
}
|
|
144
|
-
finally {
|
|
145
|
-
fs.rmSync(tmp, { force: true });
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
const release = (f, token) => {
|
|
149
|
-
if (ownerOf(f) === token)
|
|
150
|
-
fs.rmSync(f, { force: true });
|
|
151
|
-
};
|
|
152
|
-
const lockWait = new Int32Array(new SharedArrayBuffer(4));
|
|
153
|
-
export const locked = (file, fn, timeout = 120000) => {
|
|
154
|
-
const token = `${process.pid}.${Math.random().toString(36).slice(2)}`;
|
|
155
|
-
const gate = `${file}.recover`;
|
|
156
|
-
const until = Date.now() + timeout;
|
|
157
|
-
for (;;) {
|
|
158
|
-
if (claim(gate, token)) {
|
|
159
|
-
try {
|
|
160
|
-
if (deadOwner(ownerOf(file)))
|
|
161
|
-
fs.rmSync(file, { force: true });
|
|
162
|
-
if (claim(file, token))
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
release(gate, token);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else if (deadOwner(ownerOf(gate))) {
|
|
170
|
-
fail(`${gate} was abandoned; if no ringi process runs, remove it`);
|
|
171
|
-
}
|
|
172
|
-
if (Date.now() >= until)
|
|
173
|
-
fail(`${file} is held by another process or an unknown owner; if no ringi process runs, remove it`);
|
|
174
|
-
Atomics.wait(lockWait, 0, 0, 25);
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
return fn();
|
|
178
|
-
}
|
|
179
|
-
finally {
|
|
180
|
-
release(file, token);
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
// --- writing where a sandbox may refuse ---
|
|
184
|
-
export const SANDBOX = /Operation not permitted|Permission denied|Read-only file system|EPERM|EACCES|EROFS/;
|
|
185
|
-
export const cannotWrite = (where, detail) => fail(`cannot write ${where}: ${detail}
|
|
186
|
-
An agent in a sandbox: re-run this same command with your host's sandbox escalation; the operator approves it.
|
|
187
|
-
The operator can instead add ${where} to the host's writable roots (Codex: [sandbox_workspace_write] writable_roots
|
|
188
|
-
in ~/.codex/config.toml) or point RINGI_HOME at a location the host already allows.`);
|
|
189
|
-
export const guardWrite = (where, fn) => {
|
|
190
|
-
try {
|
|
191
|
-
return fn();
|
|
192
|
-
}
|
|
193
|
-
catch (e) {
|
|
194
|
-
if (e instanceof Fail)
|
|
195
|
-
throw e;
|
|
196
|
-
if (['EPERM', 'EACCES', 'EROFS'].includes(errno(e) ?? ''))
|
|
197
|
-
cannotWrite(where, `${errno(e)} on ${e.path ?? 'a file'}`);
|
|
198
|
-
throw e;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
export const mkdirIn = (where, d) => { guardWrite(where, () => fs.mkdirSync(d, { recursive: true, mode: 0o700 })); };
|
|
25
|
+
export * from './fail.js';
|
|
26
|
+
export * from './json.js';
|
|
202
27
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// json: JSON read strictly. JSON.parse silently keeps the last of duplicate
|
|
2
|
+
// fields; for contracts and authority that hides a second value, so the structure is checked first and a duplicate
|
|
3
|
+
// field is refused.
|
|
4
|
+
import { fail } from './fail.js';
|
|
5
|
+
const LITERAL = /^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)/;
|
|
6
|
+
// A recursive-descent check of JSON's structure: each kind of value is one small method.
|
|
7
|
+
class Strict {
|
|
8
|
+
at = 0;
|
|
9
|
+
text;
|
|
10
|
+
label;
|
|
11
|
+
constructor(text, label) { this.text = text; this.label = label; }
|
|
12
|
+
bad() { return fail(`${this.label}: malformed or duplicate JSON field at ${this.at}`); }
|
|
13
|
+
ws() { while (this.at < this.text.length && /\s/.test(this.text[this.at]))
|
|
14
|
+
this.at++; }
|
|
15
|
+
peek() { this.ws(); return this.text[this.at]; }
|
|
16
|
+
take(c) { if (this.text[this.at++] !== c)
|
|
17
|
+
this.bad(); }
|
|
18
|
+
str() {
|
|
19
|
+
const start = this.at++;
|
|
20
|
+
while (this.at < this.text.length && this.text[this.at] !== '"')
|
|
21
|
+
this.at += this.text[this.at] === '\\' ? 2 : 1;
|
|
22
|
+
this.take('"');
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(this.text.slice(start, this.at));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return this.bad();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// The character after the next item: a comma, or the closing bracket.
|
|
31
|
+
next() { this.ws(); return this.text[this.at++]; }
|
|
32
|
+
// Items between an opening bracket and `close`, separated by commas.
|
|
33
|
+
items(close, item) {
|
|
34
|
+
this.at++;
|
|
35
|
+
if (this.peek() === close) {
|
|
36
|
+
this.at++;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
do
|
|
40
|
+
item();
|
|
41
|
+
while (this.next() === ',');
|
|
42
|
+
if (this.text[this.at - 1] !== close)
|
|
43
|
+
this.bad();
|
|
44
|
+
}
|
|
45
|
+
object() {
|
|
46
|
+
const keys = new Set();
|
|
47
|
+
this.items('}', () => this.member(keys));
|
|
48
|
+
}
|
|
49
|
+
member(keys) {
|
|
50
|
+
if (this.peek() !== '"')
|
|
51
|
+
this.bad();
|
|
52
|
+
const k = this.str();
|
|
53
|
+
if (keys.has(k))
|
|
54
|
+
this.bad();
|
|
55
|
+
keys.add(k);
|
|
56
|
+
this.ws();
|
|
57
|
+
this.take(':');
|
|
58
|
+
this.value();
|
|
59
|
+
}
|
|
60
|
+
literal() { this.at += (LITERAL.exec(this.text.slice(this.at)) ?? this.bad())[0].length; }
|
|
61
|
+
value() {
|
|
62
|
+
const c = this.peek();
|
|
63
|
+
if (c === '{')
|
|
64
|
+
this.object();
|
|
65
|
+
else if (c === '[')
|
|
66
|
+
this.items(']', () => this.value());
|
|
67
|
+
else if (c === '"')
|
|
68
|
+
this.str();
|
|
69
|
+
else
|
|
70
|
+
this.literal();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export const strictJson = (text, label = 'JSON') => {
|
|
74
|
+
const s = new Strict(text, label);
|
|
75
|
+
s.value();
|
|
76
|
+
s.ws();
|
|
77
|
+
if (s.at !== text.length)
|
|
78
|
+
s.bad();
|
|
79
|
+
return JSON.parse(text);
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import type { Session } from '../runtime/session.ts';
|
|
2
|
-
import type { Actor } from './room.ts';
|
|
3
|
-
export { bound } from '../runtime/session.ts';
|
|
4
|
-
export { watch } from '../runtime/watch.ts';
|
|
5
|
-
export type { WatchOptions } from '../runtime/watch.ts';
|
|
6
|
-
export type InboxOptions = {
|
|
7
|
-
peek?: boolean;
|
|
8
|
-
limit?: number;
|
|
9
|
-
};
|
|
10
|
-
export declare const started: ({ R }: Actor) => {
|
|
11
|
-
quorum: number | null;
|
|
12
|
-
agents: number;
|
|
13
|
-
started: boolean;
|
|
14
|
-
};
|
|
15
|
-
export declare const inbox: ({ R, me }: Actor, { peek, limit }?: InboxOptions) => {
|
|
16
|
-
rest: number;
|
|
17
|
-
cursors: {
|
|
18
|
-
[x: string]: string;
|
|
19
|
-
};
|
|
20
|
-
all: import("../protocol/index.ts").All;
|
|
21
|
-
msgs: {
|
|
22
|
-
id: string;
|
|
23
|
-
from: string;
|
|
24
|
-
trust: 'asserted' | 'verified';
|
|
25
|
-
time: number;
|
|
26
|
-
seq: number;
|
|
27
|
-
invalid: string | null;
|
|
28
|
-
subject: string;
|
|
29
|
-
body: string;
|
|
30
|
-
to: string[];
|
|
31
|
-
re: string | null;
|
|
32
|
-
kind: string | null;
|
|
33
|
-
state: string | null;
|
|
34
|
-
assign: string[] | null;
|
|
35
|
-
roles: Record<string, string> | null;
|
|
36
|
-
hop: number;
|
|
37
|
-
bad: string | null;
|
|
38
|
-
trailers: import("../protocol/index.ts").Trailers;
|
|
39
|
-
refused: import("../protocol/index.ts").Refused[];
|
|
40
|
-
reId: string | null;
|
|
41
|
-
hopEff: number;
|
|
42
|
-
files: import("../protocol/index.ts").FileRef[];
|
|
43
|
-
}[];
|
|
44
|
-
};
|
|
45
|
-
export type Inbox = ReturnType<typeof inbox>;
|
|
46
|
-
export declare const take: ({ R, me }: Actor, ref: string) => {
|
|
47
|
-
m: import("../protocol/index.ts").Message;
|
|
48
|
-
made: boolean;
|
|
49
|
-
};
|
|
50
|
-
export declare const whoami: ({ s, R }: Actor & {
|
|
51
|
-
s?: Session;
|
|
52
|
-
}) => {
|
|
53
|
-
session: Session;
|
|
54
|
-
profile: string;
|
|
55
|
-
members: string[];
|
|
56
|
-
};
|
|
57
|
-
export declare const card: ({ R, me }: Actor, text: string) => string;
|
|
58
|
-
export type PingInput = {
|
|
59
|
-
to: string;
|
|
60
|
-
text?: string;
|
|
61
|
-
next?: number;
|
|
62
|
-
re?: string;
|
|
63
|
-
};
|
|
64
|
-
export declare const ping: ({ R, me }: Actor, { to, text, next, re }: PingInput) => {
|
|
65
|
-
id: string;
|
|
66
|
-
to: string;
|
|
67
|
-
previous: {
|
|
68
|
-
id: string;
|
|
69
|
-
answeredAt: number | null;
|
|
70
|
-
} | null;
|
|
71
|
-
};
|
|
72
|
-
export declare const wait: (a: Actor, { max, ...options }?: InboxOptions & {
|
|
73
|
-
max?: number;
|
|
74
|
-
}) => Promise<{
|
|
75
|
-
inbox: {
|
|
76
|
-
rest: number;
|
|
77
|
-
cursors: {
|
|
78
|
-
[x: string]: string;
|
|
79
|
-
};
|
|
80
|
-
all: import("../protocol/index.ts").All;
|
|
81
|
-
msgs: {
|
|
82
|
-
id: string;
|
|
83
|
-
from: string;
|
|
84
|
-
trust: 'asserted' | 'verified';
|
|
85
|
-
time: number;
|
|
86
|
-
seq: number;
|
|
87
|
-
invalid: string | null;
|
|
88
|
-
subject: string;
|
|
89
|
-
body: string;
|
|
90
|
-
to: string[];
|
|
91
|
-
re: string | null;
|
|
92
|
-
kind: string | null;
|
|
93
|
-
state: string | null;
|
|
94
|
-
assign: string[] | null;
|
|
95
|
-
roles: Record<string, string> | null;
|
|
96
|
-
hop: number;
|
|
97
|
-
bad: string | null;
|
|
98
|
-
trailers: import("../protocol/index.ts").Trailers;
|
|
99
|
-
refused: import("../protocol/index.ts").Refused[];
|
|
100
|
-
reId: string | null;
|
|
101
|
-
hopEff: number;
|
|
102
|
-
files: import("../protocol/index.ts").FileRef[];
|
|
103
|
-
}[];
|
|
104
|
-
};
|
|
105
|
-
seconds: number;
|
|
106
|
-
} | {
|
|
107
|
-
inbox: null;
|
|
108
|
-
seconds: number;
|
|
109
|
-
}>;
|