Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ JIT memory management framework for Claude Code -- persistent context across ses
## Key Paths
| Path | Purpose |
|------|---------|
| templates/commands/ | Slash command templates (22 files: 16 commands + 5 shortcuts + test-tools) |
| templates/commands/ | Slash command templates (22 files: 17 commands + 5 shortcuts) |
| templates/hooks/ | Hook script templates (4 hooks) |
| templates/engrams/ | Engram templates + examples |
| templates/rules/ | Path-scoped rule templates |
Expand All @@ -24,9 +24,9 @@ JIT memory management framework for Claude Code -- persistent context across ses
| install.sh / install.ps1 | Installation scripts (workspace/project/user modes) |

## Key Components
- 16 commands: help, session, sessions, divergent, learn, health, gitstatus, diff, enterprise, audit, bundle, onboard, orchestrate, conversation-log, test-tools, schedule
- 17 commands: help, session, sessions, divergent, learn, health, gitstatus, diff, enterprise, audit, bundle, onboard, orchestrate, conversation-log, test-tools, schedule, verify
- 5 shortcuts: save, load, pulse, status, dashboard (delegate to session/sessions based on preference)
- 4 hooks: PreCompact save, SessionStart recovery, Branch protection, SessionEnd auto-save
- 10 hook scripts / 9 hook events: PreCompact save, SessionStart (write-id, post-clear, recovery, scheduled-agents), PreToolUse (branch-protection, pre-agent-register), PostToolUse (heartbeat, post-agent-complete), SessionEnd auto-save
- Engram system: per-project deep context files (50-150 lines each)
- Bundle system: domain knowledge files loaded on-demand via routing weights
- Context manifest: bundle index and routing weight definitions
Expand Down
32 changes: 31 additions & 1 deletion docs/commands-reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Commands Reference

JitNeuro ships 15 commands and 5 shortcuts organized into 7 categories. All commands are read-only unless explicitly noted.
JitNeuro ships 17 commands and 5 shortcuts organized into 7 categories. All commands are read-only unless explicitly noted.

---

Expand Down Expand Up @@ -283,6 +283,36 @@ Examples:

---

## Setup and Verification

### /help
Display JitNeuro quick reference. Zero token cost -- reads and displays a static help file verbatim.

- **Arguments:** None
- **Source:** Reads `.claude/help.md` from the install root; falls back to the jitneuro templates `help.md`

Example:
```
/help
```
Displays the quick-reference card for all commands, shortcuts, and common workflows. Offers to open the file in the editor.

---

### /verify
Post-install health check. Reads the install root and validates all 9 framework components. Read-only -- does not modify any files.

- **Arguments:** None
- **Checks:** install version, commands directory, hook scripts, hooks config, hook paths, hook event names, bundles, engrams, context manifest

Example:
```
/verify
```
Returns a GREEN/YELLOW/RED table for each component with recommended remediation steps for any failures.

---

## Shortcuts

