@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.
- package/LICENSE +21 -21
- package/README.md +381 -381
- package/assets/floom-skill.md +32 -0
- package/bin/floom-mcp +9 -9
- package/bin/workeros-mcp +13 -13
- package/dist/cli.js +60 -10
- package/dist/cli.js.map +1 -1
- package/dist/commands/completion.js +85 -85
- package/dist/commands/connections.js +3 -3
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/contexts.js +9 -9
- package/dist/commands/contexts.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +64 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.js +5 -9
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp.d.ts +4 -0
- package/dist/commands/mcp.js +67 -8
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/runs.d.ts +1 -0
- package/dist/commands/runs.js +83 -20
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/whoami.js +5 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workers.d.ts +3 -1
- package/dist/commands/workers.js +37 -18
- package/dist/commands/workers.js.map +1 -1
- package/dist/commands/workspaces.js +9 -4
- package/dist/commands/workspaces.js.map +1 -1
- package/dist/lib/api.js +2 -2
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/cli-errors.d.ts +3 -1
- package/dist/lib/cli-errors.js +10 -2
- package/dist/lib/cli-errors.js.map +1 -1
- package/dist/lib/credentials.js +2 -2
- package/dist/lib/credentials.js.map +1 -1
- package/dist/lib/output.d.ts +1 -0
- package/dist/lib/output.js +11 -7
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/worker-authoring.js +154 -154
- package/dist/server.js +4 -4
- package/dist/server.js.map +1 -1
- 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
|
|
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).
|