@unified-product-graph/mcp-server 0.7.5 → 0.7.6
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/CHANGELOG.md +12 -0
- package/TOOLS.md +93 -73
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -1
- package/dist/tools-manifest.json +352 -101
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@unified-product-graph/mcp-server` are documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
4
4
|
|
|
5
|
+
## [0.7.6] - 2026-05-30
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`start` tool (UPG-525):** a zero-state on-ramp. An empty or barely-started graph gives an agent nothing to plan against; `start` reads the live graph and recommends the first canonical playbook (from `UPG_PLAYBOOKS`) plus the exact `create_node` call for its anchor entity. Young graphs (< 8 non-product nodes) get the first canonical playbook whose anchor isn't present yet; established graphs are routed to `plan` / `inspect` / `get_graph_digest`. 94 tools total.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **`create_node` orphan warning (UPG-525):** when a node lands with no parent and its type sits at position > 0 in its domain's creation sequence (the spec expects it under the domain anchor), the response carries a warning naming the typical parent and the canonical edge. Anchors, roots, and guide-less types never warn.
|
|
14
|
+
- **Tool reference return shapes are now authored-source-derived (UPG-556):** the generator parses each tool's `@returns` prose into a structured `return_shape` / `return_notes` at build time, shipped on the manifest. Fixed a `create_node` `@returns` wrap artifact at source.
|
|
15
|
+
- **Dissolved the singleton `Migrations` and `Skills Introspection` tool-reference sections (UPG-557):** `migrate_status` now groups under Nodes and `skill_audit` under Validation, without moving the source. Reference drops from 11 to 9 domains.
|
|
16
|
+
|
|
5
17
|
## [0.6.3] - 2026-05-27
|
|
6
18
|
|
|
7
19
|
### Changed
|
package/TOOLS.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# UPG MCP Server: Tool Reference
|
|
2
2
|
|
|
3
|
-
Reference for the
|
|
3
|
+
Reference for the 94 tools exposed by `@unified-product-graph/mcp-server`. Generated from JSDoc on `src/tools/*.ts` (do not edit by hand).
|
|
4
4
|
|
|
5
5
|
## Contents
|
|
6
6
|
|
|
7
|
-
- [Context & Session](#context-session):
|
|
8
|
-
- [Nodes](#nodes):
|
|
7
|
+
- [Context & Session](#context-session): 5 tools
|
|
8
|
+
- [Nodes](#nodes): 15 tools
|
|
9
9
|
- [Edges](#edges): 9 tools
|
|
10
10
|
- [Areas & Change Log](#areas-change-log): 5 tools
|
|
11
11
|
- [Workspace & Portfolios](#workspace-portfolios): 10 tools
|
|
12
12
|
- [Schema](#schema): 1 tool
|
|
13
13
|
- [Spec Introspection](#spec-introspection): 43 tools
|
|
14
14
|
- [Cloud Sync](#cloud-sync): 3 tools
|
|
15
|
-
- [Validation](#validation):
|
|
16
|
-
- [Migrations](#migrations): 1 tool
|
|
17
|
-
- [Skills Introspection](#skills-introspection): 1 tool
|
|
15
|
+
- [Validation](#validation): 3 tools
|
|
18
16
|
|
|
19
17
|
## Context & Session
|
|
20
18
|
|
|
@@ -23,6 +21,7 @@ _Product overview, graph digest, lens-aware session state._
|
|
|
23
21
|
- [`get_graph_digest`](#get-graph-digest)
|
|
24
22
|
- [`get_product_context`](#get-product-context)
|
|
25
23
|
- [`get_session_context`](#get-session-context)
|
|
24
|
+
- [`start`](#start)
|
|
26
25
|
- [`update_session_context`](#update-session-context)
|
|
27
26
|
|
|
28
27
|
### `get_graph_digest`
|
|
@@ -116,6 +115,37 @@ dedup rule from prose.
|
|
|
116
115
|
**See also:** `update_session_context`
|
|
117
116
|
|
|
118
117
|
|
|
118
|
+
### `start`
|
|
119
|
+
|
|
120
|
+
Zero-state on-ramp: "there is nothing here yet, where do I begin?". Reads the live graph and, for an empty or barely-started graph, recommends the first canonical playbook (from UPG_PLAYBOOKS) plus the exact create_node call for its anchor entity. Established graphs are routed to plan / inspect / get_graph_digest instead. Takes no arguments.
|
|
121
|
+
|
|
122
|
+
**Atomicity:** `atomic (read-only)`
|
|
123
|
+
|
|
124
|
+
_No arguments._
|
|
125
|
+
|
|
126
|
+
**Returns:**
|
|
127
|
+
|
|
128
|
+
JSON: `{ graph_state: "empty" | "young" | "established", product,
|
|
129
|
+
node_count, recommended_playbook?, first_action?, recommendation,
|
|
130
|
+
next_tools }`. `recommended_playbook` and `first_action` are present only
|
|
131
|
+
for empty/young graphs.
|
|
132
|
+
|
|
133
|
+
**Examples:**
|
|
134
|
+
|
|
135
|
+
// Input (empty graph):
|
|
136
|
+
{}
|
|
137
|
+
// Output (truncated):
|
|
138
|
+
{
|
|
139
|
+
"graph_state": "empty",
|
|
140
|
+
"node_count": 0,
|
|
141
|
+
"recommended_playbook": { "id": "playbook:users-needs", "name": "Users & Needs", "target_anchor_entity": "persona" },
|
|
142
|
+
"first_action": { "tool": "create_node", "args": { "type": "persona", "title": "<your first persona>" } },
|
|
143
|
+
"recommendation": "Your graph is empty. Begin with the \"Users & Needs\" playbook: create your first persona."
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
**See also:** `plan`, `get_playbook`, `list_playbooks`, `get_graph_digest`
|
|
147
|
+
|
|
148
|
+
|
|
119
149
|
### `update_session_context`
|
|
120
150
|
|
|
121
151
|
Update session context: register a skill invocation, record a recommendation, set focus area, switch lens, or store custom state for cross-skill coordination.
|
|
@@ -145,7 +175,7 @@ new state.
|
|
|
145
175
|
|
|
146
176
|
## Nodes
|
|
147
177
|
|
|
148
|
-
_Read, search, traverse, mutate, batch, migrate, dedupe._
|
|
178
|
+
_Read, search, traverse, mutate, batch, migrate type/properties/status, dedupe._
|
|
149
179
|
|
|
150
180
|
- [`batch_create_nodes`](#batch-create-nodes)
|
|
151
181
|
- [`batch_delete_nodes`](#batch-delete-nodes)
|
|
@@ -157,6 +187,7 @@ _Read, search, traverse, mutate, batch, migrate, dedupe._
|
|
|
157
187
|
- [`get_nodes`](#get-nodes)
|
|
158
188
|
- [`list_nodes`](#list-nodes)
|
|
159
189
|
- [`migrate_properties`](#migrate-properties)
|
|
190
|
+
- [`migrate_status`](#migrate-status)
|
|
160
191
|
- [`migrate_type`](#migrate-type)
|
|
161
192
|
- [`query`](#query)
|
|
162
193
|
- [`search_nodes`](#search-nodes)
|
|
@@ -262,8 +293,8 @@ Create one entity, optionally with a parent edge. For 3+ entities, use `batch_cr
|
|
|
262
293
|
JSON: `{ node, edge?, unknown_properties?, warning? }`. The `edge`
|
|
263
294
|
field is present only when `parent_id` was supplied and a canonical
|
|
264
295
|
hierarchy edge could be inferred. `unknown_properties` and `warning` are
|
|
265
|
-
present when the caller passed properties not in the entity's schema
|
|
266
|
-
|
|
296
|
+
present when the caller passed properties not in the entity's schema.
|
|
297
|
+
Pass `strict: true` to reject unknown properties instead of
|
|
267
298
|
warning. For portfolio-scoped types the response shape is
|
|
268
299
|
`{ node, portfolio_file, written_to, warning? }` where `node` is the
|
|
269
300
|
persisted typed record.
|
|
@@ -466,6 +497,40 @@ changes (idempotent on the canonical-properties shape).
|
|
|
466
497
|
**See also:** `migrate_type`, `validate_graph`, `list_type_migrations`
|
|
467
498
|
|
|
468
499
|
|
|
500
|
+
### `migrate_status`
|
|
501
|
+
|
|
502
|
+
Apply `UPG_STATUS_MIGRATIONS` graph-wide: rewrite legacy lifecycle status values to canonical phase ids. Auto-mode (no filters) selects nodes whose current status is invalid against the entity type's lifecycle and has a registered replacement (the same invariant that drives `validate_graph` lifecycle_drift). Surgical mode (`from_status` + `to_status`) overrides the registry and rewrites every (entity_type?, from_status) match. Nodes with invalid statuses but no registered replacement surface under `skipped_no_migration`. Default `dry_run=true`; pass `dry_run=false` to commit.
|
|
503
|
+
|
|
504
|
+
**Atomicity:** `per-node. Status writes go through `store.updateNode`
|
|
505
|
+
one at a time. Dry-run is read-only.`
|
|
506
|
+
|
|
507
|
+
**Arguments:**
|
|
508
|
+
|
|
509
|
+
| Name | Type | Required | Description |
|
|
510
|
+
| ---- | ---- | -------- | ----------- |
|
|
511
|
+
| `dry_run` | boolean | | Preview changes without applying (default true). Pass false to commit. |
|
|
512
|
+
| `entity_type` | string | | Optional. Restrict the rewrite to nodes of this canonical entity type (e.g. "service", "feature"). |
|
|
513
|
+
| `from_status` | string | | Optional. Restrict the rewrite to nodes whose current status equals this exact value. When provided, `to_status` is required and the registry is bypassed. |
|
|
514
|
+
| `to_status` | string | | Required when `from_status` is provided. The canonical phase id to write. |
|
|
515
|
+
|
|
516
|
+
**Returns:**
|
|
517
|
+
|
|
518
|
+
JSON: `MigrateStatusResult`.
|
|
519
|
+
|
|
520
|
+
**Throws:**
|
|
521
|
+
|
|
522
|
+
- Returns a textError when `from_status` is provided without
|
|
523
|
+
`to_status`, or when `entity_type` is provided but isn't a string.
|
|
524
|
+
|
|
525
|
+
**Warnings (non-error surfaces):**
|
|
526
|
+
|
|
527
|
+
- Default is `dry_run: true`. Pass `dry_run: false` to commit.
|
|
528
|
+
Idempotent on retry; re-running after a successful commit reports
|
|
529
|
+
zero changes (canonical statuses pass the validity check).
|
|
530
|
+
|
|
531
|
+
**See also:** `migrate_type`, `migrate_properties`, `validate_graph`, `list_lifecycles`
|
|
532
|
+
|
|
533
|
+
|
|
469
534
|
### `migrate_type`
|
|
470
535
|
|
|
471
536
|
Migrate every entity of one type to another, applying defaults from `UPG_MIGRATIONS`. Three passes commit as one write: (1) node rename, (2) edges through `UPG_EDGE_MIGRATIONS` (catalog-aware renames, direction flips, drops; endpoint guards check post-migration types; uncatalogued edges surface as `unmapped_legacy_edges`), (3) every node through `UPG_PROPERTY_MIGRATIONS` (top-level renames, lifts, drops, self-referential cleanup). Type-specific property rules see the post-rename type.
|
|
@@ -2388,9 +2453,10 @@ target an existing one.
|
|
|
2388
2453
|
|
|
2389
2454
|
## Validation
|
|
2390
2455
|
|
|
2391
|
-
_Schema-drift detection
|
|
2456
|
+
_Schema-drift detection, full per-node drift reports, and source-vs-deployed integrity audits of UPG `/upg-*` skills._
|
|
2392
2457
|
|
|
2393
2458
|
- [`get_anti_pattern_violations_for`](#get-anti-pattern-violations-for)
|
|
2459
|
+
- [`skill_audit`](#skill-audit)
|
|
2394
2460
|
- [`validate_graph`](#validate-graph)
|
|
2395
2461
|
|
|
2396
2462
|
### `get_anti_pattern_violations_for`
|
|
@@ -2442,6 +2508,23 @@ per-id matching once `target_entities` carries ids.
|
|
|
2442
2508
|
**See also:** `validate_graph`, `list_anti_patterns`, `get_anti_pattern`, `inspect`
|
|
2443
2509
|
|
|
2444
2510
|
|
|
2511
|
+
### `skill_audit`
|
|
2512
|
+
|
|
2513
|
+
Audit one or every UPG skill for source-vs-deployed integrity. Use before recommending a skill to confirm `.claude/skills/<name>/SKILL.md` is a symlink to canonical source and the bodies match. When `in_sync: false`, what you read from `packages/upg-mcp-server/skills/` is NOT what the user will experience.
|
|
2514
|
+
|
|
2515
|
+
**Atomicity:** `atomic (read-only filesystem stat + read)`
|
|
2516
|
+
|
|
2517
|
+
**Arguments:**
|
|
2518
|
+
|
|
2519
|
+
| Name | Type | Required | Description |
|
|
2520
|
+
| ---- | ---- | -------- | ----------- |
|
|
2521
|
+
| `name` | string | | Optional skill name (e.g. "upg-trace"). If omitted, audits every canonical skill. |
|
|
2522
|
+
|
|
2523
|
+
**Returns:**
|
|
2524
|
+
|
|
2525
|
+
`{ skills: SkillAuditRecord[] }`
|
|
2526
|
+
|
|
2527
|
+
|
|
2445
2528
|
### `validate_graph`
|
|
2446
2529
|
|
|
2447
2530
|
Walk the loaded graph and return a per-class, per-node report of schema drift plus anti-pattern violations from `UPG_ANTI_PATTERNS`. Schema-drift classes: non-canonical entity types, non-canonical edge types, top-level fields outside `UPGBaseNode`, invalid status values, self-referential `source_id`/`source_type`, properties matching `UPG_PROPERTY_MIGRATIONS` rules. Anti-patterns: catalog entries that fired against the live graph, sorted high → medium → low. Each entry carries `suggested_migration` (drift) or `remediation` (anti-pattern). Top-level `valid` is true iff drift is empty AND no violations fired. Read-only; pairs with `migrate_type`, `rename_edge_type`, `get_anti_pattern_violations_for`.
|
|
@@ -2534,66 +2617,3 @@ pure spec-shape check; `skip_drift: true` for catalog-only.
|
|
|
2534
2617
|
|
|
2535
2618
|
**See also:** `migrate_type`, `migrate_properties`, `rename_edge_type`, `get_anti_pattern_violations_for`, `list_anti_patterns`, `list_type_migrations`, `list_edge_migrations`, `inspect`
|
|
2536
2619
|
|
|
2537
|
-
|
|
2538
|
-
## Migrations
|
|
2539
|
-
|
|
2540
|
-
_Status value migration across the graph._
|
|
2541
|
-
|
|
2542
|
-
- [`migrate_status`](#migrate-status)
|
|
2543
|
-
|
|
2544
|
-
### `migrate_status`
|
|
2545
|
-
|
|
2546
|
-
Apply `UPG_STATUS_MIGRATIONS` graph-wide: rewrite legacy lifecycle status values to canonical phase ids. Auto-mode (no filters) selects nodes whose current status is invalid against the entity type's lifecycle and has a registered replacement (the same invariant that drives `validate_graph` lifecycle_drift). Surgical mode (`from_status` + `to_status`) overrides the registry and rewrites every (entity_type?, from_status) match. Nodes with invalid statuses but no registered replacement surface under `skipped_no_migration`. Default `dry_run=true`; pass `dry_run=false` to commit.
|
|
2547
|
-
|
|
2548
|
-
**Atomicity:** `per-node. Status writes go through `store.updateNode`
|
|
2549
|
-
one at a time. Dry-run is read-only.`
|
|
2550
|
-
|
|
2551
|
-
**Arguments:**
|
|
2552
|
-
|
|
2553
|
-
| Name | Type | Required | Description |
|
|
2554
|
-
| ---- | ---- | -------- | ----------- |
|
|
2555
|
-
| `dry_run` | boolean | | Preview changes without applying (default true). Pass false to commit. |
|
|
2556
|
-
| `entity_type` | string | | Optional. Restrict the rewrite to nodes of this canonical entity type (e.g. "service", "feature"). |
|
|
2557
|
-
| `from_status` | string | | Optional. Restrict the rewrite to nodes whose current status equals this exact value. When provided, `to_status` is required and the registry is bypassed. |
|
|
2558
|
-
| `to_status` | string | | Required when `from_status` is provided. The canonical phase id to write. |
|
|
2559
|
-
|
|
2560
|
-
**Returns:**
|
|
2561
|
-
|
|
2562
|
-
JSON: `MigrateStatusResult`.
|
|
2563
|
-
|
|
2564
|
-
**Throws:**
|
|
2565
|
-
|
|
2566
|
-
- Returns a textError when `from_status` is provided without
|
|
2567
|
-
`to_status`, or when `entity_type` is provided but isn't a string.
|
|
2568
|
-
|
|
2569
|
-
**Warnings (non-error surfaces):**
|
|
2570
|
-
|
|
2571
|
-
- Default is `dry_run: true`. Pass `dry_run: false` to commit.
|
|
2572
|
-
Idempotent on retry; re-running after a successful commit reports
|
|
2573
|
-
zero changes (canonical statuses pass the validity check).
|
|
2574
|
-
|
|
2575
|
-
**See also:** `migrate_type`, `migrate_properties`, `validate_graph`, `list_lifecycles`
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
## Skills Introspection
|
|
2579
|
-
|
|
2580
|
-
_Verify source-vs-deployed integrity of UPG `/upg-*` skills before recommending them._
|
|
2581
|
-
|
|
2582
|
-
- [`skill_audit`](#skill-audit)
|
|
2583
|
-
|
|
2584
|
-
### `skill_audit`
|
|
2585
|
-
|
|
2586
|
-
Audit one or every UPG skill for source-vs-deployed integrity. Use before recommending a skill to confirm `.claude/skills/<name>/SKILL.md` is a symlink to canonical source and the bodies match. When `in_sync: false`, what you read from `packages/upg-mcp-server/skills/` is NOT what the user will experience.
|
|
2587
|
-
|
|
2588
|
-
**Atomicity:** `atomic (read-only filesystem stat + read)`
|
|
2589
|
-
|
|
2590
|
-
**Arguments:**
|
|
2591
|
-
|
|
2592
|
-
| Name | Type | Required | Description |
|
|
2593
|
-
| ---- | ---- | -------- | ----------- |
|
|
2594
|
-
| `name` | string | | Optional skill name (e.g. "upg-trace"). If omitted, audits every canonical skill. |
|
|
2595
|
-
|
|
2596
|
-
**Returns:**
|
|
2597
|
-
|
|
2598
|
-
`{ skills: SkillAuditRecord[] }`
|
|
2599
|
-
|
package/dist/index.js
CHANGED
|
@@ -23011,6 +23011,62 @@ var getGraphDigest = (args, ctx) => {
|
|
|
23011
23011
|
}
|
|
23012
23012
|
return text(JSON.stringify({ ...digest, lens: sessionContext.lens, lens_digest: lensDigest, _hash: currentHash }, null, 2));
|
|
23013
23013
|
};
|
|
23014
|
+
var YOUNG_GRAPH_THRESHOLD = 8;
|
|
23015
|
+
var start = (_args, ctx) => {
|
|
23016
|
+
const { store } = ctx;
|
|
23017
|
+
const allNodes = store.getAllNodes();
|
|
23018
|
+
const realNodes = allNodes.filter((n) => n.type !== "product");
|
|
23019
|
+
const nodeCount = realNodes.length;
|
|
23020
|
+
const product = store.getProduct();
|
|
23021
|
+
const presentTypes = new Set(allNodes.map((n) => n.type));
|
|
23022
|
+
const productInfo = product ? { title: product.title, stage: product.stage ?? null } : null;
|
|
23023
|
+
const state = nodeCount === 0 ? "empty" : nodeCount < YOUNG_GRAPH_THRESHOLD ? "young" : "established";
|
|
23024
|
+
if (state === "established") {
|
|
23025
|
+
return text(
|
|
23026
|
+
JSON.stringify(
|
|
23027
|
+
{
|
|
23028
|
+
graph_state: state,
|
|
23029
|
+
product: productInfo,
|
|
23030
|
+
node_count: nodeCount,
|
|
23031
|
+
recommendation: `Graph is established (${nodeCount} entities). Use plan for the missing-entities backlog, inspect for issues, and get_graph_digest for health.`,
|
|
23032
|
+
next_tools: ["plan", "inspect", "get_graph_digest"]
|
|
23033
|
+
},
|
|
23034
|
+
null,
|
|
23035
|
+
2
|
|
23036
|
+
)
|
|
23037
|
+
);
|
|
23038
|
+
}
|
|
23039
|
+
const canonicalPlaybooks = UPG_PLAYBOOKS.filter((p) => p.is_canonical === true);
|
|
23040
|
+
const recommend = canonicalPlaybooks.find(
|
|
23041
|
+
(p) => p.target_anchor_entity ? !presentTypes.has(p.target_anchor_entity) : true
|
|
23042
|
+
) ?? canonicalPlaybooks[0];
|
|
23043
|
+
const response = {
|
|
23044
|
+
graph_state: state,
|
|
23045
|
+
product: productInfo,
|
|
23046
|
+
node_count: nodeCount
|
|
23047
|
+
};
|
|
23048
|
+
if (recommend) {
|
|
23049
|
+
const anchor = recommend.target_anchor_entity;
|
|
23050
|
+
response.recommended_playbook = {
|
|
23051
|
+
id: recommend.id,
|
|
23052
|
+
name: recommend.name,
|
|
23053
|
+
region: recommend.region,
|
|
23054
|
+
target_anchor_entity: anchor ?? null,
|
|
23055
|
+
description: recommend.description
|
|
23056
|
+
};
|
|
23057
|
+
if (anchor) {
|
|
23058
|
+
response.first_action = {
|
|
23059
|
+
tool: "create_node",
|
|
23060
|
+
args: { type: anchor, title: `<your first ${anchor}>` }
|
|
23061
|
+
};
|
|
23062
|
+
}
|
|
23063
|
+
response.recommendation = state === "empty" ? `Your graph is empty. Begin with the "${recommend.name}" playbook${anchor ? `: create your first ${anchor}` : ""}. Open the full sequence with get_playbook("${recommend.id}").` : `You have ${nodeCount} ${nodeCount === 1 ? "entity" : "entities"}. Continue with the "${recommend.name}" playbook${anchor ? `: add a ${anchor}` : ""}. Use plan for the full missing-entities backlog.`;
|
|
23064
|
+
} else {
|
|
23065
|
+
response.recommendation = "No canonical playbooks available. Use plan to see the missing-entities backlog.";
|
|
23066
|
+
}
|
|
23067
|
+
response.next_tools = state === "empty" ? ["get_playbook", "create_node", "list_playbooks"] : ["plan", "get_playbook", "get_graph_digest"];
|
|
23068
|
+
return text(JSON.stringify(response, null, 2));
|
|
23069
|
+
};
|
|
23014
23070
|
var getSessionContext = (_args, ctx) => {
|
|
23015
23071
|
const { sessionContext } = ctx;
|
|
23016
23072
|
const recommendationsToAvoid = Array.from(
|
|
@@ -23738,6 +23794,21 @@ function buildFirstUseHints(canonicalType) {
|
|
|
23738
23794
|
if (edgesOut.length > 0) hints.canonical_edges_out = edgesOut;
|
|
23739
23795
|
return hints;
|
|
23740
23796
|
}
|
|
23797
|
+
function buildOrphanWarning(canonicalType) {
|
|
23798
|
+
let schema;
|
|
23799
|
+
try {
|
|
23800
|
+
schema = buildEntitySchema(canonicalType);
|
|
23801
|
+
} catch {
|
|
23802
|
+
return void 0;
|
|
23803
|
+
}
|
|
23804
|
+
const guide = schema.domain_guide;
|
|
23805
|
+
if (!guide || guide.position_in_sequence <= 0) return void 0;
|
|
23806
|
+
const anchor = guide.anchor_entity;
|
|
23807
|
+
if (!anchor || anchor === canonicalType) return void 0;
|
|
23808
|
+
const edge = resolveContainmentEdge(anchor, canonicalType);
|
|
23809
|
+
const via = edge ? ` (canonical edge: ${edge})` : "";
|
|
23810
|
+
return `Orphan: created ${canonicalType} with no parent. ${canonicalType} typically attaches under ${anchor}${via}. Pass parent_id on create, or wire it later with create_edge.`;
|
|
23811
|
+
}
|
|
23741
23812
|
var createNode = async (args, ctx) => {
|
|
23742
23813
|
const { store } = ctx;
|
|
23743
23814
|
if (!args.type) return textError(`Missing required parameter: type`);
|
|
@@ -23804,6 +23875,10 @@ var createNode = async (args, ctx) => {
|
|
|
23804
23875
|
const aggregatedWarnings = [];
|
|
23805
23876
|
if (warning) aggregatedWarnings.push(warning);
|
|
23806
23877
|
if (lengthWarnings.length > 0) aggregatedWarnings.push(...lengthWarnings);
|
|
23878
|
+
if (!args.parent_id && !result.edge) {
|
|
23879
|
+
const orphanWarning = buildOrphanWarning(result.node.type);
|
|
23880
|
+
if (orphanWarning) aggregatedWarnings.push(orphanWarning);
|
|
23881
|
+
}
|
|
23807
23882
|
const libWarning = result.warning;
|
|
23808
23883
|
const combinedWarning = libWarning ? aggregatedWarnings.length > 0 ? `${libWarning} | ${aggregatedWarnings.join(" | ")}` : libWarning : aggregatedWarnings.length > 0 ? aggregatedWarnings.join(" | ") : void 0;
|
|
23809
23884
|
if (unknown_properties.length > 0 || combinedWarning || hints) {
|
|
@@ -26753,6 +26828,14 @@ var TOOL_DEFINITIONS = [
|
|
|
26753
26828
|
}
|
|
26754
26829
|
}
|
|
26755
26830
|
},
|
|
26831
|
+
{
|
|
26832
|
+
name: "start",
|
|
26833
|
+
description: 'Zero-state on-ramp: "there is nothing here yet, where do I begin?". Reads the live graph and, for an empty or barely-started graph, recommends the first canonical playbook (from UPG_PLAYBOOKS) plus the exact create_node call for its anchor entity. Established graphs are routed to plan / inspect / get_graph_digest instead. Takes no arguments.',
|
|
26834
|
+
inputSchema: {
|
|
26835
|
+
type: "object",
|
|
26836
|
+
properties: {}
|
|
26837
|
+
}
|
|
26838
|
+
},
|
|
26756
26839
|
{
|
|
26757
26840
|
name: "list_nodes",
|
|
26758
26841
|
description: "List entities with filtering, edge inclusion, count-only mode, and pagination. For graph-wide edge enumeration, prefer `export_edges` (flat) or `query` (traversal). `list_nodes(include_edges:true)` is for entity-scoped reads.",
|
|
@@ -28052,6 +28135,7 @@ var TOOL_DEFINITIONS = [
|
|
|
28052
28135
|
var HANDLERS = {
|
|
28053
28136
|
get_product_context: getProductContext,
|
|
28054
28137
|
get_graph_digest: getGraphDigest,
|
|
28138
|
+
start,
|
|
28055
28139
|
list_nodes: listNodes,
|
|
28056
28140
|
get_node: getNode,
|
|
28057
28141
|
get_nodes: getNodes,
|