Skip to content

Commit 45b6935

Browse files
authored
Merge pull request #36 from ChronoAIProject/auto-refact-dev
Auto refact dev
2 parents 69e42d5 + 13a3042 commit 45b6935

83 files changed

Lines changed: 18626 additions & 1977 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"statusLine": {
3+
"type": "command",
4+
"command": "$CLAUDE_PROJECT_DIR/skills/codex-refactor-loop/scripts/statusline.sh"
5+
}
6+
}

.codex-plugin/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"interface": {
2525
"displayName": "Consensus R&D",
2626
"shortDescription": "偏置独立的多角度共识构建引擎",
27-
"longDescription": "把任意持续向仓库提交状态的活动当作研发:多 solver 先验对立、互不可见,meta-judge 仲裁收敛,验证侧同构。当前内置 codex-refactor-loop 无人值守三阶段循环(audit → implement → verify)",
27+
"longDescription": "把任意持续向仓库提交状态的活动当作研发:多 solver 先验对立、互不可见,meta-judge 仲裁收敛,验证侧同构。当前内置 codex-refactor-loop 是 Consensus R&D work-unit 循环的稳定入口;audit/refactor 保留为兼容 intake",
2828
"developerName": "auric",
2929
"category": "Coding",
3030
"capabilities": [
@@ -33,7 +33,7 @@
3333
"Write"
3434
],
3535
"defaultPrompt": [
36-
"对本仓库跑一轮无人值守共识重构循环"
36+
"对本仓库跑一轮无人值守 Consensus R&D work-unit 循环;audit/refactor 可作为兼容 intake"
3737
],
3838
"websiteURL": "https://github.com/ChronoAIProject/consensus-rnd"
3939
}

