archgraph-argo 0.22.1 → 0.22.2

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.
@@ -893,11 +893,42 @@ function fullProjection(graph, qeaPath, opts) {
893
893
  // ---------------------------------------------------------------------------
894
894
  // Export
895
895
  // ---------------------------------------------------------------------------
896
+ // EA stores connector layout in two distinct t_diagramlinks columns, and they mean
897
+ // different things:
898
+ // - Path = the connector ROUTE: user-adjusted bend points as "x:y;x:y;" in diagram
899
+ // coordinates (empty when EA auto-routes a straight/orthogonal line).
900
+ // - Geometry = the non-route OVERRIDE tokens (SX/SY/EX/EY dock offsets, EDGE route
901
+ // style and label positions). It never contains bend points.
902
+ // Reading Geometry as if it were the line was the original defect: callers got the
903
+ // override string and could not rebuild the connector. We expose the route under `path`
904
+ // (+ parsed `points`), the route style as `edge`, and keep the override as `geometry`.
905
+ function parseRoutePoints(raw) {
906
+ const s = String(raw === null || raw === undefined ? '' : raw).trim();
907
+ if (s === '') { return []; }
908
+ const points = [];
909
+ for (const seg of s.split(';')) {
910
+ const t = seg.trim();
911
+ if (t === '') { continue; }
912
+ const parts = t.split(':');
913
+ if (parts.length < 2) { continue; }
914
+ const x = Number(parts[0]);
915
+ const y = Number(parts[1]);
916
+ if (!Number.isFinite(x) || !Number.isFinite(y)) { continue; }
917
+ points.push({ x, y });
918
+ }
919
+ return points;
920
+ }
921
+ function parseEdgeToken(geometry) {
922
+ const m = /(?:^|;)EDGE=(-?\d+)(?:;|$)/.exec(String(geometry === null || geometry === undefined ? '' : geometry));
923
+ return m ? Number(m[1]) : null;
924
+ }
925
+
896
926
  // Read the EA diagram GEOMETRY for one KG view from a .qea model (read-only).
897
927
  // The view maps to the diagram anchored by the deterministic ea_guid (diag:<viewId>)
898
928
  // or the schema_view_id StyleEx token written by the sync. Returns:
899
929
  // - element boxes = t_diagramobjects rects joined to t_object.Alias (schema id)
900
- // - connector lines = t_diagramlinks rows joined to the connector's schema_id tag
930
+ // - connector lines = t_diagramlinks rows joined to the connector's schema_id tag,
931
+ // with the ROUTE (t_diagramlinks.Path) parsed into `points`
901
932
  // Returns null when the view has no matching EA diagram. Never writes EA geometry.
902
933
  function readViewDiagramGeometry(qeaPath, viewId) {
903
934
  const v = String(viewId === null || viewId === undefined ? '' : viewId).trim();
@@ -920,13 +951,14 @@ function readViewDiagramGeometry(qeaPath, viewId) {
920
951
  left: Number(r.left), top: Number(r.top), right: Number(r.right), bottom: Number(r.bottom),
921
952
  }));
922
953
  const relationships = db.prepare(
923
- 'SELECT t.VALUE AS id, dl.Geometry AS path ' +
954
+ 'SELECT t.VALUE AS id, dl.Path AS path, dl.Geometry AS geometry ' +
924
955
  'FROM t_diagramlinks dl JOIN t_connectortag t ON t.ElementID = dl.ConnectorID AND t.Property = ? ' +
925
956
  'WHERE dl.DiagramID = ? ORDER BY dl.ConnectorID'
926
- ).all('schema_id', diagramId).map((r) => ({
927
- id: String(r.id),
928
- path: String(r.path === null || r.path === undefined ? '' : r.path),
929
- }));
957
+ ).all('schema_id', diagramId).map((r) => {
958
+ const path = String(r.path === null || r.path === undefined ? '' : r.path);
959
+ const geometry = String(r.geometry === null || r.geometry === undefined ? '' : r.geometry);
960
+ return { id: String(r.id), path, points: parseRoutePoints(path), edge: parseEdgeToken(geometry), geometry };
961
+ });
930
962
  return { diagramId, elements, relationships };
