@wairon/cli 5.0.1 → 5.0.2-dev.2

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.2";
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);
@@ -25454,6 +25456,7 @@ init_validation();
25454
25456
  init_diagram();
25455
25457
  init_loader();
25456
25458
  init_extensions();
25459
+ init_types();
25457
25460
  init_server();
25458
25461
 
25459
25462
  // src/git/config.ts
@@ -25974,7 +25977,11 @@ var hostCore = {
25974
25977
  checkDeclarativePack: (raw) => {
25975
25978
  const result = DeclarativePackSchema.safeParse(raw);
25976
25979
  return result.success ? null : result.error.issues[0]?.message ?? "shape mismatch";
25977
- }
25980
+ },
25981
+ /** The ids of wairon's built-in architectural profiles, read from the core rules
25982
+ * registry's built-in profile set (BUILTIN_PROFILES) — a pure, side-effect-free
25983
+ * read of a bundled constant. */
25984
+ builtinProfileIds: () => [...BUILTIN_PROFILES]
25978
25985
  };
25979
25986
  function validateProjectAsComplete() {
25980
25987
  const config = loadProjectConfig();
@@ -26383,7 +26390,12 @@ function probe(loadRef, baseRoot, scope, displayRef) {
26383
26390
  ref: displayRef,
26384
26391
  profiles: Object.keys(loaded.profiles).length,
26385
26392
  languages: Object.keys(loaded.languages).length,
26386
- rules: loaded.rules.length
26393
+ rules: loaded.rules.length,
26394
+ // Structured id lists paralleling the counts above — a UI can present a
26395
+ // pack's profiles/languages/rules as choices instead of a bare number.
26396
+ profileIds: Object.keys(loaded.profiles),
26397
+ languageIds: Object.keys(loaded.languages),
26398
+ ruleIds: loaded.rules.map((r) => r.name)
26387
26399
  };
26388
26400
  }
26389
26401
  function writeFileAtomic(file, content) {
@@ -26413,6 +26425,71 @@ function storeListGlobalPacks() {
26413
26425
  );
26414
26426
  return [...instance, ...image];
26415
26427
  }
