engineering-memory 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "engineering-memory",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "Installs the Engineering Memory skill and its local MCP bridge. Sign in after installing; your organization and project are resolved from your account.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -48,6 +48,7 @@ export class GitInspector {
48
48
  repoRoot: root,
49
49
  head,
50
50
  changedPaths,
51
+ worktreeHash: sha256(`${stableStringify(normalizedManifest)}\n`),
51
52
  diffHash: sha256(`${head ?? '<unborn>'}\n${stableStringify(normalizedManifest)}\n`),
52
53
  };
53
54
  }
@@ -81,6 +81,13 @@ export const engineeringMemoryToolNames = [
81
81
  'auth.signin_browser',
82
82
  'auth.logout',
83
83
  ];
84
+ const discoverableKindNames = [
85
+ 'screen_logic',
86
+ 'component_mapping',
87
+ 'module_logic',
88
+ 'data_model',
89
+ 'api_endpoint',
90
+ ];
84
91
  const reconciliationEntry = z.object({
85
92
  resourceId: z.string().min(1),
86
93
  type: z.enum(['approved_revision', 'no_semantic_memory_change']),
@@ -193,6 +200,9 @@ export function registerEngineeringMemoryTools(server, service) {
193
200
  'figma_mapping',
194
201
  'figma_reference',
195
202
  'flow_logic',
203
+ 'module_logic',
204
+ 'data_model',
205
+ 'api_endpoint',
196
206
  'current_deviation',
197
207
  'quality_gate',
198
208
  'task_history',
@@ -348,7 +358,7 @@ export function registerEngineeringMemoryTools(server, service) {
348
358
  newResources: z
349
359
  .array(z.object({
350
360
  path: z.string().min(1),
351
- kind: z.enum(['screen_logic', 'component_mapping']),
361
+ kind: z.enum(discoverableKindNames),
352
362
  resourceKey: z.string().min(2),
353
363
  }))
354
364
  .optional(),
@@ -382,13 +392,7 @@ export function registerEngineeringMemoryTools(server, service) {
382
392
  content: z.string().min(2),
383
393
  discoveryUnits: z
384
394
  .array(z.object({
385
- kind: z.enum([
386
- 'screen_logic',
387
- 'component_mapping',
388
- 'module_logic',
389
- 'data_model',
390
- 'api_endpoint',
391
- ]),
395
+ kind: z.enum(discoverableKindNames),
392
396
  patterns: z.array(z.string().min(1)).min(1),
393
397
  }))
394
398
  .min(1)
@@ -94,7 +94,9 @@ export class BridgeService {
94
94
  taskKind: persistedBootstrap.taskKind,
95
95
  mode: persistedBootstrap.mode ?? 'write',
96
96
  repoFingerprint: repository.repoFingerprint,
97
- ...(input.mode === 'read_only' ? { baselineDiffHash: repository.git.diffHash } : {}),
97
+ ...(input.mode === 'read_only'
98
+ ? { baselineDiffHash: repository.git.worktreeHash }
99
+ : {}),
98
100
  checkpointIdempotencyKey: checkpointId,
99
101
  knownRevisions: persistedBootstrap.knownRevisions,
100
102
  }),
@@ -1009,6 +1011,7 @@ export class BridgeService {
1009
1011
  changedPaths: taskMode === 'read_only' ? [] : taskChangedPaths,
1010
1012
  pathChanges: pathChangeManifest,
1011
1013
  diffHash: repository.git.diffHash,
1014
+ ...(taskMode === 'read_only' ? { worktreeHash: repository.git.worktreeHash } : {}),
1012
1015
  validations,
1013
1016
  pendingOutboxCount,
1014
1017
  newResources: input.newResources,
@@ -1305,12 +1308,19 @@ export class BridgeService {
1305
1308
  const authenticated = authentication.authenticated === true;
1306
1309
  const state = decision?.state ?? (repository.projectId ? 'bound' : 'none');
1307
1310
  const client = await this.clientUpdate(authenticated);
1311
+ const shipped = objectValue(objectValue(client)?.shippedKnowledge);
1312
+ const incomplete = shipped && (shipped.failure !== null || Number(shipped.live) < Number(shipped.expected));
1308
1313
  return asJsonValue({
1309
1314
  authenticated,
1310
1315
  repository: publicRepository(repository),
1311
1316
  decision: state,
1312
1317
  projectId: repository.projectId ?? decision?.projectId ?? null,
1313
1318
  client,
1319
+ ...(incomplete
1320
+ ? {
1321
+ shippedKnowledgeWarning: 'The backend is not serving all of the knowledge this release ships. Tell the user before relying on the rules: some are missing from the running server, so a review against them is incomplete. The counts and the reason are in client.shippedKnowledge.',
1322
+ }
1323
+ : {}),
1314
1324
  nextAction: entryNextAction(authenticated, state),
1315
1325
  });
1316
1326
  });
@@ -2393,6 +2403,16 @@ export function newMemoryResourceCandidate(entry, policy) {
2393
2403
  ]).has(extension)) {
2394
2404
  return [];
2395
2405
  }
2406
+ const name = entry.path.toLowerCase().split('/').slice(-1)[0] ?? '';
2407
+ if (name.endsWith('.entity.ts')) {
2408
+ return [{ path: entry.path, kind: 'data_model' }];
2409
+ }
2410
+ if (name.endsWith('.controller.ts')) {
2411
+ return [{ path: entry.path, kind: 'api_endpoint' }];
2412
+ }
2413
+ if (name.endsWith('.module.ts') || name.endsWith('.service.ts')) {
2414
+ return [{ path: entry.path, kind: 'module_logic' }];
2415
+ }
2396
2416
  const segments = entry.path.toLowerCase().split('/').slice(0, -1);
2397
2417
  const screenIndex = segments.findIndex((segment) => ['screen', 'screens', 'view', 'views'].includes(segment));
2398
2418
  const componentIndex = segments.findIndex((segment) => ['widget', 'widgets', 'component', 'components'].includes(segment));