@jmfederico/pi-web 1.202607.2 → 1.202608.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 (103) hide show
  1. package/README.md +1 -1
  2. package/dist/client/assets/{CodeViewer-B4M13447.js → CodeViewer-D91Sp61M.js} +1 -1
  3. package/dist/client/assets/{TerminalPanel-Bmvj-Ecn.js → TerminalPanel-fYrKc3jh.js} +2 -2
  4. package/dist/client/assets/{UnifiedDiffViewer-C0hygwRo.js → UnifiedDiffViewer-BafLWGtF.js} +1 -1
  5. package/dist/client/assets/index-CA8q9_o7.js +4025 -0
  6. package/dist/client/index.html +1 -1
  7. package/dist/config.js +39 -0
  8. package/dist/config.js.map +1 -1
  9. package/dist/pi-web-plugins/info/infoInternals.js +208 -0
  10. package/dist/pi-web-plugins/info/pi-web-plugin.js +12 -15
  11. package/dist/pi-web-plugins/relays/markdownDocument.js +81 -0
  12. package/dist/pi-web-plugins/relays/package.json +9 -0
  13. package/dist/pi-web-plugins/relays/pi-web-plugin.js +44 -0
  14. package/dist/pi-web-plugins/relays/relayDiscovery.js +228 -0
  15. package/dist/pi-web-plugins/relays/relaysPanelElement.js +550 -0
  16. package/dist/pi-web-plugins/relays/vendor/README.md +24 -0
  17. package/dist/pi-web-plugins/relays/vendor/marked.esm.js +76 -0
  18. package/dist/plugin-api.d.ts +7 -1
  19. package/dist/server/app.js +0 -22
  20. package/dist/server/app.js.map +1 -1
  21. package/dist/server/browserMessageProjection.js +0 -2
  22. package/dist/server/browserMessageProjection.js.map +1 -1
  23. package/dist/server/configRoutes.js +13 -11
  24. package/dist/server/configRoutes.js.map +1 -1
  25. package/dist/server/machines/machineProxyRoutes.js +2 -13
  26. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  27. package/dist/server/piWebStatus.js +12 -38
  28. package/dist/server/piWebStatus.js.map +1 -1
  29. package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
  30. package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
  31. package/dist/server/sessiond/agentProcessEnvironment.js +62 -0
  32. package/dist/server/sessiond/agentProcessEnvironment.js.map +1 -0
  33. package/dist/server/sessiond/sessionServiceDependencies.js +33 -0
  34. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -0
  35. package/dist/server/sessiond.js +145 -116
  36. package/dist/server/sessiond.js.map +1 -1
  37. package/dist/server/sessions/askUserTool.js +102 -0
  38. package/dist/server/sessions/askUserTool.js.map +1 -0
  39. package/dist/server/sessions/authRoutes.js +0 -10
  40. package/dist/server/sessions/authRoutes.js.map +1 -1
  41. package/dist/server/sessions/authService.js +0 -24
  42. package/dist/server/sessions/authService.js.map +1 -1
  43. package/dist/server/sessions/extensionDialogWaiters.js +76 -0
  44. package/dist/server/sessions/extensionDialogWaiters.js.map +1 -0
  45. package/dist/server/sessions/globalProviderPolicy.js +79 -10
  46. package/dist/server/sessions/globalProviderPolicy.js.map +1 -1
  47. package/dist/server/sessions/messagePaging.js +2 -2
  48. package/dist/server/sessions/messagePaging.js.map +1 -1
  49. package/dist/server/sessions/modelCatalogRefresher.js +8 -0
  50. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -1
  51. package/dist/server/sessions/oauthLoginFlowService.js +2 -5
  52. package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
  53. package/dist/server/sessions/parentSessionLocator.js +75 -0
  54. package/dist/server/sessions/parentSessionLocator.js.map +1 -0
  55. package/dist/server/sessions/pendingAskStore.js +275 -0
  56. package/dist/server/sessions/pendingAskStore.js.map +1 -0
  57. package/dist/server/sessions/pendingExtensionDialogStore.js +196 -0
  58. package/dist/server/sessions/pendingExtensionDialogStore.js.map +1 -0
  59. package/dist/server/sessions/piSessionManagerGateway.js +182 -2
  60. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  61. package/dist/server/sessions/piSessionService.js +721 -203
  62. package/dist/server/sessions/piSessionService.js.map +1 -1
  63. package/dist/server/sessions/sessionFileHeader.js +117 -0
  64. package/dist/server/sessions/sessionFileHeader.js.map +1 -0
  65. package/dist/server/sessions/sessionRoutes.js +169 -54
  66. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  67. package/dist/server/sessions/sessionSummaryScanner.js +619 -0
  68. package/dist/server/sessions/sessionSummaryScanner.js.map +1 -0
  69. package/dist/server/sessions/spawnSessionTool.js +8 -1
  70. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  71. package/dist/server/sessions/spawnSubsessionTool.js +7 -1
  72. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  73. package/dist/server/sessions/spawnTargetResolver.js +3 -16
  74. package/dist/server/sessions/spawnTargetResolver.js.map +1 -1
  75. package/dist/server/workspaces/effectivePathAccess.js +0 -19
  76. package/dist/server/workspaces/effectivePathAccess.js.map +1 -1
  77. package/dist/server/workspaces/gitWorktreeDiscovery.js +9 -0
  78. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +1 -1
  79. package/dist/server/workspaces/projectWorkspaceCwds.js +22 -0
  80. package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -0
  81. package/dist/server/workspaces/workspaceDeletionRoutes.js +30 -4
  82. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -1
  83. package/dist/server/workspaces/workspaceService.js +15 -2
  84. package/dist/server/workspaces/workspaceService.js.map +1 -1
  85. package/dist/sessiond/config.js +2 -2
  86. package/dist/sessiond/config.js.map +1 -1
  87. package/dist/shared/activity.js +9 -1
  88. package/dist/shared/activity.js.map +1 -1
  89. package/dist/shared/apiTypes.d.ts +300 -24
  90. package/dist/shared/apiTypes.js +30 -15
  91. package/dist/shared/apiTypes.js.map +1 -1
  92. package/dist/shared/capabilities.js +10 -41
  93. package/dist/shared/capabilities.js.map +1 -1
  94. package/dist/shared/federatedRoutes.js +4 -3
  95. package/dist/shared/federatedRoutes.js.map +1 -1
  96. package/docs/config.md +115 -11
  97. package/docs/plugins.md +82 -14
  98. package/package.json +11 -9
  99. package/dist/client/assets/index-TvPsRyS1.js +0 -3545
  100. package/dist/server/sessiond/sessionDaemonStartup.js +0 -49
  101. package/dist/server/sessiond/sessionDaemonStartup.js.map +0 -1
  102. package/dist/server/sessions/sessionArchiveMigration.js +0 -590
  103. package/dist/server/sessions/sessionArchiveMigration.js.map +0 -1
