@pi-in-go/pigpen-ahp 0.1.1 → 0.4.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 (53) hide show
  1. package/CREDITS.md +5 -0
  2. package/README.md +42 -7
  3. package/extensions/ahp/extension.go +27 -3
  4. package/extensions/ahp/go.mod +1 -1
  5. package/extensions/ahp/go.sum +2 -2
  6. package/extensions/ahp/internal/changeset/changeset_test.go +714 -0
  7. package/extensions/ahp/internal/changeset/differential_test.go +179 -0
  8. package/extensions/ahp/internal/changeset/git.go +835 -0
  9. package/extensions/ahp/internal/changeset/git_test.go +333 -0
  10. package/extensions/ahp/internal/changeset/git_unix.go +19 -0
  11. package/extensions/ahp/internal/changeset/git_windows.go +13 -0
  12. package/extensions/ahp/internal/changeset/lifecycle_test.go +403 -0
  13. package/extensions/ahp/internal/changeset/perf_test.go +58 -0
  14. package/extensions/ahp/internal/changeset/service.go +953 -0
  15. package/extensions/ahp/internal/changeset/uri.go +135 -0
  16. package/extensions/ahp/internal/changeset/uri_test.go +76 -0
  17. package/extensions/ahp/internal/changeset/watch.go +142 -0
  18. package/extensions/ahp/internal/changeset/watch_test.go +130 -0
  19. package/extensions/ahp/internal/compose/compose.go +191 -2
  20. package/extensions/ahp/internal/gaps/gaps_test.go +0 -47
  21. package/extensions/ahp/internal/host/store.go +3 -0
  22. package/extensions/ahp/internal/live/live.go +1 -1
  23. package/extensions/ahp/internal/live/live_test.go +6 -1
  24. package/extensions/ahp/internal/pi/lifecycle_test.go +12 -0
  25. package/extensions/ahp/internal/pi/refusal.go +15 -0
  26. package/extensions/ahp/internal/pi/refusal_test.go +15 -0
  27. package/extensions/ahp/internal/pi/registry.go +4 -5
  28. package/extensions/ahp/internal/svc/mime.go +30 -23
  29. package/extensions/ahp/internal/svc/mime_test.go +51 -0
  30. package/extensions/ahp/internal/svc/mimetable.go +1249 -0
  31. package/extensions/ahp/internal/svc/resource.go +4 -0
  32. package/extensions/ahp/internal/tunnel/devtunnel.go +417 -0
  33. package/extensions/ahp/internal/tunnel/discovery.go +58 -0
  34. package/extensions/ahp/internal/tunnel/signal_unix.go +20 -0
  35. package/extensions/ahp/internal/tunnel/signal_windows.go +8 -0
  36. package/extensions/ahp/internal/tunnel/tunnel_test.go +586 -0
  37. package/extensions/ahp/realpig_test.go +108 -1
  38. package/extensions/ahp/runtime.go +46 -8
  39. package/extensions/ahp/runtime_test.go +11 -0
  40. package/extensions/ahp/tunnelhost.go +286 -0
  41. package/extensions/ahp/tunnelhost_test.go +330 -0
  42. package/extensions/ahp/tunnelsignal_unix.go +10 -0
  43. package/extensions/ahp/tunnelsignal_windows.go +8 -0
  44. package/package.json +1 -1
  45. package/proof/PORT.md +50 -9
  46. package/proof/differential/oracle-run.mjs +97 -0
  47. package/proof/differential/run.sh +18 -0
  48. package/proof/mutations.json +486 -0
  49. package/proof/perf/coldstart.sh +37 -0
  50. package/proof/perf/compute.mjs +24 -0
  51. package/proof/perf/mkrepo.sh +27 -0
  52. package/proof/perf/run.sh +11 -0
  53. package/proof/tools/gen-mime.mjs +25 -0
package/CREDITS.md CHANGED
@@ -21,6 +21,11 @@ with the Microsoft license. The five protocol JSON schemas used by the tests are
21
21
  same commit into `extensions/ahp/internal/testkit/schema`, and the recorded Pi event streams in
22
22
  `extensions/ahp/internal/mapper/testdata/fixtures` come from pi-ahp's test fixtures.
23
23
 
