@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.
Files changed (159) hide show
  1. package/.agents/skills/ppc-pipefy-flow-authoring/SKILL.md +262 -262
  2. package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-danfe-consulta.json +247 -247
  3. package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-webhook-retorno-consulta.json +589 -589
  4. package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-4-recebimento-barramento.json +1391 -1391
  5. package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-2-danfe-retorno.json +623 -623
  6. package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-4-criacao-operacao.json +636 -636
  7. package/.agents/skills/ppc-pipefy-flow-authoring/examples/03-subflow-4-criacao-titulo.json +3642 -3642
  8. package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-cedente.json +863 -863
  9. package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-sacado.json +799 -799
  10. package/.agents/skills/ppc-pipefy-flow-authoring/examples/README.md +42 -42
  11. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-acompanhamento-cobranca.json +581 -581
  12. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-nfe-monitoramento.json +503 -503
  13. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-retorno-bancario.json +562 -562
  14. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-cedente.json +557 -557
  15. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-sacado.json +609 -609
  16. package/.agents/skills/ppc-pipefy-pipe-authoring/SKILL.md +146 -146
  17. package/.agents/skills/ppc-pipefy-process-design/SKILL.md +127 -127
  18. package/.agents/skills/ppc-pipefy-workspace/SKILL.md +91 -91
  19. package/AGENTS.md +465 -456
  20. package/README.md +825 -807
  21. package/bin/pipe.js +25 -4
  22. package/dist/apply/adopt.js +128 -0
  23. package/dist/apply/agentops.js +42 -0
  24. package/dist/apply/compile.js +722 -0
  25. package/dist/apply/execute.js +277 -0
  26. package/dist/apply/flowops.js +293 -0
  27. package/dist/apply/idmap.js +233 -0
  28. package/dist/apply/mutations.js +704 -0
  29. package/dist/apply/registry.js +348 -0
  30. package/dist/apply/types.js +18 -0
  31. package/dist/cli/args.js +79 -0
  32. package/dist/cli.js +187 -0
  33. package/dist/codec/flow.js +164 -0
  34. package/dist/codec/pack.js +88 -0
  35. package/dist/codec/roundtrip.js +86 -0
  36. package/dist/codec/unpack.js +181 -0
  37. package/dist/commands/agents.js +145 -0
  38. package/dist/commands/apply.js +982 -0
  39. package/dist/commands/context.js +79 -0
  40. package/dist/commands/create.js +63 -0
  41. package/dist/commands/diff.js +294 -0
  42. package/dist/commands/flows.js +348 -0
  43. package/dist/commands/misc.js +528 -0
  44. package/dist/commands/plan.js +301 -0
  45. package/dist/commands/pull.js +511 -0
  46. package/dist/commands/runs.js +74 -0
  47. package/dist/commands/skills.js +131 -0
  48. package/dist/commands/verify.js +205 -0
  49. package/dist/config.js +125 -0
  50. package/dist/diff/agents.js +80 -0
  51. package/dist/diff/diff.js +983 -0
  52. package/dist/diff/flow.js +258 -0
  53. package/{src/diff/html.ts → dist/diff/html.js} +274 -322
  54. package/dist/diff/render.js +90 -0
  55. package/dist/model/payload.js +84 -0
  56. package/dist/model/tree.js +7 -0
  57. package/dist/model/volatile.js +54 -0
  58. package/dist/pipefy/agents.js +122 -0
  59. package/dist/pipefy/automations.js +155 -0
  60. package/dist/pipefy/capability.js +84 -0
  61. package/dist/pipefy/client.js +204 -0
  62. package/dist/pipefy/discovery.js +148 -0
  63. package/dist/pipefy/internal.js +315 -0
  64. package/dist/pipefy/ipaas.js +269 -0
  65. package/dist/pipefy/reconstruct.js +674 -0
  66. package/dist/pipefy/reference.js +172 -0
  67. package/dist/pipefy/snapshot.js +185 -0
  68. package/dist/pipefy/toolkit.js +158 -0
  69. package/dist/report/integrations.js +165 -0
  70. package/dist/report/run.js +355 -0
  71. package/dist/util/fsx.js +50 -0
  72. package/dist/util/git.js +25 -0
  73. package/dist/util/json.js +56 -0
  74. package/dist/util/log.js +69 -0
  75. package/dist/util/pool.js +42 -0
  76. package/dist/util/slug.js +23 -0
  77. package/dist/util/tui.js +287 -0
  78. package/dist/validate/index.js +86 -0
  79. package/dist/validate/integrity.js +370 -0
  80. package/dist/validate/reference.js +120 -0
  81. package/dist/validate/schema.js +278 -0
  82. package/dist/workspace/agents.js +245 -0
  83. package/{src/workspace/docs.ts → dist/workspace/docs.js} +367 -407
  84. package/dist/workspace/flows.js +149 -0
  85. package/dist/workspace/layout.js +146 -0
  86. package/dist/workspace/lock.js +83 -0
  87. package/dist/workspace/read.js +168 -0
  88. package/dist/workspace/reference.js +24 -0
  89. package/dist/workspace/stamp.js +234 -0
  90. package/dist/workspace/write.js +194 -0
  91. package/package.json +37 -35
  92. package/src/apply/adopt.ts +0 -150
  93. package/src/apply/agentops.ts +0 -71
  94. package/src/apply/compile.ts +0 -875
  95. package/src/apply/execute.ts +0 -336
  96. package/src/apply/flowops.ts +0 -399
  97. package/src/apply/idmap.ts +0 -241
  98. package/src/apply/mutations.ts +0 -955
  99. package/src/apply/registry.ts +0 -430
  100. package/src/apply/types.ts +0 -134
  101. package/src/cli/args.ts +0 -88
  102. package/src/cli.ts +0 -211
  103. package/src/codec/flow.ts +0 -199
  104. package/src/codec/pack.ts +0 -103
  105. package/src/codec/roundtrip.ts +0 -94
  106. package/src/codec/unpack.ts +0 -198
  107. package/src/commands/agents.ts +0 -184
  108. package/src/commands/apply.ts +0 -1144
  109. package/src/commands/context.ts +0 -119
  110. package/src/commands/create.ts +0 -79
  111. package/src/commands/diff.ts +0 -314
  112. package/src/commands/flows.ts +0 -414
  113. package/src/commands/misc.ts +0 -644
  114. package/src/commands/plan.ts +0 -331
  115. package/src/commands/pull.ts +0 -567
  116. package/src/commands/runs.ts +0 -83
  117. package/src/commands/skills.ts +0 -137
  118. package/src/commands/verify.ts +0 -253
  119. package/src/config.ts +0 -168
  120. package/src/diff/agents.ts +0 -122
  121. package/src/diff/diff.ts +0 -1130
  122. package/src/diff/flow.ts +0 -318
  123. package/src/diff/render.ts +0 -101
  124. package/src/model/payload.ts +0 -154
  125. package/src/model/tree.ts +0 -99
  126. package/src/model/volatile.ts +0 -55
  127. package/src/pipefy/agents.ts +0 -165
  128. package/src/pipefy/automations.ts +0 -219
  129. package/src/pipefy/capability.ts +0 -119
  130. package/src/pipefy/client.ts +0 -267
  131. package/src/pipefy/discovery.ts +0 -209
  132. package/src/pipefy/internal.ts +0 -380
  133. package/src/pipefy/ipaas.ts +0 -365
  134. package/src/pipefy/reconstruct.ts +0 -775
  135. package/src/pipefy/reference.ts +0 -251
  136. package/src/pipefy/snapshot.ts +0 -245
  137. package/src/pipefy/toolkit.ts +0 -200
  138. package/src/report/integrations.ts +0 -231
  139. package/src/report/run.ts +0 -475
  140. package/src/util/fsx.ts +0 -45
  141. package/src/util/git.ts +0 -32
  142. package/src/util/json.ts +0 -55
  143. package/src/util/log.ts +0 -76
  144. package/src/util/pool.ts +0 -48
  145. package/src/util/slug.ts +0 -26
  146. package/src/util/tui.ts +0 -335
  147. package/src/validate/index.ts +0 -123
  148. package/src/validate/integrity.ts +0 -387
  149. package/src/validate/reference.ts +0 -136
  150. package/src/validate/schema.ts +0 -328
  151. package/src/workspace/agents.ts +0 -290
  152. package/src/workspace/flows.ts +0 -191
  153. package/src/workspace/layout.ts +0 -165
  154. package/src/workspace/lock.ts +0 -148
  155. package/src/workspace/read.ts +0 -165
  156. package/src/workspace/reference.ts +0 -24
  157. package/src/workspace/stamp.ts +0 -301
  158. package/src/workspace/write.ts +0 -225
  159. /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
+ }