@compilr-dev/sdk 0.29.5 → 0.29.7

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.
@@ -25,5 +25,4 @@
25
25
  * ```
26
26
  */
27
27
  export type { ActionContext, ActionDefinition } from './types.js';
28
- export { ACTION_REGISTRY, getActionsForContext, getActionById } from './registry.js';
29
- export { resolveActionPrompt, buildContextSummary, getSuggestedRole } from './resolver.js';
28
+ export { resolveActionPrompt, buildContextSummary } from './resolver.js';
@@ -25,6 +25,14 @@
25
25
  * ```
26
26
  */
27
27
  // Registry
28
- export { ACTION_REGISTRY, getActionsForContext, getActionById } from './registry.js';
28
+ /*
29
+ ⚠️ ACTION_REGISTRY IS GONE — superseded, not merely unused. `MACRO_META_REGISTRY` replaced it
30
+ during the macro rename and is a strict superset (55 entries against 14, every id present). The
31
+ old one kept an IPC handler and a preload binding alive that nothing called, which made it look
32
+ like the action source and cost a wrong assumption in the Projects plan.
33
+
34
+ `resolveActionPrompt` never read it: it resolves by skill NAME from the array it is given, so
35
+ the live path was never coupled to the dead one.
36
+ */
29
37
  // Resolver
