@cliphijack/santaclaude 1.0.26 → 1.0.27
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/package.json +1 -1
- package/santaclaude.js +16 -2
package/package.json
CHANGED
package/santaclaude.js
CHANGED
|
@@ -263,6 +263,7 @@ function tok24h() { const now = Date.now(); if (LEAGUE_ON && now - _tokAt > 5 *
|
|
|
263
263
|
const SHARE_PORT = 8799;
|
|
264
264
|
const SHARE_DIRS = [path.join(os.homedir(), '.santaclaude', 'outbox'), path.join(os.homedir(), '.santaclaude', 'share'), path.join(os.homedir(), 'Downloads')];
|
|
265
265
|
let _tnCache = null, _shareToken = null, _shareServer = null;
|
|
266
|
+
function notionSet() { try { return /^NOTION_TOKEN=.+/m.test(fs.readFileSync(path.join(os.homedir(), '.santaclaude', '.env'), 'utf8')); } catch (e) { return false; } } // ~/.santaclaude/.env 에 토큰 있나
|
|
266
267
|
function startShareServer(ip) { // 테일넷 IP에만 바인드 → 테일넷 피어만 접근. 경로 토큰 + basename으로 보호
|
|
267
268
|
if (_shareServer || !ip) return;
|
|
268
269
|
try { _shareToken = require('crypto').randomBytes(8).toString('hex'); } catch (e) { _shareToken = String(Date.now()); }
|
|
@@ -480,6 +481,19 @@ async function run(conf) {
|
|
|
480
481
|
setTimeout(() => { try { execFileSync('tmux', ['send-keys', '-t', w, 'Enter']); } catch (e) {} }, 300);
|
|
481
482
|
return;
|
|
482
483
|
}
|
|
484
|
+
if (cmd.action === 'notion-setup') { // 🔮 노션 연결 — 토큰·부모페이지를 PC ~/.santaclaude/.env 에만 기록(우리 서버 저장 X)
|
|
485
|
+
const ntok = String(cmd.ntoken || '').trim(); if (!ntok) return;
|
|
486
|
+
let pid = String(cmd.parent || '').replace(/-/g, '').match(/[0-9a-fA-F]{32}/); pid = pid ? pid[0] : '';
|
|
487
|
+
try {
|
|
488
|
+
const dir = path.join(os.homedir(), '.santaclaude'); fs.mkdirSync(dir, { recursive: true });
|
|
489
|
+
const ep = path.join(dir, '.env'); let env = ''; try { env = fs.readFileSync(ep, 'utf8'); } catch (e) {}
|
|
490
|
+
env = env.split('\n').filter((l) => l && !/^NOTION_(TOKEN|PARENT_PAGE)=/.test(l)).join('\n'); if (env && !env.endsWith('\n')) env += '\n';
|
|
491
|
+
env += 'NOTION_TOKEN=' + ntok + '\n'; if (pid) env += 'NOTION_PARENT_PAGE=' + pid + '\n';
|
|
492
|
+
fs.writeFileSync(ep, env, { mode: 0o600 });
|
|
493
|
+
console.log(' 🔮 노션 연결 저장 → ~/.santaclaude/.env' + (pid ? ' (부모페이지 포함)' : ''));
|
|
494
|
+
} catch (e) { console.warn(' 노션 저장 실패: ' + (e.message || '')); }
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
483
497
|
if (cmd.action === 'taildrop') { // 📲 PC→폰 Taildrop 푸시 (C). 공유폴더 파일을 지정 피어로
|
|
484
498
|
const fn = path.basename(String(cmd.file || '')); const peer = String(cmd.peer || '').replace(/[^A-Za-z0-9._-]/g, '');
|
|
485
499
|
if (!fn || !peer) return;
|
|
@@ -676,7 +690,7 @@ async function run(conf) {
|
|
|
676
690
|
console.log(`[발사] ${new Date().toISOString()} → ${tgt}: ${String(j.message).slice(0, 60)}`);
|
|
677
691
|
try { inject(tgt, '[SantaClaude] ' + j.message); } catch (e) { console.warn(` 주입 실패(${tgt}): ${e.message}`); }
|
|
678
692
|
}
|
|
679
|
-
function sendHb() { if (ws && ws.readyState === 1) { try { ws.send(JSON.stringify({ type: 'hb', pane, sessions: listWindows(session), token: LEAGUE_ON ? token : undefined, tok: LEAGUE_ON ? tok24h() : undefined, tn: _tnCache })); } catch (e) {} } }
|
|
693
|
+
function sendHb() { if (ws && ws.readyState === 1) { try { ws.send(JSON.stringify({ type: 'hb', pane, sessions: listWindows(session), token: LEAGUE_ON ? token : undefined, tok: LEAGUE_ON ? tok24h() : undefined, tn: _tnCache, notion: { set: notionSet() } })); } catch (e) {} } }
|
|
680
694
|
// 화면 미러 — 변경됐을 때만 전송(claude 멈추면 0). 2.5초 체크라 응답 직후 빠르게 반영
|
|
681
695
|
let lastScr = '';
|
|
682
696
|
function sendScreen() { if (!ws || ws.readyState !== 1) return; let cur; try { cur = JSON.stringify(captureAll(session)); } catch (e) { return; } if (cur === lastScr) return; lastScr = cur; try { ws.send(JSON.stringify({ type: 'screen', screens: JSON.parse(cur) })); } catch (e) {} }
|
|
@@ -702,7 +716,7 @@ async function run(conf) {
|
|
|
702
716
|
// 폴링 폴백 (node<21 = WebSocket 미지원) — 워커가 DO 백엔드라 폴링이어도 KV write 0
|
|
703
717
|
async function pollTick() {
|
|
704
718
|
try {
|
|
705
|
-
post(api, '/api/heartbeat', { token, pane, sessions: listWindows(session), screens: captureAll(session), tok: LEAGUE_ON ? tok24h() : undefined, tn: _tnCache }).catch(() => {});
|
|
719
|
+
post(api, '/api/heartbeat', { token, pane, sessions: listWindows(session), screens: captureAll(session), tok: LEAGUE_ON ? tok24h() : undefined, tn: _tnCache, notion: { set: notionSet() } }).catch(() => {});
|
|
706
720
|
post(api, '/api/control/claim', { token }).then((c) => { for (const cmd of (c && c.commands) || []) runControl(cmd); }).catch(() => {});
|
|
707
721
|
const d = await post(api, '/api/jobs/claim', { token });
|
|
708
722
|
for (const j of (d.jobs || [])) onJob(j);
|