24
+ The file-extension to content-type table in `extensions/ahp/internal/svc/mimetable.go` is generated by
25
+ `proof/tools/gen-mime.mjs` from the **mime** package 4.1.1 by Robert Kieffer (https://github.com/broofa/mime, MIT,
26
+ Copyright (c) 2010 Benjamin Thomas, Robert Kieffer), whose data is **mime-db** (https://github.com/jshttp/mime-db, MIT,
27
+ Copyright (c) 2014 Jonathan Ong, Copyright (c) 2015-2022 Douglas Christopher Wilson). Only the data is used; no code of either is copied.
28
+
24
29
  The Go code, the scenarios and the tests were written for this Package by Michael Kinsy. The
25
30
  behavior, wording and structure of the host follow the original. Modified paths: none of the
26
31
  originals is modified; the port is a separate implementation, and its deviations are listed in
package/README.md CHANGED
@@ -36,7 +36,7 @@ for every deviation and gap.
36
36
 
37
37
  With `filesystem.enabled` and no `roots`, access is confined to the session's working directory;
38
38
  `unrestricted: true` must be said explicitly. A terminal is a shell as you, claimed by the client
39
- that started it. The dev tunnel of pi-ahp is not bundled.
39
+ that started it. A dev tunnel is a separate way to open the listener, with no token (see Dev tunnel).
40
40
 
41
41
  **What a connected client can always do.** The opt-ins above cover the host's own filesystem,
42
42
  watch, terminal and deletion services. They do not limit the agent. Anyone who holds the token
@@ -49,9 +49,40 @@ can do all of the following, so treat the token like a shell login:
49
49
  - List and read the stored history of **every** PiG session under the session directory, from all
50
50
  projects, not only the running one.
51
51
  - Get `@` completions, which list file names under the working directory.
52
+ - Read the git changesets of the working directory (the diff of the last commit and the uncommitted work, with the content of the changed
53
+ files from git) through `git-blob:` references. These are served without the filesystem opt-in because they are read-only and confined to
54
+ the working directory's subtree; with `filesystem.enabled` the filesystem roots limit them too.
52
55
 
53
56
  The token is shown in the `/ahp` status and in the "listening" notice.
54
57
 
58
+ ## Git changesets
59
+
60
+ Like pi-ahp, the host runs the `git` command line (it must be on `PATH`; without it, or outside a work tree, no changesets are advertised)
61
+ to compute two changesets per session: **Latest Commit** (HEAD against its parent, or the root commit) and **Uncommitted Changes**
62
+ (tracked changes against HEAD plus untracked files that git does not ignore). Nothing in the repository or its index is modified:
63
+ git runs with `GIT_OPTIONAL_LOCKS=0`, the ambient `GIT_DIR`/`GIT_INDEX_FILE`/`GIT_WORK_TREE`-style overrides are removed, and each
64
+ call is limited to 30 seconds and 32 MiB of output. A changeset is computed when a client subscribes, again after every turn, and
65
+ while it stays subscribed whenever the working directory, the git index, HEAD, the refs or the ignore rules change (the watcher
66
+ polls once a second and does not descend into ignored directories). Unsubscribed changesets are dropped after 30 seconds.
67
+
68
+ ## Dev tunnel
69
+
70
+ `/ahp tunnel [name]` is the counterpart of pi-ahp's `pi-ahp-tunnel [--name <label>]`. It needs Microsoft's `devtunnel` CLI on `PATH`
71
+ (https://aka.ms/devtunnels/download), which is not bundled, and a login (`devtunnel user login -g` for GitHub, or
72
+ `devtunnel user login`; add `-d` without a browser). It then runs the same `devtunnel` commands pi-ahp does: `user show`, `list`
73
+ for this host's tunnel (labels `_pi_ahp` and `vscode-server-launcher`), `create` when there is none (labels `vscode-server-launcher`,
74
+ `protocolv5`, `_pi_ahp` and the display name), `update` to rename it, and `port list`, `port show`, `port create` or `port delete` to
75
+ make port 31546 forward HTTP, refusing to replace a port that has its own access control. `name` is folded the way VS Code folds a
76
+ tunnel name (letters, digits, `_` and `-`, at most 20 characters); `--name <label>` is accepted too.
77
+
78
+ Then the session is served on `127.0.0.1:31546` **without a token** (the dev tunnel's account is the access control, as in pi-ahp)
79
+ and `devtunnel host <tunnel id>` runs as a child process that forwards it; its output is shown as notices. Because that listener has no
80
+ token, any process on this machine can connect to it: use it on a machine you trust, and know that the opt-ins of the settings file
81
+ (filesystem, terminals, session deletion, allowed origins) still apply to whoever reaches it through the tunnel. The tunnel does not
82
+ read or write the direct listener's `port`, `host` or `token`, and it cannot run while the direct listener does (`/ahp stop`
83
+ first). `/ahp stop`, or the session being replaced or ending, stops `devtunnel host` and then the listener; if `devtunnel host` exits
84
+ on its own the listener is shut down with a notice.
85
+
55
86
  ## Commands and flags
