perttool 0.10.6 → 0.11.1

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 (241) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/README.md +273 -609
  3. package/dist/application/cli-facade.d.ts +4 -10
  4. package/dist/application/cli-facade.d.ts.map +1 -1
  5. package/dist/application/cli-facade.js +1 -1
  6. package/dist/application/cli-facade.js.map +1 -1
  7. package/dist/application/contract10-candidate.d.ts +33 -0
  8. package/dist/application/contract10-candidate.d.ts.map +1 -0
  9. package/dist/application/contract10-candidate.js +38 -0
  10. package/dist/application/contract10-candidate.js.map +1 -0
  11. package/dist/application/contract10-planning-history.d.ts +4 -0
  12. package/dist/application/contract10-planning-history.d.ts.map +1 -0
  13. package/dist/application/contract10-planning-history.js +28 -0
  14. package/dist/application/contract10-planning-history.js.map +1 -0
  15. package/dist/application/contract10-planning.d.ts +61 -0
  16. package/dist/application/contract10-planning.d.ts.map +1 -0
  17. package/dist/application/contract10-planning.js +165 -0
  18. package/dist/application/contract10-planning.js.map +1 -0
  19. package/dist/application/contract10-runtime.d.ts +185 -0
  20. package/dist/application/contract10-runtime.d.ts.map +1 -0
  21. package/dist/application/contract10-runtime.js +236 -0
  22. package/dist/application/contract10-runtime.js.map +1 -0
  23. package/dist/application/contract8-milestone-acceptance.d.ts +6 -22
  24. package/dist/application/contract8-milestone-acceptance.d.ts.map +1 -1
  25. package/dist/application/contract8-milestone-acceptance.js +21 -99
  26. package/dist/application/contract8-milestone-acceptance.js.map +1 -1
  27. package/dist/application/contract8-milestone-read.d.ts +25 -0
  28. package/dist/application/contract8-milestone-read.d.ts.map +1 -0
  29. package/dist/application/contract8-milestone-read.js +111 -0
  30. package/dist/application/contract8-milestone-read.js.map +1 -0
  31. package/dist/application/contract9-assurance-evaluate.d.ts +3 -0
  32. package/dist/application/contract9-assurance-evaluate.d.ts.map +1 -0
  33. package/dist/application/contract9-assurance-evaluate.js +75 -0
  34. package/dist/application/contract9-assurance-evaluate.js.map +1 -0
  35. package/dist/application/contract9-assurance.d.ts +1 -2
  36. package/dist/application/contract9-assurance.d.ts.map +1 -1
  37. package/dist/application/contract9-assurance.js +2 -56
  38. package/dist/application/contract9-assurance.js.map +1 -1
  39. package/dist/application/contract9-candidate.d.ts +8 -0
  40. package/dist/application/contract9-candidate.d.ts.map +1 -1
  41. package/dist/application/contract9-candidate.js +36 -11
  42. package/dist/application/contract9-candidate.js.map +1 -1
  43. package/dist/application/contract9-mixed-mutation.d.ts +3 -0
  44. package/dist/application/contract9-mixed-mutation.d.ts.map +1 -1
  45. package/dist/application/contract9-mixed-mutation.js +5 -4
  46. package/dist/application/contract9-mixed-mutation.js.map +1 -1
  47. package/dist/application/contract9-temporal.js +1 -1
  48. package/dist/application/contract9-temporal.js.map +1 -1
  49. package/dist/application/target-actuals-analysis.d.ts.map +1 -1
  50. package/dist/application/target-actuals-analysis.js +10 -6
  51. package/dist/application/target-actuals-analysis.js.map +1 -1
  52. package/dist/application/target-temporal-analysis.d.ts +1 -0
  53. package/dist/application/target-temporal-analysis.d.ts.map +1 -1
  54. package/dist/application/target-temporal-analysis.js +5 -1
  55. package/dist/application/target-temporal-analysis.js.map +1 -1
  56. package/dist/cli.js +761 -87
  57. package/dist/cli.js.map +1 -1
  58. package/dist/command/contract10-discovery.d.ts +17 -0
  59. package/dist/command/contract10-discovery.d.ts.map +1 -0
  60. package/dist/command/contract10-discovery.js +304 -0
  61. package/dist/command/contract10-discovery.js.map +1 -0
  62. package/dist/command/contract10-usage.d.ts +24 -0
  63. package/dist/command/contract10-usage.d.ts.map +1 -0
  64. package/dist/command/contract10-usage.js +49 -0
  65. package/dist/command/contract10-usage.js.map +1 -0
  66. package/dist/core/index.d.ts +11 -2
  67. package/dist/core/index.d.ts.map +1 -1
  68. package/dist/core/index.js +3 -1
  69. package/dist/core/index.js.map +1 -1
  70. package/dist/help/assurance-guide.js +1 -1
  71. package/dist/help/assurance-guide.js.map +1 -1
  72. package/dist/help/contract10-guide.d.ts +10 -0
  73. package/dist/help/contract10-guide.d.ts.map +1 -0
  74. package/dist/help/contract10-guide.js +244 -0
  75. package/dist/help/contract10-guide.js.map +1 -0
  76. package/dist/index.d.ts +18 -8
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +8 -5
  79. package/dist/index.js.map +1 -1
  80. package/dist/milestone-acceptance/advance.d.ts +9 -0
  81. package/dist/milestone-acceptance/advance.d.ts.map +1 -1
  82. package/dist/milestone-acceptance/advance.js +29 -2
  83. package/dist/milestone-acceptance/advance.js.map +1 -1
  84. package/dist/milestone-acceptance/mutation.d.ts +2 -0
  85. package/dist/milestone-acceptance/mutation.d.ts.map +1 -1
  86. package/dist/milestone-acceptance/mutation.js +48 -12
  87. package/dist/milestone-acceptance/mutation.js.map +1 -1
  88. package/dist/model/source-result.d.ts +12 -0
  89. package/dist/model/source-result.d.ts.map +1 -0
  90. package/dist/model/source-result.js +16 -0
  91. package/dist/model/source-result.js.map +1 -0
  92. package/dist/mutation/advance-deletion.d.ts +1 -0
  93. package/dist/mutation/advance-deletion.d.ts.map +1 -1
  94. package/dist/mutation/advance-deletion.js +4 -1
  95. package/dist/mutation/advance-deletion.js.map +1 -1
  96. package/dist/mutation/validated-source.d.ts +30 -0
  97. package/dist/mutation/validated-source.d.ts.map +1 -0
  98. package/dist/mutation/validated-source.js +58 -0
  99. package/dist/mutation/validated-source.js.map +1 -0
  100. package/dist/node/planning-token-store.d.ts +3 -0
  101. package/dist/node/planning-token-store.d.ts.map +1 -0
  102. package/dist/node/planning-token-store.js +90 -0
  103. package/dist/node/planning-token-store.js.map +1 -0
  104. package/dist/parser/document-parser.d.ts +1 -0
  105. package/dist/parser/document-parser.d.ts.map +1 -1
  106. package/dist/parser/document-parser.js +1 -1
  107. package/dist/parser/document-parser.js.map +1 -1
  108. package/dist/perttool-vscode-private-0.0.0-d1578b9.vsix +0 -0
  109. package/dist/planning-pool/advance.d.ts +10 -0
  110. package/dist/planning-pool/advance.d.ts.map +1 -0
  111. package/dist/planning-pool/advance.js +158 -0
  112. package/dist/planning-pool/advance.js.map +1 -0
  113. package/dist/planning-pool/format.d.ts +12 -0
  114. package/dist/planning-pool/format.d.ts.map +1 -0
  115. package/dist/planning-pool/format.js +199 -0
  116. package/dist/planning-pool/format.js.map +1 -0
  117. package/dist/planning-pool/history-guard.d.ts +19 -0
  118. package/dist/planning-pool/history-guard.d.ts.map +1 -0
  119. package/dist/planning-pool/history-guard.js +123 -0
  120. package/dist/planning-pool/history-guard.js.map +1 -0
  121. package/dist/planning-pool/history-types.d.ts +174 -0
  122. package/dist/planning-pool/history-types.d.ts.map +1 -0
  123. package/dist/planning-pool/history-types.js +2 -0
  124. package/dist/planning-pool/history-types.js.map +1 -0
  125. package/dist/planning-pool/history.d.ts +11 -0
  126. package/dist/planning-pool/history.d.ts.map +1 -0
  127. package/dist/planning-pool/history.js +977 -0
  128. package/dist/planning-pool/history.js.map +1 -0
  129. package/dist/planning-pool/human.d.ts +9 -0
  130. package/dist/planning-pool/human.d.ts.map +1 -0
  131. package/dist/planning-pool/human.js +305 -0
  132. package/dist/planning-pool/human.js.map +1 -0
  133. package/dist/planning-pool/intent-types.d.ts +76 -0
  134. package/dist/planning-pool/intent-types.d.ts.map +1 -0
  135. package/dist/planning-pool/intent-types.js +2 -0
  136. package/dist/planning-pool/intent-types.js.map +1 -0
  137. package/dist/planning-pool/intent.d.ts +7 -0
  138. package/dist/planning-pool/intent.d.ts.map +1 -0
  139. package/dist/planning-pool/intent.js +590 -0
  140. package/dist/planning-pool/intent.js.map +1 -0
  141. package/dist/planning-pool/observation-types.d.ts +143 -0
  142. package/dist/planning-pool/observation-types.d.ts.map +1 -0
  143. package/dist/planning-pool/observation-types.js +2 -0
  144. package/dist/planning-pool/observation-types.js.map +1 -0
  145. package/dist/planning-pool/observation.d.ts +8 -0
  146. package/dist/planning-pool/observation.d.ts.map +1 -0
  147. package/dist/planning-pool/observation.js +582 -0
  148. package/dist/planning-pool/observation.js.map +1 -0
  149. package/dist/planning-pool/projection.d.ts +28 -0
  150. package/dist/planning-pool/projection.d.ts.map +1 -0
  151. package/dist/planning-pool/projection.js +148 -0
  152. package/dist/planning-pool/projection.js.map +1 -0
  153. package/dist/planning-pool/public-core.d.ts +32 -0
  154. package/dist/planning-pool/public-core.d.ts.map +1 -0
  155. package/dist/planning-pool/public-core.js +122 -0
  156. package/dist/planning-pool/public-core.js.map +1 -0
  157. package/dist/planning-pool/reshape-normalize.d.ts +15 -0
  158. package/dist/planning-pool/reshape-normalize.d.ts.map +1 -0
  159. package/dist/planning-pool/reshape-normalize.js +688 -0
  160. package/dist/planning-pool/reshape-normalize.js.map +1 -0
  161. package/dist/planning-pool/reshape-token.d.ts +20 -0
  162. package/dist/planning-pool/reshape-token.d.ts.map +1 -0
  163. package/dist/planning-pool/reshape-token.js +193 -0
  164. package/dist/planning-pool/reshape-token.js.map +1 -0
  165. package/dist/planning-pool/reshape-types.d.ts +183 -0
  166. package/dist/planning-pool/reshape-types.d.ts.map +1 -0
  167. package/dist/planning-pool/reshape-types.js +2 -0
  168. package/dist/planning-pool/reshape-types.js.map +1 -0
  169. package/dist/planning-pool/reshape.d.ts +13 -0
  170. package/dist/planning-pool/reshape.d.ts.map +1 -0
  171. package/dist/planning-pool/reshape.js +1434 -0
  172. package/dist/planning-pool/reshape.js.map +1 -0
  173. package/dist/planning-pool/source-lexical.d.ts +30 -0
  174. package/dist/planning-pool/source-lexical.d.ts.map +1 -0
  175. package/dist/planning-pool/source-lexical.js +158 -0
  176. package/dist/planning-pool/source-lexical.js.map +1 -0
  177. package/dist/planning-pool/source-types.d.ts +169 -0
  178. package/dist/planning-pool/source-types.d.ts.map +1 -0
  179. package/dist/planning-pool/source-types.js +2 -0
  180. package/dist/planning-pool/source-types.js.map +1 -0
  181. package/dist/planning-pool/source-values.d.ts +16 -0
  182. package/dist/planning-pool/source-values.d.ts.map +1 -0
  183. package/dist/planning-pool/source-values.js +120 -0
  184. package/dist/planning-pool/source-values.js.map +1 -0
  185. package/dist/planning-pool/source.d.ts +18 -0
  186. package/dist/planning-pool/source.d.ts.map +1 -0
  187. package/dist/planning-pool/source.js +811 -0
  188. package/dist/planning-pool/source.js.map +1 -0
  189. package/dist/planning-pool/window-types.d.ts +133 -0
  190. package/dist/planning-pool/window-types.d.ts.map +1 -0
  191. package/dist/planning-pool/window-types.js +2 -0
  192. package/dist/planning-pool/window-types.js.map +1 -0
  193. package/dist/planning-pool/window.d.ts +6 -0
  194. package/dist/planning-pool/window.d.ts.map +1 -0
  195. package/dist/planning-pool/window.js +625 -0
  196. package/dist/planning-pool/window.js.map +1 -0
  197. package/dist/schema/registry.d.ts +1 -1
  198. package/dist/schema/registry.d.ts.map +1 -1
  199. package/dist/schema/registry.js +17 -3
  200. package/dist/schema/registry.js.map +1 -1
  201. package/dist/temporal-schedule/format.d.ts.map +1 -1
  202. package/dist/temporal-schedule/format.js +4 -54
  203. package/dist/temporal-schedule/format.js.map +1 -1
  204. package/dist/temporal-schedule/source-lexical.d.ts +9 -0
  205. package/dist/temporal-schedule/source-lexical.d.ts.map +1 -1
  206. package/dist/temporal-schedule/source-lexical.js +21 -10
  207. package/dist/temporal-schedule/source-lexical.js.map +1 -1
  208. package/dist/temporal-schedule/source.d.ts.map +1 -1
  209. package/dist/temporal-schedule/source.js +3 -13
  210. package/dist/temporal-schedule/source.js.map +1 -1
  211. package/dist/version.d.ts +1 -1
  212. package/dist/version.js +1 -1
  213. package/package.json +1 -1
  214. package/schemas/{Perttool.AdvanceResult.v3.schema.json → Perttool.AdvanceResult.v4.schema.json} +42 -4
  215. package/schemas/Perttool.AgentGuidanceResult.v1.schema.json +1 -1
  216. package/schemas/Perttool.AnalysisResult.v7.schema.json +1 -1
  217. package/schemas/Perttool.CheckResult.v6.schema.json +1 -1
  218. package/schemas/Perttool.CliError.v1.schema.json +1 -1
  219. package/schemas/Perttool.CommandHelpResult.v1.schema.json +2 -2
  220. package/schemas/Perttool.ExportResult.v1.schema.json +1 -1
  221. package/schemas/Perttool.FormatResult.v1.schema.json +1 -1
  222. package/schemas/Perttool.GuideResult.v1.schema.json +1 -1
  223. package/schemas/Perttool.HistoricalGraphResult.v1.schema.json +1 -1
  224. package/schemas/Perttool.ImportResult.v1.schema.json +1 -1
  225. package/schemas/Perttool.InitResult.v1.schema.json +1 -1
  226. package/schemas/Perttool.MilestoneAcceptanceMigrationResult.v1.schema.json +1 -1
  227. package/schemas/Perttool.MilestoneAcceptanceResult.v1.schema.json +1 -1
  228. package/schemas/Perttool.MutationResult.v6.schema.json +1 -1
  229. package/schemas/Perttool.NextResult.v8.schema.json +7 -4
  230. package/schemas/Perttool.PlanAssuranceResult.v2.schema.json +1 -1
  231. package/schemas/Perttool.PlanningMutationResult.v1.schema.json +567 -0
  232. package/schemas/Perttool.PlanningObservationRequest.v1.schema.json +6 -0
  233. package/schemas/Perttool.PlanningPoolResult.v1.schema.json +469 -0
  234. package/schemas/Perttool.PlanningReshapePreflightResult.v1.schema.json +906 -0
  235. package/schemas/Perttool.PlanningReshapeRequest.v1.schema.json +19 -0
  236. package/schemas/Perttool.ProjectHistoryResult.v1.schema.json +1 -1
  237. package/schemas/Perttool.ProjectResult.v5.schema.json +1 -1
  238. package/schemas/Perttool.SchemaResult.v1.schema.json +1 -1
  239. package/schemas/{Perttool.UnitMigrationResult.v4.schema.json → Perttool.UnitMigrationResult.v5.schema.json} +42 -17
  240. package/schemas/Perttool.VelocityObservationResult.v1.schema.json +1 -1
  241. package/schemas/Perttool.WindowMutationRequest.v1.schema.json +6 -0
