project-cypher 0.19.0 → 0.21.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 +15 -1
  2. package/package.json +1 -1
package/bin/cypher.js CHANGED
@@ -287,7 +287,7 @@ const cmds = {
287
287
  connect() {
288
288
  const autoOn = id => !!rawCfg().autoApprove?.[id];
289
289
  const announce = () => [{ id: 'root', name: 'Root', root: true, auto: autoOn('root') }, ...readRegistry().map(({ id, name, summary }) => ({ id, name, summary, auto: autoOn(id) }))];
290
- const hello = () => ({ type: 'hello', name: devName(), projects: announce(), running: [...runs].map(([projectId, ch]) => ({ projectId, reqId: ch.reqId })) }); // running: lets the relay know which prompts are still in progress after a reconnect
290
+ const hello = () => ({ type: 'hello', ver: require('../package.json').version, npm: fs.realpathSync(__filename).includes(path.sep + 'node_modules' + path.sep), name: devName(), projects: announce(), running: [...runs].map(([projectId, ch]) => ({ projectId, reqId: ch.reqId })) }); // running: lets the relay know which prompts are still in progress after a reconnect
291
291
  const WebSocket = require('ws'); let c = load(); if (!c.token) return console.log('not linked yet. Run: cypher link');
292
292
  ensureRoot();
293
293
  const runs = new Map(); let retry = 1000; let tx = () => false;
@@ -341,6 +341,19 @@ const cmds = {
341
341
  if (m.type === 'rmproject') { if (m.projectId !== 'root') writeRegistry(readRegistry().filter(x => x.id !== m.projectId)); return; }
342
342
  if (m.type === 'autoapprove') { const k = rawCfg(); k.autoApprove = { ...(k.autoApprove || {}) }; if (m.on) k.autoApprove[m.projectId] = true; else delete k.autoApprove[m.projectId]; save(k); console.log(`[${m.projectId}] auto-approve ${m.on ? 'ON' : 'off'}`); return tx(hello()); }
343
343
  if (m.type === 'reset') { const k = load(); if (k.sessions) { delete k.sessions[m.projectId]; save(k); } return; }
344
+ if (m.type === 'update') { // phone asked this computer to update itself (fixed npm command only)
345
+ const say = (ok, message) => tx({ type: 'updated', ok, message });
346
+ const cur = require('../package.json').version;
347
+ if (!fs.realpathSync(__filename).includes(path.sep + 'node_modules' + path.sep)) return say(false, 'This copy runs from a source folder. Update it with git pull.');
348
+ if (runs.size) return say(false, 'Claude is working. Try again when it finishes.');
349
+ const cp = require('child_process'); const win = process.platform === 'win32';
350
+ cp.execFile('npm', ['i', '-g', 'project-cypher@latest', '--prefer-online'], { shell: win, timeout: 300000 }, (err, so, se) => {
351
+ if (err) return say(false, ('Update failed: ' + (String(se).trim().split('\n').filter(Boolean).pop() || err.message)).slice(0, 200));
352
+ say(true, 'Updated. Restarting.'); console.log('updated from ' + cur + ' via the app');
353
+ setTimeout(() => { if (SVC.running()) SVC.start(); else process.exit(0); }, 800);
354
+ });
355
+ return;
356
+ }
344
357
  if (m.type === 'sessions') { if (!proj) return; return tx({ ...ctx, type: 'sessions', list: listSessions(proj.path, load().sessions?.[proj.id]) }); }
345
358
  if (m.type === 'usesession') { // switch the project to an older Claude session and send its chat back
346
359
  if (!proj || !SID.test(String(m.id))) return tx({ ...ctx, type: 'error', message: 'Unknown session.' });
@@ -379,6 +392,7 @@ const cmds = {
379
392
  let e; try { e = JSON.parse(l); } catch { return; }
380
393
  if (e.type === 'assistant') for (const b of e.message?.content || []) {
381
394
  if (b.type === 'text' && b.text) tx({ ...ctx, type: 'text', text: b.text });
395
+ else if (b.type === 'thinking' && b.thinking) tx({ ...ctx, type: 'thinking', text: String(b.thinking).slice(-600) });
382
396
  else if (b.type === 'tool_use') { const i = b.input || {}; tx({ ...ctx, type: 'tool', name: b.name, summary: String(i.file_path || i.command || i.pattern || i.path || i.url || i.description || '').slice(0, 120) }); }
383
397
  } else if (e.type === 'result') {
384
398
  if (e.session_id) { const k = load(); k.sessions = { ...k.sessions, [proj.id]: e.session_id }; save(k); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-cypher",
3
- "version": "0.19.0",
3
+ "version": "0.21.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"