cli-jaw 1.7.7 → 1.7.8

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.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * macOS LaunchAgent plist 생성 — 순수 함수.
3
+ * bin/commands/launchd.ts 및 테스트에서 공유.
4
+ */
5
+ const xmlEsc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
6
+ export function generateLaunchdPlist(o) {
7
+ return `<?xml version="1.0" encoding="UTF-8"?>
8
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
9
+ <plist version="1.0">
10
+ <dict>
11
+ <key>Label</key>
12
+ <string>${xmlEsc(o.label)}</string>
13
+ <key>ProgramArguments</key>
14
+ <array>
15
+ <string>${xmlEsc(o.nodePath)}</string>
16
+ <string>${xmlEsc(o.jawPath)}</string>
17
+ <string>--home</string>
18
+ <string>${xmlEsc(o.jawHome)}</string>
19
+ <string>serve</string>
20
+ <string>--port</string>
21
+ <string>${xmlEsc(o.port)}</string>
22
+ </array>
23
+ <key>RunAtLoad</key>
24
+ <true/>
25
+ <key>KeepAlive</key>
26
+ <true/>
27
+ <key>LimitLoadToSessionType</key>
28
+ <string>Aqua</string>
29
+ <key>ProcessType</key>
30
+ <string>Interactive</string>
31
+ <key>SessionCreate</key>
32
+ <true/>
33
+ <key>WorkingDirectory</key>
34
+ <string>${xmlEsc(o.jawHome)}</string>
35
+ <key>StandardOutPath</key>
36
+ <string>${xmlEsc(o.logDir)}/jaw-serve.log</string>
37
+ <key>StandardErrorPath</key>
38
+ <string>${xmlEsc(o.logDir)}/jaw-serve.err</string>
39
+ <key>EnvironmentVariables</key>
40
+ <dict>
41
+ <key>PATH</key>
42
+ <string>${xmlEsc(o.servicePath)}</string>
43
+ <key>CLI_JAW_HOME</key>
44
+ <string>${xmlEsc(o.jawHome)}</string>
45
+ </dict>
46
+ </dict>
47
+ </plist>`;
48
+ }
49
+ //# sourceMappingURL=launchd-plist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd-plist.js","sourceRoot":"","sources":["../../../src/core/launchd-plist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CACzB,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAEzE,MAAM,UAAU,oBAAoB,CAAC,CAAe;IAChD,OAAO;;;;;cAKG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;;;kBAGX,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;kBAClB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;;kBAEjB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;;;kBAGjB,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;;;;;;;;;;;;;cAalB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;;cAEjB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;;cAEhB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;;;;kBAIZ,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;;kBAErB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;;;SAG1B,CAAC;AACV,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * macOS TCC 진단 유틸리티 (read-only).
3
+ * TCC DB는 SIP 보호 대상 — 읽기만 가능.
4
+ */
5
+ import { execFileSync } from 'node:child_process';
6
+ import { existsSync } from 'node:fs';
7
+ import { homedir } from 'node:os';
8
+ import { join } from 'node:path';
9
+ const TCC_USER_DB = join(homedir(), 'Library', 'Application Support', 'com.apple.TCC', 'TCC.db');
10
+ const CUA_APP_PATH = '/Applications/Codex Computer Use.app';
11
+ export function readTccAppleEventsGrants() {
12
+ if (process.platform !== 'darwin' || !existsSync(TCC_USER_DB))
13
+ return [];
14
+ try {
15
+ const out = execFileSync('sqlite3', [
16
+ TCC_USER_DB,
17
+ "SELECT client, client_type, auth_value, auth_reason, service FROM access WHERE service='kTCCServiceAppleEvents';",
18
+ ], { encoding: 'utf8', stdio: 'pipe', timeout: 5000 });
19
+ return out.trim().split('\n').filter(Boolean).map(line => {
20
+ const [client, clientType, authValue, authReason, service] = line.split('|');
21
+ return {
22
+ client: client ?? '',
23
+ clientType: Number(clientType),
24
+ authValue: Number(authValue),
25
+ authReason: Number(authReason),
26
+ service: service ?? '',
27
+ };
28
+ });
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ }
34
+ export function getLaunchdProcessType(label) {
35
+ if (process.platform !== 'darwin')
36
+ return null;
37
+ const uid = typeof process.getuid === 'function' ? process.getuid() : Number(process.env.UID || 0);
38
+ try {
39
+ const out = execFileSync('launchctl', ['print', `gui/${uid}/${label}`], {
40
+ encoding: 'utf8', stdio: 'pipe', timeout: 5000,
41
+ });
42
+ const match = out.match(/process type\s*=\s*(\w+)/i);
43
+ return match ? match[1] : null;
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ export function cuaAppInstalled() {
50
+ return process.platform === 'darwin' && existsSync(CUA_APP_PATH);
51
+ }
52
+ export function cuaBundleIdRegistered() {
53
+ if (!cuaAppInstalled())
54
+ return false;
55
+ try {
56
+ const out = execFileSync('mdls', ['-name', 'kMDItemCFBundleIdentifier', CUA_APP_PATH], {
57
+ encoding: 'utf8', stdio: 'pipe', timeout: 3000,
58
+ });
59
+ return out.includes('com.openai.sky.CUAService');
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ export { CUA_APP_PATH };
66
+ //# sourceMappingURL=tcc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcc.js","sourceRoot":"","sources":["../../../src/core/tcc.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.7",
3
+ "version": "1.7.8",
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,37 @@
1
+ #!/bin/bash
2
+ # prime-tcc.sh — TCC AppleEvents 권한 프롬프트 명시 트리거 (macOS)
3
+ # 사용: jaw doctor --tcc --prime 또는 수동 1회 실행
4
+
5
+ set -e
6
+
7
+ CUA_APP="/Applications/Codex Computer Use.app"
8
+
9
+ if [[ "$(uname -s)" != "Darwin" ]]; then
10
+ echo "❌ macOS 전용 스크립트"
11
+ exit 1
12
+ fi
13
+
14
+ if [[ ! -d "$CUA_APP" ]]; then
15
+ echo "❌ CUA 앱 없음 — jaw doctor --tcc --fix 또는 npm rebuild -g cli-jaw"
16
+ exit 1
17
+ fi
18
+
19
+ # 1. CUA 앱을 1회 실행해 Launch Services 등록 확정
20
+ open -g "$CUA_APP"
21
+ sleep 1
22
+ osascript -e 'tell application "Codex Computer Use" to quit' 2>/dev/null || true
23
+
24
+ # 2. Chrome 제어 테스트 — 최초 실행 시 권한 프롬프트
25
+ echo "🔐 Chrome 제어 권한 프롬프트가 뜨면 '허용'을 클릭하세요..."
26
+ if ! osascript -e 'tell application "Google Chrome" to get name of front window' 2>/dev/null; then
27
+ echo ""
28
+ echo "❌ 권한 거부 또는 프롬프트 없음"
29
+ echo " 시스템 설정 → 개인정보 보호 및 보안 → 자동화"
30
+ echo " → Terminal 또는 Codex Computer Use에서 Google Chrome 허용"
31
+ exit 1
32
+ fi
33
+
34
+ # 3. System Events 테스트
35
+ osascript -e 'tell application "System Events" to get name of first process' >/dev/null 2>&1 || true
36
+
37
+ echo "✅ TCC 권한 준비 완료"