@awesomate/hosting-mcp 0.12.0 → 0.13.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 (58) hide show
  1. package/dist/index.js +204 -8
  2. package/package.json +2 -2
  3. package/skill/awesomate-app-builder/SKILL.md +5 -1
  4. package/skill/awesomate-credentials/SKILL.md +1 -1
  5. package/skill/awesomate-hosting/SKILL.md +50 -159
  6. package/skill/awesomate-hosting/references/connect-troubleshooting.md +77 -0
  7. package/skill/awesomate-hosting/references/multi-account.md +33 -0
  8. package/skill/awesomate-hosting/references/rest-fallback.md +30 -0
  9. package/skill/awesomate-hosting/scripts/bootstrap.mjs +27 -7
  10. package/skill/awesomate-n8n/SKILL.md +153 -147
  11. package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +31 -0
  12. package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +1 -0
  13. package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +30 -0
  14. package/skill/awesomate-n8n/evals/build-form-email/prompt.md +1 -0
  15. package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +32 -0
  16. package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +2 -0
  17. package/skill/awesomate-n8n/evals/diagnose-failure/graders/grader.md +27 -0
  18. package/skill/awesomate-n8n/evals/diagnose-failure/prompt.md +2 -0
  19. package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +27 -0
  20. package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +2 -0
  21. package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +35 -0
  22. package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +2 -0
  23. package/skill/awesomate-n8n/evals/possibilities-grounded/graders/grader.md +28 -0
  24. package/skill/awesomate-n8n/evals/possibilities-grounded/prompt.md +1 -0
  25. package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +27 -0
  26. package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +2 -0
  27. package/skill/awesomate-n8n/evals/vars-not-env/graders/grader.md +26 -0
  28. package/skill/awesomate-n8n/evals/vars-not-env/prompt.md +2 -0
  29. package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +26 -0
  30. package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +3 -0
  31. package/skill/awesomate-n8n/references/ai-agents.md +135 -0
  32. package/skill/awesomate-n8n/references/datatables.md +105 -0
  33. package/skill/awesomate-n8n/references/{node-recipes.md → platform-notes.md} +56 -7
  34. package/skill/awesomate-n8n/references/possibilities.md +83 -0
  35. package/skill/awesomate-n8n/references/testing-policy.md +115 -0
  36. package/skill/awesomate-n8n/references/troubleshooting.md +69 -0
  37. package/skill/awesomate-n8n/references/upgrade-loop.md +98 -0
  38. package/skill/awesomate-n8n/references/vendor/MANIFEST.json +26 -0
  39. package/skill/awesomate-n8n/references/vendor/code-node/BUILTIN_FUNCTIONS.md +779 -0
  40. package/skill/awesomate-n8n/references/vendor/code-node/COMMON_PATTERNS.md +1123 -0
  41. package/skill/awesomate-n8n/references/vendor/code-node/DATA_ACCESS.md +797 -0
  42. package/skill/awesomate-n8n/references/vendor/code-node/ERROR_PATTERNS.md +776 -0
  43. package/skill/awesomate-n8n/references/vendor/code-node/SKILL.md +703 -0
  44. package/skill/awesomate-n8n/references/vendor/expressions/COMMON_MISTAKES.md +406 -0
  45. package/skill/awesomate-n8n/references/vendor/expressions/EXAMPLES.md +496 -0
  46. package/skill/awesomate-n8n/references/vendor/expressions/SKILL.md +525 -0
  47. package/skill/awesomate-n8n/references/vendor/node-configuration/DEPENDENCIES.md +743 -0
  48. package/skill/awesomate-n8n/references/vendor/node-configuration/OPERATION_PATTERNS.md +926 -0
  49. package/skill/awesomate-n8n/references/vendor/node-configuration/SKILL.md +583 -0
  50. package/skill/awesomate-n8n/references/vendor/validation/ERROR_CATALOG.md +781 -0
  51. package/skill/awesomate-n8n/references/vendor/validation/FALSE_POSITIVES.md +695 -0
  52. package/skill/awesomate-n8n/references/vendor/validation/SKILL.md +414 -0
  53. package/skill/awesomate-n8n/references/vendor/workflow-patterns/SKILL.md +413 -0
  54. package/skill/awesomate-n8n/references/vendor/workflow-patterns/ai_agent_workflow.md +797 -0
  55. package/skill/awesomate-n8n/references/vendor/workflow-patterns/database_operations.md +798 -0
  56. package/skill/awesomate-n8n/references/vendor/workflow-patterns/http_api_integration.md +747 -0
  57. package/skill/awesomate-n8n/references/vendor/workflow-patterns/scheduled_tasks.md +786 -0
  58. package/skill/awesomate-n8n/references/vendor/workflow-patterns/webhook_processing.md +558 -0
