@event4u/agent-config 1.13.0 → 1.14.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/.agent-src/commands/agent-handoff.md +3 -0
- package/.agent-src/commands/agent-status.md +3 -0
- package/.agent-src/commands/agents-audit.md +4 -0
- package/.agent-src/commands/agents-cleanup.md +6 -1
- package/.agent-src/commands/agents-prepare.md +3 -0
- package/.agent-src/commands/analyze-reference-repo.md +4 -0
- package/.agent-src/commands/bug-fix.md +5 -1
- package/.agent-src/commands/bug-investigate.md +4 -0
- package/.agent-src/commands/chat-history-checkpoint.md +126 -0
- package/.agent-src/commands/chat-history-clear.md +5 -0
- package/.agent-src/commands/chat-history-resume.md +5 -0
- package/.agent-src/commands/chat-history.md +5 -0
- package/.agent-src/commands/check-current-md.md +126 -0
- package/.agent-src/commands/commit-in-chunks.md +98 -0
- package/.agent-src/commands/commit.md +4 -0
- package/.agent-src/commands/compress.md +3 -0
- package/.agent-src/commands/context-create.md +4 -0
- package/.agent-src/commands/context-refactor.md +4 -0
- package/.agent-src/commands/copilot-agents-init.md +3 -0
- package/.agent-src/commands/copilot-agents-optimize.md +3 -0
- package/.agent-src/commands/create-pr-description.md +4 -0
- package/.agent-src/commands/create-pr.md +4 -0
- package/.agent-src/commands/do-and-judge.md +4 -1
- package/.agent-src/commands/do-in-steps.md +3 -0
- package/.agent-src/commands/e2e-heal.md +4 -0
- package/.agent-src/commands/e2e-plan.md +4 -0
- package/.agent-src/commands/estimate-ticket.md +4 -1
- package/.agent-src/commands/feature-dev.md +4 -0
- package/.agent-src/commands/feature-explore.md +4 -0
- package/.agent-src/commands/feature-plan.md +4 -0
- package/.agent-src/commands/feature-refactor.md +4 -0
- package/.agent-src/commands/feature-roadmap.md +6 -0
- package/.agent-src/commands/fix-ci.md +4 -0
- package/.agent-src/commands/fix-portability.md +3 -0
- package/.agent-src/commands/fix-pr-bot-comments.md +4 -0
- package/.agent-src/commands/fix-pr-comments.md +4 -0
- package/.agent-src/commands/fix-pr-developer-comments.md +4 -0
- package/.agent-src/commands/fix-references.md +3 -0
- package/.agent-src/commands/fix-seeder.md +4 -0
- package/.agent-src/commands/implement-ticket.md +39 -13
- package/.agent-src/commands/jira-ticket.md +4 -0
- package/.agent-src/commands/judge.md +3 -0
- package/.agent-src/commands/memory-add.md +5 -3
- package/.agent-src/commands/memory-full.md +5 -2
- package/.agent-src/commands/memory-promote.md +7 -6
- package/.agent-src/commands/mode.md +3 -0
- package/.agent-src/commands/module-create.md +4 -0
- package/.agent-src/commands/module-explore.md +4 -0
- package/.agent-src/commands/onboard.md +24 -0
- package/.agent-src/commands/optimize-agents.md +4 -0
- package/.agent-src/commands/optimize-augmentignore.md +3 -0
- package/.agent-src/commands/optimize-rtk-filters.md +3 -0
- package/.agent-src/commands/optimize-skills.md +4 -0
- package/.agent-src/commands/override-create.md +4 -0
- package/.agent-src/commands/override-manage.md +4 -0
- package/.agent-src/commands/package-reset.md +3 -0
- package/.agent-src/commands/package-test.md +3 -0
- package/.agent-src/commands/prepare-for-review.md +4 -0
- package/.agent-src/commands/project-analyze.md +4 -0
- package/.agent-src/commands/project-health.md +4 -0
- package/.agent-src/commands/propose-memory.md +6 -8
- package/.agent-src/commands/quality-fix.md +4 -0
- package/.agent-src/commands/refine-ticket.md +4 -1
- package/.agent-src/commands/review-changes.md +4 -0
- package/.agent-src/commands/review-routing.md +4 -0
- package/.agent-src/commands/roadmap-create.md +7 -0
- package/.agent-src/commands/roadmap-execute.md +12 -1
- package/.agent-src/commands/rule-compliance-audit.md +4 -0
- package/.agent-src/commands/set-cost-profile.md +3 -0
- package/.agent-src/commands/sync-agent-settings.md +3 -0
- package/.agent-src/commands/sync-gitignore.md +3 -0
- package/.agent-src/commands/tests-create.md +4 -0
- package/.agent-src/commands/tests-execute.md +4 -0
- package/.agent-src/commands/threat-model.md +4 -0
- package/.agent-src/commands/update-form-request-messages.md +4 -0
- package/.agent-src/commands/upstream-contribute.md +4 -0
- package/.agent-src/commands/work.md +161 -0
- package/.agent-src/guidelines/agent-infra/engineering-memory-data-format.md +2 -6
- package/.agent-src/guidelines/agent-infra/layered-settings.md +0 -1
- package/.agent-src/guidelines/agent-infra/memory-access.md +0 -7
- package/.agent-src/guidelines/agent-infra/role-contracts.md +2 -4
- package/.agent-src/guidelines/agent-infra/self-improvement-pipeline.md +0 -1
- package/.agent-src/guidelines/php/patterns/strategy.md +180 -2
- package/.agent-src/personas/README.md +0 -1
- package/.agent-src/rules/artifact-drafting-protocol.md +7 -2
- package/.agent-src/rules/artifact-engagement-recording.md +133 -0
- package/.agent-src/rules/ask-when-uncertain.md +18 -13
- package/.agent-src/rules/augment-portability.md +8 -0
- package/.agent-src/rules/autonomous-execution.md +158 -0
- package/.agent-src/rules/chat-history.md +147 -118
- package/.agent-src/rules/cli-output-handling.md +26 -3
- package/.agent-src/rules/command-suggestion.md +133 -0
- package/.agent-src/rules/commit-policy.md +99 -0
- package/.agent-src/rules/direct-answers.md +114 -0
- package/.agent-src/rules/docs-sync.md +36 -0
- package/.agent-src/rules/downstream-changes.md +10 -9
- package/.agent-src/rules/improve-before-implement.md +9 -6
- package/.agent-src/rules/language-and-tone.md +81 -6
- package/.agent-src/rules/non-destructive-by-default.md +117 -0
- package/.agent-src/rules/package-ci-checks.md +4 -0
- package/.agent-src/rules/preservation-guard.md +20 -0
- package/.agent-src/rules/roadmap-progress-sync.md +103 -30
- package/.agent-src/rules/scope-control.md +42 -1
- package/.agent-src/rules/size-enforcement.md +1 -3
- package/.agent-src/rules/skill-quality.md +3 -8
- package/.agent-src/rules/ui-audit-before-build.md +106 -0
- package/.agent-src/rules/user-interaction.md +82 -50
- package/.agent-src/scripts/update_roadmap_progress.py +17 -5
- package/.agent-src/skills/blade-ui/SKILL.md +30 -5
- package/.agent-src/skills/command-routing/SKILL.md +32 -0
- package/.agent-src/skills/command-writing/SKILL.md +41 -2
- package/.agent-src/skills/description-assist/SKILL.md +21 -0
- package/.agent-src/skills/estimate-ticket/SKILL.md +0 -1
- package/.agent-src/skills/existing-ui-audit/SKILL.md +187 -0
- package/.agent-src/skills/fe-design/SKILL.md +72 -60
- package/.agent-src/skills/finishing-a-development-branch/SKILL.md +4 -0
- package/.agent-src/skills/flux/SKILL.md +31 -4
- package/.agent-src/skills/guideline-writing/SKILL.md +24 -2
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +51 -9
- package/.agent-src/skills/livewire/SKILL.md +30 -4
- package/.agent-src/skills/md-language-check/SKILL.md +103 -0
- package/.agent-src/skills/php-coder/SKILL.md +24 -0
- package/.agent-src/skills/react-shadcn-ui/SKILL.md +121 -0
- package/.agent-src/skills/refine-prompt/SKILL.md +220 -0
- package/.agent-src/skills/refine-ticket/SKILL.md +2 -4
- package/.agent-src/skills/roadmap-management/SKILL.md +10 -3
- package/.agent-src/skills/rule-writing/SKILL.md +23 -1
- package/.agent-src/skills/skill-writing/SKILL.md +1 -3
- package/.agent-src/skills/upstream-contribute/SKILL.md +1 -1
- package/.agent-src/skills/using-git-worktrees/SKILL.md +3 -1
- package/.agent-src/templates/AGENTS.md +24 -6
- package/.agent-src/templates/agent-settings.md +149 -0
- package/.agent-src/templates/roadmaps.md +8 -2
- package/.agent-src/templates/scripts/implement_ticket/__init__.py +63 -26
- package/.agent-src/templates/scripts/implement_ticket/__main__.py +8 -2
- package/.agent-src/templates/scripts/telemetry/__init__.py +42 -0
- package/.agent-src/templates/scripts/telemetry/aggregator.py +154 -0
- package/.agent-src/templates/scripts/telemetry/boundary.py +171 -0
- package/.agent-src/templates/scripts/telemetry/engagement.py +238 -0
- package/.agent-src/templates/scripts/telemetry/report_renderer.py +170 -0
- package/.agent-src/templates/scripts/telemetry/settings.py +112 -0
- package/.agent-src/templates/scripts/telemetry_record.py +166 -0
- package/.agent-src/templates/scripts/telemetry_report.py +161 -0
- package/.agent-src/templates/scripts/telemetry_status.py +142 -0
- package/.agent-src/templates/scripts/work_engine/__init__.py +58 -0
- package/.agent-src/templates/scripts/work_engine/__main__.py +9 -0
- package/.agent-src/templates/scripts/work_engine/cli.py +592 -0
- package/.agent-src/templates/scripts/{implement_ticket → work_engine}/delivery_state.py +7 -0
- package/.agent-src/templates/scripts/work_engine/directives/__init__.py +33 -0
- package/.agent-src/templates/scripts/work_engine/directives/backend/__init__.py +98 -0
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/analyze.py +1 -1
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/implement.py +2 -2
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/memory.py +1 -1
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/plan.py +1 -1
- package/.agent-src/templates/scripts/work_engine/directives/backend/refine.py +396 -0
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/report.py +36 -4
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/test.py +2 -2
- package/.agent-src/templates/scripts/{implement_ticket/steps → work_engine/directives/backend}/verify.py +2 -2
- package/.agent-src/templates/scripts/work_engine/directives/mixed/__init__.py +116 -0
- package/.agent-src/templates/scripts/work_engine/directives/mixed/contract.py +254 -0
- package/.agent-src/templates/scripts/work_engine/directives/mixed/stitch.py +229 -0
- package/.agent-src/templates/scripts/work_engine/directives/mixed/ui.py +231 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/__init__.py +113 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +44 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/apply.py +241 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/audit.py +414 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/design.py +335 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/polish.py +510 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui/review.py +468 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/__init__.py +119 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/_skipped.py +37 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/apply.py +165 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/refine.py +66 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/report.py +62 -0
- package/.agent-src/templates/scripts/work_engine/directives/ui_trivial/test.py +115 -0
- package/.agent-src/templates/scripts/work_engine/dispatcher.py +331 -0
- package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +54 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +32 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/_chat_history_base.py +103 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_append.py +44 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_halt_append.py +42 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_heartbeat.py +50 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/chat_history_turn_check.py +49 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/directive_set_guard.py +53 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/halt_surface_audit.py +50 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/state_shape_validation.py +52 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/trace.py +84 -0
- package/.agent-src/templates/scripts/work_engine/hooks/context.py +66 -0
- package/.agent-src/templates/scripts/work_engine/hooks/events.py +44 -0
- package/.agent-src/templates/scripts/work_engine/hooks/exceptions.py +79 -0
- package/.agent-src/templates/scripts/work_engine/hooks/registry.py +60 -0
- package/.agent-src/templates/scripts/work_engine/hooks/runner.py +73 -0
- package/.agent-src/templates/scripts/work_engine/hooks/settings.py +141 -0
- package/.agent-src/templates/scripts/work_engine/intent/__init__.py +47 -0
- package/.agent-src/templates/scripts/work_engine/intent/classify.py +280 -0
- package/.agent-src/templates/scripts/work_engine/migration/__init__.py +8 -0
- package/.agent-src/templates/scripts/work_engine/migration/v0_to_v1.py +199 -0
- package/.agent-src/templates/scripts/work_engine/resolvers/__init__.py +22 -0
- package/.agent-src/templates/scripts/work_engine/resolvers/diff.py +106 -0
- package/.agent-src/templates/scripts/work_engine/resolvers/file.py +113 -0
- package/.agent-src/templates/scripts/work_engine/resolvers/prompt.py +90 -0
- package/.agent-src/templates/scripts/work_engine/scoring/__init__.py +14 -0
- package/.agent-src/templates/scripts/work_engine/scoring/confidence.py +300 -0
- package/.agent-src/templates/scripts/work_engine/stack/__init__.py +31 -0
- package/.agent-src/templates/scripts/work_engine/stack/detect.py +187 -0
- package/.agent-src/templates/scripts/work_engine/state.py +641 -0
- package/.claude-plugin/marketplace.json +105 -2
- package/AGENTS.md +36 -8
- package/CHANGELOG.md +534 -0
- package/README.md +125 -4
- package/config/agent-settings.template.yml +45 -0
- package/config/gitignore-block.txt +4 -0
- package/docs/architecture.md +28 -1
- package/docs/development.md +1 -1
- package/docs/getting-started.md +2 -2
- package/docs/installation.md +86 -0
- package/docs/showcase.md +204 -0
- package/package.json +1 -1
- package/scripts/agent-config +199 -0
- package/scripts/audit_cloud_compatibility.py +288 -0
- package/scripts/build_cloud_bundle.py +458 -0
- package/scripts/build_linear_digest.py +263 -0
- package/scripts/chat_history.py +796 -7
- package/scripts/check_compression.py +139 -0
- package/scripts/check_iron_law_prominence.py +143 -0
- package/scripts/check_md_language.py +159 -0
- package/scripts/check_portability.py +36 -0
- package/scripts/check_reply_consistency.py +140 -0
- package/scripts/command_suggester/__init__.py +51 -0
- package/scripts/command_suggester/cooldown.py +132 -0
- package/scripts/command_suggester/loader.py +70 -0
- package/scripts/command_suggester/match.py +180 -0
- package/scripts/command_suggester/rank.py +120 -0
- package/scripts/command_suggester/render.py +86 -0
- package/scripts/command_suggester/sanitize.py +113 -0
- package/scripts/command_suggester/settings.py +125 -0
- package/scripts/command_suggester/types.py +78 -0
- package/scripts/hooks/augment-chat-history.sh +56 -0
- package/scripts/install-hooks.sh +67 -0
- package/scripts/install.py +150 -33
- package/scripts/lint_marketplace.py +27 -0
- package/scripts/migrate_command_suggestions.py +151 -0
- package/scripts/schemas/command.schema.json +41 -0
- package/scripts/skill_linter.py +67 -0
- package/scripts/sync_agent_settings.py +42 -12
- package/templates/consumer-settings/augment-cli-hooks.json +54 -0
- package/templates/consumer-settings/claude-settings.json +55 -1
- package/.agent-src/templates/scripts/implement_ticket/cli.py +0 -171
- package/.agent-src/templates/scripts/implement_ticket/dispatcher.py +0 -134
- package/.agent-src/templates/scripts/implement_ticket/steps/__init__.py +0 -49
- package/.agent-src/templates/scripts/implement_ticket/steps/refine.py +0 -140
- /package/.agent-src/templates/scripts/{implement_ticket → work_engine}/persona_policy.py +0 -0
package/scripts/agent-config
CHANGED
|
@@ -49,6 +49,26 @@ Commands:
|
|
|
49
49
|
hooks:install Install the pre-commit roadmap-progress hook
|
|
50
50
|
(use --print to dump it, --force to overwrite an existing hook)
|
|
51
51
|
first-run Guided first-run setup — cost profile, settings, tooling
|
|
52
|
+
implement-ticket Drive the work_engine Python engine on a ticket envelope
|
|
53
|
+
(Option-A loop; called by the /implement-ticket command)
|
|
54
|
+
work Drive the work_engine Python engine on a free-form prompt
|
|
55
|
+
(Option-A loop; called by the /work command)
|
|
56
|
+
migrate-state Migrate a legacy .implement-ticket-state.json file
|
|
57
|
+
to the v1 .work-state.json schema (preserves .bak)
|
|
58
|
+
memory:lookup Retrieve memory entries (text or JSON envelope)
|
|
59
|
+
memory:signal Append a provisional intake signal (memory proposal)
|
|
60
|
+
memory:hash Hash a memory entry (YAML or JSON stdin)
|
|
61
|
+
memory:check Validate memory YAML schema + staleness
|
|
62
|
+
memory:check-proposal Run the admission gate on a memory proposal
|
|
63
|
+
proposal:check Validate a learning/skill/rule proposal markdown
|
|
64
|
+
refine-ticket:detect Run the deterministic refine-ticket detection helper
|
|
65
|
+
chat-history:hook Platform hook entry point (read JSON from stdin)
|
|
66
|
+
Usage: chat-history:hook --platform <claude|augment|cursor|cline|windsurf|gemini>
|
|
67
|
+
chat-history:checkpoint Append a phase-boundary entry to .agent-chat-history
|
|
68
|
+
(CHECKPOINT fallback for platforms without native hooks)
|
|
69
|
+
telemetry:record Append one artefact-engagement event (default-off)
|
|
70
|
+
telemetry:status Print artefact-engagement telemetry status (read-only)
|
|
71
|
+
telemetry:report Aggregate the engagement log into a quartile report
|
|
52
72
|
help Show this help
|
|
53
73
|
--version, -V Print package version
|
|
54
74
|
|
|
@@ -59,6 +79,17 @@ Examples:
|
|
|
59
79
|
./agent-config roadmap:progress
|
|
60
80
|
./agent-config hooks:install
|
|
61
81
|
./agent-config first-run
|
|
82
|
+
./agent-config implement-ticket --state-file .work-state.json
|
|
83
|
+
./agent-config work --state-file .work-state.json --prompt-file prompt.txt
|
|
84
|
+
./agent-config migrate-state
|
|
85
|
+
./agent-config memory:lookup --types domain-invariants --key billing
|
|
86
|
+
./agent-config memory:signal --type architecture-decision --path src/Foo.php --body "…"
|
|
87
|
+
./agent-config memory:check --path agents/memory
|
|
88
|
+
./agent-config refine-ticket:detect ticket-body.txt
|
|
89
|
+
./agent-config telemetry:status
|
|
90
|
+
./agent-config telemetry:status --format json
|
|
91
|
+
./agent-config telemetry:report --since 30d --top 20
|
|
92
|
+
./agent-config telemetry:report --since 7d --format json --top 0
|
|
62
93
|
|
|
63
94
|
All commands operate on the CURRENT DIRECTORY (your project root).
|
|
64
95
|
The CLI is strictly consumer-facing. Maintainer tasks live in Taskfile.yml.
|
|
@@ -101,6 +132,32 @@ resolve_script() {
|
|
|
101
132
|
return 1
|
|
102
133
|
}
|
|
103
134
|
|
|
135
|
+
# Resolve a script that ships under templates/scripts/. Tries (in order):
|
|
136
|
+
# 1. CONSUMER_ROOT/scripts/<name> — local copy / customization
|
|
137
|
+
# 2. CONSUMER_ROOT/.augment/templates/scripts/<name> — installer-shipped
|
|
138
|
+
# 3. PACKAGE_ROOT/.agent-src/templates/scripts/<name> — package-internal fallback
|
|
139
|
+
# Consumer customization wins so projects can patch behavior locally
|
|
140
|
+
# without losing the upstream default.
|
|
141
|
+
resolve_template_script() {
|
|
142
|
+
local name="$1"
|
|
143
|
+
local p
|
|
144
|
+
for p in \
|
|
145
|
+
"$CONSUMER_ROOT/scripts/$name" \
|
|
146
|
+
"$CONSUMER_ROOT/.augment/templates/scripts/$name" \
|
|
147
|
+
"$PACKAGE_ROOT/.agent-src/templates/scripts/$name"; do
|
|
148
|
+
if [[ -f "$p" ]]; then
|
|
149
|
+
printf '%s' "$p"
|
|
150
|
+
return 0
|
|
151
|
+
fi
|
|
152
|
+
done
|
|
153
|
+
echo "❌ agent-config: template script not found: $name" >&2
|
|
154
|
+
echo " Searched:" >&2
|
|
155
|
+
echo " - $CONSUMER_ROOT/scripts/$name" >&2
|
|
156
|
+
echo " - $CONSUMER_ROOT/.augment/templates/scripts/$name" >&2
|
|
157
|
+
echo " - $PACKAGE_ROOT/.agent-src/templates/scripts/$name" >&2
|
|
158
|
+
return 1
|
|
159
|
+
}
|
|
160
|
+
|
|
104
161
|
cmd_mcp_render() {
|
|
105
162
|
require_python3
|
|
106
163
|
local script
|
|
@@ -135,6 +192,133 @@ cmd_first_run() {
|
|
|
135
192
|
exec bash "$script" "$@"
|
|
136
193
|
}
|
|
137
194
|
|
|
195
|
+
cmd_implement_ticket() {
|
|
196
|
+
require_python3
|
|
197
|
+
local engine_root="$PACKAGE_ROOT/.agent-src/templates/scripts"
|
|
198
|
+
if [[ ! -d "$engine_root/work_engine" ]]; then
|
|
199
|
+
echo "❌ agent-config: work_engine module not found at $engine_root/work_engine" >&2
|
|
200
|
+
echo " Reinstall the package and retry." >&2
|
|
201
|
+
return 1
|
|
202
|
+
fi
|
|
203
|
+
exec env PYTHONPATH="$engine_root" python3 -m work_engine "$@"
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
cmd_work() {
|
|
207
|
+
# /work shares the engine with /implement-ticket — only the input
|
|
208
|
+
# envelope differs (kind=prompt vs kind=ticket). Keeping a separate
|
|
209
|
+
# subcommand makes the user-facing distinction explicit and lets the
|
|
210
|
+
# two flows diverge later without churn at the wrapper layer.
|
|
211
|
+
require_python3
|
|
212
|
+
local engine_root="$PACKAGE_ROOT/.agent-src/templates/scripts"
|
|
213
|
+
if [[ ! -d "$engine_root/work_engine" ]]; then
|
|
214
|
+
echo "❌ agent-config: work_engine module not found at $engine_root/work_engine" >&2
|
|
215
|
+
echo " Reinstall the package and retry." >&2
|
|
216
|
+
return 1
|
|
217
|
+
fi
|
|
218
|
+
exec env PYTHONPATH="$engine_root" python3 -m work_engine "$@"
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
cmd_migrate_state() {
|
|
222
|
+
require_python3
|
|
223
|
+
local engine_root="$PACKAGE_ROOT/.agent-src/templates/scripts"
|
|
224
|
+
if [[ ! -d "$engine_root/work_engine/migration" ]]; then
|
|
225
|
+
echo "❌ agent-config: work_engine.migration module not found at $engine_root/work_engine/migration" >&2
|
|
226
|
+
echo " Reinstall the package and retry." >&2
|
|
227
|
+
return 1
|
|
228
|
+
fi
|
|
229
|
+
# -W ignore::RuntimeWarning suppresses the known sys.modules notice from
|
|
230
|
+
# `python3 -m pkg.subpkg.module` when the parent package eagerly imports
|
|
231
|
+
# the submodule via its CLI module. The migration is non-invasive and
|
|
232
|
+
# the warning is cosmetic; suppressing here avoids touching the engine.
|
|
233
|
+
exec env PYTHONPATH="$engine_root" python3 -W ignore::RuntimeWarning -m work_engine.migration.v0_to_v1 "$@"
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
cmd_memory_lookup() {
|
|
237
|
+
require_python3
|
|
238
|
+
local script
|
|
239
|
+
script="$(resolve_template_script "memory_lookup.py")" || return 1
|
|
240
|
+
exec python3 "$script" "$@"
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
cmd_memory_signal() {
|
|
244
|
+
require_python3
|
|
245
|
+
local script
|
|
246
|
+
script="$(resolve_template_script "memory_signal.py")" || return 1
|
|
247
|
+
exec python3 "$script" "$@"
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
cmd_memory_hash() {
|
|
251
|
+
require_python3
|
|
252
|
+
local script
|
|
253
|
+
script="$(resolve_template_script "memory_hash.py")" || return 1
|
|
254
|
+
exec python3 "$script" "$@"
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
cmd_telemetry_record() {
|
|
258
|
+
require_python3
|
|
259
|
+
local script
|
|
260
|
+
script="$(resolve_template_script "telemetry_record.py")" || return 1
|
|
261
|
+
exec python3 "$script" "$@"
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
cmd_telemetry_status() {
|
|
265
|
+
require_python3
|
|
266
|
+
local script
|
|
267
|
+
script="$(resolve_template_script "telemetry_status.py")" || return 1
|
|
268
|
+
exec python3 "$script" "$@"
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
cmd_telemetry_report() {
|
|
272
|
+
require_python3
|
|
273
|
+
local script
|
|
274
|
+
script="$(resolve_template_script "telemetry_report.py")" || return 1
|
|
275
|
+
exec python3 "$script" "$@"
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
cmd_memory_check() {
|
|
279
|
+
require_python3
|
|
280
|
+
local script
|
|
281
|
+
script="$(resolve_template_script "check_memory.py")" || return 1
|
|
282
|
+
exec python3 "$script" "$@"
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
cmd_memory_check_proposal() {
|
|
286
|
+
require_python3
|
|
287
|
+
local script
|
|
288
|
+
script="$(resolve_template_script "check_memory_proposal.py")" || return 1
|
|
289
|
+
exec python3 "$script" "$@"
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
cmd_proposal_check() {
|
|
293
|
+
require_python3
|
|
294
|
+
local script
|
|
295
|
+
script="$(resolve_script "scripts/check_proposal.py")" || return 1
|
|
296
|
+
exec python3 "$script" "$@"
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
cmd_refine_ticket_detect() {
|
|
300
|
+
require_python3
|
|
301
|
+
local script
|
|
302
|
+
script="$(resolve_script "scripts/refine_ticket_detect.py")" || return 1
|
|
303
|
+
exec python3 "$script" "$@"
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
cmd_chat_history_hook() {
|
|
307
|
+
require_python3
|
|
308
|
+
local script
|
|
309
|
+
script="$(resolve_script "scripts/chat_history.py")" || return 1
|
|
310
|
+
exec python3 "$script" hook-dispatch "$@"
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
cmd_chat_history_checkpoint() {
|
|
314
|
+
require_python3
|
|
315
|
+
local script
|
|
316
|
+
script="$(resolve_script "scripts/chat_history.py")" || return 1
|
|
317
|
+
# Default cadence-bearing event when a user/agent invokes /chat-history-checkpoint:
|
|
318
|
+
# "phase" — explicit phase boundary, lands under per_phase / per_turn cadences.
|
|
319
|
+
exec python3 "$script" hook-append --event phase "$@"
|
|
320
|
+
}
|
|
321
|
+
|
|
138
322
|
cmd_hooks_install() {
|
|
139
323
|
local force=false
|
|
140
324
|
local print_only=false
|
|
@@ -217,6 +401,21 @@ main() {
|
|
|
217
401
|
roadmap:progress-check) cmd_roadmap_progress_check "$@" ;;
|
|
218
402
|
hooks:install) cmd_hooks_install "$@" ;;
|
|
219
403
|
first-run) cmd_first_run "$@" ;;
|
|
404
|
+
implement-ticket) cmd_implement_ticket "$@" ;;
|
|
405
|
+
work) cmd_work "$@" ;;
|
|
406
|
+
migrate-state) cmd_migrate_state "$@" ;;
|
|
407
|
+
memory:lookup) cmd_memory_lookup "$@" ;;
|
|
408
|
+
memory:signal) cmd_memory_signal "$@" ;;
|
|
409
|
+
memory:hash) cmd_memory_hash "$@" ;;
|
|
410
|
+
memory:check) cmd_memory_check "$@" ;;
|
|
411
|
+
memory:check-proposal) cmd_memory_check_proposal "$@" ;;
|
|
412
|
+
proposal:check) cmd_proposal_check "$@" ;;
|
|
413
|
+
refine-ticket:detect) cmd_refine_ticket_detect "$@" ;;
|
|
414
|
+
chat-history:hook) cmd_chat_history_hook "$@" ;;
|
|
415
|
+
chat-history:checkpoint) cmd_chat_history_checkpoint "$@" ;;
|
|
416
|
+
telemetry:record) cmd_telemetry_record "$@" ;;
|
|
417
|
+
telemetry:status) cmd_telemetry_status "$@" ;;
|
|
418
|
+
telemetry:report) cmd_telemetry_report "$@" ;;
|
|
220
419
|
help|--help|-h|"") usage ;;
|
|
221
420
|
--version|-V) print_version ;;
|
|
222
421
|
*)
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""audit_cloud_compatibility.py — tier each artefact for cloud distribution.
|
|
3
|
+
|
|
4
|
+
Classifies every .md under .agent-src.uncompressed/{skills,rules,commands,
|
|
5
|
+
guidelines} into a tier:
|
|
6
|
+
|
|
7
|
+
T1 Universal no script / no FS / pure guidance
|
|
8
|
+
T2 Local-Agent references repo paths or FS work, no script
|
|
9
|
+
T3-S Script-soft mentions a script as one option (manual fallback exists)
|
|
10
|
+
T3-H Script-hard artefact's core procedure REQUIRES a script
|
|
11
|
+
|
|
12
|
+
Cloud-safe markers (HTML comment on its own line, anywhere in body):
|
|
13
|
+
|
|
14
|
+
<!-- cloud_safe: noop --> artefact is inert on cloud → tier = T1
|
|
15
|
+
<!-- cloud_safe: degrade --> prose fallback is provided → tier = T3-S
|
|
16
|
+
|
|
17
|
+
The marker downgrades the audit tier so build_cloud_bundle.py can emit a
|
|
18
|
+
cloud-aware variant. Source still ships its full local content; the
|
|
19
|
+
marker plus a "## Cloud Behavior" section is what the cloud agent reads.
|
|
20
|
+
|
|
21
|
+
Output: JSON summary on stdout + per-artefact list on --details.
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import argparse
|
|
26
|
+
import json
|
|
27
|
+
import re
|
|
28
|
+
import sys
|
|
29
|
+
from collections import Counter
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
ROOT = Path(__file__).resolve().parent.parent
|
|
33
|
+
SOURCE = ROOT / ".agent-src.uncompressed"
|
|
34
|
+
SCAN_DIRS = ["skills", "rules", "commands", "guidelines"]
|
|
35
|
+
|
|
36
|
+
# patterns
|
|
37
|
+
SCRIPT_RE = re.compile(
|
|
38
|
+
r"(?:scripts/[a-z_]+\.(?:py|sh)|python3\s+scripts/|bash\s+scripts/|\./scripts/)"
|
|
39
|
+
)
|
|
40
|
+
TASK_RE = re.compile(r"`task\s+[a-z][a-z0-9-]+`")
|
|
41
|
+
HARD_RE = re.compile(
|
|
42
|
+
r"(?:MUST\s+(?:run|invoke|call)|"
|
|
43
|
+
r"^\s*[*-]?\s*(?:Run|Invoke|Call)\s+`?(?:python3\s+)?scripts/|"
|
|
44
|
+
r"first\s+tool\s+call.*scripts/|"
|
|
45
|
+
r"runs?\s+silently\s+before|"
|
|
46
|
+
r"automatically\s+(?:invokes?|runs?)\s+`?scripts/)",
|
|
47
|
+
re.IGNORECASE | re.MULTILINE,
|
|
48
|
+
)
|
|
49
|
+
FS_RE = re.compile(
|
|
50
|
+
r"(?:\.agent-src(?:\.uncompressed)?/|"
|
|
51
|
+
r"\.augment/|\.claude/|\.cursor/|\.clinerules/|"
|
|
52
|
+
r"agents/|\.agent-settings\.yml|\.agent-chat-history)"
|
|
53
|
+
)
|
|
54
|
+
CLOUD_MARKER_RE = re.compile(
|
|
55
|
+
r"<!--\s*cloud_safe:\s*(noop|degrade)\s*-->",
|
|
56
|
+
re.IGNORECASE,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Cloud-action heuristics — Phase 4 Step 1, narrow second pass.
|
|
60
|
+
#
|
|
61
|
+
# Goal: flag only artefacts whose PROSE imperatives the cloud agent
|
|
62
|
+
# cannot execute. False positives from a broad first pass (inline
|
|
63
|
+
# backtick CLI, ```bash example blocks, "write a test" coding
|
|
64
|
+
# instructions) are explicitly excluded — the bundle builder's
|
|
65
|
+
# SANDBOX_NOTE preamble already neutralises CLI-as-guidance.
|
|
66
|
+
#
|
|
67
|
+
# Two signals that DO matter on cloud:
|
|
68
|
+
#
|
|
69
|
+
# 1. AGENT_EDIT_RE — procedure imperatively tells the AGENT to write
|
|
70
|
+
# or edit a specific local path the user owns (`.agent-settings.yml`,
|
|
71
|
+
# `.gitignore`, `.augmentignore`, `composer.json`, etc.). Plain
|
|
72
|
+
# "create a file" / "write a class" is coding work, fine on cloud.
|
|
73
|
+
# 2. AGENT_RUN_RE — procedure imperatively tells the AGENT to invoke
|
|
74
|
+
# a local command as ITS OWN action ("first tool call is …",
|
|
75
|
+
# "MUST run `task ci`", "automatically invokes scripts/x.py").
|
|
76
|
+
# Backtick CLI in mid-sentence ("with `composer install`") is
|
|
77
|
+
# guidance for the user and does NOT match.
|
|
78
|
+
AGENT_EDIT_RE = re.compile(
|
|
79
|
+
r"(?:"
|
|
80
|
+
r"\b(?:edit|write|update|modify|patch|append\s+to|set)\s+"
|
|
81
|
+
r"(?:the\s+|a\s+|this\s+|that\s+|your\s+)?"
|
|
82
|
+
r"`?\.(?:agent-settings\.yml|gitignore|augmentignore|"
|
|
83
|
+
r"agent-chat-history|env|claude/|cursor/|clinerules|windsurfrules)"
|
|
84
|
+
r"|"
|
|
85
|
+
r"\b(?:str-replace-editor|save-file|remove-files)\b"
|
|
86
|
+
r")",
|
|
87
|
+
re.IGNORECASE,
|
|
88
|
+
)
|
|
89
|
+
AGENT_RUN_RE = re.compile(
|
|
90
|
+
r"(?:"
|
|
91
|
+
r"MUST\s+(?:run|invoke|call|execute)\s+`?(?:task|python3|bash|"
|
|
92
|
+
r"scripts/|\.augment/scripts/|\.augment/scripts)"
|
|
93
|
+
r"|"
|
|
94
|
+
r"first\s+tool\s+call\s+(?:is|must\s+be)\b"
|
|
95
|
+
r"|"
|
|
96
|
+
r"automatically\s+(?:invokes?|runs?)\s+`?(?:task|scripts/|"
|
|
97
|
+
r"\.augment/scripts/)"
|
|
98
|
+
r"|"
|
|
99
|
+
r"runs?\s+silently\s+before"
|
|
100
|
+
r"|"
|
|
101
|
+
r"^\s*[*-]\s*(?:Run|Invoke|Call|Execute)\s+`(?:task|python3|"
|
|
102
|
+
r"bash\s+scripts|scripts/|\.augment/scripts/)"
|
|
103
|
+
r")",
|
|
104
|
+
re.IGNORECASE | re.MULTILINE,
|
|
105
|
+
)
|
|
106
|
+
# READ_RE retained for completeness — but it's mostly informational
|
|
107
|
+
# (read-only ops are universally cloud-safe; we don't rewrite them).
|
|
108
|
+
AGENT_READ_RE = re.compile(
|
|
109
|
+
r"\b(?:MUST\s+read|first\s+(?:reads?|inspects?))\s+"
|
|
110
|
+
r"(?:the\s+|a\s+)?(?:file|frontmatter|`\.)",
|
|
111
|
+
re.IGNORECASE,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def detect_cloud_marker(text: str) -> str | None:
|
|
116
|
+
"""Return 'noop', 'degrade', or None for the cloud-safe marker."""
|
|
117
|
+
m = CLOUD_MARKER_RE.search(text)
|
|
118
|
+
return m.group(1).lower() if m else None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def classify_cloud_action(text: str) -> str:
|
|
122
|
+
"""Tag T2/T3-S artefact with cloud-action category.
|
|
123
|
+
|
|
124
|
+
Returns one of: 'reads-only', 'edits', 'runs-task', 'mixed', 'none'.
|
|
125
|
+
Narrow heuristic — only matches imperatives directed at the agent
|
|
126
|
+
itself. CLI examples shown to the user (backtick or ```bash) do
|
|
127
|
+
not match — the bundle builder's SANDBOX_NOTE handles those.
|
|
128
|
+
"""
|
|
129
|
+
has_edit = bool(AGENT_EDIT_RE.search(text))
|
|
130
|
+
has_run = bool(AGENT_RUN_RE.search(text))
|
|
131
|
+
has_read = bool(AGENT_READ_RE.search(text))
|
|
132
|
+
|
|
133
|
+
active = sum([has_edit, has_run, has_read])
|
|
134
|
+
if active == 0:
|
|
135
|
+
return "none"
|
|
136
|
+
if active >= 2:
|
|
137
|
+
return "mixed"
|
|
138
|
+
if has_edit:
|
|
139
|
+
return "edits"
|
|
140
|
+
if has_run:
|
|
141
|
+
return "runs-task"
|
|
142
|
+
return "reads-only"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def classify(text: str) -> tuple[str, dict]:
|
|
146
|
+
scripts = sorted(set(SCRIPT_RE.findall(text)))
|
|
147
|
+
tasks = sorted(set(m.strip("`") for m in TASK_RE.findall(text)))
|
|
148
|
+
fs_refs = sorted(set(FS_RE.findall(text)))
|
|
149
|
+
has_hard = bool(HARD_RE.search(text))
|
|
150
|
+
cloud_marker = detect_cloud_marker(text)
|
|
151
|
+
|
|
152
|
+
has_script = bool(scripts) or bool(tasks)
|
|
153
|
+
has_fs = bool(fs_refs)
|
|
154
|
+
|
|
155
|
+
if has_script and has_hard:
|
|
156
|
+
raw_tier = "T3-H"
|
|
157
|
+
elif has_script:
|
|
158
|
+
raw_tier = "T3-S"
|
|
159
|
+
elif has_fs:
|
|
160
|
+
raw_tier = "T2"
|
|
161
|
+
else:
|
|
162
|
+
raw_tier = "T1"
|
|
163
|
+
|
|
164
|
+
# Cloud marker downgrades the served tier — local behavior unchanged.
|
|
165
|
+
if cloud_marker == "noop":
|
|
166
|
+
tier = "T1"
|
|
167
|
+
elif cloud_marker == "degrade":
|
|
168
|
+
tier = "T3-S" if raw_tier == "T3-H" else raw_tier
|
|
169
|
+
else:
|
|
170
|
+
tier = raw_tier
|
|
171
|
+
|
|
172
|
+
# Cloud-action category is meaningful for tiers that *might* run on
|
|
173
|
+
# cloud (T1 / T2 / T3-S). For T3-H the answer is always "blocked".
|
|
174
|
+
if tier in ("T1", "T2", "T3-S"):
|
|
175
|
+
cloud_action = classify_cloud_action(text)
|
|
176
|
+
else:
|
|
177
|
+
cloud_action = "blocked"
|
|
178
|
+
|
|
179
|
+
return tier, {
|
|
180
|
+
"scripts": scripts,
|
|
181
|
+
"tasks": tasks,
|
|
182
|
+
"fs_refs_sample": fs_refs[:3],
|
|
183
|
+
"has_hard_dep_marker": has_hard,
|
|
184
|
+
"raw_tier": raw_tier,
|
|
185
|
+
"cloud_marker": cloud_marker,
|
|
186
|
+
"cloud_action": cloud_action,
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def scan() -> list[dict]:
|
|
191
|
+
rows: list[dict] = []
|
|
192
|
+
for sub in SCAN_DIRS:
|
|
193
|
+
base = SOURCE / sub
|
|
194
|
+
if not base.is_dir():
|
|
195
|
+
continue
|
|
196
|
+
for md in sorted(base.rglob("*.md")):
|
|
197
|
+
if md.name.lower() == "readme.md":
|
|
198
|
+
continue
|
|
199
|
+
text = md.read_text(encoding="utf-8")
|
|
200
|
+
tier, evidence = classify(text)
|
|
201
|
+
rows.append({
|
|
202
|
+
"path": str(md.relative_to(ROOT)),
|
|
203
|
+
"kind": sub,
|
|
204
|
+
"tier": tier,
|
|
205
|
+
**evidence,
|
|
206
|
+
})
|
|
207
|
+
return rows
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def summarize(rows: list[dict]) -> dict:
|
|
211
|
+
by_tier = Counter(r["tier"] for r in rows)
|
|
212
|
+
by_kind_tier: dict[str, Counter] = {}
|
|
213
|
+
for r in rows:
|
|
214
|
+
by_kind_tier.setdefault(r["kind"], Counter())[r["tier"]] += 1
|
|
215
|
+
script_freq = Counter()
|
|
216
|
+
task_freq = Counter()
|
|
217
|
+
cloud_action_freq = Counter()
|
|
218
|
+
cloud_action_by_tier: dict[str, Counter] = {}
|
|
219
|
+
for r in rows:
|
|
220
|
+
for s in r["scripts"]:
|
|
221
|
+
script_freq[s] += 1
|
|
222
|
+
for t in r["tasks"]:
|
|
223
|
+
task_freq[t] += 1
|
|
224
|
+
ca = r.get("cloud_action")
|
|
225
|
+
if ca:
|
|
226
|
+
cloud_action_freq[ca] += 1
|
|
227
|
+
cloud_action_by_tier.setdefault(r["tier"], Counter())[ca] += 1
|
|
228
|
+
return {
|
|
229
|
+
"total": len(rows),
|
|
230
|
+
"by_tier": dict(by_tier.most_common()),
|
|
231
|
+
"by_kind_tier": {k: dict(v) for k, v in by_kind_tier.items()},
|
|
232
|
+
"by_cloud_action": dict(cloud_action_freq.most_common()),
|
|
233
|
+
"cloud_action_by_tier": {
|
|
234
|
+
k: dict(v) for k, v in cloud_action_by_tier.items()
|
|
235
|
+
},
|
|
236
|
+
"top_scripts": script_freq.most_common(15),
|
|
237
|
+
"top_tasks": task_freq.most_common(10),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def main(argv: list[str] | None = None) -> int:
|
|
242
|
+
p = argparse.ArgumentParser(description=__doc__.split("\n", 1)[0])
|
|
243
|
+
p.add_argument("--details", action="store_true",
|
|
244
|
+
help="emit per-artefact rows, not just summary")
|
|
245
|
+
p.add_argument("--tier", choices=["T1", "T2", "T3-S", "T3-H"],
|
|
246
|
+
help="filter --details to one tier")
|
|
247
|
+
p.add_argument(
|
|
248
|
+
"--cloud-action",
|
|
249
|
+
choices=["reads-only", "edits", "runs-task", "mixed", "none",
|
|
250
|
+
"blocked"],
|
|
251
|
+
help="filter --details to one cloud-action category",
|
|
252
|
+
)
|
|
253
|
+
p.add_argument("--format", choices=["json", "md"], default="json")
|
|
254
|
+
args = p.parse_args(argv)
|
|
255
|
+
|
|
256
|
+
rows = scan()
|
|
257
|
+
summary = summarize(rows)
|
|
258
|
+
|
|
259
|
+
if args.details:
|
|
260
|
+
filtered = [
|
|
261
|
+
r for r in rows
|
|
262
|
+
if (not args.tier or r["tier"] == args.tier)
|
|
263
|
+
and (not args.cloud_action
|
|
264
|
+
or r.get("cloud_action") == args.cloud_action)
|
|
265
|
+
]
|
|
266
|
+
if args.format == "json":
|
|
267
|
+
print(json.dumps({"summary": summary, "rows": filtered}, indent=2))
|
|
268
|
+
else:
|
|
269
|
+
print(f"# Cloud-compat audit — tier filter: {args.tier or 'all'}"
|
|
270
|
+
f" · cloud-action: {args.cloud_action or 'all'}\n")
|
|
271
|
+
print(f"Total in scope: {len(filtered)}\n")
|
|
272
|
+
for r in filtered:
|
|
273
|
+
marker = " 🔴" if r["has_hard_dep_marker"] else ""
|
|
274
|
+
action = r.get("cloud_action", "—")
|
|
275
|
+
print(f"- `{r['path']}` — **{r['tier']}** · "
|
|
276
|
+
f"action: `{action}`{marker}")
|
|
277
|
+
if r["scripts"]:
|
|
278
|
+
print(f" - scripts: `{'`, `'.join(r['scripts'])}`")
|
|
279
|
+
if r["tasks"]:
|
|
280
|
+
print(f" - tasks: `{'`, `'.join(r['tasks'])}`")
|
|
281
|
+
return 0
|
|
282
|
+
|
|
283
|
+
print(json.dumps(summary, indent=2))
|
|
284
|
+
return 0
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
if __name__ == "__main__":
|
|
288
|
+
sys.exit(main())
|