Skip to content

Commit 797d1ea

Browse files
authored
Merge pull request #419 from ProverCoderAI/issue-417
fix(container): sync plan-to-git against upstream repo
2 parents 4581997 + 6637e88 commit 797d1ea

6 files changed

Lines changed: 180 additions & 103 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const githubRemoteHelpersTemplate = String.raw`docker_git_github_repo_from_remote_url() {
2+
local remote_url="$1"
3+
local repo_path=""
4+
local owner=""
5+
local repo=""
6+
7+
case "$remote_url" in
8+
https://github.com/*)
9+
repo_path="${"${"}remote_url#https://github.com/}"
10+
;;
11+
https://*@github.com/*)
12+
repo_path="${"${"}remote_url#https://*@github.com/}"
13+
;;
14+
ssh://git@github.com/*)
15+
repo_path="${"${"}remote_url#ssh://git@github.com/}"
16+
;;
17+
git@github.com:*)
18+
repo_path="${"${"}remote_url#git@github.com:}"
19+
;;
20+
*)
21+
return 1
22+
;;
23+
esac
24+
25+
repo_path="${"${"}repo_path%%\?*}"
26+
repo_path="${"${"}repo_path%%#*}"
27+
repo_path="${"${"}repo_path%/}"
28+
repo_path="${"${"}repo_path%.git}"
29+
owner="${"${"}repo_path%%/*}"
30+
repo="${"${"}repo_path#*/}"
31+
repo="${"${"}repo%%/*}"
32+
repo="${"${"}repo%.git}"
33+
34+
if [[ -z "$owner" || -z "$repo" || "$owner" == "$repo_path" ]]; then
35+
return 1
36+
fi
37+
38+
printf "%s/%s\n" "$owner" "$repo"
39+
}
40+
41+
docker_git_github_repo_from_remote() {
42+
local remote="$1"
43+
local remote_url=""
44+
45+
remote_url="$(git remote get-url "$remote" 2>/dev/null || true)"
46+
if [[ -z "$remote_url" ]]; then
47+
return 1
48+
fi
49+
50+
docker_git_github_repo_from_remote_url "$remote_url"
51+
}`
52+
53+
export const renderGitHubRemoteHelpers = (): string => githubRemoteHelpersTemplate

packages/container/src/core/templates-entrypoint/plan-to-git.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
1+
import { renderGitHubRemoteHelpers } from "./github-remotes.js"
2+
13
const planToGitHookPathsTemplate = `PLAN_TO_GIT_SYNC_HELPER="$HOOKS_DIR/plan-to-git-sync"
24
PLAN_TO_GIT_CODEX_HOOK="$HOOKS_DIR/plan-to-git-codex-hook"
35
PLAN_TO_GIT_CLAUDE_HOOK="$HOOKS_DIR/plan-to-git-claude-hook"
46
CODEX_REQUIREMENTS_FILE="/etc/codex/requirements.toml"
57
CLAUDE_PLAN_TO_GIT_SETTINGS_FILE="$CLAUDE_CONFIG_DIR/settings.json"`
68

