@axplusb/kepler 1.0.4 → 1.0.9

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 (48) hide show
  1. package/KEPLER-README.md +128 -2
  2. package/package.json +4 -4
  3. package/pulse/app/activity/page.tsx +1 -1
  4. package/pulse/app/api/import/route.ts +1 -1
  5. package/pulse/app/api/memory/route.ts +2 -2
  6. package/pulse/app/costs/page.tsx +1 -1
  7. package/pulse/app/export/page.tsx +3 -3
  8. package/pulse/app/globals.css +3 -3
  9. package/pulse/app/help/page.tsx +11 -11
  10. package/pulse/app/history/page.tsx +2 -2
  11. package/pulse/app/layout.tsx +2 -2
  12. package/pulse/app/memory/page.tsx +2 -2
  13. package/pulse/app/overview-client.tsx +1 -1
  14. package/pulse/app/page.tsx +2 -2
  15. package/pulse/app/plans/page.tsx +2 -2
  16. package/pulse/app/projects/page.tsx +1 -1
  17. package/pulse/app/sessions/page.tsx +1 -1
  18. package/pulse/app/settings/page.tsx +4 -4
  19. package/pulse/app/todos/page.tsx +2 -2
  20. package/pulse/app/tools/page.tsx +1 -1
  21. package/pulse/cli.js +15 -25
  22. package/pulse/components/layout/sidebar.tsx +2 -2
  23. package/pulse/components/sessions/replay/user-tool-result.tsx +1 -1
  24. package/pulse/lib/claude-reader.ts +1 -1
  25. package/pulse/lib/decode.ts +1 -1
  26. package/pulse/package.json +3 -3
  27. package/src/auth/tarang-auth.mjs +1 -1
  28. package/src/config/cli-args.mjs +5 -0
  29. package/src/context/retriever.mjs +1 -1
  30. package/src/context/skeleton.mjs +1 -1
  31. package/src/core/approval.mjs +22 -53
  32. package/src/core/headless.mjs +68 -24
  33. package/src/core/paths.mjs +1 -1
  34. package/src/core/project-artifacts.mjs +37 -0
  35. package/src/core/stream-client.mjs +6 -1
  36. package/src/core/tool-executor.mjs +163 -55
  37. package/src/skills/installer.mjs +188 -0
  38. package/src/skills/loader.mjs +217 -112
  39. package/src/terminal/main.mjs +19 -1
  40. package/src/terminal/repl.mjs +40 -105
  41. package/src/terminal/skills.mjs +54 -0
  42. package/src/terminal/tool-display.mjs +82 -0
  43. package/src/tools/bash.mjs +5 -2
  44. package/src/tools/project-overview.mjs +418 -0
  45. package/src/tools/registry.mjs +0 -16
  46. package/src/ui/banner.mjs +7 -14
  47. package/src/ui/formatter.mjs +6 -40
  48. package/README.md.orca +0 -82
package/KEPLER-README.md CHANGED
@@ -26,9 +26,42 @@ kepler dashboard Open Kepler Pulse analytics dashboard
26
26
  kepler sessions List recent local sessions
27
27
  kepler stats Aggregate session stats (tokens, cost, tools)
28
28
  kepler history Recent prompt history
29
+ kepler skills list List discovered project and global skills
30
+ kepler skills view NAME View a skill procedure or bundled resource
31
+ kepler skills install SRC Install skills from a directory or Git repository
32
+ kepler skills update NAME Update a locked installed skill
33
+ kepler skills remove NAME Remove an installed skill
29
34
  kepler version Show version
30
35
  ```
31
36
 
37
+ ## Agent Skills
38
+
39
+ Kepler supports portable `SKILL.md` bundles and Claude-compatible skill
40
+ directories. Skill metadata is included in the cached agent context; full
41
+ instructions and references are loaded only when the agent calls
42
+ `skill_view`.
43
+
44
+ Discovery precedence:
45
+
46
+ 1. `<project>/.kepler/skills`
47
+ 2. `<project>/.claude/skills`
48
+ 3. `~/.kepler/skills`
49
+ 4. `~/.claude/skills`
50
+
51
+ Install a local bundle or a repository containing one or more skills:
52
+
53
+ ```bash
54
+ kepler skills install ./my-skill
55
+ kepler skills install github:owner/skills-repository
56
+ kepler skills install https://github.com/owner/skills.git
57
+ kepler skills install ./team-skills --project
58
+ ```
59
+
60
+ Global installations are recorded in `~/.kepler/skills.lock.json`. Project
61
+ installations use `<project>/.kepler/skills.lock.json`. Kepler copies skill
62
+ files as data, rejects symlinks, and does not execute bundled scripts during
63
+ installation.
64
+
32
65
  ## REPL Commands
33
66
 
34
67
  ```
