@dk/jolly 0.1.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/.env.example +3 -0
- package/.mcp.json +7 -0
- package/.sisyphus/boulder.json +13 -0
- package/.sisyphus/notepads/saleor-agent-cli/decisions.md +11 -0
- package/.sisyphus/notepads/saleor-agent-cli/issues.md +6 -0
- package/.sisyphus/notepads/saleor-agent-cli/learnings.md +6 -0
- package/.sisyphus/plans/saleor-agent-cli.md +600 -0
- package/AGENTS.md +46 -0
- package/README.md +121 -0
- package/bun.lock +65 -0
- package/bunfig.toml +8 -0
- package/dist/agent.js +259 -0
- package/dist/bootstrap.js +492 -0
- package/dist/index.js +5798 -0
- package/package.json +29 -0
- package/src/agents/index.ts +1 -0
- package/src/agents/setup.ts +210 -0
- package/src/api/auth.ts +21 -0
- package/src/api/client.ts +78 -0
- package/src/api/endpoints.ts +8 -0
- package/src/api/index.ts +4 -0
- package/src/cli/agent.ts +26 -0
- package/src/cli/bootstrap.ts +24 -0
- package/src/cli/commands/agent.ts +40 -0
- package/src/cli/commands/app.ts +51 -0
- package/src/cli/commands/config.ts +38 -0
- package/src/cli/commands/store.ts +65 -0
- package/src/cli/index.ts +16 -0
- package/src/commands/app.ts +126 -0
- package/src/commands/index.ts +1 -0
- package/src/commands/store.ts +64 -0
- package/src/test/command-handlers.test.ts +227 -0
- package/src/test/e2e-flows.test.ts +212 -0
- package/src/test/entry-points.test.ts +123 -0
- package/src/test/error-handling.test.ts +137 -0
- package/src/test/helpers.ts +49 -0
- package/src/test/index.ts +1 -0
- package/src/test/mocks.ts +132 -0
- package/src/test/setup.ts +29 -0
- package/src/tui/components.ts +77 -0
- package/src/tui/index.ts +3 -0
- package/src/tui/renderer.ts +34 -0
- package/src/tui/theme.ts +38 -0
- package/tsconfig.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Jolly - Saleor CLI for AI Agents
|
|
2
|
+
|
|
3
|
+
Bootstraps Saleor projects and configures AI agents with Saleor skills.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @saleor/jolly
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
### Store Management
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Create a new Saleor Cloud store
|
|
17
|
+
jolly store create --name my-store
|
|
18
|
+
|
|
19
|
+
# Create with specific region
|
|
20
|
+
jolly store create --name my-store --region eu-west-1
|
|
21
|
+
|
|
22
|
+
# List your stores
|
|
23
|
+
jolly store list
|
|
24
|
+
|
|
25
|
+
# Create environment
|
|
26
|
+
jolly store env create --store <store-id> --name production
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### App Scaffolding
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Create a dashboard extension
|
|
33
|
+
jolly app create --name my-dashboard --type dashboard-extension
|
|
34
|
+
|
|
35
|
+
# Create a payment app (hosted)
|
|
36
|
+
jolly app create --name my-payment --type payment --provider stripe
|
|
37
|
+
|
|
38
|
+
# Create a webhook handler
|
|
39
|
+
jolly app create --name my-webhook --type webhook
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Agent Setup
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Setup AI agent with Saleor skills and MCP
|
|
46
|
+
jolly agent setup
|
|
47
|
+
|
|
48
|
+
# Install skills only
|
|
49
|
+
jolly agent skills install
|
|
50
|
+
|
|
51
|
+
# Setup in specific directory
|
|
52
|
+
jolly agent setup --path /my/project
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Configuration
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Deploy configuration to store
|
|
59
|
+
jolly config deploy --store <store-id>
|
|
60
|
+
|
|
61
|
+
# Introspect current configuration
|
|
62
|
+
jolly config introspect --store <store-id>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## npm Entry Points
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Bootstrap new Saleor project
|
|
69
|
+
npm create @saleor/jolly my-project
|
|
70
|
+
|
|
71
|
+
# Configure AI agent for Saleor
|
|
72
|
+
npm init @saleor/jolly
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Environment Variables
|
|
76
|
+
|
|
77
|
+
You can set environment variables via a `.env` file:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Copy the example file
|
|
81
|
+
cp .env.example .env
|
|
82
|
+
|
|
83
|
+
# Edit with your token
|
|
84
|
+
SALEOR_CLOUD_TOKEN=your-token-here
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or export directly:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
export SALEOR_CLOUD_TOKEN=your-token-here
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Get your token at: https://cloud.saleor.io/settings/api-tokens
|
|
94
|
+
|
|
95
|
+
## Development
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Install dependencies
|
|
99
|
+
bun install
|
|
100
|
+
|
|
101
|
+
# Build
|
|
102
|
+
bun run build
|
|
103
|
+
|
|
104
|
+
# Run tests
|
|
105
|
+
bun test
|
|
106
|
+
|
|
107
|
+
# Type check
|
|
108
|
+
bun run typecheck
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Architecture
|
|
112
|
+
|
|
113
|
+
- **CLI Framework**: yargs for argument parsing
|
|
114
|
+
- **Runtime**: Bun
|
|
115
|
+
- **API Client**: Direct Saleor Cloud API integration
|
|
116
|
+
- **Agent Skills**: saleor/agent-skills from GitHub
|
|
117
|
+
- **MCP**: Official saleor-mcp at mcp.saleor.app
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT
|
package/bun.lock
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "@saleor/jolly",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"dotenv": "^17.4.0",
|
|
9
|
+
"yargs": "^17.7.2",
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@types/yargs": "^17.0.32",
|
|
13
|
+
"bun-types": "^1.3.11",
|
|
14
|
+
"typescript": "^5.4.0",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
"packages": {
|
|
19
|
+
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
|
20
|
+
|
|
21
|
+
"@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="],
|
|
22
|
+
|
|
23
|
+
"@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
|
|
24
|
+
|
|
25
|
+
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
26
|
+
|
|
27
|
+
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
|
28
|
+
|
|
29
|
+
"bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
|
|
30
|
+
|
|
31
|
+
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
|
|
32
|
+
|
|
33
|
+
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
34
|
+
|
|
35
|
+
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
|
36
|
+
|
|
37
|
+
"dotenv": ["dotenv@17.4.0", "", {}, "sha512-kCKF62fwtzwYm0IGBNjRUjtJgMfGapII+FslMHIjMR5KTnwEmBmWLDRSnc3XSNP8bNy34tekgQyDT0hr7pERRQ=="],
|
|
38
|
+
|
|
39
|
+
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
40
|
+
|
|
41
|
+
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
|
42
|
+
|
|
43
|
+
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
|
44
|
+
|
|
45
|
+
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
|
46
|
+
|
|
47
|
+
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
|
|
48
|
+
|
|
49
|
+
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
50
|
+
|
|
51
|
+
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
52
|
+
|
|
53
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
54
|
+
|
|
55
|
+
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
|
56
|
+
|
|
57
|
+
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
|
58
|
+
|
|
59
|
+
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
|
|
60
|
+
|
|
61
|
+
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
|
|
62
|
+
|
|
63
|
+
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
|
64
|
+
}
|
|
65
|
+
}
|
package/bunfig.toml
ADDED
package/dist/agent.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// src/agents/setup.ts
|
|
5
|
+
import { writeFileSync, mkdirSync, existsSync } from "fs";
|
|
6
|
+
import { spawnSync } from "child_process";
|
|
7
|
+
import { join } from "path";
|
|
8
|
+
|
|
9
|
+
// src/tui/theme.ts
|
|
10
|
+
var theme = {
|
|
11
|
+
reset: "\x1B[0m",
|
|
12
|
+
bold: "\x1B[1m",
|
|
13
|
+
dim: "\x1B[2m",
|
|
14
|
+
italic: "\x1B[3m",
|
|
15
|
+
underline: "\x1B[4m",
|
|
16
|
+
fg: {
|
|
17
|
+
black: "\x1B[30m",
|
|
18
|
+
red: "\x1B[31m",
|
|
19
|
+
green: "\x1B[32m",
|
|
20
|
+
yellow: "\x1B[33m",
|
|
21
|
+
blue: "\x1B[34m",
|
|
22
|
+
magenta: "\x1B[35m",
|
|
23
|
+
cyan: "\x1B[36m",
|
|
24
|
+
white: "\x1B[37m",
|
|
25
|
+
gray: "\x1B[90m",
|
|
26
|
+
brightBlack: "\x1B[30;1m",
|
|
27
|
+
brightRed: "\x1B[31;1m",
|
|
28
|
+
brightGreen: "\x1B[32;1m",
|
|
29
|
+
brightYellow: "\x1B[33;1m",
|
|
30
|
+
brightBlue: "\x1B[34;1m",
|
|
31
|
+
brightMagenta: "\x1B[35;1m",
|
|
32
|
+
brightCyan: "\x1B[36;1m",
|
|
33
|
+
brightWhite: "\x1B[37;1m"
|
|
34
|
+
},
|
|
35
|
+
bg: {
|
|
36
|
+
black: "\x1B[40m",
|
|
37
|
+
red: "\x1B[41m",
|
|
38
|
+
green: "\x1B[42m",
|
|
39
|
+
yellow: "\x1B[43m",
|
|
40
|
+
blue: "\x1B[44m",
|
|
41
|
+
magenta: "\x1B[45m",
|
|
42
|
+
cyan: "\x1B[46m",
|
|
43
|
+
white: "\x1B[47m"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/tui/components.ts
|
|
48
|
+
function text(content, color) {
|
|
49
|
+
return `${color || theme.fg.white}${content}${theme.reset}`;
|
|
50
|
+
}
|
|
51
|
+
function success(msg) {
|
|
52
|
+
return text(msg, theme.fg.green);
|
|
53
|
+
}
|
|
54
|
+
function info(msg) {
|
|
55
|
+
return text(msg, theme.fg.cyan);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/agents/setup.ts
|
|
59
|
+
var AGENT_PATHS = {
|
|
60
|
+
opencode: {
|
|
61
|
+
skills: ".agents/skills",
|
|
62
|
+
agentsMd: "AGENTS.md",
|
|
63
|
+
mcpJson: ".mcp.json"
|
|
64
|
+
},
|
|
65
|
+
claude: {
|
|
66
|
+
skills: ".claude/skills",
|
|
67
|
+
agentsMd: "CLAUDE.md",
|
|
68
|
+
mcpJson: ".mcp.json"
|
|
69
|
+
},
|
|
70
|
+
openclaw: {
|
|
71
|
+
skills: ".openclaw/skills",
|
|
72
|
+
agentsMd: "AGENTS.md",
|
|
73
|
+
mcpJson: ".mcp.json"
|
|
74
|
+
},
|
|
75
|
+
nanobot: {
|
|
76
|
+
skills: ".nanobot/skills",
|
|
77
|
+
agentsMd: "AGENTS.md",
|
|
78
|
+
mcpJson: ".mcp.json"
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var SKILLS = [
|
|
82
|
+
"saleor-app",
|
|
83
|
+
"saleor-configurator",
|
|
84
|
+
"saleor-core",
|
|
85
|
+
"saleor-storefront"
|
|
86
|
+
];
|
|
87
|
+
async function setupAgent(projectPath = ".") {
|
|
88
|
+
info("Detecting AI agents...");
|
|
89
|
+
const detectedAgents = detectAgents(projectPath);
|
|
90
|
+
if (detectedAgents.length === 0) {
|
|
91
|
+
info("No AI agents detected. Installing skills anyway...");
|
|
92
|
+
installSkills(projectPath, "opencode");
|
|
93
|
+
createAgentsMd(projectPath);
|
|
94
|
+
createMcpConfig(projectPath);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
info(`Detected agents: ${detectedAgents.map((a) => a.name).join(", ")}
|
|
98
|
+
`);
|
|
99
|
+
for (const agent of detectedAgents) {
|
|
100
|
+
info(`Configuring ${agent.name}...`);
|
|
101
|
+
installSkills(projectPath, agent.name);
|
|
102
|
+
createAgentsMd(projectPath, agent.name);
|
|
103
|
+
createMcpConfig(projectPath);
|
|
104
|
+
success(` ${agent.name} configured!`);
|
|
105
|
+
}
|
|
106
|
+
success(`
|
|
107
|
+
Agent setup complete!`);
|
|
108
|
+
info(`
|
|
109
|
+
Skills installed: ` + SKILLS.join(", "));
|
|
110
|
+
info("AGENTS.md created with Saleor conventions");
|
|
111
|
+
info(".mcp.json configured for saleor-mcp");
|
|
112
|
+
}
|
|
113
|
+
async function installSkillsCommand(projectPath = ".") {
|
|
114
|
+
info("Installing Saleor agent skills...");
|
|
115
|
+
info("Skills: " + SKILLS.join(", "));
|
|
116
|
+
const detectedAgents = detectAgents(projectPath);
|
|
117
|
+
if (detectedAgents.length === 0) {
|
|
118
|
+
installSkills(projectPath, "opencode");
|
|
119
|
+
} else {
|
|
120
|
+
for (const agent of detectedAgents) {
|
|
121
|
+
installSkills(projectPath, agent.name);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
success(`
|
|
125
|
+
Skills installed successfully!`);
|
|
126
|
+
}
|
|
127
|
+
function detectAgents(projectPath) {
|
|
128
|
+
const detected = [];
|
|
129
|
+
const filesToCheck = [
|
|
130
|
+
{ name: "opencode", file: ".agents/skills" },
|
|
131
|
+
{ name: "claude", file: ".claude" },
|
|
132
|
+
{ name: "openclaw", file: ".openclaw" },
|
|
133
|
+
{ name: "nanobot", file: ".nanobot" }
|
|
134
|
+
];
|
|
135
|
+
for (const { name, file } of filesToCheck) {
|
|
136
|
+
const fullPath = join(projectPath, file);
|
|
137
|
+
if (existsSync(fullPath)) {
|
|
138
|
+
detected.push({
|
|
139
|
+
name,
|
|
140
|
+
path: fullPath,
|
|
141
|
+
skillsPath: join(fullPath, "skills")
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return detected;
|
|
146
|
+
}
|
|
147
|
+
function installSkills(projectPath, agentName) {
|
|
148
|
+
const agentPaths = AGENT_PATHS[agentName];
|
|
149
|
+
const skillsDir = join(projectPath, agentPaths.skills);
|
|
150
|
+
mkdirSync(skillsDir, { recursive: true });
|
|
151
|
+
info(` Installing skills to ${skillsDir}...`);
|
|
152
|
+
const skillUrl = "https://github.com/saleor/agent-skills";
|
|
153
|
+
const baseDir = join(skillsDir, "..");
|
|
154
|
+
try {
|
|
155
|
+
const result = spawnSync("git", ["clone", "--depth", "1", skillUrl, "skills"], {
|
|
156
|
+
cwd: baseDir,
|
|
157
|
+
stdio: "pipe"
|
|
158
|
+
});
|
|
159
|
+
if (result.status === 0) {
|
|
160
|
+
for (const skill of SKILLS) {
|
|
161
|
+
info(` Installed ${skill}`);
|
|
162
|
+
}
|
|
163
|
+
success(` Skills installed to ${skillsDir}`);
|
|
164
|
+
} else {
|
|
165
|
+
info(` Could not clone skills, skipping...`);
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
info(` Could not clone skills, skipping...`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function createAgentsMd(projectPath, agentName = "opencode") {
|
|
172
|
+
const agentsMdContent = `# Saleor Development Guide
|
|
173
|
+
|
|
174
|
+
This project uses Saleor e-commerce platform.
|
|
175
|
+
|
|
176
|
+
## Commands
|
|
177
|
+
|
|
178
|
+
\`\`\`bash
|
|
179
|
+
# Development
|
|
180
|
+
npm run dev
|
|
181
|
+
|
|
182
|
+
# Build
|
|
183
|
+
npm run build
|
|
184
|
+
|
|
185
|
+
# Test
|
|
186
|
+
npm run test
|
|
187
|
+
|
|
188
|
+
# Lint
|
|
189
|
+
npm run lint
|
|
190
|
+
\`\`\`
|
|
191
|
+
|
|
192
|
+
## Saleor Cloud
|
|
193
|
+
|
|
194
|
+
- Dashboard: https://cloud.saleor.io
|
|
195
|
+
- Documentation: https://docs.saleor.io
|
|
196
|
+
- API Reference: https://docs.saleor.io/api
|
|
197
|
+
|
|
198
|
+
## Saleor Skills
|
|
199
|
+
|
|
200
|
+
This project includes Saleor agent skills:
|
|
201
|
+
- saleor-app: App development patterns
|
|
202
|
+
- saleor-configurator: Config as code
|
|
203
|
+
- saleor-core: Backend internals
|
|
204
|
+
- saleor-storefront: Storefront patterns
|
|
205
|
+
|
|
206
|
+
## MCP Server
|
|
207
|
+
|
|
208
|
+
Configure saleor-mcp for AI agent capabilities:
|
|
209
|
+
\`\`\`json
|
|
210
|
+
{
|
|
211
|
+
"mcpServers": {
|
|
212
|
+
"saleor": {
|
|
213
|
+
"url": "https://mcp.saleor.app"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
\`\`\`
|
|
218
|
+
`;
|
|
219
|
+
const agentsMdPath = join(projectPath, "AGENTS.md");
|
|
220
|
+
writeFileSync(agentsMdPath, agentsMdContent);
|
|
221
|
+
info(` Created AGENTS.md`);
|
|
222
|
+
}
|
|
223
|
+
function createMcpConfig(projectPath) {
|
|
224
|
+
const mcpConfig = {
|
|
225
|
+
mcpServers: {
|
|
226
|
+
saleor: {
|
|
227
|
+
url: "https://mcp.saleor.app"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const mcpPath = join(projectPath, ".mcp.json");
|
|
232
|
+
writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
|
|
233
|
+
info(` Created .mcp.json`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/cli/agent.ts
|
|
237
|
+
async function main() {
|
|
238
|
+
const args = process.argv.slice(2);
|
|
239
|
+
const action = args[0] || "setup";
|
|
240
|
+
if (action === "setup" || action === "install") {
|
|
241
|
+
console.log("Saleor Agent Setup");
|
|
242
|
+
console.log(`-------------------
|
|
243
|
+
`);
|
|
244
|
+
await setupAgent(".");
|
|
245
|
+
console.log(`
|
|
246
|
+
Agent configured successfully!`);
|
|
247
|
+
console.log("Restart your AI agent to enable Saleor capabilities.");
|
|
248
|
+
} else if (action === "skills") {
|
|
249
|
+
await installSkillsCommand(".");
|
|
250
|
+
} else {
|
|
251
|
+
console.error(`Unknown action: ${action}`);
|
|
252
|
+
console.log("Usage: jolly-agent [setup|skills]");
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
main().catch((err) => {
|
|
257
|
+
console.error(`Agent setup failed: ${err}`);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
});
|