@agentxm/extension-lifecycle 0.28.11 → 0.28.13

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 (207) hide show
  1. package/dist/src/activation/display-paths.d.ts +25 -0
  2. package/dist/src/activation/display-paths.js +25 -0
  3. package/dist/src/activation/errors.d.ts +16 -0
  4. package/dist/src/activation/errors.js +7 -0
  5. package/dist/src/activation/set-activation.d.ts +134 -0
  6. package/dist/src/activation/set-activation.js +772 -0
  7. package/dist/src/demote/demote-to-external-source.d.ts +82 -0
  8. package/dist/src/demote/demote-to-external-source.js +233 -0
  9. package/dist/src/errors.d.ts +0 -8
  10. package/dist/src/errors.js +0 -8
  11. package/dist/src/glob.d.ts +35 -0
  12. package/dist/src/glob.js +75 -0
  13. package/dist/src/hooks/configured-agent-outcomes-provider.d.ts +7 -3
  14. package/dist/src/hooks/configured-agent-outcomes-provider.js +11 -4
  15. package/dist/src/hooks/install/plan.d.ts +45 -0
  16. package/dist/src/hooks/install/plan.js +224 -0
  17. package/dist/src/hooks/uninstall/plan.d.ts +20 -0
  18. package/dist/src/hooks/uninstall/plan.js +77 -0
  19. package/dist/src/index.d.ts +48 -16
  20. package/dist/src/index.js +60 -17
  21. package/dist/src/install/aggregate-projection-step.d.ts +16 -0
  22. package/dist/src/install/aggregate-projection-step.js +49 -0
  23. package/dist/src/install/configured.d.ts +65 -0
  24. package/dist/src/install/configured.js +406 -0
  25. package/dist/src/install/inline-mcp-operation.d.ts +4 -0
  26. package/dist/src/install/inline-mcp-operation.js +25 -0
  27. package/dist/src/install/install-extensions.d.ts +110 -0
  28. package/dist/src/install/install-extensions.js +282 -0
  29. package/dist/src/install/per-type-install.d.ts +12 -0
  30. package/dist/src/install/per-type-install.js +12 -0
  31. package/dist/src/install/registry-install-target.d.ts +35 -0
  32. package/dist/src/install/registry-install-target.js +66 -0
  33. package/dist/src/install/registry-login-suggestion.d.ts +21 -0
  34. package/dist/src/install/registry-login-suggestion.js +34 -0
  35. package/dist/src/install/registry-source-resolution.d.ts +54 -0
  36. package/dist/src/install/registry-source-resolution.js +216 -0
  37. package/dist/src/install/root-intent.d.ts +19 -0
  38. package/dist/src/install/root-intent.js +122 -0
  39. package/dist/src/install/selection-interaction.d.ts +46 -0
  40. package/dist/src/install/selection-interaction.js +22 -0
  41. package/dist/src/install/vocabulary.d.ts +143 -0
  42. package/dist/src/install/vocabulary.js +29 -0
  43. package/dist/src/knowledge/install/plan.d.ts +35 -0
  44. package/dist/src/knowledge/install/plan.js +128 -0
  45. package/dist/src/knowledge/uninstall/plan.d.ts +23 -0
  46. package/dist/src/knowledge/uninstall/plan.js +140 -0
  47. package/dist/src/live.d.ts +4 -11
  48. package/dist/src/live.js +4 -11
  49. package/dist/src/mcps/install/plan.d.ts +65 -0
  50. package/dist/src/mcps/install/plan.js +301 -0
  51. package/dist/src/mcps/operations/disable.d.ts +5 -3
  52. package/dist/src/mcps/operations/disable.js +6 -4
  53. package/dist/src/mcps/operations/enable.d.ts +5 -3
  54. package/dist/src/mcps/operations/enable.js +8 -6
  55. package/dist/src/mcps/operations/sync-outcome.d.ts +1 -1
  56. package/dist/src/mcps/operations/uninstall.d.ts +5 -3
  57. package/dist/src/mcps/operations/uninstall.js +4 -4
  58. package/dist/src/mcps/uninstall/plan.d.ts +24 -0
  59. package/dist/src/mcps/uninstall/plan.js +109 -0
  60. package/dist/src/packs/artifact.d.ts +21 -0
  61. package/dist/src/packs/artifact.js +32 -0
  62. package/dist/src/packs/constraint-gate.d.ts +30 -0
  63. package/dist/src/packs/constraint-gate.js +76 -0
  64. package/dist/src/packs/expansion.d.ts +13 -14
  65. package/dist/src/packs/expansion.js +1 -2
  66. package/dist/src/packs/graph-transition.d.ts +64 -0
  67. package/dist/src/packs/graph-transition.js +219 -0
  68. package/dist/src/packs/install/plan.d.ts +95 -0
  69. package/dist/src/packs/install/plan.js +845 -0
  70. package/dist/src/packs/member-install-step.d.ts +29 -0
  71. package/dist/src/packs/member-install-step.js +156 -0
  72. package/dist/src/packs/operations/install.d.ts +3 -3
  73. package/dist/src/packs/operations/install.js +5 -5
  74. package/dist/src/packs/promote-authored-pack.d.ts +86 -0
  75. package/dist/src/packs/promote-authored-pack.js +239 -0
  76. package/dist/src/packs/resolved-dependency.d.ts +9 -26
  77. package/dist/src/packs/resolved-dependency.js +8 -20
  78. package/dist/src/packs/uninstall/plan.d.ts +66 -0
  79. package/dist/src/packs/uninstall/plan.js +344 -0
  80. package/dist/src/packs/uninstall/readiness.d.ts +50 -0
  81. package/dist/src/packs/uninstall/readiness.js +130 -0
  82. package/dist/src/publisher-binding.d.ts +8 -40
  83. package/dist/src/publisher-binding.js +8 -46
  84. package/dist/src/rules/install/plan.d.ts +35 -0
  85. package/dist/src/rules/install/plan.js +133 -0
  86. package/dist/src/rules/uninstall/plan.d.ts +19 -0
  87. package/dist/src/rules/uninstall/plan.js +54 -0
  88. package/dist/src/skills/install/bundled.d.ts +73 -0
  89. package/dist/src/skills/install/bundled.js +244 -0
  90. package/dist/src/skills/install/plan.d.ts +72 -0
  91. package/dist/src/skills/install/plan.js +429 -0
  92. package/dist/src/skills/install/selection.d.ts +26 -0
  93. package/dist/src/skills/install/selection.js +41 -0
  94. package/dist/src/skills/install/source.d.ts +21 -0
  95. package/dist/src/skills/install/source.js +76 -0
  96. package/dist/src/skills/operations/disable.d.ts +3 -2
  97. package/dist/src/skills/operations/disable.js +7 -11
  98. package/dist/src/skills/operations/enable.d.ts +3 -2
  99. package/dist/src/skills/operations/enable.js +6 -8
  100. package/dist/src/skills/operations/install.d.ts +4 -4
  101. package/dist/src/skills/operations/install.js +13 -12
  102. package/dist/src/skills/uninstall/plan.d.ts +23 -0
  103. package/dist/src/skills/uninstall/plan.js +165 -0
  104. package/dist/src/skills/utils.js +1 -1
  105. package/dist/src/step-failure-conversion.d.ts +44 -0
  106. package/dist/src/step-failure-conversion.js +26 -0
  107. package/dist/src/step-failure.d.ts +29 -0
  108. package/dist/src/step-failure.js +130 -0
  109. package/dist/src/subagents/install/plan.d.ts +49 -0
  110. package/dist/src/subagents/install/plan.js +270 -0
  111. package/dist/src/subagents/install/selection.d.ts +26 -0
  112. package/dist/src/subagents/install/selection.js +37 -0
  113. package/dist/src/subagents/install/source.d.ts +18 -0
  114. package/dist/src/subagents/install/source.js +72 -0
  115. package/dist/src/subagents/operations/disable.d.ts +5 -3
  116. package/dist/src/subagents/operations/disable.js +5 -3
  117. package/dist/src/subagents/operations/enable.d.ts +5 -3
  118. package/dist/src/subagents/operations/enable.js +17 -12
  119. package/dist/src/subagents/uninstall/plan.d.ts +20 -0
  120. package/dist/src/subagents/uninstall/plan.js +142 -0
  121. package/dist/src/test-packages.d.ts +34 -0
  122. package/dist/src/test-packages.js +111 -0
  123. package/dist/src/test-registry.d.ts +78 -0
  124. package/dist/src/test-registry.js +223 -0
  125. package/dist/src/testing.d.ts +108 -0
  126. package/dist/src/testing.js +241 -0
  127. package/dist/src/uninstall/retention-policy.d.ts +21 -0
  128. package/dist/src/uninstall/retention-policy.js +28 -0
  129. package/dist/src/uninstall/root-intent.d.ts +17 -0
  130. package/dist/src/uninstall/root-intent.js +101 -0
  131. package/dist/src/uninstall/uninstall-extensions.d.ts +61 -0
  132. package/dist/src/uninstall/uninstall-extensions.js +127 -0
  133. package/dist/src/uninstall/vocabulary.d.ts +40 -0
  134. package/dist/src/uninstall/vocabulary.js +14 -0
  135. package/dist/src/update/atomicity.d.ts +22 -0
  136. package/dist/src/update/atomicity.js +23 -0
  137. package/dist/src/update/blockers.d.ts +31 -0
  138. package/dist/src/update/blockers.js +78 -0
  139. package/dist/src/update/configured.d.ts +78 -0
  140. package/dist/src/update/configured.js +546 -0
  141. package/dist/src/update/root-request.d.ts +39 -0
  142. package/dist/src/update/root-request.js +117 -0
  143. package/dist/src/update/selective/plan.d.ts +45 -0
  144. package/dist/src/update/selective/plan.js +61 -0
  145. package/dist/src/update/selective/requirements.d.ts +17 -0
  146. package/dist/src/update/selective/requirements.js +14 -0
  147. package/dist/src/update/selective/selection.d.ts +63 -0
  148. package/dist/src/update/selective/selection.js +85 -0
  149. package/dist/src/update/selective/skills.d.ts +55 -0
  150. package/dist/src/update/selective/skills.js +596 -0
  151. package/dist/src/update/selective/subagents.d.ts +52 -0
  152. package/dist/src/update/selective/subagents.js +331 -0
  153. package/dist/src/update/selective/use-case.d.ts +121 -0
  154. package/dist/src/update/selective/use-case.js +28 -0
  155. package/dist/src/update/selective/vocabulary.d.ts +43 -0
  156. package/dist/src/update/selective/vocabulary.js +28 -0
  157. package/dist/src/update/selector.d.ts +72 -0
  158. package/dist/src/update/selector.js +120 -0
  159. package/dist/src/update/targeted-plan.d.ts +30 -0
  160. package/dist/src/update/targeted-plan.js +113 -0
  161. package/dist/src/update/update-extensions.d.ts +164 -0
  162. package/dist/src/update/update-extensions.js +579 -0
  163. package/dist/src/workspace-paths.d.ts +31 -0
  164. package/dist/src/workspace-paths.js +46 -0
  165. package/package.json +22 -12
  166. package/dist/src/configured-entry-resolution.d.ts +0 -111
  167. package/dist/src/configured-entry-resolution.js +0 -731
  168. package/dist/src/failure-adapter.d.ts +0 -35
  169. package/dist/src/failure-adapter.js +0 -23
  170. package/dist/src/hooks/manager.d.ts +0 -15
  171. package/dist/src/hooks/manager.js +0 -769
  172. package/dist/src/internal/fs-helpers.d.ts +0 -12
  173. package/dist/src/internal/fs-helpers.js +0 -13
  174. package/dist/src/internal/integrity.d.ts +0 -13
  175. package/dist/src/internal/integrity.js +0 -17
  176. package/dist/src/knowledge/manager.d.ts +0 -11
  177. package/dist/src/knowledge/manager.js +0 -711
  178. package/dist/src/mcps/manager.d.ts +0 -16
  179. package/dist/src/mcps/manager.js +0 -247
  180. package/dist/src/mcps/operations/artifact.d.ts +0 -24
  181. package/dist/src/mcps/operations/artifact.js +0 -74
  182. package/dist/src/mcps/operations/install.d.ts +0 -78
  183. package/dist/src/mcps/operations/install.js +0 -596
  184. package/dist/src/packs/dependency-resolution.d.ts +0 -65
  185. package/dist/src/packs/dependency-resolution.js +0 -414
  186. package/dist/src/packs/manager.d.ts +0 -16
  187. package/dist/src/packs/manager.js +0 -181
  188. package/dist/src/registry-materialization.d.ts +0 -52
  189. package/dist/src/registry-materialization.js +0 -72
  190. package/dist/src/release-age-posture.d.ts +0 -23
  191. package/dist/src/release-age-posture.js +0 -15
  192. package/dist/src/resolution-timeout.d.ts +0 -5
  193. package/dist/src/resolution-timeout.js +0 -11
  194. package/dist/src/rules/manager.d.ts +0 -20
  195. package/dist/src/rules/manager.js +0 -480
  196. package/dist/src/skills/manager.d.ts +0 -18
  197. package/dist/src/skills/manager.js +0 -346
  198. package/dist/src/skills/materialization.d.ts +0 -54
  199. package/dist/src/skills/materialization.js +0 -158
  200. package/dist/src/skills/operations/source-hash.d.ts +0 -2
  201. package/dist/src/skills/operations/source-hash.js +0 -6
  202. package/dist/src/subagents/manager.d.ts +0 -18
  203. package/dist/src/subagents/manager.js +0 -722
  204. package/dist/src/workflows/install-command/workflow.d.ts +0 -56
  205. package/dist/src/workflows/install-command/workflow.js +0 -46
  206. package/dist/src/workflows/uninstall-command/workflow.d.ts +0 -42
  207. package/dist/src/workflows/uninstall-command/workflow.js +0 -29
