@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
@@ -0,0 +1,54 @@
1
+ export interface PageComment {
2
+ id: string;
3
+ path: string;
4
+ text: string;
5
+ createdAt: string;
6
+ proposalId?: string;
7
+ changeId?: string;
8
+ hunkId?: string;
9
+ resolvedAt?: string;
10
+ }
11
+ export declare function pageComments(root: string): Promise<PageComment[]>;
12
+ export declare function savePageComment(root: string, input: {
13
+ path: string;
14
+ text: string;
15
+ proposalId?: string;
16
+ changeId?: string;
17
+ hunkId?: string;
18
+ resolveId?: string;
19
+ }): Promise<PageComment[]>;
20
+ export declare function searchPageText(root: string, query: string): Promise<{
21
+ path: string;
22
+ title: string;
23
+ line: number;
24
+ section: string;
25
+ excerpt: string;
26
+ route: string;
27
+ }[]>;
28
+ export declare function auditDocumentation(root: string): Promise<{
29
+ generator: import("./types.js").GeneratorName;
30
+ contentDir: string;
31
+ pages: import("./pages.js").PageSummary[];
32
+ unmapped: string[];
33
+ unverified: string[];
34
+ drift: import("./types.js").DriftResult;
35
+ configuration: {
36
+ file: string;
37
+ text: string;
38
+ }[];
39
+ message: string;
40
+ }>;
41
+ export declare function backfillEvidence(root: string): Promise<import("./direct-edit.js").DirectEditResult>;
42
+ export declare function readerVerification(root: string, enabled?: boolean): Promise<import("./direct-edit.js").DirectEditResult | {
43
+ enabled: boolean;
44
+ }>;
45
+ export declare function authoringEstimate(root: string, pages: number, agent?: string, model?: string): Promise<{
46
+ message: string;
47
+ cost: string;
48
+ range?: {
49
+ minimumMinutes: number;
50
+ maximumMinutes: number;
51
+ };
52
+ samples: number;
53
+ }>;
54
+ //# sourceMappingURL=workspace-tools.d.ts.map
@@ -0,0 +1,123 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { readFile, writeFile, mkdir, rename } from 'node:fs/promises';
3
+ import { join, relative } from 'node:path';
4
+ import { applyDirectEdit, safePath } from './direct-edit.js';
5
+ import { computeDrift } from './drift.js';
6
+ import { readEvidenceMap, EVIDENCE_MAP_FILE } from './evidence.js';
7
+ import { DoxloopError } from './errors.js';
8
+ import { listRequests } from './history.js';
9
+ import { listPages, resolveEditScope } from './pages.js';
10
+ import { loadPages, loadProject } from './project.js';
11
+ import { withProjectLock } from './project-lock.js';
12
+ import { readSyncRun } from './sync-runs.js';
13
+ import { loadQualityConfig, QUALITY_CONFIG_FILE } from './quality-config.js';
14
+ import { reverifyClaims, VERIFICATION_METADATA_FILE } from './quality-claims.js';
15
+ const COMMENTS = '.doxloop/comments.json';
16
+ export async function pageComments(root) {
17
+ try {
18
+ return JSON.parse(await readFile(await safePath(root, COMMENTS), 'utf8'));
19
+ }
20
+ catch (error) {
21
+ if (error.code === 'ENOENT')
22
+ return [];
23
+ throw error;
24
+ }
25
+ }
26
+ export async function savePageComment(root, input) {
27
+ return withProjectLock(root, 'write', async () => {
28
+ const comments = await pageComments(root);
29
+ if (input.resolveId) {
30
+ const item = comments.find((comment) => comment.id === input.resolveId);
31
+ if (!item)
32
+ throw new DoxloopError('Comment was not found.');
33
+ item.resolvedAt = new Date().toISOString();
34
+ }
35
+ else {
36
+ if (!input.text.trim() || input.text.length > 8000)
37
+ throw new DoxloopError('Write a comment of 1–8000 characters.');
38
+ if (input.proposalId) {
39
+ const run = await readSyncRun(root, input.proposalId);
40
+ const change = run.changes.find((item) => item.id === input.changeId && item.path === input.path);
41
+ if (!change || (input.hunkId && !change.hunks.some((hunk) => hunk.id === input.hunkId)))
42
+ throw new DoxloopError('Select a valid proposal file or hunk.');
43
+ }
44
+ else
45
+ await resolveEditScope(root, await loadProject(root), [input.path], false);
46
+ comments.push({ id: randomUUID(), path: input.path, text: input.text.trim(), createdAt: new Date().toISOString(), ...(input.proposalId ? { proposalId: input.proposalId, changeId: input.changeId } : {}), ...(input.hunkId ? { hunkId: input.hunkId } : {}) });
47
+ }
48
+ const target = await safePath(root, COMMENTS);
49
+ await mkdir(join(root, '.doxloop'), { recursive: true });
50
+ const temporary = `${target}.${randomUUID()}.tmp`;
51
+ await writeFile(temporary, JSON.stringify(comments, null, 2) + '\n', { mode: 0o600 });
52
+ await rename(temporary, target);
53
+ return comments;
54
+ });
55
+ }
56
+ export async function searchPageText(root, query) {
57
+ if (!query.trim())
58
+ return [];
59
+ const term = query.trim().toLocaleLowerCase().slice(0, 300);
60
+ const project = await loadProject(root);
61
+ const pages = await listPages(root);
62
+ const results = [];
63
+ for (const page of pages) {
64
+ const lines = (await readFile(await safePath(root, page.path), 'utf8')).split('\n');
65
+ let section = page.title;
66
+ for (let index = 0; index < lines.length; index++) {
67
+ const line = lines[index];
68
+ const heading = /^#{1,6}\s+(.+)|<h[1-6][^>]*>(.*?)<\/h[1-6]>/i.exec(line);
69
+ if (heading)
70
+ section = (heading[1] ?? heading[2]).replace(/<[^>]+>/g, '');
71
+ if (line.toLocaleLowerCase().includes(term))
72
+ results.push({ path: page.path, title: page.title, line: index + 1, section, excerpt: line.trim().slice(0, 240), route: page.route });
73
+ if (results.length >= 200)
74
+ return results;
75
+ }
76
+ }
77
+ return results;
78
+ }
79
+ export async function auditDocumentation(root) {
80
+ const project = await loadProject(root);
81
+ const [pages, evidence, drift] = await Promise.all([listPages(root), readEvidenceMap(root), computeDrift(root, project)]);
82
+ const nativeFiles = project.generator === 'docusaurus' ? ['versions.json', 'docusaurus.config.js', 'docusaurus.config.ts'] : project.generator === 'mkdocs' ? ['mkdocs.yml', 'mkdocs.yaml'] : [];
83
+ const configuration = [];
84
+ for (const file of nativeFiles) {
85
+ try {
86
+ configuration.push({ file, text: (await readFile(await safePath(root, file), 'utf8')).slice(0, 10000) });
87
+ }
88
+ catch (error) {
89
+ if (error.code !== 'ENOENT')
90
+ throw error;
91
+ }
92
+ }
93
+ return { generator: project.generator, contentDir: project.contentDir, pages, unmapped: pages.filter((page) => !evidence?.pages[page.path]).map((page) => page.path), unverified: pages.filter((page) => page.evidence !== 'verified').map((page) => page.path), drift, configuration, message: 'Read-only audit. No pages, source baselines, or verification claims were changed. Backfill adds missing pages as unverified; it does not infer source associations.' };
94
+ }
95
+ export async function backfillEvidence(root) {
96
+ return withProjectLock(root, 'write', async () => {
97
+ const map = await readEvidenceMap(root) ?? { schemaVersion: 1, pages: {} };
98
+ const files = await loadPages(root, await loadProject(root));
99
+ for (const file of files) {
100
+ const path = relative(root, file).replace(/\\/g, '/');
101
+ map.pages[path] ??= { sources: [], confidence: 'needs-human' };
102
+ }
103
+ return applyDirectEdit(root, { kind: 'metadata', requestText: 'Backfilled unverified evidence entries without rewriting documentation', files: [EVIDENCE_MAP_FILE], apply: async () => { await writeFile(await safePath(root, EVIDENCE_MAP_FILE), JSON.stringify(map, null, 2) + '\n'); } });
104
+ });
105
+ }
106
+ export async function readerVerification(root, enabled) {
107
+ const config = await loadQualityConfig(root);
108
+ if (enabled === undefined)
109
+ return { enabled: config.readerVerification?.enabled ?? false };
110
+ return applyDirectEdit(root, { kind: 'metadata', requestText: `${enabled ? 'Enabled' : 'Disabled'} reader verification labels`, files: [QUALITY_CONFIG_FILE, VERIFICATION_METADATA_FILE], apply: async () => {
111
+ const current = await loadQualityConfig(root);
112
+ current.readerVerification = { ...current.readerVerification, enabled };
113
+ await writeFile(await safePath(root, QUALITY_CONFIG_FILE), JSON.stringify(current, null, 2) + '\n');
114
+ await reverifyClaims(root, await loadProject(root), true);
115
+ } });
116
+ }
117
+ export async function authoringEstimate(root, pages, agent, model) {
118
+ const samples = (await listRequests(root, 200)).filter((run) => run.status === 'completed' && ['create', 'update'].includes(run.kind) && run.durationMs && run.pagesChanged > 0 && (!agent || run.agent === agent) && (!model || run.model === model));
119
+ const rates = samples.map((run) => run.durationMs / run.pagesChanged / 60000).sort((a, b) => a - b);
120
+ const range = rates.length >= 3 ? { minimumMinutes: Math.ceil(rates[Math.floor((rates.length - 1) * .2)] * pages), maximumMinutes: Math.ceil(rates[Math.ceil((rates.length - 1) * .8)] * pages) } : undefined;
121
+ return { samples: rates.length, ...(range ? { range } : {}), message: range ? 'Observed 20th–80th percentile duration per changed page, scaled to this batch. Screenshots and source complexity can increase time.' : 'At least three comparable completed runs are needed for an observed time range. Your time limit is a cap, not an estimate.', cost: 'Billing is controlled by your agent provider. Doxloop has no reliable usage-price data for this run.' };
122
+ }
123
+ //# sourceMappingURL=workspace-tools.js.map
@@ -1,41 +1,63 @@
1
1
  # Agent compatibility
