@lobu/cli 3.0.3 → 3.0.5

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 (113) hide show
  1. package/README.md +18 -222
  2. package/dist/api/context.d.ts +20 -0
  3. package/dist/api/context.d.ts.map +1 -0
  4. package/dist/api/context.js +113 -0
  5. package/dist/api/context.js.map +1 -0
  6. package/dist/api/credentials.d.ts +9 -4
  7. package/dist/api/credentials.d.ts.map +1 -1
  8. package/dist/api/credentials.js +127 -15
  9. package/dist/api/credentials.js.map +1 -1
  10. package/dist/commands/chat.d.ts +16 -0
  11. package/dist/commands/chat.d.ts.map +1 -0
  12. package/dist/commands/chat.js +281 -0
  13. package/dist/commands/chat.js.map +1 -0
  14. package/dist/commands/context.d.ts +8 -0
  15. package/dist/commands/context.d.ts.map +1 -0
  16. package/dist/commands/context.js +46 -0
  17. package/dist/commands/context.js.map +1 -0
  18. package/dist/commands/dev.d.ts +3 -9
  19. package/dist/commands/dev.d.ts.map +1 -1
  20. package/dist/commands/dev.js +95 -64
  21. package/dist/commands/dev.js.map +1 -1
  22. package/dist/commands/init.d.ts.map +1 -1
  23. package/dist/commands/init.js +421 -673
  24. package/dist/commands/init.js.map +1 -1
  25. package/dist/commands/login.d.ts +2 -0
  26. package/dist/commands/login.d.ts.map +1 -1
  27. package/dist/commands/login.js +283 -14
  28. package/dist/commands/login.js.map +1 -1
  29. package/dist/commands/logout.d.ts +3 -1
  30. package/dist/commands/logout.d.ts.map +1 -1
  31. package/dist/commands/logout.js +5 -3
  32. package/dist/commands/logout.js.map +1 -1
  33. package/dist/commands/providers/add.d.ts.map +1 -1
  34. package/dist/commands/providers/add.js +38 -14
  35. package/dist/commands/providers/add.js.map +1 -1
  36. package/dist/commands/providers/list.d.ts.map +1 -1
  37. package/dist/commands/providers/list.js +4 -2
  38. package/dist/commands/providers/list.js.map +1 -1
  39. package/dist/commands/skills/add.d.ts.map +1 -1
  40. package/dist/commands/skills/add.js +25 -7
  41. package/dist/commands/skills/add.js.map +1 -1
  42. package/dist/commands/skills/info.d.ts.map +1 -1
  43. package/dist/commands/skills/info.js +0 -9
  44. package/dist/commands/skills/info.js.map +1 -1
  45. package/dist/commands/skills/list.d.ts.map +1 -1
  46. package/dist/commands/skills/list.js +5 -6
  47. package/dist/commands/skills/list.js.map +1 -1
  48. package/dist/commands/skills/registry.d.ts +6 -11
  49. package/dist/commands/skills/registry.d.ts.map +1 -1
  50. package/dist/commands/skills/registry.js +0 -3
  51. package/dist/commands/skills/registry.js.map +1 -1
  52. package/dist/commands/skills/search.d.ts.map +1 -1
  53. package/dist/commands/skills/search.js +3 -1
  54. package/dist/commands/skills/search.js.map +1 -1
  55. package/dist/commands/status.d.ts +1 -1
  56. package/dist/commands/status.d.ts.map +1 -1
  57. package/dist/commands/status.js +107 -4
  58. package/dist/commands/status.js.map +1 -1
  59. package/dist/commands/validate.d.ts.map +1 -1
  60. package/dist/commands/validate.js +9 -20
  61. package/dist/commands/validate.js.map +1 -1
  62. package/dist/commands/whoami.d.ts +3 -1
  63. package/dist/commands/whoami.d.ts.map +1 -1
  64. package/dist/commands/whoami.js +17 -3
  65. package/dist/commands/whoami.js.map +1 -1
  66. package/dist/config/loader.d.ts.map +1 -1
  67. package/dist/config/loader.js.map +1 -1
  68. package/dist/config/schema.d.ts +546 -111
  69. package/dist/config/schema.d.ts.map +1 -1
  70. package/dist/config/schema.js +26 -19
  71. package/dist/config/schema.js.map +1 -1
  72. package/dist/index.d.ts +0 -4
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +60 -25
  75. package/dist/index.js.map +1 -1
  76. package/dist/utils/markdown.d.ts +3 -0
  77. package/dist/utils/markdown.d.ts.map +1 -0
  78. package/dist/utils/markdown.js +10 -0
  79. package/dist/utils/markdown.js.map +1 -0
  80. package/package.json +4 -3
  81. package/dist/api/client.d.ts +0 -11
  82. package/dist/api/client.d.ts.map +0 -1
  83. package/dist/api/client.js +0 -35
  84. package/dist/api/client.js.map +0 -1
  85. package/dist/commands/launch.d.ts +0 -6
  86. package/dist/commands/launch.d.ts.map +0 -1
  87. package/dist/commands/launch.js +0 -32
  88. package/dist/commands/launch.js.map +0 -1
  89. package/dist/config/transformer.d.ts +0 -11
  90. package/dist/config/transformer.d.ts.map +0 -1
  91. package/dist/config/transformer.js +0 -49
  92. package/dist/config/transformer.js.map +0 -1
  93. package/dist/mcp-servers.d.ts +0 -11
  94. package/dist/mcp-servers.d.ts.map +0 -1
  95. package/dist/mcp-servers.js +0 -27
  96. package/dist/mcp-servers.js.map +0 -1
  97. package/dist/mcp-servers.json +0 -216
  98. package/dist/system-skills.json +0 -561
  99. package/dist/templates/.env.tmpl +0 -29
  100. package/dist/templates/.gitignore.tmpl +0 -32
  101. package/dist/templates/AGENTS.md.tmpl +0 -1
  102. package/dist/templates/Dockerfile.worker.tmpl +0 -29
  103. package/dist/templates/README.md.tmpl +0 -95
  104. package/dist/templates/TESTING.md.tmpl +0 -225
  105. package/dist/templates/lobu.toml.tmpl +0 -44
  106. package/dist/types.d.ts +0 -76
  107. package/dist/types.d.ts.map +0 -1
  108. package/dist/types.js +0 -2
  109. package/dist/types.js.map +0 -1
  110. package/dist/utils/config.d.ts +0 -2
  111. package/dist/utils/config.d.ts.map +0 -1
  112. package/dist/utils/config.js +0 -13
  113. package/dist/utils/config.js.map +0 -1
