crewly 1.5.15 → 1.5.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/config/skills/agent/browse-stealth/stealth-browse.py +7 -2
  2. package/config/skills/agent/core/recall/SKILL.md +22 -9
  3. package/config/skills/agent/core/recall/execute.sh +94 -17
  4. package/config/skills/agent/core/record-learning/SKILL.md +22 -10
  5. package/config/skills/agent/core/record-learning/execute.sh +91 -22
  6. package/config/skills/agent/core/remember/SKILL.md +23 -10
  7. package/config/skills/agent/core/remember/execute.sh +129 -22
  8. package/config/skills/agent/core/report-status/SKILL.md +26 -14
  9. package/config/skills/agent/core/report-status/execute.sh +139 -25
  10. package/config/skills/agent/core/send-message/SKILL.md +20 -6
  11. package/config/skills/agent/core/send-message/execute.sh +90 -8
  12. package/config/skills/orchestrator/delegate-task/SKILL.md +33 -15
  13. package/config/skills/orchestrator/delegate-task/execute.sh +69 -15
  14. package/config/skills/team-leader/delegate-task/SKILL.md +30 -13
  15. package/config/skills/team-leader/delegate-task/execute.sh +69 -13
  16. package/dist/backend/backend/src/constants.d.ts +20 -3
  17. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  18. package/dist/backend/backend/src/constants.js +21 -4
  19. package/dist/backend/backend/src/constants.js.map +1 -1
  20. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts +7 -9
  21. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
  22. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +28 -17
  23. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  24. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  25. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +38 -19
  26. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  27. package/dist/backend/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  28. package/dist/backend/backend/src/services/session/session-command-helper.js +13 -0
  29. package/dist/backend/backend/src/services/session/session-command-helper.js.map +1 -1
  30. package/dist/cli/backend/src/constants.d.ts +20 -3
  31. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  32. package/dist/cli/backend/src/constants.js +21 -4
  33. package/dist/cli/backend/src/constants.js.map +1 -1
  34. package/frontend/dist/assets/{index-371b68d4.css → index-a2db8a73.css} +1 -1
  35. package/frontend/dist/assets/{index-506f70da.js → index-d516a3cd.js} +147 -147
  36. package/frontend/dist/index.html +2 -2
  37. package/package.json +1 -1
@@ -1,26 +1,149 @@
1
1
  #!/bin/bash
2
2
  # Report task status to the orchestrator
3
+ # Supports both CLI flags (preferred) and legacy JSON argument.
3
4
  set -euo pipefail
4
5
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
6
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
7
 