@@ -84,8 +117,101 @@ Platform default included free. Bring your own API key for unlimited.
84
117
 
85
118
  | Model | Score | Cost |
86
119
  |-------|-------|------|
87
- | DeepSeek V4 Flash | 30.7% (92/300) | $0.03/fix |
88
- | DeepSeek V4 Pro | 50% (14/28 sample) | $0.48/fix |
120
+ | DeepSeek V4 Flash + stagnation | 47.3% (142/300) | $0.046/instance |
121
+ | DeepSeek V4 Flash | 39.7% (119/300) | $0.046/instance |
122
+ | DeepSeek V4 Flash (baseline) | 30.7% (92/300) | $0.03/instance |
123
+ | DeepSeek V4 Pro | 50% (14/28 sample) | $0.48/instance |
124
+
125
+ ### Running SWE-bench
126
+
127
+ Benchmarks run on an Azure VM (`swebench-eval-vm`, D8s_v3) with a local backend + CLI.
128
+
129
+ **Setup (one-time):**
130
+
131
+ ```bash
132
+ # Deploy backend + CLI + harness to VM
133
+ ./benchmark/vm-setup.sh
134
+ ```
135
+
136
+ **Run benchmark:**
137
+
138
+ ```bash
139
+ # SSH into VM
140
+ ssh azureuser@20.9.77.9
141
+
142
+ # Start backend
143
+ source ~/.tarang-benchmark.env
144
+ cd ~/tarang-backend
145
+ source ~/backend-env/bin/activate
146
+ uvicorn app.main:app --port 8000 &
147
+
148
+ # Run all 300 instances (3 parallel workers, skip already-done)
149
+ source ~/swebench-env/bin/activate
150
+ cd ~/tarang-npm
151
+ python3 benchmark/swe-bench/harness.py \
152
+ --dataset lite \
153
+ --model deepseek/deepseek-v4-flash \
154
+ --parallel 3 \
155
+ --skip-done \
156
+ --timeout 600
157
+ ```
158
+
159
+ **Flags:**
160
+
161
+ | Flag | Description |
162
+ |------|-------------|
163
+ | `--dataset lite\|verified\|full` | SWE-bench split (default: lite, 300 instances) |
164
+ | `--model <id>` | OpenRouter model ID |
165
+ | `--parallel <n>` | Number of parallel workers (default: 1) |
166
+ | `--skip-done` | Skip instances already in the output file |
167
+ | `--timeout <s>` | Per-instance timeout in seconds (default: 600) |
168
+ | `--limit <n>` | Only run first N instances |
169
+ | `--instance <id>` | Run a single instance by ID |
170
+ | `--gen-only` | Generate patches only (skip test evaluation) |
171
+ | `--output <path>` | Custom output file path |
172
+
173
+ **Results** are saved incrementally to `benchmark/results/<model>_<dataset>.json` — no data loss on kill.
174
+
175
+ **Convenience scripts on VM:**
176
+
177
+ ```bash
178
+ # Watchdog (auto-restarts on crash)
179
+ tmux new-session -d -s bench "bash /tmp/start-parallel.sh"
180
+
181
+ # Check progress
182
+ tmux capture-pane -t bench -p | tail -20
183
+
184
+ # Or use the pre-built start script
185
+ ./start-benchmark.sh deepseek/deepseek-v4-flash
186
+ ```
187
+
188
+ ## Terminal-Bench
189
+
190
+ Use the benchmark-only adapter under `benchmark/terminal-bench/` when you want to
191
+ evaluate Kepler in Terminal-Bench without touching the production CLI.
192
+
193
+ It runs with:
194
+
195
+ - a separate backend venv
196
+ - a separate backend port (`8001` by default)
197
+ - a custom `--agent-import-path kepler_agent:KeplerAgent`
198
+ - per-trial workspace isolation so memory does not leak across tasks
199
+
200
+ Reusable entrypoints:
201
+
202
+ ```bash
203
+ benchmark/terminal-bench/setup-kepler-backend.sh
204
+ benchmark/terminal-bench/run-kepler-backend.sh
205
+ benchmark/terminal-bench/run-kepler-benchmark.sh --task-id hello-world
206
+ ```
207
+
208
+ Environment variables that can be overridden in another machine or CI setup:
209
+
210
+ `BACKEND_DIR`, `FRAMEWORK_DIR`, `VENV_DIR`, `TB_VENV`, `TARANG_NPM_DIR`,
211
+ `ENV_FILE`, `BACKEND_URL`, `PORT`, `MODEL`, `DATASET`, `CONCURRENCY`.
212
+
213
+ Create a local `.tarang-tbench.env` with the benchmark credentials and backend
214
+ auth token, then point `ENV_FILE` at it if needed.
89
215
 
