@futdevpro/fdp-agent-memory 0.1.0 → 1.1.12

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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -7
  3. package/build/package.json +6 -5
  4. package/build/src/_cli/_collections/fam-arg.util.js +48 -0
  5. package/build/src/_cli/_collections/fam-cli.const.js +40 -0
  6. package/build/src/_cli/_collections/fam-output.util.js +86 -0
  7. package/build/src/_cli/_collections/fam-project-discovery.util.js +98 -0
  8. package/build/src/_cli/_commands/capture.command.js +73 -0
  9. package/build/src/_cli/_commands/config.command.js +93 -0
  10. package/build/src/_cli/_commands/doctor.command.js +124 -0
  11. package/build/src/_cli/_commands/errors.command.js +66 -0
  12. package/build/src/_cli/_commands/export.command.js +65 -0
  13. package/build/src/_cli/_commands/find-duplicates.command.js +97 -0
  14. package/build/src/_cli/_commands/import.command.js +136 -0
  15. package/build/src/_cli/_commands/init.command.js +147 -0
  16. package/build/src/_cli/_commands/read.command.js +109 -0
  17. package/build/src/_cli/_commands/scan-projects.command.js +138 -0
  18. package/build/src/_cli/_commands/scan.command.js +98 -0
  19. package/build/src/_cli/_commands/seed.command.js +40 -0
  20. package/build/src/_cli/_commands/serve.command.js +350 -0
  21. package/build/src/_cli/_commands/start.command.js +134 -0
  22. package/build/src/_cli/_commands/stats.command.js +54 -0
  23. package/build/src/_cli/_commands/write.command.js +103 -0
  24. package/build/src/_cli/_models/interfaces/fam-cli-global-options.interface.js +2 -0
  25. package/build/src/_cli/_models/interfaces/fam-cli-output.interface.js +9 -0
  26. package/build/src/_cli/_models/interfaces/fam-client-result.interface.js +2 -0
  27. package/build/src/_cli/_services/fam-client.service.js +140 -0
  28. package/build/src/_cli/register-commands.js +86 -0
  29. package/build/src/_collections/config-catalog.const.js +67 -1
  30. package/build/src/_collections/fam-console.util.js +367 -0
  31. package/build/src/_collections/fam-entry-bootstrap.util.js +158 -4
  32. package/build/src/_collections/fam-error-factory.util.js +0 -9
  33. package/build/src/_collections/fam-mcp-bridge.util.js +49 -0
  34. package/build/src/_collections/fam-reference-code.util.js +105 -0
  35. package/build/src/_collections/fam-version.const.js +10 -0
  36. package/build/src/_models/data-models/fam-entry-base-properties.const.js +1 -0
  37. package/build/src/_models/data-models/fam-entry.data-model.js +6 -0
  38. package/build/src/_models/data-models/fam-ingest-run.data-model.js +3 -1
  39. package/build/src/_models/data-models/fam-reference.data-model.js +7 -0
  40. package/build/src/_modules/capture/_collections/fam-capture.const.js +11 -0
  41. package/build/src/_modules/capture/_services/fam-auto-capture.control-service.js +87 -0
  42. package/build/src/_modules/capture/index.js +8 -0
  43. package/build/src/_modules/embedding/_collections/fam-embedding-prefix.util.js +77 -0
  44. package/build/src/_modules/embedding/_services/fam-duplicate-scan.control-service.js +202 -0
  45. package/build/src/_modules/embedding/_services/fam-embedding-pipeline.control-service.js +33 -9
  46. package/build/src/_modules/embedding/_services/fam-embedding.control-service.js +21 -2
  47. package/build/src/_modules/embedding/_services/fam-entry.data-service.js +135 -0
  48. package/build/src/_modules/embedding/_services/fam-vector-search.control-service.js +42 -32
  49. package/build/src/_modules/embedding/index.js +4 -1
  50. package/build/src/_modules/export/_collections/fam-export.const.js +22 -0
  51. package/build/src/_modules/export/_services/fam-export.control-service.js +64 -0
  52. package/build/src/_modules/export/index.js +8 -0
  53. package/build/src/_modules/ingest/_collections/fam-famignore.util.js +83 -0
  54. package/build/src/_modules/ingest/_collections/fam-file-routing.util.js +59 -48
  55. package/build/src/_modules/ingest/_collections/fam-project-identity.util.js +134 -0
  56. package/build/src/_modules/ingest/_collections/fam-scan-progress.util.js +57 -0
  57. package/build/src/_modules/ingest/_collections/fam-scan-summary.util.js +60 -0
  58. package/build/src/_modules/ingest/_collections/fam-scan-weight.util.js +53 -0
  59. package/build/src/_modules/ingest/_collections/fam-secret-exclude.util.js +37 -14
  60. package/build/src/_modules/ingest/_collections/fam-sliding-chunker.util.js +34 -0
  61. package/build/src/_modules/ingest/_collections/fam-ts-chunker.util.js +200 -14
  62. package/build/src/_modules/ingest/_services/fam-delta-compare.util.js +4 -1
  63. package/build/src/_modules/ingest/_services/fam-ingest-run.data-service.js +7 -4
  64. package/build/src/_modules/ingest/_services/fam-ingest.control-service.js +346 -17
  65. package/build/src/_modules/ingest/_services/fam-scan.control-service.js +25 -2
  66. package/build/src/_modules/ingest/index.js +3 -1
  67. package/build/src/_modules/mcp/_collections/fam-active-rules.util.js +56 -0
  68. package/build/src/_modules/mcp/_collections/fam-core-tools.const.js +47 -6
  69. package/build/src/_modules/mcp/_services/fam-capabilities-tool.service.js +4 -4
  70. package/build/src/_modules/mcp/_services/fam-capability-registry.service.js +224 -18
  71. package/build/src/_modules/mcp/_services/fam-mcp-adapter.service.js +4 -4
  72. package/build/src/_modules/mcp/_services/fam-mcp-server.service.js +4 -4
  73. package/build/src/_modules/mcp/_services/fam-read-tool.service.js +53 -1
  74. package/build/src/_modules/mcp/_services/fam-write-tool.service.js +104 -8
  75. package/build/src/_modules/mcp/index.js +4 -4
  76. package/build/src/_modules/migration/_collections/fam-claude-mem-normalize.util.js +66 -3
  77. package/build/src/_modules/migration/_collections/fam-prompt-aggregate.util.js +143 -0
  78. package/build/src/_modules/migration/_collections/fam-target-mapping.util.js +19 -0
  79. package/build/src/_modules/migration/_enums/fam-claude-mem-source.type-enum.js +6 -0
  80. package/build/src/_modules/migration/_models/interfaces/fam-claude-mem.interface.js +5 -0
  81. package/build/src/_modules/migration/_services/fam-agent-memory-reader.service.js +125 -0
  82. package/build/src/_modules/migration/_services/fam-claude-mem-import.control-service.js +101 -18
  83. package/build/src/_modules/migration/_services/fam-import-dedup.data-service.js +53 -0
  84. package/build/src/_modules/migration/index.js +3 -1
  85. package/build/src/_modules/retrieval/_services/fam-retrieval-candidate.data-service.js +78 -4
  86. package/build/src/_modules/retrieval/_services/fam-retrieval.control-service.js +293 -50
  87. package/build/src/_modules/scope-reference/_collections/fam-scope-normalize.util.js +6 -3
  88. package/build/src/_modules/scope-reference/_services/fam-reference.data-service.js +18 -0
  89. package/build/src/_modules/scope-reference/_services/fam-scope-resolver.control-service.js +79 -20
  90. package/build/src/_routes/server/api/api.controller.js +34 -2
  91. package/build/src/_routes/server/client-app/client-app.control-service.js +1 -1
  92. package/build/src/_routes/server/server-status/server-status.controller.js +2 -1
  93. package/build/src/app.server.js +13 -1
  94. package/build/src/environments/environment.js +1 -1
  95. package/build/src/index.js +1 -1
  96. package/client-dist/{chunk-GHKRM4SM.js → chunk-I77GXVAQ.js} +1 -1
  97. package/client-dist/{chunk-LMTL7GA3.js → chunk-YXHWCJ5O.js} +1 -1
  98. package/client-dist/index.html +1 -1
  99. package/client-dist/{main-2KWB3QYK.js → main-PJPEDVJT.js} +1 -1
  100. package/package.json +6 -5
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_Errors_Util = void 0;
4
+ const commander_1 = require("commander");
5
+ const fam_output_util_1 = require("../_collections/fam-output.util");
6
+ const fam_client_service_1 = require("../_services/fam-client.service");
7
+ const fam_cli_const_1 = require("../_collections/fam-cli.const");
8
+ /**
9
+ * `fam errors` — a persistált `FAM_Error` rekordok CLI-tükre (dsgn-010 §11.3, dsgn-008). `--list`
10
+ * (default akció) a `GET /server/errors`-t hívja (`--level`/`--limit` szűréssel); `--mark-done <id>` a
11
+ * `POST /server/errors/mark-handled/:id`-t (occurrence-count + dedup megmarad). A `--limit` kliens-oldalon
12
+ * vág (a server a teljes szűrt listát adja).
13
+ */
14
+ class FAM_Errors_Util {
15
+ /** Az `errors` parancs-deszkriptor. */
16
+ static command() {
17
+ const command = new commander_1.Command('errors');
18
+ command
19
+ .description('Persistált FAM hibák listázása / kezeltnek jelölése (dsgn-008)')
20
+ .option('--list', 'hiba-lista (default akció)', false)
21
+ .option('--level <level>', 'debug|info|warn|error|critical szűrő')
22
+ .option('--limit <N>', 'lista-limit (kliens-oldali vágás)')
23
+ .option('--mark-done <id>', 'egy hiba "kezelve" jelölése')
24
+ .action(async () => {
25
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Errors_Util.run(command));
26
+ });
27
+ return command;
28
+ }
29
+ /** Az `errors` futtatása: mark-done VAGY list. */
30
+ static async run(command) {
31
+ const globals = command.optsWithGlobals();
32
+ const local = command.opts();
33
+ const client = new fam_client_service_1.FAM_CliClient_Service(globals.serverUrl);
34
+ if (local.markDone) {
35
+ const markResult = await client.post(`/server/errors/mark-handled/${encodeURIComponent(local.markDone)}`, {});
36
+ if (!markResult.ok) {
37
+ return FAM_Errors_Util.fail(globals, markResult, 'FAM-CLI-ERRORS-002');
38
+ }
39
+ return fam_output_util_1.FAM_Output_Util.success({
40
+ options: globals,
41
+ command: 'errors',
42
+ data: { markedHandled: local.markDone },
43
+ });
44
+ }
45
+ // Default: list (a `--list` opcionális — a mark-done hiányában is listázunk).
46
+ const query = local.level ? `?level=${encodeURIComponent(local.level)}` : '';
47
+ const listResult = await client.get(`/server/errors${query}`);
48
+ if (!listResult.ok) {
49
+ return FAM_Errors_Util.fail(globals, listResult, 'FAM-CLI-ERRORS-001');
50
+ }
51
+ const all = listResult.data ?? [];
52
+ const limit = local.limit ? Number(local.limit) : undefined;
53
+ const errors = limit && limit > 0 ? all.slice(0, limit) : all;
54
+ return fam_output_util_1.FAM_Output_Util.success({ options: globals, command: 'errors', data: { errors: errors } });
55
+ }
56
+ /** Közös hiba-render (unreachable → 3, egyébként 1). */
57
+ static fail(globals, result, fallbackCode) {
58
+ return fam_output_util_1.FAM_Output_Util.failure({
59
+ options: globals,
60
+ command: 'errors',
61
+ error: result.error ?? { errorCode: fallbackCode, message: 'Ismeretlen errors-hiba.' },
62
+ exitCode: result.unreachable ? fam_cli_const_1.FAM_CliExitCode.serverUnreachable : fam_cli_const_1.FAM_CliExitCode.operationError,
63
+ });
64
+ }
65
+ }
66
+ exports.FAM_Errors_Util = FAM_Errors_Util;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_Export_Util = void 0;
4
+ const commander_1 = require("commander");
5
+ const fs_1 = require("fs");
6
+ const fam_output_util_1 = require("../_collections/fam-output.util");
7
+ const fam_client_service_1 = require("../_services/fam-client.service");
8
+ const fam_cli_const_1 = require("../_collections/fam-cli.const");
9
+ /**
10
+ * `fam export` — FEAT-007 thin-wrapper: a **non-file-derived** (kézzel/agent-írt, `source.type ∈ {manual, agent}`)
11
+ * bejegyzések biztonsági mentése. Ezeket re-scan NEM regenerálja → pótolhatatlan kurált érték. A szerver
12
+ * `export_authored` capability-jére delegál (NINCS export-logika a CLI-ben), és `--out` esetén JSON-fájlba írja
13
+ * (egyébként a standard success-outputon adja vissza). A `contentVector` kimarad (re-embeddel regenerálható).
14
+ */
15
+ class FAM_Export_Util {
16
+ /** Az `export` parancs-deszkriptor. */
17
+ static command() {
18
+ const command = new commander_1.Command('export');
19
+ command
20
+ .description('A non-file-derived (kézzel/agent-írt) bejegyzések biztonsági mentése JSON-ba (FEAT-007)')
21
+ .option('--out <file>', 'cél JSON-fájl útvonala (alapból: a standard outputon adja vissza)')
22
+ .action(async () => {
23
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Export_Util.run(command));
24
+ });
25
+ return command;
26
+ }
27
+ /** A flow: az `export_authored` capability invoke → opcionális fájl-írás → render. */
28
+ static async run(command) {
29
+ const globals = command.optsWithGlobals();
30
+ const local = command.opts();
31
+ const client = new fam_client_service_1.FAM_CliClient_Service(globals.serverUrl);
32
+ const result = await client.post('/api/capabilities', {
33
+ action: 'invoke',
34
+ name: 'export_authored',
35
+ arguments: {},
36
+ });
37
+ if (!result.ok) {
38
+ return fam_output_util_1.FAM_Output_Util.failure({
39
+ options: globals,
40
+ command: 'export',
41
+ error: result.error ?? { errorCode: 'FAM-CLI-EXPORT-002', message: 'Ismeretlen export-hiba.' },
42
+ exitCode: result.unreachable ? fam_cli_const_1.FAM_CliExitCode.serverUnreachable : fam_cli_const_1.FAM_CliExitCode.operationError,
43
+ });
44
+ }
45
+ if (local.out) {
46
+ try {
47
+ (0, fs_1.writeFileSync)(local.out, JSON.stringify(result.data, null, 2), 'utf8');
48
+ fam_output_util_1.FAM_Output_Util.logInfo(globals, `Authored backup kiírva: ${local.out}`);
49
+ }
50
+ catch (error) {
51
+ return fam_output_util_1.FAM_Output_Util.failure({
52
+ options: globals,
53
+ command: 'export',
54
+ error: {
55
+ errorCode: 'FAM-CLI-EXPORT-001',
56
+ message: `A backup-fájl írása sikertelen: ${error.message}`,
57
+ fixHint: 'Ellenőrizd az --out útvonal írhatóságát (mappa létezik, van jogosultság).',
58
+ },
59
+ });
60
+ }
61
+ }
62
+ return fam_output_util_1.FAM_Output_Util.success({ options: globals, command: 'export', data: result.data });
63
+ }
64
+ }
65
+ exports.FAM_Export_Util = FAM_Export_Util;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_FindDuplicates_Util = void 0;
4
+ const commander_1 = require("commander");
5
+ const fam_output_util_1 = require("../_collections/fam-output.util");
6
+ const fam_client_service_1 = require("../_services/fam-client.service");
7
+ const fam_cli_const_1 = require("../_collections/fam-cli.const");
8
+ /**
9
+ * `fam find-duplicates --table <t>` — near-duplikátum / multiplikáció FELDERÍTŐ (read-only; user-direktíva
10
+ * 2026-06-21). Egy tár vektor-pool-jában megkeresi a NAGYON HASONLÓ (koszinusz ≥ `--threshold`) entry-ket és
11
+ * cluster-ekbe vonja — **NEM töröl**, csak megmutatja az ismétlődéseket (a user dönt). A `GET /api/duplicates/:table`
12
+ * REST-tükre. `--threshold` (0..1, default 0.95), `--neighbors`, `--max-entries` (O(n²)-cap), `--max-clusters`.
13
+ */
14
+ class FAM_FindDuplicates_Util {
15
+ /** A `find-duplicates` parancs-deszkriptor. */
16
+ static command() {
17
+ const command = new commander_1.Command('find-duplicates');
18
+ command
19
+ .description('Near-duplikátum / multiplikáció felderítés egy tárban (koszinusz-cluster, NEM töröl)')
20
+ .requiredOption('--table <table>', 'a vizsgált tár (rules/documents/codebase/knowledge/coding_patterns/memory)')
21
+ .option('--threshold <n>', 'koszinusz-küszöb 0..1 (default 0.95)')
22
+ .option('--neighbors <n>', 'szomszéd-szám/entry (default 10)')
23
+ .option('--max-entries <n>', 'entry-cap az O(n²) ellen (default 3000; a capped jelzi, ha több)')
24
+ .option('--max-clusters <n>', 'a visszaadott cluster-ek max száma (default 100)')
25
+ .action(async () => {
26
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_FindDuplicates_Util.run(command));
27
+ });
28
+ return command;
29
+ }
30
+ /** A `find-duplicates` futtatása: a REST `/api/duplicates/:table` query-paraméterekkel. */
31
+ static async run(command) {
32
+ const globals = command.optsWithGlobals();
33
+ const local = command.opts();
34
+ const client = new fam_client_service_1.FAM_CliClient_Service(globals.serverUrl);
35
+ const query = FAM_FindDuplicates_Util.buildQuery({
36
+ threshold: local.threshold,
37
+ neighbors: local.neighbors,
38
+ maxEntries: local.maxEntries,
39
+ maxClusters: local.maxClusters,
40
+ });
41
+ const path = `/api/duplicates/${encodeURIComponent(local.table)}${query}`;
42
+ const result = await client.get(path);
43
+ if (!result.ok) {
44
+ return fam_output_util_1.FAM_Output_Util.failure({
45
+ options: globals,
46
+ command: 'find-duplicates',
47
+ error: result.error ?? { errorCode: 'FAM-CLI-DUP-001', message: 'Ismeretlen duplikátum-scan hiba.' },
48
+ exitCode: result.unreachable ? fam_cli_const_1.FAM_CliExitCode.serverUnreachable : fam_cli_const_1.FAM_CliExitCode.operationError,
49
+ });
50
+ }
51
+ return fam_output_util_1.FAM_Output_Util.success({
52
+ options: globals,
53
+ command: 'find-duplicates',
54
+ data: result.data,
55
+ humanFormatter: (data) => FAM_FindDuplicates_Util.format(data),
56
+ });
57
+ }
58
+ /** A query-string összeállítása a megadott (definiált) opciókból. */
59
+ static buildQuery(options) {
60
+ const parts = [];
61
+ if (options.threshold !== undefined) {
62
+ parts.push(`threshold=${encodeURIComponent(options.threshold)}`);
63
+ }
64
+ if (options.neighbors !== undefined) {
65
+ parts.push(`neighbors=${encodeURIComponent(options.neighbors)}`);
66
+ }
67
+ if (options.maxEntries !== undefined) {
68
+ parts.push(`maxEntries=${encodeURIComponent(options.maxEntries)}`);
69
+ }
70
+ if (options.maxClusters !== undefined) {
71
+ parts.push(`maxClusters=${encodeURIComponent(options.maxClusters)}`);
72
+ }
73
+ return parts.length ? `?${parts.join('&')}` : '';
74
+ }
75
+ /** Ember-olvasható összegzés: scan-fejléc (+ capped-figyelmeztetés) + a top cluster-ek tagokkal. */
76
+ static format(report) {
77
+ const lines = [];
78
+ lines.push(`Near-duplikátum scan — '${report.table}' (küszöb ${report.threshold}):`);
79
+ lines.push(` vizsgált ${report.scanned} / ${report.totalInPool} entry`
80
+ + `${report.capped ? ' ⚠ CAPPED (a tár nagyobb — emeld a --max-entries-t a teljes scan-hez)' : ''}`);
81
+ lines.push(` ${report.clusterCount} duplikátum-cluster, összesen ${report.duplicateEntryCount} érintett entry`);
82
+ if (!report.clusterCount) {
83
+ lines.push(' ✓ nincs a küszöb feletti near-duplikátum.');
84
+ return lines.join('\n');
85
+ }
86
+ for (const [index, cluster] of report.clusters.entries()) {
87
+ lines.push('');
88
+ lines.push(` #${index + 1} — ${cluster.size} elem (score ${cluster.minScore.toFixed(3)}…${cluster.maxScore.toFixed(3)}):`);
89
+ for (const member of cluster.members) {
90
+ const snippet = member.snippet ? `: ${member.snippet}` : '';
91
+ lines.push(` • [${member.id}]${member.kind ? ` (${member.kind})` : ''}${snippet}`);
92
+ }
93
+ }
94
+ return lines.join('\n');
95
+ }
96
+ }
97
+ exports.FAM_FindDuplicates_Util = FAM_FindDuplicates_Util;
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_Import_Util = void 0;
4
+ const commander_1 = require("commander");
5
+ const fam_output_util_1 = require("../_collections/fam-output.util");
6
+ const fam_client_service_1 = require("../_services/fam-client.service");
7
+ const fam_cli_const_1 = require("../_collections/fam-cli.const");
8
+ /**
9
+ * `fam import claude-mem` — a claude-mem migráció CLI thin-wrapper-e (dsgn-010 §8, dsgn-009). EGYIRÁNYÚ
10
+ * (claude-mem → FAM; visszaimport nincs, REQ-012). Az MP-11 import-katalógusra delegál a
11
+ * `capabilities.invoke`-on át — NINCS külön import-logika a CLI-ben (a dedup/target-mapping/rollback
12
+ * MP-11/dsgn-009 SSOT). **Preview-first**: alap esetben preview, `--yes` átugorja a megerősítést.
13
+ *
14
+ * > Az import-engine MP-11; addig a `capabilities.invoke` clear "pending MP-11" hibát adhat runtime-ban
15
+ * > (nem néma, nem crash) — a CLI a REST-kontraktusra COMPILE-ol, függetlenül az engine-állapottól.
16
+ *
17
+ * A `migrate` setup-alias erre delegál (dsgn-010 §10).
18
+ */
19
+ class FAM_Import_Util {
20
+ /** Az `import` parancs-deszkriptor (claude-mem + agent-memory alparancsokkal). */
21
+ static command() {
22
+ const command = new commander_1.Command('import');
23
+ command.description('Migráció FAM-ba (claude-mem / agent-memory; egyirányú, dsgn-009)');
24
+ command.addCommand(FAM_Import_Util.claudeMemCommand('claude-mem'));
25
+ command.addCommand(FAM_Import_Util.agentMemoryCommand('agent-memory'));
26
+ return command;
27
+ }
28
+ /**
29
+ * A `agent-memory` parancs: az agent (Claude) tartós memóriájának (`.claude/.../memory/*.md`) importja.
30
+ * UGYANAZ az engine (preview/run/rollback/dedup/embed), mint a claude-mem-é — csak a `from` rögzített
31
+ * (`agent-memory`), és a `--path` a memória-mappára mutat. Preview-first; `--yes` átugorja a megerősítést.
32
+ */
33
+ static agentMemoryCommand(commandName) {
34
+ const command = new commander_1.Command(commandName);
35
+ command
36
+ .description('agent-memory import (.claude/.../memory/*.md), preview-first')
37
+ .requiredOption('--path <dir>', 'a memória-mappa (frontmatter-es *.md fájlok)')
38
+ .option('--preview', 'csak preview (dedup + target-mapping); nem ír', false)
39
+ .option('--yes', 'preview-megerősítés átugrása (non-interactive)', false)
40
+ .option('--rollback <batchId>', 'egy import-batch visszavonása')
41
+ .action(async () => {
42
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Import_Util.run(command, 'agent-memory'));
43
+ });
44
+ return command;
45
+ }
46
+ /** A `migrate` delegáló alias (dsgn-010 §10) — az `import claude-mem` flow-ra fut. */
47
+ static aliasCommand(aliasName) {
48
+ return FAM_Import_Util.claudeMemCommand(aliasName);
49
+ }
50
+ /** A `claude-mem` (vagy az alias) parancs-fa: a preview/run/rollback flag-keret. */
51
+ static claudeMemCommand(commandName) {
52
+ const command = new commander_1.Command(commandName);
53
+ command
54
+ .description('claude-mem migráció (sqlite|export-json|worker-api), preview-first')
55
+ .option('--from <sqlite|export-json|worker-api>', 'forrás-csatorna')
56
+ .option('--path <db|json>', 'SQLite/export-JSON útvonal')
57
+ .option('--url <workerUrl>', 'live worker base URL (worker-api)')
58
+ .option('--preview', 'csak preview (dedup + target-mapping); nem ír', false)
59
+ .option('--yes', 'preview-megerősítés átugrása (non-interactive)', false)
60
+ .option('--rollback <batchId>', 'egy import-batch visszavonása')
61
+ .action(async () => {
62
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Import_Util.run(command));
63
+ });
64
+ return command;
65
+ }
66
+ /**
67
+ * A flow: rollback VAGY preview VAGY (preview→megerősítés→) run — a server capability-jeire delegálva.
68
+ * A `forcedFrom` (ha megadva, pl. az `agent-memory` subcommand) felülírja a `--from`-ot — a hívó nem
69
+ * adhat más csatornát.
70
+ */
71
+ static async run(command, forcedFrom) {
72
+ const globals = command.optsWithGlobals();
73
+ const local = command.opts();
74
+ const from = forcedFrom ?? local.from;
75
+ const client = new fam_client_service_1.FAM_CliClient_Service(globals.serverUrl);
76
+ // 1) Rollback (a többi flaget figyelmen kívül hagyja).
77
+ if (local.rollback) {
78
+ const rollbackResult = await client.post('/api/capabilities', {
79
+ action: 'invoke',
80
+ name: 'rollback_import',
81
+ arguments: { batchId: local.rollback },
82
+ });
83
+ return FAM_Import_Util.render(globals, 'import rollback', rollbackResult);
84
+ }
85
+ if (!from) {
86
+ return fam_output_util_1.FAM_Output_Util.failure({
87
+ options: globals,
88
+ command: 'import',
89
+ error: {
90
+ errorCode: 'FAM-CLI-IMPORT-001',
91
+ message: 'A --from kötelező (sqlite|export-json|worker-api), vagy adj --rollback <batchId>-t.',
92
+ fixHint: 'Pl.: fam import claude-mem --from export-json --path ./export.json --preview',
93
+ },
94
+ });
95
+ }
96
+ const importArgs = {
97
+ source: 'claude-mem',
98
+ from: from,
99
+ path: local.path,
100
+ url: local.url,
101
+ };
102
+ // 2) Preview (mindig fut a run előtt; a `--yes` nélkül itt megáll).
103
+ const previewResult = await client.post('/api/capabilities', {
104
+ action: 'invoke',
105
+ name: 'preview_claude_mem_import',
106
+ arguments: importArgs,
107
+ });
108
+ if (!previewResult.ok || local.preview || !local.yes) {
109
+ // preview-only VAGY hiba VAGY nincs --yes → itt megállunk (idempotens, nem ír).
110
+ if (previewResult.ok && !local.preview && !local.yes) {
111
+ fam_output_util_1.FAM_Output_Util.logInfo(globals, 'Preview kész. Az íráshoz add hozzá a --yes flaget.');
112
+ }
113
+ return FAM_Import_Util.render(globals, 'import preview', previewResult);
114
+ }
115
+ // 3) Run (csak --yes esetén, preview után).
116
+ const runResult = await client.post('/api/capabilities', {
117
+ action: 'invoke',
118
+ name: 'import_claude_mem',
119
+ arguments: importArgs,
120
+ });
121
+ return FAM_Import_Util.render(globals, 'import', runResult);
122
+ }
123
+ /** Közös render (unreachable → 3, egyébként 1/0). */
124
+ static render(globals, commandLabel, result) {
125
+ if (!result.ok) {
126
+ return fam_output_util_1.FAM_Output_Util.failure({
127
+ options: globals,
128
+ command: commandLabel,
129
+ error: result.error ?? { errorCode: 'FAM-CLI-IMPORT-002', message: 'Ismeretlen import-hiba.' },
130
+ exitCode: result.unreachable ? fam_cli_const_1.FAM_CliExitCode.serverUnreachable : fam_cli_const_1.FAM_CliExitCode.operationError,
131
+ });
132
+ }
133
+ return fam_output_util_1.FAM_Output_Util.success({ options: globals, command: commandLabel, data: result.data });
134
+ }
135
+ }
136
+ exports.FAM_Import_Util = FAM_Import_Util;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_Init_Util = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const commander_1 = require("commander");
7
+ const fam_output_util_1 = require("../_collections/fam-output.util");
8
+ /** A default Mongo connection-string (dsgn-010 §4). */
9
+ const DEFAULT_MONGODB_URI = 'mongodb://0.0.0.0:29017/';
10
+ /** A default Mongo DB-név. */
11
+ const DEFAULT_DB_NAME = 'fdp_agent_memory';
12
+ /**
13
+ * `fam init` — config-scaffold (dsgn-010 §4). Egy működő lokális `.env`-váz előállítása (a hiányzó
14
+ * kulcsokkal), egy MCP-kliens config-snippet kiírása, és záró-tipp (`fam doctor`). A DB-backed config
15
+ * seed (a `fam_config` global rekordok) a futó szervert igényli — szerver/DB hiányában **env-only
16
+ * fallback + warning** (a tervezés nem áll meg; dsgn-010 §4 / MP-9-detailed).
17
+ *
18
+ * A `create-config` setup-alias ennek a config-scaffold lépésére delegál (dsgn-010 §10).
19
+ */
20
+ class FAM_Init_Util {
21
+ /** Az `init` parancs-deszkriptor. */
22
+ static command() {
23
+ const command = new commander_1.Command('init');
24
+ command
25
+ .description('Lokális config + .env váz scaffold (dsgn-010 §4)')
26
+ .option('--force', 'meglévő kulcsok felülírása', false)
27
+ .option('--mongodb-uri <uri>', `Mongo connection string (default ${DEFAULT_MONGODB_URI})`)
28
+ .option('--db-name <name>', `Mongo DB-név (default ${DEFAULT_DB_NAME})`)
29
+ .option('--embedding-provider <openai|lmstudio>', 'embedding-provider preset')
30
+ .option('--non-interactive', 'nincs prompt; csak flag/env/default', false)
31
+ .action(async () => {
32
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Init_Util.run(command));
33
+ });
34
+ return command;
35
+ }
36
+ /**
37
+ * A `create-config` delegáló alias (dsgn-010 §10) — ugyanazt a config-scaffold lépést futtatja, mint
38
+ * az `init`. Nincs külön logika (a `run`-ra delegál).
39
+ */
40
+ static configScaffoldAlias(aliasName) {
41
+ const command = new commander_1.Command(aliasName);
42
+ command
43
+ .description('(alias) a `fam init` config-scaffold lépése')
44
+ .option('--force', 'meglévő kulcsok felülírása', false)
45
+ .option('--mongodb-uri <uri>', 'Mongo connection string')
46
+ .option('--db-name <name>', 'Mongo DB-név')
47
+ .option('--embedding-provider <openai|lmstudio>', 'embedding-provider preset')
48
+ .action(async () => {
49
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Init_Util.run(command));
50
+ });
51
+ return command;
52
+ }
53
+ /** A scaffold futtatása: a `.env`-váz írása + MCP-snippet + záró-tipp. */
54
+ static async run(command) {
55
+ const globals = command.optsWithGlobals();
56
+ const local = command.opts();
57
+ const provider = local.embeddingProvider === 'lmstudio' ? 'lmstudio' : 'openai';
58
+ const desired = {
59
+ MONGODB_URI: local.mongodbUri ?? DEFAULT_MONGODB_URI,
60
+ MONGODB_DB_NAME: local.dbName ?? DEFAULT_DB_NAME,
61
+ EMBEDDING_PROVIDER: provider,
62
+ };
63
+ if (provider === 'openai') {
64
+ desired.OPENAI_API_KEY = '';
65
+ desired.OPENAI_EMBEDDING_MODEL = 'text-embedding-3-small';
66
+ }
67
+ else {
68
+ desired.LMSTUDIO_BASE_URL = 'http://localhost:1234/v1';
69
+ desired.LMSTUDIO_EMBEDDING_MODEL = 'text-embedding-nomic-embed-text-v1.5';
70
+ }
71
+ const envPath = (0, path_1.resolve)(process.cwd(), '.env');
72
+ const existing = FAM_Init_Util.readEnv(envPath);
73
+ const createdKeys = [];
74
+ for (const key of Object.keys(desired)) {
75
+ if (local.force || existing[key] === undefined) {
76
+ existing[key] = desired[key];
77
+ createdKeys.push(key);
78
+ }
79
+ }
80
+ try {
81
+ (0, fs_1.writeFileSync)(envPath, FAM_Init_Util.serializeEnv(existing), 'utf-8');
82
+ }
83
+ catch (writeError) {
84
+ return fam_output_util_1.FAM_Output_Util.failure({
85
+ options: globals,
86
+ command: 'init',
87
+ error: {
88
+ errorCode: 'FAM-CLI-INIT-001',
89
+ message: `A .env nem írható (${envPath}): ${writeError.message}.`,
90
+ },
91
+ });
92
+ }
93
+ const mcpClientSnippet = {
94
+ mcpServers: { 'fdp-agent-memory': { command: 'fam', args: ['start'] } },
95
+ };
96
+ const warnings = [
97
+ 'A DB-backed config-seed a futó szervert igényli — most env-only scaffold készült (env-only fallback).',
98
+ ];
99
+ return fam_output_util_1.FAM_Output_Util.success({
100
+ options: globals,
101
+ command: 'init',
102
+ warnings: warnings,
103
+ data: {
104
+ configFile: '.env',
105
+ createdKeys: createdKeys,
106
+ seededConfig: { scope: 'global', preset: `${provider}-recommended` },
107
+ mcpClientSnippet: mcpClientSnippet,
108
+ nextStep: 'fam doctor',
109
+ },
110
+ humanFormatter: (data) => FAM_Init_Util.formatHuman(data),
111
+ });
112
+ }
113
+ /** A meglévő `.env` beolvasása kulcs→érték térképbe (vagy üres, ha nincs). */
114
+ static readEnv(envPath) {
115
+ const map = {};
116
+ if (!(0, fs_1.existsSync)(envPath)) {
117
+ return map;
118
+ }
119
+ for (const line of (0, fs_1.readFileSync)(envPath, 'utf-8').split('\n')) {
120
+ const trimmed = line.trim();
121
+ if (!trimmed || trimmed.startsWith('#')) {
122
+ continue;
123
+ }
124
+ const eq = trimmed.indexOf('=');
125
+ if (eq < 0) {
126
+ continue;
127
+ }
128
+ map[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim();
129
+ }
130
+ return map;
131
+ }
132
+ /** A kulcs→érték térkép → `.env` szöveg. */
133
+ static serializeEnv(map) {
134
+ return `${Object.keys(map).map((key) => `${key}=${map[key]}`).join('\n')}\n`;
135
+ }
136
+ /** Ember-olvasható init-összefoglaló. */
137
+ static formatHuman(data) {
138
+ const typed = data;
139
+ const lines = [];
140
+ lines.push(`✓ .env scaffold kész (új kulcsok: ${(typed.createdKeys ?? []).join(', ') || '(nincs új)'}).`);
141
+ lines.push('\nMCP-kliens config-snippet (Claude Desktop/Code):');
142
+ lines.push(JSON.stringify(typed.mcpClientSnippet, null, 2));
143
+ lines.push(`\nKövetkező lépés: ${typed.nextStep ?? 'fam doctor'}`);
144
+ return lines.join('\n');
145
+ }
146
+ }
147
+ exports.FAM_Init_Util = FAM_Init_Util;
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_Read_Util = void 0;
4
+ const commander_1 = require("commander");
5
+ const fam_arg_util_1 = require("../_collections/fam-arg.util");
6
+ const fam_output_util_1 = require("../_collections/fam-output.util");
7
+ const fam_client_service_1 = require("../_services/fam-client.service");
8
+ const fam_cli_const_1 = require("../_collections/fam-cli.const");
9
+ /**
10
+ * `fam read` — a dsgn-003 §2 `read` MCP-tool / `POST /api/read` REST CLI-tükre (dsgn-010 §7.1). Egy
11
+ * hívásban **több** `--query` + `--tables` blokk (a két-query Béla-eset): minden `--tables` a megelőző
12
+ * `--query`-hez tartozik. A CLI csak flag→server-input map (nincs külön retrieval-logika).
13
+ */
14
+ class FAM_Read_Util {
15
+ /** A `read` parancs-deszkriptor (a `buildCli()`/`registerFAMCommands` adja a programhoz). */
16
+ static command() {
17
+ const command = new commander_1.Command('read');
18
+ command
19
+ .description('Multi-tábla + multi-query keresés (dsgn-003 §2 read REST-tükre)')
20
+ .option('-q, --query <phrase>', 'keresési phrase (ismételhető — minden query egy blokk)', fam_arg_util_1.FAM_Arg_Util.collect, [])
21
+ .option('-t, --tables <t1,t2>', 'a megelőző --query 1+ fő tára (ismételhető)', fam_arg_util_1.FAM_Arg_Util.collect, [])
22
+ .option('--top-k <N>', `találat-limit query-nként (default ${fam_cli_const_1.FAM_DEFAULT_TOP_K})`)
23
+ .option('--scope <layer=name,...>', 'opcionális subtree-scope prefilter')
24
+ .option('--tags <tag,...>', 'tag-szűrő')
25
+ .option('--kind <kind>', 'kind-szűrő')
26
+ .option('--min-score <f>', 'minimum-score küszöb')
27
+ .option('--no-content', 'kompakt lista (id+score+source), includeContent:false')
28
+ .action(async () => {
29
+ fam_output_util_1.FAM_Output_Util.exit(await FAM_Read_Util.run(command));
30
+ });
31
+ return command;
32
+ }
33
+ /** A `read` futtatása: a `--query`/`--tables` blokkok → `POST /api/read` input. */
34
+ static async run(command) {
35
+ const globals = command.optsWithGlobals();
36
+ const local = command.opts();
37
+ if (!local.query.length) {
38
+ return fam_output_util_1.FAM_Output_Util.failure({
39
+ options: globals,
40
+ command: 'read',
41
+ error: {
42
+ errorCode: 'FAM-CLI-READ-001',
43
+ message: 'Legalább egy --query kötelező.',
44
+ fixHint: 'Pl.: fam read --query "ki az a Béla" --tables memory',
45
+ },
46
+ });
47
+ }
48
+ if (local.tables.length !== local.query.length) {
49
+ return fam_output_util_1.FAM_Output_Util.failure({
50
+ options: globals,
51
+ command: 'read',
52
+ error: {
53
+ errorCode: 'FAM-CLI-READ-002',
54
+ message: `Minden --query-hez pontosan egy --tables kell (${local.query.length} query / ${local.tables.length} tables).`,
55
+ fixHint: 'Add meg a --tables-t minden --query után (a `reference` tár NEM adható meg).',
56
+ },
57
+ });
58
+ }
59
+ const topK = local.topK ? Number(local.topK) : undefined;
60
+ const minScore = local.minScore ? Number(local.minScore) : undefined;
61
+ const queries = local.query.map((phrase, index) => ({
62
+ query: phrase,
63
+ tables: fam_arg_util_1.FAM_Arg_Util.parseList(local.tables[index]) ?? [],
64
+ topK: topK,
65
+ minScore: minScore,
66
+ scopeFilter: fam_arg_util_1.FAM_Arg_Util.parseScope(local.scope),
67
+ tagFilter: fam_arg_util_1.FAM_Arg_Util.parseList(local.tags),
68
+ kindFilter: local.kind,
69
+ }));
70
+ const body = { queries: queries, includeContent: local.content !== false };
71
+ const client = new fam_client_service_1.FAM_CliClient_Service(globals.serverUrl);
72
+ const result = await client.post('/api/read', body);
73
+ return FAM_Read_Util.render(globals, result);
74
+ }
75
+ /** A server-választ → CLI-kimenet (siker/hiba/unreachable → 0/1/3). */
76
+ static render(globals, result) {
77
+ if (!result.ok) {
78
+ return fam_output_util_1.FAM_Output_Util.failure({
79
+ options: globals,
80
+ command: 'read',
81
+ error: result.error ?? { errorCode: 'FAM-CLI-READ-003', message: 'Ismeretlen read-hiba.' },
82
+ exitCode: result.unreachable ? fam_cli_const_1.FAM_CliExitCode.serverUnreachable : fam_cli_const_1.FAM_CliExitCode.operationError,
83
+ });
84
+ }
85
+ return fam_output_util_1.FAM_Output_Util.success({
86
+ options: globals,
87
+ command: 'read',
88
+ data: result.data,
89
+ humanFormatter: (data) => FAM_Read_Util.formatHuman(data),
90
+ });
91
+ }
92
+ /** Ember-olvasható read-kimenet: query-nként a hits + a dense-jelzés kötelező kiemelése (REQ-007). */
93
+ static formatHuman(data) {
94
+ const results = data.results ?? [];
95
+ const lines = [];
96
+ for (const block of results) {
97
+ lines.push(`\n● "${block.query ?? ''}" [${(block.tables ?? []).join(', ')}] (${block.totalRelevant ?? block.hits?.length ?? 0} relevant)`);
98
+ if (block.denseResults) {
99
+ lines.push(` ⚑ DENSE RESULTS — szűkítsd: ${(block.suggestions ?? []).join(' | ') || '(adj scope-ot/tag-et)'}`);
100
+ }
101
+ for (const hit of block.hits ?? []) {
102
+ const preview = (hit.content ?? '').replace(/\s+/g, ' ').slice(0, 100);
103
+ lines.push(` - [${(hit.score ?? 0).toFixed(3)}] ${hit.id ?? ''} ${preview}`);
104
+ }
105
+ }
106
+ return lines.join('\n');
107
+ }
108
+ }
109
+ exports.FAM_Read_Util = FAM_Read_Util;