sessionpipe 0.7.0 → 0.10.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.
Files changed (47) hide show
  1. package/README.md +83 -6
  2. package/dist/cli.d.ts +11 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +5043 -2609
  5. package/dist/cli.js.map +4 -4
  6. package/dist/connect.d.ts.map +1 -1
  7. package/dist/control/aliases.d.ts +5 -0
  8. package/dist/control/aliases.d.ts.map +1 -1
  9. package/dist/control/autoupdate.d.ts +1 -18
  10. package/dist/control/autoupdate.d.ts.map +1 -1
  11. package/dist/control/cli.d.ts +8 -1
  12. package/dist/control/cli.d.ts.map +1 -1
  13. package/dist/control/daemon.d.ts +95 -9
  14. package/dist/control/daemon.d.ts.map +1 -1
  15. package/dist/control/files.d.ts +35 -0
  16. package/dist/control/files.d.ts.map +1 -0
  17. package/dist/control/pair.d.ts +22 -23
  18. package/dist/control/pair.d.ts.map +1 -1
  19. package/dist/control/route.d.ts +1 -1
  20. package/dist/control/route.d.ts.map +1 -1
  21. package/dist/control/sdk.d.ts.map +1 -1
  22. package/dist/control/store.d.ts +21 -2
  23. package/dist/control/store.d.ts.map +1 -1
  24. package/dist/control/stream.d.ts.map +1 -1
  25. package/dist/help.d.ts +3 -0
  26. package/dist/help.d.ts.map +1 -0
  27. package/dist/hook.d.ts +9 -1
  28. package/dist/hook.d.ts.map +1 -1
  29. package/dist/hook.js +190 -158
  30. package/dist/hook.js.map +3 -3
  31. package/dist/http-sink.d.ts +3 -0
  32. package/dist/http-sink.d.ts.map +1 -1
  33. package/dist/index.js +1038 -237
  34. package/dist/index.js.map +4 -4
  35. package/dist/launcher.d.ts.map +1 -1
  36. package/dist/run.d.ts +70 -8
  37. package/dist/run.d.ts.map +1 -1
  38. package/dist/runtime.d.ts +5 -1
  39. package/dist/runtime.d.ts.map +1 -1
  40. package/dist/secrets.d.ts.map +1 -1
  41. package/dist/update.d.ts +1 -6
  42. package/dist/update.d.ts.map +1 -1
  43. package/dist/worker.d.ts +3 -1
  44. package/dist/worker.d.ts.map +1 -1
  45. package/dist/worker.js +1127 -287
  46. package/dist/worker.js.map +4 -4
  47. package/package.json +5 -4
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # sessionpipe
2
2
 
3
3
  **An open protocol, and a client, for what your coding agents are doing.** One
4
- install hooks Claude Code, Codex, Gemini CLI and Antigravity (Cursor, Copilot CLI,
5
- Droid, Kiro and OpenCode are next); every event is filtered to a privacy tier you
4
+ install hooks Claude Code, Codex, Gemini CLI, Antigravity and Devin (Cursor, Copilot
5
+ CLI, Droid, Kiro and OpenCode are next); every event is filtered to a privacy tier you
6
6
  choose per destination; secrets are removed on your machine before anything leaves
7
7
  it; it goes to your server, to a file, or nowhere at all.
8
8
 
@@ -14,6 +14,19 @@ sessionpipe doctor # what is wired, hook timing, sink state
14
14
  sessionpipe uninstall # every config file byte-identical again
15
15
  ```
16
16
 
17
+ `connect` and `install` refuse to replace a newer global package or hook launcher
18
+ with an older build, including a newer prerelease (`0.9.0-devin.1` is newer than
19
+ `0.7.0`). The refusal prints both versions and exits before installing or writing
20
+ hooks. Use the installed newer CLI, or explicitly pass `--allow-downgrade` to
21
+ replace it. Already-published older CLIs do not gain this guard retroactively.
22
+
23
+ `--machine NAME` sets the initial name. On later runs, setup keeps the configured
24
+ name and says when it ignores a different `--machine`, so a copied setup command
25
+ cannot separate sessions from their daemon or reset the identity used for backoff.
26
+ `--machine NAME --rename-machine` explicitly renames it, the paired daemon included:
27
+ control.json takes the name and the daemon says it in its next hello. A receiver keys
28
+ machines by their id, so the pairing holds and its two cards become one.
29
+
17
30
  | Tier | What leaves |
18
31
  |-----:|-------------|
19
32
  | 0 | session state and timing, folder, repo, branch, model, title, the *kind* of attention needed |
@@ -23,7 +36,7 @@ sessionpipe uninstall # every config file byte-identical again
23
36
 
24
37
  No telemetry. Secrets never leave (`secrets@1` runs above tier 0, always). Your
25
38
  server or none. Pre-release: the reference receiver is still being built; see the
26
- [roadmap](https://github.com/micmmakarov/sessionpipe/blob/main/ROADMAP.md).
39
+ [roadmap](https://github.com/spacesheep-dev/sessionpipe/blob/main/ROADMAP.md).
27
40
 
28
41
  ## Control: messages to your sessions (M6: Claude Code, Codex, Antigravity)
29
42
 
@@ -34,6 +47,8 @@ enroll at this terminal; the receiver can queue a message but can never forge on
34
47
 
35
48
  ```sh