@@ -0,0 +1,625 @@
1
+ import { parseDeclaredCalendarValue } from "../model/calendar.js";
2
+ import { scanTemporalDeclarationBlocks } from "../temporal-schedule/source-lexical.js";
3
+ import { planPlanningPoolSourceMutation } from "./format.js";
4
+ import { planningReshapeSha256 } from "./reshape-normalize.js";
5
+ import { scanPlanningDeclarationBlocks, } from "./source-lexical.js";
6
+ import { parsePlanningPoolSource, PLANNING_POOL_SOURCE_CAPABILITY, PLANNING_POOL_SOURCE_LIMITS, } from "./source.js";
7
+ import { canonicalPlanningCalendar, comparePlanningCalendarValues, } from "./source-values.js";
8
+ export const PLANNING_WINDOW_CORE_CAPABILITY = Object.freeze({ id: "perttool.planning-window-core", version: 1 });
9
+ const WINDOW_REQUEST_SCHEMA = "Perttool.WindowMutationRequest.v1";
10
+ const digestPattern = /^sha256:[0-9a-f]{64}$/u;
11
+ const qualifiedPattern = /^([A-Za-z][A-Za-z0-9_-]*)::([A-Za-z][A-Za-z0-9_-]*)$/u;
12
+ const requestKeys = new Set([
13
+ "request_schema_version", "source_digest", "operation", "window_id",
14
+ "final", "objective_disposition", "carry_over_work_ids", "carry_over_target",
15
+ ]);
16
+ function requireCapability(capability) {
17
+ if (capability !== PLANNING_WINDOW_CORE_CAPABILITY) {
18
+ throw new TypeError("the private planning Window Core capability is required");
19
+ }
20
+ }
21
+ function diagnostic(code, message, entityId) {
22
+ return Object.freeze({
23
+ code,
24
+ severity: "error",
25
+ message,
26
+ ...(entityId === undefined ? {} : { entityId }),
27
+ data: Object.freeze({}),
28
+ });
29
+ }
30
+ function record(value) {
31
+ return typeof value === "object" && value !== null && !Array.isArray(value)
32
+ ? value
33
+ : null;
34
+ }
35
+ function closed(value, keys, label, diagnostics) {
36
+ const parsed = record(value);
37
+ if (parsed === null) {
38
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} must be an object`));
39
+ return null;
40
+ }
41
+ const actual = Object.keys(parsed);
42
+ const missing = [...keys].filter((key) => !(key in parsed));
43
+ const unknown = actual.filter((key) => !keys.has(key));
44
+ if (missing.length > 0 || unknown.length > 0) {
45
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} has ${missing.length > 0 ? `missing ${missing.join(", ")}` : ""}${missing.length > 0 && unknown.length > 0 ? " and " : ""}${unknown.length > 0 ? `unknown ${unknown.join(", ")}` : ""}`));
46
+ }
47
+ return parsed;
48
+ }
49
+ function nonEmptyString(value, label, diagnostics) {
50
+ if (typeof value !== "string" || value.length === 0) {
51
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} must be a non-empty string`));
52
+ return null;
53
+ }
54
+ return value;
55
+ }
56
+ function qualifiedId(value, label, diagnostics) {
57
+ const parsed = nonEmptyString(value, label, diagnostics);
58
+ if (parsed !== null && !qualifiedPattern.test(parsed)) {
59
+ diagnostics.push(diagnostic("PTPOOL-102", `${label} must be a qualified identity`));
60
+ return null;
61
+ }
62
+ return parsed;
63
+ }
64
+ function stringSet(value, label, diagnostics) {
65
+ if (!Array.isArray(value)) {
66
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} must be an array`));
67
+ return null;
68
+ }
69
+ const result = value.map((item) => qualifiedId(item, label, diagnostics))
70
+ .filter((item) => item !== null);
71
+ if (new Set(result).size !== result.length) {
72
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} contains a duplicate`));
73
+ }
74
+ return Object.freeze([...result].sort());
75
+ }
76
+ function calendar(value, label, diagnostics) {
77
+ if (value === null)
78
+ return null;
79
+ if (typeof value !== "string") {
80
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} must be null or an ISO date or fixed-offset date-time`));
81
+ return undefined;
82
+ }
83
+ const canonical = canonicalPlanningCalendar(value);
84
+ if (canonical === null) {
85
+ diagnostics.push(diagnostic("PTPOOL-107", `${label} is not an ISO date or fixed-offset date-time`));
86
+ return undefined;
87
+ }
88
+ return canonical;
89
+ }
90
+ function validateBounds(start, end, diagnostics) {
91
+ if (start === null || end === null)
92
+ return;
93
+ const left = parseDeclaredCalendarValue(start);
94
+ const right = parseDeclaredCalendarValue(end);
95
+ const comparison = comparePlanningCalendarValues(left, right);
96
+ if (comparison === null || comparison >= 0) {
97
+ diagnostics.push(diagnostic("PTPOOL-107", "Window bounds must have one kind and satisfy start < end"));
98
+ }
99
+ }
100
+ function finalFields(value, diagnostics) {
101
+ const parsed = closed(value, new Set(["title", "objective", "start", "end", "work_ids"]), "Window final fields", diagnostics);
102
+ if (parsed === null)
103
+ return null;
104
+ const title = nonEmptyString(parsed["title"], "Window title", diagnostics);
105
+ const objective = nonEmptyString(parsed["objective"], "Window objective", diagnostics);
106
+ const start = calendar(parsed["start"], "Window start", diagnostics);
107
+ const end = calendar(parsed["end"], "Window end", diagnostics);
108
+ const works = stringSet(parsed["work_ids"], "Window Work", diagnostics);
109
+ if (works !== null && works.length === 0)
110
+ diagnostics.push(diagnostic("PTPOOL-107", "A persisted Window requires at least one Work"));
111
+ if (start !== undefined && end !== undefined)
112
+ validateBounds(start, end, diagnostics);
113
+ return title === null || objective === null || start === undefined || end === undefined || works === null
114
+ ? null
115
+ : Object.freeze({ title, objective, start, end, work_ids: works });
116
+ }
117
+ function existingCarryTarget(value, diagnostics) {
118
+ const parsed = closed(value, new Set(["kind", "window_id"]), "existing carry-over target", diagnostics);
119
+ const id = qualifiedId(parsed?.["window_id"], "carry-over Window", diagnostics);
120
+ return parsed === null || id === null ? null : Object.freeze({ kind: "existing", window_id: id });
121
+ }
122
+ function newCarryTarget(value, diagnostics) {
123
+ const parsed = closed(value, new Set(["kind", "window_id", "title", "objective", "start", "end"]), "new carry-over target", diagnostics);
124
+ if (parsed === null)
125
+ return null;
126
+ const id = qualifiedId(parsed["window_id"], "new carry-over Window", diagnostics);
127
+ const title = nonEmptyString(parsed["title"], "new Window title", diagnostics);
128
+ const objective = nonEmptyString(parsed["objective"], "new Window objective", diagnostics);
129
+ const start = calendar(parsed["start"], "new Window start", diagnostics);
130
+ const end = calendar(parsed["end"], "new Window end", diagnostics);
131
+ if (start !== undefined && end !== undefined)
132
+ validateBounds(start, end, diagnostics);
133
+ return id === null || title === null || objective === null || start === undefined || end === undefined
134
+ ? null
135
+ : Object.freeze({ kind: "new", window_id: id, title, objective, start, end });
136
+ }
137
+ function carryTarget(value, diagnostics) {
138
+ if (value === null)
139
+ return null;
140
+ const kind = record(value)?.["kind"];
141
+ if (kind === "existing")
142
+ return existingCarryTarget(value, diagnostics);
143
+ if (kind === "new")
144
+ return newCarryTarget(value, diagnostics);
145
+ diagnostics.push(diagnostic("PTPOOL-107", "carry_over_target must be null, existing, or new"));
146
+ return null;
147
+ }
148
+ function requestSizeIsValid(input, diagnostics) {
149
+ try {
150
+ if (new TextEncoder().encode(JSON.stringify(input)).byteLength <= PLANNING_POOL_SOURCE_LIMITS.sourceOrCandidateUtf8Bytes)
151
+ return true;
152
+ diagnostics.push(diagnostic("PTPOOL-115", "Window mutation request exceeds 8388608 UTF-8 bytes"));
153
+ }
154
+ catch {
155
+ diagnostics.push(diagnostic("PTPOOL-107", "Window mutation request is not JSON-compatible"));
156
+ }
157
+ return false;
158
+ }
159
+ function operationValue(value, diagnostics) {
160
+ if (value === "add" || value === "set" || value === "close")
161
+ return value;
162
+ diagnostics.push(diagnostic("PTPOOL-107", "Window operation must be add, set, or close"));
163
+ return null;
164
+ }
165
+ function objectiveDisposition(value, diagnostics) {
166
+ if (value === null || value === "discard")
167
+ return value;
168
+ diagnostics.push(diagnostic("PTPOOL-107", "objective_disposition must be null or discard"));
169
+ return undefined;
170
+ }
171
+ function validateOperationFields(operation, final, disposition, carry, target, diagnostics) {
172
+ if (operation === "close") {
173
+ if (final !== null || disposition !== "discard")
174
+ diagnostics.push(diagnostic("PTPOOL-107", "Window close requires null final fields and objective_disposition discard"));
175
+ if ((carry.length === 0) !== (target === null))
176
+ diagnostics.push(diagnostic("PTPOOL-107", "Window close requires a target exactly when carry-over is non-empty"));
177
+ return;
178
+ }
179
+ if (final === null || disposition !== null || carry.length > 0 || target !== null) {
180
+ diagnostics.push(diagnostic("PTPOOL-107", "Window add and set require complete final fields and no close fields"));
181
+ }
182
+ }
183
+ function normalizeRequest(input, diagnostics) {
184
+ if (!requestSizeIsValid(input, diagnostics))
185
+ return null;
186
+ const parsed = closed(input, requestKeys, "Window mutation request", diagnostics);
187
+ if (parsed === null)
188
+ return null;
189
+ if (parsed["request_schema_version"] !== WINDOW_REQUEST_SCHEMA) {
190
+ diagnostics.push(diagnostic("PTPOOL-107", "Window mutation request schema identity is unsupported"));
191
+ }
192
+ const sourceDigest = nonEmptyString(parsed["source_digest"], "source_digest", diagnostics);
193
+ if (sourceDigest !== null && !digestPattern.test(sourceDigest))
194
+ diagnostics.push(diagnostic("PTPOOL-111", "source_digest must be a lowercase SHA-256 identity"));
195
+ const operation = operationValue(parsed["operation"], diagnostics);
196
+ const windowId = qualifiedId(parsed["window_id"], "Window id", diagnostics);
197
+ const final = parsed["final"] === null ? null : finalFields(parsed["final"], diagnostics);
198
+ const disposition = objectiveDisposition(parsed["objective_disposition"], diagnostics);
199
+ const carry = stringSet(parsed["carry_over_work_ids"], "carry-over Work", diagnostics);
200
+ const target = carryTarget(parsed["carry_over_target"], diagnostics);
201
+ if (sourceDigest === null || operation === null || windowId === null || disposition === undefined || carry === null)
202
+ return null;
203
+ validateOperationFields(operation, final, disposition, carry, target, diagnostics);
204
+ return Object.freeze({
205
+ request_schema_version: WINDOW_REQUEST_SCHEMA,
206
+ source_digest: sourceDigest,
207
+ operation,
208
+ window_id: windowId,
209
+ final,
210
+ objective_disposition: disposition,
211
+ carry_over_work_ids: carry,
212
+ carry_over_target: target,
213
+ });
214
+ }
215
+ function localId(qualified, documentId, label, diagnostics) {
216
+ const match = qualifiedPattern.exec(qualified);
217
+ if (match === null || match[1] !== documentId) {
218
+ diagnostics.push(diagnostic("PTPOOL-102", `${label} must use namespace ${documentId}`, qualified));
219
+ return null;
220
+ }
221
+ return match[2];
222
+ }
223
+ function knownWorkIds(model) {
224
+ return new Set(model.works.map(({ qualifiedId }) => qualifiedId));
225
+ }
226
+ function validateWorks(ids, model, diagnostics) {
227
+ const known = knownWorkIds(model);
228
+ for (const id of ids) {
229
+ localId(id, model.documentId, "Window Work", diagnostics);
230
+ if (!known.has(id))
231
+ diagnostics.push(diagnostic("PTPOOL-107", `Window references unknown Work ${id}`, id));
232
+ }
233
+ }
234
+ function lineEnding(text) {
235
+ return text.includes("\r\n") ? "\r\n" : "\n";
236
+ }
237
+ function renderWindow(id, fields, ending) {
238
+ const lines = [
239
+ `window ${id}:`,
240
+ ` title ${JSON.stringify(fields.title)}`,
241
+ ` objective ${JSON.stringify(fields.objective)}`,
242
+ ];
243
+ if (fields.start !== null)
244
+ lines.push(` start ${fields.start}`);
245
+ if (fields.end !== null)
246
+ lines.push(` end ${fields.end}`);
247
+ lines.push(" works:", ...fields.work_ids.map((work) => ` ${qualifiedPattern.exec(work)[2]}`));
248
+ return `${lines.join(ending)}${ending}`;
249
+ }
250
+ function snapshot(window) {
251
+ return Object.freeze({
252
+ kind: "persisted",
253
+ qualifiedId: window.qualifiedId,
254
+ title: window.title,
255
+ objective: window.objective,
256
+ start: window.start?.sourceText ?? null,
257
+ end: window.end?.sourceText ?? null,
258
+ workIds: Object.freeze(window.works.map(({ qualifiedId }) => qualifiedId)),
259
+ });
260
+ }
261
+ function finalSnapshot(id, fields) {
262
+ return Object.freeze({
263
+ kind: "persisted",
264
+ qualifiedId: id,
265
+ title: fields.title,
266
+ objective: fields.objective,
267
+ start: fields.start,
268
+ end: fields.end,
269
+ workIds: fields.work_ids,
270
+ });
271
+ }
272
+ function blockFor(text, id) {
273
+ return scanPlanningDeclarationBlocks(text).find((block) => block.kind === "window" && block.id === id);
274
+ }
275
+ function insertionOffset(text) {
276
+ const blocks = scanPlanningDeclarationBlocks(text);
277
+ const order = blocks.find(({ kind }) => kind === "work_order");
278
+ if (order !== undefined)
279
+ return order.span.start.offset;
280
+ const strict = scanTemporalDeclarationBlocks(text).find(({ kind }) => kind === "milestone" || kind === "task");
281
+ return strict?.span.start.offset ?? text.length;
282
+ }
283
+ function targetNewFields(target, carry) {
284
+ return Object.freeze({
285
+ title: target.title,
286
+ objective: target.objective,
287
+ start: target.start,
288
+ end: target.end,
289
+ work_ids: carry,
290
+ });
291
+ }
292
+ function destructive(window) {
293
+ return Object.freeze({
294
+ ownerClass: "canonical",
295
+ entityKind: "window",
296
+ qualifiedId: window.qualifiedId,
297
+ startOffset: window.span.start.offset,
298
+ endOffset: window.span.end.offset,
299
+ });
300
+ }
301
+ function planAddOrSet(text, request, model, diagnostics) {
302
+ const local = localId(request.window_id, model.documentId, "Window id", diagnostics);
303
+ const existing = model.windows.find(({ qualifiedId }) => qualifiedId === request.window_id);
304
+ const fields = request.final;
305
+ if (local === null || fields === null)
306
+ return null;
307
+ validateWorks(fields.work_ids, model, diagnostics);
308
+ if (request.operation === "add" && existing !== undefined)
309
+ diagnostics.push(diagnostic("PTPOOL-102", `Window ${request.window_id} already exists`, request.window_id));
310
+ if (request.operation === "set" && existing === undefined)
311
+ diagnostics.push(diagnostic("PTPOOL-107", `Window ${request.window_id} does not exist`, request.window_id));
312
+ if (diagnostics.length > 0)
313
+ return null;
314
+ const ending = lineEnding(text);
315
+ const replacement = renderWindow(local, fields, ending);
316
+ const edit = existing === undefined
317
+ ? Object.freeze({ startOffset: insertionOffset(text), endOffset: insertionOffset(text), replacement: `${replacement}${ending}` })
318
+ : Object.freeze({ startOffset: existing.span.start.offset, endOffset: existing.span.end.offset, replacement });
319
+ return Object.freeze({
320
+ edits: Object.freeze([edit]),
321
+ before: existing === undefined ? null : snapshot(existing),
322
+ after: finalSnapshot(request.window_id, fields),
323
+ closeReport: null,
324
+ destructiveRecords: existing === undefined ? Object.freeze([]) : Object.freeze([destructive(existing)]),
325
+ });
326
+ }
327
+ function validateCarrySelection(request, model, source, diagnostics) {
328
+ validateWorks(request.carry_over_work_ids, model, diagnostics);
329
+ const sourceWorks = new Set(source.works.map(({ qualifiedId }) => qualifiedId));
330
+ for (const work of request.carry_over_work_ids) {
331
+ if (!sourceWorks.has(work))
332
+ diagnostics.push(diagnostic("PTPOOL-107", `Carry-over Work ${work} is not selected by ${source.qualifiedId}`, work));
333
+ }
334
+ }
335
+ function resolveCarryTarget(target, model, source, diagnostics) {
336
+ if (target.window_id === source.qualifiedId)
337
+ diagnostics.push(diagnostic("PTPOOL-107", "Window cannot carry over to itself", source.qualifiedId));
338
+ const local = localId(target.window_id, model.documentId, "carry-over Window", diagnostics);
339
+ const existing = model.windows.find(({ qualifiedId }) => qualifiedId === target.window_id);
340
+ if (target.kind === "existing" && existing === undefined)
341
+ diagnostics.push(diagnostic("PTPOOL-107", `Carry-over Window ${target.window_id} does not exist`, target.window_id));
342
+ if (target.kind === "new" && existing !== undefined)
343
+ diagnostics.push(diagnostic("PTPOOL-102", `New carry-over Window ${target.window_id} already exists`, target.window_id));
344
+ return local === null || diagnostics.length > 0 ? null : Object.freeze({ localId: local, existing });
345
+ }
346
+ function fieldsForCarryTarget(target, existing, finalWorks) {
347
+ return target.kind === "new"
348
+ ? targetNewFields(target, finalWorks)
349
+ : Object.freeze({
350
+ title: existing.title,
351
+ objective: existing.objective,
352
+ start: existing.start?.sourceText ?? null,
353
+ end: existing.end?.sourceText ?? null,
354
+ work_ids: finalWorks,
355
+ });
356
+ }
357
+ function carryRecords(request, target, existingWorks) {
358
+ return Object.freeze(request.carry_over_work_ids.map((workId) => Object.freeze({
359
+ workId,
360
+ targetWindowId: target.window_id,
361
+ status: existingWorks.has(workId) ? "already_selected" : "selected",
362
+ })));
363
+ }
364
+ function emptyCloseTarget(source) {
365
+ return Object.freeze({
366
+ edits: Object.freeze([{ startOffset: source.span.start.offset, endOffset: source.span.end.offset, replacement: "" }]),
367
+ report: Object.freeze({ removedWindow: snapshot(source), objectiveDisposition: "discard", carryOver: Object.freeze([]), targetCreated: false }),
368
+ destructive: Object.freeze([destructive(source)]),
369
+ });
370
+ }
371
+ function closeTarget(text, request, model, source, diagnostics) {
372
+ const target = request.carry_over_target;
373
+ if (target === null)
374
+ return emptyCloseTarget(source);
375
+ validateCarrySelection(request, model, source, diagnostics);
376
+ const resolved = resolveCarryTarget(target, model, source, diagnostics);
377
+ if (resolved === null)
378
+ return null;
379
+ const { localId: targetLocal, existing } = resolved;
380
+ const existingWorks = new Set(existing?.works.map(({ qualifiedId }) => qualifiedId) ?? []);
381
+ const finalWorks = Object.freeze([...new Set([...existingWorks, ...request.carry_over_work_ids])].sort());
382
+ const targetReplacement = renderWindow(targetLocal, fieldsForCarryTarget(target, existing, finalWorks), lineEnding(text));
383
+ const edits = [
384
+ { startOffset: source.span.start.offset, endOffset: source.span.end.offset, replacement: target.kind === "new" ? targetReplacement : "" },
385
+ ];
386
+ if (existing !== undefined)
387
+ edits.push({ startOffset: existing.span.start.offset, endOffset: existing.span.end.offset, replacement: targetReplacement });
388
+ return Object.freeze({
389
+ edits: Object.freeze(edits),
390
+ report: Object.freeze({ removedWindow: snapshot(source), objectiveDisposition: "discard", carryOver: carryRecords(request, target, existingWorks), targetCreated: target.kind === "new" }),
391
+ destructive: Object.freeze([destructive(source), ...(existing === undefined ? [] : [destructive(existing)])]),
392
+ });
393
+ }
394
+ function planClose(text, request, model, diagnostics) {
395
+ const local = localId(request.window_id, model.documentId, "Window id", diagnostics);
396
+ const source = model.windows.find(({ qualifiedId }) => qualifiedId === request.window_id);
397
+ if (local !== null && source === undefined)
398
+ diagnostics.push(diagnostic("PTPOOL-107", `Window ${request.window_id} does not exist`, request.window_id));
399
+ if (source === undefined || diagnostics.length > 0)
400
+ return null;
401
+ const target = closeTarget(text, request, model, source, diagnostics);
402
+ return target === null ? null : Object.freeze({
403
+ edits: target.edits,
404
+ before: snapshot(source),
405
+ after: null,
406
+ closeReport: target.report,
407
+ destructiveRecords: target.destructive,
408
+ });
409
+ }
410
+ const ordinaryAuthority = Object.freeze({
411
+ affectedScopes: Object.freeze([]),
412
+ ordinaryMaintenance: true,
413
+ userResponseRequired: false,
414
+ });
415
+ function failedMutation(sourceDigest, documentId, request, diagnostics) {
416
+ return Object.freeze({
417
+ schemaVersion: "Perttool.PlanningMutationResult.v1",
418
+ windowCapability: "perttool.planning-window-core@1",
419
+ ok: false,
420
+ documentId,
421
+ sourceDigest,
422
+ normalizedRequest: request,
423
+ candidateDigest: null,
424
+ candidateText: null,
425
+ changed: false,
426
+ edits: Object.freeze([]),
427
+ before: null,
428
+ after: null,
429
+ closeReport: null,
430
+ destructiveRecords: Object.freeze([]),
431
+ authorityImpact: null,
432
+ diagnostics: Object.freeze(diagnostics),
433
+ });
434
+ }
435
+ export function auditPlanningWindowMutation(text, input, capability) {
436
+ requireCapability(capability);
437
+ const sourceDigest = planningReshapeSha256(text);
438
+ const diagnostics = [];
439
+ const parsed = parsePlanningPoolSource(text, PLANNING_POOL_SOURCE_CAPABILITY);
440
+ const request = normalizeRequest(input, diagnostics);
441
+ if (!parsed.ok || parsed.model === null) {
442
+ diagnostics.push(...parsed.diagnostics, diagnostic("PTPOOL-116", "Window mutation requires a valid Grammar 9 source"));
443
+ }
444
+ if (request !== null && request.source_digest !== sourceDigest)
445
+ diagnostics.push(diagnostic("PTPOOL-111", "Window mutation source digest does not match current source"));
446
+ if (request === null || parsed.model === null || diagnostics.length > 0) {
447
+ return failedMutation(sourceDigest, parsed.documentId, request, diagnostics);
448
+ }
449
+ const plan = request.operation === "close"
450
+ ? planClose(text, request, parsed.model, diagnostics)
451
+ : planAddOrSet(text, request, parsed.model, diagnostics);
452
+ if (plan === null || diagnostics.length > 0)
453
+ return failedMutation(sourceDigest, parsed.documentId, request, diagnostics);
454
+ const candidate = planPlanningPoolSourceMutation(text, plan.edits, PLANNING_POOL_SOURCE_CAPABILITY);
455
+ if (!candidate.ok || candidate.updatedText === null) {
456
+ return failedMutation(sourceDigest, parsed.documentId, request, [...diagnostics, ...candidate.diagnostics]);
457
+ }
458
+ return Object.freeze({
459
+ schemaVersion: "Perttool.PlanningMutationResult.v1",
460
+ windowCapability: "perttool.planning-window-core@1",
461
+ ok: true,
462
+ documentId: parsed.documentId,
463
+ sourceDigest,
464
+ normalizedRequest: request,
465
+ candidateDigest: planningReshapeSha256(candidate.updatedText),
466
+ candidateText: candidate.updatedText,
467
+ changed: candidate.changed,
468
+ edits: candidate.edits,
469
+ before: plan.before,
470
+ after: plan.after,
471
+ closeReport: plan.closeReport,
472
+ destructiveRecords: plan.destructiveRecords,
473
+ authorityImpact: ordinaryAuthority,
474
+ diagnostics: Object.freeze(candidate.diagnostics),
475
+ });
476
+ }
477
+ function selectionInput(input, diagnostics) {
478
+ const base = record(input);
479
+ if (base?.["kind"] === "persisted") {
480
+ const parsed = closed(input, new Set(["kind", "window_id"]), "persisted Window selection", diagnostics);
481
+ const id = qualifiedId(parsed?.["window_id"], "Window id", diagnostics);
482
+ return parsed === null || id === null ? null : Object.freeze({ kind: "persisted", window_id: id });
483
+ }
484
+ if (base?.["kind"] !== "ad_hoc") {
485
+ diagnostics.push(diagnostic("PTPOOL-107", "Window selection kind must be persisted or ad_hoc"));
486
+ return null;
487
+ }
488
+ const parsed = closed(input, new Set(["kind", "title", "objective", "start", "end", "work_ids"]), "ad hoc Window selection", diagnostics);
489
+ if (parsed === null)
490
+ return null;
491
+ const title = parsed["title"] === null ? null : nonEmptyString(parsed["title"], "ad hoc title", diagnostics);
492
+ const objective = parsed["objective"] === null ? null : nonEmptyString(parsed["objective"], "ad hoc objective", diagnostics);
493
+ const start = calendar(parsed["start"], "ad hoc start", diagnostics);
494
+ const end = calendar(parsed["end"], "ad hoc end", diagnostics);
495
+ const works = stringSet(parsed["work_ids"], "ad hoc Work", diagnostics);
496
+ if (start !== undefined && end !== undefined)
497
+ validateBounds(start, end, diagnostics);
498
+ return title === undefined || objective === undefined || start === undefined || end === undefined || works === null
499
+ ? null
500
+ : Object.freeze({ kind: "ad_hoc", title, objective, start, end, work_ids: works });
501
+ }
502
+ function adHocSnapshot(input) {
503
+ return Object.freeze({
504
+ kind: "ad_hoc",
505
+ qualifiedId: null,
506
+ title: input.title,
507
+ objective: input.objective,
508
+ start: input.start,
509
+ end: input.end,
510
+ workIds: input.work_ids,
511
+ });
512
+ }
513
+ function dependencies(selection, model) {
514
+ const selected = new Set(selection.workIds);
515
+ return Object.freeze(model.works.flatMap((work) => selected.has(work.qualifiedId)
516
+ ? work.dependsOn.map((prerequisite) => Object.freeze({
517
+ dependentWorkId: work.qualifiedId,
518
+ prerequisiteWorkId: prerequisite.qualifiedId,
519
+ covered: selected.has(prerequisite.qualifiedId),
520
+ }))
521
+ : []));
522
+ }
523
+ function membershipOverlaps(selection, model) {
524
+ const selected = new Set(selection.workIds);
525
+ return Object.freeze(model.windows.flatMap((window) => {
526
+ if (window.qualifiedId === selection.qualifiedId)
527
+ return [];
528
+ const shared = window.works.map(({ qualifiedId }) => qualifiedId).filter((id) => selected.has(id));
529
+ return shared.length === 0 ? [] : [Object.freeze({ windowId: window.qualifiedId, sharedWorkIds: Object.freeze(shared) })];
530
+ }));
531
+ }
532
+ function parsedBound(value) {
533
+ return value === null ? null : parseDeclaredCalendarValue(value) ?? null;
534
+ }
535
+ function intervalKind(snapshotValue) {
536
+ return parsedBound(snapshotValue.start)?.kind ?? parsedBound(snapshotValue.end)?.kind ?? null;
537
+ }
538
+ function selectBound(left, right, chooseLater) {
539
+ if (left === null)
540
+ return right;
541
+ if (right === null)
542
+ return left;
543
+ const comparison = comparePlanningCalendarValues(left, right);
544
+ return chooseLater === comparison >= 0 ? left : right;
545
+ }
546
+ function temporalOverlap(selection, other) {
547
+ const currentKind = intervalKind(selection);
548
+ const otherSnapshot = snapshot(other);
549
+ const otherKind = intervalKind(otherSnapshot);
550
+ if (currentKind !== null && otherKind !== null && currentKind !== otherKind)
551
+ return Object.freeze({
552
+ windowId: other.qualifiedId,
553
+ state: "unavailable",
554
+ intersectionStart: null,
555
+ intersectionEnd: null,
556
+ cause: "incomparable_temporal_kinds",
557
+ });
558
+ const start = selectBound(parsedBound(selection.start), parsedBound(otherSnapshot.start), true);
559
+ const end = selectBound(parsedBound(selection.end), parsedBound(otherSnapshot.end), false);
560
+ const disjoint = start !== null && end !== null && comparePlanningCalendarValues(start, end) >= 0;
561
+ return Object.freeze({
562
+ windowId: other.qualifiedId,
563
+ state: disjoint ? "disjoint" : "overlap",
564
+ intersectionStart: disjoint ? null : start?.sourceText ?? null,
565
+ intersectionEnd: disjoint ? null : end?.sourceText ?? null,
566
+ cause: null,
567
+ });
568
+ }
569
+ function temporalOverlaps(selection, model) {
570
+ return Object.freeze(model.windows
571
+ .filter(({ qualifiedId }) => qualifiedId !== selection.qualifiedId)
572
+ .map((window) => temporalOverlap(selection, window)));
573
+ }
574
+ function failedSelection(documentId, sourceDigest, diagnostics) {
575
+ return Object.freeze({
576
+ ok: false,
577
+ documentId,
578
+ sourceDigest,
579
+ selection: null,
580
+ orderedWorkIds: Object.freeze([]),
581
+ dependencies: Object.freeze([]),
582
+ membershipOverlaps: Object.freeze([]),
583
+ temporalOverlaps: Object.freeze([]),
584
+ diagnostics: Object.freeze(diagnostics),
585
+ });
586
+ }
587
+ export function inspectPlanningWindowSelection(text, input, capability) {
588
+ requireCapability(capability);
589
+ const sourceDigest = planningReshapeSha256(text);
590
+ const diagnostics = [];
591
+ const parsed = parsePlanningPoolSource(text, PLANNING_POOL_SOURCE_CAPABILITY);
592
+ const request = selectionInput(input, diagnostics);
593
+ if (!parsed.ok || parsed.model === null)
594
+ diagnostics.push(...parsed.diagnostics, diagnostic("PTPOOL-116", "Window selection requires a valid Grammar 9 source"));
595
+ if (request === null || parsed.model === null || diagnostics.length > 0) {
596
+ return failedSelection(parsed.documentId, sourceDigest, diagnostics);
597
+ }
598
+ const selected = request.kind === "persisted"
599
+ ? parsed.model.windows.find(({ qualifiedId }) => qualifiedId === request.window_id)
600
+ : null;
601
+ if (request.kind === "persisted" && selected === undefined)
602
+ diagnostics.push(diagnostic("PTPOOL-107", `Window ${request.window_id} does not exist`, request.window_id));
603
+ if (request.kind === "persisted")
604
+ localId(request.window_id, parsed.model.documentId, "Window id", diagnostics);
605
+ if (request.kind === "ad_hoc")
606
+ validateWorks(request.work_ids, parsed.model, diagnostics);
607
+ if (diagnostics.length > 0)
608
+ return failedSelection(parsed.documentId, sourceDigest, diagnostics);
609
+ const selectedSnapshot = selected === null || selected === undefined
610
+ ? adHocSnapshot(request)
611
+ : snapshot(selected);
612
+ const selectedSet = new Set(selectedSnapshot.workIds);
613
+ return Object.freeze({
614
+ ok: true,
615
+ documentId: parsed.model.documentId,
616
+ sourceDigest,
617
+ selection: selectedSnapshot,
618
+ orderedWorkIds: Object.freeze(parsed.model.workOrder.map(({ qualifiedId }) => qualifiedId).filter((id) => selectedSet.has(id))),
619
+ dependencies: dependencies(selectedSnapshot, parsed.model),
620
+ membershipOverlaps: membershipOverlaps(selectedSnapshot, parsed.model),
621
+ temporalOverlaps: temporalOverlaps(selectedSnapshot, parsed.model),
622
+ diagnostics: Object.freeze([]),
623
+ });
624
+ }
625
+ //# sourceMappingURL=window.js.map