@lousy-agents/cli 5.14.10 → 5.15.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 (33) hide show
  1. package/api/copilot-with-fastify/.agents/skills/feature-to-plan/SKILL.md +164 -0
  2. package/api/copilot-with-fastify/.agents/skills/feature-to-plan/references/interactive-flow.md +122 -0
  3. package/api/copilot-with-fastify/.agents/skills/feature-to-plan/references/spec-format.md +434 -0
  4. package/api/copilot-with-fastify/.devcontainer/devcontainer.json +2 -2
  5. package/api/copilot-with-fastify/.github/ISSUE_TEMPLATE/feature-to-spec.yml +18 -10
  6. package/api/copilot-with-fastify/.github/instructions/spec.instructions.md +5 -2
  7. package/api/copilot-with-fastify/.nvmrc +1 -1
  8. package/api/copilot-with-fastify/biome.template.json +1 -1
  9. package/api/copilot-with-fastify/package-lock.json +340 -285
  10. package/api/copilot-with-fastify/package.json +7 -7
  11. package/cli/copilot-with-citty/.agents/skills/feature-to-plan/SKILL.md +164 -0
  12. package/cli/copilot-with-citty/.agents/skills/feature-to-plan/references/interactive-flow.md +122 -0
  13. package/cli/copilot-with-citty/.agents/skills/feature-to-plan/references/spec-format.md +434 -0
  14. package/cli/copilot-with-citty/.devcontainer/devcontainer.json +2 -2
  15. package/cli/copilot-with-citty/.github/ISSUE_TEMPLATE/feature-to-spec.yml +18 -10
  16. package/cli/copilot-with-citty/.nvmrc +1 -1
  17. package/cli/copilot-with-citty/biome.template.json +1 -1
  18. package/cli/copilot-with-citty/package.json +5 -5
  19. package/dist/116.js +4 -3
  20. package/dist/316.js +4 -3
  21. package/dist/475.js +2 -2
  22. package/dist/653.js +13 -10
  23. package/dist/index.js +510 -285
  24. package/package.json +1 -1
  25. package/ui/copilot-with-react/.agents/skills/feature-to-plan/SKILL.md +164 -0
  26. package/ui/copilot-with-react/.agents/skills/feature-to-plan/references/interactive-flow.md +122 -0
  27. package/ui/copilot-with-react/.agents/skills/feature-to-plan/references/spec-format.md +434 -0
  28. package/ui/copilot-with-react/.devcontainer/devcontainer.json +2 -2
  29. package/ui/copilot-with-react/.github/ISSUE_TEMPLATE/feature-to-spec.yml +18 -10
  30. package/ui/copilot-with-react/.github/instructions/spec.instructions.md +5 -2
  31. package/ui/copilot-with-react/.nvmrc +1 -1
  32. package/ui/copilot-with-react/biome.template.json +1 -1
  33. package/ui/copilot-with-react/package.json +11 -11
package/dist/index.js CHANGED
@@ -2990,7 +2990,7 @@ exports.basename = (path, { windows } = {}) => {
2990
2990
 
2991
2991
 
2992
2992
  },
2993
- 1809(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
2993
+ 8634(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
2994
2994
  // NAMESPACE OBJECT: ../../node_modules/micromark/lib/constructs.js
2995
2995
  var constructs_namespaceObject = {};
2996
2996
  __webpack_require__.r(constructs_namespaceObject);
@@ -3481,6 +3481,191 @@ function guardedRmSync(params) {
3481
3481
  }), { verifyAfter: params.verifyAfter });
3482
3482
  }
3483
3483
 