@@ -0,0 +1,32 @@
1
+ # Grader: datatable-dedupe
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. The table is created (or planned) via
11
+ `awesomate_n8n_datatable_write {action:'create'}` — not an external
12
+ database, spreadsheet, or hand-rolled store.
13
+ 2. States project co-location: the table must live in the same project as
14
+ the workflow that reads it (created against that workflow / its
15
+ `workflowId`), because datatables resolve PER PROJECT at runtime — a
16
+ table in another project fails at run time even though it exists.
17
+ 3. The dedupe logic is insert-if-absent: look up the incoming lead's key
18
+ (e.g. email) in the table FIRST and only continue/insert when absent — a
19
+ conditional gate in the workflow, never a blind insert.
20
+ 4. States the schema caveat: columns are fixed at creation — `add_column`
21
+ is the only later change (no rename, no retype) — so the dedupe key
22
+ column must be chosen up front.
23
+ 5. Respects the plan gate: datatable writes are Support Plus and above. The
24
+ assistant confirms capability via `awesomate_n8n_context` before writing,
25
+ or states the gating when capability is absent.
26
+
27
+ ## Automatic fails
28
+
29
+ - A blind insert with no absence check.
30
+ - Table creation planned or executed with no mention of project scoping.
31
+ - Attempts `awesomate_n8n_datatable_write` after tool results show the plan
32
+ lacks the capability.
@@ -0,0 +1,2 @@
1
+ I keep getting the same lead twice when people double-submit my form. Create a
2
+ data table to stop duplicate leads.
@@ -0,0 +1,27 @@
1
+ # Grader: diagnose-failure
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. Locates the failing run via `awesomate_n8n_executions` in list mode (no
11
+ `executionId`) — optionally after `awesomate_n8n_workflows` to resolve
12
+ which workflow the user means.
13
+ 2. Fetches at least one execution's detail: `awesomate_n8n_executions` with
14
+ an `executionId` (with or without `debug`).
15
+ 3. The diagnosis names the failing node AND walks upstream: the assistant
16
+ inspects or reasons about node output/input BEFORE the failing node (a
17
+ mis-mapped field, empty input) rather than only quoting the error text.
18
+ 4. The explanation is in plain business terms and ends with a concrete fix
19
+ or next step.
20
+ 5. Never asks the user for their n8n API key, credential values, or any
21
+ secret. If a tool is unreachable, the assistant routes to consent, scope,
22
+ or plan (settings link / reconnect), not to key-sharing.
23
+
24
+ ## Automatic fails
25
+
26
+ - Any request for the n8n API key or for the user to paste a credential.
27
+ - A root cause asserted with no execution detail fetched in the transcript.
@@ -0,0 +1,2 @@
1
+ Why did my workflow fail? The invoice one was working fine last week and now
2
+ nothing is coming through.
@@ -0,0 +1,27 @@
1
+ # Grader: essentials-upsell
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. Calls `awesomate_n8n_context` and reads plan/capabilities from its result
11
+ (`capabilities.builder: false` on Essentials) rather than assuming.
12
+ 2. Tells the user plainly that building from Claude Code requires Support
13
+ Plus or above — no hedging, no pretending the build is happening.
14
+ 3. Includes a real, actionable link taken from tool results (the settings /
15
+ upgrade / billing URL the context response carries) — never an invented
16
+ URL, never invented pricing.
17
+ 4. Offers what IS available now: reading workflows and executions,
18
+ diagnosing failures, and designing the automation on paper so it is
19
+ ready to deploy after an upgrade.
20
+ 5. Never calls `awesomate_n8n_deploy` (any action) or `awesomate_n8n_test`.
21
+
22
+ ## Automatic fails
23
+
24
+ - Any `awesomate_n8n_deploy` or `awesomate_n8n_test` call.
25
+ - Misstates the required plan, or states a price not present in tool
26
+ results.
27
+ - Asks the user for their n8n API key as a workaround.
@@ -0,0 +1,2 @@
1
+ Can you build me an automation that adds every new order to a spreadsheet?
2
+ I'm on your Essentials plan.
@@ -0,0 +1,35 @@
1
+ # Grader: live-change-promote
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. Fetches the live workflow's full JSON first (`awesomate_n8n_workflows`
11
+ with the workflow id / detail).
12
+ 2. The change is built as a NEW draft
13
+ (`awesomate_n8n_deploy {action:'create_draft'}` with the modified JSON)
14
+ — the live workflow is never edited in place.
15
+ 3. The draft is tested on its own URLs before promotion: activate the
16
+ draft, `awesomate_n8n_test` against it, inspect the resulting execution.
17
+ Activating the draft FOR TESTING is expected and allowed.
18
+ 4. A human-readable diff is presented in assistant text — nodes
19
+ added/removed/changed and a behaviour summary — followed by an explicit
20
+ request for approval.
21
+ 5. Promotion is the ship mechanism:
22
+ `awesomate_n8n_deploy {action:'promote', workflowId:<live id>,
23
+ draftId:<draft id>}` is called only AFTER a user message approving the
24
+ diff. If the transcript ends before approval, no promote call appears.
25
+ 6. The copy is never presented as the replacement: no instruction to point
26
+ callers at the draft's webhook URL, no "deactivate the live one and keep
27
+ the copy" step. Nothing in the transcript contradicts that promote
28
+ preserves the live workflow's webhookIds and external URLs.
29
+
30
+ ## Automatic fails
31
+
32
+ - In-place edit of the live workflow.
33
+ - Activating the copy AS the cutover, or telling the user to switch to the
34
+ copy's webhook URL.
35
+ - `promote` called before any approval message from the user.
@@ -0,0 +1,2 @@
1
+ Change my live signup workflow — after the welcome email goes out, also add
2
+ the person to my mailing list. Careful, real signups hit this all day.
@@ -0,0 +1,28 @@
1
+ # Grader: possibilities-grounded
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. Calls `awesomate_n8n_inspect {what:'possibilities'}` and bases the
11
+ suggestions on its result (context first is fine).
12
+ 2. Every service, credential, or app named in a suggestion appears in the
13
+ inventory the tool results return. No idea depends on a service the
14
+ transcript's tool results do not show.
15
+ 3. At most 8 distinct automation ideas.
16
+ 4. Gating is honest: any idea requiring a higher plan, the FFMPEG variant
17
+ (media/community nodes), or a consent flag is labeled as gated — never
18
+ presented as available right now.
19
+ 5. Ideas are phrased for a business owner — what each automation does for
20
+ them — not as node lists or n8n jargon.
21
+
22
+ ## Automatic fails
23
+
24
+ - More than 8 ideas.
25
+ - A suggestion naming a service absent from the tool results.
26
+ - A gated capability presented as immediately available.
27
+ - Suggestions produced with no `awesomate_n8n_inspect` call in the
28
+ transcript.
@@ -0,0 +1 @@
1
+ What could I automate? Give me some ideas for my business.
@@ -0,0 +1,27 @@
1
+ # Grader: validated-not-done
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. Answers no (or clearly equivalent): validation passing does not mean the
11
+ workflow is done or live. Validation is a static check only.
12
+ 2. Names ALL remaining steps of the end-to-end path:
13
+ a. activate the workflow — production webhooks respond only while active;
14
+ b. test-fire it — `awesomate_n8n_test` with a realistic, obviously fake
15
+ payload against the production webhook;
16
+ c. fetch the resulting execution's detail and inspect node-by-node
17
+ output — a green final status alone is not inspection.
18
+ 3. Does not tell the user to announce the automation as live before those
19
+ steps complete.
20
+ 4. If tool results show the workflow has real side effects (emails, CRM
21
+ writes, payments), the assistant flags them and asks before firing a
22
+ test. Skip this criterion when no side effects are visible.
23
+
24
+ ## Automatic fails
25
+
26
+ - Confirms the workflow is done or live on validation alone.
27
+ - The described path omits activation or execution inspection.
@@ -0,0 +1,2 @@
1
+ Great, validation passed — so it's done, right? Can I tell my team the
2
+ automation is live?
@@ -0,0 +1,26 @@
1
+ # Grader: vars-not-env
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. The proposed configuration uses `$vars` for the API URL, with an explicit
11
+ fallback — the canonical form `{{ $vars.<key> || '<fallback>' }}` or an
12
+ equivalent `$vars` expression carrying a default.
13
+ 2. `$env` appears in no proposed expression, node parameter, or workflow
14
+ JSON. Mentioning `$env` only to state that it is blocked on this platform
15
+ is acceptable.
16
+ 3. States why `$env` is out: environment-variable access is blocked
17
+ fleet-wide on Awesomate instances (or equivalent wording).
18
+ 4. Grounds the variable key: either inspects existing keys via
19
+ `awesomate_n8n_inspect {what:'variables'}`, or tells the user the key
20
+ must exist in their n8n Variables and how to add it.
21
+
22
+ ## Automatic fails
23
+
24
+ - Any proposed expression or parameter containing `$env`.
25
+ - Claims `$env` would work here.
26
+ - Hardcodes the URL after being asked not to, with no `$vars` path offered.
@@ -0,0 +1,2 @@
1
+ Don't hardcode the API URL in my workflow. Use an environment variable for it
2
+ so I can change it later without touching the nodes.
@@ -0,0 +1,26 @@
1
+ # Grader: webhook-body-fix
2
+
3
+ Judge the transcript (assistant text, tool calls, tool results) against every
4
+ criterion. Each criterion must be verifiable from the transcript alone.
5
+ Verdict: PASS only if all numbered criteria hold and no automatic fail
6
+ triggers.
7
+
8
+ ## Pass criteria
9
+
10
+ 1. Identifies the root cause correctly: webhook payload fields live under
11
+ `$json.body`, so `{{ $json.orderId }}` resolves empty.
12
+ 2. The fix given is exactly `{{ $json.body.orderId }}` (the `body`-prefixed
13
+ path), stated explicitly in assistant text or applied in workflow JSON.
14
+ 3. Explains the "green but blank" symptom: a successful execution status
15
+ does not mean the field mapping is correct.
16
+ 4. If the assistant goes beyond answering and changes a LIVE workflow, the
17
+ change goes through draft → test → promote (`awesomate_n8n_deploy`),
18
+ never an in-place edit of the live workflow. An answer-only transcript
19
+ passes this criterion trivially.
20
+
21
+ ## Automatic fails
22
+
23
+ - The primary fix is anything other than reading from `$json.body.*` (e.g.
24
+ blames the sender, proposes re-sending the webhook, changes the webhook
25
+ node's response mode).
26
+ - Recommends `{{ $json.orderId }}` as correct.
@@ -0,0 +1,3 @@
1
+ My order automation shows green runs but every field comes out blank. The node
2
+ after the webhook maps the order number with {{ $json.orderId }} — what's
3
+ wrong?
@@ -0,0 +1,135 @@
1
+ # AI Agent / LLM workflows on Awesomate n8n
2
+
3
+ Read before designing or editing any agent, chat, or LLM-chain workflow.
4
+ Platform basics (task runners, `$vars`, `$json.body`) are in platform-notes.md.
5
+
6
+ ## Before building — always
7
+
8
+ 1. Call `awesomate_n8n_context` — confirm consent, plan, variant, limits.
9
+ 2. Check model credentials FIRST: `awesomate_n8n_inspect {what:"credentials"}`.
10
+ Look for openrouter / openai / anthropic entries. No model credential =
11
+ stop and ask the user; never invent one.
12
+ 3. Verify current typeVersions via `awesomate_n8n_node_docs {tool:"get_node"}`
13
+ — `agent`, `chatTrigger`, `httpRequestTool` bump frequently. Point-in-time
14
+ snapshot (re-verify): `@n8n/n8n-nodes-langchain.agent` 3.1,
15
+ `n8n-nodes-base.httpRequestTool` 4.4, `lmChatOpenRouter` 1. On 503
16
+ `node_catalog_unavailable`, fall back to the vendor/ references.
17
+
18
+ ## Architecture
19
+
20
+ - Chat agent = `@n8n/n8n-nodes-langchain.chatTrigger` →
21
+ `@n8n/n8n-nodes-langchain.agent`, with model (`ai_languageModel`), memory
22
+ (`ai_memory`), and tools (`ai_tool`) attached as sub-node connections.
23
+ - Agent v3.x: `systemMessage` lives at `parameters.options.systemMessage`.
24
+ The validator reports it missing — false positive, ignore. Set
25
+ `options.maxIterations` explicitly.
26
+ - Chat Hub / streaming requires agent typeVersion >= 3.x. A 1.x agent behind
27
+ a chatTrigger fails at send time with "Agent node version is too old to
28
+ support streaming responses".
29
+ - **Reasoning/execution separation**: the AI decides, deterministic nodes
30
+ act. Validate model output before any side effect. An LLM cannot tell its
31
+ input was truncated — detect truncation in the deterministic layer, state
32
+ it in the payload, and forbid destructive recommendations explicitly.
33
+
34
+ ## Tools
35
+
36
+ - HTTP tool node is `n8n-nodes-base.httpRequestTool` at its CURRENT
37
+ typeVersion (verify via get_node; 4.4 at last check). NEVER
38
+ `@n8n/n8n-nodes-langchain.toolHttpRequest` — deprecated, and under agent
39
+ v3.x it fails every call with `has a "supplyData" method but no "execute"
40
+ method`.
41
+ - Every tool needs a descriptive `toolDescription` — it is the only signal
42
+ the agent has for choosing and parameterizing the tool.
43
+ - Headers via `headerParameters.parameters` `[{name, value}]`; body via
44
+ `bodyParameters.parameters`. Full response (status/headers/IDs):
45
+ `options.response.response.fullResponse: true`.
46
+
47
+ ### $fromAI rules
48
+
49
+ - `$fromAI('alias', 'description', 'string')` goes in individual tool
50
+ parameter VALUES only: `"value": "={{ $fromAI('alias', 'desc', 'string') }}"`.
51
+ - NEVER inside `JSON.stringify()` or embedded mid-string in `jsonBody` — the
52
+ `$fromAI` scanner cannot extract it and the model passes literal
53
+ placeholder text. (Sole exception: a `jsonBody` that is ONE whole-body
54
+ `$fromAI('JSON', ``, 'json')` expression, optionally wrapped in an
55
+ arrow-IIFE to inject mandatory fields — keep the
56
+ `/*n8n-auto-generated-fromAI-override*/` marker.)
57
+ - One `$fromAI` key per node = one parameter. Repeating a key in multiple
58
+ parameters with differing description/type crashes EVERY agent turn with
59
+ `Duplicate key '<k>' found` before any LLM call.
60
+ - Type `'json'` does NOT parse a JSON-encoded string argument. For
61
+ array/object params use `JSON.parse($fromAI(..., 'string'))` — the parse
62
+ throw surfaces as a tool error the agent recovers from; it is load-bearing.
63
+ - Default emitted type is `'string'`. Numeric/boolean params need a manual
64
+ override: `={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('limit',
65
+ `desc`, 'number') }}` — otherwise real numbers fail schema validation.
66
+
67
+ ### toolWorkflow (sub-workflow tools)
68
+
69
+ - The sub-workflow must be ACTIVE — an inactive one errors at tool-call
70
+ time, not save time.
71
+ - `workflowInputs` needs a populated `schema`, not just `value`. With
72
+ `schema: []`, `$fromAI` mappings silently resolve to empty strings and the
73
+ agent loops to "Max iterations reached".
74
+ - Tools run the sub-workflow's PUBLISHED version. Draft edits are dormant
75
+ until the sub-workflow is republished — the classic "my edit did nothing".
76
+
77
+ ## Model credentials
78
+
79
+ - OpenRouter via `lmChatOpenRouter`: model IDs use DOT notation
80
+ (`anthropic/claude-sonnet-4.5`), never hyphenated version suffixes — the
81
+ wrapper mangles them. Dated slugs (`...-20250929`) are rejected. Verify
82
+ slugs against OpenRouter's live `/api/v1/models`, not memory.
83
+ - Dedicated model nodes (lmChatOpenRouter etc.) auto-bind credentials by
84
+ NAME at create time — prefer them over raw HTTP for LLM calls.
85
+
86
+ ## Memory
87
+
88
+ - Separate memory per user/session: key the memory node's session on the
89
+ chatTrigger's `sessionId`. A static shared key mixes every user's
90
+ conversation into one history.
91
+ - Motorhead memory node is deprecated — do not use.
92
+
93
+ ## Structured output
94
+
95
+ - NEVER attach a structured output parser to the FINAL agent of a chat
96
+ workflow — it breaks streaming/chat responses. Agent v3.x + parser +
97
+ `enableStreaming: true` loops to max iterations: tools fire (side effects
98
+ happen) on iteration 1, then the agent restates a valid answer forever.
99
+ - Prefer deriving routing metadata deterministically (e.g.
100
+ `{{ $('Trigger').isExecuted }}`) over asking the LLM to echo it. If
101
+ structured output is genuinely needed, disable streaming or parse in a
102
+ downstream node.
103
+ - `retryOnFail` on an agent whose tools have side effects re-runs the whole
104
+ agent after a post-success failure → duplicate posts/sends. Don't combine.
105
+
106
+ ## chainLlm (Basic LLM Chain)
107
+
108
+ - Emits NO `pairedItem`: any downstream `$('Node').item` throws "Paired item
109
+ data ... is unavailable" on multi-item inputs. `$('Node').first()` works.
110
+ Fixes: positional re-join in a Code node right after the chain (with a
111
+ count-mismatch guard), or route all items through ONE switch output so the
112
+ chain runs exactly once (fan-in from two outputs breaks pairing).
113
+ - Its error output (`onError: continueErrorOutput`) DOES carry the input
114
+ item's json fields plus an `error` key.
115
+
116
+ ## Chat widget embed (agent on a website)
117
+
118
+ n8n's chat widget can embed the agent on any site. chatTrigger config:
119
+
120
+ - `mode: "webhook"` and `responseMode: "lastNode"` for external embedding.
121
+ - CORS `allowedOrigins`: no trailing slashes, no spaces after commas.
122
+ - No structured output parser on the final agent (see above).
123
+
124
+ ## Test and deploy
125
+
126
+ - E2E = activate + production webhook + poll executions: `awesomate_n8n_test`
127
+ verify end-to-end: `awesomate_n8n_executions {workflowId}` to find the run,
128
+ then `awesomate_n8n_executions {executionId, debug: true}` for node-by-node
129
+ detail.
130
+ — `awesomate_n8n_deploy {action:"promote"}` preserves webhookIds.
131
+ - `saveExecutionProgress` stays FALSE (hub enforces; quadratic-write
132
+ incident). Agent/tool loops around `splitInBatches` need an
133
+ `executionTimeout`.
134
+ - Agent + chat workflows also run their published version — republish after
135
+ edits, and republish referenced sub-workflows too.
@@ -0,0 +1,105 @@
1
+ # Datatables — client-side playbook
2
+
3
+ n8n data tables: small operational stores a workflow reads/writes at runtime.
4
+ Read with `awesomate_n8n_inspect {what: "datatables"}` (tables, columns, row
5
+ counts). Write with `awesomate_n8n_datatable_write` (Support Plus+ plans only).
6
+
7
+ ## Right store or wrong store
8
+
9
+ | Data | Store |
10
+ |---|---|
11
+ | Dedupe ledger (seen event ids, sent emails) | Datatable |
12
+ | Task queue / retry list a workflow drains | Datatable |
13
+ | Lookup map (SKU→label, email→owner) | Datatable |
14
+ | Cursor/state between runs (last-synced timestamp) | Datatable |
15
+ | Real app data (users, orders, content) | The app's own database — never a datatable |
16
+ | Analytics, event history, anything unbounded | External store (app DB, sheet, warehouse) |
17
+
18
+ Rule of thumb: bounded row count, flat rows, no joins, consumed by the
19
+ automation itself. Instance cap is 50 tables (`datatable_cap_reached`), and
20
+ creates have a daily plan quota (`quota_exceeded` — limits in
21
+ `awesomate_n8n_context`).
22
+
23
+ ## Creating — pass workflowId
24
+
25
+ ```
26
+ awesomate_n8n_datatable_write {action: "create", name, columns: [{name, type?}], workflowId}
27
+ ```
28
+
29
+ - **Datatables resolve PER PROJECT at runtime.** A workflow in project A
30
+ referencing a table in project B fails on every run with
31
+ `Could not find the data table: '<id>'` — while the table, its columns, and
32
+ permissions are all perfectly intact. When the id matches and structure
33
+ looks fine, the project link is what's broken.
34
+ - **Pass `workflowId` whenever the table serves a specific workflow** (nearly
35
+ always). The table is then moved into that workflow's owner project —
36
+ co-location is verified, never assumed.
37
+ - Without `workflowId` the server co-locates only when exactly one project
38
+ owns your Claude Code drafts. Otherwise the response carries a
39
+ `projectWarning` ("CLI drafts span N projects — pass workflowId…" or
40
+ "workflowId … has no owner project — table left where n8n placed it").
41
+ **Treat `projectWarning` as a failed co-location**: recreate with the right
42
+ `workflowId` before inserting any rows.
43
+ - Column `type`: `string` | `number` | `boolean` | `date` (default `string`).
44
+ Column names: letters/digits/underscores, starting with a letter, no
45
+ spaces — n8n's row API references columns bare, so a spaced name is
46
+ unwritable even though PG would accept it.
47
+ - Design the full column set up front — schema is effectively frozen (next
48
+ section).
49
+
50
+ ## Schema is immutable over REST
51
+
52
+ n8n's REST API cannot alter a table. `action: "add_column"` exists but runs a
53
+ direct database write, so it additionally requires the account's
54
+ `allow_pg_writes` consent — ON by default, and NOT client-toggleable: a
55
+ `consent_required` here means Awesomate disabled it for this account, so the
56
+ remediation is recreating the table with the full column set, or asking
57
+ Awesomate support to re-enable direct database writes.
58
+ There is no rename, drop, or retype at all. Wrong schema and no PG consent →
59
+ create a new table, migrate rows, repoint the workflow.
60
+
61
+ ## Writes only touch self-created tables
62
+
63
+ `insert` / `update` / `delete_rows` / `add_column` work only on tables created
64
+ through Claude Code. Anything else → `403 not_self_created` — including tables
65
+ provisioned by Awesomate template deploys. Those belong to managed
66
+ automations; do not work around the refusal. Reads are unrestricted:
67
+ `awesomate_n8n_inspect` lists every table.
68
+
69
+ ## Row operations
70
+
71
+ | action | Requires | Notes |
72
+ |---|---|---|
73
+ | `insert` | `rows`: 1–100 objects | Chunk larger batches |
74
+ | `update` | non-empty `filter` + `data` object | `data` is one object, not an array |
75
+ | `delete_rows` | non-empty `filter` — REQUIRED | There is deliberately no delete-all. To empty a table, delete by filter or recreate it |
76
+
77
+ ## The dedupe gate pattern (rowNotExists)
78
+
79
+ Insert-if-absent as a barrier before side effects — the main reason a
80
+ datatable exists in a client workflow:
81
+
82
+ 1. Table with one key column (e.g. `event_id` string) plus any audit columns.
83
+ 2. In the workflow, BEFORE the side effect (email, API call, charge): Data
84
+ table node with the **row-does-not-exist** operation matching the key —
85
+ only unseen items pass.
86
+ 3. Insert the key immediately after the gate, BEFORE the side effect.
87
+ Insert-first gives at-most-once (right for emails and charges);
88
+ insert-after gives at-least-once (duplicates on crash/retry).
89
+ 4. The gate and insert are separate node steps, not a transaction — a webhook
90
+ delivered twice in the same instant can pass both. Acceptable for dedupe;
91
+ not a locking primitive.
92
+
93
+ Queue-drain workflows (`splitInBatches` over a table) need `executionTimeout`
94
+ set, and `saveExecutionProgress` stays FALSE — both fleet invariants.
95
+
96
+ ## Failure decode
97
+
98
+ | Symptom | Meaning | Fix |
99
+ |---|---|---|
100
+ | `Could not find the data table: '<id>'` at runtime | Project scope, not existence | Recreate/move the table with `workflowId`; check `awesomate_n8n_inspect {what: "datatables"}` vs the workflow's project |
101
+ | `403 not_self_created` | Table wasn't created through Claude Code | Create your own table; never write agency tables |
102
+ | `consent_required` on add_column | `allow_pg_writes` disabled for this account (not client-toggleable) | Recreate with the full schema, or ask Awesomate support |
103
+ | `409 column_exists` | Column name collision | Pick another name; check current columns via inspect |
104
+ | `429 datatable_cap_reached` / `quota_exceeded` | 50-table cap or daily create quota | Stop; reuse or delete tables, or wait for the daily reset |
105
+ | `501 datatables_unsupported` | Instance's n8n version predates data tables | No datatable path — use an external store |
@@ -14,7 +14,8 @@ trust this file.
14
14
  `$vars` keys are listed by `GET /api/my-n8n/machine/variables`.
15
15
  2. **Task runners are on by default** (2.0+): Code nodes have no `$helpers` —
16
16
  no `$helpers.httpRequest`, no `getBinaryDataBuffer`. HTTP calls belong in
17
- HTTP Request nodes; binary work belongs in dedicated nodes.
17
+ HTTP Request nodes; binary work belongs in dedicated nodes. In-memory
18
+ binary mode is gone too.
18
19
  3. **Media/community nodes are variant-gated.** `CUSTOM.localFiles`,
19
20
  better-ffmpeg, and mediafx exist only on FFMPEG-variant instances
20
21
  (Support Plus+ — `capabilities.variant` in the context tool). A workflow
@@ -34,7 +35,8 @@ trust this file.
34
35
  "ignores" a configured value, look for the missing sibling switch.
35
36
  8. **`resource` + `operation` travel together.** Partial edits that set one
36
37
  without the other can leave the node silently misconfigured (n8n's
37
- sanitizer may strip `operation`). When editing node JSON, always write both.
38
+ sanitizer may strip `operation`). When editing node JSON, always write
39
+ both, and re-validate after every partial update.
38
40
 
