@istar-ts/actions 0.15.0-beta.8 → 0.15.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/dist/index.cjs CHANGED
@@ -201,12 +201,13 @@ function injectCreatedIds(operation, createdIds, model) {
201
201
  return withCreatedIds(operation, [...elementIds], [...linkIds], model);
202
202
  }
203
203
  //#endregion
204
- //#region src/hints.ts
204
+ //#region src/kind-selectors.ts
205
205
  /**
206
- * What a client can know before it asks: type hints from the metamodel, and the palette as
207
- * GLSP context actions. Both are derived from data (`Metamodel`, `PaletteDescription`), so they
208
- * work for any root or extension.
206
+ * Internal: which element and link kinds a rule selector matches, the same way `canLink` does.
207
+ * Shared by `hints.ts` (GLSP type hints) and `metamodel-context.ts` (#240), not part of this
208
+ * package's public API — `index.ts` doesn't re-export this module.
209
209
  */
210
+ /** A generated kind (a hub, leg or end) that an n-ary link's declaration adds on its own. */
210
211
  function isHub(definition) {
211
212
  return definition.role === "hub";
212
213
  }
@@ -227,6 +228,13 @@ function union(metamodel, selectors) {
227
228
  function ofCategory(metamodel, category) {
228
229
  return [...metamodel.elements.values()].filter((d) => !isHub(d) && (category === void 0 || d.category === category)).map((d) => d.kind);
229
230
  }
231
+ //#endregion
232
+ //#region src/hints.ts
233
+ /**
234
+ * What a client can know before it asks: type hints from the metamodel, and the palette as
235
+ * GLSP context actions. Both are derived from data (`Metamodel`, `PaletteDescription`), so they
236
+ * work for any root or extension.
237
+ */
230
238
  /**
231
239
  * GLSP type hints of a metamodel. Shapes: every element kind (hubs can't be resized or
232
240
  * reparented; actors contain the node kinds that can be inner elements). Edges: every link kind,
@@ -1047,6 +1055,130 @@ function contextText(provider, model) {
1047
1055
  return Promise.resolve(typeof text === "string" ? text : text(model));
1048
1056
  }
1049
1057
  //#endregion
1058
+ //#region src/metamodel-context.ts
1059
+ /**
1060
+ * A built-in context provider (#240): what an agent needs to know about a model's own
1061
+ * vocabulary — its element and link kinds, containment, link rules and value sets — derived
1062
+ * only from the `Metamodel`, so it works unchanged for iStar 2.0, KAOS, NFR, an
1063
+ * `extendMetamodel` result or a file metamodel (pistarExt). No dialect names in this file.
1064
+ *
1065
+ * `metamodelContextProvider` is the `HostContextProvider` every launcher and agent session
1066
+ * includes by default (opt-out: `metamodelContext: false`); a host's own providers are appended
1067
+ * after it.
1068
+ */
1069
+ function propertiesOf(kind, byKind) {
1070
+ const schemas = byKind.get(kind);
1071
+ if (!schemas || schemas.length === 0) return void 0;
1072
+ const properties = [];
1073
+ for (const schema of schemas) for (const [key, field] of Object.entries(schema.shape)) properties.push({
1074
+ key,
1075
+ type: field.type,
1076
+ ...field.values ? { values: field.values } : {},
1077
+ ...field.options.optional ? { optional: true } : {},
1078
+ ...field.options.description ? { description: field.options.description } : {}
1079
+ });
1080
+ return properties;
1081
+ }
1082
+ /**
1083
+ * `metamodel`, as a typed, JSON-serializable description: every element and link kind a
1084
+ * modeller declares directly (kinds generated for an n-ary link's hub, leg or end are left out,
1085
+ * as a hand-written palette hides them too), its containment, and each link kind's source and
1086
+ * target kinds in words, resolved the same way `canLink` does (`union`/`ofCategory`).
1087
+ */
1088
+ function metamodelContext(metamodel, options = {}) {
1089
+ const schemasByKind = /* @__PURE__ */ new Map();
1090
+ for (const schema of options.schemas ?? []) {
1091
+ const list = schemasByKind.get(schema.kind) ?? [];
1092
+ list.push(schema);
1093
+ schemasByKind.set(schema.kind, list);
1094
+ }
1095
+ const elements = [];
1096
+ for (const definition of metamodel.elements.values()) {
1097
+ if (isHub(definition)) continue;
1098
+ elements.push({
1099
+ kind: definition.kind,
1100
+ label: definition.label,
1101
+ ...definition.description !== void 0 ? { description: definition.description } : {},
1102
+ category: definition.category,
1103
+ ...definition.info ? {
1104
+ canBeOnPaper: definition.info.canBeOnPaper,
1105
+ canBeInnerElement: definition.info.canBeInnerElement
1106
+ } : {},
1107
+ ...propertiesOf(definition.kind, schemasByKind) ? { properties: propertiesOf(definition.kind, schemasByKind) } : {}
1108
+ });
1109
+ }
1110
+ const links = [];
1111
+ for (const definition of metamodel.links.values()) {
1112
+ if (definition.role !== void 0) continue;
1113
+ const rules = metamodel.links.get((0, _istar_ts_core.effectiveLinkKind)(metamodel, definition.kind))?.rules;
1114
+ const builtIn = definition.category === "dependency" ? ofCategory(metamodel) : ofCategory(metamodel, definition.category);
1115
+ links.push({
1116
+ kind: definition.kind,
1117
+ label: definition.label,
1118
+ ...definition.description !== void 0 ? { description: definition.description } : {},
1119
+ category: definition.category,
1120
+ sources: rules ? union(metamodel, rules.sources) : builtIn,
1121
+ targets: rules ? union(metamodel, rules.targets) : builtIn,
1122
+ ...definition.arity === "n" ? { arity: definition.arity } : {},
1123
+ ...definition.info.possibleLabels ? { values: definition.info.possibleLabels } : {},
1124
+ ...propertiesOf(definition.kind, schemasByKind) ? { properties: propertiesOf(definition.kind, schemasByKind) } : {}
1125
+ });
1126
+ }
1127
+ return {
1128
+ framework: metamodel.framework,
1129
+ elements,
1130
+ links
1131
+ };
1132
+ }
1133
+ function propertiesLine(properties) {
1134
+ if (!properties || properties.length === 0) return [];
1135
+ return [` properties: ${properties.map((p) => {
1136
+ const bits = [p.type, ...p.values ? [`values: ${p.values.join("/")}`] : []];
1137
+ return `${p.key} (${bits.join(", ")})${p.optional ? "?" : ""}`;
1138
+ }).join(", ")}`];
1139
+ }
1140
+ function flags(element) {
1141
+ const bits = [];
1142
+ if (element.canBeOnPaper) bits.push("on paper");
1143
+ if (element.canBeInnerElement) bits.push("inner");
1144
+ return bits.length > 0 ? ` [${bits.join(", ")}]` : "";
1145
+ }
1146
+ function elementLine(element) {
1147
+ const description = element.description ? ` — ${element.description}` : "";
1148
+ return [`- ${element.kind} (${element.label})${flags(element)}${description}`, ...propertiesLine(element.properties)];
1149
+ }
1150
+ function linkLine(link) {
1151
+ const arity = link.arity === "n" ? " [n-ary, via a hub]" : "";
1152
+ const values = link.values ? `; values: ${link.values.join(", ")}` : "";
1153
+ const description = link.description ? ` — ${link.description}` : "";
1154
+ return [`- ${link.kind} (${link.label})${arity}: ${link.category} link, ${link.sources.join(", ")} → ${link.targets.join(", ")}${values}${description}`, ...propertiesLine(link.properties)];
1155
+ }
1156
+ /**
1157
+ * `context`, rendered as compact, deterministic markdown for an LLM: one section each for actor
1158
+ * kinds, node kinds and link kinds, in the metamodel's own declaration order.
1159
+ */
1160
+ function metamodelContextText(context) {
1161
+ const actors = context.elements.filter((e) => e.category === "actor");
1162
+ const nodes = context.elements.filter((e) => e.category === "node");
1163
+ const sections = [`# ${context.framework} metamodel`];
1164
+ if (actors.length > 0) sections.push(["## Actor kinds", ...actors.flatMap(elementLine)].join("\n"));
1165
+ if (nodes.length > 0) sections.push(["## Node kinds", ...nodes.flatMap(elementLine)].join("\n"));
1166
+ if (context.links.length > 0) sections.push(["## Link kinds", ...context.links.flatMap(linkLine)].join("\n"));
1167
+ return sections.join("\n\n");
1168
+ }
1169
+ /**
1170
+ * The built-in `HostContextProvider` (#240): its text is always read from the model at hand
1171
+ * (`metamodelOf(model)`), so one instance works for every dialect a host serves. `options`
1172
+ * (`schemas`, mainly from a dialect's `IstarGlspContribution`) are fixed at creation time.
1173
+ */
1174
+ function metamodelContextProvider(options = {}) {
1175
+ return {
1176
+ name: "metamodel",
1177
+ title: "This model's language",
1178
+ text: (model) => metamodelContextText(metamodelContext((0, _istar_ts_core.metamodelOf)(model), options))
1179
+ };
1180
+ }
1181
+ //#endregion
1050
1182
  //#region src/mirror.ts
1051
1183
  /**
1052
1184
  * A mirror store: a read-only `ModelStore` in this process whose model follows a dispatcher that
@@ -1406,6 +1538,9 @@ exports.injectCreatedIds = injectCreatedIds;
1406
1538
  exports.isOperation = isOperation;
1407
1539
  exports.isRequestAction = isRequestAction;
1408
1540
  exports.markerToDiagnostic = markerToDiagnostic;
1541
+ exports.metamodelContext = metamodelContext;
1542
+ exports.metamodelContextProvider = metamodelContextProvider;
1543
+ exports.metamodelContextText = metamodelContextText;
1409
1544
  exports.paletteFromMetamodel = paletteFromMetamodel;
1410
1545
  exports.readOnlyDispatcher = readOnlyDispatcher;
1411
1546
  exports.typeHintsFor = typeHintsFor;