90
216
  ## Links
91
217
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@axplusb/kepler",
3
- "version": "1.0.4",
4
- "description": "Kepler — AI coding agent that plans, builds, tests, and ships. 30.7% on SWE-bench Lite.",
3
+ "version": "1.0.9",
4
+ "description": "Kepler — AI coding agent with operating brief, preflight planning, and sub-agents. SWE-bench Lite evaluated.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "kepler": "src/terminal/main.mjs"
@@ -14,7 +14,7 @@
14
14
  "readme": "KEPLER-README.md",
15
15
  "scripts": {
16
16
  "start": "node src/terminal/main.mjs",
17
- "test": "node test/test-sse-client.mjs && node test/test-tool-executor.mjs && node test/test-callback.mjs && node test/test-formatter.mjs && node test/test-terminal-rendering.mjs && node test/test-slash-commands.mjs && node test/test-approval.mjs && node test/test-session-manager.mjs && node test/test-safety.mjs && node test/test-jsonl-writer.mjs && node test/test-analytics.mjs && node test/test-stagnation.mjs"
17
+ "test": "node test/test-sse-client.mjs && node test/test-tool-executor.mjs && node test/test-project-artifacts.mjs && node test/test-skills.mjs && node test/test-callback.mjs && node test/test-formatter.mjs && node test/test-terminal-rendering.mjs && node test/test-slash-commands.mjs && node test/test-approval.mjs && node test/test-session-manager.mjs && node test/test-safety.mjs && node test/test-jsonl-writer.mjs && node test/test-analytics.mjs && node test/test-stagnation.mjs"
18
18
  },
19
19
  "engines": {
20
20
  "node": ">=18.0.0"
@@ -38,7 +38,7 @@
38
38
  "homepage": "https://codekepler.ai",
39
39
  "repository": {
40
40
  "type": "git",
41
- "url": "git+https://github.com/raviakasapu/codekepler-web.git"
41
+ "url": "git+https://github.com/raviakasapu/codekepler-npm.git"
42
42
  },
43
43
  "dependencies": {}
44
44
  }
