@crypto512/jicon-mcp 2.2.1 → 2.3.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 (142) hide show
  1. package/README.md +7 -2
  2. package/TOOL_LIST.md +361 -296
  3. package/dist/config/constants.d.ts +15 -0
  4. package/dist/config/constants.d.ts.map +1 -1
  5. package/dist/config/constants.js +19 -0
  6. package/dist/config/constants.js.map +1 -1
  7. package/dist/config/loader.d.ts.map +1 -1
  8. package/dist/config/loader.js +7 -1
  9. package/dist/config/loader.js.map +1 -1
  10. package/dist/config/types.d.ts +38 -6
  11. package/dist/config/types.d.ts.map +1 -1
  12. package/dist/config/types.js +16 -0
  13. package/dist/config/types.js.map +1 -1
  14. package/dist/confluence/formatters.d.ts +20 -0
  15. package/dist/confluence/formatters.d.ts.map +1 -1
  16. package/dist/confluence/formatters.js +74 -8
  17. package/dist/confluence/formatters.js.map +1 -1
  18. package/dist/confluence/tools.d.ts +8 -7
  19. package/dist/confluence/tools.d.ts.map +1 -1
  20. package/dist/confluence/tools.js +52 -31
  21. package/dist/confluence/tools.js.map +1 -1
  22. package/dist/credentials/extractor.d.ts +1 -2
  23. package/dist/credentials/extractor.d.ts.map +1 -1
  24. package/dist/credentials/extractor.js +21 -4
  25. package/dist/credentials/extractor.js.map +1 -1
  26. package/dist/credentials/index.d.ts +3 -2
  27. package/dist/credentials/index.d.ts.map +1 -1
  28. package/dist/credentials/index.js +3 -2
  29. package/dist/credentials/index.js.map +1 -1
  30. package/dist/index.js +43 -20
  31. package/dist/index.js.map +1 -1
  32. package/dist/jira/activity-tools.d.ts +8 -11
  33. package/dist/jira/activity-tools.d.ts.map +1 -1
  34. package/dist/jira/activity-tools.js +91 -27
  35. package/dist/jira/activity-tools.js.map +1 -1
  36. package/dist/jira/client.d.ts +12 -0
  37. package/dist/jira/client.d.ts.map +1 -1
  38. package/dist/jira/client.js +35 -0
  39. package/dist/jira/client.js.map +1 -1
  40. package/dist/jira/formatters.d.ts +58 -0
  41. package/dist/jira/formatters.d.ts.map +1 -1
  42. package/dist/jira/formatters.js +80 -11
  43. package/dist/jira/formatters.js.map +1 -1
  44. package/dist/jira/tools.d.ts +30 -12
  45. package/dist/jira/tools.d.ts.map +1 -1
  46. package/dist/jira/tools.js +127 -37
  47. package/dist/jira/tools.js.map +1 -1
  48. package/dist/permissions/tool-registry.d.ts +6 -6
  49. package/dist/permissions/tool-registry.d.ts.map +1 -1
  50. package/dist/permissions/tool-registry.js +4 -3
  51. package/dist/permissions/tool-registry.js.map +1 -1
  52. package/dist/session/context.d.ts +81 -0
  53. package/dist/session/context.d.ts.map +1 -0
  54. package/dist/session/context.js +107 -0
  55. package/dist/session/context.js.map +1 -0
  56. package/dist/session/index.d.ts +12 -0
  57. package/dist/session/index.d.ts.map +1 -0
  58. package/dist/session/index.js +22 -0
  59. package/dist/session/index.js.map +1 -0
  60. package/dist/session/manager.d.ts +155 -0
  61. package/dist/session/manager.d.ts.map +1 -0
  62. package/dist/session/manager.js +285 -0
  63. package/dist/session/manager.js.map +1 -0
  64. package/dist/tempo/client.d.ts +14 -0
  65. package/dist/tempo/client.d.ts.map +1 -1
  66. package/dist/tempo/client.js +55 -0
  67. package/dist/tempo/client.js.map +1 -1
  68. package/dist/tempo/formatters.d.ts +13 -0
  69. package/dist/tempo/formatters.d.ts.map +1 -1
  70. package/dist/tempo/formatters.js +106 -20
  71. package/dist/tempo/formatters.js.map +1 -1
  72. package/dist/tempo/tools.d.ts +10 -9
  73. package/dist/tempo/tools.d.ts.map +1 -1
  74. package/dist/tempo/tools.js +188 -33
  75. package/dist/tempo/tools.js.map +1 -1
  76. package/dist/tempo/types.d.ts +20 -6
  77. package/dist/tempo/types.d.ts.map +1 -1
  78. package/dist/transport/http.d.ts +20 -3
  79. package/dist/transport/http.d.ts.map +1 -1
  80. package/dist/transport/http.js +171 -15
  81. package/dist/transport/http.js.map +1 -1
  82. package/dist/transport/types.d.ts +2 -0
  83. package/dist/transport/types.d.ts.map +1 -1
  84. package/dist/transport/types.js.map +1 -1
  85. package/dist/utils/buffer-tools.d.ts +46 -722
  86. package/dist/utils/buffer-tools.d.ts.map +1 -1
  87. package/dist/utils/buffer-tools.js +303 -158
  88. package/dist/utils/buffer-tools.js.map +1 -1
  89. package/dist/utils/content-buffer.d.ts +10 -31
  90. package/dist/utils/content-buffer.d.ts.map +1 -1
  91. package/dist/utils/content-buffer.js +12 -86
  92. package/dist/utils/content-buffer.js.map +1 -1
  93. package/dist/utils/jicon-help.d.ts +3 -3
  94. package/dist/utils/jicon-help.d.ts.map +1 -1
  95. package/dist/utils/jicon-help.js +163 -101
  96. package/dist/utils/jicon-help.js.map +1 -1
  97. package/dist/utils/plantuml/tools.d.ts.map +1 -1
  98. package/dist/utils/plantuml/tools.js +8 -7
  99. package/dist/utils/plantuml/tools.js.map +1 -1
  100. package/dist/utils/response-formatter.d.ts +12 -2
  101. package/dist/utils/response-formatter.d.ts.map +1 -1
  102. package/dist/utils/response-formatter.js +85 -13
  103. package/dist/utils/response-formatter.js.map +1 -1
  104. package/dist/utils/sandbox/formatters.d.ts +25 -0
  105. package/dist/utils/sandbox/formatters.d.ts.map +1 -0
  106. package/dist/utils/sandbox/formatters.js +690 -0
  107. package/dist/utils/sandbox/formatters.js.map +1 -0
  108. package/dist/utils/sandbox/helpers.d.ts +16 -0
  109. package/dist/utils/sandbox/helpers.d.ts.map +1 -0
  110. package/dist/utils/sandbox/helpers.js +252 -0
  111. package/dist/utils/sandbox/helpers.js.map +1 -0
  112. package/dist/utils/sandbox/index.d.ts +19 -0
  113. package/dist/utils/sandbox/index.d.ts.map +1 -0
  114. package/dist/utils/sandbox/index.js +269 -0
  115. package/dist/utils/sandbox/index.js.map +1 -0
  116. package/dist/utils/sandbox/schema.d.ts +55 -0
  117. package/dist/utils/sandbox/schema.d.ts.map +1 -0
  118. package/dist/utils/sandbox/schema.js +39 -0
  119. package/dist/utils/sandbox/schema.js.map +1 -0
  120. package/dist/utils/sandbox/types.d.ts +179 -0
  121. package/dist/utils/sandbox/types.d.ts.map +1 -0
  122. package/dist/utils/sandbox/types.js +8 -0
  123. package/dist/utils/sandbox/types.js.map +1 -0
  124. package/dist/utils/schemas/confluence.d.ts +41 -0
  125. package/dist/utils/schemas/confluence.d.ts.map +1 -0
  126. package/dist/utils/schemas/confluence.js +105 -0
  127. package/dist/utils/schemas/confluence.js.map +1 -0
  128. package/dist/utils/schemas/index.d.ts +66 -0
  129. package/dist/utils/schemas/index.d.ts.map +1 -0
  130. package/dist/utils/schemas/index.js +107 -0
  131. package/dist/utils/schemas/index.js.map +1 -0
  132. package/dist/utils/schemas/jira.d.ts +49 -0
  133. package/dist/utils/schemas/jira.d.ts.map +1 -0
  134. package/dist/utils/schemas/jira.js +151 -0
  135. package/dist/utils/schemas/jira.js.map +1 -0
  136. package/dist/utils/schemas/tempo.d.ts +29 -0
  137. package/dist/utils/schemas/tempo.d.ts.map +1 -0
  138. package/dist/utils/schemas/tempo.js +72 -0
  139. package/dist/utils/schemas/tempo.js.map +1 -0
  140. package/dist/utils/xhtml/error-locator.js +5 -5
  141. package/dist/utils/xhtml/error-locator.js.map +1 -1
  142. package/package.json +10 -9
