claws-code 0.8.0
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/.claude/commands/claws-auto.md +90 -0
- package/.claude/commands/claws-bin.md +28 -0
- package/.claude/commands/claws-cleanup.md +28 -0
- package/.claude/commands/claws-do.md +82 -0
- package/.claude/commands/claws-fix.md +40 -0
- package/.claude/commands/claws-goal.md +111 -0
- package/.claude/commands/claws-help.md +54 -0
- package/.claude/commands/claws-plan.md +103 -0
- package/.claude/commands/claws-report.md +29 -0
- package/.claude/commands/claws-status.md +37 -0
- package/.claude/commands/claws-update.md +32 -0
- package/.claude/commands/claws.md +64 -0
- package/.claude/rules/claws-default-behavior.md +76 -0
- package/.claude/settings.json +112 -0
- package/.claude/settings.local.json +19 -0
- package/.claude/skills/claws-auto-engine/SKILL.md +97 -0
- package/.claude/skills/claws-goal-tracker/SKILL.md +106 -0
- package/.claude/skills/claws-prompt-templates/SKILL.md +203 -0
- package/.claude/skills/claws-wave-lead/SKILL.md +126 -0
- package/.claude/skills/claws-wave-subworker/SKILL.md +60 -0
- package/CHANGELOG.md +1949 -0
- package/LICENSE +21 -0
- package/README.md +420 -0
- package/bin/cli.js +84 -0
- package/cli.js +223 -0
- package/docs/ARCHITECTURE.md +511 -0
- package/docs/event-protocol.md +588 -0
- package/docs/features.md +562 -0
- package/docs/guide.md +891 -0
- package/docs/index.html +716 -0
- package/docs/protocol.md +323 -0
- package/extension/.vscodeignore +15 -0
- package/extension/CHANGELOG.md +1906 -0
- package/extension/LICENSE +21 -0
- package/extension/README.md +137 -0
- package/extension/docs/features.md +424 -0
- package/extension/docs/protocol.md +197 -0
- package/extension/esbuild.mjs +25 -0
- package/extension/icon.png +0 -0
- package/extension/native/.metadata.json +10 -0
- package/extension/native/node-pty/LICENSE +69 -0
- package/extension/native/node-pty/README.md +165 -0
- package/extension/native/node-pty/lib/conpty_console_list_agent.js +16 -0
- package/extension/native/node-pty/lib/conpty_console_list_agent.js.map +1 -0
- package/extension/native/node-pty/lib/eventEmitter2.js +47 -0
- package/extension/native/node-pty/lib/eventEmitter2.js.map +1 -0
- package/extension/native/node-pty/lib/index.js +52 -0
- package/extension/native/node-pty/lib/index.js.map +1 -0
- package/extension/native/node-pty/lib/interfaces.js +7 -0
- package/extension/native/node-pty/lib/interfaces.js.map +1 -0
- package/extension/native/node-pty/lib/shared/conout.js +11 -0
- package/extension/native/node-pty/lib/shared/conout.js.map +1 -0
- package/extension/native/node-pty/lib/terminal.js +190 -0
- package/extension/native/node-pty/lib/terminal.js.map +1 -0
- package/extension/native/node-pty/lib/types.js +7 -0
- package/extension/native/node-pty/lib/types.js.map +1 -0
- package/extension/native/node-pty/lib/unixTerminal.js +346 -0
- package/extension/native/node-pty/lib/unixTerminal.js.map +1 -0
- package/extension/native/node-pty/lib/utils.js +39 -0
- package/extension/native/node-pty/lib/utils.js.map +1 -0
- package/extension/native/node-pty/lib/windowsConoutConnection.js +125 -0
- package/extension/native/node-pty/lib/windowsConoutConnection.js.map +1 -0
- package/extension/native/node-pty/lib/windowsPtyAgent.js +320 -0
- package/extension/native/node-pty/lib/windowsPtyAgent.js.map +1 -0
- package/extension/native/node-pty/lib/windowsTerminal.js +199 -0
- package/extension/native/node-pty/lib/windowsTerminal.js.map +1 -0
- package/extension/native/node-pty/lib/worker/conoutSocketWorker.js +22 -0
- package/extension/native/node-pty/lib/worker/conoutSocketWorker.js.map +1 -0
- package/extension/native/node-pty/package.json +64 -0
- package/extension/native/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/extension/native/node-pty/prebuilds/darwin-x64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/winpty-agent.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/winpty.dll +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/winpty-agent.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/winpty.dll +0 -0
- package/extension/package-lock.json +605 -0
- package/extension/package.json +343 -0
- package/extension/scripts/bundle-native.mjs +104 -0
- package/extension/scripts/deploy-dev.mjs +60 -0
- package/extension/src/ansi-strip.ts +52 -0
- package/extension/src/backends/vscode/claws-pty.ts +483 -0
- package/extension/src/backends/vscode/status-bar.ts +99 -0
- package/extension/src/backends/vscode/vscode-backend.ts +282 -0
- package/extension/src/capture-store.ts +125 -0
- package/extension/src/event-log.ts +629 -0
- package/extension/src/event-schemas.ts +478 -0
- package/extension/src/extension.js +492 -0
- package/extension/src/extension.ts +873 -0
- package/extension/src/lifecycle-engine.ts +60 -0
- package/extension/src/lifecycle-rules.ts +171 -0
- package/extension/src/lifecycle-store.ts +506 -0
- package/extension/src/peer-registry.ts +176 -0
- package/extension/src/pipeline-registry.ts +82 -0
- package/extension/src/platform.ts +64 -0
- package/extension/src/protocol.ts +532 -0
- package/extension/src/server-config.ts +98 -0
- package/extension/src/server.ts +2210 -0
- package/extension/src/task-registry.ts +51 -0
- package/extension/src/terminal-backend.ts +211 -0
- package/extension/src/terminal-manager.ts +395 -0
- package/extension/src/topic-registry.ts +70 -0
- package/extension/src/topic-utils.ts +46 -0
- package/extension/src/transport.ts +45 -0
- package/extension/src/uninstall-cleanup.ts +232 -0
- package/extension/src/wave-registry.ts +314 -0
- package/extension/src/websocket-transport.ts +153 -0
- package/extension/tsconfig.json +23 -0
- package/lib/capabilities.js +145 -0
- package/lib/dry-run.js +43 -0
- package/lib/install.js +1018 -0
- package/lib/mcp-setup.js +92 -0
- package/lib/platform.js +240 -0
- package/lib/preflight.js +152 -0
- package/lib/shell-hook.js +343 -0
- package/lib/uninstall.js +162 -0
- package/lib/verify.js +166 -0
- package/mcp_server.js +3529 -0
- package/package.json +48 -0
- package/rules/claws-default-behavior.md +72 -0
- package/scripts/_helpers/atomic-file.mjs +137 -0
- package/scripts/_helpers/fix-repair.js +64 -0
- package/scripts/_helpers/json-safe.mjs +218 -0
- package/scripts/bump-version.sh +84 -0
- package/scripts/codegen/gen-docs.mjs +61 -0
- package/scripts/codegen/gen-json-schema.mjs +62 -0
- package/scripts/codegen/gen-mcp-tools.mjs +358 -0
- package/scripts/codegen/gen-types.mjs +172 -0
- package/scripts/codegen/index.mjs +42 -0
- package/scripts/dev-hooks/check-extension-dirs.js +77 -0
- package/scripts/dev-hooks/check-open-claws-terminals.js +70 -0
- package/scripts/dev-hooks/check-stale-main.js +55 -0
- package/scripts/dev-hooks/check-tag-pushed.js +51 -0
- package/scripts/dev-hooks/check-tag-vs-main.js +56 -0
- package/scripts/dev-vsix-install.sh +60 -0
- package/scripts/fix.sh +702 -0
- package/scripts/gen-client-types.mjs +81 -0
- package/scripts/git-hooks/pre-commit +31 -0
- package/scripts/hooks/lifecycle-state.js +61 -0
- package/scripts/hooks/package.json +4 -0
- package/scripts/hooks/post-tool-use-claws.js +292 -0
- package/scripts/hooks/pre-bash-no-verify-block.js +72 -0
- package/scripts/hooks/pre-tool-use-claws.js +206 -0
- package/scripts/hooks/session-start-claws.js +97 -0
- package/scripts/hooks/stop-claws.js +88 -0
- package/scripts/inject-claude-md.js +205 -0
- package/scripts/inject-dev-hooks.js +96 -0
- package/scripts/inject-global-claude-md.js +140 -0
- package/scripts/inject-settings-hooks.js +370 -0
- package/scripts/install.ps1 +146 -0
- package/scripts/install.sh +1729 -0
- package/scripts/monitor-arm-watch.js +155 -0
- package/scripts/rebuild-node-pty.sh +245 -0
- package/scripts/report.sh +232 -0
- package/scripts/shell-hook.fish +164 -0
- package/scripts/shell-hook.ps1 +33 -0
- package/scripts/shell-hook.sh +232 -0
- package/scripts/stream-events.js +399 -0
- package/scripts/terminal-wrapper.sh +36 -0
- package/scripts/test-enforcement.sh +132 -0
- package/scripts/test-install.sh +174 -0
- package/scripts/test-installer-parity.sh +135 -0
- package/scripts/test-template-enforcement.sh +76 -0
- package/scripts/uninstall.sh +143 -0
- package/scripts/update.sh +337 -0
- package/scripts/verify-release.sh +323 -0
- package/scripts/verify-wrapped.sh +194 -0
- package/templates/CLAUDE.global.md +135 -0
- package/templates/CLAUDE.project.md +37 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# CLAWS — Terminal Control Bridge
|
|
2
|
+
# Native fish hook — sourced from ~/.config/fish/conf.d/claws.fish
|
|
3
|
+
# No bass dependency. Pure fish syntax.
|
|
4
|
+
|
|
5
|
+
if not status is-interactive
|
|
6
|
+
exit
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Avoid showing banner more than once per session
|
|
10
|
+
if set -q CLAWS_BANNER_SHOWN
|
|
11
|
+
# Still define functions even if banner already shown
|
|
12
|
+
else
|
|
13
|
+
set -gx CLAWS_BANNER_SHOWN 1
|
|
14
|
+
|
|
15
|
+
# Detect socket status.
|
|
16
|
+
# Walk up from $PWD — the extension creates the socket at
|
|
17
|
+
# <workspace-root>/.claws/claws.sock, not relative to $PWD.
|
|
18
|
+
set -l sock ""
|
|
19
|
+
if test -n "$CLAWS_SOCKET"
|
|
20
|
+
set sock $CLAWS_SOCKET
|
|
21
|
+
else
|
|
22
|
+
set -l _walk (pwd)
|
|
23
|
+
while test -n "$_walk"; and test "$_walk" != "/"
|
|
24
|
+
if test -S "$_walk/.claws/claws.sock"
|
|
25
|
+
set sock "$_walk/.claws/claws.sock"
|
|
26
|
+
break
|
|
27
|
+
end
|
|
28
|
+
set -l _parent (dirname $_walk)
|
|
29
|
+
if test "$_parent" = "$_walk"
|
|
30
|
+
break
|
|
31
|
+
end
|
|
32
|
+
set _walk $_parent
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
set -l claws_status ""
|
|
36
|
+
set -l claws_terms "-"
|
|
37
|
+
|
|
38
|
+
if test -n "$sock"; and test -S $sock
|
|
39
|
+
set claws_status "\033[32m● connected\033[0m"
|
|
40
|
+
set claws_terms (node -e "
|
|
41
|
+
const net=require('net');
|
|
42
|
+
const s=net.createConnection('$sock');
|
|
43
|
+
s.on('connect',()=>s.write(JSON.stringify({id:0,cmd:'list'})+'\n'));
|
|
44
|
+
let b='';
|
|
45
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){try{process.stdout.write(String(JSON.parse(b.split('\n')[0]).terminals.length))}catch(e){process.stdout.write('?')};s.destroy()}});
|
|
46
|
+
s.on('error',()=>{process.stdout.write('?');s.destroy()});
|
|
47
|
+
setTimeout(()=>{process.stdout.write('?');s.destroy()},2000);
|
|
48
|
+
" 2>/dev/null; or echo "?")
|
|
49
|
+
else
|
|
50
|
+
set claws_status "\033[33m○ socket not found\033[0m"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Detect wrapped
|
|
54
|
+
set -l claws_wrap ""
|
|
55
|
+
if test -n "$CLAWS_WRAPPED" && test "$CLAWS_WRAPPED" = "1"
|
|
56
|
+
set claws_wrap "\033[32m● wrapped\033[0m (pty logged)"
|
|
57
|
+
else
|
|
58
|
+
set claws_wrap "\033[90m○ unwrapped\033[0m"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
set -l T "\033[38;2;200;90;62m"
|
|
62
|
+
set -l W "\033[1;37m"
|
|
63
|
+
set -l D "\033[90m"
|
|
64
|
+
set -l R "\033[0m"
|
|
65
|
+
|
|
66
|
+
printf "\n"
|
|
67
|
+
printf " $T╔═══════════════════════════════════════════════╗$R\n"
|
|
68
|
+
printf " $T║$R $T║$R\n"
|
|
69
|
+
printf " $T║$R $T ██████╗██╗ █████╗ ██╗ ██╗███████╗$R $T║$R\n"
|
|
70
|
+
printf " $T║$R $T██╔════╝██║ ██╔══██╗██║ ██║██╔════╝$R $T║$R\n"
|
|
71
|
+
printf " $T║$R $T██║ ██║ ███████║██║ █╗ ██║███████╗$R $T║$R\n"
|
|
72
|
+
printf " $T║$R $T██║ ██║ ██╔══██║██║███╗██║╚════██║$R $T║$R\n"
|
|
73
|
+
printf " $T║$R $T╚██████╗███████╗██║ ██║╚███╔███╔╝███████║$R $T║$R\n"
|
|
74
|
+
printf " $T║$R $T ╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝$R $T║$R\n"
|
|
75
|
+
printf " $T║$R $T║$R\n"
|
|
76
|
+
printf " $T║$R ${D}Terminal Control Bridge$R $T║$R\n"
|
|
77
|
+
printf " $T║$R $T║$R\n"
|
|
78
|
+
printf " $T║$R Bridge: $claws_status $T║$R\n"
|
|
79
|
+
printf " $T║$R Terminals: $W$claws_terms$R active $T║$R\n"
|
|
80
|
+
printf " $T║$R This term: $claws_wrap $T║$R\n"
|
|
81
|
+
printf " $T║$R $T║$R\n"
|
|
82
|
+
printf " $T║$R ${D}claws-ls$R list terminals $T║$R\n"
|
|
83
|
+
printf " $T║$R ${D}claws-new$R create wrapped terminal $T║$R\n"
|
|
84
|
+
printf " $T║$R ${D}claws-run$R exec command in terminal $T║$R\n"
|
|
85
|
+
printf " $T║$R ${D}claws-log$R read wrapped terminal log $T║$R\n"
|
|
86
|
+
printf " $T║$R $T║$R\n"
|
|
87
|
+
printf " $T╚═══════════════════════════════════════════════╝$R\n"
|
|
88
|
+
printf "\n"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# ── Shell functions ─────────────────────────────────────────────────────────
|
|
92
|
+
|
|
93
|
+
function _claws_find_sock
|
|
94
|
+
if test -n "$CLAWS_SOCKET"
|
|
95
|
+
echo $CLAWS_SOCKET; return
|
|
96
|
+
end
|
|
97
|
+
set -l _w (pwd)
|
|
98
|
+
while test -n "$_w"; and test "$_w" != "/"
|
|
99
|
+
if test -S "$_w/.claws/claws.sock"
|
|
100
|
+
echo "$_w/.claws/claws.sock"; return
|
|
101
|
+
end
|
|
102
|
+
set -l _p (dirname $_w)
|
|
103
|
+
if test "$_p" = "$_w"
|
|
104
|
+
break
|
|
105
|
+
end
|
|
106
|
+
set _w $_p
|
|
107
|
+
end
|
|
108
|
+
echo ".claws/claws.sock"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
function claws-ls
|
|
112
|
+
set -l sock (_claws_find_sock)
|
|
113
|
+
node -e "
|
|
114
|
+
const net=require('net');
|
|
115
|
+
const s=net.createConnection('$sock');
|
|
116
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'list'})+'\n'));
|
|
117
|
+
let b='';
|
|
118
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){try{const d2=JSON.parse(b.split('\n')[0]);(d2.terminals||[]).forEach(t=>{const w=t.logPath?'WRAPPED':' ';const a=t.active?'*':' ';console.log(a+' '+String(t.id).padStart(3)+' '+String(t.name||'').padEnd(25)+' pid='+t.pid+' ['+w+']')})}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
119
|
+
s.on('error',e=>{console.log('error: '+e.message+' — is the Claws extension running?');s.destroy()});
|
|
120
|
+
setTimeout(()=>{console.log('error: timeout');s.destroy()},5000);
|
|
121
|
+
" 2>/dev/null; or echo "error: node not available"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
function claws-new
|
|
125
|
+
set -l name (test -n "$argv[1]" && echo $argv[1] || echo "claws")
|
|
126
|
+
set -l sock (_claws_find_sock)
|
|
127
|
+
node -e "
|
|
128
|
+
const net=require('net');
|
|
129
|
+
const s=net.createConnection('$sock');
|
|
130
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'create',name:'$name',wrapped:true})+'\n'));
|
|
131
|
+
let b='';
|
|
132
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){try{const r=JSON.parse(b.split('\n')[0]);console.log('created terminal id='+r.id+(r.logPath?' log='+r.logPath:''))}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
133
|
+
s.on('error',e=>{console.log('error: '+e.message);s.destroy()});
|
|
134
|
+
setTimeout(()=>{console.log('error: timeout');s.destroy()},5000);
|
|
135
|
+
" 2>/dev/null; or echo "error: node not available"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
function claws-run
|
|
139
|
+
set -l cmd (string join " " $argv)
|
|
140
|
+
set -l sock (_claws_find_sock)
|
|
141
|
+
node -e "
|
|
142
|
+
const net=require('net');
|
|
143
|
+
const s=net.createConnection('$sock');
|
|
144
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'exec',command:'$cmd'})+'\n'));
|
|
145
|
+
let b='';
|
|
146
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){try{const r=JSON.parse(b.split('\n')[0]);console.log(r.output||'');process.exit(r.exitCode||0)}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
147
|
+
s.on('error',e=>{console.log('error: '+e.message);s.destroy()});
|
|
148
|
+
setTimeout(()=>{console.log('error: timeout');s.destroy()},30000);
|
|
149
|
+
" 2>/dev/null; or echo "error: node not available"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
function claws-log
|
|
153
|
+
set -l id $argv[1]
|
|
154
|
+
set -l sock (_claws_find_sock)
|
|
155
|
+
node -e "
|
|
156
|
+
const net=require('net');
|
|
157
|
+
const s=net.createConnection('$sock');
|
|
158
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'readLog',id:'$id',strip:true})+'\n'));
|
|
159
|
+
let b='';
|
|
160
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){try{const r=JSON.parse(b.split('\n')[0]);process.stdout.write(r.bytes||'')}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
161
|
+
s.on('error',e=>{console.log('error: '+e.message);s.destroy()});
|
|
162
|
+
setTimeout(()=>{console.log('error: timeout');s.destroy()},5000);
|
|
163
|
+
" 2>/dev/null; or echo "error: node not available"
|
|
164
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# CLAWS terminal hook (auto-generated — do not edit)
|
|
2
|
+
# Sourced from $PROFILE on PowerShell startup.
|
|
3
|
+
# Only shows banner when running inside a Claws-wrapped terminal.
|
|
4
|
+
# CLAWS_WRAPPED is set by the VS Code extension (claws-pty.ts) when a real
|
|
5
|
+
# pty session is active; it is never set in ordinary PowerShell sessions.
|
|
6
|
+
|
|
7
|
+
if ($env:CLAWS_WRAPPED -ne '1') { return }
|
|
8
|
+
if ($env:CLAWS_BANNER_SHOWN -eq '1') { return }
|
|
9
|
+
$env:CLAWS_BANNER_SHOWN = '1'
|
|
10
|
+
|
|
11
|
+
# ASCII-only banner — Unicode box chars render as ? in PS 5.1 / legacy CP437 consoles.
|
|
12
|
+
# Matches install.ps1 format.
|
|
13
|
+
Write-Host ""
|
|
14
|
+
Write-Host " +-------------------------------------------+" -ForegroundColor DarkYellow
|
|
15
|
+
Write-Host " | |" -ForegroundColor DarkYellow
|
|
16
|
+
Write-Host " | CLAWS Terminal Control Bridge |" -ForegroundColor DarkYellow
|
|
17
|
+
Write-Host " | |" -ForegroundColor DarkYellow
|
|
18
|
+
Write-Host " +-------------------------------------------+" -ForegroundColor DarkYellow
|
|
19
|
+
Write-Host ""
|
|
20
|
+
|
|
21
|
+
# Wrap / pipe-mode state
|
|
22
|
+
$_wrapState = if ($env:CLAWS_PIPE_MODE -eq '1') {
|
|
23
|
+
"pipe-mode (degraded)"
|
|
24
|
+
} else {
|
|
25
|
+
"wrapped (pty logged)"
|
|
26
|
+
}
|
|
27
|
+
Write-Host (" This term " + $_wrapState)
|
|
28
|
+
if ($env:CLAWS_TERMINAL_ID) {
|
|
29
|
+
Write-Host (" Term ID " + $env:CLAWS_TERMINAL_ID) -ForegroundColor DarkGray
|
|
30
|
+
}
|
|
31
|
+
Write-Host ""
|
|
32
|
+
|
|
33
|
+
Remove-Variable -Name '_wrapState' -ErrorAction SilentlyContinue
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# ═══════════════════════════════════════════════════════════════
|
|
2
|
+
# CLAWS — Terminal Control Bridge
|
|
3
|
+
# This hook is sourced by .zshrc/.bashrc after install.
|
|
4
|
+
# It displays a startup banner and adds claws shell functions.
|
|
5
|
+
# ═══════════════════════════════════════════════════════════════
|
|
6
|
+
|
|
7
|
+
# Export CLAWS_DIR so slash commands (/claws-fix, /claws-update) can locate scripts
|
|
8
|
+
# without hardcoding ~/.claws-src. Shell-hook.sh lives at $INSTALL_DIR/scripts/,
|
|
9
|
+
# so we walk up one level to get the repo root.
|
|
10
|
+
if [ -z "${CLAWS_DIR:-}" ]; then
|
|
11
|
+
_hook_dir=""
|
|
12
|
+
[ -n "${BASH_SOURCE[0]:-}" ] && _hook_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd -P)"
|
|
13
|
+
[ -z "$_hook_dir" ] && [ -n "${ZSH_SCRIPT:-}" ] && _hook_dir="$(cd "$(dirname "$ZSH_SCRIPT")" 2>/dev/null && pwd -P)"
|
|
14
|
+
if [ -n "$_hook_dir" ]; then
|
|
15
|
+
export CLAWS_DIR="${_hook_dir%/scripts}"
|
|
16
|
+
else
|
|
17
|
+
export CLAWS_DIR="$HOME/.claws-src"
|
|
18
|
+
fi
|
|
19
|
+
unset _hook_dir
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Only show banner in interactive shells
|
|
23
|
+
if [[ $- == *i* ]] && [[ -z "${CLAWS_BANNER_SHOWN:-}" ]]; then
|
|
24
|
+
# NOTE: do NOT export — the flag must scope to the current shell only.
|
|
25
|
+
# Exporting leaks into every child process (including VS Code itself if
|
|
26
|
+
# VS Code was launched from a banner-painted shell), and every terminal
|
|
27
|
+
# VS Code spawns inherits the flag pre-set, suppressing the banner
|
|
28
|
+
# forever in that window. Plain shell variable: child processes start
|
|
29
|
+
# fresh and paint their own banner once.
|
|
30
|
+
CLAWS_BANNER_SHOWN=1
|
|
31
|
+
|
|
32
|
+
# ── Version: CLAWS_VERSION env > nearest package.json from script dir ──
|
|
33
|
+
if [ -n "${CLAWS_VERSION:-}" ]; then
|
|
34
|
+
_CLAWS_VERSION="$CLAWS_VERSION"
|
|
35
|
+
elif command -v node >/dev/null 2>&1; then
|
|
36
|
+
# BASH_SOURCE[0] in bash; ZSH_SCRIPT (zsh 5.3+) in zsh; fallback to common install path
|
|
37
|
+
_csd=""
|
|
38
|
+
[ -n "${BASH_SOURCE[0]:-}" ] && _csd="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd -P)"
|
|
39
|
+
[ -z "$_csd" ] && [ -n "${ZSH_SCRIPT:-}" ] && _csd="$(cd "$(dirname "$ZSH_SCRIPT")" 2>/dev/null && pwd -P)"
|
|
40
|
+
[ -z "$_csd" ] && _csd="$HOME/.claws-src/scripts"
|
|
41
|
+
_CLAWS_VERSION=$(node -e "
|
|
42
|
+
const path=require('path'),fs=require('fs');
|
|
43
|
+
let d=path.resolve('$_csd');
|
|
44
|
+
for(let i=0;i<8&&d&&d!=='/';i++,d=path.dirname(d)){
|
|
45
|
+
try{const v=JSON.parse(fs.readFileSync(path.join(d,'package.json'),'utf8')).version;
|
|
46
|
+
if(v){process.stdout.write(v);process.exit(0)}}catch(e){}
|
|
47
|
+
}
|
|
48
|
+
process.stdout.write('?.?.?');
|
|
49
|
+
" 2>/dev/null || echo "?.?.?")
|
|
50
|
+
unset _csd
|
|
51
|
+
else
|
|
52
|
+
_CLAWS_VERSION="?.?.?"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# ── Socket detection ──
|
|
56
|
+
CLAWS_SOCK="${CLAWS_SOCKET:-}"
|
|
57
|
+
if [ -z "$CLAWS_SOCK" ]; then
|
|
58
|
+
_walk="$PWD"
|
|
59
|
+
while [ -n "$_walk" ] && [ "$_walk" != "/" ]; do
|
|
60
|
+
if [ -S "$_walk/.claws/claws.sock" ]; then
|
|
61
|
+
CLAWS_SOCK="$_walk/.claws/claws.sock"
|
|
62
|
+
break
|
|
63
|
+
fi
|
|
64
|
+
_walk="${_walk%/*}"
|
|
65
|
+
done
|
|
66
|
+
unset _walk
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# ── Colors (ANSI-C quoting — expand cleanly in printf) ──
|
|
70
|
+
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
|
|
71
|
+
_GRN=$'\033[32m'; _AMB=$'\033[33m'
|
|
72
|
+
_ORG=$'\033[38;5;208m'; _BLD=$'\033[1;37m'; _DIM=$'\033[2m'; _RST=$'\033[0m'
|
|
73
|
+
else
|
|
74
|
+
_GRN=''; _AMB=''; _ORG=''; _BLD=''; _DIM=''; _RST=''
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# ── Bridge status ──
|
|
78
|
+
if [ -S "${CLAWS_SOCK:-}" ] 2>/dev/null; then
|
|
79
|
+
_bstxt="● connected"
|
|
80
|
+
_bsansi="${_GRN}● connected${_RST}"
|
|
81
|
+
_CLAWS_TERMS=$(node -e "
|
|
82
|
+
const net=require('net');
|
|
83
|
+
const s=net.createConnection('$CLAWS_SOCK');
|
|
84
|
+
let done=false;
|
|
85
|
+
const finish=(out)=>{if(done)return;done=true;process.stdout.write(out);try{s.destroy()}catch(e){};process.exit(0)};
|
|
86
|
+
s.on('connect',()=>s.write(JSON.stringify({id:0,cmd:'list'})+'\n'));
|
|
87
|
+
let b='';
|
|
88
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){
|
|
89
|
+
try{finish(String(JSON.parse(b.split('\n')[0]).terminals.length))}
|
|
90
|
+
catch(e){finish('?')}}});
|
|
91
|
+
s.on('error',()=>finish('?'));
|
|
92
|
+
setTimeout(()=>finish('?'),2000);
|
|
93
|
+
" 2>/dev/null || echo "?")
|
|
94
|
+
else
|
|
95
|
+
_bstxt="○ socket not found"
|
|
96
|
+
_bsansi="${_AMB}○ socket not found${_RST}"
|
|
97
|
+
_CLAWS_TERMS="-"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# ── Wrap / pipe-mode state ──
|
|
101
|
+
if [ "${CLAWS_WRAPPED:-}" = "1" ]; then
|
|
102
|
+
if [ "${CLAWS_PIPE_MODE:-}" = "1" ]; then
|
|
103
|
+
_wrtxt="◑ pipe-mode (degraded)"
|
|
104
|
+
_wransi="${_AMB}◑ pipe-mode (degraded)${_RST}"
|
|
105
|
+
else
|
|
106
|
+
_wrtxt="● wrapped (pty logged)"
|
|
107
|
+
_wransi="${_GRN}● wrapped (pty logged)${_RST}"
|
|
108
|
+
fi
|
|
109
|
+
else
|
|
110
|
+
_wrtxt="○ unwrapped"
|
|
111
|
+
_wransi="${_DIM}○ unwrapped${_RST}"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# ── Banner — orange CLAWS ASCII, no border ──
|
|
115
|
+
printf "\n"
|
|
116
|
+
printf " ${_ORG} ██████╗██╗ █████╗ ██╗ ██╗███████╗${_RST}\n"
|
|
117
|
+
printf " ${_ORG}██╔════╝██║ ██╔══██╗██║ ██║██╔════╝${_RST}\n"
|
|
118
|
+
printf " ${_ORG}██║ ██║ ███████║██║ █╗ ██║███████╗${_RST}\n"
|
|
119
|
+
printf " ${_ORG}██║ ██║ ██╔══██║██║███╗██║╚════██║${_RST}\n"
|
|
120
|
+
printf " ${_ORG}╚██████╗███████╗██║ ██║╚███╔███╔╝███████║${_RST}\n"
|
|
121
|
+
printf " ${_ORG} ╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ ╚══════╝${_RST}\n"
|
|
122
|
+
printf "\n"
|
|
123
|
+
printf " ${_DIM}Terminal Control Bridge v%s${_RST}\n" "$_CLAWS_VERSION"
|
|
124
|
+
printf "\n"
|
|
125
|
+
printf " %-11s %s\n" "Bridge" "$_bsansi"
|
|
126
|
+
printf " %-11s %s active\n" "Terminals" "$_CLAWS_TERMS"
|
|
127
|
+
printf " %-11s %s\n" "This term" "$_wransi"
|
|
128
|
+
printf "\n"
|
|
129
|
+
|
|
130
|
+
unset _GRN _AMB _ORG _BLD _DIM _RST
|
|
131
|
+
unset _bstxt _bsansi _CLAWS_TERMS _wrtxt _wransi
|
|
132
|
+
unset CLAWS_SOCK _CLAWS_VERSION
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# ═══════════════════════════════════════════════════════════════
|
|
136
|
+
# Shell commands — type these in any terminal
|
|
137
|
+
# ═══════════════════════════════════════════════════════════════
|
|
138
|
+
|
|
139
|
+
_claws_find_sock() {
|
|
140
|
+
if [ -n "${CLAWS_SOCKET:-}" ]; then echo "$CLAWS_SOCKET"; return; fi
|
|
141
|
+
local _w="$PWD"
|
|
142
|
+
while [ -n "$_w" ] && [ "$_w" != "/" ]; do
|
|
143
|
+
[ -S "$_w/.claws/claws.sock" ] && { echo "$_w/.claws/claws.sock"; return; }
|
|
144
|
+
_w="${_w%/*}"
|
|
145
|
+
done
|
|
146
|
+
echo ""
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
_claws_require_sock() {
|
|
150
|
+
local _s; _s="$(_claws_find_sock)"
|
|
151
|
+
if [ -z "$_s" ]; then
|
|
152
|
+
echo "claws: no socket found — open a Claws project in VS Code first" >&2
|
|
153
|
+
return 1
|
|
154
|
+
fi
|
|
155
|
+
echo "$_s"
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
claws-ls() {
|
|
159
|
+
local sock; sock="$(_claws_require_sock)" || return 1
|
|
160
|
+
node -e "
|
|
161
|
+
const net=require('net');
|
|
162
|
+
const s=net.createConnection('$sock');
|
|
163
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'list'})+'\n'));
|
|
164
|
+
let b='';
|
|
165
|
+
const t=setTimeout(()=>{console.log('error: timeout — is VS Code open with the Claws extension?');s.destroy()},5000);
|
|
166
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){clearTimeout(t);try{const d2=JSON.parse(b.split('\n')[0]);(d2.terminals||[]).forEach(t=>{const w=t.logPath?'WRAPPED':' ';const a=t.active?'*':' ';console.log(a+' '+String(t.id).padStart(3)+' '+String(t.name||'').padEnd(25)+' pid='+t.pid+' ['+w+']')})}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
167
|
+
s.on('error',e=>{clearTimeout(t);console.log('error: '+e.message+' — is the Claws extension running?');s.destroy()});
|
|
168
|
+
" 2>/dev/null || echo "error: node not available"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
claws-new() {
|
|
172
|
+
local name="${1:-claws}"
|
|
173
|
+
local sock; sock="$(_claws_require_sock)" || return 1
|
|
174
|
+
node -e "
|
|
175
|
+
const net=require('net');
|
|
176
|
+
const s=net.createConnection('$sock');
|
|
177
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'create',name:'$name',wrapped:true})+'\n'));
|
|
178
|
+
let b='';
|
|
179
|
+
const t=setTimeout(()=>{console.log('error: timeout');s.destroy()},5000);
|
|
180
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){clearTimeout(t);try{const d2=JSON.parse(b.split('\n')[0]);if(d2.ok){console.log('created terminal '+d2.id+' — log: '+(d2.logPath||'none'))}else{console.log('error: '+d2.error)}}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
181
|
+
s.on('error',e=>{clearTimeout(t);console.log('error: '+e.message);s.destroy()});
|
|
182
|
+
" 2>/dev/null || echo "error: node not available"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
claws-run() {
|
|
186
|
+
if [ -z "$1" ] || [ -z "$2" ]; then
|
|
187
|
+
echo "usage: claws-run <terminal-id> <command>"
|
|
188
|
+
return 1
|
|
189
|
+
fi
|
|
190
|
+
local id="$1"; shift
|
|
191
|
+
local cmd="$*"
|
|
192
|
+
local sock; sock="$(_claws_require_sock)" || return 1
|
|
193
|
+
# Write command to temp file to avoid shell injection via $cmd interpolation
|
|
194
|
+
local tmpf="/tmp/claws-cmd-$$.txt"
|
|
195
|
+
printf '%s' "$cmd" > "$tmpf"
|
|
196
|
+
node -e "
|
|
197
|
+
const net=require('net'),fs=require('fs'),path=require('path'),crypto=require('crypto');
|
|
198
|
+
const sockPath='$sock',termId='$id',cmdFile='$tmpf';
|
|
199
|
+
const cmd=fs.readFileSync(cmdFile,'utf8');
|
|
200
|
+
try{fs.unlinkSync(cmdFile)}catch(e){}
|
|
201
|
+
const s=net.createConnection(sockPath);
|
|
202
|
+
const eid=crypto.randomBytes(4).toString('hex');
|
|
203
|
+
const base='/tmp/claws-exec';
|
|
204
|
+
try{fs.mkdirSync(base,{recursive:true})}catch(e){}
|
|
205
|
+
const outF=path.join(base,eid+'.out'),doneF=path.join(base,eid+'.done');
|
|
206
|
+
const wrapper='{ '+cmd+'; } > '+outF+' 2>&1; echo \$? > '+doneF;
|
|
207
|
+
s.on('connect',()=>{s.write(JSON.stringify({id:1,cmd:'send',id:termId,text:wrapper})+'\n')});
|
|
208
|
+
let b='';
|
|
209
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){poll()}});
|
|
210
|
+
function poll(){const deadline=Date.now()+180000;const iv=setInterval(()=>{try{if(fs.existsSync(doneF)){clearInterval(iv);console.log('exit '+fs.readFileSync(doneF,'utf8').trim());try{console.log(fs.readFileSync(outF,'utf8'))}catch(e){};try{fs.unlinkSync(outF)}catch(e){};try{fs.unlinkSync(doneF)}catch(e){};s.destroy()}}catch(e){}if(Date.now()>deadline){clearInterval(iv);console.log('timeout');s.destroy()}},200)}
|
|
211
|
+
s.on('error',e=>{console.log('error: '+e.message);s.destroy()});
|
|
212
|
+
" 2>/dev/null || echo "error: node not available"
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
claws-log() {
|
|
216
|
+
local id="${1:-}"
|
|
217
|
+
local lines="${2:-30}"
|
|
218
|
+
if [ -z "$id" ]; then
|
|
219
|
+
echo "usage: claws-log <terminal-id> [lines]"
|
|
220
|
+
return 1
|
|
221
|
+
fi
|
|
222
|
+
local sock; sock="$(_claws_require_sock)" || return 1
|
|
223
|
+
node -e "
|
|
224
|
+
const net=require('net');
|
|
225
|
+
const s=net.createConnection('$sock');
|
|
226
|
+
s.on('connect',()=>s.write(JSON.stringify({id:1,cmd:'readLog',id:'$id',strip:true})+'\n'));
|
|
227
|
+
let b='';
|
|
228
|
+
const t=setTimeout(()=>{console.log('error: timeout');s.destroy()},10000);
|
|
229
|
+
s.on('data',d=>{b+=d;if(b.includes('\n')){clearTimeout(t);try{const d2=JSON.parse(b.split('\n')[0]);if(d2.ok){const lines=(d2.bytes||'').split('\n');lines.slice(-$lines).forEach(l=>console.log(l));console.log('\n['+(d2.totalSize||0)+' bytes total]')}else{console.log('error: '+d2.error)}}catch(e){console.log('error: '+e.message)};s.destroy()}});
|
|
230
|
+
s.on('error',e=>{clearTimeout(t);console.log('error: '+e.message);s.destroy()});
|
|
231
|
+
" 2>/dev/null || echo "error: node not available"
|
|
232
|
+
}
|