@shahmilsaari/memory-core 1.0.29 → 1.0.31

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.
@@ -71,6 +71,22 @@ async function runMigrations() {
71
71
  WHERE content_hash IS NULL`
72
72
  );
73
73
  await client.query(`CREATE INDEX IF NOT EXISTS memories_content_hash_idx ON memories (content_hash)`);
74
+ await client.query(`
75
+ CREATE TABLE IF NOT EXISTS arch_profiles (
76
+ id SERIAL PRIMARY KEY,
77
+ name TEXT NOT NULL,
78
+ arch_type TEXT NOT NULL DEFAULT 'custom',
79
+ layers JSONB NOT NULL DEFAULT '[]',
80
+ rules JSONB NOT NULL DEFAULT '[]',
81
+ project_name TEXT,
82
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
83
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
84
+ )
85
+ `);
86
+ await client.query(`
87
+ CREATE UNIQUE INDEX IF NOT EXISTS arch_profiles_name_project_idx
88
+ ON arch_profiles (name, COALESCE(project_name, ''))
89
+ `);
74
90
  await client.query("COMMIT");
75
91
  migrationsRun = true;
76
92
  } catch (err) {
@@ -80,6 +96,38 @@ async function runMigrations() {
80
96
  client.release();
81
97
  }
82
98
  }
99
+ async function saveArchProfile(input) {
100
+ await runMigrations();
101
+ const result = await getPool().query(
102
+ `INSERT INTO arch_profiles (name, arch_type, layers, rules, project_name)
103
+ VALUES ($1, $2, $3::jsonb, $4::jsonb, $5)
104
+ ON CONFLICT (name, COALESCE(project_name, ''))
105
+ DO UPDATE SET arch_type = EXCLUDED.arch_type, layers = EXCLUDED.layers, rules = EXCLUDED.rules, updated_at = NOW()
106
+ RETURNING *`,
107
+ [input.name, input.archType, JSON.stringify(input.layers), JSON.stringify(input.rules), input.projectName ?? null]
108
+ );
109
+ return result.rows[0];
110
+ }
111
+ async function listArchProfiles(projectName) {
112
+ await runMigrations();
113
+ const result = await getPool().query(
114
+ `SELECT * FROM arch_profiles
115
+ WHERE project_name IS NULL OR project_name = $1
116
+ ORDER BY updated_at DESC`,
117
+ [projectName ?? null]
118
+ );
119
+ return result.rows;
120
+ }
121
+ async function getArchProfile(id) {
122
+ await runMigrations();
123
+ const result = await getPool().query(`SELECT * FROM arch_profiles WHERE id = $1`, [id]);
124
+ return result.rows[0] ?? null;
125
+ }
126
+ async function deleteArchProfile(id) {
127
+ await runMigrations();
128
+ const result = await getPool().query(`DELETE FROM arch_profiles WHERE id = $1`, [id]);
129
+ return (result.rowCount ?? 0) > 0;
130
+ }
83
131
  async function saveMemory(memory) {
84
132
  await runMigrations();
85
133
  const { type, scope, architecture, projectName, title, content, reason, context, tags, embedding } = memory;
@@ -289,6 +337,10 @@ export {
289
337
  hashMemoryContent,
290
338
  getPool,
291
339
  runMigrations,
340
+ saveArchProfile,
341
+ listArchProfiles,
342
+ getArchProfile,
343
+ deleteArchProfile,
292
344
  saveMemory,
293
345
  upsertMemory,
294
346
  listMemories,
@@ -14,7 +14,7 @@ import {
14
14
  searchMemories,
15
15
  updateMemory,
16
16
  upsertMemory
17
- } from "./chunk-M7NKSXFS.js";
17
+ } from "./chunk-4ZSVQMI7.js";
18
18
  import {
19
19
  buildModuleDependencyEdges,
20
20
  collectResolvedImports,
@@ -23,6 +23,238 @@ import {
23
23
  parseChangedFilesFromDiff
24
24
  } from "./chunk-ZZBQEXEO.js";
25
25
 
26
+ // src/arch-profiles.ts
27
+ function buildLayersTemplate(arch) {
28
+ switch (arch) {
29
+ case "nestjs":
30
+ return {
31
+ layers: [
32
+ { name: "modules", paths: ["src/modules/**"], description: "Feature modules \u2014 each owns its controller, service, DTOs, entities" },
33
+ { name: "controllers", paths: ["src/modules/*/controllers/**", "src/modules/*.controller.ts"], description: "HTTP request handlers \u2014 thin, delegate to services" },
34
+ { name: "services", paths: ["src/modules/*/services/**", "src/modules/*.service.ts"], description: "Business logic \u2014 never import controllers or HTTP classes" },
35
+ { name: "repositories", paths: ["src/modules/*/repositories/**"], description: "Data access \u2014 services depend on these interfaces" },
36
+ { name: "common", paths: ["src/common/**", "src/guards/**", "src/filters/**", "src/interceptors/**", "src/pipes/**"], description: "Guards, filters, interceptors, pipes" }
37
+ ]
38
+ };
39
+ case "mvc":
40
+ return {
41
+ layers: [
42
+ { name: "models", paths: ["src/models/**", "app/models/**"], description: "Data models \u2014 represent DB records" },
43
+ { name: "controllers", paths: ["src/controllers/**", "app/controllers/**"], description: "Route handlers \u2014 thin, delegate to services" },
44
+ { name: "services", paths: ["src/services/**", "app/services/**"], description: "Business logic \u2014 called by controllers" },
45
+ { name: "views", paths: ["src/views/**", "app/views/**", "resources/views/**"], description: "Templates and view logic" },
46
+ { name: "shared", paths: ["src/utils/**", "src/helpers/**", "app/helpers/**"], description: "Shared utilities and helpers" }
47
+ ]
48
+ };
49
+ case "laravel-service-repository":
50
+ return {
51
+ layers: [
52
+ { name: "models", paths: ["app/Models/**"], description: "Eloquent models" },
53
+ { name: "controllers", paths: ["app/Http/Controllers/**"], description: "HTTP controllers \u2014 thin, delegate to services" },
54
+ { name: "services", paths: ["app/Services/**"], description: "Business logic services" },
55
+ { name: "repositories", paths: ["app/Repositories/**"], description: "Data access \u2014 services depend on these" },
56
+ { name: "shared", paths: ["app/Helpers/**", "app/Traits/**"], description: "Helpers and traits" }
57
+ ]
58
+ };
59
+ case "go-api":
60
+ return {
61
+ layers: [
62
+ { name: "handlers", paths: ["internal/handlers/**", "api/**"], description: "HTTP handlers \u2014 parse request, call service, write response" },
63
+ { name: "services", paths: ["internal/services/**"], description: "Business logic \u2014 orchestrates domain and repositories" },
64
+ { name: "repositories", paths: ["internal/repositories/**", "internal/store/**"], description: "Data access \u2014 DB queries, external calls" },
65
+ { name: "models", paths: ["internal/models/**", "internal/domain/**"], description: "Structs and domain types" },
66
+ { name: "shared", paths: ["pkg/**", "internal/utils/**"], description: "Shared packages \u2014 no business logic" }
67
+ ]
68
+ };
69
+ case "react":
70
+ return {
71
+ layers: [
72
+ { name: "pages", paths: ["src/pages/**", "src/app/**", "src/routes/**"], description: "Route-level components \u2014 wire hooks and components together" },
73
+ { name: "components", paths: ["src/components/**"], description: "Reusable UI components \u2014 presentational and feature" },
74
+ { name: "hooks", paths: ["src/hooks/**"], description: "Custom hooks \u2014 stateful and side-effect logic" },
75
+ { name: "store", paths: ["src/store/**", "src/state/**", "src/atoms/**"], description: "Global client state \u2014 Zustand, Jotai, Redux" },
76
+ { name: "services", paths: ["src/services/**", "src/api/**", "src/clients/**"], description: "API clients and external service calls" }
77
+ ]
78
+ };
79
+ case "vue":
80
+ return {
81
+ layers: [
82
+ { name: "pages", paths: ["src/pages/**", "src/views/**"], description: "Route-level views" },
83
+ { name: "components", paths: ["src/components/**"], description: "Reusable Vue components" },
84
+ { name: "composables", paths: ["src/composables/**"], description: "Composables \u2014 stateful and reusable logic" },
85
+ { name: "store", paths: ["src/stores/**", "src/store/**"], description: "Pinia stores \u2014 global state" },
86
+ { name: "services", paths: ["src/services/**", "src/api/**"], description: "API clients and external calls" }
87
+ ]
88
+ };
89
+ case "svelte":
90
+ return {
91
+ layers: [
92
+ { name: "routes", paths: ["src/routes/**"], description: "SvelteKit routes \u2014 pages and layouts" },
93
+ { name: "components", paths: ["src/lib/components/**", "src/components/**"], description: "Reusable Svelte components" },
94
+ { name: "stores", paths: ["src/lib/stores/**", "src/stores/**"], description: "Svelte stores \u2014 reactive state" },
95
+ { name: "lib", paths: ["src/lib/**"], description: "Shared utilities, server actions, API clients" },
96
+ { name: "utils", paths: ["src/utils/**", "src/helpers/**"], description: "Pure utility functions" }
97
+ ]
98
+ };
99
+ case "nuxt":
100
+ return {
101
+ layers: [
102
+ { name: "pages", paths: ["pages/**"], description: "Nuxt pages \u2014 file-based routing" },
103
+ { name: "components", paths: ["components/**"], description: "Auto-imported Vue components" },
104
+ { name: "composables", paths: ["composables/**"], description: "Auto-imported composables" },
105
+ { name: "server", paths: ["server/**"], description: "Nitro server routes and API" },
106
+ { name: "utils", paths: ["utils/**", "lib/**"], description: "Shared utilities" }
107
+ ]
108
+ };
109
+ case "angular":
110
+ return {
111
+ layers: [
112
+ { name: "modules", paths: ["src/app/**/*.module.ts"], description: "Angular feature modules" },
113
+ { name: "components", paths: ["src/app/**/*.component.ts"], description: "Components \u2014 UI logic only" },
114
+ { name: "services", paths: ["src/app/**/*.service.ts"], description: "Injectable services \u2014 business logic and HTTP" },
115
+ { name: "guards", paths: ["src/app/**/*.guard.ts"], description: "Route guards \u2014 auth and access control" },
116
+ { name: "shared", paths: ["src/app/shared/**", "src/shared/**"], description: "Shared module \u2014 directives, pipes, components" }
117
+ ]
118
+ };
119
+ case "react-native":
120
+ return {
121
+ layers: [
122
+ { name: "screens", paths: ["src/screens/**", "app/**"], description: "Screen components \u2014 navigation targets" },
123
+ { name: "components", paths: ["src/components/**"], description: "Reusable UI components" },
124
+ { name: "hooks", paths: ["src/hooks/**"], description: "Custom hooks \u2014 stateful logic" },
125
+ { name: "store", paths: ["src/store/**", "src/state/**"], description: "Global state \u2014 Zustand, Redux, Jotai" },
126
+ { name: "services", paths: ["src/services/**", "src/api/**"], description: "API clients and native service wrappers" }
127
+ ]
128
+ };
129
+ case "hexagonal":
130
+ return {
131
+ layers: [
132
+ { name: "domain", paths: ["src/domain/**", "src/core/**"], description: "Pure domain \u2014 entities, value objects, domain services" },
133
+ { name: "ports", paths: ["src/ports/**", "src/application/ports/**"], description: "Interfaces \u2014 driving and driven port contracts" },
134
+ { name: "adapters", paths: ["src/adapters/**", "src/infrastructure/adapters/**"], description: "Adapter implementations \u2014 REST, DB, queues" },
135
+ { name: "infrastructure", paths: ["src/infrastructure/**"], description: "Technical infrastructure \u2014 config, DI, framework" },
136
+ { name: "shared", paths: ["src/shared/**", "src/utils/**"], description: "Cross-cutting utilities" }
137
+ ]
138
+ };
139
+ case "modular-monolith":
140
+ return {
141
+ layers: [
142
+ { name: "modules", paths: ["src/modules/**"], description: "Self-contained feature modules \u2014 each owns its DB, API, logic" },
143
+ { name: "shared", paths: ["src/shared/**", "src/common/**"], description: "Shared kernel \u2014 only pure utilities, no module business logic" },
144
+ { name: "infrastructure", paths: ["src/infrastructure/**"], description: "Technical infrastructure \u2014 DB connections, messaging, config" },
145
+ { name: "api", paths: ["src/api/**", "src/interfaces/**"], description: "Public API surface \u2014 HTTP, GraphQL, events" }
146
+ ]
147
+ };
148
+ default:
149
+ return {
150
+ layers: [
151
+ { name: "domain", paths: ["src/domain/**", "src/core/domain/**", "src/modules/*/domain/**"], description: "Business logic, entities, use cases" },
152
+ { name: "application", paths: ["src/application/**", "src/core/application/**", "src/modules/*/application/**"], description: "Use cases and orchestration" },
153
+ { name: "infrastructure", paths: ["src/infrastructure/**", "src/modules/*/infrastructure/**"], description: "Database, external APIs, low-level I/O" },
154
+ { name: "api", paths: ["src/api/**", "src/interfaces/**", "src/controllers/**"], description: "HTTP handlers, request/response" },
155
+ { name: "shared", paths: ["src/shared/**", "src/utils/**", "src/helpers/**"], description: "Utilities, helpers, constants" }
156
+ ]
157
+ };
158
+ }
159
+ }
160
+ function buildArchRules(arch) {
161
+ switch (arch) {
162
+ case "nestjs":
163
+ return { rules: [
164
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
165
+ { id: "controllers-no-repos", name: "Controllers must not import repositories", fromLayer: "controllers", toLayer: "repositories", allowed: false, severity: "critical", enforcement: "block" },
166
+ { id: "services-no-controllers", name: "Services must not import controllers", fromLayer: "services", toLayer: "controllers", allowed: false, severity: "critical", enforcement: "block" },
167
+ { id: "controllers-use-services", name: "Controllers delegate to services", fromLayer: "controllers", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
168
+ { id: "services-use-repos", name: "Services use repositories", fromLayer: "services", toLayer: "repositories", allowed: true, severity: "low", enforcement: "suggest" },
169
+ { id: "common-no-modules", name: "Common must not import feature modules", fromLayer: "common", toLayer: "modules", allowed: false, severity: "medium", enforcement: "warn" }
170
+ ] };
171
+ case "mvc":
172
+ case "laravel-service-repository":
173
+ return { rules: [
174
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
175
+ { id: "controllers-no-models", name: "Controllers must not query models directly", fromLayer: "controllers", toLayer: "models", allowed: false, severity: "medium", enforcement: "warn" },
176
+ { id: "controllers-use-services", name: "Controllers delegate to services", fromLayer: "controllers", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
177
+ { id: "services-use-repos", name: "Services use repositories for data access", fromLayer: "services", toLayer: "repositories", allowed: true, severity: "low", enforcement: "suggest" },
178
+ { id: "shared-no-controllers", name: "Shared must not import controllers", fromLayer: "shared", toLayer: "controllers", allowed: false, severity: "medium", enforcement: "warn" }
179
+ ] };
180
+ case "go-api":
181
+ return { rules: [
182
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
183
+ { id: "handlers-no-repos", name: "Handlers must not import repositories", fromLayer: "handlers", toLayer: "repositories", allowed: false, severity: "critical", enforcement: "block" },
184
+ { id: "handlers-use-services", name: "Handlers call services only", fromLayer: "handlers", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
185
+ { id: "services-use-repos", name: "Services use repositories", fromLayer: "services", toLayer: "repositories", allowed: true, severity: "low", enforcement: "suggest" },
186
+ { id: "shared-no-services", name: "Shared must not import services", fromLayer: "shared", toLayer: "services", allowed: false, severity: "medium", enforcement: "warn" }
187
+ ] };
188
+ case "react":
189
+ case "react-native":
190
+ return { rules: [
191
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
192
+ { id: "components-no-pages", name: "Components must not import pages", fromLayer: "components", toLayer: "pages", allowed: false, severity: "critical", enforcement: "block" },
193
+ { id: "components-no-store", name: "Presentational components must not read store", fromLayer: "components", toLayer: "store", allowed: false, severity: "medium", enforcement: "warn" },
194
+ { id: "services-no-components", name: "Services must not import components", fromLayer: "services", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
195
+ { id: "hooks-use-services", name: "Hooks use services for API calls", fromLayer: "hooks", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" }
196
+ ] };
197
+ case "vue":
198
+ case "nuxt":
199
+ return { rules: [
200
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
201
+ { id: "components-no-pages", name: "Components must not import pages/views", fromLayer: "components", toLayer: "pages", allowed: false, severity: "critical", enforcement: "block" },
202
+ { id: "services-no-components", name: "Services must not import components", fromLayer: "services", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
203
+ { id: "composables-use-services", name: "Composables use services for API calls", fromLayer: "composables", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
204
+ { id: "store-no-components", name: "Store must not import components", fromLayer: "store", toLayer: "components", allowed: false, severity: "medium", enforcement: "warn" }
205
+ ] };
206
+ case "svelte":
207
+ return { rules: [
208
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
209
+ { id: "components-no-routes", name: "Components must not import route modules", fromLayer: "components", toLayer: "routes", allowed: false, severity: "critical", enforcement: "block" },
210
+ { id: "stores-no-components", name: "Stores must not import components", fromLayer: "stores", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
211
+ { id: "lib-no-routes", name: "Lib must not import routes", fromLayer: "lib", toLayer: "routes", allowed: false, severity: "critical", enforcement: "block" },
212
+ { id: "lib-no-stores", name: "Lib must not import client stores", fromLayer: "lib", toLayer: "stores", allowed: false, severity: "critical", enforcement: "block" },
213
+ { id: "lib-no-components", name: "Lib must not import components", fromLayer: "lib", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
214
+ { id: "utils-no-stores", name: "Utils must not import stores", fromLayer: "utils", toLayer: "stores", allowed: false, severity: "medium", enforcement: "warn" },
215
+ { id: "utils-no-lib", name: "Utils must not import lib \u2014 keep utils pure", fromLayer: "utils", toLayer: "lib", allowed: false, severity: "medium", enforcement: "warn" },
216
+ { id: "routes-use-components", name: "Routes use components", fromLayer: "routes", toLayer: "components", allowed: true, severity: "low", enforcement: "suggest" },
217
+ { id: "routes-use-stores", name: "Routes use stores", fromLayer: "routes", toLayer: "stores", allowed: true, severity: "low", enforcement: "suggest" },
218
+ { id: "routes-use-lib", name: "Routes use lib for server actions and API", fromLayer: "routes", toLayer: "lib", allowed: true, severity: "low", enforcement: "suggest" },
219
+ { id: "components-use-stores", name: "Components use stores for reactive state", fromLayer: "components", toLayer: "stores", allowed: true, severity: "low", enforcement: "suggest" },
220
+ { id: "components-use-lib", name: "Components use lib for API clients", fromLayer: "components", toLayer: "lib", allowed: true, severity: "low", enforcement: "suggest" },
221
+ { id: "stores-use-lib", name: "Stores use lib for API and utilities", fromLayer: "stores", toLayer: "lib", allowed: true, severity: "low", enforcement: "suggest" }
222
+ ] };
223
+ case "angular":
224
+ return { rules: [
225
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
226
+ { id: "components-no-services-in-template", name: "Components use DI \u2014 do not import services directly", fromLayer: "components", toLayer: "services", allowed: false, severity: "medium", enforcement: "warn" },
227
+ { id: "guards-use-services", name: "Guards use auth services", fromLayer: "guards", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
228
+ { id: "shared-no-modules", name: "Shared must not import feature modules", fromLayer: "shared", toLayer: "modules", allowed: false, severity: "medium", enforcement: "warn" }
229
+ ] };
230
+ case "hexagonal":
231
+ return { rules: [
232
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
233
+ { id: "domain-no-adapters", name: "Domain must not import adapters", fromLayer: "domain", toLayer: "adapters", allowed: false, severity: "critical", enforcement: "block" },
234
+ { id: "domain-no-infra", name: "Domain must not import infrastructure", fromLayer: "domain", toLayer: "infrastructure", allowed: false, severity: "critical", enforcement: "block" },
235
+ { id: "adapters-implement-ports", name: "Adapters implement port interfaces", fromLayer: "adapters", toLayer: "ports", allowed: true, severity: "low", enforcement: "suggest" },
236
+ { id: "ports-no-adapters", name: "Ports must not import adapters", fromLayer: "ports", toLayer: "adapters", allowed: false, severity: "critical", enforcement: "block" }
237
+ ] };
238
+ case "modular-monolith":
239
+ return { rules: [
240
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
241
+ { id: "modules-no-direct-import", name: "Modules must not import each other directly", fromLayer: "modules", toLayer: "modules", allowed: false, severity: "critical", enforcement: "block" },
242
+ { id: "shared-no-modules", name: "Shared kernel must not import feature modules", fromLayer: "shared", toLayer: "modules", allowed: false, severity: "critical", enforcement: "block" },
243
+ { id: "modules-use-shared", name: "Modules may use shared kernel", fromLayer: "modules", toLayer: "shared", allowed: true, severity: "low", enforcement: "suggest" }
244
+ ] };
245
+ default:
246
+ return { rules: [
247
+ { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
248
+ { id: "domain-no-infra", name: "Domain must not import infrastructure", fromLayer: "domain", toLayer: "infrastructure", allowed: false, severity: "critical", enforcement: "block" },
249
+ { id: "domain-no-api", name: "Domain must not import API layer", fromLayer: "domain", toLayer: "api", allowed: false, severity: "critical", enforcement: "block" },
250
+ { id: "api-no-infra-direct", name: "API should not import infrastructure directly", fromLayer: "api", toLayer: "infrastructure", allowed: false, severity: "medium", enforcement: "warn" },
251
+ { id: "application-no-api", name: "Application must not import API layer", fromLayer: "application", toLayer: "api", allowed: false, severity: "critical", enforcement: "block" },
252
+ { id: "application-uses-domain", name: "Application depends on domain", fromLayer: "application", toLayer: "domain", allowed: true, severity: "low", enforcement: "suggest" },
253
+ { id: "shared-no-domain", name: "Shared must not import domain", fromLayer: "shared", toLayer: "domain", allowed: false, severity: "medium", enforcement: "warn" }
254
+ ] };
255
+ }
256
+ }
257
+
26
258
  // src/project-detector.ts
27
259
  import { existsSync, readFileSync } from "fs";
28
260
  import { join } from "path";
@@ -4029,6 +4261,8 @@ function printModelMissing(model) {
4029
4261
  }
4030
4262
 
4031
4263
  export {
4264
+ buildLayersTemplate,
4265
+ buildArchRules,
4032
4266
  detectProject,
4033
4267
  embed,
4034
4268
  migrateGraphSnapshots,
package/dist/cli.js CHANGED
@@ -3,6 +3,8 @@ import {
3
3
  AGENT_NAMES,
4
4
  MEMORY_FILE,
5
5
  OUTPUT_FILES,
6
+ buildArchRules,
7
+ buildLayersTemplate,
6
8
  checkCi,
7
9
  checkCommitMsg,
8
10
  checkFile,
@@ -27,13 +29,13 @@ import {
27
29
  toPortableMemory,
28
30
  uninstallHook,
29
31
  writeMemoryFile
30
- } from "./chunk-3XTHE74V.js";
32
+ } from "./chunk-KNZ3JNHE.js";
31
33
  import "./chunk-PQBWHAZN.js";
32
34
  import {
33
35
  closePool,
34
36
  getPool,
35
37
  runMigrations
36
- } from "./chunk-M7NKSXFS.js";
38
+ } from "./chunk-4ZSVQMI7.js";
37
39
  import "./chunk-ZZBQEXEO.js";
38
40
 
39
41
  // src/cli.ts
@@ -1753,7 +1755,7 @@ program.command("dashboard").description("Start the live Svelte dashboard with W
1753
1755
  }
1754
1756
  return void 0;
1755
1757
  };
1756
- const { startDashboard } = await import("./dashboard-server-DHSVWCCD.js");
1758
+ const { startDashboard } = await import("./dashboard-server-FMKL4KZG.js");
1757
1759
  await startDashboard({
1758
1760
  port: parseInt(opts.port, 10),
1759
1761
  path: resolveDashboardPath(),
@@ -2386,7 +2388,7 @@ program.command("check").description("Check staged changes against architecture
2386
2388
  }
2387
2389
  let storedMemories = [];
2388
2390
  try {
2389
- const { listMemories } = await import("./db-PRDHI2CN.js");
2391
+ const { listMemories } = await import("./db-Y6BXHLRN.js");
2390
2392
  const allMemories = await listMemories({ limit: 1e4 });
2391
2393
  const ranked = allMemories.filter((m) => ["rule", "pattern", "decision"].includes(m.type));
2392
2394
  const changedLayers = packet.layersAffected;
@@ -2575,226 +2577,6 @@ program.command("watch").description("Watch source files and check violations in
2575
2577
  });
2576
2578
  });
2577
2579
  var ARCHMIND_DIR = join(process.cwd(), ".archmind");
2578
- function buildLayersTemplate(arch2) {
2579
- switch (arch2) {
2580
- case "nestjs":
2581
- return {
2582
- layers: [
2583
- { name: "modules", paths: ["src/modules/**"], description: "Feature modules \u2014 each owns its controller, service, DTOs, entities" },
2584
- { name: "controllers", paths: ["src/modules/*/controllers/**", "src/modules/*.controller.ts"], description: "HTTP request handlers \u2014 thin, delegate to services" },
2585
- { name: "services", paths: ["src/modules/*/services/**", "src/modules/*.service.ts"], description: "Business logic \u2014 never import controllers or HTTP classes" },
2586
- { name: "repositories", paths: ["src/modules/*/repositories/**"], description: "Data access \u2014 services depend on these interfaces" },
2587
- { name: "common", paths: ["src/common/**", "src/guards/**", "src/filters/**", "src/interceptors/**", "src/pipes/**"], description: "Guards, filters, interceptors, pipes" }
2588
- ]
2589
- };
2590
- case "mvc":
2591
- return {
2592
- layers: [
2593
- { name: "models", paths: ["src/models/**", "app/models/**"], description: "Data models \u2014 represent DB records" },
2594
- { name: "controllers", paths: ["src/controllers/**", "app/controllers/**"], description: "Route handlers \u2014 thin, delegate to services" },
2595
- { name: "services", paths: ["src/services/**", "app/services/**"], description: "Business logic \u2014 called by controllers" },
2596
- { name: "views", paths: ["src/views/**", "app/views/**", "resources/views/**"], description: "Templates and view logic" },
2597
- { name: "shared", paths: ["src/utils/**", "src/helpers/**", "app/helpers/**"], description: "Shared utilities and helpers" }
2598
- ]
2599
- };
2600
- case "laravel-service-repository":
2601
- return {
2602
- layers: [
2603
- { name: "models", paths: ["app/Models/**"], description: "Eloquent models" },
2604
- { name: "controllers", paths: ["app/Http/Controllers/**"], description: "HTTP controllers \u2014 thin, delegate to services" },
2605
- { name: "services", paths: ["app/Services/**"], description: "Business logic services" },
2606
- { name: "repositories", paths: ["app/Repositories/**"], description: "Data access \u2014 services depend on these" },
2607
- { name: "shared", paths: ["app/Helpers/**", "app/Traits/**"], description: "Helpers and traits" }
2608
- ]
2609
- };
2610
- case "go-api":
2611
- return {
2612
- layers: [
2613
- { name: "handlers", paths: ["internal/handlers/**", "api/**"], description: "HTTP handlers \u2014 parse request, call service, write response" },
2614
- { name: "services", paths: ["internal/services/**"], description: "Business logic \u2014 orchestrates domain and repositories" },
2615
- { name: "repositories", paths: ["internal/repositories/**", "internal/store/**"], description: "Data access \u2014 DB queries, external calls" },
2616
- { name: "models", paths: ["internal/models/**", "internal/domain/**"], description: "Structs and domain types" },
2617
- { name: "shared", paths: ["pkg/**", "internal/utils/**"], description: "Shared packages \u2014 no business logic" }
2618
- ]
2619
- };
2620
- case "react":
2621
- return {
2622
- layers: [
2623
- { name: "pages", paths: ["src/pages/**", "src/app/**", "src/routes/**"], description: "Route-level components \u2014 wire hooks and components together" },
2624
- { name: "components", paths: ["src/components/**"], description: "Reusable UI components \u2014 presentational and feature" },
2625
- { name: "hooks", paths: ["src/hooks/**"], description: "Custom hooks \u2014 stateful and side-effect logic" },
2626
- { name: "store", paths: ["src/store/**", "src/state/**", "src/atoms/**"], description: "Global client state \u2014 Zustand, Jotai, Redux" },
2627
- { name: "services", paths: ["src/services/**", "src/api/**", "src/clients/**"], description: "API clients and external service calls" }
2628
- ]
2629
- };
2630
- case "vue":
2631
- return {
2632
- layers: [
2633
- { name: "pages", paths: ["src/pages/**", "src/views/**"], description: "Route-level views" },
2634
- { name: "components", paths: ["src/components/**"], description: "Reusable Vue components" },
2635
- { name: "composables", paths: ["src/composables/**"], description: "Composables \u2014 stateful and reusable logic" },
2636
- { name: "store", paths: ["src/stores/**", "src/store/**"], description: "Pinia stores \u2014 global state" },
2637
- { name: "services", paths: ["src/services/**", "src/api/**"], description: "API clients and external calls" }
2638
- ]
2639
- };
2640
- case "svelte":
2641
- return {
2642
- layers: [
2643
- { name: "routes", paths: ["src/routes/**"], description: "SvelteKit routes \u2014 pages and layouts" },
2644
- { name: "components", paths: ["src/lib/components/**", "src/components/**"], description: "Reusable Svelte components" },
2645
- { name: "stores", paths: ["src/lib/stores/**", "src/stores/**"], description: "Svelte stores \u2014 reactive state" },
2646
- { name: "lib", paths: ["src/lib/**"], description: "Shared utilities, server actions, API clients" },
2647
- { name: "utils", paths: ["src/utils/**", "src/helpers/**"], description: "Pure utility functions" }
2648
- ]
2649
- };
2650
- case "nuxt":
2651
- return {
2652
- layers: [
2653
- { name: "pages", paths: ["pages/**"], description: "Nuxt pages \u2014 file-based routing" },
2654
- { name: "components", paths: ["components/**"], description: "Auto-imported Vue components" },
2655
- { name: "composables", paths: ["composables/**"], description: "Auto-imported composables" },
2656
- { name: "server", paths: ["server/**"], description: "Nitro server routes and API" },
2657
- { name: "utils", paths: ["utils/**", "lib/**"], description: "Shared utilities" }
2658
- ]
2659
- };
2660
- case "angular":
2661
- return {
2662
- layers: [
2663
- { name: "modules", paths: ["src/app/**/*.module.ts"], description: "Angular feature modules" },
2664
- { name: "components", paths: ["src/app/**/*.component.ts"], description: "Components \u2014 UI logic only" },
2665
- { name: "services", paths: ["src/app/**/*.service.ts"], description: "Injectable services \u2014 business logic and HTTP" },
2666
- { name: "guards", paths: ["src/app/**/*.guard.ts"], description: "Route guards \u2014 auth and access control" },
2667
- { name: "shared", paths: ["src/app/shared/**", "src/shared/**"], description: "Shared module \u2014 directives, pipes, components" }
2668
- ]
2669
- };
2670
- case "react-native":
2671
- return {
2672
- layers: [
2673
- { name: "screens", paths: ["src/screens/**", "app/**"], description: "Screen components \u2014 navigation targets" },
2674
- { name: "components", paths: ["src/components/**"], description: "Reusable UI components" },
2675
- { name: "hooks", paths: ["src/hooks/**"], description: "Custom hooks \u2014 stateful logic" },
2676
- { name: "store", paths: ["src/store/**", "src/state/**"], description: "Global state \u2014 Zustand, Redux, Jotai" },
2677
- { name: "services", paths: ["src/services/**", "src/api/**"], description: "API clients and native service wrappers" }
2678
- ]
2679
- };
2680
- case "hexagonal":
2681
- return {
2682
- layers: [
2683
- { name: "domain", paths: ["src/domain/**", "src/core/**"], description: "Pure domain \u2014 entities, value objects, domain services" },
2684
- { name: "ports", paths: ["src/ports/**", "src/application/ports/**"], description: "Interfaces \u2014 driving and driven port contracts" },
2685
- { name: "adapters", paths: ["src/adapters/**", "src/infrastructure/adapters/**"], description: "Adapter implementations \u2014 REST, DB, queues" },
2686
- { name: "infrastructure", paths: ["src/infrastructure/**"], description: "Technical infrastructure \u2014 config, DI, framework" },
2687
- { name: "shared", paths: ["src/shared/**", "src/utils/**"], description: "Cross-cutting utilities" }
2688
- ]
2689
- };
2690
- case "modular-monolith":
2691
- return {
2692
- layers: [
2693
- { name: "modules", paths: ["src/modules/**"], description: "Self-contained feature modules \u2014 each owns its DB, API, logic" },
2694
- { name: "shared", paths: ["src/shared/**", "src/common/**"], description: "Shared kernel \u2014 only pure utilities, no module business logic" },
2695
- { name: "infrastructure", paths: ["src/infrastructure/**"], description: "Technical infrastructure \u2014 DB connections, messaging, config" },
2696
- { name: "api", paths: ["src/api/**", "src/interfaces/**"], description: "Public API surface \u2014 HTTP, GraphQL, events" }
2697
- ]
2698
- };
2699
- default:
2700
- return {
2701
- layers: [
2702
- { name: "domain", paths: ["src/domain/**", "src/core/domain/**", "src/modules/*/domain/**"], description: "Business logic, entities, use cases" },
2703
- { name: "application", paths: ["src/application/**", "src/core/application/**", "src/modules/*/application/**"], description: "Use cases and orchestration" },
2704
- { name: "infrastructure", paths: ["src/infrastructure/**", "src/modules/*/infrastructure/**"], description: "Database, external APIs, low-level I/O" },
2705
- { name: "api", paths: ["src/api/**", "src/interfaces/**", "src/controllers/**"], description: "HTTP handlers, request/response" },
2706
- { name: "shared", paths: ["src/shared/**", "src/utils/**", "src/helpers/**"], description: "Utilities, helpers, constants" }
2707
- ]
2708
- };
2709
- }
2710
- }
2711
- function buildArchRules(arch2) {
2712
- switch (arch2) {
2713
- case "nestjs":
2714
- return { rules: [
2715
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2716
- { id: "controllers-no-repos", name: "Controllers must not import repositories", fromLayer: "controllers", toLayer: "repositories", allowed: false, severity: "critical", enforcement: "block" },
2717
- { id: "services-no-controllers", name: "Services must not import controllers", fromLayer: "services", toLayer: "controllers", allowed: false, severity: "critical", enforcement: "block" },
2718
- { id: "controllers-use-services", name: "Controllers delegate to services", fromLayer: "controllers", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
2719
- { id: "services-use-repos", name: "Services use repositories", fromLayer: "services", toLayer: "repositories", allowed: true, severity: "low", enforcement: "suggest" },
2720
- { id: "common-no-modules", name: "Common must not import feature modules", fromLayer: "common", toLayer: "modules", allowed: false, severity: "medium", enforcement: "warn" }
2721
- ] };
2722
- case "mvc":
2723
- case "laravel-service-repository":
2724
- return { rules: [
2725
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2726
- { id: "controllers-no-models", name: "Controllers must not query models directly", fromLayer: "controllers", toLayer: "models", allowed: false, severity: "medium", enforcement: "warn" },
2727
- { id: "controllers-use-services", name: "Controllers delegate to services", fromLayer: "controllers", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
2728
- { id: "services-use-repos", name: "Services use repositories for data access", fromLayer: "services", toLayer: "repositories", allowed: true, severity: "low", enforcement: "suggest" },
2729
- { id: "shared-no-controllers", name: "Shared must not import controllers", fromLayer: "shared", toLayer: "controllers", allowed: false, severity: "medium", enforcement: "warn" }
2730
- ] };
2731
- case "go-api":
2732
- return { rules: [
2733
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2734
- { id: "handlers-no-repos", name: "Handlers must not import repositories", fromLayer: "handlers", toLayer: "repositories", allowed: false, severity: "critical", enforcement: "block" },
2735
- { id: "handlers-use-services", name: "Handlers call services only", fromLayer: "handlers", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
2736
- { id: "services-use-repos", name: "Services use repositories", fromLayer: "services", toLayer: "repositories", allowed: true, severity: "low", enforcement: "suggest" },
2737
- { id: "shared-no-services", name: "Shared must not import services", fromLayer: "shared", toLayer: "services", allowed: false, severity: "medium", enforcement: "warn" }
2738
- ] };
2739
- case "react":
2740
- case "react-native":
2741
- return { rules: [
2742
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2743
- { id: "components-no-pages", name: "Components must not import pages", fromLayer: "components", toLayer: "pages", allowed: false, severity: "critical", enforcement: "block" },
2744
- { id: "components-no-store", name: "Presentational components must not read store", fromLayer: "components", toLayer: "store", allowed: false, severity: "medium", enforcement: "warn" },
2745
- { id: "services-no-components", name: "Services must not import components", fromLayer: "services", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
2746
- { id: "hooks-use-services", name: "Hooks use services for API calls", fromLayer: "hooks", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" }
2747
- ] };
2748
- case "vue":
2749
- case "nuxt":
2750
- return { rules: [
2751
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2752
- { id: "components-no-pages", name: "Components must not import pages/views", fromLayer: "components", toLayer: "pages", allowed: false, severity: "critical", enforcement: "block" },
2753
- { id: "services-no-components", name: "Services must not import components", fromLayer: "services", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
2754
- { id: "composables-use-services", name: "Composables use services for API calls", fromLayer: "composables", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
2755
- { id: "store-no-components", name: "Store must not import components", fromLayer: "store", toLayer: "components", allowed: false, severity: "medium", enforcement: "warn" }
2756
- ] };
2757
- case "svelte":
2758
- return { rules: [
2759
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2760
- { id: "components-no-routes", name: "Components must not import route modules", fromLayer: "components", toLayer: "routes", allowed: false, severity: "critical", enforcement: "block" },
2761
- { id: "stores-no-components", name: "Stores must not import components", fromLayer: "stores", toLayer: "components", allowed: false, severity: "critical", enforcement: "block" },
2762
- { id: "utils-no-stores", name: "Utils must not import stores", fromLayer: "utils", toLayer: "stores", allowed: false, severity: "medium", enforcement: "warn" }
2763
- ] };
2764
- case "angular":
2765
- return { rules: [
2766
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2767
- { id: "components-no-services-in-template", name: "Components use DI \u2014 do not import services directly", fromLayer: "components", toLayer: "services", allowed: false, severity: "medium", enforcement: "warn" },
2768
- { id: "guards-use-services", name: "Guards use auth services", fromLayer: "guards", toLayer: "services", allowed: true, severity: "low", enforcement: "suggest" },
2769
- { id: "shared-no-modules", name: "Shared must not import feature modules", fromLayer: "shared", toLayer: "modules", allowed: false, severity: "medium", enforcement: "warn" }
2770
- ] };
2771
- case "hexagonal":
2772
- return { rules: [
2773
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2774
- { id: "domain-no-adapters", name: "Domain must not import adapters", fromLayer: "domain", toLayer: "adapters", allowed: false, severity: "critical", enforcement: "block" },
2775
- { id: "domain-no-infra", name: "Domain must not import infrastructure", fromLayer: "domain", toLayer: "infrastructure", allowed: false, severity: "critical", enforcement: "block" },
2776
- { id: "adapters-implement-ports", name: "Adapters implement port interfaces", fromLayer: "adapters", toLayer: "ports", allowed: true, severity: "low", enforcement: "suggest" },
2777
- { id: "ports-no-adapters", name: "Ports must not import adapters", fromLayer: "ports", toLayer: "adapters", allowed: false, severity: "critical", enforcement: "block" }
2778
- ] };
2779
- case "modular-monolith":
2780
- return { rules: [
2781
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2782
- { id: "modules-no-direct-import", name: "Modules must not import each other directly", fromLayer: "modules", toLayer: "modules", allowed: false, severity: "critical", enforcement: "block" },
2783
- { id: "shared-no-modules", name: "Shared kernel must not import feature modules", fromLayer: "shared", toLayer: "modules", allowed: false, severity: "critical", enforcement: "block" },
2784
- { id: "modules-use-shared", name: "Modules may use shared kernel", fromLayer: "modules", toLayer: "shared", allowed: true, severity: "low", enforcement: "suggest" }
2785
- ] };
2786
- default:
2787
- return { rules: [
2788
- { id: "no-circular", name: "No circular dependencies", fromLayer: "*", toLayer: "*", allowed: false, severity: "critical", enforcement: "block" },
2789
- { id: "domain-no-infra", name: "Domain must not import infrastructure", fromLayer: "domain", toLayer: "infrastructure", allowed: false, severity: "critical", enforcement: "block" },
2790
- { id: "domain-no-api", name: "Domain must not import API layer", fromLayer: "domain", toLayer: "api", allowed: false, severity: "critical", enforcement: "block" },
2791
- { id: "api-no-infra-direct", name: "API should not import infrastructure directly", fromLayer: "api", toLayer: "infrastructure", allowed: false, severity: "medium", enforcement: "warn" },
2792
- { id: "application-no-api", name: "Application must not import API layer", fromLayer: "application", toLayer: "api", allowed: false, severity: "critical", enforcement: "block" },
2793
- { id: "application-uses-domain", name: "Application depends on domain", fromLayer: "application", toLayer: "domain", allowed: true, severity: "low", enforcement: "suggest" },
2794
- { id: "shared-no-domain", name: "Shared must not import domain", fromLayer: "shared", toLayer: "domain", allowed: false, severity: "medium", enforcement: "warn" }
2795
- ] };
2796
- }
2797
- }
2798
2580
  function getArchmindDir() {
2799
2581
  return ARCHMIND_DIR;
2800
2582
  }