@digital-lake/lognexus 1.0.0-alpha.0 → 1.0.0-alpha.4

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 (84) hide show
  1. package/README.md +86 -59
  2. package/dist/cli.js +271 -88
  3. package/dist/cli.js.map +1 -1
  4. package/dist/doctor.d.ts +10 -0
  5. package/dist/doctor.d.ts.map +1 -0
  6. package/dist/doctor.js +109 -0
  7. package/dist/doctor.js.map +1 -0
  8. package/dist/index.d.ts +12 -7
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +12 -7
  11. package/dist/index.js.map +1 -1
  12. package/dist/mcp/prompts.d.ts +30 -0
  13. package/dist/mcp/prompts.d.ts.map +1 -0
  14. package/dist/mcp/prompts.js +150 -0
  15. package/dist/mcp/prompts.js.map +1 -0
  16. package/dist/mcp/resources.d.ts +25 -0
  17. package/dist/mcp/resources.d.ts.map +1 -0
  18. package/dist/mcp/resources.js +75 -0
  19. package/dist/mcp/resources.js.map +1 -0
  20. package/dist/mcp/server.d.ts +22 -0
  21. package/dist/mcp/server.d.ts.map +1 -0
  22. package/dist/mcp/server.js +202 -0
  23. package/dist/mcp/server.js.map +1 -0
  24. package/dist/mcp/tools.d.ts +26 -0
  25. package/dist/mcp/tools.d.ts.map +1 -0
  26. package/dist/mcp/tools.js +197 -0
  27. package/dist/mcp/tools.js.map +1 -0
  28. package/dist/notes/attach.d.ts +20 -0
  29. package/dist/notes/attach.d.ts.map +1 -0
  30. package/dist/notes/attach.js +27 -0
  31. package/dist/notes/attach.js.map +1 -0
  32. package/dist/notes/notes.d.ts +14 -0
  33. package/dist/notes/notes.d.ts.map +1 -0
  34. package/dist/notes/notes.js +82 -0
  35. package/dist/notes/notes.js.map +1 -0
  36. package/dist/scaffold.d.ts +7 -0
  37. package/dist/scaffold.d.ts.map +1 -0
  38. package/dist/scaffold.js +33 -0
  39. package/dist/scaffold.js.map +1 -0
  40. package/dist/state/manager.d.ts +9 -0
  41. package/dist/state/manager.d.ts.map +1 -0
  42. package/dist/state/manager.js +72 -0
  43. package/dist/state/manager.js.map +1 -0
  44. package/dist/state/schema.d.ts +111 -0
  45. package/dist/state/schema.d.ts.map +1 -0
  46. package/dist/state/schema.js +31 -0
  47. package/dist/state/schema.js.map +1 -0
  48. package/dist/state/sync.d.ts +8 -0
  49. package/dist/state/sync.d.ts.map +1 -0
  50. package/dist/state/sync.js +79 -0
  51. package/dist/state/sync.js.map +1 -0
  52. package/dist/status.d.ts +9 -0
  53. package/dist/status.d.ts.map +1 -0
  54. package/dist/status.js +52 -0
  55. package/dist/status.js.map +1 -0
  56. package/package.json +7 -4
  57. package/dist/config/loadConfig.d.ts +0 -36
  58. package/dist/config/loadConfig.d.ts.map +0 -1
  59. package/dist/config/loadConfig.js +0 -65
  60. package/dist/config/loadConfig.js.map +0 -1
  61. package/dist/providers/deepseek.d.ts +0 -10
  62. package/dist/providers/deepseek.d.ts.map +0 -1
  63. package/dist/providers/deepseek.js +0 -13
  64. package/dist/providers/deepseek.js.map +0 -1
  65. package/dist/providers/factory.d.ts +0 -4
  66. package/dist/providers/factory.d.ts.map +0 -1
  67. package/dist/providers/factory.js +0 -23
  68. package/dist/providers/factory.js.map +0 -1
  69. package/dist/providers/gemini.d.ts +0 -17
  70. package/dist/providers/gemini.d.ts.map +0 -1
  71. package/dist/providers/gemini.js +0 -105
  72. package/dist/providers/gemini.js.map +0 -1
  73. package/dist/providers/openaiCompatible.d.ts +0 -17
  74. package/dist/providers/openaiCompatible.d.ts.map +0 -1
  75. package/dist/providers/openaiCompatible.js +0 -100
  76. package/dist/providers/openaiCompatible.js.map +0 -1
  77. package/dist/providers/types.d.ts +0 -35
  78. package/dist/providers/types.d.ts.map +0 -1
  79. package/dist/providers/types.js +0 -2
  80. package/dist/providers/types.js.map +0 -1
  81. package/dist/routing/tierRouter.d.ts +0 -11
  82. package/dist/routing/tierRouter.d.ts.map +0 -1
  83. package/dist/routing/tierRouter.js +0 -42
  84. package/dist/routing/tierRouter.js.map +0 -1
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  # LogNexus
6
6
 
