abvx-set 0.2.3__py3-none-any.whl
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.
- abvx_set-0.2.3.dist-info/METADATA +125 -0
- abvx_set-0.2.3.dist-info/RECORD +11 -0
- abvx_set-0.2.3.dist-info/WHEEL +5 -0
- abvx_set-0.2.3.dist-info/entry_points.txt +3 -0
- abvx_set-0.2.3.dist-info/licenses/LICENSE +21 -0
- abvx_set-0.2.3.dist-info/top_level.txt +1 -0
- scripts/__init__.py +2 -0
- scripts/plan_config_apply.py +848 -0
- scripts/resolve_inputs.py +90 -0
- scripts/validate_registry.py +155 -0
- scripts/write_summary.py +161 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _read_preset(name: str) -> dict[str, str]:
|
|
8
|
+
if not name:
|
|
9
|
+
return {}
|
|
10
|
+
preset_path = Path(__file__).resolve().parents[1] / 'presets' / f'{name}.env'
|
|
11
|
+
if not preset_path.exists():
|
|
12
|
+
available = ', '.join(sorted(p.stem for p in preset_path.parent.glob('*.env')))
|
|
13
|
+
raise SystemExit(f"Unknown workflow_preset '{name}'. Available presets: {available}")
|
|
14
|
+
values: dict[str, str] = {}
|
|
15
|
+
for line in preset_path.read_text().splitlines():
|
|
16
|
+
line = line.strip()
|
|
17
|
+
if not line or line.startswith('#'):
|
|
18
|
+
continue
|
|
19
|
+
key, _, value = line.partition('=')
|
|
20
|
+
values[key.strip()] = value.strip()
|
|
21
|
+
return values
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _resolve_flag(explicit: str, preset: dict[str, str], key: str, fallback: str) -> str:
|
|
25
|
+
if explicit in {'true', 'false'}:
|
|
26
|
+
return explicit
|
|
27
|
+
if key in preset:
|
|
28
|
+
return preset[key]
|
|
29
|
+
return fallback
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> int:
|
|
33
|
+
preset_name = os.environ.get('INPUT_WORKFLOW_PRESET', '').strip()
|
|
34
|
+
preset = _read_preset(preset_name)
|
|
35
|
+
|
|
36
|
+
resolved = {
|
|
37
|
+
'SET_RESOLVED_AGENTSGEN': _resolve_flag(os.environ.get('INPUT_AGENTSGEN', ''), preset, 'AGENTSGEN', 'true'),
|
|
38
|
+
'SET_RESOLVED_INIT': _resolve_flag(os.environ.get('INPUT_INIT', ''), preset, 'INIT', 'true'),
|
|
39
|
+
'SET_RESOLVED_PACK': _resolve_flag(os.environ.get('INPUT_PACK', ''), preset, 'PACK', 'false'),
|
|
40
|
+
'SET_RESOLVED_SITE_PACK': _resolve_flag(os.environ.get('INPUT_SITE_PACK', ''), preset, 'SITE_PACK', 'false'),
|
|
41
|
+
'SET_RESOLVED_CHECK': _resolve_flag(os.environ.get('INPUT_CHECK', ''), preset, 'CHECK', 'false'),
|
|
42
|
+
'SET_RESOLVED_REPOMAP': _resolve_flag(os.environ.get('INPUT_REPOMAP', ''), preset, 'REPOMAP', 'false'),
|
|
43
|
+
'SET_RESOLVED_SNIPPETS': _resolve_flag(os.environ.get('INPUT_SNIPPETS', ''), preset, 'SNIPPETS', 'false'),
|
|
44
|
+
'SET_RESOLVED_ANALYZE': _resolve_flag(os.environ.get('INPUT_ANALYZE', ''), preset, 'ANALYZE', 'false'),
|
|
45
|
+
'SET_RESOLVED_META': _resolve_flag(os.environ.get('INPUT_META', ''), preset, 'META', 'false'),
|
|
46
|
+
'SET_RESOLVED_PROOF_LOOP': _resolve_flag(os.environ.get('INPUT_PROOF_LOOP', ''), preset, 'PROOF_LOOP', 'false'),
|
|
47
|
+
'SET_RESOLVED_ID_ENABLED': _resolve_flag(os.environ.get('INPUT_ID_ENABLED', ''), preset, 'ID_ENABLED', 'false'),
|
|
48
|
+
'SET_RESOLVED_ID_PRE_TASK': _resolve_flag(os.environ.get('INPUT_ID_PRE_TASK', ''), preset, 'ID_PRE_TASK', 'false'),
|
|
49
|
+
'SET_RESOLVED_ID_WEEKLY_REVIEW': _resolve_flag(os.environ.get('INPUT_ID_WEEKLY_REVIEW', ''), preset, 'ID_WEEKLY_REVIEW', 'false'),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
site_url = os.environ.get('INPUT_SITE_URL', '').strip()
|
|
53
|
+
analyze_url = os.environ.get('INPUT_ANALYZE_URL', '').strip()
|
|
54
|
+
meta_url = os.environ.get('INPUT_META_URL', '').strip()
|
|
55
|
+
default_site_url = site_url or preset.get('SITE_URL', '')
|
|
56
|
+
resolved['SET_RESOLVED_SITE_URL'] = default_site_url
|
|
57
|
+
resolved['SET_RESOLVED_ANALYZE_URL'] = analyze_url or default_site_url
|
|
58
|
+
resolved['SET_RESOLVED_META_URL'] = meta_url or default_site_url
|
|
59
|
+
resolved['SET_RESOLVED_PROOF_TASK_ID'] = os.environ.get('INPUT_PROOF_TASK_ID', '').strip() or preset.get('PROOF_TASK_ID', '')
|
|
60
|
+
resolved['SET_RESOLVED_ID_OWNER_ID'] = os.environ.get('INPUT_ID_OWNER_ID', '').strip() or preset.get('ID_OWNER_ID', '')
|
|
61
|
+
resolved['SET_RESOLVED_ID_TARGET'] = os.environ.get('INPUT_ID_TARGET', '').strip() or preset.get('ID_TARGET', 'set') or 'set'
|
|
62
|
+
|
|
63
|
+
output_path = os.environ['GITHUB_ENV']
|
|
64
|
+
with open(output_path, 'a', encoding='utf-8') as fh:
|
|
65
|
+
for key, value in resolved.items():
|
|
66
|
+
fh.write(f'{key}={value}\n')
|
|
67
|
+
|
|
68
|
+
summary = (
|
|
69
|
+
'SET preset resolution: '
|
|
70
|
+
f"workflow_preset={preset_name or 'none'}, "
|
|
71
|
+
f"agentsgen={resolved['SET_RESOLVED_AGENTSGEN']}, "
|
|
72
|
+
f"init={resolved['SET_RESOLVED_INIT']}, "
|
|
73
|
+
f"pack={resolved['SET_RESOLVED_PACK']}, "
|
|
74
|
+
f"site_pack={resolved['SET_RESOLVED_SITE_PACK']}, "
|
|
75
|
+
f"check={resolved['SET_RESOLVED_CHECK']}, "
|
|
76
|
+
f"repomap={resolved['SET_RESOLVED_REPOMAP']}, "
|
|
77
|
+
f"snippets={resolved['SET_RESOLVED_SNIPPETS']}, "
|
|
78
|
+
f"analyze={resolved['SET_RESOLVED_ANALYZE']}, "
|
|
79
|
+
f"meta={resolved['SET_RESOLVED_META']}, "
|
|
80
|
+
f"proof_loop={resolved['SET_RESOLVED_PROOF_LOOP']}, "
|
|
81
|
+
f"id_enabled={resolved['SET_RESOLVED_ID_ENABLED']}, "
|
|
82
|
+
f"id_pre_task={resolved['SET_RESOLVED_ID_PRE_TASK']}, "
|
|
83
|
+
f"id_weekly_review={resolved['SET_RESOLVED_ID_WEEKLY_REVIEW']}"
|
|
84
|
+
)
|
|
85
|
+
print(summary)
|
|
86
|
+
return 0
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if __name__ == '__main__':
|
|
90
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
ALLOWED_PRESETS = {'minimal', 'repo-docs', 'site-ai'}
|
|
7
|
+
ALLOWED_TOP_LEVEL = {'version', 'repo', 'site', 'tools', 'presets'}
|
|
8
|
+
ALLOWED_SITE_KEYS = {'url'}
|
|
9
|
+
ALLOWED_TOOL_BLOCKS = {'agentsgen', 'git_tweet', 'id'}
|
|
10
|
+
ALLOWED_AGENTSGEN_KEYS = {
|
|
11
|
+
'init',
|
|
12
|
+
'pack',
|
|
13
|
+
'check',
|
|
14
|
+
'repomap',
|
|
15
|
+
'repomap_policy',
|
|
16
|
+
'snippets',
|
|
17
|
+
'analyze_url',
|
|
18
|
+
'meta_url',
|
|
19
|
+
'proof_loop',
|
|
20
|
+
}
|
|
21
|
+
ALLOWED_GIT_TWEET_KEYS = {'enabled'}
|
|
22
|
+
ALLOWED_ID_KEYS = {'enabled', 'owner_id', 'target', 'pre_task', 'weekly_review'}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _fail(message: str) -> SystemExit:
|
|
26
|
+
return SystemExit(message)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _require(condition: bool, message: str) -> None:
|
|
30
|
+
if not condition:
|
|
31
|
+
raise _fail(message)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _validate_bool_or_none(value: object, field: str) -> None:
|
|
35
|
+
_require(value is None or isinstance(value, bool), f'{field} must be boolean or null')
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _validate_url_or_none(value: object, field: str) -> None:
|
|
39
|
+
_require(value is None or isinstance(value, str), f'{field} must be string or null')
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _validate_positive_int(value: object, field: str) -> None:
|
|
43
|
+
_require(isinstance(value, int) and value > 0, f'{field} must be a positive integer')
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def validate_config(path: Path) -> dict[str, object]:
|
|
47
|
+
data = json.loads(path.read_text())
|
|
48
|
+
_require(isinstance(data, dict), f'{path.name}: config must be an object')
|
|
49
|
+
unknown_top = set(data) - ALLOWED_TOP_LEVEL
|
|
50
|
+
_require(not unknown_top, f"{path.name}: unknown top-level keys: {', '.join(sorted(unknown_top))}")
|
|
51
|
+
_require(data.get('version') == 1, f'{path.name}: version must be 1')
|
|
52
|
+
repo = data.get('repo')
|
|
53
|
+
_require(isinstance(repo, str) and '/' in repo, f'{path.name}: repo must be owner/name')
|
|
54
|
+
|
|
55
|
+
site = data.get('site')
|
|
56
|
+
if site is not None:
|
|
57
|
+
_require(isinstance(site, dict), f'{path.name}: site must be an object')
|
|
58
|
+
unknown_site = set(site) - ALLOWED_SITE_KEYS
|
|
59
|
+
_require(not unknown_site, f"{path.name}: unknown site keys: {', '.join(sorted(unknown_site))}")
|
|
60
|
+
if 'url' in site:
|
|
61
|
+
_require(isinstance(site['url'], str) and site['url'].startswith('http'), f'{path.name}: site.url must be http(s) string')
|
|
62
|
+
|
|
63
|
+
tools = data.get('tools')
|
|
64
|
+
_require(isinstance(tools, dict), f'{path.name}: tools must be an object')
|
|
65
|
+
unknown_tools = set(tools) - ALLOWED_TOOL_BLOCKS
|
|
66
|
+
_require(not unknown_tools, f"{path.name}: unknown tool blocks: {', '.join(sorted(unknown_tools))}")
|
|
67
|
+
|
|
68
|
+
agentsgen = tools.get('agentsgen')
|
|
69
|
+
if agentsgen is not None:
|
|
70
|
+
_require(isinstance(agentsgen, dict), f'{path.name}: tools.agentsgen must be an object')
|
|
71
|
+
unknown_agentsgen = set(agentsgen) - ALLOWED_AGENTSGEN_KEYS
|
|
72
|
+
_require(not unknown_agentsgen, f"{path.name}: unknown agentsgen keys: {', '.join(sorted(unknown_agentsgen))}")
|
|
73
|
+
for key in ('init', 'pack', 'check', 'repomap', 'snippets'):
|
|
74
|
+
if key in agentsgen:
|
|
75
|
+
_validate_bool_or_none(agentsgen[key], f'{path.name}: agentsgen.{key}')
|
|
76
|
+
for key in ('analyze_url', 'meta_url'):
|
|
77
|
+
if key in agentsgen:
|
|
78
|
+
_validate_url_or_none(agentsgen[key], f'{path.name}: agentsgen.{key}')
|
|
79
|
+
repomap_policy = agentsgen.get('repomap_policy')
|
|
80
|
+
if repomap_policy is not None:
|
|
81
|
+
_require(isinstance(repomap_policy, dict), f'{path.name}: agentsgen.repomap_policy must be an object')
|
|
82
|
+
unknown_policy = set(repomap_policy) - {'compact_budget', 'top_ranked_files', 'focus', 'changed'}
|
|
83
|
+
_require(not unknown_policy, f"{path.name}: unknown repomap_policy keys: {', '.join(sorted(unknown_policy))}")
|
|
84
|
+
if 'compact_budget' in repomap_policy:
|
|
85
|
+
_validate_positive_int(repomap_policy['compact_budget'], f'{path.name}: agentsgen.repomap_policy.compact_budget')
|
|
86
|
+
if 'top_ranked_files' in repomap_policy:
|
|
87
|
+
_validate_positive_int(repomap_policy['top_ranked_files'], f'{path.name}: agentsgen.repomap_policy.top_ranked_files')
|
|
88
|
+
if 'focus' in repomap_policy:
|
|
89
|
+
_require(repomap_policy['focus'] is None or isinstance(repomap_policy['focus'], str), f'{path.name}: agentsgen.repomap_policy.focus must be string or null')
|
|
90
|
+
if 'changed' in repomap_policy:
|
|
91
|
+
_require(isinstance(repomap_policy['changed'], bool), f'{path.name}: agentsgen.repomap_policy.changed must be boolean')
|
|
92
|
+
proof_loop = agentsgen.get('proof_loop')
|
|
93
|
+
if proof_loop is not None:
|
|
94
|
+
_require(isinstance(proof_loop, dict), f'{path.name}: agentsgen.proof_loop must be an object')
|
|
95
|
+
unknown_proof = set(proof_loop) - {'enabled', 'task_id', 'expected_artifacts'}
|
|
96
|
+
_require(not unknown_proof, f"{path.name}: unknown proof_loop keys: {', '.join(sorted(unknown_proof))}")
|
|
97
|
+
if 'enabled' in proof_loop:
|
|
98
|
+
_require(isinstance(proof_loop['enabled'], bool), f'{path.name}: agentsgen.proof_loop.enabled must be boolean')
|
|
99
|
+
if 'task_id' in proof_loop:
|
|
100
|
+
_require(proof_loop['task_id'] is None or isinstance(proof_loop['task_id'], str), f'{path.name}: agentsgen.proof_loop.task_id must be string or null')
|
|
101
|
+
if 'expected_artifacts' in proof_loop:
|
|
102
|
+
_require(isinstance(proof_loop['expected_artifacts'], list), f'{path.name}: agentsgen.proof_loop.expected_artifacts must be a list')
|
|
103
|
+
for item in proof_loop['expected_artifacts']:
|
|
104
|
+
_require(isinstance(item, str) and item.strip(), f'{path.name}: agentsgen.proof_loop.expected_artifacts items must be non-empty strings')
|
|
105
|
+
|
|
106
|
+
git_tweet = tools.get('git_tweet')
|
|
107
|
+
if git_tweet is not None:
|
|
108
|
+
_require(isinstance(git_tweet, dict), f'{path.name}: tools.git_tweet must be an object')
|
|
109
|
+
unknown_git_tweet = set(git_tweet) - ALLOWED_GIT_TWEET_KEYS
|
|
110
|
+
_require(not unknown_git_tweet, f"{path.name}: unknown git_tweet keys: {', '.join(sorted(unknown_git_tweet))}")
|
|
111
|
+
if 'enabled' in git_tweet:
|
|
112
|
+
_validate_bool_or_none(git_tweet['enabled'], f'{path.name}: git_tweet.enabled')
|
|
113
|
+
|
|
114
|
+
id_tool = tools.get('id')
|
|
115
|
+
if id_tool is not None:
|
|
116
|
+
_require(isinstance(id_tool, dict), f'{path.name}: tools.id must be an object')
|
|
117
|
+
unknown_id = set(id_tool) - ALLOWED_ID_KEYS
|
|
118
|
+
_require(not unknown_id, f"{path.name}: unknown id keys: {', '.join(sorted(unknown_id))}")
|
|
119
|
+
if 'enabled' in id_tool:
|
|
120
|
+
_validate_bool_or_none(id_tool['enabled'], f'{path.name}: id.enabled')
|
|
121
|
+
for key in ('pre_task', 'weekly_review'):
|
|
122
|
+
if key in id_tool:
|
|
123
|
+
_validate_bool_or_none(id_tool[key], f'{path.name}: id.{key}')
|
|
124
|
+
for key in ('owner_id', 'target'):
|
|
125
|
+
if key in id_tool:
|
|
126
|
+
_require(id_tool[key] is None or isinstance(id_tool[key], str), f'{path.name}: id.{key} must be string or null')
|
|
127
|
+
|
|
128
|
+
presets = data.get('presets', [])
|
|
129
|
+
_require(isinstance(presets, list), f'{path.name}: presets must be a list')
|
|
130
|
+
for preset in presets:
|
|
131
|
+
_require(isinstance(preset, str), f'{path.name}: preset names must be strings')
|
|
132
|
+
_require(preset in ALLOWED_PRESETS, f'{path.name}: unsupported preset {preset!r}')
|
|
133
|
+
|
|
134
|
+
return data
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def main() -> int:
|
|
138
|
+
root = Path(__file__).resolve().parents[1]
|
|
139
|
+
registry_dir = root / 'registry' / 'repos'
|
|
140
|
+
configs = sorted(registry_dir.glob('*.json'))
|
|
141
|
+
if not configs:
|
|
142
|
+
print('No registry configs found.')
|
|
143
|
+
return 0
|
|
144
|
+
|
|
145
|
+
print('SET registry validation')
|
|
146
|
+
for config_path in configs:
|
|
147
|
+
data = validate_config(config_path)
|
|
148
|
+
repo = data['repo']
|
|
149
|
+
presets = ', '.join(data.get('presets', [])) or 'none'
|
|
150
|
+
print(f'- ok: {config_path.name} -> {repo} (presets: {presets})')
|
|
151
|
+
return 0
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
if __name__ == '__main__':
|
|
155
|
+
raise SystemExit(main())
|
scripts/write_summary.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _enabled(name: str) -> bool:
|
|
9
|
+
return os.environ.get(name, '').strip() == 'true'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _line(label: str, value: str) -> str:
|
|
13
|
+
return f'- **{label}:** {value}\n'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _repomap_mode(focus: str, changed: str) -> str:
|
|
17
|
+
focus_value = focus.strip()
|
|
18
|
+
changed_enabled = changed.strip() == 'true'
|
|
19
|
+
if focus_value and changed_enabled:
|
|
20
|
+
return 'focus+changed'
|
|
21
|
+
if focus_value:
|
|
22
|
+
return 'focus'
|
|
23
|
+
if changed_enabled:
|
|
24
|
+
return 'changed'
|
|
25
|
+
return 'full'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _repomap_label(mode: str) -> str:
|
|
29
|
+
return {
|
|
30
|
+
'full': 'Full Repo Slice',
|
|
31
|
+
'focus': 'Focused Code Slice',
|
|
32
|
+
'changed': 'Changed Files Slice',
|
|
33
|
+
'focus+changed': 'Hybrid Slice',
|
|
34
|
+
}.get(mode, 'Full Repo Slice')
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _load_json(path: Path) -> dict[str, object] | None:
|
|
38
|
+
if not path.exists():
|
|
39
|
+
return None
|
|
40
|
+
try:
|
|
41
|
+
payload = json.loads(path.read_text(encoding='utf-8'))
|
|
42
|
+
except Exception:
|
|
43
|
+
return None
|
|
44
|
+
return payload if isinstance(payload, dict) else None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def main() -> int:
|
|
48
|
+
summary_path = os.environ.get('GITHUB_STEP_SUMMARY', '').strip()
|
|
49
|
+
if not summary_path:
|
|
50
|
+
print('SET summary skipped: GITHUB_STEP_SUMMARY is not available.')
|
|
51
|
+
return 0
|
|
52
|
+
|
|
53
|
+
workflow_preset = os.environ.get('INPUT_WORKFLOW_PRESET', '').strip() or 'none'
|
|
54
|
+
path_value = os.environ.get('INPUT_PATH', '.').strip() or '.'
|
|
55
|
+
autodetect = os.environ.get('INPUT_AUTODETECT', 'true').strip() or 'true'
|
|
56
|
+
init_preset = os.environ.get('INPUT_PRESET', '').strip() or 'none'
|
|
57
|
+
|
|
58
|
+
operations: list[str] = []
|
|
59
|
+
if _enabled('SET_RESOLVED_INIT'):
|
|
60
|
+
operations.append('init')
|
|
61
|
+
if _enabled('SET_RESOLVED_PACK') and _enabled('SET_RESOLVED_SITE_PACK'):
|
|
62
|
+
operations.append('pack --site')
|
|
63
|
+
elif _enabled('SET_RESOLVED_PACK'):
|
|
64
|
+
operations.append('pack')
|
|
65
|
+
if _enabled('SET_RESOLVED_CHECK'):
|
|
66
|
+
operations.append('check --all --ci')
|
|
67
|
+
if _enabled('SET_RESOLVED_REPOMAP'):
|
|
68
|
+
operations.append('understand')
|
|
69
|
+
if _enabled('SET_RESOLVED_SNIPPETS'):
|
|
70
|
+
operations.append('snippets')
|
|
71
|
+
if _enabled('SET_RESOLVED_ANALYZE'):
|
|
72
|
+
operations.append('analyze')
|
|
73
|
+
if _enabled('SET_RESOLVED_META'):
|
|
74
|
+
operations.append('meta')
|
|
75
|
+
if _enabled('SET_RESOLVED_PROOF_LOOP'):
|
|
76
|
+
operations.append('proof-loop')
|
|
77
|
+
if _enabled('SET_RESOLVED_ID_ENABLED') and _enabled('SET_RESOLVED_ID_PRE_TASK'):
|
|
78
|
+
operations.append('id pre_task')
|
|
79
|
+
if _enabled('SET_RESOLVED_ID_ENABLED') and _enabled('SET_RESOLVED_ID_WEEKLY_REVIEW'):
|
|
80
|
+
operations.append('id weekly_review')
|
|
81
|
+
|
|
82
|
+
body = []
|
|
83
|
+
body.append('## SET execution summary\n\n')
|
|
84
|
+
body.append(_line('workflow preset', workflow_preset))
|
|
85
|
+
body.append(_line('path', f'`{path_value}`'))
|
|
86
|
+
body.append(_line('autodetect', autodetect))
|
|
87
|
+
body.append(_line('init preset', init_preset))
|
|
88
|
+
body.append(_line('agentsgen ref', os.environ.get('INPUT_AGENTSGEN_REF', 'main').strip() or 'main'))
|
|
89
|
+
body.append(_line('operations', ', '.join(operations) if operations else 'none'))
|
|
90
|
+
|
|
91
|
+
site_url = os.environ.get('SET_RESOLVED_SITE_URL', '').strip()
|
|
92
|
+
analyze_url = os.environ.get('SET_RESOLVED_ANALYZE_URL', '').strip()
|
|
93
|
+
meta_url = os.environ.get('SET_RESOLVED_META_URL', '').strip()
|
|
94
|
+
repomap_budget = os.environ.get('INPUT_REPOMAP_COMPACT_BUDGET', '').strip() or '4000'
|
|
95
|
+
repomap_focus = os.environ.get('INPUT_REPOMAP_FOCUS', '').strip()
|
|
96
|
+
repomap_changed = os.environ.get('INPUT_REPOMAP_CHANGED', '').strip()
|
|
97
|
+
id_owner_id = os.environ.get('SET_RESOLVED_ID_OWNER_ID', '').strip() or os.environ.get('INPUT_ID_OWNER_ID', '').strip()
|
|
98
|
+
id_target = os.environ.get('SET_RESOLVED_ID_TARGET', '').strip() or os.environ.get('INPUT_ID_TARGET', '').strip() or 'set'
|
|
99
|
+
if _enabled('SET_RESOLVED_REPOMAP'):
|
|
100
|
+
repomap_mode = _repomap_mode(repomap_focus, repomap_changed)
|
|
101
|
+
body.append(_line('repomap compact budget', repomap_budget))
|
|
102
|
+
body.append(_line('repomap policy mode', repomap_mode))
|
|
103
|
+
body.append(_line('repomap policy label', _repomap_label(repomap_mode)))
|
|
104
|
+
body.append(_line('repomap slice', repomap_focus if repomap_focus else ('changed' if repomap_changed == 'true' else 'full')))
|
|
105
|
+
if _enabled('SET_RESOLVED_ID_ENABLED'):
|
|
106
|
+
body.append(_line('id integration', 'enabled'))
|
|
107
|
+
body.append(_line('id owner id', id_owner_id or 'missing'))
|
|
108
|
+
body.append(_line('id target', id_target))
|
|
109
|
+
body.append(_line('id pre_task', str(_enabled('SET_RESOLVED_ID_PRE_TASK')).lower()))
|
|
110
|
+
body.append(_line('id weekly_review', str(_enabled('SET_RESOLVED_ID_WEEKLY_REVIEW')).lower()))
|
|
111
|
+
if _enabled('SET_RESOLVED_PROOF_LOOP'):
|
|
112
|
+
body.append(_line('proof loop', 'enabled'))
|
|
113
|
+
proof_task_id = os.environ.get('SET_RESOLVED_PROOF_TASK_ID', '').strip() or 'missing'
|
|
114
|
+
body.append(_line('proof task id', proof_task_id))
|
|
115
|
+
repo_root = Path(path_value)
|
|
116
|
+
proof_dir = repo_root / 'docs' / 'ai' / 'tasks' / proof_task_id
|
|
117
|
+
evidence = _load_json(proof_dir / 'evidence.json') or _load_json(proof_dir / 'evidence.generated.json')
|
|
118
|
+
verdict = _load_json(proof_dir / 'verdict.json') or _load_json(proof_dir / 'verdict.generated.json')
|
|
119
|
+
if isinstance(evidence, dict):
|
|
120
|
+
body.append(_line('proof evidence status', str(evidence.get('evidence_status', 'unknown'))))
|
|
121
|
+
check_summary = evidence.get('check_summary')
|
|
122
|
+
artifact_summary = evidence.get('artifact_summary')
|
|
123
|
+
if isinstance(check_summary, dict):
|
|
124
|
+
body.append(
|
|
125
|
+
_line(
|
|
126
|
+
'proof checks',
|
|
127
|
+
f"passed {check_summary.get('passed', 0)}, failed {check_summary.get('failed', 0)}, pending {check_summary.get('pending', 0)}",
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
if isinstance(artifact_summary, dict):
|
|
131
|
+
body.append(
|
|
132
|
+
_line(
|
|
133
|
+
'proof artifacts',
|
|
134
|
+
f"present {artifact_summary.get('present', 0)} / total {artifact_summary.get('total', 0)}",
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
if isinstance(verdict, dict):
|
|
138
|
+
body.append(_line('proof verdict', str(verdict.get('status', 'unknown'))))
|
|
139
|
+
body.append(_line('proof decision', str(verdict.get('decision', 'unknown'))))
|
|
140
|
+
body.append(_line('proof blockers', str(len(verdict.get('blocking_details', []) or verdict.get('blocking_items', []) or []))))
|
|
141
|
+
body.append(_line('proof ready for apply', str(verdict.get('ready_for_apply', False)).lower()))
|
|
142
|
+
recommendation = str(verdict.get('recommendation', '') or '')
|
|
143
|
+
if recommendation:
|
|
144
|
+
body.append(_line('proof recommendation', recommendation))
|
|
145
|
+
|
|
146
|
+
if site_url:
|
|
147
|
+
body.append(_line('site url', site_url))
|
|
148
|
+
if _enabled('SET_RESOLVED_ANALYZE') and analyze_url:
|
|
149
|
+
body.append(_line('analyze url', analyze_url))
|
|
150
|
+
if _enabled('SET_RESOLVED_META') and meta_url:
|
|
151
|
+
body.append(_line('meta url', meta_url))
|
|
152
|
+
|
|
153
|
+
with Path(summary_path).open('a', encoding='utf-8') as fh:
|
|
154
|
+
fh.writelines(body)
|
|
155
|
+
|
|
156
|
+
print('SET execution summary written.')
|
|
157
|
+
return 0
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
if __name__ == '__main__':
|
|
161
|
+
raise SystemExit(main())
|