@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.
- package/.llms/chunks/cli.casen.aikit-skills.md +19 -0
- package/.llms/chunks/cli.casen.bpmn-generation-pipeline.md +32 -0
- package/.llms/chunks/cli.casen.connection-profiles.md +62 -0
- package/.llms/chunks/cli.casen.generate-bpmn-files.md +28 -0
- package/.llms/chunks/cli.casen.md +80 -0
- package/.llms/chunks/cli.casen.plugins.md +56 -0
- package/.llms/chunks/cli.casen.worker-commands.md +45 -0
- package/.llms/chunks/cli.connector.all-flags.md +29 -0
- package/.llms/chunks/cli.connector.browse-the-bundled-ootb-catalog.md +32 -0
- package/.llms/chunks/cli.connector.built-in-catalog.md +41 -0
- package/.llms/chunks/cli.connector.common-workflows.md +50 -0
- package/.llms/chunks/cli.connector.generate-from-the-openapi-catalog.md +30 -0
- package/.llms/chunks/cli.connector.md +20 -0
- package/.llms/chunks/cli.connector.programmatic-usage.md +7 -0
- package/.llms/chunks/cli.connector.what-gets-generated.md +20 -0
- package/.llms/chunks/cli.generate.definition-mode-ai-scripting-path.md +89 -0
- package/.llms/chunks/cli.generate.md +52 -0
- package/.llms/chunks/cli.generate.modify-existing-mode-input.md +59 -0
- package/.llms/chunks/cli.generate.typical-ai-workflow.md +18 -0
- package/.llms/chunks/cli.plugin-authoring.md +59 -0
- package/.llms/chunks/cli.plugin-authoring.plugin-naming-conventions.md +11 -0
- package/.llms/chunks/cli.plugin-authoring.test-locally.md +41 -0
- package/.llms/chunks/cli.plugin-authoring.the-bpmnkit-cli-sdk-sdk.md +82 -0
- package/.llms/chunks/cli.plugin-authoring.what-gets-generated.md +69 -0
- package/.llms/chunks/cli.plugin-authoring.writing-commands.md +84 -0
- package/.llms/chunks/cli.plugins.bpmnkit-casen-report.md +39 -0
- package/.llms/chunks/cli.plugins.bpmnkit-casen-worker-http.md +23 -0
- package/.llms/chunks/cli.plugins.md +25 -0
- package/.llms/chunks/cli.skills.deploy.md +24 -0
- package/.llms/chunks/cli.skills.implement.md +36 -0
- package/.llms/chunks/cli.skills.md +29 -0
- package/.llms/chunks/cli.skills.no-mcp-server-required.md +6 -0
- package/.llms/chunks/cli.skills.review.md +33 -0
- package/.llms/chunks/cli.skills.test.md +33 -0
- package/.llms/chunks/cli.view.folder-support.md +31 -0
- package/.llms/chunks/cli.view.md +70 -0
- package/.llms/chunks/cli.view.tabbed-navigation.md +28 -0
- package/.llms/chunks/getting-started.concepts.ai-compact-format.md +23 -0
- package/.llms/chunks/getting-started.concepts.auto-layout.md +24 -0
- package/.llms/chunks/getting-started.concepts.parsing-and-serializing.md +26 -0
- package/.llms/chunks/getting-started.concepts.the-fluent-builder.md +41 -0
- package/.llms/chunks/getting-started.concepts.zeebe-extensions.md +25 -0
- package/.llms/chunks/getting-started.installation.md +38 -0
- package/.llms/chunks/getting-started.installation.runtime-requirements.md +13 -0
- package/.llms/chunks/getting-started.installation.svg-canvas-viewer.md +41 -0
- package/.llms/chunks/getting-started.installation.worker-client.md +40 -0
- package/.llms/chunks/getting-started.quick-start.md +31 -0
- package/.llms/chunks/getting-started.quick-start.step-2-simulate-locally.md +28 -0
- package/.llms/chunks/getting-started.quick-start.step-3-deploy-to-camunda-8.md +33 -0
- package/.llms/chunks/getting-started.quick-start.what-s-next.md +14 -0
- package/.llms/chunks/guides.ai-agents.deploy-grade-validation.md +19 -0
- package/.llms/chunks/guides.ai-agents.how-it-s-modeled.md +11 -0
- package/.llms/chunks/guides.ai-agents.md +18 -0
- package/.llms/chunks/guides.ai-agents.see-also.md +7 -0
- package/.llms/chunks/guides.ai-agents.testing-without-a-real-llm-call.md +26 -0
- package/.llms/chunks/guides.ai-agents.the-aiagent-plan-step.md +62 -0
- package/.llms/chunks/guides.ai-implement.deploying.md +49 -0
- package/.llms/chunks/guides.ai-implement.extending-an-existing-process.md +10 -0
- package/.llms/chunks/guides.ai-implement.lightweight-alternative-casen-skills-install.md +28 -0
- package/.llms/chunks/guides.ai-implement.md +32 -0
- package/.llms/chunks/guides.ai-implement.the-claude-code-plugin.md +21 -0
- package/.llms/chunks/guides.ai.claude-api-example.md +41 -0
- package/.llms/chunks/guides.ai.mcp-server.md +20 -0
- package/.llms/chunks/guides.ai.md +32 -0
- package/.llms/chunks/guides.ai.minimal-empty-diagram.md +32 -0
- package/.llms/chunks/guides.ai.openai-function-calling.md +40 -0
- package/.llms/chunks/guides.building-processes.boundary-events.md +47 -0
- package/.llms/chunks/guides.building-processes.call-activities.md +47 -0
- package/.llms/chunks/guides.building-processes.events.md +57 -0
- package/.llms/chunks/guides.building-processes.multi-instance.md +20 -0
- package/.llms/chunks/guides.building-processes.service-tasks.md +39 -0
- package/.llms/chunks/guides.building-processes.sub-processes.md +40 -0
- package/.llms/chunks/guides.building-processes.task-defaults.md +18 -0
- package/.llms/chunks/guides.claude-code-plugin.ambient-hooks.md +24 -0
- package/.llms/chunks/guides.claude-code-plugin.configuration.md +126 -0
- package/.llms/chunks/guides.claude-code-plugin.md +47 -0
- package/.llms/chunks/guides.claude-code-plugin.reference-docs.md +61 -0
- package/.llms/chunks/guides.deployment.ci-cd-deploy-on-push.md +47 -0
- package/.llms/chunks/guides.deployment.deploying-a-process.md +52 -0
- package/.llms/chunks/guides.deployment.handling-jobs.md +50 -0
- package/.llms/chunks/guides.deployment.managing-incidents.md +33 -0
- package/.llms/chunks/guides.deployment.md +49 -0
- package/.llms/chunks/guides.gateways.branching-inside-sub-processes.md +27 -0
- package/.llms/chunks/guides.gateways.exclusive-gateway-xor.md +41 -0
- package/.llms/chunks/guides.gateways.inclusive-gateway-or.md +43 -0
- package/.llms/chunks/guides.gateways.nested-branching.md +27 -0
- package/.llms/chunks/guides.gateways.parallel-gateway-and.md +26 -0
- package/.llms/chunks/guides.patterns.how-matching-works.md +17 -0
- package/.llms/chunks/guides.patterns.md +26 -0
- package/.llms/chunks/guides.patterns.pattern-schema.md +38 -0
- package/.llms/chunks/guides.patterns.see-also.md +7 -0
- package/.llms/chunks/guides.patterns.using-patterns-from-the-cli.md +30 -0
- package/.llms/chunks/guides.patterns.what-a-pattern-contains.md +18 -0
- package/.llms/chunks/guides.simulation.dmn-decision-evaluation.md +51 -0
- package/.llms/chunks/guides.simulation.instance-state.md +29 -0
- package/.llms/chunks/guides.simulation.md +51 -0
- package/.llms/chunks/guides.simulation.message-correlation.md +30 -0
- package/.llms/chunks/guides.simulation.multiple-deployments.md +14 -0
- package/.llms/chunks/guides.workers-standalone.anatomy-of-a-worker.md +42 -0
- package/.llms/chunks/guides.workers-standalone.camunda-saas.md +43 -0
- package/.llms/chunks/guides.workers-standalone.environment-variables.md +14 -0
- package/.llms/chunks/guides.workers-standalone.md +35 -0
- package/.llms/chunks/guides.workers-standalone.running-workers.md +61 -0
- package/.llms/chunks/guides.workers-standalone.see-also.md +7 -0
- package/.llms/chunks/packages.api.incident-resolution.md +31 -0
- package/.llms/chunks/packages.api.observability-events.md +13 -0
- package/.llms/chunks/packages.api.overview.md +49 -0
- package/.llms/chunks/packages.api.process-operations.md +60 -0
- package/.llms/chunks/packages.api.resource-namespaces.md +20 -0
- package/.llms/chunks/packages.canvas.events.md +56 -0
- package/.llms/chunks/packages.canvas.options.md +24 -0
- package/.llms/chunks/packages.canvas.overview.md +35 -0
- package/.llms/chunks/packages.connector-gen.body-expansion.md +18 -0
- package/.llms/chunks/packages.connector-gen.catalog-reference.md +54 -0
- package/.llms/chunks/packages.connector-gen.catalogentry-type.md +21 -0
- package/.llms/chunks/packages.connector-gen.generating-from-the-catalog.md +44 -0
- package/.llms/chunks/packages.connector-gen.installation.md +42 -0
- package/.llms/chunks/packages.connector-gen.lower-level-api.md +31 -0
- package/.llms/chunks/packages.connector-gen.overview.md +16 -0
- package/.llms/chunks/packages.connector-gen.writeoptions.md +26 -0
- package/.llms/chunks/packages.core.dmn-support.md +36 -0
- package/.llms/chunks/packages.core.installation-bpmn.creatediagram-id.md +18 -0
- package/.llms/chunks/packages.core.installation-bpmn.createprocess-id-name.md +10 -0
- package/.llms/chunks/packages.core.installation-bpmn.export-definitions.md +10 -0
- package/.llms/chunks/packages.core.installation-bpmn.makeempty-processid-processname.md +11 -0
- package/.llms/chunks/packages.core.installation-bpmn.parse-xml.md +10 -0
- package/.llms/chunks/packages.core.installation-bpmn.sample_xml.md +7 -0
- package/.llms/chunks/packages.core.installation-compactify-definitions.md +13 -0
- package/.llms/chunks/packages.core.installation-expand-compact.md +13 -0
- package/.llms/chunks/packages.core.installation-layoutprocess-process.md +15 -0
- package/.llms/chunks/packages.core.installation-processbuilder-methods.md +29 -0
- package/.llms/chunks/packages.core.installation.md +11 -0
- package/.llms/chunks/packages.core.overview.md +15 -0
- package/.llms/chunks/packages.docspack.installation.md +45 -0
- package/.llms/chunks/packages.docspack.overview.md +23 -0
- package/.llms/chunks/packages.docspack.reading-it-yourself.md +34 -0
- package/.llms/chunks/packages.docspack.trust.md +13 -0
- package/.llms/chunks/packages.docspack.using-the-index-directly.md +52 -0
- package/.llms/chunks/packages.editor.basic-setup.md +41 -0
- package/.llms/chunks/packages.editor.full-editor-with-all-plugins.md +30 -0
- package/.llms/chunks/packages.editor.hud-options.md +41 -0
- package/.llms/chunks/packages.editor.overview.md +21 -0
- package/.llms/chunks/packages.engine.installation.md +77 -0
- package/.llms/chunks/packages.engine.overview.md +19 -0
- package/.llms/chunks/packages.engine.processinstance.md +17 -0
- package/.llms/chunks/packages.engine.variable-scoping.md +27 -0
- package/.llms/chunks/packages.worker-client.client.poll-jobtype-options.md +40 -0
- package/.llms/chunks/packages.worker-client.createworkerclient-options.md +32 -0
- package/.llms/chunks/packages.worker-client.job.complete-variables.md +29 -0
- package/.llms/chunks/packages.worker-client.md +33 -0
- package/.llms/chunks/packages.worker-client.oauth2-camunda-saas.md +26 -0
- package/.llms/chunks/packages.worker-client.see-also.md +7 -0
- package/.llms/manifest.json +2083 -0
- package/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/build.d.ts +29 -0
- package/dist/build.js +89 -0
- package/dist/chunk.d.ts +41 -0
- package/dist/chunk.js +242 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +160 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/load.d.ts +27 -0
- package/dist/load.js +144 -0
- package/dist/search.d.ts +53 -0
- package/dist/search.js +104 -0
- package/dist/text.d.ts +22 -0
- package/dist/text.js +204 -0
- package/dist/types.d.ts +48 -0
- package/dist/types.js +3 -0
- package/llms.txt +174 -0
- 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
|
+
[](https://www.npmjs.com/package/@bpmnkit/docspack)
|
|
7
|
+
[](https://github.com/bpmnkit/monorepo/blob/main/LICENSE)
|
|
8
|
+
[](https://github.com/bpmnkit/monorepo)
|
|
9
|
+
[](https://github.com/bpmnkit/monorepo)
|
|
10
|
+
[](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>
|
package/dist/build.d.ts
ADDED
|
@@ -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
|
package/dist/chunk.d.ts
ADDED
|
@@ -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
|