project-cypher 0.13.0 → 0.14.0

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/bin/cypher.js +17 -2
  2. package/package.json +1 -1
package/bin/cypher.js CHANGED
@@ -242,11 +242,26 @@ const cmds = {
242
242
  if (m.type !== 'prompt') return;
243
243
  if (!proj) return tx({ ...ctx, type: 'error', message: 'unknown project' });
244
244
  if (runs.has(proj.id)) return tx({ ...ctx, type: 'error', message: 'Claude is still working on this project.' });
245
- const cfg = load(); const args = ['-p', m.text, '--output-format', 'stream-json', '--verbose', '--permission-mode', cfg.permissionMode || 'acceptEdits'];
245
+ // Attachments from the phone: saved under ~/.cypher/uploads/<project>/, then referenced in the prompt so Claude can Read them.
246
+ let text = String(m.text || ''); const saved = []; const upDir = path.join(CFG_DIR, 'uploads', proj.id);
247
+ if (Array.isArray(m.files) && m.files.length) {
248
+ try {
249
+ fs.mkdirSync(upDir, { recursive: true });
250
+ for (const f of m.files.slice(0, 6)) {
251
+ if (!f || typeof f.data !== 'string' || f.data.length > 16 * 1024 * 1024) continue;
252
+ const nm = String(f.name || 'file').replace(/[^\w.\- ]+/g, '_').slice(-80) || 'file'; const fp = path.join(upDir, Date.now() + '-' + nm);
253
+ fs.writeFileSync(fp, Buffer.from(f.data, 'base64')); saved.push(fp);
254
+ }
255
+ } catch (e) { console.log('attachment save failed: ' + e.message); }
256
+ if (saved.length) text += '\n\n[The user attached ' + saved.length + ' file(s) from their phone. Read them with the Read tool:]\n' + saved.map(x => '- ' + x).join('\n');
257
+ }
258
+ try { for (const d of fs.readdirSync(path.join(CFG_DIR, 'uploads'))) for (const f of fs.readdirSync(path.join(CFG_DIR, 'uploads', d))) { const fp = path.join(CFG_DIR, 'uploads', d, f); if (Date.now() - fs.statSync(fp).mtimeMs > 7 * 864e5) fs.rmSync(fp, { force: true }); } } catch {}
259
+ const cfg = load(); const args = ['-p', text, '--output-format', 'stream-json', '--verbose', '--permission-mode', cfg.permissionMode || 'acceptEdits'];
246
260
  if (proj.root) { const wsd = rawCfg().workspace; args.push('--allowedTools', ROOT_TOOLS); if (wsd) args.push('--add-dir', wsd); }
261
+ if (saved.length) args.push('--add-dir', upDir);
247
262
  if (typeof m.model === 'string' && /^[a-z][a-z0-9.\-\[\]]{0,60}$/i.test(m.model) && m.model !== 'default') args.push('--model', m.model);
248
263
  if (cfg.sessions?.[proj.id]) args.push('--resume', cfg.sessions[proj.id]);
249
- console.log(`[${proj.id}] ${m.text.slice(0, 60)}`);
264
+ console.log(`[${proj.id}] ${String(m.text || '').slice(0, 60)}${saved.length ? ' (+' + saved.length + ' files)' : ''}`);
250
265
  const ch = spawn('claude', args, { cwd: proj.path, stdio: ['ignore', 'pipe', 'pipe'] }); runs.set(proj.id, ch);
251
266
  let buf = '', err = '';
252
267
  const line = l => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-cypher",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Connect your machine's Claude Code projects to the Project Cypher phone app.",
5
5
  "bin": {
6
6
  "cypher": "bin/cypher.js"