2
2
 
3
- Doxloop supports Codex, Claude Code, and Gemini CLI. It discovers executables on
4
- `PATH` or accepts an explicit `--agent`.
3
+ Doxloop works with Codex, Claude Code, and Gemini CLI. It discovers the
4
+ executables installed on the machine and lists all three wherever you choose a
5
+ coding assistant: the **Tools** step of the setup wizard, the **Planning
6
+ agent** field on the Create and Update pages, and **Default documentation
7
+ agent** under **Settings → General**.
8
+
9
+ Selecting an assistant that is not installed offers to install its official
10
+ npm package globally. Doxloop verifies that the new executable is available and
11
+ then continues. The agent uses its own existing sign-in; Doxloop never accepts
12
+ or stores a model API key.
5
13
 
6
14
  ## Invocation modes
7
15
 
8
16
  | Workflow | Codex | Claude Code | Gemini CLI |
9
17
  | --- | --- | --- | --- |
10
- | Create/update | Interactive prompt | Interactive prompt | Interactive `-i` prompt |
11
- | Review | Read-only ephemeral execution | Print with plan permissions | Plan approval mode |
12
- | External IDE | `--print` prepared prompt | `--print` prepared prompt | `--print` prepared prompt |
13
-
14
- Review is deliberately non-interactive so it can remain read-only. Create may
15
- pause once for consolidated reader or scope decisions.
16
-
17
- Doxloop forwards `--model` using each CLI's native model option. The
18
- `--reasoning` option is Codex-only and accepts `minimal`, `low`, `medium`,
19
- `high`, or `xhigh`.
18
+ | Planning | Read-only research run | Read-only research run | Read-only research run |
19
+ | Generation and revision | Unattended run in an isolated proposal workspace | Unattended run in an isolated proposal workspace | Unattended run in an isolated proposal workspace |
20
+ | Guide screenshots | Run-scoped Playwright browser passed on the command line | Run-scoped Playwright browser passed on the command line | Run-scoped Playwright browser merged into the workspace's `.gemini/settings.json` and trusted for the run |
21
+ | External sources | Read through a sandbox that denies writes | Read through a sandbox that denies writes | **Limited.** Gemini cannot be denied writes to an extra directory, so an unattended run reads a throwaway copy of each local folder (beside the remote snapshots under `.doxloop-sources`) and never sees the real checkout |
22
+ | Spending cap | Not available | `--max-budget-usd` from **Maximum Claude spend** | Not available |
23
+ | Live activity log | Formatted from `codex exec --json` | Formatted from the stream-json output | Formatted from `--output-format stream-json` |
24
+ | Stage progress | From tool calls and file writes | From tool calls and file writes | From tool calls and file writes |
25
+ | Sign-in check | `codex login status` | `claude auth status` | **Limited.** Checks for an API key or Vertex AI project in the environment, or the Google sign-in token file; nothing is read beyond presence |
26
+ | Validation during a run | Commands allowed by the sandbox | Commands allowed by the sandbox | **Limited.** Only the `doxloop` CLI is pre-approved; other commands need a confirmation an unattended run cannot give |
27
+
28
+ The same matrix is shown in the setup wizard's **Tools** step and under
29
+ **Settings → General**, with **Limited** marking each row where an assistant
30
+ is not at parity.
31
+
32
+ Planning may pause for consolidated reader or scope decisions; these appear
33
+ under **Needs your decision** on the plan, and the **Planner questions**
34
+ setting controls whether the planner asks in review, uses recommendations, or
35
+ always waits for answers.
36
+
37
+ The **Model** field forwards the chosen model using each assistant's native
38
+ model option. Reasoning effort is available for Codex and Claude Code; the
39
+ picker limits the choices to the values the selected model supports.
20
40
 