30
- export { resolveActionPrompt, buildContextSummary, getSuggestedRole } from './resolver.js';
38
+ export { resolveActionPrompt, buildContextSummary } from './resolver.js';
@@ -23,7 +23,3 @@ export declare function resolveActionPrompt(actionId: string, context: ActionCon
23
23
  * Used by the ActionCard component to show a brief description.
24
24
  */
25
25
  export declare function buildContextSummary(context: ActionContext): string;
26
- /**
27
- * Get the suggested agent role for an action.
28
- */
29
- export declare function getSuggestedRole(actionId: string): string | undefined;
@@ -7,7 +7,6 @@
7
7
  *
8
8
  * Used by both CLI and desktop to turn user actions into agent prompts.
9
9
  */
10
- import { getActionById } from './registry.js';
11
10
  /**
12
11
  * Resolve an action + context into a final prompt for the agent.
13
12
  *
@@ -99,9 +98,3 @@ export function buildContextSummary(context) {
99
98
  }
100
99
  return '';
101
100
  }
102
- /**
103
- * Get the suggested agent role for an action.
104
- */
105
- export function getSuggestedRole(actionId) {
106
- return getActionById(actionId)?.suggestedRole;
107
- }
package/dist/index.d.ts CHANGED
@@ -87,7 +87,7 @@ export type { MacroListEntry, BuildMacroListOptions } from './skills/index.js';
87
87
  export { generateSkillCatalog, toCatalogEntry, createLoadSkillTool } from './skills/index.js';
88
88
  export type { SkillCatalogEntry, SkillSource } from './skills/index.js';
89
89
  export { platformMacros, designMacro, sketchMacro, prdMacro, refineMacro, refineItemMacro, architectureMacro, sessionNotesMacro, buildMacro, scaffoldMacro, outlineMacro, literatureReviewMacro, draftSectionMacro, peerReviewMacro, researchScaffoldMacro, businessVisionMacro, marketAnalysisMacro, competitorAnalysisMacro, financialModelMacro, pitchOutlineMacro, businessReviewMacro, brandSetupMacro, contentStrategyMacro, contentCalendarMacro, createContentMacro, contentReviewMacro, curriculumDesignMacro, lessonPlanMacro, assessmentDesignMacro, courseReviewMacro, bookOutlineMacro, characterDesignMacro, plotThreadsMacro, sceneBreakdownMacro, bookReviewMacro, } from './skills/index.js';
90
- export { ACTION_REGISTRY, getActionsForContext, getActionById, resolveActionPrompt, buildContextSummary, getSuggestedRole, } from './actions/index.js';
90
+ export { resolveActionPrompt, buildContextSummary } from './actions/index.js';
91
91
  export type { ActionContext, ActionDefinition } from './actions/index.js';
92
92
  export { PROJECT_TYPES, getProjectTypeConfig, getEnrichedProjectTypeConfig, getProjectTypesByCategory, generalConfig, softwareConfig, researchConfig, businessPlanConfig, contentConfig, techDocsConfig, courseConfig, MACRO_META_REGISTRY, resolveActionMeta, getRelevantMacros, getMacroMeta, getAllMacroMeta, } from './project-types/index.js';
93
93
  export type { ActionMeta, MacroMeta, MacroCategory, MacroCapabilities, } from './project-types/index.js';
package/dist/index.js CHANGED
@@ -166,7 +166,7 @@ export { platformMacros, designMacro, sketchMacro, prdMacro, refineMacro, refine
166
166
  // =============================================================================
167
167
  // Contextual Actions (skill invocations with context)
168
168
  // =============================================================================
169
- export { ACTION_REGISTRY, getActionsForContext, getActionById, resolveActionPrompt, buildContextSummary, getSuggestedRole, } from './actions/index.js';
169
+ export { resolveActionPrompt, buildContextSummary } from './actions/index.js';
170
170
  // =============================================================================
171
171
  // Project Types
172
172
  // =============================================================================
@@ -10,7 +10,7 @@
10
10
  * └── project-{id}.json # Per-project anchors
11
11
  */
12
12
  import { AnchorManager } from '@compilr-dev/agents';
13
- import type { Anchor, AnchorInput, AnchorQueryOptions } from '@compilr-dev/agents';
13
+ import type { Anchor, AnchorInput, AnchorPriority, AnchorQueryOptions } from '@compilr-dev/agents';
14
14
  import type { IAnchorService } from './services.js';
15
15
  export interface ProjectAnchorStoreConfig {
16
16
  /** Directory for anchor JSON files (e.g. ~/.compilr-dev/anchors/) */
@@ -36,6 +36,55 @@ export declare class ProjectAnchorStore {
36
36
  addAnchor(input: AnchorInput & {
37
37
  projectId?: string;
38
38
  }): Anchor;
39
+ /**
40
+ * Find an anchor by id, and say which file holds it.
41
+ *
42
+ * Searches the active project's manager then the global one — the same two the UI lists, and
43
+ * the same order `toService().remove` already uses. It deliberately does not sweep
44
+ * `this.managers`: those are lazily cached, so which ones exist depends on what happened
45
+ * earlier in the session, and the answer would drift with it.
46
+ *
47
+ * The null check on `currentProjectId` is defensive rather than behavioural — `String(null)`
48
+ * would key an empty manager and the lookup would fall through to global with the same
49
+ * result, and `loadPersistent` writes nothing for a file that does not exist. It is here so
50
+ * the intent is legible, not because a test can tell the difference. Mutating it away leaves
51
+ * every test green, and that is correct.
52
+ */
53
+ findAnchor(id: string, currentProjectId?: string | null): {
54
+ anchor: Anchor;
55
+ projectKey: string | null;
56
+ } | undefined;
57
+ /** Remove an anchor by id from whichever file holds it. */
58
+ removeAnchorById(id: string, currentProjectId?: string | null): {
59
+ removed: boolean;
60
+ scope?: 'global' | 'project';
61
+ };
62
+ /**
63
+ * Edit an anchor in place, keeping its id.
64
+ *
65
+ * ⚠️ WHY THE ID MATTERS. Without this the caller has to remove and re-add, which mints a new
66
+ * id — an open tab would then point at an anchor that no longer exists, and the row would
67
+ * jump in the list. `AnchorInput` accepts an id, so the re-add reuses the old one and both
68
+ * stay put.
69
+ *
70
+ * ⚠️ CHANGING SCOPE IS A MOVE BETWEEN FILES, not a field edit. Global anchors live in
71
+ * `global.json` and project ones in `project-<id>.json`, so switching "applies to" removes
72
+ * from one manager and adds to the other. The id survives that too.
73
+ *
74
+ * ⚠️ `createdAt` IS RESET, deliberately. `AnchorManager.add` always stamps `new Date()` and
75
+ * its `savePersistent` is private, so the only ways to keep the original are to mutate a
76
+ * stored object behind the manager's back or to widen `AnchorInput` in @compilr-dev/agents.
77
+ * Nothing displays `createdAt`; it is read only by the two eviction tie-breakers
78
+ * (`makeRoom`, `removeOldestLowPriority`), so on an edited anchor it now means "last edited"
79
+ * and that anchor is evicted last under budget pressure. Built-ins keep `new Date(0)` because
80
+ * they cannot be edited at all. See F-4.
81
+ */
82
+ updateAnchor(id: string, patch: {
83
+ content?: string;
84
+ priority?: AnchorPriority;
85
+ tags?: string[];
86
+ scope?: 'global' | 'project';
87
+ }, currentProjectId?: string | null): Anchor | undefined;
39
88
  /** Get all anchors across all cached managers. */
40
89
  getAllAnchors(options?: AnchorQueryOptions): Anchor[];
41
90
  /** Clear all anchors for a project and delete the persistence file. */
@@ -53,6 +102,29 @@ export declare class ProjectAnchorStore {
53
102
  projectCounts: Map<string, number>;
54
103
  totalTokens: number;
55
104
  };
105
+ /**
106
+ * Usage against the caps, per file.
107
+ *
108
+ * ⚠️ THE CAPS ARE PER FILE, NOT COMBINED. Each `AnchorManager` enforces `maxAnchors` and
109
+ * `maxTokens` on its own store, so global.json and project-<id>.json each get the full
110
+ * budget. A single meter summing the two and measuring it against one cap would read half
111
+ * full at the moment an `anchor_add` starts evicting — which is the opposite of the point,
112
+ * since the meter exists to show the limit before it bites.
113
+ *
114
+ * Both are returned and the caller shows the fuller one.
115
+ */
116
+ getUsage(projectId?: string | null): {
117
+ global: {
118
+ anchors: number;
119
+ tokens: number;
120
+ };
121
+ project: {
122
+ anchors: number;
123
+ tokens: number;
124
+ } | null;
125
+ maxAnchors: number;
126
+ maxTokens: number;
127
+ };
56
128
  /** Clear all cached managers (useful for testing or refresh). */
57
129
  clearCache(): void;
58
130
  /** Create an IAnchorService implementation for use with createPlatformTools(). */
@@ -52,6 +52,89 @@ export class ProjectAnchorStore {
52
52
  const manager = this.getManager(input.projectId ?? null);
53
53
  return manager.add(input);
54
54
  }
55
+ /**
56
+ * Find an anchor by id, and say which file holds it.
57
+ *
58
+ * Searches the active project's manager then the global one — the same two the UI lists, and
59
+ * the same order `toService().remove` already uses. It deliberately does not sweep
60
+ * `this.managers`: those are lazily cached, so which ones exist depends on what happened
61
+ * earlier in the session, and the answer would drift with it.
62
+ *
63
+ * The null check on `currentProjectId` is defensive rather than behavioural — `String(null)`
64
+ * would key an empty manager and the lookup would fall through to global with the same
65
+ * result, and `loadPersistent` writes nothing for a file that does not exist. It is here so
66
+ * the intent is legible, not because a test can tell the difference. Mutating it away leaves
67
+ * every test green, and that is correct.
68
+ */
69
+ findAnchor(id, currentProjectId) {
70
+ if (currentProjectId != null && currentProjectId !== '') {
71
+ const projectManager = this.getManager(currentProjectId);
72
+ const anchor = projectManager.get(id);
73
+ if (anchor)
74
+ return { anchor, projectKey: currentProjectId };
75
+ }
76
+ const anchor = this.getGlobalManager().get(id);
77
+ return anchor ? { anchor, projectKey: null } : undefined;
78
+ }
79
+ /** Remove an anchor by id from whichever file holds it. */
80
+ removeAnchorById(id, currentProjectId) {
81
+ const found = this.findAnchor(id, currentProjectId);
82
+ if (!found)
83
+ return { removed: false };
84
+ const removed = this.getManager(found.projectKey).remove(id);
85
+ return { removed, scope: found.projectKey === null ? 'global' : 'project' };
86
+ }
87
+ /**
88
+ * Edit an anchor in place, keeping its id.
89
+ *
90
+ * ⚠️ WHY THE ID MATTERS. Without this the caller has to remove and re-add, which mints a new
91
+ * id — an open tab would then point at an anchor that no longer exists, and the row would
92
+ * jump in the list. `AnchorInput` accepts an id, so the re-add reuses the old one and both
93
+ * stay put.
94
+ *
95
+ * ⚠️ CHANGING SCOPE IS A MOVE BETWEEN FILES, not a field edit. Global anchors live in
96
+ * `global.json` and project ones in `project-<id>.json`, so switching "applies to" removes
97
+ * from one manager and adds to the other. The id survives that too.
98
+ *
99
+ * ⚠️ `createdAt` IS RESET, deliberately. `AnchorManager.add` always stamps `new Date()` and
100
+ * its `savePersistent` is private, so the only ways to keep the original are to mutate a
101
+ * stored object behind the manager's back or to widen `AnchorInput` in @compilr-dev/agents.
102
+ * Nothing displays `createdAt`; it is read only by the two eviction tie-breakers
103
+ * (`makeRoom`, `removeOldestLowPriority`), so on an edited anchor it now means "last edited"
104
+ * and that anchor is evicted last under budget pressure. Built-ins keep `new Date(0)` because
105
+ * they cannot be edited at all. See F-4.
106
+ */
107
+ updateAnchor(id, patch, currentProjectId) {
108
+ const found = this.findAnchor(id, currentProjectId);
109
+ if (!found)
110
+ return undefined;
111
+ const { anchor, projectKey } = found;
112
+ let targetKey = projectKey;
113
+ if (patch.scope !== undefined) {
114
+ if (patch.scope === 'project') {
115
+ if (currentProjectId == null || currentProjectId === '') {
116
+ throw new Error('Cannot scope an anchor to a project: no active project. Use scope: "global" instead.');
117
+ }
118
+ targetKey = currentProjectId;
119
+ }
120
+ else {
121
+ targetKey = null;
122
+ }
123
+ }
124
+ // Remove first: re-adding the same id into the same manager would otherwise be an
125
+ // overwrite whose budget accounting counts the content twice.
126
+ this.getManager(projectKey).remove(id);
127
+ return this.getManager(targetKey).add({
128
+ id,
129
+ content: patch.content ?? anchor.content,
130
+ priority: patch.priority ?? anchor.priority,
131
+ scope: anchor.scope,
132
+ tags: patch.tags ?? anchor.tags,
133
+ metadata: anchor.metadata,
134
+ expiresAt: anchor.expiresAt,
135
+ projectId: targetKey ?? undefined,
136
+ });
137
+ }
55
138
  /** Get all anchors across all cached managers. */
56
139
  getAllAnchors(options) {
57
140
  const all = [];
@@ -127,6 +210,30 @@ export class ProjectAnchorStore {
127
210
  totalTokens,
128
211
  };
129
212
  }
213
+ /**
214
+ * Usage against the caps, per file.
215
+ *
216
+ * ⚠️ THE CAPS ARE PER FILE, NOT COMBINED. Each `AnchorManager` enforces `maxAnchors` and
217
+ * `maxTokens` on its own store, so global.json and project-<id>.json each get the full
218
+ * budget. A single meter summing the two and measuring it against one cap would read half
219
+ * full at the moment an `anchor_add` starts evicting — which is the opposite of the point,
220
+ * since the meter exists to show the limit before it bites.
221
+ *
222
+ * Both are returned and the caller shows the fuller one.
223
+ */
224
+ getUsage(projectId) {
225
+ const globalManager = this.getGlobalManager();
226
+ const hasProject = projectId != null && projectId !== '';
227
+ const projectManager = hasProject ? this.getManager(projectId) : null;
228
+ return {
229
+ global: { anchors: globalManager.size, tokens: globalManager.getTotalTokens() },
230
+ project: projectManager === null
231
+ ? null
232
+ : { anchors: projectManager.size, tokens: projectManager.getTotalTokens() },
233
+ maxAnchors: this.config.maxAnchors ?? 50,
234
+ maxTokens: this.config.maxTokens ?? 4000,
235
+ };
236
+ }
130
237
  /** Clear all cached managers (useful for testing or refresh). */
131
238
  clearCache() {
132
239
  this.managers.clear();
@@ -164,6 +271,32 @@ export class ProjectAnchorStore {
164
271
  tags: anchor.tags,
165
272
  });
166
273
  },
274
+ update: (id, patch) => {
275
+ const projId = this.config.getCurrentProjectId();
276
+ const updated = this.updateAnchor(id, patch, projId == null ? null : String(projId));
277
+ if (!updated)
278
+ return Promise.resolve(null);
279
+ return Promise.resolve({
280
+ id: updated.id,
281
+ content: updated.content,
282
+ priority: updated.priority,
283
+ scope: updated.projectId === undefined ? 'global' : 'project',
284
+ tags: updated.tags,
285
+ });
286
+ },
287
+ get: (id) => {
288
+ const projId = this.config.getCurrentProjectId();
289
+ const found = this.findAnchor(id, projId == null ? null : String(projId));
290
+ if (!found)
291
+ return Promise.resolve(null);
292
+ return Promise.resolve({
293
+ id: found.anchor.id,
294
+ content: found.anchor.content,
295
+ priority: found.anchor.priority,
296
+ scope: found.projectKey === null ? 'global' : 'project',
297
+ tags: found.anchor.tags,
298
+ });
299
+ },
167
300
  remove: (id) => {
168
301
  let removed = false;
169
302
  let scope;
@@ -23,6 +23,21 @@ export interface IAnchorService {
23
23
  removed: boolean;
24
24
  scope?: string;
25
25
  }>;
26
+ /**
27
+ * Edit an anchor in place, keeping its id.
28
+ *
29
+ * Optional so existing hosts are unaffected. Without it a caller has to remove and re-add,
30
+ * which mints a new id — anything holding the old one (an open tab, a row in a list) is then
31
+ * pointing at an anchor that no longer exists.
32
+ */
33
+ update?(id: string, patch: {
34
+ content?: string;
35
+ priority?: AnchorPriority;
36
+ tags?: string[];
37
+ scope?: 'global' | 'project';
38
+ }): Promise<AnchorData | null>;
39
+ /** One anchor by id, or null. */
40
+ get?(id: string): Promise<AnchorData | null>;
26
41
  list(options?: {
27
42
  scope?: 'global' | 'project' | 'all';
28
43
  priority?: AnchorPriority;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/sdk",
3
- "version": "0.29.5",
3
+ "version": "0.29.7",
4
4
  "description": "Universal agent runtime for building AI-powered applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,17 +0,0 @@
1
- /**
2
- * Action Registry — Defines which actions are available and where.
3
- *
4
- * Each action maps to a skill (from platformMacros/builtinSkills)
5
- * but adds UI metadata: icon, label, category, applicable contexts,
6
- * and suggested agent role.
7
- */
8
- import type { ActionDefinition } from './types.js';
9
- export declare const ACTION_REGISTRY: ActionDefinition[];
10
- /**
11
- * Get actions applicable to a given context type.
12
- */
13
- export declare function getActionsForContext(contextType: 'project' | 'workitem' | 'document'): ActionDefinition[];
14
- /**
15
- * Get an action definition by ID.
16
- */
17
- export declare function getActionById(id: string): ActionDefinition | undefined;
@@ -1,161 +0,0 @@
1
- /**
2
- * Action Registry — Defines which actions are available and where.
3
- *
4
- * Each action maps to a skill (from platformMacros/builtinSkills)
5
- * but adds UI metadata: icon, label, category, applicable contexts,
6
- * and suggested agent role.
7
- */
8
- export const ACTION_REGISTRY = [
9
- // ─── Project-level actions ─────────────────────────────────────────────
10
- {
11
- id: 'design',
12
- label: 'Design App',
13
- description: 'Describe an idea, get a full application design',
14
- icon: 'Wand2',
15
- applicableTo: ['project'],
16
- category: 'design',
17
- // BA owns requirements: the 'ba' role (analyst profile) has both
18
- // backlog_write and documents, so it can complete the full /design action
19
- // (create work items + write the PRD). The architect profile lacks
20
- // backlog_write and cannot create the backlog.
21
- suggestedRole: 'ba',
22
- needsInput: true,
23
- inputPrompt: 'What would you like to design?',
24
- },
25
- {
26
- id: 'sketch',
27
- label: 'Quick Sketch',
28
- description: 'Quickly sketch out an idea or concept',
29
- icon: 'Pencil',
30
- applicableTo: ['project'],
31
- category: 'design',
32
- needsInput: true,
33
- inputPrompt: 'What would you like to sketch?',
34
- },
35
- {
36
- id: 'prd',
37
- label: 'Write PRD',
38
- description: 'Create a product requirements document',
39
- icon: 'FileText',
40
- applicableTo: ['project'],
41
- // PRD is artifact-authoring (requirements), grouped with design/architecture
42
- // rather than backlog-breakdown 'planning' (refine/refine-item).
43
- category: 'design',
44
- // Requirements work → Business Analyst, not PM. The 'ba' role (analyst
45
- // profile) is purpose-built for requirements gathering and has the
46
- // documents tools needed to author the PRD.
47
- suggestedRole: 'ba',
48
- },
49
- {
50
- id: 'architecture',
51
- label: 'Architecture',
52
- description: 'Design the system architecture',
53
- icon: 'Network',
54
- applicableTo: ['project'],
55
- category: 'design',
56
- suggestedRole: 'architect',
57
- },
58
- {
59
- id: 'scaffold',
60
- label: 'Scaffold',
61
- description: 'Generate project code from the app model',
62
- icon: 'Layers',
63
- applicableTo: ['project'],
64
- category: 'development',
65
- suggestedRole: 'developer',
66
- },
67
- {
68
- id: 'session-notes',
69
- label: 'Session Notes',
70
- description: 'Summarize what was accomplished in this session',
71
- icon: 'StickyNote',
72
- applicableTo: ['project'],
73
- category: 'documentation',
74
- },
75
- // ─── Work item actions ─────────────────────────────────────────────────
76
- {
77
- id: 'refine',
78
- label: 'Refine',
79
- description: 'Break down into smaller tasks',
80
- icon: 'RefreshCw',
81
- applicableTo: ['project', 'workitem'],
82
- category: 'planning',
83
- suggestedRole: 'pm',
84
- },
85
- {
86
- id: 'refine-item',
87
- label: 'Refine Item',
88
- description: 'Add detail and acceptance criteria to this item',
89
- icon: 'RefreshCw',
90
- applicableTo: ['workitem'],
91
- category: 'planning',
92
- suggestedRole: 'pm',
93
- },
94
- {
95
- id: 'build',
96
- label: 'Build',
97
- description: 'Implement this work item',
98
- icon: 'Hammer',
99
- applicableTo: ['workitem'],
100
- category: 'development',
101
- suggestedRole: 'developer',
102
- },
103
- {
104
- id: 'code-review',
105
- label: 'Code Review',
106
- description: 'Review code for quality and correctness',
107
- icon: 'Search',
108
- applicableTo: ['project', 'workitem'],
109
- category: 'development',
110
- suggestedRole: 'qa',
111
- },
112
- {
113
- id: 'debug',
114
- label: 'Debug',
115
- description: 'Debug an issue or error',
116
- icon: 'Bug',
117
- applicableTo: ['project', 'workitem'],
118
- category: 'development',
119
- suggestedRole: 'developer',
120
- },
121
- // ─── Document actions ──────────────────────────────────────────────────
122
- {
123
- id: 'explain',
124
- label: 'Explain',
125
- description: 'Explain this code or document',
126
- icon: 'BookOpen',
127
- applicableTo: ['document', 'workitem'],
128
- category: 'documentation',
129
- },
130
- // ─── Analysis actions ──────────────────────────────────────────────────
131
- {
132
- id: 'security-review',
133
- label: 'Security Review',
134
- description: 'Review for security vulnerabilities',
135
- icon: 'Shield',
136
- applicableTo: ['project'],
137
- category: 'analysis',
138
- suggestedRole: 'security',
139
- },
140
- {
141
- id: 'refactor',
142
- label: 'Refactor',
143
- description: 'Improve code quality without changing behavior',
144
- icon: 'Scissors',
145
- applicableTo: ['project', 'workitem'],
146
- category: 'development',
147
- suggestedRole: 'developer',
148
- },
149
- ];
150
- /**
151
- * Get actions applicable to a given context type.
152
- */
153
- export function getActionsForContext(contextType) {
154
- return ACTION_REGISTRY.filter((a) => a.applicableTo.includes(contextType));
155
- }
156
- /**
157
- * Get an action definition by ID.
158
- */
159
- export function getActionById(id) {
160
- return ACTION_REGISTRY.find((a) => a.id === id);
161
- }