@bpmnkit/docspack 0.0.1

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 (173) hide show
  1. package/.llms/chunks/cli.casen.aikit-skills.md +19 -0
  2. package/.llms/chunks/cli.casen.bpmn-generation-pipeline.md +32 -0
  3. package/.llms/chunks/cli.casen.connection-profiles.md +62 -0
  4. package/.llms/chunks/cli.casen.generate-bpmn-files.md +28 -0
  5. package/.llms/chunks/cli.casen.md +80 -0
  6. package/.llms/chunks/cli.casen.plugins.md +56 -0
  7. package/.llms/chunks/cli.casen.worker-commands.md +45 -0
  8. package/.llms/chunks/cli.connector.all-flags.md +29 -0
  9. package/.llms/chunks/cli.connector.browse-the-bundled-ootb-catalog.md +32 -0
  10. package/.llms/chunks/cli.connector.built-in-catalog.md +41 -0
  11. package/.llms/chunks/cli.connector.common-workflows.md +50 -0
  12. package/.llms/chunks/cli.connector.generate-from-the-openapi-catalog.md +30 -0
  13. package/.llms/chunks/cli.connector.md +20 -0
  14. package/.llms/chunks/cli.connector.programmatic-usage.md +7 -0
  15. package/.llms/chunks/cli.connector.what-gets-generated.md +20 -0
  16. package/.llms/chunks/cli.generate.definition-mode-ai-scripting-path.md +89 -0
  17. package/.llms/chunks/cli.generate.md +52 -0
  18. package/.llms/chunks/cli.generate.modify-existing-mode-input.md +59 -0
  19. package/.llms/chunks/cli.generate.typical-ai-workflow.md +18 -0
  20. package/.llms/chunks/cli.plugin-authoring.md +59 -0
  21. package/.llms/chunks/cli.plugin-authoring.plugin-naming-conventions.md +11 -0
  22. package/.llms/chunks/cli.plugin-authoring.test-locally.md +41 -0
  23. package/.llms/chunks/cli.plugin-authoring.the-bpmnkit-cli-sdk-sdk.md +82 -0
  24. package/.llms/chunks/cli.plugin-authoring.what-gets-generated.md +69 -0
  25. package/.llms/chunks/cli.plugin-authoring.writing-commands.md +84 -0
  26. package/.llms/chunks/cli.plugins.bpmnkit-casen-report.md +39 -0
  27. package/.llms/chunks/cli.plugins.bpmnkit-casen-worker-http.md +23 -0
  28. package/.llms/chunks/cli.plugins.md +25 -0
  29. package/.llms/chunks/cli.skills.deploy.md +24 -0
  30. package/.llms/chunks/cli.skills.implement.md +36 -0
  31. package/.llms/chunks/cli.skills.md +29 -0
  32. package/.llms/chunks/cli.skills.no-mcp-server-required.md +6 -0
  33. package/.llms/chunks/cli.skills.review.md +33 -0
  34. package/.llms/chunks/cli.skills.test.md +33 -0
  35. package/.llms/chunks/cli.view.folder-support.md +31 -0
  36. package/.llms/chunks/cli.view.md +70 -0
  37. package/.llms/chunks/cli.view.tabbed-navigation.md +28 -0
  38. package/.llms/chunks/getting-started.concepts.ai-compact-format.md +23 -0
  39. package/.llms/chunks/getting-started.concepts.auto-layout.md +24 -0
  40. package/.llms/chunks/getting-started.concepts.parsing-and-serializing.md +26 -0
  41. package/.llms/chunks/getting-started.concepts.the-fluent-builder.md +41 -0
  42. package/.llms/chunks/getting-started.concepts.zeebe-extensions.md +25 -0
  43. package/.llms/chunks/getting-started.installation.md +38 -0
  44. package/.llms/chunks/getting-started.installation.runtime-requirements.md +13 -0
  45. package/.llms/chunks/getting-started.installation.svg-canvas-viewer.md +41 -0
  46. package/.llms/chunks/getting-started.installation.worker-client.md +40 -0
  47. package/.llms/chunks/getting-started.quick-start.md +31 -0
  48. package/.llms/chunks/getting-started.quick-start.step-2-simulate-locally.md +28 -0
  49. package/.llms/chunks/getting-started.quick-start.step-3-deploy-to-camunda-8.md +33 -0
  50. package/.llms/chunks/getting-started.quick-start.what-s-next.md +14 -0
  51. package/.llms/chunks/guides.ai-agents.deploy-grade-validation.md +19 -0
  52. package/.llms/chunks/guides.ai-agents.how-it-s-modeled.md +11 -0
  53. package/.llms/chunks/guides.ai-agents.md +18 -0
  54. package/.llms/chunks/guides.ai-agents.see-also.md +7 -0
  55. package/.llms/chunks/guides.ai-agents.testing-without-a-real-llm-call.md +26 -0
  56. package/.llms/chunks/guides.ai-agents.the-aiagent-plan-step.md +62 -0
  57. package/.llms/chunks/guides.ai-implement.deploying.md +49 -0
  58. package/.llms/chunks/guides.ai-implement.extending-an-existing-process.md +10 -0
  59. package/.llms/chunks/guides.ai-implement.lightweight-alternative-casen-skills-install.md +28 -0
  60. package/.llms/chunks/guides.ai-implement.md +32 -0
  61. package/.llms/chunks/guides.ai-implement.the-claude-code-plugin.md +21 -0
  62. package/.llms/chunks/guides.ai.claude-api-example.md +41 -0
  63. package/.llms/chunks/guides.ai.mcp-server.md +20 -0
  64. package/.llms/chunks/guides.ai.md +32 -0
  65. package/.llms/chunks/guides.ai.minimal-empty-diagram.md +32 -0
  66. package/.llms/chunks/guides.ai.openai-function-calling.md +40 -0
  67. package/.llms/chunks/guides.building-processes.boundary-events.md +47 -0
  68. package/.llms/chunks/guides.building-processes.call-activities.md +47 -0
  69. package/.llms/chunks/guides.building-processes.events.md +57 -0
  70. package/.llms/chunks/guides.building-processes.multi-instance.md +20 -0
  71. package/.llms/chunks/guides.building-processes.service-tasks.md +39 -0
  72. package/.llms/chunks/guides.building-processes.sub-processes.md +40 -0
  73. package/.llms/chunks/guides.building-processes.task-defaults.md +18 -0
  74. package/.llms/chunks/guides.claude-code-plugin.ambient-hooks.md +24 -0
  75. package/.llms/chunks/guides.claude-code-plugin.configuration.md +126 -0
  76. package/.llms/chunks/guides.claude-code-plugin.md +47 -0
  77. package/.llms/chunks/guides.claude-code-plugin.reference-docs.md +61 -0
  78. package/.llms/chunks/guides.deployment.ci-cd-deploy-on-push.md +47 -0
  79. package/.llms/chunks/guides.deployment.deploying-a-process.md +52 -0
  80. package/.llms/chunks/guides.deployment.handling-jobs.md +50 -0
  81. package/.llms/chunks/guides.deployment.managing-incidents.md +33 -0
  82. package/.llms/chunks/guides.deployment.md +49 -0
  83. package/.llms/chunks/guides.gateways.branching-inside-sub-processes.md +27 -0
  84. package/.llms/chunks/guides.gateways.exclusive-gateway-xor.md +41 -0
  85. package/.llms/chunks/guides.gateways.inclusive-gateway-or.md +43 -0
  86. package/.llms/chunks/guides.gateways.nested-branching.md +27 -0
  87. package/.llms/chunks/guides.gateways.parallel-gateway-and.md +26 -0
  88. package/.llms/chunks/guides.patterns.how-matching-works.md +17 -0
  89. package/.llms/chunks/guides.patterns.md +26 -0
  90. package/.llms/chunks/guides.patterns.pattern-schema.md +38 -0
  91. package/.llms/chunks/guides.patterns.see-also.md +7 -0
  92. package/.llms/chunks/guides.patterns.using-patterns-from-the-cli.md +30 -0
  93. package/.llms/chunks/guides.patterns.what-a-pattern-contains.md +18 -0
  94. package/.llms/chunks/guides.simulation.dmn-decision-evaluation.md +51 -0
  95. package/.llms/chunks/guides.simulation.instance-state.md +29 -0
  96. package/.llms/chunks/guides.simulation.md +51 -0
  97. package/.llms/chunks/guides.simulation.message-correlation.md +30 -0
  98. package/.llms/chunks/guides.simulation.multiple-deployments.md +14 -0
  99. package/.llms/chunks/guides.workers-standalone.anatomy-of-a-worker.md +42 -0
  100. package/.llms/chunks/guides.workers-standalone.camunda-saas.md +43 -0
  101. package/.llms/chunks/guides.workers-standalone.environment-variables.md +14 -0
  102. package/.llms/chunks/guides.workers-standalone.md +35 -0
  103. package/.llms/chunks/guides.workers-standalone.running-workers.md +61 -0
  104. package/.llms/chunks/guides.workers-standalone.see-also.md +7 -0
  105. package/.llms/chunks/packages.api.incident-resolution.md +31 -0
  106. package/.llms/chunks/packages.api.observability-events.md +13 -0
  107. package/.llms/chunks/packages.api.overview.md +49 -0
  108. package/.llms/chunks/packages.api.process-operations.md +60 -0
  109. package/.llms/chunks/packages.api.resource-namespaces.md +20 -0
  110. package/.llms/chunks/packages.canvas.events.md +56 -0
  111. package/.llms/chunks/packages.canvas.options.md +24 -0
  112. package/.llms/chunks/packages.canvas.overview.md +35 -0
  113. package/.llms/chunks/packages.connector-gen.body-expansion.md +18 -0
  114. package/.llms/chunks/packages.connector-gen.catalog-reference.md +54 -0
  115. package/.llms/chunks/packages.connector-gen.catalogentry-type.md +21 -0
  116. package/.llms/chunks/packages.connector-gen.generating-from-the-catalog.md +44 -0
  117. package/.llms/chunks/packages.connector-gen.installation.md +42 -0
  118. package/.llms/chunks/packages.connector-gen.lower-level-api.md +31 -0
  119. package/.llms/chunks/packages.connector-gen.overview.md +16 -0
  120. package/.llms/chunks/packages.connector-gen.writeoptions.md +26 -0
  121. package/.llms/chunks/packages.core.dmn-support.md +36 -0
  122. package/.llms/chunks/packages.core.installation-bpmn.creatediagram-id.md +18 -0
  123. package/.llms/chunks/packages.core.installation-bpmn.createprocess-id-name.md +10 -0
  124. package/.llms/chunks/packages.core.installation-bpmn.export-definitions.md +10 -0
  125. package/.llms/chunks/packages.core.installation-bpmn.makeempty-processid-processname.md +11 -0
  126. package/.llms/chunks/packages.core.installation-bpmn.parse-xml.md +10 -0
  127. package/.llms/chunks/packages.core.installation-bpmn.sample_xml.md +7 -0
  128. package/.llms/chunks/packages.core.installation-compactify-definitions.md +13 -0
  129. package/.llms/chunks/packages.core.installation-expand-compact.md +13 -0
  130. package/.llms/chunks/packages.core.installation-layoutprocess-process.md +15 -0
  131. package/.llms/chunks/packages.core.installation-processbuilder-methods.md +29 -0
  132. package/.llms/chunks/packages.core.installation.md +11 -0
  133. package/.llms/chunks/packages.core.overview.md +15 -0
  134. package/.llms/chunks/packages.docspack.installation.md +45 -0
  135. package/.llms/chunks/packages.docspack.overview.md +23 -0
  136. package/.llms/chunks/packages.docspack.reading-it-yourself.md +34 -0
  137. package/.llms/chunks/packages.docspack.trust.md +13 -0
  138. package/.llms/chunks/packages.docspack.using-the-index-directly.md +52 -0
  139. package/.llms/chunks/packages.editor.basic-setup.md +41 -0
  140. package/.llms/chunks/packages.editor.full-editor-with-all-plugins.md +30 -0
  141. package/.llms/chunks/packages.editor.hud-options.md +41 -0
  142. package/.llms/chunks/packages.editor.overview.md +21 -0
  143. package/.llms/chunks/packages.engine.installation.md +77 -0
  144. package/.llms/chunks/packages.engine.overview.md +19 -0
  145. package/.llms/chunks/packages.engine.processinstance.md +17 -0
  146. package/.llms/chunks/packages.engine.variable-scoping.md +27 -0
  147. package/.llms/chunks/packages.worker-client.client.poll-jobtype-options.md +40 -0
  148. package/.llms/chunks/packages.worker-client.createworkerclient-options.md +32 -0
  149. package/.llms/chunks/packages.worker-client.job.complete-variables.md +29 -0
  150. package/.llms/chunks/packages.worker-client.md +33 -0
  151. package/.llms/chunks/packages.worker-client.oauth2-camunda-saas.md +26 -0
  152. package/.llms/chunks/packages.worker-client.see-also.md +7 -0
  153. package/.llms/manifest.json +2083 -0
  154. package/LICENSE +21 -0
  155. package/README.md +150 -0
  156. package/dist/build.d.ts +29 -0
  157. package/dist/build.js +89 -0
  158. package/dist/chunk.d.ts +41 -0
  159. package/dist/chunk.js +242 -0
  160. package/dist/cli.d.ts +9 -0
  161. package/dist/cli.js +160 -0
  162. package/dist/index.d.ts +13 -0
  163. package/dist/index.js +12 -0
  164. package/dist/load.d.ts +27 -0
  165. package/dist/load.js +144 -0
  166. package/dist/search.d.ts +53 -0
  167. package/dist/search.js +104 -0
  168. package/dist/text.d.ts +22 -0
  169. package/dist/text.js +204 -0
  170. package/dist/types.d.ts +48 -0
  171. package/dist/types.js +3 -0
  172. package/llms.txt +174 -0
  173. package/package.json +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 urbanisierung
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,150 @@
1
+ <div align="center">
2
+ <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="72" height="72" alt="BPMN Kit logo"></a>
3
+ <h1>@bpmnkit/docspack</h1>
4
+ <p>BPMN Kit documentation as an offline, version-locked docspack package with a built-in search CLI for AI agents</p>
5
+
6
+ [![npm](https://img.shields.io/npm/v/@bpmnkit/docspack?style=flat-square&color=6244d7)](https://www.npmjs.com/package/@bpmnkit/docspack)
7
+ [![license](https://img.shields.io/npm/l/@bpmnkit/docspack?style=flat-square)](https://github.com/bpmnkit/monorepo/blob/main/LICENSE)
8
+ [![typescript](https://img.shields.io/badge/TypeScript-strict-6244d7?style=flat-square&logo=typescript&logoColor=white)](https://github.com/bpmnkit/monorepo)
9
+ [![ai-assisted](https://img.shields.io/badge/AI--assisted-claude-8b5cf6?style=flat-square)](https://github.com/bpmnkit/monorepo)
10
+ [![experimental](https://img.shields.io/badge/status-experimental-f59e0b?style=flat-square)](https://github.com/bpmnkit/monorepo)
11
+
12
+ [Website](https://bpmnkit.com) · [Documentation](https://docs.bpmnkit.com) · [GitHub](https://github.com/bpmnkit/monorepo) · [Changelog](https://github.com/bpmnkit/monorepo/blob/main/packages/docspack/CHANGELOG.md)
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## Overview
18
+
19
+ `@bpmnkit/docspack` ships the BPMN Kit documentation the way an AI agent can actually use it: as an npm package whose version tracks the docs, indexed locally and searched offline.
20
+
21
+ An agent installs it, asks a question, and gets back the two or three passages that answer it — not a whole documentation site, and not whatever the model remembers about an older release.
22
+
23
+ It follows the [docspack package format](https://docspack.dev/spec), so the upstream `docspack` CLI discovers and indexes it like any other vendor pack. The bundled `bpmnkit-docs` command does the same job with no extra tooling.
24
+
25
+ ```
26
+ Markdown docs → chunks + manifest → BM25 index → three passages
27
+ ```
28
+
29
+ ## Features
30
+
31
+ - **Offline** — `ask`, `search` and `list` read the filesystem only. No server, no network call, nothing resident between questions
32
+ - **Version-locked** — the installed `package.json` version wins over the manifest, so an agent reads the docs for the release it has
33
+ - **Bounded answers** — three chunks and 3,000 tokens by default, budgeted from the manifest before any content is read
34
+ - **Real retrieval** — BM25 over chunk text with Porter stemming, so `authenticate` finds a passage that only says `authentication`; tags and API identifiers weigh 3× prose
35
+ - **docspack-compatible** — `.llms/manifest.json` validates against `https://docspack.dev/schema/v1.json`
36
+ - **Safe by construction** — a manifest is untrusted input: chunk paths that escape `.llms/` are refused, and community packages are labelled
37
+ - **Zero runtime dependencies**
38
+
39
+ ## Installation
40
+
41
+ ```sh
42
+ npm install -D @bpmnkit/docspack
43
+ ```
44
+
45
+ ## Quick Start
46
+
47
+ Give an agent one line in `AGENTS.md` or `CLAUDE.md`:
48
+
49
+ ```
50
+ Run \`npx bpmnkit-docs ask "<question>"\` for BPMN Kit documentation.
51
+ It answers from the version this project installed.
52
+ ```
53
+
54
+ Then:
55
+
56
+ ```sh
57
+ npx bpmnkit-docs ask "how do I deploy a process to Camunda 8"
58
+ npx bpmnkit-docs search "exclusive gateway"
59
+ npx bpmnkit-docs list
60
+ ```
61
+
62
+ ```
63
+ ## @bpmnkit/docspack@0.0.1/getting-started.quick-start.step-3-deploy-and-run
64
+
65
+ # Quick Start — Step 3: Deploy and run
66
+ ...
67
+
68
+ ---
69
+ cost: 1,204 tokens, capped at 3,000
70
+ ```
71
+
72
+ ## API Reference
73
+
74
+ ```typescript
75
+ // Discover and index every docs package installed under a directory
76
+ function discoverPacks(cwd?: string): Pack[]
77
+ function indexPacks(packs: readonly Pack[]): DocsIndex
78
+
79
+ // Rank chunks, or take the top ones that fit a token budget
80
+ function search(index: DocsIndex, query: string, options?: SearchOptions): SearchHit[]
81
+ function answer(
82
+ index: DocsIndex,
83
+ query: string,
84
+ options?: AnswerOptions,
85
+ ): { hits: SearchHit[]; tokens: number; maxTokens: number }
86
+
87
+ interface SearchOptions {
88
+ limit?: number // chunks to return. Default: 3
89
+ packs?: readonly string[] // restrict to these package names
90
+ }
91
+
92
+ interface AnswerOptions extends SearchOptions {
93
+ maxTokens?: number // ceiling for an answer. Default: 3000
94
+ }
95
+
96
+ // Generate a .llms/ payload from a directory of Markdown
97
+ function buildPack(options: BuildOptions): BuildResult
98
+
99
+ // Read one package, validating it the way a consumer must
100
+ function loadPack(dir: string): Pack
101
+ ```
102
+
103
+ ### CLI
104
+
105
+ | Command | Purpose |
106
+ | --- | --- |
107
+ | `bpmnkit-docs ask <question>` | Answer from the installed docs packages — the command to give an agent |
108
+ | `bpmnkit-docs search <query>` | Rank matching chunks, for reading in a terminal |
109
+ | `bpmnkit-docs list` | Show the docs packages found and their index state |
110
+ | `bpmnkit-docs build` | Regenerate this package's `.llms/` payload from the docs source |
111
+
112
+ Options: `--limit <n>`, `--max-tokens <n>`, `--pack <name>`, `--cwd <dir>`.
113
+
114
+ ---
115
+
116
+ ## Related Packages
117
+
118
+ | Package | Description |
119
+ |---------|-------------|
120
+ | [`@bpmnkit/core`](https://www.npmjs.com/package/@bpmnkit/core) | BPMN/DMN/Form parser, builder, layout engine |
121
+ | [`@bpmnkit/canvas`](https://www.npmjs.com/package/@bpmnkit/canvas) | Zero-dependency SVG BPMN viewer |
122
+ | [`@bpmnkit/editor`](https://www.npmjs.com/package/@bpmnkit/editor) | Full-featured interactive BPMN editor |
123
+ | [`@bpmnkit/engine`](https://www.npmjs.com/package/@bpmnkit/engine) | Lightweight BPMN process execution engine |
124
+ | [`@bpmnkit/feel`](https://www.npmjs.com/package/@bpmnkit/feel) | FEEL expression language parser & evaluator |
125
+ | [`@bpmnkit/plugins`](https://www.npmjs.com/package/@bpmnkit/plugins) | 22 composable canvas plugins |
126
+ | [`@bpmnkit/api`](https://www.npmjs.com/package/@bpmnkit/api) | Camunda 8 REST API TypeScript client |
127
+ | [`@bpmnkit/ascii`](https://www.npmjs.com/package/@bpmnkit/ascii) | Render BPMN diagrams as Unicode ASCII art |
128
+ | [`@bpmnkit/ui`](https://www.npmjs.com/package/@bpmnkit/ui) | Shared design tokens and UI components |
129
+ | [`@bpmnkit/profiles`](https://www.npmjs.com/package/@bpmnkit/profiles) | Shared auth, profile storage, and client factories for CLI & proxy |
130
+ | [`@bpmnkit/operate`](https://www.npmjs.com/package/@bpmnkit/operate) | Monitoring & operations frontend for Camunda clusters |
131
+ | [`@bpmnkit/connector-gen`](https://www.npmjs.com/package/@bpmnkit/connector-gen) | Generate connector templates from OpenAPI specs |
132
+ | [`@bpmnkit/connectors`](https://www.npmjs.com/package/@bpmnkit/connectors) | Camunda 8 OOTB connector catalog and deterministic template application |
133
+ | [`@bpmnkit/cli`](https://www.npmjs.com/package/@bpmnkit/cli) | Camunda 8 command-line interface (casen) |
134
+ | [`@bpmnkit/proxy`](https://www.npmjs.com/package/@bpmnkit/proxy) | Local AI bridge and Camunda API proxy server |
135
+ | [`@bpmnkit/patterns`](https://www.npmjs.com/package/@bpmnkit/patterns) | Domain process patterns for BPMNKit AIKit |
136
+ | [`@bpmnkit/reebe-wasm`](https://www.npmjs.com/package/@bpmnkit/reebe-wasm) | WebAssembly BPMN engine for browser simulation |
137
+ | [`@bpmnkit/worker-client`](https://www.npmjs.com/package/@bpmnkit/worker-client) | Thin Zeebe REST client for standalone workers |
138
+ | [`@bpmnkit/cli-sdk`](https://www.npmjs.com/package/@bpmnkit/cli-sdk) | Plugin authoring SDK for the casen CLI |
139
+ | [`@bpmnkit/create-casen-plugin`](https://www.npmjs.com/package/@bpmnkit/create-casen-plugin) | Scaffold a new casen CLI plugin in seconds |
140
+ | [`@bpmnkit/casen-report`](https://www.npmjs.com/package/@bpmnkit/casen-report) | HTML reports from Camunda 8 incident and SLA data |
141
+ | [`@bpmnkit/casen-worker-http`](https://www.npmjs.com/package/@bpmnkit/casen-worker-http) | Example HTTP worker plugin — completes jobs with live JSONPlaceholder API data |
142
+ | [`@bpmnkit/casen-worker-ai`](https://www.npmjs.com/package/@bpmnkit/casen-worker-ai) | AI task worker — classify, summarize, extract, and decide using Claude |
143
+
144
+ ## License
145
+
146
+ [MIT](https://github.com/bpmnkit/monorepo/blob/main/LICENSE) © BPMN Kit — made by [u11g](https://u11g.com)
147
+
148
+ <div align="center">
149
+ <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="32" height="32" alt="BPMN Kit"></a>
150
+ </div>
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Generating the `.llms/` payload from a directory of Markdown.
3
+ *
4
+ * The output is what gets published: `.llms/chunks/*.md`, `.llms/manifest.json`
5
+ * and an `llms.txt` table of contents at the package root.
6
+ */
7
+ export declare const SCHEMA_URL = "https://docspack.dev/schema/v1.json";
8
+ export interface BuildOptions {
9
+ /** Directory of Markdown documents, walked recursively. */
10
+ source: string;
11
+ /** Package root — `.llms/` and `llms.txt` are written here. */
12
+ packDir: string;
13
+ name: string;
14
+ version: string;
15
+ /** Libraries this package documents, each `name` or `name@version`. */
16
+ documents: string[];
17
+ description?: string;
18
+ /** Base URL each chunk links back to. */
19
+ siteUrl?: string;
20
+ maxTokens?: number;
21
+ minTokens?: number;
22
+ }
23
+ export interface BuildResult {
24
+ documents: number;
25
+ chunks: number;
26
+ tokens: number;
27
+ }
28
+ export declare function buildPack(options: BuildOptions): BuildResult;
29
+ //# sourceMappingURL=build.d.ts.map
package/dist/build.js ADDED
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Generating the `.llms/` payload from a directory of Markdown.
3
+ *
4
+ * The output is what gets published: `.llms/chunks/*.md`, `.llms/manifest.json`
5
+ * and an `llms.txt` table of contents at the package root.
6
+ */
7
+ import { mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
8
+ import { join, relative, resolve } from "node:path";
9
+ import { chunkDocument, uniqueId } from "./chunk.js";
10
+ export const SCHEMA_URL = "https://docspack.dev/schema/v1.json";
11
+ export function buildPack(options) {
12
+ const source = resolve(options.source);
13
+ const packDir = resolve(options.packDir);
14
+ const files = markdownFiles(source);
15
+ if (files.length === 0)
16
+ throw new Error(`${source}: no Markdown documents found`);
17
+ const built = [];
18
+ const ids = new Set();
19
+ for (const file of files) {
20
+ const slug = relative(source, file)
21
+ .replace(/\.mdx?$/, "")
22
+ .split(/[\\/]/)
23
+ .join("/");
24
+ const chunks = chunkDocument({ slug, markdown: readFileSync(file, "utf8") }, {
25
+ maxTokens: options.maxTokens,
26
+ minTokens: options.minTokens,
27
+ ...(options.siteUrl ? { siteUrl: options.siteUrl } : {}),
28
+ });
29
+ for (const chunk of chunks)
30
+ built.push({ ...chunk, id: uniqueId(chunk.id, ids) });
31
+ }
32
+ const chunksDir = join(packDir, ".llms", "chunks");
33
+ rmSync(chunksDir, { recursive: true, force: true });
34
+ mkdirSync(chunksDir, { recursive: true });
35
+ for (const chunk of built)
36
+ writeFileSync(join(chunksDir, `${chunk.id}.md`), chunk.body);
37
+ const manifest = {
38
+ $schema: SCHEMA_URL,
39
+ name: options.name,
40
+ version: options.version,
41
+ documents: options.documents,
42
+ chunks: built.map((chunk) => ({
43
+ id: chunk.id,
44
+ file: `chunks/${chunk.id}.md`,
45
+ tokens: chunk.tokens,
46
+ tags: chunk.tags,
47
+ entities: chunk.entities,
48
+ })),
49
+ };
50
+ writeFileSync(join(packDir, ".llms", "manifest.json"), `${JSON.stringify(manifest, null, "\t")}\n`);
51
+ writeFileSync(join(packDir, "llms.txt"), tableOfContents(options, built));
52
+ return {
53
+ documents: files.length,
54
+ chunks: built.length,
55
+ tokens: built.reduce((sum, chunk) => sum + chunk.tokens, 0),
56
+ };
57
+ }
58
+ /** The human-readable table of contents the format requires at the package root. */
59
+ function tableOfContents(options, chunks) {
60
+ const lines = [`# ${options.name}`, ""];
61
+ if (options.description)
62
+ lines.push(`> ${options.description}`, "");
63
+ lines.push(`Version ${options.version}. ${chunks.length} chunks documenting ${options.documents.join(", ")}.`, "", "```sh", `npm i -D ${options.name}`, `npx bpmnkit-docs ask "how do I deploy a process"`, "```", "");
64
+ const groups = new Map();
65
+ for (const chunk of chunks) {
66
+ const group = chunk.id.includes(".") ? (chunk.id.split(".")[0] ?? "docs") : "docs";
67
+ groups.set(group, [...(groups.get(group) ?? []), chunk]);
68
+ }
69
+ for (const [group, entries] of [...groups].sort(([a], [b]) => a.localeCompare(b))) {
70
+ lines.push(`## ${group}`, "");
71
+ for (const chunk of entries) {
72
+ lines.push(`- [${chunk.title}](.llms/chunks/${chunk.id}.md) — ${chunk.tokens} tokens`);
73
+ }
74
+ lines.push("");
75
+ }
76
+ return lines.join("\n");
77
+ }
78
+ function markdownFiles(dir) {
79
+ const out = [];
80
+ for (const name of readdirSync(dir).sort()) {
81
+ const path = join(dir, name);
82
+ if (statSync(path).isDirectory())
83
+ out.push(...markdownFiles(path));
84
+ else if (name.endsWith(".md"))
85
+ out.push(path);
86
+ }
87
+ return out;
88
+ }
89
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Splitting Markdown into retrievable chunks.
3
+ *
4
+ * A chunk is one `##` section: the unit a reader would have scrolled to anyway.
5
+ * Sections too large for the budget are subdivided at `###` and then at paragraph
6
+ * boundaries; sections too small to stand alone are merged with the next one, so
7
+ * reference tables do not become one chunk per row.
8
+ */
9
+ /** A Markdown file to be chunked, identified by its slug under the docs root. */
10
+ export interface SourceDoc {
11
+ /** Path relative to the docs root without extension, e.g. `guides/ai-agents`. */
12
+ slug: string;
13
+ markdown: string;
14
+ }
15
+ /** A chunk before it is written: the manifest entry and the file body together. */
16
+ export interface BuiltChunk {
17
+ id: string;
18
+ title: string;
19
+ tags: string[];
20
+ entities: string[];
21
+ /** Markdown written to `.llms/chunks/<id>.md`. */
22
+ body: string;
23
+ tokens: number;
24
+ }
25
+ export interface ChunkOptions {
26
+ /** Subdivide a section above this many tokens. */
27
+ maxTokens?: number;
28
+ /** Merge a section below this many tokens into the next one. */
29
+ minTokens?: number;
30
+ /** Base URL used for the source link at the foot of each chunk. */
31
+ siteUrl?: string;
32
+ }
33
+ /** Split one document into chunks. */
34
+ export declare function chunkDocument(doc: SourceDoc, options?: ChunkOptions): BuiltChunk[];
35
+ /**
36
+ * Make `id` unique against `used`, recording it. Ids are unique within a document
37
+ * by construction, but two documents can still land on the same one — a page
38
+ * `cli/casen` and a `## casen` section of a page `cli` both want `cli.casen`.
39
+ */
40
+ export declare function uniqueId(id: string, used: Set<string>): string;
41
+ //# sourceMappingURL=chunk.d.ts.map
package/dist/chunk.js ADDED
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Splitting Markdown into retrievable chunks.
3
+ *
4
+ * A chunk is one `##` section: the unit a reader would have scrolled to anyway.
5
+ * Sections too large for the budget are subdivided at `###` and then at paragraph
6
+ * boundaries; sections too small to stand alone are merged with the next one, so
7
+ * reference tables do not become one chunk per row.
8
+ */
9
+ import { STOP_WORDS, estimateTokens, tokenize } from "./text.js";
10
+ const FRONT_MATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
11
+ const DIRECTIVE = /^<!--\s*docspack:\s*(tags|entities)\s*=\s*(.+?)\s*-->\s*$/;
12
+ /** Split one document into chunks. */
13
+ export function chunkDocument(doc, options = {}) {
14
+ const maxTokens = options.maxTokens ?? 800;
15
+ const minTokens = options.minTokens ?? 120;
16
+ const { attributes, body } = parseFrontMatter(doc.markdown);
17
+ const title = attributes.title ?? titleFromSlug(doc.slug);
18
+ const docTags = attributes.tags ?? [];
19
+ const merged = mergeSmall(splitByHeading(body, 2), minTokens);
20
+ const chunks = [];
21
+ const used = new Set();
22
+ for (const section of merged) {
23
+ for (const part of subdivide(section, maxTokens)) {
24
+ const text = part.lines.join("\n").trim();
25
+ if (text === "")
26
+ continue;
27
+ const directives = readDirectives(part.lines);
28
+ const chunkTitle = part.heading === "" ? title : `${title} — ${part.heading}`;
29
+ const source = options.siteUrl ? `\n\n---\nSource: ${options.siteUrl}/${doc.slug}/` : "";
30
+ const bodyText = `# ${chunkTitle}\n\n${stripDirectives(text)}${source}\n`;
31
+ chunks.push({
32
+ id: uniqueId(makeId(doc.slug, part.heading), used),
33
+ title: chunkTitle,
34
+ tags: dedupe([
35
+ ...docTags,
36
+ ...directives.tags,
37
+ ...doc.slug.split("/"),
38
+ ...headingTags(part.heading),
39
+ ]).slice(0, 12),
40
+ entities: dedupe([...directives.entities, ...extractEntities(text)]).slice(0, 12),
41
+ body: bodyText,
42
+ tokens: estimateTokens(bodyText),
43
+ });
44
+ }
45
+ }
46
+ return chunks;
47
+ }
48
+ /** Parse the leading YAML front matter. Only the keys a chunk needs are read. */
49
+ function parseFrontMatter(markdown) {
50
+ const match = FRONT_MATTER.exec(markdown);
51
+ if (!match?.[1])
52
+ return { attributes: {}, body: markdown };
53
+ const attributes = {};
54
+ for (const line of match[1].split(/\r?\n/)) {
55
+ const pair = /^(title|tags):\s*(.*)$/.exec(line);
56
+ if (!pair?.[1])
57
+ continue;
58
+ const value = (pair[2] ?? "").trim();
59
+ if (pair[1] === "title")
60
+ attributes.title = unquote(value);
61
+ else
62
+ attributes.tags = value
63
+ .replace(/^\[|\]$/g, "")
64
+ .split(",")
65
+ .map(unquote)
66
+ .filter(Boolean);
67
+ }
68
+ return { attributes, body: markdown.slice(match[0].length) };
69
+ }
70
+ function unquote(value) {
71
+ return value
72
+ .trim()
73
+ .replace(/^["']|["']$/g, "")
74
+ .trim();
75
+ }
76
+ /**
77
+ * Split on ATX headings of exactly `level`, ignoring anything inside a fenced
78
+ * code block — a `## comment` in a shell sample is not a section.
79
+ */
80
+ function splitByHeading(body, level) {
81
+ const marker = new RegExp(`^#{${level}}\\s+(.+?)\\s*$`);
82
+ const sections = [{ heading: "", lines: [] }];
83
+ let fence = null;
84
+ for (const line of body.split(/\r?\n/)) {
85
+ const fenceMatch = /^\s*(```+|~~~+)/.exec(line);
86
+ if (fenceMatch?.[1]) {
87
+ if (fence === null)
88
+ fence = fenceMatch[1][0] ?? null;
89
+ else if (line.trimStart().startsWith(fence))
90
+ fence = null;
91
+ }
92
+ const heading = fence === null ? marker.exec(line) : null;
93
+ if (heading?.[1])
94
+ sections.push({ heading: heading[1], lines: [] });
95
+ else
96
+ sections[sections.length - 1]?.lines.push(line);
97
+ }
98
+ return sections.filter((s) => s.heading !== "" || s.lines.join("").trim() !== "");
99
+ }
100
+ /** Merge each section that is too short to answer anything into the one after it. */
101
+ function mergeSmall(sections, minTokens) {
102
+ const out = [];
103
+ for (const section of sections) {
104
+ const previous = out[out.length - 1];
105
+ if (previous && estimateTokens(previous.lines.join("\n")) < minTokens) {
106
+ previous.lines.push("", section.heading === "" ? "" : `## ${section.heading}`, ...section.lines);
107
+ continue;
108
+ }
109
+ out.push({ heading: section.heading, lines: [...section.lines] });
110
+ }
111
+ return out;
112
+ }
113
+ /** Break an oversized section at `###`, then at paragraph boundaries. */
114
+ function subdivide(section, maxTokens) {
115
+ if (estimateTokens(section.lines.join("\n")) <= maxTokens)
116
+ return [section];
117
+ const parts = [];
118
+ for (const sub of splitByHeading(section.lines.join("\n"), 3)) {
119
+ const heading = sub.heading === "" ? section.heading : `${section.heading} — ${sub.heading}`;
120
+ parts.push(...byParagraph({ heading, lines: sub.lines }, maxTokens));
121
+ }
122
+ return parts.length > 0 ? parts : [section];
123
+ }
124
+ /** Last resort: pack whole paragraphs until the budget is spent, never mid-fence. */
125
+ function byParagraph(section, maxTokens) {
126
+ if (estimateTokens(section.lines.join("\n")) <= maxTokens)
127
+ return [section];
128
+ const parts = [];
129
+ let current = [];
130
+ let fence = null;
131
+ const flush = () => {
132
+ if (current.join("").trim() === "")
133
+ return;
134
+ const suffix = parts.length === 0 ? "" : ` (${parts.length + 1})`;
135
+ parts.push({ heading: `${section.heading}${suffix}`, lines: current });
136
+ current = [];
137
+ };
138
+ for (const line of section.lines) {
139
+ const fenceMatch = /^\s*(```+|~~~+)/.exec(line);
140
+ if (fenceMatch?.[1]) {
141
+ if (fence === null)
142
+ fence = fenceMatch[1][0] ?? null;
143
+ else if (line.trimStart().startsWith(fence))
144
+ fence = null;
145
+ }
146
+ if (fence === null && line.trim() === "" && estimateTokens(current.join("\n")) >= maxTokens) {
147
+ flush();
148
+ continue;
149
+ }
150
+ current.push(line);
151
+ }
152
+ flush();
153
+ return parts;
154
+ }
155
+ function readDirectives(lines) {
156
+ const tags = [];
157
+ const entities = [];
158
+ for (const line of lines) {
159
+ const match = DIRECTIVE.exec(line.trim());
160
+ if (!match?.[2])
161
+ continue;
162
+ const values = match[2]
163
+ .split(",")
164
+ .map((v) => v.trim())
165
+ .filter(Boolean);
166
+ if (match[1] === "tags")
167
+ tags.push(...values);
168
+ else
169
+ entities.push(...values);
170
+ }
171
+ return { tags, entities };
172
+ }
173
+ function stripDirectives(text) {
174
+ return text
175
+ .split(/\r?\n/)
176
+ .filter((line) => !DIRECTIVE.test(line.trim()))
177
+ .join("\n")
178
+ .trim();
179
+ }
180
+ /** Heading words carry the topic; function words carry nothing worth weighting 3x. */
181
+ function headingTags(heading) {
182
+ return tokenize(heading).filter((word) => word.length > 2 && !STOP_WORDS.has(word));
183
+ }
184
+ /**
185
+ * Identifiers named in inline code. A bare word in backticks is usually a value,
186
+ * not an API, so only qualified, called or camel-cased names are kept.
187
+ */
188
+ function extractEntities(text) {
189
+ const found = [];
190
+ for (const match of text.matchAll(/`([^`\n]{2,60})`/g)) {
191
+ const value = (match[1] ?? "").trim();
192
+ if (!/^@?[A-Za-z][\w./-]*(\(\))?$/.test(value))
193
+ continue;
194
+ if (!/[./]/.test(value) && !value.endsWith("()") && !/[a-z][A-Z]/.test(value))
195
+ continue;
196
+ found.push(value);
197
+ }
198
+ return found;
199
+ }
200
+ function makeId(slug, heading) {
201
+ const base = slugify(slug.replace(/\//g, "."));
202
+ const section = slugify(heading);
203
+ return section === "" ? base : `${base}.${section}`;
204
+ }
205
+ /** Reduce to the manifest's `^[A-Za-z0-9][A-Za-z0-9._-]*$`. */
206
+ function slugify(value) {
207
+ return value
208
+ .toLowerCase()
209
+ .replace(/[^a-z0-9._-]+/g, "-")
210
+ .replace(/-{2,}/g, "-")
211
+ .replace(/^[^a-z0-9]+|[-._]+$/g, "");
212
+ }
213
+ /**
214
+ * Make `id` unique against `used`, recording it. Ids are unique within a document
215
+ * by construction, but two documents can still land on the same one — a page
216
+ * `cli/casen` and a `## casen` section of a page `cli` both want `cli.casen`.
217
+ */
218
+ export function uniqueId(id, used) {
219
+ const base = id === "" ? "chunk" : id;
220
+ let candidate = base;
221
+ for (let n = 2; used.has(candidate); n++)
222
+ candidate = `${base}-${n}`;
223
+ used.add(candidate);
224
+ return candidate;
225
+ }
226
+ function titleFromSlug(slug) {
227
+ const last = slug.split("/").pop() ?? slug;
228
+ return last.replace(/[-_]+/g, " ").replace(/\b[a-z]/g, (c) => c.toUpperCase());
229
+ }
230
+ function dedupe(values) {
231
+ const seen = new Set();
232
+ const out = [];
233
+ for (const value of values) {
234
+ const key = value.toLowerCase();
235
+ if (value === "" || seen.has(key))
236
+ continue;
237
+ seen.add(key);
238
+ out.push(value);
239
+ }
240
+ return out;
241
+ }
242
+ //# sourceMappingURL=chunk.js.map
package/dist/cli.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `bpmnkit-docs` — read the installed documentation packages and answer from them.
4
+ *
5
+ * Every command reads the filesystem only. There is no server, no network call
6
+ * and nothing resident between questions.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=cli.d.ts.map