@cliphijack/santaclaude 1.0.25 → 1.0.26

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/santaclaude.js +18 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cliphijack/santaclaude",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "publishConfig": { "access": "public" },
5
5
  "description": "SantaClaude 커넥터 — 클라우드 예약을 내 로컬 Claude(tmux)에 발사",
6
6
  "bin": { "santaclaude": "./santaclaude.js" },
package/santaclaude.js CHANGED
@@ -356,7 +356,7 @@ description: 산타클로드 파일 보내기 — 만든·가진 파일(이미
356
356
 
357
357
  ## 규칙
358
358
  - **파일명 그대로 유지**(확장자 포함) — 사용자가 그 이름으로 받는다.
359
- - **18MB 이하**만 지금 가능. 초과 파일은 보내고 알림이 뜬다 영상은 잘라 보내거나 외부 링크로.
359
+ - **크기 제한 사실상 없음** — 18MB 이하는 자동 릴레이, 파일(영상 등)은 테일스케일이 켜져 있으면 **테일넷 직다운(📡)으로 자동 전환**(폰이 같은 테일넷이면 한도 없이 받음). 테일스케일이 없을 때만 18MB 초과 불가.
360
360
  - **원본 그대로 복사** — 재인코딩·리사이즈·압축 금지.
361
361
  - 옮기지 말고 **복사**(cp). 원본 작업물은 그대로 둔다.
362
362
  - 보낸 뒤 사용자에게 "보냈어 — <파일명>" 한 줄 확인.
@@ -399,9 +399,11 @@ function installDefaultSkills(cwd) {
399
399
  for (const [fn, content] of Object.entries(files)) {
400
400
  try {
401
401
  const fp = path.join(base, '.claude', 'skills', name, fn);
402
- if (fs.existsSync(fp)) continue; // 이미 있으면 덮지 않음(고객 수정 보존)
402
+ const existed = fs.existsSync(fp);
403
+ if (existed) { try { if (fs.readFileSync(fp, 'utf8') === content) continue; } catch (e) {} } // santa-* 는 시스템 스킬 — 내용 다르면(구버전) 갱신, 같으면 스킵
403
404
  fs.mkdirSync(path.dirname(fp), { recursive: true });
404
405
  fs.writeFileSync(fp, content);
406
+ if (existed) console.log(` 🔄 기본 스킬 갱신: ${name}`);
405
407
  } catch (e) {}
406
408
  }
407
409
  }
@@ -436,7 +438,8 @@ async function run(conf) {
436
438
  console.warn(` ⚠️ tmux "${session}" 세션 없음 (--no-spawn) — 직접 띄워줘.`);
437
439
  }
438
440
  // 기본 스킬 자동 설치 (메인 루돌프 작업 폴더에)
439
- try { let c = os.homedir(); try { const pc = execFileSync('tmux', ['display-message', '-t', pane, '-p', '#{pane_current_path}'], { encoding: 'utf8' }).trim(); if (pc) c = pc; } catch (e) {} installDefaultSkills(c); } catch (e) {}
441
+ try { installDefaultSkills(os.homedir()); } catch (e) {} // 글로벌(~/.claude/skills) 기본스킬 설치·갱신 모든 세션 공용
442
+ try { let c = ''; try { const pc = execFileSync('tmux', ['display-message', '-t', pane, '-p', '#{pane_current_path}'], { encoding: 'utf8' }).trim(); if (pc && pc !== os.homedir()) c = pc; } catch (e) {} if (c) installDefaultSkills(c); } catch (e) {}
440
443
 
441
444
  // 루돌프 = 작업장(session) 안의 윈도우(탭). 별도 세션 아님.
442
445
  async function runControl(cmd) {
@@ -637,7 +640,18 @@ async function run(conf) {
637
640
  const fp = path.join(OUTBOXDIR, fn);
638
641
  let st; try { st = fs.statSync(fp); } catch (e) { continue; }
639
642
  if (!st.isFile()) continue;
640
- if (st.size > MAXOUT) { console.warn(` ⚠️ "${fn}" ${(st.size / 1048576).toFixed(1)}MB > 18MB 못 보냄(R2 대기)`); try { fs.renameSync(fp, fp + '.toobig'); } catch (e) {} continue; }
643
+ if (st.size > MAXOUT) { // 18MB 초과 테일스케일 있으면 share/로 옮겨 미니서버 직다운(📡), 없으면 보류
644
+ if (_tnCache && _tnCache.ip) {
645
+ try {
646
+ const shareDir = path.join(os.homedir(), '.santaclaude', 'share'); fs.mkdirSync(shareDir, { recursive: true });
647
+ fs.renameSync(fp, path.join(shareDir, fn)); // outbox 밖으로 → 재스캔 안 됨, 미니서버가 서빙
648
+ const mime = EXT_MIME[(fn.split('.').pop() || '').toLowerCase()] || 'application/octet-stream';
649
+ await post(api, '/api/outfile', { token, name: fn, mime, size: st.size, tn: true }).catch(() => {});
650
+ console.log(` 📡 "${fn}" ${(st.size / 1048576).toFixed(1)}MB → 테일넷 직다운(share/)`);
651
+ } catch (e) { console.warn(' big→테일넷 실패: ' + e.message); }
652
+ } else { console.warn(` ⚠️ "${fn}" ${(st.size / 1048576).toFixed(1)}MB > 18MB · 테일스케일 없어 못 보냄`); try { fs.renameSync(fp, fp + '.toobig'); } catch (e) {} }
653
+ continue;
654
+ }
641
655
  const ext = (fn.split('.').pop() || '').toLowerCase();
642
656
  const mime = EXT_MIME[ext] || 'application/octet-stream';
643
657
  let data; try { data = fs.readFileSync(fp).toString('base64'); } catch (e) { continue; }