7
- INPUT=$(read_json_input "${1:-}")
8
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"sessionName\":\"dev-1\",\"status\":\"done\",\"summary\":\"...\"}' or echo '{...}' | execute.sh"
8
+ print_usage() {
9
+ cat <<'EOF_USAGE'
10
+ Usage:
11
+ # CLI flags (preferred — avoids shell escaping issues)
12
+ bash execute.sh --session dev-1 --status done --summary "Fixed the bug" --project /path/to/project
9
13
 
10
- SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
11
- STATUS=$(printf '%s' "$INPUT" | jq -r '.status // empty')
12
- SUMMARY=$(printf '%s' "$INPUT" | jq -r '.summary // empty')
13
- TASK_PATH=$(printf '%s' "$INPUT" | jq -r '.taskPath // empty')
14
- require_param "sessionName" "$SESSION_NAME"
15
- require_param "status" "$STATUS"
16
- require_param "summary" "$SUMMARY"
14
+ # Summary from stdin (for multi-line or special characters)
15
+ echo "Fixed the bug — it's working" | bash execute.sh --session dev-1 --status done --project /path
17
16
 
18
- # Optional structured StatusReport fields (for hierarchical workflows)
19
- TASK_ID=$(printf '%s' "$INPUT" | jq -r '.taskId // empty')
20
- PROGRESS=$(printf '%s' "$INPUT" | jq -r '.progress // empty')
21
- ARTIFACTS=$(printf '%s' "$INPUT" | jq -c '.artifacts // empty')
22
- BLOCKERS=$(printf '%s' "$INPUT" | jq -c '.blockers // empty')
23
- USE_STRUCTURED=$(printf '%s' "$INPUT" | jq -r '.structured // "false"')
17
+ # Summary from file
18
+ bash execute.sh --session dev-1 --status done --summary-file /tmp/summary.txt --project /path
19
+
20
+ # Legacy JSON argument (backward compatible)
21
+ bash execute.sh '{"sessionName":"dev-1","status":"done","summary":"Fixed the bug"}'
22
+
23
+ Options:
24
+ --session | -s Agent session name (required)
25
+ --status | -S Status: done, blocked, failed, in_progress, active (required)
26
+ --summary | -m Status summary text (required unless piped via stdin)
27
+ --summary-file Read summary from file path
28
+ --project | -p Project path for auto-remember on completion
29
+ --task-path Task file path to auto-complete
30
+ --task-id Task ID (for structured StatusReport format)
31
+ --progress Progress percentage (0-100, for structured format)
32
+ --structured Use structured StatusReport format (true/false)
33
+ --json | -j Raw JSON payload (same as legacy)
34
+ --help | -h Show this help
35
+ EOF_USAGE
36
+ }
37
+
38
+ INPUT_JSON=""
39
+ SESSION_NAME=""
40
+ STATUS=""
41
+ SUMMARY=""
42
+ PROJECT_PATH=""
43
+ TASK_PATH=""
44
+ TASK_ID=""
45
+ PROGRESS=""
46
+ STRUCTURED="false"
47
+
48
+ # Detect legacy JSON argument as the first parameter
49
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
50
+ INPUT_JSON="$1"
51
+ shift || true
52
+ fi
53
+
54
+ while [[ $# -gt 0 ]]; do
55
+ case "$1" in
56
+ --session|-s)
57
+ SESSION_NAME="$2"
58
+ shift 2
59
+ ;;
60
+ --status|-S)
61
+ STATUS="$2"
62
+ shift 2
63
+ ;;
64
+ --summary|-m)
65
+ SUMMARY="$2"
66
+ shift 2
67
+ ;;
68
+ --summary-file)
69
+ SUMMARY="$(cat "$2")"
70
+ shift 2
71
+ ;;
72
+ --project|-p)
73
+ PROJECT_PATH="$2"
74
+ shift 2
75
+ ;;
76
+ --task-path)
77
+ TASK_PATH="$2"
78
+ shift 2
79
+ ;;
80
+ --task-id)
81
+ TASK_ID="$2"
82
+ shift 2
83
+ ;;
84
+ --progress)
85
+ PROGRESS="$2"
86
+ shift 2
87
+ ;;
88
+ --structured)
89
+ STRUCTURED="true"
90
+ shift
91
+ ;;
92
+ --json|-j)
93
+ INPUT_JSON="$2"
94
+ shift 2
95
+ ;;
96
+ --help|-h)
97
+ print_usage
98
+ exit 0
99
+ ;;
100
+ --)
101
+ shift
102
+ break
103
+ ;;
104
+ *)
105
+ if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then
106
+ INPUT_JSON="$1"
107
+ shift
108
+ else
109
+ error_exit "Unknown argument: $1. Use --help for usage."
110
+ fi
111
+ ;;
112
+ esac
113
+ done
114
+
115
+ # If nothing provided yet but stdin has data, read it as summary
116
+ if [ -z "$INPUT_JSON" ] && [ -z "$SUMMARY" ] && [ ! -t 0 ]; then
117
+ STDIN_DATA="$(cat)"
118
+ if [[ ${STDIN_DATA:0:1} == '{' ]]; then
119
+ INPUT_JSON="$STDIN_DATA"
120
+ else
121
+ SUMMARY="$STDIN_DATA"
122
+ fi
123
+ fi
124
+
125
+ # Parse JSON input if provided (backward compatible)
126
+ if [ -n "$INPUT_JSON" ]; then
127
+ INPUT=$(read_json_input "$INPUT_JSON")
128
+ [ -z "$SESSION_NAME" ] && SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
129
+ [ -z "$STATUS" ] && STATUS=$(printf '%s' "$INPUT" | jq -r '.status // empty')
130
+ [ -z "$SUMMARY" ] && SUMMARY=$(printf '%s' "$INPUT" | jq -r '.summary // empty')
131
+ [ -z "$TASK_PATH" ] && TASK_PATH=$(printf '%s' "$INPUT" | jq -r '.taskPath // empty')
132
+ [ -z "$TASK_ID" ] && TASK_ID=$(printf '%s' "$INPUT" | jq -r '.taskId // empty')
133
+ [ -z "$PROGRESS" ] && PROGRESS=$(printf '%s' "$INPUT" | jq -r '.progress // empty')
134
+ [ -z "$PROJECT_PATH" ] && PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
135
+ ARTIFACTS=$(printf '%s' "$INPUT" | jq -c '.artifacts // empty')
136
+ BLOCKERS=$(printf '%s' "$INPUT" | jq -c '.blockers // empty')
137
+ USE_STRUCTURED=$(printf '%s' "$INPUT" | jq -r '.structured // "false"')
138
+ [ "$USE_STRUCTURED" = "true" ] && STRUCTURED="true"
139
+ else
140
+ ARTIFACTS=""
141
+ BLOCKERS=""
142
+ fi
143
+
144
+ require_param "sessionName (--session)" "$SESSION_NAME"
145
+ require_param "status (--status)" "$STATUS"
146
+ require_param "summary (--summary)" "$SUMMARY"
24
147
 
