project-cypher 0.12.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.
- package/bin/cypher.js +30 -4
- package/package.json +1 -1
package/bin/cypher.js
CHANGED
|
@@ -194,7 +194,17 @@ const cmds = {
|
|
|
194
194
|
let id = slug(p), n = 2; if (id === 'root') id = 'root-project'; while (list.some(x => x.id === id)) id = slug(p) + '-' + n++;
|
|
195
195
|
list.push({ id, name: path.basename(p), path: p, summary: '' }); writeRegistry(list); console.log(`added ${id} (${p})`);
|
|
196
196
|
},
|
|
197
|
-
remove(id) {
|
|
197
|
+
async remove(id, ...rest) {
|
|
198
|
+
if (id && id !== '--yes') { writeRegistry(readRegistry().filter(x => x.id !== id)); return console.log('removed project ' + id); }
|
|
199
|
+
console.log(`This fully removes Cypher from this computer:\n - unlinks it from your phone app\n - stops and deletes the background service\n - deletes ${CFG_DIR} (login, project list, Root notes, chat sessions)\nYour actual project folders are NOT touched.`);
|
|
200
|
+
if (id !== '--yes' && !rest.includes('--yes') && !yes(await ask('Continue? [y/N] '), false)) return console.log('cancelled.');
|
|
201
|
+
const c = rawCfg();
|
|
202
|
+
if (c.token) await fetch(httpOf(c.server || 'http://140.238.248.30:3300') + '/unlink', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ token: c.token }) }).then(() => console.log('[ok] unlinked from the app')).catch(() => console.log('[!!] could not reach the server; remove this computer from the app Projects list'));
|
|
203
|
+
SVC.remove(); console.log('[ok] background service removed');
|
|
204
|
+
fs.rmSync(CFG_DIR, { recursive: true, force: true }); console.log('[ok] deleted ' + CFG_DIR);
|
|
205
|
+
console.log('\nClean. To reinstall: npm i -g project-cypher@latest && cypher init\nTo also remove the program itself: npm uninstall -g project-cypher');
|
|
206
|
+
},
|
|
207
|
+
removeProject(id) { writeRegistry(readRegistry().filter(x => x.id !== id)); console.log('removed ' + id); },
|
|
198
208
|
projects() { const c = load(); if (!c.projects.length) return console.log('none yet. cypher add <folder>'); c.projects.forEach(p => console.log(`${p.id.padEnd(20)} ${p.path}`)); },
|
|
199
209
|
// Service control
|
|
200
210
|
start() { const c = load(); if (!c.token) return console.log('Not linked yet. Run: cypher init'); console.log(SVC.start() ? 'Cypher is running in the background and will start automatically when this computer turns on.' : 'Could not start the background service. Run it in this window instead: cypher connect'); },
|
|
@@ -232,11 +242,26 @@ const cmds = {
|
|
|
232
242
|
if (m.type !== 'prompt') return;
|
|
233
243
|
if (!proj) return tx({ ...ctx, type: 'error', message: 'unknown project' });
|
|
234
244
|
if (runs.has(proj.id)) return tx({ ...ctx, type: 'error', message: 'Claude is still working on this project.' });
|
|
235
|
-
|
|
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'];
|
|
236
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);
|
|
237
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);
|
|
238
263
|
if (cfg.sessions?.[proj.id]) args.push('--resume', cfg.sessions[proj.id]);
|
|
239
|
-
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)' : ''}`);
|
|
240
265
|
const ch = spawn('claude', args, { cwd: proj.path, stdio: ['ignore', 'pipe', 'pipe'] }); runs.set(proj.id, ch);
|
|
241
266
|
let buf = '', err = '';
|
|
242
267
|
const line = l => {
|
|
@@ -266,7 +291,8 @@ const help = () => console.log(`Project Cypher
|
|
|
266
291
|
cypher link [server-url] link this computer to your phone (QR or code), add this folder, go online
|
|
267
292
|
cypher pair <server-url> <code> alternative: pair with a code made in the app
|
|
268
293
|
cypher add [folder] register a project folder (or just ask Root in the app)
|
|
269
|
-
cypher projects | remove <id> list / remove
|
|
294
|
+
cypher projects | remove <id> list projects / remove one project
|
|
295
|
+
cypher remove FULL removal (unlink, service, all local data) for a clean reinstall
|
|
270
296
|
cypher disconnect unlink this computer from the app
|
|
271
297
|
cypher connect go online in this window (no background service)
|
|
272
298
|
cypher start | stop start / stop the background service (auto-starts at boot)
|