@loopstack/loopstack-studio 0.33.0 → 0.35.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 (146) hide show
  1. package/dist/app/EnvironmentEmbedRoot.js +17 -25
  2. package/dist/components/layout/StudioSidebar.js +34 -34
  3. package/dist/components/messages/CompletionMessagePaper.js +25 -29
  4. package/dist/events/api-client-events.js +13 -1
  5. package/dist/events/index.js +1 -0
  6. package/dist/features/code-explorer/components/FileTabsBarBase.js +1 -1
  7. package/dist/features/code-explorer/index.js +0 -3
  8. package/dist/features/dashboard/AppLauncher.js +111 -64
  9. package/dist/features/debug/components/WorkflowFlowViewer.js +2 -1
  10. package/dist/features/debug/components/workflow-flow/WorkflowGraph.js +2 -1
  11. package/dist/features/documents/DocumentRenderer.js +42 -42
  12. package/dist/features/documents/components/DocumentList.js +1 -1
  13. package/dist/features/documents/document-details/DocumentDetails.js +0 -5
  14. package/dist/features/documents/renderers/DocumentFormRenderer.js +13 -12
  15. package/dist/features/documents/renderers/LinkMessageRenderer.js +2 -1
  16. package/dist/features/documents/renderers/useDocumentTransition.js +3 -2
  17. package/dist/features/feature-registry/FeatureRegistryProvider.js +17 -18
  18. package/dist/features/feature-registry/available-features.js +3 -2
  19. package/dist/features/feature-registry/index.js +1 -1
  20. package/dist/features/file-explorer/components/FileExplorerPanel.js +64 -43
  21. package/dist/features/file-explorer/components/FileTabsBar.js +1 -1
  22. package/dist/features/file-explorer/components/FileTree.js +1 -1
  23. package/dist/features/file-explorer/file-explorer-feature.js +15 -7
  24. package/dist/features/file-explorer/hooks/useFileExplorer.js +41 -34
  25. package/dist/features/file-explorer/index.js +1 -1
  26. package/dist/features/file-explorer/providers/FileExplorerProvider.js +91 -89
  27. package/dist/features/git/components/WorkbenchGitPanel.js +7 -10
  28. package/dist/features/git/hooks/useGit.js +55 -57
  29. package/dist/features/health/LocalHealthCheck.js +46 -47
  30. package/dist/features/oauth/OAuthPromptRenderer.js +6 -5
  31. package/dist/features/runs/Runs.js +3 -2
  32. package/dist/features/secrets/components/WorkbenchSecretsPanel.js +1 -1
  33. package/dist/features/secrets/renderers/SecretInputRenderer.js +3 -2
  34. package/dist/features/workbench/Workbench.js +16 -16
  35. package/dist/features/workbench/WorkflowItem.js +5 -8
  36. package/dist/features/workbench/components/NewRunDialog.js +173 -171
  37. package/dist/features/workbench/components/PreviewEmptyState.js +1 -1
  38. package/dist/features/workbench/components/WorkbenchIconSidebar.js +1 -1
  39. package/dist/features/workbench/components/WorkbenchRunsPanel.js +2 -1
  40. package/dist/features/workbench/components/WorkbenchSidebarShell.js +3 -3
  41. package/dist/features/workbench/components/WorkflowForms.js +1 -1
  42. package/dist/features/workbench/components/WorkflowHistoryItem.js +2 -1
  43. package/dist/features/workbench/components/buttons/WorkflowButtons.js +8 -14
  44. package/dist/features/workbench/hooks/useLlmStreamingDocuments.js +65 -132
  45. package/dist/features/workbench/hooks/useWorkflowData.js +8 -6
  46. package/dist/features/workbench/index.js +1 -1
  47. package/dist/features/workspaces/Workspaces.js +5 -3
  48. package/dist/features/workspaces/components/CreateWorkspace.js +7 -5
  49. package/dist/features/workspaces/components/ExecutionTimeline.js +69 -65
  50. package/dist/features/workspaces/components/WorkflowRunForm.js +6 -4
  51. package/dist/features/workspaces/components/WorkspaceHomePage.js +1 -1
  52. package/dist/hooks/index.js +5 -5
  53. package/dist/hooks/useAuth.js +14 -53
  54. package/dist/hooks/useConfig.js +13 -37
  55. package/dist/hooks/useDocuments.js +5 -30
  56. package/dist/hooks/useEnvironments.js +34 -24
  57. package/dist/hooks/useProcessor.js +2 -31
  58. package/dist/hooks/useSecrets.js +71 -53
  59. package/dist/hooks/useWorkflows.js +43 -172
  60. package/dist/hooks/useWorkspaces.js +24 -130
  61. package/dist/index.d.ts +137 -481
  62. package/dist/index.js +15 -17
  63. package/dist/loopstack-studio.css +1 -1
  64. package/dist/packages/client/dist/client.js +35 -0
  65. package/dist/packages/client/dist/http.js +47 -0
  66. package/dist/packages/client/dist/index.js +15 -0
  67. package/dist/packages/client/dist/queries/query-keys.js +94 -0
  68. package/dist/packages/client/dist/queries/query-options.js +97 -0
  69. package/dist/packages/client/dist/resources/auth.js +10 -0
  70. package/dist/packages/client/dist/resources/config.js +11 -0
  71. package/dist/packages/client/dist/resources/dashboard.js +4 -0
  72. package/dist/packages/client/dist/resources/documents.js +7 -0
  73. package/dist/packages/client/dist/resources/processor.js +7 -0
  74. package/dist/packages/client/dist/resources/workflows.js +13 -0
  75. package/dist/packages/client/dist/resources/workspaces.js +12 -0
  76. package/dist/packages/client/dist/stream/invalidations.js +20 -0
  77. package/dist/packages/client/dist/stream/llm-reducer.js +65 -0
  78. package/dist/packages/client/dist/stream/sse-parser.js +40 -0
  79. package/dist/packages/client/dist/stream/stream.js +147 -0
  80. package/dist/packages/contracts/dist/events/client-message-base.schema.js +6 -0
  81. package/dist/packages/contracts/dist/events/client-message.schema.js +24 -0
  82. package/dist/packages/contracts/dist/events/index.js +6 -0
  83. package/dist/packages/contracts/dist/events/llm-events.schema.js +44 -0
  84. package/dist/packages/contracts/dist/events/stream-events.schema.js +4 -0
  85. package/dist/packages/contracts/dist/events/workflow-events.schema.js +20 -0
  86. package/dist/packages/contracts/dist/events/workspace-events.schema.js +5 -0
  87. package/dist/packages/contracts/dist/types/types/ui-message.type.js +39 -0
  88. package/dist/packages/react/dist/hooks/mutations.js +175 -0
  89. package/dist/packages/react/dist/hooks/queries.js +139 -0
  90. package/dist/packages/react/dist/hooks/use-live-invalidation.js +39 -0
  91. package/dist/packages/react/dist/hooks/use-llm-stream.js +18 -0
  92. package/dist/packages/react/dist/index.js +5 -0
  93. package/dist/packages/react/dist/provider.js +15 -0
  94. package/dist/pages/DashboardPage.js +2 -1
  95. package/dist/pages/DebugWorkflowDetailsPage.js +2 -1
  96. package/dist/pages/DebugWorkflowsPage.js +2 -1
  97. package/dist/pages/EmbedWorkbenchPage.js +50 -43
  98. package/dist/pages/PreviewWorkbenchPage.js +60 -59
  99. package/dist/pages/StudioLandingPage.js +1 -1
  100. package/dist/pages/WorkbenchPage.js +53 -47
  101. package/dist/pages/WorkflowDebugPage.js +3 -2
  102. package/dist/pages/WorkspacePage.js +42 -27
  103. package/dist/pages/WorkspaceRunsPage.js +36 -27
  104. package/dist/providers/LoopstackClientProvider.js +31 -0
  105. package/dist/services/createApiClient.js +9 -3
  106. package/dist/services/index.js +0 -1
  107. package/dist/services/reporting-fetch.js +13 -0
  108. package/package.json +4 -3
  109. package/dist/api/auth.js +0 -10
  110. package/dist/api/client.js +0 -13
  111. package/dist/api/config.js +0 -11
  112. package/dist/api/dashboard.js +0 -4
  113. package/dist/api/documents.js +0 -7
  114. package/dist/api/environments.js +0 -8
  115. package/dist/api/index.js +0 -28
  116. package/dist/api/processor.js +0 -7
  117. package/dist/api/secrets.js +0 -16
  118. package/dist/api/workflows.js +0 -15
  119. package/dist/api/workspaces.js +0 -12
  120. package/dist/events/sse-client-events.js +0 -13
  121. package/dist/features/code-explorer/CodeExplorer.js +0 -6
  122. package/dist/features/code-explorer/components/CodeExplorerTree.js +0 -6
  123. package/dist/features/code-explorer/components/FileTabsBar.js +0 -4
  124. package/dist/features/code-explorer/providers/CodeExplorerProvider.js +0 -5
  125. package/dist/features/file-explorer/api/files.js +0 -7
  126. package/dist/features/git/api/git.js +0 -9
  127. package/dist/hooks/query-keys.js +0 -145
  128. package/dist/hooks/useApi.js +0 -15
  129. package/dist/hooks/useFiles.js +0 -3
  130. package/dist/node_modules/lodash/_Symbol.js +0 -7
  131. package/dist/node_modules/lodash/_baseGetTag.js +0 -13
  132. package/dist/node_modules/lodash/_baseTrim.js +0 -11
  133. package/dist/node_modules/lodash/_freeGlobal.js +0 -6
  134. package/dist/node_modules/lodash/_getRawTag.js +0 -17
  135. package/dist/node_modules/lodash/_objectToString.js +0 -10
  136. package/dist/node_modules/lodash/_root.js +0 -8
  137. package/dist/node_modules/lodash/_trimmedEndIndex.js +0 -11
  138. package/dist/node_modules/lodash/debounce.js +0 -53
  139. package/dist/node_modules/lodash/isObject.js +0 -10
  140. package/dist/node_modules/lodash/isObjectLike.js +0 -9
  141. package/dist/node_modules/lodash/isSymbol.js +0 -12
  142. package/dist/node_modules/lodash/now.js +0 -10
  143. package/dist/node_modules/lodash/toNumber.js +0 -22
  144. package/dist/providers/InvalidationEventsProvider.js +0 -41
  145. package/dist/providers/SseProvider.js +0 -37
  146. package/dist/services/eventEmitter.js +0 -12