25
148
  # Map simple status strings to InProgressTaskStatus values
26
149
  map_status_to_state() {
@@ -34,7 +157,7 @@ map_status_to_state() {
34
157
  }
35
158
 
36
159
  # Build the message the orchestrator will receive
37
- if [ "$USE_STRUCTURED" = "true" ] && [ -n "$TASK_ID" ]; then
160
+ if [ "$STRUCTURED" = "true" ] && [ -n "$TASK_ID" ]; then
38
161
  # Structured StatusReport format for hierarchical teams
39
162
  STATE=$(map_status_to_state "$STATUS")
40
163
  MESSAGE="---\n[STATUS REPORT]\nTask ID: ${TASK_ID}\nState: ${STATE}"
@@ -68,12 +191,6 @@ BODY=$(jq -n --arg content "$MESSAGE" --arg senderName "$SESSION_NAME" \
68
191
 
69
192
  api_call POST "/chat/agent-response" "$BODY"
70
193
 
71
- # Auto-register as active when reporting "active" or first status.
72
- # This ensures the agent's agentStatus transitions from "started" to "active"
73
- # in storage, which the queue processor requires before delivering messages.
74
- # Without this, agents that call report-status instead of register-self
75
- # remain stuck in "started" state indefinitely.
76
-
77
194
  # If task is done and taskPath provided, move task file to done folder
78
195
  if [ "$STATUS" = "done" ] && [ -n "$TASK_PATH" ]; then
79
196
  COMPLETE_BODY=$(jq -n \
@@ -90,9 +207,6 @@ if [ "$STATUS" = "done" ]; then
90
207
  fi
91
208
 
92
209
  # Auto-persist key findings as project knowledge when task is done (#127, #219).
93
- # Use [COMPLETED] prefix so recall can distinguish completed tasks from other patterns.
94
- # This prevents PM from re-delegating tasks that were already done.
95
210
  if [ "$STATUS" = "done" ] && [ -n "$SUMMARY" ]; then
96
- PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
97
211
  auto_remember "$SESSION_NAME" "[COMPLETED] Task completed by ${SESSION_NAME}: ${SUMMARY}" "decision" "project" "$PROJECT_PATH"
98
212
  fi
@@ -42,15 +42,29 @@ Send a direct message to another agent's terminal session. The message is writte
42
42
 
43
43
  ## Parameters
44
44
 
45
- | Parameter | Required | Description |
46
- |-----------|----------|-------------|
47
- | `to` | Yes | Target agent's PTY session name |
48
- | `message` | Yes | The message text to send |
45
+ | Flag | JSON Field | Required | Description |
46
+ |------|-----------|----------|-------------|
47
+ | `--to` / `-t` | `to` | Yes | Target agent's PTY session name |
48
+ | `--message` / `-m` | `message` | Yes | Message text (or pipe via stdin) |
49
+ | `--message-file` | — | No | Read message from a file path |
49
50
 
50
- ## Example
51
+ ## Examples — CLI Flags (preferred)
51
52
 
52
53
  ```bash
53
- bash config/skills/agent/send-message/execute.sh '{"to":"qa-1","message":"PR #42 is ready for review. I added unit tests for the auth module."}'
54
+ # Simple message
55
+ bash execute.sh --to qa-1 --message "PR #42 is ready for review"
56
+
57
+ # Multi-line message via stdin (avoids shell escaping)
58
+ echo "PR #42 is ready for review. It's passing all tests." | bash execute.sh --to qa-1
59
+
60
+ # Message from file
61
+ bash execute.sh --to qa-1 --message-file /tmp/task-details.txt
62
+ ```
63
+
64
+ ## Examples — Legacy JSON (backward compatible)
65
+
66
+ ```bash
67
+ bash execute.sh '{"to":"qa-1","message":"PR #42 is ready for review."}'
54
68
  ```
55
69
 
56
70
  ## Output
@@ -1,18 +1,100 @@
1
1
  #!/bin/bash
2
2
  # Send a direct message to another agent's terminal session.
3
- # Supports: argument, stdin pipe, or @filepath for JSON input (#292, #293).
3
+ # Supports CLI flags (preferred), legacy JSON, stdin pipe, or @filepath.
4
4
  set -euo pipefail
5
5
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
6
  source "${SCRIPT_DIR}/../../_common/lib.sh"
7
7
 
8
- INPUT=$(read_json_input "${1:-}")
9
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"to\":\"agent-session\",\"message\":\"...\"}' or echo '{...}' | execute.sh"
8
+ print_usage() {
9
+ cat <<'EOF_USAGE'
10
+ Usage:
11
+ # CLI flags (preferred)
12
+ bash execute.sh --to agent-session --message "Please implement feature X"
10
13
 
11
- # Accept both "to" and "sessionName" for compatibility (#231)
12
- TO=$(printf '%s' "$INPUT" | jq -r '.to // .sessionName // empty')
13
- MESSAGE=$(printf '%s' "$INPUT" | jq -r '.message // empty')
14
- require_param "to (or sessionName)" "$TO"
15
- require_param "message" "$MESSAGE"
14
+ # Message from stdin (for multi-line or special characters)
15
+ echo "Implement feature X — it's urgent" | bash execute.sh --to agent-session
16
+
17
+ # Message from file
18
+ bash execute.sh --to agent-session --message-file /tmp/task.txt
19
+
20
+ # Legacy JSON (backward compatible)
21
+ bash execute.sh '{"to":"agent-session","message":"..."}'
22
+
23
+ Options:
24
+ --to | -t Target agent session name (required)
25
+ --message | -m Message text (required unless piped via stdin)
26
+ --message-file Read message from file path
27
+ --json | -j Raw JSON payload (same as legacy)
28
+ --help | -h Show this help
29
+ EOF_USAGE
30
+ }
31
+
32
+ INPUT_JSON=""
33
+ TO=""
34
+ MESSAGE=""
35
+
36
+ # Detect legacy JSON argument
37
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
38
+ INPUT_JSON="$1"
39
+ shift || true
40
+ fi
41
+
42
+ while [[ $# -gt 0 ]]; do
43
+ case "$1" in
44
+ --to|-t)
45
+ TO="$2"
46
+ shift 2
47
+ ;;
48
+ --message|-m)
49
+ MESSAGE="$2"
50
+ shift 2
51
+ ;;
52
+ --message-file)
53
+ MESSAGE="$(cat "$2")"
54
+ shift 2
55
+ ;;
56
+ --json|-j)
57
+ INPUT_JSON="$2"
58
+ shift 2
59
+ ;;
60
+ --help|-h)
61
+ print_usage
62
+ exit 0
63
+ ;;
64
+ --)
65
+ shift
66
+ break
67
+ ;;
68
+ *)
69
+ if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then
70
+ INPUT_JSON="$1"
71
+ shift
72
+ else
73
+ error_exit "Unknown argument: $1. Use --help for usage."
74
+ fi
75
+ ;;
76
+ esac
77
+ done
78
+
79
+ # Read from stdin if no message yet
80
+ if [ -z "$INPUT_JSON" ] && [ -z "$MESSAGE" ] && [ ! -t 0 ]; then
81
+ STDIN_DATA="$(cat)"
82
+ if [[ ${STDIN_DATA:0:1} == '{' ]]; then
83
+ INPUT_JSON="$STDIN_DATA"
84
+ else
85
+ MESSAGE="$STDIN_DATA"
86
+ fi
87
+ fi
88
+
89
+ # Parse JSON if provided
90
+ if [ -n "$INPUT_JSON" ]; then
91
+ INPUT=$(read_json_input "$INPUT_JSON")
92
+ [ -z "$TO" ] && TO=$(printf '%s' "$INPUT" | jq -r '.to // .sessionName // empty')
93
+ [ -z "$MESSAGE" ] && MESSAGE=$(printf '%s' "$INPUT" | jq -r '.message // empty')
94
+ fi
95
+
96
+ require_param "to (--to)" "$TO"
97
+ require_param "message (--message)" "$MESSAGE"
16
98
 
