@amalgm/automations 0.3.2 → 0.4.1

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 (42) hide show
  1. package/AXIOMS.md +16 -1
  2. package/PURPOSE.md +30 -0
  3. package/README.md +53 -4
  4. package/dist/host/auth.js +4 -1
  5. package/dist/host/main.js +11 -1
  6. package/dist/host/notifications.d.ts +4 -0
  7. package/dist/host/notifications.js +19 -0
  8. package/dist/host/server.d.ts +1 -0
  9. package/dist/host/server.js +51 -10
  10. package/dist/host/skill.d.ts +2 -0
  11. package/dist/host/skill.js +33 -0
  12. package/dist/skills/amalgm-automations.5e4e14f0ace632c8383cd014e1f0f34b24ec0d5c5600132a840abc4c313b31d4.tgz +0 -0
  13. package/dist/skills/index.json +1 -0
  14. package/dist/src/cli/run.d.ts +1 -1
  15. package/dist/src/cli/run.js +17 -0
  16. package/dist/src/crud/triggers.js +0 -1
  17. package/dist/src/index.d.ts +1 -0
  18. package/dist/src/index.js +1 -0
  19. package/dist/src/machine-client.d.ts +3 -1
  20. package/dist/src/machine-client.js +6 -0
  21. package/dist/src/machine-event-stream.d.ts +8 -0
  22. package/dist/src/machine-event-stream.js +58 -0
  23. package/dist/src/machine-http.d.ts +2 -0
  24. package/dist/src/machine-http.js +8 -2
  25. package/dist/src/machine-notifications.d.ts +15 -0
  26. package/dist/src/machine-notifications.js +124 -0
  27. package/dist/src/machine.d.ts +1 -0
  28. package/dist/src/mcp.d.ts +2 -1
  29. package/dist/src/mcp.js +4 -2
  30. package/dist/src/runner.d.ts +3 -1
  31. package/dist/src/runner.js +69 -46
  32. package/dist/src/schema.js +9 -3
  33. package/dist/src/supabase-machine.d.ts +1 -0
  34. package/dist/src/supabase-machine.js +3 -0
  35. package/dist/src/tool-surface.js +21 -2
  36. package/package.json +3 -2
  37. package/skills/amalgm-automations/SKILL.md +49 -11
  38. package/skills/amalgm-automations/agents/openai.yaml +2 -2
  39. package/skills/amalgm-automations/references/command-contract.md +7 -0
  40. package/skills/amalgm-automations/references/setup-and-support.md +236 -0
  41. package/supabase/migrations/20260904020000_machine_run_notifications.sql +52 -0
  42. package/supabase/migrations/20260904030000_machine_notification_permissions.sql +4 -0