26428
+ function storeListAvailableProfiles() {
26429
+ const out = [];
26430
+ const seen = /* @__PURE__ */ new Set();
26431
+ const emit = (id, source, family) => {
26432
+ const key = JSON.stringify([id, source]);
26433
+ if (seen.has(key)) return;
26434
+ seen.add(key);
26435
+ out.push(family ? { id, source, family } : { id, source });
26436
+ };
26437
+ for (const id of hostCore.builtinProfileIds()) emit(id, "builtin");
26438
+ const scanTier = (dir) => {
26439
+ for (const full of hostCore.discoverPacks(dir)) {
26440
+ try {
26441
+ const loaded = hostCore.loadExtensionPacks([{ ref: full, scope: "global" }], path45.dirname(full));
26442
+ if (loaded.errors.length) continue;
26443
+ const source = loaded.packNames[0] ?? path45.basename(full);
26444
+ for (const [id, def] of Object.entries(loaded.profiles)) emit(id, source, def.family);
26445
+ } catch {
26446
+ }
26447
+ }
26448
+ };
26449
+ scanTier(hostCore.globalPacksDir());
26450
+ scanTier(imagePacksDir());
26451
+ return out;
26452
+ }
26453
+ function readPackContent(full) {
26454
+ const st = fs36.statSync(full);
26455
+ if (st.isFile()) return fs36.readFileSync(full, "utf8");
26456
+ if (st.isDirectory()) {
26457
+ for (const entry of ["pack.yaml", "pack.yml"]) {
26458
+ const p = path45.join(full, entry);
26459
+ if (fs36.existsSync(p) && fs36.statSync(p).isFile()) return fs36.readFileSync(p, "utf8");
26460
+ }
26461
+ }
26462
+ return null;
26463
+ }
26464
+ function storeResolveGlobalPacks(names) {
26465
+ const index = /* @__PURE__ */ new Map();
26466
+ const indexTier = (dir, tier) => {
26467
+ for (const full of hostCore.discoverPacks(dir)) {
26468
+ const manifestName = probe(full, path45.dirname(full), "global", path45.basename(full)).name;
26469
+ const candidate = { full, manifestName, tier };
26470
+ for (const key of [manifestName, stem(full), path45.basename(full)]) {
26471
+ if (!index.has(key)) index.set(key, candidate);
26472
+ }
26473
+ }
26474
+ };
26475
+ indexTier(hostCore.globalPacksDir(), "instance");
26476
+ indexTier(imagePacksDir(), "image");
26477
+ const resolved = [];
26478
+ const resolvedCanonical = /* @__PURE__ */ new Set();
26479
+ const unresolved = [];
26480
+ for (const requested of new Set(names)) {
26481
+ const candidate = index.get(requested);
26482
+ const content = candidate ? readPackContent(candidate.full) : null;
26483
+ if (!candidate || content == null) {
26484
+ unresolved.push(requested);
26485
+ continue;
26486
+ }
26487
+ if (resolvedCanonical.has(candidate.manifestName)) continue;
26488
+ resolvedCanonical.add(candidate.manifestName);
26489
+ resolved.push({ requestedName: requested, name: candidate.manifestName, content, tier: candidate.tier });
26490
+ }
26491
+ return { resolved, unresolved };
26492
+ }
26416
26493
  function storeInstallGlobalPack(name, content) {
26417
26494
  assertName(name);
26418
26495
  assertDeclarative(content);
@@ -26559,12 +26636,32 @@ function installProjectPack(cfg, credential, project2, name, content) {
26559
26636
  requireCap(cfg, credential, "project:admin", "project", project2, "Forbidden \u2014 installing a project pack requires project:admin over the project");
26560
26637
  return executeApprovedInstallProjectPack(cfg, project2, name, content);
26561
26638
  }
26639
+ function listAvailableProfiles(cfg, credential) {
26640
+ requirePrincipal2(cfg, credential);
26641
+ return storeListAvailableProfiles();
26642
+ }
26643
+ function listAdoptableProjectPacks(cfg, credential, project2) {
26644
+ requireCap(cfg, credential, "project:read", "project", project2, "Forbidden \u2014 listing adoptable packs requires project:read over the project");
26645
+ return storeListGlobalPacks();
26646
+ }
26647
+ function adoptProjectPack(cfg, credential, project2, name) {
26648
+ requireCap(cfg, credential, "project:admin", "project", project2, "Forbidden \u2014 adopting a project pack requires project:admin over the project");
26649
+ const resolution = executeApprovedResolveGlobalPacks([name]);
26650
+ if (resolution.resolved.length === 0) {
26651
+ throw new Error(`no such server-global pack "${name}" \u2014 cannot adopt a pack the instance does not carry`);
26652
+ }
26653
+ const resolved = resolution.resolved[0];
26654
+ return executeApprovedInstallProjectPack(cfg, project2, resolved.name, resolved.content);
26655
+ }
26562
26656
  function executeApprovedListProjectPacks(cfg, project2) {
26563
26657
  return runWithProjectRoot(boundProject2(cfg, project2), () => storeListProjectPacks());
26564
26658
  }
26565
26659
  function executeApprovedInstallProjectPack(cfg, project2, name, content) {
26566
26660
  return runWithProjectRoot(boundProject2(cfg, project2), () => storeInstallProjectPack(name, content));
26567
26661
  }
26662
+ function executeApprovedResolveGlobalPacks(names) {
26663
+ return storeResolveGlobalPacks(names);
26664
+ }
26568
26665
  function removeProjectPack(cfg, credential, project2, name) {
26569
26666
  requireCap(cfg, credential, "project:admin", "project", project2, "Forbidden \u2014 removing a project pack requires project:admin over the project");
26570
26667
  runWithProjectRoot(boundProject2(cfg, project2), () => storeRemoveProjectPack(name));
@@ -27515,27 +27612,16 @@ function tryAppendAudit2(cfg, event) {
27515
27612
  );
27516
27613
  }
27517
27614
  }
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;
27615
+ var PACK_ENFORCEMENT_MODES = ["warn", "block", "auto_reconcile"];
27616
+ function requiredDefaultNames(policy) {
27617
+ return [.../* @__PURE__ */ new Set([...policy.requiredGlobalPacks, ...policy.defaultProjectPacks])];
27531
27618
  }
