@lousy-agents/mcp 5.17.15 → 5.18.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.
@@ -6559,7 +6559,7 @@ function escapeJsonPtr(str) {
6559
6559
 
6560
6560
 
6561
6561
  },
6562
- 1895(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
6562
+ 8454(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
6563
6563
  // NAMESPACE OBJECT: ../../node_modules/micromark/lib/constructs.js
6564
6564
  var constructs_namespaceObject = {};
6565
6565
  __webpack_require__.r(constructs_namespaceObject);
@@ -32915,7 +32915,7 @@ function packageImportsResolve(name, base, conditions) {
32915
32915
  while (++i < keys.length) {
32916
32916
  const key = keys[i];
32917
32917
  const patternIndex = key.indexOf("*");
32918
- if (patternIndex !== -1 && name.startsWith(key.slice(0, -1))) {
32918
+ if (patternIndex !== -1 && name.startsWith(key.slice(0, patternIndex))) {
32919
32919
  const patternTrailer = key.slice(patternIndex + 1);
32920
32920
  if (name.length >= key.length && name.endsWith(patternTrailer) && patternKeyCompare(bestMatch, key) === 1 && key.lastIndexOf("*") === patternIndex) {
32921
32921
  bestMatch = key;
@@ -37466,6 +37466,312 @@ const PackageJsonSchema = schemas_object({
37466
37466
  return new FileSystemSkillFileGateway();
37467
37467
  }
37468
37468
 
37469
+ ;// CONCATENATED MODULE: ../core/src/entities/agentic-location-catalog.ts
37470
+ /**
37471
+ * Canonical catalog of agentic construct locations shared by lint and doctor.
37472
+ * Pure data only — no filesystem I/O.
37473
+ */ const agentic_location_catalog_AGENTIC_LOCATION_CATALOG = [
37474
+ // Skill lint roots
37475
+ {
37476
+ id: "skill-github",
37477
+ path: ".github/skills",
37478
+ matchKind: "directory-prefix",
37479
+ primaryConstruct: "skill",
37480
+ lintTarget: "skills",
37481
+ harnessHints: [
37482
+ "copilot"
37483
+ ]
37484
+ },
37485
+ {
37486
+ id: "skill-claude",
37487
+ path: ".claude/skills",
37488
+ matchKind: "directory-prefix",
37489
+ primaryConstruct: "skill",
37490
+ lintTarget: "skills",
37491
+ harnessHints: [
37492
+ "claude"
37493
+ ]
37494
+ },
37495
+ {
37496
+ id: "skill-agents",
37497
+ path: ".agents/skills",
37498
+ matchKind: "directory-prefix",
37499
+ primaryConstruct: "skill",
37500
+ lintTarget: "skills",
37501
+ harnessHints: [
37502
+ "shared"
37503
+ ]
37504
+ },
37505
+ // Doctor-only skill locations
37506
+ {
37507
+ id: "skill-pi",
37508
+ path: ".pi/skills",
37509
+ matchKind: "directory-prefix",
37510
+ primaryConstruct: "skill",
37511
+ lintTarget: "none",
37512
+ harnessHints: [
37513
+ "pi"
37514
+ ]
37515
+ },
37516
+ {
37517
+ id: "skill-pi-prompts",
37518
+ path: ".pi/prompts",
37519
+ matchKind: "directory-prefix",
37520
+ primaryConstruct: "skill",
37521
+ lintTarget: "none",
37522
+ harnessHints: [
37523
+ "pi"
37524
+ ]
37525
+ },
37526
+ // Agent lint root (dual-role: agent + instruction)
37527
+ {
37528
+ id: "agent-github",
37529
+ path: ".github/agents",
37530
+ matchKind: "directory-prefix",
37531
+ primaryConstruct: "agent",
37532
+ secondaryConstructs: [
37533
+ "instruction"
37534
+ ],
37535
+ lintTarget: "agents",
37536
+ harnessHints: [
37537
+ "copilot"
37538
+ ],
37539
+ instructionFormat: "copilot-agent"
37540
+ },
37541
+ // Hook lint exact configs
37542
+ {
37543
+ id: "hook-copilot-agent-shell",
37544
+ path: ".github/hooks/agent-shell/hooks.json",
37545
+ matchKind: "exact",
37546
+ primaryConstruct: "hook",
37547
+ lintTarget: "hooks",
37548
+ harnessHints: [
37549
+ "copilot"
37550
+ ],
37551
+ hookPlatform: "copilot"
37552
+ },
37553
+ {
37554
+ id: "hook-claude-settings",
37555
+ path: ".claude/settings.json",
37556
+ matchKind: "exact",
37557
+ primaryConstruct: "hook",
37558
+ lintTarget: "hooks",
37559
+ harnessHints: [
37560
+ "claude"
37561
+ ],
37562
+ hookPlatform: "claude"
37563
+ },
37564
+ {
37565
+ id: "hook-claude-settings-local",
37566
+ path: ".claude/settings.local.json",
37567
+ matchKind: "exact",
37568
+ primaryConstruct: "hook",
37569
+ lintTarget: "hooks",
37570
+ harnessHints: [
37571
+ "claude"
37572
+ ],
37573
+ hookPlatform: "claude"
37574
+ },
37575
+ // Doctor-only hook directory prefixes
37576
+ {
37577
+ id: "hook-github-dir",
37578
+ path: ".github/hooks",
37579
+ matchKind: "directory-prefix",
37580
+ primaryConstruct: "hook",
37581
+ lintTarget: "none",
37582
+ harnessHints: [
37583
+ "copilot"
37584
+ ]
37585
+ },
37586
+ {
37587
+ id: "hook-claude-dir",
37588
+ path: ".claude/hooks",
37589
+ matchKind: "directory-prefix",
37590
+ primaryConstruct: "hook",
37591
+ lintTarget: "none",
37592
+ harnessHints: [
37593
+ "claude"
37594
+ ]
37595
+ },
37596
+ // Instruction lint locations
37597
+ {
37598
+ id: "instruction-copilot-root",
37599
+ path: ".github/copilot-instructions.md",
37600
+ matchKind: "exact",
37601
+ primaryConstruct: "instruction",
37602
+ lintTarget: "instructions",
37603
+ harnessHints: [
37604
+ "copilot"
37605
+ ],
37606
+ instructionFormat: "copilot-instructions"
37607
+ },
37608
+ {
37609
+ id: "instruction-copilot-scoped",
37610
+ path: ".github/instructions",
37611
+ matchKind: "directory-prefix",
37612
+ primaryConstruct: "instruction",
37613
+ lintTarget: "instructions",
37614
+ harnessHints: [
37615
+ "copilot"
37616
+ ],
37617
+ instructionFormat: "copilot-scoped"
37618
+ },
37619
+ {
37620
+ id: "instruction-agents-md",
37621
+ path: "AGENTS.md",
37622
+ matchKind: "exact",
37623
+ primaryConstruct: "instruction",
37624
+ lintTarget: "instructions",
37625
+ harnessHints: [
37626
+ "shared"
37627
+ ],
37628
+ instructionFormat: "agents-md"
37629
+ },
37630
+ {
37631
+ id: "instruction-claude-md",
37632
+ path: "CLAUDE.md",
37633
+ matchKind: "exact",
37634
+ primaryConstruct: "instruction",
37635
+ lintTarget: "instructions",
37636
+ harnessHints: [
37637
+ "claude"
37638
+ ],
37639
+ instructionFormat: "claude-md"
37640
+ },
37641
+ // Doctor-only construct locations
37642
+ {
37643
+ id: "subagent-claude",
37644
+ path: ".claude/agents",
37645
+ matchKind: "directory-prefix",
37646
+ primaryConstruct: "subagent",
37647
+ lintTarget: "none",
37648
+ harnessHints: [
37649
+ "claude"
37650
+ ]
37651
+ },
37652
+ {
37653
+ id: "agent-claude-commands",
37654
+ path: ".claude/commands",
37655
+ matchKind: "directory-prefix",
37656
+ primaryConstruct: "agent",
37657
+ lintTarget: "none",
37658
+ harnessHints: [
37659
+ "claude"
37660
+ ]
37661
+ },
37662
+ {
37663
+ id: "plugin-codex",
37664
+ path: ".codex-plugin",
37665
+ matchKind: "directory-prefix",
37666
+ primaryConstruct: "plugin",
37667
+ lintTarget: "none",
37668
+ harnessHints: [
37669
+ "codex"
37670
+ ]
37671
+ }
37672
+ ];
37673
+
37674
+ ;// CONCATENATED MODULE: ../core/src/lib/agentic-location-matchers.ts
37675
+ /**
37676
+ * Pure path→construct matching helpers over the agentic location catalog.
37677
+ * No filesystem I/O.
37678
+ */
37679
+ /**
37680
+ * Normalizes a repo-relative path for catalog matching.
37681
+ * Collapses `.` / `..` segments. Returns "" when the path is absolute or
37682
+ * escapes the repository root — callers treat "" as non-matching.
37683
+ */ function normalizeRepoRelativePath(path) {
37684
+ const normalized = path.replaceAll("\\", "/");
37685
+ // POSIX absolute, UNC-style leading slash after backslash conversion,
37686
+ // and Windows drive-letter absolute (C:/..., d:\...).
37687
+ if (normalized.startsWith("/") || /^[A-Za-z]:(\/|$)/.test(normalized)) {
37688
+ return "";
37689
+ }
37690
+ const resolved = [];
37691
+ for (const segment of normalized.split("/")){
37692
+ if (segment === "" || segment === ".") {
37693
+ continue;
37694
+ }
37695
+ if (segment === "..") {
37696
+ if (resolved.length === 0) {
37697
+ return "";
37698
+ }
37699
+ resolved.pop();
37700
+ continue;
37701
+ }
37702
+ resolved.push(segment);
37703
+ }
37704
+ return resolved.join("/");
37705
+ }
37706
+ function matchesLocationEntry(path, entry) {
37707
+ const normalized = normalizeRepoRelativePath(path);
37708
+ if (entry.matchKind === "exact") {
37709
+ return normalized === entry.path;
37710
+ }
37711
+ return normalized === entry.path || normalized.startsWith(`${entry.path}/`);
37712
+ }
37713
+ function entriesMatchingPath(path, catalog = AGENTIC_LOCATION_CATALOG) {
37714
+ return catalog.filter((entry)=>matchesLocationEntry(path, entry));
37715
+ }
37716
+ function specificityScore(entry) {
37717
+ // Exact matches outrank any prefix; longer prefixes outrank shorter ones.
37718
+ const kindBonus = entry.matchKind === "exact" ? 1_000_000 : 0;
37719
+ return kindBonus + entry.path.length;
37720
+ }
37721
+ function bestMatchingEntry(path, catalog = AGENTIC_LOCATION_CATALOG) {
37722
+ const matches = entriesMatchingPath(path, catalog);
37723
+ if (matches.length === 0) {
37724
+ return null;
37725
+ }
37726
+ let best = matches[0];
37727
+ let bestScore = specificityScore(best);
37728
+ for(let i = 1; i < matches.length; i++){
37729
+ const candidate = matches[i];
37730
+ const score = specificityScore(candidate);
37731
+ if (score > bestScore) {
37732
+ best = candidate;
37733
+ bestScore = score;
37734
+ }
37735
+ }
37736
+ return best;
37737
+ }
37738
+ function primaryConstructTypeForPath(path, catalog = AGENTIC_LOCATION_CATALOG) {
37739
+ return bestMatchingEntry(path, catalog)?.primaryConstruct ?? null;
37740
+ }
37741
+ function constructTypesForPath(path, catalog = AGENTIC_LOCATION_CATALOG) {
37742
+ const best = bestMatchingEntry(path, catalog);
37743
+ if (!best) {
37744
+ return [];
37745
+ }
37746
+ if (best.secondaryConstructs && best.secondaryConstructs.length > 0) {
37747
+ return [
37748
+ best.primaryConstruct,
37749
+ ...best.secondaryConstructs
37750
+ ];
37751
+ }
37752
+ return [
37753
+ best.primaryConstruct
37754
+ ];
37755
+ }
37756
+ function lintTargetEntries(target, catalog = agentic_location_catalog_AGENTIC_LOCATION_CATALOG) {
37757
+ return catalog.filter((entry)=>entry.lintTarget === target);
37758
+ }
37759
+ function skillDirectoryRoots(catalog = agentic_location_catalog_AGENTIC_LOCATION_CATALOG) {
37760
+ return lintTargetEntries("skills", catalog).filter((entry)=>entry.matchKind === "directory-prefix").map((entry)=>entry.path);
37761
+ }
37762
+ function agentDirectoryRoots(catalog = AGENTIC_LOCATION_CATALOG) {
37763
+ return lintTargetEntries("agents", catalog).filter((entry)=>entry.matchKind === "directory-prefix").map((entry)=>entry.path);
37764
+ }
37765
+ function hookConfigPaths(catalog = AGENTIC_LOCATION_CATALOG) {
37766
+ return lintTargetEntries("hooks", catalog).filter((entry)=>entry.matchKind === "exact" && entry.hookPlatform != null).map((entry)=>({
37767
+ relativePath: entry.path,
37768
+ platform: entry.hookPlatform
37769
+ }));
37770
+ }
37771
+ function instructionDiscoveryEntries(catalog = agentic_location_catalog_AGENTIC_LOCATION_CATALOG) {
37772
+ return catalog.filter((entry)=>entry.instructionFormat != null);
37773
+ }
37774
+
37469
37775
  ;// CONCATENATED MODULE: ../core/src/gateways/skill-lint-gateway.ts
37470
37776
  /**
37471
37777
  * Gateway for skill lint file system operations.
@@ -37474,14 +37780,9 @@ const PackageJsonSchema = schemas_object({
37474
37780
 
37475
37781
 
37476
37782
 
37783
+
37477
37784
  /** Maximum skill file size: 1 MB */ const MAX_SKILL_FILE_BYTES = 1_048_576;
37478
- /**
37479
- * Skill directory locations to search for SKILL.md files.
37480
- */ const SKILL_DIRECTORIES = [
37481
- (0,external_node_path_.join)(".github", "skills"),
37482
- (0,external_node_path_.join)(".claude", "skills"),
37483
- (0,external_node_path_.join)(".agents", "skills")
37484
- ];
37785
+ /** Catalog skill roots converted to OS-native relative paths. */ const SKILL_DIRECTORIES = skillDirectoryRoots().map((root)=>(0,external_node_path_.join)(...root.split("/")));
37485
37786
  /** Maximum lock file size: 256 KB */ const MAX_LOCK_FILE_BYTES = 262_144;
37486
37787
  /** Relative path to the skills lock file. */ const SKILLS_LOCK_PATH = "skills-lock.json";
37487
37788
  /** Zod schema for skills-lock.json structure */ const SkillsLockSchema = schemas_object({
@@ -38149,40 +38450,28 @@ function createWorkflowGateway(cwd) {
38149
38450
  * Supports GitHub Copilot, Claude Code, and community agent instruction formats.
38150
38451
  */
38151
38452
 
38453
+
38152
38454
  /**
38153
38455
  * File system implementation of the instruction file discovery gateway.
38154
38456
  */ class FileSystemInstructionFileDiscoveryGateway {
38155
38457
  async discoverInstructionFiles(targetDir) {
38156
38458
  const files = [];
38157
- // .github/copilot-instructions.md
38158
- const copilotInstructions = (0,external_node_path_.join)(".github", "copilot-instructions.md");
38159
- if (await this.safePathExists(targetDir, copilotInstructions)) {
38160
- files.push({
38161
- filePath: (0,external_node_path_.join)(targetDir, copilotInstructions),
38162
- format: "copilot-instructions"
38163
- });
38164
- }
38165
- // .github/instructions/*.md
38166
- const instructionsDir = (0,external_node_path_.join)(".github", "instructions");
38167
- await this.discoverMdFilesInDir(targetDir, instructionsDir, "copilot-scoped", files);
38168
- // .github/agents/*.md
38169
- const agentsDir = (0,external_node_path_.join)(".github", "agents");
38170
- await this.discoverMdFilesInDir(targetDir, agentsDir, "copilot-agent", files);
38171
- // AGENTS.md at repo root
38172
- const agentsMd = "AGENTS.md";
38173
- if (await this.safePathExists(targetDir, agentsMd)) {
38174
- files.push({
38175
- filePath: (0,external_node_path_.join)(targetDir, agentsMd),
38176
- format: "agents-md"
38177
- });
38178
- }
38179
- // CLAUDE.md at repo root
38180
- const claudeMd = "CLAUDE.md";
38181
- if (await this.safePathExists(targetDir, claudeMd)) {
38182
- files.push({
38183
- filePath: (0,external_node_path_.join)(targetDir, claudeMd),
38184
- format: "claude-md"
38185
- });
38459
+ for (const entry of instructionDiscoveryEntries()){
38460
+ const format = entry.instructionFormat;
38461
+ if (format == null) {
38462
+ continue;
38463
+ }
38464
+ const relativePath = (0,external_node_path_.join)(...entry.path.split("/"));
38465
+ if (entry.matchKind === "exact") {
38466
+ if (await this.safePathExists(targetDir, relativePath)) {
38467
+ files.push({
38468
+ filePath: (0,external_node_path_.join)(targetDir, relativePath),
38469
+ format
38470
+ });
38471
+ }
38472
+ continue;
38473
+ }
38474
+ await this.discoverMdFilesInDir(targetDir, relativePath, format, files);
38186
38475
  }
38187
38476
  return files;
38188
38477
  }
@@ -59889,7 +60178,12 @@ function normalize (uri, options) {
59889
60178
  */
59890
60179
  function resolve (baseURI, relativeURI, options) {
59891
60180
  const schemelessOptions = options ? Object.assign({ scheme: 'null' }, options) : { scheme: 'null' }
59892
- const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true)
60181
+ const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions)
60182
+ const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions)
60183
+ if (baseMalformed || relativeMalformed) {
60184
+ throw new Error(baseParsed.error || relativeParsed.error || 'URI is malformed.')
60185
+ }
60186
+ const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true)
59893
60187
  schemelessOptions.skipEscape = true
59894
60188
  return serialize(resolved, schemelessOptions)
59895
60189
  }
@@ -60069,6 +60363,15 @@ const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:
60069
60363
  // with or without a scheme prefix, for the literal-backslash rejection below.
60070
60364
  const AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/
60071
60365
 
60366
+ // Captures the leading authority-introducer region after an optional scheme: a
60367
+ // run of forward slashes, backslashes, and the characters the WHATWG URL parser
60368
+ // removes before parsing (TAB U+0009, LF U+000A, CR U+000D). A valid introducer
60369
+ // is exactly "//". Node treats "\" as "/" on special schemes and strips those
60370
+ // characters first, so forms like "\\", "/\", "\/", "/<TAB>/", or a leading
60371
+ // "<TAB>//" reach an authority in Node while fast-uri's URI_PARSE folds them into
60372
+ // the path group (host confusion / SSRF / redirect bypass).
60373
+ const AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/
60374
+
60072
60375
  /**
60073
60376
  * @param {import('./types/index').URIComponent} parsed
60074
60377
  * @param {RegExpMatchArray} matches
@@ -60128,6 +60431,28 @@ function parseWithStatus (uri, opts) {
60128
60431
  malformedAuthorityOrPort = true
60129
60432
  }
60130
60433
 
60434
+ // Reject a malformed or whitespace-smuggled authority introducer. fast-uri
60435
+ // only recognizes a literal "//"; anything else in the leading separator run
60436
+ // (a backslash, or a "//" that appears only after removing the TAB/LF/CR that
60437
+ // Node strips) means the authority fast-uri parses differs from the one Node's
60438
+ // URL resolves. Reject rather than rewrite, mirroring the literal-backslash
60439
+ // guard above. Percent-encoded forms (%5C, %09) are untouched, valid data.
60440
+ const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION)
60441
+ if (introducerMatch !== null) {
60442
+ const region = introducerMatch[1]
60443
+ const normalizedRegion = region.replace(/[\t\n\r]/g, '')
60444
+ // Two or more leading separators introduce an authority.
60445
+ if (normalizedRegion.length >= 2) {
60446
+ if (normalizedRegion.slice(0, 2) !== '//') {
60447
+ parsed.error = parsed.error || 'URI authority must not contain a literal backslash.'
60448
+ malformedAuthorityOrPort = true
60449
+ } else if (region.length !== normalizedRegion.length) {
60450
+ parsed.error = parsed.error || 'URI authority introducer must not contain whitespace.'
60451
+ malformedAuthorityOrPort = true
60452
+ }
60453
+ }
60454
+ }
60455
+
60131
60456
  const matches = uri.match(URI_PARSE)
60132
60457
 
60133
60458
  if (matches) {
@@ -69568,4 +69893,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
69568
69893
  // module factories are used so entry inlining is disabled
69569
69894
  // startup
69570
69895
  // Load entry module and return exports
69571
- var __webpack_exports__ = __webpack_require__(1895);
69896
+ var __webpack_exports__ = __webpack_require__(8454);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/mcp",
3
- "version": "5.17.15",
3
+ "version": "5.18.0",
4
4
  "description": "MCP server for lousy-agents - provides AI coding assistant tools via the Model Context Protocol",
5
5
  "type": "module",
6
6
  "repository": {