@futdevpro/fdp-agent-memory 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +345 -0
  2. package/build/package.json +96 -0
  3. package/build/src/_assets/mcp-client-config/README.md +29 -0
  4. package/build/src/_assets/mcp-client-config/claude_desktop_config.json +15 -0
  5. package/build/src/_assets/mcp-client-config/mcp.json +15 -0
  6. package/build/src/_collections/config-catalog.const.js +180 -0
  7. package/build/src/_collections/config-error-codes.const.js +30 -0
  8. package/build/src/_collections/config-presets.const.js +25 -0
  9. package/build/src/_collections/error-banners.const.js +100 -0
  10. package/build/src/_collections/error-codes.const.js +150 -0
  11. package/build/src/_collections/fam-db-models.const.js +37 -0
  12. package/build/src/_collections/fam-entry-bootstrap.util.js +80 -0
  13. package/build/src/_collections/fam-error-context.util.js +90 -0
  14. package/build/src/_collections/fam-error-factory.util.js +64 -0
  15. package/build/src/_enums/fam-config-level.type-enum.js +15 -0
  16. package/build/src/_enums/fam-table.type-enum.js +20 -0
  17. package/build/src/_integration-tests/_helpers/fam-integration-test-setup.util.js +105 -0
  18. package/build/src/_models/data-models/fam-codebase.data-model.js +51 -0
  19. package/build/src/_models/data-models/fam-coding-patterns.data-model.js +58 -0
  20. package/build/src/_models/data-models/fam-config.data-model.js +68 -0
  21. package/build/src/_models/data-models/fam-documents.data-model.js +53 -0
  22. package/build/src/_models/data-models/fam-entry-base-properties.const.js +43 -0
  23. package/build/src/_models/data-models/fam-entry.data-model.js +81 -0
  24. package/build/src/_models/data-models/fam-error.data-model.js +88 -0
  25. package/build/src/_models/data-models/fam-ingest-run.data-model.js +74 -0
  26. package/build/src/_models/data-models/fam-knowledge.data-model.js +48 -0
  27. package/build/src/_models/data-models/fam-memory.data-model.js +55 -0
  28. package/build/src/_models/data-models/fam-reference.data-model.js +67 -0
  29. package/build/src/_models/data-models/fam-rules.data-model.js +51 -0
  30. package/build/src/_models/data-models/fam-scope.data-model.js +52 -0
  31. package/build/src/_models/interfaces/fam-common.interface.js +23 -0
  32. package/build/src/_models/interfaces/fam-config.interface.js +2 -0
  33. package/build/src/_models/interfaces/fam-error.interface.js +2 -0
  34. package/build/src/_modules/embedding/_collections/fam-embedding-pricing.const.js +22 -0
  35. package/build/src/_modules/embedding/_collections/fam-store-registry.const.js +63 -0
  36. package/build/src/_modules/embedding/_models/interfaces/fam-embedding-cost.interface.js +10 -0
  37. package/build/src/_modules/embedding/_models/interfaces/fam-embedding-provider.interface.js +2 -0
  38. package/build/src/_modules/embedding/_models/interfaces/fam-resolved-provider.interface.js +2 -0
  39. package/build/src/_modules/embedding/_services/fam-embedding-bootstrap.control-service.js +52 -0
  40. package/build/src/_modules/embedding/_services/fam-embedding-cost.control-service.js +175 -0
  41. package/build/src/_modules/embedding/_services/fam-embedding-pipeline.control-service.js +202 -0
  42. package/build/src/_modules/embedding/_services/fam-embedding-preset.control-service.js +66 -0
  43. package/build/src/_modules/embedding/_services/fam-embedding.control-service.js +253 -0
  44. package/build/src/_modules/embedding/_services/fam-entry.data-service.js +64 -0
  45. package/build/src/_modules/embedding/_services/fam-lmstudio-embedding.provider.js +112 -0
  46. package/build/src/_modules/embedding/_services/fam-mock-embedding.provider.js +64 -0
  47. package/build/src/_modules/embedding/_services/fam-openai-embedding.provider.js +64 -0
  48. package/build/src/_modules/embedding/_services/fam-vector-search.control-service.js +244 -0
  49. package/build/src/_modules/embedding/index.js +40 -0
  50. package/build/src/_modules/ingest/_collections/fam-content-hash.util.js +35 -0
  51. package/build/src/_modules/ingest/_collections/fam-file-routing.util.js +95 -0
  52. package/build/src/_modules/ingest/_collections/fam-glob-match.util.js +84 -0
  53. package/build/src/_modules/ingest/_collections/fam-md-chunker.util.js +164 -0
  54. package/build/src/_modules/ingest/_collections/fam-scan-path.util.js +91 -0
  55. package/build/src/_modules/ingest/_collections/fam-secret-exclude.util.js +54 -0
  56. package/build/src/_modules/ingest/_collections/fam-sliding-chunker.util.js +76 -0
  57. package/build/src/_modules/ingest/_collections/fam-ts-chunker.util.js +316 -0
  58. package/build/src/_modules/ingest/_models/interfaces/fam-ingest.interface.js +2 -0
  59. package/build/src/_modules/ingest/_services/fam-chunker.control-service.js +114 -0
  60. package/build/src/_modules/ingest/_services/fam-delta-compare.util.js +74 -0
  61. package/build/src/_modules/ingest/_services/fam-ingest-run.data-service.js +85 -0
  62. package/build/src/_modules/ingest/_services/fam-ingest.control-service.js +384 -0
  63. package/build/src/_modules/ingest/_services/fam-scan.control-service.js +211 -0
  64. package/build/src/_modules/ingest/index.js +46 -0
  65. package/build/src/_modules/mcp/_collections/fam-core-tools.const.js +186 -0
  66. package/build/src/_modules/mcp/_models/interfaces/fam-mcp.interface.js +31 -0
  67. package/build/src/_modules/mcp/_services/fam-capabilities-tool.service.js +111 -0
  68. package/build/src/_modules/mcp/_services/fam-capability-registry.service.js +1180 -0
  69. package/build/src/_modules/mcp/_services/fam-mcp-adapter.service.js +123 -0
  70. package/build/src/_modules/mcp/_services/fam-mcp-server.service.js +69 -0
  71. package/build/src/_modules/mcp/_services/fam-read-tool.service.js +99 -0
  72. package/build/src/_modules/mcp/_services/fam-write-tool.service.js +460 -0
  73. package/build/src/_modules/mcp/index.js +35 -0
  74. package/build/src/_modules/migration/_collections/fam-claude-mem-normalize.util.js +166 -0
  75. package/build/src/_modules/migration/_collections/fam-import-content-hash.util.js +38 -0
  76. package/build/src/_modules/migration/_collections/fam-target-mapping.util.js +90 -0
  77. package/build/src/_modules/migration/_enums/fam-claude-mem-source.type-enum.js +20 -0
  78. package/build/src/_modules/migration/_models/interfaces/fam-claude-mem.interface.js +26 -0
  79. package/build/src/_modules/migration/_services/fam-claude-mem-export-reader.service.js +134 -0
  80. package/build/src/_modules/migration/_services/fam-claude-mem-import.control-service.js +533 -0
  81. package/build/src/_modules/migration/_services/fam-claude-mem-sqlite-reader.service.js +144 -0
  82. package/build/src/_modules/migration/_services/fam-claude-mem-worker-reader.service.js +115 -0
  83. package/build/src/_modules/migration/_services/fam-import-dedup.data-service.js +102 -0
  84. package/build/src/_modules/migration/index.js +38 -0
  85. package/build/src/_modules/retrieval/_models/interfaces/fam-retrieval.interface.js +2 -0
  86. package/build/src/_modules/retrieval/_services/fam-retrieval-candidate.data-service.js +67 -0
  87. package/build/src/_modules/retrieval/_services/fam-retrieval-suggestions.util.js +182 -0
  88. package/build/src/_modules/retrieval/_services/fam-retrieval.control-service.js +282 -0
  89. package/build/src/_modules/retrieval/index.js +22 -0
  90. package/build/src/_modules/scope-reference/_collections/fam-fuzzy-match.util.js +86 -0
  91. package/build/src/_modules/scope-reference/_collections/fam-scope-normalize.util.js +47 -0
  92. package/build/src/_modules/scope-reference/_models/interfaces/fam-reference-resolution.interface.js +2 -0
  93. package/build/src/_modules/scope-reference/_models/interfaces/fam-resolution-trace.interface.js +2 -0
  94. package/build/src/_modules/scope-reference/_services/fam-reference.data-service.js +179 -0
  95. package/build/src/_modules/scope-reference/_services/fam-scope-resolver.control-service.js +473 -0
  96. package/build/src/_modules/scope-reference/_services/fam-scope.data-service.js +215 -0
  97. package/build/src/_modules/scope-reference/index.js +26 -0
  98. package/build/src/_routes/server/api/api.controller.js +400 -0
  99. package/build/src/_routes/server/client-app/client-app.control-service.js +132 -0
  100. package/build/src/_routes/server/client-app/client-app.controller.js +35 -0
  101. package/build/src/_routes/server/config/config.control-service.js +476 -0
  102. package/build/src/_routes/server/config/config.data-service.js +49 -0
  103. package/build/src/_routes/server/errors/errors.control-service.js +123 -0
  104. package/build/src/_routes/server/errors/errors.controller.js +65 -0
  105. package/build/src/_routes/server/errors/errors.data-service.js +80 -0
  106. package/build/src/_routes/server/server-status/server-status.control-service.js +19 -0
  107. package/build/src/_routes/server/server-status/server-status.controller.js +39 -0
  108. package/build/src/app.server.js +122 -0
  109. package/build/src/environments/environment.js +20 -0
  110. package/build/src/index.js +18 -0
  111. package/client-dist/chunk-GHKRM4SM.js +1 -0
  112. package/client-dist/chunk-LMTL7GA3.js +575 -0
  113. package/client-dist/index.html +17 -0
  114. package/client-dist/main-2KWB3QYK.js +2 -0
  115. package/client-dist/polyfills-HGDOEU5L.js +2 -0
  116. package/client-dist/styles-3J7JD5YE.css +1 -0
  117. package/package.json +96 -0
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_ImportContentHash_Util = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const crypto = tslib_1.__importStar(require("crypto"));
6
+ /**
7
+ * `FAM_ImportContentHash_Util` (SP-11.2, dsgn-009 §3) — a claude-mem import `contentHash`-e:
8
+ * `sha256(normalize(narrative + text + facts))`. A `normalize` a dsgn-009 §3 szerinti
9
+ * **whitespace-collapse + trim + lowercase** a hash-bemeneten — így az `importSourceId`-egyezés
10
+ * (1. lépcső) hiányában a `contentHash`-összevetés (2. lépcső) megbízhatóan kiszűri az azonos
11
+ * tartalmat más id alatt. Statikus util (egy implementáció — a fals-negatív dedup elkerülésére).
12
+ *
13
+ * **FIGYELEM:** ez a normalizálás SZÁNDÉKOSAN agresszívabb (lowercase + `\s+→' '`), mint a dsgn-004
14
+ * delta-detection `FAM_ContentHash_Util` (ami a SOR-szerkezetet megőrzi a kódstruktúra-jelentős
15
+ * sortörésekhez). Az import a TARTALMI ekvivalenciát keresi (más rendszerből importált, eltérő
16
+ * whitespace-/kis-nagybetű-formázású szöveg is duplikátum), ezért a teljes whitespace-collapse +
17
+ * lowercase a helyes — dsgn-009 §3.
18
+ */
19
+ class FAM_ImportContentHash_Util {
20
+ /**
21
+ * Az import-tartalom SHA-256 ujjlenyomata (dsgn-009 §3). A `narrative`+`text`+`facts` összefűzve,
22
+ * normalizálva. Determinisztikus: ugyanaz a (normalizált) tartalom mindig ugyanazt a hash-t adja.
23
+ */
24
+ static hash(set) {
25
+ const composed = [set.narrative, set.text, set.facts]
26
+ .filter((part) => typeof part === 'string' && part.length > 0)
27
+ .join('\n');
28
+ return crypto.createHash('sha256').update(FAM_ImportContentHash_Util.normalize(composed)).digest('hex');
29
+ }
30
+ /**
31
+ * A dsgn-009 §3 normalizálás: minden whitespace-szekvencia EGY szóközre, trim, lowercase. Így a
32
+ * formázás-/kis-nagybetű-zaj NEM okoz fals-negatív content-dedup-ot.
33
+ */
34
+ static normalize(content) {
35
+ return content.replace(/\s+/g, ' ').trim().toLowerCase();
36
+ }
37
+ }
38
+ exports.FAM_ImportContentHash_Util = FAM_ImportContentHash_Util;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_TargetMapping_Util = void 0;
4
+ const fam_table_type_enum_1 = require("../../../_enums/fam-table.type-enum");
5
+ const fam_claude_mem_interface_1 = require("../_models/interfaces/fam-claude-mem.interface");
6
+ /**
7
+ * A §4 default target-mapping az observation `type`-okra (dsgn-009 §4 tábla). Ahol két tár jöhet szóba,
8
+ * az ELSŐ a default. A `decision`→knowledge, `bugfix`→coding_patterns, `feature`→memory,
9
+ * `refactor`→coding_patterns, `discovery`→knowledge, `change`→memory. Ismeretlen/hiányzó type → `change`.
10
+ */
11
+ const OBSERVATION_TYPE_DEFAULTS = {
12
+ decision: { table: fam_table_type_enum_1.FAM_Table.knowledge, kind: 'knowledge', tags: ['decision_rationale'] },
13
+ bugfix: { table: fam_table_type_enum_1.FAM_Table.codingPatterns, kind: 'pattern', tags: ['debugging_pattern', 'bugfix'] },
14
+ feature: { table: fam_table_type_enum_1.FAM_Table.memory, kind: 'memory_entry', tags: ['development_history', 'feature'] },
15
+ refactor: { table: fam_table_type_enum_1.FAM_Table.codingPatterns, kind: 'pattern', tags: ['refactor'] },
16
+ discovery: { table: fam_table_type_enum_1.FAM_Table.knowledge, kind: 'knowledge', tags: ['fact', 'discovery'] },
17
+ change: { table: fam_table_type_enum_1.FAM_Table.memory, kind: 'memory_entry', tags: ['development_history', 'change'] },
18
+ };
19
+ /** A nem-observation entitások default-leképezése (dsgn-009 §4). */
20
+ const ENTITY_DEFAULTS = {
21
+ [fam_claude_mem_interface_1.FAM_ClaudeMemEntity_Type.sessionSummary]: { table: fam_table_type_enum_1.FAM_Table.memory, kind: 'summary', tags: ['session_history'] },
22
+ [fam_claude_mem_interface_1.FAM_ClaudeMemEntity_Type.userPrompt]: { table: fam_table_type_enum_1.FAM_Table.memory, kind: 'user_prompt', tags: ['temporary_context'] },
23
+ };
24
+ /**
25
+ * `FAM_TargetMapping_Util` (SP-11.2, dsgn-009 §4) — egy normalizált claude-mem rekord → cél-leképezés
26
+ * (table + kind + tags + content). Statikus, tisztán determinista (nincs DB/async): a `project`→scope
27
+ * feloldás KÜLÖN, a engine-ben (MP-3 `resolveForWrite`) megy. A §4 default leképezést alkalmazza, majd
28
+ * az override-okat (`byType` / `byId`) ráhúzza; a `concepts[]` további tag-ekként hozzáfűződik.
29
+ */
30
+ class FAM_TargetMapping_Util {
31
+ /**
32
+ * A `importSourceId` ELSŐDLEGES dedup-kulcs (dsgn-009 §3 tábla): `<forrás-tábla>:<row id>`. Az
33
+ * entitás-enum értéke MÁR a forrás-tábla neve (`observations` / `session_summaries` / `user_prompts`).
34
+ */
35
+ static importSourceId(record) {
36
+ return `${record.entity}:${record.sourceRowId}`;
37
+ }
38
+ /**
39
+ * A cél-tár + kind + tags feloldása (default → override). Az observation a `type`-ról, a
40
+ * summary/prompt az entitás-default-ról; ismeretlen → `change` (memory). Az override (`byId`
41
+ * elsőbbség a `byType` előtt) szelektíven felülír; a `concepts[]` mindig tag-ként hozzáfűződik
42
+ * (kivéve ha az override teljes tag-cserét ad — akkor is hozzáfűzzük a concept-eket a provenance-hoz).
43
+ */
44
+ static resolveTarget(set) {
45
+ const base = FAM_TargetMapping_Util.defaultFor(set.record);
46
+ const importSourceId = FAM_TargetMapping_Util.importSourceId(set.record);
47
+ const byType = set.record.type ? set.overrides?.byType?.[set.record.type] : undefined;
48
+ const byId = set.overrides?.byId?.[importSourceId];
49
+ // Precedencia: byId > byType > default.
50
+ const table = byId?.table ?? byType?.table ?? base.table;
51
+ const kind = byId?.kind ?? byType?.kind ?? base.kind;
52
+ const baseTags = byId?.tags ?? byType?.tags ?? base.tags;
53
+ // A concept-ek további tag-ekként (dedup-olva, üres kiszűrve) — provenance.
54
+ const tags = FAM_TargetMapping_Util.mergeTags(baseTags, set.record.concepts);
55
+ return { table: table, kind: kind, tags: tags };
56
+ }
57
+ /**
58
+ * A vektorizálandó content-kompozíció (dsgn-009 §4): `join(title, subtitle, narrative, text, facts)`.
59
+ * Az üres mezők kihagyva; sortöréssel fűzve (a szemantikai jel maximalizálásához). Summary/prompt
60
+ * esetén a `text` hordozza a tartalmat (a `narrative`/`facts` üres) — a join ezt is lefedi.
61
+ */
62
+ static composeContent(record) {
63
+ return [record.title, record.subtitle, record.narrative, record.text, record.facts]
64
+ .filter((part) => typeof part === 'string' && part.trim().length > 0)
65
+ .map((part) => part.trim())
66
+ .join('\n');
67
+ }
68
+ /** A default target egy rekordra: observation → `type`-default (ismeretlen → `change`); egyébként entitás-default. */
69
+ static defaultFor(record) {
70
+ if (record.entity === fam_claude_mem_interface_1.FAM_ClaudeMemEntity_Type.observation) {
71
+ const type = record.type ?? 'change';
72
+ return OBSERVATION_TYPE_DEFAULTS[type] ?? OBSERVATION_TYPE_DEFAULTS.change;
73
+ }
74
+ return ENTITY_DEFAULTS[record.entity] ?? { table: fam_table_type_enum_1.FAM_Table.memory, kind: 'memory_entry', tags: [] };
75
+ }
76
+ /** A base-tag-ek + a concept-tag-ek egyesítése (rendezett dedup, üres kiszűrve). */
77
+ static mergeTags(baseTags, concepts) {
78
+ const seen = new Set();
79
+ const result = [];
80
+ for (const tag of [...baseTags, ...concepts]) {
81
+ const clean = (tag ?? '').trim();
82
+ if (clean.length && !seen.has(clean)) {
83
+ seen.add(clean);
84
+ result.push(clean);
85
+ }
86
+ }
87
+ return result;
88
+ }
89
+ }
90
+ exports.FAM_TargetMapping_Util = FAM_TargetMapping_Util;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_ClaudeMemSource_Type = void 0;
4
+ /**
5
+ * A claude-mem import forrás-csatorna (dsgn-009 §1 tábla). A `from` lokátor választja meg, melyik
6
+ * reader olvas: export-JSON (default, függőség-mentes), SQLite (build-only, BFR-AM-009 fallback),
7
+ * live worker-api (opcionális).
8
+ *
9
+ * Enum-konvenció (workspace base CLAUDE.md): key camelCase, value kebab-case (a wire-érték a
10
+ * dsgn-009 §1 string-je; ez kerül a `write.import.from` / capability `from` argumentumba).
11
+ */
12
+ var FAM_ClaudeMemSource_Type;
13
+ (function (FAM_ClaudeMemSource_Type) {
14
+ /** Export-JSON fájl (`<path>.json`) — MVP1 default, csak `JSON.parse` (függőség-mentes). */
15
+ FAM_ClaudeMemSource_Type["exportJson"] = "export-json";
16
+ /** SQLite DB (`~/.claude-mem/claude-mem.db`) — build-only izolált függőség (BFR-AM-009 fallback). */
17
+ FAM_ClaudeMemSource_Type["sqlite"] = "sqlite";
18
+ /** Live worker-api (`http://localhost:<port>`) — opcionális, csak ha a worker fut. */
19
+ FAM_ClaudeMemSource_Type["workerApi"] = "worker-api";
20
+ })(FAM_ClaudeMemSource_Type || (exports.FAM_ClaudeMemSource_Type = FAM_ClaudeMemSource_Type = {}));
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_ClaudeMemEntity_Type = void 0;
4
+ /**
5
+ * claude-mem migráció shared vokabulár (MP-11, dsgn-009). Egy fájlban a szorosan összetartozó
6
+ * import-/dedup-/mapping-/flow-típusok (`*.interface.ts` az egy-export-per-file konvenció ismert
7
+ * kivétele, mint a `fam-common.interface.ts`). A `FAM_Entry` / `importSource` / `importSourceId` /
8
+ * `contentHash` mezőket NEM redefiniáljuk — dsgn-001 §2 a szerződés; ITT a forrás-shape + a
9
+ * normalizált köztes rekord + a leképezés/flow I/O él.
10
+ */
11
+ /**
12
+ * A claude-mem entitás-típusa a normalizált köztes rekordban (dsgn-009 §2). A `observation` a fő
13
+ * forrás; a `session_summary`/`user_prompt` leszármaztatott entry; a `session` NEM önálló entry
14
+ * (metaadat — `project`→scope + sessionId/runId hidratálás), ezért NEM a normalizált halmazban.
15
+ *
16
+ * Enum-konvenció: key camelCase, value a forrás-tábla neve (a `importSourceId` prefixe is ez).
17
+ */
18
+ var FAM_ClaudeMemEntity_Type;
19
+ (function (FAM_ClaudeMemEntity_Type) {
20
+ /** observations — a migráció gerince (`type`-tól függő cél-tár, dsgn-009 §4). */
21
+ FAM_ClaudeMemEntity_Type["observation"] = "observations";
22
+ /** session_summaries — `memory` (`kind=summary`). */
23
+ FAM_ClaudeMemEntity_Type["sessionSummary"] = "session_summaries";
24
+ /** user_prompts — opcionális (`memory`, `kind=user_prompt`); default OFF. */
25
+ FAM_ClaudeMemEntity_Type["userPrompt"] = "user_prompts";
26
+ })(FAM_ClaudeMemEntity_Type || (exports.FAM_ClaudeMemEntity_Type = FAM_ClaudeMemEntity_Type = {}));
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_ClaudeMemExportReader_Service = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fs = tslib_1.__importStar(require("fs"));
6
+ const error_codes_const_1 = require("../../../_collections/error-codes.const");
7
+ const fam_error_factory_util_1 = require("../../../_collections/fam-error-factory.util");
8
+ const fam_claude_mem_source_type_enum_1 = require("../_enums/fam-claude-mem-source.type-enum");
9
+ const fam_claude_mem_normalize_util_1 = require("../_collections/fam-claude-mem-normalize.util");
10
+ /**
11
+ * `FAM_ClaudeMemExportReader_Service` (SP-11.1) — az **export-JSON reader** (MVP1 DEFAULT,
12
+ * függőség-mentes). A claude-mem export-wrapper-t (`{ observations[], sessions[], summaries[],
13
+ * prompts[] }`, dsgn-009 §1.1) `JSON.parse`-olja, majd a közös normalizálóra adja. Statikus util-szerű
14
+ * service (nincs DB-/external-függőség; egy belépési pont). NEM az LLM-facing MCP-toolokon megy át —
15
+ * közvetlenül a fájlból olvas (dsgn-009 §1 dedikált bulk import adapter).
16
+ *
17
+ * **Defenzív parse (dsgn-009 §9):** fájl-hiány / nem-JSON / nem-objektum → tiszta strukturált hiba
18
+ * (`FAM-IMP-SOURCE-001`), NEM hang/crash; hiányzó vagy nem-tömb mező → warning + üres lista (a többi
19
+ * mező feldolgozva). A deklarált `total*` és a tényleges hossz eltérése drift-warning.
20
+ */
21
+ class FAM_ClaudeMemExportReader_Service {
22
+ static _instance;
23
+ /** Default issuer (a forrás-hibák issuer-éhez; dsgn-008). */
24
+ issuer = 'FAM_ClaudeMemExportReader_Service';
25
+ static getInstance() {
26
+ if (!FAM_ClaudeMemExportReader_Service._instance) {
27
+ FAM_ClaudeMemExportReader_Service._instance = new FAM_ClaudeMemExportReader_Service();
28
+ }
29
+ return FAM_ClaudeMemExportReader_Service._instance;
30
+ }
31
+ /**
32
+ * Az export-JSON fájl beolvasása + parse + normalizálás (SP-11.1). A `path` az export-fájl
33
+ * útvonala. Fájl-hiány / parse-hiba → `FAM-IMP-SOURCE-001` (deskriptív). A normalizált rekordokat
34
+ * + a session-metaadatot + a counts-ot + a defenzív warning-okat adja.
35
+ */
36
+ read(set) {
37
+ if (!set.path || !set.path.trim().length) {
38
+ throw fam_error_factory_util_1.FAM_Error_Util.create({
39
+ errorCode: error_codes_const_1.FAM_ERROR_CODES.impSource,
40
+ message: 'Az export-JSON importhoz `path` kötelező (a claude-mem export-fájl útvonala).',
41
+ issuer: this.issuer,
42
+ context: { operation: 'import-read-export-json' },
43
+ });
44
+ }
45
+ if (!fs.existsSync(set.path)) {
46
+ throw fam_error_factory_util_1.FAM_Error_Util.create({
47
+ errorCode: error_codes_const_1.FAM_ERROR_CODES.impSource,
48
+ message: `A claude-mem export-JSON fájl nem található: '${set.path}'. Ellenőrizd az útvonalat `
49
+ + '(a default forrás `~/.claude-mem`-ből exportált JSON).',
50
+ issuer: this.issuer,
51
+ context: { operation: 'import-read-export-json' },
52
+ });
53
+ }
54
+ const rawText = this.readFile(set.path);
55
+ const wrapper = this.parseWrapper(rawText, set.path);
56
+ const warnings = [];
57
+ const observations = this.asArray(wrapper.observations, 'observations', warnings);
58
+ const summaries = this.asArray(wrapper.summaries, 'summaries', warnings);
59
+ const prompts = this.asArray(wrapper.prompts, 'prompts', warnings);
60
+ const sessions = this.asArray(wrapper.sessions, 'sessions', warnings);
61
+ // Drift-ellenőrzés: a deklarált total* és a tényleges hossz eltérése (nem-néma, csak warning).
62
+ this.checkDrift(wrapper.totalObservations, observations.length, 'observations', warnings);
63
+ this.checkDrift(wrapper.totalSummaries, summaries.length, 'summaries', warnings);
64
+ this.checkDrift(wrapper.totalPrompts, prompts.length, 'prompts', warnings);
65
+ this.checkDrift(wrapper.totalSessions, sessions.length, 'sessions', warnings);
66
+ const normalized = fam_claude_mem_normalize_util_1.FAM_ClaudeMemNormalize_Util.normalizeAll({
67
+ from: fam_claude_mem_source_type_enum_1.FAM_ClaudeMemSource_Type.exportJson,
68
+ observations: observations, summaries: summaries, prompts: prompts, sessions: sessions,
69
+ includePrompts: set.includePrompts,
70
+ });
71
+ normalized.warnings = [...warnings, ...normalized.warnings];
72
+ return normalized;
73
+ }
74
+ /** A fájl beolvasása UTF-8-ként; I/O-hiba → `FAM-IMP-SOURCE-001`. */
75
+ readFile(path) {
76
+ try {
77
+ return fs.readFileSync(path, 'utf-8');
78
+ }
79
+ catch (error) {
80
+ throw fam_error_factory_util_1.FAM_Error_Util.create({
81
+ errorCode: error_codes_const_1.FAM_ERROR_CODES.impSource,
82
+ message: `A claude-mem export-JSON fájl nem olvasható: '${path}'.`,
83
+ issuer: this.issuer,
84
+ context: { operation: 'import-read-export-json' },
85
+ cause: error,
86
+ });
87
+ }
88
+ }
89
+ /** A nyers szöveg parse-olása export-wrapper-ré; nem-JSON / nem-objektum → `FAM-IMP-SOURCE-001`. */
90
+ parseWrapper(rawText, path) {
91
+ let parsed;
92
+ try {
93
+ parsed = JSON.parse(rawText);
94
+ }
95
+ catch (error) {
96
+ throw fam_error_factory_util_1.FAM_Error_Util.create({
97
+ errorCode: error_codes_const_1.FAM_ERROR_CODES.impSource,
98
+ message: `A claude-mem export-JSON nem érvényes JSON: '${path}'.`,
99
+ issuer: this.issuer,
100
+ context: { operation: 'import-read-export-json' },
101
+ cause: error,
102
+ });
103
+ }
104
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
105
+ throw fam_error_factory_util_1.FAM_Error_Util.create({
106
+ errorCode: error_codes_const_1.FAM_ERROR_CODES.impSource,
107
+ message: `A claude-mem export-JSON gyökere nem objektum (várt: { observations[], sessions[], `
108
+ + `summaries[], prompts[] }): '${path}'.`,
109
+ issuer: this.issuer,
110
+ context: { operation: 'import-read-export-json' },
111
+ });
112
+ }
113
+ return parsed;
114
+ }
115
+ /** Egy mező tömbként; hiányzó/nem-tömb → warning + []. */
116
+ asArray(value, field, warnings) {
117
+ if (value === undefined || value === null) {
118
+ return [];
119
+ }
120
+ if (!Array.isArray(value)) {
121
+ warnings.push(`A '${field}' mező nem tömb az export-JSON-ban — üres listaként kezelve.`);
122
+ return [];
123
+ }
124
+ return value;
125
+ }
126
+ /** A deklarált total és a tényleges hossz eltérésének warning-ja (nem-néma drift-jelzés). */
127
+ checkDrift(declared, actual, field, warnings) {
128
+ if (typeof declared === 'number' && declared !== actual) {
129
+ warnings.push(`A '${field}' deklarált száma (${declared}) eltér a tényleges hossztól (${actual}) — `
130
+ + 'lehetséges export-drift.');
131
+ }
132
+ }
133
+ }
134
+ exports.FAM_ClaudeMemExportReader_Service = FAM_ClaudeMemExportReader_Service;