27532
27619
  function installedPackNames(cfg, projectId) {
27533
27620
  return executeApprovedListProjectPacks(cfg, projectId).map((d) => d.name);
27534
27621
  }
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);
27622
+ function installResolvedPacks(cfg, projectId, resolution) {
27623
+ for (const pack of resolution.resolved) {
27624
+ executeApprovedInstallProjectPack(cfg, projectId, pack.name, pack.content);
27539
27625
  }
27540
27626
  }
27541
27627
  function readProjectProfileSelection(root) {
@@ -27568,10 +27654,25 @@ function resolvedSelection(request, policy, selectedBy) {
27568
27654
  return selection;
27569
27655
  }
27570
27656
  function buildEvaluation(input) {
27571
- const { policy, presentPackNames, selectedProfileIds, hasSelection, countMissingPacksAsViolation } = input;
27657
+ const {
27658
+ policy,
27659
+ presentPackNames,
27660
+ selectedProfileIds,
27661
+ hasSelection,
27662
+ countMissingPacksAsViolation,
27663
+ requiredDefaultResolution
27664
+ } = input;
27572
27665
  const present = new Set(presentPackNames);
27573
- const requiredDefault = [.../* @__PURE__ */ new Set([...policy.requiredGlobalPacks, ...policy.defaultProjectPacks])];
27574
- const missingPackNames = requiredDefault.filter((n) => !present.has(n));
27666
+ let missingPackNames;
27667
+ let unresolvedPacks;
27668
+ if (requiredDefaultResolution) {
27669
+ unresolvedPacks = requiredDefaultResolution.unresolved;
27670
+ const canonical = [...new Set(requiredDefaultResolution.resolved.map((r) => r.name))];
27671
+ missingPackNames = canonical.filter((n) => !present.has(n));
27672
+ } else {
27673
+ missingPackNames = requiredDefaultNames(policy).filter((n) => !present.has(n));
27674
+ unresolvedPacks = [];
27675
+ }
27575
27676
  const blocked = new Set(policy.blockedPackNames ?? []);
27576
27677
  const blockedPackNames = presentPackNames.filter((n) => blocked.has(n));
27577
27678
  const requiredProfileIds = policy.requiredProfileIds ?? [];
@@ -27585,16 +27686,20 @@ function buildEvaluation(input) {
27585
27686
  messages.push("Profile selection is required by policy but none was provided.");
27586
27687
  }
27587
27688
  for (const n of missingPackNames) messages.push(`Required pack "${n}" is not installed.`);
27689
+ for (const n of unresolvedPacks) {
27690
+ messages.push(`Required pack "${n}" is not available on the instance (no matching server-global pack).`);
27691
+ }
27588
27692
  for (const n of blockedPackNames) messages.push(`Pack "${n}" is blocked by policy.`);
27589
27693
  for (const id of missingProfileIds) messages.push(`Required profile "${id}" is not selected.`);
27590
27694
  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;
27695
+ const violation = selectionRequiredUnmet || blockedPackNames.length > 0 || missingProfileIds.length > 0 || disallowedProfileIds.length > 0 || countMissingPacksAsViolation && (missingPackNames.length > 0 || unresolvedPacks.length > 0);
27592
27696
  return {
27593
27697
  compliant: !violation,
27594
27698
  mode: policy.enforcementMode,
27595
27699
  missingPackNames,
27596
27700
  blockedPackNames,
27597
27701
  missingProfileIds,
27702
+ unresolvedPacks,
27598
27703
  messages
27599
27704
  };
27600
27705
  }
@@ -27616,11 +27721,15 @@ function performInit(cfg, request, principal) {
27616
27721
  request.ownerUnitId,
27617
27722
  principal ? principalSubject3(principal) : void 0
27618
27723
  );
27619
- installPacks(cfg, record2.id, [
27620
- ...policy.requiredGlobalPacks,
27621
- ...policy.defaultProjectPacks,
27622
- ...requestPackNames(request)
27623
- ]);
27724
+ installResolvedPacks(
27725
+ cfg,
27726
+ record2.id,
27727
+ executeApprovedResolveGlobalPacks([
27728
+ ...policy.requiredGlobalPacks,
27729
+ ...policy.defaultProjectPacks,
27730
+ ...requestPackNames(request)
27731
+ ])
27732
+ );
27624
27733
  const selectedBy = principal ? principalSubject3(principal) : void 0;
27625
27734
  recordProjectProfileSelection(record2.rootPath, resolvedSelection(request, policy, selectedBy));
27626
27735
  const actor = principal ? principalSubject3(principal) : SYSTEM_SUBJECT;
@@ -27678,7 +27787,8 @@ function evaluateProjectPolicy(cfg, credential, projectId) {
27678
27787
  presentPackNames: installedPackNames(cfg, projectId),
27679
27788
  selectedProfileIds: selection?.profileIds ?? [],
27680
27789
  hasSelection: !!selection,
27681
- countMissingPacksAsViolation: true
27790
+ countMissingPacksAsViolation: true,
27791
+ requiredDefaultResolution: executeApprovedResolveGlobalPacks(requiredDefaultNames(policy))
27682
27792
  });