package/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  CLI tool for initializing and managing Lobu projects.
4
4
 
5
- ## Installation
6
-
7
- ### npx (Recommended)
5
+ ## Quick Start
8
6
 
9
7
  ```bash
10
8
  npx @lobu/cli init my-bot
@@ -12,106 +10,26 @@ cd my-bot
12
10
  docker compose up -d
13
11
  ```
14
12
 
15
- ### Global Install
16
-
17
- ```bash
18
- npm install -g @lobu/cli
19
-
20
- lobu init my-bot
21
- cd my-bot
22
- docker compose up -d
23
- ```
24
-
25
- ## Worker Deployment Options
26
-
27
- Lobu supports two deployment patterns for workers:
28
-
29
- ### Option 1: Base Image (Day 0 - Quick Start)
30
-
31
- **Best for:** Beginners, tutorials, quick prototypes
32
-
33
- ```dockerfile
34
- # Extends our curated base image
35
- FROM buremba/lobu-worker-base:0.1.0
36
-
37
- # Add your customizations
38
- RUN pip install pandas
39
- RUN apt-get install postgresql-client
40
- ```
41
-
42
- **Pros:**
43
- - Turnkey experience - just works
44
- - All dependencies pre-installed
45
- - Predictable environment
46
-
47
- **Cons:**
48
- - Stuck with our base OS choice
49
- - May not meet compliance requirements
50
-
51
- ---
52
-
53
- ### Option 2: Package Installation (Day 2 - Advanced)
54
-
55
- **Best for:** Enterprise, compliance-heavy environments, custom requirements
56
-
57
- ```dockerfile
58
- # Use YOUR approved base image
59
- FROM company-registry/ubuntu:22.04
60
-
61
- # Install system dependencies
62
- RUN apt-get update && apt-get install -y \
63
- nodejs npm git docker.io python3 curl
64
-
65
- # Install Claude CLI
66
- RUN curl -L https://claude.ai/install.sh | sh
67
-
68
- # Install Lobu worker as a package
69
- RUN npm install -g @lobu/worker@^0.1.0
70
-
71
- # Your customizations
72
- COPY ./scripts /workspace/scripts
73
-
74
- CMD ["lobu-worker"]
75
- ```
76
-
77
- **Pros:**
78
- - Full control over base OS
79
- - Use company-approved images
80
- - Smaller images (Alpine, Distroless)
81
- - Meet security/compliance requirements
82
-
83
- **Cons:**
84
- - More setup required
85
- - Must install system dependencies yourself
86
-
87
- See [Worker Package Documentation](../worker/docs/custom-base-image.md) for details.
88
-
89
- ---
90
-
91
13
  ## Commands