@@ -175,7 +175,7 @@ export default function ActivityPage() {
175
175
  <CalendarDays className="h-4 w-4 shrink-0 text-muted-foreground" />
176
176
  Day of Week
177
177
  </CardTitle>
178
- <CardDescription>Which days you use Orca most</CardDescription>
178
+ <CardDescription>Which days you use Kepler most</CardDescription>
179
179
  </CardHeader>
180
180
  <CardContent className="flex flex-1 flex-col justify-between pt-3 pb-0">
181
181
  <DayOfWeekChart data={data.dow_counts} />
@@ -24,7 +24,7 @@ export async function POST(req: Request) {
24
24
  }
25
25
 
26
26
  // Note: actual file writing is intentionally not implemented here
27
- // to prevent accidental corruption of ~/.orca/ live data.
27
+ // to prevent accidental corruption of ~/.kepler/ live data.
28
28
  // The import feature shows a diff preview only.
29
29
 
30
30
  return NextResponse.json(diff)
@@ -6,7 +6,7 @@ import { readMemories } from '@/lib/claude-reader'
6
6
 
7
7
  export const dynamic = 'force-dynamic'
8
8
 
9
- const CLAUDE_DIR = path.join(os.homedir(), '.orca')
9
+ const CLAUDE_DIR = path.join(os.homedir(), '.kepler')
10
10
 
11
11
  export async function GET() {
12
12
  const memories = await readMemories()
@@ -37,7 +37,7 @@ export async function PATCH(req: Request) {
37
37
 
38
38
  const filePath = path.join(CLAUDE_DIR, 'projects', projectSlug, 'memory', file)
39
39
 
40
- // Ensure the resolved path stays within ~/.orca/projects/
40
+ // Ensure the resolved path stays within ~/.kepler/projects/
41
41
  const allowedRoot = path.join(CLAUDE_DIR, 'projects')
42
42
  if (!filePath.startsWith(allowedRoot + path.sep)) {
43
43
  return NextResponse.json({ error: 'Path outside allowed directory' }, { status: 403 })
@@ -23,7 +23,7 @@ export default function CostsPage() {
23
23
 
24
24
  return (
25
25
  <div className="flex flex-col min-h-screen">
26
- <TopBar title="Costs" subtitle="Estimated spend from ~/.orca/" />
26
+ <TopBar title="Costs" subtitle="Estimated spend from ~/.kepler/" />
27
27
  <div className="p-6 space-y-6">
28
28
 
29
29
  {error && (
@@ -146,7 +146,7 @@ export default function ExportPage() {
146
146
  <div className="flex flex-col min-h-screen">
147
147
  <TopBar
148
148
  title="Export & import"
149
- subtitle="Download a portable backup of ~/.orca/ analytics or merge data from another machine"
149
+ subtitle="Download a portable backup of ~/.kepler/ analytics or merge data from another machine"
150
150
  />
151
151
 
152
152
  <div className="p-6 space-y-6 flex-1">
@@ -239,7 +239,7 @@ export default function ExportPage() {
239
239
  </CardTitle>
240
240
  </CardHeader>
241
241
  <CardContent className="pt-0">
242
- <p className="text-xs text-muted-foreground">From ~/.orca/ when available</p>
242
+ <p className="text-xs text-muted-foreground">From ~/.kepler/ when available</p>
243
243
  </CardContent>
244
244
  </Card>
245
245
  </>
@@ -436,7 +436,7 @@ export default function ExportPage() {
436
436
  <Alert className="border-amber-500/40 bg-amber-500/5">
437
437
  <AlertTriangle className="h-4 w-4 text-amber-600" />
438
438
  <AlertDescription className="text-xs text-amber-800 dark:text-amber-200/90">
439
- Writing merged data to ~/.orca/ is not implemented in this build — this is a preview only.
439
+ Writing merged data to ~/.kepler/ is not implemented in this build — this is a preview only.
440
440
  </AlertDescription>
441
441
  </Alert>
442
442
  <div className="max-h-36 overflow-auto rounded-md border border-border/60 bg-background/50 space-y-1 p-2 font-mono text-[11px] text-muted-foreground">
@@ -86,9 +86,9 @@
86
86
  --radius-lg: var(--radius);
87
87
  --radius-xl: calc(var(--radius) + 4px);
88
88
 
89
- /* Orca accent colors */
90
- --color-orca-cyan: #06b6d4;
91
- --color-orca-cyan-light: #22d3ee;
89
+ /* Kepler accent colors */
90
+ --color-kepler-cyan: #06b6d4;
91
+ --color-kepler-cyan-light: #22d3ee;
92
92
  --color-terminal-cyan: #06b6d4;
93
93
  --color-terminal-green: #34d399;
94
94
  --color-terminal-amber: #f59e0b;
@@ -2,14 +2,14 @@ import { TopBar } from '@/components/layout/top-bar'
2
2
  import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
3
3
 
4
4
  const CLI_COMMANDS = [
5
- { cmd: 'orca', desc: 'Start interactive REPL' },
6
- { cmd: 'orca "instruction"', desc: 'Run a single instruction and exit' },
7
- { cmd: 'orca dashboard', desc: 'Open Orca Pulse analytics dashboard' },
8
- { cmd: 'orca sessions', desc: 'List recent local sessions' },
9
- { cmd: 'orca stats', desc: 'Show aggregate local session stats' },
10
- { cmd: 'orca history', desc: 'Show recent prompt history' },
11
- { cmd: 'orca login', desc: 'Sign in via browser' },
12
- { cmd: 'orca version', desc: 'Show version' },
5
+ { cmd: 'kepler', desc: 'Start interactive REPL' },
6
+ { cmd: 'kepler "instruction"', desc: 'Run a single instruction and exit' },
7
+ { cmd: 'kepler dashboard', desc: 'Open Kepler Pulse analytics dashboard' },
8
+ { cmd: 'kepler sessions', desc: 'List recent local sessions' },
9
+ { cmd: 'kepler stats', desc: 'Show aggregate local session stats' },
10
+ { cmd: 'kepler history', desc: 'Show recent prompt history' },
11
+ { cmd: 'kepler login', desc: 'Sign in via browser' },
12
+ { cmd: 'kepler version', desc: 'Show version' },
13
13
  ]
14
14
 
15
15
  const REPL_COMMANDS = [
@@ -38,7 +38,7 @@ const ENV_VARS = [
38
38
  { name: 'TARANG_ENV', desc: 'Set backend environment (local, development, production)' },
39
39
  { name: 'ANTHROPIC_API_KEY', desc: 'Direct Anthropic API key for local mode' },
40
40
  { name: 'OPENROUTER_API_KEY', desc: 'OpenRouter API key' },
41
- { name: 'ORCA_CONFIG_DIR', desc: 'Override config directory (default: ~/.orca)' },
41
+ { name: 'KEPLER_CONFIG_DIR', desc: 'Override config directory (default: ~/.kepler)' },
42
42
  { name: 'TARANG_BACKEND_URL', desc: 'Override backend URL explicitly' },
43
43
  ]
44
44
 
@@ -46,7 +46,7 @@ const FEATURES = [
46
46
  { title: 'Multi-Agent Orchestration', desc: 'Primary agent spawns explore, plan, and review sub-agents for complex tasks.' },
47
47
  { title: 'Smart Tool Routing', desc: 'Write operations routed to CLI for local execution. Read tools run server-side.' },
48
48
  { title: 'Safety Guardrails', desc: 'Destructive commands (rm, delete) always require approval. Path validation on all file operations.' },
49
- { title: 'Local JSONL Analytics', desc: 'Every session is recorded to ~/.orca/ for offline analytics via Orca Pulse.' },
49
+ { title: 'Local JSONL Analytics', desc: 'Every session is recorded to ~/.kepler/ for offline analytics via Kepler Pulse.' },
50
50
  { title: 'Conversation History', desc: 'Multi-turn conversations within a REPL session. Context preserved across turns.' },
51
51
  { title: 'BM25 Code Index', desc: 'Project files indexed on startup for fast semantic code search.' },
52
52
  ]
@@ -67,7 +67,7 @@ function CommandTable({ commands }: { commands: { cmd: string; desc: string }[]
67
67
  export default function HelpPage() {
68
68
  return (
69
69
  <div className="flex flex-col min-h-screen">
70
- <TopBar title="Help" subtitle="Orca CLI commands, shortcuts, and configuration" />
70
+ <TopBar title="Help" subtitle="Kepler CLI commands, shortcuts, and configuration" />
71
71
  <div className="px-6 py-6 space-y-6">
72
72
 
73
73
  <Card>
@@ -55,7 +55,7 @@ export default function HistoryPage() {
55
55
 
56
56
  return (
57
57
  <div className="flex flex-col min-h-screen">
58
- <TopBar title="History" subtitle="~/.orca/history.jsonl" />
58
+ <TopBar title="History" subtitle="~/.kepler/history.jsonl" />
59
59
  <div className="p-4 md:p-6 space-y-4">
60
60
 
61
61
  {error && (
@@ -92,7 +92,7 @@ export default function HistoryPage() {
92
92
  {pageEntries.length === 0 ? (
93
93
  <div className="text-center py-16 text-muted-foreground text-sm">
94
94
  {(data.history?.length ?? 0) === 0
95
- ? 'No history found in ~/.orca/history.jsonl'
95
+ ? 'No history found in ~/.kepler/history.jsonl'
96
96
  : 'No entries match your search.'}
97
97
  </div>
98
98
  ) : (
@@ -20,8 +20,8 @@ const pressStart2P = Press_Start_2P({
20
20
  })
21
21
 
22
22
  export const metadata: Metadata = {
23
- title: 'Orca Pulse',
24
- description: 'Real-time analytics for your Orca AI agent sessions',
23
+ title: 'Kepler Pulse',
24
+ description: 'Real-time analytics for your Kepler AI agent sessions',
25
25
  }
26
26
 
27
27
  export default function RootLayout({
@@ -260,7 +260,7 @@ export default function MemoryPage() {
260
260
 
261
261
  return (
262
262
  <div className="flex flex-col min-h-screen">
263
- <TopBar title="orca-pulse · memory" subtitle="~/.orca/projects/*/memory/" />
263
+ <TopBar title="kepler-pulse · memory" subtitle="~/.kepler/projects/*/memory/" />
264
264
  <div className="p-4 md:p-6 space-y-5">
265
265
 
266
266
  {error && <p className="text-[#f87171] text-sm font-mono">Error loading memories.</p>}
@@ -338,7 +338,7 @@ export default function MemoryPage() {
338
338
  <p className="text-3xl mb-3">🧠</p>
339
339
  <p className="text-muted-foreground/60 text-sm font-mono">
340
340
  {memories.length === 0
341
- ? 'No memory files found in ~/.orca/projects/*/memory/'
341
+ ? 'No memory files found in ~/.kepler/projects/*/memory/'
342
342
  : 'No memories match your filter.'}
343
343
  </p>
344
344
  </div>
@@ -381,7 +381,7 @@ export function OverviewClient() {
381
381
  <Card>
382
382
  <CardHeader>
383
383
  <CardTitle>Recent Sessions</CardTitle>
384
- <CardDescription>Your latest Orca sessions</CardDescription>
384
+ <CardDescription>Your latest Kepler sessions</CardDescription>
385
385
  </CardHeader>
386
386
  <CardContent>
387
387
  <OverviewConversationTable sessions={sessions} />
@@ -5,8 +5,8 @@ export default function OverviewPage() {
5
5
  return (
6
6
  <div className="flex flex-col min-h-screen">
7
7
  <TopBar
8
- title="Orca Pulse"
9
- subtitle="Real-time analytics for your Orca AI agent sessions"
8
+ title="Kepler Pulse"
9
+ subtitle="Real-time analytics for your Kepler AI agent sessions"
10
10
  />
11
11
  <OverviewClient />
12
12
  </div>
@@ -251,7 +251,7 @@ export default function PlansPage() {
251
251
 
252
252
  return (
253
253
  <div className="flex flex-col min-h-screen">
254
- <TopBar title="orca-pulse · plans" subtitle="~/.orca/plans/" />
254
+ <TopBar title="kepler-pulse · plans" subtitle="~/.kepler/plans/" />
255
255
  <div className="p-4 md:p-6 space-y-5">
256
256
 
257
257
  {error && <p className="text-[#f87171] text-sm font-mono">Error: {String(error)}</p>}
@@ -289,7 +289,7 @@ export default function PlansPage() {
289
289
  <p className="text-[#d97706] text-2xl mb-3">📋</p>
290
290
  <p className="text-muted-foreground/60 text-sm font-mono">
291
291
  {plans.length === 0
292
- ? 'No plans found in ~/.orca/plans/'
292
+ ? 'No plans found in ~/.kepler/plans/'
293
293
  : 'No plans match your search.'}
294
294
  </p>
295
295
  </div>
@@ -101,7 +101,7 @@ export default function ProjectsPage() {
101
101
 
102
102
  {!isLoading && sorted.length === 0 && (
103
103
  <div className="text-center py-16 text-muted-foreground text-sm">
104
- {search ? 'No projects match your search.' : 'No projects found in ~/.orca/'}
104
+ {search ? 'No projects match your search.' : 'No projects found in ~/.kepler/'}
105
105
  </div>
106
106
  )}
107
107
  </div>
@@ -18,7 +18,7 @@ export default function SessionsPage() {
18
18
  return (
19
19
  <div className="flex flex-col min-h-screen">
20
20
  <TopBar
21
- title="Orca Pulse · Sessions"
21
+ title="Kepler Pulse · Sessions"
22
22
  subtitle={data ? `${data.total} total sessions` : 'loading...'}
23
23
  />
24
24
  <div className="p-6">
@@ -83,7 +83,7 @@ export default function SettingsPage() {
83
83
 
84
84
  return (
85
85
  <div className="flex flex-col min-h-screen">
86
- <TopBar title="orca-pulse · settings" subtitle="~/.orca/settings.json" />
86
+ <TopBar title="kepler-pulse · settings" subtitle="~/.kepler/settings.json" />
87
87
  <div className="p-4 md:p-6 space-y-6">
88
88
  {error && <p className="text-[#f87171] text-sm font-mono">Error: {String(error)}</p>}
89
89
  {isLoading && (
@@ -100,13 +100,13 @@ export default function SettingsPage() {
100
100
  <span className="text-primary text-2xl font-mono font-bold">
101
101
  {formatBytes(data.storageBytes)}
102
102
  </span>
103
- <span className="text-muted-foreground text-sm font-mono">used by ~/.orca/</span>
103
+ <span className="text-muted-foreground text-sm font-mono">used by ~/.kepler/</span>
104
104
  </div>
105
105
  </Section>
106
106
 
107
107
  <Section title="Settings">
108
108
  {Object.keys(data.settings).length === 0 ? (
109
- <p className="text-muted-foreground/60 text-sm font-mono">No settings found in ~/.orca/settings.json</p>
109
+ <p className="text-muted-foreground/60 text-sm font-mono">No settings found in ~/.kepler/settings.json</p>
110
110
  ) : (
111
111
  <div className="font-mono text-sm leading-relaxed overflow-x-auto">
112
112
  <JsonValue value={data.settings} />
@@ -139,7 +139,7 @@ export default function SettingsPage() {
139
139
 
140
140
  <Section title={`Skills (${data.skills.length})`}>
141
141
  {data.skills.length === 0 ? (
142
- <p className="text-muted-foreground/60 text-sm font-mono">No skills found in ~/.orca/skills/</p>
142
+ <p className="text-muted-foreground/60 text-sm font-mono">No skills found in ~/.kepler/skills/</p>
143
143
  ) : (
144
144
  <div className="grid gap-2">
145
145
  {data.skills.map(skill => (
@@ -126,7 +126,7 @@ export default function TodosPage() {
126
126
 
127
127
  return (
128
128
  <div className="flex flex-col min-h-screen">
129
- <TopBar title="Todos" subtitle="~/.orca/todos/" />
129
+ <TopBar title="Todos" subtitle="~/.kepler/todos/" />
130
130
  <div className="p-4 md:p-6 space-y-5">
131
131
 
132
132
  {error && (
@@ -192,7 +192,7 @@ export default function TodosPage() {
192
192
  <CircleCheck className="w-8 h-8 mx-auto mb-3 text-muted-foreground/40" />
193
193
  <p className="text-muted-foreground text-sm">
194
194
  {allItems.length === 0
195
- ? 'No todos found in ~/.orca/todos/'
195
+ ? 'No todos found in ~/.kepler/todos/'
196
196
  : 'No todos match your filter.'}
197
197
  </p>
198
198
  </div>
@@ -201,7 +201,7 @@ export default function ToolsPage() {
201
201
  {data.versions.length > 0 && (
202
202
  <Card>
203
203
  <CardHeader>
204
- <CardTitle>Orca Version History</CardTitle>
204
+ <CardTitle>Kepler Version History</CardTitle>
205
205
  <CardDescription>Versions seen across your sessions</CardDescription>
206
206
  </CardHeader>
207
207
  <CardContent>
package/pulse/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Orca Pulse — local analytics dashboard launcher.
4
- * Launches a Next.js dev server from ~/.orca-pulse/ cache directory.
3
+ * Kepler Pulse — local analytics dashboard launcher.
4
+ * Launches a Next.js dev server from ~/.kepler-pulse/ cache directory.
5
5
  */
6
6
 
7
7
  const { spawn, exec } = require('child_process')
@@ -11,9 +11,9 @@ const path = require('path')
11
11
  const fs = require('fs')
12
12
 
13
13
  const PKG_DIR = __dirname
14
- const CACHE_DIR = path.join(os.homedir(), '.orca-pulse')
14
+ const CACHE_DIR = path.join(os.homedir(), '.kepler-pulse')
15
15
 
16
- // ANSI helpers — Orca cyan palette
16
+ // ANSI helpers — Kepler cyan palette
17
17
  const C = '\x1b[36m' // cyan
18
18
  const C2 = '\x1b[96m' // bright cyan
19
19
  const DIM = '\x1b[2m'
@@ -22,20 +22,10 @@ const R = '\x1b[0m'
22
22
  const G = '\x1b[32m'
23
23
 
24
24
  function printBanner() {
25
- const art = [
26
- `${C}${B} ██████╗ ██████╗ ██████╗ █████╗ ██████╗ ██╗ ██╗██╗ ███████╗███████╗${R}`,
27
- `${C}${B}██╔═══██╗██╔══██╗██╔════╝██╔══██╗ ██╔══██╗██║ ██║██║ ██╔════╝██╔════╝${R}`,
28
- `${C2}${B}██║ ██║██████╔╝██║ ███████║ ██████╔╝██║ ██║██║ ███████╗█████╗ ${R}`,
29
- `${C2}${B}██║ ██║██╔══██╗██║ ██╔══██║ ██╔═══╝ ██║ ██║██║ ╚════██║██╔══╝ ${R}`,
30
- `${C}${B}╚██████╔╝██║ ██║╚██████╗██║ ██║ ██║ ╚██████╔╝███████╗███████║███████╗${R}`,
31
- `${C}${B} ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝${R}`,
32
- ]
33
-
34
- console.log()
35
- art.forEach((line) => console.log(' ' + line))
36
25
  console.log()
37
- const configDir = process.env.ORCA_CONFIG_DIR ?? path.join(os.homedir(), '.orca')
38
- console.log(` ${B}${C}Orca Pulse${R} ${DIM}— real-time analytics for your Orca sessions${R}`)
26
+ const configDir = process.env.KEPLER_CONFIG_DIR ?? path.join(os.homedir(), '.kepler')
27
+ console.log(` ${B}${C}K · E · P · L · E · R${R}`)
28
+ console.log(` ${B}${C2}Kepler Pulse${R} ${DIM}real-time agent analytics${R}`)
39
29
  console.log()
40
30
  console.log(` ${DIM}Data dir:${R} ${C2}${configDir}${R}`)
41
31
  console.log()
@@ -58,7 +48,7 @@ function openBrowser(url) {
58
48
  exec(cmd)
59
49
  }
60
50
 
61
- // Source dirs/files to mirror into ~/.orca-pulse/
51
+ // Source dirs/files to mirror into ~/.kepler-pulse/
62
52
  const SRC_DIRS = ['app', 'components', 'lib', 'types', 'public']
63
53
  const SRC_FILES = ['next.config.ts', 'tsconfig.json', 'postcss.config.mjs', 'components.json']
64
54
 
@@ -78,7 +68,7 @@ function syncSource(pkg) {
78
68
  }
79
69
  // Write a minimal package.json with only runtime dependencies
80
70
  fs.writeFileSync(path.join(CACHE_DIR, 'package.json'), JSON.stringify({
81
- name: 'orca-pulse-runtime',
71
+ name: 'kepler-pulse-runtime',
82
72
  version: pkg.version,
83
73
  dependencies: pkg.dependencies,
84
74
  }, null, 2))
@@ -89,8 +79,8 @@ async function main() {
89
79
 
90
80
  const pkg = require(path.join(PKG_DIR, 'package.json'))
91
81
 
92
- // Check whether ~/.orca-pulse/ is up-to-date for this version
93
- const versionFile = path.join(CACHE_DIR, '.orca-pulse-version')
82
+ // Check whether ~/.kepler-pulse/ is up-to-date for this version
83
+ const versionFile = path.join(CACHE_DIR, '.kepler-pulse-version')
94
84
  const cachedVersion = fs.existsSync(versionFile)
95
85
  ? fs.readFileSync(versionFile, 'utf8').trim()
96
86
  : null
@@ -120,13 +110,13 @@ async function main() {
120
110
  const port = await findFreePort(3000)
121
111
  const url = `http://localhost:${port}`
122
112
 
123
- // Pass ORCA_CONFIG_DIR to the Next.js process so it reads from ~/.orca/
124
- const orcaDir = process.env.ORCA_CONFIG_DIR ?? path.join(os.homedir(), '.orca')
113
+ // Pass KEPLER_CONFIG_DIR to the Next.js process so it reads from ~/.kepler/
114
+ const keplerDir = process.env.KEPLER_CONFIG_DIR ?? path.join(os.homedir(), '.kepler')
125
115
  const env = {
126
116
  ...process.env,
127
117
  PORT: String(port),
128
- ORCA_CONFIG_DIR: orcaDir,
129
- CLAUDE_CONFIG_DIR: orcaDir,
118
+ KEPLER_CONFIG_DIR: keplerDir,
119
+ CLAUDE_CONFIG_DIR: keplerDir,
130
120
  }
131
121
 
132
122
  console.log(` ${DIM}Starting server on${R} ${C2}${B}${url}${R}\n`)
@@ -101,7 +101,7 @@ function SidebarContents({
101
101
  <span
102
102
  className="dark:[text-shadow:0_1px_0_#0e4f5c,0_2px_0_#083344,0_3px_6px_rgba(0,0,0,0.35)] [text-shadow:0_1px_0_rgba(255,255,255,0.4)]"
103
103
  >
104
- Orca Pulse
104
+ Kepler Pulse
105
105
  </span>
106
106
  </span>
107
107
  )}
@@ -140,7 +140,7 @@ function SidebarContents({
140
140
  )}>
141
141
  {!collapsed && (
142
142
  <span className="text-xs text-sidebar-foreground/50">
143
- Orca Pulse
143
+ Kepler Pulse
144
144
  </span>
145
145
  )}
146
146
  <button
@@ -19,7 +19,7 @@ function restAfterAction(s: string, idx: number, needleLen: number): string | un
19
19
  }
20
20
 
21
21
  /**
22
- * Best-effort parse of common Orca / tool sandbox result strings.
22
+ * Best-effort parse of common Kepler / tool sandbox result strings.
23
23
  */
24
24
  export function parseToolResultMessage(raw: string): ParsedToolResult {
25
25
  const s = raw.trim()
@@ -32,7 +32,7 @@ export async function resolveProjectPath(slug: string): Promise<string> {
32
32
  return slugToPath(slug)
33
33
  }
34
34
 
35
- const CLAUDE_DIR = process.env.ORCA_CONFIG_DIR ?? process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), '.orca')
35
+ const CLAUDE_DIR = process.env.KEPLER_CONFIG_DIR ?? process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), '.kepler')
36
36
 
37
37
  export function claudePath(...segments: string[]): string {
38
38
  return path.join(CLAUDE_DIR, ...segments)
@@ -10,7 +10,7 @@ export function slugToPath(slug: string): string {
10
10
  }
11
11
 
12
12
  /**
13
- * Encode a filesystem path to the slug format used by Orca.
13
+ * Encode a filesystem path to the slug format used by Kepler.
14
14
  */
15
15
  export function pathToSlug(path: string): string {
16
16
  return path.replace(/\//g, '-')