coding-os 0.3.2__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.
- adapters/claude/README.md +6 -0
- adapters/claude/_install_helpers/extract_stacks.py +43 -0
- adapters/claude/_install_helpers/update_mcp_json.py +75 -0
- adapters/claude/adapter.yaml +164 -0
- adapters/claude/hooks/README.md +40 -0
- adapters/claude/hooks/agent_memory_sync.py +131 -0
- adapters/claude/hooks/ensure-agent-memory-link.sh +36 -0
- adapters/claude/hooks/sync-agent-memory.sh +21 -0
- adapters/claude/install.sh +86 -0
- adapters/claude/sdk_dispatcher.py +871 -0
- adapters/claude/settings.local.template.json +31 -0
- adapters/claude/settings.template.json +808 -0
- adapters/claude/update_mcp_json.py +85 -0
- adapters/codex/adapter.yaml +254 -0
- adapters/codex/chat_provider.py +230 -0
- adapters/codex/commands/formula-f1.md +129 -0
- adapters/codex/commands/formula-f10.md +100 -0
- adapters/codex/commands/formula-f11.md +123 -0
- adapters/codex/commands/formula-f2.md +139 -0
- adapters/codex/commands/formula-f3.md +127 -0
- adapters/codex/commands/formula-f4.md +101 -0
- adapters/codex/commands/formula-f5.md +135 -0
- adapters/codex/commands/formula-f6.md +147 -0
- adapters/codex/commands/formula-f7.md +111 -0
- adapters/codex/commands/formula-f8.md +133 -0
- adapters/codex/commands/formula-f9.md +112 -0
- adapters/codex/enable_codex_hooks.py +94 -0
- adapters/codex/ensure_codex_mcp.py +124 -0
- adapters/codex/hooks/codex-merge-hook-output.py +72 -0
- adapters/codex/hooks/codex-normalize-edit.py +96 -0
- adapters/codex/hooks/codex-postedit-dispatch.sh +75 -0
- adapters/codex/hooks/codex-posttool-dispatch.sh +70 -0
- adapters/codex/hooks/codex-preedit-dispatch.sh +83 -0
- adapters/codex/hooks/codex-pretool-dispatch.sh +82 -0
- adapters/codex/hooks/codex-sessionend-dispatch.sh +20 -0
- adapters/codex/hooks/codex-sessionstart-dispatch.sh +68 -0
- adapters/codex/hooks/codex-stop-dispatch.sh +73 -0
- adapters/codex/hooks/codex-userpromptsubmit-dispatch.sh +74 -0
- adapters/codex/hooks.template.json +208 -0
- adapters/codex/install.sh +83 -0
- adapters/codex/sdk_dispatcher.py +449 -0
- board_os/__init__.py +39 -0
- board_os/_agent_runtime.py +256 -0
- board_os/config.py +421 -0
- board_os/git_coherence.py +107 -0
- board_os/hub_adapter_manifest.py +140 -0
- board_os/mcp_tools.py +3228 -0
- board_os/migration.py +166 -0
- board_os/parser.py +317 -0
- board_os/presence.py +156 -0
- board_os/sync.py +320 -0
- board_os/transition_gates.py +224 -0
- board_os/transition_gates_cli.py +272 -0
- board_os/transition_gates_validator.py +551 -0
- board_os/verify_suites.py +126 -0
- board_os/verify_suites_cli.py +328 -0
- board_os/workflow.py +967 -0
- cli/__init__.py +0 -0
- cli/_data_types.py +248 -0
- cli/_init_helpers.py +587 -0
- cli/_resources.py +100 -0
- cli/adapter_registry.py +239 -0
- cli/add_stack.py +315 -0
- cli/aggregator.py +438 -0
- cli/board_commands.py +1218 -0
- cli/brain_commands.py +255 -0
- cli/cognition.py +345 -0
- cli/config_composer.py +349 -0
- cli/core_version.py +41 -0
- cli/cron_commands.py +278 -0
- cli/db_reset.py +298 -0
- cli/doc_commands.py +111 -0
- cli/doctor.py +2953 -0
- cli/doctor_board.py +365 -0
- cli/doctor_extras.py +1121 -0
- cli/doctor_graph.py +608 -0
- cli/doctor_tokens.py +254 -0
- cli/graph_commands.py +1265 -0
- cli/hook_renderer.py +393 -0
- cli/hub_commands.py +580 -0
- cli/list_adapters.py +79 -0
- cli/list_stacks.py +105 -0
- cli/logs_commands.py +89 -0
- cli/main.py +3070 -0
- cli/materialize_file.py +65 -0
- cli/mcp_start.py +153 -0
- cli/module_commands.py +513 -0
- cli/pr_commands.py +2024 -0
- cli/preset_commands.py +126 -0
- cli/preset_registry.py +171 -0
- cli/project_overrides.py +119 -0
- cli/registry.py +365 -0
- cli/remove_stack.py +492 -0
- cli/renderer.py +620 -0
- cli/setup.py +464 -0
- cli/skill_commands.py +689 -0
- cli/skill_registry.py +235 -0
- cli/skills_list.py +332 -0
- cli/stack_lint.py +351 -0
- cli/stack_registry.py +688 -0
- cli/subsystems.py +335 -0
- cli/sync_all.py +310 -0
- cli/tail_command.py +410 -0
- cli/update.py +608 -0
- cli/verify_since_edit.py +439 -0
- coding_os-0.3.2.dist-info/METADATA +508 -0
- coding_os-0.3.2.dist-info/RECORD +1304 -0
- coding_os-0.3.2.dist-info/WHEEL +5 -0
- coding_os-0.3.2.dist-info/entry_points.txt +5 -0
- coding_os-0.3.2.dist-info/licenses/LICENSE +201 -0
- coding_os-0.3.2.dist-info/top_level.txt +10 -0
- core/__init__.py +0 -0
- core/board_os/__init__.py +39 -0
- core/board_os/_agent_runtime.py +256 -0
- core/board_os/config.py +421 -0
- core/board_os/git_coherence.py +107 -0
- core/board_os/hub_adapter_manifest.py +140 -0
- core/board_os/mcp_tools.py +3228 -0
- core/board_os/migration.py +166 -0
- core/board_os/parser.py +317 -0
- core/board_os/presence.py +156 -0
- core/board_os/sync.py +320 -0
- core/board_os/transition-gates.yaml +176 -0
- core/board_os/transition_gates.py +224 -0
- core/board_os/transition_gates_cli.py +272 -0
- core/board_os/transition_gates_validator.py +551 -0
- core/board_os/verify-suites.yaml +113 -0
- core/board_os/verify_suites.py +126 -0
- core/board_os/verify_suites_cli.py +328 -0
- core/board_os/workflow.py +967 -0
- core/commands/board.md +27 -0
- core/commands/classify.md +23 -0
- core/commands/compose.md +23 -0
- core/commands/daily.md +31 -0
- core/commands/diagnose.md +7 -0
- core/commands/memory-search.md +23 -0
- core/commands/new-project.md +33 -0
- core/commands/retro.md +38 -0
- core/commands/review.md +14 -0
- core/commands/task.md +17 -0
- core/commands/verify.md +34 -0
- core/docs/thinking_os-final-edition.md +1449 -0
- core/doctor-config.yaml +74 -0
- core/graph_os/__init__.py +29 -0
- core/graph_os/backend.py +233 -0
- core/graph_os/backends/__init__.py +13 -0
- core/graph_os/backends/sqlite_backend.py +1053 -0
- core/graph_os/bench/__init__.py +17 -0
- core/graph_os/bench/fixtures.py +56 -0
- core/graph_os/bench/harness.py +95 -0
- core/graph_os/bench/persian_precision.py +142 -0
- core/graph_os/bench/scale_500k.py +120 -0
- core/graph_os/bench/token_cost.py +170 -0
- core/graph_os/bench/viewer_fps.py +110 -0
- core/graph_os/communities.py +410 -0
- core/graph_os/enterprise.py +218 -0
- core/graph_os/entry_points.py +226 -0
- core/graph_os/extractors/__init__.py +25 -0
- core/graph_os/extractors/code_generic.py +914 -0
- core/graph_os/extractors/code_go.py +1422 -0
- core/graph_os/extractors/code_json.py +340 -0
- core/graph_os/extractors/code_php.py +979 -0
- core/graph_os/extractors/code_python.py +1454 -0
- core/graph_os/extractors/code_shell.py +538 -0
- core/graph_os/extractors/code_toml.py +302 -0
- core/graph_os/extractors/code_ts.py +1665 -0
- core/graph_os/extractors/code_yaml.py +394 -0
- core/graph_os/extractors/contracts.py +1592 -0
- core/graph_os/extractors/md_links.py +890 -0
- core/graph_os/extractors/task_deps.py +345 -0
- core/graph_os/groups/__init__.py +22 -0
- core/graph_os/groups/cross_repo.py +156 -0
- core/graph_os/groups/manifest.py +141 -0
- core/graph_os/ingest/__init__.py +19 -0
- core/graph_os/ingest/base.py +306 -0
- core/graph_os/ingest/github.py +112 -0
- core/graph_os/ingest/zip.py +95 -0
- core/graph_os/toolchain.py +393 -0
- core/graph_os/tools/__init__.py +9 -0
- core/graph_os/tools/graph.py +5573 -0
- core/graph_os/tools/reindex_dispatch.py +730 -0
- core/graph_os/tree_sitter_overlay.py +235 -0
- core/graph_os/types.py +252 -0
- core/graph_os/vec_index.py +277 -0
- core/graph_os/viewer/__init__.py +12 -0
- core/graph_os/viewer/exporter.py +93 -0
- core/graph_os/viewer/template.py +189 -0
- core/hooks/_helpers/_paths.py +40 -0
- core/hooks/_helpers/advance_role.py +72 -0
- core/hooks/_helpers/auto_compose.py +228 -0
- core/hooks/_helpers/auto_validate_lessons.py +55 -0
- core/hooks/_helpers/branch_guard_check.py +796 -0
- core/hooks/_helpers/check_commit_message.py +108 -0
- core/hooks/_helpers/check_dangerous_rm.py +80 -0
- core/hooks/_helpers/check_git_bypass.py +154 -0
- core/hooks/_helpers/check_git_destructive.py +77 -0
- core/hooks/_helpers/check_settings_write.py +97 -0
- core/hooks/_helpers/consume_override.py +51 -0
- core/hooks/_helpers/context_budget.py +77 -0
- core/hooks/_helpers/cos_say_json.py +103 -0
- core/hooks/_helpers/destructive_edit_check.py +163 -0
- core/hooks/_helpers/detect_status_transition.py +82 -0
- core/hooks/_helpers/digest_regen.py +56 -0
- core/hooks/_helpers/doc_sync_check.py +498 -0
- core/hooks/_helpers/drain_embedding_outbox.py +52 -0
- core/hooks/_helpers/extract_additional_context.py +51 -0
- core/hooks/_helpers/extract_commit_msg_arg.py +74 -0
- core/hooks/_helpers/git_command_parse.py +424 -0
- core/hooks/_helpers/git_settings_fields.py +47 -0
- core/hooks/_helpers/graph_context_match.py +37 -0
- core/hooks/_helpers/graph_marker_check.py +70 -0
- core/hooks/_helpers/jit_recall.py +56 -0
- core/hooks/_helpers/json_field.py +41 -0
- core/hooks/_helpers/narrative_signal.py +59 -0
- core/hooks/_helpers/observation_count.py +31 -0
- core/hooks/_helpers/pre_commit_batch.py +177 -0
- core/hooks/_helpers/pre_commit_fake_input.py +42 -0
- core/hooks/_helpers/presence_gc.py +102 -0
- core/hooks/_helpers/presence_write.py +167 -0
- core/hooks/_helpers/recover_indirect.py +35 -0
- core/hooks/_helpers/routing_evolution.py +104 -0
- core/hooks/_helpers/session_recap.py +72 -0
- core/hooks/_helpers/skill_primer.py +229 -0
- core/hooks/_helpers/task_sync.py +59 -0
- core/hooks/_helpers/tool_failure_capture.py +147 -0
- core/hooks/_helpers/trajectory_autosnap.py +278 -0
- core/hooks/_helpers/trajectory_startup.py +62 -0
- core/hooks/_helpers/turn_summary.py +82 -0
- core/hooks/_helpers/validate_task_frontmatter.py +98 -0
- core/hooks/_helpers/wip_limit_check.py +103 -0
- core/hooks/_helpers/wip_lines.py +53 -0
- core/hooks/_helpers/work_log_append.py +89 -0
- core/hooks/_helpers/wrap_dispatch_output.py +82 -0
- core/hooks/advance-role.sh +48 -0
- core/hooks/agent-presence.sh +179 -0
- core/hooks/auto-brain-decay.sh +184 -0
- core/hooks/auto-compose-roles.sh +83 -0
- core/hooks/auto-graph-reconcile-shell.sh +119 -0
- core/hooks/auto-regen-doc-index.sh +120 -0
- core/hooks/auto-reindex-docs.sh +130 -0
- core/hooks/auto-task-sync.sh +56 -0
- core/hooks/auto-trace-rotate.sh +88 -0
- core/hooks/block-bad-patterns.sh +212 -0
- core/hooks/block-dangerous-commands.sh +182 -0
- core/hooks/block-hardcoded-literals.sh +90 -0
- core/hooks/block-migration-conflict.sh +114 -0
- core/hooks/block-protected-files.sh +129 -0
- core/hooks/block-secrets.sh +185 -0
- core/hooks/block-shared-tree-edit.sh +75 -0
- core/hooks/block-uv-heredoc.sh +78 -0
- core/hooks/branch-guard.sh +122 -0
- core/hooks/capture-observation.sh +76 -0
- core/hooks/capture-tool-failure.sh +24 -0
- core/hooks/capture-work-log.sh +89 -0
- core/hooks/check-agents-md-refs.sh +75 -0
- core/hooks/check-agents-md-size.sh +49 -0
- core/hooks/check-capture-worked.sh +148 -0
- core/hooks/check-doc-size.sh +61 -0
- core/hooks/check-mcp-extras.sh +92 -0
- core/hooks/check-state.sh +87 -0
- core/hooks/classify-task-mode.sh +103 -0
- core/hooks/cos-env.sh +1301 -0
- core/hooks/drain-embedding-outbox.sh +24 -0
- core/hooks/enforce-anti-ambiguity.sh +74 -0
- core/hooks/enforce-commit-message.sh +73 -0
- core/hooks/enforce-doc-anchor.sh +224 -0
- core/hooks/enforce-doc-sync.sh +206 -0
- core/hooks/enforce-graph-context.sh +89 -0
- core/hooks/enforce-graph-first-read.sh +94 -0
- core/hooks/enforce-memory-check.sh +128 -0
- core/hooks/enforce-rename-plan.sh +78 -0
- core/hooks/enforce-scaffold-boundary.sh +68 -0
- core/hooks/enforce-skill.sh +125 -0
- core/hooks/enforce-task-body.sh +52 -0
- core/hooks/enforce-task-start.sh +81 -0
- core/hooks/enforce-task-transition.sh +75 -0
- core/hooks/enforce-template.sh +143 -0
- core/hooks/enforce-verify.sh +112 -0
- core/hooks/enforce-wip-limit.sh +43 -0
- core/hooks/enforce-zoom.sh +69 -0
- core/hooks/ensure-hub-up.sh +67 -0
- core/hooks/inject-mcp-caller-session.sh +70 -0
- core/hooks/jit-recall.sh +65 -0
- core/hooks/link-commit-to-task.sh +143 -0
- core/hooks/lint-task.sh +40 -0
- core/hooks/nudge-docs-first.sh +71 -0
- core/hooks/nudge-git-mode.sh +29 -0
- core/hooks/nudge-graph-os.sh +118 -0
- core/hooks/nudge-learn-narrative.sh +36 -0
- core/hooks/nudge-model-routing.sh +32 -0
- core/hooks/nudge-reentry.sh +101 -0
- core/hooks/nudge-reuse-first.sh +68 -0
- core/hooks/nudge-task-discovery.sh +81 -0
- core/hooks/nudge-thinking-os.sh +109 -0
- core/hooks/pr-reap.sh +23 -0
- core/hooks/reclaim-sweep.sh +58 -0
- core/hooks/record-verify-auto.sh +77 -0
- core/hooks/record-verify.sh +74 -0
- core/hooks/regen-reminder.sh +104 -0
- core/hooks/registry.yaml +1262 -0
- core/hooks/remind-daily.sh +27 -0
- core/hooks/remind-dogfood.sh +70 -0
- core/hooks/remind-learn-validate.sh +94 -0
- core/hooks/rules-primer.sh +50 -0
- core/hooks/search-enforce-inventory.sh +108 -0
- core/hooks/search-verify-remaining.sh +132 -0
- core/hooks/session-context.sh +729 -0
- core/hooks/session-end.sh +145 -0
- core/hooks/session-skill-primer.sh +43 -0
- core/hooks/snapshot-transcript.sh +56 -0
- core/hooks/sync-task-current.sh +85 -0
- core/hooks/test-first-reminder.sh +120 -0
- core/hooks/test-governor.sh +173 -0
- core/hooks/thinking_os-gate.sh +52 -0
- core/hooks/track-backtrack.sh +35 -0
- core/hooks/track-discovery.sh +121 -0
- core/hooks/track-skill.sh +53 -0
- core/hooks/validate-task-frontmatter.sh +49 -0
- core/hooks/verify-rename-callers.sh +119 -0
- core/hooks/warn-abandoned-task.sh +99 -0
- core/hooks/warn-destructive-edit.sh +64 -0
- core/hooks/warn-diff-size.sh +43 -0
- core/hooks/warn-graph-empty.sh +81 -0
- core/hooks/warn-mcp-down.sh +190 -0
- core/hooks/write-state.sh +55 -0
- core/logging_os/__init__.py +33 -0
- core/logging_os/api.py +127 -0
- core/logging_os/bridge.py +80 -0
- core/logging_os/config.py +172 -0
- core/logging_os/fingerprint.py +25 -0
- core/logging_os/redact.py +53 -0
- core/logging_os/render.py +83 -0
- core/logging_os/sinks.py +164 -0
- core/rules/anti-overengineering.md +44 -0
- core/rules/api-contract-discipline.md +41 -0
- core/rules/dimension-registry.md +155 -0
- core/rules/git-workflow.md +57 -0
- core/rules/memory.md +46 -0
- core/rules/model-routing.md +22 -0
- core/rules/skill-enforcement.md +75 -0
- core/rules/test-discipline.md +38 -0
- core/rules/thinking_os.md +48 -0
- core/rules/transparency-banner.md +37 -0
- core/runtime_paths.yaml +36 -0
- core/scaffold_manifest.json +14430 -0
- core/scheduled/__init__.py +0 -0
- core/scheduled/_activity.py +126 -0
- core/scheduled/_state.py +113 -0
- core/scheduled/config.py +86 -0
- core/scheduled/dep_reconcile.py +135 -0
- core/scheduled/error_sweep.py +137 -0
- core/scheduled/nightly.py +930 -0
- core/scheduled/responsive_extract.py +65 -0
- core/schemas/adapter.schema.json +269 -0
- core/schemas/preset.schema.json +50 -0
- core/schemas/skill.schema.json +81 -0
- core/schemas/stack.schema.json +404 -0
- core/scripts/_lib.sh +9 -0
- core/scripts/docs-lint.sh +228 -0
- core/scripts/docs-nav-fix.sh +133 -0
- core/scripts/docs-staleness-check.sh +154 -0
- core/scripts/install-adapter.sh +266 -0
- core/scripts/link-stack-skills.sh +52 -0
- core/scripts/log-latest.sh +106 -0
- core/scripts/log-search.sh +89 -0
- core/scripts/log-write.sh +134 -0
- core/scripts/ref-resolve.sh +71 -0
- core/skills/a11y/SKILL.md +305 -0
- core/skills/a11y/assets/a11y-checklist.md +137 -0
- core/skills/a11y/references/aria-and-focus.md +247 -0
- core/skills/a11y/references/rn-accessibility.md +343 -0
- core/skills/a11y/references/screen-reader-testing.md +190 -0
- core/skills/agent-memory/SKILL.md +191 -0
- core/skills/agent-memory/assets/memory-checklist.md +21 -0
- core/skills/agent-memory/references/memory-recipes.md +57 -0
- core/skills/api-design/SKILL.md +232 -0
- core/skills/api-design/assets/api-design-checklist.md +110 -0
- core/skills/api-design/references/error-envelope.md +381 -0
- core/skills/api-design/references/idempotency-pagination.md +312 -0
- core/skills/api-design/references/rest-contracts.md +426 -0
- core/skills/auth-patterns/SKILL.md +352 -0
- core/skills/auth-patterns/assets/auth-checklist.md +118 -0
- core/skills/auth-patterns/references/jwt-and-service-tokens.md +343 -0
- core/skills/auth-patterns/references/passkeys-2fa.md +289 -0
- core/skills/auth-patterns/references/sessions-vs-jwt.md +230 -0
- core/skills/auth-patterns/scripts/cookie-flag-check.py +146 -0
- core/skills/backend-fundamentals/SKILL.md +238 -0
- core/skills/backend-fundamentals/assets/backend-checklist.md +27 -0
- core/skills/backend-fundamentals/references/backend-patterns.md +56 -0
- core/skills/backend-fundamentals/scripts/check_layering.py +83 -0
- core/skills/clean-code/SKILL.md +642 -0
- core/skills/clean-code/scripts/audit-fail-closed.py +167 -0
- core/skills/codebase-explorer/SKILL.md +89 -0
- core/skills/codebase-explorer/assets/reading-checklist.md +24 -0
- core/skills/codebase-explorer/references/reading-strategies.md +52 -0
- core/skills/codebase-explorer/scripts/outline.py +99 -0
- core/skills/db-design/SKILL.md +327 -0
- core/skills/db-design/assets/migration-template.sql +49 -0
- core/skills/db-design/references/migration-discipline.md +290 -0
- core/skills/db-design/references/postgres-patterns.md +340 -0
- core/skills/db-design/scripts/migration-safety.sh +150 -0
- core/skills/deployment-cicd/SKILL.md +260 -0
- core/skills/deployment-cicd/assets/deploy-checklist.md +26 -0
- core/skills/deployment-cicd/references/pipeline-and-release.md +54 -0
- core/skills/deployment-cicd/scripts/lint_workflow.py +79 -0
- core/skills/docker/SKILL.md +114 -0
- core/skills/docker/assets/dockerfile-checklist.md +31 -0
- core/skills/docker/references/compose-patterns.md +66 -0
- core/skills/docker/references/dockerfile-optimization.md +64 -0
- core/skills/docker/scripts/lint_dockerfile.sh +48 -0
- core/skills/docker/versions.json +16 -0
- core/skills/end-to-end-testing/SKILL.md +101 -0
- core/skills/end-to-end-testing/assets/e2e-checklist.md +23 -0
- core/skills/end-to-end-testing/references/maestro.md +63 -0
- core/skills/end-to-end-testing/references/playwright.md +68 -0
- core/skills/end-to-end-testing/scripts/lint_e2e.py +88 -0
- core/skills/end-to-end-testing/versions.json +16 -0
- core/skills/frontend-design/SKILL.md +76 -0
- core/skills/frontend-design/assets/design-checklist.md +29 -0
- core/skills/frontend-design/references/design-principles.md +65 -0
- core/skills/frontend-design/scripts/check_contrast.py +89 -0
- core/skills/frontend-fundamentals/SKILL.md +213 -0
- core/skills/frontend-fundamentals/assets/frontend-checklist.md +25 -0
- core/skills/frontend-fundamentals/references/rendering-and-state.md +66 -0
- core/skills/frontend-fundamentals/scripts/check_frontend.py +86 -0
- core/skills/graph-explorer/SKILL.md +215 -0
- core/skills/graph-explorer/scripts/explain-impact.sh +64 -0
- core/skills/graphql/SKILL.md +187 -0
- core/skills/grpc-microservices/SKILL.md +174 -0
- core/skills/hexagonal-architecture/SKILL.md +199 -0
- core/skills/hexagonal-architecture/assets/folder-scaffold.md +233 -0
- core/skills/hexagonal-architecture/references/anti-patterns.md +129 -0
- core/skills/hexagonal-architecture/references/go-fiber-layout.md +429 -0
- core/skills/hexagonal-architecture/references/python-fastapi-layout.md +453 -0
- core/skills/hexagonal-architecture/references/react-native-layout.md +428 -0
- core/skills/i18n/SKILL.md +126 -0
- core/skills/incident-response/SKILL.md +225 -0
- core/skills/incident-response/assets/incident-checklist.md +29 -0
- core/skills/incident-response/references/severity-and-runbook.md +53 -0
- core/skills/incident-response/scripts/classify_severity.py +86 -0
- core/skills/linux-sysadmin/SKILL.md +115 -0
- core/skills/linux-sysadmin/assets/hardening-checklist.md +29 -0
- core/skills/linux-sysadmin/references/ssh-hardening.md +62 -0
- core/skills/linux-sysadmin/references/systemd-and-services.md +77 -0
- core/skills/linux-sysadmin/scripts/triage.sh +50 -0
- core/skills/linux-sysadmin/versions.json +17 -0
- core/skills/llm-patterns/SKILL.md +410 -0
- core/skills/llm-patterns/assets/llm-feature-checklist.md +26 -0
- core/skills/llm-patterns/references/rag-and-evals.md +59 -0
- core/skills/llm-patterns/scripts/estimate_tokens.py +75 -0
- core/skills/messaging-queues/SKILL.md +142 -0
- core/skills/mobile-fundamentals/SKILL.md +406 -0
- core/skills/mobile-fundamentals/assets/mobile-launch-checklist.md +130 -0
- core/skills/mobile-fundamentals/references/navigation-and-deep-links.md +337 -0
- core/skills/mobile-fundamentals/references/offline-sync.md +339 -0
- core/skills/node-backend/SKILL.md +114 -0
- core/skills/node-backend/assets/node-checklist.md +25 -0
- core/skills/node-backend/references/async-and-errors.md +67 -0
- core/skills/node-backend/references/event-loop.md +65 -0
- core/skills/node-backend/scripts/check_package.py +78 -0
- core/skills/node-backend/versions.json +17 -0
- core/skills/observability/SKILL.md +289 -0
- core/skills/observability/assets/observability-checklist.md +27 -0
- core/skills/observability/references/instrumentation.md +57 -0
- core/skills/observability/scripts/lint_logging.py +77 -0
- core/skills/payments/SKILL.md +102 -0
- core/skills/performance/SKILL.md +305 -0
- core/skills/performance/assets/perf-checklist.md +143 -0
- core/skills/performance/references/mobile-performance.md +249 -0
- core/skills/performance/references/web-vitals.md +209 -0
- core/skills/php/SKILL.md +116 -0
- core/skills/php/assets/php-checklist.md +26 -0
- core/skills/php/references/modern-php.md +64 -0
- core/skills/php/references/security.md +72 -0
- core/skills/php/scripts/scan_php_smells.py +99 -0
- core/skills/php/versions.json +9 -0
- core/skills/pr-mode-driver/SKILL.md +65 -0
- core/skills/realtime-websockets/SKILL.md +152 -0
- core/skills/redis/SKILL.md +105 -0
- core/skills/redis/assets/redis-checklist.md +27 -0
- core/skills/redis/references/operations.md +66 -0
- core/skills/redis/references/patterns.md +62 -0
- core/skills/redis/scripts/analyze_info.py +101 -0
- core/skills/redis/versions.json +9 -0
- core/skills/search/SKILL.md +91 -0
- core/skills/search/references/grep.md +76 -0
- core/skills/search/scripts/verify-count.sh +73 -0
- core/skills/search-infra/SKILL.md +109 -0
- core/skills/security-mobile/SKILL.md +394 -0
- core/skills/security-mobile/assets/mobile-security-checklist.md +117 -0
- core/skills/security-mobile/references/masvs-l1-checklist.md +127 -0
- core/skills/security-web/SKILL.md +217 -0
- core/skills/security-web/assets/security-web-checklist.md +167 -0
- core/skills/security-web/references/owasp-top-10.md +551 -0
- core/skills/security-web/references/supply-chain.md +179 -0
- core/skills/security-web/scripts/csp-check.sh +153 -0
- core/skills/shell-scripting/SKILL.md +128 -0
- core/skills/shell-scripting/assets/script-checklist.md +33 -0
- core/skills/shell-scripting/references/argument-parsing.md +84 -0
- core/skills/shell-scripting/references/bash-robustness.md +78 -0
- core/skills/shell-scripting/scripts/lint_script.sh +53 -0
- core/skills/shell-scripting/scripts/new_script.py +131 -0
- core/skills/shell-scripting/versions.json +23 -0
- core/skills/sql-authoring/SKILL.md +104 -0
- core/skills/sql-authoring/assets/query-review-checklist.md +26 -0
- core/skills/sql-authoring/references/query-patterns.md +89 -0
- core/skills/sql-authoring/references/reading-explain.md +52 -0
- core/skills/sql-authoring/scripts/analyze_plan.py +100 -0
- core/skills/sql-authoring/versions.json +17 -0
- core/skills/state-management/SKILL.md +428 -0
- core/skills/state-management/references/tanstack-query-recipes.md +301 -0
- core/skills/state-management/references/zustand-recipes.md +364 -0
- core/skills/supabase/SKILL.md +108 -0
- core/skills/supabase/assets/supabase-checklist.md +26 -0
- core/skills/supabase/references/realtime-and-storage.md +55 -0
- core/skills/supabase/references/rls-and-auth.md +65 -0
- core/skills/supabase/scripts/check_rls.py +88 -0
- core/skills/supabase/versions.json +9 -0
- core/skills/task-driver/SKILL.md +272 -0
- core/skills/task-driver/scripts/task-lint.sh +163 -0
- core/skills/technical-writing/SKILL.md +85 -0
- core/skills/technical-writing/assets/doc-checklist.md +29 -0
- core/skills/technical-writing/references/doc-anatomy.md +53 -0
- core/skills/technical-writing/references/writing-craft.md +59 -0
- core/skills/technical-writing/scripts/new_doc.py +81 -0
- core/skills/terraform-k8s/SKILL.md +133 -0
- core/skills/testing-strategy/SKILL.md +266 -0
- core/skills/testing-strategy/assets/test-review-checklist.md +25 -0
- core/skills/testing-strategy/references/test-types.md +52 -0
- core/skills/testing-strategy/scripts/coverage_gate.py +79 -0
- core/skills/thinking_os/SKILL.md +288 -0
- core/skills/thinking_os/scripts/classify.sh +122 -0
- core/skills/typescript/SKILL.md +110 -0
- core/skills/typescript/assets/typescript-checklist.md +24 -0
- core/skills/typescript/references/strictness.md +53 -0
- core/skills/typescript/references/type-system.md +86 -0
- core/skills/typescript/scripts/check_tsconfig.py +92 -0
- core/skills/typescript/versions.json +9 -0
- core/subsystems.yaml +202 -0
- core/thinking_os/__init__.py +1 -0
- core/thinking_os/_agent_markers.py +32 -0
- core/thinking_os/agents/README.md +71 -0
- core/thinking_os/agents/analyst.md +139 -0
- core/thinking_os/agents/architect.md +127 -0
- core/thinking_os/agents/debugger.md +111 -0
- core/thinking_os/agents/deployer.md +112 -0
- core/thinking_os/agents/distiller.md +28 -0
- core/thinking_os/agents/documenter.md +101 -0
- core/thinking_os/agents/implementer.md +135 -0
- core/thinking_os/agents/internal/session_observer.md +39 -0
- core/thinking_os/agents/observer.md +100 -0
- core/thinking_os/agents/onboarder.md +81 -0
- core/thinking_os/agents/refactorer.md +123 -0
- core/thinking_os/agents/repairer.md +47 -0
- core/thinking_os/agents/researcher.md +129 -0
- core/thinking_os/agents/reviewer.md +147 -0
- core/thinking_os/agents/security_auditor.md +133 -0
- core/thinking_os/background.py +405 -0
- core/thinking_os/bootstrap_outcomes.py +200 -0
- core/thinking_os/budget.py +302 -0
- core/thinking_os/capture.py +495 -0
- core/thinking_os/cognition.py +516 -0
- core/thinking_os/cognition_schemas.py +517 -0
- core/thinking_os/compress.py +192 -0
- core/thinking_os/concepts.py +233 -0
- core/thinking_os/dashboard.py +159 -0
- core/thinking_os/database.py +2883 -0
- core/thinking_os/decay.py +393 -0
- core/thinking_os/digest.py +295 -0
- core/thinking_os/dispatcher.py +192 -0
- core/thinking_os/dispatcher_helpers.py +48 -0
- core/thinking_os/dispatchers/__init__.py +3 -0
- core/thinking_os/dispatchers/default.py +47 -0
- core/thinking_os/distill.py +192 -0
- core/thinking_os/doc_indexer.py +905 -0
- core/thinking_os/embeddings.py +943 -0
- core/thinking_os/formula_composer.py +556 -0
- core/thinking_os/gate_marker.py +75 -0
- core/thinking_os/graph.py +296 -0
- core/thinking_os/graph_indexer.py +360 -0
- core/thinking_os/health_check.py +517 -0
- core/thinking_os/impact.py +119 -0
- core/thinking_os/memory_gc.py +356 -0
- core/thinking_os/migrator_embeddings.py +318 -0
- core/thinking_os/precision.py +194 -0
- core/thinking_os/presets/registry.yaml +127 -0
- core/thinking_os/record_outcome.py +399 -0
- core/thinking_os/repair.py +105 -0
- core/thinking_os/retrieval_quality.py +239 -0
- core/thinking_os/roles/analyst.yaml +83 -0
- core/thinking_os/roles/architect.yaml +88 -0
- core/thinking_os/roles/debugger.yaml +71 -0
- core/thinking_os/roles/deployer.yaml +71 -0
- core/thinking_os/roles/documenter.yaml +72 -0
- core/thinking_os/roles/implementer.yaml +83 -0
- core/thinking_os/roles/observer.yaml +70 -0
- core/thinking_os/roles/refactorer.yaml +71 -0
- core/thinking_os/roles/researcher.yaml +72 -0
- core/thinking_os/roles/reviewer.yaml +79 -0
- core/thinking_os/roles/security_auditor.yaml +83 -0
- core/thinking_os/roles_state.py +168 -0
- core/thinking_os/sanitizer.py +320 -0
- core/thinking_os/server.py +3160 -0
- core/thinking_os/session_enrich.py +272 -0
- core/thinking_os/session_observe_worker.py +111 -0
- core/thinking_os/session_startup.py +74 -0
- core/thinking_os/session_summary.py +245 -0
- core/thinking_os/situations/registry.yaml +99 -0
- core/thinking_os/task_analyzer.py +462 -0
- core/thinking_os/task_parser.py +342 -0
- core/thinking_os/task_sync.py +73 -0
- core/thinking_os/tools/__init__.py +6 -0
- core/thinking_os/tools/_shared.py +947 -0
- core/thinking_os/tools/cognition.py +1867 -0
- core/thinking_os/tools/docs.py +770 -0
- core/thinking_os/tools/learning.py +2078 -0
- core/thinking_os/tools/logs.py +79 -0
- core/thinking_os/tools/memory.py +840 -0
- core/thinking_os/tools/metrics.py +200 -0
- core/thinking_os/tools/retrieve.py +415 -0
- core/thinking_os/tools/routing.py +658 -0
- core/thinking_os/tools/tasks.py +449 -0
- core/thinking_os/tools/trajectory.py +181 -0
- core/thinking_os/tracing.py +235 -0
- core/web/__init__.py +5 -0
- core/web/_cache.py +118 -0
- core/web/_deps.py +56 -0
- core/web/_envelope.py +85 -0
- core/web/_project_context.py +140 -0
- core/web/chat_providers.py +108 -0
- core/web/init_jobs.py +216 -0
- core/web/routes/__init__.py +25 -0
- core/web/routes/_bounded_read.py +76 -0
- core/web/routes/board.py +1089 -0
- core/web/routes/cognition.py +1838 -0
- core/web/routes/config.py +635 -0
- core/web/routes/graph.py +513 -0
- core/web/routes/health.py +180 -0
- core/web/routes/hooks.py +288 -0
- core/web/routes/hub.py +1219 -0
- core/web/routes/logs.py +374 -0
- core/web/routes/metrics.py +43 -0
- core/web/routes/observability.py +400 -0
- core/web/routes/patterns.py +227 -0
- core/web/routes/presence.py +609 -0
- core/web/routes/roles.py +446 -0
- core/web/routes/scheduled.py +261 -0
- core/web/routes/search.py +238 -0
- core/web/routes/sessions.py +220 -0
- core/web/routes/settings.py +363 -0
- core/web/routes/stream.py +547 -0
- core/web/security.py +157 -0
- core/web/server.py +283 -0
- graph_os/__init__.py +29 -0
- graph_os/backend.py +233 -0
- graph_os/backends/__init__.py +13 -0
- graph_os/backends/sqlite_backend.py +1053 -0
- graph_os/communities.py +410 -0
- graph_os/enterprise.py +218 -0
- graph_os/entry_points.py +226 -0
- graph_os/extractors/__init__.py +25 -0
- graph_os/extractors/code_generic.py +914 -0
- graph_os/extractors/code_go.py +1422 -0
- graph_os/extractors/code_json.py +340 -0
- graph_os/extractors/code_php.py +979 -0
- graph_os/extractors/code_python.py +1454 -0
- graph_os/extractors/code_shell.py +538 -0
- graph_os/extractors/code_toml.py +302 -0
- graph_os/extractors/code_ts.py +1665 -0
- graph_os/extractors/code_yaml.py +394 -0
- graph_os/extractors/contracts.py +1592 -0
- graph_os/extractors/md_links.py +890 -0
- graph_os/extractors/task_deps.py +345 -0
- graph_os/groups/__init__.py +22 -0
- graph_os/groups/cross_repo.py +156 -0
- graph_os/groups/manifest.py +141 -0
- graph_os/ingest/__init__.py +19 -0
- graph_os/ingest/base.py +306 -0
- graph_os/ingest/github.py +112 -0
- graph_os/ingest/zip.py +95 -0
- graph_os/toolchain.py +393 -0
- graph_os/tools/__init__.py +9 -0
- graph_os/tools/graph.py +5573 -0
- graph_os/tools/reindex_dispatch.py +730 -0
- graph_os/tree_sitter_overlay.py +235 -0
- graph_os/types.py +252 -0
- graph_os/vec_index.py +277 -0
- graph_os/viewer/__init__.py +12 -0
- graph_os/viewer/exporter.py +93 -0
- graph_os/viewer/template.py +189 -0
- scheduled/__init__.py +0 -0
- scheduled/_activity.py +126 -0
- scheduled/_state.py +113 -0
- scheduled/config.py +86 -0
- scheduled/dep_reconcile.py +135 -0
- scheduled/error_sweep.py +137 -0
- scheduled/nightly.py +930 -0
- scheduled/responsive_extract.py +65 -0
- scripts/__init__.py +4 -0
- scripts/_commit_msg_body.sh +31 -0
- scripts/_post_commit_body.sh +49 -0
- scripts/_pre_commit_body.sh +121 -0
- scripts/_prepare_commit_msg_body.sh +53 -0
- scripts/audit_mcp_tools.py +693 -0
- scripts/bench_sdk_dispatcher.py +177 -0
- scripts/capture_golden.py +169 -0
- scripts/check_graph_phantoms.py +75 -0
- scripts/dev/audit_doc_links.py +359 -0
- scripts/dev/audit_scaffold_module_tags.py +107 -0
- scripts/dev/backfill_doc_headers.py +328 -0
- scripts/dev/backfill_nav_lines.py +119 -0
- scripts/dev/fix_nav_placement.py +106 -0
- scripts/dev/inspect_sdk_options.py +45 -0
- scripts/dev/migrate_check_ids.py +170 -0
- scripts/dev/strip_purpose_blocks.py +154 -0
- scripts/dump_openapi.py +66 -0
- scripts/e2e_dispatch_tool.py +195 -0
- scripts/generate_manifest.py +166 -0
- scripts/golden_sections.py +20 -0
- scripts/graph_demo.py +161 -0
- scripts/install-git-hooks.sh +47 -0
- scripts/migrate_embeddings_minilm_to_bge_m3.py +84 -0
- scripts/operational_eval.py +445 -0
- scripts/probe_agent_session_resolver.py +59 -0
- scripts/prune_deleted_path.py +127 -0
- scripts/refactor_agent_dual_mode.py +171 -0
- scripts/refresh_skill_versions.py +302 -0
- scripts/regen_doc_index.py +209 -0
- scripts/regen_doctor_schema.py +62 -0
- scripts/regen_rules.py +94 -0
- scripts/rename_formulas_to_semantic.py +241 -0
- scripts/smoke_db_connections.py +183 -0
- scripts/smoke_doc_header.py +72 -0
- scripts/smoke_graph_e2e.py +374 -0
- scripts/smoke_sdk_dispatch.py +84 -0
- scripts/smoke_uid_resolver.py +164 -0
- scripts/verify_dispatchers.py +244 -0
- scripts/verify_phase_c_e2e.py +436 -0
- templates/__init__.py +6 -0
- templates/_base/Makefile.base +353 -0
- templates/_base/base.yaml +59 -0
- templates/_base/coding-os.yaml.template +39 -0
- templates/_base/dimension-registry.template.md +68 -0
- templates/_base/domain-config.template.json +46 -0
- templates/_base/fragments/anatomy-map.md.tmpl +11 -0
- templates/_base/fragments/context-discipline.md.tmpl +3 -0
- templates/_base/fragments/core-loop.md.tmpl +52 -0
- templates/_base/fragments/engineering-routing.md.tmpl +3 -0
- templates/_base/fragments/header.md.tmpl +6 -0
- templates/_base/fragments/identity.md.tmpl +3 -0
- templates/_base/fragments/principles.md.tmpl +3 -0
- templates/_base/fragments/retrieval-routing.md.tmpl +23 -0
- templates/_base/fragments/session-handoff.md.tmpl +3 -0
- templates/_base/fragments/skills.md.tmpl +3 -0
- templates/_base/fragments/ssot-map.md.tmpl +3 -0
- templates/_base/fragments/stop-conditions.md.tmpl +3 -0
- templates/_base/fragments/subagent-dispatch.md.tmpl +3 -0
- templates/_base/fragments/task-authoring.md.tmpl +69 -0
- templates/_base/fragments/task-logging.md.tmpl +8 -0
- templates/_base/fragments/tool-routing.md.tmpl +9 -0
- templates/_base/fragments/verification-matrix.md.tmpl +12 -0
- templates/_base/lang/dart/analysis_options.yaml +7 -0
- templates/_base/lang/php/phpcs.xml.dist +10 -0
- templates/_base/lang/python/pyproject.toml +19 -0
- templates/_base/lang/rust/clippy.toml +5 -0
- templates/_base/lang/rust/rustfmt.toml +3 -0
- templates/_base/lang/typescript/eslint.config.js +26 -0
- templates/_base/lang/typescript/tsconfig.json +15 -0
- templates/_base/lang/typescript/vitest.config.ts +10 -0
- templates/_base/scaffold/changes.log +1 -0
- templates/_base/scaffold/docs/00-index.md +55 -0
- templates/_base/scaffold/docs/_meta/feature-dependency-tree.md +30 -0
- templates/_base/scaffold/docs/_meta/foundation-map.md +56 -0
- templates/_base/scaffold/docs/_meta/questions.md +8 -0
- templates/_base/scaffold/docs/_meta/roadmap.md +33 -0
- templates/_base/scaffold/docs/api-contracts/00-index.md +58 -0
- templates/_base/scaffold/docs/api-contracts/error-format.md +58 -0
- templates/_base/scaffold/docs/architecture/00-index.md +42 -0
- templates/_base/scaffold/docs/architecture/adr/00-index.md +39 -0
- templates/_base/scaffold/docs/engineering/00-index.md +9 -0
- templates/_base/scaffold/docs/governance/00-index.md +55 -0
- templates/_base/scaffold/docs/governance/_templates/doc-cheat-sheet.md +202 -0
- templates/_base/scaffold/docs/governance/_templates/playbook-template.md +81 -0
- templates/_base/scaffold/docs/governance/_templates/post-mortem-template.md +85 -0
- templates/_base/scaffold/docs/governance/_templates/runbook-template.md +88 -0
- templates/_base/scaffold/docs/governance/_templates/security-review-template.md +111 -0
- templates/_base/scaffold/docs/governance/_templates/task-detail.md +61 -0
- templates/_base/scaffold/docs/governance/agent-workflow.md +101 -0
- templates/_base/scaffold/docs/governance/anatomy-contract.md +150 -0
- templates/_base/scaffold/docs/governance/critical-rules.md +224 -0
- templates/_base/scaffold/docs/governance/decision-records.md +58 -0
- templates/_base/scaffold/docs/governance/docs-first-protocol.md +157 -0
- templates/_base/scaffold/docs/governance/docs-system.md +151 -0
- templates/_base/scaffold/docs/governance/gdpr-compliance.md +66 -0
- templates/_base/scaffold/docs/governance/mcp-tool-inventory.md +112 -0
- templates/_base/scaffold/docs/governance/risk-register.md +26 -0
- templates/_base/scaffold/docs/governance/scaffold-boundary-contract.md +161 -0
- templates/_base/scaffold/docs/governance/task-lifecycle.md +125 -0
- templates/_base/scaffold/docs/governance/wrapper-derivation.md +50 -0
- templates/_base/scaffold/docs/insights/00-index.md +17 -0
- templates/_base/scaffold/docs/ops/00-index.md +59 -0
- templates/_base/scaffold/docs/ops/runbooks/00-index.md +9 -0
- templates/_base/scaffold/docs/playbooks/00-index.md +12 -0
- templates/_base/scaffold/docs/playbooks/research-validation.md +29 -0
- templates/_base/scaffold/docs/playbooks/security-review.md +41 -0
- templates/_base/scaffold/docs/prd/00-index.md +43 -0
- templates/_base/scaffold/docs/prd/01-snapshot-vision.md +56 -0
- templates/_base/scaffold/docs/workflow/workflow-guide.md +138 -0
- templates/_base/scaffold/src/shared/README.md +23 -0
- templates/_base/skill-enforcement.template.md +14 -0
- templates/_base/task-detail.template.md +61 -0
- templates/_presets/ai-saas.yaml +9 -0
- templates/_presets/django-next.yaml +8 -0
- templates/_presets/dotnet-react.yaml +8 -0
- templates/_presets/flutter-baas.yaml +8 -0
- templates/_presets/go-react.yaml +8 -0
- templates/_presets/hexagonal-product.yaml +16 -0
- templates/_presets/jamstack.yaml +8 -0
- templates/_presets/laravel-vue.yaml +8 -0
- templates/_presets/mean.yaml +8 -0
- templates/_presets/mern.yaml +9 -0
- templates/_presets/nest-angular.yaml +8 -0
- templates/_presets/nextjs-fastapi.yaml +10 -0
- templates/_presets/nuxt-fullstack.yaml +9 -0
- templates/_presets/pern.yaml +9 -0
- templates/_presets/rails-react.yaml +8 -0
- templates/_presets/rn-api.yaml +8 -0
- templates/_presets/rust-svelte.yaml +8 -0
- templates/_presets/spring-react.yaml +8 -0
- templates/_presets/t3-style.yaml +9 -0
- templates/_presets/tall.yaml +8 -0
- templates/_presets/wordpress-cms.yaml +8 -0
- templates/angular/rules/frontend.md +19 -0
- templates/angular/scaffold/docs/engineering/accessibility.md +46 -0
- templates/angular/scaffold/docs/engineering/angular-rules.md +35 -0
- templates/angular/scaffold/docs/playbooks/angular-app.md +42 -0
- templates/angular/scaffold/src/frontend/angular.json +52 -0
- templates/angular/scaffold/src/frontend/package.json +28 -0
- templates/angular/scaffold/src/frontend/src/app/app.component.ts +19 -0
- templates/angular/scaffold/src/frontend/src/app/app.config.ts +22 -0
- templates/angular/scaffold/src/frontend/src/app/app.routes.ts +8 -0
- templates/angular/scaffold/src/frontend/src/app/core/global-error-handler.ts +12 -0
- templates/angular/scaffold/src/frontend/src/app/health/health.component.ts +14 -0
- templates/angular/scaffold/src/frontend/src/app/health/health.service.spec.ts +16 -0
- templates/angular/scaffold/src/frontend/src/app/health/health.service.ts +10 -0
- templates/angular/scaffold/src/frontend/src/index.html +11 -0
- templates/angular/scaffold/src/frontend/src/main.ts +9 -0
- templates/angular/scaffold/src/frontend/src/styles.css +14 -0
- templates/angular/scaffold/src/frontend/tsconfig.app.json +8 -0
- templates/angular/scaffold/src/frontend/tsconfig.json +27 -0
- templates/angular/scaffold/src/frontend/tsconfig.spec.json +8 -0
- templates/angular/scaffold-boundary.yaml +27 -0
- templates/angular/skills/angular/SKILL.md +79 -0
- templates/angular/skills/angular/references/anatomy.md +69 -0
- templates/angular/stack.yaml +75 -0
- templates/aspnet-core/rules/backend.md +20 -0
- templates/aspnet-core/scaffold/docs/engineering/aspnet-core-rules.md +36 -0
- templates/aspnet-core/scaffold/docs/playbooks/aspnet-core-service.md +40 -0
- templates/aspnet-core/scaffold/src/backend/Backend.csproj +11 -0
- templates/aspnet-core/scaffold/src/backend/Backend.sln +27 -0
- templates/aspnet-core/scaffold/src/backend/Common/ExceptionHandlingMiddleware.cs +35 -0
- templates/aspnet-core/scaffold/src/backend/Features/Health/HealthEndpoints.cs +10 -0
- templates/aspnet-core/scaffold/src/backend/Features/Health/HealthService.cs +9 -0
- templates/aspnet-core/scaffold/src/backend/Program.cs +22 -0
- templates/aspnet-core/scaffold/src/backend/tests/Backend.Tests/Backend.Tests.csproj +22 -0
- templates/aspnet-core/scaffold/src/backend/tests/Backend.Tests/HealthServiceTests.cs +15 -0
- templates/aspnet-core/scaffold-boundary.yaml +24 -0
- templates/aspnet-core/skills/aspnet-core/SKILL.md +80 -0
- templates/aspnet-core/skills/aspnet-core/references/anatomy.md +65 -0
- templates/aspnet-core/stack.yaml +68 -0
- templates/astro/rules/frontend.md +20 -0
- templates/astro/scaffold/docs/engineering/astro-rules.md +40 -0
- templates/astro/scaffold/docs/playbooks/astro-app.md +57 -0
- templates/astro/scaffold/docs/playbooks/content-seo.md +37 -0
- templates/astro/scaffold/src/frontend/astro.config.mjs +10 -0
- templates/astro/scaffold/src/frontend/package.json +23 -0
- templates/astro/scaffold/src/frontend/src/components/Greeting.astro +13 -0
- templates/astro/scaffold/src/frontend/src/content/posts/hello.md +10 -0
- templates/astro/scaffold/src/frontend/src/content.config.ts +19 -0
- templates/astro/scaffold/src/frontend/src/lib/problem.test.ts +39 -0
- templates/astro/scaffold/src/frontend/src/lib/problem.ts +30 -0
- templates/astro/scaffold/src/frontend/src/pages/api/health.ts +13 -0
- templates/astro/scaffold/src/frontend/src/pages/index.astro +21 -0
- templates/astro/scaffold/src/frontend/tsconfig.json +9 -0
- templates/astro/scaffold/src/frontend/vitest.config.ts +10 -0
- templates/astro/scaffold-boundary.yaml +28 -0
- templates/astro/skills/astro/SKILL.md +71 -0
- templates/astro/skills/astro/references/anatomy.md +66 -0
- templates/astro/stack.yaml +75 -0
- templates/csharp-plain/scaffold/src/backend/Backend.csproj +12 -0
- templates/csharp-plain/scaffold/src/backend/Program.cs +1 -0
- templates/csharp-plain/scaffold-boundary.yaml +23 -0
- templates/csharp-plain/stack.yaml +50 -0
- templates/django/rules/backend.md +18 -0
- templates/django/scaffold/docs/engineering/anti-ambiguity.md +74 -0
- templates/django/scaffold/docs/engineering/backend-rules.md +133 -0
- templates/django/scaffold/docs/engineering/glossary.md +51 -0
- templates/django/scaffold/docs/engineering/logging-standards.md +107 -0
- templates/django/scaffold/docs/engineering/naming-conventions.md +68 -0
- templates/django/scaffold/docs/engineering/secrets-rotation-runbook.md +142 -0
- templates/django/scaffold/docs/playbooks/backend-api.md +119 -0
- templates/django/scaffold/src/backend/config/__init__.py +0 -0
- templates/django/scaffold/src/backend/config/settings.py +31 -0
- templates/django/scaffold/src/backend/config/urls.py +11 -0
- templates/django/scaffold/src/backend/config/wsgi.py +6 -0
- templates/django/scaffold/src/backend/manage.py +14 -0
- templates/django/scaffold/src/backend/pyproject.toml +37 -0
- templates/django/scaffold/src/backend/tests/test_health.py +4 -0
- templates/django/scaffold-boundary.yaml +25 -0
- templates/django/skills/python-django/SKILL.md +450 -0
- templates/django/skills/python-django/references/anatomy.md +117 -0
- templates/django/skills/python-django/scripts/new_endpoint.py +89 -0
- templates/django/stack.yaml +73 -0
- templates/fastapi/rules/backend.md +18 -0
- templates/fastapi/scaffold/docs/engineering/fastapi-rules.md +37 -0
- templates/fastapi/scaffold/docs/playbooks/fastapi-service.md +30 -0
- templates/fastapi/scaffold/src/backend/app/__init__.py +0 -0
- templates/fastapi/scaffold/src/backend/app/main.py +8 -0
- templates/fastapi/scaffold/src/backend/pyproject.toml +39 -0
- templates/fastapi/scaffold/src/backend/tests/test_health.py +11 -0
- templates/fastapi/scaffold-boundary.yaml +25 -0
- templates/fastapi/skills/python-fastapi/SKILL.md +75 -0
- templates/fastapi/skills/python-fastapi/references/anatomy.md +117 -0
- templates/fastapi/skills/python-fastapi/scripts/new_endpoint.py +101 -0
- templates/fastapi/stack.yaml +57 -0
- templates/flutter/rules/mobile.md +26 -0
- templates/flutter/scaffold/docs/engineering/flutter-rules.md +35 -0
- templates/flutter/scaffold/docs/playbooks/flutter-app.md +45 -0
- templates/flutter/scaffold/src/mobile/lib/core/error_mapper.dart +17 -0
- templates/flutter/scaffold/src/mobile/lib/core/router.dart +13 -0
- templates/flutter/scaffold/src/mobile/lib/main.dart +22 -0
- templates/flutter/scaffold/src/mobile/lib/screens/health_screen.dart +32 -0
- templates/flutter/scaffold/src/mobile/lib/services/health_service.dart +11 -0
- templates/flutter/scaffold/src/mobile/lib/state/health_provider.dart +13 -0
- templates/flutter/scaffold/src/mobile/pubspec.yaml +22 -0
- templates/flutter/scaffold/src/mobile/test/health_provider_test.dart +90 -0
- templates/flutter/scaffold-boundary.yaml +28 -0
- templates/flutter/skills/flutter/SKILL.md +76 -0
- templates/flutter/skills/flutter/references/anatomy.md +64 -0
- templates/flutter/stack.yaml +70 -0
- templates/go/rules/backend.md +19 -0
- templates/go/scaffold/docs/engineering/go-rules.md +45 -0
- templates/go/scaffold/docs/playbooks/go-service.md +30 -0
- templates/go/scaffold/src/backend/cmd/api/main.go +22 -0
- templates/go/scaffold/src/backend/cmd/api/main_test.go +20 -0
- templates/go/scaffold/src/backend/go.mod +3 -0
- templates/go/scaffold-boundary.yaml +25 -0
- templates/go/skills/go-patterns/SKILL.md +68 -0
- templates/go/skills/go-patterns/assets/go-checklist.md +29 -0
- templates/go/skills/go-patterns/references/anatomy.md +115 -0
- templates/go/skills/go-patterns/references/go-2026-idioms.md +92 -0
- templates/go/skills/go-patterns/scripts/new_endpoint.py +117 -0
- templates/go/skills/go-patterns/versions.json +16 -0
- templates/go/stack.yaml +54 -0
- templates/go-fiber/rules/backend.md +20 -0
- templates/go-fiber/scaffold/docs/engineering/fiber-rules.md +97 -0
- templates/go-fiber/scaffold/docs/playbooks/fiber-service.md +149 -0
- templates/go-fiber/scaffold/src/backend/cmd/api/main.go +21 -0
- templates/go-fiber/scaffold/src/backend/cmd/api/main_test.go +17 -0
- templates/go-fiber/scaffold/src/backend/go.mod +23 -0
- templates/go-fiber/scaffold/src/backend/go.sum +49 -0
- templates/go-fiber/scaffold-boundary.yaml +26 -0
- templates/go-fiber/skills/go-fiber/SKILL.md +203 -0
- templates/go-fiber/skills/go-fiber/assets/fiber-checklist.md +26 -0
- templates/go-fiber/skills/go-fiber/references/anatomy.md +116 -0
- templates/go-fiber/skills/go-fiber/references/fiber-v3-patterns.md +89 -0
- templates/go-fiber/skills/go-fiber/scripts/new_endpoint.py +107 -0
- templates/go-fiber/skills/go-fiber/versions.json +16 -0
- templates/go-fiber/stack.yaml +59 -0
- templates/go-plain/scaffold/src/backend/go.mod +3 -0
- templates/go-plain/scaffold/src/backend/main.go +7 -0
- templates/go-plain/scaffold-boundary.yaml +22 -0
- templates/go-plain/stack.yaml +51 -0
- templates/java-plain/scaffold/src/backend/mvnw +302 -0
- templates/java-plain/scaffold/src/backend/pom.xml +41 -0
- templates/java-plain/scaffold/src/backend/src/main/java/com/example/app/Main.java +10 -0
- templates/java-plain/scaffold-boundary.yaml +23 -0
- templates/java-plain/stack.yaml +51 -0
- templates/laravel/rules/backend.md +20 -0
- templates/laravel/scaffold/docs/engineering/laravel-rules.md +28 -0
- templates/laravel/scaffold/docs/playbooks/laravel-service.md +28 -0
- templates/laravel/scaffold/src/backend/app/Exceptions/Handler.php +27 -0
- templates/laravel/scaffold/src/backend/app/Http/Controllers/HealthController.php +15 -0
- templates/laravel/scaffold/src/backend/app/Support/HealthStatus.php +14 -0
- templates/laravel/scaffold/src/backend/composer.json +24 -0
- templates/laravel/scaffold/src/backend/phpunit.xml +10 -0
- templates/laravel/scaffold/src/backend/public/index.php +8 -0
- templates/laravel/scaffold/src/backend/routes/api.php +7 -0
- templates/laravel/scaffold/src/backend/tests/Unit/HealthStatusTest.php +16 -0
- templates/laravel/scaffold-boundary.yaml +23 -0
- templates/laravel/skills/laravel/SKILL.md +56 -0
- templates/laravel/skills/laravel/references/anatomy.md +65 -0
- templates/laravel/stack.yaml +66 -0
- templates/meta/rules/graph-first.md +27 -0
- templates/meta/rules/hook-author.md +19 -0
- templates/meta/rules/mcp-tool-author.md +18 -0
- templates/meta/rules/meta-engineering.md +17 -0
- templates/meta/scaffold-boundary.yaml +55 -0
- templates/meta/skills/claude-sdk-integration/SKILL.md +163 -0
- templates/meta/skills/claude-sdk-integration/assets/sdk-checklist.md +27 -0
- templates/meta/skills/claude-sdk-integration/scripts/check_model_ids.py +97 -0
- templates/meta/skills/graph-os-authoring/SKILL.md +278 -0
- templates/meta/skills/graph-os-authoring/assets/graph-os-checklist.md +25 -0
- templates/meta/skills/graph-os-authoring/scripts/new_extractor.py +76 -0
- templates/meta/skills/hook-authoring/SKILL.md +292 -0
- templates/meta/skills/hook-authoring/assets/hook-checklist.md +30 -0
- templates/meta/skills/hook-authoring/scripts/new_hook.sh +75 -0
- templates/meta/skills/mcp-tool-authoring/SKILL.md +301 -0
- templates/meta/skills/mcp-tool-authoring/assets/mcp-tool-checklist.md +29 -0
- templates/meta/skills/mcp-tool-authoring/scripts/new_tool.py +74 -0
- templates/meta/skills/meta-engineering/SKILL.md +151 -0
- templates/meta/skills/meta-engineering/assets/meta-edit-checklist.md +28 -0
- templates/meta/skills/meta-engineering/scripts/which_layer.py +61 -0
- templates/meta/skills/python-meta-server/SKILL.md +162 -0
- templates/meta/skills/python-meta-server/assets/meta-server-checklist.md +28 -0
- templates/meta/skills/python-meta-server/scripts/check_envelope.py +91 -0
- templates/meta/skills/react-vite-hub/SKILL.md +140 -0
- templates/meta/skills/react-vite-hub/assets/hub-ui-checklist.md +23 -0
- templates/meta/skills/react-vite-hub/scripts/check_vite_env.py +73 -0
- templates/meta/stack.yaml +119 -0
- templates/nestjs/rules/backend.md +20 -0
- templates/nestjs/scaffold/docs/engineering/nestjs-rules.md +33 -0
- templates/nestjs/scaffold/docs/playbooks/nestjs-service.md +39 -0
- templates/nestjs/scaffold/src/backend/nest-cli.json +5 -0
- templates/nestjs/scaffold/src/backend/package.json +28 -0
- templates/nestjs/scaffold/src/backend/src/app.module.ts +9 -0
- templates/nestjs/scaffold/src/backend/src/common/all-exceptions.filter.ts +59 -0
- templates/nestjs/scaffold/src/backend/src/health/health.controller.ts +14 -0
- templates/nestjs/scaffold/src/backend/src/health/health.module.ts +10 -0
- templates/nestjs/scaffold/src/backend/src/health/health.service.spec.ts +21 -0
- templates/nestjs/scaffold/src/backend/src/health/health.service.ts +9 -0
- templates/nestjs/scaffold/src/backend/src/main.ts +26 -0
- templates/nestjs/scaffold/src/backend/tsconfig.json +16 -0
- templates/nestjs/scaffold/src/backend/vitest.config.ts +9 -0
- templates/nestjs/scaffold-boundary.yaml +25 -0
- templates/nestjs/skills/nestjs/SKILL.md +67 -0
- templates/nestjs/skills/nestjs/references/anatomy.md +65 -0
- templates/nestjs/stack.yaml +68 -0
- templates/nextjs/rules/frontend.md +18 -0
- templates/nextjs/scaffold/docs/design/00-index.md +23 -0
- templates/nextjs/scaffold/docs/design/colors-tokens.md +141 -0
- templates/nextjs/scaffold/docs/design/components-patterns.md +159 -0
- templates/nextjs/scaffold/docs/design/motion-accessibility.md +137 -0
- templates/nextjs/scaffold/docs/design/typography-spacing.md +107 -0
- templates/nextjs/scaffold/docs/engineering/accessibility-web.md +56 -0
- templates/nextjs/scaffold/docs/engineering/copywriting-standard.md +102 -0
- templates/nextjs/scaffold/docs/engineering/formatting-rules.md +89 -0
- templates/nextjs/scaffold/docs/engineering/frontend-rendering-rules.md +80 -0
- templates/nextjs/scaffold/docs/engineering/frontend-rules.md +183 -0
- templates/nextjs/scaffold/docs/engineering/i18n-policy.md +99 -0
- templates/nextjs/scaffold/docs/pages-content-spec/00-index.md +78 -0
- templates/nextjs/scaffold/docs/playbooks/content-seo.md +55 -0
- templates/nextjs/scaffold/docs/playbooks/docs-governance.md +51 -0
- templates/nextjs/scaffold/docs/playbooks/frontend-ui.md +63 -0
- templates/nextjs/scaffold/src/frontend/app/layout.tsx +14 -0
- templates/nextjs/scaffold/src/frontend/app/page.tsx +3 -0
- templates/nextjs/scaffold/src/frontend/eslint.config.js +17 -0
- templates/nextjs/scaffold/src/frontend/lib/greeting.test.ts +9 -0
- templates/nextjs/scaffold/src/frontend/lib/greeting.ts +3 -0
- templates/nextjs/scaffold/src/frontend/package.json +28 -0
- templates/nextjs/scaffold/src/frontend/tsconfig.json +18 -0
- templates/nextjs/scaffold/src/frontend/vitest.config.ts +10 -0
- templates/nextjs/scaffold-boundary.yaml +30 -0
- templates/nextjs/skills/nextjs-react/SKILL.md +485 -0
- templates/nextjs/skills/nextjs-react/references/anatomy.md +116 -0
- templates/nextjs/skills/nextjs-react/scripts/new_component.py +72 -0
- templates/nextjs/stack.yaml +81 -0
- templates/node-express/rules/backend.md +20 -0
- templates/node-express/scaffold/docs/engineering/express-rules.md +30 -0
- templates/node-express/scaffold/docs/playbooks/express-service.md +35 -0
- templates/node-express/scaffold/src/backend/package.json +24 -0
- templates/node-express/scaffold/src/backend/src/index.ts +17 -0
- templates/node-express/scaffold/src/backend/src/middleware/error-handler.ts +12 -0
- templates/node-express/scaffold/src/backend/src/routes/health.test.ts +33 -0
- templates/node-express/scaffold/src/backend/src/routes/health.ts +7 -0
- templates/node-express/scaffold/src/backend/tsconfig.json +15 -0
- templates/node-express/scaffold/src/backend/types/express-bootstrap.d.ts +21 -0
- templates/node-express/scaffold-boundary.yaml +25 -0
- templates/node-express/skills/node-express/SKILL.md +70 -0
- templates/node-express/skills/node-express/references/anatomy.md +63 -0
- templates/node-express/stack.yaml +63 -0
- templates/python/scaffold/docs/engineering/python-rules.md +27 -0
- templates/python/scaffold/docs/playbooks/python-library.md +35 -0
- templates/python/stack.yaml +60 -0
- templates/rails/rules/backend.md +10 -0
- templates/rails/scaffold/docs/engineering/rails-rules.md +33 -0
- templates/rails/scaffold/docs/playbooks/rails-service.md +42 -0
- templates/rails/scaffold/src/backend/Gemfile +12 -0
- templates/rails/scaffold/src/backend/app/controllers/application_controller.rb +26 -0
- templates/rails/scaffold/src/backend/app/controllers/health_controller.rb +6 -0
- templates/rails/scaffold/src/backend/app/models/health.rb +6 -0
- templates/rails/scaffold/src/backend/config/application.rb +12 -0
- templates/rails/scaffold/src/backend/config/boot.rb +3 -0
- templates/rails/scaffold/src/backend/config/routes.rb +4 -0
- templates/rails/scaffold/src/backend/config.ru +5 -0
- templates/rails/scaffold/src/backend/spec/rails_helper.rb +18 -0
- templates/rails/scaffold/src/backend/spec/requests/health_spec.rb +24 -0
- templates/rails/scaffold-boundary.yaml +25 -0
- templates/rails/skills/rails/SKILL.md +62 -0
- templates/rails/skills/rails/references/anatomy.md +71 -0
- templates/rails/stack.yaml +72 -0
- templates/react-native/rules/mobile.md +26 -0
- templates/react-native/scaffold/docs/engineering/accessibility-mobile.md +95 -0
- templates/react-native/scaffold/docs/engineering/mobile-rules.md +56 -0
- templates/react-native/scaffold/docs/engineering/offline-first.md +61 -0
- templates/react-native/scaffold/docs/playbooks/mobile-app.md +49 -0
- templates/react-native/scaffold/src/mobile/App.tsx +9 -0
- templates/react-native/scaffold/src/mobile/eslint.config.js +17 -0
- templates/react-native/scaffold/src/mobile/package.json +23 -0
- templates/react-native/scaffold/src/mobile/src/greeting.test.ts +9 -0
- templates/react-native/scaffold/src/mobile/src/greeting.ts +3 -0
- templates/react-native/scaffold/src/mobile/tsconfig.json +17 -0
- templates/react-native/scaffold/src/mobile/vitest.config.ts +10 -0
- templates/react-native/scaffold-boundary.yaml +30 -0
- templates/react-native/skills/react-native-mobile/SKILL.md +119 -0
- templates/react-native/skills/react-native-mobile/assets/rn-mobile-checklist.md +28 -0
- templates/react-native/skills/react-native-mobile/references/anatomy.md +140 -0
- templates/react-native/skills/react-native-mobile/references/rn-2026-practices.md +54 -0
- templates/react-native/skills/react-native-mobile/scripts/new_screen.py +73 -0
- templates/react-native/skills/react-native-mobile/versions.json +16 -0
- templates/react-native/skills/react-native-patterns/SKILL.md +512 -0
- templates/react-native/skills/react-native-patterns/assets/rn-review-checklist.md +26 -0
- templates/react-native/skills/react-native-patterns/references/anatomy.md +62 -0
- templates/react-native/skills/react-native-patterns/references/list-performance.md +70 -0
- templates/react-native/skills/react-native-patterns/scripts/scan_rn_perf.py +77 -0
- templates/react-native/stack.yaml +70 -0
- templates/ruby-plain/scaffold/src/backend/Gemfile +8 -0
- templates/ruby-plain/scaffold/src/backend/main.rb +3 -0
- templates/ruby-plain/scaffold-boundary.yaml +23 -0
- templates/ruby-plain/stack.yaml +50 -0
- templates/rust-axum/rules/backend.md +20 -0
- templates/rust-axum/scaffold/docs/engineering/rust-axum-rules.md +35 -0
- templates/rust-axum/scaffold/docs/playbooks/rust-axum-service.md +43 -0
- templates/rust-axum/scaffold/src/backend/Cargo.toml +20 -0
- templates/rust-axum/scaffold/src/backend/src/app.rs +12 -0
- templates/rust-axum/scaffold/src/backend/src/error.rs +48 -0
- templates/rust-axum/scaffold/src/backend/src/main.rs +24 -0
- templates/rust-axum/scaffold/src/backend/src/routes/health.rs +37 -0
- templates/rust-axum/scaffold/src/backend/src/routes/mod.rs +2 -0
- templates/rust-axum/scaffold-boundary.yaml +25 -0
- templates/rust-axum/skills/rust/SKILL.md +73 -0
- templates/rust-axum/skills/rust/references/anatomy.md +63 -0
- templates/rust-axum/stack.yaml +65 -0
- templates/rust-plain/scaffold/src/backend/Cargo.toml +6 -0
- templates/rust-plain/scaffold/src/backend/src/main.rs +3 -0
- templates/rust-plain/scaffold-boundary.yaml +23 -0
- templates/rust-plain/stack.yaml +51 -0
- templates/spring-boot/rules/backend.md +20 -0
- templates/spring-boot/scaffold/docs/engineering/spring-boot-rules.md +35 -0
- templates/spring-boot/scaffold/docs/playbooks/spring-boot-service.md +45 -0
- templates/spring-boot/scaffold/src/backend/mvnw +302 -0
- templates/spring-boot/scaffold/src/backend/pom.xml +69 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/Application.java +16 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/common/GlobalExceptionHandler.java +31 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/health/HealthController.java +22 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/health/HealthService.java +12 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/health/HealthStatus.java +4 -0
- templates/spring-boot/scaffold/src/backend/src/test/java/com/example/app/health/HealthServiceTest.java +15 -0
- templates/spring-boot/scaffold-boundary.yaml +26 -0
- templates/spring-boot/skills/spring-boot/SKILL.md +84 -0
- templates/spring-boot/skills/spring-boot/references/anatomy.md +63 -0
- templates/spring-boot/stack.yaml +65 -0
- templates/svelte-sveltekit/rules/frontend.md +20 -0
- templates/svelte-sveltekit/scaffold/docs/engineering/svelte-sveltekit-rules.md +37 -0
- templates/svelte-sveltekit/scaffold/docs/playbooks/svelte-sveltekit-app.md +36 -0
- templates/svelte-sveltekit/scaffold/src/frontend/package.json +22 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/app.html +12 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/hooks.server.ts +14 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/lib/components/Greeting.svelte +6 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/lib/stores/count.test.ts +26 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/lib/stores/count.ts +4 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/+layout.svelte +24 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/+page.svelte +9 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/+page.ts +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/health/+server.ts +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/svelte.config.js +10 -0
- templates/svelte-sveltekit/scaffold/src/frontend/tsconfig.json +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/vite.config.ts +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/vitest.config.ts +11 -0
- templates/svelte-sveltekit/scaffold-boundary.yaml +29 -0
- templates/svelte-sveltekit/skills/svelte/SKILL.md +90 -0
- templates/svelte-sveltekit/skills/svelte/references/anatomy.md +62 -0
- templates/svelte-sveltekit/stack.yaml +70 -0
- templates/typescript-plain/scaffold/src/index.ts +3 -0
- templates/typescript-plain/scaffold/tsconfig.json +13 -0
- templates/typescript-plain/scaffold-boundary.yaml +22 -0
- templates/typescript-plain/stack.yaml +44 -0
- templates/vue-nuxt/rules/frontend.md +19 -0
- templates/vue-nuxt/scaffold/docs/engineering/nuxt-rules.md +30 -0
- templates/vue-nuxt/scaffold/docs/playbooks/nuxt-app.md +29 -0
- templates/vue-nuxt/scaffold/src/frontend/app.vue +3 -0
- templates/vue-nuxt/scaffold/src/frontend/nuxt.config.ts +11 -0
- templates/vue-nuxt/scaffold/src/frontend/package.json +20 -0
- templates/vue-nuxt/scaffold/src/frontend/pages/index.test.ts +19 -0
- templates/vue-nuxt/scaffold/src/frontend/pages/index.vue +11 -0
- templates/vue-nuxt/scaffold/src/frontend/vitest.config.ts +12 -0
- templates/vue-nuxt/scaffold-boundary.yaml +26 -0
- templates/vue-nuxt/skills/vue-nuxt/SKILL.md +57 -0
- templates/vue-nuxt/skills/vue-nuxt/references/anatomy.md +60 -0
- templates/vue-nuxt/stack.yaml +61 -0
- templates/wordpress/rules/backend.md +19 -0
- templates/wordpress/scaffold/docs/engineering/wordpress-rules.md +28 -0
- templates/wordpress/scaffold/docs/playbooks/wordpress-service.md +29 -0
- templates/wordpress/scaffold/src/backend/composer.json +17 -0
- templates/wordpress/scaffold/src/backend/phpcs.xml.dist +11 -0
- templates/wordpress/scaffold/src/backend/phpunit.xml +10 -0
- templates/wordpress/scaffold/src/backend/plugin/inc/health.php +8 -0
- templates/wordpress/scaffold/src/backend/plugin/plugin.php +28 -0
- templates/wordpress/scaffold/src/backend/tests/HealthStatusTest.php +15 -0
- templates/wordpress/scaffold/src/backend/theme/functions.php +18 -0
- templates/wordpress/scaffold/src/backend/theme/style.css +11 -0
- templates/wordpress/scaffold-boundary.yaml +23 -0
- templates/wordpress/skills/wordpress/SKILL.md +110 -0
- templates/wordpress/skills/wordpress/assets/wp-checklist.md +28 -0
- templates/wordpress/skills/wordpress/references/wp-development.md +75 -0
- templates/wordpress/skills/wordpress/references/wp-security.md +68 -0
- templates/wordpress/skills/wordpress/scripts/scan_wp_smells.py +91 -0
- templates/wordpress/skills/wordpress/versions.json +16 -0
- templates/wordpress/stack.yaml +60 -0
- thinking_os/__init__.py +1 -0
- thinking_os/_agent_markers.py +32 -0
- thinking_os/background.py +405 -0
- thinking_os/bootstrap_outcomes.py +200 -0
- thinking_os/budget.py +302 -0
- thinking_os/capture.py +495 -0
- thinking_os/cognition.py +516 -0
- thinking_os/cognition_schemas.py +517 -0
- thinking_os/compress.py +192 -0
- thinking_os/concepts.py +233 -0
- thinking_os/dashboard.py +159 -0
- thinking_os/database.py +2883 -0
- thinking_os/decay.py +393 -0
- thinking_os/digest.py +295 -0
- thinking_os/dispatcher.py +192 -0
- thinking_os/dispatcher_helpers.py +48 -0
- thinking_os/dispatchers/__init__.py +3 -0
- thinking_os/dispatchers/default.py +47 -0
- thinking_os/distill.py +192 -0
- thinking_os/doc_indexer.py +905 -0
- thinking_os/embeddings.py +943 -0
- thinking_os/formula_composer.py +556 -0
- thinking_os/gate_marker.py +75 -0
- thinking_os/graph.py +296 -0
- thinking_os/graph_indexer.py +360 -0
- thinking_os/health_check.py +517 -0
- thinking_os/impact.py +119 -0
- thinking_os/memory_gc.py +356 -0
- thinking_os/migrator_embeddings.py +318 -0
- thinking_os/precision.py +194 -0
- thinking_os/record_outcome.py +399 -0
- thinking_os/repair.py +105 -0
- thinking_os/retrieval_quality.py +239 -0
- thinking_os/roles_state.py +168 -0
- thinking_os/sanitizer.py +320 -0
- thinking_os/server.py +3160 -0
- thinking_os/session_enrich.py +272 -0
- thinking_os/session_observe_worker.py +111 -0
- thinking_os/session_startup.py +74 -0
- thinking_os/session_summary.py +245 -0
- thinking_os/task_analyzer.py +462 -0
- thinking_os/task_parser.py +342 -0
- thinking_os/task_sync.py +73 -0
- thinking_os/tools/__init__.py +6 -0
- thinking_os/tools/_shared.py +947 -0
- thinking_os/tools/cognition.py +1867 -0
- thinking_os/tools/docs.py +770 -0
- thinking_os/tools/learning.py +2078 -0
- thinking_os/tools/logs.py +79 -0
- thinking_os/tools/memory.py +840 -0
- thinking_os/tools/metrics.py +200 -0
- thinking_os/tools/retrieve.py +415 -0
- thinking_os/tools/routing.py +658 -0
- thinking_os/tools/tasks.py +449 -0
- thinking_os/tools/trajectory.py +181 -0
- thinking_os/tracing.py +235 -0
- web/__init__.py +5 -0
- web/_cache.py +118 -0
- web/_deps.py +56 -0
- web/_envelope.py +85 -0
- web/_project_context.py +140 -0
- web/chat_providers.py +108 -0
- web/init_jobs.py +216 -0
- web/routes/__init__.py +25 -0
- web/routes/_bounded_read.py +76 -0
- web/routes/board.py +1089 -0
- web/routes/cognition.py +1838 -0
- web/routes/config.py +635 -0
- web/routes/graph.py +513 -0
- web/routes/health.py +180 -0
- web/routes/hooks.py +288 -0
- web/routes/hub.py +1219 -0
- web/routes/logs.py +374 -0
- web/routes/metrics.py +43 -0
- web/routes/observability.py +400 -0
- web/routes/patterns.py +227 -0
- web/routes/presence.py +609 -0
- web/routes/roles.py +446 -0
- web/routes/scheduled.py +261 -0
- web/routes/search.py +238 -0
- web/routes/sessions.py +220 -0
- web/routes/settings.py +363 -0
- web/routes/stream.py +547 -0
- web/security.py +157 -0
- web/server.py +283 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Block known anti-patterns in code being written.
|
|
3
|
+
# Source: docs/engineering/backend-rules.md, docs/engineering/frontend-rules.md
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
7
|
+
|
|
8
|
+
# Fail-closed: an anti-pattern gate that cannot read its input must DENY,
|
|
9
|
+
# not silently allow when jq is absent (observability-eye I8). cos_json_field
|
|
10
|
+
# falls back to python3, so the gate keeps working when only jq is missing.
|
|
11
|
+
cos_require_parser block-bad-patterns
|
|
12
|
+
|
|
13
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
14
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
15
|
+
|
|
16
|
+
if [[ "$TOOL" != "Write" && "$TOOL" != "Edit" ]]; then
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
FILE_PATH=$(printf '%s' "$INPUT" | cos_json_field tool_input.file_path)
|
|
21
|
+
CONTENT=$(printf '%s' "$INPUT" | cos_json_field tool_input.new_string tool_input.content)
|
|
22
|
+
|
|
23
|
+
# === SHELL HOOK / INSTALLER GUARD (bash 5.3.9 deadlock) ===
|
|
24
|
+
# Homebrew bash 5.3.9 sporadically deadlocks `cmd - <<HEREDOC` patterns
|
|
25
|
+
# in heredoc_write before forking the child. Hot-path hooks accumulate
|
|
26
|
+
# zombie bashes that eventually starve the agent runtime's auxiliary
|
|
27
|
+
# subprocess spawns ("Subprocess initialization did not complete within
|
|
28
|
+
# 60000ms"). install.sh hangs at the first heredoc that hits the bug.
|
|
29
|
+
#
|
|
30
|
+
# Safe replacements (verified zero-zombie under stress):
|
|
31
|
+
# A) python3 -c "$(cat <<'PY' ... PY)" arg1 arg2 ← cat captures heredoc;
|
|
32
|
+
# python3 receives -c <string> as argument. No stdin pipe.
|
|
33
|
+
# B) python3 path/to/helper.py arg1 arg2 ← extracted helper.
|
|
34
|
+
#
|
|
35
|
+
# Past incidents: agent-presence zombie pile-up (2026-04-25 morning),
|
|
36
|
+
# install.sh hang on `Re-linked stack skills` (2026-04-26).
|
|
37
|
+
# Forensics: docs/engineering/bash-heredoc-deadlock.md.
|
|
38
|
+
if [[ "$FILE_PATH" == *.sh ]] && [[
|
|
39
|
+
"$FILE_PATH" == *core/hooks/* ||
|
|
40
|
+
"$FILE_PATH" == *adapters/*/install* ||
|
|
41
|
+
"$FILE_PATH" == *adapters/*/hooks/* ||
|
|
42
|
+
"$FILE_PATH" == *.claude/hooks/* ||
|
|
43
|
+
"$FILE_PATH" == *.codex/hooks/* ]]; then
|
|
44
|
+
# Strip shell comment lines before scanning so docs that *describe* the
|
|
45
|
+
# dangerous pattern (e.g. session-context.sh line 159 warns about the
|
|
46
|
+
# heredoc-write deadlock) do not trip the regex.
|
|
47
|
+
CODE_ONLY=$(echo "$CONTENT" | grep -vE '^[[:space:]]*#')
|
|
48
|
+
|
|
49
|
+
if echo "$CODE_ONLY" | grep -qE 'python3? +- +.*<<'; then
|
|
50
|
+
echo "BLOCKED: \`cmd - <<HEREDOC\` pattern detected — bash 5.3.9 sporadically" >&2
|
|
51
|
+
echo " deadlocks this in heredoc_write before fork. Hot-path hooks +" >&2
|
|
52
|
+
echo " installer scripts that fire it accumulate zombies and starve" >&2
|
|
53
|
+
echo " agent runtime spawns. See docs/engineering/bash-heredoc-deadlock.md." >&2
|
|
54
|
+
echo "" >&2
|
|
55
|
+
echo " Safe replacement: separate .py file invoked as" >&2
|
|
56
|
+
echo " python3 \$(dirname \"\$0\")/_helpers/<name>.py arg1 arg2" >&2
|
|
57
|
+
exit 2
|
|
58
|
+
fi
|
|
59
|
+
# Detect form A nested inside command substitution (sample(1) shows the
|
|
60
|
+
# hang at expand_word_internal -> command_substitute -> wait_for).
|
|
61
|
+
# See docs/engineering/bash-heredoc-deadlock.md for the full forensics.
|
|
62
|
+
if echo "$CODE_ONLY" | grep -qE '\$\(.*python3? +-c +.*\$\(cat +<<'; then
|
|
63
|
+
echo "BLOCKED: nested heredoc-in-\$(...) detected — bash 5.3.9 sporadically" >&2
|
|
64
|
+
echo " deadlocks even \`python3 -c \"\$(cat <<'PY'...)\"\` when wrapped" >&2
|
|
65
|
+
echo " inside another \$(...). install.sh hung on this 2026-04-26." >&2
|
|
66
|
+
echo "" >&2
|
|
67
|
+
echo " Safe replacement: separate .py file" >&2
|
|
68
|
+
echo " VAR=\$(python3 \"\$HELPER_DIR/extract.py\" \"\$arg1\")" >&2
|
|
69
|
+
echo " See docs/engineering/bash-heredoc-deadlock.md for forensics." >&2
|
|
70
|
+
exit 2
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Skip non-code files and migration files
|
|
75
|
+
if [[ "$FILE_PATH" != *.py ]] && [[ "$FILE_PATH" != *.ts ]] && [[ "$FILE_PATH" != *.tsx ]] && [[ "$FILE_PATH" != *.js ]]; then
|
|
76
|
+
exit 0
|
|
77
|
+
fi
|
|
78
|
+
if [[ "$FILE_PATH" == *__pycache__* ]] || [[ "$FILE_PATH" == *node_modules* ]]; then
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# Migration-specific rules (before skipping migrations for general rules)
|
|
83
|
+
if [[ "$FILE_PATH" == *migrations* ]] && [[ "$FILE_PATH" == *.py ]]; then
|
|
84
|
+
# Block RunPython without reverse_code
|
|
85
|
+
# Source: backend-rules.md § Migration Rules
|
|
86
|
+
if echo "$CONTENT" | grep -qE 'RunPython\(' && ! echo "$CONTENT" | grep -qE 'reverse_code'; then
|
|
87
|
+
echo "BLOCKED: RunPython migration must include reverse_code for rollback safety. See docs/engineering/backend-rules.md § Migration Rules." >&2
|
|
88
|
+
exit 2
|
|
89
|
+
fi
|
|
90
|
+
# Migrations pass all other checks
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# === UNIVERSAL RULES ===
|
|
95
|
+
|
|
96
|
+
# A committed TODO is untracked work — prefer `cos task-create` over a marker. This
|
|
97
|
+
# blocks a bare marker; a task-ref only makes a transient mid-dev marker trackable
|
|
98
|
+
# (remove before commit) — it is NOT comment provenance, which clean-code §4 forbids
|
|
99
|
+
# in explanatory comments. Skip: tests + templates/*/skills/*/scripts/ placeholders.
|
|
100
|
+
if [[ "$FILE_PATH" != *test* ]] && [[ "$FILE_PATH" != *spec* ]] \
|
|
101
|
+
&& [[ "$FILE_PATH" != *templates/*/skills/*/scripts/* ]]; then
|
|
102
|
+
# Check if TODO exists but TASK-### does NOT exist in the same content
|
|
103
|
+
if echo "$CONTENT" | grep -qiE '(//|#)\s*TODO' && ! echo "$CONTENT" | grep -qE 'TASK-[0-9]{3}'; then
|
|
104
|
+
echo "BLOCKED: bare TODO in committed code. Prefer 'cos task-create' over a marker; if a transient mid-dev marker is unavoidable make it trackable as 'TODO(TASK-###)' and remove before commit — a task-ref is a TODO-tracker, never provenance in an explanatory comment (clean-code §4 / Rule 12)." >&2
|
|
105
|
+
exit 2
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# === BACKEND RULES ===
|
|
110
|
+
if [[ "$FILE_PATH" == *.py ]]; then
|
|
111
|
+
|
|
112
|
+
# Skip test files for backend-specific rules (tests may legitimately use print, pass, etc.)
|
|
113
|
+
if [[ "$FILE_PATH" == *test* ]]; then
|
|
114
|
+
exit 0
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# Block except-pass where pass is the ONLY handler (no logging, no re-raise)
|
|
118
|
+
# Source: backend-rules.md § Error Handling Policy
|
|
119
|
+
if echo "$CONTENT" | grep -qE 'except' && echo "$CONTENT" | grep -qE '^\s*pass\s*$'; then
|
|
120
|
+
# Only block if there's no logging in the same content (indicating bare except:pass)
|
|
121
|
+
if ! echo "$CONTENT" | grep -qE 'logger\.|logging\.|raise '; then
|
|
122
|
+
echo "BLOCKED: Bare 'except: pass' swallows errors silently. Log the error or re-raise. See docs/engineering/backend-rules.md § Error Handling Policy." >&2
|
|
123
|
+
exit 2
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Block print() in production backend code (use logger instead)
|
|
128
|
+
# Source: backend-rules.md § Observability
|
|
129
|
+
if [[ "$FILE_PATH" == *backend/apps/* ]]; then
|
|
130
|
+
if echo "$CONTENT" | grep -qE '^\s*print\('; then
|
|
131
|
+
echo "BLOCKED: Use 'import logging; logger = logging.getLogger(__name__); logger.info(...)' instead of print() in backend code. See docs/engineering/backend-rules.md." >&2
|
|
132
|
+
exit 2
|
|
133
|
+
fi
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# Block .save()/.delete() in views (views should be thin, use services)
|
|
137
|
+
# Source: backend-rules.md § Core Rules
|
|
138
|
+
if [[ "$FILE_PATH" == *views* ]] || [[ "$FILE_PATH" == *viewsets* ]]; then
|
|
139
|
+
if echo "$CONTENT" | grep -qE '\.(save|delete)\(\)'; then
|
|
140
|
+
echo "BLOCKED: Views must be thin — do not call .save() or .delete() in views. Move business logic to a service function. See docs/engineering/backend-rules.md § Core Rules." >&2
|
|
141
|
+
exit 2
|
|
142
|
+
fi
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Block ORM queries in views (use selectors instead)
|
|
146
|
+
# Source: backend-rules.md § Core Rules
|
|
147
|
+
if [[ "$FILE_PATH" == *views* ]] || [[ "$FILE_PATH" == *viewsets* ]]; then
|
|
148
|
+
if echo "$CONTENT" | grep -qE '\.objects\.(filter|get|exclude|annotate|aggregate|create|update|bulk)'; then
|
|
149
|
+
echo "BLOCKED: Do not query ORM directly in views. Use a selector function from selectors.py. See docs/engineering/backend-rules.md § Core Rules." >&2
|
|
150
|
+
exit 2
|
|
151
|
+
fi
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Block bare raise ValueError/Exception in service layer (use typed domain exceptions)
|
|
155
|
+
# Source: backend-rules.md § Error Handling Policy
|
|
156
|
+
if [[ "$FILE_PATH" == *services* ]]; then
|
|
157
|
+
if echo "$CONTENT" | grep -qE 'raise\s+(ValueError|Exception|RuntimeError)\('; then
|
|
158
|
+
echo "BLOCKED: Do not raise bare ValueError/Exception in services. Define a typed exception in apps/<domain>/exceptions.py inheriting APIException. See docs/engineering/backend-rules.md § Error Handling Policy." >&2
|
|
159
|
+
exit 2
|
|
160
|
+
fi
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# === FRONTEND RULES ===
|
|
166
|
+
if [[ "$FILE_PATH" == *.ts ]] || [[ "$FILE_PATH" == *.tsx ]] || [[ "$FILE_PATH" == *.js ]]; then
|
|
167
|
+
|
|
168
|
+
# Skip test/spec files
|
|
169
|
+
if [[ "$FILE_PATH" == *test* ]] || [[ "$FILE_PATH" == *spec* ]] || [[ "$FILE_PATH" == *__tests__* ]]; then
|
|
170
|
+
exit 0
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
# Block console.log in production frontend code (allow console.error/warn)
|
|
174
|
+
# Source: frontend-rules.md § Code Style
|
|
175
|
+
if [[ "$FILE_PATH" == *frontend/src/* ]]; then
|
|
176
|
+
if echo "$CONTENT" | grep -qE 'console\.log\('; then
|
|
177
|
+
echo "BLOCKED: Remove console.log() from production code. Use console.error() for real errors only. See docs/engineering/frontend-rules.md." >&2
|
|
178
|
+
exit 2
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# Block 'any' type in TypeScript (use proper types)
|
|
183
|
+
# Source: frontend-rules.md § Non-Negotiables
|
|
184
|
+
# Honors the standard `// eslint-disable-next-line @typescript-eslint/no-explicit-any`
|
|
185
|
+
# escape hatch so lines explicitly marked safe (e.g. third-party generics
|
|
186
|
+
# with overly strict types) do not trip the gate. Without this exemption
|
|
187
|
+
# the hook fires on every commit touching the file even when the diff
|
|
188
|
+
# does not introduce new `any` usage.
|
|
189
|
+
if [[ "$FILE_PATH" == *.ts ]] || [[ "$FILE_PATH" == *.tsx ]]; then
|
|
190
|
+
if echo "$CONTENT" | awk '
|
|
191
|
+
/eslint-disable-next-line.*no-explicit-any/ { skip=1; next }
|
|
192
|
+
skip { skip=0; next }
|
|
193
|
+
/:[[:space:]]*any($|[^[:alnum:]_])|<any>|(^|[^[:alnum:]_])as[[:space:]]+any($|[^[:alnum:]_])|,[[:space:]]*any($|[^[:alnum:]_])|\|[[:space:]]*any($|[^[:alnum:]_])/ { found=1; exit }
|
|
194
|
+
END { exit !found }
|
|
195
|
+
'; then
|
|
196
|
+
echo "BLOCKED: Do not use 'any' type. Define a proper TypeScript type or interface. See docs/engineering/frontend-rules.md § Non-Negotiables." >&2
|
|
197
|
+
echo " Hint: prefix the line with: // eslint-disable-next-line @typescript-eslint/no-explicit-any" >&2
|
|
198
|
+
exit 2
|
|
199
|
+
fi
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# Block non-NEXT_PUBLIC_ env vars in frontend client code (backend secret leak)
|
|
203
|
+
# Source: frontend-rules.md § Mandatory Engineering Rules
|
|
204
|
+
if [[ "$FILE_PATH" == *frontend/* ]]; then
|
|
205
|
+
if echo "$CONTENT" | grep -qE 'process\.env\.(STRIPE_SECRET|DATABASE_URL|DJANGO_SECRET|POSTMARK_SERVER_TOKEN|SECRET_KEY)'; then
|
|
206
|
+
echo "BLOCKED: Backend secret detected in frontend code. Only NEXT_PUBLIC_* variables are safe for the browser. See docs/engineering/frontend-rules.md § Mandatory Engineering Rules." >&2
|
|
207
|
+
exit 2
|
|
208
|
+
fi
|
|
209
|
+
fi
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
exit 0
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Block dangerous bash commands that could cause data loss.
|
|
3
|
+
# Source: AGENTS.md § Principles (P5), git safety
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
7
|
+
if ! command -v cos_log_hook >/dev/null 2>&1; then cos_log_hook() { :; }; fi
|
|
8
|
+
|
|
9
|
+
# Resolve a _helpers/<name> path through THIS hook's symlink chain — the
|
|
10
|
+
# .claude/.codex symlink points at the .sh only, not the _helpers/ tree, so a
|
|
11
|
+
# $(dirname "$0")-relative path misses. Echoes the absolute helper path.
|
|
12
|
+
_resolve_helper() {
|
|
13
|
+
local src="${BASH_SOURCE[0]}" dir
|
|
14
|
+
while [ -L "$src" ]; do
|
|
15
|
+
dir="$(cd -P "$(dirname "$src")" && pwd)"
|
|
16
|
+
src="$(readlink "$src")"
|
|
17
|
+
[[ "$src" != /* ]] && src="${dir}/${src}"
|
|
18
|
+
done
|
|
19
|
+
printf '%s' "$(cd -P "$(dirname "$src")" && pwd)/_helpers/$1"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Fail-closed: a data-loss gate that cannot read the command must DENY,
|
|
23
|
+
# not silently allow when jq is absent (observability-eye I8).
|
|
24
|
+
cos_require_parser block-dangerous-commands
|
|
25
|
+
|
|
26
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
27
|
+
|
|
28
|
+
# Fast-path: this gate fires on EVERY Bash command. The common case (no
|
|
29
|
+
# dangerous verb anywhere in the payload) must cost zero jq/python spawns.
|
|
30
|
+
# Every block below keys on one of these literals; if the raw payload mentions
|
|
31
|
+
# none of them there is nothing to deny — bail before parsing. (`rm`/`mv` etc.
|
|
32
|
+
# are still parsed properly downstream; this only short-circuits the no-match.)
|
|
33
|
+
# Indirection tokens (eval/xargs/<<</|sh) and hub-settings.json are included so an
|
|
34
|
+
# indirection-wrapped dangerous op or a policy-file write is never fast-skipped.
|
|
35
|
+
case "$INPUT" in
|
|
36
|
+
*"git push"*|*"git reset"*|*"git clean"*|*rm*|*migrate*|*DROP*|*Drop*|*drop*|*eval*|*xargs*|*"<<<"*|*"|sh"*|*"| sh"*|*"|bash"*|*"| bash"*|*hub-settings.json*) ;;
|
|
37
|
+
*) exit 0 ;;
|
|
38
|
+
esac
|
|
39
|
+
|
|
40
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
41
|
+
|
|
42
|
+
if [[ "$TOOL" != "Bash" ]]; then
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
cos_log_hook block-dangerous-commands fire "tool=Bash"
|
|
47
|
+
COMMAND=$(printf '%s' "$INPUT" | cos_json_field tool_input.command)
|
|
48
|
+
|
|
49
|
+
# Block a Bash write to the git-policy file (TASK-587b): rewriting
|
|
50
|
+
# .coding-os/hub-settings.json from a shell self-downgrades pr-mode -> trunk,
|
|
51
|
+
# where a non-force push to main is legal. Gated on the basename so non-policy
|
|
52
|
+
# commands skip the python spawn. Defense-in-depth — fails OPEN on helper error;
|
|
53
|
+
# the authoritative wall is server-side branch protection.
|
|
54
|
+
case "$COMMAND" in
|
|
55
|
+
*hub-settings.json*)
|
|
56
|
+
SET_VERDICT=$(printf '%s' "$INPUT" | python3 "$(_resolve_helper check_settings_write.py)" 2>/dev/null || echo allow)
|
|
57
|
+
if [ "$SET_VERDICT" = "block" ]; then
|
|
58
|
+
cos_log_hook block-dangerous-commands block "rule=settings-policy-write"
|
|
59
|
+
echo "BLOCKED: writing .coding-os/hub-settings.json from a shell flips the git workflow (pr<->trunk). Change git settings only via the Hub Config->Git tab — it is the policy file branch-guard reads on every hook." >&2
|
|
60
|
+
exit 2
|
|
61
|
+
fi
|
|
62
|
+
;;
|
|
63
|
+
esac
|
|
64
|
+
|
|
65
|
+
# Shell-indirection recovery (TASK-587a): un-glue git commands hidden inside
|
|
66
|
+
# eval / pipe-into-sh / here-string / xargs so the force-push / reset / clean
|
|
67
|
+
# greps below see them. Gated on an indirection token so the common path spawns
|
|
68
|
+
# no python. branch-guard is the fail-closed twin for the protected ops.
|
|
69
|
+
COMMAND_SCAN="$COMMAND"
|
|
70
|
+
case "$COMMAND" in
|
|
71
|
+
*eval*|*xargs*|*"<<<"*|*"|sh"*|*"| sh"*|*"|bash"*|*"| bash"*)
|
|
72
|
+
_RECOVERED=$(printf '%s' "$INPUT" | python3 "$(_resolve_helper recover_indirect.py)" 2>/dev/null || true)
|
|
73
|
+
[[ -n "$_RECOVERED" ]] && COMMAND_SCAN="$COMMAND"$'\n'"$_RECOVERED"
|
|
74
|
+
unset _RECOVERED
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
|
|
78
|
+
# Block force push to main/master. Opt-in escape hatch for legitimate cases
|
|
79
|
+
# (pre-public history scrub, secret removal, BFG-style cleanup): EXPORT
|
|
80
|
+
# COS_ALLOW_FORCE_PUSH_MAIN=1 into the session env before the call. An inline
|
|
81
|
+
# `COS_ALLOW_FORCE_PUSH_MAIN=1 git push …` prefix does NOT work and is rejected
|
|
82
|
+
# by design — the assignment has not executed when this PreToolUse hook reads
|
|
83
|
+
# its own process env, so an agent cannot self-grant the override from the
|
|
84
|
+
# command string (TASK-567 F3). Only a deliberate operator session-export opens it.
|
|
85
|
+
_FORCE_PUSH_OPT_IN=0
|
|
86
|
+
if [[ "${COS_ALLOW_FORCE_PUSH_MAIN:-0}" == "1" ]]; then
|
|
87
|
+
_FORCE_PUSH_OPT_IN=1
|
|
88
|
+
fi
|
|
89
|
+
if [[ "$_FORCE_PUSH_OPT_IN" != "1" ]]; then
|
|
90
|
+
# Force-push to main/master. git IGNORES flag position, so detect the push, the
|
|
91
|
+
# force flag, and the main/master target INDEPENDENTLY — the old `--force.*main`
|
|
92
|
+
# regex missed `git push origin main --force` / `... main -f` (flag AFTER refspec,
|
|
93
|
+
# TASK-571). `--force-with-lease` is the safe variant (and the pr-mode submit path)
|
|
94
|
+
# so the boundary `--force([space]|$)` deliberately excludes it.
|
|
95
|
+
if echo "$COMMAND_SCAN" | grep -qE '(^|[[:space:];&|])git[[:space:]]+push' \
|
|
96
|
+
&& echo "$COMMAND_SCAN" | grep -qE '(--force([[:space:]]|$)|(^|[[:space:]])-f([[:space:]]|$))' \
|
|
97
|
+
&& echo "$COMMAND_SCAN" | grep -qE '(^|[[:space:]/+:])(main|master)([[:space:]]|$)'; then
|
|
98
|
+
cos_log_hook block-dangerous-commands block "rule=force-push-main"
|
|
99
|
+
echo "BLOCKED: Force push to main/master is extremely dangerous and can destroy shared history. Use a feature branch instead. (Override: export COS_ALLOW_FORCE_PUSH_MAIN=1 session-wide; an inline prefix is rejected.)" >&2
|
|
100
|
+
exit 2
|
|
101
|
+
fi
|
|
102
|
+
# Force via refspec: `+main` / `+HEAD:main` / `+refs/heads/main` (any qualifier —
|
|
103
|
+
# the old regex needed a colon, so the fully-qualified `+refs/heads/main` slipped).
|
|
104
|
+
if echo "$COMMAND_SCAN" | grep -qE '(^|[[:space:];&|])git[[:space:]]+push[^|;&]*[[:space:]]\+[^[:space:]]*(main|master)\b'; then
|
|
105
|
+
cos_log_hook block-dangerous-commands block "rule=force-push-main-refspec"
|
|
106
|
+
echo "BLOCKED: force-push refspec (+main/+master) rewrites shared history. Use a feature branch instead. (Override: export COS_ALLOW_FORCE_PUSH_MAIN=1 session-wide; an inline prefix is rejected.)" >&2
|
|
107
|
+
exit 2
|
|
108
|
+
fi
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# Block dropping database tables
|
|
112
|
+
if echo "$COMMAND" | grep -qiE 'DROP\s+(TABLE|DATABASE)'; then
|
|
113
|
+
cos_log_hook block-dangerous-commands block "rule=drop-db"
|
|
114
|
+
echo "BLOCKED: DROP TABLE/DATABASE is destructive and irreversible. If this is intentional, ask the user to confirm and run it manually." >&2
|
|
115
|
+
exit 2
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Block recursive rm of a critical path (root / cwd / parent / glob / project
|
|
119
|
+
# dirs / top-level absolute). Delegated to a shlex-correct helper so flag-order
|
|
120
|
+
# (-fr, -r -f) and bare /·.·..·* targets can't slip past a regex word-boundary.
|
|
121
|
+
# Skip the python helper spawn entirely when COMMAND has no `rm` token — the
|
|
122
|
+
# helper would return `allow` for a command with no rm, so this is a pure
|
|
123
|
+
# fast-path (saves a ~50ms python3 startup on every non-rm git/sql command).
|
|
124
|
+
case "$COMMAND" in
|
|
125
|
+
*rm*) ;;
|
|
126
|
+
*)
|
|
127
|
+
# No rm at all → nothing for the helper to deny; fall through past the
|
|
128
|
+
# rm gate to the remaining (migrate / reset / clean) checks.
|
|
129
|
+
RM_VERDICT="allow"
|
|
130
|
+
;;
|
|
131
|
+
esac
|
|
132
|
+
if [ "${RM_VERDICT:-}" != "allow" ]; then
|
|
133
|
+
RM_VERDICT=$(printf '%s' "$INPUT" | python3 "$(_resolve_helper check_dangerous_rm.py)" 2>/dev/null || echo error)
|
|
134
|
+
fi
|
|
135
|
+
# Fail-closed but SCOPED: a helper crash/absence (RM_VERDICT=error) blocks
|
|
136
|
+
# only when the command actually contains a recursive rm we could not verify —
|
|
137
|
+
# never brick unrelated commands (observability-eye I8/A2).
|
|
138
|
+
if [ "$RM_VERDICT" = "error" ]; then
|
|
139
|
+
if echo "$COMMAND" | grep -qE '(^|[[:space:];&|])(sudo[[:space:]]+)?rm[[:space:]]+(-[A-Za-z]*[rR]|--recursive)'; then
|
|
140
|
+
cos_say error hook.block_dangerous_commands "check_dangerous_rm helper unavailable — failing closed on a recursive rm" 2>/dev/null || true
|
|
141
|
+
RM_VERDICT="block"
|
|
142
|
+
else
|
|
143
|
+
RM_VERDICT="allow"
|
|
144
|
+
fi
|
|
145
|
+
fi
|
|
146
|
+
if [ "$RM_VERDICT" = "block" ]; then
|
|
147
|
+
cos_log_hook block-dangerous-commands block "rule=rm-rf-critical"
|
|
148
|
+
echo "BLOCKED: recursive rm targeting a critical path (/, ., .., *, a project dir, or a top-level directory). Name the exact files to remove, or ask the user to run it manually." >&2
|
|
149
|
+
exit 2
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# Block direct migration apply to production
|
|
153
|
+
if echo "$COMMAND" | grep -qE 'manage\.py migrate.*--settings.*production'; then
|
|
154
|
+
cos_log_hook block-dangerous-commands block "rule=prod-migrate"
|
|
155
|
+
echo "BLOCKED: Production migrations require human execution (AGENTS.md P5). Ask the user to run this command manually." >&2
|
|
156
|
+
exit 2
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# Block destructive `git reset --hard` / `git clean -f`. Delegated to a
|
|
160
|
+
# shlex-correct helper so a long-option ABBREVIATION (`reset --har`, `clean
|
|
161
|
+
# --for`/`--f`) or a split short cluster (`clean -d -f`) can't slip the old
|
|
162
|
+
# literal greps — git resolves any unambiguous prefix. Fed COMMAND_SCAN so a
|
|
163
|
+
# recovered-indirection git op is scanned too. Fails OPEN on helper error;
|
|
164
|
+
# branch-guard is the fail-closed twin for the HEAD-moving reset.
|
|
165
|
+
if echo "$COMMAND_SCAN" | grep -qE 'git[[:space:]]+(reset|clean)'; then
|
|
166
|
+
DESTRUCTIVE_VERDICT=$(
|
|
167
|
+
jq -n --arg c "$COMMAND_SCAN" '{tool_name:"Bash",tool_input:{command:$c}}' \
|
|
168
|
+
| python3 "$(_resolve_helper check_git_destructive.py)" 2>/dev/null || echo allow
|
|
169
|
+
)
|
|
170
|
+
if [ "$DESTRUCTIVE_VERDICT" = "reset-hard" ]; then
|
|
171
|
+
cos_log_hook block-dangerous-commands block "rule=reset-hard"
|
|
172
|
+
echo "BLOCKED: git reset --hard discards all uncommitted changes permanently. Consider 'git stash' instead, or ask the user to confirm." >&2
|
|
173
|
+
exit 2
|
|
174
|
+
fi
|
|
175
|
+
if [ "$DESTRUCTIVE_VERDICT" = "clean-force" ]; then
|
|
176
|
+
cos_log_hook block-dangerous-commands block "rule=git-clean-force"
|
|
177
|
+
echo "BLOCKED: git clean -f permanently deletes untracked files. Ask the user to confirm which files should be removed." >&2
|
|
178
|
+
exit 2
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
exit 0
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse Write|Edit hook: block hardcoded stack/adapter literals in cli/*.py.
|
|
3
|
+
#
|
|
4
|
+
# Catches the SSOT drift at EDIT time instead of test time. Stack and
|
|
5
|
+
# adapter IDs ("django", "claude", "python-django", …) must never appear
|
|
6
|
+
# as quoted literals inside cli/*.py — the registry loader reads them
|
|
7
|
+
# from YAML. Pytest has tests/test_no_hardcoded_stacks.py as the rear
|
|
8
|
+
# guard; this hook is the front guard so the offending edit never
|
|
9
|
+
# lands on disk.
|
|
10
|
+
#
|
|
11
|
+
# Scope: only fires for files under cli/*.py (the data-driven layer).
|
|
12
|
+
# Everywhere else — tests, templates, adapters — literals are expected.
|
|
13
|
+
#
|
|
14
|
+
# Escape hatch: $COS_STATE_DIR/.literals-override for one-shot bypass.
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
18
|
+
|
|
19
|
+
# Fail-closed: an SSOT-drift gate that cannot read its input must DENY,
|
|
20
|
+
# not silently allow when jq is absent (observability-eye I8). cos_json_field
|
|
21
|
+
# falls back to python3, so the gate keeps working when only jq is missing.
|
|
22
|
+
cos_require_parser block-hardcoded-literals
|
|
23
|
+
|
|
24
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
25
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
26
|
+
if [[ "$TOOL" != "Write" && "$TOOL" != "Edit" ]]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
FILE_PATH=$(printf '%s' "$INPUT" | cos_json_field tool_input.file_path)
|
|
31
|
+
[[ -z "$FILE_PATH" ]] && exit 0
|
|
32
|
+
|
|
33
|
+
# Only guard the data-driven CLI layer.
|
|
34
|
+
case "$FILE_PATH" in
|
|
35
|
+
*cli/*.py) ;;
|
|
36
|
+
*) exit 0 ;;
|
|
37
|
+
esac
|
|
38
|
+
|
|
39
|
+
COS_STATE_DIR="${COS_STATE_DIR:-.coding-os}"
|
|
40
|
+
|
|
41
|
+
if cos_one_shot_override literals 2>/dev/null; then
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [[ "$TOOL" == "Write" ]]; then
|
|
46
|
+
CONTENT=$(printf '%s' "$INPUT" | cos_json_field tool_input.content)
|
|
47
|
+
else
|
|
48
|
+
CONTENT=$(printf '%s' "$INPUT" | cos_json_field tool_input.new_string)
|
|
49
|
+
fi
|
|
50
|
+
[[ -z "$CONTENT" ]] && exit 0
|
|
51
|
+
|
|
52
|
+
# Resolve the checker against the REAL src/core/hooks dir. This script runs
|
|
53
|
+
# via a per-file symlink inside a dir-of-symlinks (.claude/hooks/ in every
|
|
54
|
+
# consumer AND the meta-repo's own .claude), so $(dirname "$0")/../scripts
|
|
55
|
+
# lands at the nonexistent .claude/scripts/ and the gate went SILENTLY inert
|
|
56
|
+
# — letting hardcoded literals through on every PreToolUse edit. cos-env's
|
|
57
|
+
# _cos_helpers_dir follows the symlink chain to the real .../hooks/_helpers;
|
|
58
|
+
# its parent is the real hooks dir, whose ../scripts holds the checker.
|
|
59
|
+
if declare -F _cos_helpers_dir >/dev/null 2>&1; then
|
|
60
|
+
CORE_HOOKS_DIR="$(dirname "$(_cos_helpers_dir)")"
|
|
61
|
+
else
|
|
62
|
+
CORE_HOOKS_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
63
|
+
fi
|
|
64
|
+
CHECKER="${CORE_HOOKS_DIR}/../scripts/check_hardcoded_literals.py"
|
|
65
|
+
|
|
66
|
+
if [[ ! -f "$CHECKER" ]]; then
|
|
67
|
+
# Never silent again: a missing checker means a broken install, not "all
|
|
68
|
+
# clear". Stay fail-open (this gate's scope is narrow — cli/*.py only — and
|
|
69
|
+
# a half-installed tree must not block every cli edit), but make it LOUD.
|
|
70
|
+
echo "block-hardcoded-literals: SSOT-drift checker not found at $CHECKER — gate INERT; reinstall the adapter (bash src/adapters/<id>/install.sh)" >&2
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# `|| RC=$?` keeps set -e from killing the script on the checker's rc=2, so
|
|
75
|
+
# the override hint below actually prints (it was dead code under pipefail).
|
|
76
|
+
RC=0
|
|
77
|
+
echo "$CONTENT" | python3 "$CHECKER" --file "$FILE_PATH" || RC=$?
|
|
78
|
+
|
|
79
|
+
if [[ $RC -eq 2 ]]; then
|
|
80
|
+
echo " One-shot override: touch $COS_STATE_DIR/.literals-override" >&2
|
|
81
|
+
echo " (or: echo '{\"literals\":{\"reason\":\"\"}}' > $COS_STATE_DIR/.overrides.json)" >&2
|
|
82
|
+
exit 2
|
|
83
|
+
elif [[ $RC -ne 0 ]]; then
|
|
84
|
+
# A crashing checker (argparse/traceback, rc=1/127) is NOT a clean pass — stay
|
|
85
|
+
# fail-open (don't block every cli edit on a checker bug) but make it LOUD so
|
|
86
|
+
# the dead gate is observable, never silent (pass-3 review).
|
|
87
|
+
echo "block-hardcoded-literals: checker errored (rc=$RC) — edit allowed but the SSOT-drift gate did NOT run" >&2
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
exit 0
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse Write|Edit hook: block duplicate migration versions.
|
|
3
|
+
#
|
|
4
|
+
# Source of truth: CLAUDE.md Critical Rule #10 — "Schema migrations are
|
|
5
|
+
# append-only. New tables → migration vN+1, never edit past migrations."
|
|
6
|
+
#
|
|
7
|
+
# Scope: runs only on files named `db.py` (migration registries in
|
|
8
|
+
# thinking_os) and on files under `*/migrations/` for frameworks that
|
|
9
|
+
# use numbered migration files (Django, Alembic).
|
|
10
|
+
#
|
|
11
|
+
# For database.py-style files: detects `MIGRATIONS.append((N, ...))` in the
|
|
12
|
+
# new content and rejects N if it already exists in the current file.
|
|
13
|
+
#
|
|
14
|
+
# For framework migration files: detects attempts to create a file
|
|
15
|
+
# named with a version prefix that already exists in the same dir
|
|
16
|
+
# (0003_foo.py + 0003_bar.py = conflict).
|
|
17
|
+
#
|
|
18
|
+
# Fail-closed — a duplicate-version DB is corrupt and silent: this must
|
|
19
|
+
# block, not warn.
|
|
20
|
+
set -euo pipefail
|
|
21
|
+
|
|
22
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
23
|
+
|
|
24
|
+
# Fail-closed: a duplicate-migration gate that cannot read its input must DENY,
|
|
25
|
+
# not silently allow when jq is absent (observability-eye I8). cos_json_field
|
|
26
|
+
# falls back to python3, so the gate keeps working when only jq is missing.
|
|
27
|
+
cos_require_parser block-migration-conflict
|
|
28
|
+
|
|
29
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
30
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
31
|
+
if [[ "$TOOL" != "Write" && "$TOOL" != "Edit" ]]; then
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
FILE_PATH=$(printf '%s' "$INPUT" | cos_json_field tool_input.file_path)
|
|
36
|
+
[[ -z "$FILE_PATH" ]] && exit 0
|
|
37
|
+
|
|
38
|
+
# --- database.py-style registries ------------------------------------------
|
|
39
|
+
# Fires when the changed file is named db.py OR when the diff adds a
|
|
40
|
+
# MIGRATIONS.append line — whichever comes first.
|
|
41
|
+
BASENAME=$(basename "$FILE_PATH")
|
|
42
|
+
|
|
43
|
+
if [[ "$BASENAME" == "database.py" ]]; then
|
|
44
|
+
# Extract proposed new version from the tool input.
|
|
45
|
+
if [[ "$TOOL" == "Write" ]]; then
|
|
46
|
+
CONTENT=$(printf '%s' "$INPUT" | cos_json_field tool_input.content)
|
|
47
|
+
else
|
|
48
|
+
CONTENT=$(printf '%s' "$INPUT" | cos_json_field tool_input.new_string)
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Find any N in `MIGRATIONS.append((N, ...))` patterns in the new content.
|
|
52
|
+
PROPOSED_VERSIONS=$(echo "$CONTENT" | grep -oE 'MIGRATIONS\.append\(\([[:space:]]*[0-9]+' | grep -oE '[0-9]+' | sort -u)
|
|
53
|
+
|
|
54
|
+
if [[ -z "$PROPOSED_VERSIONS" ]]; then
|
|
55
|
+
# No migration addition in this diff → allow.
|
|
56
|
+
exit 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Current versions in the existing file.
|
|
60
|
+
if [[ -f "$FILE_PATH" ]]; then
|
|
61
|
+
EXISTING_VERSIONS=$(grep -oE 'MIGRATIONS\.append\(\([[:space:]]*[0-9]+' "$FILE_PATH" | grep -oE '[0-9]+' | sort -u)
|
|
62
|
+
else
|
|
63
|
+
EXISTING_VERSIONS=""
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
CONFLICTS=()
|
|
67
|
+
for v in $PROPOSED_VERSIONS; do
|
|
68
|
+
if echo "$EXISTING_VERSIONS" | grep -qw "$v"; then
|
|
69
|
+
# Edit tool rewrites a line — only flag if the OLD string didn't
|
|
70
|
+
# already contain this version (i.e. truly adding a dup, not
|
|
71
|
+
# renaming an existing one).
|
|
72
|
+
if [[ "$TOOL" == "Edit" ]]; then
|
|
73
|
+
OLD_STRING=$(printf '%s' "$INPUT" | cos_json_field tool_input.old_string)
|
|
74
|
+
if echo "$OLD_STRING" | grep -qE "MIGRATIONS\.append\(\([[:space:]]*${v}[^0-9]"; then
|
|
75
|
+
continue # this edit is replacing the v entry in-place
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
CONFLICTS+=("$v")
|
|
79
|
+
fi
|
|
80
|
+
done
|
|
81
|
+
|
|
82
|
+
if [[ ${#CONFLICTS[@]} -gt 0 ]]; then
|
|
83
|
+
NEXT=$(echo "$EXISTING_VERSIONS" | sort -n | tail -1)
|
|
84
|
+
NEXT=$(( NEXT + 1 ))
|
|
85
|
+
echo "BLOCKED: duplicate migration version(s): ${CONFLICTS[*]}" >&2
|
|
86
|
+
echo " File: $FILE_PATH" >&2
|
|
87
|
+
echo " Existing versions: $(echo "$EXISTING_VERSIONS" | paste -sd',' -)" >&2
|
|
88
|
+
echo " CLAUDE.md Rule #10 — migrations are append-only." >&2
|
|
89
|
+
echo " Use the next available version: $NEXT" >&2
|
|
90
|
+
exit 2
|
|
91
|
+
fi
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# --- Numbered framework migrations -----------------------------------
|
|
96
|
+
# Typical layout: backend/apps/<app>/migrations/NNNN_name.py
|
|
97
|
+
# New Write creating 0003_foo.py when 0003_bar.py exists → conflict.
|
|
98
|
+
if [[ "$FILE_PATH" == *migrations/*.py ]] && [[ "$TOOL" == "Write" ]]; then
|
|
99
|
+
if [[ ! -f "$FILE_PATH" ]]; then
|
|
100
|
+
DIR=$(dirname "$FILE_PATH")
|
|
101
|
+
NEW_PREFIX=$(basename "$FILE_PATH" | grep -oE '^[0-9]+' || true)
|
|
102
|
+
if [[ -n "$NEW_PREFIX" ]] && [[ -d "$DIR" ]]; then
|
|
103
|
+
EXISTING=$(find "$DIR" -maxdepth 1 -name "${NEW_PREFIX}_*.py" ! -path "$FILE_PATH" | head -3)
|
|
104
|
+
if [[ -n "$EXISTING" ]]; then
|
|
105
|
+
echo "BLOCKED: migration prefix ${NEW_PREFIX} already used in $DIR:" >&2
|
|
106
|
+
echo "$EXISTING" | sed 's/^/ - /' >&2
|
|
107
|
+
echo " Use the next available prefix. Regenerate with \`makemigrations\`." >&2
|
|
108
|
+
exit 2
|
|
109
|
+
fi
|
|
110
|
+
fi
|
|
111
|
+
fi
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
exit 0
|