17
99
  BODY=$(jq -n --arg data "$MESSAGE" --arg mode "message" '{data: $data, mode: $mode}')
18
100
 
@@ -32,30 +32,48 @@ The script auto-resolves `config/skills/...` references to absolute paths so del
32
32
 
33
33
  **Monitoring is enabled by default** — idle event subscriptions and recurring fallback checks (every 5 minutes) are automatically set up for every delegation. These are linked to the task and will be **automatically cleaned up** when the task is completed via `report-status` or `complete-task`. To disable monitoring, explicitly pass `"monitor": {"idleEvent": false, "fallbackCheckMinutes": 0}`.
34
34
 
35
- ## Usage
35
+ ## Parameters
36
+
37
+ | Flag | JSON Field | Required | Description |
38
+ |------|-----------|----------|-------------|
39
+ | `--to` / `-t` | `to` | Yes | Target agent's PTY session name |
40
+ | `--task` / `-T` | `task` | Yes | Task description (or pipe via stdin) |
41
+ | `--task-file` | — | No | Read task description from a file path |
42
+ | `--priority` / `-P` | `priority` | No | Priority: `low`, `normal`, `high` (default: `normal`) |
43
+ | `--context` / `-c` | `context` | No | Additional context for the task |
44
+ | `--project` / `-p` | `projectPath` | No | Project path; creates task file in `.crewly/tasks/` |
45
+ | `--team` / `-g` | `teamId` | No | Team ID for cross-team validation |
46
+ | `--task-type` | `taskType` | No | Task type: `general`, `technical` (default: `general`) |
47
+ | `--force-cross-team` | `forceCrossTeam` | No | Allow cross-team delegation |
48
+ | `monitor` (JSON only) | `monitor` | No | Auto-monitoring config (see below) |
49
+
50
+ ## Usage — CLI Flags (preferred)
36
51
 
