@ulpi/cli 0.1.0 → 0.1.1

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.
package/README.md CHANGED
@@ -40,20 +40,19 @@ cd your-project
40
40
  ulpi init
41
41
  ```
42
42
 
43
- That's it. ULPI detects your stack — language, framework, package manager, test runner, linter — and generates a tailored rules configuration. Hooks are installed into Claude Code automatically.
43
+ ULPI detects your stack — language, framework, package manager, test runner, linter — and generates a tailored rules configuration. Hooks are installed into Claude Code automatically.
44
44
 
45
45
  Next time you start a Claude Code session, ULPI is active.
46
46
 
47
47
  ### Try it without installing
48
48
 
49
49
  ```bash
50
- cd your-project
51
50
  npx @ulpi/cli init
52
51
  ```
53
52
 
54
53
  ---
55
54
 
56
- ## What You Get
55
+ ## Features
57
56
 
58
57
  ### Automatic Permissions
59
58
 
@@ -66,6 +65,12 @@ permissions:
66
65
  matcher: Bash
67
66
  command_pattern: "npm test|pnpm test|yarn test"
68
67
  decision: allow
68
+
69
+ auto-approve-git-read:
70
+ trigger: PermissionRequest
71
+ matcher: Bash
72
+ command_pattern: "git (status|log|diff|branch)"
73
+ decision: allow
69
74
  ```
70
75
 
71
76
  ### Guardrails
@@ -83,33 +88,140 @@ preconditions:
83
88
  matcher: "Write|Edit"
84
89
  message: "Read the file before editing it."
85
90
  requires_read: true
91
+
92
+ test-before-commit:
93
+ trigger: PreToolUse
94
+ matcher: Bash
95
+ command_pattern: "git commit"
96
+ message: "Run tests before committing."
97
+ requires:
98
+ tests_run: true
99
+ ```
100
+
101
+ ### Pipelines
102
+
103
+ Chain multiple steps into automated workflows that run after tool execution.
104
+
105
+ ```yaml
106
+ pipelines:
107
+ pre-commit-checks:
108
+ trigger: PostToolUse
109
+ matcher: Bash
110
+ command_pattern: "git commit"
111
+ steps:
112
+ - name: build
113
+ command: "pnpm -r build"
114
+ - name: test
115
+ command: "pnpm test"
116
+ block_on_failure: true
86
117
  ```
87
118
 
88
119
  ### Session Tracking
89
120
 
90
- ULPI knows what happened in your sessionwhich files were read, which were written, which commands ran. Rules can use this context to make smarter decisions.
121
+ ULPI tracks every action in real time — files read and written, commands executed, rules enforced, tests passed or failed. Session state powers smarter rule evaluation and feeds into history, memory, and the web dashboard.
122
+
123
+ Each session follows a state machine (`idle` -> `active` -> `active_committed` -> `ended`) and logs up to 10,000 events as an append-only JSONL file.
91
124
 
92
125
  ### Web Dashboard
93
126
 
94
- A full web UI for managing rules, viewing live sessions, reviewing AI-generated plans, and browsing session history.
127
+ A full web UI for managing rules, monitoring live sessions, reviewing plans and code, and browsing history.
95
128
 
96
129
  ```bash
97
130
  ulpi ui
