@doxbrix/doxloop 0.1.4 → 0.2.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 (357) hide show
  1. package/CHANGELOG.md +1153 -0
  2. package/README.md +422 -226
  3. package/assets/doxbrix-preview.css +77 -15
  4. package/contracts/agent-events-v1.schema.json +1 -0
  5. package/contracts/coverage-v1.schema.json +59 -0
  6. package/contracts/drift-v1.schema.json +1 -0
  7. package/contracts/evaluation-v1.schema.json +62 -0
  8. package/contracts/quality-codes-v1.json +1 -0
  9. package/contracts/quality-report-v1.schema.json +1 -0
  10. package/contracts/validation-v1.schema.json +1 -0
  11. package/dist/agent-failure.d.ts +36 -0
  12. package/dist/agent-failure.js +98 -0
  13. package/dist/agent-isolation.d.ts +17 -0
  14. package/dist/agent-isolation.js +94 -0
  15. package/dist/agent-log.d.ts +197 -0
  16. package/dist/agent-log.js +1094 -0
  17. package/dist/agent-process.d.ts +63 -0
  18. package/dist/agent-process.js +128 -0
  19. package/dist/agent-reply.d.ts +47 -0
  20. package/dist/agent-reply.js +315 -0
  21. package/dist/agents.d.ts +40 -4
  22. package/dist/agents.js +115 -11
  23. package/dist/api-coverage.d.ts +11 -0
  24. package/dist/api-coverage.js +72 -0
  25. package/dist/application-probe.d.ts +28 -0
  26. package/dist/application-probe.js +93 -0
  27. package/dist/application-url.d.ts +14 -0
  28. package/dist/application-url.js +26 -0
  29. package/dist/args.js +15 -0
  30. package/dist/artifact-deploy.d.ts +9 -0
  31. package/dist/artifact-deploy.js +28 -8
  32. package/dist/assets.d.ts +72 -0
  33. package/dist/assets.js +382 -0
  34. package/dist/auth.d.ts +10 -0
  35. package/dist/auth.js +38 -9
  36. package/dist/author.d.ts +206 -4
  37. package/dist/author.js +1650 -52
  38. package/dist/authoring-batches.d.ts +190 -0
  39. package/dist/authoring-batches.js +489 -0
  40. package/dist/authoring-postpass.d.ts +79 -0
  41. package/dist/authoring-postpass.js +1289 -0
  42. package/dist/authoring-progress.d.ts +95 -0
  43. package/dist/authoring-progress.js +269 -0
  44. package/dist/autosync.d.ts +56 -0
  45. package/dist/autosync.js +442 -0
  46. package/dist/batch-artifacts.d.ts +81 -0
  47. package/dist/batch-artifacts.js +412 -0
  48. package/dist/batch-limits.d.ts +37 -0
  49. package/dist/batch-limits.js +80 -0
  50. package/dist/branding.d.ts +41 -0
  51. package/dist/branding.js +229 -0
  52. package/dist/bundle-upload.d.ts +26 -0
  53. package/dist/bundle-upload.js +99 -0
  54. package/dist/capture-auth.d.ts +95 -0
  55. package/dist/capture-auth.js +204 -0
  56. package/dist/capture.d.ts +48 -0
  57. package/dist/capture.js +20 -1
  58. package/dist/cli.js +839 -32
  59. package/dist/content-links.d.ts +10 -0
  60. package/dist/content-links.js +49 -0
  61. package/dist/contract-validation.d.ts +4 -0
  62. package/dist/contract-validation.js +25 -0
  63. package/dist/coverage-actions.d.ts +8 -0
  64. package/dist/coverage-actions.js +71 -0
  65. package/dist/coverage-resolutions.d.ts +16 -0
  66. package/dist/coverage-resolutions.js +58 -0
  67. package/dist/db.d.ts +37 -0
  68. package/dist/db.js +288 -0
  69. package/dist/demo.d.ts +12 -0
  70. package/dist/demo.js +122 -0
  71. package/dist/deploy-credentials.d.ts +7 -0
  72. package/dist/deploy-credentials.js +76 -0
  73. package/dist/deploy-targets/github-pages.d.ts +3 -0
  74. package/dist/deploy-targets/github-pages.js +100 -0
  75. package/dist/deploy-targets/index.d.ts +8 -0
  76. package/dist/deploy-targets/index.js +78 -0
  77. package/dist/deploy-targets/netlify.d.ts +3 -0
  78. package/dist/deploy-targets/netlify.js +49 -0
  79. package/dist/deploy-targets/types.d.ts +32 -0
  80. package/dist/deploy-targets/types.js +2 -0
  81. package/dist/deploy-targets/vercel.d.ts +3 -0
  82. package/dist/deploy-targets/vercel.js +95 -0
  83. package/dist/deploy.d.ts +9 -0
  84. package/dist/deploy.js +87 -13
  85. package/dist/deterministic-capture.d.ts +90 -0
  86. package/dist/deterministic-capture.js +435 -0
  87. package/dist/direct-edit.d.ts +40 -0
  88. package/dist/direct-edit.js +159 -0
  89. package/dist/docs-crawl.d.ts +86 -0
  90. package/dist/docs-crawl.js +536 -0
  91. package/dist/docs-site.d.ts +49 -0
  92. package/dist/docs-site.js +233 -0
  93. package/dist/doctor.js +8 -0
  94. package/dist/documentation-collections.d.ts +23 -0
  95. package/dist/documentation-collections.js +191 -0
  96. package/dist/documentation-plan.d.ts +253 -0
  97. package/dist/documentation-plan.js +2563 -0
  98. package/dist/doxbrix-build.d.ts +19 -0
  99. package/dist/doxbrix-build.js +167 -0
  100. package/dist/doxbrix-markdown.d.ts +9 -0
  101. package/dist/doxbrix-markdown.js +115 -14
  102. package/dist/drift.d.ts +10 -0
  103. package/dist/drift.js +164 -0
  104. package/dist/evaluation.d.ts +46 -0
  105. package/dist/evaluation.js +113 -0
  106. package/dist/evidence-pack.d.ts +47 -0
  107. package/dist/evidence-pack.js +358 -0
  108. package/dist/evidence.d.ts +25 -0
  109. package/dist/evidence.js +175 -0
  110. package/dist/fs.d.ts +8 -2
  111. package/dist/fs.js +41 -11
  112. package/dist/generator-api.d.ts +89 -0
  113. package/dist/generator-preflight.d.ts +27 -0
  114. package/dist/generator-preflight.js +105 -0
  115. package/dist/generator-runtime.d.ts +7 -0
  116. package/dist/generator-runtime.js +17 -1
  117. package/dist/generators.d.ts +24 -2
  118. package/dist/generators.js +54 -1
  119. package/dist/git-delivery.d.ts +17 -0
  120. package/dist/git-delivery.js +123 -0
  121. package/dist/globs.d.ts +16 -0
  122. package/dist/globs.js +65 -0
  123. package/dist/glossary.d.ts +26 -0
  124. package/dist/glossary.js +179 -0
  125. package/dist/history.d.ts +106 -0
  126. package/dist/history.js +600 -0
  127. package/dist/html-markdown.d.ts +46 -0
  128. package/dist/html-markdown.js +423 -0
  129. package/dist/interactive.js +16 -15
  130. package/dist/job-events.d.ts +74 -0
  131. package/dist/job-events.js +377 -0
  132. package/dist/keep-awake.d.ts +50 -0
  133. package/dist/keep-awake.js +123 -0
  134. package/dist/local-source-snapshot.d.ts +20 -0
  135. package/dist/local-source-snapshot.js +61 -0
  136. package/dist/mintlify-detect.d.ts +3 -0
  137. package/dist/mintlify-detect.js +18 -0
  138. package/dist/mintlify-import.d.ts +75 -0
  139. package/dist/mintlify-import.js +190 -0
  140. package/dist/navigation.d.ts +98 -0
  141. package/dist/navigation.js +310 -0
  142. package/dist/openapi.d.ts +60 -0
  143. package/dist/openapi.js +439 -0
  144. package/dist/page-editor-bridge.d.ts +3 -0
  145. package/dist/page-editor-bridge.js +109 -0
  146. package/dist/page-editor-preview.d.ts +10 -0
  147. package/dist/page-editor-preview.js +55 -0
  148. package/dist/page-extension.d.ts +9 -0
  149. package/dist/page-extension.js +15 -0
  150. package/dist/page-metadata.d.ts +28 -0
  151. package/dist/page-metadata.js +166 -0
  152. package/dist/page-operations.d.ts +34 -0
  153. package/dist/page-operations.js +215 -0
  154. package/dist/page-routes.d.ts +4 -0
  155. package/dist/page-routes.js +61 -0
  156. package/dist/pages.d.ts +20 -0
  157. package/dist/pages.js +184 -0
  158. package/dist/plan-generator.d.ts +3 -0
  159. package/dist/plan-generator.js +21 -0
  160. package/dist/plan-navigation.d.ts +11 -0
  161. package/dist/plan-navigation.js +30 -0
  162. package/dist/planning-captures.d.ts +20 -0
  163. package/dist/planning-captures.js +143 -0
  164. package/dist/planning-research.d.ts +135 -0
  165. package/dist/planning-research.js +472 -0
  166. package/dist/planning-triage.d.ts +23 -0
  167. package/dist/planning-triage.js +131 -0
  168. package/dist/preview.d.ts +24 -0
  169. package/dist/preview.js +280 -29
  170. package/dist/project-detect.d.ts +36 -0
  171. package/dist/project-detect.js +251 -0
  172. package/dist/project-import.d.ts +54 -0
  173. package/dist/project-import.js +157 -0
  174. package/dist/project-lock.d.ts +6 -0
  175. package/dist/project-lock.js +96 -0
  176. package/dist/project-registry.d.ts +25 -0
  177. package/dist/project-registry.js +79 -0
  178. package/dist/project.d.ts +35 -3
  179. package/dist/project.js +388 -38
  180. package/dist/prompts.d.ts +9 -0
  181. package/dist/prompts.js +33 -4
  182. package/dist/proposal-replay.d.ts +32 -0
  183. package/dist/proposal-replay.js +99 -0
  184. package/dist/quality-claims.d.ts +8 -0
  185. package/dist/quality-claims.js +168 -0
  186. package/dist/quality-config.d.ts +5 -0
  187. package/dist/quality-config.js +84 -0
  188. package/dist/quality-contract.d.ts +37 -0
  189. package/dist/quality-contract.js +46 -0
  190. package/dist/quality-examples.d.ts +4 -0
  191. package/dist/quality-examples.js +233 -0
  192. package/dist/quality-gates.d.ts +16 -0
  193. package/dist/quality-gates.js +192 -0
  194. package/dist/quality-links.d.ts +7 -0
  195. package/dist/quality-links.js +149 -0
  196. package/dist/quality-lint.d.ts +6 -0
  197. package/dist/quality-lint.js +124 -0
  198. package/dist/quality-rendered.d.ts +11 -0
  199. package/dist/quality-rendered.js +222 -0
  200. package/dist/quality-schema.d.ts +3 -0
  201. package/dist/quality-schema.js +71 -0
  202. package/dist/release-notes.d.ts +44 -0
  203. package/dist/release-notes.js +183 -0
  204. package/dist/remote-monitor.d.ts +16 -0
  205. package/dist/remote-monitor.js +74 -0
  206. package/dist/remote-source.d.ts +34 -0
  207. package/dist/remote-source.js +426 -0
  208. package/dist/review-diff.d.ts +82 -0
  209. package/dist/review-diff.js +400 -0
  210. package/dist/review-learning.d.ts +11 -0
  211. package/dist/review-learning.js +60 -0
  212. package/dist/review-render.d.ts +38 -0
  213. package/dist/review-render.js +224 -0
  214. package/dist/review-report.d.ts +9 -0
  215. package/dist/review-report.js +89 -0
  216. package/dist/review-ui.d.ts +14 -0
  217. package/dist/review-ui.js +1248 -0
  218. package/dist/schedule.d.ts +78 -0
  219. package/dist/schedule.js +480 -0
  220. package/dist/screen-capture-provider.d.ts +52 -0
  221. package/dist/screen-capture-provider.js +218 -0
  222. package/dist/screenshot-workflow.d.ts +167 -0
  223. package/dist/screenshot-workflow.js +1237 -0
  224. package/dist/settings.d.ts +1 -1
  225. package/dist/settings.js +95 -7
  226. package/dist/site-export.d.ts +18 -0
  227. package/dist/site-export.js +87 -0
  228. package/dist/source-connectors.d.ts +33 -0
  229. package/dist/source-connectors.js +268 -0
  230. package/dist/source-discovery.d.ts +132 -0
  231. package/dist/source-discovery.js +823 -0
  232. package/dist/source-intelligence.d.ts +9 -0
  233. package/dist/source-intelligence.js +306 -0
  234. package/dist/sync-review.d.ts +28 -0
  235. package/dist/sync-review.js +264 -0
  236. package/dist/sync-runs.d.ts +192 -0
  237. package/dist/sync-runs.js +2244 -0
  238. package/dist/sync.d.ts +35 -0
  239. package/dist/sync.js +298 -32
  240. package/dist/text-diff.d.ts +9 -0
  241. package/dist/text-diff.js +59 -0
  242. package/dist/types.d.ts +946 -1
  243. package/dist/ui/assets/doxloop-logo-light-De7Nx7j7.png +0 -0
  244. package/dist/ui/assets/index-BHBYU2aG.css +1 -0
  245. package/dist/ui/assets/index-Cq3RPQiC.js +33 -0
  246. package/dist/ui/index.html +18 -0
  247. package/dist/ui-server.d.ts +83 -0
  248. package/dist/ui-server.js +3532 -0
  249. package/dist/usage-budget.d.ts +28 -0
  250. package/dist/usage-budget.js +90 -0
  251. package/dist/validation.d.ts +25 -1
  252. package/dist/validation.js +312 -26
  253. package/dist/workspace-tools.d.ts +54 -0
  254. package/dist/workspace-tools.js +123 -0
  255. package/docs/agent-compatibility.md +50 -28
  256. package/docs/ci-and-automation.md +105 -66
  257. package/docs/doxbrix-http-api.md +8 -1
  258. package/docs/existing-documentation.md +80 -0
  259. package/docs/generation-performance.md +108 -0
  260. package/docs/generator-authoring.md +68 -5
  261. package/docs/generator-selection.md +50 -13
  262. package/docs/mintlify-import.md +71 -0
  263. package/docs/openapi-security.md +25 -0
  264. package/docs/project-format.md +331 -36
  265. package/docs/release-quality.md +158 -0
  266. package/docs/releasing.md +72 -0
  267. package/docs/review-workflows.md +51 -0
  268. package/docs/security-model.md +102 -39
  269. package/docs/troubleshooting.md +226 -93
  270. package/package.json +46 -15
  271. package/scripts/test-auto-screenshot.mjs +172 -0
  272. package/skills/doxloop-authoring/SKILL.md +242 -361
  273. package/skills/doxloop-authoring/references/existing-documentation.md +94 -0
  274. package/skills/doxloop-authoring/references/navigation-architecture.md +18 -7
  275. package/skills/doxloop-authoring/references/page-depth.md +169 -0
  276. package/skills/doxloop-authoring/references/project-format.md +106 -7
  277. package/skills/doxloop-authoring/references/quality.md +10 -0
  278. package/skills/doxloop-authoring/references/screenshot-manifest.md +113 -0
  279. package/skills/doxloop-authoring/references/screenshots.md +149 -235
  280. package/skills/doxloop-authoring/references/workflows.md +76 -0
  281. package/skills/doxloop-doxbrix/SKILL.md +38 -22
  282. package/skills/doxloop-doxbrix/references/api-endpoints.md +15 -14
  283. package/skills/doxloop-doxbrix/references/components.md +30 -3
  284. package/skills/doxloop-doxbrix/references/manifest.md +3 -2
  285. package/vendor/doxbrix-import/LICENSE +202 -0
  286. package/vendor/doxbrix-import/README.md +17 -0
  287. package/vendor/doxbrix-import/UPSTREAM.json +47 -0
  288. package/vendor/doxbrix-import/dist/docs/frontmatter.d.ts +13 -0
  289. package/vendor/doxbrix-import/dist/docs/frontmatter.js +83 -0
  290. package/vendor/doxbrix-import/dist/docs/import.d.ts +21 -0
  291. package/vendor/doxbrix-import/dist/docs/import.js +147 -0
  292. package/vendor/doxbrix-import/dist/docs/manifest.d.ts +163 -0
  293. package/vendor/doxbrix-import/dist/docs/manifest.js +64 -0
  294. package/vendor/doxbrix-import/dist/docs/project.d.ts +25 -0
  295. package/vendor/doxbrix-import/dist/docs/project.js +77 -0
  296. package/vendor/doxbrix-import/dist/docs/starter.d.ts +4 -0
  297. package/vendor/doxbrix-import/dist/docs/starter.js +11 -0
  298. package/vendor/doxbrix-import/dist/importer.d.ts +227 -0
  299. package/vendor/doxbrix-import/dist/importer.js +1567 -0
  300. package/vendor/doxbrix-import/dist/mintlify-openapi.d.ts +37 -0
  301. package/vendor/doxbrix-import/dist/mintlify-openapi.js +305 -0
  302. package/vendor/doxbrix-import/dist/safe-path.d.ts +9 -0
  303. package/vendor/doxbrix-import/dist/safe-path.js +47 -0
  304. package/dist/agents.d.ts.map +0 -1
  305. package/dist/agents.js.map +0 -1
  306. package/dist/args.d.ts.map +0 -1
  307. package/dist/args.js.map +0 -1
  308. package/dist/artifact-deploy.d.ts.map +0 -1
  309. package/dist/artifact-deploy.js.map +0 -1
  310. package/dist/auth.d.ts.map +0 -1
  311. package/dist/auth.js.map +0 -1
  312. package/dist/author.d.ts.map +0 -1
  313. package/dist/author.js.map +0 -1
  314. package/dist/capture.d.ts.map +0 -1
  315. package/dist/capture.js.map +0 -1
  316. package/dist/cli.d.ts.map +0 -1
  317. package/dist/cli.js.map +0 -1
  318. package/dist/deploy.d.ts.map +0 -1
  319. package/dist/deploy.js.map +0 -1
  320. package/dist/deployment-visibility.d.ts.map +0 -1
  321. package/dist/deployment-visibility.js.map +0 -1
  322. package/dist/doctor.d.ts.map +0 -1
  323. package/dist/doctor.js.map +0 -1
  324. package/dist/doxbrix-markdown.d.ts.map +0 -1
  325. package/dist/doxbrix-markdown.js.map +0 -1
  326. package/dist/errors.d.ts.map +0 -1
  327. package/dist/errors.js.map +0 -1
  328. package/dist/fs.d.ts.map +0 -1
  329. package/dist/fs.js.map +0 -1
  330. package/dist/generator-api.d.ts.map +0 -1
  331. package/dist/generator-api.js.map +0 -1
  332. package/dist/generator-manager.d.ts.map +0 -1
  333. package/dist/generator-manager.js.map +0 -1
  334. package/dist/generator-runtime.d.ts.map +0 -1
  335. package/dist/generator-runtime.js.map +0 -1
  336. package/dist/generators.d.ts.map +0 -1
  337. package/dist/generators.js.map +0 -1
  338. package/dist/interactive.d.ts.map +0 -1
  339. package/dist/interactive.js.map +0 -1
  340. package/dist/preview.d.ts.map +0 -1
  341. package/dist/preview.js.map +0 -1
  342. package/dist/progress.d.ts.map +0 -1
  343. package/dist/progress.js.map +0 -1
  344. package/dist/project.d.ts.map +0 -1
  345. package/dist/project.js.map +0 -1
  346. package/dist/prompts.d.ts.map +0 -1
  347. package/dist/prompts.js.map +0 -1
  348. package/dist/settings.d.ts.map +0 -1
  349. package/dist/settings.js.map +0 -1
  350. package/dist/sync.d.ts.map +0 -1
  351. package/dist/sync.js.map +0 -1
  352. package/dist/types.d.ts.map +0 -1
  353. package/dist/types.js.map +0 -1
  354. package/dist/validation.d.ts.map +0 -1
  355. package/dist/validation.js.map +0 -1
  356. package/dist/version.d.ts.map +0 -1
  357. package/dist/version.js.map +0 -1
