@neyugn/agent-kits 0.3.0 → 0.3.2
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 +20 -18
- package/README.vi.md +2 -2
- package/README.zh.md +2 -2
- package/dist/cli.js +300 -10
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -40,14 +40,14 @@
|
|
|
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
|
|
|
47
47
|
## 🚀 Quick Start
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
|
-
npx @neyugn/agent-kits
|
|
50
|
+
npx @neyugn/agent-kits@latest
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
That's it! The interactive installer will guide you through:
|
|
@@ -64,7 +64,7 @@ That's it! The interactive installer will guide you through:
|
|
|
64
64
|
### 🎯 One Command, Any Tool
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
npx @neyugn/agent-kits
|
|
67
|
+
npx @neyugn/agent-kits@latest
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
```
|
|
@@ -100,13 +100,14 @@ npx @neyugn/agent-kits
|
|
|
100
100
|
|
|
101
101
|
**Global Paths by Tool:**
|
|
102
102
|
|
|
103
|
-
| Tool | Global Path
|
|
104
|
-
| ----------- |
|
|
105
|
-
| Claude Code | `~/.claude/`
|
|
106
|
-
| Gemini CLI | `~/.gemini/`
|
|
107
|
-
| Codex CLI | `~/.codex/`
|
|
108
|
-
| Antigravity | `~/.agent/`
|
|
109
|
-
|
|
|
103
|
+
| Tool | Global Path | Workspace Path |
|
|
104
|
+
| ----------- | --------------------- | -------------- |
|
|
105
|
+
| Claude Code | `~/.claude/` | `.claude/` |
|
|
106
|
+
| Gemini CLI | `~/.gemini/` | `.gemini/` |
|
|
107
|
+
| Codex CLI | `~/.codex/` | `.codex/` |
|
|
108
|
+
| Antigravity | `~/.agent/` | `.agent/` |
|
|
109
|
+
| OpenCode | `~/.config/opencode/` | `.opencode/` |
|
|
110
|
+
| Cursor | `~/.cursor/` | `.cursor/` |
|
|
110
111
|
|
|
111
112
|
> **Note:** On Windows, `~` is replaced with `C:\Users\<username>\`
|
|
112
113
|
|
|
@@ -121,14 +122,15 @@ If the installer detects an existing installation, you'll be prompted:
|
|
|
121
122
|
|
|
122
123
|
### 🔌 Universal Compatibility
|
|
123
124
|
|
|
124
|
-
| Tool | Workspace Path | Global Path
|
|
125
|
-
| ----------- | ----------------- |
|
|
126
|
-
| Antigravity | `.agent/skills/` | `~/.agent/`
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
125
|
+
| Tool | Workspace Path | Global Path | Status |
|
|
126
|
+
| ----------- | ----------------- | --------------------- | ------------------ |
|
|
127
|
+
| Antigravity | `.agent/skills/` | `~/.agent/` | ✅ Fully Supported |
|
|
128
|
+
| OpenCode | `.opencode/` | `~/.config/opencode/` | ✅ Fully Supported |
|
|
129
|
+
| Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ Fully Supported |
|
|
130
|
+
| Claude Code | `.claude/skills/` | `~/.claude/` | 🔜 Coming Soon |
|
|
131
|
+
| Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🔜 Coming Soon |
|
|
132
|
+
| Codex CLI | `.codex/skills/` | `~/.codex/` | 🔜 Coming Soon |
|
|
133
|
+
| Custom | Configurable | `~/.ai/` | 🔜 Coming Soon |
|
|
132
134
|
|
|
133
135
|
> **Note:** Tools marked as 🔜 Coming Soon are planned for future releases. The infrastructure is ready, but these tools require additional testing and configuration.
|
|
134
136
|
|
package/README.vi.md
CHANGED
|
@@ -39,7 +39,7 @@ Hoạt động với **mọi công cụ AI** — Claude, Gemini, Codex, Cursor,
|
|
|
39
39
|
## 🚀 Bắt đầu nhanh
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
npx @neyugn/agent-kits
|
|
42
|
+
npx @neyugn/agent-kits@latest
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
Đó là tất cả! Installer tương tác sẽ hướng dẫn bạn:
|
|
@@ -56,7 +56,7 @@ npx @neyugn/agent-kits
|
|
|
56
56
|
### 🎯 Một lệnh, mọi công cụ
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npx @neyugn/agent-kits
|
|
59
|
+
npx @neyugn/agent-kits@latest
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
```
|
package/README.zh.md
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
## 🚀 快速开始
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
npx @neyugn/agent-kits
|
|
42
|
+
npx @neyugn/agent-kits@latest
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
就这样!交互式安装程序将引导您:
|
|
@@ -56,7 +56,7 @@ npx @neyugn/agent-kits
|
|
|
56
56
|
### 🎯 一条命令,任何工具
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npx @neyugn/agent-kits
|
|
59
|
+
npx @neyugn/agent-kits@latest
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
```
|
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,139 @@ function createCursorWorkflowTransformer() {
|
|
|
465
479
|
return new CursorWorkflowTransformer();
|
|
466
480
|
}
|
|
467
481
|
|
|
482
|
+
// src/transformers/opencode-agent.ts
|
|
483
|
+
var TOOL_NAME_MAP = {
|
|
484
|
+
read: "read",
|
|
485
|
+
write: "write",
|
|
486
|
+
edit: "edit",
|
|
487
|
+
bash: "bash",
|
|
488
|
+
grep: "grep",
|
|
489
|
+
glob: "glob",
|
|
490
|
+
agent: "agent"
|
|
491
|
+
};
|
|
492
|
+
var OpenCodeAgentTransformer = class {
|
|
493
|
+
/**
|
|
494
|
+
* Transform agent content from Agent-Kits format to OpenCode agent format
|
|
495
|
+
*/
|
|
496
|
+
transform(content, context) {
|
|
497
|
+
const parsed = parseFrontmatter(content);
|
|
498
|
+
const originalData = parsed.data;
|
|
499
|
+
const toolsRecord = this.parseToolsToRecord(originalData.tools);
|
|
500
|
+
const opencodeFrontmatter = {
|
|
501
|
+
description: originalData.description,
|
|
502
|
+
...originalData.model && { model: originalData.model },
|
|
503
|
+
...Object.keys(toolsRecord).length > 0 && { tools: toolsRecord }
|
|
504
|
+
};
|
|
505
|
+
const newFrontmatter = this.serializeOpenCodeFrontmatter(opencodeFrontmatter);
|
|
506
|
+
let bodyContent = parsed.content;
|
|
507
|
+
bodyContent = this.transformPaths(bodyContent, context);
|
|
508
|
+
return combineMarkdown(newFrontmatter, bodyContent);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Parse comma-separated tools string into a record of { toolName: boolean }
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* "Read, Grep, Glob, Bash, Edit, Write" →
|
|
515
|
+
* { read: true, grep: true, glob: true, bash: true, edit: true, write: true }
|
|
516
|
+
*/
|
|
517
|
+
parseToolsToRecord(toolsString) {
|
|
518
|
+
if (!toolsString) return {};
|
|
519
|
+
const tools = {};
|
|
520
|
+
const toolNames = toolsString.split(",").map((t) => t.trim().toLowerCase());
|
|
521
|
+
for (const toolName of toolNames) {
|
|
522
|
+
const mappedName = TOOL_NAME_MAP[toolName] || toolName;
|
|
523
|
+
tools[mappedName] = true;
|
|
524
|
+
}
|
|
525
|
+
return tools;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Custom serializer for OpenCode frontmatter
|
|
529
|
+
*
|
|
530
|
+
* OpenCode expects tools as a nested YAML map:
|
|
531
|
+
* ```yaml
|
|
532
|
+
* tools:
|
|
533
|
+
* read: true
|
|
534
|
+
* write: true
|
|
535
|
+
* ```
|
|
536
|
+
*
|
|
537
|
+
* The standard serializeFrontmatter outputs flat key-value pairs,
|
|
538
|
+
* so we need custom handling for the `tools` field.
|
|
539
|
+
*/
|
|
540
|
+
serializeOpenCodeFrontmatter(data) {
|
|
541
|
+
const lines = ["---"];
|
|
542
|
+
if (data.description) {
|
|
543
|
+
lines.push(`description: ${data.description}`);
|
|
544
|
+
}
|
|
545
|
+
if (data.model) {
|
|
546
|
+
lines.push(`model: ${data.model}`);
|
|
547
|
+
}
|
|
548
|
+
if (data.mode) {
|
|
549
|
+
lines.push(`mode: ${data.mode}`);
|
|
550
|
+
}
|
|
551
|
+
if (data.tools && Object.keys(data.tools).length > 0) {
|
|
552
|
+
lines.push("tools:");
|
|
553
|
+
for (const [tool, enabled] of Object.entries(data.tools)) {
|
|
554
|
+
lines.push(` ${tool}: ${enabled}`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
lines.push("---");
|
|
558
|
+
return lines.join("\n");
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Replace .agent/ paths with .opencode/
|
|
562
|
+
*/
|
|
563
|
+
transformPaths(content, context) {
|
|
564
|
+
const toolPath = context.aiTool?.path || ".opencode";
|
|
565
|
+
return content.replace(/\.agent\//g, `${toolPath}/`);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
function createOpenCodeAgentTransformer() {
|
|
569
|
+
return new OpenCodeAgentTransformer();
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// src/transformers/opencode-workflow.ts
|
|
573
|
+
var OpenCodeWorkflowTransformer = class {
|
|
574
|
+
/**
|
|
575
|
+
* Transform workflow content from Agent-Kits format to OpenCode command format
|
|
576
|
+
*/
|
|
577
|
+
transform(content, context) {
|
|
578
|
+
const parsed = parseFrontmatter(content);
|
|
579
|
+
const originalData = parsed.data;
|
|
580
|
+
const commandFrontmatter = {
|
|
581
|
+
description: String(originalData.description || "")
|
|
582
|
+
};
|
|
583
|
+
const newFrontmatter = serializeFrontmatter(
|
|
584
|
+
commandFrontmatter
|
|
585
|
+
);
|
|
586
|
+
let bodyContent = parsed.content;
|
|
587
|
+
bodyContent = this.transformPaths(bodyContent, context);
|
|
588
|
+
bodyContent = this.transformTerminology(bodyContent);
|
|
589
|
+
return combineMarkdown(newFrontmatter, bodyContent);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Replace .agent/ paths with .opencode/
|
|
593
|
+
*/
|
|
594
|
+
transformPaths(content, context) {
|
|
595
|
+
const toolPath = context.aiTool?.path || ".opencode";
|
|
596
|
+
return content.replace(/\.agent\//g, `${toolPath}/`);
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Transform terminology: workflow → command
|
|
600
|
+
*/
|
|
601
|
+
transformTerminology(content) {
|
|
602
|
+
let transformed = content;
|
|
603
|
+
transformed = transformed.replace(/workflows?\//gi, "commands/");
|
|
604
|
+
transformed = transformed.replace(/\/workflow/gi, "/command");
|
|
605
|
+
transformed = transformed.replace(/workflow/gi, "command");
|
|
606
|
+
transformed = transformed.replace(/Workflow/g, "Command");
|
|
607
|
+
transformed = transformed.replace(/WORKFLOW/g, "COMMAND");
|
|
608
|
+
return transformed;
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
function createOpenCodeWorkflowTransformer() {
|
|
612
|
+
return new OpenCodeWorkflowTransformer();
|
|
613
|
+
}
|
|
614
|
+
|
|
468
615
|
// src/installers/cursor.ts
|
|
469
616
|
var CursorInstaller = class {
|
|
470
617
|
// Cursor uses "commands" instead of "workflows"
|
|
@@ -650,6 +797,147 @@ var CursorInstaller = class {
|
|
|
650
797
|
}
|
|
651
798
|
};
|
|
652
799
|
|
|
800
|
+
// src/installers/opencode.ts
|
|
801
|
+
import fs4 from "fs/promises";
|
|
802
|
+
import path5 from "path";
|
|
803
|
+
var OpenCodeInstaller = class {
|
|
804
|
+
// OpenCode uses "commands" instead of "workflows"
|
|
805
|
+
COMMANDS_FOLDER = "commands";
|
|
806
|
+
// Transformers for OpenCode-specific formats
|
|
807
|
+
agentTransformer = createOpenCodeAgentTransformer();
|
|
808
|
+
workflowTransformer = createOpenCodeWorkflowTransformer();
|
|
809
|
+
async install(options) {
|
|
810
|
+
const { aiTool, kits, targetPath } = options;
|
|
811
|
+
const results = [];
|
|
812
|
+
for (const kitId of kits) {
|
|
813
|
+
const { kitSourcePath, kit } = getKitSource(kitId);
|
|
814
|
+
const kitTargetPath = path5.join(targetPath, aiTool.path);
|
|
815
|
+
await fs4.mkdir(kitTargetPath, { recursive: true });
|
|
816
|
+
await copyDirectory(
|
|
817
|
+
kitSourcePath,
|
|
818
|
+
kitTargetPath,
|
|
819
|
+
["rules", "workflows", "agents"],
|
|
820
|
+
aiTool.path
|
|
821
|
+
);
|
|
822
|
+
await this.copyAgentsWithTransform(
|
|
823
|
+
kitSourcePath,
|
|
824
|
+
kitTargetPath,
|
|
825
|
+
aiTool.path
|
|
826
|
+
);
|
|
827
|
+
await this.copyWorkflowsWithTransform(
|
|
828
|
+
kitSourcePath,
|
|
829
|
+
kitTargetPath,
|
|
830
|
+
aiTool.path
|
|
831
|
+
);
|
|
832
|
+
await copyRulesFile(
|
|
833
|
+
kitSourcePath,
|
|
834
|
+
kitTargetPath,
|
|
835
|
+
targetPath,
|
|
836
|
+
aiTool,
|
|
837
|
+
options.scope,
|
|
838
|
+
this.COMMANDS_FOLDER
|
|
839
|
+
// Replace workflows/ with commands/
|
|
840
|
+
);
|
|
841
|
+
try {
|
|
842
|
+
await copyCommonAssets(kitTargetPath, aiTool, this.COMMANDS_FOLDER);
|
|
843
|
+
} catch {
|
|
844
|
+
}
|
|
845
|
+
const agents = await countItems(path5.join(kitTargetPath, "agents"));
|
|
846
|
+
const skills = await countItems(path5.join(kitTargetPath, "skills"));
|
|
847
|
+
const commands = await countItems(
|
|
848
|
+
path5.join(kitTargetPath, this.COMMANDS_FOLDER)
|
|
849
|
+
);
|
|
850
|
+
results.push({
|
|
851
|
+
kit: kit.name,
|
|
852
|
+
agents,
|
|
853
|
+
skills,
|
|
854
|
+
workflows: commands
|
|
855
|
+
// Still called "workflows" in result for consistency
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
return results;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Copy agents with transformation to OpenCode format
|
|
862
|
+
*
|
|
863
|
+
* This method:
|
|
864
|
+
* 1. Reads each agent file from the kit
|
|
865
|
+
* 2. Replaces tool path references (.agent/ → .opencode/)
|
|
866
|
+
* 3. Transforms the frontmatter `tools` field from string to record
|
|
867
|
+
* 4. Removes unnecessary fields (name, skills, tier)
|
|
868
|
+
* 5. Writes the transformed agent to the target directory
|
|
869
|
+
*/
|
|
870
|
+
async copyAgentsWithTransform(kitSourcePath, kitTargetPath, toolPath) {
|
|
871
|
+
const agentsSource = path5.join(kitSourcePath, "agents");
|
|
872
|
+
const agentsTarget = path5.join(kitTargetPath, "agents");
|
|
873
|
+
try {
|
|
874
|
+
await fs4.access(agentsSource);
|
|
875
|
+
} catch {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
await fs4.mkdir(agentsTarget, { recursive: true });
|
|
879
|
+
const entries = await fs4.readdir(agentsSource, { withFileTypes: true });
|
|
880
|
+
for (const entry of entries) {
|
|
881
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
const sourcePath = path5.join(agentsSource, entry.name);
|
|
885
|
+
const targetPath = path5.join(agentsTarget, entry.name);
|
|
886
|
+
let content = await fs4.readFile(sourcePath, "utf-8");
|
|
887
|
+
content = replaceToolPaths(content, toolPath);
|
|
888
|
+
const context = {
|
|
889
|
+
aiTool: { path: toolPath },
|
|
890
|
+
sourcePath,
|
|
891
|
+
targetPath
|
|
892
|
+
};
|
|
893
|
+
const transformedContent = this.agentTransformer.transform(
|
|
894
|
+
content,
|
|
895
|
+
context
|
|
896
|
+
);
|
|
897
|
+
await fs4.writeFile(targetPath, transformedContent);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Copy workflows with transformation to OpenCode command format
|
|
902
|
+
*
|
|
903
|
+
* This method:
|
|
904
|
+
* 1. Reads each workflow file from the kit
|
|
905
|
+
* 2. Transforms the frontmatter to OpenCode command format
|
|
906
|
+
* 3. Replaces path references (.agent/ → .opencode/)
|
|
907
|
+
* 4. Replaces terminology (workflow → command)
|
|
908
|
+
* 5. Writes the transformed command to the commands directory
|
|
909
|
+
*/
|
|
910
|
+
async copyWorkflowsWithTransform(kitSourcePath, kitTargetPath, toolPath) {
|
|
911
|
+
const workflowsSource = path5.join(kitSourcePath, "workflows");
|
|
912
|
+
const commandsTarget = path5.join(kitTargetPath, this.COMMANDS_FOLDER);
|
|
913
|
+
try {
|
|
914
|
+
await fs4.access(workflowsSource);
|
|
915
|
+
} catch {
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
await fs4.mkdir(commandsTarget, { recursive: true });
|
|
919
|
+
const entries = await fs4.readdir(workflowsSource, { withFileTypes: true });
|
|
920
|
+
for (const entry of entries) {
|
|
921
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
const sourcePath = path5.join(workflowsSource, entry.name);
|
|
925
|
+
const targetPath = path5.join(commandsTarget, entry.name);
|
|
926
|
+
const content = await fs4.readFile(sourcePath, "utf-8");
|
|
927
|
+
const context = {
|
|
928
|
+
aiTool: { path: toolPath },
|
|
929
|
+
sourcePath,
|
|
930
|
+
targetPath
|
|
931
|
+
};
|
|
932
|
+
const transformedContent = this.workflowTransformer.transform(
|
|
933
|
+
content,
|
|
934
|
+
context
|
|
935
|
+
);
|
|
936
|
+
await fs4.writeFile(targetPath, transformedContent);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
|
|
653
941
|
// src/installers/index.ts
|
|
654
942
|
var installerRegistry = {
|
|
655
943
|
// Antigravity is the base/default installer
|
|
@@ -660,7 +948,9 @@ var installerRegistry = {
|
|
|
660
948
|
codex: new AntigravityInstaller(),
|
|
661
949
|
custom: new AntigravityInstaller(),
|
|
662
950
|
// Cursor has special handling (workflows -> commands)
|
|
663
|
-
cursor: new CursorInstaller()
|
|
951
|
+
cursor: new CursorInstaller(),
|
|
952
|
+
// OpenCode has special handling (workflows -> commands, AGENTS.md at root)
|
|
953
|
+
opencode: new OpenCodeInstaller()
|
|
664
954
|
};
|
|
665
955
|
function getInstaller(toolId) {
|
|
666
956
|
const installer = installerRegistry[toolId];
|
|
@@ -677,13 +967,13 @@ async function installKit(options) {
|
|
|
677
967
|
// src/cli.ts
|
|
678
968
|
function expandPath(inputPath) {
|
|
679
969
|
if (inputPath.startsWith("~")) {
|
|
680
|
-
return
|
|
970
|
+
return path6.join(os2.homedir(), inputPath.slice(1));
|
|
681
971
|
}
|
|
682
972
|
return inputPath;
|
|
683
973
|
}
|
|
684
974
|
function directoryExists(dirPath) {
|
|
685
975
|
try {
|
|
686
|
-
return
|
|
976
|
+
return fs5.existsSync(dirPath) && fs5.statSync(dirPath).isDirectory();
|
|
687
977
|
} catch {
|
|
688
978
|
return false;
|
|
689
979
|
}
|
|
@@ -692,7 +982,7 @@ function getInstallPath(aiTool, scope, workspacePath) {
|
|
|
692
982
|
if (scope === "global") {
|
|
693
983
|
return getGlobalPath(aiTool);
|
|
694
984
|
}
|
|
695
|
-
return
|
|
985
|
+
return path6.join(workspacePath, aiTool.path);
|
|
696
986
|
}
|
|
697
987
|
function getDisplayPath(absolutePath) {
|
|
698
988
|
const home = os2.homedir();
|
|
@@ -747,7 +1037,7 @@ async function main() {
|
|
|
747
1037
|
{
|
|
748
1038
|
value: "workspace",
|
|
749
1039
|
label: "Workspace (Project)",
|
|
750
|
-
hint: `Best for sharing with team (${
|
|
1040
|
+
hint: `Best for sharing with team (${path6.join(process.cwd(), aiTool.path)})`
|
|
751
1041
|
},
|
|
752
1042
|
{
|
|
753
1043
|
value: "global",
|
|
@@ -782,7 +1072,7 @@ async function main() {
|
|
|
782
1072
|
workspacePath = expandPath(pathResult);
|
|
783
1073
|
}
|
|
784
1074
|
const finalInstallPath = getInstallPath(aiTool, scope, workspacePath);
|
|
785
|
-
const rulesFilePath = scope === "global" || aiTool.rulesInsideKit ?
|
|
1075
|
+
const rulesFilePath = scope === "global" || aiTool.rulesInsideKit ? path6.join(finalInstallPath, aiTool.rulesFile) : path6.join(workspacePath, aiTool.rulesFile);
|
|
786
1076
|
if (directoryExists(finalInstallPath)) {
|
|
787
1077
|
p.log.warn(
|
|
788
1078
|
`${pc.yellow("\u26A0")} Existing toolkit found at: ${pc.cyan(getDisplayPath(finalInstallPath))}`
|
|
@@ -823,7 +1113,7 @@ async function main() {
|
|
|
823
1113
|
if (replaceResult === "replace") {
|
|
824
1114
|
const s_rm = p.spinner();
|
|
825
1115
|
s_rm.start("Cleaning up old files...");
|
|
826
|
-
|
|
1116
|
+
fs5.rmSync(finalInstallPath, { recursive: true, force: true });
|
|
827
1117
|
s_rm.stop("Cleanup complete.");
|
|
828
1118
|
}
|
|
829
1119
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neyugn/agent-kits",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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"
|