9+
const planToGitRunnerTemplate = `${renderGitHubRemoteHelpers()}
10+
11+
docker_git_plan_to_git_run() {
12+
local base_repo=""
13+
14+
if ! base_repo="$(docker_git_github_repo_from_remote upstream)"; then
15+
base_repo="$(docker_git_github_repo_from_remote origin || true)"
16+
fi
17+
18+
if [[ -z "$base_repo" ]]; then
19+
plan-to-git "$@"
20+
return $?
21+
fi
22+
23+
PLAN_TO_GIT_REPO="$base_repo" plan-to-git "$@"
24+
}`
25+
726
const planToGitSyncHelperInstallTemplate = String.raw`cat <<'EOF' > "$PLAN_TO_GIT_SYNC_HELPER"
827
#!/usr/bin/env bash
928
set -euo pipefail
@@ -19,8 +38,10 @@ fi
1938
2039
export PLAN_TO_GIT_STATE_DIR="${"${"}PLAN_TO_GIT_STATE_DIR:-/tmp/plan-to-git}"
2140
41+
${planToGitRunnerTemplate}
42+
2243
docker_git_plan_to_git_explicit_pr_supported() {
23-
plan-to-git sync --help 2>/dev/null | grep -q -- "--pr <PR>"
44+
docker_git_plan_to_git_run sync --help 2>/dev/null | grep -q -- "--pr <PR>"
2445
}
2546
2647
docker_git_plan_to_git_resolve_pr_number() {
@@ -61,12 +82,12 @@ docker_git_plan_to_git_sync() {
6182
6283
if [[ -n "$pr_number" ]] && docker_git_plan_to_git_explicit_pr_supported; then
6384
echo "[plan-to-git] Syncing queued agent plans to PR #$pr_number"
64-
plan-to-git sync --pr "$pr_number"
85+
docker_git_plan_to_git_run sync --pr "$pr_number"
6586
return 0
6687
fi
6788
6889
echo "[plan-to-git] Syncing queued agent plans via current branch discovery"
69-
plan-to-git sync
90+
docker_git_plan_to_git_run sync
7091
}
7192
7293
docker_git_plan_to_git_sync
@@ -83,14 +104,15 @@ if [ "\${DOCKER_GIT_SKIP_PLAN_TO_GIT:-}" != "1" ]; then
83104
echo "[plan-to-git] Error: plan-to-git not found" >&2
84105
exit 1
85106
fi
86-
plan-to-git import-codex --no-sync
87-
plan-to-git import-claude --no-sync
107+
${planToGitRunnerTemplate}
108+
docker_git_plan_to_git_run import-codex --no-sync
109+
docker_git_plan_to_git_run import-claude --no-sync
88110
PLAN_TO_GIT_SYNC_HELPER="\${DOCKER_GIT_PLAN_TO_GIT_SYNC_HELPER:-/opt/docker-git/hooks/plan-to-git-sync}"
89111
if [[ -x "$PLAN_TO_GIT_SYNC_HELPER" ]]; then
90112
"$PLAN_TO_GIT_SYNC_HELPER"
91113
else
92114
echo "[plan-to-git] Sync helper not found; falling back to current branch discovery" >&2
93-
plan-to-git sync
115+
docker_git_plan_to_git_run sync
94116
fi
95117
fi`
96118

