claude-dev-env 2.8.0 → 2.10.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/CLAUDE.md +8 -2
- package/_shared/pr-loop/CLAUDE.md +1 -1
- package/_shared/pr-loop/audit-contract.md +17 -6
- package/_shared/pr-loop/audit-reply-template.md +4 -4
- package/_shared/pr-loop/code-rules-gate.md +3 -5
- package/_shared/pr-loop/fix-protocol.md +2 -3
- package/_shared/pr-loop/gh-payloads.md +1 -1
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/README.md +1 -1
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_running.py +16 -1
- package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +11 -5
- package/_shared/pr-loop/scripts/preflight.py +9 -4
- package/_shared/pr-loop/scripts/reviews_disabled.py +50 -22
- package/_shared/pr-loop/scripts/tests/conftest.py +20 -0
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +6 -6
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +50 -6
- package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +1 -1
- package/_shared/pr-loop/state-schema.md +5 -14
- package/agents/CLAUDE.md +2 -2
- package/agents/clean-coder.md +62 -562
- package/agents/code-quality-agent.md +10 -2
- package/agents/code-verifier.md +1 -1
- package/agents/test_agent_frontmatter.py +58 -40
- package/audit-rubrics/CLAUDE.md +2 -1
- package/audit-rubrics/audit-categories.json +704 -0
- package/audit-rubrics/prompts/category-i-concurrency.md +1 -1
- package/bin/CLAUDE.md +16 -5
- package/bin/ever-shipped-skills.mjs +2 -0
- package/bin/install-plan.mjs +402 -0
- package/bin/install-transaction.mjs +455 -0
- package/bin/install.mjs +593 -147
- package/bin/install.plan.test.mjs +194 -0
- package/bin/install.profile-root.test.mjs +154 -0
- package/bin/install.profiles.test.mjs +253 -0
- package/bin/install.settings-defaults.test.mjs +200 -0
- package/bin/install.transaction.test.mjs +400 -0
- package/bin/install.uninstall-transaction.test.mjs +418 -0
- package/bin/merge_managed_permissions.mjs +130 -0
- package/bin/resolve-install-root.mjs +181 -0
- package/bin/select-install-targets.mjs +401 -0
- package/commands/CLAUDE.md +0 -2
- package/docs/CODE_RULES.md +4 -2
- package/docs/references/CLAUDE.md +3 -2
- package/docs/references/advisor-tool.md +44 -6
- package/docs/references/prose-style-enforcement.md +25 -0
- package/docs/references/team-advisor-skill.md +14 -8
- package/hooks/blocking/CLAUDE.md +6 -6
- package/hooks/blocking/_path_setup.py +9 -5
- package/hooks/blocking/code_rules_docstrings.py +124 -30
- package/hooks/blocking/code_rules_enforcer.py +161 -16
- package/hooks/blocking/code_rules_shared.py +40 -23
- package/hooks/blocking/config/CLAUDE.md +3 -5
- package/hooks/blocking/config/prose_style_enforcement_constants.py +38 -0
- package/hooks/blocking/config/test_prose_style_enforcement_constants.py +45 -0
- package/hooks/blocking/eli11_reply_enforcer.py +70 -113
- package/hooks/blocking/hedging_language_blocker.py +103 -20
- package/hooks/blocking/hook_prose_detector_consistency.py +6 -0
- package/hooks/blocking/intent_only_ending_blocker.py +6 -0
- package/hooks/blocking/plain_language_blocker.py +139 -20
- package/hooks/blocking/pre_tool_use_dispatcher.py +102 -20
- package/hooks/blocking/state_description_blocker.py +7 -1
- package/hooks/blocking/tdd_enforcer.py +8 -0
- package/hooks/blocking/test__path_setup.py +28 -0
- package/hooks/blocking/test_code_rules_enforcer_agent_home_tooling.py +99 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_args_span_scope.py +232 -10
- package/hooks/blocking/test_code_rules_enforcer_ephemeral.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_join_separator_magic.py +41 -0
- package/hooks/blocking/test_code_rules_enforcer_string_magic.py +98 -0
- package/hooks/blocking/test_eli11_reply_enforcer.py +98 -165
- package/hooks/blocking/test_hedging_language_blocker.py +120 -1
- package/hooks/blocking/test_hook_prose_detector_consistency.py +28 -8
- package/hooks/blocking/test_intent_only_ending_blocker.py +27 -2
- package/hooks/blocking/test_package_inventory_stale_blocker.py +11 -4
- package/hooks/blocking/test_plain_language_blocker.py +129 -19
- package/hooks/blocking/test_plain_language_blocker_allowlist.py +70 -26
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +99 -26
- package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +87 -50
- package/hooks/blocking/test_state_description_blocker.py +45 -2
- package/hooks/blocking/test_stop_dispatcher.py +11 -7
- package/hooks/blocking/test_volatile_path_in_post_blocker.py +12 -12
- package/hooks/blocking/volatile_path_in_post_blocker.py +2 -2
- package/hooks/hooks.json +15 -0
- package/hooks/hooks_constants/CLAUDE.md +14 -3
- package/hooks/hooks_constants/ask_user_question_shape.py +281 -0
- package/hooks/hooks_constants/code_rules_enforcer_constants.py +2 -1
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
- package/hooks/hooks_constants/eli11_reply_enforcer_constants.py +5 -12
- package/hooks/hooks_constants/hedging_uncertainty_constants.py +42 -0
- package/hooks/hooks_constants/issue_tracker_session_starter_constants.py +23 -0
- package/hooks/hooks_constants/orchestrator_auto_starter_constants.py +23 -0
- package/hooks/hooks_constants/piped_pytest_blocker_constants.py +4 -1
- package/hooks/hooks_constants/plain_language_blocker_constants.py +4 -1
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +6 -0
- package/hooks/hooks_constants/project_paths_reader.py +31 -4
- package/hooks/hooks_constants/prose_matcher_precision_constants.py +40 -0
- package/hooks/hooks_constants/pytest_invocation.py +354 -0
- package/hooks/hooks_constants/session_start_injector.py +163 -0
- package/hooks/hooks_constants/session_start_injector_constants.py +46 -0
- package/hooks/hooks_constants/shell_command_pipeline.py +397 -0
- package/hooks/hooks_constants/shell_command_segments.py +5 -0
- package/hooks/hooks_constants/test_ask_user_question_shape.py +167 -0
- package/hooks/hooks_constants/test_project_paths_reader.py +29 -0
- package/hooks/hooks_constants/test_prose_metrics_parity.py +8 -0
- package/hooks/hooks_constants/test_pytest_invocation.py +130 -0
- package/hooks/hooks_constants/test_session_start_injector.py +168 -0
- package/hooks/hooks_constants/test_shell_command_pipeline.py +135 -0
- package/hooks/hooks_constants/volatile_path_in_post_blocker_constants.py +1 -1
- package/hooks/hooks_constants/working_style_prompt_constants.py +30 -0
- package/hooks/observability/CLAUDE.md +2 -0
- package/hooks/observability/prose_matcher_advisory.py +237 -0
- package/hooks/observability/test_prose_matcher_advisory.py +143 -0
- package/hooks/session/CLAUDE.md +9 -1
- package/hooks/session/_path_setup.py +13 -0
- package/hooks/session/issue_tracker_session_starter.py +135 -0
- package/hooks/session/orchestrator_auto_starter.py +100 -0
- package/hooks/session/test__path_setup.py +28 -0
- package/hooks/session/test_issue_tracker_session_starter.py +104 -0
- package/hooks/session/test_orchestrator_auto_starter.py +99 -0
- package/hooks/session/test_working_style_prompt.py +47 -0
- package/hooks/session/untracked_repo_detector.py +1 -24
- package/hooks/session/working_style_prompt.py +36 -0
- package/hooks/validators/_path_setup.py +19 -0
- package/hooks/validators/run_all_validators.py +8 -13
- package/installable-surfaces.manifest.json +21 -0
- package/output-styles/CLAUDE.md +15 -0
- package/package.json +5 -2
- package/rules/CLAUDE.md +1 -0
- package/rules/code-standards.md +33 -7
- package/rules/durable-post-artifacts.md +2 -2
- package/rules/eli11-replies.md +7 -2
- package/rules/hedging-claims.md +4 -2
- package/rules/long-horizon-autonomy.md +3 -1
- package/rules/opus5-communication-contract.md +45 -0
- package/rules/plain-language.md +2 -2
- package/rules/research-mode.md +1 -1
- package/scripts/CLAUDE.md +13 -2
- package/scripts/Sync-RepoMain.ps1 +215 -0
- package/scripts/active_capability_references.py +218 -0
- package/scripts/ci/windows-installer-lifecycle.ps1 +78 -0
- package/scripts/claude_chain_runner.py +394 -6
- package/scripts/claude_chain_usage.py +1 -1
- package/scripts/codex_compat_materializer.py +105 -85
- package/scripts/dev_env_scripts_constants/CLAUDE.md +3 -1
- package/scripts/dev_env_scripts_constants/active_capability_constants.py +46 -0
- package/scripts/dev_env_scripts_constants/claude_chain_constants.py +74 -0
- package/scripts/dev_env_scripts_constants/grok_run_ledger_constants.py +50 -0
- package/scripts/dev_env_scripts_constants/grok_worker_constants.py +104 -0
- package/scripts/dev_env_scripts_constants/verify_installable_package_constants.py +116 -0
- package/scripts/grok_patch_artifacts.py +123 -0
- package/scripts/grok_run_ledger.py +318 -0
- package/scripts/profile-isolation-launchers/config/mcp-bundles.json +25 -0
- package/scripts/profile-isolation-launchers/config/profile-isolation-constants.mjs +60 -0
- package/scripts/profile-isolation-launchers/config/profiles.manifest.json +54 -0
- package/scripts/profile-isolation-launchers/config/shared-allowlist.json +64 -0
- package/scripts/profile-isolation-launchers/launcher-runtime.mjs +180 -0
- package/scripts/profile-isolation-launchers/lib/profile-manifest.mjs +288 -0
- package/scripts/profile-isolation-launchers/mcp-bundles.mjs +275 -0
- package/scripts/profile-isolation-launchers/profile-isolation-contract.test.mjs +221 -0
- package/scripts/profile-isolation-launchers/tests/launcher-runtime.test.mjs +108 -0
- package/scripts/profile-isolation-launchers/tests/mcp-bundles.test.mjs +147 -0
- package/scripts/profile-isolation-launchers/tests/shortcut-contract.test.ps1 +102 -0
- package/scripts/profile-isolation-launchers/tests/version-compatibility.test.mjs +210 -0
- package/scripts/profile-isolation-launchers/version-compatibility.mjs +299 -0
- package/scripts/profile-isolation-launchers/windows/shortcut-inventory.ps1 +127 -0
- package/scripts/profile-isolation-launchers/windows/shortcut-manifest.json +51 -0
- package/scripts/profile-isolation-launchers/windows/shortcut-reconcile.ps1 +77 -0
- package/scripts/spawn_grok_batch.py +556 -9
- package/scripts/test_active_capability_references.py +108 -0
- package/scripts/test_claude_chain_runner.py +414 -82
- package/scripts/test_claude_chain_usage.py +12 -12
- package/scripts/test_grok_patch_artifacts.py +82 -0
- package/scripts/test_grok_run_ledger.py +116 -0
- package/scripts/test_resolve_worker_spawn.py +2 -2
- package/scripts/test_spawn_grok_batch.py +295 -0
- package/scripts/test_verify_installable_package.py +208 -0
- package/scripts/tests/test_codex_compat_materializer.py +33 -0
- package/scripts/verify_installable_package.py +612 -0
- package/settings.json +10 -0
- package/skills/CLAUDE.md +6 -2
- package/skills/_shared/CLAUDE.md +37 -4
- package/skills/_shared/advisor/CLAUDE.md +9 -0
- package/skills/_shared/advisor/advisor-protocol.md +5 -0
- package/skills/_shared/advisor/scripts/README.md +9 -0
- package/skills/_shared/end-of-run-gotcha-recommendations.md +156 -0
- package/skills/_shared/pr-loop/CLAUDE.md +18 -1
- package/skills/_shared/pr-loop/audit-contract.md +5 -0
- package/skills/_shared/pr-loop/audit-reply-template.md +5 -0
- package/skills/_shared/pr-loop/code-rules-gate.md +5 -0
- package/skills/_shared/pr-loop/fix-protocol.md +5 -0
- package/skills/_shared/pr-loop/gh-payloads.md +5 -0
- package/skills/_shared/pr-loop/post-audit-thread-contract.md +5 -0
- package/skills/_shared/pr-loop/precatch-rubric.md +5 -0
- package/skills/_shared/pr-loop/scripts/CLAUDE.md +9 -1
- package/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +29 -0
- package/skills/_shared/pr-loop/scripts/audit_category_schema.py +355 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +1 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +32 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +7 -19
- package/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +94 -0
- package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +21 -0
- package/skills/_shared/pr-loop/state-schema.md +5 -0
- package/skills/_shared/pr-loop/worker-spawn.md +5 -0
- package/skills/autoconverge/reference/convergence.md +2 -1
- package/skills/autoconverge/reference/stop-conditions.md +5 -3
- package/skills/beat-sheet/SKILL.md +54 -0
- package/skills/beat-sheet/reference/visual-beats.md +29 -0
- package/skills/bugteam/CONSTRAINTS.md +4 -4
- package/skills/bugteam/EXAMPLES.md +1 -1
- package/skills/bugteam/reference/README.md +1 -1
- package/skills/e-code-review/SKILL.md +29 -3
- package/skills/e-code-review/reference/effort-evaluation.md +35 -0
- package/skills/e-code-review/reference/medium.md +15 -4
- package/skills/e-code-review/reference/runner-selection.md +40 -0
- package/skills/e-code-review/scripts/config/e_code_review_effort_constants/__init__.py +41 -0
- package/skills/e-code-review/scripts/config/e_code_review_effort_constants/effort_constants.py +40 -0
- package/skills/e-code-review/scripts/e_code_review_scripts_constants/__init__.py +1 -0
- package/skills/e-code-review/scripts/e_code_review_scripts_constants/finding_pipeline_constants.py +49 -0
- package/skills/e-code-review/scripts/e_code_review_scripts_constants/grok_code_review_constants.py +55 -0
- package/skills/e-code-review/scripts/effort_defaults_evidence.json +186 -0
- package/skills/e-code-review/scripts/effort_evaluation.py +362 -0
- package/skills/e-code-review/scripts/finding_pipeline.py +140 -0
- package/skills/e-code-review/scripts/fixtures/demanding.json +26 -0
- package/skills/e-code-review/scripts/fixtures/easy.json +14 -0
- package/skills/e-code-review/scripts/fixtures/medium.json +20 -0
- package/skills/e-code-review/scripts/grok_code_review.py +230 -0
- package/skills/e-code-review/scripts/test_effort_evaluation.py +180 -0
- package/skills/e-code-review/scripts/test_finding_pipeline.py +197 -0
- package/skills/e-code-review/scripts/test_grok_code_review.py +289 -0
- package/skills/grok-spawn/SKILL.md +5 -0
- package/skills/orchestrator/SKILL.md +5 -0
- package/skills/plan-to-pr/scripts/create_packet.py +4 -4
- package/skills/plan-to-pr/scripts/load_skill_constants.py +41 -0
- package/skills/plan-to-pr/scripts/validate_packet.py +4 -4
- package/skills/plan-to-pr/scripts/validate_protocol.py +4 -1
- package/skills/plan-to-pr/scripts/validate_run.py +4 -1
- package/skills/pr-converge/scripts/check_convergence.py +21 -19
- package/skills/pr-converge/scripts/check_convergence_availability.py +50 -7
- package/skills/pr-converge/scripts/conftest.py +35 -0
- package/skills/pr-converge/scripts/test_check_convergence_availability.py +65 -0
- package/skills/pr-converge/scripts/test_check_convergence_codex.py +11 -1
- package/skills/pr-converge/scripts/test_check_convergence_contract.py +9 -2
- package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
- package/skills/rebase/SKILL.md +15 -3
- package/skills/reviewer-gates/SKILL.md +2 -2
- package/skills/show/SKILL.md +51 -0
- package/skills/show/references/accessibility.md +7 -0
- package/skills/show/references/art.md +3 -0
- package/skills/show/references/charts.md +3 -0
- package/skills/show/references/core-design.md +14 -0
- package/skills/show/references/erds.md +3 -0
- package/skills/show/references/flowcharts.md +3 -0
- package/skills/show/references/host-and-html.md +3 -0
- package/skills/show/references/illustrative-diagrams.md +10 -0
- package/skills/show/references/interaction.md +3 -0
- package/skills/show/references/mockups.md +3 -0
- package/skills/show/references/quality-gates.md +7 -0
- package/skills/show/references/structural-diagrams.md +3 -0
- package/skills/show/references/subject-inventory.md +21 -0
- package/skills/show/references/svg-contract.md +22 -0
- package/skills/show/routing.yaml +30 -0
- package/skills/show/samples/pr1262-v2.svg +222 -0
- package/skills/show/scripts/README.md +6 -0
- package/skills/show/scripts/validate-artifact.py +91 -0
- package/skills/show/scripts/validate-package.py +18 -0
- package/skills/show/templates/html-widget.html +4 -0
- package/skills/show/templates/svg-base.svg +19 -0
- package/skills/show/tests/fixtures/css-var.svg +6 -0
- package/skills/show/tests/fixtures/dead-ref.svg +7 -0
- package/skills/show/tests/fixtures/filled-glyph.svg +8 -0
- package/skills/show/tests/fixtures/inherited-fill.svg +18 -0
- package/skills/show/tests/fixtures/invalid.svg +1 -0
- package/skills/show/tests/fixtures/large-canvas.svg +21 -0
- package/skills/show/tests/fixtures/unfilled-connector.svg +15 -0
- package/skills/show/tests/fixtures/valid.html +1 -0
- package/skills/show/tests/test_validate-artifact.py +74 -0
- package/skills/show/tests/test_validators.py +59 -0
- package/skills/show/workflows/create-visual.md +13 -0
- package/skills/show/workflows/review-visual.md +20 -0
- package/skills/split-pr/SKILL.md +85 -0
- package/skills/split-pr/reference/path-layers.md +16 -0
- package/skills/split-pr/reference/proposal-format.md +15 -0
- package/skills/split-pr/reference/split-further-loop.md +10 -0
- package/skills/split-pr/reference/splitting-principles.md +26 -0
- package/skills/split-pr/scripts/analyze_pr.py +279 -0
- package/skills/split-pr/scripts/categorize_files.py +106 -0
- package/skills/split-pr/scripts/config/__init__.py +1 -0
- package/skills/split-pr/scripts/config/dependency_constants.py +14 -0
- package/skills/split-pr/scripts/config/git_operations_constants.py +36 -0
- package/skills/split-pr/scripts/config/packing_constants.py +61 -0
- package/skills/split-pr/scripts/config/plan_constants.py +49 -0
- package/skills/split-pr/scripts/config/split_pr_constants.py +110 -0
- package/skills/split-pr/scripts/execute_split_slices.py +82 -0
- package/skills/split-pr/scripts/pack_files_into_slices.py +212 -0
- package/skills/split-pr/scripts/split_pr_dependency_graph.py +70 -0
- package/skills/split-pr/scripts/split_pr_git_operations.py +184 -0
- package/skills/split-pr/scripts/split_pr_layer_order.py +58 -0
- package/skills/split-pr/scripts/split_pr_paginate.py +119 -0
- package/skills/split-pr/scripts/split_pr_process_runner.py +52 -0
- package/skills/split-pr/scripts/split_pr_script_types.py +126 -0
- package/skills/split-pr/scripts/split_pr_title.py +41 -0
- package/skills/split-pr/scripts/test_analyze_pr.py +228 -0
- package/skills/split-pr/scripts/test_categorize_files.py +55 -0
- package/skills/split-pr/scripts/test_categorize_files_packing.py +59 -0
- package/skills/split-pr/scripts/test_execute_split_slices.py +99 -0
- package/skills/split-pr/scripts/test_split_pr_dependency_graph.py +47 -0
- package/skills/split-pr/scripts/test_split_pr_git_operations.py +125 -0
- package/skills/split-pr/scripts/test_split_pr_layer_order.py +36 -0
- package/skills/split-pr/scripts/test_split_pr_paginate.py +65 -0
- package/skills/split-pr/scripts/test_split_pr_script_types.py +73 -0
- package/skills/split-pr/scripts/test_split_pr_title.py +28 -0
- package/skills/split-pr/scripts/test_verify_dependency_graph.py +46 -0
- package/skills/split-pr/scripts/test_verify_plan.py +56 -0
- package/skills/split-pr/scripts/test_verify_plan_contract.py +50 -0
- package/skills/split-pr/scripts/test_verify_plan_path_normalization.py +45 -0
- package/skills/split-pr/scripts/verify_dependency_graph.py +111 -0
- package/skills/split-pr/scripts/verify_plan.py +139 -0
- package/skills/task-build/reference/tool-routing.md +3 -0
- package/skills/team-advisor/SKILL.md +23 -44
- package/system-prompts/software-engineer.xml +17 -5
- package/commands/initialize.md +0 -90
- package/commands/stubcheck.md +0 -88
- package/skills/test_markdown_link_integrity.py +0 -107
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
|
-
import ast
|
|
7
6
|
import hashlib
|
|
8
7
|
import json
|
|
9
8
|
import os
|
|
@@ -15,6 +14,8 @@ from dataclasses import dataclass, field
|
|
|
15
14
|
from pathlib import Path
|
|
16
15
|
from typing import Callable, Iterable
|
|
17
16
|
|
|
17
|
+
import yaml
|
|
18
|
+
|
|
18
19
|
|
|
19
20
|
ManagedContent = str | bytes
|
|
20
21
|
|
|
@@ -24,7 +25,6 @@ reparse_point_attribute_name = "FILE_ATTRIBUTE_REPARSE_POINT"
|
|
|
24
25
|
manifest_indentation_width = 2
|
|
25
26
|
publish_plan_max_positional_arguments = 3
|
|
26
27
|
publish_plan_failure_injector_position = 2
|
|
27
|
-
frontmatter_required_fields = ("name", "description")
|
|
28
28
|
frontmatter_unsupported_fields = ("tools", "model", "color")
|
|
29
29
|
full_prune_opt_in_flag = "--allow-prune-all"
|
|
30
30
|
unreadable_source_root_message = (
|
|
@@ -259,73 +259,67 @@ def validate_target_path(target_root: Path, relative_path: str) -> Path:
|
|
|
259
259
|
return _validate_containment(root, candidate)
|
|
260
260
|
|
|
261
261
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if
|
|
305
|
-
raise MaterializerError("
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if any(character in entry for character in "[]{}:"):
|
|
320
|
-
raise MaterializerError("malformed frontmatter value")
|
|
321
|
-
return entry
|
|
322
|
-
if not isinstance(parsed, str):
|
|
323
|
-
raise MaterializerError("frontmatter list entries must be strings")
|
|
324
|
-
return parsed
|
|
262
|
+
class _UniqueKeySafeLoader(yaml.SafeLoader):
|
|
263
|
+
"""SafeLoader that rejects duplicate mapping keys (safe_load keeps last)."""
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def _construct_mapping_rejecting_duplicates(
|
|
267
|
+
loader: yaml.SafeLoader,
|
|
268
|
+
node: yaml.nodes.MappingNode,
|
|
269
|
+
is_deep: bool = False,
|
|
270
|
+
) -> dict:
|
|
271
|
+
mapping: dict = {}
|
|
272
|
+
for each_key_node, each_field_node in node.value:
|
|
273
|
+
key = loader.construct_object(each_key_node, deep=is_deep)
|
|
274
|
+
if key in mapping:
|
|
275
|
+
raise yaml.constructor.ConstructorError(
|
|
276
|
+
None,
|
|
277
|
+
None,
|
|
278
|
+
f"duplicate key {key!r}",
|
|
279
|
+
each_key_node.start_mark,
|
|
280
|
+
)
|
|
281
|
+
mapping[key] = loader.construct_object(each_field_node, deep=is_deep)
|
|
282
|
+
return mapping
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
_UniqueKeySafeLoader.add_constructor(
|
|
286
|
+
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
|
287
|
+
_construct_mapping_rejecting_duplicates,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _require_nonempty_string(field_content: object, source_path: Path) -> str:
|
|
292
|
+
if not isinstance(field_content, str):
|
|
293
|
+
raise MaterializerError(f"name and description are required: {source_path}")
|
|
294
|
+
if not field_content.strip():
|
|
295
|
+
raise MaterializerError(f"name and description are required: {source_path}")
|
|
296
|
+
return field_content
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def _require_optional_string(
|
|
300
|
+
field_content: object, field_name: str, source_path: Path
|
|
301
|
+
) -> str | None:
|
|
302
|
+
if field_content is None:
|
|
303
|
+
return None
|
|
304
|
+
if not isinstance(field_content, str):
|
|
305
|
+
raise MaterializerError(f"{field_name} must be a string: {source_path}")
|
|
306
|
+
return field_content
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _require_tools_list(tools_content: object, source_path: Path) -> tuple[str, ...]:
|
|
310
|
+
if tools_content is None:
|
|
311
|
+
return ()
|
|
312
|
+
if isinstance(tools_content, str):
|
|
313
|
+
return (tools_content,)
|
|
314
|
+
if not isinstance(tools_content, list):
|
|
315
|
+
raise MaterializerError(f"tools must be a list: {source_path}")
|
|
316
|
+
if not all(isinstance(each_entry, str) for each_entry in tools_content):
|
|
317
|
+
raise MaterializerError(f"tools must be a list: {source_path}")
|
|
318
|
+
return tuple(tools_content)
|
|
325
319
|
|
|
326
320
|
|
|
327
321
|
def parse_frontmatter(source_path: Path, source_text: str, relative_source: str) -> ClaudeAgent:
|
|
328
|
-
"""Parse one Claude agent's frontmatter.
|
|
322
|
+
"""Parse one Claude agent's frontmatter through validated YAML.
|
|
329
323
|
|
|
330
324
|
Args:
|
|
331
325
|
source_path: Path used in validation errors.
|
|
@@ -342,30 +336,56 @@ def parse_frontmatter(source_path: Path, source_text: str, relative_source: str)
|
|
|
342
336
|
lines = source_text.splitlines()
|
|
343
337
|
if len(lines) < 3 or lines[0].strip() != "---":
|
|
344
338
|
raise MaterializerError(f"malformed frontmatter: {source_path}")
|
|
345
|
-
delimiters = [
|
|
339
|
+
delimiters = [
|
|
340
|
+
each_index for each_index, line in enumerate(lines[1:], 1) if line.strip() == "---"
|
|
341
|
+
]
|
|
346
342
|
if len(delimiters) != 1:
|
|
347
343
|
raise MaterializerError(f"malformed frontmatter delimiters: {source_path}")
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
344
|
+
frontmatter_text = line_separator.join(lines[1 : delimiters[0]]) + line_separator
|
|
345
|
+
try:
|
|
346
|
+
parsed_fields = yaml.load(frontmatter_text, Loader=_UniqueKeySafeLoader)
|
|
347
|
+
except yaml.YAMLError as yaml_error:
|
|
348
|
+
raise MaterializerError(f"malformed frontmatter: {source_path}") from yaml_error
|
|
349
|
+
if not isinstance(parsed_fields, dict):
|
|
350
|
+
raise MaterializerError(f"malformed frontmatter: {source_path}")
|
|
351
|
+
for each_key in parsed_fields:
|
|
352
|
+
if not isinstance(each_key, str) or not re.fullmatch(
|
|
353
|
+
r"[A-Za-z][A-Za-z0-9_-]*", each_key
|
|
354
|
+
):
|
|
355
355
|
raise MaterializerError(f"malformed frontmatter key: {source_path}")
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
unknown = tuple(
|
|
357
|
+
sorted(
|
|
358
|
+
each_key
|
|
359
|
+
for each_key in parsed_fields
|
|
360
|
+
if each_key not in frontmatter_allowed_fields
|
|
361
|
+
)
|
|
362
|
+
)
|
|
358
363
|
if unknown:
|
|
359
364
|
raise MaterializerError(f"unknown frontmatter keys: {source_path}")
|
|
360
|
-
unsupported = tuple(
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
365
|
+
unsupported = tuple(
|
|
366
|
+
sorted(
|
|
367
|
+
each_key
|
|
368
|
+
for each_key in parsed_fields
|
|
369
|
+
if each_key in frontmatter_unsupported_fields
|
|
370
|
+
)
|
|
371
|
+
)
|
|
372
|
+
name = _require_nonempty_string(parsed_fields.get("name"), source_path)
|
|
373
|
+
description = _require_nonempty_string(
|
|
374
|
+
parsed_fields.get("description"), source_path
|
|
375
|
+
)
|
|
376
|
+
tools = _require_tools_list(parsed_fields.get("tools"), source_path)
|
|
377
|
+
model = _require_optional_string(parsed_fields.get("model"), "model", source_path)
|
|
378
|
+
color = _require_optional_string(parsed_fields.get("color"), "color", source_path)
|
|
379
|
+
return ClaudeAgent(
|
|
380
|
+
source_path,
|
|
381
|
+
source_identity,
|
|
382
|
+
name,
|
|
383
|
+
description,
|
|
384
|
+
tools,
|
|
385
|
+
model,
|
|
386
|
+
color,
|
|
387
|
+
unsupported,
|
|
388
|
+
)
|
|
369
389
|
|
|
370
390
|
|
|
371
391
|
def convert_agent(agent: ClaudeAgent) -> str:
|
|
@@ -10,8 +10,10 @@ Named constants for scripts in `scripts/`. Follows the project convention that t
|
|
|
10
10
|
| `gh_artifact_upload_constants.py` | `gh_artifact_upload.py` - the `artifacts` release tag, title, and notes body, the GitHub CLI binary name, the asset-name timestamp format and template, the asset download URL template, the notes-file suffix, and the text encoding |
|
|
11
11
|
| `claude_chain_constants.py` | `claude_chain_runner.py` - the chain config filename and home subdirectory, the usage-limit signature text, the per-binary status labels, routing-mode tokens (`usage_ranked` / `ordered_account`), outcome `terminal_status` values (`served` / `advisor_blocked` / `chain_exhausted` / `timeout`), the default timeout, CLI flag and separator tokens, config JSON keys (including optional `credentials_path`), invalid-shape reason text, config-error and exhausted-chain message templates, and CLI exit codes (including advisor-blocked); `invoke_code_review.py` and `resolve_worker_spawn.py` - the text-codec keyword names and the `collect_forwarded_text_codec` helper that forwards them to the subprocess runner for text-mode capture |
|
|
12
12
|
| `claude_chain_usage_constants.py` | `claude_chain_usage.py` - full weekly percent scale, usage-pause skill path segments, CLI config-path flag, JSON report keys, and probe error message templates |
|
|
13
|
-
| `grok_worker_constants.py` | `grok_worker_preflight.py`, `grok_headless_runner.py`, `spawn_grok_batch.py`, and `resolve_worker_spawn.py` - the `grok` binary name and CLI flags, model and subcommand tokens, leader-socket and scratch-file name parts, auth and usage-limit signature lists, outcome classifications, fallthrough reasons, tool-profile names and prompt headers, worker timeouts (default, plus the floor and the `MAXIMUM_WORKER_TIMEOUT_SECONDS` ceiling that the batch spec parse, the headless runner, and the spawn dispatcher all enforce, each bound carrying one rejection template shared by those sites, plus launch-failure return code and post-kill grace), the process-tree kill attempt limit and kill-failed classification, the preflight ping's single-turn cap, ping-cache keys and TTL, batch-spec and summary JSON keys, the prompt-part and report-stream join separators, and the CLI launch-error stderr prefix |
|
|
13
|
+
| `grok_worker_constants.py` | `grok_worker_preflight.py`, `grok_headless_runner.py`, `spawn_grok_batch.py`, and `resolve_worker_spawn.py` - the `grok` binary name and CLI flags, model and subcommand tokens, leader-socket and scratch-file name parts, auth and usage-limit signature lists, outcome classifications, fallthrough reasons, tool-profile names and prompt headers, worker timeouts (default, plus the floor and the `MAXIMUM_WORKER_TIMEOUT_SECONDS` ceiling that the batch spec parse, the headless runner, and the spawn dispatcher all enforce, each bound carrying one rejection template shared by those sites, plus launch-failure return code and post-kill grace), the process-tree kill attempt limit and kill-failed classification, the preflight ping's single-turn cap, ping-cache keys and TTL, batch-spec and summary JSON keys, worker-advisor placeholder launcher/model/effort tokens, four verdict signals, MAXIMUM_WORKER_ADVISOR_CORRECTIONS, advisor_blocked classification, and advisor_session_id report keys, the prompt-part and report-stream join separators, and the CLI launch-error stderr prefix |
|
|
14
14
|
| `code_review_constants.py` | `invoke_code_review.py` - the `/code-review ultra --fix` prompt, opus model alias, permission-mode flag and value, result mode and JSON keys, session-model CLI flag, git dirty-check tokens, and in-session return markers; finding severity tokens (`blocker` / `high` / `medium` / `low` / `nit`), verification verdict tokens, loop terminal tokens (`clean` / `nits_fixed` / `advisor_blocked`), and pure helpers for retained-finding checks, head recording, terminal resolution, and terminal encoding |
|
|
15
|
+
| `active_capability_constants.py` | `active_capability_references.py` - package skills/agents/commands directory names, skill manifest filename, ban-listed capability names, inert fence languages, slash and backtick extract patterns, fence open/close patterns, banned-reason prefix, UTF-8 encoding, and newline join separator |
|
|
16
|
+
| `verify_installable_package_constants.py` | `verify_installable_package.py` - manifest filename and keys, npm pack / tarball / plugin-root tokens, git and node smoke argv pieces, surface classification labels, exit codes, and CLI status headers |
|
|
15
17
|
| `__init__.py` | Empty package marker |
|
|
16
18
|
|
|
17
19
|
## Convention
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Constants for the active_capability_references script.
|
|
2
|
+
|
|
3
|
+
Script-level scalar constants live in dev_env_scripts_constants alongside
|
|
4
|
+
timing.py and the other per-script constant modules.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
PACKAGE_SKILLS_DIRECTORY: str = "skills"
|
|
10
|
+
PACKAGE_AGENTS_DIRECTORY: str = "agents"
|
|
11
|
+
PACKAGE_COMMANDS_DIRECTORY: str = "commands"
|
|
12
|
+
SKILL_MANIFEST_FILENAME: str = "SKILL.md"
|
|
13
|
+
|
|
14
|
+
# Slash-command and skill names that must never appear as active instructions.
|
|
15
|
+
ALL_BANNED_ACTIVE_CAPABILITY_NAMES: frozenset[str] = frozenset(
|
|
16
|
+
{
|
|
17
|
+
"stub-detector",
|
|
18
|
+
"superpowers",
|
|
19
|
+
"qbug",
|
|
20
|
+
"findbugs",
|
|
21
|
+
"fixbugs",
|
|
22
|
+
"monitor-open-prs",
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Fence languages treated as inert historical/example content.
|
|
27
|
+
ALL_INERT_FENCE_LANGUAGES: frozenset[str] = frozenset(
|
|
28
|
+
{
|
|
29
|
+
"example",
|
|
30
|
+
"history",
|
|
31
|
+
"historical",
|
|
32
|
+
"quote",
|
|
33
|
+
"diff",
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
SLASH_CAPABILITY_PATTERN: str = r"(?<![`\w])/([a-z][a-z0-9-]{2,})"
|
|
38
|
+
BACKTICK_CAPABILITY_PATTERN: str = (
|
|
39
|
+
r"`(?:skills/)?([a-z][a-z0-9-]{2,})(?:/SKILL\.md)?`"
|
|
40
|
+
)
|
|
41
|
+
FENCE_OPEN_PATTERN: str = r"^```([A-Za-z0-9_-]*)\s*$"
|
|
42
|
+
FENCE_CLOSE_PATTERN: str = r"^```\s*$"
|
|
43
|
+
BANNED_REASON_PREFIX: str = "banned_active_capability:"
|
|
44
|
+
|
|
45
|
+
UTF8_ENCODING: str = "utf-8"
|
|
46
|
+
NEWLINE_JOIN_SEPARATOR: str = "\n"
|
|
@@ -227,3 +227,77 @@ ATTEMPT_SUMMARY_ENTRY_TEMPLATE: str = "{command}={status}"
|
|
|
227
227
|
|
|
228
228
|
ATTEMPT_SUMMARY_JOIN_SEPARATOR: str = ", "
|
|
229
229
|
"""Separator joining per-attempt fragments in the exhausted-chain summary."""
|
|
230
|
+
|
|
231
|
+
AFFINITY_STATE_SCHEMA_VERSION: int = 1
|
|
232
|
+
"""Version field written into the session-to-binary affinity state document."""
|
|
233
|
+
|
|
234
|
+
AFFINITY_STATE_FILENAME: str = "claude-chain-affinity.json"
|
|
235
|
+
"""Default affinity state file name under the Claude home directory."""
|
|
236
|
+
|
|
237
|
+
AFFINITY_MAXIMUM_ENTRIES: int = 64
|
|
238
|
+
"""Hard cap on retained session-to-binary affinity rows (oldest drop first)."""
|
|
239
|
+
|
|
240
|
+
AFFINITY_KEY_SCHEMA_VERSION: str = "schema_version"
|
|
241
|
+
"""JSON key for the affinity document schema version."""
|
|
242
|
+
|
|
243
|
+
AFFINITY_KEY_ALL_BINDINGS: str = "all_bindings"
|
|
244
|
+
"""JSON key for the ordered list of session-to-command bindings."""
|
|
245
|
+
|
|
246
|
+
AFFINITY_KEY_SESSION_ID: str = "session_id"
|
|
247
|
+
"""JSON key for a bound Claude session id."""
|
|
248
|
+
|
|
249
|
+
AFFINITY_KEY_COMMAND: str = "command"
|
|
250
|
+
"""JSON key for the chain binary command bound to a session id."""
|
|
251
|
+
|
|
252
|
+
AFFINITY_TEMP_SUFFIX: str = ".tmp"
|
|
253
|
+
"""Suffix for the temporary file used during atomic affinity replacement."""
|
|
254
|
+
|
|
255
|
+
AFFINITY_BINDING_NOT_OBJECT_REASON: str = "a binding entry is not an object"
|
|
256
|
+
"""Reason when an affinity binding entry is not a JSON object."""
|
|
257
|
+
|
|
258
|
+
AFFINITY_BINDING_SESSION_ID_MISSING_REASON: str = (
|
|
259
|
+
"binding missing non-empty session_id"
|
|
260
|
+
)
|
|
261
|
+
"""Reason when an affinity binding lacks a usable session_id."""
|
|
262
|
+
|
|
263
|
+
AFFINITY_BINDING_COMMAND_MISSING_REASON: str = "binding missing non-empty command"
|
|
264
|
+
"""Reason when an affinity binding lacks a usable command."""
|
|
265
|
+
|
|
266
|
+
AFFINITY_UNSUPPORTED_SCHEMA_VERSION_REASON_TEMPLATE: str = (
|
|
267
|
+
"unsupported schema_version {schema_version!r}"
|
|
268
|
+
)
|
|
269
|
+
"""Reason when the affinity document schema version is not supported."""
|
|
270
|
+
|
|
271
|
+
AFFINITY_BINDINGS_MISSING_OR_NOT_LIST_REASON: str = (
|
|
272
|
+
"all_bindings is missing or not a list"
|
|
273
|
+
)
|
|
274
|
+
"""Reason when all_bindings is absent or the wrong type."""
|
|
275
|
+
|
|
276
|
+
AFFINITY_TOP_LEVEL_NOT_OBJECT_REASON: str = "top-level value is not a JSON object"
|
|
277
|
+
"""Reason when the affinity document root is not an object."""
|
|
278
|
+
|
|
279
|
+
AFFINITY_SESSION_ID_AND_COMMAND_REQUIRED_MESSAGE: str = (
|
|
280
|
+
"session_id and command must be non-empty"
|
|
281
|
+
)
|
|
282
|
+
"""ValueError message when record_affinity_binding receives empty ids."""
|
|
283
|
+
|
|
284
|
+
AFFINITY_MAXIMUM_ENTRIES_MINIMUM_MESSAGE: str = "maximum_entries must be at least 1"
|
|
285
|
+
"""ValueError message when maximum_entries is below one."""
|
|
286
|
+
|
|
287
|
+
AFFINITY_CORRUPT_MESSAGE_TEMPLATE: str = (
|
|
288
|
+
"Affinity state at {state_path} is corrupt or unreadable: {error}. "
|
|
289
|
+
"Delete or repair the file before retrying."
|
|
290
|
+
)
|
|
291
|
+
"""Actionable diagnostic when affinity state cannot be loaded."""
|
|
292
|
+
|
|
293
|
+
AFFINITY_WRITE_FAILED_MESSAGE_TEMPLATE: str = (
|
|
294
|
+
"Failed to write affinity state at {state_path}: {error}. "
|
|
295
|
+
"Check directory permissions and free space."
|
|
296
|
+
)
|
|
297
|
+
"""Actionable diagnostic when atomic affinity replacement fails."""
|
|
298
|
+
|
|
299
|
+
AFFINITY_JSON_INDENT_SPACES: int = 2
|
|
300
|
+
"""Indent width for the written affinity state JSON document."""
|
|
301
|
+
|
|
302
|
+
RESUME_SESSION_FLAG: str = "--resume"
|
|
303
|
+
"""Claude CLI flag that continues a prior session by id."""
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Named constants for the host-neutral Grok run ledger and patch artifacts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
LEDGER_SCHEMA_VERSION: str = "1.0.0"
|
|
6
|
+
"""Schema version stamped on every ledger document and task record."""
|
|
7
|
+
|
|
8
|
+
LEDGER_FILENAME: str = "grok-run-ledger.json"
|
|
9
|
+
"""Default ledger filename under a run-state directory."""
|
|
10
|
+
|
|
11
|
+
PATCH_MANIFEST_FILENAME: str = "patch-manifest.json"
|
|
12
|
+
"""Default patch-manifest filename under a run-state directory."""
|
|
13
|
+
|
|
14
|
+
TASK_STATUS_PENDING: str = "pending"
|
|
15
|
+
"""Task is recorded and waiting for dispatch."""
|
|
16
|
+
|
|
17
|
+
TASK_STATUS_IN_PROGRESS: str = "in_progress"
|
|
18
|
+
"""Task has exactly one live owner and is being worked."""
|
|
19
|
+
|
|
20
|
+
TASK_STATUS_COMPLETED: str = "completed"
|
|
21
|
+
"""Task reached a successful terminal state."""
|
|
22
|
+
|
|
23
|
+
TASK_STATUS_ADVISOR_BLOCKED: str = "advisor_blocked"
|
|
24
|
+
"""Task stopped because the advisor bind or verdict failed closed."""
|
|
25
|
+
|
|
26
|
+
TASK_STATUS_PENDING_REVIEW: str = "pending_review"
|
|
27
|
+
"""Task was invalidated by snapshot drift and needs re-review."""
|
|
28
|
+
|
|
29
|
+
ALL_LEGAL_TASK_STATUSES: frozenset[str] = frozenset(
|
|
30
|
+
{
|
|
31
|
+
TASK_STATUS_PENDING,
|
|
32
|
+
TASK_STATUS_IN_PROGRESS,
|
|
33
|
+
TASK_STATUS_COMPLETED,
|
|
34
|
+
TASK_STATUS_ADVISOR_BLOCKED,
|
|
35
|
+
TASK_STATUS_PENDING_REVIEW,
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
"""Every legal task status the ledger accepts."""
|
|
39
|
+
|
|
40
|
+
UTF8_ENCODING: str = "utf-8"
|
|
41
|
+
"""Text encoding for ledger and patch-manifest files."""
|
|
42
|
+
|
|
43
|
+
JSON_INDENT: int = 2
|
|
44
|
+
"""Indent width for pretty-printed ledger and patch-manifest JSON."""
|
|
45
|
+
|
|
46
|
+
TEMPORARY_LEDGER_PREFIX: str = ".ledger-"
|
|
47
|
+
"""Prefix for atomic ledger temp files before replace."""
|
|
48
|
+
|
|
49
|
+
TEMPORARY_LEDGER_SUFFIX: str = ".tmp"
|
|
50
|
+
"""Suffix for atomic ledger temp files before replace."""
|
|
@@ -503,3 +503,107 @@ CLI_ENABLE_CLAUDE_TIER_FLAG: str = "--enable-claude-tier"
|
|
|
503
503
|
|
|
504
504
|
EMPTY_OUTPUT: str = ""
|
|
505
505
|
"""Empty captured output when no tier produced stdout."""
|
|
506
|
+
|
|
507
|
+
BATCH_SPEC_ADVISOR_KEY: str = "advisor"
|
|
508
|
+
"""JSON key for the optional batch-level worker-advisor block."""
|
|
509
|
+
|
|
510
|
+
ADVISOR_SPEC_LAUNCHER_KEY: str = "launcher"
|
|
511
|
+
"""JSON key for the lead-supplied advisor launcher executable name."""
|
|
512
|
+
|
|
513
|
+
ADVISOR_SPEC_MODEL_KEY: str = "model"
|
|
514
|
+
"""JSON key for the advisor model name."""
|
|
515
|
+
|
|
516
|
+
ADVISOR_SPEC_EFFORT_KEY: str = "effort"
|
|
517
|
+
"""JSON key for the advisor effort level."""
|
|
518
|
+
|
|
519
|
+
DEFAULT_ADVISOR_LAUNCHER_PLACEHOLDER: str = "ADVISOR_LAUNCHER_PLACEHOLDER"
|
|
520
|
+
"""Committed placeholder; real launcher arrives only from the lead's batch spec."""
|
|
521
|
+
|
|
522
|
+
DEFAULT_ADVISOR_MODEL: str = "opus"
|
|
523
|
+
"""Default advisor model when the batch advisor block omits model."""
|
|
524
|
+
|
|
525
|
+
DEFAULT_ADVISOR_EFFORT: str = "high"
|
|
526
|
+
"""Default advisor effort when the batch advisor block omits effort."""
|
|
527
|
+
|
|
528
|
+
MAXIMUM_WORKER_ADVISOR_CORRECTIONS: int = 3
|
|
529
|
+
"""Maximum CORRECTION/PLAN re-consults per worker before advisor_blocked."""
|
|
530
|
+
|
|
531
|
+
MAXIMUM_ADVISOR_TIMEOUT_SECONDS: int = 600
|
|
532
|
+
"""Timeout for one advisor launcher subprocess call, in seconds."""
|
|
533
|
+
|
|
534
|
+
ADVISOR_SIGNAL_ENDORSE: str = "ENDORSE"
|
|
535
|
+
"""Opening signal that accepts a worker report."""
|
|
536
|
+
|
|
537
|
+
ADVISOR_SIGNAL_CORRECTION: str = "CORRECTION"
|
|
538
|
+
"""Opening signal that requires a re-consult up to the correction cap."""
|
|
539
|
+
|
|
540
|
+
ADVISOR_SIGNAL_PLAN: str = "PLAN"
|
|
541
|
+
"""Opening signal treated like CORRECTION for re-consult counting."""
|
|
542
|
+
|
|
543
|
+
ADVISOR_SIGNAL_STOP: str = "STOP"
|
|
544
|
+
"""Opening signal that ends the worker as advisor_blocked immediately."""
|
|
545
|
+
|
|
546
|
+
ALL_KNOWN_ADVISOR_SIGNALS: frozenset[str] = frozenset(
|
|
547
|
+
{
|
|
548
|
+
ADVISOR_SIGNAL_ENDORSE,
|
|
549
|
+
ADVISOR_SIGNAL_CORRECTION,
|
|
550
|
+
ADVISOR_SIGNAL_PLAN,
|
|
551
|
+
ADVISOR_SIGNAL_STOP,
|
|
552
|
+
}
|
|
553
|
+
)
|
|
554
|
+
"""The four allowed first tokens of an advisor reply."""
|
|
555
|
+
|
|
556
|
+
CLASSIFICATION_ADVISOR_BLOCKED: str = "advisor_blocked"
|
|
557
|
+
"""Worker classification when advisor bind, resume, or verdict fails closed."""
|
|
558
|
+
|
|
559
|
+
PENDING_BIND_SENTINEL: str = "PENDING_BIND"
|
|
560
|
+
"""Unbound advisor session or signal sentinel; must fail closed before launch."""
|
|
561
|
+
|
|
562
|
+
ADVISOR_PROMPT_HEADER_TEMPLATE: str = (
|
|
563
|
+
"Worker advisor session: {session_id}\n"
|
|
564
|
+
"Advisor model: {model}\n"
|
|
565
|
+
"Advisor effort: {effort}\n"
|
|
566
|
+
"Report only after the same session endorses or corrections are applied.\n\n"
|
|
567
|
+
)
|
|
568
|
+
"""Prefix injected into each worker prompt after a successful pre-dispatch bind."""
|
|
569
|
+
|
|
570
|
+
SUMMARY_ADVISOR_SESSION_ID_KEY: str = "advisor_session_id"
|
|
571
|
+
"""Per-worker report JSON key for the unique advisor session id."""
|
|
572
|
+
|
|
573
|
+
SUMMARY_ADVISOR_SIGNAL_KEY: str = "advisor_completion_signal"
|
|
574
|
+
"""Per-worker report JSON key for the final advisor opening signal."""
|
|
575
|
+
|
|
576
|
+
SUMMARY_ADVISOR_LAUNCHER_KEY: str = "advisor_launcher"
|
|
577
|
+
"""Per-worker report JSON key for the spec-supplied launcher (runtime only)."""
|
|
578
|
+
|
|
579
|
+
ADVISOR_CLI_PRINT_FLAG: str = "-p"
|
|
580
|
+
"""Print/non-interactive flag passed to the advisor launcher."""
|
|
581
|
+
|
|
582
|
+
ADVISOR_CLI_MODEL_FLAG: str = "--model"
|
|
583
|
+
"""Model flag passed to the advisor launcher."""
|
|
584
|
+
|
|
585
|
+
ADVISOR_CLI_EFFORT_FLAG: str = "--effort"
|
|
586
|
+
"""Effort flag passed to the advisor launcher."""
|
|
587
|
+
|
|
588
|
+
ADVISOR_CLI_OUTPUT_FORMAT_FLAG: str = "--output-format"
|
|
589
|
+
"""Output-format flag passed to the advisor launcher."""
|
|
590
|
+
|
|
591
|
+
ADVISOR_CLI_OUTPUT_FORMAT_JSON: str = "json"
|
|
592
|
+
"""JSON output format value for advisor launcher calls."""
|
|
593
|
+
|
|
594
|
+
ADVISOR_CLI_RESUME_FLAG: str = "--resume"
|
|
595
|
+
"""Resume flag for post-report advisor consults."""
|
|
596
|
+
|
|
597
|
+
ADVISOR_BIND_PROMPT_TEMPLATE: str = (
|
|
598
|
+
"You are the unique worker advisor for role {role_name}. "
|
|
599
|
+
"Answer only. Open with exactly one of: ENDORSE | CORRECTION | PLAN | STOP. "
|
|
600
|
+
"Pre-dispatch: ENDORSE this worker assignment if safe, else CORRECTION."
|
|
601
|
+
)
|
|
602
|
+
"""Prompt body used for the pre-dispatch advisor bind."""
|
|
603
|
+
|
|
604
|
+
ADVISOR_VERDICT_PROMPT_TEMPLATE: str = (
|
|
605
|
+
"You are the unique worker advisor for role {role_name}, session {session_id}. "
|
|
606
|
+
"Answer only. Open with exactly one of: ENDORSE | CORRECTION | PLAN | STOP. "
|
|
607
|
+
"Post-report review of the worker report follows.\n\n{report_text}"
|
|
608
|
+
)
|
|
609
|
+
"""Prompt body used for the post-report advisor verdict."""
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Constants for verify_installable_package — npm pack surface checks.
|
|
2
|
+
|
|
3
|
+
Holds manifest keys, pack/tarball path tokens, hook-command path markers,
|
|
4
|
+
git and smoke-tool argv pieces, and CLI status messages.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
MANIFEST_FILENAME: str = "installable-surfaces.manifest.json"
|
|
8
|
+
"""Basename of the committed installable-surfaces manifest under the package root."""
|
|
9
|
+
|
|
10
|
+
PACKAGE_JSON_FILENAME: str = "package.json"
|
|
11
|
+
"""Basename of the npm package manifest that lists the files field."""
|
|
12
|
+
|
|
13
|
+
PACKAGE_JSON_FILES_KEY: str = "files"
|
|
14
|
+
"""JSON key on package.json that lists packaged path entries."""
|
|
15
|
+
|
|
16
|
+
PACKAGE_JSON_EXCLUDE_PREFIX: str = "!"
|
|
17
|
+
"""Prefix on package.json files entries that exclude a path pattern."""
|
|
18
|
+
|
|
19
|
+
MANIFEST_DIRECTORIES_KEY: str = "directories"
|
|
20
|
+
"""JSON key listing required top-level package directories."""
|
|
21
|
+
|
|
22
|
+
MANIFEST_ROOT_FILES_KEY: str = "root_files"
|
|
23
|
+
"""JSON key listing required package-root files."""
|
|
24
|
+
|
|
25
|
+
TARBALL_PACKAGE_PREFIX: str = "package/"
|
|
26
|
+
"""Path prefix npm pack applies to every member inside the generated tarball."""
|
|
27
|
+
|
|
28
|
+
PLUGIN_ROOT_TOKEN: str = "${CLAUDE_PLUGIN_ROOT}/"
|
|
29
|
+
"""Placeholder prefix hooks.json uses for package-relative hook script paths."""
|
|
30
|
+
|
|
31
|
+
PYTHON_FILE_SUFFIX: str = ".py"
|
|
32
|
+
"""Suffix that marks a hook command token as a Python script path."""
|
|
33
|
+
|
|
34
|
+
HOOKS_DIRECTORY_NAME: str = "hooks"
|
|
35
|
+
"""Top-level package directory that holds hook scripts and hooks.json."""
|
|
36
|
+
|
|
37
|
+
HOOKS_DIRECTORY_PREFIX: str = "hooks/"
|
|
38
|
+
"""Package-relative prefix that marks a hook script path under hooks/."""
|
|
39
|
+
|
|
40
|
+
HOOKS_JSON_RELATIVE_PATH: str = "hooks/hooks.json"
|
|
41
|
+
"""Package-relative path of the hook registration map."""
|
|
42
|
+
|
|
43
|
+
JSON_COMMAND_KEY: str = "command"
|
|
44
|
+
"""JSON object key whose string value is a hook command line."""
|
|
45
|
+
|
|
46
|
+
INSTALL_ENTRYPOINT_RELATIVE_PATH: str = "bin/install.mjs"
|
|
47
|
+
"""Package-relative path of the primary install CLI entrypoint."""
|
|
48
|
+
|
|
49
|
+
PACKAGE_PATH_FROM_REPOSITORY: str = "packages/claude-dev-env"
|
|
50
|
+
"""Repository-relative path of the published package directory."""
|
|
51
|
+
|
|
52
|
+
NPM_BINARY_NAME: str = "npm"
|
|
53
|
+
"""npm CLI binary name used to build the pack tarball on POSIX hosts."""
|
|
54
|
+
|
|
55
|
+
NPM_CMD_BINARY_NAME: str = "npm.cmd"
|
|
56
|
+
"""Windows npm launcher resolved before the extensionless npm name."""
|
|
57
|
+
|
|
58
|
+
NEWLINE_JOIN_SEPARATOR: str = "\n"
|
|
59
|
+
"""Separator used when joining multi-line verification failure reports."""
|
|
60
|
+
|
|
61
|
+
NPM_PACK_SUBCOMMAND: str = "pack"
|
|
62
|
+
"""npm subcommand that writes the installable tarball."""
|
|
63
|
+
|
|
64
|
+
NPM_PACK_JSON_FLAG: str = "--json"
|
|
65
|
+
"""Flag that makes npm pack emit machine-readable filename metadata."""
|
|
66
|
+
|
|
67
|
+
NPM_PACK_DESTINATION_FLAG: str = "--pack-destination"
|
|
68
|
+
"""Flag that directs npm pack to write the tarball into a chosen directory."""
|
|
69
|
+
|
|
70
|
+
NPM_PACK_FILENAME_KEY: str = "filename"
|
|
71
|
+
"""JSON field on an npm pack --json record that holds the tarball basename."""
|
|
72
|
+
|
|
73
|
+
GIT_BINARY_NAME: str = "git"
|
|
74
|
+
"""git CLI binary name used to confirm hook scripts are committed."""
|
|
75
|
+
|
|
76
|
+
GIT_LS_FILES_SUBCOMMAND: str = "ls-files"
|
|
77
|
+
"""git subcommand that lists tracked paths in the index."""
|
|
78
|
+
|
|
79
|
+
NODE_BINARY_NAME: str = "node"
|
|
80
|
+
"""Node.js binary name used for install-entrypoint syntax smoke checks."""
|
|
81
|
+
|
|
82
|
+
NODE_CHECK_FLAG: str = "--check"
|
|
83
|
+
"""Flag that makes node parse a script without executing it."""
|
|
84
|
+
|
|
85
|
+
UTF8_ENCODING: str = "utf-8"
|
|
86
|
+
"""Text encoding for manifest, hooks.json, and subprocess text mode."""
|
|
87
|
+
|
|
88
|
+
CLASS_PACKAGED: str = "packaged"
|
|
89
|
+
"""Surface classification when a directory is on disk and listed for packaging."""
|
|
90
|
+
|
|
91
|
+
CLASS_SOURCE_ONLY: str = "source_only"
|
|
92
|
+
"""Surface classification when a directory is on disk but not listed for packaging."""
|
|
93
|
+
|
|
94
|
+
CLASS_CONTRADICTORY: str = "contradictory"
|
|
95
|
+
"""Surface classification when package.json lists a directory that is missing on disk."""
|
|
96
|
+
|
|
97
|
+
EXIT_CODE_SUCCESS: int = 0
|
|
98
|
+
"""Process exit code when every installable-surface check passes."""
|
|
99
|
+
|
|
100
|
+
EXIT_CODE_FAILURE: int = 1
|
|
101
|
+
"""Process exit code when one or more installable-surface checks fail."""
|
|
102
|
+
|
|
103
|
+
MISSING_MANIFEST_SURFACES_HEADER: str = "Missing surfaces in npm pack tarball:"
|
|
104
|
+
"""Header printed when required manifest paths are absent from the packed tarball."""
|
|
105
|
+
|
|
106
|
+
UNTRACKED_HOOK_SCRIPTS_HEADER: str = "Hook scripts missing from git index:"
|
|
107
|
+
"""Header printed when a hooks.json command resolves to an untracked or missing file."""
|
|
108
|
+
|
|
109
|
+
SMOKE_COMPILE_FAILURES_HEADER: str = "Hook scripts failed py_compile:"
|
|
110
|
+
"""Header printed when a resolved hook script fails Python syntax compilation."""
|
|
111
|
+
|
|
112
|
+
INSTALL_ENTRYPOINT_SMOKE_FAILURE_HEADER: str = "Install entrypoint failed node --check:"
|
|
113
|
+
"""Header printed when bin/install.mjs fails the Node syntax smoke check."""
|
|
114
|
+
|
|
115
|
+
VERIFICATION_PASSED_MESSAGE: str = "installable package verification passed"
|
|
116
|
+
"""Status line printed when every check succeeds."""
|