@tyroneross/build-loop 0.30.3 → 0.34.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/.agents/plugins/marketplace.json +2 -2
- package/.claude-plugin/marketplace.json +4 -4
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +9 -0
- package/README.md +8 -7
- package/agents/advisor.md +111 -0
- package/agents/alignment-checker.md +11 -0
- package/agents/assessment-orchestrator.md +1 -1
- package/agents/build-orchestrator.md +28 -33
- package/agents/fact-checker.md +1 -1
- package/agents/fix-critique.md +1 -1
- package/agents/independent-auditor.md +1 -1
- package/agents/overfitting-reviewer.md +1 -1
- package/agents/plan-critic.md +5 -4
- package/agents/promotion-reviewer.md +1 -1
- package/agents/retrospective-synthesizer.md +20 -3
- package/agents/scope-auditor.md +1 -1
- package/agents/security-reviewer.md +1 -1
- package/agents/self-improvement-architect.md +1 -1
- package/commands/{handoff.md → compose-handoff.md} +4 -4
- package/commands/{optimize.md → optimize-run.md} +1 -1
- package/commands/{agent-rally-point.md → rally-point.md} +3 -3
- package/commands/{research.md → research-run.md} +1 -1
- package/commands/setup-memory.md +32 -0
- package/commands/{plan-verify.md → verify-plan.md} +1 -1
- package/docs/agent-surface-policy.md +38 -20
- package/docs/memory-setup.md +19 -14
- package/hooks/_resolve_python.sh +28 -0
- package/hooks/closeout.sh +58 -0
- package/hooks/git/pre-push +69 -6
- package/hooks/hooks.json +34 -13
- package/hooks/post-push-closeout.sh +73 -0
- package/hooks/session-start-closeout.sh +69 -0
- package/hooks/session-start-memory.sh +27 -0
- package/hooks/session-start-plugin-heal.sh +33 -0
- package/hooks/test_closeout.sh +124 -0
- package/package.json +7 -4
- package/plugin-artifacts/codex/.codex-plugin/plugin.json +41 -0
- package/plugin-artifacts/codex/AGENTS.md +499 -0
- package/plugin-artifacts/codex/BUILD-ARTIFACT.md +5 -0
- package/plugin-artifacts/codex/LICENSE +202 -0
- package/plugin-artifacts/codex/README.md +404 -0
- package/plugin-artifacts/codex/docs/agent-surface-policy.md +63 -0
- package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +62 -0
- package/plugin-artifacts/codex/references/agent-role-taxonomy.md +101 -0
- package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +161 -0
- package/plugin-artifacts/codex/references/autonomy-config.md +231 -0
- package/plugin-artifacts/codex/references/capability-routing.md +182 -0
- package/plugin-artifacts/codex/references/codex-subagents.md +106 -0
- package/plugin-artifacts/codex/references/coordination-file-template.md +181 -0
- package/plugin-artifacts/codex/references/coordination-rules.md +283 -0
- package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +112 -0
- package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +102 -0
- package/plugin-artifacts/codex/references/implementer-envelope-schema.md +302 -0
- package/plugin-artifacts/codex/references/intent-capability-pack.md +257 -0
- package/plugin-artifacts/codex/references/intent-exploration-prompts.md +96 -0
- package/plugin-artifacts/codex/references/leadership.md +72 -0
- package/plugin-artifacts/codex/references/memory-systems.md +238 -0
- package/plugin-artifacts/codex/references/memory.md +297 -0
- package/plugin-artifacts/codex/references/model-tier-mapping.md +257 -0
- package/plugin-artifacts/codex/references/modular-systems-pack.md +96 -0
- package/plugin-artifacts/codex/references/phase-1-assess.md +231 -0
- package/plugin-artifacts/codex/references/phase-2-plan.md +77 -0
- package/plugin-artifacts/codex/references/phase-3-execute.md +47 -0
- package/plugin-artifacts/codex/references/phase-4-review.md +320 -0
- package/plugin-artifacts/codex/references/phase-5-iterate.md +71 -0
- package/plugin-artifacts/codex/references/phase-6-learn.md +56 -0
- package/plugin-artifacts/codex/references/recent-design-structures.md +274 -0
- package/plugin-artifacts/codex/references/research-trigger-policy.md +140 -0
- package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +42 -0
- package/plugin-artifacts/codex/references/self-review.md +234 -0
- package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +90 -0
- package/plugin-artifacts/codex/references/task-capture-policy.md +68 -0
- package/plugin-artifacts/codex/references/ui-io-contract.md +116 -0
- package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +65 -0
- package/plugin-artifacts/codex/skills/build-loop/SKILL.md +372 -0
- package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +82 -0
- package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +65 -0
- package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +549 -0
- package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +42 -0
- package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +267 -0
- package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
- package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +439 -0
- package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
- package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +182 -0
- package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +106 -0
- package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +161 -0
- package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +177 -0
- package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +72 -0
- package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +257 -0
- package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +96 -0
- package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +72 -0
- package/plugin-artifacts/codex/skills/build-loop/references/memory.md +297 -0
- package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +96 -0
- package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +129 -0
- package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +98 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +231 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +77 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +47 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +320 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +71 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +56 -0
- package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +274 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
- package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +77 -0
- package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +234 -0
- package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +116 -0
- package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
- package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +35 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +96 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +40 -0
- package/scripts/_paths.py +59 -13
- package/scripts/build_codex_plugin_artifact.py +314 -0
- package/scripts/check_cache_sync.py +1 -1
- package/scripts/install_memory.py +11 -3
- package/scripts/prune_plugin_cache.py +225 -11
- package/scripts/sync_navgator_lessons.py +25 -0
- package/scripts/sync_plugin_cache.py +66 -36
- package/skills/agent-rally-point/SKILL.md +1 -1
- package/skills/agent-rally-watcher/SKILL.md +1 -1
- package/skills/build-loop/SKILL.md +11 -155
- package/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
- package/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
- package/skills/build-loop/references/capability-routing.md +4 -3
- package/skills/build-loop/references/codex-subagents.md +8 -0
- package/skills/build-loop/references/coordination.md +1 -1
- package/skills/build-loop/references/intent-capability-pack.md +88 -1
- package/skills/build-loop/references/memory.md +17 -2
- package/skills/build-loop/references/phase-1-assess.md +13 -0
- package/skills/build-loop/references/phase-2-plan.md +1 -1
- package/skills/build-loop/references/phase-4-review.md +12 -0
- package/skills/build-loop/references/phase-6-learn.md +1 -1
- package/skills/build-loop/references/self-review.md +4 -2
- package/skills/build-loop/templates/codex-worker-prompt.md +41 -34
- package/skills/handoff/SKILL.md +3 -3
- package/skills/loop-builder/SKILL.md +98 -0
- package/skills/loop-builder/presets/active-project-evidence.yaml +97 -0
- package/skills/loop-builder/presets/generic-artifact-loop.yaml +95 -0
- package/skills/loop-builder/presets/presentation-audit.yaml +96 -0
- package/skills/loop-builder/presets/research-synthesis.yaml +96 -0
- package/skills/loop-builder/presets/source-ingestion-raw-data-audit.yaml +96 -0
- package/skills/loop-builder/references/spec-format.md +80 -0
- package/skills/loop-builder/scripts/loop_builder.py +346 -0
- package/skills/model-tiering/SKILL.md +65 -40
- package/skills/optimize/SKILL.md +2 -2
- package/skills/plan-verify/SKILL.md +1 -1
- package/skills/plugin-builder/references/distribution.md +8 -0
- package/skills/research/SKILL.md +33 -6
- package/skills/runtime-parity-verification/SKILL.md +51 -0
- package/skills/spec-writing/SKILL.md +19 -0
- package/templates/memory/README.md +65 -0
- package/templates/memory/charter.md.template +46 -0
- package/templates/memory/manifest.json +24 -4
- package/codex-skills/debug-loop/SKILL.md +0 -18
- package/codex-skills/handoff/SKILL.md +0 -22
- package/codex-skills/knowledge/SKILL.md +0 -21
- package/codex-skills/optimize/SKILL.md +0 -18
- package/codex-skills/research/SKILL.md +0 -18
- /package/commands/{knowledge-review.md → review-knowledge.md} +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# post-push-closeout.sh — warm-context soft closeout after a `git push`.
|
|
6
|
+
#
|
|
7
|
+
# Triggered by Claude Code PostToolUse:Bash (see hooks/hooks.json). When the
|
|
8
|
+
# command that just ran was a `git push`, fire the EXISTING closeout in the
|
|
9
|
+
# BACKGROUND (nohup) while context is still warm. This complements — does NOT
|
|
10
|
+
# replace — the crash-fallback path:
|
|
11
|
+
#
|
|
12
|
+
# - pre-push (hooks/git/pre-push) arms .build-loop/closeout/armed.json.
|
|
13
|
+
# - next SessionStart (hooks/session-start-closeout.sh) drains the baton.
|
|
14
|
+
#
|
|
15
|
+
# This hook short-circuits that fallback in the common case by draining
|
|
16
|
+
# immediately in the background. It reuses `python3 -m closeout` verbatim — NO
|
|
17
|
+
# duplicated closeout logic. Because closeout writes durable memory + clears the
|
|
18
|
+
# baton on success, the next SessionStart simply finds nothing to drain.
|
|
19
|
+
#
|
|
20
|
+
# Discipline: PostToolUse hooks observe; this one never blocks the tool result.
|
|
21
|
+
# Fail-open (always exit 0). The actual closeout runs detached so a slow memory
|
|
22
|
+
# write never stalls the agent's turn. Minimal-PATH safe (resolves python3 via
|
|
23
|
+
# command -v); no bare `set -e`.
|
|
24
|
+
|
|
25
|
+
set -u
|
|
26
|
+
|
|
27
|
+
# PostToolUse passes the tool command; Claude Code exposes it as $TOOL_INPUT
|
|
28
|
+
# (matching the sibling Bash matcher in hooks.json). Fall back to reading stdin
|
|
29
|
+
# JSON if the env var is absent (host portability).
|
|
30
|
+
CMD="${TOOL_INPUT:-}"
|
|
31
|
+
if [ -z "$CMD" ]; then
|
|
32
|
+
# Best-effort: some hosts deliver the payload on stdin as JSON.
|
|
33
|
+
STDIN_JSON="$(cat 2>/dev/null || true)"
|
|
34
|
+
CMD="$STDIN_JSON"
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Only act on a real `git push`. Anchor on the verb pair to avoid matching
|
|
38
|
+
# `git push --help`-style noise loosely; a trailing `--dry-run` push still
|
|
39
|
+
# closes out harmlessly (closeout is idempotent + fail-open).
|
|
40
|
+
printf '%s' "$CMD" | grep -qE '\bgit[[:space:]]+push\b' || exit 0
|
|
41
|
+
|
|
42
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-${PWD}}"
|
|
43
|
+
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${PROJECT_DIR}}"
|
|
44
|
+
|
|
45
|
+
# A closeout only makes sense inside a build-loop project.
|
|
46
|
+
[ -d "${PROJECT_DIR}/.build-loop" ] || exit 0
|
|
47
|
+
|
|
48
|
+
# Resolve python3 without depending on a populated PATH (shared helper).
|
|
49
|
+
_HOOK_DIR="$(dirname "$0")"
|
|
50
|
+
_py=""
|
|
51
|
+
[ -f "${_HOOK_DIR}/_resolve_python.sh" ] && . "${_HOOK_DIR}/_resolve_python.sh"
|
|
52
|
+
[ -n "$_py" ] || exit 0
|
|
53
|
+
|
|
54
|
+
CLOSEOUT_LOG_DIR="${PROJECT_DIR}/.build-loop/closeout"
|
|
55
|
+
mkdir -p "$CLOSEOUT_LOG_DIR" 2>/dev/null || true
|
|
56
|
+
RID="postpush-$(date -u +%Y%m%dT%H%M%SZ)"
|
|
57
|
+
|
|
58
|
+
# Ensure the closeout package (scripts/closeout/) is importable regardless of
|
|
59
|
+
# the invoking environment's PYTHONPATH (hooks run under minimal PATH; the package
|
|
60
|
+
# is not installed globally — it lives under PLUGIN_ROOT/scripts/).
|
|
61
|
+
export PYTHONPATH="${PLUGIN_ROOT}/scripts${PYTHONPATH:+:$PYTHONPATH}"
|
|
62
|
+
|
|
63
|
+
# Fire the existing closeout in the background; never block the turn. On success
|
|
64
|
+
# the closeout module clears the armed baton, so the SessionStart fallback finds
|
|
65
|
+
# nothing to do. Detached + redirected so the agent's turn returns immediately.
|
|
66
|
+
nohup "$_py" -m closeout \
|
|
67
|
+
--workdir "$PROJECT_DIR" \
|
|
68
|
+
--run-id "$RID" \
|
|
69
|
+
--source post-push \
|
|
70
|
+
--json \
|
|
71
|
+
>"${CLOSEOUT_LOG_DIR}/${RID}.stdout.json" 2>/dev/null &
|
|
72
|
+
|
|
73
|
+
exit 0
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# session-start-closeout.sh — drain a post-push armed baton and surface
|
|
6
|
+
# pending-lesson candidates to the host coding agent.
|
|
7
|
+
#
|
|
8
|
+
# Triggered by Claude Code SessionStart (see hooks/hooks.json). Fail-open
|
|
9
|
+
# (always ``exit 0``) so a broken hook can never wedge a session start.
|
|
10
|
+
#
|
|
11
|
+
# Two responsibilities:
|
|
12
|
+
# 1. If ``.build-loop/closeout/armed.json`` exists, the previous session
|
|
13
|
+
# ran ``git push``. Drain the baton by invoking ``python3 -m closeout``
|
|
14
|
+
# with ``--source post-push-armed`` and delete the baton on success.
|
|
15
|
+
# 2. Surface pending-lesson candidates (one-shot) so the host agent sees
|
|
16
|
+
# them in the next turn without having to re-discover them.
|
|
17
|
+
#
|
|
18
|
+
# Minimal PATH safe: resolves ``python3`` via ``command -v``; bare ``set -e``
|
|
19
|
+
# is intentionally avoided.
|
|
20
|
+
|
|
21
|
+
set -u
|
|
22
|
+
|
|
23
|
+
# Resolve the project / plugin root.
|
|
24
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-${PWD}}"
|
|
25
|
+
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${PROJECT_DIR}}"
|
|
26
|
+
|
|
27
|
+
# Resolve a python3 binary without depending on PATH being populated (shared helper).
|
|
28
|
+
_HOOK_DIR="$(dirname "$0")"
|
|
29
|
+
_py=""
|
|
30
|
+
[ -f "${_HOOK_DIR}/_resolve_python.sh" ] && . "${_HOOK_DIR}/_resolve_python.sh"
|
|
31
|
+
[ -n "$_py" ] || exit 0
|
|
32
|
+
|
|
33
|
+
ARMED="${PROJECT_DIR}/.build-loop/closeout/armed.json"
|
|
34
|
+
CLOSEOUT_LOG_DIR="${PROJECT_DIR}/.build-loop/closeout"
|
|
35
|
+
mkdir -p "$CLOSEOUT_LOG_DIR" 2>/dev/null || true
|
|
36
|
+
|
|
37
|
+
# Ensure the closeout package (scripts/closeout/) is importable in hook env.
|
|
38
|
+
# PLUGIN_ROOT already resolves to the repo root (see above); scripts/ is the
|
|
39
|
+
# package parent. Set once here so both the closeout call and surface_pending use it.
|
|
40
|
+
export PYTHONPATH="${PLUGIN_ROOT}/scripts${PYTHONPATH:+:$PYTHONPATH}"
|
|
41
|
+
|
|
42
|
+
# 1. Drain the armed baton if present.
|
|
43
|
+
if [ -f "$ARMED" ]; then
|
|
44
|
+
RID="armed-$(date -u +%Y%m%dT%H%M%SZ)"
|
|
45
|
+
"$_py" -m closeout \
|
|
46
|
+
--workdir "$PROJECT_DIR" \
|
|
47
|
+
--run-id "$RID" \
|
|
48
|
+
--source post-push-armed \
|
|
49
|
+
--json \
|
|
50
|
+
2>/dev/null \
|
|
51
|
+
>"${CLOSEOUT_LOG_DIR}/${RID}.stdout.json" \
|
|
52
|
+
&& rm -f "$ARMED" 2>/dev/null \
|
|
53
|
+
|| true
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# 2. Surface pending-lesson candidates (quiet — nothing prints when empty).
|
|
57
|
+
SURFACED="${CLOSEOUT_LOG_DIR}/surfaced-$(date -u +%Y%m%dT%H%M%SZ).md"
|
|
58
|
+
"$_py" "${PLUGIN_ROOT}/scripts/surface_pending_lessons.py" \
|
|
59
|
+
--workdir "$PROJECT_DIR" \
|
|
60
|
+
--quiet \
|
|
61
|
+
2>/dev/null \
|
|
62
|
+
>"$SURFACED" \
|
|
63
|
+
|| true
|
|
64
|
+
# Drop the surfaced file when empty so the directory stays clean.
|
|
65
|
+
if [ ! -s "$SURFACED" ]; then
|
|
66
|
+
rm -f "$SURFACED" 2>/dev/null || true
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
exit 0
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Bootstrap build-loop-memory on session start (idempotent, fail-open).
|
|
4
|
+
# Seeds the central memory store (constitution.md, MEMORY.md, indexes/,
|
|
5
|
+
# projects/) from the packaged PUBLIC seed only when the store is entirely
|
|
6
|
+
# absent. install_memory.py is idempotent (skip-if-exists) and copies no
|
|
7
|
+
# personal content. Never blocks, never overwrites, never errors the session.
|
|
8
|
+
# Repair of a partial store is the user-facing `/build-loop:setup-memory` job.
|
|
9
|
+
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PROJECT_DIR:-$PWD}}"
|
|
10
|
+
installer="${PLUGIN_ROOT}/scripts/install_memory.py"
|
|
11
|
+
[ -f "$installer" ] || exit 0
|
|
12
|
+
command -v python3 >/dev/null 2>&1 || exit 0
|
|
13
|
+
|
|
14
|
+
# Seed only when the store ROOT dir is missing. Parse --check JSON properly so a
|
|
15
|
+
# nested per-file "exists" cannot be mistaken for the top-level store flag.
|
|
16
|
+
# (python3 -c, not a heredoc: a heredoc inside $() with an apostrophe trips
|
|
17
|
+
# macOS bash 3.2 tokenization.)
|
|
18
|
+
need="$(python3 -c '
|
|
19
|
+
import json, subprocess, sys
|
|
20
|
+
try:
|
|
21
|
+
out = subprocess.run([sys.executable, sys.argv[1], "--check", "--json"], capture_output=True, text=True, timeout=5).stdout
|
|
22
|
+
print("1" if not json.loads(out).get("exists") else "0")
|
|
23
|
+
except Exception:
|
|
24
|
+
print("0")
|
|
25
|
+
' "$installer")"
|
|
26
|
+
[ "$need" = "1" ] && python3 "$installer" >/dev/null 2>&1
|
|
27
|
+
exit 0
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
# Plugin-cache self-heal, fire-and-forget, plugin-relative.
|
|
4
|
+
#
|
|
5
|
+
# Heals a Claude Code plugin install whose versioned cache dir vanished while
|
|
6
|
+
# another session was bound to it. Two cases:
|
|
7
|
+
# A) /plugin install archived the prior dir to ~/.claude/plugins/removed/
|
|
8
|
+
# → move it back to its registered installPath.
|
|
9
|
+
# B) /plugin update hard-deleted the prior dir after installing a newer one
|
|
10
|
+
# → create a symlink old→new so the frozen ${CLAUDE_PLUGIN_ROOT} path
|
|
11
|
+
# resolves to live scripts.
|
|
12
|
+
#
|
|
13
|
+
# Heals the NEXT session (CC re-resolves ${CLAUDE_PLUGIN_ROOT} only at session
|
|
14
|
+
# start). Cannot save a currently-bound dead-path session — restart-or-symlink
|
|
15
|
+
# remains the only in-session remedy.
|
|
16
|
+
#
|
|
17
|
+
# Opt out: BUILDLOOP_NO_PLUGIN_HEAL=1.
|
|
18
|
+
D="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
19
|
+
. "$D/_session_start_lib.sh"
|
|
20
|
+
ROOT="${CLAUDE_PLUGIN_ROOT:-$D/..}"
|
|
21
|
+
# Heal only runs against ~/.claude (Claude Code's pre-validate-dir-exists is
|
|
22
|
+
# the hazard; Codex doesn't have the same harness behaviour). Cheap-skip on
|
|
23
|
+
# Codex hosts by path heuristic.
|
|
24
|
+
case "$ROOT" in
|
|
25
|
+
*/.codex/*) exit 0 ;;
|
|
26
|
+
esac
|
|
27
|
+
if [ "${BUILDLOOP_NO_PLUGIN_HEAL:-}" = "1" ]; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
if [ -f "$ROOT/scripts/hooks/plugin_dir_heal.py" ]; then
|
|
31
|
+
bl_fire_bg "$ROOT/scripts/hooks/plugin_dir_heal.py"
|
|
32
|
+
fi
|
|
33
|
+
exit 0
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
#
|
|
5
|
+
# test_closeout.sh — integration tests for hooks/closeout.sh + scripts/stop_closeout.py (f6).
|
|
6
|
+
#
|
|
7
|
+
# Exercises the bash shim end-to-end (the part the python unit tests can't cover):
|
|
8
|
+
# self-gating, minimal-PATH safety, interpreter fail-open, and the session-id
|
|
9
|
+
# stdin path. Run directly: bash hooks/test_closeout.sh
|
|
10
|
+
|
|
11
|
+
set -u
|
|
12
|
+
|
|
13
|
+
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
|
14
|
+
HOOK="$REPO/hooks/closeout.sh"
|
|
15
|
+
PASS=0
|
|
16
|
+
FAIL=0
|
|
17
|
+
|
|
18
|
+
ok() { PASS=$((PASS+1)); printf ' ok %s\n' "$1"; }
|
|
19
|
+
bad() { FAIL=$((FAIL+1)); printf ' FAIL %s\n' "$1"; }
|
|
20
|
+
|
|
21
|
+
# Build a throwaway project with a recordable inline run (matching session,
|
|
22
|
+
# stakes-gated, not yet in runs[]).
|
|
23
|
+
make_project() {
|
|
24
|
+
local dir; dir="$(mktemp -d)"
|
|
25
|
+
mkdir -p "$dir/.build-loop"
|
|
26
|
+
cat >"$dir/.build-loop/state.json" <<'JSON'
|
|
27
|
+
{
|
|
28
|
+
"phase": "done",
|
|
29
|
+
"triggers": {"riskSurfaceChange": true},
|
|
30
|
+
"execution": {
|
|
31
|
+
"build_loop_id": "bl-itest-001",
|
|
32
|
+
"current_session_id": "sess-itest",
|
|
33
|
+
"started_by_session_id": "sess-itest",
|
|
34
|
+
"last_heartbeat_at": "2999-01-01T00:00:00Z",
|
|
35
|
+
"run_label": "itest#001"
|
|
36
|
+
},
|
|
37
|
+
"runs": []
|
|
38
|
+
}
|
|
39
|
+
JSON
|
|
40
|
+
printf '%s' "$dir"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
runs_count() { python3 -c "import json,sys;print(len(json.load(open(sys.argv[1])).get('runs',[])))" "$1/.build-loop/state.json"; }
|
|
44
|
+
|
|
45
|
+
# --- 1. present + matching session → records + surfaces WARN + exit 0 -------
|
|
46
|
+
P="$(make_project)"
|
|
47
|
+
OUT="$(printf '{"session_id":"sess-itest"}' | CLAUDE_PROJECT_DIR="$P" CLAUDE_PLUGIN_ROOT="$REPO" bash "$HOOK" stop)"
|
|
48
|
+
RC=$?
|
|
49
|
+
if [ "$RC" -eq 0 ] && [ "$(runs_count "$P")" = "1" ] && printf '%s' "$OUT" | grep -q '"systemMessage"' && printf '%s' "$OUT" | grep -q 'WARN'; then
|
|
50
|
+
ok "present+stakes → append_run ran + WARN surfaced + exit 0"
|
|
51
|
+
else
|
|
52
|
+
bad "present+stakes (rc=$RC runs=$(runs_count "$P") out=$OUT)"
|
|
53
|
+
fi
|
|
54
|
+
[ -f "$P/.build-loop/closeout-pending/bl-itest-001.md" ] && ok "closeout-pending marker written" || bad "marker not written"
|
|
55
|
+
|
|
56
|
+
# --- 1b. second Stop in the same run → no-op (no double-record, no advisory) -
|
|
57
|
+
OUT2="$(printf '{"session_id":"sess-itest"}' | CLAUDE_PROJECT_DIR="$P" CLAUDE_PLUGIN_ROOT="$REPO" bash "$HOOK" stop)"
|
|
58
|
+
if [ "$(runs_count "$P")" = "1" ] && ! printf '%s' "$OUT2" | grep -q 'systemMessage'; then
|
|
59
|
+
ok "second Stop same run → no-op"
|
|
60
|
+
else
|
|
61
|
+
bad "second Stop not idempotent (runs=$(runs_count "$P") out=$OUT2)"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# --- 1c. session-start surfaces the marker once, then archives it -----------
|
|
65
|
+
OUT3="$(CLAUDE_PROJECT_DIR="$P" CLAUDE_PLUGIN_ROOT="$REPO" bash "$HOOK" session-start </dev/null)"
|
|
66
|
+
if printf '%s' "$OUT3" | grep -q 'additionalContext' && printf '%s' "$OUT3" | grep -q 'bl-itest-001' \
|
|
67
|
+
&& [ ! -f "$P/.build-loop/closeout-pending/bl-itest-001.md" ] \
|
|
68
|
+
&& [ -f "$P/.build-loop/closeout-pending/surfaced/bl-itest-001.md" ]; then
|
|
69
|
+
ok "session-start surfaced marker once + archived"
|
|
70
|
+
else
|
|
71
|
+
bad "session-start surfacing (out=$OUT3)"
|
|
72
|
+
fi
|
|
73
|
+
rm -rf "$P"
|
|
74
|
+
|
|
75
|
+
# --- 2. no .build-loop/ → silent exit 0 ------------------------------------
|
|
76
|
+
P2="$(mktemp -d)"
|
|
77
|
+
OUT="$(printf '{"session_id":"x"}' | CLAUDE_PROJECT_DIR="$P2" CLAUDE_PLUGIN_ROOT="$REPO" bash "$HOOK" stop)"
|
|
78
|
+
RC=$?
|
|
79
|
+
if [ "$RC" -eq 0 ] && [ -z "$OUT" ]; then
|
|
80
|
+
ok "no .build-loop/ → silent exit 0"
|
|
81
|
+
else
|
|
82
|
+
bad "no .build-loop (rc=$RC out=$OUT)"
|
|
83
|
+
fi
|
|
84
|
+
rm -rf "$P2"
|
|
85
|
+
|
|
86
|
+
# --- 3. minimal PATH (/usr/bin:/bin — the real hook env) → still works ------
|
|
87
|
+
P3="$(make_project)"
|
|
88
|
+
OUT="$(printf '{"session_id":"sess-itest"}' | env -i PATH="/usr/bin:/bin" CLAUDE_PROJECT_DIR="$P3" CLAUDE_PLUGIN_ROOT="$REPO" bash "$HOOK" stop)"
|
|
89
|
+
RC=$?
|
|
90
|
+
if [ "$RC" -eq 0 ] && [ "$(runs_count "$P3")" = "1" ]; then
|
|
91
|
+
ok "minimal PATH=/usr/bin:/bin → records + exit 0"
|
|
92
|
+
else
|
|
93
|
+
bad "minimal PATH (rc=$RC runs=$(runs_count "$P3") out=$OUT)"
|
|
94
|
+
fi
|
|
95
|
+
rm -rf "$P3"
|
|
96
|
+
|
|
97
|
+
# --- 4. broken PATH (python not on PATH) → resolves via absolute fallback ---
|
|
98
|
+
# Invoke bash by absolute path (so the harness itself survives the broken PATH);
|
|
99
|
+
# inside, command -v python3 fails and the script must fall back to an absolute
|
|
100
|
+
# python (/usr/bin/python3 …). Contract: exit 0, never crash, valid/empty JSON.
|
|
101
|
+
P4="$(make_project)"
|
|
102
|
+
OUT="$(printf '{"session_id":"sess-itest"}' | env -i PATH="/nonexistent" CLAUDE_PROJECT_DIR="$P4" CLAUDE_PLUGIN_ROOT="$REPO" /bin/bash "$HOOK" stop 2>/dev/null)"
|
|
103
|
+
RC=$?
|
|
104
|
+
if [ "$RC" -eq 0 ] && { [ -z "$OUT" ] || printf '%s' "$OUT" | python3 -c 'import json,sys;json.load(sys.stdin)' 2>/dev/null; }; then
|
|
105
|
+
ok "broken PATH → fail-open exit 0 (absolute-fallback python or silent skip)"
|
|
106
|
+
else
|
|
107
|
+
bad "broken PATH not fail-open (rc=$RC out=$OUT)"
|
|
108
|
+
fi
|
|
109
|
+
rm -rf "$P4"
|
|
110
|
+
|
|
111
|
+
# --- 5. helper script missing (fake plugin root) → silent exit 0 -----------
|
|
112
|
+
P5="$(make_project)"
|
|
113
|
+
FAKE="$(mktemp -d)" # no scripts/stop_closeout.py here
|
|
114
|
+
OUT="$(printf '{"session_id":"sess-itest"}' | CLAUDE_PROJECT_DIR="$P5" CLAUDE_PLUGIN_ROOT="$FAKE" bash "$HOOK" stop)"
|
|
115
|
+
RC=$?
|
|
116
|
+
if [ "$RC" -eq 0 ] && [ "$(runs_count "$P5")" = "0" ]; then
|
|
117
|
+
ok "missing helper script → silent exit 0 (no record)"
|
|
118
|
+
else
|
|
119
|
+
bad "missing helper not fail-open (rc=$RC runs=$(runs_count "$P5") out=$OUT)"
|
|
120
|
+
fi
|
|
121
|
+
rm -rf "$P5" "$FAKE"
|
|
122
|
+
|
|
123
|
+
printf '\n%d passed, %d failed\n' "$PASS" "$FAIL"
|
|
124
|
+
[ "$FAIL" -eq 0 ]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tyroneross/build-loop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://npm.pkg.github.com",
|
|
6
6
|
"access": "public"
|
|
@@ -18,12 +18,14 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
20
|
"codex-skills",
|
|
21
|
+
"plugin-artifacts/codex",
|
|
21
22
|
"commands",
|
|
22
23
|
"skills",
|
|
23
24
|
"scripts/_paths.py",
|
|
24
25
|
"scripts/_db_url.py",
|
|
25
26
|
"scripts/blm.py",
|
|
26
27
|
"scripts/blm_api.py",
|
|
28
|
+
"scripts/build_codex_plugin_artifact.py",
|
|
27
29
|
"scripts/check_cache_sync.py",
|
|
28
30
|
"scripts/embed_backend.py",
|
|
29
31
|
"scripts/install_memory.py",
|
|
@@ -44,7 +46,7 @@
|
|
|
44
46
|
".cursor",
|
|
45
47
|
".claude-plugin",
|
|
46
48
|
".codex-plugin",
|
|
47
|
-
".agents",
|
|
49
|
+
".agents/plugins",
|
|
48
50
|
"README.md",
|
|
49
51
|
"AGENTS.md",
|
|
50
52
|
"LICENSE",
|
|
@@ -61,10 +63,11 @@
|
|
|
61
63
|
"clean": "rm -rf dist",
|
|
62
64
|
"plugin:prune-cache": "python3 scripts/prune_plugin_cache.py --source .",
|
|
63
65
|
"plugin:prune-cache:apply": "python3 scripts/prune_plugin_cache.py --source . --apply",
|
|
64
|
-
"plugin:sync-cache": "python3 scripts/sync_plugin_cache.py --source . --host
|
|
66
|
+
"plugin:sync-cache": "python3 scripts/sync_plugin_cache.py --source . --host claude && npm run codex:sync-cache",
|
|
65
67
|
"plugin:sync-cache:hooks": "python3 scripts/sync_plugin_cache.py --source . --host all --install-git-hooks",
|
|
66
68
|
"codex:prune-cache": "python3 scripts/prune_codex_plugin_cache.py --source .",
|
|
67
|
-
"codex:
|
|
69
|
+
"codex:build-artifact": "python3 scripts/build_codex_plugin_artifact.py --source . --target plugin-artifacts/codex",
|
|
70
|
+
"codex:sync-cache": "npm run codex:build-artifact && python3 scripts/sync_plugin_cache.py --source plugin-artifacts/codex --host codex",
|
|
68
71
|
"codex:prune-cache:apply": "python3 scripts/prune_codex_plugin_cache.py --source . --apply",
|
|
69
72
|
"claude:prune-cache": "python3 scripts/prune_plugin_cache.py --source . --host claude",
|
|
70
73
|
"claude:sync-cache": "python3 scripts/sync_plugin_cache.py --source . --host claude",
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "build-loop",
|
|
3
|
+
"version": "0.33.0",
|
|
4
|
+
"description": "Multi-phase build orchestration with native debugging: assess, plan, execute, review, iterate. Plan-verify gate on Phase 2. Optional UI design gates. Native debug-loop, debugging-memory, and logging-tracer skills provide root-cause investigation without a bundled MCP server. Orchestrator owns when-to-fire; bundled skills own procedural detail; bridges are optional escalation hops to supporting plugins for extended capability.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Tyrone Ross",
|
|
7
|
+
"url": "https://github.com/tyroneross"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/tyroneross/build-loop#readme",
|
|
10
|
+
"repository": "https://github.com/tyroneross/build-loop",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"development",
|
|
14
|
+
"orchestration",
|
|
15
|
+
"evaluation",
|
|
16
|
+
"iteration",
|
|
17
|
+
"build",
|
|
18
|
+
"tdd",
|
|
19
|
+
"fact-checking",
|
|
20
|
+
"code-quality",
|
|
21
|
+
"ui-validation",
|
|
22
|
+
"accessibility",
|
|
23
|
+
"design-rules",
|
|
24
|
+
"debug-loop",
|
|
25
|
+
"debugging",
|
|
26
|
+
"causal-tree",
|
|
27
|
+
"incident-memory"
|
|
28
|
+
],
|
|
29
|
+
"skills": "./skills",
|
|
30
|
+
"interface": {
|
|
31
|
+
"displayName": "Build Loop",
|
|
32
|
+
"shortDescription": "Multi-phase build orchestration with review gates, UI validation, debugging, and a Codex subagent adapter.",
|
|
33
|
+
"longDescription": "Multi-phase build orchestration with native debugging: assess, plan, execute, review, iterate. Plan-verify gate on Phase 2. Optional UI design gates. Native debug-loop, debugging-memory, and logging-tracer skills provide root-cause investigation without a bundled MCP server. Orchestrator owns when-to-fire; bundled skills own procedural detail; bridges are optional escalation hops to supporting plugins for extended capability.",
|
|
34
|
+
"developerName": "Ross Labs",
|
|
35
|
+
"category": "Coding",
|
|
36
|
+
"capabilities": [
|
|
37
|
+
"Read",
|
|
38
|
+
"Write"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|