21
41
  ## Project skills
22
42
 
23
- Initialization installs the shared authoring skill and selected format skill
24
- under `.agents/skills` for Codex and Gemini and `.claude/skills` for Claude
25
- Code. Use:
26
-
27
- ```bash
28
- doxloop agent status
29
- doxloop agent update
30
- ```
31
-
32
- `review` does not install or replace skills because that would mutate the
33
- project. Run `doxloop agent setup` before review if skills were removed.
43
+ Creating a workspace installs the shared authoring skill and the selected
44
+ generator's format skill under `.agents/skills` for Codex and Gemini and
45
+ `.claude/skills` for Claude Code. Every planning and generation run checks
46
+ those skills against the packaged version and refreshes them when the package
47
+ was upgraded. A skill with local edits is not overwritten silently: the run
48
+ stops with a message naming the changed directory. Delete or restore that
49
+ directory and start the run again.
34
50
 
35
51
  ## Compatibility policy
36
52
 
37
- Agent CLIs evolve independently. Release checks validate argument construction,
38
- and optional real-agent evaluations exercise installed CLIs. A release should
39
- record the tested CLI versions in its release notes. When an invocation fails,
40
- run the agent directly to confirm its installed version and then use
41
- `doxloop create --print` as a version-independent fallback.
53
+ Agent CLIs evolve independently. Release checks validate argument
54
+ construction, and optional real-agent evaluations exercise installed
55
+ assistants. A release should record the tested versions in its release notes.
56
+ When a run fails as soon as the assistant starts, open **Open full log** in
57
+ **Live activity** to see the assistant's own output, then confirm the
58
+ installed version by running the assistant directly.
59
+
60
+ For automated tests only, `DOXLOOP_AGENT_EXECUTABLE_CODEX`,
61
+ `DOXLOOP_AGENT_EXECUTABLE_CLAUDE`, and `DOXLOOP_AGENT_EXECUTABLE_GEMINI` can
62
+ point Doxloop at a fake executable instead of searching `PATH`. Production
63
+ workflows should rely on the installed assistant executable.
@@ -1,66 +1,105 @@
1
- # CI and automation
2
-
3
- Deterministic validation is suitable for pull requests. Agent authoring is
4
- optional because it may require credentials, model access, and interactive
5
- decisions.
6
-
7
- ## Validate in CI
8
-
9
- ```bash
10
- pnpm install --frozen-lockfile
11
- doxloop test
12
- ```
13
-
14
- `doxloop test` exits with status 1 when validation errors remain. Warnings are
15
- reported but do not change the exit status.
16
-
17
- Use structured output when another tool consumes the result:
18
-
19
- ```bash
20
- doxloop test --format json > doxloop-validation.json
21
- doxloop status --format json
22
- ```
23
-
24
- Run the selected generator's strict build after Doxloop validation. Obtain the
25
- command and output directory with:
26
-
27
- ```bash
28
- doxloop generator doctor
29
- doxloop generator info <generator>
30
- ```
31
-
32
- ## Agent evaluations
33
-
34
- ```bash
35
- pnpm eval:agents -- --agent codex --case cli
36
- ```
37
-
38
- Real-agent evaluations run reviews in read-only/plan mode. A case must:
39
-
40
- - exit successfully;
41
- - identify the required behavior signals;
42
- - cite enough configured source evidence;
43
- - prioritize findings;
44
- - report a score out of 100; and
45
- - leave the fixture project byte-for-byte unchanged.
46
-
47
- Evaluation output is written below the Git-ignored `evals/results/` directory.
48
- Use a scheduled or manually approved job for model-backed evaluations; keep the
49
- deterministic typecheck, tests, skill validation, build, and package checks on
50
- every pull request.
51
-
52
- ## Publishing
53
-
54
- Never run `doxloop deploy` in an untrusted pull-request context. Use protected
55
- environments and short-lived or scoped credentials. Run `doxloop deploy
56
- --dry-run` before an approved deployment.
57
-
58
- Project identity, slug, destination, and visibility can be committed through
59
- `doxloop settings`. An approved non-interactive job then runs:
60
-
61
- ```bash
62
- doxloop deploy --yes
63
- ```
64
-
65
- Use `doxloop deploy --public --yes` only when the job is explicitly authorized
66
- to override the saved visibility and publish to everyone.
1
+ # Automation and CI
2
+
3
+ Doxloop automates documentation maintenance from the control center. Monitoring
4
+ watches the product repository, drafts a proposal when pages go stale, and
5
+ leaves the decision to a reviewer. Hosted continuous integration is a separate,
6
+ narrower concern: a runner has no signed-in coding agent and no browser, so it
7
+ can only run deterministic checks.
8
+
9
+ ## Doxloop's own CI
10
+
11
+ The Doxloop repository runs `.github/workflows/ci.yml` on every pull request:
12
+ typecheck, the unit suite, skill validation, and a matrix that scaffolds,
13
+ previews, and builds every official generator with `scripts/ci-generator-smoke.mjs`.
14
+ `pnpm test` no longer triggers the full build; it compiles the core and the
15
+ generator packages only (`pnpm run build:test`), and the UI bundle is built by
16
+ `pnpm run build`.
17
+
18
+ ## Automate maintenance with Monitoring
19
+
20
+ Open **Sources** and choose **Monitoring**. The dialog asks for:
21
+
22
+ - **Product branch**: the branch documentation follows.
23
+ - **Schedule**: daily, weekdays, weekly, monthly, or a custom interval in
24
+ minutes or hours. Times use the device timezone.
25
+ - **Advanced watch scope and budgets**: watched paths, ignored paths, the
26
+ maximum agent minutes and runs per day, the maximum Claude spend per run in
27
+ US dollars (Claude Code only; Codex and Gemini have no spending flag), how
28
+ many days verified evidence may age before it is re-verified, and whether
29
+ expired verification warns or fails validation. The agent-minutes budget
30
+ also bounds planning; `DOXLOOP_PLAN_TIMEOUT_MINUTES` overrides it for
31
+ planning alone, and both default to 20 minutes for the planner.
32
+
33
+ **Save and install** registers a local OS scheduled job using launchd,
34
+ systemd or cron, or Windows Task Scheduler. On macOS, Doxloop smoke-tests the
35
+ new job in the real scheduler context before reporting success, including
36
+ whether the background process can find the coding agent. Other platforms
37
+ verify that the native schedule was installed.
38
+
39
+ Each cycle compares the documented commit with the provider's branch head
40
+ through the provider's read-only API. When the commit changed, Doxloop asks for
41
+ the changed-file list, downloads that exact commit as isolated evidence, and
42
+ checks which pages the change made stale. Current documentation records a quiet
43
+ no-op and starts no agent. Stale documentation starts the coding agent already
44
+ signed in on the machine, in an isolated workspace, and the result appears as a
45
+ proposal under **Review**. Monitoring never clones, fetches, commits, pushes, or
46
+ changes hooks in a source checkout, never edits the real documentation before a
47
+ reviewer accepts it, and never publishes.
48
+
49
+ Scheduled monitoring works with every source type. A Git repository source is
50
+ checked through the provider's API. A local folder is checked in place: a Git
51
+ checkout by its HEAD commit and working tree, any other folder by the file
52
+ digests recorded at the last sync, so even a plain folder can name the files
53
+ that changed. Private GitHub repositories use the environment variable named
54
+ by the source's `tokenEnv` setting, `GITHUB_TOKEN` by default, which is read
55
+ at runtime and never saved.
56
+
57
+ Every cycle computes what to do from the current repository state rather than
58
+ from the event that triggered it, so a missed, delayed, or duplicated run costs
59
+ time but never correctness.
60
+
61
+ ## Check status and run a cycle
62
+
63
+ The **Sources** page shows each connected source with its last check time and
64
+ a **Test connection** action. **Home** shows when the loop was last
65
+ checked and whether a proposal needs review. In the Monitoring dialog, **Check
66
+ now** starts one cycle as a visible job: its live log is under **Plan**, and
67
+ when it finishes a notice reports whether anything changed, how many pages
68
+ are stale, and which proposal was drafted. **Disable** removes the schedule
69
+ while keeping the saved settings for later.
70
+
71
+ ## Review background proposals
72
+
73
+ Background proposals stay pending until reviewed. Open **Review** to see every
74
+ proposal with its trigger and status. Each file shows the current version
75
+ beside the proposed version, rendered the way the published site renders them,
76
+ with changed words highlighted. The source view shows line-level context with
77
+ an **Accept change** button on each change. Only accepted changes are applied:
78
+ current file fingerprints are verified and the selected result is validated
79
+ before the actual documentation is touched.
80
+
81
+ ## Publish from the control center
82
+
83
+ Publishing is always an explicit action on the **Publish** page. Sign in to
84
+ Doxbrix with your browser, choose **Public** or **Private**, then choose
85
+ **Publish to Doxbrix**. Every publish validates and builds first and uploads
86
+ nothing if a check fails. Sites are private unless you choose otherwise.
87
+
88
+ ## Headless checks for hosted CI
89
+
90
+ A hosted runner cannot open the control center or run a signed-in coding
91
+ agent, so keep it limited to deterministic checks that need no agent, no model,
92
+ and no credentials. The Doxloop package exposes three headless checks for that
93
+ purpose, each with a `--format json` option and a non-zero exit status on
94
+ failure:
95
+
96
+ | Check | Purpose |
97
+ | --- | --- |
98
+ | `doxloop check` | Report the pages a source change made stale, using the committed evidence map and the provider branch. |
99
+ | `doxloop test` | Validate pages, navigation, links, metadata, code fences, and page depth. Errors fail; warnings do not. |
100
+ | `doxloop quality` | Run the versioned release-quality contract, including the generator's strict build. See [release quality](./release-quality.md). |
101
+
102
+ Keep authoring on machines where a coding agent is signed in: a developer
103
+ workstation or a self-hosted runner on hardware the team controls. Never deploy
104
+ from an untrusted pull-request context; use protected environments and
105
+ short-lived, scoped credentials.
@@ -122,7 +122,8 @@ The request body is:
122
122
  "media": [
123
123
  {"path": "assets/logo.svg", "base64": "…"}
124
124
  ],
