@cliphijack/santaclaude 1.0.7 → 1.0.9

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 +35 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cliphijack/santaclaude",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "publishConfig": { "access": "public" },
5
5
  "description": "SantaClaude 커넥터 — 클라우드 예약을 내 로컬 Claude(tmux)에 발사",
6
6
  "bin": { "santaclaude": "./santaclaude.js" },
package/santaclaude.js CHANGED
@@ -29,6 +29,8 @@ function parseArgs(argv) {
29
29
  function loadConf() { try { return JSON.parse(fs.readFileSync(CONF, 'utf8')); } catch { return {}; } }
30
30
  function saveConf(c) { fs.writeFileSync(CONF, JSON.stringify(c, null, 2)); }
31
31
  function paneExists(pane) { try { execFileSync('tmux', ['has-session', '-t', pane.split(':')[0]], { stdio: 'ignore' }); return true; } catch { return false; } }
32
+ // 사람이 직접 이 세션에 붙어있나(tmux attach 등). 붙어있으면 리사이즈 금지 — 고객 화면 망가뜨리면 안 됨
33
+ function clientsAttached(session) { try { return execFileSync('tmux', ['list-clients', '-t', session, '-F', '#{client_name}'], { encoding: 'utf8' }).trim().length > 0; } catch (e) { return false; } }
32
34
 
33
35
  function inject(pane, message) {
34
36
  const msg = String(message);
@@ -54,7 +56,7 @@ function spawnClaude(session, cmd, cwd) {
54
56
  }
55
57
  // 한 세션(작업장) 안에 새 윈도우(탭)로 claude 실행 — 프로젝트별 분리
56
58
  function spawnWindow(session, name, cmd, cwd) {
57
- try { execFileSync('tmux', ['resize-window', '-t', session, '-x', '220', '-y', '50']); } catch (e) {} // 세션 크게
59
+ if (!clientsAttached(session)) { try { execFileSync('tmux', ['resize-window', '-t', session, '-x', '220', '-y', '50']); } catch (e) {} } // 사람 안 붙어있을 때만 크게(고객 세션 보호)
58
60
  const a = ['new-window', '-t', session, '-n', name];
59
61
  if (cwd) a.push('-c', cwd);
60
62
  execFileSync('tmux', a);
@@ -152,6 +154,34 @@ description: 산타클로드 파일 보내기 — 만든·가진 파일(이미
152
154
  - **원본 그대로 복사** — 재인코딩·리사이즈·압축 금지.
153
155
  - 옮기지 말고 **복사**(cp). 원본 작업물은 그대로 둔다.
154
156
  - 보낸 뒤 사용자에게 "보냈어 — <파일명>" 한 줄 확인.
157
+ `
158
+ },
159
+ 'santa-brain': {
160
+ 'SKILL.md': `---
161
+ name: santa-brain
162
+ description: 산타 Gbrain — 내 노트·문서·지식 폴더에서 답을 찾을 때. "내 노트에서 ~ 찾아줘", "지난번에 정한 ~ 뭐였지", "~ 관련 문서 정리해줘" 등 개인 지식베이스 질의에 사용.
163
+ ---
164
+
165
+ # 산타 Gbrain — 내 지식에서 답 찾기
166
+
167
+ 사용자가 자기 노트·문서·메모에서 무언가를 찾거나 종합해 달라고 하면, **임베딩·벡터DB 없이 직접 파일을 뒤져 출처와 함께 답한다.** 이게 산타클로드 방식 — 네가 두뇌다(외부 비용 0).
168
+
169
+ ## 지식 폴더(brain)
170
+ - 사용자가 폴더를 지정했으면 거기서. 안 했으면 **물어본다**("어느 폴더에서 찾을까? 예: \`~/notes\`").
171
+ - \`~/santa-brain/\` 가 있으면 기본 후보로 써도 된다. 지정 폴더는 기억해 다음에 재사용.
172
+
173
+ ## 절차 (agentic retrieval)
174
+ 1. **검색** — 질문 키워드로 \`grep -ri\`, glob(\`*.md\` 등)으로 후보 파일 추림. 동의어·관련어도 시도.
175
+ 2. **읽기** — 후보 파일 read. 링크(\`[[...]]\`·상대경로) 있으면 따라가 맥락 보강.
176
+ 3. **답** — 근거로 답 작성, **핵심 주장마다 끝에 출처 \`(파일:라인)\` 표기.**
177
+ 4. **gap** — 폴더에 근거 없으면 "근거 없음"이라 말하고 무엇이 더 필요한지 알려준다. **폴더 밖 추측으로 지어내지 말 것.**
178
+ 5. 끝에 **한 줄 요약.**
179
+
180
+ ## 규칙
181
+ - 출처 없는 단정 금지 — 찾은 것만, 출처 달아서.
182
+ - 큰 폴더면 grep으로 먼저 좁히고 **필요한 파일만 read**(토큰 절약).
183
+ - 정리·요약 요청이면 여러 파일 read 후 종합 + 끝에 출처 목록.
184
+ - 노트는 사용자 로컬에만 있고 우리 서버를 거치지 않는다(프라이버시).
155
185
  `
156
186
  }
157
187
  };
@@ -182,8 +212,9 @@ async function run(conf) {
182
212
  cleanOldImages();
183
213
  console.log(`🛷 SantaClaude 커넥터 가동 — pane=${pane} · ${every / 1000}s 폴링 · ${api}`);
184
214
  if (paneExists(pane)) {
185
- try { execFileSync('tmux', ['resize-window', '-t', session, '-x', '220', '-y', '50']); } catch (e) {} // 기존 세션도 크게(더 많은 줄)
186
- console.log(` ✅ tmux "${session}" 세션에 붙음 (기존 claude에 주입).`);
215
+ // 기존(고객) 세션엔 사람이 붙어있을 때만 리사이즈 직접 쓰고 있으면 화면 절대 건드림
216
+ if (!clientsAttached(session)) { try { execFileSync('tmux', ['resize-window', '-t', session, '-x', '220', '-y', '50']); } catch (e) {} }
217
+ console.log(` ✅ tmux "${session}" 세션에 붙음 (기존 claude에 주입${clientsAttached(session) ? ', 사람 사용중→사이즈 안 건드림' : ''}).`);
187
218
  } else if (conf.spawn !== false) {
188
219
  console.log(` 🦌 "${session}" 세션이 없어서 claude를 새로 띄울게…`);
189
220
  try {
@@ -280,6 +311,7 @@ async function run(conf) {
280
311
  } else if (cmd.action === 'resize') {
281
312
  // 웹 뷰어 폭에 맞춰 tmux 윈도우 리사이즈 — claude TUI가 그 폭으로 reflow(모바일 가로스크롤 해소)
282
313
  // 보통 cols만 옴 = 폭만 맞추고 높이는 그대로(스크롤백으로 세로 내역 풍부하게). rows 오면 같이 적용.
314
+ if (clientsAttached(session)) { console.log(' 📐 리사이즈 건너뜀 — 사람이 tmux에 붙어있음(고객 화면 보호)'); return; } // 사람이 직접 보고있으면 reflow로 화면 망가뜨리지 않음
283
315
  const w = (cmd.name && windowExists(session, cmd.name)) ? (session + ':' + cmd.name) : pane;
284
316
  const c = parseInt(cmd.cols) || 0, rr = parseInt(cmd.rows) || 0;
285
317
  const args = ['resize-window', '-t', w];