@@ -0,0 +1,236 @@
1
+ # Setup and support
2
+
3
+ Read this when installing, signing in, repairing a connection, or helping with
4
+ an error. Use Shell's commands for setup and Automations reads to verify access.
5
+ The agent handles the commands; the person chooses their Google account and
6
+ approves connecting their computer in the browser.
7
+
8
+ ## Install this skill
9
+
10
+ The public download includes this skill and all its references; it needs no
11
+ GitHub account or access to Amalgm's source repositories. With Node.js 22.20+
12
+ (or Amalgm's supplied Node runtime), run:
13
+
14
+ ```bash
15
+ npx skills add https://automations.amalgm.ai --skill amalgm-automations
16
+ ```
17
+
18
+ Choose the intended agent in the installer's prompt. Installing the skill
19
+ supplies guidance; use the connection steps below to access Automations.
20
+
21
+ ## Start with the connection you have
22
+
23
+ If Automations MCP already answers `list` with `{"limit":1}`, continue the task.
24
+ Do not require a local CLI for a working remote MCP connection. If that remote
25
+ connection requires authorization, use its actual sign-in/reconnect link. A
26
+ cloud agent cannot repair the user's computer by installing Shell on its own
27
+ temporary machine.
28
+
29
+ For local CLI work, use the existing `amalgm` executable or the exact Shell
30
+ launcher supplied by Amalgm's installer/app. The examples below use `amalgm`
31
+ as shorthand for that executable. Keep the same installation and account
32
+ throughout setup and verification.
33
+
34
+ ```bash
35
+ amalgm --version
36
+ amalgm --help
37
+ amalgm automations --help
38
+ amalgm automations list --input '{"limit":1}'
39
+ ```
40
+
41
+ When the user has chosen an account, add `--user` with that actual email to
42
+ Shell commands, including `amalgm automations ...`. An email selects a local
43
+ account; it does not authenticate it. `targetId` selects an execution computer,
44
+ not an account. Never substitute one for the other.
45
+
46
+ A successful Automations response is a JSON `result` envelope; an empty list
47
+ is valid. The six Automations commands use that envelope. Shell's `status`
48
+ returns a different JSON shape; `login` and `run` report progress as text.
49
+
50
+ For a local stdio MCP client, configure this server using the actual selected
51
+ account email (Shell 0.1.176 or newer):
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "amalgm-automations": {
57
+ "command": "amalgm",
58
+ "args": ["automations", "mcp", "--user", "person@example.com"]
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ This is the server entry for clients using `mcpServers` JSON; clients with a
65
+ different configuration format use the same command and arguments. Use the
66
+ exact installed launcher path if the client cannot find `amalgm` on PATH.
67
+ Shell supplies the current local connection on every tool call, including
68
+ after a runtime restart. Do not add credentials or environment variables.
69
+ Listing tools works before login; calling them requires a running signed-in
70
+ runtime. After configuring the client, verify its Automations `list` tool.
71
+
72
+ ## Install only when needed
73
+
74
+ Check for an existing app-managed installation before adding another copy.
75
+ If the desktop app already manages this computer, use its setup/connection
76
+ flow. A missing PATH entry is not proof that Amalgm is uninstalled.
77
+
78
+ On a fresh computer with Node.js and npm, the Shell package supplies the
79
+ global command. Check the published package's requirements before installing:
80
+
81
+ ```bash
82
+ node --version
83
+ npm view @amalgm/shell version engines --json
84
+ npm install --global @amalgm/shell
85
+ amalgm --version
86
+ amalgm automations --help
87
+ ```
88
+
89
+ Do not install `@amalgm/automations` alone as a substitute for Shell: its direct
90
+ CLI/MCP executables do not perform the user's Shell login. Do not change an
91
+ existing app's exact runtime binding or install a second runner to fix a
92
+ version mismatch. If the installed Shell lacks `automations`, report that
93
+ version and use its supported update path; do not invent `amalgm update`.
94
+
95
+ If Node/npm is unavailable or global installation is denied, use
96
+ [Amalgm computer setup](https://amalgm.ai/setup). The person signs in with
97
+ Google and the page supplies the current platform-specific install command.
98
+ That installer includes a private Node runtime and a one-time setup code.
99
+ Execute the command supplied by the trusted setup page when the user has
100
+ authorized connecting this computer. Do not invent a code, run a code-less
101
+ `install.sh`, or use sudo as an automatic workaround. Keep the code private
102
+ to this setup session.
103
+
104
+ The web installer places Shell under
105
+ `~/.amalgm/runtime-packages/shell/<installed-version>/bin/amalgm` on macOS/Linux.
106
+ If it is absent from PATH, use the exact launcher/version identified by the
107
+ installer or app, not whichever version directory happens to sort last.
108
+
109
+ ## Sign in and connect the computer
110
+
111
+ For a first login through the CLI:
112
+
113
+ ```bash
114
+ amalgm login --no-open
115
+ ```
116
+
117
+ Run it in a persistent terminal/process session. Show the **verification URL
118
+ printed by that process** to the user as a clickable link; do not construct
119
+ the URL yourself. Omit `--no-open` only when the command should open the browser
120
+ on the same computer. The approval link and setup code are short-lived setup
121
+ information, not material for logs or support emails.
122
+
123
+ Tell the person: “Continue with Google, choose your Amalgm account, and approve
124
+ connecting this computer. I'll check the connection and continue afterward.”
125
+ Show the computer name when known. The browser owns sign-in and consent; do
126
+ not ask for passwords, provider tokens, or a credit card. Existing accounts
127
+ can use their existing supported sign-in method rather than creating a second
128
+ account just to use Google.
129
+
130
+ Keep that process alive while the person approves. Follow its progress until
131
+ `AMALGM_READY` appears or it reports an error. `login` continues hosting the
132
+ runtime after readiness; it is not expected to exit successfully. Do not kill
133
+ it after approval or use `--exit-after-ready` for real setup.
134
+
135
+ An already approved, unexpired code can be passed to
136
+ `amalgm login --setup-code CODE` if the original waiting process ended. Use
137
+ only the actual code from this setup attempt. If approval expired, finish the
138
+ old attempt and start a fresh login. If the person cancels, stop that attempt;
139
+ do not reopen approval until they choose to continue.
140
+
141
+ ## Reuse or resume a registered computer
142
+
143
+ Discover registered accounts with `amalgm status --all` (Shell 0.1.176+).
144
+ It returns email and registration state only. A sole ready account is selected
145
+ implicitly; multiple ready accounts require `--user`. Once the account email
146
+ is known, inspect it explicitly. Replace the example email below with the
147
+ user's actual selected account:
148
+
149
+ ```bash
150
+ amalgm status --user person@example.com
151
+ ```
152
+
153
+ | Observed state | Next action |
154
+ | --- | --- |
155
+ | `registration: "ready"`, `running: true` | Reuse this runtime; verify Automations access. |
156
+ | `registration: "ready"`, `running: false` | Run `amalgm run --user person@example.com` in a persistent session, then verify. |
157
+ | `registration: "absent"` or `"incomplete"` | Complete the supported login/setup flow for this account; preserve existing registration files. |
158
+ | Shell requests `--user` or lists several accounts | Ask which account to use if it is not already established. Supply that email consistently. |
159
+ | Status fails | Diagnose the actual error; a failed read is not proof that registration is absent. |
160
+
161
+ After login or resume, require both ready/running status and a successful read:
162
+
163
+ ```bash
164
+ amalgm automations list --user person@example.com --input '{"limit":1}'
165
+ ```
166
+
167
+ Then return to the user's original automation request. This proves connection
168
+ and access, not that a future workflow ran or that every executable is installed.
169
+ MCP results can independently prove hosted access, but do not prove the selected
170
+ execution computer is online.
171
+
172
+ Use an existing app/installer-managed background runtime when possible. A
173
+ foreground `login`/`run` process must remain alive for local execution; do not
174
+ promise it survives terminal closure, logout, or reboot without evidence. If
175
+ the agent's process sessions cannot persist, use the app/setup-managed path or
176
+ explain the remaining requirement. An offline target leaves admitted runs
177
+ pending; it does not erase their history.
178
+
179
+ ## Diagnose the failing boundary
180
+
181
+ Read the error's code, message, and status together. Keep automation and run
182
+ ids when available. Try the
183
+ appropriate repair and verify again. If the same failure persists with no new
184
+ evidence, explain it and offer support rather than looping through login,
185
+ reinstallation, or repeated writes.
186
+
187
+ | Failure | What to do |
188
+ | --- | --- |
189
+ | `user_not_registered` or `user_selection_required` | Use `amalgm status --all` to discover local accounts, then select the intended email or complete login for it. |
190
+ | `runtime_unavailable`, connection refused, or Shell says it is not running | Inspect the selected account's status and use the resume/setup decision above. A standalone adapter asking for environment credentials should be replaced by the global `amalgm automations` path. |
191
+ | `runtime_unauthorized` | Retry the read once through the public Shell command, which obtains the current local connection. If it still fails, keep the error for support; never extract or replace tokens manually. |
192
+ | `runtime_transport` or `runtime_protocol` | Check local readiness, connectivity, and the installed version. A timeout or service outage is not evidence that the user needs a new account. |
193
+ | Wrong account, `forbidden`, or a target authorization error | Verify the chosen account and computer. Do not change ownership, guess another target, or treat every 403 as an expired login. |
194
+ | Missing/corrupt device key or an explicit recovery-required error | Explain key recovery and use `amalgm auth recover --user person@example.com` only when the user chooses recovery. It requires its own browser approval. Never delete identity files or silently re-register. After recovery, inspect status and resume if needed. |
195
+ | HTTP 429 or a reported rate limit | Honor a supplied retry delay/reset time and reduce request frequency. Limits are per minute/hour; do not invent numeric allowances or a reset time. If no delay is supplied, back off conservatively with a bounded retry, then report the unresolved limit. Never switch accounts to bypass it. |
196
+ | An installed native agent needs login, or its model/provider rejects work | Use that program/service's own supported login. Amalgm Google sign-in does not sign into Codex, Claude, or other providers. Do not add Amalgm credits as a guessed fix. |
197
+ | Missing executable, failed step, or invalid workflow | Read [workflow diagnoses](workflow-plans.md#common-boundary-diagnoses); repair the actual step/configuration without replacing the automation to hide the failure. |
198
+
199
+ For a failed mutation, inspect existing state before retrying. Reuse the same
200
+ Run Now input and idempotency key after an uncertain response. Preserve a
201
+ returned disabled draft id: get that definition, then repair it with `update`
202
+ instead of retrying `create`. Invalid supplied configuration is rejected
203
+ before any write; a later service failure can still leave a disabled draft.
204
+ A retry must not turn one requested automation or run into several.
205
+
206
+ ## Get support
207
+
208
+ Support is **Aayush, aayush@amalgm.ai**:
209
+ [Email Aayush](mailto:aayush@amalgm.ai?subject=Amalgm%20Automations%20help).
210
+ Offer this as soon as the user asks, or when the supported repair does not
211
+ resolve their problem. They do not need to complete a troubleshooting checklist
212
+ to contact a person.
213
+
214
+ Prepare a short email when helpful:
215
+
216
+ ```text
217
+ To: aayush@amalgm.ai
218
+ Subject: Amalgm Automations — <short problem>
219
+
220
+ I was trying to: <intended result>
221
+ What happened: <failure and approximate time, including timezone>
222
+ Setup: <OS, agent/client, and Amalgm version if available>
223
+ Error: <code/status and a short redacted message>
224
+ Automation/run: <ids or viewing links, if available>
225
+ Already tried: <relevant checks or repair>
226
+ ```
227
+
228
+ Use only relevant evidence. Do not attach raw runtime logs, browser cookies,
229
+ private auth files, setup links/codes, webhook URLs/signing secrets, or the
230
+ user's code, prompts, file paths, and workflow output without reviewing and
231
+ redacting them. Status output can contain private local paths; summarize its
232
+ registration/running fields instead of copying the entire object.
233
+
234
+ Send through an available email tool only if the user has explicitly authorized
235
+ the email; otherwise provide the draft and mail link. Do not invent a support
236
+ ticket, response-time promise, or claim that an email was sent.
@@ -0,0 +1,52 @@
1
+ -- Commit the run and its private wakeup together. Every Fly host observes the
2
+ -- same change; local processes never subscribe with Supabase credentials.
3
+ CREATE OR REPLACE FUNCTION public.notify_amalgm_machine_run()
4
+ RETURNS trigger
5
+ LANGUAGE plpgsql
6
+ SECURITY DEFINER
7
+ SET search_path = ''
8
+ AS $$
9
+ BEGIN
10
+ IF TG_OP = 'UPDATE' AND
11
+ (OLD.status, OLD.retry_at, OLD.lease_expires_at) IS NOT DISTINCT FROM
12
+ (NEW.status, NEW.retry_at, NEW.lease_expires_at) THEN
13
+ RETURN NEW;
14
+ END IF;
15
+ PERFORM realtime.send(
16
+ jsonb_build_object('userId', NEW.user_id, 'targetId', NEW.target_id),
17
+ 'changed', 'amalgm:automations:runs', true
18
+ );
19
+ RETURN NEW;
20
+ END;
21
+ $$;
22
+
23
+ REVOKE ALL ON FUNCTION public.notify_amalgm_machine_run() FROM PUBLIC;
24
+ CREATE TRIGGER amalgm_machine_run_notification
25
+ AFTER INSERT OR UPDATE ON public.amalgm_automation_runs
26
+ FOR EACH ROW EXECUTE FUNCTION public.notify_amalgm_machine_run();
27
+
28
+ -- Remain private even if a different product permits broad authenticated
29
+ -- Broadcast access. service_role is the only subscriber and bypasses RLS.
30
+ CREATE POLICY amalgm_run_notifications_service_only
31
+ ON realtime.messages AS RESTRICTIVE FOR ALL TO PUBLIC
32
+ USING (topic <> 'amalgm:automations:runs')
33
+ WITH CHECK (topic <> 'amalgm:automations:runs');
34
+
35
+ -- Use the database clock, exactly as claim_amalgm_machine_runs does. The host
36
+ -- sleeps until this deadline; no deadline means no work-check timer at all.
37
+ CREATE OR REPLACE FUNCTION public.amalgm_machine_wake_delay(p_user_id uuid, p_target_id text)
38
+ RETURNS double precision
39
+ LANGUAGE sql
40
+ SECURITY DEFINER
41
+ SET search_path = ''
42
+ AS $$
43
+ SELECT CASE WHEN count(*) = 0 THEN NULL ELSE
44
+ greatest(0, ceil(extract(epoch FROM (min(CASE WHEN status = 'pending'
45
+ THEN coalesce(retry_at, now()) ELSE coalesce(lease_expires_at, now()) END) - now())) * 1000))
46
+ END
47
+ FROM public.amalgm_automation_runs
48
+ WHERE user_id = p_user_id AND target_id = p_target_id
49
+ AND status IN ('pending', 'sent', 'running');
50
+ $$;
51
+ REVOKE ALL ON FUNCTION public.amalgm_machine_wake_delay(uuid, text) FROM PUBLIC;
52
+ GRANT EXECUTE ON FUNCTION public.amalgm_machine_wake_delay(uuid, text) TO service_role;
@@ -0,0 +1,4 @@
1
+ -- Supabase can grant EXECUTE directly through schema default privileges;
2
+ -- revoking PUBLIC alone does not remove those explicit grants.
3
+ REVOKE ALL ON FUNCTION public.notify_amalgm_machine_run() FROM anon, authenticated;
4
+ REVOKE ALL ON FUNCTION public.amalgm_machine_wake_delay(uuid, text) FROM anon, authenticated;