create-egregore 0.17.4 → 0.18.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 (110) hide show
  1. package/assets/egregore-launcher.js +1965 -0
  2. package/assets/egregore-launcher.sh +385 -0
  3. package/bin/cli.js +472 -81
  4. package/lib/api.js +2 -2
  5. package/lib/auth.js +255 -20
  6. package/lib/codex-runtime.js +268 -0
  7. package/lib/commands.js +31 -0
  8. package/lib/context.js +1 -1
  9. package/lib/local.js +616 -189
  10. package/lib/setup.js +822 -84
  11. package/lib/ui.js +780 -84
  12. package/package.json +11 -3
  13. package/runtime/codex/.codex/config.toml +15 -0
  14. package/runtime/codex/.codex/hooks/branch-guard.js +234 -0
  15. package/runtime/codex/.codex/hooks.json +17 -0
  16. package/runtime/codex/.codex/skills/activity/SKILL.md +70 -0
  17. package/runtime/codex/.codex/skills/add/SKILL.md +25 -0
  18. package/runtime/codex/.codex/skills/announce/SKILL.md +54 -0
  19. package/runtime/codex/.codex/skills/answer/SKILL.md +25 -0
  20. package/runtime/codex/.codex/skills/archive/SKILL.md +41 -0
  21. package/runtime/codex/.codex/skills/ask/SKILL.md +59 -0
  22. package/runtime/codex/.codex/skills/branch/SKILL.md +25 -0
  23. package/runtime/codex/.codex/skills/checkup/SKILL.md +41 -0
  24. package/runtime/codex/.codex/skills/comment/SKILL.md +25 -0
  25. package/runtime/codex/.codex/skills/commit/SKILL.md +25 -0
  26. package/runtime/codex/.codex/skills/contribute/SKILL.md +25 -0
  27. package/runtime/codex/.codex/skills/dark-mode/SKILL.md +25 -0
  28. package/runtime/codex/.codex/skills/dashboard/SKILL.md +59 -0
  29. package/runtime/codex/.codex/skills/deep-reflect/SKILL.md +70 -0
  30. package/runtime/codex/.codex/skills/delete-user/SKILL.md +25 -0
  31. package/runtime/codex/.codex/skills/edit/SKILL.md +25 -0
  32. package/runtime/codex/.codex/skills/edit-process/SKILL.md +25 -0
  33. package/runtime/codex/.codex/skills/egregore-voice/SKILL.md +25 -0
  34. package/runtime/codex/.codex/skills/emissary/SKILL.md +41 -0
  35. package/runtime/codex/.codex/skills/env/SKILL.md +25 -0
  36. package/runtime/codex/.codex/skills/handoff/SKILL.md +67 -0
  37. package/runtime/codex/.codex/skills/harvest/SKILL.md +107 -0
  38. package/runtime/codex/.codex/skills/infra/SKILL.md +41 -0
  39. package/runtime/codex/.codex/skills/ingest/SKILL.md +25 -0
  40. package/runtime/codex/.codex/skills/ingest-google/SKILL.md +25 -0
  41. package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +41 -0
  42. package/runtime/codex/.codex/skills/invite/SKILL.md +40 -0
  43. package/runtime/codex/.codex/skills/issue/SKILL.md +41 -0
  44. package/runtime/codex/.codex/skills/me/SKILL.md +25 -0
  45. package/runtime/codex/.codex/skills/meeting/SKILL.md +41 -0
  46. package/runtime/codex/.codex/skills/note/SKILL.md +25 -0
  47. package/runtime/codex/.codex/skills/onboarding/SKILL.md +41 -0
  48. package/runtime/codex/.codex/skills/pr/SKILL.md +25 -0
  49. package/runtime/codex/.codex/skills/project/SKILL.md +41 -0
  50. package/runtime/codex/.codex/skills/pull/SKILL.md +25 -0
  51. package/runtime/codex/.codex/skills/push/SKILL.md +25 -0
  52. package/runtime/codex/.codex/skills/quest/SKILL.md +77 -0
  53. package/runtime/codex/.codex/skills/quest-suggest/SKILL.md +25 -0
  54. package/runtime/codex/.codex/skills/reflect/SKILL.md +41 -0
  55. package/runtime/codex/.codex/skills/review-pr/SKILL.md +41 -0
  56. package/runtime/codex/.codex/skills/save/SKILL.md +62 -0
  57. package/runtime/codex/.codex/skills/setup/SKILL.md +25 -0
  58. package/runtime/codex/.codex/skills/summon/SKILL.md +41 -0
  59. package/runtime/codex/.codex/skills/sync-repos/SKILL.md +25 -0
  60. package/runtime/codex/.codex/skills/telegram-connect/SKILL.md +25 -0
  61. package/runtime/codex/.codex/skills/telemetry/SKILL.md +25 -0
  62. package/runtime/codex/.codex/skills/test/SKILL.md +41 -0
  63. package/runtime/codex/.codex/skills/the-spiral/SKILL.md +84 -0
  64. package/runtime/codex/.codex/skills/todo/SKILL.md +41 -0
  65. package/runtime/codex/.codex/skills/tui-design/SKILL.md +41 -0
  66. package/runtime/codex/.codex/skills/tutorial/SKILL.md +41 -0
  67. package/runtime/codex/.codex/skills/update/SKILL.md +25 -0
  68. package/runtime/codex/.codex/skills/view/SKILL.md +41 -0
  69. package/runtime/codex/.codex/skills/visual-explain/SKILL.md +41 -0
  70. package/runtime/codex/.codex/skills/wrap/SKILL.md +55 -0
  71. package/runtime/codex/.codex/spec-manifest.json +108 -0
  72. package/runtime/codex/AGENTS.md +328 -0
  73. package/runtime/codex/bin/activity-data.sh +180 -0
  74. package/runtime/codex/bin/agent.sh +669 -0
  75. package/runtime/codex/bin/codex-install-skills.sh +78 -0
  76. package/runtime/codex/bin/codex-render-spec.mjs +308 -0
  77. package/runtime/codex/bin/codex-session-start.sh +238 -0
  78. package/runtime/codex/bin/codex-skill-render.mjs +315 -0
  79. package/runtime/codex/bin/codex-sync-skills.sh +223 -0
  80. package/runtime/codex/bin/dashboard-data.sh +178 -0
  81. package/runtime/codex/bin/graph-batch.sh +60 -0
  82. package/runtime/codex/bin/graph-op.sh +397 -0
  83. package/runtime/codex/bin/graph-wal.sh +228 -0
  84. package/runtime/codex/bin/graph.sh +141 -0
  85. package/runtime/codex/bin/handoff-pr-backfill.sh +86 -0
  86. package/runtime/codex/bin/handoff-run.sh +569 -0
  87. package/runtime/codex/bin/handoff-save-egregore.sh +131 -0
  88. package/runtime/codex/bin/index-handoff.sh +306 -0
  89. package/runtime/codex/bin/lib/artifact-id.sh +46 -0
  90. package/runtime/codex/bin/lib/config.sh +71 -0
  91. package/runtime/codex/bin/lib/context.sh +511 -0
  92. package/runtime/codex/bin/lib/dashboard-artifact.sh +142 -0
  93. package/runtime/codex/bin/lib/edit-loopback.mjs +652 -0
  94. package/runtime/codex/bin/lib/ensure-develop.sh +183 -0
  95. package/runtime/codex/bin/lib/git-sync.sh +262 -0
  96. package/runtime/codex/bin/lib/greeting.sh +432 -0
  97. package/runtime/codex/bin/lib/hash.sh +13 -0
  98. package/runtime/codex/bin/lib/identity.sh +164 -0
  99. package/runtime/codex/bin/lib/permissions.sh +106 -0
  100. package/runtime/codex/bin/lib/time.sh +56 -0
  101. package/runtime/codex/bin/lib/worktree-links.sh +54 -0
  102. package/runtime/codex/bin/notify.sh +207 -0
  103. package/runtime/codex/bin/publish-artifact.sh +187 -0
  104. package/runtime/codex/bin/publish-references.sh +144 -0
  105. package/runtime/codex/bin/repo-state.sh +99 -0
  106. package/runtime/codex/bin/telemetry.sh +350 -0
  107. package/runtime/codex/bin/worktree-create.sh +115 -0
  108. package/runtime/codex/bin/worktree-remove.sh +50 -0
  109. package/runtime/codex/bin/worktree.sh +199 -0
  110. package/runtime/codex/manifest.json +162 -0
