sessionpipe 0.6.1 → 0.9.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 (44) hide show
  1. package/README.md +74 -5
  2. package/dist/cli.d.ts +11 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +3331 -1371
  5. package/dist/cli.js.map +4 -4
  6. package/dist/connect.d.ts.map +1 -1
  7. package/dist/control/aliases.d.ts +15 -0
  8. package/dist/control/aliases.d.ts.map +1 -0
  9. package/dist/control/autoupdate.d.ts.map +1 -1
  10. package/dist/control/cli.d.ts +8 -1
  11. package/dist/control/cli.d.ts.map +1 -1
  12. package/dist/control/daemon.d.ts +65 -10
  13. package/dist/control/daemon.d.ts.map +1 -1
  14. package/dist/control/files.d.ts +33 -0
  15. package/dist/control/files.d.ts.map +1 -0
  16. package/dist/control/pair.d.ts +9 -0
  17. package/dist/control/pair.d.ts.map +1 -1
  18. package/dist/control/route.d.ts +5 -2
  19. package/dist/control/route.d.ts.map +1 -1
  20. package/dist/control/store.d.ts.map +1 -1
  21. package/dist/control/stream.d.ts.map +1 -1
  22. package/dist/help.d.ts +3 -0
  23. package/dist/help.d.ts.map +1 -0
  24. package/dist/hook.d.ts +9 -1
  25. package/dist/hook.d.ts.map +1 -1
  26. package/dist/hook.js +184 -158
  27. package/dist/hook.js.map +3 -3
  28. package/dist/http-sink.d.ts +3 -0
  29. package/dist/http-sink.d.ts.map +1 -1
  30. package/dist/index.js +943 -220
  31. package/dist/index.js.map +4 -4
  32. package/dist/launcher.d.ts.map +1 -1
  33. package/dist/run.d.ts +70 -8
  34. package/dist/run.d.ts.map +1 -1
  35. package/dist/runtime.d.ts +5 -1
  36. package/dist/runtime.d.ts.map +1 -1
  37. package/dist/secrets.d.ts.map +1 -1
  38. package/dist/update.d.ts +3 -2
  39. package/dist/update.d.ts.map +1 -1
  40. package/dist/worker.d.ts +3 -1
  41. package/dist/worker.d.ts.map +1 -1
  42. package/dist/worker.js +1021 -259
  43. package/dist/worker.js.map +4 -4
  44. 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,9 +36,9 @@ 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
- ## Control: messages to your sessions (M6, Claude Code first)
41
+ ## Control: messages to your sessions (M6: Claude Code, Codex, Antigravity)
29
42
 
30
43
  A receiver that lists `control` can carry a message from your phone to a session on
31
44
  this machine. It is signed on your device and **checked here**, against a key you
@@ -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,12 +83,32 @@ 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
95
  you're away.
70
96
 
97
+ Codex and Antigravity sessions are reached headlessly too, when `codex` or `agy` is
98
+ installed (the daemon looks on PATH, beside its own Node, in `~/.local/bin`, or where
99
+ `SESSIONPIPE_CODEX` / `SESSIONPIPE_AGY` point). A new session is
100
+ `codex exec --json -C <folder>` or `agy -p … --output-format stream-json`; the next
101
+ message is `codex exec resume <thread>` or `agy --conversation <id>`. Safe mode runs
102
+ Codex in its `workspace-write` sandbox and agy with no permission flag (it denies, and
103
+ the reply lists, what it wasn't allowed to do); auto mode passes `--approve-for-me` /
104
+ `--mode accept-edits`. The bypass flags are never passed. Both CLIs pick a new
105
+ session's id themselves, so the daemon keeps the one your start named: it records the
106
+ pair in `~/.local/state/sessionpipe/control/aliases.json`, and your receiver keeps
107
+ seeing one session under one id. A message to a Codex session someone has open (its
108
+ rollout written in the last 90 seconds) is acked `unsupported` rather than resumed beside them.
109
+ Before a Codex run the daemon checks `codex login status` (or `CODEX_API_KEY`) and says
110
+ `codex login --device-auth` if it isn't signed in.
111
+
71
112
  ## Updates
72
113
 
73
114
  The control daemon keeps its own copy current. About a minute after it starts, and then
@@ -112,6 +153,34 @@ sessionpipe update # install the latest now; the daemon restarts onto i
112
153
  a launchd or systemd service doesn't inherit your shell's variables, while
113
154
  `sessionpipe update off` reaches it (it re-reads the config every ten minutes).
114
155
 
156
+ ## Help and status JSON
157
+
158
+ `sessionpipe <command> --help` (or `-h`) prints usage and exits successfully before
159
+ running the command. This also works after operands and for nested commands, such
160
+ as `sessionpipe sink remove example --help` and `sessionpipe control pair example --help`.
161
+
162
+ `sessionpipe status --json` prints one JSON object. Its shared fields use the same
163
+ names and meanings as `doctor --json`:
164
+
165
+ | Field | Shape / meaning |
166
+ |---|---|
167
+ | `version`, `machine`, `state`, `config` | Strings; state and config are absolute paths. |
168
+ | `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. |
169
+ | `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. |
170
+ | `timing` | `{n, p50, p95}` from the last 100 local hook timings, in milliseconds; `null` when unavailable. |
171
+ | `update` | Doctor's update summary: `{auto, off, last_check, latest, last_error, pending, updated, failed}`. `auto` is boolean; absent details are `null`. |
172
+ | `jobs` | Number of entries waiting in the local jobs directory; zero when absent. |
173
+
174
+ `pending_sessions` counts outbox session files with bytes beyond that sink's cursor,
175
+ including paused sinks; it counts files, not individual events. Empty collections
176
+ are `{}` / `[]`. Status omits doctor's active hook benchmark, login/keychain checks,
177
+ and warnings. Both commands still check hook installation, which can run
178
+ `gemini --version` (up to four seconds) when `tools.enableHooks` is unset. JSON is an
179
+ output format, not a promise of constant-time diagnostics. Plain `sessionpipe status`
180
+ keeps its existing human output.
181
+
182
+ ---
183
+
115
184
  Docs and the protocol: [sessionpipe.org](https://sessionpipe.org) · Source:
116
- [github.com/micmmakarov/sessionpipe](https://github.com/micmmakarov/sessionpipe) · Apache-2.0.
185
+ [github.com/spacesheep-dev/sessionpipe](https://github.com/spacesheep-dev/sessionpipe) · Apache-2.0.
117
186
  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"}