@@ -1,711 +0,0 @@
1
- // @effect-diagnostics anyUnknownInErrorContext:off — schema and filesystem errors are swept into KnowledgeIoFailed inside this manager
2
- /** Lifecycle manager for isolated Open Knowledge Format bundles. */
3
- import * as Effect from "effect/Effect";
4
- import * as FileSystem from "effect/FileSystem";
5
- import * as HttpClient from "effect/unstable/http/HttpClient";
6
- import * as Layer from "effect/Layer";
7
- import * as Option from "effect/Option";
8
- import * as Path from "effect/Path";
9
- import * as Ref from "effect/Ref";
10
- import * as Schema from "effect/Schema";
11
- import * as Scope from "effect/Scope";
12
- import * as Result from "effect/Result";
13
- import { PlatformError } from "effect/PlatformError";
14
- import { KnowledgeDefinitionInvalid, KnowledgeDesiredStateUnreconcilable, KnowledgeInstallStateMissing, KnowledgeIoFailed, KnowledgeObservableContractViolated, KnowledgeResolutionMissing, KnowledgeUnavailable, applyProjectionPlans, formatProjectionExclusions, planAggregateProjection, requireCompleteGraph, KNOWLEDGE_REGION_OWNER, reconcileKnowledgeDiscovery, resolveInstructionsConfig, } from "@agentxm/extension-workspace";
15
- import { canReuseInstalledPackage, materializeExternalPackage } from "@agentxm/extension-workspace";
16
- import { materializeRegistryPackage } from "../registry-materialization.js";
17
- import { computeExtensionPathsForLayout, extensionPathSourceFromLockEntry, } from "@agentxm/workspace-state";
18
- import { computePackageContentHash } from "@agentxm/workspace-state";
19
- import { computeMaterializedTreeIntegrity } from "@agentxm/workspace-state";
20
- import { acceptedRegistryVersionForRef, validateExactResolvedVersion, } from "@agentxm/workspace-state";
21
- import { gitSourceLockFields } from "@agentxm/workspace-state";
22
- import { SourceHostProviders, WorkspaceCatalog } from "@agentxm/extension-sources";
23
- import { knowledgeLockEntryToRef } from "@agentxm/workspace-state";
24
- import { stripFileProtocol } from "../internal/fs-helpers.js";
25
- import { makeWorkspaceRelativeSourcePath } from "@agentxm/extension-model/unstable/path-types";
26
- import { recordFootprint } from "@agentxm/workspace-state";
27
- import { makeWorkspaceRelativePath } from "@agentxm/extension-model/unstable/path-types";
28
- import { decodeVersionSync } from "@agentxm/extension-model/unstable/version-constraints";
29
- import { usableAcceptedCanonicalRef } from "@agentxm/workspace-state";
30
- import { getKnowledgeLockEntries } from "@agentxm/workspace-state";
31
- import { KnowledgeManager, } from "@agentxm/extension-workspace";
32
- import { WorkspaceMutations } from "@agentxm/workspace-state";
33
- import { isObservedInstalled } from "@agentxm/workspace-state";
34
- import { acceptedCanonicalObservation, prepareAcceptedCanonicalTransition, removableAcceptedCanonicalPath, } from "@agentxm/workspace-state";
35
- import { protectWorkspacePath } from "@agentxm/workspace-state";
36
- import { isSourcedDesiredExtension } from "@agentxm/workspace-state";
37
- import { KNOWLEDGE_EXTENSION_DIR, KNOWLEDGE_MANIFEST_FILENAME, KNOWLEDGE_SOURCE_DIR, KnowledgeManifestSchema, } from "@agentxm/extension-model/unstable/knowledge/manifest-schema";
38
- import { inspectKnowledgeBundle, } from "@agentxm/registry-protocol/unstable/knowledge/okf";
39
- import { resolveKnowledgeInstructionEntry } from "@agentxm/extension-workspace";
40
- import { coupleLifecycleDependencyFailure } from "../errors.js";
41
- import { LifecycleFailureAdapter } from "../failure-adapter.js";
42
- const decodeManifest = Schema.decodeUnknownEffect(KnowledgeManifestSchema);
43
- const registryLockEntry = (ref, treeIntegrity) => ({
44
- type: "registry",
45
- sourceType: "registry",
46
- packageFormat: "agentxm",
47
- endpoint: ref.source.location,
48
- extensionType: "knowledge",
49
- workspaceName: ref.knowledge.name,
50
- owner: ref.owner,
51
- name: ref.name,
52
- resolvedVersion: decodeVersionSync(ref.version),
53
- integrity: Option.getOrElse(ref.integrity, () => ""),
54
- sourceName: ref.source.name,
55
- publisherBindingId: ref.publisherBindingId,
56
- treeIntegrity,
57
- });
58
- const gitLockEntry = (ref, contentIdentity, treeIntegrity) => ({
59
- ...gitSourceLockFields(ref.source, "knowledge", ref.knowledge.name, Option.fromUndefinedOr(ref.sourcePath), ref.gitCommitSha, ref.gitTreeSha, contentIdentity, ref.owner, ref.name, treeIntegrity),
60
- });
61
- const localLockEntry = (ref, relativePath, contentIdentity, treeIntegrity) => ({
62
- type: "local",
63
- sourceType: "local",
64
- sourceName: "local",
65
- extensionType: "knowledge",
66
- workspaceName: ref.knowledge.name,
67
- packageFormat: "agentxm",
68
- packageOwner: ref.owner,
69
- packageName: ref.name,
70
- path: Option.getOrElse(relativePath, () => ref.source.path),
71
- contentIdentity,
72
- treeIntegrity,
73
- });
74
- export const KnowledgeManagerLive = Layer.effect(KnowledgeManager, Effect.gen(function* () {
75
- const ws = yield* WorkspaceMutations;
76
- const fs = yield* FileSystem.FileSystem;
77
- const httpClient = yield* HttpClient.HttpClient;
78
- const path = yield* Path.Path;
79
- const sources = yield* SourceHostProviders;
80
- const catalog = yield* WorkspaceCatalog;
81
- const adapter = yield* LifecycleFailureAdapter;
82
- const baseDir = ws.baseDir;
83
- const env = Layer.mergeAll(Layer.succeed(FileSystem.FileSystem, fs), Layer.succeed(HttpClient.HttpClient, httpClient), Layer.succeed(Path.Path, path), Layer.succeed(WorkspaceMutations, ws), Layer.succeed(SourceHostProviders, sources), Layer.succeed(WorkspaceCatalog, catalog), Layer.succeed(LifecycleFailureAdapter, adapter));
84
- const provide = (effect) => Effect.provide(effect, env);
85
- const lastInstallState = new Map();
86
- const canonicalPathForRef = (ref) => computeExtensionPathsForLayout(path.join, ws.layout, ref, KNOWLEDGE_EXTENSION_DIR, ref.name)
87
- .canonicalPath;
88
- const materializePackage = (ref, options) => {
89
- const canonicalPath = options?.destinationPath ?? canonicalPathForRef(ref);
90
- const materializationBaseDir = options?.baseDir ?? baseDir;
91
- switch (ref.refType) {
92
- case "registry":
93
- return Effect.gen(function* () {
94
- return yield* provide(materializeRegistryPackage({
95
- baseDir: materializationBaseDir,
96
- destinationPath: canonicalPath,
97
- sourceLocation: ref.source.location,
98
- owner: ref.owner,
99
- type: "knowledge",
100
- name: ref.name,
101
- version: ref.version,
102
- integrity: ref.integrity,
103
- messages: {
104
- integrityMismatchDetail: `Integrity mismatch for knowledge:${ref.name}@${ref.version}`,
105
- },
106
- }));
107
- });
108
- case "git-hosted":
109
- case "local":
110
- return provide(materializeExternalPackage({
111
- baseDir: materializationBaseDir,
112
- canonicalPath,
113
- sourceLocation: ref.location,
114
- copyFailureCode: "validation",
115
- copyFailureDetail: (target) => `Failed to copy knowledge package to ${target}`,
116
- }));
117
- case "workspace":
118
- if (ref.scope !== ws.scope ||
119
- path.resolve(ref.location) !== path.resolve(canonicalPath)) {
120
- return Effect.fail(new KnowledgeDefinitionInvalid({
121
- detail: `Invalid workspace knowledge source location: ${ref.location}`,
122
- }));
123
- }
124
- return Effect.succeed(ref.location);
125
- }
126
- };
127
- const inspectPackage = (packageRoot) => Effect.gen(function* () {
128
- const raw = yield* fs
129
- .readFileString(path.join(packageRoot, KNOWLEDGE_MANIFEST_FILENAME))
130
- .pipe(Effect.mapError((cause) => new KnowledgeDefinitionInvalid({
131
- detail: `Failed to read ${KNOWLEDGE_MANIFEST_FILENAME}`,
132
- cause,
133
- })));
134
- const manifest = yield* Effect.try({
135
- try: () => JSON.parse(raw),
136
- catch: (cause) => new KnowledgeDefinitionInvalid({
137
- detail: `Failed to parse ${KNOWLEDGE_MANIFEST_FILENAME}`,
138
- cause,
139
- }),
140
- }).pipe(Effect.flatMap(decodeManifest), Effect.mapError((cause) => new KnowledgeDefinitionInvalid({
141
- detail: `Invalid ${KNOWLEDGE_MANIFEST_FILENAME}`,
142
- cause,
143
- })));
144
- const inspection = yield* provide(inspectKnowledgeBundle(path.join(packageRoot, KNOWLEDGE_SOURCE_DIR))).pipe(Effect.mapError((cause) => new KnowledgeDefinitionInvalid({
145
- detail: "Failed to inspect Open Knowledge Format bundle",
146
- cause,
147
- })));
148
- const errors = inspection.diagnostics.filter((item) => item.severity === "error");
149
- if (errors.length > 0) {
150
- return yield* new KnowledgeDefinitionInvalid({
151
- detail: errors
152
- .map((item) => item.details?.kind === "frontmatter-parse"
153
- ? `${item.relativePath}: ${item.message}`
154
- : item.message)
155
- .join(" "),
156
- });
157
- }
158
- return { manifest, inspection };
159
- });
160
- const preparePackage = (ref, force = false) => Effect.gen(function* () {
161
- const canonicalPath = canonicalPathForRef(ref);
162
- if (ref.refType === "workspace") {
163
- const root = yield* materializePackage(ref);
164
- yield* inspectPackage(root);
165
- return {
166
- root,
167
- sourceHash: ref.sourceHash,
168
- commit: Effect.void,
169
- rollback: Effect.void,
170
- };
171
- }
172
- // Decide against the canonical tree before staging: the staged path
173
- // never exists, so a decision made there would re-extract every time
174
- // and revert workspace-owned content on a no-op install.
175
- if (ref.refType === "registry") {
176
- const lockedEntry = yield* ws.getLockedKnowledgeEntry(ref.knowledge.name);
177
- const lockedVersion = acceptedRegistryVersionForRef(lockedEntry, ref);
178
- const reuse = yield* provide(canReuseInstalledPackage({
179
- installedPath: canonicalPath,
180
- force,
181
- refVersion: ref.version,
182
- hasIntegrity: Option.isSome(ref.integrity),
183
- ...(lockedVersion === undefined ? {} : { lockedVersion }),
184
- existsFailureDetail: (target) => `Failed to inspect knowledge path: ${target}`,
185
- }));
186
- if (reuse && Option.isSome(lockedEntry)) {
187
- const observedTree = yield* provide(computeMaterializedTreeIntegrity(canonicalPath));
188
- if (observedTree !== lockedEntry.value.treeIntegrity) {
189
- yield* Effect.logWarning(`Knowledge package ${ref.knowledge.name} differs from its accepted tree; rematerializing`);
190
- }
191
- else {
192
- return {
193
- root: canonicalPath,
194
- sourceHash: yield* provide(computePackageContentHash(canonicalPath)),
195
- treeIntegrity: lockedEntry.value.treeIntegrity,
196
- commit: Effect.void,
197
- rollback: Effect.void,
198
- };
199
- }
200
- }
201
- }
202
- const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "axm-knowledge-package-" });
203
- const stagedPath = path.join(tempDir, "staged");
204
- const backupPath = path.join(tempDir, "previous");
205
- const stageState = yield* Ref.make({ phase: "preparing" });
206
- const restoreStagedPackage = Ref.get(stageState).pipe(Effect.flatMap((state) => {
207
- if (state.phase !== "staged")
208
- return Effect.void;
209
- return fs.remove(canonicalPath, { recursive: true, force: true }).pipe(Effect.mapError((cause) => new KnowledgeIoFailed({
210
- detail: `Failed to remove staged Knowledge package during rollback: ${canonicalPath}`,
211
- cause,
212
- })), Effect.andThen(state.hadCanonical
213
- ? fs.rename(backupPath, canonicalPath).pipe(Effect.mapError((cause) => new KnowledgeIoFailed({
214
- detail: `Failed to restore Knowledge package during rollback: ${canonicalPath}`,
215
- cause,
216
- })))
217
- : Effect.void), Effect.andThen(Ref.set(stageState, { phase: "settled" })));
218
- }));
219
- yield* Effect.addFinalizer(() => restoreStagedPackage.pipe(Effect.catchCause((cause) => Effect.logError("Failed to restore staged Knowledge package during finalization", cause))));
220
- const stagedRoot = yield* materializePackage(ref, {
221
- baseDir: tempDir,
222
- destinationPath: stagedPath,
223
- });
224
- yield* inspectPackage(stagedRoot);
225
- const sourceHash = yield* provide(computePackageContentHash(stagedRoot));
226
- const treeIntegrity = yield* provide(computeMaterializedTreeIntegrity(stagedRoot));
227
- yield* protectWorkspacePath(canonicalPath);
228
- const hadCanonical = yield* fs.exists(canonicalPath);
229
- yield* Effect.uninterruptible(Effect.gen(function* () {
230
- if (hadCanonical)
231
- yield* fs.rename(canonicalPath, backupPath);
232
- yield* fs.makeDirectory(path.dirname(canonicalPath), { recursive: true });
233
- yield* fs.rename(stagedPath, canonicalPath).pipe(Effect.tapError(() => hadCanonical
234
- ? fs.rename(backupPath, canonicalPath).pipe(Effect.mapError((cause) => new KnowledgeIoFailed({
235
- detail: `Failed to restore Knowledge package after staging failed: ${canonicalPath}`,
236
- cause,
237
- })))
238
- : Effect.void));
239
- yield* Ref.set(stageState, { phase: "staged", hadCanonical });
240
- }));
241
- yield* recordFootprint({
242
- path: canonicalPath,
243
- change: hadCanonical ? "modified" : "created",
244
- });
245
- return {
246
- root: canonicalPath,
247
- sourceHash,
248
- treeIntegrity,
249
- commit: Ref.set(stageState, { phase: "settled" }),
250
- rollback: restoreStagedPackage,
251
- };
252
- }).pipe(Effect.mapError((cause) => cause instanceof PlatformError
253
- ? new KnowledgeIoFailed({
254
- detail: `Failed to stage Knowledge bundle ${ref.knowledge.name}`,
255
- cause,
256
- })
257
- : cause));
258
- const getInstructionsTarget = () => Effect.gen(function* () {
259
- const config = yield* ws.getInstructionsConfig();
260
- const enabled = Option.isSome(config) && config.value !== false;
261
- const resolved = resolveInstructionsConfig(enabled ? config.value : undefined);
262
- const relative = makeWorkspaceRelativePath(path, baseDir, resolved.fileName);
263
- if (Option.isNone(relative)) {
264
- return yield* new KnowledgeDefinitionInvalid({
265
- detail: `Knowledge discovery instruction target escapes workspace: ${resolved.fileName}`,
266
- });
267
- }
268
- return {
269
- path: path.resolve(baseDir, relative.value),
270
- enabled,
271
- preserveSource: enabled,
272
- };
273
- });
274
- const canonicalRoot = (_name, locked) => computeExtensionPathsForLayout(path.join, ws.layout, extensionPathSourceFromLockEntry(locked), KNOWLEDGE_EXTENSION_DIR, locked.workspaceName).canonicalPath;
275
- const desiredCanonicalRoot = (node, locked) => {
276
- if (node.identity.startsWith("workspace:")) {
277
- return ws.layout.scope === "project"
278
- ? Effect.succeed(path.join(ws.layout.authoredRoot("knowledge"), node.name))
279
- : Effect.fail(new KnowledgeDefinitionInvalid({
280
- detail: "User workspaces do not support workspace-authored Knowledge bundles",
281
- }));
282
- }
283
- return locked === undefined
284
- ? Effect.fail(new KnowledgeResolutionMissing({ name: node.name }))
285
- : Effect.succeed(canonicalRoot(node.name, locked));
286
- };
287
- const toProjectionBundle = (root, inspected) => ({
288
- owner: inspected.manifest.owner,
289
- name: inspected.manifest.name,
290
- sourceDir: path.join(root, KNOWLEDGE_SOURCE_DIR),
291
- ...(inspected.manifest.description === undefined
292
- ? {}
293
- : { description: inspected.manifest.description }),
294
- });
295
- const activeKnowledgeNodes = () => ws
296
- .getDesiredStateGraph()
297
- .pipe(Effect.flatMap((graph) => graph.complete
298
- ? Effect.succeed(graph.nodes
299
- .filter(isSourcedDesiredExtension)
300
- .filter((node) => node.type === "knowledge" && node.enabled))
301
- : new KnowledgeDesiredStateUnreconcilable()));
302
- /**
303
- * Classify a bundle whose package could not be inspected. Only the
304
- * bundle's own content is in question here: resolution facts have already
305
- * succeeded, so the two truthful answers are that the package is gone or
306
- * that its content is invalid.
307
- */
308
- const excludedContributor = (name, root, failure) => Effect.gen(function* () {
309
- const probe = yield* Effect.result(fs.exists(path.join(root, KNOWLEDGE_MANIFEST_FILENAME)));
310
- const manifestPresent = Result.isSuccess(probe) && probe.success;
311
- if (!manifestPresent)
312
- return { contributor: name, reason: "package-missing" };
313
- return {
314
- contributor: name,
315
- reason: "package-invalid",
316
- detail: failure._tag === "KnowledgeDefinitionInvalid"
317
- ? failure.detail
318
- : adapter.describeFailure(failure),
319
- };
320
- });
321
- /**
322
- * Resolve the contributor set for the discovery region. A bundle that
323
- * fails inspection cannot supply a row, so it is excluded and reported
324
- * rather than failing every other bundle's command with it. Resolution
325
- * failures — a missing lock entry, an unsupported workspace-authored
326
- * bundle — remain fail-closed: they are AXM state problems, not bundle
327
- * content problems.
328
- */
329
- const selectKnowledgeBundles = (graph, locked, configured, config, instructionFilesEnabled) => Effect.forEach(graph.nodes.filter((node) => node.type === "knowledge" && node.enabled), (node) => Effect.gen(function* () {
330
- const root = yield* desiredCanonicalRoot(node, locked[node.name]);
331
- const workspaceInstructionEntry = configured[node.name]?.instructionEntry;
332
- const resolveInclusion = (manifestInstructionEntry) => resolveKnowledgeInstructionEntry({
333
- bundleEnabled: node.enabled,
334
- instructionFilesEnabled,
335
- knowledgeInstructionsEnabled: config.instructions,
336
- ...(workspaceInstructionEntry === undefined ? {} : { workspaceInstructionEntry }),
337
- ...(manifestInstructionEntry === undefined ? {} : { manifestInstructionEntry }),
338
- });
339
- const inspection = yield* Effect.result(inspectPackage(root));
340
- if (Result.isFailure(inspection)) {
341
- // A bundle the workspace would not publish anyway is simply
342
- // absent from the region; reporting it would be noise.
343
- return resolveInclusion().included
344
- ? {
345
- contributors: [],
346
- exclusions: [yield* excludedContributor(node.name, root, inspection.failure)],
347
- }
348
- : { contributors: [], exclusions: [] };
349
- }
350
- const inspected = inspection.success;
351
- const resolution = resolveInclusion(inspected.manifest.instructionEntry);
352
- return {
353
- contributors: resolution.included ? [toProjectionBundle(root, inspected)] : [],
354
- exclusions: [],
355
- };
356
- })).pipe(Effect.map((selections) => ({
357
- contributors: selections.flatMap(({ contributors }) => contributors),
358
- exclusions: selections.flatMap(({ exclusions }) => exclusions),
359
- })));
360
- const resolveKnowledgeProjection = () => Effect.gen(function* () {
361
- const graph = yield* ws.getDesiredStateGraph();
362
- const locked = yield* getKnowledgeLockEntries(ws);
363
- const configured = yield* ws.getConfiguredKnowledgeEntries();
364
- const config = yield* ws.getKnowledgeDiscoveryConfig();
365
- const instructionsTarget = yield* getInstructionsTarget();
366
- return { graph, locked, configured, config, instructionsTarget };
367
- });
368
- const runKnowledgeProjectionAdapter = (args) => provide(reconcileKnowledgeDiscovery({
369
- scopeRoot: baseDir,
370
- config: args.config,
371
- bundles: args.bundles,
372
- instructionsPath: args.instructionsTarget.path,
373
- instructionManagementEnabled: args.instructionsTarget.enabled,
374
- preserveInstructionsSource: args.instructionsTarget.preserveSource,
375
- ...(args.dryRun === undefined ? {} : { dryRun: args.dryRun }),
376
- }));
377
- const makeKnowledgeProjectionPlan = () => Effect.gen(function* () {
378
- const { graph, locked, configured, config, instructionsTarget } = yield* resolveKnowledgeProjection();
379
- return yield* planAggregateProjection({
380
- unitId: "knowledge:discovery-region",
381
- targetFile: instructionsTarget.path,
382
- graph,
383
- select: (completeGraph) => selectKnowledgeBundles(completeGraph, locked, configured, config, instructionsTarget.enabled),
384
- adapter: {
385
- observe: (input) => runKnowledgeProjectionAdapter({
386
- bundles: input.contributors,
387
- config,
388
- instructionsTarget,
389
- dryRun: true,
390
- }).pipe(Effect.map((result) => ({
391
- unitId: "knowledge:discovery-region",
392
- path: `${instructionsTarget.path}#knowledge`,
393
- owner: KNOWLEDGE_REGION_OWNER,
394
- present: Option.isSome(result.observedRegion),
395
- current: !result.changed,
396
- expectedContributors: input.contributors.map(({ owner, name }) => `${owner}/knowledge/${name}`),
397
- }))),
398
- apply: (input) => runKnowledgeProjectionAdapter({
399
- bundles: input.contributors,
400
- config,
401
- instructionsTarget,
402
- }).pipe(Effect.asVoid),
403
- },
404
- });
405
- });
406
- const projectionPlans = () => makeKnowledgeProjectionPlan().pipe(Effect.map((plan) => [plan]));
407
- const applyKnowledgeProjection = projectionPlans().pipe(Effect.flatMap(applyProjectionPlans));
408
- const reconcileDiscovery = (options) => resolveKnowledgeProjection().pipe(Effect.flatMap(({ graph, locked, configured, config, instructionsTarget }) => requireCompleteGraph(graph).pipe(Effect.flatMap((completeGraph) => selectKnowledgeBundles(completeGraph, locked, configured, config, instructionsTarget.enabled)), Effect.flatMap(({ contributors, exclusions }) => runKnowledgeProjectionAdapter({
409
- bundles: contributors,
410
- config,
411
- instructionsTarget,
412
- ...(options?.dryRun === undefined ? {} : { dryRun: options.dryRun }),
413
- }).pipe(Effect.map((result) => ({
414
- ...result,
415
- warnings: formatProjectionExclusions({
416
- exclusions,
417
- targetFile: instructionsTarget.path,
418
- }),
419
- })))))));
420
- const buildLockEntry = (ref) => Effect.gen(function* () {
421
- const state = lastInstallState.get(ref.knowledge.name);
422
- switch (ref.refType) {
423
- case "registry":
424
- return state?.treeIntegrity === undefined
425
- ? yield* new KnowledgeInstallStateMissing({
426
- name: ref.knowledge.name,
427
- kind: "tree-integrity",
428
- })
429
- : Option.some(registryLockEntry(ref, state.treeIntegrity));
430
- case "git-hosted":
431
- return state?.treeIntegrity === undefined
432
- ? yield* new KnowledgeInstallStateMissing({
433
- name: ref.knowledge.name,
434
- kind: "content-identity",
435
- })
436
- : Option.some(gitLockEntry(ref, state.sourceHash, state.treeIntegrity));
437
- case "local":
438
- return state?.treeIntegrity === undefined
439
- ? yield* new KnowledgeInstallStateMissing({
440
- name: ref.knowledge.name,
441
- kind: "content-identity",
442
- })
443
- : Option.some(localLockEntry(ref, state.relativeLocalSource, state.sourceHash, state.treeIntegrity));
444
- case "workspace":
445
- return Option.none();
446
- }
447
- });
448
- const setKnowledgeSourceEntry = (name, source) => Effect.gen(function* () {
449
- const configured = yield* ws.getConfiguredKnowledgeEntries();
450
- const current = configured[name];
451
- yield* ws.setKnowledgeEntry(name, {
452
- source,
453
- enabled: true,
454
- ...(current?.instructionEntry === undefined
455
- ? {}
456
- : { instructionEntry: current.instructionEntry }),
457
- });
458
- });
459
- const restoreLockedPackage = (name, entry) => Effect.gen(function* () {
460
- const ref = yield* knowledgeLockEntryToRef(name, entry, {
461
- baseDir,
462
- path,
463
- scope: ws.scope,
464
- getConfiguredSourceByName: (sourceName) => ws.getConfiguredSourceByName(sourceName),
465
- });
466
- if (ref.refType === "registry" && Option.isNone(ref.integrity)) {
467
- return yield* new KnowledgeUnavailable({
468
- detail: `Locked registry Knowledge bundle has no integrity and cannot be restored: ${name}`,
469
- });
470
- }
471
- if (ref.refType !== "git-hosted") {
472
- return yield* preparePackage(ref);
473
- }
474
- const discovered = yield* sources
475
- .find(ref.source, {
476
- names: [name],
477
- type: "knowledge",
478
- owner: Option.none(),
479
- versionRange: Option.none(),
480
- })
481
- .pipe(Effect.mapError(coupleLifecycleDependencyFailure));
482
- const candidate = discovered.find((item) => item.type === "knowledge" && item.refType === "git-hosted");
483
- if (candidate === undefined ||
484
- candidate.gitTreeSha !== ref.gitTreeSha ||
485
- candidate.gitCommitSha !== ref.gitCommitSha) {
486
- return yield* new KnowledgeUnavailable({
487
- detail: `Git Knowledge source no longer resolves to locked commit/tree ${ref.gitCommitSha}/${ref.gitTreeSha}: ${name}`,
488
- });
489
- }
490
- return yield* preparePackage(candidate);
491
- });
492
- const syncLocked = (dryRun) => Effect.gen(function* () {
493
- const desired = yield* activeKnowledgeNodes();
494
- const locked = yield* getKnowledgeLockEntries(ws);
495
- const prepared = [];
496
- for (const node of desired) {
497
- const { name } = node;
498
- const entry = locked[name];
499
- const root = yield* desiredCanonicalRoot(node, entry);
500
- const inspection = yield* Effect.result(inspectPackage(root));
501
- if (Result.isSuccess(inspection))
502
- continue;
503
- if (node.identity.startsWith("workspace:")) {
504
- return yield* new KnowledgeDefinitionInvalid({
505
- detail: `Active workspace-authored Knowledge bundle is missing or invalid: ${name}`,
506
- cause: inspection.failure,
507
- });
508
- }
509
- if (entry === undefined) {
510
- return yield* new KnowledgeResolutionMissing({ name });
511
- }
512
- const restored = yield* Effect.result(restoreLockedPackage(name, entry));
513
- if (Result.isFailure(restored)) {
514
- yield* Effect.forEach([...prepared].reverse(), (item) => item.rollback, {
515
- discard: true,
516
- });
517
- const restoreFailure = restored.failure;
518
- return yield* new KnowledgeUnavailable({
519
- detail: `Active Knowledge bundle could not be restored: ${name}. ${adapter.describeFailure(restoreFailure)}`,
520
- cause: restoreFailure,
521
- });
522
- }
523
- else
524
- prepared.push(restored.success);
525
- }
526
- const discovered = yield* Effect.result(reconcileDiscovery({ dryRun: true }));
527
- if (Result.isFailure(discovered)) {
528
- yield* Effect.forEach([...prepared].reverse(), (item) => item.rollback, {
529
- discard: true,
530
- });
531
- return yield* discovered.failure;
532
- }
533
- if (!dryRun)
534
- yield* applyKnowledgeProjection;
535
- yield* Effect.forEach(dryRun ? [...prepared].reverse() : prepared, (item) => (dryRun ? item.rollback : item.commit), { discard: true });
536
- const discovery = discovered.success;
537
- return {
538
- changed: prepared.length > 0 || discovery.changed,
539
- warnings: discovery.warnings,
540
- artifacts: discovery.artifacts,
541
- };
542
- });
543
- const installAtomically = (args) => ws
544
- .runTransaction({
545
- transition: Effect.gen(function* () {
546
- const name = args.ref.knowledge.name;
547
- const relativeLocalSource = args.ref.refType === "local"
548
- ? makeWorkspaceRelativeSourcePath(path, baseDir, args.ref.sourcePath ?? stripFileProtocol(args.ref.location))
549
- : Option.none();
550
- if (args.ref.refType === "local" && Option.isNone(relativeLocalSource)) {
551
- return yield* new KnowledgeDefinitionInvalid({
552
- detail: `Local knowledge source must stay within the workspace: ${args.ref.source.path}`,
553
- });
554
- }
555
- const cleanupSupersededCanonical = yield* provide(prepareAcceptedCanonicalTransition({
556
- workspace: ws,
557
- type: "knowledge",
558
- name,
559
- ref: args.ref,
560
- }));
561
- const prepared = yield* preparePackage(args.ref);
562
- const committed = yield* Effect.gen(function* () {
563
- lastInstallState.set(name, {
564
- relativeLocalSource,
565
- sourceHash: prepared.sourceHash,
566
- ...(prepared.treeIntegrity === undefined
567
- ? {}
568
- : { treeIntegrity: prepared.treeIntegrity }),
569
- });
570
- if (args.ref.refType !== "workspace" && prepared.treeIntegrity === undefined) {
571
- return yield* new KnowledgeInstallStateMissing({
572
- name,
573
- kind: "staged-tree-integrity",
574
- });
575
- }
576
- const lockEntry = yield* buildLockEntry(args.ref);
577
- if (Option.isSome(lockEntry)) {
578
- yield* ws.setKnowledge({
579
- name,
580
- lockEntry: lockEntry.value,
581
- versionRange: args.versionRange,
582
- });
583
- }
584
- else {
585
- yield* setKnowledgeSourceEntry(name, "workspace");
586
- }
587
- yield* cleanupSupersededCanonical;
588
- return { name };
589
- });
590
- if (args.deferProjection !== true)
591
- yield* applyKnowledgeProjection;
592
- // The workspace transaction owns a nested scope. Settle the staged
593
- // package before that scope closes; a later postcondition failure
594
- // still restores the transaction snapshot.
595
- yield* prepared.commit;
596
- return committed;
597
- }),
598
- validate: ({ name }) => isObservedInstalled(ws, "knowledge", name).pipe(Effect.flatMap((installed) => installed ? Effect.void : new KnowledgeObservableContractViolated({ name }))),
599
- })
600
- .pipe(Effect.scoped, Effect.tapError(() => Effect.sync(() => {
601
- lastInstallState.delete(args.ref.knowledge.name);
602
- })), Effect.asVoid);
603
- // Canonical removal only. The shared operation flow re-renders the
604
- // discovery region after settings and lock removal, once the target has
605
- // left the graph.
606
- const materializeUninstall = Effect.fn("KnowledgeManager.materializeUninstall")(function* ({ target }) {
607
- const canonical = yield* provide(acceptedCanonicalObservation({
608
- workspace: ws,
609
- type: "knowledge",
610
- name: target.name,
611
- }));
612
- const root = removableAcceptedCanonicalPath(canonical);
613
- const locked = yield* ws.getLockedKnowledgeEntry(target.name);
614
- const ownedRoot = Option.orElse(root, () => Option.map(locked, (entry) => canonicalRoot(target.name, entry)));
615
- if (Option.isSome(ownedRoot)) {
616
- yield* protectWorkspacePath(ownedRoot.value);
617
- yield* fs.remove(ownedRoot.value, { recursive: true, force: true }).pipe(Effect.mapError((cause) => new KnowledgeIoFailed({
618
- detail: `Failed to remove Knowledge package source: ${ownedRoot.value}`,
619
- cause,
620
- })));
621
- }
622
- }, Effect.asVoid);
623
- // Deactivation retains canonical content; the caller updates settings
624
- // first, so re-rendering the whole region drops this bundle's routing.
625
- const materializeDeactivate = Effect.fn("KnowledgeManager.materializeDeactivate")(() => applyKnowledgeProjection);
626
- return {
627
- type: "knowledge",
628
- projectionPlans,
629
- runTransaction: ws.runTransaction,
630
- refreshCatalog: () => ws.runTransaction({
631
- transition: applyKnowledgeProjection,
632
- validate: () => Effect.void,
633
- }),
634
- sync: ({ dryRun }) => dryRun
635
- ? Effect.scoped(syncLocked(true))
636
- : Effect.scoped(ws.runTransaction({
637
- transition: syncLocked(false),
638
- validate: () => Effect.void,
639
- })),
640
- install: installAtomically,
641
- isInstalled: ({ target }) => isObservedInstalled(ws, "knowledge", target.name),
642
- materializeInstall: Effect.fn("KnowledgeManager.materializeInstall")(function* ({ ref, force }) {
643
- const relativeLocalSource = ref.refType === "local"
644
- ? makeWorkspaceRelativeSourcePath(path, baseDir, ref.sourcePath ?? stripFileProtocol(ref.location))
645
- : Option.none();
646
- if (ref.refType === "local" && Option.isNone(relativeLocalSource)) {
647
- return yield* new KnowledgeDefinitionInvalid({
648
- detail: `Local knowledge source must stay within the workspace: ${ref.source.path}`,
649
- });
650
- }
651
- const prepared = yield* preparePackage(ref, force === true);
652
- yield* prepared.commit;
653
- lastInstallState.set(ref.knowledge.name, {
654
- relativeLocalSource,
655
- sourceHash: prepared.sourceHash,
656
- ...(prepared.treeIntegrity === undefined
657
- ? {}
658
- : { treeIntegrity: prepared.treeIntegrity }),
659
- });
660
- }, Effect.asVoid, Effect.scoped),
661
- prepareSourceTransition: ({ ref }) => provide(prepareAcceptedCanonicalTransition({
662
- workspace: ws,
663
- type: "knowledge",
664
- name: ref.knowledge.name,
665
- ref,
666
- })),
667
- getConfiguredSource: ({ target }) => ws
668
- .getConfiguredKnowledgeEntries()
669
- .pipe(Effect.map((entries) => Option.fromUndefinedOr(entries[target.name]?.source))),
670
- /**
671
- * Every enabled entry's accepted canonical package, read from accepted
672
- * resolution rather than re-resolved from source. Materialization
673
- * realizes what the workspace already accepted; going back to the
674
- * source would put an unrelated configured entry's release age between
675
- * an operator and the extension they are authoring.
676
- */
677
- listMaterializable: () => Effect.gen(function* () {
678
- const nodes = yield* activeKnowledgeNodes();
679
- const refs = yield* Effect.forEach(nodes, (node) => provide(usableAcceptedCanonicalRef({
680
- workspace: ws,
681
- type: "knowledge",
682
- name: node.name,
683
- }).pipe(Effect.map(Option.filter((ref) => ref.type === "knowledge")))), { concurrency: "unbounded" });
684
- return refs.flatMap((ref) => (Option.isSome(ref) ? [ref.value] : []));
685
- }),
686
- materializeUninstall,
687
- materializeDeactivate,
688
- upsertSettingsEntry: ({ ref, versionRange }) => buildLockEntry(ref).pipe(Effect.flatMap((lockEntry) => Option.isSome(lockEntry)
689
- ? ws.setKnowledge({
690
- name: ref.knowledge.name,
691
- lockEntry: lockEntry.value,
692
- versionRange,
693
- })
694
- : setKnowledgeSourceEntry(ref.knowledge.name, "workspace"))),
695
- removeSettingsEntry: ({ target }) => ws.removeKnowledgeSettings(target.name),
696
- upsertLockfileEntry: ({ ref }) => buildLockEntry(ref).pipe(Effect.flatMap((lockEntry) => {
697
- if (Option.isNone(lockEntry))
698
- return ws.removeKnowledgeLock(ref.knowledge.name);
699
- const validate = lockEntry.value.type === "registry"
700
- ? validateExactResolvedVersion(`knowledge.${ref.knowledge.name}.resolvedVersion`, lockEntry.value.resolvedVersion)
701
- : Effect.void;
702
- return validate.pipe(Effect.flatMap(() => ws.setKnowledgeLock({
703
- name: ref.knowledge.name,
704
- lockEntry: lockEntry.value,
705
- versionRange: Option.none(),
706
- })));
707
- })),
708
- removeLockfileEntry: ({ target }) => ws.removeKnowledgeLock(target.name),
709
- };
710
- }));
711
- //# sourceMappingURL=manager.js.map