@@ -0,0 +1,115 @@
1
+ #!/bin/bash
2
+ # WorktreeCreate hook — replaces EnterWorktree's default behavior.
3
+ # Receives {"name": "<slug>"} on stdin. Must print absolute worktree path to stdout.
4
+ # All diagnostic output goes to stderr or /dev/null — stdout is ONLY for the path.
5
+ # Must complete in under 2 seconds.
6
+
7
+ # No set -e — a jq failure must not crash the hook
8
+ set -o pipefail
9
+
10
+ # --- Read input ---
11
+ INPUT=$(cat /dev/stdin 2>/dev/null || echo '{}')
12
+ SLUG=$(echo "$INPUT" | jq -r '.name // empty' 2>/dev/null)
13
+
14
+ if [ -z "$SLUG" ]; then
15
+ echo "Error: no name provided" >&2
16
+ exit 1
17
+ fi
18
+
19
+ # --- Resolve main repo root ---
20
+ # CLAUDE_PROJECT_DIR may point to main repo or a worktree
21
+ REPO_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
22
+ if [ -f "$REPO_ROOT/.git" ]; then
23
+ # In a worktree — trace back to main repo
24
+ WT_GITDIR=$(sed 's/^gitdir: //' "$REPO_ROOT/.git" 2>/dev/null)
25
+ REPO_ROOT=$(cd "$WT_GITDIR/../../.." 2>/dev/null && pwd)
26
+ fi
27
+
28
+ # --- Read author ---
29
+ STATE_FILE="$REPO_ROOT/.egregore-state.json"
30
+ AUTHOR=$(jq -r '.github_username // .display_name // "unknown"' "$STATE_FILE" 2>/dev/null) || AUTHOR="unknown"
31
+
32
+ # --- Branch and worktree names ---
33
+ BRANCH="dev/${AUTHOR}/${SLUG}"
34
+ WT_PATH="$REPO_ROOT/.claude/worktrees/${SLUG}"
35
+
36
+ # --- Ensure origin/develop is available ---
37
+ git -C "$REPO_ROOT" fetch origin develop --quiet 2>/dev/null || true
38
+
39
+ # --- Create branch (idempotent — skip if exists) ---
40
+ if ! git -C "$REPO_ROOT" show-ref --verify --quiet "refs/heads/$BRANCH" 2>/dev/null; then
41
+ git -C "$REPO_ROOT" branch "$BRANCH" origin/develop >/dev/null 2>&1 || {
42
+ echo "Error: failed to create branch $BRANCH" >&2
43
+ exit 1
44
+ }
45
+ fi
46
+
47
+ # --- Handle stale worktree at same path ---
48
+ if [ -d "$WT_PATH" ]; then
49
+ git -C "$REPO_ROOT" worktree remove "$WT_PATH" --force 2>/dev/null || rm -rf "$WT_PATH" 2>/dev/null
50
+ git -C "$REPO_ROOT" worktree prune 2>/dev/null || true
51
+ fi
52
+
53
+ # --- Create worktree on our branch ---
54
+ mkdir -p "$REPO_ROOT/.claude/worktrees" 2>/dev/null
55
+ git -C "$REPO_ROOT" worktree add "$WT_PATH" "$BRANCH" --quiet 2>/dev/null || {
56
+ echo "Error: failed to create worktree at $WT_PATH" >&2
57
+ exit 1
58
+ }
59
+
60
+ # --- Symlinks (same as worktree.sh setup) ---
61
+ # Memory
62
+ if [ -L "$REPO_ROOT/memory" ] || [ -d "$REPO_ROOT/memory" ]; then
63
+ MEMORY_TARGET=$(realpath "$REPO_ROOT/memory" 2>/dev/null)
64
+ if [ -n "$MEMORY_TARGET" ] && [ -d "$MEMORY_TARGET" ]; then
65
+ ln -sfn "$MEMORY_TARGET" "$WT_PATH/memory"
66
+ fi
67
+ fi
68
+
69
+ # .env
70
+ [ -f "$REPO_ROOT/.env" ] && ln -sfn "$REPO_ROOT/.env" "$WT_PATH/.env"
71
+
72
+ # .egregore-state.json
73
+ [ -f "$REPO_ROOT/.egregore-state.json" ] && ln -sfn "$REPO_ROOT/.egregore-state.json" "$WT_PATH/.egregore-state.json"
74
+
75
+ # .egregore-session-id
76
+ [ -f "$REPO_ROOT/.egregore-session-id" ] && ln -sfn "$REPO_ROOT/.egregore-session-id" "$WT_PATH/.egregore-session-id"
77
+
78
+ # egregore.json
79
+ [ -f "$REPO_ROOT/egregore.json" ] && [ ! -f "$WT_PATH/egregore.json" ] && ln -sfn "$REPO_ROOT/egregore.json" "$WT_PATH/egregore.json"
80
+
81
+ # --- Compute boundary for worktree (so isolation hook works) ---
82
+ # session-start.sh doesn't re-run for worktrees, so we compute it here.
83
+ HASH=$(echo -n "$WT_PATH" | md5 2>/dev/null || echo -n "$WT_PATH" | md5sum 2>/dev/null | cut -d' ' -f1)
84
+ BOUNDARY_FILE="/tmp/egregore-boundary-${HASH}.json"
85
+ MEMORY_DIR=""
86
+ [ -L "$WT_PATH/memory" ] && MEMORY_DIR=$(realpath "$WT_PATH/memory" 2>/dev/null || true)
87
+ # Managed repos: include main repo (worktree symlinks resolve there) + sibling repos
88
+ MANAGED_REPOS_JSON="[\"$REPO_ROOT\""
89
+ PARENT_DIR="$(dirname "$REPO_ROOT")"
90
+ _repos=$(jq -r '(.repos[]? // empty) | if type == "object" then .name else . end' "$WT_PATH/egregore.json" 2>/dev/null || true)
91
+ for _r in $_repos; do
92
+ [[ "$_r" == *".."* ]] && continue
93
+ _resolved=$(realpath "$PARENT_DIR/$_r" 2>/dev/null || true)
94
+ [ -z "$_resolved" ] && continue
95
+ MANAGED_REPOS_JSON="$MANAGED_REPOS_JSON,\"$_resolved\""
96
+ done
97
+ MANAGED_REPOS_JSON="$MANAGED_REPOS_JSON]"
98
+ # Denied paths: other instances, but NOT the main repo (worktree is its child)
99
+ DENIED_JSON="[]"
100
+ REGISTRY="$HOME/.egregore/instances.json"
101
+ if [ -f "$REGISTRY" ]; then
102
+ DENIED_JSON=$(jq --arg self "$REPO_ROOT" --arg wt "$WT_PATH" \
103
+ '[.[] | select(.path != $self and .path != $wt) | .path]' \
104
+ "$REGISTRY" 2>/dev/null || echo "[]")
105
+ fi
106
+ jq -n \
107
+ --arg project_dir "$WT_PATH" \
108
+ --arg memory_dir "$MEMORY_DIR" \
109
+ --argjson managed_repos "$MANAGED_REPOS_JSON" \
110
+ --argjson denied_paths "$DENIED_JSON" \
111
+ '{project_dir: $project_dir, memory_dir: $memory_dir, managed_repos: $managed_repos, denied_paths: $denied_paths}' \
112
+ > "$BOUNDARY_FILE.tmp" 2>/dev/null && mv "$BOUNDARY_FILE.tmp" "$BOUNDARY_FILE" 2>/dev/null || true
113
+
114
+ # --- Output the worktree path (ONLY stdout line) ---
115
+ echo "$WT_PATH"
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ # WorktreeRemove hook — handles cleanup when a worktree is removed.
3
+ # Receives {"worktree_path": "<path>"} on stdin. Best-effort, always exit 0.
4
+
5
+ INPUT=$(cat /dev/stdin 2>/dev/null || echo '{}')
6
+ WT_PATH=$(echo "$INPUT" | jq -r '.worktree_path // empty' 2>/dev/null)
7
+
8
+ if [ -z "$WT_PATH" ] || [ ! -d "$WT_PATH" ]; then
9
+ exit 0
10
+ fi
11
+
12
+ # --- Resolve main repo for git operations ---
13
+ REPO_ROOT="${CLAUDE_PROJECT_DIR:-}"
14
+ if [ -z "$REPO_ROOT" ] || [ -f "$REPO_ROOT/.git" ]; then
15
+ # In a worktree or no CLAUDE_PROJECT_DIR — trace from the worktree path
16
+ if [ -f "$WT_PATH/.git" ]; then
17
+ WT_GITDIR=$(sed 's/^gitdir: //' "$WT_PATH/.git" 2>/dev/null)
18
+ REPO_ROOT=$(cd "$WT_GITDIR/../../.." 2>/dev/null && pwd) || REPO_ROOT=""
19
+ fi
20
+ fi
21
+
22
+ # --- Remove from instance registry ---
23
+ REGISTRY="$HOME/.egregore/instances.json"
24
+ if [ -f "$REGISTRY" ]; then
25
+ RESOLVED_WT=$(realpath "$WT_PATH" 2>/dev/null || echo "$WT_PATH")
26
+ UPDATED=$(jq --arg p "$RESOLVED_WT" '[.[] | select(.path != $p)]' "$REGISTRY" 2>/dev/null)
27
+ if [ -n "$UPDATED" ]; then
28
+ echo "$UPDATED" > "$REGISTRY.tmp" && mv "$REGISTRY.tmp" "$REGISTRY"
29
+ fi
30
+ fi
31
+
32
+ # --- Remove worktree ---
33
+ if [ -n "$REPO_ROOT" ] && [ -d "$REPO_ROOT/.git" ]; then
34
+ git -C "$REPO_ROOT" worktree remove "$WT_PATH" --force 2>/dev/null || true
35
+ git -C "$REPO_ROOT" worktree prune 2>/dev/null || true
36
+ else
37
+ # Fallback: just remove the directory
38
+ rm -rf "$WT_PATH" 2>/dev/null || true
39
+ fi
40
+
41
+ # --- Clean up stale marker files ---
42
+ for MARKER_FILE in "$HOME/.egregore"/worktree-cleanup-*.marker; do
43
+ [ -f "$MARKER_FILE" ] || continue
44
+ MARKER_PATH=$(cat "$MARKER_FILE" 2>/dev/null)
45
+ if [ "$MARKER_PATH" = "$WT_PATH" ] || [ ! -d "$MARKER_PATH" ]; then
46
+ rm -f "$MARKER_FILE" 2>/dev/null || true
47
+ fi
48
+ done
49
+
50
+ exit 0
@@ -0,0 +1,199 @@
1
+ #!/bin/bash
2
+ # Worktree lifecycle management for Egregore sessions.
3
+ # Each session gets an isolated worktree so parallel sessions don't conflict.
4
+ #
5
+ # Usage:
6
+ # bash bin/worktree.sh setup <worktree-path> <main-project-dir>
7
+ # bash bin/worktree.sh cleanup <worktree-path>
8
+ # bash bin/worktree.sh cleanup-stale <main-project-dir>
9
+ # bash bin/worktree.sh health [path]
10
+ # bash bin/worktree.sh list
11
+
12
+ set -o pipefail
13
+
14
+ if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
15
+ echo "Usage: worktree.sh <command> [args...]"
16
+ echo ""
17
+ echo "Worktree lifecycle management for Egregore sessions."
18
+ echo ""
19
+ echo "Commands:"
20
+ echo " setup <path> <main-dir> Set up symlinks for a new worktree"
21
+ echo " cleanup <path> Remove a worktree"
22
+ echo " cleanup-stale <main-dir> List stale worktrees (manual review)"
23
+ echo " health [path] Check worktree + branch health"
24
+ echo " list List all git worktrees"
25
+ exit 0
26
+ fi
27
+
28
+ CMD="${1:-}"
29
+ shift 2>/dev/null || true
30
+
31
+ case "$CMD" in
32
+
33
+ setup)
34
+ # Setup symlinks so worktree shares state with main project.
35
+ # Args: <worktree-path> <main-project-dir>
36
+ WT_PATH="${1:?Usage: worktree.sh setup <worktree-path> <main-project-dir>}"
37
+ MAIN_DIR="${2:?Usage: worktree.sh setup <worktree-path> <main-project-dir>}"
38
+
39
+ # Symlink shared files from main project
40
+ for FILE in memory .env .egregore-state.json .egregore-session-id; do
41
+ SRC="$MAIN_DIR/$FILE"
42
+ DST="$WT_PATH/$FILE"
43
+ if [ "$FILE" = "memory" ]; then
44
+ # Follow the shared memory symlink or direct directory to get an
45
+ # absolute path. Most installs use a symlink; local/dev fixtures may
46
+ # use a directory.
47
+ [ -L "$SRC" ] || [ -d "$SRC" ] || continue
48
+ SRC=$(realpath "$SRC" 2>/dev/null) || continue
49
+ [ -d "$SRC" ] || continue
50
+ else
51
+ [ -f "$SRC" ] || continue
52
+ fi
53
+ ln -sfn "$SRC" "$DST"
54
+ done
55
+
56
+ # Symlink egregore.json if not already present (committed file)
57
+ if [ -f "$MAIN_DIR/egregore.json" ] && [ ! -f "$WT_PATH/egregore.json" ]; then
58
+ ln -sfn "$MAIN_DIR/egregore.json" "$WT_PATH/egregore.json"
59
+ fi
60
+
61
+ # Find terminal TTY for statusline matching
62
+ _pid=$$
63
+ _tty=""
64
+ while [ "$_pid" -gt 1 ] 2>/dev/null; do
65
+ _ptty=$(ps -o tty= -p "$_pid" 2>/dev/null | tr -d ' ')
66
+ if [ -n "$_ptty" ] && [ "$_ptty" != "??" ]; then
67
+ _tty="$_ptty"
68
+ break
69
+ fi
70
+ _pid=$(ps -o ppid= -p "$_pid" 2>/dev/null | tr -d ' ')
71
+ done
72
+ [ -n "$_tty" ] && echo "$_tty" > "$WT_PATH/.egregore-worktree-tty"
73
+
74
+ echo "Worktree setup complete: $WT_PATH"
75
+ ;;
76
+
77
+ cleanup)
78
+ # Remove a worktree. Only called explicitly (ExitWorktree or manual).
79
+ # Args: <worktree-path>
80
+ WT_PATH="${1:?Usage: worktree.sh cleanup <worktree-path>}"
81
+
82
+ # Remove from instance registry if accidentally registered
83
+ REGISTRY="$HOME/.egregore/instances.json"
84
+ if [ -f "$REGISTRY" ]; then
85
+ RESOLVED_WT=$(realpath "$WT_PATH" 2>/dev/null || echo "$WT_PATH")
86
+ UPDATED=$(jq --arg p "$RESOLVED_WT" '[.[] | select(.path != $p)]' "$REGISTRY" 2>/dev/null)
87
+ if [ -n "$UPDATED" ]; then
88
+ echo "$UPDATED" > "$REGISTRY.tmp" && mv "$REGISTRY.tmp" "$REGISTRY"
89
+ fi
90
+ fi
91
+
92
+ git worktree remove "$WT_PATH" --force 2>/dev/null || true
93
+ git worktree prune 2>/dev/null || true
94
+
95
+ echo "Worktree cleaned up: $WT_PATH"
96
+ ;;
97
+
98
+ cleanup-stale)
99
+ # List stale worktrees for manual review. Does NOT auto-delete.
100
+ # Run interactively or from a cleanup command — never from session-start.
101
+ # Args: <main-project-dir>
102
+ MAIN_DIR="${1:?Usage: worktree.sh cleanup-stale <main-project-dir>}"
103
+ WT_BASE="$MAIN_DIR/.claude/worktrees"
104
+
105
+ if [ ! -d "$WT_BASE" ]; then
106
+ echo "No worktrees directory."
107
+ exit 0
108
+ fi
109
+
110
+ NOW_TS=$(date +%s)
111
+ FOUND=0
112
+
113
+ for WT_DIR in "$WT_BASE"/*/; do
114
+ [ -d "$WT_DIR" ] || continue
115
+
116
+ WT_NAME=$(basename "$WT_DIR")
117
+ WT_BRANCH=""
118
+ STATUS="unknown"
119
+
120
+ if [ -f "$WT_DIR/.git" ]; then
121
+ WT_BRANCH=$(git -C "$WT_DIR" branch --show-current 2>/dev/null || echo "?")
122
+
123
+ # Check if merged
124
+ if [ "$WT_BRANCH" != "?" ] && [ "$WT_BRANCH" != "develop" ] && [ "$WT_BRANCH" != "main" ]; then
125
+ if git merge-base --is-ancestor "$(git -C "$WT_DIR" rev-parse HEAD 2>/dev/null)" \
126
+ "$(git -C "$MAIN_DIR" rev-parse origin/develop 2>/dev/null)" 2>/dev/null; then
127
+ STATUS="merged"
128
+ else
129
+ STATUS="active"
130
+ fi
131
+ fi
132
+ else
133
+ STATUS="broken"
134
+ fi
135
+
136
+ # Age
137
+ WT_MTIME=$(stat -f %m "$WT_DIR" 2>/dev/null || stat -c %Y "$WT_DIR" 2>/dev/null || echo "$NOW_TS")
138
+ WT_AGE_H=$(( (NOW_TS - WT_MTIME) / 3600 ))
139
+
140
+ if [ "$STATUS" = "merged" ] || [ "$STATUS" = "broken" ] || [ "$WT_AGE_H" -gt 24 ]; then
141
+ echo " $WT_NAME [$STATUS] ${WT_AGE_H}h old branch: ${WT_BRANCH:-none}"
142
+ FOUND=$((FOUND + 1))
143
+ fi
144
+ done
145
+
146
+ if [ "$FOUND" -eq 0 ]; then
147
+ echo "No stale worktrees found."
148
+ else
149
+ echo ""
150
+ echo "To remove: bash bin/worktree.sh cleanup <path>"
151
+ fi
152
+
153
+ # Prune git's internal worktree list
154
+ git -C "$MAIN_DIR" worktree prune 2>/dev/null || true
155
+ ;;
156
+
157
+ health)
158
+ # Check worktree + branch health
159
+ # Exit codes: 0=healthy, 1=not_worktree, 2=branch_gone, 3=protected_branch
160
+ WT_PATH="${1:-$(pwd)}"
161
+
162
+ if [ ! -f "$WT_PATH/.git" ]; then
163
+ echo '{"status":"not_worktree"}'
164
+ exit 1
165
+ fi
166
+
167
+ BRANCH=$(git -C "$WT_PATH" branch --show-current 2>/dev/null || echo "")
168
+
169
+ case "$BRANCH" in
170
+ develop|main|master)
171
+ jq -n --arg branch "$BRANCH" '{status: "protected_branch", branch: $branch}'
172
+ exit 3
173
+ ;;
174
+ esac
175
+
176
+ # Check if remote branch still exists
177
+ git -C "$WT_PATH" fetch origin --prune --quiet 2>/dev/null || true
178
+ if ! git -C "$WT_PATH" ls-remote --heads origin "$BRANCH" 2>/dev/null | grep -q "$BRANCH"; then
179
+ if git -C "$WT_PATH" branch -r --merged origin/develop 2>/dev/null | grep -q "origin/$BRANCH" 2>/dev/null; then
180
+ jq -n --arg branch "$BRANCH" '{status: "merged", branch: $branch}'
181
+ else
182
+ jq -n --arg branch "$BRANCH" '{status: "remote_deleted", branch: $branch}'
183
+ fi
184
+ exit 2
185
+ fi
186
+
187
+ jq -n --arg branch "$BRANCH" '{status: "healthy", branch: $branch}'
188
+ exit 0
189
+ ;;
190
+
191
+ list)
192
+ git worktree list
193
+ ;;
194
+
195
+ *)
196
+ echo "Usage: worktree.sh {setup|cleanup|cleanup-stale|health|list}" >&2
197
+ exit 1
198
+ ;;
199
+ esac
@@ -0,0 +1,162 @@
1
+ {
2
+ "generatedAt": "2026-06-15T13:36:14.132Z",
3
+ "source": "egregore-runtime",
4
+ "policy": "public-safe subset derived from .syncignore; internal .codex/skills exclusions omitted",
5
+ "skillCount": 55,
6
+ "skills": [
7
+ "activity",
8
+ "add",
9
+ "announce",
10
+ "answer",
11
+ "archive",
12
+ "ask",
13
+ "branch",
14
+ "checkup",
15
+ "comment",
16
+ "commit",
17
+ "contribute",
18
+ "dark-mode",
19
+ "dashboard",
20
+ "deep-reflect",
21
+ "delete-user",
22
+ "edit",
23
+ "edit-process",
24
+ "egregore-voice",
25
+ "emissary",
26
+ "env",
27
+ "handoff",
28
+ "harvest",
29
+ "infra",
30
+ "ingest",
31
+ "ingest-google",
32
+ "ingest-user-interview",
33
+ "invite",
34
+ "issue",
35
+ "me",
36
+ "meeting",
37
+ "note",
38
+ "onboarding",
39
+ "pr",
40
+ "project",
41
+ "pull",
42
+ "push",
43
+ "quest",
44
+ "quest-suggest",
45
+ "reflect",
46
+ "review-pr",
47
+ "save",
48
+ "setup",
49
+ "summon",
50
+ "sync-repos",
51
+ "telegram-connect",
52
+ "telemetry",
53
+ "test",
54
+ "the-spiral",
55
+ "todo",
56
+ "tui-design",
57
+ "tutorial",
58
+ "update",
59
+ "view",
60
+ "visual-explain",
61
+ "wrap"
62
+ ],
63
+ "files": [
64
+ ".codex/config.toml",
65
+ ".codex/hooks.json",
66
+ ".codex/hooks/branch-guard.js",
67
+ ".codex/skills/activity/SKILL.md",
68
+ ".codex/skills/add/SKILL.md",
69
+ ".codex/skills/announce/SKILL.md",
70
+ ".codex/skills/answer/SKILL.md",
71
+ ".codex/skills/archive/SKILL.md",
72
+ ".codex/skills/ask/SKILL.md",
73
+ ".codex/skills/branch/SKILL.md",
74
+ ".codex/skills/checkup/SKILL.md",
75
+ ".codex/skills/comment/SKILL.md",
76
+ ".codex/skills/commit/SKILL.md",
77
+ ".codex/skills/contribute/SKILL.md",
78
+ ".codex/skills/dark-mode/SKILL.md",
79
+ ".codex/skills/dashboard/SKILL.md",
80
+ ".codex/skills/deep-reflect/SKILL.md",
81
+ ".codex/skills/delete-user/SKILL.md",
82
+ ".codex/skills/edit-process/SKILL.md",
83
+ ".codex/skills/edit/SKILL.md",
84
+ ".codex/skills/egregore-voice/SKILL.md",
85
+ ".codex/skills/emissary/SKILL.md",
86
+ ".codex/skills/env/SKILL.md",
87
+ ".codex/skills/handoff/SKILL.md",
88
+ ".codex/skills/harvest/SKILL.md",
89
+ ".codex/skills/infra/SKILL.md",
90
+ ".codex/skills/ingest-google/SKILL.md",
91
+ ".codex/skills/ingest-user-interview/SKILL.md",
92
+ ".codex/skills/ingest/SKILL.md",
93
+ ".codex/skills/invite/SKILL.md",
94
+ ".codex/skills/issue/SKILL.md",
95
+ ".codex/skills/me/SKILL.md",
96
+ ".codex/skills/meeting/SKILL.md",
97
+ ".codex/skills/note/SKILL.md",
98
+ ".codex/skills/onboarding/SKILL.md",
99
+ ".codex/skills/pr/SKILL.md",
100
+ ".codex/skills/project/SKILL.md",
101
+ ".codex/skills/pull/SKILL.md",
102
+ ".codex/skills/push/SKILL.md",
103
+ ".codex/skills/quest-suggest/SKILL.md",
104
+ ".codex/skills/quest/SKILL.md",
105
+ ".codex/skills/reflect/SKILL.md",
106
+ ".codex/skills/review-pr/SKILL.md",
107
+ ".codex/skills/save/SKILL.md",
108
+ ".codex/skills/setup/SKILL.md",
109
+ ".codex/skills/summon/SKILL.md",
110
+ ".codex/skills/sync-repos/SKILL.md",
111
+ ".codex/skills/telegram-connect/SKILL.md",
112
+ ".codex/skills/telemetry/SKILL.md",
113
+ ".codex/skills/test/SKILL.md",
114
+ ".codex/skills/the-spiral/SKILL.md",
115
+ ".codex/skills/todo/SKILL.md",
116
+ ".codex/skills/tui-design/SKILL.md",
117
+ ".codex/skills/tutorial/SKILL.md",
118
+ ".codex/skills/update/SKILL.md",
119
+ ".codex/skills/view/SKILL.md",
120
+ ".codex/skills/visual-explain/SKILL.md",
121
+ ".codex/skills/wrap/SKILL.md",
122
+ ".codex/spec-manifest.json",
123
+ "AGENTS.md",
124
+ "bin/activity-data.sh",
125
+ "bin/agent.sh",
126
+ "bin/codex-install-skills.sh",
127
+ "bin/codex-render-spec.mjs",
128
+ "bin/codex-session-start.sh",
129
+ "bin/codex-skill-render.mjs",
130
+ "bin/codex-sync-skills.sh",
131
+ "bin/dashboard-data.sh",
132
+ "bin/graph-batch.sh",
133
+ "bin/graph-op.sh",
134
+ "bin/graph-wal.sh",
135
+ "bin/graph.sh",
136
+ "bin/handoff-pr-backfill.sh",
137
+ "bin/handoff-run.sh",
138
+ "bin/handoff-save-egregore.sh",
139
+ "bin/index-handoff.sh",
140
+ "bin/lib/artifact-id.sh",
141
+ "bin/lib/config.sh",
142
+ "bin/lib/context.sh",
143
+ "bin/lib/dashboard-artifact.sh",
144
+ "bin/lib/edit-loopback.mjs",
145
+ "bin/lib/ensure-develop.sh",
146
+ "bin/lib/git-sync.sh",
147
+ "bin/lib/greeting.sh",
148
+ "bin/lib/hash.sh",
149
+ "bin/lib/identity.sh",
150
+ "bin/lib/permissions.sh",
151
+ "bin/lib/time.sh",
152
+ "bin/lib/worktree-links.sh",
153
+ "bin/notify.sh",
154
+ "bin/publish-artifact.sh",
155
+ "bin/publish-references.sh",
156
+ "bin/repo-state.sh",
157
+ "bin/telemetry.sh",
158
+ "bin/worktree-create.sh",
159
+ "bin/worktree-remove.sh",
160
+ "bin/worktree.sh"
161
+ ]
162
+ }