@cliphijack/santaclaude 1.0.6 → 1.0.7
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 +11 -12
package/package.json
CHANGED
package/santaclaude.js
CHANGED
|
@@ -279,9 +279,13 @@ async function run(conf) {
|
|
|
279
279
|
console.log(` ⌨️ 키 → ${w}: ${cmd.key}`);
|
|
280
280
|
} else if (cmd.action === 'resize') {
|
|
281
281
|
// 웹 뷰어 폭에 맞춰 tmux 윈도우 리사이즈 — claude TUI가 그 폭으로 reflow(모바일 가로스크롤 해소)
|
|
282
|
+
// 보통 cols만 옴 = 폭만 맞추고 높이는 그대로(스크롤백으로 세로 내역 풍부하게). rows 오면 같이 적용.
|
|
282
283
|
const w = (cmd.name && windowExists(session, cmd.name)) ? (session + ':' + cmd.name) : pane;
|
|
283
|
-
const
|
|
284
|
-
|
|
284
|
+
const c = parseInt(cmd.cols) || 0, rr = parseInt(cmd.rows) || 0;
|
|
285
|
+
const args = ['resize-window', '-t', w];
|
|
286
|
+
if (c > 0) args.push('-x', String(Math.max(20, Math.min(400, c))));
|
|
287
|
+
if (rr > 0) args.push('-y', String(Math.max(10, Math.min(200, rr))));
|
|
288
|
+
if (args.length > 3) { try { execFileSync('tmux', args); console.log(` 📐 리사이즈 ${w} → 폭${c || '그대로'}${rr ? '×높이' + rr : ''}`); } catch (e) {} }
|
|
285
289
|
}
|
|
286
290
|
} catch (e) { console.warn(` ⚠️ 제어 실패(${cmd.action} ${cmd.name}): ${e.message}`); }
|
|
287
291
|
}
|
|
@@ -312,10 +316,8 @@ async function run(conf) {
|
|
|
312
316
|
const r = await fetch(api + '/api/skill', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, name, publisher, files, public: true }) });
|
|
313
317
|
const j = await r.json();
|
|
314
318
|
if (j.ok) {
|
|
315
|
-
console.log(` 🏪 스킬 "${name}" 마켓 클린등록 완료`);
|
|
319
|
+
console.log(` 🏪 스킬 "${name}" 마켓 클린등록 완료`); // 확인은 웹 마켓에 — claude 입력칸 주입 금지(사용자 메시지로 오인됨)
|
|
316
320
|
try { fs.rmSync(d, { recursive: true, force: true }); } catch (e) {}
|
|
317
|
-
execFileSync('tmux', ['send-keys', '-t', pane, '-l', '🏪 "' + name + '" 마켓에 클린 등록됐어!']);
|
|
318
|
-
setTimeout(() => { try { execFileSync('tmux', ['send-keys', '-t', pane, 'Enter']); } catch (e) {} }, 300);
|
|
319
321
|
} else { console.warn(` 스킬 등록 실패(${name}): ${j.error}`); try { fs.unlinkSync(path.join(d, 'READY')); } catch (e) {} }
|
|
320
322
|
} catch (e) { console.error('[scan fetch err]', e.message); }
|
|
321
323
|
}
|
|
@@ -335,10 +337,8 @@ async function run(conf) {
|
|
|
335
337
|
try {
|
|
336
338
|
const j = await post(api, '/api/schedule', Object.assign({}, req, { token }));
|
|
337
339
|
if (j.ok) {
|
|
338
|
-
console.log(` 🎄 세션 예약 등록 — ${req.kind || 'once'} · ${String(req.message).slice(0, 40)}`);
|
|
340
|
+
console.log(` 🎄 세션 예약 등록 — ${req.kind || 'once'} · ${String(req.message).slice(0, 40)}`); // 확인은 웹 예약내역에 — claude 주입 금지
|
|
339
341
|
try { fs.unlinkSync(fp); } catch (e) {}
|
|
340
|
-
execFileSync('tmux', ['send-keys', '-t', pane, '-l', '🎄 예약 걸렸어 — ' + String(req.message).slice(0, 40)]);
|
|
341
|
-
setTimeout(() => { try { execFileSync('tmux', ['send-keys', '-t', pane, 'Enter']); } catch (e) {} }, 300);
|
|
342
342
|
} else { console.warn(` 예약 실패: ${j.error}`); try { fs.renameSync(fp, fp + '.err'); } catch (e) {} }
|
|
343
343
|
} catch (e) { console.error('[sched fetch err]', e.message); }
|
|
344
344
|
}
|
|
@@ -348,7 +348,7 @@ async function run(conf) {
|
|
|
348
348
|
// 루돌프가 사용자에게 보내는 파일 — santa-show 스킬이 ~/.santaclaude/outbox/ 에 복사하면 릴레이
|
|
349
349
|
const OUTBOXDIR = path.join(os.homedir(), '.santaclaude', 'outbox');
|
|
350
350
|
const MAXOUT = 18 * 1024 * 1024; // 18MB (KV 릴레이 한계 — 초과는 R2 예정)
|
|
351
|
-
|
|
351
|
+
// 주의: 상태 알림을 claude pane에 send-keys 하면 사용자 메시지로 오인돼 claude가 되받아침 → 절대 금지. 확인은 웹 UI(드로어)에서.
|
|
352
352
|
async function scanOutbox() {
|
|
353
353
|
try {
|
|
354
354
|
if (!fs.existsSync(OUTBOXDIR)) return;
|
|
@@ -357,7 +357,7 @@ async function run(conf) {
|
|
|
357
357
|
const fp = path.join(OUTBOXDIR, fn);
|
|
358
358
|
let st; try { st = fs.statSync(fp); } catch (e) { continue; }
|
|
359
359
|
if (!st.isFile()) continue;
|
|
360
|
-
if (st.size > MAXOUT) { console.warn(` ⚠️ "${fn}" ${(st.size / 1048576).toFixed(1)}MB > 18MB — 못
|
|
360
|
+
if (st.size > MAXOUT) { console.warn(` ⚠️ "${fn}" ${(st.size / 1048576).toFixed(1)}MB > 18MB — 못 보냄(R2 대기)`); try { fs.renameSync(fp, fp + '.toobig'); } catch (e) {} continue; }
|
|
361
361
|
const ext = (fn.split('.').pop() || '').toLowerCase();
|
|
362
362
|
const mime = EXT_MIME[ext] || 'application/octet-stream';
|
|
363
363
|
let data; try { data = fs.readFileSync(fp).toString('base64'); } catch (e) { continue; }
|
|
@@ -365,9 +365,8 @@ async function run(conf) {
|
|
|
365
365
|
const j = await post(api, '/api/upload', { token, data, mime, name: fn });
|
|
366
366
|
if (j && j.id) {
|
|
367
367
|
await post(api, '/api/outfile', { token, id: j.id, name: fn, mime, size: st.size }).catch(() => {});
|
|
368
|
-
console.log(` 📤 "${fn}" (${(st.size / 1024).toFixed(0)}KB) → 사용자 화면으로 보냄`);
|
|
368
|
+
console.log(` 📤 "${fn}" (${(st.size / 1024).toFixed(0)}KB) → 사용자 화면으로 보냄`); // 확인은 웹 드로어 '받은파일'에 — claude 주입 금지
|
|
369
369
|
try { fs.unlinkSync(fp); } catch (e) {}
|
|
370
|
-
tmuxNote('📤 보냈어 — ' + fn);
|
|
371
370
|
} else { console.warn(` 파일 보내기 실패(${fn}): ${j && j.error}`); try { fs.renameSync(fp, fp + '.err'); } catch (e) {} }
|
|
372
371
|
} catch (e) { console.error('[outbox fetch err]', e.message); }
|
|
373
372
|
}
|