.github/scripts/bump_version.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#!/usr/bin/env python3
2+
"""Synchronize release manifest versions."""
3+
4+
from __future__ import annotations
5+
6+
import argparse
7+
import json
8+
import re
9+
import sys
10+
from dataclasses import dataclass
11+
from pathlib import Path
12+
from typing import Any
13+
14+
15+
ROOT = Path(__file__).resolve().parents[2]
16+
MAP_PATH = ROOT / ".version-bump.json"
17+
SEMVER_RE = re.compile(r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$")
18+
19+
20+
@dataclass(frozen=True)
21+
class ManifestTarget:
22+
path: Path
23+
field: str
24+
version: str
25+
data: Any
26+
27+
28+
def parse_version(version: str) -> tuple[int, int, int]:
29+
match = SEMVER_RE.match(version)
30+
if not match:
31+
raise ValueError(f"invalid semver: {version}")
32+
return tuple(int(part) for part in match.groups())
33+
34+
35+
def bump_semver(version: str, level: str) -> str:
36+
major, minor, patch = parse_version(version)
37+
if level == "major":
38+
return f"{major + 1}.0.0"
39+
if level == "minor":
40+
return f"{major}.{minor + 1}.0"
41+
if level == "patch":
42+
return f"{major}.{minor}.{patch + 1}"
43+
raise ValueError(f"invalid bump level: {level}")
44+
45+
46+
def resolve_field(data: Any, field: str) -> Any:
47+
current = data
48+
for part in field.split("."):
49+
if isinstance(current, list):
50+
if not part.isdigit():
51+
raise KeyError(f"expected list index at {part!r} in {field}")
52+
index = int(part)
53+
current = current[index]
54+
continue
55+
if not isinstance(current, dict):
56+
raise KeyError(f"cannot resolve {part!r} in {field}")
57+
current = current[part]
58+
return current
59+
60+
61+
def set_field(data: Any, field: str, value: str) -> None:
62+
current = data
63+
parts = field.split(".")
64+
for part in parts[:-1]:
65+
if isinstance(current, list):
66+
if not part.isdigit():
67+
raise KeyError(f"expected list index at {part!r} in {field}")
68+
current = current[int(part)]
69+
continue
70+
if not isinstance(current, dict):
71+
raise KeyError(f"cannot resolve {part!r} in {field}")
72+
current = current[part]
73+
74+
last = parts[-1]
75+
if isinstance(current, list):
76+
if not last.isdigit():
77+
raise KeyError(f"expected list index at {last!r} in {field}")
78+
current[int(last)] = value
79+
elif isinstance(current, dict):
80+
current[last] = value
81+
else:
82+
raise KeyError(f"cannot set {last!r} in {field}")
83+
84+
85+
def read_json(path: Path) -> Any:
86+
with path.open("r", encoding="utf-8") as handle:
87+
return json.load(handle)
88+
89+
90+
def write_json(path: Path, data: Any) -> None:
91+
with path.open("w", encoding="utf-8") as handle:
92+
json.dump(data, handle, ensure_ascii=False, indent=2)
93+
handle.write("\n")
94+
95+
96+
def load_targets(root: Path = ROOT) -> list[ManifestTarget]:
97+
mapping = read_json(root / ".version-bump.json")
98+
targets: list[ManifestTarget] = []
99+
for item in mapping["files"]:
100+
path = root / item["path"]
101+
field = item["field"]
102+
data = read_json(path)
103+
version = resolve_field(data, field)
104+
if not isinstance(version, str):
105+
raise ValueError(f"{item['path']}:{field} is not a string")
106+
parse_version(version)
107+
targets.append(ManifestTarget(path=path, field=field, version=version, data=data))
108+
return targets
109+
110+
111+
# Refactor (iter3/skill-release-pipeline): Old: 无机械 release 管道 New: bump_version + release.yml minimal option A(#32 minimal 共识)
112+
def assert_versions_sync(targets: list[ManifestTarget]) -> str:
113+
versions = {target.version for target in targets}
114+
if len(versions) != 1:
115+
lines = ["manifest versions are not synchronized:"]
116+
lines.extend(f"- {target.path.relative_to(ROOT)}:{target.field} = {target.version}" for target in targets)
117+
raise ValueError("\n".join(lines))
118+
return targets[0].version
119+
120+
121+
# Refactor (iter3/skill-release-pipeline): Old: 无机械 release 管道 New: bump_version + release.yml minimal option A(#32 minimal 共识)
122+
def write_version(targets: list[ManifestTarget], version: str, dry_run: bool) -> None:
123+
parse_version(version)
124+
for target in targets:
125+
set_field(target.data, target.field, version)
126+
if dry_run:
127+
return
128+
for target in targets:
129+
write_json(target.path, target.data)
130+
131+
132+
# Refactor (iter3/skill-release-pipeline): Old: 无机械 release 管道 New: bump_version + release.yml minimal option A(#32 minimal 共识)
133+
def main(argv: list[str] | None = None) -> int:
134+
parser = argparse.ArgumentParser(description=__doc__)
135+
parser.add_argument("--check", action="store_true", help="validate mapped manifest versions are synchronized")
136+
parser.add_argument("--read-version", action="store_true", help="print the synchronized manifest version")
137+
parser.add_argument("--dry-run", action="store_true", help="compute changes without writing files")
138+
parser.add_argument("--level", choices=("patch", "minor", "major"), help="semver bump level")
139+
parser.add_argument("--version", help="exact semver version to write")
140+
args = parser.parse_args(argv)
141+
142+
try:
143+
if args.level and args.version:
144+
raise ValueError("--level and --version are mutually exclusive")
145+
targets = load_targets()
146+
current = assert_versions_sync(targets)
147+
next_version = args.version or (bump_semver(current, args.level) if args.level else None)
148+
if next_version is not None:
149+
write_version(targets, next_version, args.dry_run)
150+
current = next_version
151+
if args.read_version:
152+
print(current)
153+
except Exception as exc:
154+
print(f"bump_version.py: {exc}", file=sys.stderr)
155+
return 1
156+
return 0
157+
158+
159+
if __name__ == "__main__":
160+
raise SystemExit(main())
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
name: consensus-rnd-ci
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- auto-refact-dev
7+
- dev
8+
push:
9+
branches:
10+
- auto-refact-dev
11+
- dev
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
17+
concurrency:
18+
group: consensus-rnd-ci-${{ github.workflow }}-${{ github.ref }}
19+
cancel-in-progress: true
20+
21+
jobs:
22+
contract-tests:
23+
name: contract-tests
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
31+
- name: Fetch source-regression base
32+
run: git fetch origin auto-refact-dev
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: "3.12"
38+
39+
- name: Run contract tests
40+
run: python3 -m unittest discover -s skills/codex-refactor-loop/scripts -p 'test_*.py'
41+
42+
manifest-version-sync:
43+
name: manifest-version-sync
44+
runs-on: ubuntu-latest
45+
steps:
46+
- name: Checkout
47+
uses: actions/checkout@v4
48+
49+
- name: Set up Python
50+
uses: actions/setup-python@v5
51+
with:
52+
python-version: "3.12"
53+
54+
- name: Check manifest version sync
55+
run: python3 skills/codex-refactor-loop/scripts/check_manifest_version_sync.py
56+
57+
skill-degradation:
58+
name: skill-degradation
59+
runs-on: ubuntu-latest
60+
steps:
61+
- name: Checkout
62+
uses: actions/checkout@v4
63+
64+
- name: Set up Python
65+
uses: actions/setup-python@v5
66+
with:
67+
python-version: "3.12"
68+
69+
- name: Check skill degradation
70+
run: python3 skills/codex-refactor-loop/scripts/check_skill_degradation.py --static
71+
72+
lint-advisory:
73+
name: lint-advisory
74+
runs-on: ubuntu-latest
75+
steps:
76+
- name: Checkout
77+
uses: actions/checkout@v4
78+
79+
- name: Set up Python
80+
uses: actions/setup-python@v5
81+
with:
82+
python-version: "3.12"
83+
84+
- name: Install advisory lint tools
85+
shell: bash
86+
run: |
87+
set +e
88+
python3 -m pip install --user ruff
89+
RUFF_INSTALL_STATUS=$?
90+
npm install -g markdownlint-cli2
91+
MARKDOWNLINT_INSTALL_STATUS=$?
92+
{
93+
echo "## lint-advisory installs"
94+
echo "- ruff install exit: ${RUFF_INSTALL_STATUS}"
95+
echo "- markdownlint-cli2 install exit: ${MARKDOWNLINT_INSTALL_STATUS}"
96+
} >> "$GITHUB_STEP_SUMMARY"
97+
exit 0
98+
99+
- name: Run advisory linters
100+
shell: bash
101+
run: |
102+
set +e
103+
shellcheck skills/codex-refactor-loop/scripts/*.sh
104+
SHELLCHECK_STATUS=$?
105+
python3 -m ruff check --select E9,F63,F7,F82 skills/codex-refactor-loop/scripts/*.py
106+
RUFF_STATUS=$?
107+
markdownlint-cli2 "**/*.md" "!node_modules" "!.git" "!.refactor-loop"
108+
MARKDOWNLINT_STATUS=$?
109+
{
110+
echo "## lint-advisory results"
111+
echo "- shellcheck exit: ${SHELLCHECK_STATUS}"
112+
echo "- ruff exit: ${RUFF_STATUS}"
113+
echo "- markdownlint-cli2 exit: ${MARKDOWNLINT_STATUS}"
114+
} >> "$GITHUB_STEP_SUMMARY"
115+
exit 0

0 commit comments

Comments
 (0)