37
52
  ```bash
38
- bash config/skills/orchestrator/delegate-task/execute.sh '{"to":"agent-joe","task":"Implement the login form","priority":"high","context":"Use React hooks","projectPath":"/path/to/project"}'
53
+ # Basic delegation
54
+ bash execute.sh --to agent-joe --task "Implement the login form" --priority high --project /path/to/project
55
+
56
+ # With context
57
+ bash execute.sh --to agent-joe --task "Implement login form" --priority high --context "Use React hooks" --project /path
58
+
59
+ # Task from stdin (for long descriptions with special characters)
60
+ echo "Implement the OAuth2 flow — it's critical for launch" | bash execute.sh --to agent-joe --priority high --project /path
61
+
62
+ # Task from file
63
+ bash execute.sh --to agent-joe --task-file /tmp/task-description.txt --priority high --project /path
39
64
  ```
40
65
 
41
- ### With monitoring disabled (opt-out)
66
+ ## Usage Legacy JSON (backward compatible)
42
67
 
43
68
  ```bash
44
- bash config/skills/orchestrator/delegate-task/execute.sh '{"to":"agent-joe","task":"Implement the login form","priority":"high","projectPath":"/path/to/project","monitor":{"idleEvent":false,"fallbackCheckMinutes":0}}'
69
+ bash execute.sh '{"to":"agent-joe","task":"Implement the login form","priority":"high","context":"Use React hooks","projectPath":"/path/to/project"}'
45
70
  ```
46
71
 
47
- ## Parameters
72
+ ### With monitoring disabled (opt-out, JSON only)
48
73
 
49
- | Parameter | Required | Description |
50
- |-----------|----------|-------------|
51
- | `to` | Yes | Target agent's PTY session name |
52
- | `task` | Yes | Task description |
53
- | `priority` | No | Task priority: `low`, `normal`, `high` (default: `normal`) |
54
- | `context` | No | Additional context for the task |
55
- | `projectPath` | No | Project path; when provided, creates a task MD file in `.crewly/tasks/` |
56
- | `monitor` | No | Auto-monitoring configuration (see below). Enabled by default. |
57
- | `monitor.idleEvent` | No | If `true`, subscribes to `agent:idle` event for the target agent (default: `true`) |
58
- | `monitor.fallbackCheckMinutes` | No | If > 0, sets up a recurring fallback check every N minutes (default: `5`) |
74
+ ```bash
75
+ bash execute.sh '{"to":"agent-joe","task":"Implement the login form","priority":"high","projectPath":"/path/to/project","monitor":{"idleEvent":false,"fallbackCheckMinutes":0}}'
76
+ ```
59
77
 
60
78
  ## Examples
61
79
 
@@ -6,21 +6,75 @@ set -euo pipefail
6
6
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
7
  source "${SCRIPT_DIR}/../_common/lib.sh"
