@agentxm/workspace-lint 0.28.12 → 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 (69) hide show
  1. package/dist/src/catalog/index.d.ts +2 -2
  2. package/dist/src/catalog/index.js +7 -7
  3. package/dist/src/catalog/workspace/agents-detected-declared.d.ts +1 -1
  4. package/dist/src/catalog/workspace/agents-projections-stale.d.ts +1 -1
  5. package/dist/src/catalog/workspace/agents-recognized.d.ts +2 -2
  6. package/dist/src/catalog/workspace/agents-recognized.js +1 -1
  7. package/dist/src/catalog/workspace/axm-skill-compatible.d.ts +1 -1
  8. package/dist/src/catalog/workspace/axm-skill-compatible.js +1 -1
  9. package/dist/src/catalog/workspace/axm-skill-declared.d.ts +1 -1
  10. package/dist/src/catalog/workspace/configured-but-not-installed.d.ts +1 -1
  11. package/dist/src/catalog/workspace/desired-state-reconcilable.d.ts +1 -1
  12. package/dist/src/catalog/workspace/desired-state-reconcilable.js +1 -1
  13. package/dist/src/catalog/workspace/helpers/empty.d.ts +1 -1
  14. package/dist/src/catalog/workspace/helpers/finding.d.ts +1 -1
  15. package/dist/src/catalog/workspace/hook-ownership-ambiguous.d.ts +1 -1
  16. package/dist/src/catalog/workspace/initialized.d.ts +1 -1
  17. package/dist/src/catalog/workspace/instructions-agent-supported.d.ts +1 -1
  18. package/dist/src/catalog/workspace/instructions-gitignore-current.d.ts +1 -1
  19. package/dist/src/catalog/workspace/instructions-source-present.d.ts +1 -1
  20. package/dist/src/catalog/workspace/instructions-target-current.d.ts +1 -1
  21. package/dist/src/catalog/workspace/instructions-target-stale.d.ts +1 -1
  22. package/dist/src/catalog/workspace/instructions-target-unowned.d.ts +1 -1
  23. package/dist/src/catalog/workspace/knowledge-state-valid.d.ts +1 -1
  24. package/dist/src/catalog/workspace/lockfile-valid.d.ts +1 -1
  25. package/dist/src/catalog/workspace/managed-file-unowned.d.ts +1 -1
  26. package/dist/src/catalog/workspace/mcps-agent-drift.d.ts +1 -1
  27. package/dist/src/catalog/workspace/mcps-agent-drift.js +3 -2
  28. package/dist/src/catalog/workspace/mcps-agent-orphaned.d.ts +1 -1
  29. package/dist/src/catalog/workspace/mcps-agent-orphaned.js +2 -2
  30. package/dist/src/catalog/workspace/mcps-no-secret-literal.d.ts +1 -1
  31. package/dist/src/catalog/workspace/mcps-transport-exclusivity.d.ts +1 -1
  32. package/dist/src/catalog/workspace/packs-declarations-valid.d.ts +1 -1
  33. package/dist/src/catalog/workspace/packs-dependencies-resolved.d.ts +1 -1
  34. package/dist/src/catalog/workspace/projection-contributors-rendered.d.ts +2 -2
  35. package/dist/src/catalog/workspace/projection-contributors-rendered.js +1 -1
  36. package/dist/src/catalog/workspace/projection-ownership-valid.d.ts +2 -2
  37. package/dist/src/catalog/workspace/projection-ownership-valid.js +1 -1
  38. package/dist/src/catalog/workspace/settings-keys-recognized.d.ts +1 -1
  39. package/dist/src/catalog/workspace/settings-schema-valid.d.ts +1 -1
  40. package/dist/src/catalog/workspace/skills-artifacts-correct.d.ts +1 -1
  41. package/dist/src/catalog/workspace/skills-declarations-valid.d.ts +1 -1
  42. package/dist/src/catalog/workspace/skills-integrity-valid.d.ts +1 -1
  43. package/dist/src/catalog/workspace/skills-lockfile-aligned.d.ts +1 -1
  44. package/dist/src/catalog/workspace/source-endpoints-aligned.d.ts +1 -1
  45. package/dist/src/catalog/workspace-read-model/lint-workspace.d.ts +9 -9
  46. package/dist/src/catalog/workspace-read-model/lint-workspace.js +7 -5
  47. package/dist/src/catalog/workspace-read-model/manifest-json.d.ts +1 -1
  48. package/dist/src/catalog/workspace-read-model/manifest-json.js +1 -1
  49. package/dist/src/catalog/workspace.d.ts +1 -1
  50. package/dist/src/catalog-contexts.d.ts +9 -9
  51. package/dist/src/catalog-contexts.js +7 -7
  52. package/dist/src/cli.d.ts +6 -6
  53. package/dist/src/cli.js +5 -4
  54. package/dist/src/index.d.ts +2 -1
  55. package/dist/src/index.js +3 -0
  56. package/dist/src/json-schema.js +1 -1
  57. package/dist/src/run/lint-workspace.d.ts +144 -0
  58. package/dist/src/run/lint-workspace.js +204 -0
  59. package/dist/src/run/settings.d.ts +2 -2
  60. package/dist/src/run/settings.js +2 -2
  61. package/dist/src/testing.d.ts +153 -0
  62. package/dist/src/testing.js +303 -0
  63. package/dist/src/workspace-context.d.ts +3 -2
  64. package/dist/src/workspace-context.js +1 -1
  65. package/package.json +17 -10
  66. package/dist/src/catalog/workspace-fixtures/fixture-state.d.ts +0 -8
  67. package/dist/src/catalog/workspace-fixtures/fixture-state.js +0 -120
  68. package/dist/src/catalog/workspace-fixtures/interpret-ops.d.ts +0 -11
  69. package/dist/src/catalog/workspace-fixtures/interpret-ops.js +0 -9
