kea-brain 1.0.1__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.
Files changed (116) hide show
  1. kea_brain-1.0.1/.claude-plugin/marketplace.json +19 -0
  2. kea_brain-1.0.1/.claude-plugin/plugin.json +14 -0
  3. kea_brain-1.0.1/.editorconfig +34 -0
  4. kea_brain-1.0.1/.github/ISSUE_TEMPLATE/bug_report.yml +25 -0
  5. kea_brain-1.0.1/.github/ISSUE_TEMPLATE/config.yml +6 -0
  6. kea_brain-1.0.1/.github/ISSUE_TEMPLATE/feature_request.yml +16 -0
  7. kea_brain-1.0.1/.github/dependabot.yml +11 -0
  8. kea_brain-1.0.1/.github/pull_request_template.md +20 -0
  9. kea_brain-1.0.1/.github/workflows/dev.yml +70 -0
  10. kea_brain-1.0.1/.github/workflows/python-checks.yml +107 -0
  11. kea_brain-1.0.1/.github/workflows/python-tests.yml +52 -0
  12. kea_brain-1.0.1/.github/workflows/release.yml +67 -0
  13. kea_brain-1.0.1/.gitignore +19 -0
  14. kea_brain-1.0.1/.mcp.json +15 -0
  15. kea_brain-1.0.1/AGENTS.md +58 -0
  16. kea_brain-1.0.1/CHANGELOG.md +52 -0
  17. kea_brain-1.0.1/CODE_OF_CONDUCT.md +6 -0
  18. kea_brain-1.0.1/CONTRIBUTING.md +34 -0
  19. kea_brain-1.0.1/Dockerfile +20 -0
  20. kea_brain-1.0.1/LICENSE +21 -0
  21. kea_brain-1.0.1/Makefile +137 -0
  22. kea_brain-1.0.1/PKG-INFO +307 -0
  23. kea_brain-1.0.1/README.md +265 -0
  24. kea_brain-1.0.1/SECURITY.md +36 -0
  25. kea_brain-1.0.1/docs/MANUAL.md +366 -0
  26. kea_brain-1.0.1/docs/brand/mark.svg +11 -0
  27. kea_brain-1.0.1/docs/images/banner-dark.png +0 -0
  28. kea_brain-1.0.1/docs/images/banner-light.png +0 -0
  29. kea_brain-1.0.1/docs/images/social-preview.png +0 -0
  30. kea_brain-1.0.1/llms.txt +20 -0
  31. kea_brain-1.0.1/pyproject.toml +130 -0
  32. kea_brain-1.0.1/scripts/bench.py +67 -0
  33. kea_brain-1.0.1/scripts/build_man.py +153 -0
  34. kea_brain-1.0.1/setup.cfg +20 -0
  35. kea_brain-1.0.1/skills/kea/SKILL.md +75 -0
  36. kea_brain-1.0.1/skills/kea-council/SKILL.md +47 -0
  37. kea_brain-1.0.1/skills/kea-frameworks/SKILL.md +32 -0
  38. kea_brain-1.0.1/src/kea/__init__.py +8 -0
  39. kea_brain-1.0.1/src/kea/__main__.py +3 -0
  40. kea_brain-1.0.1/src/kea/_version.py +1 -0
  41. kea_brain-1.0.1/src/kea/brain.py +506 -0
  42. kea_brain-1.0.1/src/kea/cli.py +1251 -0
  43. kea_brain-1.0.1/src/kea/council.py +630 -0
  44. kea_brain-1.0.1/src/kea/data/MANUAL.md +366 -0
  45. kea_brain-1.0.1/src/kea/data/example/DECISIONS.md +36 -0
  46. kea_brain-1.0.1/src/kea/data/example/IDEAS.md +16 -0
  47. kea_brain-1.0.1/src/kea/data/example/METRICS.md +13 -0
  48. kea_brain-1.0.1/src/kea/data/example/PREDICTIONS.md +68 -0
  49. kea_brain-1.0.1/src/kea/data/example/ROADMAP.md +27 -0
  50. kea_brain-1.0.1/src/kea/data/example/STATE.md +42 -0
  51. kea_brain-1.0.1/src/kea/data/example/frameworks/INDEX.md +7 -0
  52. kea_brain-1.0.1/src/kea/data/example/frameworks/constraints.md +94 -0
  53. kea_brain-1.0.1/src/kea/data/example/journal/wholesale-samples.md +11 -0
  54. kea_brain-1.0.1/src/kea/data/example/plans/second-cafe/00-proposal.md +64 -0
  55. kea_brain-1.0.1/src/kea/data/example/plans/second-cafe/01-review-questions.md +9 -0
  56. kea_brain-1.0.1/src/kea/data/example/plans/second-cafe/reviews/example_chair_your-agent.md +25 -0
  57. kea_brain-1.0.1/src/kea/data/example/plans/second-cafe/reviews/example_contrarian_gpt-oss-120b.md +26 -0
  58. kea_brain-1.0.1/src/kea/data/example/plans/second-cafe/reviews/example_operator_mistral-small-latest.md +26 -0
  59. kea_brain-1.0.1/src/kea/data/kea.1 +421 -0
  60. kea_brain-1.0.1/src/kea/data/skills/kea/SKILL.md +75 -0
  61. kea_brain-1.0.1/src/kea/data/skills/kea-council/SKILL.md +47 -0
  62. kea_brain-1.0.1/src/kea/data/skills/kea-frameworks/SKILL.md +32 -0
  63. kea_brain-1.0.1/src/kea/data/templates/AGENTS.md +63 -0
  64. kea_brain-1.0.1/src/kea/data/templates/CLAUDE.md +1 -0
  65. kea_brain-1.0.1/src/kea/data/templates/DECISIONS.md +9 -0
  66. kea_brain-1.0.1/src/kea/data/templates/IDEAS.md +8 -0
  67. kea_brain-1.0.1/src/kea/data/templates/LEARNING.md +17 -0
  68. kea_brain-1.0.1/src/kea/data/templates/METRICS.md +8 -0
  69. kea_brain-1.0.1/src/kea/data/templates/PREDICTIONS.md +11 -0
  70. kea_brain-1.0.1/src/kea/data/templates/README.md +21 -0
  71. kea_brain-1.0.1/src/kea/data/templates/ROADMAP.md +28 -0
  72. kea_brain-1.0.1/src/kea/data/templates/SOURCES.md +22 -0
  73. kea_brain-1.0.1/src/kea/data/templates/STATE.md +23 -0
  74. kea_brain-1.0.1/src/kea/data/templates/VOICE.md +16 -0
  75. kea_brain-1.0.1/src/kea/data/templates/council/PROTOCOL.md +69 -0
  76. kea_brain-1.0.1/src/kea/data/templates/council/roster.toml +80 -0
  77. kea_brain-1.0.1/src/kea/data/templates/frameworks/INDEX.md +16 -0
  78. kea_brain-1.0.1/src/kea/data/templates/frameworks/_TEMPLATE.md +80 -0
  79. kea_brain-1.0.1/src/kea/data/templates/gitignore +6 -0
  80. kea_brain-1.0.1/src/kea/data/templates/journal/README.md +4 -0
  81. kea_brain-1.0.1/src/kea/data/templates/kea.toml +27 -0
  82. kea_brain-1.0.1/src/kea/data/templates/plans/_template/00-proposal.md +79 -0
  83. kea_brain-1.0.1/src/kea/data/templates/plans/_template/01-review-questions.md +36 -0
  84. kea_brain-1.0.1/src/kea/data/templates/plans/_template/20-production-plan.md +44 -0
  85. kea_brain-1.0.1/src/kea/data/templates/plans/_template/30-execution-log.md +23 -0
  86. kea_brain-1.0.1/src/kea/digest.py +210 -0
  87. kea_brain-1.0.1/src/kea/ingest.py +1014 -0
  88. kea_brain-1.0.1/src/kea/ledger.py +913 -0
  89. kea_brain-1.0.1/src/kea/markdown.py +431 -0
  90. kea_brain-1.0.1/src/kea/mcp.py +756 -0
  91. kea_brain-1.0.1/src/kea/providers.py +333 -0
  92. kea_brain-1.0.1/src/kea/py.typed +0 -0
  93. kea_brain-1.0.1/src/kea/redact.py +517 -0
  94. kea_brain-1.0.1/src/kea/skills.py +92 -0
  95. kea_brain-1.0.1/src/kea/store.py +499 -0
  96. kea_brain-1.0.1/src/kea_brain.egg-info/PKG-INFO +307 -0
  97. kea_brain-1.0.1/src/kea_brain.egg-info/SOURCES.txt +115 -0
  98. kea_brain-1.0.1/src/kea_brain.egg-info/dependency_links.txt +1 -0
  99. kea_brain-1.0.1/src/kea_brain.egg-info/entry_points.txt +2 -0
  100. kea_brain-1.0.1/src/kea_brain.egg-info/requires.txt +14 -0
  101. kea_brain-1.0.1/src/kea_brain.egg-info/scm_file_list.json +110 -0
  102. kea_brain-1.0.1/src/kea_brain.egg-info/scm_version.json +8 -0
  103. kea_brain-1.0.1/src/kea_brain.egg-info/top_level.txt +1 -0
  104. kea_brain-1.0.1/tests/conftest.py +66 -0
  105. kea_brain-1.0.1/tests/kea/test_brain.py +109 -0
  106. kea_brain-1.0.1/tests/kea/test_cli.py +172 -0
  107. kea_brain-1.0.1/tests/kea/test_council.py +230 -0
  108. kea_brain-1.0.1/tests/kea/test_digest.py +67 -0
  109. kea_brain-1.0.1/tests/kea/test_hardening.py +1399 -0
  110. kea_brain-1.0.1/tests/kea/test_ingest.py +363 -0
  111. kea_brain-1.0.1/tests/kea/test_ledger.py +183 -0
  112. kea_brain-1.0.1/tests/kea/test_markdown.py +108 -0
  113. kea_brain-1.0.1/tests/kea/test_mcp.py +116 -0
  114. kea_brain-1.0.1/tests/kea/test_redact.py +53 -0
  115. kea_brain-1.0.1/tests/kea/test_redact_corpus.py +296 -0
  116. kea_brain-1.0.1/tests/kea/test_skills.py +44 -0
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "kea",
4
+ "description": "kea: a second brain that checks its facts, for you and your agents.",
5
+ "owner": {
6
+ "name": "James Phillip Sanders",
7
+ "email": "hello@jamesphillipsanders.com"
8
+ },
9
+ "plugins": [
10
+ {
11
+ "name": "kea",
12
+ "description": "Sourced facts, decisions with revisit dates, scored predictions, a council of rival models and local search over your AI sessions: three skills and an MCP server.",
13
+ "version": "1.0.1",
14
+ "source": "./",
15
+ "category": "productivity",
16
+ "homepage": "https://github.com/jpsanders/kea"
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "kea",
3
+ "description": "A second brain that checks its facts: sourced facts, decisions with revisit dates, scored predictions, a council of rival AI models, and local search over your AI sessions. Three skills and an MCP server.",
4
+ "version": "1.0.1",
5
+ "author": {
6
+ "name": "James Phillip Sanders",
7
+ "email": "hello@jamesphillipsanders.com",
8
+ "url": "https://jamesphillipsanders.com"
9
+ },
10
+ "homepage": "https://github.com/jpsanders/kea",
11
+ "repository": "https://github.com/jpsanders/kea",
12
+ "license": "MIT",
13
+ "keywords": ["second-brain", "memory", "decisions", "predictions", "calibration", "council", "mcp", "search", "pkm"]
14
+ }
@@ -0,0 +1,34 @@
1
+ root = true
2
+
3
+ [*.{sh,py}]
4
+ indent_style = space
5
+ indent_size = 4
6
+ tab_width = 4
7
+ end_of_line = lf
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+ max_line_length = 120
11
+
12
+ [*.{yaml,yml,toml}]
13
+ indent_style = space
14
+ indent_size = 2
15
+ tab_width = 2
16
+ end_of_line = lf
17
+ trim_trailing_whitespace = true
18
+ insert_final_newline = true
19
+ max_line_length = 120
20
+
21
+ [*.md]
22
+ trim_trailing_whitespace = true
23
+ max_line_length = 120
24
+ insert_final_newline = true
25
+
26
+ [*.json]
27
+ indent_style = space
28
+ indent_size = 2
29
+ end_of_line = lf
30
+ insert_final_newline = true
31
+
32
+ # Badge rows, the skill front matter and generated roff carry long lines by design
33
+ [{SKILL.md,*.1,README.md}]
34
+ max_line_length = off
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: Bug report
3
+ description: A command that did not do what the manual says
4
+ labels: ["bug"]
5
+ body:
6
+ - type: textarea
7
+ id: what
8
+ attributes:
9
+ label: What happened
10
+ description: The command you ran, what it did, and what you expected instead.
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: output
15
+ attributes:
16
+ label: Output
17
+ description: The output, ideally with --json. Remove anything private from your brain first.
18
+ render: text
19
+ - type: input
20
+ id: version
21
+ attributes:
22
+ label: kea, Python and operating system
23
+ placeholder: kea 1.0.1, Python 3.15.2 on Ubuntu 26.04
24
+ validations:
25
+ required: true
@@ -0,0 +1,6 @@
1
+ ---
2
+ blank_issues_enabled: true
3
+ contact_links:
4
+ - name: Security problem
5
+ url: https://github.com/jpsanders/kea/security/advisories/new
6
+ about: Report security problems privately, please.
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: Feature request
3
+ description: A source to ingest, a provider, a check, or a command kea should have
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: textarea
7
+ id: problem
8
+ attributes:
9
+ label: The problem
10
+ description: What you do by hand today, or what your agent gets wrong without it.
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: idea
15
+ attributes:
16
+ label: What would help
@@ -0,0 +1,11 @@
1
+ ---
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "github-actions"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "monthly"
8
+ - package-ecosystem: "pip"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "monthly"
@@ -0,0 +1,20 @@
1
+ ### Description
2
+ <!--- Provide a brief description of the changes introduced by this pull request -->
3
+
4
+ ### Reference
5
+ <!--- Provide the related ticket(s) or issue id(s) this PR addresses -->
6
+ **Ticket:**
7
+
8
+ ### Additional Notes
9
+ <!--- Add any additional notes or comments for the reviewers (test instructions, examples, screenshots etc) -->
10
+
11
+ ### Checklist
12
+ <!--- Use this checklist to make sure you haven't missed anything -->
13
+
14
+ - [ ] Related tests have been added or updated, (if applicable)
15
+ - [ ] Updated documentation (if applicable)
16
+ - [ ] All checks and tests passed locally (`make checks`)
17
+ - [ ] All checks and tests passed in CI
18
+ - [ ] The branch is current with the base branch
19
+ - [ ] PR has a clean commit history
20
+ - [ ] Examples/additional configuration notes added to PR description (if applicable)
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: ci
3
+
4
+ on:
5
+ push:
6
+ branches:
7
+ - 'main'
8
+ pull_request:
9
+ branches:
10
+ - '*'
11
+ # Run CI manually
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ lint:
19
+ uses: "./.github/workflows/python-checks.yml"
20
+ with:
21
+ python-version: "3.15"
22
+
23
+ test:
24
+ needs: lint
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ os: ["ubuntu-latest", "macos-latest"]
29
+ uses: "./.github/workflows/python-tests.yml"
30
+ with:
31
+ os: ${{ matrix.os }}
32
+ python-version: "3.15"
33
+
34
+ # Proves the built wheel installs on its own and works, with no source tree around it.
35
+ package:
36
+ needs: test
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - name: "Checkout code"
40
+ uses: actions/checkout@v7
41
+ with:
42
+ fetch-depth: 0
43
+
44
+ - name: "Set up Python"
45
+ uses: actions/setup-python@v7
46
+ with:
47
+ python-version: "3.15"
48
+
49
+ - name: "Build the wheel and the sdist"
50
+ run: |
51
+ python -m pip install build
52
+ python -m build -o dist
53
+
54
+ - name: "Install the wheel in a clean environment and use it"
55
+ run: |
56
+ python -m venv /tmp/clean
57
+ /tmp/clean/bin/pip install dist/*.whl
58
+ cd /tmp
59
+ export XDG_CONFIG_HOME=/tmp/config
60
+ /tmp/clean/bin/kea --version
61
+ /tmp/clean/bin/kea init /tmp/demo --example --no-git
62
+ cd /tmp/demo
63
+ /tmp/clean/bin/kea status
64
+ /tmp/clean/bin/kea calibration --json
65
+ /tmp/clean/bin/kea synth second-cafe
66
+ /tmp/clean/bin/kea search wholesale --limit 1
67
+ /tmp/clean/bin/kea check
68
+ /tmp/clean/bin/kea guide | head -3
69
+ /tmp/clean/bin/kea man --raw | head -1
70
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | /tmp/clean/bin/kea mcp | head -c 200
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: python-checks
3
+
4
+ on:
5
+ workflow_call:
6
+ inputs:
7
+ python-version:
8
+ type: string
9
+ default: "3.15"
10
+
11
+ cache-dependency-path:
12
+ type: string
13
+ default: "pyproject.toml"
14
+
15
+ enable-ec:
16
+ type: boolean
17
+ default: true
18
+
19
+ enable-black:
20
+ type: boolean
21
+ default: true
22
+
23
+ enable-isort:
24
+ type: boolean
25
+ default: true
26
+
27
+ enable-lint:
28
+ type: boolean
29
+ default: true
30
+
31
+ enable-docstyle:
32
+ type: boolean
33
+ default: true
34
+
35
+ enable-mypy:
36
+ type: boolean
37
+ default: true
38
+
39
+ enable-bandit:
40
+ type: boolean
41
+ default: true
42
+
43
+ checkout-fetch-depth:
44
+ type: number
45
+ default: 1
46
+
47
+
48
+ jobs:
49
+ checks:
50
+ runs-on: ubuntu-latest
51
+
52
+ steps:
53
+ - name: "Checkout code"
54
+ uses: actions/checkout@v7
55
+ with:
56
+ fetch-depth: ${{ inputs.checkout-fetch-depth }}
57
+
58
+ - name: "Set up Python"
59
+ uses: actions/setup-python@v7
60
+ with:
61
+ python-version: ${{ inputs.python-version }}
62
+ cache: 'pip'
63
+ cache-dependency-path: ${{ inputs.cache-dependency-path }}
64
+
65
+ - name: "Install dependencies"
66
+ run: |
67
+ make init-dev
68
+
69
+ - name: "Run editorconfig-checker style checks"
70
+ if: ${{ inputs.enable-ec && (success() || failure()) }}
71
+ run: |
72
+ make ec
73
+
74
+ - name: "Run black style checks"
75
+ if: ${{ inputs.enable-black && (success() || failure()) }}
76
+ run: |
77
+ make black-check
78
+
79
+ - name: "Run isort import checks"
80
+ if: ${{ inputs.enable-isort && (success() || failure()) }}
81
+ run: |
82
+ make isort-check
83
+
84
+ - name: "Run bandit security checks"
85
+ if: ${{ inputs.enable-bandit && (success() || failure()) }}
86
+ run: |
87
+ make bandit
88
+
89
+ - name: "Run flake8 lint checks"
90
+ if: ${{ inputs.enable-lint && (success() || failure()) }}
91
+ run: |
92
+ make lint
93
+
94
+ - name: "Run docstring checks"
95
+ if: ${{ inputs.enable-docstyle && (success() || failure()) }}
96
+ run: |
97
+ make docstyle
98
+
99
+ - name: "Run mypy static type checks"
100
+ if: ${{ inputs.enable-mypy && (success() || failure()) }}
101
+ run: |
102
+ make mypy
103
+
104
+ - name: "Check the man page, the packaged manual and the packaged skills are up to date"
105
+ if: ${{ success() || failure() }}
106
+ run: |
107
+ make man-check
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: python-tests
3
+
4
+ on:
5
+ workflow_call:
6
+ inputs:
7
+ python-version:
8
+ type: string
9
+ default: "3.15"
10
+
11
+ os:
12
+ type: string
13
+ default: "ubuntu-latest"
14
+
15
+ cache-dependency-path:
16
+ type: string
17
+ default: "pyproject.toml"
18
+
19
+ enable-lfs:
20
+ type: boolean
21
+ default: false
22
+
23
+ checkout-fetch-depth:
24
+ type: number
25
+ default: 1
26
+
27
+
28
+ jobs:
29
+ test:
30
+ runs-on: ${{ inputs.os }}
31
+
32
+ steps:
33
+ - name: "Checkout code"
34
+ uses: actions/checkout@v7
35
+ with:
36
+ lfs: ${{ inputs.enable-lfs }}
37
+ fetch-depth: ${{ inputs.checkout-fetch-depth }}
38
+
39
+ - name: "Set up Python"
40
+ uses: actions/setup-python@v7
41
+ with:
42
+ python-version: ${{ inputs.python-version }}
43
+ cache: 'pip'
44
+ cache-dependency-path: ${{ inputs.cache-dependency-path }}
45
+
46
+ - name: "Install dependencies"
47
+ run: |
48
+ make init-dev
49
+
50
+ - name: "Run tests"
51
+ run: |
52
+ make pytest
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: release
3
+
4
+ on:
5
+ release:
6
+ types: [published]
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ assets:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: "Checkout the tag"
16
+ uses: actions/checkout@v7
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: "Set up Python"
21
+ uses: actions/setup-python@v7
22
+ with:
23
+ python-version: "3.15"
24
+
25
+ - name: "Check the README badge, the plugin, the MCP config and the changelog all name this version"
26
+ env:
27
+ TAG: ${{ github.event.release.tag_name }}
28
+ run: |
29
+ grep -q "badge/release-${TAG}-" README.md
30
+ grep -q "\"version\": \"${TAG}\"" .claude-plugin/plugin.json
31
+ grep -q "\"version\": \"${TAG}\"" .claude-plugin/marketplace.json
32
+ grep -q "kea-brain==${TAG}\"" .mcp.json
33
+ grep -q "^## ${TAG} " CHANGELOG.md
34
+
35
+ - name: "Build the wheel and the sdist"
36
+ run: |
37
+ python -m pip install build
38
+ python -m build -o dist
39
+ test -f "dist/kea_brain-${{ github.event.release.tag_name }}-py3-none-any.whl"
40
+
41
+ - name: "Attach them to the release"
42
+ env:
43
+ GH_TOKEN: ${{ github.token }}
44
+ run: gh release upload "${{ github.event.release.tag_name }}" dist/* --clobber
45
+
46
+
47
+ # Publishes kea-brain to PyPI through trusted publishing: PyPI trusts this workflow in this repository, so no token
48
+ # is stored anywhere. Off until the repository variable PUBLISH_TO_PYPI is "true".
49
+ pypi:
50
+ needs: assets
51
+ if: ${{ vars.PUBLISH_TO_PYPI == 'true' }}
52
+ runs-on: ubuntu-latest
53
+ environment:
54
+ name: pypi
55
+ url: https://pypi.org/project/kea-brain/
56
+ permissions:
57
+ contents: read
58
+ id-token: write
59
+ steps:
60
+ - name: "Download the wheel and the sdist the release now carries"
61
+ env:
62
+ GH_TOKEN: ${{ github.token }}
63
+ TAG: ${{ github.event.release.tag_name }}
64
+ run: gh release download "$TAG" -R "${{ github.repository }}" -D dist -p "kea_brain-*"
65
+
66
+ - name: "Publish to PyPI"
67
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,19 @@
1
+ # Make text search tools know that these "hidden" directories contain code
2
+ !/.github/
3
+
4
+ # Caches and build artifacts
5
+ __pycache__
6
+ /build
7
+ .terraform
8
+ .terraform.lock.hcl
9
+
10
+ # Per-user config such as the following should generally be stored in ~/.gitignore rather than here
11
+ #.python-version
12
+ #.envrc
13
+
14
+
15
+ # Local virtual environment and editor state
16
+ /.venv
17
+ /.idea
18
+ /src/*.egg-info
19
+ /src/kea/_version.py
@@ -0,0 +1,15 @@
1
+ {
2
+ "mcpServers": {
3
+ "kea": {
4
+ "command": "uvx",
5
+ "args": [
6
+ "--python",
7
+ "3.15",
8
+ "--from",
9
+ "kea-brain==1.0.1",
10
+ "kea",
11
+ "mcp"
12
+ ]
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,58 @@
1
+ # AGENTS.md
2
+
3
+ Instructions for AI coding agents working on kea itself. People will find them useful too. (To work inside a kea
4
+ brain, read that brain's own AGENTS.md, or the skill in `skills/kea/SKILL.md`.)
5
+
6
+ ## Commands
7
+
8
+ ```sh
9
+ make init-dev # install kea and the development tools into the active environment (Python 3.15)
10
+ make format # apply black and isort
11
+ make checks # every check CI runs, in CI's order; run it before you say a change is done
12
+ make man # rebuild the man page, the packaged manual and the packaged skills
13
+ make bench # start up and command times
14
+ make demo # the example brain in /tmp/kea-demo
15
+ make build # wheel and sdist into build/dist
16
+ ```
17
+
18
+ ## Layout
19
+
20
+ ```text
21
+ src/kea/cli.py the command line: one cmd_* function per command, lazy imports
22
+ src/kea/brain.py finding a brain, kea.toml, the clock, kea init
23
+ src/kea/markdown.py reading and writing ledger entries without touching other lines
24
+ src/kea/ledger.py facts, log, decisions, predictions, calibration, ideas, roadmap, check, status
25
+ src/kea/store.py the SQLite and FTS5 evidence index
26
+ src/kea/ingest.py the adapters: claude-code, codex, opencode, chatgpt, claude, git, docs, the brain
27
+ src/kea/redact.py the credential path denylist and secret redaction
28
+ src/kea/council.py plans, packets, the parallel council run, the synthesis scaffold
29
+ src/kea/providers.py OpenAI compatible, Gemini and Anthropic clients on urllib
30
+ src/kea/mcp.py the MCP server: tools, resources, prompts
31
+ src/kea/digest.py Claude Code transcripts as readable files
32
+ src/kea/skills.py installing the skills into agent folders
33
+ src/kea/data/ templates and example brains, plus generated files: MANUAL.md, kea.1, skills/
34
+ docs/MANUAL.md the one source for kea guide and the man page
35
+ skills/ the agent skills; make man copies them into the package
36
+ tests/kea/ pytest, one file per module
37
+ ```
38
+
39
+ ## Rules the checks enforce
40
+
41
+ - mypy runs in strict mode, on the tests too: every function has full type hints.
42
+ - Docstrings use the Sphinx style and darglint checks them. Private helpers (`_name`) need none.
43
+ - Imports are absolute. Lines are at most 120 characters in every file type, Markdown included.
44
+ - bandit fails on shell injection and string built SQL; a justified exception carries `# nosec <code>: <reason>`.
45
+ - `make checks` fails when `src/kea/data/MANUAL.md`, `kea.1` or the packaged skills are stale.
46
+
47
+ ## Conventions the checks cannot see
48
+
49
+ - No runtime dependencies. The standard library only; that is a feature.
50
+ - Every command that prints data takes `--json` with stable fields. Exit 0 on success, 1 on failure, 2 on bad
51
+ arguments. Commands load their modules lazily so start up stays near 30 ms.
52
+ - kea never writes outside the brain, the per user config and the folders a command names. Ingest is read only.
53
+ - Nothing leaves the machine except `kea council`, which asks first.
54
+ - When a command or option changes, update `docs/MANUAL.md` and the skills in the same commit, then `make man`.
55
+ - Add an entry to `CHANGELOG.md` for anything a user would notice.
56
+ - Tags carry the bare version, `1.2.0`, never `v1.2.0`. The release workflow checks that the README badge, the
57
+ plugin files, `.mcp.json` and the changelog all name the tag.
58
+ - Never commit secrets, a real brain, `.env` files or anything from `build/`.
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ Versions follow [semantic versioning](https://semver.org). Tags carry the bare version, such as `1.0.0`.
4
+
5
+ ## 1.0.1 (2026-11-14)
6
+
7
+ - kea is on PyPI as `kea-brain`: `uv tool install --python 3.15 kea-brain`, `pipx install kea-brain` or
8
+ `pip install kea-brain`. The command is still `kea`.
9
+ - The Claude Code plugin starts its MCP server from the PyPI wheel (`uvx --from kea-brain==1.0.1`), which is faster
10
+ than building from git.
11
+ - The release workflow publishes the wheel and the sdist that the GitHub release carries, through trusted publishing,
12
+ so no token is stored anywhere.
13
+ - A council seat whose server drops the connection while sending an error ends as a seat error with the HTTP status,
14
+ instead of an unhandled connection error; kea reads at most 4 KB of an error message.
15
+
16
+ ## 1.0.0 (2026-11-14)
17
+
18
+ The first release.
19
+
20
+ - **The ledger**, in plain Markdown that people and agents edit side by side: facts with a source and a verified date
21
+ (`kea fact`), a dated log (`kea log`), decisions with a revisit date or trigger (`kea decide`, `kea revisit`),
22
+ predictions with a date and a confidence (`kea predict`, `kea score`), parked ideas and a roadmap with a section for
23
+ what waits for the owner.
24
+ - **Calibration**: `kea calibration` gives the Brier score, skill over a coin, and ten buckets of stated against
25
+ observed confidence.
26
+ - **Health**: `kea status` shows the whole brain and six health checks; `kea check` lints unsourced facts, facts past
27
+ their recheck date, malformed entries and overdue decisions and predictions, and exits 1 on errors.
28
+ - **The council**: `kea plan new`, `kea brief` (one hashed packet for every seat), `kea council` (every ready seat in
29
+ parallel, with per provider pacing, after asking before anything leaves the machine) and `kea synth` (verdicts,
30
+ convergence, splits and solo insights). Twelve providers preset, any OpenAI compatible server, Ollama and LM Studio
31
+ for local seats.
32
+ - **Evidence search**: `kea ingest` indexes Claude Code, Codex and OpenCode sessions, ChatGPT and Claude exports, git
33
+ history and folders of notes into SQLite with FTS5, incrementally, read only, with credential paths refused and
34
+ secrets redacted. `kea search`, `kea show` with provenance and context, `kea effort` for where attention went,
35
+ `kea forget`.
36
+ - **Agents**: an MCP server with 25 tools, five resources and three prompts; three skills installed into Claude Code,
37
+ Codex, OpenCode and `~/.agents` by `kea skill install`; a Claude Code plugin; `AGENTS.md` and `CLAUDE.md` in every
38
+ brain.
39
+ - **Safety**: nothing shaped like a key or token is stored in the index or sent in a packet (provider keys,
40
+ `NAME_API_KEY=` lines, passwords in URLs, private keys), and unmistakable key shapes never reach the ledger;
41
+ credential paths such as `.ssh`, `.env.local`, shell histories and `.pem` files are refused, symbolic links
42
+ included; the index is private to you; requests follow no redirects; agents on MCP can neither add sources nor send
43
+ a packet off the machine unless `kea.toml` allows it.
44
+ Before release, three independent review agents found 56 issues. Six further rounds, by two more agents each,
45
+ checked the fixes and found more problems in them. Every leak, crash and loss of data they confirmed is fixed, and
46
+ each code fix is pinned by a test.
47
+ - `kea digest` turns a Claude Code transcript into private readable files in the brain's `digests/` folder.
48
+ - `kea init --example` makes a complete example brain to explore. `kea init` on an existing brain puts back missing
49
+ files and changes nothing else; `--add` makes a brain beside files you already have, and `--force` keeps a backup
50
+ of every file it overwrites.
51
+ - A manual for people and agents: `kea guide`, `kea man`, `man kea` after `kea man --install`.
52
+ - Python 3.15, no dependencies, lazy imports: about 30 ms to start.
@@ -0,0 +1,6 @@
1
+ # Code of conduct
2
+
3
+ This project follows the
4
+ [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
5
+ Be kind, assume good faith, and keep discussion about the work. Report unacceptable behaviour to
6
+ hello@jamesphillipsanders.com; reports are handled in confidence.
@@ -0,0 +1,34 @@
1
+ # Contributing
2
+
3
+ Issues and pull requests are welcome.
4
+
5
+ ## Set up
6
+
7
+ ```sh
8
+ git clone https://github.com/jpsanders/kea && cd kea
9
+ python3.15 -m venv .venv && . .venv/bin/activate
10
+ make init-dev
11
+ make demo
12
+ ```
13
+
14
+ ## Before a pull request
15
+
16
+ ```sh
17
+ make format # black and isort
18
+ make checks # every check CI runs, in the same order
19
+ ```
20
+
21
+ `make checks` runs isort, black, editorconfig-checker, darglint, flake8, mypy in strict mode, bandit, the manual and
22
+ skills freshness check and pytest with coverage. CI runs the same, then the tests on Linux and macOS, then installs
23
+ the built wheel in a clean environment and runs it against the example brain.
24
+
25
+ ## Changing things
26
+
27
+ - **No dependencies.** kea runs on the standard library alone. A change that needs a package needs a very good reason.
28
+ - **The manual** is `docs/MANUAL.md` and **the skills** are `skills/*/SKILL.md`. `make man` copies them into the
29
+ package and builds the man page; `make checks` fails while any copy is stale.
30
+ - **Templates** for new brains live in `src/kea/data/templates`, the example brain in `src/kea/data/example`. Keep
31
+ every line at 120 characters or fewer.
32
+ - **A new ingest source** is an adapter in `src/kea/ingest.py` that reads, never writes, passes every text through
33
+ `redact`, and comes with a test built on a small fake export.
34
+ - **Commits** are signed. Tags carry the bare version, `1.2.0`, never `v1.2.0`.
@@ -0,0 +1,20 @@
1
+ FROM python:3.15-slim
2
+
3
+ ARG USER=kea
4
+
5
+ # git lets kea ingest repositories; nothing else is needed at run time
6
+ RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/* \
7
+ && useradd -rms /bin/bash $USER
8
+
9
+ WORKDIR /app
10
+ COPY --chown=$USER:$USER src src
11
+ COPY --chown=$USER:$USER pyproject.toml README.md LICENSE ./
12
+ RUN --mount=source=.git,target=.git,type=bind \
13
+ python3 -m pip install --no-cache-dir .
14
+
15
+ USER $USER
16
+ WORKDIR /brain
17
+ ENV KEA_BRAIN=/brain
18
+ # docker run --rm -it -v ~/brain:/brain kea status
19
+ ENTRYPOINT ["kea"]
20
+ CMD ["status"]