8
8
 
9
- INPUT=$(read_json_input "${1:-}")
10
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"to\":\"agent-session\",\"task\":\"...\"}' or echo '{...}' | execute.sh"
11
-
12
- TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
13
- TASK=$(printf '%s' "$INPUT" | jq -r '.task // empty')
14
- PRIORITY=$(printf '%s' "$INPUT" | jq -r '.priority // "normal"')
15
- CONTEXT=$(printf '%s' "$INPUT" | jq -r '.context // empty')
16
- PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
17
- # #150: Task type classification — 'technical' tasks can bypass PM routing
18
- TASK_TYPE=$(printf '%s' "$INPUT" | jq -r '.taskType // "general"')
19
- # #180: Cross-team validation
20
- TEAM_ID=$(printf '%s' "$INPUT" | jq -r '.teamId // empty')
21
- FORCE_CROSS_TEAM=$(printf '%s' "$INPUT" | jq -r '.forceCrossTeam // "false"')
22
- require_param "to" "$TO"
23
- require_param "task" "$TASK"
9
+ # --- Input parsing: CLI flags (preferred) or legacy JSON ---
10
+ INPUT_JSON=""
11
+ TO=""
12
+ TASK=""
13
+ PRIORITY="normal"
14
+ CONTEXT=""
15
+ PROJECT_PATH=""
16
+ TASK_TYPE="general"
17
+ TEAM_ID=""
18
+ FORCE_CROSS_TEAM="false"
19
+
20
+ # Detect legacy JSON argument
21
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
22
+ INPUT_JSON="$1"
23
+ shift || true
24
+ fi
25
+
26
+ while [[ $# -gt 0 ]]; do
27
+ case "$1" in
28
+ --to|-t) TO="$2"; shift 2 ;;
29
+ --task|-T) TASK="$2"; shift 2 ;;
30
+ --task-file) TASK="$(cat "$2")"; shift 2 ;;
31
+ --priority|-P) PRIORITY="$2"; shift 2 ;;
32
+ --context|-c) CONTEXT="$2"; shift 2 ;;
33
+ --project|-p) PROJECT_PATH="$2"; shift 2 ;;
34
+ --task-type) TASK_TYPE="$2"; shift 2 ;;
35
+ --team|-g) TEAM_ID="$2"; shift 2 ;;
36
+ --force-cross-team) FORCE_CROSS_TEAM="true"; shift ;;
37
+ --json|-j) INPUT_JSON="$2"; shift 2 ;;
38
+ --help|-h)
39
+ echo "Usage: execute.sh --to agent-session --task 'implement feature' --priority high --project /path [--team teamId] [--context 'extra info']"
40
+ exit 0
41
+ ;;
42
+ --) shift; break ;;
43
+ *)
44
+ if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then
45
+ INPUT_JSON="$1"; shift
46
+ else
47
+ error_exit "Unknown argument: $1"
48
+ fi
49
+ ;;
50
+ esac
51
+ done
52
+
53
+ # Read task from stdin if not yet provided
54
+ if [ -z "$INPUT_JSON" ] && [ -z "$TASK" ] && [ ! -t 0 ]; then
55
+ STDIN_DATA="$(cat)"
56
+ if [[ ${STDIN_DATA:0:1} == '{' ]]; then
57
+ INPUT_JSON="$STDIN_DATA"
58
+ else
59
+ TASK="$STDIN_DATA"
60
+ fi
61
+ fi
62
+
63
+ # Parse JSON if provided (backward compatible)
64
+ if [ -n "$INPUT_JSON" ]; then
65
+ INPUT=$(read_json_input "$INPUT_JSON")
66
+ [ -z "$TO" ] && TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
67
+ [ -z "$TASK" ] && TASK=$(printf '%s' "$INPUT" | jq -r '.task // empty')
68
+ [ "$PRIORITY" = "normal" ] && { P=$(printf '%s' "$INPUT" | jq -r '.priority // empty'); [ -n "$P" ] && PRIORITY="$P"; }
69
+ [ -z "$CONTEXT" ] && CONTEXT=$(printf '%s' "$INPUT" | jq -r '.context // empty')
70
+ [ -z "$PROJECT_PATH" ] && PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
71
+ [ "$TASK_TYPE" = "general" ] && { TT=$(printf '%s' "$INPUT" | jq -r '.taskType // empty'); [ -n "$TT" ] && TASK_TYPE="$TT"; }
72
+ [ -z "$TEAM_ID" ] && TEAM_ID=$(printf '%s' "$INPUT" | jq -r '.teamId // empty')
73
+ [ "$FORCE_CROSS_TEAM" = "false" ] && FORCE_CROSS_TEAM=$(printf '%s' "$INPUT" | jq -r '.forceCrossTeam // "false"')
74
+ fi
75
+
76
+ require_param "to (--to)" "$TO"
77
+ require_param "task (--task)" "$TASK"
24
78
 