3484
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/deny-mutations.js
3485
+
3486
+
3487
+
3488
+
3489
+ async function pathExists(filePath) {
3490
+ try {
3491
+ await promises_.lstat(filePath);
3492
+ return true;
3493
+ }
3494
+ catch (err) {
3495
+ if (!path_isNotFoundPathError(err)) {
3496
+ throw err;
3497
+ }
3498
+ return false;
3499
+ }
3500
+ }
3501
+ async function resolvePathViaExistingAncestor(targetPath) {
3502
+ const normalized = external_node_path_.resolve(targetPath);
3503
+ let cursor = normalized;
3504
+ const missingSuffix = [];
3505
+ while (external_node_path_.dirname(cursor) !== cursor && !(await pathExists(cursor))) {
3506
+ missingSuffix.unshift(external_node_path_.basename(cursor));
3507
+ cursor = external_node_path_.dirname(cursor);
3508
+ }
3509
+ if (!(await pathExists(cursor))) {
3510
+ return normalized;
3511
+ }
3512
+ try {
3513
+ const resolvedAncestor = external_node_path_.resolve(await promises_.realpath(cursor));
3514
+ return missingSuffix.length === 0
3515
+ ? resolvedAncestor
3516
+ : external_node_path_.resolve(resolvedAncestor, ...missingSuffix);
3517
+ }
3518
+ catch {
3519
+ return normalized;
3520
+ }
3521
+ }
3522
+ async function comparablePaths(rawPath) {
3523
+ path_assertNoNulPathInput(rawPath, "path contains a NUL byte");
3524
+ const resolved = external_node_path_.resolve(rawPath);
3525
+ return new Set([resolved, await resolvePathViaExistingAncestor(resolved)]);
3526
+ }
3527
+ function isSamePath(left, right) {
3528
+ return path_isPathInside(left, right) && path_isPathInside(right, left);
3529
+ }
3530
+ function hasPolicyEntries(policy) {
3531
+ return Boolean(policy?.paths?.length || policy?.prefixes?.length);
3532
+ }
3533
+ function policyPathEntries(entries) {
3534
+ const paths = [];
3535
+ for (const entry of entries ?? []) {
3536
+ if (entry.length === 0) {
3537
+ throw new errors_FsSafeError("invalid-path", "deny mutation paths must be non-empty");
3538
+ }
3539
+ path_assertNoNulPathInput(entry, "deny mutation path contains a NUL byte");
3540
+ if (!external_node_path_.isAbsolute(entry)) {
3541
+ throw new errors_FsSafeError("invalid-path", "deny mutation paths must be absolute");
3542
+ }
3543
+ paths.push(entry);
3544
+ }
3545
+ return paths;
3546
+ }
3547
+ async function assertMutationNotDenied(filePath, policy, options = {}) {
3548
+ if (!hasPolicyEntries(policy)) {
3549
+ return;
3550
+ }
3551
+ const targetPaths = await comparablePaths(filePath);
3552
+ for (const deniedPath of policyPathEntries(policy.paths)) {
3553
+ const deniedPaths = await comparablePaths(deniedPath);
3554
+ for (const target of targetPaths) {
3555
+ for (const denied of deniedPaths) {
3556
+ if (isSamePath(denied, target) ||
3557
+ (options.protectAncestors === true && path_isPathInside(target, denied))) {
3558
+ throw new errors_FsSafeError("denied-path", "path is denied by denyMutations policy");
3559
+ }
3560
+ }
3561
+ }
3562
+ }
3563
+ for (const deniedPrefix of policyPathEntries(policy.prefixes)) {
3564
+ const deniedPaths = await comparablePaths(deniedPrefix);
3565
+ for (const target of targetPaths) {
3566
+ for (const denied of deniedPaths) {
3567
+ if (path_isPathInside(denied, target) ||
3568
+ (options.protectAncestors === true && path_isPathInside(target, denied))) {
3569
+ throw new errors_FsSafeError("denied-path", "path is denied by denyMutations policy");
3570
+ }
3571
+ }
3572
+ }
3573
+ }
3574
+ }
3575
+ function mergeDenyMutationPolicies(defaultPolicy, callPolicy) {
3576
+ if (!defaultPolicy) {
3577
+ return callPolicy;
3578
+ }
3579
+ if (!callPolicy) {
3580
+ return defaultPolicy;
3581
+ }
3582
+ return {
3583
+ paths: [...(defaultPolicy.paths ?? []), ...(callPolicy.paths ?? [])],
3584
+ prefixes: [...(defaultPolicy.prefixes ?? []), ...(callPolicy.prefixes ?? [])],
3585
+ };
3586
+ }
3587
+
3588
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/opened-realpath.js
3589
+
3590
+
3591
+
3592
+
3593
+
3594
+ async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
3595
+ const handleStat = await handle.stat();
3596
+ const fdCandidates = process.platform === "linux"
3597
+ ? [`/proc/self/fd/${handle.fd}`, `/dev/fd/${handle.fd}`]
3598
+ : process.platform === "win32"
3599
+ ? []
3600
+ : [`/dev/fd/${handle.fd}`];
3601
+ for (const fdPath of fdCandidates) {
3602
+ try {
3603
+ const fdRealPath = await promises_.realpath(fdPath);
3604
+ const fdRealStat = await promises_.stat(fdRealPath);
3605
+ if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
3606
+ return fdRealPath;
3607
+ }
3608
+ }
3609
+ catch {
3610
+ // try next fd path
3611
+ }
3612
+ }
3613
+ try {
3614
+ const ioRealPath = await promises_.realpath(ioPath);
3615
+ const ioRealStat = await promises_.stat(ioRealPath);
3616
+ if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
3617
+ return ioRealPath;
3618
+ }
3619
+ }
3620
+ catch (err) {
3621
+ if (!path_isNotFoundPathError(err)) {
3622
+ throw err;
3623
+ }
3624
+ }
3625
+ const parentResolved = await resolveOpenedFileRealPathFromParent(handleStat, ioPath);
3626
+ if (parentResolved) {
3627
+ return parentResolved;
3628
+ }
3629
+ throw new errors_FsSafeError("path-mismatch", "unable to resolve opened file path");
3630
+ }
3631
+ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath) {
3632
+ let parentReal;
3633
+ try {
3634
+ parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
3635
+ }
3636
+ catch (err) {
3637
+ if (path_isNotFoundPathError(err)) {
3638
+ return null;
3639
+ }
3640
+ throw err;
3641
+ }
3642
+ let entries;
3643
+ try {
3644
+ entries = await promises_.readdir(parentReal);
3645
+ }
3646
+ catch (err) {
3647
+ if (path_isNotFoundPathError(err)) {
3648
+ return null;
3649
+ }
3650
+ throw err;
3651
+ }
3652
+ for (const entry of entries.toSorted()) {
3653
+ const candidatePath = external_node_path_.join(parentReal, entry);
3654
+ try {
3655
+ const candidateStat = await promises_.lstat(candidatePath);
3656
+ if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
3657
+ return await promises_.realpath(candidatePath);
3658
+ }
3659
+ }
3660
+ catch (err) {
3661
+ if (!path_isNotFoundPathError(err)) {
3662
+ throw err;
3663
+ }
3664
+ }
3665
+ }
3666
+ return null;
3667
+ }
3668
+
3484
3669
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/pinned-python-config.js
3485
3670
  let overrideConfig = {};
3486
3671
  function parseMode(value) {
@@ -4327,7 +4512,7 @@ async function runPinnedWriteHelper(params) {
4327
4512
  relativeParentPath: params.relativeParentPath,
4328
4513
  });
4329
4514
  if (getFsSafePythonConfig().mode === "off") {
4330
- return await runPinnedWriteFallbackOrThrow(params);
4515
+ return await runPinnedWriteFallback(params);
4331
4516
  }
4332
4517
  if (params.input.kind === "stream") {
4333
4518
  try {
@@ -4335,7 +4520,7 @@ async function runPinnedWriteHelper(params) {
4335
4520
  }
4336
4521
  catch (error) {
4337
4522
  if (canFallbackFromPythonError(error)) {
4338
- return await runPinnedWriteFallbackOrThrow(params, error);
4523
+ return await runPinnedWriteFallback(params);
4339
4524
  }
4340
4525
  throw error;
4341
4526
  }
@@ -4359,7 +4544,7 @@ async function runPinnedWriteHelper(params) {
4359
4544
  }
4360
4545
  catch (error) {
4361
4546
  if (canFallbackFromPythonError(error)) {
4362
- return await runPinnedWriteFallbackOrThrow(params, error);
4547
+ return await runPinnedWriteFallback(params);
4363
4548
  }
4364
4549
  throw error;
4365
4550
  }
@@ -4386,12 +4571,6 @@ async function runPinnedCopyHelper(params) {
4386
4571
  },
4387
4572
  });
4388
4573
  }