@@ -18,13 +18,13 @@
18
18
  * @experimental This API is unstable and may change without notice.
19
19
  * @packageDocumentation
20
20
  */
21
- import { hookRules } from "@agentxm/registry-protocol/unstable/lint/catalog/hook";
22
- import { knowledgeRules } from "@agentxm/registry-protocol/unstable/lint/catalog/knowledge";
23
- import { mcpServerRules } from "@agentxm/registry-protocol/unstable/lint/catalog/mcp-server";
24
- import { packRules } from "@agentxm/registry-protocol/unstable/lint/catalog/pack";
25
- import { ruleRules } from "@agentxm/registry-protocol/unstable/lint/catalog/rule";
26
- import { skillRules } from "@agentxm/registry-protocol/unstable/lint/catalog/skill";
27
- import { subagentRules } from "@agentxm/registry-protocol/unstable/lint/catalog/subagent";
21
+ import { hookRules } from "@agentxm/extension-content/lint";
22
+ import { knowledgeRules } from "@agentxm/extension-content/lint";
23
+ import { mcpServerRules } from "@agentxm/extension-content/lint";
24
+ import { packRules } from "@agentxm/extension-content/lint";
25
+ import { ruleRules } from "@agentxm/extension-content/lint";
26
+ import { skillRules } from "@agentxm/extension-content/lint";
27
+ import { subagentRules } from "@agentxm/extension-content/lint";
28
28
  import { liveOnlyWorkspaceRules, repositoryWorkspaceRules, workspaceRules, } from "./catalog/index.js";
29
29
  /**
30
30
  * Every rule catalog, keyed by group.
package/dist/src/cli.d.ts CHANGED
@@ -21,7 +21,7 @@
21
21
  * 5.9).
22
22
  *
23
23
  * Lint-intent → canonical `Operation` adapter composition happens in the CLI
24
- * handler (`packages/cli/src/root/lint/handler.ts`), which re-resolves each
24
+ * handler (`apps/cli/src/root/lint/handler.ts`), which re-resolves each
25
25
  * intent's `source` via the `resolveConfigured*` helpers and hands the
26
26
  * resulting canonical Operation to the per-extension plan-step builder. The
27
27
  * runner here stays accessor-free.
@@ -30,13 +30,13 @@
30
30
  * @packageDocumentation
31
31
  */
32
32
  import * as Effect from "effect/Effect";
33
- import type { LintConfig } from "@agentxm/registry-protocol/unstable/lint/config";
34
- import { platformCanonicalLintConfig } from "@agentxm/registry-protocol/unstable/lint/config";
35
- import type { Evaluated } from "@agentxm/registry-protocol/unstable/lint/evaluate";
33
+ import type { LintConfig } from "@agentxm/extension-content/lint";
34
+ import { platformCanonicalLintConfig } from "@agentxm/extension-content/lint";
35
+ import type { Evaluated } from "@agentxm/extension-content/lint";
36
36
  import type { LintInput, LintJsonDocument } from "./json-schema.js";
37
- import type { LintFinding, Severity } from "@agentxm/registry-protocol/unstable/lint/rule";
38
- import type { AxmSkillCompatibility } from "@agentxm/extension-workspace";
37
+ import type { LintFinding, Severity } from "@agentxm/extension-content/lint";
39
38
  import { type CatalogContext, type CatalogGroup, type CatalogRuleContexts, type LintView } from "./catalog-contexts.js";
39
+ import { type AxmSkillCompatibility } from "@agentxm/extension-resolution";
40
40
  /**
41
41
  * A single finding annotated with the context that produced it.
42
42
  *
package/dist/src/cli.js CHANGED
@@ -21,7 +21,7 @@
21
21
  * 5.9).
22
22
  *
23
23
  * Lint-intent → canonical `Operation` adapter composition happens in the CLI
24
- * handler (`packages/cli/src/root/lint/handler.ts`), which re-resolves each
24
+ * handler (`apps/cli/src/root/lint/handler.ts`), which re-resolves each
25
25
  * intent's `source` via the `resolveConfigured*` helpers and hands the
26
26
  * resulting canonical Operation to the per-extension plan-step builder. The
27
27
  * runner here stays accessor-free.
@@ -30,10 +30,11 @@
30
30
  * @packageDocumentation
31
31
  */
32
32
  import * as Effect from "effect/Effect";
33
- import { composePath } from "@agentxm/registry-protocol/unstable/lint/compose-path";
34
- import { platformCanonicalLintConfig } from "@agentxm/registry-protocol/unstable/lint/config";
35
- import { evaluateContexts } from "@agentxm/registry-protocol/unstable/lint/evaluate";
33
+ import { composePath } from "@agentxm/extension-content/lint";
34
+ import { platformCanonicalLintConfig } from "@agentxm/extension-content/lint";
35
+ import { evaluateContexts } from "@agentxm/extension-content/lint";
36
36
  import { CATALOG_GROUP_ORDER, lintCatalogsForView, } from "./catalog-contexts.js";
37
+ import {} from "@agentxm/extension-resolution";
37
38
  // -----------------------------------------------------------------------------
38
39
  // Evaluation
39
40
  // -----------------------------------------------------------------------------