36
49
  sessionpipe control pair spacesheep.dev # one link: approve with your passkey; installs the daemon (this folder by default)
50
+ sessionpipe control folders add ~/work/api # let messages reach sessions in another folder too (no new pairing)
51
+ sessionpipe control folders [remove <dir>] # the list, or stop allowing a folder
37
52
  sessionpipe control status # receivers, parked waiters, sessions mid-turn, open permission prompts
38
53
  sessionpipe control keys [remove <id>]
39
54
  sessionpipe control off # tell the receiver, forget its token and keys
@@ -49,6 +64,12 @@ After upgrading, run `sessionpipe control pair <receiver>` again (without
49
64
  already-running daemon afterward with `systemctl --user restart sessionpipe-control.service`;
50
65
  macOS pairing reloads the LaunchAgent.
51
66
 
67
+ A new session started from the receiver may bring files (screenshots, PDFs: up to 10,
68
+ 50 MiB together), whichever harness it is for. The daemon downloads each one, checks
69
+ it against the hash you signed, saves it under `<folder>/.sessionpipe/files/<session>/`
70
+ (a folder that git-ignores itself) and tells the session where they are. If any file
71
+ is missing or doesn't match, the session doesn't start.
72
+
52
73
  One daemon per computer holds one long-poll per receiver and delivers each message the
53
74
  cheapest way the session allows: to `sessionpipe wait` parked in the session's
54
75
  background (in place, ~60 ms, no network), at the session's next Stop if it is
@@ -62,11 +83,22 @@ background command with the longest timeout it can (Claude Code: raise
62
83
  sessionpipe wait # Claude Code: the session id comes from CLAUDE_CODE_SESSION_ID
63
84
  ```
64
85
 
86
+ The waiter and next-Stop modes work in any Claude Code session that runs your hooks,
87
+ the Claude desktop app's included, and need nothing else. The Agent SDK, resume and fork
88
+ modes run the `claude` command, which has its own login (`claude auth login`); the
89
+ desktop app doesn't share its login with that command.
90
+
65
91
  Permission prompts can be answered from the receiver too: while the terminal shows
66
92
  its prompt, the PermissionRequest hook waits for your signed answer, and whichever
67
93
  comes first wins. Nothing is ever auto-allowed. Safe mode (the default) runs headless
68
94
  turns with `--permission-mode dontAsk`, so nothing that needs approval runs while
69
- you're away.
95
+ you're away. Auto mode runs them with `--permission-mode auto`; where Claude Code's
96
+ settings turn auto mode off (`permissions.disableAutoMode`), Claude Code runs them in
97
+ its default mode instead, which refuses whatever needs approval. Inherit mode
98
+ (`sessionpipe control mode inherit`, chosen only at the machine) passes no permission
99
+ flag, so each turn starts in the mode Claude Code picks by itself there, its
100
+ settings' `permissions.defaultMode`: messaged sessions run the way your own do,
101
+ `bypassPermissions` included if that is what you set.
70
102
 
71
103
  Codex and Antigravity sessions are reached headlessly too, when `codex` or `agy` is
72
104
  installed (the daemon looks on PATH, beside its own Node, in `~/.local/bin`, or where
@@ -75,7 +107,9 @@ installed (the daemon looks on PATH, beside its own Node, in `~/.local/bin`, or
75
107
  message is `codex exec resume <thread>` or `agy --conversation <id>`. Safe mode runs
76
108
  Codex in its `workspace-write` sandbox and agy with no permission flag (it denies, and
77
109
  the reply lists, what it wasn't allowed to do); auto mode passes `--approve-for-me` /
78
- `--mode accept-edits`. The bypass flags are never passed. Both CLIs pick a new
110
+ `--mode accept-edits`; inherit mode passes no flag, so Codex follows the
111
+ `approval_policy` and `sandbox_mode` in your `config.toml`. The bypass flags are never
112
+ passed. Both CLIs pick a new
79
113
  session's id themselves, so the daemon keeps the one your start named: it records the
80
114
  pair in `~/.local/state/sessionpipe/control/aliases.json`, and your receiver keeps
81
115
  seeing one session under one id. A message to a Codex session someone has open (its
@@ -83,6 +117,21 @@ rollout written in the last 90 seconds) is acked `unsupported` rather than resum
83
117
  Before a Codex run the daemon checks `codex login status` (or `CODEX_API_KEY`) and says
84
118
  `codex login --device-auth` if it isn't signed in.
85
119
 
120
+ Any other agent that speaks the [Agent Client Protocol](https://agentclientprotocol.com)
121
+ is reached the same way: Gemini CLI, OpenCode, goose, Copilot CLI, Cursor, Droid, Devin,
122
+ Kilo, Qwen Code, Cline and the rest of the ACP registry ([the list, with each one's
123
+ launch line](../../spec/ADAPTERS.md#agents-driven-through-acp-control-only)). The daemon
124
+ runs the agent's own CLI (`gemini --acp`, `opencode acp`, …) when it is installed, on
125
+ PATH or where `SESSIONPIPE_ACP_<HARNESS>` points (`SESSIONPIPE_ACP_GEMINI_CLI`), and
126
+ never downloads one. It is the agent's client: a start opens a session in your folder,
127
+ the reply streams back as the agent writes it, and the process stays up so the next
128
+ message lands in it with no cold start (`api` mode); `cancel` works there too. An agent
129
+ idle for ten minutes is closed, and a later message reopens the session where the agent
130
+ supports `session/load`. Safe mode answers every permission the agent asks with a
131
+ refusal, listed in the reply; auto mode allows. An agent that never asks (OpenCode, by
132
+ its own settings) runs its tools as it would at your terminal. Signing in is yours to do
133
+ at the terminal: an agent that wants it says so in the reply.
134
+
86
135
  ## Updates
87
136
 
88
137
  The control daemon keeps its own copy current. About a minute after it starts, and then
@@ -127,6 +176,34 @@ sessionpipe update # install the latest now; the daemon restarts onto i
127
176
  a launchd or systemd service doesn't inherit your shell's variables, while
128
177
  `sessionpipe update off` reaches it (it re-reads the config every ten minutes).
129
178
 
179
+ ## Help and status JSON
180
+
181
+ `sessionpipe <command> --help` (or `-h`) prints usage and exits successfully before
182
+ running the command. This also works after operands and for nested commands, such
183
+ as `sessionpipe sink remove example --help` and `sessionpipe control pair example --help`.
184
+
185
+ `sessionpipe status --json` prints one JSON object. Its shared fields use the same
186
+ names and meanings as `doctor --json`:
187
+
188
+ | Field | Shape / meaning |
189
+ |---|---|
190
+ | `version`, `machine`, `state`, `config` | Strings; state and config are absolute paths. |
191
+ | `harnesses` | Object keyed by harness name; each value is an array of `{file, state, note?}` hook checks. `file` uses `~` for home, as doctor does. Includes detected **or configured** harnesses. |
192
+ | `sinks` | Array of `{name, url, tier, max_tier, pii, control, paused, pending_sessions}`. `tier` is the configured tier; the effective tier is `min(tier, max_tier ?? 3)`. `max_tier` and `paused` are `null` when unset. No token or secret is included. |
193
+ | `timing` | `{n, p50, p95}` from the last 100 local hook timings, in milliseconds; `null` when unavailable. |
194
+ | `update` | Doctor's update summary: `{auto, off, last_check, latest, last_error, pending, updated, failed}`. `auto` is boolean; absent details are `null`. |
195
+ | `jobs` | Number of entries waiting in the local jobs directory; zero when absent. |
196
+
197
+ `pending_sessions` counts outbox session files with bytes beyond that sink's cursor,
198
+ including paused sinks; it counts files, not individual events. Empty collections
199
+ are `{}` / `[]`. Status omits doctor's active hook benchmark, login/keychain checks,
200
+ and warnings. Both commands still check hook installation, which can run
201
+ `gemini --version` (up to four seconds) when `tools.enableHooks` is unset. JSON is an
202
+ output format, not a promise of constant-time diagnostics. Plain `sessionpipe status`
203
+ keeps its existing human output.
204
+
205
+ ---
206
+
130
207
  Docs and the protocol: [sessionpipe.org](https://sessionpipe.org) · Source:
131
- [github.com/micmmakarov/sessionpipe](https://github.com/micmmakarov/sessionpipe) · Apache-2.0.
208
+ [github.com/spacesheep-dev/sessionpipe](https://github.com/spacesheep-dev/sessionpipe) · Apache-2.0.
132
209
  Provided as-is; check what a sink receives with `sessionpipe tail` before you point it anywhere.
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,13 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export interface Io {
3
+ /** One line of output. */
4
+ out: (s?: string) => void;
5
+ /** What a failed command says, then `exit(1)`. */
6
+ err: (s: string) => void;
7
+ exit: (code: number) => void;
8
+ }
9
+ /** Run one command: `argv` is what follows `sessionpipe`; `io` is this process by default. */
10
+ export declare function main(argv: string[], io?: Io): Promise<void>;
11
+ /** Is this file the process entrypoint? By real path: npm's bin link to it counts. */
12
+ export declare function isEntrypoint(argv1: string | undefined, url: string): boolean;
3
13
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAoEA,MAAM,WAAW,EAAE;IACjB,0BAA0B;IAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1B,kDAAkD;IAClD,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,8FAA8F;AAC9F,wBAAsB,IAAI,CACxB,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,GAAE,EAA2F,GAC9F,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAM5E"}