@rsconcept/rstool 1.5.0 → 1.7.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.
Files changed (65) hide show
  1. package/README.md +6 -4
  2. package/dist/agent-workflow-DY-hfAap.d.ts +116 -0
  3. package/dist/{analysis-DA44pfgA.d.ts → analysis-ktWFu4BY.d.ts} +2 -2
  4. package/dist/{constituenta-QY5w1x91.d.ts → constituenta-HTnFtmxt.d.ts} +3 -3
  5. package/dist/{diagnostic-C6TRoBgt.d.ts → diagnostic-CODFUU-Q.d.ts} +5 -4
  6. package/dist/{diagnostic-assembly-DRunIcKQ.js → diagnostic-assembly-B-6vIA5I.js} +3 -1
  7. package/dist/diagnostic-assembly-B-6vIA5I.js.map +1 -0
  8. package/dist/{evaluation-Cd4S7-3t.d.ts → evaluation-6A7rK4t7.d.ts} +2 -2
  9. package/dist/index.d.ts +9 -9
  10. package/dist/index.js +1 -1
  11. package/dist/mappers/model-adapter.d.ts +2 -2
  12. package/dist/mappers/model-adapter.js +127 -1
  13. package/dist/mappers/model-adapter.js.map +1 -0
  14. package/dist/mappers/schema-adapter.d.ts +9 -5
  15. package/dist/mappers/schema-adapter.js +44 -11
  16. package/dist/mappers/schema-adapter.js.map +1 -1
  17. package/dist/mappers/types.d.ts +2 -2
  18. package/dist/mappers/types.js +1 -1
  19. package/dist/models/agent-workflow.d.ts +2 -2
  20. package/dist/models/analysis.d.ts +1 -1
  21. package/dist/models/constituenta.d.ts +1 -1
  22. package/dist/models/diagnostic.d.ts +1 -1
  23. package/dist/models/diagnostic.js +1 -1
  24. package/dist/models/evaluation.d.ts +1 -1
  25. package/dist/models/index.d.ts +9 -9
  26. package/dist/models/index.js +1 -1
  27. package/dist/models/rstool-agent.d.ts +1 -1
  28. package/dist/models/rstool-agent.js +1 -1
  29. package/dist/models/session.d.ts +1 -1
  30. package/dist/models/tool-contract.d.ts +1 -1
  31. package/dist/models/tool-contract.js +1 -1
  32. package/dist/models/tool-contract.js.map +1 -1
  33. package/dist/{models-B255GaEC.js → models-BKmWx92e.js} +138 -4
  34. package/dist/models-BKmWx92e.js.map +1 -0
  35. package/dist/rsform-builder-DKwZfJvN.js +102 -0
  36. package/dist/rsform-builder-DKwZfJvN.js.map +1 -0
  37. package/dist/{rstool-agent-BGQAzFly.d.ts → rstool-agent-D-w4DlEo.d.ts} +14 -8
  38. package/dist/session/session-store.d.ts +2 -2
  39. package/dist/session/session-store.js +1 -1
  40. package/dist/{session-CI4rLYby.d.ts → session-Uc_vHrq9.d.ts} +2 -2
  41. package/dist/{tool-contract-sQfr-DYD.d.ts → tool-contract-i0v2gbWs.d.ts} +18 -8
  42. package/dist/wrapper/stdio-wrapper.js +14 -2
  43. package/dist/wrapper/stdio-wrapper.js.map +1 -1
  44. package/docs/DIAGNOSTICS.md +32 -31
  45. package/docs/DOMAIN.md +9 -2
  46. package/docs/README.md +1 -1
  47. package/package.json +1 -1
  48. package/skills/rstool-helper/EXAMPLES.md +26 -0
  49. package/skills/rstool-helper/GUIDE.md +2 -1
  50. package/skills/rstool-helper/REFERENCE.md +65 -19
  51. package/src/index.ts +4 -1
  52. package/src/mappers/diagnostic-assembly.ts +7 -4
  53. package/src/mappers/rsform-builder.ts +1 -1
  54. package/src/mappers/schema-adapter.ts +48 -16
  55. package/src/models/agent-workflow.ts +53 -0
  56. package/src/models/index.ts +6 -9
  57. package/src/models/rstool-agent.test.ts +83 -0
  58. package/src/models/rstool-agent.ts +182 -1
  59. package/src/models/tool-contract.ts +17 -2
  60. package/src/wrapper/stdio-handler.ts +15 -1
  61. package/dist/agent-workflow-D22FeODL.d.ts +0 -64
  62. package/dist/diagnostic-assembly-DRunIcKQ.js.map +0 -1
  63. package/dist/model-adapter-D-YmIvQW.js +0 -225
  64. package/dist/model-adapter-D-YmIvQW.js.map +0 -1
  65. package/dist/models-B255GaEC.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import { a as Diagnostic, r as ListDiagnosticsFilters } from "./diagnostic-C6TRoBgt.js";
1
+ import { a as Diagnostic, r as ListDiagnosticsFilters } from "./diagnostic-CODFUU-Q.js";
2
2
  import { a as RSToolValue, t as BasicBinding } from "./common-D6TFl6l_.js";
3
- import { n as AnalyzeExpressionInput, t as AnalysisResult } from "./analysis-DA44pfgA.js";
4
- import { o as ConstituentaDraft } from "./constituenta-QY5w1x91.js";
3
+ import { n as AnalyzeExpressionInput, t as AnalysisResult } from "./analysis-ktWFu4BY.js";
4
+ import { o as ConstituentaDraft } from "./constituenta-HTnFtmxt.js";
5
5
  import { i as SessionModelState, r as RecalculateModelResult, s as SetModelValuesInput } from "./model-value-BUhr2IjA.js";
6
- import { n as SessionRevision, r as SessionState, t as SessionHandle } from "./session-CI4rLYby.js";
7
- import { a as SessionStateResult, i as SessionStateDetail, n as ApplySchemaPatchInput, r as ApplySchemaPatchResult } from "./agent-workflow-D22FeODL.js";
8
- import { i as EvaluationResult, r as EvaluateInput } from "./evaluation-Cd4S7-3t.js";
6
+ import { n as SessionRevision, r as SessionState, t as SessionHandle } from "./session-Uc_vHrq9.js";
7
+ import { a as SessionStateDetail, d as SynthesizeResult, i as RestoreOrderResult, n as ApplySchemaPatchInput, o as SessionStateResult, r as ApplySchemaPatchResult, u as SynthesizeInput } from "./agent-workflow-DY-hfAap.js";
8
+ import { i as EvaluationResult, r as EvaluateInput } from "./evaluation-6A7rK4t7.js";
9
9
 
10
10
  //#region src/models/portal-json.d.ts
