@el-j/magic-helix-plugins 4.0.0-beta.7 → 4.0.0-beta.8

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.
@@ -1,21 +1,22 @@
1
- import * as s from "node:fs";
2
- import * as a from "node:path";
3
- class l {
1
+ import * as n from "node:fs";
2
+ import * as s from "node:path";
3
+ import { fileURLToPath as c } from "node:url";
4
+ class u {
4
5
  // Helper methods for common operations
5
6
  /**
6
7
  * Check if a file exists in the project
7
8
  */
8
9
  fileExists(e, r) {
9
- return s.existsSync(a.join(e, r));
10
+ return n.existsSync(s.join(e, r));
10
11
  }
11
12
  /**
12
13
  * Read a file from the project
13
14
  */
14
15
  readFile(e, r) {
15
16
  try {
16
- const t = a.join(e, r);
17
- if (s.existsSync(t))
18
- return s.readFileSync(t, "utf-8");
17
+ const t = s.join(e, r);
18
+ if (n.existsSync(t))
19
+ return n.readFileSync(t, "utf-8");
19
20
  } catch {
20
21
  }
21
22
  return null;
@@ -36,15 +37,31 @@ class l {
36
37
  * Get project name from path
37
38
  */
38
39
  getProjectName(e) {
39
- return a.basename(e);
40
+ return s.basename(e);
41
+ }
42
+ /**
43
+ * List entries in a project directory (non-recursive)
44
+ */
45
+ listFiles(e) {
46
+ try {
47
+ return n.readdirSync(e);
48
+ } catch {
49
+ return [];
50
+ }
51
+ }
52
+ /**
53
+ * Get the directory name from import.meta.url (ES module alternative to __dirname)
54
+ */
55
+ getDirname(e) {
56
+ return s.dirname(c(e));
40
57
  }
41
58
  /**
42
59
  * Load template from file
43
60
  */
44
61
  async loadTemplateFromFile(e) {
45
62
  try {
46
- if (s.existsSync(e))
47
- return s.readFileSync(e, "utf-8");
63
+ if (n.existsSync(e))
64
+ return n.readFileSync(e, "utf-8");
48
65
  } catch {
49
66
  }
50
67
  return null;
@@ -52,12 +69,12 @@ class l {
52
69
  /**
53
70
  * Create a template definition with lazy loading
54
71
  */
55
- createTemplate(e, r, t, n = {}) {
72
+ createTemplate(e, r, t, i = {}) {
56
73
  return {
57
74
  name: e,
58
75
  tags: r,
59
76
  content: t,
60
- ...n
77
+ ...i
61
78
  };
62
79
  }
63
80
  /**
@@ -65,9 +82,9 @@ class l {
65
82
  */
66
83
  parseDependencies(e, ...r) {
67
84
  const t = {};
68
- for (const n of r) {
69
- const i = e[n];
70
- i && typeof i == "object" && Object.assign(t, i);
85
+ for (const i of r) {
86
+ const a = e[i];
87
+ a && typeof a == "object" && Object.assign(t, a);
71
88
  }
72
89
  return t;
73
90
  }
@@ -93,5 +110,5 @@ class l {
93
110
  }
94
111
  }
95
112
  export {
96
- l as B
113
+ u as B
97
114
  };
@@ -0,0 +1 @@
1
+ "use strict";var o=Object.create;var l=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var g=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of d(e))!p.call(n,s)&&s!==t&&l(n,s,{get:()=>e[s],enumerable:!(r=f(e,s))||r.enumerable});return n};var m=(n,e,t)=>(t=n!=null?o(y(n)):{},g(e||!n||!n.__esModule?l(t,"default",{value:n,enumerable:!0}):t,n));const b=require("node:fs"),h=require("node:path"),F=require("node:url");function u(n){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const i=u(b),a=u(h);class S{fileExists(e,t){return i.existsSync(a.join(e,t))}readFile(e,t){try{const r=a.join(e,t);if(i.existsSync(r))return i.readFileSync(r,"utf-8")}catch{}return null}readJSON(e,t){try{const r=this.readFile(e,t);if(r)return JSON.parse(r)}catch{}return null}getProjectName(e){return a.basename(e)}listFiles(e){try{return i.readdirSync(e)}catch{return[]}}getDirname(e){return a.dirname(F.fileURLToPath(e))}async loadTemplateFromFile(e){try{if(i.existsSync(e))return i.readFileSync(e,"utf-8")}catch{}return null}createTemplate(e,t,r,s={}){return{name:e,tags:t,content:r,...s}}parseDependencies(e,...t){const r={};for(const s of t){const c=e[s];c&&typeof c=="object"&&Object.assign(r,c)}return r}async findFiles(e,t){try{const{glob:r}=await import("glob");return await r(t,{cwd:e,absolute:!1})}catch{return[]}}async hasFiles(e,t){return(await this.findFiles(e,t)).length>0}}exports.BasePlugin=S;
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("../BasePlugin-odQJAKA-.cjs");class m extends u.BasePlugin{constructor(){super(...arguments),this.name="cpp",this.displayName="C/C++",this.version="3.0.0",this.priority=85}async detect(t){const i=[],s={};let r,o=this.getProjectName(t);const e=await this.detectPlatformIO(t);if(e&&(i.push("platformio"),r="platformio.ini",e.board&&i.push(`board-${e.board}`),e.platform&&(i.push(`platform-${e.platform}`),e.platform.includes("espressif32")&&i.push("esp32"),e.platform.includes("espressif8266")&&i.push("esp8266"),e.platform.includes("atmelavr")&&i.push("arduino")),e.framework&&(i.push(`framework-${e.framework}`),e.framework==="arduino"&&i.push("arduino")),e.libs))for(const a of e.libs)s[a]="*";if(this.fileExists(t,"CMakeLists.txt")){i.push("cmake"),r||(r="CMakeLists.txt");const a=this.readFile(t,"CMakeLists.txt");if(a){const c=a.match(/project\s*\(\s*([^\s)]+)/i);c&&(o=c[1])}}return(this.fileExists(t,"Makefile")||this.fileExists(t,"makefile"))&&(i.push("makefile"),r||(r="Makefile")),await this.hasFiles(t,"*.ino")&&(i.push("arduino"),r||(r="*.ino")),await this.hasFiles(t,"**/*.{cpp,c,h,hpp}")&&(i.push("cpp"),r||(r="*.cpp")),i.length===0?null:{language:"C/C++",name:o,dependencies:s,manifestFile:r,projectPath:t,tags:i}}async detectPlatformIO(t){if(!this.fileExists(t,"platformio.ini"))return null;const i=this.readFile(t,"platformio.ini");if(!i)return null;const s={libs:[]},r=i.split(`
2
- `);let o=!1,e=null;for(const p of r){const n=p.trim();if(n.startsWith("[env:")){o=!0,e=null;continue}if(n.startsWith("[")&&n.endsWith("]")){o=!1,e=null;continue}if(o||!s.board){const l=n.match(/^(\w+)\s*=\s*(.*)$/);if(l){const[,f,a]=l;switch(e=f,f){case"board":s.board=a.trim();break;case"platform":s.platform=a.trim();break;case"framework":s.framework=a.trim();break;case"lib_deps":a.trim()&&s.libs?.push(a.trim());break}}else e==="lib_deps"&&n&&!n.startsWith("[")&&s.libs?.push(n)}}return s.board||s.platform?s:null}getTemplates(){return[{name:"cpp-core",tags:["cpp"],content:this.getCppTemplate()},{name:"platformio-core",tags:["platformio"],content:this.getPlatformIOTemplate()},{name:"arduino-core",tags:["arduino"],content:this.getArduinoTemplate()}]}getDependencyTagMap(){return{boost:"boost",fmt:"fmt",spdlog:"spdlog",googletest:"gtest",catch2:"catch2","Adafruit GFX Library":"adafruit-gfx",WiFi:"wifi",ESP32:"esp32",FastLED:"fastled",ArduinoJson:"arduino-json"}}getConfigFileTagMap(){return{"platformio.ini":"platformio","CMakeLists.txt":"cmake",Makefile:"makefile",".clang-format":"clang-format",".clang-tidy":"clang-tidy"}}getCppTemplate(){return`# C/C++ Development Guidelines
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("../BasePlugin-Be6rLq9o.cjs");var p=typeof document<"u"?document.currentScript:null;class d extends m.BasePlugin{constructor(){super(...arguments),this.name="cpp",this.displayName="C/C++",this.version="3.0.0",this.priority=85}async detect(t){const i=[],r={};let s,o=this.getProjectName(t);const e=await this.detectPlatformIO(t);if(e&&(i.push("platformio"),s="platformio.ini",e.board&&i.push(`board-${e.board}`),e.platform&&(i.push(`platform-${e.platform}`),e.platform.includes("espressif32")&&i.push("esp32"),e.platform.includes("espressif8266")&&i.push("esp8266"),e.platform.includes("atmelavr")&&i.push("arduino")),e.framework&&(i.push(`framework-${e.framework}`),e.framework==="arduino"&&i.push("arduino")),e.libs))for(const n of e.libs)r[n]="*";if(this.fileExists(t,"CMakeLists.txt")){i.push("cmake"),s||(s="CMakeLists.txt");const n=this.readFile(t,"CMakeLists.txt");if(n){const u=n.match(/project\s*\(\s*([^\s)]+)/i);u&&(o=u[1])}}return(this.fileExists(t,"Makefile")||this.fileExists(t,"makefile"))&&(i.push("makefile"),s||(s="Makefile")),await this.hasFiles(t,"*.ino")&&(i.push("arduino"),s||(s="*.ino")),await this.hasFiles(t,"**/*.{cpp,c,h,hpp}")&&(i.push("cpp"),s||(s="*.cpp")),i.length===0?null:{language:"C/C++",name:o,dependencies:r,manifestFile:s,projectPath:t,tags:i}}async detectPlatformIO(t){if(!this.fileExists(t,"platformio.ini"))return null;const i=this.readFile(t,"platformio.ini");if(!i)return null;const r={libs:[]},s=i.split(`
2
+ `);let o=!1,e=null;for(const f of s){const a=f.trim();if(a.startsWith("[env:")){o=!0,e=null;continue}if(a.startsWith("[")&&a.endsWith("]")){o=!1,e=null;continue}if(o||!r.board){const l=a.match(/^(\w+)\s*=\s*(.*)$/);if(l){const[,c,n]=l;switch(e=c,c){case"board":r.board=n.trim();break;case"platform":r.platform=n.trim();break;case"framework":r.framework=n.trim();break;case"lib_deps":n.trim()&&r.libs?.push(n.trim());break}}else e==="lib_deps"&&a&&!a.startsWith("[")&&r.libs?.push(a)}}return r.board||r.platform?r:null}getTemplates(){return this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:p&&p.tagName.toUpperCase()==="SCRIPT"&&p.src||new URL("cpp/index.cjs",document.baseURI).href),[{name:"cpp-core",tags:["cpp"],content:this.getCppTemplate()},{name:"platformio-core",tags:["platformio"],content:this.getPlatformIOTemplate()},{name:"arduino-core",tags:["arduino"],content:this.getArduinoTemplate()}]}getDependencyTagMap(){return{boost:"boost",fmt:"fmt",spdlog:"spdlog",googletest:"gtest",catch2:"catch2","Adafruit GFX Library":"adafruit-gfx",WiFi:"wifi",ESP32:"esp32",FastLED:"fastled",ArduinoJson:"arduino-json"}}getConfigFileTagMap(){return{"platformio.ini":"platformio","CMakeLists.txt":"cmake",Makefile:"makefile",".clang-format":"clang-format",".clang-tidy":"clang-tidy"}}getCppTemplate(){return`# C/C++ Development Guidelines
3
3
 
4
4
  This project uses C/C++.
5
5
 
@@ -76,4 +76,4 @@ This is an Arduino project.
76
76
  - Check Serial Monitor baud rate
77
77
  - Validate sensor readings
78
78
  - Test incrementally
79
- `}}exports.CppPlugin=m;
79
+ `}}exports.CppPlugin=d;
@@ -1,4 +1,4 @@
1
- import { B as u } from "../BasePlugin-6wv0hYJ9.js";
1
+ import { B as u } from "../BasePlugin-BXz3Zpy5.js";
2
2
  class g extends u {
3
3
  constructor() {
4
4
  super(...arguments), this.name = "cpp", this.displayName = "C/C++", this.version = "3.0.0", this.priority = 85;
@@ -74,7 +74,7 @@ class g extends u {
74
74
  return s.board || s.platform ? s : null;
75
75
  }
76
76
  getTemplates() {
77
- return [
77
+ return this.getDirname(import.meta.url), [
78
78
  {
79
79
  name: "cpp-core",
80
80
  tags: ["cpp"],
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("node:path"),p=require("../BasePlugin-odQJAKA-.cjs");function l(n){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const a=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,a.get?a:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const u=l(c);class g extends p.BasePlugin{constructor(){super(...arguments),this.name="csharp",this.displayName="C#",this.version="3.0.0",this.priority=60}async detect(e){const t=await this.findFiles(e,"*.csproj");if(t.length===0)return null;const a=t[0],s=this.readFile(e,a),r={};if(s){const o=s.matchAll(/<PackageReference\s+Include="([^"]+)"(?:\s+Version="([^"]+)")?/g);for(const i of o)r[i[1]]=i[2]||"*"}return{language:"C#",name:a.replace(".csproj",""),dependencies:r,manifestFile:a,projectPath:e}}getTemplates(){return[{name:"csharp-core",tags:["csharp","dotnet"],content:()=>this.loadTemplateFromFile(u.join(__dirname,"templates/lang-csharp.md")).then(e=>e||this.getCSharpFallbackTemplate())}]}getCSharpFallbackTemplate(){return`# C# / .NET Development Guidelines
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("node:path"),l=require("../BasePlugin-Be6rLq9o.cjs");var a=typeof document<"u"?document.currentScript:null;function u(n){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const d=u(p);class g extends l.BasePlugin{constructor(){super(...arguments),this.name="csharp",this.displayName="C#",this.version="3.0.0",this.priority=60}async detect(e){const t=await this.findFiles(e,"*.csproj");if(t.length===0)return null;const r=t[0],s=this.readFile(e,r),i={};if(s){const o=s.matchAll(/<PackageReference\s+Include="([^"]+)"(?:\s+Version="([^"]+)")?/g);for(const c of o)i[c[1]]=c[2]||"*"}return{language:"C#",name:r.replace(".csproj",""),dependencies:i,manifestFile:r,projectPath:e}}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:a&&a.tagName.toUpperCase()==="SCRIPT"&&a.src||new URL("csharp/index.cjs",document.baseURI).href);return[{name:"csharp-core",tags:["csharp","dotnet"],content:()=>this.loadTemplateFromFile(d.join(e,"templates/lang-csharp.md")).then(t=>t||this.getCSharpFallbackTemplate())}]}getCSharpFallbackTemplate(){return`# C# / .NET Development Guidelines
2
2
 
3
3
  This project uses C# and .NET.
4
4
 
@@ -1,14 +1,14 @@
1
1
  import * as o from "node:path";
2
- import { B as p } from "../BasePlugin-6wv0hYJ9.js";
3
- class g extends p {
2
+ import { B as p } from "../BasePlugin-BXz3Zpy5.js";
3
+ class m extends p {
4
4
  constructor() {
5
5
  super(...arguments), this.name = "csharp", this.displayName = "C#", this.version = "3.0.0", this.priority = 60;
6
6
  }
7
7
  async detect(e) {
8
- const s = await this.findFiles(e, "*.csproj");
9
- if (s.length === 0)
8
+ const t = await this.findFiles(e, "*.csproj");
9
+ if (t.length === 0)
10
10
  return null;
11
- const t = s[0], n = this.readFile(e, t), a = {};
11
+ const s = t[0], n = this.readFile(e, s), a = {};
12
12
  if (n) {
13
13
  const i = n.matchAll(
14
14
  /<PackageReference\s+Include="([^"]+)"(?:\s+Version="([^"]+)")?/g
@@ -18,20 +18,21 @@ class g extends p {
18
18
  }
19
19
  return {
20
20
  language: "C#",
21
- name: t.replace(".csproj", ""),
21
+ name: s.replace(".csproj", ""),
22
22
  dependencies: a,
23
- manifestFile: t,
23
+ manifestFile: s,
24
24
  projectPath: e
25
25
  };
26
26
  }
27
27
  getTemplates() {
28
+ const e = this.getDirname(import.meta.url);
28
29
  return [
29
30
  {
30
31
  name: "csharp-core",
31
32
  tags: ["csharp", "dotnet"],
32
33
  content: () => this.loadTemplateFromFile(
33
- o.join(__dirname, "templates/lang-csharp.md")
34
- ).then((e) => e || this.getCSharpFallbackTemplate())
34
+ o.join(e, "templates/lang-csharp.md")
35
+ ).then((t) => t || this.getCSharpFallbackTemplate())
35
36
  }
36
37
  ];
37
38
  }
@@ -64,5 +65,5 @@ This project uses C# and .NET.
64
65
  }
65
66
  }
66
67
  export {
67
- g as CSharpPlugin
68
+ m as CSharpPlugin
68
69
  };
package/dist/go/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("node:path"),g=require("../BasePlugin-odQJAKA-.cjs");function m(o){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(o){for(const t in o)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(o,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:()=>o[t]})}}return e.default=o,Object.freeze(e)}const u=m(c);class d extends g.BasePlugin{constructor(){super(...arguments),this.name="go",this.displayName="Go",this.version="3.0.0",this.priority=90}async detect(e){if(!this.fileExists(e,"go.mod"))return null;const t=this.readFile(e,"go.mod");if(!t)return{language:"Go",name:this.getProjectName(e),dependencies:{},manifestFile:"go.mod",projectPath:e};const s=t.match(/module\s+([^\s\n]+)/),r={},l=t.split(`
2
- `);let a=!1;for(const i of l){if(i.trim().startsWith("require (")){a=!0;continue}if(a){if(i.trim()===")")break;const n=i.match(/^\s*([^\s]+)\s+v([^\s]+)/);n&&(r[n[1]]=n[2])}else if(i.trim().startsWith("require ")){const n=i.match(/require\s+([^\s]+)\s+v([^\s]+)/);n&&(r[n[1]]=n[2])}}return{language:"Go",name:s?.[1]||this.getProjectName(e),dependencies:r,manifestFile:"go.mod",projectPath:e}}getTemplates(){return[{name:"go-core",tags:["go"],content:()=>this.loadTemplateFromFile(u.join(__dirname,"templates/lang-go.md")).then(e=>e||this.getGoFallbackTemplate())}]}getDependencyTagMap(){return{"github.com/gin-gonic/gin":"gin","github.com/gofiber/fiber":"fiber","github.com/labstack/echo":"echo","gorm.io/gorm":"gorm"}}getGoFallbackTemplate(){return`# Go Development Guidelines
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("node:path"),d=require("../BasePlugin-Be6rLq9o.cjs");var c=typeof document<"u"?document.currentScript:null;function u(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const f=u(m);class p extends d.BasePlugin{constructor(){super(...arguments),this.name="go",this.displayName="Go",this.version="3.0.0",this.priority=90}async detect(e){if(!this.fileExists(e,"go.mod"))return null;const t=this.readFile(e,"go.mod");if(!t){const i=await this.enrichTags(e,{});return{language:"Go",name:this.getProjectName(e),dependencies:{},manifestFile:"go.mod",projectPath:e,tags:Array.from(i)}}const n=t.match(/module\s+([^\s\n]+)/),o={},a=t.split(`
2
+ `);let g=!1;for(const i of a){if(i.trim().startsWith("require (")){g=!0;continue}if(g){if(i.trim()===")")break;const r=i.match(/^\s*([^\s]+)\s+v([^\s]+)/);r&&(o[r[1]]=r[2])}else if(i.trim().startsWith("require ")){const r=i.match(/require\s+([^\s]+)\s+v([^\s]+)/);r&&(o[r[1]]=r[2])}}const l=await this.enrichTags(e,o);return{language:"Go",name:n?.[1]||this.getProjectName(e),dependencies:o,manifestFile:"go.mod",projectPath:e,tags:Array.from(l)}}async enrichTags(e,t){const n=new Set(["go"]),o=this.getDependencyTagMap();for(const a in t)o[a]&&n.add(o[a]);return n}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:c&&c.tagName.toUpperCase()==="SCRIPT"&&c.src||new URL("go/index.cjs",document.baseURI).href);return[{name:"go-core",tags:["go"],content:()=>this.loadTemplateFromFile(f.join(e,"templates/lang-go.md")).then(t=>t||this.getGoFallbackTemplate())}]}getDependencyTagMap(){return{"github.com/gin-gonic/gin":"gin","github.com/gofiber/fiber":"fiber","github.com/labstack/echo":"echo","gorm.io/gorm":"gorm"}}getGoFallbackTemplate(){return`# Go Development Guidelines
3
3
 
4
4
  This project uses Go.
5
5
 
@@ -26,4 +26,4 @@ This project uses Go.
26
26
  ## Dependencies
27
27
  - Use Go modules (\`go.mod\`)
28
28
  - Keep dependencies minimal
29
- - Review dependency licenses`}}exports.GoPlugin=d;
29
+ - Review dependency licenses`}}exports.GoPlugin=p;
package/dist/go/index.mjs CHANGED
@@ -1,54 +1,69 @@
1
1
  import * as m from "node:path";
2
- import { B as g } from "../BasePlugin-6wv0hYJ9.js";
3
- class d extends g {
2
+ import { B as c } from "../BasePlugin-BXz3Zpy5.js";
3
+ class u extends c {
4
4
  constructor() {
5
5
  super(...arguments), this.name = "go", this.displayName = "Go", this.version = "3.0.0", this.priority = 90;
6
6
  }
7
7
  async detect(e) {
8
8
  if (!this.fileExists(e, "go.mod"))
9
9
  return null;
10
- const i = this.readFile(e, "go.mod");
11
- if (!i)
10
+ const t = this.readFile(e, "go.mod");
11
+ if (!t) {
12
+ const i = await this.enrichTags(e, {});
12
13
  return {
13
14
  language: "Go",
14
15
  name: this.getProjectName(e),
15
16
  dependencies: {},
16
17
  manifestFile: "go.mod",
17
- projectPath: e
18
+ projectPath: e,
19
+ tags: Array.from(i)
18
20
  };
19
- const r = i.match(/module\s+([^\s\n]+)/), n = {}, a = i.split(`
21
+ }
22
+ const o = t.match(/module\s+([^\s\n]+)/), s = {}, r = t.split(`
20
23
  `);
21
- let s = !1;
22
- for (const o of a) {
23
- if (o.trim().startsWith("require (")) {
24
- s = !0;
24
+ let a = !1;
25
+ for (const i of r) {
26
+ if (i.trim().startsWith("require (")) {
27
+ a = !0;
25
28
  continue;
26
29
  }
27
- if (s) {
28
- if (o.trim() === ")") break;
29
- const t = o.match(/^\s*([^\s]+)\s+v([^\s]+)/);
30
- t && (n[t[1]] = t[2]);
31
- } else if (o.trim().startsWith("require ")) {
32
- const t = o.match(/require\s+([^\s]+)\s+v([^\s]+)/);
33
- t && (n[t[1]] = t[2]);
30
+ if (a) {
31
+ if (i.trim() === ")") break;
32
+ const n = i.match(/^\s*([^\s]+)\s+v([^\s]+)/);
33
+ n && (s[n[1]] = n[2]);
34
+ } else if (i.trim().startsWith("require ")) {
35
+ const n = i.match(/require\s+([^\s]+)\s+v([^\s]+)/);
36
+ n && (s[n[1]] = n[2]);
34
37
  }
35
38
  }
39
+ const g = await this.enrichTags(e, s);
36
40
  return {
37
41
  language: "Go",
38
- name: r?.[1] || this.getProjectName(e),
39
- dependencies: n,
42
+ name: o?.[1] || this.getProjectName(e),
43
+ dependencies: s,
40
44
  manifestFile: "go.mod",
41
- projectPath: e
45
+ projectPath: e,
46
+ tags: Array.from(g)
42
47
  };
43
48
  }
49
+ /**
50
+ * Enrich tags from dependencies
51
+ */
52
+ async enrichTags(e, t) {
53
+ const o = /* @__PURE__ */ new Set(["go"]), s = this.getDependencyTagMap();
54
+ for (const r in t)
55
+ s[r] && o.add(s[r]);
56
+ return o;
57
+ }
44
58
  getTemplates() {
59
+ const e = this.getDirname(import.meta.url);
45
60
  return [
46
61
  {
47
62
  name: "go-core",
48
63
  tags: ["go"],
49
64
  content: () => this.loadTemplateFromFile(
50
- m.join(__dirname, "templates/lang-go.md")
51
- ).then((e) => e || this.getGoFallbackTemplate())
65
+ m.join(e, "templates/lang-go.md")
66
+ ).then((t) => t || this.getGoFallbackTemplate())
52
67
  }
53
68
  ];
54
69
  }
@@ -92,5 +107,5 @@ This project uses Go.
92
107
  }
93
108
  }
94
109
  export {
95
- d as GoPlugin
110
+ u as GoPlugin
96
111
  };
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./BasePlugin-odQJAKA-.cjs"),d=require("./nodejs/index.cjs"),m=require("./go/index.cjs"),p=require("./python/index.cjs"),g=require("./rust/index.cjs"),f=require("./java/index.cjs"),h=require("./ruby/index.cjs"),y=require("./php/index.cjs"),b=require("./csharp/index.cjs"),v=require("./cpp/index.cjs"),x=require("./swift/index.cjs"),F=require("node:path");function P(a){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const t in a)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(a,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>a[t]})}}return e.default=a,Object.freeze(e)}const r=P(F);class k extends o.BasePlugin{constructor(){super(...arguments),this.name="elixir",this.displayName="Elixir",this.version="1.0.0",this.priority=80}async detect(e){if(!this.fileExists(e,"mix.exs"))return null;const t=this.readFile(e,"mix.exs"),i=["elixir"],s={};if(t){const l=t.match(/app:\s*:(\w+)/),n=t.match(/version:\s*"([^"]+)"/);return t.includes(":phoenix")&&(i.push("phoenix"),s.phoenix="*"),t.includes(":ecto")&&(i.push("ecto"),s.ecto="*"),{language:"Elixir",name:l?.[1]||this.getProjectName(e),version:n?.[1]||"0.1.0",dependencies:s,manifestFile:"mix.exs",projectPath:e,tags:i}}return{language:"Elixir",name:this.getProjectName(e),dependencies:{},manifestFile:"mix.exs",projectPath:e,tags:i}}getTemplates(){return[{name:"elixir-core",tags:["elixir"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-elixir.md")).then(e=>e||this.getElixirFallbackTemplate())}]}getDependencyTagMap(){return{phoenix:"phoenix",ecto:"ecto",absinthe:"graphql",plug:"plug"}}getElixirFallbackTemplate(){return`# Elixir Development Guidelines
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./BasePlugin-Be6rLq9o.cjs"),d=require("./nodejs/index.cjs"),m=require("./go/index.cjs"),p=require("./python/index.cjs"),g=require("./rust/index.cjs"),f=require("./java/index.cjs"),h=require("./ruby/index.cjs"),y=require("./php/index.cjs"),b=require("./csharp/index.cjs"),x=require("./cpp/index.cjs"),F=require("./swift/index.cjs"),P=require("node:path");var i=typeof document<"u"?document.currentScript:null;function v(a){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const t in a)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(a,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>a[t]})}}return e.default=a,Object.freeze(e)}const o=v(P);class T extends c.BasePlugin{constructor(){super(...arguments),this.name="elixir",this.displayName="Elixir",this.version="1.0.0",this.priority=80}async detect(e){if(!this.fileExists(e,"mix.exs"))return null;const t=this.readFile(e,"mix.exs"),n=["elixir"],s={};if(t){const l=t.match(/app:\s*:(\w+)/),r=t.match(/version:\s*"([^"]+)"/);return t.includes(":phoenix")&&(n.push("phoenix"),s.phoenix="*"),t.includes(":ecto")&&(n.push("ecto"),s.ecto="*"),{language:"Elixir",name:l?.[1]||this.getProjectName(e),version:r?.[1]||"0.1.0",dependencies:s,manifestFile:"mix.exs",projectPath:e,tags:n}}return{language:"Elixir",name:this.getProjectName(e),dependencies:{},manifestFile:"mix.exs",projectPath:e,tags:n}}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"elixir-core",tags:["elixir"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-elixir.md")).then(t=>t||this.getElixirFallbackTemplate())}]}getDependencyTagMap(){return{phoenix:"phoenix",ecto:"ecto",absinthe:"graphql",plug:"plug"}}getElixirFallbackTemplate(){return`# Elixir Development Guidelines
2
2
 
3
3
  ## Language-Specific Rules
4
4
  - Use pattern matching and guards extensively
@@ -19,7 +19,7 @@
19
19
  - GenServer for state management
20
20
  - Phoenix contexts for domain logic
21
21
  - Ecto changesets for data validation
22
- `}}class T extends o.BasePlugin{constructor(){super(...arguments),this.name="dart",this.displayName="Dart",this.version="1.0.0",this.priority=80}async detect(e){if(!this.fileExists(e,"pubspec.yaml"))return null;const t=this.readFile(e,"pubspec.yaml"),i=["dart"],s={};if(t){const l=t.match(/name:\s*(.+)/),n=t.match(/version:\s*(.+)/);return(t.includes("flutter:")||t.includes("flutter_test:"))&&(i.push("flutter"),s.flutter="*"),(t.includes("flutter_riverpod:")||t.includes("riverpod:"))&&i.push("riverpod"),(t.includes("flutter_bloc:")||t.includes("bloc:"))&&i.push("bloc"),{language:"Dart",name:l?.[1]?.trim()||this.getProjectName(e),version:n?.[1]?.trim()||"1.0.0",dependencies:s,manifestFile:"pubspec.yaml",projectPath:e,tags:i}}return{language:"Dart",name:this.getProjectName(e),dependencies:{},manifestFile:"pubspec.yaml",projectPath:e,tags:i}}getTemplates(){return[{name:"dart-core",tags:["dart"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-dart.md")).then(e=>e||this.getDartFallbackTemplate())},{name:"flutter-core",tags:["flutter"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/flutter.md")).then(e=>e||this.getFlutterFallbackTemplate())}]}getDependencyTagMap(){return{flutter:"flutter",flutter_riverpod:"riverpod",riverpod:"riverpod",flutter_bloc:"bloc",bloc:"bloc",provider:"provider"}}getDartFallbackTemplate(){return`# Dart Development Guidelines
22
+ `}}class U extends c.BasePlugin{constructor(){super(...arguments),this.name="dart",this.displayName="Dart",this.version="1.0.0",this.priority=80}async detect(e){if(!this.fileExists(e,"pubspec.yaml"))return null;const t=this.readFile(e,"pubspec.yaml"),n=["dart"],s={};if(t){const l=t.match(/name:\s*(.+)/),r=t.match(/version:\s*(.+)/);return(t.includes("flutter:")||t.includes("flutter_test:"))&&(n.push("flutter"),s.flutter="*"),(t.includes("flutter_riverpod:")||t.includes("riverpod:"))&&n.push("riverpod"),(t.includes("flutter_bloc:")||t.includes("bloc:"))&&n.push("bloc"),{language:"Dart",name:l?.[1]?.trim()||this.getProjectName(e),version:r?.[1]?.trim()||"1.0.0",dependencies:s,manifestFile:"pubspec.yaml",projectPath:e,tags:n}}return{language:"Dart",name:this.getProjectName(e),dependencies:{},manifestFile:"pubspec.yaml",projectPath:e,tags:n}}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"dart-core",tags:["dart"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-dart.md")).then(t=>t||this.getDartFallbackTemplate())},{name:"flutter-core",tags:["flutter"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/flutter.md")).then(t=>t||this.getFlutterFallbackTemplate())}]}getDependencyTagMap(){return{flutter:"flutter",flutter_riverpod:"riverpod",riverpod:"riverpod",flutter_bloc:"bloc",bloc:"bloc",provider:"provider"}}getDartFallbackTemplate(){return`# Dart Development Guidelines
23
23
 
24
24
  ## Language-Specific Rules
25
25
  - Use strong typing throughout
@@ -45,7 +45,7 @@
45
45
  - Choose appropriate state solution (Riverpod, Bloc, Provider)
46
46
  - Keep business logic separate from UI
47
47
  - Use ValueNotifier for simple state
48
- `}}class S extends o.BasePlugin{constructor(){super(...arguments),this.name="scala",this.displayName="Scala",this.version="1.0.0",this.priority=80}async detect(e){return this.fileExists(e,"build.sbt")?this.detectFromSbt(e):this.fileExists(e,"build.sc")?this.detectFromMill(e):null}getTemplates(){return[{name:"scala-core",tags:["scala"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-scala.md")).then(e=>e||this.getScalaFallbackTemplate())}]}getDependencyTagMap(){return{akka:"akka","akka-http":"akka-http",play:"play","cats-effect":"cats",zio:"zio",scalatest:"scalatest"}}detectFromSbt(e){const t=this.readFile(e,"build.sbt"),i=["scala"],s={};if(t){const l=t.match(/name\s*:=\s*"([^"]+)"/),n=t.match(/version\s*:=\s*"([^"]+)"/);return(t.includes("akka-actor")||t.includes("com.typesafe.akka"))&&(i.push("akka"),s.akka="*"),(t.includes("play")||t.includes("com.typesafe.play"))&&(i.push("play"),s.play="*"),t.includes("zio")&&i.push("zio"),(t.includes("cats-effect")||t.includes("cats-core"))&&i.push("cats"),{language:"Scala",name:l?.[1]||this.getProjectName(e),version:n?.[1]||"0.1.0",dependencies:s,manifestFile:"build.sbt",projectPath:e,tags:i}}return{language:"Scala",name:this.getProjectName(e),dependencies:{},manifestFile:"build.sbt",projectPath:e,tags:i}}detectFromMill(e){return{language:"Scala",name:this.getProjectName(e),dependencies:{},manifestFile:"build.sc",projectPath:e,tags:["scala"]}}getScalaFallbackTemplate(){return`# Scala Development Guidelines
48
+ `}}class k extends c.BasePlugin{constructor(){super(...arguments),this.name="scala",this.displayName="Scala",this.version="1.0.0",this.priority=80}async detect(e){return this.fileExists(e,"build.sbt")?this.detectFromSbt(e):this.fileExists(e,"build.sc")?this.detectFromMill(e):null}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"scala-core",tags:["scala"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-scala.md")).then(t=>t||this.getScalaFallbackTemplate())}]}getDependencyTagMap(){return{akka:"akka","akka-http":"akka-http",play:"play","cats-effect":"cats",zio:"zio",scalatest:"scalatest"}}detectFromSbt(e){const t=this.readFile(e,"build.sbt"),n=["scala"],s={};if(t){const l=t.match(/name\s*:=\s*"([^"]+)"/);return(t.includes("akka-actor")||t.includes("com.typesafe.akka"))&&(n.push("akka"),s.akka="*"),(t.includes("play")||t.includes("com.typesafe.play"))&&(n.push("play"),s.play="*"),t.includes("zio")&&n.push("zio"),(t.includes("cats-effect")||t.includes("cats-core"))&&n.push("cats"),{language:"Scala",name:l?.[1]||this.getProjectName(e),dependencies:s,manifestFile:"build.sbt",projectPath:e,tags:n}}return{language:"Scala",name:this.getProjectName(e),dependencies:{},manifestFile:"build.sbt",projectPath:e,tags:n}}detectFromMill(e){return{language:"Scala",name:this.getProjectName(e),dependencies:{},manifestFile:"build.sc",projectPath:e,tags:["scala"]}}getScalaFallbackTemplate(){return`# Scala Development Guidelines
49
49
 
50
50
  ## Functional Programming
51
51
  - Prefer immutable data structures
@@ -62,7 +62,7 @@
62
62
  - Use type inference where appropriate
63
63
  - Leverage sealed traits for ADTs
64
64
  - Use implicit conversions sparingly
65
- `}}class U extends o.BasePlugin{constructor(){super(...arguments),this.name="kotlin",this.displayName="Kotlin",this.version="1.0.0",this.priority=85}async detect(e){if(!(this.fileExists(e,"build.gradle.kts")||this.fileExists(e,"settings.gradle.kts")))return null;const i=this.readFile(e,"build.gradle.kts"),s=["kotlin"],l={};return i&&(i.includes("ktor")&&(s.push("ktor"),l.ktor="*"),i.includes("spring-boot")&&(s.push("spring-boot"),l["spring-boot"]="*"),i.includes("exposed")&&s.push("exposed"),i.includes("kotlinx-coroutines")&&s.push("coroutines")),{language:"Kotlin",name:this.getProjectName(e),dependencies:l,manifestFile:"build.gradle.kts",projectPath:e,tags:s}}getTemplates(){return[{name:"kotlin-core",tags:["kotlin"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-kotlin.md")).then(e=>e||this.getKotlinFallbackTemplate())}]}getDependencyTagMap(){return{ktor:"ktor","spring-boot":"spring-boot",exposed:"exposed","kotlinx-coroutines":"coroutines"}}getKotlinFallbackTemplate(){return`# Kotlin Development Guidelines
65
+ `}}class R extends c.BasePlugin{constructor(){super(...arguments),this.name="kotlin",this.displayName="Kotlin",this.version="1.0.0",this.priority=85}async detect(e){if(!(this.fileExists(e,"build.gradle.kts")||this.fileExists(e,"settings.gradle.kts")))return null;const n=this.readFile(e,"build.gradle.kts"),s=["kotlin"],l={};return n&&(n.includes("ktor")&&(s.push("ktor"),l.ktor="*"),n.includes("spring-boot")&&(s.push("spring-boot"),l["spring-boot"]="*"),n.includes("exposed")&&s.push("exposed"),n.includes("kotlinx-coroutines")&&s.push("coroutines")),{language:"Kotlin",name:this.getProjectName(e),dependencies:l,manifestFile:"build.gradle.kts",projectPath:e,tags:s}}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"kotlin-core",tags:["kotlin"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-kotlin.md")).then(t=>t||this.getKotlinFallbackTemplate())}]}getDependencyTagMap(){return{ktor:"ktor","spring-boot":"spring-boot",exposed:"exposed","kotlinx-coroutines":"coroutines"}}getKotlinFallbackTemplate(){return`# Kotlin Development Guidelines
66
66
 
67
67
  ## Language Features
68
68
  - Use data classes for simple data holders
@@ -79,7 +79,7 @@
79
79
  - Use collection builders and operations
80
80
  - Leverage sequences for large datasets
81
81
  - Understand the difference between List/MutableList
82
- `}}class _ extends o.BasePlugin{constructor(){super(...arguments),this.name="lua",this.displayName="Lua",this.version="1.0.0",this.priority=75}async detect(e){const i=this.listFiles(e)?.find(s=>s.endsWith(".rockspec"));if(i||this.fileExists(e,"lua_modules")){const s=["lua"];return{language:"Lua",name:this.getProjectName(e),dependencies:{},manifestFile:i||"lua_modules",projectPath:e,tags:s}}return null}getTemplates(){return[{name:"lua-core",tags:["lua"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-lua.md")).then(e=>e||this.getLuaFallbackTemplate())}]}getDependencyTagMap(){return{lapis:"lapis",openresty:"openresty",busted:"busted"}}getLuaFallbackTemplate(){return`# Lua Development Guidelines
82
+ `}}class S extends c.BasePlugin{constructor(){super(...arguments),this.name="lua",this.displayName="Lua",this.version="1.0.0",this.priority=75}async detect(e){const n=this.listFiles(e)?.find(s=>s.endsWith(".rockspec"));if(n||this.fileExists(e,"lua_modules")){const s=["lua"];return{language:"Lua",name:this.getProjectName(e),dependencies:{},manifestFile:n||"lua_modules",projectPath:e,tags:s}}return null}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"lua-core",tags:["lua"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-lua.md")).then(t=>t||this.getLuaFallbackTemplate())}]}getDependencyTagMap(){return{lapis:"lapis",openresty:"openresty",busted:"busted"}}getLuaFallbackTemplate(){return`# Lua Development Guidelines
83
83
 
84
84
  ## Tables
85
85
  - Tables are the primary data structure
@@ -95,7 +95,7 @@
95
95
  - Keep functions small
96
96
  - Use local variables for performance
97
97
  - Understand upvalues and closures
98
- `}}class D extends o.BasePlugin{constructor(){super(...arguments),this.name="r",this.displayName="R",this.version="1.0.0",this.priority=75}async detect(e){const i=this.listFiles(e)?.some(s=>s.endsWith(".Rproj"));if(this.fileExists(e,"DESCRIPTION")||i){const s=["r"],l={},n=this.readFile(e,"DESCRIPTION");if(n){const c=n.match(/Package:\s*(.+)/),u=n.match(/Version:\s*(.+)/);return(n.includes("tidyverse")||n.includes("dplyr"))&&s.push("tidyverse"),n.includes("shiny")&&(s.push("shiny"),l.shiny="*"),{language:"R",name:c?.[1]?.trim()||this.getProjectName(e),version:u?.[1]?.trim()||"0.1.0",dependencies:l,manifestFile:"DESCRIPTION",projectPath:e,tags:s}}return{language:"R",name:this.getProjectName(e),dependencies:{},manifestFile:i?".Rproj":"DESCRIPTION",projectPath:e,tags:s}}return null}getTemplates(){return[{name:"r-core",tags:["r"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-r.md")).then(e=>e||this.getRFallbackTemplate())}]}getDependencyTagMap(){return{tidyverse:"tidyverse",shiny:"shiny",ggplot2:"ggplot2","data.table":"data-table"}}getRFallbackTemplate(){return`# R Development Guidelines
98
+ `}}class D extends c.BasePlugin{constructor(){super(...arguments),this.name="r",this.displayName="R",this.version="1.0.0",this.priority=75}async detect(e){const n=this.listFiles(e)?.some(s=>s.endsWith(".Rproj"));if(this.fileExists(e,"DESCRIPTION")||n){const s=["r"],l={},r=this.readFile(e,"DESCRIPTION");if(r){const u=r.match(/Package:\s*(.+)/);return(r.includes("tidyverse")||r.includes("dplyr"))&&s.push("tidyverse"),r.includes("shiny")&&(s.push("shiny"),l.shiny="*"),{language:"R",name:u?.[1]?.trim()||this.getProjectName(e),dependencies:l,manifestFile:"DESCRIPTION",projectPath:e,tags:s}}return{language:"R",name:this.getProjectName(e),dependencies:{},manifestFile:n?".Rproj":"DESCRIPTION",projectPath:e,tags:s}}return null}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"r-core",tags:["r"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-r.md")).then(t=>t||this.getRFallbackTemplate())}]}getDependencyTagMap(){return{tidyverse:"tidyverse",shiny:"shiny",ggplot2:"ggplot2","data.table":"data-table"}}getRFallbackTemplate(){return`# R Development Guidelines
99
99
 
100
100
  ## Tidyverse Principles
101
101
  - Use pipes (%>% or |>) for data transformations
@@ -111,7 +111,7 @@
111
111
  - Document functions with roxygen2
112
112
  - Write unit tests with testthat
113
113
  - Use consistent naming (snake_case)
114
- `}}class M extends o.BasePlugin{constructor(){super(...arguments),this.name="perl",this.displayName="Perl",this.version="1.0.0",this.priority=70}async detect(e){if(this.fileExists(e,"Makefile.PL")||this.fileExists(e,"Build.PL")||this.fileExists(e,"cpanfile")){const t=this.fileExists(e,"Makefile.PL")?"Makefile.PL":this.fileExists(e,"Build.PL")?"Build.PL":"cpanfile";return{language:"Perl",name:this.getProjectName(e),dependencies:{},manifestFile:t,projectPath:e,tags:["perl"]}}return null}getTemplates(){return[{name:"perl-core",tags:["perl"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-perl.md")).then(e=>e||this.getPerlFallbackTemplate())}]}getDependencyTagMap(){return{Mojolicious:"mojolicious",Dancer2:"dancer",Catalyst:"catalyst"}}getPerlFallbackTemplate(){return`# Perl Development Guidelines
114
+ `}}class L extends c.BasePlugin{constructor(){super(...arguments),this.name="perl",this.displayName="Perl",this.version="1.0.0",this.priority=70}async detect(e){if(this.fileExists(e,"Makefile.PL")||this.fileExists(e,"Build.PL")||this.fileExists(e,"cpanfile")){const t=this.fileExists(e,"Makefile.PL")?"Makefile.PL":this.fileExists(e,"Build.PL")?"Build.PL":"cpanfile";return{language:"Perl",name:this.getProjectName(e),dependencies:{},manifestFile:t,projectPath:e,tags:["perl"]}}return null}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"perl-core",tags:["perl"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-perl.md")).then(t=>t||this.getPerlFallbackTemplate())}]}getDependencyTagMap(){return{Mojolicious:"mojolicious",Dancer2:"dancer",Catalyst:"catalyst"}}getPerlFallbackTemplate(){return`# Perl Development Guidelines
115
115
 
116
116
  ## Modern Perl
117
117
  - Use strict and warnings
@@ -127,7 +127,7 @@
127
127
  - Follow PBP (Perl Best Practices)
128
128
  - Use perlcritic for linting
129
129
  - Write tests with Test::More
130
- `}}class N extends o.BasePlugin{constructor(){super(...arguments),this.name="shell",this.displayName="Shell",this.version="1.0.0",this.priority=60}async detect(e){const t=this.listFiles(e);if(t?.some(s=>s.endsWith(".sh")||s==="Makefile"||s.endsWith(".bash")||s.endsWith(".zsh"))){const s=["shell"];if((t?.filter(n=>n.endsWith(".sh")||n.endsWith(".bash")||n.endsWith(".zsh")).length||0)>=2||t?.includes("install.sh")||t?.includes("setup.sh"))return{language:"Shell",name:this.getProjectName(e),dependencies:{},manifestFile:"scripts",projectPath:e,tags:s}}return null}getTemplates(){return[{name:"shell-core",tags:["shell"],content:()=>this.loadTemplateFromFile(r.join(__dirname,"templates/lang-shell.md")).then(e=>e||this.getShellFallbackTemplate())}]}getDependencyTagMap(){return{}}getShellFallbackTemplate(){return`# Shell Script Development Guidelines
130
+ `}}class C extends c.BasePlugin{constructor(){super(...arguments),this.name="shell",this.displayName="Shell",this.version="1.0.0",this.priority=60}async detect(e){const t=this.listFiles(e);if(t?.some(s=>s.endsWith(".sh")||s==="Makefile"||s.endsWith(".bash")||s.endsWith(".zsh"))){const s=["shell"];if((t?.filter(r=>r.endsWith(".sh")||r.endsWith(".bash")||r.endsWith(".zsh")).length||0)>=2||t?.includes("install.sh")||t?.includes("setup.sh"))return{language:"Shell",name:this.getProjectName(e),dependencies:{},manifestFile:"scripts",projectPath:e,tags:s}}return null}getTemplates(){const e=this.getDirname(typeof document>"u"?require("url").pathToFileURL(__filename).href:i&&i.tagName.toUpperCase()==="SCRIPT"&&i.src||new URL("index.cjs",document.baseURI).href);return[{name:"shell-core",tags:["shell"],content:()=>this.loadTemplateFromFile(o.join(e,"templates/lang-shell.md")).then(t=>t||this.getShellFallbackTemplate())}]}getDependencyTagMap(){return{}}getShellFallbackTemplate(){return`# Shell Script Development Guidelines
131
131
 
132
132
  ## Best Practices
133
133
  - Use #!/usr/bin/env bash for portability
@@ -144,4 +144,4 @@
144
144
  - Keep functions focused
145
145
  - Use local variables
146
146
  - Return meaningful exit codes
147
- `}}exports.BasePlugin=o.BasePlugin;exports.NodeJSPlugin=d.NodeJSPlugin;exports.GoPlugin=m.GoPlugin;exports.PythonPlugin=p.PythonPlugin;exports.RustPlugin=g.RustPlugin;exports.JavaPlugin=f.JavaPlugin;exports.RubyPlugin=h.RubyPlugin;exports.PHPPlugin=y.PHPPlugin;exports.CSharpPlugin=b.CSharpPlugin;exports.CppPlugin=v.CppPlugin;exports.SwiftPlugin=x.SwiftPlugin;exports.DartPlugin=T;exports.ElixirPlugin=k;exports.KotlinPlugin=U;exports.LuaPlugin=_;exports.PerlPlugin=M;exports.RPlugin=D;exports.ScalaPlugin=S;exports.ShellPlugin=N;
147
+ `}}exports.BasePlugin=c.BasePlugin;exports.NodeJSPlugin=d.NodeJSPlugin;exports.GoPlugin=m.GoPlugin;exports.PythonPlugin=p.PythonPlugin;exports.RustPlugin=g.RustPlugin;exports.JavaPlugin=f.JavaPlugin;exports.RubyPlugin=h.RubyPlugin;exports.PHPPlugin=y.PHPPlugin;exports.CSharpPlugin=b.CSharpPlugin;exports.CppPlugin=x.CppPlugin;exports.SwiftPlugin=F.SwiftPlugin;exports.DartPlugin=U;exports.ElixirPlugin=T;exports.KotlinPlugin=R;exports.LuaPlugin=S;exports.PerlPlugin=L;exports.RPlugin=D;exports.ScalaPlugin=k;exports.ShellPlugin=C;