axiom-appkit 0.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 (30) hide show
  1. axiom_appkit-0.0.1/.github/workflows/ci.yml +20 -0
  2. axiom_appkit-0.0.1/.github/workflows/publish.yml +67 -0
  3. axiom_appkit-0.0.1/.gitignore +11 -0
  4. axiom_appkit-0.0.1/CHANGELOG.md +15 -0
  5. axiom_appkit-0.0.1/LICENSE +17 -0
  6. axiom_appkit-0.0.1/NOTICE +6 -0
  7. axiom_appkit-0.0.1/PKG-INFO +57 -0
  8. axiom_appkit-0.0.1/README.md +38 -0
  9. axiom_appkit-0.0.1/docs/soilmetrix-appkit-migration.md +96 -0
  10. axiom_appkit-0.0.1/frontend/package-lock.json +1554 -0
  11. axiom_appkit-0.0.1/frontend/package.json +22 -0
  12. axiom_appkit-0.0.1/frontend/src/AppShell.tsx +47 -0
  13. axiom_appkit-0.0.1/frontend/src/ChatDock.tsx +62 -0
  14. axiom_appkit-0.0.1/frontend/src/WorkbenchLayout.tsx +55 -0
  15. axiom_appkit-0.0.1/frontend/src/index.ts +11 -0
  16. axiom_appkit-0.0.1/frontend/src/tokens.css +86 -0
  17. axiom_appkit-0.0.1/frontend/src/usePanel.ts +67 -0
  18. axiom_appkit-0.0.1/frontend/tsconfig.json +9 -0
  19. axiom_appkit-0.0.1/frontend/vite.config.ts +3 -0
  20. axiom_appkit-0.0.1/pyproject.toml +34 -0
  21. axiom_appkit-0.0.1/runtime/logs/cli_events.jsonl +6 -0
  22. axiom_appkit-0.0.1/runtime/logs/cli_events.jsonl.lock +0 -0
  23. axiom_appkit-0.0.1/src/axiom_appkit/__init__.py +28 -0
  24. axiom_appkit-0.0.1/src/axiom_appkit/extensions/__init__.py +0 -0
  25. axiom_appkit-0.0.1/src/axiom_appkit/extensions/builtins/__init__.py +0 -0
  26. axiom_appkit-0.0.1/src/axiom_appkit/extensions/builtins/appkit/axiom-extension.toml +22 -0
  27. axiom_appkit-0.0.1/src/axiom_appkit/mount.py +46 -0
  28. axiom_appkit-0.0.1/src/axiom_appkit/tests/__init__.py +0 -0
  29. axiom_appkit-0.0.1/src/axiom_appkit/tests/test_appkit.py +33 -0
  30. axiom_appkit-0.0.1/src/axiom_appkit/tokens.css +86 -0
