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.
Files changed (170) hide show
  1. package/.agentic/00.chat/README.md +78 -0
  2. package/.agentic/00.chat/checklists/before-commit.md +195 -0
  3. package/.agentic/00.chat/checklists/llm-workbench-public-beta.md +94 -0
  4. package/.agentic/00.chat/commands/README.md +108 -0
  5. package/.agentic/00.chat/migration-plan.md +132 -0
  6. package/.agentic/00.chat/skills/session-summary.md +48 -0
  7. package/.agentic/00.chat/standards/llm-workbench-public-beta-contract.md +216 -0
  8. package/.agentic/00.chat/standards/main-refresh-conflict-types.md +358 -0
  9. package/.agentic/00.chat/workflows/README.md +40 -0
  10. package/.agentic/00.chat/workflows/bootstrap-chat-workbench-repo.md +212 -0
  11. package/.agentic/00.chat/workflows/chat-cleanup.md +102 -0
  12. package/.agentic/00.chat/workflows/chat-commit.md +56 -0
  13. package/.agentic/00.chat/workflows/chat-promote-to-main.md +169 -0
  14. package/.agentic/00.chat/workflows/chat-refresh-from-main.md +242 -0
  15. package/.agentic/00.chat/workflows/chat-reporting.md +69 -0
  16. package/.agentic/00.chat/workflows/chat-start.md +173 -0
  17. package/.agentic/00.chat/workflows/chat-upstream-reusable-lesson.md +123 -0
  18. package/.agentic/shared/standards/README.md +32 -0
  19. package/.agentic/shared/standards/upstream-repo-bootstrap.md +131 -0
  20. package/.agentic/shared/workflows/README.md +35 -0
  21. package/.agentic/shared/workflows/capability-resolution-workflow.md +189 -0
  22. package/.agentic/shared/workflows/change-shared-process.md +92 -0
  23. package/.cursor/rules/llm-workbench.mdc +17 -0
  24. package/.github/copilot-instructions.md +16 -0
  25. package/AGENTS.md +63 -0
  26. package/CLAUDE.md +16 -0
  27. package/CONTRIBUTING.md +57 -0
  28. package/LICENSE +21 -0
  29. package/LLM_WORKBENCH.md +17 -0
  30. package/README.md +98 -0
  31. package/SECURITY.md +44 -0
  32. package/bin/llm-workbench.js +672 -0
  33. package/docs/00.chat/README.md +47 -0
  34. package/docs/00.chat/llm-workbench-acceptance-matrix.md +55 -0
  35. package/docs/00.chat/script-layout.md +107 -0
  36. package/docs/adapting-to-your-repo.md +29 -0
  37. package/docs/concepts.md +38 -0
  38. package/docs/install.md +114 -0
  39. package/docs/public-beta-contract.md +45 -0
  40. package/docs/workflows.md +103 -0
  41. package/examples/minimal-repo/README.md +13 -0
  42. package/package.json +93 -0
  43. package/scripts/00.chat/README.md +46 -0
  44. package/scripts/00.chat/bootstrap/README.md +35 -0
  45. package/scripts/00.chat/bootstrap/audit-chat-bootstrap-file-set/README.md +39 -0
  46. package/scripts/00.chat/bootstrap/audit-chat-bootstrap-file-set/script.sh +213 -0
  47. package/scripts/00.chat/closeout/README.md +30 -0
  48. package/scripts/00.chat/closeout/build-closeout-prompt/README.md +35 -0
  49. package/scripts/00.chat/closeout/build-closeout-prompt/script.sh +124 -0
  50. package/scripts/00.chat/command/README.md +31 -0
  51. package/scripts/00.chat/command/close/README.md +30 -0
  52. package/scripts/00.chat/command/close/script.sh +25 -0
  53. package/scripts/00.chat/command/dispatcher/README.md +46 -0
  54. package/scripts/00.chat/command/dispatcher/script.sh +91 -0
  55. package/scripts/00.chat/command/dispatcher/smoke-test.sh +168 -0
  56. package/scripts/00.chat/command/new/README.md +32 -0
  57. package/scripts/00.chat/command/new/script.sh +28 -0
  58. package/scripts/00.chat/command/open-window/README.md +38 -0
  59. package/scripts/00.chat/command/open-window/script.sh +25 -0
  60. package/scripts/00.chat/command/package-scripts/README.md +34 -0
  61. package/scripts/00.chat/command/package-scripts/smoke-test.sh +113 -0
  62. package/scripts/00.chat/git/README.md +30 -0
  63. package/scripts/00.chat/git/cleanup-empty-chat-branches/README.md +36 -0
  64. package/scripts/00.chat/git/cleanup-empty-chat-branches/script.sh +243 -0
  65. package/scripts/00.chat/git/cleanup-empty-chat-branches/smoke-test.sh +136 -0
  66. package/scripts/00.chat/local-merge/README.md +30 -0
  67. package/scripts/00.chat/local-merge/list-active-chat-branches/README.md +29 -0
  68. package/scripts/00.chat/local-merge/list-active-chat-branches/script.sh +109 -0
  69. package/scripts/00.chat/local-merge/report-chat-branch-overlaps/README.md +29 -0
  70. package/scripts/00.chat/local-merge/report-chat-branch-overlaps/script.sh +142 -0
  71. package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/README.md +33 -0
  72. package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/script.sh +345 -0
  73. package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/smoke-test.sh +244 -0
  74. package/scripts/00.chat/main-refresh/README.md +39 -0
  75. package/scripts/00.chat/main-refresh/apply-rehearsed-refresh/README.md +32 -0
  76. package/scripts/00.chat/main-refresh/apply-rehearsed-refresh/script.sh +198 -0
  77. package/scripts/00.chat/main-refresh/check-chat-is-current-with-main/README.md +30 -0
  78. package/scripts/00.chat/main-refresh/check-chat-is-current-with-main/script.sh +121 -0
  79. package/scripts/00.chat/main-refresh/classify-conflict/README.md +39 -0
  80. package/scripts/00.chat/main-refresh/classify-conflict/script.sh +169 -0
  81. package/scripts/00.chat/main-refresh/classify-conflict/smoke-test.sh +137 -0
  82. package/scripts/00.chat/main-refresh/classify-refresh-readiness/README.md +35 -0
  83. package/scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh +171 -0
  84. package/scripts/00.chat/main-refresh/classify-refresh-readiness/smoke-test.sh +132 -0
  85. package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/README.md +34 -0
  86. package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/script.sh +124 -0
  87. package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/smoke-test.sh +257 -0
  88. package/scripts/00.chat/main-refresh/show-main-update-status/README.md +31 -0
  89. package/scripts/00.chat/main-refresh/show-main-update-status/script.sh +73 -0
  90. package/scripts/00.chat/main-refresh/verify-conflict-audit/README.md +37 -0
  91. package/scripts/00.chat/main-refresh/verify-conflict-audit/script.sh +154 -0
  92. package/scripts/00.chat/main-refresh/verify-conflict-audit/smoke-test.sh +99 -0
  93. package/scripts/00.chat/metrics/README.md +35 -0
  94. package/scripts/00.chat/metrics/data/chat-pricing.json +107 -0
  95. package/scripts/00.chat/metrics/data/chat-pricing.schema.json +63 -0
  96. package/scripts/00.chat/metrics/estimate-chat-cost/README.md +40 -0
  97. package/scripts/00.chat/metrics/estimate-chat-cost/script.js +130 -0
  98. package/scripts/00.chat/migration/README.md +30 -0
  99. package/scripts/00.chat/migration/audit-chat-layer-migration/README.md +33 -0
  100. package/scripts/00.chat/migration/audit-chat-layer-migration/script.sh +127 -0
  101. package/scripts/00.chat/recovery/README.md +30 -0
  102. package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/README.md +76 -0
  103. package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/script.sh +212 -0
  104. package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/smoke-test.sh +162 -0
  105. package/scripts/00.chat/reporting/README.md +30 -0
  106. package/scripts/00.chat/reporting/generate-commit-log-summary/README.md +35 -0
  107. package/scripts/00.chat/reporting/generate-commit-log-summary/script.sh +299 -0
  108. package/scripts/00.chat/reporting/generate-commit-log-summary/smoke-test.sh +93 -0
  109. package/scripts/00.chat/reporting/report-chat-workspaces/README.md +32 -0
  110. package/scripts/00.chat/reporting/report-chat-workspaces/script.sh +82 -0
  111. package/scripts/00.chat/session-log/README.md +33 -0
  112. package/scripts/00.chat/session-log/check-commit-prerequisites/README.md +89 -0
  113. package/scripts/00.chat/session-log/check-commit-prerequisites/script.sh +121 -0
  114. package/scripts/00.chat/session-log/check-commit-prerequisites/smoke-test.sh +119 -0
  115. package/scripts/00.chat/session-log/check-commitlog-deletions/README.md +90 -0
  116. package/scripts/00.chat/session-log/check-commitlog-deletions/script.sh +131 -0
  117. package/scripts/00.chat/session-log/check-commitlog-deletions/smoke-test.sh +123 -0
  118. package/scripts/00.chat/session-log/checkpoint-chat-session-log/README.md +98 -0
  119. package/scripts/00.chat/session-log/checkpoint-chat-session-log/script.sh +126 -0
  120. package/scripts/00.chat/session-log/paths/README.md +38 -0
  121. package/scripts/00.chat/session-log/paths/lib.sh +133 -0
  122. package/scripts/00.chat/session-log/prepare-chat-session-before-commit/README.md +90 -0
  123. package/scripts/00.chat/session-log/prepare-chat-session-before-commit/script.sh +145 -0
  124. package/scripts/00.chat/session-log/read-current-chat-log/README.md +44 -0
  125. package/scripts/00.chat/session-log/read-current-chat-log/script.sh +92 -0
  126. package/scripts/00.chat/session-log/read-current-chat-log/smoke-test.sh +127 -0
  127. package/scripts/00.chat/session-log/record-chat-commit/README.md +133 -0
  128. package/scripts/00.chat/session-log/record-chat-commit/script.sh +394 -0
  129. package/scripts/00.chat/session-log/record-chat-commit/smoke-test.sh +227 -0
  130. package/scripts/00.chat/session-log/record-main-refresh-conflict/README.md +34 -0
  131. package/scripts/00.chat/session-log/record-main-refresh-conflict/script.sh +239 -0
  132. package/scripts/00.chat/session-log/rename-current-chat-log-folder/README.md +32 -0
  133. package/scripts/00.chat/session-log/rename-current-chat-log-folder/script.sh +112 -0
  134. package/scripts/00.chat/session-log/update-chat-log/README.md +32 -0
  135. package/scripts/00.chat/session-log/update-chat-log/script.sh +294 -0
  136. package/scripts/00.chat/startup/README.md +37 -0
  137. package/scripts/00.chat/startup/auto-start-missing-session/README.md +113 -0
  138. package/scripts/00.chat/startup/auto-start-missing-session/script.sh +54 -0
  139. package/scripts/00.chat/startup/resolve-current-chat-session/README.md +57 -0
  140. package/scripts/00.chat/startup/resolve-current-chat-session/script.sh +47 -0
  141. package/scripts/00.chat/startup/resolve-current-chat-session/smoke-test.sh +130 -0
  142. package/scripts/00.chat/startup/start-chat-session/README.md +197 -0
  143. package/scripts/00.chat/startup/start-chat-session/script.sh +330 -0
  144. package/scripts/00.chat/startup/start-chat-session/smoke-test.sh +182 -0
  145. package/scripts/00.chat/startup/start-new-chat/README.md +31 -0
  146. package/scripts/00.chat/startup/start-new-chat/script.sh +29 -0
  147. package/scripts/00.chat/transcript/README.md +36 -0
  148. package/scripts/00.chat/transcript/discover-codex-session-log/README.md +32 -0
  149. package/scripts/00.chat/transcript/discover-codex-session-log/script.sh +106 -0
  150. package/scripts/00.chat/transcript/register-codex-session-log/README.md +32 -0
  151. package/scripts/00.chat/transcript/register-codex-session-log/script.sh +115 -0
  152. package/scripts/00.chat/worktree/README.md +32 -0
  153. package/scripts/00.chat/worktree/check-write-location/README.md +87 -0
  154. package/scripts/00.chat/worktree/check-write-location/script.sh +95 -0
  155. package/scripts/00.chat/worktree/dirty-worktree-check/README.md +77 -0
  156. package/scripts/00.chat/worktree/dirty-worktree-check/script.sh +93 -0
  157. package/scripts/00.chat/worktree/ensure-chat-worktree/README.md +33 -0
  158. package/scripts/00.chat/worktree/ensure-chat-worktree/script.sh +132 -0
  159. package/scripts/00.chat/worktree/open-window/README.md +34 -0
  160. package/scripts/00.chat/worktree/open-window/script.sh +131 -0
  161. package/scripts/00.chat/worktree/paths/README.md +32 -0
  162. package/scripts/00.chat/worktree/paths/lib.sh +71 -0
  163. package/scripts/01.harness/artifact-metadata/check-headers/script.sh +522 -0
  164. package/scripts/01.harness/artifact-metadata/check-headers/smoke-test.sh +48 -0
  165. package/scripts/01.harness/check-deterministic-process-drift.sh +416 -0
  166. package/scripts/01.harness/check-governed-script-command-drift.sh +184 -0
  167. package/scripts/01.harness/run-governed-script.sh +178 -0
  168. package/scripts/install.sh +503 -0
  169. package/scripts/uninstall.sh +199 -0
  170. package/tests/smoke-test-install.sh +70 -0
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.git.cleanup-empty-chat-branches
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: git
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Delete empty chat branches and matching empty session logs after dry-run
15
+ # inspection.
16
+ # portability:
17
+ # class: required
18
+ # targets:
19
+ # - llm-workbench
20
+ # used_by:
21
+ # - id: chat.workflows.chat-cleanup
22
+ # path: .agentic/00.chat/workflows/chat-cleanup.md
23
+ # - id: harness.architecture.adr.0017-organize-scripts-by-owner-domain-and-capability
24
+ # - id: chat.script.startup.start-chat-session
25
+ # path: scripts/00.chat/startup/start-chat-session/script.sh
26
+ # effects:
27
+ # - branches
28
+ # - destructive
29
+ # - writes-files
30
+
31
+ # shellcheck source=../../session-log/paths/lib.sh
32
+ source "scripts/00.chat/session-log/paths/lib.sh"
33
+
34
+ MODE="dry-run"
35
+ BASE_BRANCH=""
36
+
37
+ usage() {
38
+ cat <<'EOF'
39
+ Usage: cleanup-empty-chat-branches.sh [--dry-run|--apply] [--base <branch>]
40
+
41
+ Deletes empty chat branches and their matching empty commitLogs directories.
42
+
43
+ Safety:
44
+ - Dry-run is the default.
45
+ - --apply is required to delete branches or commitLogs.
46
+ - The current branch is never deleted.
47
+ - Branches checked out in any worktree are never deleted by this script.
48
+ - Only chat/* branches are considered.
49
+ - A branch is empty when it has no commits beyond the base branch.
50
+ - commitLogs/<yyyy>/<mmm>/<dd>/<session> or legacy commitLogs/<session> is
51
+ deleted only when it names the same branch and has no recorded commits or
52
+ retention marker.
53
+ EOF
54
+ }
55
+
56
+ log_names_branch() {
57
+ local log_file="$1"
58
+ local branch="$2"
59
+ local metadata
60
+
61
+ metadata="$(sed -n '/<!-- agentic-session/,/-->/p' "$log_file")"
62
+
63
+ if [ -n "$metadata" ]; then
64
+ printf '%s\n' "$metadata" | grep -Fxq "branch: ${branch}"
65
+ return
66
+ fi
67
+
68
+ grep -Fxq "\`${branch}\`" "$log_file"
69
+ }
70
+
71
+ log_has_recorded_commit() {
72
+ local log_file="$1"
73
+
74
+ if sed -n '/<!-- agentic-session/,/-->/s/^latest_commit_sha: //p' "$log_file" \
75
+ | grep -Eq '[^[:space:]]'; then
76
+ return 0
77
+ fi
78
+
79
+ awk '
80
+ $0 == "## Commits" {
81
+ in_section = 1
82
+ next
83
+ }
84
+ in_section && /^## / {
85
+ exit
86
+ }
87
+ in_section && /^- Commit: `[^`]+`/ {
88
+ found = 1
89
+ }
90
+ in_section && /^Commit: `[^`]+`/ {
91
+ found = 1
92
+ }
93
+ END {
94
+ exit found ? 0 : 1
95
+ }
96
+ ' "$log_file"
97
+ }
98
+
99
+ log_has_retention_marker() {
100
+ local log_file="$1"
101
+
102
+ grep -Eiq \
103
+ '^(saved|retain|retained|preserve|preserved|keep|kept): +(yes|true)$|agentic-(save|saved|retain|retained|preserve|preserved|keep|kept)-log' \
104
+ "$log_file"
105
+ }
106
+
107
+ while [ $# -gt 0 ]; do
108
+ case "$1" in
109
+ --dry-run)
110
+ MODE="dry-run"
111
+ shift
112
+ ;;
113
+ --apply)
114
+ MODE="apply"
115
+ shift
116
+ ;;
117
+ --base)
118
+ if [ $# -lt 2 ] || [ -z "${2:-}" ]; then
119
+ echo "ERROR: --base requires a branch name." >&2
120
+ exit 2
121
+ fi
122
+ BASE_BRANCH="$2"
123
+ shift 2
124
+ ;;
125
+ --help|-h)
126
+ usage
127
+ exit 0
128
+ ;;
129
+ *)
130
+ echo "ERROR: unknown argument: $1" >&2
131
+ usage >&2
132
+ exit 2
133
+ ;;
134
+ esac
135
+ done
136
+
137
+ current_branch="$(git branch --show-current)"
138
+
139
+ if [ -z "$current_branch" ]; then
140
+ echo "ERROR: current HEAD is detached; refusing cleanup." >&2
141
+ exit 1
142
+ fi
143
+
144
+ if [ -z "$BASE_BRANCH" ]; then
145
+ if git show-ref --verify --quiet refs/heads/main; then
146
+ BASE_BRANCH="main"
147
+ elif git show-ref --verify --quiet refs/heads/master; then
148
+ BASE_BRANCH="master"
149
+ else
150
+ echo "ERROR: could not infer base branch. Pass --base <branch>." >&2
151
+ exit 1
152
+ fi
153
+ fi
154
+
155
+ if ! git rev-parse --verify --quiet "$BASE_BRANCH" >/dev/null; then
156
+ echo "ERROR: base branch does not exist: $BASE_BRANCH" >&2
157
+ exit 1
158
+ fi
159
+
160
+ deleted_count=0
161
+ skipped_count=0
162
+
163
+ echo "Mode: $MODE"
164
+ echo "Base branch: $BASE_BRANCH"
165
+ echo "Current branch: $current_branch"
166
+
167
+ while IFS= read -r branch; do
168
+ case "$branch" in
169
+ chat/*)
170
+ ;;
171
+ *)
172
+ continue
173
+ ;;
174
+ esac
175
+
176
+ if [ "$branch" = "$current_branch" ]; then
177
+ echo "SKIP current branch: $branch"
178
+ skipped_count=$((skipped_count + 1))
179
+ continue
180
+ fi
181
+
182
+ if git worktree list --porcelain \
183
+ | awk -v branch="refs/heads/${branch}" '/^branch / && substr($0, 8) == branch { found = 1 } END { exit found ? 0 : 1 }'; then
184
+ echo "SKIP checked-out worktree branch: $branch"
185
+ skipped_count=$((skipped_count + 1))
186
+ continue
187
+ fi
188
+
189
+ ahead_count="$(git rev-list --count "${BASE_BRANCH}..${branch}")"
190
+ if [ "$ahead_count" != "0" ]; then
191
+ echo "SKIP non-empty branch: $branch ($ahead_count commits ahead of $BASE_BRANCH)"
192
+ skipped_count=$((skipped_count + 1))
193
+ continue
194
+ fi
195
+
196
+ session="${branch#chat/}"
197
+ log_dir="$(chat_log_dir_for_session "$session")"
198
+ log_file="${log_dir}/README.md"
199
+ delete_log="no"
200
+ keep_log_reason=""
201
+
202
+ if [ -f "$log_file" ]; then
203
+ if log_names_branch "$log_file" "$branch"; then
204
+ if log_has_recorded_commit "$log_file"; then
205
+ keep_log_reason="recorded commits"
206
+ elif log_has_retention_marker "$log_file"; then
207
+ keep_log_reason="retention marker"
208
+ else
209
+ delete_log="yes"
210
+ fi
211
+ else
212
+ echo "WARN log branch mismatch, leaving log in place: $log_dir"
213
+ fi
214
+ elif [ -e "$log_dir" ]; then
215
+ echo "WARN commit log path exists without README, leaving in place: $log_dir"
216
+ fi
217
+
218
+ if [ "$MODE" = "dry-run" ]; then
219
+ echo "DRY-RUN delete branch: $branch"
220
+ if [ "$delete_log" = "yes" ]; then
221
+ echo "DRY-RUN delete log: $log_dir"
222
+ elif [ -n "$keep_log_reason" ]; then
223
+ echo "DRY-RUN keep log (${keep_log_reason}): $log_dir"
224
+ fi
225
+ else
226
+ git branch -D "$branch"
227
+ if [ "$delete_log" = "yes" ]; then
228
+ git rm -r --ignore-unmatch "$log_dir" >/dev/null
229
+ rm -rf "$log_dir"
230
+ fi
231
+ echo "Deleted empty branch: $branch"
232
+ if [ "$delete_log" = "yes" ]; then
233
+ echo "Deleted matching log: $log_dir"
234
+ elif [ -n "$keep_log_reason" ]; then
235
+ echo "Kept matching log (${keep_log_reason}): $log_dir"
236
+ fi
237
+ fi
238
+
239
+ deleted_count=$((deleted_count + 1))
240
+ done < <(git branch --format='%(refname:short)')
241
+
242
+ echo "Empty chat branches found: $deleted_count"
243
+ echo "Branches skipped: $skipped_count"
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.git.cleanup-empty-chat-branches.smoke-test
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: git
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Smoke test empty chat branch and session log cleanup safety.
15
+ # portability:
16
+ # class: reusable
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: harness.architecture.adr.0017-organize-scripts-by-owner-domain-and-capability
23
+ # effects:
24
+ # - branches
25
+ # - commits
26
+ # - destructive
27
+ # - writes-files
28
+
29
+ SOURCE_ROOT="$(git rev-parse --show-toplevel)"
30
+ TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/cleanup-empty-chat-branches-smoke.XXXXXX")"
31
+
32
+ cleanup() {
33
+ rm -rf "$TMP_ROOT"
34
+ }
35
+
36
+ trap cleanup EXIT
37
+
38
+ fail() {
39
+ echo "ERROR: $*" >&2
40
+ exit 1
41
+ }
42
+
43
+ REPO="$TMP_ROOT/repo"
44
+ mkdir -p "$REPO/scripts/00.chat/git/cleanup-empty-chat-branches" "$REPO/scripts/00.chat/session-log/paths"
45
+ cp "$SOURCE_ROOT/scripts/00.chat/git/cleanup-empty-chat-branches/script.sh" "$REPO/scripts/00.chat/git/cleanup-empty-chat-branches/script.sh"
46
+ cp "$SOURCE_ROOT/scripts/00.chat/session-log/paths/lib.sh" "$REPO/scripts/00.chat/session-log/paths/lib.sh"
47
+
48
+ git -C "$REPO" init -q -b main
49
+ git -C "$REPO" config user.name "Smoke Test"
50
+ git -C "$REPO" config user.email "smoke@example.invalid"
51
+
52
+ printf 'base\n' > "$REPO/base.txt"
53
+ git -C "$REPO" add base.txt scripts/00.chat/git/cleanup-empty-chat-branches/script.sh scripts/00.chat/session-log/paths/lib.sh
54
+ git -C "$REPO" commit -q -m "initial"
55
+
56
+ COMMITTED_SESSION="2026-06-16-07-18-committed-log"
57
+ COMMITTED_BRANCH="chat/$COMMITTED_SESSION"
58
+ COMMITTED_LOG="$REPO/commitLogs/2026/jun/16/$COMMITTED_SESSION/README.md"
59
+
60
+ git -C "$REPO" switch -q -c "$COMMITTED_BRANCH"
61
+ printf 'work\n' > "$REPO/work.txt"
62
+ git -C "$REPO" add work.txt
63
+ git -C "$REPO" commit -q -m "committed chat work"
64
+ COMMITTED_SHA="$(git -C "$REPO" rev-parse --short HEAD)"
65
+
66
+ git -C "$REPO" switch -q main
67
+ git -C "$REPO" merge -q --ff-only "$COMMITTED_BRANCH"
68
+
69
+ mkdir -p "$(dirname "$COMMITTED_LOG")"
70
+ cat > "$COMMITTED_LOG" <<EOF
71
+ # Chat Session: committed log
72
+
73
+ <!-- agentic-session
74
+ id: $COMMITTED_SESSION
75
+ branch: $COMMITTED_BRANCH
76
+ latest_commit_sha: $COMMITTED_SHA
77
+ -->
78
+
79
+ ## Commits
80
+
81
+ - Commit: \`$COMMITTED_SHA\`
82
+ EOF
83
+
84
+ EMPTY_SESSION="2026-06-16-07-19-empty-log"
85
+ EMPTY_BRANCH="chat/$EMPTY_SESSION"
86
+ EMPTY_LOG="$REPO/commitLogs/2026/jun/16/$EMPTY_SESSION/README.md"
87
+
88
+ git -C "$REPO" branch "$EMPTY_BRANCH"
89
+ mkdir -p "$(dirname "$EMPTY_LOG")"
90
+ cat > "$EMPTY_LOG" <<EOF
91
+ # Chat Session: empty log
92
+
93
+ <!-- agentic-session
94
+ id: $EMPTY_SESSION
95
+ branch: $EMPTY_BRANCH
96
+ latest_commit_sha:
97
+ -->
98
+
99
+ ## Commits
100
+
101
+ - None recorded yet.
102
+ EOF
103
+
104
+ git -C "$REPO" add "$COMMITTED_LOG" "$EMPTY_LOG"
105
+ git -C "$REPO" commit -q -m "add chat logs"
106
+
107
+ (
108
+ cd "$REPO"
109
+ bash scripts/00.chat/git/cleanup-empty-chat-branches/script.sh --apply
110
+ ) > "$TMP_ROOT/cleanup.out" 2> "$TMP_ROOT/cleanup.err"
111
+
112
+ if git -C "$REPO" show-ref --verify --quiet "refs/heads/$COMMITTED_BRANCH"; then
113
+ fail "merged committed branch was not deleted"
114
+ fi
115
+
116
+ if [ ! -f "$COMMITTED_LOG" ]; then
117
+ fail "commit log with recorded commit was deleted"
118
+ fi
119
+
120
+ if git -C "$REPO" show-ref --verify --quiet "refs/heads/$EMPTY_BRANCH"; then
121
+ fail "empty branch was not deleted"
122
+ fi
123
+
124
+ if [ -e "$EMPTY_LOG" ]; then
125
+ fail "empty unsaved commit log was not deleted"
126
+ fi
127
+
128
+ if ! grep -q "Kept matching log (recorded commits)" "$TMP_ROOT/cleanup.out"; then
129
+ fail "cleanup did not report keeping the committed log"
130
+ fi
131
+
132
+ if ! grep -q "Deleted matching log" "$TMP_ROOT/cleanup.out"; then
133
+ fail "cleanup did not report deleting the empty log"
134
+ fi
135
+
136
+ echo "cleanup empty chat branches smoke test passed."
@@ -0,0 +1,30 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.local-merge.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: local-merge
8
+ disciplines:
9
+ - agentic
10
+ kind: script-domain-readme
11
+ purpose: Explain local merge readiness and visibility scripts.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.workflows.chat-promote-to-main
18
+ path: .agentic/00.chat/workflows/chat-promote-to-main.md
19
+ - id: chat.script.local-merge.verify-chat-ready-to-merge-local-main.readme
20
+ path: scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/README.md
21
+ -->
22
+ # Local Merge Scripts
23
+
24
+ Local merge scripts help decide whether chat work can be integrated into local
25
+ `main`. They are local coordination tools, not push tools.
26
+
27
+ Use this domain when checking whether a chat branch is current with `main`,
28
+ whether related chat branches are active, or whether overlapping chat work
29
+ needs human attention before promotion.
30
+
@@ -0,0 +1,29 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.local-merge.list-active-chat-branches.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: local-merge
8
+ disciplines:
9
+ - agentic
10
+ kind: guide
11
+ purpose: Explain the read-only report that lists active chat branches before local
12
+ merge decisions.
13
+ portability:
14
+ class: required
15
+ targets:
16
+ - llm-workbench
17
+ used_by:
18
+ - id: chat.script.local-merge.list-active-chat-branches
19
+ path: scripts/00.chat/local-merge/list-active-chat-branches/script.sh
20
+ -->
21
+ # List Active Chat Branches
22
+
23
+ This capability answers: which chat branches are active, and how do they relate
24
+ to local `main`?
25
+
26
+ It prints chat branches, ahead/behind relation to the base branch, and available
27
+ session metadata such as layer, mode, status, and task. It is read-only and is
28
+ useful before choosing whether to refresh, merge, clean up, or inspect a chat
29
+ branch.
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.local-merge.list-active-chat-branches
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: local-merge
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: List active chat branches with session metadata and relation to local main.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.workflows.chat-refresh-from-main
21
+ # path: .agentic/00.chat/workflows/chat-refresh-from-main.md
22
+ # - id: harness.script.run-governed-script
23
+ # path: scripts/01.harness/run-governed-script.sh
24
+ # effects:
25
+ # - read-only
26
+
27
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
28
+ REPO_ROOT="$(cd "$REPO_ROOT" && pwd -P)"
29
+
30
+ # shellcheck source=../../session-log/paths/lib.sh
31
+ source "$REPO_ROOT/scripts/00.chat/session-log/paths/lib.sh"
32
+
33
+ BASE_BRANCH="${1:-main}"
34
+
35
+ if ! git show-ref --verify --quiet "refs/heads/${BASE_BRANCH}"; then
36
+ echo "ERROR: base branch does not exist: ${BASE_BRANCH}" >&2
37
+ exit 1
38
+ fi
39
+
40
+ current_branch="$(git branch --show-current)"
41
+ tmp_dir="$(mktemp -d)"
42
+
43
+ cleanup() {
44
+ rm -rf "$tmp_dir"
45
+ }
46
+
47
+ trap cleanup EXIT
48
+
49
+ if [ -z "$current_branch" ]; then
50
+ echo "ERROR: current HEAD is detached." >&2
51
+ exit 1
52
+ fi
53
+
54
+ printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
55
+ "branch" "relation" "behind" "ahead" "layer" "mode" "status" "task"
56
+
57
+ git branch --format='%(refname:short)' | while IFS= read -r branch; do
58
+ case "$branch" in
59
+ chat/*)
60
+ ;;
61
+ *)
62
+ continue
63
+ ;;
64
+ esac
65
+
66
+ session_id="${branch#chat/}"
67
+ log_file="$(chat_log_file_for_session "$session_id")"
68
+ branch_log_file="${tmp_dir}/$(printf '%s\n' "$session_id" | tr -c 'A-Za-z0-9._-' '_').README.md"
69
+
70
+ if [ -f "$log_file" ]; then
71
+ layer="$(chat_log_metadata_value "$log_file" "layer")"
72
+ mode="$(chat_log_metadata_value "$log_file" "mode")"
73
+ status="$(chat_log_metadata_value "$log_file" "status")"
74
+ task="$(chat_log_metadata_value "$log_file" "task")"
75
+ elif git cat-file -e "${branch}:commitLogs/${session_id}/README.md" 2>/dev/null; then
76
+ git show "${branch}:commitLogs/${session_id}/README.md" > "$branch_log_file"
77
+ layer="$(chat_log_metadata_value "$branch_log_file" "layer")"
78
+ mode="$(chat_log_metadata_value "$branch_log_file" "mode")"
79
+ status="$(chat_log_metadata_value "$branch_log_file" "status")"
80
+ task="$(chat_log_metadata_value "$branch_log_file" "task")"
81
+ else
82
+ layer="missing-log"
83
+ mode="missing-log"
84
+ status="missing-log"
85
+ task="missing session log: ${log_file}"
86
+ fi
87
+
88
+ counts="$(git rev-list --left-right --count "${BASE_BRANCH}...${branch}")"
89
+ behind="${counts%% *}"
90
+ ahead="${counts##* }"
91
+
92
+ if [ "$behind" = "0" ] && [ "$ahead" = "0" ]; then
93
+ relation="even"
94
+ elif [ "$behind" = "0" ]; then
95
+ relation="ahead"
96
+ elif [ "$ahead" = "0" ]; then
97
+ relation="behind"
98
+ else
99
+ relation="diverged"
100
+ fi
101
+
102
+ if [ "$branch" = "$current_branch" ]; then
103
+ branch="${branch}*"
104
+ fi
105
+
106
+ printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
107
+ "$branch" "$relation" "$behind" "$ahead" \
108
+ "${layer:-unknown}" "${mode:-unknown}" "${status:-unknown}" "${task:-}"
109
+ done
@@ -0,0 +1,29 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.local-merge.report-chat-branch-overlaps.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: local-merge
8
+ disciplines:
9
+ - agentic
10
+ kind: guide
11
+ purpose: Explain the read-only report that finds changed-path overlap between chat
12
+ branches.
13
+ portability:
14
+ class: required
15
+ targets:
16
+ - llm-workbench
17
+ used_by:
18
+ - id: chat.script.local-merge.report-chat-branch-overlaps
19
+ path: scripts/00.chat/local-merge/report-chat-branch-overlaps/script.sh
20
+ -->
21
+ # Report Chat Branch Overlaps
22
+
23
+ This capability answers: which chat branches or active worktree changes touch
24
+ the same files?
25
+
26
+ It builds changed-path sets for local chat branches relative to a base branch,
27
+ adds the current worktree's unstaged, staged, and untracked paths, and reports
28
+ overlaps between those sets. It is read-only and helps identify merge risk
29
+ before refresh or local merge work.