@uipath/skills 1.197.2 → 1.198.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CODEOWNERS +18 -11
- package/README.md +1 -0
- package/assets/skill-status.json +8 -0
- package/hooks/hooks.json +44 -8
- package/hooks/send-telemetry.ps1 +392 -0
- package/hooks/send-telemetry.sh +118 -86
- package/hooks/set-session-env.ps1 +72 -0
- package/hooks/set-session-env.sh +64 -0
- package/hooks/suggest-permissions.ps1 +45 -0
- package/hooks/suggest-permissions.sh +4 -0
- package/package.json +1 -1
- package/skills/uipath-admin/references/audit-commands.md +2 -2
- package/skills/uipath-admin/references/audit-workflow-guide.md +4 -4
- package/skills/uipath-agents/references/coded/capabilities/batch-transform/planning.md +1 -1
- package/skills/uipath-agents/references/coded/capabilities/deeprag/planning.md +1 -1
- package/skills/uipath-agents/references/coded/capabilities/guardrails/guardrails-recommend.md +5 -2
- package/skills/uipath-agents/references/coded/capabilities/guardrails/guardrails.md +8 -4
- package/skills/uipath-agents/references/coded/embedding-in-flows.md +1 -1
- package/skills/uipath-agents/references/coded/flow-integration.md +2 -2
- package/skills/uipath-agents/references/coded/lifecycle/build.md +0 -1
- package/skills/uipath-agents/references/coded/lifecycle/setup.md +0 -1
- package/skills/uipath-agents/references/coded/quickstart.md +1 -1
- package/skills/uipath-agents/references/lowcode/agent-definition.md +24 -5
- package/skills/uipath-agents/references/lowcode/capabilities/built-in-tools/batch-transform/planning.md +1 -1
- package/skills/uipath-agents/references/lowcode/capabilities/built-in-tools/deeprag/planning.md +1 -1
- package/skills/uipath-agents/references/lowcode/capabilities/context/attachments.md +1 -0
- package/skills/uipath-agents/references/lowcode/capabilities/guardrails/guardrails-recommend.md +1 -0
- package/skills/uipath-api-workflow/references/cli-reference.md +1 -1
- package/skills/uipath-api-workflow/references/connector-activity-discovery.md +1 -1
- package/skills/uipath-api-workflow/references/troubleshooting.md +1 -1
- package/skills/uipath-automation-discovery/SKILL.md +26 -1
- package/skills/uipath-automation-discovery/assets/templates/estimation-worksheet-template.md +80 -0
- package/skills/uipath-automation-discovery/references/estimation-guide.md +104 -0
- package/skills/uipath-connector-builder/SKILL.md +6 -4
- package/skills/uipath-connector-builder/references/auth.md +137 -13
- package/skills/uipath-connector-builder/references/configuration.md +29 -7
- package/skills/uipath-connector-builder/references/debugging.md +1 -1
- package/skills/uipath-connector-builder/references/standard-resources.md +162 -13
- package/skills/uipath-feedback/SKILL.md +12 -6
- package/skills/uipath-governance/references/cli-cheatsheet.md +3 -3
- package/skills/uipath-governance/references/diagnose/references/failure-modes.md +5 -5
- package/skills/uipath-insights/SKILL.md +277 -0
- package/skills/uipath-insights/references/investigation-playbook-guide.md +145 -0
- package/skills/uipath-insights/references/jobs-commands-guide.md +144 -0
- package/skills/uipath-ixp/SKILL.md +6 -3
- package/skills/uipath-ixp/references/cli-reference.md +19 -4
- package/skills/uipath-maestro-bpmn/references/cli-conventions.md +2 -0
- package/skills/uipath-maestro-bpmn/validator/README.md +12 -2
- package/skills/uipath-maestro-case/SKILL.md +27 -13
- package/skills/uipath-maestro-case/assets/templates/sdd-template-examples.md +37 -4
- package/skills/uipath-maestro-case/assets/templates/sdd-template.md +20 -9
- package/skills/uipath-maestro-case/assets/templates/sdd-viewer.html +8 -7
- package/skills/uipath-maestro-case/references/bindings-v2-sync.md +5 -1
- package/skills/uipath-maestro-case/references/brownfield.md +86 -0
- package/skills/uipath-maestro-case/references/case-commands.md +8 -0
- package/skills/uipath-maestro-case/references/case-editing-operations.md +230 -21
- package/skills/uipath-maestro-case/references/case-schema.md +29 -11
- package/skills/uipath-maestro-case/references/connector-integration.md +1 -1
- package/skills/uipath-maestro-case/references/connector-trigger-common.md +1 -1
- package/skills/uipath-maestro-case/references/entry-points-sync.md +204 -0
- package/skills/uipath-maestro-case/references/implementation.md +19 -9
- package/skills/uipath-maestro-case/references/phase-0-interview.md +10 -8
- package/skills/uipath-maestro-case/references/phased-execution.md +11 -4
- package/skills/uipath-maestro-case/references/placeholder-tasks.md +24 -2
- package/skills/uipath-maestro-case/references/planning.md +9 -3
- package/skills/uipath-maestro-case/references/plugins/case/planning.md +2 -0
- package/skills/uipath-maestro-case/references/plugins/sla/impl-json.md +1 -1
- package/skills/uipath-maestro-case/references/plugins/sla/planning.md +1 -1
- package/skills/uipath-maestro-case/references/plugins/stages/impl-json.md +11 -10
- package/skills/uipath-maestro-case/references/plugins/stages/planning.md +13 -14
- package/skills/uipath-maestro-case/references/plugins/tasks/agent/impl-json.md +3 -1
- package/skills/uipath-maestro-case/references/plugins/tasks/agent/planning.md +91 -2
- package/skills/uipath-maestro-case/references/plugins/tasks/api-workflow/impl-json.md +3 -1
- package/skills/uipath-maestro-case/references/plugins/tasks/api-workflow/planning.md +87 -2
- package/skills/uipath-maestro-case/references/plugins/tasks/connector-activity/planning.md +1 -1
- package/skills/uipath-maestro-case/references/plugins/triggers/event/impl-json.md +1 -1
- package/skills/uipath-maestro-case/references/plugins/triggers/manual/impl-json.md +3 -1
- package/skills/uipath-maestro-case/references/plugins/triggers/timer/impl-json.md +2 -1
- package/skills/uipath-maestro-case/references/plugins/variables/bindings/impl-json.md +2 -0
- package/skills/uipath-maestro-case/references/plugins/variables/global-vars/impl-json.md +20 -10
- package/skills/uipath-maestro-case/references/plugins/variables/global-vars/planning.md +9 -8
- package/skills/uipath-maestro-case/references/plugins/variables/io-binding/impl-json.md +1 -1
- package/skills/uipath-maestro-case/references/plugins/variables/io-binding/planning.md +1 -1
- package/skills/uipath-maestro-case/references/registry-discovery.md +87 -10
- package/skills/uipath-maestro-case/references/sdd-generation-rules.md +34 -26
- package/skills/uipath-maestro-flow/SKILL.md +4 -1
- package/skills/uipath-maestro-flow/references/author/CAPABILITY.md +1 -2
- package/skills/uipath-maestro-flow/references/author/references/editing-operations-json.md +3 -3
- package/skills/uipath-maestro-flow/references/author/references/greenfield.md +4 -2
- package/skills/uipath-maestro-flow/references/author/references/planning-arch.md +0 -1
- package/skills/uipath-maestro-flow/references/author/references/planning-impl.md +0 -1
- package/skills/uipath-maestro-flow/references/author/references/plugins/connector/impl.md +1 -0
- package/skills/uipath-maestro-flow/references/author/references/plugins/connector-trigger/impl.md +7 -7
- package/skills/uipath-maestro-flow/references/author/references/plugins/ixp/impl.md +14 -14
- package/skills/uipath-maestro-flow/references/author/references/plugins/script/impl.md +10 -6
- package/skills/uipath-maestro-flow/references/shared/cli-conventions.md +7 -0
- package/skills/uipath-maestro-flow/references/shared/file-format.md +1 -1
- package/skills/uipath-mcp-servers/references/is-activity-workflow.md +3 -3
- package/skills/uipath-planner/SKILL.md +1 -1
- package/skills/uipath-platform/SKILL.md +4 -14
- package/skills/uipath-platform/references/data-fabric/data-fabric.md +1 -1
- package/skills/uipath-platform/references/integration-service/agent-workflow.md +4 -4
- package/skills/uipath-platform/references/integration-service/reference-resolution.md +1 -1
- package/skills/uipath-platform/references/integration-service/resources.md +5 -5
- package/skills/uipath-platform/references/integration-service/triggers.md +10 -9
- package/skills/uipath-platform/references/orchestrator/setup-environment.md +2 -0
- package/skills/uipath-review/SKILL.md +8 -4
- package/skills/uipath-review/references/agents/agent-review-checklist.md +1 -22
- package/skills/uipath-review/references/agents/agents-coded-rules.md +24 -7
- package/skills/uipath-review/references/agents/agents-lowcode-rules.md +0 -1
- package/skills/uipath-review/references/agents/guardrails/coded-guardrails-review.md +231 -0
- package/skills/uipath-review/references/rule-catalog-workflow.md +4 -2
- package/skills/uipath-rpa/SKILL.md +2 -2
- package/skills/uipath-rpa/references/activity-docs/UiPath.DataService.Activities/guides/data-service-filter-builder-guide.md +1 -1
- package/skills/uipath-rpa/references/activity-docs/UiPath.Web.Activities/2.5/coded/coded-api.md +1 -1
- package/skills/uipath-rpa/references/activity-docs/UiPath.Web.Activities/2.5/coded/curl-import.md +3 -3
- package/skills/uipath-rpa/references/activity-docs/UiPath.Web.Activities/2.5/coded/http-request-upgrade.md +3 -3
- package/skills/uipath-rpa/references/activity-docs/UiPath.Web.Activities/2.5/coded/service-discovery.md +2 -2
- package/skills/uipath-rpa/references/coded/coding-guidelines.md +1 -1
- package/skills/uipath-rpa/references/ui-automation-guide.md +7 -7
- package/skills/uipath-rpa/references/uia-configure-target-workflows.md +5 -5
- package/skills/uipath-rpa/references/uia-elements-interaction-guide.md +19 -10
- package/skills/uipath-rpa/references/uia-prerequisites.md +7 -7
- package/skills/uipath-rpa/references/validation-guide.md +2 -2
- package/skills/uipath-rpa/references/xaml/common-pitfalls.md +4 -0
- package/skills/uipath-rpa/references/xaml/csharp-activity-binding-guide.md +3 -1
- package/skills/uipath-rpa/references/xaml/csharp-expression-pitfalls.md +9 -4
- package/skills/uipath-rpa/references/xaml/workflow-guide.md +2 -2
- package/skills/uipath-rpa/references/xaml/xaml-basics-and-rules.md +1 -1
- package/skills/uipath-solution/SKILL.md +4 -4
- package/skills/uipath-solution/references/activate-and-manage.md +6 -1
- package/skills/uipath-solution/references/develop-solution.md +24 -5
- package/skills/uipath-solution/references/pack-and-deploy.md +5 -2
- package/skills/uipath-solution/references/scenarios/manual-edits.md +2 -2
- package/skills/uipath-solution/references/solution-overview.md +2 -2
- package/skills/uipath-troubleshoot/SKILL.md +3 -3
- package/skills/uipath-troubleshoot/references/products/agents/playbooks/context-grounding-index-not-found.md +0 -2
- package/skills/uipath-troubleshoot/references/products/maestro/playbooks/personal-automation-quota.md +1 -1
- package/version-manifest.json +3 -3
- package/hooks/ensure-uip.sh +0 -220
- package/skills/uipath-maestro-flow/references/author/references/plugins/connector/data-fabric/impl.md +0 -683
- package/skills/uipath-maestro-flow/references/author/references/plugins/connector/data-fabric/planning.md +0 -45
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"name": "uipath",
|
|
10
10
|
"source": "./",
|
|
11
11
|
"description": "UiPath plugin for Claude Code — custom skills, agents, hooks, and MCP servers for UiPath workflows, UI automation, UI testing and UiPath troubleshoot",
|
|
12
|
-
"version": "1.
|
|
12
|
+
"version": "1.198.0",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "UiPath"
|
|
15
15
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uipath",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.198.0",
|
|
4
4
|
"description": "UiPath plugin for Claude Code — custom skills, agents, hooks, and MCP servers for UiPath RPA workflows, UI automation, UI testing, Python coded agents and UiPath troubleshoot",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "UiPath"
|
package/CODEOWNERS
CHANGED
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
/tests/tasks/uipath-rpa/ @DragosUnguru @RaduAna-Maria @gabrielavaduva @AlvinStanescu @Mihaiii
|
|
24
24
|
|
|
25
25
|
# Platform skill
|
|
26
|
-
/skills/uipath-platform/ @gabrielavaduva @alexenica @andreiopr @vlad-voinea-uipath @emanueldejanu @gcoman @puscasu-ion-daniel @razvalex @aeremencu @alinahornet @DinuDanNicolae @florin-munteanu-uipath @StefanPopaUi @razvanpotcoveanu @vladbucur-8 @busesorin94 @dmorosanu @MarinRzv @vladimir-cozma @UiPath/team-merlot @UiPath/team-orange
|
|
26
|
+
/skills/uipath-platform/ @gabrielavaduva @alexenica @andreiopr @vlad-voinea-uipath @emanueldejanu @gcoman @puscasu-ion-daniel @razvalex @aeremencu @alinahornet @DinuDanNicolae @florin-munteanu-uipath @StefanPopaUi @razvanpotcoveanu @vladbucur-8 @busesorin94 @dmorosanu @MarinRzv @vladimir-cozma @UiPath/team-merlot @UiPath/team-orange @UiPath/DatafabricCodingAgent
|
|
27
27
|
/skills/uipath-platform/references/traces/ @UiPath/llmops-team
|
|
28
28
|
/skills/uipath-platform/references/integration-service/ @chandusailella @baishalighosh
|
|
29
29
|
/skills/uipath-platform/references/data-fabric/ @UiPath/DatafabricCodingAgent
|
|
30
30
|
/skills/uipath-platform/references/llmgateway/ @denispetre @vstoleru-uipath @dragosvelcea
|
|
31
|
-
/tests/tasks/uipath-platform/ @gabrielavaduva @alexenica @andreiopr @vlad-voinea-uipath @emanueldejanu @gcoman @puscasu-ion-daniel @razvalex @aeremencu @alinahornet @DinuDanNicolae @florin-munteanu-uipath @StefanPopaUi @razvanpotcoveanu @vladbucur-8 @busesorin94 @dmorosanu @MarinRzv @vladimir-cozma @UiPath/team-merlot @UiPath/team-orange
|
|
31
|
+
/tests/tasks/uipath-platform/ @gabrielavaduva @alexenica @andreiopr @vlad-voinea-uipath @emanueldejanu @gcoman @puscasu-ion-daniel @razvalex @aeremencu @alinahornet @DinuDanNicolae @florin-munteanu-uipath @StefanPopaUi @razvanpotcoveanu @vladbucur-8 @busesorin94 @dmorosanu @MarinRzv @vladimir-cozma @UiPath/team-merlot @UiPath/team-orange @UiPath/DatafabricCodingAgent
|
|
32
32
|
/tests/tasks/uipath-platform/orchestrator/ @gabrielavaduva @alexenica @andreiopr @vlad-voinea-uipath @emanueldejanu @gcoman @puscasu-ion-daniel @razvalex @aeremencu @alinahornet @DinuDanNicolae @florin-munteanu-uipath @StefanPopaUi @razvanpotcoveanu @vladbucur-8 @busesorin94 @dmorosanu @MarinRzv @vladimir-cozma @UiPath/team-merlot @UiPath/team-orange
|
|
33
33
|
/tests/tasks/uipath-platform/resources/ @gabrielavaduva @alexenica @andreiopr @vlad-voinea-uipath @emanueldejanu @gcoman @puscasu-ion-daniel @razvalex @aeremencu @alinahornet @DinuDanNicolae @florin-munteanu-uipath @StefanPopaUi @razvanpotcoveanu @vladbucur-8 @busesorin94 @dmorosanu @MarinRzv @vladimir-cozma @UiPath/team-merlot @UiPath/team-orange
|
|
34
34
|
/tests/tasks/uipath-platform/integration-service/ @chandusailella @baishalighosh
|
|
@@ -62,6 +62,8 @@
|
|
|
62
62
|
# Guardrails tests (folder-level ownership)
|
|
63
63
|
/tests/tasks/uipath-agents/lowcode/guardrails/ @apetraru-uipath @valentinabojan @ctiliescuuipath
|
|
64
64
|
/tests/tasks/uipath-agents/coded/guardrails/ @apetraru-uipath @valentinabojan @ctiliescuuipath
|
|
65
|
+
# Guardrails in lowcode/conversational (more specific than /lowcode/conversational/ above — wins via last-match)
|
|
66
|
+
/tests/tasks/uipath-agents/lowcode/conversational/guardrails/ @apetraru-uipath @valentinabojan @ctiliescuuipath
|
|
65
67
|
|
|
66
68
|
# Functions skill (Python Coded Functions — Phase 1; JS HTTP/background Phase 2/3)
|
|
67
69
|
/skills/uipath-functions/ @AlexBizon @UiPath/team-coded-agents
|
|
@@ -77,9 +79,9 @@
|
|
|
77
79
|
/tests/tasks/uipath-solution/ @UiPath/team-merlot @UiPath/team-orange
|
|
78
80
|
|
|
79
81
|
# Flow skill
|
|
80
|
-
/skills/uipath-maestro-flow/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh
|
|
82
|
+
/skills/uipath-maestro-flow/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh @DevMomo
|
|
81
83
|
# Flow test tasks (general) — more specific subfolder rules below override this
|
|
82
|
-
/tests/tasks/uipath-maestro-flow/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh
|
|
84
|
+
/tests/tasks/uipath-maestro-flow/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh @DevMomo
|
|
83
85
|
|
|
84
86
|
# Context grounding team — flow plugins (Summarize/Batch Transform) + tasks
|
|
85
87
|
/skills/uipath-maestro-flow/references/author/references/plugins/summarize/ @gcuip @JeremyReist2 @cfauchere @CalebMartinUiPath @jordan-uipath @eteodorovici @pateljay43 @swathiJayav
|
|
@@ -87,8 +89,8 @@
|
|
|
87
89
|
/tests/tasks/uipath-maestro-flow/context-grounding/ @gcuip @JeremyReist2 @cfauchere @CalebMartinUiPath @jordan-uipath @eteodorovici @pateljay43 @swathiJayav
|
|
88
90
|
|
|
89
91
|
# Maestro BPMN skill
|
|
90
|
-
/skills/uipath-maestro-bpmn/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh
|
|
91
|
-
/tests/tasks/uipath-maestro-bpmn/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh
|
|
92
|
+
/skills/uipath-maestro-bpmn/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh @DevMomo
|
|
93
|
+
/tests/tasks/uipath-maestro-bpmn/ @bai-uipath @rockymadden @gozhang2 @tmatup @akshaylive @jiyangzh @nikhil-maryala @baishalighosh @DevMomo
|
|
92
94
|
# API Workflow skill
|
|
93
95
|
/skills/uipath-api-workflow/ @rares-baesu-uipath @liviubobocu @mirastroie
|
|
94
96
|
/tests/tasks/uipath-api-workflow/ @rares-baesu-uipath @liviubobocu @mirastroie
|
|
@@ -100,6 +102,7 @@
|
|
|
100
102
|
# Case Management skill
|
|
101
103
|
/skills/uipath-maestro-case/ @charlesliu9 @song-zhao-25 @jundayin
|
|
102
104
|
/tests/tasks/uipath-maestro-case/ @charlesliu9 @song-zhao-25 @jundayin
|
|
105
|
+
/tests/tasks/uipath-maestro-case/guardrails/ @apetraru-uipath @valentinabojan @ctiliescuuipath
|
|
103
106
|
|
|
104
107
|
# Coded Apps skill
|
|
105
108
|
/skills/uipath-coded-apps/ @Raina451 @deepeshrai-tech @Sandeepan-Ghosh-0312 @swati354
|
|
@@ -111,8 +114,8 @@
|
|
|
111
114
|
|
|
112
115
|
# Flow skill — plugin guides (away team owned)
|
|
113
116
|
# Add your team here when contributing a new plugin category
|
|
114
|
-
/skills/uipath-maestro-flow/references/plugins/connector/ @baishalighosh @chandusailella @bai-uipath @rockymadden
|
|
115
|
-
/skills/uipath-maestro-flow/references/plugins/connector-trigger/ @baishalighosh @chandusailella @bai-uipath @rockymadden
|
|
117
|
+
/skills/uipath-maestro-flow/references/plugins/connector/ @baishalighosh @chandusailella @bai-uipath @rockymadden @DevMomo
|
|
118
|
+
/skills/uipath-maestro-flow/references/plugins/connector-trigger/ @baishalighosh @chandusailella @bai-uipath @rockymadden @DevMomo
|
|
116
119
|
/skills/uipath-maestro-flow/references/author/references/plugins/inline-agent/ @AlexandruCGhimisi @andreibalas-uipath @al3xanndru
|
|
117
120
|
/tests/tasks/uipath-maestro-flow/connector_features/ @baishalighosh
|
|
118
121
|
|
|
@@ -122,6 +125,7 @@
|
|
|
122
125
|
|
|
123
126
|
# Review skill
|
|
124
127
|
/skills/uipath-review/ @AlvinStanescu @gabrielavaduva @roalexandru
|
|
128
|
+
/skills/uipath-review/references/agents/guardrails/ @apetraru-uipath @valentinabojan @ctiliescuuipath
|
|
125
129
|
/tests/tasks/uipath-review/ @AlvinStanescu @gabrielavaduva @roalexandru
|
|
126
130
|
|
|
127
131
|
# Legacy RPA — merged into uipath-rpa
|
|
@@ -151,12 +155,15 @@
|
|
|
151
155
|
/tests/tasks/uipath-admin/ @sriramva-uipath @bansal-anushree @jianjunwang2 @t-hsia @ZuerWang99 @litheon @IsabellaCapriottiUIPath @uipathswapnil @ashleyetheridge @yadvender-uipath @CalinMPopa @chandhanshanth
|
|
152
156
|
|
|
153
157
|
# IXP skill
|
|
154
|
-
/skills/uipath-ixp/ @cezara98t @paul-ciobanu @misupantea-uipath @andrei-uipath
|
|
155
|
-
/
|
|
156
|
-
/tests/tasks/uipath-ixp/ @cezara98t @paul-ciobanu @misupantea-uipath @andrei-uipath
|
|
158
|
+
/skills/uipath-ixp/ @cezara98t @paul-ciobanu @misupantea-uipath @andrei-uipath @alexandrujircan
|
|
159
|
+
/tests/tasks/uipath-ixp/ @cezara98t @paul-ciobanu @misupantea-uipath @andrei-uipath @alexandrujircan
|
|
157
160
|
# MCP skill (UiPath AgentHub MCP server registration + tool authoring)
|
|
158
161
|
/skills/uipath-mcp-servers/ @cosminpaunel @UiPath/team-coded-agents
|
|
159
162
|
/tests/tasks/uipath-mcp-servers/ @cosminpaunel @UiPath/team-coded-agents
|
|
160
163
|
|
|
164
|
+
# Insights skill (job monitoring and analytics)
|
|
165
|
+
/skills/uipath-insights/ @suranabhavya @rliuup
|
|
166
|
+
/tests/tasks/uipath-insights/ @suranabhavya @rliuup
|
|
167
|
+
|
|
161
168
|
# Automation Discovery skill
|
|
162
169
|
/skills/uipath-automation-discovery/ @uisherif
|
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ Every skill's maturity is tracked in [`assets/skill-status.json`](assets/skill-s
|
|
|
98
98
|
| `uipath-functions` | Preview |
|
|
99
99
|
| `uipath-governance` | In-development |
|
|
100
100
|
| `uipath-human-in-the-loop` | In-development |
|
|
101
|
+
| `uipath-insights` | Preview |
|
|
101
102
|
| `uipath-ixp` | In-development |
|
|
102
103
|
| `uipath-maestro-bpmn` | In-development |
|
|
103
104
|
| `uipath-maestro-case` | In-development |
|
package/assets/skill-status.json
CHANGED
|
@@ -94,6 +94,14 @@
|
|
|
94
94
|
},
|
|
95
95
|
"last_synced": null
|
|
96
96
|
},
|
|
97
|
+
"uipath-insights": {
|
|
98
|
+
"status": "preview",
|
|
99
|
+
"confluence": {
|
|
100
|
+
"page_id": "90824180832",
|
|
101
|
+
"url": "https://uipath.atlassian.net/wiki/spaces/CA/pages/90824180832"
|
|
102
|
+
},
|
|
103
|
+
"last_synced": null
|
|
104
|
+
},
|
|
97
105
|
"uipath-ixp": {
|
|
98
106
|
"status": "in-development",
|
|
99
107
|
"confluence": {
|
package/hooks/hooks.json
CHANGED
|
@@ -5,16 +5,19 @@
|
|
|
5
5
|
"hooks": [
|
|
6
6
|
{
|
|
7
7
|
"type": "command",
|
|
8
|
-
"command": "
|
|
9
|
-
"timeout":
|
|
10
|
-
"once": true
|
|
11
|
-
"statusMessage": "Checking uip and rpa-tool installation..."
|
|
8
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/suggest-permissions.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/suggest-permissions.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
9
|
+
"timeout": 5,
|
|
10
|
+
"once": true
|
|
12
11
|
},
|
|
13
12
|
{
|
|
14
13
|
"type": "command",
|
|
15
|
-
"command": "
|
|
16
|
-
"timeout": 5
|
|
17
|
-
|
|
14
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/set-session-env.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/set-session-env.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
15
|
+
"timeout": 5
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
20
|
+
"async": true
|
|
18
21
|
}
|
|
19
22
|
]
|
|
20
23
|
}
|
|
@@ -25,7 +28,40 @@
|
|
|
25
28
|
"hooks": [
|
|
26
29
|
{
|
|
27
30
|
"type": "command",
|
|
28
|
-
"command": "
|
|
31
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
32
|
+
"async": true
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"SessionEnd": [
|
|
38
|
+
{
|
|
39
|
+
"hooks": [
|
|
40
|
+
{
|
|
41
|
+
"type": "command",
|
|
42
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
43
|
+
"timeout": 30
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"Stop": [
|
|
49
|
+
{
|
|
50
|
+
"hooks": [
|
|
51
|
+
{
|
|
52
|
+
"type": "command",
|
|
53
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
54
|
+
"async": true
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"StopFailure": [
|
|
60
|
+
{
|
|
61
|
+
"hooks": [
|
|
62
|
+
{
|
|
63
|
+
"type": "command",
|
|
64
|
+
"command": "echo `# <#` >/dev/null\nbash \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.sh\"\nexit $?\n: <<'POLYEOF' #> > $null\n& \"${CLAUDE_PLUGIN_ROOT}/hooks/send-telemetry.ps1\"\nif ($null -eq $LASTEXITCODE) { exit 1 } else { exit $LASTEXITCODE }\nPOLYEOF\n",
|
|
29
65
|
"async": true
|
|
30
66
|
}
|
|
31
67
|
]
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# Telemetry hook for the UiPath skills plugin (Claude Code).
|
|
2
|
+
#
|
|
3
|
+
# TWIN SCRIPT: hooks/send-telemetry.sh is the bash twin of this file — any
|
|
4
|
+
# behavioral change here MUST be mirrored there in the same PR (see CLAUDE.md).
|
|
5
|
+
# hooks.json runs whichever twin matches the executing shell via a
|
|
6
|
+
# bash/PowerShell polyglot command.
|
|
7
|
+
#
|
|
8
|
+
# Registered on multiple Claude Code hook events (PostToolUse, SessionStart,
|
|
9
|
+
# SessionEnd, Stop, StopFailure). Reads the hook JSON payload from stdin, maps
|
|
10
|
+
# the event to a canonical eventName, and pipes one flat JSON object to
|
|
11
|
+
# `uip track`, which forwards it through the CLI's own telemetry tracker as a
|
|
12
|
+
# single uip.skills.<event> Application Insights event.
|
|
13
|
+
#
|
|
14
|
+
# tool-use is per-call and gated on plugin attribution (skill gate) — calls from
|
|
15
|
+
# other plugins or bare Claude Code are dropped. Lifecycle events (session-start,
|
|
16
|
+
# session-end, completion) are session-scoped and fire for every session where
|
|
17
|
+
# this plugin is installed.
|
|
18
|
+
#
|
|
19
|
+
# The CLI (see UiPath/cli#2600) owns transport, the App Insights connection,
|
|
20
|
+
# the event name, the authenticated cloud identity, the `source:
|
|
21
|
+
# "skills-plugin"` dimension, and — since UiPath/cli#2806 — the
|
|
22
|
+
# environment/base_url/region base dimensions stamped fresh on every event
|
|
23
|
+
# from its own auth context (so this hook sends no environment info). This
|
|
24
|
+
# hook only derives + sanitizes fields and gates on the opt-out flag; value
|
|
25
|
+
# sanitization stays the hook's responsibility because the CLI and skills
|
|
26
|
+
# ship co-versioned.
|
|
27
|
+
#
|
|
28
|
+
# REGION-SCOPED EXTRACTION: the payload embeds free-form customer content
|
|
29
|
+
# (prompts, command lines, stdout/stderr, file contents). A naive text scan
|
|
30
|
+
# over the whole payload mis-extracts fields when that content contains
|
|
31
|
+
# JSON-shaped text (`"success":false`, `uip solution publish`, `.flow"`,
|
|
32
|
+
# `"resolvedModel":"..."`). So the payload is parsed as real JSON
|
|
33
|
+
# (ConvertFrom-Json) and each field is read ONLY from the region it lives in:
|
|
34
|
+
# ENVELOPE (top-level) -> toolName, toolUseId, session_id, permissionMode,
|
|
35
|
+
# durationMs, effortLevel (effort.level), agentType,
|
|
36
|
+
# source (-> session_source), reason (session-end),
|
|
37
|
+
# model (-> agent_model; Claude sends it on
|
|
38
|
+
# SessionStart, Codex on every event)
|
|
39
|
+
# tool_input -> skillName, uipSubcommand (command), fileExtension
|
|
40
|
+
# (file_path), subagentType (subagent_type, or
|
|
41
|
+
# agent_type for a Codex spawn_agent call)
|
|
42
|
+
# tool_response -> outcome (interrupted/success), subagentModel
|
|
43
|
+
# (resolvedModel)
|
|
44
|
+
#
|
|
45
|
+
# CROSS-AGENT: registered as a PostToolUse hook, this also runs under other
|
|
46
|
+
# coding agents that honor hooks.json (e.g. Codex). Codex's envelope matches
|
|
47
|
+
# Claude's (hook_event_name, tool_name, tool_use_id, session_id,
|
|
48
|
+
# permission_mode, tool_input/{command,file_path}), so Bash-`uip` and file
|
|
49
|
+
# attribution work unchanged. Differences handled / accepted: agent spawns use
|
|
50
|
+
# `spawn_agent` + tool_input.agent_type (see Test-UipathCall + extraction);
|
|
51
|
+
# Codex omits duration_ms / effort.level (-> durationMs null, effortLevel "")
|
|
52
|
+
# and serializes tool_response as a JSON STRING, not an object, so success /
|
|
53
|
+
# interrupted / resolvedModel are absent and outcome is ok|unknown only.
|
|
54
|
+
# Only derived, low-cardinality, PII-free values ever leave the machine.
|
|
55
|
+
#
|
|
56
|
+
# Non-blocking by contract: registered as an async hook in hooks.json
|
|
57
|
+
# ("async": true) on every event EXCEPT SessionEnd, so Claude Code runs it in
|
|
58
|
+
# the background and never waits for it. SessionEnd is registered
|
|
59
|
+
# SYNCHRONOUSLY (30s timeout): async hooks still running at session teardown
|
|
60
|
+
# are killed after a short grace window — shorter than this hook's PowerShell
|
|
61
|
+
# + `uip track` startup — which would silently drop the session-end event.
|
|
62
|
+
# Always exits 0 and swallows every error. Runs under Windows PowerShell 5.1
|
|
63
|
+
# and PowerShell 7+ (pwsh) on Windows, macOS, and Linux — no jq, node, or
|
|
64
|
+
# python.
|
|
65
|
+
#
|
|
66
|
+
# Structure: pure helpers (below), driven by Main (bottom). Configuration is
|
|
67
|
+
# env only:
|
|
68
|
+
# UIPATH_TELEMETRY_DISABLED Gate. Reuses the uip CLI's variable name.
|
|
69
|
+
# Opt-out: send by DEFAULT. Skip ONLY when set to
|
|
70
|
+
# "1". Unset (default) or "0" -> send. Absent is
|
|
71
|
+
# treated as enabled.
|
|
72
|
+
|
|
73
|
+
$ErrorActionPreference = 'SilentlyContinue'
|
|
74
|
+
|
|
75
|
+
# schemaVersion of the emitted event. Bump on ANY change to the key set so App
|
|
76
|
+
# Insights can segment events emitted with older/churned schemas. v2: adds the
|
|
77
|
+
# eventName / session_source / reason / agent_model keys, renames
|
|
78
|
+
# sessionId -> session_id (canonical casing, matches the CLI command stream,
|
|
79
|
+
# UiPath/cli#2800), and drops environment/baseUrl (the CLI stamps fresh
|
|
80
|
+
# environment/base_url/region base dimensions itself, UiPath/cli#2806).
|
|
81
|
+
$SCHEMA_VERSION = 2
|
|
82
|
+
|
|
83
|
+
# --- extraction helpers ------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
# Safe property read on a ConvertFrom-Json PSCustomObject: $null when the key
|
|
86
|
+
# is absent (never throws, never falls back to another region).
|
|
87
|
+
function Get-Prop($Obj, [string]$Name) {
|
|
88
|
+
if ($null -eq $Obj) { return $null }
|
|
89
|
+
$p = $Obj.PSObject.Properties[$Name]
|
|
90
|
+
if ($p) { return $p.Value }
|
|
91
|
+
return $null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function Test-JsonObject($Value) {
|
|
95
|
+
return ($Value -is [System.Management.Automation.PSCustomObject])
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# JSON booleans -> the literal strings 'true'/'false'; everything else -> ''.
|
|
99
|
+
function ConvertTo-BoolString($Value) {
|
|
100
|
+
if ($Value -is [bool]) { if ($Value) { return 'true' } return 'false' }
|
|
101
|
+
return ''
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# --- relevance gate --------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
# Test-UipathCall: $true if this call is attributable to the plugin, else
|
|
107
|
+
# $false. No "active plugin" field exists, so attribute per-call from
|
|
108
|
+
# tool_input signals only (command / file_path), so stdout or prompt content
|
|
109
|
+
# can never over-attribute. Matching is case-sensitive to mirror the CLI's
|
|
110
|
+
# own casing (file extensions are the deliberate case-insensitive exception).
|
|
111
|
+
function Test-UipathCall([string]$Tool, [string]$Skill, [string]$SubagentType, [string]$Command, [string]$FilePath) {
|
|
112
|
+
switch ($Tool) {
|
|
113
|
+
'Skill' {
|
|
114
|
+
if ($Skill -clike 'uipath:*' -or $Skill -clike 'uipath-*') { return $true }
|
|
115
|
+
break
|
|
116
|
+
}
|
|
117
|
+
{ $_ -cin @('Agent', 'spawn_agent') } {
|
|
118
|
+
# UiPath agents, or a built-in/generic agent type — NOT custom agents from
|
|
119
|
+
# other plugins (`<plugin>:<name>`) or user-defined ones. Claude Code spawns
|
|
120
|
+
# via `Agent` + tool_input.subagent_type; Codex via `spawn_agent` +
|
|
121
|
+
# tool_input.agent_type (extraction normalizes that to subagent_type).
|
|
122
|
+
# `default` is Codex's generic agent — the equivalent of Claude's
|
|
123
|
+
# general-purpose/claude.
|
|
124
|
+
if ($SubagentType -clike 'uipath:*' -or $SubagentType -clike 'uipath-*') { return $true }
|
|
125
|
+
if (@('general-purpose', 'Explore', 'Plan', 'claude', 'claude-code-guide', 'statusline-setup', 'fork', 'default') -ccontains $SubagentType) { return $true }
|
|
126
|
+
break
|
|
127
|
+
}
|
|
128
|
+
{ $_ -cin @('Bash', 'PowerShell') } {
|
|
129
|
+
if ($Command -cmatch '(^|[\\";|&(\s])(uip|rpa-tool)\s' -or $Command -cmatch '\$UIP\b') { return $true }
|
|
130
|
+
break
|
|
131
|
+
}
|
|
132
|
+
{ $_ -cin @('Edit', 'Write', 'Read', 'Glob', 'Grep') } {
|
|
133
|
+
if ($FilePath -imatch '\.(cs|flow|xaml|uipx|bpmn)$' -or $FilePath -imatch '(^|[/\\])(agent|caseplan|project|app\.config|action-schema)\.json$') { return $true }
|
|
134
|
+
break
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return $false
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
# --- field derivation ------------------------------------------------------
|
|
141
|
+
|
|
142
|
+
# Get-DerivedFields: skillName, uipSubcommand, fileExt from the parsed
|
|
143
|
+
# tool_input values (so stdout content can't leak in).
|
|
144
|
+
function Get-DerivedFields([string]$Tool, [string]$Skill, [string]$Command, [string]$FilePath) {
|
|
145
|
+
$derived = @{ skillName = ''; uipSubcommand = ''; fileExt = '' }
|
|
146
|
+
switch ($Tool) {
|
|
147
|
+
'Skill' {
|
|
148
|
+
$derived.skillName = $Skill
|
|
149
|
+
break
|
|
150
|
+
}
|
|
151
|
+
{ $_ -cin @('Bash', 'PowerShell') } {
|
|
152
|
+
# e.g. "solution publish" from "uip solution publish --output json".
|
|
153
|
+
$m = [regex]::Match($Command, '(uip|\$UIP)\s+[a-z][a-z-]*(\s+[a-z][a-z-]*)?')
|
|
154
|
+
if ($m.Success) {
|
|
155
|
+
$derived.uipSubcommand = $m.Value -creplace '^(uip|\$UIP)\s+', ''
|
|
156
|
+
}
|
|
157
|
+
break
|
|
158
|
+
}
|
|
159
|
+
{ $_ -cin @('Edit', 'Write', 'Read', 'Glob', 'Grep') } {
|
|
160
|
+
$m = [regex]::Match($FilePath, '\.[A-Za-z0-9]+$')
|
|
161
|
+
if ($m.Success) { $derived.fileExt = $m.Value }
|
|
162
|
+
if ($FilePath -clike '*agent.json') { $derived.fileExt = 'agent.json' }
|
|
163
|
+
if ($FilePath -clike '*caseplan.json') { $derived.fileExt = 'caseplan.json' }
|
|
164
|
+
break
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return $derived
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# Get-Outcome: outcome from the tool_response region ONLY — content never
|
|
171
|
+
# flips it.
|
|
172
|
+
# interrupted == true -> interrupted (takes precedence)
|
|
173
|
+
# success == false -> failure
|
|
174
|
+
# tool_response present, no failure signal -> ok (Read/Edit/Write/most MCP)
|
|
175
|
+
# no tool_response at all -> unknown
|
|
176
|
+
function Get-Outcome([string]$Interrupted, [string]$Success, [bool]$ResponseSeen) {
|
|
177
|
+
if ($Interrupted -eq 'true') { return 'interrupted' }
|
|
178
|
+
if ($Success -eq 'false') { return 'failure' }
|
|
179
|
+
if ($ResponseSeen) { return 'ok' }
|
|
180
|
+
return 'unknown'
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
# Get-EventName: translate the agent hook event into the canonical eventName
|
|
184
|
+
# token the CLI's `uip track` maps to a uip.skills.<event> event. An
|
|
185
|
+
# unrecognized event returns empty so Main drops it. Stop and StopFailure both
|
|
186
|
+
# map to `completion`, distinguished by outcome (see Get-LifecycleOutcome).
|
|
187
|
+
# CROSS-AGENT: Codex fires SessionStart and Stop under these SAME names with a
|
|
188
|
+
# matching envelope (session_id/source/model; docs: developers.openai.com/
|
|
189
|
+
# codex/hooks), so both map here unchanged. Codex has NO SessionEnd (completion
|
|
190
|
+
# is its terminal signal) and no StopFailure (its API-error turns are not
|
|
191
|
+
# distinguished). Gemini/Cursor use different hook names — separate follow-ups.
|
|
192
|
+
function Get-EventName([string]$HookEvent) {
|
|
193
|
+
switch ($HookEvent) {
|
|
194
|
+
'PostToolUse' { return 'tool-use' }
|
|
195
|
+
'SessionStart' { return 'session-start' }
|
|
196
|
+
'SessionEnd' { return 'session-end' }
|
|
197
|
+
'Stop' { return 'completion' }
|
|
198
|
+
'StopFailure' { return 'completion' }
|
|
199
|
+
}
|
|
200
|
+
return ''
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
# Get-LifecycleOutcome: outcome for the non-tool events. A normal turn end
|
|
204
|
+
# (Stop) is `ok`; an API-error turn end (StopFailure) is `failure`.
|
|
205
|
+
# session-start and session-end carry no turn outcome (session-end's `reason`
|
|
206
|
+
# conveys the why).
|
|
207
|
+
function Get-LifecycleOutcome([string]$HookEvent) {
|
|
208
|
+
switch ($HookEvent) {
|
|
209
|
+
'Stop' { return 'ok' }
|
|
210
|
+
'StopFailure' { return 'failure' }
|
|
211
|
+
}
|
|
212
|
+
return ''
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
# Get-ModelFamily: the low-cardinality family, dropping the context-window
|
|
216
|
+
# marker (e.g. claude-opus-4-8[1m] -> opus). Empty when absent (plain
|
|
217
|
+
# main-loop call); `other` for an unrecognized family.
|
|
218
|
+
function Get-ModelFamily([string]$Model) {
|
|
219
|
+
if (-not $Model) { return '' }
|
|
220
|
+
if ($Model -clike '*opus*') { return 'opus' }
|
|
221
|
+
if ($Model -clike '*sonnet*') { return 'sonnet' }
|
|
222
|
+
if ($Model -clike '*haiku*') { return 'haiku' }
|
|
223
|
+
if ($Model -clike '*fable*') { return 'fable' }
|
|
224
|
+
return 'other'
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
# Read-SkillsVersion: skills/CLI co-version from version-manifest.json (NOT
|
|
228
|
+
# git, NOT the plugin package version). The CLI's own app version already rides
|
|
229
|
+
# the tracker as application_Version, so no separate cliVersion is sent.
|
|
230
|
+
function Read-SkillsVersion {
|
|
231
|
+
$root = $env:CLAUDE_PLUGIN_ROOT
|
|
232
|
+
if (-not $root) { $root = '.' }
|
|
233
|
+
try { $text = [System.IO.File]::ReadAllText((Join-Path $root 'version-manifest.json')) }
|
|
234
|
+
catch { return '' }
|
|
235
|
+
$m = [regex]::Match($text, '"skillsVersion"\s*:\s*"([^"]*)"')
|
|
236
|
+
if ($m.Success) { return $m.Groups[1].Value }
|
|
237
|
+
return ''
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Get-Sanitized: sanitize free-ish text to keep the assembled JSON valid and
|
|
241
|
+
# bounded. Strips anything outside a safe charset (so no quotes / backslashes /
|
|
242
|
+
# control chars / pipes survive) and caps length.
|
|
243
|
+
function Get-Sanitized([string]$Value) {
|
|
244
|
+
if ($null -eq $Value) { return '' }
|
|
245
|
+
$s = $Value -creplace '[^A-Za-z0-9:._/ -]', '_'
|
|
246
|
+
if ($s.Length -gt 120) { $s = $s.Substring(0, 120) }
|
|
247
|
+
return $s
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
# --- main ------------------------------------------------------------------
|
|
251
|
+
function Main {
|
|
252
|
+
# Opt-out: send by default; skip only when telemetry is explicitly disabled
|
|
253
|
+
# (UIPATH_TELEMETRY_DISABLED=1 or =true). Matches the CLI's isTelemetryDisabled()
|
|
254
|
+
# gate, so `uip track` and this hook short-circuit on the same values.
|
|
255
|
+
if ($env:UIPATH_TELEMETRY_DISABLED -cin @('1', 'true')) { exit 0 }
|
|
256
|
+
|
|
257
|
+
$raw = ''
|
|
258
|
+
try { $raw = [Console]::In.ReadToEnd() } catch { exit 0 }
|
|
259
|
+
$payload = $null
|
|
260
|
+
try { $payload = $raw | ConvertFrom-Json -ErrorAction Stop } catch { exit 0 }
|
|
261
|
+
if (-not (Test-JsonObject $payload)) { exit 0 }
|
|
262
|
+
|
|
263
|
+
# ENVELOPE region.
|
|
264
|
+
$hookEvent = [string](Get-Prop $payload 'hook_event_name')
|
|
265
|
+
$tool = [string](Get-Prop $payload 'tool_name')
|
|
266
|
+
$toolUseId = [string](Get-Prop $payload 'tool_use_id')
|
|
267
|
+
$sessionId = [string](Get-Prop $payload 'session_id')
|
|
268
|
+
$permissionMode = [string](Get-Prop $payload 'permission_mode')
|
|
269
|
+
$durationMs = Get-Prop $payload 'duration_ms'
|
|
270
|
+
$agentType = [string](Get-Prop $payload 'agent_type')
|
|
271
|
+
$sessionSource = [string](Get-Prop $payload 'source')
|
|
272
|
+
$reason = [string](Get-Prop $payload 'reason')
|
|
273
|
+
$agentModel = [string](Get-Prop $payload 'model')
|
|
274
|
+
|
|
275
|
+
$effortLevel = ''
|
|
276
|
+
$effort = Get-Prop $payload 'effort'
|
|
277
|
+
if (Test-JsonObject $effort) { $effortLevel = [string](Get-Prop $effort 'level') }
|
|
278
|
+
|
|
279
|
+
# tool_input region.
|
|
280
|
+
$skill = ''; $command = ''; $filePath = ''; $subagentType = ''
|
|
281
|
+
$toolInput = Get-Prop $payload 'tool_input'
|
|
282
|
+
if (Test-JsonObject $toolInput) {
|
|
283
|
+
$skill = [string](Get-Prop $toolInput 'skill')
|
|
284
|
+
$command = [string](Get-Prop $toolInput 'command')
|
|
285
|
+
$filePath = [string](Get-Prop $toolInput 'file_path')
|
|
286
|
+
$subagentType = [string](Get-Prop $toolInput 'subagent_type')
|
|
287
|
+
# Codex spawn_agent carries the spawned type in tool_input.agent_type;
|
|
288
|
+
# normalize it to subagentType so it lands in the same field as Claude and
|
|
289
|
+
# never collides with the envelope agent_type (agentType).
|
|
290
|
+
if (-not $subagentType) { $subagentType = [string](Get-Prop $toolInput 'agent_type') }
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
# tool_response region. Presence of the KEY (any value shape) marks the
|
|
294
|
+
# response as seen; the fields are read only when it is a real object
|
|
295
|
+
# (Codex serializes tool_response as a JSON string -> ok|unknown only).
|
|
296
|
+
$responseSeen = [bool]$payload.PSObject.Properties['tool_response']
|
|
297
|
+
$interrupted = ''; $success = ''; $resolvedModel = ''
|
|
298
|
+
$toolResponse = Get-Prop $payload 'tool_response'
|
|
299
|
+
if (Test-JsonObject $toolResponse) {
|
|
300
|
+
$interrupted = ConvertTo-BoolString (Get-Prop $toolResponse 'interrupted')
|
|
301
|
+
$success = ConvertTo-BoolString (Get-Prop $toolResponse 'success')
|
|
302
|
+
$resolvedModel = [string](Get-Prop $toolResponse 'resolvedModel')
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
# Map the hook event to a canonical eventName; drop unrecognized events.
|
|
306
|
+
$eventName = Get-EventName $hookEvent
|
|
307
|
+
if (-not $eventName) { exit 0 }
|
|
308
|
+
|
|
309
|
+
# Derived only on tool-use; keep defined so the fixed key set always assembles.
|
|
310
|
+
$skillName = ''; $uipSubcommand = ''; $fileExt = ''; $subagentModel = ''
|
|
311
|
+
|
|
312
|
+
if ($eventName -eq 'tool-use') {
|
|
313
|
+
# tool-use is per-call: gate on plugin attribution, then derive tool fields.
|
|
314
|
+
if (-not (Test-UipathCall $tool $skill $subagentType $command $filePath)) { exit 0 }
|
|
315
|
+
$derived = Get-DerivedFields $tool $skill $command $filePath
|
|
316
|
+
$skillName = $derived.skillName
|
|
317
|
+
$uipSubcommand = $derived.uipSubcommand
|
|
318
|
+
$fileExt = $derived.fileExt
|
|
319
|
+
$outcome = Get-Outcome $interrupted $success $responseSeen
|
|
320
|
+
$subagentModel = Get-ModelFamily $resolvedModel
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
# Lifecycle events are session-scoped — they fire for every session where
|
|
324
|
+
# this plugin is installed (the activation-rate denominator), so they skip
|
|
325
|
+
# the per-call attribution gate and tool-field derivation.
|
|
326
|
+
$outcome = Get-LifecycleOutcome $hookEvent
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
# Enforce the per-event field scoping the contract documents: session_source
|
|
330
|
+
# only on session-start, reason only on session-end. `source`/`reason` are
|
|
331
|
+
# extracted from ANY event's envelope, so a future payload that adds either
|
|
332
|
+
# key to another event must not bleed into these dimensions.
|
|
333
|
+
if ($eventName -ne 'session-start') { $sessionSource = '' }
|
|
334
|
+
if ($eventName -ne 'session-end') { $reason = '' }
|
|
335
|
+
|
|
336
|
+
$skillsVer = Read-SkillsVersion
|
|
337
|
+
|
|
338
|
+
# durationMs is a JSON number. Emit JSON null (not 0) when absent, so a missing
|
|
339
|
+
# value doesn't skew latency aggregations. The CLI drops a null-valued
|
|
340
|
+
# property, so a missing duration records as "no data". Stays unquoted.
|
|
341
|
+
$durJson = 'null'
|
|
342
|
+
if ($null -ne $durationMs -and "$durationMs" -cmatch '^[0-9]+$') { $durJson = "$durationMs" }
|
|
343
|
+
|
|
344
|
+
# Assemble the canonical, ordered, flat JSON. The key set is defined ONCE
|
|
345
|
+
# here (fixed order, every key always emitted). Each row is
|
|
346
|
+
# (name, kind, value): `s` -> JSON string, `n` -> JSON number/literal. Every
|
|
347
|
+
# string value passes Get-Sanitized, so no quote/backslash can survive into
|
|
348
|
+
# the assembled JSON.
|
|
349
|
+
$spec = @(
|
|
350
|
+
@('schemaVersion', 'n', "$SCHEMA_VERSION"),
|
|
351
|
+
@('eventName', 's', $eventName),
|
|
352
|
+
@('toolName', 's', $tool),
|
|
353
|
+
@('skillName', 's', $skillName),
|
|
354
|
+
@('uipSubcommand', 's', $uipSubcommand),
|
|
355
|
+
@('fileExtension', 's', $fileExt),
|
|
356
|
+
@('outcome', 's', $outcome),
|
|
357
|
+
@('permissionMode', 's', $permissionMode),
|
|
358
|
+
@('effortLevel', 's', $effortLevel),
|
|
359
|
+
@('skillsVersion', 's', $skillsVer),
|
|
360
|
+
@('toolUseId', 's', $toolUseId),
|
|
361
|
+
@('session_id', 's', $sessionId),
|
|
362
|
+
@('subagentModel', 's', $subagentModel),
|
|
363
|
+
@('subagentType', 's', $subagentType),
|
|
364
|
+
@('agentType', 's', $agentType),
|
|
365
|
+
@('agent_model', 's', $agentModel),
|
|
366
|
+
@('session_source', 's', $sessionSource),
|
|
367
|
+
@('reason', 's', $reason),
|
|
368
|
+
@('durationMs', 'n', $durJson)
|
|
369
|
+
)
|
|
370
|
+
$parts = foreach ($field in $spec) {
|
|
371
|
+
if ($field[1] -eq 'n') { '"' + $field[0] + '":' + $field[2] }
|
|
372
|
+
else { '"' + $field[0] + '":"' + (Get-Sanitized $field[2]) + '"' }
|
|
373
|
+
}
|
|
374
|
+
$json = '{' + ($parts -join ',') + '}'
|
|
375
|
+
|
|
376
|
+
# Hand off to the CLI telemetry tracker. The CLI maps our eventName token to
|
|
377
|
+
# the uip.skills.<event> name, stamps source: "skills-plugin", attaches the
|
|
378
|
+
# authenticated cloud identity + CLI app version, owns transport + flush,
|
|
379
|
+
# redacts PII, and drops any non-scalar value (so a null durationMs
|
|
380
|
+
# disappears). Send no envelope and no `source` (the CLI overrides it).
|
|
381
|
+
#
|
|
382
|
+
# `uip track` is never-fail (exits 0, emits nothing when telemetry is opted
|
|
383
|
+
# out); piping to it is harmless even if the CLI is absent (the catch
|
|
384
|
+
# swallows the command-not-found error). The hook is registered async in
|
|
385
|
+
# hooks.json (sync with a 30s timeout on SessionEnd — see header), so the
|
|
386
|
+
# agent never waits on this call mid-session.
|
|
387
|
+
try { $json | & uip track *> $null } catch { }
|
|
388
|
+
|
|
389
|
+
exit 0
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
Main
|