@amalgm/automations 0.3.1 → 0.4.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 (34) hide show
  1. package/AXIOMS.md +11 -0
  2. package/PURPOSE.md +18 -0
  3. package/README.md +34 -0
  4. package/dist/host/auth.js +4 -1
  5. package/dist/host/main.js +9 -1
  6. package/dist/host/notifications.d.ts +4 -0
  7. package/dist/host/notifications.js +19 -0
  8. package/dist/host/server.js +46 -7
  9. package/dist/src/cli/run.d.ts +1 -1
  10. package/dist/src/cli/run.js +12 -0
  11. package/dist/src/index.d.ts +1 -0
  12. package/dist/src/index.js +1 -0
  13. package/dist/src/machine-client.d.ts +3 -1
  14. package/dist/src/machine-client.js +6 -0
  15. package/dist/src/machine-event-stream.d.ts +8 -0
  16. package/dist/src/machine-event-stream.js +58 -0
  17. package/dist/src/machine-http.d.ts +2 -0
  18. package/dist/src/machine-http.js +8 -2
  19. package/dist/src/machine-notifications.d.ts +15 -0
  20. package/dist/src/machine-notifications.js +124 -0
  21. package/dist/src/machine.d.ts +1 -0
  22. package/dist/src/runner.d.ts +3 -1
  23. package/dist/src/runner.js +69 -46
  24. package/dist/src/supabase-machine.d.ts +1 -0
  25. package/dist/src/supabase-machine.js +3 -0
  26. package/package.json +2 -1
  27. package/skills/amalgm-automations/SKILL.md +148 -0
  28. package/skills/amalgm-automations/agents/openai.yaml +4 -0
  29. package/skills/amalgm-automations/references/command-contract.md +173 -0
  30. package/skills/amalgm-automations/references/setup-and-support.md +195 -0
  31. package/skills/amalgm-automations/references/workflow-plans.md +152 -0
  32. package/supabase/migrations/20260904020000_machine_run_notifications.sql +52 -0
  33. package/supabase/migrations/20260904030000_machine_notification_permissions.sql +4 -0
  34. package/skills/automations/SKILL.md +0 -141