package/TOOL_LIST.md CHANGED
@@ -5,8 +5,8 @@ This document provides a comprehensive reference of all available tools in the J
5
5
 
6
6
  ## Summary
7
7
 
8
- **Total Tools**: 79
9
- - **Jira Tools**: 26 (21 read + 5 write)
8
+ **Total Tools**: 80
9
+ - **Jira Tools**: 27 (22 read + 5 write)
10
10
  - **Confluence Tools**: 21 (13 read + 8 write)
11
11
  - **Tempo Tools**: 13 (10 read + 3 write)
12
12
  - **Buffer Tools**: 11
@@ -17,7 +17,7 @@ This document provides a comprehensive reference of all available tools in the J
17
17
  - **PlantUML Tools**: 3
18
18
 
19
19
  **Note**: All data-heavy tools (search, list, get) **always** return buffered responses with metadata for origin tracking:
20
- - **JSON arrays**: Use `buffer_get_items` for complete items, `buffer_pipeline` for reports
20
+ - **JSON arrays**: Use `buffer_get_items` for complete items, `buffer_transform` for reports
21
21
  - **XHTML**: Use `buffer_get_element` for element-based access
22
22
  - **Search**: Use `buffer_grep` to search within any buffer
23
23
 
@@ -49,7 +49,7 @@ JSON responses include `suggestedNextTools` based on context:
49
49
  "bufferId": "buf_xxx",
50
50
  "structure": { "type": "array", "itemCount": 500 },
51
51
  "suggestedNextTools": [
52
- { "tool": "buffer_pipeline", "description": "Transform to table/report (98% token reduction)", "condition": "for Confluence reports" },
52
+ { "tool": "buffer_transform", "description": "Transform to table/report (98% token reduction)", "condition": "for Confluence reports" },
53
53
  { "tool": "buffer_get_items", "description": "Get complete items for AI analysis", "condition": "for detailed analysis" },
54
54
  { "tool": "buffer_grep", "description": "Search within results" }
55
55
  ]
@@ -111,7 +111,7 @@ When XHTML validation fails, the response includes element ID and suggested acti
111
111
  #### Jira Search → Confluence Report
112
112
  ```
113
113
  1. jira_search_issues(jql) → bufferId, suggestedNextTools
114
- 2. buffer_pipeline(bufferId, pipeline) → tableBufferId (98% token reduction)
114
+ 2. buffer_transform(inputs, code) → tableBufferId (98% token reduction)
115
115
  3. confluence_edit(pageId) → pageBufferId, structure
116
116
  4. buffer_edit(pageBufferId, after=ID, fromBufferId=tableBufferId)
117
117
  5. confluence_draft_create(pageId, pageBufferId, autoRetry=true) → draft URL
@@ -121,7 +121,7 @@ When XHTML validation fails, the response includes element ID and suggested acti
121
121
  ```
122
122
  1. tempo_get_user_info() → workerKey
123
123
  2. tempo_get_worklogs(dateFrom, dateTo, workerKey) → bufferId, suggestedNextTools
124
- 3. buffer_pipeline(bufferId, groupBy=project, sum=hours) → summaryBufferId
124
+ 3. buffer_transform(bufferId, groupBy=project, sum=hours) → summaryBufferId
125
125
  4. Use in report or display directly
126
126
  ```
127
127
 
@@ -137,7 +137,7 @@ When XHTML validation fails, the response includes element ID and suggested acti
137
137
 
138
138
  ---
139
139
 
140
- ## Jira Tools (25)
140
+ ## Jira Tools (27)
141
141
 
142
142
  ### Localization / Non-English Jira
143
143
 
@@ -194,7 +194,7 @@ The server automatically handles localized changelog field names for activity tr
194
194
  }
195
195
  ```
196
196
 
197
- **Returns**: `bufferId` with issues. Use `buffer_pipeline` for tables, `buffer_get_items` for AI analysis.
197
+ **Returns**: `bufferId` with issues. Use `buffer_transform` for tables, `buffer_get_items` for AI analysis.
198
198
 
199
199
  ---
200
200
 
@@ -366,7 +366,28 @@ The server automatically handles localized changelog field names for activity tr
366
366
 
367
367
  ---
368
368
 
369
- ### 14. jira_get_board
369
+ ### 14. jira_list_boards
370
+ **Description**: List all Jira Agile boards (Scrum and Kanban). Entry point for board discovery.
371
+ **Use Cases**: Discover available boards, filter by project or type, find board IDs
372
+
373
+ | Parameter | Type | Required | Description |
374
+ |-----------|------|----------|-------------|
375
+ | projectKeyOrId | string | ✗ | Filter by project key or ID |
376
+ | type | string | ✗ | Filter by board type ("scrum" or "kanban") |
377
+ | name | string | ✗ | Filter by board name (contains) |
378
+
379
+ **Returns**: `bufferId` with boards array. Each board has `id`, `name`, `type`, `projectKey`.
380
+
381
+ **Examples**:
382
+ ```
383
+ jira_list_boards() # All boards
384
+ jira_list_boards(projectKeyOrId="PROJ") # Boards for project
385
+ jira_list_boards(type="scrum") # Only Scrum boards
386
+ ```
387
+
388
+ ---
389
+
390
+ ### 15. jira_get_board
370
391
  **Description**: Get Agile board information
371
392
  **Use Cases**: View board details, get board configuration
372
393
 
@@ -378,7 +399,7 @@ The server automatically handles localized changelog field names for activity tr
378
399
 
379
400
  ---
380
401
 
381
- ### 15. jira_get_sprints
402
+ ### 16. jira_get_sprints
382
403
  **Description**: List all sprints for a board
383
404
  **Use Cases**: View active sprints, check sprint schedules
384
405
 
@@ -391,7 +412,7 @@ The server automatically handles localized changelog field names for activity tr
391
412
 
392
413
  ---
393
414
 
394
- ### 16. jira_get_sprint_issues
415
+ ### 17. jira_get_sprint_issues
395
416
  **Description**: Get all issues in a specific sprint