7
7
  <p align="center">
8
- <strong>The Git-Powered Memory Nexus for AI Agents</strong>
8
+ <strong>The Universal, Git-Powered Context & Rules Framework for Native AI Agents</strong>
9
9
  </p>
10
10
 
11
11
  <p align="center">
@@ -19,9 +19,11 @@
19
19
 
20
20
  ## What is LogNexus?
21
21
 
22
- As AI coding agents take on multi-step engineering tasks, they suffer from a fundamental failure mode: **cognitive amnesia**. Between conversation resets, context compactations, model handoffs, and unexpected bugs, the *why* behind design decisions, discarded alternatives, and technical discoveries vanishes.
22
+ As AI coding agents take on complex engineering tasks across different IDEs, they suffer from a fundamental failure mode: **cognitive amnesia**. Between conversation resets, context compactations, model handoffs, and unexpected bugs, the *why* behind design decisions, discarded alternatives, and technical discoveries vanishes.
23
23
 
24
- **LogNexus transforms Git and GitHub into a persistent, traceable knowledge graph.** It turns every brainstorm into an issue, every issue into a scoped branch, every commit into an annotated milestone, and every Pull Request into an auditable timeline of the entire development journey.
24
+ **LogNexus transforms Git and GitHub into a persistent, traceable knowledge graph.** It is a **100% generic, model-agnostic and editor-agnostic framework** that operates directly inside your native AI development environments:
25
+ - **Clients:** Claude Code, Cursor, Codex, Google Antigravity, Kimi Code, VS Code, Zed.
26
+ - **Models:** Anthropic Claude (Opus, Sonnet, Haiku), OpenAI (o3, o1, GPT-4o), Google Gemini (2.5/3.8 Pro & Flash), DeepSeek (R1, V3, Chat).
25
27
 
26
28
  ```
27
29
  Issues (Why & Goals) ──▶ Branches (Task Scopes) ──▶ Commits (Context & Diffs) ──▶ PR (Timeline & Review)
@@ -29,26 +31,24 @@ Issues (Why & Goals) ──▶ Branches (Task Scopes) ──▶ Commits (Context
29
31
  └─────────────────────── Git-Backed Knowledge Graph ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
30
32
  ```
31
33
 
34
+ > **Framework, Not an API Proxy:** LogNexus never intercepts network calls or wraps vendor APIs. Your models remain inside their native IDEs with full access to editor buffers, interactive diff viewers, terminals, MCP servers, and local tools.
35
+
32
36
  ---
33
37
 
34
38
  ## Key Features
35
39
 
36
- - **Dual-Layer Architecture:**
37
- - **Skill Layer (Markdown):** Drop-in compatibility with **Claude Code**, **Cursor**, **Codex**, **Antigravity**, and **Gemini CLI**.
38
- - **Runtime Layer (TypeScript):** Lightweight, zero-heavy-dependency runtime with native `fetch` and a flexible **Strategy/Factory** pattern.
39
- - **Native Multi-Model Routing:**
40
- - Route planning, PR synthesis, and cross-review to high-reasoning tiers (**Gemini / Claude Opus / DeepSeek Reasoner**).
41
- - Ingest massive codebases using long-context windows (**Gemini** with 1M tokens).
42
- - Delegate closed-contract implementation tasks to cost-effective execution engines (**DeepSeek Chat** at marginal cost).
43
- - **Cross-Model Review Gates:** Enforce non-negotiable review separation (`Authored-by:` vs `Reviewed-by:`). No model merges its own code without independent verification.
40
+ - **Universal Multi-Model Support:** Native cognitive guidelines and prompt specifications for **Anthropic Claude**, **OpenAI**, **Google Gemini**, and **DeepSeek**.
41
+ - **Universal Client Compatibility:** Drop-in support for **Claude Code**, **Cursor**, **Codex**, **Google Antigravity**, and **Kimi Code / VS Code**.
42
+ - **Cross-Model Review Gates:** Non-negotiable review separation (`Authored-by:` vs `Reviewed-by:`). No model merges its own code without independent verification from another model family or version.
44
43
  - **Contract-First Subtasks:** Tasks are bounded by strict decision budgets, file allowlists, and stop conditions (`feat(#42/T1)`).
45
44
  - **Hidden Metadata Envelopes:** HTML comments preserve machine-parseable state (`<!-- lognexus: kind: state ... -->`) without cluttering human-readable markdown.
45
+ - **Scaffolding & Health CLI (`@digital-lake/lognexus`):** Lightweight scaffolding utility (`npx @digital-lake/lognexus init`) and environment health checking (`doctor`).
46
46
 
