@supacortex/cli 0.1.4 → 0.2.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/dist/index.js +232 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -233,7 +233,6 @@ var registerBookmarksCommand = (program2) => {
|
|
|
233
233
|
console.log(`URL: ${data.url}`);
|
|
234
234
|
if (data.author) console.log(`Author: ${data.author}`);
|
|
235
235
|
if (data.content) console.log(`Content: ${data.content.slice(0, 200)}${data.content.length > 200 ? "\u2026" : ""}`);
|
|
236
|
-
console.log(`Read: ${data.isRead ? "yes" : "no"}`);
|
|
237
236
|
console.log(`Created: ${data.createdAt}`);
|
|
238
237
|
});
|
|
239
238
|
bookmarks.command("delete").description("Delete a bookmark").argument("<id>", "Bookmark ID to delete").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
@@ -357,6 +356,236 @@ var registerUpdateCommand = (program2, version) => {
|
|
|
357
356
|
});
|
|
358
357
|
};
|
|
359
358
|
|
|
359
|
+
// src/commands/conversation.ts
|
|
360
|
+
var TIERS = ["brief", "summary", "detailed"];
|
|
361
|
+
var tierType = (tier) => `conversation_${tier}`;
|
|
362
|
+
var registerConversationCommand = (program2) => {
|
|
363
|
+
const convo = program2.command("conversation").description("Manage conversation memories \u2014 summaries of AI chat sessions");
|
|
364
|
+
convo.command("list").option("-s, --search <string>", "Search conversations").option("--tier <tier>", "Filter by tier (brief, summary, detailed)").option("-l, --limit <number>", "Max results", "20").option("-o, --offset <number>", "Skip results").option("-j, --json", "Output raw JSON").description("List saved conversations").action(async (option) => {
|
|
365
|
+
const searchParams = new URLSearchParams();
|
|
366
|
+
if (option.limit) searchParams.append("limit", String(parseInt(option.limit, 10)));
|
|
367
|
+
if (option.offset) searchParams.append("offset", String(parseInt(option.offset, 10)));
|
|
368
|
+
if (option.search) searchParams.append("search", option.search);
|
|
369
|
+
if (option.tier) {
|
|
370
|
+
if (!TIERS.includes(option.tier)) {
|
|
371
|
+
console.error(`Error: --tier must be one of: ${TIERS.join(", ")}`);
|
|
372
|
+
process.exit(1);
|
|
373
|
+
}
|
|
374
|
+
searchParams.append("type", tierType(option.tier));
|
|
375
|
+
} else {
|
|
376
|
+
searchParams.append("type", "conversation_brief");
|
|
377
|
+
searchParams.delete("type");
|
|
378
|
+
}
|
|
379
|
+
const result = await apiRequest(`memory?${searchParams.toString()}`, "GET");
|
|
380
|
+
if (option.json) {
|
|
381
|
+
console.log(JSON.stringify(result, null, 2));
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const { data } = result;
|
|
385
|
+
const conversations = option.tier ? data : data.filter((m) => String(m.type).startsWith("conversation_"));
|
|
386
|
+
if (conversations.length === 0) {
|
|
387
|
+
console.log("No conversations found.");
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
for (const m of conversations) {
|
|
391
|
+
const title = m.title || m.content?.slice(0, 80) || "Untitled";
|
|
392
|
+
const truncated = title.length > 80 ? title.slice(0, 80) + "..." : title;
|
|
393
|
+
const tier = String(m.type).replace("conversation_", "");
|
|
394
|
+
const date = m.createdAt ? new Date(m.createdAt).toISOString().slice(0, 10) : "";
|
|
395
|
+
console.log(` ${truncated}`);
|
|
396
|
+
console.log(` ${tier} \xB7 ${date}`);
|
|
397
|
+
console.log();
|
|
398
|
+
}
|
|
399
|
+
console.log(`Showing ${conversations.length} conversations`);
|
|
400
|
+
});
|
|
401
|
+
convo.command("add").description("Save a conversation summary").argument("<content>", "Conversation summary text").requiredOption("--tier <tier>", "Tier: brief (1 sentence), summary (bullet points), detailed (full document)").option("-t, --title <string>", "Title for the conversation").option("-m, --metadata <json>", "Metadata as JSON (e.g. source, sessionId, tags)").option("-j, --json", "Output raw JSON").action(async (content, option) => {
|
|
402
|
+
if (!TIERS.includes(option.tier)) {
|
|
403
|
+
console.error(`Error: --tier must be one of: ${TIERS.join(", ")}`);
|
|
404
|
+
process.exit(1);
|
|
405
|
+
}
|
|
406
|
+
const body = {
|
|
407
|
+
type: tierType(option.tier),
|
|
408
|
+
content
|
|
409
|
+
};
|
|
410
|
+
if (option.title) body.title = option.title;
|
|
411
|
+
if (option.metadata) {
|
|
412
|
+
try {
|
|
413
|
+
body.metadata = JSON.parse(option.metadata);
|
|
414
|
+
} catch {
|
|
415
|
+
console.error("Error: --metadata must be valid JSON");
|
|
416
|
+
process.exit(1);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const result = await apiRequest("memory", "POST", body);
|
|
420
|
+
if (option.json) {
|
|
421
|
+
console.log(JSON.stringify(result, null, 2));
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
console.log(`Conversation saved: ${result.title || result.content?.slice(0, 60) || result.id}`);
|
|
425
|
+
});
|
|
426
|
+
convo.command("get").description("Get a conversation by ID").argument("<id>", "Conversation ID").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
427
|
+
const data = await apiRequest(`memory/${id}`, "GET");
|
|
428
|
+
if (option.json) {
|
|
429
|
+
console.log(JSON.stringify(data, null, 2));
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
const tier = String(data.type).replace("conversation_", "");
|
|
433
|
+
console.log(`ID: ${data.id}`);
|
|
434
|
+
console.log(`Tier: ${tier}`);
|
|
435
|
+
console.log(`Title: ${data.title || "(none)"}`);
|
|
436
|
+
console.log(`Content: ${data.content?.slice(0, 500)}${data.content?.length > 500 ? "\u2026" : ""}`);
|
|
437
|
+
if (data.metadata) console.log(`Metadata: ${JSON.stringify(data.metadata)}`);
|
|
438
|
+
console.log(`Created: ${data.createdAt}`);
|
|
439
|
+
if (data.updatedAt) console.log(`Updated: ${data.updatedAt}`);
|
|
440
|
+
});
|
|
441
|
+
convo.command("update").description("Update a saved conversation").argument("<id>", "Conversation ID").option("-t, --title <string>", "New title").option("-c, --content <string>", "New content").option("--tier <tier>", "Change tier (brief, summary, detailed)").option("-m, --metadata <json>", "New metadata as JSON").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
442
|
+
const body = {};
|
|
443
|
+
if (option.title) body.title = option.title;
|
|
444
|
+
if (option.content) body.content = option.content;
|
|
445
|
+
if (option.tier) {
|
|
446
|
+
if (!TIERS.includes(option.tier)) {
|
|
447
|
+
console.error(`Error: --tier must be one of: ${TIERS.join(", ")}`);
|
|
448
|
+
process.exit(1);
|
|
449
|
+
}
|
|
450
|
+
body.type = tierType(option.tier);
|
|
451
|
+
}
|
|
452
|
+
if (option.metadata) {
|
|
453
|
+
try {
|
|
454
|
+
body.metadata = JSON.parse(option.metadata);
|
|
455
|
+
} catch {
|
|
456
|
+
console.error("Error: --metadata must be valid JSON");
|
|
457
|
+
process.exit(1);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (Object.keys(body).length === 0) {
|
|
461
|
+
console.error("Error: provide at least one field to update (--title, --content, --tier, --metadata)");
|
|
462
|
+
process.exit(1);
|
|
463
|
+
}
|
|
464
|
+
const result = await apiRequest(`memory/${id}`, "PATCH", body);
|
|
465
|
+
if (option.json) {
|
|
466
|
+
console.log(JSON.stringify(result, null, 2));
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
console.log(`Conversation updated: ${result.title || result.id}`);
|
|
470
|
+
});
|
|
471
|
+
convo.command("delete").description("Delete a saved conversation").argument("<id>", "Conversation ID").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
472
|
+
const result = await apiRequest(`memory/${id}`, "DELETE");
|
|
473
|
+
if (option.json) {
|
|
474
|
+
console.log(JSON.stringify(result, null, 2));
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
console.log("Conversation deleted.");
|
|
478
|
+
});
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
// src/commands/identity.ts
|
|
482
|
+
var CATEGORIES = ["core", "goals", "preferences", "interests"];
|
|
483
|
+
var registerIdentityCommand = (program2) => {
|
|
484
|
+
const identity = program2.command("identity").description("Manage identity \u2014 persistent context about the user (name, goals, preferences, interests)");
|
|
485
|
+
identity.command("list").option("-s, --search <string>", "Search identity entries").option("--category <category>", "Filter by category (core, goals, preferences, interests)").option("-l, --limit <number>", "Max results", "20").option("-o, --offset <number>", "Skip results").option("-j, --json", "Output raw JSON").description("List identity entries").action(async (option) => {
|
|
486
|
+
const searchParams = new URLSearchParams();
|
|
487
|
+
searchParams.append("type", "identity");
|
|
488
|
+
if (option.limit) searchParams.append("limit", String(parseInt(option.limit, 10)));
|
|
489
|
+
if (option.offset) searchParams.append("offset", String(parseInt(option.offset, 10)));
|
|
490
|
+
if (option.search) searchParams.append("search", option.search);
|
|
491
|
+
const result = await apiRequest(`memory?${searchParams.toString()}`, "GET");
|
|
492
|
+
if (option.json) {
|
|
493
|
+
console.log(JSON.stringify(result, null, 2));
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
let { data } = result;
|
|
497
|
+
if (option.category) {
|
|
498
|
+
data = data.filter(
|
|
499
|
+
(m) => m.metadata?.category === option.category
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
if (data.length === 0) {
|
|
503
|
+
console.log("No identity entries found.");
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
for (const m of data) {
|
|
507
|
+
const category = m.metadata?.category || "uncategorized";
|
|
508
|
+
const title = m.title || m.content?.slice(0, 80) || "Untitled";
|
|
509
|
+
const truncated = title.length > 80 ? title.slice(0, 80) + "..." : title;
|
|
510
|
+
console.log(` ${truncated}`);
|
|
511
|
+
console.log(` ${category}`);
|
|
512
|
+
console.log();
|
|
513
|
+
}
|
|
514
|
+
console.log(`Showing ${data.length} entries`);
|
|
515
|
+
});
|
|
516
|
+
identity.command("add").description("Add an identity entry").argument("<content>", 'Identity content (e.g. "Solo founder based in Nepal, building Supacortex")').option("-t, --title <string>", 'Title (e.g. "Core profile", "Tech preferences")').option("--category <category>", "Category: core, goals, preferences, interests").option("-m, --metadata <json>", "Additional metadata as JSON").option("-j, --json", "Output raw JSON").action(async (content, option) => {
|
|
517
|
+
const metadata = option.metadata ? JSON.parse(option.metadata) : {};
|
|
518
|
+
if (option.category) {
|
|
519
|
+
if (!CATEGORIES.includes(option.category)) {
|
|
520
|
+
console.error(`Error: --category must be one of: ${CATEGORIES.join(", ")}`);
|
|
521
|
+
process.exit(1);
|
|
522
|
+
}
|
|
523
|
+
metadata.category = option.category;
|
|
524
|
+
}
|
|
525
|
+
const body = {
|
|
526
|
+
type: "identity",
|
|
527
|
+
content,
|
|
528
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
529
|
+
};
|
|
530
|
+
if (option.title) body.title = option.title;
|
|
531
|
+
const result = await apiRequest("memory", "POST", body);
|
|
532
|
+
if (option.json) {
|
|
533
|
+
console.log(JSON.stringify(result, null, 2));
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
console.log(`Identity added: ${result.title || result.content?.slice(0, 60) || result.id}`);
|
|
537
|
+
});
|
|
538
|
+
identity.command("get").description("Get an identity entry by ID").argument("<id>", "Identity entry ID").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
539
|
+
const data = await apiRequest(`memory/${id}`, "GET");
|
|
540
|
+
if (option.json) {
|
|
541
|
+
console.log(JSON.stringify(data, null, 2));
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
const category = data.metadata?.category || "uncategorized";
|
|
545
|
+
console.log(`ID: ${data.id}`);
|
|
546
|
+
console.log(`Category: ${category}`);
|
|
547
|
+
console.log(`Title: ${data.title || "(none)"}`);
|
|
548
|
+
console.log(`Content: ${data.content}`);
|
|
549
|
+
if (data.metadata) console.log(`Metadata: ${JSON.stringify(data.metadata)}`);
|
|
550
|
+
console.log(`Created: ${data.createdAt}`);
|
|
551
|
+
if (data.updatedAt) console.log(`Updated: ${data.updatedAt}`);
|
|
552
|
+
});
|
|
553
|
+
identity.command("update").description("Update an identity entry").argument("<id>", "Identity entry ID").option("-t, --title <string>", "New title").option("-c, --content <string>", "New content").option("--category <category>", "Change category (core, goals, preferences, interests)").option("-m, --metadata <json>", "New metadata as JSON").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
554
|
+
const body = {};
|
|
555
|
+
if (option.title) body.title = option.title;
|
|
556
|
+
if (option.content) body.content = option.content;
|
|
557
|
+
if (option.category || option.metadata) {
|
|
558
|
+
const metadata = option.metadata ? JSON.parse(option.metadata) : {};
|
|
559
|
+
if (option.category) {
|
|
560
|
+
if (!CATEGORIES.includes(option.category)) {
|
|
561
|
+
console.error(`Error: --category must be one of: ${CATEGORIES.join(", ")}`);
|
|
562
|
+
process.exit(1);
|
|
563
|
+
}
|
|
564
|
+
metadata.category = option.category;
|
|
565
|
+
}
|
|
566
|
+
body.metadata = metadata;
|
|
567
|
+
}
|
|
568
|
+
if (Object.keys(body).length === 0) {
|
|
569
|
+
console.error("Error: provide at least one field to update (--title, --content, --category, --metadata)");
|
|
570
|
+
process.exit(1);
|
|
571
|
+
}
|
|
572
|
+
const result = await apiRequest(`memory/${id}`, "PATCH", body);
|
|
573
|
+
if (option.json) {
|
|
574
|
+
console.log(JSON.stringify(result, null, 2));
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
console.log(`Identity updated: ${result.title || result.id}`);
|
|
578
|
+
});
|
|
579
|
+
identity.command("delete").description("Delete an identity entry").argument("<id>", "Identity entry ID").option("-j, --json", "Output raw JSON").action(async (id, option) => {
|
|
580
|
+
const result = await apiRequest(`memory/${id}`, "DELETE");
|
|
581
|
+
if (option.json) {
|
|
582
|
+
console.log(JSON.stringify(result, null, 2));
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
console.log("Identity entry deleted.");
|
|
586
|
+
});
|
|
587
|
+
};
|
|
588
|
+
|
|
360
589
|
// src/lib/update-notifier.ts
|
|
361
590
|
var NPM_REGISTRY_URL2 = "https://registry.npmjs.org/@supacortex/cli/latest";
|
|
362
591
|
var CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
|
|
@@ -407,6 +636,8 @@ registerWhoamiCommand(program);
|
|
|
407
636
|
registerBookmarksCommand(program);
|
|
408
637
|
registerGroupsCommand(program);
|
|
409
638
|
registerSyncCommand(program);
|
|
639
|
+
registerConversationCommand(program);
|
|
640
|
+
registerIdentityCommand(program);
|
|
410
641
|
registerUpdateCommand(program, pkg.version);
|
|
411
642
|
checkForUpdates(pkg.version);
|
|
412
643
|
program.parse();
|