98
131
  ```
99
132
 
100
- <!-- TODO: Add screenshot -->
133
+ The dashboard shows:
134
+
135
+ - **Guards** — Active rule counts, enforcement stats, rule breakdown by type
136
+ - **Session** — Live session state with real-time event timeline (WebSocket)
137
+ - **Review** — Pending plan and code reviews
138
+ - **CodeMap** — Index status, file and chunk counts
139
+ - **Memory** — Memory count, classified sessions, importance breakdown
140
+ - **History** — Captured entries with AI enrichment status
141
+ - **Skills** — Available bundled, project, and global skills
142
+ - **Responses** — Notification channel configuration
101
143
 
102
144
  ### Plan & Code Review
103
145
 
104
- Review AI-generated plans and code changes in a dedicated UI before they execute. Annotate, approve, or reject with feedback that gets sent back to the agent.
146
+ Review AI-generated plans and code changes in a browser-based UI before they execute.
147
+
148
+ **Plan review** intercepts `ExitPlanMode` — the plan is parsed into sections, scored across 8 quality dimensions (test coverage, error handling, rollback strategy, scope clarity, and more), and presented for your review. You can annotate sections, assign priorities and risk levels, add per-section instructions, or make inline edits. Approve or deny with feedback that goes directly back to the agent.
149
+
150
+ **Code review** intercepts `git commit` — the staged diff and commit message are shown for review with line-level annotation tools.
151
+
152
+ Both flows use long-poll HTTP transport with a 10-minute timeout. If the server isn't running, the agent continues normally (fail-open).
105
153
 
106
- ### Semantic Code Search
154
+ ### Semantic Code Search (CodeMap)
107
155
 
108
- ULPI indexes your codebase and exposes it as MCP tools that Claude Code can use for smarter, context-aware search — beyond simple grep.
156
+ ULPI indexes your entire codebase using hybrid vector + BM25 search with AST-aware chunking. The agent gets smarter search than grep it understands code semantics, symbol names, and file context.
157
+
158
+ - **AST chunking** aligns chunks to function and class boundaries
159
+ - **Symbol extraction** identifies functions, classes, interfaces, and types
160
+ - **Hybrid ranking** fuses vector similarity (60%), keyword matching (25%), symbol boost (10%), and path relevance (5%)
161
+ - **Incremental indexing** — only re-indexes changed files
162
+ - **Per-branch indexes** — each git branch gets its own index
163
+ - **Shadow branch export** — share indexes across machines via git
164
+
165
+ Exposed to Claude Code as MCP tools: `search_code`, `search_symbols`, `get_file_summary`, `get_index_stats`, and `reindex`.
166
+
167
+ ```bash
168
+ ulpi codemap init # Index your codebase
169
+ ulpi codemap search "authentication middleware"
170
+ ```
109
171
 
110
172
  ### Agent Memory
111
173
 
112
- Captures decisions, patterns, and lessons learned across sessions. Your AI agent builds institutional knowledge over time instead of starting fresh every conversation.
174
+ Your AI agent builds institutional knowledge across sessions instead of starting fresh every conversation.
175
+
176
+ ULPI captures session events, classifies them with an LLM into 8 memory types — **decisions**, **patterns**, **bug root causes**, **preferences**, **constraints**, **context**, **lessons**, and **relationships** — then stores them with vector embeddings for semantic search.
177
+
178
+ At the start of each session, the most relevant memories are surfaced to the agent automatically.
179
+
180
+ - **Deduplication** — new memories are compared against existing ones (0.92 similarity threshold) to prevent redundancy
181
+ - **Importance-weighted ranking** — critical memories never decay; low-importance ones fade over time
182
+ - **Redaction** — API keys, tokens, and secrets are stripped before storage
183
+ - **Soft delete** — memories can be superseded rather than permanently removed
184
+
185
+ Exposed as MCP tools: `search_memory`, `save_memory`, `get_timeline`, `get_session_context`, `forget`, and `memory_stats`.
186
+
187
+ ```bash
188
+ ulpi memory search "authentication approach"
189
+ ulpi memory status
190
+ ```
191
+
192
+ ### Session History
193
+
194
+ Every coding session is recorded on a per-user orphan git branch (`ulpi/history-<username>`) — separate from your code, never touching your working tree.
195
+
196
+ Each commit gets a structured JSON entry with:
197
+
198
+ - Git metadata (SHA, message, author, branch, parents)
199
+ - Diff statistics (files changed, insertions, deletions, per-file breakdown)
200
+ - Session summary (files read/written, commands run, rules enforced)
201
+ - Hook-derived analytics (rule evaluations, permission decisions, tool usage)
202
+ - AI enrichment (summary, intent, challenges, learnings, recommendations)
203
+ - Review plan snapshots and session transcripts
204
+
205
+ ```bash
206
+ ulpi history init # Create the history branch
207
+ ulpi history list # Browse captured sessions
208
+ ulpi history enrich --all # AI-enrich all entries
209
+ ```
210
+
211
+ ### Notifications
212
+
213
+ Route events to desktop notifications, webhooks, terminal bells, or log files based on classification rules. Built-in deduplication prevents notification storms.
214
+
215
+ ### Templates & Skills
216
+
217
+ ULPI ships with **28 built-in templates** for popular stacks — Node.js, Python, Go, Rust, Next.js, Express, Laravel, Django, FastAPI, Prisma, Docker, and more.
218
+
219
+ **Skills** are injectable markdown guides that ULPI attaches to blocked tool messages — teaching the agent how to fix the issue instead of just blocking it.
220
+
221
+ ```bash
222
+ ulpi templates list
223
+ ulpi skills list
224
+ ```
113
225
 
114
226
  ---
115
227
 
@@ -143,12 +255,12 @@ permissions:
143
255
  matcher: Bash
144
256
  command_pattern: "git (status|log|diff|branch)"
145
257
  decision: allow
146
- ```
147
-
148
- ULPI ships with **28 built-in templates** for popular stacks — Node.js, Python, Go, Rust, Next.js, Laravel, Django, FastAPI, and more.
149
258
 
