@cobaltio/cobalt-js 9.2.0-beta.6 → 9.2.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/.claude/skills/method/SKILL.md +282 -0
- package/.claude/skills/review-pr/SKILL.md +80 -0
- package/.claude/skills/style/SKILL.md +67 -0
- package/.claude/skills/verify/SKILL.md +85 -0
- package/.github/workflows/npm-publish.yml +6 -7
- package/CLAUDE.md +99 -19
- package/cobalt.d.ts +72 -63
- package/cobalt.js +422 -365
- package/cobalt.ts +101 -123
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/main.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Cobalt.html +42 -33
- package/docs/enums/AuthStatus.html +2 -2
- package/docs/enums/AuthType.html +3 -3
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +1 -1
- package/docs/interfaces/Application.html +19 -15
- package/docs/interfaces/CobaltOptions.html +3 -3
- package/docs/interfaces/Config.html +2 -2
- package/docs/interfaces/ConfigField.html +4 -4
- package/docs/interfaces/ConfigPayload.html +5 -5
- package/docs/interfaces/ConfigWorkflow.html +2 -2
- package/docs/interfaces/ExecuteWorkflowPayload.html +5 -5
- package/docs/interfaces/Execution.html +2 -2
- package/docs/interfaces/ExecutionFilters.html +16 -0
- package/docs/interfaces/GetExecutionsParams.html +19 -0
- package/docs/interfaces/InputField.html +10 -10
- package/docs/interfaces/Label.html +4 -4
- package/docs/interfaces/PublicWorkflow.html +9 -9
- package/docs/interfaces/PublicWorkflowPayload.html +5 -5
- package/docs/interfaces/PublicWorkflowsPayload.html +13 -2
- package/docs/interfaces/RuleOptions.html +2 -2
- package/docs/interfaces/UpdateConfigPayload.html +6 -6
- package/docs/interfaces/WorkflowPayload.html +5 -5
- package/docs/interfaces/WorkflowPayloadResponse.html +2 -2
- package/docs/llms.txt +260 -248
- package/docs/modules.html +1 -1
- package/docs/types/ExecutionSource.html +2 -0
- package/docs/types/ExecutionStatus.html +2 -0
- package/docs/types/ExecutionType.html +2 -0
- package/package.json +4 -4
- package/tsconfig.json +12 -12
- package/docs/interfaces/AuthConfig.html +0 -9
- package/docs/interfaces/ConnectedAccount.html +0 -14
- package/docs/interfaces/KeyBasedParams.html +0 -7
- package/docs/interfaces/OAuthParams.html +0 -9
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: method
|
|
3
|
+
description: Add a new public API method to the Cobalt SDK with types, JSDoc, and endpoint mapping. Use when adding new SDK functionality.
|
|
4
|
+
metadata:
|
|
5
|
+
author: iamtraction
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
argument-hint: <method-name>
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Add SDK Method
|
|
11
|
+
|
|
12
|
+
Add a new public API method to the Cobalt class with TypeScript types, JSDoc documentation, and backend endpoint mapping.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
The user provides a method name (e.g., "getWorkflows", "createConfig") and describes the backend endpoint it maps to.
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
1. **Ask for details** if not provided: method name, HTTP method, endpoint URL, request payload shape, response shape, whether it supports pagination
|
|
21
|
+
2. **Define TypeScript interfaces** — request payload and response types
|
|
22
|
+
3. **Add JSDoc-documented method** to the `Cobalt` class
|
|
23
|
+
4. **Build** to verify compilation
|
|
24
|
+
|
|
25
|
+
## Implementation Order
|
|
26
|
+
|
|
27
|
+
1. **Interfaces** — Define request/response types (before the class)
|
|
28
|
+
2. **Method** — Add to `Cobalt` class with JSDoc
|
|
29
|
+
3. **Build** — Run `npm run build` to generate `.js` and `.d.ts`
|
|
30
|
+
|
|
31
|
+
## Interface Template
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// Add before the Cobalt class in cobalt.ts
|
|
35
|
+
|
|
36
|
+
/** The payload for creating a resource. */
|
|
37
|
+
export interface CreateResourcePayload {
|
|
38
|
+
/** The resource name. */
|
|
39
|
+
name: string;
|
|
40
|
+
/** Optional description. */
|
|
41
|
+
description?: string;
|
|
42
|
+
/** Configuration object. */
|
|
43
|
+
config?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** A resource object. */
|
|
47
|
+
export interface Resource {
|
|
48
|
+
/** The resource ID. */
|
|
49
|
+
_id: string;
|
|
50
|
+
/** The resource name. */
|
|
51
|
+
name: string;
|
|
52
|
+
/** The resource description. */
|
|
53
|
+
description?: string;
|
|
54
|
+
/** When the resource was created. */
|
|
55
|
+
createdAt: string;
|
|
56
|
+
/** When the resource was last updated. */
|
|
57
|
+
updatedAt: string;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Method Templates
|
|
62
|
+
|
|
63
|
+
### GET Request (single item)
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
/**
|
|
67
|
+
* Returns the resource details for the specified resource ID.
|
|
68
|
+
* @param {String} id The resource ID.
|
|
69
|
+
* @returns {Promise<Resource>} The resource details.
|
|
70
|
+
*/
|
|
71
|
+
public async getResource(id: string): Promise<Resource> {
|
|
72
|
+
const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/resource/${id}`, {
|
|
73
|
+
headers: {
|
|
74
|
+
authorization: `Bearer ${this.token}`,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (res.status >= 400 && res.status < 600) {
|
|
79
|
+
const error = await res.json();
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return await res.json();
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### GET Request (list with optional overloads)
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
/**
|
|
91
|
+
* Returns the list of all resources.
|
|
92
|
+
* @returns {Promise<Resource[]>} The list of resources.
|
|
93
|
+
*/
|
|
94
|
+
public async getResources(): Promise<Resource[]>;
|
|
95
|
+
/**
|
|
96
|
+
* Returns the resource details for the specified slug.
|
|
97
|
+
* @param {String} slug The resource slug.
|
|
98
|
+
* @returns {Promise<Resource>} The resource details.
|
|
99
|
+
*/
|
|
100
|
+
public async getResources(slug: string): Promise<Resource>;
|
|
101
|
+
public async getResources(slug?: string): Promise<Resource | Resource[]> {
|
|
102
|
+
const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/resource${slug ? `/${slug}` : ""}`, {
|
|
103
|
+
headers: {
|
|
104
|
+
authorization: `Bearer ${this.token}`,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (res.status >= 400 && res.status < 600) {
|
|
109
|
+
const error = await res.json();
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return await res.json();
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### POST Request (with JSON body)
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
/**
|
|
121
|
+
* Creates a new resource with the specified configuration.
|
|
122
|
+
* @param {CreateResourcePayload} payload The resource configuration.
|
|
123
|
+
* @returns {Promise<Resource>} The created resource.
|
|
124
|
+
*/
|
|
125
|
+
public async createResource(payload: CreateResourcePayload): Promise<Resource> {
|
|
126
|
+
const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/resource`, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: {
|
|
129
|
+
authorization: `Bearer ${this.token}`,
|
|
130
|
+
"content-type": "application/json",
|
|
131
|
+
},
|
|
132
|
+
body: JSON.stringify(payload),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if (res.status >= 400 && res.status < 600) {
|
|
136
|
+
const error = await res.json();
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return await res.json();
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### PUT Request (update)
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
/**
|
|
148
|
+
* Updates an existing resource.
|
|
149
|
+
* @param {String} id The resource ID.
|
|
150
|
+
* @param {Partial<CreateResourcePayload>} payload The fields to update.
|
|
151
|
+
* @returns {Promise<Resource>} The updated resource.
|
|
152
|
+
*/
|
|
153
|
+
public async updateResource(id: string, payload: Partial<CreateResourcePayload>): Promise<Resource> {
|
|
154
|
+
const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/resource/${id}`, {
|
|
155
|
+
method: "PUT",
|
|
156
|
+
headers: {
|
|
157
|
+
authorization: `Bearer ${this.token}`,
|
|
158
|
+
"content-type": "application/json",
|
|
159
|
+
},
|
|
160
|
+
body: JSON.stringify(payload),
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if (res.status >= 400 && res.status < 600) {
|
|
164
|
+
const error = await res.json();
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return await res.json();
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### DELETE Request
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
/**
|
|
176
|
+
* Deletes the specified resource.
|
|
177
|
+
* @param {String} id The resource ID.
|
|
178
|
+
* @returns {Promise<unknown>} The deletion result.
|
|
179
|
+
*/
|
|
180
|
+
public async deleteResource(id: string): Promise<unknown> {
|
|
181
|
+
const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/resource/${id}`, {
|
|
182
|
+
method: "DELETE",
|
|
183
|
+
headers: {
|
|
184
|
+
authorization: `Bearer ${this.token}`,
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (res.status >= 400 && res.status < 600) {
|
|
189
|
+
const error = await res.json();
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return await res.json();
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Paginated GET Request
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
/**
|
|
201
|
+
* Returns a paginated list of resources.
|
|
202
|
+
* @param {Object} [params] Pagination parameters.
|
|
203
|
+
* @param {Number} [params.page] The page number.
|
|
204
|
+
* @param {Number} [params.limit] The number of items per page.
|
|
205
|
+
* @returns {Promise<PaginatedResponse<Resource>>} The paginated list.
|
|
206
|
+
*/
|
|
207
|
+
public async listResources(params?: { page?: number; limit?: number }): Promise<PaginatedResponse<Resource>> {
|
|
208
|
+
const query = new URLSearchParams();
|
|
209
|
+
if (params?.page) query.set("page", String(params.page));
|
|
210
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
211
|
+
|
|
212
|
+
const res = await fetch(`${this.baseUrl}/api/v2/f-sdk/resources?${query}`, {
|
|
213
|
+
headers: {
|
|
214
|
+
authorization: `Bearer ${this.token}`,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
if (res.status >= 400 && res.status < 600) {
|
|
219
|
+
const error = await res.json();
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return await res.json();
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Existing Patterns Reference
|
|
228
|
+
|
|
229
|
+
### Error Handling Pattern (used by ALL methods)
|
|
230
|
+
```ts
|
|
231
|
+
if (res.status >= 400 && res.status < 600) {
|
|
232
|
+
const error = await res.json();
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Auth Header (used by ALL methods)
|
|
238
|
+
```ts
|
|
239
|
+
headers: {
|
|
240
|
+
authorization: `Bearer ${this.token}`,
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Custom Headers (some methods pass app slug)
|
|
245
|
+
```ts
|
|
246
|
+
headers: {
|
|
247
|
+
authorization: `Bearer ${this.token}`,
|
|
248
|
+
"content-type": "application/json",
|
|
249
|
+
slug, // Custom header for app context
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### PaginatedResponse Generic
|
|
254
|
+
```ts
|
|
255
|
+
interface PaginatedResponse<T> {
|
|
256
|
+
docs: T[];
|
|
257
|
+
totalDocs: number;
|
|
258
|
+
limit: number;
|
|
259
|
+
totalPages: number;
|
|
260
|
+
page: number;
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Verification
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
npm run build # Compile to cobalt.js + cobalt.d.ts
|
|
268
|
+
npm run docs:llms # Generate TypeDoc (optional)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Important
|
|
272
|
+
|
|
273
|
+
- **Zero dependencies** — only use native `fetch`, no external HTTP libraries
|
|
274
|
+
- **JSDoc on every method** — TypeDoc generates SDK documentation from these
|
|
275
|
+
- **JSDoc on every interface field** — include description for each property
|
|
276
|
+
- **Method overloads** — use TypeScript overloads for methods with optional parameters that change return type
|
|
277
|
+
- **Error handling** — always check `res.status >= 400 && res.status < 600` and throw the parsed error
|
|
278
|
+
- **`Bearer` auth** — all methods include `authorization: Bearer ${this.token}`
|
|
279
|
+
- **Single file** — everything goes in `cobalt.ts`, no separate files
|
|
280
|
+
- **Export interfaces** — all types are exported for consumer use
|
|
281
|
+
- **Backward compatibility** — never rename or remove existing methods, use `@deprecated` JSDoc tag
|
|
282
|
+
- **Build output** — `cobalt.js` (CommonJS) + `cobalt.d.ts` (type declarations)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-pr
|
|
3
|
+
description: Review a pull request for code quality, patterns consistency, and potential issues. Use when asked to review a PR by number or URL.
|
|
4
|
+
metadata:
|
|
5
|
+
author: iamtraction
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
argument-hint: <pr-number-or-url>
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Review Pull Request
|
|
11
|
+
|
|
12
|
+
Perform a thorough code review of a GitHub pull request.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
The user provides a PR number or URL (e.g., `123`, `https://github.com/gocobalt/cobalt-js/pull/123`).
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
1. **Fetch PR details** using `gh pr view {number} --json title,body,files,additions,deletions,baseRefName,headRefName`
|
|
21
|
+
2. **Fetch the diff** using `gh pr diff {number}`
|
|
22
|
+
3. **Analyze every changed file** against the checklist below
|
|
23
|
+
4. **Output a structured review** with findings grouped by severity
|
|
24
|
+
|
|
25
|
+
## Review Checklist
|
|
26
|
+
|
|
27
|
+
### SDK Design
|
|
28
|
+
- Zero runtime dependencies maintained — no new `dependencies` added to package.json
|
|
29
|
+
- Public API backward compatible — no breaking changes without major version bump
|
|
30
|
+
- Deprecated methods/fields marked with `@deprecated` JSDoc, not removed
|
|
31
|
+
- New public methods have JSDoc with `@param` and `@returns`
|
|
32
|
+
- New interfaces/types exported correctly
|
|
33
|
+
- Error handling follows existing pattern: throw parsed JSON for 4xx/5xx responses
|
|
34
|
+
- Native `fetch` API used — no axios, node-fetch, or other HTTP libraries
|
|
35
|
+
- OAuth popup flow: no changes that break `window.open()` + polling pattern
|
|
36
|
+
|
|
37
|
+
### Code Quality
|
|
38
|
+
- TypeScript strict mode passes — no `any` types unless truly unavoidable
|
|
39
|
+
- All public methods have explicit return types
|
|
40
|
+
- No unused imports or dead code
|
|
41
|
+
- No hardcoded URLs — base URL comes from constructor option
|
|
42
|
+
- Bearer token attached to all requests via `Authorization` header
|
|
43
|
+
- Pagination support: `page`/`limit` parameters where applicable
|
|
44
|
+
|
|
45
|
+
### Backward Compatibility
|
|
46
|
+
- Existing method signatures unchanged (or new optional params added at the end)
|
|
47
|
+
- Existing interfaces only extended, never fields removed
|
|
48
|
+
- `connected` and `auth_type` fields preserved (deprecated, not removed)
|
|
49
|
+
- AuthType enum values unchanged
|
|
50
|
+
|
|
51
|
+
### Security
|
|
52
|
+
- No secrets or tokens in code
|
|
53
|
+
- No `eval()`, `Function()`, or dynamic code execution
|
|
54
|
+
- Token not logged or exposed in error messages
|
|
55
|
+
|
|
56
|
+
### Naming & Style
|
|
57
|
+
- 4 spaces indentation, double quotes, semicolons
|
|
58
|
+
- camelCase for methods/variables, PascalCase for interfaces/types/enums
|
|
59
|
+
- Method names follow existing patterns: `get*`, `create*`, `update*`, `delete*`, `execute*`
|
|
60
|
+
|
|
61
|
+
## Output Format
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
## PR Review: #{number} — {title}
|
|
65
|
+
|
|
66
|
+
### Summary
|
|
67
|
+
Brief description of what the PR does.
|
|
68
|
+
|
|
69
|
+
### Critical Issues
|
|
70
|
+
- **[file:line]** Description of critical issue
|
|
71
|
+
|
|
72
|
+
### Suggestions
|
|
73
|
+
- **[file:line]** Description of improvement suggestion
|
|
74
|
+
|
|
75
|
+
### Nits
|
|
76
|
+
- **[file:line]** Minor style/preference issue
|
|
77
|
+
|
|
78
|
+
### Positive Notes
|
|
79
|
+
- Things done well worth calling out
|
|
80
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: style
|
|
3
|
+
description: Code style and formatting conventions for this codebase. Reference this when writing or reviewing code to ensure consistency.
|
|
4
|
+
metadata:
|
|
5
|
+
author: iamtraction
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
user-invocable: false
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Code Style Guide
|
|
11
|
+
|
|
12
|
+
These conventions apply to all code written in this codebase. Follow them when creating, modifying, or reviewing code.
|
|
13
|
+
|
|
14
|
+
## Formatting
|
|
15
|
+
|
|
16
|
+
- **Indentation:** 4 spaces — never tabs
|
|
17
|
+
- **Quotes:** Double quotes for strings
|
|
18
|
+
- **Semicolons:** Always
|
|
19
|
+
- **Line endings:** Unix (LF)
|
|
20
|
+
- **Trailing commas:** Use trailing commas in multiline arrays, objects, function parameters, and imports
|
|
21
|
+
- **Blank lines:** One blank line between top-level declarations (imports, interfaces, functions, exports). No multiple consecutive blank lines.
|
|
22
|
+
- **Braces:** Opening brace on the same line (`if (...) {`), closing brace on its own line
|
|
23
|
+
- **Bracket spacing:** Spaces inside object braces — `{ key: value }`, not `{key: value}`
|
|
24
|
+
- **Template literals:** Prefer template literals over string concatenation
|
|
25
|
+
|
|
26
|
+
## Naming
|
|
27
|
+
|
|
28
|
+
- **Functions/variables:** camelCase — `getApp`, `executeWorkflow`, `configId`
|
|
29
|
+
- **Constants:** SCREAMING_SNAKE_CASE for true constants
|
|
30
|
+
- **Interfaces/Types:** PascalCase, no `I` prefix — `Application`, `Config`, `Execution`
|
|
31
|
+
- **Enums:** PascalCase name, PascalCase members — `AuthType.OAuth2`, `AuthStatus.Active`
|
|
32
|
+
- **Booleans:** Prefix with `is`, `has`, `can`, `should` — `isConnected`, `hasToken`
|
|
33
|
+
|
|
34
|
+
## TypeScript
|
|
35
|
+
|
|
36
|
+
- **Strict typing:** Avoid `any` — use `unknown` when the type is genuinely unknown, then narrow
|
|
37
|
+
- **Interfaces over types:** Prefer `interface` for object shapes, `type` for unions, intersections, and utility types
|
|
38
|
+
- **Explicit return types:** Add them for all public methods — this is a published SDK, types are the API contract
|
|
39
|
+
- **Non-null assertions:** Avoid `!` — prefer optional chaining (`?.`) and nullish coalescing (`??`)
|
|
40
|
+
|
|
41
|
+
## SDK-Specific Conventions
|
|
42
|
+
|
|
43
|
+
- **Zero dependencies:** This SDK has no runtime dependencies. Do not add any. Use native `fetch` API.
|
|
44
|
+
- **Single class:** All public API lives on the `Cobalt` class. Keep it that way.
|
|
45
|
+
- **Backward compatibility:** Mark deprecated fields/methods with `@deprecated` JSDoc tag — never remove them without a major version bump
|
|
46
|
+
- **Error propagation:** Throw parsed JSON error responses for 4xx/5xx — don't catch and transform in the SDK. Let consumers handle errors.
|
|
47
|
+
- **JSDoc on all public methods:** Every public method must have a JSDoc block with `@param` and `@returns` tags. This generates the TypeDoc documentation.
|
|
48
|
+
|
|
49
|
+
## Functions
|
|
50
|
+
|
|
51
|
+
- **Method style:** Use class methods for the `Cobalt` class
|
|
52
|
+
- **Private methods:** Mark with `private` keyword — `private oauth(...)`, `private keybased(...)`
|
|
53
|
+
- **Async/await:** All API calls are async — use `async`/`await`, never raw `.then()` chains in new code
|
|
54
|
+
- **Early returns:** Prefer early returns to reduce nesting
|
|
55
|
+
|
|
56
|
+
## Error Handling
|
|
57
|
+
|
|
58
|
+
- **Fetch errors:** Check `res.status >= 400 && res.status < 600`, parse JSON, throw it
|
|
59
|
+
- **No try/catch in SDK methods** — let errors propagate to the consumer
|
|
60
|
+
- **OAuth polling:** Catch errors in the polling interval and log to console — don't reject the promise on transient failures
|
|
61
|
+
|
|
62
|
+
## Comments
|
|
63
|
+
|
|
64
|
+
- **JSDoc for all public API** — every exported method, interface, enum, and type
|
|
65
|
+
- **No obvious comments** — don't describe what the code does when it's self-evident
|
|
66
|
+
- **Why, not what** — comment the reasoning, not the mechanics
|
|
67
|
+
- **No commented-out code** — delete it; git has history
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify
|
|
3
|
+
description: Verify code quality, catch bugs, and validate implementation against codebase patterns. Use for testing, linting, type-checking, and manual review.
|
|
4
|
+
metadata:
|
|
5
|
+
author: iamtraction
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
argument-hint: <file-path-or-feature>
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Verify & Test
|
|
11
|
+
|
|
12
|
+
Perform comprehensive verification of code changes.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
The user provides a file path, feature name, or asks to verify recent changes. If no argument, verify all uncommitted changes.
|
|
17
|
+
|
|
18
|
+
## Verification Steps
|
|
19
|
+
|
|
20
|
+
### 1. Static Analysis
|
|
21
|
+
Run these checks and report results:
|
|
22
|
+
```bash
|
|
23
|
+
npm run build # TypeScript compilation → cobalt.js + cobalt.d.ts
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. Type Safety Review
|
|
27
|
+
- Check for `any` types that should be properly typed
|
|
28
|
+
- Verify all public methods have explicit return types
|
|
29
|
+
- Ensure interface fields match the backend API responses
|
|
30
|
+
- Verify generic type parameters on Promise return types
|
|
31
|
+
- Check that deprecated fields are still present with `@deprecated` JSDoc
|
|
32
|
+
|
|
33
|
+
### 3. SDK Design Compliance
|
|
34
|
+
Verify the code follows SDK conventions:
|
|
35
|
+
- **Zero dependencies**: No runtime dependencies added
|
|
36
|
+
- **Native fetch**: No HTTP libraries — uses `fetch` API only
|
|
37
|
+
- **Single class**: All public API on the `Cobalt` class
|
|
38
|
+
- **Error handling**: 4xx/5xx → parse JSON → throw (no swallowing errors)
|
|
39
|
+
- **JSDoc on all public methods**: `@param`, `@returns` tags
|
|
40
|
+
- **Backward compatibility**: No removed methods/fields, no changed signatures
|
|
41
|
+
|
|
42
|
+
### 4. Runtime Safety Review
|
|
43
|
+
Check for common issues:
|
|
44
|
+
- **Missing error checks** — `res.status >= 400` not checked after fetch
|
|
45
|
+
- **OAuth polling** — `setInterval` properly cleaned up with `clearInterval`
|
|
46
|
+
- **Popup handling** — `window.open` result checked for null (popup blocked)
|
|
47
|
+
- **Token usage** — `this.token` attached to all requests
|
|
48
|
+
- **Base URL** — uses `this.baseUrl`, no hardcoded URLs
|
|
49
|
+
|
|
50
|
+
### 5. Backward Compatibility Check
|
|
51
|
+
- Existing method signatures unchanged
|
|
52
|
+
- Existing interfaces only extended (no field removal)
|
|
53
|
+
- Enum values unchanged
|
|
54
|
+
- `getApp()` overload still works for both single and all apps
|
|
55
|
+
|
|
56
|
+
## Output Format
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
## Verification Report
|
|
60
|
+
|
|
61
|
+
### Build: PASS/FAIL
|
|
62
|
+
Details...
|
|
63
|
+
|
|
64
|
+
### Type Safety: X issues found
|
|
65
|
+
- [file:line] Description
|
|
66
|
+
|
|
67
|
+
### SDK Design: X issues found
|
|
68
|
+
- [file:line] Description
|
|
69
|
+
|
|
70
|
+
### Runtime Safety: X issues found
|
|
71
|
+
- [file:line] Description
|
|
72
|
+
|
|
73
|
+
### Backward Compatibility: X issues found
|
|
74
|
+
- [file:line] Description
|
|
75
|
+
|
|
76
|
+
### Overall: PASS / NEEDS FIXES
|
|
77
|
+
Summary and recommended actions.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Important
|
|
81
|
+
|
|
82
|
+
- Always run `npm run build` — don't skip compilation check
|
|
83
|
+
- Verify both `cobalt.js` and `cobalt.d.ts` are generated correctly
|
|
84
|
+
- Be specific about issues — include file paths and line numbers
|
|
85
|
+
- Breaking changes require major version bump — flag them as critical
|
|
@@ -11,24 +11,23 @@ jobs:
|
|
|
11
11
|
build:
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
15
|
-
- uses: actions/setup-node@
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
- uses: actions/setup-node@v6
|
|
16
16
|
with:
|
|
17
|
-
node-version:
|
|
17
|
+
node-version: 24
|
|
18
18
|
- run: |
|
|
19
19
|
echo 'NPM Token ${secrets.NPM_TOKEN}'
|
|
20
20
|
npm ci
|
|
21
21
|
npm test
|
|
22
|
-
|
|
23
22
|
|
|
24
23
|
publish-npm:
|
|
25
24
|
needs: build
|
|
26
25
|
runs-on: ubuntu-latest
|
|
27
26
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: actions/setup-node@
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
- uses: actions/setup-node@v6
|
|
30
29
|
with:
|
|
31
|
-
node-version:
|
|
30
|
+
node-version: 24
|
|
32
31
|
registry-url: https://registry.npmjs.org/
|
|
33
32
|
- run: npm ci
|
|
34
33
|
- run: npm publish
|
package/CLAUDE.md
CHANGED
|
@@ -2,36 +2,116 @@
|
|
|
2
2
|
|
|
3
3
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
4
|
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Cobalt JS SDK (`@cobaltio/cobalt-js`) — a zero-dependency TypeScript frontend SDK for integrating with the Cobalt platform. Provides methods for application connection (OAuth2 + key-based), configuration management, workflow execution, and execution monitoring. Published to npm as a public package. Single-file library (`cobalt.ts`, ~970 lines).
|
|
8
|
+
|
|
5
9
|
## Commands
|
|
6
10
|
|
|
7
11
|
```bash
|
|
8
|
-
npm run build
|
|
9
|
-
npm run docs
|
|
10
|
-
npm run docs:llms
|
|
12
|
+
npm run build # Compile TypeScript (tsc) → cobalt.js + cobalt.d.ts
|
|
13
|
+
npm run docs # Generate TypeDoc HTML documentation
|
|
14
|
+
npm run docs:llms # Generate LLM-optimized markdown docs (docs/llms.txt)
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
No test runner is configured. No runtime dependencies.
|
|
18
|
+
|
|
19
|
+
## Build Output
|
|
20
|
+
|
|
21
|
+
- `cobalt.js` — Compiled CommonJS module (main entry point)
|
|
22
|
+
- `cobalt.d.ts` — TypeScript type definitions
|
|
23
|
+
- `docs/` — Generated TypeDoc documentation (HTML + `llms.txt`)
|
|
24
|
+
|
|
25
|
+
Published to npm (`@cobaltio/cobalt-js`) and served via jsDelivr CDN.
|
|
14
26
|
|
|
15
27
|
## Architecture
|
|
16
28
|
|
|
17
|
-
|
|
29
|
+
### Single-Class Design
|
|
30
|
+
The entire SDK is a single `Cobalt` class using native `fetch` API. No external dependencies.
|
|
31
|
+
|
|
32
|
+
### Authentication
|
|
33
|
+
- Bearer token auth via `Authorization` header on all requests
|
|
34
|
+
- Token set via constructor option or `cobalt.token = "..."` after initialization
|
|
35
|
+
- Default base URL: `https://api.gocobalt.io` (configurable via `baseUrl` option)
|
|
36
|
+
|
|
37
|
+
### Public API
|
|
38
|
+
|
|
39
|
+
**Constructor:**
|
|
40
|
+
```typescript
|
|
41
|
+
const cobalt = new Cobalt({ token?: string, baseUrl?: string })
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Application Management:**
|
|
45
|
+
- `getApp(): Promise<Application[]>` — Get all enabled apps
|
|
46
|
+
- `getApp(slug: string): Promise<Application>` — Get specific app
|
|
47
|
+
- `getApps(): Promise<Application[]>` — Alias for getApp()
|
|
48
|
+
|
|
49
|
+
**Connection:**
|
|
50
|
+
- `connect({ slug, type?, payload? }): Promise<boolean>` — Connect app (OAuth2 popup or key-based POST)
|
|
51
|
+
- `disconnect(slug, type?): Promise<unknown>` — Disconnect app
|
|
52
|
+
|
|
53
|
+
**Configuration:**
|
|
54
|
+
- `config(payload): Promise<Config>` — Create/get config
|
|
55
|
+
- `getConfigs(slug): Promise<{ config_id }[]>` — List configs
|
|
56
|
+
- `getConfig(slug, configId?): Promise<Config>` — Get specific config
|
|
57
|
+
- `updateConfig(payload): Promise<Config>` — Update config
|
|
58
|
+
- `deleteConfig(slug, configId?): Promise<unknown>` — Delete config
|
|
59
|
+
- `getConfigField(slug, fieldId, workflowId?): Promise<Config>` — Get field
|
|
60
|
+
- `updateConfigField(slug, fieldId, value, workflowId?): Promise<Config>` — Update field
|
|
61
|
+
- `deleteConfigField(slug, fieldId, workflowId?): Promise<unknown>` — Delete field
|
|
62
|
+
- `getFieldOptions(lhs, slug, fieldId, workflowId?): Promise<RuleOptions>` — Rule engine options
|
|
63
|
+
|
|
64
|
+
**Workflows:**
|
|
65
|
+
- `getWorkflows(params?): Promise<PaginatedResponse<PublicWorkflow>>` — List workflows
|
|
66
|
+
- `createWorkflow(params): Promise<PublicWorkflow>` — Create workflow
|
|
67
|
+
- `deleteWorkflow(workflowId): Promise<unknown>` — Delete workflow
|
|
68
|
+
- `getWorkflowPayload(workflowId): Promise<WorkflowPayloadResponse>` — Get payload schema
|
|
69
|
+
- `executeWorkflow(options): Promise<unknown>` — Execute workflow
|
|
70
|
+
|
|
71
|
+
**Executions:**
|
|
72
|
+
- `getExecutions({ page?, limit? }?): Promise<PaginatedResponse<Execution>>` — List executions
|
|
73
|
+
- `getExecution(executionId): Promise<Execution>` — Get execution details
|
|
74
|
+
|
|
75
|
+
### Key Types
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
enum AuthType { OAuth2 = "oauth2", KeyBased = "keybased" }
|
|
79
|
+
enum AuthStatus { Active = "active", Expired = "expired" }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Application** — app_id, name, slug, icon, tags, auth_type_options, connected_accounts (with status)
|
|
83
|
+
**Config** — slug, config_id, fields (ConfigField[]), workflows (ConfigWorkflow[]), field_errors
|
|
84
|
+
**Execution** — status (COMPLETED/RUNNING/ERRORED/STOPPED/STOPPING/TIMED_OUT), nodes with node_status, completion_percentage
|
|
85
|
+
|
|
86
|
+
### OAuth Flow
|
|
87
|
+
- Opens popup via `window.open(oauthUrl)`
|
|
88
|
+
- Polls `/api/v2/f-sdk/application/{slug}` every 3 seconds
|
|
89
|
+
- Resolves when `connected_accounts` shows active OAuth connection or window closes
|
|
90
|
+
|
|
91
|
+
### Error Handling
|
|
92
|
+
All 4xx/5xx HTTP responses throw the parsed JSON error response. No try/catch in SDK — errors propagate to caller.
|
|
18
93
|
|
|
19
|
-
|
|
94
|
+
### Backend API Endpoints Used
|
|
95
|
+
All requests include `Authorization: Bearer ${token}`:
|
|
96
|
+
- Auth service: `/api/v3/org/basics`, `/api/v2/public/linked-account`
|
|
97
|
+
- Apps: `/api/v2/f-sdk/application`, `/api/v1/{slug}/integrate`, `/api/v2/app/{slug}/save`
|
|
98
|
+
- Config: `/api/v2/f-sdk/config`, `/api/v2/f-sdk/slug/{slug}/config/{configId}`, `/api/v2/public/config/field/{fieldId}`
|
|
99
|
+
- Workflows: `/api/v2/public/workflow`, `/api/v2/public/workflow/{id}/execute`
|
|
100
|
+
- Executions: `/api/v2/public/execution`
|
|
20
101
|
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
- Endpoints are primarily `/api/v2/`, with some `/api/v3/` (e.g. `getAccountDetails`)
|
|
102
|
+
### Browser & Node Compatibility
|
|
103
|
+
- **Browser:** Uses native `fetch`, `window.open()` for OAuth popups, `setInterval` for polling
|
|
104
|
+
- **Node.js:** Works in Node 18+ (native fetch). No browser APIs called in non-OAuth flows.
|
|
25
105
|
|
|
26
|
-
|
|
27
|
-
- Account: `getAccountDetails`, `updateAccount`
|
|
28
|
-
- Apps/Auth configs: `getApp`, `getApps`, `getAuthConfigs`, `connect`, `disconnect`
|
|
29
|
-
- Config (integration settings): `config`, `getConfigs`, `getConfig`, `updateConfig`, `deleteConfig`, and field-level CRUD
|
|
30
|
-
- Workflows: `getWorkflows`, `createWorkflow`, `deleteWorkflow`, `getWorkflowPayload`, `executeWorkflow`
|
|
31
|
-
- Executions: `getExecutions`, `getExecution`
|
|
106
|
+
## TypeScript Configuration
|
|
32
107
|
|
|
33
|
-
|
|
108
|
+
- Target: ES6, Module: CommonJS
|
|
109
|
+
- Strict mode enabled
|
|
110
|
+
- Declarations emitted (`cobalt.d.ts`)
|
|
111
|
+
- LF line endings enforced
|
|
34
112
|
|
|
35
|
-
##
|
|
113
|
+
## Version History
|
|
36
114
|
|
|
37
|
-
|
|
115
|
+
- **v9.x:** Added `getWorkflowPayload()`, `executeWorkflow()`, multi-auth support
|
|
116
|
+
- **v8.x:** Introduced `AuthType` enum for multi-auth
|
|
117
|
+
- Deprecated fields maintained for backward compatibility
|