@nemus-cli/nemus 0.2.4 → 0.2.5
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/CHANGELOG.md +24 -1
- package/dist/cli/ai-prompt.js +1 -1
- package/dist/cli/tui.js +1 -1
- package/dist/commands/configure.js +1 -1
- package/dist/commands/ghq-status.js +1 -1
- package/dist/mcp/install.js +12 -12
- package/dist/mcp/server.js +2 -2
- package/dist/pi-extensions/permission-sync.ts.template +1 -1
- package/dist/pi-extensions/permissions-gate.ts.template +1 -1
- package/dist/pi-extensions/pr-fix-trigger.ts.template +2 -2
- package/dist/pi-extensions/review-reminder.ts.template +1 -1
- package/dist/pi-extensions/workspace-input-status.ts.template +3 -3
- package/dist/scripts/workspace-table.py +3 -3
- package/dist/utils/agent-state.js +1 -1
- package/dist/utils/bug-report.js +3 -3
- package/dist/utils/claude-integration.js +8 -8
- package/dist/utils/permission-sync.js +10 -10
- package/dist/utils/pi-extensions.js +5 -5
- package/package.json +1 -1
- package/skills/analyze-deps.md +0 -3
- package/skills/branch-create.md +0 -3
- package/skills/create-workspace.md +0 -11
- package/skills/delete-workspace.md +0 -3
- package/skills/list-org-repos.md +0 -6
- package/skills/list-suites.md +0 -4
- package/skills/list-workspaces.md +0 -7
- package/skills/nemus/SKILL.md +110 -0
- package/skills/{workspace-manager → nemus}/references/ai-prompt.md +0 -6
- package/skills/{workspace-manager → nemus}/references/analyze-deps.md +0 -11
- package/skills/{workspace-manager → nemus}/references/archive-workspace.md +0 -9
- package/skills/{workspace-manager → nemus}/references/branch-create.md +0 -3
- package/skills/{workspace-manager → nemus}/references/branch-merge.md +0 -4
- package/skills/{workspace-manager → nemus}/references/branch-rebase.md +0 -4
- package/skills/{workspace-manager → nemus}/references/cache-clear.md +0 -3
- package/skills/{workspace-manager → nemus}/references/cache-info.md +0 -3
- package/skills/{workspace-manager → nemus}/references/configure-claude.md +0 -3
- package/skills/{workspace-manager → nemus}/references/configure.md +1 -4
- package/skills/{workspace-manager → nemus}/references/create-workspace.md +0 -4
- package/skills/{workspace-manager → nemus}/references/dashboard.md +0 -4
- package/skills/{workspace-manager → nemus}/references/delete-workspace.md +0 -4
- package/skills/{workspace-manager → nemus}/references/generate-docs.md +0 -9
- package/skills/{workspace-manager → nemus}/references/ghq-status.md +0 -5
- package/skills/{workspace-manager → nemus}/references/go.md +0 -4
- package/skills/{workspace-manager → nemus}/references/history.md +1 -5
- package/skills/{workspace-manager → nemus}/references/list-org-repos.md +0 -4
- package/skills/{workspace-manager → nemus}/references/list-suites.md +0 -4
- package/skills/{workspace-manager → nemus}/references/list-workspaces.md +1 -5
- package/skills/{workspace-manager → nemus}/references/mcp.md +3 -8
- package/skills/{workspace-manager → nemus}/references/remove-repo.md +0 -3
- package/skills/{workspace-manager → nemus}/references/run-command.md +1 -5
- package/skills/{workspace-manager → nemus}/references/search-repos.md +0 -4
- package/skills/{workspace-manager → nemus}/references/sessions.md +0 -5
- package/skills/{workspace-manager → nemus}/references/suite-create.md +0 -4
- package/skills/{workspace-manager → nemus}/references/suite-delete.md +0 -3
- package/skills/{workspace-manager → nemus}/references/suite-export.md +0 -4
- package/skills/{workspace-manager → nemus}/references/suite-import.md +0 -4
- package/skills/{workspace-manager → nemus}/references/suite-use.md +0 -4
- package/skills/{workspace-manager → nemus}/references/switch-branch.md +0 -4
- package/skills/{workspace-manager → nemus}/references/update-cache.md +0 -3
- package/skills/{workspace-manager → nemus}/references/update-workspace.md +0 -4
- package/skills/{workspace-manager → nemus}/references/workspace-cleanup.md +0 -4
- package/skills/{workspace-manager → nemus}/references/workspace-diff.md +0 -3
- package/skills/{workspace-manager → nemus}/references/workspace-doctor.md +0 -4
- package/skills/{workspace-manager → nemus}/references/workspace-info.md +0 -3
- package/skills/{workspace-manager → nemus}/references/workspace-status.md +1 -13
- package/skills/{workspace-manager → nemus}/references/workspace-sync.md +0 -4
- package/skills/refresh-workspace-docs.md +6 -78
- package/skills/run-command.md +0 -3
- package/skills/save-context.md +1 -13
- package/skills/search-repos.md +0 -6
- package/skills/snapshot-list.md +0 -3
- package/skills/snapshot-save.md +1 -1
- package/skills/switch-branch.md +0 -3
- package/skills/update-workspace.md +0 -11
- package/skills/workspace-cleanup.md +0 -3
- package/skills/workspace-diff.md +0 -3
- package/skills/workspace-doctor.md +0 -3
- package/skills/workspace-info.md +0 -17
- package/skills/workspace-status.md +0 -6
- package/skills/workspace-sync.md +0 -3
- package/src/cli/ai-prompt.ts +1 -1
- package/src/cli/tui.tsx +1 -1
- package/src/commands/configure.ts +1 -1
- package/src/commands/ghq-status.ts +1 -1
- package/src/mcp/install.ts +12 -12
- package/src/mcp/server.ts +2 -2
- package/src/pi-extensions/permission-sync.ts.template +1 -1
- package/src/pi-extensions/permissions-gate.ts.template +1 -1
- package/src/pi-extensions/pr-fix-trigger.ts.template +2 -2
- package/src/pi-extensions/review-reminder.ts.template +1 -1
- package/src/pi-extensions/workspace-input-status.ts.template +3 -3
- package/src/scripts/workspace-table.py +3 -3
- package/src/utils/agent-state.ts +1 -1
- package/src/utils/bug-report.ts +3 -3
- package/src/utils/claude-integration.ts +8 -8
- package/src/utils/permission-sync.test.ts +4 -4
- package/src/utils/permission-sync.ts +10 -10
- package/src/utils/pi-extensions.test.ts +1 -1
- package/src/utils/pi-extensions.ts +5 -5
- package/src/utils/repo-resolver.test.ts +1 -1
- package/skills/workspace-manager/SKILL.md +0 -201
package/skills/run-command.md
CHANGED
package/skills/save-context.md
CHANGED
|
@@ -16,7 +16,7 @@ Save a progress summary or important context to the workspace. This persists in
|
|
|
16
16
|
|
|
17
17
|
## Using the MCP Tool (Claude Code)
|
|
18
18
|
|
|
19
|
-
Call `
|
|
19
|
+
Call `mcp__nemus__save-context` with:
|
|
20
20
|
- `workspace` (string): the workspace name
|
|
21
21
|
- `content` (string): markdown content to save
|
|
22
22
|
- `append` (boolean, optional): true to append, false to replace (default: false)
|
|
@@ -49,20 +49,8 @@ Good context summaries include:
|
|
|
49
49
|
## Example
|
|
50
50
|
|
|
51
51
|
```markdown
|
|
52
|
-
## Progress
|
|
53
|
-
|
|
54
|
-
- Refactored auth service to use JWT tokens (PR #42 merged)
|
|
55
|
-
- Updated partnerships-api to call new auth endpoints
|
|
56
|
-
- Fixed rate limiting bug in payment-gateway
|
|
57
|
-
|
|
58
52
|
## Current State
|
|
59
53
|
|
|
60
54
|
All services passing CI. Auth migration is complete for internal services.
|
|
61
55
|
External API consumers still use legacy tokens (tracked in JIRA PAY-123).
|
|
62
56
|
|
|
63
|
-
## Next Steps
|
|
64
|
-
|
|
65
|
-
1. Migrate external consumers to JWT (need coordination with partners team)
|
|
66
|
-
2. Add monitoring dashboard for token refresh failures
|
|
67
|
-
3. Remove legacy token support after 30-day deprecation window
|
|
68
|
-
```
|
package/skills/search-repos.md
CHANGED
|
@@ -23,9 +23,3 @@ nemus cache refresh
|
|
|
23
23
|
|
|
24
24
|
Then search again.
|
|
25
25
|
|
|
26
|
-
## Presenting Results
|
|
27
|
-
|
|
28
|
-
Show matching repos with their names and descriptions. If the user wants to add repos to a workspace, suggest:
|
|
29
|
-
```bash
|
|
30
|
-
nemus update --workspace <name> --repos <repo1,repo2> --yes
|
|
31
|
-
```
|
package/skills/snapshot-list.md
CHANGED
package/skills/snapshot-save.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Save a snapshot of the current workspace state
|
|
|
5
5
|
|
|
6
6
|
# Snapshot Save
|
|
7
7
|
|
|
8
|
-
Snapshots are automatically saved by
|
|
8
|
+
Snapshots are automatically saved by Nemus operations (create, update, delete, etc.). There is no separate snapshot command — the history command shows past operations:
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
nemus history
|
package/skills/switch-branch.md
CHANGED
|
@@ -53,14 +53,3 @@ nemus update --workspace <name> --repos casper:cas-101 --yes # -> casper-cas-1
|
|
|
53
53
|
Suffix = letters, numbers, hyphens, underscores. Each instance is tracked
|
|
54
54
|
independently by `nemus status`/`nemus sync`.
|
|
55
55
|
|
|
56
|
-
## Presenting Results
|
|
57
|
-
|
|
58
|
-
The command output shows which repos were added and which were skipped. Report:
|
|
59
|
-
- Successfully added repos
|
|
60
|
-
- Skipped repos (already exist in workspace) - this is not an error
|
|
61
|
-
- Any failures with their error reason
|
|
62
|
-
|
|
63
|
-
## Suggested Follow-ups
|
|
64
|
-
|
|
65
|
-
- `nemus status <workspace>` to verify the new repos
|
|
66
|
-
- `nemus sync <workspace>` to pull latest on all repos
|
package/skills/workspace-diff.md
CHANGED
package/skills/workspace-info.md
CHANGED
|
@@ -26,20 +26,3 @@ The workspace path can be found by checking the current directory or using:
|
|
|
26
26
|
nemus status <workspace-name>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
## Presenting Results
|
|
30
|
-
|
|
31
|
-
The JSON contains workspace metadata. Present clearly:
|
|
32
|
-
|
|
33
|
-
- **Name** and **creation date**
|
|
34
|
-
- **Disk path** where the workspace lives
|
|
35
|
-
- **Repositories** - list each with:
|
|
36
|
-
- Directory name (may differ from repo name if a suffix was used)
|
|
37
|
-
- Clone URL
|
|
38
|
-
- Status (success/failed from creation)
|
|
39
|
-
- **Tags** and any custom metadata if present
|
|
40
|
-
|
|
41
|
-
## Suggested Follow-ups
|
|
42
|
-
|
|
43
|
-
- `nemus status <workspace>` to see current git status of each repo
|
|
44
|
-
- `nemus update --workspace <name> --repos <repos>` to add more repos
|
|
45
|
-
- `nemus doctor <workspace>` to check workspace health
|
|
@@ -18,9 +18,3 @@ Or for the current workspace:
|
|
|
18
18
|
nemus status
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
## Presenting Results
|
|
22
|
-
|
|
23
|
-
The command shows per-repo git status (branch, uncommitted changes, ahead/behind). Report:
|
|
24
|
-
- Which repos have uncommitted changes
|
|
25
|
-
- Which repos are on non-default branches
|
|
26
|
-
- Any repos that are ahead/behind remote
|
package/skills/workspace-sync.md
CHANGED
package/src/cli/ai-prompt.ts
CHANGED
|
@@ -186,7 +186,7 @@ function throwExtractionError(
|
|
|
186
186
|
const secs = Math.round(EXTRACTION_TIMEOUT_MS / 1000);
|
|
187
187
|
let msg =
|
|
188
188
|
`${cmd} did not respond within ${secs}s while parsing your request.\n` +
|
|
189
|
-
` This is usually a transient model/provider stall, not a
|
|
189
|
+
` This is usually a transient model/provider stall, not a nemus bug.\n` +
|
|
190
190
|
` • Verify the agent itself responds quickly: time ${testCmd}\n` +
|
|
191
191
|
` • If it's slow, your default model may be heavy (e.g. Opus) or the provider\n` +
|
|
192
192
|
` may be rate-limiting/refreshing credentials. Retry, or switch to a faster model.\n` +
|
package/src/cli/tui.tsx
CHANGED
|
@@ -10,7 +10,7 @@ export const main = async () => {
|
|
|
10
10
|
try {
|
|
11
11
|
logInfo('Interactive TUI mode');
|
|
12
12
|
console.log(colorize('\n╔══════════════════════════════════════════╗', 'cyan'));
|
|
13
|
-
console.log(colorize('║
|
|
13
|
+
console.log(colorize('║ Nemus - Interactive UI ║', 'cyan'));
|
|
14
14
|
console.log(colorize('╚══════════════════════════════════════════╝\n', 'cyan'));
|
|
15
15
|
|
|
16
16
|
const workspaces = await listWorkspaces();
|
|
@@ -20,7 +20,7 @@ export function registerConfigureCommand(parent: Command) {
|
|
|
20
20
|
|
|
21
21
|
async function handleConfigure() {
|
|
22
22
|
console.log('\n' + '='.repeat(60));
|
|
23
|
-
console.log(colorize('
|
|
23
|
+
console.log(colorize('Nemus Configuration', 'bright'));
|
|
24
24
|
console.log('='.repeat(60) + '\n');
|
|
25
25
|
|
|
26
26
|
const current = getUserConfig();
|
|
@@ -56,7 +56,7 @@ async function handleGhqStatus() {
|
|
|
56
56
|
if (showInfo) { displayGhqInfo(); }
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
console.log(colorize('
|
|
59
|
+
console.log(colorize('Nemus Behavior:', 'cyan'));
|
|
60
60
|
console.log(' • Auto-detects ghq installation');
|
|
61
61
|
console.log(' • Uses ghq when available');
|
|
62
62
|
console.log(' • Falls back to git clone if needed');
|
package/src/mcp/install.ts
CHANGED
|
@@ -114,11 +114,11 @@ function installHooksAndSkills() {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
// Install
|
|
117
|
+
// Install nemus skills (MCP + CLI command skills) — always for all active agents
|
|
118
118
|
try {
|
|
119
119
|
installWorkspaceSkills();
|
|
120
120
|
} catch (error) {
|
|
121
|
-
logError('Failed to install
|
|
121
|
+
logError('Failed to install nemus skills');
|
|
122
122
|
if (error instanceof Error) {
|
|
123
123
|
logError(error.message);
|
|
124
124
|
}
|
|
@@ -143,7 +143,7 @@ function installHooksAndSkills() {
|
|
|
143
143
|
|
|
144
144
|
/**
|
|
145
145
|
* Backfill .mcp.json for all existing workspaces that don't have the
|
|
146
|
-
*
|
|
146
|
+
* nemus entry yet.
|
|
147
147
|
*/
|
|
148
148
|
async function backfillMcpJson() {
|
|
149
149
|
const { installMcp } = getUserConfig();
|
|
@@ -265,11 +265,11 @@ async function install() {
|
|
|
265
265
|
|
|
266
266
|
try {
|
|
267
267
|
execSync(
|
|
268
|
-
`claude mcp add
|
|
268
|
+
`claude mcp add nemus -s user -- node "${serverPath}"`,
|
|
269
269
|
{ stdio: 'pipe' }
|
|
270
270
|
);
|
|
271
271
|
logSuccess('MCP server registered globally with Claude Code');
|
|
272
|
-
console.log('\nYou can now use
|
|
272
|
+
console.log('\nYou can now use nemus tools in any Claude Code session.');
|
|
273
273
|
console.log('Try asking: "list my workspaces" or "what\'s the status of my-workspace"');
|
|
274
274
|
} catch (error) {
|
|
275
275
|
const stderr = error instanceof Error && 'stderr' in error
|
|
@@ -341,12 +341,12 @@ async function upgrade() {
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
function uninstall() {
|
|
344
|
-
// Remove
|
|
344
|
+
// Remove nemus skills (from all agent directories)
|
|
345
345
|
try {
|
|
346
346
|
uninstallWorkspaceSkills();
|
|
347
347
|
logSuccess('Workspace-manager skills removed from all agents');
|
|
348
348
|
} catch (error) {
|
|
349
|
-
logError('Failed to remove
|
|
349
|
+
logError('Failed to remove nemus skills');
|
|
350
350
|
if (error instanceof Error) {
|
|
351
351
|
logError(error.message);
|
|
352
352
|
}
|
|
@@ -384,7 +384,7 @@ function uninstall() {
|
|
|
384
384
|
// Unregister MCP from Claude (if available)
|
|
385
385
|
if (isAgentCliAvailable('claude')) {
|
|
386
386
|
try {
|
|
387
|
-
execSync('claude mcp remove
|
|
387
|
+
execSync('claude mcp remove nemus -s user', { stdio: 'inherit' });
|
|
388
388
|
logSuccess('MCP server unregistered from Claude Code');
|
|
389
389
|
} catch (error) {
|
|
390
390
|
logError('Failed to unregister MCP server');
|
|
@@ -427,10 +427,10 @@ function status() {
|
|
|
427
427
|
if (agent.supportsMcp) {
|
|
428
428
|
try {
|
|
429
429
|
const output = execSync('claude mcp list', { encoding: 'utf-8' });
|
|
430
|
-
const isRegistered = output.includes('
|
|
430
|
+
const isRegistered = output.includes('nemus');
|
|
431
431
|
if (isRegistered) {
|
|
432
432
|
logSuccess(' MCP server registered');
|
|
433
|
-
const lines = output.split('\n').filter(l => l.includes('
|
|
433
|
+
const lines = output.split('\n').filter(l => l.includes('nemus'));
|
|
434
434
|
if (lines.length > 0) {
|
|
435
435
|
console.log(` ${lines[0].trim()}`);
|
|
436
436
|
}
|
|
@@ -473,7 +473,7 @@ function syncPermissions() {
|
|
|
473
473
|
}
|
|
474
474
|
|
|
475
475
|
function updateSkills() {
|
|
476
|
-
logInfo('Updating
|
|
476
|
+
logInfo('Updating nemus skills...');
|
|
477
477
|
try {
|
|
478
478
|
installWorkspaceSkills();
|
|
479
479
|
} catch (error) {
|
|
@@ -512,7 +512,7 @@ export async function main(subCommandArg?: string) {
|
|
|
512
512
|
MCP Integration
|
|
513
513
|
|
|
514
514
|
Usage:
|
|
515
|
-
w mcp install Register
|
|
515
|
+
w mcp install Register nemus MCP server with Claude Code
|
|
516
516
|
w mcp uninstall Unregister the MCP server
|
|
517
517
|
w mcp upgrade Update hooks and skills without re-registering the MCP server
|
|
518
518
|
w mcp update-skills Update only the Claude Code skills (faster than full upgrade)
|
package/src/mcp/server.ts
CHANGED
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
import { getPackageVersion } from '../utils/config';
|
|
47
47
|
|
|
48
48
|
const server = new McpServer({
|
|
49
|
-
name: '
|
|
49
|
+
name: 'nemus',
|
|
50
50
|
version: getPackageVersion(),
|
|
51
51
|
});
|
|
52
52
|
|
|
@@ -570,7 +570,7 @@ server.tool(
|
|
|
570
570
|
async function main() {
|
|
571
571
|
const transport = new StdioServerTransport();
|
|
572
572
|
await server.connect(transport);
|
|
573
|
-
process.stderr.write('
|
|
573
|
+
process.stderr.write('nemus MCP server started\n');
|
|
574
574
|
}
|
|
575
575
|
|
|
576
576
|
main().catch((error) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pi Permission Sync Extension (auto-generated by
|
|
2
|
+
* Pi Permission Sync Extension (auto-generated by nemus)
|
|
3
3
|
*
|
|
4
4
|
* Equivalent of Claude Code's sync-permissions.sh Stop hook.
|
|
5
5
|
* Syncs project-level permissions to global settings on session shutdown.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pi PR-Fix Trigger Extension (auto-generated by
|
|
2
|
+
* Pi PR-Fix Trigger Extension (auto-generated by nemus)
|
|
3
3
|
*
|
|
4
4
|
* Equivalent of Claude Code's check-pr-fix-trigger.sh PostToolUse hook.
|
|
5
5
|
* Detects `gh pr create` in bash tool results, extracts the PR URL,
|
|
6
6
|
* and injects a directive to monitor CI and address review comments.
|
|
7
7
|
*
|
|
8
|
-
* @managed
|
|
8
|
+
* @managed nemus
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pi Review Reminder Extension (auto-generated by
|
|
2
|
+
* Pi Review Reminder Extension (auto-generated by nemus)
|
|
3
3
|
*
|
|
4
4
|
* Equivalent of Claude Code's check-review-reminder.sh SessionStart hook.
|
|
5
5
|
* Reminds user to review global permissions periodically.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Workspace input status — Claude-Code-style layout (auto-generated by
|
|
2
|
+
* Workspace input status — Claude-Code-style layout (auto-generated by nemus)
|
|
3
3
|
*
|
|
4
4
|
* Layout (matching the Claude Code reference):
|
|
5
5
|
*
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* ⠋ ✦ sonnet-4-6 ⚡ high 📂 ws:foo (3) 🧠 24k/200k 34% 💰 $0.42 ⏱ 2m 5s
|
|
10
10
|
*
|
|
11
11
|
* REPO BRANCH PR DIRTY
|
|
12
|
-
*
|
|
13
|
-
* ▸
|
|
12
|
+
* nemus-fix-… feat/oauth #41 open ✓
|
|
13
|
+
* ▸ nemus-security security/x #45 draft *2
|
|
14
14
|
*
|
|
15
15
|
* [pi's default footer renders below — untouched]
|
|
16
16
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
workspace-table.py —
|
|
4
|
-
(auto-generated by
|
|
3
|
+
workspace-table.py — Nemus status-line extension for Claude Code
|
|
4
|
+
(auto-generated by nemus)
|
|
5
5
|
|
|
6
6
|
Outputs ONLY the workspace repo table (branch · PR · CI · dirty state).
|
|
7
7
|
Claude Code already renders model / cost / context itself, so this script
|
|
@@ -10,7 +10,7 @@ adds only what it doesn't show.
|
|
|
10
10
|
Configure in ~/.claude/settings.json:
|
|
11
11
|
"statusLine": {
|
|
12
12
|
"type": "command",
|
|
13
|
-
"command": "~/.
|
|
13
|
+
"command": "~/.nemus-table.py",
|
|
14
14
|
"padding": 0
|
|
15
15
|
}
|
|
16
16
|
|
package/src/utils/agent-state.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as path from 'path';
|
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import { AgentState, DASHBOARD_DEFAULTS } from '../types/dashboard';
|
|
5
5
|
|
|
6
|
-
export const AGENTS_STATE_DIR = path.join(os.homedir(), '.
|
|
6
|
+
export const AGENTS_STATE_DIR = path.join(os.homedir(), '.nemus', 'agents');
|
|
7
7
|
|
|
8
8
|
export function ensureStateDir(): void {
|
|
9
9
|
fs.mkdirSync(AGENTS_STATE_DIR, { recursive: true });
|
package/src/utils/bug-report.ts
CHANGED
|
@@ -165,7 +165,7 @@ export function buildIssueBody(err: CapturedError, env: BugReportEnv): string {
|
|
|
165
165
|
const sig = errorSignature(err.message, err.stack);
|
|
166
166
|
const stack = err.stack ? sanitize(err.stack).slice(0, 4000) : '(no stack captured)';
|
|
167
167
|
return [
|
|
168
|
-
`**Auto-reported by
|
|
168
|
+
`**Auto-reported by nemus.**`,
|
|
169
169
|
``,
|
|
170
170
|
`**Signature:** \`${sig}\``,
|
|
171
171
|
`**Command:** \`${sanitize(err.command)}\``,
|
|
@@ -184,7 +184,7 @@ export function buildIssueBody(err: CapturedError, env: BugReportEnv): string {
|
|
|
184
184
|
`### Environment`,
|
|
185
185
|
`| | |`,
|
|
186
186
|
`|---|---|`,
|
|
187
|
-
`|
|
|
187
|
+
`| nemus | ${env.version} |`,
|
|
188
188
|
`| node | ${env.node} |`,
|
|
189
189
|
`| os | ${env.os} |`,
|
|
190
190
|
`| arch | ${env.arch} |`,
|
|
@@ -261,7 +261,7 @@ function ensureLabel(): void {
|
|
|
261
261
|
'label', 'create', BUG_LABEL,
|
|
262
262
|
'--repo', BUG_REPORT_REPO,
|
|
263
263
|
'--color', 'B60205',
|
|
264
|
-
'--description', 'Auto-reported by
|
|
264
|
+
'--description', 'Auto-reported by nemus',
|
|
265
265
|
], { encoding: 'utf-8', timeout: 15_000, stdio: 'ignore' });
|
|
266
266
|
} catch {
|
|
267
267
|
/* may already exist or no perms — ignore */
|
|
@@ -112,7 +112,7 @@ export async function backfillAgentRules(workspacePath: string, workspaceName: s
|
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
export async function loadClaudeConfig(): Promise<ClaudeConfig> {
|
|
115
|
-
const configFile = path.join(process.env.HOME || '~', '.
|
|
115
|
+
const configFile = path.join(process.env.HOME || '~', '.nemus-claude-config.json');
|
|
116
116
|
|
|
117
117
|
try {
|
|
118
118
|
const content = await fs.readFile(configFile, 'utf-8');
|
|
@@ -126,7 +126,7 @@ export async function loadClaudeConfig(): Promise<ClaudeConfig> {
|
|
|
126
126
|
* Save Claude integration config
|
|
127
127
|
*/
|
|
128
128
|
export async function saveClaudeConfig(config: ClaudeConfig): Promise<void> {
|
|
129
|
-
const configFile = path.join(process.env.HOME || '~', '.
|
|
129
|
+
const configFile = path.join(process.env.HOME || '~', '.nemus-claude-config.json');
|
|
130
130
|
|
|
131
131
|
try {
|
|
132
132
|
await fs.writeFile(configFile, JSON.stringify(config, null, 2), 'utf-8');
|
|
@@ -184,7 +184,7 @@ export async function generateClaudeContext(
|
|
|
184
184
|
|
|
185
185
|
let content = `# Workspace: ${workspaceName}
|
|
186
186
|
|
|
187
|
-
This workspace was created with [
|
|
187
|
+
This workspace was created with [Nemus](https://github.com/${githubOrg}/nemus).
|
|
188
188
|
|
|
189
189
|
## Organization
|
|
190
190
|
|
|
@@ -328,7 +328,7 @@ This workspace contains ${entries.length} repositories for focused development w
|
|
|
328
328
|
logSuccess(`Generated ${colorize(fileName, 'cyan')} with workspace context`);
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
// Generate .mcp.json with
|
|
331
|
+
// Generate .mcp.json with nemus MCP server (if enabled)
|
|
332
332
|
const { installMcp } = getUserConfig();
|
|
333
333
|
if (installMcp) {
|
|
334
334
|
await generateMcpConfig(workspacePath);
|
|
@@ -408,9 +408,9 @@ function resolveMcpServerPath(): string | null {
|
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
/**
|
|
411
|
-
* Generate .mcp.json with
|
|
411
|
+
* Generate .mcp.json with nemus MCP server config.
|
|
412
412
|
* This ensures Claude Code sessions in the workspace have access to
|
|
413
|
-
*
|
|
413
|
+
* nemus tools even without global MCP registration.
|
|
414
414
|
*/
|
|
415
415
|
export async function generateMcpConfig(workspacePath: string): Promise<boolean> {
|
|
416
416
|
try {
|
|
@@ -434,7 +434,7 @@ export async function generateMcpConfig(workspacePath: string): Promise<boolean>
|
|
|
434
434
|
...existingConfig,
|
|
435
435
|
mcpServers: {
|
|
436
436
|
...(existingConfig.mcpServers || {}),
|
|
437
|
-
'
|
|
437
|
+
'nemus': {
|
|
438
438
|
command: 'node',
|
|
439
439
|
args: [serverPath],
|
|
440
440
|
},
|
|
@@ -442,7 +442,7 @@ export async function generateMcpConfig(workspacePath: string): Promise<boolean>
|
|
|
442
442
|
};
|
|
443
443
|
|
|
444
444
|
await fs.writeFile(mcpFile, JSON.stringify(mcpConfig, null, 2) + '\n', 'utf-8');
|
|
445
|
-
logSuccess(`Generated ${colorize('.mcp.json', 'cyan')} with
|
|
445
|
+
logSuccess(`Generated ${colorize('.mcp.json', 'cyan')} with nemus MCP server`);
|
|
446
446
|
return true;
|
|
447
447
|
} catch (error) {
|
|
448
448
|
logWarning('Failed to generate .mcp.json file');
|
|
@@ -21,7 +21,7 @@ describe('isReusablePermission', () => {
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
it('keeps mcp tool permissions', () => {
|
|
24
|
-
expect(isReusablePermission('
|
|
24
|
+
expect(isReusablePermission('mcp__nemus__list-workspaces')).toBe(true);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('keeps Skill and WebFetch permissions', () => {
|
|
@@ -480,7 +480,7 @@ describe('uninstallWorkspaceSkills', () => {
|
|
|
480
480
|
expect(() => uninstallWorkspaceSkills(targetDir)).not.toThrow();
|
|
481
481
|
});
|
|
482
482
|
|
|
483
|
-
it('does not remove non-
|
|
483
|
+
it('does not remove non-nemus skills', () => {
|
|
484
484
|
const targetDir = path.join(tmpDir, 'skills');
|
|
485
485
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
486
486
|
|
|
@@ -520,7 +520,7 @@ describe('repairStaleHooks', () => {
|
|
|
520
520
|
expect(repairStaleHooks(missing)).toBe(0);
|
|
521
521
|
});
|
|
522
522
|
|
|
523
|
-
it('returns 0 when there are no
|
|
523
|
+
it('returns 0 when there are no nemus hooks', () => {
|
|
524
524
|
const settingsPath = path.join(tmpDir, 'settings.json');
|
|
525
525
|
fs.writeFileSync(settingsPath, JSON.stringify({
|
|
526
526
|
hooks: { Stop: [{ hooks: [{ type: 'command', command: 'echo hi' }] }] },
|
|
@@ -544,7 +544,7 @@ describe('repairStaleHooks', () => {
|
|
|
544
544
|
Stop: [{
|
|
545
545
|
hooks: [{
|
|
546
546
|
type: 'command',
|
|
547
|
-
command: 'bash "/Users/x/.volta/tmp/image/packages/.tmpABC/lib/node_modules/@acme/
|
|
547
|
+
command: 'bash "/Users/x/.volta/tmp/image/packages/.tmpABC/lib/node_modules/@acme/nemus/sync-permissions.sh"',
|
|
548
548
|
}],
|
|
549
549
|
}],
|
|
550
550
|
},
|
|
@@ -419,7 +419,7 @@ function getSkillsSourceDir(): string {
|
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
/**
|
|
422
|
-
* Install all
|
|
422
|
+
* Install all nemus skills from the skills/ directory.
|
|
423
423
|
* Each .md file becomes a skill under <skillsDir>/<skill-name>/SKILL.md.
|
|
424
424
|
* Installs to all active agent skills directories.
|
|
425
425
|
* Idempotent — safe to call multiple times.
|
|
@@ -471,7 +471,7 @@ export function installWorkspaceSkills(skillsDir?: string): void {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
if (installed > 0) {
|
|
474
|
-
logSuccess(`Installed ${installed}
|
|
474
|
+
logSuccess(`Installed ${installed} nemus skills in ${targetBase}`);
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
}
|
|
@@ -493,7 +493,7 @@ function copyDirRecursive(src: string, dest: string): void {
|
|
|
493
493
|
}
|
|
494
494
|
|
|
495
495
|
/**
|
|
496
|
-
* Remove all
|
|
496
|
+
* Remove all nemus skills from all possible agent directories.
|
|
497
497
|
* Reads the skills/ source directory to know which skill names to remove.
|
|
498
498
|
* Removes from both Claude and Pi dirs regardless of current config to avoid orphans.
|
|
499
499
|
*/
|
|
@@ -536,7 +536,7 @@ export function uninstallWorkspaceSkills(skillsDir?: string): void {
|
|
|
536
536
|
// ─── Workspace status-line ────────────────────────────────────────────────────
|
|
537
537
|
|
|
538
538
|
/** Absolute install path for the workspace-table Python script. */
|
|
539
|
-
const WORKSPACE_TABLE_SCRIPT = path.join(os.homedir(), '.
|
|
539
|
+
const WORKSPACE_TABLE_SCRIPT = path.join(os.homedir(), '.nemus-table.py');
|
|
540
540
|
|
|
541
541
|
/**
|
|
542
542
|
* Resolve the bundled workspace-table.py path from the installed package.
|
|
@@ -558,7 +558,7 @@ function getWorkspaceTableSourcePath(): string {
|
|
|
558
558
|
* Claude Code shows its default footer — the user's existing styling is
|
|
559
559
|
* never affected.
|
|
560
560
|
*
|
|
561
|
-
* The script is copied to ~/.
|
|
561
|
+
* The script is copied to ~/.nemus-table.py and registered in
|
|
562
562
|
* ~/.claude/settings.json only when no statusLine is already configured —
|
|
563
563
|
* we never overwrite a custom status line the user already has.
|
|
564
564
|
*
|
|
@@ -570,7 +570,7 @@ export function installWorkspaceStatusLine(settingsPath?: string): void {
|
|
|
570
570
|
|
|
571
571
|
if ((settings as any).statusLine) {
|
|
572
572
|
logInfo('statusLine already configured in ~/.claude/settings.json — skipping workspace-table install');
|
|
573
|
-
logInfo(` To use
|
|
573
|
+
logInfo(` To use nemus\'s table, replace your statusLine command with: ${WORKSPACE_TABLE_SCRIPT}`);
|
|
574
574
|
return;
|
|
575
575
|
}
|
|
576
576
|
|
|
@@ -597,7 +597,7 @@ export function installWorkspaceStatusLine(settingsPath?: string): void {
|
|
|
597
597
|
|
|
598
598
|
/**
|
|
599
599
|
* Remove the workspace status-line from Claude Code\'s settings.json.
|
|
600
|
-
* Only removes it if the command points to
|
|
600
|
+
* Only removes it if the command points to nemus\'s own script.
|
|
601
601
|
*
|
|
602
602
|
* @param settingsPath Override ~/.claude/settings.json (for testing).
|
|
603
603
|
*/
|
|
@@ -612,8 +612,8 @@ export function uninstallWorkspaceStatusLine(settingsPath?: string): void {
|
|
|
612
612
|
}
|
|
613
613
|
|
|
614
614
|
const cmd: string = existing.command ?? '';
|
|
615
|
-
if (!cmd.includes('
|
|
616
|
-
logInfo('statusLine is not managed by
|
|
615
|
+
if (!cmd.includes('nemus-table')) {
|
|
616
|
+
logInfo('statusLine is not managed by nemus — leaving it unchanged');
|
|
617
617
|
return;
|
|
618
618
|
}
|
|
619
619
|
|
|
@@ -639,7 +639,7 @@ function extractScriptPath(command: string): string | null {
|
|
|
639
639
|
}
|
|
640
640
|
|
|
641
641
|
/**
|
|
642
|
-
* Detect and repair
|
|
642
|
+
* Detect and repair nemus hook commands in ~/.claude/settings.json
|
|
643
643
|
* that point to script paths which no longer exist on disk.
|
|
644
644
|
*
|
|
645
645
|
* This happens when the package is installed via a manager (e.g. Volta) whose
|
|
@@ -38,7 +38,7 @@ describe('Pi extensions', () => {
|
|
|
38
38
|
|
|
39
39
|
for (const file of fs.readdirSync(extensionsDir)) {
|
|
40
40
|
const content = fs.readFileSync(path.join(extensionsDir, file), 'utf-8');
|
|
41
|
-
expect(content).toContain('auto-generated by
|
|
41
|
+
expect(content).toContain('auto-generated by nemus');
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -16,8 +16,8 @@ import { logSuccess, logInfo, logWarning } from './logger';
|
|
|
16
16
|
|
|
17
17
|
const PI_EXTENSIONS_DIR = path.join(os.homedir(), '.pi', 'agent', 'extensions');
|
|
18
18
|
|
|
19
|
-
/** Marker comment that identifies
|
|
20
|
-
const MANAGED_MARKER = '(auto-generated by
|
|
19
|
+
/** Marker comment that identifies nemus managed extensions */
|
|
20
|
+
const MANAGED_MARKER = '(auto-generated by nemus)';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Extension template definitions.
|
|
@@ -92,7 +92,7 @@ function getExtensionTemplates(options: { workspaceInputStatus?: boolean } = {})
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* Install all
|
|
95
|
+
* Install all nemus Pi extensions.
|
|
96
96
|
* Idempotent — overwrites existing managed extensions with latest templates.
|
|
97
97
|
*
|
|
98
98
|
* @param extensionsDir Override the extensions directory (for testing).
|
|
@@ -142,14 +142,14 @@ export function installPiExtensions(extensionsDir?: string, options: { workspace
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/**
|
|
145
|
-
* Uninstall
|
|
145
|
+
* Uninstall nemus managed Pi extensions.
|
|
146
146
|
* Only removes extensions that contain the managed marker or match
|
|
147
147
|
* known installed names.
|
|
148
148
|
*
|
|
149
149
|
* @param extensionsDir Override the extensions directory (for testing).
|
|
150
150
|
*/
|
|
151
151
|
/**
|
|
152
|
-
* Uninstall
|
|
152
|
+
* Uninstall nemus managed Pi extensions.
|
|
153
153
|
* Pass `onlyNames` to remove only specific extension files (for opt-out).
|
|
154
154
|
*
|
|
155
155
|
* @param extensionsDir Override the extensions directory (for testing).
|