gnosys 4.4.7 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/cli.js +140 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.js +65 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/attachments.d.ts +43 -0
  6. package/dist/lib/attachments.d.ts.map +1 -0
  7. package/dist/lib/attachments.js +154 -0
  8. package/dist/lib/attachments.js.map +1 -0
  9. package/dist/lib/audioExtract.d.ts +39 -0
  10. package/dist/lib/audioExtract.d.ts.map +1 -0
  11. package/dist/lib/audioExtract.js +220 -0
  12. package/dist/lib/audioExtract.js.map +1 -0
  13. package/dist/lib/chunkSplitter.d.ts +46 -0
  14. package/dist/lib/chunkSplitter.d.ts.map +1 -0
  15. package/dist/lib/chunkSplitter.js +233 -0
  16. package/dist/lib/chunkSplitter.js.map +1 -0
  17. package/dist/lib/config.d.ts +70 -1
  18. package/dist/lib/config.d.ts.map +1 -1
  19. package/dist/lib/config.js +24 -0
  20. package/dist/lib/config.js.map +1 -1
  21. package/dist/lib/db.d.ts +7 -1
  22. package/dist/lib/db.d.ts.map +1 -1
  23. package/dist/lib/db.js +31 -4
  24. package/dist/lib/db.js.map +1 -1
  25. package/dist/lib/dbWrite.d.ts.map +1 -1
  26. package/dist/lib/dbWrite.js +11 -0
  27. package/dist/lib/dbWrite.js.map +1 -1
  28. package/dist/lib/docxExtract.d.ts +27 -0
  29. package/dist/lib/docxExtract.d.ts.map +1 -0
  30. package/dist/lib/docxExtract.js +80 -0
  31. package/dist/lib/docxExtract.js.map +1 -0
  32. package/dist/lib/fileDetect.d.ts +20 -0
  33. package/dist/lib/fileDetect.d.ts.map +1 -0
  34. package/dist/lib/fileDetect.js +124 -0
  35. package/dist/lib/fileDetect.js.map +1 -0
  36. package/dist/lib/imageExtract.d.ts +26 -0
  37. package/dist/lib/imageExtract.d.ts.map +1 -0
  38. package/dist/lib/imageExtract.js +113 -0
  39. package/dist/lib/imageExtract.js.map +1 -0
  40. package/dist/lib/llm.d.ts +9 -0
  41. package/dist/lib/llm.d.ts.map +1 -1
  42. package/dist/lib/llm.js +102 -0
  43. package/dist/lib/llm.js.map +1 -1
  44. package/dist/lib/multimodalIngest.d.ts +68 -0
  45. package/dist/lib/multimodalIngest.d.ts.map +1 -0
  46. package/dist/lib/multimodalIngest.js +463 -0
  47. package/dist/lib/multimodalIngest.js.map +1 -0
  48. package/dist/lib/pdfExtract.d.ts +29 -0
  49. package/dist/lib/pdfExtract.d.ts.map +1 -0
  50. package/dist/lib/pdfExtract.js +163 -0
  51. package/dist/lib/pdfExtract.js.map +1 -0
  52. package/dist/lib/setup.d.ts.map +1 -1
  53. package/dist/lib/setup.js +96 -36
  54. package/dist/lib/setup.js.map +1 -1
  55. package/dist/lib/store.d.ts +3 -0
  56. package/dist/lib/store.d.ts.map +1 -1
  57. package/dist/lib/store.js.map +1 -1
  58. package/dist/lib/videoExtract.d.ts +30 -0
  59. package/dist/lib/videoExtract.d.ts.map +1 -0
  60. package/dist/lib/videoExtract.js +92 -0
  61. package/dist/lib/videoExtract.js.map +1 -0
  62. package/package.json +3 -1
package/dist/cli.js CHANGED
@@ -350,6 +350,36 @@ program
350
350
  console.error("No writable store found. Create a .gnosys/ directory or set GNOSYS_PERSONAL.");
351
351
  process.exit(1);
352
352
  }
