@stacknet/stacks 0.1.2 → 0.2.2

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 (67) hide show
  1. package/README.md +136 -0
  2. package/dist/{billing-BqscteyZ.d.cts → billing-cj0eSVrp.d.cts} +61 -1
  3. package/dist/{billing-BqscteyZ.d.ts → billing-cj0eSVrp.d.ts} +61 -1
  4. package/dist/clients/index.cjs +4 -4
  5. package/dist/clients/index.d.cts +27 -1
  6. package/dist/clients/index.d.ts +27 -1
  7. package/dist/clients/index.js +4 -4
  8. package/dist/{index-DVzKiF_0.d.cts → index-B_dUFmAg.d.cts} +31 -6
  9. package/dist/{index-DVzKiF_0.d.ts → index-B_dUFmAg.d.ts} +31 -6
  10. package/dist/index.cjs +12 -16
  11. package/dist/index.d.cts +4 -4
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.js +12 -16
  14. package/dist/proxy/index.cjs +2 -2
  15. package/dist/proxy/index.d.cts +1 -1
  16. package/dist/proxy/index.d.ts +1 -1
  17. package/dist/proxy/index.js +2 -2
  18. package/dist/streaming/index.cjs +8 -12
  19. package/dist/streaming/index.js +8 -12
  20. package/dist/types/index.d.cts +1 -1
  21. package/dist/types/index.d.ts +1 -1
  22. package/package.json +15 -13
  23. package/src/clients/agents.ts +0 -233
  24. package/src/clients/billing.ts +0 -197
  25. package/src/clients/coder.ts +0 -655
  26. package/src/clients/files.ts +0 -86
  27. package/src/clients/index.ts +0 -93
  28. package/src/clients/magma.ts +0 -299
  29. package/src/clients/mcp.ts +0 -208
  30. package/src/clients/network.ts +0 -118
  31. package/src/clients/points.ts +0 -403
  32. package/src/clients/skills.ts +0 -236
  33. package/src/clients/social.ts +0 -286
  34. package/src/clients/stack-management.ts +0 -279
  35. package/src/clients/task-network.ts +0 -303
  36. package/src/clients/user.ts +0 -84
  37. package/src/clients/widgets.ts +0 -171
  38. package/src/index.ts +0 -387
  39. package/src/managers/index.ts +0 -10
  40. package/src/managers/task-manager.ts +0 -310
  41. package/src/proxy/forwarder.ts +0 -146
  42. package/src/proxy/index.ts +0 -32
  43. package/src/proxy/route-handlers.ts +0 -950
  44. package/src/streaming/component-stream.ts +0 -319
  45. package/src/streaming/index.ts +0 -21
  46. package/src/streaming/sse.ts +0 -241
  47. package/src/types/agent.ts +0 -106
  48. package/src/types/billing.ts +0 -121
  49. package/src/types/chat.ts +0 -58
  50. package/src/types/coder.ts +0 -345
  51. package/src/types/credential.ts +0 -111
  52. package/src/types/file.ts +0 -15
  53. package/src/types/imagination.ts +0 -50
  54. package/src/types/index.ts +0 -20
  55. package/src/types/mcp.ts +0 -35
  56. package/src/types/network.ts +0 -97
  57. package/src/types/points.ts +0 -250
  58. package/src/types/skill.ts +0 -107
  59. package/src/types/social.ts +0 -109
  60. package/src/types/stack.ts +0 -269
  61. package/src/types/task.ts +0 -41
  62. package/src/types/user.ts +0 -29
  63. package/src/types/widget.ts +0 -57
  64. package/src/utils/constants.ts +0 -26
  65. package/src/utils/errors.ts +0 -169
  66. package/src/utils/helpers.ts +0 -85
  67. package/src/utils/index.ts +0 -7