package/dist/deploy.js CHANGED
@@ -1,12 +1,21 @@
1
- import { readFile } from 'node:fs/promises';
1
+ import { tmpdir } from 'node:os';
2
+ import { mkdtemp, rm, readFile } from 'node:fs/promises';
3
+ import { join, resolve } from 'node:path';
2
4
  import { apiUrl, authenticatedRequest, authenticatedRequestOptional, } from './auth.js';
3
5
  import { DoxloopError } from './errors.js';
6
+ import { pushDeploymentBundle } from './bundle-upload.js';
4
7
  import { listFiles, resolveContainedDirectory } from './fs.js';
8
+ import { recordDeployment } from './history.js';
5
9
  import { deployGeneratedSite } from './artifact-deploy.js';
10
+ import { packageStaticOutput, writeDryRunArchive } from './artifact-deploy.js';
11
+ import { buildDoxbrixStaticSite } from './doxbrix-build.js';
6
12
  import { deploymentVisibility, updateDeploymentVisibility, } from './deployment-visibility.js';
7
- import { loadPages, loadProject, loadSiteConfig, relativePath, } from './project.js';
13
+ import { loadPages, loadProject, loadSiteConfig, relativePath, ROOT_CONTENT_IGNORED_DIRECTORIES, } from './project.js';
8
14
  import { createStepList, formatDuration } from './progress.js';
