@pedroaugusto04/kb-cli 1.2.1 → 1.2.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.
@@ -1,6 +1,7 @@
1
1
  import pc from 'picocolors';
2
2
  import * as clackPrompts from '@clack/prompts';
3
3
  import { client, ApiClientError } from '../client.js';
4
+ import { loadConfig } from '../config.js';
4
5
  export const clack = {
5
6
  select: clackPrompts.select,
6
7
  isCancel: clackPrompts.isCancel,
@@ -435,38 +436,55 @@ export async function runSyncAi(options) {
435
436
  console.log(pc.yellow('\nNo local AI sessions found from Claude Code, Codex, Antigravity, or OpenCode.'));
436
437
  return;
437
438
  }
438
- // Display select prompt to choose a session
439
- const selectOptions = allSessions.slice(0, 25).map(session => {
440
- const dateStr = new Date(session.timestamp).toISOString().split('T')[0];
441
- return {
442
- value: session,
443
- label: `[${session.providerName}] ${session.title}`,
444
- hint: `${dateStr} (${session.turns.length} turns)`
445
- };
446
- });
447
- const selected = await clack.select({
448
- message: 'Select an AI session to import/sync to Knowledge Vault:',
449
- options: selectOptions,
450
- });
451
- if (clack.isCancel(selected)) {
452
- console.log(pc.yellow('Cancelled.'));
453
- return;
439
+ let displayedCount = 20;
440
+ let selectedSession = null;
441
+ while (true) {
442
+ const selectOptions = allSessions.slice(0, displayedCount).map(session => {
443
+ const dateStr = new Date(session.timestamp).toISOString().split('T')[0];
444
+ return {
445
+ value: session,
446
+ label: `[${session.providerName}] ${session.title}`,
447
+ hint: `${dateStr} (${session.turns.length} turns)`
448
+ };
449
+ });
450
+ if (allSessions.length > displayedCount) {
451
+ selectOptions.push({
452
+ value: 'LOAD_MORE',
453
+ label: pc.cyan('❯ Load More...'),
454
+ hint: `Showing ${displayedCount} of ${allSessions.length} sessions`
455
+ });
456
+ }
457
+ const selected = await clack.select({
458
+ message: 'Select an AI session to import/sync to Knowledge Vault:',
459
+ options: selectOptions,
460
+ });
461
+ if (clack.isCancel(selected)) {
462
+ console.log(pc.yellow('Cancelled.'));
463
+ return;
464
+ }
465
+ if (selected === 'LOAD_MORE') {
466
+ displayedCount += 20;
467
+ continue;
468
+ }
469
+ selectedSession = selected;
470
+ break;
454
471
  }
455
- const session = selected;
472
+ const session = selectedSession;
456
473
  const titleWithDate = getTitleWithDate(session);
457
474
  const rawText = getMarkdownText(session);
458
475
  s.start(`Saving "${titleWithDate}" as note to Knowledge Vault...`);
459
476
  try {
460
- const targetProject = options.project || session.projectSlug || 'inbox';
461
- const note = await client.createNote({
477
+ const config = loadConfig();
478
+ const targetProject = options.project || session.projectSlug || config.defaultProjectSlug || 'inbox';
479
+ await client.createNote({
462
480
  title: titleWithDate,
463
481
  rawText,
464
482
  projectSlug: targetProject,
465
483
  sourceChannel: 'ai-chat',
484
+ source: session.providerId,
466
485
  });
467
486
  s.stop(pc.green('Import complete!'));
468
- console.log(pc.cyan(`\nNote saved successfully to project "${targetProject}"!`));
469
- console.log(pc.gray(`Note ID: ${note.id}`));
487
+ console.log(pc.cyan(`\nNote saved to Knowledge Vault successfully!`));
470
488
  }
471
489
  catch (error) {
472
490
  s.stop(pc.red('Save failed'));
@@ -1 +1 @@
1
- {"version":3,"file":"sync-ai.js","sourceRoot":"","sources":["../../src/commands/sync-ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,YAAY,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,MAAM,EAAE,YAAY,CAAC,MAAM;IAC3B,QAAQ,EAAE,YAAY,CAAC,QAAQ;IAC/B,OAAO,EAAE,YAAY,CAAC,OAAO;CAC9B,CAAC;AACF,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAiBzB,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC/B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,+BAA+B;AAC/B,4EAA4E;AAE5E,SAAS,qBAAqB;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,OAAO;oBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,SAAS;IACX,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,KAAK,GAAgB,EAAE,CAAC;QAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAClH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBAEjD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;oBAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9C,CAAC;qBAAM,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpC,IAAI,KAAK,GAAG,gBAAgB,CAAC;QAC7B,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QACzD,IAAI,aAAa,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/F,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,GAAG,WAAW,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACvF,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAExD,OAAO;YACL,UAAU,EAAE,aAAa;YACzB,YAAY,EAAE,aAAa;YAC3B,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;YAC5C,KAAK;YACL,KAAK;YACL,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO;YACxC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;SACzF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9D,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACzC,IAAI,OAAO;oBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,KAAK,GAAgB,EAAE,CAAC;QAE9B,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,SAAS;gBAC3B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAChC,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACtD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;wBAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;4BAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;4BAC1B,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gCAC5C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gCAC3C,IAAI,WAAW,GAAG,EAAE,CAAC;gCACrB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;oCACjC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wCACf,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;wCAC9B,IAAI,GAAG,CAAC,UAAU,CAAC,uBAAuB,CAAC;4CACvC,GAAG,CAAC,UAAU,CAAC,0BAA0B,CAAC;4CAC1C,GAAG,CAAC,QAAQ,CAAC,4BAA4B,CAAC;4CAC1C,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC;4CACrC,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;4CACxC,SAAS;wCACX,CAAC;wCACD,IAAI,GAAG,EAAE,CAAC;4CACR,IAAI,WAAW;gDAAE,WAAW,IAAI,MAAM,CAAC;4CACvC,WAAW,IAAI,GAAG,CAAC;wCACrB,CAAC;oCACH,CAAC;gCACH,CAAC;gCACD,IAAI,WAAW,EAAE,CAAC;oCAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;gCACrF,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBAClH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;wBACjD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;4BAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC9C,CAAC;6BAAM,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,EAAE,CAAC;4BACxC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;wBACnD,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBACxE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC3C,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;oBAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9C,CAAC;qBAAM,IAAI,IAAI,EAAE,CAAC;oBAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpC,IAAI,KAAK,GAAG,eAAe,CAAC;QAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QACzD,IAAI,aAAa,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/F,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,GAAG,UAAU,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACtF,CAAC;QACH,CAAC;QAED,OAAO;YACL,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,WAAW;YACzB,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAClC,KAAK;YACL,KAAK;YACL,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO;SACzC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IACvE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;gBACvF,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC/B,MAAM,OAAO,GAAG,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;oBAC1D,IAAI,OAAO;wBAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB,EAAE,SAAiB;IAC/D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,KAAK,GAAgB,EAAE,CAAC;QAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,MAAM,CAAC,MAAM,KAAK,eAAe,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBACtE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;oBACxC,MAAM,gBAAgB,GAAG,0CAA0C,CAAC;oBACpE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;oBACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;oBACzD,IAAI,IAAI,EAAE,CAAC;wBACT,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9C,CAAC;gBACH,CAAC;qBAAM,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;oBAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;oBAClC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;oBACtF,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEpC,IAAI,KAAK,GAAG,qBAAqB,CAAC;QAClC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QACzD,IAAI,aAAa,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/F,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,GAAG,gBAAgB,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5F,CAAC;QACH,CAAC;QAED,OAAO;YACL,UAAU,EAAE,aAAa;YACzB,YAAY,EAAE,aAAa;YAC3B,SAAS;YACT,KAAK;YACL,KAAK;YACL,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO;SACzC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IACrF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IAEtC,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACjD,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC;QAC/C,IAAI,CAAC,YAAY;YAAE,OAAO,EAAE,CAAC;QAE7B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG;;;;;;;;;;;;;KAab,CAAC;QAEF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,EAAW,CAAC;QAC9C,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,MAAM,WAAW,GAAG,IAAI,GAAG,EAGvB,CAAC;QAEL,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;YAE3F,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG;oBACN,OAAO,EAAE;wBACP,UAAU,EAAE,WAAW;wBACvB,YAAY,EAAE,UAAU;wBACxB,SAAS;wBACT,KAAK,EAAE,KAAK,IAAI,kBAAkB;wBAClC,KAAK,EAAE,EAAE;wBACT,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC;wBAC5B,WAAW,EAAE,WAAW,IAAI,SAAS;qBACtC;oBACD,WAAW,EAAE,IAAI,GAAG,EAAE;iBACvB,CAAC;gBACF,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACpC,CAAC;YAED,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;gBAC7B,IAAI,OAAO,GAAgC,IAAI,CAAC;gBAChD,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;oBACtC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;wBAAE,OAAO,GAAG,MAAM,CAAC;yBACvC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;wBAAE,OAAO,GAAG,WAAW,CAAC;gBAC7D,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBAEV,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,QAAQ,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;wBAC5C,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAC7C,CAAC;oBAED,IAAI,QAAQ,EAAE,CAAC;wBACb,IAAI,CAAC;4BACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;4BACnC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gCACxC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BACtC,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC,CAAA,CAAC;oBACZ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAgB,EAAE,CAAC;YAC9B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;gBACvD,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAqB;IAC7C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;IAChD,OAAO,GAAG,OAAO,CAAC,KAAK,KAAK,aAAa,GAAG,CAAC;AAC/C,CAAC;AAED,SAAS,eAAe,CAAC,OAAqB;IAC5C,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,OAAO,GAAG,KAAK,aAAa,MAAM,CAAC;IACvC,OAAO,IAAI,WAAW,OAAO,CAAC,YAAY,IAAI,CAAC;IAC/C,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO,IAAI,YAAY,OAAO,CAAC,WAAW,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,WAAW,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC;QACrE,OAAO,IAAI,OAAO,UAAU,KAAK,IAAI,CAAC,OAAO,MAAM,CAAC;IACtD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,uBAAuB;AACvB,4EAA4E;AAE5E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAA6B;IAC3D,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAmB,EAAE,CAAC;IAEvC,qCAAqC;IACrC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,qBAAqB,EAAE,CAAC;QAC/C,WAAW,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACzC,WAAW,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,IAAI,CAAC;QACH,MAAM,mBAAmB,GAAG,sBAAsB,EAAE,CAAC;QACrD,WAAW,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,EAAE,CAAC;QACrD,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,8BAA8B;IAC9B,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAEtD,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEnC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,iFAAiF,CAAC,CAAC,CAAC;QAC1G,OAAO;IACT,CAAC;IAED,4CAA4C;IAC5C,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QAC3D,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,KAAK,EAAE,OAAO;YACd,KAAK,EAAE,IAAI,OAAO,CAAC,YAAY,KAAK,OAAO,CAAC,KAAK,EAAE;YACnD,IAAI,EAAE,GAAG,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,SAAS;SACnD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC;QAClC,OAAO,EAAE,yDAAyD;QAClE,OAAO,EAAE,aAAa;KACvB,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,QAAwB,CAAC;IACzC,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,KAAK,CAAC,WAAW,aAAa,iCAAiC,CAAC,CAAC;IAEnE,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC;QACxE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;YACnC,KAAK,EAAE,aAAa;YACpB,OAAO;YACP,WAAW,EAAE,aAAa;YAC1B,aAAa,EAAE,SAAS;SACzB,CAAC,CAAC;QAEH,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,yCAAyC,aAAa,IAAI,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;QAC9B,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,MAAM,MAAO,KAAK,CAAC,IAAY,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACrG,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,qBAAqB,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC","sourcesContent":["import pc from 'picocolors';\nimport * as clackPrompts from '@clack/prompts';\nimport { client, ApiClientError } from '../client.js';\n\nexport const clack = {\n select: clackPrompts.select,\n isCancel: clackPrompts.isCancel,\n spinner: clackPrompts.spinner,\n};\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\ninterface CliAiTurn {\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface CliAiSession {\n providerId: string;\n providerName: string;\n sessionId: string;\n title: string;\n turns: CliAiTurn[];\n timestamp: number;\n projectSlug?: string;\n}\n\nfunction getAllFiles(dir: string): string[] {\n let results: string[] = [];\n try {\n const list = fs.readdirSync(dir);\n for (const file of list) {\n const filePath = path.join(dir, file);\n const stat = fs.statSync(filePath);\n if (stat && stat.isDirectory()) {\n results = results.concat(getAllFiles(filePath));\n } else {\n results.push(filePath);\n }\n }\n } catch {\n // Ignore errors\n }\n return results;\n}\n\n// -------------------------------------------------------------------------\n// Provider Ingestion Functions\n// -------------------------------------------------------------------------\n\nfunction getClaudeCodeSessions(): CliAiSession[] {\n const dir = path.join(os.homedir(), '.claude', 'projects');\n if (!fs.existsSync(dir)) return [];\n\n const sessions: CliAiSession[] = [];\n try {\n const allFiles = getAllFiles(dir);\n for (const filePath of allFiles) {\n if (filePath.endsWith('.jsonl')) {\n const session = parseClaudeFile(filePath);\n if (session) sessions.push(session);\n }\n }\n } catch (err) {\n // Ignore\n }\n return sessions;\n}\n\nfunction parseClaudeFile(filePath: string): CliAiSession | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n const turns: CliAiTurn[] = [];\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const record = JSON.parse(line);\n const role = record.role || (record.type === 'prompt' ? 'user' : record.type === 'response' ? 'assistant' : null);\n const text = record.content || record.text || '';\n\n if (role === 'user' && text) {\n turns.push({ role: 'user', content: text });\n } else if (role === 'assistant' && text) {\n turns.push({ role: 'assistant', content: text });\n }\n } catch {}\n }\n\n if (turns.length === 0) return null;\n\n let title = 'Claude Session';\n const firstUserTurn = turns.find(t => t.role === 'user');\n if (firstUserTurn && firstUserTurn.content) {\n const cleanPrompt = firstUserTurn.content.replace(/[\\r\\n]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (cleanPrompt) {\n title = `Claude: ${cleanPrompt.slice(0, 60)}${cleanPrompt.length > 60 ? '...' : ''}`;\n }\n }\n\n const parentDir = path.basename(path.dirname(filePath));\n\n return {\n providerId: 'claude-code',\n providerName: 'Claude Code',\n sessionId: path.basename(filePath, '.jsonl'),\n title,\n turns,\n timestamp: fs.statSync(filePath).mtimeMs,\n projectSlug: parentDir ? parentDir.toLowerCase().replace(/[^a-z0-9-]/g, '-') : undefined,\n };\n } catch {\n return null;\n }\n}\n\nfunction getCodexSessions(): CliAiSession[] {\n const dir = path.join(os.homedir(), '.codex', 'sessions');\n if (!fs.existsSync(dir)) return [];\n\n const sessions: CliAiSession[] = [];\n try {\n const allFiles = getAllFiles(dir);\n for (const filePath of allFiles) {\n if (filePath.endsWith('.json') || filePath.endsWith('.jsonl')) {\n const session = parseCodexFile(filePath);\n if (session) sessions.push(session);\n }\n }\n } catch {}\n return sessions;\n}\n\nfunction parseCodexFile(filePath: string): CliAiSession | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8').trim();\n if (!content) return null;\n const turns: CliAiTurn[] = [];\n\n if (filePath.endsWith('.jsonl')) {\n const lines = content.split('\\n');\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const record = JSON.parse(line);\n if (record.type === 'response_item' && record.payload) {\n const payload = record.payload;\n if (payload.type === 'message') {\n const role = payload.role;\n if (role === 'user' || role === 'assistant') {\n const contentArray = payload.content || [];\n let textContent = '';\n for (const block of contentArray) {\n if (block.text) {\n const txt = block.text.trim();\n if (txt.startsWith('<environment_context>') || \n txt.startsWith('# AGENTS.md instructions') || \n txt.includes('<permissions instructions>') ||\n txt.includes('<skills_instructions>') ||\n txt.includes('<apps_instructions>')) {\n continue;\n }\n if (txt) {\n if (textContent) textContent += '\\n\\n';\n textContent += txt;\n }\n }\n }\n if (textContent) {\n turns.push({ role: role === 'user' ? 'user' : 'assistant', content: textContent });\n }\n }\n }\n } else {\n const role = record.role || (record.type === 'prompt' ? 'user' : record.type === 'response' ? 'assistant' : null);\n const text = record.content || record.text || '';\n if (role === 'user' && text) {\n turns.push({ role: 'user', content: text });\n } else if (role === 'assistant' && text) {\n turns.push({ role: 'assistant', content: text });\n }\n }\n } catch {}\n }\n } else {\n const data = JSON.parse(content);\n const messages = data.messages || data.turns || [];\n for (const msg of messages) {\n const role = msg.role || (msg.type === 'prompt' ? 'user' : 'assistant');\n const text = msg.content || msg.text || '';\n if (role === 'user' && text) {\n turns.push({ role: 'user', content: text });\n } else if (text) {\n turns.push({ role: 'assistant', content: text });\n }\n }\n }\n\n if (turns.length === 0) return null;\n\n let title = 'Codex Session';\n const firstUserTurn = turns.find(t => t.role === 'user');\n if (firstUserTurn && firstUserTurn.content) {\n const cleanPrompt = firstUserTurn.content.replace(/[\\r\\n]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (cleanPrompt) {\n title = `Codex: ${cleanPrompt.slice(0, 60)}${cleanPrompt.length > 60 ? '...' : ''}`;\n }\n }\n\n return {\n providerId: 'codex-cli',\n providerName: 'Codex CLI',\n sessionId: path.basename(filePath),\n title,\n turns,\n timestamp: fs.statSync(filePath).mtimeMs,\n };\n } catch {\n return null;\n }\n}\n\nfunction getAntigravitySessions(): CliAiSession[] {\n const dir = path.join(os.homedir(), '.gemini', 'antigravity', 'brain');\n if (!fs.existsSync(dir)) return [];\n\n const sessions: CliAiSession[] = [];\n try {\n const folders = fs.readdirSync(dir);\n for (const folder of folders) {\n const folderPath = path.join(dir, folder);\n const stat = fs.statSync(folderPath);\n if (stat.isDirectory()) {\n const logFilePath = path.join(folderPath, '.system_generated', 'logs', 'overview.txt');\n if (fs.existsSync(logFilePath)) {\n const session = parseAntigravityFile(logFilePath, folder);\n if (session) sessions.push(session);\n }\n }\n }\n } catch {}\n return sessions;\n}\n\nfunction parseAntigravityFile(filePath: string, sessionId: string): CliAiSession | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n const turns: CliAiTurn[] = [];\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const record = JSON.parse(line);\n if (record.source === 'USER_EXPLICIT' && record.type === 'USER_INPUT') {\n const rawContent = record.content || '';\n const userRequestRegex = /<USER_REQUEST>([\\s\\S]*?)<\\/USER_REQUEST>/;\n const match = rawContent.match(userRequestRegex);\n const text = match ? match[1].trim() : rawContent.trim();\n if (text) {\n turns.push({ role: 'user', content: text });\n }\n } else if (record.source === 'MODEL' && record.type === 'PLANNER_RESPONSE') {\n const text = record.content || '';\n const hasToolCalls = Array.isArray(record.tool_calls) && record.tool_calls.length > 0;\n if (text && !hasToolCalls) {\n turns.push({ role: 'assistant', content: text.trim() });\n }\n }\n } catch {}\n }\n\n if (turns.length === 0) return null;\n\n let title = 'Antigravity Session';\n const firstUserTurn = turns.find(t => t.role === 'user');\n if (firstUserTurn && firstUserTurn.content) {\n const cleanPrompt = firstUserTurn.content.replace(/[\\r\\n]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (cleanPrompt) {\n title = `Antigravity: ${cleanPrompt.slice(0, 60)}${cleanPrompt.length > 60 ? '...' : ''}`;\n }\n }\n\n return {\n providerId: 'antigravity',\n providerName: 'Antigravity',\n sessionId,\n title,\n turns,\n timestamp: fs.statSync(filePath).mtimeMs,\n };\n } catch {\n return null;\n }\n}\n\nasync function getOpenCodeSessions(): Promise<CliAiSession[]> {\n const dbPath = path.join(os.homedir(), '.local', 'share', 'opencode', 'opencode.db');\n if (!fs.existsSync(dbPath)) return [];\n\n try {\n const sqliteModule = await import('node:sqlite');\n const DatabaseSync = sqliteModule.DatabaseSync;\n if (!DatabaseSync) return [];\n\n const db = new DatabaseSync(dbPath, { readOnly: true });\n const query = `\n SELECT \n s.id as sessionId,\n s.title,\n s.time_updated as timestamp,\n s.slug as projectSlug,\n m.id as messageId,\n m.data as messageData,\n p.data as partData\n FROM session s\n JOIN message m ON m.session_id = s.id\n LEFT JOIN part p ON p.message_id = m.id\n ORDER BY s.time_updated DESC, m.time_created ASC, p.time_created ASC\n `;\n\n const rows = db.prepare(query).all() as any[];\n db.close();\n\n const sessionsMap = new Map<string, {\n session: CliAiSession;\n messagesMap: Map<string, { role: 'user' | 'assistant'; textParts: string[] }>;\n }>();\n\n for (const row of rows) {\n const { sessionId, title, timestamp, projectSlug, messageId, messageData, partData } = row;\n \n let entry = sessionsMap.get(sessionId);\n if (!entry) {\n entry = {\n session: {\n providerId: 'open-code',\n providerName: 'OpenCode',\n sessionId,\n title: title || 'OpenCode Session',\n turns: [],\n timestamp: Number(timestamp),\n projectSlug: projectSlug || undefined,\n },\n messagesMap: new Map(),\n };\n sessionsMap.set(sessionId, entry);\n }\n\n if (messageId && messageData) {\n let msgRole: 'user' | 'assistant' | null = null;\n try {\n const mData = JSON.parse(messageData);\n if (mData.role === 'user') msgRole = 'user';\n else if (mData.role === 'assistant') msgRole = 'assistant';\n } catch {}\n\n if (msgRole) {\n let msgEntry = entry.messagesMap.get(messageId);\n if (!msgEntry) {\n msgEntry = { role: msgRole, textParts: [] };\n entry.messagesMap.set(messageId, msgEntry);\n }\n\n if (partData) {\n try {\n const pData = JSON.parse(partData);\n if (pData.type === 'text' && pData.text) {\n msgEntry.textParts.push(pData.text);\n }\n } catch {}\n }\n }\n }\n }\n\n const sessions: CliAiSession[] = [];\n for (const entry of sessionsMap.values()) {\n const turns: CliAiTurn[] = [];\n for (const msgEntry of entry.messagesMap.values()) {\n const content = msgEntry.textParts.join('\\n\\n').trim();\n if (content) {\n turns.push({ role: msgEntry.role, content });\n }\n }\n if (turns.length > 0) {\n entry.session.turns = turns;\n sessions.push(entry.session);\n }\n }\n\n return sessions;\n } catch {\n return [];\n }\n}\n\nfunction getTitleWithDate(session: CliAiSession): string {\n const dateObj = new Date(session.timestamp);\n const year = dateObj.getFullYear();\n const month = String(dateObj.getMonth() + 1).padStart(2, '0');\n const day = String(dateObj.getDate()).padStart(2, '0');\n const formattedDate = `${year}-${month}-${day}`;\n return `${session.title} (${formattedDate})`;\n}\n\nfunction getMarkdownText(session: CliAiSession): string {\n const titleWithDate = getTitleWithDate(session);\n let rawText = `# ${titleWithDate}\\n\\n`;\n rawText += `Source: ${session.providerName}\\n`;\n if (session.projectSlug) {\n rawText += `Project: ${session.projectSlug}\\n`;\n }\n rawText += `\\n---\\n\\n`;\n \n for (const turn of session.turns) {\n const roleHeader = turn.role === 'user' ? '👤 User' : '🤖 Assistant';\n rawText += `### ${roleHeader}\\n${turn.content}\\n\\n`;\n }\n return rawText;\n}\n\n// -------------------------------------------------------------------------\n// Main Command Handler\n// -------------------------------------------------------------------------\n\nexport async function runSyncAi(options: { project?: string }): Promise<void> {\n const s = clack.spinner();\n s.start('Scanning local AI history logs...');\n\n const allSessions: CliAiSession[] = [];\n\n // Gather sessions from all providers\n try {\n const claudeSessions = getClaudeCodeSessions();\n allSessions.push(...claudeSessions);\n } catch {}\n\n try {\n const codexSessions = getCodexSessions();\n allSessions.push(...codexSessions);\n } catch {}\n\n try {\n const antigravitySessions = getAntigravitySessions();\n allSessions.push(...antigravitySessions);\n } catch {}\n\n try {\n const openCodeSessions = await getOpenCodeSessions();\n allSessions.push(...openCodeSessions);\n } catch {}\n\n // Sort: newest sessions first\n allSessions.sort((a, b) => b.timestamp - a.timestamp);\n\n s.stop(pc.green('Scan complete!'));\n\n if (allSessions.length === 0) {\n console.log(pc.yellow('\\nNo local AI sessions found from Claude Code, Codex, Antigravity, or OpenCode.'));\n return;\n }\n\n // Display select prompt to choose a session\n const selectOptions = allSessions.slice(0, 25).map(session => {\n const dateStr = new Date(session.timestamp).toISOString().split('T')[0];\n return {\n value: session,\n label: `[${session.providerName}] ${session.title}`,\n hint: `${dateStr} (${session.turns.length} turns)`\n };\n });\n\n const selected = await clack.select({\n message: 'Select an AI session to import/sync to Knowledge Vault:',\n options: selectOptions,\n });\n\n if (clack.isCancel(selected)) {\n console.log(pc.yellow('Cancelled.'));\n return;\n }\n\n const session = selected as CliAiSession;\n const titleWithDate = getTitleWithDate(session);\n const rawText = getMarkdownText(session);\n s.start(`Saving \"${titleWithDate}\" as note to Knowledge Vault...`);\n\n try {\n const targetProject = options.project || session.projectSlug || 'inbox';\n const note = await client.createNote({\n title: titleWithDate,\n rawText,\n projectSlug: targetProject,\n sourceChannel: 'ai-chat',\n });\n\n s.stop(pc.green('Import complete!'));\n console.log(pc.cyan(`\\nNote saved successfully to project \"${targetProject}\"!`));\n console.log(pc.gray(`Note ID: ${note.id}`));\n } catch (error: any) {\n s.stop(pc.red('Save failed'));\n if (error instanceof ApiClientError) {\n console.error(pc.red(`Error (${error.status}): ${(error.body as any)?.message || error.message}`));\n } else {\n console.error(pc.red(`Error: ${error.message || 'Failed to save note'}`));\n }\n process.exit(1);\n }\n}\n"]}
1
+ {"version":3,"file":"sync-ai.js","sourceRoot":"","sources":["../../src/commands/sync-ai.ts"],"names":[],"mappings":"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","sourcesContent":["import pc from 'picocolors';\nimport * as clackPrompts from '@clack/prompts';\nimport { client, ApiClientError } from '../client.js';\nimport { loadConfig } from '../config.js';\n\nexport const clack = {\n select: clackPrompts.select,\n isCancel: clackPrompts.isCancel,\n spinner: clackPrompts.spinner,\n};\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\ninterface CliAiTurn {\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface CliAiSession {\n providerId: string;\n providerName: string;\n sessionId: string;\n title: string;\n turns: CliAiTurn[];\n timestamp: number;\n projectSlug?: string;\n}\n\nfunction getAllFiles(dir: string): string[] {\n let results: string[] = [];\n try {\n const list = fs.readdirSync(dir);\n for (const file of list) {\n const filePath = path.join(dir, file);\n const stat = fs.statSync(filePath);\n if (stat && stat.isDirectory()) {\n results = results.concat(getAllFiles(filePath));\n } else {\n results.push(filePath);\n }\n }\n } catch {\n // Ignore errors\n }\n return results;\n}\n\n// -------------------------------------------------------------------------\n// Provider Ingestion Functions\n// -------------------------------------------------------------------------\n\nfunction getClaudeCodeSessions(): CliAiSession[] {\n const dir = path.join(os.homedir(), '.claude', 'projects');\n if (!fs.existsSync(dir)) return [];\n\n const sessions: CliAiSession[] = [];\n try {\n const allFiles = getAllFiles(dir);\n for (const filePath of allFiles) {\n if (filePath.endsWith('.jsonl')) {\n const session = parseClaudeFile(filePath);\n if (session) sessions.push(session);\n }\n }\n } catch (err) {\n // Ignore\n }\n return sessions;\n}\n\nfunction parseClaudeFile(filePath: string): CliAiSession | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n const turns: CliAiTurn[] = [];\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const record = JSON.parse(line);\n const role = record.role || (record.type === 'prompt' ? 'user' : record.type === 'response' ? 'assistant' : null);\n const text = record.content || record.text || '';\n\n if (role === 'user' && text) {\n turns.push({ role: 'user', content: text });\n } else if (role === 'assistant' && text) {\n turns.push({ role: 'assistant', content: text });\n }\n } catch {}\n }\n\n if (turns.length === 0) return null;\n\n let title = 'Claude Session';\n const firstUserTurn = turns.find(t => t.role === 'user');\n if (firstUserTurn && firstUserTurn.content) {\n const cleanPrompt = firstUserTurn.content.replace(/[\\r\\n]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (cleanPrompt) {\n title = `Claude: ${cleanPrompt.slice(0, 60)}${cleanPrompt.length > 60 ? '...' : ''}`;\n }\n }\n\n const parentDir = path.basename(path.dirname(filePath));\n\n return {\n providerId: 'claude-code',\n providerName: 'Claude Code',\n sessionId: path.basename(filePath, '.jsonl'),\n title,\n turns,\n timestamp: fs.statSync(filePath).mtimeMs,\n projectSlug: parentDir ? parentDir.toLowerCase().replace(/[^a-z0-9-]/g, '-') : undefined,\n };\n } catch {\n return null;\n }\n}\n\nfunction getCodexSessions(): CliAiSession[] {\n const dir = path.join(os.homedir(), '.codex', 'sessions');\n if (!fs.existsSync(dir)) return [];\n\n const sessions: CliAiSession[] = [];\n try {\n const allFiles = getAllFiles(dir);\n for (const filePath of allFiles) {\n if (filePath.endsWith('.json') || filePath.endsWith('.jsonl')) {\n const session = parseCodexFile(filePath);\n if (session) sessions.push(session);\n }\n }\n } catch {}\n return sessions;\n}\n\nfunction parseCodexFile(filePath: string): CliAiSession | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8').trim();\n if (!content) return null;\n const turns: CliAiTurn[] = [];\n\n if (filePath.endsWith('.jsonl')) {\n const lines = content.split('\\n');\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const record = JSON.parse(line);\n if (record.type === 'response_item' && record.payload) {\n const payload = record.payload;\n if (payload.type === 'message') {\n const role = payload.role;\n if (role === 'user' || role === 'assistant') {\n const contentArray = payload.content || [];\n let textContent = '';\n for (const block of contentArray) {\n if (block.text) {\n const txt = block.text.trim();\n if (txt.startsWith('<environment_context>') || \n txt.startsWith('# AGENTS.md instructions') || \n txt.includes('<permissions instructions>') ||\n txt.includes('<skills_instructions>') ||\n txt.includes('<apps_instructions>')) {\n continue;\n }\n if (txt) {\n if (textContent) textContent += '\\n\\n';\n textContent += txt;\n }\n }\n }\n if (textContent) {\n turns.push({ role: role === 'user' ? 'user' : 'assistant', content: textContent });\n }\n }\n }\n } else {\n const role = record.role || (record.type === 'prompt' ? 'user' : record.type === 'response' ? 'assistant' : null);\n const text = record.content || record.text || '';\n if (role === 'user' && text) {\n turns.push({ role: 'user', content: text });\n } else if (role === 'assistant' && text) {\n turns.push({ role: 'assistant', content: text });\n }\n }\n } catch {}\n }\n } else {\n const data = JSON.parse(content);\n const messages = data.messages || data.turns || [];\n for (const msg of messages) {\n const role = msg.role || (msg.type === 'prompt' ? 'user' : 'assistant');\n const text = msg.content || msg.text || '';\n if (role === 'user' && text) {\n turns.push({ role: 'user', content: text });\n } else if (text) {\n turns.push({ role: 'assistant', content: text });\n }\n }\n }\n\n if (turns.length === 0) return null;\n\n let title = 'Codex Session';\n const firstUserTurn = turns.find(t => t.role === 'user');\n if (firstUserTurn && firstUserTurn.content) {\n const cleanPrompt = firstUserTurn.content.replace(/[\\r\\n]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (cleanPrompt) {\n title = `Codex: ${cleanPrompt.slice(0, 60)}${cleanPrompt.length > 60 ? '...' : ''}`;\n }\n }\n\n return {\n providerId: 'codex-cli',\n providerName: 'Codex CLI',\n sessionId: path.basename(filePath),\n title,\n turns,\n timestamp: fs.statSync(filePath).mtimeMs,\n };\n } catch {\n return null;\n }\n}\n\nfunction getAntigravitySessions(): CliAiSession[] {\n const dir = path.join(os.homedir(), '.gemini', 'antigravity', 'brain');\n if (!fs.existsSync(dir)) return [];\n\n const sessions: CliAiSession[] = [];\n try {\n const folders = fs.readdirSync(dir);\n for (const folder of folders) {\n const folderPath = path.join(dir, folder);\n const stat = fs.statSync(folderPath);\n if (stat.isDirectory()) {\n const logFilePath = path.join(folderPath, '.system_generated', 'logs', 'overview.txt');\n if (fs.existsSync(logFilePath)) {\n const session = parseAntigravityFile(logFilePath, folder);\n if (session) sessions.push(session);\n }\n }\n }\n } catch {}\n return sessions;\n}\n\nfunction parseAntigravityFile(filePath: string, sessionId: string): CliAiSession | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n const turns: CliAiTurn[] = [];\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const record = JSON.parse(line);\n if (record.source === 'USER_EXPLICIT' && record.type === 'USER_INPUT') {\n const rawContent = record.content || '';\n const userRequestRegex = /<USER_REQUEST>([\\s\\S]*?)<\\/USER_REQUEST>/;\n const match = rawContent.match(userRequestRegex);\n const text = match ? match[1].trim() : rawContent.trim();\n if (text) {\n turns.push({ role: 'user', content: text });\n }\n } else if (record.source === 'MODEL' && record.type === 'PLANNER_RESPONSE') {\n const text = record.content || '';\n const hasToolCalls = Array.isArray(record.tool_calls) && record.tool_calls.length > 0;\n if (text && !hasToolCalls) {\n turns.push({ role: 'assistant', content: text.trim() });\n }\n }\n } catch {}\n }\n\n if (turns.length === 0) return null;\n\n let title = 'Antigravity Session';\n const firstUserTurn = turns.find(t => t.role === 'user');\n if (firstUserTurn && firstUserTurn.content) {\n const cleanPrompt = firstUserTurn.content.replace(/[\\r\\n]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (cleanPrompt) {\n title = `Antigravity: ${cleanPrompt.slice(0, 60)}${cleanPrompt.length > 60 ? '...' : ''}`;\n }\n }\n\n return {\n providerId: 'antigravity',\n providerName: 'Antigravity',\n sessionId,\n title,\n turns,\n timestamp: fs.statSync(filePath).mtimeMs,\n };\n } catch {\n return null;\n }\n}\n\nasync function getOpenCodeSessions(): Promise<CliAiSession[]> {\n const dbPath = path.join(os.homedir(), '.local', 'share', 'opencode', 'opencode.db');\n if (!fs.existsSync(dbPath)) return [];\n\n try {\n const sqliteModule = await import('node:sqlite');\n const DatabaseSync = sqliteModule.DatabaseSync;\n if (!DatabaseSync) return [];\n\n const db = new DatabaseSync(dbPath, { readOnly: true });\n const query = `\n SELECT \n s.id as sessionId,\n s.title,\n s.time_updated as timestamp,\n s.slug as projectSlug,\n m.id as messageId,\n m.data as messageData,\n p.data as partData\n FROM session s\n JOIN message m ON m.session_id = s.id\n LEFT JOIN part p ON p.message_id = m.id\n ORDER BY s.time_updated DESC, m.time_created ASC, p.time_created ASC\n `;\n\n const rows = db.prepare(query).all() as any[];\n db.close();\n\n const sessionsMap = new Map<string, {\n session: CliAiSession;\n messagesMap: Map<string, { role: 'user' | 'assistant'; textParts: string[] }>;\n }>();\n\n for (const row of rows) {\n const { sessionId, title, timestamp, projectSlug, messageId, messageData, partData } = row;\n \n let entry = sessionsMap.get(sessionId);\n if (!entry) {\n entry = {\n session: {\n providerId: 'open-code',\n providerName: 'OpenCode',\n sessionId,\n title: title || 'OpenCode Session',\n turns: [],\n timestamp: Number(timestamp),\n projectSlug: projectSlug || undefined,\n },\n messagesMap: new Map(),\n };\n sessionsMap.set(sessionId, entry);\n }\n\n if (messageId && messageData) {\n let msgRole: 'user' | 'assistant' | null = null;\n try {\n const mData = JSON.parse(messageData);\n if (mData.role === 'user') msgRole = 'user';\n else if (mData.role === 'assistant') msgRole = 'assistant';\n } catch {}\n\n if (msgRole) {\n let msgEntry = entry.messagesMap.get(messageId);\n if (!msgEntry) {\n msgEntry = { role: msgRole, textParts: [] };\n entry.messagesMap.set(messageId, msgEntry);\n }\n\n if (partData) {\n try {\n const pData = JSON.parse(partData);\n if (pData.type === 'text' && pData.text) {\n msgEntry.textParts.push(pData.text);\n }\n } catch {}\n }\n }\n }\n }\n\n const sessions: CliAiSession[] = [];\n for (const entry of sessionsMap.values()) {\n const turns: CliAiTurn[] = [];\n for (const msgEntry of entry.messagesMap.values()) {\n const content = msgEntry.textParts.join('\\n\\n').trim();\n if (content) {\n turns.push({ role: msgEntry.role, content });\n }\n }\n if (turns.length > 0) {\n entry.session.turns = turns;\n sessions.push(entry.session);\n }\n }\n\n return sessions;\n } catch {\n return [];\n }\n}\n\nfunction getTitleWithDate(session: CliAiSession): string {\n const dateObj = new Date(session.timestamp);\n const year = dateObj.getFullYear();\n const month = String(dateObj.getMonth() + 1).padStart(2, '0');\n const day = String(dateObj.getDate()).padStart(2, '0');\n const formattedDate = `${year}-${month}-${day}`;\n return `${session.title} (${formattedDate})`;\n}\n\nfunction getMarkdownText(session: CliAiSession): string {\n const titleWithDate = getTitleWithDate(session);\n let rawText = `# ${titleWithDate}\\n\\n`;\n rawText += `Source: ${session.providerName}\\n`;\n if (session.projectSlug) {\n rawText += `Project: ${session.projectSlug}\\n`;\n }\n rawText += `\\n---\\n\\n`;\n \n for (const turn of session.turns) {\n const roleHeader = turn.role === 'user' ? '👤 User' : '🤖 Assistant';\n rawText += `### ${roleHeader}\\n${turn.content}\\n\\n`;\n }\n return rawText;\n}\n\n// -------------------------------------------------------------------------\n// Main Command Handler\n// -------------------------------------------------------------------------\n\nexport async function runSyncAi(options: { project?: string }): Promise<void> {\n const s = clack.spinner();\n s.start('Scanning local AI history logs...');\n\n const allSessions: CliAiSession[] = [];\n\n // Gather sessions from all providers\n try {\n const claudeSessions = getClaudeCodeSessions();\n allSessions.push(...claudeSessions);\n } catch {}\n\n try {\n const codexSessions = getCodexSessions();\n allSessions.push(...codexSessions);\n } catch {}\n\n try {\n const antigravitySessions = getAntigravitySessions();\n allSessions.push(...antigravitySessions);\n } catch {}\n\n try {\n const openCodeSessions = await getOpenCodeSessions();\n allSessions.push(...openCodeSessions);\n } catch {}\n\n // Sort: newest sessions first\n allSessions.sort((a, b) => b.timestamp - a.timestamp);\n\n s.stop(pc.green('Scan complete!'));\n\n if (allSessions.length === 0) {\n console.log(pc.yellow('\\nNo local AI sessions found from Claude Code, Codex, Antigravity, or OpenCode.'));\n return;\n }\n\n let displayedCount = 20;\n let selectedSession: CliAiSession | null = null;\n\n while (true) {\n const selectOptions: any[] = allSessions.slice(0, displayedCount).map(session => {\n const dateStr = new Date(session.timestamp).toISOString().split('T')[0];\n return {\n value: session,\n label: `[${session.providerName}] ${session.title}`,\n hint: `${dateStr} (${session.turns.length} turns)`\n };\n });\n\n if (allSessions.length > displayedCount) {\n selectOptions.push({\n value: 'LOAD_MORE',\n label: pc.cyan('❯ Load More...'),\n hint: `Showing ${displayedCount} of ${allSessions.length} sessions`\n });\n }\n\n const selected = await clack.select({\n message: 'Select an AI session to import/sync to Knowledge Vault:',\n options: selectOptions,\n });\n\n if (clack.isCancel(selected)) {\n console.log(pc.yellow('Cancelled.'));\n return;\n }\n\n if (selected === 'LOAD_MORE') {\n displayedCount += 20;\n continue;\n }\n\n selectedSession = selected as CliAiSession;\n break;\n }\n\n const session = selectedSession;\n const titleWithDate = getTitleWithDate(session);\n const rawText = getMarkdownText(session);\n s.start(`Saving \"${titleWithDate}\" as note to Knowledge Vault...`);\n\n try {\n const config = loadConfig();\n const targetProject = options.project || session.projectSlug || config.defaultProjectSlug || 'inbox';\n await client.createNote({\n title: titleWithDate,\n rawText,\n projectSlug: targetProject,\n sourceChannel: 'ai-chat',\n source: session.providerId,\n });\n\n s.stop(pc.green('Import complete!'));\n console.log(pc.cyan(`\\nNote saved to Knowledge Vault successfully!`));\n } catch (error: any) {\n s.stop(pc.red('Save failed'));\n if (error instanceof ApiClientError) {\n console.error(pc.red(`Error (${error.status}): ${(error.body as any)?.message || error.message}`));\n } else {\n console.error(pc.red(`Error: ${error.message || 'Failed to save note'}`));\n }\n process.exit(1);\n }\n}\n"]}
@@ -109,6 +109,7 @@ async function syncDirectory(targetDir, defaultProject, ledgerPath, dryRun, file
109
109
  tags: parsed.tags || [],
110
110
  status: parsed.status || 'active',
111
111
  canonicalType: parsed.canonicalType || 'event',
112
+ source: 'manual',
112
113
  };
113
114
  if (noteId) {
114
115
  // Update existing note
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport pc from 'picocolors';\nimport { spinner, outro } from '@clack/prompts';\nimport { client, ApiClientError } from '../client.js';\nimport { loadConfig } from '../config.js';\n\nexport interface SyncOptions {\n dir: string;\n project?: string;\n dryRun?: boolean;\n watch?: boolean;\n}\n\ninterface LedgerEntry {\n noteId: string;\n sha256: string;\n lastModified: string;\n}\n\ninterface SyncLedger {\n lastSyncedAt: string;\n files: Record<string, LedgerEntry>;\n}\n\nexport async function runSync(options: SyncOptions): Promise<void> {\n const targetPath = path.resolve(options.dir);\n if (!fs.existsSync(targetPath)) {\n console.error(pc.red(`Error: Path not found at ${options.dir}`));\n process.exit(1);\n }\n\n const isFile = fs.statSync(targetPath).isFile();\n const targetDir = isFile ? path.dirname(targetPath) : targetPath;\n const ledgerPath = path.join(targetDir, '.kb-sync.json');\n const filesList = isFile ? [targetPath] : undefined;\n\n const config = loadConfig();\n const defaultProject = options.project || config.defaultProjectSlug || 'inbox';\n\n if (options.dryRun) {\n console.log(pc.yellow('Running in DRY-RUN mode. No changes will be written or sent to the server.'));\n }\n\n if (options.watch) {\n console.log(pc.cyan(`Starting sync in WATCH mode for: ${targetPath}`));\n await syncDirectory(targetDir, defaultProject, ledgerPath, options.dryRun || false, filesList);\n\n // Watch logic\n let debounceTimer: NodeJS.Timeout | null = null;\n fs.watch(targetPath, { recursive: !isFile }, (eventType, filename) => {\n if (!isFile) {\n if (!filename || filename.endsWith('.kb-sync.json') || !filename.endsWith('.md')) return;\n }\n\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(async () => {\n console.log(pc.blue(`\\nChange detected in ${filename || path.basename(targetPath)}. Syncing...`));\n try {\n await syncDirectory(targetDir, defaultProject, ledgerPath, options.dryRun || false, filesList);\n } catch (err: any) {\n console.error(pc.red(`Watch sync failed: ${err.message}`));\n }\n }, 500);\n });\n\n // Keep process alive in watch mode\n await new Promise(() => { });\n return;\n }\n\n const s = spinner();\n s.start('Synchronizing files...');\n\n try {\n const stats = await syncDirectory(targetDir, defaultProject, ledgerPath, options.dryRun || false, filesList);\n s.stop(pc.green('Sync complete!'));\n\n console.log('\\n' + pc.bold('Sync Summary:'));\n console.log(` - Created: ${pc.green(stats.created)}`);\n console.log(` - Updated: ${pc.cyan(stats.updated)}`);\n console.log(` - Skipped: ${pc.gray(stats.skipped)}`);\n console.log(` - Failed: ${pc.red(stats.failed)}\\n`);\n\n outro(pc.green('Files synced successfully.'));\n } catch (error: any) {\n s.stop(pc.red('Sync failed'));\n console.error(pc.red(`Error: ${error.message || 'Failed to sync folder.'}`));\n process.exit(1);\n }\n}\n\nasync function syncDirectory(\n targetDir: string,\n defaultProject: string,\n ledgerPath: string,\n dryRun: boolean,\n filesList?: string[]\n) {\n const ledger = loadLedger(ledgerPath);\n const files = filesList || getMarkdownFiles(targetDir);\n\n const stats = { created: 0, updated: 0, skipped: 0, failed: 0 };\n const updatedLedgerFiles: Record<string, LedgerEntry> = {};\n\n for (const filePath of files) {\n // Relative path to use as key in ledger\n const relativePath = path.relative(targetDir, filePath).replace(/\\\\/g, '/');\n if (relativePath === '.kb-sync.json') continue;\n\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n const sha256 = calculateSha256(content);\n const mtime = fs.statSync(filePath).mtime.toISOString();\n const filename = path.basename(filePath, '.md');\n\n const parsed = parseMarkdown(content, filename);\n const targetProject = parsed.projectSlug || defaultProject;\n\n // Determine Note ID\n let noteId: string | undefined = parsed.id || ledger.files[relativePath]?.noteId;\n\n // Check if we need to sync\n const ledgerEntry = ledger.files[relativePath];\n if (ledgerEntry && ledgerEntry.sha256 === sha256 && noteId === ledgerEntry.noteId) {\n stats.skipped++;\n updatedLedgerFiles[relativePath] = ledgerEntry;\n continue;\n }\n\n if (dryRun) {\n if (noteId) {\n console.log(pc.cyan(`[Dry-run] Would UPDATE note ${noteId} (${relativePath})`));\n stats.updated++;\n } else {\n console.log(pc.green(`[Dry-run] Would CREATE note for ${relativePath}`));\n stats.created++;\n }\n continue;\n }\n\n // Sync payload\n const notePayload = {\n title: parsed.title,\n rawText: parsed.body,\n projectSlug: targetProject,\n tags: parsed.tags || [],\n status: parsed.status || 'active',\n canonicalType: parsed.canonicalType || 'event',\n };\n\n if (noteId) {\n // Update existing note\n try {\n const updatePayload: any = {\n title: notePayload.title,\n rawText: notePayload.rawText,\n tags: notePayload.tags,\n canonicalType: notePayload.canonicalType,\n };\n if (notePayload.status === 'resolved' || notePayload.status === 'archived') {\n updatePayload.status = notePayload.status;\n }\n await client.updateNote(noteId, updatePayload);\n stats.updated++;\n console.log(pc.cyan(`Updated: ${relativePath}`));\n } catch (err: any) {\n if (err instanceof ApiClientError && err.status === 404) {\n // Note was deleted remotely, treat as new creation\n console.log(pc.yellow(`Note ${noteId} not found on server. Re-creating: ${relativePath}`));\n noteId = undefined;\n } else {\n throw err;\n }\n }\n }\n\n if (!noteId) {\n // Create new note\n const res = await client.createNote(notePayload);\n const createdId = res.noteId || res.id;\n if (!createdId) {\n throw new Error('Failed to retrieve note ID from server response');\n }\n noteId = createdId;\n stats.created++;\n console.log(pc.green(`Created: ${relativePath}`));\n\n // Inject ID back to frontmatter\n injectIdIntoFrontmatter(filePath, content, noteId as string);\n }\n\n // Record in ledger\n updatedLedgerFiles[relativePath] = {\n noteId: noteId as string,\n sha256: calculateSha256(fs.readFileSync(filePath, 'utf8')), // recalculate in case we injected id\n lastModified: mtime,\n };\n\n } catch (err: any) {\n stats.failed++;\n console.error(pc.red(`Failed to sync ${relativePath}: ${err.message}`));\n }\n }\n\n if (!dryRun) {\n saveLedger(ledgerPath, {\n lastSyncedAt: new Date().toISOString(),\n files: {\n ...ledger.files,\n ...updatedLedgerFiles,\n },\n });\n }\n\n return stats;\n}\n\nconst IGNORED_DIRS = new Set([\n 'node_modules',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.git',\n '.next',\n]);\n\nfunction getMarkdownFiles(dir: string): string[] {\n let results: string[] = [];\n const list = fs.readdirSync(dir);\n for (const file of list) {\n if (file.startsWith('.')) continue; // skip hidden dirs/files\n const filePath = path.join(dir, file);\n const stat = fs.statSync(filePath);\n if (stat && stat.isDirectory()) {\n if (IGNORED_DIRS.has(file)) continue;\n results = results.concat(getMarkdownFiles(filePath));\n } else if (file.endsWith('.md')) {\n results.push(filePath);\n }\n }\n return results;\n}\n\nfunction calculateSha256(content: string): string {\n return crypto.createHash('sha256').update(content, 'utf8').digest('hex');\n}\n\nfunction loadLedger(ledgerPath: string): SyncLedger {\n const defaults: SyncLedger = {\n lastSyncedAt: '',\n files: {},\n };\n try {\n if (!fs.existsSync(ledgerPath)) return defaults;\n const data = fs.readFileSync(ledgerPath, 'utf8');\n return JSON.parse(data) as SyncLedger;\n } catch {\n return defaults;\n }\n}\n\nfunction saveLedger(ledgerPath: string, ledger: SyncLedger): void {\n try {\n fs.writeFileSync(ledgerPath, JSON.stringify(ledger, null, 2), 'utf8');\n } catch (err: any) {\n console.error(pc.red(`Error saving sync ledger: ${err.message}`));\n }\n}\n\ninterface ParsedMarkdown {\n id?: string;\n title?: string;\n projectSlug?: string;\n tags?: string[];\n canonicalType?: string;\n status?: string;\n body: string;\n}\n\nfunction parseMarkdown(content: string, fallbackTitle: string): ParsedMarkdown {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n if (!match) {\n return { body: content.trim(), title: fallbackTitle };\n }\n const yaml = match[1];\n const body = content.replace(frontmatterRegex, '').trim();\n const metadata: Record<string, string> = {};\n for (const line of yaml.split('\\n')) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const key = line.substring(0, colonIdx).trim();\n const val = line.substring(colonIdx + 1).trim();\n metadata[key] = val.replace(/^['\"]|['\"]$/g, '');\n }\n }\n return {\n id: metadata.id || undefined,\n title: metadata.title || fallbackTitle,\n projectSlug: metadata.project || undefined,\n tags: metadata.tags ? metadata.tags.split(',').map(t => t.trim()).filter(Boolean) : undefined,\n canonicalType: metadata.canonicalType || undefined,\n status: metadata.status || undefined,\n body,\n };\n}\n\nfunction injectIdIntoFrontmatter(filePath: string, content: string, id: string): void {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n if (match) {\n const yaml = match[1];\n if (yaml.includes('id:')) {\n const updatedYaml = yaml.replace(/id:\\s*[^\\r\\n]*/, `id: ${id}`);\n const updatedContent = content.replace(frontmatterRegex, `---\\n${updatedYaml}\\n---`);\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n } else {\n const updatedYaml = `id: ${id}\\n${yaml}`;\n const updatedContent = content.replace(frontmatterRegex, `---\\n${updatedYaml}\\n---`);\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n }\n } else {\n const updatedContent = `---\\nid: ${id}\\n---\\n${content}`;\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n }\n}\n"]}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport pc from 'picocolors';\nimport { spinner, outro } from '@clack/prompts';\nimport { client, ApiClientError } from '../client.js';\nimport { loadConfig } from '../config.js';\n\nexport interface SyncOptions {\n dir: string;\n project?: string;\n dryRun?: boolean;\n watch?: boolean;\n}\n\ninterface LedgerEntry {\n noteId: string;\n sha256: string;\n lastModified: string;\n}\n\ninterface SyncLedger {\n lastSyncedAt: string;\n files: Record<string, LedgerEntry>;\n}\n\nexport async function runSync(options: SyncOptions): Promise<void> {\n const targetPath = path.resolve(options.dir);\n if (!fs.existsSync(targetPath)) {\n console.error(pc.red(`Error: Path not found at ${options.dir}`));\n process.exit(1);\n }\n\n const isFile = fs.statSync(targetPath).isFile();\n const targetDir = isFile ? path.dirname(targetPath) : targetPath;\n const ledgerPath = path.join(targetDir, '.kb-sync.json');\n const filesList = isFile ? [targetPath] : undefined;\n\n const config = loadConfig();\n const defaultProject = options.project || config.defaultProjectSlug || 'inbox';\n\n if (options.dryRun) {\n console.log(pc.yellow('Running in DRY-RUN mode. No changes will be written or sent to the server.'));\n }\n\n if (options.watch) {\n console.log(pc.cyan(`Starting sync in WATCH mode for: ${targetPath}`));\n await syncDirectory(targetDir, defaultProject, ledgerPath, options.dryRun || false, filesList);\n\n // Watch logic\n let debounceTimer: NodeJS.Timeout | null = null;\n fs.watch(targetPath, { recursive: !isFile }, (eventType, filename) => {\n if (!isFile) {\n if (!filename || filename.endsWith('.kb-sync.json') || !filename.endsWith('.md')) return;\n }\n\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(async () => {\n console.log(pc.blue(`\\nChange detected in ${filename || path.basename(targetPath)}. Syncing...`));\n try {\n await syncDirectory(targetDir, defaultProject, ledgerPath, options.dryRun || false, filesList);\n } catch (err: any) {\n console.error(pc.red(`Watch sync failed: ${err.message}`));\n }\n }, 500);\n });\n\n // Keep process alive in watch mode\n await new Promise(() => { });\n return;\n }\n\n const s = spinner();\n s.start('Synchronizing files...');\n\n try {\n const stats = await syncDirectory(targetDir, defaultProject, ledgerPath, options.dryRun || false, filesList);\n s.stop(pc.green('Sync complete!'));\n\n console.log('\\n' + pc.bold('Sync Summary:'));\n console.log(` - Created: ${pc.green(stats.created)}`);\n console.log(` - Updated: ${pc.cyan(stats.updated)}`);\n console.log(` - Skipped: ${pc.gray(stats.skipped)}`);\n console.log(` - Failed: ${pc.red(stats.failed)}\\n`);\n\n outro(pc.green('Files synced successfully.'));\n } catch (error: any) {\n s.stop(pc.red('Sync failed'));\n console.error(pc.red(`Error: ${error.message || 'Failed to sync folder.'}`));\n process.exit(1);\n }\n}\n\nasync function syncDirectory(\n targetDir: string,\n defaultProject: string,\n ledgerPath: string,\n dryRun: boolean,\n filesList?: string[]\n) {\n const ledger = loadLedger(ledgerPath);\n const files = filesList || getMarkdownFiles(targetDir);\n\n const stats = { created: 0, updated: 0, skipped: 0, failed: 0 };\n const updatedLedgerFiles: Record<string, LedgerEntry> = {};\n\n for (const filePath of files) {\n // Relative path to use as key in ledger\n const relativePath = path.relative(targetDir, filePath).replace(/\\\\/g, '/');\n if (relativePath === '.kb-sync.json') continue;\n\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n const sha256 = calculateSha256(content);\n const mtime = fs.statSync(filePath).mtime.toISOString();\n const filename = path.basename(filePath, '.md');\n\n const parsed = parseMarkdown(content, filename);\n const targetProject = parsed.projectSlug || defaultProject;\n\n // Determine Note ID\n let noteId: string | undefined = parsed.id || ledger.files[relativePath]?.noteId;\n\n // Check if we need to sync\n const ledgerEntry = ledger.files[relativePath];\n if (ledgerEntry && ledgerEntry.sha256 === sha256 && noteId === ledgerEntry.noteId) {\n stats.skipped++;\n updatedLedgerFiles[relativePath] = ledgerEntry;\n continue;\n }\n\n if (dryRun) {\n if (noteId) {\n console.log(pc.cyan(`[Dry-run] Would UPDATE note ${noteId} (${relativePath})`));\n stats.updated++;\n } else {\n console.log(pc.green(`[Dry-run] Would CREATE note for ${relativePath}`));\n stats.created++;\n }\n continue;\n }\n\n // Sync payload\n const notePayload = {\n title: parsed.title,\n rawText: parsed.body,\n projectSlug: targetProject,\n tags: parsed.tags || [],\n status: parsed.status || 'active',\n canonicalType: parsed.canonicalType || 'event',\n source: 'manual',\n };\n\n if (noteId) {\n // Update existing note\n try {\n const updatePayload: any = {\n title: notePayload.title,\n rawText: notePayload.rawText,\n tags: notePayload.tags,\n canonicalType: notePayload.canonicalType,\n };\n if (notePayload.status === 'resolved' || notePayload.status === 'archived') {\n updatePayload.status = notePayload.status;\n }\n await client.updateNote(noteId, updatePayload);\n stats.updated++;\n console.log(pc.cyan(`Updated: ${relativePath}`));\n } catch (err: any) {\n if (err instanceof ApiClientError && err.status === 404) {\n // Note was deleted remotely, treat as new creation\n console.log(pc.yellow(`Note ${noteId} not found on server. Re-creating: ${relativePath}`));\n noteId = undefined;\n } else {\n throw err;\n }\n }\n }\n\n if (!noteId) {\n // Create new note\n const res = await client.createNote(notePayload);\n const createdId = res.noteId || res.id;\n if (!createdId) {\n throw new Error('Failed to retrieve note ID from server response');\n }\n noteId = createdId;\n stats.created++;\n console.log(pc.green(`Created: ${relativePath}`));\n\n // Inject ID back to frontmatter\n injectIdIntoFrontmatter(filePath, content, noteId as string);\n }\n\n // Record in ledger\n updatedLedgerFiles[relativePath] = {\n noteId: noteId as string,\n sha256: calculateSha256(fs.readFileSync(filePath, 'utf8')), // recalculate in case we injected id\n lastModified: mtime,\n };\n\n } catch (err: any) {\n stats.failed++;\n console.error(pc.red(`Failed to sync ${relativePath}: ${err.message}`));\n }\n }\n\n if (!dryRun) {\n saveLedger(ledgerPath, {\n lastSyncedAt: new Date().toISOString(),\n files: {\n ...ledger.files,\n ...updatedLedgerFiles,\n },\n });\n }\n\n return stats;\n}\n\nconst IGNORED_DIRS = new Set([\n 'node_modules',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.git',\n '.next',\n]);\n\nfunction getMarkdownFiles(dir: string): string[] {\n let results: string[] = [];\n const list = fs.readdirSync(dir);\n for (const file of list) {\n if (file.startsWith('.')) continue; // skip hidden dirs/files\n const filePath = path.join(dir, file);\n const stat = fs.statSync(filePath);\n if (stat && stat.isDirectory()) {\n if (IGNORED_DIRS.has(file)) continue;\n results = results.concat(getMarkdownFiles(filePath));\n } else if (file.endsWith('.md')) {\n results.push(filePath);\n }\n }\n return results;\n}\n\nfunction calculateSha256(content: string): string {\n return crypto.createHash('sha256').update(content, 'utf8').digest('hex');\n}\n\nfunction loadLedger(ledgerPath: string): SyncLedger {\n const defaults: SyncLedger = {\n lastSyncedAt: '',\n files: {},\n };\n try {\n if (!fs.existsSync(ledgerPath)) return defaults;\n const data = fs.readFileSync(ledgerPath, 'utf8');\n return JSON.parse(data) as SyncLedger;\n } catch {\n return defaults;\n }\n}\n\nfunction saveLedger(ledgerPath: string, ledger: SyncLedger): void {\n try {\n fs.writeFileSync(ledgerPath, JSON.stringify(ledger, null, 2), 'utf8');\n } catch (err: any) {\n console.error(pc.red(`Error saving sync ledger: ${err.message}`));\n }\n}\n\ninterface ParsedMarkdown {\n id?: string;\n title?: string;\n projectSlug?: string;\n tags?: string[];\n canonicalType?: string;\n status?: string;\n body: string;\n}\n\nfunction parseMarkdown(content: string, fallbackTitle: string): ParsedMarkdown {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n if (!match) {\n return { body: content.trim(), title: fallbackTitle };\n }\n const yaml = match[1];\n const body = content.replace(frontmatterRegex, '').trim();\n const metadata: Record<string, string> = {};\n for (const line of yaml.split('\\n')) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const key = line.substring(0, colonIdx).trim();\n const val = line.substring(colonIdx + 1).trim();\n metadata[key] = val.replace(/^['\"]|['\"]$/g, '');\n }\n }\n return {\n id: metadata.id || undefined,\n title: metadata.title || fallbackTitle,\n projectSlug: metadata.project || undefined,\n tags: metadata.tags ? metadata.tags.split(',').map(t => t.trim()).filter(Boolean) : undefined,\n canonicalType: metadata.canonicalType || undefined,\n status: metadata.status || undefined,\n body,\n };\n}\n\nfunction injectIdIntoFrontmatter(filePath: string, content: string, id: string): void {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n if (match) {\n const yaml = match[1];\n if (yaml.includes('id:')) {\n const updatedYaml = yaml.replace(/id:\\s*[^\\r\\n]*/, `id: ${id}`);\n const updatedContent = content.replace(frontmatterRegex, `---\\n${updatedYaml}\\n---`);\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n } else {\n const updatedYaml = `id: ${id}\\n${yaml}`;\n const updatedContent = content.replace(frontmatterRegex, `---\\n${updatedYaml}\\n---`);\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n }\n } else {\n const updatedContent = `---\\nid: ${id}\\n---\\n${content}`;\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pedroaugusto04/kb-cli",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "CLI client for the Knowledge Base AI system",
5
5
  "type": "module",
6
6
  "bin": {