codymaster 4.6.0 → 5.2.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 (161) hide show
  1. package/CHANGELOG.md +74 -8
  2. package/README.md +192 -95
  3. package/dist/advisory-handoff.js +89 -0
  4. package/dist/advisory-report.js +105 -0
  5. package/dist/browse-server.js +251 -0
  6. package/dist/cli/command-registry.js +34 -0
  7. package/dist/cli/commands/agent.js +120 -0
  8. package/dist/cli/commands/bench.js +69 -0
  9. package/dist/cli/commands/brain.js +108 -0
  10. package/dist/cli/commands/dashboard.js +93 -0
  11. package/dist/cli/commands/design-studio.js +111 -0
  12. package/dist/cli/commands/distro.js +25 -0
  13. package/dist/cli/commands/engineering.js +596 -0
  14. package/dist/cli/commands/evolve.js +123 -0
  15. package/dist/cli/commands/mcp-serve.js +104 -0
  16. package/dist/cli/commands/project.js +324 -0
  17. package/dist/cli/commands/skill-chain.js +269 -0
  18. package/dist/cli/commands/system.js +89 -0
  19. package/dist/cli/commands/task.js +254 -0
  20. package/dist/cli/update-check.js +83 -0
  21. package/dist/cm-config.js +92 -0
  22. package/dist/cm-suggest.js +77 -0
  23. package/dist/codybench/judges/automated.js +31 -0
  24. package/dist/codybench/runners/claude-code.js +32 -0
  25. package/dist/codybench/suites/memory-retention.js +85 -0
  26. package/dist/codybench/suites/tdd-regression.js +35 -0
  27. package/dist/codybench/suites/token-efficiency.js +55 -0
  28. package/dist/codybench/types.js +2 -0
  29. package/dist/context-db.js +157 -0
  30. package/dist/continuity.js +2 -6
  31. package/dist/distro-validate.js +54 -0
  32. package/dist/execution-analyzer.js +138 -0
  33. package/dist/guardian-core.js +74 -0
  34. package/dist/index.js +36 -2759
  35. package/dist/indexer/skills-lib.js +533 -0
  36. package/dist/indexer/skills-map.js +1374 -0
  37. package/dist/indexer/skills.js +16 -0
  38. package/dist/learning-promoter.js +246 -0
  39. package/dist/mcp-context-server.js +289 -1
  40. package/dist/mcp-skills-tools.js +81 -0
  41. package/dist/retro-summary.js +70 -0
  42. package/dist/second-opinion-providers.js +79 -0
  43. package/dist/skill-chain.js +63 -1
  44. package/dist/skill-evolver.js +456 -0
  45. package/dist/skill-execution-cache.js +254 -0
  46. package/dist/smart-brain-router.js +184 -0
  47. package/dist/sprint-pipeline.js +228 -0
  48. package/dist/storage-backend.js +14 -67
  49. package/dist/token-budget.js +88 -0
  50. package/dist/utils/cli-utils.js +76 -0
  51. package/dist/utils/skill-utils.js +32 -0
  52. package/package.json +17 -7
  53. package/scripts/build-skills.mjs +51 -0
  54. package/scripts/gate-0-repo-hygiene.js +75 -0
  55. package/scripts/postinstall.js +34 -28
  56. package/scripts/security-scan.js +1 -1
  57. package/scripts/validate-skills.mjs +42 -0
  58. package/skills/CLAUDE.md +2 -7
  59. package/skills/_shared/helpers.md +2 -8
  60. package/skills/cm-ads-tracker/SKILL.md +3 -6
  61. package/skills/cm-browse/SKILL.md +34 -0
  62. package/skills/cm-conductor-worktrees/SKILL.md +28 -0
  63. package/skills/cm-content-factory/SKILL.md +1 -1
  64. package/skills/cm-content-factory/landing/docs/content/changelog.md +36 -0
  65. package/skills/cm-content-factory/landing/docs/content/deployment.md +46 -0
  66. package/skills/cm-content-factory/landing/docs/content/execution-flow.md +67 -0
  67. package/skills/cm-content-factory/landing/docs/content/memory-system.md +38 -0
  68. package/skills/cm-content-factory/landing/docs/content/openspace.md +27 -0
  69. package/skills/cm-content-factory/landing/docs/content/use-cases.md +26 -0
  70. package/skills/cm-content-factory/landing/docs/content/v5-intro.md +28 -0
  71. package/skills/cm-content-factory/landing/docs/index.html +240 -0
  72. package/skills/cm-content-factory/landing/index.html +100 -100
  73. package/skills/cm-content-factory/landing/script.js +42 -0
  74. package/skills/cm-content-factory/landing/translations.js +400 -400
  75. package/skills/cm-continuity/SKILL.md +32 -33
  76. package/skills/cm-design-studio/SKILL.md +34 -0
  77. package/skills/cm-ecosystem-roadmap/SKILL.md +15 -0
  78. package/skills/cm-engineering-meta/SKILL.md +73 -0
  79. package/skills/cm-growth-hacking/SKILL.md +1 -12
  80. package/skills/cm-guardian-runtime/SKILL.md +26 -0
  81. package/skills/cm-mcp-engineering/SKILL.md +22 -0
  82. package/skills/cm-notebooklm/SKILL.md +1 -17
  83. package/skills/cm-post-deploy-canary/SKILL.md +22 -0
  84. package/skills/cm-project-bootstrap/SKILL.md +11 -0
  85. package/skills/cm-qa-visual-cli/SKILL.md +22 -0
  86. package/skills/cm-retro-cli/SKILL.md +23 -0
  87. package/skills/cm-second-opinion-cli/SKILL.md +23 -0
  88. package/skills/cm-secret-shield/SKILL.md +2 -2
  89. package/skills/cm-security-gate/SKILL.md +1 -0
  90. package/skills/cm-skill-chain/SKILL.md +25 -4
  91. package/skills/cm-skill-evolution/SKILL.md +83 -0
  92. package/skills/cm-skill-health/SKILL.md +83 -0
  93. package/skills/cm-skill-index/SKILL.md +11 -3
  94. package/skills/cm-skill-search/SKILL.md +49 -0
  95. package/skills/cm-skill-share/SKILL.md +58 -0
  96. package/skills/cm-sprint-bus/SKILL.md +33 -0
  97. package/skills/cm-start/SKILL.md +0 -10
  98. package/skills/cm-tdd/SKILL.md +59 -72
  99. package/skills/profiles/README.md +21 -0
  100. package/skills/profiles/core.txt +23 -0
  101. package/skills/profiles/design.txt +6 -0
  102. package/skills/profiles/full.txt +62 -0
  103. package/skills/profiles/growth.txt +10 -0
  104. package/skills/profiles/knowledge.txt +7 -0
  105. package/install.sh +0 -901
  106. package/scripts/test-gemini.js +0 -13
  107. package/skills/cm-frappe-agent/SKILL.md +0 -134
  108. package/skills/cm-frappe-agent/agents/doctype-architect.md +0 -596
  109. package/skills/cm-frappe-agent/agents/erpnext-customizer.md +0 -643
  110. package/skills/cm-frappe-agent/agents/frappe-backend.md +0 -814
  111. package/skills/cm-frappe-agent/agents/frappe-custom-frontend.md +0 -557
  112. package/skills/cm-frappe-agent/agents/frappe-debugger.md +0 -625
  113. package/skills/cm-frappe-agent/agents/frappe-fixer.md +0 -275
  114. package/skills/cm-frappe-agent/agents/frappe-frontend.md +0 -660
  115. package/skills/cm-frappe-agent/agents/frappe-installer.md +0 -158
  116. package/skills/cm-frappe-agent/agents/frappe-performance.md +0 -307
  117. package/skills/cm-frappe-agent/agents/frappe-planner.md +0 -419
  118. package/skills/cm-frappe-agent/agents/frappe-remote-ops.md +0 -153
  119. package/skills/cm-frappe-agent/agents/github-workflow.md +0 -286
  120. package/skills/cm-frappe-agent/commands/frappe-app.md +0 -351
  121. package/skills/cm-frappe-agent/commands/frappe-backend.md +0 -162
  122. package/skills/cm-frappe-agent/commands/frappe-bench.md +0 -254
  123. package/skills/cm-frappe-agent/commands/frappe-debug.md +0 -263
  124. package/skills/cm-frappe-agent/commands/frappe-doctype-create.md +0 -272
  125. package/skills/cm-frappe-agent/commands/frappe-doctype-field.md +0 -310
  126. package/skills/cm-frappe-agent/commands/frappe-erpnext.md +0 -210
  127. package/skills/cm-frappe-agent/commands/frappe-fix.md +0 -59
  128. package/skills/cm-frappe-agent/commands/frappe-frontend.md +0 -210
  129. package/skills/cm-frappe-agent/commands/frappe-fullstack.md +0 -243
  130. package/skills/cm-frappe-agent/commands/frappe-github.md +0 -57
  131. package/skills/cm-frappe-agent/commands/frappe-install.md +0 -52
  132. package/skills/cm-frappe-agent/commands/frappe-plan.md +0 -442
  133. package/skills/cm-frappe-agent/commands/frappe-remote.md +0 -58
  134. package/skills/cm-frappe-agent/commands/frappe-test.md +0 -356
  135. package/skills/cm-frappe-agent/docs/README.md +0 -51
  136. package/skills/cm-frappe-agent/docs/agents-catalog.md +0 -113
  137. package/skills/cm-frappe-agent/docs/architecture.md +0 -149
  138. package/skills/cm-frappe-agent/docs/commands-catalog.md +0 -82
  139. package/skills/cm-frappe-agent/docs/resources-catalog.md +0 -66
  140. package/skills/cm-frappe-agent/docs/sitemap-urls.txt +0 -52
  141. package/skills/cm-frappe-agent/docs/sitemap.md +0 -81
  142. package/skills/cm-frappe-agent/docs/sop/user-guide.md +0 -178
  143. package/skills/cm-frappe-agent/docs/sop/vibe-coding-guide.md +0 -122
  144. package/skills/cm-frappe-agent/resources/7-layer-architecture.md +0 -985
  145. package/skills/cm-frappe-agent/resources/bench_commands.md +0 -73
  146. package/skills/cm-frappe-agent/resources/code-patterns-guide.md +0 -948
  147. package/skills/cm-frappe-agent/resources/common_pitfalls.md +0 -266
  148. package/skills/cm-frappe-agent/resources/doctype-registry.md +0 -158
  149. package/skills/cm-frappe-agent/resources/installation-guide.md +0 -289
  150. package/skills/cm-frappe-agent/resources/rest-api-patterns.md +0 -182
  151. package/skills/cm-frappe-agent/resources/scaffold_checklist.md +0 -82
  152. package/skills/cm-frappe-agent/resources/upgrade_patterns.md +0 -113
  153. package/skills/cm-frappe-agent/resources/web-form-patterns.md +0 -252
  154. package/skills/cm-frappe-agent/skills/bench-commands/SKILL.md +0 -621
  155. package/skills/cm-frappe-agent/skills/client-scripts/SKILL.md +0 -642
  156. package/skills/cm-frappe-agent/skills/doctype-patterns/SKILL.md +0 -576
  157. package/skills/cm-frappe-agent/skills/frappe-api/SKILL.md +0 -740
  158. package/skills/cm-frappe-agent/skills/remote-operations/SKILL.md +0 -47
  159. package/skills/cm-frappe-agent/skills/server-scripts/SKILL.md +0 -608
  160. package/skills/cm-frappe-agent/skills/web-forms/SKILL.md +0 -46
  161. package/skills/frappe-app-builder.zip +0 -0
