@nemus-cli/nemus 0.2.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/CHANGELOG.md +86 -0
- package/LICENSE +21 -0
- package/README.md +275 -0
- package/assets/README.md +53 -0
- package/assets/banner.png +0 -0
- package/assets/banner.svg +66 -0
- package/assets/favicon-32.png +0 -0
- package/assets/favicon-64.png +0 -0
- package/assets/icon-256.png +0 -0
- package/assets/icon.svg +23 -0
- package/assets/logo-256.png +0 -0
- package/assets/logo-512.png +0 -0
- package/assets/logo-wordmark.svg +35 -0
- package/assets/logo.svg +32 -0
- package/bin/workspace.js +130 -0
- package/dist/cli/ai-prompt.js +421 -0
- package/dist/cli/dashboard/AgentList.js +61 -0
- package/dist/cli/dashboard/DashboardSidebar.js +280 -0
- package/dist/cli/dashboard/HelpFooter.js +73 -0
- package/dist/cli/dashboard/StatusBadge.js +50 -0
- package/dist/cli/dashboard/index.js +11 -0
- package/dist/cli/dashboard/types.js +2 -0
- package/dist/cli/tui.js +48 -0
- package/dist/commands/ai-prompt.js +22 -0
- package/dist/commands/analyze-deps.js +138 -0
- package/dist/commands/archive.js +113 -0
- package/dist/commands/branch/create.js +119 -0
- package/dist/commands/branch/index.js +104 -0
- package/dist/commands/branch/merge.js +90 -0
- package/dist/commands/branch/rebase.js +84 -0
- package/dist/commands/branch/switch.js +165 -0
- package/dist/commands/cache/index.js +80 -0
- package/dist/commands/cache/manager.js +198 -0
- package/dist/commands/cleanup.js +153 -0
- package/dist/commands/configure-claude.js +55 -0
- package/dist/commands/configure.js +231 -0
- package/dist/commands/create.js +204 -0
- package/dist/commands/dashboard/hook-handler.js +162 -0
- package/dist/commands/dashboard/index.js +258 -0
- package/dist/commands/dashboard/launcher.js +40 -0
- package/dist/commands/dashboard/session-picker.js +106 -0
- package/dist/commands/dashboard/sidebar.js +39 -0
- package/dist/commands/dashboard/workspace-picker.js +95 -0
- package/dist/commands/delete.js +194 -0
- package/dist/commands/deprecated-aliases.js +44 -0
- package/dist/commands/diff.js +129 -0
- package/dist/commands/doctor.js +141 -0
- package/dist/commands/generate-docs.js +77 -0
- package/dist/commands/ghq-status.js +72 -0
- package/dist/commands/go.js +154 -0
- package/dist/commands/history.js +124 -0
- package/dist/commands/list.js +191 -0
- package/dist/commands/mcp/index.js +69 -0
- package/dist/commands/migrate.js +296 -0
- package/dist/commands/remove-repo.js +217 -0
- package/dist/commands/report-bug.js +112 -0
- package/dist/commands/run.js +147 -0
- package/dist/commands/save-context.js +171 -0
- package/dist/commands/sessions.js +129 -0
- package/dist/commands/status.js +138 -0
- package/dist/commands/suite/create.js +212 -0
- package/dist/commands/suite/delete.js +64 -0
- package/dist/commands/suite/export.js +126 -0
- package/dist/commands/suite/import.js +128 -0
- package/dist/commands/suite/index.js +94 -0
- package/dist/commands/suite/list.js +49 -0
- package/dist/commands/suite/use.js +227 -0
- package/dist/commands/sync.js +117 -0
- package/dist/commands/update.js +203 -0
- package/dist/mcp/install.js +550 -0
- package/dist/mcp/server.js +398 -0
- package/dist/mcp/tools.js +922 -0
- package/dist/pi-extensions/permission-sync.ts.template +41 -0
- package/dist/pi-extensions/permissions-gate.ts.template +69 -0
- package/dist/pi-extensions/pr-fix-trigger.ts.template +124 -0
- package/dist/pi-extensions/review-reminder.ts.template +58 -0
- package/dist/pi-extensions/workspace-input-status.ts.template +919 -0
- package/dist/program.js +136 -0
- package/dist/scripts/workspace-table.py +394 -0
- package/dist/types/dashboard.js +11 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/agent-config.js +263 -0
- package/dist/utils/agent-state.js +178 -0
- package/dist/utils/banner.js +24 -0
- package/dist/utils/branch-operations.js +232 -0
- package/dist/utils/bug-report.js +355 -0
- package/dist/utils/cache.js +168 -0
- package/dist/utils/claude-integration.js +617 -0
- package/dist/utils/claude-sessions.js +260 -0
- package/dist/utils/cleanup-operations.js +120 -0
- package/dist/utils/colors.js +26 -0
- package/dist/utils/command-helpers.js +44 -0
- package/dist/utils/config.js +150 -0
- package/dist/utils/context-file.js +33 -0
- package/dist/utils/dashboard-hooks.js +172 -0
- package/dist/utils/dependency-analyzer.js +234 -0
- package/dist/utils/diff-operations.js +80 -0
- package/dist/utils/doc-generator.js +184 -0
- package/dist/utils/ghq-integration.js +332 -0
- package/dist/utils/git-operations.js +237 -0
- package/dist/utils/git-status.js +187 -0
- package/dist/utils/github.js +68 -0
- package/dist/utils/health-checks.js +345 -0
- package/dist/utils/history.js +150 -0
- package/dist/utils/hooks.js +100 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/permission-sync.js +681 -0
- package/dist/utils/pi-extensions.js +224 -0
- package/dist/utils/progress.js +92 -0
- package/dist/utils/prompts.js +279 -0
- package/dist/utils/repo-resolver.js +260 -0
- package/dist/utils/retry.js +65 -0
- package/dist/utils/run-operations.js +30 -0
- package/dist/utils/suite.js +159 -0
- package/dist/utils/sync-operations.js +107 -0
- package/dist/utils/tmux-dashboard.js +184 -0
- package/dist/utils/validation.js +153 -0
- package/dist/utils/version-check.js +121 -0
- package/dist/utils/workspace-meta.js +185 -0
- package/install-shell-integration.sh +532 -0
- package/install.sh +401 -0
- package/package.json +90 -0
- package/remove-shell-block.awk +44 -0
- package/scripts/postinstall.js +85 -0
- package/skills/analyze-deps.md +23 -0
- package/skills/archive-workspace.md +26 -0
- package/skills/branch-create.md +18 -0
- package/skills/create-workspace.md +39 -0
- package/skills/delete-workspace.md +37 -0
- package/skills/list-org-repos.md +26 -0
- package/skills/list-suites.md +24 -0
- package/skills/list-workspaces.md +27 -0
- package/skills/refresh-workspace-docs.md +89 -0
- package/skills/remove-repo.md +25 -0
- package/skills/run-command.md +23 -0
- package/skills/save-context.md +68 -0
- package/skills/search-repos.md +31 -0
- package/skills/snapshot-list.md +18 -0
- package/skills/snapshot-save.md +12 -0
- package/skills/switch-branch.md +18 -0
- package/skills/update-cache.md +21 -0
- package/skills/update-workspace.md +66 -0
- package/skills/workspace-cleanup.md +18 -0
- package/skills/workspace-diff.md +23 -0
- package/skills/workspace-doctor.md +23 -0
- package/skills/workspace-info.md +45 -0
- package/skills/workspace-manager/SKILL.md +201 -0
- package/skills/workspace-manager/references/ai-prompt.md +44 -0
- package/skills/workspace-manager/references/analyze-deps.md +45 -0
- package/skills/workspace-manager/references/archive-workspace.md +38 -0
- package/skills/workspace-manager/references/branch-create.md +31 -0
- package/skills/workspace-manager/references/branch-merge.md +22 -0
- package/skills/workspace-manager/references/branch-rebase.md +22 -0
- package/skills/workspace-manager/references/cache-clear.md +18 -0
- package/skills/workspace-manager/references/cache-info.md +22 -0
- package/skills/workspace-manager/references/configure-claude.md +31 -0
- package/skills/workspace-manager/references/configure.md +35 -0
- package/skills/workspace-manager/references/create-workspace.md +45 -0
- package/skills/workspace-manager/references/dashboard.md +61 -0
- package/skills/workspace-manager/references/delete-workspace.md +33 -0
- package/skills/workspace-manager/references/generate-docs.md +36 -0
- package/skills/workspace-manager/references/ghq-status.md +28 -0
- package/skills/workspace-manager/references/go.md +33 -0
- package/skills/workspace-manager/references/history.md +41 -0
- package/skills/workspace-manager/references/list-org-repos.md +26 -0
- package/skills/workspace-manager/references/list-suites.md +21 -0
- package/skills/workspace-manager/references/list-workspaces.md +27 -0
- package/skills/workspace-manager/references/mcp.md +49 -0
- package/skills/workspace-manager/references/remove-repo.md +26 -0
- package/skills/workspace-manager/references/run-command.md +44 -0
- package/skills/workspace-manager/references/search-repos.md +24 -0
- package/skills/workspace-manager/references/sessions.md +27 -0
- package/skills/workspace-manager/references/suite-create.md +22 -0
- package/skills/workspace-manager/references/suite-delete.md +21 -0
- package/skills/workspace-manager/references/suite-export.md +19 -0
- package/skills/workspace-manager/references/suite-import.md +19 -0
- package/skills/workspace-manager/references/suite-use.md +27 -0
- package/skills/workspace-manager/references/switch-branch.md +25 -0
- package/skills/workspace-manager/references/update-cache.md +22 -0
- package/skills/workspace-manager/references/update-workspace.md +50 -0
- package/skills/workspace-manager/references/workspace-cleanup.md +33 -0
- package/skills/workspace-manager/references/workspace-diff.md +27 -0
- package/skills/workspace-manager/references/workspace-doctor.md +27 -0
- package/skills/workspace-manager/references/workspace-info.md +33 -0
- package/skills/workspace-manager/references/workspace-status.md +43 -0
- package/skills/workspace-manager/references/workspace-sync.md +26 -0
- package/skills/workspace-status.md +26 -0
- package/skills/workspace-sync.md +23 -0
- package/src/cli/ai-prompt.test.ts +667 -0
- package/src/cli/ai-prompt.ts +421 -0
- package/src/cli/dashboard/AgentList.tsx +44 -0
- package/src/cli/dashboard/DashboardSidebar.tsx +291 -0
- package/src/cli/dashboard/HelpFooter.tsx +22 -0
- package/src/cli/dashboard/StatusBadge.tsx +23 -0
- package/src/cli/dashboard/index.ts +5 -0
- package/src/cli/dashboard/types.ts +16 -0
- package/src/cli/tui.tsx +51 -0
- package/src/cli/workspace-cli.test.ts +30 -0
- package/src/commands/ai-prompt.ts +21 -0
- package/src/commands/analyze-deps.ts +119 -0
- package/src/commands/archive.ts +114 -0
- package/src/commands/branch/create.ts +94 -0
- package/src/commands/branch/index.ts +74 -0
- package/src/commands/branch/merge.ts +61 -0
- package/src/commands/branch/rebase.ts +54 -0
- package/src/commands/branch/switch.ts +150 -0
- package/src/commands/cache/index.ts +51 -0
- package/src/commands/cache/manager.ts +168 -0
- package/src/commands/cleanup.ts +132 -0
- package/src/commands/configure-claude.ts +55 -0
- package/src/commands/configure.ts +204 -0
- package/src/commands/create.ts +196 -0
- package/src/commands/dashboard/hook-handler.ts +138 -0
- package/src/commands/dashboard/index.ts +248 -0
- package/src/commands/dashboard/launcher.ts +42 -0
- package/src/commands/dashboard/session-picker.ts +73 -0
- package/src/commands/dashboard/sidebar.js +39 -0
- package/src/commands/dashboard/workspace-picker.ts +62 -0
- package/src/commands/delete.test.ts +250 -0
- package/src/commands/delete.ts +171 -0
- package/src/commands/deprecated-aliases.ts +55 -0
- package/src/commands/diff.ts +106 -0
- package/src/commands/doctor.ts +110 -0
- package/src/commands/generate-docs.ts +45 -0
- package/src/commands/ghq-status.ts +70 -0
- package/src/commands/go.ts +125 -0
- package/src/commands/history.ts +136 -0
- package/src/commands/list.test.ts +219 -0
- package/src/commands/list.ts +176 -0
- package/src/commands/mcp/index.ts +39 -0
- package/src/commands/migrate.ts +277 -0
- package/src/commands/remove-repo.ts +194 -0
- package/src/commands/report-bug.ts +88 -0
- package/src/commands/run.ts +125 -0
- package/src/commands/save-context.test.ts +113 -0
- package/src/commands/save-context.ts +141 -0
- package/src/commands/sessions.ts +99 -0
- package/src/commands/status.ts +111 -0
- package/src/commands/suite/create.ts +240 -0
- package/src/commands/suite/delete.ts +65 -0
- package/src/commands/suite/export.ts +97 -0
- package/src/commands/suite/import.ts +100 -0
- package/src/commands/suite/index.ts +66 -0
- package/src/commands/suite/list.ts +54 -0
- package/src/commands/suite/use.ts +232 -0
- package/src/commands/sync.ts +97 -0
- package/src/commands/update.ts +197 -0
- package/src/mcp/install.ts +529 -0
- package/src/mcp/server.ts +579 -0
- package/src/mcp/tools.test.ts +545 -0
- package/src/mcp/tools.ts +1019 -0
- package/src/mcp/update-workspace.test.ts +220 -0
- package/src/pi-extensions/permission-sync.ts.template +41 -0
- package/src/pi-extensions/permissions-gate.ts.template +69 -0
- package/src/pi-extensions/pr-fix-trigger.ts.template +124 -0
- package/src/pi-extensions/review-reminder.ts.template +58 -0
- package/src/pi-extensions/workspace-input-status.ts.template +919 -0
- package/src/program.ts +112 -0
- package/src/scripts/workspace-table.py +394 -0
- package/src/types/dashboard.ts +29 -0
- package/src/types/index.ts +109 -0
- package/src/types/ink.d.ts +171 -0
- package/src/utils/agent-config.test.ts +303 -0
- package/src/utils/agent-config.ts +264 -0
- package/src/utils/agent-state.test.ts +166 -0
- package/src/utils/agent-state.ts +135 -0
- package/src/utils/banner.ts +24 -0
- package/src/utils/branch-operations.ts +237 -0
- package/src/utils/bug-report.test.ts +174 -0
- package/src/utils/bug-report.ts +355 -0
- package/src/utils/cache.ts +150 -0
- package/src/utils/claude-integration.test.ts +381 -0
- package/src/utils/claude-integration.ts +649 -0
- package/src/utils/claude-sessions.test.ts +262 -0
- package/src/utils/claude-sessions.ts +251 -0
- package/src/utils/cleanup-operations.ts +94 -0
- package/src/utils/colors.ts +25 -0
- package/src/utils/command-helpers.ts +46 -0
- package/src/utils/config.test.ts +203 -0
- package/src/utils/config.ts +133 -0
- package/src/utils/context-file.ts +36 -0
- package/src/utils/dashboard-hooks.test.ts +168 -0
- package/src/utils/dashboard-hooks.ts +163 -0
- package/src/utils/dependency-analyzer.ts +243 -0
- package/src/utils/diff-operations.ts +59 -0
- package/src/utils/doc-generator.ts +187 -0
- package/src/utils/ghq-integration.test.ts +195 -0
- package/src/utils/ghq-integration.ts +317 -0
- package/src/utils/git-operations.test.ts +265 -0
- package/src/utils/git-operations.ts +233 -0
- package/src/utils/git-status.ts +171 -0
- package/src/utils/github.ts +74 -0
- package/src/utils/health-checks.ts +359 -0
- package/src/utils/history.ts +140 -0
- package/src/utils/hooks.ts +92 -0
- package/src/utils/logger.ts +37 -0
- package/src/utils/permission-sync.test.ts +593 -0
- package/src/utils/permission-sync.ts +720 -0
- package/src/utils/pi-extensions.test.ts +182 -0
- package/src/utils/pi-extensions.ts +226 -0
- package/src/utils/progress.ts +73 -0
- package/src/utils/prompts.test.ts +169 -0
- package/src/utils/prompts.ts +296 -0
- package/src/utils/repo-resolver.test.ts +313 -0
- package/src/utils/repo-resolver.ts +294 -0
- package/src/utils/retry.test.ts +124 -0
- package/src/utils/retry.ts +85 -0
- package/src/utils/run-operations.ts +38 -0
- package/src/utils/suite.test.ts +256 -0
- package/src/utils/suite.ts +144 -0
- package/src/utils/sync-operations.ts +87 -0
- package/src/utils/tmux-dashboard.ts +193 -0
- package/src/utils/validation.test.ts +139 -0
- package/src/utils/validation.ts +128 -0
- package/src/utils/version-check.test.ts +108 -0
- package/src/utils/version-check.ts +96 -0
- package/src/utils/workspace-meta.ts +173 -0
- package/sync-permissions.sh +137 -0
- package/tsconfig.json +20 -0
- package/uninstall.sh +162 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Nemus - Shell Integration Installer
|
|
4
|
+
# This script installs a shell function that allows automatic CD after workspace creation
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
9
|
+
SHELL_TYPE="${1:-detect}"
|
|
10
|
+
|
|
11
|
+
# Detect shell if not specified
|
|
12
|
+
if [ "$SHELL_TYPE" = "detect" ]; then
|
|
13
|
+
if [ -n "$BASH_VERSION" ]; then
|
|
14
|
+
SHELL_TYPE="bash"
|
|
15
|
+
elif [ -n "$ZSH_VERSION" ]; then
|
|
16
|
+
SHELL_TYPE="zsh"
|
|
17
|
+
else
|
|
18
|
+
SHELL_CURRENT=$(basename "$SHELL")
|
|
19
|
+
if [ "$SHELL_CURRENT" = "bash" ]; then
|
|
20
|
+
SHELL_TYPE="bash"
|
|
21
|
+
elif [ "$SHELL_CURRENT" = "zsh" ]; then
|
|
22
|
+
SHELL_TYPE="zsh"
|
|
23
|
+
else
|
|
24
|
+
echo "Could not detect shell type. Please specify: bash or zsh"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
fi
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Shell function to wrap workspace command
|
|
31
|
+
read -r -d '' SHELL_FUNCTION << 'EOF' || true
|
|
32
|
+
|
|
33
|
+
# Nemus - Shell Integration (v50)
|
|
34
|
+
# Wraps both 'nemus' and 'nem' commands so the shell can CD after
|
|
35
|
+
# create / list / go commands. A child process cannot change the parent
|
|
36
|
+
# shell's directory, so we need shell functions that read a temp file
|
|
37
|
+
# written by the Node CLI and call `cd` in the current shell.
|
|
38
|
+
|
|
39
|
+
# ── helper: deterministic tab color from workspace name ──────────────
|
|
40
|
+
# Hashes the workspace name and maps it to a color on the full HSL hue
|
|
41
|
+
# wheel, then converts to RGB. This gives ~360 distinct, readable colors
|
|
42
|
+
# (vs the old 16-entry palette that repeated after a handful of
|
|
43
|
+
# workspaces). Always produces the same color for the same name.
|
|
44
|
+
# Output: "R G B" as three space-separated integers (0-255).
|
|
45
|
+
__workspace_hash_color() {
|
|
46
|
+
local str="$1"
|
|
47
|
+
local hash=0
|
|
48
|
+
local i char
|
|
49
|
+
for (( i=0; i<${#str}; i++ )); do
|
|
50
|
+
char="${str:$i:1}"
|
|
51
|
+
# 24-bit accumulator for a wide, well-distributed hash.
|
|
52
|
+
hash=$(( (hash * 31 + $(printf '%d' "'$char")) % 16777216 ))
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
# Derive hue across the whole wheel (0-359) plus small saturation/lightness
|
|
56
|
+
# variation from independent slices of the hash for extra distinctness,
|
|
57
|
+
# kept within a tasteful, readable band (not neon, not muddy).
|
|
58
|
+
local hue=$(( hash % 360 ))
|
|
59
|
+
local sat=$(( 58 + (hash / 360) % 15 )) # 58-72 %
|
|
60
|
+
local light=$(( 60 + (hash / 97) % 11 )) # 60-70 %
|
|
61
|
+
|
|
62
|
+
# HSL -> RGB. Prefer awk (handles the float math) for a smooth spectrum;
|
|
63
|
+
# fall back to a small built-in palette if awk is somehow unavailable.
|
|
64
|
+
if command -v awk >/dev/null 2>&1; then
|
|
65
|
+
awk -v h="$hue" -v s="$sat" -v l="$light" 'BEGIN{
|
|
66
|
+
s/=100.0; l/=100.0;
|
|
67
|
+
c=(1-((2*l-1)<0?-(2*l-1):(2*l-1)))*s;
|
|
68
|
+
hp=h/60.0;
|
|
69
|
+
m2=hp-2*int(hp/2); d=m2-1; if(d<0)d=-d;
|
|
70
|
+
x=c*(1-d);
|
|
71
|
+
if(hp<1){r=c;g=x;b=0} else if(hp<2){r=x;g=c;b=0}
|
|
72
|
+
else if(hp<3){r=0;g=c;b=x} else if(hp<4){r=0;g=x;b=c}
|
|
73
|
+
else if(hp<5){r=x;g=0;b=c} else {r=c;g=0;b=x}
|
|
74
|
+
m=l-c/2.0;
|
|
75
|
+
printf "%d %d %d", (r+m)*255+0.5, (g+m)*255+0.5, (b+m)*255+0.5;
|
|
76
|
+
}'
|
|
77
|
+
else
|
|
78
|
+
# Fallback palette (only used if awk is missing).
|
|
79
|
+
local palette=(
|
|
80
|
+
"86 156 214" "106 153 85" "214 157 133" "156 220 254"
|
|
81
|
+
"220 220 170" "197 134 192" "78 201 176" "255 198 109"
|
|
82
|
+
"229 192 123" "97 175 239" "224 108 117" "152 195 121"
|
|
83
|
+
"180 100 166" "209 154 102" "129 162 190" "140 170 175"
|
|
84
|
+
)
|
|
85
|
+
local idx=$(( hash % ${#palette[@]} ))
|
|
86
|
+
if [ -n "${ZSH_VERSION:-}" ]; then idx=$(( idx + 1 )); fi
|
|
87
|
+
echo "${palette[$idx]}"
|
|
88
|
+
fi
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# ── helper: set iTerm2 tab background color ────────────────────────
|
|
92
|
+
# Uses the xterm OSC 6 escape sequence that iTerm2 supports.
|
|
93
|
+
# Silently does nothing in terminals that don't understand it.
|
|
94
|
+
__workspace_set_tab_color() {
|
|
95
|
+
local r="$1" g="$2" b="$3"
|
|
96
|
+
if [ "${TERM_PROGRAM:-}" = "iTerm.app" ] || [ "${TERM_PROGRAM:-}" = "iTerm2" ]; then
|
|
97
|
+
printf '\033]6;1;bg;red;brightness;%d\007' "$r"
|
|
98
|
+
printf '\033]6;1;bg;green;brightness;%d\007' "$g"
|
|
99
|
+
printf '\033]6;1;bg;blue;brightness;%d\007' "$b"
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# ── helper: reset iTerm2 tab color to the profile default ─────────
|
|
104
|
+
__workspace_reset_tab_color() {
|
|
105
|
+
if [ "${TERM_PROGRAM:-}" = "iTerm.app" ] || [ "${TERM_PROGRAM:-}" = "iTerm2" ]; then
|
|
106
|
+
printf '\033]6;1;bg;*;default\007'
|
|
107
|
+
fi
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# ── helper: set terminal tab title + iTerm2 tab color ────────────────
|
|
111
|
+
# Uses both OSC 0 (window title) and OSC 1 (tab title) for broad
|
|
112
|
+
# terminal support. Installs a precmd/PROMPT_COMMAND hook so the title
|
|
113
|
+
# and color persist across prompts (zsh/oh-my-zsh and bash reset titles
|
|
114
|
+
# on each prompt). The hook auto-clears when the user CDs out of the
|
|
115
|
+
# workspace, restoring the default tab color.
|
|
116
|
+
__workspace_set_tab_title() {
|
|
117
|
+
local title="$1"
|
|
118
|
+
# Set title immediately
|
|
119
|
+
printf '\033]0;%s\007' "$title"
|
|
120
|
+
printf '\033]1;%s\007' "$title"
|
|
121
|
+
|
|
122
|
+
# Compute and apply a deterministic color for this workspace
|
|
123
|
+
local color r g b
|
|
124
|
+
color=$(__workspace_hash_color "$title")
|
|
125
|
+
read -r r g b <<< "$color"
|
|
126
|
+
__workspace_set_tab_color "$r" "$g" "$b"
|
|
127
|
+
|
|
128
|
+
# Persist state for the hook
|
|
129
|
+
export __WORKSPACE_TAB_TITLE="$title"
|
|
130
|
+
export __WORKSPACE_TAB_DIR="$PWD"
|
|
131
|
+
export __WORKSPACE_TAB_R="$r"
|
|
132
|
+
export __WORKSPACE_TAB_G="$g"
|
|
133
|
+
export __WORKSPACE_TAB_B="$b"
|
|
134
|
+
|
|
135
|
+
if [ -n "${ZSH_VERSION:-}" ]; then
|
|
136
|
+
# Disable oh-my-zsh auto-title so it doesn't overwrite ours
|
|
137
|
+
if [ -z "${__WORKSPACE_PREV_DISABLE_AUTO_TITLE+x}" ]; then
|
|
138
|
+
export __WORKSPACE_PREV_DISABLE_AUTO_TITLE="${DISABLE_AUTO_TITLE:-}"
|
|
139
|
+
fi
|
|
140
|
+
export DISABLE_AUTO_TITLE=true
|
|
141
|
+
__workspace_precmd() {
|
|
142
|
+
if [ -n "$__WORKSPACE_TAB_TITLE" ]; then
|
|
143
|
+
if [ "$PWD" = "$__WORKSPACE_TAB_DIR" ] || [[ "$PWD" = "$__WORKSPACE_TAB_DIR"/* ]]; then
|
|
144
|
+
printf '\033]0;%s\007' "$__WORKSPACE_TAB_TITLE"
|
|
145
|
+
printf '\033]1;%s\007' "$__WORKSPACE_TAB_TITLE"
|
|
146
|
+
__workspace_set_tab_color "$__WORKSPACE_TAB_R" "$__WORKSPACE_TAB_G" "$__WORKSPACE_TAB_B"
|
|
147
|
+
else
|
|
148
|
+
# Left the workspace — clear everything and restore defaults
|
|
149
|
+
unset __WORKSPACE_TAB_TITLE __WORKSPACE_TAB_DIR
|
|
150
|
+
unset __WORKSPACE_TAB_R __WORKSPACE_TAB_G __WORKSPACE_TAB_B
|
|
151
|
+
__workspace_reset_tab_color
|
|
152
|
+
# Restore previous DISABLE_AUTO_TITLE value
|
|
153
|
+
if [ -n "${__WORKSPACE_PREV_DISABLE_AUTO_TITLE:-}" ]; then
|
|
154
|
+
export DISABLE_AUTO_TITLE="$__WORKSPACE_PREV_DISABLE_AUTO_TITLE"
|
|
155
|
+
else
|
|
156
|
+
unset DISABLE_AUTO_TITLE
|
|
157
|
+
fi
|
|
158
|
+
unset __WORKSPACE_PREV_DISABLE_AUTO_TITLE
|
|
159
|
+
# Remove ourselves from precmd_functions
|
|
160
|
+
precmd_functions=(${precmd_functions:#__workspace_precmd})
|
|
161
|
+
fi
|
|
162
|
+
fi
|
|
163
|
+
}
|
|
164
|
+
# Add to precmd_functions array (zsh hook mechanism)
|
|
165
|
+
if (( ! ${precmd_functions[(Ie)__workspace_precmd]} )); then
|
|
166
|
+
precmd_functions+=(__workspace_precmd)
|
|
167
|
+
fi
|
|
168
|
+
elif [ -n "${BASH_VERSION:-}" ]; then
|
|
169
|
+
__workspace_prompt_command() {
|
|
170
|
+
if [ -n "$__WORKSPACE_TAB_TITLE" ]; then
|
|
171
|
+
if [ "$PWD" = "$__WORKSPACE_TAB_DIR" ] || [[ "$PWD" == "$__WORKSPACE_TAB_DIR"/* ]]; then
|
|
172
|
+
printf '\033]0;%s\007' "$__WORKSPACE_TAB_TITLE"
|
|
173
|
+
printf '\033]1;%s\007' "$__WORKSPACE_TAB_TITLE"
|
|
174
|
+
__workspace_set_tab_color "$__WORKSPACE_TAB_R" "$__WORKSPACE_TAB_G" "$__WORKSPACE_TAB_B"
|
|
175
|
+
else
|
|
176
|
+
# Left the workspace — clear everything and restore defaults
|
|
177
|
+
unset __WORKSPACE_TAB_TITLE __WORKSPACE_TAB_DIR
|
|
178
|
+
unset __WORKSPACE_TAB_R __WORKSPACE_TAB_G __WORKSPACE_TAB_B
|
|
179
|
+
__workspace_reset_tab_color
|
|
180
|
+
PROMPT_COMMAND="${PROMPT_COMMAND//__workspace_prompt_command;/}" 2>/dev/null || true
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
}
|
|
184
|
+
case "${PROMPT_COMMAND:-}" in
|
|
185
|
+
*__workspace_prompt_command*) ;;
|
|
186
|
+
*) PROMPT_COMMAND="__workspace_prompt_command;${PROMPT_COMMAND:-}" ;;
|
|
187
|
+
esac
|
|
188
|
+
fi
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# ── helper: detect configured AI agent ───────────────────────────────
|
|
192
|
+
# Reads primaryAgent from Nemus config and returns the CLI command.
|
|
193
|
+
# Falls back to 'claude' if config is missing or unreadable.
|
|
194
|
+
# Caches result for the shell session to avoid repeated node invocations.
|
|
195
|
+
__ws_cached_agent=""
|
|
196
|
+
__workspace_detect_agent() {
|
|
197
|
+
# Return cached result if available
|
|
198
|
+
if [ -n "$__ws_cached_agent" ]; then
|
|
199
|
+
echo "$__ws_cached_agent"
|
|
200
|
+
return
|
|
201
|
+
fi
|
|
202
|
+
# An explicit primaryAgent from config wins; otherwise we auto-detect.
|
|
203
|
+
local agent=""
|
|
204
|
+
if command -v node >/dev/null 2>&1; then
|
|
205
|
+
local cfg="$HOME/.workspace-manager-cache/config.json"
|
|
206
|
+
if [ -f "$cfg" ]; then
|
|
207
|
+
local ai
|
|
208
|
+
ai=$(CFG="$cfg" node -e '
|
|
209
|
+
try {
|
|
210
|
+
const c = JSON.parse(require("fs").readFileSync(process.env.CFG, "utf-8"));
|
|
211
|
+
console.log(c.primaryAgent || "auto");
|
|
212
|
+
} catch { console.log("auto"); }
|
|
213
|
+
' 2>/dev/null)
|
|
214
|
+
case "$ai" in
|
|
215
|
+
pi) agent="pi" ;;
|
|
216
|
+
opencode) agent="opencode" ;;
|
|
217
|
+
codex) agent="codex" ;;
|
|
218
|
+
gemini) agent="gemini" ;;
|
|
219
|
+
claude) agent="claude" ;;
|
|
220
|
+
# 'auto' (or anything else) falls through to the probe below.
|
|
221
|
+
esac
|
|
222
|
+
fi
|
|
223
|
+
fi
|
|
224
|
+
# No explicit choice (no config file, node unavailable, or primaryAgent=auto):
|
|
225
|
+
# probe for an installed agent in the same order as the TS getPrimaryAgent()
|
|
226
|
+
# 'auto' path (claude → pi → opencode → codex → gemini). This is what lets a
|
|
227
|
+
# Pi-only machine with no config actually launch the seeded prompt instead of
|
|
228
|
+
# silently defaulting to a claude that isn't installed.
|
|
229
|
+
if [ -z "$agent" ]; then
|
|
230
|
+
if command -v claude >/dev/null 2>&1; then
|
|
231
|
+
agent="claude"
|
|
232
|
+
elif command -v pi >/dev/null 2>&1; then
|
|
233
|
+
agent="pi"
|
|
234
|
+
elif command -v opencode >/dev/null 2>&1; then
|
|
235
|
+
agent="opencode"
|
|
236
|
+
elif command -v codex >/dev/null 2>&1; then
|
|
237
|
+
agent="codex"
|
|
238
|
+
elif command -v gemini >/dev/null 2>&1; then
|
|
239
|
+
agent="gemini"
|
|
240
|
+
else
|
|
241
|
+
agent="claude"
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
__ws_cached_agent="$agent"
|
|
245
|
+
echo "$agent"
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
# ── helper: run the real binary then handle CD ──────────────────────
|
|
249
|
+
__workspace_run() {
|
|
250
|
+
local bin="$1" # "nemus" or "nem"
|
|
251
|
+
shift
|
|
252
|
+
if [ $# -eq 0 ]; then
|
|
253
|
+
command "$bin"
|
|
254
|
+
return $?
|
|
255
|
+
fi
|
|
256
|
+
local cmd="$1"
|
|
257
|
+
shift
|
|
258
|
+
|
|
259
|
+
local temp_file="$HOME/.workspace-last-created"
|
|
260
|
+
local go_file="$HOME/.workspace-last-go"
|
|
261
|
+
local resume_file="$HOME/.workspace-resume-session"
|
|
262
|
+
local ai_prompt_file="$HOME/.workspace-ai-prompt"
|
|
263
|
+
|
|
264
|
+
# Classify the command
|
|
265
|
+
local is_create=false
|
|
266
|
+
local is_go=false
|
|
267
|
+
local is_ai=false
|
|
268
|
+
case "$cmd" in
|
|
269
|
+
create|c) is_create=true ;;
|
|
270
|
+
# Deprecated flat aliases that create workspaces
|
|
271
|
+
from-template|ft|from-suite|fs) is_create=true ;;
|
|
272
|
+
# AI prompt creates workspaces via MCP tools, then hands off
|
|
273
|
+
--) is_create=true; is_ai=true ;;
|
|
274
|
+
list|l|go|sessions|ses) is_go=true ;;
|
|
275
|
+
esac
|
|
276
|
+
# Grouped commands: "nemus suite use" / "nemus template use" — check second arg
|
|
277
|
+
if [ "$is_create" = false ]; then
|
|
278
|
+
case "$cmd" in
|
|
279
|
+
suite|template)
|
|
280
|
+
local sub="${1:-}"
|
|
281
|
+
if [ "$sub" = "use" ]; then
|
|
282
|
+
is_create=true
|
|
283
|
+
fi
|
|
284
|
+
;;
|
|
285
|
+
esac
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
# Detect --yes/-y (non-interactive mode): skip auto-launching the agent
|
|
289
|
+
# after workspace creation so one-shot/scripted invocations don't hang
|
|
290
|
+
# waiting on an interactive claude/pi/opencode session. Does not apply
|
|
291
|
+
# to the AI-prompt path ("nemus -- <prompt>"), which is interactive-only.
|
|
292
|
+
local skip_agent_launch=false
|
|
293
|
+
if [ "$is_create" = true ] && [ "$is_ai" = false ]; then
|
|
294
|
+
local arg
|
|
295
|
+
for arg in "$@"; do
|
|
296
|
+
case "$arg" in
|
|
297
|
+
-y|--yes) skip_agent_launch=true ;;
|
|
298
|
+
esac
|
|
299
|
+
done
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# Remove stale temp files before running
|
|
303
|
+
if [ "$is_create" = true ]; then
|
|
304
|
+
[ -f "$temp_file" ] && rm -f "$temp_file"
|
|
305
|
+
[ -f "$ai_prompt_file" ] && rm -f "$ai_prompt_file"
|
|
306
|
+
fi
|
|
307
|
+
if [ "$is_go" = true ]; then
|
|
308
|
+
[ -f "$go_file" ] && rm -f "$go_file"
|
|
309
|
+
[ -f "$resume_file" ] && rm -f "$resume_file"
|
|
310
|
+
fi
|
|
311
|
+
|
|
312
|
+
# Run the real binary
|
|
313
|
+
command "$bin" "$cmd" "$@"
|
|
314
|
+
local exit_code=$?
|
|
315
|
+
|
|
316
|
+
# For go-like commands, always CD if the go file exists (even after
|
|
317
|
+
# Ctrl+C in the fuzzy picker, which exits non-zero).
|
|
318
|
+
if [ "$is_go" = true ] && [ -f "$go_file" ]; then
|
|
319
|
+
local workspace_path
|
|
320
|
+
workspace_path=$(cat "$go_file")
|
|
321
|
+
rm -f "$go_file"
|
|
322
|
+
if [ -d "$workspace_path" ]; then
|
|
323
|
+
local ws_name
|
|
324
|
+
ws_name="$(basename "$workspace_path")"
|
|
325
|
+
echo ""
|
|
326
|
+
echo "📁 Changing directory to: $workspace_path"
|
|
327
|
+
cd "$workspace_path" || return 1
|
|
328
|
+
__workspace_set_tab_title "$ws_name"
|
|
329
|
+
local __ws_agent
|
|
330
|
+
__ws_agent=$(__workspace_detect_agent)
|
|
331
|
+
if command -v "$__ws_agent" >/dev/null 2>&1; then
|
|
332
|
+
# Check for resume file and read session's agent type.
|
|
333
|
+
# Resume file format: JSON { sessionId, agentType } (new) or plain sessionId (old).
|
|
334
|
+
# Old format gracefully falls back to configured agent type.
|
|
335
|
+
local resume_agent=""
|
|
336
|
+
if [ -f "$resume_file" ]; then
|
|
337
|
+
local resume_data
|
|
338
|
+
resume_data=$(cat "$resume_file")
|
|
339
|
+
rm -f "$resume_file"
|
|
340
|
+
# Default to configured agent (ensures --continue for old-format files)
|
|
341
|
+
resume_agent="$__ws_agent"
|
|
342
|
+
# Extract agentType from JSON resume file
|
|
343
|
+
local resume_agent_type
|
|
344
|
+
resume_agent_type=$(RESUME_DATA="$resume_data" node -e '
|
|
345
|
+
try {
|
|
346
|
+
const d = JSON.parse(process.env.RESUME_DATA);
|
|
347
|
+
console.log(d.agentType || "");
|
|
348
|
+
} catch { console.log(""); }
|
|
349
|
+
' 2>/dev/null)
|
|
350
|
+
# Override with session's agent type if available
|
|
351
|
+
if [ "$resume_agent_type" = "pi" ] && command -v pi >/dev/null 2>&1; then
|
|
352
|
+
resume_agent="pi"
|
|
353
|
+
elif [ "$resume_agent_type" = "opencode" ] && command -v opencode >/dev/null 2>&1; then
|
|
354
|
+
resume_agent="opencode"
|
|
355
|
+
elif [ "$resume_agent_type" = "claude" ] && command -v claude >/dev/null 2>&1; then
|
|
356
|
+
resume_agent="claude"
|
|
357
|
+
fi
|
|
358
|
+
fi
|
|
359
|
+
|
|
360
|
+
# Launch agent: with resume if file existed, otherwise fresh session
|
|
361
|
+
if [ -n "$resume_agent" ]; then
|
|
362
|
+
if [ "$resume_agent" = "pi" ]; then
|
|
363
|
+
pi --continue
|
|
364
|
+
elif [ "$resume_agent" = "opencode" ]; then
|
|
365
|
+
opencode --continue
|
|
366
|
+
else
|
|
367
|
+
claude --continue --name "$ws_name"
|
|
368
|
+
fi
|
|
369
|
+
else
|
|
370
|
+
# No resume file - fresh session
|
|
371
|
+
if [ "$__ws_agent" = "pi" ]; then
|
|
372
|
+
pi
|
|
373
|
+
elif [ "$__ws_agent" = "opencode" ]; then
|
|
374
|
+
opencode
|
|
375
|
+
else
|
|
376
|
+
claude --name "$ws_name"
|
|
377
|
+
fi
|
|
378
|
+
fi
|
|
379
|
+
fi
|
|
380
|
+
# Re-apply tab title after agent exits
|
|
381
|
+
__workspace_set_tab_title "$ws_name"
|
|
382
|
+
fi
|
|
383
|
+
fi
|
|
384
|
+
|
|
385
|
+
# For create-like commands, only CD on success
|
|
386
|
+
if [ $exit_code -eq 0 ] && [ "$is_create" = true ] && [ -f "$temp_file" ]; then
|
|
387
|
+
local workspace_path
|
|
388
|
+
workspace_path=$(cat "$temp_file")
|
|
389
|
+
rm -f "$temp_file"
|
|
390
|
+
if [ -d "$workspace_path" ]; then
|
|
391
|
+
local ws_name
|
|
392
|
+
ws_name="$(basename "$workspace_path")"
|
|
393
|
+
echo ""
|
|
394
|
+
echo "📁 Changing directory to: $workspace_path"
|
|
395
|
+
cd "$workspace_path" || return 1
|
|
396
|
+
__workspace_set_tab_title "$ws_name"
|
|
397
|
+
local __ws_agent
|
|
398
|
+
__ws_agent=$(__workspace_detect_agent)
|
|
399
|
+
if [ "$skip_agent_launch" = true ]; then
|
|
400
|
+
echo "🤖 Skipping agent auto-launch (--yes / non-interactive mode)"
|
|
401
|
+
elif command -v "$__ws_agent" >/dev/null 2>&1; then
|
|
402
|
+
if [ "$__ws_agent" = "claude" ]; then
|
|
403
|
+
if [ "$is_ai" = true ] && [ -f "$ai_prompt_file" ]; then
|
|
404
|
+
local original_prompt
|
|
405
|
+
original_prompt=$(cat "$ai_prompt_file")
|
|
406
|
+
rm -f "$ai_prompt_file"
|
|
407
|
+
claude --name "$ws_name" "$original_prompt"
|
|
408
|
+
else
|
|
409
|
+
claude --name "$ws_name"
|
|
410
|
+
fi
|
|
411
|
+
elif [ "$__ws_agent" = "opencode" ]; then
|
|
412
|
+
if [ "$is_ai" = true ] && [ -f "$ai_prompt_file" ]; then
|
|
413
|
+
local original_prompt
|
|
414
|
+
original_prompt=$(cat "$ai_prompt_file")
|
|
415
|
+
rm -f "$ai_prompt_file"
|
|
416
|
+
opencode run "$original_prompt"
|
|
417
|
+
else
|
|
418
|
+
opencode
|
|
419
|
+
fi
|
|
420
|
+
else
|
|
421
|
+
if [ "$is_ai" = true ] && [ -f "$ai_prompt_file" ]; then
|
|
422
|
+
local original_prompt
|
|
423
|
+
original_prompt=$(cat "$ai_prompt_file")
|
|
424
|
+
rm -f "$ai_prompt_file"
|
|
425
|
+
# Interactive mode with initial prompt (positional arg)
|
|
426
|
+
pi "$original_prompt"
|
|
427
|
+
else
|
|
428
|
+
pi
|
|
429
|
+
fi
|
|
430
|
+
fi
|
|
431
|
+
fi
|
|
432
|
+
# Re-apply tab title after agent exits
|
|
433
|
+
__workspace_set_tab_title "$ws_name"
|
|
434
|
+
fi
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
# Clean up ai prompt file if it wasn't consumed (e.g. no workspace was created)
|
|
438
|
+
[ -f "$ai_prompt_file" ] && rm -f "$ai_prompt_file"
|
|
439
|
+
|
|
440
|
+
return $exit_code
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
# ── public wrappers ─────────────────────────────────────────────────
|
|
444
|
+
nemus() { __workspace_run nemus "$@"; }
|
|
445
|
+
nem() { __workspace_run nem "$@"; }
|
|
446
|
+
|
|
447
|
+
# Quick navigation to workspace with fuzzy search
|
|
448
|
+
nemgo() {
|
|
449
|
+
local temp_file="$HOME/.workspace-last-go"
|
|
450
|
+
[ -f "$temp_file" ] && rm -f "$temp_file"
|
|
451
|
+
|
|
452
|
+
command nemus go "$@"
|
|
453
|
+
local exit_code=$?
|
|
454
|
+
|
|
455
|
+
if [ -f "$temp_file" ]; then
|
|
456
|
+
local workspace_path
|
|
457
|
+
workspace_path=$(cat "$temp_file")
|
|
458
|
+
rm -f "$temp_file"
|
|
459
|
+
if [ -d "$workspace_path" ]; then
|
|
460
|
+
local ws_name
|
|
461
|
+
ws_name="$(basename "$workspace_path")"
|
|
462
|
+
cd "$workspace_path" || return 1
|
|
463
|
+
__workspace_set_tab_title "$ws_name"
|
|
464
|
+
local __ws_agent
|
|
465
|
+
__ws_agent=$(__workspace_detect_agent)
|
|
466
|
+
if command -v "$__ws_agent" >/dev/null 2>&1; then
|
|
467
|
+
if [ "$__ws_agent" = "claude" ]; then
|
|
468
|
+
claude --name "$ws_name"
|
|
469
|
+
elif [ "$__ws_agent" = "opencode" ]; then
|
|
470
|
+
opencode
|
|
471
|
+
else
|
|
472
|
+
pi
|
|
473
|
+
fi
|
|
474
|
+
fi
|
|
475
|
+
__workspace_set_tab_title "$ws_name"
|
|
476
|
+
fi
|
|
477
|
+
fi
|
|
478
|
+
|
|
479
|
+
return $exit_code
|
|
480
|
+
}
|
|
481
|
+
EOF
|
|
482
|
+
|
|
483
|
+
# Determine RC file based on shell type
|
|
484
|
+
if [ "$SHELL_TYPE" = "bash" ]; then
|
|
485
|
+
RC_FILE="$HOME/.bashrc"
|
|
486
|
+
elif [ "$SHELL_TYPE" = "zsh" ]; then
|
|
487
|
+
RC_FILE="$HOME/.zshrc"
|
|
488
|
+
else
|
|
489
|
+
echo "❌ Unsupported shell: $SHELL_TYPE"
|
|
490
|
+
echo "Supported shells: bash, zsh"
|
|
491
|
+
exit 1
|
|
492
|
+
fi
|
|
493
|
+
|
|
494
|
+
# Check if already installed (version marker is in the grep below)
|
|
495
|
+
if grep -q "Shell Integration (v50)" "$RC_FILE" 2>/dev/null; then
|
|
496
|
+
echo "✅ Shell integration already up to date in $RC_FILE"
|
|
497
|
+
elif grep -q "# Nemus - Shell Integration" "$RC_FILE" 2>/dev/null; then
|
|
498
|
+
# Old version installed — remove it and install new version
|
|
499
|
+
echo "🔄 Upgrading shell integration in $RC_FILE..."
|
|
500
|
+
TMPFILE=$(mktemp)
|
|
501
|
+
awk -f "$SCRIPT_DIR/remove-shell-block.awk" "$RC_FILE" > "$TMPFILE"
|
|
502
|
+
# Append new shell integration to temp file so mv is atomic
|
|
503
|
+
echo "" >> "$TMPFILE"
|
|
504
|
+
echo "$SHELL_FUNCTION" >> "$TMPFILE"
|
|
505
|
+
cp "$RC_FILE" "${RC_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
506
|
+
chmod --reference="$RC_FILE" "$TMPFILE" 2>/dev/null || chmod "$(stat -f '%Lp' "$RC_FILE")" "$TMPFILE" 2>/dev/null || true
|
|
507
|
+
mv "$TMPFILE" "$RC_FILE"
|
|
508
|
+
|
|
509
|
+
echo "✅ Shell integration upgraded in $RC_FILE"
|
|
510
|
+
else
|
|
511
|
+
# Backup RC file if it exists
|
|
512
|
+
if [ -f "$RC_FILE" ]; then
|
|
513
|
+
cp "$RC_FILE" "${RC_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
514
|
+
echo "📦 Backup created: ${RC_FILE}.backup.*"
|
|
515
|
+
fi
|
|
516
|
+
|
|
517
|
+
# Append shell function (creates the file if it doesn't exist)
|
|
518
|
+
echo "" >> "$RC_FILE"
|
|
519
|
+
echo "$SHELL_FUNCTION" >> "$RC_FILE"
|
|
520
|
+
|
|
521
|
+
echo "✅ Shell integration installed in $RC_FILE"
|
|
522
|
+
echo ""
|
|
523
|
+
echo "To activate, run:"
|
|
524
|
+
echo " source $RC_FILE"
|
|
525
|
+
echo ""
|
|
526
|
+
echo "Or restart your terminal."
|
|
527
|
+
fi
|
|
528
|
+
|
|
529
|
+
echo ""
|
|
530
|
+
echo "After activation:"
|
|
531
|
+
echo " • 'nemus create' / 'nemus list' will automatically CD to the workspace! 🚀"
|
|
532
|
+
echo " • 'nemgo' command for quick navigation with fuzzy search! 🔍"
|