Commit Graph
16 Commits
Author SHA1 Message Date
tommy0103 f963f14b10 fix: stabilize live session UI and skill publishing
Keep message navigation and progress state synchronized, and preserve
sequential split-flap count updates with a bounded queue.

Publish the Obelisk skill under skills/obelisk for npx skills, sharing
the same staging layout between CI and local releases with regression coverage.
2026-07-13 22:02:44 +08:00
tommy0103andCodex a9687ba8b7 feat(app): live session update + tool renderer + input_tokens migration
SessionDetail live update:
- Extract session-view-state.mjs: capture scroll position, disclosure
  (open/skill-md-open) state, and visible-UUID anchor before refresh;
  reconcile messages by UUID (in-place update, append tail only); restore
  scroll and disclosure state after DOM patch. findLastMessageAtOrAbove uses
  binary search (O(log n)) instead of linear scan.
- scrollRevision tracks user scrolls during refresh to avoid stale anchors
  overriding manual navigation.
- Throttle onScroll to one rAF per frame.

Tool renderer:
- Extract tool-renderer.js: standalone module for rendering tool call cards
  (Read/Write/Edit diffs, Bash terminal output, search results, JS/TS
  syntax highlighting). Replaces inline rendering in SessionDetail.
- tests/app-tool-renderer.test.mjs covers escaping, highlighting, and
  terminal formatting.

Input tokens semantics migration:
- Claude provider now sums input_tokens + cache_creation_input_tokens +
  cache_read_input_tokens into a single input_tokens value (was previously
  only the raw field, undercounting when cache tokens are present).
- One-time index-wide re-parse triggered when the marker
  __claude_input_tokens_include_cache_v1__ is absent and the DB already
  has token data (self-healing on first build after upgrade).
- App indexer.ts carries the same marker check for the app's build path.

Also:
- PRODUCT.md: product register (users, purpose, brand, design principles,
  accessibility targets).
- README.md: minor wording updates.

Co-Authored-By: Codex (GPT-5) <noreply@openai.com>
2026-07-13 21:02:38 +08:00
tommy0103andClaude Opus 4.8 410b0a8df3 docs(readme): rewrite for dual-surface product (skill + app) and workspace structure
Rewrite README to reflect the current state of the project:
- Describe both surfaces: skill (agent-first retrieval) and app (human browser).
- Add Codex support section (unified schema, source tagging, child-thread mapping).
- Update Structure tree to match the packages/core workspace layout with all
  TypeScript modules (providers, persist, tx, write-coordinator, writer-lease).
- Document generated build outputs (packages/core/dist, dist/obelisk-skill).
- License badge corrected to AGPL-3.0 (skill artifact is MIT; source is AGPL).
- Skill invocation examples updated to /obelisk-skill.
- Add recap flow documentation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 00:59:33 +08:00
tommy0103andClaude Opus 4.8 6edaf5231f ci: auto-publish skill artifact to tommy0103/obelisk-skill on push to main (Phase 7)
Add a GitHub Actions workflow that builds the readable, non-bundled skill
artifact (`npm run build:skill`) and force-pushes it to the dedicated
tommy0103/obelisk-skill public repo whenever the main branch is updated.
The skill repo is a pure derivative — no manual commits, no PRs; the source
of truth stays in tommy0103/obelisk.

- .github/workflows/publish-skill.yml: checkout → npm ci → build:skill →
  clone skill repo → replace content → commit + force push. Auth via
  SKILL_REPO_DEPLOY_KEY (SSH deploy key with write access to obelisk-skill).
- packaging/skill-README.md: the README placed in the skill repo (install
  instructions + link back to source + "auto-published, don't PR here").
- packaging/skill-LICENSE: MIT license for the skill artifact (relicensed
  from the AGPL-3.0 source by the copyright holder).
- packaging/publish-skill.sh: local convenience script for manual publish.
- packaging/skill-package.json: license field updated to MIT.
- README.md: install command updated to tommy0103/obelisk-skill.
- package.json: add publish:skill script.

The skill repo is MIT-licensed for zero adoption friction (local tool, no
library API, no derivative works expected); the source repo stays AGPL-3.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 16:18:43 +08:00
tommy0103andClaude Opus 4.8 e3e61cc7ab fix: coordinate sqlite index writers
Implement the full ADR-0006 plan: three-layer separation of transaction
correctness, retry policy, and cross-process writer coordination.