150
- ```bash
151
- ulpi templates list
259
+ review:
260
+ enabled: true
261
+ plan_review: true
262
+ code_review: true
263
+ auto_open_browser: true
152
264
  ```
153
265
 
154
266
  ---
@@ -179,12 +291,19 @@ ulpi templates list
179
291
 
180
292
  ## How It Works
181
293
 
182
- ULPI uses [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) — lifecycle events that fire before and after every tool execution:
294
+ ULPI uses [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) — lifecycle events that fire before and after every tool execution.
295
+
296
+ Seven hooks intercept the full session lifecycle:
183
297
 
184
- 1. **Before a tool runs**, ULPI checks your rules. Should this file edit be allowed? Has the file been read first? Is this command safe?
185
- 2. **When a permission is requested**, ULPI decides automatically based on your rules — allow, deny, or ask the user.
186
- 3. **After a tool runs**, ULPI updates session state and runs any postconditions you've defined.
187
- 4. **At session boundaries**, ULPI captures history, classifies memories, and indexes code changes.
298
+ | Hook | When | What ULPI Does |
299
+ |------|------|----------------|
300
+ | **SessionStart** | Claude Code session begins | Detect stack, capture branch/HEAD, surface memories, import CodeMap index |
301
+ | **PreToolUse** | Before any tool runs | Evaluate preconditions, block dangerous commands, intercept git commits for code review |
302
+ | **PostToolUse** | After a tool completes | Track files/commands, run postconditions, capture history on new commits, export CodeMap on git push |
303
+ | **PermissionRequest** | Tool needs approval | Auto-approve or deny based on rules, intercept ExitPlanMode for plan review |
304
+ | **Notification** | Event notification | Classify and route to desktop, webhook, terminal, or log channels |
305
+ | **Stop** | Session stopping | Final checks (warn about missing tests/lint) |
306
+ | **SessionEnd** | Session complete | Persist summary, capture commits to history, classify memories, export indexes |
188
307
 
189
308
  If ULPI ever encounters an error, it fails open — Claude Code continues normally. Your agent is never blocked by a bug in ULPI.
190
309
 
@@ -13,7 +13,7 @@ var REGISTRY_URL = CLI_REGISTRY_URL;
13
13
  var FETCH_TIMEOUT_MS = 5e3;