92
14
 
93
- ### `lobu init`
94
-
95
- Initialize a new Lobu project in the current directory.
15
+ ### `lobu init [name]`
96
16
 
97
- **Interactive prompts:**
98
- - **Worker mode:** Base image vs Package installation
99
- - Slack credentials
100
- - Anthropic API key
101
- - Public gateway URL (for OAuth)
17
+ Scaffold a new Lobu project with interactive prompts:
102
18
 
103
- **Generates:**
104
- - `docker-compose.yml` - Service definitions (redis, gateway, worker)
105
- - `.env` - Credentials
106
- - `Dockerfile.worker` - Worker customization via Dockerfile
107
- - `.gitignore`, `README.md`
19
+ - **Project name** and **deployment mode** (embedded/Docker workers)
20
+ - **Gateway port** and optional **public URL** (for OAuth callbacks)
21
+ - **Admin password**
22
+ - **Worker network access** (isolated, allowlist, or unrestricted)
23
+ - **AI provider** selection from the skills registry + API key
24
+ - **Skills** to enable (from `config/system-skills.json`)
25
+ - **Messaging platform** (Telegram, Slack, Discord, or none)
26
+ - **Auth provider** (Owletto, custom, or none)
27
+ - **Memory plugin** configuration
108
28
 
109
- **If docker-compose.yml exists**, you'll be prompted for an alternative filename.
29
+ **Generates:** `docker-compose.yml`, `.env`, `Dockerfile.worker`, `lobu.toml`, `IDENTITY.md`, `.gitignore`, `README.md`
110
30
 
111
31
  ## Usage
112
32
 
113
- After running `npx @lobu/cli init`:
114
-
115
33
  ```bash
116
34
  # Start services
117
35
  docker compose up -d
@@ -126,12 +44,12 @@ docker compose down
126
44
  docker compose build worker
127
45
  ```
128
46
 
129
- ## Configuration
47
+ ## Worker Customization
130
48
 
131
- ### Dockerfile.worker (Base Image Mode)
49
+ Extend the generated `Dockerfile.worker` to add tools:
132
50
 
133
51
  ```dockerfile
134
- FROM buremba/lobu-worker-base:0.1.0
52
+ FROM ghcr.io/lobu-ai/lobu-worker-base:0.1.0
135
53
 
136
54
  # Add system packages
137
55
  RUN apt-get update && apt-get install -y postgresql-client
@@ -139,134 +57,12 @@ RUN apt-get update && apt-get install -y postgresql-client
139
57
  # Add Python packages
140
58
  RUN pip install pandas matplotlib
141
59
 
142
- # Add Node.js packages
143
- RUN bun add @octokit/rest
144
-
145
60
  # Copy custom scripts
146
61
  COPY ./scripts /workspace/scripts
147
62
  ```
148
63
 
