@cyanautomation/kaseki-agent 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +54 -0
- package/.eslintignore +11 -0
- package/.eslintrc.json +95 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +53 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +53 -0
- package/.github/ISSUE_TEMPLATE/security.md +51 -0
- package/.github/PULL_REQUEST_TEMPLATE/default.md +71 -0
- package/.github/dependabot.yml +38 -0
- package/.github/skills/dependency-cache-optimization/SKILL.md +526 -0
- package/.github/skills/docker-image-management/SKILL.md +532 -0
- package/.github/skills/frontend-design/SKILL.md +782 -0
- package/.github/skills/prompt-engineering/SKILL.md +360 -0
- package/.github/skills/quality-gate-config/SKILL.md +591 -0
- package/.github/skills/result-report-analysis/SKILL.md +576 -0
- package/.github/skills/test-automation/SKILL.md +593 -0
- package/.github/skills/workflow-diagnosis/SKILL.md +468 -0
- package/.github/workflows/build-docker-image.yml +453 -0
- package/.github/workflows/release.yml +68 -0
- package/.releaserc.json +135 -0
- package/CHANGELOG.md +117 -0
- package/CLAUDE.md +336 -0
- package/CONTRIBUTING.md +339 -0
- package/Dockerfile +217 -0
- package/README.md +1527 -0
- package/STYLE.md +521 -0
- package/add-js-extensions.d.ts +9 -0
- package/add-js-extensions.d.ts.map +1 -0
- package/add-js-extensions.js.map +1 -0
- package/dist/add-js-extensions.d.ts +9 -0
- package/dist/add-js-extensions.d.ts.map +1 -0
- package/dist/add-js-extensions.js +52 -0
- package/dist/add-js-extensions.js.map +1 -0
- package/dist/ansi-colors.d.ts +26 -0
- package/dist/ansi-colors.d.ts.map +1 -0
- package/dist/ansi-colors.js +51 -0
- package/dist/ansi-colors.js.map +1 -0
- package/dist/cli/BaseCommand.d.ts +18 -0
- package/dist/cli/BaseCommand.d.ts.map +1 -0
- package/dist/cli/BaseCommand.js +31 -0
- package/dist/cli/BaseCommand.js.map +1 -0
- package/dist/cli/KasekiCLI.d.ts +30 -0
- package/dist/cli/KasekiCLI.d.ts.map +1 -0
- package/dist/cli/KasekiCLI.js +134 -0
- package/dist/cli/KasekiCLI.js.map +1 -0
- package/dist/cli/commands/ConfigCommand.d.ts +13 -0
- package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
- package/dist/cli/commands/ConfigCommand.js +131 -0
- package/dist/cli/commands/ConfigCommand.js.map +1 -0
- package/dist/cli/commands/DoctorCommand.d.ts +45 -0
- package/dist/cli/commands/DoctorCommand.d.ts.map +1 -0
- package/dist/cli/commands/DoctorCommand.js +309 -0
- package/dist/cli/commands/DoctorCommand.js.map +1 -0
- package/dist/cli/commands/ListCommand.d.ts +9 -0
- package/dist/cli/commands/ListCommand.d.ts.map +1 -0
- package/dist/cli/commands/ListCommand.js +81 -0
- package/dist/cli/commands/ListCommand.js.map +1 -0
- package/dist/cli/commands/ReportCommand.d.ts +9 -0
- package/dist/cli/commands/ReportCommand.d.ts.map +1 -0
- package/dist/cli/commands/ReportCommand.js +98 -0
- package/dist/cli/commands/ReportCommand.js.map +1 -0
- package/dist/cli/commands/RunCommand.d.ts +13 -0
- package/dist/cli/commands/RunCommand.d.ts.map +1 -0
- package/dist/cli/commands/RunCommand.js +191 -0
- package/dist/cli/commands/RunCommand.js.map +1 -0
- package/dist/cli/commands/SecretsCommand.d.ts +9 -0
- package/dist/cli/commands/SecretsCommand.d.ts.map +1 -0
- package/dist/cli/commands/SecretsCommand.js +109 -0
- package/dist/cli/commands/SecretsCommand.js.map +1 -0
- package/dist/cli/commands/ServeCommand.d.ts +9 -0
- package/dist/cli/commands/ServeCommand.d.ts.map +1 -0
- package/dist/cli/commands/ServeCommand.js +50 -0
- package/dist/cli/commands/ServeCommand.js.map +1 -0
- package/dist/cli/commands/SetupCommand.d.ts +42 -0
- package/dist/cli/commands/SetupCommand.d.ts.map +1 -0
- package/dist/cli/commands/SetupCommand.js +249 -0
- package/dist/cli/commands/SetupCommand.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +130 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/ConfigManager.d.ts +395 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +446 -0
- package/dist/config/ConfigManager.js.map +1 -0
- package/dist/docker/DockerManager.d.ts +69 -0
- package/dist/docker/DockerManager.d.ts.map +1 -0
- package/dist/docker/DockerManager.js +266 -0
- package/dist/docker/DockerManager.js.map +1 -0
- package/dist/event-aggregator.d.ts +71 -0
- package/dist/event-aggregator.d.ts.map +1 -0
- package/dist/event-aggregator.js +95 -0
- package/dist/event-aggregator.js.map +1 -0
- package/dist/github-app-token.d.ts +16 -0
- package/dist/github-app-token.d.ts.map +1 -0
- package/dist/github-app-token.js +148 -0
- package/dist/github-app-token.js.map +1 -0
- package/dist/idempotency-store.d.ts +61 -0
- package/dist/idempotency-store.d.ts.map +1 -0
- package/dist/idempotency-store.js +321 -0
- package/dist/idempotency-store.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/instance/InstanceManager.d.ts +81 -0
- package/dist/instance/InstanceManager.d.ts.map +1 -0
- package/dist/instance/InstanceManager.js +220 -0
- package/dist/instance/InstanceManager.js.map +1 -0
- package/dist/instance-metadata-reader.d.ts +48 -0
- package/dist/instance-metadata-reader.d.ts.map +1 -0
- package/dist/instance-metadata-reader.js +94 -0
- package/dist/instance-metadata-reader.js.map +1 -0
- package/dist/instance-state-derivation.d.ts +42 -0
- package/dist/instance-state-derivation.d.ts.map +1 -0
- package/dist/instance-state-derivation.js +133 -0
- package/dist/instance-state-derivation.js.map +1 -0
- package/dist/job-scheduler.d.ts +124 -0
- package/dist/job-scheduler.d.ts.map +1 -0
- package/dist/job-scheduler.js +992 -0
- package/dist/job-scheduler.js.map +1 -0
- package/dist/kaseki-api-client.d.ts +89 -0
- package/dist/kaseki-api-client.d.ts.map +1 -0
- package/dist/kaseki-api-client.js +405 -0
- package/dist/kaseki-api-client.js.map +1 -0
- package/dist/kaseki-api-config.d.ts +34 -0
- package/dist/kaseki-api-config.d.ts.map +1 -0
- package/dist/kaseki-api-config.js +113 -0
- package/dist/kaseki-api-config.js.map +1 -0
- package/dist/kaseki-api-routes.d.ts +13 -0
- package/dist/kaseki-api-routes.d.ts.map +1 -0
- package/dist/kaseki-api-routes.js +559 -0
- package/dist/kaseki-api-routes.js.map +1 -0
- package/dist/kaseki-api-service-wrapper.d.ts +43 -0
- package/dist/kaseki-api-service-wrapper.d.ts.map +1 -0
- package/dist/kaseki-api-service-wrapper.js +150 -0
- package/dist/kaseki-api-service-wrapper.js.map +1 -0
- package/dist/kaseki-api-service.d.ts +16 -0
- package/dist/kaseki-api-service.d.ts.map +1 -0
- package/dist/kaseki-api-service.js +143 -0
- package/dist/kaseki-api-service.js.map +1 -0
- package/dist/kaseki-api-types.d.ts +440 -0
- package/dist/kaseki-api-types.d.ts.map +1 -0
- package/dist/kaseki-api-types.js +64 -0
- package/dist/kaseki-api-types.js.map +1 -0
- package/dist/kaseki-cli-lib.d.ts +219 -0
- package/dist/kaseki-cli-lib.d.ts.map +1 -0
- package/dist/kaseki-cli-lib.js +523 -0
- package/dist/kaseki-cli-lib.js.map +1 -0
- package/dist/kaseki-cli.d.ts +38 -0
- package/dist/kaseki-cli.d.ts.map +1 -0
- package/dist/kaseki-cli.js +559 -0
- package/dist/kaseki-cli.js.map +1 -0
- package/dist/kaseki-report.d.ts +3 -0
- package/dist/kaseki-report.d.ts.map +1 -0
- package/dist/kaseki-report.js +140 -0
- package/dist/kaseki-report.js.map +1 -0
- package/dist/lib/subprocess-helpers.d.ts +98 -0
- package/dist/lib/subprocess-helpers.d.ts.map +1 -0
- package/dist/lib/subprocess-helpers.js +136 -0
- package/dist/lib/subprocess-helpers.js.map +1 -0
- package/dist/logger.d.ts +39 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +79 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +19 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +59 -0
- package/dist/metrics.js.map +1 -0
- package/dist/middleware/job-lookup.d.ts +27 -0
- package/dist/middleware/job-lookup.d.ts.map +1 -0
- package/dist/middleware/job-lookup.js +28 -0
- package/dist/middleware/job-lookup.js.map +1 -0
- package/dist/pi-event-filter.d.ts +3 -0
- package/dist/pi-event-filter.d.ts.map +1 -0
- package/dist/pi-event-filter.js +126 -0
- package/dist/pi-event-filter.js.map +1 -0
- package/dist/pi-progress-stream.d.ts +3 -0
- package/dist/pi-progress-stream.d.ts.map +1 -0
- package/dist/pi-progress-stream.js +205 -0
- package/dist/pi-progress-stream.js.map +1 -0
- package/dist/pi-progress-summarizer.d.ts +61 -0
- package/dist/pi-progress-summarizer.d.ts.map +1 -0
- package/dist/pi-progress-summarizer.js +246 -0
- package/dist/pi-progress-summarizer.js.map +1 -0
- package/dist/pre-flight-validator.d.ts +72 -0
- package/dist/pre-flight-validator.d.ts.map +1 -0
- package/dist/pre-flight-validator.js +513 -0
- package/dist/pre-flight-validator.js.map +1 -0
- package/dist/progress-stream-utils.d.ts +3 -0
- package/dist/progress-stream-utils.d.ts.map +1 -0
- package/dist/progress-stream-utils.js +15 -0
- package/dist/progress-stream-utils.js.map +1 -0
- package/dist/result-cache.d.ts +52 -0
- package/dist/result-cache.d.ts.map +1 -0
- package/dist/result-cache.js +134 -0
- package/dist/result-cache.js.map +1 -0
- package/dist/routes/artifact-routes.d.ts +10 -0
- package/dist/routes/artifact-routes.d.ts.map +1 -0
- package/dist/routes/artifact-routes.js +126 -0
- package/dist/routes/artifact-routes.js.map +1 -0
- package/dist/routes/log-routes.d.ts +8 -0
- package/dist/routes/log-routes.d.ts.map +1 -0
- package/dist/routes/log-routes.js +345 -0
- package/dist/routes/log-routes.js.map +1 -0
- package/dist/routes/status-routes.d.ts +8 -0
- package/dist/routes/status-routes.d.ts.map +1 -0
- package/dist/routes/status-routes.js +82 -0
- package/dist/routes/status-routes.js.map +1 -0
- package/dist/routes/webhook-routes.d.ts +6 -0
- package/dist/routes/webhook-routes.d.ts.map +1 -0
- package/dist/routes/webhook-routes.js +86 -0
- package/dist/routes/webhook-routes.js.map +1 -0
- package/dist/run-artifact-metadata-cache.d.ts +42 -0
- package/dist/run-artifact-metadata-cache.d.ts.map +1 -0
- package/dist/run-artifact-metadata-cache.js +139 -0
- package/dist/run-artifact-metadata-cache.js.map +1 -0
- package/dist/secret-value-cache.d.ts +13 -0
- package/dist/secret-value-cache.d.ts.map +1 -0
- package/dist/secret-value-cache.js +44 -0
- package/dist/secret-value-cache.js.map +1 -0
- package/dist/secrets/SecretsManager.d.ts +80 -0
- package/dist/secrets/SecretsManager.d.ts.map +1 -0
- package/dist/secrets/SecretsManager.js +306 -0
- package/dist/secrets/SecretsManager.js.map +1 -0
- package/dist/test-utils.d.ts +55 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +48 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/timestamp-tracker.d.ts +75 -0
- package/dist/timestamp-tracker.d.ts.map +1 -0
- package/dist/timestamp-tracker.js +121 -0
- package/dist/timestamp-tracker.js.map +1 -0
- package/dist/utils/failure-artifact-writer.d.ts +29 -0
- package/dist/utils/failure-artifact-writer.d.ts.map +1 -0
- package/dist/utils/failure-artifact-writer.js +157 -0
- package/dist/utils/failure-artifact-writer.js.map +1 -0
- package/dist/utils/file-helpers.d.ts +41 -0
- package/dist/utils/file-helpers.d.ts.map +1 -0
- package/dist/utils/file-helpers.js +143 -0
- package/dist/utils/file-helpers.js.map +1 -0
- package/dist/utils/http-client-factory.d.ts +46 -0
- package/dist/utils/http-client-factory.d.ts.map +1 -0
- package/dist/utils/http-client-factory.js +114 -0
- package/dist/utils/http-client-factory.js.map +1 -0
- package/dist/utils/progress-normalizer.d.ts +13 -0
- package/dist/utils/progress-normalizer.d.ts.map +1 -0
- package/dist/utils/progress-normalizer.js +57 -0
- package/dist/utils/progress-normalizer.js.map +1 -0
- package/dist/utils/response-helpers.d.ts +34 -0
- package/dist/utils/response-helpers.d.ts.map +1 -0
- package/dist/utils/response-helpers.js +78 -0
- package/dist/utils/response-helpers.js.map +1 -0
- package/dist/utils/route-helpers.d.ts +17 -0
- package/dist/utils/route-helpers.d.ts.map +1 -0
- package/dist/utils/route-helpers.js +22 -0
- package/dist/utils/route-helpers.js.map +1 -0
- package/dist/utils/status-response-builder.d.ts +23 -0
- package/dist/utils/status-response-builder.d.ts.map +1 -0
- package/dist/utils/status-response-builder.js +144 -0
- package/dist/utils/status-response-builder.js.map +1 -0
- package/dist/utils/type-guards.d.ts +37 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +45 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/utf8-helpers.d.ts +32 -0
- package/dist/utils/utf8-helpers.d.ts.map +1 -0
- package/dist/utils/utf8-helpers.js +97 -0
- package/dist/utils/utf8-helpers.js.map +1 -0
- package/dist/utils/webhook-event-builder.d.ts +26 -0
- package/dist/utils/webhook-event-builder.d.ts.map +1 -0
- package/dist/utils/webhook-event-builder.js +77 -0
- package/dist/utils/webhook-event-builder.js.map +1 -0
- package/dist/webhook-manager.d.ts +56 -0
- package/dist/webhook-manager.d.ts.map +1 -0
- package/dist/webhook-manager.js +359 -0
- package/dist/webhook-manager.js.map +1 -0
- package/docker/workspace-cache/package-lock.json +13 -0
- package/docker/workspace-cache/package.json +7 -0
- package/docker-compose.yml +53 -0
- package/docs/API.md +708 -0
- package/docs/BACKLOG.md +19 -0
- package/docs/BUILD_STRATEGY.md +404 -0
- package/docs/CLI.md +569 -0
- package/docs/DEPLOYMENT.md +521 -0
- package/docs/DEVELOPMENT.md +459 -0
- package/docs/DOCKER_SETUP.md +522 -0
- package/docs/ENHANCED_PROGRESS_LOGS.md +264 -0
- package/docs/IMPLEMENTATION_SUMMARY.md +549 -0
- package/docs/INTEGRATION_EXAMPLE.md +217 -0
- package/docs/NPM_SETUP.md +468 -0
- package/docs/PHASE1-4_IMPLEMENTATION.md +302 -0
- package/docs/PHASE1_COMPLETION.md +192 -0
- package/docs/PHASE2_COMPLETION.md +134 -0
- package/docs/PHASE6_MIGRATION.md +392 -0
- package/docs/PRINTF_SAFETY_FIX.md +282 -0
- package/docs/QUALITY_GATES.md +369 -0
- package/docs/SETUP_GUIDE.md +482 -0
- package/docs/TASK_PROMPT_TEMPLATES.md +533 -0
- package/docs/VALIDATION_FIX.md +139 -0
- package/docs/VERIFICATION_CHECKLIST.md +335 -0
- package/docs/repo-maturity.md +760 -0
- package/fix-tests.d.ts +9 -0
- package/fix-tests.d.ts.map +1 -0
- package/fix-tests.js.map +1 -0
- package/fix-tests.ts +53 -0
- package/jest.config.ts +31 -0
- package/kaseki +183 -0
- package/kaseki-agent.sh +1961 -0
- package/ops/logrotate/kaseki +10 -0
- package/package.json +83 -0
- package/perf/README.md +54 -0
- package/perf/pi-event-filter.benchmark.test.ts +98 -0
- package/run-kaseki-json.test.sh +106 -0
- package/run-kaseki.sh +990 -0
- package/scripts/allowlist-helper.sh +56 -0
- package/scripts/cleanup-kaseki.sh +168 -0
- package/scripts/deploy-pi-template.sh +293 -0
- package/scripts/docker-entrypoint.sh +71 -0
- package/scripts/dry-run-allowlist.sh +161 -0
- package/scripts/kaseki-activate.sh +396 -0
- package/scripts/kaseki-api.service +62 -0
- package/scripts/kaseki-container-entrypoint-wrapper.sh +119 -0
- package/scripts/kaseki-container-setup-remote.sh +172 -0
- package/scripts/kaseki-container-setup.sh +193 -0
- package/scripts/kaseki-healthcheck.sh +95 -0
- package/scripts/kaseki-install.sh +50 -0
- package/scripts/kaseki-maturity-score.sh +291 -0
- package/scripts/kaseki-performance-metrics.sh +122 -0
- package/scripts/kaseki-preflight.sh +270 -0
- package/scripts/kaseki-setup.sh +265 -0
- package/scripts/pi-setup-remote.sh +213 -0
- package/scripts/setup-github-labels.sh +42 -0
- package/scripts/suggest-allowlist.sh +68 -0
- package/scripts/templates/MULTI_HOST_DISTRIBUTED.md +337 -0
- package/scripts/templates/REST_API_SERVICE.md +490 -0
- package/scripts/templates/SINGLE_HOST_CLI.md +194 -0
- package/scripts/test-github-app.sh +248 -0
- package/src/add-js-extensions.ts +61 -0
- package/src/ansi-colors.test.ts +62 -0
- package/src/ansi-colors.ts +67 -0
- package/src/cli/BaseCommand.ts +40 -0
- package/src/cli/KasekiCLI.ts +154 -0
- package/src/cli/commands/ConfigCommand.ts +145 -0
- package/src/cli/commands/DoctorCommand.ts +329 -0
- package/src/cli/commands/ListCommand.ts +105 -0
- package/src/cli/commands/ReportCommand.ts +110 -0
- package/src/cli/commands/RunCommand.ts +218 -0
- package/src/cli/commands/SecretsCommand.ts +120 -0
- package/src/cli/commands/ServeCommand.ts +62 -0
- package/src/cli/commands/SetupCommand.ts +301 -0
- package/src/cli.ts +138 -0
- package/src/config/ConfigManager.ts +476 -0
- package/src/docker/DockerManager.ts +319 -0
- package/src/docker-entrypoint-packaging.test.ts +33 -0
- package/src/event-aggregator.test.ts +117 -0
- package/src/event-aggregator.ts +126 -0
- package/src/github-app-token.ts +215 -0
- package/src/idempotency-store.test.ts +117 -0
- package/src/idempotency-store.ts +385 -0
- package/src/index.ts +89 -0
- package/src/instance/InstanceManager.ts +285 -0
- package/src/instance-metadata-reader.test.ts +190 -0
- package/src/instance-metadata-reader.ts +129 -0
- package/src/instance-state-derivation.test.ts +263 -0
- package/src/instance-state-derivation.ts +148 -0
- package/src/job-scheduler.test.ts +1236 -0
- package/src/job-scheduler.ts +1117 -0
- package/src/kaseki-api-client.ts +488 -0
- package/src/kaseki-api-config.test.ts +315 -0
- package/src/kaseki-api-config.ts +175 -0
- package/src/kaseki-api-routes.test.ts +1615 -0
- package/src/kaseki-api-routes.ts +643 -0
- package/src/kaseki-api-service-wrapper.ts +188 -0
- package/src/kaseki-api-service.test.ts +418 -0
- package/src/kaseki-api-service.ts +192 -0
- package/src/kaseki-api-types.ts +320 -0
- package/src/kaseki-cli-lib.test.ts +552 -0
- package/src/kaseki-cli-lib.ts +760 -0
- package/src/kaseki-cli.ts +682 -0
- package/src/kaseki-report.test.ts +118 -0
- package/src/kaseki-report.ts +192 -0
- package/src/lib/subprocess-helpers.ts +177 -0
- package/src/logger.ts +114 -0
- package/src/metrics.ts +66 -0
- package/src/middleware/job-lookup.test.ts +113 -0
- package/src/middleware/job-lookup.ts +45 -0
- package/src/pi-event-filter.test.ts +183 -0
- package/src/pi-event-filter.ts +183 -0
- package/src/pi-progress-stream.ts +287 -0
- package/src/pi-progress-summarizer.test.ts +302 -0
- package/src/pi-progress-summarizer.ts +287 -0
- package/src/pre-flight-validator.test.ts +512 -0
- package/src/pre-flight-validator.ts +618 -0
- package/src/progress-stream-utils.test.ts +35 -0
- package/src/progress-stream-utils.ts +14 -0
- package/src/result-cache.test.ts +195 -0
- package/src/result-cache.ts +181 -0
- package/src/routes/artifact-routes.ts +169 -0
- package/src/routes/log-routes.ts +391 -0
- package/src/routes/status-routes.ts +92 -0
- package/src/routes/webhook-routes.ts +97 -0
- package/src/run-artifact-metadata-cache.test.ts +80 -0
- package/src/run-artifact-metadata-cache.ts +184 -0
- package/src/secret-value-cache.test.ts +66 -0
- package/src/secret-value-cache.ts +55 -0
- package/src/secrets/SecretsManager.ts +343 -0
- package/src/test-utils.ts +81 -0
- package/src/timestamp-tracker.test.ts +134 -0
- package/src/timestamp-tracker.ts +132 -0
- package/src/utils/failure-artifact-writer.ts +187 -0
- package/src/utils/file-helpers.test.ts +235 -0
- package/src/utils/file-helpers.ts +150 -0
- package/src/utils/http-client-factory.test.ts +245 -0
- package/src/utils/http-client-factory.ts +157 -0
- package/src/utils/progress-normalizer.test.ts +442 -0
- package/src/utils/progress-normalizer.ts +68 -0
- package/src/utils/response-helpers.test.ts +122 -0
- package/src/utils/response-helpers.ts +101 -0
- package/src/utils/route-helpers.ts +30 -0
- package/src/utils/status-response-builder.ts +159 -0
- package/src/utils/type-guards.ts +52 -0
- package/src/utils/utf8-helpers.ts +102 -0
- package/src/utils/webhook-event-builder.test.ts +143 -0
- package/src/utils/webhook-event-builder.ts +87 -0
- package/src/webhook-manager.test.ts +152 -0
- package/src/webhook-manager.ts +445 -0
- package/templates/allowlist-api-route.txt +7 -0
- package/templates/allowlist-comprehensive.txt +8 -0
- package/templates/allowlist-parser-fix.txt +6 -0
- package/templates/allowlist-ui-component.txt +9 -0
- package/templates/allowlist-utility.txt +9 -0
- package/test/actual-model-metadata.test.sh +102 -0
- package/test/dry-run.test.sh +131 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-0.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-1.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-invalid.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-str-0.json +1 -0
- package/test/fixtures/kaseki-report-exit-codes/metadata-exit-str-1.json +1 -0
- package/test/kaseki-api.integration.test.sh +165 -0
- package/test/pi-event-filter-failure.test.sh +83 -0
- package/test/printf-safety-focused.test.sh +99 -0
- package/test/printf-safety-results/results/restoration.jsonl +10 -0
- package/test/printf-safety-results/results/test.jsonl +0 -0
- package/test/printf-safety.test.sh +297 -0
- package/test/validation-fix.test.sh +79 -0
- package/test/validation-integration.test.sh +109 -0
- package/tests/allowlist-glob.test.sh +61 -0
- package/tests/dependency-cache-key.test.sh +48 -0
- package/tests/dependency-restore-mode.test.sh +48 -0
- package/tests/doctor-template-parity.test.sh +95 -0
- package/tests/github-operations.test.sh +142 -0
- package/tests/npm-install-flags.test.sh +58 -0
- package/tests/quality-gates.test.sh +178 -0
- package/tests/repo-memory.test.sh +103 -0
- package/tests/restore-disallowed-changes.test.sh +80 -0
- package/tests/validation-missing-npm-scripts.test.sh +93 -0
- package/tests/validation-strict-mode.test.sh +118 -0
- package/tsconfig.changed.json +7 -0
- package/tsconfig.json +39 -0
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-automation
|
|
3
|
+
description: Testing kaseki-agent behavior changes and adding new test coverage
|
|
4
|
+
tags: [kaseki, testing, qa, automation, vitest]
|
|
5
|
+
relatedSkills: [workflow-diagnosis]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Test Automation for Kaseki Agent
|
|
9
|
+
|
|
10
|
+
This skill guides adding and updating tests when kaseki-agent behavior changes, ensuring quality and catching regressions.
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
**When to Use**:
|
|
15
|
+
- Adding a new feature to kaseki-agent (e.g., new cache layer)
|
|
16
|
+
- Changing behavior of existing scripts (run-kaseki.sh, kaseki-agent.sh)
|
|
17
|
+
- Security or validation logic changes
|
|
18
|
+
- Bug fixes in core components
|
|
19
|
+
- Pre-PR validation of changes
|
|
20
|
+
|
|
21
|
+
**Key Concepts**:
|
|
22
|
+
- Tests include unit tests (scripts, logic) and integration tests (Docker-based)
|
|
23
|
+
- Validation in CI/CD must pass before merging
|
|
24
|
+
- Coverage expectations vary by change type (bug fix vs. new feature)
|
|
25
|
+
- Tests should validate both success and failure paths
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Test Structure Overview
|
|
30
|
+
|
|
31
|
+
Kaseki-agent uses a two-tier testing strategy:
|
|
32
|
+
|
|
33
|
+
### 1. **Unit Tests** (JavaScript/Node.js)
|
|
34
|
+
Location: `tests/` directory (or integrated in repo root)
|
|
35
|
+
Tools: Vitest, Node.js assertions
|
|
36
|
+
Scope: Pure logic (not Docker-dependent)
|
|
37
|
+
|
|
38
|
+
**Examples**:
|
|
39
|
+
- `pi-event-filter.js` logic: filtering JSONL events correctly
|
|
40
|
+
- `kaseki-report.js` logic: parsing metadata and formatting output
|
|
41
|
+
- Utility functions: hashing, path construction, env var handling
|
|
42
|
+
|
|
43
|
+
**Run Locally**:
|
|
44
|
+
```bash
|
|
45
|
+
npm test
|
|
46
|
+
npm test -- tests/pi-event-filter.test.js # Single test file
|
|
47
|
+
npm test -- --watch # Watch mode during development
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. **Integration Tests** (Docker-based)
|
|
51
|
+
Location: `.github/workflows/` or custom scripts
|
|
52
|
+
Scope: Full pipeline (clone, build image, run container)
|
|
53
|
+
|
|
54
|
+
**Examples**:
|
|
55
|
+
- Image builds successfully on amd64 + arm64
|
|
56
|
+
- kaseki-agent.sh correctly clones repo and runs agent
|
|
57
|
+
- Quality gates properly reject oversized diffs
|
|
58
|
+
- Secret scan correctly identifies credential patterns
|
|
59
|
+
|
|
60
|
+
**Run Locally**:
|
|
61
|
+
```bash
|
|
62
|
+
docker build -t kaseki-template:latest .
|
|
63
|
+
docker run --rm kaseki-template:latest --doctor # Sanity check
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Unit Test Patterns
|
|
69
|
+
|
|
70
|
+
### Test File Naming
|
|
71
|
+
- Source: `src/lib/parser.ts`
|
|
72
|
+
- Test: `tests/lib/parser.test.ts` (or `parser.test.js` for JS files)
|
|
73
|
+
|
|
74
|
+
### Basic Test Structure
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
import { describe, it, expect } from 'vitest';
|
|
78
|
+
import { piEventFilter } from '../pi-event-filter.js';
|
|
79
|
+
|
|
80
|
+
describe('pi-event-filter', () => {
|
|
81
|
+
it('filters out thinking blocks from events', () => {
|
|
82
|
+
const input = [
|
|
83
|
+
{ type: 'thought', content: 'Let me think about this...' },
|
|
84
|
+
{ type: 'tool_call', tool: 'bash', input: 'echo hello' },
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const output = piEventFilter(input);
|
|
88
|
+
|
|
89
|
+
expect(output).toHaveLength(1);
|
|
90
|
+
expect(output[0].type).toBe('tool_call');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('handles empty input gracefully', () => {
|
|
94
|
+
const output = piEventFilter([]);
|
|
95
|
+
expect(output).toEqual([]);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Testing Success Paths
|
|
101
|
+
|
|
102
|
+
**Pattern**: Expected behavior under normal conditions
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
describe('kaseki-report', () => {
|
|
106
|
+
it('parses metadata.json correctly', () => {
|
|
107
|
+
const metadata = {
|
|
108
|
+
instance: 'kaseki-1',
|
|
109
|
+
exit_codes: { overall: 0 },
|
|
110
|
+
duration_seconds: 600,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const report = generateReport(metadata);
|
|
114
|
+
|
|
115
|
+
expect(report).toContain('kaseki-1');
|
|
116
|
+
expect(report).toContain('600s');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Testing Failure Paths
|
|
122
|
+
|
|
123
|
+
**Pattern**: Graceful degradation and error handling
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
describe('run-kaseki.sh validation', () => {
|
|
127
|
+
it('exits with code 2 when OPENROUTER_API_KEY is missing', async () => {
|
|
128
|
+
const result = await runKasekiWithEnv({
|
|
129
|
+
OPENROUTER_API_KEY: undefined,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
expect(result.exitCode).toBe(2);
|
|
133
|
+
expect(result.stderr).toContain('API key required');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('exits with code 5 when changed files violate allowlist', async () => {
|
|
137
|
+
const result = await runKasekiWithDiff({
|
|
138
|
+
changedFiles: ['src/lib/parser.ts', 'src/other/config.ts'],
|
|
139
|
+
allowlist: 'src/lib/parser.ts',
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
expect(result.exitCode).toBe(5);
|
|
143
|
+
expect(result.stderr).toContain('allowlist');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Testing Edge Cases
|
|
149
|
+
|
|
150
|
+
**Pattern**: Boundary conditions and unusual inputs
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
describe('dependency cache', () => {
|
|
154
|
+
it('handles repos with no package-lock.json', () => {
|
|
155
|
+
const lockHash = computeLockHash({ hasLock: false });
|
|
156
|
+
expect(lockHash).toBe('no-lock');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('detects lock file changes and busts cache', () => {
|
|
160
|
+
const oldStamp = 'repo-abc123-lock-def456';
|
|
161
|
+
const newLock = 'lock-xyz789';
|
|
162
|
+
|
|
163
|
+
const shouldBust = shouldBustCache(oldStamp, newLock);
|
|
164
|
+
expect(shouldBust).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('handles very large lock files (>1MB)', () => {
|
|
168
|
+
const largeContent = 'x'.repeat(2000000);
|
|
169
|
+
const hash = computeLockHash({ content: largeContent });
|
|
170
|
+
|
|
171
|
+
expect(hash).toHaveLength(40); // SHA1 hex digest
|
|
172
|
+
expect(hash).toMatch(/^[a-f0-9]{40}$/);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Integration Test Patterns
|
|
180
|
+
|
|
181
|
+
### Docker Image Tests
|
|
182
|
+
|
|
183
|
+
**Pattern**: Verify image builds and basic functionality
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
#!/bin/bash
|
|
187
|
+
# tests/docker-image.test.sh
|
|
188
|
+
|
|
189
|
+
set -e
|
|
190
|
+
|
|
191
|
+
echo "Building Docker image..."
|
|
192
|
+
docker build -t kaseki-test:latest .
|
|
193
|
+
|
|
194
|
+
echo "Testing Pi CLI is installed..."
|
|
195
|
+
docker run --rm kaseki-test:latest which pi
|
|
196
|
+
docker run --rm kaseki-test:latest pi --version | grep -q "0.70.2"
|
|
197
|
+
|
|
198
|
+
echo "Testing non-root user..."
|
|
199
|
+
docker run --rm kaseki-test:latest id -u | grep -q "10001"
|
|
200
|
+
|
|
201
|
+
echo "✓ All image tests passed"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Run**:
|
|
205
|
+
```bash
|
|
206
|
+
bash tests/docker-image.test.sh
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Multi-Arch Build Tests
|
|
210
|
+
|
|
211
|
+
**Pattern**: Verify builds work on amd64 + arm64 (if using buildx)
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
#!/bin/bash
|
|
215
|
+
# tests/multi-arch-build.test.sh
|
|
216
|
+
|
|
217
|
+
set -e
|
|
218
|
+
|
|
219
|
+
echo "Building for amd64..."
|
|
220
|
+
docker buildx build --platform linux/amd64 -t kaseki-amd64:test .
|
|
221
|
+
|
|
222
|
+
echo "Building for arm64..."
|
|
223
|
+
docker buildx build --platform linux/arm64 -t kaseki-arm64:test .
|
|
224
|
+
|
|
225
|
+
echo "✓ Multi-arch builds successful"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Smoke Tests (Sanity Check)
|
|
229
|
+
|
|
230
|
+
**Pattern**: Run --doctor without actually invoking the agent
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
#!/bin/bash
|
|
234
|
+
# tests/smoke.test.sh
|
|
235
|
+
|
|
236
|
+
set -e
|
|
237
|
+
|
|
238
|
+
echo "Testing --doctor (sanity check)..."
|
|
239
|
+
|
|
240
|
+
# This should verify setup without requiring API key
|
|
241
|
+
./run-kaseki.sh --doctor
|
|
242
|
+
EXIT_CODE=$?
|
|
243
|
+
|
|
244
|
+
if [ $EXIT_CODE -eq 0 ]; then
|
|
245
|
+
echo "✓ Setup is valid"
|
|
246
|
+
else
|
|
247
|
+
echo "✗ Setup check failed with code $EXIT_CODE"
|
|
248
|
+
exit 1
|
|
249
|
+
fi
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Test Coverage Expectations
|
|
255
|
+
|
|
256
|
+
### By Change Type
|
|
257
|
+
|
|
258
|
+
| Change Type | Expected Coverage | Example |
|
|
259
|
+
|---|---|---|
|
|
260
|
+
| **Bug Fix** | Regression test + fix verification | Add test for null/undefined case, then fix |
|
|
261
|
+
| **New Feature** | Feature test + edge cases | New cache layer: test hit, miss, invalidation |
|
|
262
|
+
| **Refactor** | Preserve all existing tests | Move function: same tests still pass |
|
|
263
|
+
| **Performance** | Baseline + improvement test | Caching: measure time before/after |
|
|
264
|
+
| **Security** | Security test + validation | Secret scan: test detection of credentials |
|
|
265
|
+
| **Dependency Update** | Compatibility test | Node upgrade: verify no breaking changes |
|
|
266
|
+
|
|
267
|
+
### Calculating Coverage
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Run tests with coverage report (if configured)
|
|
271
|
+
npm test -- --coverage
|
|
272
|
+
|
|
273
|
+
# Output example:
|
|
274
|
+
# PASS tests/pi-event-filter.test.js
|
|
275
|
+
# ✓ filters out thinking blocks (25ms)
|
|
276
|
+
# ✓ handles empty input (2ms)
|
|
277
|
+
#
|
|
278
|
+
# PASS tests/kaseki-report.test.js
|
|
279
|
+
# ✓ parses metadata correctly (5ms)
|
|
280
|
+
#
|
|
281
|
+
# Test Files: 2 passed (2)
|
|
282
|
+
# Tests: 5 passed (5)
|
|
283
|
+
# Coverage: 85% (target: 80%+)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Adding Tests for Common Changes
|
|
289
|
+
|
|
290
|
+
### Change: New Quality Gate
|
|
291
|
+
|
|
292
|
+
**Scenario**: Add a new validation rule (e.g., "no console.log in production code")
|
|
293
|
+
|
|
294
|
+
**Test Plan**:
|
|
295
|
+
1. Success case: Valid code passes gate
|
|
296
|
+
2. Failure case: Invalid code fails gate
|
|
297
|
+
3. Edge case: Empty or unusual input
|
|
298
|
+
|
|
299
|
+
**Test Code**:
|
|
300
|
+
```javascript
|
|
301
|
+
describe('no-console-log gate', () => {
|
|
302
|
+
it('passes when code has no console.log', () => {
|
|
303
|
+
const diff = `
|
|
304
|
+
+function log() {
|
|
305
|
+
+ logger.debug('message');
|
|
306
|
+
+}
|
|
307
|
+
`;
|
|
308
|
+
|
|
309
|
+
const result = validateNoConsoleLog(diff);
|
|
310
|
+
expect(result.passed).toBe(true);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('fails when code has console.log', () => {
|
|
314
|
+
const diff = `
|
|
315
|
+
+function log() {
|
|
316
|
+
+ console.log('debug');
|
|
317
|
+
+}
|
|
318
|
+
`;
|
|
319
|
+
|
|
320
|
+
const result = validateNoConsoleLog(diff);
|
|
321
|
+
expect(result.passed).toBe(false);
|
|
322
|
+
expect(result.message).toContain('console.log');
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('handles diffs with multiple console references', () => {
|
|
326
|
+
const diff = `
|
|
327
|
+
+console.log('start');
|
|
328
|
+
+console.error('failed');
|
|
329
|
+
-console.warn('old');
|
|
330
|
+
`;
|
|
331
|
+
|
|
332
|
+
const result = validateNoConsoleLog(diff);
|
|
333
|
+
expect(result.violations).toHaveLength(2); // log + error
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Change: Dependency Cache Logic
|
|
339
|
+
|
|
340
|
+
**Scenario**: Modify the 4-layer cache strategy
|
|
341
|
+
|
|
342
|
+
**Test Plan**:
|
|
343
|
+
1. Cache hit: Stamp matches, skip install
|
|
344
|
+
2. Cache miss: Stamp mismatch, run install
|
|
345
|
+
3. Layer hierarchy: Try workspace → seed → fresh
|
|
346
|
+
|
|
347
|
+
**Test Code**:
|
|
348
|
+
```javascript
|
|
349
|
+
describe('dependency cache', () => {
|
|
350
|
+
it('skips npm install if stamp matches', async () => {
|
|
351
|
+
const workspace = createTempWorkspace({
|
|
352
|
+
stamp: 'repo-abc-lock-def',
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const result = await prepareNodeDependencies(workspace, {
|
|
356
|
+
expectedStamp: 'repo-abc-lock-def',
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
expect(result.cacheHit).toBe(true);
|
|
360
|
+
expect(result.npmInstallRan).toBe(false);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it('restores from workspace cache if available', async () => {
|
|
364
|
+
const workspace = createTempWorkspace({
|
|
365
|
+
stamp: 'old-stamp',
|
|
366
|
+
cacheDir: '.kaseki-cache/repo-abc/lock-def/',
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const result = await prepareNodeDependencies(workspace);
|
|
370
|
+
|
|
371
|
+
expect(result.source).toBe('workspace-cache');
|
|
372
|
+
expect(result.npmInstallRan).toBe(false);
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
it('falls back to npm install on cache miss', async () => {
|
|
376
|
+
const workspace = createTempWorkspace({
|
|
377
|
+
stamp: 'missing', // No cache
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
const result = await prepareNodeDependencies(workspace);
|
|
381
|
+
|
|
382
|
+
expect(result.source).toBe('fresh-install');
|
|
383
|
+
expect(result.npmInstallRan).toBe(true);
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Change: Secret Scanning
|
|
389
|
+
|
|
390
|
+
**Scenario**: Update secret patterns or scanning logic
|
|
391
|
+
|
|
392
|
+
**Test Plan**:
|
|
393
|
+
1. Detect real pattern: sk-or-* credentials
|
|
394
|
+
2. Avoid false positives: sk-or in comments
|
|
395
|
+
3. Scan all artifacts: logs, diffs, metadata
|
|
396
|
+
|
|
397
|
+
**Test Code**:
|
|
398
|
+
```javascript
|
|
399
|
+
describe('secret scanning', () => {
|
|
400
|
+
it('detects sk-or- API keys', () => {
|
|
401
|
+
const content = 'OPENROUTER_API_KEY=sk-or-abc123xyz789';
|
|
402
|
+
const secrets = scanForSecrets(content);
|
|
403
|
+
|
|
404
|
+
expect(secrets).toHaveLength(1);
|
|
405
|
+
expect(secrets[0]).toMatch(/sk-or-[a-z0-9]+/);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('ignores sk-or in comments or strings', () => {
|
|
409
|
+
const content = `
|
|
410
|
+
// This is a comment about sk-or- keys
|
|
411
|
+
const example = 'sk-or- pattern';
|
|
412
|
+
`;
|
|
413
|
+
|
|
414
|
+
const secrets = scanForSecrets(content);
|
|
415
|
+
expect(secrets).toHaveLength(0); // No real keys
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('scans all artifact files', async () => {
|
|
419
|
+
const artifacts = {
|
|
420
|
+
'pi-events.jsonl': 'some sk-or-secret in event',
|
|
421
|
+
'git.diff': 'another sk-or-secret in diff',
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const result = scanArtifacts(artifacts);
|
|
425
|
+
expect(result.violations).toHaveLength(2);
|
|
426
|
+
expect(result.files).toContain('pi-events.jsonl');
|
|
427
|
+
expect(result.files).toContain('git.diff');
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Running Tests Locally
|
|
435
|
+
|
|
436
|
+
### Setup
|
|
437
|
+
```bash
|
|
438
|
+
# Install dependencies
|
|
439
|
+
npm ci
|
|
440
|
+
|
|
441
|
+
# Or, if you've modified package.json
|
|
442
|
+
npm install
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Run All Tests
|
|
446
|
+
```bash
|
|
447
|
+
npm test
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Run Specific Test File
|
|
451
|
+
```bash
|
|
452
|
+
npm test -- tests/pi-event-filter.test.js
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Watch Mode (TDD)
|
|
456
|
+
```bash
|
|
457
|
+
npm test -- --watch
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### With Coverage
|
|
461
|
+
```bash
|
|
462
|
+
npm test -- --coverage
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Specific Test (by name)
|
|
466
|
+
```bash
|
|
467
|
+
npm test -- -t "filters out thinking blocks"
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## CI/CD Integration
|
|
473
|
+
|
|
474
|
+
### GitHub Actions Workflow
|
|
475
|
+
|
|
476
|
+
Tests typically run in `.github/workflows/` on pull requests and merges:
|
|
477
|
+
|
|
478
|
+
```yaml
|
|
479
|
+
name: Tests
|
|
480
|
+
|
|
481
|
+
on: [push, pull_request]
|
|
482
|
+
|
|
483
|
+
jobs:
|
|
484
|
+
test:
|
|
485
|
+
runs-on: ubuntu-latest
|
|
486
|
+
steps:
|
|
487
|
+
- uses: actions/checkout@v3
|
|
488
|
+
|
|
489
|
+
- uses: actions/setup-node@v3
|
|
490
|
+
with:
|
|
491
|
+
node-version: '22.22.2'
|
|
492
|
+
|
|
493
|
+
- run: npm ci
|
|
494
|
+
|
|
495
|
+
- run: npm test
|
|
496
|
+
# Fails PR if tests don't pass
|
|
497
|
+
|
|
498
|
+
- run: npm test -- --coverage
|
|
499
|
+
# Optional: report coverage
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Pre-Commit Hook (Optional)
|
|
503
|
+
|
|
504
|
+
Optionally run tests before committing:
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
# .husky/pre-commit
|
|
508
|
+
#!/bin/sh
|
|
509
|
+
npm test
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Debugging Failed Tests
|
|
515
|
+
|
|
516
|
+
### Test Fails Locally
|
|
517
|
+
|
|
518
|
+
**Step 1**: Read the error message carefully
|
|
519
|
+
```
|
|
520
|
+
FAIL tests/pi-event-filter.test.js
|
|
521
|
+
✓ filters out thinking blocks (25ms)
|
|
522
|
+
✗ handles empty input (12ms)
|
|
523
|
+
|
|
524
|
+
Expected: []
|
|
525
|
+
Received: [{ type: 'message', content: '' }]
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
**Step 2**: Isolate the test
|
|
529
|
+
```bash
|
|
530
|
+
npm test -- -t "handles empty input"
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
**Step 3**: Add debug output
|
|
534
|
+
```javascript
|
|
535
|
+
it('handles empty input gracefully', () => {
|
|
536
|
+
const output = piEventFilter([]);
|
|
537
|
+
console.log('Actual output:', JSON.stringify(output, null, 2));
|
|
538
|
+
expect(output).toEqual([]);
|
|
539
|
+
});
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
**Step 4**: Run in watch mode to iterate
|
|
543
|
+
```bash
|
|
544
|
+
npm test -- --watch
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Test Fails in CI
|
|
548
|
+
|
|
549
|
+
**Diagnose**:
|
|
550
|
+
1. Check GitHub Actions logs (Actions tab in PR)
|
|
551
|
+
2. Look for differences from local environment (Node version, OS, etc.)
|
|
552
|
+
3. Reproduce locally with same Node version:
|
|
553
|
+
```bash
|
|
554
|
+
nvm use 22.22.2 # Match CI version
|
|
555
|
+
npm ci
|
|
556
|
+
npm test
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## Best Practices
|
|
562
|
+
|
|
563
|
+
1. **Test Behavior, Not Implementation**
|
|
564
|
+
- ✓ "Function returns null when input is null"
|
|
565
|
+
- ✗ "Function calls helper.check() exactly once"
|
|
566
|
+
|
|
567
|
+
2. **Use Descriptive Test Names**
|
|
568
|
+
- ✓ "exits with code 5 when changed files violate allowlist"
|
|
569
|
+
- ✗ "test allowlist"
|
|
570
|
+
|
|
571
|
+
3. **Keep Tests Isolated**
|
|
572
|
+
- Each test should be independent
|
|
573
|
+
- Don't rely on test execution order
|
|
574
|
+
- Clean up (mock cleanup, temp files) in `afterEach`
|
|
575
|
+
|
|
576
|
+
4. **Test Both Success and Failure**
|
|
577
|
+
- Happy path + error cases
|
|
578
|
+
- Edge cases and boundaries
|
|
579
|
+
- Upstream failures (e.g., Docker unavailable)
|
|
580
|
+
|
|
581
|
+
5. **Use Realistic Test Data**
|
|
582
|
+
- Real exit codes, diff formats, API responses
|
|
583
|
+
- Redact sensitive information
|
|
584
|
+
- Keep data minimal (just enough for test)
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## Related Skills & Docs
|
|
589
|
+
|
|
590
|
+
- [Workflow Diagnosis](workflow-diagnosis.md) — Validate test results and troubleshoot failures
|
|
591
|
+
- [Docker Image Management](docker-image-management.md) — Integration test patterns
|
|
592
|
+
- [CONTRIBUTING.md](../../CONTRIBUTING.md) — Contribution guidelines and validation expectations
|
|
593
|
+
- [Dockerfile](../../Dockerfile) — Image structure for integration tests
|