@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
package/hooks/send-telemetry.sh
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
#
|
|
2
|
+
# Telemetry hook for the UiPath skills plugin (Claude Code).
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# which forwards it through the CLI's own telemetry tracker as a
|
|
8
|
-
# uip.skills
|
|
9
|
-
#
|
|
4
|
+
# Registered on multiple Claude Code hook events (PostToolUse, SessionStart,
|
|
5
|
+
# SessionEnd, Stop, StopFailure). Reads the hook JSON payload from stdin, maps
|
|
6
|
+
# the event to a canonical eventName, and pipes one flat JSON object to
|
|
7
|
+
# `uip track`, which forwards it through the CLI's own telemetry tracker as a
|
|
8
|
+
# single uip.skills.<event> Application Insights event.
|
|
9
|
+
#
|
|
10
|
+
# tool-use is per-call and gated on plugin attribution (skill gate) — calls from
|
|
11
|
+
# other plugins or bare Claude Code are dropped. Lifecycle events (session-start,
|
|
12
|
+
# session-end, completion) are session-scoped and fire for every session where
|
|
13
|
+
# this plugin is installed.
|
|
10
14
|
#
|
|
11
15
|
# The CLI (see UiPath/cli#2600) owns transport, the App Insights connection,
|
|
12
|
-
# the event name, the authenticated cloud identity,
|
|
13
|
-
# "skills-plugin"` dimension
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
+
# the event name, the authenticated cloud identity, the `source:
|
|
17
|
+
# "skills-plugin"` dimension, and — since UiPath/cli#2806 — the
|
|
18
|
+
# environment/base_url/region base dimensions stamped fresh on every event
|
|
19
|
+
# from its own auth context (so this hook sends no environment info). This
|
|
20
|
+
# hook only derives + sanitizes fields and gates on the opt-out flag; value
|
|
21
|
+
# sanitization stays the hook's responsibility because the CLI and skills
|
|
22
|
+
# ship co-versioned.
|
|
16
23
|
#
|
|
17
24
|
# REGION-SCOPED EXTRACTION (see extract_fields): the payload embeds free-form
|
|
18
25
|
# customer content (prompts, command lines, stdout/stderr, file contents). A
|
|
@@ -20,8 +27,11 @@
|
|
|
20
27
|
# contains JSON-shaped text (`"success":false`, `uip solution publish`,
|
|
21
28
|
# `.flow"`, `"resolvedModel":"..."`). So a single string-aware awk pass walks
|
|
22
29
|
# the JSON once and pulls each field ONLY from the region it lives in:
|
|
23
|
-
# ENVELOPE (top-level) -> toolName, toolUseId,
|
|
24
|
-
# durationMs, effortLevel (effort.level), agentType
|
|
30
|
+
# ENVELOPE (top-level) -> toolName, toolUseId, session_id, permissionMode,
|
|
31
|
+
# durationMs, effortLevel (effort.level), agentType,
|
|
32
|
+
# source (-> session_source), reason (session-end),
|
|
33
|
+
# model (-> agent_model; Claude sends it on
|
|
34
|
+
# SessionStart, Codex on every event)
|
|
25
35
|
# tool_input -> skillName, uipSubcommand (command), fileExtension
|
|
26
36
|
# (file_path), subagentType (subagent_type, or
|
|
27
37
|
# agent_type for a Codex spawn_agent call)
|
|
@@ -39,11 +49,19 @@
|
|
|
39
49
|
# interrupted / resolvedModel are absent and outcome is ok|unknown only.
|
|
40
50
|
# Only derived, low-cardinality, PII-free values ever leave the machine.
|
|
41
51
|
#
|
|
52
|
+
# TWIN SCRIPT: hooks/send-telemetry.ps1 is the PowerShell twin of this file —
|
|
53
|
+
# any behavioral change here MUST be mirrored there in the same PR (see
|
|
54
|
+
# CLAUDE.md). hooks.json runs whichever twin matches the executing shell via a
|
|
55
|
+
# bash/PowerShell polyglot command.
|
|
56
|
+
#
|
|
42
57
|
# Non-blocking by contract: registered as an async hook in hooks.json
|
|
43
|
-
# ("async": true), so Claude Code runs it in
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
58
|
+
# ("async": true) on every event EXCEPT SessionEnd, so Claude Code runs it in
|
|
59
|
+
# the background and never waits for it. SessionEnd is registered
|
|
60
|
+
# SYNCHRONOUSLY (30s timeout): async hooks still running at session teardown
|
|
61
|
+
# are killed after a short grace window, which would silently drop the
|
|
62
|
+
# session-end event. Always exits 0, swallows every error, and pipes to
|
|
63
|
+
# `uip track` in a detached subshell. Cross-platform (macOS, Linux, Windows
|
|
64
|
+
# via Git Bash / MSYS). Pure bash + grep/sed/awk — no jq, node, or python.
|
|
47
65
|
#
|
|
48
66
|
# Structure: pure helpers + side-effecting procedures (below), driven by main()
|
|
49
67
|
# (bottom). Configuration is env only:
|
|
@@ -55,8 +73,12 @@
|
|
|
55
73
|
set +e
|
|
56
74
|
|
|
57
75
|
# schemaVersion of the emitted event. Bump on ANY change to the key set so App
|
|
58
|
-
# Insights can segment events emitted with older/churned schemas.
|
|
59
|
-
|
|
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
|
|
60
82
|
|
|
61
83
|
# --- extraction ------------------------------------------------------------
|
|
62
84
|
|
|
@@ -73,7 +95,7 @@ extract_fields() {
|
|
|
73
95
|
if (d == 1)
|
|
74
96
|
return (k=="tool_name"||k=="tool_use_id"||k=="session_id"|| \
|
|
75
97
|
k=="permission_mode"||k=="duration_ms"||k=="agent_type"|| \
|
|
76
|
-
k=="hook_event_name")
|
|
98
|
+
k=="hook_event_name"||k=="source"||k=="reason"||k=="model")
|
|
77
99
|
if (d == 2 && c == "input")
|
|
78
100
|
return (k=="skill"||k=="command"||k=="file_path"||k=="subagent_type"|| \
|
|
79
101
|
k=="agent_type")
|
|
@@ -173,7 +195,8 @@ read_fields() {
|
|
|
173
195
|
event=""; tool=""; tool_use_id=""; session_id=""; permission_mode=""
|
|
174
196
|
duration_ms=""; agent_type=""; skill=""; command=""; file_path=""
|
|
175
197
|
subagent_type=""; interrupted=""; success=""; resolved_model=""
|
|
176
|
-
effort_level=""; response_seen=""
|
|
198
|
+
effort_level=""; response_seen=""; session_source=""; reason=""
|
|
199
|
+
agent_model=""
|
|
177
200
|
local k v
|
|
178
201
|
while IFS="$(printf '\t')" read -r k v; do
|
|
179
202
|
case "$k" in
|
|
@@ -184,6 +207,9 @@ read_fields() {
|
|
|
184
207
|
permission_mode) permission_mode="$v" ;;
|
|
185
208
|
duration_ms) duration_ms="$v" ;;
|
|
186
209
|
agent_type) agent_type="$v" ;;
|
|
210
|
+
source) session_source="$v" ;;
|
|
211
|
+
reason) reason="$v" ;;
|
|
212
|
+
model) agent_model="$v" ;;
|
|
187
213
|
skill) skill="$v" ;;
|
|
188
214
|
command) command="$v" ;;
|
|
189
215
|
file_path) file_path="$v" ;;
|
|
@@ -233,54 +259,6 @@ is_uipath_call() {
|
|
|
233
259
|
return 1
|
|
234
260
|
}
|
|
235
261
|
|
|
236
|
-
# --- environment resolution ------------------------------------------------
|
|
237
|
-
|
|
238
|
-
# cache_val <file> <key>: emit a cached value stripped to a safe charset. Parses
|
|
239
|
-
# the cache as DATA — never `source` it, so a tampered cache can't execute
|
|
240
|
-
# arbitrary shell in this hook's context.
|
|
241
|
-
cache_val() {
|
|
242
|
-
grep -E "^$2=" "$1" 2>/dev/null | head -1 | cut -d= -f2- | tr -cd 'A-Za-z0-9:._/-'
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
# resolve_environment: set env_name + base_url from `uip login status` (~0.5s),
|
|
246
|
-
# cached per-user for 1h so only one tool call per hour pays the cost. The cache
|
|
247
|
-
# dir is per-user, owner-only (NOT world-writable /tmp), so another local user
|
|
248
|
-
# can't pre-create the file. chmod is a no-op on Windows but harmless.
|
|
249
|
-
resolve_environment() {
|
|
250
|
-
local cache_dir cache ttl now _ts status_json
|
|
251
|
-
cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/uipath-telemetry"
|
|
252
|
-
mkdir -p "$cache_dir" 2>/dev/null && chmod 700 "$cache_dir" 2>/dev/null
|
|
253
|
-
cache="$cache_dir/env.cache"
|
|
254
|
-
ttl=3600
|
|
255
|
-
now="$(date +%s 2>/dev/null || echo 0)"
|
|
256
|
-
|
|
257
|
-
env_name="unknown"; base_url=""; _ts=0
|
|
258
|
-
if [ -f "$cache" ]; then
|
|
259
|
-
_ts="$(cache_val "$cache" _ts)"
|
|
260
|
-
env_name="$(cache_val "$cache" env_name)"
|
|
261
|
-
base_url="$(cache_val "$cache" base_url)"
|
|
262
|
-
case "$_ts" in *[!0-9]*|"") _ts=0 ;; esac # non-numeric -> treat as stale
|
|
263
|
-
fi
|
|
264
|
-
|
|
265
|
-
[ "$(( now - _ts ))" -ge "$ttl" ] || return 0
|
|
266
|
-
|
|
267
|
-
status_json="$(uip login status --output json 2>/dev/null)"
|
|
268
|
-
base_url="$(printf '%s' "$status_json" \
|
|
269
|
-
| grep -oE '"BaseUrl"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')"
|
|
270
|
-
case "$base_url" in
|
|
271
|
-
*alpha.uipath.com*) env_name="alpha" ;;
|
|
272
|
-
*staging.uipath.com*) env_name="staging" ;;
|
|
273
|
-
*cloud.uipath.com*) env_name="prod" ;;
|
|
274
|
-
"") env_name="unknown" ;;
|
|
275
|
-
*) env_name="other" ;;
|
|
276
|
-
esac
|
|
277
|
-
{
|
|
278
|
-
echo "_ts=$now"
|
|
279
|
-
echo "env_name=$env_name"
|
|
280
|
-
echo "base_url=$base_url"
|
|
281
|
-
} > "$cache" 2>/dev/null
|
|
282
|
-
}
|
|
283
|
-
|
|
284
262
|
# --- field derivation ------------------------------------------------------
|
|
285
263
|
|
|
286
264
|
# derive_fields: set skill_name, uip_subcommand, file_ext from the parsed
|
|
@@ -321,6 +299,36 @@ compute_outcome() {
|
|
|
321
299
|
fi
|
|
322
300
|
}
|
|
323
301
|
|
|
302
|
+
# map_event_name: translate the agent hook event into the canonical eventName
|
|
303
|
+
# token the CLI's `uip track` maps to a uip.skills.<event> event. An
|
|
304
|
+
# unrecognized event prints empty so main() drops it. Stop and StopFailure both
|
|
305
|
+
# map to `completion`, distinguished by outcome (see lifecycle_outcome).
|
|
306
|
+
# CROSS-AGENT: Codex fires SessionStart and Stop under these SAME names with a
|
|
307
|
+
# matching envelope (session_id/source/model; docs: developers.openai.com/
|
|
308
|
+
# codex/hooks), so both map here unchanged. Codex has NO SessionEnd (completion
|
|
309
|
+
# is its terminal signal) and no StopFailure (its API-error turns are not
|
|
310
|
+
# distinguished). Gemini/Cursor use different hook names — separate follow-ups.
|
|
311
|
+
map_event_name() {
|
|
312
|
+
case "$event" in
|
|
313
|
+
PostToolUse) printf 'tool-use' ;;
|
|
314
|
+
SessionStart) printf 'session-start' ;;
|
|
315
|
+
SessionEnd) printf 'session-end' ;;
|
|
316
|
+
Stop|StopFailure) printf 'completion' ;;
|
|
317
|
+
*) printf '' ;;
|
|
318
|
+
esac
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
# lifecycle_outcome: outcome for the non-tool events. A normal turn end (Stop)
|
|
322
|
+
# is `ok`; an API-error turn end (StopFailure) is `failure`. session-start and
|
|
323
|
+
# session-end carry no turn outcome (session-end's `reason` conveys the why).
|
|
324
|
+
lifecycle_outcome() {
|
|
325
|
+
case "$event" in
|
|
326
|
+
Stop) printf 'ok' ;;
|
|
327
|
+
StopFailure) printf 'failure' ;;
|
|
328
|
+
*) printf '' ;;
|
|
329
|
+
esac
|
|
330
|
+
}
|
|
331
|
+
|
|
324
332
|
# model_family <resolvedModel>: print the low-cardinality family and drop the
|
|
325
333
|
# context-window marker (e.g. claude-opus-4-8[1m] -> opus). Empty when absent
|
|
326
334
|
# (plain main-loop call); `other` for an unrecognized family.
|
|
@@ -357,21 +365,23 @@ san() { printf '%s' "$1" | tr -c 'A-Za-z0-9:._/ -' '_' | cut -c1-120; }
|
|
|
357
365
|
build_event_json() {
|
|
358
366
|
local spec json sep fkey ftyp fval
|
|
359
367
|
spec="schemaVersion|n|$SCHEMA_VERSION
|
|
368
|
+
eventName|s|$event_name
|
|
360
369
|
toolName|s|$tool
|
|
361
370
|
skillName|s|$skill_name
|
|
362
371
|
uipSubcommand|s|$uip_subcommand
|
|
363
372
|
fileExtension|s|$file_ext
|
|
364
|
-
environment|s|$env_name
|
|
365
|
-
baseUrl|s|$base_url
|
|
366
373
|
outcome|s|$outcome
|
|
367
374
|
permissionMode|s|$permission_mode
|
|
368
375
|
effortLevel|s|$effort_level
|
|
369
376
|
skillsVersion|s|$skills_ver
|
|
370
377
|
toolUseId|s|$tool_use_id
|
|
371
|
-
|
|
378
|
+
session_id|s|$session_id
|
|
372
379
|
subagentModel|s|$subagent_model
|
|
373
380
|
subagentType|s|$subagent_type
|
|
374
381
|
agentType|s|$agent_type
|
|
382
|
+
agent_model|s|$agent_model
|
|
383
|
+
session_source|s|$session_source
|
|
384
|
+
reason|s|$reason
|
|
375
385
|
durationMs|n|$dur_json"
|
|
376
386
|
json="{"; sep=""
|
|
377
387
|
while IFS='|' read -r fkey ftyp fval; do
|
|
@@ -397,27 +407,46 @@ main() {
|
|
|
397
407
|
payload="$(cat)"
|
|
398
408
|
read_fields "$(printf '%s' "$payload" | extract_fields)"
|
|
399
409
|
|
|
400
|
-
|
|
401
|
-
|
|
410
|
+
# Map the hook event to a canonical eventName; drop unrecognized events.
|
|
411
|
+
event_name="$(map_event_name)"
|
|
412
|
+
[ -n "$event_name" ] || exit 0
|
|
402
413
|
|
|
403
|
-
|
|
404
|
-
|
|
414
|
+
# Derived only on tool-use; keep defined so the fixed key set always assembles.
|
|
415
|
+
skill_name=""; uip_subcommand=""; file_ext=""; subagent_model=""
|
|
416
|
+
|
|
417
|
+
if [ "$event_name" = "tool-use" ]; then
|
|
418
|
+
# tool-use is per-call: gate on plugin attribution, then derive tool fields.
|
|
419
|
+
is_uipath_call || exit 0
|
|
420
|
+
derive_fields
|
|
421
|
+
outcome="$(compute_outcome)"
|
|
422
|
+
subagent_model="$(model_family "$resolved_model")"
|
|
423
|
+
else
|
|
424
|
+
# Lifecycle events are session-scoped — they fire for every session where
|
|
425
|
+
# this plugin is installed (the activation-rate denominator), so they skip
|
|
426
|
+
# the per-call attribution gate and tool-field derivation.
|
|
427
|
+
outcome="$(lifecycle_outcome)"
|
|
428
|
+
fi
|
|
429
|
+
|
|
430
|
+
# Enforce the per-event field scoping the contract documents: session_source
|
|
431
|
+
# only on session-start, reason only on session-end. The awk pass extracts
|
|
432
|
+
# `source`/`reason` from ANY event's envelope, so a future payload that adds
|
|
433
|
+
# either key to another event must not bleed into these dimensions.
|
|
434
|
+
[ "$event_name" = "session-start" ] || session_source=""
|
|
435
|
+
[ "$event_name" = "session-end" ] || reason=""
|
|
436
|
+
|
|
437
|
+
skills_ver="$(read_skills_version)"
|
|
405
438
|
|
|
406
|
-
outcome="$(compute_outcome)"
|
|
407
439
|
# durationMs is a JSON number. Emit JSON null (not 0) when absent, so a missing
|
|
408
440
|
# value doesn't skew latency aggregations. The CLI drops a null-valued
|
|
409
441
|
# property, so a missing duration records as "no data". Stays unquoted.
|
|
410
442
|
case "$duration_ms" in ''|*[!0-9]*) dur_json="null" ;; *) dur_json="$duration_ms" ;; esac
|
|
411
|
-
subagent_model="$(model_family "$resolved_model")"
|
|
412
|
-
skills_ver="$(read_skills_version)"
|
|
413
443
|
|
|
414
444
|
# Sanitize every string field before assembly.
|
|
445
|
+
event_name="$(san "$event_name")"
|
|
415
446
|
tool="$(san "$tool")"
|
|
416
447
|
skill_name="$(san "$skill_name")"
|
|
417
448
|
uip_subcommand="$(san "$uip_subcommand")"
|
|
418
449
|
file_ext="$(san "$file_ext")"
|
|
419
|
-
env_name="$(san "$env_name")"
|
|
420
|
-
base_url="$(san "$base_url")"
|
|
421
450
|
outcome="$(san "$outcome")"
|
|
422
451
|
permission_mode="$(san "$permission_mode")"
|
|
423
452
|
effort_level="$(san "$effort_level")"
|
|
@@ -427,12 +456,15 @@ main() {
|
|
|
427
456
|
subagent_model="$(san "$subagent_model")"
|
|
428
457
|
subagent_type="$(san "$subagent_type")"
|
|
429
458
|
agent_type="$(san "$agent_type")"
|
|
459
|
+
agent_model="$(san "$agent_model")"
|
|
460
|
+
session_source="$(san "$session_source")"
|
|
461
|
+
reason="$(san "$reason")"
|
|
430
462
|
|
|
431
|
-
# Hand off to the CLI telemetry tracker. The CLI
|
|
432
|
-
#
|
|
433
|
-
# authenticated cloud identity + CLI app version,
|
|
434
|
-
#
|
|
435
|
-
#
|
|
463
|
+
# Hand off to the CLI telemetry tracker. The CLI maps our eventName token to
|
|
464
|
+
# the uip.skills.<event> name, stamps source: "skills-plugin", attaches the
|
|
465
|
+
# authenticated cloud identity + CLI app version, owns transport + flush,
|
|
466
|
+
# redacts PII, and drops any non-scalar value (so a null durationMs
|
|
467
|
+
# disappears). Send no envelope and no `source` (the CLI overrides it).
|
|
436
468
|
#
|
|
437
469
|
# Detached subshell ( cmd & ) survives this hook's exit so the agent never
|
|
438
470
|
# waits. `uip track` is never-fail (exits 0, emits nothing when telemetry is
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# SessionStart step: export the agent's session id to the uip CLI.
|
|
2
|
+
#
|
|
3
|
+
# TWIN SCRIPT: hooks/set-session-env.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
|
+
#
|
|
6
|
+
# Reads the SessionStart payload on stdin, takes its top-level `session_id`,
|
|
7
|
+
# and appends `export UIPATH_SESSION_ID='<id>'` to $env:CLAUDE_ENV_FILE so
|
|
8
|
+
# every subsequent shell tool subprocess — and therefore every `uip` command
|
|
9
|
+
# the agent runs — inherits it. The CLI stamps that value as the `session_id`
|
|
10
|
+
# dimension on native command telemetry (UiPath/cli#2800), which joins the
|
|
11
|
+
# command stream with the skills events emitted by send-telemetry.ps1: both
|
|
12
|
+
# streams then carry the same session id.
|
|
13
|
+
#
|
|
14
|
+
# Registered SYNCHRONOUSLY in hooks.json (no "async": true): the write must
|
|
15
|
+
# complete before the session's first shell call, or early `uip` commands
|
|
16
|
+
# would miss the id. Costs a few ms (regex only, no network, no uip call).
|
|
17
|
+
#
|
|
18
|
+
# Deliberately NOT gated on UIPATH_TELEMETRY_DISABLED: writing a variable
|
|
19
|
+
# transmits nothing — whether any event carrying it is ever sent stays
|
|
20
|
+
# governed by the CLI's own telemetry gate.
|
|
21
|
+
#
|
|
22
|
+
# Safety:
|
|
23
|
+
# - host wins: no-op when UIPATH_SESSION_ID is already set in the env;
|
|
24
|
+
# - idempotent: no-op when the env file already exports it;
|
|
25
|
+
# - injection-safe: $env:CLAUDE_ENV_FILE is sourced by the agent, so the
|
|
26
|
+
# value is stripped to [A-Za-z0-9._-] and length-capped before being
|
|
27
|
+
# written inside single quotes (agent session ids are UUIDs, so a
|
|
28
|
+
# legitimate value is never altered);
|
|
29
|
+
# - never-fail: always exits 0, never blocks the session.
|
|
30
|
+
#
|
|
31
|
+
# Runs under Windows PowerShell 5.1 and PowerShell 7+ (pwsh).
|
|
32
|
+
|
|
33
|
+
$ErrorActionPreference = 'SilentlyContinue'
|
|
34
|
+
|
|
35
|
+
function Main {
|
|
36
|
+
$envFile = $env:CLAUDE_ENV_FILE
|
|
37
|
+
if (-not $envFile) { exit 0 }
|
|
38
|
+
if ($env:UIPATH_SESSION_ID) { exit 0 }
|
|
39
|
+
|
|
40
|
+
$existing = ''
|
|
41
|
+
if (Test-Path -LiteralPath $envFile -PathType Leaf) {
|
|
42
|
+
try { $existing = [System.IO.File]::ReadAllText($envFile) } catch { $existing = '' }
|
|
43
|
+
if ($existing -cmatch '(?m)^export UIPATH_SESSION_ID=') { exit 0 }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# Top-level `session_id` from the SessionStart payload. The payload for this
|
|
47
|
+
# event is small and carries no tool output, and the value is hard-sanitized
|
|
48
|
+
# anyway, so a plain regex is sufficient here (no full JSON parse needed).
|
|
49
|
+
$payload = ''
|
|
50
|
+
try { $payload = [Console]::In.ReadToEnd() } catch { exit 0 }
|
|
51
|
+
$sid = ''
|
|
52
|
+
$m = [regex]::Match($payload, '"session_id"\s*:\s*"([^"]*)"')
|
|
53
|
+
if ($m.Success) { $sid = $m.Groups[1].Value }
|
|
54
|
+
$sid = $sid -replace '[^A-Za-z0-9._-]', ''
|
|
55
|
+
if ($sid.Length -gt 64) { $sid = $sid.Substring(0, 64) }
|
|
56
|
+
if (-not $sid) { exit 0 }
|
|
57
|
+
|
|
58
|
+
# If the file exists but doesn't end with a newline (another hook's partial
|
|
59
|
+
# write), appending directly would concatenate onto its last line and could
|
|
60
|
+
# break the sourced env file for the whole session — repair it first.
|
|
61
|
+
$prefix = ''
|
|
62
|
+
if ($existing -and -not $existing.EndsWith("`n")) { $prefix = "`n" }
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
[System.IO.File]::AppendAllText($envFile, "${prefix}export UIPATH_SESSION_ID='$sid'`n")
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
|
|
69
|
+
exit 0
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Main
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# SessionStart step: export the agent's session id to the uip CLI.
|
|
3
|
+
#
|
|
4
|
+
# TWIN SCRIPT: hooks/set-session-env.ps1 is the PowerShell twin of this file —
|
|
5
|
+
# any behavioral change here MUST be mirrored there in the same PR (see
|
|
6
|
+
# CLAUDE.md).
|
|
7
|
+
#
|
|
8
|
+
# Reads the SessionStart payload on stdin, takes its top-level `session_id`,
|
|
9
|
+
# and appends `export UIPATH_SESSION_ID='<id>'` to $CLAUDE_ENV_FILE so every
|
|
10
|
+
# subsequent Bash tool subprocess — and therefore every `uip` command the
|
|
11
|
+
# agent runs — inherits it. The CLI stamps that value as the `session_id`
|
|
12
|
+
# dimension on native command telemetry (UiPath/cli#2800), which joins the
|
|
13
|
+
# command stream with the skills events emitted by send-telemetry.sh: both
|
|
14
|
+
# streams then carry the same session id.
|
|
15
|
+
#
|
|
16
|
+
# Registered SYNCHRONOUSLY in hooks.json (no "async": true): the write must
|
|
17
|
+
# complete before the session's first Bash call, or early `uip` commands would
|
|
18
|
+
# miss the id. Costs a few ms (grep/sed/tr only, no network, no uip call).
|
|
19
|
+
#
|
|
20
|
+
# Deliberately NOT gated on UIPATH_TELEMETRY_DISABLED: writing a variable
|
|
21
|
+
# transmits nothing — whether any event carrying it is ever sent stays
|
|
22
|
+
# governed by the CLI's own telemetry gate.
|
|
23
|
+
#
|
|
24
|
+
# Safety:
|
|
25
|
+
# - host wins: no-op when UIPATH_SESSION_ID is already set in the env;
|
|
26
|
+
# - idempotent: no-op when the env file already exports it;
|
|
27
|
+
# - injection-safe: $CLAUDE_ENV_FILE is sourced by the agent, so the value
|
|
28
|
+
# is stripped to [A-Za-z0-9._-] and length-capped before being written
|
|
29
|
+
# inside single quotes (agent session ids are UUIDs, so a legitimate
|
|
30
|
+
# value is never altered);
|
|
31
|
+
# - never-fail: always exits 0, never blocks the session.
|
|
32
|
+
|
|
33
|
+
set +e
|
|
34
|
+
|
|
35
|
+
main() {
|
|
36
|
+
[ -n "$CLAUDE_ENV_FILE" ] || exit 0
|
|
37
|
+
[ -z "$UIPATH_SESSION_ID" ] || exit 0
|
|
38
|
+
if [ -f "$CLAUDE_ENV_FILE" ] \
|
|
39
|
+
&& grep -q '^export UIPATH_SESSION_ID=' "$CLAUDE_ENV_FILE" 2>/dev/null; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Top-level `session_id` from the SessionStart payload. The payload for this
|
|
44
|
+
# event is small and carries no tool output, and the value is hard-sanitized
|
|
45
|
+
# anyway, so a plain grep is sufficient here (no region-scoped pass needed).
|
|
46
|
+
sid="$(grep -oE '"session_id"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
|
47
|
+
| head -1 | sed 's/.*"\([^"]*\)"$/\1/' | tr -cd 'A-Za-z0-9._-' | cut -c1-64)"
|
|
48
|
+
[ -n "$sid" ] || exit 0
|
|
49
|
+
|
|
50
|
+
# If the file exists but doesn't end with a newline (another hook's partial
|
|
51
|
+
# write), appending directly would concatenate onto its last line and could
|
|
52
|
+
# break the sourced env file for the whole session — repair it first.
|
|
53
|
+
# `tail -c 1` in a $() strips a trailing newline, so "" means the file is
|
|
54
|
+
# newline-terminated.
|
|
55
|
+
if [ -s "$CLAUDE_ENV_FILE" ] && [ -n "$(tail -c 1 "$CLAUDE_ENV_FILE" 2>/dev/null)" ]; then
|
|
56
|
+
printf '\n' >> "$CLAUDE_ENV_FILE" 2>/dev/null
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
printf "export UIPATH_SESSION_ID='%s'\n" "$sid" >> "$CLAUDE_ENV_FILE" 2>/dev/null
|
|
60
|
+
|
|
61
|
+
exit 0
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Detects whether Claude Code has an allowlist for `uip` subcommands.
|
|
2
|
+
# If none is found, prints a one-line nudge pointing at /uipath:install-permissions.
|
|
3
|
+
# Non-blocking — never fails the session, even if detection fails.
|
|
4
|
+
# Runs under Windows PowerShell 5.1 and PowerShell 7+ (pwsh).
|
|
5
|
+
#
|
|
6
|
+
# TWIN SCRIPT: hooks/suggest-permissions.sh is the bash twin of this file —
|
|
7
|
+
# any behavioral change here MUST be mirrored there in the same PR (see
|
|
8
|
+
# CLAUDE.md).
|
|
9
|
+
|
|
10
|
+
$ErrorActionPreference = 'SilentlyContinue'
|
|
11
|
+
|
|
12
|
+
# Only run inside a Claude Code plugin context.
|
|
13
|
+
if (-not $env:CLAUDE_PLUGIN_ROOT) { exit 0 }
|
|
14
|
+
|
|
15
|
+
# Codex exposes Claude-compatible plugin environment variables for hook
|
|
16
|
+
# compatibility. This nudge is Claude-specific, so keep Codex sessions silent.
|
|
17
|
+
if ($env:PLUGIN_ROOT) { exit 0 }
|
|
18
|
+
|
|
19
|
+
# Candidate settings files, most-to-least specific.
|
|
20
|
+
$candidates = @()
|
|
21
|
+
if ($env:CLAUDE_PROJECT_DIR) {
|
|
22
|
+
$candidates += Join-Path $env:CLAUDE_PROJECT_DIR '.claude/settings.local.json'
|
|
23
|
+
$candidates += Join-Path $env:CLAUDE_PROJECT_DIR '.claude/settings.json'
|
|
24
|
+
}
|
|
25
|
+
$cwd = (Get-Location).Path
|
|
26
|
+
$candidates += Join-Path $cwd '.claude/settings.local.json'
|
|
27
|
+
$candidates += Join-Path $cwd '.claude/settings.json'
|
|
28
|
+
$candidates += Join-Path $HOME '.claude/settings.json'
|
|
29
|
+
|
|
30
|
+
# If any candidate already mentions Bash(uip...) in its permissions, stay silent.
|
|
31
|
+
# Intentional simplification: this matches `allow`, `ask`, AND `deny` blocks.
|
|
32
|
+
# Any explicit `uip` rule means the user has made a decision about this CLI —
|
|
33
|
+
# we don't second-guess by nudging them toward a permissive allowlist.
|
|
34
|
+
foreach ($f in $candidates) {
|
|
35
|
+
if (-not (Test-Path -LiteralPath $f -PathType Leaf)) { continue }
|
|
36
|
+
try {
|
|
37
|
+
if (Select-String -LiteralPath $f -Pattern 'Bash(uip' -SimpleMatch -Quiet) { exit 0 }
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# No allowlist detected — print a one-line nudge to stderr (the Claude Code
|
|
43
|
+
# SessionStart convention for status messages).
|
|
44
|
+
[Console]::Error.WriteLine('uipath: To skip 25+ approval prompts per uip build, run: /uipath:install-permissions')
|
|
45
|
+
exit 0
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
# If none is found, prints a one-line nudge pointing at /uipath:install-permissions.
|
|
4
4
|
# Non-blocking — never fails the session, even if detection fails.
|
|
5
5
|
# Cross-platform (macOS, Linux, Windows via Git Bash / MSYS / Cygwin).
|
|
6
|
+
#
|
|
7
|
+
# TWIN SCRIPT: hooks/suggest-permissions.ps1 is the PowerShell twin of this
|
|
8
|
+
# file — any behavioral change here MUST be mirrored there in the same PR (see
|
|
9
|
+
# CLAUDE.md).
|
|
6
10
|
|
|
7
11
|
# Only run inside a Claude Code plugin context.
|
|
8
12
|
if [ -z "${CLAUDE_PLUGIN_ROOT:-}" ]; then
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/skills",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.198.0",
|
|
4
4
|
"description": "UiPath agent skills for Claude Code, Codex, Cursor, Copilot, Gemini and OpenCode — RPA, UI automation, UI testing, coded agents/apps/workflows, and troubleshooting. Distributed as the UiPath Claude Code plugin.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "UiPath"
|
|
@@ -200,8 +200,8 @@ uip admin audit tenant export \
|
|
|
200
200
|
**Implementation notes (worth knowing for diagnostic conversations):**
|
|
201
201
|
|
|
202
202
|
- Both formats share the same fetch: the CLI issues **one HTTP call per UTC day** inside `[from, to]` and aggregates the per-day responses. Mirrors the `audit-dowload-from-longterm-store.sh` pattern in the AuditService repo.
|
|
203
|
-
- **JSON (default):** a uniquely-named `audit_<from>_<to>_<generated-at>` **folder** is created under `--output-path`, holding one file per UTC day named `<YYYY-MM-DD>.json` (nested-ZIP entries from the server are flattened to `<inner>_<outer>.json`; same-name collisions get an iso-day suffix). The server names the per-day payloads `.txt`; the CLI writes them with a `.json` extension since each is a JSON array of events with
|
|
204
|
-
- **CSV:** the same per-day JSON arrays are parsed and merged into **one** RFC 4180 CSV (CRLF line endings, header row first). Columns follow the long-term-store field order — `
|
|
203
|
+
- **JSON (default):** a uniquely-named `audit_<from>_<to>_<generated-at>` **folder** is created under `--output-path`, holding one file per UTC day named `<YYYY-MM-DD>.json` (nested-ZIP entries from the server are flattened to `<inner>_<outer>.json`; same-name collisions get an iso-day suffix). The server names the per-day payloads `.txt`; the CLI writes them with a `.json` extension since each is a JSON array of events with LTS-schema keys (`Identifier`, `DateCreatedUtc`, `Action`, …). Entry names are validated as safe basenames and confirmed to resolve inside the folder before any write (no path traversal / Zip-Slip).
|
|
204
|
+
- **CSV:** the same per-day JSON arrays are parsed and merged into **one** RFC 4180 CSV (CRLF line endings, header row first). Columns follow the long-term-store field order — `OrganizationId, TenantId, ActorId, ActorEmail, ActorDetails, EventDetails, Status, Identifier, DateCreatedUtc, User, Action, Source, Category, ClientInformation` — with any extra server fields appended (union across events) so no data is dropped. `Status` is the numeric enum (`0`=Success, `1`=Failure); nested objects (e.g. `ClientInformation`) are JSON-stringified into the cell. String cells beginning with `= + - @` (or TAB/CR) are prefixed with a single quote to neutralize spreadsheet formula injection.
|
|
205
205
|
- On any single-day HTTP failure (or, for CSV, a day whose payload is not valid JSON), **nothing is written** — for `json` the output folder isn't even created — and the error message identifies which day failed. Earlier successful chunks are not preserved (atomic export).
|
|
206
206
|
- `Days` reports the total number of UTC days requested; `NonEmptyDays` reports how many actually had data. A long export with `NonEmptyDays: 0` means the window was entirely idle, not that the export failed. For `json`, `Files` counts the day-wise files written; for `csv`, `Events: 0` yields a header-only file.
|
|
207
207
|
|
|
@@ -226,17 +226,17 @@ audit-exports/
|
|
|
226
226
|
└── 2026-01-31.json
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
-
Each `.json` file is a JSON array of audit events with **
|
|
229
|
+
Each `.json` file is a JSON array of audit events with **LTS-schema** keys (`Identifier`, `DateCreatedUtc`, `OrganizationId`, `ActorId`, `User`, `Action`, …) — different from the camelCase shape returned by the live `events` endpoint. Note this in the user's hand-off if they're going to feed the dump into other tooling.
|
|
230
230
|
|
|
231
231
|
**CSV** — find the generated file, then inspect the header and row count:
|
|
232
232
|
|
|
233
233
|
```bash
|
|
234
234
|
csv=$(ls ./audit-exports/audit_*.csv | head -1) # the generated audit_<from>_<to>_<generatedAt>.csv
|
|
235
|
-
head -1 "$csv" # shared header (
|
|
235
|
+
head -1 "$csv" # shared header (LTS-schema columns)
|
|
236
236
|
python3 -c "import csv,sys; print(sum(1 for _ in csv.reader(open(sys.argv[1]))) - 1, 'rows')" "$csv"
|
|
237
237
|
```
|
|
238
238
|
|
|
239
|
-
One header row, then every event across all days as a data row (same
|
|
239
|
+
One header row, then every event across all days as a data row (same LTS-schema column names as the JSON files' keys). The row count should match `Events` in the result envelope.
|
|
240
240
|
|
|
241
241
|
Edge cases the CLI handles automatically — surface in your hand-off only if they appear:
|
|
242
242
|
|
|
@@ -302,7 +302,7 @@ Two or more signals? Run them in sequence and stitch the results in the final re
|
|
|
302
302
|
- **`tenant` events without an active tenant fail loudly.** If `uip login` has no tenant selected, every tenant-scoped command throws. Either re-`uip login` and pick a tenant, or pass `--tenant-id <guid>` on every call.
|
|
303
303
|
- **`events` cursor pagination is chronologically reversed from intuition.** `next` = newer (often null), `previous` = older (the typical "load more"). The CLI tool follows `previous` automatically when you bump `--limit > 200` — don't re-implement this in the agent.
|
|
304
304
|
- **Date-only ISO strings are interpreted as UTC midnight.** `--from-date 2026-01-01` means `2026-01-01T00:00:00Z`. To capture the full final day in `--to-date`, use `2026-02-01` (exclusive next day) or `2026-01-31T23:59:59.999Z`.
|
|
305
|
-
- **Export format depends on `--file-format`.** The default `json` writes one **JSON** file per UTC day (named `<YYYY-MM-DD>.json`) into a generated subfolder under `--output-path`, with **
|
|
305
|
+
- **Export format depends on `--file-format`.** The default `json` writes one **JSON** file per UTC day (named `<YYYY-MM-DD>.json`) into a generated subfolder under `--output-path`, with **LTS-schema** keys; `--file-format csv` produces a single merged **CSV** whose header uses those same LTS-schema field names. Both differ from the camelCase live `events` endpoint — don't paste an export into a parser expecting the live shape. In the CSV, `Status` is numeric (`0`/`1`) and `ClientInformation` is a JSON-stringified cell.
|
|
306
306
|
- **Org sources and tenant sources are different sets.** Don't reuse a GUID from `org sources` in a `tenant events` query — the filter will silently match nothing.
|
|
307
307
|
|
|
308
308
|
## Output Etiquette — after an audit query or export
|
|
@@ -11,7 +11,7 @@ Pick this when:
|
|
|
11
11
|
|
|
12
12
|
Confirm BatchTransform is the right mode first — see [../../../context-grounding-patterns.md](../../../context-grounding-patterns.md).
|
|
13
13
|
|
|
14
|
-
For Studio Web Agent Builder → [
|
|
14
|
+
For Studio Web Agent Builder → [../../../lowcode/capabilities/built-in-tools/batch-transform/planning.md](../../../lowcode/capabilities/built-in-tools/batch-transform/planning.md).
|
|
15
15
|
|
|
16
16
|
## Inputs You Need Before Building
|
|
17
17
|
|
|
@@ -11,7 +11,7 @@ Pick this when:
|
|
|
11
11
|
|
|
12
12
|
Confirm DeepRAG is the right mode first — see [../../../context-grounding-patterns.md](../../../context-grounding-patterns.md).
|
|
13
13
|
|
|
14
|
-
For Studio Web Agent Builder → [
|
|
14
|
+
For Studio Web Agent Builder → [../../../lowcode/capabilities/built-in-tools/deeprag/planning.md](../../../lowcode/capabilities/built-in-tools/deeprag/planning.md).
|
|
15
15
|
|
|
16
16
|
## Inputs You Need Before Building
|
|
17
17
|
|
package/skills/uipath-agents/references/coded/capabilities/guardrails/guardrails-recommend.md
CHANGED
|
@@ -191,6 +191,9 @@ Map catalog parameter shapes to Python:
|
|
|
191
191
|
| `enum-list` (e.g. `entities`) | List of enum members (e.g. `[PIIDetectionEntityType.EMAIL, PIIDetectionEntityType.PHONE_NUMBER]`) — names taken from SDK docs |
|
|
192
192
|
| `map-enum` (e.g. `entityThresholds`) | Dict from enum member → number (e.g. `{PIIDetectionEntityType.EMAIL: 0.5}`) — keys must exactly match the `enum-list` parameter's values |
|
|
193
193
|
| `number` (e.g. `threshold`) | Plain `float` / `int` constructor argument |
|
|
194
|
+
| `text` (e.g. `guardrailText`) | Plain `str` constructor argument |
|
|
195
|
+
| `enum` (e.g. `model`) | `str` value from the allowed options list. When the catalog shows an empty options list (as with `llm_as_judge`'s `model`), ask the user which model ID to use — the available values depend on the LLM Gateway configuration in their tenant. |
|
|
196
|
+
| `text-list` (e.g. `positiveExamples`, `negativeExamples`) | `List[str]` constructor argument |
|
|
194
197
|
|
|
195
198
|
Use `BlockAction(...)`, `LogAction(severity_level=...)`, or `EscalateAction(app_name=..., app_folder_path=..., recipient=...)` for human-in-the-loop review — or any other action the SDK docs expose. Never invent action class names. For `EscalateAction`, the fetched SDK docs must expose the class/parameters, and the Action App must be deployed and declared in `bindings.json` using [../../lifecycle/bindings-reference.md](../../lifecycle/bindings-reference.md) (see [guardrails.md § Escalation action (HITL)](guardrails.md#escalation-action-human-in-the-loop)).
|
|
196
199
|
|
|
@@ -204,7 +207,7 @@ Write the recommended guardrails into the Python file using the patterns from [g
|
|
|
204
207
|
```bash
|
|
205
208
|
python3 -c "import ast; ast.parse(open('graph.py').read())"
|
|
206
209
|
```
|
|
207
|
-
2. **Runtime wiring (mandatory)** — the guardrails are actually attached. A guardrail whose symbols were imported from the wrong module parses fine but **silently never fires**. Run the adapter-registration and `_GuardedLLM` / `_GuardedTool` wrap checks from [guardrails.md § Verify Guardrails Are Actually Wired](guardrails.md#verify-guardrails-are-actually-wired-mandatory-after-writing). Do not report the guardrails as added until these pass.
|
|
210
|
+
2. **Runtime wiring (mandatory)** — the guardrails are actually attached. A guardrail whose symbols were imported from the wrong module parses fine but **silently never fires**. Run the adapter-registration and `_GuardedLLM` / `_GuardedTool` wrap checks from [guardrails.md § Verify Guardrails Are Actually Wired](guardrails.md#verify-guardrails-are-actually-wired-mandatory-after-writing-for-langchain-ml-guardrails). Do not report the guardrails as added until these pass.
|
|
208
211
|
|
|
209
212
|
(Replace `graph.py` with the actual entrypoint file from Step 1.)
|
|
210
213
|
|
|
@@ -279,7 +282,7 @@ python3 -c "import ast; ast.parse(open('graph.py').read())"
|
|
|
279
282
|
5. **Never recommend two validators with the same `security_category` at the same scope and stage** (e.g. `prompt_injection` + `user_prompt_attacks` at LLM PRE). De-duplicate per Step 3: drop catalog-deprecated entries, keep the best fit, mention the alternative. Derive the grouping and deprecation from the catalog's own fields — do not hardcode validator names.
|
|
280
283
|
6. **Default the action to the catalog example's `action_type`; never silently downgrade Block → Log.** Security-critical guardrails (`adversarial_input`, `content_safety`) default to `Block`. If you use `LogAction` for a guardrail whose catalog default is `Block`, state it and the reason in the report (Step 6).
|
|
281
284
|
7. **Block as early as possible — pick the outermost scope the validator allows.** For input protection (PII, jailbreak, injection) prefer `GuardrailScope.AGENT` · PRE over Llm over Tool, so the run halts before the LLM call. PII meant to stop the agent handling personal data goes at **Agent**, not Llm. Only narrow when the validator is scope-restricted (e.g. `prompt_injection` / `user_prompt_attacks` are Llm-only) or the user asks for a narrower scope. See Step 5.
|
|
282
|
-
8. **For LangChain / LangGraph agents, import guardrail symbols from `uipath_langchain.guardrails`, not `uipath.platform.guardrails`.** Only `uipath_langchain.guardrails` registers the LangChain adapter as an import side effect; the platform module exposes identical names but registers nothing, so guardrails silently no-op. For any other framework (LlamaIndex, OpenAI Agents, plain Python), no UiPath framework adapter is published yet — use `uipath.platform.guardrails` (the framework-agnostic SDK) directly. After writing for LangChain, verify runtime wiring (adapter registered + `_GuardedLLM`/`_GuardedTool` wrap), not just `ast.parse`. See [guardrails.md § Imports Pattern](guardrails.md#imports-pattern) and [§ Verify Guardrails Are Actually Wired](guardrails.md#verify-guardrails-are-actually-wired-mandatory-after-writing).
|
|
285
|
+
8. **For LangChain / LangGraph agents, import guardrail symbols from `uipath_langchain.guardrails`, not `uipath.platform.guardrails`.** Only `uipath_langchain.guardrails` registers the LangChain adapter as an import side effect; the platform module exposes identical names but registers nothing, so guardrails silently no-op. For any other framework (LlamaIndex, OpenAI Agents, plain Python), no UiPath framework adapter is published yet — use `uipath.platform.guardrails` (the framework-agnostic SDK) directly. After writing for LangChain, verify runtime wiring (adapter registered + `_GuardedLLM`/`_GuardedTool` wrap), not just `ast.parse`. See [guardrails.md § Imports Pattern](guardrails.md#imports-pattern) and [§ Verify Guardrails Are Actually Wired](guardrails.md#verify-guardrails-are-actually-wired-mandatory-after-writing-for-langchain-ml-guardrails).
|
|
283
286
|
9. **For Tool scope**: verify the tool exists as a `@tool` function in the agent code before adding the guardrail. If the agent has no tools, do not add a Tool-scoped guardrail.
|
|
284
287
|
10. **For LLM-scope decorator**: the LLM must be inside a named factory function. If it is assigned directly (`llm = UiPathChat(...)`), refactor into a factory first — never decorate a module-level assignment.
|
|
285
288
|
11. **For Agent-scope decorator**: `create_agent(...)` must be inside a named factory function. If it is called at module level, refactor into a factory first.
|