149
- ### Dockerfile.worker (Package Mode)
150
-
151
- ```dockerfile
152
- # Bring your own base
153
- FROM node:20-alpine
154
-
155
- # Install required system dependencies
156
- RUN apk add --no-cache git docker-cli python3 py3-pip curl
157
-
158
- # Install Claude CLI
159
- RUN curl -L https://claude.ai/install.sh | sh
160
-
161
- # Install worker package
162
- RUN npm install -g @lobu/worker@^0.1.0
163
-
164
- # Your customizations
165
- RUN pip3 install pandas matplotlib
166
-
167
- CMD ["lobu-worker"]
168
- ```
169
-
170
- ## Development Workflow
171
-
172
- ```bash
173
- # 1. Create project
174
- npx @lobu/cli init my-bot
175
-
176
- # 2. Choose worker mode during init
177
- # - Base image (recommended)
178
- # - Package installation (advanced)
179
-
180
- # 3. Customize worker (optional)
181
- # Edit Dockerfile.worker
182
-
183
- # 4. Start services
184
- cd my-bot
185
- docker compose up -d
186
-
187
- # 5. View logs
188
- docker compose logs -f
189
-
190
- # 6. Rebuild after changes
191
- docker compose build worker
192
-
193
- # 7. Stop services
194
- docker compose down
195
- ```
196
-
197
- ## Version Locking
198
-
199
- The CLI version locks to base image versions:
200
-
201
- - CLI `0.1.0` -> `buremba/lobu-worker-base:0.1.0`
202
- - CLI `0.2.0` -> `buremba/lobu-worker-base:0.2.0`
203
-
204
- This ensures compatibility between CLI and runtime images.
205
-
206
- ## Distribution Strategy
207
-
208
- Lobu uses a dual distribution pattern:
209
-
210
- **Day 0 (Quick Start):**
211
- - Use `buremba/lobu-worker-base` Docker image
212
- - Extend with Dockerfile
213
- - Perfect for learning, prototypes
214
-
215
- **Day 2+ (Production):**
216
- - Install `@lobu/worker` npm package
217
- - Use your own base image
218
- - Perfect for enterprise, compliance
219
-
220
- ## Published Artifacts
221
-
222
- **Docker Hub:**
223
- ```bash
224
- # For production (gateway)
225
- docker pull buremba/lobu-gateway:0.1.0
226
-
227
- # For quick start (extend this)
228
- docker pull buremba/lobu-worker-base:0.1.0
229
- ```
230
-
231
- **NPM Registry:**
232
- ```bash
233
- # CLI tool
234
- npm install -g @lobu/cli
235
-
236
- # Worker runtime (for custom base images)
237
- npm install -g @lobu/worker@0.1.0
238
- ```
239
-
240
- ## Architecture
241
-
242
- ```
243
- User creates project
244
- |
245
- npx @lobu/cli init my-bot
246
- |
247
- Choose: Base image or Package?
248
- |
249
- +---------------+----------------+
250
- | Base Image Mode | Package Mode
251
- | |
252
- | FROM lobu-worker-base | FROM your-company/base
253
- | RUN pip install pandas | RUN npm install -g @lobu/worker
254
- | | RUN pip install pandas
255
- +---------------+----------------+
256
- |
257
- CLI generates docker-compose.yml
258
- |
259
- User runs: docker compose up -d
260
- |
261
- Docker builds worker:latest
262
- |
263
- Gateway spawns workers dynamically
264
- ```
265
-
266
- ## Contributing
267
-
268
- Lobu CLI generates Docker Compose configurations. To modify the generated setup, see `src/commands/init.ts`.
64
+ See [custom base image docs](../worker/docs/custom-base-image.md) for using your own base image.
269
65
 
270
66
  ## License
271
67
 