27683
27793
  }
27684
27794
  function reconcileProjectPolicy(cfg, credential, projectId) {
@@ -27692,11 +27802,12 @@ function reconcileProjectPolicy(cfg, credential, projectId) {
27692
27802
  if (!root) throw new Error(`Unknown project "${projectId}".`);
27693
27803
  const policy = effectivePolicy(cfg.dataDir);
27694
27804
  const selection = readProjectProfileSelection(root);
27805
+ const resolution = executeApprovedResolveGlobalPacks(requiredDefaultNames(policy));
27695
27806
  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);
27807
+ const installedSet = new Set(installed);
27808
+ const toApply = resolution.resolved.filter((p) => !installedSet.has(p.name));
27809
+ if (toApply.length > 0) {
27810
+ installResolvedPacks(cfg, projectId, { resolved: toApply, unresolved: [] });
27700
27811
  installed = installedPackNames(cfg, projectId);
27701
27812
  }
27702
27813
  const result = buildEvaluation({
@@ -27704,7 +27815,8 @@ function reconcileProjectPolicy(cfg, credential, projectId) {
27704
27815
  presentPackNames: installed,
27705
27816
  selectedProfileIds: selection?.profileIds ?? [],
27706
27817
  hasSelection: !!selection,
27707
- countMissingPacksAsViolation: true
27818
+ countMissingPacksAsViolation: true,
27819
+ requiredDefaultResolution: resolution
27708
27820
  });
27709
27821
  tryAppendAudit2(
27710
27822
  cfg,
@@ -27728,6 +27840,11 @@ function setPackPolicy(cfg, credential, policy) {
27728
27840
  if (!carriesInstancePermission(cfg, principal, POLICY_MANAGE_CAPABILITY)) {
27729
27841
  throw new ForbiddenError("policy administration requires instance-level project:admin");
27730
27842
  }
27843
+ if (!PACK_ENFORCEMENT_MODES.includes(policy.enforcementMode)) {
27844
+ throw new Error(
27845
+ `invalid enforcementMode "${policy.enforcementMode}" \u2014 must be one of ${PACK_ENFORCEMENT_MODES.join(", ")}`
27846
+ );
27847
+ }
27731
27848
  const stamped = { ...policy, updatedBy: principalSubject3(principal) };
27732
27849
  const stored = setPackPolicyRecord(cfg.dataDir, stamped);
27733
27850
  tryAppendAudit2(
@@ -30641,6 +30758,15 @@ function installGlobalPackArchive2(cfg, credential, archive, name) {
30641
30758
  function installProjectPackArchive2(cfg, credential, project2, archive, name) {
30642
30759
  return installProjectPackArchive(cfg, credential, project2, archive, name);
30643
30760
  }
30761
+ function listAvailableProfiles2(cfg, credential) {
30762
+ return listAvailableProfiles(cfg, credential);
30763
+ }
30764
+ function listAdoptableProjectPacks2(cfg, credential, project2) {
30765
+ return listAdoptableProjectPacks(cfg, credential, project2);
30766
+ }
30767
+ function adoptProjectPack2(cfg, credential, project2, name) {
30768
+ return adoptProjectPack(cfg, credential, project2, name);
30769
+ }
30644
30770
  function getPackPolicy2(cfg, credential) {
30645
30771
  return getPackPolicy(cfg, credential);
30646
30772
  }
@@ -33934,6 +34060,15 @@ function opsInstallGlobalPackArchive(cfg, sessionId, req, body, res) {
33934
34060
  function opsInstallProjectPackArchive(cfg, sessionId, req, url, body, res) {
33935
34061
  sendJson(res, 200, installProjectPackArchive2(cfg, sessionId, q(url, "projectId") ?? "", archiveBody(body), packNameOverride(req)));
33936
34062
  }
34063
+ function opsListAvailableProfiles(cfg, sessionId, res) {
34064
+ sendJson(res, 200, { profiles: listAvailableProfiles2(cfg, sessionId) });
34065
+ }
34066
+ function opsListAdoptableProjectPacks(cfg, sessionId, url, res) {
34067
+ sendJson(res, 200, { packs: listAdoptableProjectPacks2(cfg, sessionId, q(url, "projectId") ?? "") });
34068
+ }
34069
+ function opsAdoptProjectPack(cfg, sessionId, body, res) {
34070
+ sendJson(res, 200, adoptProjectPack2(cfg, sessionId, String(body?.projectId ?? ""), String(body?.name ?? "")));
34071
+ }
33937
34072
  function opsGetPackPolicy(cfg, sessionId, res) {
33938
34073
  sendJson(res, 200, getPackPolicy2(cfg, sessionId));
33939
34074
  }
@@ -34172,6 +34307,12 @@ async function handleWebRequest(cfg, req, res, body, url, ctx) {
34172
34307
  if (req.method === "POST" && parts.length === 4 && parts[2] === "packs" && parts[3] === "remove") {
34173
34308
  return opsRemoveProjectPack(cfg, sessionId, body, res);
34174
34309
  }
34310
+ if (req.method === "GET" && parts.length === 4 && parts[2] === "packs" && parts[3] === "adoptable") {
34311
+ return opsListAdoptableProjectPacks(cfg, sessionId, url, res);
34312
+ }
34313
+ if (req.method === "POST" && parts.length === 4 && parts[2] === "packs" && parts[3] === "adopt") {
34314
+ return opsAdoptProjectPack(cfg, sessionId, body, res);
34315
+ }
34175
34316
  if (req.method === "GET" && parts.length === 3 && parts[2] === "policy") {
34176
34317
  return opsPolicyEvaluate(cfg, sessionId, url, res);
34177
34318
  }
@@ -34285,6 +34426,9 @@ async function handleWebRequest(cfg, req, res, body, url, ctx) {
34285
34426
  if (req.method === "POST" && parts.length === 4 && parts[2] === "packs" && parts[3] === "remove") {
34286
34427
  return opsRemoveGlobalPack(cfg, sessionId, body, res);
34287
34428
  }
34429
+ if (req.method === "GET" && parts.length === 3 && parts[2] === "profiles") {
34430
+ return opsListAvailableProfiles(cfg, sessionId, res);
34431
+ }
34288
34432
  if (req.method === "GET" && parts.length === 3 && parts[2] === "policy") {
34289
34433
  return opsGetPackPolicy(cfg, sessionId, res);
34290
34434
  }
@@ -35086,6 +35230,7 @@ var WEB_MUTATION_PATHS = /* @__PURE__ */ new Set([
35086
35230
  "/web/projects/packs",
35087
35231
  "/web/projects/packs/upload",
35088
35232
  "/web/projects/packs/remove",
35233
+ "/web/projects/packs/adopt",
35089
35234
  "/web/projects/policy/reconcile",
35090
35235
  "/web/projects/producers",
35091
35236
  "/web/projects/producers/remove",