@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.
Files changed (215) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +11 -0
  3. package/dist/src/index.d.ts +72 -0
  4. package/dist/src/index.js +88 -0
  5. package/dist/src/knowledge/discovery-config.d.ts +12 -0
  6. package/dist/src/knowledge/discovery-config.js +9 -0
  7. package/dist/src/lockfile/accepted-registry-version.d.ts +12 -0
  8. package/dist/src/lockfile/accepted-registry-version.js +13 -0
  9. package/dist/src/lockfile/entry-fields.d.ts +189 -0
  10. package/dist/src/lockfile/entry-fields.js +89 -0
  11. package/dist/src/lockfile/errors.d.ts +48 -0
  12. package/dist/src/lockfile/errors.js +27 -0
  13. package/dist/src/lockfile/index.d.ts +18 -0
  14. package/dist/src/lockfile/index.js +16 -0
  15. package/dist/src/lockfile/lockfile.d.ts +2255 -0
  16. package/dist/src/lockfile/lockfile.js +235 -0
  17. package/dist/src/lockfile/resolved-version.d.ts +4 -0
  18. package/dist/src/lockfile/resolved-version.js +7 -0
  19. package/dist/src/lockfile/schema.d.ts +3062 -0
  20. package/dist/src/lockfile/schema.js +406 -0
  21. package/dist/src/schema/index.d.ts +3 -0
  22. package/dist/src/schema/index.js +2 -0
  23. package/dist/src/schema/read-and-validate-json-file.d.ts +20 -0
  24. package/dist/src/schema/read-and-validate-json-file.js +85 -0
  25. package/dist/src/schema/types.d.ts +26 -0
  26. package/dist/src/schema/types.js +2 -0
  27. package/dist/src/settings/errors.d.ts +22 -0
  28. package/dist/src/settings/errors.js +15 -0
  29. package/dist/src/settings/format-preserving-json.d.ts +40 -0
  30. package/dist/src/settings/format-preserving-json.js +80 -0
  31. package/dist/src/settings/index.d.ts +15 -0
  32. package/dist/src/settings/index.js +14 -0
  33. package/dist/src/settings/schema.d.ts +687 -0
  34. package/dist/src/settings/schema.js +977 -0
  35. package/dist/src/settings/settings.d.ts +38 -0
  36. package/dist/src/settings/settings.js +213 -0
  37. package/dist/src/testing.d.ts +17 -0
  38. package/dist/src/testing.js +17 -0
  39. package/dist/src/utils/atomic-write.d.ts +67 -0
  40. package/dist/src/utils/atomic-write.js +71 -0
  41. package/dist/src/utils/environment.d.ts +16 -0
  42. package/dist/src/utils/environment.js +19 -0
  43. package/dist/src/utils/path-safety.d.ts +25 -0
  44. package/dist/src/utils/path-safety.js +34 -0
  45. package/dist/src/utils/resolve-parent-symlinks.d.ts +16 -0
  46. package/dist/src/utils/resolve-parent-symlinks.js +36 -0
  47. package/dist/src/workspace/accepted-canonical-ref.d.ts +58 -0
  48. package/dist/src/workspace/accepted-canonical-ref.js +229 -0
  49. package/dist/src/workspace/artifact-change.d.ts +14 -0
  50. package/dist/src/workspace/artifact-change.js +18 -0
  51. package/dist/src/workspace/canonical-observation.d.ts +39 -0
  52. package/dist/src/workspace/canonical-observation.js +307 -0
  53. package/dist/src/workspace/configured-agent-outcome.d.ts +22 -0
  54. package/dist/src/workspace/configured-agent-outcome.js +33 -0
  55. package/dist/src/workspace/configured-agent-outcomes-provider.d.ts +50 -0
  56. package/dist/src/workspace/configured-agent-outcomes-provider.js +26 -0
  57. package/dist/src/workspace/configured-agent-outcomes.d.ts +48 -0
  58. package/dist/src/workspace/configured-agent-outcomes.js +113 -0
  59. package/dist/src/workspace/configured-entry-resolution/types.d.ts +32 -0
  60. package/dist/src/workspace/configured-entry-resolution/types.js +2 -0
  61. package/dist/src/workspace/configured-entry-resolution/workspace-ref.d.ts +32 -0
  62. package/dist/src/workspace/configured-entry-resolution/workspace-ref.js +176 -0
  63. package/dist/src/workspace/constants.d.ts +6 -0
  64. package/dist/src/workspace/constants.js +6 -0
  65. package/dist/src/workspace/create-symlink.d.ts +26 -0
  66. package/dist/src/workspace/create-symlink.js +87 -0
  67. package/dist/src/workspace/desired-pack-lock.d.ts +18 -0
  68. package/dist/src/workspace/desired-pack-lock.js +132 -0
  69. package/dist/src/workspace/desired-state-enabled.d.ts +18 -0
  70. package/dist/src/workspace/desired-state-enabled.js +16 -0
  71. package/dist/src/workspace/desired-state-graph.d.ts +114 -0
  72. package/dist/src/workspace/desired-state-graph.js +384 -0
  73. package/dist/src/workspace/desired-state-problem-text.d.ts +6 -0
  74. package/dist/src/workspace/desired-state-problem-text.js +27 -0
  75. package/dist/src/workspace/errors.d.ts +184 -0
  76. package/dist/src/workspace/errors.js +79 -0
  77. package/dist/src/workspace/extension-name.d.ts +28 -0
  78. package/dist/src/workspace/extension-name.js +66 -0
  79. package/dist/src/workspace/extension-paths.d.ts +82 -0
  80. package/dist/src/workspace/extension-paths.js +172 -0
  81. package/dist/src/workspace/footprint-recorder.d.ts +30 -0
  82. package/dist/src/workspace/footprint-recorder.js +32 -0
  83. package/dist/src/workspace/layout.d.ts +43 -0
  84. package/dist/src/workspace/layout.js +164 -0
  85. package/dist/src/workspace/lock-entry-to-ref.d.ts +40 -0
  86. package/dist/src/workspace/lock-entry-to-ref.js +433 -0
  87. package/dist/src/workspace/lock-entry-to-source-params.d.ts +26 -0
  88. package/dist/src/workspace/lock-entry-to-source-params.js +81 -0
  89. package/dist/src/workspace/locked-entries.d.ts +30 -0
  90. package/dist/src/workspace/locked-entries.js +34 -0
  91. package/dist/src/workspace/materialized-file-target.d.ts +14 -0
  92. package/dist/src/workspace/materialized-file-target.js +14 -0
  93. package/dist/src/workspace/materialized-tree.d.ts +23 -0
  94. package/dist/src/workspace/materialized-tree.js +90 -0
  95. package/dist/src/workspace/mcp-entry-semantics.d.ts +31 -0
  96. package/dist/src/workspace/mcp-entry-semantics.js +60 -0
  97. package/dist/src/workspace/observed-installed.d.ts +9 -0
  98. package/dist/src/workspace/observed-installed.js +9 -0
  99. package/dist/src/workspace/pack-manifest-content-identity.d.ts +12 -0
  100. package/dist/src/workspace/pack-manifest-content-identity.js +20 -0
  101. package/dist/src/workspace/pack-paths.d.ts +24 -0
  102. package/dist/src/workspace/pack-paths.js +16 -0
  103. package/dist/src/workspace/package-hash.d.ts +25 -0
  104. package/dist/src/workspace/package-hash.js +45 -0
  105. package/dist/src/workspace/paths.d.ts +24 -0
  106. package/dist/src/workspace/paths.js +52 -0
  107. package/dist/src/workspace/read-model/__fixtures__/builder.d.ts +199 -0
  108. package/dist/src/workspace/read-model/__fixtures__/builder.js +588 -0
  109. package/dist/src/workspace/read-model/__fixtures__/decoders.d.ts +15 -0
  110. package/dist/src/workspace/read-model/__fixtures__/decoders.js +15 -0
  111. package/dist/src/workspace/read-model/__fixtures__/occurrences.d.ts +72 -0
  112. package/dist/src/workspace/read-model/__fixtures__/occurrences.js +134 -0
  113. package/dist/src/workspace/read-model/__fixtures__/scenario-harness.d.ts +99 -0
  114. package/dist/src/workspace/read-model/__fixtures__/scenario-harness.js +142 -0
  115. package/dist/src/workspace/read-model/__fixtures__/test-layer.d.ts +60 -0
  116. package/dist/src/workspace/read-model/__fixtures__/test-layer.js +57 -0
  117. package/dist/src/workspace/read-model/agent-presence.d.ts +32 -0
  118. package/dist/src/workspace/read-model/agent-presence.js +21 -0
  119. package/dist/src/workspace/read-model/agent-root-resolver.d.ts +38 -0
  120. package/dist/src/workspace/read-model/agent-root-resolver.js +35 -0
  121. package/dist/src/workspace/read-model/agents/index.d.ts +38 -0
  122. package/dist/src/workspace/read-model/agents/index.js +45 -0
  123. package/dist/src/workspace/read-model/agents/shared.d.ts +27 -0
  124. package/dist/src/workspace/read-model/agents/shared.js +63 -0
  125. package/dist/src/workspace/read-model/agents/types.d.ts +133 -0
  126. package/dist/src/workspace/read-model/agents/types.js +51 -0
  127. package/dist/src/workspace/read-model/diagnostics.d.ts +18 -0
  128. package/dist/src/workspace/read-model/diagnostics.js +14 -0
  129. package/dist/src/workspace/read-model/discovery/index.d.ts +5 -0
  130. package/dist/src/workspace/read-model/discovery/index.js +5 -0
  131. package/dist/src/workspace/read-model/discovery/plugin-manifests.d.ts +16 -0
  132. package/dist/src/workspace/read-model/discovery/plugin-manifests.js +168 -0
  133. package/dist/src/workspace/read-model/discovery/skills.d.ts +58 -0
  134. package/dist/src/workspace/read-model/discovery/skills.js +263 -0
  135. package/dist/src/workspace/read-model/discovery/subagents.d.ts +37 -0
  136. package/dist/src/workspace/read-model/discovery/subagents.js +48 -0
  137. package/dist/src/workspace/read-model/errors.d.ts +93 -0
  138. package/dist/src/workspace/read-model/errors.js +30 -0
  139. package/dist/src/workspace/read-model/extensions/actual-helpers.d.ts +4 -0
  140. package/dist/src/workspace/read-model/extensions/actual-helpers.js +4 -0
  141. package/dist/src/workspace/read-model/extensions/hook.d.ts +104 -0
  142. package/dist/src/workspace/read-model/extensions/hook.js +119 -0
  143. package/dist/src/workspace/read-model/extensions/index.d.ts +19 -0
  144. package/dist/src/workspace/read-model/extensions/index.js +43 -0
  145. package/dist/src/workspace/read-model/extensions/indexByName.d.ts +31 -0
  146. package/dist/src/workspace/read-model/extensions/indexByName.js +30 -0
  147. package/dist/src/workspace/read-model/extensions/inventory.d.ts +99 -0
  148. package/dist/src/workspace/read-model/extensions/inventory.js +111 -0
  149. package/dist/src/workspace/read-model/extensions/knowledge.d.ts +101 -0
  150. package/dist/src/workspace/read-model/extensions/knowledge.js +121 -0
  151. package/dist/src/workspace/read-model/extensions/mcp-server.d.ts +106 -0
  152. package/dist/src/workspace/read-model/extensions/mcp-server.js +122 -0
  153. package/dist/src/workspace/read-model/extensions/pack.d.ts +104 -0
  154. package/dist/src/workspace/read-model/extensions/pack.js +123 -0
  155. package/dist/src/workspace/read-model/extensions/package-root.d.ts +39 -0
  156. package/dist/src/workspace/read-model/extensions/package-root.js +48 -0
  157. package/dist/src/workspace/read-model/extensions/projection.d.ts +137 -0
  158. package/dist/src/workspace/read-model/extensions/projection.js +180 -0
  159. package/dist/src/workspace/read-model/extensions/rule.d.ts +104 -0
  160. package/dist/src/workspace/read-model/extensions/rule.js +113 -0
  161. package/dist/src/workspace/read-model/extensions/skill.d.ts +170 -0
  162. package/dist/src/workspace/read-model/extensions/skill.js +148 -0
  163. package/dist/src/workspace/read-model/extensions/subagent.d.ts +97 -0
  164. package/dist/src/workspace/read-model/extensions/subagent.js +120 -0
  165. package/dist/src/workspace/read-model/scanners/agent-dir.d.ts +49 -0
  166. package/dist/src/workspace/read-model/scanners/agent-dir.js +180 -0
  167. package/dist/src/workspace/read-model/scanners/agent-root.d.ts +73 -0
  168. package/dist/src/workspace/read-model/scanners/agent-root.js +148 -0
  169. package/dist/src/workspace/read-model/scanners/agent-settings.d.ts +43 -0
  170. package/dist/src/workspace/read-model/scanners/agent-settings.js +54 -0
  171. package/dist/src/workspace/read-model/scanners/canonical-extensions.d.ts +48 -0
  172. package/dist/src/workspace/read-model/scanners/canonical-extensions.js +237 -0
  173. package/dist/src/workspace/read-model/scanners/fs-helpers.d.ts +63 -0
  174. package/dist/src/workspace/read-model/scanners/fs-helpers.js +106 -0
  175. package/dist/src/workspace/read-model/scanners/index.d.ts +15 -0
  176. package/dist/src/workspace/read-model/scanners/index.js +34 -0
  177. package/dist/src/workspace/read-model/scanners/mcp-config.d.ts +47 -0
  178. package/dist/src/workspace/read-model/scanners/mcp-config.js +212 -0
  179. package/dist/src/workspace/read-model/scanners/types.d.ts +170 -0
  180. package/dist/src/workspace/read-model/scanners/types.js +86 -0
  181. package/dist/src/workspace/read-model/service.d.ts +103 -0
  182. package/dist/src/workspace/read-model/service.js +391 -0
  183. package/dist/src/workspace/read-model/state.d.ts +35 -0
  184. package/dist/src/workspace/read-model/state.js +97 -0
  185. package/dist/src/workspace/read-model/types.d.ts +75 -0
  186. package/dist/src/workspace/read-model/types.js +26 -0
  187. package/dist/src/workspace/read-model-record-readers.d.ts +34 -0
  188. package/dist/src/workspace/read-model-record-readers.js +467 -0
  189. package/dist/src/workspace/read-model-record-rows.d.ts +45 -0
  190. package/dist/src/workspace/read-model-record-rows.js +33 -0
  191. package/dist/src/workspace/read-model-record-types.d.ts +45 -0
  192. package/dist/src/workspace/read-model-record-types.js +13 -0
  193. package/dist/src/workspace/remove-if-exists.d.ts +13 -0
  194. package/dist/src/workspace/remove-if-exists.js +26 -0
  195. package/dist/src/workspace/rendered-files.d.ts +53 -0
  196. package/dist/src/workspace/rendered-files.js +50 -0
  197. package/dist/src/workspace/scope-refusal.d.ts +26 -0
  198. package/dist/src/workspace/scope-refusal.js +29 -0
  199. package/dist/src/workspace/service-interface.d.ts +479 -0
  200. package/dist/src/workspace/service-interface.js +27 -0
  201. package/dist/src/workspace/service.d.ts +1665 -0
  202. package/dist/src/workspace/service.js +1263 -0
  203. package/dist/src/workspace/setup-scope-support.d.ts +27 -0
  204. package/dist/src/workspace/setup-scope-support.js +299 -0
  205. package/dist/src/workspace/skill-paths.d.ts +33 -0
  206. package/dist/src/workspace/skill-paths.js +14 -0
  207. package/dist/src/workspace/source-metadata.d.ts +7 -0
  208. package/dist/src/workspace/source-metadata.js +10 -0
  209. package/dist/src/workspace/source-to-lock-entry.d.ts +32 -0
  210. package/dist/src/workspace/source-to-lock-entry.js +68 -0
  211. package/dist/src/workspace/test-stubs.d.ts +144 -0
  212. package/dist/src/workspace/test-stubs.js +412 -0
  213. package/dist/src/workspace/transaction.d.ts +218 -0
  214. package/dist/src/workspace/transaction.js +177 -0
  215. package/package.json +57 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Catalog-derived agent projections and the scoped agent read-model API.