396
417
  **Use Cases**: View sprint backlog, check sprint progress
397
418
 
@@ -403,7 +424,7 @@ The server automatically handles localized changelog field names for activity tr
403
424
 
404
425
  ---
405
426
 
406
- ### 17. jira_get_issue_watchers
427
+ ### 18. jira_get_issue_watchers
407
428
  **Description**: Get list of watchers on an issue
408
429
  **Use Cases**: See who's following an issue
409
430
 
@@ -413,7 +434,7 @@ The server automatically handles localized changelog field names for activity tr
413
434
 
414
435
  ---
415
436
 
416
- ### 18. jira_get_issue_worklogs
437
+ ### 19. jira_get_issue_worklogs
417
438
  **Description**: Retrieve all worklogs from a Jira issue
418
439
  **Use Cases**: Analyze time logged against an issue, see worklog history
419
440
 
@@ -425,7 +446,7 @@ The server automatically handles localized changelog field names for activity tr
425
446
 
426
447
  ---
427
448
 
428
- ### 19. jira_get_total_worklogs
449
+ ### 20. jira_get_total_worklogs
429
450
  **Description**: Get total worklogs for an issue and all its children recursively
430
451
  **Use Cases**: Get total time spent on an Epic including all stories and sub-tasks
431
452
 
@@ -437,7 +458,7 @@ The server automatically handles localized changelog field names for activity tr
437
458
 
438
459
  ---
439
460
 
440
- ### 20. jira_list_epic_children
461
+ ### 21. jira_list_epic_children
441
462
  **Description**: List all children of an Epic/Initiative without needing JQL
442
463
  **Use Cases**: Get Epic children, list Initiative epics, find issue hierarchy
443
464
 
@@ -460,7 +481,7 @@ Automatically detects Epic Link and Parent Link fields for language-independent
460
481
 
461
482
  ---
462
483
 
463
- ### 21. jira_get_activity_digest
484
+ ### 22. jira_get_activity_digest
464
485
  **Description**: Get recent activity across issues for LLM analysis. Returns DIRECTLY (not buffered).
465
486
  **Use Cases**: Project activity summary, team updates, blocker detection, weekly reports
466
487
 
@@ -501,7 +522,7 @@ Fetches comments, status changes, priority changes, and assignee changes - forma
501
522
 
502
523
  ---
503
524
 
504
- ### 22. jira_get_recent_comments
525
+ ### 23. jira_get_recent_comments
505
526
  **Description**: Get comments across multiple issues for discussion analysis. Returns DIRECTLY (not buffered).
506
527
  **Use Cases**: Discussion summaries, finding comments about specific topics, tracking team communication
507
528
 
@@ -521,7 +542,7 @@ Fetches comments, status changes, priority changes, and assignee changes - forma
521
542
 
522
543
  ---
523
544
 
524
- ### 23. jira_get_changelog
545
+ ### 24. jira_get_changelog
525
546
  **Description**: Get field changes across issues for tracking what happened. Returns DIRECTLY (not buffered).
526
547
  **Use Cases**: Status change tracking, priority escalation analysis, assignment history
527
548
 
@@ -551,7 +572,7 @@ Fetches comments, status changes, priority changes, and assignee changes - forma
551
572
 
552
573
  ---
553
574
 
554
- ### 24. jira_analyze_epic
575
+ ### 25. jira_analyze_epic
555
576
  **Description**: Comprehensive Epic/Feature analysis for LLM insights. Returns DIRECTLY (not buffered).
556
577
  **Use Cases**: Epic progress analysis, velocity tracking, time metrics, feature status
557
578
 
@@ -596,7 +617,7 @@ Currently **3 issues** are in progress.
596
617
 
597
618
  ---
598
619
 
599
- ### 25. jira_epic_summary
620
+ ### 26. jira_epic_summary
600
621
  **Description**: Lightweight Epic/Initiative summary with hierarchy and status breakdown. Returns DIRECTLY (not buffered).
601
622
  **Use Cases**: Quick Epic overview, status breakdown, cross-project dependencies
602
623
 
@@ -643,7 +664,7 @@ Provides quick overview without the heavy metrics of `jira_analyze_epic` - no ti
643
664
 
644
665
  ---
645
666
 
646
- ### 26. jira_analyze_sprint
667
+ ### 27. jira_analyze_sprint
647
668
  **Description**: Comprehensive Sprint analysis for LLM insights. Returns DIRECTLY (not buffered).
648
669
  **Use Cases**: Sprint progress, risk assessment, team workload, daily standups
649
670
 
@@ -1402,13 +1423,13 @@ Aggregates Tempo worklogs and returns ranked results in markdown format.
1402
1423
 
1403
1424
  ---
1404
1425
 
1405
- ## Buffer Tools (11)
1426
+ ## Buffer Tools (12)
1406
1427
 
1407
1428
  Buffer tools are used for local content management. All buffer operations are in-memory - write enforcement is on Jira/Confluence/Tempo tools.
1408
1429
 
1409
1430
  **XHTML Editing**: `buffer_edit` uses element IDs for precise positioning in XHTML content. Each element gets a unique ID when loaded - use `buffer_get_structure` to see them. `buffer_validate_xhtml` validates Confluence storage format. XHTML validation is also automatically applied before any Confluence write operation.
1410
1431
 
1411
- **Data Pipelines**: `buffer_pipeline` transforms JSON buffers (from Jira/Tempo searches) with server-side filtering, grouping, sorting, and output generation - minimizing token usage.
1432
+ **Data Transformation**: `buffer_transform` transforms JSON buffers (from Jira/Tempo searches) with JavaScript code for filtering, grouping, sorting, and output generation - minimizing token usage.
1412
1433
 
1413
1434
  ### 1. buffer_create
1414
1435
  **Description**: Create a new buffer with initial content. Returns bufferId and structure.
@@ -1417,7 +1438,7 @@ Buffer tools are used for local content management. All buffer operations are in
1417
1438
 
1418
1439
  **Content types**:
1419
1440
  - **xhtml**: Confluence storage format. Returns element IDs for `buffer_edit`.
1420
- - **json**: JSON data (array or object). Use `buffer_get_items` to access, `buffer_pipeline` to transform.
1441
+ - **json**: JSON data (array or object). Use `buffer_get_items` to access, `buffer_transform` to transform.
1421
1442
 
1422
1443
  **Use Cases**: Draft new Confluence pages, prepare content before persisting, create JSON arrays for aggregation
1423
1444
 
