docsgraph 0.1.0a2__tar.gz
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.
- docsgraph-0.1.0a2/.cairn/config.toml +40 -0
- docsgraph-0.1.0a2/.env.example +48 -0
- docsgraph-0.1.0a2/.github/ISSUE_TEMPLATE/bug_report.yml +65 -0
- docsgraph-0.1.0a2/.github/ISSUE_TEMPLATE/config.yml +8 -0
- docsgraph-0.1.0a2/.github/ISSUE_TEMPLATE/feature_request.yml +55 -0
- docsgraph-0.1.0a2/.github/PULL_REQUEST_TEMPLATE.md +50 -0
- docsgraph-0.1.0a2/.github/dependabot.yml +13 -0
- docsgraph-0.1.0a2/.github/workflows/ci.yml +72 -0
- docsgraph-0.1.0a2/.github/workflows/release.yml +77 -0
- docsgraph-0.1.0a2/.github/workflows/repo-regression.yml +36 -0
- docsgraph-0.1.0a2/.gitignore +82 -0
- docsgraph-0.1.0a2/ARCHITECTURE.md +579 -0
- docsgraph-0.1.0a2/CHANGELOG.md +220 -0
- docsgraph-0.1.0a2/CLAUDE.md +212 -0
- docsgraph-0.1.0a2/CODE_OF_CONDUCT.md +122 -0
- docsgraph-0.1.0a2/CONTRIBUTING.md +167 -0
- docsgraph-0.1.0a2/LICENSE +201 -0
- docsgraph-0.1.0a2/PKG-INFO +688 -0
- docsgraph-0.1.0a2/PRODUCT.md +231 -0
- docsgraph-0.1.0a2/README.md +434 -0
- docsgraph-0.1.0a2/ROADMAP.md +206 -0
- docsgraph-0.1.0a2/SECURITY.md +57 -0
- docsgraph-0.1.0a2/benchmarks/README.md +123 -0
- docsgraph-0.1.0a2/benchmarks/architecture.toml +83 -0
- docsgraph-0.1.0a2/docs/assets/cairn-demo.svg +50 -0
- docsgraph-0.1.0a2/docs/canvas.html +1283 -0
- docsgraph-0.1.0a2/docs/decisions/0000-template.md +31 -0
- docsgraph-0.1.0a2/docs/decisions/0001-foundation.md +142 -0
- docsgraph-0.1.0a2/docs/golden-docs-standard.md +231 -0
- docsgraph-0.1.0a2/docs/inspector-principle.html +873 -0
- docsgraph-0.1.0a2/docs/release-checklist.md +148 -0
- docsgraph-0.1.0a2/docs/repo-lifecycle-canvas.html +647 -0
- docsgraph-0.1.0a2/docs/specs/mcp-tools.md +739 -0
- docsgraph-0.1.0a2/examples/hero-demo.md +276 -0
- docsgraph-0.1.0a2/examples/real-llm-doubao.md +86 -0
- docsgraph-0.1.0a2/pyproject.toml +122 -0
- docsgraph-0.1.0a2/scripts/eval_repos.py +615 -0
- docsgraph-0.1.0a2/scripts/smoke_many_repos.py +356 -0
- docsgraph-0.1.0a2/src/cairn/__init__.py +5 -0
- docsgraph-0.1.0a2/src/cairn/bench/__init__.py +37 -0
- docsgraph-0.1.0a2/src/cairn/bench/baseline.py +236 -0
- docsgraph-0.1.0a2/src/cairn/bench/dataset.py +109 -0
- docsgraph-0.1.0a2/src/cairn/bench/judge.py +126 -0
- docsgraph-0.1.0a2/src/cairn/bench/metrics.py +32 -0
- docsgraph-0.1.0a2/src/cairn/bench/report.py +143 -0
- docsgraph-0.1.0a2/src/cairn/bench/runner.py +219 -0
- docsgraph-0.1.0a2/src/cairn/cli/__init__.py +5 -0
- docsgraph-0.1.0a2/src/cairn/cli/app.py +776 -0
- docsgraph-0.1.0a2/src/cairn/cli/config.py +105 -0
- docsgraph-0.1.0a2/src/cairn/core/__init__.py +41 -0
- docsgraph-0.1.0a2/src/cairn/core/errors.py +68 -0
- docsgraph-0.1.0a2/src/cairn/core/types.py +147 -0
- docsgraph-0.1.0a2/src/cairn/embed/__init__.py +17 -0
- docsgraph-0.1.0a2/src/cairn/embed/base.py +31 -0
- docsgraph-0.1.0a2/src/cairn/embed/doubao.py +167 -0
- docsgraph-0.1.0a2/src/cairn/embed/fake.py +36 -0
- docsgraph-0.1.0a2/src/cairn/embed/openai_compatible.py +155 -0
- docsgraph-0.1.0a2/src/cairn/engine/__init__.py +18 -0
- docsgraph-0.1.0a2/src/cairn/engine/indexer.py +298 -0
- docsgraph-0.1.0a2/src/cairn/engine/manifest.py +83 -0
- docsgraph-0.1.0a2/src/cairn/entity/__init__.py +21 -0
- docsgraph-0.1.0a2/src/cairn/entity/base.py +52 -0
- docsgraph-0.1.0a2/src/cairn/entity/fake.py +34 -0
- docsgraph-0.1.0a2/src/cairn/entity/heuristic.py +148 -0
- docsgraph-0.1.0a2/src/cairn/index/__init__.py +39 -0
- docsgraph-0.1.0a2/src/cairn/index/entities.py +244 -0
- docsgraph-0.1.0a2/src/cairn/index/summaries.py +269 -0
- docsgraph-0.1.0a2/src/cairn/index/tree.py +274 -0
- docsgraph-0.1.0a2/src/cairn/index/vectors.py +287 -0
- docsgraph-0.1.0a2/src/cairn/index/xrefs.py +195 -0
- docsgraph-0.1.0a2/src/cairn/ingest/__init__.py +36 -0
- docsgraph-0.1.0a2/src/cairn/ingest/base.py +46 -0
- docsgraph-0.1.0a2/src/cairn/ingest/markdown.py +244 -0
- docsgraph-0.1.0a2/src/cairn/ingest/markitdown.py +145 -0
- docsgraph-0.1.0a2/src/cairn/ingest/pdf.py +357 -0
- docsgraph-0.1.0a2/src/cairn/inspection.py +971 -0
- docsgraph-0.1.0a2/src/cairn/mcp/__init__.py +12 -0
- docsgraph-0.1.0a2/src/cairn/mcp/schemas.py +547 -0
- docsgraph-0.1.0a2/src/cairn/mcp/server.py +363 -0
- docsgraph-0.1.0a2/src/cairn/providers.py +50 -0
- docsgraph-0.1.0a2/src/cairn/py.typed +0 -0
- docsgraph-0.1.0a2/src/cairn/repo.py +1486 -0
- docsgraph-0.1.0a2/src/cairn/repo_search.py +1505 -0
- docsgraph-0.1.0a2/src/cairn/summarize/__init__.py +18 -0
- docsgraph-0.1.0a2/src/cairn/summarize/base.py +56 -0
- docsgraph-0.1.0a2/src/cairn/summarize/cache.py +66 -0
- docsgraph-0.1.0a2/src/cairn/summarize/fake.py +43 -0
- docsgraph-0.1.0a2/src/cairn/summarize/openai_compatible.py +148 -0
- docsgraph-0.1.0a2/src/cairn/summarize/prompts.py +73 -0
- docsgraph-0.1.0a2/src/cairn/tools/__init__.py +31 -0
- docsgraph-0.1.0a2/src/cairn/tools/base.py +126 -0
- docsgraph-0.1.0a2/src/cairn/tools/find_mentions.py +93 -0
- docsgraph-0.1.0a2/src/cairn/tools/get_related.py +140 -0
- docsgraph-0.1.0a2/src/cairn/tools/get_section.py +130 -0
- docsgraph-0.1.0a2/src/cairn/tools/outline.py +75 -0
- docsgraph-0.1.0a2/src/cairn/tools/read_range.py +94 -0
- docsgraph-0.1.0a2/src/cairn/tools/search_keyword.py +94 -0
- docsgraph-0.1.0a2/src/cairn/tools/search_semantic.py +181 -0
- docsgraph-0.1.0a2/src/cairn/xref/__init__.py +24 -0
- docsgraph-0.1.0a2/src/cairn/xref/base.py +50 -0
- docsgraph-0.1.0a2/src/cairn/xref/fake.py +40 -0
- docsgraph-0.1.0a2/src/cairn/xref/heuristic.py +217 -0
- docsgraph-0.1.0a2/tests/__init__.py +0 -0
- docsgraph-0.1.0a2/tests/conftest.py +39 -0
- docsgraph-0.1.0a2/tests/fixtures/empty.md +0 -0
- docsgraph-0.1.0a2/tests/fixtures/nested.md +21 -0
- docsgraph-0.1.0a2/tests/fixtures/no_headings.md +3 -0
- docsgraph-0.1.0a2/tests/fixtures/simple.md +20 -0
- docsgraph-0.1.0a2/tests/fixtures/with_frontmatter.md +8 -0
- docsgraph-0.1.0a2/tests/unit/__init__.py +0 -0
- docsgraph-0.1.0a2/tests/unit/conftest.py +35 -0
- docsgraph-0.1.0a2/tests/unit/test_bench_baseline.py +100 -0
- docsgraph-0.1.0a2/tests/unit/test_bench_dataset.py +86 -0
- docsgraph-0.1.0a2/tests/unit/test_bench_judge.py +110 -0
- docsgraph-0.1.0a2/tests/unit/test_bench_metrics.py +44 -0
- docsgraph-0.1.0a2/tests/unit/test_bench_runner.py +97 -0
- docsgraph-0.1.0a2/tests/unit/test_cli.py +268 -0
- docsgraph-0.1.0a2/tests/unit/test_cli_config.py +64 -0
- docsgraph-0.1.0a2/tests/unit/test_embed_doubao.py +176 -0
- docsgraph-0.1.0a2/tests/unit/test_embed_fake.py +76 -0
- docsgraph-0.1.0a2/tests/unit/test_embed_openai_compatible.py +165 -0
- docsgraph-0.1.0a2/tests/unit/test_engine_indexer.py +212 -0
- docsgraph-0.1.0a2/tests/unit/test_engine_manifest.py +70 -0
- docsgraph-0.1.0a2/tests/unit/test_entities_builder.py +184 -0
- docsgraph-0.1.0a2/tests/unit/test_entity_heuristic.py +168 -0
- docsgraph-0.1.0a2/tests/unit/test_markdown_parser.py +194 -0
- docsgraph-0.1.0a2/tests/unit/test_markitdown_parser.py +71 -0
- docsgraph-0.1.0a2/tests/unit/test_mcp_server.py +338 -0
- docsgraph-0.1.0a2/tests/unit/test_pdf_parser.py +188 -0
- docsgraph-0.1.0a2/tests/unit/test_repo.py +1108 -0
- docsgraph-0.1.0a2/tests/unit/test_repo_eval_gates.py +85 -0
- docsgraph-0.1.0a2/tests/unit/test_summaries_builder.py +236 -0
- docsgraph-0.1.0a2/tests/unit/test_summaries_reader.py +89 -0
- docsgraph-0.1.0a2/tests/unit/test_summarize_cache.py +76 -0
- docsgraph-0.1.0a2/tests/unit/test_summarize_fake.py +50 -0
- docsgraph-0.1.0a2/tests/unit/test_summarize_openai_compatible.py +163 -0
- docsgraph-0.1.0a2/tests/unit/test_summarize_prompts.py +69 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_document_index.py +75 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_find_mentions.py +120 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_get_related.py +176 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_get_section.py +81 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_outline.py +65 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_read_range.py +118 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_search_keyword.py +94 -0
- docsgraph-0.1.0a2/tests/unit/test_tool_search_semantic.py +123 -0
- docsgraph-0.1.0a2/tests/unit/test_tree_builder.py +203 -0
- docsgraph-0.1.0a2/tests/unit/test_types.py +168 -0
- docsgraph-0.1.0a2/tests/unit/test_vectors_builder.py +154 -0
- docsgraph-0.1.0a2/tests/unit/test_vectors_reader.py +161 -0
- docsgraph-0.1.0a2/tests/unit/test_xref_heuristic.py +160 -0
- docsgraph-0.1.0a2/tests/unit/test_xrefs_builder.py +229 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Cairn repository documentation index.
|
|
2
|
+
# Paths are relative to the repository root.
|
|
3
|
+
documents_dir = "documents"
|
|
4
|
+
enable_markitdown = false
|
|
5
|
+
search_sections_per_doc = 1
|
|
6
|
+
primary_doc = "readme"
|
|
7
|
+
|
|
8
|
+
include = [
|
|
9
|
+
"*.md",
|
|
10
|
+
"*.markdown",
|
|
11
|
+
"*.mdown",
|
|
12
|
+
"*.mkd",
|
|
13
|
+
"*.pdf",
|
|
14
|
+
"*/README.md",
|
|
15
|
+
"*/README.markdown",
|
|
16
|
+
"docs/**/*.md",
|
|
17
|
+
"docs/**/*.markdown",
|
|
18
|
+
"docs/**/*.mdown",
|
|
19
|
+
"docs/**/*.mkd",
|
|
20
|
+
"docs/**/*.pdf",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
exclude = [
|
|
24
|
+
".git/**",
|
|
25
|
+
".cairn/**",
|
|
26
|
+
".codegraph/**",
|
|
27
|
+
".hypothesis/**",
|
|
28
|
+
".mypy_cache/**",
|
|
29
|
+
".pytest_cache/**",
|
|
30
|
+
".ruff_cache/**",
|
|
31
|
+
".venv/**",
|
|
32
|
+
".tox/**",
|
|
33
|
+
".nox/**",
|
|
34
|
+
"venv/**",
|
|
35
|
+
"node_modules/**",
|
|
36
|
+
"dist/**",
|
|
37
|
+
"build/**",
|
|
38
|
+
"site/**",
|
|
39
|
+
"__pycache__/**",
|
|
40
|
+
]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Cairn environment example.
|
|
2
|
+
# Copy to .env for local experiments. Never commit real API keys.
|
|
3
|
+
|
|
4
|
+
# ---------------------------------------------------------------------------
|
|
5
|
+
# Local defaults: Ollama-compatible summarization + embeddings
|
|
6
|
+
# ---------------------------------------------------------------------------
|
|
7
|
+
# CAIRN_LLM_BASE_URL=http://localhost:11434/v1
|
|
8
|
+
# CAIRN_LLM_MODEL=qwen2.5:7b
|
|
9
|
+
# CAIRN_LLM_API_KEY=ollama
|
|
10
|
+
#
|
|
11
|
+
# CAIRN_EMBED_PROVIDER=openai-compatible
|
|
12
|
+
# CAIRN_EMBED_BASE_URL=http://localhost:11434/v1
|
|
13
|
+
# CAIRN_EMBED_MODEL=nomic-embed-text
|
|
14
|
+
# CAIRN_EMBED_API_KEY=ollama
|
|
15
|
+
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
# OpenAI-compatible hosted endpoint
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
# CAIRN_LLM_BASE_URL=https://api.example.com/v1
|
|
20
|
+
# CAIRN_LLM_MODEL=your-chat-model
|
|
21
|
+
# CAIRN_LLM_API_KEY=replace-me
|
|
22
|
+
#
|
|
23
|
+
# CAIRN_EMBED_PROVIDER=openai-compatible
|
|
24
|
+
# CAIRN_EMBED_BASE_URL=https://api.example.com/v1
|
|
25
|
+
# CAIRN_EMBED_MODEL=your-embedding-model
|
|
26
|
+
# CAIRN_EMBED_API_KEY=replace-me
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Volcengine ARK / Doubao
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
# CAIRN_LLM_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
|
|
32
|
+
# CAIRN_LLM_MODEL=doubao-seed-2-0-code-preview-260215
|
|
33
|
+
# CAIRN_LLM_API_KEY=replace-me
|
|
34
|
+
#
|
|
35
|
+
# CAIRN_EMBED_PROVIDER=doubao-vision
|
|
36
|
+
# CAIRN_EMBED_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
|
|
37
|
+
# CAIRN_EMBED_MODEL=doubao-embedding-vision-251215
|
|
38
|
+
# CAIRN_EMBED_API_KEY=replace-me
|
|
39
|
+
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
# Hosted API stability knobs
|
|
42
|
+
# ---------------------------------------------------------------------------
|
|
43
|
+
# CAIRN_LLM_TIMEOUT=60
|
|
44
|
+
# CAIRN_LLM_MAX_RETRIES=2
|
|
45
|
+
# CAIRN_EMBED_TIMEOUT=60
|
|
46
|
+
# CAIRN_EMBED_MAX_RETRIES=2
|
|
47
|
+
# CAIRN_SUMMARY_CONCURRENCY=4
|
|
48
|
+
# CAIRN_EMBED_BATCH_SIZE=32
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something Cairn does, but shouldn't (or doesn't, but should).
|
|
3
|
+
labels: ["bug", "triage"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for taking the time. Please fill in the boxes below — the
|
|
9
|
+
more concrete the reproducer, the faster the fix.
|
|
10
|
+
|
|
11
|
+
- type: input
|
|
12
|
+
id: version
|
|
13
|
+
attributes:
|
|
14
|
+
label: Cairn version
|
|
15
|
+
description: Output of `cairn version` (or your installed package version).
|
|
16
|
+
placeholder: "0.1.0a1"
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: input
|
|
21
|
+
id: python
|
|
22
|
+
attributes:
|
|
23
|
+
label: Python version
|
|
24
|
+
placeholder: "3.12.3"
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: input
|
|
29
|
+
id: os
|
|
30
|
+
attributes:
|
|
31
|
+
label: Operating system
|
|
32
|
+
placeholder: "macOS 14.5 / Ubuntu 24.04 / Windows 11"
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: reproducer
|
|
38
|
+
attributes:
|
|
39
|
+
label: Minimal reproducer
|
|
40
|
+
description: A short markdown file, a shell command, or a Python snippet that triggers the issue.
|
|
41
|
+
render: shell
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
|
|
45
|
+
- type: textarea
|
|
46
|
+
id: expected
|
|
47
|
+
attributes:
|
|
48
|
+
label: Expected behavior
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
|
|
52
|
+
- type: textarea
|
|
53
|
+
id: actual
|
|
54
|
+
attributes:
|
|
55
|
+
label: Actual behavior
|
|
56
|
+
description: Include any error output. If `cairn serve` is involved, the JSON-line log is very helpful.
|
|
57
|
+
render: shell
|
|
58
|
+
validations:
|
|
59
|
+
required: true
|
|
60
|
+
|
|
61
|
+
- type: textarea
|
|
62
|
+
id: extras
|
|
63
|
+
attributes:
|
|
64
|
+
label: Additional context
|
|
65
|
+
description: Endpoint configuration (Ollama / OpenAI / other), document size, anything else relevant.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security disclosure
|
|
4
|
+
url: https://github.com/jokeuncle/cairn/blob/main/SECURITY.md
|
|
5
|
+
about: Report a security issue privately — please do not open a public issue.
|
|
6
|
+
- name: Architecture decisions
|
|
7
|
+
url: https://github.com/jokeuncle/cairn/tree/main/docs/decisions
|
|
8
|
+
about: Browse existing ADRs before proposing structural changes.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a change to Cairn.
|
|
3
|
+
labels: ["enhancement", "triage"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Before opening a feature request, please read
|
|
9
|
+
[`PRODUCT.md`](https://github.com/jokeuncle/cairn/blob/main/PRODUCT.md)
|
|
10
|
+
— especially §6 (Non-goals). The project is deliberately
|
|
11
|
+
opinionated, and proposals that contradict the thesis or expand
|
|
12
|
+
the scope beyond structured-document retrieval are unlikely to
|
|
13
|
+
land.
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: problem
|
|
17
|
+
attributes:
|
|
18
|
+
label: What problem are you trying to solve?
|
|
19
|
+
description: Describe the user-facing problem first, the proposed solution second.
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
|
|
23
|
+
- type: textarea
|
|
24
|
+
id: proposal
|
|
25
|
+
attributes:
|
|
26
|
+
label: Proposed solution
|
|
27
|
+
description: Sketch the API or behavior. If it touches the MCP tool catalog, sub-index format, or layer boundaries, an ADR will be required before code.
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
|
|
31
|
+
- type: textarea
|
|
32
|
+
id: alternatives
|
|
33
|
+
attributes:
|
|
34
|
+
label: Alternatives considered
|
|
35
|
+
description: What else did you look at, and why was it not enough?
|
|
36
|
+
|
|
37
|
+
- type: dropdown
|
|
38
|
+
id: scope
|
|
39
|
+
attributes:
|
|
40
|
+
label: Which subsystem does this touch?
|
|
41
|
+
multiple: true
|
|
42
|
+
options:
|
|
43
|
+
- Markdown ingest
|
|
44
|
+
- PDF ingest
|
|
45
|
+
- Summaries (S)
|
|
46
|
+
- Vectors (V)
|
|
47
|
+
- Entities (E)
|
|
48
|
+
- Cross-references (X)
|
|
49
|
+
- Tools / MCP server
|
|
50
|
+
- CLI
|
|
51
|
+
- Bench
|
|
52
|
+
- Documentation
|
|
53
|
+
- Other (please describe in "Proposed solution")
|
|
54
|
+
validations:
|
|
55
|
+
required: true
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Thanks for opening a PR! Before you submit, please make sure the items
|
|
3
|
+
below are taken care of. CI will catch most of them, but it helps
|
|
4
|
+
reviewers move faster if you've already verified them locally.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
<!-- One sentence: what changes and why. -->
|
|
10
|
+
|
|
11
|
+
## Type of change
|
|
12
|
+
|
|
13
|
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
|
14
|
+
- [ ] Feature (non-breaking change which adds functionality)
|
|
15
|
+
- [ ] Breaking change (fix or feature that changes existing behavior)
|
|
16
|
+
- [ ] Documentation only
|
|
17
|
+
- [ ] Refactor / internal cleanup
|
|
18
|
+
|
|
19
|
+
## Linked ADR / Roadmap milestone
|
|
20
|
+
|
|
21
|
+
<!--
|
|
22
|
+
If this PR touches PRODUCT.md, ARCHITECTURE.md, the MCP tool catalog,
|
|
23
|
+
or on-disk formats, an ADR is required. Link it here.
|
|
24
|
+
Otherwise reference the ROADMAP milestone (e.g. "v0.2.5").
|
|
25
|
+
-->
|
|
26
|
+
|
|
27
|
+
## Test plan
|
|
28
|
+
|
|
29
|
+
<!--
|
|
30
|
+
Walk through what you ran locally. Concrete commands beat "I tested it".
|
|
31
|
+
-->
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
ruff check src tests
|
|
35
|
+
mypy src/cairn
|
|
36
|
+
pytest tests/unit -q
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- [ ] Unit tests added / updated
|
|
40
|
+
- [ ] CHANGELOG.md updated (for user-facing changes)
|
|
41
|
+
|
|
42
|
+
## Anti-checklist (CLAUDE.md anti-patterns)
|
|
43
|
+
|
|
44
|
+
The following are non-goals; check that this PR does **not**:
|
|
45
|
+
|
|
46
|
+
- [ ] Add a chatbot / answer-generation tool to the public catalog
|
|
47
|
+
- [ ] Replace structure-aware retrieval with vector-chunking as the primary path
|
|
48
|
+
- [ ] Change progressive-disclosure defaults to return more by default
|
|
49
|
+
- [ ] Introduce a network dependency in the default install
|
|
50
|
+
- [ ] Pull a heavy dependency without an ADR
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "github-actions"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
open-pull-requests-limit: 5
|
|
8
|
+
|
|
9
|
+
- package-ecosystem: "pip"
|
|
10
|
+
directory: "/"
|
|
11
|
+
schedule:
|
|
12
|
+
interval: "weekly"
|
|
13
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
# Cancel in-progress runs of the same workflow on the same branch/PR.
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
lint-types-tests:
|
|
16
|
+
name: lint + types + tests (Python ${{ matrix.python-version }})
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
cache: pip
|
|
31
|
+
|
|
32
|
+
- name: Install package + dev extras
|
|
33
|
+
run: |
|
|
34
|
+
python -m pip install --upgrade pip
|
|
35
|
+
python -m pip install -e ".[dev]"
|
|
36
|
+
|
|
37
|
+
- name: ruff
|
|
38
|
+
run: ruff check .
|
|
39
|
+
|
|
40
|
+
- name: mypy --strict
|
|
41
|
+
run: mypy src tests
|
|
42
|
+
|
|
43
|
+
- name: pytest
|
|
44
|
+
run: pytest
|
|
45
|
+
|
|
46
|
+
build:
|
|
47
|
+
name: build wheel + sdist
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
needs: lint-types-tests
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
|
|
53
|
+
- name: Set up Python
|
|
54
|
+
uses: actions/setup-python@v5
|
|
55
|
+
with:
|
|
56
|
+
python-version: "3.12"
|
|
57
|
+
|
|
58
|
+
- name: Install build tooling
|
|
59
|
+
run: python -m pip install --upgrade pip build twine
|
|
60
|
+
|
|
61
|
+
- name: Build distributions
|
|
62
|
+
run: python -m build --wheel --sdist
|
|
63
|
+
|
|
64
|
+
- name: Check distributions
|
|
65
|
+
run: python -m twine check dist/*
|
|
66
|
+
|
|
67
|
+
- name: Upload artifacts
|
|
68
|
+
uses: actions/upload-artifact@v4
|
|
69
|
+
with:
|
|
70
|
+
name: cairn-dist
|
|
71
|
+
path: dist/*
|
|
72
|
+
retention-days: 14
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build wheel + sdist for ${{ github.ref_name }}
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
|
|
20
|
+
- name: Install build tooling
|
|
21
|
+
run: python -m pip install --upgrade pip build twine
|
|
22
|
+
|
|
23
|
+
- name: Build distributions
|
|
24
|
+
run: python -m build --wheel --sdist
|
|
25
|
+
|
|
26
|
+
- name: Check distributions
|
|
27
|
+
run: python -m twine check dist/*
|
|
28
|
+
|
|
29
|
+
- name: Upload artifacts
|
|
30
|
+
uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/*
|
|
34
|
+
|
|
35
|
+
publish-pypi:
|
|
36
|
+
name: Publish to PyPI
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
needs: build
|
|
39
|
+
# Trusted publishing — requires the PyPI project to opt into
|
|
40
|
+
# GitHub OIDC publishing under Settings → Publishing.
|
|
41
|
+
# Until then, leave this job disabled by editing the `if`.
|
|
42
|
+
if: ${{ false }}
|
|
43
|
+
environment:
|
|
44
|
+
name: pypi
|
|
45
|
+
url: https://pypi.org/p/cairn
|
|
46
|
+
permissions:
|
|
47
|
+
id-token: write
|
|
48
|
+
steps:
|
|
49
|
+
- name: Download artifacts
|
|
50
|
+
uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist
|
|
54
|
+
|
|
55
|
+
- name: Publish to PyPI
|
|
56
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
57
|
+
|
|
58
|
+
github-release:
|
|
59
|
+
name: Attach artifacts to GitHub release
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
needs: build
|
|
62
|
+
permissions:
|
|
63
|
+
contents: write
|
|
64
|
+
steps:
|
|
65
|
+
- name: Download artifacts
|
|
66
|
+
uses: actions/download-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
name: dist
|
|
69
|
+
path: dist
|
|
70
|
+
|
|
71
|
+
- name: Create GitHub release
|
|
72
|
+
uses: softprops/action-gh-release@v2
|
|
73
|
+
with:
|
|
74
|
+
files: dist/*
|
|
75
|
+
generate_release_notes: true
|
|
76
|
+
draft: false
|
|
77
|
+
prerelease: ${{ contains(github.ref_name, '-') || contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Repo regression
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "23 3 * * *"
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
public-repo-regression:
|
|
14
|
+
name: public repo regression
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 60
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.12"
|
|
25
|
+
cache: pip
|
|
26
|
+
|
|
27
|
+
- name: Install package + dev extras
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
python -m pip install -e ".[dev]"
|
|
31
|
+
|
|
32
|
+
- name: Labeled repo eval
|
|
33
|
+
run: python scripts/eval_repos.py --repo all --strict
|
|
34
|
+
|
|
35
|
+
- name: Broad repo smoke
|
|
36
|
+
run: python scripts/smoke_many_repos.py --limit 37 --strict
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
MANIFEST
|
|
23
|
+
|
|
24
|
+
# Virtual envs
|
|
25
|
+
.venv/
|
|
26
|
+
venv/
|
|
27
|
+
env/
|
|
28
|
+
ENV/
|
|
29
|
+
|
|
30
|
+
# Testing / coverage
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.hypothesis/
|
|
33
|
+
.coverage
|
|
34
|
+
.coverage.*
|
|
35
|
+
htmlcov/
|
|
36
|
+
.tox/
|
|
37
|
+
.nox/
|
|
38
|
+
coverage.xml
|
|
39
|
+
*.cover
|
|
40
|
+
|
|
41
|
+
# Linting / typing
|
|
42
|
+
.mypy_cache/
|
|
43
|
+
.ruff_cache/
|
|
44
|
+
.pyre/
|
|
45
|
+
|
|
46
|
+
# Tooling
|
|
47
|
+
.uv/
|
|
48
|
+
.codegraph/
|
|
49
|
+
uv.lock
|
|
50
|
+
.python-version
|
|
51
|
+
|
|
52
|
+
# IDEs
|
|
53
|
+
.idea/
|
|
54
|
+
.vscode/
|
|
55
|
+
*.swp
|
|
56
|
+
*.swo
|
|
57
|
+
|
|
58
|
+
# OS
|
|
59
|
+
.DS_Store
|
|
60
|
+
Thumbs.db
|
|
61
|
+
|
|
62
|
+
# Cairn runtime data
|
|
63
|
+
.cairn/documents/
|
|
64
|
+
.cairn/manifest.json
|
|
65
|
+
.cairn/inspector.html
|
|
66
|
+
*.lancedb/
|
|
67
|
+
*.sqlite
|
|
68
|
+
*.sqlite-*
|
|
69
|
+
|
|
70
|
+
# Secrets
|
|
71
|
+
.env
|
|
72
|
+
.env.*
|
|
73
|
+
!.env.example
|
|
74
|
+
|
|
75
|
+
# Logs
|
|
76
|
+
*.log
|
|
77
|
+
logs/
|
|
78
|
+
|
|
79
|
+
# Local agent runs / benchmarks output
|
|
80
|
+
runs/
|
|
81
|
+
results/
|
|
82
|
+
benchmarks/output/
|