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.
- axiom_appkit-0.0.1/.github/workflows/ci.yml +20 -0
- axiom_appkit-0.0.1/.github/workflows/publish.yml +67 -0
- axiom_appkit-0.0.1/.gitignore +11 -0
- axiom_appkit-0.0.1/CHANGELOG.md +15 -0
- axiom_appkit-0.0.1/LICENSE +17 -0
- axiom_appkit-0.0.1/NOTICE +6 -0
- axiom_appkit-0.0.1/PKG-INFO +57 -0
- axiom_appkit-0.0.1/README.md +38 -0
- axiom_appkit-0.0.1/docs/soilmetrix-appkit-migration.md +96 -0
- axiom_appkit-0.0.1/frontend/package-lock.json +1554 -0
- axiom_appkit-0.0.1/frontend/package.json +22 -0
- axiom_appkit-0.0.1/frontend/src/AppShell.tsx +47 -0
- axiom_appkit-0.0.1/frontend/src/ChatDock.tsx +62 -0
- axiom_appkit-0.0.1/frontend/src/WorkbenchLayout.tsx +55 -0
- axiom_appkit-0.0.1/frontend/src/index.ts +11 -0
- axiom_appkit-0.0.1/frontend/src/tokens.css +86 -0
- axiom_appkit-0.0.1/frontend/src/usePanel.ts +67 -0
- axiom_appkit-0.0.1/frontend/tsconfig.json +9 -0
- axiom_appkit-0.0.1/frontend/vite.config.ts +3 -0
- axiom_appkit-0.0.1/pyproject.toml +34 -0
- axiom_appkit-0.0.1/runtime/logs/cli_events.jsonl +6 -0
- axiom_appkit-0.0.1/runtime/logs/cli_events.jsonl.lock +0 -0
- axiom_appkit-0.0.1/src/axiom_appkit/__init__.py +28 -0
- axiom_appkit-0.0.1/src/axiom_appkit/extensions/__init__.py +0 -0
- axiom_appkit-0.0.1/src/axiom_appkit/extensions/builtins/__init__.py +0 -0
- axiom_appkit-0.0.1/src/axiom_appkit/extensions/builtins/appkit/axiom-extension.toml +22 -0
- axiom_appkit-0.0.1/src/axiom_appkit/mount.py +46 -0
- axiom_appkit-0.0.1/src/axiom_appkit/tests/__init__.py +0 -0
- axiom_appkit-0.0.1/src/axiom_appkit/tests/test_appkit.py +33 -0
- 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,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.
|