25
79
  # #180: Validate target agent belongs to the specified team
26
80
  if [ -n "$TEAM_ID" ] && [ "$FORCE_CROSS_TEAM" != "true" ]; then
@@ -34,24 +34,41 @@ Assigns a task to a worker within the Team Leader's subordinate scope. Validates
34
34
  - When `handle-failure` decides to `reassign` a task
35
35
  - When a new worker needs to be given work
36
36
 
37
- ## Usage
37
+ ## Parameters
38
+
39
+ | Flag | JSON Field | Required | Description |
40
+ |------|-----------|----------|-------------|
41
+ | `--to` / `-t` | `to` | Yes | Target worker's PTY session name |
42
+ | `--task` / `-T` | `task` | Yes | Task description (or pipe via stdin) |
43
+ | `--task-file` | — | No | Read task description from a file path |
44
+ | `--priority` / `-P` | `priority` | No | Priority: `low`, `normal`, `high` (default: `normal`) |
45
+ | `--context` / `-c` | `context` | No | Additional context for the worker |
46
+ | `--project` / `-p` | `projectPath` | No | Project path; creates task file in `.crewly/tasks/` |
47
+ | `--team` / `-g` | `teamId` | No | Team ID for hierarchy validation |
48
+ | `--tl-member` | `tlMemberId` | No | TL's member ID for hierarchy validation |
49
+ | `--from` | `fromSession` | No | Delegating TL's session name (for monitoring) |
50
+
51
+ ## Usage — CLI Flags (preferred)
38
52
 
39
53
  ```bash
40
- bash {{SKILLS_PATH}}/team-leader/delegate-task/execute.sh '{"to":"worker-session","task":"Implement login form","priority":"high","teamId":"team-123","tlMemberId":"tl-member-id","projectPath":"/path/to/project"}'
54
+ # Basic delegation
55
+ bash execute.sh --to worker-session --task "Implement login form" --priority high --project /path/to/project
56
+
57
+ # With hierarchy validation
58
+ bash execute.sh --to worker-session --task "Implement login form" --priority high --team team-123 --tl-member tl-member-id --project /path/to/project
59
+
60
+ # Task from stdin (for long descriptions with special characters)
61
+ echo "Implement the OAuth2 flow — it's critical for launch" | bash execute.sh --to worker-session --priority high --project /path
62
+
63
+ # Task from file
64
+ bash execute.sh --to worker-session --task-file /tmp/task-description.txt --priority high --project /path
41
65
  ```
42
66
 
43
- ## Parameters
67
+ ## Usage — Legacy JSON (backward compatible)
44
68
 
45
- | Parameter | Required | Description |
46
- |-----------|----------|-------------|
47
- | `to` | Yes | Target worker's PTY session name |
48
- | `task` | Yes | Task description (skill paths auto-resolved to absolute) |
49
- | `priority` | No | Task priority: `low`, `normal`, `high` (default: `normal`) |
50
- | `context` | No | Additional context for the worker |
51
- | `teamId` | No | Team ID for hierarchy validation |
52
- | `tlMemberId` | No | TL's member ID for hierarchy validation |
53
- | `projectPath` | No | Project path; creates task file in `.crewly/tasks/` |
54
- | `monitor` | No | Auto-monitoring config (same as orchestrator delegate-task) |
69
+ ```bash
70
+ bash execute.sh '{"to":"worker-session","task":"Implement login form","priority":"high","teamId":"team-123","tlMemberId":"tl-member-id","projectPath":"/path/to/project"}'
71
+ ```
55
72
 
56
73
  ## Hierarchy Validation
57
74
 
@@ -6,19 +6,75 @@ set -euo pipefail
6
6
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
7
  source "${SCRIPT_DIR}/../_common/lib.sh"
8
8
 