56
87
 
57
88
  | | |
@@ -59,6 +90,7 @@ The token is shown in the `/ahp` status and in the "listening" notice.
59
90
  | `--ahp` | start the listener when the session starts |
60
91
  | `--ahp-settings <file>` | settings file (default `<pig home>/ahp/settings.json`) |
61
92
  | `/ahp [status]` `/ahp start` `/ahp stop` | inspect, start or stop the listener |
93
+ | `/ahp tunnel [name]` | serve the session through a Microsoft dev tunnel (see Dev tunnel); `/ahp stop` ends it |
62
94
 
63
95
  If the PiG session is replaced (new, resume, fork, reload), the listener closes with it and connected
64
96
  clients are dropped. With `--ahp` it opens again for the new session on the same port. After
@@ -96,10 +128,11 @@ Reaching a host on another machine:
96
128
  on the remote. VS Code reads the first `ws://127.0.0.1:<port>?tkn=<token>` in the command's output, which is how the notice
97
129
  starts. The command has to keep pig running without a terminal: `pig --mode rpc --ahp` prints the notice on standard output at
98
130
  once and runs while its input stays open (checked with a plain shell, not yet with VS Code).
99
- - **A dev tunnel** is not bundled (the pi-ahp tunnel feature is not ported), and VS Code's own tunnel support looks for VS Code agent
100
- hosts, not this one. A tunnel you start yourself can forward the port and give a `wss://` address that **Add Remote Agent Host...**
101
- accepts, but VS Code sends no tunnel credentials on that connection, so the tunnel has to admit it anonymously and the token is
102
- the only protection. Not tried.
131
+ - **A dev tunnel**: `/ahp tunnel` (see Dev tunnel) sets up the fixed-port tunnel that Dev Tunnel-capable AHP clients discover, the
132
+ way `pi-ahp-tunnel` does. It has not been tried against VS Code. VS Code's own tunnel support looks for VS Code agent hosts; a
133
+ tunnel you start yourself can instead forward the direct listener's port and give a `wss://` address that **Add Remote Agent
134
+ Host...** accepts, but VS Code sends no tunnel credentials on that connection, so the tunnel has to admit it anonymously and
135
+ the token is the only protection. Not tried.
103
136
 
104
137
  Debugging: set `"chat.agentHost.ahpJsonlLoggingEnabled": true` to have VS Code log every AHP message as JSON lines under the
105
138
  window's log directory (it is off by default in stable builds).
@@ -112,9 +145,11 @@ What to expect, and the limits that apply to this port:
112
145
  [proof/PORT.md](proof/PORT.md), deviation 15). A browser `Origin` that is not allowed also gets 403.
113
146
  - The host serves **the one running session** as one agent (`pi`). Other sessions are readable from their files; they are not
114
147
  running agents. If the session is replaced (new, resume, fork, reload) clients are dropped (see Commands and flags).
115
- - No git changeset channels: VS Code's change views will have nothing to show (the changeset service of pi-ahp is not ported).
148
+ - Git changesets: when the session's working directory is inside a git work tree, the session advertises two changesets, **Latest Commit**
149
+ (once the repository has a commit) and **Uncommitted Changes**, which VS Code's change views show. They are read-only, limited to the
150
+ working directory's subtree, and refreshed while a client has them open (see Git changesets above).
116
151
  - The remote filesystem, watches, terminals and session deletion are off until you opt in (see Safe by default).
