create-operor 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/dist/index.d-BnefwYtp.d.ts +2 -0
- package/dist/index.js +153 -0
- package/dist/index.js.map +1 -0
- package/package.json +24 -0
- package/templates/default/.env.example +9 -0
- package/templates/default/USER.md +3 -0
- package/templates/default/agents/_defaults/SOUL.md +25 -0
- package/templates/default/agents/support/INSTRUCTIONS.md +49 -0
- package/templates/default/package.json.tmpl +20 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
import * as p from "@clack/prompts";
|
|
7
|
+
|
|
8
|
+
//#region src/index.ts
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const TEMPLATES_DIR = path.join(__dirname, "..", "templates", "default");
|
|
11
|
+
function parseArgs(args) {
|
|
12
|
+
const rest = args.slice(2);
|
|
13
|
+
const demo = rest.includes("--demo");
|
|
14
|
+
return {
|
|
15
|
+
projectName: rest.filter((a) => !a.startsWith("--"))[0] ?? "",
|
|
16
|
+
demo
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function detectPackageManager() {
|
|
20
|
+
const ua = process.env.npm_config_user_agent ?? "";
|
|
21
|
+
if (ua.startsWith("pnpm")) return "pnpm";
|
|
22
|
+
if (ua.startsWith("yarn")) return "yarn";
|
|
23
|
+
if (ua.startsWith("bun")) return "bun";
|
|
24
|
+
return "npm";
|
|
25
|
+
}
|
|
26
|
+
function copyDir(src, dest) {
|
|
27
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
28
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
29
|
+
const srcPath = path.join(src, entry.name);
|
|
30
|
+
const destPath = path.join(dest, entry.name);
|
|
31
|
+
if (entry.isDirectory()) copyDir(srcPath, destPath);
|
|
32
|
+
else fs.copyFileSync(srcPath, destPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function main() {
|
|
36
|
+
const opts = parseArgs(process.argv);
|
|
37
|
+
p.intro("create-operor");
|
|
38
|
+
let projectName = opts.projectName;
|
|
39
|
+
if (!projectName) {
|
|
40
|
+
const result = await p.text({
|
|
41
|
+
message: "Project name:",
|
|
42
|
+
placeholder: "my-bot",
|
|
43
|
+
validate: (v) => !v.trim() ? "Project name is required" : void 0
|
|
44
|
+
});
|
|
45
|
+
if (p.isCancel(result)) {
|
|
46
|
+
p.cancel("Cancelled.");
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
projectName = result;
|
|
50
|
+
}
|
|
51
|
+
const projectDir = path.resolve(process.cwd(), projectName);
|
|
52
|
+
if (fs.existsSync(projectDir)) {
|
|
53
|
+
p.cancel(`Directory "${projectName}" already exists.`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
let provider = "mock";
|
|
57
|
+
let apiKey = "";
|
|
58
|
+
let description = "My Operor project";
|
|
59
|
+
if (opts.demo) p.log.info("Demo mode — using MockProvider defaults");
|
|
60
|
+
else {
|
|
61
|
+
const providerResult = await p.select({
|
|
62
|
+
message: "LLM provider:",
|
|
63
|
+
options: [
|
|
64
|
+
{
|
|
65
|
+
value: "openai",
|
|
66
|
+
label: "OpenAI"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
value: "anthropic",
|
|
70
|
+
label: "Anthropic"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
value: "google",
|
|
74
|
+
label: "Google"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
value: "groq",
|
|
78
|
+
label: "Groq"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
value: "ollama",
|
|
82
|
+
label: "Ollama (local)"
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
});
|
|
86
|
+
if (p.isCancel(providerResult)) {
|
|
87
|
+
p.cancel("Cancelled.");
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
provider = providerResult;
|
|
91
|
+
if (provider !== "ollama") {
|
|
92
|
+
const keyResult = await p.password({ message: "API key:" });
|
|
93
|
+
if (p.isCancel(keyResult)) {
|
|
94
|
+
p.cancel("Cancelled.");
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
apiKey = keyResult ?? "";
|
|
98
|
+
}
|
|
99
|
+
const descResult = await p.text({
|
|
100
|
+
message: "Describe your business in one sentence:",
|
|
101
|
+
placeholder: "We sell handmade candles"
|
|
102
|
+
});
|
|
103
|
+
if (p.isCancel(descResult)) {
|
|
104
|
+
p.cancel("Cancelled.");
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
description = descResult || description;
|
|
108
|
+
}
|
|
109
|
+
const s = p.spinner();
|
|
110
|
+
s.start("Creating project");
|
|
111
|
+
copyDir(TEMPLATES_DIR, projectDir);
|
|
112
|
+
const tmplPath = path.join(projectDir, "package.json.tmpl");
|
|
113
|
+
const pkgContent = fs.readFileSync(tmplPath, "utf-8").replace(/\{\{name\}\}/g, projectName);
|
|
114
|
+
fs.writeFileSync(path.join(projectDir, "package.json"), pkgContent);
|
|
115
|
+
fs.unlinkSync(tmplPath);
|
|
116
|
+
const envLines = [`# LLM Configuration`, `LLM_PROVIDER=${provider}`];
|
|
117
|
+
if (apiKey) envLines.push(`LLM_API_KEY=${apiKey}`);
|
|
118
|
+
if (provider === "mock") envLines.push(`CHANNEL=mock`);
|
|
119
|
+
envLines.push("", "# Knowledge Base", "KB_ENABLED=true", "", "# Analytics", "ANALYTICS_ENABLED=true");
|
|
120
|
+
fs.writeFileSync(path.join(projectDir, ".env"), envLines.join("\n") + "\n");
|
|
121
|
+
const userMdPath = path.join(projectDir, "USER.md");
|
|
122
|
+
const userMd = fs.readFileSync(userMdPath, "utf-8").replace(/\{\{description\}\}/g, description);
|
|
123
|
+
fs.writeFileSync(userMdPath, userMd);
|
|
124
|
+
s.stop("Project created");
|
|
125
|
+
const pm = detectPackageManager();
|
|
126
|
+
const installCmd = pm === "yarn" ? "yarn" : `${pm} install`;
|
|
127
|
+
s.start(`Installing dependencies (${pm})`);
|
|
128
|
+
try {
|
|
129
|
+
execSync(installCmd, {
|
|
130
|
+
cwd: projectDir,
|
|
131
|
+
stdio: "pipe"
|
|
132
|
+
});
|
|
133
|
+
s.stop("Dependencies installed");
|
|
134
|
+
} catch {
|
|
135
|
+
s.stop("Could not install dependencies");
|
|
136
|
+
p.log.warn(`Run \`cd ${projectName} && ${installCmd}\` to install manually.`);
|
|
137
|
+
}
|
|
138
|
+
p.note([
|
|
139
|
+
`cd ${projectName}`,
|
|
140
|
+
"",
|
|
141
|
+
provider === "mock" ? `${pm === "npm" ? "npm run" : pm} chat # try it out` : `${pm === "npm" ? "npm run" : pm} setup # configure your agent`,
|
|
142
|
+
`${pm === "npm" ? "npm run" : pm} start # launch the agent`
|
|
143
|
+
].join("\n"), "Next steps");
|
|
144
|
+
p.outro("Happy building!");
|
|
145
|
+
}
|
|
146
|
+
main().catch((err) => {
|
|
147
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
148
|
+
process.exit(1);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { };
|
|
153
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execSync } from 'node:child_process';\nimport * as p from '@clack/prompts';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.join(__dirname, '..', 'templates', 'default');\n\ninterface Options {\n projectName: string;\n demo: boolean;\n provider?: string;\n apiKey?: string;\n description?: string;\n}\n\nfunction parseArgs(args: string[]): Options {\n const rest = args.slice(2);\n const demo = rest.includes('--demo');\n const positional = rest.filter((a) => !a.startsWith('--'));\n const projectName = positional[0] ?? '';\n return { projectName, demo };\n}\n\nfunction detectPackageManager(): string {\n const ua = process.env.npm_config_user_agent ?? '';\n if (ua.startsWith('pnpm')) return 'pnpm';\n if (ua.startsWith('yarn')) return 'yarn';\n if (ua.startsWith('bun')) return 'bun';\n return 'npm';\n}\n\nfunction copyDir(src: string, dest: string) {\n fs.mkdirSync(dest, { recursive: true });\n for (const entry of fs.readdirSync(src, { withFileTypes: true })) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n if (entry.isDirectory()) {\n copyDir(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n}\n\nasync function main() {\n const opts = parseArgs(process.argv);\n\n p.intro('create-operor');\n\n // Get project name\n let projectName = opts.projectName;\n if (!projectName) {\n const result = await p.text({\n message: 'Project name:',\n placeholder: 'my-bot',\n validate: (v) => (!v.trim() ? 'Project name is required' : undefined),\n });\n if (p.isCancel(result)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n projectName = result;\n }\n\n const projectDir = path.resolve(process.cwd(), projectName);\n\n if (fs.existsSync(projectDir)) {\n p.cancel(`Directory \"${projectName}\" already exists.`);\n process.exit(1);\n }\n\n let provider = 'mock';\n let apiKey = '';\n let description = 'My Operor project';\n\n if (opts.demo) {\n p.log.info('Demo mode — using MockProvider defaults');\n } else {\n const providerResult = await p.select({\n message: 'LLM provider:',\n options: [\n { value: 'openai', label: 'OpenAI' },\n { value: 'anthropic', label: 'Anthropic' },\n { value: 'google', label: 'Google' },\n { value: 'groq', label: 'Groq' },\n { value: 'ollama', label: 'Ollama (local)' },\n ],\n });\n if (p.isCancel(providerResult)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n provider = providerResult as string;\n\n if (provider !== 'ollama') {\n const keyResult = await p.password({\n message: 'API key:',\n });\n if (p.isCancel(keyResult)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n apiKey = keyResult ?? '';\n }\n\n const descResult = await p.text({\n message: 'Describe your business in one sentence:',\n placeholder: 'We sell handmade candles',\n });\n if (p.isCancel(descResult)) {\n p.cancel('Cancelled.');\n process.exit(0);\n }\n description = descResult || description;\n }\n\n // Scaffold project\n const s = p.spinner();\n s.start('Creating project');\n\n // Copy template files\n copyDir(TEMPLATES_DIR, projectDir);\n\n // Process package.json.tmpl → package.json\n const tmplPath = path.join(projectDir, 'package.json.tmpl');\n const pkgContent = fs.readFileSync(tmplPath, 'utf-8').replace(/\\{\\{name\\}\\}/g, projectName);\n fs.writeFileSync(path.join(projectDir, 'package.json'), pkgContent);\n fs.unlinkSync(tmplPath);\n\n // Write .env\n const envLines = [`# LLM Configuration`, `LLM_PROVIDER=${provider}`];\n if (apiKey) {\n envLines.push(`LLM_API_KEY=${apiKey}`);\n }\n if (provider === 'mock') {\n envLines.push(`CHANNEL=mock`);\n }\n envLines.push('', '# Knowledge Base', 'KB_ENABLED=true', '', '# Analytics', 'ANALYTICS_ENABLED=true');\n fs.writeFileSync(path.join(projectDir, '.env'), envLines.join('\\n') + '\\n');\n\n // Write USER.md with business description\n const userMdPath = path.join(projectDir, 'USER.md');\n const userMd = fs.readFileSync(userMdPath, 'utf-8').replace(/\\{\\{description\\}\\}/g, description);\n fs.writeFileSync(userMdPath, userMd);\n\n s.stop('Project created');\n\n // Install dependencies\n const pm = detectPackageManager();\n const installCmd = pm === 'yarn' ? 'yarn' : `${pm} install`;\n\n s.start(`Installing dependencies (${pm})`);\n try {\n execSync(installCmd, { cwd: projectDir, stdio: 'pipe' });\n s.stop('Dependencies installed');\n } catch {\n s.stop('Could not install dependencies');\n p.log.warn(`Run \\`cd ${projectName} && ${installCmd}\\` to install manually.`);\n }\n\n // Success\n p.note(\n [\n `cd ${projectName}`,\n '',\n provider === 'mock'\n ? `${pm === 'npm' ? 'npm run' : pm} chat # try it out`\n : `${pm === 'npm' ? 'npm run' : pm} setup # configure your agent`,\n `${pm === 'npm' ? 'npm run' : pm} start # launch the agent`,\n ].join('\\n'),\n 'Next steps',\n );\n\n p.outro('Happy building!');\n}\n\nmain().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-operor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Create a new Agent OS project",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-operor": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"templates"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@clack/prompts": "^1.0.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"tsdown": "^0.12.0",
|
|
18
|
+
"typescript": "^5.7.0"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsdown",
|
|
22
|
+
"test": "echo 'no tests yet'"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Agent Soul
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
|
|
5
|
+
- The customer's time is valuable — resolve issues in as few messages as possible
|
|
6
|
+
- Empathy first, solutions second — acknowledge feelings before jumping to fixes
|
|
7
|
+
- Honesty builds trust — if you don't know, say so and find out
|
|
8
|
+
|
|
9
|
+
## Boundaries
|
|
10
|
+
|
|
11
|
+
- Stay within your scope; escalate gracefully when you can't help
|
|
12
|
+
- Don't overpromise — set realistic expectations about timelines and outcomes
|
|
13
|
+
|
|
14
|
+
## Tone
|
|
15
|
+
|
|
16
|
+
- Conversational but professional
|
|
17
|
+
- Positive without being dismissive of problems
|
|
18
|
+
- Direct — avoid filler phrases
|
|
19
|
+
- Match the customer's energy — if they're brief, be brief; if they need reassurance, provide it
|
|
20
|
+
|
|
21
|
+
## When Things Go Wrong
|
|
22
|
+
|
|
23
|
+
- Lead with accountability: "I see the issue and I'm sorry about that"
|
|
24
|
+
- Offer a concrete next step, not just an apology
|
|
25
|
+
- Follow through — if you say you'll check on something, do it
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: support
|
|
3
|
+
purpose: Handle customer support inquiries
|
|
4
|
+
triggers:
|
|
5
|
+
- "*"
|
|
6
|
+
knowledgeBase: true
|
|
7
|
+
guardrails:
|
|
8
|
+
maxResponseLength: 500
|
|
9
|
+
blockedTopics:
|
|
10
|
+
- competitor pricing
|
|
11
|
+
- internal company policies
|
|
12
|
+
- employee information
|
|
13
|
+
escalationTriggers:
|
|
14
|
+
- speak to a human
|
|
15
|
+
- talk to a manager
|
|
16
|
+
- escalate
|
|
17
|
+
systemRules:
|
|
18
|
+
- Never share customer data with other customers
|
|
19
|
+
- Always verify order ownership before sharing details
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Role
|
|
23
|
+
|
|
24
|
+
You are a helpful customer support agent. Your job is to answer questions, resolve issues, and provide a great experience.
|
|
25
|
+
|
|
26
|
+
## Scope
|
|
27
|
+
|
|
28
|
+
- Answer questions about products, services, and policies
|
|
29
|
+
- Help with order tracking and status updates
|
|
30
|
+
- Assist with returns and exchanges
|
|
31
|
+
- Provide shipping and delivery information
|
|
32
|
+
|
|
33
|
+
## Out of Scope
|
|
34
|
+
|
|
35
|
+
- Cannot process refunds directly (escalate to a team member)
|
|
36
|
+
- Cannot access or discuss other customers' information
|
|
37
|
+
- Do not provide legal, medical, or financial advice
|
|
38
|
+
|
|
39
|
+
## Style
|
|
40
|
+
|
|
41
|
+
- Warm, professional, and concise
|
|
42
|
+
- Use short paragraphs and bullet points for clarity
|
|
43
|
+
- Acknowledge the customer's concern before problem-solving
|
|
44
|
+
- End each interaction with a clear next step
|
|
45
|
+
|
|
46
|
+
## Escalation
|
|
47
|
+
|
|
48
|
+
- If the customer asks for a human agent, acknowledge their request and provide handoff instructions
|
|
49
|
+
- Use the phrase: "Let me connect you with a team member who can help with this."
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "agent-os start",
|
|
8
|
+
"setup": "agent-os setup",
|
|
9
|
+
"chat": "agent-os chat",
|
|
10
|
+
"test": "agent-os test"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@agent-os/cli": "^0.1.0",
|
|
14
|
+
"@agent-os/core": "^0.1.0",
|
|
15
|
+
"@agent-os/llm": "^0.1.0",
|
|
16
|
+
"@agent-os/memory": "^0.1.0",
|
|
17
|
+
"@agent-os/knowledge": "^0.1.0",
|
|
18
|
+
"@agent-os/provider-mock": "^0.1.0"
|
|
19
|
+
}
|
|
20
|
+
}
|