- Replace all occurrences of 'ss-tools' with 'superset-tools' in 104 files - Rename git bundle file ss-tools.bundle → superset-tools.bundle - Update .gitignore pattern accordingly - Preserve variable names (hasSsTools etc.) and code identifiers
162 lines
6.9 KiB
Python
162 lines
6.9 KiB
Python
# #region MergePrompts [C:2] [TYPE Module]
|
|
# @LAYER Infra
|
|
# @BRIEF Merge all agent prompts, skills, constitution, and speckit commands into one file for external LLM review.
|
|
# @RATIONALE Other LLMs need the full protocol context to evaluate the prompt architecture. This script mirrors merge_spec.py pattern.
|
|
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
REVIEW_PROMPT = (
|
|
"Below is the complete GRACE-Poly semantic protocol for the superset-tools project — "
|
|
"agent prompts, skills, constitution, and speckit workflow commands.\n\n"
|
|
"Your task: independently review this protocol architecture. Evaluate:\n"
|
|
"1. Consistency across agents — do all agents follow the same structural pattern?\n"
|
|
"2. Attention optimization — are contracts optimized for MLA/CSA/HCA/DSA compression?\n"
|
|
"3. Cross-stack integrity — do Python and Svelte contracts align at API boundaries?\n"
|
|
"4. Decision memory coverage — are @RATIONALE/@REJECTED present where needed?\n"
|
|
"5. Gaps and contradictions — what is missing or inconsistent?\n"
|
|
"Focus on architectural review, not implementation details.\n"
|
|
)
|
|
|
|
# Canonical order for the merged output
|
|
CANONICAL_ORDER = [
|
|
# Layer 1: Constitution (project laws)
|
|
("file", ".specify/memory/constitution.md", "CONSTITUTION — Project Laws"),
|
|
# Layer 2: Skills (protocol reference)
|
|
("file", ".opencode/skills/semantics-core/SKILL.md", "SKILL — Semantics Core"),
|
|
("file", ".opencode/skills/semantics-contracts/SKILL.md", "SKILL — Semantics Contracts"),
|
|
("file", ".opencode/skills/semantics-python/SKILL.md", "SKILL — Semantics Python"),
|
|
("file", ".opencode/skills/semantics-svelte/SKILL.md", "SKILL — Semantics Svelte"),
|
|
("file", ".opencode/skills/semantics-testing/SKILL.md", "SKILL — Semantics Testing"),
|
|
("file", ".opencode/skills/molecular-cot-logging/SKILL.md", "SKILL — Molecular CoT Logging"),
|
|
# Layer 3: Agent Prompts (thin shims)
|
|
("file", ".opencode/agents/semantic-curator.md", "AGENT — Semantic Curator"),
|
|
("file", ".opencode/agents/python-coder.md", "AGENT — Python Coder"),
|
|
("file", ".opencode/agents/svelte-coder.md", "AGENT — Svelte Coder"),
|
|
("file", ".opencode/agents/fullstack-coder.md", "AGENT — Fullstack Coder"),
|
|
("file", ".opencode/agents/qa-tester.md", "AGENT — QA Tester"),
|
|
("file", ".opencode/agents/reflection-agent.md", "AGENT — Reflection Agent"),
|
|
("file", ".opencode/agents/swarm-master.md", "AGENT — Swarm Master"),
|
|
("file", ".opencode/agents/closure-gate.md", "AGENT — Closure Gate"),
|
|
("file", ".opencode/agents/speckit.md", "AGENT — Speckit Workflow"),
|
|
# Layer 4: Speckit Commands (workflow)
|
|
("file", ".opencode/command/speckit.specify.md", "COMMAND — speckit.specify"),
|
|
("file", ".opencode/command/speckit.clarify.md", "COMMAND — speckit.clarify"),
|
|
("file", ".opencode/command/speckit.plan.md", "COMMAND — speckit.plan"),
|
|
("file", ".opencode/command/speckit.tasks.md", "COMMAND — speckit.tasks"),
|
|
("file", ".opencode/command/speckit.implement.md", "COMMAND — speckit.implement"),
|
|
("file", ".opencode/command/speckit.analyze.md", "COMMAND — speckit.analyze"),
|
|
("file", ".opencode/command/speckit.test.md", "COMMAND — speckit.test"),
|
|
("file", ".opencode/command/speckit.checklist.md", "COMMAND — speckit.checklist"),
|
|
("file", ".opencode/command/speckit.constitution.md", "COMMAND — speckit.constitution"),
|
|
("file", ".opencode/command/speckit.semantics.md", "COMMAND — speckit.semantics"),
|
|
("file", ".opencode/command/speckit.taskstoissues.md", "COMMAND — speckit.taskstoissues"),
|
|
("file", ".opencode/command/read_semantics.md", "COMMAND — read_semantics"),
|
|
# Layer 5: Templates (what speckit generates)
|
|
("file", ".specify/templates/spec-template.md", "TEMPLATE — spec"),
|
|
("file", ".specify/templates/ux-reference-template.md", "TEMPLATE — ux-reference"),
|
|
("file", ".specify/templates/plan-template.md", "TEMPLATE — plan"),
|
|
("file", ".specify/templates/tasks-template.md", "TEMPLATE — tasks"),
|
|
("file", ".specify/templates/checklist-template.md", "TEMPLATE — checklist"),
|
|
("file", ".specify/templates/test-docs-template.md", "TEMPLATE — test-docs"),
|
|
("file", ".specify/templates/agent-file-template.md", "TEMPLATE — agent-file"),
|
|
]
|
|
|
|
|
|
def merge_prompts(root: Path = None) -> str:
|
|
"""Merge all prompts, skills, and workflow artifacts into one markdown file."""
|
|
if root is None:
|
|
root = Path.cwd()
|
|
|
|
now = datetime.now().strftime("%Y%m%d-%H%M%S")
|
|
output_filename = f"prompts-merged-{now}.md"
|
|
|
|
content_blocks = [
|
|
REVIEW_PROMPT,
|
|
"",
|
|
"=" * 80,
|
|
"",
|
|
"Artifact order: Constitution → Skills → Agents → Commands → Templates",
|
|
f"Generated: {datetime.now().isoformat()}",
|
|
f"Root: {root}",
|
|
"",
|
|
"=" * 80,
|
|
"",
|
|
]
|
|
|
|
files_merged = 0
|
|
files_skipped = 0
|
|
skipped_details = []
|
|
|
|
for entry_type, path_str, section_title in CANONICAL_ORDER:
|
|
file_path = root / path_str
|
|
|
|
if not file_path.exists():
|
|
files_skipped += 1
|
|
skipped_details.append(f" [MISSING] {path_str}")
|
|
continue
|
|
|
|
try:
|
|
content = file_path.read_text(encoding="utf-8")
|
|
except Exception as e:
|
|
files_skipped += 1
|
|
skipped_details.append(f" [ERROR] {path_str}: {e}")
|
|
continue
|
|
|
|
files_merged += 1
|
|
|
|
# Section header
|
|
content_blocks.append("")
|
|
content_blocks.append("=" * 80)
|
|
content_blocks.append(f"## {section_title}")
|
|
content_blocks.append(f"Source: {path_str}")
|
|
content_blocks.append("=" * 80)
|
|
content_blocks.append("")
|
|
content_blocks.append(content)
|
|
content_blocks.append("")
|
|
|
|
# Summary footer
|
|
content_blocks.append("")
|
|
content_blocks.append("=" * 80)
|
|
content_blocks.append("## MERGE SUMMARY")
|
|
content_blocks.append(f"Files merged: {files_merged}")
|
|
content_blocks.append(f"Files skipped: {files_skipped}")
|
|
if skipped_details:
|
|
content_blocks.append("Skipped:")
|
|
content_blocks.extend(skipped_details)
|
|
content_blocks.append("=" * 80)
|
|
|
|
merged = "\n".join(content_blocks)
|
|
|
|
output_path = root / output_filename
|
|
output_path.write_text(merged, encoding="utf-8")
|
|
|
|
return output_filename, files_merged, files_skipped
|
|
|
|
|
|
def main():
|
|
root = Path.cwd()
|
|
|
|
# Allow explicit root path
|
|
if len(sys.argv) > 1:
|
|
root = Path(sys.argv[1])
|
|
if not root.is_dir():
|
|
print(f"Error: '{sys.argv[1]}' is not a valid directory.")
|
|
sys.exit(1)
|
|
|
|
print(f"Merging prompts from: {root}")
|
|
print()
|
|
|
|
output_filename, merged, skipped = merge_prompts(root)
|
|
|
|
print(f"✓ Merged {merged} files → {output_filename}")
|
|
if skipped:
|
|
print(f"⚠ Skipped {skipped} files (see summary in output)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
# #endregion MergePrompts
|