From 53bdbef989b1bc693163b36b2cdff3ee110878ab Mon Sep 17 00:00:00 2001 From: CrewCircle Date: Mon, 27 Jul 2026 01:06:39 +1000 Subject: [PATCH] Add @crewcircle/docs-gen: generic OpenWiki documentation generation, opt-in in CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a shared package other CrewCircle repos can npm-install/npx rather than copy-pasting a CI script, wrapping langchain-ai/openwiki with org defaults: - OPENWIKI_PROVIDER=openrouter, OPENWIKI_MODEL_ID=inclusionai/ling-2.6-flash — picked by querying OpenRouter's live pricing API for the cheapest model that both supports tool-calling (required, since OpenWiki reads files via tool calls) and has enough context for real source files. Free-tier models share a fragile ~20 req/day rate-limited pool, too flaky for CI, so a cheap paid model was chosen as the default instead. - A `--mode engineering|client` CLI flag and both INSTRUCTIONS templates are scaffolded now; `client` (end-user product docs) isn't wired into any workflow yet — OpenWiki's code mode has no documented output-path override, so running both modes in one repo needs that confirmed first (see the package README). Wired into CI as a new `docs` job in ci.yml, gated on `vars.OPENWIKI_DOCS_ENABLED` (unset by default, so it's a no-op until a maintainer opts in) and scoped to `push` only, never `pull_request`. The actual generation logic lives in a new `workflow_call` reusable workflow (docs-generate.yml) so other CrewCircle repos can call it directly by reference instead of duplicating it. Also fixes a latent bug in release.yml found while extending it: the existing `knowledge` publish step ran `npm publish packages/knowledge/dist`, but dist/ has no package.json of its own — confirmed via dry-run this would fail with ENOENT the first time a real `knowledge-v*` tag was pushed (never yet exercised). Switched both publish jobs to `npm publish --workspace=` from the repo root, with an explicit `files` field on each package.json so the published tarball is still scoped to just `dist/` (+ `templates/` for docs-gen) instead of shipping source and tests. Co-Authored-By: Claude Sonnet 5 --- .changeset/add-docs-gen.md | 5 + .github/workflows/ci.yml | 36 +- .github/workflows/docs-generate.yml | 60 ++ .github/workflows/release.yml | 42 +- package-lock.json | 865 ++++++++++++++++++ packages/docs-gen/.gitignore | 4 + packages/docs-gen/README.md | 44 + packages/docs-gen/package.json | 58 ++ packages/docs-gen/src/cli.ts | 70 ++ packages/docs-gen/src/defaults.ts | 14 + packages/docs-gen/src/index.ts | 2 + .../docs-gen/templates/INSTRUCTIONS.client.md | 15 + .../templates/INSTRUCTIONS.engineering.md | 8 + packages/docs-gen/test/defaults.test.ts | 14 + packages/docs-gen/tsconfig.json | 23 + packages/knowledge/package.json | 3 + 16 files changed, 1252 insertions(+), 11 deletions(-) create mode 100644 .changeset/add-docs-gen.md create mode 100644 .github/workflows/docs-generate.yml create mode 100644 packages/docs-gen/.gitignore create mode 100644 packages/docs-gen/README.md create mode 100644 packages/docs-gen/package.json create mode 100644 packages/docs-gen/src/cli.ts create mode 100644 packages/docs-gen/src/defaults.ts create mode 100644 packages/docs-gen/src/index.ts create mode 100644 packages/docs-gen/templates/INSTRUCTIONS.client.md create mode 100644 packages/docs-gen/templates/INSTRUCTIONS.engineering.md create mode 100644 packages/docs-gen/test/defaults.test.ts create mode 100644 packages/docs-gen/tsconfig.json diff --git a/.changeset/add-docs-gen.md b/.changeset/add-docs-gen.md new file mode 100644 index 0000000..bd85a58 --- /dev/null +++ b/.changeset/add-docs-gen.md @@ -0,0 +1,5 @@ +--- +"@crewcircle/docs-gen": minor +--- + +Initial release: generic OpenWiki-based documentation generation shared across CrewCircle repos, defaulting to the cheapest tool-calling-capable model available via the org's OpenRouter key. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb50c69..93a928f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,9 @@ jobs: run: npm ci - name: TypeCheck - run: npm run typecheck --workspace=@crewcircle/knowledge + run: | + npm run typecheck --workspace=@crewcircle/knowledge + npm run typecheck --workspace=@crewcircle/docs-gen lint: name: Lint @@ -45,7 +47,9 @@ jobs: run: npm ci - name: Lint - run: npm run lint --workspace=@crewcircle/knowledge + run: | + npm run lint --workspace=@crewcircle/knowledge + npm run lint --workspace=@crewcircle/docs-gen test: name: Test @@ -65,7 +69,9 @@ jobs: run: npm ci - name: Run Tests - run: npm test --workspace=@crewcircle/knowledge + run: | + npm test --workspace=@crewcircle/knowledge + npm test --workspace=@crewcircle/docs-gen build: name: Build @@ -86,15 +92,35 @@ jobs: run: npm ci - name: Build - run: npm run build --workspace=@crewcircle/knowledge + run: | + npm run build --workspace=@crewcircle/knowledge + npm run build --workspace=@crewcircle/docs-gen - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: dist - path: packages/knowledge/dist + path: | + packages/knowledge/dist + packages/docs-gen/dist retention-days: 7 + docs: + name: Generate Docs + needs: [build] + # Opt-in only: unset by default, so this job is skipped on every normal + # push/PR until a maintainer sets the OPENWIKI_DOCS_ENABLED repository + # (or org) variable to "true". Never runs on pull_request — an LLM pass + # on every contributor's PR would be wasteful and noisy. + if: github.event_name == 'push' && vars.OPENWIKI_DOCS_ENABLED == 'true' + permissions: + contents: write + pull-requests: write + uses: ./.github/workflows/docs-generate.yml + with: + mode: engineering + secrets: inherit + changeset: name: Changeset runs-on: ubuntu-latest diff --git a/.github/workflows/docs-generate.yml b/.github/workflows/docs-generate.yml new file mode 100644 index 0000000..33c1652 --- /dev/null +++ b/.github/workflows/docs-generate.yml @@ -0,0 +1,60 @@ +name: Generate Docs (reusable) + +# Generic OpenWiki-based documentation generation, shared across CrewCircle +# repos via @crewcircle/docs-gen. Called by this repo's own ci.yml (gated, +# default off) and by other CrewCircle repos as: +# uses: crewcircle/crewcircle-website/.github/workflows/docs-generate.yml@main +# +# Requires the calling workflow to pass `secrets: inherit` (or explicitly +# forward OPENROUTER_API_KEY) so the shared org-wide OpenRouter key reaches +# this job. + +on: + workflow_call: + inputs: + mode: + description: "Documentation audience: engineering (default) or client" + type: string + default: engineering + workflow_dispatch: + inputs: + mode: + description: "Documentation audience: engineering (default) or client" + type: string + default: engineering + +jobs: + generate: + name: Generate Docs + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: true + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Run OpenWiki via @crewcircle/docs-gen + run: npx --yes @crewcircle/docs-gen generate --mode=${{ inputs.mode }} + env: + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + + - name: Create documentation update pull request + uses: peter-evans/create-pull-request@v7 + with: + add-paths: | + openwiki + AGENTS.md + CLAUDE.md + branch: docs/update + commit-message: "docs: update generated documentation" + title: "docs: update generated documentation" + body: | + Automated documentation update via `@crewcircle/docs-gen` (OpenWiki, mode: ${{ inputs.mode }}). diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7d749c..aa82625 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,7 @@ on: branches: [main] tags: - 'knowledge-v*' + - 'docs-gen-v*' workflow_dispatch: permissions: @@ -77,8 +78,8 @@ jobs: automated draft: false - publish: - name: Publish to npm + publish-knowledge: + name: Publish knowledge to npm runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/knowledge-v') steps: @@ -101,11 +102,40 @@ jobs: run: npm run build --workspace=@crewcircle/knowledge - name: Verify package - run: | - cd packages/knowledge/dist - npm pack --dry-run + run: npm pack --dry-run --workspace=@crewcircle/knowledge + + - name: Publish to npm + run: npm publish --workspace=@crewcircle/knowledge --access public --provenance + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + publish-docs-gen: + name: Publish docs-gen to npm + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/docs-gen-v') + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: npm ci + + - name: Build docs-gen package + run: npm run build --workspace=@crewcircle/docs-gen + + - name: Verify package + run: npm pack --dry-run --workspace=@crewcircle/docs-gen - name: Publish to npm - run: npm publish packages/knowledge/dist --access public --provenance + run: npm publish --workspace=@crewcircle/docs-gen --access public --provenance env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2d29ba6..e90ff8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1035,6 +1035,10 @@ "resolved": "packages/database", "link": true }, + "node_modules/@crewcircle/docs-gen": { + "resolved": "packages/docs-gen", + "link": true + }, "node_modules/@crewcircle/knowledge": { "resolved": "packages/knowledge", "link": true @@ -15957,6 +15961,867 @@ "typescript": "^5" } }, + "packages/docs-gen": { + "name": "@crewcircle/docs-gen", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "commander": "^12.0.0" + }, + "bin": { + "crewcircle-docs": "dist/cli.js" + }, + "devDependencies": { + "@types/node": "^20.11.0", + "typescript": "^5.3.3", + "vitest": "^1.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "packages/docs-gen/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "packages/docs-gen/node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", + "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/docs-gen/node_modules/@vitest/runner": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz", + "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.6.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/docs-gen/node_modules/@vitest/snapshot": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz", + "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/docs-gen/node_modules/@vitest/spy": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz", + "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/docs-gen/node_modules/@vitest/utils": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz", + "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/docs-gen/node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "packages/docs-gen/node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "packages/docs-gen/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "packages/docs-gen/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "packages/docs-gen/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "packages/docs-gen/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "packages/docs-gen/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "packages/docs-gen/node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "packages/docs-gen/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/docs-gen/node_modules/vitest": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz", + "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "1.6.1", + "@vitest/runner": "1.6.1", + "@vitest/snapshot": "1.6.1", + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.1", + "@vitest/ui": "1.6.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "packages/docs-gen/node_modules/vitest/node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "packages/docs-gen/node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/knowledge": { "name": "@crewcircle/knowledge", "version": "0.1.0", diff --git a/packages/docs-gen/.gitignore b/packages/docs-gen/.gitignore new file mode 100644 index 0000000..480ab16 --- /dev/null +++ b/packages/docs-gen/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +dist/ +*.tsbuildinfo +coverage/ diff --git a/packages/docs-gen/README.md b/packages/docs-gen/README.md new file mode 100644 index 0000000..648b5ea --- /dev/null +++ b/packages/docs-gen/README.md @@ -0,0 +1,44 @@ +# @crewcircle/docs-gen + +Generic, shared wrapper around [OpenWiki](https://github.com/langchain-ai/openwiki) +for CrewCircle repos. One package, one default model, one place to update — +every repo runs the same CLI instead of a copy-pasted CI script. + +## Usage + +```sh +npx @crewcircle/docs-gen generate --mode=engineering +``` + +- Writes `openwiki/INSTRUCTIONS.md` from the matching template in + `templates/` **only if one doesn't already exist** — it never overwrites a + repo's hand-edited brief. +- Applies the shared defaults from `src/defaults.ts` (provider, model, + telemetry) unless the calling environment already sets them, then runs + `openwiki code --update --print`. + +Requires `OPENROUTER_API_KEY` in the environment (already provisioned as a +CrewCircle GitHub org secret). + +## Model choice + +Defaults to `inclusionai/ling-2.6-flash` via OpenRouter — the cheapest model +on OpenRouter's live catalog, at the time this was written, that both supports +tool-calling (required — OpenWiki is an agentic CLI that reads files via tool +calls) and has enough context (262k tokens) to read real source files. Free-tier +(`:free`) models were intentionally not chosen as the default: they share a +global rate-limited pool (as low as 20 requests/day) too fragile for a CI job +that needs many tool-call round-trips per run. Override per-repo by setting +`OPENWIKI_MODEL_ID` in the calling workflow's environment before invoking this +CLI — it wins over the default. + +## Modes + +- `engineering` (default, active): OpenWiki's native internal/developer wiki, + written to `openwiki/`, for coding agents and contributors. +- `client`: end-user product documentation. **Scaffolded but not yet wired + into any CI workflow.** OpenWiki's code mode writes to a fixed `openwiki/` + directory with no documented output-path override, so running both modes in + the same repo needs either a confirmed override flag or generating + client-mode docs in an isolated checkout and relocating the output + afterward. Resolve that before adding a `client` job anywhere. diff --git a/packages/docs-gen/package.json b/packages/docs-gen/package.json new file mode 100644 index 0000000..1661cfa --- /dev/null +++ b/packages/docs-gen/package.json @@ -0,0 +1,58 @@ +{ + "name": "@crewcircle/docs-gen", + "version": "0.1.0", + "description": "Generic OpenWiki-based documentation generation, shared across CrewCircle repos", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "bin": { + "crewcircle-docs": "dist/cli.js" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "files": [ + "dist", + "templates" + ], + "scripts": { + "build": "tsc -p tsconfig.json", + "build:watch": "tsc -w", + "test": "vitest run", + "test:watch": "vitest", + "lint": "eslint src --ext .ts", + "typecheck": "tsc --noEmit" + }, + "keywords": [ + "documentation", + "openwiki", + "crewcircle", + "ci" + ], + "author": "CrewCircle", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/crewcircle/crewcircle-website.git", + "directory": "packages/docs-gen" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/", + "provenance": true + }, + "dependencies": { + "commander": "^12.0.0" + }, + "devDependencies": { + "@types/node": "^20.11.0", + "typescript": "^5.3.3", + "vitest": "^1.2.0" + }, + "engines": { + "node": ">=20.0.0" + } +} diff --git a/packages/docs-gen/src/cli.ts b/packages/docs-gen/src/cli.ts new file mode 100644 index 0000000..87bfd10 --- /dev/null +++ b/packages/docs-gen/src/cli.ts @@ -0,0 +1,70 @@ +#!/usr/bin/env node +import { Command } from "commander"; +import { spawnSync } from "node:child_process"; +import { copyFileSync, existsSync, mkdirSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { DEFAULT_ENV, VALID_MODES, type DocsMode } from "./defaults.js"; + +const packageRoot = join(dirname(fileURLToPath(import.meta.url)), ".."); + +function templatePathFor(mode: DocsMode): string { + return join(packageRoot, "templates", `INSTRUCTIONS.${mode}.md`); +} + +function ensureInstructions(mode: DocsMode): void { + const wikiDir = join(process.cwd(), "openwiki"); + const instructionsPath = join(wikiDir, "INSTRUCTIONS.md"); + + if (existsSync(instructionsPath)) { + // Never clobber a repo's hand-edited brief. + return; + } + + const template = templatePathFor(mode); + if (!existsSync(template)) { + throw new Error(`No INSTRUCTIONS template found for mode "${mode}" at ${template}`); + } + + mkdirSync(wikiDir, { recursive: true }); + copyFileSync(template, instructionsPath); +} + +function runGenerate(mode: DocsMode): void { + if (!VALID_MODES.includes(mode)) { + throw new Error(`Invalid mode "${mode}". Expected one of: ${VALID_MODES.join(", ")}`); + } + + ensureInstructions(mode); + + const env = { ...DEFAULT_ENV, ...process.env }; + + const result = spawnSync("npx", ["--yes", "openwiki", "code", "--update", "--print"], { + stdio: "inherit", + env, + }); + + if (result.status !== 0) { + process.exit(result.status ?? 1); + } +} + +const program = new Command(); + +program + .name("crewcircle-docs") + .description("Generate CrewCircle documentation via OpenWiki with shared org defaults"); + +program + .command("generate") + .description("Run an OpenWiki documentation update") + .option( + "--mode ", + `documentation audience: ${VALID_MODES.join(" | ")}`, + "engineering" + ) + .action((options: { mode: string }) => { + runGenerate(options.mode as DocsMode); + }); + +program.parse(); diff --git a/packages/docs-gen/src/defaults.ts b/packages/docs-gen/src/defaults.ts new file mode 100644 index 0000000..43c176f --- /dev/null +++ b/packages/docs-gen/src/defaults.ts @@ -0,0 +1,14 @@ +/** + * Default OpenWiki configuration shared by every CrewCircle repo. + * Bump OPENWIKI_MODEL_ID here to change the model for all repos at once — + * see the model-selection note in the docs-gen README for how this was chosen. + */ +export const DEFAULT_ENV: Record = { + OPENWIKI_PROVIDER: "openrouter", + OPENWIKI_MODEL_ID: "inclusionai/ling-2.6-flash", + OPENWIKI_TELEMETRY_DISABLED: "1", +}; + +export type DocsMode = "engineering" | "client"; + +export const VALID_MODES: DocsMode[] = ["engineering", "client"]; diff --git a/packages/docs-gen/src/index.ts b/packages/docs-gen/src/index.ts new file mode 100644 index 0000000..99844cc --- /dev/null +++ b/packages/docs-gen/src/index.ts @@ -0,0 +1,2 @@ +export { DEFAULT_ENV, VALID_MODES } from "./defaults"; +export type { DocsMode } from "./defaults"; diff --git a/packages/docs-gen/templates/INSTRUCTIONS.client.md b/packages/docs-gen/templates/INSTRUCTIONS.client.md new file mode 100644 index 0000000..08dbc6b --- /dev/null +++ b/packages/docs-gen/templates/INSTRUCTIONS.client.md @@ -0,0 +1,15 @@ +# Wiki instructions — client-facing mode + +> Not yet wired into any CI workflow. Scaffolded ahead of the output-directory +> question described in `packages/docs-gen/README.md` — using this template +> today would still write into `openwiki/`, the same directory the +> engineering mode uses. + +Audience: end users of the product — not engineers, not this codebase's +contributors. Assume no knowledge of the implementation. + +Document what the product does and how to use it: features, workflows, +account setup, and troubleshooting from a user's point of view. Do not +describe internal architecture, code structure, database schemas, or +implementation details. Use the product's own terminology, not the +codebase's internal naming. diff --git a/packages/docs-gen/templates/INSTRUCTIONS.engineering.md b/packages/docs-gen/templates/INSTRUCTIONS.engineering.md new file mode 100644 index 0000000..54a8cb3 --- /dev/null +++ b/packages/docs-gen/templates/INSTRUCTIONS.engineering.md @@ -0,0 +1,8 @@ +# Wiki instructions — engineering mode + +Audience: engineers and coding agents working in this repository. + +Document the architecture, module boundaries, data flow, and non-obvious +design decisions. Prefer explaining *why* something is built the way it is +over restating what the code already makes obvious. Call out cross-repo or +cross-package dependencies explicitly. Keep pages scoped to one concept each. diff --git a/packages/docs-gen/test/defaults.test.ts b/packages/docs-gen/test/defaults.test.ts new file mode 100644 index 0000000..90e81ad --- /dev/null +++ b/packages/docs-gen/test/defaults.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from "vitest"; +import { DEFAULT_ENV, VALID_MODES } from "../src/defaults"; + +describe("defaults", () => { + it("configures the OpenRouter provider with a tool-calling-capable model", () => { + expect(DEFAULT_ENV.OPENWIKI_PROVIDER).toBe("openrouter"); + expect(DEFAULT_ENV.OPENWIKI_MODEL_ID).toBeTruthy(); + expect(DEFAULT_ENV.OPENWIKI_TELEMETRY_DISABLED).toBe("1"); + }); + + it("only exposes the supported documentation modes", () => { + expect(VALID_MODES).toEqual(["engineering", "client"]); + }); +}); diff --git a/packages/docs-gen/tsconfig.json b/packages/docs-gen/tsconfig.json new file mode 100644 index 0000000..c08988b --- /dev/null +++ b/packages/docs-gen/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "isolatedModules": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true, + "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo", + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test"] +} diff --git a/packages/knowledge/package.json b/packages/knowledge/package.json index 9840911..b6c74a2 100644 --- a/packages/knowledge/package.json +++ b/packages/knowledge/package.json @@ -5,6 +5,9 @@ "main": "dist/index.js", "module": "dist/esm/index.js", "types": "dist/index.d.ts", + "files": [ + "dist" + ], "exports": { ".": { "types": "./dist/index.d.ts",