@corenel/cli 0.10.0 → 0.11.0

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.
Files changed (2) hide show
  1. package/dist/main.js +1183 -291
  2. package/package.json +7 -7
package/dist/main.js CHANGED
@@ -52,7 +52,7 @@ function diskFullError(shownPath, e) {
52
52
  if (!code3 || !DISK_FULL_CODES.has(code3)) return null;
53
53
  return Object.assign(new Error(`Disk full: could not write ${shownPath}`), { code: code3, cause: e });
54
54
  }
55
- async function resolveTarget(abs, shown) {
55
+ async function resolveTarget(abs, shown2) {
56
56
  let target;
57
57
  try {
58
58
  target = await fs.realpath(abs);
@@ -62,7 +62,7 @@ async function resolveTarget(abs, shown) {
62
62
  if (codeOf(le) === "ENOENT") return null;
63
63
  throw le;
64
64
  });
65
- if (link?.isSymbolicLink()) throw new Error(`refusing to write through a dangling symlink: ${shown}`);
65
+ if (link?.isSymbolicLink()) throw new Error(`refusing to write through a dangling symlink: ${shown2}`);
66
66
  return { target: abs, st: null };
67
67
  }
68
68
  try {
@@ -85,9 +85,9 @@ async function renameWithRetry(from, to) {
85
85
  }
86
86
  }
87
87
  async function writeFileAtomic(abs, data, opts = {}) {
88
- const shown = opts.shownPath ?? abs;
89
- const fail = (e) => diskFullError(shown, e) ?? (e instanceof Error ? e : new Error(String(e)));
90
- const { target, st } = await resolveTarget(abs, shown);
88
+ const shown2 = opts.shownPath ?? abs;
89
+ const fail = (e) => diskFullError(shown2, e) ?? (e instanceof Error ? e : new Error(String(e)));
90
+ const { target, st } = await resolveTarget(abs, shown2);
91
91
  if (st && !st.isFile()) {
92
92
  try {
93
93
  await fs.writeFile(target, data);
@@ -178,8 +178,8 @@ function touchesGitDir(rel, platformSep = sep) {
178
178
  return seg === ".git";
179
179
  });
180
180
  }
181
- async function assertNotGitDir(root, abs, shown) {
182
- const refuse = () => new Error(`refusing to write inside a .git directory: ${shown}`);
181
+ async function assertNotGitDir(root, abs, shown2) {
182
+ const refuse = () => new Error(`refusing to write inside a .git directory: ${shown2}`);
183
183
  if (touchesGitDir(relative(root, abs))) throw refuse();
184
184
  let realRoot;
185
185
  try {
@@ -240,6 +240,11 @@ var init_fileService = __esm({
240
240
  /** An OUTER bound: the approved root this folder sits inside (a project
241
241
  * inside an operator's --root). See the constructor. */
242
242
  confineTo;
243
+ /** The absolute folder this service is rooted at (read-only), so a host can
244
+ * tell which folder a definition was loaded from. */
245
+ get rootDir() {
246
+ return this.root;
247
+ }
243
248
  /** `confineTo`: when `root` is a folder INSIDE an approved root, name that
244
249
  * approved root here. Every per-operation symlink check recomputes
245
250
  * realpath(root), so without it, swapping `root` itself for a link after
@@ -361,6 +366,10 @@ var init_fileService = __esm({
361
366
  async read(path) {
362
367
  return fs2.readFile(await this.realAbs(path), "utf8");
363
368
  }
369
+ /** Raw bytes, confined exactly as `read` is (lexical bound + symlink check). */
370
+ async readBytes(path) {
371
+ return new Uint8Array(await fs2.readFile(await this.realAbs(path)));
372
+ }
364
373
  async stat(path) {
365
374
  let a;
366
375
  try {
@@ -594,10 +603,10 @@ async function writeLoginCredential(token, opts = {}) {
594
603
  }
595
604
  }
596
605
  async function publishSignIn(credPath, tokPath, cred, notify) {
597
- const record = { ...await readForeignAuthSections(credPath, notify), ...cred };
606
+ const record2 = { ...await readForeignAuthSections(credPath, notify), ...cred };
598
607
  const credTmp = `${credPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
599
608
  const tokTmp = `${tokPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
600
- await fs3.writeFile(credTmp, `${JSON.stringify(record, null, 2)}
609
+ await fs3.writeFile(credTmp, `${JSON.stringify(record2, null, 2)}
601
610
  `, { mode: 384 });
602
611
  await fs3.writeFile(tokTmp, `${cred.accessToken}
603
612
  `, { mode: 384 });
@@ -727,9 +736,9 @@ async function resolveNodeCredential(opts = {}) {
727
736
  const fileToken = tokenRead.value;
728
737
  const unreadable = credRead.unreadable || tokenRead.unreadable ? { unreadable: true } : {};
729
738
  if (fileToken) {
730
- const same = cred && cred.accessToken === fileToken ? cred : null;
739
+ const same2 = cred && cred.accessToken === fileToken ? cred : null;
731
740
  return {
732
- ...withExpiry({ token: fileToken, source: "token-file", path: tokenFilePath(stateDir) }, same, now),
741
+ ...withExpiry({ token: fileToken, source: "token-file", path: tokenFilePath(stateDir) }, same2, now),
733
742
  ...unreadable
734
743
  };
735
744
  }
@@ -1766,14 +1775,14 @@ var require_foldFlowLines = __commonJS({
1766
1775
  var FOLD_FLOW = "flow";
1767
1776
  var FOLD_BLOCK = "block";
1768
1777
  var FOLD_QUOTED = "quoted";
1769
- function foldFlowLines(text, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
1778
+ function foldFlowLines(text2, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
1770
1779
  if (!lineWidth || lineWidth < 0)
1771
- return text;
1780
+ return text2;
1772
1781
  if (lineWidth < minContentWidth)
1773
1782
  minContentWidth = 0;
1774
1783
  const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
1775
- if (text.length <= endStep)
1776
- return text;
1784
+ if (text2.length <= endStep)
1785
+ return text2;
1777
1786
  const folds = [];
1778
1787
  const escapedFolds = {};
1779
1788
  let end = lineWidth - indent.length;
@@ -1790,14 +1799,14 @@ var require_foldFlowLines = __commonJS({
1790
1799
  let escStart = -1;
1791
1800
  let escEnd = -1;
1792
1801
  if (mode === FOLD_BLOCK) {
1793
- i = consumeMoreIndentedLines(text, i, indent.length);
1802
+ i = consumeMoreIndentedLines(text2, i, indent.length);
1794
1803
  if (i !== -1)
1795
1804
  end = i + endStep;
1796
1805
  }
1797
- for (let ch; ch = text[i += 1]; ) {
1806
+ for (let ch; ch = text2[i += 1]; ) {
1798
1807
  if (mode === FOLD_QUOTED && ch === "\\") {
1799
1808
  escStart = i;
1800
- switch (text[i + 1]) {
1809
+ switch (text2[i + 1]) {
1801
1810
  case "x":
1802
1811
  i += 3;
1803
1812
  break;
@@ -1814,12 +1823,12 @@ var require_foldFlowLines = __commonJS({
1814
1823
  }
1815
1824
  if (ch === "\n") {
1816
1825
  if (mode === FOLD_BLOCK)
1817
- i = consumeMoreIndentedLines(text, i, indent.length);
1826
+ i = consumeMoreIndentedLines(text2, i, indent.length);
1818
1827
  end = i + indent.length + endStep;
1819
1828
  split = void 0;
1820
1829
  } else {
1821
1830
  if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
1822
- const next = text[i + 1];
1831
+ const next = text2[i + 1];
1823
1832
  if (next && next !== " " && next !== "\n" && next !== " ")
1824
1833
  split = i;
1825
1834
  }
@@ -1831,12 +1840,12 @@ var require_foldFlowLines = __commonJS({
1831
1840
  } else if (mode === FOLD_QUOTED) {
1832
1841
  while (prev === " " || prev === " ") {
1833
1842
  prev = ch;
1834
- ch = text[i += 1];
1843
+ ch = text2[i += 1];
1835
1844
  overflow = true;
1836
1845
  }
1837
1846
  const j = i > escEnd + 1 ? i - 2 : escStart - 1;
1838
1847
  if (escapedFolds[j])
1839
- return text;
1848
+ return text2;
1840
1849
  folds.push(j);
1841
1850
  escapedFolds[j] = true;
1842
1851
  end = j + endStep;
@@ -1851,39 +1860,39 @@ var require_foldFlowLines = __commonJS({
1851
1860
  if (overflow && onOverflow)
1852
1861
  onOverflow();
1853
1862
  if (folds.length === 0)
1854
- return text;
1863
+ return text2;
1855
1864
  if (onFold)
1856
1865
  onFold();
1857
- let res = text.slice(0, folds[0]);
1866
+ let res = text2.slice(0, folds[0]);
1858
1867
  for (let i2 = 0; i2 < folds.length; ++i2) {
1859
1868
  const fold = folds[i2];
1860
- const end2 = folds[i2 + 1] || text.length;
1869
+ const end2 = folds[i2 + 1] || text2.length;
1861
1870
  if (fold === 0)
1862
1871
  res = `
1863
- ${indent}${text.slice(0, end2)}`;
1872
+ ${indent}${text2.slice(0, end2)}`;
1864
1873
  else {
1865
1874
  if (mode === FOLD_QUOTED && escapedFolds[fold])
1866
- res += `${text[fold]}\\`;
1875
+ res += `${text2[fold]}\\`;
1867
1876
  res += `
1868
- ${indent}${text.slice(fold + 1, end2)}`;
1877
+ ${indent}${text2.slice(fold + 1, end2)}`;
1869
1878
  }
1870
1879
  }
1871
1880
  return res;
1872
1881
  }
1873
- function consumeMoreIndentedLines(text, i, indent) {
1882
+ function consumeMoreIndentedLines(text2, i, indent) {
1874
1883
  let end = i;
1875
1884
  let start = i + 1;
1876
- let ch = text[start];
1885
+ let ch = text2[start];
1877
1886
  while (ch === " " || ch === " ") {
1878
1887
  if (i < start + indent) {
1879
- ch = text[++i];
1888
+ ch = text2[++i];
1880
1889
  } else {
1881
1890
  do {
1882
- ch = text[++i];
1891
+ ch = text2[++i];
1883
1892
  } while (ch && ch !== "\n");
1884
1893
  end = i;
1885
1894
  start = i + 1;
1886
- ch = text[start];
1895
+ ch = text2[start];
1887
1896
  }
1888
1897
  }
1889
1898
  return end;
@@ -8014,7 +8023,7 @@ var require_public_api = __commonJS({
8014
8023
  }
8015
8024
  return doc;
8016
8025
  }
8017
- function parse3(src, reviver, options) {
8026
+ function parse4(src, reviver, options) {
8018
8027
  let _reviver = void 0;
8019
8028
  if (typeof reviver === "function") {
8020
8029
  _reviver = reviver;
@@ -8055,7 +8064,7 @@ var require_public_api = __commonJS({
8055
8064
  return value.toString(options);
8056
8065
  return new Document.Document(value, _replacer, options).toString(options);
8057
8066
  }
8058
- exports.parse = parse3;
8067
+ exports.parse = parse4;
8059
8068
  exports.parseAllDocuments = parseAllDocuments;
8060
8069
  exports.parseDocument = parseDocument;
8061
8070
  exports.stringify = stringify2;
@@ -8581,7 +8590,7 @@ var require_parse = __commonJS({
8581
8590
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js"(exports, module) {
8582
8591
  "use strict";
8583
8592
  var SemVer = require_semver();
8584
- var parse3 = (version2, options, throwErrors = false) => {
8593
+ var parse4 = (version2, options, throwErrors = false) => {
8585
8594
  if (version2 instanceof SemVer) {
8586
8595
  return version2;
8587
8596
  }
@@ -8594,7 +8603,7 @@ var require_parse = __commonJS({
8594
8603
  throw er;
8595
8604
  }
8596
8605
  };
8597
- module.exports = parse3;
8606
+ module.exports = parse4;
8598
8607
  }
8599
8608
  });
8600
8609
 
@@ -8602,9 +8611,9 @@ var require_parse = __commonJS({
8602
8611
  var require_valid = __commonJS({
8603
8612
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js"(exports, module) {
8604
8613
  "use strict";
8605
- var parse3 = require_parse();
8614
+ var parse4 = require_parse();
8606
8615
  var valid = (version2, options) => {
8607
- const v = parse3(version2, options);
8616
+ const v = parse4(version2, options);
8608
8617
  return v ? v.version : null;
8609
8618
  };
8610
8619
  module.exports = valid;
@@ -8615,9 +8624,9 @@ var require_valid = __commonJS({
8615
8624
  var require_clean = __commonJS({
8616
8625
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/clean.js"(exports, module) {
8617
8626
  "use strict";
8618
- var parse3 = require_parse();
8627
+ var parse4 = require_parse();
8619
8628
  var clean = (version2, options) => {
8620
- const s = parse3(version2.trim().replace(/^[=v]+/, ""), options);
8629
+ const s = parse4(version2.trim().replace(/^[=v]+/, ""), options);
8621
8630
  return s ? s.version : null;
8622
8631
  };
8623
8632
  module.exports = clean;
@@ -8652,10 +8661,10 @@ var require_inc = __commonJS({
8652
8661
  var require_diff = __commonJS({
8653
8662
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/diff.js"(exports, module) {
8654
8663
  "use strict";
8655
- var parse3 = require_parse();
8664
+ var parse4 = require_parse();
8656
8665
  var diff = (version1, version2) => {
8657
- const v1 = parse3(version1, null, true);
8658
- const v2 = parse3(version2, null, true);
8666
+ const v1 = parse4(version1, null, true);
8667
+ const v2 = parse4(version2, null, true);
8659
8668
  const comparison = v1.compare(v2);
8660
8669
  if (comparison === 0) {
8661
8670
  return null;
@@ -8726,9 +8735,9 @@ var require_patch = __commonJS({
8726
8735
  var require_prerelease = __commonJS({
8727
8736
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/prerelease.js"(exports, module) {
8728
8737
  "use strict";
8729
- var parse3 = require_parse();
8738
+ var parse4 = require_parse();
8730
8739
  var prerelease = (version2, options) => {
8731
- const parsed = parse3(version2, options);
8740
+ const parsed = parse4(version2, options);
8732
8741
  return parsed && parsed.prerelease.length ? parsed.prerelease : null;
8733
8742
  };
8734
8743
  module.exports = prerelease;
@@ -8914,7 +8923,7 @@ var require_coerce = __commonJS({
8914
8923
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/coerce.js"(exports, module) {
8915
8924
  "use strict";
8916
8925
  var SemVer = require_semver();
8917
- var parse3 = require_parse();
8926
+ var parse4 = require_parse();
8918
8927
  var { safeRe: re, t } = require_re();
8919
8928
  var coerce = (version2, options) => {
8920
8929
  if (version2 instanceof SemVer) {
@@ -8949,7 +8958,7 @@ var require_coerce = __commonJS({
8949
8958
  const patch = match[4] || "0";
8950
8959
  const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : "";
8951
8960
  const build = options.includePrerelease && match[6] ? `+${match[6]}` : "";
8952
- return parse3(`${major}.${minor}.${patch}${prerelease}${build}`, options);
8961
+ return parse4(`${major}.${minor}.${patch}${prerelease}${build}`, options);
8953
8962
  };
8954
8963
  module.exports = coerce;
8955
8964
  }
@@ -8959,7 +8968,7 @@ var require_coerce = __commonJS({
8959
8968
  var require_truncate = __commonJS({
8960
8969
  "../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/truncate.js"(exports, module) {
8961
8970
  "use strict";
8962
- var parse3 = require_parse();
8971
+ var parse4 = require_parse();
8963
8972
  var constants2 = require_constants();
8964
8973
  var SemVer = require_semver();
8965
8974
  var truncate2 = (version2, truncation, options) => {
@@ -8971,7 +8980,7 @@ var require_truncate = __commonJS({
8971
8980
  };
8972
8981
  var cloneInputVersion = (version2, options) => {
8973
8982
  const versionStringToParse = version2 instanceof SemVer ? version2.version : version2;
8974
- return parse3(versionStringToParse, options);
8983
+ return parse4(versionStringToParse, options);
8975
8984
  };
8976
8985
  var doTruncation = (version2, truncation) => {
8977
8986
  if (isPrerelease(truncation)) {
@@ -9932,7 +9941,7 @@ var require_subset = __commonJS({
9932
9941
  }
9933
9942
  return true;
9934
9943
  }
9935
- let higher, lower;
9944
+ let higher, lower2;
9936
9945
  let hasDomLT, hasDomGT;
9937
9946
  let needDomLTPre = lt && !options.includePrerelease && lt.semver.prerelease.length ? lt.semver : false;
9938
9947
  let needDomGTPre = gt && !options.includePrerelease && gt.semver.prerelease.length ? gt.semver : false;
@@ -9964,8 +9973,8 @@ var require_subset = __commonJS({
9964
9973
  }
9965
9974
  }
9966
9975
  if (c.operator === "<" || c.operator === "<=") {
9967
- lower = lowerLT(lt, c, options);
9968
- if (lower === c && lower !== lt) {
9976
+ lower2 = lowerLT(lt, c, options);
9977
+ if (lower2 === c && lower2 !== lt) {
9969
9978
  return false;
9970
9979
  }
9971
9980
  } else if (lt.operator === "<=" && !c.test(lt.semver)) {
@@ -10013,7 +10022,7 @@ var require_semver2 = __commonJS({
10013
10022
  var constants2 = require_constants();
10014
10023
  var SemVer = require_semver();
10015
10024
  var identifiers = require_identifiers();
10016
- var parse3 = require_parse();
10025
+ var parse4 = require_parse();
10017
10026
  var valid = require_valid();
10018
10027
  var clean = require_clean();
10019
10028
  var inc = require_inc();
@@ -10052,7 +10061,7 @@ var require_semver2 = __commonJS({
10052
10061
  var simplifyRange = require_simplify();
10053
10062
  var subset = require_subset();
10054
10063
  module.exports = {
10055
- parse: parse3,
10064
+ parse: parse4,
10056
10065
  valid,
10057
10066
  clean,
10058
10067
  inc,
@@ -10955,7 +10964,7 @@ var require_lexer2 = __commonJS({
10955
10964
  this.colno--;
10956
10965
  }
10957
10966
  };
10958
- _proto.current = function current() {
10967
+ _proto.current = function current2() {
10959
10968
  if (!this.isFinished()) {
10960
10969
  return this.str.charAt(this.index);
10961
10970
  }
@@ -12439,7 +12448,7 @@ var require_parser2 = __commonJS({
12439
12448
  }
12440
12449
  return buf;
12441
12450
  };
12442
- _proto.parse = function parse3() {
12451
+ _proto.parse = function parse4() {
12443
12452
  return new nodes.NodeList(0, 0, this.parseNodes());
12444
12453
  };
12445
12454
  _proto.parseAsRoot = function parseAsRoot() {
@@ -12448,7 +12457,7 @@ var require_parser2 = __commonJS({
12448
12457
  return Parser2;
12449
12458
  }(Obj);
12450
12459
  module.exports = {
12451
- parse: function parse3(src, extensions, opts) {
12460
+ parse: function parse4(src, extensions, opts) {
12452
12461
  var p = new Parser(lexer.lex(src, opts));
12453
12462
  if (extensions !== void 0) {
12454
12463
  p.extensions = extensions;
@@ -14076,11 +14085,11 @@ var require_filters = __commonJS({
14076
14085
  }
14077
14086
  }
14078
14087
  _exports.list = list;
14079
- function lower(str) {
14088
+ function lower2(str) {
14080
14089
  str = normalize(str, "");
14081
14090
  return str.toLowerCase();
14082
14091
  }
14083
- _exports.lower = lower;
14092
+ _exports.lower = lower2;
14084
14093
  function nl2br(str) {
14085
14094
  if (str === null || str === void 0) {
14086
14095
  return "";
@@ -14663,10 +14672,10 @@ var require_tests = __commonJS({
14663
14672
  }
14664
14673
  exports.lessthan = lessthan;
14665
14674
  exports.lt = exports.lessthan;
14666
- function lower(value) {
14675
+ function lower2(value) {
14667
14676
  return value.toLowerCase() === value;
14668
14677
  }
14669
- exports.lower = lower;
14678
+ exports.lower = lower2;
14670
14679
  function ne(one, two) {
14671
14680
  return one !== two;
14672
14681
  }
@@ -16267,11 +16276,11 @@ var require_stream_writable = __commonJS({
16267
16276
  this.corkedRequestsFree = new CorkedRequest(this);
16268
16277
  }
16269
16278
  WritableState.prototype.getBuffer = function getBuffer() {
16270
- var current = this.bufferedRequest;
16279
+ var current2 = this.bufferedRequest;
16271
16280
  var out = [];
16272
- while (current) {
16273
- out.push(current);
16274
- current = current.next;
16281
+ while (current2) {
16282
+ out.push(current2);
16283
+ current2 = current2.next;
16275
16284
  }
16276
16285
  return out;
16277
16286
  };
@@ -21796,7 +21805,7 @@ var require_deflate2 = __commonJS({
21796
21805
  "use strict";
21797
21806
  var zlib_deflate = require_deflate();
21798
21807
  var utils = require_common();
21799
- var strings = require_strings();
21808
+ var strings2 = require_strings();
21800
21809
  var msg = require_messages();
21801
21810
  var ZStream = require_zstream();
21802
21811
  var toString = Object.prototype.toString;
@@ -21848,7 +21857,7 @@ var require_deflate2 = __commonJS({
21848
21857
  if (opt.dictionary) {
21849
21858
  var dict;
21850
21859
  if (typeof opt.dictionary === "string") {
21851
- dict = strings.string2buf(opt.dictionary);
21860
+ dict = strings2.string2buf(opt.dictionary);
21852
21861
  } else if (toString.call(opt.dictionary) === "[object ArrayBuffer]") {
21853
21862
  dict = new Uint8Array(opt.dictionary);
21854
21863
  } else {
@@ -21870,7 +21879,7 @@ var require_deflate2 = __commonJS({
21870
21879
  }
21871
21880
  _mode = mode === ~~mode ? mode : mode === true ? Z_FINISH : Z_NO_FLUSH;
21872
21881
  if (typeof data === "string") {
21873
- strm.input = strings.string2buf(data);
21882
+ strm.input = strings2.string2buf(data);
21874
21883
  } else if (toString.call(data) === "[object ArrayBuffer]") {
21875
21884
  strm.input = new Uint8Array(data);
21876
21885
  } else {
@@ -21892,7 +21901,7 @@ var require_deflate2 = __commonJS({
21892
21901
  }
21893
21902
  if (strm.avail_out === 0 || strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH)) {
21894
21903
  if (this.options.to === "string") {
21895
- this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
21904
+ this.onData(strings2.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
21896
21905
  } else {
21897
21906
  this.onData(utils.shrinkBuf(strm.output, strm.next_out));
21898
21907
  }
@@ -23785,7 +23794,7 @@ var require_inflate2 = __commonJS({
23785
23794
  "use strict";
23786
23795
  var zlib_inflate = require_inflate();
23787
23796
  var utils = require_common();
23788
- var strings = require_strings();
23797
+ var strings2 = require_strings();
23789
23798
  var c = require_constants2();
23790
23799
  var msg = require_messages();
23791
23800
  var ZStream = require_zstream();
@@ -23830,7 +23839,7 @@ var require_inflate2 = __commonJS({
23830
23839
  zlib_inflate.inflateGetHeader(this.strm, this.header);
23831
23840
  if (opt.dictionary) {
23832
23841
  if (typeof opt.dictionary === "string") {
23833
- opt.dictionary = strings.string2buf(opt.dictionary);
23842
+ opt.dictionary = strings2.string2buf(opt.dictionary);
23834
23843
  } else if (toString.call(opt.dictionary) === "[object ArrayBuffer]") {
23835
23844
  opt.dictionary = new Uint8Array(opt.dictionary);
23836
23845
  }
@@ -23854,7 +23863,7 @@ var require_inflate2 = __commonJS({
23854
23863
  }
23855
23864
  _mode = mode === ~~mode ? mode : mode === true ? c.Z_FINISH : c.Z_NO_FLUSH;
23856
23865
  if (typeof data === "string") {
23857
- strm.input = strings.binstring2buf(data);
23866
+ strm.input = strings2.binstring2buf(data);
23858
23867
  } else if (toString.call(data) === "[object ArrayBuffer]") {
23859
23868
  strm.input = new Uint8Array(data);
23860
23869
  } else {
@@ -23884,9 +23893,9 @@ var require_inflate2 = __commonJS({
23884
23893
  if (strm.next_out) {
23885
23894
  if (strm.avail_out === 0 || status === c.Z_STREAM_END || strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH)) {
23886
23895
  if (this.options.to === "string") {
23887
- next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
23896
+ next_out_utf8 = strings2.utf8border(strm.output, strm.next_out);
23888
23897
  tail = strm.next_out - next_out_utf8;
23889
- utf8str = strings.buf2string(strm.output, next_out_utf8);
23898
+ utf8str = strings2.buf2string(strm.output, next_out_utf8);
23890
23899
  strm.next_out = tail;
23891
23900
  strm.avail_out = chunkSize - tail;
23892
23901
  if (tail) {
@@ -24231,9 +24240,9 @@ var require_ZipFileWorker = __commonJS({
24231
24240
  this.currentFile = streamInfo["file"].name;
24232
24241
  var streamedContent = this.streamFiles && !streamInfo["file"].dir;
24233
24242
  if (streamedContent) {
24234
- var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
24243
+ var record2 = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
24235
24244
  this.push({
24236
- data: record.fileRecord,
24245
+ data: record2.fileRecord,
24237
24246
  meta: { percent: 0 }
24238
24247
  });
24239
24248
  } else {
@@ -24243,8 +24252,8 @@ var require_ZipFileWorker = __commonJS({
24243
24252
  ZipFileWorker.prototype.closedSource = function(streamInfo) {
24244
24253
  this.accumulate = false;
24245
24254
  var streamedContent = this.streamFiles && !streamInfo["file"].dir;
24246
- var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
24247
- this.dirRecords.push(record.dirRecord);
24255
+ var record2 = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
24256
+ this.dirRecords.push(record2.dirRecord);
24248
24257
  if (streamedContent) {
24249
24258
  this.push({
24250
24259
  data: generateDataDescriptors(streamInfo),
@@ -24252,7 +24261,7 @@ var require_ZipFileWorker = __commonJS({
24252
24261
  });
24253
24262
  } else {
24254
24263
  this.push({
24255
- data: record.fileRecord,
24264
+ data: record2.fileRecord,
24256
24265
  meta: { percent: 0 }
24257
24266
  });
24258
24267
  while (this.contentBuffer.length) {
@@ -25510,7 +25519,10 @@ var require_lib4 = __commonJS({
25510
25519
  }
25511
25520
  });
25512
25521
 
25513
- // ../../node_modules/.pnpm/@prompd+core@0.6.0/node_modules/@prompd/core/dist/index.js
25522
+ // ../../node_modules/.pnpm/@prompd+core@0.7.0/node_modules/@prompd/core/dist/index.js
25523
+ function isValidPackageType(type) {
25524
+ return VALID_PACKAGE_TYPES.includes(type);
25525
+ }
25514
25526
  function posixNormalize(p) {
25515
25527
  const isAbs = p.startsWith("/");
25516
25528
  const out = [];
@@ -25603,15 +25615,15 @@ function extname(p) {
25603
25615
  return dot <= 0 ? "" : base.slice(dot);
25604
25616
  }
25605
25617
  function isPrompdFile(p) {
25606
- const lower = p.toLowerCase();
25607
- return lower.endsWith(".prmd") || lower.endsWith(".md");
25618
+ const lower2 = p.toLowerCase();
25619
+ return lower2.endsWith(".prmd") || lower2.endsWith(".md");
25608
25620
  }
25609
25621
  function parseDateExpr(input) {
25610
25622
  const v = (input ?? "").trim();
25611
25623
  if (!v) return null;
25612
- const lower = v.toLowerCase();
25613
- if (lower === "now" || lower === "today") return /* @__PURE__ */ new Date();
25614
- const rel = lower.match(/^(?:now|today)\s*([+-])\s*(\d+)\s*([a-z]+)$/);
25624
+ const lower2 = v.toLowerCase();
25625
+ if (lower2 === "now" || lower2 === "today") return /* @__PURE__ */ new Date();
25626
+ const rel = lower2.match(/^(?:now|today)\s*([+-])\s*(\d+)\s*([a-z]+)$/);
25615
25627
  if (rel) {
25616
25628
  const n = (rel[1] === "-" ? -1 : 1) * parseInt(rel[2], 10);
25617
25629
  const u = rel[3];
@@ -25654,37 +25666,483 @@ function getLanguageAliasesForExtension(ext) {
25654
25666
  function generateCompilationId() {
25655
25667
  return `compile-${++compilationCounter}-${Date.now()}`;
25656
25668
  }
25657
- function isBinaryAsset(name) {
25658
- const dot = name.lastIndexOf(".");
25659
- return dot >= 0 && BINARY_ASSET_EXT.has(name.slice(dot + 1).toLowerCase());
25669
+ function isPackageVerificationError(e) {
25670
+ if (!(e instanceof Error)) return false;
25671
+ const code3 = e.code;
25672
+ return e.name === "PackageVerificationError" && typeof code3 === "string";
25673
+ }
25674
+ function hasControl(s) {
25675
+ for (let i = 0; i < s.length; i++) {
25676
+ const c = s.charCodeAt(i);
25677
+ if (c < 32 || c >= 127 && c <= 159) return true;
25678
+ }
25679
+ return false;
25660
25680
  }
25661
- function isSymlinkEntry(perms) {
25662
- return typeof perms === "number" && (perms & 61440) === 40960;
25681
+ function shown(name) {
25682
+ if (hasControl(name) || BIDI_RE.test(name)) return "a file name in the package";
25683
+ return name.length > ARCHIVE_LIMITS.maxNameLength ? `${name.slice(0, ARCHIVE_LIMITS.maxNameLength)}...` : name;
25684
+ }
25685
+ function entryNameProblem(name) {
25686
+ if (hasControl(name)) return "a file name in the package holds a control character";
25687
+ if (!name) return "a file in the package has no name";
25688
+ if (BIDI_RE.test(name)) return "a file name in the package holds a text-direction character";
25689
+ if (name.length > ARCHIVE_LIMITS.maxNameLength) return `a file name in the package is too long (over ${ARCHIVE_LIMITS.maxNameLength} characters)`;
25690
+ if (name.includes("\\")) return `${name} uses a backslash; package paths use forward slashes`;
25691
+ if (name.startsWith("/") || /^[A-Za-z]:/.test(name)) return `${name} is an absolute path`;
25692
+ const segs = name.split("/");
25693
+ if (segs.some((s) => s === ".." || s === "." || s === "")) return `${name} has an empty, "." or ".." segment`;
25694
+ if (name.includes(":")) return `${name} holds a colon`;
25695
+ if (segs.length > ARCHIVE_LIMITS.maxSegments) return `${name} is nested too deeply`;
25696
+ for (const s of segs) {
25697
+ if (s.endsWith(".") || s.endsWith(" ")) return `${name} has a part that ends with a dot or a space`;
25698
+ const stem = s.split(".")[0]?.replace(/ +$/, "") ?? "";
25699
+ if (WINDOWS_DEVICE_RE.test(stem)) return `${name} uses a device name Windows has reserved`;
25700
+ }
25701
+ if (name !== name.normalize("NFC")) return `${name} is not in normalized (NFC) form`;
25702
+ return null;
25663
25703
  }
25664
- async function extractPdpkg(buffer) {
25665
- const zip = await import_jszip.default.loadAsync(buffer);
25666
- const out = /* @__PURE__ */ new Map();
25704
+ function u16(b, at) {
25705
+ return (b[at] ?? 0) | (b[at + 1] ?? 0) << 8;
25706
+ }
25707
+ function u32(b, at) {
25708
+ return u16(b, at) + u16(b, at + 2) * 65536;
25709
+ }
25710
+ function refuseUnicodePathField(raw, start, end, name) {
25711
+ let at = start;
25712
+ while (at < end) {
25713
+ if (at + 4 > end) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25714
+ const id = u16(raw, at);
25715
+ const len = u16(raw, at + 2);
25716
+ if (at + 4 + len > end) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25717
+ if (id === UNICODE_PATH_FIELD) throw new PackageVerificationError("UNSAFE_PATH", `${shown(name)} carries an alternate path field`, name);
25718
+ at += 4 + len;
25719
+ }
25720
+ }
25721
+ function checkLocalHeader(raw, centralName, name, localAt, centralStart) {
25722
+ if (localAt + LOCAL_LEN > centralStart || u32(raw, localAt) !== LOCAL_SIG) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP, name);
25723
+ const nameLen = u16(raw, localAt + 26);
25724
+ const extraLen = u16(raw, localAt + 28);
25725
+ const nameEnd = localAt + LOCAL_LEN + nameLen;
25726
+ if (nameEnd + extraLen > centralStart) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP, name);
25727
+ const localName = raw.subarray(localAt + LOCAL_LEN, nameEnd);
25728
+ if (localName.length !== centralName.length || !localName.every((b, i) => b === centralName[i])) {
25729
+ throw new PackageVerificationError("ARCHIVE_INVALID", `${shown(name)} is named differently in its local header`, name);
25730
+ }
25731
+ refuseUnicodePathField(raw, nameEnd, nameEnd + extraLen, name);
25732
+ }
25733
+ function scanCentralDirectory(raw) {
25734
+ const lowest = Math.max(0, raw.length - EOCD_LEN - 65535);
25735
+ let eocd = -1;
25736
+ for (let i = raw.length - EOCD_LEN; i >= lowest; i--) {
25737
+ if (u32(raw, i) === EOCD_SIG) {
25738
+ eocd = i;
25739
+ break;
25740
+ }
25741
+ }
25742
+ if (eocd < 0) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25743
+ if (eocd + EOCD_LEN + u16(raw, eocd + 20) !== raw.length) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25744
+ const count = u16(raw, eocd + 10);
25745
+ const size = u32(raw, eocd + 12);
25746
+ const offset = u32(raw, eocd + 16);
25747
+ if (count === 65535 || size === 4294967295 || offset === 4294967295) {
25748
+ throw new PackageVerificationError("ARCHIVE_INVALID", "the package is a zip64 archive, which a package never needs");
25749
+ }
25750
+ if (u16(raw, eocd + 4) !== 0 || u16(raw, eocd + 6) !== 0 || u16(raw, eocd + 8) !== count) {
25751
+ throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25752
+ }
25753
+ if (count > ARCHIVE_LIMITS.maxEntries) {
25754
+ throw new PackageVerificationError("TOO_LARGE", `the package holds too many files (over ${ARCHIVE_LIMITS.maxEntries})`);
25755
+ }
25756
+ if (offset + size !== eocd) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25757
+ const out = [];
25667
25758
  let total = 0;
25668
- for (const entry of Object.values(zip.files)) {
25669
- if (entry.name.includes("\0")) {
25670
- throw new Error(`Security violation: null byte in entry name: ${entry.name}`);
25759
+ let at = offset;
25760
+ for (let i = 0; i < count; i++) {
25761
+ if (at + CENTRAL_LEN > eocd || u32(raw, at) !== CENTRAL_SIG) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25762
+ const compressed = u32(raw, at + 20);
25763
+ const uncompressed = u32(raw, at + 24);
25764
+ const nameLen = u16(raw, at + 28);
25765
+ const next = at + CENTRAL_LEN + nameLen + u16(raw, at + 30) + u16(raw, at + 32);
25766
+ if (next > eocd) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25767
+ let name;
25768
+ try {
25769
+ name = nameDecoder.decode(raw.subarray(at + CENTRAL_LEN, at + CENTRAL_LEN + nameLen));
25770
+ } catch {
25771
+ throw new PackageVerificationError("ARCHIVE_INVALID", "a file name in the package is not UTF-8");
25772
+ }
25773
+ const centralName = raw.subarray(at + CENTRAL_LEN, at + CENTRAL_LEN + nameLen);
25774
+ const extraStart = at + CENTRAL_LEN + nameLen;
25775
+ refuseUnicodePathField(raw, extraStart, extraStart + u16(raw, at + 30), name);
25776
+ checkLocalHeader(raw, centralName, name, u32(raw, at + 42), offset);
25777
+ const external = u32(raw, at + 38);
25778
+ if ((Math.floor(external / 65536) & 61440) === 40960) {
25779
+ throw new PackageVerificationError("UNSAFE_PATH", `${shown(name)} is a link`, name);
25780
+ }
25781
+ const folder = (external & 16) !== 0 || name.endsWith("/");
25782
+ if (folder && uncompressed !== 0) throw new PackageVerificationError("ARCHIVE_INVALID", `${shown(name)} is marked as a folder but holds data`, name);
25783
+ if (!folder) {
25784
+ if (uncompressed > ARCHIVE_LIMITS.maxFileBytes) throw new PackageVerificationError("TOO_LARGE", `${shown(name)} is over ${ARCHIVE_LIMITS.maxFileBytes} bytes`, name);
25785
+ if (uncompressed > 0 && compressed === 0) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP, name);
25786
+ if (compressed > 0 && uncompressed / compressed > ARCHIVE_LIMITS.maxRatio) {
25787
+ throw new PackageVerificationError("TOO_LARGE", `${shown(name)} compresses more than ${ARCHIVE_LIMITS.maxRatio}:1`, name);
25788
+ }
25789
+ total += uncompressed;
25790
+ if (total > ARCHIVE_LIMITS.maxTotalBytes) throw new PackageVerificationError("TOO_LARGE", `the package is over ${ARCHIVE_LIMITS.maxTotalBytes} bytes unpacked`);
25791
+ }
25792
+ out.push({ name, compressed, uncompressed, folder });
25793
+ at = next;
25794
+ }
25795
+ if (at !== offset + size) throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25796
+ return out;
25797
+ }
25798
+ function checkNames(records) {
25799
+ const keys = /* @__PURE__ */ new Set();
25800
+ const files = records.filter((r) => !r.folder);
25801
+ for (const r of files) {
25802
+ const problem = entryNameProblem(r.name);
25803
+ if (problem) throw new PackageVerificationError("UNSAFE_PATH", problem, r.name);
25804
+ const key = r.name.toLowerCase();
25805
+ if (keys.has(key)) throw new PackageVerificationError("UNSAFE_PATH", `the package holds two entries with the same name (${r.name})`, r.name);
25806
+ keys.add(key);
25807
+ }
25808
+ for (const r of files) {
25809
+ const segs = r.name.toLowerCase().split("/");
25810
+ for (let i = 1; i < segs.length; i++) {
25811
+ const parent = segs.slice(0, i).join("/");
25812
+ if (keys.has(parent)) throw new PackageVerificationError("UNSAFE_PATH", `${r.name} uses ${parent} as a folder, but it is a file`, r.name);
25671
25813
  }
25672
- if (entry.name.startsWith("/") || /(^|\/)\.\.(\/|$)/.test(entry.name)) {
25673
- throw new Error(`Security violation: path traversal in entry: ${entry.name}`);
25814
+ }
25815
+ }
25816
+ function inflateOne(entry, limit, state) {
25817
+ return new Promise((resolveBytes, reject) => {
25818
+ const chunks = [];
25819
+ let size = 0;
25820
+ let settled = false;
25821
+ const stream = entry.internalStream("uint8array");
25822
+ const fail = (e) => {
25823
+ if (!settled) {
25824
+ settled = true;
25825
+ stream.pause();
25826
+ reject(e);
25827
+ }
25828
+ };
25829
+ stream.on("data", (chunk) => {
25830
+ if (settled) return;
25831
+ size += chunk.length;
25832
+ state.total += chunk.length;
25833
+ if (size > limit || size > ARCHIVE_LIMITS.maxFileBytes) {
25834
+ fail(new PackageVerificationError("TOO_LARGE", `${shown(entry.name)} is larger than its header says`, entry.name));
25835
+ return;
25836
+ }
25837
+ if (state.total > ARCHIVE_LIMITS.maxTotalBytes) {
25838
+ fail(new PackageVerificationError("TOO_LARGE", `the package is over ${ARCHIVE_LIMITS.maxTotalBytes} bytes unpacked`));
25839
+ return;
25840
+ }
25841
+ chunks.push(chunk);
25842
+ });
25843
+ stream.on("error", (e) => fail(new PackageVerificationError("ARCHIVE_INVALID", `${shown(entry.name)} could not be unpacked: ${e.message}`, entry.name)));
25844
+ stream.on("end", () => {
25845
+ if (settled) return;
25846
+ settled = true;
25847
+ const out = new Uint8Array(size);
25848
+ let at = 0;
25849
+ for (const c of chunks) {
25850
+ out.set(c, at);
25851
+ at += c.length;
25852
+ }
25853
+ resolveBytes(out);
25854
+ });
25855
+ stream.resume();
25856
+ });
25857
+ }
25858
+ async function readArchive(raw) {
25859
+ const records = scanCentralDirectory(raw);
25860
+ checkNames(records);
25861
+ let zip;
25862
+ try {
25863
+ zip = await import_jszip.default.loadAsync(raw, { createFolders: false });
25864
+ } catch {
25865
+ throw new PackageVerificationError("ARCHIVE_INVALID", NOT_A_ZIP);
25866
+ }
25867
+ const all = Object.values(zip.files);
25868
+ if (all.length !== records.length) throw new PackageVerificationError("ARCHIVE_INVALID", "the package holds two entries with the same name");
25869
+ const declared = new Map(records.map((r) => [r.name, r.uncompressed]));
25870
+ const out = /* @__PURE__ */ new Map();
25871
+ const state = { total: 0 };
25872
+ for (const [i, entry] of all.entries()) {
25873
+ if (entry.name !== records[i]?.name) {
25874
+ throw new PackageVerificationError("ARCHIVE_INVALID", `${shown(entry.name)} does not match the package's central directory`, entry.name);
25674
25875
  }
25675
- if (isSymlinkEntry(entry.unixPermissions)) {
25676
- throw new Error(`Security violation: symlink entry in archive: ${entry.name}`);
25876
+ const original = entry.unsafeOriginalName ?? entry.name;
25877
+ if (original !== entry.name || !declared.has(original)) {
25878
+ throw new PackageVerificationError("UNSAFE_PATH", `${shown(original)} is not a plain path inside the package`, original);
25677
25879
  }
25678
- if (entry.dir || isBinaryAsset(entry.name)) continue;
25679
- const bytes = await entry.async("uint8array");
25680
- if (bytes.length > MAX_FILE_SIZE_IN_ZIP) {
25681
- throw new Error(`File too large in package: ${entry.name} (${bytes.length} bytes, max ${MAX_FILE_SIZE_IN_ZIP})`);
25880
+ if (entry.dir) continue;
25881
+ out.set(entry.name, await inflateOne(entry, declared.get(entry.name) ?? 0, state));
25882
+ }
25883
+ return out;
25884
+ }
25885
+ function subtle() {
25886
+ const c = globalThis.crypto;
25887
+ if (!c?.subtle) throw new Error("WebCrypto (crypto.subtle) is not available in this runtime; Node 20 or later is required.");
25888
+ return c.subtle;
25889
+ }
25890
+ async function sha256Hex(bytes) {
25891
+ const buf = await subtle().digest("SHA-256", bytes);
25892
+ const out = new Uint8Array(buf);
25893
+ let hex = "";
25894
+ for (let i = 0; i < out.length; i++) hex += out[i].toString(16).padStart(2, "0");
25895
+ return hex;
25896
+ }
25897
+ async function archiveDigest(bytes) {
25898
+ return `sha256:${await sha256Hex(bytes)}`;
25899
+ }
25900
+ function invalid(message) {
25901
+ return new PackageVerificationError("MANIFEST_INVALID", message, "prompd.json");
25902
+ }
25903
+ function isRecord(v) {
25904
+ return typeof v === "object" && v !== null && !Array.isArray(v);
25905
+ }
25906
+ function stringList(v, field) {
25907
+ if (v === void 0) return void 0;
25908
+ if (!Array.isArray(v) || v.some((s) => typeof s !== "string" || !s)) throw invalid(`${field} must be a list of names`);
25909
+ return v;
25910
+ }
25911
+ function unscopedName(name) {
25912
+ const slash = name.indexOf("/");
25913
+ return name.startsWith("@") && slash > 0 ? name.slice(slash + 1) : name;
25914
+ }
25915
+ function parseManifest(bytes) {
25916
+ let text2;
25917
+ try {
25918
+ text2 = decoder.decode(bytes);
25919
+ } catch {
25920
+ throw invalid("prompd.json is not UTF-8 text");
25921
+ }
25922
+ let raw;
25923
+ try {
25924
+ raw = JSON.parse(text2, (k, v) => PROTO_KEYS.has(k) ? void 0 : v);
25925
+ } catch {
25926
+ throw invalid("prompd.json is not valid JSON");
25927
+ }
25928
+ if (!isRecord(raw)) throw invalid("prompd.json is not a JSON object");
25929
+ const { name, version: version2, type, dependencies, requires } = raw;
25930
+ if (typeof name !== "string" || !PACKAGE_NAME_RE.test(name)) throw invalid('prompd.json "name" must be a scoped package name like @scope/name');
25931
+ if (typeof version2 !== "string" || import_semver.default.valid(version2) !== version2) throw invalid('prompd.json "version" must be an exact semver version');
25932
+ let resolvedType = "package";
25933
+ if (type !== void 0) {
25934
+ if (typeof type !== "string" || !isValidPackageType(type)) {
25935
+ throw new PackageVerificationError("TYPE_INVALID", `package type "${String(type)}" is not one of package, workflow, skill, agent`, "prompd.json");
25936
+ }
25937
+ resolvedType = type;
25938
+ }
25939
+ let deps;
25940
+ if (dependencies !== void 0) {
25941
+ if (!isRecord(dependencies)) throw invalid('prompd.json "dependencies" must be an object');
25942
+ deps = {};
25943
+ for (const [dep, range] of Object.entries(dependencies)) {
25944
+ if (!PACKAGE_NAME_RE.test(dep)) throw invalid(`dependency "${dep}" is not a scoped package name`);
25945
+ if (typeof range !== "string" || import_semver.default.validRange(range) === null) throw invalid(`dependency "${dep}" has an invalid version range`);
25946
+ deps[dep] = range;
25947
+ }
25948
+ }
25949
+ let req;
25950
+ if (requires !== void 0) {
25951
+ if (!isRecord(requires)) throw invalid('prompd.json "requires" must be an object');
25952
+ const mcp = stringList(requires.mcp, "requires.mcp");
25953
+ const skills = stringList(requires.skills, "requires.skills");
25954
+ req = { ...mcp ? { mcp } : {}, ...skills ? { skills } : {} };
25955
+ }
25956
+ return {
25957
+ ...raw,
25958
+ name,
25959
+ version: version2,
25960
+ type: resolvedType,
25961
+ ...deps ? { dependencies: deps } : {},
25962
+ ...req ? { requires: req } : {}
25963
+ };
25964
+ }
25965
+ function invalid2(message, path) {
25966
+ return new PackageVerificationError("MANIFEST_INVALID", message, path);
25967
+ }
25968
+ function text(files, name) {
25969
+ const b = files.get(name);
25970
+ if (!b) throw invalid2(`an agent package must contain ${name}`, name);
25971
+ try {
25972
+ return decoder2.decode(b);
25973
+ } catch {
25974
+ throw invalid2(`${name} is not UTF-8 text`, name);
25975
+ }
25976
+ }
25977
+ function record(v) {
25978
+ return typeof v === "object" && v !== null && !Array.isArray(v) ? v : {};
25979
+ }
25980
+ function strings(v) {
25981
+ if (!Array.isArray(v)) return [];
25982
+ return v.filter((s) => typeof s === "string").map((s) => s.trim()).filter((s) => s.length > 0);
25983
+ }
25984
+ function yamlOf(src, path) {
25985
+ try {
25986
+ return (0, import_yaml.parse)(src);
25987
+ } catch {
25988
+ throw invalid2(`${path} is not valid YAML`, path);
25989
+ }
25990
+ }
25991
+ function frontmatter(src) {
25992
+ const m = /^---\r?\n([\s\S]*?)\r?\n---/.exec(src);
25993
+ return m ? record(yamlOf(m[1], "AGENT.md")) : {};
25994
+ }
25995
+ function unique(xs) {
25996
+ return [...new Set(xs)];
25997
+ }
25998
+ function unnamedMcp(addr) {
25999
+ return invalid2(`POLICY.yaml allows "${addr}", which can reach MCP servers it does not name; MCP access in a package must name each server (mcp:<server>/<tool> or mcp:<server>/*)`, "POLICY.yaml");
26000
+ }
26001
+ function mcpWireName(addr) {
26002
+ return invalid2(`POLICY.yaml allows "${addr}", an MCP wire name; in a package, allow MCP tools as mcp:<server>/<tool> or mcp:<server>/*`, "POLICY.yaml");
26003
+ }
26004
+ function mcpServerOf(addr) {
26005
+ if (addr.startsWith(MCP_WIRE_PREFIX)) throw mcpWireName(addr);
26006
+ const glob = addr.search(GLOB_RE);
26007
+ if (glob >= 0) {
26008
+ const literal = addr.slice(0, glob);
26009
+ if (MCP_PREFIX.startsWith(literal)) throw unnamedMcp(addr);
26010
+ if (MCP_WIRE_PREFIX.startsWith(literal)) throw mcpWireName(addr);
26011
+ if (literal.startsWith(MCP_PREFIX)) {
26012
+ const slash2 = addr.indexOf("/", MCP_PREFIX.length);
26013
+ const server = addr.slice(MCP_PREFIX.length, slash2 < 0 ? void 0 : slash2);
26014
+ if (GLOB_RE.test(server)) throw unnamedMcp(addr);
26015
+ }
26016
+ }
26017
+ if (!addr.startsWith(MCP_PREFIX)) return null;
26018
+ const slash = addr.indexOf("/", MCP_PREFIX.length);
26019
+ if (addr.slice(MCP_PREFIX.length, slash < 0 ? void 0 : slash).includes("\\")) {
26020
+ throw invalid2(`POLICY.yaml allows "${addr}"; MCP server names with escaped characters cannot be used in a package`, "POLICY.yaml");
26021
+ }
26022
+ const m = NAMED_MCP_RE.exec(addr);
26023
+ if (!m) throw unnamedMcp(addr);
26024
+ return m[1];
26025
+ }
26026
+ function checkAgentPackage(manifest, files) {
26027
+ const allowed = new Set(AGENT_PACKAGE_FILES);
26028
+ for (const name of files.keys()) {
26029
+ if (!allowed.has(name)) throw invalid2(`an agent package may hold only ${AGENT_PACKAGE_FILES.join(", ")}; found ${name}`, name);
26030
+ }
26031
+ for (const name of AGENT_PACKAGE_FILES) {
26032
+ if (!files.has(name)) throw invalid2(`an agent package must contain ${name}`, name);
26033
+ }
26034
+ const fm = frontmatter(text(files, "AGENT.md"));
26035
+ const policy = record(yamlOf(text(files, "POLICY.yaml"), "POLICY.yaml"));
26036
+ const deps = new Set(Object.keys(manifest.dependencies ?? {}).map(unscopedName));
26037
+ const reqSkills = new Set(manifest.requires?.skills ?? []);
26038
+ const reqMcp = new Set(manifest.requires?.mcp ?? []);
26039
+ if (fm.canCallAll === true) throw invalid2("canCallAll cannot be used in a package; list the agents in canCall and declare them as dependencies", "AGENT.md");
26040
+ const skills = unique(strings(policy.skills));
26041
+ for (const s of skills) {
26042
+ if (!deps.has(s) && !reqSkills.has(s)) throw invalid2(`POLICY.yaml grants skill "${s}", which is neither a dependency nor listed in requires.skills`, "POLICY.yaml");
26043
+ }
26044
+ const after = [];
26045
+ for (const trig of Array.isArray(fm.triggers) ? fm.triggers : []) {
26046
+ const t = record(trig);
26047
+ if (t.type === "run-complete") after.push(...strings(record(t.config).after));
26048
+ }
26049
+ const agents = unique([...strings(fm.canCall), ...after]);
26050
+ for (const a of agents) {
26051
+ if (!deps.has(a)) throw invalid2(`AGENT.md calls agent "${a}", which is not a dependency`, "AGENT.md");
26052
+ }
26053
+ const mcp = [];
26054
+ for (const addr of strings(record(policy.tools).allow)) {
26055
+ const server = mcpServerOf(addr);
26056
+ if (server !== null) mcp.push(server);
26057
+ }
26058
+ const servers = unique(mcp);
26059
+ for (const s of servers) {
26060
+ if (!reqMcp.has(s)) throw invalid2(`POLICY.yaml allows MCP server "${s}", which is not listed in requires.mcp`, "POLICY.yaml");
26061
+ }
26062
+ return { skills: skills.filter((s) => deps.has(s)), agents, mcp: servers };
26063
+ }
26064
+ function integrityOf(raw) {
26065
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
26066
+ throw new PackageVerificationError("INTEGRITY_MISSING", 'the package has no integrity block; republish it with "prompd package create"', MANIFEST_FILE);
26067
+ }
26068
+ const r = raw;
26069
+ if (r.algorithm !== "sha256") {
26070
+ throw new PackageVerificationError("UNSUPPORTED_ALGORITHM", `integrity algorithm "${String(r.algorithm)}" is not supported (sha256 only)`, MANIFEST_FILE);
26071
+ }
26072
+ const files = r.files;
26073
+ if (typeof files !== "object" || files === null || Array.isArray(files)) {
26074
+ throw new PackageVerificationError("INTEGRITY_MISSING", "the integrity block lists no files", MANIFEST_FILE);
26075
+ }
26076
+ const out = {};
26077
+ for (const [p, h] of Object.entries(files)) {
26078
+ if (typeof h !== "string" || !HEX_RE.test(h)) throw new PackageVerificationError("MANIFEST_INVALID", `the recorded hash for ${p} is not a sha256 hex digest`, MANIFEST_FILE);
26079
+ out[p] = h;
26080
+ }
26081
+ return { algorithm: "sha256", files: out };
26082
+ }
26083
+ async function openPdpkg(input, expect = {}) {
26084
+ if (input.length > MAX_PACKAGE_BYTES) {
26085
+ throw new PackageVerificationError("TOO_LARGE", `the package is ${input.length} bytes (max ${MAX_PACKAGE_BYTES})`);
26086
+ }
26087
+ const bytes = new Uint8Array(input);
26088
+ const digest = await archiveDigest(bytes);
26089
+ if (expect.digest !== void 0 && expect.digest !== digest) {
26090
+ throw new PackageVerificationError("DIGEST_MISMATCH", `the package is ${digest}, expected ${expect.digest}`);
26091
+ }
26092
+ const entries = await readArchive(bytes);
26093
+ for (const name of entries.keys()) {
26094
+ const folded = name.toLowerCase();
26095
+ if (folded === RESERVED_MANIFEST || folded === MANIFEST_FILE && name !== MANIFEST_FILE) {
26096
+ throw new PackageVerificationError("MANIFEST_RESERVED", `the package holds a root ${name}; the manifest is prompd.json only`, name);
25682
26097
  }
25683
- total += bytes.length;
25684
- if (total > MAX_TOTAL_EXTRACTED_SIZE) {
25685
- throw new Error(`Package total decompressed size exceeds limit (${MAX_TOTAL_EXTRACTED_SIZE} bytes). Possible decompression bomb.`);
26098
+ if (RESERVED_LAYOUT.has(folded)) {
26099
+ throw new PackageVerificationError("MANIFEST_RESERVED", `the package holds a root ${name}, a name the install writes itself`, name);
26100
+ }
26101
+ }
26102
+ const manifestBytes = entries.get(MANIFEST_FILE);
26103
+ if (!manifestBytes) throw new PackageVerificationError("MANIFEST_MISSING", "the package has no prompd.json", MANIFEST_FILE);
26104
+ const parsed = parseManifest(manifestBytes);
26105
+ const integrity = integrityOf(parsed.integrity);
26106
+ const files = /* @__PURE__ */ new Map();
26107
+ for (const [p, b] of entries) if (p !== MANIFEST_FILE) files.set(p, b);
26108
+ for (const p of files.keys()) {
26109
+ if (!Object.prototype.hasOwnProperty.call(integrity.files, p)) {
26110
+ throw new PackageVerificationError("FILE_UNLISTED", `${p} is not listed in the integrity block`, p);
26111
+ }
26112
+ }
26113
+ for (const p of Object.keys(integrity.files)) {
26114
+ if (!files.has(p)) throw new PackageVerificationError("FILE_MISSING", `${p} is listed in the integrity block but not in the package`, p);
26115
+ }
26116
+ for (const [p, b] of files) {
26117
+ if (await sha256Hex(b) !== integrity.files[p]) {
26118
+ throw new PackageVerificationError("HASH_MISMATCH", `${p} does not match its recorded hash`, p);
26119
+ }
26120
+ }
26121
+ const manifest = { ...parsed, integrity };
26122
+ const agentRefs = manifest.type === "agent" ? checkAgentPackage(manifest, files) : void 0;
26123
+ if (expect.name !== void 0 && manifest.name !== expect.name) {
26124
+ throw new PackageVerificationError("NAME_MISMATCH", `asked for ${expect.name}, the package is ${manifest.name}`);
26125
+ }
26126
+ if (expect.range !== void 0 && !import_semver.default.satisfies(manifest.version, expect.range)) {
26127
+ throw new PackageVerificationError("VERSION_MISMATCH", `asked for ${expect.range}, the package is ${manifest.version}`);
26128
+ }
26129
+ return { manifest, manifestBytes, files, digest, ...agentRefs ? { agentRefs } : {} };
26130
+ }
26131
+ function isBinaryAsset(name) {
26132
+ const dot = name.lastIndexOf(".");
26133
+ return dot >= 0 && BINARY_ASSET_EXT.has(name.slice(dot + 1).toLowerCase());
26134
+ }
26135
+ async function extractPdpkg(buffer, expect = {}) {
26136
+ const pkg = await openPdpkg(buffer, expect);
26137
+ const out = /* @__PURE__ */ new Map();
26138
+ out.set("prompd.json", textDecoder.decode(pkg.manifestBytes));
26139
+ for (const [p, b] of pkg.files) {
26140
+ if (isBinaryAsset(p)) continue;
26141
+ try {
26142
+ out.set(p, textDecoder.decode(b));
26143
+ } catch {
26144
+ throw new Error(`${p} in ${pkg.manifest.name}@${pkg.manifest.version} is not UTF-8 text`);
25686
26145
  }
25687
- out.set(entry.name, pdpkgDecoder.decode(bytes));
25688
26146
  }
25689
26147
  return out;
25690
26148
  }
@@ -25734,10 +26192,29 @@ function createCoreStages() {
25734
26192
  new CodeGenerationStage()
25735
26193
  ];
25736
26194
  }
25737
- var yaml, import_semver, nunjucks, import_jszip, PrompdParser, PACKAGE_TYPE_DIRS, VALID_PACKAGE_TYPES, PrompdError, ParseError, ValidationError, CompilationError, SecurityError, CompilationContext, DEFAULT_SECURITY_CONFIG, PROMPD_EXTENSIONS, CompilerPipeline, LexicalAnalysisStage, DependencyResolutionStage, SemanticAnalysisStage, _SectionOverrideProcessor, SectionOverrideProcessor, EXTENSION_TO_LANGUAGE_ALIASES, globalIncludeStacks, compilationCounter, PrompdLoader, TemplateProcessingStage, MarkdownFormatter, OpenAIFormatter, AnthropicFormatter, CodeGenerationStage, BINARY_ASSET_EXT, MAX_FILE_SIZE_IN_ZIP, MAX_TOTAL_EXTRACTED_SIZE, pdpkgDecoder, _MemoryFileSystem, MemoryFileSystem, HybridFileSystem, MAX_PACKAGE_SIZE, PrompdCompiler, ASSIGNMENT_OPS, OP_CONSTRUCTS, OPS;
26195
+ function same(a, b) {
26196
+ if (a.length !== b.length) return false;
26197
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
26198
+ return true;
26199
+ }
26200
+ async function verifyInstalled(read, expectedDigest, expect = {}) {
26201
+ const archive = await read(ARCHIVE_COPY);
26202
+ if (!archive) {
26203
+ throw new PackageVerificationError("FILE_MISSING", `${ARCHIVE_COPY} is missing, so this install cannot be verified; reinstall the package`, ARCHIVE_COPY);
26204
+ }
26205
+ const pkg = await openPdpkg(archive, { ...expect, digest: expectedDigest });
26206
+ for (const [p, b] of pkg.files) {
26207
+ const onDisk = await read(p);
26208
+ if (!onDisk) throw new PackageVerificationError("FILE_MISSING", `${p} is missing from the installed package`, p);
26209
+ if (!same(onDisk, b)) throw new PackageVerificationError("HASH_MISMATCH", `${p} does not match its recorded hash`, p);
26210
+ }
26211
+ return pkg;
26212
+ }
26213
+ var yaml, import_yaml, import_semver, nunjucks, import_jszip, PrompdParser, PACKAGE_TYPE_DIRS, VALID_PACKAGE_TYPES, PrompdError, ParseError, ValidationError, CompilationError, SecurityError, CompilationContext, DEFAULT_SECURITY_CONFIG, PROMPD_EXTENSIONS, CompilerPipeline, LexicalAnalysisStage, DependencyResolutionStage, SemanticAnalysisStage, _SectionOverrideProcessor, SectionOverrideProcessor, EXTENSION_TO_LANGUAGE_ALIASES, globalIncludeStacks, compilationCounter, PrompdLoader, TemplateProcessingStage, MarkdownFormatter, OpenAIFormatter, AnthropicFormatter, CodeGenerationStage, PackageVerificationError, ARCHIVE_LIMITS, EOCD_SIG, CENTRAL_SIG, EOCD_LEN, CENTRAL_LEN, LOCAL_SIG, LOCAL_LEN, UNICODE_PATH_FIELD, WINDOWS_DEVICE_RE, NOT_A_ZIP, BIDI_RE, nameDecoder, PACKAGE_NAME_RE, decoder, PROTO_KEYS, AGENT_PACKAGE_FILES, decoder2, MCP_PREFIX, MCP_WIRE_PREFIX, GLOB_RE, NAMED_MCP_RE, ARCHIVE_COPY, META_FILE, MAX_PACKAGE_BYTES, MANIFEST_FILE, RESERVED_MANIFEST, RESERVED_LAYOUT, HEX_RE, BINARY_ASSET_EXT, textDecoder, MemoryFileSystem, HybridFileSystem, INSTALL_LIMITS, textDecoder2, PrompdCompiler, ASSIGNMENT_OPS, OP_CONSTRUCTS, OPS, RESERVED_LAYOUT2, encoder;
25738
26214
  var init_dist = __esm({
25739
- "../../node_modules/.pnpm/@prompd+core@0.6.0/node_modules/@prompd/core/dist/index.js"() {
26215
+ "../../node_modules/.pnpm/@prompd+core@0.7.0/node_modules/@prompd/core/dist/index.js"() {
25740
26216
  yaml = __toESM(require_dist(), 1);
26217
+ import_yaml = __toESM(require_dist(), 1);
25741
26218
  import_semver = __toESM(require_semver2(), 1);
25742
26219
  nunjucks = __toESM(require_nunjucks(), 1);
25743
26220
  import_jszip = __toESM(require_lib4(), 1);
@@ -25874,7 +26351,7 @@ var init_dist = __esm({
25874
26351
  "package": "packages",
25875
26352
  "workflow": "workflows",
25876
26353
  "skill": "skills",
25877
- "node-template": "templates"
26354
+ "agent": "agents"
25878
26355
  };
25879
26356
  VALID_PACKAGE_TYPES = Object.keys(PACKAGE_TYPE_DIRS);
25880
26357
  PrompdError = class _PrompdError extends Error {
@@ -27257,13 +27734,13 @@ ${yamlContent}` : yamlContent;
27257
27734
  const line = lines[i].trim();
27258
27735
  if (!line) continue;
27259
27736
  const values = this.parseCsvLine(line);
27260
- const record = {};
27737
+ const record3 = {};
27261
27738
  for (let j = 0; j < headers.length; j++) {
27262
27739
  const header = headers[j].trim();
27263
27740
  const value = values[j]?.trim() ?? "";
27264
- record[header] = value;
27741
+ record3[header] = value;
27265
27742
  }
27266
- records.push(record);
27743
+ records.push(record3);
27267
27744
  }
27268
27745
  return records;
27269
27746
  }
@@ -27272,25 +27749,25 @@ ${yamlContent}` : yamlContent;
27272
27749
  */
27273
27750
  parseCsvLine(line) {
27274
27751
  const result = [];
27275
- let current = "";
27752
+ let current2 = "";
27276
27753
  let inQuotes = false;
27277
27754
  for (let i = 0; i < line.length; i++) {
27278
27755
  const char = line[i];
27279
27756
  if (char === '"') {
27280
27757
  if (inQuotes && line[i + 1] === '"') {
27281
- current += '"';
27758
+ current2 += '"';
27282
27759
  i++;
27283
27760
  } else {
27284
27761
  inQuotes = !inQuotes;
27285
27762
  }
27286
27763
  } else if (char === "," && !inQuotes) {
27287
- result.push(current);
27288
- current = "";
27764
+ result.push(current2);
27765
+ current2 = "";
27289
27766
  } else {
27290
- current += char;
27767
+ current2 += char;
27291
27768
  }
27292
27769
  }
27293
- result.push(current);
27770
+ result.push(current2);
27294
27771
  return result;
27295
27772
  }
27296
27773
  async process(context) {
@@ -27418,8 +27895,8 @@ ${yamlContent}` : yamlContent;
27418
27895
  return content;
27419
27896
  }
27420
27897
  if (parentData.content) {
27421
- const parentDir = fs6.dirname(parentFile);
27422
- parentData.content = this.resolveIncludePaths(parentData.content, parentDir);
27898
+ const parentDir2 = fs6.dirname(parentFile);
27899
+ parentData.content = this.resolveIncludePaths(parentData.content, parentDir2);
27423
27900
  }
27424
27901
  const overrides = context.metadata?.override || {};
27425
27902
  if (parentData.content || content) {
@@ -27972,7 +28449,7 @@ ${content}` : parentData.content;
27972
28449
  async validateParentFileReferences(context, metadata, fs6, parentFile) {
27973
28450
  if (!metadata) return;
27974
28451
  const metadataAsRecord = metadata;
27975
- const parentDir = fs6.dirname(parentFile);
28452
+ const parentDir2 = fs6.dirname(parentFile);
27976
28453
  const fileFields = ["system", "task", "user", "assistant", "response", "output", "context"];
27977
28454
  for (const field of fileFields) {
27978
28455
  const fieldValue = metadataAsRecord[field];
@@ -27980,7 +28457,7 @@ ${content}` : parentData.content;
27980
28457
  const refs = Array.isArray(fieldValue) ? fieldValue.filter((v) => typeof v === "string") : typeof fieldValue === "string" ? [fieldValue] : [];
27981
28458
  for (const ref of refs) {
27982
28459
  if (!ref.startsWith("./") && !ref.startsWith("../")) continue;
27983
- const resolvedPath = fs6.resolve(parentDir, ref);
28460
+ const resolvedPath = fs6.resolve(parentDir2, ref);
27984
28461
  const exists = await Promise.resolve(fs6.exists(resolvedPath));
27985
28462
  if (!exists) {
27986
28463
  const location = context.findLocation(/inherits:/);
@@ -28315,6 +28792,49 @@ ${firstUserMsg.content}`;
28315
28792
  return "Code Generation";
28316
28793
  }
28317
28794
  };
28795
+ PackageVerificationError = class extends Error {
28796
+ constructor(code3, message, path) {
28797
+ super(message);
28798
+ this.name = "PackageVerificationError";
28799
+ this.code = code3;
28800
+ if (path !== void 0) this.path = path;
28801
+ }
28802
+ };
28803
+ ARCHIVE_LIMITS = {
28804
+ maxEntries: 2e3,
28805
+ maxFileBytes: 10 * 1024 * 1024,
28806
+ maxTotalBytes: 500 * 1024 * 1024,
28807
+ maxRatio: 100,
28808
+ maxNameLength: 512,
28809
+ maxSegments: 24
28810
+ };
28811
+ EOCD_SIG = 101010256;
28812
+ CENTRAL_SIG = 33639248;
28813
+ EOCD_LEN = 22;
28814
+ CENTRAL_LEN = 46;
28815
+ LOCAL_SIG = 67324752;
28816
+ LOCAL_LEN = 30;
28817
+ UNICODE_PATH_FIELD = 28789;
28818
+ WINDOWS_DEVICE_RE = /^(con|prn|aux|nul|conin\$|conout\$|com[0-9\u00b9\u00b2\u00b3]|lpt[0-9\u00b9\u00b2\u00b3])$/i;
28819
+ NOT_A_ZIP = "the package is not a readable zip";
28820
+ BIDI_RE = /[\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
28821
+ nameDecoder = new TextDecoder("utf-8", { fatal: true });
28822
+ PACKAGE_NAME_RE = /^@(?!\.+\/)[a-z0-9._-]+\/(?!\.+$)[a-z0-9._-]+$/;
28823
+ decoder = new TextDecoder("utf-8", { fatal: true });
28824
+ PROTO_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
28825
+ AGENT_PACKAGE_FILES = ["AGENT.md", "SOUL.md", "PERSONA.md", "POLICY.yaml"];
28826
+ decoder2 = new TextDecoder("utf-8", { fatal: true });
28827
+ MCP_PREFIX = "mcp:";
28828
+ MCP_WIRE_PREFIX = "mcp_";
28829
+ GLOB_RE = /[*?]/;
28830
+ NAMED_MCP_RE = /^mcp:([^*?/]+)\//;
28831
+ ARCHIVE_COPY = ".package.pdpkg";
28832
+ META_FILE = ".prmdmeta";
28833
+ MAX_PACKAGE_BYTES = 50 * 1024 * 1024;
28834
+ MANIFEST_FILE = "prompd.json";
28835
+ RESERVED_MANIFEST = "manifest.json";
28836
+ RESERVED_LAYOUT = new Set([ARCHIVE_COPY, META_FILE].map((n) => n.toLowerCase()));
28837
+ HEX_RE = /^[0-9a-f]{64}$/;
28318
28838
  BINARY_ASSET_EXT = /* @__PURE__ */ new Set([
28319
28839
  "png",
28320
28840
  "jpg",
@@ -28350,10 +28870,8 @@ ${firstUserMsg.content}`;
28350
28870
  "mov",
28351
28871
  "avi"
28352
28872
  ]);
28353
- MAX_FILE_SIZE_IN_ZIP = 10 * 1024 * 1024;
28354
- MAX_TOTAL_EXTRACTED_SIZE = 500 * 1024 * 1024;
28355
- pdpkgDecoder = new TextDecoder();
28356
- _MemoryFileSystem = class _MemoryFileSystem2 {
28873
+ textDecoder = new TextDecoder("utf-8", { fatal: true });
28874
+ MemoryFileSystem = class {
28357
28875
  constructor(files = {}) {
28358
28876
  this.files = /* @__PURE__ */ new Map();
28359
28877
  for (const [filePath, content] of Object.entries(files)) {
@@ -28423,18 +28941,19 @@ ${firstUserMsg.content}`;
28423
28941
  /**
28424
28942
  * Extract a `.pdpkg` (ZIP) buffer into memory under getPackagePath(name, ver).
28425
28943
  *
28426
- * Uses JSZip — isomorphic (browser + Node) — so this is the SINGLE package-ingest
28427
- * path for every host (replacing the CLI's Node-only adm-zip subclass and the
28428
- * skill installer's ad-hoc unzip). Text files only: binary assets aren't
28944
+ * Verifies the archive through openPdpkg (isomorphic, browser + Node), so this is
28945
+ * the SINGLE package-ingest path for every host (replacing the CLI's Node-only
28946
+ * adm-zip subclass and the skill installer's ad-hoc unzip). Text files only: binary assets aren't
28429
28947
  * representable in the string-backed FS, so they're skipped (a `using:` package's
28430
28948
  * .prmd/.md/.json/.yaml is what matters for compilation). Validates entry paths
28431
28949
  * can't escape the package directory.
28432
28950
  */
28433
- async addPackage(packageName, version2, packageBuffer) {
28434
- if (packageBuffer.length > _MemoryFileSystem2.MAX_PACKAGE_SIZE) {
28435
- throw new Error(`Package too large: ${packageBuffer.length} bytes (max ${_MemoryFileSystem2.MAX_PACKAGE_SIZE})`);
28436
- }
28437
- const files = await extractPdpkg(packageBuffer);
28951
+ async addPackage(packageName, version2, packageBuffer, expect = {}) {
28952
+ const files = await extractPdpkg(packageBuffer, {
28953
+ name: packageName,
28954
+ ...import_semver.default.validRange(version2) !== null ? { range: version2 } : {},
28955
+ ...expect
28956
+ });
28438
28957
  const packagePath = this.getPackagePath(packageName, version2);
28439
28958
  const packagePrefix = this.normalizePath(packagePath.endsWith("/") ? packagePath : packagePath + "/");
28440
28959
  const packageRoot = this.normalizePath(packagePath);
@@ -28476,8 +28995,6 @@ ${firstUserMsg.content}`;
28476
28995
  return toRelKey(filePath);
28477
28996
  }
28478
28997
  };
28479
- _MemoryFileSystem.MAX_PACKAGE_SIZE = 50 * 1024 * 1024;
28480
- MemoryFileSystem = _MemoryFileSystem;
28481
28998
  HybridFileSystem = class {
28482
28999
  constructor(files = {}, backend) {
28483
29000
  this.mem = new MemoryFileSystem(files);
@@ -28497,8 +29014,8 @@ ${firstUserMsg.content}`;
28497
29014
  }
28498
29015
  /** Ingest a `.pdpkg` (ZIP) buffer into the in-memory layer, so package files are
28499
29016
  * served synchronously alongside the workspace sources. */
28500
- addPackage(packageName, version2, packageBuffer) {
28501
- return this.mem.addPackage(packageName, version2, packageBuffer);
29017
+ addPackage(packageName, version2, packageBuffer, expect = {}) {
29018
+ return this.mem.addPackage(packageName, version2, packageBuffer, expect);
28502
29019
  }
28503
29020
  exists(filePath) {
28504
29021
  if (this.mem.exists(filePath)) return true;
@@ -28535,7 +29052,15 @@ ${firstUserMsg.content}`;
28535
29052
  return toRelKey(filePath);
28536
29053
  }
28537
29054
  };
28538
- MAX_PACKAGE_SIZE = 50 * 1024 * 1024;
29055
+ INSTALL_LIMITS = {
29056
+ /** Dependencies one manifest may declare. */
29057
+ maxDependencies: 100,
29058
+ /** Packages in one install tree, the requested package included. */
29059
+ maxPackages: 500,
29060
+ /** Unpacked bytes across the whole tree (1 GiB). */
29061
+ maxTotalBytes: 1024 * 1024 * 1024
29062
+ };
29063
+ textDecoder2 = new TextDecoder("utf-8", { fatal: true });
28539
29064
  PrompdCompiler = class {
28540
29065
  constructor(options = {}) {
28541
29066
  this.securityConfig = options.securityConfig || DEFAULT_SECURITY_CONFIG;
@@ -28627,6 +29152,8 @@ ${firstUserMsg.content}`;
28627
29152
  "~",
28628
29153
  ";"
28629
29154
  ].sort((a, b) => b.length - a.length);
29155
+ RESERVED_LAYOUT2 = new Set([ARCHIVE_COPY, META_FILE].map((n) => n.toLowerCase()));
29156
+ encoder = new TextEncoder();
28630
29157
  }
28631
29158
  });
28632
29159
 
@@ -28870,11 +29397,11 @@ async function ensurePrivateDir(dir) {
28870
29397
  } catch {
28871
29398
  }
28872
29399
  }
28873
- async function writePrivate(abs, text) {
29400
+ async function writePrivate(abs, text2) {
28874
29401
  await fs5.mkdir(dirname4(abs), { recursive: true, mode: 448 });
28875
29402
  const tmp = join5(dirname4(abs), `.${basename3(abs)}.tmp-${randomBytes2(8).toString("hex")}`);
28876
29403
  try {
28877
- await fs5.writeFile(tmp, text, { encoding: "utf8", mode: 384 });
29404
+ await fs5.writeFile(tmp, text2, { encoding: "utf8", mode: 384 });
28878
29405
  try {
28879
29406
  await fs5.chmod(tmp, 384);
28880
29407
  } catch {
@@ -28895,8 +29422,8 @@ function fileTextStore(abs) {
28895
29422
  throw e;
28896
29423
  }
28897
29424
  },
28898
- write: (text) => writePrivate(abs, text),
28899
- preserve: (text) => writePrivate(`${abs}.bad`, text)
29425
+ write: (text2) => writePrivate(abs, text2),
29426
+ preserve: (text2) => writePrivate(`${abs}.bad`, text2)
28900
29427
  };
28901
29428
  }
28902
29429
  async function realOrAncestor(abs) {
@@ -29045,11 +29572,11 @@ async function deviceLogin(opts) {
29045
29572
  body: JSON.stringify(body),
29046
29573
  signal: opts.signal
29047
29574
  });
29048
- const text = await res.text();
29575
+ const text2 = await res.text();
29049
29576
  try {
29050
- return JSON.parse(text);
29577
+ return JSON.parse(text2);
29051
29578
  } catch {
29052
- const looksLikeHtml = /^\s*</.test(text);
29579
+ const looksLikeHtml = /^\s*</.test(text2);
29053
29580
  throw new Error(
29054
29581
  `${url} answered ${res.status} with ${looksLikeHtml ? "an HTML page" : "a non-JSON body"}, not JSON.` + (res.status === 404 ? `
29055
29582
  That usually means --base is wrong. The device endpoints live under /api \u2014 try --base ${base.replace(/\/api$/, "")}/api` : "")
@@ -31247,7 +31774,7 @@ var require_extension = __commonJS({
31247
31774
  if (dest[name] === void 0) dest[name] = [elem];
31248
31775
  else dest[name].push(elem);
31249
31776
  }
31250
- function parse3(header) {
31777
+ function parse4(header) {
31251
31778
  const offers = /* @__PURE__ */ Object.create(null);
31252
31779
  let params = /* @__PURE__ */ Object.create(null);
31253
31780
  let mustUnescape = false;
@@ -31387,7 +31914,7 @@ var require_extension = __commonJS({
31387
31914
  }).join(", ");
31388
31915
  }).join(", ");
31389
31916
  }
31390
- module.exports = { format, parse: parse3 };
31917
+ module.exports = { format, parse: parse4 };
31391
31918
  }
31392
31919
  });
31393
31920
 
@@ -31421,7 +31948,7 @@ var require_websocket = __commonJS({
31421
31948
  var {
31422
31949
  EventTarget: { addEventListener, removeEventListener }
31423
31950
  } = require_event_target();
31424
- var { format, parse: parse3 } = require_extension();
31951
+ var { format, parse: parse4 } = require_extension();
31425
31952
  var { toBuffer } = require_buffer_util();
31426
31953
  var kAborted = Symbol("kAborted");
31427
31954
  var protocolVersions = [8, 13];
@@ -32098,7 +32625,7 @@ var require_websocket = __commonJS({
32098
32625
  }
32099
32626
  let extensions;
32100
32627
  try {
32101
- extensions = parse3(secWebSocketExtensions);
32628
+ extensions = parse4(secWebSocketExtensions);
32102
32629
  } catch (err) {
32103
32630
  const message = "Invalid Sec-WebSocket-Extensions header";
32104
32631
  abortHandshake(websocket, socket, message);
@@ -32390,7 +32917,7 @@ var require_subprotocol = __commonJS({
32390
32917
  "../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/subprotocol.js"(exports, module) {
32391
32918
  "use strict";
32392
32919
  var { tokenChars } = require_validation();
32393
- function parse3(header) {
32920
+ function parse4(header) {
32394
32921
  const protocols = /* @__PURE__ */ new Set();
32395
32922
  let start = -1;
32396
32923
  let end = -1;
@@ -32426,7 +32953,7 @@ var require_subprotocol = __commonJS({
32426
32953
  protocols.add(protocol);
32427
32954
  return protocols;
32428
32955
  }
32429
- module.exports = { parse: parse3 };
32956
+ module.exports = { parse: parse4 };
32430
32957
  }
32431
32958
  });
32432
32959
 
@@ -32957,6 +33484,7 @@ __export(crew_exports, {
32957
33484
  AUTONOMY_TOOLS: () => AUTONOMY_TOOLS,
32958
33485
  CHECK_IN_BLOCK: () => CHECK_IN_BLOCK,
32959
33486
  COMMAND_CAPABILITIES: () => COMMAND_CAPABILITIES,
33487
+ CREW_DEFINITION_MARKERS: () => CREW_DEFINITION_MARKERS,
32960
33488
  CREW_EXCLUDED_TOOLS: () => CREW_EXCLUDED_TOOLS,
32961
33489
  CREW_SEG: () => CREW_SEG,
32962
33490
  DEPLOYMENT_FILE: () => DEPLOYMENT_FILE,
@@ -32966,16 +33494,23 @@ __export(crew_exports, {
32966
33494
  DONT_BLANK: () => DONT_BLANK,
32967
33495
  DONT_CONTROL: () => DONT_CONTROL,
32968
33496
  DONT_TOO_LONG: () => DONT_TOO_LONG,
33497
+ MANAGED_IN_SESSION_REFUSED: () => MANAGED_IN_SESSION_REFUSED,
33498
+ MANAGED_LOCKED: () => MANAGED_LOCKED,
33499
+ MANAGED_UNREADABLE: () => MANAGED_UNREADABLE,
33500
+ MANAGED_UNTRUSTED: () => MANAGED_UNTRUSTED,
32969
33501
  MAX_ROOM_BRIEF: () => MAX_ROOM_BRIEF,
33502
+ MCP_DENY_ALL: () => MCP_DENY_ALL,
32970
33503
  MEMORY_USERS_DIR: () => MEMORY_USERS_DIR,
32971
33504
  NOT_IN_YOUR_MEMORY: () => NOT_IN_YOUR_MEMORY,
32972
33505
  NO_ASKER_MEMORY_READ_ONLY: () => NO_ASKER_MEMORY_READ_ONLY,
33506
+ NO_TOOL_SENTINEL: () => NO_TOOL_SENTINEL,
32973
33507
  PROJECT_MARKER_FILE: () => PROJECT_MARKER_FILE,
32974
33508
  ROOM_KIND: () => ROOM_KIND,
32975
33509
  ROOM_MEMORY_READ_ONLY: () => ROOM_MEMORY_READ_ONLY,
32976
33510
  RUN_STATUS_VALUES: () => RUN_STATUS_VALUES,
32977
33511
  RoomReadError: () => RoomReadError,
32978
33512
  RoomStore: () => RoomStore,
33513
+ accessAllows: () => accessAllows,
32979
33514
  advance: () => advance,
32980
33515
  agentMemoryRoot: () => agentMemoryRoot,
32981
33516
  allowedAutonomy: () => allowedAutonomy,
@@ -32988,7 +33523,9 @@ __export(crew_exports, {
32988
33523
  callCandidates: () => callCandidates,
32989
33524
  callReach: () => callReach,
32990
33525
  closeRoomByHuman: () => closeRoomByHuman,
33526
+ copyCrewAgentAt: () => copyCrewAgentAt,
32991
33527
  crewAgentDir: () => crewAgentDir,
33528
+ crewAgentPresent: () => crewAgentPresent,
32992
33529
  crewAgentSessionsRoot: () => crewAgentSessionsRoot,
32993
33530
  crewBudgetConstraints: () => crewBudgetConstraints,
32994
33531
  crewListEntry: () => crewListEntry,
@@ -33003,9 +33540,11 @@ __export(crew_exports, {
33003
33540
  deploymentRootFor: () => deploymentRootFor,
33004
33541
  dontsProblems: () => dontsProblems,
33005
33542
  editFindingByHuman: () => editFindingByHuman,
33543
+ egressIsEmpty: () => egressIsEmpty,
33006
33544
  emptyDeployment: () => emptyDeployment,
33007
33545
  encodeRoomLine: () => encodeRoomLine,
33008
33546
  enforcedLevel: () => enforcedLevel,
33547
+ filterDefinition: () => filterDefinition,
33009
33548
  findingsPath: () => findingsPath,
33010
33549
  finishTurn: () => finishTurn,
33011
33550
  foldRoom: () => foldRoom,
@@ -33013,7 +33552,10 @@ __export(crew_exports, {
33013
33552
  grantOfferedTools: () => grantOfferedTools,
33014
33553
  grantsCommandTools: () => grantsCommandTools,
33015
33554
  interjectHuman: () => interjectHuman,
33555
+ intersectAllowList: () => intersectAllowList,
33016
33556
  isAutonomyPreset: () => isAutonomyPreset,
33557
+ isManaged: () => isManaged,
33558
+ isManagedOnDisk: () => isManagedOnDisk,
33017
33559
  isOrchestrator: () => isOrchestrator,
33018
33560
  isRoomSafeTool: () => isRoomSafeTool,
33019
33561
  isSafeProjectPath: () => isSafeProjectPath,
@@ -33024,19 +33566,26 @@ __export(crew_exports, {
33024
33566
  listCrewSummariesAt: () => listCrewSummariesAt,
33025
33567
  loadCrewAgentAt: () => loadCrewAgentAt,
33026
33568
  loadCrewAgentAtIfExists: () => loadCrewAgentAtIfExists,
33569
+ loadCrewAgentAtIfPresent: () => loadCrewAgentAtIfPresent,
33027
33570
  loadCrewSummaryAt: () => loadCrewSummaryAt,
33028
33571
  makeAgentMemoryProvider: () => makeAgentMemoryProvider,
33029
33572
  makeCrewTurnRuntime: () => makeCrewTurnRuntime,
33030
33573
  makePartitionedMemoryProvider: () => makePartitionedMemoryProvider,
33031
33574
  makeReadOnlyMemoryProvider: () => makeReadOnlyMemoryProvider,
33575
+ managedCap: () => managedCap,
33576
+ managedClaimOf: () => managedClaimOf,
33577
+ managedLockReason: () => managedLockReason,
33578
+ managedTrusted: () => managedTrusted,
33032
33579
  matchFileChange: () => matchFileChange,
33033
33580
  matchRunComplete: () => matchRunComplete,
33581
+ narrowDefinition: () => narrowDefinition,
33034
33582
  newCrewDraft: () => newCrewDraft,
33035
33583
  nextCronAfter: () => nextCronAfter,
33036
33584
  normalizeRunStatus: () => normalizeRunStatus,
33037
33585
  offersCommandTools: () => offersCommandTools,
33038
33586
  openLineOf: () => openLineOf,
33039
33587
  openRoom: () => openRoom,
33588
+ packagePolicyModels: () => packagePolicyModels,
33040
33589
  parseCron: () => parseCron,
33041
33590
  parseDeployment: () => parseDeployment,
33042
33591
  parseFrontmatter: () => parseFrontmatter,
@@ -33048,6 +33597,8 @@ __export(crew_exports, {
33048
33597
  projectMarkerPath: () => projectMarkerPath,
33049
33598
  readAutonomy: () => readAutonomy,
33050
33599
  readCrewListing: () => readCrewListing,
33600
+ readManagedEntry: () => readManagedEntry,
33601
+ readManagedRef: () => readManagedRef,
33051
33602
  registerCrewPolicy: () => registerCrewPolicy,
33052
33603
  resolveCallSet: () => resolveCallSet,
33053
33604
  resolveCrewModel: () => resolveCrewModel,
@@ -33062,6 +33613,8 @@ __export(crew_exports, {
33062
33613
  runRoom: () => runRoom,
33063
33614
  runTurnRuntime: () => runTurnRuntime,
33064
33615
  serializeDeployment: () => serializeDeployment,
33616
+ setDefinitionFilter: () => setDefinitionFilter,
33617
+ setManagedTrust: () => setManagedTrust,
33065
33618
  splitRunStatus: () => splitRunStatus,
33066
33619
  stampAuthor: () => stampAuthor,
33067
33620
  stringArray: () => stringArray,
@@ -33075,14 +33628,14 @@ __export(crew_exports, {
33075
33628
  });
33076
33629
 
33077
33630
  // ../crew/frontmatter.ts
33078
- var import_yaml = __toESM(require_dist(), 1);
33631
+ var import_yaml2 = __toESM(require_dist(), 1);
33079
33632
  var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
33080
- function parseFrontmatter(text) {
33081
- const m = text.match(FRONTMATTER);
33082
- if (!m) return { meta: {}, body: text };
33633
+ function parseFrontmatter(text2) {
33634
+ const m = text2.match(FRONTMATTER);
33635
+ if (!m) return { meta: {}, body: text2 };
33083
33636
  let meta = {};
33084
33637
  try {
33085
- const parsed = import_yaml.default.parse(m[1]);
33638
+ const parsed = import_yaml2.default.parse(m[1]);
33086
33639
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
33087
33640
  meta = parsed;
33088
33641
  }
@@ -33093,7 +33646,7 @@ function parseFrontmatter(text) {
33093
33646
  }
33094
33647
 
33095
33648
  // ../crew/policy.ts
33096
- var import_yaml2 = __toESM(require_dist(), 1);
33649
+ var import_yaml3 = __toESM(require_dist(), 1);
33097
33650
  var LEVELS = ["allow", "ask", "owner", "deny"];
33098
33651
  var UNATTENDED = ["deny", "park", "allow"];
33099
33652
  function asLevel(v) {
@@ -33123,11 +33676,11 @@ function coercePermissions(v) {
33123
33676
  }
33124
33677
  return out;
33125
33678
  }
33126
- function parsePolicyYaml(text, agentName) {
33679
+ function parsePolicyYaml(text2, agentName) {
33127
33680
  let raw = {};
33128
- if (text.trim()) {
33681
+ if (text2.trim()) {
33129
33682
  try {
33130
- const parsed = import_yaml2.default.parse(text);
33683
+ const parsed = import_yaml3.default.parse(text2);
33131
33684
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
33132
33685
  raw = parsed;
33133
33686
  }
@@ -33183,6 +33736,23 @@ function parsePolicyYaml(text, agentName) {
33183
33736
  return policy;
33184
33737
  }
33185
33738
 
33739
+ // ../crew/packagePolicy.ts
33740
+ var import_yaml4 = __toESM(require_dist(), 1);
33741
+ import { validateModelEgress } from "@corenel/protocol";
33742
+ function packagePolicyModels(text2) {
33743
+ let raw;
33744
+ try {
33745
+ raw = text2.trim() ? import_yaml4.default.parse(text2) : null;
33746
+ } catch {
33747
+ return { ok: false, error: "POLICY.yaml is not valid YAML" };
33748
+ }
33749
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { ok: true, value: null };
33750
+ const models = raw.models;
33751
+ if (models === void 0) return { ok: true, value: null };
33752
+ const checked = validateModelEgress(models);
33753
+ return checked.ok ? { ok: true, value: checked.value } : { ok: false, error: checked.error };
33754
+ }
33755
+
33186
33756
  // ../crew/donts.ts
33187
33757
  import { DONTS_MAX, DONT_MAX_CHARS, hasControlChars } from "@corenel/protocol";
33188
33758
  var DONT_BLANK = "A don't cannot be blank.";
@@ -33338,8 +33908,8 @@ function allowedAutonomy(def) {
33338
33908
  function tightenAutonomy(def, requested) {
33339
33909
  if (!isAutonomyPreset(requested)) return { ok: false, reason: "Unknown autonomy level." };
33340
33910
  if (!fits(def, requested)) {
33341
- const current = readAutonomy(def);
33342
- const name = current === "custom" ? "a custom policy" : LABEL[current];
33911
+ const current2 = readAutonomy(def);
33912
+ const name = current2 === "custom" ? "a custom policy" : LABEL[current2];
33343
33913
  return { ok: false, reason: `This orchestrator is set to ${name}; a task cannot run as ${LABEL[requested]}. Change it on the agent.` };
33344
33914
  }
33345
33915
  const want = PRESET_LEVEL[requested];
@@ -33356,8 +33926,90 @@ function tightenAutonomy(def, requested) {
33356
33926
  }
33357
33927
 
33358
33928
  // ../crew/store.ts
33359
- var import_yaml3 = __toESM(require_dist(), 1);
33360
- import { flattenFiles as flattenFiles3 } from "@corenel/protocol";
33929
+ var import_yaml5 = __toESM(require_dist(), 1);
33930
+ init_dist();
33931
+ import {
33932
+ flattenFiles as flattenFiles3,
33933
+ PACKAGE_REF_FILE as PACKAGE_REF_FILE2,
33934
+ packageInstallDir,
33935
+ parentDir,
33936
+ parsePackageRef as parsePackageRef2
33937
+ } from "@corenel/protocol";
33938
+
33939
+ // ../crew/notFound.ts
33940
+ function isNotFound(e) {
33941
+ if (!e || typeof e !== "object") return false;
33942
+ const o = e;
33943
+ if (o.code === "ENOENT" || o.code === "ENOTDIR" || o.name === "NotFoundError") return true;
33944
+ return typeof o.message === "string" && /^(not found|no such file( or directory)?)(:|$)/i.test(o.message);
33945
+ }
33946
+
33947
+ // ../crew/managed.ts
33948
+ import { PACKAGE_REF_FILE, parsePackageRef } from "@corenel/protocol";
33949
+ var MANAGED_UNTRUSTED = "managed by a deployment this node does not hold";
33950
+ var MANAGED_LOCKED = "is managed by the fleet; its definition and settings cannot be changed, copied or deleted on this machine";
33951
+ var MANAGED_UNREADABLE = "has a PACKAGE.json that cannot be read, so it is treated as managed by the fleet: it cannot be changed, copied or deleted on this machine";
33952
+ var trust = null;
33953
+ function setManagedTrust(check) {
33954
+ trust = check;
33955
+ }
33956
+ function managedTrusted(name, managed) {
33957
+ if (!trust) return false;
33958
+ try {
33959
+ return trust(name, managed) === true;
33960
+ } catch {
33961
+ return false;
33962
+ }
33963
+ }
33964
+ function isManaged(x) {
33965
+ return x.source?.managed !== void 0;
33966
+ }
33967
+ async function readManagedRef(files, root, name) {
33968
+ const path = `${root}/${name}/${PACKAGE_REF_FILE}`;
33969
+ try {
33970
+ const st = await files.stat(path);
33971
+ if (st === null) return null;
33972
+ } catch (e) {
33973
+ return isNotFound(e) ? null : "unknown";
33974
+ }
33975
+ let text2;
33976
+ try {
33977
+ text2 = await files.read(path);
33978
+ } catch {
33979
+ return "unknown";
33980
+ }
33981
+ return managedClaimOf(text2);
33982
+ }
33983
+ function managedClaimOf(text2) {
33984
+ let ref;
33985
+ try {
33986
+ ref = parsePackageRef(text2);
33987
+ } catch {
33988
+ return "unknown";
33989
+ }
33990
+ return ref.managed ? { ...ref, managed: ref.managed } : null;
33991
+ }
33992
+ async function readManagedEntry(files, root, name) {
33993
+ const ref = await readManagedRef(files, root, name);
33994
+ return ref === null || ref === "unknown" ? ref : ref.managed;
33995
+ }
33996
+ async function managedLockReason(files, root, name) {
33997
+ const m = await readManagedEntry(files, root, name);
33998
+ if (m === null) return null;
33999
+ return m === "unknown" ? MANAGED_UNREADABLE : MANAGED_LOCKED;
34000
+ }
34001
+ async function isManagedOnDisk(files, root, name) {
34002
+ return await readManagedEntry(files, root, name) !== null;
34003
+ }
34004
+
34005
+ // ../crew/definitionFilter.ts
34006
+ var current = null;
34007
+ function setDefinitionFilter(f) {
34008
+ current = f;
34009
+ }
34010
+ function filterDefinition(def, at) {
34011
+ return current ? current(def, at) : def;
34012
+ }
33361
34013
 
33362
34014
  // ../crew/sessionBinding.ts
33363
34015
  var SESSION_NAME_RE = /^[a-z0-9_-]{1,32}$/;
@@ -33414,6 +34066,73 @@ async function readOr(files, path, fallback = "") {
33414
34066
  return fallback;
33415
34067
  }
33416
34068
  }
34069
+ var DEFINITION_FILES = ["AGENT.md", "SOUL.md", "PERSONA.md", "POLICY.yaml"];
34070
+ var textDecoder3 = new TextDecoder();
34071
+ async function isFile(files, path) {
34072
+ try {
34073
+ return (await files.stat(path))?.kind === "file";
34074
+ } catch (e) {
34075
+ if (isNotFound(e)) return false;
34076
+ throw e;
34077
+ }
34078
+ }
34079
+ var CREW_DEFINITION_MARKERS = ["AGENT.md", PACKAGE_REF_FILE2];
34080
+ async function crewAgentPresent(files, root, name) {
34081
+ if (!isValidAgentName(name)) return false;
34082
+ for (const f of CREW_DEFINITION_MARKERS) {
34083
+ if (await isFile(files, `${root}/${name}/${f}`)) return true;
34084
+ }
34085
+ return false;
34086
+ }
34087
+ async function definitionSource(files, root, name) {
34088
+ const dir = `${root}/${name}`;
34089
+ if (!await isFile(files, `${dir}/${PACKAGE_REF_FILE2}`)) {
34090
+ return { read: (f) => readOr(files, `${dir}/${f}`) };
34091
+ }
34092
+ for (const f of DEFINITION_FILES) {
34093
+ if (await isFile(files, `${dir}/${f}`)) {
34094
+ throw new Error(`crew agent ${name}: the folder holds both ${PACKAGE_REF_FILE2} and definition files (${f}); remove one`);
34095
+ }
34096
+ }
34097
+ let ref;
34098
+ try {
34099
+ ref = parsePackageRef2(await files.read(`${dir}/${PACKAGE_REF_FILE2}`));
34100
+ } catch (e) {
34101
+ throw new Error(`crew agent ${name}: ${e.message}`);
34102
+ }
34103
+ if (ref.managed && !managedTrusted(name, ref.managed)) {
34104
+ throw new Error(`crew agent ${name}: ${MANAGED_UNTRUSTED}`);
34105
+ }
34106
+ const label = `${ref.package}@${ref.version} (${ref.digest})`;
34107
+ const readBytes = files.readBytes?.bind(files);
34108
+ if (!readBytes) {
34109
+ throw new Error(`crew agent ${name}: package ${label} cannot be loaded: cannot read package archives on this host (its file service has no binary reads)`);
34110
+ }
34111
+ const installDir = packageInstallDir(parentDir(root), "agent", ref);
34112
+ let pkg;
34113
+ try {
34114
+ pkg = await verifyInstalled(async (rel) => {
34115
+ try {
34116
+ return await readBytes(`${installDir}/${rel}`);
34117
+ } catch {
34118
+ return null;
34119
+ }
34120
+ }, ref.digest, { name: ref.package, range: ref.version });
34121
+ } catch (e) {
34122
+ if (isPackageVerificationError(e) && e.code === "FILE_MISSING" && e.path === ARCHIVE_COPY) {
34123
+ throw new Error(`crew agent ${name}: package ${label} is not installed`);
34124
+ }
34125
+ throw new Error(`crew agent ${name}: package ${ref.package}@${ref.version} failed verification: ${e.message}`);
34126
+ }
34127
+ const source = { kind: "package", package: ref.package, version: ref.version, digest: ref.digest, ...ref.managed ? { managed: ref.managed } : {} };
34128
+ return {
34129
+ read: async (f) => {
34130
+ const b = pkg.files.get(f);
34131
+ return b ? textDecoder3.decode(b) : "";
34132
+ },
34133
+ source
34134
+ };
34135
+ }
33417
34136
  function parseTriggers(meta) {
33418
34137
  const raw = meta.triggers;
33419
34138
  if (!Array.isArray(raw)) return [];
@@ -33480,13 +34199,16 @@ function parseWorkRoots(raw) {
33480
34199
  }
33481
34200
  return Object.keys(out).length ? out : void 0;
33482
34201
  }
33483
- function parseSettings(text) {
34202
+ function parseSettings(text2) {
33484
34203
  try {
33485
- const raw = JSON.parse(text);
34204
+ const raw = JSON.parse(text2);
33486
34205
  if (raw && typeof raw === "object" && !Array.isArray(raw)) {
33487
34206
  const o = raw;
33488
34207
  return {
33489
34208
  model: typeof o.model === "string" ? o.model : void 0,
34209
+ /* Meaningful only for a package agent (its AGENT.md is immutable); a
34210
+ * local agent's switch lives in AGENT.md and this is ignored for it. */
34211
+ enabled: typeof o.enabled === "boolean" ? o.enabled : void 0,
33490
34212
  temperature: typeof o.temperature === "number" ? o.temperature : void 0,
33491
34213
  /* Carried through as-is. Validation belongs to the daemon, which is the
33492
34214
  * only side that knows its own approved roots -- checking here would be
@@ -33500,45 +34222,60 @@ function parseSettings(text) {
33500
34222
  }
33501
34223
  return {};
33502
34224
  }
34225
+ function packageModelsOf(policyText) {
34226
+ const m = packagePolicyModels(policyText);
34227
+ if (!m.ok) return { packageModels: { allow: [] } };
34228
+ return m.value === null ? {} : { packageModels: m.value };
34229
+ }
33503
34230
  async function loadCrewAgentAt(files, root, name, scope = "workspace") {
33504
34231
  if (!isValidAgentName(name)) throw new Error(`invalid crew agent name: ${name}`);
33505
34232
  const dir = `${root}/${name}`;
33506
- const { meta, body } = parseFrontmatter(await readOr(files, `${dir}/AGENT.md`));
34233
+ const src = await definitionSource(files, root, name);
34234
+ const { meta, body } = parseFrontmatter(await src.read("AGENT.md"));
34235
+ const settings = parseSettings(await readOr(files, `${dir}/settings.json`, "{}"));
34236
+ if (!src.source) delete settings.enabled;
33507
34237
  const session = parseSessionBinding(meta);
33508
34238
  const orchestration = parseOrchestration(meta);
33509
34239
  const tags = (0, tags_exports.parseTags)(meta);
33510
- return {
34240
+ const policyText = await src.read("POLICY.yaml");
34241
+ return filterDefinition({
33511
34242
  name,
33512
34243
  jobTitle: typeof meta.jobTitle === "string" ? meta.jobTitle : "",
33513
34244
  description: typeof meta.description === "string" ? meta.description : "",
33514
34245
  ...tags ? { tags } : {},
33515
34246
  scope,
33516
- enabled: meta.enabled !== false,
33517
- // absent/anything-but-false -> enabled
34247
+ // absent/anything-but-false -> enabled; a package agent's switch is in settings.json
34248
+ enabled: src.source ? settings.enabled !== false : meta.enabled !== false,
33518
34249
  triggers: parseTriggers(meta),
33519
34250
  instructions: body,
33520
- soul: await readOr(files, `${dir}/SOUL.md`),
33521
- persona: await readOr(files, `${dir}/PERSONA.md`),
33522
- policy: parsePolicyYaml(await readOr(files, `${dir}/POLICY.yaml`), name),
33523
- settings: parseSettings(await readOr(files, `${dir}/settings.json`, "{}")),
34251
+ soul: await src.read("SOUL.md"),
34252
+ persona: await src.read("PERSONA.md"),
34253
+ policy: parsePolicyYaml(policyText, name),
34254
+ settings,
33524
34255
  budget: parseBudget(meta),
33525
34256
  canCall: parseCanCall(meta),
33526
34257
  canCallAll: meta.canCallAll === true,
33527
34258
  ...orchestration !== void 0 ? { orchestration } : {},
33528
34259
  ...session.kind === "binding" ? { session: session.binding } : {},
33529
- ...session.kind === "malformed" ? { sessionError: session.reason } : {}
33530
- };
34260
+ ...session.kind === "malformed" ? { sessionError: session.reason } : {},
34261
+ ...src.source ? { source: src.source } : {},
34262
+ ...src.source ? packageModelsOf(policyText) : {}
34263
+ }, { files, root });
33531
34264
  }
33532
34265
  async function loadCrewAgentAtIfExists(files, root, name, scope = "workspace") {
33533
34266
  if (!isValidAgentName(name)) return null;
33534
34267
  try {
33535
- const st = await files.stat(`${root}/${name}/AGENT.md`);
33536
- if (st?.kind !== "file") return null;
34268
+ if (!await crewAgentPresent(files, root, name)) return null;
33537
34269
  return await loadCrewAgentAt(files, root, name, scope);
33538
34270
  } catch {
33539
34271
  return null;
33540
34272
  }
33541
34273
  }
34274
+ async function loadCrewAgentAtIfPresent(files, root, name, scope = "workspace") {
34275
+ if (!isValidAgentName(name)) return null;
34276
+ if (!await crewAgentPresent(files, root, name)) return null;
34277
+ return loadCrewAgentAt(files, root, name, scope);
34278
+ }
33542
34279
  async function listCrewAgentsAt(files, root, opts = {}) {
33543
34280
  let nodes;
33544
34281
  try {
@@ -33575,7 +34312,7 @@ function serializePolicy(policy) {
33575
34312
  if (policy.unattended) ordered.unattended = policy.unattended;
33576
34313
  if (typeof policy.parkTimeoutMs === "number") ordered.parkTimeoutMs = policy.parkTimeoutMs;
33577
34314
  if (typeof policy.pushWaitMs === "number") ordered.pushWaitMs = policy.pushWaitMs;
33578
- return import_yaml3.default.stringify(ordered, { lineWidth: 0 });
34315
+ return import_yaml5.default.stringify(ordered, { lineWidth: 0 });
33579
34316
  }
33580
34317
  function serializeAgentMd(def) {
33581
34318
  const meta = { name: def.name };
@@ -33601,13 +34338,15 @@ function serializeAgentMd(def) {
33601
34338
  meta.session = def.session.createIfMissing ? { name: def.session.name } : { name: def.session.name, createIfMissing: false };
33602
34339
  }
33603
34340
  return `---
33604
- ${import_yaml3.default.stringify(meta, { lineWidth: 0 })}---
34341
+ ${import_yaml5.default.stringify(meta, { lineWidth: 0 })}---
33605
34342
  ${def.instructions.replace(/\n+$/, "")}
33606
34343
  `;
33607
34344
  }
33608
34345
  async function loadCrewSummaryAt(files, root, name, scope = "workspace") {
33609
34346
  if (!isValidAgentName(name)) throw new Error(`invalid crew agent name: ${name}`);
33610
- const { meta } = parseFrontmatter(await readOr(files, `${root}/${name}/AGENT.md`));
34347
+ const src = await definitionSource(files, root, name);
34348
+ const { meta } = parseFrontmatter(await src.read("AGENT.md"));
34349
+ const enabled = src.source ? parseSettings(await readOr(files, `${root}/${name}/settings.json`, "{}")).enabled !== false : meta.enabled !== false;
33611
34350
  const tags = (0, tags_exports.parseTags)(meta);
33612
34351
  return {
33613
34352
  name,
@@ -33615,20 +34354,30 @@ async function loadCrewSummaryAt(files, root, name, scope = "workspace") {
33615
34354
  description: typeof meta.description === "string" ? meta.description : "",
33616
34355
  ...tags ? { tags } : {},
33617
34356
  triggers: parseTriggers(meta).map((t) => t.type),
33618
- enabled: meta.enabled !== false,
34357
+ enabled,
33619
34358
  scope,
33620
34359
  delegates: Array.isArray(meta.canCall) && meta.canCall.length > 0 || meta.canCallAll === true,
33621
- orchestrator: orchestrationBlock(meta) !== void 0
34360
+ orchestrator: orchestrationBlock(meta) !== void 0,
34361
+ ...src.source ? { source: src.source } : {}
33622
34362
  };
33623
34363
  }
34364
+ async function referencedSource(files, dir) {
34365
+ try {
34366
+ const ref = parsePackageRef2(await files.read(`${dir}/${PACKAGE_REF_FILE2}`));
34367
+ return { kind: "package", package: ref.package, version: ref.version, digest: ref.digest, ...ref.managed ? { managed: ref.managed } : {} };
34368
+ } catch {
34369
+ return void 0;
34370
+ }
34371
+ }
33624
34372
  async function listCrewSummariesAt(files, root, scope = "workspace", opts = {}) {
33625
34373
  const names = await listCrewAgentsAt(files, root, opts);
33626
34374
  const out = [];
33627
34375
  for (const name of names.sort()) {
33628
34376
  try {
33629
34377
  out.push(await loadCrewSummaryAt(files, root, name, scope));
33630
- } catch {
33631
- out.push({ name, description: "", enabled: true, scope, delegates: false, orchestrator: false });
34378
+ } catch (e) {
34379
+ const source = await referencedSource(files, `${root}/${name}`);
34380
+ out.push({ name, description: "", enabled: false, scope, delegates: false, orchestrator: false, ...source ? { source } : {}, loadError: e.message });
33632
34381
  }
33633
34382
  }
33634
34383
  return out;
@@ -33642,22 +34391,37 @@ async function put(files, path, content) {
33642
34391
  }
33643
34392
  function stripWorkRoots(settings) {
33644
34393
  const { workRoots: _workRoots, ...rest } = settings;
34394
+ for (const k of Object.keys(rest)) {
34395
+ if (rest[k] === void 0) delete rest[k];
34396
+ }
33645
34397
  return rest;
33646
34398
  }
33647
34399
  async function dontsUnchanged(files, dir, def) {
33648
- let text;
34400
+ let text2;
33649
34401
  try {
33650
- text = await files.read(`${dir}/POLICY.yaml`);
34402
+ text2 = await files.read(`${dir}/POLICY.yaml`);
33651
34403
  } catch {
33652
34404
  return false;
33653
34405
  }
33654
- const stored = parsePolicyYaml(text, def.name).donts ?? [];
34406
+ const stored = parsePolicyYaml(text2, def.name).donts ?? [];
33655
34407
  const next = (def.policy.donts ?? []).map((d) => d.trim());
33656
34408
  return stored.length === next.length && stored.every((d, i) => d === next[i]);
33657
34409
  }
33658
34410
  async function writeCrewAgentAt(files, root, def) {
33659
34411
  if (!isValidAgentName(def.name)) throw new Error(`invalid crew agent name: ${def.name}`);
33660
34412
  const dir = `${root}/${def.name}`;
34413
+ if (await isFile(files, `${dir}/${PACKAGE_REF_FILE2}`)) {
34414
+ const locked2 = await managedLockReason(files, root, def.name);
34415
+ if (locked2) throw new Error(`crew agent ${def.name} ${locked2}`);
34416
+ await put(files, `${dir}/settings.json`, `${JSON.stringify(stripWorkRoots({ ...def.settings, enabled: def.enabled }), null, 2)}
34417
+ `);
34418
+ return;
34419
+ }
34420
+ if (def.source) {
34421
+ throw new Error(`crew agent ${def.name} is package ${def.source.package}@${def.source.version} but its folder has no ${PACKAGE_REF_FILE2}; copy it to make a local agent`);
34422
+ }
34423
+ const localSettings = { ...def.settings };
34424
+ delete localSettings.enabled;
33661
34425
  if (!await dontsUnchanged(files, dir, def)) {
33662
34426
  const problems = dontsProblems(def.policy);
33663
34427
  if (problems.length) throw new Error(problems.join(" "));
@@ -33666,11 +34430,25 @@ async function writeCrewAgentAt(files, root, def) {
33666
34430
  await put(files, `${dir}/SOUL.md`, def.soul);
33667
34431
  await put(files, `${dir}/PERSONA.md`, def.persona);
33668
34432
  await put(files, `${dir}/POLICY.yaml`, serializePolicy(def.policy));
33669
- await put(files, `${dir}/settings.json`, `${JSON.stringify(stripWorkRoots(def.settings), null, 2)}
34433
+ await put(files, `${dir}/settings.json`, `${JSON.stringify(stripWorkRoots(localSettings), null, 2)}
33670
34434
  `);
33671
34435
  }
34436
+ async function copyCrewAgentAt(files, root, from, to) {
34437
+ if (!isValidAgentName(to)) throw new Error(`invalid crew agent name: ${to}`);
34438
+ if (await crewAgentPresent(files, root, to)) throw new Error(`crew agent ${to} already exists`);
34439
+ const def = await loadCrewAgentAt(files, root, from);
34440
+ const locked2 = isManaged(def) ? MANAGED_LOCKED : await managedLockReason(files, root, from);
34441
+ if (locked2) throw new Error(`crew agent ${from} ${locked2}`);
34442
+ const copy = { ...def, name: to, settings: { ...def.settings } };
34443
+ delete copy.source;
34444
+ delete copy.settings.enabled;
34445
+ await writeCrewAgentAt(files, root, copy);
34446
+ return copy;
34447
+ }
33672
34448
  async function deleteCrewAgentAt(files, root, name) {
33673
34449
  if (!isValidAgentName(name)) throw new Error(`invalid crew agent name: ${name}`);
34450
+ const locked2 = await managedLockReason(files, root, name);
34451
+ if (locked2) throw new Error(`crew agent ${name} ${locked2}`);
33674
34452
  await files.remove(`${root}/${name}`);
33675
34453
  }
33676
34454
 
@@ -33948,10 +34726,10 @@ function normalizeRunStatus(raw) {
33948
34726
  return RUN_STATUS_BY_RAW.get((raw ?? "").trim()) ?? "error";
33949
34727
  }
33950
34728
  function splitRunStatus(raw) {
33951
- const text = (raw ?? "").trim();
33952
- const stopReason = normalizeRunStatus(text);
33953
- if (stopReason !== "error" || text === "error" || !text) return { stopReason };
33954
- return { stopReason, message: text };
34729
+ const text2 = (raw ?? "").trim();
34730
+ const stopReason = normalizeRunStatus(text2);
34731
+ if (stopReason !== "error" || text2 === "error" || !text2) return { stopReason };
34732
+ return { stopReason, message: text2 };
33955
34733
  }
33956
34734
  function matchRunComplete(config, completion) {
33957
34735
  const after = stringArray(config.after);
@@ -33985,11 +34763,11 @@ function emptyDeployment() {
33985
34763
  function deploymentKey(name, wsId) {
33986
34764
  return wsId ? `workspaces/${wsId}/crew/${name}` : `crew/${name}`;
33987
34765
  }
33988
- function parseDeployment(text) {
34766
+ function parseDeployment(text2) {
33989
34767
  const out = emptyDeployment();
33990
34768
  let raw;
33991
34769
  try {
33992
- raw = JSON.parse(text);
34770
+ raw = JSON.parse(text2);
33993
34771
  } catch {
33994
34772
  return out;
33995
34773
  }
@@ -34140,11 +34918,12 @@ function nextCronAfter(f, from) {
34140
34918
  }
34141
34919
 
34142
34920
  // ../crew/offerGrants.ts
34143
- import { policyNamesTool, toolGateCovers } from "@corenel/harness/guardrail";
34921
+ import { matchesAnyGlob as matchesAnyGlob2, policyNamesTool, toolGateCovers } from "@corenel/harness/guardrail";
34144
34922
  import { toolAddress as toolAddress2 } from "@corenel/harness/tools/namespaces";
34145
- function grantOfferedTools(policy, offered) {
34923
+ function grantOfferedTools(policy, offered, cap = null) {
34146
34924
  const missing = offered.filter((name) => {
34147
34925
  const subject = { name, address: toolAddress2({ name }) };
34926
+ if (cap !== null && !matchesAnyGlob2(subject.name, cap) && !matchesAnyGlob2(subject.address, cap)) return false;
34148
34927
  return !policyNamesTool(policy, subject) && !toolGateCovers(policy, subject);
34149
34928
  });
34150
34929
  if (!missing.length) return policy;
@@ -34152,6 +34931,93 @@ function grantOfferedTools(policy, offered) {
34152
34931
  for (const name of missing) permissions[name] = "allow";
34153
34932
  return { ...policy, permissions };
34154
34933
  }
34934
+ function managedCap(def) {
34935
+ if (!def.source?.managed) return null;
34936
+ const allow = def.policy.tools?.allow ?? [];
34937
+ return allow.length ? [...allow] : null;
34938
+ }
34939
+
34940
+ // ../crew/acl.ts
34941
+ import {
34942
+ intersectModelEgress,
34943
+ toolsWider
34944
+ } from "@corenel/protocol";
34945
+ var NO_TOOL_SENTINEL = "__none__";
34946
+ var MCP_DENY_ALL = "mcp:**";
34947
+ var MANAGED_IN_SESSION_REFUSED = "managed agents run only on this machine's daemon, never in a session";
34948
+ function uniq(xs) {
34949
+ return [...new Set(xs)];
34950
+ }
34951
+ function intersectAllowList(pkg, acl) {
34952
+ const p = pkg ?? [];
34953
+ const entries = uniq(acl);
34954
+ const widened = toolsWider(entries, p);
34955
+ return { allow: entries.filter((e) => !widened.includes(e)), widened };
34956
+ }
34957
+ function egressIsEmpty(e) {
34958
+ if (e === "any") return false;
34959
+ return e.allow.every((ep) => ep.models !== "*" && ep.models.length === 0);
34960
+ }
34961
+ function accessAllows(level, userId, adminId) {
34962
+ if (level === void 0 || level === "members") return true;
34963
+ return !!userId && !!adminId && userId === adminId;
34964
+ }
34965
+ function lower(a, b) {
34966
+ if (a === void 0) return b;
34967
+ if (b === void 0) return a;
34968
+ return Math.min(a, b);
34969
+ }
34970
+ function narrowDefinition(def, acl, nodePolicy) {
34971
+ let refused;
34972
+ const refuse = (why) => {
34973
+ if (refused === void 0) refused = why;
34974
+ };
34975
+ if (def.session !== void 0 || def.sessionError !== void 0) refuse(MANAGED_IN_SESSION_REFUSED);
34976
+ const pkgAllow = def.policy.tools?.allow ?? [];
34977
+ let allow = [...pkgAllow];
34978
+ if (acl.tools) {
34979
+ const r = intersectAllowList(pkgAllow, acl.tools.allow);
34980
+ if (r.widened.length) refuse(`tools would widen the package: ${r.widened.join(", ")}`);
34981
+ allow = r.allow.length ? r.allow : [NO_TOOL_SENTINEL];
34982
+ }
34983
+ const deny = [...def.policy.tools?.deny ?? []];
34984
+ if (allow.length === 0 && !deny.includes(MCP_DENY_ALL)) deny.push(MCP_DENY_ALL);
34985
+ const tools = allow.length || deny.length ? { ...allow.length ? { allow } : {}, ...deny.length ? { deny } : {} } : void 0;
34986
+ let skills = def.policy.skills;
34987
+ const aclSkills = acl.tools?.skills;
34988
+ if (aclSkills) {
34989
+ const pkgSkills = def.policy.skills ?? [];
34990
+ const kept = pkgSkills.filter((s) => aclSkills.includes(s));
34991
+ const widened = aclSkills.filter((s) => !pkgSkills.includes(s));
34992
+ if (widened.length) refuse(`skills would widen the package: ${widened.join(", ")}`);
34993
+ skills = kept.length ? kept : [NO_TOOL_SENTINEL];
34994
+ }
34995
+ const { tools: _tools, skills: _skills, ...policyRest } = def.policy;
34996
+ const policy = { ...policyRest, ...tools ? { tools } : {}, ...skills ? { skills } : {} };
34997
+ const allowedTriggers = acl.triggers?.allow;
34998
+ const triggers = allowedTriggers ? def.triggers.filter((t) => allowedTriggers.includes(t.type)) : [...def.triggers];
34999
+ const budget = { ...def.budget ?? {} };
35000
+ if (acl.budget) {
35001
+ const usd = lower(budget.maxUsd, acl.budget.perRunUsd);
35002
+ const tok = lower(budget.maxTokens, acl.budget.perRunTokens);
35003
+ if (usd !== void 0) budget.maxUsd = usd;
35004
+ if (tok !== void 0) budget.maxTokens = tok;
35005
+ }
35006
+ const effectiveModels = intersectModelEgress(
35007
+ intersectModelEgress(nodePolicy.models, def.packageModels ?? "any"),
35008
+ acl.models ?? "any"
35009
+ );
35010
+ if (egressIsEmpty(effectiveModels)) refuse("no allowed model");
35011
+ const out = {
35012
+ ...def,
35013
+ policy,
35014
+ triggers,
35015
+ budget,
35016
+ egress: effectiveModels,
35017
+ ...acl.access ? { aclAccess: { run: acl.access.run } } : {}
35018
+ };
35019
+ return refused === void 0 ? { def: out, effectiveModels } : { def: out, effectiveModels, refused };
35020
+ }
34155
35021
 
34156
35022
  // ../crew/memory.ts
34157
35023
  import { MEMORY_USERS_DIR } from "@corenel/protocol";
@@ -34304,9 +35170,9 @@ var ROOM_KIND = "room";
34304
35170
  function encodeRoomLine(line) {
34305
35171
  return JSON.stringify(line) + "\n";
34306
35172
  }
34307
- function roomLines(text) {
35173
+ function roomLines(text2) {
34308
35174
  const out = [];
34309
- for (const raw of text.split("\n")) {
35175
+ for (const raw of text2.split("\n")) {
34310
35176
  const s = raw.trim();
34311
35177
  if (!s) continue;
34312
35178
  let line;
@@ -34319,14 +35185,14 @@ function roomLines(text) {
34319
35185
  }
34320
35186
  return out;
34321
35187
  }
34322
- function openLineOf(text) {
34323
- for (const line of roomLines(text)) if (line.op === "open") return line;
35188
+ function openLineOf(text2) {
35189
+ for (const line of roomLines(text2)) if (line.op === "open") return line;
34324
35190
  return null;
34325
35191
  }
34326
- function foldRoom(text) {
35192
+ function foldRoom(text2) {
34327
35193
  let state = null;
34328
35194
  let lastAt;
34329
- for (const line of roomLines(text)) {
35195
+ for (const line of roomLines(text2)) {
34330
35196
  if (typeof line.at === "number" && (lastAt === void 0 || line.at > lastAt)) lastAt = line.at;
34331
35197
  if (line.op === "open") {
34332
35198
  if (state) continue;
@@ -34376,9 +35242,9 @@ function foldRoom(text) {
34376
35242
  if (state && lastAt !== void 0) state = { ...state, lastAt };
34377
35243
  return state;
34378
35244
  }
34379
- function pendingParticipant(text) {
35245
+ function pendingParticipant(text2) {
34380
35246
  let pending = null;
34381
- for (const line of roomLines(text)) {
35247
+ for (const line of roomLines(text2)) {
34382
35248
  if (line.op === "pending") {
34383
35249
  if (typeof line.participant === "string") pending = line.participant;
34384
35250
  } else if (line.op === "floor" || line.op === "close") {
@@ -34387,9 +35253,9 @@ function pendingParticipant(text) {
34387
35253
  }
34388
35254
  return pending;
34389
35255
  }
34390
- function pendingReason(text) {
35256
+ function pendingReason(text2) {
34391
35257
  let reason = null;
34392
- for (const line of roomLines(text)) {
35258
+ for (const line of roomLines(text2)) {
34393
35259
  if (line.op === "pending") {
34394
35260
  reason = typeof line.reason === "string" ? line.reason : null;
34395
35261
  } else if (line.op === "floor" || line.op === "close") {
@@ -34398,10 +35264,10 @@ function pendingReason(text) {
34398
35264
  }
34399
35265
  return reason;
34400
35266
  }
34401
- function turnCosts(text) {
35267
+ function turnCosts(text2) {
34402
35268
  const out = [];
34403
35269
  let opened = false;
34404
- for (const line of roomLines(text)) {
35270
+ for (const line of roomLines(text2)) {
34405
35271
  if (line.op === "open") {
34406
35272
  if (typeof line.roomId === "string" && Array.isArray(line.participants) && typeof line.maxTurns === "number") opened = true;
34407
35273
  continue;
@@ -34500,8 +35366,8 @@ var RoomStore = class {
34500
35366
  * reader wants a document either way. A file that exists but cannot be read
34501
35367
  * throws (see `textAt`). */
34502
35368
  async readFindings(roomId) {
34503
- const text = await this.textAt(findingsPath(this.getRoot(), roomId));
34504
- return text == null ? [] : foldFindings(text);
35369
+ const text2 = await this.textAt(findingsPath(this.getRoot(), roomId));
35370
+ return text2 == null ? [] : foldFindings(text2);
34505
35371
  }
34506
35372
  /** Append one finding op. A genuine read-then-concat append, exactly as
34507
35373
  * `append` does for the room fold, because the engine and a human's edit both
@@ -34513,8 +35379,8 @@ var RoomStore = class {
34513
35379
  await files.write(path, prior + encodeFindingLine(line));
34514
35380
  }
34515
35381
  async read(roomId) {
34516
- const text = await this.text(roomId);
34517
- return text == null ? null : foldRoom(text);
35382
+ const text2 = await this.text(roomId);
35383
+ return text2 == null ? null : foldRoom(text2);
34518
35384
  }
34519
35385
  /** Every room this store can find on disk, folded to its current state.
34520
35386
  * Mirrors `JsonlSessionStore.list()` (packages/harness/sessions/
@@ -34530,38 +35396,38 @@ var RoomStore = class {
34530
35396
  const roomFiles = flattenFiles4(nodes).filter((f) => f.name === "SESSION.jsonl" && f.path.startsWith(`${root}/`));
34531
35397
  const out = [];
34532
35398
  for (const f of roomFiles) {
34533
- const text = await files.read(f.path).catch(() => null);
34534
- const state = text != null ? foldRoom(text) : null;
35399
+ const text2 = await files.read(f.path).catch(() => null);
35400
+ const state = text2 != null ? foldRoom(text2) : null;
34535
35401
  if (state) out.push(state);
34536
35402
  }
34537
35403
  return out;
34538
35404
  }
34539
35405
  async readSession(roomId) {
34540
- const text = await this.text(roomId);
34541
- return text == null ? null : foldSession(text);
35406
+ const text2 = await this.text(roomId);
35407
+ return text2 == null ? null : foldSession(text2);
34542
35408
  }
34543
35409
  /** The participant the room is currently parked on, or null. Lets a caller
34544
35410
  * that re-polls a parked room (`runRoom`) tell "still parked on the same
34545
35411
  * person" from "needs a fresh `{op:'pending'}` line" without appending one
34546
35412
  * just to find out. */
34547
35413
  async pendingParticipant(roomId) {
34548
- const text = await this.text(roomId);
34549
- return text == null ? null : pendingParticipant(text);
35414
+ const text2 = await this.text(roomId);
35415
+ return text2 == null ? null : pendingParticipant(text2);
34550
35416
  }
34551
35417
  /** Why the room is parked, when the park was not simply someone's turn (see
34552
35418
  * `pendingReason` in lines.ts). Null for an ordinary human turn, and for a
34553
35419
  * room that is not parked. */
34554
35420
  async pendingReason(roomId) {
34555
- const text = await this.text(roomId);
34556
- return text == null ? null : pendingReason(text);
35421
+ const text2 = await this.text(roomId);
35422
+ return text2 == null ? null : pendingReason(text2);
34557
35423
  }
34558
35424
  /** What each of this room's turns cost, in order (see `turnCosts` in
34559
35425
  * lines.ts). Empty for a room that has taken no turn, and for a room that
34560
35426
  * does not exist -- a reader of a transcript wants an array it can index by
34561
35427
  * turn, and "no room" and "no turns yet" annotate that transcript alike. */
34562
35428
  async turnCosts(roomId) {
34563
- const text = await this.text(roomId);
34564
- return text == null ? [] : turnCosts(text);
35429
+ const text2 = await this.text(roomId);
35430
+ return text2 == null ? [] : turnCosts(text2);
34565
35431
  }
34566
35432
  };
34567
35433
 
@@ -34770,7 +35636,7 @@ function makeCrewTurnRuntime(opts) {
34770
35636
  const { def, participants, meId, deps } = opts;
34771
35637
  const findings = opts.findings ?? [];
34772
35638
  const refs = participants.map((p) => ({ id: p.id, name: p.name }));
34773
- const policy = grantOfferedTools(def.policy, [...ROOM_TOOL_NAMES]);
35639
+ const policy = grantOfferedTools(def.policy, [...ROOM_TOOL_NAMES], managedCap(def));
34774
35640
  const permission = new PermissionService2({
34775
35641
  policy,
34776
35642
  ...deps.prompt ? { prompt: deps.prompt } : {},
@@ -34992,7 +35858,7 @@ async function runRoom(roomId, deps) {
34992
35858
  }
34993
35859
  }
34994
35860
  }
34995
- async function answerHumanTurn(roomId, participantId, text, deps, addressed) {
35861
+ async function answerHumanTurn(roomId, participantId, text2, deps, addressed) {
34996
35862
  const state = await deps.store.read(roomId);
34997
35863
  if (!state) throw new Error(`No room "${roomId}".`);
34998
35864
  if (state.closed) {
@@ -35029,7 +35895,7 @@ async function answerHumanTurn(roomId, participantId, text, deps, addressed) {
35029
35895
  }
35030
35896
  target = res.id;
35031
35897
  }
35032
- const message = stampAuthor({ role: "user", content: text }, participantId);
35898
+ const message = stampAuthor({ role: "user", content: text2 }, participantId);
35033
35899
  await appendMessages(deps.store, roomId, [message], deps.now());
35034
35900
  let next = advance(state, target);
35035
35901
  if (next.closed) {
@@ -35060,14 +35926,14 @@ function requireHuman(roomId, state, participantId) {
35060
35926
  }
35061
35927
  return found;
35062
35928
  }
35063
- async function interjectHuman(roomId, participantId, text, deps) {
35929
+ async function interjectHuman(roomId, participantId, text2, deps) {
35064
35930
  const state = await deps.store.read(roomId);
35065
35931
  if (!state) throw new Error(`No room "${roomId}".`);
35066
35932
  if (state.closed) {
35067
35933
  throw new Error(`Room "${roomId}" is closed (${state.closed.reason}), so nothing further can be said in it.`);
35068
35934
  }
35069
35935
  const speaker = requireHuman(roomId, state, participantId);
35070
- const body = text.trim();
35936
+ const body = text2.trim();
35071
35937
  if (!body) {
35072
35938
  throw new Error(`${speaker.name} said nothing: an empty interjection is not appended.`);
35073
35939
  }
@@ -35384,6 +36250,15 @@ var EXTENSIONS = [
35384
36250
  ...SIDECAR,
35385
36251
  summary: "deploy, undeploy, pause and resume crew agents on this machine",
35386
36252
  argv: (rest) => ["crew", ...rest]
36253
+ },
36254
+ {
36255
+ command: "fleet",
36256
+ pkg: "@corenel/fleet",
36257
+ entry: "dist/server/main.js",
36258
+ summary: "run a fleet control plane (enroll, lease and revoke sidecars)",
36259
+ monorepoOnly: true,
36260
+ // 'corenel fleet start --data d' reads naturally; the server takes flags directly.
36261
+ argv: (rest) => rest[0] === "start" ? rest.slice(1) : rest
35387
36262
  }
35388
36263
  ];
35389
36264
  function findExtension(command) {
@@ -35391,6 +36266,13 @@ function findExtension(command) {
35391
36266
  }
35392
36267
  var EXTENSION_COMMANDS = EXTENSIONS.map((e) => e.command);
35393
36268
  function missingMessage(e) {
36269
+ if (e.monorepoOnly) {
36270
+ return [
36271
+ `${e.command} needs ${e.pkg}, which is not published yet and only runs from a checkout of the monorepo.`,
36272
+ "",
36273
+ " pnpm fleet:start"
36274
+ ].join("\n");
36275
+ }
35394
36276
  return [
35395
36277
  `${e.command} needs ${e.pkg}, which is not installed.`,
35396
36278
  "",
@@ -35489,6 +36371,7 @@ var COMMANDS = [
35489
36371
  { name: "acp", args: "<agent> [flags]", summary: "proxy an external coding agent under Corenel policy" },
35490
36372
  { name: "sandboxes", args: "[list|show|create|run|pause|resume|destroy]", summary: "create, list and run in local sandboxes" },
35491
36373
  { name: "crew", args: "deployments | deploy|undeploy|resume <agent> | pause <agent> --reason R", summary: "deploy, undeploy, pause and resume crew agents on this machine" },
36374
+ { name: "fleet", args: "[start] --data <dir> [flags] | keys new", summary: "run a fleet control plane (enroll, lease and revoke sidecars)" },
35492
36375
  { name: "login", args: "[--base URL]", summary: "sign in through your browser (device flow)" },
35493
36376
  { name: "auth", summary: "show whether you are signed in, and as what" },
35494
36377
  { name: "logout", summary: "forget the stored token" },
@@ -35506,16 +36389,16 @@ function isVersionFlag(a) {
35506
36389
  return a === "--version" || a === "-v" || a === "version";
35507
36390
  }
35508
36391
  function helpText(version2) {
35509
- const shown = COMMANDS.filter((c) => c.name);
36392
+ const shown2 = COMMANDS.filter((c) => c.name);
35510
36393
  const left = (c) => `corenel ${c.name}${c.args ? ` ${c.args}` : ""}`;
35511
- const width = Math.max(...shown.map((c) => left(c).length));
36394
+ const width = Math.max(...shown2.map((c) => left(c).length));
35512
36395
  const bare = COMMANDS.find((c) => !c.name);
35513
36396
  return [
35514
36397
  `corenel ${version2} \u2014 the harness, in node.`,
35515
36398
  "",
35516
36399
  "Usage:",
35517
36400
  ` corenel${" ".repeat(Math.max(1, width - 7))} ${bare ? bare.summary : ""}`,
35518
- ...shown.map((c) => ` ${left(c).padEnd(width)} ${c.summary}`),
36401
+ ...shown2.map((c) => ` ${left(c).padEnd(width)} ${c.summary}`),
35519
36402
  "",
35520
36403
  "Common flags:",
35521
36404
  " --model <id> model for this turn (default gpt-4o-mini)",
@@ -35542,6 +36425,7 @@ function helpText(version2) {
35542
36425
  "",
35543
36426
  "sidecar, acp, sandboxes and crew are provided by @corenel/sidecar, installed separately.",
35544
36427
  "Each takes its own flags: `corenel sidecar --help`.",
36428
+ "fleet is provided by @corenel/fleet, installed separately: `corenel fleet --help`.",
35545
36429
  "",
35546
36430
  "Exit codes (corenel run, corenel run-agent):",
35547
36431
  " 0 the turn completed with an answer",
@@ -35721,7 +36605,9 @@ var KNOWN_KEYS = [
35721
36605
  "speech",
35722
36606
  "speechModel",
35723
36607
  "peerCallTimeoutMs",
35724
- "peers"
36608
+ "peers",
36609
+ "models",
36610
+ "providers"
35725
36611
  ];
35726
36612
  function daemonConfigPath(stateDir) {
35727
36613
  return join8(stateDir, "daemon.json");
@@ -36066,8 +36952,8 @@ function isQuit(line) {
36066
36952
  const t = line.trim().toLowerCase();
36067
36953
  return t === "/exit" || t === "/quit" || t === "exit" || t === "quit";
36068
36954
  }
36069
- function nextShownCursor(itemsLength, shown) {
36070
- return itemsLength < shown ? 0 : shown;
36955
+ function nextShownCursor(itemsLength, shown2) {
36956
+ return itemsLength < shown2 ? 0 : shown2;
36071
36957
  }
36072
36958
  function formatWriteDiff(diff) {
36073
36959
  if (diff.noop) return " (no change -- new content is identical to what's on disk)\n";
@@ -36202,12 +37088,12 @@ async function runRepl(deps) {
36202
37088
  ...deps.policy ? { policy: deps.policy } : {},
36203
37089
  ...deps.policySource ? { policySource: deps.policySource } : {}
36204
37090
  });
36205
- let shown = 0;
37091
+ let shown2 = 0;
36206
37092
  session.subscribe(() => {
36207
37093
  const items = session.getSnapshot().committed;
36208
- shown = nextShownCursor(items.length, shown);
36209
- for (; shown < items.length; shown++) {
36210
- const it = items[shown];
37094
+ shown2 = nextShownCursor(items.length, shown2);
37095
+ for (; shown2 < items.length; shown2++) {
37096
+ const it = items[shown2];
36211
37097
  if (it.kind !== "note") continue;
36212
37098
  writeLine(` ${it.level === "info" ? "" : "! "}${it.text}
36213
37099
  `);
@@ -36319,11 +37205,11 @@ async function runRepl(deps) {
36319
37205
  for (; ; ) {
36320
37206
  const line = await ask("\u203A ");
36321
37207
  if (line === null) break;
36322
- const text = line.trim();
36323
- if (!text) continue;
36324
- if (isQuit(text)) break;
37208
+ const text2 = line.trim();
37209
+ if (!text2) continue;
37210
+ if (isQuit(text2)) break;
36325
37211
  turnActive = true;
36326
- await session.submit(text);
37212
+ await session.submit(text2);
36327
37213
  turnActive = false;
36328
37214
  await askSuggestions();
36329
37215
  if (session.wantsExit) break;
@@ -36475,9 +37361,9 @@ ${rules(r.workspace)}`);
36475
37361
  return 0;
36476
37362
  }
36477
37363
  if (sub === "set") {
36478
- let current;
37364
+ let current2;
36479
37365
  try {
36480
- current = await svc.settingsStrict();
37366
+ current2 = await svc.settingsStrict();
36481
37367
  } catch (e) {
36482
37368
  deps.err(`could not read settings: ${e instanceof Error ? e.message : String(e)}
36483
37369
  `);
@@ -36485,13 +37371,13 @@ ${rules(r.workspace)}`);
36485
37371
  }
36486
37372
  if (arg === "threshold") {
36487
37373
  const threshold = Number(value);
36488
- await svc.saveSettings({ ...current, threshold });
37374
+ await svc.saveSettings({ ...current2, threshold });
36489
37375
  deps.out(threshold === 0 ? "suggestions off\n" : `suggest after ${threshold} approvals
36490
37376
  `);
36491
37377
  return 0;
36492
37378
  }
36493
37379
  const raw = value.toLowerCase();
36494
- await svc.saveSettings({ ...current, captureRawArgs: raw === "on" });
37380
+ await svc.saveSettings({ ...current2, captureRawArgs: raw === "on" });
36495
37381
  deps.out(`raw argument capture ${raw}
36496
37382
  `);
36497
37383
  return 0;
@@ -36654,7 +37540,7 @@ import { procTools } from "@corenel/harness/tools/procs";
36654
37540
 
36655
37541
  // src/sidecarConnect.ts
36656
37542
  import { stateDirName as stateDirName4 } from "@corenel/protocol";
36657
- import { SidecarHost, isSidecarKeyMismatch, isSidecarAccountRefusal } from "@corenel/harness/sidecar/host";
37543
+ import { SidecarHost, isSidecarKeyMismatch, isSidecarAccountRefusal, isFleetLoginsRefusal } from "@corenel/harness/sidecar/host";
36658
37544
 
36659
37545
  // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/wrapper.mjs
36660
37546
  var import_stream = __toESM(require_stream2(), 1);
@@ -36796,8 +37682,8 @@ function hostBackedProcs(host, seed = []) {
36796
37682
  if (!e) return { chunks: [], truncated: false };
36797
37683
  return { chunks: e.chunks.filter((c) => c.seq > sinceSeq), truncated: e.truncated };
36798
37684
  },
36799
- write: (procId, text) => {
36800
- void host.procInput(procId, text).catch(() => {
37685
+ write: (procId, text2) => {
37686
+ void host.procInput(procId, text2).catch(() => {
36801
37687
  });
36802
37688
  },
36803
37689
  kill: (procId) => {
@@ -36832,10 +37718,10 @@ function isCliDevice(v) {
36832
37718
  const k = r.privateJwk;
36833
37719
  return typeof r.id === "string" && B64.test(r.id) && typeof r.sidecarJkt === "string" && B43.test(r.sidecarJkt) && typeof k === "object" && k !== null && !!asEcPublicJwk({ kty: k.kty, crv: k.crv, x: k.x, y: k.y }) && typeof k.d === "string" && B43.test(k.d);
36834
37720
  }
36835
- function parse2(text) {
37721
+ function parse3(text2) {
36836
37722
  let raw;
36837
37723
  try {
36838
- raw = JSON.parse(text);
37724
+ raw = JSON.parse(text2);
36839
37725
  } catch {
36840
37726
  return null;
36841
37727
  }
@@ -36854,8 +37740,8 @@ function cliDeviceStore(path = cliDevicesPath()) {
36854
37740
  const file = fileTextStore(path);
36855
37741
  const dir = join10(path, "..");
36856
37742
  const load = async () => {
36857
- const text = await file.read();
36858
- return text === null ? { version: 1, devices: /* @__PURE__ */ Object.create(null) } : parse2(text);
37743
+ const text2 = await file.read();
37744
+ return text2 === null ? { version: 1, devices: /* @__PURE__ */ Object.create(null) } : parse3(text2);
36859
37745
  };
36860
37746
  const change = async (edit) => {
36861
37747
  const f = await load();
@@ -36994,6 +37880,11 @@ async function reportHandshakeFailure(e, url, usedDevice, store, identity2, fall
36994
37880
  return;
36995
37881
  }
36996
37882
  if (isSidecarAccountRefusal(e)) {
37883
+ if (isFleetLoginsRefusal(e)) {
37884
+ process.stderr.write(`corenel: the sidecar at ${url} did not accept this CLI: sign-in to it is limited by its fleet policy. A fleet admin can change that. -- ${fallback}
37885
+ `);
37886
+ return;
37887
+ }
36997
37888
  const problem = identity2.problem() ?? "the sidecar verified this account and did not admit it (not its owner, or not a member of its organization, or a device another member paired).";
36998
37889
  process.stderr.write(`corenel: the sidecar at ${url} did not accept this CLI: ${problem} -- ${fallback}
36999
37890
  `);
@@ -37253,8 +38144,7 @@ function isFailedTurn(outcome) {
37253
38144
  import { stateReadDirs } from "@corenel/protocol";
37254
38145
  import { loadModes, loadPersonas } from "@corenel/harness/prompts/config";
37255
38146
  import { composeAgentSystem as composeAgentSystem2 } from "@corenel/harness/prompts";
37256
- import { listSkills, stripFrontmatter } from "@corenel/harness/skills";
37257
- import { configWorkspace } from "@corenel/harness/prompts/host";
38147
+ import { listSkills, readSkillInstructions, stripFrontmatter } from "@corenel/harness/skills";
37258
38148
  function createIdentityState() {
37259
38149
  return { mode: "auto", persona: "" };
37260
38150
  }
@@ -37288,7 +38178,8 @@ async function armSkillById(id) {
37288
38178
  const found = skills.find((s) => s.name === id && s.instructions !== null);
37289
38179
  if (!found || !found.instructions) return null;
37290
38180
  try {
37291
- const raw = await configWorkspace().read(found.instructions);
38181
+ const raw = await readSkillInstructions(found.name);
38182
+ if (raw === null) return null;
37292
38183
  return { id: found.name, label: found.name, instructions: stripFrontmatter(raw) };
37293
38184
  } catch {
37294
38185
  return null;
@@ -37373,9 +38264,9 @@ function isErrnoException(e) {
37373
38264
  return e instanceof Error && "code" in e;
37374
38265
  }
37375
38266
  async function loadRequiredPolicyFile(path, notFoundMessage) {
37376
- let text;
38267
+ let text2;
37377
38268
  try {
37378
- text = await readFile2(path, "utf8");
38269
+ text2 = await readFile2(path, "utf8");
37379
38270
  } catch (e) {
37380
38271
  if (isErrnoException(e) && e.code === "ENOENT") {
37381
38272
  throw new PolicyResolutionError(notFoundMessage);
@@ -37384,22 +38275,22 @@ async function loadRequiredPolicyFile(path, notFoundMessage) {
37384
38275
  `corenel: could not read policy file "${path}": ${e instanceof Error ? e.message : String(e)}`
37385
38276
  );
37386
38277
  }
37387
- return validateOrThrow(text, path);
38278
+ return validateOrThrow(text2, path);
37388
38279
  }
37389
38280
  async function loadDiscoveredPolicyFile(path) {
37390
- let text;
38281
+ let text2;
37391
38282
  try {
37392
- text = await readFile2(path, "utf8");
38283
+ text2 = await readFile2(path, "utf8");
37393
38284
  } catch (e) {
37394
38285
  if (isErrnoException(e) && e.code === "ENOENT") return void 0;
37395
38286
  throw new PolicyResolutionError(
37396
38287
  `corenel: could not read policy file "${path}": ${e instanceof Error ? e.message : String(e)}`
37397
38288
  );
37398
38289
  }
37399
- return validateOrThrow(text, path);
38290
+ return validateOrThrow(text2, path);
37400
38291
  }
37401
- function validateOrThrow(text, path) {
37402
- const result = policyFromYaml(text);
38292
+ function validateOrThrow(text2, path) {
38293
+ const result = policyFromYaml(text2);
37403
38294
  if (!result.ok || !result.policy) {
37404
38295
  throw new PolicyResolutionError(`corenel: policy file "${path}" is not a valid policy document.`, result.errors);
37405
38296
  }
@@ -37477,14 +38368,14 @@ var McpHttpClient = class {
37477
38368
  }
37478
38369
  async listTools() {
37479
38370
  const result = await this.send("tools/list", {});
37480
- const tools = isRecord(result) ? result.tools : void 0;
38371
+ const tools = isRecord2(result) ? result.tools : void 0;
37481
38372
  if (!Array.isArray(tools)) return [];
37482
38373
  return tools.filter(isMcpTool);
37483
38374
  }
37484
38375
  async callTool(name, args) {
37485
38376
  const result = await this.send("tools/call", { name, arguments: args });
37486
- const record = isRecord(result) ? result : {};
37487
- return { content: record.content, isError: record.isError === true };
38377
+ const record2 = isRecord2(result) ? result : {};
38378
+ return { content: record2.content, isError: record2.isError === true };
37488
38379
  }
37489
38380
  /** Send one JSON-RPC request, retrying exactly once on a 401 that the
37490
38381
  * AuthProvider says it recovered from. `isRetry` prevents a second retry
@@ -37534,12 +38425,12 @@ var McpHttpClient = class {
37534
38425
  throw new Error(`MCP server "${this.server.name}" closed the stream without a response`);
37535
38426
  }
37536
38427
  const reader = res.body.getReader();
37537
- const decoder = new TextDecoder();
38428
+ const decoder3 = new TextDecoder();
37538
38429
  let buffer = "";
37539
38430
  try {
37540
38431
  for (; ; ) {
37541
38432
  const { done, value } = await reader.read();
37542
- if (value) buffer += decoder.decode(value, { stream: true });
38433
+ if (value) buffer += decoder3.decode(value, { stream: true });
37543
38434
  buffer = buffer.replace(/\r\n/g, "\n");
37544
38435
  let boundary = buffer.indexOf("\n\n");
37545
38436
  while (boundary !== -1) {
@@ -37570,7 +38461,7 @@ var McpHttpClient = class {
37570
38461
  } catch {
37571
38462
  return null;
37572
38463
  }
37573
- if (!isRecord(parsed) || parsed.id !== id) return null;
38464
+ if (!isRecord2(parsed) || parsed.id !== id) return null;
37574
38465
  if (!("result" in parsed) && !("error" in parsed)) return null;
37575
38466
  return parsed;
37576
38467
  }
@@ -37604,11 +38495,11 @@ var McpHttpClient = class {
37604
38495
  return headers;
37605
38496
  }
37606
38497
  };
37607
- function isRecord(value) {
38498
+ function isRecord2(value) {
37608
38499
  return typeof value === "object" && value !== null;
37609
38500
  }
37610
38501
  function isMcpTool(value) {
37611
- return isRecord(value) && typeof value.name === "string" && "inputSchema" in value;
38502
+ return isRecord2(value) && typeof value.name === "string" && "inputSchema" in value;
37612
38503
  }
37613
38504
 
37614
38505
  // ../mcp/src/config.ts
@@ -38372,7 +39263,7 @@ var McpRegistry = class {
38372
39263
  const inflight = this.slotConnecting.get(key);
38373
39264
  if (inflight) return inflight;
38374
39265
  const self2 = {};
38375
- const current = () => self2.attempt !== void 0 && this.slotConnecting.get(key) === self2.attempt;
39266
+ const current2 = () => self2.attempt !== void 0 && this.slotConnecting.get(key) === self2.attempt;
38376
39267
  const attempt = (async () => {
38377
39268
  const def = (await readMcpServers(this.stateDir, this.configEnv)).find((s) => s.name === server);
38378
39269
  if (!def) throw new Error(`MCP server "${server}" is not configured on this daemon`);
@@ -38381,10 +39272,10 @@ var McpRegistry = class {
38381
39272
  await client.initialize();
38382
39273
  return { client, tools: await client.listTools() };
38383
39274
  })(), SERVER_CONNECT_TIMEOUT_MS, `MCP server "${server}" timed out after ${SERVER_CONNECT_TIMEOUT_MS / 1e3}s`);
38384
- if (current()) this.slotted.set(key, entry);
39275
+ if (current2()) this.slotted.set(key, entry);
38385
39276
  return entry;
38386
39277
  })().finally(() => {
38387
- if (current()) this.slotConnecting.delete(key);
39278
+ if (current2()) this.slotConnecting.delete(key);
38388
39279
  });
38389
39280
  self2.attempt = attempt;
38390
39281
  this.slotConnecting.set(key, attempt);
@@ -38405,10 +39296,10 @@ var McpRegistry = class {
38405
39296
  };
38406
39297
 
38407
39298
  // ../mcp/src/policy.ts
38408
- import { PermissionService as PermissionService5, matchesAnyGlob as matchesAnyGlob2 } from "@corenel/harness/guardrail";
39299
+ import { PermissionService as PermissionService5, matchesAnyGlob as matchesAnyGlob3 } from "@corenel/harness/guardrail";
38409
39300
  function mcpCallAllowed(address, policy) {
38410
39301
  const allow = policy.tools?.allow ?? [];
38411
- if (!matchesAnyGlob2(address, allow)) {
39302
+ if (!matchesAnyGlob3(address, allow)) {
38412
39303
  return { ok: false, reason: `${address} is not allowed - add it with: corenel config add mcpAllow ${address}` };
38413
39304
  }
38414
39305
  const service = new PermissionService5({
@@ -38430,7 +39321,7 @@ function mcpCallAllowed(address, policy) {
38430
39321
  import {
38431
39322
  mcpToolAddress,
38432
39323
  parseMcpToolAddress,
38433
- mcpWireName,
39324
+ mcpWireName as mcpWireName2,
38434
39325
  parseMcpWireName,
38435
39326
  canEncodeMcpWireName,
38436
39327
  looksLikeMcpWireName
@@ -38470,7 +39361,7 @@ function asAgentTools(registry) {
38470
39361
  return out;
38471
39362
  }
38472
39363
  function toAgentTool(registry, server, tool) {
38473
- const name = mcpWireName(server, tool.name);
39364
+ const name = mcpWireName2(server, tool.name);
38474
39365
  const address = mcpToolAddress(server, tool.name);
38475
39366
  return {
38476
39367
  name,
@@ -38480,14 +39371,14 @@ function toAgentTool(registry, server, tool) {
38480
39371
  mutates: true,
38481
39372
  async run(args) {
38482
39373
  const result = await registry.call(server, tool.name, args);
38483
- const text = formatContent(result.content);
38484
- return result.isError ? `Error: ${text}` : text;
39374
+ const text2 = formatContent(result.content);
39375
+ return result.isError ? `Error: ${text2}` : text2;
38485
39376
  }
38486
39377
  };
38487
39378
  }
38488
39379
 
38489
39380
  // ../mcp/src/portTools.ts
38490
- import { MCP_CALL_FAILED, canEncodeMcpWireName as canEncodeMcpWireName2, mcpWireName as mcpWireName2, parseMcpToolAddress as parseMcpToolAddress2 } from "@corenel/protocol";
39381
+ import { MCP_CALL_FAILED, canEncodeMcpWireName as canEncodeMcpWireName2, mcpWireName as mcpWireName3, parseMcpToolAddress as parseMcpToolAddress2 } from "@corenel/protocol";
38491
39382
  var CALL_FAILED_TEXT = `Error: ${MCP_CALL_FAILED}: the MCP call failed before a result came back; it may or may not have run, so do not repeat it without checking.`;
38492
39383
 
38493
39384
  // ../mcp/src/gatedAgentTools.ts
@@ -38497,7 +39388,7 @@ function gatedAgentTools(registry, policy) {
38497
39388
  const wrapped = [];
38498
39389
  for (const { server, tool } of registry.tools()) {
38499
39390
  if (!canEncodeMcpWireName(server, tool.name)) continue;
38500
- const name = mcpWireName(server, tool.name);
39391
+ const name = mcpWireName2(server, tool.name);
38501
39392
  const original = byWireName.get(name);
38502
39393
  if (!original) continue;
38503
39394
  const address = mcpToolAddress(server, tool.name);
@@ -38640,12 +39531,12 @@ async function registerClient(meta, redirectUri, fetchImpl) {
38640
39531
  if (typeof body !== "object" || body === null || Array.isArray(body)) {
38641
39532
  throw new Error(`Client registration at ${meta.registrationEndpoint} returned a malformed response`);
38642
39533
  }
38643
- const record = body;
38644
- const clientId = record.client_id;
39534
+ const record2 = body;
39535
+ const clientId = record2.client_id;
38645
39536
  if (typeof clientId !== "string" || clientId.length === 0) {
38646
39537
  throw new Error(`Client registration at ${meta.registrationEndpoint} did not return a client_id`);
38647
39538
  }
38648
- const clientSecret = typeof record.client_secret === "string" ? record.client_secret : void 0;
39539
+ const clientSecret = typeof record2.client_secret === "string" ? record2.client_secret : void 0;
38649
39540
  return { clientId, clientSecret };
38650
39541
  }
38651
39542
 
@@ -39427,7 +40318,8 @@ async function main() {
39427
40318
  case "sidecar":
39428
40319
  case "acp":
39429
40320
  case "sandboxes":
39430
- case "crew": {
40321
+ case "crew":
40322
+ case "fleet": {
39431
40323
  const ext = findExtension(cmd);
39432
40324
  process.exitCode = ext ? await runExtension(ext, rest) : 2;
39433
40325
  break;