@agentxm/workspace-operations 0.29.4 → 0.30.1
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/dist/src/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @packageDocumentation
|
|
13
13
|
*/
|
|
14
14
|
export { BlockingClassSchema, defaultOperationPresentation, operationPresentation, presentationOf, ArtifactMechanismSchema, PackMembershipDeltaSchema, ConfirmableConsentSchema, OperationPreconditionSchema, PlanPolicyIdSchema, PlanPolicyIds, PlanRiskConditionSchema, } from "./plan/plan.js";
|
|
15
|
-
export type { ArtifactMechanism, BlockingClass, CompletedJobStep, ConfirmableConsent, ErrorJobStep, ExecutedJob, ExecutedPlan, Job, JobStepArtifact, PackMembershipDelta, JobStepArtifactSource, JobStepArtifactTarget, JobStepResult, Operation, OperationPrecondition, OperationPresentation, Plan, PlanExecutionCapabilities, PlanPolicyId, PlanRiskCondition, PlannedJobStep, ReadyJobStep, RegistryLifecycleEvidence, UnitBlocking, WarnJobStep, } from "./plan/plan.js";
|
|
15
|
+
export type { ArtifactMechanism, BlockingClass, CompletedJobStep, ConfirmableConsent, ErrorJobStep, ExecutedJob, ExecutedPlan, Job, JobStepArtifact, PackMembershipDelta, JobStepArtifactSource, JobStepArtifactTarget, JobStepArtifactReference, JobStepResult, Operation, OperationPrecondition, OperationPresentation, Plan, PlanExecutionCapabilities, PlanPolicyId, PlanRiskCondition, PlannedJobStep, ReadyJobStep, RegistryLifecycleEvidence, UnitBlocking, WarnJobStep, } from "./plan/plan.js";
|
|
16
16
|
export { AtomicityClassSchema, OperationOutcomeSchema, OperationPhaseSchema, UnitDispositionSchema, UnitStateSchema, countUnitStates, declaredAtomicity, deriveOperationOutcome, executedUnits, makeOperationResolution, plannedUnits, unitIdOf, unitsByStableIdentity, } from "./plan/operation-resolution.js";
|
|
17
17
|
export type { AtomicityClass, MakeOperationResolutionArgs, OperationAtomicity, OperationBlock, OperationFootprintEntry, OperationInterruption, OperationOutcome, OperationPhase, OperationRecovery, OperationResolution, ResolvedUnit, UnitDisposition, UnitState, UnitStateCounts, } from "./plan/operation-resolution.js";
|
|
18
18
|
export { OperationJournal, appendResolvedUnit, appendStartedUnit, recordJournalPhase, getOperationJournal, makeOperationJournal, recordOperationJournal, updateOperationJournal, type OperationJournalService, type OperationJournalState, } from "./plan/operation-journal.js";
|
|
@@ -23,9 +23,9 @@ export type OperationHandler<Op, R = never> = (op: Op) => Effect.Effect<JobStepR
|
|
|
23
23
|
/**
|
|
24
24
|
* Apply a plan by iterating jobs and executing step run closures.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* Readiness errors in ordered jobs gate the complete plan. A job may explicitly
|
|
27
|
+
* opt into best-effort execution for independent siblings, including siblings
|
|
28
|
+
* blocked during preparation. Runtime failures still block
|
|
29
29
|
* all subsequent jobs.
|
|
30
30
|
*
|
|
31
31
|
* Never fails — catches StepFailure and converts to error results.
|
|
@@ -36,19 +36,9 @@ const stepEvidence = (step) => ({
|
|
|
36
36
|
const executeStep = (step) => {
|
|
37
37
|
switch (step.readiness) {
|
|
38
38
|
case "error":
|
|
39
|
-
return Effect.succeed({
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
label: step.label,
|
|
43
|
-
result: {
|
|
44
|
-
result: "error",
|
|
45
|
-
message: step.errorMessage,
|
|
46
|
-
error: new StepFailure({
|
|
47
|
-
category: "internal",
|
|
48
|
-
detail: step.errorMessage,
|
|
49
|
-
}),
|
|
50
|
-
},
|
|
51
|
-
});
|
|
39
|
+
return Effect.succeed(blockStep(step, step.errorMessage, {
|
|
40
|
+
class: "precondition-unmet",
|
|
41
|
+
}));
|
|
52
42
|
case "ready":
|
|
53
43
|
return step.run.pipe(Effect.map((result) => ({
|
|
54
44
|
...(step.key === undefined ? {} : { key: step.key }),
|
|
@@ -202,7 +192,8 @@ const executeDependencyAwareJob = (job, observeStart, observeStep) => Effect.gen
|
|
|
202
192
|
export const applyPlan = (plan, options) => Effect.gen(function* () {
|
|
203
193
|
const observeStep = options?.onStepCompleted ?? (() => Effect.void);
|
|
204
194
|
const observeStart = options?.onStepStarted ?? (() => Effect.void);
|
|
205
|
-
const hasReadinessError = plan.jobs.some((job) => job.
|
|
195
|
+
const hasReadinessError = plan.jobs.some((job) => job.executionPolicy !== "best-effort" &&
|
|
196
|
+
job.steps.some((step) => step.readiness === "error"));
|
|
206
197
|
// Any job with an error blocks every later job; the fact travels in a
|
|
207
198
|
// `Ref` because it crosses the job traversal's iteration boundary.
|
|
208
199
|
const blocked = yield* Ref.make(false);
|
|
@@ -6,8 +6,14 @@ import * as Option from "effect/Option";
|
|
|
6
6
|
import { CandidateFingerprintFailed } from "./errors.js";
|
|
7
7
|
const collectArtifactPaths = (plan) => plan.jobs.flatMap((job) => job.steps.flatMap((step) => {
|
|
8
8
|
if (step.artifact === undefined)
|
|
9
|
-
return [];
|
|
10
|
-
return [
|
|
9
|
+
return step.materialPaths ?? [];
|
|
10
|
+
return [
|
|
11
|
+
...(step.materialPaths ?? []),
|
|
12
|
+
step.artifact.path,
|
|
13
|
+
...(step.artifact.targets ?? []).map((target) => target.path),
|
|
14
|
+
...(step.artifact.references ?? []).map((reference) => reference.path),
|
|
15
|
+
...(step.artifact.managedRegions ?? []).map((region) => region.path),
|
|
16
|
+
];
|
|
11
17
|
}));
|
|
12
18
|
const resolveMaterialPaths = (plan, settingsPath, lockPath, baseDir, path) => Array.from(new Set([settingsPath, lockPath, ...(plan.materialPaths ?? []), ...collectArtifactPaths(plan)].map((candidate) => path.resolve(baseDir, candidate)))).sort();
|
|
13
19
|
const fingerprintPath = (target, label, fs, path) => Effect.gen(function* () {
|
|
@@ -57,6 +63,7 @@ const planIdentity = (plan, baseDir, path) => JSON.stringify({
|
|
|
57
63
|
steps: job.steps.map((step) => ({
|
|
58
64
|
key: step.key,
|
|
59
65
|
dependsOn: step.dependsOn,
|
|
66
|
+
materialPaths: step.materialPaths,
|
|
60
67
|
label: step.label,
|
|
61
68
|
readiness: step.readiness,
|
|
62
69
|
artifact: step.artifact,
|
package/dist/src/plan/plan.d.ts
CHANGED
|
@@ -104,6 +104,8 @@ export interface JobStepArtifact {
|
|
|
104
104
|
readonly previousVersion?: string;
|
|
105
105
|
readonly fileCount?: number;
|
|
106
106
|
readonly targets?: ReadonlyArray<JobStepArtifactTarget>;
|
|
107
|
+
/** Observed retained, absent, or unresolved state; these are not write targets. */
|
|
108
|
+
readonly references?: ReadonlyArray<JobStepArtifactReference>;
|
|
107
109
|
readonly agentOutcomes?: ReadonlyArray<ConfiguredAgentOutcome>;
|
|
108
110
|
readonly source?: JobStepArtifactSource;
|
|
109
111
|
readonly managedRegions?: ReadonlyArray<JobStepManagedRegion>;
|
|
@@ -118,10 +120,20 @@ export interface JobStepManagedRegion {
|
|
|
118
120
|
readonly path: string;
|
|
119
121
|
readonly owner: string;
|
|
120
122
|
}
|
|
123
|
+
export interface JobStepArtifactReference {
|
|
124
|
+
readonly path: string;
|
|
125
|
+
readonly state: "retained" | "absent" | "unknown";
|
|
126
|
+
readonly reason: string;
|
|
127
|
+
readonly unitId?: string;
|
|
128
|
+
readonly owner?: string;
|
|
129
|
+
}
|
|
121
130
|
export interface JobStepArtifactTarget {
|
|
122
131
|
readonly path: string;
|
|
123
132
|
readonly change: ArtifactChange;
|
|
124
133
|
readonly agentIds?: ReadonlyArray<string>;
|
|
134
|
+
readonly unitId?: string;
|
|
135
|
+
readonly owner?: string;
|
|
136
|
+
readonly entryName?: string;
|
|
125
137
|
}
|
|
126
138
|
export interface JobStepArtifactSource {
|
|
127
139
|
readonly type: string;
|
|
@@ -154,6 +166,8 @@ export type JobStepResult<Output = never> = {
|
|
|
154
166
|
export interface ReadyJobStep<Requirements = never, Output = never> {
|
|
155
167
|
readonly key?: string;
|
|
156
168
|
readonly dependsOn?: ReadonlyArray<string>;
|
|
169
|
+
/** Read-only inputs fingerprinted with this step, distinct from its write footprint. */
|
|
170
|
+
readonly materialPaths?: ReadonlyArray<string>;
|
|
157
171
|
readonly readiness: "ready";
|
|
158
172
|
readonly label: string;
|
|
159
173
|
readonly message?: string;
|
|
@@ -166,6 +180,8 @@ export interface ReadyJobStep<Requirements = never, Output = never> {
|
|
|
166
180
|
export interface WarnJobStep<Requirements = never, Output = never> {
|
|
167
181
|
readonly key?: string;
|
|
168
182
|
readonly dependsOn?: ReadonlyArray<string>;
|
|
183
|
+
/** Read-only inputs fingerprinted with this step, distinct from its write footprint. */
|
|
184
|
+
readonly materialPaths?: ReadonlyArray<string>;
|
|
169
185
|
readonly readiness: "warn";
|
|
170
186
|
readonly warnMessage: string;
|
|
171
187
|
readonly label: string;
|
|
@@ -178,6 +194,8 @@ export interface WarnJobStep<Requirements = never, Output = never> {
|
|
|
178
194
|
export interface ErrorJobStep {
|
|
179
195
|
readonly key?: string;
|
|
180
196
|
readonly dependsOn?: ReadonlyArray<string>;
|
|
197
|
+
/** Read-only inputs fingerprinted with this step, distinct from its write footprint. */
|
|
198
|
+
readonly materialPaths?: ReadonlyArray<string>;
|
|
181
199
|
readonly readiness: "error";
|
|
182
200
|
readonly errorMessage: string;
|
|
183
201
|
readonly label: string;
|
|
@@ -203,7 +221,8 @@ export interface Job<Requirements = never, Output = never> {
|
|
|
203
221
|
readonly concurrency: "unbounded" | number;
|
|
204
222
|
/**
|
|
205
223
|
* Defaults to ordered fail-fast execution. Use `best-effort` only when every
|
|
206
|
-
* sibling step is independent; a failure still
|
|
224
|
+
* sibling step is independent, including readiness failures; a failure still
|
|
225
|
+
* blocks subsequent jobs.
|
|
207
226
|
*/
|
|
208
227
|
readonly executionPolicy?: JobExecutionPolicy;
|
|
209
228
|
}
|
|
@@ -108,7 +108,10 @@ const outcomesFor = (ws, provider, configuredAgents, operation, state) => {
|
|
|
108
108
|
/** The readiness blockers a plan's error steps contribute beyond declared conditions. */
|
|
109
109
|
const readinessBlockersOf = (plan) => {
|
|
110
110
|
const declaredConditionIds = new Set((plan.riskConditions ?? []).map((condition) => condition.id));
|
|
111
|
-
|
|
111
|
+
const hasRunnable = plan.jobs.some((job) => job.steps.some((step) => step.readiness !== "error"));
|
|
112
|
+
return plan.jobs
|
|
113
|
+
.filter((job) => !hasRunnable || job.executionPolicy !== "best-effort")
|
|
114
|
+
.flatMap((job) => job.steps.flatMap((step) => step.readiness === "error"
|
|
112
115
|
? (step.blockingConditionIds ?? []).length > 0 &&
|
|
113
116
|
(step.blockingConditionIds ?? []).every((id) => declaredConditionIds.has(id))
|
|
114
117
|
? []
|
|
@@ -193,7 +196,10 @@ export const resolveExecutionCandidate = Effect.fn("resolveExecutionCandidate")(
|
|
|
193
196
|
const candidatePlan = candidate.plan;
|
|
194
197
|
const operations = candidate.configuredAgentOperations;
|
|
195
198
|
const configuredAgents = operations.length === 0 ? [] : yield* ws.getConfiguredAgents();
|
|
196
|
-
const readiness = scanPlanReadiness(
|
|
199
|
+
const readiness = scanPlanReadiness({
|
|
200
|
+
...candidatePlan,
|
|
201
|
+
jobs: candidatePlan.jobs.filter((job) => job.executionPolicy !== "best-effort"),
|
|
202
|
+
});
|
|
197
203
|
const readinessBlockers = readinessBlockersOf(candidatePlan);
|
|
198
204
|
const riskConditions = candidatePlan.riskConditions ?? [];
|
|
199
205
|
const atomicity = declaredAtomicity(candidatePlan);
|
package/package.json
CHANGED
|
@@ -4,36 +4,33 @@
|
|
|
4
4
|
"url": "https://github.com/agentxm/axm/issues"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@agentxm/extension-model": "^0.
|
|
8
|
-
"@agentxm/extension-resolution": "^0.
|
|
9
|
-
"@agentxm/registry-protocol": "^0.
|
|
10
|
-
"@agentxm/workspace-state": "^0.
|
|
11
|
-
"@agentxm/workspace-transactions": "^0.
|
|
7
|
+
"@agentxm/extension-model": "^0.30.1",
|
|
8
|
+
"@agentxm/extension-resolution": "^0.30.1",
|
|
9
|
+
"@agentxm/registry-protocol": "^0.30.1",
|
|
10
|
+
"@agentxm/workspace-state": "^0.30.1",
|
|
11
|
+
"@agentxm/workspace-transactions": "^0.30.1",
|
|
12
12
|
"effect": "4.0.0-rc.115"
|
|
13
13
|
},
|
|
14
14
|
"description": "AXM workspace operations: plans, execution candidates, closure execution, and operation resolutions for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@agentxm/specification-metadata": "^0.
|
|
16
|
+
"@agentxm/specification-metadata": "^0.30.1",
|
|
17
17
|
"@effect/platform-node": "4.0.0-rc.115",
|
|
18
18
|
"@effect/vitest": "4.0.0-rc.115",
|
|
19
19
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
20
20
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
21
|
-
"vitest": "^5.0.0"
|
|
22
|
-
"yaml": "^2.9.0"
|
|
21
|
+
"vitest": "^5.0.0"
|
|
23
22
|
},
|
|
24
23
|
"engines": {
|
|
25
24
|
"node": ">=22.19.0"
|
|
26
25
|
},
|
|
27
26
|
"exports": {
|
|
28
27
|
".": {
|
|
29
|
-
"
|
|
30
|
-
"default": "./dist/src/index.js"
|
|
31
|
-
"types": "./dist/src/index.d.ts"
|
|
28
|
+
"types": "./dist/src/index.d.ts",
|
|
29
|
+
"default": "./dist/src/index.js"
|
|
32
30
|
},
|
|
33
31
|
"./testing": {
|
|
34
|
-
"
|
|
35
|
-
"default": "./dist/src/testing.js"
|
|
36
|
-
"types": "./dist/src/testing.d.ts"
|
|
32
|
+
"types": "./dist/src/testing.d.ts",
|
|
33
|
+
"default": "./dist/src/testing.js"
|
|
37
34
|
}
|
|
38
35
|
},
|
|
39
36
|
"files": [
|
|
@@ -56,5 +53,5 @@
|
|
|
56
53
|
},
|
|
57
54
|
"sideEffects": false,
|
|
58
55
|
"type": "module",
|
|
59
|
-
"version": "0.
|
|
56
|
+
"version": "0.30.1"
|
|
60
57
|
}
|