@floomhq/floom 5.0.12 → 5.1.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 (46) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +381 -381
  3. package/assets/floom-skill.md +32 -0
  4. package/bin/floom-mcp +9 -9
  5. package/bin/workeros-mcp +13 -13
  6. package/dist/cli.js +60 -10
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/completion.js +85 -85
  9. package/dist/commands/connections.js +3 -3
  10. package/dist/commands/connections.js.map +1 -1
  11. package/dist/commands/contexts.js +9 -9
  12. package/dist/commands/contexts.js.map +1 -1
  13. package/dist/commands/doctor.js +2 -2
  14. package/dist/commands/doctor.js.map +1 -1
  15. package/dist/commands/init.d.ts +5 -0
  16. package/dist/commands/init.js +64 -0
  17. package/dist/commands/init.js.map +1 -0
  18. package/dist/commands/login.js +5 -9
  19. package/dist/commands/login.js.map +1 -1
  20. package/dist/commands/mcp.d.ts +4 -0
  21. package/dist/commands/mcp.js +67 -8
  22. package/dist/commands/mcp.js.map +1 -1
  23. package/dist/commands/runs.d.ts +1 -0
  24. package/dist/commands/runs.js +83 -20
  25. package/dist/commands/runs.js.map +1 -1
  26. package/dist/commands/whoami.js +5 -1
  27. package/dist/commands/whoami.js.map +1 -1
  28. package/dist/commands/workers.d.ts +3 -1
  29. package/dist/commands/workers.js +37 -18
  30. package/dist/commands/workers.js.map +1 -1
  31. package/dist/commands/workspaces.js +9 -4
  32. package/dist/commands/workspaces.js.map +1 -1
  33. package/dist/lib/api.js +2 -2
  34. package/dist/lib/api.js.map +1 -1
  35. package/dist/lib/cli-errors.d.ts +3 -1
  36. package/dist/lib/cli-errors.js +10 -2
  37. package/dist/lib/cli-errors.js.map +1 -1
  38. package/dist/lib/credentials.js +2 -2
  39. package/dist/lib/credentials.js.map +1 -1
  40. package/dist/lib/output.d.ts +1 -0
  41. package/dist/lib/output.js +11 -7
  42. package/dist/lib/output.js.map +1 -1
  43. package/dist/lib/worker-authoring.js +154 -154
  44. package/dist/server.js +4 -4
  45. package/dist/server.js.map +1 -1
  46. package/package.json +47 -46
