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,179 @@
|
|
|
1
|
+
# Supply-Chain Hardening
|
|
2
|
+
|
|
3
|
+
The most common vector in the 2024-2025 breach landscape. Defense is a layered process, not a single tool.
|
|
4
|
+
|
|
5
|
+
## The Threat Surface
|
|
6
|
+
|
|
7
|
+
A modern app pulls hundreds of transitive dependencies. Each one is a potential vector:
|
|
8
|
+
|
|
9
|
+
1. **Typosquatting** — `requests` vs `requets`, `lodash` vs `lodash-es-utils`. Devs mistype, install malware.
|
|
10
|
+
2. **Compromised maintainer account** — original maintainer's npm/PyPI account hijacked, malicious version published. (Examples: `event-stream` 2018, `colors.js` 2022, `xz-utils` 2024.)
|
|
11
|
+
3. **Dependency confusion** — internal package name registered on public registry by attacker; pip/npm prefers public version.
|
|
12
|
+
4. **Source-code injection** — malicious PR merged into legitimate package.
|
|
13
|
+
5. **Build-time compromise** — CI pipeline tokens leaked → attacker publishes a tainted release.
|
|
14
|
+
|
|
15
|
+
## Defenses — The Layered Approach
|
|
16
|
+
|
|
17
|
+
### Layer 1: Lockfiles (mandatory)
|
|
18
|
+
|
|
19
|
+
Every package manager produces a lockfile that pins exact transitive versions + integrity hashes:
|
|
20
|
+
|
|
21
|
+
| Ecosystem | Lockfile |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Go | `go.sum` |
|
|
24
|
+
| Python (uv) | `uv.lock` |
|
|
25
|
+
| Python (poetry) | `poetry.lock` |
|
|
26
|
+
| Python (pip-tools) | `requirements.txt` (compiled, with hashes) |
|
|
27
|
+
| Node (npm) | `package-lock.json` |
|
|
28
|
+
| Node (yarn) | `yarn.lock` |
|
|
29
|
+
| Node (pnpm) | `pnpm-lock.yaml` |
|
|
30
|
+
|
|
31
|
+
Rules:
|
|
32
|
+
|
|
33
|
+
- **Commit the lockfile**.
|
|
34
|
+
- **CI uses `--frozen-lockfile`** (or equivalent: `npm ci`, `yarn install --immutable`, `pnpm install --frozen-lockfile`, `uv sync --frozen`). Fails if `package.json` and lockfile disagree.
|
|
35
|
+
- **Hash verification on install** — every package manager does this when given a lockfile with hashes.
|
|
36
|
+
|
|
37
|
+
### Layer 2: Vulnerability Scanning (CI)
|
|
38
|
+
|
|
39
|
+
Run on every PR. Fail on high-severity. Don't merge until resolved (or explicitly waived with an expiration).
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
# .github/workflows/audit.yml
|
|
43
|
+
jobs:
|
|
44
|
+
audit:
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
# Go
|
|
50
|
+
- run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
|
51
|
+
- run: govulncheck ./...
|
|
52
|
+
|
|
53
|
+
# Python
|
|
54
|
+
- run: pipx install pip-audit
|
|
55
|
+
- run: pip-audit --strict
|
|
56
|
+
|
|
57
|
+
# Node (RN client)
|
|
58
|
+
- run: cd mobile && yarn install --immutable
|
|
59
|
+
- run: cd mobile && yarn npm audit --severity high --recursive
|
|
60
|
+
|
|
61
|
+
# Cross-ecosystem (preferred — single tool, full coverage)
|
|
62
|
+
- run: pipx install osv-scanner
|
|
63
|
+
- run: osv-scanner --recursive .
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
OSV (Open Source Vulnerabilities) database aggregates across ecosystems. Use it as the canonical scanner.
|
|
67
|
+
|
|
68
|
+
### Layer 3: Dependency Review on PRs
|
|
69
|
+
|
|
70
|
+
- **GitHub Dependency Review** (built-in) — flags new vulnerabilities introduced by the PR.
|
|
71
|
+
- **Dependabot / Renovate** — automated PRs to update deps. Review like any other PR (don't auto-merge transitives blindly; let security patches auto-merge with full test pass).
|
|
72
|
+
|
|
73
|
+
### Layer 4: Minimize Surface
|
|
74
|
+
|
|
75
|
+
- **Audit every new dependency** at PR time. One paragraph in the PR description: what does this do? Is there a smaller alternative? Could you write it yourself in <100 lines?
|
|
76
|
+
- **Remove unused deps** quarterly: `depcheck` (Node), `pip-autoremove` (Python), `go mod tidy` (Go).
|
|
77
|
+
- **Avoid abandoned packages**: check last-commit timestamp; replace anything inactive >2 years.
|
|
78
|
+
- **Pin major versions** in `package.json` / `pyproject.toml` (`^` is fine for minor/patch with lockfile; never `latest`).
|
|
79
|
+
|
|
80
|
+
### Layer 5: Dependency Confusion Defense
|
|
81
|
+
|
|
82
|
+
For internal packages (private monorepo, internal SDK):
|
|
83
|
+
|
|
84
|
+
- **Scoped packages** in npm: `@app/internal-utils` — register the scope on npmjs.org even if you never publish, claiming it.
|
|
85
|
+
- **Private registry first** in `.npmrc`:
|
|
86
|
+
```
|
|
87
|
+
registry=https://registry.npmjs.org
|
|
88
|
+
@app:registry=https://npm.internal.app.com
|
|
89
|
+
```
|
|
90
|
+
- **Python**: Pin internal packages with `extra-index-url` strict ordering, OR install from URL/path directly.
|
|
91
|
+
- **Verify package source** in your build: assert that `@app/internal-utils` resolves from your private registry, not public.
|
|
92
|
+
|
|
93
|
+
### Layer 6: Provenance + Sigstore
|
|
94
|
+
|
|
95
|
+
For packages you PUBLISH (your own libraries, internal SDKs):
|
|
96
|
+
|
|
97
|
+
- **npm provenance** (`--provenance` flag on publish) — attaches verifiable build metadata via Sigstore.
|
|
98
|
+
- **Sigstore** for Go modules and container images.
|
|
99
|
+
- **Reproducible builds** where feasible.
|
|
100
|
+
|
|
101
|
+
For packages you CONSUME, look for and prefer those with provenance attestations (npm + GitHub now show this on the package page).
|
|
102
|
+
|
|
103
|
+
### Layer 7: Build Pipeline Hardening
|
|
104
|
+
|
|
105
|
+
- **Short-lived OIDC tokens** for cloud auth in CI (no long-lived secrets in GitHub Actions / GitLab CI).
|
|
106
|
+
- **Pin GitHub Action versions to commit SHA**, not tag (`uses: actions/checkout@8e5e7e5...` not `@v4`).
|
|
107
|
+
- **Restrict who can approve releases**.
|
|
108
|
+
- **Two-person rule** for publishing high-impact packages.
|
|
109
|
+
- **Separate publish-only credentials** (no PR-merge perms).
|
|
110
|
+
- **Scan the build environment** itself: minimal base images, no unnecessary tools.
|
|
111
|
+
|
|
112
|
+
### Layer 8: Runtime Detection
|
|
113
|
+
|
|
114
|
+
You can't catch every bad dep at install. Some defenses run at runtime:
|
|
115
|
+
|
|
116
|
+
- **Outbound-traffic allowlist** at the network layer (your prod app should only talk to known endpoints). Sudden new outbound destination = exfiltration alert.
|
|
117
|
+
- **Process-level monitoring** (Falco, Tracee) — alerts on `curl | sh` patterns, unusual syscalls.
|
|
118
|
+
- **Container image scanning** (Trivy, Grype) on every build.
|
|
119
|
+
|
|
120
|
+
## The Build Manifest — SBOM
|
|
121
|
+
|
|
122
|
+
Generate a Software Bill of Materials per build artifact. Standard format: CycloneDX or SPDX.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Cross-language
|
|
126
|
+
syft scan ./mobile -o cyclonedx-json > sbom-mobile.json
|
|
127
|
+
syft scan ./backend -o cyclonedx-json > sbom-backend.json
|
|
128
|
+
|
|
129
|
+
# Then verify SBOM doesn't have known vulns:
|
|
130
|
+
grype sbom:sbom-mobile.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Attach SBOMs to GitHub releases. Customers / auditors / compliance teams will ask.
|
|
134
|
+
|
|
135
|
+
## Operational Practices
|
|
136
|
+
|
|
137
|
+
### Weekly Dependency Hygiene
|
|
138
|
+
|
|
139
|
+
- [ ] `osv-scanner --recursive .` — zero high-severity.
|
|
140
|
+
- [ ] Dependabot / Renovate PRs reviewed and merged.
|
|
141
|
+
- [ ] One pass through `pnpm/npm/yarn audit` looking for transitives that snuck in.
|
|
142
|
+
|
|
143
|
+
### Monthly Dependency Audit
|
|
144
|
+
|
|
145
|
+
- [ ] Quarterly `pnpm dlx depcheck` / `pip-autoremove` / `go mod tidy` — drop unused.
|
|
146
|
+
- [ ] Review of new direct deps added since last audit — still justified?
|
|
147
|
+
- [ ] Refresh of "abandoned package" check — anyone left maintainership?
|
|
148
|
+
|
|
149
|
+
### Incident: "Compromised Package"
|
|
150
|
+
|
|
151
|
+
When a notice drops ("colors.js v1.4.x is malicious"):
|
|
152
|
+
|
|
153
|
+
1. **Pin LOWER** in your lockfile + redeploy in <2 hours.
|
|
154
|
+
2. **Audit logs** for the time window when the compromised version was deployed.
|
|
155
|
+
3. **Rotate any secrets** the deployment had access to.
|
|
156
|
+
4. **Notify users** if data was at risk.
|
|
157
|
+
5. **Post-mortem** — what could have caught this earlier?
|
|
158
|
+
|
|
159
|
+
## Common Supply-Chain Mistakes
|
|
160
|
+
|
|
161
|
+
1. **Lockfile not committed** — non-reproducible builds; transitive surprise.
|
|
162
|
+
2. **`npm install` instead of `npm ci`** in CI — re-resolves; lockfile becomes advisory.
|
|
163
|
+
3. **No `audit` in CI** — vulnerabilities ship to prod.
|
|
164
|
+
4. **Auto-merging Dependabot** without test pass — broken release in 5 minutes.
|
|
165
|
+
5. **GitHub Actions tags pinned** instead of SHAs — tag re-pointed at malicious commit = supply-chain attack.
|
|
166
|
+
6. **Long-lived secrets** in CI — first leak forever.
|
|
167
|
+
7. **Public package install before private check** — dependency confusion.
|
|
168
|
+
8. **No SBOM** — can't quickly answer "are we affected by CVE-X" without grepping every lockfile.
|
|
169
|
+
9. **Pulling Docker `image:latest`** in production — non-reproducible; new "latest" = silent change.
|
|
170
|
+
10. **`curl | sh` install** in CI — full code-execution from a remote server you didn't audit.
|
|
171
|
+
|
|
172
|
+
## Source Material
|
|
173
|
+
|
|
174
|
+
- *OWASP CycloneDX*: <https://cyclonedx.org/>
|
|
175
|
+
- *Sigstore*: <https://www.sigstore.dev/>
|
|
176
|
+
- *SLSA framework*: <https://slsa.dev/>
|
|
177
|
+
- *npm provenance*: <https://docs.npmjs.com/generating-provenance-statements>
|
|
178
|
+
- *OSV database*: <https://osv.dev/>
|
|
179
|
+
- *Snyk supply-chain reports* (annual) — current threat landscape data.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Probe an HTTP endpoint for Content-Security-Policy + other security
|
|
3
|
+
# headers (HSTS, X-Content-Type-Options, Referrer-Policy, Permissions-Policy,
|
|
4
|
+
# COOP, COEP, X-Frame-Options).
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# bash csp-check.sh https://example.com
|
|
8
|
+
# bash csp-check.sh --strict https://example.com # fails on missing headers
|
|
9
|
+
# bash csp-check.sh --json https://example.com
|
|
10
|
+
#
|
|
11
|
+
# Exit codes:
|
|
12
|
+
# 0 = all required headers present (or non-strict mode)
|
|
13
|
+
# 1 = one or more required headers missing (only in --strict)
|
|
14
|
+
# 2 = curl error / bad URL
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
# Safety: ensure core POSIX tools resolvable even when caller PATH is restricted.
|
|
19
|
+
export PATH="/usr/bin:/bin:/usr/local/bin:${PATH:-}"
|
|
20
|
+
|
|
21
|
+
STRICT=0
|
|
22
|
+
EMIT_JSON=0
|
|
23
|
+
URL=""
|
|
24
|
+
|
|
25
|
+
while [ $# -gt 0 ]; do
|
|
26
|
+
case "$1" in
|
|
27
|
+
--strict) STRICT=1; shift ;;
|
|
28
|
+
--json) EMIT_JSON=1; shift ;;
|
|
29
|
+
-h|--help) sed -n '2,12p' "$0"; exit 0 ;;
|
|
30
|
+
-*) echo "Unknown flag: $1" >&2; exit 2 ;;
|
|
31
|
+
*) URL="$1"; shift ;;
|
|
32
|
+
esac
|
|
33
|
+
done
|
|
34
|
+
|
|
35
|
+
if [ -z "$URL" ]; then
|
|
36
|
+
echo "usage: $0 [--strict] [--json] <url>" >&2
|
|
37
|
+
exit 2
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
if ! command -v curl >/dev/null 2>&1; then
|
|
41
|
+
echo "curl not installed" >&2
|
|
42
|
+
exit 2
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Fetch headers only. -I = HEAD; some servers respond differently to HEAD
|
|
46
|
+
# vs GET so also try GET with -X GET and discard body.
|
|
47
|
+
HEADERS=$(curl -sS -L -D - -X GET -o /dev/null --max-time 10 "$URL" 2>&1) || {
|
|
48
|
+
echo "curl failed for $URL" >&2
|
|
49
|
+
exit 2
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Normalise: lowercase header names for grep
|
|
53
|
+
headers_lower=$(echo "$HEADERS" | tr 'A-Z' 'a-z')
|
|
54
|
+
|
|
55
|
+
# Required + recommended headers
|
|
56
|
+
declare -a REQUIRED=(
|
|
57
|
+
"content-security-policy"
|
|
58
|
+
"strict-transport-security"
|
|
59
|
+
"x-content-type-options"
|
|
60
|
+
"referrer-policy"
|
|
61
|
+
)
|
|
62
|
+
declare -a RECOMMENDED=(
|
|
63
|
+
"permissions-policy"
|
|
64
|
+
"cross-origin-opener-policy"
|
|
65
|
+
"cross-origin-embedder-policy"
|
|
66
|
+
"x-frame-options"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
declare -a MISSING_REQ=()
|
|
70
|
+
declare -a MISSING_REC=()
|
|
71
|
+
declare -A PRESENT=()
|
|
72
|
+
|
|
73
|
+
check_header() {
|
|
74
|
+
local h="$1"
|
|
75
|
+
if echo "$headers_lower" | grep -qE "^${h}:"; then
|
|
76
|
+
# Extract value (case-insensitive on header)
|
|
77
|
+
local value
|
|
78
|
+
value=$(echo "$HEADERS" | grep -iE "^${h}:" | head -1 | sed -E 's/^[^:]+:[[:space:]]*//' | tr -d '\r')
|
|
79
|
+
PRESENT[$h]="$value"
|
|
80
|
+
return 0
|
|
81
|
+
fi
|
|
82
|
+
return 1
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for h in "${REQUIRED[@]}"; do
|
|
86
|
+
if ! check_header "$h"; then
|
|
87
|
+
MISSING_REQ+=("$h")
|
|
88
|
+
fi
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
for h in "${RECOMMENDED[@]}"; do
|
|
92
|
+
if ! check_header "$h"; then
|
|
93
|
+
MISSING_REC+=("$h")
|
|
94
|
+
fi
|
|
95
|
+
done
|
|
96
|
+
|
|
97
|
+
# Emit
|
|
98
|
+
if [ "$EMIT_JSON" -eq 1 ]; then
|
|
99
|
+
# Build JSON manually (no jq dependency)
|
|
100
|
+
printf '{\n "url": "%s",\n "missing_required": [' "$URL"
|
|
101
|
+
first=1
|
|
102
|
+
for h in "${MISSING_REQ[@]+"${MISSING_REQ[@]}"}"; do
|
|
103
|
+
[ $first -eq 0 ] && printf ', '
|
|
104
|
+
printf '"%s"' "$h"
|
|
105
|
+
first=0
|
|
106
|
+
done
|
|
107
|
+
printf '],\n "missing_recommended": ['
|
|
108
|
+
first=1
|
|
109
|
+
for h in "${MISSING_REC[@]+"${MISSING_REC[@]}"}"; do
|
|
110
|
+
[ $first -eq 0 ] && printf ', '
|
|
111
|
+
printf '"%s"' "$h"
|
|
112
|
+
first=0
|
|
113
|
+
done
|
|
114
|
+
printf '],\n "present": {'
|
|
115
|
+
first=1
|
|
116
|
+
for h in "${!PRESENT[@]}"; do
|
|
117
|
+
[ $first -eq 0 ] && printf ', '
|
|
118
|
+
# Naive JSON-escape: replace " with \" and \ with \\
|
|
119
|
+
value="${PRESENT[$h]//\\/\\\\}"
|
|
120
|
+
value="${value//\"/\\\"}"
|
|
121
|
+
printf '"%s": "%s"' "$h" "$value"
|
|
122
|
+
first=0
|
|
123
|
+
done
|
|
124
|
+
printf '}\n}\n'
|
|
125
|
+
else
|
|
126
|
+
echo "Security header probe — $URL"
|
|
127
|
+
echo
|
|
128
|
+
if [ "${#MISSING_REQ[@]}" -gt 0 ]; then
|
|
129
|
+
echo "MISSING (required):"
|
|
130
|
+
for h in "${MISSING_REQ[@]}"; do
|
|
131
|
+
echo " - $h"
|
|
132
|
+
done
|
|
133
|
+
echo
|
|
134
|
+
fi
|
|
135
|
+
if [ "${#MISSING_REC[@]}" -gt 0 ]; then
|
|
136
|
+
echo "Missing (recommended):"
|
|
137
|
+
for h in "${MISSING_REC[@]}"; do
|
|
138
|
+
echo " - $h"
|
|
139
|
+
done
|
|
140
|
+
echo
|
|
141
|
+
fi
|
|
142
|
+
if [ "${#PRESENT[@]}" -gt 0 ]; then
|
|
143
|
+
echo "Present:"
|
|
144
|
+
for h in "${!PRESENT[@]}"; do
|
|
145
|
+
printf " %-32s %s\n" "$h:" "${PRESENT[$h]}"
|
|
146
|
+
done
|
|
147
|
+
fi
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if [ "$STRICT" -eq 1 ] && [ "${#MISSING_REQ[@]}" -gt 0 ]; then
|
|
151
|
+
exit 1
|
|
152
|
+
fi
|
|
153
|
+
exit 0
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shell-scripting
|
|
3
|
+
tier: quality
|
|
4
|
+
domain: [universal]
|
|
5
|
+
description: Write production-grade shell and CLI scripts — Bash and Python. Use when authoring or reviewing any script, Makefile target, hook, CI step, or automation that takes input, does work, and reports a result. Enforces runtime arguments (not hardcoded paths), fail-closed error handling, progress/observable output, idempotency, algorithmic efficiency, and precise machine-readable results. Triggers — "write a script", "bash script", "make target", "automate", "cron job", "CLI tool", any `*.sh`/`scripts/*.py`. Pairs with clean-code (naming/structure), deployment-cicd (CI steps), observability (log hygiene), hook-authoring (coding-os hooks).
|
|
6
|
+
globs: ""
|
|
7
|
+
paths: []
|
|
8
|
+
last_reviewed: "2026-06-04"
|
|
9
|
+
versions_ref: versions.json
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Shell & CLI Scripting
|
|
13
|
+
|
|
14
|
+
A script is a **contract**: given inputs, do exactly one job, report a precise result, fail loud on anything unexpected. A script that hardcodes a path, swallows errors, or prints a paragraph the caller must parse is a liability — it breaks silently in the next environment and taxes every agent that runs it. This skill makes "robust, data-driven, observable" the default shape.
|
|
15
|
+
|
|
16
|
+
> Scaffold a compliant script instead of hand-writing the boilerplate:
|
|
17
|
+
> `python3 scripts/new_script.py --lang bash --name deploy --root .`
|
|
18
|
+
> Lint an existing one against the discipline:
|
|
19
|
+
> `bash scripts/lint_script.sh path/to/script.sh`
|
|
20
|
+
|
|
21
|
+
## The seven non-negotiables
|
|
22
|
+
|
|
23
|
+
Every script — Bash or Python — satisfies all seven. The checklist in [assets/script-checklist.md](assets/script-checklist.md) is the ship gate.
|
|
24
|
+
|
|
25
|
+
1. **Runtime arguments, never hardcoded.** Inputs come from flags with sane defaults. No literal machine paths, no baked-in hostnames, no magic constants buried in the body.
|
|
26
|
+
2. **Fail-closed.** Any unmet precondition or sub-command failure stops the script with a non-zero exit and a message — never continue on error.
|
|
27
|
+
3. **Idempotent.** Re-running is safe: detect already-done state, refuse to clobber (or require `--force`).
|
|
28
|
+
4. **Observable.** Progress to stderr for anything slow; a final, parseable result (one line or `--json`) on stdout.
|
|
29
|
+
5. **Precise output.** stdout is the *result* a caller consumes; stderr is *narration*. Never mix them.
|
|
30
|
+
6. **Algorithmically honest.** No O(n²) where a set/index is O(n). Stream large inputs; bound memory. State complexity when non-obvious.
|
|
31
|
+
7. **Documented header.** `PURPOSE / INPUT / OUTPUT / DEPENDENCIES / NOTES` at the top — the contract in five lines.
|
|
32
|
+
|
|
33
|
+
## Bash — the robust preamble (copy, don't retype)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
#!/usr/bin/env bash
|
|
37
|
+
# deploy.sh — PURPOSE: ... / INPUT: ... / OUTPUT: ... / DEPS: ... / NOTES: ...
|
|
38
|
+
set -euo pipefail # -e exit on error · -u unset var is error · -o pipefail catch piped failures
|
|
39
|
+
IFS=$'\n\t' # safe word-splitting (no space-splitting surprises)
|
|
40
|
+
|
|
41
|
+
cleanup() { rm -f "${_tmp:-}"; }
|
|
42
|
+
trap cleanup EXIT # run on ANY exit path — success, error, or signal
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Why each flag matters — bad→good:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Wrong — silent data loss: cd fails, rm runs in the WRONG directory
|
|
49
|
+
cd "$build_dir"
|
|
50
|
+
rm -rf ./*
|
|
51
|
+
|
|
52
|
+
# Correct — set -e aborts before rm if cd fails; quoting survives spaces
|
|
53
|
+
set -euo pipefail
|
|
54
|
+
cd "$build_dir" # aborts here if $build_dir is unset (-u) or missing (-e)
|
|
55
|
+
rm -rf -- "${build_dir:?build_dir required}"/*
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Wrong — pipefail off: the pipeline "succeeds" even though curl failed
|
|
60
|
+
curl -s "$url" | jq .version # exit 0 even on 404
|
|
61
|
+
|
|
62
|
+
# Correct
|
|
63
|
+
set -o pipefail
|
|
64
|
+
curl -fsS "$url" | jq .version # -f makes curl fail on HTTP error; pipefail propagates it
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Quoting + `grep` exit-code traps (the two that bite every script): always `"$var"`, and a `grep`/`grep -c` that matches nothing returns exit 1 — under `set -e` that kills the script. Guard it: `count=$(grep -c foo file || true)`. Full rules → [references/bash-robustness.md](references/bash-robustness.md).
|
|
68
|
+
|
|
69
|
+
## Arguments — `getopts` (Bash) / `argparse` (Python)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Bash — flags with defaults, a usage(), and a required-arg check
|
|
73
|
+
usage() { echo "usage: $0 --target <env> [--dry-run]" >&2; exit 2; }
|
|
74
|
+
target="" ; dry_run=0
|
|
75
|
+
while [[ $# -gt 0 ]]; do
|
|
76
|
+
case "$1" in
|
|
77
|
+
--target) target="${2:?--target needs a value}"; shift 2 ;;
|
|
78
|
+
--dry-run) dry_run=1; shift ;;
|
|
79
|
+
-h|--help) usage ;;
|
|
80
|
+
*) echo "unknown arg: $1" >&2; usage ;;
|
|
81
|
+
esac
|
|
82
|
+
done
|
|
83
|
+
[[ -n "$target" ]] || { echo "error: --target is required" >&2; usage; }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Python scripts use `argparse` with `--root` defaulting to a consumer-relative path (`src/backend`), never an absolute one. Full comparison + when to graduate from Bash to Python → [references/argument-parsing.md](references/argument-parsing.md).
|
|
87
|
+
|
|
88
|
+
## Progress + result discipline
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
log() { printf '%s\n' "$*" >&2; } # narration → stderr
|
|
92
|
+
log "[1/3] fetching..." # progress the caller can ignore
|
|
93
|
+
log "[2/3] transforming..."
|
|
94
|
+
printf '{"changed":%d,"skipped":%d}\n' "$changed" "$skipped" # result → stdout, parseable
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The rule that collapses agent cost: **emit the minimum the caller needs to decide the next step, not a transcript.** A script that prints one JSON line replaces ten tool calls the agent would otherwise spend re-deriving state. Quiet by default; `--verbose` opts into detail.
|
|
98
|
+
|
|
99
|
+
## When Bash, when Python
|
|
100
|
+
|
|
101
|
+
| Reach for Bash | Reach for Python |
|
|
102
|
+
|---|---|
|
|
103
|
+
| ≤ ~50 lines, glue of existing CLIs | parsing/transforming structured data (JSON, CSV) |
|
|
104
|
+
| process orchestration, file moves | non-trivial control flow, data structures |
|
|
105
|
+
| no arrays-of-structs, no math | needs tests, types, or stdlib beyond coreutils |
|
|
106
|
+
|
|
107
|
+
Past ~50 lines or the first associative-array-of-records, graduate to Python. A 200-line Bash script with nested `eval` is a maintenance trap — the line where you reach for `eval` is the line you should have been in Python.
|
|
108
|
+
|
|
109
|
+
## `make` targets
|
|
110
|
+
|
|
111
|
+
A Makefile target is a script too: `.PHONY` it, one job per target, `@` to quiet the echo, fail-closed (make stops on non-zero by default — don't `|| true` away real failures). Document with `## comment` so `make help` lists it.
|
|
112
|
+
|
|
113
|
+
## Anti-patterns (reject on sight)
|
|
114
|
+
|
|
115
|
+
- Hardcoded `/Users/...`, `/home/...`, or a literal hostname → take a flag.
|
|
116
|
+
- `set -e` absent, or defeated by a trailing `|| true` on a command whose failure matters.
|
|
117
|
+
- `cmd2` running after `cmd1` failed because there is no `&&` and no `set -e`.
|
|
118
|
+
- stdout polluted with progress so the caller can't parse the result.
|
|
119
|
+
- Re-running the script doubles the effect (not idempotent).
|
|
120
|
+
- Parsing `ls` output, or `for f in $(ls)` — use a glob or `find -print0 | while read -d ''`.
|
|
121
|
+
- `eval` on interpolated input — almost always a quoting bug or a Python signal.
|
|
122
|
+
|
|
123
|
+
## See also
|
|
124
|
+
|
|
125
|
+
- [references/bash-robustness.md](references/bash-robustness.md) — strict mode, traps, quoting, the `grep` exit trap.
|
|
126
|
+
- [references/argument-parsing.md](references/argument-parsing.md) — `getopts` vs `argparse`, the Bash→Python line.
|
|
127
|
+
- [assets/script-checklist.md](assets/script-checklist.md) — the ship gate.
|
|
128
|
+
- [docs/playbooks/skill-authoring.md](../../../docs/playbooks/skill-authoring.md) § scripts contract — why every skill's scripts obey this.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!-- domain:UNIVERSAL | layer:asset | ssot:false | updated:2026-06-04 -->
|
|
2
|
+
# Script Ship Checklist
|
|
3
|
+
|
|
4
|
+
Run before committing any script, hook, or `make` target. Every box ticked, or it does not ship.
|
|
5
|
+
|
|
6
|
+
## The seven non-negotiables
|
|
7
|
+
- [ ] **Arguments, not constants** — every input is a flag with a sane default; zero hardcoded machine paths / hosts / magic numbers.
|
|
8
|
+
- [ ] **Fail-closed** — Bash: `set -euo pipefail`. Python: explicit non-zero exit on any unmet precondition. No `|| true` on a failure that matters.
|
|
9
|
+
- [ ] **Idempotent** — re-running is safe; already-done state is detected; clobbering requires `--force`.
|
|
10
|
+
- [ ] **Observable** — progress to stderr for slow work; final parseable result (one line or `--json`) on stdout.
|
|
11
|
+
- [ ] **stdout = result, stderr = narration** — never mixed.
|
|
12
|
+
- [ ] **Algorithmically honest** — no O(n²) where a set/index works; large inputs streamed; memory bounded.
|
|
13
|
+
- [ ] **Header present** — `PURPOSE / INPUT / OUTPUT / DEPENDENCIES / NOTES`.
|
|
14
|
+
|
|
15
|
+
## Bash-specific
|
|
16
|
+
- [ ] Shebang `#!/usr/bin/env bash`.
|
|
17
|
+
- [ ] `IFS=$'\n\t'` when word-splitting matters.
|
|
18
|
+
- [ ] `trap cleanup EXIT` if any temp file / lock is created.
|
|
19
|
+
- [ ] All expansions quoted: `"$var"`, `"${arr[@]}"`, `"$@"`.
|
|
20
|
+
- [ ] `grep`/`grep -c` that may match nothing wrapped with `|| true`.
|
|
21
|
+
- [ ] No `for f in $(ls ...)` — glob or `find -print0`.
|
|
22
|
+
- [ ] `shellcheck -S warning` clean; `shfmt` formatted.
|
|
23
|
+
|
|
24
|
+
## Python-specific
|
|
25
|
+
- [ ] `argparse` with explicit `main(argv)` (testable).
|
|
26
|
+
- [ ] `--root` / path defaults are consumer-relative, never absolute.
|
|
27
|
+
- [ ] stdlib-only unless a dependency is justified.
|
|
28
|
+
- [ ] Pure logic separated from IO so it unit-tests without network/fs.
|
|
29
|
+
|
|
30
|
+
## Verify
|
|
31
|
+
- [ ] `bash scripts/lint_script.sh <file>` → `0 issue(s)`.
|
|
32
|
+
- [ ] Ran it twice — second run is a no-op (idempotent).
|
|
33
|
+
- [ ] `make verify-hooks` green (for hooks / `src/core/**` scripts).
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<!-- domain:UNIVERSAL | layer:reference | ssot:true | updated:2026-06-04 -->
|
|
2
|
+
# Argument Parsing — `getopts`, manual `case`, and `argparse`
|
|
3
|
+
|
|
4
|
+
> P: How to take runtime arguments correctly in Bash and Python, and exactly when to abandon Bash for Python.
|
|
5
|
+
> R: Any script that takes a flag, a path, or a mode.
|
|
6
|
+
> S: A zero-argument one-shot (rare — most "one-shots" grow a flag within a week).
|
|
7
|
+
> N: [SKILL.md](../SKILL.md), [bash-robustness.md](bash-robustness.md)
|
|
8
|
+
|
|
9
|
+
> Nav: [Skill](../SKILL.md)
|
|
10
|
+
|
|
11
|
+
## Bash — manual `while/case` (preferred for long flags)
|
|
12
|
+
|
|
13
|
+
`getopts` only handles single-letter flags (`-t`) and no `--long` forms. For readable scripts use a manual loop:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
usage() { echo "usage: $0 --target <env> [--workers N] [--dry-run]" >&2; exit 2; }
|
|
17
|
+
target="" ; workers=4 ; dry_run=0
|
|
18
|
+
while [[ $# -gt 0 ]]; do
|
|
19
|
+
case "$1" in
|
|
20
|
+
--target) target="${2:?--target needs a value}"; shift 2 ;;
|
|
21
|
+
--workers) workers="${2:?--workers needs a value}"; shift 2 ;;
|
|
22
|
+
--dry-run) dry_run=1; shift ;;
|
|
23
|
+
-h|--help) usage ;;
|
|
24
|
+
--) shift; break ;; # explicit end-of-flags
|
|
25
|
+
-*) echo "unknown flag: $1" >&2; usage ;;
|
|
26
|
+
*) break ;; # first positional
|
|
27
|
+
esac
|
|
28
|
+
done
|
|
29
|
+
[[ -n "$target" ]] || { echo "error: --target required" >&2; usage; }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Three rules: every flag has a default, a missing required flag prints `usage` and exits non-zero, and `${2:?msg}` guarantees a value-taking flag was actually given one.
|
|
33
|
+
|
|
34
|
+
### `getopts` — when single-letter is enough
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
while getopts ":t:w:nh" opt; do
|
|
38
|
+
case "$opt" in
|
|
39
|
+
t) target="$OPTARG" ;;
|
|
40
|
+
w) workers="$OPTARG" ;;
|
|
41
|
+
n) dry_run=1 ;;
|
|
42
|
+
h) usage ;;
|
|
43
|
+
:) echo "-$OPTARG needs a value" >&2; usage ;;
|
|
44
|
+
\?) echo "unknown -$OPTARG" >&2; usage ;;
|
|
45
|
+
esac
|
|
46
|
+
done
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Defaults must be consumer-relative, never absolute
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Wrong — breaks on every machine but the author's
|
|
53
|
+
root="/Users/me/project/src/backend"
|
|
54
|
+
|
|
55
|
+
# Correct — relative default, overridable
|
|
56
|
+
root="${1:-src/backend}"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Python mirror: `parser.add_argument("--root", default="src/backend", type=Path)`. A script that bakes in `/Users/...` or `/home/...` fails the lint and the review.
|
|
60
|
+
|
|
61
|
+
## Python — `argparse` (the default past ~50 lines)
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
parser = argparse.ArgumentParser(description=__doc__.split("\n")[0])
|
|
65
|
+
parser.add_argument("--root", default="src/backend", type=Path)
|
|
66
|
+
parser.add_argument("--workers", default=4, type=int)
|
|
67
|
+
parser.add_argument("--dry-run", action="store_true")
|
|
68
|
+
parser.add_argument("--json", action="store_true", dest="as_json")
|
|
69
|
+
args = parser.parse_args(argv) # pass argv explicitly so it's testable
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`description=__doc__.split("\n")[0]` reuses the module docstring's first line as `--help` text — one source for both. Take `argv: list[str]` in `main(argv)` rather than reading `sys.argv` inside, so the parser is unit-testable.
|
|
73
|
+
|
|
74
|
+
## The Bash → Python line
|
|
75
|
+
|
|
76
|
+
Graduate to Python the moment **any** of these appears:
|
|
77
|
+
|
|
78
|
+
- structured data in/out (JSON, CSV, an API response you must field-access);
|
|
79
|
+
- an array of records / an associative array of structs;
|
|
80
|
+
- arithmetic beyond `$(( ))` increments;
|
|
81
|
+
- you want unit tests or type hints;
|
|
82
|
+
- the script crosses ~50 lines or you reach for `eval`.
|
|
83
|
+
|
|
84
|
+
A 200-line Bash script with nested `eval` and string-built JSON is a rewrite waiting to happen. Spend the 20 minutes now.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<!-- domain:UNIVERSAL | layer:reference | ssot:true | updated:2026-06-04 -->
|
|
2
|
+
# Bash Robustness — Strict Mode, Traps, Quoting
|
|
3
|
+
|
|
4
|
+
> P: The exact failure modes strict mode prevents and the idioms that survive spaces, empty matches, and signals.
|
|
5
|
+
> R: Writing or reviewing any Bash longer than a one-liner.
|
|
6
|
+
> S: Pure Python scripts — see [argument-parsing.md](argument-parsing.md) for the Bash→Python line.
|
|
7
|
+
> N: [SKILL.md](../SKILL.md), [script-checklist.md](../assets/script-checklist.md)
|
|
8
|
+
|
|
9
|
+
> Nav: [Skill](../SKILL.md)
|
|
10
|
+
|
|
11
|
+
## Strict mode — what each flag actually prevents
|
|
12
|
+
|
|
13
|
+
| Flag | Without it | With it |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `set -e` | a failed command is ignored; the script ploughs on with bad state | first non-zero exit aborts (except in conditionals) |
|
|
16
|
+
| `set -u` | a typo'd `$VARNAME` expands to empty → `rm -rf $DIR/` becomes `rm -rf /` | unset variable is a hard error |
|
|
17
|
+
| `set -o pipefail` | `false | true` exits 0 — a failed `curl` in a pipe looks successful | the pipeline's exit is the last non-zero |
|
|
18
|
+
| `IFS=$'\n\t'` | word-splitting on spaces mangles filenames with spaces | splits only on newline/tab |
|
|
19
|
+
|
|
20
|
+
`set -euo pipefail` is the floor. It is not magic — know its three escape hatches:
|
|
21
|
+
|
|
22
|
+
1. **Conditionals are exempt.** `if grep -q x f; then` does not abort on no-match — that is correct. But a *bare* `grep -q x f` on its own line WILL abort under `-e` when there is no match.
|
|
23
|
+
2. **`local x=$(cmd)` hides the exit code** — `local` returns 0, masking `cmd`'s failure. Split: `local x; x=$(cmd)`.
|
|
24
|
+
3. **`cmd || true`** deliberately swallows failure — use ONLY when the failure is genuinely fine (e.g. a `grep -c` that legitimately matches nothing). Never use it to silence a failure that matters.
|
|
25
|
+
|
|
26
|
+
## The `grep` / `find` exit-code trap
|
|
27
|
+
|
|
28
|
+
`grep` returns exit 1 when it matches nothing; `grep -c` likewise. Under `set -e` that aborts the script even though "zero matches" is a valid answer.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Wrong — aborts the whole script when the pattern is simply absent
|
|
32
|
+
count=$(grep -c ERROR app.log)
|
|
33
|
+
|
|
34
|
+
# Correct — capture the count, tolerate zero matches
|
|
35
|
+
count=$(grep -c ERROR app.log || true)
|
|
36
|
+
[[ -z "$count" ]] && count=0
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Traps — cleanup on every exit path
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
_tmp="$(mktemp)"
|
|
43
|
+
cleanup() { rm -f "$_tmp"; }
|
|
44
|
+
trap cleanup EXIT # runs on success, error (-e), AND Ctrl-C / SIGTERM
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`EXIT` covers normal return + error abort + most signals. Add `trap 'cleanup; exit 130' INT` only when you need a distinct exit code per signal. Never leave temp files behind for the next run to trip over.
|
|
48
|
+
|
|
49
|
+
## Quoting — the rule with no exceptions
|
|
50
|
+
|
|
51
|
+
Always `"$var"`, always `"${array[@]}"`, always `"$@"` (not `$*`). Unquoted expansion re-splits on `IFS` and glob-expands — the source of "works on my machine, deletes your repo on theirs".
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Wrong — a path with a space becomes two arguments
|
|
55
|
+
cp $src $dst
|
|
56
|
+
|
|
57
|
+
# Correct
|
|
58
|
+
cp -- "$src" "$dst" # -- stops option parsing if $src starts with '-'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Iterating files — never parse `ls`
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Wrong — breaks on spaces, newlines, globs in names
|
|
65
|
+
for f in $(ls *.log); do ... done
|
|
66
|
+
|
|
67
|
+
# Correct — NUL-delimited, survives any filename
|
|
68
|
+
while IFS= read -r -d '' f; do
|
|
69
|
+
process "$f"
|
|
70
|
+
done < <(find . -name '*.log' -print0)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Tooling
|
|
74
|
+
|
|
75
|
+
- **shellcheck** (`koalaman/shellcheck`, pinned in [versions.json](../versions.json)) — static analysis; treat warnings as errors in CI. `make verify-hooks` runs it across the repo's hooks.
|
|
76
|
+
- **shfmt** (`mvdan/sh`) — deterministic formatter; `shfmt -i 2 -w script.sh`.
|
|
77
|
+
|
|
78
|
+
Run both in the script's CI step; a script that shellcheck flags is not shippable.
|