pipane 0.1.6 → 0.1.8

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 (58) hide show
  1. package/README.md +14 -3
  2. package/bin/pipane-rendezvous.js +21 -0
  3. package/bin/pipane.js +21 -1
  4. package/dist/build-info.json +5 -0
  5. package/dist/client/assets/__vite-browser-external-DtLbhLGx.js +1 -0
  6. package/dist/client/assets/app-runtime-Rw-O-AwW.js +1 -0
  7. package/dist/client/assets/backend-landing-page-B7SbyIXQ.js +1 -0
  8. package/dist/client/assets/index-C7_1ODks.js +2 -0
  9. package/dist/client/assets/index-DgI_gkjg.css +1 -0
  10. package/dist/client/assets/main-DEfSB8wO.js +2822 -0
  11. package/dist/client/assets/pairing-page-C0YByC2D.js +1 -0
  12. package/dist/client/assets/remote-backend-manager-DCSdS38m.js +1 -0
  13. package/dist/client/assets/rendezvous-trust-api-C2Zob5i4.js +4 -0
  14. package/dist/client/assets/webrtc-frame-transport-DGX5EO_A.js +1 -0
  15. package/dist/client/assets/ws-agent-adapter-DpkkZGPl.js +6 -0
  16. package/dist/client/index.html +2 -2
  17. package/dist/server/rendezvous/rendezvous-hub.js +426 -0
  18. package/dist/server/rendezvous/server.js +247 -0
  19. package/dist/server/rendezvous/trust-store.js +432 -0
  20. package/dist/server/server/auth-guard.js +61 -0
  21. package/dist/server/server/backend-connection-authorizer.js +29 -0
  22. package/dist/server/server/backend-identity.js +167 -0
  23. package/dist/server/server/backend-protocol-handler.js +132 -0
  24. package/dist/server/server/backend-trust-store.js +157 -0
  25. package/dist/server/server/backend-webrtc.js +245 -0
  26. package/dist/server/server/build-info.js +13 -0
  27. package/dist/server/server/conversation-file-access.js +97 -0
  28. package/dist/server/server/frame-connection.js +106 -0
  29. package/dist/server/server/frame-router.js +45 -0
  30. package/dist/server/server/ice-servers.js +24 -0
  31. package/dist/server/server/local-backend-api.js +389 -0
  32. package/dist/server/server/local-settings.js +17 -4
  33. package/dist/server/server/pi-rpc-protocol.js +407 -0
  34. package/dist/server/server/process-pool.js +27 -24
  35. package/dist/server/server/rendezvous-client.js +282 -0
  36. package/dist/server/server/rest-api.js +133 -176
  37. package/dist/server/server/server.js +167 -97
  38. package/dist/server/server/session-index.js +105 -28
  39. package/dist/server/server/session-jsonl.js +82 -5
  40. package/dist/server/server/session-path.js +145 -0
  41. package/dist/server/server/update-api.js +28 -0
  42. package/dist/server/server/update-check.js +33 -13
  43. package/dist/server/server/update-manager.js +233 -0
  44. package/dist/server/server/worktree-name.js +116 -31
  45. package/dist/server/server/ws-handler.js +267 -186
  46. package/dist/server/shared/backend-api.js +1 -0
  47. package/dist/server/shared/backend-protocol.js +164 -0
  48. package/dist/server/shared/data-channel-framing.js +137 -0
  49. package/dist/server/shared/node-trust-crypto.js +61 -0
  50. package/dist/server/shared/rendezvous-protocol.js +243 -0
  51. package/dist/server/shared/tool-runtime.js +1 -0
  52. package/dist/server/shared/trust-protocol.js +97 -0
  53. package/dist/server/shared/updates.js +4 -0
  54. package/dist/server/shared/ws-protocol.js +473 -1
  55. package/docs/protocol.md +129 -0
  56. package/package.json +21 -8
  57. package/dist/client/assets/index-Dl_wdLZH.css +0 -1
  58. package/dist/client/assets/index-hNqbnG06.js +0 -2482
@@ -1,39 +1,124 @@
1
- import { existsSync, readFileSync, statSync } from "node:fs";
1
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  /**
4
- * Return a short label for the Git checkout containing cwd.
5
- *
6
- * A linked worktree has a .git file whose target contains a `commondir`
7
- * pointer. Regular checkouts (and non-Git directories) are labelled `root`.
4
+ * Filesystem-only Git checkout lookup. One instance is shared across all
5
+ * sessions in a single listing, then discarded so worktree changes are visible
6
+ * on the next request.
8
7
  */
