agentwheel 0.20.4 → 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";
@@ -3814,6 +3814,7 @@ async function matchingGitAuthProfile(url) {
3814
3814
  const config = await readGitAuthConfig();
3815
3815
  if (!config) return void 0;
3816
3816
  const repository = repositoryKey(url);
3817
+ if (!repository) return void 0;
3817
3818
  return Object.values(config.profiles).find(
3818
3819
  (profile) => profile.repositories.some((pattern) => matchesRepository(pattern, repository))
3819
3820
  );
@@ -3847,8 +3848,13 @@ function parseGitAuthConfig(value, path) {
3847
3848
  return { profiles };
3848
3849
  }
3849
3850
  function repositoryKey(url) {
3850
- const parsed = new URL(url);
3851
- return `${parsed.host}/${parsed.pathname.replace(/^\//, "").replace(/\.git$/, "")}`.toLowerCase();
3851
+ try {
3852
+ const parsed = new URL(url);
3853
+ if (!parsed.host) return void 0;
3854
+ return `${parsed.host}/${parsed.pathname.replace(/^\//, "").replace(/\.git$/, "")}`.toLowerCase();
3855
+ } catch {
3856
+ return void 0;
3857
+ }
3852
3858
  }
3853
3859
  function matchesRepository(pattern, repository) {
3854
3860
  const escaped = pattern.toLowerCase().replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
@@ -5962,16 +5968,27 @@ function normalizeLiteralProviderSpec(source, prefix) {
5962
5968
  }
5963
5969
 
5964
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
+ };
5965
5980
  var cacheLocks = /* @__PURE__ */ new Map();
5966
5981
  async function resolveDependencyGraph(roots, options) {
5967
5982
  if (roots.length === 0) throw new Error("At least one graph root is required.");
5968
5983
  const graphRoot = await mkdtemp2(join29(tmpdir3(), "agentwheel-graph-"));
5969
5984
  const fetchCache = /* @__PURE__ */ new Map();
5970
5985
  const nodesByKey = /* @__PURE__ */ new Map();
5986
+ const nodesBySource = /* @__PURE__ */ new Map();
5971
5987
  const rootResults = [];
5972
5988
  const edgeMap = /* @__PURE__ */ new Map();
5989
+ const trackingRefreshSources = /* @__PURE__ */ new Set();
5973
5990
  assertDependencyUpdateSelectors(options.previousLock, options.dependencyUpdateSelectors);
5974
- const queue = roots.map((root, index) => {
5991
+ const rootRequirements = () => roots.map((root, index) => {
5975
5992
  const rootId = root.rootId ?? `root-${index + 1}`;
5976
5993
  return {
5977
5994
  source: root.source,
@@ -5994,15 +6011,33 @@ async function resolveDependencyGraph(roots, options) {
5994
6011
  suggestionAliases: sortedUnique2([...root.suggestionAliases ?? [], ...options.suggestionAliases ?? []])
5995
6012
  };
5996
6013
  });
6014
+ const requiredQueue = rootRequirements();
6015
+ const optionalQueue = [];
5997
6016
  let iterations = 0;
5998
6017
  const cap = Math.max(64, roots.length * 64);
5999
- while (queue.length > 0) {
6018
+ while (requiredQueue.length > 0 || optionalQueue.length > 0) {
6000
6019
  if (++iterations > cap) {
6001
6020
  throw new Error(`Dependency graph did not reach a fixed point after ${cap} iterations.`);
6002
6021
  }
6022
+ const queue = requiredQueue.length > 0 ? requiredQueue : optionalQueue;
6003
6023
  const batch = queue.splice(0, queue.length);
6004
- const next = await mapLimit(batch, options.concurrency ?? 4, async (requirement) => processRequirement(requirement, options, fetchCache, nodesByKey, rootResults, edgeMap));
6005
- 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
+ }
6006
6041
  }
6007
6042
  const rawNodes = [...nodesByKey.values()].sort((a, b) => a.node.id.localeCompare(b.node.id)).map((state) => materializeRawNode(state));
6008
6043
  const selectedByNodeId = new Map(rawNodes.map((raw) => [raw.node.id, raw.node.selected]));
@@ -6027,6 +6062,7 @@ function createGraphLock(graph, artifacts = [], targetFingerprint, includeEdges
6027
6062
  graphNodeId: root.graphNodeId,
6028
6063
  mode: root.mode,
6029
6064
  selected: root.selected,
6065
+ fullPackageSelected: root.fullPackageSelected,
6030
6066
  aliases: root.aliases,
6031
6067
  overrides: root.overrides,
6032
6068
  selectionImport: root.selectionImport
@@ -6046,7 +6082,7 @@ function createGraphLock(graph, artifacts = [], targetFingerprint, includeEdges
6046
6082
  }
6047
6083
  };
6048
6084
  }
6049
- async function processRequirement(requirement, options, fetchCache, nodesByKey, rootResults, edgeMap) {
6085
+ async function processRequirement(requirement, options, fetchCache, nodesByKey, nodesBySource, rootResults, edgeMap, trackingRefreshSources) {
6050
6086
  try {
6051
6087
  const lockLabel = options.offline ? "Offline" : options.frozenLock ? "Frozen lock" : "Locked install";
6052
6088
  let lockedByReference = lockedNodeForRequirementReference(requirement, options, lockLabel);
@@ -6077,7 +6113,18 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6077
6113
  requirement.updateClosure = true;
6078
6114
  }
6079
6115
  }
6080
- 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
+ }
6081
6128
  let fetched;
6082
6129
  try {
6083
6130
  fetched = await fetchPackage(normalized, requirement.mode, options, fetchCache, frozen);
@@ -6102,7 +6149,13 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6102
6149
  requirement.chain
6103
6150
  );
6104
6151
  if (selectionImport) selectionImport = { ...selectionImport, effective: selected };
6105
- 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;
6106
6159
  if (!state) {
6107
6160
  const id = graphNodeId(fetched.name, fetched.version, normalized.normalizedSource, fetched.resolved.resolvedCommit, fetched.sourceHash);
6108
6161
  state = {
@@ -6137,7 +6190,9 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6137
6190
  updateClosure: false
6138
6191
  };
6139
6192
  nodesByKey.set(nodeKey, state);
6193
+ nodesBySource.set(normalized.normalizedSource, state);
6140
6194
  }
6195
+ if (requirement.mode === "tracking") state.node.mode = "tracking";
6141
6196
  state.depth = Math.min(state.depth, requirement.depth);
6142
6197
  state.fullPackageSelected = state.fullPackageSelected || requirement.select === void 0 && !requirement.selection;
6143
6198
  state.includeSuggestions = state.includeSuggestions || requirement.includeSuggestions === true;
@@ -6152,8 +6207,9 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6152
6207
  source: fetched.resolved.source,
6153
6208
  normalizedSource: normalized.normalizedSource,
6154
6209
  graphNodeId: state.node.id,
6155
- mode: state.node.mode,
6210
+ mode: requirement.mode,
6156
6211
  selected: state.node.selected,
6212
+ fullPackageSelected: requirement.select === void 0 && !requirement.selection,
6157
6213
  aliases: requirement.aliases,
6158
6214
  overrides: requirement.overrides,
6159
6215
  selectionImport
@@ -6177,6 +6233,7 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
6177
6233
  }
6178
6234
  return await collectDependencyNeeds(state, fetched, options, requirement.chain);
6179
6235
  } catch (error) {
6236
+ if (error instanceof TrackingRefreshRestart) throw error;
6180
6237
  if (requirement.optional) {
6181
6238
  const message2 = error instanceof Error ? error.message : String(error);
6182
6239
  options.warn?.(`optional dependency skipped: ${message2}`);
@@ -6199,17 +6256,19 @@ async function collectDependencyNeeds(state, fetched, options, chain) {
6199
6256
  warnNoDepsOnce(state, [...dependencyEntries.map(([alias]) => alias), ...suggestionEntries.map(([alias]) => alias)], options.warn);
6200
6257
  } else {
6201
6258
  for (const [alias, dependency] of dependencyEntries) {
6202
- if (state.processedPackageAliases.has(alias)) continue;
6259
+ const processedKey = closureProcessingKey(alias, state.updateClosure);
6260
+ if (state.processedPackageAliases.has(processedKey)) continue;
6203
6261
  if (!dependency.select?.length && !(state.fullPackageSelected && dependency.select === void 0)) continue;
6204
- state.processedPackageAliases.add(alias);
6262
+ state.processedPackageAliases.add(processedKey);
6205
6263
  if (!dependencyTargetsRuntime(dependency.runtimes, options.runtime, state.node.id, alias, options.warn)) continue;
6206
6264
  requirements.push(dependencyRequirement(state, fetched, alias, dependency, dependency.select, chain, options));
6207
6265
  }
6208
6266
  for (const [alias, suggestion] of suggestionEntries) {
6209
- if (state.processedSuggestions.has(alias)) continue;
6267
+ const processedKey = closureProcessingKey(alias, state.updateClosure);
6268
+ if (state.processedSuggestions.has(processedKey)) continue;
6210
6269
  if (!shouldIncludeSuggestionAlias(alias, suggestionOptions, state.fullPackageSelected)) continue;
6211
6270
  if (!suggestion.select?.length && !(state.fullPackageSelected && suggestion.select === void 0) && !explicitSuggestionAlias(alias, suggestionOptions)) continue;
6212
- state.processedSuggestions.add(alias);
6271
+ state.processedSuggestions.add(processedKey);
6213
6272
  if (!dependencyTargetsRuntime(suggestion.runtimes, options.runtime, state.node.id, alias, options.warn)) continue;
6214
6273
  requirements.push(suggestionRequirement(state, fetched, alias, suggestion, suggestion.select, chain, suggestionOptions));
6215
6274
  }
@@ -6217,10 +6276,10 @@ async function collectDependencyNeeds(state, fetched, options, chain) {
6217
6276
  const artifactsBySelector = new Map(fetched.artifacts.map((artifact) => [artifactSelectorKey(artifact), artifact]));
6218
6277
  const artifactsByRelativePath = new Map(fetched.artifacts.map((artifact) => [artifact.relativePath.replaceAll("\\", "/"), artifact]));
6219
6278
  while (true) {
6220
- 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));
6221
6280
  if (pending.length === 0) break;
6222
6281
  for (const parentSelector of pending) {
6223
- state.processedNeeds.add(parentSelector);
6282
+ state.processedNeeds.add(closureProcessingKey(parentSelector, state.updateClosure));
6224
6283
  const artifact = artifactsBySelector.get(parentSelector);
6225
6284
  if (!artifact) continue;
6226
6285
  if (!artifactTargetsRuntime(artifact.runtimes, options.runtime, state.node.id, parentSelector, options.warn)) continue;
@@ -6375,7 +6434,7 @@ function matchingDependencyUpdateEdges(lock, selector) {
6375
6434
  const nodes = new Map(lock.canonical.nodes.map((node) => [node.id, node]));
6376
6435
  return lock.canonical.edges.filter((edge) => {
6377
6436
  const node = nodes.get(edge.to);
6378
- if (!node || node.mode !== "tracking") return false;
6437
+ if (!node || edge.mode !== "tracking") return false;
6379
6438
  return selector === edge.alias || selector === edge.source || selector === edge.normalizedSource || selector === node.id || selector === node.name || selector === node.source || selector === node.normalizedSource;
6380
6439
  });
6381
6440
  }
@@ -6622,6 +6681,28 @@ function lockedNodeForRequirement(normalizedSource, requirement, options, label)
6622
6681
  cacheIdentity: node.cacheIdentity
6623
6682
  };
6624
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
+ }
6625
6706
  function lockedNodeForRequirementReference(requirement, options, label) {
6626
6707
  const hard = options.frozenLock === true || options.offline === true;
6627
6708
  if (!hard && !requirement.useLock) return void 0;
@@ -6772,16 +6853,25 @@ function graphNodeId(name, version, normalizedSource, resolvedCommit, sourceHash
6772
6853
  function sortedUnique2(values) {
6773
6854
  return [...new Set(values)].sort((a, b) => a.localeCompare(b));
6774
6855
  }
6856
+ function closureProcessingKey(value, updateClosure) {
6857
+ return `${updateClosure ? "update" : "locked"}\0${value}`;
6858
+ }
6775
6859
  async function mapLimit(items, limit, fn) {
6776
6860
  const out = new Array(items.length);
6777
6861
  let index = 0;
6862
+ let failure;
6778
6863
  const workers = Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, async () => {
6779
- while (index < items.length) {
6864
+ while (index < items.length && failure === void 0) {
6780
6865
  const current = index++;
6781
- out[current] = await fn(items[current]);
6866
+ try {
6867
+ out[current] = await fn(items[current]);
6868
+ } catch (error) {
6869
+ failure ??= error;
6870
+ }
6782
6871
  }
6783
6872
  });
6784
6873
  await Promise.all(workers);
6874
+ if (failure !== void 0) throw failure;
6785
6875
  return out;
6786
6876
  }
6787
6877
 
@@ -14103,7 +14193,7 @@ function dependencyUpdateNodeIds(lock, selectors) {
14103
14193
  for (const selector of selectors) {
14104
14194
  for (const edge of lock.canonical.edges) {
14105
14195
  const node = nodes.get(edge.to);
14106
- if (!node || node.mode !== "tracking") continue;
14196
+ if (!node || edge.mode !== "tracking") continue;
14107
14197
  if (selector === edge.alias || selector === edge.source || selector === edge.normalizedSource || selector === node.id || selector === node.name || selector === node.source || selector === node.normalizedSource) {
14108
14198
  selected.add(edge.to);
14109
14199
  }
@@ -14133,7 +14223,7 @@ function dependencyUpdatePackageNames(lock, selectors) {
14133
14223
  }
14134
14224
  for (const edge of lock.canonical.edges) {
14135
14225
  const node = nodes.get(edge.to);
14136
- if (!node || node.mode !== "tracking") continue;
14226
+ if (!node || edge.mode !== "tracking") continue;
14137
14227
  if (selector === edge.alias || selector === edge.source || selector === edge.normalizedSource || selector === node.id || selector === node.name || selector === node.source || selector === node.normalizedSource) {
14138
14228
  names.add(node.name);
14139
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.4",
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.4",
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.4"
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.4"
8
+ version: "0.20.6"
9
9
  ---
10
10
 
11
11
  # Agentwheel Discovery