@@ -50,57 +50,57 @@ export const WORKER_TEMPLATES = [
50
50
  title: "Python Script Worker",
51
51
  description: "Deterministic E2B worker that reads inputs.json and writes result.json.",
52
52
  mode: "pure-script",
53
- worker_yml: `schema_version: "0.3"
54
- name: text-normalizer
55
- title: Text Normalizer
56
- description: Normalize a text input and return the normalized value.
57
- version: "0.1.0"
58
- entrypoint: run.py
59
- trigger:
60
- type: manual
61
- exec:
62
- mode: pure-script
63
- entry: run.py
64
- runtime: python311
65
- runner: e2b
66
- command: python run.py
67
- inputs:
68
- - name: text
69
- label: Text
70
- type: string
71
- kind: scalar
72
- required: true
73
- outputs:
74
- - name: normalized
75
- label: Normalized text
76
- type: string
77
- kind: scalar
78
- required: true
79
- capabilities:
80
- network:
81
- egress: false
82
- secrets: []
83
- connections: []
53
+ worker_yml: `schema_version: "0.3"
54
+ name: text-normalizer
55
+ title: Text Normalizer
56
+ description: Normalize a text input and return the normalized value.
57
+ version: "0.1.0"
58
+ entrypoint: run.py
59
+ trigger:
60
+ type: manual
61
+ exec:
62
+ mode: pure-script
63
+ entry: run.py
64
+ runtime: python311
65
+ runner: e2b
66
+ command: python run.py
67
+ inputs:
68
+ - name: text
69
+ label: Text
70
+ type: string
71
+ kind: scalar
72
+ required: true
73
+ outputs:
74
+ - name: normalized
75
+ label: Normalized text
76
+ type: string
77
+ kind: scalar
78
+ required: true
79
+ capabilities:
80
+ network:
81
+ egress: false
82
+ secrets: []
83
+ connections: []
84
84
  `,
85
- run_py: `import json
86
- from pathlib import Path
87
-
88
-
89
- def main() -> None:
90
- inputs_path = Path("inputs.json")
91
- inputs = json.loads(inputs_path.read_text(encoding="utf-8")) if inputs_path.exists() else {}
92
- text = str(inputs.get("text", "")).strip()
93
- result = {
94
- "status": "success",
95
- "outputs": {"normalized": " ".join(text.split())},
96
- "artifacts": [],
97
- "error": None,
98
- }
99
- Path("result.json").write_text(json.dumps(result), encoding="utf-8")
100
-
101
-
102
- if __name__ == "__main__":
103
- main()
85
+ run_py: `import json
86
+ from pathlib import Path
87
+
88
+
89
+ def main() -> None:
90
+ inputs_path = Path("inputs.json")
91
+ inputs = json.loads(inputs_path.read_text(encoding="utf-8")) if inputs_path.exists() else {}
92
+ text = str(inputs.get("text", "")).strip()
93
+ result = {
94
+ "status": "success",
95
+ "outputs": {"normalized": " ".join(text.split())},
96
+ "artifacts": [],
97
+ "error": None,
98
+ }
99
+ Path("result.json").write_text(json.dumps(result), encoding="utf-8")
100
+
101
+
102
+ if __name__ == "__main__":
103
+ main()
104
104
  `,
105
105
  notes: [
106
106
  "Use this when the job can be completed deterministically in code.",
@@ -112,54 +112,54 @@ if __name__ == "__main__":
112
112
  title: "Gmail Summary Agent",
113
113
  description: "Agent-mode worker that uses a Gmail connection and produces a markdown summary.",
114
114
  mode: "agent",
115
- worker_yml: `schema_version: "0.3"
116
- name: gmail-summary-agent
117
- title: Gmail Summary Agent
118
- description: Summarize recent Gmail messages into a concise markdown brief.
119
- version: "0.1.0"
120
- entrypoint: SKILL.md
121
- trigger:
122
- type: manual
123
- connections:
124
- - app: gmail
125
- allowed_tools:
126
- - GMAIL_FETCH_EMAILS
127
- exec:
128
- mode: agent
129
- entry: SKILL.md
130
- runtime: python311
131
- runner: e2b
132
- inputs:
133
- - name: query
134
- label: Gmail query
135
- type: string
136
- kind: scalar
137
- required: false
138
- default: newer_than:1d
139
- outputs:
140
- - name: summary
141
- label: Summary
142
- kind: file
143
- media_type: text/markdown
144
- path: out/summary.md
145
- required: true
146
- limits:
147
- max_tool_iterations: 60
148
- max_output_tokens: 100000
149
- max_total_tokens: 1000000
150
- timeout_seconds: 300
151
- capabilities:
152
- network:
153
- egress: true
154
- secrets: []
155
- connections:
156
- - gmail
115
+ worker_yml: `schema_version: "0.3"
116
+ name: gmail-summary-agent
117
+ title: Gmail Summary Agent
118
+ description: Summarize recent Gmail messages into a concise markdown brief.
119
+ version: "0.1.0"
120
+ entrypoint: SKILL.md
121
+ trigger:
122
+ type: manual
123
+ connections:
124
+ - app: gmail
125
+ allowed_tools:
126
+ - GMAIL_FETCH_EMAILS
127
+ exec:
128
+ mode: agent
129
+ entry: SKILL.md
130
+ runtime: python311
131
+ runner: e2b
132
+ inputs:
133
+ - name: query
134
+ label: Gmail query
135
+ type: string
136
+ kind: scalar
137
+ required: false
138
+ default: newer_than:1d
139
+ outputs:
140
+ - name: summary
141
+ label: Summary
142
+ kind: file
143
+ media_type: text/markdown
144
+ path: out/summary.md
145
+ required: true
146
+ limits:
147
+ max_tool_iterations: 60
148
+ max_output_tokens: 100000
149
+ max_total_tokens: 1000000
150
+ timeout_seconds: 300
151
+ capabilities:
152
+ network:
153
+ egress: true
154
+ secrets: []
155
+ connections:
156
+ - gmail
157
157
  `,
158
- skill_md: `# Gmail Summary Agent
159
-
160
- Fetch recent Gmail messages using the declared Gmail connection, summarize the important items, and write a markdown brief to out/summary.md.
161
-
162
- Call the Gmail runtime tool once with the declared allowed tool, summarize the returned messages, then call finish_with_outputs with the output named summary. Do not ask the user for OAuth tokens or passwords.
158
+ skill_md: `# Gmail Summary Agent
159
+
160
+ Fetch recent Gmail messages using the declared Gmail connection, summarize the important items, and write a markdown brief to out/summary.md.
161
+
162
+ Call the Gmail runtime tool once with the declared allowed tool, summarize the returned messages, then call finish_with_outputs with the output named summary. Do not ask the user for OAuth tokens or passwords.
163
163
  `,
164
164
  notes: [
165
165
  "Use agent mode when the work needs reasoning or tool calls.",
@@ -171,64 +171,64 @@ Call the Gmail runtime tool once with the declared allowed tool, summarize the r
171
171
  title: "Approval Script Worker",
172
172
  description: "Script worker that prepares a human approval payload before an external action.",
173
173
  mode: "pure-script",
174
- worker_yml: `schema_version: "0.3"
175
- name: approval-script
176
- title: Approval Script
177
- description: Build an approval payload for a proposed outbound action.
178
- version: "0.1.0"
179
- entrypoint: run.py
180
- trigger:
181
- type: manual
182
- exec:
183
- mode: pure-script
184
- entry: run.py
185
- runtime: python311
186
- runner: e2b
187
- command: python run.py
188
- inputs:
189
- - name: message
190
- label: Message
191
- type: string
192
- kind: scalar
193
- required: true
194
- outputs:
195
- - name: plan
196
- label: Approval plan
197
- kind: file
198
- media_type: text/markdown
199
- path: out/plan.md
200
- required: true
201
- approvals:
202
- required: true
203
- label: Approve outbound action
204
- capabilities:
205
- network:
206
- egress: false
207
- secrets: []
208
- connections: []
174
+ worker_yml: `schema_version: "0.3"
175
+ name: approval-script
176
+ title: Approval Script
177
+ description: Build an approval payload for a proposed outbound action.
178
+ version: "0.1.0"
179
+ entrypoint: run.py
180
+ trigger:
181
+ type: manual
182
+ exec:
183
+ mode: pure-script
184
+ entry: run.py
185
+ runtime: python311
186
+ runner: e2b
187
+ command: python run.py
188
+ inputs:
189
+ - name: message
190
+ label: Message
191
+ type: string
192
+ kind: scalar
193
+ required: true
194
+ outputs:
195
+ - name: plan
196
+ label: Approval plan
197
+ kind: file
198
+ media_type: text/markdown
199
+ path: out/plan.md
200
+ required: true
201
+ approvals:
202
+ required: true
203
+ label: Approve outbound action
204
+ capabilities:
205
+ network:
206
+ egress: false
207
+ secrets: []
208
+ connections: []
209
209
  `,
210
- run_py: `import json
211
- from pathlib import Path
212
-
213
-
214
- def main() -> None:
215
- inputs = json.loads(Path("inputs.json").read_text(encoding="utf-8"))
216
- message = str(inputs.get("message", "")).strip()
217
- out_dir = Path("out")
218
- out_dir.mkdir(exist_ok=True)
219
- plan_path = out_dir / "plan.md"
220
- plan_path.write_text(f"# Proposed action\\n\\n{message}\\n", encoding="utf-8")
221
- result = {
222
- "status": "success",
223
- "outputs": {"plan": str(plan_path)},
224
- "artifacts": [{"name": "plan.md", "path": str(plan_path), "type": "text/markdown"}],
225
- "error": None,
226
- }
227
- Path("result.json").write_text(json.dumps(result), encoding="utf-8")
228
-
229
-
230
- if __name__ == "__main__":
231
- main()
210
+ run_py: `import json
211
+ from pathlib import Path
212
+
213
+
214
+ def main() -> None:
215
+ inputs = json.loads(Path("inputs.json").read_text(encoding="utf-8"))
216
+ message = str(inputs.get("message", "")).strip()
217
+ out_dir = Path("out")
218
+ out_dir.mkdir(exist_ok=True)
219
+ plan_path = out_dir / "plan.md"
220
+ plan_path.write_text(f"# Proposed action\\n\\n{message}\\n", encoding="utf-8")
221
+ result = {
222
+ "status": "success",
223
+ "outputs": {"plan": str(plan_path)},
224
+ "artifacts": [{"name": "plan.md", "path": str(plan_path), "type": "text/markdown"}],
225
+ "error": None,
226
+ }
227
+ Path("result.json").write_text(json.dumps(result), encoding="utf-8")
228
+
229
+
230
+ if __name__ == "__main__":
231
+ main()
232
232
  `,
233
233
  notes: [
234
234
  "Use approvals.required when a human must review before publication or side effects.",
package/dist/server.js CHANGED
@@ -28,14 +28,14 @@ class FloomApiError extends Error {
28
28
  }
29
29
  }
30
30
  function apiBase() {
31
- return (process.env.WORKEROS_API_BASE || DEFAULT_API_BASE).replace(/\/+$/, "");
31
+ return (process.env.FLOOM_API_BASE || process.env.WORKEROS_API_BASE || DEFAULT_API_BASE).replace(/\/+$/, "");
32
32
  }
33
33
  function hostedModeRequested() {
34
34
  const value = (process.env.WORKEROS_CLOUD || "").trim().toLowerCase();
35
35
  return value === "1" || value === "true" || value === "yes" || value === "on";
36
36
  }
37
37
  function isHostedApi() {
38
- return Boolean(process.env.WORKEROS_API_TOKEN) || hostedModeRequested();
38
+ return Boolean(process.env.FLOOM_TOKEN || process.env.WORKEROS_API_TOKEN) || hostedModeRequested();
39
39
  }
40
40
  function resolvePath(path) {
41
41
  if (!isHostedApi())
@@ -63,14 +63,14 @@ function activeWorkspaceId() {
63
63
  }
64
64
  function authHeader() {
65
65
  const headers = {};
66
- const token = process.env.WORKEROS_API_TOKEN?.trim();
66
+ const token = (process.env.FLOOM_TOKEN || process.env.WORKEROS_API_TOKEN || "").trim();
67
67
  if (token) {
68
68
  headers["x-floom-token"] = token;
69
69
  }
70
70
  else {
71
71
  const secret = process.env.WORKEROS_API_SECRET?.trim();
72
72
  if (!secret) {
73
- throw new Error("WORKEROS_API_TOKEN or WORKEROS_API_SECRET is required");
73
+ throw new Error("FLOOM_TOKEN, WORKEROS_API_TOKEN, or WORKEROS_API_SECRET is required");
74
74
  }
75
75
  headers["x-floom-secret"] = secret;
76
76
  // Self-hosted engines with user-header scope require x-floom-user (OSS only).