47
47
  ---
48
48
 
49
- ## Why Multi-Model Routing?
49
+ ## Model-Tier Routing Matrix
50
50
 
51
- Empirical benchmarks and community data demonstrate that routing specialized agent tasks to provider tiers according to context, reasoning, and execution profiles drastically reduces operating costs while improving quality.
51
+ LogNexus organizes development phases into three cognitive tiers. You can assign any model or native client to any tier according to your team's workflow and cost preferences:
52
52
 
53
53
  <p align="center">
54
54
  <img src="docs/assets/multimodel-routing-costs.png" alt="Multi-Model Routing Cost and Performance Analysis" width="85%">
@@ -56,21 +56,26 @@ Empirical benchmarks and community data demonstrate that routing specialized age
56
56
 
57
57
  ### Operational Tiers
58
58
 
59
- | Tier | Default Provider / Model | Primary Role |
60
- |---|---|---|
61
- | **tier-1 (Reasoning)** | Gemini Pro/Flash (High) Ā· DeepSeek Reasoner Ā· Claude Opus | Architectural design, brainstorm synthesis, PR timelines, and cross-model review gates. |
62
- | **tier-2 (Context)** | Gemini (1M Context Window) | Rapid codebase exploration, large context loading, discovery triage, and documentation. |
63
- | **tier-3 (Execution)** | DeepSeek Chat | Routine implementation under closed delegation contracts, subtask commits, and timeline logging. |
64
-
65
- ---
59
+ | Tier | Cognitive Role | Anthropic Claude | OpenAI | Google Gemini | DeepSeek | Primary Activities |
60
+ |---|---|---|---|---|---|---|
61
+ | **tier-1 (Reasoning)** | Deep synthesis, architectural design, narrative review | Claude Opus 3.7 / 4.x | o3, o1, GPT-5 | Gemini 2.5 / 3.8 Pro | DeepSeek R1 | Brainstorming-to-issue planning, PR journey timeline synthesis, cross-model review sign-offs. |
62
+ | **tier-2 (Context & Triage)** | Long context ingestion, discovery triage, structured mapping | Claude Sonnet | GPT-4.1, GPT-4o | Gemini Flash / Pro (1M context) | DeepSeek V3 | Large codebase exploration, discovery classification, knowledge retrieval. |
63
+ | **tier-3 (Execution)** | Surgical implementation, template filling, fast execution | Claude Haiku | GPT-4o-mini | Gemini Flash | DeepSeek Chat (V3) | Subtask commits (`feat(#N/Tk)`), atomic code changes under closed contracts, timeline logging. |
66
64
 
67
- ## Architecture & Competitive Positioning
65
+ ### Example Deployment Setups
68
66
 
69
- LogNexus advances agentic development workflows beyond passive markdown instructions into an active, verifiable development platform.
67
+ LogNexus adapts to your existing toolstack. Configure your advisory preferences in `.lognexus/routing.md`:
70
68
 
71
- <p align="center">
72
- <img src="docs/assets/competitive-gap-map.png" alt="Competitive Gap Map and Roadmap" width="85%">
73
- </p>
69
+ ```
70
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
71
+ │ POPULAR DEPLOYMENT SETUPS │
72
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
73
+ │ Setup A (Anthropic Pure): Claude Opus (t1) + Claude Sonnet (t2) + Claude Haiku (t3) │
74
+ │ Setup B (Google + DeepSeek): Gemini Pro (t1/t2) in Antigravity + DeepSeek Chat in Kimi │
75
+ │ Setup C (OpenAI + DeepSeek): OpenAI o3 (t1) in Cursor + DeepSeek Chat (t3) for code │
76
+ │ Setup D (Claude + OpenAI): Claude Opus (t1) for design + GPT-4o-mini (t3) for tasks │
77
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
78
+ ```
74
79
 
75
80
  ---
76
81
 
@@ -110,58 +115,79 @@ An independent model inspects the PR diff, verifies task contracts, and signs of
110
115
 
111
116
  ---
112
117
 
113
- ## Installation
118
+ ## Installation & Setup
119
+
120
+ ### 1. Scaffold Rules & Manage State with the CLI
114
121
 
115
- ### As a Claude Code Plugin
122
+ Initialize `.lognexus/` rules, templates, and routing configuration:
116
123
  ```bash
117
- # From repository
118
- claude plugin add digital-lake-ai/lognexus
124
+ npx @digital-lake/lognexus init
125
+ ```
119
126
 
120
- # Or link locally
121
- claude plugin add ./path/to/lognexus
127
+ Verify your environment anytime:
128
+ ```bash
129
+ npx @digital-lake/lognexus doctor
122
130
  ```
123
131
 