4389
- async function runPinnedWriteFallbackOrThrow(params, cause) {
4390
- if (process.platform !== "win32") {
4391
- throw new errors_FsSafeError("helper-unavailable", "Python helper is required for pinned writes on this platform", { cause });
4392
- }
4393
- return await runPinnedWriteFallback(params);
4394
- }
4395
4574
  async function runPinnedWriteFallback(params) {
4396
4575
  const parentPath = params.relativeParentPath
4397
4576
  ? external_node_path_.join(params.rootPath, ...params.relativeParentPath.split("/"))
@@ -4514,7 +4693,7 @@ async function resolveRootPath(params) {
4514
4693
  const absolutePath = external_node_path_.resolve(params.absolutePath);
4515
4694
  const rootCanonicalPath = params.rootCanonicalPath
4516
4695
  ? external_node_path_.resolve(params.rootCanonicalPath)
4517
- : await resolvePathViaExistingAncestor(rootPath);
4696
+ : await root_path_resolvePathViaExistingAncestor(rootPath);
4518
4697
  const context = createBoundaryResolutionContext({
4519
4698
  resolveParams: params,
4520
4699
  rootPath,
@@ -4883,7 +5062,7 @@ async function resolveOutsideLexicalCanonicalPathAsync(params) {
4883
5062
  if (path_isPathInside(params.rootPath, params.absolutePath)) {
4884
5063
  return undefined;
4885
5064
  }
4886
- return await resolvePathViaExistingAncestor(params.absolutePath);
5065
+ return await root_path_resolvePathViaExistingAncestor(params.absolutePath);
4887
5066
  }
4888
5067
  function resolveOutsideLexicalCanonicalPathSync(params) {
4889
5068
  if (isPathInside(params.rootPath, params.absolutePath)) {
@@ -4930,11 +5109,11 @@ function buildResolvedRootPath(params) {
4930
5109
  kind: params.kind.kind,
4931
5110
  };
4932
5111
  }
4933
- async function resolvePathViaExistingAncestor(targetPath) {
5112
+ async function root_path_resolvePathViaExistingAncestor(targetPath) {
4934
5113
  const normalized = external_node_path_.resolve(targetPath);
4935
5114
  let cursor = normalized;
4936
5115
  const missingSuffix = [];
4937
- while (!isFilesystemRoot(cursor) && !(await pathExists(cursor))) {
5116
+ while (!isFilesystemRoot(cursor) && !(await root_path_pathExists(cursor))) {
4938
5117
  missingSuffix.unshift(external_node_path_.basename(cursor));
4939
5118
  const parent = external_node_path_.dirname(cursor);
4940
5119
  if (parent === cursor) {
@@ -4942,7 +5121,7 @@ async function resolvePathViaExistingAncestor(targetPath) {
4942
5121
  }
4943
5122
  cursor = parent;
4944
5123
  }
4945
- if (!(await pathExists(cursor))) {
5124
+ if (!(await root_path_pathExists(cursor))) {
4946
5125
  return normalized;
4947
5126
  }
4948
5127
  try {
@@ -5054,7 +5233,7 @@ function shortPath(value) {
5054
5233
  function isFilesystemRoot(candidate) {
5055
5234
  return external_node_path_.parse(candidate).root === candidate;
5056
5235
  }
5057
- async function pathExists(targetPath) {
5236
+ async function root_path_pathExists(targetPath) {
5058
5237
  try {
5059
5238
  await promises_.lstat(targetPath);
5060
5239
  return true;
@@ -5076,7 +5255,7 @@ async function resolveSymlinkHopPath(symlinkPath) {
5076
5255
  }
5077
5256
  const linkTarget = await promises_.readlink(symlinkPath);
5078
5257
  const linkAbsolute = external_node_path_.resolve(external_node_path_.dirname(symlinkPath), linkTarget);
5079
- return resolvePathViaExistingAncestor(linkAbsolute);
5258
+ return root_path_resolvePathViaExistingAncestor(linkAbsolute);
5080
5259
  }
5081
5260
  }
5082
5261
  function resolveSymlinkHopPathSync(symlinkPath) {
@@ -5145,6 +5324,23 @@ function path_policy_shortPath(value) {
5145
5324
  return value;
5146
5325
  }
5147
5326
 
5327
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/read-opened-file.js
5328
+
5329
+ async function read_opened_file_readOpenedFileSafely(params) {
5330
+ if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
5331
+ throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
5332
+ }
5333
+ const buffer = await params.opened.handle.readFile();
5334
+ if (params.maxBytes !== undefined && buffer.byteLength > params.maxBytes) {
5335
+ throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${buffer.byteLength})`);
5336
+ }
5337
+ return {
5338
+ buffer,
5339
+ realPath: params.opened.realPath,
5340
+ stat: params.opened.stat,
5341
+ };
5342
+ }
5343
+
5148
5344
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/path-stat.js
5149
5345
  function pathStatFromStats(stat) {
5150
5346
  return {
@@ -5472,6 +5668,10 @@ async function serializePathWrite(key, run) {
5472
5668
 
5473
5669
 
5474
5670
 
5671
+
5672
+
5673
+
5674
+
5475
5675
 
5476
5676
 
5477
5677
 
@@ -5670,6 +5870,7 @@ class RootHandle {
5670
5870
  mkdir: this.defaults.mkdir,
5671
5871
  mode: this.defaults.mode,
5672
5872
  ...options,
5873
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5673
5874
  append: writeMode === "append",
5674
5875
  truncateExisting: writeMode === "replace",
5675
5876
  });
@@ -5681,18 +5882,29 @@ class RootHandle {
5681
5882
  mkdir: this.defaults.mkdir,
5682
5883
  mode: this.defaults.mode,
5683
5884
  ...options,
5885
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5684
5886
  });
5685
5887
  }
5686
- async remove(relativePath) {
5888
+ async remove(relativePath, options = {}) {
5687
5889
  assertValidRootRelativePath(relativePath);
5688
- await removePathInRoot(this.context, relativePath);
5890
+ await removePathInRoot(this.context, {
5891
+ relativePath,
5892
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5893
+ });
5689
5894
  }
5690
- async mkdir(relativePath) {
5895
+ async mkdir(relativePath, options = {}) {
5691
5896
  assertValidRootRelativePath(relativePath);
5692
- await mkdirPathInRoot(this.context, { relativePath });
5897
+ await mkdirPathInRoot(this.context, {
5898
+ relativePath,
5899
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5900
+ });
5693
5901
  }
5694
- async ensureRoot() {
5695
- await mkdirPathInRoot(this.context, { relativePath: "", allowRoot: true });
5902
+ async ensureRoot(options = {}) {
5903
+ await mkdirPathInRoot(this.context, {
5904
+ relativePath: "",
5905
+ allowRoot: true,
5906
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5907
+ });
5696
5908
  }
5697
5909
  async write(relativePath, data, options = {}) {
5698
5910
  await writeFileInRoot(this.context, {
@@ -5701,6 +5913,7 @@ class RootHandle {
5701
5913
  mkdir: this.defaults.mkdir,
5702
5914
  mode: this.defaults.mode,
5703
5915
  ...options,
5916
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5704
5917
  });
5705
5918
  }
5706
5919
  async create(relativePath, data, options = {}) {
@@ -5710,6 +5923,7 @@ class RootHandle {
5710
5923
  mkdir: this.defaults.mkdir,
5711
5924
  mode: this.defaults.mode,
5712
5925
  ...options,
5926
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5713
5927
  overwrite: false,
5714
5928
  });
5715
5929
  }
@@ -5732,6 +5946,7 @@ class RootHandle {
5732
5946
  mkdir: this.defaults.mkdir,
5733
5947
  mode: this.defaults.mode,
5734
5948
  ...options,
5949
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
5735
5950
  });
5736
5951
  }
5737
5952
  async exists(relativePath) {
@@ -5775,6 +5990,12 @@ class RootHandle {
5775
5990
  async move(fromRelative, toRelative, options = {}) {
5776
5991
  assertValidRootRelativePath(fromRelative);
5777
5992
  assertValidRootRelativePath(toRelative);
5993
+ const denyMutations = mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations);
5994
+ await assertMoveMutationAllowed(this.context, {
5995
+ fromRelative,
5996
+ toRelative,
5997
+ denyMutations,
5998
+ });
5778
5999
  try {
5779
6000
  await runPinnedHelper("rename", this.rootReal, {
5780
6001
  from: fromRelative,
@@ -5786,6 +6007,7 @@ class RootHandle {
5786
6007
  if (canFallbackFromPythonError(error)) {
5787
6008
  await movePathFallback(this.context, {
5788
6009
  fromRelative,
6010
+ denyMutations,
5789
6011
  overwrite: options.overwrite ?? false,
5790
6012
  toRelative,
5791
6013
  });
@@ -5834,7 +6056,7 @@ async function openFileInRoot(root, params) {
5834
6056
  async function readFileInRoot(root, params) {
5835
6057
  const opened = await openFileInRoot(root, params);
5836
6058
  try {
5837
- return await readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
6059
+ return await read_opened_file_readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
5838
6060
  }
5839
6061
  finally {
5840
6062
  await opened.handle.close().catch(() => { });
@@ -5867,20 +6089,6 @@ async function openLocalFileSafely(params) {
5867
6089
  assertNoNulPathInput(params.filePath, "file path contains a NUL byte");
5868
6090
  return await openVerifiedLocalFile(params.filePath);
5869
6091
  }
5870
- async function readOpenedFileSafely(params) {
5871
- if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
5872
- throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
5873
- }
5874
- const buffer = await params.opened.handle.readFile();
5875
- if (params.maxBytes !== undefined && buffer.byteLength > params.maxBytes) {
5876
- throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${buffer.byteLength})`);
5877
- }
5878
- return {
5879
- buffer,
5880
- realPath: params.opened.realPath,
5881
- stat: params.opened.stat,
5882
- };
5883
- }
5884
6092
  function emitWriteBoundaryWarning(reason) {
5885
6093
  logWarn(`security: fs-safe write boundary warning (${reason})`);
5886
6094
  }
@@ -5921,82 +6129,9 @@ async function verifyAtomicWriteResult(params) {
5921
6129
  await opened.handle.close().catch(() => { });
5922
6130
  }
5923
6131
  }
5924
- async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
5925
- const handleStat = await handle.stat();
5926
- const fdCandidates = process.platform === "linux"
5927
- ? [`/proc/self/fd/${handle.fd}`, `/dev/fd/${handle.fd}`]
5928
- : process.platform === "win32"
5929
- ? []
5930
- : [`/dev/fd/${handle.fd}`];
5931
- for (const fdPath of fdCandidates) {
5932
- try {
5933
- const fdRealPath = await promises_.realpath(fdPath);
5934
- const fdRealStat = await promises_.stat(fdRealPath);
5935
- if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
5936
- return fdRealPath;
5937
- }
5938
- }
5939
- catch {
5940
- // try next fd path
5941
- }
5942
- }
5943
- try {
5944
- const ioRealPath = await promises_.realpath(ioPath);
5945
- const ioRealStat = await promises_.stat(ioRealPath);
5946
- if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
5947
- return ioRealPath;
5948
- }
5949
- }
5950
- catch (err) {
5951
- if (!path_isNotFoundPathError(err)) {
5952
- throw err;
5953
- }
5954
- }
5955
- const parentResolved = await resolveOpenedFileRealPathFromParent(handleStat, ioPath);
5956
- if (parentResolved) {
5957
- return parentResolved;
5958
- }
5959
- throw new errors_FsSafeError("path-mismatch", "unable to resolve opened file path");
5960
- }
5961
- async function resolveOpenedFileRealPathFromParent(handleStat, ioPath) {
5962
- let parentReal;
5963
- try {
5964
- parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
5965
- }
5966
- catch (err) {
5967
- if (path_isNotFoundPathError(err)) {
5968
- return null;
5969
- }
5970
- throw err;
5971
- }
5972
- let entries;
5973
- try {
5974
- entries = await promises_.readdir(parentReal);
5975
- }
5976
- catch (err) {
5977
- if (path_isNotFoundPathError(err)) {
5978
- return null;
5979
- }
5980
- throw err;
5981
- }
5982
- for (const entry of entries.toSorted()) {
5983
- const candidatePath = external_node_path_.join(parentReal, entry);
5984
- try {
5985
- const candidateStat = await promises_.lstat(candidatePath);
5986
- if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
5987
- return await promises_.realpath(candidatePath);
5988
- }
5989
- }
5990
- catch (err) {
5991
- if (!path_isNotFoundPathError(err)) {
5992
- throw err;
5993
- }
5994
- }
5995
- }
5996
- return null;
5997
- }
5998
6132
  async function openWritableFileInRoot(root, params) {
5999
6133
  const { rootReal, rootWithSep, resolved } = await resolvePathInRoot(root, params.relativePath);
6134
+ await assertMutationNotDenied(resolved, params.denyMutations);
6000
6135
  try {
6001
6136
  await assertNoPathAliasEscape({
6002
6137
  absolutePath: resolved,
@@ -6123,6 +6258,7 @@ async function appendFileInRoot(root, params) {
6123
6258
  relativePath: params.relativePath,
6124
6259
  mkdir: params.mkdir,
6125
6260
  mode: params.mode,
6261
+ denyMutations: params.denyMutations,
6126
6262
  truncateExisting: false,
6127
6263
  append: true,
6128
6264
  });
@@ -6150,8 +6286,8 @@ async function appendFileInRoot(root, params) {
6150
6286
  await target.handle.close().catch(() => { });
6151
6287
  }
6152
6288
  }
6153
- async function removePathInRoot(root, relativePath) {
6154
- const resolved = await resolvePinnedRemovePathInRoot(root, relativePath);
6289
+ async function removePathInRoot(root, params) {
6290
+ const resolved = await resolvePinnedRemovePathInRoot(root, params.relativePath, params.denyMutations);
6155
6291
  if (process.platform === "win32") {
6156
6292
  await removePathFallback(resolved);
6157
6293
  return;
@@ -6199,7 +6335,7 @@ async function writeFileInRoot(root, params) {
6199
6335
  });
6200
6336
  return;
6201
6337
  }
6202
- const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode);
6338
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
6203
6339
  await serializePathWrite(pinned.targetPath, async () => {
6204
6340
  let identity;
6205
6341
  try {
@@ -6255,7 +6391,7 @@ async function copyFileInRoot(root, params) {
6255
6391
  });
6256
6392
  return;
6257
6393
  }
6258
- const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode);
6394
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
6259
6395
  await serializePathWrite(pinned.targetPath, async () => {
6260
6396
  let identity;
6261
6397
  try {
@@ -6299,8 +6435,9 @@ async function copyFileInRoot(root, params) {
6299
6435
  await source.handle.close().catch(() => { });
6300
6436
  }
6301
6437
  }
6302
- async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode) {
6438
+ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode, denyMutations) {
6303
6439
  const { rootReal, rootWithSep, resolved } = await resolvePathInRoot(root, relativePath);
6440
+ await assertMutationNotDenied(resolved, denyMutations);
6304
6441
  try {
6305
6442
  await assertNoPathAliasEscape({
6306
6443
  absolutePath: resolved,
@@ -6357,12 +6494,16 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode)
6357
6494
  async function resolvePinnedPathInRoot(root, params) {
6358
6495
  return await resolvePinnedOperationPathInRoot(root, {
6359
6496
  allowRoot: params.allowRoot,
6497
+ denyMutations: params.denyMutations,
6498
+ protectDenyMutationAncestors: false,
6360
6499
  relativePath: params.relativePath,
6361
6500
  policy: PATH_ALIAS_POLICIES.strict,
6362
6501
  });
6363
6502
  }
6364
- async function resolvePinnedRemovePathInRoot(root, relativePath) {
6503
+ async function resolvePinnedRemovePathInRoot(root, relativePath, denyMutations) {
6365
6504
  return await resolvePinnedOperationPathInRoot(root, {
6505
+ denyMutations,
6506
+ protectDenyMutationAncestors: true,
6366
6507
  relativePath,
6367
6508
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
6368
6509
  });
@@ -6374,6 +6515,7 @@ async function resolvePinnedOperationPathInRoot(root, params) {
6374
6515
  });
6375
6516
  const relativeResolved = external_node_path_.relative(resolved.rootReal, resolved.canonicalPath);
6376
6517
  if ((relativeResolved === "" || relativeResolved === ".") && params.allowRoot === true) {
6518
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations);
6377
6519
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix: "" };
6378
6520
  }
6379
6521
  const firstSegment = relativeResolved.split(external_node_path_.sep)[0];
@@ -6387,6 +6529,9 @@ async function resolvePinnedOperationPathInRoot(root, params) {
6387
6529
  if (!path_isPathInside(resolved.rootWithSep, resolved.canonicalPath)) {
6388
6530
  throw new errors_FsSafeError("outside-workspace", "file is outside workspace root");
6389
6531
  }
6532
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
6533
+ protectAncestors: params.protectDenyMutationAncestors,
6534
+ });
6390
6535
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
6391
6536
  }
6392
6537
  async function resolvePinnedRootPathInRoot(root, params) {
@@ -6464,13 +6609,21 @@ async function listPathFallback(root, relativePath, withFileTypes) {
6464
6609
  throw error;
6465
6610
  }
6466
6611
  }
6612
+ async function assertMoveMutationAllowed(root, params) {
6613
+ const source = await resolvePathInRoot(root, params.fromRelative);
6614
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
6615
+ const target = await resolvePathInRoot(root, params.toRelative);
6616
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
6617
+ }
6467
6618
  async function movePathFallback(root, params) {
6468
6619
  const source = await resolvePathInRoot(root, params.fromRelative);
6620
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
6469
6621
  await resolvePinnedRootPathInRoot(root, {
6470
6622
  relativePath: params.fromRelative,
6471
6623
  policy: PATH_ALIAS_POLICIES.strict,
6472
6624
  });
6473
6625
  const target = await resolvePathInRoot(root, params.toRelative);
6626
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
6474
6627
  await resolvePinnedRootPathInRoot(root, {
6475
6628
  relativePath: params.toRelative,
6476
6629
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
@@ -6554,6 +6707,7 @@ async function writeFileFallback(root, params) {
6554
6707
  relativePath: params.relativePath,
6555
6708
  mkdir: params.mkdir,
6556
6709
  mode: params.mode,
6710
+ denyMutations: params.denyMutations,
6557
6711
  truncateExisting: false,
6558
6712
  });
6559
6713
  const destinationPath = target.realPath;
@@ -6599,6 +6753,7 @@ async function writeFileFallback(root, params) {
6599
6753
  }
6600
6754
  async function writeMissingFileFallback(root, params) {
6601
6755
  const { rootReal, resolved } = await resolvePathInRoot(root, params.relativePath);
6756
+ await assertMutationNotDenied(resolved, params.denyMutations);
6602
6757
  try {
6603
6758
  await assertNoPathAliasEscape({
6604
6759
  absolutePath: resolved,
@@ -6672,6 +6827,7 @@ async function copyFileFallback(root, params, source) {
6672
6827
  relativePath: params.relativePath,
6673
6828
  mkdir: params.mkdir,
6674
6829
  mode: params.mode,
6830
+ denyMutations: params.denyMutations,
6675
6831
  truncateExisting: false,
6676
6832
  });
6677
6833
  const destinationPath = target.realPath;
@@ -21554,8 +21710,8 @@ function dist_bundle_withDefaults(oldDefaults, newDefaults) {
21554
21710
  var dist_bundle_endpoint = dist_bundle_withDefaults(null, DEFAULTS);
21555
21711
 
21556
21712
 
21557
- // EXTERNAL MODULE: ../../node_modules/fast-content-type-parse/index.js
21558
- var fast_content_type_parse = __webpack_require__(2592);
21713
+ // EXTERNAL MODULE: ../../node_modules/@octokit/request/node_modules/content-type/dist/index.js
21714
+ var content_type_dist = __webpack_require__(9703);
21559
21715
  ;// CONCATENATED MODULE: ../../node_modules/json-with-bigint/json-with-bigint.js
21560
21716
  const intRegex = /^-?\d+$/;
21561
21717
  const noiseValue = /^-?\d+n+$/; // Noise - strings that match the custom format before being converted to it
@@ -21822,7 +21978,7 @@ class RequestError extends Error {
21822
21978
 
21823
21979
 
21824
21980
  // pkg/dist-src/version.js
21825
- var dist_bundle_VERSION = "10.0.8";
21981
+ var dist_bundle_VERSION = "10.0.10";
21826
21982
 
21827
21983
  // pkg/dist-src/defaults.js
21828
21984
  var defaults_default = {
@@ -21951,7 +22107,7 @@ async function getResponseData(response) {
21951
22107
  if (!contentType) {
21952
22108
  return response.text().catch(noop);
21953
22109
  }
21954
- const mimetype = (0,fast_content_type_parse/* .safeParse */.xL)(contentType);
22110
+ const mimetype = (0,content_type_dist/* .parse */.qg)(contentType);
21955
22111
  if (isJSONResponse(mimetype)) {
21956
22112
  let text = "";
21957
22113
  try {
@@ -25800,6 +25956,7 @@ const PackageJsonSchema = schemas_object({
25800
25956
  */
25801
25957
 
25802
25958
 
25959
+
25803
25960
  /** Maximum skill file size: 1 MB */ const MAX_SKILL_FILE_BYTES = 1_048_576;
25804
25961
  /**
25805
25962
  * Skill directory locations to search for SKILL.md files.
@@ -25808,6 +25965,33 @@ const PackageJsonSchema = schemas_object({
25808
25965
  (0,external_node_path_.join)(".claude", "skills"),
25809
25966
  (0,external_node_path_.join)(".agents", "skills")
25810
25967
  ];
25968
+ /** Maximum lock file size: 256 KB */ const MAX_LOCK_FILE_BYTES = 262_144;
25969
+ /** Relative path to the skills lock file. */ const SKILLS_LOCK_PATH = "skills-lock.json";
25970
+ /** Zod schema for skills-lock.json structure */ const SkillsLockSchema = schemas_object({
25971
+ skills: record(schemas_string(), unknown()).optional()
25972
+ });
25973
+ /**
25974
+ * Reads the skills-lock.json file and returns the set of locked skill names.
25975
+ * Returns an empty set if the file does not exist or cannot be parsed.
25976
+ */ async function readLockedSkillNames(targetDir) {
25977
+ try {
25978
+ const exists = await file_system_utils_pathExistsWithinRoot(targetDir, SKILLS_LOCK_PATH);
25979
+ if (!exists) {
25980
+ return new Set();
25981
+ }
25982
+ const content = await file_system_utils_readTextWithinRoot(targetDir, SKILLS_LOCK_PATH, MAX_LOCK_FILE_BYTES);
25983
+ const result = SkillsLockSchema.safeParse(JSON.parse(content));
25984
+ if (result.success && Object.hasOwn(result.data, "skills") && result.data.skills != null) {
25985
+ return new Set(Object.keys(result.data.skills));
25986
+ }
25987
+ return new Set();
25988
+ } catch (error) {
25989
+ if (file_system_utils_isFsSafeViolation(error)) {
25990
+ throw error;
25991
+ }
25992
+ return new Set();
25993
+ }
25994
+ }
25811
25995
  /**
25812
25996
  * File system implementation of the skill lint gateway.
25813
25997
  */ class FileSystemSkillLintGateway {
@@ -25817,7 +26001,11 @@ const PackageJsonSchema = schemas_object({
25817
26001
  const discovered = await this.discoverSkillsInDir(targetDir, relativeDir);
25818
26002
  skills.push(...discovered);
25819
26003
  }
25820
- return skills;
26004
+ const lockedNames = await readLockedSkillNames(targetDir);
26005
+ if (lockedNames.size === 0) {
26006
+ return skills;
26007
+ }
26008
+ return skills.filter((skill)=>!lockedNames.has(skill.skillName));
25821
26009
  }
25822
26010
  async discoverSkillsInDir(targetDir, skillsDir) {
25823
26011
  try {
@@ -27696,6 +27884,38 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
27696
27884
  type: "file",
27697
27885
  path: ".devcontainer/devcontainer.json",
27698
27886
  content: reader(".devcontainer/devcontainer.json")
27887
+ },
27888
+ // Agent skills — required by the feature-to-plan skill invocation in the issue template
27889
+ {
27890
+ type: "directory",
27891
+ path: ".agents"
27892
+ },
27893
+ {
27894
+ type: "directory",
27895
+ path: ".agents/skills"
27896
+ },
27897
+ {
27898
+ type: "directory",
27899
+ path: ".agents/skills/feature-to-plan"
27900
+ },
27901
+ {
27902
+ type: "file",
27903
+ path: ".agents/skills/feature-to-plan/SKILL.md",
27904
+ content: reader(".agents/skills/feature-to-plan/SKILL.md")
27905
+ },
27906
+ {
27907
+ type: "directory",
27908
+ path: ".agents/skills/feature-to-plan/references"
27909
+ },
27910
+ {
27911
+ type: "file",
27912
+ path: ".agents/skills/feature-to-plan/references/interactive-flow.md",
27913
+ content: reader(".agents/skills/feature-to-plan/references/interactive-flow.md")
27914
+ },
27915
+ {
27916
+ type: "file",
27917
+ path: ".agents/skills/feature-to-plan/references/spec-format.md",
27918
+ content: reader(".agents/skills/feature-to-plan/references/spec-format.md")
27699
27919
  }
27700
27920
  ];
27701
27921
  }
@@ -43320,7 +43540,7 @@ function formatHeadingAsSetext(node, state) {
43320
43540
  node.type === 'break'
43321
43541
  ) {
43322
43542
  literalWithBreak = true
43323
- return EXIT
43543
+ return (/* inlined export .EXIT */false)
43324
43544
  }
43325
43545
  })
43326
43546
 
@@ -50422,178 +50642,178 @@ module.exports = __rspack_createRequire_require("process");
50422
50642
  module.exports = __rspack_createRequire_require("zlib");
50423
50643
 
50424
50644
  },
50425
- 2592(module) {
50645
+ 9703(__unused_rspack_module, exports) {
50426
50646
  var __webpack_unused_export__;
50427
50647
 
50428
-
50429
- const NullObject = function NullObject () { }
50430
- NullObject.prototype = Object.create(null)
50431
-
50432
- /**
50433
- * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
50434
- *
50435
- * parameter = token "=" ( token / quoted-string )
50436
- * token = 1*tchar
50437
- * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
50438
- * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
50439
- * / DIGIT / ALPHA
50440
- * ; any VCHAR, except delimiters
50441
- * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
50442
- * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
50443
- * obs-text = %x80-FF
50444
- * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
50648
+ /*!
50649
+ * content-type
50650
+ * Copyright(c) 2015 Douglas Christopher Wilson
50651
+ * MIT Licensed
50445
50652
  */
50446
- const paramRE = /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu
50447
-
50653
+ __webpack_unused_export__ = ({ value: true });
50654
+ __webpack_unused_export__ = format;
50655
+ exports.qg = parse;
50656
+ const TEXT_REGEXP = /^[\u0009\u0020-\u007e\u0080-\u00ff]*$/;
50657
+ const TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
50448
50658
  /**
50449
- * RegExp to match quoted-pair in RFC 7230 sec 3.2.6
50450
- *
50451
- * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
50452
- * obs-text = %x80-FF
50659
+ * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4
50453
50660
  */
50454
- const quotedPairRE = /\\([\v\u0020-\u00ff])/gu
50455
-
50661
+ const QUOTE_REGEXP = /[\\"]/g;
50456
50662
  /**
50457
- * RegExp to match type in RFC 7231 sec 3.1.1.1
50663
+ * RegExp to match type in RFC 9110 sec 8.3.1
50458
50664
  *
50459
50665
  * media-type = type "/" subtype
50460
50666
  * type = token
50461
50667
  * subtype = token
50462
50668
  */
50463
- const mediaTypeRE = /^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u
50464
-
50465
- // default ContentType to prevent repeated object creation
50466
- const defaultContentType = { type: '', parameters: new NullObject() }
50467
- Object.freeze(defaultContentType.parameters)
50468
- Object.freeze(defaultContentType)
50469
-
50669
+ const TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
50470
50670
  /**
50471
- * Parse media type to object.
50472
- *
50473
- * @param {string|object} header
50474
- * @return {Object}
50475
- * @public
50671
+ * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`.
50476
50672
  */
50477
-
50478
- function parse (header) {
50479
- if (typeof header !== 'string') {
50480
- throw new TypeError('argument header is required and must be a string')
50481
- }
50482
-
50483
- let index = header.indexOf(';')
50484
- const type = index !== -1
50485
- ? header.slice(0, index).trim()
50486
- : header.trim()
50487
-
50488
- if (mediaTypeRE.test(type) === false) {
50489
- throw new TypeError('invalid media type')
50490
- }
50491
-
50492
- const result = {
50493
- type: type.toLowerCase(),
50494
- parameters: new NullObject()
50495
- }
50496
-
50497
- // parse parameters
50498
- if (index === -1) {
50499
- return result
50500
- }
50501
-
50502
- let key
50503
- let match
50504
- let value
50505
-
50506
- paramRE.lastIndex = index
50507
-
50508
- while ((match = paramRE.exec(header))) {
50509
- if (match.index !== index) {
50510
- throw new TypeError('invalid parameter format')
50673
+ const NullObject = /* @__PURE__ */ (() => {
50674
+ const C = function () { };
50675
+ C.prototype = Object.create(null);
50676
+ return C;
50677
+ })();
50678
+ /**
50679
+ * Format an object into a `Content-Type` header.
50680
+ */
50681
+ function format(obj) {
50682
+ const { type, parameters } = obj;
50683
+ if (!type || !TYPE_REGEXP.test(type)) {
50684
+ throw new TypeError(`Invalid type: ${type}`);
50511
50685
  }
50512
-
50513
- index += match[0].length
50514
- key = match[1].toLowerCase()
50515
- value = match[2]
50516
-
50517
- if (value[0] === '"') {
50518
- // remove quotes and escapes
50519
- value = value
50520
- .slice(1, value.length - 1)
50521
-
50522
- quotedPairRE.test(value) && (value = value.replace(quotedPairRE, '$1'))
50686
+ let result = type;
50687
+ if (parameters) {
50688
+ for (const param of Object.keys(parameters)) {
50689
+ if (!TOKEN_REGEXP.test(param)) {
50690
+ throw new TypeError(`Invalid parameter name: ${param}`);
50691
+ }
50692
+ result += `; ${param}=${qstring(parameters[param])}`;
50693
+ }
50523
50694
  }
50524
-
50525
- result.parameters[key] = value
50526
- }
50527
-
50528
- if (index !== header.length) {
50529
- throw new TypeError('invalid parameter format')
50530
- }
50531
-
50532
- return result
50695
+ return result;
50533
50696
  }
50534
-
50535
- function safeParse (header) {
50536
- if (typeof header !== 'string') {
50537
- return defaultContentType
50538
- }
50539
-
50540
- let index = header.indexOf(';')
50541
- const type = index !== -1
50542
- ? header.slice(0, index).trim()
50543
- : header.trim()
50544
-
50545
- if (mediaTypeRE.test(type) === false) {
50546
- return defaultContentType
50547
- }
50548
-
50549
- const result = {
50550
- type: type.toLowerCase(),
50551
- parameters: new NullObject()
50552
- }
50553
-
50554
- // parse parameters
50555
- if (index === -1) {
50556
- return result
50557
- }
50558
-
50559
- let key
50560
- let match
50561
- let value
50562
-
50563
- paramRE.lastIndex = index
50564
-
50565
- while ((match = paramRE.exec(header))) {
50566
- if (match.index !== index) {
50567
- return defaultContentType
50697
+ /**
50698
+ * Parse a `Content-Type` header.
50699
+ */
50700
+ function parse(header, options) {
50701
+ const len = header.length;
50702
+ let index = skipOWS(header, 0, len);
50703
+ const valueStart = index;
50704
+ index = skipValue(header, index, len);
50705
+ const valueEnd = trailingOWS(header, valueStart, index);
50706
+ const type = header.slice(valueStart, valueEnd).toLowerCase();
50707
+ const parameters = options?.parameters === false
50708
+ ? new NullObject()
50709
+ : parseParameters(header, index, len);
50710
+ return { type, parameters };
50711
+ }
50712
+ const SP = 32; // " "
50713
+ const HTAB = 9; // "\t"
50714
+ const SEMI = 59; // ";"
50715
+ const EQ = 61; // "="
50716
+ const DQUOTE = 34; // '"'
50717
+ const BSLASH = 92; // "\\"
50718
+ /**
50719
+ * Parses the parameters of a `Content-Type` header starting at the given index.
50720
+ */
50721
+ function parseParameters(header, index, len) {
50722
+ const parameters = new NullObject();
50723
+ parameter: while (index < len) {
50724
+ index = skipOWS(header, index + 1 /* Skip over ; */, len);
50725
+ const keyStart = index;
50726
+ while (index < len) {
50727
+ const code = header.charCodeAt(index);
50728
+ if (code === SEMI)
50729
+ continue parameter;
50730
+ if (code === EQ) {
50731
+ const keyEnd = trailingOWS(header, keyStart, index);
50732
+ const key = header.slice(keyStart, keyEnd).toLowerCase();
50733
+ index = skipOWS(header, index + 1, len);
50734
+ if (index < len && header.charCodeAt(index) === DQUOTE) {
50735
+ index++;
50736
+ let value = "";
50737
+ while (index < len) {
50738
+ const code = header.charCodeAt(index++);
50739
+ if (code === DQUOTE) {
50740
+ index = skipValue(header, index, len);
50741
+ if (parameters[key] === undefined)
50742
+ parameters[key] = value;
50743
+ break;
50744
+ }
50745
+ if (code === BSLASH && index < len) {
50746
+ value += header[index++];
50747
+ continue;
50748
+ }
50749
+ value += String.fromCharCode(code);
50750
+ }
50751
+ continue parameter;
50752
+ }
50753
+ const valueStart = index;
50754
+ index = skipValue(header, index, len);
50755
+ if (parameters[key] === undefined) {
50756
+ const valueEnd = trailingOWS(header, valueStart, index);
50757
+ parameters[key] = header.slice(valueStart, valueEnd);
50758
+ }
50759
+ continue parameter;
50760
+ }
50761
+ index++;
50762
+ }
50568
50763
  }
50569
-
50570
- index += match[0].length
50571
- key = match[1].toLowerCase()
50572
- value = match[2]
50573
-
50574
- if (value[0] === '"') {
50575
- // remove quotes and escapes
50576
- value = value
50577
- .slice(1, value.length - 1)
50578
-
50579
- quotedPairRE.test(value) && (value = value.replace(quotedPairRE, '$1'))
50764
+ return parameters;
50765
+ }
50766
+ /**
50767
+ * Skip over characters until a semicolon.
50768
+ */
50769
+ function skipValue(str, index, len) {
50770
+ while (index < len) {
50771
+ const char = str.charCodeAt(index);
50772
+ if (char === SEMI)
50773
+ break;
50774
+ index++;
50580
50775
  }
50581
-
50582
- result.parameters[key] = value
50583
- }
50584
-
50585
- if (index !== header.length) {
50586
- return defaultContentType
50587
- }
50588
-
50589
- return result
50776
+ return index;
50590
50777
  }
50591
-
50592
- __webpack_unused_export__ = { parse, safeParse }
50593
- __webpack_unused_export__ = parse
50594
- module.exports.xL = safeParse
50595
- __webpack_unused_export__ = defaultContentType
50596
-
50778
+ /**
50779
+ * Skip optional whitespace (OWS) in an HTTP header value.
50780
+ *
50781
+ * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t").
50782
+ */
50783
+ function skipOWS(header, index, len) {
50784
+ while (index < len) {
50785
+ const char = header.charCodeAt(index);
50786
+ if (char !== SP && char !== HTAB)
50787
+ break;
50788
+ index++;
50789
+ }
50790
+ return index;
50791
+ }
50792
+ /**
50793
+ * Trim optional whitespace (OWS) from the end of a substring.
50794
+ *
50795
+ * OWS is defined in RFC 9110 sec 5.6.3 as SP (" ") or HTAB ("\t").
50796
+ */
50797
+ function trailingOWS(header, start, end) {
50798
+ while (end > start) {
50799
+ const char = header.charCodeAt(end - 1);
50800
+ if (char !== SP && char !== HTAB)
50801
+ break;
50802
+ end--;
50803
+ }
50804
+ return end;
50805
+ }
50806
+ /**
50807
+ * Serialize a parameter value.
50808
+ */
50809
+ function qstring(str) {
50810
+ if (TOKEN_REGEXP.test(str))
50811
+ return str;
50812
+ if (TEXT_REGEXP.test(str))
50813
+ return `"${str.replace(QUOTE_REGEXP, "\\$&")}"`;
50814
+ throw new TypeError(`Invalid parameter value: ${str}`);
50815
+ }
50816
+ //# sourceMappingURL=index.js.map
50597
50817
 
50598
50818
  },
50599
50819
  3273(module, __unused_rspack_exports, __webpack_require__) {
@@ -58949,10 +59169,11 @@ exports.visitAsync = visitAsync;
58949
59169
 
58950
59170
  },
58951
59171
  5492(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
59172
+ const t=Symbol.for(`__confbox_fmt__`),n=/^(\s+)/,r=/(\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}
58952
59173
  __webpack_require__.d(__webpack_exports__, {
58953
59174
  n: () => (a)
58954
59175
  });
58955
- const t=Symbol.for(`__confbox_fmt__`),n=/^(\s+)/,r=/(\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}
59176
+
58956
59177
 
58957
59178
  },
58958
59179
  5975(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -59049,12 +59270,16 @@ __webpack_require__.t = function(value, mode) {
59049
59270
  })();
59050
59271
  // webpack/runtime/define_property_getters
59051
59272
  (() => {
59052
- __webpack_require__.d = (exports, definition) => {
59053
- for(var key in definition) {
59054
- if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
59055
- Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
59056
- }
59057
- }
59273
+ __webpack_require__.d = (exports, getters, values) => {
59274
+ var define = (defs, kind) => {
59275
+ for(var key in defs) {
59276
+ if(__webpack_require__.o(defs, key) && !__webpack_require__.o(exports, key)) {
59277
+ Object.defineProperty(exports, key, { enumerable: true, [kind]: defs[key] });
59278
+ }
59279
+ }
59280
+ };
59281
+ define(getters, "get");
59282
+ define(values, "value");
59058
59283
  };
59059
59284
  })();
59060
59285
  // webpack/runtime/ensure_chunk
@@ -59156,4 +59381,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
59156
59381
  // module factories are used so entry inlining is disabled
59157
59382
  // startup
59158
59383
  // Load entry module and return exports
59159
- var __webpack_exports__ = __webpack_require__(1809);
59384
+ var __webpack_exports__ = __webpack_require__(8634);