bigpowers 2.66.0 → 2.67.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 (47) hide show
  1. package/.fix_regex.sh +16 -0
  2. package/.hermes-verify-sed-fix.py +53 -0
  3. package/.pi/package.json +2 -2
  4. package/.pi/prompts/build-epic.md +8 -0
  5. package/.pi/prompts/gate-trace.md +2 -1
  6. package/.pi/prompts/kickoff-branch.md +19 -0
  7. package/.pi/prompts/maintain-wiki.md +63 -0
  8. package/.pi/prompts/plan-tests.md +1 -1
  9. package/.pi/prompts/release-branch.md +17 -13
  10. package/.pi/prompts/verify-work.md +9 -5
  11. package/.pi/skills/build-epic/SKILL.md +8 -0
  12. package/.pi/skills/gate-trace/SKILL.md +2 -1
  13. package/.pi/skills/kickoff-branch/SKILL.md +19 -0
  14. package/.pi/skills/maintain-wiki/SKILL.md +65 -0
  15. package/.pi/skills/plan-tests/SKILL.md +1 -1
  16. package/.pi/skills/release-branch/SKILL.md +17 -13
  17. package/.pi/skills/verify-work/SKILL.md +9 -5
  18. package/CHANGELOG.md +13 -0
  19. package/README.md +1 -1
  20. package/SKILL-INDEX.md +1 -1
  21. package/_test_e28s01.sh +2 -0
  22. package/hermes-verify-sed-fix.py +30 -0
  23. package/package.json +1 -1
  24. package/scripts/build-skill-graph.sh +151 -183
  25. package/scripts/check-spec-drift.sh +121 -0
  26. package/scripts/check-spec-version-gap.sh +143 -0
  27. package/scripts/decompose-conventions.sh +147 -0
  28. package/scripts/generate-agent-guide.sh +89 -0
  29. package/scripts/hermes-verify-e39s02.sh +28 -0
  30. package/scripts/migrate-version.sh +721 -0
  31. package/scripts/okf-post-sync.sh +163 -0
  32. package/scripts/validate-okf.sh +18 -0
  33. package/skills/build-epic/SKILL.md +8 -0
  34. package/skills/gate-trace/SKILL.md +2 -1
  35. package/skills/kickoff-branch/SKILL.md +19 -0
  36. package/skills/maintain-wiki/SKILL.md +66 -0
  37. package/skills/plan-tests/SKILL.md +1 -1
  38. package/skills/release-branch/SKILL.md +17 -13
  39. package/skills/verify-work/SKILL.md +9 -5
  40. package/skills-lock.json +11 -6
  41. package/tests/fixtures/v1.x-project/CLAUDE.md +4 -0
  42. package/tests/fixtures/v1.x-project/CONVENTIONS.md +4 -0
  43. package/tests/fixtures/v2.0.0-project/CLAUDE.md +4 -0
  44. package/tests/fixtures/v2.0.0-project/CONVENTIONS.md +3 -0
  45. package/tests/fixtures/v2.20-project/CLAUDE.md +4 -0
  46. package/tests/fixtures/v2.20-project/CONVENTIONS.md +4 -0
  47. package/tests/run-golden-migrate-version.sh +155 -0
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env bash
2
+ # story: e39s05
3
+ # Decompose CONVENTIONS.md into specs/conventions-wiki/ OKF concept bundle
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
8
+ CONVENTIONS="$REPO_ROOT/CONVENTIONS.md"
9
+ CONVENTIONS_WIKI="$REPO_ROOT/specs/conventions-wiki"
10
+ CONVENTIONS_INDEX="$CONVENTIONS_WIKI/index.md"
11
+ SKILL_GRAPH="$REPO_ROOT/specs/skill-graph.json"
12
+
13
+ show_help() {
14
+ cat <<EOF
15
+ Usage: $(basename "$0") [OPTION]
16
+
17
+ Decompose CONVENTIONS.md into specs/conventions-wiki/ OKF concept bundle.
18
+ Each major heading becomes a concept page with cross-references to enforcing skills.
19
+
20
+ Options:
21
+ --help Show this help and exit
22
+ EOF
23
+ }
24
+
25
+ if [ "$#" -eq 1 ] && [ "$1" = "--help" ]; then
26
+ show_help
27
+ exit 0
28
+ fi
29
+
30
+ if [ ! -f "$CONVENTIONS" ]; then
31
+ echo "[ERROR] CONVENTIONS.md not found at $CONVENTIONS" >&2
32
+ exit 1
33
+ fi
34
+
35
+ mkdir -p "$CONVENTIONS_WIKI"
36
+
37
+ # Generate index page
38
+ cat > "$CONVENTIONS_INDEX" << 'IDXEOF'
39
+ ---
40
+ type: Index
41
+ title: Conventions Wiki
42
+ context: conventions
43
+ ---
44
+
45
+ # Conventions Wiki — OKF Bundle
46
+
47
+ **Generated by:** scripts/decompose-conventions.sh (e39s05)
48
+
49
+ ## Convention Sections
50
+
51
+ IDXEOF
52
+
53
+ # Parse CONVENTIONS.md headings into sections
54
+ python3 -c "
55
+ import re, os, json
56
+
57
+ with open('$CONVENTIONS') as f:
58
+ content = f.read()
59
+
60
+ # Split on markdown headings (## or ###)
61
+ sections = re.split(r'^(#{2,3})\s+(.+)$', content, flags=re.MULTILINE)
62
+
63
+ # Load skill graph for cross-references
64
+ graph_data = {}
65
+ if os.path.exists('$SKILL_GRAPH'):
66
+ with open('$SKILL_GRAPH') as gf:
67
+ graph_data = json.load(gf)
68
+
69
+ convention_skills = {} # convention_name -> [skill_names]
70
+
71
+ # Build mapping from edges (skill -> convention)
72
+ for edge in graph_data.get('edges', []):
73
+ src = edge.get('source', '')
74
+ tgt = edge.get('target', '')
75
+ rel = edge.get('relation', '')
76
+ if rel == 'enforces' and tgt:
77
+ # tgt is something like 'CONVENTIONS.md §Tests;'
78
+ convention_name = tgt.replace('CONVENTIONS.md', '').replace('§', '').replace(';', '').strip()
79
+ if convention_name:
80
+ if convention_name not in convention_skills:
81
+ convention_skills[convention_name] = []
82
+ convention_skills[convention_name].append(src)
83
+
84
+ # Process sections
85
+ current_level = ''
86
+ current_title = ''
87
+ current_body = []
88
+ section_count = 0
89
+
90
+ for part in sections:
91
+ if part in ('##', '###'):
92
+ current_level = part
93
+ elif current_level and (current_title == ''):
94
+ current_title = part.strip()
95
+ elif current_level and current_title:
96
+ current_body.append(part)
97
+ elif current_level and current_title and not part.startswith('#'):
98
+ current_body.append(part)
99
+
100
+ # Actually let me rebuild this properly
101
+ lines = content.split('\n')
102
+ i = 0
103
+ sections_data = []
104
+ current = None
105
+
106
+ while i < len(lines):
107
+ line = lines[i]
108
+ m = re.match(r'^(###?)\s+(.+)$', line)
109
+ if m:
110
+ if current:
111
+ sections_data.append(current)
112
+ current = {
113
+ 'level': len(m.group(1)),
114
+ 'title': m.group(2).strip(),
115
+ 'body': []
116
+ }
117
+ elif current:
118
+ current['body'].append(line)
119
+ i += 1
120
+
121
+ if current:
122
+ sections_data.append(current)
123
+
124
+ with open('$CONVENTIONS_INDEX', 'a') as idx:
125
+ for sec in sections_data:
126
+ slug = re.sub(r'[^a-z0-9]+', '-', sec['title'].lower()).strip('-')
127
+ sec_file = os.path.join('$CONVENTIONS_WIKI', f'{slug}.md')
128
+
129
+ # Check for enforcing skills
130
+ enforcing = convention_skills.get(sec['title'], [])
131
+
132
+ body_text = '\n'.join(sec['body']).strip()
133
+
134
+ with open(sec_file, 'w') as sf:
135
+ sf.write(f'---\ntype: Convention\ntitle: {sec[\"title\"]}\ncontext: conventions\n')
136
+ if enforcing:
137
+ sf.write(f'enforced_by:\n')
138
+ for sk in enforcing:
139
+ sf.write(f' - {sk}\n')
140
+ sf.write(f'---\n\n# {sec[\"title\"]}\n\n')
141
+ sf.write(f'{body_text}\n\n---\n*Auto-generated by scripts/decompose-conventions.sh (e39s05)*\n')
142
+
143
+ idx.write(f'- [{sec[\"title\"]}]({slug}.md)\\n')
144
+ section_count += 1
145
+
146
+ print(f'OK: {section_count} convention sections written to specs/conventions-wiki/')
147
+ "
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env bash
2
+ # story: e39s06
3
+ # Decompose CLAUDE.md into specs/agent-guide/ for progressive disclosure
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
8
+ CLAUDE_MD="$REPO_ROOT/CLAUDE.md"
9
+ AGENT_GUIDE="$REPO_ROOT/specs/agent-guide"
10
+
11
+ show_help() {
12
+ cat <<EOF
13
+ Usage: $(basename "$0") [OPTION]
14
+
15
+ Decompose CLAUDE.md into specs/agent-guide/ OKF concept pages.
16
+ Each section becomes a Guide concept with thin pointers.
17
+
18
+ Options:
19
+ --help Show this help and exit
20
+ EOF
21
+ }
22
+
23
+ if [ "$#" -eq 1 ] && [ "$1" = "--help" ]; then
24
+ show_help
25
+ exit 0
26
+ fi
27
+
28
+ if [ ! -f "$CLAUDE_MD" ]; then
29
+ echo "[WARN] CLAUDE.md not found — trying GEMINI.md" >&2
30
+ CLAUDE_MD="$REPO_ROOT/GEMINI.md"
31
+ if [ ! -f "$CLAUDE_MD" ]; then
32
+ echo "[ERROR] Neither CLAUDE.md nor GEMINI.md found" >&2
33
+ exit 1
34
+ fi
35
+ fi
36
+
37
+ mkdir -p "$AGENT_GUIDE"
38
+
39
+ python3 -c "
40
+ import re, os
41
+
42
+ with open('$CLAUDE_MD') as f:
43
+ content = f.read()
44
+
45
+ lines = content.split('\n')
46
+ sections = []
47
+ current_title = ''
48
+ current_body = []
49
+
50
+ for line in lines:
51
+ m = re.match(r'^(#{2,3})\s+(.+)$', line)
52
+ if m:
53
+ if current_title:
54
+ sections.append((current_title, '\n'.join(current_body)))
55
+ current_title = m.group(2).strip()
56
+ current_body = []
57
+ elif current_title:
58
+ current_body.append(line)
59
+
60
+ if current_title:
61
+ sections.append((current_title, '\n'.join(current_body)))
62
+
63
+ guide_dir = '$AGENT_GUIDE'
64
+
65
+ with open(os.path.join(guide_dir, 'index.md'), 'w') as idx:
66
+ idx.write('---\ntype: Index\ntitle: Agent Guide\ncontext: guide\n---\n\n')
67
+ idx.write('# Agent Guide — OKF Bundle\n\n')
68
+ idx.write(f'**Generated by:** scripts/generate-agent-guide.sh (e39s06)\n')
69
+ idx.write(f'**Source:** CLAUDE.md\n\n')
70
+ idx.write('## Guide Sections\n\n')
71
+
72
+ for title, body in sections:
73
+ slug = re.sub(r'[^a-z0-9]+', '-', title.lower()).strip('-')
74
+ sec_file = os.path.join(guide_dir, f'{slug}.md')
75
+
76
+ with open(sec_file, 'w') as sf:
77
+ sf.write(f'---\ntype: Guide\ntitle: {title}\ncontext: guide\n')
78
+ sf.write(f'source: CLAUDE.md#{slug}\n---\n\n')
79
+ sf.write(f'# {title}\n\n')
80
+ # Thin pointer — first 200 chars
81
+ preview = body.strip()[:200]
82
+ sf.write(f'{preview}\n\n')
83
+ sf.write(f'> Full content: $CLAUDE_MD section \"{title}\"\n')
84
+ sf.write('---\n*Auto-generated by scripts/generate-agent-guide.sh*\n')
85
+
86
+ idx.write(f'- [{title}]({slug}.md)\n')
87
+
88
+ print(f'OK: {len(sections)} guide sections written to specs/agent-guide/')
89
+ "
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ # Ad-hoc verification: e39s02 agent-locks protocol
3
+ REPO="/Users/danielvm/Developer/bigpowers"
4
+ ERR=0
5
+ echo "=== e39s02 agent-locks verification ==="
6
+
7
+ echo -n "1. agent-locks.yaml: "
8
+ test -f "$REPO/specs/agent-locks.yaml" || { echo "MISSING"; ERR=1; }
9
+ LOCKS=$(yq '.locks | length' "$REPO/specs/agent-locks.yaml" 2>/dev/null)
10
+ [ "$LOCKS" = "0" ] && echo "OK (0 locks)" || { echo "FAIL ($LOCKS)"; ERR=1; }
11
+
12
+ echo -n "2. kickoff-branch: "
13
+ grep -q 'agent-locks' "$REPO/skills/kickoff-branch/SKILL.md" && echo "OK" || { echo "FAIL"; ERR=1; }
14
+
15
+ echo -n "3. release-branch: "
16
+ grep -q 'agent-locks' "$REPO/skills/release-branch/SKILL.md" && echo "OK" || { echo "FAIL"; ERR=1; }
17
+
18
+ echo -n "4. CI workflow: "
19
+ grep -rq 'agent-locks' "$REPO/.github/workflows/" && echo "OK" || { echo "FAIL"; ERR=1; }
20
+ echo -n " 24h threshold: "
21
+ grep -q 'timedelta(hours=24)' "$REPO/.github/workflows/agent-locks.yml" && echo "OK" || { echo "FAIL"; ERR=1; }
22
+ echo -n " exit(1): "
23
+ grep -q 'sys.exit(1)' "$REPO/.github/workflows/agent-locks.yml" && echo "OK" || { echo "FAIL"; ERR=1; }
24
+ echo -n " hourly cron: "
25
+ grep -q 'cron: "0 \* \* \* \*"' "$REPO/.github/workflows/agent-locks.yml" && echo "OK" || { echo "FAIL"; ERR=1; }
26
+
27
+ [ $ERR -eq 0 ] && echo "ALL CHECKS PASSED" || echo "SOME FAILED"
28
+ exit $ERR