@iceinvein/agent-skills 0.5.1 → 0.6.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/package.json +1 -1
- package/skills/index.json +1 -1
- package/skills/sluice/SKILL.md +30 -14
- package/skills/sluice/references/deep-channel.md +17 -7
- package/skills/sluice/references/meter.md +14 -2
- package/skills/sluice/references/review.md +14 -9
- package/skills/sluice/scripts/run-stats.sh +103 -29
- package/skills/sluice/skill.json +1 -1
package/package.json
CHANGED
package/skills/index.json
CHANGED
|
@@ -283,7 +283,7 @@
|
|
|
283
283
|
"name": "sluice",
|
|
284
284
|
"description": "Routes work by change shape into four channels (bypass, fast, main, deep) and applies only the rules each channel needs, so a one-line fix does not pay the cost of a multi-subsystem build. Carries seven rules as one-liners in the router and the full treatment in references read only on friction, and closes each run with a ledger read out of the session transcript: elapsed, tools, tokens, and what every dispatched agent cost. Claude Code only; conflicts with the superpowers plugin.",
|
|
285
285
|
"type": "prompt",
|
|
286
|
-
"version": "0.
|
|
286
|
+
"version": "0.3.0"
|
|
287
287
|
},
|
|
288
288
|
{
|
|
289
289
|
"name": "temporal-coupling-detector",
|
package/skills/sluice/SKILL.md
CHANGED
|
@@ -20,10 +20,13 @@ announcement is how your partner redirects you without being asked.
|
|
|
20
20
|
| `main` | Adds an interface, or crosses subsystems | + agree intent, review before merge | "Main channel, new interface. Agreeing the shape first." |
|
|
21
21
|
| `deep` | Several subsystems, or a plan was asked for | + written design and plan | "Deep channel, several subsystems. Design before code." |
|
|
22
22
|
|
|
23
|
+
Two subsystems is `main`; the third is what makes it `deep`.
|
|
24
|
+
|
|
23
25
|
`bypass`, `fast`, and `main` proceed without stopping for approval; only
|
|
24
|
-
`deep` stops
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
`deep` stops: once for design sign-off before code, once for the plan and
|
|
27
|
+
pre-flight together before Task 1. A stop ends your turn. Asking a question
|
|
28
|
+
with a tool is not one, however many options it carried: the answer comes
|
|
29
|
+
back to you and the run never left your hands.
|
|
27
30
|
|
|
28
31
|
Name the channel and the signal that actually routed you there. The strings above
|
|
29
32
|
are examples, not fixed copy, and a channel with a two-part signal should say
|
|
@@ -36,6 +39,9 @@ account for. An integration event, merging, pushing, or opening a PR, triggers
|
|
|
36
39
|
the second. Handing the work back triggers the third, whether or not it ever
|
|
37
40
|
reaches an integration event. The first two fire in every channel, `bypass`
|
|
38
41
|
included; `meter` cannot, because `bypass` announces nothing to measure from.
|
|
42
|
+
A question that turns on how something looks is triggered the same way and in
|
|
43
|
+
any channel: `references/show-or-say.md` decides whether to show it or say it,
|
|
44
|
+
and `bypass` is where it comes up most.
|
|
39
45
|
|
|
40
46
|
## The rules
|
|
41
47
|
|
|
@@ -79,18 +85,23 @@ Design to `docs/specs/YYYY-MM-DD-<topic>.md`, plan to
|
|
|
79
85
|
`docs/plans/YYYY-MM-DD-<topic>.md`, unless the repo has a convention or
|
|
80
86
|
your partner states a preference. Get the design signed off before code.
|
|
81
87
|
|
|
82
|
-
The plan
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
The plan gets a stop of its own, whoever executes it. Dispatched agents each
|
|
89
|
+
see only their own task, so nobody reads it whole; executing it yourself is
|
|
90
|
+
the weaker case rather than the exempt one, because then nobody reads it but
|
|
91
|
+
its author.
|
|
85
92
|
|
|
86
93
|
Order the plan so the tasks that change nothing come first, and mark the one
|
|
87
94
|
task that turns the new behaviour on. Then a late re-baseline, re-blessed
|
|
88
95
|
snapshots, regenerated fixtures, attributes to that one point instead of to
|
|
89
96
|
the branch at large.
|
|
90
97
|
|
|
91
|
-
|
|
92
|
-
whether the work runs in a worktree. Ask
|
|
93
|
-
|
|
98
|
+
Pre-flight rides in the plan's stop: which flagged tasks get a reviewer, and
|
|
99
|
+
whether the work runs in a worktree. Ask them as choices with the counts in
|
|
100
|
+
them, never as a paragraph, then end the turn on the answers rather than
|
|
101
|
+
opening Task 1 with them. A session that dispatches only when asked has not
|
|
102
|
+
ruled dispatch out, it has made this question the place to ask. Genuine
|
|
103
|
+
unavailability is the tool not being there at all, which is a different case
|
|
104
|
+
and a different paragraph. Review that turns out to be missing is only
|
|
94
105
|
actionable while the plan can still change.
|
|
95
106
|
|
|
96
107
|
Read the plan as a graph rather than a list. `Needs` and `Offers` are
|
|
@@ -98,7 +109,7 @@ dependency edges and `Touches` says what cannot overlap, so which tasks may
|
|
|
98
109
|
run at once is derivable rather than guessed. Fan out wherever that graph
|
|
99
110
|
allows; serial is the fallback for where it doesn't, not the default.
|
|
100
111
|
|
|
101
|
-
Then read `references/deep-channel.md` for the plan format, that
|
|
112
|
+
Then read `references/deep-channel.md` for the plan format, that stop,
|
|
102
113
|
the dispatch rules, and when a task actually needs a reviewer. Three that
|
|
103
114
|
catch people out: concurrent implementers need a worktree each and the flip
|
|
104
115
|
runs alone, review is tiered rather than automatic, and a `deep` run that
|
|
@@ -107,7 +118,12 @@ ship without one.
|
|
|
107
118
|
|
|
108
119
|
## Conflicts
|
|
109
120
|
|
|
110
|
-
Sluice cannot run alongside the superpowers
|
|
111
|
-
own fixed
|
|
112
|
-
software does, not just code edits, and that
|
|
113
|
-
outright
|
|
121
|
+
Sluice cannot run alongside the superpowers pipeline. Superpowers requires its
|
|
122
|
+
own fixed sequence up front for anything that adds to or changes what the
|
|
123
|
+
software does, not just code edits, and that sequence overrides this router
|
|
124
|
+
outright.
|
|
125
|
+
|
|
126
|
+
The test is whether that pipeline governs the work in front of you, not whether
|
|
127
|
+
a plugin is installed. A repo whose own instructions mandate the sequence rules
|
|
128
|
+
this router out exactly as the plugin does, with the plugin disabled or absent.
|
|
129
|
+
Stand down and say so once, in the same breath you would have named a channel.
|
|
@@ -60,11 +60,20 @@ Split it. A plan with none is not a `deep` plan: nothing in it does anything.
|
|
|
60
60
|
|
|
61
61
|
## Pre-flight
|
|
62
62
|
|
|
63
|
-
Design signed off, plan written, nothing built yet. Before Task 1,
|
|
64
|
-
and settle two things with your partner. Ask them as questions with
|
|
65
|
-
not as a paragraph they have to reply to in prose: what you are after
|
|
66
|
-
decision, and a wall of considerations asks them to extract the decision
|
|
67
|
-
it first.
|
|
63
|
+
Design signed off, plan written, nothing built yet. Before Task 1, hand back
|
|
64
|
+
once and settle two things with your partner. Ask them as questions with
|
|
65
|
+
options, not as a paragraph they have to reply to in prose: what you are after
|
|
66
|
+
is a decision, and a wall of considerations asks them to extract the decision
|
|
67
|
+
from it first.
|
|
68
|
+
|
|
69
|
+
This handback is the plan's sign-off as well, so it ends your turn, and a
|
|
70
|
+
question tool does not end it for you. That tool returns an answer without
|
|
71
|
+
returning control: two options came back, the plan itself did not, and your
|
|
72
|
+
partner reads the summary of it in the same message as Task 1's first edit,
|
|
73
|
+
by which point their only remaining move is to interrupt. Ask the questions,
|
|
74
|
+
then end the turn on the answers and let the next instruction start the
|
|
75
|
+
build. If the answers arrive with that instruction already attached, you have
|
|
76
|
+
your sign-off and Task 1 begins.
|
|
68
77
|
|
|
69
78
|
**Review.** Name the tasks the table below sends to a reviewer, each with the
|
|
70
79
|
trigger that qualified it, and say how many of the rest skip with a ledger
|
|
@@ -159,8 +168,9 @@ unavailable, where there is nothing to ask.
|
|
|
159
168
|
say so is the routing announcement, where your partner can still act on it,
|
|
160
169
|
not the summary at the end where it reads as an excuse.
|
|
161
170
|
|
|
162
|
-
Three things change. The plan
|
|
163
|
-
|
|
171
|
+
Three things change. The plan stops being a brief for strangers and becomes
|
|
172
|
+
your own worklist, which makes its handback the only outside read it will ever
|
|
173
|
+
get rather than a formality on the way to dispatch. Task isolation is gone, so
|
|
164
174
|
`TaskCreate` now carries all of the state that outlives compaction and matters
|
|
165
175
|
more, not less. And fresh context is unavailable, which was the entire thing
|
|
166
176
|
review was buying.
|
|
@@ -33,12 +33,24 @@ chain and a finding for one whose graph was not, so read it against the plan
|
|
|
33
33
|
rather than on its own. Nine agents at 1.0× on a plan with four independent
|
|
34
34
|
tasks in it is a run that took four times longer than it needed to.
|
|
35
35
|
|
|
36
|
+
An agent dispatched into the background is handed back before it runs, so the
|
|
37
|
+
result the session sees carries no cost at all. The ledger reads that agent's
|
|
38
|
+
own transcript instead, which is why a plan run entirely on dispatched agents
|
|
39
|
+
still prices. Agent rows count output tokens, the same unit the run reports for
|
|
40
|
+
itself, so they can be read against each other and against the run.
|
|
41
|
+
|
|
42
|
+
Where that log has been cleaned up the row reads "cost not reported", the
|
|
43
|
+
totals leave it out, and the agent line carries the count. That is a gap in
|
|
44
|
+
what could be measured rather than a cheap run, and it needs a sentence from
|
|
45
|
+
you: a smaller total must not be allowed to stand for the whole.
|
|
46
|
+
|
|
36
47
|
Read it before you paste it. A row showing an agent that errored, or an agent
|
|
37
48
|
whose token count dwarfs every other row, is a finding about the run and
|
|
38
49
|
belongs in your prose, not left for your partner to spot in a table.
|
|
39
50
|
|
|
40
|
-
Exit 2 means
|
|
41
|
-
|
|
51
|
+
Exit 2 means neither an announcement nor an invocation of this skill was found,
|
|
52
|
+
so there was no run to report. That is a fact about the work, not a failure: do
|
|
53
|
+
not synthesise a ledger to fill the gap.
|
|
42
54
|
|
|
43
55
|
The friction line: "I know roughly what this cost." Roughly is the problem.
|
|
44
56
|
Every number here is already on disk, and the remembered version is reliably
|
|
@@ -47,18 +47,23 @@ reviews, and it spends context the plan still needs.
|
|
|
47
47
|
|
|
48
48
|
## When you cannot dispatch
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
Separate the two cases before you say anything. A session that grants subagents
|
|
51
|
+
only on request has not withheld them: asking is the whole procedure, and a
|
|
52
|
+
claim that you cannot dispatch is false there. A session that withholds them
|
|
53
|
+
outright is the one this section is about. The review is owed either way.
|
|
54
|
+
`deep` has its own treatment in `references/deep-channel.md`, where there is a
|
|
55
|
+
plan to shrink and a tier table to argue from; this is the `main` case, which
|
|
56
|
+
has neither.
|
|
54
57
|
|
|
55
58
|
Say it twice, and only twice.
|
|
56
59
|
|
|
57
|
-
The first time is the routing announcement, in the same breath as the channel
|
|
58
|
-
"Main channel, new interface. I cannot dispatch a reviewer in this
|
|
59
|
-
this merges unreviewed unless you want one."
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
The first time is the routing announcement, in the same breath as the channel.
|
|
61
|
+
Withheld: "Main channel, new interface. I cannot dispatch a reviewer in this
|
|
62
|
+
session, so this merges unreviewed unless you want one." On request: "Main
|
|
63
|
+
channel, new interface. A reviewer is one dispatch away if you want one, and
|
|
64
|
+
without it this merges unreviewed." Either way, that is the moment it is still
|
|
65
|
+
a decision. Your partner can authorise the dispatch, split the change, or
|
|
66
|
+
accept the gap knowingly. The same words at the end are a disclaimer.
|
|
62
67
|
|
|
63
68
|
The second is the integration event, where `references/finish.md` puts the
|
|
64
69
|
three options. Review status belongs beside them, because it is part of what
|
|
@@ -46,7 +46,32 @@ if [ -z "$TRANSCRIPT" ] || [ ! -f "$TRANSCRIPT" ]; then
|
|
|
46
46
|
exit 1
|
|
47
47
|
fi
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
# An agent handed back before it ran leaves no cost on its tool result, but it
|
|
50
|
+
# keeps a transcript of its own beside the session. That file is the only place
|
|
51
|
+
# a backgrounded agent's cost is ever written down, so read it rather than
|
|
52
|
+
# reporting the work as free.
|
|
53
|
+
SUBS="$(dirname "$TRANSCRIPT")/$(basename "$TRANSCRIPT" .jsonl)/subagents"
|
|
54
|
+
COSTS='{}'
|
|
55
|
+
if [ -d "$SUBS" ]; then
|
|
56
|
+
COSTS="$(
|
|
57
|
+
for f in "$SUBS"/agent-*.jsonl; do
|
|
58
|
+
[ -e "$f" ] || continue
|
|
59
|
+
id="$(basename "$f" .jsonl)"; id="${id#agent-}"
|
|
60
|
+
jq -s --arg id "$id" '
|
|
61
|
+
def ts: sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601;
|
|
62
|
+
[ .[] | select(.timestamp) ] as $t
|
|
63
|
+
| { ($id): {
|
|
64
|
+
tokens: ([ .[] | .message.usage.output_tokens // 0 ] | add // 0),
|
|
65
|
+
tools: ([ .[] | .message.content[]? | select(.type == "tool_use") ] | length),
|
|
66
|
+
model: ([ .[] | .message.model // empty ] | last // "?"),
|
|
67
|
+
starts: (if ($t | length) > 0 then ($t[0].timestamp | ts) else 0 end),
|
|
68
|
+
ends: (if ($t | length) > 0 then ($t[-1].timestamp | ts) else 0 end) } }' "$f"
|
|
69
|
+
done | jq -s 'add // {}'
|
|
70
|
+
)"
|
|
71
|
+
fi
|
|
72
|
+
[ -n "$COSTS" ] || COSTS='{}'
|
|
73
|
+
|
|
74
|
+
SUMMARY="$(jq -s --argjson costs "$COSTS" '
|
|
50
75
|
# ---- what counts as a real turn ----------------------------------------
|
|
51
76
|
# Transcript stamps carry milliseconds, which fromdateiso8601 will not take.
|
|
52
77
|
def ts: sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601;
|
|
@@ -56,9 +81,20 @@ SUMMARY="$(jq -s '
|
|
|
56
81
|
# opens the message. Anchoring there is what separates it from prose that
|
|
57
82
|
# merely discusses a channel, which a session about sluice is full of.
|
|
58
83
|
def marker: "^[*_#>[:space:]]*(?<c>fast|main|deep)[[:space:]]+channel";
|
|
84
|
+
# Real announcements carry a lead-in the anchor above misses: "Sluice: **deep
|
|
85
|
+
# channel**", "Tier 2 (new contract surface) = **deep channel**". Emphasis is
|
|
86
|
+
# what still separates one from prose naming a channel, and holding it to the
|
|
87
|
+
# opening line keeps a session reviewing sluice from starting a run per quote.
|
|
88
|
+
def emph: "\\*\\*[[:space:]]*(?<c>fast|main|deep)[[:space:]]+channel";
|
|
89
|
+
def head_line: texts | split("\n") | (.[0] // "");
|
|
59
90
|
def announces: (.type == "assistant") and (is_meta | not)
|
|
60
|
-
and (texts | test(marker; "i"));
|
|
61
|
-
def chan: texts |
|
|
91
|
+
and ((texts | test(marker; "i")) or (head_line | test(emph; "i")));
|
|
92
|
+
def chan: (if (texts | test(marker; "i")) then (texts | capture(marker; "i"))
|
|
93
|
+
else (head_line | capture(emph; "i")) end) | .c | ascii_downcase;
|
|
94
|
+
def invokes_sluice: (.type == "assistant") and (is_meta | not) and ([
|
|
95
|
+
.message.content[]? | select(.type == "tool_use" and .name == "Skill")
|
|
96
|
+
| select((.input.skill // "") == "sluice")
|
|
97
|
+
] | length > 0);
|
|
62
98
|
def is_stats_call: (.type == "assistant") and ([
|
|
63
99
|
.message.content[]? | select(.type == "tool_use" and .name == "Bash")
|
|
64
100
|
| select((.input.command // "") | test("run-stats\\.sh"))
|
|
@@ -74,7 +110,11 @@ SUMMARY="$(jq -s '
|
|
|
74
110
|
|
|
75
111
|
. as $all
|
|
76
112
|
| [ range(0; $all | length) ] as $ix
|
|
77
|
-
| [ $ix[] | select($all[.] | announces) ] as $
|
|
113
|
+
| [ $ix[] | select($all[.] | announces) ] as $said
|
|
114
|
+
# A run whose announcement never matched is still a run when the skill was
|
|
115
|
+
# invoked by name. Anchoring there beats reporting the work as nothing.
|
|
116
|
+
| [ $ix[] | select($all[.] | invokes_sluice) ] as $called
|
|
117
|
+
| (if ($said | length) > 0 then $said else $called end) as $ann
|
|
78
118
|
| if ($ann | length) == 0 then { empty: true } else
|
|
79
119
|
|
|
80
120
|
# A previous ledger closes the run before it. The call running right now has
|
|
@@ -87,7 +127,7 @@ SUMMARY="$(jq -s '
|
|
|
87
127
|
| [ $all[$from:][] | select(.timestamp) ] as $run
|
|
88
128
|
|
|
89
129
|
# ---- channel, and the trail if it escalated ----------------------------
|
|
90
|
-
| ([ $
|
|
130
|
+
| ([ $said[] | select(. >= $from) | $all[.] | chan ]
|
|
91
131
|
| reduce .[] as $c ([]; if (. | last) == $c then . else . + [$c] end)) as $trail
|
|
92
132
|
|
|
93
133
|
# ---- clocks ------------------------------------------------------------
|
|
@@ -114,20 +154,39 @@ SUMMARY="$(jq -s '
|
|
|
114
154
|
| from_entries) as $labels
|
|
115
155
|
# toolUseResult is whatever the tool returned: object, array or string.
|
|
116
156
|
| [ $run[] | select((.toolUseResult | type) == "object") | select(.toolUseResult.agentId)
|
|
117
|
-
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
157
|
+
| . as $e
|
|
158
|
+
# Inline cost when the agent ran to completion here, its own transcript
|
|
159
|
+
# when it was handed back before it ran, and neither only when the file
|
|
160
|
+
# has been cleaned up. Priced at zero it would understate the run and drag
|
|
161
|
+
# the concurrency factor to a number the ledger has no meaning for.
|
|
162
|
+
| ($costs[$e.toolUseResult.agentId] // null) as $c
|
|
163
|
+
# The log wins where there is one. The two sources count different things,
|
|
164
|
+
# the inline total being the harness accounting and the log being output
|
|
165
|
+
# tokens, and rows drawn from different bases cannot be read against each
|
|
166
|
+
# other. Output tokens is also the unit the run reports for itself.
|
|
167
|
+
| (if $c == null then $e.toolUseResult.totalDurationMs
|
|
168
|
+
else (($c.ends - $c.starts) * 1000) end) as $ms
|
|
169
|
+
| ($c.tokens // $e.toolUseResult.totalTokens) as $tokens
|
|
170
|
+
| { label: ($labels[[ $e.message.content[]? | select(.type == "tool_result") | .tool_use_id ][0]]
|
|
171
|
+
// $e.toolUseResult.commandName // "agent"),
|
|
172
|
+
model: ($c.model // $e.toolUseResult.resolvedModel // "?"),
|
|
173
|
+
status: ($e.toolUseResult.status // "?"),
|
|
174
|
+
measured: (($ms != null) or ($tokens != null)),
|
|
175
|
+
tokens: ($tokens // 0),
|
|
176
|
+
ms: ($ms // 0),
|
|
177
|
+
# The session transcript timestamps when an agent returned, not when
|
|
178
|
+
# it began, so that start is back-derived from its own duration. An
|
|
179
|
+
# agent log of its own carries both ends directly.
|
|
180
|
+
ends: (if $c != null then $c.ends else ($e.timestamp | ts) end),
|
|
181
|
+
starts: (if $c != null then $c.starts
|
|
182
|
+
else (($e.timestamp | ts) - (($ms // 0) / 1000)) end),
|
|
183
|
+
tools: ($c.tools // $e.toolUseResult.totalToolUseCount // 0) } ] as $agents
|
|
184
|
+
|
|
185
|
+
| [ $agents[] | select(.measured) ] as $priced
|
|
127
186
|
|
|
128
187
|
# Union of the agent intervals: sum the merged runs rather than the raw ones,
|
|
129
188
|
# so overlapping agents are counted once against the clock they shared.
|
|
130
|
-
| ([ $
|
|
189
|
+
| ([ $priced[] | { s: .starts, e: .ends } ] | sort_by(.s)
|
|
131
190
|
| reduce .[] as $i ([];
|
|
132
191
|
if (length == 0) or (.[-1].e < $i.s)
|
|
133
192
|
then . + [$i]
|
|
@@ -135,17 +194,18 @@ SUMMARY="$(jq -s '
|
|
|
135
194
|
| map(.e - .s) | add // 0) as $agent_span
|
|
136
195
|
|
|
137
196
|
| { empty: false,
|
|
138
|
-
trail: ($trail | join(" → ")),
|
|
197
|
+
trail: (if ($trail | length) == 0 then "not announced" else ($trail | join(" → ")) end),
|
|
139
198
|
elapsed: $elapsed, waiting: $waiting,
|
|
140
199
|
tool_total: ($tools | length),
|
|
141
200
|
tool_top: ([ $tools | group_by(.)[] | { n: length, name: (.[0] | ascii_downcase | split("__") | last) } ]
|
|
142
201
|
| sort_by(-.n) | .[0:3]),
|
|
143
202
|
out_tok: $out_tok, cache_tok: $cache_tok,
|
|
144
203
|
agents: $agents,
|
|
145
|
-
|
|
146
|
-
|
|
204
|
+
unmeasured: (($agents | length) - ($priced | length)),
|
|
205
|
+
agent_tokens: ([ $priced[].tokens ] | add // 0),
|
|
206
|
+
agent_ms: ([ $priced[].ms ] | add // 0),
|
|
147
207
|
concurrency: (if $agent_span > 0
|
|
148
|
-
then (([ $
|
|
208
|
+
then (([ $priced[].ms ] | add // 0) / 1000) / $agent_span
|
|
149
209
|
else 0 end) }
|
|
150
210
|
end
|
|
151
211
|
' "$TRANSCRIPT" 2>/dev/null)"
|
|
@@ -229,24 +289,38 @@ if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
|
229
289
|
fi
|
|
230
290
|
|
|
231
291
|
count=$(g '.agents | length')
|
|
292
|
+
unmeasured=$(g '.unmeasured')
|
|
232
293
|
if [ "$count" -eq 0 ]; then
|
|
233
294
|
printf 'agents none dispatched\n'
|
|
234
295
|
else
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
296
|
+
if [ "$count" -eq "$unmeasured" ]; then
|
|
297
|
+
# Every agent was handed back before it ran, so there is no cost to report
|
|
298
|
+
# and none to invent. Saying so beats a row of zeroes that reads as a total.
|
|
299
|
+
printf 'agents %s dispatched · cost not reported\n' "$count"
|
|
300
|
+
else
|
|
301
|
+
# 1.0× means every agent had the clock to itself. On a plan whose graph had
|
|
302
|
+
# independent tasks in it, that number is the finding.
|
|
303
|
+
printf 'agents %s dispatched · %s tok · %s wall · %s× concurrent' \
|
|
304
|
+
"$count" "$(tok "$(g '.agent_tokens')")" "$(dur "$(( $(g '.agent_ms') / 1000 ))")" \
|
|
305
|
+
"$(printf '%.1f' "$(g '.concurrency')")"
|
|
306
|
+
[ "$unmeasured" -gt 0 ] && printf ' · %s unmeasured' "$unmeasured"
|
|
307
|
+
printf '\n'
|
|
308
|
+
fi
|
|
240
309
|
|
|
241
310
|
# Up to a dozen rows read as the narrative of the plan. Past that the order
|
|
242
311
|
# stops helping, so show what the run actually spent on and say what is cut.
|
|
243
312
|
if [ "$count" -le 12 ]; then rows='.agents[]'; else rows='(.agents | sort_by(-.tokens) | .[0:10][])'; fi
|
|
244
|
-
while IFS=$'\t' read -r label model status tokens ms tools; do
|
|
313
|
+
while IFS=$'\t' read -r label model status tokens ms tools measured; do
|
|
245
314
|
model="${model#claude-}"; model="$(sed 's/-[0-9]\{8\}$//' <<<"$model")"
|
|
246
315
|
[ "$status" = "completed" ] && status="" || status=" ($status)"
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
316
|
+
if [ "$measured" = "true" ]; then
|
|
317
|
+
printf ' %-22.22s %-10s %6s %7s %s tools%s\n' \
|
|
318
|
+
"$label" "$model" "$(tok "$tokens")" "$(dur "$((ms / 1000))")" "$tools" "$status"
|
|
319
|
+
else
|
|
320
|
+
printf ' %-22.22s %-10s %6s %7s %s%s\n' \
|
|
321
|
+
"$label" "$model" "-" "-" "cost not reported" "$status"
|
|
322
|
+
fi
|
|
323
|
+
done < <(g "$rows | [.label, .model, .status, .tokens, .ms, .tools, .measured] | @tsv")
|
|
250
324
|
|
|
251
325
|
if [ "$count" -gt 12 ]; then
|
|
252
326
|
printf ' +%s more · %s tok (dearest 10 shown)\n' \
|
package/skills/sluice/skill.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sluice",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Routes work by change shape into four channels (bypass, fast, main, deep) and applies only the rules each channel needs, so a one-line fix does not pay the cost of a multi-subsystem build. Carries seven rules as one-liners in the router and the full treatment in references read only on friction, and closes each run with a ledger read out of the session transcript: elapsed, tools, tokens, and what every dispatched agent cost. Claude Code only; conflicts with the superpowers plugin.",
|
|
5
5
|
"author": "iceinvein",
|
|
6
6
|
"type": "prompt",
|