11
11
  /** Portal JSON import/export format version (schema and model files). */
@@ -103,7 +103,7 @@ type ExportPortalResult = string | PortalSchemaImportData | PortalModelImportDat
103
103
  //#endregion
104
104
  //#region src/models/tool-contract.d.ts
105
105
  /** Agent-visible contract version; bump on breaking API changes. */
106
- declare const CONTRACT_VERSION = "3.0.0";
106
+ declare const CONTRACT_VERSION = "3.2.0";
107
107
  /** Options for constructing an {@link RSToolAgent}. */
108
108
  interface RSToolAgentOptions {
109
109
  /** When set, sessions are persisted to this directory and survive process restarts. */
@@ -158,7 +158,17 @@ interface RSToolAgentContract {
158
158
  evaluate(input: EvaluateInput, sessionId?: string): EvaluationResult;
159
159
  /** Recompute derived model values for all constituents. */
160
160
  recalculateModel(sessionId?: string): RecalculateModelResult;
161
+ /**
162
+ * Restore declaration order: formal topology, semantic clusters when ready,
163
+ * otherwise stable against type/kernel preferred ranks.
164
+ */
165
+ restoreOrder(sessionId?: string): RestoreOrderResult;
166
+ /**
167
+ * Synthesis by embedding: merge constituents from another session into the receiver,
168
+ * then apply an identification table.
169
+ */
170
+ synthesize(input: SynthesizeInput, sessionId?: string): SynthesizeResult;
161
171
  }
162
172
  //#endregion
163
173
  export { ExportPortalInput as a, PortalExportKind as c, PortalModelImportData as d, PortalRsformDetails as f, portalItemToDraft as g, PortalTermForm as h, ExportFormat as i, PORTAL_JSON_CONTRACT_VERSION as l, PortalSchemaImportData as m, RSToolAgentContract as n, ExportPortalResult as o, PortalSchemaConstituenta as p, RSToolAgentOptions as r, ImportDataKind as s, CONTRACT_VERSION as t, PortalImportMetadata as u };
164
- //# sourceMappingURL=tool-contract-sQfr-DYD.d.ts.map
174
+ //# sourceMappingURL=tool-contract-i0v2gbWs.d.ts.map
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as RSToolAgent } from "../models-B255GaEC.js";
2
+ import { t as RSToolAgent } from "../models-BKmWx92e.js";
3
3
  import readline from "node:readline";
4
4
  //#region src/wrapper/stdio-handler.ts