353
+ // Check if input is a file path — if so, route through multimodal ingestion
354
+ if (existsSync(input)) {
355
+ const { ingestFile } = await import("./lib/multimodalIngest.js");
356
+ const storePath = writeTarget.store.getStorePath();
357
+ console.log(`Detected file: ${input}`);
358
+ console.log("Ingesting via multimodal pipeline...");
359
+ const result = await ingestFile({
360
+ filePath: path.resolve(input),
361
+ storePath,
362
+ mode: "llm",
363
+ author: opts.author,
364
+ authority: opts.authority,
365
+ onProgress: (p) => {
366
+ console.log(` [${p.current}/${p.total}] ${p.title || "Processing..."}`);
367
+ },
368
+ });
369
+ console.log(`\nFile type: ${result.fileType}`);
370
+ console.log(`Memories created: ${result.memories.length}`);
371
+ console.log(`Duration: ${(result.duration / 1000).toFixed(1)}s`);
372
+ for (const mem of result.memories) {
373
+ console.log(` ${mem.id}: ${mem.title}`);
374
+ }
375
+ if (result.errors.length > 0) {
376
+ console.error(`\nErrors (${result.errors.length}):`);
377
+ for (const err of result.errors) {
378
+ console.error(` Chunk ${err.chunk}: ${err.error}`);
379
+ }
380
+ }
381
+ return;
382
+ }
353
383
  const tagRegistry = new GnosysTagRegistry(writeTarget.store.getStorePath());
354
384
  await tagRegistry.load();
355
385
  const ingestion = new GnosysIngestion(writeTarget.store, tagRegistry);
@@ -439,6 +469,12 @@ program
439
469
  await fs.writeFile(path.join(storePath, ".config", "tags.json"), JSON.stringify(defaultRegistry, null, 2), "utf-8");
440
470
  // Write default gnosys.json config (LLM settings)
441
471
  await fs.writeFile(path.join(storePath, ".config", "gnosys-config.json"), generateConfigTemplate() + "\n", "utf-8");
472
+ // v5.0: Create attachments directory and empty manifest
473
+ await fs.mkdir(path.join(storePath, "attachments"), { recursive: true });
474
+ await fs.writeFile(path.join(storePath, "attachments", "attachments.json"), JSON.stringify({ attachments: [] }, null, 2) + "\n", "utf-8");
475
+ // Create .gitignore inside .gnosys to exclude large binary attachments
476
+ const storeGitignore = "# Large binary attachments (tracked via manifest, not git)\nattachments/\n";
477
+ await fs.writeFile(path.join(storePath, ".gitignore"), storeGitignore, "utf-8");
442
478
  const changelog = `# Gnosys Changelog\n\n## ${new Date().toISOString().split("T")[0]}\n\n- Store initialized\n`;
443
479
  await fs.writeFile(path.join(storePath, "CHANGELOG.md"), changelog, "utf-8");
444
480
  try {
@@ -793,6 +829,110 @@ program
793
829
  console.log(`Memory added to [${writeTarget.label}]: ${opts.title}`);
794
830
  console.log(`Path: ${writeTarget.label}:${relPath}`);
795
831
  });