117
- - No dev tunnel is bundled, and project trust cannot be gated from an extension (see [proof/PORT.md](proof/PORT.md)).
152
+ - Project trust cannot be gated from an extension (see [proof/PORT.md](proof/PORT.md)).
118
153
 
119
154
  ## Other AHP clients
120
155
 
@@ -28,8 +28,9 @@ func Extension() *sdk.Extension {
28
28
  rt.live.Register(e, rt.onSessionStart, rt.onSessionShutdown)
29
29
  rt.live.OnModelChanged(rt.onModelChanged)
30
30
 
31
- e.Command("ahp", "AHP host: /ahp [status|start|stop]", func(ctx sdk.Context, args string) error {
32
- switch strings.TrimSpace(args) {
31
+ e.Command("ahp", "AHP host: /ahp [status|start|stop|tunnel [name]]", func(ctx sdk.Context, args string) error {
32
+ command, rest, _ := strings.Cut(strings.TrimSpace(args), " ")
33
+ switch command {
33
34
  case "", "status":
34
35
  ctx.Notify(rt.status(), "info")
35
36
  case "start":
@@ -45,10 +46,33 @@ func Extension() *sdk.Extension {
45
46
  } else {
46
47
  ctx.Notify("AHP listener is not running", "info")
47
48
  }
49
+ case "tunnel":
50
+ name, err := tunnelName(strings.TrimSpace(rest))
51
+ if err != nil {
52
+ return err
53
+ }
54
+ if err := rt.startTunnel(ctx, name); err != nil {
55
+ ctx.Notify("AHP: "+err.Error(), "error")
56
+ return nil
57
+ }
58
+ ctx.Notify("AHP: setting up the dev tunnel (needs `devtunnel` on PATH and a login)", "info")
48
59
  default:
49
- return fmt.Errorf("usage: /ahp [status|start|stop]")
60
+ return fmt.Errorf("usage: /ahp [status|start|stop|tunnel [name]]")
50
61
  }
51
62
  return nil
52
63
  })
53
64
  return e
54
65
  }
66
+
67
+ // tunnelName is the display name given to /ahp tunnel: the rest of the line, optionally as
68
+ // `--name <label>` as pi-ahp-tunnel takes it.
69
+ func tunnelName(rest string) (string, error) {
70
+ if name, ok := strings.CutPrefix(rest, "--name"); ok {
71
+ name = strings.TrimSpace(name)
72
+ if name == "" {
73
+ return "", fmt.Errorf("usage: /ahp tunnel [--name <label>]")
74
+ }
75
+ return name, nil
76
+ }
77
+ return rest, nil
78
+ }
@@ -3,7 +3,7 @@ module github.com/MichaelKinsy/pigpen/ahp
3
3
  go 1.26
4
4
 
5
5
  // PiG resolves this requirement to the version-matched staged SDK at build time.
6
- require github.com/MichaelKinsy/PiG/extensions/sdk v0.4.1
6
+ require github.com/MichaelKinsy/PiG/extensions/sdk v0.5.3
7
7
 
8
8
  // The Microsoft Agent Host Protocol Go types and reducers (MIT), vendored byte for byte.
9
9
  // See third_party/agent-host-protocol-go/NOTICE-PIGPEN.md.
@@ -1,2 +1,2 @@
1
- github.com/MichaelKinsy/PiG/extensions/sdk v0.4.1/go.mod h1:4j0XhCW0EPOBWvqYE7XKjTvIAahI7K1VyyW3KpjTKj8=
2
- github.com/MichaelKinsy/PiG/extensions/sdk v0.4.1 h1:Ql9sTkc6dvAXaYQLq5nxqmSZgqu8S0L53ZTs8MkOuxw=
1
+ github.com/MichaelKinsy/PiG/extensions/sdk v0.5.3 h1:mgLZchfHrmjoyuKNzP5rpn/D/6hx6ZFoDfwHsqcU8Yo=
2
+ github.com/MichaelKinsy/PiG/extensions/sdk v0.5.3/go.mod h1:4j0XhCW0EPOBWvqYE7XKjTvIAahI7K1VyyW3KpjTKj8=