Layer 1 — scripts/tx.ts (transaction correctness):
- runWriteTransaction executes work exactly once; no internal retry.
- BEGIN IMMEDIATE takes the write lock up front (avoids SQLITE_BUSY_SNAPSHOT).
- Guarded rollback: checks inTransaction() via adapter before attempting
  ROLLBACK; never masks the primary exception.
- WriteTxDiagnostics attached to errors: phase, code, label,
  rollbackSucceeded, rollbackError, transactionActive.
- Binding adapters (betterSqliteTransactionAdapter, nodeSqliteTransactionAdapter)
  mapping better-sqlite3's `.inTransaction` and node:sqlite's `.isTransaction`.
- configureConnection centralizes WAL + synchronous + busy_timeout.

Layer 2 — scripts/write-coordinator.ts (retry policy):
- runRetryableWriteTransaction: bounded retry with total time budget.
- Only retries when the transaction confirmed ended (transactionActive=false)
  and the error is SQLITE_BUSY during work/commit phase.
- BEGIN-phase BUSY = abort entire build (isBeginBusyFailure); the caller
  returns `{ deferred: true, reason: 'writer_busy' }` instead of waiting.
- hasUnusableTransaction detects a still-active transaction after failure;
  aborts the build immediately, never retries.

Layer 3 — scripts/writer-lease.ts (cross-process coordination):
- acquireWriterLease: dedicated writer.lock.sqlite with busy_timeout=0 +
  BEGIN IMMEDIATE. Non-blocking attempt; bounded wait with retryDelayMs.
- writerLockPathFor derives lock path from the target DB path.
- Lease held for the entire build; released on completion or failure.
- Lock DB uses DELETE journal (not WAL); crash/close auto-releases.
- All consumers obey: skill acquires at build start (returns deferred if
  unavailable); app daemon (via worker) acquires for its build cycle.

Build semantics changes:
- affectedSessionIds updated only after successful commit.
- BuildIndexResult gains skipped/skippedFiles for observability.
- Skill finalize failure now fails the build (was silently warned).
- Checkpoint changed to PASSIVE (TRUNCATE reserved for maintenance/exit).
- Skill buildIndex returns { deferred, reason } on lease contention;
  indexer-service reschedules the build (deferredRetryMs) without publishing
  a heartbeat (so the build-deferred state is visible to cross-process
  arbitration).
- Service publishes heartbeat immediately on start() for correct arbitration.

Tests:
- tests/write-transaction.test.mjs: single-shot execution, diagnostics
  propagation, auto-rolled-back transaction detected, rollback failure
  captured as metadata, BEGIN IMMEDIATE semantics.
- tests/writer-lease.test.mjs: acquire/release, contention returns null,
  bounded wait with release during budget.
- tests/app-writer-lease.test.mjs: better-sqlite3 adapter integration.
- tests/app-rollback-guard.test.mjs: rewritten — transient BUSY recovered
  by coordinator, persistent BUSY skips file, begin-busy aborts build,
  live-transaction aborts build, phantom affectedSessionIds prevented.
- tests/daemon-arbitration.test.mjs: skill defers to fresh app heartbeat,
  builds when heartbeat is stale.
- tests/app-indexer-service.test.mjs: new cases for deferred-retry
  scheduling and immediate heartbeat on start.
- app/tests/electron-concurrency.mjs + child: dual-child IPC structure for
  real better-sqlite3 contention (holder acquires lock → build child starts
  → delayed release → result collected; persistent contention bounded).

ADR-0006 updated to reflect the implemented design.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 00:42:43 +08:00
tommy0103 b7506ee765 feat(app): add Settings view, configurable claude dir, and recap docs refactor
Introduce a Settings view for configuring the Claude data directory
  (with WSL auto-detection on Windows), sidebar project grouping module,
  and an empty-state onboarding screen for SessionList. Refactor
  recap-patterns.md into per-card reference files under references/recap/
  with separate retrieval and writing guides. Remove the legacy panel.html.
  On the data layer: incremental indexing via changedPaths, per-session
  live-update IPC (obelisk:session-updated), and session dirty-tracking
  in the renderer.
