cli-jaw 1.7.9 → 1.7.11
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/dist/bin/commands/dispatch.js +8 -1
- package/dist/bin/commands/dispatch.js.map +1 -1
- package/dist/bin/commands/launchd.js +6 -0
- package/dist/bin/commands/launchd.js.map +1 -1
- package/dist/bin/postinstall.js +181 -0
- package/dist/bin/postinstall.js.map +1 -1
- package/dist/lib/mcp/skills-utils.js +5 -1
- package/dist/lib/mcp/skills-utils.js.map +1 -1
- package/dist/server.js +4 -0
- package/dist/server.js.map +1 -1
- package/dist/src/agent/args.js +11 -6
- package/dist/src/agent/args.js.map +1 -1
- package/dist/src/agent/spawn.js +30 -1
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/cli/compact.js +32 -36
- package/dist/src/cli/compact.js.map +1 -1
- package/dist/src/core/boss-auth.js +38 -0
- package/dist/src/core/boss-auth.js.map +1 -0
- package/dist/src/core/compact.js +205 -0
- package/dist/src/core/compact.js.map +1 -1
- package/dist/src/core/employees.js +115 -0
- package/dist/src/core/employees.js.map +1 -1
- package/dist/src/core/launchd-plist.js +25 -10
- package/dist/src/core/launchd-plist.js.map +1 -1
- package/dist/src/core/main-session.js +14 -0
- package/dist/src/core/main-session.js.map +1 -1
- package/dist/src/core/runtime-path.js +29 -0
- package/dist/src/core/runtime-path.js.map +1 -1
- package/dist/src/orchestrator/distribute.js +40 -30
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/worker-registry.js +17 -0
- package/dist/src/orchestrator/worker-registry.js.map +1 -1
- package/dist/src/prompt/builder.js +52 -2
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +87 -26
- package/dist/src/prompt/templates/control-system.md +48 -0
- package/dist/src/routes/orchestrate.js +86 -7
- package/dist/src/routes/orchestrate.js.map +1 -1
- package/package.json +1 -1
- package/scripts/darwin/spike-tcc-attribution.sh +333 -0
- package/scripts/darwin/test-computeruse-e2e.sh +204 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrate.js","sourceRoot":"","sources":["../../../src/routes/orchestrate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAM,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAC;AAChG,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEzG,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"orchestrate.js","sourceRoot":"","sources":["../../../src/routes/orchestrate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cli-jaw",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.11",
|
|
4
4
|
"description": "Personal AI assistant powered by 5 engines (Claude, Codex, Gemini, OpenCode, Copilot) — Web, Terminal, Telegram, and Discord interfaces with 107 built-in skills",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# spike-tcc-attribution.sh
|
|
3
|
+
# 목적: macOS TCC가 `Jaw.app` bundle identity로 Automation 권한을 귀속시키는지 실측 검증.
|
|
4
|
+
# 이 스크립트는 31/32 계획의 핵심 가정(shell-shim launcher → com.cli-jaw.agent 책임)을
|
|
5
|
+
# 실제 하드웨어에서 확인한다. 계획을 B로 진입시키기 전 반드시 1회 이상 PASS해야 한다.
|
|
6
|
+
#
|
|
7
|
+
# 사용:
|
|
8
|
+
# bash scripts/darwin/spike-tcc-attribution.sh # dry-run check
|
|
9
|
+
# bash scripts/darwin/spike-tcc-attribution.sh --build # 임시 Jaw.app 번들 생성 후 검증
|
|
10
|
+
# bash scripts/darwin/spike-tcc-attribution.sh --cleanup # 생성된 임시 번들 제거
|
|
11
|
+
#
|
|
12
|
+
# 출력 원칙:
|
|
13
|
+
# - 각 단계마다 PASS/FAIL을 찍고 실패 시 즉시 exit (fail-fast 규칙)
|
|
14
|
+
# - 마지막에 `RESULT=...` 한 줄을 찍어 호출자가 grep하기 쉽게 한다
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
# ── Colors ──
|
|
19
|
+
CYAN='\033[0;36m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'
|
|
20
|
+
DIM='\033[2m'; BOLD='\033[1m'; NC='\033[0m'
|
|
21
|
+
info() { echo -e "${CYAN}▸${NC} $*"; }
|
|
22
|
+
ok() { echo -e "${GREEN}✔${NC} $*"; }
|
|
23
|
+
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
|
|
24
|
+
fail() { echo -e "${RED}✖${NC} $*"; echo "RESULT=FAIL"; exit 1; }
|
|
25
|
+
|
|
26
|
+
if [[ "$(uname -s)" != "Darwin" ]]; then fail "macOS 전용"; fi
|
|
27
|
+
|
|
28
|
+
MODE="${1:-check}"
|
|
29
|
+
SPIKE_APP_DIR="/Applications/JawSpike.app"
|
|
30
|
+
SPIKE_BUNDLE_ID="com.cli-jaw.spike"
|
|
31
|
+
|
|
32
|
+
print_header() {
|
|
33
|
+
echo ""
|
|
34
|
+
echo -e "${CYAN}${BOLD}🔬 TCC Attribution Spike${NC}"
|
|
35
|
+
echo -e "${DIM} 검증: shell-shim launcher가 $SPIKE_BUNDLE_ID 로 귀속되는가${NC}"
|
|
36
|
+
echo ""
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
step_check_prereqs() {
|
|
40
|
+
info "1/6 전제 조건 점검"
|
|
41
|
+
command -v osascript >/dev/null || fail "osascript 없음"
|
|
42
|
+
[[ -d "/Applications/Google Chrome.app" ]] || fail "Google Chrome 미설치 — 설치 후 재시도"
|
|
43
|
+
command -v /usr/libexec/PlistBuddy >/dev/null || fail "PlistBuddy 없음"
|
|
44
|
+
ok "prereq OK"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
step_probe_path_sources() {
|
|
48
|
+
info "2/6 CLI binary PATH 감지 (bun / npm-global / nvm)"
|
|
49
|
+
BUN_BIN_DIR=""
|
|
50
|
+
NPM_BIN_DIR=""
|
|
51
|
+
NVM_BIN_DIR=""
|
|
52
|
+
if command -v bun >/dev/null; then BUN_BIN_DIR="$(dirname "$(command -v bun)")"; fi
|
|
53
|
+
if command -v npm >/dev/null; then NPM_BIN_DIR="$(npm config get prefix 2>/dev/null)/bin"; fi
|
|
54
|
+
if [[ -n "${NVM_DIR:-}" && -d "$NVM_DIR" ]]; then
|
|
55
|
+
NVM_BIN_DIR="$(ls -dt "$NVM_DIR"/versions/node/*/bin 2>/dev/null | head -1 || true)"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
echo " BUN: ${BUN_BIN_DIR:-∅}"
|
|
59
|
+
echo " NPM: ${NPM_BIN_DIR:-∅}"
|
|
60
|
+
echo " NVM: ${NVM_BIN_DIR:-∅}"
|
|
61
|
+
|
|
62
|
+
# cli-jaw가 실제로 어디서 발견되는지
|
|
63
|
+
JAW_BIN="$(command -v cli-jaw || true)"
|
|
64
|
+
[[ -n "$JAW_BIN" ]] || fail "cli-jaw가 현재 PATH에 없음 — npm i -g cli-jaw 먼저"
|
|
65
|
+
JAW_BIN_DIR="$(dirname "$JAW_BIN")"
|
|
66
|
+
echo " cli-jaw: $JAW_BIN"
|
|
67
|
+
|
|
68
|
+
# PATH 머지 (중복 제거, 존재하는 것만)
|
|
69
|
+
MERGED_PATH=""
|
|
70
|
+
for d in "$JAW_BIN_DIR" "$BUN_BIN_DIR" "$NPM_BIN_DIR" "$NVM_BIN_DIR" \
|
|
71
|
+
"/opt/homebrew/bin" "/usr/local/bin" "/usr/bin" "/bin"; do
|
|
72
|
+
[[ -z "$d" || ! -d "$d" ]] && continue
|
|
73
|
+
case ":$MERGED_PATH:" in *":$d:"*) ;; *) MERGED_PATH="${MERGED_PATH:+$MERGED_PATH:}$d";; esac
|
|
74
|
+
done
|
|
75
|
+
echo " MERGED_PATH=$MERGED_PATH"
|
|
76
|
+
ok "PATH sources detected"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
build_spike_app() {
|
|
80
|
+
info "3/6 임시 Jaw.app (JawSpike.app) 생성"
|
|
81
|
+
if [[ -d "$SPIKE_APP_DIR" ]]; then
|
|
82
|
+
warn "기존 $SPIKE_APP_DIR 감지 — 삭제 후 재생성"
|
|
83
|
+
rm -rf "$SPIKE_APP_DIR"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
mkdir -p "$SPIKE_APP_DIR/Contents/MacOS"
|
|
87
|
+
mkdir -p "$SPIKE_APP_DIR/Contents/Resources"
|
|
88
|
+
|
|
89
|
+
cat > "$SPIKE_APP_DIR/Contents/Info.plist" <<PLIST
|
|
90
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
91
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
92
|
+
<plist version="1.0">
|
|
93
|
+
<dict>
|
|
94
|
+
<key>CFBundleIdentifier</key><string>$SPIKE_BUNDLE_ID</string>
|
|
95
|
+
<key>CFBundleName</key><string>JawSpike</string>
|
|
96
|
+
<key>CFBundleDisplayName</key><string>Jaw Spike</string>
|
|
97
|
+
<key>CFBundleExecutable</key><string>jaw-spike-launcher</string>
|
|
98
|
+
<key>CFBundlePackageType</key><string>APPL</string>
|
|
99
|
+
<key>CFBundleShortVersionString</key><string>0.0.1</string>
|
|
100
|
+
<key>CFBundleVersion</key><string>0.0.1</string>
|
|
101
|
+
<key>LSBackgroundOnly</key><true/>
|
|
102
|
+
<key>LSUIElement</key><true/>
|
|
103
|
+
<key>NSAppleEventsUsageDescription</key><string>Jaw Spike — TCC attribution test</string>
|
|
104
|
+
</dict>
|
|
105
|
+
</plist>
|
|
106
|
+
PLIST
|
|
107
|
+
|
|
108
|
+
cat > "$SPIKE_APP_DIR/Contents/MacOS/jaw-spike-launcher" <<LAUNCHER
|
|
109
|
+
#!/bin/bash
|
|
110
|
+
# PATH pin: CLI discovery from bun / npm / nvm
|
|
111
|
+
export PATH="$MERGED_PATH"
|
|
112
|
+
# 실제 책임 주체가 누구인지 보기 위해 osascript를 직접 실행
|
|
113
|
+
exec /usr/bin/osascript -e 'tell application "Google Chrome" to get URL of active tab of front window'
|
|
114
|
+
LAUNCHER
|
|
115
|
+
chmod +x "$SPIKE_APP_DIR/Contents/MacOS/jaw-spike-launcher"
|
|
116
|
+
|
|
117
|
+
# Launch Services 등록
|
|
118
|
+
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister \
|
|
119
|
+
-f -R "$SPIKE_APP_DIR" 2>/dev/null || warn "lsregister 실패 (무시 가능)"
|
|
120
|
+
xattr -dr com.apple.quarantine "$SPIKE_APP_DIR" 2>/dev/null || true
|
|
121
|
+
|
|
122
|
+
ok "JawSpike.app 생성됨: $SPIKE_APP_DIR"
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
probe_attribution() {
|
|
126
|
+
info "4/6 첫 실행 (TCC 프롬프트 예상)"
|
|
127
|
+
echo ""
|
|
128
|
+
echo -e "${YELLOW} 프롬프트가 뜨면 '허용'을 누르세요. 이름은 '${BOLD}Jaw Spike${NC}${YELLOW}'로 보여야 합니다.${NC}"
|
|
129
|
+
echo -e "${YELLOW} 만약 'Terminal' 또는 'osascript'로 뜨면 귀속 실패입니다.${NC}"
|
|
130
|
+
echo ""
|
|
131
|
+
read -r -p " 계속하려면 Enter..." _
|
|
132
|
+
|
|
133
|
+
# open -a는 LaunchServices를 통해 번들을 실행 → responsibility가 번들로 귀속됨
|
|
134
|
+
if ! open -W -a "$SPIKE_APP_DIR" 2>&1; then
|
|
135
|
+
warn "open -W가 non-zero — 권한 거부 또는 Chrome 비실행 상태일 수 있음"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
info "5/6 권한 DB에서 귀속 주체 조회"
|
|
139
|
+
DB="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
|
|
140
|
+
if [[ ! -f "$DB" ]]; then warn "유저 TCC.db 없음 (조회 스킵)"; return; fi
|
|
141
|
+
|
|
142
|
+
# kTCCServiceAppleEvents 레코드에서 client 필드 확인 (read-only)
|
|
143
|
+
ATTR=$(sqlite3 "$DB" \
|
|
144
|
+
"SELECT client FROM access WHERE service='kTCCServiceAppleEvents' AND client LIKE '%cli-jaw%' OR client LIKE '%jaw-spike%';" \
|
|
145
|
+
2>/dev/null || true)
|
|
146
|
+
|
|
147
|
+
if [[ -z "$ATTR" ]]; then
|
|
148
|
+
warn "TCC.db에 $SPIKE_BUNDLE_ID 관련 레코드 없음 — 아직 허용이 기록되지 않았거나 귀속 실패"
|
|
149
|
+
else
|
|
150
|
+
echo " TCC client 엔트리:"
|
|
151
|
+
echo "$ATTR" | sed 's/^/ /'
|
|
152
|
+
fi
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
verdict() {
|
|
156
|
+
info "6/6 결론 출력"
|
|
157
|
+
DB="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
|
|
158
|
+
PASS=false
|
|
159
|
+
if [[ -f "$DB" ]]; then
|
|
160
|
+
if sqlite3 "$DB" "SELECT client FROM access WHERE service='kTCCServiceAppleEvents' AND client='$SPIKE_BUNDLE_ID';" 2>/dev/null | grep -q "$SPIKE_BUNDLE_ID"; then
|
|
161
|
+
PASS=true
|
|
162
|
+
fi
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
if $PASS; then
|
|
166
|
+
ok "RESULT=PASS — shell-shim launcher가 $SPIKE_BUNDLE_ID 로 귀속됨"
|
|
167
|
+
echo "RESULT=PASS"
|
|
168
|
+
echo " → 31/32 계획의 shell-shim 전략 진행 가능"
|
|
169
|
+
else
|
|
170
|
+
warn "RESULT=INCONCLUSIVE_OR_FAIL"
|
|
171
|
+
echo "RESULT=INCONCLUSIVE"
|
|
172
|
+
echo ""
|
|
173
|
+
echo " 가능한 원인과 대처:"
|
|
174
|
+
echo " 1) 프롬프트에서 거부/무시함 → 재실행"
|
|
175
|
+
echo " 2) Terminal/osascript로 귀속됨 → shell-shim 전략 불가. 대안:"
|
|
176
|
+
echo " a. Swift/C 네이티브 mini-launcher (앱 번들 executable이 실제 네이티브 바이너리)"
|
|
177
|
+
echo " b. launchd ProgramArguments에 Jaw.app 자체를 지정하는 대신"
|
|
178
|
+
echo " /Applications/Jaw.app/Contents/MacOS/jaw-launcher 를 pid 1 자식으로 두기"
|
|
179
|
+
echo " 3) TCC.db 권한 없음 → Full Disk Access가 필요할 수 있음"
|
|
180
|
+
fi
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
build_native_spike() {
|
|
184
|
+
info "3/6 [V2 native] clang 확인 + Obj-C launcher 컴파일"
|
|
185
|
+
if ! command -v /usr/bin/clang >/dev/null; then
|
|
186
|
+
fail "clang 없음 — Xcode Command Line Tools 설치: xcode-select --install"
|
|
187
|
+
fi
|
|
188
|
+
ok "clang: $(/usr/bin/clang --version | head -1)"
|
|
189
|
+
|
|
190
|
+
if [[ -d "$SPIKE_APP_DIR" ]]; then
|
|
191
|
+
warn "기존 $SPIKE_APP_DIR 제거"
|
|
192
|
+
rm -rf "$SPIKE_APP_DIR"
|
|
193
|
+
fi
|
|
194
|
+
mkdir -p "$SPIKE_APP_DIR/Contents/MacOS"
|
|
195
|
+
mkdir -p "$SPIKE_APP_DIR/Contents/Resources"
|
|
196
|
+
|
|
197
|
+
cat > "$SPIKE_APP_DIR/Contents/Info.plist" <<PLIST
|
|
198
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
199
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
200
|
+
<plist version="1.0">
|
|
201
|
+
<dict>
|
|
202
|
+
<key>CFBundleIdentifier</key><string>$SPIKE_BUNDLE_ID</string>
|
|
203
|
+
<key>CFBundleName</key><string>JawSpike</string>
|
|
204
|
+
<key>CFBundleDisplayName</key><string>Jaw Spike Native</string>
|
|
205
|
+
<key>CFBundleExecutable</key><string>jaw-spike-launcher</string>
|
|
206
|
+
<key>CFBundlePackageType</key><string>APPL</string>
|
|
207
|
+
<key>CFBundleShortVersionString</key><string>0.0.2</string>
|
|
208
|
+
<key>CFBundleVersion</key><string>0.0.2</string>
|
|
209
|
+
<key>LSBackgroundOnly</key><true/>
|
|
210
|
+
<key>LSUIElement</key><true/>
|
|
211
|
+
<key>NSAppleEventsUsageDescription</key><string>Jaw Spike — native launcher TCC test</string>
|
|
212
|
+
</dict>
|
|
213
|
+
</plist>
|
|
214
|
+
PLIST
|
|
215
|
+
|
|
216
|
+
# Objective-C source: Mach-O that fires an AppleEvent (TCC 진짜 트리거)
|
|
217
|
+
local SRC="$(mktemp -t jaw-spike-XXXXXX).m"
|
|
218
|
+
cat > "$SRC" <<'OBJC'
|
|
219
|
+
#import <Foundation/Foundation.h>
|
|
220
|
+
int main(void) {
|
|
221
|
+
@autoreleasepool {
|
|
222
|
+
NSAppleScript *s = [[NSAppleScript alloc] initWithSource:
|
|
223
|
+
@"tell application \"Google Chrome\" to get URL of active tab of front window"];
|
|
224
|
+
NSDictionary *err = nil;
|
|
225
|
+
NSAppleEventDescriptor *r = [s executeAndReturnError:&err];
|
|
226
|
+
if (err) {
|
|
227
|
+
fprintf(stderr, "ERR: %s\n", [[err description] UTF8String]);
|
|
228
|
+
return 1;
|
|
229
|
+
}
|
|
230
|
+
NSString *v = [r stringValue];
|
|
231
|
+
printf("URL=%s\n", v ? [v UTF8String] : "(null)");
|
|
232
|
+
return 0;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
OBJC
|
|
236
|
+
|
|
237
|
+
local OUT="$SPIKE_APP_DIR/Contents/MacOS/jaw-spike-launcher"
|
|
238
|
+
if ! /usr/bin/clang -framework Foundation -O2 -o "$OUT" "$SRC"; then
|
|
239
|
+
rm -f "$SRC"
|
|
240
|
+
fail "clang compile 실패"
|
|
241
|
+
fi
|
|
242
|
+
rm -f "$SRC"
|
|
243
|
+
chmod +x "$OUT"
|
|
244
|
+
|
|
245
|
+
# ad-hoc codesign so TCC accepts the bundle identity stably
|
|
246
|
+
/usr/bin/codesign --force --sign - "$SPIKE_APP_DIR" 2>/dev/null || warn "codesign 실패 (무시 가능)"
|
|
247
|
+
|
|
248
|
+
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister \
|
|
249
|
+
-f -R "$SPIKE_APP_DIR" 2>/dev/null || warn "lsregister 실패"
|
|
250
|
+
xattr -dr com.apple.quarantine "$SPIKE_APP_DIR" 2>/dev/null || true
|
|
251
|
+
|
|
252
|
+
ok "Native JawSpike.app 컴파일 완료: $SPIKE_APP_DIR"
|
|
253
|
+
file "$OUT" | sed 's/^/ /'
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
verdict_native() {
|
|
257
|
+
info "6/6 V2 결론"
|
|
258
|
+
DB="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
|
|
259
|
+
if [[ ! -f "$DB" ]]; then
|
|
260
|
+
warn "TCC.db 접근 불가 — Terminal/iTerm에 Full Disk Access 필요"
|
|
261
|
+
echo "RESULT=INCONCLUSIVE_NO_TCC_ACCESS"
|
|
262
|
+
return
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
local SPIKE_ROW
|
|
266
|
+
SPIKE_ROW=$(sqlite3 "$DB" \
|
|
267
|
+
"SELECT client FROM access WHERE service='kTCCServiceAppleEvents' AND client='$SPIKE_BUNDLE_ID';" \
|
|
268
|
+
2>/dev/null || true)
|
|
269
|
+
|
|
270
|
+
if [[ -n "$SPIKE_ROW" ]]; then
|
|
271
|
+
ok "RESULT=PASS — Mach-O launcher가 $SPIKE_BUNDLE_ID 로 귀속됨"
|
|
272
|
+
echo "RESULT=PASS"
|
|
273
|
+
echo " → 31/32의 native launcher 전략 진행 가능"
|
|
274
|
+
return
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# 실패 상세: 실제 누구에게 귀속됐는지 힌트
|
|
278
|
+
warn "RESULT=FAIL — $SPIKE_BUNDLE_ID TCC 엔트리 없음"
|
|
279
|
+
echo "RESULT=FAIL"
|
|
280
|
+
echo ""
|
|
281
|
+
echo " TCC.db의 최근 AppleEvents 허용 client 상위 10개:"
|
|
282
|
+
sqlite3 "$DB" \
|
|
283
|
+
"SELECT client, datetime(last_modified, 'unixepoch', 'localtime') FROM access WHERE service='kTCCServiceAppleEvents' ORDER BY last_modified DESC LIMIT 10;" \
|
|
284
|
+
2>/dev/null | sed 's/^/ /'
|
|
285
|
+
echo ""
|
|
286
|
+
echo " 프롬프트 제목이 무엇으로 떴는지(예: 'Jaw Spike Native' vs 'osascript' vs 'bash')가 핵심 증거입니다."
|
|
287
|
+
echo " 'Jaw Spike Native'였다면 유저가 허용만 안 누른 것 — 재실행하세요."
|
|
288
|
+
echo " 다른 이름이었다면 native launcher도 귀속 실패 → 계획 재협상 필요."
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
cleanup() {
|
|
292
|
+
info "cleanup"
|
|
293
|
+
if [[ -d "$SPIKE_APP_DIR" ]]; then
|
|
294
|
+
rm -rf "$SPIKE_APP_DIR"
|
|
295
|
+
ok "$SPIKE_APP_DIR 제거됨"
|
|
296
|
+
else
|
|
297
|
+
ok "이미 깨끗함"
|
|
298
|
+
fi
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
case "$MODE" in
|
|
302
|
+
--cleanup|cleanup) cleanup; exit 0 ;;
|
|
303
|
+
--build|build)
|
|
304
|
+
print_header
|
|
305
|
+
warn "V1 (shell-shim) 모드는 이미 FAIL 판정 — 참고용으로만 실행하세요."
|
|
306
|
+
step_check_prereqs
|
|
307
|
+
step_probe_path_sources
|
|
308
|
+
build_spike_app
|
|
309
|
+
probe_attribution
|
|
310
|
+
verdict
|
|
311
|
+
;;
|
|
312
|
+
--build-native|build-native|--v2|v2)
|
|
313
|
+
print_header
|
|
314
|
+
echo -e "${DIM} V2: Mach-O Objective-C launcher 기반 재검증${NC}"
|
|
315
|
+
echo ""
|
|
316
|
+
step_check_prereqs
|
|
317
|
+
step_probe_path_sources
|
|
318
|
+
build_native_spike
|
|
319
|
+
probe_attribution
|
|
320
|
+
verdict_native
|
|
321
|
+
;;
|
|
322
|
+
*)
|
|
323
|
+
print_header
|
|
324
|
+
step_check_prereqs
|
|
325
|
+
step_probe_path_sources
|
|
326
|
+
warn "dry-run 모드 — 번들 생성/권한 요청은 스킵"
|
|
327
|
+
echo ""
|
|
328
|
+
echo "다음 단계:"
|
|
329
|
+
echo " bash $0 --build-native # V2: clang Mach-O 기반 (권장)"
|
|
330
|
+
echo " bash $0 --build # V1: shell-shim (이미 FAIL, 참고용)"
|
|
331
|
+
echo " bash $0 --cleanup # spike 번들 제거"
|
|
332
|
+
;;
|
|
333
|
+
esac
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# test-computeruse-e2e.sh
|
|
3
|
+
# End-to-end smoke test for the Computer Use integration on macOS.
|
|
4
|
+
# Mirrors the R1..R10 matrix in devlog/_plan/computeruse/36_rollout_validation.md.
|
|
5
|
+
#
|
|
6
|
+
# Each check either PASSES, SKIPS (environment missing), or FAILS.
|
|
7
|
+
# The script returns exit 0 only when no check FAILS.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# bash scripts/darwin/test-computeruse-e2e.sh # full run
|
|
11
|
+
# bash scripts/darwin/test-computeruse-e2e.sh --fast # skip network/MCP checks
|
|
12
|
+
# VERBOSE=1 bash scripts/darwin/test-computeruse-e2e.sh # show intermediate output
|
|
13
|
+
|
|
14
|
+
set -u
|
|
15
|
+
|
|
16
|
+
BOLD='\033[1m'
|
|
17
|
+
RED='\033[31m'
|
|
18
|
+
GREEN='\033[32m'
|
|
19
|
+
YELLOW='\033[33m'
|
|
20
|
+
DIM='\033[2m'
|
|
21
|
+
OFF='\033[0m'
|
|
22
|
+
|
|
23
|
+
FAST=0
|
|
24
|
+
if [ "${1:-}" = "--fast" ]; then FAST=1; fi
|
|
25
|
+
VERBOSE=${VERBOSE:-0}
|
|
26
|
+
|
|
27
|
+
PASS=0
|
|
28
|
+
FAIL=0
|
|
29
|
+
SKIP=0
|
|
30
|
+
|
|
31
|
+
hr() { printf '%s\n' '----------------------------------------'; }
|
|
32
|
+
|
|
33
|
+
check() {
|
|
34
|
+
local name="$1"; shift
|
|
35
|
+
local status="$1"; shift
|
|
36
|
+
local detail="${*:-}"
|
|
37
|
+
case "$status" in
|
|
38
|
+
PASS) printf "%b[PASS]%b %s %b%s%b\n" "$GREEN" "$OFF" "$name" "$DIM" "$detail" "$OFF"; PASS=$((PASS+1));;
|
|
39
|
+
FAIL) printf "%b[FAIL]%b %s %b%s%b\n" "$RED" "$OFF" "$name" "$DIM" "$detail" "$OFF"; FAIL=$((FAIL+1));;
|
|
40
|
+
SKIP) printf "%b[SKIP]%b %s %b%s%b\n" "$YELLOW" "$OFF" "$name" "$DIM" "$detail" "$OFF"; SKIP=$((SKIP+1));;
|
|
41
|
+
esac
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
require_cmd() {
|
|
45
|
+
command -v "$1" >/dev/null 2>&1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
printf "%bcli-jaw · Computer Use E2E smoke%b\n" "$BOLD" "$OFF"
|
|
49
|
+
hr
|
|
50
|
+
|
|
51
|
+
# ─── A. Platform + core binaries ──────────────────────────────
|
|
52
|
+
|
|
53
|
+
if [ "$(uname -s)" = "Darwin" ]; then
|
|
54
|
+
check "darwin platform" PASS "$(uname -sr)"
|
|
55
|
+
else
|
|
56
|
+
check "darwin platform" FAIL "$(uname -sr) — this test is darwin-only"
|
|
57
|
+
printf "\nExiting early on non-darwin host.\n"
|
|
58
|
+
exit 2
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
if require_cmd cli-jaw; then
|
|
62
|
+
check "cli-jaw in PATH" PASS "$(command -v cli-jaw)"
|
|
63
|
+
else
|
|
64
|
+
check "cli-jaw in PATH" FAIL "install: npm i -g cli-jaw"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if require_cmd /usr/bin/clang; then
|
|
68
|
+
check "clang available" PASS
|
|
69
|
+
else
|
|
70
|
+
check "clang available" SKIP "prebuilt fallback will be used"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# ─── B. Jaw.app + launcher ────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
JAW_APP=/Applications/Jaw.app
|
|
76
|
+
LAUNCHER="$JAW_APP/Contents/MacOS/jaw-launcher"
|
|
77
|
+
|
|
78
|
+
if [ -d "$JAW_APP" ]; then
|
|
79
|
+
check "Jaw.app installed" PASS "$JAW_APP"
|
|
80
|
+
else
|
|
81
|
+
check "Jaw.app installed" FAIL "run: jaw init (postinstall ensureJawAppInstall)"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
if [ -x "$LAUNCHER" ]; then
|
|
85
|
+
if file "$LAUNCHER" 2>/dev/null | grep -q "Mach-O"; then
|
|
86
|
+
check "jaw-launcher is Mach-O" PASS "$(file "$LAUNCHER" | cut -d: -f2- | xargs)"
|
|
87
|
+
else
|
|
88
|
+
check "jaw-launcher is Mach-O" FAIL "not a Mach-O binary — TCC attribution will break"
|
|
89
|
+
fi
|
|
90
|
+
else
|
|
91
|
+
check "jaw-launcher executable" FAIL "missing: $LAUNCHER"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$JAW_APP/Contents/Info.plist" 2>/dev/null || echo "")
|
|
95
|
+
if [ "$BUNDLE_ID" = "com.cli-jaw.agent" ]; then
|
|
96
|
+
check "Info.plist bundle id" PASS "$BUNDLE_ID"
|
|
97
|
+
else
|
|
98
|
+
check "Info.plist bundle id" FAIL "got '$BUNDLE_ID' — expected com.cli-jaw.agent"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if /usr/bin/codesign --verify --deep --strict "$JAW_APP" >/dev/null 2>&1; then
|
|
102
|
+
check "Jaw.app codesign" PASS
|
|
103
|
+
else
|
|
104
|
+
check "Jaw.app codesign" FAIL "run: codesign --sign - --force --deep $JAW_APP"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# ─── C. Codex Computer Use.app ─────────────────────────────────
|
|
108
|
+
|
|
109
|
+
CUA_APP="/Applications/Codex Computer Use.app"
|
|
110
|
+
if [ -d "$CUA_APP" ]; then
|
|
111
|
+
check "Codex Computer Use.app" PASS
|
|
112
|
+
else
|
|
113
|
+
check "Codex Computer Use.app" FAIL "run: jaw doctor --tcc --fix"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# ─── D. launchd plist (if registered) ──────────────────────────
|
|
117
|
+
|
|
118
|
+
LAUNCH_AGENTS="$HOME/Library/LaunchAgents"
|
|
119
|
+
LAUNCHD_PLIST=$(ls -1 "$LAUNCH_AGENTS"/com.cli-jaw.*.plist 2>/dev/null | head -1)
|
|
120
|
+
|
|
121
|
+
if [ -n "$LAUNCHD_PLIST" ]; then
|
|
122
|
+
if grep -q "<key>SessionCreate</key>" "$LAUNCHD_PLIST" \
|
|
123
|
+
&& grep -q "<true/>" "$LAUNCHD_PLIST" \
|
|
124
|
+
&& grep -q "<string>Interactive</string>" "$LAUNCHD_PLIST"; then
|
|
125
|
+
check "launchd plist SessionCreate + Interactive" PASS "$LAUNCHD_PLIST"
|
|
126
|
+
else
|
|
127
|
+
check "launchd plist SessionCreate + Interactive" FAIL "re-run: jaw launchd"
|
|
128
|
+
fi
|
|
129
|
+
if grep -q "CLI_JAW_RUNTIME" "$LAUNCHD_PLIST"; then
|
|
130
|
+
check "plist CLI_JAW_RUNTIME env" PASS
|
|
131
|
+
else
|
|
132
|
+
check "plist CLI_JAW_RUNTIME env" FAIL "plist is stale — jaw launchd"
|
|
133
|
+
fi
|
|
134
|
+
if grep -q "$JAW_APP/Contents/MacOS/jaw-launcher" "$LAUNCHD_PLIST"; then
|
|
135
|
+
check "plist ProgramArguments → Jaw.app launcher" PASS
|
|
136
|
+
else
|
|
137
|
+
check "plist ProgramArguments → Jaw.app launcher" SKIP "legacy plist still points at node directly"
|
|
138
|
+
fi
|
|
139
|
+
else
|
|
140
|
+
check "launchd plist registered" SKIP "run: jaw launchd (optional for foreground mode)"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# ─── E. desktop-control skill installed ────────────────────────
|
|
144
|
+
|
|
145
|
+
SKILL_DIR="$HOME/.cli-jaw/skills/desktop-control"
|
|
146
|
+
if [ -f "$SKILL_DIR/SKILL.md" ]; then
|
|
147
|
+
check "desktop-control skill active" PASS "$SKILL_DIR"
|
|
148
|
+
missing=""
|
|
149
|
+
for ref in cdp.md computer-use.md vision-click.md intent-routing.md; do
|
|
150
|
+
[ -f "$SKILL_DIR/reference/$ref" ] || missing="$missing $ref"
|
|
151
|
+
done
|
|
152
|
+
if [ -z "$missing" ]; then
|
|
153
|
+
check "desktop-control reference/ complete" PASS
|
|
154
|
+
else
|
|
155
|
+
check "desktop-control reference/ complete" FAIL "missing:$missing"
|
|
156
|
+
fi
|
|
157
|
+
else
|
|
158
|
+
check "desktop-control skill active" FAIL "expected $SKILL_DIR/SKILL.md"
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# ─── F. prompt anchors baked in A-1.md ─────────────────────────
|
|
162
|
+
|
|
163
|
+
A1_DISK="$HOME/.cli-jaw/prompts/A-1.md"
|
|
164
|
+
if [ -f "$A1_DISK" ]; then
|
|
165
|
+
if grep -q "anchor:desktop-control" "$A1_DISK"; then
|
|
166
|
+
check "A-1.md desktop-control anchor" PASS
|
|
167
|
+
else
|
|
168
|
+
check "A-1.md desktop-control anchor" FAIL "restart jaw serve to trigger safe-append"
|
|
169
|
+
fi
|
|
170
|
+
else
|
|
171
|
+
check "A-1.md on disk" SKIP "first-run only (jaw serve will create it)"
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# ─── G. Server reachable (optional) ────────────────────────────
|
|
175
|
+
|
|
176
|
+
if [ "$FAST" -eq 0 ]; then
|
|
177
|
+
if require_cmd curl; then
|
|
178
|
+
if curl -sfm 2 http://localhost:3457/api/health >/dev/null 2>&1; then
|
|
179
|
+
check "jaw serve reachable on :3457" PASS
|
|
180
|
+
else
|
|
181
|
+
check "jaw serve reachable on :3457" SKIP "start: jaw serve (or jaw launchd)"
|
|
182
|
+
fi
|
|
183
|
+
fi
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
# ─── H. Computer Use MCP probe (requires codex) ────────────────
|
|
187
|
+
|
|
188
|
+
if [ "$FAST" -eq 0 ]; then
|
|
189
|
+
if require_cmd codex; then
|
|
190
|
+
check "codex CLI available" PASS "$(command -v codex)"
|
|
191
|
+
else
|
|
192
|
+
check "codex CLI available" SKIP "Computer Use MCP unreachable without codex"
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
hr
|
|
197
|
+
printf "%bResult%b pass=%d fail=%d skip=%d\n" "$BOLD" "$OFF" "$PASS" "$FAIL" "$SKIP"
|
|
198
|
+
|
|
199
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
200
|
+
printf "%b✗ one or more checks failed%b\n" "$RED" "$OFF"
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
203
|
+
printf "%b✓ all required checks passed%b\n" "$GREEN" "$OFF"
|
|
204
|
+
exit 0
|