@pipefy/pipefy-process-coder 0.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/.agents/skills/ppc-pipefy-flow-authoring/SKILL.md +262 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-danfe-consulta.json +247 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-webhook-retorno-consulta.json +589 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-4-recebimento-barramento.json +1391 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-2-danfe-retorno.json +623 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-4-criacao-operacao.json +636 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/03-subflow-4-criacao-titulo.json +3642 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-cedente.json +863 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-sacado.json +799 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/README.md +42 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-acompanhamento-cobranca.json +581 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-nfe-monitoramento.json +503 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-retorno-bancario.json +562 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-cedente.json +557 -0
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-sacado.json +609 -0
- package/.agents/skills/ppc-pipefy-pipe-authoring/SKILL.md +146 -0
- package/.agents/skills/ppc-pipefy-process-design/SKILL.md +127 -0
- package/.agents/skills/ppc-pipefy-workspace/SKILL.md +91 -0
- package/AGENTS.md +456 -0
- package/README.md +808 -0
- package/bin/pipe.js +13 -0
- package/package.json +35 -0
- package/src/apply/adopt.ts +150 -0
- package/src/apply/agentops.ts +71 -0
- package/src/apply/compile.ts +875 -0
- package/src/apply/execute.ts +336 -0
- package/src/apply/flowops.ts +399 -0
- package/src/apply/idmap.ts +241 -0
- package/src/apply/mutations.ts +955 -0
- package/src/apply/registry.ts +430 -0
- package/src/apply/types.ts +134 -0
- package/src/cli/args.ts +88 -0
- package/src/cli.ts +211 -0
- package/src/codec/flow.ts +199 -0
- package/src/codec/pack.ts +103 -0
- package/src/codec/roundtrip.ts +94 -0
- package/src/codec/unpack.ts +198 -0
- package/src/commands/agents.ts +184 -0
- package/src/commands/apply.ts +1144 -0
- package/src/commands/context.ts +119 -0
- package/src/commands/create.ts +79 -0
- package/src/commands/diff.ts +314 -0
- package/src/commands/flows.ts +414 -0
- package/src/commands/misc.ts +644 -0
- package/src/commands/plan.ts +331 -0
- package/src/commands/pull.ts +567 -0
- package/src/commands/runs.ts +83 -0
- package/src/commands/skills.ts +137 -0
- package/src/commands/verify.ts +253 -0
- package/src/config.ts +168 -0
- package/src/diff/agents.ts +122 -0
- package/src/diff/diff.ts +1130 -0
- package/src/diff/flow.ts +318 -0
- package/src/diff/html.ts +322 -0
- package/src/diff/render.ts +101 -0
- package/src/model/payload.ts +154 -0
- package/src/model/tree.ts +99 -0
- package/src/model/volatile.ts +55 -0
- package/src/pipefy/agents.ts +165 -0
- package/src/pipefy/automations.ts +219 -0
- package/src/pipefy/capability.ts +119 -0
- package/src/pipefy/client.ts +267 -0
- package/src/pipefy/discovery.ts +209 -0
- package/src/pipefy/internal.ts +380 -0
- package/src/pipefy/ipaas.ts +365 -0
- package/src/pipefy/reconstruct.ts +775 -0
- package/src/pipefy/reference.ts +251 -0
- package/src/pipefy/snapshot.ts +245 -0
- package/src/pipefy/toolkit.ts +200 -0
- package/src/pipefy/toolkit_bearer.py +137 -0
- package/src/report/integrations.ts +231 -0
- package/src/report/run.ts +475 -0
- package/src/util/fsx.ts +45 -0
- package/src/util/git.ts +32 -0
- package/src/util/json.ts +55 -0
- package/src/util/log.ts +76 -0
- package/src/util/pool.ts +48 -0
- package/src/util/slug.ts +26 -0
- package/src/util/tui.ts +335 -0
- package/src/validate/index.ts +123 -0
- package/src/validate/integrity.ts +387 -0
- package/src/validate/reference.ts +136 -0
- package/src/validate/schema.ts +328 -0
- package/src/workspace/agents.ts +290 -0
- package/src/workspace/docs.ts +407 -0
- package/src/workspace/flows.ts +191 -0
- package/src/workspace/layout.ts +165 -0
- package/src/workspace/lock.ts +148 -0
- package/src/workspace/read.ts +165 -0
- package/src/workspace/reference.ts +24 -0
- package/src/workspace/stamp.ts +301 -0
- package/src/workspace/write.ts +225 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ppc-pipefy-pipe-authoring
|
|
3
|
+
description: Use when writing or editing the JSON of a Pipefy pipe's structure in a pipefy-process-coder workspace — phases, fields, automations, field conditions, labels, webhooks, pipe relations, preferences, public form. Covers the file layout, referencing entities that do not exist yet, and the specific edits that fail silently because a mutation accepts them and ignores them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Authoring pipe structure JSON
|
|
7
|
+
|
|
8
|
+
Read `ppc-pipefy-workspace` first for the loop and the identity rules. This is the
|
|
9
|
+
detail: what goes in which file, and which edits look fine and are not.
|
|
10
|
+
|
|
11
|
+
## Where things live
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
pipes/<id>--<name>/
|
|
15
|
+
pipe.json the repo row: name, noun, public, title_field_id
|
|
16
|
+
phases/NN--name.json the phase, its fields[], jump_target_ids[], team_member_ids[]
|
|
17
|
+
automations/<name>.json the automation, its condition, field_maps, response_schemas
|
|
18
|
+
field-conditions/<name>.json the condition and its actions
|
|
19
|
+
labels.json webhooks.json public-form.json preferences.json relations.json
|
|
20
|
+
_readonly/ _non-snapshot/ _meta.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Fields live inside their phase file.** That is where they make sense and where
|
|
24
|
+
you will edit them most. Ordering comes from the `index` value inside the file,
|
|
25
|
+
never from the filename — renumbering works without renaming.
|
|
26
|
+
|
|
27
|
+
The start form is a real phase at `index: 0`. Deleting or reindexing it is
|
|
28
|
+
catastrophic; the validator refuses.
|
|
29
|
+
|
|
30
|
+
## Creating something new
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{ "id": null, "_new": true, "uuid": "<fresh v4>", "label": "Severity", "type_id": "select", … }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
A new field nested in an existing phase file needs no `phase_id` — it inherits its
|
|
37
|
+
owner's. A field in a *new* phase leaves it null; the compiler substitutes the
|
|
38
|
+
phase's real id after the phase is created.
|
|
39
|
+
|
|
40
|
+
**Referencing something you are creating in the same edit:** leave
|
|
41
|
+
`%{_new:<its uuid>}` and the applier substitutes the real id once it exists. This
|
|
42
|
+
works in automation `field_maps`, condition `field_address`, `jump_target_ids`,
|
|
43
|
+
and field-condition action targets.
|
|
44
|
+
|
|
45
|
+
## What cannot be changed at all
|
|
46
|
+
|
|
47
|
+
| Edit | Why |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| a field's `type_id` | `updatePhaseField` has no `type_id`. Delete+create destroys every existing value. |
|
|
50
|
+
| a field's `phase_id` | same — no input, and moving it would destroy the data |
|
|
51
|
+
| a phase's `index` | `createPhase` takes an index, `updatePhase` does not |
|
|
52
|
+
| a pipe's `description` | `UpdatePipeInput` has no `description` field at all |
|
|
53
|
+
| `start_form_title` | no input on any preference mutation |
|
|
54
|
+
| anything under `_readonly/` | no public write path exists |
|
|
55
|
+
|
|
56
|
+
If a request needs one of these, say so and stop. `pipe plan` refuses them per
|
|
57
|
+
column, with the reason.
|
|
58
|
+
|
|
59
|
+
## The silent failures — every one of these cost a live incident
|
|
60
|
+
|
|
61
|
+
These are edits the API *accepts* and does not apply, or applies wrongly. They are
|
|
62
|
+
guarded now, but understanding them stops you writing them.
|
|
63
|
+
|
|
64
|
+
**A mutation can succeed and change nothing.** Arguments are filtered against the
|
|
65
|
+
live schema, so an argument the mutation has no input for is dropped and the call
|
|
66
|
+
returns success. `description`, `anyone_can_create_card` and `create_card_label`
|
|
67
|
+
all did this on `updatePipe`. That is why the registry names settable columns per
|
|
68
|
+
entity rather than trusting the mutation.
|
|
69
|
+
|
|
70
|
+
**Some arguments want a uuid where the payload stores an id.**
|
|
71
|
+
`updatePipe.title_field_id` takes the field's **uuid** or slug, never the numeric
|
|
72
|
+
id the payload holds. `archiveField` takes `{ uuid }`. Both are translated for you.
|
|
73
|
+
|
|
74
|
+
**`phaseSettings` reports failure for changes it has already made.** Observed on
|
|
75
|
+
three separate runs, with the row present in the read-back and timestamped to the
|
|
76
|
+
failing call. Its errors are inconclusive — re-read before assuming nothing
|
|
77
|
+
happened.
|
|
78
|
+
|
|
79
|
+
**`hidden_top_buttons` and `hidden_start_form_attributes` are closed sets:**
|
|
80
|
+
`Assignees, Attachments, Checklist, Comments, DueDate, Labels`. Anything else is
|
|
81
|
+
rejected mid-apply. Checked offline now.
|
|
82
|
+
|
|
83
|
+
**Every event and action accepts a fixed parameter list, and nothing enforces it.**
|
|
84
|
+
Read `REFERENCE.md` in the workspace before writing an automation. It is generated
|
|
85
|
+
by `pipe pull` from the API and lists each event's `event_params`, each action's
|
|
86
|
+
`action_params`, and which pairings are refused.
|
|
87
|
+
|
|
88
|
+
The reason it needs reading: the schema publishes these lists, then types
|
|
89
|
+
`event_id`, `action_id` and `type_id` as `ID` and `String`, so GraphQL validates
|
|
90
|
+
none of them. A wrong value returns `is invalid` or `All fields must be filled
|
|
91
|
+
properly.` — naming nothing — partway through an apply. And the mistakes are
|
|
92
|
+
near-misses, not nonsense:
|
|
93
|
+
|
|
94
|
+
- `card_moved` takes only `to_phase_id`. `in_phase_id` is real, on
|
|
95
|
+
`card_inbox_received_email`.
|
|
96
|
+
- `card_id` is accepted on `update_card_field` and refused on `move_single_card`.
|
|
97
|
+
|
|
98
|
+
`pipe validate` catches all of it offline and names the parameter, so run it before
|
|
99
|
+
`plan`. Treat it as the backstop, not the reference.
|
|
100
|
+
|
|
101
|
+
**Automation params mix naming conventions.** `AutomationActionParamsInput` has
|
|
102
|
+
`card_id`, `to_phase_id` and `field_map` in snake_case, but `taskParams`,
|
|
103
|
+
`aiParams` and `httpMethod` in camelCase. Getting one wrong deleted a live
|
|
104
|
+
automation once, because the update strategy is delete-then-recreate.
|
|
105
|
+
|
|
106
|
+
**Pipe relation flags are spelled differently in the mutation and the payload.**
|
|
107
|
+
`createPipeRelation` says `canCreateNewItems`; the payload row says
|
|
108
|
+
`can_create_connected_cards`. Set both, or read the one that is there.
|
|
109
|
+
|
|
110
|
+
**A phase's jump set is set-replacing.** `jump_target_ids` is written whole. Never
|
|
111
|
+
append blindly to a set you have not fully read.
|
|
112
|
+
|
|
113
|
+
## Cross-surface obligations
|
|
114
|
+
|
|
115
|
+
**Deleting a field obliges you to fix every reference to it.** Automations and
|
|
116
|
+
conditions hold bare numeric ids inside opaque JSON — `"field_address": "<fieldId>"`,
|
|
117
|
+
`"trigger_field_ids": ["<fieldId>"]`, `"%{<fieldId>}"`. `pipe validate` fails on a
|
|
118
|
+
dangling reference by design. `MAPPING.md` translates every id.
|
|
119
|
+
|
|
120
|
+
**If the pipe has iPaaS flows, a field may be referenced there too**, by slug,
|
|
121
|
+
and the tool cannot yet see it. Check `flows/` if it exists before deleting a
|
|
122
|
+
field. See `ppc-pipefy-flow-authoring`.
|
|
123
|
+
|
|
124
|
+
## A worked shape: creating a phase with fields and a jump
|
|
125
|
+
|
|
126
|
+
The numbers below are made up — use the real ids from `MAPPING.md`.
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
// phases/09--customer-validation.json
|
|
130
|
+
{
|
|
131
|
+
"id": null, "_new": true, "uuid": "<fresh v4>",
|
|
132
|
+
"name": "Customer Validation", "index": 9, "done": false,
|
|
133
|
+
"repo_id": 100200300,
|
|
134
|
+
"fields": [
|
|
135
|
+
{ "id": null, "_new": true, "uuid": "<fresh v4>", "label": "Customer acceptance",
|
|
136
|
+
"type_id": "select", "options": ["Accepted", "Needs rework", "Declined"],
|
|
137
|
+
"index": 0, "required": false, "repo_id": 100200300 }
|
|
138
|
+
],
|
|
139
|
+
"jump_target_ids": [400500600],
|
|
140
|
+
"team_member_ids": []
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Set `index` on new phases explicitly and leave existing ones alone — their index
|
|
145
|
+
cannot be edited. Creating a phase auto-links jumps, so state the jump set you
|
|
146
|
+
want or the platform's default stands.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ppc-pipefy-process-design
|
|
3
|
+
description: Use when deciding HOW to build a requirement in Pipefy — which mechanism a need calls for (phase, field condition, automation, iPaaS flow, pipe relation, phase jump, connector field), and how to shape a process so it survives contact with real users. Read before authoring, when the question is "what should this look like" rather than "what JSON does this need".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Designing a process in Pipefy
|
|
7
|
+
|
|
8
|
+
Most bad Pipefy builds are not bad JSON. They are the right JSON for the wrong
|
|
9
|
+
mechanism — an automation doing what a field condition should, a `CODE` node doing
|
|
10
|
+
what a piece action does, a flow built where a phase would have been enough.
|
|
11
|
+
|
|
12
|
+
Pick the mechanism first.
|
|
13
|
+
|
|
14
|
+
## Choosing the mechanism
|
|
15
|
+
|
|
16
|
+
Work down this list and stop at the first one that fits. Each rung costs more to
|
|
17
|
+
build, more to explain, and more to debug than the one above it.
|
|
18
|
+
|
|
19
|
+
| Need | Mechanism | Why it is the cheapest fit |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Show or hide a field depending on another field | **field condition** | Instant, no run history, no failure mode. Never build this as an automation. |
|
|
22
|
+
| Constrain where a card can move | **phase jump set** | Structural. The board enforces it; no rule can be out of date. |
|
|
23
|
+
| Stamp a timestamp, copy a value, set a label, move a card, send a task or email — **within one pipe** | **automation** | Native, visible in the pipe, no external dependency, no separate credential |
|
|
24
|
+
| Compute something from fields in the same card | **automation with a formula, or an AI action** | Still inside the pipe |
|
|
25
|
+
| Link cards between two pipes so people can navigate between them | **pipe relation + connector field** | Structural and bidirectional. An automation that "creates a card" does not link anything. |
|
|
26
|
+
| Hold a reusable list people pick from — departments, products, suppliers, services | **a database**, not a pipe | A database has columns and records but no workflow. Reach it with a `connector` field. Reaching for a pipe here gives you phases nobody moves cards through. |
|
|
27
|
+
| Store rows that a process reads but nobody works on | **a database** | If a row has no owner and no next step, it is reference data. Cards are for work that moves. |
|
|
28
|
+
| Create a card in another pipe when something happens | **automation with `create_card` and `action_repo_id`** | Cross-pipe *writes* are within the automation engine's reach |
|
|
29
|
+
| **Read** a pipe other than the one that triggered | **iPaaS flow** | The automation engine cannot. This is the real dividing line. |
|
|
30
|
+
| Touch anything outside Pipefy — Slack, HTTP, Sheets, an ERP | **iPaaS flow** | Only iPaaS has pieces |
|
|
31
|
+
| Aggregate across many cards, or run on a schedule | **iPaaS flow** | No automation trigger does either |
|
|
32
|
+
| Anything else, plus arbitrary logic | **iPaaS flow with a `CODE` node** | Last rung. See the ladder below. |
|
|
33
|
+
|
|
34
|
+
### The dividing line worth memorising
|
|
35
|
+
|
|
36
|
+
**An automation can write to another pipe. It cannot read one.** That single fact
|
|
37
|
+
decides most automation-versus-flow questions. "When X completes, open a card in
|
|
38
|
+
Y" is an automation. "When X completes, check whether the card in Y exists" is a
|
|
39
|
+
flow.
|
|
40
|
+
|
|
41
|
+
### Inside a flow, the same discipline applies
|
|
42
|
+
|
|
43
|
+
1. A **piece action** that already does it — check the catalogue first.
|
|
44
|
+
2. An **inline formula expression** in a free-text input.
|
|
45
|
+
3. A **`CODE` node**, only when no piece fits and the logic exceeds a formula.
|
|
46
|
+
|
|
47
|
+
A `CODE` node is where the destination of a write can be computed at runtime,
|
|
48
|
+
which means no static check can see it. That is the most expensive kind of bug in
|
|
49
|
+
this domain — prefer a piece.
|
|
50
|
+
|
|
51
|
+
## Shaping the process itself
|
|
52
|
+
|
|
53
|
+
**Name the phases after states, not actions.** "Qualification & Prioritization",
|
|
54
|
+
not "Qualify". A card *is in* a state; it does not *do* a phase.
|
|
55
|
+
|
|
56
|
+
**Every phase needs an exit.** A phase whose `jump_target_ids` is empty is a dead
|
|
57
|
+
end — cards arrive and cannot leave. Author the jump set explicitly; creating a
|
|
58
|
+
phase auto-links jumps, and the platform's default is rarely the process you meant.
|
|
59
|
+
|
|
60
|
+
**Make required fields answerable at the moment they are asked.** An intake form
|
|
61
|
+
that requires a value only known after triage is a form nobody can submit. Real
|
|
62
|
+
example: a Customer Success intake required "Account tier" and "Customer impact",
|
|
63
|
+
which meant an automated handoff from another pipe could never satisfy it — the
|
|
64
|
+
form was blocked until both became triage-time fields.
|
|
65
|
+
|
|
66
|
+
**Distinguish intake from work.** The start form is what the requester knows; the
|
|
67
|
+
first phase is what the team adds. Do not put "Triage owner" on the start form.
|
|
68
|
+
|
|
69
|
+
**Let the last phase mean something.** Set `done: true` on the phase that ends the
|
|
70
|
+
process. Webhooks and `cardDone` triggers depend on it, and a pipe whose final
|
|
71
|
+
phase is not marked done cannot fire either.
|
|
72
|
+
|
|
73
|
+
**Give closure a reason.** A "Rejected / Closed" phase with a `select` for the
|
|
74
|
+
reason turns a dead card into data. Without it, nobody can answer "why do we
|
|
75
|
+
decline things".
|
|
76
|
+
|
|
77
|
+
## Designing the integration, not just the flow
|
|
78
|
+
|
|
79
|
+
**Silence on success, noise on failure.** A flow that messages someone every time
|
|
80
|
+
things go right gets muted, and then the one that matters is invisible too. If both
|
|
81
|
+
outcomes are worth saying, say different things — and make the failure louder.
|
|
82
|
+
|
|
83
|
+
**Assume the other side can be missing.** A cross-pipe read returns an empty list
|
|
84
|
+
when the thing you expected was never created. That empty list is usually the most
|
|
85
|
+
interesting outcome — handle it in a `ROUTER` branch rather than letting the flow
|
|
86
|
+
run on with nothing.
|
|
87
|
+
|
|
88
|
+
**Let a search fail without stopping the flow.** Set `continueOnFailure` on the
|
|
89
|
+
step that can legitimately find nothing, so the branch that reports "not found"
|
|
90
|
+
is reachable.
|
|
91
|
+
|
|
92
|
+
**Never assume a connection exists in another workspace.** Connections are
|
|
93
|
+
pipe-scoped. A flow that works in one pipe will not import into another that has
|
|
94
|
+
no connection for the same piece.
|
|
95
|
+
|
|
96
|
+
## Reviewing a process someone else built
|
|
97
|
+
|
|
98
|
+
Ask these in order. Each has caught a real problem.
|
|
99
|
+
|
|
100
|
+
1. **Does every phase have an exit?** Check every `jump_target_ids`.
|
|
101
|
+
2. **Can the start form actually be submitted** by the people and systems that
|
|
102
|
+
need to submit it?
|
|
103
|
+
3. **Is any required field only knowable later?**
|
|
104
|
+
4. **Does the final phase have `done: true`?**
|
|
105
|
+
5. **Does anything reference a field that no longer exists?** `pipe validate`
|
|
106
|
+
answers this; a dangling reference is an error by design.
|
|
107
|
+
6. **If the pipe has flows, does any of them read a field the pipe is about to
|
|
108
|
+
lose?** The tool cannot check this yet — look at `flows/` yourself.
|
|
109
|
+
7. **Is any automation doing a field condition's job?** Those are the first
|
|
110
|
+
things to delete.
|
|
111
|
+
8. **Are there duplicate automations?** Two identical rules on one trigger is
|
|
112
|
+
almost always the residue of a failed apply, not a decision.
|
|
113
|
+
|
|
114
|
+
## Two failure modes specific to this tool
|
|
115
|
+
|
|
116
|
+
**A partial apply leaves created entities looking new.** If an apply half-fails,
|
|
117
|
+
the files may still say `"id": null, "_new": true` for things that now exist.
|
|
118
|
+
Re-planning would create them twice. `pipe apply` repairs this automatically, and
|
|
119
|
+
`pipe verify --adopt` does it on demand — but if you see a diff proposing to create
|
|
120
|
+
something you know exists, that is the cause.
|
|
121
|
+
|
|
122
|
+
**A clean `pipe diff` covers flows too** — but only where they were readable.
|
|
123
|
+
Check `pipes/<id>--<name>/flows/_meta.json`: `coverage: "complete"` means the
|
|
124
|
+
flows were compared and match. **`coverage: "unknown"` means iPaaS could not be
|
|
125
|
+
reached for that pipe, so its flows were not compared at all** — and a pipe can
|
|
126
|
+
diff clean while its actual behaviour changed entirely, because the change was in
|
|
127
|
+
a flow nobody looked at. That is the one case where a clean diff is not proof.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ppc-pipefy-workspace
|
|
3
|
+
description: Use when working in a pipefy-process-coder workspace — pulling a Pipefy pipe to disk, editing its JSON, diffing, planning and applying changes back. Covers the loop, which command to run when, what each generated doc is for, and the safety rules that make an apply trustworthy. Start here before editing anything.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Working in a Pipefy workspace
|
|
7
|
+
|
|
8
|
+
A workspace is a Pipefy pipe pulled to disk as JSON. You edit the files; the tool
|
|
9
|
+
turns your edits into API calls. Nothing about a pipe is edited through this tool
|
|
10
|
+
except by changing a file and applying it.
|
|
11
|
+
|
|
12
|
+
## The loop, and why each step exists
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pipe pull <pipeId> --out ./my-pipe # the pipe AND its iPaaS flows
|
|
16
|
+
cd my-pipe
|
|
17
|
+
# edit the JSON
|
|
18
|
+
pipe validate # shape + referential integrity. Offline, instant.
|
|
19
|
+
pipe diff # what you changed — pipe structure and flows
|
|
20
|
+
pipe plan --dry-run # is every change applicable? refuses if not
|
|
21
|
+
pipe apply # snapshot, apply step by step, verify, adopt
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**One loop covers both halves of a process.** A pipe's iPaaS flows are entities of
|
|
25
|
+
that pipe — its own webhook URLs carry their ids — so they are pulled, diffed,
|
|
26
|
+
planned and applied by the same commands, and land under
|
|
27
|
+
`pipes/<id>--<name>/flows/`. `--no-flows` opts out of the flow half.
|
|
28
|
+
|
|
29
|
+
**`pipe validate && pipe plan --dry-run` must both be clean before you propose an
|
|
30
|
+
apply.** Both are free — validate needs no network, plan sends no writes — so
|
|
31
|
+
iterate against them yourself rather than asking the user to run an apply and see.
|
|
32
|
+
|
|
33
|
+
`pipe apply` does four things in order: snapshots the pipe as a rollback point,
|
|
34
|
+
executes step by step persisting each status so a failure is resumable, reads the
|
|
35
|
+
pipe back and diffs it against your intent, then adopts the result into the files
|
|
36
|
+
so server-assigned ids are real. If it half-succeeds, read the output — it tells
|
|
37
|
+
you whether to `--resume` or re-plan.
|
|
38
|
+
|
|
39
|
+
## Read these first, in this order
|
|
40
|
+
|
|
41
|
+
Every workspace generates three docs. They are not filler.
|
|
42
|
+
|
|
43
|
+
| | |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `AGENTS.md` | the editing rules for *this* workspace, including what its read path could and could not see |
|
|
46
|
+
| `MAPPING.md` | every field id → label, slug, type and phase. **You need this constantly**, because automations and conditions reference fields by bare numeric id |
|
|
47
|
+
| `CAPABILITIES.md` | what this endpoint can actually write, and the reason for every gap |
|
|
48
|
+
| `REFERENCE.md` | what the API accepts wherever a value comes from a fixed list — automation event and action parameters, field `type_id`, colours. **Read it before writing an automation**: those lists are published by the schema and enforced by nothing, so a wrong value is only ever reported as `is invalid` |
|
|
49
|
+
|
|
50
|
+
`pipe capabilities` prints the same registry with reasons. When a change is
|
|
51
|
+
refused, that is where the answer is.
|
|
52
|
+
|
|
53
|
+
## The rules that are not style preferences
|
|
54
|
+
|
|
55
|
+
- **`id` is server-owned.** Never invent one, never edit one, never reuse one.
|
|
56
|
+
- **A new entity is `"id": null` plus `"_new": true`.** For phases, fields,
|
|
57
|
+
automations and labels — the only four arrays with one — also add a fresh v4
|
|
58
|
+
`uuid`. Everything else is identified by its owner.
|
|
59
|
+
- **To delete, remove the object or the file.** Never a tombstone.
|
|
60
|
+
- **`_`-prefixed keys are tool metadata.** Leave them alone.
|
|
61
|
+
- **Never edit under `_readonly/` or `_non-snapshot/`.** No write path exists;
|
|
62
|
+
plan refuses them by path alone.
|
|
63
|
+
|
|
64
|
+
## Coverage: absence is not always absence
|
|
65
|
+
|
|
66
|
+
Every entity group carries `complete`, `partial` or `unknown` coverage in
|
|
67
|
+
`_meta.json`. An `unknown` group means the read path could not see it — not that
|
|
68
|
+
the pipe has none. Such a group is never diffed and never applied.
|
|
69
|
+
|
|
70
|
+
This matters most on a reconstructed pull (no snapshots): webhooks or automations
|
|
71
|
+
may be `unknown`, and adding to a list you cannot fully see risks duplicating what
|
|
72
|
+
is already there. Check `_meta.json` before concluding a pipe lacks something.
|
|
73
|
+
|
|
74
|
+
## Where to go next
|
|
75
|
+
|
|
76
|
+
| Task | Skill |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| Editing phases, fields, automations, conditions, labels | `ppc-pipefy-pipe-authoring` |
|
|
79
|
+
| Editing or building an iPaaS (Advanced Automations) flow | `ppc-pipefy-flow-authoring` |
|
|
80
|
+
| Deciding *which* Pipefy mechanism a requirement needs | `ppc-pipefy-process-design` |
|
|
81
|
+
|
|
82
|
+
## Two habits worth keeping
|
|
83
|
+
|
|
84
|
+
**Diff before you explain.** `pipe diff` on a real change costs ~150 tokens and
|
|
85
|
+
tells you exactly what you altered. Reading the whole pipe back to check your work
|
|
86
|
+
costs 50× that and is less reliable.
|
|
87
|
+
|
|
88
|
+
**Believe the refusal.** When `pipe plan` says a change has no write path, it is
|
|
89
|
+
because the mutation genuinely lacks that input — the registry records the reason
|
|
90
|
+
per column. Do not route around it with a delete and a create; that destroys data.
|
|
91
|
+
Say so plainly and stop.
|