@@ -4,8 +4,9 @@ export { LintInputSchema, LintJsonDocumentSchema, LintJsonFindingSchema, type Li
4
4
  export { findingsForProjectionOwnership } from "./catalog/workspace/projection-ownership-valid.js";
5
5
  export { findingsForProjectionExclusions } from "./catalog/workspace/projection-contributors-rendered.js";
6
6
  export { collectRenderedFindings, countFindings, detectPublishGateDrift, evaluateAllCatalogs, renderFindingsText, resolveLintExitCategory, summarizeEvaluations, toLintHumanBlocks, toLintJsonDocument, type FindingCounts, type GroupEvaluations, type LintHumanBlock, type LintHumanDiagnostic, type LintHumanReporter, type LintExitCategory, type LintSummary, type RenderFindingsArgs, type RenderedFinding, } from "./cli.js";
7
- export { allCatalogErrorRuleIds, allCatalogRuleMetadata, allCatalogRuleIds, buildAcquiredInstalledSkillInfo, buildInstalledPackInfo, buildLintWorkspace, buildNativeInstalledSkillInfo, acquiredSkillDisplayRoot, registryNativeSkillDisplayRoot, registryPackDisplayRoot, liveOnlyWorkspaceRules, repositoryWorkspaceRules, workspaceRules, type BuildInstalledPackInfoArgs, type BuildAcquiredInstalledSkillInfoArgs, type BuildInstalledSkillInfoNativeArgs, type BuildLintWorkspaceArgs, type LintWorkspace, type LintWorkspaceView, } from "./catalog/index.js";
7
+ export { allCatalogErrorRuleIds, allCatalogRuleMetadata, allCatalogRuleIds, buildAcquiredInstalledSkillInfo, buildInstalledPackInfo, buildLintWorkspace, buildNativeInstalledSkillInfo, acquiredSkillDisplayRoot, registryNativeSkillDisplayRoot, registryPackDisplayRoot, liveOnlyWorkspaceRules, repositoryWorkspaceRules, workspaceRules, type BuildInstalledPackInfoArgs, type BuildAcquiredInstalledSkillInfoArgs, type BuildInstalledSkillInfoNativeArgs, type BuildLintWorkspaceArgs, type LintWorkspaceBuild, type LintWorkspaceView, } from "./catalog/index.js";
8
8
  export { LintStagingFailed } from "./run/errors.js";
9
9
  export { isolatedGitEnvironment, materializeGitIndexWorkspace, type StagedWorkspace, } from "./run/staged-workspace.js";
10
10
  export { applyDeterminedRepairs, lintConfigFromSettings, loadSettingsDocument, remapLintSummaryPaths, resolveLintRoot, type PathRemapper, } from "./run/settings.js";
11
+ export { LintWorkspace, admitLintRequest, fixLintWorkspace, lintSelectionRoot, queryLintWorkspace, type LintSelection, type LintWorkspaceFailure, type LintWorkspaceRequest, type LintWorkspaceRequirements, type LintWorkspaceResult, } from "./run/lint-workspace.js";
11
12
  //# sourceMappingURL=index.d.ts.map
package/dist/src/index.js CHANGED
@@ -16,4 +16,7 @@ export { allCatalogErrorRuleIds, allCatalogRuleMetadata, allCatalogRuleIds, buil
16
16
  export { LintStagingFailed } from "./run/errors.js";
17
17
  export { isolatedGitEnvironment, materializeGitIndexWorkspace, } from "./run/staged-workspace.js";
18
18
  export { applyDeterminedRepairs, lintConfigFromSettings, loadSettingsDocument, remapLintSummaryPaths, resolveLintRoot, } from "./run/settings.js";
19
+ // The lint application API: admit a request, then report the workspace's
20
+ // facts (or repair the determined ones first).
21
+ export { LintWorkspace, admitLintRequest, fixLintWorkspace, lintSelectionRoot, queryLintWorkspace, } from "./run/lint-workspace.js";
19
22
  //# sourceMappingURL=index.js.map
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import * as Schema from "effect/Schema";
16
16
  import { CATALOG_GROUP_ORDER } from "./catalog-contexts.js";
17
- import { AxmSkillCompatibilitySchema } from "@agentxm/extension-workspace";
17
+ import { AxmSkillCompatibilitySchema } from "@agentxm/extension-resolution";
18
18
  const LintJsonLocationSchema = Schema.Struct({
19
19
  file: Schema.String,
20
20
  line: Schema.optional(Schema.Number),
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Linting a workspace: admitting the request, gathering the facts every rule
3
+ * catalog decides against, and reporting what the workspace actually is.
4
+ *
5
+ * Lint answers one question — is this workspace's state coherent — and it
6
+ * answers it from facts, not from a plan. The facts come from the workspace
7
+ * read model, the shared projection capability, and the content rule
8
+ * catalogs; assembling them here rather than in an adapter is what makes the
9
+ * answer the same however lint is invoked. In particular the reconciliation
10
+ * facts (ownership proofs and realized agent outputs) come from
11
+ * `@agentxm/workspace-projection`, the capability the reconciliation feature
12
+ * also reads them from, so lint and sync cannot disagree about what AXM owns.
13
+ *
14
+ * Two decisions about lint's inputs live here because they are decisions
15
+ * about what lint can honestly report, not about flag grammar: repairing
16
+ * determined state means writing to the working tree, so it cannot be
17
+ * combined with a Git-index view that is a snapshot of something else; and a
18
+ * Git index is a property of a repository, so it cannot be combined with the
19
+ * user scope.
20
+ *
21
+ * @experimental This API is unstable and may change without notice.
22
+ */
23
+ import * as Effect from "effect/Effect";
24
+ import * as FileSystem from "effect/FileSystem";
25
+ import * as Path from "effect/Path";
26
+ import type { WorkspaceScope } from "@agentxm/extension-model/unstable/workspace-scope";
27
+ import { AxmSkillCompatibilityPolicy } from "@agentxm/extension-resolution";
28
+ import { CodingAgentRepository, WorkspaceInvariantFacts } from "@agentxm/workspace-projection";
29
+ import { WorkspaceMutations, acceptedCanonicalObservation } from "@agentxm/workspace-state";
30
+ import { buildLintWorkspace } from "../catalog/index.js";
31
+ import type { LintView } from "../catalog-contexts.js";
32
+ import { type LintExitCategory, type LintSummary } from "../cli.js";
33
+ import type { LintInput, LintJsonDocument } from "../json-schema.js";
34
+ import { LintStagingFailed } from "./errors.js";
35
+ import { applyDeterminedRepairs } from "./settings.js";
36
+ export interface LintWorkspaceRequest {
37
+ /** An explicit workspace directory to lint; the working directory otherwise. */
38
+ readonly path?: string;
39
+ readonly scope: WorkspaceScope;
40
+ readonly view: LintView;
41
+ /** Repair the state whose desired value is already determined, then report. */
42
+ readonly fix: boolean;
43
+ readonly cwd: string;
44
+ readonly userHome: string;
45
+ }
46
+ /**
47
+ * The workspace lint will read, and the view it reads it through. For a
48
+ * Git-index run this names the materialized snapshot rather than the working
49
+ * tree, together with the root findings are reported against.
50
+ */
51
+ export interface LintSelection {
52
+ readonly workspaceRoot: string;
53
+ /** The home the alternate scope's root is validated against. */
54
+ readonly userHome: string;
55
+ readonly scope: WorkspaceScope;
56
+ readonly input: LintInput;
57
+ /** The root findings are reported against, when it differs from the one read. */
58
+ readonly displayWorkspaceRoot?: string;
59
+ readonly fix: boolean;
60
+ }
61
+ /**
62
+ * Admit a lint request: refuse the input combinations lint cannot honestly
63
+ * answer, and materialize the Git index when that is the selected view.
64
+ */
65
+ export declare const admitLintRequest: (request: LintWorkspaceRequest) => Effect.Effect<{
66
+ workspaceRoot: string;
67
+ userHome: string;
68
+ scope: "project";
69
+ input: {
70
+ view: "git-index";
71
+ fingerprint: string;
72
+ };
73
+ displayWorkspaceRoot: string;
74
+ fix: false;
75
+ } | {
76
+ workspaceRoot: string;
77
+ userHome: string;
78
+ scope: "project" | "user";
79
+ input: {
80
+ view: "workspace";
81
+ fingerprint?: never;
82
+ };
83
+ fix: boolean;
84
+ displayWorkspaceRoot?: never;
85
+ }, LintStagingFailed, FileSystem.FileSystem | Path.Path | import("effect/Scope").Scope | import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner>;
86
+ /** The absolute root a selection names, for the workspace layer the run needs. */
87
+ export declare const lintSelectionRoot: (selection: LintSelection) => string & import("effect/Brand").Brand<"AbsolutePath">;
88
+ export interface LintWorkspaceResult {
89
+ /** The machine document: findings, counts, input, and compatibility state. */
90
+ readonly document: LintJsonDocument;
91
+ readonly summary: LintSummary;
92
+ /** The severity verdict before any process mapping. */
93
+ readonly exitCategory: LintExitCategory;
94
+ /** Whether this run passes, under the run's strictness. */
95
+ readonly outcome: "success" | "fail";
96
+ }
97
+ /** Every service a lint run reads the workspace and its projections through. */
98
+ export type LintWorkspaceRequirements = AxmSkillCompatibilityPolicy | CodingAgentRepository | FileSystem.FileSystem | Path.Path | WorkspaceInvariantFacts | WorkspaceMutations;
99
+ /** Every failure a lint run can settle into. */
100
+ export type LintWorkspaceFailure = LintStagingFailed | Effect.Error<ReturnType<typeof buildLintWorkspace>> | Effect.Error<ReturnType<typeof acceptedCanonicalObservation>> | Effect.Error<ReturnType<typeof applyDeterminedRepairs>>;
101
+ /** Report the workspace's facts without changing it. */
102
+ export declare const queryLintWorkspace: (selection: LintSelection, options: {
103
+ readonly strict: boolean;
104
+ }) => Effect.Effect<LintWorkspaceResult, LintWorkspaceFailure, LintWorkspaceRequirements>;
105
+ /**
106
+ * Repair the state whose desired value the workspace already determines, then
107
+ * report what remains. Only determined state is repaired: a target whose
108
+ * content is derived from a canonical source expresses no preference, so
109
+ * regenerating it cannot overwrite a choice.
110
+ */
111
+ export declare const fixLintWorkspace: (selection: LintSelection, options: {
112
+ readonly strict: boolean;
113
+ }) => Effect.Effect<LintWorkspaceResult, LintWorkspaceFailure, LintWorkspaceRequirements>;
114
+ /** The workspace lint use case. */
115
+ export declare const LintWorkspace: {
116
+ readonly admit: (request: LintWorkspaceRequest) => Effect.Effect<{
117
+ workspaceRoot: string;
118
+ userHome: string;
119
+ scope: "project";
120
+ input: {
121
+ view: "git-index";
122
+ fingerprint: string;
123
+ };
124
+ displayWorkspaceRoot: string;
125
+ fix: false;
126
+ } | {
127
+ workspaceRoot: string;
128
+ userHome: string;
129
+ scope: "project" | "user";
130
+ input: {
131
+ view: "workspace";
132
+ fingerprint?: never;
133
+ };
134
+ fix: boolean;
135
+ displayWorkspaceRoot?: never;
136
+ }, LintStagingFailed, FileSystem.FileSystem | Path.Path | import("effect/Scope").Scope | import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner>;
137
+ readonly query: (selection: LintSelection, options: {
138
+ readonly strict: boolean;
139
+ }) => Effect.Effect<LintWorkspaceResult, LintWorkspaceFailure, LintWorkspaceRequirements>;
140
+ readonly fix: (selection: LintSelection, options: {
141
+ readonly strict: boolean;
142
+ }) => Effect.Effect<LintWorkspaceResult, LintWorkspaceFailure, LintWorkspaceRequirements>;
143
+ };
144
+ //# sourceMappingURL=lint-workspace.d.ts.map
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Linting a workspace: admitting the request, gathering the facts every rule
3
+ * catalog decides against, and reporting what the workspace actually is.
4
+ *
5
+ * Lint answers one question — is this workspace's state coherent — and it
6
+ * answers it from facts, not from a plan. The facts come from the workspace
7
+ * read model, the shared projection capability, and the content rule
8
+ * catalogs; assembling them here rather than in an adapter is what makes the
9
+ * answer the same however lint is invoked. In particular the reconciliation
10
+ * facts (ownership proofs and realized agent outputs) come from
11
+ * `@agentxm/workspace-projection`, the capability the reconciliation feature
12
+ * also reads them from, so lint and sync cannot disagree about what AXM owns.
13
+ *
14
+ * Two decisions about lint's inputs live here because they are decisions
15
+ * about what lint can honestly report, not about flag grammar: repairing
16
+ * determined state means writing to the working tree, so it cannot be
17
+ * combined with a Git-index view that is a snapshot of something else; and a
18
+ * Git index is a property of a repository, so it cannot be combined with the
19
+ * user scope.
20
+ *
21
+ * @experimental This API is unstable and may change without notice.
22
+ */
23
+ import * as Effect from "effect/Effect";
24
+ import * as FileSystem from "effect/FileSystem";
25
+ import * as Option from "effect/Option";
26
+ import * as Path from "effect/Path";
27
+ import { buildPackRuleContexts, buildSkillRuleContexts } from "@agentxm/extension-content/lint";
28
+ import { decodeAbsolutePathSync } from "@agentxm/extension-model/unstable/path-types";
29
+ import { AxmSkillCompatibilityPolicy } from "@agentxm/extension-resolution";
30
+ import { CodingAgentRepository, WorkspaceInvariantFacts, expectedProjectionNames, observeAgentOutputs, observeWorkspaceOwnershipIssues, } from "@agentxm/workspace-projection";
31
+ import { WorkspaceMutations, acceptedCanonicalObservation, } from "@agentxm/workspace-state";
32
+ import { buildLintWorkspace } from "../catalog/index.js";
33
+ import { evaluateAllCatalogs, resolveLintExitCategory, summarizeEvaluations, toLintJsonDocument, } from "../cli.js";
34
+ import { LintStagingFailed } from "./errors.js";
35
+ import { applyDeterminedRepairs, lintConfigFromSettings, loadSettingsDocument, remapLintSummaryPaths, resolveLintRoot, } from "./settings.js";
36
+ import { materializeGitIndexWorkspace } from "./staged-workspace.js";
37
+ /**
38
+ * Admit a lint request: refuse the input combinations lint cannot honestly
39
+ * answer, and materialize the Git index when that is the selected view.
40
+ */
41
+ export const admitLintRequest = (request) => Effect.gen(function* () {
42
+ if (request.fix && request.view === "git-index") {
43
+ return yield* new LintStagingFailed({
44
+ category: "validation",
45
+ detail: "--fix cannot be combined with --view git-index because the index snapshot is not the working tree",
46
+ });
47
+ }
48
+ if (request.view === "git-index" && request.scope === "user") {
49
+ return yield* new LintStagingFailed({
50
+ category: "validation",
51
+ detail: "--view git-index cannot be combined with --scope user because Git indexes are project-scoped",
52
+ });
53
+ }
54
+ if (request.view === "git-index") {
55
+ const snapshot = yield* materializeGitIndexWorkspace(request.path ?? request.cwd, {
56
+ selectRepositoryRoot: request.path === undefined,
57
+ });
58
+ return {
59
+ workspaceRoot: snapshot.workspaceRoot,
60
+ userHome: request.userHome,
61
+ scope: "project",
62
+ input: { view: "git-index", fingerprint: snapshot.fingerprint },
63
+ displayWorkspaceRoot: snapshot.displayWorkspaceRoot,
64
+ fix: false,
65
+ };
66
+ }
67
+ return {
68
+ workspaceRoot: resolveLintRoot({
69
+ pathArg: request.path === undefined ? Option.none() : Option.some(request.path),
70
+ scope: request.scope,
71
+ cwd: request.cwd,
72
+ userHome: request.userHome,
73
+ }),
74
+ userHome: request.userHome,
75
+ scope: request.scope,
76
+ input: { view: "workspace" },
77
+ fix: request.fix,
78
+ };
79
+ });
80
+ /** The absolute root a selection names, for the workspace layer the run needs. */
81
+ export const lintSelectionRoot = (selection) => decodeAbsolutePathSync(selection.workspaceRoot);
82
+ const runLint = (selection, options) => Effect.gen(function* () {
83
+ const fileSystem = yield* FileSystem.FileSystem;
84
+ const path = yield* Path.Path;
85
+ const workspace = yield* WorkspaceMutations;
86
+ const agentRepository = yield* CodingAgentRepository;
87
+ const axmSkillCompatibilityPolicy = yield* AxmSkillCompatibilityPolicy;
88
+ const invariantFacts = yield* WorkspaceInvariantFacts;
89
+ const settings = yield* loadSettingsDocument(selection.workspaceRoot, selection.scope);
90
+ // Repair before observing, so the report reflects the reconciled state.
91
+ if (selection.fix) {
92
+ yield* applyDeterminedRepairs({
93
+ workspaceRoot: selection.workspaceRoot,
94
+ scope: selection.scope,
95
+ settings,
96
+ });
97
+ }
98
+ const config = lintConfigFromSettings(settings);
99
+ const userHome = selection.scope === "user" ? selection.workspaceRoot : selection.userHome;
100
+ const { rule: workspaceContext, view } = yield* buildLintWorkspace({
101
+ platform: { fs: fileSystem, path },
102
+ workspaceRoot: selection.workspaceRoot,
103
+ userHome,
104
+ scope: selection.scope,
105
+ gitIndexView: selection.input.view === "git-index",
106
+ axmSkillCompatibilityPolicy,
107
+ owner: workspace.getConfiguredOwner().pipe(Effect.catch(() => Effect.succeed(Option.none()))),
108
+ projections: { facts: invariantFacts.projectionFacts },
109
+ });
110
+ // Reconciliation facts: what AXM owns, and what it realized for the agents
111
+ // this workspace configures. Both come from the shared projection
112
+ // capability, never from the reconciliation feature.
113
+ const configuredAgents = yield* workspace.getConfiguredAgents();
114
+ const skillOwnershipRoots = workspace.layout.scope === "project"
115
+ ? [workspace.layout.acquiredRoot, workspace.layout.authoredRoot("skill")]
116
+ : [workspace.layout.acquiredRoot];
117
+ const ownership = yield* observeWorkspaceOwnershipIssues({
118
+ workspaceRoot: workspace.baseDir,
119
+ scope: workspace.scope,
120
+ configuredAgentIds: new Set(configuredAgents),
121
+ skillOwnershipRoots,
122
+ });
123
+ const desiredGraph = yield* workspace.getDesiredStateGraph();
124
+ const materializationAgentIds = new Set((yield* agentRepository.getMaterializationAgents()).map(({ id }) => id));
125
+ const agentOutputs = yield* observeAgentOutputs({
126
+ workspaceRoot: workspace.baseDir,
127
+ scope: workspace.scope,
128
+ desiredAgentIds: materializationAgentIds,
129
+ expectedNames: expectedProjectionNames(desiredGraph),
130
+ skillOwnershipRoots,
131
+ });
132
+ const canonicalObservations = Effect.gen(function* () {
133
+ const graph = yield* workspace.getDesiredStateGraph();
134
+ return yield* Effect.forEach(graph.nodes, (node) => acceptedCanonicalObservation({
135
+ workspace,
136
+ type: node.type,
137
+ name: node.name,
138
+ }).pipe(Effect.flatMap((accepted) => Option.isNone(accepted)
139
+ ? new LintStagingFailed({
140
+ category: "internal",
141
+ detail: `Desired extension disappeared while linting: ${node.type}:${node.name}`,
142
+ })
143
+ : Effect.succeed({ desired: node, observation: accepted.value.observation }))), { concurrency: 16 });
144
+ }).pipe(Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.provideService(Path.Path, path));
145
+ const evaluations = yield* evaluateAllCatalogs({
146
+ view: selection.input.view,
147
+ contexts: {
148
+ skill: buildSkillRuleContexts(view),
149
+ pack: buildPackRuleContexts(view),
150
+ subagent: view.subagentContexts,
151
+ "mcp-server": view.mcpServerContexts,
152
+ rule: view.ruleContexts,
153
+ hook: view.hookContexts,
154
+ knowledge: view.knowledgeContexts,
155
+ workspace: [
156
+ {
157
+ ...workspaceContext,
158
+ ownership: Effect.succeed(ownership),
159
+ agentOutputs: Effect.succeed(agentOutputs),
160
+ health: {
161
+ desiredState: workspace.getDesiredStateGraph(),
162
+ canonicalObservations,
163
+ },
164
+ },
165
+ ],
166
+ },
167
+ config,
168
+ });
169
+ const rawSummary = summarizeEvaluations(evaluations, config);
170
+ const summary = selection.displayWorkspaceRoot === undefined
171
+ ? rawSummary
172
+ : remapLintSummaryPaths(rawSummary, selection.workspaceRoot, selection.displayWorkspaceRoot, path);
173
+ const axmSkillCompatibility = workspaceContext.axmSkillCompatibility === undefined
174
+ ? undefined
175
+ : Option.getOrUndefined(Option.flatten(yield* workspaceContext.axmSkillCompatibility.pipe(Effect.option)));
176
+ const exitCategory = summary.exitCategory;
177
+ const outcome = resolveLintExitCategory({ category: exitCategory, strict: options.strict });
178
+ return {
179
+ document: toLintJsonDocument({
180
+ summary,
181
+ input: selection.input,
182
+ ...(axmSkillCompatibility === undefined ? {} : { axmSkillCompatibility }),
183
+ }),
184
+ summary,
185
+ exitCategory,
186
+ outcome,
187
+ };
188
+ });
189
+ /** Report the workspace's facts without changing it. */
190
+ export const queryLintWorkspace = (selection, options) => runLint({ ...selection, fix: false }, options);
191
+ /**
192
+ * Repair the state whose desired value the workspace already determines, then
193
+ * report what remains. Only determined state is repaired: a target whose
194
+ * content is derived from a canonical source expresses no preference, so
195
+ * regenerating it cannot overwrite a choice.
196
+ */
197
+ export const fixLintWorkspace = (selection, options) => runLint({ ...selection, fix: true }, options);
198
+ /** The workspace lint use case. */
199
+ export const LintWorkspace = {
200
+ admit: admitLintRequest,
201
+ query: queryLintWorkspace,
202
+ fix: fixLintWorkspace,
203
+ };
204
+ //# sourceMappingURL=lint-workspace.js.map
@@ -11,7 +11,7 @@ import * as Effect from "effect/Effect";
11
11
  import * as FileSystem from "effect/FileSystem";
12
12
  import * as Option from "effect/Option";
13
13
  import * as Path from "effect/Path";
14
- import type { LintConfig } from "@agentxm/registry-protocol/unstable/lint/config";
14
+ import type { LintConfig } from "@agentxm/extension-content/lint";
15
15
  import { type Settings } from "@agentxm/workspace-state";
16
16
  import { type WorkspaceScope } from "@agentxm/extension-model/unstable/workspace-scope";
17
17
  import type { LintSummary } from "../cli.js";
@@ -59,5 +59,5 @@ export declare const applyDeterminedRepairs: (args: {
59
59
  readonly workspaceRoot: string;
60
60
  readonly scope: WorkspaceScope;
61
61
  readonly settings: Option.Option<Settings>;
62
- }) => Effect.Effect<void, import("@agentxm/extension-workspace").InstructionMaintenanceFailure, FileSystem.FileSystem | Path.Path>;
62
+ }) => Effect.Effect<void, import("@agentxm/workspace-projection").InstructionMaintenanceFailure, FileSystem.FileSystem | Path.Path>;
63
63
  //# sourceMappingURL=settings.d.ts.map
@@ -14,8 +14,8 @@ import * as Option from "effect/Option";
14
14
  import * as Path from "effect/Path";
15
15
  import * as Result from "effect/Result";
16
16
  import * as Schema from "effect/Schema";
17
- import { reconcileInstructionTargets, resolveInstructionsConfig, } from "@agentxm/extension-workspace";
18
- import { composePath } from "@agentxm/registry-protocol/unstable/lint/compose-path";
17
+ import { reconcileInstructionTargets, resolveInstructionsConfig, } from "@agentxm/workspace-projection";
18
+ import { composePath } from "@agentxm/extension-content/lint";
19
19
  import { AXM_DIR_NAME, SettingsSchema, USER_WORKSPACE_DIRECTORY, } from "@agentxm/workspace-state";
20
20
  import {} from "@agentxm/extension-model/unstable/workspace-scope";
21
21
  const remapAbsolutePath = (value, sourceRoot, displayRoot, path) => {
@@ -0,0 +1,153 @@
1
+ /**
2
+ * @agentxm/workspace-lint deterministic test fixtures.
3
+ *
4
+ * A lint run reads a real workspace through the state, agent-repository and
5
+ * invariant-fact services, so a fixture here composes those over a throwaway
6
+ * directory rather than answering for them. What it does supply is the two
7
+ * things a lint example cannot state for itself without becoming brittle: a
8
+ * configured rule set in which exactly one catalog rule is live, so no
9
+ * unrelated finding can decide the scenario, and a workspace whose files are
10
+ * written as the product writes them.
11
+ *
12
+ * `ProjectionParticipants` stays in the layer's requirements on purpose. Which
13
+ * extension types contribute projections is a fact this package may not
14
+ * invent — `@agentxm/workspace-lint` does not depend on the materialization
15
+ * managers — so the caller states it, either with the real registry from
16
+ * `@agentxm/extension-materialization/live` or with a deliberate stand-in from
17
+ * `@agentxm/workspace-projection/testing`.
18
+ *
19
+ * Production source never imports this module.
20
+ *
21
+ * @experimental This API is unstable and may change without notice.
22
+ * @packageDocumentation
23
+ */
24
+ import type * as FileSystem from "effect/FileSystem";
25
+ import * as Layer from "effect/Layer";
26
+ import type * as Path from "effect/Path";
27
+ import type * as HttpClient from "effect/unstable/http/HttpClient";
28
+ import type { ProjectionParticipants } from "@agentxm/workspace-projection";
29
+ import type { WorkspaceMutationsError } from "@agentxm/workspace-state";
30
+ import type { LintWorkspaceRequirements } from "./run/lint-workspace.js";
31
+ /** The severities a workspace may configure a catalog rule at. */
32
+ export type ConfiguredLintSeverity = "off" | "info" | "warn" | "error";
33
+ /**
34
+ * A rule configuration in which exactly one catalog rule is live and every
35
+ * other is `off`. A lint example that asserts on one rule's finding needs
36
+ * this: without it an unrelated rule's finding can decide the run's exit
37
+ * category and the example proves nothing about its own subject.
38
+ *
39
+ * Pass `undefined` for `severity` to leave the named rule at its catalog
40
+ * default while every other rule is silenced. An unknown rule id throws, so a
41
+ * renamed rule fails the example rather than silently matching nothing.
42
+ */
43
+ export declare const isolatedLintRules: (ruleId: string, severity: ConfiguredLintSeverity | undefined) => Readonly<Record<string, ConfiguredLintSeverity>>;
44
+ export interface LintWorkspaceFixtureOptions {
45
+ /** Settings document written to `axm.json`; `agents` defaults to empty. */
46
+ readonly settings?: Readonly<Record<string, unknown>>;
47
+ /** Files written into the workspace root, keyed by workspace-relative path. */
48
+ readonly files?: Readonly<Record<string, string>>;
49
+ /** The CLI version the official-skill compatibility policy evaluates against. */
50
+ readonly cliVersion?: string | null;
51
+ }
52
+ /**
53
+ * Every workspace-facing service a lint run reads through. The platform
54
+ * services stay the caller's, so a test runs lint over the same file system
55
+ * the product runs on; `ProjectionParticipants` stays in the requirements
56
+ * because which extension types contribute projections is not this package's
57
+ * fact to invent.
58
+ */
59
+ export type LintWorkspaceServices = Layer.Layer<Exclude<LintWorkspaceRequirements, FileSystem.FileSystem | Path.Path>, WorkspaceMutationsError, FileSystem.FileSystem | Path.Path | HttpClient.HttpClient | ProjectionParticipants>;
60
+ export interface LintWorkspaceFixture {
61
+ readonly root: string;
62
+ readonly writeFile: (relativePath: string, contents: string) => void;
63
+ readonly readFile: (relativePath: string) => string;
64
+ readonly exists: (relativePath: string) => boolean;
65
+ readonly remove: (relativePath: string) => void;
66
+ /** Rewrites `axm.json` wholesale, as an operator editing settings would. */
67
+ readonly writeSettings: (settings: Readonly<Record<string, unknown>>) => void;
68
+ /**
69
+ * Link one workspace path at another, the way the product realizes an
70
+ * extension into an agent's directory: a relative directory symlink from
71
+ * the agent entry to the canonical source.
72
+ */
73
+ readonly link: (linkPath: string, targetPath: string) => void;
74
+ /**
75
+ * Every entry under the workspace, sorted by path: a file as its contents, a
76
+ * directory as `directory`, a symbolic link as `symlink:<target>`. A lint
77
+ * run that changed anything — including a link's target — changes this.
78
+ */
79
+ readonly snapshot: () => ReadonlyArray<readonly [string, string]>;
80
+ /** Every workspace-facing service a lint run over this workspace reads through. */
81
+ readonly layer: LintWorkspaceServices;
82
+ readonly cleanup: () => void;
83
+ }
84
+ /**
85
+ * Every workspace-facing service a lint run over one root reads through. A
86
+ * Git-index run lints a materialized snapshot rather than the working tree, so
87
+ * the root a run's services are built over is decided by the admitted
88
+ * selection, not by the directory a fixture created.
89
+ */
90
+ export declare const lintWorkspaceServices: (args: {
91
+ readonly workspaceRoot: string;
92
+ /** The CLI version the official-skill compatibility policy evaluates against. */
93
+ readonly cliVersion?: string | null;
94
+ }) => LintWorkspaceServices;
95
+ /** A throwaway initialized workspace with the services a lint run reads it through. */
96
+ export declare const makeLintWorkspace: (options?: LintWorkspaceFixtureOptions) => LintWorkspaceFixture;
97
+ /** Where a project workspace keeps the official AXM skill's canonical package. */
98
+ export declare const OFFICIAL_AXM_SKILL_PACKAGE_ROOT = "agent_extensions/agentxm/@agentxm/skills/axm";
99
+ /** Where a workspace that authors its own `axm` skill keeps it. */
100
+ export declare const AUTHORED_AXM_SKILL_PACKAGE_ROOT = "skills/axm";
101
+ /** The agent directory entry `claude-code` reads a project skill from. */
102
+ export declare const CLAUDE_CODE_SKILLS_DIR = ".claude/skills";
103
+ /**
104
+ * The states lint distinguishes for the official AXM skill: not declared at
105
+ * all, declared under another owner's name, or declared as the official skill
106
+ * and then missing, registry-sourced at an incompatible release,
107
+ * version-skewed, workspace-authored, compatible (including a prerelease
108
+ * inside the declared range), or unreadable.
109
+ */
110
+ export type OfficialAxmSkillState = "undeclared" | "non-official" | "official-missing" | "official-registry" | "official-skewed" | "official-authored" | "official-compatible" | "official-compatible-prerelease" | "official-unreadable";
111
+ /** The two rules that decide what lint says about the official AXM skill. */
112
+ export declare const OFFICIAL_AXM_SKILL_RULE_IDS: readonly ["workspace/axm-skill-declared", "workspace/axm-skill-compatible"];
113
+ /**
114
+ * A rule configuration in which only the two official-skill rules are live.
115
+ * An official-skill example is about what lint concludes from the declaration
116
+ * and the installed package, so no unrelated rule may decide its run.
117
+ */
118
+ export declare const isolateOfficialAxmSkillRules: () => Readonly<Record<string, ConfiguredLintSeverity>>;
119
+ /** The CLI release every official-skill fixture but the prerelease one runs as. */
120
+ export declare const FIXTURE_CLI_VERSION = "1.2.3";
121
+ /** The prerelease CLI release the in-range prerelease fixture runs as. */
122
+ export declare const FIXTURE_PRERELEASE_CLI_VERSION = "1.3.0-preview.1";
123
+ /** The canonical package files a materialized official AXM skill is made of. */
124
+ export declare const officialAxmSkillPackage: (args: {
125
+ readonly packageRoot: string;
126
+ readonly version: string;
127
+ /** `null` writes no `SKILL.md` at all, as a truncated materialization leaves it. */
128
+ readonly metadata: {
129
+ readonly cliVersion: string;
130
+ readonly cliVersionRange: string;
131
+ } | null;
132
+ readonly withSkillMd?: boolean;
133
+ }) => Readonly<Record<string, string>>;
134
+ /** A lint workspace whose official AXM skill is arranged in one named state. */
135
+ export interface OfficialAxmSkillWorkspace extends LintWorkspaceFixture {
136
+ /** The CLI release this workspace's compatibility policy evaluates against. */
137
+ readonly cliVersion: string;
138
+ }
139
+ export interface OfficialAxmSkillWorkspaceOptions {
140
+ /** Settings merged over the state's own; `lint.rules` belongs here. */
141
+ readonly settings?: Readonly<Record<string, unknown>>;
142
+ /** Coding agents the workspace configures. Defaults to `claude-code`. */
143
+ readonly agents?: ReadonlyArray<string>;
144
+ /** Extra files written into the workspace root. */
145
+ readonly files?: Readonly<Record<string, string>>;
146
+ }
147
+ /**
148
+ * A throwaway workspace whose official AXM skill is arranged in the named
149
+ * state, with the compatibility policy pinned to the CLI release that state
150
+ * is about.
151
+ */
152
+ export declare const makeOfficialAxmSkillWorkspace: (state: OfficialAxmSkillState, options?: OfficialAxmSkillWorkspaceOptions) => OfficialAxmSkillWorkspace;
153
+ //# sourceMappingURL=testing.d.ts.map