@@ -1,642 +0,0 @@
1
- ---
2
- name: client-scripts
3
- description: Frappe client-side JavaScript patterns for form events, field manipulation, dialogs, and UI customization. Use when writing form scripts, handling field changes, creating dialogs, or customizing the Frappe desk interface.
4
- ---
5
-
6
- # Frappe Client Scripts Reference
7
-
8
- Complete reference for client-side JavaScript development in Frappe Framework.
9
-
10
- ## When to Use This Skill
11
-
12
- - Writing form scripts (refresh, validate, field events)
13
- - Manipulating form fields (show/hide, require, read-only)
14
- - Creating dialogs and prompts
15
- - Making API calls from client
16
- - Customizing list views
17
- - Adding custom buttons
18
- - Handling child table events
19
-
20
- ## Form Script Location
21
-
22
- ```
23
- my_app/
24
- └── my_module/
25
- └── doctype/
26
- └── my_doctype/
27
- └── my_doctype.js # Client script
28
- ```
29
-
30
- ## Form Events
31
-
32
- ### Complete Event Reference
33
-
34
- ```javascript
35
- frappe.ui.form.on('My DocType', {
36
- // === LOAD EVENTS ===
37
-
38
- setup: function(frm) {
39
- // Called once when form is created (before data loads)
40
- // Use for: setting queries, initializing variables
41
- frm.set_query('customer', () => ({ filters: { status: 'Active' } }));
42
- },
43
-
44
- onload: function(frm) {
45
- // Called when form data is loaded (before refresh)
46
- // Use for: setting defaults for new docs
47
- if (frm.is_new()) {
48
- frm.set_value('posting_date', frappe.datetime.nowdate());
49
- }
50
- },
51
-
52
- onload_post_render: function(frm) {
53
- // Called after form is rendered
54
- // Use for: DOM manipulation, focus setting
55
- frm.get_field('customer').focus();
56
- },
57
-
58
- refresh: function(frm) {
59
- // Called every time form refreshes
60
- // Use for: custom buttons, field toggles, indicators
61
- if (!frm.is_new()) {
62
- frm.add_custom_button(__('Action'), () => do_action(frm));
63
- }
64
- frm.toggle_display('section_name', frm.doc.show_section);
65
- },
66
-
67
- // === SAVE EVENTS ===
68
-
69
- validate: function(frm) {
70
- // Called before save - return false to prevent
71
- if (frm.doc.end_date < frm.doc.start_date) {
72
- frappe.msgprint(__('End Date cannot be before Start Date'));
73
- return false;
74
- }
75
- },
76
-
77
- before_save: function(frm) {
78
- // Called after validate, before server request
79
- frm.doc.last_updated_by = frappe.session.user;
80
- },
81
-
82
- after_save: function(frm) {
83
- // Called after successful save
84
- frappe.show_alert({
85
- message: __('Saved successfully'),
86
- indicator: 'green'
87
- });
88
- },
89
-
90
- // === WORKFLOW EVENTS ===
91
-
92
- before_submit: function(frm) {
93
- // Called before document submission
94
- },
95
-
96
- on_submit: function(frm) {
97
- // Called after successful submission
98
- },
99
-
100
- before_cancel: function(frm) {
101
- // Called before cancellation
102
- },
103
-
104
- after_cancel: function(frm) {
105
- // Called after cancellation
106
- },
107
-
108
- // === FIELD EVENTS ===
109
-
110
- customer: function(frm) {
111
- // Called when 'customer' field changes
112
- if (frm.doc.customer) {
113
- fetch_customer_details(frm);
114
- }
115
- },
116
-
117
- posting_date: function(frm) {
118
- // Called when 'posting_date' field changes
119
- calculate_due_date(frm);
120
- }
121
- });
122
- ```
123
-
124
- ## Field Manipulation
125
-
126
- ### Display Properties
127
-
128
- ```javascript
129
- // Show/hide field
130
- frm.toggle_display('fieldname', true); // Show
131
- frm.toggle_display('fieldname', false); // Hide
132
- frm.toggle_display(['field1', 'field2'], condition);
133
-
134
- // Set read-only
135
- frm.set_df_property('fieldname', 'read_only', 1);
136
- frm.toggle_enable('fieldname', false); // Disable
137
-
138
- // Set required
139
- frm.set_df_property('fieldname', 'reqd', 1);
140
- frm.toggle_reqd('fieldname', true);
141
- frm.toggle_reqd(['field1', 'field2'], condition);
142
-
143
- // Set hidden
144
- frm.set_df_property('fieldname', 'hidden', 1);
145
-
146
- // Change label
147
- frm.set_df_property('fieldname', 'label', 'New Label');
148
-
149
- // Change description
150
- frm.set_df_property('fieldname', 'description', 'Help text');
151
-
152
- // Change options (for Select)
153
- frm.set_df_property('fieldname', 'options', 'Option1\nOption2\nOption3');
154
-
155
- // Refresh after changes
156
- frm.refresh_field('fieldname');
157
- frm.refresh_fields();
158
- ```
159
-
160
- ### Set Values
161
-
162
- ```javascript
163
- // Set single value
164
- frm.set_value('fieldname', value);
165
-
166
- // Set multiple values
167
- frm.set_value({
168
- 'field1': 'value1',
169
- 'field2': 'value2',
170
- 'field3': 'value3'
171
- });
172
-
173
- // Set with callback
174
- frm.set_value('fieldname', value).then(() => {
175
- // After value is set
176
- });
177
-
178
- // Clear field
179
- frm.set_value('fieldname', null);
180
- frm.set_value('fieldname', '');
181
-
182
- // Set default value
183
- frm.set_df_property('fieldname', 'default', 'default_value');
184
- ```
185
-
186
- ### Link Field Queries
187
-
188
- ```javascript
189
- // Basic filter
190
- frm.set_query('customer', function() {
191
- return {
192
- filters: {
193
- status: 'Active',
194
- customer_type: 'Company'
195
- }
196
- };
197
- });
198
-
199
- // Dynamic filter based on form values
200
- frm.set_query('item_code', function() {
201
- return {
202
- filters: {
203
- item_group: frm.doc.item_group,
204
- is_stock_item: 1
205
- }
206
- };
207
- });
208
-
209
- // Filter in child table
210
- frm.set_query('item_code', 'items', function(doc, cdt, cdn) {
211
- let row = locals[cdt][cdn];
212
- return {
213
- filters: {
214
- warehouse: row.warehouse || doc.default_warehouse
215
- }
216
- };
217
- });
218
-
219
- // Custom query (server method)
220
- frm.set_query('supplier', function() {
221
- return {
222
- query: 'my_app.api.get_suppliers',
223
- filters: {
224
- region: frm.doc.region
225
- }
226
- };
227
- });
228
-
229
- // Clear query
230
- frm.set_query('fieldname', null);
231
- ```
232
-
233
- ## Custom Buttons
234
-
235
- ```javascript
236
- refresh: function(frm) {
237
- // Simple button
238
- frm.add_custom_button(__('Do Something'), function() {
239
- do_something(frm);
240
- });
241
-
242
- // Button in group/dropdown
243
- frm.add_custom_button(__('Action 1'), function() {
244
- action_1(frm);
245
- }, __('Actions'));
246
-
247
- frm.add_custom_button(__('Action 2'), function() {
248
- action_2(frm);
249
- }, __('Actions'));
250
-
251
- // Primary button (highlighted)
252
- frm.add_custom_button(__('Submit'), function() {
253
- submit_doc(frm);
254
- }).addClass('btn-primary');
255
-
256
- // Button with icon
257
- let btn = frm.add_custom_button(__('Print'), function() {
258
- print_doc(frm);
259
- });
260
- btn.prepend('<i class="fa fa-print"></i> ');
261
-
262
- // Conditional buttons
263
- if (frm.doc.status === 'Draft') {
264
- frm.add_custom_button(__('Submit for Review'), function() {
265
- submit_for_review(frm);
266
- });
267
- }
268
-
269
- // Remove button
270
- frm.remove_custom_button(__('Do Something'));
271
- frm.remove_custom_button(__('Action 1'), __('Actions'));
272
-
273
- // Clear all buttons
274
- frm.clear_custom_buttons();
275
-
276
- // Page actions
277
- frm.page.set_primary_action(__('Save'), function() {
278
- frm.save();
279
- });
280
-
281
- frm.page.set_secondary_action(__('Cancel'), function() {
282
- frappe.set_route('List', 'My DocType');
283
- });
284
- }
285
- ```
286
-
287
- ## Child Table Operations
288
-
289
- ### Events
290
-
291
- ```javascript
292
- frappe.ui.form.on('My DocType Item', {
293
- // Row added
294
- items_add: function(frm, cdt, cdn) {
295
- let row = locals[cdt][cdn];
296
- row.warehouse = frm.doc.default_warehouse;
297
- frm.refresh_field('items');
298
- },
299
-
300
- // Before row removed (can prevent)
301
- before_items_remove: function(frm, cdt, cdn) {
302
- let row = locals[cdt][cdn];
303
- if (row.is_mandatory) {
304
- frappe.throw(__('Cannot remove mandatory item'));
305
- }
306
- },
307
-
308
- // Row removed
309
- items_remove: function(frm, cdt, cdn) {
310
- calculate_total(frm);
311
- },
312
-
313
- // Field in row changes
314
- qty: function(frm, cdt, cdn) {
315
- let row = locals[cdt][cdn];
316
- row.amount = flt(row.qty) * flt(row.rate);
317
- frm.refresh_field('items');
318
- calculate_total(frm);
319
- },
320
-
321
- rate: function(frm, cdt, cdn) {
322
- let row = locals[cdt][cdn];
323
- row.amount = flt(row.qty) * flt(row.rate);
324
- frm.refresh_field('items');
325
- calculate_total(frm);
326
- },
327
-
328
- item_code: function(frm, cdt, cdn) {
329
- let row = locals[cdt][cdn];
330
- if (row.item_code) {
331
- frappe.call({
332
- method: 'my_app.api.get_item_details',
333
- args: { item_code: row.item_code },
334
- callback: function(r) {
335
- if (r.message) {
336
- frappe.model.set_value(cdt, cdn, {
337
- 'rate': r.message.rate,
338
- 'uom': r.message.uom,
339
- 'description': r.message.description
340
- });
341
- }
342
- }
343
- });
344
- }
345
- }
346
- });
347
-
348
- function calculate_total(frm) {
349
- let total = 0;
350
- frm.doc.items.forEach(item => {
351
- total += flt(item.amount);
352
- });
353
- frm.set_value('total', total);
354
- }
355
- ```
356
-
357
- ### Manipulating Rows
358
-
359
- ```javascript
360
- // Add row
361
- let row = frm.add_child('items', {
362
- item_code: 'ITEM-001',
363
- qty: 10,
364
- rate: 100
365
- });
366
- frm.refresh_field('items');
367
-
368
- // Get row by index
369
- let first_row = frm.doc.items[0];
370
-
371
- // Get row by name
372
- let row = locals['My DocType Item'][cdn];
373
-
374
- // Update row
375
- frappe.model.set_value(cdt, cdn, 'fieldname', value);
376
- frappe.model.set_value(cdt, cdn, {
377
- 'field1': 'value1',
378
- 'field2': 'value2'
379
- });
380
-
381
- // Remove row
382
- frm.get_field('items').grid.grid_rows[0].remove();
383
- frm.refresh_field('items');
384
-
385
- // Remove all rows
386
- frm.clear_table('items');
387
- frm.refresh_field('items');
388
-
389
- // Iterate rows
390
- frm.doc.items.forEach((item, idx) => {
391
- console.log(idx, item.item_code);
392
- });
393
- ```
394
-
395
- ## Dialogs
396
-
397
- ### Simple Prompt
398
-
399
- ```javascript
400
- // Single field
401
- frappe.prompt(
402
- {
403
- fieldname: 'reason',
404
- fieldtype: 'Small Text',
405
- label: 'Reason',
406
- reqd: 1
407
- },
408
- function(values) {
409
- console.log(values.reason);
410
- },
411
- __('Enter Reason'),
412
- __('Submit')
413
- );
414
- ```
415
-
416
- ### Multi-field Prompt
417
-
418
- ```javascript
419
- frappe.prompt([
420
- {
421
- fieldname: 'customer',
422
- fieldtype: 'Link',
423
- options: 'Customer',
424
- label: 'Customer',
425
- reqd: 1
426
- },
427
- {
428
- fieldname: 'date',
429
- fieldtype: 'Date',
430
- label: 'Date',
431
- default: frappe.datetime.nowdate()
432
- },
433
- {
434
- fieldname: 'priority',
435
- fieldtype: 'Select',
436
- label: 'Priority',
437
- options: 'Low\nMedium\nHigh',
438
- default: 'Medium'
439
- }
440
- ], function(values) {
441
- process_data(values);
442
- }, __('Enter Details'), __('Process'));
443
- ```
444
-
445
- ### Custom Dialog
446
-
447
- ```javascript
448
- let dialog = new frappe.ui.Dialog({
449
- title: __('Custom Dialog'),
450
- fields: [
451
- {
452
- fieldname: 'customer',
453
- fieldtype: 'Link',
454
- options: 'Customer',
455
- label: __('Customer'),
456
- reqd: 1,
457
- get_query: function() {
458
- return { filters: { status: 'Active' } };
459
- },
460
- change: function() {
461
- // Field change handler
462
- let value = dialog.get_value('customer');
463
- if (value) {
464
- dialog.set_value('customer_name', 'Loading...');
465
- }
466
- }
467
- },
468
- { fieldtype: 'Column Break' },
469
- {
470
- fieldname: 'customer_name',
471
- fieldtype: 'Data',
472
- label: __('Customer Name'),
473
- read_only: 1
474
- },
475
- { fieldtype: 'Section Break', label: 'Items' },
476
- {
477
- fieldname: 'items',
478
- fieldtype: 'Table',
479
- label: __('Items'),
480
- cannot_add_rows: false,
481
- in_place_edit: true,
482
- fields: [
483
- {
484
- fieldname: 'item',
485
- fieldtype: 'Link',
486
- options: 'Item',
487
- in_list_view: 1,
488
- label: __('Item')
489
- },
490
- {
491
- fieldname: 'qty',
492
- fieldtype: 'Float',
493
- in_list_view: 1,
494
- label: __('Qty')
495
- }
496
- ]
497
- }
498
- ],
499
- size: 'large', // small, large, extra-large
500
- primary_action_label: __('Submit'),
501
- primary_action: function(values) {
502
- console.log(values);
503
- dialog.hide();
504
- process_dialog(values);
505
- },
506
- secondary_action_label: __('Cancel')
507
- });
508
-
509
- dialog.show();
510
-
511
- // Set values
512
- dialog.set_value('customer', 'CUST-001');
513
- dialog.set_values({
514
- 'customer': 'CUST-001',
515
- 'date': frappe.datetime.nowdate()
516
- });
517
-
518
- // Get values
519
- let values = dialog.get_values();
520
- let customer = dialog.get_value('customer');
521
-
522
- // Access fields
523
- let field = dialog.get_field('customer');
524
- field.set_description('Select active customer');
525
- ```
526
-
527
- ### Confirmation Dialog
528
-
529
- ```javascript
530
- frappe.confirm(
531
- __('Are you sure you want to delete this?'),
532
- function() {
533
- // On Yes
534
- delete_record();
535
- },
536
- function() {
537
- // On No (optional)
538
- }
539
- );
540
- ```
541
-
542
- ## API Calls
543
-
544
- ### frappe.call
545
-
546
- ```javascript
547
- // Basic call
548
- frappe.call({
549
- method: 'my_app.api.get_data',
550
- args: {
551
- customer: frm.doc.customer
552
- },
553
- callback: function(r) {
554
- if (r.message) {
555
- frm.set_value('data', r.message);
556
- }
557
- }
558
- });
559
-
560
- // With loading indicator
561
- frappe.call({
562
- method: 'my_app.api.process',
563
- args: { data: frm.doc },
564
- freeze: true,
565
- freeze_message: __('Processing...'),
566
- callback: function(r) {
567
- frappe.msgprint(__('Done!'));
568
- },
569
- error: function(r) {
570
- frappe.msgprint(__('Error occurred'));
571
- }
572
- });
573
-
574
- // Async/await
575
- async function getData() {
576
- const r = await frappe.call({
577
- method: 'my_app.api.get_data',
578
- args: { id: 123 }
579
- });
580
- return r.message;
581
- }
582
-
583
- // Promise chain
584
- frappe.call({
585
- method: 'my_app.api.get_data'
586
- }).then(r => {
587
- return frappe.call({
588
- method: 'my_app.api.process',
589
- args: { data: r.message }
590
- });
591
- }).then(r => {
592
- console.log('Done', r.message);
593
- });
594
- ```
595
-
596
- ## Messages & Alerts
597
-
598
- ```javascript
599
- // Toast alert
600
- frappe.show_alert({
601
- message: __('Success!'),
602
- indicator: 'green' // green, blue, orange, red
603
- }, 5); // seconds
604
-
605
- // Message dialog
606
- frappe.msgprint({
607
- title: __('Information'),
608
- message: __('This is important'),
609
- indicator: 'blue'
610
- });
611
-
612
- // Error (stops execution)
613
- frappe.throw(__('Cannot proceed'));
614
-
615
- // Confirmation required
616
- frappe.validated = false; // In validate event
617
- ```
618
-
619
- ## Utilities
620
-
621
- ```javascript
622
- // Date/Time
623
- frappe.datetime.nowdate(); // "2024-01-15"
624
- frappe.datetime.now_datetime(); // "2024-01-15 10:30:00"
625
- frappe.datetime.add_days("2024-01-15", 7);
626
- frappe.datetime.add_months("2024-01-15", 1);
627
-
628
- // Formatting
629
- frappe.format(1234.56, {fieldtype: 'Currency'});
630
- format_currency(1234.56, 'USD');
631
- flt(value); // Float
632
- cint(value); // Integer
633
-
634
- // Navigation
635
- frappe.set_route('Form', 'Customer', 'CUST-001');
636
- frappe.set_route('List', 'Customer');
637
- frappe.new_doc('Customer');
638
-
639
- // Translation
640
- __('Translate this');
641
- __('Hello {0}', [name]);
642
- ```