@neyugn/agent-kits 0.3.0 → 0.3.1
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/README.md +3 -1
- package/dist/cli.js +164 -10
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
- 📜 **Workflows** — Slash commands for common tasks
|
|
41
41
|
- 🔍 **Smart Filtering** — Auto-detect techstack and optimize loaded skills
|
|
42
42
|
|
|
43
|
-
Works with **any AI tool** — Claude, Gemini, Codex, Cursor, and more.
|
|
43
|
+
Works with **any AI tool** — Claude, Gemini, Codex, Cursor, OpenCode, and more.
|
|
44
44
|
|
|
45
45
|
<br/>
|
|
46
46
|
|
|
@@ -106,6 +106,7 @@ npx @neyugn/agent-kits
|
|
|
106
106
|
| Gemini CLI | `~/.gemini/` | `.gemini/` |
|
|
107
107
|
| Codex CLI | `~/.codex/` | `.codex/` |
|
|
108
108
|
| Antigravity | `~/.agent/` | `.agent/` |
|
|
109
|
+
| OpenCode | `~/.config/opencode/` | `.opencode/` |
|
|
109
110
|
| Cursor | `~/.cursor/` | `.cursor/` |
|
|
110
111
|
|
|
111
112
|
> **Note:** On Windows, `~` is replaced with `C:\Users\<username>\`
|
|
@@ -124,6 +125,7 @@ If the installer detects an existing installation, you'll be prompted:
|
|
|
124
125
|
| Tool | Workspace Path | Global Path | Status |
|
|
125
126
|
| ----------- | ----------------- | ------------ | ------------------ |
|
|
126
127
|
| Antigravity | `.agent/skills/` | `~/.agent/` | ✅ Fully Supported |
|
|
128
|
+
| OpenCode | `.opencode/` | `~/.config/opencode/` | ✅ Fully Supported |
|
|
127
129
|
| Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ Fully Supported |
|
|
128
130
|
| Claude Code | `.claude/skills/` | `~/.claude/` | 🔜 Coming Soon |
|
|
129
131
|
| Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🔜 Coming Soon |
|
package/dist/cli.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
import boxen from "boxen";
|
|
6
6
|
import figlet from "figlet";
|
|
7
|
-
import
|
|
7
|
+
import fs5 from "fs";
|
|
8
8
|
import gradient from "gradient-string";
|
|
9
9
|
import os2 from "os";
|
|
10
|
-
import
|
|
10
|
+
import path6 from "path";
|
|
11
11
|
import pc from "picocolors";
|
|
12
12
|
|
|
13
13
|
// src/config.ts
|
|
@@ -92,6 +92,20 @@ var AI_TOOLS = [
|
|
|
92
92
|
// Cursor calls workflows "commands" in .cursor/commands/
|
|
93
93
|
available: true
|
|
94
94
|
},
|
|
95
|
+
{
|
|
96
|
+
id: "opencode",
|
|
97
|
+
name: "OpenCode",
|
|
98
|
+
icon: "\u232C",
|
|
99
|
+
path: ".opencode",
|
|
100
|
+
globalPathPattern: "~/.config/opencode",
|
|
101
|
+
rulesFile: "AGENTS.md",
|
|
102
|
+
kitRulesFile: "AGENTS.md",
|
|
103
|
+
rulesInsideKit: false,
|
|
104
|
+
// OpenCode reads AGENTS.md from project root
|
|
105
|
+
workflowsAs: "commands",
|
|
106
|
+
// OpenCode calls workflows "commands" in .opencode/commands/
|
|
107
|
+
available: true
|
|
108
|
+
},
|
|
95
109
|
{
|
|
96
110
|
id: "custom",
|
|
97
111
|
name: "Custom",
|
|
@@ -169,7 +183,7 @@ function getKitSource(kitId) {
|
|
|
169
183
|
}
|
|
170
184
|
function replaceToolPaths(content, targetPath) {
|
|
171
185
|
return content.replace(
|
|
172
|
-
/\.(agent|claude|gemini|cursor|codex)\//g,
|
|
186
|
+
/\.(agent|claude|gemini|cursor|codex|opencode)\//g,
|
|
173
187
|
`${targetPath}/`
|
|
174
188
|
);
|
|
175
189
|
}
|
|
@@ -465,6 +479,49 @@ function createCursorWorkflowTransformer() {
|
|
|
465
479
|
return new CursorWorkflowTransformer();
|
|
466
480
|
}
|
|
467
481
|
|
|
482
|
+
// src/transformers/opencode-workflow.ts
|
|
483
|
+
var OpenCodeWorkflowTransformer = class {
|
|
484
|
+
/**
|
|
485
|
+
* Transform workflow content from Agent-Kits format to OpenCode command format
|
|
486
|
+
*/
|
|
487
|
+
transform(content, context) {
|
|
488
|
+
const parsed = parseFrontmatter(content);
|
|
489
|
+
const originalData = parsed.data;
|
|
490
|
+
const commandFrontmatter = {
|
|
491
|
+
description: String(originalData.description || "")
|
|
492
|
+
};
|
|
493
|
+
const newFrontmatter = serializeFrontmatter(
|
|
494
|
+
commandFrontmatter
|
|
495
|
+
);
|
|
496
|
+
let bodyContent = parsed.content;
|
|
497
|
+
bodyContent = this.transformPaths(bodyContent, context);
|
|
498
|
+
bodyContent = this.transformTerminology(bodyContent);
|
|
499
|
+
return combineMarkdown(newFrontmatter, bodyContent);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Replace .agent/ paths with .opencode/
|
|
503
|
+
*/
|
|
504
|
+
transformPaths(content, context) {
|
|
505
|
+
const toolPath = context.aiTool?.path || ".opencode";
|
|
506
|
+
return content.replace(/\.agent\//g, `${toolPath}/`);
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Transform terminology: workflow → command
|
|
510
|
+
*/
|
|
511
|
+
transformTerminology(content) {
|
|
512
|
+
let transformed = content;
|
|
513
|
+
transformed = transformed.replace(/workflows?\//gi, "commands/");
|
|
514
|
+
transformed = transformed.replace(/\/workflow/gi, "/command");
|
|
515
|
+
transformed = transformed.replace(/workflow/gi, "command");
|
|
516
|
+
transformed = transformed.replace(/Workflow/g, "Command");
|
|
517
|
+
transformed = transformed.replace(/WORKFLOW/g, "COMMAND");
|
|
518
|
+
return transformed;
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
function createOpenCodeWorkflowTransformer() {
|
|
522
|
+
return new OpenCodeWorkflowTransformer();
|
|
523
|
+
}
|
|
524
|
+
|
|
468
525
|
// src/installers/cursor.ts
|
|
469
526
|
var CursorInstaller = class {
|
|
470
527
|
// Cursor uses "commands" instead of "workflows"
|
|
@@ -650,6 +707,101 @@ var CursorInstaller = class {
|
|
|
650
707
|
}
|
|
651
708
|
};
|
|
652
709
|
|
|
710
|
+
// src/installers/opencode.ts
|
|
711
|
+
import fs4 from "fs/promises";
|
|
712
|
+
import path5 from "path";
|
|
713
|
+
var OpenCodeInstaller = class {
|
|
714
|
+
// OpenCode uses "commands" instead of "workflows"
|
|
715
|
+
COMMANDS_FOLDER = "commands";
|
|
716
|
+
// Transformer for OpenCode command format
|
|
717
|
+
workflowTransformer = createOpenCodeWorkflowTransformer();
|
|
718
|
+
async install(options) {
|
|
719
|
+
const { aiTool, kits, targetPath } = options;
|
|
720
|
+
const results = [];
|
|
721
|
+
for (const kitId of kits) {
|
|
722
|
+
const { kitSourcePath, kit } = getKitSource(kitId);
|
|
723
|
+
const kitTargetPath = path5.join(targetPath, aiTool.path);
|
|
724
|
+
await fs4.mkdir(kitTargetPath, { recursive: true });
|
|
725
|
+
await copyDirectory(
|
|
726
|
+
kitSourcePath,
|
|
727
|
+
kitTargetPath,
|
|
728
|
+
["rules", "workflows"],
|
|
729
|
+
aiTool.path
|
|
730
|
+
);
|
|
731
|
+
await this.copyWorkflowsWithTransform(
|
|
732
|
+
kitSourcePath,
|
|
733
|
+
kitTargetPath,
|
|
734
|
+
aiTool.path
|
|
735
|
+
);
|
|
736
|
+
await copyRulesFile(
|
|
737
|
+
kitSourcePath,
|
|
738
|
+
kitTargetPath,
|
|
739
|
+
targetPath,
|
|
740
|
+
aiTool,
|
|
741
|
+
options.scope,
|
|
742
|
+
this.COMMANDS_FOLDER
|
|
743
|
+
// Replace workflows/ with commands/
|
|
744
|
+
);
|
|
745
|
+
try {
|
|
746
|
+
await copyCommonAssets(kitTargetPath, aiTool, this.COMMANDS_FOLDER);
|
|
747
|
+
} catch {
|
|
748
|
+
}
|
|
749
|
+
const agents = await countItems(path5.join(kitTargetPath, "agents"));
|
|
750
|
+
const skills = await countItems(path5.join(kitTargetPath, "skills"));
|
|
751
|
+
const commands = await countItems(
|
|
752
|
+
path5.join(kitTargetPath, this.COMMANDS_FOLDER)
|
|
753
|
+
);
|
|
754
|
+
results.push({
|
|
755
|
+
kit: kit.name,
|
|
756
|
+
agents,
|
|
757
|
+
skills,
|
|
758
|
+
workflows: commands
|
|
759
|
+
// Still called "workflows" in result for consistency
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
return results;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Copy workflows with transformation to OpenCode command format
|
|
766
|
+
*
|
|
767
|
+
* This method:
|
|
768
|
+
* 1. Reads each workflow file from the kit
|
|
769
|
+
* 2. Transforms the frontmatter to OpenCode command format
|
|
770
|
+
* 3. Replaces path references (.agent/ → .opencode/)
|
|
771
|
+
* 4. Replaces terminology (workflow → command)
|
|
772
|
+
* 5. Writes the transformed command to the commands directory
|
|
773
|
+
*/
|
|
774
|
+
async copyWorkflowsWithTransform(kitSourcePath, kitTargetPath, toolPath) {
|
|
775
|
+
const workflowsSource = path5.join(kitSourcePath, "workflows");
|
|
776
|
+
const commandsTarget = path5.join(kitTargetPath, this.COMMANDS_FOLDER);
|
|
777
|
+
try {
|
|
778
|
+
await fs4.access(workflowsSource);
|
|
779
|
+
} catch {
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
await fs4.mkdir(commandsTarget, { recursive: true });
|
|
783
|
+
const entries = await fs4.readdir(workflowsSource, { withFileTypes: true });
|
|
784
|
+
for (const entry of entries) {
|
|
785
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
const sourcePath = path5.join(workflowsSource, entry.name);
|
|
789
|
+
const targetPath = path5.join(commandsTarget, entry.name);
|
|
790
|
+
const content = await fs4.readFile(sourcePath, "utf-8");
|
|
791
|
+
const context = {
|
|
792
|
+
aiTool: { path: toolPath },
|
|
793
|
+
sourcePath,
|
|
794
|
+
targetPath
|
|
795
|
+
};
|
|
796
|
+
const transformedContent = this.workflowTransformer.transform(
|
|
797
|
+
content,
|
|
798
|
+
context
|
|
799
|
+
);
|
|
800
|
+
await fs4.writeFile(targetPath, transformedContent);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
|
|
653
805
|
// src/installers/index.ts
|
|
654
806
|
var installerRegistry = {
|
|
655
807
|
// Antigravity is the base/default installer
|
|
@@ -660,7 +812,9 @@ var installerRegistry = {
|
|
|
660
812
|
codex: new AntigravityInstaller(),
|
|
661
813
|
custom: new AntigravityInstaller(),
|
|
662
814
|
// Cursor has special handling (workflows -> commands)
|
|
663
|
-
cursor: new CursorInstaller()
|
|
815
|
+
cursor: new CursorInstaller(),
|
|
816
|
+
// OpenCode has special handling (workflows -> commands, AGENTS.md at root)
|
|
817
|
+
opencode: new OpenCodeInstaller()
|
|
664
818
|
};
|
|
665
819
|
function getInstaller(toolId) {
|
|
666
820
|
const installer = installerRegistry[toolId];
|
|
@@ -677,13 +831,13 @@ async function installKit(options) {
|
|
|
677
831
|
// src/cli.ts
|
|
678
832
|
function expandPath(inputPath) {
|
|
679
833
|
if (inputPath.startsWith("~")) {
|
|
680
|
-
return
|
|
834
|
+
return path6.join(os2.homedir(), inputPath.slice(1));
|
|
681
835
|
}
|
|
682
836
|
return inputPath;
|
|
683
837
|
}
|
|
684
838
|
function directoryExists(dirPath) {
|
|
685
839
|
try {
|
|
686
|
-
return
|
|
840
|
+
return fs5.existsSync(dirPath) && fs5.statSync(dirPath).isDirectory();
|
|
687
841
|
} catch {
|
|
688
842
|
return false;
|
|
689
843
|
}
|
|
@@ -692,7 +846,7 @@ function getInstallPath(aiTool, scope, workspacePath) {
|
|
|
692
846
|
if (scope === "global") {
|
|
693
847
|
return getGlobalPath(aiTool);
|
|
694
848
|
}
|
|
695
|
-
return
|
|
849
|
+
return path6.join(workspacePath, aiTool.path);
|
|
696
850
|
}
|
|
697
851
|
function getDisplayPath(absolutePath) {
|
|
698
852
|
const home = os2.homedir();
|
|
@@ -747,7 +901,7 @@ async function main() {
|
|
|
747
901
|
{
|
|
748
902
|
value: "workspace",
|
|
749
903
|
label: "Workspace (Project)",
|
|
750
|
-
hint: `Best for sharing with team (${
|
|
904
|
+
hint: `Best for sharing with team (${path6.join(process.cwd(), aiTool.path)})`
|
|
751
905
|
},
|
|
752
906
|
{
|
|
753
907
|
value: "global",
|
|
@@ -782,7 +936,7 @@ async function main() {
|
|
|
782
936
|
workspacePath = expandPath(pathResult);
|
|
783
937
|
}
|
|
784
938
|
const finalInstallPath = getInstallPath(aiTool, scope, workspacePath);
|
|
785
|
-
const rulesFilePath = scope === "global" || aiTool.rulesInsideKit ?
|
|
939
|
+
const rulesFilePath = scope === "global" || aiTool.rulesInsideKit ? path6.join(finalInstallPath, aiTool.rulesFile) : path6.join(workspacePath, aiTool.rulesFile);
|
|
786
940
|
if (directoryExists(finalInstallPath)) {
|
|
787
941
|
p.log.warn(
|
|
788
942
|
`${pc.yellow("\u26A0")} Existing toolkit found at: ${pc.cyan(getDisplayPath(finalInstallPath))}`
|
|
@@ -823,7 +977,7 @@ async function main() {
|
|
|
823
977
|
if (replaceResult === "replace") {
|
|
824
978
|
const s_rm = p.spinner();
|
|
825
979
|
s_rm.start("Cleaning up old files...");
|
|
826
|
-
|
|
980
|
+
fs5.rmSync(finalInstallPath, { recursive: true, force: true });
|
|
827
981
|
s_rm.stop("Cleanup complete.");
|
|
828
982
|
}
|
|
829
983
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neyugn/agent-kits",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Universal AI Agent Toolkit - Skills, Agents, and Workflows for any AI coding assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"codex",
|
|
21
21
|
"cursor",
|
|
22
22
|
"copilot",
|
|
23
|
+
"opencode",
|
|
23
24
|
"workflow",
|
|
24
25
|
"prompt",
|
|
25
26
|
"toolkit"
|