14
14
  function getCurrentVersion() {
15
15
  try {
16
- return "0.1.0";
16
+ return "0.1.1";
17
17
  } catch {
18
18
  return "0.0.0";
19
19
  }
@@ -412,7 +412,7 @@ async function initSubcommand(projectDir) {
412
412
  }
413
413
  const projectName = path2.basename(projectDir);
414
414
  try {
415
- initHistoryBranch(projectDir, projectName, "0.1.0");
415
+ initHistoryBranch(projectDir, projectName, "0.1.1");
416
416
  } catch (err) {
417
417
  const message = err instanceof Error ? err.message : String(err);
418
418
  console.log(chalk.red(`Error: ${message}`));
package/dist/index.js CHANGED
@@ -138,7 +138,7 @@ async function handleSessionStart(ctx) {
138
138
  if (shouldPromptForGeneration(projectDir2)) {
139
139
  outputGenerationPrompt();
140
140
  }
141
- import("./version-checker-ANCS3IHR.js").then((m) => m.checkForUpdates()).catch(() => {
141
+ import("./version-checker-M37KI7DY.js").then((m) => m.checkForUpdates()).catch(() => {
142
142
  });
143
143
  try {
144
144
  const { isMemoryEnabled, loadMemoryConfig, getTopMemories, formatMemoriesForAgent } = await import("./dist-R5F4MX3I.js");
@@ -2043,9 +2043,9 @@ async function main() {
2043
2043
  case "ui":
2044
2044
  return (await import("./ui-L7UAWXDY.js")).runUI(args.slice(1), projectDir);
2045
2045
  case "update":
2046
- return (await import("./update-M2B4RLGH.js")).runUpdate(args.slice(1));
2046
+ return (await import("./update-DJ227LL3.js")).runUpdate(args.slice(1));
2047
2047
  case "history":
2048
- return (await import("./history-ATTUKOHO.js")).runHistory(args.slice(1), projectDir);
2048
+ return (await import("./history-Q2LDADFW.js")).runHistory(args.slice(1), projectDir);
2049
2049
  case "review":
2050
2050
  return (await import("./review-ADUPV3PN.js")).runReview(args.slice(1), projectDir);
2051
2051
  case "config":
@@ -2058,7 +2058,7 @@ async function main() {
2058
2058
  return (await import("./projects-ATHDD3D6.js")).runProjects(args.slice(1));
2059
2059
  case "--version":
2060
2060
  case "-v":
2061
- console.log("0.1.0");
2061
+ console.log("0.1.1");
2062
2062
  return;
2063
2063
  case "--help":
2064
2064
  case "-h":
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  checkForUpdates
3
- } from "./chunk-PKD4ASEM.js";
3
+ } from "./chunk-4KRVDKGB.js";
4
4
  import {
5
5
  CLI_BIN_NAME,
6
6
  CLI_NPM_PACKAGE
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  checkForUpdates,
3
3
  getCurrentVersion
4
- } from "./chunk-PKD4ASEM.js";
4
+ } from "./chunk-4KRVDKGB.js";
5
5
  import "./chunk-7LXY5UVC.js";
6
6
  import "./chunk-4VNS5WPM.js";
7
7
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ulpi/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "ulpi": "./dist/index.js"
@@ -43,22 +43,22 @@
43
43
  "tsup": "^8.4.0",
44
44
  "typescript": "^5.7.0",
45
45
  "vitest": "^3.0.0",
46
- "@ulpi/guards-engine": "0.1.0",
47
46
  "@ulpi/contracts": "0.1.0",
48
47
  "@ulpi/config": "0.1.0",
48
+ "@ulpi/guards-engine": "0.1.0",
49
49
  "@ulpi/session-engine": "0.1.0",
50
50
  "@ulpi/templates-engine": "0.1.0",
51
51
  "@ulpi/notifications-engine": "0.1.0",
52
- "@ulpi/history-engine": "0.1.0",
52
+ "@ulpi/stack-engine": "0.1.0",
53
53
  "@ulpi/projects-engine": "0.1.0",
54
+ "@ulpi/history-engine": "0.1.0",
55
+ "@ulpi/review-engine": "0.1.0",
54
56
  "@ulpi/review-runtime": "0.1.0",
55
57
  "@ulpi/codemap-engine": "0.1.0",
56
- "@ulpi/review-engine": "0.1.0",
57
- "@ulpi/api": "0.1.0",
58
- "@ulpi/memory-mcp": "0.1.0",
59
58
  "@ulpi/depgraph-engine": "0.1.0",
60
59
  "@ulpi/memory-engine": "0.1.0",
61
- "@ulpi/stack-engine": "0.1.0",
60
+ "@ulpi/api": "0.1.0",
61
+ "@ulpi/memory-mcp": "0.1.0",
62
62
  "@ulpi/codemap-mcp": "0.1.0"
63
63
  },
64
64
  "publishConfig": {