llm-wb 0.1.0-beta.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/.agentic/00.chat/README.md +78 -0
- package/.agentic/00.chat/checklists/before-commit.md +195 -0
- package/.agentic/00.chat/checklists/llm-workbench-public-beta.md +94 -0
- package/.agentic/00.chat/commands/README.md +108 -0
- package/.agentic/00.chat/migration-plan.md +132 -0
- package/.agentic/00.chat/skills/session-summary.md +48 -0
- package/.agentic/00.chat/standards/llm-workbench-public-beta-contract.md +216 -0
- package/.agentic/00.chat/standards/main-refresh-conflict-types.md +358 -0
- package/.agentic/00.chat/workflows/README.md +40 -0
- package/.agentic/00.chat/workflows/bootstrap-chat-workbench-repo.md +212 -0
- package/.agentic/00.chat/workflows/chat-cleanup.md +102 -0
- package/.agentic/00.chat/workflows/chat-commit.md +56 -0
- package/.agentic/00.chat/workflows/chat-promote-to-main.md +169 -0
- package/.agentic/00.chat/workflows/chat-refresh-from-main.md +242 -0
- package/.agentic/00.chat/workflows/chat-reporting.md +69 -0
- package/.agentic/00.chat/workflows/chat-start.md +173 -0
- package/.agentic/00.chat/workflows/chat-upstream-reusable-lesson.md +123 -0
- package/.agentic/shared/standards/README.md +32 -0
- package/.agentic/shared/standards/upstream-repo-bootstrap.md +131 -0
- package/.agentic/shared/workflows/README.md +35 -0
- package/.agentic/shared/workflows/capability-resolution-workflow.md +189 -0
- package/.agentic/shared/workflows/change-shared-process.md +92 -0
- package/.cursor/rules/llm-workbench.mdc +17 -0
- package/.github/copilot-instructions.md +16 -0
- package/AGENTS.md +63 -0
- package/CLAUDE.md +16 -0
- package/CONTRIBUTING.md +57 -0
- package/LICENSE +21 -0
- package/LLM_WORKBENCH.md +17 -0
- package/README.md +98 -0
- package/SECURITY.md +44 -0
- package/bin/llm-workbench.js +672 -0
- package/docs/00.chat/README.md +47 -0
- package/docs/00.chat/llm-workbench-acceptance-matrix.md +55 -0
- package/docs/00.chat/script-layout.md +107 -0
- package/docs/adapting-to-your-repo.md +29 -0
- package/docs/concepts.md +38 -0
- package/docs/install.md +114 -0
- package/docs/public-beta-contract.md +45 -0
- package/docs/workflows.md +103 -0
- package/examples/minimal-repo/README.md +13 -0
- package/package.json +93 -0
- package/scripts/00.chat/README.md +46 -0
- package/scripts/00.chat/bootstrap/README.md +35 -0
- package/scripts/00.chat/bootstrap/audit-chat-bootstrap-file-set/README.md +39 -0
- package/scripts/00.chat/bootstrap/audit-chat-bootstrap-file-set/script.sh +213 -0
- package/scripts/00.chat/closeout/README.md +30 -0
- package/scripts/00.chat/closeout/build-closeout-prompt/README.md +35 -0
- package/scripts/00.chat/closeout/build-closeout-prompt/script.sh +124 -0
- package/scripts/00.chat/command/README.md +31 -0
- package/scripts/00.chat/command/close/README.md +30 -0
- package/scripts/00.chat/command/close/script.sh +25 -0
- package/scripts/00.chat/command/dispatcher/README.md +46 -0
- package/scripts/00.chat/command/dispatcher/script.sh +91 -0
- package/scripts/00.chat/command/dispatcher/smoke-test.sh +168 -0
- package/scripts/00.chat/command/new/README.md +32 -0
- package/scripts/00.chat/command/new/script.sh +28 -0
- package/scripts/00.chat/command/open-window/README.md +38 -0
- package/scripts/00.chat/command/open-window/script.sh +25 -0
- package/scripts/00.chat/command/package-scripts/README.md +34 -0
- package/scripts/00.chat/command/package-scripts/smoke-test.sh +113 -0
- package/scripts/00.chat/git/README.md +30 -0
- package/scripts/00.chat/git/cleanup-empty-chat-branches/README.md +36 -0
- package/scripts/00.chat/git/cleanup-empty-chat-branches/script.sh +243 -0
- package/scripts/00.chat/git/cleanup-empty-chat-branches/smoke-test.sh +136 -0
- package/scripts/00.chat/local-merge/README.md +30 -0
- package/scripts/00.chat/local-merge/list-active-chat-branches/README.md +29 -0
- package/scripts/00.chat/local-merge/list-active-chat-branches/script.sh +109 -0
- package/scripts/00.chat/local-merge/report-chat-branch-overlaps/README.md +29 -0
- package/scripts/00.chat/local-merge/report-chat-branch-overlaps/script.sh +142 -0
- package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/README.md +33 -0
- package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/script.sh +345 -0
- package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/smoke-test.sh +244 -0
- package/scripts/00.chat/main-refresh/README.md +39 -0
- package/scripts/00.chat/main-refresh/apply-rehearsed-refresh/README.md +32 -0
- package/scripts/00.chat/main-refresh/apply-rehearsed-refresh/script.sh +198 -0
- package/scripts/00.chat/main-refresh/check-chat-is-current-with-main/README.md +30 -0
- package/scripts/00.chat/main-refresh/check-chat-is-current-with-main/script.sh +121 -0
- package/scripts/00.chat/main-refresh/classify-conflict/README.md +39 -0
- package/scripts/00.chat/main-refresh/classify-conflict/script.sh +169 -0
- package/scripts/00.chat/main-refresh/classify-conflict/smoke-test.sh +137 -0
- package/scripts/00.chat/main-refresh/classify-refresh-readiness/README.md +35 -0
- package/scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh +171 -0
- package/scripts/00.chat/main-refresh/classify-refresh-readiness/smoke-test.sh +132 -0
- package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/README.md +34 -0
- package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/script.sh +124 -0
- package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/smoke-test.sh +257 -0
- package/scripts/00.chat/main-refresh/show-main-update-status/README.md +31 -0
- package/scripts/00.chat/main-refresh/show-main-update-status/script.sh +73 -0
- package/scripts/00.chat/main-refresh/verify-conflict-audit/README.md +37 -0
- package/scripts/00.chat/main-refresh/verify-conflict-audit/script.sh +154 -0
- package/scripts/00.chat/main-refresh/verify-conflict-audit/smoke-test.sh +99 -0
- package/scripts/00.chat/metrics/README.md +35 -0
- package/scripts/00.chat/metrics/data/chat-pricing.json +107 -0
- package/scripts/00.chat/metrics/data/chat-pricing.schema.json +63 -0
- package/scripts/00.chat/metrics/estimate-chat-cost/README.md +40 -0
- package/scripts/00.chat/metrics/estimate-chat-cost/script.js +130 -0
- package/scripts/00.chat/migration/README.md +30 -0
- package/scripts/00.chat/migration/audit-chat-layer-migration/README.md +33 -0
- package/scripts/00.chat/migration/audit-chat-layer-migration/script.sh +127 -0
- package/scripts/00.chat/recovery/README.md +30 -0
- package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/README.md +76 -0
- package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/script.sh +212 -0
- package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/smoke-test.sh +162 -0
- package/scripts/00.chat/reporting/README.md +30 -0
- package/scripts/00.chat/reporting/generate-commit-log-summary/README.md +35 -0
- package/scripts/00.chat/reporting/generate-commit-log-summary/script.sh +299 -0
- package/scripts/00.chat/reporting/generate-commit-log-summary/smoke-test.sh +93 -0
- package/scripts/00.chat/reporting/report-chat-workspaces/README.md +32 -0
- package/scripts/00.chat/reporting/report-chat-workspaces/script.sh +82 -0
- package/scripts/00.chat/session-log/README.md +33 -0
- package/scripts/00.chat/session-log/check-commit-prerequisites/README.md +89 -0
- package/scripts/00.chat/session-log/check-commit-prerequisites/script.sh +121 -0
- package/scripts/00.chat/session-log/check-commit-prerequisites/smoke-test.sh +119 -0
- package/scripts/00.chat/session-log/check-commitlog-deletions/README.md +90 -0
- package/scripts/00.chat/session-log/check-commitlog-deletions/script.sh +131 -0
- package/scripts/00.chat/session-log/check-commitlog-deletions/smoke-test.sh +123 -0
- package/scripts/00.chat/session-log/checkpoint-chat-session-log/README.md +98 -0
- package/scripts/00.chat/session-log/checkpoint-chat-session-log/script.sh +126 -0
- package/scripts/00.chat/session-log/paths/README.md +38 -0
- package/scripts/00.chat/session-log/paths/lib.sh +133 -0
- package/scripts/00.chat/session-log/prepare-chat-session-before-commit/README.md +90 -0
- package/scripts/00.chat/session-log/prepare-chat-session-before-commit/script.sh +145 -0
- package/scripts/00.chat/session-log/read-current-chat-log/README.md +44 -0
- package/scripts/00.chat/session-log/read-current-chat-log/script.sh +92 -0
- package/scripts/00.chat/session-log/read-current-chat-log/smoke-test.sh +127 -0
- package/scripts/00.chat/session-log/record-chat-commit/README.md +133 -0
- package/scripts/00.chat/session-log/record-chat-commit/script.sh +394 -0
- package/scripts/00.chat/session-log/record-chat-commit/smoke-test.sh +227 -0
- package/scripts/00.chat/session-log/record-main-refresh-conflict/README.md +34 -0
- package/scripts/00.chat/session-log/record-main-refresh-conflict/script.sh +239 -0
- package/scripts/00.chat/session-log/rename-current-chat-log-folder/README.md +32 -0
- package/scripts/00.chat/session-log/rename-current-chat-log-folder/script.sh +112 -0
- package/scripts/00.chat/session-log/update-chat-log/README.md +32 -0
- package/scripts/00.chat/session-log/update-chat-log/script.sh +294 -0
- package/scripts/00.chat/startup/README.md +37 -0
- package/scripts/00.chat/startup/auto-start-missing-session/README.md +113 -0
- package/scripts/00.chat/startup/auto-start-missing-session/script.sh +54 -0
- package/scripts/00.chat/startup/resolve-current-chat-session/README.md +57 -0
- package/scripts/00.chat/startup/resolve-current-chat-session/script.sh +47 -0
- package/scripts/00.chat/startup/resolve-current-chat-session/smoke-test.sh +130 -0
- package/scripts/00.chat/startup/start-chat-session/README.md +197 -0
- package/scripts/00.chat/startup/start-chat-session/script.sh +330 -0
- package/scripts/00.chat/startup/start-chat-session/smoke-test.sh +182 -0
- package/scripts/00.chat/startup/start-new-chat/README.md +31 -0
- package/scripts/00.chat/startup/start-new-chat/script.sh +29 -0
- package/scripts/00.chat/transcript/README.md +36 -0
- package/scripts/00.chat/transcript/discover-codex-session-log/README.md +32 -0
- package/scripts/00.chat/transcript/discover-codex-session-log/script.sh +106 -0
- package/scripts/00.chat/transcript/register-codex-session-log/README.md +32 -0
- package/scripts/00.chat/transcript/register-codex-session-log/script.sh +115 -0
- package/scripts/00.chat/worktree/README.md +32 -0
- package/scripts/00.chat/worktree/check-write-location/README.md +87 -0
- package/scripts/00.chat/worktree/check-write-location/script.sh +95 -0
- package/scripts/00.chat/worktree/dirty-worktree-check/README.md +77 -0
- package/scripts/00.chat/worktree/dirty-worktree-check/script.sh +93 -0
- package/scripts/00.chat/worktree/ensure-chat-worktree/README.md +33 -0
- package/scripts/00.chat/worktree/ensure-chat-worktree/script.sh +132 -0
- package/scripts/00.chat/worktree/open-window/README.md +34 -0
- package/scripts/00.chat/worktree/open-window/script.sh +131 -0
- package/scripts/00.chat/worktree/paths/README.md +32 -0
- package/scripts/00.chat/worktree/paths/lib.sh +71 -0
- package/scripts/01.harness/artifact-metadata/check-headers/script.sh +522 -0
- package/scripts/01.harness/artifact-metadata/check-headers/smoke-test.sh +48 -0
- package/scripts/01.harness/check-deterministic-process-drift.sh +416 -0
- package/scripts/01.harness/check-governed-script-command-drift.sh +184 -0
- package/scripts/01.harness/run-governed-script.sh +178 -0
- package/scripts/install.sh +503 -0
- package/scripts/uninstall.sh +199 -0
- package/tests/smoke-test-install.sh +70 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# agentic-artifact:
|
|
5
|
+
# schema: agentic-artifact/v2
|
|
6
|
+
# id: chat.script.reporting.generate-commit-log-summary
|
|
7
|
+
# version: 1
|
|
8
|
+
# status: active
|
|
9
|
+
# layer: 00.chat
|
|
10
|
+
# domain: reporting
|
|
11
|
+
# disciplines:
|
|
12
|
+
# - agentic
|
|
13
|
+
# kind: script
|
|
14
|
+
# purpose: Generate on-demand aggregate summaries from chat session logs.
|
|
15
|
+
# portability:
|
|
16
|
+
# class: required
|
|
17
|
+
# targets:
|
|
18
|
+
# - llm-workbench
|
|
19
|
+
# used_by:
|
|
20
|
+
# - id: chat.skills.session-summary
|
|
21
|
+
# path: .agentic/00.chat/skills/session-summary.md
|
|
22
|
+
# - id: chat.workflows.chat-reporting
|
|
23
|
+
# path: .agentic/00.chat/workflows/chat-reporting.md
|
|
24
|
+
# effects:
|
|
25
|
+
# - read-only
|
|
26
|
+
# - writes-files
|
|
27
|
+
|
|
28
|
+
usage() {
|
|
29
|
+
cat <<'EOF'
|
|
30
|
+
Usage:
|
|
31
|
+
generate-commit-log-summary.sh [--print|--output <path>]
|
|
32
|
+
|
|
33
|
+
Prints an aggregate summary from individual chat session logs.
|
|
34
|
+
Use --output to write the summary to an explicit on-demand artifact path.
|
|
35
|
+
Do not write commitLogs/README.md.
|
|
36
|
+
EOF
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
OUTPUT_PATH=""
|
|
40
|
+
MODE="print"
|
|
41
|
+
|
|
42
|
+
while [ $# -gt 0 ]; do
|
|
43
|
+
case "$1" in
|
|
44
|
+
--print)
|
|
45
|
+
MODE="print"
|
|
46
|
+
shift
|
|
47
|
+
;;
|
|
48
|
+
--output)
|
|
49
|
+
if [ $# -lt 2 ]; then
|
|
50
|
+
usage >&2
|
|
51
|
+
exit 2
|
|
52
|
+
fi
|
|
53
|
+
MODE="output"
|
|
54
|
+
OUTPUT_PATH="$2"
|
|
55
|
+
shift 2
|
|
56
|
+
;;
|
|
57
|
+
-h|--help)
|
|
58
|
+
usage
|
|
59
|
+
exit 0
|
|
60
|
+
;;
|
|
61
|
+
*)
|
|
62
|
+
usage >&2
|
|
63
|
+
exit 2
|
|
64
|
+
;;
|
|
65
|
+
esac
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
if [ "$OUTPUT_PATH" = "commitLogs/README.md" ]; then
|
|
69
|
+
echo "ERROR: commitLogs/README.md is not maintained as an aggregate artifact." >&2
|
|
70
|
+
echo "Write on-demand summaries somewhere else, such as /tmp/chat-summary.md." >&2
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
node - "$MODE" "$OUTPUT_PATH" <<'NODE'
|
|
75
|
+
const fs = require('fs');
|
|
76
|
+
const path = require('path');
|
|
77
|
+
|
|
78
|
+
const mode = process.argv[2];
|
|
79
|
+
const outputPath = process.argv[3];
|
|
80
|
+
const root = 'commitLogs';
|
|
81
|
+
const retiredOutputPath = path.join(root, 'README.md');
|
|
82
|
+
|
|
83
|
+
function walk(dir) {
|
|
84
|
+
if (!fs.existsSync(dir)) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
89
|
+
const entryPath = path.join(dir, entry.name);
|
|
90
|
+
if (entry.isDirectory()) {
|
|
91
|
+
return walk(entryPath);
|
|
92
|
+
}
|
|
93
|
+
if (entry.isFile() && entry.name === 'README.md' && entryPath !== retiredOutputPath) {
|
|
94
|
+
return [entryPath];
|
|
95
|
+
}
|
|
96
|
+
return [];
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function metadata(content) {
|
|
101
|
+
const match = content.match(/<!-- agentic-session\n([\s\S]*?)\n-->/);
|
|
102
|
+
if (!match) {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Object.fromEntries(
|
|
107
|
+
match[1].split('\n').map((line) => {
|
|
108
|
+
const separator = line.indexOf(':');
|
|
109
|
+
if (separator === -1) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return [
|
|
113
|
+
line.slice(0, separator).trim(),
|
|
114
|
+
line.slice(separator + 1).trim(),
|
|
115
|
+
];
|
|
116
|
+
}).filter(Boolean),
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function parseDurationSeconds(value) {
|
|
121
|
+
const match = String(value || '').match(/(\d+)s\b/);
|
|
122
|
+
return match ? Number(match[1]) : null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function parseTokenCount(value) {
|
|
126
|
+
const match = String(value || '').match(/^(\d+)\b/);
|
|
127
|
+
return match ? Number(match[1]) : null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function parseUsdCost(value) {
|
|
131
|
+
const match = String(value || '').match(/^USD\s+(\d+(?:\.\d+)?)\b/);
|
|
132
|
+
return match ? Number(match[1]) : null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function mean(values) {
|
|
136
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function standardDeviation(values, average) {
|
|
140
|
+
const variance = values.reduce((sum, value) => {
|
|
141
|
+
return sum + ((value - average) ** 2);
|
|
142
|
+
}, 0) / values.length;
|
|
143
|
+
return Math.sqrt(variance);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function quantile(sortedValues, q) {
|
|
147
|
+
if (sortedValues.length === 0) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
if (sortedValues.length === 1) {
|
|
151
|
+
return sortedValues[0];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const position = (sortedValues.length - 1) * q;
|
|
155
|
+
const lower = Math.floor(position);
|
|
156
|
+
const upper = Math.ceil(position);
|
|
157
|
+
const weight = position - lower;
|
|
158
|
+
|
|
159
|
+
return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function metricStats(values) {
|
|
163
|
+
const valid = values.filter((value) => Number.isFinite(value));
|
|
164
|
+
if (valid.length === 0) {
|
|
165
|
+
return {
|
|
166
|
+
validCount: 0,
|
|
167
|
+
includedCount: 0,
|
|
168
|
+
outlierCount: 0,
|
|
169
|
+
total: null,
|
|
170
|
+
min: null,
|
|
171
|
+
max: null,
|
|
172
|
+
average: null,
|
|
173
|
+
q1: null,
|
|
174
|
+
median: null,
|
|
175
|
+
q3: null,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const average = mean(valid);
|
|
180
|
+
const sd = standardDeviation(valid, average);
|
|
181
|
+
const included = sd === 0
|
|
182
|
+
? valid
|
|
183
|
+
: valid.filter((value) => Math.abs(value - average) <= 3 * sd);
|
|
184
|
+
const sorted = [...included].sort((a, b) => a - b);
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
validCount: valid.length,
|
|
188
|
+
includedCount: included.length,
|
|
189
|
+
outlierCount: valid.length - included.length,
|
|
190
|
+
total: included.reduce((sum, value) => sum + value, 0),
|
|
191
|
+
min: sorted[0],
|
|
192
|
+
max: sorted[sorted.length - 1],
|
|
193
|
+
average: mean(included),
|
|
194
|
+
q1: quantile(sorted, 0.25),
|
|
195
|
+
median: quantile(sorted, 0.5),
|
|
196
|
+
q3: quantile(sorted, 0.75),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function formatNumber(value) {
|
|
201
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
202
|
+
return 'n/a';
|
|
203
|
+
}
|
|
204
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(2);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function formatUsd(value) {
|
|
208
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
209
|
+
return 'n/a';
|
|
210
|
+
}
|
|
211
|
+
if (value > 0 && value < 1) {
|
|
212
|
+
return `USD ${value.toFixed(4)}`;
|
|
213
|
+
}
|
|
214
|
+
return `USD ${value.toFixed(2)}`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function formatDuration(value) {
|
|
218
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
219
|
+
return 'n/a';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const rounded = Math.round(value);
|
|
223
|
+
const days = Math.floor(rounded / 86400);
|
|
224
|
+
const hours = Math.floor((rounded % 86400) / 3600);
|
|
225
|
+
const minutes = Math.floor((rounded % 3600) / 60);
|
|
226
|
+
const seconds = rounded % 60;
|
|
227
|
+
|
|
228
|
+
return `${rounded}s (${String(days).padStart(2, '0')}:` +
|
|
229
|
+
`${String(hours).padStart(2, '0')}:` +
|
|
230
|
+
`${String(minutes).padStart(2, '0')}:` +
|
|
231
|
+
`${String(seconds).padStart(2, '0')})`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function metricTable(stats, formatter) {
|
|
235
|
+
return [
|
|
236
|
+
'| Metric | Value |',
|
|
237
|
+
'| --- | ---: |',
|
|
238
|
+
`| Valid chats | ${stats.validCount} |`,
|
|
239
|
+
`| Included chats | ${stats.includedCount} |`,
|
|
240
|
+
`| Outliers excluded | ${stats.outlierCount} |`,
|
|
241
|
+
`| Total | ${formatter(stats.total)} |`,
|
|
242
|
+
`| Min | ${formatter(stats.min)} |`,
|
|
243
|
+
`| Max | ${formatter(stats.max)} |`,
|
|
244
|
+
`| Average | ${formatter(stats.average)} |`,
|
|
245
|
+
`| Q1 | ${formatter(stats.q1)} |`,
|
|
246
|
+
`| Median | ${formatter(stats.median)} |`,
|
|
247
|
+
`| Q3 | ${formatter(stats.q3)} |`,
|
|
248
|
+
].join('\n');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const logs = walk(root).sort();
|
|
252
|
+
const records = logs.map((filePath) => {
|
|
253
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
254
|
+
const data = metadata(content);
|
|
255
|
+
return {
|
|
256
|
+
filePath,
|
|
257
|
+
id: data.id || path.basename(path.dirname(filePath)),
|
|
258
|
+
durationSeconds: parseDurationSeconds(data.chat_duration),
|
|
259
|
+
tokens: parseTokenCount(data.estimated_chat_tokens),
|
|
260
|
+
cost: parseUsdCost(data.estimated_chat_cost),
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const durationStats = metricStats(records.map((record) => record.durationSeconds));
|
|
265
|
+
const tokenStats = metricStats(records.map((record) => record.tokens));
|
|
266
|
+
const costStats = metricStats(records.map((record) => record.cost));
|
|
267
|
+
|
|
268
|
+
const lines = [
|
|
269
|
+
'# Commit Log Summary',
|
|
270
|
+
'',
|
|
271
|
+
`Total chats: ${records.length}`,
|
|
272
|
+
'',
|
|
273
|
+
'Outliers are values more than 3 standard deviations from the mean for each metric.',
|
|
274
|
+
'',
|
|
275
|
+
'## Chat Duration',
|
|
276
|
+
'',
|
|
277
|
+
metricTable(durationStats, formatDuration),
|
|
278
|
+
'',
|
|
279
|
+
'## Estimated Chat Tokens',
|
|
280
|
+
'',
|
|
281
|
+
metricTable(tokenStats, formatNumber),
|
|
282
|
+
'',
|
|
283
|
+
'## Estimated Chat Cost',
|
|
284
|
+
'',
|
|
285
|
+
metricTable(costStats, formatUsd),
|
|
286
|
+
'',
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
const output = lines.join('\n');
|
|
290
|
+
|
|
291
|
+
if (mode === 'print') {
|
|
292
|
+
process.stdout.write(output);
|
|
293
|
+
process.exit(0);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
297
|
+
fs.writeFileSync(outputPath, output);
|
|
298
|
+
console.log(`Wrote ${outputPath}`);
|
|
299
|
+
NODE
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# agentic-artifact:
|
|
5
|
+
# schema: agentic-artifact/v2
|
|
6
|
+
# id: chat.script.reporting.generate-commit-log-summary.smoke-test
|
|
7
|
+
# version: 1
|
|
8
|
+
# status: active
|
|
9
|
+
# layer: 00.chat
|
|
10
|
+
# domain: validation
|
|
11
|
+
# disciplines:
|
|
12
|
+
# - agentic
|
|
13
|
+
# kind: script
|
|
14
|
+
# purpose: Smoke test on-demand chat commit log summary generation.
|
|
15
|
+
# portability:
|
|
16
|
+
# class: reusable
|
|
17
|
+
# targets:
|
|
18
|
+
# - llm-workbench
|
|
19
|
+
# used_by:
|
|
20
|
+
# - id: chat.workflows.chat-reporting
|
|
21
|
+
# path: .agentic/00.chat/workflows/chat-reporting.md
|
|
22
|
+
# effects:
|
|
23
|
+
# - writes-files
|
|
24
|
+
|
|
25
|
+
fail() {
|
|
26
|
+
echo "FAIL: $*" >&2
|
|
27
|
+
exit 1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
SOURCE_ROOT="$(git rev-parse --show-toplevel)"
|
|
31
|
+
TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/commit-log-summary-smoke.XXXXXX")"
|
|
32
|
+
|
|
33
|
+
cleanup() {
|
|
34
|
+
rm -rf "$TMP_ROOT"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
trap cleanup EXIT
|
|
38
|
+
|
|
39
|
+
REPO="$TMP_ROOT/repo"
|
|
40
|
+
mkdir -p "$REPO/scripts/00.chat/reporting/generate-commit-log-summary" "$REPO/commitLogs/2026/jun/17/test-chat"
|
|
41
|
+
cp "$SOURCE_ROOT/scripts/00.chat/reporting/generate-commit-log-summary/script.sh" \
|
|
42
|
+
"$REPO/scripts/00.chat/reporting/generate-commit-log-summary/script.sh"
|
|
43
|
+
|
|
44
|
+
cat > "$REPO/commitLogs/2026/jun/17/test-chat/README.md" <<'EOF'
|
|
45
|
+
# Chat Session: test-chat
|
|
46
|
+
|
|
47
|
+
<!-- agentic-session
|
|
48
|
+
id: test-chat
|
|
49
|
+
chat_duration: 42s
|
|
50
|
+
estimated_chat_tokens: 100 tokens
|
|
51
|
+
estimated_chat_cost: USD 0.0030 estimated from estimated_chat_tokens
|
|
52
|
+
-->
|
|
53
|
+
EOF
|
|
54
|
+
|
|
55
|
+
(
|
|
56
|
+
cd "$REPO"
|
|
57
|
+
bash scripts/00.chat/reporting/generate-commit-log-summary/script.sh > "$TMP_ROOT/printed.md"
|
|
58
|
+
bash scripts/00.chat/reporting/generate-commit-log-summary/script.sh --output "$TMP_ROOT/written.md" >/dev/null
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
if ! cmp -s "$TMP_ROOT/written.md" "$TMP_ROOT/printed.md"; then
|
|
62
|
+
fail "printed output did not match explicit output file"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
set +e
|
|
66
|
+
(
|
|
67
|
+
cd "$REPO"
|
|
68
|
+
bash scripts/00.chat/reporting/generate-commit-log-summary/script.sh --output commitLogs/README.md
|
|
69
|
+
) >/dev/null 2>"$TMP_ROOT/blocked.err"
|
|
70
|
+
BLOCKED_STATUS="$?"
|
|
71
|
+
set -e
|
|
72
|
+
|
|
73
|
+
if [ "$BLOCKED_STATUS" -eq 0 ]; then
|
|
74
|
+
fail "script allowed writing commitLogs/README.md"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
if ! grep -q "not maintained" "$TMP_ROOT/blocked.err"; then
|
|
78
|
+
fail "script did not explain retired aggregate path"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if ! grep -q "Estimated Chat Tokens" "$TMP_ROOT/printed.md"; then
|
|
82
|
+
fail "summary did not use estimated chat token heading"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
if ! grep -q "Estimated Chat Cost" "$TMP_ROOT/printed.md"; then
|
|
86
|
+
fail "summary did not use estimated chat cost heading"
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
if ! grep -q '| Total | USD 0.0030 |' "$TMP_ROOT/printed.md"; then
|
|
90
|
+
fail "summary did not aggregate estimated chat cost"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
echo "commit log summary smoke test passed."
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!-- agentic-artifact:
|
|
2
|
+
schema: agentic-artifact/v2
|
|
3
|
+
id: chat.script.reporting.report-chat-workspaces.readme
|
|
4
|
+
version: 1
|
|
5
|
+
status: active
|
|
6
|
+
layer: 00.chat
|
|
7
|
+
domain: reporting
|
|
8
|
+
disciplines:
|
|
9
|
+
- agentic
|
|
10
|
+
kind: capability-readme
|
|
11
|
+
purpose: Explain chat branch and worktree status reporting.
|
|
12
|
+
portability:
|
|
13
|
+
class: required
|
|
14
|
+
targets:
|
|
15
|
+
- llm-workbench
|
|
16
|
+
used_by:
|
|
17
|
+
- id: chat.workflows.chat-cleanup
|
|
18
|
+
path: .agentic/00.chat/workflows/chat-cleanup.md
|
|
19
|
+
- id: chat.script.reporting.report-chat-workspaces
|
|
20
|
+
path: scripts/00.chat/reporting/report-chat-workspaces/script.sh
|
|
21
|
+
-->
|
|
22
|
+
# Report Chat Workspaces
|
|
23
|
+
|
|
24
|
+
`script.sh` prints a table of local `chat/*` branches, ahead/behind state,
|
|
25
|
+
recorded log head state, and worktree path.
|
|
26
|
+
|
|
27
|
+
Use this before cleanup or promotion when a human needs to understand which
|
|
28
|
+
chat branches are active, stale, missing logs, or checked out elsewhere.
|
|
29
|
+
|
|
30
|
+
The script is read-only. It does not delete branches, clean worktrees, merge,
|
|
31
|
+
or push.
|
|
32
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# agentic-artifact:
|
|
5
|
+
# schema: agentic-artifact/v2
|
|
6
|
+
# id: chat.script.reporting.report-chat-workspaces
|
|
7
|
+
# version: 1
|
|
8
|
+
# status: active
|
|
9
|
+
# layer: 00.chat
|
|
10
|
+
# domain: reporting
|
|
11
|
+
# disciplines:
|
|
12
|
+
# - agentic
|
|
13
|
+
# kind: script
|
|
14
|
+
# purpose: Report chat branches, log head state, and worktree status.
|
|
15
|
+
# portability:
|
|
16
|
+
# class: required
|
|
17
|
+
# targets:
|
|
18
|
+
# - llm-workbench
|
|
19
|
+
# used_by:
|
|
20
|
+
# - id: chat.workflows.chat-cleanup
|
|
21
|
+
# path: .agentic/00.chat/workflows/chat-cleanup.md
|
|
22
|
+
# - id: chat.workflows.chat-promote-to-main
|
|
23
|
+
# path: .agentic/00.chat/workflows/chat-promote-to-main.md
|
|
24
|
+
# effects:
|
|
25
|
+
# - read-only
|
|
26
|
+
|
|
27
|
+
BASE_BRANCH="${1:-main}"
|
|
28
|
+
|
|
29
|
+
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
30
|
+
REPO_ROOT="$(cd "$REPO_ROOT" && pwd -P)"
|
|
31
|
+
|
|
32
|
+
# shellcheck source=../../worktree/paths/lib.sh
|
|
33
|
+
source "$REPO_ROOT/scripts/00.chat/worktree/paths/lib.sh"
|
|
34
|
+
# shellcheck source=../../session-log/paths/lib.sh
|
|
35
|
+
source "$REPO_ROOT/scripts/00.chat/session-log/paths/lib.sh"
|
|
36
|
+
|
|
37
|
+
if ! git -C "$REPO_ROOT" show-ref --verify --quiet "refs/heads/${BASE_BRANCH}"; then
|
|
38
|
+
echo "ERROR: base branch does not exist: $BASE_BRANCH" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
printf 'Base branch: %s\n' "$BASE_BRANCH"
|
|
43
|
+
printf '%-64s %-8s %-8s %-8s %-10s %s\n' "branch" "ahead" "behind" "status" "log-head" "worktree"
|
|
44
|
+
|
|
45
|
+
git -C "$REPO_ROOT" branch --format='%(refname:short)' | while IFS= read -r branch; do
|
|
46
|
+
case "$branch" in
|
|
47
|
+
chat/*) ;;
|
|
48
|
+
*) continue ;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
session_id="${branch#chat/}"
|
|
52
|
+
log_file="$(chat_log_file_for_session "$session_id")"
|
|
53
|
+
branch_head="$(git -C "$REPO_ROOT" rev-parse --short "$branch")"
|
|
54
|
+
recorded_head=""
|
|
55
|
+
log_head_state="missing"
|
|
56
|
+
|
|
57
|
+
if [ -f "$log_file" ]; then
|
|
58
|
+
recorded_head="$(chat_worktree_metadata_value "$log_file" "latest_commit_sha")"
|
|
59
|
+
if [ -z "${recorded_head// }" ]; then
|
|
60
|
+
log_head_state="unrecorded"
|
|
61
|
+
elif [ "${recorded_head:0:7}" = "$branch_head" ]; then
|
|
62
|
+
log_head_state="matches"
|
|
63
|
+
else
|
|
64
|
+
log_head_state="differs"
|
|
65
|
+
fi
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
ahead="$(git -C "$REPO_ROOT" rev-list --count "${BASE_BRANCH}..${branch}")"
|
|
69
|
+
behind="$(git -C "$REPO_ROOT" rev-list --count "${branch}..${BASE_BRANCH}")"
|
|
70
|
+
worktree_path="$(chat_worktree_path_for_branch "$REPO_ROOT" "$branch")"
|
|
71
|
+
status="absent"
|
|
72
|
+
|
|
73
|
+
if [ -d "$worktree_path/.git" ] || git -C "$worktree_path" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
74
|
+
if [ -z "$(git -C "$worktree_path" status --porcelain)" ]; then
|
|
75
|
+
status="clean"
|
|
76
|
+
else
|
|
77
|
+
status="dirty"
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
printf '%-64s %-8s %-8s %-8s %-10s %s\n' "$branch" "$ahead" "$behind" "$status" "$log_head_state" "$worktree_path"
|
|
82
|
+
done
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!-- agentic-artifact:
|
|
2
|
+
schema: agentic-artifact/v2
|
|
3
|
+
id: chat.script.session-log.readme
|
|
4
|
+
version: 1
|
|
5
|
+
status: active
|
|
6
|
+
layer: 00.chat
|
|
7
|
+
domain: session-log
|
|
8
|
+
disciplines:
|
|
9
|
+
- agentic
|
|
10
|
+
kind: script-domain-readme
|
|
11
|
+
purpose: Explain session-log scripts for durable chat evidence.
|
|
12
|
+
portability:
|
|
13
|
+
class: required
|
|
14
|
+
targets:
|
|
15
|
+
- llm-workbench
|
|
16
|
+
used_by:
|
|
17
|
+
- id: chat.checklists.before-commit
|
|
18
|
+
path: .agentic/00.chat/checklists/before-commit.md
|
|
19
|
+
- id: chat.script.session-log.record-chat-commit.readme
|
|
20
|
+
path: scripts/00.chat/session-log/record-chat-commit/README.md
|
|
21
|
+
-->
|
|
22
|
+
# Session Log Scripts
|
|
23
|
+
|
|
24
|
+
Session-log scripts read and update the durable evidence for a chat. The
|
|
25
|
+
session log records task intent, branch/worktree metadata, workflow routing,
|
|
26
|
+
activity, decisions, issues, commits, conflicts, and metrics.
|
|
27
|
+
|
|
28
|
+
These scripts are part of why chats are auditable. They should update only the
|
|
29
|
+
current chat's log unless a workflow explicitly says otherwise.
|
|
30
|
+
|
|
31
|
+
The helper libraries in this domain provide shared path and metadata parsing
|
|
32
|
+
for other chat capabilities.
|
|
33
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!-- agentic-artifact:
|
|
2
|
+
schema: agentic-artifact/v2
|
|
3
|
+
id: chat.script.session-log.check-commit-prerequisites.readme
|
|
4
|
+
version: 1
|
|
5
|
+
status: active
|
|
6
|
+
layer: 00.chat
|
|
7
|
+
domain: session-log
|
|
8
|
+
disciplines:
|
|
9
|
+
- agentic
|
|
10
|
+
kind: capability-readme
|
|
11
|
+
purpose: Explain how commit prerequisite checks verify workflow and gate references
|
|
12
|
+
before chat commits.
|
|
13
|
+
portability:
|
|
14
|
+
class: required
|
|
15
|
+
targets:
|
|
16
|
+
- llm-workbench
|
|
17
|
+
used_by:
|
|
18
|
+
- id: chat.script.session-log.check-commit-prerequisites
|
|
19
|
+
path: scripts/00.chat/session-log/check-commit-prerequisites/script.sh
|
|
20
|
+
- id: chat.script.session-log.check-commit-prerequisites.smoke-test
|
|
21
|
+
path: scripts/00.chat/session-log/check-commit-prerequisites/smoke-test.sh
|
|
22
|
+
- id: harness.architecture.adr.0017-organize-scripts-by-owner-domain-and-capability
|
|
23
|
+
-->
|
|
24
|
+
# Check Commit Prerequisites
|
|
25
|
+
|
|
26
|
+
`script.sh` verifies that the current chat session points at real governance
|
|
27
|
+
artifacts before a task commit proceeds.
|
|
28
|
+
|
|
29
|
+
It is a structural readiness check. It does not decide whether the code change
|
|
30
|
+
is good. It checks that the session log, declared workflow, canonical checklist,
|
|
31
|
+
and referenced gate scripts are present so the commit boundary is governed by
|
|
32
|
+
real files rather than stale documentation.
|
|
33
|
+
|
|
34
|
+
## Mental Model
|
|
35
|
+
|
|
36
|
+
A chat session is only committable if its process map still resolves.
|
|
37
|
+
|
|
38
|
+
The session log names a workflow. The workflow and before-commit checklist name
|
|
39
|
+
scripts that should exist. If any of those links are broken, the agent might be
|
|
40
|
+
following a workflow that cannot actually run.
|
|
41
|
+
|
|
42
|
+
This gate catches that problem before the task commit.
|
|
43
|
+
|
|
44
|
+
## Checks
|
|
45
|
+
|
|
46
|
+
The script verifies:
|
|
47
|
+
|
|
48
|
+
- current branch is a `chat/*` branch
|
|
49
|
+
- matching session log exists
|
|
50
|
+
- session metadata includes a `workflow`
|
|
51
|
+
- declared workflow file exists
|
|
52
|
+
- canonical `.agentic/00.chat/checklists/before-commit.md` exists
|
|
53
|
+
- executable script references in the workflow and checklist point to real
|
|
54
|
+
`.sh` files
|
|
55
|
+
|
|
56
|
+
Directory prose such as `scripts/00.chat/` is ignored; only script-looking
|
|
57
|
+
references ending in `.sh` are treated as gate references.
|
|
58
|
+
|
|
59
|
+
## What This Does Not Do
|
|
60
|
+
|
|
61
|
+
- It does not run every referenced gate.
|
|
62
|
+
- It does not inspect code quality.
|
|
63
|
+
- It does not stage, commit, merge, or push.
|
|
64
|
+
- It does not validate ADR disposition content.
|
|
65
|
+
- It does not replace `prepare-chat-session-before-commit`; it is one gate that
|
|
66
|
+
the readiness coordinator runs.
|
|
67
|
+
|
|
68
|
+
## Validation
|
|
69
|
+
|
|
70
|
+
`smoke-test.sh` builds a throwaway chat repo and verifies that:
|
|
71
|
+
|
|
72
|
+
- a valid workflow/checklist setup passes
|
|
73
|
+
- prose directory references are not mistaken for missing scripts
|
|
74
|
+
|
|
75
|
+
Run the canonical smoke test with:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
bash scripts/00.chat/session-log/check-commit-prerequisites/smoke-test.sh
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Compatibility
|
|
82
|
+
|
|
83
|
+
The old shared path remains available:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
scripts/00.chat/session-log/check-commit-prerequisites/script.sh
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
That file is now a compatibility wrapper around the canonical implementation.
|