125
- "publish": true
125
+ "publish": true,
126
+ "replace": true
126
127
  }
127
128
  ```
128
129
 
@@ -133,6 +134,12 @@ Only the manifest and files under the configured documentation directory may
133
134
  be represented in the payload; configured product-source directories must
134
135
  never be included.
135
136
 
137
+ Set `replace` to `true` when the bundle is the complete source of truth. The
138
+ server then removes pages, navigation items, and spaces that existed in the
139
+ previous bundle but are absent from this one. Doxloop deployments always use
140
+ this mode so deleting or renaming a local page cannot leave stale published
141
+ content behind.
142
+
136
143
  This endpoint is the native Doxbrix generator boundary. Do not send external
137
144
  generator output to it; use the artifact deployment API below.
138
145
 
@@ -0,0 +1,80 @@
1
+ # Rewrite existing documentation
2
+
3
+ Doxloop can start from the documentation you already publish. Add the site's
4
+ address as an **Existing documentation** source, on its own or next to source
5
+ code and API specifications. The agent audits the existing pages, verifies
6
+ them against your product sources, and rewrites them as a new professional
7
+ documentation set that you review page by page and deploy to Doxbrix.
8
+
9
+ ## Add the site
10
+
11
+ 1. Start `doxloop ui`. In the setup wizard's **Sources** step, or on the
12
+ **Sources** page of an open workspace, choose **Add source** → **Existing
13
+ documentation**.
14
+ 2. Enter the public address of the documentation, for example
15
+ `https://docs.example.com` or a section such as
16
+ `https://example.com/docs/`. The address sets the crawl scope: only pages
17
+ under that path on the same host are read.
18
+ 3. Choose **Crawl site**. Doxloop discovers pages through the site's
19
+ `sitemap.xml`, `llms.txt`, and the links between pages, converts each page
20
+ to Markdown, and shows how many pages and words it read, the generator it
21
+ detected, sample titles, and any broken links or skipped URLs.
22
+ 4. Choose **Add source**. Add product code or an OpenAPI specification as
23
+ further sources when you have them; they decide the facts.
24
+
25
+ From the command line, `doxloop init my-docs --docs https://docs.example.com
26
+ --source product=../my-app` and `doxloop create --docs <url> --output <dir>`
27
+ do the same.
28
+
29
+ Doxloop reads the site as a visitor. It executes no scripts, follows
30
+ `robots.txt`, stops after three redirects, limits pages to 2 MB, and reads at
31
+ most 150 pages by default (500 at most). Only public HTTP(S) addresses are
32
+ accepted; localhost and private networks are refused. A documentation site
33
+ behind the same sign-in as the captured application reuses the browser
34
+ session recorded under **Application sign-in**; the cookies are matched by
35
+ domain, so an unrelated site receives nothing.
36
+
37
+ ## What the agent does with it
38
+
39
+ The crawled pages become a read-only snapshot beside your other materialized
40
+ sources, outside the documentation project, so the old content can never be
41
+ published by accident. The snapshot holds one Markdown file per page with its
42
+ original URL, plus an `index.md` that lists every page.
43
+
44
+ During planning the agent audits the existing documentation and the plan shows
45
+ the result under **Existing documentation audit**:
46
+
47
+ - **Not covered today** — product surfaces found in your source code that the
48
+ existing documentation never explains. Each gets a planned page.
49
+ - **Contradicted by the product** — existing claims your sources disprove. The
50
+ rewrite corrects them.
51
+ - **Obsolete** — pages or claims about behavior the product no longer has.
52
+ - **Kept from the existing docs** — knowledge code cannot show (policies,
53
+ environment notes, support-born troubleshooting) that the rewrite carries
54
+ over.
55
+ - **Findings** with a severity, and a decision for every crawled page:
56
+ rewrite, merge into a planned page, preserve, or drop with the reason.
57
+
58
+ Approve, edit, or send the plan back for revision as usual. When you approve,
59
+ Doxloop records a redirect from every existing page route to the page that
60
+ absorbs it, so the preview and the Doxbrix build honor the old addresses.
61
+
62
+ ## With and without product sources
63
+
64
+ With source code or an API specification connected, the product decides the
65
+ facts. The agent writes corrected facts, never repeats a contradicted claim,
66
+ and lists every correction in its summary.
67
+
68
+ With only the documentation site connected, the agent restructures, clarifies,
69
+ deduplicates, and deepens what the existing pages already say, but does not
70
+ add facts they do not support. Every page is recorded with `inferred`
71
+ confidence and shows as unverified until you connect a product source and run
72
+ an update, which verifies the claims against the code.
73
+
74
+ ## Keep the snapshot current
75
+
76
+ The snapshot is frozen at crawl time. On the **Sources** page, the globe
77
+ action re-crawls the site; the next update names the existing pages that
78
+ changed since the last crawl so the agent can decide whether the rewritten
79
+ documentation must follow. A stale snapshot on disk shows as **Needs
80
+ attention** in the source's status.