2026-06-15 01:44:32 +08:00
tommy0103 9fc7f202f0 feat(app): add weekly recap cards with swipeable story UI and export
Introduce a Spotify-Wrapped-style recap feature: five themed cards
  (Cover, Path, Vibe, Workflow, Closing) rendered per archetype palette,
  with keyboard/swipe navigation and image export via capture IPC. Add
  RecapList, RecapDetail, RecapExport views and recap component library.
  Wire recap:list/read/updated IPC channels through preload, document the
  retrieval-to-card contract in references/recap-patterns.md, and bundle
  dist-renderer for production use.
2026-06-14 03:16:49 +08:00
tommy0103 4eec6b38c9 feat(app): embed indexer in Electron with file-watching service and UI refinements
Extract schema DDL into scripts/schema.sql shared between CLI and app.
  Add an in-process chokidar-based indexer-service that watches ~/.claude/projects
  for JSONL changes, debounces, and triggers background rebuilds via a worker
  thread. Rename Usage view to Activity, flesh out MemoryDetail and SubagentDetail
  views, and refine App.vue layout/routing. The main process now starts/stops the
  indexer lifecycle and notifies renderer windows on index updates.
2026-06-13 03:42:01 +08:00
tommy0103 b524339d85 feat(app): add Electron desktop UI and evolve memory/retrieval layer
Introduce an Electron app with session browser, memory list, and usage
  views (vanilla JS + Vue scaffolding). On the data layer: add content_type
  and is_meta to messages for transcript control-plane filtering, introduce
  FTS5-backed memory recall with safe tokenization, support memory archival
  via forget() through the renamed --attune runtime, and expose anchors on
  memory records.
2026-06-12 22:20:29 +08:00
tommy0103 807e5141fa feat(query): add overview() for project-aware session/memory discovery
Resolves current project from cwd, lists all known projects with session
  and memory counts, and returns the current project's recent sessions and
  memories in one call. Enables the agent to orient itself at the start of
  a retrieval without multiple exploratory queries.
2026-06-10 03:04:11 +08:00
tommy0103 34f3a164ab feat(memory): persistent memory layer with remember/recall CodeAct API
Add a memories table (survives index rebuilds) for agent-written
  conclusions with provenance (session, message range, project). The agent
  writes markdown files via Write tool (user-approved), then registers
  them via a --remember CodeAct script with remember(). Recall via
  memories() in --query scripts, filtered by project/session/time.

  Separates query (read-only, assertReadOnlySql) from remember (write)
  execution contexts in runtime.mjs.
2026-06-10 02:05:27 +08:00
tommy0103 297ef01eaf refactor(docs): restructure SKILL.md into progressive-disclosure layers
Split the monolithic skill prompt into three tiers:
  - Core API (search/context/sql) stays in the first prompt
  - Structured helpers listed as one-liners with filter signatures
  - Detailed patterns and pitfalls extracted to references/

  Add references/query-patterns.md (copyable CodeAct recipes) and
  references/pitfalls.md (scope, FTS, ordering, compactness traps).
  Clarify project scope semantics (slug vs path vs cwd) throughout.
  Add ORDER BY timestamp DESC to failures() for newest-first default.
2026-06-07 16:42:41 +08:00
tommy0103 5593990440 docs(SKILL.md): add raw() usage and sql schema reminder 2026-05-30 04:57:06 +08:00
tommy0103 2b02a7b6c8 fix(indexer): preserve session metadata during incremental reindex
Previously the session metadata accumulator started from zero on every
  reindex pass, so an incremental update would overwrite started_at and
  message_count with values derived only from the new lines.

  Now reads the existing session row first and merges new data on top.
2026-05-30 03:53:16 +08:00
tommy0103 1d45c91a8a chore: update README 2026-05-30 03:27:03 +08:00
tommy0103 bc9b6dde72 build(obelisk): let Claude Code search its own session history
- SQLite + FTS5 index over ~/.claude JSONL transcripts.
  - Agent writes JS queries at runtime — same sandbox pattern as workflows.
  - Covers sessions, subagents, workflow executions, tool calls, and full-text search.
2026-05-30 03:21:35 +08:00