claude-flow-novice 2.15.1 → 2.15.3
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/cfn-extras/agents/google-sheets-specialist.md +614 -0
- package/.claude/commands/cfn/create-handoff.md +224 -0
- package/.claude/hooks/cfn-BACKUP_USAGE.md +243 -243
- package/.claude/hooks/cfn-invoke-security-validation.sh +69 -69
- package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +78 -78
- package/.claude/hooks/cfn-post-edit.config.json +44 -44
- package/.claude/skills/agent-lifecycle/SKILL.md +60 -0
- package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +573 -0
- package/.claude/skills/agent-lifecycle/simple-audit.sh +31 -0
- package/.claude/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
- package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
- package/.claude/skills/cfn-redis-coordination/get-context.sh +112 -112
- package/.claude/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
- package/.claude/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
- package/.claude/skills/cfn-transparency-middleware/test-integration.sh +161 -161
- package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
- package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +92 -92
- package/.claude/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +662 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +29 -0
- package/claude-assets/cfn-extras/agents/google-sheets-specialist.md +614 -0
- package/claude-assets/commands/cfn/create-handoff.md +224 -0
- package/claude-assets/hooks/cfn-BACKUP_USAGE.md +243 -243
- package/claude-assets/hooks/cfn-invoke-security-validation.sh +69 -69
- package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +78 -78
- package/claude-assets/hooks/cfn-post-edit.config.json +44 -44
- package/claude-assets/hooks/cfn-post-execution/memory-cleanup.sh +19 -19
- package/claude-assets/hooks/cfn-pre-execution/memory-check.sh +19 -19
- package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +572 -572
- package/claude-assets/skills/agent-lifecycle/simple-audit.sh +30 -30
- package/claude-assets/skills/cfn-automatic-memory-persistence/persist-agent-output.sh +48 -48
- package/claude-assets/skills/cfn-automatic-memory-persistence/query-agent-history.sh +34 -34
- package/claude-assets/skills/cfn-deliverable-validation/confidence-calculator.sh +261 -261
- package/claude-assets/skills/cfn-expert-update/update-expert.sh +345 -345
- package/claude-assets/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
- package/claude-assets/skills/cfn-intervention-detector/detect-intervention.sh +110 -110
- package/claude-assets/skills/cfn-intervention-orchestrator/execute-intervention.sh +58 -58
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
- package/claude-assets/skills/cfn-loop2-output-processing/process-validator-output.sh +275 -275
- package/claude-assets/skills/cfn-memory-management/check-memory.sh +159 -159
- package/claude-assets/skills/cfn-memory-management/cleanup-memory.sh +196 -196
- package/claude-assets/skills/cfn-node-heap-sizer/task-mode-heap-limiter.sh +325 -325
- package/claude-assets/skills/cfn-playbook-auto-update/auto-update-playbook.sh +85 -85
- package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
- package/claude-assets/skills/cfn-redis-coordination/get-context.sh +112 -112
- package/claude-assets/skills/cfn-scope-simplifier/simplify-scope.sh +67 -67
- package/claude-assets/skills/cfn-specialist-injection/recommend-specialist.sh +56 -56
- package/claude-assets/skills/cfn-standardized-error-handling/capture-agent-error.sh +86 -86
- package/claude-assets/skills/cfn-standardized-error-handling/test-error-handling.sh +165 -165
- package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +264 -264
- package/claude-assets/skills/cfn-task-decomposition/task-decomposer.sh +278 -278
- package/claude-assets/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
- package/claude-assets/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
- package/claude-assets/skills/cfn-transparency-middleware/test-integration.sh +161 -161
- package/claude-assets/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
- package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +92 -92
- package/claude-assets/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
- package/claude-assets/skills/docker-build/SKILL.md +96 -203
- package/claude-assets/skills/docker-build/build.sh +73 -73
- package/claude-assets/skills/integration/agent-handoff.sh +494 -0
- package/claude-assets/skills/integration/file-operations.sh +414 -0
- package/claude-assets/skills/workflow-codification/APPROVAL_WORKFLOW.md +806 -0
- package/claude-assets/skills/workflow-codification/COST_TRACKING.md +637 -0
- package/claude-assets/skills/workflow-codification/EDGE_CASE_TRACKING.md +404 -0
- package/claude-assets/skills/workflow-codification/README_PHASE4.md +457 -0
- package/claude-assets/skills/workflow-codification/SKILL.md +110 -0
- package/claude-assets/skills/workflow-codification/analyze-patterns.sh +899 -0
- package/claude-assets/skills/workflow-codification/approval-workflow.sh +514 -0
- package/claude-assets/skills/workflow-codification/generate-skill-update.sh +525 -0
- package/claude-assets/skills/workflow-codification/review-skill.sh +643 -0
- package/claude-assets/skills/workflow-codification/templates/email-notification.txt +114 -0
- package/claude-assets/skills/workflow-codification/templates/slack-notification.md +85 -0
- package/claude-assets/skills/workflow-codification/test-integration.sh +281 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh +445 -0
- package/claude-assets/skills/workflow-codification/track-edge-case.sh +323 -0
- package/dist/agents/agent-loader.js +165 -146
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/integration/DatabaseHandoff.js +507 -0
- package/dist/integration/DatabaseHandoff.js.map +1 -0
- package/dist/integration/StandardAdapter.js +291 -0
- package/dist/integration/StandardAdapter.js.map +1 -0
- package/dist/lib/agent-output-parser.js +518 -0
- package/dist/lib/agent-output-parser.js.map +1 -0
- package/dist/lib/agent-output-validator.js +950 -0
- package/dist/lib/agent-output-validator.js.map +1 -0
- package/dist/lib/artifact-registry.js +443 -0
- package/dist/lib/artifact-registry.js.map +1 -0
- package/dist/lib/config-validator.js +687 -0
- package/dist/lib/config-validator.js.map +1 -0
- package/dist/types/agent-output.js +44 -0
- package/dist/types/agent-output.js.map +1 -0
- package/dist/types/config.js +28 -0
- package/dist/types/config.js.map +1 -0
- package/package.json +2 -1
- package/scripts/artifact-cleanup.sh +392 -0
- package/scripts/build-linux.sh +78 -0
- package/scripts/deploy-production.sh +355 -355
- package/scripts/docker-playwright-fix.sh +311 -311
- package/scripts/docker-rebuild-all-agents.sh +127 -127
- package/scripts/memory-leak-prevention.sh +305 -305
- package/scripts/migrate-artifacts.sh +563 -0
- package/scripts/migrate-yaml-to-json.sh +465 -0
- package/scripts/run-marketing-tests.sh +42 -42
- package/scripts/update_paths.sh +46 -46
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# review-skill.sh - Expert Review CLI for Workflow Codification Approval
|
|
4
|
+
#
|
|
5
|
+
# Actions: approve, reject, correct
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# ./review-skill.sh --skill-id UUID --action approve|reject|correct [--feedback TEXT]
|
|
9
|
+
# ./review-skill.sh --list-pending [--team TEAM_NAME]
|
|
10
|
+
# ./review-skill.sh --check-sla
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
# Configuration
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
|
18
|
+
|
|
19
|
+
# Load environment
|
|
20
|
+
if [ -f "${PROJECT_ROOT}/.env" ]; then
|
|
21
|
+
# shellcheck source=/dev/null
|
|
22
|
+
source "${PROJECT_ROOT}/.env"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
DB_HOST="${CFN_DB_HOST:-localhost}"
|
|
26
|
+
DB_PORT="${CFN_DB_PORT:-5432}"
|
|
27
|
+
DB_NAME="${CFN_DB_NAME:-cfn_workflow}"
|
|
28
|
+
DB_USER="${CFN_DB_USER:-postgres}"
|
|
29
|
+
DB_PASSWORD="${CFN_DB_PASSWORD:-}"
|
|
30
|
+
|
|
31
|
+
# Expert information (from env or defaults)
|
|
32
|
+
EXPERT_ID="${CFN_EXPERT_ID:-$(whoami)}"
|
|
33
|
+
EXPERT_EMAIL="${CFN_EXPERT_EMAIL:-}"
|
|
34
|
+
|
|
35
|
+
# SLA thresholds (in hours)
|
|
36
|
+
SLA_HIGH_PRIORITY=48
|
|
37
|
+
SLA_MEDIUM_LOW_PRIORITY=168 # 7 days
|
|
38
|
+
|
|
39
|
+
# Color codes
|
|
40
|
+
RED='\033[0;31m'
|
|
41
|
+
GREEN='\033[0;32m'
|
|
42
|
+
YELLOW='\033[1;33m'
|
|
43
|
+
BLUE='\033[0;34m'
|
|
44
|
+
CYAN='\033[0;36m'
|
|
45
|
+
NC='\033[0m'
|
|
46
|
+
|
|
47
|
+
#######################################
|
|
48
|
+
# Utility functions
|
|
49
|
+
#######################################
|
|
50
|
+
error_exit() {
|
|
51
|
+
echo -e "${RED}ERROR: $1${NC}" >&2
|
|
52
|
+
exit 1
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
success_msg() {
|
|
56
|
+
echo -e "${GREEN}✓ $1${NC}"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
warn_msg() {
|
|
60
|
+
echo -e "${YELLOW}⚠ $1${NC}"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
info_msg() {
|
|
64
|
+
echo -e "${BLUE}ℹ $1${NC}"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#######################################
|
|
68
|
+
# Execute PostgreSQL query
|
|
69
|
+
#######################################
|
|
70
|
+
execute_query() {
|
|
71
|
+
local query="$1"
|
|
72
|
+
|
|
73
|
+
PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -t -A -c "$query" 2>&1
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
execute_query_formatted() {
|
|
77
|
+
local query="$1"
|
|
78
|
+
|
|
79
|
+
PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -c "$query" 2>&1
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#######################################
|
|
83
|
+
# Get skill details by skill_id
|
|
84
|
+
# Arguments:
|
|
85
|
+
# $1 - Skill ID (UUID)
|
|
86
|
+
#######################################
|
|
87
|
+
get_skill_details() {
|
|
88
|
+
local skill_id="$1"
|
|
89
|
+
|
|
90
|
+
local query="
|
|
91
|
+
SELECT
|
|
92
|
+
wp.id,
|
|
93
|
+
wp.pattern_name,
|
|
94
|
+
wp.status,
|
|
95
|
+
wp.priority,
|
|
96
|
+
wp.occurrence_count,
|
|
97
|
+
wp.teams_affected,
|
|
98
|
+
wp.estimated_savings_usd,
|
|
99
|
+
wp.created_at,
|
|
100
|
+
EXTRACT(EPOCH FROM (NOW() - wp.created_at))/3600 as hours_pending
|
|
101
|
+
FROM workflow_patterns wp
|
|
102
|
+
WHERE wp.id = '${skill_id}'
|
|
103
|
+
LIMIT 1;
|
|
104
|
+
"
|
|
105
|
+
|
|
106
|
+
execute_query "$query"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#######################################
|
|
110
|
+
# Approve skill
|
|
111
|
+
# Arguments:
|
|
112
|
+
# $1 - Skill ID
|
|
113
|
+
# $2 - Feedback (optional)
|
|
114
|
+
#######################################
|
|
115
|
+
approve_skill() {
|
|
116
|
+
local skill_id="$1"
|
|
117
|
+
local feedback="${2:-Approved for deployment}"
|
|
118
|
+
local timestamp
|
|
119
|
+
timestamp=$(date -u +"%Y-%m-%d %H:%M:%S")
|
|
120
|
+
|
|
121
|
+
info_msg "Approving skill ${skill_id}..."
|
|
122
|
+
|
|
123
|
+
# Get current status
|
|
124
|
+
local current_status
|
|
125
|
+
current_status=$(execute_query "SELECT status FROM workflow_patterns WHERE id = '${skill_id}';")
|
|
126
|
+
|
|
127
|
+
if [ -z "$current_status" ]; then
|
|
128
|
+
error_exit "Skill ID not found: ${skill_id}"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
if [ "$current_status" != "PENDING_REVIEW" ] && [ "$current_status" != "NEEDS_CORRECTION" ]; then
|
|
132
|
+
error_exit "Cannot approve skill in state: ${current_status}. Must be PENDING_REVIEW or NEEDS_CORRECTION."
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Log approval in skill_approvals table
|
|
136
|
+
local approval_query="
|
|
137
|
+
BEGIN;
|
|
138
|
+
|
|
139
|
+
-- Insert approval record
|
|
140
|
+
INSERT INTO skill_approvals (
|
|
141
|
+
skill_id,
|
|
142
|
+
expert_id,
|
|
143
|
+
action,
|
|
144
|
+
feedback,
|
|
145
|
+
timestamp
|
|
146
|
+
) VALUES (
|
|
147
|
+
'${skill_id}',
|
|
148
|
+
'${EXPERT_ID}',
|
|
149
|
+
'approve',
|
|
150
|
+
'${feedback}',
|
|
151
|
+
'${timestamp}'
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
-- Transition state to APPROVED (using approval-workflow.sh would be better, but inline for atomicity)
|
|
155
|
+
UPDATE workflow_patterns
|
|
156
|
+
SET status = 'APPROVED', updated_at = '${timestamp}'
|
|
157
|
+
WHERE id = '${skill_id}';
|
|
158
|
+
|
|
159
|
+
-- Log state transition
|
|
160
|
+
INSERT INTO pattern_state_history (pattern_id, from_state, to_state, metadata, timestamp)
|
|
161
|
+
VALUES (
|
|
162
|
+
'${skill_id}',
|
|
163
|
+
'${current_status}',
|
|
164
|
+
'APPROVED',
|
|
165
|
+
'{\"approved_by\": \"${EXPERT_ID}\", \"feedback\": \"${feedback}\"}'::jsonb,
|
|
166
|
+
'${timestamp}'
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
-- Log audit event
|
|
170
|
+
INSERT INTO workflow_audit_log (pattern_id, event_type, description, metadata, timestamp)
|
|
171
|
+
VALUES (
|
|
172
|
+
'${skill_id}',
|
|
173
|
+
'SKILL_APPROVED',
|
|
174
|
+
'Expert approved skill for deployment',
|
|
175
|
+
'{\"expert_id\": \"${EXPERT_ID}\", \"feedback\": \"${feedback}\"}'::jsonb,
|
|
176
|
+
'${timestamp}'
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
COMMIT;
|
|
180
|
+
"
|
|
181
|
+
|
|
182
|
+
if execute_query "$approval_query" > /dev/null 2>&1; then
|
|
183
|
+
success_msg "Skill approved successfully!"
|
|
184
|
+
info_msg "Skill is now ready for deployment to production."
|
|
185
|
+
|
|
186
|
+
# Trigger deployment notification (optional)
|
|
187
|
+
send_approval_notification "$skill_id" "approved"
|
|
188
|
+
else
|
|
189
|
+
error_exit "Failed to approve skill. Transaction rolled back."
|
|
190
|
+
fi
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
#######################################
|
|
194
|
+
# Reject skill
|
|
195
|
+
# Arguments:
|
|
196
|
+
# $1 - Skill ID
|
|
197
|
+
# $2 - Feedback (required)
|
|
198
|
+
#######################################
|
|
199
|
+
reject_skill() {
|
|
200
|
+
local skill_id="$1"
|
|
201
|
+
local feedback="${2:-}"
|
|
202
|
+
local timestamp
|
|
203
|
+
timestamp=$(date -u +"%Y-%m-%d %H:%M:%S")
|
|
204
|
+
|
|
205
|
+
if [ -z "$feedback" ]; then
|
|
206
|
+
error_exit "Feedback is required when rejecting a skill. Use --feedback 'reason for rejection'"
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
warn_msg "Rejecting skill ${skill_id}..."
|
|
210
|
+
|
|
211
|
+
# Get current status
|
|
212
|
+
local current_status
|
|
213
|
+
current_status=$(execute_query "SELECT status FROM workflow_patterns WHERE id = '${skill_id}';")
|
|
214
|
+
|
|
215
|
+
if [ -z "$current_status" ]; then
|
|
216
|
+
error_exit "Skill ID not found: ${skill_id}"
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
if [ "$current_status" != "PENDING_REVIEW" ] && [ "$current_status" != "NEEDS_CORRECTION" ]; then
|
|
220
|
+
error_exit "Cannot reject skill in state: ${current_status}. Must be PENDING_REVIEW or NEEDS_CORRECTION."
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
# Log rejection
|
|
224
|
+
local rejection_query="
|
|
225
|
+
BEGIN;
|
|
226
|
+
|
|
227
|
+
-- Insert rejection record
|
|
228
|
+
INSERT INTO skill_approvals (
|
|
229
|
+
skill_id,
|
|
230
|
+
expert_id,
|
|
231
|
+
action,
|
|
232
|
+
feedback,
|
|
233
|
+
timestamp
|
|
234
|
+
) VALUES (
|
|
235
|
+
'${skill_id}',
|
|
236
|
+
'${EXPERT_ID}',
|
|
237
|
+
'reject',
|
|
238
|
+
'${feedback}',
|
|
239
|
+
'${timestamp}'
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
-- Transition state to REJECTED
|
|
243
|
+
UPDATE workflow_patterns
|
|
244
|
+
SET status = 'REJECTED', updated_at = '${timestamp}'
|
|
245
|
+
WHERE id = '${skill_id}';
|
|
246
|
+
|
|
247
|
+
-- Log state transition
|
|
248
|
+
INSERT INTO pattern_state_history (pattern_id, from_state, to_state, metadata, timestamp)
|
|
249
|
+
VALUES (
|
|
250
|
+
'${skill_id}',
|
|
251
|
+
'${current_status}',
|
|
252
|
+
'REJECTED',
|
|
253
|
+
'{\"rejected_by\": \"${EXPERT_ID}\", \"feedback\": \"${feedback}\"}'::jsonb,
|
|
254
|
+
'${timestamp}'
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
-- Log audit event
|
|
258
|
+
INSERT INTO workflow_audit_log (pattern_id, event_type, description, metadata, timestamp)
|
|
259
|
+
VALUES (
|
|
260
|
+
'${skill_id}',
|
|
261
|
+
'SKILL_REJECTED',
|
|
262
|
+
'Expert rejected skill',
|
|
263
|
+
'{\"expert_id\": \"${EXPERT_ID}\", \"reason\": \"${feedback}\"}'::jsonb,
|
|
264
|
+
'${timestamp}'
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
COMMIT;
|
|
268
|
+
"
|
|
269
|
+
|
|
270
|
+
if execute_query "$rejection_query" > /dev/null 2>&1; then
|
|
271
|
+
success_msg "Skill rejected successfully."
|
|
272
|
+
info_msg "Reason: ${feedback}"
|
|
273
|
+
|
|
274
|
+
# Send rejection notification
|
|
275
|
+
send_approval_notification "$skill_id" "rejected"
|
|
276
|
+
else
|
|
277
|
+
error_exit "Failed to reject skill. Transaction rolled back."
|
|
278
|
+
fi
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
#######################################
|
|
282
|
+
# Request correction for skill
|
|
283
|
+
# Arguments:
|
|
284
|
+
# $1 - Skill ID
|
|
285
|
+
# $2 - Feedback (required)
|
|
286
|
+
#######################################
|
|
287
|
+
request_correction() {
|
|
288
|
+
local skill_id="$1"
|
|
289
|
+
local feedback="${2:-}"
|
|
290
|
+
local timestamp
|
|
291
|
+
timestamp=$(date -u +"%Y-%m-%d %H:%M:%S")
|
|
292
|
+
|
|
293
|
+
if [ -z "$feedback" ]; then
|
|
294
|
+
error_exit "Feedback is required when requesting corrections. Use --feedback 'what needs to be corrected'"
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
info_msg "Requesting corrections for skill ${skill_id}..."
|
|
298
|
+
|
|
299
|
+
# Get current status
|
|
300
|
+
local current_status
|
|
301
|
+
current_status=$(execute_query "SELECT status FROM workflow_patterns WHERE id = '${skill_id}';")
|
|
302
|
+
|
|
303
|
+
if [ -z "$current_status" ]; then
|
|
304
|
+
error_exit "Skill ID not found: ${skill_id}"
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
if [ "$current_status" != "PENDING_REVIEW" ]; then
|
|
308
|
+
error_exit "Cannot request corrections for skill in state: ${current_status}. Must be PENDING_REVIEW."
|
|
309
|
+
fi
|
|
310
|
+
|
|
311
|
+
# Log correction request
|
|
312
|
+
local correction_query="
|
|
313
|
+
BEGIN;
|
|
314
|
+
|
|
315
|
+
-- Insert correction request record
|
|
316
|
+
INSERT INTO skill_approvals (
|
|
317
|
+
skill_id,
|
|
318
|
+
expert_id,
|
|
319
|
+
action,
|
|
320
|
+
feedback,
|
|
321
|
+
timestamp
|
|
322
|
+
) VALUES (
|
|
323
|
+
'${skill_id}',
|
|
324
|
+
'${EXPERT_ID}',
|
|
325
|
+
'correct',
|
|
326
|
+
'${feedback}',
|
|
327
|
+
'${timestamp}'
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
-- Transition state to NEEDS_CORRECTION
|
|
331
|
+
UPDATE workflow_patterns
|
|
332
|
+
SET status = 'NEEDS_CORRECTION', updated_at = '${timestamp}'
|
|
333
|
+
WHERE id = '${skill_id}';
|
|
334
|
+
|
|
335
|
+
-- Log state transition
|
|
336
|
+
INSERT INTO pattern_state_history (pattern_id, from_state, to_state, metadata, timestamp)
|
|
337
|
+
VALUES (
|
|
338
|
+
'${skill_id}',
|
|
339
|
+
'${current_status}',
|
|
340
|
+
'NEEDS_CORRECTION',
|
|
341
|
+
'{\"requested_by\": \"${EXPERT_ID}\", \"feedback\": \"${feedback}\"}'::jsonb,
|
|
342
|
+
'${timestamp}'
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
-- Log audit event
|
|
346
|
+
INSERT INTO workflow_audit_log (pattern_id, event_type, description, metadata, timestamp)
|
|
347
|
+
VALUES (
|
|
348
|
+
'${skill_id}',
|
|
349
|
+
'CORRECTION_REQUESTED',
|
|
350
|
+
'Expert requested corrections',
|
|
351
|
+
'{\"expert_id\": \"${EXPERT_ID}\", \"corrections\": \"${feedback}\"}'::jsonb,
|
|
352
|
+
'${timestamp}'
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
COMMIT;
|
|
356
|
+
"
|
|
357
|
+
|
|
358
|
+
if execute_query "$correction_query" > /dev/null 2>&1; then
|
|
359
|
+
success_msg "Correction request submitted successfully."
|
|
360
|
+
info_msg "Feedback: ${feedback}"
|
|
361
|
+
info_msg "Skill will be regenerated with your feedback."
|
|
362
|
+
|
|
363
|
+
# Send correction notification
|
|
364
|
+
send_approval_notification "$skill_id" "needs_correction"
|
|
365
|
+
else
|
|
366
|
+
error_exit "Failed to request corrections. Transaction rolled back."
|
|
367
|
+
fi
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
#######################################
|
|
371
|
+
# List pending skills for review
|
|
372
|
+
# Arguments:
|
|
373
|
+
# $1 - Team filter (optional)
|
|
374
|
+
#######################################
|
|
375
|
+
list_pending_skills() {
|
|
376
|
+
local team_filter="${1:-}"
|
|
377
|
+
|
|
378
|
+
info_msg "Fetching pending skills for review..."
|
|
379
|
+
|
|
380
|
+
local query="
|
|
381
|
+
SELECT
|
|
382
|
+
wp.id,
|
|
383
|
+
wp.pattern_name,
|
|
384
|
+
wp.status,
|
|
385
|
+
wp.priority,
|
|
386
|
+
wp.occurrence_count,
|
|
387
|
+
wp.estimated_savings_usd,
|
|
388
|
+
ROUND(EXTRACT(EPOCH FROM (NOW() - wp.created_at))/3600, 1) as hours_pending,
|
|
389
|
+
CASE
|
|
390
|
+
WHEN wp.priority = 'high' AND EXTRACT(EPOCH FROM (NOW() - wp.created_at))/3600 > ${SLA_HIGH_PRIORITY} THEN 'SLA_BREACH'
|
|
391
|
+
WHEN wp.priority IN ('medium', 'low') AND EXTRACT(EPOCH FROM (NOW() - wp.created_at))/3600 > ${SLA_MEDIUM_LOW_PRIORITY} THEN 'SLA_BREACH'
|
|
392
|
+
ELSE 'OK'
|
|
393
|
+
END as sla_status
|
|
394
|
+
FROM workflow_patterns wp
|
|
395
|
+
WHERE wp.status IN ('PENDING_REVIEW', 'NEEDS_CORRECTION')
|
|
396
|
+
"
|
|
397
|
+
|
|
398
|
+
if [ -n "$team_filter" ]; then
|
|
399
|
+
query+=" AND '${team_filter}' = ANY(wp.teams_affected)"
|
|
400
|
+
fi
|
|
401
|
+
|
|
402
|
+
query+=" ORDER BY
|
|
403
|
+
CASE wp.priority
|
|
404
|
+
WHEN 'high' THEN 1
|
|
405
|
+
WHEN 'medium' THEN 2
|
|
406
|
+
WHEN 'low' THEN 3
|
|
407
|
+
END,
|
|
408
|
+
wp.created_at ASC;"
|
|
409
|
+
|
|
410
|
+
echo -e "${CYAN}=== Pending Skills for Review ===${NC}"
|
|
411
|
+
execute_query_formatted "$query"
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
#######################################
|
|
415
|
+
# Check SLA status for pending reviews
|
|
416
|
+
#######################################
|
|
417
|
+
check_sla_status() {
|
|
418
|
+
info_msg "Checking SLA status for pending reviews..."
|
|
419
|
+
|
|
420
|
+
local query="
|
|
421
|
+
SELECT
|
|
422
|
+
COUNT(*) FILTER (WHERE
|
|
423
|
+
priority = 'high' AND
|
|
424
|
+
EXTRACT(EPOCH FROM (NOW() - created_at))/3600 > ${SLA_HIGH_PRIORITY}
|
|
425
|
+
) as high_priority_breaches,
|
|
426
|
+
COUNT(*) FILTER (WHERE
|
|
427
|
+
priority IN ('medium', 'low') AND
|
|
428
|
+
EXTRACT(EPOCH FROM (NOW() - created_at))/3600 > ${SLA_MEDIUM_LOW_PRIORITY}
|
|
429
|
+
) as medium_low_breaches,
|
|
430
|
+
COUNT(*) as total_pending
|
|
431
|
+
FROM workflow_patterns
|
|
432
|
+
WHERE status IN ('PENDING_REVIEW', 'NEEDS_CORRECTION');
|
|
433
|
+
"
|
|
434
|
+
|
|
435
|
+
echo -e "${CYAN}=== SLA Status ===${NC}"
|
|
436
|
+
local result
|
|
437
|
+
result=$(execute_query "$query")
|
|
438
|
+
|
|
439
|
+
# Parse result (format: high_breaches|medium_breaches|total)
|
|
440
|
+
IFS='|' read -r high_breaches medium_breaches total <<< "$result"
|
|
441
|
+
|
|
442
|
+
echo "High Priority Breaches (>48h): ${high_breaches}"
|
|
443
|
+
echo "Medium/Low Priority Breaches (>7d): ${medium_breaches}"
|
|
444
|
+
echo "Total Pending Reviews: ${total}"
|
|
445
|
+
|
|
446
|
+
if [ "$high_breaches" -gt 0 ] || [ "$medium_breaches" -gt 0 ]; then
|
|
447
|
+
warn_msg "SLA breaches detected! Please review pending skills urgently."
|
|
448
|
+
return 1
|
|
449
|
+
else
|
|
450
|
+
success_msg "All pending reviews within SLA."
|
|
451
|
+
return 0
|
|
452
|
+
fi
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
#######################################
|
|
456
|
+
# Send approval notification
|
|
457
|
+
# Arguments:
|
|
458
|
+
# $1 - Skill ID
|
|
459
|
+
# $2 - Action (approved|rejected|needs_correction)
|
|
460
|
+
#######################################
|
|
461
|
+
send_approval_notification() {
|
|
462
|
+
local skill_id="$1"
|
|
463
|
+
local action="$2"
|
|
464
|
+
|
|
465
|
+
# Get skill details
|
|
466
|
+
local skill_name
|
|
467
|
+
skill_name=$(execute_query "SELECT pattern_name FROM workflow_patterns WHERE id = '${skill_id}';")
|
|
468
|
+
|
|
469
|
+
# Placeholder for notification integration
|
|
470
|
+
# In production, integrate with email/Slack services
|
|
471
|
+
|
|
472
|
+
info_msg "Notification: Skill '${skill_name}' has been ${action}"
|
|
473
|
+
|
|
474
|
+
# TODO: Integrate with notification service
|
|
475
|
+
# - Send email using templates/email-notification.txt
|
|
476
|
+
# - Send Slack message using templates/slack-notification.md
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
#######################################
|
|
480
|
+
# Initialize skill_approvals table
|
|
481
|
+
#######################################
|
|
482
|
+
init_approvals_table() {
|
|
483
|
+
info_msg "Initializing skill_approvals table..."
|
|
484
|
+
|
|
485
|
+
local schema_query="
|
|
486
|
+
CREATE TABLE IF NOT EXISTS skill_approvals (
|
|
487
|
+
id SERIAL PRIMARY KEY,
|
|
488
|
+
skill_id UUID REFERENCES workflow_patterns(id) ON DELETE CASCADE,
|
|
489
|
+
expert_id VARCHAR(255) NOT NULL,
|
|
490
|
+
action VARCHAR(50) NOT NULL,
|
|
491
|
+
feedback TEXT,
|
|
492
|
+
timestamp TIMESTAMP DEFAULT NOW()
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
CREATE INDEX IF NOT EXISTS idx_skill_approvals_skill_id ON skill_approvals(skill_id);
|
|
496
|
+
CREATE INDEX IF NOT EXISTS idx_skill_approvals_expert_id ON skill_approvals(expert_id);
|
|
497
|
+
CREATE INDEX IF NOT EXISTS idx_skill_approvals_timestamp ON skill_approvals(timestamp);
|
|
498
|
+
"
|
|
499
|
+
|
|
500
|
+
if execute_query "$schema_query" > /dev/null 2>&1; then
|
|
501
|
+
success_msg "skill_approvals table initialized successfully"
|
|
502
|
+
else
|
|
503
|
+
error_exit "Failed to initialize skill_approvals table"
|
|
504
|
+
fi
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
#######################################
|
|
508
|
+
# Show usage information
|
|
509
|
+
#######################################
|
|
510
|
+
usage() {
|
|
511
|
+
cat << EOF
|
|
512
|
+
Usage: $0 [COMMAND] [OPTIONS]
|
|
513
|
+
|
|
514
|
+
Commands:
|
|
515
|
+
(default) Review a specific skill (requires --skill-id and --action)
|
|
516
|
+
--list-pending List all pending skills for review
|
|
517
|
+
--check-sla Check SLA status for pending reviews
|
|
518
|
+
--init Initialize skill_approvals table
|
|
519
|
+
|
|
520
|
+
Review Options:
|
|
521
|
+
--skill-id UUID Skill ID to review (required for review action)
|
|
522
|
+
--action ACTION Action to take: approve, reject, correct (required)
|
|
523
|
+
--feedback TEXT Feedback/reason for action (required for reject/correct)
|
|
524
|
+
|
|
525
|
+
List Options:
|
|
526
|
+
--team TEAM_NAME Filter pending skills by team (optional)
|
|
527
|
+
|
|
528
|
+
Examples:
|
|
529
|
+
# Approve a skill
|
|
530
|
+
$0 --skill-id "123e4567-e89b-12d3-a456-426614174000" --action approve
|
|
531
|
+
|
|
532
|
+
# Reject a skill with feedback
|
|
533
|
+
$0 --skill-id "123e4567-e89b-12d3-a456-426614174000" \\
|
|
534
|
+
--action reject --feedback "Script has security vulnerabilities"
|
|
535
|
+
|
|
536
|
+
# Request corrections
|
|
537
|
+
$0 --skill-id "123e4567-e89b-12d3-a456-426614174000" \\
|
|
538
|
+
--action correct --feedback "Add input validation for domain parameter"
|
|
539
|
+
|
|
540
|
+
# List all pending skills
|
|
541
|
+
$0 --list-pending
|
|
542
|
+
|
|
543
|
+
# List pending skills for frontend team
|
|
544
|
+
$0 --list-pending --team frontend
|
|
545
|
+
|
|
546
|
+
# Check SLA status
|
|
547
|
+
$0 --check-sla
|
|
548
|
+
|
|
549
|
+
EOF
|
|
550
|
+
exit 1
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
#######################################
|
|
554
|
+
# Main execution
|
|
555
|
+
#######################################
|
|
556
|
+
main() {
|
|
557
|
+
local skill_id=""
|
|
558
|
+
local action=""
|
|
559
|
+
local feedback=""
|
|
560
|
+
local team_filter=""
|
|
561
|
+
local list_pending=false
|
|
562
|
+
local check_sla=false
|
|
563
|
+
local init_table=false
|
|
564
|
+
|
|
565
|
+
# Parse arguments
|
|
566
|
+
while [ $# -gt 0 ]; do
|
|
567
|
+
case "$1" in
|
|
568
|
+
--skill-id)
|
|
569
|
+
skill_id="$2"
|
|
570
|
+
shift 2
|
|
571
|
+
;;
|
|
572
|
+
--action)
|
|
573
|
+
action="$2"
|
|
574
|
+
shift 2
|
|
575
|
+
;;
|
|
576
|
+
--feedback)
|
|
577
|
+
feedback="$2"
|
|
578
|
+
shift 2
|
|
579
|
+
;;
|
|
580
|
+
--team)
|
|
581
|
+
team_filter="$2"
|
|
582
|
+
shift 2
|
|
583
|
+
;;
|
|
584
|
+
--list-pending)
|
|
585
|
+
list_pending=true
|
|
586
|
+
shift
|
|
587
|
+
;;
|
|
588
|
+
--check-sla)
|
|
589
|
+
check_sla=true
|
|
590
|
+
shift
|
|
591
|
+
;;
|
|
592
|
+
--init)
|
|
593
|
+
init_table=true
|
|
594
|
+
shift
|
|
595
|
+
;;
|
|
596
|
+
--help|-h)
|
|
597
|
+
usage
|
|
598
|
+
;;
|
|
599
|
+
*)
|
|
600
|
+
error_exit "Unknown option: $1"
|
|
601
|
+
;;
|
|
602
|
+
esac
|
|
603
|
+
done
|
|
604
|
+
|
|
605
|
+
# Execute command
|
|
606
|
+
if [ "$init_table" = true ]; then
|
|
607
|
+
init_approvals_table
|
|
608
|
+
exit 0
|
|
609
|
+
fi
|
|
610
|
+
|
|
611
|
+
if [ "$list_pending" = true ]; then
|
|
612
|
+
list_pending_skills "$team_filter"
|
|
613
|
+
exit 0
|
|
614
|
+
fi
|
|
615
|
+
|
|
616
|
+
if [ "$check_sla" = true ]; then
|
|
617
|
+
check_sla_status
|
|
618
|
+
exit $?
|
|
619
|
+
fi
|
|
620
|
+
|
|
621
|
+
# Default: review action
|
|
622
|
+
if [ -z "$skill_id" ] || [ -z "$action" ]; then
|
|
623
|
+
usage
|
|
624
|
+
fi
|
|
625
|
+
|
|
626
|
+
# Validate action
|
|
627
|
+
case "$action" in
|
|
628
|
+
approve)
|
|
629
|
+
approve_skill "$skill_id" "$feedback"
|
|
630
|
+
;;
|
|
631
|
+
reject)
|
|
632
|
+
reject_skill "$skill_id" "$feedback"
|
|
633
|
+
;;
|
|
634
|
+
correct)
|
|
635
|
+
request_correction "$skill_id" "$feedback"
|
|
636
|
+
;;
|
|
637
|
+
*)
|
|
638
|
+
error_exit "Invalid action: $action. Must be approve, reject, or correct."
|
|
639
|
+
;;
|
|
640
|
+
esac
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
main "$@"
|