9
- INPUT=$(read_json_input "${1:-}")
10
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"to\":\"worker-session\",\"task\":\"...\"}' or echo '{...}' | execute.sh"
11
-
12
- TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
13
- TASK=$(printf '%s' "$INPUT" | jq -r '.task // empty')
14
- PRIORITY=$(printf '%s' "$INPUT" | jq -r '.priority // "normal"')
15
- CONTEXT=$(printf '%s' "$INPUT" | jq -r '.context // empty')
16
- PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
17
- TEAM_ID=$(printf '%s' "$INPUT" | jq -r '.teamId // empty')
18
- TL_MEMBER_ID=$(printf '%s' "$INPUT" | jq -r '.tlMemberId // empty')
19
- FROM_SESSION=$(printf '%s' "$INPUT" | jq -r '.fromSession // empty')
20
- require_param "to" "$TO"
21
- require_param "task" "$TASK"
9
+ # --- Input parsing: CLI flags (preferred) or legacy JSON ---
10
+ INPUT_JSON=""
11
+ TO=""
12
+ TASK=""
13
+ PRIORITY="normal"
14
+ CONTEXT=""
15
+ PROJECT_PATH=""
16
+ TEAM_ID=""
17
+ TL_MEMBER_ID=""
18
+ FROM_SESSION=""
19
+
20
+ # Detect legacy JSON argument
21
+ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
22
+ INPUT_JSON="$1"
23
+ shift || true
24
+ fi
25
+
26
+ while [[ $# -gt 0 ]]; do
27
+ case "$1" in
28
+ --to|-t) TO="$2"; shift 2 ;;
29
+ --task|-T) TASK="$2"; shift 2 ;;
30
+ --task-file) TASK="$(cat "$2")"; shift 2 ;;
31
+ --priority|-P) PRIORITY="$2"; shift 2 ;;
32
+ --context|-c) CONTEXT="$2"; shift 2 ;;
33
+ --project|-p) PROJECT_PATH="$2"; shift 2 ;;
34
+ --team|-g) TEAM_ID="$2"; shift 2 ;;
35
+ --tl-member) TL_MEMBER_ID="$2"; shift 2 ;;
36
+ --from) FROM_SESSION="$2"; shift 2 ;;
37
+ --json|-j) INPUT_JSON="$2"; shift 2 ;;
38
+ --help|-h)
39
+ echo "Usage: execute.sh --to worker-session --task 'implement feature' --priority high --project /path [--team teamId] [--tl-member memberId]"
40
+ exit 0
41
+ ;;
42
+ --) shift; break ;;
43
+ *)
44
+ if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then
45
+ INPUT_JSON="$1"; shift
46
+ else
47
+ error_exit "Unknown argument: $1"
48
+ fi
49
+ ;;
50
+ esac
51
+ done
52
+
53
+ # Read task from stdin if not yet provided
54
+ if [ -z "$INPUT_JSON" ] && [ -z "$TASK" ] && [ ! -t 0 ]; then
55
+ STDIN_DATA="$(cat)"
56
+ if [[ ${STDIN_DATA:0:1} == '{' ]]; then
57
+ INPUT_JSON="$STDIN_DATA"
58
+ else
59
+ TASK="$STDIN_DATA"
60
+ fi
61
+ fi
62
+
63
+ # Parse JSON if provided (backward compatible)
64
+ if [ -n "$INPUT_JSON" ]; then
65
+ INPUT=$(read_json_input "$INPUT_JSON")
66
+ [ -z "$TO" ] && TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
67
+ [ -z "$TASK" ] && TASK=$(printf '%s' "$INPUT" | jq -r '.task // empty')
68
+ [ "$PRIORITY" = "normal" ] && { P=$(printf '%s' "$INPUT" | jq -r '.priority // empty'); [ -n "$P" ] && PRIORITY="$P"; }
69
+ [ -z "$CONTEXT" ] && CONTEXT=$(printf '%s' "$INPUT" | jq -r '.context // empty')
70
+ [ -z "$PROJECT_PATH" ] && PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
71
+ [ -z "$TEAM_ID" ] && TEAM_ID=$(printf '%s' "$INPUT" | jq -r '.teamId // empty')
72
+ [ -z "$TL_MEMBER_ID" ] && TL_MEMBER_ID=$(printf '%s' "$INPUT" | jq -r '.tlMemberId // empty')
73
+ [ -z "$FROM_SESSION" ] && FROM_SESSION=$(printf '%s' "$INPUT" | jq -r '.fromSession // empty')
74
+ fi
75
+
76
+ require_param "to (--to)" "$TO"
77
+ require_param "task (--task)" "$TASK"
22
78
 
23
79
  # Resolve Crewly root from this script path:
24
80
  # config/skills/team-leader/delegate-task/execute.sh -> project root