@@ -0,0 +1,35 @@
1
+ import { createHttpClient } from "./http.js";
2
+ import { createQueries } from "./queries/query-options.js";
3
+ import { createAuthResource } from "./resources/auth.js";
4
+ import { createConfigResource } from "./resources/config.js";
5
+ import { createDashboardResource } from "./resources/dashboard.js";
6
+ import { createDocumentsResource } from "./resources/documents.js";
7
+ import { createProcessorResource } from "./resources/processor.js";
8
+ import { createWorkflowsResource } from "./resources/workflows.js";
9
+ import { createWorkspacesResource } from "./resources/workspaces.js";
10
+ import { LoopstackStream } from "./stream/stream.js";
11
+ function createClient(u) {
12
+ let d = u.envKey ?? u.url, f = createHttpClient(u), p = createWorkflowsResource(f), m = createDocumentsResource(f), h = createProcessorResource(f), g = createWorkspacesResource(f), _ = createConfigResource(f), v = createDashboardResource(f), y = createAuthResource(f);
13
+ return {
14
+ envKey: d,
15
+ http: f,
16
+ workflows: p,
17
+ documents: m,
18
+ processor: h,
19
+ workspaces: g,
20
+ config: _,
21
+ dashboard: v,
22
+ auth: y,
23
+ queries: createQueries({
24
+ envKey: d,
25
+ workflows: p,
26
+ documents: m,
27
+ workspaces: g,
28
+ config: _,
29
+ dashboard: v,
30
+ auth: y
31
+ }),
32
+ stream: new LoopstackStream(u)
33
+ };
34
+ }
35
+ export { createClient };
@@ -0,0 +1,47 @@
1
+ var LoopstackApiError = class extends Error {
2
+ status;
3
+ body;
4
+ constructor(e, n, r) {
5
+ super(r), this.status = e, this.body = n, this.name = "LoopstackApiError";
6
+ }
7
+ };
8
+ function extractErrorMessage(e, n) {
9
+ if (e && typeof e == "object" && "message" in e) {
10
+ let n = e.message;
11
+ if (Array.isArray(n)) return n.join("; ");
12
+ if (typeof n == "string") return n;
13
+ }
14
+ return `Request failed with status ${n}`;
15
+ }
16
+ function createHttpClient(r) {
17
+ let i = r.fetch ?? fetch, a = r.url.replace(/\/+$/, "");
18
+ async function o(o, s, c = {}) {
19
+ let l = new URL(a + s);
20
+ for (let [e, n] of Object.entries(c.query ?? {})) n !== void 0 && l.searchParams.set(e, typeof n == "object" ? JSON.stringify(n) : String(n));
21
+ let u = { Accept: "application/json" };
22
+ c.body !== void 0 && (u["Content-Type"] = "application/json"), r.token && (u.Authorization = `Bearer ${r.token}`);
23
+ let d = await i(l, {
24
+ method: o,
25
+ headers: u,
26
+ credentials: r.credentials ?? "include",
27
+ body: c.body === void 0 ? void 0 : JSON.stringify(c.body)
28
+ }), f = await d.text(), p = f ? safeJsonParse(f) : void 0;
29
+ if (!d.ok) throw new LoopstackApiError(d.status, p ?? f, extractErrorMessage(p, d.status));
30
+ return p;
31
+ }
32
+ return {
33
+ get: (e, n) => o("GET", e, { query: n }),
34
+ post: (e, n) => o("POST", e, { body: n }),
35
+ put: (e, n) => o("PUT", e, { body: n }),
36
+ patch: (e, n) => o("PATCH", e, { body: n }),
37
+ delete: (e, n) => o("DELETE", e, { body: n })
38
+ };
39
+ }
40
+ function safeJsonParse(e) {
41
+ try {
42
+ return JSON.parse(e);
43
+ } catch {
44
+ return e;
45
+ }
46
+ }
47
+ export { LoopstackApiError, createHttpClient };
@@ -0,0 +1,15 @@
1
+ import { LoopstackApiError, createHttpClient } from "./http.js";
2
+ import { queryKeys } from "./queries/query-keys.js";
3
+ import { createQueries } from "./queries/query-options.js";
4
+ import { createAuthResource } from "./resources/auth.js";
5
+ import { createConfigResource } from "./resources/config.js";
6
+ import { createDashboardResource } from "./resources/dashboard.js";
7
+ import { createDocumentsResource } from "./resources/documents.js";
8
+ import { createProcessorResource } from "./resources/processor.js";
9
+ import { createWorkflowsResource } from "./resources/workflows.js";
10
+ import { createWorkspacesResource } from "./resources/workspaces.js";
11
+ import { createSseParser } from "./stream/sse-parser.js";
12
+ import { LoopstackStream } from "./stream/stream.js";
13
+ import { createClient } from "./client.js";
14
+ import { resolveInvalidations } from "./stream/invalidations.js";
15
+ import { reduceLlmStream } from "./stream/llm-reducer.js";
@@ -0,0 +1,94 @@
1
+ const queryKeys = {
2
+ workflow: (e, t) => [
3
+ "workflow",
4
+ e,
5
+ t
6
+ ],
7
+ workflowStatus: (e, t) => [
8
+ "workflowStatus",
9
+ e,
10
+ t
11
+ ],
12
+ workflows: (e) => ["workflows", e],
13
+ workflowList: (e, t = {}) => [
14
+ "workflows",
15
+ e,
16
+ "list",
17
+ t
18
+ ],
19
+ childWorkflows: (e, t) => [
20
+ "childWorkflows",
21
+ e,
22
+ t
23
+ ],
24
+ workflowCheckpoints: (e, t) => [
25
+ "workflow",
26
+ e,
27
+ t,
28
+ "checkpoints"
29
+ ],
30
+ workspace: (e, t) => [
31
+ "workspace",
32
+ e,
33
+ t
34
+ ],
35
+ workspaces: (e) => ["workspaces", e],
36
+ workspaceList: (e, t = {}) => [
37
+ "workspaces",
38
+ e,
39
+ "list",
40
+ t
41
+ ],
42
+ me: (e) => ["me", e],
43
+ workerHealth: (e) => ["workerHealth", e],
44
+ apps: (e) => ["apps", e],
45
+ workflowConfig: (e, t) => [
46
+ "workflowConfig",
47
+ e,
48
+ t
49
+ ],
50
+ workflowSource: (e, t) => [
51
+ "workflowSource",
52
+ e,
53
+ t
54
+ ],
55
+ toolConfigs: (e) => ["toolConfigs", e],
56
+ toolConfig: (e, t) => [
57
+ "toolConfig",
58
+ e,
59
+ t
60
+ ],
61
+ availableEnvironments: (e) => ["availableEnvironments", e],
62
+ dashboardStats: (e) => ["dashboardStats", e],
63
+ document: (e, t) => [
64
+ "document",
65
+ e,
66
+ t
67
+ ],
68
+ documents: (e, t) => [
69
+ "documents",
70
+ e,
71
+ t
72
+ ],
73
+ secrets: (e, t) => [
74
+ "secrets",
75
+ e,
76
+ t
77
+ ],
78
+ gitStatus: (e, t) => [
79
+ "gitStatus",
80
+ e,
81
+ t
82
+ ],
83
+ gitLog: (e, t) => [
84
+ "gitLog",
85
+ e,
86
+ t
87
+ ],
88
+ gitRemote: (e, t) => [
89
+ "gitRemote",
90
+ e,
91
+ t
92
+ ]
93
+ };
94
+ export { queryKeys };
@@ -0,0 +1,97 @@
1
+ import { SortOrder } from "../../../contracts/dist/enums/sort-order.enum.js";
2
+ import "../../../contracts/dist/enums/index.js";
3
+ import { queryKeys } from "./query-keys.js";
4
+ function createQueries({ envKey: n, workflows: r, documents: i, workspaces: a, config: o, dashboard: s, auth: c }) {
5
+ return {
6
+ workflow: (e) => ({
7
+ queryKey: queryKeys.workflow(n, e),
8
+ queryFn: () => r.get(e)
9
+ }),
10
+ workflowStatus: (e) => ({
11
+ queryKey: queryKeys.workflowStatus(n, e),
12
+ queryFn: () => r.status(e)
13
+ }),
14
+ workflowList: (e = {}) => ({
15
+ queryKey: queryKeys.workflowList(n, e),
16
+ queryFn: () => r.list(e)
17
+ }),
18
+ childWorkflows: (i) => ({
19
+ queryKey: queryKeys.childWorkflows(n, i),
20
+ queryFn: () => r.list({
21
+ filter: { parentId: i },
22
+ sortBy: [{
23
+ field: "createdAt",
24
+ order: SortOrder.ASC
25
+ }],
26
+ page: 0,
27
+ limit: 100
28
+ })
29
+ }),
30
+ workflowCheckpoints: (e) => ({
31
+ queryKey: queryKeys.workflowCheckpoints(n, e),
32
+ queryFn: () => r.checkpoints(e)
33
+ }),
34
+ document: (e) => ({
35
+ queryKey: queryKeys.document(n, e),
36
+ queryFn: () => i.get(e)
37
+ }),
38
+ documents: (r) => ({
39
+ queryKey: queryKeys.documents(n, r),
40
+ queryFn: () => i.list({
41
+ filter: {
42
+ workflowId: r,
43
+ isInvalidated: !1
44
+ },
45
+ sortBy: [{
46
+ field: "index",
47
+ order: SortOrder.ASC
48
+ }]
49
+ })
50
+ }),
51
+ workspace: (e) => ({
52
+ queryKey: queryKeys.workspace(n, e),
53
+ queryFn: () => a.get(e)
54
+ }),
55
+ workspaceList: (e = {}) => ({
56
+ queryKey: queryKeys.workspaceList(n, e),
57
+ queryFn: () => a.list(e)
58
+ }),
59
+ apps: () => ({
60
+ queryKey: queryKeys.apps(n),
61
+ queryFn: () => o.apps()
62
+ }),
63
+ workflowConfig: (e) => ({
64
+ queryKey: queryKeys.workflowConfig(n, e),
65
+ queryFn: () => o.workflowConfig(e)
66
+ }),
67
+ workflowSource: (e) => ({
68
+ queryKey: queryKeys.workflowSource(n, e),
69
+ queryFn: () => o.workflowSource(e)
70
+ }),
71
+ toolConfigs: () => ({
72
+ queryKey: queryKeys.toolConfigs(n),
73
+ queryFn: () => o.tools()
74
+ }),
75
+ toolConfig: (e) => ({
76
+ queryKey: queryKeys.toolConfig(n, e),
77
+ queryFn: () => o.tool(e)
78
+ }),
79
+ availableEnvironments: () => ({
80
+ queryKey: queryKeys.availableEnvironments(n),
81
+ queryFn: () => o.availableEnvironments()
82
+ }),
83
+ dashboardStats: () => ({
84
+ queryKey: queryKeys.dashboardStats(n),
85
+ queryFn: () => s.stats()
86
+ }),
87
+ me: () => ({
88
+ queryKey: queryKeys.me(n),
89
+ queryFn: () => c.me()
90
+ }),
91
+ workerHealth: () => ({
92
+ queryKey: queryKeys.workerHealth(n),
93
+ queryFn: () => c.workerHealth()
94
+ })
95
+ };
96
+ }
97
+ export { createQueries };
@@ -0,0 +1,10 @@
1
+ function createAuthResource(e) {
2
+ return {
3
+ me: () => e.get("/api/v1/auth/me"),
4
+ workerHealth: () => e.get("/api/v1/auth/worker/health"),
5
+ hubLogin: (t) => e.post("/api/v1/auth/oauth/hub", t),
6
+ refresh: () => e.post("/api/v1/auth/refresh"),
7
+ logout: () => e.post("/api/v1/auth/logout")
8
+ };
9
+ }
10
+ export { createAuthResource };
@@ -0,0 +1,11 @@
1
+ function createConfigResource(e) {
2
+ return {
3
+ apps: () => e.get("/api/v1/config/apps"),
4
+ workflowConfig: (t) => e.get(`/api/v1/config/workflows/${encodeURIComponent(t)}`),
5
+ workflowSource: (t) => e.get(`/api/v1/config/workflows/${encodeURIComponent(t)}/source`),
6
+ tools: () => e.get("/api/v1/config/tools"),
7
+ tool: (t) => e.get(`/api/v1/config/tools/${encodeURIComponent(t)}`),
8
+ availableEnvironments: () => e.get("/api/v1/config/environments")
9
+ };
10
+ }
11
+ export { createConfigResource };
@@ -0,0 +1,4 @@
1
+ function createDashboardResource(e) {
2
+ return { stats: () => e.get("/api/v1/dashboard") };
3
+ }
4
+ export { createDashboardResource };
@@ -0,0 +1,7 @@
1
+ function createDocumentsResource(e) {
2
+ return {
3
+ get: (t) => e.get(`/api/v1/documents/${t}`),
4
+ list: (t = {}) => e.get("/api/v1/documents", t)
5
+ };
6
+ }
7
+ export { createDocumentsResource };
@@ -0,0 +1,7 @@
1
+ function createProcessorResource(e) {
2
+ return {
3
+ start: (t) => e.post("/api/v1/processor/start", t),
4
+ run: (t, n = {}) => e.post(`/api/v1/processor/run/${t}`, n)
5
+ };
6
+ }
7
+ export { createProcessorResource };
@@ -0,0 +1,13 @@
1
+ function createWorkflowsResource(e) {
2
+ return {
3
+ get: (t) => e.get(`/api/v1/workflows/${t}`),
4
+ status: (t) => e.get(`/api/v1/workflows/${t}/status`),
5
+ list: (t = {}) => e.get("/api/v1/workflows", t),
6
+ create: (t) => e.post("/api/v1/workflows", t),
7
+ update: (t, n) => e.put(`/api/v1/workflows/${t}`, n),
8
+ delete: (t) => e.delete(`/api/v1/workflows/id/${t}`),
9
+ batchDelete: (t) => e.delete("/api/v1/workflows/batch", { ids: t }),
10
+ checkpoints: (t) => e.get(`/api/v1/workflows/${t}/checkpoints`)
11
+ };
12
+ }
13
+ export { createWorkflowsResource };
@@ -0,0 +1,12 @@
1
+ function createWorkspacesResource(e) {
2
+ return {
3
+ get: (t) => e.get(`/api/v1/workspaces/${t}`),
4
+ list: (t = {}) => e.get("/api/v1/workspaces", t),
5
+ create: (t) => e.post("/api/v1/workspaces", t),
6
+ update: (t, n) => e.put(`/api/v1/workspaces/${t}`, n),
7
+ setFavourite: (t, n) => e.patch(`/api/v1/workspaces/${t}/favourite`, { isFavourite: n }),
8
+ delete: (t) => e.delete(`/api/v1/workspaces/id/${t}`),
9
+ batchDelete: (t) => e.delete("/api/v1/workspaces/batch", { ids: t })
10
+ };
11
+ }
12
+ export { createWorkspacesResource };
@@ -0,0 +1,20 @@
1
+ import { queryKeys } from "../queries/query-keys.js";
2
+ function resolveInvalidations(t, n) {
3
+ switch (t.type) {
4
+ case "workflow.created": return t.parentId ? [queryKeys.childWorkflows(n, t.parentId)] : [];
5
+ case "workflow.updated": {
6
+ let r = [queryKeys.workflow(n, t.id), queryKeys.workflowStatus(n, t.id)];
7
+ return t.parentId && r.push(queryKeys.childWorkflows(n, t.parentId)), r;
8
+ }
9
+ case "document.created": return [queryKeys.documents(n, t.workflowId)];
10
+ case "secret.upserted":
11
+ case "secret.deleted": return [queryKeys.secrets(n, t.workspaceId)];
12
+ case "git.updated": return [
13
+ queryKeys.gitStatus(n, t.workspaceId),
14
+ queryKeys.gitLog(n, t.workspaceId),
15
+ queryKeys.gitRemote(n, t.workspaceId)
16
+ ];
17
+ default: return [];
18
+ }
19
+ }
20
+ export { resolveInvalidations };
@@ -0,0 +1,65 @@
1
+ function emptyMessageState(e) {
2
+ return {
3
+ messageId: e.messageId,
4
+ workflowId: e.workflowId,
5
+ text: "",
6
+ thinking: "",
7
+ toolCalls: [],
8
+ completed: !1
9
+ };
10
+ }
11
+ function reduceLlmStream(t, n) {
12
+ let r = t[n.messageId] ?? emptyMessageState(n);
13
+ switch (n.type) {
14
+ case "llm.response.start": return {
15
+ ...t,
16
+ [n.messageId]: {
17
+ ...r,
18
+ completed: !1,
19
+ error: void 0
20
+ }
21
+ };
22
+ case "llm.response.text_delta": return {
23
+ ...t,
24
+ [n.messageId]: {
25
+ ...r,
26
+ text: r.text + n.delta
27
+ }
28
+ };
29
+ case "llm.response.thinking_delta": return {
30
+ ...t,
31
+ [n.messageId]: {
32
+ ...r,
33
+ thinking: r.thinking + n.delta
34
+ }
35
+ };
36
+ case "llm.response.tool_call": return {
37
+ ...t,
38
+ [n.messageId]: {
39
+ ...r,
40
+ toolCalls: [...r.toolCalls, {
41
+ id: n.id,
42
+ name: n.name,
43
+ args: n.args
44
+ }]
45
+ }
46
+ };
47
+ case "llm.response.done": return {
48
+ ...t,
49
+ [n.messageId]: {
50
+ ...r,
51
+ completed: !0,
52
+ message: n.message
53
+ }
54
+ };
55
+ case "llm.response.error": return {
56
+ ...t,
57
+ [n.messageId]: {
58
+ ...r,
59
+ completed: !0,
60
+ error: n.error
61
+ }
62
+ };
63
+ }
64
+ }
65
+ export { reduceLlmStream };
@@ -0,0 +1,40 @@
1
+ function createSseParser(e) {
2
+ let t = "", n = [], r, i;
3
+ function a() {
4
+ (n.length > 0 || r !== void 0 || i !== void 0) && e({
5
+ id: i,
6
+ event: r,
7
+ data: n.join("\n")
8
+ }), n = [], r = void 0, i = void 0;
9
+ }
10
+ function o(e) {
11
+ if (e === "") {
12
+ a();
13
+ return;
14
+ }
15
+ if (e.startsWith(":")) return;
16
+ let t = e.indexOf(":"), o = t === -1 ? e : e.slice(0, t), s = t === -1 ? "" : e.slice(t + 1);
17
+ switch (s.startsWith(" ") && (s = s.slice(1)), o) {
18
+ case "data":
19
+ n.push(s);
20
+ break;
21
+ case "event":
22
+ r = s;
23
+ break;
24
+ case "id":
25
+ s.includes("\0") || (i = s);
26
+ break;
27
+ }
28
+ }
29
+ return { feed(e) {
30
+ t += e;
31
+ let n;
32
+ for (; (n = t.search(/\r\n|\n|\r/)) !== -1;) {
33
+ let e = t[n] === "\r";
34
+ if (e && n === t.length - 1) return;
35
+ let r = t.slice(0, n);
36
+ t = t.slice(n + (e && t[n + 1] === "\n" ? 2 : 1)), o(r);
37
+ }
38
+ } };
39
+ }
40
+ export { createSseParser };
@@ -0,0 +1,147 @@
1
+ import { LoopstackApiError } from "../http.js";
2
+ import { ClientMessageSchema } from "../../../contracts/dist/events/client-message.schema.js";
3
+ import "../../../contracts/dist/events/index.js";
4
+ import { createSseParser } from "./sse-parser.js";
5
+ var INITIAL_RETRY_DELAY_MS = 500;
6
+ function matchesWorkflow(e, t) {
7
+ return !t || e.type === "stream.reset" ? !0 : "workflowId" in e ? e.workflowId === t : !0;
8
+ }
9
+ var LoopstackStream = class {
10
+ config;
11
+ handlers = /* @__PURE__ */ new Map();
12
+ anyHandlers = /* @__PURE__ */ new Set();
13
+ statusHandlers = /* @__PURE__ */ new Set();
14
+ subscriberCount = 0;
15
+ abortController;
16
+ watchdog;
17
+ running = !1;
18
+ closed = !1;
19
+ currentStatus = "idle";
20
+ lastEventId;
21
+ constructor(e) {
22
+ this.config = e, this.lastEventId = e.lastEventId;
23
+ }
24
+ get status() {
25
+ return this.currentStatus;
26
+ }
27
+ on(e, t) {
28
+ this.handlers.has(e) || this.handlers.set(e, /* @__PURE__ */ new Set()), this.handlers.get(e).add(t), this.retain();
29
+ let n = !0;
30
+ return () => {
31
+ n && (n = !1, this.handlers.get(e)?.delete(t), this.release());
32
+ };
33
+ }
34
+ onAny(e) {
35
+ this.anyHandlers.add(e), this.retain();
36
+ let t = !0;
37
+ return () => {
38
+ t && (t = !1, this.anyHandlers.delete(e), this.release());
39
+ };
40
+ }
41
+ onStatus(e) {
42
+ return this.statusHandlers.add(e), () => this.statusHandlers.delete(e);
43
+ }
44
+ events(e = {}) {
45
+ let t = [], n, r = !1, a = this.onAny((r) => {
46
+ "userId" in r && matchesWorkflow(r, e.workflowId) && (t.push(r), n?.());
47
+ }), o = {
48
+ [Symbol.asyncIterator]: () => o,
49
+ next: async () => {
50
+ for (; t.length === 0 && !r;) await new Promise((e) => n = e), n = void 0;
51
+ return t.length === 0 ? {
52
+ done: !0,
53
+ value: void 0
54
+ } : {
55
+ done: !1,
56
+ value: t.shift()
57
+ };
58
+ },
59
+ return: async () => (r = !0, a(), n?.(), {
60
+ done: !0,
61
+ value: void 0
62
+ })
63
+ };
64
+ return o;
65
+ }
66
+ close() {
67
+ this.closed = !0, this.handlers.clear(), this.anyHandlers.clear(), this.subscriberCount = 0, this.abortController?.abort(), this.clearWatchdog(), this.setStatus("closed");
68
+ }
69
+ retain() {
70
+ this.subscriberCount++, this.subscriberCount === 1 && !this.running && !this.closed && this.runLoop();
71
+ }
72
+ release() {
73
+ this.subscriberCount = Math.max(0, this.subscriberCount - 1), this.subscriberCount === 0 && this.abortController?.abort();
74
+ }
75
+ setStatus(e) {
76
+ if (this.currentStatus !== e) {
77
+ this.currentStatus = e;
78
+ for (let t of this.statusHandlers) t(e);
79
+ }
80
+ }
81
+ buildUrl() {
82
+ let e = new URL(`${this.config.url.replace(/\/+$/, "")}/api/v1/sse/stream`);
83
+ return this.config.workflowId && e.searchParams.set("workflowId", this.config.workflowId), e;
84
+ }
85
+ async runLoop() {
86
+ this.running = !0;
87
+ let t = this.config.fetch ?? fetch, i = 0;
88
+ for (; !this.closed && this.subscriberCount > 0;) {
89
+ this.abortController = new AbortController();
90
+ let { signal: a } = this.abortController;
91
+ try {
92
+ this.setStatus("connecting");
93
+ let r = { Accept: "text/event-stream" };
94
+ this.config.token && (r.Authorization = `Bearer ${this.config.token}`), this.lastEventId !== void 0 && (r["Last-Event-ID"] = this.lastEventId);
95
+ let o = await t(this.buildUrl(), {
96
+ headers: r,
97
+ credentials: this.config.credentials ?? "include",
98
+ signal: a
99
+ });
100
+ if (!o.ok || !o.body) throw new LoopstackApiError(o.status, void 0, `Event stream failed with status ${o.status}`);
101
+ this.setStatus("open"), i = 0, this.resetWatchdog();
102
+ let s = createSseParser((e) => {
103
+ this.resetWatchdog(), e.id !== void 0 && e.id !== "" && (this.lastEventId = e.id), e.event !== "ping" && e.data && this.dispatch(e.data);
104
+ }), c = o.body.getReader(), l = new TextDecoder();
105
+ for (;;) {
106
+ let { done: e, value: t } = await c.read();
107
+ if (e) break;
108
+ s.feed(l.decode(t, { stream: !0 }));
109
+ }
110
+ } catch {}
111
+ if (this.clearWatchdog(), this.currentStatus === "open" && this.setStatus("connecting"), this.closed || this.subscriberCount === 0) break;
112
+ i++;
113
+ let o = Math.min(this.config.maxRetryDelayMs ?? 1e4, INITIAL_RETRY_DELAY_MS * 2 ** (i - 1)) * (.8 + Math.random() * .4);
114
+ await new Promise((e) => setTimeout(e, o));
115
+ }
116
+ this.running = !1, this.setStatus(this.closed ? "closed" : "idle");
117
+ }
118
+ dispatch(e) {
119
+ let n;
120
+ try {
121
+ n = JSON.parse(e);
122
+ } catch {
123
+ return;
124
+ }
125
+ let r = ClientMessageSchema.safeParse(n);
126
+ if (r.success) {
127
+ let e = r.data;
128
+ for (let t of this.handlers.get(e.type) ?? []) t(e);
129
+ for (let t of this.anyHandlers) t(e);
130
+ return;
131
+ }
132
+ let i = n && typeof n == "object" && "type" in n && typeof n.type == "string" ? n.type : "unknown";
133
+ for (let e of this.anyHandlers) e({
134
+ type: i,
135
+ raw: n
136
+ });
137
+ }
138
+ resetWatchdog() {
139
+ this.clearWatchdog(), this.watchdog = setTimeout(() => {
140
+ this.abortController?.abort();
141
+ }, this.config.heartbeatTimeoutMs ?? 6e4), this.watchdog.unref?.();
142
+ }
143
+ clearWatchdog() {
144
+ this.watchdog !== void 0 && clearTimeout(this.watchdog), this.watchdog = void 0;
145
+ }
146
+ };
147
+ export { LoopstackStream };
@@ -0,0 +1,6 @@
1
+ import { z } from "zod";
2
+ const ClientMessageBaseSchema = z.object({
3
+ userId: z.string().nullable(),
4
+ workerId: z.string()
5
+ });
6
+ export { ClientMessageBaseSchema };
@@ -0,0 +1,24 @@
1
+ import { DocumentCreatedEventSchema, WorkflowCreatedEventSchema, WorkflowUpdatedEventSchema } from "./workflow-events.schema.js";
2
+ import { GitUpdatedEventSchema, SecretDeletedEventSchema, SecretUpsertedEventSchema } from "./workspace-events.schema.js";
3
+ import { LlmResponseDoneEventSchema, LlmResponseErrorEventSchema, LlmResponseStartEventSchema, LlmResponseTextDeltaEventSchema, LlmResponseThinkingDeltaEventSchema, LlmResponseToolCallEventSchema } from "./llm-events.schema.js";
4
+ import { StreamResetEventSchema } from "./stream-events.schema.js";
5
+ import { z } from "zod";
6
+ const ClientMessageSchema = z.discriminatedUnion("type", [
7
+ WorkflowCreatedEventSchema,
8
+ WorkflowUpdatedEventSchema,
9
+ DocumentCreatedEventSchema,
10
+ SecretUpsertedEventSchema,
11
+ SecretDeletedEventSchema,
12
+ GitUpdatedEventSchema,
13
+ LlmResponseStartEventSchema,
14
+ LlmResponseTextDeltaEventSchema,
15
+ LlmResponseThinkingDeltaEventSchema,
16
+ LlmResponseToolCallEventSchema,
17
+ LlmResponseDoneEventSchema,
18
+ LlmResponseErrorEventSchema,
19
+ StreamResetEventSchema
20
+ ]);
21
+ function isLlmResponseEvent(e) {
22
+ return e.type.startsWith("llm.response.");
23
+ }
24
+ export { ClientMessageSchema, isLlmResponseEvent };
@@ -0,0 +1,6 @@
1
+ import { ClientMessageBaseSchema } from "./client-message-base.schema.js";
2
+ import { DocumentCreatedEventSchema, WorkflowCreatedEventSchema, WorkflowUpdatedEventSchema } from "./workflow-events.schema.js";
3
+ import { GitUpdatedEventSchema, SecretDeletedEventSchema, SecretUpsertedEventSchema } from "./workspace-events.schema.js";
4
+ import { LlmNormalizedMessageSchema, LlmResponseDoneEventSchema, LlmResponseErrorEventSchema, LlmResponseStartEventSchema, LlmResponseTextDeltaEventSchema, LlmResponseThinkingDeltaEventSchema, LlmResponseToolCallEventSchema } from "./llm-events.schema.js";
5
+ import { StreamResetEventSchema } from "./stream-events.schema.js";
6
+ import { ClientMessageSchema, isLlmResponseEvent } from "./client-message.schema.js";