3
+ *
4
+ * All agents share the same declared, actual, and detected projectors. The
5
+ * canonical capability catalog carries genuine per-agent variance, so adding
6
+ * an agent does not require a placeholder module or registry edit here.
7
+ */
8
+ import * as Array from "effect/Array";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Option from "effect/Option";
11
+ import { AGENTS } from "@agentxm/extension-model/unstable/agents/registry";
12
+ import { AGENT_IDS, CONFIGURABLE_AGENT_IDS, isConfigurableAgentId, } from "@agentxm/extension-model/unstable/agents/types";
13
+ import { defineAgentModule, } from "./types.js";
14
+ export { defineAgentModule } from "./types.js";
15
+ /** Every configurable catalog agent, in canonical order. */
16
+ export const registeredAgentModules = CONFIGURABLE_AGENT_IDS.map((agentId) => defineAgentModule({ agentId, descriptor: AGENTS[agentId] }));
17
+ /** Build the common projector module for one catalog agent. */
18
+ export const getAgentModule = (id) => defineAgentModule({ agentId: id, descriptor: AGENTS[id] });
19
+ const isAgentId = (id) => Object.hasOwn(AGENTS, id);
20
+ /** Build the agent portion of a scoped workspace read model. */
21
+ export const makeScopedAgentsApi = (deps) => {
22
+ const { scope, settings, presence, observations } = deps;
23
+ const declared = (id) => isConfigurableAgentId(id)
24
+ ? settings.pipe(Effect.map((decoded) => getAgentModule(id).declared(scope, decoded)))
25
+ : Effect.succeed(Option.none());
26
+ const actual = (id) => isConfigurableAgentId(id)
27
+ ? observations.pipe(Effect.map((obs) => getAgentModule(id).actual(scope, obs)))
28
+ : Effect.succeed(Option.none());
29
+ const detected = Effect.all([
30
+ Effect.result(settings).pipe(Effect.map((settingsResult) => settingsResult._tag === "Failure"
31
+ ? Option.none()
32
+ : settingsResult.success)),
33
+ presence,
34
+ observations,
35
+ ]).pipe(Effect.map(([decoded, presentAgentIds, obs]) => Array.getSomes(registeredAgentModules.map((module) => module.detected(scope, module.declared(scope, decoded), presentAgentIds.has(module.agentId), module.actual(scope, obs))))));
36
+ return {
37
+ list: Effect.succeed(AGENT_IDS),
38
+ known: Effect.succeed(AGENT_IDS.map((id) => AGENTS[id])),
39
+ byId: (id) => (isAgentId(id) ? Option.some(AGENTS[id]) : Option.none()),
40
+ declared,
41
+ actual,
42
+ detected,
43
+ };
44
+ };
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared default projectors used by every per-agent module.
3
+ *
4
+ * The default behavior captures the v1 contract:
5
+ *
6
+ * - `defaultDeclared(agentId, scope, settings)` — returns
7
+ * `Option.some(DeclaredAgent)` iff the decoded settings list the agent in
8
+ * its `agents` array. Pure function over already-decoded settings.
9
+ * - `defaultActual(agentId, scope, observations)` — returns
10
+ * `Option.some(ActualAgent)` iff at least one scanner observation refers to
11
+ * the agent. Combines agent-dir, agent-settings, and per-agent MCP-config
12
+ * evidence.
13
+ * - `defaultDetected(agentId, scope, declared, actual)` — combines the two
14
+ * into a `DetectedAgent` when at least one is present; returns
15
+ * `Option.none()` when both are absent (no evidence either way).
16
+ *
17
+ * Per-agent modules override these only if their native config requires
18
+ * agent-specific evidence rules. v1 modules all reuse these defaults.
19
+ */
20
+ import * as Option from "effect/Option";
21
+ import type { AgentId } from "@agentxm/extension-model/unstable/agents/types";
22
+ import type { Scope } from "../types.js";
23
+ import type { ActualAgent, AgentScannerObservations, DeclaredAgent, DeclaredSettingsShape, DetectedAgent } from "./types.js";
24
+ export declare const defaultDeclared: (agentId: AgentId, scope: Scope, settings: Option.Option<DeclaredSettingsShape>) => Option.Option<DeclaredAgent>;
25
+ export declare const defaultActual: (agentId: AgentId, scope: Scope, observations: AgentScannerObservations) => Option.Option<ActualAgent>;
26
+ export declare const defaultDetected: (agentId: AgentId, scope: Scope, declared: Option.Option<DeclaredAgent>, present: boolean, actual: Option.Option<ActualAgent>) => Option.Option<DetectedAgent>;
27
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Shared default projectors used by every per-agent module.
3
+ *
4
+ * The default behavior captures the v1 contract:
5
+ *
6
+ * - `defaultDeclared(agentId, scope, settings)` — returns
7
+ * `Option.some(DeclaredAgent)` iff the decoded settings list the agent in
8
+ * its `agents` array. Pure function over already-decoded settings.
9
+ * - `defaultActual(agentId, scope, observations)` — returns
10
+ * `Option.some(ActualAgent)` iff at least one scanner observation refers to
11
+ * the agent. Combines agent-dir, agent-settings, and per-agent MCP-config
12
+ * evidence.
13
+ * - `defaultDetected(agentId, scope, declared, actual)` — combines the two
14
+ * into a `DetectedAgent` when at least one is present; returns
15
+ * `Option.none()` when both are absent (no evidence either way).
16
+ *
17
+ * Per-agent modules override these only if their native config requires
18
+ * agent-specific evidence rules. v1 modules all reuse these defaults.
19
+ */
20
+ import * as Option from "effect/Option";
21
+ export const defaultDeclared = (agentId, scope, settings) => {
22
+ if (Option.isNone(settings))
23
+ return Option.none();
24
+ const declaredAgents = settings.value.agents ?? [];
25
+ if (!declaredAgents.includes(agentId))
26
+ return Option.none();
27
+ return Option.some({ scope, agentId });
28
+ };
29
+ export const defaultActual = (agentId, scope, observations) => {
30
+ const agentDir = observations.agentDir.filter((occ) => occ.agentId === agentId &&
31
+ (occ.readPathStatus === undefined || occ.readPathStatus === "primary"));
32
+ const agentSettings = observations.agentSettings.filter((occ) => occ.agentId === agentId);
33
+ const mcpConfig = observations.mcpConfig.filter((occ) => occ.surface._tag === "agent" && occ.surface.agentId === agentId);
34
+ if (agentDir.length === 0 && agentSettings.length === 0 && mcpConfig.length === 0) {
35
+ return Option.none();
36
+ }
37
+ return Option.some({
38
+ scope,
39
+ agentId,
40
+ agentDirOccurrences: agentDir,
41
+ agentSettingsOccurrences: agentSettings,
42
+ mcpConfigOccurrences: mcpConfig,
43
+ });
44
+ };
45
+ export const defaultDetected = (agentId, scope, declared, present, actual) => {
46
+ const isDeclared = Option.isSome(declared);
47
+ const status = isDeclared && present
48
+ ? Option.some("managed-and-present")
49
+ : isDeclared
50
+ ? Option.some("managed-not-present")
51
+ : present
52
+ ? Option.some("unmanaged-present")
53
+ : Option.none();
54
+ return Option.map(status, (s) => ({
55
+ scope,
56
+ agentId,
57
+ status: s,
58
+ present,
59
+ declared,
60
+ actual,
61
+ }));
62
+ };
63
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Shared agent projection types used by the generated module registry.
3
+ *
4
+ * Per Decision 3 (agents have declared + actual only; no resolved layer) and
5
+ * Decision 4 (per-subject modules carry the genuine variance) of the
6
+ * workspace read-model design:
7
+ *
8
+ * - `DeclaredAgent` / `ActualAgent` / `DetectedAgent` are the per-agent
9
+ * payload shapes the projectors return through `Option`.
10
+ * - `AgentModule<TId>` is the common projector contract generated from the
11
+ * canonical agent catalog.
12
+ * - `AgentScannerObservations` is the input projector helpers consume from the
13
+ * live composition (Phase 9). It carries the agent-specific slice of scanner
14
+ * outputs — directly observable evidence that this agent has any presence in
15
+ * the workspace.
16
+ *
17
+ * `AgentSubjectType` mirrors `scanners/types.ts#AgentDirSubjectType` so the
18
+ * agent registry barrel does not need to import scanner types at runtime.
19
+ */
20
+ import type * as Option from "effect/Option";
21
+ import type { AgentDescriptor, AgentId } from "@agentxm/extension-model/unstable/agents/types";
22
+ import type { AgentDirOccurrence, AgentSettingsOccurrence, McpConfigOccurrence } from "../scanners/types.js";
23
+ import type { Scope } from "../types.js";
24
+ /**
25
+ * Subject types renderable into per-agent directories. Mirrors the
26
+ * `AgentDirSubjectType` discriminator on the agent-dir scanner. Per-agent
27
+ * modules expose the subjects they support so the registry barrel can answer
28
+ * "which subjects does this agent render?" without re-scanning the agent
29
+ * registry.
30
+ */
31
+ export type AgentSubjectType = "skill" | "subagent";
32
+ /**
33
+ * Settings-derived declaration of an agent for a given scope. Produced by the
34
+ * per-agent `declared(scope, settings)` projector when the scope's
35
+ * `axm.json` lists the agent in its `agents` array.
36
+ */
37
+ export interface DeclaredAgent {
38
+ readonly scope: Scope;
39
+ readonly agentId: AgentId;
40
+ }
41
+ /**
42
+ * Observable per-agent evidence collected from scanner outputs. An agent is
43
+ * "actual present" in a scope if at least one scanner observation refers to
44
+ * that agent — agent-dir occurrences for any subject, an agent-settings file,
45
+ * or an agent MCP config. The projector collects the underlying observations
46
+ * so consumers can render diagnostic detail.
47
+ *
48
+ * The actual layer NEVER fails (Decision 1).
49
+ */
50
+ export interface ActualAgent {
51
+ readonly scope: Scope;
52
+ readonly agentId: AgentId;
53
+ readonly agentDirOccurrences: ReadonlyArray<AgentDirOccurrence>;
54
+ readonly agentSettingsOccurrences: ReadonlyArray<AgentSettingsOccurrence>;
55
+ readonly mcpConfigOccurrences: ReadonlyArray<McpConfigOccurrence>;
56
+ }
57
+ /**
58
+ * Classification of an agent by combining declared + actual evidence. The
59
+ * three values mirror today's "managed agent" / "unmanaged agent" / "missing"
60
+ * classifications used by `axm setup` and lint diagnostics.
61
+ *
62
+ * - `managed-and-present` — settings declares the agent AND scanners observed
63
+ * evidence in the workspace.
64
+ * - `managed-not-present` — settings declares the agent BUT no scanners
65
+ * observed evidence.
66
+ * - `unmanaged-present` — scanners observed evidence BUT settings does not
67
+ * declare the agent.
68
+ *
69
+ * Agents that are neither declared nor present are NOT included in the
70
+ * `detected` projection — there is nothing to surface for an agent the user
71
+ * has not interacted with.
72
+ */
73
+ export type DetectionStatus = "managed-and-present" | "managed-not-present" | "unmanaged-present";
74
+ export interface DetectedAgent {
75
+ readonly scope: Scope;
76
+ readonly agentId: AgentId;
77
+ readonly status: DetectionStatus;
78
+ readonly present: boolean;
79
+ readonly declared: Option.Option<DeclaredAgent>;
80
+ readonly actual: Option.Option<ActualAgent>;
81
+ }
82
+ /**
83
+ * Pre-filtered scanner observations for one agent. Phase 9's live composition
84
+ * narrows scanner outputs by `agentId` once and threads the result into each
85
+ * per-agent module's `actual` projector.
86
+ *
87
+ * Each array is the (possibly empty) sequence of observations for this agent
88
+ * within the same scope. Per design Decision 5, the actual layer concatenates
89
+ * scanner outputs — duplicates of the same physical occurrence are collapsed
90
+ * upstream by the scanner-occurrence-identity helper.
91
+ */
92
+ export interface AgentScannerObservations {
93
+ readonly agentDir: ReadonlyArray<AgentDirOccurrence>;
94
+ readonly agentSettings: ReadonlyArray<AgentSettingsOccurrence>;
95
+ readonly mcpConfig: ReadonlyArray<McpConfigOccurrence>;
96
+ }
97
+ /**
98
+ * Subset of decoded `axm.json` the agent `declared` projectors need.
99
+ * Phase 8 modules accept this narrowed shape so they can be unit-tested
100
+ * without depending on the full Settings schema.
101
+ */
102
+ export interface DeclaredSettingsShape {
103
+ readonly agents?: ReadonlyArray<AgentId>;
104
+ }
105
+ /**
106
+ * Common projector contract for one catalog agent. Agent-specific native
107
+ * configuration belongs in the capability catalog, not phantom read-model
108
+ * types.
109
+ */
110
+ export interface AgentModule<TId extends AgentId = AgentId> {
111
+ readonly agentId: TId;
112
+ readonly subjects: ReadonlyArray<AgentSubjectType>;
113
+ readonly declared: (scope: Scope, settings: Option.Option<DeclaredSettingsShape>) => Option.Option<DeclaredAgent>;
114
+ readonly actual: (scope: Scope, observations: AgentScannerObservations) => Option.Option<ActualAgent>;
115
+ readonly detected: (scope: Scope, declared: Option.Option<DeclaredAgent>, present: boolean, actual: Option.Option<ActualAgent>) => Option.Option<DetectedAgent>;
116
+ }
117
+ /**
118
+ * Inputs to `defineAgentModule`. The factory derives `subjects` from the
119
+ * descriptor so registration does not repeat scanner-relevant subject data.
120
+ */
121
+ export interface DefineAgentModuleInput<TId extends AgentId> {
122
+ readonly agentId: TId;
123
+ readonly descriptor: AgentDescriptor;
124
+ }
125
+ /**
126
+ * Build a complete `AgentModule` for `agentId`. The projectors call the v1
127
+ * `defaultDeclared` / `defaultActual` / `defaultDetected` helpers from
128
+ * `shared.ts`. `subjects` is derived from `descriptor`.
129
+ *
130
+ * The registry creates these modules directly from the canonical catalog.
131
+ */
132
+ export declare const defineAgentModule: <TId extends AgentId>(input: DefineAgentModuleInput<TId>) => AgentModule<TId>;
133
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Shared agent projection types used by the generated module registry.
3
+ *
4
+ * Per Decision 3 (agents have declared + actual only; no resolved layer) and
5
+ * Decision 4 (per-subject modules carry the genuine variance) of the
6
+ * workspace read-model design:
7
+ *
8
+ * - `DeclaredAgent` / `ActualAgent` / `DetectedAgent` are the per-agent
9
+ * payload shapes the projectors return through `Option`.
10
+ * - `AgentModule<TId>` is the common projector contract generated from the
11
+ * canonical agent catalog.
12
+ * - `AgentScannerObservations` is the input projector helpers consume from the
13
+ * live composition (Phase 9). It carries the agent-specific slice of scanner
14
+ * outputs — directly observable evidence that this agent has any presence in
15
+ * the workspace.
16
+ *
17
+ * `AgentSubjectType` mirrors `scanners/types.ts#AgentDirSubjectType` so the
18
+ * agent registry barrel does not need to import scanner types at runtime.
19
+ */
20
+ import { defaultActual, defaultDeclared, defaultDetected } from "./shared.js";
21
+ /**
22
+ * Derive the subjects the agent renders into per-agent directories from its
23
+ * descriptor.
24
+ */
25
+ const subjectsFromDescriptor = (descriptor) => {
26
+ const out = [];
27
+ if (descriptor.skills !== undefined)
28
+ out.push("skill");
29
+ if (descriptor.subagents !== undefined)
30
+ out.push("subagent");
31
+ return out;
32
+ };
33
+ /**
34
+ * Build a complete `AgentModule` for `agentId`. The projectors call the v1
35
+ * `defaultDeclared` / `defaultActual` / `defaultDetected` helpers from
36
+ * `shared.ts`. `subjects` is derived from `descriptor`.
37
+ *
38
+ * The registry creates these modules directly from the canonical catalog.
39
+ */
40
+ export const defineAgentModule = (input) => {
41
+ const { agentId, descriptor } = input;
42
+ const subjects = subjectsFromDescriptor(descriptor);
43
+ return {
44
+ agentId,
45
+ subjects,
46
+ declared: (scope, settings) => defaultDeclared(agentId, scope, settings),
47
+ actual: (scope, observations) => defaultActual(agentId, scope, observations),
48
+ detected: (scope, declared, present, actual) => defaultDetected(agentId, scope, declared, present, actual),
49
+ };
50
+ };
51
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,18 @@
1
+ /** Per-scope append-only diagnostics buffer for settings/lockfile/scanner warnings. */
2
+ import * as Effect from "effect/Effect";
3
+ import * as Ref from "effect/Ref";
4
+ /** A degraded-state observation surfaced through a scoped diagnostics buffer. */
5
+ export interface Warning {
6
+ readonly source: "settings" | "lockfile" | "scanner";
7
+ readonly message: string;
8
+ readonly path?: string;
9
+ readonly code?: string;
10
+ }
11
+ /** Append-only, snapshot-readable warning buffer for one scoped workspace read model. */
12
+ export interface Diagnostics {
13
+ readonly append: (warning: Warning) => Effect.Effect<void>;
14
+ readonly snapshot: Effect.Effect<ReadonlyArray<Warning>>;
15
+ }
16
+ /** Build a `Diagnostics` helper around a caller-owned `Ref<ReadonlyArray<Warning>>`. */
17
+ export declare const makeDiagnostics: (ref: Ref.Ref<ReadonlyArray<Warning>>) => Diagnostics;
18
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1,14 @@
1
+ /** Per-scope append-only diagnostics buffer for settings/lockfile/scanner warnings. */
2
+ import * as Effect from "effect/Effect";
3
+ import * as Ref from "effect/Ref";
4
+ /** Build a `Diagnostics` helper around a caller-owned `Ref<ReadonlyArray<Warning>>`. */
5
+ export const makeDiagnostics = (ref) => ({
6
+ append: Effect.fn("workspace.read-model.diagnostics.append")(function* (warning) {
7
+ yield* Ref.update(ref, (current) => [...current, warning]);
8
+ }),
9
+ snapshot: Effect.gen(function* () {
10
+ const current = yield* Ref.get(ref);
11
+ return current;
12
+ }).pipe(Effect.withSpan("workspace.read-model.diagnostics.snapshot")),
13
+ });
14
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1,5 @@
1
+ /** Discovery helpers that operate on arbitrary source directories. */
2
+ export { getPriorityDirectories, skillsInDir, type DiscoveredSkill, type DiscoveryOptions, } from "./skills.js";
3
+ export { parsePluginManifests } from "./plugin-manifests.js";
4
+ export { scanAgentSubagentFiles, scanAllSubagentFiles, type AgentSubagentSummary, type DetectedSubagentFile, } from "./subagents.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,5 @@
1
+ /** Discovery helpers that operate on arbitrary source directories. */
2
+ export { getPriorityDirectories, skillsInDir, } from "./skills.js";
3
+ export { parsePluginManifests } from "./plugin-manifests.js";
4
+ export { scanAgentSubagentFiles, scanAllSubagentFiles, } from "./subagents.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Plugin manifest parsing for skill discovery.
3
+ *
4
+ * Parses .claude-plugin/marketplace.json and .claude-plugin/plugin.json
5
+ * to discover explicitly declared skill directories.
6
+ */
7
+ import * as FileSystem from "effect/FileSystem";
8
+ import * as Path from "effect/Path";
9
+ import * as Effect from "effect/Effect";
10
+ /**
11
+ * Parse plugin manifests and return validated skill parent directories.
12
+ * All paths are validated to be within basePath.
13
+ * Errors are silently skipped (returns empty array on failure).
14
+ */
15
+ export declare const parsePluginManifests: (basePath: string) => Effect.Effect<ReadonlyArray<string>, never, FileSystem.FileSystem | Path.Path>;
16
+ //# sourceMappingURL=plugin-manifests.d.ts.map
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Plugin manifest parsing for skill discovery.
3
+ *
4
+ * Parses .claude-plugin/marketplace.json and .claude-plugin/plugin.json
5
+ * to discover explicitly declared skill directories.
6
+ */
7
+ import * as FileSystem from "effect/FileSystem";
8
+ import * as Path from "effect/Path";
9
+ import * as Array from "effect/Array";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Option from "effect/Option";
12
+ import * as Result from "effect/Result";
13
+ import * as Schema from "effect/Schema";
14
+ // -----------------------------------------------------------------------------
15
+ // Path Validation
16
+ // -----------------------------------------------------------------------------
17
+ const RelativeManifestPathSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((input) => {
18
+ if (!input.startsWith("./"))
19
+ return "Expected a relative manifest path starting with ./";
20
+ if (input.includes(".."))
21
+ return "Manifest paths must not contain .. segments";
22
+ return undefined;
23
+ })));
24
+ const decodeRelativeManifestPath = Schema.decodeUnknownResult(RelativeManifestPathSchema);
25
+ /**
26
+ * Validate a raw skill path from a manifest.
27
+ * Must start with `./`, must not contain `..`, and must resolve within basePath.
28
+ * Returns the parent directory of the skill path on success.
29
+ */
30
+ const validatePath = (rawPath, basePath, path) => {
31
+ if (Result.isFailure(decodeRelativeManifestPath(rawPath)))
32
+ return Option.none();
33
+ // Resolve and check within basePath
34
+ const resolved = path.resolve(basePath, rawPath);
35
+ const normalizedBase = path.resolve(basePath);
36
+ if (!resolved.startsWith(normalizedBase + path.sep) && resolved !== normalizedBase) {
37
+ return Option.none();
38
+ }
39
+ // Return parent directory of the skill path
40
+ return Option.some(path.dirname(resolved));
41
+ };
42
+ // -----------------------------------------------------------------------------
43
+ // Manifest Parsers
44
+ // -----------------------------------------------------------------------------
45
+ const MarketplacePlugin = Schema.Struct({
46
+ source: Schema.optional(Schema.Unknown),
47
+ skills: Schema.optional(Schema.Array(Schema.String)),
48
+ });
49
+ const MarketplaceManifest = Schema.Struct({
50
+ metadata: Schema.optional(Schema.Struct({ pluginRoot: Schema.optional(Schema.String) })),
51
+ plugins: Schema.Array(MarketplacePlugin),
52
+ });
53
+ const PluginManifest = Schema.Struct({
54
+ skills: Schema.Array(Schema.String),
55
+ });
56
+ /**
57
+ * Read a file and parse as JSON, returning None on any failure.
58
+ */
59
+ const readDecodedJsonFile = (filePath, schema) => Effect.gen(function* () {
60
+ const fs = yield* FileSystem.FileSystem;
61
+ const content = yield* fs.readFileString(filePath).pipe(Effect.option);
62
+ if (Option.isNone(content))
63
+ return Option.none();
64
+ const decode = Schema.decodeUnknownSync(Schema.fromJsonString(schema));
65
+ return yield* Effect.sync(() => {
66
+ try {
67
+ return Option.some(decode(content.value));
68
+ }
69
+ catch {
70
+ return Option.none();
71
+ }
72
+ });
73
+ });
74
+ /**
75
+ * Validate a directory path from a manifest (not a skill path — no dirname).
76
+ * Must start with `./`, must not contain `..`, and must resolve within basePath.
77
+ * Returns the resolved directory path on success.
78
+ */
79
+ const validateDirPath = (rawPath, basePath, path) => {
80
+ if (Result.isFailure(decodeRelativeManifestPath(rawPath)))
81
+ return Option.none();
82
+ const resolved = path.resolve(basePath, rawPath);
83
+ const normalizedBase = path.resolve(basePath);
84
+ if (!resolved.startsWith(normalizedBase + path.sep) && resolved !== normalizedBase) {
85
+ return Option.none();
86
+ }
87
+ return Option.some(resolved);
88
+ };
89
+ /**
90
+ * Resolve a plugin's base directory from its source field and pluginRoot.
91
+ * - string source: must start with `./`, resolve relative to basePath + pluginRoot
92
+ * - omitted source: resolve to basePath + pluginRoot (or basePath if no pluginRoot)
93
+ * - object source: skip (remote plugin)
94
+ */
95
+ const resolvePluginBase = (source, basePath, pluginRoot, path) => {
96
+ const rootBase = pluginRoot ? path.resolve(basePath, pluginRoot) : path.resolve(basePath);
97
+ // Object source → skip plugin
98
+ if (typeof source === "object" && source !== null)
99
+ return Option.none();
100
+ if (typeof source === "string") {
101
+ return validateDirPath(source, rootBase, path);
102
+ }
103
+ // Omitted source → root-level plugin
104
+ return Option.some(rootBase);
105
+ };
106
+ /**
107
+ * Parse .claude-plugin/marketplace.json and return validated skill parent directories.
108
+ *
109
+ * Supports metadata.pluginRoot, per-plugin source (string/omitted/object),
110
+ * per-plugin skills array, and conventional {pluginBase}/skills/ directory.
111
+ */
112
+ const parseMarketplaceJson = (basePath) => Effect.gen(function* () {
113
+ const path = yield* Path.Path;
114
+ const manifestPath = path.join(basePath, ".claude-plugin", "marketplace.json");
115
+ const data = yield* readDecodedJsonFile(manifestPath, MarketplaceManifest);
116
+ if (Option.isNone(data))
117
+ return [];
118
+ const pluginRoot = data.value.metadata?.pluginRoot;
119
+ if (pluginRoot !== undefined && Result.isFailure(decodeRelativeManifestPath(pluginRoot))) {
120
+ return [];
121
+ }
122
+ return data.value.plugins.flatMap((plugin) => {
123
+ const pluginBase = resolvePluginBase(plugin.source, basePath, pluginRoot, path);
124
+ if (Option.isNone(pluginBase))
125
+ return [];
126
+ // Conventional {pluginBase}/skills/ always added
127
+ const conventional = [path.join(pluginBase.value, "skills")];
128
+ // Explicit skill paths transformed via dirname
129
+ const explicit = (plugin.skills ?? []).flatMap((skillPath) => {
130
+ const validated = validatePath(skillPath, pluginBase.value, path);
131
+ return Option.isSome(validated) ? [validated.value] : [];
132
+ });
133
+ return [...conventional, ...explicit];
134
+ });
135
+ });
136
+ /**
137
+ * Parse .claude-plugin/plugin.json and return validated skill parent directories.
138
+ *
139
+ * Expected shape: { skills: string[] }
140
+ */
141
+ const parsePluginJson = (basePath) => Effect.gen(function* () {
142
+ const path = yield* Path.Path;
143
+ const manifestPath = path.join(basePath, ".claude-plugin", "plugin.json");
144
+ const data = yield* readDecodedJsonFile(manifestPath, PluginManifest);
145
+ if (Option.isNone(data))
146
+ return [];
147
+ const validatedPaths = [];
148
+ for (const skillPath of data.value.skills) {
149
+ const validated = validatePath(skillPath, basePath, path);
150
+ if (Option.isSome(validated)) {
151
+ validatedPaths.push(validated.value);
152
+ }
153
+ }
154
+ return validatedPaths;
155
+ });
156
+ // -----------------------------------------------------------------------------
157
+ // Public API
158
+ // -----------------------------------------------------------------------------
159
+ /**
160
+ * Parse plugin manifests and return validated skill parent directories.
161
+ * All paths are validated to be within basePath.
162
+ * Errors are silently skipped (returns empty array on failure).
163
+ */
164
+ export const parsePluginManifests = (basePath) => Effect.gen(function* () {
165
+ const [marketplaceDirs, pluginDirs] = yield* Effect.all([parseMarketplaceJson(basePath), parsePluginJson(basePath)], { concurrency: "unbounded" });
166
+ return Array.dedupe([...marketplaceDirs, ...pluginDirs]);
167
+ });
168
+ //# sourceMappingURL=plugin-manifests.js.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Skill discovery algorithm (3-phase: direct match, priority scan, recursive fallback).
3
+ *
4
+ * The `skillsInDir` function is used by source providers (local, git-hosting)
5
+ * to discover skills within a directory structure.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ import * as FileSystem from "effect/FileSystem";
10
+ import * as Path from "effect/Path";
11
+ import type { Skill } from "@agentxm/registry-protocol/unstable/content/skill-types";
12
+ import * as Effect from "effect/Effect";
13
+ import * as Option from "effect/Option";
14
+ import { SkillDiscoveryRootInvalid } from "../errors.js";
15
+ /**
16
+ * A discovered skill — intermediate result from directory scanning.
17
+ *
18
+ * Does not carry source, version, or gitTreeSha — the caller (provider)
19
+ * enriches with those after discovery.
20
+ */
21
+ export interface DiscoveredSkill {
22
+ readonly type: "skill";
23
+ readonly skill: Skill;
24
+ /** file:// URL to the skill directory */
25
+ readonly location: string;
26
+ }
27
+ /**
28
+ * Options controlling discovery behavior.
29
+ */
30
+ export interface DiscoveryOptions {
31
+ /** Exhaustive recursive search even if root skill found */
32
+ readonly fullDepth: boolean;
33
+ /** Include skills with metadata.internal: "true" */
34
+ readonly includeInternal: boolean;
35
+ }
36
+ /**
37
+ * Derive the full Phase 2 priority directory list.
38
+ *
39
+ * Composition:
40
+ * 1. `.` (searchPath root) — always first, highest priority
41
+ * 2. Non-agent static dirs: skills, skills/.curated, skills/.experimental, skills/.system
42
+ * 3. Agent dirs: unique primary and additional read paths from the AgentDescriptor registry
43
+ */
44
+ export declare const getPriorityDirectories: () => ReadonlyArray<string>;
45
+ /**
46
+ * Discover skills in a directory using a 3-phase algorithm:
47
+ *
48
+ * Phase 1 — Direct match: check if search root itself contains SKILL.md
49
+ * Phase 2 — Priority directory scan: scan well-known directories one level deep
50
+ * Phase 3 — Recursive fallback: bounded DFS when prior phases find nothing or fullDepth is true
51
+ *
52
+ * Skills are deduplicated by name (first-found wins). Internal skills are
53
+ * filtered unless opted in.
54
+ *
55
+ * @experimental This API is unstable and may change without notice.
56
+ */
57
+ export declare const skillsInDir: (basePath: string, subPath: Option.Option<string>, options: DiscoveryOptions) => Effect.Effect<ReadonlyArray<DiscoveredSkill>, SkillDiscoveryRootInvalid, FileSystem.FileSystem | Path.Path>;
58
+ //# sourceMappingURL=skills.d.ts.map