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,95 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.worktree.check-write-location
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: worktree
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Enforce task writes from chat-owned worktrees instead of the root integration
15
+ # worktree.
16
+ # portability:
17
+ # class: required
18
+ # targets:
19
+ # - llm-workbench
20
+ # used_by:
21
+ # - id: chat.script.worktree.check-write-location.readme
22
+ # path: scripts/00.chat/worktree/check-write-location/README.md
23
+ # effects:
24
+ # - read-only
25
+ usage() {
26
+ cat <<'EOF'
27
+ Usage:
28
+ check-write-location.sh [--allow-root-maintenance]
29
+
30
+ Fails when task writes would run from the root integration worktree. Chat task
31
+ work must run from that chat branch's canonical chat-owned worktree.
32
+
33
+ Set AGENTIC_ALLOW_ROOT_WRITE=1 only for explicit root maintenance operations.
34
+ EOF
35
+ }
36
+
37
+ ALLOW_ROOT_MAINTENANCE="no"
38
+
39
+ while [ $# -gt 0 ]; do
40
+ case "$1" in
41
+ --allow-root-maintenance)
42
+ ALLOW_ROOT_MAINTENANCE="yes"
43
+ shift
44
+ ;;
45
+ -h|--help)
46
+ usage
47
+ exit 0
48
+ ;;
49
+ *)
50
+ usage >&2
51
+ exit 2
52
+ ;;
53
+ esac
54
+ done
55
+
56
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
57
+ REPO_ROOT="$(cd "$REPO_ROOT" && pwd -P)"
58
+
59
+ # shellcheck source=../paths/lib.sh
60
+ source "$REPO_ROOT/scripts/00.chat/worktree/paths/lib.sh"
61
+
62
+ PRIMARY_PATH="$(chat_worktree_primary_path)"
63
+ PRIMARY_PATH="$(cd "$PRIMARY_PATH" && pwd -P)"
64
+ BRANCH="$(git -C "$REPO_ROOT" branch --show-current)"
65
+
66
+ if [ "$REPO_ROOT" = "$PRIMARY_PATH" ]; then
67
+ if [ "${AGENTIC_ALLOW_ROOT_WRITE:-}" = "1" ] || [ "$ALLOW_ROOT_MAINTENANCE" = "yes" ]; then
68
+ echo "root-maintenance-allowed"
69
+ exit 0
70
+ fi
71
+
72
+ echo "ERROR: refusing task write in root integration worktree: $REPO_ROOT" >&2
73
+ echo "Use the chat-owned worktree for chat work." >&2
74
+ exit 1
75
+ fi
76
+
77
+ case "$BRANCH" in
78
+ chat/*) ;;
79
+ *)
80
+ echo "ERROR: current worktree is not on a chat branch: $BRANCH" >&2
81
+ exit 1
82
+ ;;
83
+ esac
84
+
85
+ EXPECTED_PATH="$(chat_worktree_path_for_branch "$PRIMARY_PATH" "$BRANCH")"
86
+ EXPECTED_PATH="$(cd "$EXPECTED_PATH" 2>/dev/null && pwd -P || printf '%s\n' "$EXPECTED_PATH")"
87
+
88
+ if [ "$REPO_ROOT" != "$EXPECTED_PATH" ]; then
89
+ echo "ERROR: current chat branch is not in its canonical chat worktree." >&2
90
+ echo "Current: $REPO_ROOT" >&2
91
+ echo "Expected: $EXPECTED_PATH" >&2
92
+ exit 1
93
+ fi
94
+
95
+ echo "chat-worktree"
@@ -0,0 +1,77 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.worktree.dirty-worktree-check.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: worktree
8
+ disciplines:
9
+ - agentic
10
+ kind: capability-readme
11
+ purpose: Explain clean, dirty, and session-bookkeeping-only worktree checks.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.script.worktree.dirty-worktree-check
18
+ path: scripts/00.chat/worktree/dirty-worktree-check/script.sh
19
+ - id: harness.architecture.adr.0017-organize-scripts-by-owner-domain-and-capability
20
+ -->
21
+ # Dirty Worktree Check
22
+
23
+ `script.sh` reports whether the current worktree is clean enough for the next
24
+ governed step.
25
+
26
+ It is intentionally small: it answers one question before startup, refresh,
27
+ commit, or promotion workflows continue.
28
+
29
+ ## Modes
30
+
31
+ Default mode:
32
+
33
+ ```bash
34
+ bash scripts/00.chat/worktree/dirty-worktree-check/script.sh
35
+ ```
36
+
37
+ Outputs:
38
+
39
+ - `clean` and exits `0` when there are no Git changes
40
+ - `dirty` and exits non-zero when any tracked, staged, or untracked file is
41
+ dirty
42
+
43
+ Session-bookkeeping mode:
44
+
45
+ ```bash
46
+ bash scripts/00.chat/worktree/dirty-worktree-check/script.sh --allow-session-bookkeeping
47
+ ```
48
+
49
+ This mode allows dirt only when all dirty paths are the current chat session log.
50
+ It prints `bookkeeping-only` and exits `0` in that case.
51
+
52
+ ## Mental Model
53
+
54
+ Dirty state is not always bad. Sometimes the only dirty file is the session log
55
+ after a task commit has been recorded. That is expected bookkeeping and can be
56
+ checkpointed separately.
57
+
58
+ Other dirty state is ambiguous. This helper stops workflows before they
59
+ accidentally continue across unreviewed or unrelated changes.
60
+
61
+ ## What This Does Not Do
62
+
63
+ - It does not clean the worktree.
64
+ - It does not stage files.
65
+ - It does not commit session bookkeeping.
66
+ - It does not decide whether unrelated dirt is safe.
67
+ - It does not inspect file contents beyond identifying dirty paths.
68
+
69
+ ## Compatibility
70
+
71
+ The old shared path remains available:
72
+
73
+ ```bash
74
+ scripts/00.chat/worktree/dirty-worktree-check/script.sh
75
+ ```
76
+
77
+ That file is now a compatibility wrapper around the canonical implementation.
@@ -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.worktree.dirty-worktree-check
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: worktree
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Check worktree cleanliness with optional current-session bookkeeping tolerance.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.script.worktree.dirty-worktree-check.readme
21
+ # path: scripts/00.chat/worktree/dirty-worktree-check/README.md
22
+ # effects:
23
+ # - read-only
24
+ usage() {
25
+ cat <<'EOF'
26
+ Usage:
27
+ dirty-worktree-check.sh [--allow-session-bookkeeping]
28
+
29
+ Checks whether the worktree is clean. With --allow-session-bookkeeping, changes
30
+ limited to the current chat session log are accepted.
31
+ EOF
32
+ }
33
+
34
+ ALLOW_SESSION_BOOKKEEPING="no"
35
+
36
+ if [ $# -gt 1 ]; then
37
+ usage >&2
38
+ exit 2
39
+ fi
40
+
41
+ if [ $# -eq 1 ]; then
42
+ case "$1" in
43
+ --allow-session-bookkeeping)
44
+ ALLOW_SESSION_BOOKKEEPING="yes"
45
+ ;;
46
+ -h|--help)
47
+ usage
48
+ exit 0
49
+ ;;
50
+ *)
51
+ usage >&2
52
+ exit 2
53
+ ;;
54
+ esac
55
+ fi
56
+
57
+ if [[ -z "$(git status --porcelain)" ]]; then
58
+ echo "clean"
59
+ exit 0
60
+ fi
61
+
62
+ if [ "$ALLOW_SESSION_BOOKKEEPING" = "yes" ]; then
63
+ # shellcheck source=../../session-log/paths/lib.sh
64
+ source "scripts/00.chat/session-log/paths/lib.sh"
65
+
66
+ BRANCH="$(git branch --show-current)"
67
+
68
+ if SESSION_ID="$(chat_session_id_from_branch "$BRANCH")"; then
69
+ LOG_FILE="$(chat_log_file_for_session "$SESSION_ID")"
70
+ MIXED_FILES="$(
71
+ {
72
+ git diff --name-only
73
+ git diff --cached --name-only
74
+ git ls-files --others --exclude-standard
75
+ } | awk \
76
+ -v log_file="$LOG_FILE" \
77
+ '$0 != "" && $0 != log_file' \
78
+ | sort -u
79
+ )"
80
+
81
+ if [ -z "${MIXED_FILES// }" ]; then
82
+ echo "bookkeeping-only"
83
+ exit 0
84
+ fi
85
+ fi
86
+ fi
87
+
88
+ if [[ -n "$(git status --porcelain)" ]]; then
89
+ echo "dirty"
90
+ exit 1
91
+ fi
92
+
93
+ echo "clean"
@@ -0,0 +1,33 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.worktree.ensure-chat-worktree.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: worktree
8
+ disciplines:
9
+ - agentic
10
+ kind: capability-readme
11
+ purpose: Explain creating or verifying the chat-owned worktree for a session.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.script.startup.start-chat-session
18
+ path: scripts/00.chat/startup/start-chat-session/script.sh
19
+ - id: chat.script.worktree.ensure-chat-worktree
20
+ path: scripts/00.chat/worktree/ensure-chat-worktree/script.sh
21
+ -->
22
+ # Ensure Chat Worktree
23
+
24
+ `script.sh` creates or verifies the canonical worktree for the chat branch named
25
+ in a session log.
26
+
27
+ Startup uses this so the session branch has a separate physical checkout for
28
+ task work. If the worktree already exists, the script verifies that it belongs
29
+ to the same repository and is on the expected branch.
30
+
31
+ The script prints the worktree path. It does not stage task files, commit, merge,
32
+ push, or clean existing work.
33
+
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.worktree.ensure-chat-worktree
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: worktree
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Create or verify the chat-owned worktree for a session branch.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.workflows.chat-start
21
+ # path: .agentic/00.chat/workflows/chat-start.md
22
+ # - id: chat.script.startup.start-chat-session
23
+ # path: scripts/00.chat/startup/start-chat-session/script.sh
24
+ # effects:
25
+ # - worktrees
26
+ usage() {
27
+ cat <<'EOF'
28
+ Usage:
29
+ ensure-chat-worktree.sh <session-log>
30
+
31
+ Creates or verifies the canonical chat-owned worktree for the chat branch named
32
+ in a session log. The root worktree is an integration console; task work should
33
+ happen in the returned chat worktree path.
34
+ EOF
35
+ }
36
+
37
+ if [ $# -ne 1 ] || [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
38
+ usage >&2
39
+ exit 2
40
+ fi
41
+
42
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
43
+ REPO_ROOT="$(cd "$REPO_ROOT" && pwd -P)"
44
+
45
+ # shellcheck source=../paths/lib.sh
46
+ source "$REPO_ROOT/scripts/00.chat/worktree/paths/lib.sh"
47
+
48
+ SESSION_LOG="$1"
49
+ case "$SESSION_LOG" in
50
+ /*) ;;
51
+ *) SESSION_LOG="$REPO_ROOT/$SESSION_LOG" ;;
52
+ esac
53
+
54
+ if [ ! -f "$SESSION_LOG" ]; then
55
+ echo "ERROR: missing chat session log: $SESSION_LOG" >&2
56
+ exit 1
57
+ fi
58
+
59
+ BRANCH="$(chat_worktree_metadata_value "$SESSION_LOG" "branch")"
60
+ if [ -z "${BRANCH// }" ]; then
61
+ echo "ERROR: session log is missing branch metadata: $SESSION_LOG" >&2
62
+ exit 1
63
+ fi
64
+
65
+ case "$BRANCH" in
66
+ chat/*) ;;
67
+ *)
68
+ echo "ERROR: session branch is not a chat branch: $BRANCH" >&2
69
+ exit 1
70
+ ;;
71
+ esac
72
+
73
+ if ! git -C "$REPO_ROOT" show-ref --verify --quiet "refs/heads/${BRANCH}"; then
74
+ echo "ERROR: session branch does not exist locally: $BRANCH" >&2
75
+ exit 1
76
+ fi
77
+
78
+ WORKTREE_PATH="$(chat_worktree_path_for_branch "$REPO_ROOT" "$BRANCH")"
79
+ WORKTREE_ROOT="${WORKTREE_PATH%/*}"
80
+ PRIMARY_PATH="$(chat_worktree_primary_path)"
81
+ PRIMARY_PATH="$(cd "$PRIMARY_PATH" && pwd -P)"
82
+
83
+ branch_worktrees="$(
84
+ git -C "$REPO_ROOT" worktree list --porcelain \
85
+ | awk -v branch="refs/heads/${BRANCH}" '
86
+ /^worktree / { path = substr($0, 10) }
87
+ /^branch / && substr($0, 8) == branch { print path }
88
+ '
89
+ )"
90
+
91
+ while IFS= read -r branch_worktree; do
92
+ if [ -z "${branch_worktree// }" ]; then
93
+ continue
94
+ fi
95
+
96
+ branch_worktree="$(cd "$branch_worktree" && pwd -P)"
97
+
98
+ if [ "$branch_worktree" = "$WORKTREE_PATH" ]; then
99
+ continue
100
+ fi
101
+
102
+ if [ "$branch_worktree" = "$PRIMARY_PATH" ]; then
103
+ echo "ERROR: session branch is checked out in the root integration worktree:" >&2
104
+ echo "$branch_worktree" >&2
105
+ echo "Switch the root worktree away from the chat branch before creating the chat-owned worktree." >&2
106
+ exit 1
107
+ fi
108
+
109
+ echo "ERROR: session branch is already checked out in another worktree:" >&2
110
+ echo "$branch_worktree" >&2
111
+ echo "Expected chat-owned worktree:" >&2
112
+ echo "$WORKTREE_PATH" >&2
113
+ exit 1
114
+ done <<< "$branch_worktrees"
115
+
116
+ if [ -e "$WORKTREE_PATH" ]; then
117
+ if ! git -C "$WORKTREE_PATH" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
118
+ echo "ERROR: chat worktree path exists but is not a git worktree: $WORKTREE_PATH" >&2
119
+ exit 1
120
+ fi
121
+
122
+ current_branch="$(git -C "$WORKTREE_PATH" branch --show-current)"
123
+ if [ "$current_branch" != "$BRANCH" ]; then
124
+ echo "ERROR: chat worktree is on '$current_branch', expected '$BRANCH': $WORKTREE_PATH" >&2
125
+ exit 1
126
+ fi
127
+ else
128
+ mkdir -p "$WORKTREE_ROOT"
129
+ git -C "$REPO_ROOT" worktree add --quiet "$WORKTREE_PATH" "$BRANCH"
130
+ fi
131
+
132
+ printf '%s\n' "$WORKTREE_PATH"
@@ -0,0 +1,34 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.worktree.open-window.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: worktree
8
+ disciplines:
9
+ - agentic
10
+ kind: capability-readme
11
+ purpose: Explain opening a VS Code window for a chat-owned worktree.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.script.worktree.open-window
18
+ path: scripts/00.chat/worktree/open-window/script.sh
19
+ - id: chat.script.command.open-window
20
+ path: scripts/00.chat/command/open-window/script.sh
21
+ -->
22
+ # Open Window Worktree Capability
23
+
24
+ `script.sh` opens a new VS Code window for a chat-owned worktree.
25
+
26
+ With no argument, it reads the current chat branch session log and opens the
27
+ `worktree` metadata path. With one argument, it accepts either a worktree path
28
+ or a session-log `README.md` path.
29
+
30
+ The command is best-effort. If the `code` CLI is unavailable or cannot open the
31
+ window, the script prints a warning and exits successfully so chat startup does
32
+ not fail after branch and worktree creation.
33
+
34
+ Set `CHAT_OPEN_WORKTREE_WINDOW=skip` to suppress the window open.
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.worktree.open-window
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: worktree
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Open a VS Code window for a chat-owned worktree.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.script.startup.start-chat-session
21
+ # path: scripts/00.chat/startup/start-chat-session/script.sh
22
+ # - id: chat.script.command.open-window
23
+ # path: scripts/00.chat/command/open-window/script.sh
24
+ # effects:
25
+ # - read-only
26
+ usage() {
27
+ cat <<'EOF'
28
+ Usage: open-window [worktree-path|session-log]
29
+
30
+ Opens the current chat worktree in a new VS Code window. If an argument is
31
+ provided, it may be a worktree path or a session-log README.md path.
32
+ EOF
33
+ }
34
+
35
+ # shellcheck source=../../session-log/paths/lib.sh
36
+ source "scripts/00.chat/session-log/paths/lib.sh"
37
+
38
+ target="${1:-}"
39
+
40
+ if [ "${target:-}" = "-h" ] || [ "${target:-}" = "--help" ]; then
41
+ usage
42
+ exit 0
43
+ fi
44
+
45
+ if [ "$#" -gt 1 ]; then
46
+ usage >&2
47
+ exit 2
48
+ fi
49
+
50
+ resolve_current_worktree() {
51
+ local branch session_id log_file worktree
52
+
53
+ branch="$(git branch --show-current)"
54
+ if ! session_id="$(chat_session_id_from_branch "$branch")"; then
55
+ echo "ERROR: current branch is not a chat branch: $branch" >&2
56
+ echo "Pass a chat worktree path or session log path when running from the root worktree." >&2
57
+ return 1
58
+ fi
59
+
60
+ log_file="$(chat_log_file_for_session "$session_id")"
61
+ if [ ! -f "$log_file" ]; then
62
+ echo "ERROR: missing chat log: $log_file" >&2
63
+ return 1
64
+ fi
65
+
66
+ worktree="$(chat_log_metadata_value "$log_file" "worktree")"
67
+ if [ -z "${worktree// }" ]; then
68
+ echo "ERROR: session log is missing worktree metadata: $log_file" >&2
69
+ return 1
70
+ fi
71
+
72
+ printf '%s\n' "$worktree"
73
+ }
74
+
75
+ resolve_target() {
76
+ local candidate="$1"
77
+
78
+ if [ -z "${candidate// }" ]; then
79
+ resolve_current_worktree
80
+ return
81
+ fi
82
+
83
+ if [ -f "$candidate" ]; then
84
+ chat_log_metadata_value "$candidate" "worktree"
85
+ return
86
+ fi
87
+
88
+ printf '%s\n' "$candidate"
89
+ }
90
+
91
+ WORKTREE_PATH="$(resolve_target "$target")"
92
+
93
+ if [ -z "${WORKTREE_PATH// }" ]; then
94
+ echo "ERROR: could not resolve chat worktree path." >&2
95
+ exit 1
96
+ fi
97
+
98
+ if [ ! -d "$WORKTREE_PATH" ]; then
99
+ echo "ERROR: chat worktree path does not exist: $WORKTREE_PATH" >&2
100
+ exit 1
101
+ fi
102
+
103
+ if ! git -C "$WORKTREE_PATH" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
104
+ echo "ERROR: path is not a git worktree: $WORKTREE_PATH" >&2
105
+ exit 1
106
+ fi
107
+
108
+ case "${CHAT_OPEN_WORKTREE_WINDOW:-open}" in
109
+ open|"")
110
+ ;;
111
+ 0|false|no|skip)
112
+ echo "Skipping VS Code window open: $WORKTREE_PATH"
113
+ exit 0
114
+ ;;
115
+ *)
116
+ echo "ERROR: invalid CHAT_OPEN_WORKTREE_WINDOW value: ${CHAT_OPEN_WORKTREE_WINDOW}" >&2
117
+ echo "Use open, skip, 0, false, or no." >&2
118
+ exit 2
119
+ ;;
120
+ esac
121
+
122
+ if ! command -v code >/dev/null 2>&1; then
123
+ echo "WARNING: VS Code CLI 'code' not found; cannot open chat worktree window: $WORKTREE_PATH" >&2
124
+ exit 0
125
+ fi
126
+
127
+ if code --new-window "$WORKTREE_PATH"; then
128
+ echo "Opened VS Code window: $WORKTREE_PATH"
129
+ else
130
+ echo "WARNING: VS Code CLI failed to open chat worktree window: $WORKTREE_PATH" >&2
131
+ fi
@@ -0,0 +1,32 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.worktree.paths.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: worktree
8
+ disciplines:
9
+ - agentic
10
+ kind: capability-readme
11
+ purpose: Explain helper functions for chat worktree paths and metadata.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.script.worktree.paths.lib
18
+ path: scripts/00.chat/worktree/paths/lib.sh
19
+ - id: chat.script.worktree.ensure-chat-worktree
20
+ path: scripts/00.chat/worktree/ensure-chat-worktree/script.sh
21
+ -->
22
+ # Worktree Paths
23
+
24
+ `lib.sh` provides shell helper functions for deriving canonical chat worktree
25
+ paths.
26
+
27
+ The helpers make worktree paths deterministic from the repository root and chat
28
+ branch name. That lets startup, reporting, recovery, and verification agree on
29
+ where a chat-owned worktree should live.
30
+
31
+ This library is read-only. It does not create worktrees or change branches.
32
+
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # agentic-artifact:
4
+ # schema: agentic-artifact/v2
5
+ # id: chat.script.worktree.paths.lib
6
+ # version: 1
7
+ # status: active
8
+ # layer: 00.chat
9
+ # domain: worktree
10
+ # disciplines:
11
+ # - agentic
12
+ # kind: script
13
+ # purpose: Provide canonical chat worktree path and metadata helper functions.
14
+ # portability:
15
+ # class: required
16
+ # targets:
17
+ # - llm-workbench
18
+ # used_by:
19
+ # - id: chat.script.reporting.report-chat-workspaces
20
+ # path: scripts/00.chat/reporting/report-chat-workspaces/script.sh
21
+ # - id: chat.script.startup.start-chat-session
22
+ # path: scripts/00.chat/startup/start-chat-session/script.sh
23
+ # - id: chat.script.worktree.ensure-chat-worktree
24
+ # path: scripts/00.chat/worktree/ensure-chat-worktree/script.sh
25
+ # effects:
26
+ # - read-only
27
+ chat_worktree_repo_root() {
28
+ local repo_root
29
+
30
+ repo_root="$(git rev-parse --show-toplevel)"
31
+ cd "$repo_root" && pwd -P
32
+ }
33
+
34
+ chat_worktree_repo_key() {
35
+ local repo_root="$1"
36
+
37
+ printf '%s' "$repo_root" | cksum | awk '{print $1}'
38
+ }
39
+
40
+ chat_worktree_safe_name() {
41
+ printf '%s' "$1" | sed 's#[^A-Za-z0-9._-]#_#g'
42
+ }
43
+
44
+ chat_worktree_root_for_repo() {
45
+ local repo_root="$1"
46
+ local repo_slug
47
+
48
+ repo_slug="$(chat_worktree_safe_name "$(basename "$repo_root")")"
49
+ printf '%s\n' "${AGENTIC_CHAT_WORKTREE_ROOT:-${TMPDIR:-/tmp}/agentic-chat-worktrees/${repo_slug}-$(chat_worktree_repo_key "$repo_root")}"
50
+ }
51
+
52
+ chat_worktree_path_for_branch() {
53
+ local repo_root="$1"
54
+ local branch="$2"
55
+ local branch_slug branch_key
56
+
57
+ branch_slug="$(chat_worktree_safe_name "$branch")"
58
+ branch_key="$(printf '%s' "$branch" | cksum | awk '{print $1}')"
59
+ printf '%s/%s-%s\n' "$(chat_worktree_root_for_repo "$repo_root")" "$branch_slug" "$branch_key"
60
+ }
61
+
62
+ chat_worktree_primary_path() {
63
+ git worktree list --porcelain | sed -n '1s/^worktree //p'
64
+ }
65
+
66
+ chat_worktree_metadata_value() {
67
+ local log_file="$1"
68
+ local key="$2"
69
+
70
+ sed -n "/<!-- agentic-session/,/-->/s/^${key}: //p" "$log_file" | head -n 1
71
+ }