124
- ### Via Agent Skills (Antigravity / Cursor / Codex)
132
+ Inspect active branch and tier advisory:
125
133
  ```bash
126
- npx -y skills add digital-lake-ai/lognexus
134
+ npx @digital-lake/lognexus status
127
135
  ```
128
136
 
129
- ### Via Global CLI
137
+ Manage persistent agent state (`.lognexus/state.json`) and session recovery:
130
138
  ```bash
131
- npm install -g @digital-lake/lognexus
132
- lognexus doctor
139
+ npx @digital-lake/lognexus state sync
140
+ npx @digital-lake/lognexus state show
141
+ npx @digital-lake/lognexus state set-task T1 "Add user schema"
142
+ npx @digital-lake/lognexus state finish-task T1
133
143
  ```
134
144
 
135
- ---
145
+ Quiet Mode with Git Notes (`refs/notes/lognexus`, standard `git-ai` v3):
146
+ ```bash
147
+ npx @digital-lake/lognexus note attach HEAD
148
+ npx @digital-lake/lognexus note show HEAD
149
+ npx @digital-lake/lognexus note push origin
150
+ ```
136
151
 
137
- ## Configuration
152
+ ### 2. Connect via Model Context Protocol (MCP)
138
153
 
139
- Configure your active provider in `.lognexus/config.json` or through environment variables:
154
+ LogNexus includes a native, lightweight JSON-RPC 2.0 stdio server (`lognexus mcp`) with zero external SDK dependencies. Connect it to Claude Desktop, Cursor, Google Antigravity, or any MCP-compliant client:
140
155
 
141
- ```bash
142
- # Provider selection
143
- export LOGNEXUS_PROVIDER=gemini # 'gemini' or 'deepseek'
156
+ **`claude_desktop_config.json` or Cursor MCP settings:**
157
+ ```json
158
+ {
159
+ "mcpServers": {
160
+ "lognexus": {
161
+ "command": "npx",
162
+ "args": ["-y", "@digital-lake/lognexus", "mcp"]
163
+ }
164
+ }
165
+ }
166
+ ```
144
167
 
145
- # Google Gemini
146
- export GEMINI_API_KEY="your-api-key"
147
- export GEMINI_MODEL="gemini-3.8-flash"
168
+ **Exposed Capabilities:**
169
+ - **Tools:** `lognexus_status`, `lognexus_state_get`, `lognexus_state_sync`, `lognexus_state_set_task`, `lognexus_state_finish_task`, `lognexus_state_clear`, `lognexus_note_show`, `lognexus_note_attach`
170
+ - **Resources:** `lognexus://state`, `lognexus://routing`
171
+ - **Prompts:** `lognexus-plan`, `lognexus-review`
148
172
 
