@pipefy/pipefy-process-coder 0.1.0 → 0.1.2

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 (162) 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 +476 -456
  20. package/LICENSE +202 -0
  21. package/NOTICE +11 -0
  22. package/README.md +830 -808
  23. package/bin/pipe.js +25 -4
  24. package/dist/apply/adopt.js +128 -0
  25. package/dist/apply/agentops.js +42 -0
  26. package/dist/apply/compile.js +722 -0
  27. package/dist/apply/execute.js +277 -0
  28. package/dist/apply/flowops.js +293 -0
  29. package/dist/apply/idmap.js +233 -0
  30. package/dist/apply/mutations.js +704 -0
  31. package/dist/apply/registry.js +348 -0
  32. package/dist/apply/types.js +18 -0
  33. package/dist/cli/args.js +79 -0
  34. package/dist/cli.js +196 -0
  35. package/dist/codec/flow.js +164 -0
  36. package/dist/codec/pack.js +88 -0
  37. package/dist/codec/roundtrip.js +86 -0
  38. package/dist/codec/unpack.js +181 -0
  39. package/dist/commands/agents.js +145 -0
  40. package/dist/commands/apply.js +982 -0
  41. package/dist/commands/context.js +79 -0
  42. package/dist/commands/create.js +63 -0
  43. package/dist/commands/diff.js +294 -0
  44. package/dist/commands/flows.js +348 -0
  45. package/dist/commands/misc.js +562 -0
  46. package/dist/commands/plan.js +301 -0
  47. package/dist/commands/pull.js +549 -0
  48. package/dist/commands/runs.js +74 -0
  49. package/dist/commands/skills.js +131 -0
  50. package/dist/commands/verify.js +205 -0
  51. package/dist/config.js +125 -0
  52. package/dist/diff/agents.js +80 -0
  53. package/dist/diff/diff.js +983 -0
  54. package/dist/diff/flow.js +258 -0
  55. package/{src/diff/html.ts → dist/diff/html.js} +274 -322
  56. package/dist/diff/render.js +90 -0
  57. package/dist/model/payload.js +84 -0
  58. package/dist/model/tree.js +7 -0
  59. package/dist/model/volatile.js +54 -0
  60. package/dist/pipefy/agents.js +131 -0
  61. package/dist/pipefy/automations.js +155 -0
  62. package/dist/pipefy/capability.js +84 -0
  63. package/dist/pipefy/client.js +204 -0
  64. package/dist/pipefy/discovery.js +148 -0
  65. package/dist/pipefy/internal.js +406 -0
  66. package/dist/pipefy/ipaas.js +269 -0
  67. package/dist/pipefy/reconstruct.js +676 -0
  68. package/dist/pipefy/reference.js +172 -0
  69. package/dist/pipefy/snapshot.js +185 -0
  70. package/dist/pipefy/toolkit.js +174 -0
  71. package/{src → dist}/pipefy/toolkit_bearer.py +60 -14
  72. package/dist/report/integrations.js +165 -0
  73. package/dist/report/run.js +356 -0
  74. package/dist/util/fsx.js +50 -0
  75. package/dist/util/git.js +25 -0
  76. package/dist/util/json.js +56 -0
  77. package/dist/util/log.js +69 -0
  78. package/dist/util/pool.js +42 -0
  79. package/dist/util/slug.js +23 -0
  80. package/dist/util/tui.js +287 -0
  81. package/dist/validate/index.js +86 -0
  82. package/dist/validate/integrity.js +370 -0
  83. package/dist/validate/reference.js +120 -0
  84. package/dist/validate/schema.js +278 -0
  85. package/dist/version.js +18 -0
  86. package/dist/workspace/agents.js +245 -0
  87. package/{src/workspace/docs.ts → dist/workspace/docs.js} +367 -407
  88. package/dist/workspace/flows.js +149 -0
  89. package/dist/workspace/layout.js +146 -0
  90. package/dist/workspace/lock.js +83 -0
  91. package/dist/workspace/read.js +168 -0
  92. package/dist/workspace/reference.js +24 -0
  93. package/dist/workspace/stamp.js +234 -0
  94. package/dist/workspace/write.js +194 -0
  95. package/package.json +38 -35
  96. package/src/apply/adopt.ts +0 -150
  97. package/src/apply/agentops.ts +0 -71
  98. package/src/apply/compile.ts +0 -875
  99. package/src/apply/execute.ts +0 -336
  100. package/src/apply/flowops.ts +0 -399
  101. package/src/apply/idmap.ts +0 -241
  102. package/src/apply/mutations.ts +0 -955
  103. package/src/apply/registry.ts +0 -430
  104. package/src/apply/types.ts +0 -134
  105. package/src/cli/args.ts +0 -88
  106. package/src/cli.ts +0 -211
  107. package/src/codec/flow.ts +0 -199
  108. package/src/codec/pack.ts +0 -103
  109. package/src/codec/roundtrip.ts +0 -94
  110. package/src/codec/unpack.ts +0 -198
  111. package/src/commands/agents.ts +0 -184
  112. package/src/commands/apply.ts +0 -1144
  113. package/src/commands/context.ts +0 -119
  114. package/src/commands/create.ts +0 -79
  115. package/src/commands/diff.ts +0 -314
  116. package/src/commands/flows.ts +0 -414
  117. package/src/commands/misc.ts +0 -644
  118. package/src/commands/plan.ts +0 -331
  119. package/src/commands/pull.ts +0 -567
  120. package/src/commands/runs.ts +0 -83
  121. package/src/commands/skills.ts +0 -137
  122. package/src/commands/verify.ts +0 -253
  123. package/src/config.ts +0 -168
  124. package/src/diff/agents.ts +0 -122
  125. package/src/diff/diff.ts +0 -1130
  126. package/src/diff/flow.ts +0 -318
  127. package/src/diff/render.ts +0 -101
  128. package/src/model/payload.ts +0 -154
  129. package/src/model/tree.ts +0 -99
  130. package/src/model/volatile.ts +0 -55
  131. package/src/pipefy/agents.ts +0 -165
  132. package/src/pipefy/automations.ts +0 -219
  133. package/src/pipefy/capability.ts +0 -119
  134. package/src/pipefy/client.ts +0 -267
  135. package/src/pipefy/discovery.ts +0 -209
  136. package/src/pipefy/internal.ts +0 -380
  137. package/src/pipefy/ipaas.ts +0 -365
  138. package/src/pipefy/reconstruct.ts +0 -775
  139. package/src/pipefy/reference.ts +0 -251
  140. package/src/pipefy/snapshot.ts +0 -245
  141. package/src/pipefy/toolkit.ts +0 -200
  142. package/src/report/integrations.ts +0 -231
  143. package/src/report/run.ts +0 -475
  144. package/src/util/fsx.ts +0 -45
  145. package/src/util/git.ts +0 -32
  146. package/src/util/json.ts +0 -55
  147. package/src/util/log.ts +0 -76
  148. package/src/util/pool.ts +0 -48
  149. package/src/util/slug.ts +0 -26
  150. package/src/util/tui.ts +0 -335
  151. package/src/validate/index.ts +0 -123
  152. package/src/validate/integrity.ts +0 -387
  153. package/src/validate/reference.ts +0 -136
  154. package/src/validate/schema.ts +0 -328
  155. package/src/workspace/agents.ts +0 -290
  156. package/src/workspace/flows.ts +0 -191
  157. package/src/workspace/layout.ts +0 -165
  158. package/src/workspace/lock.ts +0 -148
  159. package/src/workspace/read.ts +0 -165
  160. package/src/workspace/reference.ts +0 -24
  161. package/src/workspace/stamp.ts +0 -301
  162. package/src/workspace/write.ts +0 -225
@@ -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
+ }