@@ -1632,14 +1653,14 @@ buffer_set_items({
1632
1653
  ---
1633
1654
 
1634
1655
  ### 5. buffer_list
1635
- **Description**: List all active buffers with their metadata
1636
- **Use Cases**: View active buffers, check expiration times
1656
+ **Description**: List all active buffers with their metadata. Buffers are cleaned up when session ends. Max buffers per session configurable via JICON_MAX_BUFFERS (default: 10); oldest unmodified evicted first when full.
1657
+ **Use Cases**: View active buffers, recover lost buffer IDs
1637
1658
 
1638
1659
  | Parameter | Type | Required | Description |
1639
1660
  |-----------|------|----------|-------------|
1640
1661
  | (none) | | | |
1641
1662
 
1642
- **Response includes**: `count`, list of buffers with `bufferId`, `totalSize`, `createdAt`, `expiresAt`, `metadata`
1663
+ **Response includes**: `count`, list of buffers with `bufferId`, `totalSize`, `createdAt`, `metadata`
1643
1664
 
1644
1665
  ---
1645
1666
 
@@ -1677,253 +1698,228 @@ buffer_set_items({
1677
1698
 
1678
1699
  ---
1679
1700
 
1680
- ### 8. buffer_pipeline
1681
- **Description**: Transform JSON buffer data with a declarative pipeline: select fields, filter, group/aggregate, sort, format, and output to various formats.
1682
- **Use Cases**: Server-side data transformation to minimize token usage, generate XHTML tables for Confluence, export to CSV/Markdown, aggregate statistics
1683
-
1684
- **Token Efficiency**: A pipeline that filters, sorts, and outputs a table executes in **1 tool call** instead of iterating through items. For pure data transforms, this achieves **98% token reduction**.
1685
-
1686
- **Schema Quick Reference:**
1687
- ```json
1688
- {
1689
- "sourceBufferId": "buf_xxx",
1690
- "pipeline": {
1691
- "select": { "fields": [...] },
1692
- "filter": [...],
1693
- "groupBy": { "field": "...", "aggregations": [...] },
1694
- "sort": [...],
1695
- "limit": 10,
1696
- "format": [...],
1697
- "output": { "type": "xhtml_table", "table": {...} }
1698
- }
1699
- }
1700
- ```
1701
-
1702
- **Common Mistakes:**
1701
+ ### 8. buffer_transform
1702
+ **Description**: Execute JavaScript code in a secure QuickJS sandbox to transform buffer data.
1703
+ **Use Cases**: Server-side data transformation with full JavaScript expressiveness, generate XHTML tables for Confluence, custom filtering/grouping/aggregation
1703
1704
 
1704
- | Wrong | Correct | Why |
1705
- |-------|---------|-----|
1706
- | `sortBy: [...]` | `sort: [...]` | Key name is "sort" not "sortBy" |
1707
- | `transform: "map"` | `transform: "date"` | Valid: uppercase, lowercase, date, number, boolean, string |
1708
- | No `output` | `output: {...}` | Required field - pipeline must have output |
1709
- | `pipeline: "{...}"` | `pipeline: {...}` | Must be object, not JSON string |
1710
- | After select: `sort: [{field: "issueType"}]` | `sort: [{field: "Type"}]` | After `select` renames "issueType" to "Type", use NEW name |
1705
+ **Token Efficiency**: A transformation generates complete output in **1 tool call** instead of iterating through items. For pure data transforms, this achieves **98% token reduction**.
1711
1706
 
1712
1707
  | Parameter | Type | Required | Description |
1713
1708
  |-----------|------|----------|-------------|
1714
- | bufferId | string | ✓ | Source buffer ID containing JSON array |
1715
- | pipeline | object | ✓ | Pipeline definition (see below) |
1709
+ | inputs | object | ✓ | Map of variable name to buffer ID. Example: `{ issues: "buf_abc123" }` |
1710
+ | code | string | ✓ | JavaScript code to execute (ES2020, synchronous). Access inputs as globals, return value becomes output buffer. |
1711
+ | limits | object | ✗ | Optional `{ timeout: 5000, memory: 50000000 }` (default: 5s, 50MB) |
1716
1712
 
1717
- **Type Requirement**: Buffer must have `contentType: "json"`. Returns error if buffer is XHTML or plain text.
1713
+ **Type Requirement**: All input buffers must have `contentType: "json"`. Returns error if buffer is XHTML or plain text.
1718
1714
 
1719
- **Pipeline Definition:**
1715
+ **Built-in Helper Functions (available as globals):**
1720
1716
 
1721
- ```typescript
1722
- {
1723
- // Stage 1: Select specific fields (optional)
1724
- select?: {
1725
- fields: [
1726
- { from: "key" }, // Keep field as-is
1727
- { from: "priority.name", as: "Priority" }, // Rename field
1728
- { from: "created", transform: "date" } // Transform value
1729
- ]
1730
- },
1717
+ | Category | Function | Description |
1718
+ |----------|----------|-------------|
1719
+ | **Aggregation** | `groupBy(array, keyOrFn)` | Group array by field or function → `{ key: items[] }` |
1720
+ | | `sum(array, field?)` | Sum numeric values |
1721
+ | | `avg(array, field?)` | Average numeric values |
1722
+ | | `min(array, field?)` | Minimum value |
1723
+ | | `max(array, field?)` | Maximum value |
1724
+ | | `count(array)` | Count items |
1725
+ | | `unique(array, field?)` | Unique values |
1726
+ | **Object** | `get(obj, 'path.to.field')` | Deep get with dot notation |
1727
+ | | `pick(obj, ['a', 'b'])` | Pick specific keys |
1728
+ | | `omit(obj, ['a'])` | Omit specific keys |
1729
+ | **Date** | `parseDate(string)` | Parse date → timestamp (ms) |
1730
+ | | `formatDate(ts, fmt?)` | Format timestamp (fmt: 'date', 'time', 'datetime', 'iso') |
1731
+ | | `daysBetween(d1, d2)` | Days between two dates |
1732
+ | **Output** | `toTable(array, config)` | Generate Confluence XHTML table |
1733
+ | | `toList(array, config)` | Generate Confluence XHTML list |
1734
+ | | `toMarkdownTable(array, config)` | Generate Markdown table |
1735
+ | | `toMarkdownList(array, config)` | Generate Markdown list |
1731
1736
 
1732
- // Stage 2: Filter items (optional, AND logic between conditions)
1733
- filter?: [
1734
- { field: "status.name", operator: "ne", value: "Done" },
1735
- { field: "priority.name", operator: "in", value: ["High", "Critical"] }
1736
- ],
1737
+ **Context Variables (for link generation):**
1738
+ - `JIRA_URL` - Jira base URL (from server config)
1739
+ - `CONFLUENCE_URL` - Confluence base URL (from server config)
1737
1740
 
1738
- // Stage 3: Group and aggregate (optional)
1739
- groupBy?: {
1740
- field: "assignee.displayName",
1741
- aggregations: [
1742
- { function: "count", as: "totalIssues" },
1743
- { function: "sum", field: "timeSpent", as: "totalTime" },
1744
- { function: "list", field: "key", as: "issueKeys" }
1745
- ]
1746
- },
1741
+ **toTable() Configuration:**
1747
1742
 
1748
- // Stage 4: Sort results (optional)
1749
- sort?: [
1750
- { field: "priority.name", direction: "asc" },
1751
- { field: "key", direction: "desc" }
1743
+ ```javascript
1744
+ toTable(array, {
1745
+ title: 'Table Title', // Optional h2 above table
1746
+ showRowNumbers: true, // Add # column
1747
+ tableClass: 'confluenceTable', // CSS class
1748
+ columns: [
1749
+ { field: 'key', header: 'Issue', link: { type: 'jira' } },
1750
+ { field: 'summary', header: 'Summary', width: '40%' },
1751
+ { field: 'priority.name', header: 'Priority', align: 'center' }
1752
1752
  ],
1753
-
1754
- // Stage 5: Limit results (optional)
1755
- limit?: 50,
1756
-
1757
- // Stage 6: Conditional formatting (optional)
1758
- format?: [
1753
+ format: [ // Conditional styling
1759
1754
  {
1760
- condition: { field: "priority.name", operator: "eq", value: "High" },
1761
- style: { color: "#dc3545", bold: true }
1762
- },
1763
- {
1764
- condition: { field: "status.name", operator: "eq", value: "Done" },
1765
- style: { color: "#28a745", icon: "✓" }
1755
+ condition: { field: 'priority.name', operator: 'eq', value: 'Blocker' },
1756
+ style: { color: '#d04437', bold: true, icon: '🔴' },
1757
+ fields: ['priority.name'] // Apply to specific fields (or omit for row)
1766
1758
  }
1767
- ],
1759
+ ]
1760
+ })
1761
+ ```
1768
1762
 
1769
- // Stage 7: Output configuration (REQUIRED)
1770
- output: {
1771
- type: "xhtml_table", // or "xhtml_list", "json", "csv", "markdown"
1772
- table: {
1773
- title: "Open Issues",
1774
- columns: [
1775
- { field: "key", header: "Issue", link: { type: "jira" } },
1776
- { field: "summary", header: "Summary" },
1777
- { field: "priority.name", header: "Priority" }
1778
- ]
1763
+ **toList() Configuration:**
1764
+
1765
+ ```javascript
1766
+ toList(array, {
1767
+ title: 'List Title',
1768
+ style: 'bullet', // 'bullet', 'numbered', 'none'
1769
+ template: '{{key}}: {{summary}} ({{assignee.displayName}})'
1770
+ })
1771
+ ```
1772
+
1773
+ **toMarkdownTable() Configuration:**
1774
+
1775
+ ```javascript
1776
+ toMarkdownTable(array, {
1777
+ title: 'Table Title', // Optional ## heading
1778
+ showRowNumbers: true, // Add # column
1779
+ columns: [
1780
+ { field: 'key', header: 'Issue', link: { type: 'jira' } },
1781
+ { field: 'summary', header: 'Summary' },
1782
+ { field: 'priority.name', header: 'Priority', align: 'center' }
1783
+ ],
1784
+ format: [ // Conditional styling (bold/italic in Markdown)
1785
+ {
1786
+ condition: { field: 'priority.name', operator: 'eq', value: 'Blocker' },
1787
+ style: { bold: true, icon: '🔴' },
1788
+ fields: ['priority.name']
1779
1789
  }
1780
- }
1781
- }
1790
+ ]
1791
+ })
1792
+ // Returns: { __markdown: true, content: "| # | Issue | Summary |..." }
1782
1793
  ```
1783
1794
 
1784
- **Filter Operators:**
1785
-
1786
- | Operator | Description | Example |
1787
- |----------|-------------|---------|
1788
- | `eq` | Equals | `{ field: "status.name", operator: "eq", value: "Open" }` |
1789
- | `ne` | Not equals | `{ field: "status.name", operator: "ne", value: "Done" }` |
1790
- | `gt`, `lt`, `gte`, `lte` | Numeric comparison | `{ field: "priority.id", operator: "gt", value: 2 }` |
1791
- | `contains` | Substring match (case-insensitive) | `{ field: "summary", operator: "contains", value: "bug" }` |
1792
- | `startsWith`, `endsWith` | String prefix/suffix | `{ field: "key", operator: "startsWith", value: "PROJ-" }` |
1793
- | `in`, `notIn` | Value in array | `{ field: "priority.name", operator: "in", value: ["High", "Critical"] }` |
1794
- | `exists`, `notExists` | Field presence | `{ field: "assignee", operator: "exists" }` |
1795
- | `empty`, `notEmpty` | Empty string/array/null | `{ field: "labels", operator: "notEmpty" }` |
1796
- | `regex` | Regular expression | `{ field: "summary", operator: "regex", value: "^\\[BUG\\]" }` |
1797
-
1798
- **Aggregation Functions:**
1799
-
1800
- | Function | Description | Requires `field` |
1801
- |----------|-------------|------------------|
1802
- | `count` | Count items in group | No |
1803
- | `sum` | Sum numeric values | Yes |
1804
- | `avg` | Average numeric values | Yes |
1805
- | `min`, `max` | Min/max numeric values | Yes |
1806
- | `first`, `last` | First/last value | Yes |
1807
- | `list` | Collect all values | Yes |
1808
- | `unique` | Unique values | Yes |
1809
-
1810
- **Output Types:**
1811
-
1812
- | Type | Description | Config |
1813
- |------|-------------|--------|
1814
- | `xhtml_table` | Confluence-compatible table | `table: { title?, columns: [...], showRowNumbers? }` |
1815
- | `xhtml_list` | Confluence-compatible list | `list: { title?, template: "{{key}}: {{summary}}", style?: "bullet"|"numbered"|"none" }` |
1816
- | `json` | Clean JSON array | `includeMetadata?: boolean` |
1817
- | `csv` | CSV with headers | `table: { columns: [...] }` |
1818
- | `markdown` | Markdown table | `table: { columns: [...] }` |
1819
-
1820
- **Column Configuration:**
1795
+ **toMarkdownList() Configuration:**
1821
1796
 
1822
- ```typescript
1823
- {
1824
- field: "key", // Field path (dot notation)
1825
- header: "Issue", // Column header text
1826
- link?: { type: "jira" }, // Auto-link (jira, confluence, url)
1827
- width?: "100px", // Column width
1828
- align?: "left" | "center" | "right"
1829
- }
1797
+ ```javascript
1798
+ toMarkdownList(array, {
1799
+ title: 'List Title',
1800
+ style: 'bullet', // 'bullet', 'numbered', 'task'
1801
+ template: '{{key}}: {{summary}} ({{assignee.displayName}})'
1802
+ })
1803
+ // Returns: { __markdown: true, content: "- PROJ-1: Fix bug..." }
1830
1804
  ```
1831
1805
 
1832
- **Response includes**: `bufferId` (new output buffer), `inputItems`, `outputItems`, `pipelineStages`, `outputType`, `preview`, `bufferSizeBytes`, `structure` (for XHTML), `hint`
1806
+ **Link Types:**
1807
+ - `jira` - Auto-links to Jira issue using `key` field
1808
+ - `confluence` - Links to Confluence page by ID
1809
+ - `custom` - Custom URL template with `{{field}}` placeholders
1810
+
1811
+ **Format Condition Operators:** `eq`, `ne`, `gt`, `lt`, `gte`, `lte`, `contains`, `startsWith`, `endsWith`, `in`, `notIn`, `exists`, `notExists`, `regex`, `empty`, `notEmpty`
1812
+
1813
+ **Response includes**: `bufferId` (new output buffer), `contentType` (json, xhtml, or markdown), `itemCount` (for arrays), `hint`
1833
1814
 
1834
1815
  **Example - Filter and output table:**
1835
- ```typescript
1816
+ ```javascript
1836
1817
  // Search returns bufferId with 500 issues
1837
1818
  jira_search_issues({ jql: "project = PROJ" })
1838
1819
  // -> { bufferId: "buf_issues", structure: { itemCount: 500 } }
1839
1820
 
1840
1821
  // Transform in ONE call (instead of iterating 500 items)
1841
- buffer_pipeline({
1842
- bufferId: "buf_issues",
1843
- pipeline: {
1844
- filter: [
1845
- { field: "issuetype.name", operator: "eq", value: "Bug" },
1846
- { field: "status.name", operator: "ne", value: "Done" }
1847
- ],
1848
- sort: [{ field: "priority.name", direction: "asc" }],
1849
- limit: 20,
1850
- format: [
1851
- { condition: { field: "priority.name", operator: "eq", value: "High" },
1852
- style: { color: "#dc3545", bold: true } }
1853
- ],
1854
- output: {
1855
- type: "xhtml_table",
1856
- table: {
1857
- title: "Top 20 Open Bugs",
1858
- columns: [
1859
- { field: "key", header: "Issue", link: { type: "jira" } },
1860
- { field: "summary", header: "Summary" },
1861
- { field: "priority.name", header: "Priority" },
1862
- { field: "assignee.displayName", header: "Assignee" }
1863
- ]
1864
- }
1865
- }
1866
- }
1822
+ buffer_transform({
1823
+ inputs: { issues: "buf_issues" },
1824
+ code: `
1825
+ const bugs = issues.filter(i =>
1826
+ i.issuetype?.name === 'Bug' &&
1827
+ i.status?.name !== 'Done'
1828
+ );
1829
+ bugs.sort((a, b) => (a.priority?.id || 0) - (b.priority?.id || 0));
1830
+ const top20 = bugs.slice(0, 20);
1831
+
1832
+ return toTable(top20, {
1833
+ title: 'Top 20 Open Bugs',
1834
+ columns: [
1835
+ { field: 'key', header: 'Issue', link: { type: 'jira' } },
1836
+ { field: 'summary', header: 'Summary' },
1837
+ { field: 'priority.name', header: 'Priority' },
1838
+ { field: 'assignee.displayName', header: 'Assignee' }
1839
+ ],
1840
+ format: [
1841
+ { condition: { field: 'priority.name', operator: 'eq', value: 'High' },
1842
+ style: { color: '#dc3545', bold: true } }
1843
+ ]
1844
+ });
1845
+ `
1867
1846
  })
1868
- // -> { bufferId: "buf_result", outputItems: 15, preview: "<table>...", structure: [...] }
1847
+ // -> { bufferId: "buf_result", contentType: "xhtml" }
1869
1848
  ```
1870
1849
 
1871
- **Example - Group by assignee with aggregations:**
1872
- ```typescript
1873
- buffer_pipeline({
1874
- bufferId: "buf_issues",
1875
- pipeline: {
1876
- filter: [{ field: "status.name", operator: "ne", value: "Done" }],
1877
- groupBy: {
1878
- field: "assignee.displayName",
1879
- aggregations: [
1880
- { function: "count", as: "issueCount" },
1881
- { function: "list", field: "key", as: "issues" }
1850
+ **Example - Group by assignee with statistics:**
1851
+ ```javascript
1852
+ buffer_transform({
1853
+ inputs: { issues: "buf_issues" },
1854
+ code: `
1855
+ const open = issues.filter(i => i.status?.name !== 'Done');
1856
+ const byAssignee = groupBy(open, 'assignee.displayName');
1857
+
1858
+ const stats = Object.entries(byAssignee).map(([name, items]) => ({
1859
+ assignee: name || 'Unassigned',
1860
+ count: items.length,
1861
+ issues: items.map(i => i.key).join(', ')
1862
+ }));
1863
+
1864
+ stats.sort((a, b) => b.count - a.count);
1865
+
1866
+ return toTable(stats, {
1867
+ title: 'Issues by Assignee',
1868
+ columns: [
1869
+ { field: 'assignee', header: 'Assignee' },
1870
+ { field: 'count', header: 'Count', align: 'right' },
1871
+ { field: 'issues', header: 'Issue Keys' }
1882
1872
  ]
1883
- },
1884
- sort: [{ field: "issueCount", direction: "desc" }],
1885
- output: {
1886
- type: "xhtml_table",
1887
- table: {
1888
- title: "Issues by Assignee",
1889
- columns: [
1890
- { field: "displayName", header: "Assignee" },
1891
- { field: "issueCount", header: "Count" },
1892
- { field: "issues", header: "Issues" }
1893
- ]
1894
- }
1895
- }
1896
- }
1873
+ });
1874
+ `
1897
1875
  })
1898
1876
  ```
1899
1877
 
1900
- **Example - Export to CSV:**
1901
- ```typescript
1902
- buffer_pipeline({
1903
- bufferId: "buf_issues",
1904
- pipeline: {
1905
- select: {
1906
- fields: [
1907
- { from: "key" },
1908
- { from: "summary" },
1909
- { from: "status.name", as: "Status" },
1910
- { from: "created", transform: "date" }
1878
+ **Example - Return JSON for further processing:**
1879
+ ```javascript
1880
+ buffer_transform({
1881
+ inputs: { issues: "buf_issues" },
1882
+ code: `
1883
+ const summary = issues.map(i => ({
1884
+ key: i.key,
1885
+ summary: i.summary,
1886
+ status: i.status?.name,
1887
+ priority: i.priority?.name
1888
+ }));
1889
+ return summary; // Returns JSON buffer, not XHTML
1890
+ `
1891
+ })
1892
+ // -> { bufferId: "buf_result", contentType: "json", itemCount: 500 }
1893
+ ```
1894
+
1895
+ **Example - Markdown table output:**
1896
+ ```javascript
1897
+ buffer_transform({
1898
+ inputs: { issues: "buf_issues" },
1899
+ code: `
1900
+ const open = issues.filter(i => i.status?.name !== 'Done');
1901
+ return toMarkdownTable(open.slice(0, 20), {
1902
+ title: 'Open Issues',
1903
+ columns: [
1904
+ { field: 'key', header: 'Issue', link: { type: 'jira' } },
1905
+ { field: 'summary', header: 'Summary' },
1906
+ { field: 'status.name', header: 'Status' },
1907
+ { field: 'priority.name', header: 'Priority', align: 'center' }
1908
+ ],
1909
+ format: [
1910
+ { condition: { field: 'priority.name', operator: 'eq', value: 'High' },
1911
+ style: { bold: true, icon: '🔴' } }
1911
1912
  ]
1912
- },
1913
- output: {
1914
- type: "csv",
1915
- table: {
1916
- columns: [
1917
- { field: "key", header: "Issue" },
1918
- { field: "summary", header: "Summary" },
1919
- { field: "Status", header: "Status" },
1920
- { field: "created", header: "Created" }
1921
- ]
1922
- }
1923
- }
1924
- }
1913
+ });
1914
+ `
1925
1915
  })
1926
- // -> { bufferId: "buf_csv", output: "Issue,Summary,Status,Created\nPROJ-1,..." }
1916
+ // -> { bufferId: "buf_result", contentType: "markdown" }
1917
+ // Output:
1918
+ // ## Open Issues
1919
+ //
1920
+ // | Issue | Summary | Status | Priority |
1921
+ // | --- | --- | --- | :--: |
1922
+ // | [PROJ-1](https://jira.example.com/browse/PROJ-1) | Fix login bug | Open | 🔴 **High** |
1927
1923
  ```
1928
1924
 
1929
1925
  **Common Jira Fields:**
@@ -1937,7 +1933,7 @@ buffer_pipeline({
1937
1933
  **Workflow - Jira to Confluence table:**
1938
1934
  ```
1939
1935
  1. jira_search_issues(jql) → bufferId with JSON
1940
- 2. buffer_pipeline(bufferId, pipeline) → bufferId with XHTML table
1936
+ 2. buffer_transform(inputs, code) → bufferId with XHTML table
1941
1937
  3. confluence_edit(pageId) → page bufferId
1942
1938
  4. buffer_edit(pageBufferId, after=ID, fromBufferId=tableBufferId)
1943
1939
  5. confluence_draft_create(pageId, pageBufferId) → draft for review
@@ -2139,6 +2135,79 @@ buffer_get_structure({ bufferId: "buf_xxx" })
2139
2135
 
2140
2136
  ---
2141
2137
 
2138
+ ### 12. buffer_get_schema
2139
+ **Description**: Get the schema for a JSON buffer. Returns field names, types, and sample values from the actual data.
2140
+ **Use Cases**: Understand buffer structure before writing `buffer_transform` code, discover available fields for data processing
2141
+
2142
+ | Parameter | Type | Required | Description |
2143
+ |-----------|------|----------|-------------|
2144
+ | bufferId | string | ✓ | Buffer ID to get schema for |
2145
+
2146
+ **Type Requirement**: Buffer must have `contentType: "json"`. Returns error if buffer is XHTML.
2147
+
2148
+ **Schema Types**: Buffers from API tools have a named schema type (e.g., `jira_issue`, `tempo_worklog`, `confluence_page`). The schema defines all available fields with consistent structure.
2149
+
2150
+ **Available Schema Types**:
2151
+ | Schema Type | Tools That Return It |
2152
+ |-------------|---------------------|
2153
+ | `jira_issue` | `jira_search_issues`, `jira_get_issue`, `jira_list_epic_children`, `jira_get_sprint_issues` |
2154
+ | `jira_comment` | `jira_get_issue_comments` |
2155
+ | `jira_project` | `jira_list_projects`, `jira_get_project` |
2156
+ | `jira_board` | `jira_get_board` |
2157
+ | `jira_sprint` | `jira_get_sprints` |
2158
+ | `jira_worklog` | `jira_get_issue_worklogs` |
2159
+ | `jira_worklog_total` | `jira_get_total_worklogs` |
2160
+ | `tempo_worklog` | `tempo_get_worklogs`, `tempo_get_worklog`, `tempo_get_team_worklogs`, `tempo_get_epic_worklogs` |
2161
+ | `tempo_account` | `tempo_get_accounts`, `tempo_get_account` |
2162
+ | `tempo_team` | `tempo_get_teams`, `tempo_get_team` |
2163
+ | `confluence_page` | `confluence_search_content`, `confluence_get_page_children` |
2164
+ | `confluence_space` | `confluence_list_spaces`, `confluence_get_space` |
2165
+ | `confluence_comment` | `confluence_get_comments` |
2166
+ | `confluence_attachment` | `confluence_list_attachments` |
2167
+ | `confluence_draft` | `confluence_draft_list` |
2168
+
2169
+ **Response includes**: `bufferId`, `schemaType`, `description`, `itemCount` (for arrays), `fields` (with type, required, description, sample)
2170
+
2171
+ **Example - Get schema before writing transform code:**
2172
+ ```typescript
2173
+ // 1. Search returns bufferId with schemaType in response
2174
+ jira_search_issues({ jql: "project=PROJ" })
2175
+ // Returns: { bufferId: "buf_xxx", schemaType: "jira_issue", fields: ["key", "summary", "status", ...] }
2176
+
2177
+ // 2. Get detailed schema with samples
2178
+ buffer_get_schema({ bufferId: "buf_xxx" })
2179
+ // Returns: {
2180
+ // bufferId: "buf_xxx",
2181
+ // schemaType: "jira_issue",
2182
+ // description: "Jira issue with core fields flattened for easy access",
2183
+ // itemCount: 45,
2184
+ // fields: {
2185
+ // key: { type: "string", required: true, description: "Issue key (e.g., PROJ-123)", sample: "PROJ-123" },
2186
+ // summary: { type: "string", required: true, description: "Issue title/summary", sample: "Fix login bug" },
2187
+ // status: { type: "string", required: true, description: "Current status name", sample: "In Progress" },
2188
+ // assignee: { type: "string", required: false, description: "Assignee display name", sample: "John Doe" },
2189
+ // ...
2190
+ // }
2191
+ // }
2192
+
2193
+ // 3. Now write accurate transform code using flat field names
2194
+ buffer_transform({
2195
+ inputs: [{ bufferId: "buf_xxx" }],
2196
+ code: `return toMarkdownTable(issues, {
2197
+ columns: [
2198
+ { field: 'key', header: 'Key' },
2199
+ { field: 'summary', header: 'Summary' },
2200
+ { field: 'status', header: 'Status' },
2201
+ { field: 'assignee', header: 'Assignee' }
2202
+ ]
2203
+ });`
2204
+ })
2205
+ ```
2206
+
2207
+ **Key Benefit**: All tools returning the same schemaType produce identical field structure. Once you learn `jira_issue` fields, the same structure works for `jira_search_issues`, `jira_get_issue`, `jira_list_epic_children`, and `jira_get_sprint_issues`.
2208
+
2209
+ ---
2210
+
2142
2211
  ## Workload Tools (2)
2143
2212
 
2144
2213
  Utility tools for time calculations. Always available with any Jira, Confluence, or Tempo action.
@@ -2426,7 +2495,7 @@ All data-heavy tools (search, list, get) **always** return buffered responses wi
2426
2495
  "title": "JQL: project = PROJ"
2427
2496
  },
2428
2497
  "accessors": {
2429
- "pipeline": { "tool": "buffer_pipeline", "description": "Transform to table/CSV/list" },
2498
+ "transform": { "tool": "buffer_transform", "description": "Transform with JavaScript code" },
2430
2499
  "get_items": { "tool": "buffer_get_items", "description": "Get complete items for analysis" },
2431
2500
  "search": { "tool": "buffer_grep", "description": "Search within buffer" }
2432
2501
  }
@@ -2439,7 +2508,7 @@ All data-heavy tools (search, list, get) **always** return buffered responses wi
2439
2508
  - `contentType`: Buffer type (`json`, `xhtml`, `plain`)
2440
2509
 
2441
2510
  **Working with JSON Buffers (Jira/Tempo):**
2442
- - `buffer_pipeline(bufferId, pipeline)` - Transform to table/CSV/list (98% token reduction)
2511
+ - `buffer_transform(inputs, code)` - Transform with JavaScript code (98% token reduction)
2443
2512
  - `buffer_get_items(bufferId, start, count)` - Get complete items for AI analysis
2444
2513
  - `buffer_grep(bufferId, pattern)` - Search within buffered data
2445
2514
 
@@ -2506,25 +2575,25 @@ Tools enforce type-safe buffer access - each tool only accepts buffers of the ty
2506
2575
 
2507
2576
  | Buffer Type | Tools That REQUIRE This Type |
2508
2577
  |-------------|------------------------------|
2509
- | **json** | `buffer_pipeline`, `buffer_get_items` |
2578
+ | **json** | `buffer_transform`, `buffer_get_items` |
2510
2579
  | **xhtml** | `buffer_get_structure`, `buffer_get_element`, `buffer_validate_xhtml`, `confluence_draft_create` (with bufferId), `confluence_draft_save` |
2511
2580
  | **any** | `buffer_grep`, `buffer_list`, `buffer_clear`, `buffer_edit` (string mode) |
2512
2581
 
2513
2582
  **Error Messages**: When you use a tool with the wrong buffer type, you get a helpful error:
2514
2583
  ```
2515
- buffer_pipeline requires json buffer, but got: xhtml.
2584
+ buffer_transform requires json buffer, but got: xhtml.
2516
2585
  For XHTML content, use buffer_edit or buffer_get_structure instead.
2517
2586
  ```
2518
2587
 
2519
- **Key Principle**: If you have a JSON buffer (from Jira/Tempo search), use JSON-aware tools (`buffer_pipeline`, `buffer_get_items`). If you have an XHTML buffer (from Confluence), use XHTML-aware tools (`buffer_get_structure`, `buffer_edit` with element IDs).
2588
+ **Key Principle**: If you have a JSON buffer (from Jira/Tempo search), use JSON-aware tools (`buffer_transform`, `buffer_get_items`). If you have an XHTML buffer (from Confluence), use XHTML-aware tools (`buffer_get_structure`, `buffer_edit` with element IDs).
2520
2589
 
2521
2590
  ### Large Dataset Patterns
2522
2591
 
2523
2592
  **Simple table (no AI analysis):**
2524
- Use `buffer_pipeline` - generates complete table in ONE tool call:
2593
+ Use `buffer_transform` - generates complete table in ONE tool call:
2525
2594
  ```typescript
2526
2595
  jira_search_issues({ jql: "project=PROJ" }) // → bufferId (500+ items)
2527
- buffer_pipeline({ bufferId, pipeline: { output: { type: "xhtml_table", ... } } }) // → complete table!
2596
+ buffer_transform({ inputs: { issues: bufferId }, code: "return toTable(issues, { columns: [...] })" }) // → complete table!
2528
2597
  ```
2529
2598
 
2530
2599
  **Table with AI-enhanced columns (complexity, impact):**
@@ -2661,14 +2730,14 @@ buffer_validate_xhtml({
2661
2730
  **Automatic Validation:**
2662
2731
  XHTML content is automatically validated before Confluence writes (`confluence_draft_create`, `confluence_draft_save`).
2663
2732
 
2664
- ### JSON Pipeline Workflows
2733
+ ### JSON Transform Workflows
2665
2734
 
2666
- Use `buffer_pipeline` for efficient server-side data transformation. This eliminates the need to iterate through items in the LLM context.
2735
+ Use `buffer_transform` for efficient server-side data transformation. This eliminates the need to iterate through items in the LLM context.
2667
2736
 
2668
2737
  **Workflow - Search to Table (98% token reduction):**
2669
2738
  ```
2670
2739
  1. jira_search_issues(jql) → bufferId with JSON array
2671
- 2. buffer_pipeline(bufferId, pipeline) → bufferId with XHTML/CSV/Markdown
2740
+ 2. buffer_transform(inputs, code) → bufferId with XHTML table
2672
2741
  3. Use result directly or insert into Confluence page
2673
2742
  ```
2674
2743
 
@@ -2679,29 +2748,27 @@ jira_search_issues({ jql: "project = PROJ AND type = Bug" })
2679
2748
  // → { bufferId: "buf_issues", structure: { itemCount: 150 } }
2680
2749
 
2681
2750
  // 2. Transform to table with one call (NOT iterating 150 items!)
2682
- buffer_pipeline({
2683
- bufferId: "buf_issues",
2684
- pipeline: {
2685
- filter: [{ field: "status.name", operator: "ne", value: "Done" }],
2686
- sort: [{ field: "priority.name", direction: "asc" }],
2687
- format: [
2688
- { condition: { field: "priority.name", operator: "eq", value: "High" },
2689
- style: { color: "#dc3545", bold: true } }
2690
- ],
2691
- output: {
2692
- type: "xhtml_table",
2693
- table: {
2694
- title: "Open Bugs",
2695
- columns: [
2696
- { field: "key", header: "Issue", link: { type: "jira" } },
2697
- { field: "summary", header: "Summary" },
2698
- { field: "priority.name", header: "Priority" }
2699
- ]
2700
- }
2701
- }
2702
- }
2751
+ buffer_transform({
2752
+ inputs: { issues: "buf_issues" },
2753
+ code: `
2754
+ const open = issues.filter(i => i.status?.name !== 'Done');
2755
+ open.sort((a, b) => (a.priority?.id || 0) - (b.priority?.id || 0));
2756
+
2757
+ return toTable(open, {
2758
+ title: 'Open Bugs',
2759
+ columns: [
2760
+ { field: 'key', header: 'Issue', link: { type: 'jira' } },
2761
+ { field: 'summary', header: 'Summary' },
2762
+ { field: 'priority.name', header: 'Priority' }
2763
+ ],
2764
+ format: [
2765
+ { condition: { field: 'priority.name', operator: 'eq', value: 'High' },
2766
+ style: { color: '#dc3545', bold: true } }
2767
+ ]
2768
+ });
2769
+ `
2703
2770
  })
2704
- // → { bufferId: "buf_table", outputItems: 45, preview: "<table>..." }
2771
+ // → { bufferId: "buf_table", contentType: "xhtml" }
2705
2772
 
2706
2773
  // 3. Insert into Confluence page
2707
2774
  confluence_edit("DOCS/Bug Report")
@@ -2715,41 +2782,39 @@ confluence_draft_create({ pageId: "123", bufferId: "buf_page" })
2715
2782
  **Workflow - Statistics Dashboard:**
2716
2783
  ```typescript
2717
2784
  // Group issues by assignee with counts
2718
- buffer_pipeline({
2719
- bufferId: "buf_issues",
2720
- pipeline: {
2721
- filter: [{ field: "status.name", operator: "ne", value: "Done" }],
2722
- groupBy: {
2723
- field: "assignee.displayName",
2724
- aggregations: [
2725
- { function: "count", as: "total" },
2726
- { function: "list", field: "key", as: "issues" }
2785
+ buffer_transform({
2786
+ inputs: { issues: "buf_issues" },
2787
+ code: `
2788
+ const open = issues.filter(i => i.status?.name !== 'Done');
2789
+ const byAssignee = groupBy(open, 'assignee.displayName');
2790
+
2791
+ const stats = Object.entries(byAssignee).map(([name, items]) => ({
2792
+ assignee: name || 'Unassigned',
2793
+ total: items.length,
2794
+ issues: items.map(i => i.key).join(', ')
2795
+ }));
2796
+ stats.sort((a, b) => b.total - a.total);
2797
+
2798
+ return toTable(stats, {
2799
+ title: 'Work Distribution',
2800
+ columns: [
2801
+ { field: 'assignee', header: 'Assignee' },
2802
+ { field: 'total', header: 'Open Issues', align: 'right' },
2803
+ { field: 'issues', header: 'Issue Keys' }
2727
2804
  ]
2728
- },
2729
- sort: [{ field: "total", direction: "desc" }],
2730
- output: {
2731
- type: "xhtml_table",
2732
- table: {
2733
- title: "Work Distribution",
2734
- columns: [
2735
- { field: "displayName", header: "Assignee" },
2736
- { field: "total", header: "Open Issues" },
2737
- { field: "issues", header: "Issue Keys" }
2738
- ]
2739
- }
2740
- }
2741
- }
2805
+ });
2806
+ `
2742
2807
  })
2743
2808
  ```
2744
2809
 
2745
- **When to Use `buffer_pipeline`:**
2810
+ **When to Use `buffer_transform`:**
2746
2811
  - Generating tables/lists for Confluence from Jira/Tempo data
2747
2812
  - Creating CSV/Markdown exports
2748
2813
  - Aggregating statistics (count by status, sum time by project, etc.)
2749
2814
  - Filtering and sorting large result sets server-side
2750
2815
  - Any data transformation that doesn't require LLM reasoning
2751
2816
 
2752
- **When NOT to Use `buffer_pipeline`:**
2817
+ **When NOT to Use `buffer_transform`:**
2753
2818
  - When you need to read and understand each item's content
2754
2819
  - When decisions require LLM judgment (e.g., categorizing by sentiment)
2755
2820
  - When output format depends on item content analysis