cox-protocol-package 1.0.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/COX_FILE_FORMAT_SPECIFICATION_v1.0.md +236 -0
- package/LICENSE +21 -0
- package/README.md +192 -0
- package/bin/cox-protocol.js +57 -0
- package/editor-support/vscode/.vscodeignore +9 -0
- package/editor-support/vscode/CHANGELOG.md +12 -0
- package/editor-support/vscode/LICENSE +21 -0
- package/editor-support/vscode/README.md +32 -0
- package/editor-support/vscode/language-configuration.json +47 -0
- package/editor-support/vscode/package.json +90 -0
- package/editor-support/vscode/snippets/cox-common.json +12 -0
- package/editor-support/vscode/snippets/cox-component.json +41 -0
- package/editor-support/vscode/snippets/cox-crop-metadata.json +23 -0
- package/editor-support/vscode/snippets/cox-manifest.json +39 -0
- package/editor-support/vscode/snippets/cox-page.json +44 -0
- package/editor-support/vscode/snippets/cox-protocol.json +16 -0
- package/editor-support/vscode/syntaxes/cox.tmLanguage.json +30 -0
- package/guides/imported-packages/cox_protocol_package_compiled.md +32 -0
- package/guides/npm-installation.md +296 -0
- package/manifest.cox +106 -0
- package/package.json +53 -0
- package/protocols/coding_agent_starting_point.cox +67 -0
- package/protocols/component_binding_graph.cox +52 -0
- package/protocols/design_tokens.cox +42 -0
- package/protocols/deterministic_naming_convention.cox +159 -0
- package/protocols/evidence_and_uncertainty_protocol.cox +42 -0
- package/protocols/llm_agent_zip_recreation_instructions.cox +87 -0
- package/protocols/recursive_decomposition_protocol.cox +96 -0
- package/protocols/screenshot_partitioning_protocol.cox +64 -0
- package/protocols/sub_agents_orchestration.cox +85 -0
- package/protocols/visual_acceptance_checklist.cox +30 -0
- package/protocols/website_logic_and_functionality.cox +82 -0
- package/pyproject.toml +51 -0
- package/requirements.txt +4 -0
- package/schemas/cox.component.v1.schema.json +167 -0
- package/schemas/cox.crop_metadata.v1.schema.json +83 -0
- package/schemas/cox.manifest.v1.schema.json +172 -0
- package/schemas/cox.page.v1.schema.json +229 -0
- package/schemas/cox.protocol.v1.schema.json +38 -0
- package/skills/design-spec-writer/SKILL.md +182 -0
- package/skills/package-docs-writer/SKILL.md +270 -0
- package/skills/screenshot-semantic-namer/SKILL.md +96 -0
- package/skills/visual-token-extractor/SKILL.md +102 -0
- package/skills/zip-design-orchestrator/SKILL.md +113 -0
- package/skills/zip-packager/SKILL.md +127 -0
- package/templates/ComponentName.cox.template +33 -0
- package/templates/Page.cox.template +36 -0
- package/templates/crop_metadata.cox.template +15 -0
- package/tools/__init__.py +3 -0
- package/tools/cox_cli.py +127 -0
- package/tools/cox_lib.py +557 -0
- package/tools/package_target.py +214 -0
- package/tools/react_target.py +278 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zip-packager
|
|
3
|
+
description: >
|
|
4
|
+
Expert at assembling, verifying, and delivering the final design-spec ZIP package for the
|
|
5
|
+
LLMAgentZipRecreation workflow. Use this skill for Step 09, or any time a user needs to
|
|
6
|
+
compress a structured documentation folder into a verified, downloadable ZIP. Trigger on:
|
|
7
|
+
"zip up the design specs", "create the final package", "compress and verify the output folder",
|
|
8
|
+
"make a downloadable zip from these files", or when the zip-design-orchestrator delegates Step 09.
|
|
9
|
+
Also useful standalone when a user has a folder of files they want packaged and verified before
|
|
10
|
+
download.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# ZIP Packager
|
|
14
|
+
|
|
15
|
+
You are the expert for **Step 09** of the LLMAgentZipRecreation workflow. Your job is to assemble
|
|
16
|
+
all generated files into a verified, clean ZIP archive and deliver it to the user as a download link.
|
|
17
|
+
|
|
18
|
+
## Pre-Zip Quality Gate
|
|
19
|
+
|
|
20
|
+
Before creating the ZIP, run through this checklist. Report any failures to the orchestrator
|
|
21
|
+
rather than zipping a broken package.
|
|
22
|
+
|
|
23
|
+
### File Completeness Check
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# List the project folder contents
|
|
27
|
+
ls -la {project_slug}_design_specs/
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Verify:
|
|
31
|
+
- [ ] Every screenshot file (`*.png`, `*.jpg`, `*.webp`) has a matching `.design.md`
|
|
32
|
+
- [ ] Every screenshot file has a matching `.yaml`
|
|
33
|
+
- [ ] `README.md` is present
|
|
34
|
+
- [ ] `website_logic_and_functionality.md` is present
|
|
35
|
+
- [ ] `coding_agent_starting_point.md` is present
|
|
36
|
+
- [ ] `llm_agent_zip_recreation_instructions.yaml` is present
|
|
37
|
+
- [ ] No files named with timestamps (`image001`, `screenshot_2024...`, `crop_...`)
|
|
38
|
+
- [ ] No temp or partial files (`.tmp`, `.partial`, empty files)
|
|
39
|
+
|
|
40
|
+
### UTF-8 Check
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Verify text files are valid UTF-8
|
|
44
|
+
file {project_slug}_design_specs/*.md {project_slug}_design_specs/*.yaml
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If any file shows encoding issues, flag it for the orchestrator to regenerate.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Zip Assembly
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Create ZIP from the root design-specs folder
|
|
55
|
+
cd /home/claude # or wherever the project folder lives
|
|
56
|
+
zip -r {project_slug}_full_design_and_build_docs.zip {project_slug}_design_specs/
|
|
57
|
+
|
|
58
|
+
# Verify the zip was created
|
|
59
|
+
ls -lh {project_slug}_full_design_and_build_docs.zip
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Zip Verification
|
|
65
|
+
|
|
66
|
+
After creating the ZIP, always verify its contents:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# List zip contents
|
|
70
|
+
unzip -l {project_slug}_full_design_and_build_docs.zip
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Confirm:
|
|
74
|
+
- [ ] All expected files appear in the listing
|
|
75
|
+
- [ ] No paths outside the root folder (no absolute paths, no `..` traversal)
|
|
76
|
+
- [ ] File sizes look reasonable (non-zero for all files)
|
|
77
|
+
- [ ] ZIP opens successfully (no corruption)
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Extending an Existing ZIP
|
|
82
|
+
|
|
83
|
+
If the user already has a ZIP from a previous run:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Unzip to a temp directory
|
|
87
|
+
mkdir -p /tmp/zip_extend_work
|
|
88
|
+
unzip existing_package.zip -d /tmp/zip_extend_work/
|
|
89
|
+
|
|
90
|
+
# Copy new/updated files into the unzipped folder
|
|
91
|
+
cp new_files/* /tmp/zip_extend_work/{existing_root_folder}/
|
|
92
|
+
|
|
93
|
+
# Recompress with a new descriptive name (don't overwrite original)
|
|
94
|
+
cd /tmp/zip_extend_work
|
|
95
|
+
zip -r /home/claude/{project_slug}_full_design_and_build_docs_v2.zip {existing_root_folder}/
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Never overwrite the original ZIP** unless the user explicitly requests it.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Delivery
|
|
103
|
+
|
|
104
|
+
After successful verification, present the ZIP file to the user using `present_files`. Then provide
|
|
105
|
+
a brief completion note:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
✓ ZIP package ready:
|
|
109
|
+
• {N} screenshots renamed and included
|
|
110
|
+
• {N} .design.md + .yaml spec pairs
|
|
111
|
+
• 4 package-level docs (README, logic, build guide, recreation instructions)
|
|
112
|
+
• Total size: {X}MB
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Keep the note short — the user can inspect the file themselves.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Troubleshooting
|
|
120
|
+
|
|
121
|
+
| Problem | Fix |
|
|
122
|
+
|---------|-----|
|
|
123
|
+
| ZIP too large (>50MB) | Check for uncompressed video/image artifacts; exclude with `zip -x` |
|
|
124
|
+
| Missing spec pair | Flag to orchestrator; regenerate before zipping |
|
|
125
|
+
| Encoding error | Re-save file with `iconv -f latin1 -t utf-8` or regenerate |
|
|
126
|
+
| ZIP opens as empty | Check working directory; ensure relative path used in `zip` command |
|
|
127
|
+
| Duplicate filenames | Review slug uniqueness; one screenshot per slug only |
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
CoxVersion: "1.0"
|
|
2
|
+
FileType: "component_spec"
|
|
3
|
+
ComponentName: "{component_slug}"
|
|
4
|
+
Slug: "{component_slug}"
|
|
5
|
+
Schema: "cox.component.v1"
|
|
6
|
+
Role: "{component_role}"
|
|
7
|
+
EvidenceSummary:
|
|
8
|
+
Visible: []
|
|
9
|
+
UserSpecified: []
|
|
10
|
+
Inferred: []
|
|
11
|
+
Intended: []
|
|
12
|
+
Recommended: []
|
|
13
|
+
NamingDecision:
|
|
14
|
+
ChosenName: "{component_slug}"
|
|
15
|
+
Reason: ""
|
|
16
|
+
RejectedAlternatives: []
|
|
17
|
+
AmbiguityRisk: "Low|Medium|High"
|
|
18
|
+
EvidenceLevel: "Visible|UserSpecified|Inferred"
|
|
19
|
+
VisibleStructure:
|
|
20
|
+
Regions: []
|
|
21
|
+
VisualStyle:
|
|
22
|
+
Tokens: []
|
|
23
|
+
Interactions:
|
|
24
|
+
Visible: []
|
|
25
|
+
Inferred: []
|
|
26
|
+
Intended: []
|
|
27
|
+
Recommended: []
|
|
28
|
+
Responsive:
|
|
29
|
+
Desktop: ""
|
|
30
|
+
Tablet: ""
|
|
31
|
+
Mobile: ""
|
|
32
|
+
ImplementationHints: []
|
|
33
|
+
ChildSubcomponents: []
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
CoxVersion: "1.0"
|
|
2
|
+
FileType: "page_spec"
|
|
3
|
+
PageName: "{PageName}"
|
|
4
|
+
Slug: "{page_slug}"
|
|
5
|
+
Schema: "cox.page.v1"
|
|
6
|
+
ProjectName: "{ProjectName}"
|
|
7
|
+
PageType: "{CanonicalPageType}"
|
|
8
|
+
EvidenceSummary:
|
|
9
|
+
Visible: []
|
|
10
|
+
UserSpecified: []
|
|
11
|
+
Inferred: []
|
|
12
|
+
Intended: []
|
|
13
|
+
Recommended: []
|
|
14
|
+
VisibleStructure:
|
|
15
|
+
Regions: []
|
|
16
|
+
NamingDecision:
|
|
17
|
+
ChosenName: "{PageName}"
|
|
18
|
+
Reason: "{Reason}"
|
|
19
|
+
RejectedAlternatives: []
|
|
20
|
+
AmbiguityRisk: "Low|Medium|High"
|
|
21
|
+
EvidenceLevel: "Visible|UserSpecified|Inferred"
|
|
22
|
+
Layout:
|
|
23
|
+
Desktop: ""
|
|
24
|
+
Tablet: ""
|
|
25
|
+
Mobile: ""
|
|
26
|
+
Children:
|
|
27
|
+
Components: []
|
|
28
|
+
Interactions:
|
|
29
|
+
Visible: []
|
|
30
|
+
Inferred: []
|
|
31
|
+
Intended: []
|
|
32
|
+
Recommended: []
|
|
33
|
+
RecursiveDecompositionDecision:
|
|
34
|
+
Complexity: "SimplePage|ModeratePage|ComplexPage"
|
|
35
|
+
Reason: ""
|
|
36
|
+
Action: ""
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
CoxVersion: "1.0"
|
|
2
|
+
FileType: "crop_metadata"
|
|
3
|
+
Slug: "{component_slug}_crop_metadata"
|
|
4
|
+
Schema: "cox.crop_metadata.v1"
|
|
5
|
+
SourceScreenshot: "dashboard_screenshot.png"
|
|
6
|
+
OutputScreenshot: "{component_slug}_screenshot.png"
|
|
7
|
+
BoundaryConfidence: "High"
|
|
8
|
+
EstimatedBoundingBox:
|
|
9
|
+
Unit: "px|percent"
|
|
10
|
+
X: ""
|
|
11
|
+
Y: ""
|
|
12
|
+
Width: ""
|
|
13
|
+
Height: ""
|
|
14
|
+
IncludedPaddingReason: ""
|
|
15
|
+
ExcludedRegions: []
|
package/tools/cox_cli.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# pyright: reportMissingTypeStubs=false
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import typer # type: ignore[import-untyped]
|
|
8
|
+
from rich.console import Console # type: ignore[import-untyped]
|
|
9
|
+
from rich.table import Table # type: ignore[import-untyped]
|
|
10
|
+
|
|
11
|
+
from . import __version__
|
|
12
|
+
from .cox_lib import CoxError, compile_project, validate_project
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
app = typer.Typer(
|
|
16
|
+
add_completion=False,
|
|
17
|
+
no_args_is_help=True,
|
|
18
|
+
help="Validate and compile COX projects.",
|
|
19
|
+
)
|
|
20
|
+
console = Console()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def print_validation_summary(
|
|
24
|
+
project_label: str,
|
|
25
|
+
document_count: int,
|
|
26
|
+
warnings: list[str],
|
|
27
|
+
) -> None:
|
|
28
|
+
table = Table(show_header=False, box=None)
|
|
29
|
+
table.add_row("Project", project_label)
|
|
30
|
+
table.add_row("Validated documents", str(document_count))
|
|
31
|
+
table.add_row("Warnings", str(len(warnings)))
|
|
32
|
+
console.print(table)
|
|
33
|
+
for warning in warnings:
|
|
34
|
+
console.print(f"[yellow]- {warning}[/yellow]")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@app.command("validate")
|
|
38
|
+
def validate_command(
|
|
39
|
+
project_path: Path = typer.Argument(
|
|
40
|
+
Path("."),
|
|
41
|
+
exists=True,
|
|
42
|
+
resolve_path=True,
|
|
43
|
+
),
|
|
44
|
+
) -> None:
|
|
45
|
+
"""Validate all COX documents referenced by manifest.cox."""
|
|
46
|
+
try:
|
|
47
|
+
summary = validate_project(project_path)
|
|
48
|
+
except CoxError as exc:
|
|
49
|
+
console.print(f"[bold red]Validation failed[/bold red]\n{exc}")
|
|
50
|
+
raise typer.Exit(code=1) from exc
|
|
51
|
+
|
|
52
|
+
console.print(
|
|
53
|
+
"[bold green]COX validation passed[/bold green] "
|
|
54
|
+
f"[dim](v{__version__})[/dim]"
|
|
55
|
+
)
|
|
56
|
+
print_validation_summary(
|
|
57
|
+
summary.project_root.as_posix(),
|
|
58
|
+
len(summary.documents),
|
|
59
|
+
summary.warnings,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@app.command("compile")
|
|
64
|
+
def compile_command(
|
|
65
|
+
project_path: Path = typer.Argument(
|
|
66
|
+
Path("."),
|
|
67
|
+
exists=True,
|
|
68
|
+
resolve_path=True,
|
|
69
|
+
),
|
|
70
|
+
out_dir: Path = typer.Option(
|
|
71
|
+
Path("build"),
|
|
72
|
+
"--out",
|
|
73
|
+
"-o",
|
|
74
|
+
resolve_path=False,
|
|
75
|
+
),
|
|
76
|
+
targets: list[str] = typer.Option(
|
|
77
|
+
[],
|
|
78
|
+
"--target",
|
|
79
|
+
"-t",
|
|
80
|
+
help="Compilation target(s) to emit. Repeat the flag or use commas.",
|
|
81
|
+
),
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Validate the project and emit normalized JSON outputs."""
|
|
84
|
+
try:
|
|
85
|
+
result = compile_project(project_path, out_dir, targets=targets)
|
|
86
|
+
except CoxError as exc:
|
|
87
|
+
console.print(f"[bold red]Compilation failed[/bold red]\n{exc}")
|
|
88
|
+
raise typer.Exit(code=1) from exc
|
|
89
|
+
|
|
90
|
+
console.print(
|
|
91
|
+
"[bold green]COX compilation passed[/bold green] "
|
|
92
|
+
f"[dim](v{__version__})[/dim]"
|
|
93
|
+
)
|
|
94
|
+
table = Table(show_header=False, box=None)
|
|
95
|
+
table.add_row("Build root", result["build_root"].as_posix())
|
|
96
|
+
table.add_row("Targets", ", ".join(result["targets"]))
|
|
97
|
+
json_result = result["target_results"].get("json")
|
|
98
|
+
if json_result is not None:
|
|
99
|
+
table.add_row(
|
|
100
|
+
"Normalized documents",
|
|
101
|
+
str(json_result["document_count"]),
|
|
102
|
+
)
|
|
103
|
+
react_result = result["target_results"].get("react")
|
|
104
|
+
if react_result is not None:
|
|
105
|
+
table.add_row("React pages", str(react_result["page_count"]))
|
|
106
|
+
table.add_row(
|
|
107
|
+
"React components",
|
|
108
|
+
str(react_result["component_count"]),
|
|
109
|
+
)
|
|
110
|
+
table.add_row(
|
|
111
|
+
"React manifest",
|
|
112
|
+
react_result["manifest"].as_posix(),
|
|
113
|
+
)
|
|
114
|
+
package_result = result["target_results"].get("package")
|
|
115
|
+
if package_result is not None:
|
|
116
|
+
table.add_row("Package archive", package_result["archive"].as_posix())
|
|
117
|
+
table.add_row("Package files", str(package_result["file_count"]))
|
|
118
|
+
table.add_row("Package sha256", package_result["sha256"])
|
|
119
|
+
table.add_row("Compiled manifest", result["compiled_manifest"].as_posix())
|
|
120
|
+
table.add_row("Verification report", result["report"].as_posix())
|
|
121
|
+
console.print(table)
|
|
122
|
+
for warning in result["warnings"]:
|
|
123
|
+
console.print(f"[yellow]- {warning}[/yellow]")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
if __name__ == "__main__":
|
|
127
|
+
app()
|