@pipefy/pipefy-process-coder 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/ppc-pipefy-flow-authoring/SKILL.md +262 -262
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-danfe-consulta.json +247 -247
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-webhook-retorno-consulta.json +589 -589
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-4-recebimento-barramento.json +1391 -1391
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-2-danfe-retorno.json +623 -623
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-4-criacao-operacao.json +636 -636
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/03-subflow-4-criacao-titulo.json +3642 -3642
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-cedente.json +863 -863
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-sacado.json +799 -799
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/README.md +42 -42
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-acompanhamento-cobranca.json +581 -581
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-nfe-monitoramento.json +503 -503
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-retorno-bancario.json +562 -562
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-cedente.json +557 -557
- package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-sacado.json +609 -609
- package/.agents/skills/ppc-pipefy-pipe-authoring/SKILL.md +146 -146
- package/.agents/skills/ppc-pipefy-process-design/SKILL.md +127 -127
- package/.agents/skills/ppc-pipefy-workspace/SKILL.md +91 -91
- package/AGENTS.md +465 -456
- package/README.md +825 -807
- package/bin/pipe.js +25 -4
- package/dist/apply/adopt.js +128 -0
- package/dist/apply/agentops.js +42 -0
- package/dist/apply/compile.js +722 -0
- package/dist/apply/execute.js +277 -0
- package/dist/apply/flowops.js +293 -0
- package/dist/apply/idmap.js +233 -0
- package/dist/apply/mutations.js +704 -0
- package/dist/apply/registry.js +348 -0
- package/dist/apply/types.js +18 -0
- package/dist/cli/args.js +79 -0
- package/dist/cli.js +187 -0
- package/dist/codec/flow.js +164 -0
- package/dist/codec/pack.js +88 -0
- package/dist/codec/roundtrip.js +86 -0
- package/dist/codec/unpack.js +181 -0
- package/dist/commands/agents.js +145 -0
- package/dist/commands/apply.js +982 -0
- package/dist/commands/context.js +79 -0
- package/dist/commands/create.js +63 -0
- package/dist/commands/diff.js +294 -0
- package/dist/commands/flows.js +348 -0
- package/dist/commands/misc.js +528 -0
- package/dist/commands/plan.js +301 -0
- package/dist/commands/pull.js +511 -0
- package/dist/commands/runs.js +74 -0
- package/dist/commands/skills.js +131 -0
- package/dist/commands/verify.js +205 -0
- package/dist/config.js +125 -0
- package/dist/diff/agents.js +80 -0
- package/dist/diff/diff.js +983 -0
- package/dist/diff/flow.js +258 -0
- package/{src/diff/html.ts → dist/diff/html.js} +274 -322
- package/dist/diff/render.js +90 -0
- package/dist/model/payload.js +84 -0
- package/dist/model/tree.js +7 -0
- package/dist/model/volatile.js +54 -0
- package/dist/pipefy/agents.js +122 -0
- package/dist/pipefy/automations.js +155 -0
- package/dist/pipefy/capability.js +84 -0
- package/dist/pipefy/client.js +204 -0
- package/dist/pipefy/discovery.js +148 -0
- package/dist/pipefy/internal.js +315 -0
- package/dist/pipefy/ipaas.js +269 -0
- package/dist/pipefy/reconstruct.js +674 -0
- package/dist/pipefy/reference.js +172 -0
- package/dist/pipefy/snapshot.js +185 -0
- package/dist/pipefy/toolkit.js +158 -0
- package/dist/report/integrations.js +165 -0
- package/dist/report/run.js +355 -0
- package/dist/util/fsx.js +50 -0
- package/dist/util/git.js +25 -0
- package/dist/util/json.js +56 -0
- package/dist/util/log.js +69 -0
- package/dist/util/pool.js +42 -0
- package/dist/util/slug.js +23 -0
- package/dist/util/tui.js +287 -0
- package/dist/validate/index.js +86 -0
- package/dist/validate/integrity.js +370 -0
- package/dist/validate/reference.js +120 -0
- package/dist/validate/schema.js +278 -0
- package/dist/workspace/agents.js +245 -0
- package/{src/workspace/docs.ts → dist/workspace/docs.js} +367 -407
- package/dist/workspace/flows.js +149 -0
- package/dist/workspace/layout.js +146 -0
- package/dist/workspace/lock.js +83 -0
- package/dist/workspace/read.js +168 -0
- package/dist/workspace/reference.js +24 -0
- package/dist/workspace/stamp.js +234 -0
- package/dist/workspace/write.js +194 -0
- package/package.json +37 -35
- package/src/apply/adopt.ts +0 -150
- package/src/apply/agentops.ts +0 -71
- package/src/apply/compile.ts +0 -875
- package/src/apply/execute.ts +0 -336
- package/src/apply/flowops.ts +0 -399
- package/src/apply/idmap.ts +0 -241
- package/src/apply/mutations.ts +0 -955
- package/src/apply/registry.ts +0 -430
- package/src/apply/types.ts +0 -134
- package/src/cli/args.ts +0 -88
- package/src/cli.ts +0 -211
- package/src/codec/flow.ts +0 -199
- package/src/codec/pack.ts +0 -103
- package/src/codec/roundtrip.ts +0 -94
- package/src/codec/unpack.ts +0 -198
- package/src/commands/agents.ts +0 -184
- package/src/commands/apply.ts +0 -1144
- package/src/commands/context.ts +0 -119
- package/src/commands/create.ts +0 -79
- package/src/commands/diff.ts +0 -314
- package/src/commands/flows.ts +0 -414
- package/src/commands/misc.ts +0 -644
- package/src/commands/plan.ts +0 -331
- package/src/commands/pull.ts +0 -567
- package/src/commands/runs.ts +0 -83
- package/src/commands/skills.ts +0 -137
- package/src/commands/verify.ts +0 -253
- package/src/config.ts +0 -168
- package/src/diff/agents.ts +0 -122
- package/src/diff/diff.ts +0 -1130
- package/src/diff/flow.ts +0 -318
- package/src/diff/render.ts +0 -101
- package/src/model/payload.ts +0 -154
- package/src/model/tree.ts +0 -99
- package/src/model/volatile.ts +0 -55
- package/src/pipefy/agents.ts +0 -165
- package/src/pipefy/automations.ts +0 -219
- package/src/pipefy/capability.ts +0 -119
- package/src/pipefy/client.ts +0 -267
- package/src/pipefy/discovery.ts +0 -209
- package/src/pipefy/internal.ts +0 -380
- package/src/pipefy/ipaas.ts +0 -365
- package/src/pipefy/reconstruct.ts +0 -775
- package/src/pipefy/reference.ts +0 -251
- package/src/pipefy/snapshot.ts +0 -245
- package/src/pipefy/toolkit.ts +0 -200
- package/src/report/integrations.ts +0 -231
- package/src/report/run.ts +0 -475
- package/src/util/fsx.ts +0 -45
- package/src/util/git.ts +0 -32
- package/src/util/json.ts +0 -55
- package/src/util/log.ts +0 -76
- package/src/util/pool.ts +0 -48
- package/src/util/slug.ts +0 -26
- package/src/util/tui.ts +0 -335
- package/src/validate/index.ts +0 -123
- package/src/validate/integrity.ts +0 -387
- package/src/validate/reference.ts +0 -136
- package/src/validate/schema.ts +0 -328
- package/src/workspace/agents.ts +0 -290
- package/src/workspace/flows.ts +0 -191
- package/src/workspace/layout.ts +0 -165
- package/src/workspace/lock.ts +0 -148
- package/src/workspace/read.ts +0 -165
- package/src/workspace/reference.ts +0 -24
- package/src/workspace/stamp.ts +0 -301
- package/src/workspace/write.ts +0 -225
- /package/{src → dist}/pipefy/toolkit_bearer.py +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { debug } from "../util/log.js";
|
|
2
|
+
/**
|
|
3
|
+
* Id substitution — the single subtlest thing in the write path.
|
|
4
|
+
*
|
|
5
|
+
* Two jobs, both learned from the Change Migrator recipes:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Placeholders.** A new field has no id until it is created, so an
|
|
8
|
+
* automation created in the same plan references `%{_new:<key>}` and the
|
|
9
|
+
* executor swaps in the real id once the field exists. PLAN.md §9 flags
|
|
10
|
+
* that this "fails only on the combination create field + reference it in
|
|
11
|
+
* the same plan" — i.e. constantly.
|
|
12
|
+
*
|
|
13
|
+
* 2. **Cross-repo remapping.** Recipe step 120 rewrites every dev field id
|
|
14
|
+
* inside an automation's JSON to its prod equivalent, looking each one up
|
|
15
|
+
* through a Pipefy table with one API call per id. Same transformation
|
|
16
|
+
* here, from the map the diff already built, with no API calls.
|
|
17
|
+
*
|
|
18
|
+
* Ids hide inside opaque JSON: `"%{<fieldId>}"`, `"field_address": "<fieldId>"`,
|
|
19
|
+
* `"trigger_field_ids": ["<fieldId>"]`. So substitution walks the whole
|
|
20
|
+
* structure. `%{...}` is rewritten anywhere it appears; a bare id is rewritten
|
|
21
|
+
* only under a key known to hold one, because rewriting every number that
|
|
22
|
+
* happens to match an id would corrupt values that merely look like ids.
|
|
23
|
+
*/
|
|
24
|
+
/** Keys whose values are ids, and may therefore be remapped when bare. */
|
|
25
|
+
export const ID_BEARING_KEYS = new Set([
|
|
26
|
+
'field_address',
|
|
27
|
+
'field_id',
|
|
28
|
+
'fieldId',
|
|
29
|
+
'field_ids',
|
|
30
|
+
'fieldIds',
|
|
31
|
+
'phase_id',
|
|
32
|
+
'phaseId',
|
|
33
|
+
'phaseFieldId',
|
|
34
|
+
'to_phase_id',
|
|
35
|
+
'toPhaseId',
|
|
36
|
+
'from_phase_id',
|
|
37
|
+
'fromPhaseId',
|
|
38
|
+
'in_phase_id',
|
|
39
|
+
'inPhaseId',
|
|
40
|
+
'trigger_field_ids',
|
|
41
|
+
'triggerFieldIds',
|
|
42
|
+
'trigger_automation_id',
|
|
43
|
+
'triggerAutomationId',
|
|
44
|
+
'card_id',
|
|
45
|
+
'cardId',
|
|
46
|
+
'title_field_id',
|
|
47
|
+
'connected_pipe_id',
|
|
48
|
+
'connected_repo_id',
|
|
49
|
+
'submitter_email_field_id',
|
|
50
|
+
'email_template_id',
|
|
51
|
+
'source_id',
|
|
52
|
+
'owner_id',
|
|
53
|
+
'skills_ids',
|
|
54
|
+
'skillsIds',
|
|
55
|
+
'jump_target_ids',
|
|
56
|
+
'target_phase_id',
|
|
57
|
+
'source_phase_id',
|
|
58
|
+
// Id *lists* count too. Omitting fieldConditionIds meant a placeholder inside
|
|
59
|
+
// the array was never substituted and went to the API verbatim, which came
|
|
60
|
+
// back as "Invalid input: fieldConditionIds ([0])" — an error that says
|
|
61
|
+
// nothing about the real cause.
|
|
62
|
+
'fieldConditionIds',
|
|
63
|
+
'field_condition_ids',
|
|
64
|
+
/**
|
|
65
|
+
* The field ids an `update_card_field` automation writes, in order.
|
|
66
|
+
*
|
|
67
|
+
* Fourth omission from this list, and the most quietly damaging: nothing
|
|
68
|
+
* rejected it. `fields_map_order: ["%{433584976}"]` was stored by the API
|
|
69
|
+
* verbatim, braces and all. The automation was created, reported valid,
|
|
70
|
+
* verified clean, and selected **no fields to update** — because the UI and the
|
|
71
|
+
* engine read this list to know which fields the automation writes, and
|
|
72
|
+
* `"%{433584976}"` is not a field id. Every working automation in the org
|
|
73
|
+
* stores bare ids here.
|
|
74
|
+
*
|
|
75
|
+
* `field_map[].field_id` was substituted correctly the whole time, so the
|
|
76
|
+
* automation looked right in the workspace and did nothing on the pipe.
|
|
77
|
+
*/
|
|
78
|
+
'fields_map_order',
|
|
79
|
+
'fieldsMapOrder',
|
|
80
|
+
/**
|
|
81
|
+
* The internal settings endpoint's form key, brackets and all.
|
|
82
|
+
*
|
|
83
|
+
* Substitution is keyed on the *key name*, and this one is
|
|
84
|
+
* `phase[jump_target_ids][]` — nothing like the camel or snake spellings above.
|
|
85
|
+
* Without it a target naming a phase created in the same plan was rewritten to
|
|
86
|
+
* `%{344123894}` instead of `344123894`, and the endpoint answered 404 with no
|
|
87
|
+
* hint about which value it disliked. Third time this list has been the cause;
|
|
88
|
+
* `runInternalRestStep` now asserts on the value shape as well, so a fourth
|
|
89
|
+
* omission fails loudly instead.
|
|
90
|
+
*/
|
|
91
|
+
'phase[jump_target_ids][]',
|
|
92
|
+
'teamMemberIds',
|
|
93
|
+
'team_member_ids',
|
|
94
|
+
'phaseFieldIds',
|
|
95
|
+
]);
|
|
96
|
+
/**
|
|
97
|
+
* Captures the whole token including the `_new:` prefix, because that is the key
|
|
98
|
+
* placeholders are *stored* under (`placeholderFor` emits `_new:fields:<key>`).
|
|
99
|
+
* Capturing only the tail silently makes every lookup miss.
|
|
100
|
+
*/
|
|
101
|
+
const PLACEHOLDER_RE = /%\{(_new:[^}]+)\}/g;
|
|
102
|
+
const REFERENCE_RE = /%\{(\d+)\}/g;
|
|
103
|
+
export const placeholderFor = (entity, key) => `_new:${entity}:${key}`;
|
|
104
|
+
export const placeholderToken = (p) => `%{${p}}`;
|
|
105
|
+
export class IdMap {
|
|
106
|
+
/** placeholder → real id, filled in as creating steps succeed. */
|
|
107
|
+
placeholders = new Map();
|
|
108
|
+
/** old id → new id, for cross-repo migration. */
|
|
109
|
+
remap = new Map();
|
|
110
|
+
constructor(seed = {}) {
|
|
111
|
+
for (const [k, v] of Object.entries(seed))
|
|
112
|
+
this.remap.set(String(k), Number(v));
|
|
113
|
+
}
|
|
114
|
+
resolvePlaceholder(p, id, aliases = []) {
|
|
115
|
+
this.placeholders.set(p, id);
|
|
116
|
+
for (const a of aliases)
|
|
117
|
+
if (a)
|
|
118
|
+
this.placeholders.set(a, id);
|
|
119
|
+
debug(`resolved placeholder ${p}${aliases.length ? ` (+${aliases.length} alias)` : ''} -> ${id}`);
|
|
120
|
+
}
|
|
121
|
+
hasPlaceholder(p) {
|
|
122
|
+
return this.placeholders.has(p);
|
|
123
|
+
}
|
|
124
|
+
placeholderValue(p) {
|
|
125
|
+
return this.placeholders.get(p);
|
|
126
|
+
}
|
|
127
|
+
addRemap(oldId, newId) {
|
|
128
|
+
this.remap.set(String(oldId), newId);
|
|
129
|
+
}
|
|
130
|
+
lookup(id) {
|
|
131
|
+
return this.remap.get(String(id));
|
|
132
|
+
}
|
|
133
|
+
/** Which placeholders a value still depends on. Empty means it is ready to send. */
|
|
134
|
+
unresolved(value) {
|
|
135
|
+
const out = new Set();
|
|
136
|
+
const walk = (v) => {
|
|
137
|
+
if (typeof v === 'string') {
|
|
138
|
+
for (const m of v.matchAll(PLACEHOLDER_RE)) {
|
|
139
|
+
const key = m[1];
|
|
140
|
+
if (!this.placeholders.has(key))
|
|
141
|
+
out.add(key);
|
|
142
|
+
}
|
|
143
|
+
// A bare placeholder, as compile.ts emits for phase_id on a new field.
|
|
144
|
+
if (v.startsWith('_new:') && !this.placeholders.has(v))
|
|
145
|
+
out.add(v);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (Array.isArray(v)) {
|
|
149
|
+
v.forEach(walk);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (v && typeof v === 'object')
|
|
153
|
+
Object.values(v).forEach(walk);
|
|
154
|
+
};
|
|
155
|
+
walk(value);
|
|
156
|
+
return [...out];
|
|
157
|
+
}
|
|
158
|
+
rewriteString(s) {
|
|
159
|
+
let out = s.replace(PLACEHOLDER_RE, (whole, key) => {
|
|
160
|
+
const id = this.placeholders.get(key);
|
|
161
|
+
return id === undefined ? whole : `%{${id}}`;
|
|
162
|
+
});
|
|
163
|
+
out = out.replace(REFERENCE_RE, (whole, id) => {
|
|
164
|
+
const mapped = this.remap.get(id);
|
|
165
|
+
return mapped === undefined ? whole : `%{${mapped}}`;
|
|
166
|
+
});
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
/** A bare id value, remapped if it is under an id-bearing key. */
|
|
170
|
+
rewriteBare(v) {
|
|
171
|
+
if (typeof v === 'number') {
|
|
172
|
+
const mapped = this.remap.get(String(v));
|
|
173
|
+
return mapped ?? v;
|
|
174
|
+
}
|
|
175
|
+
if (typeof v === 'string') {
|
|
176
|
+
if (/^_new:/.test(v)) {
|
|
177
|
+
const id = this.placeholders.get(v);
|
|
178
|
+
return id === undefined ? v : String(id);
|
|
179
|
+
}
|
|
180
|
+
if (/^\d+$/.test(v)) {
|
|
181
|
+
const mapped = this.remap.get(v);
|
|
182
|
+
return mapped === undefined ? v : String(mapped);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* A value under an id-bearing key that is *entirely* one reference is an
|
|
186
|
+
* id, not a template: `"phase_id": "%{_new:<uuid>}"` must become `"344…"`,
|
|
187
|
+
* not `"%{344…}"`. Only `createFieldCondition` and friends care, but they
|
|
188
|
+
* care absolutely — a braced id is rejected as a malformed ID.
|
|
189
|
+
*/
|
|
190
|
+
const whole = /^%\{(_new:[^}]+|\d+)\}$/.exec(v);
|
|
191
|
+
if (whole) {
|
|
192
|
+
const key = whole[1];
|
|
193
|
+
const resolved = key.startsWith('_new:') ? this.placeholders.get(key) : this.remap.get(key);
|
|
194
|
+
if (resolved !== undefined)
|
|
195
|
+
return String(resolved);
|
|
196
|
+
// A numeric reference with no remapping is already the id it names.
|
|
197
|
+
if (!key.startsWith('_new:'))
|
|
198
|
+
return key;
|
|
199
|
+
return v;
|
|
200
|
+
}
|
|
201
|
+
return this.rewriteString(v);
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(v))
|
|
204
|
+
return v.map((x) => this.rewriteBare(x));
|
|
205
|
+
return v;
|
|
206
|
+
}
|
|
207
|
+
/** Deep-rewrite a request payload. Returns a new value; the input is untouched. */
|
|
208
|
+
rewrite(value) {
|
|
209
|
+
const walk = (v, keyIsIdBearing) => {
|
|
210
|
+
if (typeof v === 'string')
|
|
211
|
+
return keyIsIdBearing ? this.rewriteBare(v) : this.rewriteString(v);
|
|
212
|
+
if (typeof v === 'number')
|
|
213
|
+
return keyIsIdBearing ? this.rewriteBare(v) : v;
|
|
214
|
+
if (Array.isArray(v))
|
|
215
|
+
return v.map((x) => walk(x, keyIsIdBearing));
|
|
216
|
+
if (v && typeof v === 'object') {
|
|
217
|
+
const out = {};
|
|
218
|
+
for (const [k, val] of Object.entries(v)) {
|
|
219
|
+
out[k] = walk(val, ID_BEARING_KEYS.has(k));
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
return v;
|
|
224
|
+
};
|
|
225
|
+
return walk(value, false);
|
|
226
|
+
}
|
|
227
|
+
snapshot() {
|
|
228
|
+
return {
|
|
229
|
+
placeholders: Object.fromEntries(this.placeholders),
|
|
230
|
+
remap: Object.fromEntries(this.remap),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|