@agentxm/workspace-state 0.28.4-bootstrap.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +110 -0
- package/README.md +11 -0
- package/dist/src/index.d.ts +72 -0
- package/dist/src/index.js +88 -0
- package/dist/src/knowledge/discovery-config.d.ts +12 -0
- package/dist/src/knowledge/discovery-config.js +9 -0
- package/dist/src/lockfile/accepted-registry-version.d.ts +12 -0
- package/dist/src/lockfile/accepted-registry-version.js +13 -0
- package/dist/src/lockfile/entry-fields.d.ts +189 -0
- package/dist/src/lockfile/entry-fields.js +89 -0
- package/dist/src/lockfile/errors.d.ts +48 -0
- package/dist/src/lockfile/errors.js +27 -0
- package/dist/src/lockfile/index.d.ts +18 -0
- package/dist/src/lockfile/index.js +16 -0
- package/dist/src/lockfile/lockfile.d.ts +2255 -0
- package/dist/src/lockfile/lockfile.js +235 -0
- package/dist/src/lockfile/resolved-version.d.ts +4 -0
- package/dist/src/lockfile/resolved-version.js +7 -0
- package/dist/src/lockfile/schema.d.ts +3062 -0
- package/dist/src/lockfile/schema.js +406 -0
- package/dist/src/schema/index.d.ts +3 -0
- package/dist/src/schema/index.js +2 -0
- package/dist/src/schema/read-and-validate-json-file.d.ts +20 -0
- package/dist/src/schema/read-and-validate-json-file.js +85 -0
- package/dist/src/schema/types.d.ts +26 -0
- package/dist/src/schema/types.js +2 -0
- package/dist/src/settings/errors.d.ts +22 -0
- package/dist/src/settings/errors.js +15 -0
- package/dist/src/settings/format-preserving-json.d.ts +40 -0
- package/dist/src/settings/format-preserving-json.js +80 -0
- package/dist/src/settings/index.d.ts +15 -0
- package/dist/src/settings/index.js +14 -0
- package/dist/src/settings/schema.d.ts +687 -0
- package/dist/src/settings/schema.js +977 -0
- package/dist/src/settings/settings.d.ts +38 -0
- package/dist/src/settings/settings.js +213 -0
- package/dist/src/testing.d.ts +17 -0
- package/dist/src/testing.js +17 -0
- package/dist/src/utils/atomic-write.d.ts +67 -0
- package/dist/src/utils/atomic-write.js +71 -0
- package/dist/src/utils/environment.d.ts +16 -0
- package/dist/src/utils/environment.js +19 -0
- package/dist/src/utils/path-safety.d.ts +25 -0
- package/dist/src/utils/path-safety.js +34 -0
- package/dist/src/utils/resolve-parent-symlinks.d.ts +16 -0
- package/dist/src/utils/resolve-parent-symlinks.js +36 -0
- package/dist/src/workspace/accepted-canonical-ref.d.ts +58 -0
- package/dist/src/workspace/accepted-canonical-ref.js +229 -0
- package/dist/src/workspace/artifact-change.d.ts +14 -0
- package/dist/src/workspace/artifact-change.js +18 -0
- package/dist/src/workspace/canonical-observation.d.ts +39 -0
- package/dist/src/workspace/canonical-observation.js +307 -0
- package/dist/src/workspace/configured-agent-outcome.d.ts +22 -0
- package/dist/src/workspace/configured-agent-outcome.js +33 -0
- package/dist/src/workspace/configured-agent-outcomes-provider.d.ts +50 -0
- package/dist/src/workspace/configured-agent-outcomes-provider.js +26 -0
- package/dist/src/workspace/configured-agent-outcomes.d.ts +48 -0
- package/dist/src/workspace/configured-agent-outcomes.js +113 -0
- package/dist/src/workspace/configured-entry-resolution/types.d.ts +32 -0
- package/dist/src/workspace/configured-entry-resolution/types.js +2 -0
- package/dist/src/workspace/configured-entry-resolution/workspace-ref.d.ts +32 -0
- package/dist/src/workspace/configured-entry-resolution/workspace-ref.js +176 -0
- package/dist/src/workspace/constants.d.ts +6 -0
- package/dist/src/workspace/constants.js +6 -0
- package/dist/src/workspace/create-symlink.d.ts +26 -0
- package/dist/src/workspace/create-symlink.js +87 -0
- package/dist/src/workspace/desired-pack-lock.d.ts +18 -0
- package/dist/src/workspace/desired-pack-lock.js +132 -0
- package/dist/src/workspace/desired-state-enabled.d.ts +18 -0
- package/dist/src/workspace/desired-state-enabled.js +16 -0
- package/dist/src/workspace/desired-state-graph.d.ts +114 -0
- package/dist/src/workspace/desired-state-graph.js +384 -0
- package/dist/src/workspace/desired-state-problem-text.d.ts +6 -0
- package/dist/src/workspace/desired-state-problem-text.js +27 -0
- package/dist/src/workspace/errors.d.ts +184 -0
- package/dist/src/workspace/errors.js +79 -0
- package/dist/src/workspace/extension-name.d.ts +28 -0
- package/dist/src/workspace/extension-name.js +66 -0
- package/dist/src/workspace/extension-paths.d.ts +82 -0
- package/dist/src/workspace/extension-paths.js +172 -0
- package/dist/src/workspace/footprint-recorder.d.ts +30 -0
- package/dist/src/workspace/footprint-recorder.js +32 -0
- package/dist/src/workspace/layout.d.ts +43 -0
- package/dist/src/workspace/layout.js +164 -0
- package/dist/src/workspace/lock-entry-to-ref.d.ts +40 -0
- package/dist/src/workspace/lock-entry-to-ref.js +433 -0
- package/dist/src/workspace/lock-entry-to-source-params.d.ts +26 -0
- package/dist/src/workspace/lock-entry-to-source-params.js +81 -0
- package/dist/src/workspace/locked-entries.d.ts +30 -0
- package/dist/src/workspace/locked-entries.js +34 -0
- package/dist/src/workspace/materialized-file-target.d.ts +14 -0
- package/dist/src/workspace/materialized-file-target.js +14 -0
- package/dist/src/workspace/materialized-tree.d.ts +23 -0
- package/dist/src/workspace/materialized-tree.js +90 -0
- package/dist/src/workspace/mcp-entry-semantics.d.ts +31 -0
- package/dist/src/workspace/mcp-entry-semantics.js +60 -0
- package/dist/src/workspace/observed-installed.d.ts +9 -0
- package/dist/src/workspace/observed-installed.js +9 -0
- package/dist/src/workspace/pack-manifest-content-identity.d.ts +12 -0
- package/dist/src/workspace/pack-manifest-content-identity.js +20 -0
- package/dist/src/workspace/pack-paths.d.ts +24 -0
- package/dist/src/workspace/pack-paths.js +16 -0
- package/dist/src/workspace/package-hash.d.ts +25 -0
- package/dist/src/workspace/package-hash.js +45 -0
- package/dist/src/workspace/paths.d.ts +24 -0
- package/dist/src/workspace/paths.js +52 -0
- package/dist/src/workspace/read-model/__fixtures__/builder.d.ts +199 -0
- package/dist/src/workspace/read-model/__fixtures__/builder.js +588 -0
- package/dist/src/workspace/read-model/__fixtures__/decoders.d.ts +15 -0
- package/dist/src/workspace/read-model/__fixtures__/decoders.js +15 -0
- package/dist/src/workspace/read-model/__fixtures__/occurrences.d.ts +72 -0
- package/dist/src/workspace/read-model/__fixtures__/occurrences.js +134 -0
- package/dist/src/workspace/read-model/__fixtures__/scenario-harness.d.ts +99 -0
- package/dist/src/workspace/read-model/__fixtures__/scenario-harness.js +142 -0
- package/dist/src/workspace/read-model/__fixtures__/test-layer.d.ts +60 -0
- package/dist/src/workspace/read-model/__fixtures__/test-layer.js +57 -0
- package/dist/src/workspace/read-model/agent-presence.d.ts +32 -0
- package/dist/src/workspace/read-model/agent-presence.js +21 -0
- package/dist/src/workspace/read-model/agent-root-resolver.d.ts +38 -0
- package/dist/src/workspace/read-model/agent-root-resolver.js +35 -0
- package/dist/src/workspace/read-model/agents/index.d.ts +38 -0
- package/dist/src/workspace/read-model/agents/index.js +45 -0
- package/dist/src/workspace/read-model/agents/shared.d.ts +27 -0
- package/dist/src/workspace/read-model/agents/shared.js +63 -0
- package/dist/src/workspace/read-model/agents/types.d.ts +133 -0
- package/dist/src/workspace/read-model/agents/types.js +51 -0
- package/dist/src/workspace/read-model/diagnostics.d.ts +18 -0
- package/dist/src/workspace/read-model/diagnostics.js +14 -0
- package/dist/src/workspace/read-model/discovery/index.d.ts +5 -0
- package/dist/src/workspace/read-model/discovery/index.js +5 -0
- package/dist/src/workspace/read-model/discovery/plugin-manifests.d.ts +16 -0
- package/dist/src/workspace/read-model/discovery/plugin-manifests.js +168 -0
- package/dist/src/workspace/read-model/discovery/skills.d.ts +58 -0
- package/dist/src/workspace/read-model/discovery/skills.js +263 -0
- package/dist/src/workspace/read-model/discovery/subagents.d.ts +37 -0
- package/dist/src/workspace/read-model/discovery/subagents.js +48 -0
- package/dist/src/workspace/read-model/errors.d.ts +93 -0
- package/dist/src/workspace/read-model/errors.js +30 -0
- package/dist/src/workspace/read-model/extensions/actual-helpers.d.ts +4 -0
- package/dist/src/workspace/read-model/extensions/actual-helpers.js +4 -0
- package/dist/src/workspace/read-model/extensions/hook.d.ts +104 -0
- package/dist/src/workspace/read-model/extensions/hook.js +119 -0
- package/dist/src/workspace/read-model/extensions/index.d.ts +19 -0
- package/dist/src/workspace/read-model/extensions/index.js +43 -0
- package/dist/src/workspace/read-model/extensions/indexByName.d.ts +31 -0
- package/dist/src/workspace/read-model/extensions/indexByName.js +30 -0
- package/dist/src/workspace/read-model/extensions/inventory.d.ts +99 -0
- package/dist/src/workspace/read-model/extensions/inventory.js +111 -0
- package/dist/src/workspace/read-model/extensions/knowledge.d.ts +101 -0
- package/dist/src/workspace/read-model/extensions/knowledge.js +121 -0
- package/dist/src/workspace/read-model/extensions/mcp-server.d.ts +106 -0
- package/dist/src/workspace/read-model/extensions/mcp-server.js +122 -0
- package/dist/src/workspace/read-model/extensions/pack.d.ts +104 -0
- package/dist/src/workspace/read-model/extensions/pack.js +123 -0
- package/dist/src/workspace/read-model/extensions/package-root.d.ts +39 -0
- package/dist/src/workspace/read-model/extensions/package-root.js +48 -0
- package/dist/src/workspace/read-model/extensions/projection.d.ts +137 -0
- package/dist/src/workspace/read-model/extensions/projection.js +180 -0
- package/dist/src/workspace/read-model/extensions/rule.d.ts +104 -0
- package/dist/src/workspace/read-model/extensions/rule.js +113 -0
- package/dist/src/workspace/read-model/extensions/skill.d.ts +170 -0
- package/dist/src/workspace/read-model/extensions/skill.js +148 -0
- package/dist/src/workspace/read-model/extensions/subagent.d.ts +97 -0
- package/dist/src/workspace/read-model/extensions/subagent.js +120 -0
- package/dist/src/workspace/read-model/scanners/agent-dir.d.ts +49 -0
- package/dist/src/workspace/read-model/scanners/agent-dir.js +180 -0
- package/dist/src/workspace/read-model/scanners/agent-root.d.ts +73 -0
- package/dist/src/workspace/read-model/scanners/agent-root.js +148 -0
- package/dist/src/workspace/read-model/scanners/agent-settings.d.ts +43 -0
- package/dist/src/workspace/read-model/scanners/agent-settings.js +54 -0
- package/dist/src/workspace/read-model/scanners/canonical-extensions.d.ts +48 -0
- package/dist/src/workspace/read-model/scanners/canonical-extensions.js +237 -0
- package/dist/src/workspace/read-model/scanners/fs-helpers.d.ts +63 -0
- package/dist/src/workspace/read-model/scanners/fs-helpers.js +106 -0
- package/dist/src/workspace/read-model/scanners/index.d.ts +15 -0
- package/dist/src/workspace/read-model/scanners/index.js +34 -0
- package/dist/src/workspace/read-model/scanners/mcp-config.d.ts +47 -0
- package/dist/src/workspace/read-model/scanners/mcp-config.js +212 -0
- package/dist/src/workspace/read-model/scanners/types.d.ts +170 -0
- package/dist/src/workspace/read-model/scanners/types.js +86 -0
- package/dist/src/workspace/read-model/service.d.ts +103 -0
- package/dist/src/workspace/read-model/service.js +391 -0
- package/dist/src/workspace/read-model/state.d.ts +35 -0
- package/dist/src/workspace/read-model/state.js +97 -0
- package/dist/src/workspace/read-model/types.d.ts +75 -0
- package/dist/src/workspace/read-model/types.js +26 -0
- package/dist/src/workspace/read-model-record-readers.d.ts +34 -0
- package/dist/src/workspace/read-model-record-readers.js +467 -0
- package/dist/src/workspace/read-model-record-rows.d.ts +45 -0
- package/dist/src/workspace/read-model-record-rows.js +33 -0
- package/dist/src/workspace/read-model-record-types.d.ts +45 -0
- package/dist/src/workspace/read-model-record-types.js +13 -0
- package/dist/src/workspace/remove-if-exists.d.ts +13 -0
- package/dist/src/workspace/remove-if-exists.js +26 -0
- package/dist/src/workspace/rendered-files.d.ts +53 -0
- package/dist/src/workspace/rendered-files.js +50 -0
- package/dist/src/workspace/scope-refusal.d.ts +26 -0
- package/dist/src/workspace/scope-refusal.js +29 -0
- package/dist/src/workspace/service-interface.d.ts +479 -0
- package/dist/src/workspace/service-interface.js +27 -0
- package/dist/src/workspace/service.d.ts +1665 -0
- package/dist/src/workspace/service.js +1263 -0
- package/dist/src/workspace/setup-scope-support.d.ts +27 -0
- package/dist/src/workspace/setup-scope-support.js +299 -0
- package/dist/src/workspace/skill-paths.d.ts +33 -0
- package/dist/src/workspace/skill-paths.js +14 -0
- package/dist/src/workspace/source-metadata.d.ts +7 -0
- package/dist/src/workspace/source-metadata.js +10 -0
- package/dist/src/workspace/source-to-lock-entry.d.ts +32 -0
- package/dist/src/workspace/source-to-lock-entry.js +68 -0
- package/dist/src/workspace/test-stubs.d.ts +144 -0
- package/dist/src/workspace/test-stubs.js +412 -0
- package/dist/src/workspace/transaction.d.ts +218 -0
- package/dist/src/workspace/transaction.js +177 -0
- package/package.json +57 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared projection helper: composes installed/active/unmanaged from
|
|
3
|
+
* declared/resolved/actual plus the installed-pack set.
|
|
4
|
+
*
|
|
5
|
+
* Per the projection invariant in the workspace read-model design (Decision 7):
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* direct = declared.map(withInstallationOrigin("direct"));
|
|
9
|
+
* implicit = installedPacks
|
|
10
|
+
* .flatMap(p => p.members)
|
|
11
|
+
* .filter(notDeclaredByName) // direct (incl. disabled) wins
|
|
12
|
+
* .map(withInstallationOrigin("pack-member"));
|
|
13
|
+
* installed = direct + implicit;
|
|
14
|
+
* active = installed.filter(activation === "enabled");
|
|
15
|
+
* unmanaged = actual
|
|
16
|
+
* .filter(notClaimedByInstalled)
|
|
17
|
+
* .filter(notClaimedBySubjectPolicy);
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* The helper owns:
|
|
21
|
+
* - direct-over-pack precedence;
|
|
22
|
+
* - disabled-direct still claims actual occurrences (excluded from active and
|
|
23
|
+
* from unmanaged);
|
|
24
|
+
* - actual-occurrence attachment via `policy.attachActualToInstalled`;
|
|
25
|
+
* - orphaned-resolved diagnostics — resolved entries with no direct or
|
|
26
|
+
* pack-member home publish a warning;
|
|
27
|
+
* - deterministic name-sorted ordering.
|
|
28
|
+
*
|
|
29
|
+
* The helper does NOT own subject row shape or subject policy. Both come in as
|
|
30
|
+
* parameters via `SubjectPolicy<...>`.
|
|
31
|
+
*/
|
|
32
|
+
import * as Effect from "effect/Effect";
|
|
33
|
+
import * as Option from "effect/Option";
|
|
34
|
+
import type { Diagnostics, Warning } from "../diagnostics.js";
|
|
35
|
+
import type { LockfileReadError, SettingsReadError } from "../errors.js";
|
|
36
|
+
import type { ActivationState, InstallationOrigin, InstalledPackRef } from "../types.js";
|
|
37
|
+
import { type RowWithKey } from "./indexByName.js";
|
|
38
|
+
/**
|
|
39
|
+
* One entry within a subject's `declared` payload. The shape is opaque to the
|
|
40
|
+
* helper; the policy callbacks bridge to subject internals.
|
|
41
|
+
*/
|
|
42
|
+
export type TDeclaredEntry<TDeclared> = TDeclared extends ReadonlyArray<infer E> ? E : TDeclared;
|
|
43
|
+
/** One entry within a subject's `resolved` payload. */
|
|
44
|
+
export type TResolvedEntry<TResolved> = TResolved extends ReadonlyArray<infer E> ? E : TResolved;
|
|
45
|
+
/** One actual occurrence within a subject's `actual` payload. */
|
|
46
|
+
export type TActualEntry<TActual> = TActual extends ReadonlyArray<infer E> ? E : TActual;
|
|
47
|
+
/**
|
|
48
|
+
* Subject-specific policy callbacks the projection helper requires.
|
|
49
|
+
*/
|
|
50
|
+
export interface SubjectPolicy<TDeclared, TResolved, TActual, TPackMember, TInstalled, TUnmanaged> {
|
|
51
|
+
/** Iterate the subject's declared entries from a decoded `declared` payload. */
|
|
52
|
+
readonly declaredEntries: (declared: TDeclared) => ReadonlyArray<TDeclaredEntry<TDeclared>>;
|
|
53
|
+
/** Extract the subject name from a declared entry. */
|
|
54
|
+
readonly declaredName: (entry: TDeclaredEntry<TDeclared>) => string;
|
|
55
|
+
/**
|
|
56
|
+
* Activation state derived from a declared entry.
|
|
57
|
+
*/
|
|
58
|
+
readonly declaredActivation: (entry: TDeclaredEntry<TDeclared>) => ActivationState;
|
|
59
|
+
/** Iterate the subject's resolved entries from a decoded `resolved` payload. */
|
|
60
|
+
readonly resolvedEntries: (resolved: TResolved) => ReadonlyArray<TResolvedEntry<TResolved>>;
|
|
61
|
+
/** Extract the subject name from a resolved entry. */
|
|
62
|
+
readonly resolvedName: (entry: TResolvedEntry<TResolved>) => string;
|
|
63
|
+
/** Iterate the subject's actual occurrences from an `actual` payload. */
|
|
64
|
+
readonly actualEntries: (actual: TActual) => ReadonlyArray<TActualEntry<TActual>>;
|
|
65
|
+
/** Extract the subject name from an actual occurrence. */
|
|
66
|
+
readonly actualName: (entry: TActualEntry<TActual>) => string;
|
|
67
|
+
/** Extract the subject name from a pack-member entry. */
|
|
68
|
+
readonly packMemberName: (member: TPackMember) => string;
|
|
69
|
+
/** Activation state for a pack-member installed row. */
|
|
70
|
+
readonly packMemberActivation: (member: TPackMember) => ActivationState;
|
|
71
|
+
/** Filter actual occurrences to those that match a given installed name. */
|
|
72
|
+
readonly attachActualToInstalled: (name: string, actual: ReadonlyArray<TActualEntry<TActual>>) => ReadonlyArray<TActualEntry<TActual>>;
|
|
73
|
+
/**
|
|
74
|
+
* Subject-policy filter for unmanaged actual occurrences. Returns `true` if
|
|
75
|
+
* the occurrence is NOT claimed by subject-specific policy.
|
|
76
|
+
*/
|
|
77
|
+
readonly notClaimedBySubjectPolicy: (entry: TActualEntry<TActual>) => boolean;
|
|
78
|
+
/** Build a subject installed row from the assembled facts. */
|
|
79
|
+
readonly buildInstalledRow: (input: BuildInstalledRowInput<TDeclared, TResolved, TActual, TPackMember>) => TInstalled;
|
|
80
|
+
/** Build a subject unmanaged row from one actual occurrence. */
|
|
81
|
+
readonly buildUnmanagedRow: (entry: TActualEntry<TActual>) => TUnmanaged;
|
|
82
|
+
/** Build the orphan-resolved warning published when a resolved entry has no home. */
|
|
83
|
+
readonly resolvedOrphanWarning: (name: string) => Warning;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Input passed to `buildInstalledRow`. Carries everything the subject needs
|
|
87
|
+
* to construct its installed row.
|
|
88
|
+
*/
|
|
89
|
+
export interface BuildInstalledRowInput<TDeclared, TResolved, TActual, TPackMember> {
|
|
90
|
+
readonly name: string;
|
|
91
|
+
readonly installationOrigin: InstallationOrigin<TDeclaredEntry<TDeclared>, TPackMember>;
|
|
92
|
+
readonly activation: ActivationState;
|
|
93
|
+
readonly resolved: Option.Option<TResolvedEntry<TResolved>>;
|
|
94
|
+
readonly actual: ReadonlyArray<TActualEntry<TActual>>;
|
|
95
|
+
readonly providingPacks: ReadonlyArray<InstalledPackRef>;
|
|
96
|
+
}
|
|
97
|
+
export interface ProjectInstalledExtensionsInput<TDeclared, TResolved, TActual, TPack, TPackMember, TInstalled, TUnmanaged> {
|
|
98
|
+
readonly declared: Effect.Effect<Option.Option<TDeclared>, SettingsReadError>;
|
|
99
|
+
readonly resolved: Effect.Effect<Option.Option<TResolved>, LockfileReadError>;
|
|
100
|
+
readonly actual: Effect.Effect<TActual>;
|
|
101
|
+
readonly installedPacks: Effect.Effect<ReadonlyArray<TPack>, SettingsReadError | LockfileReadError>;
|
|
102
|
+
readonly packMembers: (pack: TPack) => ReadonlyArray<TPackMember>;
|
|
103
|
+
readonly packRef: (pack: TPack) => InstalledPackRef;
|
|
104
|
+
readonly policy: SubjectPolicy<TDeclared, TResolved, TActual, TPackMember, TInstalled, TUnmanaged>;
|
|
105
|
+
readonly diagnostics: Diagnostics;
|
|
106
|
+
}
|
|
107
|
+
export interface ProjectInstalledExtensionsOutput<TInstalled, TUnmanaged> {
|
|
108
|
+
readonly installed: ReadonlyArray<TInstalled>;
|
|
109
|
+
readonly active: ReadonlyArray<TInstalled>;
|
|
110
|
+
readonly unmanaged: ReadonlyArray<TUnmanaged>;
|
|
111
|
+
}
|
|
112
|
+
export declare const makeProjectedSubjectCells: <TDeclaredEntry extends {
|
|
113
|
+
readonly name: string;
|
|
114
|
+
}, TDeclared extends ReadonlyArray<TDeclaredEntry>, TResolved, TActual, TInstalled extends RowWithKey, TUnmanaged>(args: {
|
|
115
|
+
readonly declared: Effect.Effect<Option.Option<TDeclared>, SettingsReadError>;
|
|
116
|
+
readonly resolved: Effect.Effect<Option.Option<TResolved>, LockfileReadError>;
|
|
117
|
+
readonly actual: Effect.Effect<TActual>;
|
|
118
|
+
readonly project: Effect.Effect<ProjectInstalledExtensionsOutput<TInstalled, TUnmanaged>, SettingsReadError | LockfileReadError>;
|
|
119
|
+
}) => {
|
|
120
|
+
declared: Effect.Effect<Option.Option<TDeclared>, SettingsReadError, never>;
|
|
121
|
+
resolved: Effect.Effect<Option.Option<TResolved>, LockfileReadError, never>;
|
|
122
|
+
actual: Effect.Effect<TActual, never, never>;
|
|
123
|
+
installed: Effect.Effect<readonly TInstalled[], SettingsReadError | LockfileReadError, never>;
|
|
124
|
+
byName: (name: string) => Effect.Effect<Option.Option<TInstalled>, SettingsReadError | LockfileReadError, never>;
|
|
125
|
+
declaredByName: (name: string) => Effect.Effect<Option.Option<Exclude<TDeclaredEntry, undefined>>, SettingsReadError, never>;
|
|
126
|
+
active: Effect.Effect<readonly TInstalled[], SettingsReadError | LockfileReadError, never>;
|
|
127
|
+
unmanaged: Effect.Effect<readonly TUnmanaged[], SettingsReadError | LockfileReadError, never>;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Compose installed, active, and unmanaged rows from declared/resolved/actual
|
|
131
|
+
* plus the installed-pack set, per the projection invariant.
|
|
132
|
+
*
|
|
133
|
+
* Source-read failures propagate so invalid persisted authority is never
|
|
134
|
+
* treated as absent.
|
|
135
|
+
*/
|
|
136
|
+
export declare const projectInstalledExtensions: <TDeclared, TResolved, TActual, TPack, TPackMember, TInstalled, TUnmanaged>(input: ProjectInstalledExtensionsInput<TDeclared, TResolved, TActual, TPack, TPackMember, TInstalled, TUnmanaged>) => Effect.Effect<ProjectInstalledExtensionsOutput<TInstalled, TUnmanaged>, SettingsReadError | LockfileReadError>;
|
|
137
|
+
//# sourceMappingURL=projection.d.ts.map
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared projection helper: composes installed/active/unmanaged from
|
|
3
|
+
* declared/resolved/actual plus the installed-pack set.
|
|
4
|
+
*
|
|
5
|
+
* Per the projection invariant in the workspace read-model design (Decision 7):
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* direct = declared.map(withInstallationOrigin("direct"));
|
|
9
|
+
* implicit = installedPacks
|
|
10
|
+
* .flatMap(p => p.members)
|
|
11
|
+
* .filter(notDeclaredByName) // direct (incl. disabled) wins
|
|
12
|
+
* .map(withInstallationOrigin("pack-member"));
|
|
13
|
+
* installed = direct + implicit;
|
|
14
|
+
* active = installed.filter(activation === "enabled");
|
|
15
|
+
* unmanaged = actual
|
|
16
|
+
* .filter(notClaimedByInstalled)
|
|
17
|
+
* .filter(notClaimedBySubjectPolicy);
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* The helper owns:
|
|
21
|
+
* - direct-over-pack precedence;
|
|
22
|
+
* - disabled-direct still claims actual occurrences (excluded from active and
|
|
23
|
+
* from unmanaged);
|
|
24
|
+
* - actual-occurrence attachment via `policy.attachActualToInstalled`;
|
|
25
|
+
* - orphaned-resolved diagnostics — resolved entries with no direct or
|
|
26
|
+
* pack-member home publish a warning;
|
|
27
|
+
* - deterministic name-sorted ordering.
|
|
28
|
+
*
|
|
29
|
+
* The helper does NOT own subject row shape or subject policy. Both come in as
|
|
30
|
+
* parameters via `SubjectPolicy<...>`.
|
|
31
|
+
*/
|
|
32
|
+
import * as Array from "effect/Array";
|
|
33
|
+
import * as Effect from "effect/Effect";
|
|
34
|
+
import * as Option from "effect/Option";
|
|
35
|
+
import { findByName } from "./indexByName.js";
|
|
36
|
+
export const makeProjectedSubjectCells = (args) => ({
|
|
37
|
+
declared: args.declared,
|
|
38
|
+
resolved: args.resolved,
|
|
39
|
+
actual: args.actual,
|
|
40
|
+
installed: args.project.pipe(Effect.map((out) => out.installed)),
|
|
41
|
+
byName: (name) => args.project.pipe(Effect.map((out) => findByName(out.installed, name))),
|
|
42
|
+
declaredByName: (name) => args.declared.pipe(Effect.map((opt) => Option.flatMap(opt, (rows) => Option.fromUndefinedOr(rows.find((row) => row.name === name))))),
|
|
43
|
+
active: args.project.pipe(Effect.map((out) => out.active)),
|
|
44
|
+
unmanaged: args.project.pipe(Effect.map((out) => out.unmanaged)),
|
|
45
|
+
});
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Public helper
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
/**
|
|
50
|
+
* Compose installed, active, and unmanaged rows from declared/resolved/actual
|
|
51
|
+
* plus the installed-pack set, per the projection invariant.
|
|
52
|
+
*
|
|
53
|
+
* Source-read failures propagate so invalid persisted authority is never
|
|
54
|
+
* treated as absent.
|
|
55
|
+
*/
|
|
56
|
+
export const projectInstalledExtensions = (input) => Effect.gen(function* () {
|
|
57
|
+
const { declared, resolved, actual, installedPacks, packMembers, packRef, policy, diagnostics, } = input;
|
|
58
|
+
// 1. Read the three layers + installed packs. Invalid persisted authority
|
|
59
|
+
// fails the projection instead of being treated as absent.
|
|
60
|
+
const declaredOpt = yield* declared;
|
|
61
|
+
const resolvedOpt = yield* resolved;
|
|
62
|
+
const actualPayload = yield* actual;
|
|
63
|
+
const packs = yield* installedPacks;
|
|
64
|
+
// 2. Iterate raw evidence into per-name lookups using first-wins
|
|
65
|
+
// deduplication. `dedupeFirstByName` builds an immutable Map keyed by
|
|
66
|
+
// the policy-derived name; subsequent entries with the same name are
|
|
67
|
+
// dropped, so the projection stays deterministic.
|
|
68
|
+
const emptyDeclared = [];
|
|
69
|
+
const emptyResolved = [];
|
|
70
|
+
const declaredEntries = Option.match(declaredOpt, {
|
|
71
|
+
onNone: () => emptyDeclared,
|
|
72
|
+
onSome: (d) => policy.declaredEntries(d),
|
|
73
|
+
});
|
|
74
|
+
const resolvedEntries = Option.match(resolvedOpt, {
|
|
75
|
+
onNone: () => emptyResolved,
|
|
76
|
+
onSome: (r) => policy.resolvedEntries(r),
|
|
77
|
+
});
|
|
78
|
+
const actualEntries = policy.actualEntries(actualPayload);
|
|
79
|
+
const declaredByName = dedupeFirstByName(declaredEntries, policy.declaredName);
|
|
80
|
+
const resolvedByName = dedupeFirstByName(resolvedEntries, policy.resolvedName);
|
|
81
|
+
const packMemberPairs = packs.flatMap((pack) => {
|
|
82
|
+
const ref = packRef(pack);
|
|
83
|
+
return packMembers(pack).map((member) => [member, ref]);
|
|
84
|
+
});
|
|
85
|
+
const memberByName = packMemberPairs.reduce((acc, [member, ref]) => {
|
|
86
|
+
const name = policy.packMemberName(member);
|
|
87
|
+
const existing = acc.get(name);
|
|
88
|
+
const next = new Map(acc);
|
|
89
|
+
if (existing === undefined) {
|
|
90
|
+
next.set(name, { member, pack: ref, providingPacks: [ref] });
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
next.set(name, {
|
|
94
|
+
member: existing.member,
|
|
95
|
+
pack: existing.pack,
|
|
96
|
+
providingPacks: [...existing.providingPacks, ref],
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return next;
|
|
100
|
+
}, new Map());
|
|
101
|
+
const direct = Array.getSomes(Array.fromIterable(declaredByName.entries()).map(([name, entry]) => {
|
|
102
|
+
const activation = policy.declaredActivation(entry);
|
|
103
|
+
const memberState = memberByName.get(name);
|
|
104
|
+
const providingPacks = memberState === undefined ? [] : memberState.providingPacks;
|
|
105
|
+
const attached = policy.attachActualToInstalled(name, actualEntries);
|
|
106
|
+
const row = policy.buildInstalledRow({
|
|
107
|
+
name,
|
|
108
|
+
installationOrigin: { _tag: "direct", declared: entry },
|
|
109
|
+
activation,
|
|
110
|
+
resolved: Option.fromUndefinedOr(resolvedByName.get(name)),
|
|
111
|
+
actual: attached,
|
|
112
|
+
providingPacks,
|
|
113
|
+
});
|
|
114
|
+
return Option.some({ name, row, activation });
|
|
115
|
+
}));
|
|
116
|
+
// 5. Implicit pack-member rows: skip names already declared (direct wins,
|
|
117
|
+
// including disabled).
|
|
118
|
+
const implicit = Array.getSomes(Array.fromIterable(memberByName.entries()).map(([name, state]) => {
|
|
119
|
+
if (declaredByName.has(name))
|
|
120
|
+
return Option.none(); // direct wins
|
|
121
|
+
const activation = policy.packMemberActivation(state.member);
|
|
122
|
+
const attached = policy.attachActualToInstalled(name, actualEntries);
|
|
123
|
+
const row = policy.buildInstalledRow({
|
|
124
|
+
name,
|
|
125
|
+
installationOrigin: {
|
|
126
|
+
_tag: "pack-member",
|
|
127
|
+
member: state.member,
|
|
128
|
+
pack: state.pack,
|
|
129
|
+
},
|
|
130
|
+
activation,
|
|
131
|
+
resolved: Option.fromUndefinedOr(resolvedByName.get(name)),
|
|
132
|
+
actual: attached,
|
|
133
|
+
providingPacks: state.providingPacks,
|
|
134
|
+
});
|
|
135
|
+
return Option.some({ name, row, activation });
|
|
136
|
+
}));
|
|
137
|
+
// 6. Sort by name for deterministic ordering.
|
|
138
|
+
const installedNamed = [...direct, ...implicit].sort((a, b) => a.name.localeCompare(b.name));
|
|
139
|
+
const installedNames = new Set(installedNamed.map((r) => r.name));
|
|
140
|
+
const installed = installedNamed.map((r) => r.row);
|
|
141
|
+
const active = installedNamed
|
|
142
|
+
.filter((r) => r.activation === "enabled")
|
|
143
|
+
.map((r) => r.row);
|
|
144
|
+
// 7. Orphaned-resolved diagnostics: any resolved entry whose name is
|
|
145
|
+
// neither declared nor present as a pack-member. Collect orphan names
|
|
146
|
+
// first, then publish sequentially via Effect.forEach to keep the
|
|
147
|
+
// diagnostics buffer in deterministic order.
|
|
148
|
+
const orphanNames = Array.fromIterable(resolvedByName.keys()).filter((name) => !declaredByName.has(name) && !memberByName.has(name));
|
|
149
|
+
yield* Effect.forEach(orphanNames, (name) => diagnostics.append(policy.resolvedOrphanWarning(name)), { discard: true });
|
|
150
|
+
// 8. Unmanaged: actual occurrences not claimed by an installed row and
|
|
151
|
+
// passing subject policy.
|
|
152
|
+
const unmanaged = Array.getSomes(actualEntries.map((entry) => {
|
|
153
|
+
const name = policy.actualName(entry);
|
|
154
|
+
if (installedNames.has(name))
|
|
155
|
+
return Option.none();
|
|
156
|
+
if (!policy.notClaimedBySubjectPolicy(entry))
|
|
157
|
+
return Option.none();
|
|
158
|
+
return Option.some(policy.buildUnmanagedRow(entry));
|
|
159
|
+
}));
|
|
160
|
+
return {
|
|
161
|
+
installed,
|
|
162
|
+
active,
|
|
163
|
+
unmanaged,
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
/**
|
|
167
|
+
* Build a name-indexed read-only map, keeping the first occurrence per name.
|
|
168
|
+
* Subsequent entries with the same name are dropped; the original input order
|
|
169
|
+
* determines which one wins. Pure helper used to dedupe declared/resolved
|
|
170
|
+
* entry arrays.
|
|
171
|
+
*/
|
|
172
|
+
const dedupeFirstByName = (entries, nameOf) => entries.reduce((acc, entry) => {
|
|
173
|
+
const name = nameOf(entry);
|
|
174
|
+
if (acc.has(name))
|
|
175
|
+
return acc;
|
|
176
|
+
const next = new Map(acc);
|
|
177
|
+
next.set(name, entry);
|
|
178
|
+
return next;
|
|
179
|
+
}, new Map());
|
|
180
|
+
//# sourceMappingURL=projection.js.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule subject module: declared/resolved/actual payloads, scanner composition,
|
|
3
|
+
* and projections via the shared helper.
|
|
4
|
+
*
|
|
5
|
+
* Rules have no `axm.json` entry shape and no `axm-lock.yaml` entry
|
|
6
|
+
* shape in v1. Actual occurrences come from the canonical-extensions
|
|
7
|
+
* scanner (`type === "rule"`); the agent-dir scanner emits no rule
|
|
8
|
+
* occurrences in the v1 `AgentRegistry`, but the subject module accepts an
|
|
9
|
+
* agent-dir scanner input so future agents can register rule directories
|
|
10
|
+
* without further changes here.
|
|
11
|
+
*/
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as Option from "effect/Option";
|
|
14
|
+
import type { AgentId } from "@agentxm/extension-model/unstable/agents/types";
|
|
15
|
+
import { type ExtensionName } from "@agentxm/extension-model/unstable/extensions/common";
|
|
16
|
+
import type { Lockfile, RuleLockEntry } from "../../../lockfile/schema.js";
|
|
17
|
+
import type { RuleEntry, Settings } from "../../../settings/schema.js";
|
|
18
|
+
import type { Diagnostics } from "../diagnostics.js";
|
|
19
|
+
import type { LockfileReadError, SettingsReadError } from "../errors.js";
|
|
20
|
+
import type { CanonicalExtensionOccurrence } from "../scanners/types.js";
|
|
21
|
+
import type { ActivationState, ExtensionKey, InstallationOrigin, InstalledPackRef, Scope } from "../types.js";
|
|
22
|
+
export type RuleDetectionOrigin = {
|
|
23
|
+
readonly _tag: "canonical-axm-rule";
|
|
24
|
+
} | {
|
|
25
|
+
readonly _tag: "external-axm-rule";
|
|
26
|
+
} | {
|
|
27
|
+
readonly _tag: "agent-rule-dir";
|
|
28
|
+
readonly agentId: AgentId;
|
|
29
|
+
};
|
|
30
|
+
export interface DeclaredRule {
|
|
31
|
+
readonly name: ExtensionName;
|
|
32
|
+
readonly entry: RuleEntry;
|
|
33
|
+
}
|
|
34
|
+
export type DeclaredRules = ReadonlyArray<DeclaredRule>;
|
|
35
|
+
export interface ResolvedRule {
|
|
36
|
+
readonly name: ExtensionName;
|
|
37
|
+
readonly lockEntry: RuleLockEntry;
|
|
38
|
+
}
|
|
39
|
+
export type ResolvedRules = ReadonlyArray<ResolvedRule>;
|
|
40
|
+
export interface ActualRule {
|
|
41
|
+
readonly key: ExtensionKey<"rule">;
|
|
42
|
+
readonly origin: RuleDetectionOrigin;
|
|
43
|
+
readonly contentRoot: string;
|
|
44
|
+
readonly packageRoot: string | null;
|
|
45
|
+
}
|
|
46
|
+
export type ActualRules = ReadonlyArray<ActualRule>;
|
|
47
|
+
export interface RulePackMember {
|
|
48
|
+
readonly name: ExtensionName;
|
|
49
|
+
readonly providingPack: InstalledPackRef;
|
|
50
|
+
}
|
|
51
|
+
export interface InstalledRule {
|
|
52
|
+
readonly key: ExtensionKey<"rule">;
|
|
53
|
+
readonly installationOrigin: InstallationOrigin<DeclaredRule, RulePackMember>;
|
|
54
|
+
readonly activation: ActivationState;
|
|
55
|
+
readonly resolved: Option.Option<ResolvedRule>;
|
|
56
|
+
readonly actual: ReadonlyArray<ActualRule>;
|
|
57
|
+
readonly providingPacks: ReadonlyArray<InstalledPackRef>;
|
|
58
|
+
}
|
|
59
|
+
export interface UnmanagedRule {
|
|
60
|
+
readonly key: ExtensionKey<"rule">;
|
|
61
|
+
readonly actual: ActualRule;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Rule scanners. v1 ships a canonical scanner only; the v1 `AgentRegistry`
|
|
65
|
+
* does not register rule directories, so there is no agent-dir rule input.
|
|
66
|
+
* If a future agent registers a rule directory, this scanner record gains an
|
|
67
|
+
* `agentDir` field and the subject module wires through `agent-rule-dir`
|
|
68
|
+
* origins.
|
|
69
|
+
*/
|
|
70
|
+
export interface RuleScanners {
|
|
71
|
+
readonly canonical: Effect.Effect<ReadonlyArray<CanonicalExtensionOccurrence>>;
|
|
72
|
+
}
|
|
73
|
+
export interface RuleScopedLoaders {
|
|
74
|
+
readonly settings: Effect.Effect<Option.Option<Settings>, SettingsReadError>;
|
|
75
|
+
readonly lockfile: Effect.Effect<Option.Option<Lockfile>, LockfileReadError>;
|
|
76
|
+
}
|
|
77
|
+
export interface InstalledPackForRules {
|
|
78
|
+
readonly ref: InstalledPackRef;
|
|
79
|
+
readonly rules: ReadonlyArray<RulePackMember>;
|
|
80
|
+
}
|
|
81
|
+
export interface RuleExtensionsApiDeps {
|
|
82
|
+
readonly scope: Scope;
|
|
83
|
+
readonly loaders: RuleScopedLoaders;
|
|
84
|
+
readonly scanners: RuleScanners;
|
|
85
|
+
readonly installedPacks: Effect.Effect<ReadonlyArray<InstalledPackForRules>, SettingsReadError | LockfileReadError>;
|
|
86
|
+
readonly diagnostics: Diagnostics;
|
|
87
|
+
}
|
|
88
|
+
export interface RuleExtensionsApi {
|
|
89
|
+
readonly declared: Effect.Effect<Option.Option<DeclaredRules>, SettingsReadError>;
|
|
90
|
+
readonly resolved: Effect.Effect<Option.Option<ResolvedRules>, LockfileReadError>;
|
|
91
|
+
readonly actual: Effect.Effect<ActualRules>;
|
|
92
|
+
readonly installed: Effect.Effect<ReadonlyArray<InstalledRule>, SettingsReadError | LockfileReadError>;
|
|
93
|
+
readonly byName: (name: string) => Effect.Effect<Option.Option<InstalledRule>, SettingsReadError | LockfileReadError>;
|
|
94
|
+
readonly declaredByName: (name: string) => Effect.Effect<Option.Option<DeclaredRule>, SettingsReadError>;
|
|
95
|
+
readonly active: Effect.Effect<ReadonlyArray<InstalledRule>, SettingsReadError | LockfileReadError>;
|
|
96
|
+
readonly unmanaged: Effect.Effect<ReadonlyArray<UnmanagedRule>, SettingsReadError | LockfileReadError>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Build the rule subject API. Returns an `Effect` because the projection
|
|
100
|
+
* cell is wrapped in `Effect.cached` so the four derived cells share one
|
|
101
|
+
* in-flight execution per scope, mirroring `state.ts`.
|
|
102
|
+
*/
|
|
103
|
+
export declare const makeRuleExtensionsApi: (deps: RuleExtensionsApiDeps) => Effect.Effect<RuleExtensionsApi>;
|
|
104
|
+
//# sourceMappingURL=rule.d.ts.map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule subject module: declared/resolved/actual payloads, scanner composition,
|
|
3
|
+
* and projections via the shared helper.
|
|
4
|
+
*
|
|
5
|
+
* Rules have no `axm.json` entry shape and no `axm-lock.yaml` entry
|
|
6
|
+
* shape in v1. Actual occurrences come from the canonical-extensions
|
|
7
|
+
* scanner (`type === "rule"`); the agent-dir scanner emits no rule
|
|
8
|
+
* occurrences in the v1 `AgentRegistry`, but the subject module accepts an
|
|
9
|
+
* agent-dir scanner input so future agents can register rule directories
|
|
10
|
+
* without further changes here.
|
|
11
|
+
*/
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as Option from "effect/Option";
|
|
14
|
+
import { decodeExtensionNameSync, } from "@agentxm/extension-model/unstable/extensions/common";
|
|
15
|
+
import { filterMapOccurrences } from "./actual-helpers.js";
|
|
16
|
+
import { canonicalAxmPackageRoot } from "./package-root.js";
|
|
17
|
+
import { makeProjectedSubjectCells, projectInstalledExtensions, } from "./projection.js";
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Helpers
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const canonicalToActual = (occ, scope) => {
|
|
22
|
+
const isExternal = occ.origin === "external-axm";
|
|
23
|
+
const packageRoot = canonicalAxmPackageRoot(occ);
|
|
24
|
+
return {
|
|
25
|
+
key: { scope, type: "rule", name: occ.name },
|
|
26
|
+
origin: isExternal ? { _tag: "external-axm-rule" } : { _tag: "canonical-axm-rule" },
|
|
27
|
+
contentRoot: occ.contentLocation,
|
|
28
|
+
packageRoot,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const declaredFromSettings = (settings) => {
|
|
32
|
+
if (settings.rules === undefined)
|
|
33
|
+
return [];
|
|
34
|
+
return Object.entries(settings.rules).map(([name, entry]) => ({
|
|
35
|
+
name: decodeExtensionNameSync(name),
|
|
36
|
+
entry,
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
39
|
+
const resolvedFromLockfile = (lockfile) => {
|
|
40
|
+
if (lockfile.rules === undefined)
|
|
41
|
+
return [];
|
|
42
|
+
return Object.entries(lockfile.rules).map(([name, lockEntry]) => ({
|
|
43
|
+
name: decodeExtensionNameSync(name),
|
|
44
|
+
lockEntry,
|
|
45
|
+
}));
|
|
46
|
+
};
|
|
47
|
+
const orphanResolvedWarning = (name) => ({
|
|
48
|
+
source: "lockfile",
|
|
49
|
+
message: `rule: lockfile entry "${name}" has no matching declared or pack-member home`,
|
|
50
|
+
code: "orphan-resolved",
|
|
51
|
+
});
|
|
52
|
+
const rulePolicy = (scope) => ({
|
|
53
|
+
declaredEntries: (d) => d,
|
|
54
|
+
declaredName: (entry) => entry.name,
|
|
55
|
+
declaredActivation: (entry) => (entry.entry.enabled === false ? "disabled" : "enabled"),
|
|
56
|
+
resolvedEntries: (r) => r,
|
|
57
|
+
resolvedName: (entry) => entry.name,
|
|
58
|
+
actualEntries: (a) => a,
|
|
59
|
+
actualName: (e) => e.key.name,
|
|
60
|
+
packMemberName: (m) => m.name,
|
|
61
|
+
packMemberActivation: () => "enabled",
|
|
62
|
+
attachActualToInstalled: (name, actual) => actual.filter((a) => a.key.name === name),
|
|
63
|
+
notClaimedBySubjectPolicy: () => true,
|
|
64
|
+
buildInstalledRow: (input) => ({
|
|
65
|
+
key: { scope, type: "rule", name: input.name },
|
|
66
|
+
installationOrigin: input.installationOrigin,
|
|
67
|
+
activation: input.activation,
|
|
68
|
+
resolved: input.resolved,
|
|
69
|
+
actual: input.actual,
|
|
70
|
+
providingPacks: input.providingPacks,
|
|
71
|
+
}),
|
|
72
|
+
buildUnmanagedRow: (entry) => ({
|
|
73
|
+
key: { scope, type: "rule", name: entry.key.name },
|
|
74
|
+
actual: entry,
|
|
75
|
+
}),
|
|
76
|
+
resolvedOrphanWarning: orphanResolvedWarning,
|
|
77
|
+
});
|
|
78
|
+
/**
|
|
79
|
+
* Build the rule subject API. Returns an `Effect` because the projection
|
|
80
|
+
* cell is wrapped in `Effect.cached` so the four derived cells share one
|
|
81
|
+
* in-flight execution per scope, mirroring `state.ts`.
|
|
82
|
+
*/
|
|
83
|
+
export const makeRuleExtensionsApi = (deps) => Effect.gen(function* () {
|
|
84
|
+
const { scope, scanners, diagnostics } = deps;
|
|
85
|
+
const declared = deps.loaders.settings.pipe(Effect.map((opt) => Option.map(opt, declaredFromSettings)));
|
|
86
|
+
const resolved = deps.loaders.lockfile.pipe(Effect.map((opt) => Option.map(opt, resolvedFromLockfile)));
|
|
87
|
+
const actual = Effect.gen(function* () {
|
|
88
|
+
const canonical = yield* scanners.canonical;
|
|
89
|
+
return filterMapOccurrences(canonical, "rule", (occ) => canonicalToActual(occ, scope));
|
|
90
|
+
});
|
|
91
|
+
const project = yield* Effect.cached(projectInstalledExtensions({
|
|
92
|
+
declared,
|
|
93
|
+
resolved,
|
|
94
|
+
actual,
|
|
95
|
+
installedPacks: deps.installedPacks,
|
|
96
|
+
packMembers: (pack) => pack.rules,
|
|
97
|
+
packRef: (pack) => pack.ref,
|
|
98
|
+
policy: rulePolicy(scope),
|
|
99
|
+
diagnostics,
|
|
100
|
+
}));
|
|
101
|
+
return {
|
|
102
|
+
...makeProjectedSubjectCells({
|
|
103
|
+
declared,
|
|
104
|
+
resolved,
|
|
105
|
+
actual,
|
|
106
|
+
project,
|
|
107
|
+
}),
|
|
108
|
+
declared,
|
|
109
|
+
resolved,
|
|
110
|
+
actual,
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=rule.js.map
|