archgraph-argo 0.10.13 → 0.10.15

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.
@@ -1041,6 +1041,7 @@ function applyMutations(document, mutations) {
1041
1041
  const existingElement = findById(nextDocument.elements, mutation.element.id);
1042
1042
  if (!existingElement) {
1043
1043
  nextDocument.elements.push(clone(mutation.element));
1044
+ syncViewsToElementSubdiagramViews(nextDocument, findById(nextDocument.elements, mutation.element.id));
1044
1045
  }
1045
1046
  for (const view of scopedViews) {
1046
1047
  view.included_elements = addUnique(view.included_elements || [], [mutation.element.id]);
@@ -1065,7 +1066,12 @@ function applyMutations(document, mutations) {
1065
1066
  throw new Error(`Element '${mutation.id}' does not exist`);
1066
1067
  }
1067
1068
  requirePatchDoesNotChangeElementIdentityOrType(mutation.id, mutation.patch);
1069
+ const patchesSubdiagramViews = Object.prototype.hasOwnProperty.call(mutation.patch, 'subdiagram_views');
1070
+ const patchesName = Object.prototype.hasOwnProperty.call(mutation.patch, 'name');
1068
1071
  Object.assign(element, clone(mutation.patch));
1072
+ if (patchesSubdiagramViews || patchesName) {
1073
+ reconcileSubdiagramViewsForElement(nextDocument, element);
1074
+ }
1069
1075
  touchedElementIds.add(element.id);
1070
1076
  mutationSummaries.push({ type: mutation.type, id: element.id });
1071
1077
  continue;
@@ -1077,6 +1083,10 @@ function applyMutations(document, mutations) {
1077
1083
  if (!element) {
1078
1084
  throw new Error(`Element '${mutation.id}' does not exist`);
1079
1085
  }
1086
+ const childViewIds = collectChildViewIds(nextDocument, mutation.id);
1087
+ if (childViewIds.length > 0) {
1088
+ throw new Error(`Element '${mutation.id}' cannot be removed: it still has ${childViewIds.length} sub-view(s) mounted under it (${childViewIds.join(', ')}). Remove or re-parent those sub-views first.`);
1089
+ }
1080
1090
  const scopedViews = mutation.view_ids === undefined
1081
1091
  ? nextDocument.views
1082
1092
  : requireViewScope(nextDocument.views, mutation.view_ids, 'mutation.view_ids');
@@ -1155,13 +1165,25 @@ function applyMutations(document, mutations) {
1155
1165
  throw new Error(`Relationship '${mutation.id}' does not exist`);
1156
1166
  }
1157
1167
  requirePatchDoesNotChangeRelationshipIdentityOrType(mutation.id, mutation.patch);
1168
+ const oldSourceId = relationship.source_id;
1169
+ const oldTargetId = relationship.target_id;
1158
1170
  Object.assign(relationship, clone(mutation.patch));
1159
1171
  for (const view of nextDocument.views) {
1160
- if ((view.included_relationships || []).includes(relationship.id)) {
1161
- view.included_elements = addUnique(view.included_elements || [], [
1162
- relationship.source_id,
1163
- relationship.target_id,
1164
- ]);
1172
+ if (!(view.included_relationships || []).includes(relationship.id)) {
1173
+ continue;
1174
+ }
1175
+ view.included_elements = addUnique(view.included_elements || [], [
1176
+ relationship.source_id,
1177
+ relationship.target_id,
1178
+ ]);
1179
+ for (const oldEndpointId of [oldSourceId, oldTargetId]) {
1180
+ if (oldEndpointId === relationship.source_id || oldEndpointId === relationship.target_id) {
1181
+ continue;
1182
+ }
1183
+ if (isElementUsedByRelationship(nextDocument, view, oldEndpointId, relationship.id)) {
1184
+ continue;
1185
+ }
1186
+ view.included_elements = removeEntries(view.included_elements || [], [oldEndpointId]);
1165
1187
  }
1166
1188
  }
1167
1189
  touchedRelationshipIds.add(relationship.id);
@@ -1180,6 +1202,12 @@ function applyMutations(document, mutations) {
1180
1202
  : requireViewScope(nextDocument.views, mutation.view_ids, 'mutation.view_ids');
1181
1203
  for (const view of scopedViews) {
1182
1204
  view.included_relationships = removeEntries(view.included_relationships || [], [mutation.id]);
1205
+ for (const endpointId of [relationship.source_id, relationship.target_id]) {
1206
+ if (isElementUsedByRelationship(nextDocument, view, endpointId, mutation.id)) {
1207
+ continue;
1208
+ }
1209
+ view.included_elements = removeEntries(view.included_elements || [], [endpointId]);
1210
+ }
1183
1211
  touchedViewIds.add(view.view_id);
1184
1212
  }
1185
1213
  const stillIncludedInView = nextDocument.views.some(view => (
@@ -1349,6 +1377,78 @@ function upsertSubdiagramViewIntoElement(document, elementId, view) {
1349
1377
  }
1350
1378
  }
1351
1379
 
1380
+ // Forward-sync: make every view listed in `element.subdiagram_views` point back
1381
+ // to this element (stealing the view from any previous parent when necessary).
1382
+ function syncViewsToElementSubdiagramViews(document, element) {
1383
+ if (!element || !Array.isArray(element.subdiagram_views)) {
1384
+ return;
1385
+ }
1386
+ for (const entry of element.subdiagram_views) {
1387
+ if (!entry || !entry.view_id) {
1388
+ continue;
1389
+ }
1390
+ const view = findView(document.views, entry.view_id);
1391
+ if (!view) {
1392
+ continue;
1393
+ }
1394
+ if (view.parent_element_id && view.parent_element_id !== element.id) {
1395
+ removeSubdiagramViewFromElement(document, view.parent_element_id, view.view_id);
1396
+ }
1397
+ view.parent_element_id = element.id;
1398
+ view.parent_element_name = element.name;
1399
+ }
1400
+ }
1401
+
1402
+ // Bidirectional sync after an element's subdiagram_views (or name) changed:
1403
+ // listed views point back, and views no longer listed stop pointing at this element.
1404
+ function reconcileSubdiagramViewsForElement(document, element) {
1405
+ const currentViewIds = new Set(
1406
+ (element.subdiagram_views || [])
1407
+ .filter(entry => entry && entry.view_id)
1408
+ .map(entry => entry.view_id),
1409
+ );
1410
+ syncViewsToElementSubdiagramViews(document, element);
1411
+ for (const view of document.views || []) {
1412
+ if (view && view.parent_element_id === element.id && !currentViewIds.has(view.view_id)) {
1413
+ delete view.parent_element_id;
1414
+ delete view.parent_element_name;
1415
+ }
1416
+ }
1417
+ }
1418
+
1419
+ function collectChildViewIds(document, elementId) {
1420
+ const viewIds = new Set();
1421
+ const element = findById(document.elements, elementId);
1422
+ if (element && Array.isArray(element.subdiagram_views)) {
1423
+ for (const entry of element.subdiagram_views) {
1424
+ if (entry && entry.view_id) {
1425
+ viewIds.add(entry.view_id);
1426
+ }
1427
+ }
1428
+ }
1429
+ for (const view of document.views || []) {
1430
+ if (view && view.parent_element_id === elementId && view.view_id) {
1431
+ viewIds.add(view.view_id);
1432
+ }
1433
+ }
1434
+ return Array.from(viewIds);
1435
+ }
1436
+
1437
+ // Whether any relationship in the view (other than exceptRelationshipId) still
1438
+ // references elementId as one of its endpoints.
1439
+ function isElementUsedByRelationship(document, view, elementId, exceptRelationshipId) {
1440
+ for (const relationshipId of view.included_relationships || []) {
1441
+ if (relationshipId === exceptRelationshipId) {
1442
+ continue;
1443
+ }
1444
+ const relationship = findById(document.relationships, relationshipId);
1445
+ if (relationship && (relationship.source_id === elementId || relationship.target_id === elementId)) {
1446
+ return true;
1447
+ }
1448
+ }
1449
+ return false;
1450
+ }
1451
+
1352
1452
  function addUnique(existing, additions) {
1353
1453
  const result = Array.isArray(existing) ? [...existing] : [];
1354
1454
  for (const addition of additions) {
package/install-argo.ps1 CHANGED
@@ -726,7 +726,7 @@ if ($SkipDsh) {
726
726
  Write-DshManagedBlock -Path $patchPath -Block $block -MarkerStart '# BEGIN ArchGraph ARGO deployment' -MarkerEnd '# END ArchGraph ARGO deployment'
727
727
  }
728
728
 
729
- Write-Host "[19/19] argo\agents2 -> $DshHome\.agent-presets\<id> (DeepSeek Harness agent presets)"
729
+ Write-Host "[19/19] argo\agents5 -> $DshHome\.agent-presets\<id> (DeepSeek Harness agent presets)"
730
730
  New-DshAgentPresets -DshHome $DshHome -AgentsSrc (Join-Path $argoDir 'agents')
731
731
 
732
732
  Write-Host ' Restart `dsh web` to activate the MCP bridge and the wakeup plugin;'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archgraph-argo",
3
- "version": "0.10.13",
3
+ "version": "0.10.15",
4
4
  "description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
5
5
  "license": "MIT",
6
6
  "bin": {