272
- MIT
68
+ Apache-2.0
@@ -0,0 +1,20 @@
1
+ export declare const LOBU_CONFIG_DIR: string;
2
+ export declare const DEFAULT_CONTEXT_NAME = "community";
3
+ export interface LobuContextEntry {
4
+ apiUrl: string;
5
+ }
6
+ export interface LobuContextConfig {
7
+ currentContext: string;
8
+ contexts: Record<string, LobuContextEntry>;
9
+ }
10
+ export interface ResolvedContext {
11
+ name: string;
12
+ apiUrl: string;
13
+ source: "default" | "config" | "env";
14
+ }
15
+ export declare function loadContextConfig(): Promise<LobuContextConfig>;
16
+ export declare function getCurrentContextName(): Promise<string>;
17
+ export declare function resolveContext(preferredContext?: string): Promise<ResolvedContext>;
18
+ export declare function addContext(name: string, apiUrl: string): Promise<LobuContextConfig>;
19
+ export declare function setCurrentContext(name: string): Promise<LobuContextConfig>;
20
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,QAAqC,CAAC;AAClE,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAKhD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,KAAK,CAAC;CACtC;AAOD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAQpE;AASD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ7D;AAED,wBAAsB,cAAc,CAClC,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,eAAe,CAAC,CA2B1B;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC,CAY5B;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,CAgB5B"}
@@ -0,0 +1,113 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ export const LOBU_CONFIG_DIR = join(homedir(), ".config", "lobu");
5
+ export const DEFAULT_CONTEXT_NAME = "community";
6
+ const DEFAULT_API_URL = "https://community.lobu.ai/api/v1";
7
+ const CONTEXTS_FILE = join(LOBU_CONFIG_DIR, "config.json");
8
+ export async function loadContextConfig() {
9
+ try {
10
+ const raw = await readFile(CONTEXTS_FILE, "utf-8");
11
+ const parsed = JSON.parse(raw);
12
+ return normalizeContextConfig(parsed);
13
+ }
14
+ catch {
15
+ return normalizeContextConfig({});
16
+ }
17
+ }
18
+ async function saveContextConfig(config) {
19
+ await mkdir(LOBU_CONFIG_DIR, { recursive: true });
20
+ await writeFile(CONTEXTS_FILE, JSON.stringify(config, null, 2), {
21
+ mode: 0o600,
22
+ });
23
+ }
24
+ export async function getCurrentContextName() {
25
+ const envContext = process.env.LOBU_CONTEXT?.trim();
26
+ if (envContext) {
27
+ return envContext;
28
+ }
29
+ const config = await loadContextConfig();
30
+ return config.currentContext;
31
+ }
32
+ export async function resolveContext(preferredContext) {
33
+ const envApiUrl = process.env.LOBU_API_URL?.trim();
34
+ const requestedContext = preferredContext?.trim() || process.env.LOBU_CONTEXT?.trim();
35
+ if (envApiUrl) {
36
+ return {
37
+ name: requestedContext || (await getCurrentContextName()),
38
+ apiUrl: normalizeApiUrl(envApiUrl),
39
+ source: "env",
40
+ };
41
+ }
42
+ const config = await loadContextConfig();
43
+ const contextName = requestedContext || config.currentContext;
44
+ const context = config.contexts[contextName];
45
+ if (context) {
46
+ return {
47
+ name: contextName,
48
+ apiUrl: normalizeApiUrl(context.apiUrl),
49
+ source: contextName === DEFAULT_CONTEXT_NAME ? "default" : "config",
50
+ };
51
+ }
52
+ throw new Error(`Unknown context "${contextName}". Run \`lobu context list\` to see configured contexts.`);
53
+ }
54
+ export async function addContext(name, apiUrl) {
55
+ const trimmedName = name.trim();
56
+ if (!trimmedName) {
57
+ throw new Error("Context name cannot be empty.");
58
+ }
59
+ const config = await loadContextConfig();
60
+ config.contexts[trimmedName] = {
61
+ apiUrl: normalizeAndValidateApiUrl(apiUrl),
62
+ };
63
+ await saveContextConfig(config);
64
+ return config;
65
+ }
66
+ export async function setCurrentContext(name) {
67
+ const trimmedName = name.trim();
68
+ if (!trimmedName) {
69
+ throw new Error("Context name cannot be empty.");
70
+ }
71
+ const config = await loadContextConfig();
72
+ if (!config.contexts[trimmedName]) {
73
+ throw new Error(`Unknown context "${trimmedName}". Run \`lobu context add ${trimmedName} --api-url <url>\` first.`);
74
+ }
75
+ config.currentContext = trimmedName;
76
+ await saveContextConfig(config);
77
+ return config;
78
+ }
79
+ function normalizeContextConfig(raw) {
80
+ const contexts = {
81
+ [DEFAULT_CONTEXT_NAME]: { apiUrl: DEFAULT_API_URL },
82
+ };
83
+ for (const [name, value] of Object.entries(raw.contexts ?? {})) {
84
+ if (!value || typeof value.apiUrl !== "string") {
85
+ continue;
86
+ }
87
+ contexts[name] = { apiUrl: normalizeApiUrl(value.apiUrl) };
88
+ }
89
+ const currentContext = raw.currentContext && contexts[raw.currentContext]
90
+ ? raw.currentContext
91
+ : DEFAULT_CONTEXT_NAME;
92
+ return { currentContext, contexts };
93
+ }
94
+ function normalizeAndValidateApiUrl(apiUrl) {
95
+ const normalized = normalizeApiUrl(apiUrl.trim());
96
+ if (!normalized) {
97
+ throw new Error("API URL cannot be empty.");
98
+ }
99
+ try {
100
+ const parsed = new URL(normalized);
101
+ if (!parsed.protocol || !parsed.host) {
102
+ throw new Error("Missing protocol or host");
103
+ }
104
+ }
105
+ catch {
106
+ throw new Error(`Invalid API URL: ${apiUrl}`);
107
+ }
108
+ return normalized;
109
+ }
110
+ function normalizeApiUrl(url) {
111
+ return url.replace(/\/+$/, "");
112
+ }
113
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,18 @@
1
1
  export interface Credentials {
2
- token: string;
2
+ accessToken: string;
3
+ refreshToken?: string;
4
+ expiresAt?: number;
3
5
  email?: string;
6
+ name?: string;
7
+ userId?: string;
4
8
  agentId?: string;
5
9
  }