149
- # DeepSeek
150
- export DEEPSEEK_API_KEY="your-api-key"
151
- export DEEPSEEK_BASE_URL="https://api.deepseek.com"
152
- export DEEPSEEK_MODEL="deepseek-chat"
153
- ```
173
+ ### 3. Install Rules in Your Agent Environment
154
174
 
155
- Verify your environment anytime:
156
- ```bash
157
- lognexus doctor
158
- ```
175
+ - **Claude Code:**
176
+ ```bash
177
+ claude plugin add digital-lake-ai/lognexus
178
+ ```
179
+ - **Cursor / Codex / Agent Skills:**
180
+ ```bash
181
+ npx skills add digital-lake-ai/lognexus
182
+ ```
183
+ - **Google Antigravity:** Active automatically via `skills/lognexus/SKILL.md` or workspace skills.
184
+ - **Kimi Code / VS Code:** Active via `.lognexus/` workspace instructions and prompts.
159
185
 
160
186
  ---
161
187
 
162
188
  ## Disambiguation
163
189
 
164
- **LogNexus** by Digital Lake is an open-source development orchestrator and Git memory system for AI agents. It is not affiliated with academic research papers on industrial log compression (e.g. ISSTA 2026).
190
+ **LogNexus** by Digital Lake is an open-source development framework and Git memory system for AI agents. It is not affiliated with academic research papers on industrial log compression (e.g. ISSTA 2026).
165
191
 
166
192
  ---
167
193
 
@@ -169,10 +195,11 @@ lognexus doctor
169
195
 
170
196
  LogNexus is an independent hard fork and continuation of [`shiplog`](https://github.com/devallibus/shiplog), originally created by **devallibus** under the MIT License.
171
197
 
172
- We extend our deep gratitude to **devallibus** for pioneering the concept of Git-as-knowledge-graph for AI development. LogNexus builds upon that foundation by introducing:
173
- - Multi-model routing with native **Google Gemini** and **DeepSeek** provider strategies.
174
- - A standalone TypeScript runtime and automated verification CLI.
175
- - Resilient backwards-compatibility for existing `.shiplog` envelopes and workflows.
198
+ We extend our deep gratitude to **devallibus** for pioneering the concept of Git-as-knowledge-graph for AI development. LogNexus builds upon that foundation by:
199
+ - Expanding the model ecosystem to provide first-class native support for **Google Gemini** and **DeepSeek** alongside **Claude** and **OpenAI**.
200
+ - Formalizing the multi-model tier routing taxonomy and closed delegation contracts.
201
+ - Introducing the repository scaffolding CLI (`@digital-lake/lognexus`).
202
+ - Providing seamless backwards-compatibility for existing `.shiplog` envelopes and workflows.
176
203
 
177
204
  Additional inspirations and patterns are derived from [OrchestKit](https://github.com/yonatangross/orchestkit) and [Superpowers](https://github.com/obra/superpowers). Detailed license texts are preserved in the [`LICENSES/`](LICENSES/) directory and in [`NOTICE.md`](NOTICE.md).
178
205
 
package/dist/cli.js CHANGED
@@ -1,112 +1,295 @@
1
1
  #!/usr/bin/env node
2
- import { execSync } from "node:child_process";
3
- import { loadConfig } from "./config/loadConfig.js";
4
- import { createProvider } from "./providers/factory.js";
5
- import { resolveTier } from "./routing/tierRouter.js";
2
+ import { runDiagnostics } from "./doctor.js";
3
+ import { startMcpServer } from "./mcp/server.js";
4
+ import { attachCurrentStateToCommit } from "./notes/attach.js";
5
+ import { fetchNotes, getNote, listNotes, pushNotes } from "./notes/notes.js";
6
+ import { initProject } from "./scaffold.js";
7
+ import { clearState, finishSubtask, loadState, setSubtask } from "./state/manager.js";
8
+ import { syncStateFromGit } from "./state/sync.js";
9
+ import { getProjectStatus } from "./status.js";
6
10
  function printHeader() {
7
- console.log("\nšŸ”· LogNexus CLI v1.0.0-alpha.0 — Digital Lake\n");
11
+ console.log("\nšŸ”· LogNexus CLI — Digital Lake");
12
+ console.log(" The Universal Git-Powered Context & Rules Framework for Native AI Agents\n");
8
13
  }
9
- function redactKey(key) {
10
- if (!key)
11
- return "āŒ (not set)";
12
- if (key.length <= 8)
13
- return "•••••••• (set)";
14
- return `${key.slice(0, 4)}••••${key.slice(-4)}`;
14
+ function printUsage() {
15
+ printHeader();
16
+ console.log(`Usage:
17
+ lognexus <command> [subcommand] [options]
18
+
19
+ Commands:
20
+ init Scaffold .lognexus/ configuration and rules in current repository
21
+ doctor Check Git, GitHub CLI authentication, and repository rules health
22
+ status Inspect current branch, active issue, and recommended tier
23
+ state Manage persistent agent state (.lognexus/state.json)
24
+ note Manage Git Notes under refs/notes/lognexus (git-ai standard)
25
+ mcp Start the LogNexus MCP server (stdio JSON-RPC 2.0) for native AI agents
26
+ help Display this help message
27
+
28
+ State Subcommands:
29
+ lognexus state [show] Display current active issue and task state
30
+ lognexus state sync Sync state from current Git branch & GitHub
31
+ lognexus state set-task <id> [t] Set active subtask (e.g. lognexus state set-task T1 "Add schema")
32
+ lognexus state finish-task <id> Mark subtask as completed (e.g. lognexus state finish-task T1)
33
+ lognexus state clear Reset persistent state to empty
34
+
35
+ Note Subcommands:
36
+ lognexus note [show] [commit] Display LogNexus Git Note for commit (default: HEAD)
37
+ lognexus note attach [commit] Attach current session state as Git Note to commit
38
+ lognexus note list List all commits with LogNexus Git Notes
39
+ lognexus note push [remote] Push refs/notes/lognexus to remote (default: origin)
40
+ lognexus note fetch [remote] Fetch refs/notes/lognexus from remote
41
+
42
+ MCP Server:
43
+ lognexus mcp Start MCP server on stdio (JSON-RPC 2.0) for Claude Code,
44
+ Cursor, VS Code, Antigravity or any MCP-compatible client
45
+ Tools: lognexus_status, lognexus_state_get, lognexus_state_sync, lognexus_state_set_task,
46
+ lognexus_state_finish_task, lognexus_state_clear, lognexus_note_show, lognexus_note_attach
47
+ Resources: lognexus://state, lognexus://routing
48
+ Prompts: lognexus-plan, lognexus-review
49
+
50
+ Examples:
51
+ npx @digital-lake/lognexus init
52
+ npx @digital-lake/lognexus state sync
53
+ npx @digital-lake/lognexus note attach HEAD
54
+ npx @digital-lake/lognexus note show HEAD
55
+ npx @digital-lake/lognexus mcp
56
+ `);
15
57
  }
16
- async function runDoctor(args) {
58
+ async function handleInit() {
17
59
  printHeader();
18
- console.log("Running diagnostics...\n");
19
- const live = args.includes("--live");
20
- // 1. Git Check
21
- try {
22
- const gitVer = execSync("git --version", { encoding: "utf-8" }).trim();
23
- const isRepo = execSync("git rev-parse --is-inside-work-tree", {
24
- encoding: "utf-8",
25
- stdio: ["pipe", "pipe", "ignore"],
26
- }).trim();
27
- console.log(`[PASS] Git: ${gitVer} (inside git repository: ${isRepo})`);
28
- }
29
- catch {
30
- console.log("[FAIL] Git: Git command failed or not in a git repository");
31
- }
32
- // 2. GitHub CLI Check
33
- try {
34
- const ghVer = execSync("gh --version", { encoding: "utf-8" }).split("\n")[0];
35
- console.log(`[PASS] GitHub CLI: ${ghVer}`);
36
- }
37
- catch {
38
- console.log("[WARN] GitHub CLI: 'gh' not found in PATH or not installed");
39
- }
40
- // 3. Load Configuration
41
- const config = loadConfig();
42
- console.log(`\n[INFO] Active Provider Strategy: ${config.provider.toUpperCase()}`);
43
- console.log(` - Gemini Key: ${redactKey(config.gemini.apiKey)}`);
44
- console.log(` - Gemini Model: ${config.gemini.model}`);
45
- console.log(` - DeepSeek Key: ${redactKey(config.deepseek.apiKey)}`);
46
- console.log(` - DeepSeek Model: ${config.deepseek.model}`);
47
- // 4. Live Provider Connectivity Check (Optional)
48
- if (live) {
49
- console.log("\nTesting live API connectivity...");
50
- if (config.gemini.apiKey) {
51
- const gemini = createProvider("gemini", config);
52
- const health = await gemini.healthCheck();
53
- console.log(` - Gemini Live: ${health.ok ? "āœ… PASS" : "āŒ FAIL"} — ${health.message}`);
60
+ console.log("Initializing LogNexus in current repository...\n");
61
+ const res = initProject();
62
+ if (res.created.length > 0) {
63
+ console.log("Created files:");
64
+ for (const f of res.created) {
65
+ console.log(` [+] ${f}`);
54
66
  }
55
- if (config.deepseek.apiKey) {
56
- const deepseek = createProvider("deepseek", config);
57
- const health = await deepseek.healthCheck();
58
- console.log(` - DeepSeek Live: ${health.ok ? "āœ… PASS" : "āŒ FAIL"} — ${health.message}`);
67
+ }
68
+ if (res.skipped.length > 0) {
69
+ console.log("Existing files (skipped):");
70
+ for (const f of res.skipped) {
71
+ console.log(` [.] ${f}`);
59
72
  }
60
73
  }
61
- else {
62
- console.log("\nTip: Pass --live to verify API keys with real connectivity checks.");
74
+ console.log("\nNext Steps:");
75
+ console.log(" • Claude Code / Cursor / Codex / Antigravity / Kimi: use /lognexus plan");
76
+ console.log(" • Configure model tiers in .lognexus/routing.md");
77
+ console.log(" • Verify environment anytime with: npx @digital-lake/lognexus doctor\n");
78
+ }
79
+ async function handleDoctor() {
80
+ printHeader();
81
+ console.log("Running diagnostics...\n");
82
+ const checks = runDiagnostics();
83
+ for (const c of checks) {
84
+ const tag = c.status === "pass" ? "[PASS]" : c.status === "warn" ? "[WARN]" : "[FAIL]";
85
+ console.log(`${tag} ${c.name}: ${c.message}`);
63
86
  }
64
87
  console.log("\nDiagnostic complete.\n");
65
88
  }
66
- function runRoute(args) {
67
- const tierArg = args[0];
68
- if (!tierArg || !["tier-1", "tier-2", "tier-3"].includes(tierArg)) {
69
- console.error("Usage: lognexus route <tier-1 | tier-2 | tier-3>");
70
- process.exit(1);
89
+ async function handleStatus() {
90
+ printHeader();
91
+ const st = getProjectStatus();
92
+ console.log(`Git Repository: ${st.isInsideGit ? "Yes" : "No"}`);
93
+ console.log(`Current Branch: ${st.branch}`);
94
+ console.log(`Active Issue: ${st.activeIssue ?? "(none — on base branch)"}`);
95
+ console.log(`Rules Routing Mode: ${st.routingMode}`);
96
+ console.log(`Recommended Tier: ${st.recommendedTier}\n`);
97
+ }
98
+ async function handleState(args) {
99
+ const sub = args[0]?.toLowerCase() || "show";
100
+ switch (sub) {
101
+ case "show": {
102
+ printHeader();
103
+ const state = loadState();
104
+ console.log("Persistent Agent State (.lognexus/state.json):\n");
105
+ if (state.activeIssue) {
106
+ console.log(`Active Issue: #${state.activeIssue.id} — ${state.activeIssue.title}`);
107
+ console.log(`Branch: ${state.activeIssue.branch}`);
108
+ console.log(`Phase: ${state.activeIssue.phase}`);
109
+ console.log(`Tier: ${state.activeIssue.tier}`);
110
+ console.log(`Readiness: ${state.activeIssue.readiness}`);
111
+ }
112
+ else {
113
+ console.log("Active Issue: (none)");
114
+ }
115
+ console.log("");
116
+ if (state.currentSubtask) {
117
+ console.log(`Current Subtask: ${state.currentSubtask.id} (${state.currentSubtask.status})`);
118
+ if (state.currentSubtask.title) {
119
+ console.log(` Title: ${state.currentSubtask.title}`);
120
+ }
121
+ if (state.currentSubtask.contract) {
122
+ console.log(` Allowed Files: ${state.currentSubtask.contract.allowedFiles.join(", ") || "(all)"}`);
123
+ console.log(` Decision Budget: ${state.currentSubtask.contract.decisionBudget}`);
124
+ if (state.currentSubtask.contract.verificationCmd) {
125
+ console.log(` Verify Command: ${state.currentSubtask.contract.verificationCmd}`);
126
+ }
127
+ }
128
+ }
129
+ else {
130
+ console.log("Current Subtask: (none)");
131
+ }
132
+ console.log(`Completed Tasks: ${state.completedSubtasks.length > 0 ? state.completedSubtasks.join(", ") : "(none)"}`);
133
+ console.log(`Last Synchronized: ${state.lastSync}\n`);
134
+ break;
135
+ }
136
+ case "sync": {
137
+ printHeader();
138
+ console.log("Synchronizing state from current Git branch and GitHub...\n");
139
+ const synced = syncStateFromGit();
140
+ if (synced.activeIssue) {
141
+ console.log(`[OK] Synchronized with Issue #${synced.activeIssue.id} (${synced.activeIssue.title})`);
142
+ console.log(` Branch: ${synced.activeIssue.branch}`);
143
+ }
144
+ else {
145
+ console.log("[OK] Synchronized. No active issue detected on current branch.");
146
+ }
147
+ console.log("");
148
+ break;
149
+ }
150
+ case "set-task": {
151
+ const taskId = args[1];
152
+ const title = args.slice(2).join(" ");
153
+ if (!taskId) {
154
+ console.error("Error: Subtask ID is required (e.g. lognexus state set-task T1 'Add schema')\n");
155
+ process.exit(1);
156
+ }
157
+ printHeader();
158
+ setSubtask(taskId, title);
159
+ console.log(`[OK] Active subtask set to: ${taskId}${title ? ` — ${title}` : ""}\n`);
160
+ break;
161
+ }
162
+ case "finish-task": {
163
+ const taskId = args[1];
164
+ if (!taskId) {
165
+ console.error("Error: Subtask ID is required (e.g. lognexus state finish-task T1)\n");
166
+ process.exit(1);
167
+ }
168
+ printHeader();
169
+ finishSubtask(taskId);
170
+ console.log(`[OK] Subtask ${taskId} marked as completed.\n`);
171
+ break;
172
+ }
173
+ case "clear": {
174
+ printHeader();
175
+ clearState();
176
+ console.log("[OK] Persistent state cleared.\n");
177
+ break;
178
+ }
179
+ default:
180
+ console.error(`Unknown state subcommand: ${sub}\n`);
181
+ printUsage();
182
+ process.exit(1);
71
183
  }