9
15
  import { validateProject } from './validation.js';
16
+ import { loadQualityConfig } from './quality-config.js';
17
+ import { readVerificationMetadata } from './quality-claims.js';
18
+ import { publishStaticTarget } from './deploy-targets/index.js';
10
19
  const MEDIA_EXTENSIONS = new Set([
11
20
  '.avif',
12
21
  '.bmp',
@@ -34,12 +43,29 @@ export async function deploy(options) {
34
43
  const project = await loadProject(options.root);
35
44
  const name = options.name?.trim() || project.title;
36
45
  const slug = options.slug?.trim() || slugify(project.title);
46
+ const target = options.target ?? project.deployment?.target ?? 'doxbrix';
47
+ if (target !== 'doxbrix') {
48
+ await publishStaticTarget(target, {
49
+ root: options.root,
50
+ name,
51
+ slug,
52
+ ...(options.dryRun === undefined ? {} : { dryRun: options.dryRun }),
53
+ ...(options.apiUrl ? { apiUrl: options.apiUrl } : {}),
54
+ ...(options.siteId ? { siteId: options.siteId } : {}),
55
+ ...(options.projectId ? { projectId: options.projectId } : {}),
56
+ ...(options.teamId ? { teamId: options.teamId } : {}),
57
+ ...(options.branch ? { branch: options.branch } : {}),
58
+ ...(options.basePath ? { basePath: options.basePath } : {}),
59
+ });
60
+ return;
61
+ }
37
62
  const visibility = deploymentVisibility(options.public);
38
63
  process.stdout.write(`Documentation project:\n ${options.root}\nProduct sources excluded from deployment: ${project.sources.length}\n\n`);
39
64
  if (project.generator !== 'doxbrix') {
40
65
  return deployGeneratedSite({ ...options, name, slug });
41
66
  }
42
67
  const steps = createStepList();
68
+ const startedAt = new Date().toISOString();
43
69
  process.stdout.write(`Deploying "${name}" as ${visibility} → ${apiUrl(options.apiUrl)}\n\n`);
44
70
  try {
45
71
  const validating = steps.start('Validating documentation');
@@ -53,7 +79,20 @@ export async function deploy(options) {
53
79
  const bytes = Buffer.byteLength(JSON.stringify(bundle));
54
80
  building.done('Built bundle', `${count(bundle.pages.length, 'page')}${bundle.media.length > 0 ? `, ${count(bundle.media.length, 'media file')}` : ''}, ${formatBytes(bytes)}`);
55
81
  if (options.dryRun) {
56
- process.stdout.write(`\nDeployment is valid.\nProject: ${name}\nSlug: ${slug}\nVisibility: ${visibility}\nPages: ${bundle.pages.length}\nMedia files: ${bundle.media.length}\nPayload: ${formatBytes(bytes)}\nNo data was uploaded.\n`);
82
+ const temporary = await mkdtemp(join(tmpdir(), 'doxloop-dry-run-'));
83
+ try {
84
+ const staticBuild = await buildDoxbrixStaticSite({
85
+ root: options.root,
86
+ outDir: join(temporary, 'build'),
87
+ ...(process.env.DOXLOOP_SITE_URL ? { siteUrl: process.env.DOXLOOP_SITE_URL } : {}),
88
+ });
89
+ const packaged = await packageStaticOutput(staticBuild.outputDir);
90
+ const archivePath = await writeDryRunArchive(options.root, packaged.archive);
91
+ process.stdout.write(`\nDeployment is valid.\nProject: ${name}\nSlug: ${slug}\nVisibility: ${visibility}\nPages: ${bundle.pages.length}\nMedia files: ${bundle.media.length}\nPayload: ${formatBytes(bytes)}\nArchive: ${archivePath}\nNo data was uploaded.\n`);
92
+ }
93
+ finally {
94
+ await rm(temporary, { recursive: true, force: true });
95
+ }
57
96
  return;
58
97
  }
59
98
  const locating = steps.start('Locating project');
@@ -75,29 +114,59 @@ export async function deploy(options) {
75
114
  locating.done(`Created project "${target.name}" (${target.slug})`);
76
115
  }
77
116
  const publishing = steps.start('Publishing to Doxbrix');
78
- const pushed = await authenticatedRequest(`/api/v1/projects/${encodeURIComponent(target.slug)}/bundle`, {
79
- method: 'POST',
80
- headers: { 'Content-Type': 'application/json' },
81
- body: JSON.stringify({ ...bundle, publish: true }),
82
- }, options.apiUrl);
117
+ const pushed = await pushDeploymentBundle(target.slug, bundle,
118
+ // A deployment bundle is the complete documentation snapshot. Asking
119
+ // Doxbrix to replace the previous snapshot prevents pages and menu
120
+ // items removed locally from surviving on the published site.
121
+ { publish: true, replace: true }, options.apiUrl);
83
122
  const report = pushed.result;
84
- publishing.done('Published', `${count(bundle.pages.length, 'page')} (${report.pagesCreated} created, ${report.pagesUpdated} updated), ${count(report.spaces, 'space')}${bundle.media.length > 0 ? `, ${count(bundle.media.length, 'media file')}` : ''} · ${formatDuration(publishing.durationMs)}`);
123
+ publishing.done('Published', `${count(bundle.pages.length, 'page')} (${report.pagesCreated} created, ${report.pagesUpdated} updated${report.pagesDeleted ? `, ${report.pagesDeleted} removed` : ''}), ${count(report.spaces, 'space')}${bundle.media.length > 0 ? `, ${count(bundle.media.length, 'media file')}` : ''} · ${formatDuration(publishing.durationMs)}`);
85
124
  for (const warning of report.warnings ?? []) {
86
125
  process.stdout.write(`warning: ${warning}\n`);
87
126
  }
88
- process.stdout.write(`\n${apiUrl(options.apiUrl)}/editor?project=${encodeURIComponent(target.slug)}\n`);
127
+ // Doxbrix serves every project's rendered documentation on its own host and
128
+ // reports it as `hostedUrl`. Link readers there, not at the editor; the
129
+ // editor link is only a fallback for a Doxbrix that does not report one.
130
+ const siteUrl = target.hostedUrl
131
+ || `${apiUrl(options.apiUrl)}/editor?project=${encodeURIComponent(target.slug)}`;
132
+ process.stdout.write(`\n${siteUrl}\n`);
133
+ await recordDeployment(options.root, {
134
+ target: 'doxbrix',
135
+ status: 'succeeded',
136
+ startedAt,
137
+ name: target.name,
138
+ slug: target.slug,
139
+ visibility,
140
+ url: siteUrl,
141
+ pagesCount: bundle.pages.length,
142
+ mediaCount: bundle.media.length,
143
+ bytes,
144
+ pagesCreated: report.pagesCreated,
145
+ pagesUpdated: report.pagesUpdated,
146
+ ...(report.pagesDeleted === undefined ? {} : { pagesDeleted: report.pagesDeleted }),
147
+ });
89
148
  }
90
149
  catch (error) {
91
150
  steps.failActive();
151
+ await recordDeployment(options.root, {
152
+ target: 'doxbrix',
153
+ status: 'failed',
154
+ startedAt,
155
+ name,
156
+ slug,
157
+ visibility,
158
+ error: error instanceof Error ? error.message : String(error),
159
+ });
92
160
  throw error;
93
161
  }
94
162
  }
95
163
  export async function buildDeploymentBundle(root, contentDir) {
96
164
  const project = await loadProject(root);
165
+ const qualityConfig = await loadQualityConfig(root);
97
166
  if (contentDir !== project.contentDir) {
98
167
  throw new DoxloopError('Deployment content directory must match .doxloop/project.json.');
99
168
  }
100
- const contentRoot = await resolveContainedDirectory(root, project.contentDir, 'Deployment content directory');
169
+ const contentRoot = await resolveContainedDirectory(root, project.contentDir, 'Deployment content directory', { allowRoot: project.generator === 'doxbrix' });
101
170
  const pages = [];
102
171
  for (const path of await loadPages(root, project)) {
103
172
  pages.push({
@@ -106,14 +175,19 @@ export async function buildDeploymentBundle(root, contentDir) {
106
175
  });
107
176
  }
108
177
  const media = [];
109
- for (const path of await listFiles(contentRoot, MEDIA_EXTENSIONS)) {
178
+ for (const path of await listFiles(contentRoot, MEDIA_EXTENSIONS, {
179
+ ...(contentRoot === resolve(root)
180
+ ? { ignoredDirectories: ROOT_CONTENT_IGNORED_DIRECTORIES }
181
+ : {}),
182
+ })) {
110
183
  media.push({
111
184
  path: relativePath(contentRoot, path),
112
185
  base64: (await readFile(path)).toString('base64'),
113
186
  });
114
187
  }
115
188
  const manifest = await loadSiteConfig(root, project);
116
- return { manifest, basePath: contentDir, pages, media };
189
+ const verification = qualityConfig.readerVerification?.enabled ? await readVerificationMetadata(root) : undefined;
190
+ return { manifest, basePath: contentDir, pages, media, ...(verification ? { verification } : {}) };
117
191
  }
118
192
  function slugify(value) {
119
193
  const slug = value
@@ -0,0 +1,90 @@
1
+ import type { DocumentationPlan, DocumentationPlanPage, DoxloopProject } from './types.js';
2
+ /**
3
+ * Deterministic screenshot capture for navigation-only manifest steps.
4
+ *
5
+ * The LLM agent spends most of a run's wall time driving a browser through
6
+ * MCP: several tool calls and a model turn per image, stale element refs, and
7
+ * retries. A large share of planned captures need none of that — they are the
8
+ * entry screen of a guide or a step that simply opens a route. Doxloop takes
9
+ * those itself with Playwright before the agent starts, records them as
10
+ * verified manifest rows, and leaves only steps that need interaction to the
11
+ * agent. A guide the agent later skips therefore still ends with its entry
12
+ * screen instead of zero captures.
13
+ */
14
+ export interface DeterministicCaptureInput {
15
+ workspace: string;
16
+ /** Uses project.application.{baseUrl, screenshots.viewport}, project.generator, project.contentDir. */
17
+ project: DoxloopProject;
18
+ plan: DocumentationPlan;
19
+ /** Restrict to these plan pages (a batch); default all screenshot-enabled pages. */
20
+ pages?: DocumentationPlanPage[];
21
+ /** Playwright storageState file from prepareCaptureAuth (recorded sign-in session), if any. */
22
+ storageStatePath?: string;
23
+ /**
24
+ * Saved sign-in credentials. When a capture lands on the sign-in page,
25
+ * Doxloop fills the form once for the browser session and retries, so
26
+ * navigation-only steps behind a login no longer all fall to the agent.
27
+ */
28
+ credentials?: {
29
+ username: string;
30
+ password: string;
31
+ };
32
+ /** The application's sign-in route (project.application.authentication.loginPath), default /login. */
33
+ loginPath?: string;
34
+ /** Test seam: replaces the real browser. */
35
+ capturePage?: (url: string) => Promise<CapturedPage>;
36
+ /** Test seam: replaces the real sign-in; resolves to whether the browser is now signed in. */
37
+ signIn?: (loginUrl: string, credentials: {
38
+ username: string;
39
+ password: string;
40
+ }) => Promise<boolean>;
41
+ log?: (line: string) => void;
42
+ /** Overall wall-clock cap; default 4 minutes. */
43
+ timeBudgetMs?: number;
44
+ }
45
+ export interface CapturedPage {
46
+ png: Buffer;
47
+ finalUrl: string;
48
+ status: number | undefined;
49
+ hasPasswordField: boolean;
50
+ title?: string;
51
+ }
52
+ export interface DeterministicCaptureResult {
53
+ captured: Array<{
54
+ page: string;
55
+ step: string;
56
+ file: string;
57
+ }>;
58
+ skipped: Array<{
59
+ page: string;
60
+ step: string;
61
+ reason: string;
62
+ }>;
63
+ }
64
+ /**
65
+ * Decide whether a manifest action only opens a screen.
66
+ *
67
+ * Returns the explicit app-relative path when the action names one, an empty
68
+ * object when it is a bare "open the app" instruction, and `undefined` when
69
+ * the step needs interaction (or does not start by navigating).
70
+ */
71
+ export declare function isNavigationOnlyStep(action: string): {
72
+ path?: string;
73
+ } | undefined;
74
+ /**
75
+ * Resolve the route a step should be captured at, or `undefined` when the step
76
+ * is not navigation-only.
77
+ *
78
+ * The first step of a guide is the entry screen by construction, so it needs
79
+ * no explicit route: `visuals.startPath` stands in when the action carries
80
+ * none. Every later step qualifies only when its action names a route, since
81
+ * a bare "open the dialog" describes interaction, not navigation.
82
+ */
83
+ export declare function resolveStepPath(page: DocumentationPlanPage, step: {
84
+ id: string;
85
+ action: string;
86
+ sequenceItem?: number;
87
+ }, index: number): string | undefined;
88
+ /** Capture every navigation-only planned step with a real browser (or the injected seam). */
89
+ export declare function captureNavigableSteps(input: DeterministicCaptureInput): Promise<DeterministicCaptureResult>;
90
+ //# sourceMappingURL=deterministic-capture.d.ts.map