@lousy-agents/cli 2.6.0 → 2.7.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.
- package/api/copilot-with-fastify/.vscode/mcp.json +1 -1
- package/cli/copilot-with-citty/.vscode/mcp.json +1 -1
- package/dist/index.js +431 -363
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +85 -0
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
- package/ui/copilot-with-react/.github/workflows/ci.yml +67 -0
- package/ui/copilot-with-react/.vscode/mcp.json +19 -0
- package/ui/copilot-with-react/{biome.json → biome.template.json} +1 -1
- package/ui/copilot-with-react/gitignore.template +5 -0
package/dist/index.js
CHANGED
|
@@ -14681,6 +14681,90 @@ async function watchConfig(options) {
|
|
|
14681
14681
|
|
|
14682
14682
|
// EXTERNAL MODULE: ./node_modules/yaml/dist/index.js
|
|
14683
14683
|
var dist = __webpack_require__(1198);
|
|
14684
|
+
;// CONCATENATED MODULE: ./src/gateways/skill-lint-gateway.ts
|
|
14685
|
+
/**
|
|
14686
|
+
* Gateway for skill lint file system operations.
|
|
14687
|
+
* Discovers skill files and parses YAML frontmatter.
|
|
14688
|
+
*/
|
|
14689
|
+
|
|
14690
|
+
|
|
14691
|
+
|
|
14692
|
+
/**
|
|
14693
|
+
* File system implementation of the skill lint gateway.
|
|
14694
|
+
*/ class FileSystemSkillLintGateway {
|
|
14695
|
+
async discoverSkills(targetDir) {
|
|
14696
|
+
const skillsDir = (0,external_node_path_.join)(targetDir, ".github", "skills");
|
|
14697
|
+
if (!await file_system_utils_fileExists(skillsDir)) {
|
|
14698
|
+
return [];
|
|
14699
|
+
}
|
|
14700
|
+
const entries = await (0,promises_.readdir)(skillsDir, {
|
|
14701
|
+
withFileTypes: true
|
|
14702
|
+
});
|
|
14703
|
+
const skills = [];
|
|
14704
|
+
for (const entry of entries){
|
|
14705
|
+
if (!entry.isDirectory()) {
|
|
14706
|
+
continue;
|
|
14707
|
+
}
|
|
14708
|
+
if (entry.name.includes("..") || entry.name.includes("/") || entry.name.includes("\\")) {
|
|
14709
|
+
continue;
|
|
14710
|
+
}
|
|
14711
|
+
const skillFilePath = (0,external_node_path_.join)(skillsDir, entry.name, "SKILL.md");
|
|
14712
|
+
if (await file_system_utils_fileExists(skillFilePath)) {
|
|
14713
|
+
skills.push({
|
|
14714
|
+
filePath: skillFilePath,
|
|
14715
|
+
skillName: entry.name
|
|
14716
|
+
});
|
|
14717
|
+
}
|
|
14718
|
+
}
|
|
14719
|
+
return skills;
|
|
14720
|
+
}
|
|
14721
|
+
async readSkillFileContent(filePath) {
|
|
14722
|
+
return (0,promises_.readFile)(filePath, "utf-8");
|
|
14723
|
+
}
|
|
14724
|
+
parseFrontmatter(content) {
|
|
14725
|
+
const lines = content.split("\n");
|
|
14726
|
+
if (lines[0]?.trim() !== "---") {
|
|
14727
|
+
return null;
|
|
14728
|
+
}
|
|
14729
|
+
let endIndex = -1;
|
|
14730
|
+
for(let i = 1; i < lines.length; i++){
|
|
14731
|
+
if (lines[i]?.trim() === "---") {
|
|
14732
|
+
endIndex = i;
|
|
14733
|
+
break;
|
|
14734
|
+
}
|
|
14735
|
+
}
|
|
14736
|
+
if (endIndex === -1) {
|
|
14737
|
+
return null;
|
|
14738
|
+
}
|
|
14739
|
+
const yamlContent = lines.slice(1, endIndex).join("\n");
|
|
14740
|
+
let data;
|
|
14741
|
+
try {
|
|
14742
|
+
const parsed = (0,dist.parse)(yamlContent);
|
|
14743
|
+
data = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
14744
|
+
} catch {
|
|
14745
|
+
return null;
|
|
14746
|
+
}
|
|
14747
|
+
const fieldLines = new Map();
|
|
14748
|
+
for(let i = 1; i < endIndex; i++){
|
|
14749
|
+
// Match YAML top-level field names: non-whitespace start, any chars except colon, then colon+space
|
|
14750
|
+
const match = lines[i]?.match(/^([^\s:][^:]*?):\s/);
|
|
14751
|
+
if (match?.[1]) {
|
|
14752
|
+
fieldLines.set(match[1], i + 1);
|
|
14753
|
+
}
|
|
14754
|
+
}
|
|
14755
|
+
return {
|
|
14756
|
+
data: data ?? {},
|
|
14757
|
+
fieldLines,
|
|
14758
|
+
frontmatterStartLine: 1
|
|
14759
|
+
};
|
|
14760
|
+
}
|
|
14761
|
+
}
|
|
14762
|
+
/**
|
|
14763
|
+
* Creates and returns the default skill lint gateway.
|
|
14764
|
+
*/ function createSkillLintGateway() {
|
|
14765
|
+
return new FileSystemSkillLintGateway();
|
|
14766
|
+
}
|
|
14767
|
+
|
|
14684
14768
|
;// CONCATENATED MODULE: ./src/gateways/tool-discovery-gateway.ts
|
|
14685
14769
|
/**
|
|
14686
14770
|
* Gateway for discovering CLI tools and commands from GitHub Actions workflows
|
|
@@ -15137,6 +15221,7 @@ var dist = __webpack_require__(1198);
|
|
|
15137
15221
|
|
|
15138
15222
|
|
|
15139
15223
|
|
|
15224
|
+
|
|
15140
15225
|
;// CONCATENATED MODULE: ./src/use-cases/candidate-builder.ts
|
|
15141
15226
|
/**
|
|
15142
15227
|
* Use case for building setup step candidates from environment detection.
|
|
@@ -29802,6 +29887,137 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
|
|
|
29802
29887
|
*/ function readCliTemplateFile(relativePath) {
|
|
29803
29888
|
return readTemplateFile(relativePath, CLI_TEMPLATE_DIR);
|
|
29804
29889
|
}
|
|
29890
|
+
/**
|
|
29891
|
+
* Builds the common filesystem nodes shared across all project types.
|
|
29892
|
+
* Each template has its own versions of these files, but the structure is identical.
|
|
29893
|
+
*/ function buildCommonNodes(reader) {
|
|
29894
|
+
return [
|
|
29895
|
+
{
|
|
29896
|
+
type: "file",
|
|
29897
|
+
path: "biome.json",
|
|
29898
|
+
content: reader("biome.template.json")
|
|
29899
|
+
},
|
|
29900
|
+
{
|
|
29901
|
+
type: "file",
|
|
29902
|
+
path: ".gitignore",
|
|
29903
|
+
content: reader("gitignore.template")
|
|
29904
|
+
},
|
|
29905
|
+
{
|
|
29906
|
+
type: "file",
|
|
29907
|
+
path: ".editorconfig",
|
|
29908
|
+
content: reader(".editorconfig")
|
|
29909
|
+
},
|
|
29910
|
+
{
|
|
29911
|
+
type: "file",
|
|
29912
|
+
path: ".nvmrc",
|
|
29913
|
+
content: reader(".nvmrc")
|
|
29914
|
+
},
|
|
29915
|
+
{
|
|
29916
|
+
type: "file",
|
|
29917
|
+
path: ".yamllint",
|
|
29918
|
+
content: reader(".yamllint")
|
|
29919
|
+
},
|
|
29920
|
+
// GitHub copilot instructions
|
|
29921
|
+
{
|
|
29922
|
+
type: "directory",
|
|
29923
|
+
path: ".github"
|
|
29924
|
+
},
|
|
29925
|
+
{
|
|
29926
|
+
type: "directory",
|
|
29927
|
+
path: ".github/instructions"
|
|
29928
|
+
},
|
|
29929
|
+
{
|
|
29930
|
+
type: "file",
|
|
29931
|
+
path: ".github/copilot-instructions.md",
|
|
29932
|
+
content: reader(".github/copilot-instructions.md")
|
|
29933
|
+
},
|
|
29934
|
+
{
|
|
29935
|
+
type: "file",
|
|
29936
|
+
path: ".github/instructions/test.instructions.md",
|
|
29937
|
+
content: reader(".github/instructions/test.instructions.md")
|
|
29938
|
+
},
|
|
29939
|
+
{
|
|
29940
|
+
type: "file",
|
|
29941
|
+
path: ".github/instructions/spec.instructions.md",
|
|
29942
|
+
content: reader(".github/instructions/spec.instructions.md")
|
|
29943
|
+
},
|
|
29944
|
+
{
|
|
29945
|
+
type: "file",
|
|
29946
|
+
path: ".github/instructions/pipeline.instructions.md",
|
|
29947
|
+
content: reader(".github/instructions/pipeline.instructions.md")
|
|
29948
|
+
},
|
|
29949
|
+
{
|
|
29950
|
+
type: "file",
|
|
29951
|
+
path: ".github/instructions/software-architecture.instructions.md",
|
|
29952
|
+
content: reader(".github/instructions/software-architecture.instructions.md")
|
|
29953
|
+
},
|
|
29954
|
+
// GitHub Issue Templates
|
|
29955
|
+
{
|
|
29956
|
+
type: "directory",
|
|
29957
|
+
path: ".github/ISSUE_TEMPLATE"
|
|
29958
|
+
},
|
|
29959
|
+
{
|
|
29960
|
+
type: "file",
|
|
29961
|
+
path: ".github/ISSUE_TEMPLATE/feature-to-spec.yml",
|
|
29962
|
+
content: reader(".github/ISSUE_TEMPLATE/feature-to-spec.yml")
|
|
29963
|
+
},
|
|
29964
|
+
// GitHub Workflows
|
|
29965
|
+
{
|
|
29966
|
+
type: "directory",
|
|
29967
|
+
path: ".github/workflows"
|
|
29968
|
+
},
|
|
29969
|
+
{
|
|
29970
|
+
type: "file",
|
|
29971
|
+
path: ".github/workflows/assign-copilot.yml",
|
|
29972
|
+
content: reader(".github/workflows/assign-copilot.yml")
|
|
29973
|
+
},
|
|
29974
|
+
{
|
|
29975
|
+
type: "file",
|
|
29976
|
+
path: ".github/workflows/ci.yml",
|
|
29977
|
+
content: reader(".github/workflows/ci.yml")
|
|
29978
|
+
},
|
|
29979
|
+
// Specs directory
|
|
29980
|
+
{
|
|
29981
|
+
type: "directory",
|
|
29982
|
+
path: ".github/specs"
|
|
29983
|
+
},
|
|
29984
|
+
{
|
|
29985
|
+
type: "file",
|
|
29986
|
+
path: ".github/specs/README.md",
|
|
29987
|
+
content: reader(".github/specs/README.md")
|
|
29988
|
+
},
|
|
29989
|
+
// VSCode configuration
|
|
29990
|
+
{
|
|
29991
|
+
type: "directory",
|
|
29992
|
+
path: ".vscode"
|
|
29993
|
+
},
|
|
29994
|
+
{
|
|
29995
|
+
type: "file",
|
|
29996
|
+
path: ".vscode/extensions.json",
|
|
29997
|
+
content: reader(".vscode/extensions.json")
|
|
29998
|
+
},
|
|
29999
|
+
{
|
|
30000
|
+
type: "file",
|
|
30001
|
+
path: ".vscode/launch.json",
|
|
30002
|
+
content: reader(".vscode/launch.json")
|
|
30003
|
+
},
|
|
30004
|
+
{
|
|
30005
|
+
type: "file",
|
|
30006
|
+
path: ".vscode/mcp.json",
|
|
30007
|
+
content: reader(".vscode/mcp.json")
|
|
30008
|
+
},
|
|
30009
|
+
// Devcontainer configuration
|
|
30010
|
+
{
|
|
30011
|
+
type: "directory",
|
|
30012
|
+
path: ".devcontainer"
|
|
30013
|
+
},
|
|
30014
|
+
{
|
|
30015
|
+
type: "file",
|
|
30016
|
+
path: ".devcontainer/devcontainer.json",
|
|
30017
|
+
content: reader(".devcontainer/devcontainer.json")
|
|
30018
|
+
}
|
|
30019
|
+
];
|
|
30020
|
+
}
|
|
29805
30021
|
/**
|
|
29806
30022
|
* Cached CLI structure - lazy-loaded on first access
|
|
29807
30023
|
*/ let cachedCliStructure = null;
|
|
@@ -29835,120 +30051,7 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
|
|
|
29835
30051
|
path: "vitest.setup.ts",
|
|
29836
30052
|
content: readCliTemplateFile("vitest.setup.ts")
|
|
29837
30053
|
},
|
|
29838
|
-
|
|
29839
|
-
type: "file",
|
|
29840
|
-
path: "biome.json",
|
|
29841
|
-
content: readCliTemplateFile("biome.template.json")
|
|
29842
|
-
},
|
|
29843
|
-
{
|
|
29844
|
-
type: "file",
|
|
29845
|
-
path: ".gitignore",
|
|
29846
|
-
content: readCliTemplateFile("gitignore.template")
|
|
29847
|
-
},
|
|
29848
|
-
{
|
|
29849
|
-
type: "file",
|
|
29850
|
-
path: ".editorconfig",
|
|
29851
|
-
content: readCliTemplateFile(".editorconfig")
|
|
29852
|
-
},
|
|
29853
|
-
{
|
|
29854
|
-
type: "file",
|
|
29855
|
-
path: ".nvmrc",
|
|
29856
|
-
content: readCliTemplateFile(".nvmrc")
|
|
29857
|
-
},
|
|
29858
|
-
{
|
|
29859
|
-
type: "file",
|
|
29860
|
-
path: ".yamllint",
|
|
29861
|
-
content: readCliTemplateFile(".yamllint")
|
|
29862
|
-
},
|
|
29863
|
-
// GitHub copilot instructions
|
|
29864
|
-
{
|
|
29865
|
-
type: "directory",
|
|
29866
|
-
path: ".github"
|
|
29867
|
-
},
|
|
29868
|
-
{
|
|
29869
|
-
type: "directory",
|
|
29870
|
-
path: ".github/instructions"
|
|
29871
|
-
},
|
|
29872
|
-
{
|
|
29873
|
-
type: "file",
|
|
29874
|
-
path: ".github/copilot-instructions.md",
|
|
29875
|
-
content: readCliTemplateFile(".github/copilot-instructions.md")
|
|
29876
|
-
},
|
|
29877
|
-
{
|
|
29878
|
-
type: "file",
|
|
29879
|
-
path: ".github/instructions/test.instructions.md",
|
|
29880
|
-
content: readCliTemplateFile(".github/instructions/test.instructions.md")
|
|
29881
|
-
},
|
|
29882
|
-
{
|
|
29883
|
-
type: "file",
|
|
29884
|
-
path: ".github/instructions/spec.instructions.md",
|
|
29885
|
-
content: readCliTemplateFile(".github/instructions/spec.instructions.md")
|
|
29886
|
-
},
|
|
29887
|
-
{
|
|
29888
|
-
type: "file",
|
|
29889
|
-
path: ".github/instructions/pipeline.instructions.md",
|
|
29890
|
-
content: readCliTemplateFile(".github/instructions/pipeline.instructions.md")
|
|
29891
|
-
},
|
|
29892
|
-
{
|
|
29893
|
-
type: "file",
|
|
29894
|
-
path: ".github/instructions/software-architecture.instructions.md",
|
|
29895
|
-
content: readCliTemplateFile(".github/instructions/software-architecture.instructions.md")
|
|
29896
|
-
},
|
|
29897
|
-
// GitHub Issue Templates
|
|
29898
|
-
{
|
|
29899
|
-
type: "directory",
|
|
29900
|
-
path: ".github/ISSUE_TEMPLATE"
|
|
29901
|
-
},
|
|
29902
|
-
{
|
|
29903
|
-
type: "file",
|
|
29904
|
-
path: ".github/ISSUE_TEMPLATE/feature-to-spec.yml",
|
|
29905
|
-
content: readCliTemplateFile(".github/ISSUE_TEMPLATE/feature-to-spec.yml")
|
|
29906
|
-
},
|
|
29907
|
-
// GitHub Workflows
|
|
29908
|
-
{
|
|
29909
|
-
type: "directory",
|
|
29910
|
-
path: ".github/workflows"
|
|
29911
|
-
},
|
|
29912
|
-
{
|
|
29913
|
-
type: "file",
|
|
29914
|
-
path: ".github/workflows/assign-copilot.yml",
|
|
29915
|
-
content: readCliTemplateFile(".github/workflows/assign-copilot.yml")
|
|
29916
|
-
},
|
|
29917
|
-
{
|
|
29918
|
-
type: "file",
|
|
29919
|
-
path: ".github/workflows/ci.yml",
|
|
29920
|
-
content: readCliTemplateFile(".github/workflows/ci.yml")
|
|
29921
|
-
},
|
|
29922
|
-
// Specs directory
|
|
29923
|
-
{
|
|
29924
|
-
type: "directory",
|
|
29925
|
-
path: ".github/specs"
|
|
29926
|
-
},
|
|
29927
|
-
{
|
|
29928
|
-
type: "file",
|
|
29929
|
-
path: ".github/specs/README.md",
|
|
29930
|
-
content: readCliTemplateFile(".github/specs/README.md")
|
|
29931
|
-
},
|
|
29932
|
-
// VSCode configuration
|
|
29933
|
-
{
|
|
29934
|
-
type: "directory",
|
|
29935
|
-
path: ".vscode"
|
|
29936
|
-
},
|
|
29937
|
-
{
|
|
29938
|
-
type: "file",
|
|
29939
|
-
path: ".vscode/extensions.json",
|
|
29940
|
-
content: readCliTemplateFile(".vscode/extensions.json")
|
|
29941
|
-
},
|
|
29942
|
-
{
|
|
29943
|
-
type: "file",
|
|
29944
|
-
path: ".vscode/launch.json",
|
|
29945
|
-
content: readCliTemplateFile(".vscode/launch.json")
|
|
29946
|
-
},
|
|
29947
|
-
{
|
|
29948
|
-
type: "file",
|
|
29949
|
-
path: ".vscode/mcp.json",
|
|
29950
|
-
content: readCliTemplateFile(".vscode/mcp.json")
|
|
29951
|
-
},
|
|
30054
|
+
...buildCommonNodes(readCliTemplateFile),
|
|
29952
30055
|
// Source code
|
|
29953
30056
|
{
|
|
29954
30057
|
type: "directory",
|
|
@@ -29963,16 +30066,6 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
|
|
|
29963
30066
|
type: "file",
|
|
29964
30067
|
path: "src/index.test.ts",
|
|
29965
30068
|
content: readCliTemplateFile("src/index.test.ts")
|
|
29966
|
-
},
|
|
29967
|
-
// Devcontainer configuration
|
|
29968
|
-
{
|
|
29969
|
-
type: "directory",
|
|
29970
|
-
path: ".devcontainer"
|
|
29971
|
-
},
|
|
29972
|
-
{
|
|
29973
|
-
type: "file",
|
|
29974
|
-
path: ".devcontainer/devcontainer.json",
|
|
29975
|
-
content: readCliTemplateFile(".devcontainer/devcontainer.json")
|
|
29976
30069
|
}
|
|
29977
30070
|
]
|
|
29978
30071
|
};
|
|
@@ -29994,6 +30087,11 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
|
|
|
29994
30087
|
/**
|
|
29995
30088
|
* Cached webapp structure - lazy-loaded on first access
|
|
29996
30089
|
*/ let cachedWebappStructure = null;
|
|
30090
|
+
/**
|
|
30091
|
+
* Helper function to read webapp template files
|
|
30092
|
+
*/ function readWebappTemplateFile(relativePath) {
|
|
30093
|
+
return readTemplateFile(relativePath, WEBAPP_TEMPLATE_DIR);
|
|
30094
|
+
}
|
|
29997
30095
|
/**
|
|
29998
30096
|
* Builds the webapp project filesystem structure by reading template files
|
|
29999
30097
|
* This is called lazily only when webapp scaffolding is needed
|
|
@@ -30007,137 +30105,29 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
|
|
|
30007
30105
|
{
|
|
30008
30106
|
type: "file",
|
|
30009
30107
|
path: "package.json",
|
|
30010
|
-
content:
|
|
30108
|
+
content: readWebappTemplateFile("package.json")
|
|
30011
30109
|
},
|
|
30012
30110
|
{
|
|
30013
30111
|
type: "file",
|
|
30014
30112
|
path: "tsconfig.json",
|
|
30015
|
-
content:
|
|
30113
|
+
content: readWebappTemplateFile("tsconfig.json")
|
|
30016
30114
|
},
|
|
30017
30115
|
{
|
|
30018
30116
|
type: "file",
|
|
30019
30117
|
path: "next.config.ts",
|
|
30020
|
-
content:
|
|
30118
|
+
content: readWebappTemplateFile("next.config.ts")
|
|
30021
30119
|
},
|
|
30022
30120
|
{
|
|
30023
30121
|
type: "file",
|
|
30024
30122
|
path: "vitest.config.ts",
|
|
30025
|
-
content:
|
|
30123
|
+
content: readWebappTemplateFile("vitest.config.ts")
|
|
30026
30124
|
},
|
|
30027
30125
|
{
|
|
30028
30126
|
type: "file",
|
|
30029
30127
|
path: "vitest.setup.ts",
|
|
30030
|
-
content:
|
|
30031
|
-
},
|
|
30032
|
-
{
|
|
30033
|
-
type: "file",
|
|
30034
|
-
path: "biome.json",
|
|
30035
|
-
content: readTemplateFile("biome.json")
|
|
30036
|
-
},
|
|
30037
|
-
{
|
|
30038
|
-
type: "file",
|
|
30039
|
-
path: ".editorconfig",
|
|
30040
|
-
content: readTemplateFile(".editorconfig")
|
|
30041
|
-
},
|
|
30042
|
-
{
|
|
30043
|
-
type: "file",
|
|
30044
|
-
path: ".nvmrc",
|
|
30045
|
-
content: readTemplateFile(".nvmrc")
|
|
30046
|
-
},
|
|
30047
|
-
{
|
|
30048
|
-
type: "file",
|
|
30049
|
-
path: ".yamllint",
|
|
30050
|
-
content: readTemplateFile(".yamllint")
|
|
30051
|
-
},
|
|
30052
|
-
// GitHub copilot instructions
|
|
30053
|
-
{
|
|
30054
|
-
type: "directory",
|
|
30055
|
-
path: ".github"
|
|
30056
|
-
},
|
|
30057
|
-
{
|
|
30058
|
-
type: "directory",
|
|
30059
|
-
path: ".github/instructions"
|
|
30060
|
-
},
|
|
30061
|
-
{
|
|
30062
|
-
type: "file",
|
|
30063
|
-
path: ".github/copilot-instructions.md",
|
|
30064
|
-
content: readTemplateFile(".github/copilot-instructions.md")
|
|
30065
|
-
},
|
|
30066
|
-
{
|
|
30067
|
-
type: "file",
|
|
30068
|
-
path: ".github/instructions/test.instructions.md",
|
|
30069
|
-
content: readTemplateFile(".github/instructions/test.instructions.md")
|
|
30128
|
+
content: readWebappTemplateFile("vitest.setup.ts")
|
|
30070
30129
|
},
|
|
30071
|
-
|
|
30072
|
-
type: "file",
|
|
30073
|
-
path: ".github/instructions/spec.instructions.md",
|
|
30074
|
-
content: readTemplateFile(".github/instructions/spec.instructions.md")
|
|
30075
|
-
},
|
|
30076
|
-
{
|
|
30077
|
-
type: "file",
|
|
30078
|
-
path: ".github/instructions/pipeline.instructions.md",
|
|
30079
|
-
content: readTemplateFile(".github/instructions/pipeline.instructions.md")
|
|
30080
|
-
},
|
|
30081
|
-
{
|
|
30082
|
-
type: "file",
|
|
30083
|
-
path: ".github/instructions/software-architecture.instructions.md",
|
|
30084
|
-
content: readTemplateFile(".github/instructions/software-architecture.instructions.md")
|
|
30085
|
-
},
|
|
30086
|
-
// GitHub Issue Templates
|
|
30087
|
-
{
|
|
30088
|
-
type: "directory",
|
|
30089
|
-
path: ".github/ISSUE_TEMPLATE"
|
|
30090
|
-
},
|
|
30091
|
-
{
|
|
30092
|
-
type: "file",
|
|
30093
|
-
path: ".github/ISSUE_TEMPLATE/feature-to-spec.yml",
|
|
30094
|
-
content: readTemplateFile(".github/ISSUE_TEMPLATE/feature-to-spec.yml")
|
|
30095
|
-
},
|
|
30096
|
-
// GitHub Workflows
|
|
30097
|
-
{
|
|
30098
|
-
type: "directory",
|
|
30099
|
-
path: ".github/workflows"
|
|
30100
|
-
},
|
|
30101
|
-
{
|
|
30102
|
-
type: "file",
|
|
30103
|
-
path: ".github/workflows/assign-copilot.yml",
|
|
30104
|
-
content: readTemplateFile(".github/workflows/assign-copilot.yml")
|
|
30105
|
-
},
|
|
30106
|
-
// Specs directory
|
|
30107
|
-
{
|
|
30108
|
-
type: "directory",
|
|
30109
|
-
path: ".github/specs"
|
|
30110
|
-
},
|
|
30111
|
-
{
|
|
30112
|
-
type: "file",
|
|
30113
|
-
path: ".github/specs/README.md",
|
|
30114
|
-
content: readTemplateFile(".github/specs/README.md")
|
|
30115
|
-
},
|
|
30116
|
-
// VSCode configuration
|
|
30117
|
-
{
|
|
30118
|
-
type: "directory",
|
|
30119
|
-
path: ".vscode"
|
|
30120
|
-
},
|
|
30121
|
-
{
|
|
30122
|
-
type: "file",
|
|
30123
|
-
path: ".vscode/extensions.json",
|
|
30124
|
-
content: readTemplateFile(".vscode/extensions.json")
|
|
30125
|
-
},
|
|
30126
|
-
{
|
|
30127
|
-
type: "file",
|
|
30128
|
-
path: ".vscode/launch.json",
|
|
30129
|
-
content: readTemplateFile(".vscode/launch.json")
|
|
30130
|
-
},
|
|
30131
|
-
// Devcontainer configuration
|
|
30132
|
-
{
|
|
30133
|
-
type: "directory",
|
|
30134
|
-
path: ".devcontainer"
|
|
30135
|
-
},
|
|
30136
|
-
{
|
|
30137
|
-
type: "file",
|
|
30138
|
-
path: ".devcontainer/devcontainer.json",
|
|
30139
|
-
content: readTemplateFile(".devcontainer/devcontainer.json")
|
|
30140
|
-
}
|
|
30130
|
+
...buildCommonNodes(readWebappTemplateFile)
|
|
30141
30131
|
]
|
|
30142
30132
|
};
|
|
30143
30133
|
return cachedWebappStructure;
|
|
@@ -30185,130 +30175,7 @@ const CLI_TEMPLATE_DIR = (0,external_node_path_.join)(PROJECT_ROOT, "cli", "copi
|
|
|
30185
30175
|
path: "vitest.setup.ts",
|
|
30186
30176
|
content: readRestApiTemplateFile("vitest.setup.ts")
|
|
30187
30177
|
},
|
|
30188
|
-
|
|
30189
|
-
type: "file",
|
|
30190
|
-
path: "biome.json",
|
|
30191
|
-
content: readRestApiTemplateFile("biome.template.json")
|
|
30192
|
-
},
|
|
30193
|
-
{
|
|
30194
|
-
type: "file",
|
|
30195
|
-
path: ".editorconfig",
|
|
30196
|
-
content: readRestApiTemplateFile(".editorconfig")
|
|
30197
|
-
},
|
|
30198
|
-
{
|
|
30199
|
-
type: "file",
|
|
30200
|
-
path: ".nvmrc",
|
|
30201
|
-
content: readRestApiTemplateFile(".nvmrc")
|
|
30202
|
-
},
|
|
30203
|
-
{
|
|
30204
|
-
type: "file",
|
|
30205
|
-
path: ".yamllint",
|
|
30206
|
-
content: readRestApiTemplateFile(".yamllint")
|
|
30207
|
-
},
|
|
30208
|
-
{
|
|
30209
|
-
type: "file",
|
|
30210
|
-
path: ".gitignore",
|
|
30211
|
-
content: readRestApiTemplateFile("gitignore.template")
|
|
30212
|
-
},
|
|
30213
|
-
// GitHub copilot instructions
|
|
30214
|
-
{
|
|
30215
|
-
type: "directory",
|
|
30216
|
-
path: ".github"
|
|
30217
|
-
},
|
|
30218
|
-
{
|
|
30219
|
-
type: "directory",
|
|
30220
|
-
path: ".github/instructions"
|
|
30221
|
-
},
|
|
30222
|
-
{
|
|
30223
|
-
type: "file",
|
|
30224
|
-
path: ".github/copilot-instructions.md",
|
|
30225
|
-
content: readRestApiTemplateFile(".github/copilot-instructions.md")
|
|
30226
|
-
},
|
|
30227
|
-
{
|
|
30228
|
-
type: "file",
|
|
30229
|
-
path: ".github/instructions/test.instructions.md",
|
|
30230
|
-
content: readRestApiTemplateFile(".github/instructions/test.instructions.md")
|
|
30231
|
-
},
|
|
30232
|
-
{
|
|
30233
|
-
type: "file",
|
|
30234
|
-
path: ".github/instructions/spec.instructions.md",
|
|
30235
|
-
content: readRestApiTemplateFile(".github/instructions/spec.instructions.md")
|
|
30236
|
-
},
|
|
30237
|
-
{
|
|
30238
|
-
type: "file",
|
|
30239
|
-
path: ".github/instructions/pipeline.instructions.md",
|
|
30240
|
-
content: readRestApiTemplateFile(".github/instructions/pipeline.instructions.md")
|
|
30241
|
-
},
|
|
30242
|
-
{
|
|
30243
|
-
type: "file",
|
|
30244
|
-
path: ".github/instructions/software-architecture.instructions.md",
|
|
30245
|
-
content: readRestApiTemplateFile(".github/instructions/software-architecture.instructions.md")
|
|
30246
|
-
},
|
|
30247
|
-
// GitHub Issue Templates
|
|
30248
|
-
{
|
|
30249
|
-
type: "directory",
|
|
30250
|
-
path: ".github/ISSUE_TEMPLATE"
|
|
30251
|
-
},
|
|
30252
|
-
{
|
|
30253
|
-
type: "file",
|
|
30254
|
-
path: ".github/ISSUE_TEMPLATE/feature-to-spec.yml",
|
|
30255
|
-
content: readRestApiTemplateFile(".github/ISSUE_TEMPLATE/feature-to-spec.yml")
|
|
30256
|
-
},
|
|
30257
|
-
// GitHub Workflows
|
|
30258
|
-
{
|
|
30259
|
-
type: "directory",
|
|
30260
|
-
path: ".github/workflows"
|
|
30261
|
-
},
|
|
30262
|
-
{
|
|
30263
|
-
type: "file",
|
|
30264
|
-
path: ".github/workflows/assign-copilot.yml",
|
|
30265
|
-
content: readRestApiTemplateFile(".github/workflows/assign-copilot.yml")
|
|
30266
|
-
},
|
|
30267
|
-
{
|
|
30268
|
-
type: "file",
|
|
30269
|
-
path: ".github/workflows/ci.yml",
|
|
30270
|
-
content: readRestApiTemplateFile(".github/workflows/ci.yml")
|
|
30271
|
-
},
|
|
30272
|
-
// Specs directory
|
|
30273
|
-
{
|
|
30274
|
-
type: "directory",
|
|
30275
|
-
path: ".github/specs"
|
|
30276
|
-
},
|
|
30277
|
-
{
|
|
30278
|
-
type: "file",
|
|
30279
|
-
path: ".github/specs/README.md",
|
|
30280
|
-
content: readRestApiTemplateFile(".github/specs/README.md")
|
|
30281
|
-
},
|
|
30282
|
-
// VSCode configuration
|
|
30283
|
-
{
|
|
30284
|
-
type: "directory",
|
|
30285
|
-
path: ".vscode"
|
|
30286
|
-
},
|
|
30287
|
-
{
|
|
30288
|
-
type: "file",
|
|
30289
|
-
path: ".vscode/extensions.json",
|
|
30290
|
-
content: readRestApiTemplateFile(".vscode/extensions.json")
|
|
30291
|
-
},
|
|
30292
|
-
{
|
|
30293
|
-
type: "file",
|
|
30294
|
-
path: ".vscode/launch.json",
|
|
30295
|
-
content: readRestApiTemplateFile(".vscode/launch.json")
|
|
30296
|
-
},
|
|
30297
|
-
{
|
|
30298
|
-
type: "file",
|
|
30299
|
-
path: ".vscode/mcp.json",
|
|
30300
|
-
content: readRestApiTemplateFile(".vscode/mcp.json")
|
|
30301
|
-
},
|
|
30302
|
-
// Devcontainer configuration
|
|
30303
|
-
{
|
|
30304
|
-
type: "directory",
|
|
30305
|
-
path: ".devcontainer"
|
|
30306
|
-
},
|
|
30307
|
-
{
|
|
30308
|
-
type: "file",
|
|
30309
|
-
path: ".devcontainer/devcontainer.json",
|
|
30310
|
-
content: readRestApiTemplateFile(".devcontainer/devcontainer.json")
|
|
30311
|
-
}
|
|
30178
|
+
...buildCommonNodes(readRestApiTemplateFile)
|
|
30312
30179
|
]
|
|
30313
30180
|
};
|
|
30314
30181
|
return cachedRestApiStructure;
|
|
@@ -31153,6 +31020,203 @@ const initCommand = defineCommand({
|
|
|
31153
31020
|
}
|
|
31154
31021
|
});
|
|
31155
31022
|
|
|
31023
|
+
;// CONCATENATED MODULE: ./src/use-cases/lint-skill-frontmatter.ts
|
|
31024
|
+
/**
|
|
31025
|
+
* Use case for linting GitHub Copilot Agent Skill frontmatter.
|
|
31026
|
+
* Validates required and recommended fields, name format, and directory naming.
|
|
31027
|
+
*/
|
|
31028
|
+
/**
|
|
31029
|
+
* Zod schema for validating agent skill frontmatter.
|
|
31030
|
+
* Based on the agentskills.io specification.
|
|
31031
|
+
*/ const AgentSkillFrontmatterSchema = schemas_object({
|
|
31032
|
+
name: schemas_string().min(1, "Name is required").max(64, "Name must be 64 characters or fewer").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Name must contain only lowercase letters, numbers, and hyphens. It cannot start/end with a hyphen or contain consecutive hyphens."),
|
|
31033
|
+
description: schemas_string().min(1, "Description is required").max(1024, "Description must be 1024 characters or fewer").refine((s)=>s.trim().length > 0, {
|
|
31034
|
+
message: "Description cannot be empty or whitespace-only"
|
|
31035
|
+
}),
|
|
31036
|
+
license: schemas_string().optional(),
|
|
31037
|
+
compatibility: schemas_string().max(500, "Compatibility must be 500 characters or fewer").optional(),
|
|
31038
|
+
metadata: record(schemas_string(), schemas_string()).optional(),
|
|
31039
|
+
"allowed-tools": schemas_string().optional()
|
|
31040
|
+
});
|
|
31041
|
+
/**
|
|
31042
|
+
* Recommended (optional) fields that produce warnings when missing.
|
|
31043
|
+
*/ const RECOMMENDED_FIELDS = [
|
|
31044
|
+
"allowed-tools"
|
|
31045
|
+
];
|
|
31046
|
+
/**
|
|
31047
|
+
* Use case for linting skill frontmatter across a repository.
|
|
31048
|
+
*/ class LintSkillFrontmatterUseCase {
|
|
31049
|
+
gateway;
|
|
31050
|
+
constructor(gateway){
|
|
31051
|
+
this.gateway = gateway;
|
|
31052
|
+
}
|
|
31053
|
+
async execute(input) {
|
|
31054
|
+
if (!input.targetDir) {
|
|
31055
|
+
throw new Error("Target directory is required");
|
|
31056
|
+
}
|
|
31057
|
+
const skills = await this.gateway.discoverSkills(input.targetDir);
|
|
31058
|
+
const results = [];
|
|
31059
|
+
for (const skill of skills){
|
|
31060
|
+
const content = await this.gateway.readSkillFileContent(skill.filePath);
|
|
31061
|
+
const result = this.lintSkill(skill, content);
|
|
31062
|
+
results.push(result);
|
|
31063
|
+
}
|
|
31064
|
+
const totalErrors = results.reduce((sum, r)=>sum + r.diagnostics.filter((d)=>d.severity === "error").length, 0);
|
|
31065
|
+
const totalWarnings = results.reduce((sum, r)=>sum + r.diagnostics.filter((d)=>d.severity === "warning").length, 0);
|
|
31066
|
+
return {
|
|
31067
|
+
results,
|
|
31068
|
+
totalSkills: skills.length,
|
|
31069
|
+
totalErrors,
|
|
31070
|
+
totalWarnings
|
|
31071
|
+
};
|
|
31072
|
+
}
|
|
31073
|
+
lintSkill(skill, content) {
|
|
31074
|
+
let parsed = null;
|
|
31075
|
+
let diagnostics = [];
|
|
31076
|
+
try {
|
|
31077
|
+
parsed = this.gateway.parseFrontmatter(content);
|
|
31078
|
+
} catch (error) {
|
|
31079
|
+
const messagePrefix = "Invalid YAML frontmatter";
|
|
31080
|
+
const errorMessage = error instanceof Error && error.message ? `${messagePrefix}: ${error.message}` : `${messagePrefix}.`;
|
|
31081
|
+
diagnostics.push({
|
|
31082
|
+
line: 1,
|
|
31083
|
+
severity: "error",
|
|
31084
|
+
message: errorMessage
|
|
31085
|
+
});
|
|
31086
|
+
}
|
|
31087
|
+
if (!parsed) {
|
|
31088
|
+
if (diagnostics.length === 0) {
|
|
31089
|
+
const message = hasFrontmatterDelimiters(content) ? "Invalid YAML frontmatter. The content between --- delimiters could not be parsed as valid YAML." : "Missing YAML frontmatter. Skill files must begin with --- delimited YAML frontmatter.";
|
|
31090
|
+
diagnostics.push({
|
|
31091
|
+
line: 1,
|
|
31092
|
+
severity: "error",
|
|
31093
|
+
message
|
|
31094
|
+
});
|
|
31095
|
+
}
|
|
31096
|
+
return {
|
|
31097
|
+
filePath: skill.filePath,
|
|
31098
|
+
skillName: skill.skillName,
|
|
31099
|
+
diagnostics,
|
|
31100
|
+
valid: false
|
|
31101
|
+
};
|
|
31102
|
+
}
|
|
31103
|
+
const frontmatterDiagnostics = this.validateFrontmatter(parsed, skill.skillName);
|
|
31104
|
+
diagnostics = diagnostics.concat(frontmatterDiagnostics);
|
|
31105
|
+
return {
|
|
31106
|
+
filePath: skill.filePath,
|
|
31107
|
+
skillName: skill.skillName,
|
|
31108
|
+
diagnostics,
|
|
31109
|
+
valid: diagnostics.every((d)=>d.severity !== "error")
|
|
31110
|
+
};
|
|
31111
|
+
}
|
|
31112
|
+
validateFrontmatter(parsed, parentDirName) {
|
|
31113
|
+
const diagnostics = [];
|
|
31114
|
+
// Validate against Zod schema
|
|
31115
|
+
const result = AgentSkillFrontmatterSchema.safeParse(parsed.data);
|
|
31116
|
+
if (!result.success) {
|
|
31117
|
+
for (const issue of result.error.issues){
|
|
31118
|
+
const fieldName = issue.path[0]?.toString();
|
|
31119
|
+
const line = fieldName ? parsed.fieldLines.get(fieldName) ?? parsed.frontmatterStartLine : parsed.frontmatterStartLine;
|
|
31120
|
+
diagnostics.push({
|
|
31121
|
+
line,
|
|
31122
|
+
severity: "error",
|
|
31123
|
+
message: issue.message,
|
|
31124
|
+
field: fieldName
|
|
31125
|
+
});
|
|
31126
|
+
}
|
|
31127
|
+
}
|
|
31128
|
+
// Check name matches parent directory
|
|
31129
|
+
if (result.success && result.data.name !== parentDirName) {
|
|
31130
|
+
const nameLine = parsed.fieldLines.get("name") ?? parsed.frontmatterStartLine;
|
|
31131
|
+
diagnostics.push({
|
|
31132
|
+
line: nameLine,
|
|
31133
|
+
severity: "error",
|
|
31134
|
+
message: `Frontmatter name '${result.data.name}' must match parent directory name '${parentDirName}'`,
|
|
31135
|
+
field: "name"
|
|
31136
|
+
});
|
|
31137
|
+
}
|
|
31138
|
+
// Check recommended fields
|
|
31139
|
+
for (const field of RECOMMENDED_FIELDS){
|
|
31140
|
+
if (parsed.data[field] === undefined) {
|
|
31141
|
+
diagnostics.push({
|
|
31142
|
+
line: parsed.frontmatterStartLine,
|
|
31143
|
+
severity: "warning",
|
|
31144
|
+
message: `Recommended field '${field}' is missing`,
|
|
31145
|
+
field
|
|
31146
|
+
});
|
|
31147
|
+
}
|
|
31148
|
+
}
|
|
31149
|
+
return diagnostics;
|
|
31150
|
+
}
|
|
31151
|
+
}
|
|
31152
|
+
/**
|
|
31153
|
+
* Checks whether content has opening and closing --- frontmatter delimiters.
|
|
31154
|
+
*/ function hasFrontmatterDelimiters(content) {
|
|
31155
|
+
const lines = content.split("\n");
|
|
31156
|
+
if (lines[0]?.trim() !== "---") {
|
|
31157
|
+
return false;
|
|
31158
|
+
}
|
|
31159
|
+
for(let i = 1; i < lines.length; i++){
|
|
31160
|
+
if (lines[i]?.trim() === "---") {
|
|
31161
|
+
return true;
|
|
31162
|
+
}
|
|
31163
|
+
}
|
|
31164
|
+
return false;
|
|
31165
|
+
}
|
|
31166
|
+
|
|
31167
|
+
;// CONCATENATED MODULE: ./src/commands/lint.ts
|
|
31168
|
+
/**
|
|
31169
|
+
* CLI command for linting agent skill frontmatter.
|
|
31170
|
+
* Discovers skills, validates frontmatter, and reports diagnostics.
|
|
31171
|
+
*/
|
|
31172
|
+
|
|
31173
|
+
|
|
31174
|
+
|
|
31175
|
+
/**
|
|
31176
|
+
* The `lint` command for validating agent skill files.
|
|
31177
|
+
*/ const lintCommand = defineCommand({
|
|
31178
|
+
meta: {
|
|
31179
|
+
name: "lint",
|
|
31180
|
+
description: "Lint agent skill frontmatter. Validates required and recommended fields in SKILL.md files."
|
|
31181
|
+
},
|
|
31182
|
+
run: async (context)=>{
|
|
31183
|
+
const targetDir = typeof context.data?.targetDir === "string" ? context.data.targetDir : process.cwd();
|
|
31184
|
+
const gateway = createSkillLintGateway();
|
|
31185
|
+
const useCase = new LintSkillFrontmatterUseCase(gateway);
|
|
31186
|
+
const output = await useCase.execute({
|
|
31187
|
+
targetDir
|
|
31188
|
+
});
|
|
31189
|
+
if (output.totalSkills === 0) {
|
|
31190
|
+
consola.info("No skills found in .github/skills/");
|
|
31191
|
+
return;
|
|
31192
|
+
}
|
|
31193
|
+
consola.info(`Discovered ${output.totalSkills} skill(s)`);
|
|
31194
|
+
for (const result of output.results){
|
|
31195
|
+
if (result.diagnostics.length === 0) {
|
|
31196
|
+
consola.success(`${result.filePath}: OK`);
|
|
31197
|
+
continue;
|
|
31198
|
+
}
|
|
31199
|
+
for (const diagnostic of result.diagnostics){
|
|
31200
|
+
const prefix = `${result.filePath}:${diagnostic.line}`;
|
|
31201
|
+
const fieldInfo = diagnostic.field ? ` [${diagnostic.field}]` : "";
|
|
31202
|
+
if (diagnostic.severity === "error") {
|
|
31203
|
+
consola.error(`${prefix}${fieldInfo}: ${diagnostic.message}`);
|
|
31204
|
+
} else {
|
|
31205
|
+
consola.warn(`${prefix}${fieldInfo}: ${diagnostic.message}`);
|
|
31206
|
+
}
|
|
31207
|
+
}
|
|
31208
|
+
}
|
|
31209
|
+
if (output.totalErrors > 0) {
|
|
31210
|
+
throw new Error(`Skill lint failed: ${output.totalErrors} error(s), ${output.totalWarnings} warning(s)`);
|
|
31211
|
+
}
|
|
31212
|
+
if (output.totalWarnings > 0) {
|
|
31213
|
+
consola.warn(`Skill lint passed with ${output.totalWarnings} warning(s)`);
|
|
31214
|
+
} else {
|
|
31215
|
+
consola.success("All skills passed lint checks");
|
|
31216
|
+
}
|
|
31217
|
+
}
|
|
31218
|
+
});
|
|
31219
|
+
|
|
31156
31220
|
;// CONCATENATED MODULE: ./src/entities/copilot-agent.ts
|
|
31157
31221
|
/**
|
|
31158
31222
|
* Core domain entity for GitHub Copilot custom agent files.
|
|
@@ -31272,7 +31336,9 @@ You are a ${normalizedName} agent specialized in {domain/responsibility}.
|
|
|
31272
31336
|
;// CONCATENATED MODULE: ./src/entities/skill.ts
|
|
31273
31337
|
/**
|
|
31274
31338
|
* Core domain entity for GitHub Copilot Agent Skills.
|
|
31275
|
-
* Handles name normalization
|
|
31339
|
+
* Handles name normalization, SKILL.md content generation, and lint types.
|
|
31340
|
+
*/ /**
|
|
31341
|
+
* Severity levels for skill lint diagnostics.
|
|
31276
31342
|
*/ /**
|
|
31277
31343
|
* Normalizes a skill name to lowercase with hyphens.
|
|
31278
31344
|
* Handles spaces, mixed case, multiple spaces, and leading/trailing spaces.
|
|
@@ -31486,6 +31552,7 @@ const skillArgs = {
|
|
|
31486
31552
|
|
|
31487
31553
|
|
|
31488
31554
|
|
|
31555
|
+
|
|
31489
31556
|
const src_main = defineCommand({
|
|
31490
31557
|
meta: {
|
|
31491
31558
|
name: "lousy-agents",
|
|
@@ -31494,6 +31561,7 @@ const src_main = defineCommand({
|
|
|
31494
31561
|
},
|
|
31495
31562
|
subCommands: {
|
|
31496
31563
|
init: initCommand,
|
|
31564
|
+
lint: lintCommand,
|
|
31497
31565
|
new: newCommand,
|
|
31498
31566
|
"copilot-setup": copilotSetupCommand
|
|
31499
31567
|
}
|