6
- export declare function loadCredentials(): Promise<Credentials | null>;
7
- export declare function saveCredentials(creds: Credentials): Promise<void>;
8
- export declare function clearCredentials(): Promise<void>;
10
+ export declare function loadCredentials(contextName?: string): Promise<Credentials | null>;
11
+ export declare function saveCredentials(creds: Credentials, contextName?: string): Promise<void>;
12
+ export declare function clearCredentials(contextName?: string): Promise<void>;
9
13
  /**
10
14
  * Get token from env var (CI/CD) or stored credentials.
11
15
  */
12
16
  export declare function getToken(): Promise<string | null>;
17
+ export declare function refreshCredentials(existing?: Credentials | null, contextName?: string): Promise<Credentials | null>;
13
18
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/api/credentials.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAOnE;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAKvE;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMvD"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/api/credentials.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,wBAAsB,eAAe,CACnC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAmB7B;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,WAAW,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB1E;AAED;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBvD;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,EAC7B,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA+C7B"}
@@ -1,30 +1,48 @@
1
1
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
2
  import { join } from "node:path";
4
- const CONFIG_DIR = join(homedir(), ".config", "lobu");
5
- const CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
6
- export async function loadCredentials() {
3
+ import { DEFAULT_CONTEXT_NAME, LOBU_CONFIG_DIR, resolveContext, } from "./context.js";
4
+ const CREDENTIALS_FILE = join(LOBU_CONFIG_DIR, "credentials.json");
5
+ export async function loadCredentials(contextName) {
6
+ const target = await resolveContext(contextName);
7
7
  try {
8
8
  const raw = await readFile(CREDENTIALS_FILE, "utf-8");
9
- return JSON.parse(raw);
9
+ const parsed = JSON.parse(raw);
10
+ const stored = isCredentialsStore(parsed)
11
+ ? parsed.contexts[target.name]
12
+ : target.name === DEFAULT_CONTEXT_NAME
13
+ ? parsed
14
+ : null;
15
+ return normalizeCredentials(stored);
10
16
  }
11
17
  catch {
12
18
  return null;
13
19
  }
14
20
  }
15
- export async function saveCredentials(creds) {
16
- await mkdir(CONFIG_DIR, { recursive: true });
17
- await writeFile(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), {
21
+ export async function saveCredentials(creds, contextName) {
22
+ const target = await resolveContext(contextName);
23
+ const store = await loadCredentialStore();
24
+ store.contexts[target.name] = creds;
25
+ await mkdir(LOBU_CONFIG_DIR, { recursive: true });
26
+ await writeFile(CREDENTIALS_FILE, JSON.stringify(store, null, 2), {
18
27
  mode: 0o600,
19
28
  });
20
29
  }
21
- export async function clearCredentials() {
22
- try {
23
- await rm(CREDENTIALS_FILE);
24
- }
25
- catch {
26
- // File doesn't exist, nothing to clear
30
+ export async function clearCredentials(contextName) {
31
+ const target = await resolveContext(contextName);
32
+ const store = await loadCredentialStore();
33
+ delete store.contexts[target.name];
34
+ if (Object.keys(store.contexts).length === 0) {
35
+ try {
36
+ await rm(CREDENTIALS_FILE);
37
+ }
38
+ catch {
39
+ // File doesn't exist, nothing to clear.
40
+ }
41
+ return;
27
42
  }
43
+ await writeFile(CREDENTIALS_FILE, JSON.stringify(store, null, 2), {
44
+ mode: 0o600,
45
+ });
28
46
  }
29
47
  /**
30
48
  * Get token from env var (CI/CD) or stored credentials.
@@ -34,6 +52,100 @@ export async function getToken() {
34
52
  if (envToken)
35
53
  return envToken;
36
54
  const creds = await loadCredentials();
37
- return creds?.token ?? null;
55
+ if (!creds)
56
+ return null;
57
+ if (!needsRefresh(creds)) {
58
+ return creds.accessToken;
59
+ }
60
+ if (!creds.refreshToken) {
61
+ return null;
62
+ }
63
+ const refreshed = await refreshCredentials(creds);
64
+ return refreshed?.accessToken ?? null;
65
+ }
66
+ export async function refreshCredentials(existing, contextName) {
67
+ const target = await resolveContext(contextName);
68
+ const creds = existing ?? (await loadCredentials(target.name));
69
+ if (!creds?.refreshToken) {
70
+ return creds ?? null;
71
+ }
72
+ try {
73
+ const response = await fetch(`${target.apiUrl}/auth/refresh`, {
74
+ method: "POST",
75
+ headers: {
76
+ "Content-Type": "application/json",
77
+ "X-Lobu-Org": "default",
78
+ },
79
+ body: JSON.stringify({ refreshToken: creds.refreshToken }),
80
+ });
81
+ if (!response.ok) {
82
+ return null;
83
+ }
84
+ const body = (await response.json());
85
+ const refreshed = {
86
+ ...creds,
87
+ accessToken: body.accessToken,
88
+ refreshToken: body.refreshToken || creds.refreshToken,
89
+ expiresAt: body.expiresAt,
90
+ email: body.user?.email ?? creds.email,
91
+ name: body.user?.name ?? creds.name,
92
+ userId: body.user?.userId ?? creds.userId,
93
+ };
94
+ await saveCredentials(refreshed, target.name);
95
+ return refreshed;
96
+ }
97
+ catch {
98
+ return null;
99
+ }
100
+ }
101
+ function needsRefresh(creds) {
102
+ return (typeof creds.expiresAt === "number" &&
103
+ creds.expiresAt - 60_000 <= Date.now());
104
+ }
105
+ async function loadCredentialStore() {
106
+ try {
107
+ const raw = await readFile(CREDENTIALS_FILE, "utf-8");
108
+ const parsed = JSON.parse(raw);
109
+ if (isCredentialsStore(parsed)) {
110
+ return {
111
+ version: 2,
112
+ contexts: Object.fromEntries(Object.entries(parsed.contexts)
113
+ .map(([name, value]) => [name, normalizeCredentials(value)])
114
+ .filter((entry) => !!entry[1])),
115
+ };
116
+ }
117
+ const legacy = normalizeCredentials(parsed);
118
+ return {
119
+ version: 2,
120
+ contexts: legacy ? { [DEFAULT_CONTEXT_NAME]: legacy } : {},
121
+ };
122
+ }
123
+ catch {
124
+ return {
125
+ version: 2,
126
+ contexts: {},
127
+ };
128
+ }
129
+ }
130
+ function isCredentialsStore(value) {
131
+ if (!value || typeof value !== "object") {
132
+ return false;
133
+ }
134
+ return ("contexts" in value &&
135
+ !!value.contexts &&
136
+ typeof value.contexts === "object");
137
+ }
138
+ function normalizeCredentials(value) {
139
+ if (!value || typeof value !== "object") {
140
+ return null;
141
+ }
142
+ const accessToken = value.accessToken;
143
+ if (!accessToken) {
144
+ return null;
145
+ }
146
+ return {
147
+ ...value,
148
+ accessToken,
149
+ };
38
150
  }
39
151
  //# sourceMappingURL=credentials.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/api/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AACtD,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAQ9D,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAkB;IACtD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAChE,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;IACtC,OAAO,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/api/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `lobu chat "prompt"` — send a prompt to an agent and stream the response.
3
+ *
4
+ * Without --user: API mode — creates a session, sends message, streams to terminal.
5
+ * With --user platform:id: Platform mode — sends through Telegram/Slack, response
6
+ * appears on the platform. Terminal shows the streamed response too.
7
+ */
8
+ export declare function chatCommand(cwd: string, prompt: string, options: {
9
+ agent?: string;
10
+ gateway?: string;
11
+ user?: string;
12
+ thread?: string;
13
+ dryRun?: boolean;
14
+ new?: boolean;
15
+ }): Promise<void>;
16
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,GACA,OAAO,CAAC,IAAI,CAAC,CAuCf"}