@@ -0,0 +1,20 @@
1
+ name: ci
2
+ on: { push: { branches: [main] }, pull_request: {} }
3
+ jobs:
4
+ python:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v4
8
+ - uses: actions/setup-python@v5
9
+ with: { python-version: "3.11" }
10
+ - run: pip install -e ".[dev]"
11
+ - run: ruff check src
12
+ - run: pip install fastapi httpx && pytest -q
13
+ frontend:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with: { node-version: "20" }
19
+ - working-directory: frontend
20
+ run: npm install && npm run typecheck
@@ -0,0 +1,67 @@
1
+ # Copyright (c) 2026 B-Tree Labs
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Publish axiom-appkit to PyPI — the same mechanism as axiom-os-lm: a trusted
5
+ # publisher (OIDC), no stored token, triggered on v* tags. The source repo stays
6
+ # private; the wheel is public on PyPI, so any Axiom node installs appkit as an
7
+ # ordinary dependency (no deploy key, no credential).
8
+ #
9
+ # ONE-TIME SETUP (owner action, mirrors axiom-os-lm): on pypi.org, create/claim
10
+ # the `axiom-appkit` project and add a GitHub trusted publisher —
11
+ # owner: b-tree-labs · repo: axiom-appkit · workflow: publish.yml · environment: pypi
12
+ # Until that exists the publish step fails with `invalid-publisher` (this is the
13
+ # axiom v0.7.0–v0.10.1 lesson: configure the publisher before the first tag).
14
+
15
+ name: Publish to PyPI
16
+ on:
17
+ push:
18
+ tags: ["v*"]
19
+ workflow_dispatch:
20
+ inputs:
21
+ ref: { description: "Tag or commit to publish", required: true, default: "main" }
22
+
23
+ jobs:
24
+ build:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: actions/setup-python@v5
29
+ with: { python-version: "3.11" }
30
+ - run: pip install build
31
+ - run: python -m build
32
+ - uses: actions/upload-artifact@v4
33
+ with: { name: dist, path: dist/ }
34
+
35
+ publish:
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ permissions: { id-token: write }
39
+ environment: pypi
40
+ outputs: { version: "${{ steps.v.outputs.version }}" }
41
+ steps:
42
+ - uses: actions/download-artifact@v4
43
+ with: { name: dist, path: dist/ }
44
+ - id: v
45
+ run: |
46
+ wheel=$(ls dist/*.whl | head -1)
47
+ version=$(basename "$wheel" | sed -E 's/^axiom_appkit-([^-]+)-.*/\1/')
48
+ echo "version=$version" >> "$GITHUB_OUTPUT"
49
+ echo "Publishing axiom-appkit $version"
50
+ - uses: pypa/gh-action-pypi-publish@release/v1
51
+
52
+ post_publish_smoke:
53
+ needs: publish
54
+ runs-on: ubuntu-latest
55
+ steps:
56
+ - name: Wait for PyPI to index, then install + import
57
+ env: { VERSION: "${{ needs.publish.outputs.version }}" }
58
+ run: |
59
+ set -euo pipefail
60
+ pip install --upgrade pip
61
+ for a in $(seq 1 30); do
62
+ if pip index versions axiom-appkit 2>/dev/null | grep -q "$VERSION"; then
63
+ echo "axiom-appkit $VERSION resolvable"; break
64
+ fi; sleep 10
65
+ done
66
+ pip install "axiom-appkit==$VERSION"
67
+ python -c "import axiom_appkit; assert axiom_appkit.design_tokens_css().find('--accent')>=0; print('import + tokens ok')"
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ node_modules/
8
+ frontend/dist/
9
+ .coverage
10
+ .pytest_cache/
11
+ .ruff_cache/
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ All notable changes to axiom-appkit are documented here. Format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows SemVer.
5
+
6
+ ## [Unreleased]
7
+
8
+ ### Added
9
+
10
+ - Repository scaffold: Python package (`axiom_appkit`) with the Axiom composition
11
+ hook and extension manifest; React + Vite + TypeScript + Tailwind frontend skeleton.
12
+ - **Design tokens** — the single source of truth for the Axiom app design system
13
+ (IBM Plex pairing, the light/dark token palette, burnt-orange accent), extracted
14
+ from the hand-repeated CSS in the consumer surfaces.
15
+ - **AppShell** — the shared top-bar / brand / identity / nav shell component.
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright (c) 2026 B-Tree Labs
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
@@ -0,0 +1,6 @@
1
+ axiom-appkit
2
+ Copyright (c) 2026 B-Tree Labs
3
+
4
+ The domain-agnostic front-end and application framework for Axiom (AEOS).
5
+ Composes into a single Axiom node; consumed by independent tenants (e.g.
6
+ NeutronOS and SoilMetrix). No consumer-domain content belongs in this repo.
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.5
2
+ Name: axiom-appkit
3
+ Version: 0.0.1
4
+ Summary: Domain-agnostic front-end and application framework for Axiom (AEOS)
5
+ Project-URL: Homepage, https://github.com/b-tree-labs/axiom-appkit
6
+ Project-URL: Repository, https://github.com/b-tree-labs/axiom-appkit
7
+ Author: B-Tree Labs
8
+ License: Apache-2.0
9
+ License-File: LICENSE
10
+ License-File: NOTICE
11
+ Keywords: aeos,axiom,fastapi,framework,frontend
12
+ Requires-Python: >=3.11
13
+ Provides-Extra: axiom
14
+ Requires-Dist: axiom-os-lm>=0.10; extra == 'axiom'
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8; extra == 'dev'
17
+ Requires-Dist: ruff>=0.6; extra == 'dev'
18
+ Description-Content-Type: text/markdown
19
+
20
+ # axiom-appkit
21
+
22
+ The domain-agnostic **front-end and application framework** for Axiom (AEOS) — the
23
+ tier above Axiom's HTTP primitives (`http`, `webgate`, the mount registry) that turns
24
+ declared surfaces into one coherent application: a shared design system, a React + Vite
25
+ + TypeScript app shell and component library, FastAPI application conventions, and the
26
+ agent-management and prompt-engineering surfaces.
27
+
28
+ ## Position
29
+
30
+ ```
31
+ React app shell + component library (this repo, frontend/)
32
+
33
+ FastAPI app conventions + mounts (this repo, src/axiom_appkit/)
34
+ │ composes via the extension registry into
35
+ Axiom node — http / webgate / registry (axiom core)
36
+
37
+ axiom.infra.db (ORM + OLTP) ← routine upsert from the medallion gold layer
38
+ ```
39
+
40
+ - **Standalone, but it composes.** appkit is its own package with its own release
41
+ cadence; it registers into the *one* Axiom node via the extension manifest, never a
42
+ separate runtime.
43
+ - **Domain-agnostic by construction.** No reactor, no agriculture — appkit is proven by
44
+ two independent tenants and carries neither's domain. Consumers supply their brand,
45
+ their surfaces, and their data.
46
+ - **Extend, don't fork.** Persistence rides `axiom.infra.db`; HTTP rides Axiom's mount
47
+ registry. appkit is the application tier on top.
48
+
49
+ ## Layout
50
+
51
+ | Path | What |
52
+ |---|---|
53
+ | `frontend/` | React 18 + Vite + TypeScript + Tailwind — design tokens, app shell, components |
54
+ | `src/axiom_appkit/` | FastAPI app conventions + the composition hook that mounts appkit into an Axiom node |
55
+ | `src/axiom_appkit/extensions/builtins/appkit/` | the `axiom-extension.toml` manifest for discovery |
56
+
57
+ Apache-2.0. Copyright (c) 2026 B-Tree Labs.
@@ -0,0 +1,38 @@
1
+ # axiom-appkit
2
+
3
+ The domain-agnostic **front-end and application framework** for Axiom (AEOS) — the
4
+ tier above Axiom's HTTP primitives (`http`, `webgate`, the mount registry) that turns
5
+ declared surfaces into one coherent application: a shared design system, a React + Vite
6
+ + TypeScript app shell and component library, FastAPI application conventions, and the
7
+ agent-management and prompt-engineering surfaces.
8
+
9
+ ## Position
10
+
11
+ ```
12
+ React app shell + component library (this repo, frontend/)
13
+
14
+ FastAPI app conventions + mounts (this repo, src/axiom_appkit/)
15
+ │ composes via the extension registry into
16
+ Axiom node — http / webgate / registry (axiom core)
17
+
18
+ axiom.infra.db (ORM + OLTP) ← routine upsert from the medallion gold layer
19
+ ```
20
+
21
+ - **Standalone, but it composes.** appkit is its own package with its own release
22
+ cadence; it registers into the *one* Axiom node via the extension manifest, never a
23
+ separate runtime.
24
+ - **Domain-agnostic by construction.** No reactor, no agriculture — appkit is proven by
25
+ two independent tenants and carries neither's domain. Consumers supply their brand,
26
+ their surfaces, and their data.
27
+ - **Extend, don't fork.** Persistence rides `axiom.infra.db`; HTTP rides Axiom's mount
28
+ registry. appkit is the application tier on top.
29
+
30
+ ## Layout
31
+
32
+ | Path | What |
33
+ |---|---|
34
+ | `frontend/` | React 18 + Vite + TypeScript + Tailwind — design tokens, app shell, components |
35
+ | `src/axiom_appkit/` | FastAPI app conventions + the composition hook that mounts appkit into an Axiom node |
36
+ | `src/axiom_appkit/extensions/builtins/appkit/` | the `axiom-extension.toml` manifest for discovery |
37
+
38
+ Apache-2.0. Copyright (c) 2026 B-Tree Labs.
@@ -0,0 +1,96 @@
1
+ # SoilMetrix → axiom-appkit migration ledger
2
+
3
+ **Status:** living document · **Owner:** Ben Booth · **Audience:** appkit + SoilMetrix + NeutronOS devs
4
+
5
+ ## The plan
6
+
7
+ Extract everything in SoilMetrix that is **not agriculture-specific** into `axiom-appkit`,
8
+ feature by feature. For each extracted feature the sequence is the same:
9
+
10
+ 1. **Extract** the generic capability into appkit (domain-agnostic, no soil, no reactor).
11
+ 2. **Adopt in SoilMetrix** — SoilMetrix swaps its bespoke implementation for the appkit
12
+ version (back-compatible by construction — appkit must not force a rewrite).
13
+ 3. **Deploy as foundation in NeutronOS** — the same appkit version becomes the basis of the
14
+ NOS front end.
15
+
16
+ Two independent tenants (SoilMetrix = agriculture, NeutronOS = nuclear) prove each feature is
17
+ genuinely domain-agnostic. Where appkit can do better than SoilMetrix's current version
18
+ (agent management, prompt engineering, auth), the extraction is also an **upgrade**.
19
+
20
+ **The rule:** a feature is agriculture-specific if it references crops, soil, fields, zones,
21
+ SSURGO/Modus/geospatial-soil, or the patented ML soil pipeline. Everything else is a candidate.
22
+
23
+ ## Ledger
24
+
25
+ Legend — appkit: ☐ not started · ◐ in progress · ☑ shipped. SoilMetrix / NOS: ☐ · ◐ · ☑ adopted.
26
+
27
+ | # | SoilMetrix feature | Agriculture-specific? | appkit target | appkit | SoilMetrix swap | NOS adopt |
28
+ |---|---|---|---|---|---|---|
29
+ | 1 | Design system / CSS tokens | No | `tokens.css` (single source) | ◐ | ☐ | ☐ |
30
+ | 2 | App shell (top bar / brand / identity / nav) | No | `AppShell` | ◐ | ☐ | ☐ |
31
+ | 3 | FastAPI app conventions (routes/services/models/middleware/validation) | No | appkit FastAPI scaffold | ☐ | ☐ | ☐ |
32
+ | 4 | ORM base + OLTP session | No | extend `axiom.infra.db` | ☐ | ☐ | ☐ |
33
+ | 5 | gold → OLTP upsert primitive (`ON CONFLICT UPDATE`) | No | appkit upsert primitive | ☐ | ☐ | ☐ |
34
+ | 6 | Auth | No — **DEEP MERGE** (see below) | webgate base + SoilMetrix depth | ◐ | ☐ | ☑ (NOS gate) |
35
+ | 7 | Forms + typed validation (React Hook Form + Zod) | No | appkit forms | ☐ | ☐ | ☐ |
36
+ | 8 | Chart / viz components | No | appkit chart components (Signal Studio-derived) | ☐ | ☐ | ☐ |
37
+ | 8a | App shell (top bar / nav) | No | `AppShell` | ◐ | ☐ | ☐ |
38
+ | 8b | Three-region layout (left rail / center / right dock, collapsible + resizable + persisted) | No | `WorkbenchLayout` + `usePanel` | ◐ | ☐ | ☐ |
39
+ | 8c | Chat UX idiom (log + composer + suggestions, dockable) | No | `ChatDock` | ◐ | ☐ | ☐ |
40
+ | 9 | AI chat / agent infra | No — **DEEP MERGE** (see below) | unified agentic chat | ☐ | ☐ | ☐ |
41
+ | 10 | Prompt infra | No — **DEEP MERGE** (see below) | versioned + evaluated prompt system | ☐ | ☐ | ☐ |
42
+ | 11 | RAG / chat surface | No (corpus is tenant's) | appkit chat surface + tenant RAG | ☐ | ☐ | ☐ |
43
+ | 12 | Admin / ops MCP surface | No | appkit admin surface | ☐ | ☐ | ☐ |
44
+ | 13 | Observability / metrics / health conventions | No | appkit app conventions | ☐ | ☐ | ☐ |
45
+ | 14 | Map / field viewer (Leaflet/MapBox, field geometry) | **YES — stays in SoilMetrix** | — | — | — | — |
46
+ | 15 | Soil ML pipeline (SSURGO, Modus, ensemble models) | **YES — stays in SoilMetrix** | — | — | — | — |
47
+ | 16 | Crop / yield / zone-map domain models | **YES — stays in SoilMetrix** | — | — | — | — |
48
+
49
+ ## Deep merges — prove, don't regress (chat, prompt, auth)
50
+
51
+ Three items are **not extractions** — they are **merges of two mature systems**, and the risk is
52
+ entirely regression of depth that already works. They get a different, slower discipline than the
53
+ FE extractions. Do not swap either side out until the unified capability is proven a strict
54
+ superset of both.
55
+
56
+ **The discipline for each deep merge:**
57
+
58
+ 1. **Inventory both sides honestly.** Write down what each system already does well — the features
59
+ a user would notice if they disappeared. Neither side is assumed to be the base.
60
+ 2. **Design the union as a strict superset.** The appkit version must do everything both sides do,
61
+ or the gap is named and accepted explicitly. "Better" is a claim to be proven, not assumed.
62
+ 3. **Prove no regression against BOTH tenants.** A parity harness / evaluation — real conversations,
63
+ real prompts, real logins — comparing the unified capability against each original, before any
64
+ cutover. Vibes do not count; this is the same posture as validating a ROM against measurement.
65
+ 4. **Cut over behind a flag, with rollback.** Each tenant flips when its parity passes, not on a
66
+ shared date. Keep both paths runnable until the flag has burned in.
67
+ 5. **Retire the originals only after burn-in.** The two systems coexist until the unified one has
68
+ carried real traffic without regression.
69
+
70
+ | Deep merge | SoilMetrix depth (don't lose) | NOS / Axiom depth (don't lose) | Unified target |
71
+ |---|---|---|---|
72
+ | **AI chat infra** | Field Hand agentic chat: tool actions, clarification, UI commands, artifacts, web-search sources, voice replies, custom instructions, multi-account, chat library/rename/move | Tenant-scoped ask grounded in gold verbs + the site corpus; the fused-RAG engine (semantic + structured tool-calling); `neut chat`; chat memory | One agentic chat: appkit owns the surface + orchestration; retrieval and tools stay tenant-scoped; both tenants' feature sets present |
73
+ | **Prompt infra** | Custom instructions, per-context prompt assembly | Prompts as versioned, evaluated platform assets; per-site / per-surface assembly by construction | One prompt system: versioned + evaluated assets, per-tenant/per-surface assembly, custom instructions preserved |
74
+ | **Auth** | Account model, staff tiers, OpsGate/TermsGate, reverify, session UX | webgate: OIDC/Entra SSO, ES256 sessions, forward-auth, roles, audit — **ahead on SSO/MFA/audit** | webgate as the base (the upgrade direction), but only after SoilMetrix's account/staff-tier/terms/reverify depth is carried — an adopt, not a naive swap |
75
+
76
+ These land **after** the low-risk FE extractions. The chat *UI* shell (`ChatDock`) is safe and
77
+ already extracted; the chat *engine/infra*, the prompt infra, and auth are the deep merges that
78
+ wait for the parity discipline above.
79
+
80
+ ## Notes per feature (filled in as we work each one)
81
+
82
+ - **#1 Design tokens (in progress):** appkit ships `tokens.css` as the single source; the
83
+ palette structure is appkit's, brand values (`--accent`) are tenant overrides (NOS burnt
84
+ orange, SoilMetrix green). NOS surfaces (`home.py`, studio `PAGE_TEMPLATE`) currently inline
85
+ these tokens; swap them to link `/_appkit/tokens.css`.
86
+ - **#2 AppShell (in progress):** the top bar (brand, context name, identity, nav) both tenants
87
+ repeat. appkit `AppShell` is the shared component; consumers pass brand + nav + user.
88
+ - **#8b WorkbenchLayout (in progress):** generalized from SoilMetrix's `ForeFlightLayout` — the
89
+ three-region frame (left nav rail, center that keeps min width, right dock) with per-key width
90
+ persistence, drag-to-resize with snap-to-collapse, and responsive collapse to overlays on narrow
91
+ viewports. `usePanel` is the shared collapsible/resizable/persisted primitive both sides use.
92
+ Maps 1:1 onto Signal Studio's rail/chart/chat, so NOS is the immediate first consumer.
93
+ - **#8c ChatDock (in progress):** the right-panel chat idiom from Field Hand, stripped to the shape
94
+ — scrolling message log, pinned composer, starter suggestions, header actions slot — with content
95
+ and the send handler supplied by the consumer. No agriculture, no reactor.
96
+ - Later rows get their own note + a spec section here when we pick them up.