These delegate to `/session` or `/sessions` based on the `shortcut_scope` preference in `.claude/session-state/.preferences`. Default scope: `session` (current).
Expand Down
14 changes: 7 additions & 7 deletions templates/commands/verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ When invoked as `/verify`:
| # | Component | Check | GREEN | YELLOW | RED |
|---|-----------|-------|-------|--------|-----|
| 1 | Install version | Read version from .claude/jitneuro.json | Version found | Pre-versioned install (no jitneuro.json) | Not installed |
| 2 | Commands | Scan .claude/commands/*.md | All 15 commands present | Some commands missing | commands/ dir missing |
| 3 | Hook scripts | Check .claude/hooks/*.sh exist | All 5 scripts present | Some missing | hooks/ dir missing |
| 4 | Hooks config | Read settings.local.json, verify hooks section | All 4 hook events configured | Some events missing | No hooks config |
| 2 | Commands | Scan .claude/commands/*.md | All 17 commands present | Some commands missing | commands/ dir missing |
| 3 | Hook scripts | Check .claude/hooks/*.sh exist | All 10 scripts present | Some missing | hooks/ dir missing |
| 4 | Hooks config | Read settings.local.json, verify hooks section | All 9 hook events configured | Some events missing | No hooks config |
| 5 | Hook paths | Each hook command path in settings.local.json points to existing file | All paths valid | -- | Script file not found |
| 6 | Hook events | Event names match Claude Code events (PreCompact, SessionStart, PreToolUse, SessionEnd) | All valid | Unknown event name | -- |
| 7 | Bundles | Check .claude/bundles/ has files | Has bundles | Only example.md | Empty |
Expand All @@ -42,9 +42,9 @@ When invoked as `/verify`:
Install: .claude/ at [path relative to workspace]

[1] Install version GREEN v0.1.2
[2] Commands GREEN 15/15 installed
[3] Hook scripts GREEN 5/5 present
[4] Hooks config GREEN 4 event types configured (SessionStart has 2 hooks)
[2] Commands GREEN 17/17 installed
[3] Hook scripts GREEN 10/10 present
[4] Hooks config GREEN 9 hook events configured (SessionStart has 4 hooks)
[5] Hook paths GREEN All paths valid
[6] Hook events GREEN All event names valid
[7] Bundles GREEN 3 bundles
Expand Down Expand Up @@ -73,5 +73,5 @@ When invoked as `/verify`:
## Important
- Use relative paths in output (not full system paths with username)
- This command is READ-ONLY -- never modify files
- If settings.local.json has extra hooks beyond JitNeuro's 5 scripts (4 event types), that's fine -- only check for JitNeuro's hooks
- If settings.local.json has extra hooks beyond JitNeuro's 10 scripts (9 hook events), that's fine -- only check for JitNeuro's hooks
- Do not fail on extras, only on missing components
55 changes: 47 additions & 8 deletions templates/dashboard/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const http = require('http');
const fs = require('fs');
const path = require('path');
const os = require('os');
const { exec } = require('child_process');
const { spawn } = require('child_process');

// -- Configuration --

Expand Down Expand Up @@ -306,7 +306,12 @@ function getSessions() {
}

function getSessionContent(name) {
var filePath = path.join(SESSIONS_DIR, name + '.md');
// Security: reject names with path separators or traversal sequences
if (!name || /[/\\]/.test(name) || name.indexOf('..') !== -1) return null;
var filePath = path.resolve(SESSIONS_DIR, name + '.md');
// Security: ensure resolved path stays within SESSIONS_DIR
var safeDir = path.resolve(SESSIONS_DIR) + path.sep;
if (filePath.indexOf(safeDir) !== 0) return null;
try { return fs.readFileSync(filePath, 'utf8'); }
catch (e) { return null; }
}
Expand Down Expand Up @@ -341,16 +346,30 @@ function readBody(req, cb) {
// -- Browser auto-open --

function openBrowser(url) {
var cmd = process.platform === 'win32' ? 'cmd /c start "" "' + url + '"'
: process.platform === 'darwin' ? 'open "' + url + '"'
: 'xdg-open "' + url + '"';
exec(cmd, function() {});
// Security: use spawn with arg array to avoid shell injection -- URL is controlled
// but defensive practice is to never pass untrusted values through a shell string
var args;
if (process.platform === 'win32') {
args = ['cmd', ['/c', 'start', '', url], { shell: false }];
} else if (process.platform === 'darwin') {
args = ['open', [url], { shell: false }];
} else {
args = ['xdg-open', [url], { shell: false }];
}
try { spawn(args[0], args[1], Object.assign({ detached: true, stdio: 'ignore' }, args[2])).unref(); }
catch (e) {}
}

// -- HTTP server --

var LOCALHOST_ORIGINS = ['http://localhost:' + PORT, 'http://127.0.0.1:' + PORT];

var server = http.createServer(function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
// Security: restrict CORS to localhost origins only -- dashboard is a local tool
var origin = req.headers.origin || '';
if (LOCALHOST_ORIGINS.indexOf(origin) !== -1) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

Expand Down Expand Up @@ -382,6 +401,25 @@ var server = http.createServer(function(req, res) {
readBody(req, function(body) {
try {
var data = JSON.parse(body);
// Security: validate schema -- only allow known top-level keys with expected types
if (typeof data !== 'object' || data === null || Array.isArray(data)) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Settings must be a JSON object');
return;
}
var allowed = ['dashboard'];
for (var k in data) {
if (allowed.indexOf(k) === -1) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Unknown settings key: ' + k);
return;
}
}
if (data.dashboard !== undefined && (typeof data.dashboard !== 'object' || Array.isArray(data.dashboard))) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('settings.dashboard must be an object');
return;
}
if (saveSettings(data)) {
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(JSON.stringify(getSettings()));
Expand Down Expand Up @@ -545,7 +583,8 @@ var server = http.createServer(function(req, res) {
res.end('Not found');
});

server.listen(PORT, function() {
// Security: bind to loopback only -- dashboard is a local developer tool
server.listen(PORT, '127.0.0.1', function() {
var url = 'http://localhost:' + PORT;
console.log('');
console.log(' JitNeuro Agent Dashboard');
Expand Down
Loading