832
+ // ─── gnosys ingest <file> ─────────────────────────────────────────────────
833
+ program
834
+ .command("ingest <fileOrGlob>")
835
+ .description("Ingest a file (PDF, DOCX, TXT, MD) into Gnosys memory. Extracts text, splits into chunks, and creates atomic memories.")
836
+ .option("--mode <mode>", "Ingestion mode: llm or structured", "llm")
837
+ .option("-s, --store <store>", "Target store: project, personal, global")
838
+ .option("-a, --author <author>", "Author", "human")
839
+ .option("--authority <authority>", "Authority level", "imported")
840
+ .option("--dry-run", "Preview what would be created without writing")
841
+ .option("--list-attachments", "List all stored attachments")
842
+ .option("-d, --directory <dir>", "Project directory")
843
+ .action(async (fileOrGlob, opts) => {
844
+ // List attachments mode
845
+ if (opts.listAttachments) {
846
+ const { listAttachments } = await import("./lib/attachments.js");
847
+ const resolver = await getResolver();
848
+ const writeTarget = resolver.getWriteTarget(opts.store || undefined);
849
+ if (!writeTarget) {
850
+ console.error("No writable store found.");
851
+ process.exit(1);
852
+ }
853
+ const attachments = await listAttachments(writeTarget.store.getStorePath());
854
+ if (attachments.length === 0) {
855
+ console.log("No attachments found.");
856
+ return;
857
+ }
858
+ console.log(`Found ${attachments.length} attachment(s):\n`);
859
+ for (const a of attachments) {
860
+ const sizeMb = (a.sizeBytes / (1024 * 1024)).toFixed(2);
861
+ console.log(` ${a.originalName} (${sizeMb}MB, ${a.extension})`);
862
+ console.log(` UUID: ${a.uuid}`);
863
+ console.log(` Hash: ${a.contentHash.slice(0, 16)}...`);
864
+ console.log(` Memories: ${a.memoryIds.length > 0 ? a.memoryIds.join(", ") : "none"}`);
865
+ console.log(` Created: ${a.createdAt}\n`);
866
+ }
867
+ return;
868
+ }
869
+ // Resolve the file path
870
+ const resolvedPath = path.resolve(opts.directory || process.cwd(), fileOrGlob);
871
+ // Check the file exists
872
+ try {
873
+ await fs.access(resolvedPath);
874
+ }
875
+ catch {
876
+ console.error(`File not found: ${resolvedPath}`);
877
+ process.exit(1);
878
+ }
879
+ // Resolve the store
880
+ const resolver = await getResolver();
881
+ const writeTarget = resolver.getWriteTarget(opts.store || undefined);
882
+ if (!writeTarget) {
883
+ console.error("No writable store found. Create a .gnosys/ directory or set GNOSYS_PERSONAL.");
884
+ process.exit(1);
885
+ }
886
+ const storePath = writeTarget.store.getStorePath();
887
+ // Run ingestion
888
+ const { ingestFile } = await import("./lib/multimodalIngest.js");
889
+ console.log(`Ingesting: ${path.basename(resolvedPath)}`);
890
+ if (opts.dryRun) {
891
+ console.log("(dry run — no files will be written)\n");
892
+ }
893
+ try {
894
+ const result = await ingestFile({
895
+ filePath: resolvedPath,
896
+ storePath,
897
+ mode: opts.mode,
898
+ store: opts.store || undefined,
899
+ author: opts.author,
900
+ authority: opts.authority,
901
+ dryRun: opts.dryRun,
902
+ projectRoot: opts.directory,
903
+ onProgress: (p) => {
904
+ process.stdout.write(`\r Processing chunk ${p.current}/${p.total}...`);
905
+ },
906
+ });
907
+ // Clear the progress line
908
+ if (result.memories.length > 0) {
909
+ process.stdout.write("\r" + " ".repeat(60) + "\r");
910
+ }
911
+ // Print results
912
+ console.log(`\nFile type: ${result.fileType}`);
913
+ console.log(`Attachment: ${result.attachment.originalName} (${result.attachment.uuid.slice(0, 8)}...)`);
914
+ console.log(`Duration: ${(result.duration / 1000).toFixed(1)}s`);
915
+ console.log(`Memories created: ${result.memories.length}`);
916
+ if (result.memories.length > 0) {
917
+ console.log("\nMemories:");
918
+ for (const m of result.memories) {
919
+ const extra = m.page ? ` [page ${m.page}]` : "";
920
+ console.log(` ${m.id}: ${m.title}${extra}`);
921
+ console.log(` Path: ${m.path}`);
922
+ }
923
+ }
924
+ if (result.errors.length > 0) {
925
+ console.log(`\nErrors (${result.errors.length}):`);
926
+ for (const e of result.errors) {
927
+ console.log(` Chunk ${e.chunk}: ${e.error}`);
928
+ }
929
+ }
930
+ }
931
+ catch (err) {
932
+ console.error(`\nIngestion failed: ${err instanceof Error ? err.message : err}`);
933
+ process.exit(1);
934
+ }
935
+ });
796
936
  // ─── gnosys tags-add ────────────────────────────────────────────────────
797
937
  program
798
938
  .command("tags-add")