@wairon/cli 5.0.1 → 5.0.2-dev.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/cli/index.js CHANGED
@@ -65,7 +65,7 @@ var init_defaults = __esm({
65
65
  copilot: ".github/prompts",
66
66
  codex: ".codex/agents"
67
67
  };
68
- WAIRON_VERSION = "5.0.1";
68
+ WAIRON_VERSION = "5.0.2-dev.1";
69
69
  GITHUB_REPO = "SYW-Apps/Waffle-AIron";
70
70
  ARCHITECT_AGENT_ID = "agent-architect";
71
71
  ARCHITECT_TEMPLATE_ID = "architect";
@@ -5139,18 +5139,20 @@ var MODEL = __MODEL_JSON__;
5139
5139
  return markers[id];
5140
5140
  }
5141
5141
  var collapsed = [];
5142
- // True content overflow in px, measured with FRACTIONAL rect precision:
5143
- // scrollWidth/clientWidth are rounded integers and scrollWidth never reads
5144
- // below clientWidth, so a sub-pixel overflow that still paints a scrollbar
5145
- // is invisible to them. Positive = overflowing; negative = headroom.
5142
+ // Signed fit measure in px: positive = overflowing, negative = headroom.
5143
+ // The header is a flex row whose ONLY flex:1 child is the .spacer, so the
5144
+ // spacer's rendered width IS the free space -- it grows to absorb all slack
5145
+ // and collapses to 0 the instant the row is full. That makes a right-edge
5146
+ // measurement useless (the spacer keeps the trailing controls pinned to the
5147
+ // right padding at every width, so their edge always reads as a bare fit),
5148
+ // and scrollWidth clamps at clientWidth so it can't report headroom either.
5149
+ // So take headroom from the spacer's own (fractional) width, and true
5150
+ // overflow from scrollWidth - clientWidth (only ever > 0 once the spacer has
5151
+ // already collapsed to 0). The two terms are mutually exclusive.
5146
5152
  function overflowPx() {
5147
- var box = hdr.getBoundingClientRect();
5148
- var edge = box.left;
5149
- for (var c = hdr.firstElementChild; c; c = c.nextElementSibling) {
5150
- var cr = c.getBoundingClientRect();
5151
- if (cr.width > 0 && cr.right > edge) edge = cr.right;
5152
- }
5153
- return edge - (box.right - 14); // 14 = the header's right padding
5153
+ var spacer = hdr.querySelector('.spacer');
5154
+ var slack = spacer ? spacer.getBoundingClientRect().width : 0;
5155
+ return (hdr.scrollWidth - hdr.clientWidth) - slack;
5154
5156
  }
5155
5157
  function reflow() {
5156
5158
  // Not laid out (hidden tab, non-browser DOM) \u2014 measuring would misfire.
@@ -22804,8 +22806,8 @@ function walkForPackages(projectRoot2, currentDir, depth, results) {
22804
22806
  }
22805
22807
  }
22806
22808
  function pathToId(relPath) {
22807
- const basename13 = path28.basename(relPath);
22808
- return basename13.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
22809
+ const basename12 = path28.basename(relPath);
22810
+ return basename12.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
22809
22811
  }
22810
22812
  function pathToName(relPath) {
22811
22813
  const id = pathToId(relPath);
@@ -26413,6 +26415,46 @@ function storeListGlobalPacks() {
26413
26415
  );
26414
26416
  return [...instance, ...image];
26415
26417
  }