9
- export function resolveWorktreeName(cwd) {
10
- if (!cwd)
11
- return "root";
12
- let dir = path.resolve(cwd);
13
- while (true) {
14
- const gitPath = path.join(dir, ".git");
15
- if (existsSync(gitPath)) {
16
- try {
17
- const stat = statSync(gitPath);
18
- if (stat.isDirectory())
19
- return "root";
20
- if (!stat.isFile())
21
- return "root";
22
- const marker = readFileSync(gitPath, "utf8").trim();
23
- if (!marker.startsWith("gitdir: "))
24
- return "root";
25
- const gitDir = path.resolve(dir, marker.slice("gitdir: ".length).trim());
26
- if (!existsSync(path.join(gitDir, "commondir")))
27
- return "root";
28
- return path.basename(dir) || "root";
8
+ class GitCheckoutLookup {
9
+ cache = new Map();
10
+ resolve(location) {
11
+ if (!location)
12
+ return null;
13
+ let dir = path.resolve(location);
14
+ const visited = [];
15
+ while (true) {
16
+ if (this.cache.has(dir)) {
17
+ return this.remember(visited, this.cache.get(dir) ?? null);
18
+ }
19
+ visited.push(dir);
20
+ const gitPath = path.join(dir, ".git");
21
+ if (existsSync(gitPath)) {
22
+ return this.remember(visited, this.readCheckout(dir, gitPath));
23
+ }
24
+ const parent = path.dirname(dir);
25
+ if (parent === dir)
26
+ return this.remember(visited, null);
27
+ dir = parent;
28
+ }
29
+ }
30
+ readCheckout(root, gitPath) {
31
+ try {
32
+ const stat = statSync(gitPath);
33
+ if (stat.isDirectory()) {
34
+ return {
35
+ root,
36
+ commonGitDir: canonicalPath(gitPath),
37
+ linked: false,
38
+ };
29
39
  }
30
- catch {
31
- return "root";
40
+ if (!stat.isFile())
41
+ return null;
42
+ const marker = readFileSync(gitPath, "utf8").trim();
43
+ if (!marker.startsWith("gitdir: "))
44
+ return null;
45
+ const gitDir = path.resolve(root, marker.slice("gitdir: ".length).trim());
46
+ if (!existsSync(gitDir))
47
+ return null;
48
+ const commonDirMarker = path.join(gitDir, "commondir");
49
+ if (!existsSync(commonDirMarker)) {
50
+ // A separate Git directory or submodule checkout uses a .git file too,
51
+ // but unlike a linked worktree it has no commondir pointer.
52
+ return {
53
+ root,
54
+ commonGitDir: canonicalPath(gitDir),
55
+ linked: false,
56
+ };
32
57
  }
58
+ const commonDir = path.resolve(gitDir, readFileSync(commonDirMarker, "utf8").trim());
59
+ if (!existsSync(commonDir))
60
+ return null;
61
+ return {
62
+ root,
63
+ commonGitDir: canonicalPath(commonDir),
64
+ linked: true,
65
+ };
33
66
  }
34
- const parent = path.dirname(dir);
35
- if (parent === dir)
36
- return "root";
37
- dir = parent;
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ remember(visited, checkout) {
72
+ for (const location of visited)
73
+ this.cache.set(location, checkout);
74
+ return checkout;
75
+ }
76
+ }
77
+ function canonicalPath(value) {
78
+ try {
79
+ return realpathSync(value);
80
+ }
81
+ catch {
82
+ return path.resolve(value);
38
83
  }
39
84
  }
85
+ function checkoutName(checkout) {
86
+ return checkout?.linked ? path.basename(checkout.root) || "root" : "root";
87
+ }
88
+ /**
89
+ * Create a resolver with a request-scoped filesystem cache. This avoids Git
90
+ * subprocesses and ensures shared cwd/path ancestors are only inspected once
91
+ * while listing many sessions.
92
+ */
93
+ export function createWorktreeNameResolver() {
94
+ const lookup = new GitCheckoutLookup();
95
+ return (cwd, recentToolPaths = []) => {
96
+ const cwdCheckout = lookup.resolve(cwd);
97
+ // Tool paths are stored oldest-to-newest. The newest successful project
98
+ // file operation is stronger evidence than Pi's immutable session cwd.
99
+ for (let i = recentToolPaths.length - 1; i >= 0; i--) {
100
+ const activityCheckout = lookup.resolve(recentToolPaths[i]);
101
+ if (!activityCheckout)
102
+ continue;
103
+ if (!cwdCheckout || activityCheckout.commonGitDir === cwdCheckout.commonGitDir) {
104
+ return checkoutName(activityCheckout);
105
+ }
106
+ }
107
+ // The session cwd says where Pi was launched, not which checkout the
108
+ // conversation is actively using. Until successful same-repository file
109
+ // activity provides evidence, treat the session as root.
110
+ return "root";
111
+ };
112
+ }
113
+ /**
114
+ * Return a short label for the Git checkout a session is actively using.
115
+ *
116
+ * Pi cannot change its process cwd persistently, so the recorded cwd only
117
+ * identifies the repository. Recent successful read/write/edit paths identify
118
+ * its active checkout; without one, the label defaults to root. Linked
119
+ * worktrees are recognized by their commondir pointer. Removed worktrees
120
+ * naturally stop matching because their .git metadata is no longer present.
121
+ */
122
+ export function resolveWorktreeName(cwd, recentToolPaths = []) {
123
+ return createWorktreeNameResolver()(cwd, recentToolPaths);
124
+ }