overlord-cli 0.2605131058.0 → 0.2605131312.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/bin/_cli/protocol.mjs +45 -0
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/scripts/user-prompt-submit-hook.sh +37 -5
- package/plugins/overlord/.codex-plugin/plugin.json +1 -1
- package/plugins/overlord/scripts/user-prompt-submit-hook.sh +36 -5
package/bin/_cli/protocol.mjs
CHANGED
|
@@ -1570,6 +1570,34 @@ async function protocolPrompt(args) {
|
|
|
1570
1570
|
}
|
|
1571
1571
|
}
|
|
1572
1572
|
|
|
1573
|
+
// ---------------------------------------------------------------------------
|
|
1574
|
+
// discuss-objective (mark a draft objective as submitted)
|
|
1575
|
+
// ---------------------------------------------------------------------------
|
|
1576
|
+
|
|
1577
|
+
async function protocolDiscussObjective(args) {
|
|
1578
|
+
const flags = parseFlags(args);
|
|
1579
|
+
const ticketId = requireFlag(flags, 'ticket-id', process.env.TICKET_ID);
|
|
1580
|
+
const { platformUrl, bearerToken, localSecret, organizationId } =
|
|
1581
|
+
await resolveProtocolAuthForFlags(flags, ticketId);
|
|
1582
|
+
const timeoutMs = resolveTimeout(flags);
|
|
1583
|
+
|
|
1584
|
+
const body = {
|
|
1585
|
+
ticketId,
|
|
1586
|
+
...(flags['objective-id'] ? { objectiveId: String(flags['objective-id']) } : {})
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
const data = await apiPost(
|
|
1590
|
+
platformUrl,
|
|
1591
|
+
bearerToken,
|
|
1592
|
+
localSecret,
|
|
1593
|
+
organizationId,
|
|
1594
|
+
'/api/protocol/discuss-objective',
|
|
1595
|
+
body,
|
|
1596
|
+
timeoutMs
|
|
1597
|
+
);
|
|
1598
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1573
1601
|
// ---------------------------------------------------------------------------
|
|
1574
1602
|
// create (create follow-up ticket draft only)
|
|
1575
1603
|
// ---------------------------------------------------------------------------
|
|
@@ -1761,6 +1789,7 @@ Subcommands:
|
|
|
1761
1789
|
connect Start a lightweight session without full context
|
|
1762
1790
|
load-context Read ticket context without creating a session
|
|
1763
1791
|
search-tickets Find tickets by keyword, status, project, creator, or update date
|
|
1792
|
+
discuss-objective Mark a draft objective as submitted (ready for review/execution)
|
|
1764
1793
|
create Create a draft ticket without attaching (follow-up or standalone)
|
|
1765
1794
|
prompt Create a ticket and attach to it immediately
|
|
1766
1795
|
update Post progress, activity events, and optional change rationales
|
|
@@ -1998,6 +2027,16 @@ prompt:
|
|
|
1998
2027
|
Returns:
|
|
1999
2028
|
New ticket/session JSON plus SESSION_KEY and TICKET_ID on stderr when available
|
|
2000
2029
|
|
|
2030
|
+
discuss-objective:
|
|
2031
|
+
Purpose:
|
|
2032
|
+
Mark the latest draft objective on a ticket as "submitted", indicating the objective
|
|
2033
|
+
has been discussed and is ready for review or execution. Does NOT start execution —
|
|
2034
|
+
use \`attach\` to begin execution.
|
|
2035
|
+
Required:
|
|
2036
|
+
--ticket-id <ticket_id>
|
|
2037
|
+
Optional:
|
|
2038
|
+
--objective-id <id> Target a specific draft objective by UUID
|
|
2039
|
+
|
|
2001
2040
|
create:
|
|
2002
2041
|
Purpose:
|
|
2003
2042
|
Create a draft ticket without attaching to it.
|
|
@@ -2089,6 +2128,8 @@ Examples:
|
|
|
2089
2128
|
ovld protocol connect --ticket-id 1:899
|
|
2090
2129
|
ovld protocol load-context --ticket-id 1:899
|
|
2091
2130
|
ovld protocol search-tickets --query "auth refactor" --status next-up,execute --limit 10
|
|
2131
|
+
ovld protocol discuss-objective --ticket-id 1:899
|
|
2132
|
+
ovld protocol discuss-objective --ticket-id 1:899 --objective-id <objective-uuid>
|
|
2092
2133
|
ovld protocol create --agent codex --objective "Capture follow-up work from this repo"
|
|
2093
2134
|
ovld protocol create --agent codex --session-key <key> --ticket-id <ticket_id> --objective "Capture follow-up work"
|
|
2094
2135
|
ovld protocol prompt --agent codex --objective "Implement user auth" --priority high
|
|
@@ -2138,6 +2179,10 @@ Examples:
|
|
|
2138
2179
|
await protocolSearchTickets(args);
|
|
2139
2180
|
return;
|
|
2140
2181
|
}
|
|
2182
|
+
if (subcommand === 'discuss-objective') {
|
|
2183
|
+
await protocolDiscussObjective(args);
|
|
2184
|
+
return;
|
|
2185
|
+
}
|
|
2141
2186
|
if (subcommand === 'create' || subcommand === 'create-ticket') {
|
|
2142
2187
|
await protocolCreateTicket(args);
|
|
2143
2188
|
return;
|
package/package.json
CHANGED
|
@@ -9,6 +9,23 @@ BODY=$(cat -)
|
|
|
9
9
|
OVERLORD_BASE_URL="${CLAUDE_PLUGIN_OPTION_OVERLORD_URL:-$OVERLORD_URL}"
|
|
10
10
|
OVERLORD_TOKEN="${CLAUDE_PLUGIN_OPTION_AGENT_TOKEN:-${CLAUDE_PLUGIN_OPTION_OVERLORD_ACCESS_TOKEN:-$OVERLORD_ACCESS_TOKEN}}"
|
|
11
11
|
OVERLORD_LOCAL_SECRET="${OVERLORD_LOCAL_SECRET:-}"
|
|
12
|
+
HOOK_NAME="claude"
|
|
13
|
+
LOG_DIR="${HOME:-}/.ovld/logs"
|
|
14
|
+
LOG_FILE="${LOG_DIR}/user-prompt-submit-hook.log"
|
|
15
|
+
|
|
16
|
+
log_hook() {
|
|
17
|
+
mkdir -p "$LOG_DIR" 2>/dev/null || return 0
|
|
18
|
+
printf '%s [%s] %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$HOOK_NAME" "$1" >>"$LOG_FILE" 2>/dev/null || true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
PROMPT_LEN=$(printf '%s' "$BODY" | python3 -c "import json,sys; print(len((json.load(sys.stdin).get('prompt') or '').strip()))" 2>/dev/null || echo "0")
|
|
22
|
+
SESSION_ID=$(printf '%s' "$BODY" | python3 -c "import json,sys; print(json.load(sys.stdin).get('session_id') or 'unknown')" 2>/dev/null || echo "unknown")
|
|
23
|
+
log_hook "received submit session_id=$SESSION_ID prompt_len=$PROMPT_LEN ticket_present=$([ -n "${TICKET_ID:-}" ] && echo yes || echo no)"
|
|
24
|
+
|
|
25
|
+
if [ -z "$OVERLORD_BASE_URL" ] || [ -z "$OVERLORD_TOKEN" ] || [ -z "${TICKET_ID:-}" ]; then
|
|
26
|
+
log_hook "missing required env base_url=$([ -n "$OVERLORD_BASE_URL" ] && echo yes || echo no) token=$([ -n "$OVERLORD_TOKEN" ] && echo yes || echo no) ticket=$([ -n "${TICKET_ID:-}" ] && echo yes || echo no)"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
12
29
|
|
|
13
30
|
if [ -n "$OVERLORD_BASE_URL" ] && [ -n "$OVERLORD_TOKEN" ] && [ -n "$TICKET_ID" ]; then
|
|
14
31
|
PAYLOAD=$(
|
|
@@ -48,16 +65,31 @@ tid = os.environ.get('TICKET_ID', '')
|
|
|
48
65
|
print(json.dumps({'hookType': 'UserPromptSubmit', 'ticketId': tid, 'prompt': text, 'turnIndex': turn_index}))
|
|
49
66
|
" 2>/dev/null
|
|
50
67
|
)
|
|
51
|
-
if [ -
|
|
52
|
-
|
|
68
|
+
if [ -z "$PAYLOAD" ]; then
|
|
69
|
+
log_hook "failed to build hook-event payload from submit body"
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
PAYLOAD_TURN=$(printf '%s' "$PAYLOAD" | python3 -c "import json,sys; print(json.load(sys.stdin).get('turnIndex', 'unknown'))" 2>/dev/null || echo "unknown")
|
|
74
|
+
log_hook "built payload turn=$PAYLOAD_TURN posting hook-event"
|
|
75
|
+
(
|
|
76
|
+
RESPONSE_FILE=$(mktemp "${TMPDIR:-/tmp}/overlord-hook-event.XXXXXX")
|
|
77
|
+
HTTP_CODE=$(curl -sS -m 5 -o "$RESPONSE_FILE" -w "%{http_code}" \
|
|
53
78
|
-X POST "$OVERLORD_BASE_URL/api/protocol/hook-event" \
|
|
54
79
|
-H "Authorization: Bearer $OVERLORD_TOKEN" \
|
|
55
80
|
-H "X-Overlord-Local-Secret: $OVERLORD_LOCAL_SECRET" \
|
|
56
81
|
-H "Content-Type: application/json" \
|
|
57
|
-
-d "$PAYLOAD"
|
|
58
|
-
|
|
82
|
+
-d "$PAYLOAD")
|
|
83
|
+
CURL_EXIT=$?
|
|
84
|
+
RESPONSE_PREVIEW=$(python3 -c "from pathlib import Path; import sys; p=Path(sys.argv[1]); text=p.read_text(encoding='utf-8', errors='replace') if p.exists() else ''; text=' '.join(text.split()); print(text[:200])" "$RESPONSE_FILE" 2>/dev/null || echo '')
|
|
85
|
+
rm -f "$RESPONSE_FILE"
|
|
86
|
+
if [ "$CURL_EXIT" -eq 0 ]; then
|
|
87
|
+
log_hook "hook-event POST finished exit=0 http_status=$HTTP_CODE response_preview=$RESPONSE_PREVIEW"
|
|
88
|
+
else
|
|
89
|
+
log_hook "hook-event POST failed exit=$CURL_EXIT http_status=${HTTP_CODE:-none} response_preview=$RESPONSE_PREVIEW"
|
|
90
|
+
fi
|
|
91
|
+
) >/dev/null 2>&1 &
|
|
59
92
|
disown
|
|
60
|
-
fi
|
|
61
93
|
fi
|
|
62
94
|
|
|
63
95
|
exit 0
|
|
@@ -5,24 +5,55 @@ BODY=$(cat -)
|
|
|
5
5
|
OVERLORD_BASE_URL="${OVERLORD_URL:-}"
|
|
6
6
|
OVERLORD_TOKEN="${OVERLORD_ACCESS_TOKEN:-}"
|
|
7
7
|
OVERLORD_LOCAL_SECRET="${OVERLORD_LOCAL_SECRET:-}"
|
|
8
|
+
HOOK_NAME="codex"
|
|
9
|
+
LOG_DIR="${HOME:-}/.ovld/logs"
|
|
10
|
+
LOG_FILE="${LOG_DIR}/user-prompt-submit-hook.log"
|
|
11
|
+
|
|
12
|
+
log_hook() {
|
|
13
|
+
mkdir -p "$LOG_DIR" 2>/dev/null || return 0
|
|
14
|
+
printf '%s [%s] %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$HOOK_NAME" "$1" >>"$LOG_FILE" 2>/dev/null || true
|
|
15
|
+
}
|
|
8
16
|
|
|
9
17
|
TURN=$(printf '%s' "$BODY" | python3 -c "import json,sys; print(json.load(sys.stdin).get('turn_number', 0))" 2>/dev/null || echo "0")
|
|
18
|
+
PROMPT_LEN=$(printf '%s' "$BODY" | python3 -c "import json,sys; print(len((json.load(sys.stdin).get('prompt') or '').strip()))" 2>/dev/null || echo "0")
|
|
19
|
+
log_hook "received submit turn=$TURN prompt_len=$PROMPT_LEN ticket_present=$([ -n "${TICKET_ID:-}" ] && echo yes || echo no)"
|
|
10
20
|
if [ "$TURN" = "0" ]; then
|
|
21
|
+
log_hook "skipping initial submit turn=0"
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [ -z "$OVERLORD_BASE_URL" ] || [ -z "$OVERLORD_TOKEN" ] || [ -z "${TICKET_ID:-}" ]; then
|
|
26
|
+
log_hook "missing required env base_url=$([ -n "$OVERLORD_BASE_URL" ] && echo yes || echo no) token=$([ -n "$OVERLORD_TOKEN" ] && echo yes || echo no) ticket=$([ -n "${TICKET_ID:-}" ] && echo yes || echo no)"
|
|
11
27
|
exit 0
|
|
12
28
|
fi
|
|
13
29
|
|
|
14
30
|
if [ -n "$OVERLORD_BASE_URL" ] && [ -n "$OVERLORD_TOKEN" ] && [ -n "$TICKET_ID" ]; then
|
|
15
31
|
PAYLOAD=$(printf '%s' "$BODY" | python3 -c "import json,sys; body=json.load(sys.stdin); print(json.dumps({'hookType': 'UserPromptSubmit', 'ticketId': __import__('os').environ['TICKET_ID'], 'prompt': body.get('prompt', ''), 'turnIndex': body.get('turn_number', 0)}))" 2>/dev/null || echo '')
|
|
16
|
-
if [ -
|
|
17
|
-
|
|
32
|
+
if [ -z "$PAYLOAD" ]; then
|
|
33
|
+
log_hook "failed to build hook-event payload from submit body"
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
PAYLOAD_TURN=$(printf '%s' "$PAYLOAD" | python3 -c "import json,sys; print(json.load(sys.stdin).get('turnIndex', 'unknown'))" 2>/dev/null || echo "unknown")
|
|
38
|
+
log_hook "built payload turn=$PAYLOAD_TURN posting hook-event"
|
|
39
|
+
(
|
|
40
|
+
RESPONSE_FILE=$(mktemp "${TMPDIR:-/tmp}/overlord-hook-event.XXXXXX")
|
|
41
|
+
HTTP_CODE=$(curl -sS -m 5 -o "$RESPONSE_FILE" -w "%{http_code}" \
|
|
18
42
|
-X POST "$OVERLORD_BASE_URL/api/protocol/hook-event" \
|
|
19
43
|
-H "Authorization: Bearer $OVERLORD_TOKEN" \
|
|
20
44
|
-H "X-Overlord-Local-Secret: $OVERLORD_LOCAL_SECRET" \
|
|
21
45
|
-H "Content-Type: application/json" \
|
|
22
|
-
-d "$PAYLOAD"
|
|
23
|
-
|
|
46
|
+
-d "$PAYLOAD")
|
|
47
|
+
CURL_EXIT=$?
|
|
48
|
+
RESPONSE_PREVIEW=$(python3 -c "from pathlib import Path; import sys; p=Path(sys.argv[1]); text=p.read_text(encoding='utf-8', errors='replace') if p.exists() else ''; text=' '.join(text.split()); print(text[:200])" "$RESPONSE_FILE" 2>/dev/null || echo '')
|
|
49
|
+
rm -f "$RESPONSE_FILE"
|
|
50
|
+
if [ "$CURL_EXIT" -eq 0 ]; then
|
|
51
|
+
log_hook "hook-event POST finished exit=0 http_status=$HTTP_CODE response_preview=$RESPONSE_PREVIEW"
|
|
52
|
+
else
|
|
53
|
+
log_hook "hook-event POST failed exit=$CURL_EXIT http_status=${HTTP_CODE:-none} response_preview=$RESPONSE_PREVIEW"
|
|
54
|
+
fi
|
|
55
|
+
) >/dev/null 2>&1 &
|
|
24
56
|
disown
|
|
25
|
-
fi
|
|
26
57
|
fi
|
|
27
58
|
|
|
28
59
|
exit 0
|