wicked-crew 0.7.25 → 0.7.26

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 (131) hide show
  1. package/dist/api/endpoint-manifest-live.d.ts.map +1 -1
  2. package/dist/api/endpoint-manifest-live.js +5 -0
  3. package/dist/api/endpoint-manifest-live.js.map +1 -1
  4. package/dist/api/eval-compare.d.ts +306 -0
  5. package/dist/api/eval-compare.d.ts.map +1 -0
  6. package/dist/api/eval-compare.js +610 -0
  7. package/dist/api/eval-compare.js.map +1 -0
  8. package/dist/api/eval-sample.d.ts +158 -0
  9. package/dist/api/eval-sample.d.ts.map +1 -0
  10. package/dist/api/eval-sample.js +88 -0
  11. package/dist/api/eval-sample.js.map +1 -0
  12. package/dist/api/routes.d.ts +5 -0
  13. package/dist/api/routes.d.ts.map +1 -1
  14. package/dist/api/routes.js +31 -0
  15. package/dist/api/routes.js.map +1 -1
  16. package/dist/api/run-files.d.ts +12 -2
  17. package/dist/api/run-files.d.ts.map +1 -1
  18. package/dist/api/run-files.js +17 -5
  19. package/dist/api/run-files.js.map +1 -1
  20. package/dist/api/server.d.ts +20 -0
  21. package/dist/api/server.d.ts.map +1 -1
  22. package/dist/api/server.js +62 -9
  23. package/dist/api/server.js.map +1 -1
  24. package/dist/api/skills.d.ts +88 -0
  25. package/dist/api/skills.d.ts.map +1 -0
  26. package/dist/api/skills.js +264 -0
  27. package/dist/api/skills.js.map +1 -0
  28. package/dist/api/testing.d.ts +2 -75
  29. package/dist/api/testing.d.ts.map +1 -1
  30. package/dist/api/testing.js +14 -28
  31. package/dist/api/testing.js.map +1 -1
  32. package/dist/core/adapter.d.ts +42 -0
  33. package/dist/core/adapter.d.ts.map +1 -1
  34. package/dist/core/adapter.js +83 -12
  35. package/dist/core/adapter.js.map +1 -1
  36. package/dist/interactive/bridge-root.d.ts +117 -7
  37. package/dist/interactive/bridge-root.d.ts.map +1 -1
  38. package/dist/interactive/bridge-root.js +229 -9
  39. package/dist/interactive/bridge-root.js.map +1 -1
  40. package/dist/interactive/doc-delete-routes.d.ts +2 -0
  41. package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
  42. package/dist/interactive/doc-delete-routes.js +3 -19
  43. package/dist/interactive/doc-delete-routes.js.map +1 -1
  44. package/dist/interactive/doc-list-routes.d.ts +42 -0
  45. package/dist/interactive/doc-list-routes.d.ts.map +1 -0
  46. package/dist/interactive/doc-list-routes.js +165 -0
  47. package/dist/interactive/doc-list-routes.js.map +1 -0
  48. package/dist/interactive/project-root.d.ts +36 -0
  49. package/dist/interactive/project-root.d.ts.map +1 -0
  50. package/dist/interactive/project-root.js +45 -0
  51. package/dist/interactive/project-root.js.map +1 -0
  52. package/dist/interactive/proxy-routes.d.ts +4 -1
  53. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  54. package/dist/interactive/proxy-routes.js +4 -22
  55. package/dist/interactive/proxy-routes.js.map +1 -1
  56. package/dist/projects/default-project.d.ts +10 -0
  57. package/dist/projects/default-project.d.ts.map +1 -0
  58. package/dist/projects/default-project.js +10 -0
  59. package/dist/projects/default-project.js.map +1 -0
  60. package/dist/projects/routes.d.ts +0 -2
  61. package/dist/projects/routes.d.ts.map +1 -1
  62. package/dist/projects/routes.js +1 -2
  63. package/dist/projects/routes.js.map +1 -1
  64. package/dist/skills/bundle.d.ts +94 -0
  65. package/dist/skills/bundle.d.ts.map +1 -0
  66. package/dist/skills/bundle.js +187 -0
  67. package/dist/skills/bundle.js.map +1 -0
  68. package/dist/skills/contain.d.ts +57 -0
  69. package/dist/skills/contain.d.ts.map +1 -0
  70. package/dist/skills/contain.js +90 -0
  71. package/dist/skills/contain.js.map +1 -0
  72. package/dist/skills/core-closure.d.ts +83 -0
  73. package/dist/skills/core-closure.d.ts.map +1 -0
  74. package/dist/skills/core-closure.js +130 -0
  75. package/dist/skills/core-closure.js.map +1 -0
  76. package/dist/skills/engine-env.d.ts +48 -0
  77. package/dist/skills/engine-env.d.ts.map +1 -0
  78. package/dist/skills/engine-env.js +69 -0
  79. package/dist/skills/engine-env.js.map +1 -0
  80. package/dist/skills/frontmatter.d.ts +77 -0
  81. package/dist/skills/frontmatter.d.ts.map +1 -0
  82. package/dist/skills/frontmatter.js +190 -0
  83. package/dist/skills/frontmatter.js.map +1 -0
  84. package/dist/skills/guards.d.ts +72 -0
  85. package/dist/skills/guards.d.ts.map +1 -0
  86. package/dist/skills/guards.js +147 -0
  87. package/dist/skills/guards.js.map +1 -0
  88. package/dist/skills/live-generations.d.ts +80 -0
  89. package/dist/skills/live-generations.d.ts.map +1 -0
  90. package/dist/skills/live-generations.js +163 -0
  91. package/dist/skills/live-generations.js.map +1 -0
  92. package/dist/skills/plugin-source.d.ts +109 -0
  93. package/dist/skills/plugin-source.d.ts.map +1 -0
  94. package/dist/skills/plugin-source.js +272 -0
  95. package/dist/skills/plugin-source.js.map +1 -0
  96. package/dist/skills/refs.d.ts +58 -0
  97. package/dist/skills/refs.d.ts.map +1 -0
  98. package/dist/skills/refs.js +133 -0
  99. package/dist/skills/refs.js.map +1 -0
  100. package/dist/skills/root-fence.d.ts +53 -0
  101. package/dist/skills/root-fence.d.ts.map +1 -0
  102. package/dist/skills/root-fence.js +109 -0
  103. package/dist/skills/root-fence.js.map +1 -0
  104. package/dist/skills/root-names.d.ts +42 -0
  105. package/dist/skills/root-names.d.ts.map +1 -0
  106. package/dist/skills/root-names.js +44 -0
  107. package/dist/skills/root-names.js.map +1 -0
  108. package/dist/skills/runtime.d.ts +130 -0
  109. package/dist/skills/runtime.d.ts.map +1 -0
  110. package/dist/skills/runtime.js +246 -0
  111. package/dist/skills/runtime.js.map +1 -0
  112. package/dist/skills/store.d.ts +895 -0
  113. package/dist/skills/store.d.ts.map +1 -0
  114. package/dist/skills/store.js +3575 -0
  115. package/dist/skills/store.js.map +1 -0
  116. package/dist/skills/tree.d.ts +292 -0
  117. package/dist/skills/tree.d.ts.map +1 -0
  118. package/dist/skills/tree.js +645 -0
  119. package/dist/skills/tree.js.map +1 -0
  120. package/dist/skills/venv.d.ts +52 -0
  121. package/dist/skills/venv.d.ts.map +1 -0
  122. package/dist/skills/venv.js +80 -0
  123. package/dist/skills/venv.js.map +1 -0
  124. package/dist/studio/assets/index-CK1uJWs2.css +32 -0
  125. package/dist/studio/assets/index-FcZg3WDR.js +539 -0
  126. package/dist/studio/index.html +2 -2
  127. package/dist/studio/testid-inventory.json +605 -7
  128. package/endpoint-manifest.json +183 -1
  129. package/package.json +4 -3
  130. package/dist/studio/assets/index-C4iz4uAw.js +0 -537
  131. package/dist/studio/assets/index-DEEQcRQ_.css +0 -32
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-root.d.ts","sourceRoot":"","sources":["../../src/interactive/bridge-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,8FAA8F;AAC9F,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC7C;AAED;4FAC4F;AAC5F,eAAO,MAAM,QAAQ,4BAA4B,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEvE;AASD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,EAClD,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,IAAI,GAAE,MAAkB,GACvB,MAAM,CAMR"}
1
+ {"version":3,"file":"bridge-root.d.ts","sourceRoot":"","sources":["../../src/interactive/bridge-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH,8FAA8F;AAC9F,MAAM,WAAW,sBAAsB;IACrC,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC7C;AAED;;;qDAGqD;AACrD,eAAO,MAAM,QAAQ,4BAA4B,CAAC;AAElD,6FAA6F;AAC7F,eAAO,MAAM,YAAY,aAAa,CAAC;AAQvC;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAK9F;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE/D;AAED;;;;;;;GAOG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IAGvD,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAJvB,QAAQ,CAAC,UAAU,OAAO;gBAEf,SAAS,EAAE,MAAM;IAC1B,sCAAsC;IAC7B,IAAI,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAQf;AAWD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAErG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEnG;AA+ED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,EAClD,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,IAAI,GAAE,MAAkB,GACvB,MAAM,CAER;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,EAClD,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,IAAI,GAAE,MAAkB,GACvB,MAAM,CAER;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,SAAS,EAClD,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,EACrD,IAAI,GAAE,MAAkB,GACvB,MAAM,CAER"}
@@ -3,8 +3,22 @@
3
3
  *
4
4
  * §7.1 closed the identity question: a crew Project is THE entity, and an interactive
5
5
  * "instance" (a docs directory) maps onto it through ONE nullable setting, `interactiveRoot`.
6
- * Null means "the shared default root" — it is a default, never a constraint (§7.2): two
7
- * projects that leave it null share one bridge, a project that sets it gets its own.
6
+ * Null means "the default root" — it is a default, never a constraint (§7.2): a project that
7
+ * sets it gets exactly the directory it named.
8
+ *
9
+ * WHAT "THE DEFAULT" IS DEPENDS ON THE PROJECT (crew#472). It used to be one shared directory for
10
+ * every project, which meant `:projectId` in the proxy path was honored only to resolve a setting
11
+ * no project ever had — every project fell through to the same root, one bridge, one registry,
12
+ * the same 31 docs under every project's URL. Now:
13
+ *
14
+ * - the synthesized `default` ("Unfiled") project keeps the LEGACY shared root, byte-identical
15
+ * to `wicked-interactive serve`'s own default — so every doc created before partitioning stays
16
+ * visible under Unfiled with no data migration, and an operator's already-running default
17
+ * bridge is still adopted rather than duplicated;
18
+ * - every other project without an explicit root gets its own partition UNDER that root,
19
+ * `<default root>/projects/<projectId>`. Nested there on purpose: the legacy bridge's
20
+ * `listDocs` only lists slug-named children carrying a `versions.json`, so `projects/` is
21
+ * invisible to it, and the whole interactive footprint stays in the one place it always was.
8
22
  *
9
23
  * The resolved string is also the BRIDGE POOL KEY, which is why every spelling of the same
10
24
  * directory has to collapse to one value here rather than in the pool. `~/decks`, `decks`
@@ -12,11 +26,22 @@
12
26
  * start a second `wicked-interactive serve` on a second port for each spelling — exactly the
13
27
  * "why is it on 5 ports" confusion ADR-0025 exists to prevent.
14
28
  */
29
+ import { lstatSync, mkdirSync, readlinkSync, realpathSync } from 'node:fs';
15
30
  import { homedir } from 'node:os';
16
- import { resolve } from 'node:path';
31
+ import { relative, resolve, sep } from 'node:path';
32
+ import { DEFAULT_PROJECT_ID } from '../projects/default-project.js';
17
33
  /** Env override for the SHARED DEFAULT only (never for an explicit per-project setting).
18
- * Exists so a test harness or an e2e run can point "the default root" at a scratch dir. */
34
+ * Exists so a test harness or an e2e run can point "the default root" at a scratch dir. It is
35
+ * an explicit shared binding: while set, EVERY unbound project — `default` included — resolves
36
+ * to it, exactly as before partitioning existed. */
19
37
  export const ROOT_ENV = 'WICKED_INTERACTIVE_ROOT';
38
+ /** The directory under the default root that holds the per-project partitions (crew#472). */
39
+ export const PROJECTS_DIR = 'projects';
40
+ /**
41
+ * A project id that can be a directory name: one path segment, no separators, never `.`/`..`.
42
+ * Engine-minted ids are `proj_<ms><seq>`; the reserved `default` never reaches this check.
43
+ */
44
+ const PARTITION_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
20
45
  /**
21
46
  * What `wicked-interactive serve` uses with no `--root`: the canonical shared root
22
47
  * `~/wicked-interactive/docs` (ADR-0025 amended, `bin/wicked-interactive.js:181`). Kept
@@ -26,23 +51,218 @@ export const ROOT_ENV = 'WICKED_INTERACTIVE_ROOT';
26
51
  export function defaultInteractiveRoot(home = homedir()) {
27
52
  return resolve(home, 'wicked-interactive', 'docs');
28
53
  }
54
+ /**
55
+ * The default docs root of a NON-default project with no explicit binding:
56
+ * `<default root>/projects/<projectId>` (crew#472). The directory is created on first use by the
57
+ * bridge pool (it `mkdir -p`s any root before spawning a bridge), so resolution stays pure.
58
+ *
59
+ * Throws on an id that cannot be a directory name. The route layer 404s unknown projects before
60
+ * resolving, and the seams only see ids the engine minted, so reaching this is a bug — and the
61
+ * one answer that must never be given is a silent fallback to the shared root, which would
62
+ * quietly re-open the leak this partition closes.
63
+ */
64
+ export function partitionedInteractiveRoot(projectId, home = homedir()) {
65
+ if (!PARTITION_SEGMENT.test(projectId)) {
66
+ throw new Error(`project id ${JSON.stringify(projectId)} cannot name an interactive docs partition`);
67
+ }
68
+ return resolve(partitionsBase(home), projectId);
69
+ }
70
+ /** The directory holding every partition: `<default root>/projects`. */
71
+ export function partitionsBase(home = homedir()) {
72
+ return resolve(defaultInteractiveRoot(home), PROJECTS_DIR);
73
+ }
74
+ /**
75
+ * A project's partition is NOT a real directory under the projects base — a symbolic link, a
76
+ * regular file, or a path whose real location sits outside the base. Thrown by
77
+ * `preparePartitionedInteractiveRoot`, and so by every route's `projectDocsRoot`
78
+ * (`project-root.ts`). Fastify's default error handler honors `statusCode` and answers with
79
+ * this message verbatim, so the refusal reaches the operator as a 500 that names the offending
80
+ * path — never as a silent fallback to some other root.
81
+ */
82
+ export class InteractivePartitionRefusedError extends Error {
83
+ projectId;
84
+ path;
85
+ statusCode = 500;
86
+ constructor(projectId,
87
+ /** The path that failed the check. */
88
+ path, reason, base) {
89
+ super(`refusing to serve the interactive docs of project ${JSON.stringify(projectId)}: ${path} ${reason}. ` +
90
+ `A per-project partition must be a real directory under ${base} — remove or replace it and retry`);
91
+ this.projectId = projectId;
92
+ this.path = path;
93
+ this.name = 'InteractivePartitionRefusedError';
94
+ }
95
+ }
96
+ function lstatOrNull(path) {
97
+ try {
98
+ return lstatSync(path);
99
+ }
100
+ catch (err) {
101
+ if (err.code === 'ENOENT')
102
+ return null;
103
+ throw err;
104
+ }
105
+ }
106
+ /**
107
+ * Resolve AND materialize a project's partition, refusing anything that would let the lexical
108
+ * path `<base>/<projectId>` name a different directory.
109
+ *
110
+ * `partitionedInteractiveRoot` is lexical: it proves the id cannot spell its way out of
111
+ * `projects/`, and nothing more. A symbolic link already sitting at `projects/<id>` — pointing
112
+ * at another project's partition, or anywhere else — passes that check and would be followed by
113
+ * the bridge (spawned with `--root` = this path) into the other directory: project A reading and
114
+ * writing B's docs through a URL the id check said was A's. So, on REAL paths:
115
+ *
116
+ * 1. every component under the base is `lstat`ed — a symlink or a non-directory anywhere on the
117
+ * way refuses (fail closed, naming the path); the base itself is the operator's to place (a
118
+ * docs root kept on another volume behind a link is legitimate) and is not judged;
119
+ * 2. a missing component is created with `mkdir` WITHOUT `recursive` — `mkdir(2)` never follows
120
+ * a link at the component it creates, so a link raced in between the `lstat` and the `mkdir`
121
+ * surfaces as `EEXIST` and is `lstat`ed like anything else found in place, never followed;
122
+ * 3. the real path of the partition must sit inside the real path of the base — belt and braces
123
+ * over (1), so a containment failure the walk did not name is still refused.
124
+ *
125
+ * Returns the LEXICAL path — it is the bridge pool key, and spelling collapse is unchanged. The
126
+ * check runs per resolution, not per file operation: a link swapped in under a bridge that is
127
+ * already running is that process's (and the filesystem's) business, not something crew can see
128
+ * from the resolution seam.
129
+ */
130
+ export function preparePartitionedInteractiveRoot(projectId, home = homedir()) {
131
+ return containPartitionedInteractiveRoot(projectId, home, true);
132
+ }
133
+ /**
134
+ * The SAME containment check WITHOUT materialization (crew#474, Copilot) — for a caller that only
135
+ * reads what is already there: the interactive event seams (`server.ts` `interactiveDocsRoot`),
136
+ * which `readDocHead` a manifest under a root the routes materialized, or install a demo spec
137
+ * into a doc workspace that must already exist. Every component that EXISTS under the base is
138
+ * judged exactly as `preparePartitionedInteractiveRoot` judges it — a symbolic link or a
139
+ * non-directory refuses, an existing partition must realpath-resolve inside the base — and a
140
+ * component that does not exist ends the walk: nothing sits there to be followed, and a reader
141
+ * creates nothing (an event naming a project that never had a partition must not mint one).
142
+ * Returns the lexical path either way.
143
+ */
144
+ export function checkPartitionedInteractiveRoot(projectId, home = homedir()) {
145
+ return containPartitionedInteractiveRoot(projectId, home, false);
146
+ }
147
+ /**
148
+ * The ONE containment walk both entry points above run — `materialize` is the only difference
149
+ * (create a missing component vs. stop at it). Kept single on purpose: the routes and the event
150
+ * seams must agree on what `projects/<id>` may be, or a link the routes refuse is still followed
151
+ * through the seam path (the gap Copilot found on #474).
152
+ */
153
+ function containPartitionedInteractiveRoot(projectId, home, materialize) {
154
+ const partition = partitionedInteractiveRoot(projectId, home);
155
+ const base = partitionsBase(home);
156
+ if (materialize) {
157
+ mkdirSync(base, { recursive: true });
158
+ }
159
+ else if (lstatOrNull(base) === null) {
160
+ return partition; // no base yet ⇒ no partition ⇒ nothing on disk a link could redirect
161
+ }
162
+ const refuse = (path, reason) => {
163
+ throw new InteractivePartitionRefusedError(projectId, path, reason, base);
164
+ };
165
+ // One segment today (an id is a single path segment); walked as a path so a deeper layout
166
+ // later inherits the same rule.
167
+ let cursor = base;
168
+ for (const segment of relative(base, partition).split(sep)) {
169
+ cursor = resolve(cursor, segment);
170
+ let st = lstatOrNull(cursor);
171
+ if (st === null) {
172
+ if (!materialize)
173
+ return partition; // absent: nothing to follow, and a reader mints nothing
174
+ try {
175
+ mkdirSync(cursor);
176
+ }
177
+ catch (err) {
178
+ if (err.code !== 'EEXIST')
179
+ throw err;
180
+ }
181
+ st = lstatOrNull(cursor) ?? refuse(cursor, 'vanished while it was being created');
182
+ }
183
+ if (st.isSymbolicLink()) {
184
+ let target = '?';
185
+ try {
186
+ target = readlinkSync(cursor);
187
+ }
188
+ catch {
189
+ /* an unreadable link — the path alone is the finding */
190
+ }
191
+ refuse(cursor, `is a symbolic link (→ ${target})`);
192
+ }
193
+ if (!st.isDirectory())
194
+ refuse(cursor, 'is not a directory');
195
+ }
196
+ const realBase = realpathSync.native(base);
197
+ const realPartition = realpathSync.native(partition);
198
+ if (!realPartition.startsWith(realBase + sep)) {
199
+ refuse(partition, `resolves to ${realPartition}, outside ${realBase}`);
200
+ }
201
+ return partition;
202
+ }
29
203
  /** Expand a leading `~` and absolutize, so every spelling of one directory keys the same. */
30
204
  function canonicalize(value, home) {
31
205
  const expanded = value === '~' ? home : value.startsWith('~/') || value.startsWith('~\\') ? resolve(home, value.slice(2)) : value;
32
206
  return resolve(expanded);
33
207
  }
34
208
  /**
35
- * The resolved, canonical docs root for a project — and therefore its bridge pool key.
36
- * Precedence: the project's own `interactiveRoot` › `WICKED_INTERACTIVE_ROOT` › the shared
37
- * default. A blank/whitespace setting is treated as null, not as "the cwd".
209
+ * The EXPLICIT half of the precedence — the project's own `interactiveRoot`, else the
210
+ * `WICKED_INTERACTIVE_ROOT` shared binding — or null when neither is set. A blank/whitespace
211
+ * setting is treated as null, not as "the cwd".
38
212
  */
39
- export function resolveInteractiveRoot(setting, env = process.env, home = homedir()) {
213
+ function explicitInteractiveRoot(setting, env, home) {
40
214
  const own = setting?.interactiveRoot;
41
215
  if (typeof own === 'string' && own.trim() !== '')
42
216
  return canonicalize(own.trim(), home);
43
217
  const shared = env[ROOT_ENV];
44
218
  if (typeof shared === 'string' && shared.trim() !== '')
45
219
  return canonicalize(shared.trim(), home);
46
- return defaultInteractiveRoot(home);
220
+ return null;
221
+ }
222
+ /**
223
+ * The resolved, canonical docs root for a setting WITHOUT a project identity — and therefore its
224
+ * bridge pool key. Precedence: the own `interactiveRoot` › `WICKED_INTERACTIVE_ROOT` › the
225
+ * shared default. This is the `default` project's resolution; callers that know which project
226
+ * they are resolving for use `resolveProjectInteractiveRoot` so other projects partition.
227
+ */
228
+ export function resolveInteractiveRoot(setting, env = process.env, home = homedir()) {
229
+ return explicitInteractiveRoot(setting, env, home) ?? defaultInteractiveRoot(home);
230
+ }
231
+ /**
232
+ * The resolved, canonical docs root for a PROJECT (crew#472). Precedence: the project's own
233
+ * `interactiveRoot` › `WICKED_INTERACTIVE_ROOT` › the project's default — the legacy shared root
234
+ * for `default` (and for an unknown project identity, `undefined`: an event that carries no
235
+ * `project_id` belongs to Unfiled), the `projects/<projectId>` partition for everything else.
236
+ *
237
+ * The partition is containment-checked on REAL paths (crew#474): whatever already sits at
238
+ * `projects/<projectId>` — or on the way to it — must be a real directory whose real path is
239
+ * inside `projects/`, else `InteractivePartitionRefusedError`; a partition that does not exist
240
+ * yet is returned as its lexical path and NOTHING is created (`checkPartitionedInteractiveRoot`).
241
+ * This is the event seams' resolver (`server.ts` `interactiveDocsRoot`): they read manifests
242
+ * under a root the routes materialized, and a lexical-only answer here was the one path left on
243
+ * which a symlinked partition would still have been followed (Copilot on #474).
244
+ */
245
+ export function resolveProjectInteractiveRoot(projectId, setting, env = process.env, home = homedir()) {
246
+ return resolveProjectRootWith(checkPartitionedInteractiveRoot, projectId, setting, env, home);
247
+ }
248
+ /**
249
+ * `resolveProjectInteractiveRoot` for a caller about to USE the root and entitled to create it —
250
+ * the routes, through `project-root.ts`. Same precedence, the SAME containment walk; the one
251
+ * difference is that a missing partition is materialized (`preparePartitionedInteractiveRoot`)
252
+ * instead of merely spelled. An explicit root and the `default` project's legacy root are
253
+ * returned untouched by both resolvers — an operator's own directory is theirs to place, behind
254
+ * a link or not (§7.2) — so those two never cost a disk access.
255
+ */
256
+ export function ensureProjectInteractiveRoot(projectId, setting, env = process.env, home = homedir()) {
257
+ return resolveProjectRootWith(preparePartitionedInteractiveRoot, projectId, setting, env, home);
258
+ }
259
+ /** The one precedence rule, parameterized by how a partition is produced (spelled vs. prepared). */
260
+ function resolveProjectRootWith(partition, projectId, setting, env, home) {
261
+ const explicit = explicitInteractiveRoot(setting, env, home);
262
+ if (explicit !== null)
263
+ return explicit;
264
+ if (projectId === undefined || projectId === DEFAULT_PROJECT_ID)
265
+ return defaultInteractiveRoot(home);
266
+ return partition(projectId, home);
47
267
  }
48
268
  //# sourceMappingURL=bridge-root.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-root.js","sourceRoot":"","sources":["../../src/interactive/bridge-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC;4FAC4F;AAC5F,MAAM,CAAC,MAAM,QAAQ,GAAG,yBAAyB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,OAAO,EAAE;IAC7D,OAAO,OAAO,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,6FAA6F;AAC7F,SAAS,YAAY,CAAC,KAAa,EAAE,IAAY;IAC/C,MAAM,QAAQ,GACZ,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACnH,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAkD,EAClD,MAA0C,OAAO,CAAC,GAAG,EACrD,OAAe,OAAO,EAAE;IAExB,MAAM,GAAG,GAAG,OAAO,EAAE,eAAe,CAAC;IACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IACjG,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"bridge-root.js","sourceRoot":"","sources":["../../src/interactive/bridge-root.ts"],"names":[],"mappings":"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"}
@@ -60,6 +60,8 @@ export interface DocDeleteDeps {
60
60
  * a directly-driven route set gets an inert default so unit tests never touch ~/.wicked-crew). */
61
61
  dropDocLedgerRows: (documentId: string) => DocLedgerSweep;
62
62
  env?: NodeJS.ProcessEnv;
63
+ /** The home the default root hangs off (tests point it at a scratch dir). */
64
+ home?: string;
63
65
  log?: (msg: string) => void;
64
66
  /** Budget for the bridge's retire call (tests shorten it). The tombstone write is local and
65
67
  * fast; the default only has to outlast a busy event-loop, not a build. */
@@ -1 +1 @@
1
- {"version":3,"file":"doc-delete-routes.d.ts","sourceRoot":"","sources":["../../src/interactive/doc-delete-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAA0B,KAAK,qBAAqB,EAAmB,MAAM,kBAAkB,CAAC;AAEvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAU5D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC3C;uGACmG;IACnG,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,cAAc,CAAC;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B;gFAC4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AASD,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,aAAa,GAClB,IAAI,CAuMN"}
1
+ {"version":3,"file":"doc-delete-routes.d.ts","sourceRoot":"","sources":["../../src/interactive/doc-delete-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAA0B,KAAK,qBAAqB,EAAmB,MAAM,kBAAkB,CAAC;AAEvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAW5D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC3C;uGACmG;IACnG,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,cAAc,CAAC;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B;gFAC4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AASD,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,aAAa,GAClB,IAAI,CA4LN"}
@@ -43,11 +43,9 @@
43
43
  * Every state change lands in the actor audit trail as `interactive.doc.deleted` (task #88).
44
44
  */
45
45
  import { API_PREFIX } from '../api/api-prefix.js';
46
- import { ProjectsUnsupportedError } from '../core/adapter.js';
47
- import { DEFAULT_PROJECT_ID } from '../projects/routes.js';
48
- import { resolveInteractiveRoot } from './bridge-root.js';
49
46
  import { BridgeUnavailableError } from './bridge-pool.js';
50
47
  import { DOC_NAME } from './draft-events.js';
48
+ import { projectDocsRoot } from './project-root.js';
51
49
  const V = API_PREFIX;
52
50
  /** A sweep that deliberately did not run — the "nothing diverged" half of a refused delete. */
53
51
  const SWEEP_SKIPPED = Object.freeze({
@@ -57,25 +55,11 @@ const SWEEP_SKIPPED = Object.freeze({
57
55
  });
58
56
  export function registerInteractiveDocDelete(app, adapter, deps) {
59
57
  const { settings, pool, audit, actorOf, dropDocLedgerRows } = deps;
60
- const env = deps.env ?? process.env;
61
58
  const log = deps.log ?? (() => undefined);
62
59
  const timeoutMs = deps.upstreamTimeoutMs ?? 30_000;
63
60
  /** The resolved docs root for a project, or null when no such project exists — the SAME
64
- * resolution the proxy uses (`default` is synthesized by the route layer; a pre-projects
65
- * engine still answers for the one project it can have). */
66
- async function rootFor(projectId) {
67
- if (projectId !== DEFAULT_PROJECT_ID) {
68
- try {
69
- if ((await adapter.projectGet(projectId)) === null)
70
- return null;
71
- }
72
- catch (err) {
73
- if (!(err instanceof ProjectsUnsupportedError))
74
- throw err;
75
- }
76
- }
77
- return resolveInteractiveRoot(settings.get(projectId), env);
78
- }
61
+ * resolution the proxy and the docs list use (`project-root.ts`). */
62
+ const rootFor = (projectId) => projectDocsRoot(adapter, settings, projectId, deps);
79
63
  /** One retire call to the bridge. Throws on transport failure (caller retries once). */
80
64
  async function retireUpstream(bridge, doc) {
81
65
  const res = await fetch(`http://${bridge.host}:${bridge.port}/api/docs/${doc}`, {
@@ -1 +1 @@
1
- {"version":3,"file":"doc-delete-routes.js","sourceRoot":"","sources":["../../src/interactive/doc-delete-routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doc-delete-routes.js","sourceRoot":"","sources":["../../src/interactive/doc-delete-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `GET /api/v1/projects/:projectId/interactive/api/docs` — the project-attributed docs list
3
+ * (crew#472).
4
+ *
5
+ * The bridge's own `GET /api/docs` lists the docs of ONE root and knows nothing about crew's
6
+ * projects: a row says `name`/`kind`/`head`/`versions`/`updated_at`, never which project it was
7
+ * listed for. With docs roots partitioned per project (`bridge-root.ts`), the mount a list was
8
+ * fetched under IS the attribution — so this route relays the bridge's rows field-for-field and
9
+ * stamps each with the `projectId` of the mount, the one fact the bridge cannot supply and a
10
+ * client rendering docs from several projects at once cannot otherwise recover.
11
+ *
12
+ * Deliberately NOT part of the pure-transport proxy (`proxy-routes.ts` stays response-sniffing
13
+ * free, the same posture as the governed delete): this is its own route, one static segment more
14
+ * specific than the proxy's wildcard, so fastify routes exactly this GET here while every other
15
+ * method on the same path — `POST /api/docs` creates a doc — and every other path keep flowing
16
+ * through the proxy verbatim. The query string (`?includeRetired=1`) is forwarded untouched.
17
+ *
18
+ * Non-list answers are relayed rather than reshaped: a bridge that fails its own listing answers
19
+ * with its status and body; a bridge that answers 200 with something other than a JSON array of
20
+ * doc summaries — a non-JSON body, a JSON object, a list holding `null` or a string where a row
21
+ * should be — is a 502 that says which, never an empty list pretending nothing exists and never
22
+ * `[{ projectId }]` minted from nothing. And a body that is malformed is told apart from a body
23
+ * that never fully ARRIVED: the first is the bridge's answer (no retry would change it), the
24
+ * second is a transport failure that takes the same invalidate → retry-once → diagnostic path a
25
+ * refused connect does.
26
+ */
27
+ import type { FastifyInstance } from 'fastify';
28
+ import type { CoreAdapter } from '../core/adapter.js';
29
+ import { type InteractiveBridgePool } from './bridge-pool.js';
30
+ import type { ProjectSettingsStore } from '../projects/settings.js';
31
+ export interface DocListDeps {
32
+ settings: ProjectSettingsStore;
33
+ pool: InteractiveBridgePool;
34
+ env?: NodeJS.ProcessEnv;
35
+ /** The home the default root hangs off (tests point it at a scratch dir). */
36
+ home?: string;
37
+ log?: (msg: string) => void;
38
+ /** Budget for the bridge's list call (tests shorten it). The list is a directory scan. */
39
+ upstreamTimeoutMs?: number;
40
+ }
41
+ export declare function registerInteractiveDocList(app: FastifyInstance, adapter: CoreAdapter, deps: DocListDeps): void;
42
+ //# sourceMappingURL=doc-list-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-list-routes.d.ts","sourceRoot":"","sources":["../../src/interactive/doc-list-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAA0B,KAAK,qBAAqB,EAAmB,MAAM,kBAAkB,CAAC;AACvG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAmCpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,0FAA0F;IAC1F,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA0H9G"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * `GET /api/v1/projects/:projectId/interactive/api/docs` — the project-attributed docs list
3
+ * (crew#472).
4
+ *
5
+ * The bridge's own `GET /api/docs` lists the docs of ONE root and knows nothing about crew's
6
+ * projects: a row says `name`/`kind`/`head`/`versions`/`updated_at`, never which project it was
7
+ * listed for. With docs roots partitioned per project (`bridge-root.ts`), the mount a list was
8
+ * fetched under IS the attribution — so this route relays the bridge's rows field-for-field and
9
+ * stamps each with the `projectId` of the mount, the one fact the bridge cannot supply and a
10
+ * client rendering docs from several projects at once cannot otherwise recover.
11
+ *
12
+ * Deliberately NOT part of the pure-transport proxy (`proxy-routes.ts` stays response-sniffing
13
+ * free, the same posture as the governed delete): this is its own route, one static segment more
14
+ * specific than the proxy's wildcard, so fastify routes exactly this GET here while every other
15
+ * method on the same path — `POST /api/docs` creates a doc — and every other path keep flowing
16
+ * through the proxy verbatim. The query string (`?includeRetired=1`) is forwarded untouched.
17
+ *
18
+ * Non-list answers are relayed rather than reshaped: a bridge that fails its own listing answers
19
+ * with its status and body; a bridge that answers 200 with something other than a JSON array of
20
+ * doc summaries — a non-JSON body, a JSON object, a list holding `null` or a string where a row
21
+ * should be — is a 502 that says which, never an empty list pretending nothing exists and never
22
+ * `[{ projectId }]` minted from nothing. And a body that is malformed is told apart from a body
23
+ * that never fully ARRIVED: the first is the bridge's answer (no retry would change it), the
24
+ * second is a transport failure that takes the same invalidate → retry-once → diagnostic path a
25
+ * refused connect does.
26
+ */
27
+ import { API_PREFIX } from '../api/api-prefix.js';
28
+ import { BridgeUnavailableError } from './bridge-pool.js';
29
+ import { projectDocsRoot } from './project-root.js';
30
+ const V = API_PREFIX;
31
+ function isDocSummaryRow(row) {
32
+ if (typeof row !== 'object' || row === null || Array.isArray(row))
33
+ return false;
34
+ const r = row;
35
+ return typeof r['name'] === 'string' && typeof r['kind'] === 'string';
36
+ }
37
+ /** A short, safe rendering of an offending row for the 502 detail — its type and a bounded preview. */
38
+ function describeRow(row) {
39
+ if (row === null)
40
+ return 'null';
41
+ if (Array.isArray(row))
42
+ return 'an array';
43
+ if (typeof row !== 'object')
44
+ return `a ${typeof row} (${String(JSON.stringify(row) ?? row).slice(0, 80)})`;
45
+ const keys = Object.keys(row).slice(0, 8).join(', ');
46
+ return `an object without string name/kind (keys: ${keys === '' ? 'none' : keys})`;
47
+ }
48
+ export function registerInteractiveDocList(app, adapter, deps) {
49
+ const { settings, pool } = deps;
50
+ const log = deps.log ?? (() => undefined);
51
+ const timeoutMs = deps.upstreamTimeoutMs ?? 30_000;
52
+ /**
53
+ * One list call to the bridge. Throws on transport failure — a refused connect, the timeout, a
54
+ * connection torn down while the body was still arriving — and the caller retries once. Only a
55
+ * COMPLETE body reaches the parser, so a parse failure is exactly what it looks like: the
56
+ * bridge answered with something other than JSON (its default not-found page, say). No retry
57
+ * would change that, so it is reported as the bridge's answer, never as unreachability.
58
+ */
59
+ async function listUpstream(bridge, query) {
60
+ const res = await fetch(`http://${bridge.host}:${bridge.port}/api/docs${query}`, {
61
+ signal: AbortSignal.timeout(timeoutMs),
62
+ });
63
+ const text = await res.text();
64
+ try {
65
+ return { status: res.status, body: JSON.parse(text), json: true };
66
+ }
67
+ catch {
68
+ return { status: res.status, body: null, json: false };
69
+ }
70
+ }
71
+ function unavailable(reply, err) {
72
+ if (!(err instanceof BridgeUnavailableError))
73
+ throw err;
74
+ log(`[doc-list] interactive bridge unavailable: ${err.message}`);
75
+ return reply.code(503).send({ code: 'bridge_unavailable', hint: err.hint });
76
+ }
77
+ app.get(`${V}/projects/:projectId/interactive/api/docs`, {
78
+ config: {
79
+ manifest: {
80
+ // The wire is a JSON ARRAY of rows, spelled in the manifest's TypeScript-inline form
81
+ // (`{ runs: SessionView[] }` is the wrapped-list precedent). 500 is the refused
82
+ // partition (`InteractivePartitionRefusedError`, bridge-root.ts).
83
+ responseType: 'InteractiveDocSummary[]',
84
+ statusCodes: [200, 404, 500, 502, 503],
85
+ },
86
+ },
87
+ }, async (req, reply) => {
88
+ const { projectId } = req.params;
89
+ // The RAW query, so percent-encoding survives the hop (the proxy's verbatim rule).
90
+ const raw = req.raw.url ?? '';
91
+ const query = raw.includes('?') ? raw.slice(raw.indexOf('?')) : '';
92
+ const root = await projectDocsRoot(adapter, settings, projectId, deps);
93
+ if (root === null)
94
+ return reply.code(404).send({ error: `Project ${projectId} not found` });
95
+ let bridge;
96
+ try {
97
+ bridge = await pool.ensure(root);
98
+ }
99
+ catch (err) {
100
+ return unavailable(reply, err);
101
+ }
102
+ // One retry on a dead cached bridge, the proxy's discipline: invalidate, let `ensure`
103
+ // restart it, try once more — then fail loudly instead of looping.
104
+ let upstream;
105
+ try {
106
+ upstream = await listUpstream(bridge, query);
107
+ }
108
+ catch (firstErr) {
109
+ pool.invalidate(root);
110
+ try {
111
+ bridge = await pool.ensure(root);
112
+ }
113
+ catch (startErr) {
114
+ return unavailable(reply, startErr);
115
+ }
116
+ try {
117
+ upstream = await listUpstream(bridge, query);
118
+ }
119
+ catch (err) {
120
+ const detail = err instanceof Error ? err.message : String(err);
121
+ log(`[doc-list] list call to the bridge failed for project ${projectId}: ${detail}`);
122
+ return reply.code(502).send({
123
+ error: 'wicked-interactive was unreachable — GET /api/docs did not answer',
124
+ detail,
125
+ first_attempt: firstErr instanceof Error ? firstErr.message : String(firstErr),
126
+ });
127
+ }
128
+ }
129
+ // The bridge's own failure, relayed with its status: never reshaped into an empty list. A
130
+ // non-JSON failure body (a bridge's default not-found page) gets a JSON error in its place.
131
+ if (upstream.status !== 200) {
132
+ return reply
133
+ .code(upstream.status)
134
+ .send(upstream.json && upstream.body !== null
135
+ ? upstream.body
136
+ : { error: `wicked-interactive answered GET /api/docs with HTTP ${upstream.status}` });
137
+ }
138
+ if (!upstream.json) {
139
+ log(`[doc-list] the bridge answered GET /api/docs for project ${projectId} with a body that is not JSON`);
140
+ return reply
141
+ .code(502)
142
+ .send({ error: 'wicked-interactive answered GET /api/docs with a malformed body (not JSON)' });
143
+ }
144
+ if (!Array.isArray(upstream.body)) {
145
+ log(`[doc-list] the bridge answered GET /api/docs for project ${projectId} with a non-list body`);
146
+ return reply.code(502).send({ error: 'wicked-interactive answered GET /api/docs with a non-list body' });
147
+ }
148
+ // Every row must be a doc summary before it is vouched for: `[null]` would otherwise become
149
+ // `[{ projectId }]` with a 200, and a string row would spread into char-indexed keys.
150
+ const rows = upstream.body;
151
+ const summaries = [];
152
+ for (const [index, row] of rows.entries()) {
153
+ if (!isDocSummaryRow(row)) {
154
+ const detail = `row ${index} is not a doc summary: ${describeRow(row)}`;
155
+ log(`[doc-list] the bridge answered GET /api/docs for project ${projectId} with a malformed list — ${detail}`);
156
+ return reply
157
+ .code(502)
158
+ .send({ error: 'wicked-interactive answered GET /api/docs with a malformed list', detail });
159
+ }
160
+ summaries.push(row);
161
+ }
162
+ return reply.send(summaries.map((row) => ({ ...row, projectId })));
163
+ });
164
+ }
165
+ //# sourceMappingURL=doc-list-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-list-routes.js","sourceRoot":"","sources":["../../src/interactive/doc-list-routes.ts"],"names":[],"mappings":"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"}