931
963
  } finally {
932
964
  try { db.close(); } catch { /* ignore */ }
@@ -226,7 +226,7 @@ const TOOLS = [
226
226
  },
227
227
  {
228
228
  name: 'getArchitectureViewContext',
229
- description: 'read-only query that resolves one view by view_id into its complete membership: the view object, every member element (from included_elements), every member relationship (from included_relationships), the parent element, and optionally child sub-views declared by member elements. Resolves ids into full canonical objects instead of returning raw id lists. Optional includeEaGeometry (default false) additionally returns the EA diagram geometry of the resolved view.',
229
+ description: 'read-only query that resolves one view by view_id into its complete membership: the view object, every member element (from included_elements), every member relationship (from included_relationships), the parent element, and optionally child sub-views declared by member elements. Resolves ids into full canonical objects instead of returning raw id lists. Optional includeEaGeometry (default false) additionally returns the EA diagram geometry of the resolved view: element boxes plus each connector ROUTE (t_diagramlinks.Path as `path` + parsed `points`, with the non-route Geometry override kept separately under `geometry`).',
230
230
  inputSchema: viewContextInputSchema(),
231
231
  },
232
232
  {
@@ -475,7 +475,7 @@ function viewContextInputSchema() {
475
475
  view_id: { type: 'string', description: 'The id of the view to resolve.' },
476
476
  includeParentElement: { type: 'boolean', description: 'Default: true. Resolve the parent element referenced by the view.' },
477
477
  includeChildViews: { type: 'boolean', description: 'Default: false. Include child views declared by member elements through subdiagram_views.' },
478
- includeEaGeometry: { type: 'boolean', description: 'Default: false (opt-in). When true, additionally resolve the diagram GEOMETRY (element boxes + connector line paths) for this view from the workspace EA model (.qea) and return it under a `geometry` field aligned by schema id with the resolved members. By default the EA model is never touched and no `geometry` field is returned; a missing EA model/diagram yields geometry.present=false, never an error.' },
478
+ includeEaGeometry: { type: 'boolean', description: 'Default: false (opt-in). When true, additionally resolve the diagram GEOMETRY (element boxes + connector line routes) for this view from the workspace EA model (.qea) and return it under a `geometry` field aligned by schema id with the resolved members. Each geometry relationship carries: `path` (the EA route from t_diagramlinks.Path, "" when EA auto-routes), `points` (the parsed [{x,y}] waypoints), `edge` (the EDGE route-style token or null) and `geometry` (the raw SX/SY/EX/EY override string, which contains NO waypoints). By default the EA model is never touched and no `geometry` field is returned; a missing EA model/diagram yields geometry.present=false, never an error.' },
479
479
  },
480
480
  additionalProperties: false,
481
481
  };
@@ -726,9 +726,11 @@ function buildIntentElementContext(context, args = {}) {
726
726
  // model unless the caller explicitly sets includeEaGeometry=true. The workspace's
727
727
  // EA model (.qea, the SQLite carrier this toolchain can read) may hold human-laid-out
728
728
  // diagram geometry for a view — element boxes (t_diagramobjects rects) and connector
729
- // line paths (t_diagramlinks). When present it is returned under `geometry`, aligned
729
+ // routes (t_diagramlinks.Path). When present it is returned under `geometry`, aligned
730
730
  // by schema id with the resolved members, so an image-capable LLM can redraw the view
731
- // faithfully. Absent model/diagram present:false (never an error).
731
+ // faithfully. Each connector also carries the non-route t_diagramlinks.Geometry override
732
+ // string under a distinct `geometry` key, so the route is never confused with the
733
+ // SX/SY/EX/EY/EDGE tokens. Absent model/diagram → present:false (never an error).
732
734
  const EA_GEOMETRY_MODEL_EXTENSIONS = new Set(['.qea']);
733
735
  function findEaGeometryModelPath(workspaceRoot) {
734
736
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archgraph-argo",
3
- "version": "0.22.1",
3
+ "version": "0.22.2",
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": {