agentwheel 0.20.5 → 0.20.6

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.
@@ -5,8 +5,8 @@ import {
5
5
  commitManifestMetadataJournal,
6
6
  recoverPendingApply,
7
7
  uninstall
8
- } from "./chunk-XL4ZATLD.js";
9
- import "./chunk-JIATNPDH.js";
8
+ } from "./chunk-4AM3LNUQ.js";
9
+ import "./chunk-JXX6EDIP.js";
10
10
  import "./chunk-7VPI5J5Y.js";
11
11
  export {
12
12
  applyCombinedInstallPlan,
@@ -24,7 +24,7 @@ import {
24
24
  rollbackCompletedOperations,
25
25
  sourceLockPath,
26
26
  writeApplyJournal
27
- } from "./chunk-JIATNPDH.js";
27
+ } from "./chunk-JXX6EDIP.js";
28
28
  import {
29
29
  pathExists,
30
30
  writeJsonAtomic
@@ -78,6 +78,7 @@ var graphLockRootSchema = z2.object({
78
78
  graphNodeId: z2.string().min(1),
79
79
  mode: z2.enum(["pinned", "tracking"]),
80
80
  selected: z2.array(z2.string().min(1)),
81
+ fullPackageSelected: z2.boolean().optional(),
81
82
  aliases: z2.record(z2.string(), z2.string().min(1)).optional(),
82
83
  overrides: z2.array(z2.string().min(1)).optional(),
83
84
  selectionImport: z2.object({
@@ -2625,8 +2625,8 @@ async function recoverMutationRuntime(operationId, options = {}) {
2625
2625
  }
2626
2626
  mutation = GovernedMutation.activateExisting(receipt, baseline, lock);
2627
2627
  const [{ recoverPendingApply }, { readLinkedLocalApplyJournal: readLinkedLocalApplyJournal2, removeApplyJournal: removeApplyJournal2, localPathExists: localPathExists2 }] = await Promise.all([
2628
- import("./apply-MGOL643W.js"),
2629
- import("./transaction-RJ34P3B6.js")
2628
+ import("./apply-OEKVIYBV.js"),
2629
+ import("./transaction-D7VRZZX5.js")
2630
2630
  ]);
2631
2631
  let missingReservation = false;
2632
2632
  for (const entry of pending) {
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ import {
33
33
  uninstall,
34
34
  withManifestRevision,
35
35
  writeInstallManifest
36
- } from "./chunk-XL4ZATLD.js";
36
+ } from "./chunk-4AM3LNUQ.js";
37
37
  import {
38
38
  CURRENT_WORKSPACE_SCHEMA_VERSION,
39
39
  GovernedMutation,
@@ -94,7 +94,7 @@ import {
94
94
  workspaceSelectionImportSchema,
95
95
  writeApplyJournal,
96
96
  writeWorkspaceConfig
97
- } from "./chunk-JIATNPDH.js";
97
+ } from "./chunk-JXX6EDIP.js";
98
98
  import {
99
99
  inferSourceDriverName
100
100
  } from "./chunk-EMDIG24I.js";
@@ -5968,16 +5968,27 @@ function normalizeLiteralProviderSpec(source, prefix) {
5968
5968
  }
5969
5969
 
5970
5970
  // src/resolve/graph.ts
5971
+ var TrackingRefreshRestart = class extends Error {
5972
+ constructor(normalizedSource) {
5973
+ super(`Restart graph resolution with a fresh tracking source: ${normalizedSource}`);
5974
+ this.normalizedSource = normalizedSource;
5975
+ }
5976
+ normalizedSource;
5977
+ };
5978
+ var SnapshotConflictError = class extends Error {
5979
+ };
5971
5980
  var cacheLocks = /* @__PURE__ */ new Map();
5972
5981
  async function resolveDependencyGraph(roots, options) {
5973
5982
  if (roots.length === 0) throw new Error("At least one graph root is required.");
5974
5983
  const graphRoot = await mkdtemp2(join29(tmpdir3(), "agentwheel-graph-"));
5975
5984
  const fetchCache = /* @__PURE__ */ new Map();
5976
5985
  const nodesByKey = /* @__PURE__ */ new Map();
5986
+ const nodesBySource = /* @__PURE__ */ new Map();
5977
5987
  const rootResults = [];
5978
5988
  const edgeMap = /* @__PURE__ */ new Map();
5989
+ const trackingRefreshSources = /* @__PURE__ */ new Set();
5979
5990
  assertDependencyUpdateSelectors(options.previousLock, options.dependencyUpdateSelectors);
5980
- const queue = roots.map((root, index) => {
5991
+ const rootRequirements = () => roots.map((root, index) => {
5981
5992
  const rootId = root.rootId ?? `root-${index + 1}`;
5982
5993
  return {
5983
5994
  source: root.source,
@@ -6000,15 +6011,33 @@ async function resolveDependencyGraph(roots, options) {
6000
6011
  suggestionAliases: sortedUnique2([...root.suggestionAliases ?? [], ...options.suggestionAliases ?? []])
6001
6012
  };
6002
6013
  });
6014
+ const requiredQueue = rootRequirements();
6015
+ const optionalQueue = [];
6003
6016
  let iterations = 0;
6004
6017
  const cap = Math.max(64, roots.length * 64);
6005
- while (queue.length > 0) {
6018
+ while (requiredQueue.length > 0 || optionalQueue.length > 0) {
6006
6019
  if (++iterations > cap) {
6007
6020
  throw new Error(`Dependency graph did not reach a fixed point after ${cap} iterations.`);
6008
6021
  }
6022
+ const queue = requiredQueue.length > 0 ? requiredQueue : optionalQueue;
6009
6023
  const batch = queue.splice(0, queue.length);
6010
- const next = await mapLimit(batch, options.concurrency ?? 4, async (requirement) => processRequirement(requirement, options, fetchCache, nodesByKey, rootResults, edgeMap));
6011
- queue.push(...next.flat());
6024
+ try {
6025
+ const next = (await mapLimit(batch, options.concurrency ?? 4, async (requirement) => processRequirement(requirement, options, fetchCache, nodesByKey, nodesBySource, rootResults, edgeMap, trackingRefreshSources))).flat();
6026
+ for (const requirement of next) {
6027
+ (requirement.optional ? optionalQueue : requiredQueue).push(requirement);
6028
+ }
6029
+ } catch (error) {
6030
+ if (!(error instanceof TrackingRefreshRestart)) throw error;
6031
+ trackingRefreshSources.add(error.normalizedSource);
6032
+ nodesByKey.clear();
6033
+ nodesBySource.clear();
6034
+ rootResults.length = 0;
6035
+ edgeMap.clear();
6036
+ requiredQueue.length = 0;
6037
+ optionalQueue.length = 0;
6038
+ requiredQueue.push(...rootRequirements());
6039
+ iterations = 0;
6040
+ }
6012
6041
  }
6013
6042
  const rawNodes = [...nodesByKey.values()].sort((a, b) => a.node.id.localeCompare(b.node.id)).map((state) => materializeRawNode(state));
6014
6043
  const selectedByNodeId = new Map(rawNodes.map((raw) => [raw.node.id, raw.node.selected]));
@@ -6033,6 +6062,7 @@ function createGraphLock(graph, artifacts = [], targetFingerprint, includeEdges
6033
6062
  graphNodeId: root.graphNodeId,
6034
6063
  mode: root.mode,
6035
6064
  selected: root.selected,
6065
+ fullPackageSelected: root.fullPackageSelected,
6036
6066
  aliases: root.aliases,
6037
6067
  overrides: root.overrides,
6038
6068
  selectionImport: root.selectionImport
@@ -6052,7 +6082,7 @@ function createGraphLock(graph, artifacts = [], targetFingerprint, includeEdges
6052
6082
  }
6053
6083
  };
6054
6084
  }
6055
- async function processRequirement(requirement, options, fetchCache, nodesByKey, rootResults, edgeMap) {
6085
+ async function processRequirement(requirement, options, fetchCache, nodesByKey, nodesBySource, rootResults, edgeMap, trackingRefreshSources) {
6056
6086
  try {
6057
6087
  const lockLabel = options.offline ? "Offline" : options.frozenLock ? "Frozen lock" : "Locked install";
6058
6088
  let lockedByReference = lockedNodeForRequirementReference(requirement, options, lockLabel);
@@ -6083,7 +6113,18 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6083
6113
  requirement.updateClosure = true;
6084
6114
  }
6085
6115
  }
6086
- const frozen = lockedByReference ?? lockedNodeForRequirement(normalized.normalizedSource, requirement, options, lockLabel);
6116
+ const hardLock = options.frozenLock === true || options.offline === true;
6117
+ if (!hardLock && requirement.mode === "tracking" && !requirement.useLock && !trackingRefreshSources.has(normalized.normalizedSource)) {
6118
+ throw new TrackingRefreshRestart(normalized.normalizedSource);
6119
+ }
6120
+ let frozen = lockedByReference ?? lockedNodeForRequirement(normalized.normalizedSource, requirement, options, lockLabel);
6121
+ if (!hardLock && requirement.mode === "tracking" && frozen && !trackingRefreshSources.has(normalized.normalizedSource) && !lockedNodeCoversRequirementSelection(frozen.node, requirement, options)) {
6122
+ throw new TrackingRefreshRestart(frozen.node.normalizedSource);
6123
+ }
6124
+ if (requirement.mode === "tracking" && trackingRefreshSources.has(normalized.normalizedSource)) {
6125
+ lockedByReference = void 0;
6126
+ frozen = void 0;
6127
+ }
6087
6128
  let fetched;
6088
6129
  try {
6089
6130
  fetched = await fetchPackage(normalized, requirement.mode, options, fetchCache, frozen);
@@ -6108,7 +6149,13 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6108
6149
  requirement.chain
6109
6150
  );
6110
6151
  if (selectionImport) selectionImport = { ...selectionImport, effective: selected };
6111
- let state = nodesByKey.get(nodeKey);
6152
+ const sourceState = nodesBySource.get(normalized.normalizedSource);
6153
+ if (sourceState && (sourceState.node.resolvedCommit !== fetched.resolved.resolvedCommit || sourceState.node.sourceHash !== fetched.sourceHash)) {
6154
+ throw new SnapshotConflictError(
6155
+ `Conflicting locked and refreshed snapshots for ${normalized.normalizedSource}; the same package cannot be resolved as both pinned and tracking in one graph.`
6156
+ );
6157
+ }
6158
+ let state = nodesByKey.get(nodeKey) ?? sourceState;
6112
6159
  if (!state) {
6113
6160
  const id = graphNodeId(fetched.name, fetched.version, normalized.normalizedSource, fetched.resolved.resolvedCommit, fetched.sourceHash);
6114
6161
  state = {
@@ -6143,7 +6190,9 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6143
6190
  updateClosure: false
6144
6191
  };
6145
6192
  nodesByKey.set(nodeKey, state);
6193
+ nodesBySource.set(normalized.normalizedSource, state);
6146
6194
  }
6195
+ if (requirement.mode === "tracking") state.node.mode = "tracking";
6147
6196
  state.depth = Math.min(state.depth, requirement.depth);
6148
6197
  state.fullPackageSelected = state.fullPackageSelected || requirement.select === void 0 && !requirement.selection;
6149
6198
  state.includeSuggestions = state.includeSuggestions || requirement.includeSuggestions === true;
@@ -6158,8 +6207,9 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6158
6207
  source: fetched.resolved.source,
6159
6208
  normalizedSource: normalized.normalizedSource,
6160
6209
  graphNodeId: state.node.id,
6161
- mode: state.node.mode,
6210
+ mode: requirement.mode,
6162
6211
  selected: state.node.selected,
6212
+ fullPackageSelected: requirement.select === void 0 && !requirement.selection,
6163
6213
  aliases: requirement.aliases,
6164
6214
  overrides: requirement.overrides,
6165
6215
  selectionImport
@@ -6183,6 +6233,7 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6183
6233
  }
6184
6234
  return await collectDependencyNeeds(state, fetched, options, requirement.chain);
6185
6235
  } catch (error) {
6236
+ if (error instanceof TrackingRefreshRestart) throw error;
6186
6237
  if (requirement.optional) {
6187
6238
  const message2 = error instanceof Error ? error.message : String(error);
6188
6239
  options.warn?.(`optional dependency skipped: ${message2}`);
@@ -6205,17 +6256,19 @@ async function collectDependencyNeeds(state, fetched, options, chain) {
6205
6256
  warnNoDepsOnce(state, [...dependencyEntries.map(([alias]) => alias), ...suggestionEntries.map(([alias]) => alias)], options.warn);
6206
6257
  } else {
6207
6258
  for (const [alias, dependency] of dependencyEntries) {
6208
- if (state.processedPackageAliases.has(alias)) continue;
6259
+ const processedKey = closureProcessingKey(alias, state.updateClosure);
6260
+ if (state.processedPackageAliases.has(processedKey)) continue;
6209
6261
  if (!dependency.select?.length && !(state.fullPackageSelected && dependency.select === void 0)) continue;
6210
- state.processedPackageAliases.add(alias);
6262
+ state.processedPackageAliases.add(processedKey);
6211
6263
  if (!dependencyTargetsRuntime(dependency.runtimes, options.runtime, state.node.id, alias, options.warn)) continue;
6212
6264
  requirements.push(dependencyRequirement(state, fetched, alias, dependency, dependency.select, chain, options));
6213
6265
  }
6214
6266
  for (const [alias, suggestion] of suggestionEntries) {
6215
- if (state.processedSuggestions.has(alias)) continue;
6267
+ const processedKey = closureProcessingKey(alias, state.updateClosure);
6268
+ if (state.processedSuggestions.has(processedKey)) continue;
6216
6269
  if (!shouldIncludeSuggestionAlias(alias, suggestionOptions, state.fullPackageSelected)) continue;
6217
6270
  if (!suggestion.select?.length && !(state.fullPackageSelected && suggestion.select === void 0) && !explicitSuggestionAlias(alias, suggestionOptions)) continue;
6218
- state.processedSuggestions.add(alias);
6271
+ state.processedSuggestions.add(processedKey);
6219
6272
  if (!dependencyTargetsRuntime(suggestion.runtimes, options.runtime, state.node.id, alias, options.warn)) continue;
6220
6273
  requirements.push(suggestionRequirement(state, fetched, alias, suggestion, suggestion.select, chain, suggestionOptions));
6221
6274
  }
@@ -6223,10 +6276,10 @@ async function collectDependencyNeeds(state, fetched, options, chain) {
6223
6276
  const artifactsBySelector = new Map(fetched.artifacts.map((artifact) => [artifactSelectorKey(artifact), artifact]));
6224
6277
  const artifactsByRelativePath = new Map(fetched.artifacts.map((artifact) => [artifact.relativePath.replaceAll("\\", "/"), artifact]));
6225
6278
  while (true) {
6226
- const pending = [...state.selected].filter((selector) => !state.processedNeeds.has(selector)).sort((a, b) => a.localeCompare(b));
6279
+ const pending = [...state.selected].filter((selector) => !state.processedNeeds.has(closureProcessingKey(selector, state.updateClosure))).sort((a, b) => a.localeCompare(b));
6227
6280
  if (pending.length === 0) break;
6228
6281
  for (const parentSelector of pending) {
6229
- state.processedNeeds.add(parentSelector);
6282
+ state.processedNeeds.add(closureProcessingKey(parentSelector, state.updateClosure));
6230
6283
  const artifact = artifactsBySelector.get(parentSelector);
6231
6284
  if (!artifact) continue;
6232
6285
  if (!artifactTargetsRuntime(artifact.runtimes, options.runtime, state.node.id, parentSelector, options.warn)) continue;
@@ -6381,7 +6434,7 @@ function matchingDependencyUpdateEdges(lock, selector) {
6381
6434
  const nodes = new Map(lock.canonical.nodes.map((node) => [node.id, node]));
6382
6435
  return lock.canonical.edges.filter((edge) => {
6383
6436
  const node = nodes.get(edge.to);
6384
- if (!node || node.mode !== "tracking") return false;
6437
+ if (!node || edge.mode !== "tracking") return false;
6385
6438
  return selector === edge.alias || selector === edge.source || selector === edge.normalizedSource || selector === node.id || selector === node.name || selector === node.source || selector === node.normalizedSource;
6386
6439
  });
6387
6440
  }
@@ -6628,6 +6681,28 @@ function lockedNodeForRequirement(normalizedSource, requirement, options, label)
6628
6681
  cacheIdentity: node.cacheIdentity
6629
6682
  };
6630
6683
  }
6684
+ function lockedNodeCoversRequirementSelection(node, requirement, options) {
6685
+ if (requirement.mode !== "tracking") return true;
6686
+ const lockedRoot = requirement.rootId ? options.previousLock?.canonical.roots.find((root) => root.rootId === requirement.rootId) : void 0;
6687
+ if (requirement.depth === 0 && requirement.select === void 0 && !requirement.selection) {
6688
+ return lockedRoot?.fullPackageSelected === true;
6689
+ }
6690
+ if (requirement.selection) {
6691
+ const lockedSelection2 = lockedRoot?.selectionImport;
6692
+ const requestedAdditions = normalizeArtifactSelectors(requirement.selection.add) ?? [];
6693
+ const requestedExclusions = normalizeArtifactSelectors(requirement.selection.exclude) ?? [];
6694
+ if (!lockedSelection2 || lockedSelection2.exportName !== requirement.selection.export) {
6695
+ return false;
6696
+ }
6697
+ const requestedExclusionSet = new Set(requestedExclusions);
6698
+ const requestedEffective = sortedUnique2([...lockedSelection2.inherited, ...requestedAdditions]).filter((selector) => !requestedExclusionSet.has(selector));
6699
+ const lockedSelectors = new Set(node.selected);
6700
+ return requestedEffective.every((selector) => lockedSelectors.has(selector));
6701
+ }
6702
+ const requested = normalizeArtifactSelectors(requirement.select) ?? [];
6703
+ const lockedSelection = new Set(node.selected);
6704
+ return requested.every((selector) => lockedSelection.has(selector));
6705
+ }
6631
6706
  function lockedNodeForRequirementReference(requirement, options, label) {
6632
6707
  const hard = options.frozenLock === true || options.offline === true;
6633
6708
  if (!hard && !requirement.useLock) return void 0;
@@ -6778,16 +6853,25 @@ function graphNodeId(name, version, normalizedSource, resolvedCommit, sourceHash
6778
6853
  function sortedUnique2(values) {
6779
6854
  return [...new Set(values)].sort((a, b) => a.localeCompare(b));
6780
6855
  }
6856
+ function closureProcessingKey(value, updateClosure) {
6857
+ return `${updateClosure ? "update" : "locked"}\0${value}`;
6858
+ }
6781
6859
  async function mapLimit(items, limit, fn) {
6782
6860
  const out = new Array(items.length);
6783
6861
  let index = 0;
6862
+ let failure;
6784
6863
  const workers = Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, async () => {
6785
- while (index < items.length) {
6864
+ while (index < items.length && failure === void 0) {
6786
6865
  const current = index++;
6787
- out[current] = await fn(items[current]);
6866
+ try {
6867
+ out[current] = await fn(items[current]);
6868
+ } catch (error) {
6869
+ failure ??= error;
6870
+ }
6788
6871
  }
6789
6872
  });
6790
6873
  await Promise.all(workers);
6874
+ if (failure !== void 0) throw failure;
6791
6875
  return out;
6792
6876
  }
6793
6877
 
@@ -14109,7 +14193,7 @@ function dependencyUpdateNodeIds(lock, selectors) {
14109
14193
  for (const selector of selectors) {
14110
14194
  for (const edge of lock.canonical.edges) {
14111
14195
  const node = nodes.get(edge.to);
14112
- if (!node || node.mode !== "tracking") continue;
14196
+ if (!node || edge.mode !== "tracking") continue;
14113
14197
  if (selector === edge.alias || selector === edge.source || selector === edge.normalizedSource || selector === node.id || selector === node.name || selector === node.source || selector === node.normalizedSource) {
14114
14198
  selected.add(edge.to);
14115
14199
  }
@@ -14139,7 +14223,7 @@ function dependencyUpdatePackageNames(lock, selectors) {
14139
14223
  }
14140
14224
  for (const edge of lock.canonical.edges) {
14141
14225
  const node = nodes.get(edge.to);
14142
- if (!node || node.mode !== "tracking") continue;
14226
+ if (!node || edge.mode !== "tracking") continue;
14143
14227
  if (selector === edge.alias || selector === edge.source || selector === edge.normalizedSource || selector === node.id || selector === node.name || selector === node.source || selector === node.normalizedSource) {
14144
14228
  names.add(node.name);
14145
14229
  }
@@ -18,7 +18,7 @@ import {
18
18
  removeApplyJournal,
19
19
  rollbackCompletedOperations,
20
20
  writeApplyJournal
21
- } from "./chunk-JIATNPDH.js";
21
+ } from "./chunk-JXX6EDIP.js";
22
22
  import "./chunk-7VPI5J5Y.js";
23
23
  export {
24
24
  abortApplyJournal,
package/openpack.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "name": "NestDevLab/agentwheel",
4
- "version": "0.20.5",
4
+ "version": "0.20.6",
5
5
  "provides": [
6
6
  { "type": "skills", "path": "skills" }
7
7
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentwheel",
3
- "version": "0.20.5",
3
+ "version": "0.20.6",
4
4
  "description": "Weave skills, rules, and instructions across every AI agent.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -5,7 +5,7 @@ allowed-tools: [Bash]
5
5
  license: MIT
6
6
  metadata:
7
7
  author: NestDevLab
8
- version: "0.20.5"
8
+ version: "0.20.6"
9
9
  ---
10
10
 
11
11
  # agentwheel
@@ -5,7 +5,7 @@ allowed-tools: [Bash]
5
5
  license: MIT
6
6
  metadata:
7
7
  author: NestDevLab
8
- version: "0.20.5"
8
+ version: "0.20.6"
9
9
  ---
10
10
 
11
11
  # Agentwheel Discovery