@@ -0,0 +1,228 @@
1
+ // Generated from pi-web-plugins/relays/relayDiscovery.ts. Do not edit directly.
2
+ export const RELAYS_ROOT = ".pi-web/relays";
3
+ /** Documents that anchor a relay packet, in display order. Any other files follow alphabetically. */
4
+ export const RELAY_ANCHOR_DOCUMENTS = ["status.md", "charter.md", "log.md"];
5
+ /**
6
+ * Deepest node depth listed below the relay root; direct children of the relay
7
+ * root are depth 0. Children of a directory at this depth are skipped and the
8
+ * listing is flagged partial instead of walking arbitrarily deep trees.
9
+ */
10
+ export const MAX_RELAY_TREE_DEPTH = 5;
11
+ /** Most documents listed across one relay; extras are skipped and the listing is flagged partial. */
12
+ export const MAX_RELAY_DOCUMENTS = 200;
13
+ /** Most directories walked in one relay; extras stay listed but unexplored and the listing is flagged partial. */
14
+ export const MAX_RELAY_DIRECTORIES = 50;
15
+ // The workspace file API rejects with these messages when a path is absent or
16
+ // is not a directory. For the relays root both mean "zero relays", not a failure.
17
+ const missingListingErrorMessages = new Set(["Path does not exist", "Path is not a directory"]);
18
+ /** List the workspace's relays, most recently modified first. Never rejects. */
19
+ export async function listWorkspaceRelays(files) {
20
+ let listing;
21
+ try {
22
+ listing = await files.listFiles(RELAYS_ROOT);
23
+ }
24
+ catch (error) {
25
+ return fileAccessFailure(error);
26
+ }
27
+ const relays = sortRelaysByRecency(listing.entries
28
+ .filter((entry) => entry.type === "directory")
29
+ .map((entry) => toRelaySummary(entry)));
30
+ return { kind: "loaded", relays };
31
+ }
32
+ /**
33
+ * List one relay's document tree. At the relay root the anchor documents come
34
+ * first (status.md, charter.md, log.md); at every level files sort
35
+ * alphabetically before directories. Symlinks are never followed. Never
36
+ * rejects.
37
+ */
38
+ export async function listRelayDocumentTree(files, relayPath) {
39
+ let rootListing;
40
+ try {
41
+ rootListing = await files.listFiles(relayPath);
42
+ }
43
+ catch (error) {
44
+ return fileAccessFailure(error);
45
+ }
46
+ const state = { documentCount: 0, directoryCount: 0, partial: rootListing.truncated };
47
+ const tree = await walkListing(files, rootListing, relayPath, 0, state);
48
+ return { kind: "loaded", tree, documentCount: state.documentCount, partial: state.partial };
49
+ }
50
+ /** Read one relay document. Never rejects. */
51
+ export async function readRelayDocument(files, documentPath) {
52
+ try {
53
+ const file = await files.readFile(documentPath);
54
+ return { kind: "loaded", content: file.content, truncated: file.truncated, binary: file.binary };
55
+ }
56
+ catch (error) {
57
+ return fileAccessFailure(error);
58
+ }
59
+ }
60
+ /** Newest first; relays without a usable modifiedAt sort last, alphabetically. */
61
+ export function sortRelaysByRecency(relays) {
62
+ return [...relays].sort(compareRelaysByRecency);
63
+ }
64
+ /** The document a relay opens on: the depth-first first file (root anchors sort first, so status.md wins when present). */
65
+ export function defaultRelayDocument(tree) {
66
+ for (const node of tree) {
67
+ if (node.kind === "file")
68
+ return node;
69
+ const nested = defaultRelayDocument(node.children);
70
+ if (nested !== undefined)
71
+ return nested;
72
+ }
73
+ return undefined;
74
+ }
75
+ /** All file nodes in tree order, depth-first. */
76
+ export function flattenRelayTree(tree) {
77
+ const files = [];
78
+ const visit = (nodes) => {
79
+ for (const node of nodes) {
80
+ if (node.kind === "file")
81
+ files.push(node);
82
+ else
83
+ visit(node.children);
84
+ }
85
+ };
86
+ visit(tree);
87
+ return files;
88
+ }
89
+ /** Directory paths of every directory in the tree; used to prune stale expansion state. */
90
+ export function collectDirectoryPaths(tree) {
91
+ const paths = new Set();
92
+ const visit = (nodes) => {
93
+ for (const node of nodes) {
94
+ if (node.kind !== "directory")
95
+ continue;
96
+ paths.add(node.path);
97
+ visit(node.children);
98
+ }
99
+ };
100
+ visit(tree);
101
+ return paths;
102
+ }
103
+ /** Directory paths containing the given file, from the relay root down; empty when the file is not in the tree. */
104
+ export function ancestorDirectoryPaths(tree, filePath) {
105
+ const chain = [];
106
+ const visit = (nodes) => {
107
+ for (const node of nodes) {
108
+ if (node.kind === "file") {
109
+ if (node.path === filePath)
110
+ return true;
111
+ continue;
112
+ }
113
+ chain.push(node.path);
114
+ if (visit(node.children))
115
+ return true;
116
+ chain.pop();
117
+ }
118
+ return false;
119
+ };
120
+ return visit(tree) ? chain : [];
121
+ }
122
+ /**
123
+ * Build the ordered children of one already-fetched directory listing.
124
+ * Subdirectories are walked in parallel; a subdirectory whose own listing
125
+ * fails contributes an empty node and flags the tree partial rather than
126
+ * failing the whole relay.
127
+ */
128
+ async function walkListing(files, listing, relayPath, depth, state) {
129
+ // Symlink entries are intentionally never followed.
130
+ const fileEntries = listing.entries.filter((entry) => entry.type === "file");
131
+ const directoryEntries = listing.entries.filter((entry) => entry.type === "directory");
132
+ let fileNodes = orderFileEntries(fileEntries, depth === 0).map((entry) => toFileNode(entry, relayPath, depth));
133
+ const remaining = MAX_RELAY_DOCUMENTS - state.documentCount;
134
+ if (fileNodes.length > remaining) {
135
+ fileNodes = fileNodes.slice(0, Math.max(0, remaining));
136
+ state.partial = true;
137
+ }
138
+ state.documentCount += fileNodes.length;
139
+ const directories = await Promise.all([...directoryEntries].sort(compareByName).map(async (entry) => {
140
+ const node = {
141
+ kind: "directory",
142
+ name: entry.name,
143
+ path: entry.path,
144
+ relativePath: relativePathOf(entry.path, relayPath),
145
+ depth,
146
+ children: [],
147
+ };
148
+ if (depth >= MAX_RELAY_TREE_DEPTH) {
149
+ state.partial = true;
150
+ return node;
151
+ }
152
+ // The count is bumped synchronously before any await, so the parallel
153
+ // walk below stays deterministic in sorted order.
154
+ if (state.directoryCount >= MAX_RELAY_DIRECTORIES) {
155
+ state.partial = true;
156
+ return node;
157
+ }
158
+ state.directoryCount += 1;
159
+ try {
160
+ const subListing = await files.listFiles(entry.path);
161
+ if (subListing.truncated)
162
+ state.partial = true;
163
+ node.children = await walkListing(files, subListing, relayPath, depth + 1, state);
164
+ }
165
+ catch {
166
+ state.partial = true;
167
+ }
168
+ return node;
169
+ }));
170
+ return [...fileNodes, ...directories];
171
+ }
172
+ /** At the relay root the anchor documents lead; deeper levels are simply alphabetical. */
173
+ function orderFileEntries(entries, isRelayRoot) {
174
+ return [...entries].sort(isRelayRoot ? compareRootFiles : compareByName);
175
+ }
176
+ function compareRootFiles(left, right) {
177
+ const anchorOrder = anchorIndexOf(left.name) - anchorIndexOf(right.name);
178
+ if (anchorOrder !== 0)
179
+ return anchorOrder;
180
+ return left.name.localeCompare(right.name);
181
+ }
182
+ function anchorIndexOf(name) {
183
+ const index = RELAY_ANCHOR_DOCUMENTS.indexOf(name);
184
+ return index === -1 ? RELAY_ANCHOR_DOCUMENTS.length : index;
185
+ }
186
+ function compareByName(left, right) {
187
+ return left.name.localeCompare(right.name);
188
+ }
189
+ function toRelaySummary(entry) {
190
+ return { name: entry.name, path: entry.path, modifiedAt: entry.modifiedAt };
191
+ }
192
+ function toFileNode(entry, relayPath, depth) {
193
+ return {
194
+ kind: "file",
195
+ name: entry.name,
196
+ path: entry.path,
197
+ relativePath: relativePathOf(entry.path, relayPath),
198
+ depth,
199
+ modifiedAt: entry.modifiedAt,
200
+ };
201
+ }
202
+ /** Entry paths from the file API should sit under the relay root; fall back to the file name if not. */
203
+ function relativePathOf(path, relayPath) {
204
+ const prefix = `${relayPath}/`;
205
+ return path.startsWith(prefix) ? path.slice(prefix.length) : path.slice(path.lastIndexOf("/") + 1);
206
+ }
207
+ function compareRelaysByRecency(left, right) {
208
+ const leftTime = timestampOf(left.modifiedAt);
209
+ const rightTime = timestampOf(right.modifiedAt);
210
+ if (leftTime !== undefined && rightTime !== undefined && leftTime !== rightTime)
211
+ return rightTime - leftTime;
212
+ if (leftTime !== undefined)
213
+ return -1;
214
+ if (rightTime !== undefined)
215
+ return 1;
216
+ return left.name.localeCompare(right.name);
217
+ }
218
+ function timestampOf(modifiedAt) {
219
+ if (modifiedAt === undefined)
220
+ return undefined;
221
+ const time = Date.parse(modifiedAt);
222
+ return Number.isNaN(time) ? undefined : time;
223
+ }
224
+ function fileAccessFailure(error) {
225
+ if (error instanceof Error && missingListingErrorMessages.has(error.message))
226
+ return { kind: "missing" };
227
+ return { kind: "unavailable", detail: error instanceof Error ? error.message : String(error) };
228
+ }