26418
+ function readPackContent(full) {
26419
+ const st = fs36.statSync(full);
26420
+ if (st.isFile()) return fs36.readFileSync(full, "utf8");
26421
+ if (st.isDirectory()) {
26422
+ for (const entry of ["pack.yaml", "pack.yml"]) {
26423
+ const p = path45.join(full, entry);
26424
+ if (fs36.existsSync(p) && fs36.statSync(p).isFile()) return fs36.readFileSync(p, "utf8");
26425
+ }
26426
+ }
26427
+ return null;
26428
+ }
26429
+ function storeResolveGlobalPacks(names) {
26430
+ const index = /* @__PURE__ */ new Map();
26431
+ const indexTier = (dir, tier) => {
26432
+ for (const full of hostCore.discoverPacks(dir)) {
26433
+ const manifestName = probe(full, path45.dirname(full), "global", path45.basename(full)).name;
26434
+ const candidate = { full, manifestName, tier };
26435
+ for (const key of [manifestName, stem(full), path45.basename(full)]) {
26436
+ if (!index.has(key)) index.set(key, candidate);
26437
+ }
26438
+ }
26439
+ };
26440
+ indexTier(hostCore.globalPacksDir(), "instance");
26441
+ indexTier(imagePacksDir(), "image");
26442
+ const resolved = [];
26443
+ const resolvedCanonical = /* @__PURE__ */ new Set();
26444
+ const unresolved = [];
26445
+ for (const requested of new Set(names)) {
26446
+ const candidate = index.get(requested);
26447
+ const content = candidate ? readPackContent(candidate.full) : null;
26448
+ if (!candidate || content == null) {
26449
+ unresolved.push(requested);
26450
+ continue;
26451
+ }
26452
+ if (resolvedCanonical.has(candidate.manifestName)) continue;
26453
+ resolvedCanonical.add(candidate.manifestName);
26454
+ resolved.push({ requestedName: requested, name: candidate.manifestName, content, tier: candidate.tier });
26455
+ }
26456
+ return { resolved, unresolved };
26457
+ }
26416
26458
  function storeInstallGlobalPack(name, content) {
26417
26459
  assertName(name);
26418
26460
  assertDeclarative(content);
@@ -26565,6 +26607,9 @@ function executeApprovedListProjectPacks(cfg, project2) {
26565
26607
  function executeApprovedInstallProjectPack(cfg, project2, name, content) {
26566
26608
  return runWithProjectRoot(boundProject2(cfg, project2), () => storeInstallProjectPack(name, content));
26567
26609
  }
26610
+ function executeApprovedResolveGlobalPacks(names) {
26611
+ return storeResolveGlobalPacks(names);
26612
+ }
26568
26613
  function removeProjectPack(cfg, credential, project2, name) {
26569
26614
  requireCap(cfg, credential, "project:admin", "project", project2, "Forbidden \u2014 removing a project pack requires project:admin over the project");
26570
26615
  runWithProjectRoot(boundProject2(cfg, project2), () => storeRemoveProjectPack(name));
@@ -27515,27 +27560,16 @@ function tryAppendAudit2(cfg, event) {
27515
27560
  );
27516
27561
  }
27517
27562
  }
27518
- function packStem(ref) {
27519
- return path47.basename(ref).replace(/\.(ya?ml|cjs|js)$/i, "");
27520
- }
27521
- function readGlobalPackContent(name) {
27522
- const dir = hostCore.globalPacksDir();
27523
- for (const candidate of [path47.join(dir, `${name}.yaml`), path47.join(dir, `${name}.yml`)]) {
27524
- if (fs38.existsSync(candidate) && fs38.statSync(candidate).isFile()) {
27525
- return fs38.readFileSync(candidate, "utf8");
27526
- }
27527
- }
27528
- const match = hostCore.discoverPacks(dir).find((ref) => packStem(ref) === name || path47.basename(ref) === name);
27529
- if (match && fs38.statSync(match).isFile()) return fs38.readFileSync(match, "utf8");
27530
- return null;
27563
+ var PACK_ENFORCEMENT_MODES = ["warn", "block", "auto_reconcile"];
27564
+ function requiredDefaultNames(policy) {
27565
+ return [.../* @__PURE__ */ new Set([...policy.requiredGlobalPacks, ...policy.defaultProjectPacks])];
27531
27566
  }
27532
27567
  function installedPackNames(cfg, projectId) {
27533
27568
  return executeApprovedListProjectPacks(cfg, projectId).map((d) => d.name);
27534
27569
  }
27535
- function installPacks(cfg, projectId, names) {
27536
- for (const name of new Set(names)) {
27537
- const content = readGlobalPackContent(name);
27538
- if (content) executeApprovedInstallProjectPack(cfg, projectId, name, content);
27570
+ function installResolvedPacks(cfg, projectId, resolution) {
27571
+ for (const pack of resolution.resolved) {
27572
+ executeApprovedInstallProjectPack(cfg, projectId, pack.name, pack.content);
27539
27573
  }
27540
27574
  }
27541
27575
  function readProjectProfileSelection(root) {
@@ -27568,10 +27602,25 @@ function resolvedSelection(request, policy, selectedBy) {
27568
27602
  return selection;
27569
27603
  }
27570
27604
  function buildEvaluation(input) {
27571
- const { policy, presentPackNames, selectedProfileIds, hasSelection, countMissingPacksAsViolation } = input;
27605
+ const {
27606
+ policy,
27607
+ presentPackNames,
27608
+ selectedProfileIds,
27609
+ hasSelection,
27610
+ countMissingPacksAsViolation,
27611
+ requiredDefaultResolution
27612
+ } = input;
27572
27613
  const present = new Set(presentPackNames);
27573
- const requiredDefault = [.../* @__PURE__ */ new Set([...policy.requiredGlobalPacks, ...policy.defaultProjectPacks])];
27574
- const missingPackNames = requiredDefault.filter((n) => !present.has(n));
27614
+ let missingPackNames;
27615
+ let unresolvedPacks;
27616
+ if (requiredDefaultResolution) {
27617
+ unresolvedPacks = requiredDefaultResolution.unresolved;
27618
+ const canonical = [...new Set(requiredDefaultResolution.resolved.map((r) => r.name))];
27619
+ missingPackNames = canonical.filter((n) => !present.has(n));
27620
+ } else {
27621
+ missingPackNames = requiredDefaultNames(policy).filter((n) => !present.has(n));
27622
+ unresolvedPacks = [];
27623
+ }
27575
27624
  const blocked = new Set(policy.blockedPackNames ?? []);
27576
27625
  const blockedPackNames = presentPackNames.filter((n) => blocked.has(n));
27577
27626
  const requiredProfileIds = policy.requiredProfileIds ?? [];
@@ -27585,16 +27634,20 @@ function buildEvaluation(input) {
27585
27634
  messages.push("Profile selection is required by policy but none was provided.");
27586
27635
  }
27587
27636
  for (const n of missingPackNames) messages.push(`Required pack "${n}" is not installed.`);
27637
+ for (const n of unresolvedPacks) {
27638
+ messages.push(`Required pack "${n}" is not available on the instance (no matching server-global pack).`);
27639
+ }
27588
27640
  for (const n of blockedPackNames) messages.push(`Pack "${n}" is blocked by policy.`);
27589
27641
  for (const id of missingProfileIds) messages.push(`Required profile "${id}" is not selected.`);
27590
27642
  for (const id of disallowedProfileIds) messages.push(`Profile "${id}" is not permitted by policy.`);
27591
- const violation = selectionRequiredUnmet || blockedPackNames.length > 0 || missingProfileIds.length > 0 || disallowedProfileIds.length > 0 || countMissingPacksAsViolation && missingPackNames.length > 0;
27643
+ const violation = selectionRequiredUnmet || blockedPackNames.length > 0 || missingProfileIds.length > 0 || disallowedProfileIds.length > 0 || countMissingPacksAsViolation && (missingPackNames.length > 0 || unresolvedPacks.length > 0);
27592
27644
  return {
27593
27645
  compliant: !violation,
27594
27646
  mode: policy.enforcementMode,
27595
27647
  missingPackNames,
27596
27648
  blockedPackNames,
27597
27649
  missingProfileIds,
27650
+ unresolvedPacks,
27598
27651
  messages
27599
27652
  };
27600
27653
  }
@@ -27616,11 +27669,15 @@ function performInit(cfg, request, principal) {
27616
27669
  request.ownerUnitId,
27617
27670
  principal ? principalSubject3(principal) : void 0
27618
27671
  );
27619
- installPacks(cfg, record2.id, [
27620
- ...policy.requiredGlobalPacks,
27621
- ...policy.defaultProjectPacks,
27622
- ...requestPackNames(request)
27623
- ]);
27672
+ installResolvedPacks(
27673
+ cfg,
27674
+ record2.id,
27675
+ executeApprovedResolveGlobalPacks([
27676
+ ...policy.requiredGlobalPacks,
27677
+ ...policy.defaultProjectPacks,
27678
+ ...requestPackNames(request)
27679
+ ])
27680
+ );
27624
27681
  const selectedBy = principal ? principalSubject3(principal) : void 0;
27625
27682
  recordProjectProfileSelection(record2.rootPath, resolvedSelection(request, policy, selectedBy));
27626
27683
  const actor = principal ? principalSubject3(principal) : SYSTEM_SUBJECT;
@@ -27678,7 +27735,8 @@ function evaluateProjectPolicy(cfg, credential, projectId) {
27678
27735
  presentPackNames: installedPackNames(cfg, projectId),
27679
27736
  selectedProfileIds: selection?.profileIds ?? [],
27680
27737
  hasSelection: !!selection,
27681
- countMissingPacksAsViolation: true
27738
+ countMissingPacksAsViolation: true,
27739
+ requiredDefaultResolution: executeApprovedResolveGlobalPacks(requiredDefaultNames(policy))
27682
27740
  });
27683
27741
  }
27684
27742
  function reconcileProjectPolicy(cfg, credential, projectId) {
@@ -27692,11 +27750,12 @@ function reconcileProjectPolicy(cfg, credential, projectId) {
27692
27750
  if (!root) throw new Error(`Unknown project "${projectId}".`);
27693
27751
  const policy = effectivePolicy(cfg.dataDir);
27694
27752
  const selection = readProjectProfileSelection(root);
27753
+ const resolution = executeApprovedResolveGlobalPacks(requiredDefaultNames(policy));
27695
27754
  let installed = installedPackNames(cfg, projectId);
27696
- const requiredDefault = [.../* @__PURE__ */ new Set([...policy.requiredGlobalPacks, ...policy.defaultProjectPacks])];
27697
- const missing = requiredDefault.filter((n) => !installed.includes(n));
27698
- if (policy.enforcementMode === "auto_reconcile" && missing.length > 0) {
27699
- installPacks(cfg, projectId, missing);
27755
+ const installedSet = new Set(installed);
27756
+ const toApply = resolution.resolved.filter((p) => !installedSet.has(p.name));
27757
+ if (toApply.length > 0) {
27758
+ installResolvedPacks(cfg, projectId, { resolved: toApply, unresolved: [] });
27700
27759
  installed = installedPackNames(cfg, projectId);
27701
27760
  }
27702
27761
  const result = buildEvaluation({
@@ -27704,7 +27763,8 @@ function reconcileProjectPolicy(cfg, credential, projectId) {
27704
27763
  presentPackNames: installed,
27705
27764
  selectedProfileIds: selection?.profileIds ?? [],
27706
27765
  hasSelection: !!selection,
27707
- countMissingPacksAsViolation: true
27766
+ countMissingPacksAsViolation: true,
27767
+ requiredDefaultResolution: resolution
27708
27768
  });
27709
27769
  tryAppendAudit2(
27710
27770
  cfg,
@@ -27728,6 +27788,11 @@ function setPackPolicy(cfg, credential, policy) {
27728
27788
  if (!carriesInstancePermission(cfg, principal, POLICY_MANAGE_CAPABILITY)) {
27729
27789
  throw new ForbiddenError("policy administration requires instance-level project:admin");
27730
27790
  }
27791
+ if (!PACK_ENFORCEMENT_MODES.includes(policy.enforcementMode)) {
27792
+ throw new Error(
27793
+ `invalid enforcementMode "${policy.enforcementMode}" \u2014 must be one of ${PACK_ENFORCEMENT_MODES.join(", ")}`
27794
+ );
27795
+ }
27731
27796
  const stamped = { ...policy, updatedBy: principalSubject3(principal) };
27732
27797
  const stored = setPackPolicyRecord(cfg.dataDir, stamped);
27733
27798
  tryAppendAudit2(