@@ -0,0 +1,195 @@
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
+ ## Start with the connection you have
9
+
10
+ If Automations MCP already answers `list` with `{"limit":1}`, continue the task.
11
+ Do not require a local CLI for a working remote MCP connection. If that remote
12
+ connection requires authorization, use its actual sign-in/reconnect link. A
13
+ cloud agent cannot repair the user's computer by installing Shell on its own
14
+ temporary machine.
15
+
16
+ For local CLI work, use the existing `amalgm` executable or the exact Shell
17
+ launcher supplied by Amalgm's installer/app. The examples below use `amalgm`
18
+ as shorthand for that executable. Keep the same installation and account
19
+ throughout setup and verification.
20
+
21
+ ```bash
22
+ amalgm --version
23
+ amalgm --help
24
+ amalgm automations --help
25
+ amalgm automations list --input '{"limit":1}'
26
+ ```
27
+
28
+ When the user has chosen an account, add `--user` with that actual email to
29
+ Shell commands, including `amalgm automations ...`. An email selects a local
30
+ account; it does not authenticate it. `targetId` selects an execution computer,
31
+ not an account. Never substitute one for the other.
32
+
33
+ A successful Automations response is a JSON `result` envelope; an empty list
34
+ is valid. The six Automations commands use that envelope. Shell's `status`
35
+ returns a different JSON shape; `login` and `run` report progress as text.
36
+
37
+ ## Install only when needed
38
+
39
+ Check for an existing app-managed installation before adding another copy.
40
+ If the desktop app already manages this computer, use its setup/connection
41
+ flow. A missing PATH entry is not proof that Amalgm is uninstalled.
42
+
43
+ On a fresh computer with Node.js and npm, the Shell package supplies the
44
+ global command. Check the published package's requirements before installing:
45
+
46
+ ```bash
47
+ node --version
48
+ npm view @amalgm/shell version engines --json
49
+ npm install --global @amalgm/shell
50
+ amalgm --version
51
+ amalgm automations --help
52
+ ```
53
+
54
+ Do not install `@amalgm/automations` alone as a substitute for Shell: its direct
55
+ CLI/MCP executables do not perform the user's Shell login. Do not change an
56
+ existing app's exact runtime binding or install a second runner to fix a
57
+ version mismatch. If the installed Shell lacks `automations`, report that
58
+ version and use its supported update path; do not invent `amalgm update`.
59
+
60
+ If Node/npm is unavailable or global installation is denied, use
61
+ [Amalgm computer setup](https://amalgm.ai/setup). The person signs in with
62
+ Google and the page supplies the current platform-specific install command.
63
+ That installer includes a private Node runtime and a one-time setup code.
64
+ Execute the command supplied by the trusted setup page when the user has
65
+ authorized connecting this computer. Do not invent a code, run a code-less
66
+ `install.sh`, or use sudo as an automatic workaround. Keep the code private
67
+ to this setup session.
68
+
69
+ The web installer places Shell under
70
+ `~/.amalgm/runtime-packages/shell/<installed-version>/bin/amalgm` on macOS/Linux.
71
+ If it is absent from PATH, use the exact launcher/version identified by the
72
+ installer or app, not whichever version directory happens to sort last.
73
+
74
+ ## Sign in and connect the computer
75
+
76
+ For a first login through the CLI:
77
+
78
+ ```bash
79
+ amalgm login --no-open
80
+ ```
81
+
82
+ Run it in a persistent terminal/process session. Show the **verification URL
83
+ printed by that process** to the user as a clickable link; do not construct
84
+ the URL yourself. Omit `--no-open` only when the command should open the browser
85
+ on the same computer. The approval link and setup code are short-lived setup
86
+ information, not material for logs or support emails.
87
+
88
+ Tell the person: “Continue with Google, choose your Amalgm account, and approve
89
+ connecting this computer. I'll check the connection and continue afterward.”
90
+ Show the computer name when known. The browser owns sign-in and consent; do
91
+ not ask for passwords, provider tokens, or a credit card. Existing accounts
92
+ can use their existing supported sign-in method rather than creating a second
93
+ account just to use Google.
94
+
95
+ Keep that process alive while the person approves. Follow its progress until
96
+ `AMALGM_READY` appears or it reports an error. `login` continues hosting the
97
+ runtime after readiness; it is not expected to exit successfully. Do not kill
98
+ it after approval or use `--exit-after-ready` for real setup.
99
+
100
+ An already approved, unexpired code can be passed to
101
+ `amalgm login --setup-code CODE` if the original waiting process ended. Use
102
+ only the actual code from this setup attempt. If approval expired, finish the
103
+ old attempt and start a fresh login. If the person cancels, stop that attempt;
104
+ do not reopen approval until they choose to continue.
105
+
106
+ ## Reuse or resume a registered computer
107
+
108
+ Once the account email is known, inspect it explicitly. Replace the example
109
+ email below with the user's actual selected account:
110
+
111
+ ```bash
112
+ amalgm status --user person@example.com
113
+ ```
114
+
115
+ | Observed state | Next action |
116
+ | --- | --- |
117
+ | `registration: "ready"`, `running: true` | Reuse this runtime; verify Automations access. |
118
+ | `registration: "ready"`, `running: false` | Run `amalgm run --user person@example.com` in a persistent session, then verify. |
119
+ | `registration: "absent"` or `"incomplete"` | Complete the supported login/setup flow for this account; preserve existing registration files. |
120
+ | Shell requests `--user` or lists several accounts | Ask which account to use if it is not already established. Supply that email consistently. |
121
+ | Status fails | Diagnose the actual error; a failed read is not proof that registration is absent. |
122
+
123
+ After login or resume, require both ready/running status and a successful read:
124
+
125
+ ```bash
126
+ amalgm automations list --user person@example.com --input '{"limit":1}'
127
+ ```
128
+
129
+ Then return to the user's original automation request. This proves connection
130
+ and access, not that a future workflow ran or that every executable is installed.
131
+ MCP results can independently prove hosted access, but do not prove the selected
132
+ execution computer is online.
133
+
134
+ Use an existing app/installer-managed background runtime when possible. A
135
+ foreground `login`/`run` process must remain alive for local execution; do not
136
+ promise it survives terminal closure, logout, or reboot without evidence. If
137
+ the agent's process sessions cannot persist, use the app/setup-managed path or
138
+ explain the remaining requirement. An offline target leaves admitted runs
139
+ pending; it does not erase their history.
140
+
141
+ ## Diagnose the failing boundary
142
+
143
+ Read the error's code, message, and status together; some Shell failures are
144
+ wrapped as `internal`. Keep automation and run ids when available. Try the
145
+ appropriate repair and verify again. If the same failure persists with no new
146
+ evidence, explain it and offer support rather than looping through login,
147
+ reinstallation, or repeated writes.
148
+
149
+ | Failure | What to do |
150
+ | --- | --- |
151
+ | `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. |
152
+ | `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. |
153
+ | `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. |
154
+ | 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. |
155
+ | 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. |
156
+ | 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. |
157
+ | 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. |
158
+ | 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. |
159
+
160
+ For a failed mutation, inspect existing state before retrying. Reuse the same
161
+ Run Now input and idempotency key after an uncertain response. Preserve a
162
+ returned disabled draft id. A retry must not turn one requested automation or
163
+ run into several.
164
+
165
+ ## Get support
166
+
167
+ Support is **Aayush, aayush@amalgm.ai**:
168
+ [Email Aayush](mailto:aayush@amalgm.ai?subject=Amalgm%20Automations%20help).
169
+ Offer this as soon as the user asks, or when the supported repair does not
170
+ resolve their problem. They do not need to complete a troubleshooting checklist
171
+ to contact a person.
172
+
173
+ Prepare a short email when helpful:
174
+
175
+ ```text
176
+ To: aayush@amalgm.ai
177
+ Subject: Amalgm Automations — <short problem>
178
+
179
+ I was trying to: <intended result>
180
+ What happened: <failure and approximate time, including timezone>
181
+ Setup: <OS, agent/client, and Amalgm version if available>
182
+ Error: <code/status and a short redacted message>
183
+ Automation/run: <ids or viewing links, if available>
184
+ Already tried: <relevant checks or repair>
185
+ ```
186
+
187
+ Use only relevant evidence. Do not attach raw runtime logs, browser cookies,
188
+ private auth files, setup links/codes, webhook URLs/signing secrets, or the
189
+ user's code, prompts, file paths, and workflow output without reviewing and
190
+ redacting them. Status output can contain private local paths; summarize its
191
+ registration/running fields instead of copying the entire object.
192
+
193
+ Send through an available email tool only if the user has explicitly authorized
194
+ the email; otherwise provide the draft and mail link. Do not invent a support
195
+ ticket, response-time promise, or claim that an email was sent.
@@ -0,0 +1,152 @@
1
+ # Workflow plans
2
+
3
+ The compiled plan is an immutable, ordered snapshot when a run is admitted.
4
+ Step ids must be unique and the plan must contain 1–100 steps.
5
+
6
+ ## Step forms
7
+
8
+ Version 1 accepts action steps only:
9
+
10
+ ```json
11
+ {
12
+ "version": 1,
13
+ "steps": [{
14
+ "id": "notify",
15
+ "actionId": "channels.notify_user",
16
+ "input": {"title":"Reminder","message":"Call Mom"}
17
+ }]
18
+ }
19
+ ```
20
+
21
+ Version 2 accepts any ordered mix of these three forms:
22
+
23
+ ```text
24
+ Amalgm action
25
+ { id, actionId, input }
26
+
27
+ Native command
28
+ { id, kind:"command", command, args?, cwd?, env?, stdin?,
29
+ timeoutMs?, maxOutputBytes? }
30
+
31
+ Code script
32
+ { id, kind:"script", runtime:"shell"|"node"|"python", source,
33
+ args?, cwd?, env?, stdin?, timeoutMs?, maxOutputBytes? }
34
+ ```
35
+
36
+ `id`, `actionId`, `command`, every `args` element, environment keys and values,
37
+ and `runtime` are strings. `timeoutMs` and `maxOutputBytes` are positive
38
+ integers. `cwd` is optional but must be absolute when present.
39
+
40
+ ## Amalgm actions and agents
41
+
42
+ Action steps run through the selected machine's installed Amalgm Tools/action
43
+ catalog. Discover an action before using it. Do not derive action ids from MCP
44
+ tool names.
45
+
46
+ The Amalgm-agent action is distinct from a native CLI agent:
47
+
48
+ ```json
49
+ {
50
+ "id": "review-with-amalgm-agent",
51
+ "actionId": "chat.chat_agent_run",
52
+ "input": {
53
+ "agent_installation_id": "configured-installation-id",
54
+ "message": "Review this occurrence.",
55
+ "context": {"$runInput":true}
56
+ }
57
+ }
58
+ ```
59
+
60
+ The installation must exist and declare a usable model/provider binding. Do
61
+ not guess an installation id from an adapter name such as `codex`.
62
+
63
+ ## Native CLI agents
64
+
65
+ Use a command step for the user's independently installed CLI:
66
+
67
+ ```json
68
+ {
69
+ "id": "native-codex-review",
70
+ "kind": "command",
71
+ "command": "codex",
72
+ "args": ["exec", "Review this repository and write REVIEW.md"],
73
+ "cwd": "/Users/me/src/project",
74
+ "timeoutMs": 1800000,
75
+ "maxOutputBytes": 1048576
76
+ }
77
+ ```
78
+
79
+ The executable is resolved from the target machine's PATH and uses its own
80
+ user-level login. Args are passed directly with `shell:false`; `$HOME`, pipes,
81
+ redirection, globbing, and quoting syntax are literal arguments. If shell
82
+ syntax is intended, choose the script lane explicitly.
83
+
84
+ Equivalent installed programs such as `claude -p ...` or `opencode ...` use
85
+ the same command form. Their accepted args and authentication belong to those
86
+ programs, not Automations.
87
+
88
+ ## Scripts
89
+
90
+ Scripts persist source in the workflow and execute through a temporary file on
91
+ the selected machine. The temporary file is removed after execution.
92
+
93
+ ```json
94
+ {
95
+ "id": "process-event",
96
+ "kind": "script",
97
+ "runtime": "node",
98
+ "source": "let s=''; process.stdin.on('data', c => s += c).on('end', () => console.log(JSON.parse(s)));",
99
+ "cwd": "/absolute/project",
100
+ "stdin": {"$runInput":true},
101
+ "env": {"MODE":"automation"},
102
+ "timeoutMs": 30000,
103
+ "maxOutputBytes": 262144
104
+ }
105
+ ```
106
+
107
+ Use `runtime:"shell"` for POSIX shell semantics on Unix and PowerShell file
108
+ execution on Windows. Use `node` or `python` for explicit code in those
109
+ runtimes. Account for target-machine portability when selecting a runtime or
110
+ absolute path.
111
+
112
+ ## Run input
113
+
114
+ The exact singleton object below is the only template marker:
115
+
116
+ ```json
117
+ {"$runInput":true}
118
+ ```
119
+
120
+ It resolves recursively inside action `input`. In process steps it may be used
121
+ as `stdin`; strings are passed verbatim and other JSON values are serialized
122
+ with a trailing newline. Trigger payloads are never ambient.
123
+
124
+ ## Execution and retries
125
+
126
+ Each step is recorded as running before its effect and committed as completed
127
+ before the next step begins. Completed steps are skipped after reconnect.
128
+
129
+ Every run-step pair receives the stable key `<run-id>:<step-id>`. Process steps
130
+ receive it as `AMALGM_AUTOMATION_IDEMPOTENCY_KEY`. Shell's private runtime,
131
+ tunnel, device, and machine credentials are stripped from child environments.
132
+
133
+ An uncertain machine crash can repeat the current effect. Amalgm actions can
134
+ deduplicate the step key; an arbitrary command or script is at-least-once and
135
+ must durably deduplicate that environment value when exactly-once effects are
136
+ required.
137
+
138
+ Process output records exit code, signal, stdout, stderr, and whether capture
139
+ was truncated. Timeouts, cancellation, and output bounds are enforced on the
140
+ machine. The durable journal compacts oversized results rather than allowing
141
+ large output to strand the run update.
142
+
143
+ ## Common boundary diagnoses
144
+
145
+ - `process_execution_unavailable`: selected machine host lacks process support.
146
+ - Spawn/not-found error: executable or runtime is absent from that machine PATH.
147
+ - Nonzero exit: inspect bounded stdout/stderr; the automation correctly failed.
148
+ - Timeout: adjust only when the intended command legitimately needs longer.
149
+ - `Installed agent has no model`: select or configure an actual Amalgm agent
150
+ installation with a model; this is not a native CLI-auth failure.
151
+ - Action-specific HTTP/authorization error: verify that action's owning service
152
+ and input contract without changing Run Now semantics.
@@ -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;
@@ -1,141 +0,0 @@
1
- ---
2
- name: automations
3
- description: Create, inspect, change, delete, or manually run complete Amalgm automation definitions and inspect their run history through the Automations MCP tools.
4
- ---
5
-
6
- # Amalgm Automations
7
-
8
- Use the Automations tools for scheduled or webhook-driven work. The tools are
9
- the agent adapter over the same hosted SDK used by the UI.
10
-
11
- When MCP is unavailable but the authenticated Amalgm Shell CLI is available,
12
- use the command with the matching suffix (`create`, `list`, `get`, `update`,
13
- `delete`, or `run-now`). Pass the exact MCP input object as JSON, preferably on
14
- stdin when it contains a provider secret:
15
-
16
- ```bash
17
- printf '%s\n' '{"name":"Call Mom","schedules":[{"cron":"* * * * *","timezone":"America/Los_Angeles","maxOccurrences":10}],"workflow":{"script":"Notify me to call Mom.","compiled":{"version":1,"steps":[{"id":"notify","actionId":"channels.notify_user","input":{"title":"Reminder","message":"Call Mom"}}]}}}' \
18
- | amalgm automations create --stdin
19
- ```
20
-
21
- The CLI returns `{ "result": ... }` on stdout or a structured `error` object
22
- on stderr with a nonzero exit. It has no separate low-level trigger or workflow
23
- commands; complete definitions and grouped changes use the same task-level
24
- surface as MCP.
25
-
26
- The CLI is global. Its current directory does not scope or modify the
27
- automation. Process location belongs in an absolute workflow-step `cwd`; when
28
- it is omitted, Shell uses the selected machine user's OS home.
29
-
30
- ## Choose the execution lane deliberately
31
-
32
- Use exactly one of these shapes for each compiled workflow step:
33
-
34
- Version 1 remains action-only. Use plan version 2 for every workflow containing
35
- a native command or code script; version 2 may mix all three lanes.
36
-
37
- - **Amalgm action** — `{ "id", "actionId", "input" }`. Use this for Amalgm
38
- tools, Channels, or the Amalgm agent path. `chat.chat_agent_run` is an Amalgm
39
- agent, not the user's native CLI agent.
40
- - **Native command** — `{ "id", "kind":"command", "command", "args"?,
41
- "cwd"?, "env"?, "stdin"?, "timeoutMs"?, "maxOutputBytes"? }`. Use this for
42
- installed executables such as `codex exec`, `claude -p`, `opencode`, or a
43
- script file. Args are literal argv and never pass through a shell.
44
- - **Code script** — `{ "id", "kind":"script", "runtime":"shell"|"node"|
45
- "python", "source", "args"?, "cwd"?, "env"?, "stdin"?, "timeoutMs"?,
46
- "maxOutputBytes"? }`. Use this only when inline code or shell semantics are
47
- desired explicitly.
48
-
49
- For a native Codex run on the selected machine:
50
-
51
- ```json
52
- {
53
- "version": 2,
54
- "steps": [{
55
- "id": "native-review",
56
- "kind": "command",
57
- "command": "codex",
58
- "args": ["exec", "Review this repository and write REVIEW.md"],
59
- "cwd": "/absolute/path/to/repository",
60
- "timeoutMs": 1800000
61
- }]
62
- }
63
- ```
64
-
65
- Installed CLI authentication comes from that CLI's own user setup on the
66
- selected machine. Never put Shell runtime, tunnel, or machine credentials in a
67
- workflow. `env` is persisted ordinary configuration, not a secret store.
68
- Process results and bounded stdout/stderr appear in run history. A native
69
- process may repeat after an uncertain machine crash; it receives
70
- `AMALGM_AUTOMATION_IDEMPOTENCY_KEY` for durable deduplication when needed.
71
-
72
- ## Create a scheduled notification
73
-
74
- For a request such as “remind me to call my mom every minute for the next ten
75
- minutes,” make one `amalgm_automations_create` call containing the complete
76
- definition. Include a readable workflow summary and this compiled plan:
77
-
78
- ```json
79
- {
80
- "version": 1,
81
- "steps": [
82
- {
83
- "id": "notify",
84
- "actionId": "channels.notify_user",
85
- "input": { "title": "Reminder", "message": "Call Mom" }
86
- }
87
- ]
88
- }
89
- ```
90
-
91
- Include one schedule with cron `* * * * *`, the user's timezone, and
92
- `maxOccurrences: 10`. Omit `targetId` in a machine-bound session; never guess
93
- an opaque target id.
94
-
95
- The tool stages multi-resource configuration disabled and enables it only after
96
- setup succeeds. If setup fails, report the returned disabled draft id. Never
97
- replace a bounded occurrence count with an unbounded schedule plus a promise to
98
- clean it up later.
99
-
100
- ## Read and change
101
-
102
- Use `amalgm_automations_list` or `amalgm_automations_get` before changing an
103
- existing automation. Use `amalgm_automations_update` for grouped metadata,
104
- schedule, webhook, or workflow changes, and `amalgm_automations_delete` only
105
- after identifying the exact automation. Schedule and webhook triggers remain
106
- distinct resources inside the definition. A workflow is zero-or-one per
107
- automation. Run history is read-only, requested through `get`, and remains
108
- after configuration deletion.
109
-
110
- Use `amalgm_automations_run_now` when the user wants an enabled automation to
111
- run immediately. Supply `idempotency_key` when a caller may retry the same
112
- request. The result is a durable `pending` run, not proof that its selected
113
- machine has finished it; use `amalgm_automations_get` with run history when the
114
- user asks for the outcome.
115
-
116
- Amalgm action discovery belongs to the Tools product. Native command discovery
117
- belongs to the selected machine's PATH and installed user environment.
118
-
119
- For webhook-driven work, pass the admitted provider payload into an action or
120
- process by placing the exact value `{ "$runInput": true }` at the desired point
121
- in action `input` or process `stdin`. For example, an agent-review action can
122
- use a static `message` and set `context` to `{ "$runInput": true }`. Never paste
123
- an example delivery into the workflow: every admitted run must use its own
124
- durable input.
125
-
126
- `pending` means a run is durable and waiting for its selected machine. `sent`
127
- or `running` means that machine holds a lease. `completed` and `failed` are
128
- terminal. Do not infer delivery from the schedule alone; inspect runs when the
129
- user asks whether it actually happened.
130
-
131
- Each webhook trigger returns one copyable `webhookUrl`; use that URL as the
132
- provider destination. A separate provider signing secret is optional and
133
- write-only. Never echo, log, or place either credential in a workflow. Rotate
134
- the URL when its bearer capability may have been exposed.
135
-
136
- For GitHub, register the returned URL as a repository webhook with JSON content
137
- type and select only the requested events (normally `push`). If a provider
138
- secret was configured on the trigger, use the same value as GitHub's webhook
139
- secret. Creating the Amalgm trigger does not silently mutate GitHub; finish the
140
- provider registration in the authenticated GitHub surface available to the
141
- agent, then report both sides as configured.