@lobu/cli 3.0.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.
Files changed (116) hide show
  1. package/README.md +276 -0
  2. package/bin/create-lobu.js +5 -0
  3. package/bin/lobu.js +5 -0
  4. package/dist/api/client.d.ts +11 -0
  5. package/dist/api/client.d.ts.map +1 -0
  6. package/dist/api/client.js +35 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/api/credentials.d.ts +13 -0
  9. package/dist/api/credentials.d.ts.map +1 -0
  10. package/dist/api/credentials.js +39 -0
  11. package/dist/api/credentials.js.map +1 -0
  12. package/dist/commands/dev.d.ts +13 -0
  13. package/dist/commands/dev.d.ts.map +1 -0
  14. package/dist/commands/dev.js +128 -0
  15. package/dist/commands/dev.js.map +1 -0
  16. package/dist/commands/init.d.ts +2 -0
  17. package/dist/commands/init.d.ts.map +1 -0
  18. package/dist/commands/init.js +905 -0
  19. package/dist/commands/init.js.map +1 -0
  20. package/dist/commands/launch.d.ts +6 -0
  21. package/dist/commands/launch.d.ts.map +1 -0
  22. package/dist/commands/launch.js +32 -0
  23. package/dist/commands/launch.js.map +1 -0
  24. package/dist/commands/login.d.ts +4 -0
  25. package/dist/commands/login.d.ts.map +1 -0
  26. package/dist/commands/login.js +29 -0
  27. package/dist/commands/login.js.map +1 -0
  28. package/dist/commands/logout.d.ts +2 -0
  29. package/dist/commands/logout.d.ts.map +1 -0
  30. package/dist/commands/logout.js +7 -0
  31. package/dist/commands/logout.js.map +1 -0
  32. package/dist/commands/providers/add.d.ts +2 -0
  33. package/dist/commands/providers/add.d.ts.map +1 -0
  34. package/dist/commands/providers/add.js +51 -0
  35. package/dist/commands/providers/add.js.map +1 -0
  36. package/dist/commands/providers/list.d.ts +2 -0
  37. package/dist/commands/providers/list.d.ts.map +1 -0
  38. package/dist/commands/providers/list.js +21 -0
  39. package/dist/commands/providers/list.js.map +1 -0
  40. package/dist/commands/secrets.d.ts +8 -0
  41. package/dist/commands/secrets.d.ts.map +1 -0
  42. package/dist/commands/secrets.js +98 -0
  43. package/dist/commands/secrets.js.map +1 -0
  44. package/dist/commands/skills/add.d.ts +2 -0
  45. package/dist/commands/skills/add.d.ts.map +1 -0
  46. package/dist/commands/skills/add.js +47 -0
  47. package/dist/commands/skills/add.js.map +1 -0
  48. package/dist/commands/skills/info.d.ts +2 -0
  49. package/dist/commands/skills/info.d.ts.map +1 -0
  50. package/dist/commands/skills/info.js +45 -0
  51. package/dist/commands/skills/info.js.map +1 -0
  52. package/dist/commands/skills/list.d.ts +2 -0
  53. package/dist/commands/skills/list.d.ts.map +1 -0
  54. package/dist/commands/skills/list.js +30 -0
  55. package/dist/commands/skills/list.js.map +1 -0
  56. package/dist/commands/skills/registry.d.ts +34 -0
  57. package/dist/commands/skills/registry.d.ts.map +1 -0
  58. package/dist/commands/skills/registry.js +38 -0
  59. package/dist/commands/skills/registry.js.map +1 -0
  60. package/dist/commands/skills/search.d.ts +2 -0
  61. package/dist/commands/skills/search.d.ts.map +1 -0
  62. package/dist/commands/skills/search.js +21 -0
  63. package/dist/commands/skills/search.js.map +1 -0
  64. package/dist/commands/status.d.ts +2 -0
  65. package/dist/commands/status.d.ts.map +1 -0
  66. package/dist/commands/status.js +7 -0
  67. package/dist/commands/status.js.map +1 -0
  68. package/dist/commands/validate.d.ts +2 -0
  69. package/dist/commands/validate.d.ts.map +1 -0
  70. package/dist/commands/validate.js +73 -0
  71. package/dist/commands/validate.js.map +1 -0
  72. package/dist/commands/whoami.d.ts +2 -0
  73. package/dist/commands/whoami.d.ts.map +1 -0
  74. package/dist/commands/whoami.js +25 -0
  75. package/dist/commands/whoami.js.map +1 -0
  76. package/dist/config/loader.d.ts +16 -0
  77. package/dist/config/loader.d.ts.map +1 -0
  78. package/dist/config/loader.js +41 -0
  79. package/dist/config/loader.js.map +1 -0
  80. package/dist/config/schema.d.ts +279 -0
  81. package/dist/config/schema.d.ts.map +1 -0
  82. package/dist/config/schema.js +52 -0
  83. package/dist/config/schema.js.map +1 -0
  84. package/dist/config/transformer.d.ts +11 -0
  85. package/dist/config/transformer.d.ts.map +1 -0
  86. package/dist/config/transformer.js +49 -0
  87. package/dist/config/transformer.js.map +1 -0
  88. package/dist/index.d.ts +6 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +183 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/mcp-servers.d.ts +11 -0
  93. package/dist/mcp-servers.d.ts.map +1 -0
  94. package/dist/mcp-servers.js +27 -0
  95. package/dist/mcp-servers.js.map +1 -0
  96. package/dist/mcp-servers.json +216 -0
  97. package/dist/templates/.env.tmpl +29 -0
  98. package/dist/templates/.gitignore.tmpl +32 -0
  99. package/dist/templates/AGENTS.md.tmpl +1 -0
  100. package/dist/templates/Dockerfile.worker.tmpl +29 -0
  101. package/dist/templates/README.md.tmpl +95 -0
  102. package/dist/templates/TESTING.md.tmpl +225 -0
  103. package/dist/templates/lobu.toml.tmpl +44 -0
  104. package/dist/types.d.ts +76 -0
  105. package/dist/types.d.ts.map +1 -0
  106. package/dist/types.js +2 -0
  107. package/dist/types.js.map +1 -0
  108. package/dist/utils/config.d.ts +2 -0
  109. package/dist/utils/config.d.ts.map +1 -0
  110. package/dist/utils/config.js +13 -0
  111. package/dist/utils/config.js.map +1 -0
  112. package/dist/utils/template.d.ts +2 -0
  113. package/dist/utils/template.d.ts.map +1 -0
  114. package/dist/utils/template.js +19 -0
  115. package/dist/utils/template.js.map +1 -0
  116. package/package.json +48 -0
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Transform lobu.toml config into docker-compose environment variables
3
+ * and MCP config JSON for local dev mode.
4
+ */
5
+ export function transformConfig(config) {
6
+ const envVars = {};
7
+ // Agent name as compose project name
8
+ envVars.COMPOSE_PROJECT_NAME = config.agent.name;
9
+ // Identity lives in IDENTITY.md, SOUL.md, USER.md files — loaded by dev command
10
+ // Network config
11
+ if (config.network?.allowed) {
12
+ envVars.WORKER_ALLOWED_DOMAINS = config.network.allowed.join(",");
13
+ }
14
+ if (config.network?.denied) {
15
+ envVars.WORKER_DISALLOWED_DOMAINS = config.network.denied.join(",");
16
+ }
17
+ // Worker config
18
+ if (config.worker?.timeout_minutes) {
19
+ envVars.WORKER_TIMEOUT_MINUTES = String(config.worker.timeout_minutes);
20
+ }
21
+ if (config.worker?.nix_packages?.length) {
22
+ envVars.WORKER_NIX_PACKAGES = config.worker.nix_packages.join(",");
23
+ }
24
+ // Platform flags
25
+ if (config.platforms?.telegram) {
26
+ envVars.TELEGRAM_ENABLED = "true";
27
+ }
28
+ if (config.platforms?.api !== false) {
29
+ envVars.API_ENABLED = "true";
30
+ }
31
+ // Provider config - stored as JSON for gateway to parse
32
+ if (config.providers.length > 0) {
33
+ envVars.AGENT_PROVIDERS = JSON.stringify(config.providers.map((p) => ({
34
+ id: p.id,
35
+ model: p.model,
36
+ })));
37
+ }
38
+ // Skills config
39
+ if (config.skills.enabled.length > 0) {
40
+ envVars.AGENT_SKILLS = config.skills.enabled.join(",");
41
+ }
42
+ // MCP servers from skills.mcp section
43
+ let mcpConfig = null;
44
+ if (config.skills.mcp && Object.keys(config.skills.mcp).length > 0) {
45
+ mcpConfig = config.skills.mcp;
46
+ }
47
+ return { envVars, mcpConfig };
48
+ }
49
+ //# sourceMappingURL=transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../src/config/transformer.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,qCAAqC;IACrC,OAAO,CAAC,oBAAoB,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;IAEjD,gFAAgF;IAEhF,iBAAiB;IACjB,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC5B,OAAO,CAAC,sBAAsB,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,yBAAyB,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtE,CAAC;IAED,gBAAgB;IAChB,IAAI,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;QACnC,OAAO,CAAC,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QACxC,OAAO,CAAC,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,CAAC;IAED,iBAAiB;IACjB,IAAI,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,gBAAgB,GAAG,MAAM,CAAC;IACpC,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,EAAE,GAAG,KAAK,KAAK,EAAE,CAAC;QACpC,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC;IAC/B,CAAC;IAED,wDAAwD;IACxD,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CACtC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,KAAK,EAAE,CAAC,CAAC,KAAK;SACf,CAAC,CAAC,CACJ,CAAC;IACJ,CAAC;IAED,gBAAgB;IAChB,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,sCAAsC;IACtC,IAAI,SAAS,GAA0C,IAAI,CAAC;IAC5D,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnE,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAChC,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { initCommand } from "./commands/init.js";
2
+ export * from "./types.js";
3
+ export { checkConfigExists } from "./utils/config.js";
4
+ export { renderTemplate } from "./utils/template.js";
5
+ export declare function runCli(argv?: readonly string[]): Promise<void>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAWrD,wBAAsB,MAAM,CAC1B,IAAI,GAAE,SAAS,MAAM,EAAiB,GACrC,OAAO,CAAC,IAAI,CAAC,CA0Mf"}
package/dist/index.js ADDED
@@ -0,0 +1,183 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import chalk from "chalk";
5
+ import { Command } from "commander";
6
+ // Re-exports for backward compatibility
7
+ export { initCommand } from "./commands/init.js";
8
+ export * from "./types.js";
9
+ export { checkConfigExists } from "./utils/config.js";
10
+ export { renderTemplate } from "./utils/template.js";
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ async function getPackageVersion() {
13
+ const pkgPath = join(__dirname, "..", "package.json");
14
+ const pkgContent = await readFile(pkgPath, "utf-8");
15
+ const pkg = JSON.parse(pkgContent);
16
+ return pkg.version ?? "0.0.0";
17
+ }
18
+ export async function runCli(argv = process.argv) {
19
+ const program = new Command();
20
+ const version = await getPackageVersion();
21
+ program
22
+ .name("lobu")
23
+ .description("CLI for deploying and managing AI agents on Lobu")
24
+ .version(version);
25
+ // ─── init ───────────────────────────────────────────────────────────
26
+ program
27
+ .command("init [name]")
28
+ .description("Scaffold a new agent project (lobu.toml + docker-compose)")
29
+ .option("-t, --template <template>", "Starter template (support, coding, general)")
30
+ .action(async (name) => {
31
+ try {
32
+ const { initCommand } = await import("./commands/init.js");
33
+ await initCommand(process.cwd(), name);
34
+ }
35
+ catch (error) {
36
+ console.error(chalk.red("\n Error:"), error);
37
+ process.exit(1);
38
+ }
39
+ });
40
+ // ─── validate ───────────────────────────────────────────────────────
41
+ program
42
+ .command("validate")
43
+ .description("Validate lobu.toml schema, skill IDs, and provider config")
44
+ .action(async () => {
45
+ const { validateCommand } = await import("./commands/validate.js");
46
+ const valid = await validateCommand(process.cwd());
47
+ if (!valid)
48
+ process.exit(1);
49
+ });
50
+ // ─── dev ────────────────────────────────────────────────────────────
51
+ // Passthrough to docker compose up — all extra args forwarded directly.
52
+ // lobu dev -d --build → docker compose up -d --build
53
+ program
54
+ .command("dev")
55
+ .description("Run agent locally (reads lobu.toml, then docker compose up)")
56
+ .allowUnknownOption(true)
57
+ .helpOption(false)
58
+ .action(async (_opts, cmd) => {
59
+ const { devCommand } = await import("./commands/dev.js");
60
+ await devCommand(process.cwd(), cmd.args);
61
+ });
62
+ // ─── launch ─────────────────────────────────────────────────────────
63
+ program
64
+ .command("launch")
65
+ .description("Launch agent to Lobu Cloud")
66
+ .option("-e, --env <env>", "Target environment")
67
+ .option("--dry-run", "Show what would change")
68
+ .option("-m, --message <message>", "Deployment note")
69
+ .action(async (options) => {
70
+ const { launchCommand } = await import("./commands/launch.js");
71
+ await launchCommand(process.cwd(), options);
72
+ });
73
+ // ─── login ──────────────────────────────────────────────────────────
74
+ program
75
+ .command("login")
76
+ .description("Authenticate with Lobu Cloud")
77
+ .option("--token <token>", "Use API token directly (CI/CD)")
78
+ .action(async (options) => {
79
+ const { loginCommand } = await import("./commands/login.js");
80
+ await loginCommand(options);
81
+ });
82
+ // ─── logout ─────────────────────────────────────────────────────────
83
+ program
84
+ .command("logout")
85
+ .description("Clear stored credentials")
86
+ .action(async () => {
87
+ const { logoutCommand } = await import("./commands/logout.js");
88
+ await logoutCommand();
89
+ });
90
+ // ─── whoami ─────────────────────────────────────────────────────────
91
+ program
92
+ .command("whoami")
93
+ .description("Show current user and linked agent")
94
+ .action(async () => {
95
+ const { whoamiCommand } = await import("./commands/whoami.js");
96
+ await whoamiCommand();
97
+ });
98
+ // ─── status ─────────────────────────────────────────────────────────
99
+ program
100
+ .command("status")
101
+ .description("Agent health and version info")
102
+ .action(async () => {
103
+ const { statusCommand } = await import("./commands/status.js");
104
+ await statusCommand();
105
+ });
106
+ // ─── secrets ────────────────────────────────────────────────────────
107
+ const secrets = program
108
+ .command("secrets")
109
+ .description("Manage agent secrets");
110
+ secrets
111
+ .command("set <key> <value>")
112
+ .description("Set a secret (stored in local .env for dev)")
113
+ .action(async (key, value) => {
114
+ const { secretsSetCommand } = await import("./commands/secrets.js");
115
+ await secretsSetCommand(process.cwd(), key, value);
116
+ });
117
+ secrets
118
+ .command("list")
119
+ .description("List secrets (values redacted)")
120
+ .action(async () => {
121
+ const { secretsListCommand } = await import("./commands/secrets.js");
122
+ await secretsListCommand(process.cwd());
123
+ });
124
+ secrets
125
+ .command("delete <key>")
126
+ .description("Remove a secret")
127
+ .action(async (key) => {
128
+ const { secretsDeleteCommand } = await import("./commands/secrets.js");
129
+ await secretsDeleteCommand(process.cwd(), key);
130
+ });
131
+ // ─── skills ─────────────────────────────────────────────────────────
132
+ const skills = program
133
+ .command("skills")
134
+ .description("Browse and manage skills from the registry");
135
+ skills
136
+ .command("list")
137
+ .description("Browse the skill registry")
138
+ .action(async () => {
139
+ const { skillsListCommand } = await import("./commands/skills/list.js");
140
+ await skillsListCommand();
141
+ });
142
+ skills
143
+ .command("search <query>")
144
+ .description("Search skills by name or description")
145
+ .action(async (query) => {
146
+ const { skillsSearchCommand } = await import("./commands/skills/search.js");
147
+ await skillsSearchCommand(query);
148
+ });
149
+ skills
150
+ .command("add <id>")
151
+ .description("Add a skill to lobu.toml")
152
+ .action(async (id) => {
153
+ const { skillsAddCommand } = await import("./commands/skills/add.js");
154
+ await skillsAddCommand(process.cwd(), id);
155
+ });
156
+ skills
157
+ .command("info <id>")
158
+ .description("Show skill details and required secrets")
159
+ .action(async (id) => {
160
+ const { skillsInfoCommand } = await import("./commands/skills/info.js");
161
+ await skillsInfoCommand(id);
162
+ });
163
+ // ─── providers ──────────────────────────────────────────────────────
164
+ const providers = program
165
+ .command("providers")
166
+ .description("Browse and manage LLM providers");
167
+ providers
168
+ .command("list")
169
+ .description("Browse available LLM providers")
170
+ .action(async () => {
171
+ const { providersListCommand } = await import("./commands/providers/list.js");
172
+ await providersListCommand();
173
+ });
174
+ providers
175
+ .command("add <id>")
176
+ .description("Add a provider to lobu.toml")
177
+ .action(async (id) => {
178
+ const { providersAddCommand } = await import("./commands/providers/add.js");
179
+ await providersAddCommand(process.cwd(), id);
180
+ });
181
+ await program.parseAsync(argv);
182
+ }
183
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface McpServerDefinition {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ type: "oauth" | "api-key" | "command" | "none";
6
+ config: any;
7
+ setupInstructions?: string;
8
+ }
9
+ export declare const MCP_SERVERS: McpServerDefinition[];
10
+ export declare function getRequiredEnvVars(servers: McpServerDefinition[]): string[];
11
+ //# sourceMappingURL=mcp-servers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-servers.d.ts","sourceRoot":"","sources":["../src/mcp-servers.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/C,MAAM,EAAE,GAAG,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AASD,eAAO,MAAM,WAAW,EAAE,mBAAmB,EAA2B,CAAC;AAIzE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,MAAM,EAAE,CAiB3E"}
@@ -0,0 +1,27 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ // Load MCP servers from JSON file
6
+ const mcpServersJson = readFileSync(join(__dirname, "mcp-servers.json"), "utf-8");
7
+ const mcpServersData = JSON.parse(mcpServersJson);
8
+ export const MCP_SERVERS = mcpServersData.servers;
9
+ // Helper function to get OAuth servers
10
+ // Helper function to generate env variable names
11
+ export function getRequiredEnvVars(servers) {
12
+ const envVars = new Set();
13
+ servers.forEach((server) => {
14
+ const configStr = JSON.stringify(server.config);
15
+ // Extract all ${VARIABLE} and ${env:VARIABLE} patterns
16
+ const matches = configStr.match(/\$\{(?:env:)?([A-Z_]+)\}/g) || [];
17
+ matches.forEach((match) => {
18
+ const varName = match.replace(/\$\{(?:env:)?([A-Z_]+)\}/, "$1");
19
+ if (varName !== "PUBLIC_URL") {
20
+ // PUBLIC_URL is handled separately
21
+ envVars.add(varName);
22
+ }
23
+ });
24
+ });
25
+ return Array.from(envVars);
26
+ }
27
+ //# sourceMappingURL=mcp-servers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-servers.js","sourceRoot":"","sources":["../src/mcp-servers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAW1D,kCAAkC;AAClC,MAAM,cAAc,GAAG,YAAY,CACjC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,EACnC,OAAO,CACR,CAAC;AACF,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAA0B,cAAc,CAAC,OAAO,CAAC;AAEzE,uCAAuC;AACvC,iDAAiD;AACjD,MAAM,UAAU,kBAAkB,CAAC,OAA8B;IAC/D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChD,uDAAuD;QACvD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC;QACnE,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACxB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;YAChE,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;gBAC7B,mCAAmC;gBACnC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,216 @@
1
+ {
2
+ "servers": [
3
+ {
4
+ "id": "github",
5
+ "name": "GitHub",
6
+ "description": "Access repositories, issues, and code search",
7
+ "type": "oauth",
8
+ "config": {
9
+ "url": "https://api.githubcopilot.com/mcp/",
10
+ "oauth": {
11
+ "authUrl": "https://github.com/login/oauth/authorize",
12
+ "tokenUrl": "https://github.com/login/oauth/access_token",
13
+ "clientId": "${GITHUB_CLIENT_ID}",
14
+ "clientSecret": "${env:GITHUB_CLIENT_SECRET}",
15
+ "scopes": ["repo", "read:user"],
16
+ "grantType": "authorization_code",
17
+ "responseType": "code"
18
+ }
19
+ },
20
+ "setupInstructions": "1. Create a GitHub OAuth App at https://github.com/settings/developers\n2. Set Authorization callback URL to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Client ID and Client Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add GITHUB_CLIENT_SECRET to your .env file"
21
+ },
22
+ {
23
+ "id": "playwright",
24
+ "name": "Playwright",
25
+ "description": "Browser automation and web testing",
26
+ "type": "command",
27
+ "config": {
28
+ "command": "npx",
29
+ "args": ["-y", "@modelcontextprotocol/server-playwright"]
30
+ }
31
+ },
32
+ {
33
+ "id": "figma",
34
+ "name": "Figma",
35
+ "description": "Access design files and components",
36
+ "type": "oauth",
37
+ "config": {
38
+ "url": "https://api.figma.com/v1/",
39
+ "oauth": {
40
+ "authUrl": "https://www.figma.com/oauth",
41
+ "tokenUrl": "https://www.figma.com/api/oauth/token",
42
+ "clientId": "${FIGMA_CLIENT_ID}",
43
+ "clientSecret": "${env:FIGMA_CLIENT_SECRET}",
44
+ "scopes": ["file_read"],
45
+ "grantType": "authorization_code",
46
+ "responseType": "code"
47
+ }
48
+ },
49
+ "setupInstructions": "1. Create a Figma App at https://www.figma.com/developers/apps\n2. Set Redirect URI to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Client ID and Client Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add FIGMA_CLIENT_SECRET to your .env file"
50
+ },
51
+ {
52
+ "id": "notion",
53
+ "name": "Notion",
54
+ "description": "Access and manage Notion pages and databases",
55
+ "type": "oauth",
56
+ "config": {
57
+ "url": "https://mcp.notion.com/mcp",
58
+ "oauth": {
59
+ "authUrl": "https://api.notion.com/v1/oauth/authorize",
60
+ "tokenUrl": "https://api.notion.com/v1/oauth/token",
61
+ "clientId": "${NOTION_CLIENT_ID}",
62
+ "clientSecret": "${env:NOTION_CLIENT_SECRET}",
63
+ "scopes": [],
64
+ "grantType": "authorization_code",
65
+ "responseType": "code"
66
+ }
67
+ },
68
+ "setupInstructions": "1. Create a Notion Integration at https://www.notion.so/my-integrations\n2. Set Redirect URI to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the OAuth Client ID and Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add NOTION_CLIENT_SECRET to your .env file"
69
+ },
70
+ {
71
+ "id": "firecrawl",
72
+ "name": "Firecrawl",
73
+ "description": "Web scraping and content extraction",
74
+ "type": "api-key",
75
+ "config": {
76
+ "command": "npx",
77
+ "args": ["-y", "@firecrawl/mcp-server"],
78
+ "env": {
79
+ "FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
80
+ }
81
+ },
82
+ "setupInstructions": "1. Get API key from https://www.firecrawl.dev/dashboard\n2. Add FIRECRAWL_API_KEY to your .env file"
83
+ },
84
+ {
85
+ "id": "grafana",
86
+ "name": "Grafana",
87
+ "description": "Access dashboards and metrics",
88
+ "type": "api-key",
89
+ "config": {
90
+ "url": "${GRAFANA_URL}/api",
91
+ "headers": {
92
+ "Authorization": "Bearer ${env:GRAFANA_API_KEY}"
93
+ }
94
+ },
95
+ "setupInstructions": "1. Create a Service Account in your Grafana instance\n2. Generate an API token\n3. Add GRAFANA_URL and GRAFANA_API_KEY to your .env file"
96
+ },
97
+ {
98
+ "id": "jira",
99
+ "name": "Atlassian Jira",
100
+ "description": "Access and manage Jira issues",
101
+ "type": "oauth",
102
+ "config": {
103
+ "url": "https://api.atlassian.com",
104
+ "oauth": {
105
+ "authUrl": "https://auth.atlassian.com/authorize",
106
+ "tokenUrl": "https://auth.atlassian.com/oauth/token",
107
+ "clientId": "${JIRA_CLIENT_ID}",
108
+ "clientSecret": "${env:JIRA_CLIENT_SECRET}",
109
+ "scopes": ["read:jira-work", "read:jira-user", "write:jira-work"],
110
+ "grantType": "authorization_code",
111
+ "responseType": "code"
112
+ }
113
+ },
114
+ "setupInstructions": "1. Create an OAuth 2.0 app at https://developer.atlassian.com/console/myapps/\n2. Set Callback URL to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Client ID and Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add JIRA_CLIENT_SECRET to your .env file"
115
+ },
116
+ {
117
+ "id": "datadog",
118
+ "name": "Datadog",
119
+ "description": "Monitor logs and metrics",
120
+ "type": "api-key",
121
+ "config": {
122
+ "url": "https://api.datadoghq.com/api/v2",
123
+ "headers": {
124
+ "DD-API-KEY": "${env:DATADOG_API_KEY}",
125
+ "DD-APPLICATION-KEY": "${env:DATADOG_APP_KEY}"
126
+ }
127
+ },
128
+ "setupInstructions": "1. Go to https://app.datadoghq.com/organization-settings/api-keys\n2. Create an API Key and Application Key\n3. Add DATADOG_API_KEY and DATADOG_APP_KEY to your .env file"
129
+ },
130
+ {
131
+ "id": "google-calendar",
132
+ "name": "Google Calendar",
133
+ "description": "Access and manage calendar events",
134
+ "type": "oauth",
135
+ "config": {
136
+ "url": "https://www.googleapis.com/calendar/v3",
137
+ "oauth": {
138
+ "authUrl": "https://accounts.google.com/o/oauth2/v2/auth",
139
+ "tokenUrl": "https://oauth2.googleapis.com/token",
140
+ "clientId": "${GOOGLE_CLIENT_ID}",
141
+ "clientSecret": "${env:GOOGLE_CLIENT_SECRET}",
142
+ "scopes": ["https://www.googleapis.com/auth/calendar.readonly"],
143
+ "grantType": "authorization_code",
144
+ "responseType": "code"
145
+ }
146
+ },
147
+ "setupInstructions": "1. Create OAuth credentials at https://console.cloud.google.com/apis/credentials\n2. Set Authorized redirect URI to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Client ID and Client Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add GOOGLE_CLIENT_SECRET to your .env file"
148
+ },
149
+ {
150
+ "id": "sentry",
151
+ "name": "Sentry",
152
+ "description": "Access error tracking and performance monitoring",
153
+ "type": "none",
154
+ "config": {
155
+ "url": "https://mcp.sentry.dev/mcp"
156
+ }
157
+ },
158
+ {
159
+ "id": "linear",
160
+ "name": "Linear",
161
+ "description": "Manage issues and projects",
162
+ "type": "oauth",
163
+ "config": {
164
+ "url": "https://api.linear.app/graphql",
165
+ "oauth": {
166
+ "authUrl": "https://linear.app/oauth/authorize",
167
+ "tokenUrl": "https://api.linear.app/oauth/token",
168
+ "clientId": "${LINEAR_CLIENT_ID}",
169
+ "clientSecret": "${env:LINEAR_CLIENT_SECRET}",
170
+ "scopes": ["read", "write"],
171
+ "grantType": "authorization_code",
172
+ "responseType": "code"
173
+ }
174
+ },
175
+ "setupInstructions": "1. Create OAuth app at https://linear.app/settings/api\n2. Set Redirect URL to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Client ID and Client Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add LINEAR_CLIENT_SECRET to your .env file"
176
+ },
177
+ {
178
+ "id": "discord",
179
+ "name": "Discord",
180
+ "description": "Access Discord servers and channels",
181
+ "type": "oauth",
182
+ "config": {
183
+ "url": "https://discord.com/api/v10",
184
+ "oauth": {
185
+ "authUrl": "https://discord.com/oauth2/authorize",
186
+ "tokenUrl": "https://discord.com/api/oauth2/token",
187
+ "clientId": "${DISCORD_CLIENT_ID}",
188
+ "clientSecret": "${env:DISCORD_CLIENT_SECRET}",
189
+ "scopes": ["identify", "guilds", "messages.read"],
190
+ "grantType": "authorization_code",
191
+ "responseType": "code"
192
+ }
193
+ },
194
+ "setupInstructions": "1. Create Discord app at https://discord.com/developers/applications\n2. Set Redirect URL to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Client ID and Client Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add DISCORD_CLIENT_SECRET to your .env file"
195
+ },
196
+ {
197
+ "id": "gitlab",
198
+ "name": "GitLab",
199
+ "description": "Access GitLab repositories and issues",
200
+ "type": "oauth",
201
+ "config": {
202
+ "url": "https://gitlab.com/api/v4",
203
+ "oauth": {
204
+ "authUrl": "https://gitlab.com/oauth/authorize",
205
+ "tokenUrl": "https://gitlab.com/oauth/token",
206
+ "clientId": "${GITLAB_CLIENT_ID}",
207
+ "clientSecret": "${env:GITLAB_CLIENT_SECRET}",
208
+ "scopes": ["api", "read_user"],
209
+ "grantType": "authorization_code",
210
+ "responseType": "code"
211
+ }
212
+ },
213
+ "setupInstructions": "1. Create GitLab application at https://gitlab.com/-/profile/applications\n2. Set Redirect URI to: {PUBLIC_URL}/mcp/oauth/callback\n3. Copy the Application ID and Secret\n4. Update .lobu/mcp.config.json with your Client ID\n5. Add GITLAB_CLIENT_SECRET to your .env file"
214
+ }
215
+ ]
216
+ }
@@ -0,0 +1,29 @@
1
+ # Slack Configuration
2
+ SLACK_SIGNING_SECRET={{SLACK_SIGNING_SECRET}}
3
+ SLACK_BOT_TOKEN={{SLACK_BOT_TOKEN}}
4
+ SLACK_APP_TOKEN={{SLACK_APP_TOKEN}}
5
+
6
+ # Telegram Configuration
7
+ TELEGRAM_ENABLED={{TELEGRAM_ENABLED}}
8
+ TELEGRAM_BOT_TOKEN={{TELEGRAM_BOT_TOKEN}}
9
+ TELEGRAM_ALLOW_FROM={{TELEGRAM_ALLOW_FROM}}
10
+
11
+ # Anthropic Configuration
12
+ ANTHROPIC_API_KEY={{ANTHROPIC_API_KEY}}
13
+
14
+ # Gateway Configuration
15
+ PUBLIC_GATEWAY_URL={{PUBLIC_GATEWAY_URL}}
16
+
17
+ # Security
18
+ ENCRYPTION_KEY={{ENCRYPTION_KEY}}
19
+
20
+ # Worker Network Access Control
21
+ # Empty/unset: Complete isolation (deny all)
22
+ # WORKER_ALLOWED_DOMAINS=*: Unrestricted access
23
+ # WORKER_ALLOWED_DOMAINS=domains: Allowlist mode (deny by default, allow only these)
24
+ # WORKER_DISALLOWED_DOMAINS=domains: Blocklist mode (use with WORKER_ALLOWED_DOMAINS=*)
25
+ WORKER_ALLOWED_DOMAINS={{WORKER_ALLOWED_DOMAINS}}
26
+ WORKER_DISALLOWED_DOMAINS={{WORKER_DISALLOWED_DOMAINS}}
27
+
28
+ # CLI Version (used for image tags)
29
+ CLI_VERSION={{CLI_VERSION}}
@@ -0,0 +1,32 @@
1
+ # Environment variables
2
+ .env
3
+ .env.local
4
+ .env.*.local
5
+
6
+ # Generated files
7
+ .lobu/
8
+
9
+ # Workspace data
10
+ workspaces/
11
+
12
+ # Logs
13
+ *.log
14
+ npm-debug.log*
15
+ yarn-debug.log*
16
+ yarn-error.log*
17
+ pnpm-debug.log*
18
+ lerna-debug.log*
19
+
20
+ # OS files
21
+ .DS_Store
22
+ Thumbs.db
23
+
24
+ # Editor directories
25
+ .vscode/
26
+ .idea/
27
+ *.swp
28
+ *.swo
29
+ *~
30
+
31
+ # Node modules (if you add custom scripts)
32
+ node_modules/
@@ -0,0 +1 @@
1
+ @TESTING.md
@@ -0,0 +1,29 @@
1
+ FROM ghcr.io/lobu-ai/lobu-worker-base:latest
2
+
3
+ # === CUSTOMIZE BELOW THIS LINE ===
4
+ # This Dockerfile extends the lobu worker base image with your custom tools and dependencies.
5
+ # The same Dockerfile works for local Docker development.
6
+
7
+ # Example: Add system packages
8
+ # RUN apt-get update && apt-get install -y \
9
+ # postgresql-client \
10
+ # && rm -rf /var/lib/apt/lists/*
11
+
12
+ # Example: Add Python packages
13
+ # RUN pip install --no-cache-dir \
14
+ # pandas \
15
+ # matplotlib \
16
+ # requests
17
+
18
+ # Example: Add Node.js packages
19
+ # RUN bun add @octokit/rest lodash
20
+
21
+ # Example: Copy custom scripts
22
+ # COPY ./scripts /workspace/scripts
23
+ # RUN chmod +x /workspace/scripts/*.sh
24
+
25
+ # Example: Set custom environment variables
26
+ # ENV MY_CUSTOM_VAR=value
27
+
28
+ # Example: Install language runtimes
29
+ # RUN curl -fsSL https://deno.land/install.sh | sh