72
- const tier = tierArg;
73
- const config = loadConfig();
74
- const assignment = resolveTier(tier, config);
75
- console.log(`\nšŸ”· LogNexus Tier Route: [${assignment.tier}]`);
76
- console.log(`Provider: ${assignment.provider.id}`);
77
- console.log(`Model: ${assignment.model}`);
78
- console.log(`Purpose: ${assignment.description}\n`);
79
184
  }
80
- function runHelp() {
81
- printHeader();
82
- console.log("Usage: lognexus <command> [options]\n");
83
- console.log("Commands:");
84
- console.log(" doctor [--live] Run environment and credentials diagnostic");
85
- console.log(" route <tier> Resolve assigned model/provider for a tier (tier-1, tier-2, tier-3)");
86
- console.log(" config Display sanitized configuration");
87
- console.log(" help Show this help message\n");
185
+ async function handleNote(args) {
186
+ const sub = args[0]?.toLowerCase() || "show";
187
+ switch (sub) {
188
+ case "show": {
189
+ const commit = args[1] || "HEAD";
190
+ printHeader();
191
+ const note = getNote(commit);
192
+ if (note) {
193
+ console.log(`Git Note for commit [${commit}] (refs/notes/lognexus):\n`);
194
+ console.log(note);
195
+ }
196
+ else {
197
+ console.log(`No LogNexus note found attached to commit [${commit}].`);
198
+ console.log("Tip: Run 'lognexus note attach' to attach current state to this commit.");
199
+ }
200
+ console.log("");
201
+ break;
202
+ }
203
+ case "attach": {
204
+ const commit = args[1] || "HEAD";
205
+ printHeader();
206
+ const payload = attachCurrentStateToCommit(commit);
207
+ console.log(`[OK] Attached LogNexus note to commit [${commit}] (refs/notes/lognexus):`);
208
+ console.log(` Issue: ${payload.issue ? `#${payload.issue.id} — ${payload.issue.title}` : "(none)"}`);
209
+ console.log(` Subtask: ${payload.subtask ? `${payload.subtask.id} (${payload.subtask.title})` : "(none)"}`);
210
+ console.log(` Tier: ${payload.tier}\n`);
211
+ break;
212
+ }
213
+ case "list": {
214
+ printHeader();
215
+ const notes = listNotes();
216
+ console.log(`LogNexus Notes (refs/notes/lognexus) — ${notes.length} note(s):\n`);
217
+ if (notes.length === 0) {
218
+ console.log("No notes recorded yet.");
219
+ }
220
+ else {
221
+ for (const n of notes) {
222
+ console.log(` • Commit: ${n.commitSha} (blob: ${n.noteBlob})`);
223
+ }
224
+ }
225
+ console.log("");
226
+ break;
227
+ }
228
+ case "push": {
229
+ const remote = args[1] || "origin";
230
+ printHeader();
231
+ console.log(`Pushing refs/notes/lognexus to ${remote}...`);
232
+ const ok = pushNotes(remote);
233
+ if (ok) {
234
+ console.log(`[OK] Notes pushed to ${remote} successfully.\n`);
235
+ }
236
+ else {
237
+ console.error(`[FAIL] Could not push notes to ${remote}.\n`);
238
+ }
239
+ break;
240
+ }
241
+ case "fetch": {
242
+ const remote = args[1] || "origin";
243
+ printHeader();
244
+ console.log(`Fetching refs/notes/lognexus from ${remote}...`);
245
+ const ok = fetchNotes(remote);
246
+ if (ok) {
247
+ console.log(`[OK] Notes fetched from ${remote} successfully.\n`);
248
+ }
249
+ else {
250
+ console.error(`[FAIL] Could not fetch notes from ${remote}.\n`);
251
+ }
252
+ break;
253
+ }
254
+ default:
255
+ console.error(`Unknown note subcommand: ${sub}\n`);
256
+ printUsage();
257
+ process.exit(1);
258
+ }
88
259
  }
89
260
  async function main() {
90
- const command = process.argv[2] || "help";
91
- const args = process.argv.slice(3);
261
+ const args = process.argv.slice(2);
262
+ const command = args[0]?.toLowerCase();
92
263
  switch (command) {
264
+ case "init":
265
+ await handleInit();
266
+ break;
93
267
  case "doctor":
94
- await runDoctor(args);
268
+ await handleDoctor();
95
269
  break;
96
- case "route":
97
- runRoute(args);
270
+ case "status":
271
+ await handleStatus();
98
272
  break;
99
- case "config":
100
- printHeader();
101
- console.log(JSON.stringify({
102
- ...loadConfig(),
103
- gemini: { ...loadConfig().gemini, apiKey: redactKey(loadConfig().gemini.apiKey) },
104
- deepseek: { ...loadConfig().deepseek, apiKey: redactKey(loadConfig().deepseek.apiKey) },
105
- }, null, 2));
273
+ case "state":
274
+ await handleState(args.slice(1));
106
275
  break;
107
- default:
108
- runHelp();
276
+ case "note":
277
+ await handleNote(args.slice(1));
109
278
  break;
279
+ case "mcp":
280
+ // stdout is reserved for JSON-RPC frames: never print the banner here.
281
+ await startMcpServer();
282
+ break;
283
+ case "help":
284
+ case "--help":
285
+ case "-h":
286
+ case undefined:
287
+ printUsage();
288
+ break;
289
+ default:
290
+ console.error(`Unknown command: ${command}\n`);
291
+ printUsage();
292
+ process.exit(1);
110
293
  }
111
294
  }
112
295
  main().catch((err) => {