@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,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lockfile module for managing project-root `axm-lock.yaml` or the user-scope
|
|
3
|
+
* `axm-lock.yaml` (YAML format).
|
|
4
|
+
*
|
|
5
|
+
* Provides functions to read, write, and update accepted external resolutions.
|
|
6
|
+
*
|
|
7
|
+
* @experimental This API is unstable and may change without notice.
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { LOCKFILE_NAME } from "@agentxm/extension-model/unstable/workspace-files";
|
|
11
|
+
import * as FileSystem from "effect/FileSystem";
|
|
12
|
+
import * as Path from "effect/Path";
|
|
13
|
+
import * as Effect from "effect/Effect";
|
|
14
|
+
import * as Schema from "effect/Schema";
|
|
15
|
+
import * as Semaphore from "effect/Semaphore";
|
|
16
|
+
import YAML from "yaml";
|
|
17
|
+
import { recordFootprint } from "../workspace/footprint-recorder.js";
|
|
18
|
+
import { sweepStaleAtomicWriteTemps, writeFileAtomic } from "../utils/atomic-write.js";
|
|
19
|
+
import { LockfileValidationError, LockfileWriteError } from "./errors.js";
|
|
20
|
+
import { LOCKFILE_VERSION, LockfileSchema } from "./schema.js";
|
|
21
|
+
// -----------------------------------------------------------------------------
|
|
22
|
+
// Constants
|
|
23
|
+
// -----------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Filename for the lockfile.
|
|
26
|
+
*
|
|
27
|
+
* @experimental This API is unstable and may change without notice.
|
|
28
|
+
*/
|
|
29
|
+
// eslint-disable-next-line no-restricted-syntax -- Process-owned keys are bounded by lockfiles touched during this one CLI invocation.
|
|
30
|
+
const lockSemaphores = new Map();
|
|
31
|
+
// -----------------------------------------------------------------------------
|
|
32
|
+
// Internal Helpers
|
|
33
|
+
// -----------------------------------------------------------------------------
|
|
34
|
+
const lockfilePathFor = (path, axmDir) => path.join(axmDir, LOCKFILE_NAME);
|
|
35
|
+
const inProcessSemaphoreFor = (key) => {
|
|
36
|
+
const existing = lockSemaphores.get(key);
|
|
37
|
+
if (existing !== undefined)
|
|
38
|
+
return existing;
|
|
39
|
+
const created = Semaphore.makeUnsafe(1);
|
|
40
|
+
lockSemaphores.set(key, created);
|
|
41
|
+
return created;
|
|
42
|
+
};
|
|
43
|
+
const ensureLockfileParent = (lockfilePath) => Effect.gen(function* () {
|
|
44
|
+
const fs = yield* FileSystem.FileSystem;
|
|
45
|
+
const path = yield* Path.Path;
|
|
46
|
+
const parent = path.dirname(lockfilePath);
|
|
47
|
+
yield* fs
|
|
48
|
+
.makeDirectory(parent, { recursive: true })
|
|
49
|
+
.pipe(Effect.mapError((cause) => new LockfileWriteError({ path: parent, step: "mkdir", cause })));
|
|
50
|
+
});
|
|
51
|
+
const encodeLockfileYaml = (lockfilePath, lockfile) => Effect.gen(function* () {
|
|
52
|
+
const encoded = yield* Effect.try({
|
|
53
|
+
try: () => Schema.encodeSync(LockfileSchema)(lockfile),
|
|
54
|
+
catch: (cause) => new LockfileWriteError({ path: lockfilePath, step: "encode", cause }),
|
|
55
|
+
});
|
|
56
|
+
return yield* Effect.try({
|
|
57
|
+
try: () => YAML.stringify(encoded),
|
|
58
|
+
catch: (cause) => new LockfileWriteError({ path: lockfilePath, step: "serialize", cause }),
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
const patchOptionalMap = (fresh, base, next) => {
|
|
62
|
+
if (base === undefined && next === undefined)
|
|
63
|
+
return fresh === undefined ? undefined : { ...fresh };
|
|
64
|
+
const patched = { ...(fresh ?? {}) };
|
|
65
|
+
for (const key of Object.keys(base ?? {})) {
|
|
66
|
+
if (!Object.hasOwn(next ?? {}, key)) {
|
|
67
|
+
delete patched[key];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
for (const [key, value] of Object.entries(next ?? {})) {
|
|
71
|
+
patched[key] = value;
|
|
72
|
+
}
|
|
73
|
+
return Object.keys(patched).length === 0 ? undefined : patched;
|
|
74
|
+
};
|
|
75
|
+
const patchRequiredMap = (fresh, base, next) => {
|
|
76
|
+
const patched = { ...fresh };
|
|
77
|
+
for (const key of Object.keys(base)) {
|
|
78
|
+
if (!Object.hasOwn(next, key)) {
|
|
79
|
+
delete patched[key];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const [key, value] of Object.entries(next)) {
|
|
83
|
+
patched[key] = value;
|
|
84
|
+
}
|
|
85
|
+
return patched;
|
|
86
|
+
};
|
|
87
|
+
const applyLockfileSnapshotPatch = (fresh, base, next) => {
|
|
88
|
+
const subagents = patchOptionalMap(fresh.subagents, base.subagents, next.subagents);
|
|
89
|
+
const mcpServers = patchOptionalMap(fresh.mcpServers, base.mcpServers, next.mcpServers);
|
|
90
|
+
const rules = patchOptionalMap(fresh.rules, base.rules, next.rules);
|
|
91
|
+
const hooks = patchOptionalMap(fresh.hooks, base.hooks, next.hooks);
|
|
92
|
+
const knowledge = patchOptionalMap(fresh.knowledge, base.knowledge, next.knowledge);
|
|
93
|
+
const packs = patchOptionalMap(fresh.packs, base.packs, next.packs);
|
|
94
|
+
return {
|
|
95
|
+
lockfileVersion: LOCKFILE_VERSION,
|
|
96
|
+
skills: patchRequiredMap(fresh.skills, base.skills, next.skills),
|
|
97
|
+
...(subagents !== undefined ? { subagents } : {}),
|
|
98
|
+
...(mcpServers !== undefined ? { mcpServers } : {}),
|
|
99
|
+
...(rules !== undefined ? { rules } : {}),
|
|
100
|
+
...(hooks !== undefined ? { hooks } : {}),
|
|
101
|
+
...(knowledge !== undefined ? { knowledge } : {}),
|
|
102
|
+
...(packs !== undefined ? { packs } : {}),
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
const readLockfileIfPresent = (lockfilePath) => Effect.gen(function* () {
|
|
106
|
+
const fs = yield* FileSystem.FileSystem;
|
|
107
|
+
const exists = yield* fs
|
|
108
|
+
.exists(lockfilePath)
|
|
109
|
+
.pipe(Effect.mapError((cause) => new LockfileValidationError({ path: lockfilePath, step: "check", cause })));
|
|
110
|
+
if (!exists)
|
|
111
|
+
return undefined;
|
|
112
|
+
const raw = yield* fs
|
|
113
|
+
.readFileString(lockfilePath)
|
|
114
|
+
.pipe(Effect.mapError((cause) => new LockfileValidationError({ path: lockfilePath, step: "read", cause })));
|
|
115
|
+
const parsed = yield* Effect.try({
|
|
116
|
+
try: () => YAML.parse(raw),
|
|
117
|
+
catch: (cause) => new LockfileValidationError({ path: lockfilePath, step: "parse", cause }),
|
|
118
|
+
});
|
|
119
|
+
const decoded = yield* Schema.decodeUnknownEffect(LockfileSchema)(parsed, {
|
|
120
|
+
onExcessProperty: "error",
|
|
121
|
+
}).pipe(Effect.mapError((cause) => new LockfileValidationError({ path: lockfilePath, step: "decode", cause })));
|
|
122
|
+
return decoded;
|
|
123
|
+
});
|
|
124
|
+
const withLockfileLock = (lockfilePath, effect) => Effect.gen(function* () {
|
|
125
|
+
const path = yield* Path.Path;
|
|
126
|
+
const key = path.resolve(lockfilePath);
|
|
127
|
+
const semaphore = inProcessSemaphoreFor(key);
|
|
128
|
+
// Cross-process exclusion belongs to the workspace transaction. This
|
|
129
|
+
// semaphore only serializes multiple updates in one runtime so the
|
|
130
|
+
// read/patch/write helper cannot race with itself.
|
|
131
|
+
return yield* semaphore.withPermits(1)(effect);
|
|
132
|
+
});
|
|
133
|
+
const writeLockfileUnlocked = (lockfilePath, lockfile) => Effect.gen(function* () {
|
|
134
|
+
const fs = yield* FileSystem.FileSystem;
|
|
135
|
+
const yamlContent = yield* encodeLockfileYaml(lockfilePath, lockfile);
|
|
136
|
+
const existed = yield* fs.exists(lockfilePath).pipe(Effect.orElseSucceed(() => true));
|
|
137
|
+
yield* sweepStaleAtomicWriteTemps(fs, lockfilePath);
|
|
138
|
+
const written = yield* writeFileAtomic(fs, {
|
|
139
|
+
targetPath: lockfilePath,
|
|
140
|
+
content: yamlContent,
|
|
141
|
+
skipIfUnchanged: "fail-on-read-error",
|
|
142
|
+
mapError: (failure) => new LockfileWriteError({
|
|
143
|
+
path: failure.step === "write-temp" ? failure.tempPath : lockfilePath,
|
|
144
|
+
step: failure.step,
|
|
145
|
+
cause: failure.cause,
|
|
146
|
+
}),
|
|
147
|
+
});
|
|
148
|
+
if (written === "written") {
|
|
149
|
+
yield* recordFootprint({ path: lockfilePath, change: existed ? "modified" : "created" });
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// -----------------------------------------------------------------------------
|
|
153
|
+
// Public Functions
|
|
154
|
+
// -----------------------------------------------------------------------------
|
|
155
|
+
/**
|
|
156
|
+
* Writes the lockfile to the selected scope's `axm-lock.yaml` in YAML format.
|
|
157
|
+
*
|
|
158
|
+
* Creates the containing directory if it does not exist. Writes are serialized by
|
|
159
|
+
* an in-process keyed semaphore plus a best-effort local advisory lock file.
|
|
160
|
+
* Temporary files are removed by scoped finalizer on interruption, and stale
|
|
161
|
+
* temp files from older crashed writers are swept before each write. When the
|
|
162
|
+
* encoded bytes already match, the existing lockfile is left untouched.
|
|
163
|
+
*
|
|
164
|
+
* `writeLockfile` remains a full replacement operation. Call
|
|
165
|
+
* `commitLockfileUpdates` when applying deltas that must reread the latest
|
|
166
|
+
* lockfile state under the advisory lock.
|
|
167
|
+
*
|
|
168
|
+
* @param axmDir - Directory containing the selected scope's lockfile
|
|
169
|
+
* @param lockfile - The lockfile object to write
|
|
170
|
+
* @returns Effect yielding void on success
|
|
171
|
+
*
|
|
172
|
+
* @experimental This API is unstable and may change without notice.
|
|
173
|
+
*/
|
|
174
|
+
export const writeLockfileAtPath = (lockfilePath, lockfile) => Effect.gen(function* () {
|
|
175
|
+
yield* ensureLockfileParent(lockfilePath);
|
|
176
|
+
yield* withLockfileLock(lockfilePath, Effect.gen(function* () {
|
|
177
|
+
yield* writeLockfileUnlocked(lockfilePath, lockfile);
|
|
178
|
+
}));
|
|
179
|
+
});
|
|
180
|
+
export const writeLockfile = (axmDir, lockfile) => Effect.gen(function* () {
|
|
181
|
+
const path = yield* Path.Path;
|
|
182
|
+
yield* writeLockfileAtPath(lockfilePathFor(path, axmDir), lockfile);
|
|
183
|
+
});
|
|
184
|
+
/**
|
|
185
|
+
* Applies lockfile updates in order without writing to disk.
|
|
186
|
+
*
|
|
187
|
+
* @experimental This API is unstable and may change without notice.
|
|
188
|
+
*/
|
|
189
|
+
export const applyLockfileUpdates = (lockfile, updates) => updates.reduce((current, update) => update(current), lockfile);
|
|
190
|
+
/**
|
|
191
|
+
* Applies a batch of lockfile updates and writes the result once.
|
|
192
|
+
*
|
|
193
|
+
* This is intended for sync flows that discover multiple render-hash changes
|
|
194
|
+
* while reconciling managed package targets.
|
|
195
|
+
*
|
|
196
|
+
* @experimental This API is unstable and may change without notice.
|
|
197
|
+
*/
|
|
198
|
+
export const commitLockfileUpdates = (axmDir, lockfile, updates) => Effect.gen(function* () {
|
|
199
|
+
const path = yield* Path.Path;
|
|
200
|
+
const lockfilePath = lockfilePathFor(path, axmDir);
|
|
201
|
+
yield* ensureLockfileParent(lockfilePath);
|
|
202
|
+
const updated = yield* withLockfileLock(lockfilePath, Effect.gen(function* () {
|
|
203
|
+
const current = yield* readLockfileIfPresent(lockfilePath);
|
|
204
|
+
const updated = applyLockfileUpdates(current ?? lockfile, updates);
|
|
205
|
+
yield* writeLockfileUnlocked(lockfilePath, updated);
|
|
206
|
+
return updated;
|
|
207
|
+
}));
|
|
208
|
+
return updated;
|
|
209
|
+
});
|
|
210
|
+
/**
|
|
211
|
+
* Commits a caller-computed lockfile snapshot as an entry-level patch.
|
|
212
|
+
*
|
|
213
|
+
* The caller supplies the base snapshot it read and the next snapshot it
|
|
214
|
+
* computed. The helper rereads the current on-disk lockfile under the advisory
|
|
215
|
+
* lock, applies only the base→next entry changes, then writes once. This keeps
|
|
216
|
+
* independent concurrent updates from dropping each other while preserving
|
|
217
|
+
* explicit entry deletions.
|
|
218
|
+
*
|
|
219
|
+
* @experimental This API is unstable and may change without notice.
|
|
220
|
+
*/
|
|
221
|
+
export const commitLockfileSnapshotUpdateAtPath = (lockfilePath, base, next) => Effect.gen(function* () {
|
|
222
|
+
yield* ensureLockfileParent(lockfilePath);
|
|
223
|
+
const updated = yield* withLockfileLock(lockfilePath, Effect.gen(function* () {
|
|
224
|
+
const current = yield* readLockfileIfPresent(lockfilePath);
|
|
225
|
+
const updated = applyLockfileSnapshotPatch(current ?? base, base, next);
|
|
226
|
+
yield* writeLockfileUnlocked(lockfilePath, updated);
|
|
227
|
+
return updated;
|
|
228
|
+
}));
|
|
229
|
+
return updated;
|
|
230
|
+
});
|
|
231
|
+
export const commitLockfileSnapshotUpdate = (axmDir, base, next) => Effect.gen(function* () {
|
|
232
|
+
const path = yield* Path.Path;
|
|
233
|
+
return yield* commitLockfileSnapshotUpdateAtPath(lockfilePathFor(path, axmDir), base, next);
|
|
234
|
+
});
|
|
235
|
+
//# sourceMappingURL=lockfile.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { LockfileResolvedVersionInvalid } from "./errors.js";
|
|
3
|
+
export declare const validateExactResolvedVersion: (field: string, value: string) => Effect.Effect<void, LockfileResolvedVersionInvalid, never>;
|
|
4
|
+
//# sourceMappingURL=resolved-version.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { VersionSchema } from "@agentxm/extension-model/unstable/version-constraints";
|
|
4
|
+
import { LockfileResolvedVersionInvalid } from "./errors.js";
|
|
5
|
+
const decodeVersion = Schema.decodeUnknownEffect(VersionSchema);
|
|
6
|
+
export const validateExactResolvedVersion = (field, value) => decodeVersion(value).pipe(Effect.asVoid, Effect.mapError((cause) => new LockfileResolvedVersionInvalid({ field, value, cause })));
|
|
7
|
+
//# sourceMappingURL=resolved-version.js.map
|