@cliphijack/santaclaude 0.9.2 → 0.9.3
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 +35 -1
package/package.json
CHANGED
package/santaclaude.js
CHANGED
|
@@ -74,6 +74,14 @@ function captureWindow(session, name) {
|
|
|
74
74
|
function captureAll(session) {
|
|
75
75
|
const o = {}; for (const w of listWindows(session)) o[w] = captureWindow(session, w); return o;
|
|
76
76
|
}
|
|
77
|
+
// 받은 이미지 24시간 지난 건 로컬에서 청소
|
|
78
|
+
function cleanOldImages() {
|
|
79
|
+
try {
|
|
80
|
+
const dir = path.join(os.homedir(), '.santaclaude', 'img'); if (!fs.existsSync(dir)) return;
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
for (const f of fs.readdirSync(dir)) { const fp = path.join(dir, f); try { if (now - fs.statSync(fp).mtimeMs > 86400000) fs.unlinkSync(fp); } catch (e) {} }
|
|
83
|
+
} catch (e) {}
|
|
84
|
+
}
|
|
77
85
|
|
|
78
86
|
async function post(api, p, body) {
|
|
79
87
|
const r = await fetch(api + p, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
|
@@ -88,6 +96,7 @@ async function run(conf) {
|
|
|
88
96
|
const claudeCmd = conf.claudeCmd || 'claude --dangerously-skip-permissions';
|
|
89
97
|
let warned = false; // 중복방지는 서버가 책임 (claim 시 next_fire 원자적 전진) — 클라 영구셋은 반복예약을 영구차단하므로 안 둠
|
|
90
98
|
|
|
99
|
+
cleanOldImages();
|
|
91
100
|
console.log(`🛷 SantaClaude 커넥터 가동 — pane=${pane} · ${every / 1000}s 폴링 · ${api}`);
|
|
92
101
|
if (paneExists(pane)) {
|
|
93
102
|
try { execFileSync('tmux', ['resize-window', '-t', session, '-x', '220', '-y', '50']); } catch (e) {} // 기존 세션도 크게(더 많은 줄)
|
|
@@ -103,8 +112,33 @@ async function run(conf) {
|
|
|
103
112
|
}
|
|
104
113
|
|
|
105
114
|
// 루돌프 = 작업장(session) 안의 윈도우(탭). 별도 세션 아님.
|
|
106
|
-
function runControl(cmd) {
|
|
115
|
+
async function runControl(cmd) {
|
|
107
116
|
try {
|
|
117
|
+
if (cmd.action === 'image') {
|
|
118
|
+
// 웹이 올린 이미지를 받아 로컬에 저장하고 claude에 경로 주입
|
|
119
|
+
const dir = path.join(os.homedir(), '.santaclaude', 'img');
|
|
120
|
+
try { fs.mkdirSync(dir, { recursive: true }); } catch (e) {}
|
|
121
|
+
const paths = [];
|
|
122
|
+
for (const im of (cmd.imgs || [])) {
|
|
123
|
+
try {
|
|
124
|
+
const r = await fetch(api + '/api/img?token=' + encodeURIComponent(token) + '&id=' + encodeURIComponent(im.id));
|
|
125
|
+
if (!r.ok) continue;
|
|
126
|
+
const j = await r.json();
|
|
127
|
+
const ext = String(j.mime || '').includes('png') ? 'png' : String(j.mime || '').includes('webp') ? 'webp' : 'jpg';
|
|
128
|
+
const fp = path.join(dir, Date.now() + '_' + paths.length + '.' + ext);
|
|
129
|
+
fs.writeFileSync(fp, Buffer.from(j.data, 'base64'));
|
|
130
|
+
paths.push(fp);
|
|
131
|
+
} catch (e) {}
|
|
132
|
+
}
|
|
133
|
+
if (paths.length) {
|
|
134
|
+
const w = (cmd.name && windowExists(session, cmd.name)) ? (session + ':' + cmd.name) : pane;
|
|
135
|
+
const msg = (cmd.note ? cmd.note + ' ' : '') + '첨부 이미지 ' + paths.length + '장 봐줘: ' + paths.join(' ');
|
|
136
|
+
execFileSync('tmux', ['send-keys', '-t', w, '-l', msg]);
|
|
137
|
+
setTimeout(() => { try { execFileSync('tmux', ['send-keys', '-t', w, 'Enter']); } catch (e) {} }, 300);
|
|
138
|
+
console.log(` 🖼️ 이미지 ${paths.length}장 → ${w}`);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
108
142
|
if (cmd.action === 'create') {
|
|
109
143
|
if (!paneExists(session)) spawnClaude(session, claudeCmd); // 작업장 세션 없으면 먼저 띄움
|
|
110
144
|
if (windowExists(session, cmd.name)) { console.log(` 🦌 "${cmd.name}" 탭 이미 있어 — 안 만듦`); return; }
|