Kotlin/Compose Desktop application under desktop/ with: - Gradle build: Kotlin 2.1, Compose 1.8, gRPC/Protobuf codegen, detekt - ExoClient: gRPC client for both ArtifactService and KnowledgeGraphService - Obsidian-style layout: collapsible tree sidebar, contextual main panel - Five view modes: artifact detail, note editor, search results, catalog, graph (stub) - Unified search bar with selector prefix support - Command palette (Ctrl+Shift+A) for quick actions - Menu bar with keyboard shortcuts (Ctrl+I/L/F/Q) - Dark Material 3 theme - Detekt lint config with Compose/test naming exceptions - Unit tests for AppState and model types Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
113 lines
6.4 KiB
Markdown
113 lines
6.4 KiB
Markdown
# Progress
|
|
|
|
Tracks implementation progress against the phases in `PROJECT_PLAN.md`.
|
|
|
|
## Phase 1: Foundation — COMPLETE
|
|
|
|
**Deliverables:**
|
|
- [x] Go module (`go.mod`) at `git.wntrmute.dev/kyle/exo`
|
|
- [x] `core` package: `Header`, `Metadata`, `Value`, `ObjectType`, `NewUUID`, `MapFromList`/`ListFromMap`
|
|
- [x] SQLite migration framework with embedded SQL files (`db/migrations/`)
|
|
- [x] Initial schema migration (`001_initial.sql`): 13 tables covering shared infrastructure, bibliographic, and artifact repository
|
|
- [x] Database access layer: `Open` (with WAL, foreign keys, busy timeout), `StartTX`/`EndTX`, `ToDBTime`/`FromDBTime`
|
|
- [x] `config` package: `Config` struct with paths for database, blob store, Minio endpoint, gRPC listen address
|
|
- [x] `.golangci.yaml` — strict linting (errcheck, govet, gosec, staticcheck, revive, errorlint)
|
|
- [x] `Makefile` — vet, lint, test, build targets
|
|
- [x] Full test coverage for all packages (core, db, config)
|
|
|
|
**Files created:**
|
|
- `go.mod`, `go.sum`
|
|
- `core/core.go`, `core/core_test.go`
|
|
- `db/db.go`, `db/db_test.go`, `db/migrations/001_initial.sql`
|
|
- `config/config.go`, `config/config_test.go`
|
|
- `.golangci.yaml`, `Makefile`
|
|
|
|
## Phase 2: Artifact Repository — COMPLETE
|
|
|
|
**Deliverables:**
|
|
- [x] `artifacts` package: `Artifact`, `Snapshot`, `BlobRef`, `Citation`, `Publisher` types with `Get`/`Store` methods
|
|
- [x] `MIME` type alias for clarity
|
|
- [x] Tag and category management: `CreateTag`/`GetTag`/`GetAllTags`, `CreateCategory`/`GetCategory`/`GetAllCategories`, `GetArtifactIDsForTag`
|
|
- [x] Metadata store/retrieve operations (`StoreMetadata`/`GetMetadata`)
|
|
- [x] `blob` package: Content-addressable blob store (SHA256 hashing, hierarchical directory layout, read/write/exists)
|
|
- [x] YAML import: `ArtifactYAML`, `SnapshotYAML`, `CitationYAML` with `ToStd()` conversions and `LoadArtifactFromYAML`
|
|
- [x] Protobuf message definitions for all artifact types (`proto/exo/v1/common.proto`, `proto/exo/v1/artifacts.proto`)
|
|
- [x] gRPC service: `ArtifactService` with create/get artifacts, store/retrieve blobs, manage tags/categories, search by tag
|
|
- [x] `server` package: Full gRPC service implementation with proto-domain conversion helpers
|
|
- [x] buf.yaml for proto linting, buf.gen.yaml for code generation
|
|
- [x] Full test coverage for all packages (artifacts, blob, server)
|
|
|
|
**Files created:**
|
|
- `blob/blob.go`, `blob/blob_test.go`
|
|
- `artifacts/artifact.go`, `artifacts/citation.go`, `artifacts/publisher.go`, `artifacts/snapshot.go`
|
|
- `artifacts/metadata.go`, `artifacts/tagcat.go`, `artifacts/yaml.go`, `artifacts/artifacts_test.go`
|
|
- `proto/exo/v1/common.proto`, `proto/exo/v1/artifacts.proto`
|
|
- `proto/buf.yaml`, `proto/buf.gen.yaml`
|
|
- `proto/exo/v1/*.pb.go` (generated)
|
|
- `server/server.go`, `server/server_test.go`
|
|
|
|
## Phase 3: CLI Tools — COMPLETE
|
|
|
|
**Deliverables:**
|
|
- [x] `exod` server binary: gRPC daemon with startup, graceful shutdown (SIGINT/SIGTERM), auto-migration, flag-based configuration (`-listen`, `-base`, `-version`)
|
|
- [x] `exo` CLI binary: `import` (YAML artifacts), `tag add/list`, `cat add/list`, `search tag`
|
|
- [x] YAML import parser in CLI (converts to proto messages for gRPC transport)
|
|
- [x] Environment variable support (`EXO_ADDR` for server address)
|
|
- [x] Makefile `build` target produces both binaries in `bin/`
|
|
- [x] Version injection via `-ldflags`
|
|
|
|
**Files created:**
|
|
- `cmd/exod/main.go`
|
|
- `cmd/exo/main.go`, `cmd/exo/yaml.go`
|
|
|
|
## Phase 4: Knowledge Graph — COMPLETE
|
|
|
|
**Deliverables:**
|
|
- [x] `kg` package: `Node`, `Cell`, `Fact`, `Edge` types with `Store`/`Get` methods
|
|
- [x] Database schema migration (`002_knowledge_graph.sql`): nodes, cells, facts, edges, node_tags, node_categories tables
|
|
- [x] Node hierarchy (parent/children), C2 wiki-style naming, lookup by name
|
|
- [x] Cell content types (markdown, code, plain) with ordinal ordering
|
|
- [x] EAV fact storage with transaction timestamps and retraction support
|
|
- [x] `GetCurrentFactsForEntity` applies retraction logic to return only active facts
|
|
- [x] Edge types: child, parent, related, artifact_link (cross-pillar references)
|
|
- [x] Protobuf definitions (`proto/exo/v1/kg.proto`): Node, Cell, Fact, Edge messages and KnowledgeGraphService
|
|
- [x] gRPC service: CreateNode, GetNode, AddCell, RecordFact, GetFacts, AddEdge, GetEdges
|
|
- [x] CLI commands: `exo node create <name>`, `exo node get <id>`
|
|
- [x] KG service registered in exod
|
|
- [x] Shared tag/category pool: nodes use the same tags/categories tables as artifacts
|
|
- [x] Full test coverage (kg package: 10 tests covering nodes, cells, facts, edges, hierarchy, retractions)
|
|
|
|
**Files created:**
|
|
- `kg/node.go`, `kg/cell.go`, `kg/fact.go`, `kg/edge.go`, `kg/kg_test.go`
|
|
- `db/migrations/002_knowledge_graph.sql`
|
|
- `proto/exo/v1/kg.proto`, `proto/exo/v1/kg.pb.go`, `proto/exo/v1/kg_grpc.pb.go`
|
|
- `server/kg_server.go`
|
|
|
|
## Phase 5: Desktop Application — COMPLETE
|
|
|
|
**Deliverables:**
|
|
- [x] Kotlin/Compose Multiplatform desktop application (`desktop/`)
|
|
- [x] Gradle build with Kotlin 2.1, Compose 1.8, gRPC, Protobuf code generation
|
|
- [x] gRPC client (`ExoClient`) connecting to exod for both ArtifactService and KnowledgeGraphService
|
|
- [x] Observable `AppState` model driving reactive Compose UI
|
|
- [x] Tree/outline sidebar (Obsidian-style) showing KG hierarchy and unlinked artifacts section
|
|
- [x] Contextual main panel: Artifact detail view, Note editor view, Search results view, Catalog view, Graph view stub
|
|
- [x] Unified search bar with selector prefix support (`artifact:`, `note:`, `tag:`, `doi:`, `author:`)
|
|
- [x] Command palette (Ctrl+Shift+A, IntelliJ-style): create note, import artifact, search, switch views
|
|
- [x] Menu bar with keyboard shortcuts: Ctrl+I (import), Ctrl+L (new note), Ctrl+F (search), Ctrl+Q (quit)
|
|
- [x] Dark theme (Material 3 dark color scheme)
|
|
- [x] Detekt static analysis (`detekt.yml`): strict config, Compose naming exceptions, test naming exceptions
|
|
- [x] Unit tests for AppState and model types (9 tests)
|
|
- [x] Proto files copied and generated for Kotlin (artifacts, kg, common)
|
|
|
|
**Files created:**
|
|
- `desktop/build.gradle.kts`, `desktop/settings.gradle.kts`, `desktop/detekt.yml`
|
|
- `desktop/src/main/proto/exo/v1/{common,artifacts,kg}.proto`
|
|
- `desktop/src/main/kotlin/dev/wntrmute/exo/Main.kt`
|
|
- `desktop/src/main/kotlin/dev/wntrmute/exo/client/ExoClient.kt`
|
|
- `desktop/src/main/kotlin/dev/wntrmute/exo/model/AppState.kt`
|
|
- `desktop/src/main/kotlin/dev/wntrmute/exo/ui/{App,Sidebar,MainPanel,SearchBar,CommandPalette}.kt`
|
|
- `desktop/src/test/kotlin/dev/wntrmute/exo/model/{AppStateTest,SearchResultTest}.kt`
|
|
|
|
## Phase 6: Remote Access & Backup — NOT STARTED
|