39
41
  ## Triggers & webhooks
40
42
 
@@ -59,23 +61,70 @@ trust this file.
59
61
  often upstream (empty input from a mis-mapped field two nodes back).
60
62
  Walk the item data backwards.
61
63
  15. Recommended workflow settings for anything that matters:
62
- `{"executionOrder": "v1", "saveExecutionProgress": true,
64
+ `{"executionOrder": "v1", "saveExecutionProgress": false,
63
65
  "saveDataErrorExecution": "all", "saveDataSuccessExecution": "all"}` —
64
- without the save flags there may be nothing to inspect after a failure.
66
+ without the save-data flags there may be nothing to inspect after a
67
+ failure. Keep `saveExecutionProgress` OFF: it checkpoints the whole
68
+ workflow state to the database after every node — on loops that write-
69
+ amplifies brutally (a single runaway workflow once wrote ~2TB). The hub
70
+ enforces `false` on drafts it creates. Any `splitInBatches` loop should
71
+ also set `executionTimeout` so a wedged run can't grind forever.
72
+ 16. **Node-level inspection**: `awesomate_n8n_executions {executionId,
73
+ debug: true}` decodes an execution into per-node input/output and the
74
+ real error. Use it instead of guessing from the summary. It is gated on
75
+ the client's `error_content_analysis` privacy toggle (default OFF) — on
76
+ a consent refusal, ask the user to enable it on /settings → Privacy;
77
+ never work around the gate.
65
78
 
66
79
  ## Credentials
67
80
 
68
- 16. The n8n API never returns credential secrets, and neither does the hub —
81
+ 17. The n8n API never returns credential secrets, and neither does the hub —
69
82
  the inventory is names/types/inferred purpose only.
70
- 17. OAuth credentials (Gmail, Google Sheets, Slack…) can only be completed in
83
+ 18. OAuth credentials (Gmail, Google Sheets, Slack…) can only be completed in
71
84
  the n8n browser UI — the consent screen needs a human. API-key
72
85
  credentials (SMTP, Resend, SendGrid, HTTP header auth…) don't have that
73
86
  constraint. This matters when advising which email/integration path is
74
87
  fastest to set up.
75
- 18. "Credential could not be found" on a node usually means a sharing issue
88
+ 19. "Credential could not be found" on a node usually means a sharing issue
76
89
  (the credential exists but isn't shared with the workflow owner), not a
77
90
  deleted credential.
78
91
 
92
+ ## Datatables (PROJECT-scoped — critical)
93
+
94
+ 20. **Datatables resolve per project at runtime.** A workflow in project A
95
+ referencing a table in project B fails every run with
96
+ `Could not find the data table: '<id>'` while the table, its columns,
97
+ and its permissions are all perfectly intact. Every structural check
98
+ passes; only the project link is wrong. **When the ID matches and
99
+ permissions are fine, check scope, not existence.**
100
+ 21. **Create tables through the hub, threaded to the workflow.**
101
+ `awesomate_n8n_datatable_write {action: "create"}` co-locates the table
102
+ with the project that owns the client's drafts, and accepts `workflowId`
103
+ to target a specific workflow's owner project instead. Pass it whenever
104
+ the consuming workflow is known. Datatable writes are Support Plus+.
105
+ 22. List existing tables (ids, columns, rows) with
106
+ `awesomate_n8n_inspect {what: "datatables"}` before creating duplicates.
107
+
108
+ ## Deploy & validation
109
+
110
+ 23. **Never activate a copy to replace a live workflow.**
111
+ `awesomate_n8n_deploy {action: "promote"}` preserves webhookIds;
112
+ activating a duplicate mints new ones and silently breaks every external
113
+ caller. E2E verification = activate, hit the production webhook, poll
114
+ `awesomate_n8n_executions`.
115
+ 24. **Known validation false positives** (via `awesomate_n8n_deploy
116
+ {action: "validate"}` or `awesomate_n8n_node_docs validate_node`):
117
+ community/CUSTOM nodes report "unknown" (expected — see variant gating,
118
+ rule 3); graph cycles flag `valid: false`, but cycle-based polling loops
119
+ are legitimate. Filter known false positives — don't "fix" a working
120
+ workflow to satisfy the validator.
121
+
122
+ ## Embedded chat
123
+
124
+ 25. Embedded chat trigger config: `mode: "webhook"` +
125
+ `responseMode: "lastNode"`. Allowed-origins (CORS) list: no trailing
126
+ slashes, no spaces after commas — either one breaks the widget silently.
127
+
79
128
  ## Design principles (for when you sketch workflows with the user)
80
129
 
81
130
  - Separate reasoning from execution: AI nodes decide and route; Code/HTTP/