@@ -1,310 +0,0 @@
1
- /**
2
- * TaskManager - Redis-backed task state management
3
- *
4
- * Manages task lifecycle for long-running operations with real-time updates
5
- */
6
-
7
- import type { TaskType, TaskStatus, TaskState } from '../types';
8
- import { TASK_PREFIX, CHAT_TASKS_PREFIX, TASK_TTL } from '../utils/constants';
9
- import { generateUUID } from '../utils/helpers';
10
-
11
- // Redis client type - we use a generic interface to avoid hard dependency
12
- export interface RedisClientLike {
13
- hSet(key: string, value: Record<string, string>): Promise<number>;
14
- hGetAll(key: string): Promise<Record<string, string>>;
15
- expire(key: string, seconds: number): Promise<boolean>;
16
- sAdd(key: string, ...members: string[]): Promise<number>;
17
- sMembers(key: string): Promise<string[]>;
18
- sRem(key: string, ...members: string[]): Promise<number>;
19
- del(key: string): Promise<number>;
20
- publish(channel: string, message: string): Promise<number>;
21
- subscribe(channel: string, callback: (message: string) => void): Promise<void>;
22
- unsubscribe(channel: string): Promise<void>;
23
- }
24
-
25
- export interface TaskManagerConfig {
26
- redis?: RedisClientLike;
27
- getRedisClient?: () => Promise<RedisClientLike>;
28
- taskTTL?: number;
29
- }
30
-
31
- export class TaskManager {
32
- private redis?: RedisClientLike;
33
- private getRedisClient?: () => Promise<RedisClientLike>;
34
- private taskTTL: number;
35
-
36
- constructor(config: TaskManagerConfig = {}) {
37
- this.redis = config.redis;
38
- this.getRedisClient = config.getRedisClient;
39
- this.taskTTL = config.taskTTL || TASK_TTL;
40
- }
41
-
42
- /**
43
- * Get Redis client (lazily initialized)
44
- */
45
- private async getClient(): Promise<RedisClientLike> {
46
- if (this.redis) return this.redis;
47
- if (this.getRedisClient) {
48
- this.redis = await this.getRedisClient();
49
- return this.redis;
50
- }
51
- throw new Error('Redis client not configured. Provide redis or getRedisClient in config.');
52
- }
53
-
54
- /**
55
- * Create a new task and return its ID
56
- */
57
- async createTask(
58
- chatId: string,
59
- messageId: string,
60
- type: TaskType,
61
- initialMessage: string = 'Starting...'
62
- ): Promise<string> {
63
- const redis = await this.getClient();
64
- const taskId = generateUUID();
65
- const now = Date.now();
66
-
67
- const task: TaskState = {
68
- id: taskId,
69
- chatId,
70
- messageId,
71
- type,
72
- status: 'pending',
73
- progress: 0,
74
- message: initialMessage,
75
- createdAt: now,
76
- updatedAt: now,
77
- };
78
-
79
- await redis.hSet(`${TASK_PREFIX}${taskId}`, this.taskToRedis(task));
80
- await redis.expire(`${TASK_PREFIX}${taskId}`, this.taskTTL);
81
-
82
- await redis.sAdd(`${CHAT_TASKS_PREFIX}${chatId}`, taskId);
83
- await redis.expire(`${CHAT_TASKS_PREFIX}${chatId}`, this.taskTTL);
84
-
85
- console.log(`[TaskManager] Created task ${taskId} for chat ${chatId} (${type})`);
86
-
87
- return taskId;
88
- }
89
-
90
- /**
91
- * Update task progress
92
- */
93
- async updateProgress(
94
- taskId: string,
95
- progress: number,
96
- message: string
97
- ): Promise<void> {
98
- const redis = await this.getClient();
99
-
100
- await redis.hSet(`${TASK_PREFIX}${taskId}`, {
101
- status: 'generating',
102
- progress: progress.toString(),
103
- message,
104
- updatedAt: Date.now().toString(),
105
- });
106
-
107
- await redis.publish(
108
- `task:progress:${taskId}`,
109
- JSON.stringify({
110
- taskId,
111
- progress,
112
- message,
113
- status: 'generating',
114
- })
115
- );
116
-
117
- console.log(`[TaskManager] Task ${taskId} progress: ${progress}% - ${message}`);
118
- }
119
-
120
- /**
121
- * Mark task as complete with result
122
- */
123
- async complete(taskId: string, result: unknown): Promise<void> {
124
- const redis = await this.getClient();
125
-
126
- await redis.hSet(`${TASK_PREFIX}${taskId}`, {
127
- status: 'complete',
128
- progress: '100',
129
- message: 'Complete',
130
- result: JSON.stringify(result),
131
- updatedAt: Date.now().toString(),
132
- });
133
-
134
- await redis.publish(
135
- `task:progress:${taskId}`,
136
- JSON.stringify({
137
- taskId,
138
- progress: 100,
139
- message: 'Complete',
140
- status: 'complete',
141
- result,
142
- })
143
- );
144
-
145
- console.log(`[TaskManager] Task ${taskId} completed`);
146
- }
147
-
148
- /**
149
- * Mark task as failed
150
- */
151
- async fail(taskId: string, error: string): Promise<void> {
152
- const redis = await this.getClient();
153
-
154
- await redis.hSet(`${TASK_PREFIX}${taskId}`, {
155
- status: 'failed',
156
- message: error,
157
- error,
158
- updatedAt: Date.now().toString(),
159
- });
160
-
161
- await redis.publish(
162
- `task:progress:${taskId}`,
163
- JSON.stringify({
164
- taskId,
165
- status: 'failed',
166
- error,
167
- })
168
- );
169
-
170
- console.log(`[TaskManager] Task ${taskId} failed: ${error}`);
171
- }
172
-
173
- /**
174
- * Get task by ID
175
- */
176
- async getTask(taskId: string): Promise<TaskState | null> {
177
- const redis = await this.getClient();
178
- const data = await redis.hGetAll(`${TASK_PREFIX}${taskId}`);
179
-
180
- if (!data || Object.keys(data).length === 0) {
181
- return null;
182
- }
183
-
184
- return this.redisToTask(data);
185
- }
186
-
187
- /**
188
- * Get all tasks for a chat
189
- */
190
- async getTasksForChat(chatId: string): Promise<TaskState[]> {
191
- const redis = await this.getClient();
192
- const taskIds = await redis.sMembers(`${CHAT_TASKS_PREFIX}${chatId}`);
193
-
194
- if (!taskIds || taskIds.length === 0) {
195
- return [];
196
- }
197
-
198
- const tasks: TaskState[] = [];
199
- for (const taskId of taskIds) {
200
- const task = await this.getTask(taskId);
201
- if (task) {
202
- tasks.push(task);
203
- }
204
- }
205
-
206
- return tasks.sort((a, b) => b.createdAt - a.createdAt);
207
- }
208
-
209
- /**
210
- * Get pending/generating tasks for a chat
211
- */
212
- async getPendingTasksForChat(chatId: string): Promise<TaskState[]> {
213
- const tasks = await this.getTasksForChat(chatId);
214
- return tasks.filter((t) => t.status === 'pending' || t.status === 'generating');
215
- }
216
-
217
- /**
218
- * Delete a task
219
- */
220
- async deleteTask(taskId: string): Promise<void> {
221
- const redis = await this.getClient();
222
- const task = await this.getTask(taskId);
223
-
224
- if (task) {
225
- await redis.del(`${TASK_PREFIX}${taskId}`);
226
- await redis.sRem(`${CHAT_TASKS_PREFIX}${task.chatId}`, taskId);
227
- console.log(`[TaskManager] Deleted task ${taskId}`);
228
- }
229
- }
230
-
231
- /**
232
- * Clean up old completed/failed tasks for a chat
233
- */
234
- async cleanupOldTasks(chatId: string, maxAge: number = 86400000): Promise<void> {
235
- const tasks = await this.getTasksForChat(chatId);
236
- const now = Date.now();
237
-
238
- for (const task of tasks) {
239
- if (
240
- (task.status === 'complete' || task.status === 'failed') &&
241
- now - task.updatedAt > maxAge
242
- ) {
243
- await this.deleteTask(task.id);
244
- }
245
- }
246
- }
247
-
248
- /**
249
- * Subscribe to task progress updates
250
- */
251
- async subscribeToTask(
252
- taskId: string,
253
- callback: (update: { taskId: string; status: TaskStatus; progress?: number; message?: string; result?: unknown; error?: string }) => void
254
- ): Promise<() => Promise<void>> {
255
- const redis = await this.getClient();
256
- const channel = `task:progress:${taskId}`;
257
-
258
- await redis.subscribe(channel, (message) => {
259
- try {
260
- const data = JSON.parse(message);
261
- callback(data);
262
- } catch {
263
- // Ignore parse errors
264
- }
265
- });
266
-
267
- return async () => {
268
- await redis.unsubscribe(channel);
269
- };
270
- }
271
-
272
- private taskToRedis(task: TaskState): Record<string, string> {
273
- return {
274
- id: task.id,
275
- chatId: task.chatId,
276
- messageId: task.messageId,
277
- type: task.type,
278
- status: task.status,
279
- progress: task.progress.toString(),
280
- message: task.message,
281
- result: task.result || '',
282
- error: task.error || '',
283
- createdAt: task.createdAt.toString(),
284
- updatedAt: task.updatedAt.toString(),
285
- };
286
- }
287
-
288
- private redisToTask(data: Record<string, string>): TaskState {
289
- return {
290
- id: data.id,
291
- chatId: data.chatId,
292
- messageId: data.messageId,
293
- type: data.type as TaskType,
294
- status: data.status as TaskStatus,
295
- progress: parseInt(data.progress, 10),
296
- message: data.message,
297
- result: data.result || undefined,
298
- error: data.error || undefined,
299
- createdAt: parseInt(data.createdAt, 10),
300
- updatedAt: parseInt(data.updatedAt, 10),
301
- };
302
- }
303
- }
304
-
305
- /**
306
- * Factory function to create a TaskManager
307
- */
308
- export function createTaskManager(config?: TaskManagerConfig): TaskManager {
309
- return new TaskManager(config);
310
- }
@@ -1,146 +0,0 @@
1
- /**
2
- * Generic request forwarding utilities
3
- */
4
-
5
- import { DEFAULT_TASK_NETWORK_URL } from '../utils/constants';
6
-
7
- export interface ForwarderConfig {
8
- baseUrl?: string;
9
- defaultHeaders?: Record<string, string>;
10
- timeout?: number;
11
- }
12
-
13
- export interface RequestOptions {
14
- method?: string;
15
- headers?: Record<string, string>;
16
- body?: unknown;
17
- searchParams?: Record<string, string | undefined>;
18
- stream?: boolean;
19
- }
20
-
21
- /**
22
- * Forward a request to a backend URL
23
- */
24
- export async function forwardRequest(
25
- path: string,
26
- options: RequestOptions = {},
27
- config: ForwarderConfig = {}
28
- ): Promise<Response> {
29
- const baseUrl = config.baseUrl || DEFAULT_TASK_NETWORK_URL;
30
- const { method = 'GET', headers = {}, body, searchParams, stream } = options;
31
-
32
- // Build URL with search params
33
- let url = `${baseUrl}${path}`;
34
- if (searchParams) {
35
- const params = new URLSearchParams();
36
- Object.entries(searchParams).forEach(([key, value]) => {
37
- if (value !== undefined) {
38
- params.set(key, value);
39
- }
40
- });
41
- const paramString = params.toString();
42
- if (paramString) {
43
- url += `?${paramString}`;
44
- }
45
- }
46
-
47
- const fetchOptions: RequestInit = {
48
- method,
49
- headers: {
50
- ...config.defaultHeaders,
51
- ...headers,
52
- },
53
- };
54
-
55
- if (body && method !== 'GET') {
56
- fetchOptions.headers = {
57
- ...fetchOptions.headers,
58
- 'Content-Type': 'application/json',
59
- };
60
- fetchOptions.body = JSON.stringify(body);
61
- }
62
-
63
- const response = await fetch(url, fetchOptions);
64
-
65
- // For streaming responses, return directly
66
- if (stream && response.body) {
67
- return response;
68
- }
69
-
70
- return response;
71
- }
72
-
73
- /**
74
- * Forward and return JSON response
75
- */
76
- export async function forwardJSON<T = unknown>(
77
- path: string,
78
- options: RequestOptions = {},
79
- config: ForwarderConfig = {}
80
- ): Promise<{ data: T; status: number }> {
81
- const response = await forwardRequest(path, options, config);
82
- const data = await response.json();
83
- return { data, status: response.status };
84
- }
85
-
86
- /**
87
- * Create a proxy handler that forwards requests
88
- */
89
- export function createProxyHandler(
90
- path: string | ((req: Request) => string),
91
- config: ForwarderConfig = {}
92
- ) {
93
- return async (request: Request): Promise<Response> => {
94
- const url = new URL(request.url);
95
- const targetPath = typeof path === 'function' ? path(request) : path;
96
-
97
- // Forward search params
98
- const searchParams: Record<string, string> = {};
99
- url.searchParams.forEach((value, key) => {
100
- searchParams[key] = value;
101
- });
102
-
103
- let body: unknown = undefined;
104
- if (request.method !== 'GET' && request.method !== 'HEAD') {
105
- try {
106
- body = await request.json();
107
- } catch {
108
- // No body or not JSON
109
- }
110
- }
111
-
112
- // Extract headers
113
- const requestHeaders: Record<string, string> = {};
114
- request.headers.forEach((value, key) => {
115
- requestHeaders[key] = value;
116
- });
117
-
118
- const response = await forwardRequest(
119
- targetPath,
120
- {
121
- method: request.method,
122
- headers: requestHeaders,
123
- body,
124
- searchParams,
125
- },
126
- config
127
- );
128
-
129
- // Check if streaming response
130
- const contentType = response.headers.get('content-type') || '';
131
- if (contentType.includes('text/event-stream')) {
132
- return new Response(response.body, {
133
- status: response.status,
134
- headers: {
135
- 'Content-Type': 'text/event-stream',
136
- 'Cache-Control': 'no-cache',
137
- 'Connection': 'keep-alive',
138
- },
139
- });
140
- }
141
-
142
- // Return JSON response
143
- const data = await response.json();
144
- return Response.json(data, { status: response.status });
145
- };
146
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * @stacknet/stacks - Proxy utilities
3
- */
4
-
5
- export {
6
- forwardRequest,
7
- forwardJSON,
8
- createProxyHandler,
9
- type ForwarderConfig,
10
- type RequestOptions,
11
- } from './forwarder';
12
-
13
- export {
14
- createAgentRoutes,
15
- createAgentDetailRoutes,
16
- createAgentExecuteRoute,
17
- createAgentToggleRoutes,
18
- createSkillRoutes,
19
- createSkillDetailRoutes,
20
- createWidgetRoutes,
21
- createWidgetDetailRoutes,
22
- createImaginationRoutes,
23
- // Stack management routes
24
- createStackRoutes,
25
- createStackDetailRoutes,
26
- createStackKeysRoutes,
27
- createStackMembersRoutes,
28
- type RouteHandlerConfig,
29
- type StackRouteHandlerConfig,
30
- type RouteHandler,
31
- type CRUDRouteHandlers,
32
- } from './route-handlers';