@@ -108,7 +130,8 @@ if ! command -v plan-to-git >/dev/null 2>&1; then
108130
fi
109131
110132
export PLAN_TO_GIT_STATE_DIR="${"${"}PLAN_TO_GIT_STATE_DIR:-/tmp/plan-to-git}"
111-
plan-to-git hook --source codex
133+
${planToGitRunnerTemplate}
134+
docker_git_plan_to_git_run hook --source codex
112135
PLAN_TO_GIT_SYNC_HELPER="${"${"}DOCKER_GIT_PLAN_TO_GIT_SYNC_HELPER:-/opt/docker-git/hooks/plan-to-git-sync}"
113136
"$PLAN_TO_GIT_SYNC_HELPER" >&2 || true
114137
EOF
@@ -128,7 +151,8 @@ if ! command -v plan-to-git >/dev/null 2>&1; then
128151
fi
129152
130153
export PLAN_TO_GIT_STATE_DIR="${"${"}PLAN_TO_GIT_STATE_DIR:-/tmp/plan-to-git}"
131-
plan-to-git hook --source claude
154+
${planToGitRunnerTemplate}
155+
docker_git_plan_to_git_run hook --source claude
132156
PLAN_TO_GIT_SYNC_HELPER="${"${"}DOCKER_GIT_PLAN_TO_GIT_SYNC_HELPER:-/opt/docker-git/hooks/plan-to-git-sync}"
133157
"$PLAN_TO_GIT_SYNC_HELPER" >&2 || true
134158
EOF

packages/container/src/core/templates-entrypoint/post-push-pr.ts

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,10 @@
1-
const postPushPrEnsureTemplate = String
2-
.raw`# CHANGE: ensure an open GitHub PR exists for the pushed branch before PR-bound post-push tools run.
1+
import { renderGitHubRemoteHelpers } from "./github-remotes.js"
2+
3+
const postPushPrEnsureTemplate =
4+
`# CHANGE: ensure an open GitHub PR exists for the pushed branch before PR-bound post-push tools run.
35
# WHY: issue #375 requires every successful git push to leave the branch with an open PR; plan sync and session backup both target PR discussion.
46
# REF: issue-375
5-
docker_git_github_repo_from_remote_url() {
6-
local remote_url="$1"
7-
local repo_path=""
8-
local owner=""
9-
local repo=""
10-
11-
case "$remote_url" in
12-
https://github.com/*)
13-
repo_path="${"${"}remote_url#https://github.com/}"
14-
;;
15-
https://github.com/*)
16-
repo_path="${"${"}remote_url#https://github.com/}"
17-
;;
18-
https://*@github.com/*)
19-
repo_path="${"${"}remote_url#https://*@github.com/}"
20-
;;
21-
https://*@github.com/*)
22-
repo_path="${"${"}remote_url#https://*@github.com/}"
23-
;;
24-
ssh://git@github.com/*)
25-
repo_path="${"${"}remote_url#ssh://git@github.com/}"
26-
;;
27-
git@github.com:*)
28-
repo_path="${"${"}remote_url#git@github.com:}"
29-
;;
30-
*)
31-
return 1
32-
;;
33-
esac
34-
35-
repo_path="${"${"}repo_path%%\?*}"
36-
repo_path="${"${"}repo_path%%#*}"
37-
repo_path="${"${"}repo_path%/}"
38-
repo_path="${"${"}repo_path%.git}"
39-
owner="${"${"}repo_path%%/*}"
40-
repo="${"${"}repo_path#*/}"
41-
repo="${"${"}repo%%/*}"
42-
repo="${"${"}repo%.git}"
43-
44-
if [[ -z "$owner" || -z "$repo" || "$owner" == "$repo_path" ]]; then
45-
return 1
46-
fi
47-
48-
printf "%s/%s\n" "$owner" "$repo"
49-
}
50-
51-
docker_git_github_repo_from_remote() {
52-
local remote="$1"
53-
local remote_url=""
54-
55-
remote_url="$(git remote get-url "$remote" 2>/dev/null || true)"
56-
if [[ -z "$remote_url" ]]; then
57-
return 1
58-
fi
59-
60-
docker_git_github_repo_from_remote_url "$remote_url"
61-
}
7+
${renderGitHubRemoteHelpers()}
628
639
docker_git_ensure_open_pr() {
6410
local branch=""
@@ -100,8 +46,8 @@ docker_git_ensure_open_pr() {
10046
if [[ "$head_repo" == "$base_repo" ]]; then
10147
head_arg="$branch"
10248
else
103-
head_owner="${"${"}head_repo%%/*}"
104-
head_arg="${"${"}head_owner}:${"${"}branch}"
49+
head_owner="\${head_repo%%/*}"
50+
head_arg="\${head_owner}:\${branch}"
10551
fi
10652
10753
if ! pr_url="$(gh pr list --repo "$base_repo" --state open --head "$head_arg" --json url --jq '.[0].url // ""' 2>/dev/null)"; then

packages/container/src/core/templates/dockerfile-prelude.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ RUN cargo install --git https://github.com/ProverCoderAI/rust-browser-connection
8383
RUN printf "%s\\n" "ALL ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/zz-all \
8484
&& chmod 0440 /etc/sudoers.d/zz-all`
8585

86-
const planToGitRevision = "f60fbe71131854be4c6c1d9fb79abafd2dd6949b"
86+
const planToGitRevision = "4e58e315d3a06db3f9e75682455be315cd29d7c8"
8787

8888
// CHANGE: install plan-to-git in generated project containers.
8989
// WHY: issue #397 requires multi-agent plan capture, Claude Code hooks, temp-backed state, and explicit PR sync.
9090
// QUOTE(ТЗ): "подключение новое версии plan-to-git и настройки hooks для claude code и настройки что бы всё уходило на гитхаб автоматически"
9191
// REF: issue-397
92-
// SOURCE: https://github.com/ProverCoderAI/plan-to-git/tree/f60fbe71131854be4c6c1d9fb79abafd2dd6949b
92+
// SOURCE: https://github.com/ProverCoderAI/plan-to-git/tree/4e58e315d3a06db3f9e75682455be315cd29d7c8
9393
// FORMAT THEOREM: image_build_success -> executable(/usr/local/bin/plan-to-git)
9494
// PURITY: SHELL
9595
// EFFECT: Docker build downloads and installs a pinned Rust CLI from GitHub.
@@ -99,6 +99,7 @@ const renderDockerfilePlanToGit = (): string =>
9999
`# Install plan-to-git for multi-agent plan capture and explicit PR sync (issue #397)
100100
RUN cargo install --git https://github.com/ProverCoderAI/plan-to-git --rev ${planToGitRevision} --locked --bins --root /usr/local \
101101
&& /usr/local/bin/plan-to-git --help >/dev/null \
102+
&& /usr/local/bin/plan-to-git --help | grep -q -- "--repo" \
102103
&& /usr/local/bin/plan-to-git hook --help | grep -q -- "claude" \
103104
&& /usr/local/bin/plan-to-git sync --help | grep -q -- "--pr <PR>"`
104105

0 commit comments

Comments
 (0)