omniconductor 0.3.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/CHANGELOG.md +64 -0
- package/LICENSE +219 -0
- package/NOTICE +11 -0
- package/README.md +526 -0
- package/THIRD_PARTY_NOTICES.md +31 -0
- package/TRADEMARKS.md +26 -0
- package/VISION.md +106 -0
- package/adapters/README.md +121 -0
- package/adapters/claude/README.md +102 -0
- package/adapters/claude/SUPPORTED-FEATURES.md +66 -0
- package/adapters/claude/hookify-templates/.recipe-scoped +9 -0
- package/adapters/claude/hookify-templates/README.md +93 -0
- package/adapters/claude/hookify-templates/block-completion-claim-without-push.local.md.template +56 -0
- package/adapters/claude/hookify-templates/block-direct-push-protected-branch.local.md.template +18 -0
- package/adapters/claude/hookify-templates/block-force-push-protected-branch.local.md.template +42 -0
- package/adapters/claude/hookify-templates/block-server-secret-in-client.local.md.template +36 -0
- package/adapters/claude/hookify-templates/warn-any-type-added.local.md.template +44 -0
- package/adapters/claude/hookify-templates/warn-commit-without-pre-commit-review.local.md.template +52 -0
- package/adapters/claude/hookify-templates/warn-console-direct.local.md.template +55 -0
- package/adapters/claude/hookify-templates/warn-create-table-without-access-control.local.md.template +35 -0
- package/adapters/claude/hookify-templates/warn-current-work-without-remaining-tasks.local.md.template +36 -0
- package/adapters/claude/hookify-templates/warn-gh-pr-create-without-pre-merge-review.local.md.template +38 -0
- package/adapters/claude/hookify-templates/warn-hardcoded-text-without-i18n-key.local.md.template +21 -0
- package/adapters/claude/hookify-templates/warn-on-gh-pr-merge.local.md.template +33 -0
- package/adapters/claude/hookify-templates/warn-plan-spec-without-remaining-tasks.local.md.template +44 -0
- package/adapters/claude/hookify-templates/warn-raw-hex-instead-of-token.local.md.template +21 -0
- package/adapters/claude/hookify-templates/warn-security-definer-without-search-path.local.md.template +30 -0
- package/adapters/claude/hookify-templates/warn-stop-commit-without-current-work.local.md.template +47 -0
- package/adapters/claude/hookify-templates/warn-user-manual-completion.local.md.template +40 -0
- package/adapters/claude/transform-spec.md +140 -0
- package/adapters/claude/transform.sh +1169 -0
- package/adapters/codex/README.md +87 -0
- package/adapters/codex/SUPPORTED-FEATURES.md +66 -0
- package/adapters/codex/transform-spec.md +90 -0
- package/adapters/codex/transform.sh +748 -0
- package/adapters/copilot/README.md +88 -0
- package/adapters/copilot/SUPPORTED-FEATURES.md +73 -0
- package/adapters/copilot/transform-spec.md +111 -0
- package/adapters/copilot/transform.sh +757 -0
- package/adapters/cursor/README.md +87 -0
- package/adapters/cursor/SUPPORTED-FEATURES.md +90 -0
- package/adapters/cursor/transform-spec.md +124 -0
- package/adapters/cursor/transform.sh +731 -0
- package/adapters/gemini/README.md +93 -0
- package/adapters/gemini/SUPPORTED-FEATURES.md +80 -0
- package/adapters/gemini/transform-spec.md +102 -0
- package/adapters/gemini/transform.sh +844 -0
- package/adapters/windsurf/README.md +93 -0
- package/adapters/windsurf/SUPPORTED-FEATURES.md +67 -0
- package/adapters/windsurf/transform-spec.md +99 -0
- package/adapters/windsurf/transform.sh +727 -0
- package/bin/omniconductor.js +130 -0
- package/core/README.md +64 -0
- package/core/anti-patterns/README.md +142 -0
- package/core/anti-patterns/dynamic-system-prompt.md +113 -0
- package/core/anti-patterns/frequent-rule-file-edit.md +83 -0
- package/core/anti-patterns/large-file-read-no-range.md +90 -0
- package/core/anti-patterns/no-sub-agent-dispatch.md +89 -0
- package/core/anti-patterns/single-monolithic-rule-file.md +99 -0
- package/core/anti-patterns/skill-eager-load.md +83 -0
- package/core/anti-patterns/tool-call-spam.md +93 -0
- package/core/docs-templates/CURRENT_WORK.md +64 -0
- package/core/docs-templates/INDEX.md +57 -0
- package/core/docs-templates/PLANS.md +44 -0
- package/core/docs-templates/README.md +40 -0
- package/core/docs-templates/REMAINING_TASKS.md +43 -0
- package/core/docs-templates/TASKS.md +51 -0
- package/core/docs-templates/specs/_example.md +121 -0
- package/core/hooks/README.md +62 -0
- package/core/hooks/pretool-agent-routing.sh.template +97 -0
- package/core/hooks/pretool-commit-current-work-check.sh.template +103 -0
- package/core/hooks/pretool-commit-test-coverage-check.sh.template +116 -0
- package/core/hooks/pretool-large-file-read-guard.sh.template +117 -0
- package/core/hooks/stop-cache-hit-baseline-check.sh.template +133 -0
- package/core/hooks/stop-r6-review-check.sh.template +80 -0
- package/core/hooks/stop-session-log-check.sh.template +101 -0
- package/core/hooks/stop-trajectory-log.sh.template +96 -0
- package/core/memory-pattern/EXAMPLES.md +114 -0
- package/core/memory-pattern/README.md +133 -0
- package/core/recipes/README.md +46 -0
- package/core/recipes/auto-mock-data.md +82 -0
- package/core/recipes/branch-strategy.md +100 -0
- package/core/recipes/coding-conventions.md +123 -0
- package/core/recipes/database-discipline.md +65 -0
- package/core/recipes/debugging.md +143 -0
- package/core/recipes/design-system.md +30 -0
- package/core/recipes/i18n.md +118 -0
- package/core/recipes/monorepo.md +101 -0
- package/core/recipes/self-improvement.md +61 -0
- package/core/recipes/tdd.md +128 -0
- package/core/recipes/web-mobile-parity.md +87 -0
- package/core/reflector/SCHEDULING.md +83 -0
- package/core/reflector/prune-lessons.sh +105 -0
- package/core/reflector/reflect-brief.md +11 -0
- package/core/reflector/reflect.command.md +13 -0
- package/core/reflector/run-weekly.sh +54 -0
- package/core/reflector/trajectory-log.sh +55 -0
- package/core/roles/README.md +61 -0
- package/core/roles/builder.md +75 -0
- package/core/roles/designer.md +93 -0
- package/core/roles/helper.md +70 -0
- package/core/roles/planner.md +123 -0
- package/core/roles/reflector.md +72 -0
- package/core/roles/reviewer.md +104 -0
- package/core/roles/scribe.md +89 -0
- package/core/universal-rules/README.md +71 -0
- package/core/universal-rules/meta-discipline.md +292 -0
- package/core/universal-rules/operations.md +162 -0
- package/core/universal-rules/quality-gates.md +191 -0
- package/core/universal-rules/spec-as-you-go.md +123 -0
- package/core/universal-rules/workflow.md +153 -0
- package/core/workflow/PHASES.md +134 -0
- package/core/workflow/README.md +56 -0
- package/docs/MANUAL-INSTALL.md +456 -0
- package/package.json +52 -0
- package/tools/check-framework-purity.sh +91 -0
- package/tools/measure-tokens.sh +169 -0
- package/tools/validate-adapter-output.sh +611 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# CONDUCTOR — Token measurement tool (Claude Code adapter)
|
|
4
|
+
#
|
|
5
|
+
# Reads Claude Code session JSONL files and produces a per-session token usage
|
|
6
|
+
# summary. Useful for KPI baseline measurement (cache hit rate, input tokens,
|
|
7
|
+
# tool calls per task).
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# tools/measure-tokens.sh [--latest | --session=<path>] [--export-csv=<path>]
|
|
11
|
+
#
|
|
12
|
+
# Examples:
|
|
13
|
+
# tools/measure-tokens.sh --latest
|
|
14
|
+
# tools/measure-tokens.sh --session=~/.claude/projects/-foo-bar/abc.jsonl
|
|
15
|
+
# tools/measure-tokens.sh --latest --export-csv=/tmp/conductor-stats.csv
|
|
16
|
+
#
|
|
17
|
+
# Requirements:
|
|
18
|
+
# - Claude Code installed (sessions live under ~/.claude/projects/<encoded>/*.jsonl)
|
|
19
|
+
# - python3 (standard on macOS / Linux)
|
|
20
|
+
#
|
|
21
|
+
# Output:
|
|
22
|
+
# - Total input tokens / output tokens / tool calls / dispatches
|
|
23
|
+
# - Cache hit rate (cache_read / (cache_read + uncached_input))
|
|
24
|
+
# - Top 5 most expensive turns by output tokens
|
|
25
|
+
# - Optional CSV export
|
|
26
|
+
|
|
27
|
+
set -eu
|
|
28
|
+
|
|
29
|
+
LATEST="false"
|
|
30
|
+
SESSION_PATH=""
|
|
31
|
+
EXPORT_CSV=""
|
|
32
|
+
|
|
33
|
+
while [ $# -gt 0 ]; do
|
|
34
|
+
case "$1" in
|
|
35
|
+
--latest) LATEST="true" ;;
|
|
36
|
+
--session=*) SESSION_PATH="${1#--session=}" ;;
|
|
37
|
+
--export-csv=*) EXPORT_CSV="${1#--export-csv=}" ;;
|
|
38
|
+
--help|-h)
|
|
39
|
+
/bin/cat <<EOF
|
|
40
|
+
Usage: tools/measure-tokens.sh [--latest | --session=<path>] [--export-csv=<path>]
|
|
41
|
+
|
|
42
|
+
Reports input/output tokens, cache hit rate, and tool-call counts from a Claude Code session JSONL.
|
|
43
|
+
|
|
44
|
+
Options:
|
|
45
|
+
--latest Use the most-recently-modified session under ~/.claude/projects/
|
|
46
|
+
--session=<path> Use a specific session JSONL
|
|
47
|
+
--export-csv=<path> Also write a CSV summary
|
|
48
|
+
EOF
|
|
49
|
+
exit 0
|
|
50
|
+
;;
|
|
51
|
+
*) echo "Unknown argument: $1" >&2; exit 1 ;;
|
|
52
|
+
esac
|
|
53
|
+
shift
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
# Resolve session path.
|
|
57
|
+
if [ -n "$SESSION_PATH" ]; then
|
|
58
|
+
[ -f "$SESSION_PATH" ] || { echo "Error: session not found: $SESSION_PATH" >&2; exit 1; }
|
|
59
|
+
elif [ "$LATEST" = "true" ]; then
|
|
60
|
+
SESSION_PATH=$(/usr/bin/find ~/.claude/projects/ -name '*.jsonl' -type f -newer /tmp 2>/dev/null \
|
|
61
|
+
| /usr/bin/xargs -I {} /bin/ls -t1 {} 2>/dev/null \
|
|
62
|
+
| /usr/bin/head -n 1)
|
|
63
|
+
# Fallback: use plain find + sort by mtime
|
|
64
|
+
if [ -z "$SESSION_PATH" ]; then
|
|
65
|
+
SESSION_PATH=$(/usr/bin/find ~/.claude/projects/ -name '*.jsonl' -type f 2>/dev/null \
|
|
66
|
+
| while read -r f; do printf '%s\t%s\n' "$(/usr/bin/stat -f '%m' "$f" 2>/dev/null || echo 0)" "$f"; done \
|
|
67
|
+
| /usr/bin/sort -rn | /usr/bin/head -n 1 | /usr/bin/cut -f2)
|
|
68
|
+
fi
|
|
69
|
+
[ -n "$SESSION_PATH" ] || { echo "Error: no session JSONL found under ~/.claude/projects/" >&2; exit 1; }
|
|
70
|
+
echo "Using latest session: $SESSION_PATH"
|
|
71
|
+
else
|
|
72
|
+
echo "Error: must pass --latest or --session=<path>" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Use python3 for robust large-file parsing (jq -s fails on 100MB+ files).
|
|
77
|
+
EXPORT_ARG=""
|
|
78
|
+
if [ -n "$EXPORT_CSV" ]; then
|
|
79
|
+
EXPORT_ARG="$EXPORT_CSV"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
python3 - "$SESSION_PATH" "$EXPORT_ARG" <<'PYEOF'
|
|
83
|
+
import json, os, sys
|
|
84
|
+
|
|
85
|
+
path = sys.argv[1]
|
|
86
|
+
export_csv = sys.argv[2] if len(sys.argv) > 2 else ""
|
|
87
|
+
|
|
88
|
+
total_input = 0
|
|
89
|
+
total_output = 0
|
|
90
|
+
total_cache_read = 0
|
|
91
|
+
total_cache_write = 0
|
|
92
|
+
tool_calls = 0
|
|
93
|
+
dispatches = 0
|
|
94
|
+
turns = 0
|
|
95
|
+
turn_costs = []
|
|
96
|
+
|
|
97
|
+
with open(path, "r", errors="replace") as f:
|
|
98
|
+
for line in f:
|
|
99
|
+
line = line.strip()
|
|
100
|
+
if not line:
|
|
101
|
+
continue
|
|
102
|
+
try:
|
|
103
|
+
obj = json.loads(line)
|
|
104
|
+
except Exception:
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
msg = obj.get("message") or {}
|
|
108
|
+
usage = msg.get("usage") or {}
|
|
109
|
+
|
|
110
|
+
inp = usage.get("input_tokens") or 0
|
|
111
|
+
out = usage.get("output_tokens") or 0
|
|
112
|
+
cr = usage.get("cache_read_input_tokens") or 0
|
|
113
|
+
cw = usage.get("cache_creation_input_tokens") or 0
|
|
114
|
+
|
|
115
|
+
if inp > 0 or out > 0:
|
|
116
|
+
turns += 1
|
|
117
|
+
total_input += inp
|
|
118
|
+
total_output += out
|
|
119
|
+
total_cache_read += cr
|
|
120
|
+
total_cache_write += cw
|
|
121
|
+
turn_costs.append({"turn": turns, "role": msg.get("role", "?"), "input": inp, "output": out, "total": inp + out})
|
|
122
|
+
|
|
123
|
+
content = msg.get("content") or []
|
|
124
|
+
if isinstance(content, list):
|
|
125
|
+
for item in content:
|
|
126
|
+
if isinstance(item, dict) and item.get("type") == "tool_use":
|
|
127
|
+
tool_calls += 1
|
|
128
|
+
if item.get("name") == "Agent":
|
|
129
|
+
dispatches += 1
|
|
130
|
+
|
|
131
|
+
total_eff = total_input + total_cache_read
|
|
132
|
+
hit_rate = (total_cache_read / total_eff * 100) if total_eff > 0 else 0.0
|
|
133
|
+
|
|
134
|
+
print("")
|
|
135
|
+
print("===== CONDUCTOR token-measurement =====")
|
|
136
|
+
print(f"Session: {path}")
|
|
137
|
+
print("")
|
|
138
|
+
print(f"Turns : {turns:,}")
|
|
139
|
+
print(f"Input tokens (uncached) : {total_input:,}")
|
|
140
|
+
print(f"Output tokens : {total_output:,}")
|
|
141
|
+
print(f"Cache-read tokens : {total_cache_read:,}")
|
|
142
|
+
print(f"Cache-write tokens : {total_cache_write:,}")
|
|
143
|
+
print(f"Cache hit rate : {hit_rate:.1f}%")
|
|
144
|
+
print(f"Tool calls (total) : {tool_calls:,}")
|
|
145
|
+
print(f"Sub-agent dispatches : {dispatches:,}")
|
|
146
|
+
|
|
147
|
+
top5 = sorted(turn_costs, key=lambda x: -x["total"])[:5]
|
|
148
|
+
print("")
|
|
149
|
+
print("===== Top 5 expensive turns (input + output) =====")
|
|
150
|
+
for t in top5:
|
|
151
|
+
print(f" turn={t['turn']:<6} role={t['role']:<12} in={t['input']:,} out={t['output']:,} total={t['total']:,}")
|
|
152
|
+
|
|
153
|
+
if export_csv:
|
|
154
|
+
with open(export_csv, "w") as f:
|
|
155
|
+
f.write("metric,value\n")
|
|
156
|
+
f.write(f"session,{path}\n")
|
|
157
|
+
f.write(f"turns,{turns}\n")
|
|
158
|
+
f.write(f"input_tokens,{total_input}\n")
|
|
159
|
+
f.write(f"output_tokens,{total_output}\n")
|
|
160
|
+
f.write(f"cache_read_tokens,{total_cache_read}\n")
|
|
161
|
+
f.write(f"cache_write_tokens,{total_cache_write}\n")
|
|
162
|
+
f.write(f"cache_hit_rate_percent,{hit_rate:.1f}\n")
|
|
163
|
+
f.write(f"tool_calls,{tool_calls}\n")
|
|
164
|
+
f.write(f"dispatches,{dispatches}\n")
|
|
165
|
+
print(f"\nWriting CSV: {export_csv}")
|
|
166
|
+
|
|
167
|
+
print("")
|
|
168
|
+
print("(zero telemetry — values are local only; no external transmission)")
|
|
169
|
+
PYEOF
|