5
5
  const STDIO_METHODS = [
@@ -18,7 +18,9 @@ const STDIO_METHODS = [
18
18
  "setModelValues",
19
19
  "getModelState",
20
20
  "evaluate",
21
- "recalculateModel"
21
+ "recalculateModel",
22
+ "restoreOrder",
23
+ "synthesize"
22
24
  ];
23
25
  function asObject(value) {
24
26
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -138,6 +140,16 @@ async function handleStdioRequest(tool, request) {
138
140
  ok: true,
139
141
  result: tool.recalculateModel(optionalSessionId(params))
140
142
  };
143
+ case "restoreOrder": return {
144
+ id: request.id,
145
+ ok: true,
146
+ result: tool.restoreOrder(optionalSessionId(params))
147
+ };
148
+ case "synthesize": return {
149
+ id: request.id,
150
+ ok: true,
151
+ result: tool.synthesize(omitSessionId(params), optionalSessionId(params))
152
+ };
141
153
  default: return {
142
154
  id: request.id ?? null,
143
155
  ok: false,
@@ -1 +1 @@
1
- {"version":3,"file":"stdio-wrapper.js","names":[],"sources":["../../src/wrapper/stdio-handler.ts","../../src/wrapper/stdio-wrapper.ts"],"sourcesContent":["import type { RSToolAgent } from '../models/rstool-agent';\n\nexport interface StdioRequest {\n id: string | number;\n method: string;\n params?: unknown;\n}\n\nexport interface StdioResponse {\n id: string | number | null;\n ok: boolean;\n result?: unknown;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nexport const STDIO_METHODS = [\n 'ensureSession',\n 'createSession',\n 'getCurrentSession',\n 'setCurrentSession',\n 'applySchemaPatch',\n 'getSessionState',\n 'listDiagnostics',\n 'analyzeExpression',\n 'commitStep',\n 'exportSession',\n 'exportPortal',\n 'importData',\n 'setModelValues',\n 'getModelState',\n 'evaluate',\n 'recalculateModel'\n] as const;\n\nfunction asObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(input: Record<string, unknown>, key: string): string {\n const value = input[key];\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Missing or invalid \"${key}\"`);\n }\n return value;\n}\n\nfunction optionalSessionId(input: Record<string, unknown>): string | undefined {\n const value = input.sessionId;\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction omitSessionId(input: Record<string, unknown>): Record<string, unknown> {\n const { sessionId: _sessionId, ...rest } = input;\n return rest;\n}\n\nexport async function handleStdioRequest(tool: RSToolAgent, request: StdioRequest): Promise<StdioResponse> {\n try {\n const params = asObject(request.params);\n switch (request.method) {\n case 'ping':\n return { id: request.id, ok: true, result: { pong: true, contractVersion: tool.contractVersion } };\n case 'methods':\n return { id: request.id, ok: true, result: STDIO_METHODS };\n case 'ensureSession':\n return {\n id: request.id,\n ok: true,\n result: tool.ensureSession(params.initial as never)\n };\n case 'createSession':\n return {\n id: request.id,\n ok: true,\n result: tool.createSession(params.initial as never)\n };\n case 'getCurrentSession':\n return {\n id: request.id,\n ok: true,\n result: tool.getCurrentSession()\n };\n case 'setCurrentSession':\n return {\n id: request.id,\n ok: true,\n result: tool.setCurrentSession(requiredString(params, 'sessionId'))\n };\n case 'applySchemaPatch':\n return {\n id: request.id,\n ok: true,\n result: tool.applySchemaPatch(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'getSessionState':\n return {\n id: request.id,\n ok: true,\n result: tool.getSessionState(\n (params.detail as 'summary' | 'full' | undefined) ?? 'summary',\n optionalSessionId(params)\n )\n };\n case 'listDiagnostics': {\n const constituentId = params.constituentId;\n const filters = typeof constituentId === 'number' ? { constituentId } : (params.filters as never);\n return {\n id: request.id,\n ok: true,\n result: tool.listDiagnostics(filters, optionalSessionId(params))\n };\n }\n case 'analyzeExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.analyzeExpression(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'commitStep':\n return {\n id: request.id,\n ok: true,\n result: tool.commitStep(params.message as string | undefined, optionalSessionId(params))\n };\n case 'exportSession':\n return {\n id: request.id,\n ok: true,\n result: tool.exportSession(optionalSessionId(params))\n };\n case 'exportPortal':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortal(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'importData':\n return {\n id: request.id,\n ok: true,\n result: tool.importData(params.payload as string | object, params.kind as never)\n };\n case 'setModelValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.setModelValues(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'getModelState':\n return {\n id: request.id,\n ok: true,\n result: tool.getModelState(optionalSessionId(params))\n };\n case 'evaluate':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluate(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'recalculateModel':\n return {\n id: request.id,\n ok: true,\n result: tool.recalculateModel(optionalSessionId(params))\n };\n default:\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'METHOD_NOT_FOUND',\n message: `Unknown method: ${request.method}`\n }\n };\n }\n } catch (error) {\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error\n }\n };\n }\n}\n","#!/usr/bin/env node\nimport readline from 'node:readline';\n\nimport { RSToolAgent } from '../models/rstool-agent';\nimport { handleStdioRequest, type StdioRequest, type StdioResponse } from './stdio-handler';\n\nconst persistenceDir = process.env.RSTOOL_PERSISTENCE_DIR;\nconst tool = new RSToolAgent(persistenceDir ? { persistenceDir } : {});\n\nfunction writeResponse(response: StdioResponse): void {\n if (!process.stdout.writable || process.stdout.destroyed || process.stdout.writableEnded) {\n return;\n }\n try {\n process.stdout.write(`${JSON.stringify(response)}\\n`);\n } catch {\n // The client might have already closed stdout (EPIPE). Safe to ignore.\n }\n}\n\nconst input = readline.createInterface({\n input: process.stdin,\n crlfDelay: Infinity\n});\n\nwriteResponse({\n id: null,\n ok: true,\n result: {\n ready: true,\n wrapper: 'rstool-stdio',\n contractVersion: tool.contractVersion\n }\n});\n\ninput.on('line', line => {\n if (!line.trim()) {\n return;\n }\n try {\n const request = JSON.parse(line) as StdioRequest;\n if (!('id' in request) || !('method' in request)) {\n throw new Error('Request must include \"id\" and \"method\"');\n }\n void handleStdioRequest(tool, request).then(writeResponse);\n } catch (error) {\n writeResponse({\n id: null,\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: error instanceof Error ? error.message : 'Invalid JSON'\n }\n });\n }\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"stdio-wrapper.js","names":[],"sources":["../../src/wrapper/stdio-handler.ts","../../src/wrapper/stdio-wrapper.ts"],"sourcesContent":["import type { RSToolAgent } from '../models/rstool-agent';\n\nexport interface StdioRequest {\n id: string | number;\n method: string;\n params?: unknown;\n}\n\nexport interface StdioResponse {\n id: string | number | null;\n ok: boolean;\n result?: unknown;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nexport const STDIO_METHODS = [\n 'ensureSession',\n 'createSession',\n 'getCurrentSession',\n 'setCurrentSession',\n 'applySchemaPatch',\n 'getSessionState',\n 'listDiagnostics',\n 'analyzeExpression',\n 'commitStep',\n 'exportSession',\n 'exportPortal',\n 'importData',\n 'setModelValues',\n 'getModelState',\n 'evaluate',\n 'recalculateModel',\n 'restoreOrder',\n 'synthesize'\n] as const;\n\nfunction asObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(input: Record<string, unknown>, key: string): string {\n const value = input[key];\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Missing or invalid \"${key}\"`);\n }\n return value;\n}\n\nfunction optionalSessionId(input: Record<string, unknown>): string | undefined {\n const value = input.sessionId;\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction omitSessionId(input: Record<string, unknown>): Record<string, unknown> {\n const { sessionId: _sessionId, ...rest } = input;\n return rest;\n}\n\nexport async function handleStdioRequest(tool: RSToolAgent, request: StdioRequest): Promise<StdioResponse> {\n try {\n const params = asObject(request.params);\n switch (request.method) {\n case 'ping':\n return { id: request.id, ok: true, result: { pong: true, contractVersion: tool.contractVersion } };\n case 'methods':\n return { id: request.id, ok: true, result: STDIO_METHODS };\n case 'ensureSession':\n return {\n id: request.id,\n ok: true,\n result: tool.ensureSession(params.initial as never)\n };\n case 'createSession':\n return {\n id: request.id,\n ok: true,\n result: tool.createSession(params.initial as never)\n };\n case 'getCurrentSession':\n return {\n id: request.id,\n ok: true,\n result: tool.getCurrentSession()\n };\n case 'setCurrentSession':\n return {\n id: request.id,\n ok: true,\n result: tool.setCurrentSession(requiredString(params, 'sessionId'))\n };\n case 'applySchemaPatch':\n return {\n id: request.id,\n ok: true,\n result: tool.applySchemaPatch(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'getSessionState':\n return {\n id: request.id,\n ok: true,\n result: tool.getSessionState(\n (params.detail as 'summary' | 'full' | undefined) ?? 'summary',\n optionalSessionId(params)\n )\n };\n case 'listDiagnostics': {\n const constituentId = params.constituentId;\n const filters = typeof constituentId === 'number' ? { constituentId } : (params.filters as never);\n return {\n id: request.id,\n ok: true,\n result: tool.listDiagnostics(filters, optionalSessionId(params))\n };\n }\n case 'analyzeExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.analyzeExpression(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'commitStep':\n return {\n id: request.id,\n ok: true,\n result: tool.commitStep(params.message as string | undefined, optionalSessionId(params))\n };\n case 'exportSession':\n return {\n id: request.id,\n ok: true,\n result: tool.exportSession(optionalSessionId(params))\n };\n case 'exportPortal':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortal(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'importData':\n return {\n id: request.id,\n ok: true,\n result: tool.importData(params.payload as string | object, params.kind as never)\n };\n case 'setModelValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.setModelValues(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'getModelState':\n return {\n id: request.id,\n ok: true,\n result: tool.getModelState(optionalSessionId(params))\n };\n case 'evaluate':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluate(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'recalculateModel':\n return {\n id: request.id,\n ok: true,\n result: tool.recalculateModel(optionalSessionId(params))\n };\n case 'restoreOrder':\n return {\n id: request.id,\n ok: true,\n result: tool.restoreOrder(optionalSessionId(params))\n };\n case 'synthesize':\n return {\n id: request.id,\n ok: true,\n result: tool.synthesize(omitSessionId(params) as never, optionalSessionId(params))\n };\n default:\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'METHOD_NOT_FOUND',\n message: `Unknown method: ${request.method}`\n }\n };\n }\n } catch (error) {\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error\n }\n };\n }\n}\n","#!/usr/bin/env node\nimport readline from 'node:readline';\n\nimport { RSToolAgent } from '../models/rstool-agent';\nimport { handleStdioRequest, type StdioRequest, type StdioResponse } from './stdio-handler';\n\nconst persistenceDir = process.env.RSTOOL_PERSISTENCE_DIR;\nconst tool = new RSToolAgent(persistenceDir ? { persistenceDir } : {});\n\nfunction writeResponse(response: StdioResponse): void {\n if (!process.stdout.writable || process.stdout.destroyed || process.stdout.writableEnded) {\n return;\n }\n try {\n process.stdout.write(`${JSON.stringify(response)}\\n`);\n } catch {\n // The client might have already closed stdout (EPIPE). Safe to ignore.\n }\n}\n\nconst input = readline.createInterface({\n input: process.stdin,\n crlfDelay: Infinity\n});\n\nwriteResponse({\n id: null,\n ok: true,\n result: {\n ready: true,\n wrapper: 'rstool-stdio',\n contractVersion: tool.contractVersion\n }\n});\n\ninput.on('line', line => {\n if (!line.trim()) {\n return;\n }\n try {\n const request = JSON.parse(line) as StdioRequest;\n if (!('id' in request) || !('method' in request)) {\n throw new Error('Request must include \"id\" and \"method\"');\n }\n void handleStdioRequest(tool, request).then(writeResponse);\n } catch (error) {\n writeResponse({\n id: null,\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: error instanceof Error ? error.message : 'Invalid JSON'\n }\n });\n }\n});\n"],"mappings":"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"}
@@ -46,6 +46,7 @@
46
46
  | `0x8903` | `schemaMissingConvention` | — | У `basic`/`constant`/`structure` нужна конвенция. |
47
47
  | `0x8904` | `schemaMissingTerm` | — | У неопределяемого понятия нужен термин. |
48
48
  | `0x8905` | `schemaTypeMismatch` | `[manual, computed]` | расхождение ручной и вычисленной типизации. |
49
+ | `0x8906` | `schemaDependencyCycle` | `[cycle]` | Круг в графе определений (`F3 → P1 → F3`). Разорви цикл: убери взаимные ссылки. |
49
50
 
50
51
  Поле `params` для омонимов/дубликатов — `[aliases]` (строка с alias через запятую).
51
52
 
@@ -123,37 +124,37 @@
123
124
 
124
125
  ## Типизация и структура
125
126
 
126
- | Код | Имя | `params` | Исправление |
127
- | -------- | ---------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
128
- | `0x880A` | `typesNotEqual` | `[a, b, operator]` | Операнды `operator` должны иметь равный тип (`a` ≠ `b`). |
129
- | `0x8825` | `typesNotCompatible` | `[a, b, operator]` | Типы `a` и `b` несовместимы для `operator`. |
130
- | `0x8804` | `globalNotTyped` | `[name]` | Поставщик `name` не типизирован: добавь и проанализируй его раньше. |
131
- | `0x8805` | `invalidDecart` | `[arg]` | Аргумент `arg` оператора `×` неподходящей ступени. |
132
- | `0x8806` | `invalidBoolean` | `[arg]` | Аргумент `arg` оператора `ℬ()` неподходящей ступени. |
133
- | `0x8810` | `invalidReduce` | `[arg]` | `red(arg)` требует ступень `ℬℬ`. |
134
- | `0x8807` | `invalidTypeOperation` | `[operator, type]` | Аргумент `type` оператора `operator` (`∪`, `∈`, `D{}`, `:∈` и т.п.) должен быть множеством. |
135
- | `0x8808` | `invalidCard` | `[arg]` | `card(arg)` только над множеством. |
136
- | `0x8809` | `invalidDebool` | `[arg]` | `debool(arg)` требует ступень-множество с гарантией синглетона. |
137
- | `0x880B` | `globalFuncWithoutArgs` | `[name]` | Терм-/предикат-функция `name` вызвана без аргументов: нужен `F#[…]` / `P#[…]`. |
138
- | `0x8830` | `projectionSetArgumentNotSet` | `[operator, actual]` | `Pr*` применяется к множеству; аргумент не типизирован как `ℬ(H)`. |
139
- | `0x8831` | `projectionSetArgumentNotTupleSet` | `[operator, actual]` | `Pr*` требует множество кортежей `ℬ(H1×…×Hn)`; аргумент — множество не-кортежей, напр. `ℬ(X1)`. |
140
- | `0x8832` | `projectionSetIndexOutOfRange` | `[operator, index, arity, actual]` | Индекс проекции `index` превышает размерность `arity` кортежа аргумента `actual`. |
141
- | `0x8833` | `projectionTupleArgumentNotTuple` | `[operator, actual]` | `pr*` применяется к кортежу `H1×…×Hn`; получен другой тип. |
142
- | `0x8834` | `projectionTupleIndexOutOfRange` | `[operator, index, arity, actual]` | Индекс `index` превышает размерность `arity` кортежа `actual`. |
143
- | `0x8813` | `invalidEnumeration` | `[a, b]` | Элементы перечисления разной типизации (`a` ≠ `b`). |
144
- | `0x8814` | `invalidCortegeDeclare` | — | Число переменных кортежа ≠ размерности `×` (напр. `∀(a,b)∈X1`). |
145
- | `0x8816` | `invalidElementPredicate` | `[a, operator, c]` | `a operator c` (`ξ∈S`) с несовместимыми ступенями: `a` — тип элемента, `c` — тип множества. |
146
- | `0x8817` | `invalidEmptySetUsage` | — | Бессмысленное использование `∅` (напр. `X1∪∅`). |
147
- | `0x8818` | `invalidArgsArity` | `[expected, actual]` | Неверное число аргументов функции (`expected` ≠ `actual`). |
148
- | `0x8819` | `invalidArgumentType` | `[expected, actual]` | Тип аргумента не соответствует объявлению: ожидалось `expected`, получено `actual`. |
149
- | `0x881C` | `globalStructure` | — | Некорректный домен родовой структуры (`cstType` STRUCTURED): нужна ступень-структура вроде `ℬ(X1×D2)`, а не, напр., `X1∩X1`. |
150
- | `0x8821` | `radicalUsage` | `[name]` | Радикал `name` (`R#`) допустим только в домене параметра `[…]` у `F#` / `P#`, не в теле формулы. `R#` не объявляется конституентой — см. `SYNTAX.md`. |
151
- | `0x8824` | `arithmeticNotSupported` | `[type, operator]` | `type` не поддерживает арифметику `operator`: нужна ступень `Z` или `C#`. |
152
- | `0x8826` | `orderingNotSupported` | `[type, operator]` | `type` не поддерживает порядок `operator`: нужна ступень `Z` или `C#`. |
153
- | `0x8827` | `expectedLogic` | `[type]` | Нужна логическая формула, получен тип `type`. |
154
- | `0x8828` | `expectedSetexpr` | `[type]` | Нужно теоретико-множественное выражение, получен тип `type` (напр. `Logic`). |
155
- | `0x8829` | `invalidArgumentCortegeDeclare` | — | Связное объявление кортежа запрещено в аргументах функции (`[(a,b)∈S1]`): используй проекции или раздельные переменные. |
156
- | `0x882A` | `invalidQuantifierDomain` | `[operator, type]` | Область квантора `operator` (`∀`/`∃`) должна быть множеством, а не `type`. |
127
+ | Код | Имя | `params` | Исправление |
128
+ | -------- | ---------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
129
+ | `0x880A` | `typesNotEqual` | `[a, b, operator]` | Операнды `operator` должны иметь равный тип (`a` ≠ `b`). |
130
+ | `0x8825` | `typesNotCompatible` | `[a, b, operator]` | Типы `a` и `b` несовместимы для `operator`. |
131
+ | `0x8804` | `globalNotTyped` | `[name]` | Поставщик `name` не типизирован: добавь и проанализируй его раньше. Если `name` в круге определений, анализ схемы/выражения может заменить код на `schemaDependencyCycle` (также для `globalFuncWithoutArgs` у голых `F#`/`P#`). |
132
+ | `0x8805` | `invalidDecart` | `[arg]` | Аргумент `arg` оператора `×` неподходящей ступени. |
133
+ | `0x8806` | `invalidBoolean` | `[arg]` | Аргумент `arg` оператора `ℬ()` неподходящей ступени. |
134
+ | `0x8810` | `invalidReduce` | `[arg]` | `red(arg)` требует ступень `ℬℬ`. |
135
+ | `0x8807` | `invalidTypeOperation` | `[operator, type]` | Аргумент `type` оператора `operator` (`∪`, `∈`, `D{}`, `:∈` и т.п.) должен быть множеством. |
136
+ | `0x8808` | `invalidCard` | `[arg]` | `card(arg)` только над множеством. |
137
+ | `0x8809` | `invalidDebool` | `[arg]` | `debool(arg)` требует ступень-множество с гарантией синглетона. |
138
+ | `0x880B` | `globalFuncWithoutArgs` | `[name]` | Терм-/предикат-функция `name` вызвана без аргументов: нужен `F#[…]` / `P#[…]`. |
139
+ | `0x8830` | `projectionSetArgumentNotSet` | `[operator, actual]` | `Pr*` применяется к множеству; аргумент не типизирован как `ℬ(H)`. |
140
+ | `0x8831` | `projectionSetArgumentNotTupleSet` | `[operator, actual]` | `Pr*` требует множество кортежей `ℬ(H1×…×Hn)`; аргумент — множество не-кортежей, напр. `ℬ(X1)`. |
141
+ | `0x8832` | `projectionSetIndexOutOfRange` | `[operator, index, arity, actual]` | Индекс проекции `index` превышает размерность `arity` кортежа аргумента `actual`. |
142
+ | `0x8833` | `projectionTupleArgumentNotTuple` | `[operator, actual]` | `pr*` применяется к кортежу `H1×…×Hn`; получен другой тип. |
143
+ | `0x8834` | `projectionTupleIndexOutOfRange` | `[operator, index, arity, actual]` | Индекс `index` превышает размерность `arity` кортежа `actual`. |
144
+ | `0x8813` | `invalidEnumeration` | `[a, b]` | Элементы перечисления разной типизации (`a` ≠ `b`). |
145
+ | `0x8814` | `invalidCortegeDeclare` | — | Число переменных кортежа ≠ размерности `×` (напр. `∀(a,b)∈X1`). |
146
+ | `0x8816` | `invalidElementPredicate` | `[a, operator, c]` | `a operator c` (`ξ∈S`) с несовместимыми ступенями: `a` — тип элемента, `c` — тип множества. |
147
+ | `0x8817` | `invalidEmptySetUsage` | — | Бессмысленное использование `∅` (напр. `X1∪∅`). |
148
+ | `0x8818` | `invalidArgsArity` | `[expected, actual]` | Неверное число аргументов функции (`expected` ≠ `actual`). |
149
+ | `0x8819` | `invalidArgumentType` | `[expected, actual]` | Тип аргумента не соответствует объявлению: ожидалось `expected`, получено `actual`. |
150
+ | `0x881C` | `globalStructure` | — | Некорректный домен родовой структуры (`cstType` STRUCTURED): нужна ступень-структура вроде `ℬ(X1×D2)`, а не, напр., `X1∩X1`. |
151
+ | `0x8821` | `radicalUsage` | `[name]` | Радикал `name` (`R#`) допустим только в домене параметра `[…]` у `F#` / `P#`, не в теле формулы. `R#` не объявляется конституентой — см. `SYNTAX.md`. |
152
+ | `0x8824` | `arithmeticNotSupported` | `[type, operator]` | `type` не поддерживает арифметику `operator`: нужна ступень `Z` или `C#`. |
153
+ | `0x8826` | `orderingNotSupported` | `[type, operator]` | `type` не поддерживает порядок `operator`: нужна ступень `Z` или `C#`. |
154
+ | `0x8827` | `expectedLogic` | `[type]` | Нужна логическая формула, получен тип `type`. |
155
+ | `0x8828` | `expectedSetexpr` | `[type]` | Нужно теоретико-множественное выражение, получен тип `type` (напр. `Logic`). |
156
+ | `0x8829` | `invalidArgumentCortegeDeclare` | — | Связное объявление кортежа запрещено в аргументах функции (`[(a,b)∈S1]`): используй проекции или раздельные переменные. |
157
+ | `0x882A` | `invalidQuantifierDomain` | `[operator, type]` | Область квантора `operator` (`∀`/`∃`) должна быть множеством, а не `type`. |
157
158
 
158
159
  ## Фильтр `Fi`
159
160
 
package/docs/DOMAIN.md CHANGED
@@ -55,10 +55,17 @@
55
55
  - **Основание** — конституента, из которой формально порождают новые термы.
56
56
  - **Порожденная конституента** — построена из основания без новой предметной договоренности.
57
57
 
58
- ## ОСС и синтез
58
+ ## Синтез
59
59
 
60
+ - **Синтез** — общее название операций объединения концептуальных схем через таблицу отождествлений.
61
+ - **Встраивание** — вставка конституент одной КС в другую (с опциональной таблицей отождествлений). В Portal UI — «Встраивание схемы»; в rstool — метод `synthesize`.
62
+ - **Отождествление** — замена одной конституенты другой по таблице отождествлений.
63
+
64
+ ## ОСС
65
+
66
+ - **Операционная схема синтеза (`ОСС`)** — граф загрузок и синтезов КС.
60
67
  - **Загрузка** добавляет внешнюю или собственную КС в ОСС.
61
- - **Синтез** строит новую КС из операций-аргументов через таблицу отождествлений.
68
+ - **Синтез (операция ОСС)** строит новую КС из операций-аргументов через таблицу отождествлений.
62
69
  - **Наследованные конституенты** пришли из исходных схем; их определения обычно read-only.
63
70
  - **Сквозные изменения** идут от исходной конституенты к наследникам.
64
71
  - **Ромбовидный синтез** использует КС с общими предками; чаще требует ручного отождествления дублей.
package/docs/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Какой файл читать
8
8
 
9
- - **DOMAIN.md** — термины Portal: конституента, неопределяемые и производные понятия, ядро/тело КС, интерпретация, ОСС, синтез.
9
+ - **DOMAIN.md** — термины Portal: конституента, неопределяемые и производные понятия, ядро/тело КС, интерпретация, синтез / встраивание, ОСС.
10
10
  - **CONCEPTUAL-SCHEMA.md** — проектирование и ревью концептуальных схем (в т.ч. терм-функция вместо множества пар).
11
11
  - **CONSTITUENTA.md** — структура и правила конституент.
12
12
  - **BASE-SELECTION.md** — выбор основания: `X#`, `C#` или `Z`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsconcept/rstool",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "description": "Agent-facing library for incremental RSForm construction, RSLang analysis, diagnostics, modeling, and evaluation. Wraps @rsconcept/domain with a deterministic session contract.",
5
5
  "license": "MIT",
6
6
  "author": "IRBorisov",
@@ -155,6 +155,7 @@ tool.applySchemaPatch({
155
155
  | `radicalUsage` | `R1` в теле формулы или как конституента | `R#` только в `[…]` у `F#`/`P#` |
156
156
  | `schemaMissingConvention` | `X1` без конвенции | добавь предметную конвенцию |
157
157
  | `schemaHomonym` | одинаковый термин у разных конституент | различай термины |
158
+ | `schemaDependencyCycle` | круг в определениях (`F3 → P1 → F3`) | разорви цикл: убери взаимные ссылки |
158
159
  | `localOutOfScopeParentheses` | `∀a∈S P(a) & Q(a)` | `∀a∈S (P(a) & Q(a))` |
159
160
  | `invalidFilterSyntax` | кривой `Fi` | `Fi1[{ξ}](S1)` / `Fi1,2[D1,D2](S1)` |
160
161
 
@@ -254,6 +255,31 @@ const forPortal = tool.exportPortal({ kind: 'schema' });
254
255
 
255
256
  Не передавай `/details` с `kind: 'session'`. REST и curl — [PORTAL-API.md](../../docs/PORTAL-API.md).
256
257
 
258
+ ## Встраивание схемы (синтез)
259
+
260
+ ```ts
261
+ const receiver = tool.createSession({ title: 'Base' });
262
+ tool.applySchemaPatch({ items: [{ alias: 'X1', term: 'человек' }] }, receiver.sessionId);
263
+
264
+ const source = tool.createSession({ title: 'Donor' });
265
+ tool.applySchemaPatch(
266
+ {
267
+ items: [
268
+ { alias: 'X1', term: 'персона' },
269
+ { alias: 'S1', definitionFormal: 'ℬ(X1)' }
270
+ ]
271
+ },
272
+ source.sessionId
273
+ );
274
+
275
+ tool.setCurrentSession(receiver.sessionId);
276
+ tool.synthesize({
277
+ sourceSessionId: source.sessionId,
278
+ substitutions: [{ original: 'X1', substitution: 'X1' }] // source X1 → receiver X1
279
+ });
280
+ // receiver: X1 (человек), S1 = ℬ(X1) — импортированный X1 отождествлён и удалён
281
+ ```
282
+
257
283
  ## Образец текста ревью (не код)
258
284
 
259
285
  После [воркфлоу ревью](GUIDE.md#ревью--оценка-готовой-кс) ответ может выглядеть так:
@@ -14,7 +14,7 @@
14
14
 
15
15
  ## Быстрый контракт для агента
16
16
 
17
- - Library API: `tool.applySchemaPatch(input, sessionId?)` — единственный путь правки схемы.
17
+ - Library API: `tool.applySchemaPatch(input, sessionId?)` — основной путь правки схемы; `synthesize` — встраивание конституент из другой сессии (синтез с таблицей отождествлений).
18
18
  - Stdio/MCP: **плоские** `params` — поля метода и optional `sessionId` на одном уровне (без `params.input`).
19
19
  - Состояние: `getSessionState()` (summary) или `getSessionState('full')`.
20
20
  - Импорт/экспорт Portal: `importData`, `exportPortal({ kind })`.
@@ -225,6 +225,7 @@ kind `auto` (default) определит `portal-details` или `portal-schema`
225
225
  | `convention` | конвенция |
226
226
  | `comment` | комментарий |
227
227
  | `applySchemaPatch` | правка схемы |
228
+ | `synthesize` | встраивание / синтез схем |
228
229
  | `analyzeExpression` | проверка / анализ выражения |
229
230
  | `listDiagnostics`, `diagnostics` | диагностики |
230
231
  | `setModelValues`, `getModelState` | интерпретация, значения модели |
@@ -5,7 +5,7 @@
5
5
  ## Контракт rstool
6
6
 
7
7
  - Пакет: `@rsconcept/rstool`
8
- - Версия контракта: `3.0.0` (`CONTRACT_VERSION`)
8
+ - Версия контракта: `3.2.0` (`CONTRACT_VERSION`)
9
9
  - Основной класс: `RSToolAgent`
10
10
  - Публичные импорты: `@rsconcept/rstool` и `@rsconcept/rstool/wrapper`
11
11
  - Опции: `new RSToolAgent({ persistenceDir? })` — каталог для сохранения сессий между перезапусками (stdio/MCP: `RSTOOL_PERSISTENCE_DIR`)
@@ -14,24 +14,26 @@
14
14
 
15
15
  ### Методы library API
16
16
 
17
- | Метод | Назначение |
18
- | ---------------------------------------------- | ------------------------------------------- |
19
- | `ensureSession(initial?)` | Вернуть текущую сессию или создать новую |
20
- | `createSession(initial?)` | Новая in-memory сессия (становится текущей) |
21
- | `getCurrentSession()` | Текущая активная сессия или `null` |
22
- | `setCurrentSession(sessionId)` | Сделать сессию текущей |
23
- | `applySchemaPatch(input, sessionId?)` | Единственный путь правки схемы |
24
- | `getSessionState(detail?, sessionId?)` | `summary` (default) или `full` |
25
- | `listDiagnostics(filters?, sessionId?)` | Активные диагностики |
26
- | `analyzeExpression(input, sessionId?)` | Разбор без сохранения |
27
- | `commitStep(message?, sessionId?)` | Ревизия |
28
- | `exportSession(sessionId?)` | JSON-строка сессии |
29
- | `exportPortal({ kind, format? }, sessionId?)` | Portal Load from JSON |
30
- | `importData(payload, kind?)` | Импорт сессии / Portal |
31
- | `setModelValues({ set?, clear? }, sessionId?)` | Значения модели (**async** — `await`) |
32
- | `getModelState(sessionId?)` | Состояние интерпретации |
33
- | `evaluate(input, sessionId?)` | Scratch или конституента |
34
- | `recalculateModel(sessionId?)` | Пересчёт производных |
17
+ | Метод | Назначение |
18
+ | ---------------------------------------------- | ------------------------------------------------------------------ |
19
+ | `ensureSession(initial?)` | Вернуть текущую сессию или создать новую |
20
+ | `createSession(initial?)` | Новая in-memory сессия (становится текущей) |
21
+ | `getCurrentSession()` | Текущая активная сессия или `null` |
22
+ | `setCurrentSession(sessionId)` | Сделать сессию текущей |
23
+ | `applySchemaPatch(input, sessionId?)` | Единственный путь правки схемы |
24
+ | `getSessionState(detail?, sessionId?)` | `summary` (default) или `full` |
25
+ | `listDiagnostics(filters?, sessionId?)` | Активные диагностики |
26
+ | `analyzeExpression(input, sessionId?)` | Разбор без сохранения |
27
+ | `commitStep(message?, sessionId?)` | Ревизия |
28
+ | `exportSession(sessionId?)` | JSON-строка сессии |
29
+ | `exportPortal({ kind, format? }, sessionId?)` | Portal Load from JSON |
30
+ | `importData(payload, kind?)` | Импорт сессии / Portal |
31
+ | `setModelValues({ set?, clear? }, sessionId?)` | Значения модели (**async** — `await`) |
32
+ | `getModelState(sessionId?)` | Состояние интерпретации |
33
+ | `evaluate(input, sessionId?)` | Scratch или конституента |
34
+ | `recalculateModel(sessionId?)` | Пересчёт производных |
35
+ | `restoreOrder(sessionId?)` | Упорядочить конституенты (топология + семантика) |
36
+ | `synthesize(input, sessionId?)` | Синтез (встраивание): слить другую сессию + таблица отождествлений |
35
37
 
36
38
  Служебные (stdio / MCP): `ping` / `pong`+`contractVersion`; `methods` / `list_methods`.
37
39
 
@@ -59,6 +61,8 @@ Stdio использует **camelCase** имён методов (как library
59
61
  | `getModelState` | `get_model_state` |
60
62
  | `evaluate` | `evaluate` |
61
63
  | `recalculateModel` | `recalculate_model` |
64
+ | `restoreOrder` | `restore_order` |
65
+ | `synthesize` | `synthesize` |
62
66
 
63
67
  ## `applySchemaPatch`
64
68
 
@@ -156,6 +160,48 @@ await tool.setModelValues({
156
160
 
157
161
  Формы `value` для `X#` / `S#` — [MODEL-TESTING.md](../../docs/MODEL-TESTING.md).
158
162
 
163
+ ## `restoreOrder`
164
+
165
+ Упорядочивает конституенты сессии одним проходом Kahn:
166
+
167
+ - формальные зависимости — жёстко (поставщик раньше зависимого);
168
+ - семантические дети — сразу после родителя, если уже готовы;
169
+ - иначе — стабильно относительно приоритета типов/ядра.
170
+
171
+ ```ts
172
+ const { orderedAliases } = tool.restoreOrder();
173
+ // → { orderedIds: number[], orderedAliases: string[] }
174
+ ```
175
+
176
+ ## `synthesize`
177
+
178
+ **Синтез** в rstool сейчас — это **встраивание** схемы: вставка конституент из другой сессии в текущую с опциональной таблицей отождествлений (как «Встраивание схемы» в Portal UI).
179
+
180
+ ```ts
181
+ const receiver = tool.createSession();
182
+ const source = tool.createSession();
183
+ tool.applySchemaPatch({ items: [{ alias: 'X1' }] }, source.sessionId);
184
+
185
+ tool.setCurrentSession(receiver.sessionId);
186
+ tool.synthesize({
187
+ sourceSessionId: source.sessionId,
188
+ // items?: ['X1'], // optional subset of source aliases
189
+ substitutions: [{ original: 'X1', substitution: 'X1' }], // source → receiver
190
+ commitMessage: 'merge'
191
+ });
192
+ ```
193
+
194
+ **Вход**
195
+
196
+ | Поле | Смысл |
197
+ | ----------------- | --------------------------------------------------------------------------------------------- |
198
+ | `sourceSessionId` | Сессия-источник (не должна совпадать с receiver) |
199
+ | `items?` | Алиасы конституент источника; пусто / omit — все |
200
+ | `substitutions?` | Таблица отождествлений по алиасам: в каждой строке один алиас источника и один алиас receiver |
201
+ | `commitMessage?` | Ревизия после успеха |
202
+
203
+ Алиасы импорта перенумеровываются при непустом receiver (`X1` → `X2`, …). Формулы и текстовые ссылки обновляются. Результат: `summary`, `idMap`, `aliasMapping`, `deletedIds`, `insertedIds`, и опционально `revision` (если был `commitMessage`). Также `success` / `failed` — как у `applySchemaPatch` (режим best-effort после встраивания).
204
+
159
205
  ## `importData` / `exportSession` / `exportPortal`
160
206
 
161
207
  ### `importData(payload, kind?)`
package/src/index.ts CHANGED
@@ -54,6 +54,9 @@ export {
54
54
  type SessionSummaryItem,
55
55
  type SessionState,
56
56
  type SetConstituentaValueInput,
57
- type SetModelValuesInput
57
+ type SetModelValuesInput,
58
+ type SynthesisSubstitution,
59
+ type SynthesizeInput,
60
+ type SynthesizeResult
58
61
  } from './models';
59
62
  export { RSToolWrapperClient, type RSToolWrapperClientOptions, type WrapperResponse } from './wrapper/client';
@@ -1,10 +1,10 @@
1
1
  import {
2
- type Constituenta,
3
2
  type CstDiagnostic,
4
3
  DiagnosticKind,
5
4
  modelStatusCstDiagnostic,
6
5
  RSDiagnosticCode
7
6
  } from '@rsconcept/domain/library';
7
+ import { type DiagnosticSourceFields } from '@rsconcept/domain/library/rsform-api';
8
8
  import { EvalStatus } from '@rsconcept/domain/library/rsmodel';
9
9
  import { isCritical, RSErrorCode, type RSErrorDescription } from '@rsconcept/domain/rslang/error';
10
10
 
@@ -43,7 +43,7 @@ export function getDiagnosticSeverity(code: number): DiagnosticSeverity {
43
43
  return isCritical(code as RSErrorCode) ? 'error' : 'warning';
44
44
  }
45
45
 
46
- export function expandCstDiagnostic(cst: Constituenta, diagnostic: CstDiagnostic): Diagnostic {
46
+ export function expandCstDiagnostic(cst: DiagnosticSourceFields, diagnostic: CstDiagnostic): Diagnostic {
47
47
  const expression = expressionForCstDiagnostic(cst, diagnostic);
48
48
  return {
49
49
  ...diagnostic,
@@ -76,12 +76,12 @@ export function expressionDiagnostic(
76
76
  };
77
77
  }
78
78
 
79
- export function modelStatusDiagnostic(status: EvalStatus, cst: Constituenta): Diagnostic | null {
79
+ export function modelStatusDiagnostic(status: EvalStatus, cst: DiagnosticSourceFields): Diagnostic | null {
80
80
  const base = modelStatusCstDiagnostic(status, cst.cst_type);
81
81
  return base ? expandCstDiagnostic(cst, base) : null;
82
82
  }
83
83
 
84
- function expressionForCstDiagnostic(cst: Constituenta, diagnostic: CstDiagnostic): string {
84
+ function expressionForCstDiagnostic(cst: DiagnosticSourceFields, diagnostic: CstDiagnostic): string {
85
85
  switch (diagnostic.code) {
86
86
  case RSDiagnosticCode.schemaHomonym:
87
87
  case RSDiagnosticCode.schemaMissingTerm:
@@ -90,6 +90,9 @@ function expressionForCstDiagnostic(cst: Constituenta, diagnostic: CstDiagnostic
90
90
  return cst.convention;
91
91
  case RSDiagnosticCode.schemaTypeMismatch:
92
92
  return cst.typification_manual;
93
+ case RSDiagnosticCode.schemaDependencyCycle:
94
+ case RSDiagnosticCode.schemaFormalDuplicate:
95
+ return cst.definition_formal;
93
96
  default:
94
97
  return cst.definition_formal;
95
98
  }
@@ -75,7 +75,7 @@ export function enrichSessionConstituents(session: SessionState): EnrichedConsti
75
75
  }
76
76
  }
77
77
 
78
- assignSchemaDiagnostics(schema.items, resolveAlias, normalizedDefinitions);
78
+ assignSchemaDiagnostics(schema.items, resolveAlias, normalizedDefinitions, schema.graph);
79
79
 
80
80
  return session.items.map(item => ({
81
81
  item,
@@ -1,6 +1,6 @@
1
- import { RSLangAnalyzer, type AnalysisFull, type ValueClass } from '@rsconcept/domain/rslang';
2
1
  import { getAnalysisFor } from '@rsconcept/domain/library/rsform-api';
3
- import { CstType, type RSForm } from '@rsconcept/domain/library/rsform';
2
+ import { type RSForm } from '@rsconcept/domain/library/rsform';
3
+ import { RSLangAnalyzer } from '@rsconcept/domain/rslang';
4
4
 
5
5
  import {
6
6
  type AnalysisResult,
@@ -9,6 +9,7 @@ import {
9
9
  type Diagnostic,
10
10
  type SessionState
11
11
  } from '../models';
12
+ import { buildRSFormFromSession } from './rsform-builder';
12
13
  import { toPublicAnalysis } from './types';
13
14
 
14
15
  export class SchemaAdapter {
@@ -16,9 +17,8 @@ export class SchemaAdapter {
16
17
  session: SessionState,
17
18
  draft: ConstituentaDraft
18
19
  ): { result: AnalysisResult; diagnostics: Diagnostic[] } {
19
- const analyzer = this.buildAnalyzer(session);
20
- const schema = this.toPseudoRSFormState(session, analyzer);
21
- const analysis = getAnalysisFor(draft.definitionFormal, draft.cstType, schema as unknown as RSForm, draft.alias);
20
+ const schema = this.toAnalysisSchema(session, draft);
21
+ const analysis = getAnalysisFor(draft.definitionFormal, draft.cstType, schema, draft.alias);
22
22
  const target = { constituentId: draft.id, alias: draft.alias };
23
23
  const result = toPublicAnalysis(
24
24
  {
@@ -70,18 +70,50 @@ export class SchemaAdapter {
70
70
  };
71
71
  }
72
72
 
73
- private buildAnalyzer(session: SessionState): RSLangAnalyzer {
74
- const analyzer = new RSLangAnalyzer();
75
- for (const item of session.items) {
76
- if (item.cstType === CstType.BASE) {
77
- analyzer.addBase(item.alias);
73
+ /**
74
+ * Schema view for analysis: session items with the draft expression merged in so the
75
+ * dependency graph (and cycle diagnostics) reflect the expression under check.
76
+ */
77
+ private toAnalysisSchema(session: SessionState, draft: ConstituentaDraft): RSForm {
78
+ const items = session.items.map(item => {
79
+ if (item.id !== draft.id) {
80
+ return item;
78
81
  }
79
- analyzer.setGlobal(
80
- item.alias,
81
- item.analysis.type as AnalysisFull['type'],
82
- item.analysis.valueClass as ValueClass | null
83
- );
82
+ return {
83
+ ...item,
84
+ alias: draft.alias,
85
+ cstType: draft.cstType,
86
+ definitionFormal: draft.definitionFormal,
87
+ term: draft.term ?? item.term,
88
+ definitionText: draft.definitionText ?? item.definitionText,
89
+ convention: draft.convention ?? item.convention,
90
+ // Drop cached type so mutual references surface as untyped → cycle.
91
+ analysis: {
92
+ ...item.analysis,
93
+ success: false,
94
+ type: null,
95
+ valueClass: null
96
+ }
97
+ };
98
+ });
99
+ if (!items.some(item => item.id === draft.id)) {
100
+ items.push({
101
+ id: draft.id,
102
+ alias: draft.alias,
103
+ cstType: draft.cstType,
104
+ definitionFormal: draft.definitionFormal,
105
+ term: draft.term ?? '',
106
+ definitionText: draft.definitionText ?? '',
107
+ convention: draft.convention ?? '',
108
+ analysis: {
109
+ success: false,
110
+ type: null,
111
+ valueClass: null,
112
+ diagnostics: []
113
+ }
114
+ });
84
115
  }
85
- return analyzer;
116
+
117
+ return buildRSFormFromSession({ ...session, items });
86
118
  }
87
119
  }