@unified-product-graph/mcp-server 0.8.13 → 0.8.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.
- package/TOOLS.md +89 -5
- package/dist/index.js +111 -7
- package/dist/index.js.map +1 -1
- package/dist/tools-manifest.json +144 -21
- package/package.json +3 -3
package/TOOLS.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# UPG MCP Server: Tool Reference
|
|
2
2
|
|
|
3
|
-
Reference for the
|
|
3
|
+
Reference for the 99 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
7
|
- [Context & Session](#context-session): 5 tools
|
|
8
8
|
- [Nodes](#nodes): 15 tools
|
|
9
9
|
- [Edges](#edges): 9 tools
|
|
10
|
-
- [Areas & Change Log](#areas-change-log):
|
|
11
|
-
- [Workspace & Portfolios](#workspace-portfolios):
|
|
10
|
+
- [Areas & Change Log](#areas-change-log): 6 tools
|
|
11
|
+
- [Workspace & Portfolios](#workspace-portfolios): 12 tools
|
|
12
12
|
- [Schema](#schema): 1 tool
|
|
13
13
|
- [Spec Introspection](#spec-introspection): 45 tools
|
|
14
14
|
- [Cloud Sync](#cloud-sync): 3 tools
|
|
@@ -946,12 +946,39 @@ re-computed on next save; a subsequent reload won't bring them back.
|
|
|
946
946
|
|
|
947
947
|
_Product areas, the `.upg-area.json` cwd scoper, and the session change log._
|
|
948
948
|
|
|
949
|
+
- [`assign_product_to_area`](#assign-product-to-area)
|
|
949
950
|
- [`create_area`](#create-area)
|
|
950
951
|
- [`get_area_context`](#get-area-context)
|
|
951
952
|
- [`get_area_graph`](#get-area-graph)
|
|
952
953
|
- [`get_changes`](#get-changes)
|
|
953
954
|
- [`list_product_areas`](#list-product-areas)
|
|
954
955
|
|
|
956
|
+
### `assign_product_to_area`
|
|
957
|
+
|
|
958
|
+
Place an existing product under a product area (adds it to the area's `products[]` in `.upg/portfolio.upg`). Resolves the area against the portfolio document and auto-registers the product on the portfolio registry. Use after `create_product`, or pass `area_id` to `create_product` directly.
|
|
959
|
+
|
|
960
|
+
**Atomicity:** `atomic (single portfolio.upg flush).`
|
|
961
|
+
|
|
962
|
+
**Arguments:**
|
|
963
|
+
|
|
964
|
+
| Name | Type | Required | Description |
|
|
965
|
+
| ---- | ---- | -------- | ----------- |
|
|
966
|
+
| `area_id` | string | ✓ | Product area id (from list_product_areas) |
|
|
967
|
+
| `product_id` | string | ✓ | Product id (from create_product / list_local_products) |
|
|
968
|
+
|
|
969
|
+
**Returns:**
|
|
970
|
+
|
|
971
|
+
JSON: `{ product_id, container_id, container_kind: "product_area",
|
|
972
|
+
container_title?, already_member, registered }`.
|
|
973
|
+
|
|
974
|
+
**Throws:**
|
|
975
|
+
|
|
976
|
+
- textError on a missing workspace, an unknown product, or an unknown
|
|
977
|
+
area id (the message points at list_product_areas / list_local_products).
|
|
978
|
+
|
|
979
|
+
**See also:** `attach_product_to_portfolio`, `create_product`
|
|
980
|
+
|
|
981
|
+
|
|
955
982
|
### `create_area`
|
|
956
983
|
|
|
957
984
|
Create a product area entity in the portfolio document (`.upg/portfolio.upg`). Product areas represent the organisational axis (who owns what). Supports nesting via `parent_area_id`. The portfolio document is created on demand.
|
|
@@ -966,7 +993,7 @@ flushed in one pass.`
|
|
|
966
993
|
| `description` | string | | What this area covers |
|
|
967
994
|
| `owner` | string | | Person or team that owns this area |
|
|
968
995
|
| `parent_area_id` | string | | Parent area ID for creating a sub-area |
|
|
969
|
-
| `strategic_priority` | `
|
|
996
|
+
| `strategic_priority` | `urgent` \| `high` \| `medium` \| `low` \| `none` | | Strategic priority of this area (canonical Priority scale) |
|
|
970
997
|
| `title` | string | ✓ | Area name (e.g. "Search", "Payments") |
|
|
971
998
|
|
|
972
999
|
**Returns:**
|
|
@@ -1070,6 +1097,7 @@ parent_area_id?, products? }>, total }`.
|
|
|
1070
1097
|
|
|
1071
1098
|
_Multi-product discovery, switching, init, cross-product edges._
|
|
1072
1099
|
|
|
1100
|
+
- [`attach_product_to_portfolio`](#attach-product-to-portfolio)
|
|
1073
1101
|
- [`create_cross_product_edge`](#create-cross-product-edge)
|
|
1074
1102
|
- [`create_product`](#create-product)
|
|
1075
1103
|
- [`get_organization`](#get-organization)
|
|
@@ -1080,6 +1108,33 @@ _Multi-product discovery, switching, init, cross-product edges._
|
|
|
1080
1108
|
- [`list_portfolios`](#list-portfolios)
|
|
1081
1109
|
- [`migrate_cross_edges`](#migrate-cross-edges)
|
|
1082
1110
|
- [`switch_product`](#switch-product)
|
|
1111
|
+
- [`update_product`](#update-product)
|
|
1112
|
+
|
|
1113
|
+
### `attach_product_to_portfolio`
|
|
1114
|
+
|
|
1115
|
+
Place an existing product under a portfolio (adds it to the portfolio's `products[]` in `.upg/portfolio.upg`). Resolves the portfolio against the portfolio document and auto-registers the product on the portfolio registry. Use after `create_product`, or pass `portfolio_id` to `create_product` directly.
|
|
1116
|
+
|
|
1117
|
+
**Atomicity:** `atomic (single portfolio.upg flush).`
|
|
1118
|
+
|
|
1119
|
+
**Arguments:**
|
|
1120
|
+
|
|
1121
|
+
| Name | Type | Required | Description |
|
|
1122
|
+
| ---- | ---- | -------- | ----------- |
|
|
1123
|
+
| `portfolio_id` | string | ✓ | Portfolio id (from list_portfolios) |
|
|
1124
|
+
| `product_id` | string | ✓ | Product id (from create_product / list_local_products) |
|
|
1125
|
+
|
|
1126
|
+
**Returns:**
|
|
1127
|
+
|
|
1128
|
+
JSON: `{ product_id, container_id, container_kind: "portfolio",
|
|
1129
|
+
container_title?, already_member, registered }`.
|
|
1130
|
+
|
|
1131
|
+
**Throws:**
|
|
1132
|
+
|
|
1133
|
+
- textError on a missing workspace, an unknown product, or an unknown
|
|
1134
|
+
portfolio id (the message points at list_portfolios / list_local_products).
|
|
1135
|
+
|
|
1136
|
+
**See also:** `assign_product_to_area`, `create_product`
|
|
1137
|
+
|
|
1083
1138
|
|
|
1084
1139
|
### `create_cross_product_edge`
|
|
1085
1140
|
|
|
@@ -1121,9 +1176,10 @@ portfolio edge are separate mutations.`
|
|
|
1121
1176
|
|
|
1122
1177
|
| Name | Type | Required | Description |
|
|
1123
1178
|
| ---- | ---- | -------- | ----------- |
|
|
1179
|
+
| `area_id` | string | | Optional product_area id (resolved against portfolio.upg) to place the new product under. |
|
|
1124
1180
|
| `description` | string | | Optional product description |
|
|
1125
1181
|
| `name` | string | ✓ | Product display title (required, non-empty). |
|
|
1126
|
-
| `portfolio_id` | string | | Optional portfolio
|
|
1182
|
+
| `portfolio_id` | string | | Optional portfolio id (resolved against portfolio.upg) to place the new product under. A portfolio id that resolves only in the active graph still attaches via an in-graph edge (DEPRECATED; prefer attach_product_to_portfolio). |
|
|
1127
1183
|
| `slug` | string | | Optional slug for the .upg filename. Defaults to a slug derived from `name`. Collisions append `-2`, `-3`, … |
|
|
1128
1184
|
| `stage` | string | | Product lifecycle stage. See UPGProductStage in @unified-product-graph/core. |
|
|
1129
1185
|
|
|
@@ -1318,6 +1374,34 @@ before any read/mutation to confirm the active product.
|
|
|
1318
1374
|
**See also:** `get_workspace_info`, `list_local_products`, `init_workspace`
|
|
1319
1375
|
|
|
1320
1376
|
|
|
1377
|
+
### `update_product`
|
|
1378
|
+
|
|
1379
|
+
Update the product header (`$upg.product`): stage, title, description, health_status, url. The supported way to advance a product's lifecycle stage; it writes the value get_graph_digest reads, without hand-editing the .upg file.
|
|
1380
|
+
|
|
1381
|
+
**Atomicity:** `atomic (single flush).`
|
|
1382
|
+
|
|
1383
|
+
**Arguments:**
|
|
1384
|
+
|
|
1385
|
+
| Name | Type | Required | Description |
|
|
1386
|
+
| ---- | ---- | -------- | ----------- |
|
|
1387
|
+
| `description` | string | | Product description. |
|
|
1388
|
+
| `health_status` | string | | Product health (free-form, e.g. on_track / at_risk). |
|
|
1389
|
+
| `stage` | string | | Product lifecycle stage (canonical UPGProductStage). |
|
|
1390
|
+
| `title` | string | | Product display title. |
|
|
1391
|
+
| `url` | string | | Product URL. |
|
|
1392
|
+
|
|
1393
|
+
**Returns:**
|
|
1394
|
+
|
|
1395
|
+
JSON: `{ product, updated: string[] }` (the fields changed).
|
|
1396
|
+
|
|
1397
|
+
**Throws:**
|
|
1398
|
+
|
|
1399
|
+
- textError when no field is supplied, when there is no product header,
|
|
1400
|
+
or when `stage` is non-canonical (same strict validation as create_product).
|
|
1401
|
+
|
|
1402
|
+
**See also:** `create_product`
|
|
1403
|
+
|
|
1404
|
+
|
|
1321
1405
|
## Schema
|
|
1322
1406
|
|
|
1323
1407
|
_Entity schema introspection. Same constraints the LSP enforces._
|
package/dist/index.js
CHANGED
|
@@ -10131,7 +10131,8 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10131
10131
|
// ProductAreaProperties: ProductArea entity.
|
|
10132
10132
|
product_area: {
|
|
10133
10133
|
strategic_priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Strategic priority assigned to this area" },
|
|
10134
|
-
description: { type: "string", description: "Narrative description of what this area covers" }
|
|
10134
|
+
description: { type: "string", description: "Narrative description of what this area covers" },
|
|
10135
|
+
owner: { type: "string", description: "Person or team that owns this area" }
|
|
10135
10136
|
},
|
|
10136
10137
|
// ProgramProperties: Program.
|
|
10137
10138
|
program: {
|
|
@@ -24371,7 +24372,7 @@ function serializePortfolioWithHeader(doc, opts) {
|
|
|
24371
24372
|
header.integrity = { algorithm: INTEGRITY_ALGORITHM, body: computeBodyChecksum(doc) };
|
|
24372
24373
|
return JSON.stringify({ $upg: header, ...body }, null, 2) + "\n";
|
|
24373
24374
|
}
|
|
24374
|
-
var UPG_VERSION = "0.8.
|
|
24375
|
+
var UPG_VERSION = "0.8.15";
|
|
24375
24376
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
24376
24377
|
var UPG_TYPES = getTypes();
|
|
24377
24378
|
var UPG_TYPES_SET = new Set(UPG_TYPES);
|
|
@@ -26255,6 +26256,7 @@ import * as path2 from "path";
|
|
|
26255
26256
|
import {
|
|
26256
26257
|
writePortfolioScopedNode as writePortfolioScopedNode2,
|
|
26257
26258
|
openPortfolioStoreIfExists,
|
|
26259
|
+
assignProductToArea,
|
|
26258
26260
|
PortfolioRoutingError as PortfolioRoutingError2
|
|
26259
26261
|
} from "@unified-product-graph/sdk";
|
|
26260
26262
|
var listProductAreas = async (_args, _ctx) => {
|
|
@@ -26269,11 +26271,24 @@ var listProductAreas = async (_args, _ctx) => {
|
|
|
26269
26271
|
if (area.description) row.description = area.description;
|
|
26270
26272
|
if (area.parent_area_id !== void 0) row.parent_area_id = area.parent_area_id;
|
|
26271
26273
|
if (area.strategic_priority) row.strategic_priority = area.strategic_priority;
|
|
26274
|
+
if (area.owner) row.owner = area.owner;
|
|
26272
26275
|
if (area.products) row.products = area.products;
|
|
26273
26276
|
return row;
|
|
26274
26277
|
});
|
|
26275
26278
|
return text(JSON.stringify({ areas: result, total: result.length }, null, 2));
|
|
26276
26279
|
};
|
|
26280
|
+
var assignProductToAreaTool = async (args, _ctx) => {
|
|
26281
|
+
const productId = args.product_id;
|
|
26282
|
+
const areaId = args.area_id;
|
|
26283
|
+
if (!productId) return textError("Missing required parameter: product_id");
|
|
26284
|
+
if (!areaId) return textError("Missing required parameter: area_id");
|
|
26285
|
+
try {
|
|
26286
|
+
const result = await assignProductToArea(process.cwd(), { product_id: productId, area_id: areaId });
|
|
26287
|
+
return text(JSON.stringify(result, null, 2));
|
|
26288
|
+
} catch (err) {
|
|
26289
|
+
return textError(err.message);
|
|
26290
|
+
}
|
|
26291
|
+
};
|
|
26277
26292
|
var getAreaGraph = (args, ctx) => {
|
|
26278
26293
|
const { store } = ctx;
|
|
26279
26294
|
const areaId = args.area_id;
|
|
@@ -26428,6 +26443,7 @@ var createArea = async (args, _ctx) => {
|
|
|
26428
26443
|
const properties = {};
|
|
26429
26444
|
if (args.strategic_priority) properties.strategic_priority = args.strategic_priority;
|
|
26430
26445
|
if (args.parent_area_id) properties.parent_area_id = args.parent_area_id;
|
|
26446
|
+
if (args.owner) properties.owner = args.owner;
|
|
26431
26447
|
try {
|
|
26432
26448
|
const result = await writePortfolioScopedNode2(process.cwd(), {
|
|
26433
26449
|
type: "product_area",
|
|
@@ -26474,10 +26490,12 @@ import {
|
|
|
26474
26490
|
resolvePortfolioPath,
|
|
26475
26491
|
openPortfolioStoreIfExists as openPortfolioStoreIfExists2,
|
|
26476
26492
|
registerProductOnPortfolio,
|
|
26477
|
-
findProductFileById
|
|
26493
|
+
findProductFileById,
|
|
26494
|
+
attachProductToPortfolio
|
|
26478
26495
|
} from "@unified-product-graph/sdk";
|
|
26479
26496
|
import {
|
|
26480
26497
|
createProduct,
|
|
26498
|
+
updateProduct,
|
|
26481
26499
|
initWorkspace,
|
|
26482
26500
|
InvalidProductNameError,
|
|
26483
26501
|
InvalidProductStageError,
|
|
@@ -26645,7 +26663,8 @@ var createProductTool = async (args, ctx) => {
|
|
|
26645
26663
|
slug: args.slug,
|
|
26646
26664
|
description: args.description,
|
|
26647
26665
|
stage: args.stage,
|
|
26648
|
-
portfolio_id: args.portfolio_id
|
|
26666
|
+
portfolio_id: args.portfolio_id,
|
|
26667
|
+
area_id: args.area_id
|
|
26649
26668
|
});
|
|
26650
26669
|
return text(
|
|
26651
26670
|
JSON.stringify({ message: `Created product: ${result.title}`, ...result }, null, 2)
|
|
@@ -26658,6 +26677,31 @@ var createProductTool = async (args, ctx) => {
|
|
|
26658
26677
|
return textError(`create_product failed: ${err.message}`);
|
|
26659
26678
|
}
|
|
26660
26679
|
};
|
|
26680
|
+
var updateProductTool = async (args, ctx) => {
|
|
26681
|
+
const { store } = ctx;
|
|
26682
|
+
try {
|
|
26683
|
+
const result = updateProduct({
|
|
26684
|
+
store,
|
|
26685
|
+
stage: args.stage,
|
|
26686
|
+
title: args.title,
|
|
26687
|
+
description: args.description,
|
|
26688
|
+
health_status: args.health_status,
|
|
26689
|
+
url: args.url
|
|
26690
|
+
});
|
|
26691
|
+
if (result.updated.length === 0) {
|
|
26692
|
+
return textError(
|
|
26693
|
+
"Nothing to update: pass at least one of: stage, title, description, health_status, url."
|
|
26694
|
+
);
|
|
26695
|
+
}
|
|
26696
|
+
await store.flush();
|
|
26697
|
+
return text(
|
|
26698
|
+
JSON.stringify({ message: `Updated product (${result.updated.join(", ")})`, ...result }, null, 2)
|
|
26699
|
+
);
|
|
26700
|
+
} catch (err) {
|
|
26701
|
+
if (err instanceof InvalidProductStageError) return textError(err.message);
|
|
26702
|
+
return textError(`update_product failed: ${err.message}`);
|
|
26703
|
+
}
|
|
26704
|
+
};
|
|
26661
26705
|
var listPortfolios = async (_args, _ctx) => {
|
|
26662
26706
|
const portfolioStore = await openPortfolioStoreIfExists2(process.cwd());
|
|
26663
26707
|
if (!portfolioStore) {
|
|
@@ -26867,6 +26911,21 @@ var migrateCrossEdges = async (args, ctx) => {
|
|
|
26867
26911
|
)
|
|
26868
26912
|
);
|
|
26869
26913
|
};
|
|
26914
|
+
var attachProductToPortfolioTool = async (args, _ctx) => {
|
|
26915
|
+
const productId = args.product_id;
|
|
26916
|
+
const portfolioId = args.portfolio_id;
|
|
26917
|
+
if (!productId) return textError("Missing required parameter: product_id");
|
|
26918
|
+
if (!portfolioId) return textError("Missing required parameter: portfolio_id");
|
|
26919
|
+
try {
|
|
26920
|
+
const result = await attachProductToPortfolio(process.cwd(), {
|
|
26921
|
+
product_id: productId,
|
|
26922
|
+
portfolio_id: portfolioId
|
|
26923
|
+
});
|
|
26924
|
+
return text(JSON.stringify(result, null, 2));
|
|
26925
|
+
} catch (err) {
|
|
26926
|
+
return textError(err.message);
|
|
26927
|
+
}
|
|
26928
|
+
};
|
|
26870
26929
|
|
|
26871
26930
|
// src/tools/schema.ts
|
|
26872
26931
|
var getEntitySchema = (args, _ctx) => {
|
|
@@ -29138,12 +29197,30 @@ var TOOL_DEFINITIONS = [
|
|
|
29138
29197
|
},
|
|
29139
29198
|
portfolio_id: {
|
|
29140
29199
|
type: "string",
|
|
29141
|
-
description: "Optional portfolio
|
|
29200
|
+
description: "Optional portfolio id (resolved against portfolio.upg) to place the new product under. A portfolio id that resolves only in the active graph still attaches via an in-graph edge (DEPRECATED; prefer attach_product_to_portfolio)."
|
|
29201
|
+
},
|
|
29202
|
+
area_id: {
|
|
29203
|
+
type: "string",
|
|
29204
|
+
description: "Optional product_area id (resolved against portfolio.upg) to place the new product under."
|
|
29142
29205
|
}
|
|
29143
29206
|
},
|
|
29144
29207
|
required: ["name"]
|
|
29145
29208
|
}
|
|
29146
29209
|
},
|
|
29210
|
+
{
|
|
29211
|
+
name: "update_product",
|
|
29212
|
+
description: "Update the product header (`$upg.product`): stage, title, description, health_status, url. The supported way to advance a product's lifecycle stage; it writes the value get_graph_digest reads, without hand-editing the .upg file.",
|
|
29213
|
+
inputSchema: {
|
|
29214
|
+
type: "object",
|
|
29215
|
+
properties: {
|
|
29216
|
+
stage: { type: "string", description: "Product lifecycle stage (canonical UPGProductStage)." },
|
|
29217
|
+
title: { type: "string", description: "Product display title." },
|
|
29218
|
+
description: { type: "string", description: "Product description." },
|
|
29219
|
+
health_status: { type: "string", description: "Product health (free-form, e.g. on_track / at_risk)." },
|
|
29220
|
+
url: { type: "string", description: "Product URL." }
|
|
29221
|
+
}
|
|
29222
|
+
}
|
|
29223
|
+
},
|
|
29147
29224
|
{
|
|
29148
29225
|
name: "migrate_type",
|
|
29149
29226
|
description: "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.",
|
|
@@ -29840,14 +29917,38 @@ var TOOL_DEFINITIONS = [
|
|
|
29840
29917
|
},
|
|
29841
29918
|
strategic_priority: {
|
|
29842
29919
|
type: "string",
|
|
29843
|
-
enum: ["
|
|
29844
|
-
description: "Strategic priority of this area"
|
|
29920
|
+
enum: ["urgent", "high", "medium", "low", "none"],
|
|
29921
|
+
description: "Strategic priority of this area (canonical Priority scale)"
|
|
29845
29922
|
},
|
|
29846
29923
|
owner: { type: "string", description: "Person or team that owns this area" }
|
|
29847
29924
|
},
|
|
29848
29925
|
required: ["title"]
|
|
29849
29926
|
}
|
|
29850
29927
|
},
|
|
29928
|
+
{
|
|
29929
|
+
name: "assign_product_to_area",
|
|
29930
|
+
description: "Place an existing product under a product area (adds it to the area's `products[]` in `.upg/portfolio.upg`). Resolves the area against the portfolio document and auto-registers the product on the portfolio registry. Use after `create_product`, or pass `area_id` to `create_product` directly.",
|
|
29931
|
+
inputSchema: {
|
|
29932
|
+
type: "object",
|
|
29933
|
+
properties: {
|
|
29934
|
+
product_id: { type: "string", description: "Product id (from create_product / list_local_products)" },
|
|
29935
|
+
area_id: { type: "string", description: "Product area id (from list_product_areas)" }
|
|
29936
|
+
},
|
|
29937
|
+
required: ["product_id", "area_id"]
|
|
29938
|
+
}
|
|
29939
|
+
},
|
|
29940
|
+
{
|
|
29941
|
+
name: "attach_product_to_portfolio",
|
|
29942
|
+
description: "Place an existing product under a portfolio (adds it to the portfolio's `products[]` in `.upg/portfolio.upg`). Resolves the portfolio against the portfolio document and auto-registers the product on the portfolio registry. Use after `create_product`, or pass `portfolio_id` to `create_product` directly.",
|
|
29943
|
+
inputSchema: {
|
|
29944
|
+
type: "object",
|
|
29945
|
+
properties: {
|
|
29946
|
+
product_id: { type: "string", description: "Product id (from create_product / list_local_products)" },
|
|
29947
|
+
portfolio_id: { type: "string", description: "Portfolio id (from list_portfolios)" }
|
|
29948
|
+
},
|
|
29949
|
+
required: ["product_id", "portfolio_id"]
|
|
29950
|
+
}
|
|
29951
|
+
},
|
|
29851
29952
|
{
|
|
29852
29953
|
name: "list_portfolios",
|
|
29853
29954
|
description: "List portfolios from the portfolio document (`.upg/portfolio.upg`). Portfolios represent the strategic axis (where we invest). Returns an empty list when no portfolio document exists yet.",
|
|
@@ -29999,6 +30100,7 @@ var HANDLERS = {
|
|
|
29999
30100
|
get_workspace_info: getWorkspaceInfo,
|
|
30000
30101
|
init_workspace: initWorkspaceTool,
|
|
30001
30102
|
create_product: createProductTool,
|
|
30103
|
+
update_product: updateProductTool,
|
|
30002
30104
|
migrate_type: migrateType,
|
|
30003
30105
|
migrate_properties: migrateProperties,
|
|
30004
30106
|
migrate_status: migrateStatus,
|
|
@@ -30054,9 +30156,11 @@ var HANDLERS = {
|
|
|
30054
30156
|
skill_audit: skillAudit,
|
|
30055
30157
|
get_area_context: getAreaContext,
|
|
30056
30158
|
create_area: createArea,
|
|
30159
|
+
assign_product_to_area: assignProductToAreaTool,
|
|
30057
30160
|
list_portfolios: listPortfolios,
|
|
30058
30161
|
get_organization: getOrganization,
|
|
30059
30162
|
create_cross_product_edge: createCrossProductEdge,
|
|
30163
|
+
attach_product_to_portfolio: attachProductToPortfolioTool,
|
|
30060
30164
|
list_portfolio_cross_edges: listPortfolioCrossEdges,
|
|
30061
30165
|
migrate_cross_edges: migrateCrossEdges,
|
|
30062
30166
|
get_sync_state: getSyncState,
|