Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion agentkit/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agentkit",
"version": "0.9.12",
"version": "0.9.13",
"description": "Board-aware parallel issue and PR review skills, with lifecycle hooks and a per-repository contract.",
"author": {
"name": "wrzonance",
Expand Down
2 changes: 1 addition & 1 deletion agentkit/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agentkit",
"version": "0.9.12",
"version": "0.9.13",
"description": "Board-aware parallel issue and PR review skills, with lifecycle hooks and a per-repository contract.",
"author": {
"name": "wrzonance",
Expand Down
6 changes: 3 additions & 3 deletions agentkit/skills/.shared/scripts/triage-issues.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ Recipe: triage once
"$agentkit/.shared/scripts/triage-issues.sh" --limit 30
# Alternative explicit mode (replace with the requested numbers; do not run both):
# "$agentkit/.shared/scripts/triage-issues.sh" --issues 57,54
"$agentkit/.shared/scripts/pick-issues.sh" --help # next: mechanical selection over this digest

The digest is evidence: each line includes issue number, board Status,
prior-art verdict, ADR candidates, and referencing PR. It also warms the
project-item cache used by the board mover.
Digest lines are evidence (number, Status, prior-art verdict, ADR candidates,
referencing PR) and warm the board mover's project-item cache.
EOF
}

Expand Down
8 changes: 4 additions & 4 deletions agentkit/skills/onboard-repo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ without a root test command, `agent-run.sh --cmd test` needs a dispatcher.

Edit `.agent/config.env` directly — values are line-wise and never sourced. Write active
`AGENT_REVIEW_PROVIDERS=...` and each command unquoted, then prove parsing. There is no approval
step for the first run — `agent-run.sh --cmd <name>` runs a declared command directly — but hand
the first invocation of each name to the user anyway: onboarding is attended, and them running and
reading it once is the actual review moment before this skill leaves the command declared for
every future session:
step for the first run — `$agentkit/.shared/scripts/agent-run.sh --cmd <name>` runs a declared command
directly — but hand each name's first invocation to the user anyway: onboarding is attended, and
that first run is the review moment before this skill leaves the command declared for every
future session:

```bash
[ -d "${agentkit:-}/.shared/scripts" ] && [ "${agentkit_provenance:-}" = ok ] || { printf "%s\n" "agentkit unresolved: prepend THE CACHE REHYDRATION block" >&2; exit 1; }
Expand Down
12 changes: 6 additions & 6 deletions agentkit/skills/parallel-issues/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,16 +245,16 @@ referencing it) is documented in
Use this for automatic or numbered thematic-Backlog selection; otherwise explicit numbers win.
**A thin Ready column is an invitation, not a blocker.** Read
[references/triage-and-selection.md](references/triage-and-selection.md#step-2b-choose-the-set-yourself)
in full. Selection consumes `pick-issues.sh` output only: a body-free record carries status,
in full. Selection consumes `$agentkit/.shared/scripts/pick-issues.sh` output only: a body-free record carries status,
eligibility, blockers, dispatch/queue state, `predictedWriteSet`, `requirementsDigest`, `bodyCache`, and
`workShape`. `workShape: "no-code"` means HOLD before worktree creation; retain `holdReason`, count
`no-code-hold`, and use the anchored [work-shape verdict](references/triage-and-selection.md#work-shape-verdict)
for ambiguity.
`$agentkit/.shared/scripts/pick-issues.sh` answers only the mechanical half; the root applies Backlog ranking, Step 3 conflict analysis, the slot cap, and the batch board move in order. Emit `Selection funnel:`
exactly once after the final conflict and slot-cap decisions and before dispatch. Full, thin, and
empty sets report requested/eligible/dispatched plus one reason per exclusion.
An empty selection is an answer only with evidence. If `pick-issues.sh` is missing, non-executable, or fails,
report `Selection funnel: degraded=yes; eligible=unknown`, its exact path and failure reason.
The helper answers only the mechanical half; the root applies Backlog ranking, Step 3 conflict analysis, the slot cap, and the batch board move in order. Emit `Selection funnel:`
exactly once after the final conflict and slot-cap decisions and before dispatch. Every set reports
requested/eligible/dispatched plus one reason per exclusion.
An empty selection is an answer only with evidence. Report `Selection funnel: degraded=yes; eligible=unknown`
only with `ls -l "$agentkit/.shared/scripts/pick-issues.sh"` output and its failure text, never a guessed path.
Stop automatic selection until it succeeds. A triage fallback cannot justify `eligible=0` or an empty Ready column; any assessor fan-out still uses only the slots available under the spawn cap. Preserve partial evidence as degraded.

### Step 3: Conflict analysis (file-level)
Expand Down
4 changes: 2 additions & 2 deletions opencode/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion opencode/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@wrzonance/agentkit-opencode",
"version": "0.9.12",
"version": "0.9.13",
"description": "Agent Kit plugin for OpenCode CLI: injects the environment contract into the model's system prompt at session start.",
"type": "module",
"main": "./index.js",
Expand Down
2 changes: 1 addition & 1 deletion plugin/agentkit/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agentkit",
"version": "0.9.12",
"version": "0.9.13",
"description": "Board-aware parallel issue and PR review skills, with lifecycle hooks and a per-repository contract.",
"author": {
"name": "wrzonance",
Expand Down
2 changes: 1 addition & 1 deletion plugin/agentkit/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agentkit",
"version": "0.9.12",
"version": "0.9.13",
"description": "Board-aware parallel issue and PR review skills, with lifecycle hooks and a per-repository contract.",
"author": {
"name": "wrzonance",
Expand Down
2 changes: 1 addition & 1 deletion plugin/opencode/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@wrzonance/agentkit-opencode",
"version": "0.9.12",
"version": "0.9.13",
"description": "Agent Kit plugin for OpenCode CLI: injects the environment contract into the model's system prompt at session start.",
"type": "module",
"main": "./index.js",
Expand Down
35 changes: 32 additions & 3 deletions tests/lint-helper-refs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,25 @@ check_token() {
# Only shipped helper basenames belong to this rule: external URLs, repository
# scripts, and example commands are not kit interfaces. Keep occurrence order,
# including within a line, so a later path cannot conceal an earlier bare name.
#
# The same order holds inside every heading section: agents read SKILL.md by
# anchored section, and a section that spells a helper's path only after its
# bare name has already sent the reader guessing. #889: bare `pick-issues.sh`
# five lines ahead of its path was guessed under the skill's own scripts/ and
# the run stopped. That guess lands for the skill's own helpers, so only
# shared and cross-skill helpers hold the section order. A heading-shaped
# shell comment inside fenced code is not a section break.
scan_first_mentions() {
local source_file=$1 line_no content token name candidate
local -A mentioned=()
local source_file=$1 line_no content token name candidate in_fence=0 reported own_scripts
local -A mentioned=() section_bare=() section_path=()
own_scripts=$(skill_root_for "$source_file")/scripts
while IFS=: read -r line_no content; do
[[ $content =~ ^[[:space:]]*\`\`\` ]] && in_fence=$((1 - in_fence))
if ((in_fence == 0)) && [[ $content =~ ^#{1,6}[[:space:]] ]]; then
section_bare=() section_path=()
continue
fi
[[ $content == *.sh* ]] || continue
while IFS= read -r token; do
name=${token##*/}
[[ -n ${helper_paths[$name]:-} ]] || continue
Expand All @@ -107,14 +122,28 @@ scan_first_mentions() {
;;
*) candidate=$skills_dir/${helper_paths[$name]} ;;
esac
reported=0
if [[ -z ${mentioned[$name]:-} ]]; then
mentioned[$name]=1
if [[ $token != "\$agentkit/"* || ! -f $candidate ]]; then
reported=1
# shellcheck disable=SC2016 # diagnostic names the literal root
report "$source_file" "$line_no" "$token" \
"\$agentkit/${helper_paths[$name]}" 'first helper mention; use a $agentkit-relative path for'
fi
fi
if [[ $token != */* ]]; then
((reported)) || [[ -n ${section_path[$name]:-}${section_bare[$name]:-} ]] ||
[[ -f $own_scripts/$name ]] || section_bare[$name]=$line_no
elif [[ -f $candidate ]]; then
if [[ -n ${section_bare[$name]:-} ]]; then
# shellcheck disable=SC2016 # diagnostic names the literal root
report "$source_file" "${section_bare[$name]}" "$name" \
"\$agentkit/${helper_paths[$name]}" 'section-first helper mention; a later path in the same section cannot repair'
unset 'section_bare[$name]'
fi
section_path[$name]=1
fi
# lib/ means source-only unless an explicitly documented CLI exists.
# contract-cache is currently the sole dual-use library; executable
# permission alone does not establish an invocation interface.
Expand All @@ -124,7 +153,7 @@ scan_first_mentions() {
report "$source_file" "$line_no" "$token" 'source/sourced-only library label' 'library interface for'
fi
done < <(grep -oE '[[:alnum:]_.$/{}/:-]+\.sh' <<< "$content" || true)
done < <(grep -nE '\.sh' "$source_file" || true)
done < <(grep -n '' "$source_file" || true)
}

scan_file() {
Expand Down
3 changes: 2 additions & 1 deletion tests/lint-helper-size.sh
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ readonly MAX_HELPER_TOKENS=10000
# #873 evidence repair + #874/#875 merge: exact combined helper tree measurement.
# #873/#874 + #875 + #876 provider-alias repair: exact combined helper tree measurement.
# #873 PR repair: verification-scoped post-run cleanliness and setup compatibility.
readonly MAX_TREE_TOKENS=477429
# #889: triage --help ends with the selection helper's shipped path: exact tree measurement.
readonly MAX_TREE_TOKENS=477442

violations=0
checked=0
Expand Down
23 changes: 23 additions & 0 deletions tests/test-helper-refs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,29 @@ printf '%s\n' 'Source `$agentkit/.shared/scripts/lib/private-dir.sh` (sourced-on
> "$hfixture/demo/SKILL.md"
assert_rc 0 'source instructions and the documented contract-cache CLI remain valid' -- "$lint" "$hfixture"

# #889: a section that spelled the helper's path only after its bare name sent
# a root guessing under the skill's own scripts/ and stopped the run. Order
# holds per heading section for shared and cross-skill helpers (that guess
# lands for the skill's own), and a heading-shaped shell comment inside a
# fence is not a section break.
printf '%s\n' 'Run `$agentkit/.shared/scripts/pick-issues.sh` once.' \
'' '### Later step' 'Selection consumes `pick-issues.sh` output only.' \
'Then `$agentkit/.shared/scripts/pick-issues.sh` answers the rest.' > "$hfixture/demo/SKILL.md"
section_output=$("$lint" "$hfixture" 2>&1)
assert_eq 1 "$?" 'a later path in the same section does not repair a bare section-first mention'
assert_contains "$section_output" 'SKILL.md:4' \
'the section diagnostic names the bare line, not the later path'
printf '%s\n' 'Run `$agentkit/.shared/scripts/pick-issues.sh` once.' \
'```bash' '# Step: no guessing' 'pick-issues.sh --help' '```' \
'Then `$agentkit/.shared/scripts/pick-issues.sh` answers the rest.' > "$hfixture/demo/SKILL.md"
assert_rc 0 'a heading-shaped comment inside a fence does not start a section' -- "$lint" "$hfixture"
mkdir -p "$hfixture/demo/scripts"
touch "$hfixture/demo/scripts/own-helper.sh"
printf '%s\n' 'Run `$agentkit/demo/scripts/own-helper.sh` once.' \
'' '### Later step' 'Then `own-helper.sh` again before `$agentkit/demo/scripts/own-helper.sh`.' \
> "$hfixture/demo/SKILL.md"
assert_rc 0 'a helper shipped in the skill scripts/ directory may go bare before its path in a section' -- "$lint" "$hfixture"

assert_eq yes "$([[ $(wc -c < "$root/agentkit/skills/.shared/six-step-loop.md") -le 6100 ]] && printf yes || printf no)" \
'six-step-loop policy stays at or under 6100 bytes'

Expand Down
2 changes: 1 addition & 1 deletion tests/test-parallel-dispatch-contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ assert_contains "$text" 'Selection funnel:' \
assert_contains "$normalized_text" 'exactly once after the final conflict and slot-cap decisions and before dispatch' \
'selection reconciliation is emitted once at the dispatch boundary'
assert_contains "$normalized_text" \
'`$agentkit/.shared/scripts/pick-issues.sh` answers only the mechanical half; the root applies Backlog ranking, Step 3 conflict analysis, the slot cap, and the batch board move in order' \
'The helper answers only the mechanical half; the root applies Backlog ranking, Step 3 conflict analysis, the slot cap, and the batch board move in order' \
'selection keeps judgment and board mutation root-owned'
assert_contains "$triage_and_selection_text" \
'Selection funnel: requested=3 eligible=3 dispatched=3 exclusions=none' \
Expand Down
Loading