the-grid-cc 1.3.0 → 1.5.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/.grid/plans/blog-PLAN-SUMMARY.md +518 -0
- package/.grid/plans/blog-block-03.md +253 -0
- package/.grid/plans/blog-block-04.md +287 -0
- package/.grid/plans/blog-block-05.md +235 -0
- package/.grid/plans/blog-block-06.md +325 -0
- package/DEMO_SCRIPT.md +162 -0
- package/HN_POST.md +104 -0
- package/README.md +157 -112
- package/agents/grid-e2e-exerciser.md +311 -0
- package/agents/grid-persona-simulator.md +346 -0
- package/agents/grid-refinement-synth.md +284 -0
- package/agents/grid-visual-inspector.md +229 -0
- package/commands/grid/VERSION +1 -1
- package/commands/grid/help.md +22 -3
- package/commands/grid/mc.md +208 -43
- package/commands/grid/refine.md +283 -0
- package/package.json +1 -1
- package/test-cli/converter.py +206 -0
- package/test-cli/test_data.json +39 -0
- package/test-cli/test_data.yaml +35 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
JSON/YAML Converter CLI
|
|
4
|
+
|
|
5
|
+
Converts between JSON and YAML formats with support for nested structures.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
converter.py <input_file> --to yaml|json [-o output_file] [--indent N]
|
|
9
|
+
converter.py <input_file> -t yaml|json [-o output_file] [--indent N]
|
|
10
|
+
|
|
11
|
+
Examples:
|
|
12
|
+
converter.py config.json --to yaml
|
|
13
|
+
converter.py data.yaml --to json -o output.json
|
|
14
|
+
converter.py nested.json -t yaml --indent 4
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import json
|
|
19
|
+
import sys
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import yaml
|
|
24
|
+
except ImportError:
|
|
25
|
+
print("Error: PyYAML is required. Install with: pip install pyyaml", file=sys.stderr)
|
|
26
|
+
sys.exit(1)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def detect_format(file_path: Path) -> str:
|
|
30
|
+
"""Detect file format from extension."""
|
|
31
|
+
suffix = file_path.suffix.lower()
|
|
32
|
+
if suffix in ('.json',):
|
|
33
|
+
return 'json'
|
|
34
|
+
elif suffix in ('.yaml', '.yml'):
|
|
35
|
+
return 'yaml'
|
|
36
|
+
else:
|
|
37
|
+
return 'unknown'
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def load_json(file_path: Path) -> dict:
|
|
41
|
+
"""Load and parse JSON file."""
|
|
42
|
+
try:
|
|
43
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
44
|
+
return json.load(f)
|
|
45
|
+
except json.JSONDecodeError as e:
|
|
46
|
+
raise ValueError(f"Invalid JSON: {e.msg} at line {e.lineno}, column {e.colno}")
|
|
47
|
+
except FileNotFoundError:
|
|
48
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
49
|
+
except PermissionError:
|
|
50
|
+
raise PermissionError(f"Permission denied: {file_path}")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def load_yaml(file_path: Path) -> dict:
|
|
54
|
+
"""Load and parse YAML file."""
|
|
55
|
+
try:
|
|
56
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
57
|
+
return yaml.safe_load(f)
|
|
58
|
+
except yaml.YAMLError as e:
|
|
59
|
+
if hasattr(e, 'problem_mark'):
|
|
60
|
+
mark = e.problem_mark
|
|
61
|
+
raise ValueError(f"Invalid YAML at line {mark.line + 1}, column {mark.column + 1}: {e.problem}")
|
|
62
|
+
raise ValueError(f"Invalid YAML: {e}")
|
|
63
|
+
except FileNotFoundError:
|
|
64
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
65
|
+
except PermissionError:
|
|
66
|
+
raise PermissionError(f"Permission denied: {file_path}")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def to_json(data: dict, indent: int = 2) -> str:
|
|
70
|
+
"""Convert data to pretty-printed JSON string."""
|
|
71
|
+
return json.dumps(data, indent=indent, ensure_ascii=False, sort_keys=False)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def to_yaml(data: dict, indent: int = 2) -> str:
|
|
75
|
+
"""Convert data to pretty-printed YAML string."""
|
|
76
|
+
return yaml.dump(
|
|
77
|
+
data,
|
|
78
|
+
default_flow_style=False,
|
|
79
|
+
allow_unicode=True,
|
|
80
|
+
indent=indent,
|
|
81
|
+
sort_keys=False,
|
|
82
|
+
width=120
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def convert(input_path: Path, output_format: str, indent: int = 2) -> str:
|
|
87
|
+
"""
|
|
88
|
+
Convert file between JSON and YAML formats.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
input_path: Path to input file
|
|
92
|
+
output_format: Target format ('json' or 'yaml')
|
|
93
|
+
indent: Indentation level for pretty printing
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
Converted content as string
|
|
97
|
+
"""
|
|
98
|
+
input_format = detect_format(input_path)
|
|
99
|
+
|
|
100
|
+
# Load input file
|
|
101
|
+
if input_format == 'json':
|
|
102
|
+
data = load_json(input_path)
|
|
103
|
+
elif input_format == 'yaml':
|
|
104
|
+
data = load_yaml(input_path)
|
|
105
|
+
else:
|
|
106
|
+
# Try JSON first, then YAML
|
|
107
|
+
try:
|
|
108
|
+
data = load_json(input_path)
|
|
109
|
+
input_format = 'json'
|
|
110
|
+
except ValueError:
|
|
111
|
+
try:
|
|
112
|
+
data = load_yaml(input_path)
|
|
113
|
+
input_format = 'yaml'
|
|
114
|
+
except ValueError as e:
|
|
115
|
+
raise ValueError(f"Could not parse file as JSON or YAML: {e}")
|
|
116
|
+
|
|
117
|
+
# Handle None/empty content
|
|
118
|
+
if data is None:
|
|
119
|
+
data = {}
|
|
120
|
+
|
|
121
|
+
# Convert to output format
|
|
122
|
+
if output_format == 'json':
|
|
123
|
+
return to_json(data, indent)
|
|
124
|
+
elif output_format == 'yaml':
|
|
125
|
+
return to_yaml(data, indent)
|
|
126
|
+
else:
|
|
127
|
+
raise ValueError(f"Unknown output format: {output_format}")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def main():
|
|
131
|
+
parser = argparse.ArgumentParser(
|
|
132
|
+
description='Convert between JSON and YAML formats',
|
|
133
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
134
|
+
epilog="""
|
|
135
|
+
Examples:
|
|
136
|
+
%(prog)s config.json --to yaml Convert JSON to YAML (stdout)
|
|
137
|
+
%(prog)s data.yaml --to json -o out.json Convert YAML to JSON file
|
|
138
|
+
%(prog)s nested.json -t yaml --indent 4 Convert with 4-space indent
|
|
139
|
+
"""
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
parser.add_argument(
|
|
143
|
+
'input',
|
|
144
|
+
type=Path,
|
|
145
|
+
help='Input file (JSON or YAML)'
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
parser.add_argument(
|
|
149
|
+
'-t', '--to',
|
|
150
|
+
choices=['json', 'yaml'],
|
|
151
|
+
required=True,
|
|
152
|
+
dest='format',
|
|
153
|
+
help='Output format (json or yaml)'
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
parser.add_argument(
|
|
157
|
+
'-o', '--output',
|
|
158
|
+
type=Path,
|
|
159
|
+
help='Output file (defaults to stdout)'
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
parser.add_argument(
|
|
163
|
+
'--indent',
|
|
164
|
+
type=int,
|
|
165
|
+
default=2,
|
|
166
|
+
help='Indentation level (default: 2)'
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
args = parser.parse_args()
|
|
170
|
+
|
|
171
|
+
# Validate input file exists
|
|
172
|
+
if not args.input.exists():
|
|
173
|
+
print(f"Error: Input file not found: {args.input}", file=sys.stderr)
|
|
174
|
+
sys.exit(1)
|
|
175
|
+
|
|
176
|
+
if not args.input.is_file():
|
|
177
|
+
print(f"Error: Not a file: {args.input}", file=sys.stderr)
|
|
178
|
+
sys.exit(1)
|
|
179
|
+
|
|
180
|
+
# Validate indent
|
|
181
|
+
if args.indent < 0:
|
|
182
|
+
print("Error: Indent must be non-negative", file=sys.stderr)
|
|
183
|
+
sys.exit(1)
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
# Perform conversion
|
|
187
|
+
result = convert(args.input, args.format, args.indent)
|
|
188
|
+
|
|
189
|
+
# Output result
|
|
190
|
+
if args.output:
|
|
191
|
+
with open(args.output, 'w', encoding='utf-8') as f:
|
|
192
|
+
f.write(result)
|
|
193
|
+
print(f"Converted: {args.input} -> {args.output}", file=sys.stderr)
|
|
194
|
+
else:
|
|
195
|
+
print(result)
|
|
196
|
+
|
|
197
|
+
except (ValueError, FileNotFoundError, PermissionError) as e:
|
|
198
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
199
|
+
sys.exit(1)
|
|
200
|
+
except Exception as e:
|
|
201
|
+
print(f"Unexpected error: {e}", file=sys.stderr)
|
|
202
|
+
sys.exit(1)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
if __name__ == '__main__':
|
|
206
|
+
main()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Grid Test Project",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"config": {
|
|
5
|
+
"database": {
|
|
6
|
+
"host": "localhost",
|
|
7
|
+
"port": 5432,
|
|
8
|
+
"credentials": {
|
|
9
|
+
"username": "admin",
|
|
10
|
+
"password": "secret"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"features": {
|
|
14
|
+
"auth": true,
|
|
15
|
+
"logging": true,
|
|
16
|
+
"cache": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"ttl": 3600
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"servers": [
|
|
23
|
+
{
|
|
24
|
+
"name": "primary",
|
|
25
|
+
"host": "192.168.1.1",
|
|
26
|
+
"ports": [80, 443, 8080]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "backup",
|
|
30
|
+
"host": "192.168.1.2",
|
|
31
|
+
"ports": [80, 443]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"metadata": {
|
|
35
|
+
"created": "2024-01-23",
|
|
36
|
+
"tags": ["production", "critical", "monitored"],
|
|
37
|
+
"notes": null
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
application:
|
|
2
|
+
name: YAML Test App
|
|
3
|
+
environment: production
|
|
4
|
+
|
|
5
|
+
services:
|
|
6
|
+
api:
|
|
7
|
+
enabled: true
|
|
8
|
+
endpoints:
|
|
9
|
+
- path: /users
|
|
10
|
+
methods:
|
|
11
|
+
- GET
|
|
12
|
+
- POST
|
|
13
|
+
- path: /orders
|
|
14
|
+
methods:
|
|
15
|
+
- GET
|
|
16
|
+
- POST
|
|
17
|
+
- DELETE
|
|
18
|
+
|
|
19
|
+
worker:
|
|
20
|
+
enabled: true
|
|
21
|
+
concurrency: 4
|
|
22
|
+
queues:
|
|
23
|
+
- name: high_priority
|
|
24
|
+
weight: 10
|
|
25
|
+
- name: default
|
|
26
|
+
weight: 5
|
|
27
|
+
|
|
28
|
+
settings:
|
|
29
|
+
debug: false
|
|
30
|
+
timeout: 30
|
|
31
|
+
retries: 3
|
|
32
|
+
nested:
|
|
33
|
+
deeply:
|
|
34
|
+
structured:
|
|
35
|
+
value: "found it"
|