@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,56 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Convert a glob-style repo-relative allowlist pattern into an extended regex.
|
|
4
|
+
# Supported glob operators:
|
|
5
|
+
# - * matches within a single path segment
|
|
6
|
+
# - ** matches across path segments
|
|
7
|
+
# - **/ matches zero or more path segments
|
|
8
|
+
# - ? matches one character within a single path segment
|
|
9
|
+
# All other regex metacharacters are escaped so exact path patterns remain exact.
|
|
10
|
+
allowlist_pattern_to_regex() {
|
|
11
|
+
awk -v pattern="$1" '
|
|
12
|
+
BEGIN {
|
|
13
|
+
regex = ""
|
|
14
|
+
i = 1
|
|
15
|
+
while (i <= length(pattern)) {
|
|
16
|
+
c = substr(pattern, i, 1)
|
|
17
|
+
next_c = substr(pattern, i + 1, 1)
|
|
18
|
+
next_next_c = substr(pattern, i + 2, 1)
|
|
19
|
+
|
|
20
|
+
if (c == "*" && next_c == "*") {
|
|
21
|
+
if (next_next_c == "/") {
|
|
22
|
+
regex = regex "([^/]+/)*"
|
|
23
|
+
i += 3
|
|
24
|
+
} else {
|
|
25
|
+
regex = regex ".*"
|
|
26
|
+
i += 2
|
|
27
|
+
}
|
|
28
|
+
} else if (c == "*") {
|
|
29
|
+
regex = regex "[^/]*"
|
|
30
|
+
i++
|
|
31
|
+
} else if (c == "?") {
|
|
32
|
+
regex = regex "[^/]"
|
|
33
|
+
i++
|
|
34
|
+
} else {
|
|
35
|
+
if (index(".\\^$()+{}|[]", c) > 0) {
|
|
36
|
+
regex = regex "\\" c
|
|
37
|
+
} else {
|
|
38
|
+
regex = regex c
|
|
39
|
+
}
|
|
40
|
+
i++
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
print regex
|
|
44
|
+
}
|
|
45
|
+
'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
build_allowlist_regex() {
|
|
49
|
+
local pattern regexes=()
|
|
50
|
+
while IFS= read -r pattern || [ -n "$pattern" ]; do
|
|
51
|
+
[ -z "$pattern" ] && continue
|
|
52
|
+
regexes+=("$(allowlist_pattern_to_regex "$pattern")")
|
|
53
|
+
done < <(printf '%s\n' "$KASEKI_CHANGED_FILES_ALLOWLIST" | tr ' ' '\n')
|
|
54
|
+
|
|
55
|
+
(IFS='|'; printf '%s' "${regexes[*]}")
|
|
56
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="${KASEKI_ROOT:-/agents}"
|
|
5
|
+
RUNS="$ROOT/kaseki-runs"
|
|
6
|
+
RESULTS="$ROOT/kaseki-results"
|
|
7
|
+
OLDER_THAN_DAYS="${KASEKI_CLEANUP_DAYS:-1}"
|
|
8
|
+
DRY_RUN=0
|
|
9
|
+
DOCKER_CLEANUP=0
|
|
10
|
+
FORCE=0
|
|
11
|
+
KASEKI_LOG_DIR="${KASEKI_LOG_DIR:-/var/log/kaseki}"
|
|
12
|
+
KASEKI_STRICT_HOST_LOGGING="${KASEKI_STRICT_HOST_LOGGING:-0}"
|
|
13
|
+
KASEKI_JSON_LOG_COMPONENT="cleanup-kaseki"
|
|
14
|
+
|
|
15
|
+
json_escape() {
|
|
16
|
+
local value="${1-}"
|
|
17
|
+
value="${value//\\/\\\\}"
|
|
18
|
+
value="${value//\"/\\\"}"
|
|
19
|
+
value="${value//$'\n'/\\n}"
|
|
20
|
+
value="${value//$'\r'/\\r}"
|
|
21
|
+
value="${value//$'\t'/\\t}"
|
|
22
|
+
printf '%s' "$value"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
emit_json_log() {
|
|
26
|
+
local stage="$1"
|
|
27
|
+
local status="$2"
|
|
28
|
+
local detail="${3-}"
|
|
29
|
+
printf '{"timestamp":"%s","component":"%s","stage":"%s","status":"%s","instance":"%s","detail":"%s"}\n' \
|
|
30
|
+
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
31
|
+
"$KASEKI_JSON_LOG_COMPONENT" \
|
|
32
|
+
"$(json_escape "$stage")" \
|
|
33
|
+
"$(json_escape "$status")" \
|
|
34
|
+
"maintenance" \
|
|
35
|
+
"$(json_escape "$detail")"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
on_cleanup_exit() {
|
|
39
|
+
local code=$?
|
|
40
|
+
if [ "$code" -eq 0 ]; then
|
|
41
|
+
emit_json_log "cleanup" "finished" "cleanup-kaseki.sh completed successfully"
|
|
42
|
+
else
|
|
43
|
+
emit_json_log "cleanup" "error" "cleanup-kaseki.sh exited with code $code"
|
|
44
|
+
fi
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
trap on_cleanup_exit EXIT
|
|
48
|
+
emit_json_log "cleanup" "started" "cleanup-kaseki.sh starting"
|
|
49
|
+
|
|
50
|
+
setup_host_logging() {
|
|
51
|
+
local base_name="$1"
|
|
52
|
+
local stamp host_log_file
|
|
53
|
+
if mkdir -p "$KASEKI_LOG_DIR" 2>/dev/null && [ -w "$KASEKI_LOG_DIR" ]; then
|
|
54
|
+
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
55
|
+
host_log_file="$KASEKI_LOG_DIR/${base_name}-${stamp}.log"
|
|
56
|
+
exec > >(tee -a "$host_log_file") 2> >(tee -a "$host_log_file" >&2)
|
|
57
|
+
printf 'Host log mirror: %s\n' "$host_log_file"
|
|
58
|
+
return 0
|
|
59
|
+
fi
|
|
60
|
+
if [ "$KASEKI_STRICT_HOST_LOGGING" = "1" ]; then
|
|
61
|
+
printf 'Error: strict host logging enabled, but KASEKI_LOG_DIR is not writable: %s\n' "$KASEKI_LOG_DIR" >&2
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
printf 'Warning: host logging disabled; KASEKI_LOG_DIR is unavailable: %s\n' "$KASEKI_LOG_DIR" >&2
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
show_help() {
|
|
68
|
+
cat <<HELP
|
|
69
|
+
Usage: KASEKI_CLEANUP_DAYS=1 $0 [--docker] [--dry-run] [--force]
|
|
70
|
+
|
|
71
|
+
Deletes finalized kaseki-N workspaces older than the configured age.
|
|
72
|
+
Results under $RESULTS are preserved.
|
|
73
|
+
Transient staging directories (for example: .staging-run-kaseki-N-XXXXXX)
|
|
74
|
+
are created and cleaned automatically by run-kaseki.sh.
|
|
75
|
+
|
|
76
|
+
Options:
|
|
77
|
+
--docker Also remove stopped kaseki containers and prune Docker build cache.
|
|
78
|
+
--dry-run Print what would be removed.
|
|
79
|
+
--force Required with --docker to actually prune Docker build cache.
|
|
80
|
+
HELP
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
while [ "$#" -gt 0 ]; do
|
|
84
|
+
case "$1" in
|
|
85
|
+
--help|-h)
|
|
86
|
+
show_help
|
|
87
|
+
exit 0
|
|
88
|
+
;;
|
|
89
|
+
--docker)
|
|
90
|
+
DOCKER_CLEANUP=1
|
|
91
|
+
;;
|
|
92
|
+
--dry-run)
|
|
93
|
+
DRY_RUN=1
|
|
94
|
+
;;
|
|
95
|
+
--force)
|
|
96
|
+
FORCE=1
|
|
97
|
+
;;
|
|
98
|
+
*)
|
|
99
|
+
printf 'Unknown option: %s\n' "$1" >&2
|
|
100
|
+
show_help >&2
|
|
101
|
+
exit 2
|
|
102
|
+
;;
|
|
103
|
+
esac
|
|
104
|
+
shift
|
|
105
|
+
done
|
|
106
|
+
|
|
107
|
+
setup_host_logging "cleanup-kaseki"
|
|
108
|
+
|
|
109
|
+
run_or_print() {
|
|
110
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
111
|
+
printf '+ %q' "$1"
|
|
112
|
+
shift
|
|
113
|
+
while [ "$#" -gt 0 ]; do
|
|
114
|
+
printf ' %q' "$1"
|
|
115
|
+
shift
|
|
116
|
+
done
|
|
117
|
+
printf '\n'
|
|
118
|
+
else
|
|
119
|
+
"$@"
|
|
120
|
+
fi
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
printf 'Kaseki cleanup\n'
|
|
124
|
+
printf 'Root: %s\n' "$ROOT"
|
|
125
|
+
printf 'Runs: %s\n' "$RUNS"
|
|
126
|
+
printf 'Results preserved: %s\n' "$RESULTS"
|
|
127
|
+
|
|
128
|
+
if [ -d "$RUNS" ]; then
|
|
129
|
+
emit_json_log "workspace-prune" "started" "removing stale run directories older than $OLDER_THAN_DAYS days"
|
|
130
|
+
find "$RUNS" -mindepth 1 -maxdepth 1 -type d -name 'kaseki-[0-9]*' -mtime +"$OLDER_THAN_DAYS" -print |
|
|
131
|
+
while IFS= read -r run_dir; do
|
|
132
|
+
run_or_print rm -rf "$run_dir"
|
|
133
|
+
done
|
|
134
|
+
emit_json_log "workspace-prune" "finished" "stale run directory cleanup complete"
|
|
135
|
+
else
|
|
136
|
+
printf 'No Kaseki runs directory found: %s\n' "$RUNS"
|
|
137
|
+
emit_json_log "workspace-prune" "finished" "runs directory missing; nothing to prune"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
if [ "$DOCKER_CLEANUP" -eq 1 ]; then
|
|
141
|
+
emit_json_log "docker-cleanup" "started" "docker cleanup requested"
|
|
142
|
+
if ! command -v docker >/dev/null 2>&1; then
|
|
143
|
+
printf 'Docker: missing; skipping Docker cleanup\n' >&2
|
|
144
|
+
emit_json_log "docker-cleanup" "error" "docker binary missing; skipping docker cleanup"
|
|
145
|
+
exit 0
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
printf '\nDocker disk usage before cleanup:\n'
|
|
149
|
+
docker system df || true
|
|
150
|
+
|
|
151
|
+
docker ps -a --format '{{.ID}} {{.Names}}' |
|
|
152
|
+
awk '$2 ~ /^kaseki-[0-9]+$/ { print $1 }' |
|
|
153
|
+
while IFS= read -r container_id; do
|
|
154
|
+
[ -z "$container_id" ] && continue
|
|
155
|
+
run_or_print docker rm "$container_id"
|
|
156
|
+
done
|
|
157
|
+
|
|
158
|
+
if [ "$FORCE" -eq 1 ]; then
|
|
159
|
+
run_or_print docker builder prune -f --filter until=24h
|
|
160
|
+
run_or_print docker image prune -f
|
|
161
|
+
else
|
|
162
|
+
printf 'Docker build/image prune skipped; pass --force with --docker to prune cache and dangling images.\n'
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
printf '\nDocker disk usage after cleanup:\n'
|
|
166
|
+
docker system df || true
|
|
167
|
+
emit_json_log "docker-cleanup" "finished" "docker cleanup stage complete"
|
|
168
|
+
fi
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
DEFAULT_TARGET_DIR="/agents/kaseki-template"
|
|
6
|
+
TARGET_DIR="${KASEKI_TEMPLATE_DIR:-$DEFAULT_TARGET_DIR}"
|
|
7
|
+
REQUESTED_IMAGE="${KASEKI_IMAGE:-docker.io/cyanautomation/kaseki-agent:latest}"
|
|
8
|
+
IMAGE="$REQUESTED_IMAGE"
|
|
9
|
+
LOCAL_BUILD_IMAGE="${KASEKI_LOCAL_BUILD_IMAGE:-kaseki-agent:local}"
|
|
10
|
+
KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="${KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING:-1}"
|
|
11
|
+
KASEKI_IMAGE_PULL_POLICY="${KASEKI_IMAGE_PULL_POLICY:-always}"
|
|
12
|
+
KASEKI_LOG_DIR="${KASEKI_LOG_DIR:-/var/log/kaseki}"
|
|
13
|
+
KASEKI_STRICT_HOST_LOGGING="${KASEKI_STRICT_HOST_LOGGING:-0}"
|
|
14
|
+
KASEKI_JSON_LOG_COMPONENT="deploy-pi-template"
|
|
15
|
+
CONTAINER=""
|
|
16
|
+
|
|
17
|
+
is_probably_digest_ref() {
|
|
18
|
+
local image_ref="$1"
|
|
19
|
+
case "$image_ref" in
|
|
20
|
+
*@sha256:*) return 0 ;;
|
|
21
|
+
*) return 1 ;;
|
|
22
|
+
esac
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
resolve_local_repo_digest() {
|
|
26
|
+
local image_ref="$1"
|
|
27
|
+
docker image inspect "$image_ref" --format '{{index .RepoDigests 0}}' 2>/dev/null || true
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
json_escape() {
|
|
31
|
+
local value="${1-}"
|
|
32
|
+
value="${value//\\/\\\\}"
|
|
33
|
+
value="${value//\"/\\\"}"
|
|
34
|
+
value="${value//$'\n'/\\n}"
|
|
35
|
+
value="${value//$'\r'/\\r}"
|
|
36
|
+
value="${value//$'\t'/\\t}"
|
|
37
|
+
printf '%s' "$value"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
emit_json_log() {
|
|
41
|
+
local stage="$1"
|
|
42
|
+
local status="$2"
|
|
43
|
+
local detail="${3-}"
|
|
44
|
+
printf '{"timestamp":"%s","component":"%s","stage":"%s","status":"%s","instance":"%s","detail":"%s"}\n' \
|
|
45
|
+
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
46
|
+
"$KASEKI_JSON_LOG_COMPONENT" \
|
|
47
|
+
"$(json_escape "$stage")" \
|
|
48
|
+
"$(json_escape "$status")" \
|
|
49
|
+
"template" \
|
|
50
|
+
"$(json_escape "$detail")"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
on_deploy_exit() {
|
|
54
|
+
local code=$?
|
|
55
|
+
if [ -n "${CONTAINER:-}" ]; then
|
|
56
|
+
docker rm "$CONTAINER" >/dev/null 2>&1 || true
|
|
57
|
+
fi
|
|
58
|
+
if [ "$code" -eq 0 ]; then
|
|
59
|
+
emit_json_log "deploy" "finished" "deploy-pi-template.sh completed successfully"
|
|
60
|
+
else
|
|
61
|
+
emit_json_log "deploy" "error" "deploy-pi-template.sh exited with code $code"
|
|
62
|
+
fi
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
trap on_deploy_exit EXIT
|
|
66
|
+
emit_json_log "deploy" "started" "deploy-pi-template.sh starting"
|
|
67
|
+
|
|
68
|
+
setup_host_logging() {
|
|
69
|
+
local base_name="$1"
|
|
70
|
+
local stamp host_log_file
|
|
71
|
+
if mkdir -p "$KASEKI_LOG_DIR" 2>/dev/null && [ -w "$KASEKI_LOG_DIR" ]; then
|
|
72
|
+
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
73
|
+
host_log_file="$KASEKI_LOG_DIR/${base_name}-${stamp}.log"
|
|
74
|
+
exec > >(tee -a "$host_log_file") 2> >(tee -a "$host_log_file" >&2)
|
|
75
|
+
printf 'Host log mirror: %s\n' "$host_log_file"
|
|
76
|
+
return 0
|
|
77
|
+
fi
|
|
78
|
+
if [ "$KASEKI_STRICT_HOST_LOGGING" = "1" ]; then
|
|
79
|
+
printf 'Error: strict host logging enabled, but KASEKI_LOG_DIR is not writable: %s\n' "$KASEKI_LOG_DIR" >&2
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
printf 'Warning: host logging disabled; KASEKI_LOG_DIR is unavailable: %s\n' "$KASEKI_LOG_DIR" >&2
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
setup_host_logging "deploy-pi-template"
|
|
86
|
+
|
|
87
|
+
if [ "${1:-}" = "--help" ]; then
|
|
88
|
+
cat <<HELP
|
|
89
|
+
Usage: KASEKI_TEMPLATE_DIR=$DEFAULT_TARGET_DIR $0
|
|
90
|
+
|
|
91
|
+
Deploys the current Kaseki runner files into KASEKI_TEMPLATE_DIR
|
|
92
|
+
(default: $DEFAULT_TARGET_DIR).
|
|
93
|
+
|
|
94
|
+
Idempotent behavior:
|
|
95
|
+
- Refuses to clean unexpected targets (guardrails require basename "kaseki-template"
|
|
96
|
+
and path prefix "/agents/" or "$HOME/").
|
|
97
|
+
- Cleans destination root before install.
|
|
98
|
+
- Preserves existing destination subdirectories named run, result, cache, and secrets.
|
|
99
|
+
|
|
100
|
+
Image behavior:
|
|
101
|
+
- Pulls KASEKI_IMAGE by default before using a local tag.
|
|
102
|
+
- Set KASEKI_IMAGE_PULL_POLICY=missing to pull only when absent.
|
|
103
|
+
- Set KASEKI_IMAGE_PULL_POLICY=never to use only local Docker images.
|
|
104
|
+
- If the image lacks a deployable /app template and
|
|
105
|
+
KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING=1, builds this checkout as
|
|
106
|
+
$LOCAL_BUILD_IMAGE and deploys that image instead.
|
|
107
|
+
HELP
|
|
108
|
+
exit 0
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
is_allowed_target_dir() {
|
|
112
|
+
local target="$1"
|
|
113
|
+
local base
|
|
114
|
+
base="$(basename "$target")"
|
|
115
|
+
[ "$base" = "kaseki-template" ] || return 1
|
|
116
|
+
case "$target" in
|
|
117
|
+
/agents/*) return 0 ;;
|
|
118
|
+
"$HOME"/*) return 0 ;;
|
|
119
|
+
esac
|
|
120
|
+
return 1
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
prepare_target_dir() {
|
|
124
|
+
local target="$1"
|
|
125
|
+
local abs_target
|
|
126
|
+
local backup_root=""
|
|
127
|
+
local persistent
|
|
128
|
+
local path
|
|
129
|
+
|
|
130
|
+
abs_target="$(cd "$(dirname "$target")" 2>/dev/null && pwd)/$(basename "$target")" || abs_target="$target"
|
|
131
|
+
|
|
132
|
+
if ! is_allowed_target_dir "$abs_target"; then
|
|
133
|
+
printf 'Error: target directory is not allowed: %s\n' "$abs_target" >&2
|
|
134
|
+
printf 'Allowed paths: /agents/kaseki-template, %s/kaseki-template\n' "$HOME" >&2
|
|
135
|
+
exit 2
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
if [ -d "$target" ]; then
|
|
139
|
+
backup_root="$(mktemp -d)"
|
|
140
|
+
for persistent in run result cache secrets; do
|
|
141
|
+
path="$target/$persistent"
|
|
142
|
+
if [ -d "$path" ]; then
|
|
143
|
+
printf 'Preserving: %s\n' "$path"
|
|
144
|
+
mv "$path" "$backup_root/$persistent"
|
|
145
|
+
fi
|
|
146
|
+
done
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
mkdir -p "$target"
|
|
150
|
+
rm -rf "${target:?}"/*
|
|
151
|
+
mkdir -p "$target"
|
|
152
|
+
|
|
153
|
+
if [ -n "$backup_root" ]; then
|
|
154
|
+
for persistent in run result cache secrets; do
|
|
155
|
+
if [ -d "$backup_root/$persistent" ]; then
|
|
156
|
+
mv "$backup_root/$persistent" "$target/$persistent"
|
|
157
|
+
printf 'Restored: %s\n' "$target/$persistent"
|
|
158
|
+
fi
|
|
159
|
+
done
|
|
160
|
+
rmdir "$backup_root" 2>/dev/null || true
|
|
161
|
+
fi
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
image_has_template() {
|
|
165
|
+
local image="$1"
|
|
166
|
+
local probe_container=""
|
|
167
|
+
probe_container="$(docker create "$image" 2>/dev/null)" || return 1
|
|
168
|
+
if docker cp "$probe_container:/app/run-kaseki.sh" - >/dev/null 2>&1; then
|
|
169
|
+
docker rm "$probe_container" >/dev/null 2>&1 || true
|
|
170
|
+
return 0
|
|
171
|
+
fi
|
|
172
|
+
docker rm "$probe_container" >/dev/null 2>&1 || true
|
|
173
|
+
return 1
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
ensure_deployable_image() {
|
|
177
|
+
local local_image_present=0
|
|
178
|
+
local resolved_digest=""
|
|
179
|
+
|
|
180
|
+
docker image inspect "$IMAGE" >/dev/null 2>&1 || local_image_present=1
|
|
181
|
+
|
|
182
|
+
case "$KASEKI_IMAGE_PULL_POLICY" in
|
|
183
|
+
always)
|
|
184
|
+
emit_json_log "deploy" "started" "Pulling Docker image: $IMAGE"
|
|
185
|
+
if ! docker pull "$IMAGE"; then
|
|
186
|
+
if [ "$local_image_present" -eq 0 ]; then
|
|
187
|
+
emit_json_log "deploy" "warning" "Pull failed; using existing local Docker image: $IMAGE"
|
|
188
|
+
else
|
|
189
|
+
return 1
|
|
190
|
+
fi
|
|
191
|
+
fi
|
|
192
|
+
;;
|
|
193
|
+
missing|if-not-present)
|
|
194
|
+
if [ "$local_image_present" -eq 0 ]; then
|
|
195
|
+
emit_json_log "deploy" "started" "Using local Docker image: $IMAGE"
|
|
196
|
+
else
|
|
197
|
+
emit_json_log "deploy" "started" "Pulling Docker image: $IMAGE"
|
|
198
|
+
docker pull "$IMAGE"
|
|
199
|
+
fi
|
|
200
|
+
;;
|
|
201
|
+
never)
|
|
202
|
+
if [ "$local_image_present" -eq 0 ]; then
|
|
203
|
+
emit_json_log "deploy" "started" "Using local Docker image: $IMAGE"
|
|
204
|
+
else
|
|
205
|
+
printf 'Error: image is not present locally and KASEKI_IMAGE_PULL_POLICY=never: %s\n' "$IMAGE" >&2
|
|
206
|
+
return 1
|
|
207
|
+
fi
|
|
208
|
+
;;
|
|
209
|
+
*)
|
|
210
|
+
printf 'Error: invalid KASEKI_IMAGE_PULL_POLICY: %s (expected always, missing, if-not-present, or never)\n' "$KASEKI_IMAGE_PULL_POLICY" >&2
|
|
211
|
+
return 2
|
|
212
|
+
;;
|
|
213
|
+
esac
|
|
214
|
+
|
|
215
|
+
resolved_digest="$(resolve_local_repo_digest "$IMAGE")"
|
|
216
|
+
if [ -n "$resolved_digest" ] && ! is_probably_digest_ref "$IMAGE"; then
|
|
217
|
+
emit_json_log "deploy" "started" "Resolved image tag to immutable digest: $resolved_digest"
|
|
218
|
+
elif [ -z "$resolved_digest" ] && ! is_probably_digest_ref "$IMAGE"; then
|
|
219
|
+
emit_json_log "deploy" "warning" "No repo digest found for image reference; continuing with tag: $IMAGE"
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
if image_has_template "$IMAGE"; then
|
|
223
|
+
return 0
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
if [ "$KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING" != "1" ]; then
|
|
227
|
+
printf 'Error: image does not contain deployable /app template: %s\n' "$IMAGE" >&2
|
|
228
|
+
return 1
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
emit_json_log "deploy" "started" "Image lacks /app template; building $LOCAL_BUILD_IMAGE from checkout"
|
|
232
|
+
printf 'Image lacks /app template, building local fallback: %s\n' "$LOCAL_BUILD_IMAGE"
|
|
233
|
+
docker build --progress=plain -t "$LOCAL_BUILD_IMAGE" "$SOURCE_DIR"
|
|
234
|
+
IMAGE="$LOCAL_BUILD_IMAGE"
|
|
235
|
+
|
|
236
|
+
if ! image_has_template "$IMAGE"; then
|
|
237
|
+
printf 'Error: locally built image still does not contain /app template: %s\n' "$IMAGE" >&2
|
|
238
|
+
return 1
|
|
239
|
+
fi
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
verify_template() {
|
|
243
|
+
local target="$1"
|
|
244
|
+
local missing=0
|
|
245
|
+
local required
|
|
246
|
+
for required in run-kaseki.sh kaseki kaseki-agent.sh scripts/kaseki-preflight.sh lib/pi-event-filter.js lib/pi-progress-stream.js lib/kaseki-report.js lib/github-app-token.js; do
|
|
247
|
+
if [ ! -f "$target/$required" ]; then
|
|
248
|
+
printf 'Missing deployed template file: %s\n' "$required" >&2
|
|
249
|
+
missing=1
|
|
250
|
+
fi
|
|
251
|
+
done
|
|
252
|
+
return "$missing"
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
write_image_metadata() {
|
|
256
|
+
local target="$1"
|
|
257
|
+
local configured_image="$2"
|
|
258
|
+
local deployed_image="$3"
|
|
259
|
+
local repo_digest=""
|
|
260
|
+
|
|
261
|
+
printf '%s\n' "$configured_image" > "$target/.kaseki-image"
|
|
262
|
+
repo_digest="$(docker image inspect "$deployed_image" --format '{{range .RepoDigests}}{{println .}}{{end}}' 2>/dev/null | head -n 1 || true)"
|
|
263
|
+
if [ -n "$repo_digest" ]; then
|
|
264
|
+
printf '%s\n' "$repo_digest" > "$target/.kaseki-image-digest"
|
|
265
|
+
else
|
|
266
|
+
rm -f "$target/.kaseki-image-digest"
|
|
267
|
+
fi
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
printf 'Kaseki template deployment\n'
|
|
271
|
+
printf 'Source: %s\n' "$SOURCE_DIR"
|
|
272
|
+
printf 'Target: %s\n' "$TARGET_DIR"
|
|
273
|
+
printf 'Image: %s\n' "$REQUESTED_IMAGE"
|
|
274
|
+
|
|
275
|
+
prepare_target_dir "$TARGET_DIR"
|
|
276
|
+
|
|
277
|
+
ensure_deployable_image
|
|
278
|
+
|
|
279
|
+
emit_json_log "deploy" "started" "Creating container for extraction"
|
|
280
|
+
CONTAINER=$(docker create "$IMAGE")
|
|
281
|
+
|
|
282
|
+
emit_json_log "deploy" "started" "Extracting files from container"
|
|
283
|
+
docker cp "$CONTAINER:/app/." "$TARGET_DIR/"
|
|
284
|
+
|
|
285
|
+
emit_json_log "deploy" "started" "Cleaning up container"
|
|
286
|
+
docker rm "$CONTAINER"
|
|
287
|
+
CONTAINER=""
|
|
288
|
+
|
|
289
|
+
write_image_metadata "$TARGET_DIR" "$REQUESTED_IMAGE" "$IMAGE"
|
|
290
|
+
verify_template "$TARGET_DIR"
|
|
291
|
+
|
|
292
|
+
emit_json_log "deploy" "finished" "Deployment completed successfully"
|
|
293
|
+
printf '\n✓ Kaseki template deployed to: %s\n' "$TARGET_DIR"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
case "${1:-agent}" in
|
|
5
|
+
setup)
|
|
6
|
+
# Interactive setup wizard inside container
|
|
7
|
+
# Usage: docker run -it -v ~/.kaseki/secrets:/secrets kaseki-agent setup
|
|
8
|
+
shift || true
|
|
9
|
+
exec /scripts/kaseki-container-setup.sh "$@"
|
|
10
|
+
;;
|
|
11
|
+
|
|
12
|
+
doctor)
|
|
13
|
+
# Health check and diagnostics
|
|
14
|
+
# Usage: docker run kaseki-agent doctor
|
|
15
|
+
shift || true
|
|
16
|
+
exec /usr/local/bin/kaseki-agent --doctor
|
|
17
|
+
;;
|
|
18
|
+
|
|
19
|
+
run-mode)
|
|
20
|
+
# One-command run with API key from environment variable
|
|
21
|
+
# Usage: docker run -e OPENROUTER_API_KEY=sk-or-... kaseki-agent run-mode <repo> <ref>
|
|
22
|
+
shift || true
|
|
23
|
+
|
|
24
|
+
# Validate API key is provided
|
|
25
|
+
if [ -z "${OPENROUTER_API_KEY:-}" ]; then
|
|
26
|
+
echo "Error: OPENROUTER_API_KEY environment variable is required for run-mode" >&2
|
|
27
|
+
exit 2
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Create secrets directory and store key securely
|
|
31
|
+
mkdir -p /secrets
|
|
32
|
+
echo "$OPENROUTER_API_KEY" > /secrets/openrouter_api_key
|
|
33
|
+
chmod 600 /secrets/openrouter_api_key
|
|
34
|
+
|
|
35
|
+
# Clear env var to avoid exposure in child process
|
|
36
|
+
unset OPENROUTER_API_KEY
|
|
37
|
+
|
|
38
|
+
# Set required variables and execute agent
|
|
39
|
+
export OPENROUTER_API_KEY_FILE=/secrets/openrouter_api_key
|
|
40
|
+
export KASEKI_INSTANCE="${KASEKI_INSTANCE:-kaseki-run}"
|
|
41
|
+
export KASEKI_RESULTS_DIR="${KASEKI_RESULTS_DIR:-/results}"
|
|
42
|
+
|
|
43
|
+
exec /usr/local/bin/kaseki-agent "$@"
|
|
44
|
+
;;
|
|
45
|
+
|
|
46
|
+
setup-remote)
|
|
47
|
+
# Remote host setup orchestration (runs from controller container)
|
|
48
|
+
# Usage: docker run kaseki-agent setup-remote <host> <api-key>
|
|
49
|
+
shift || true
|
|
50
|
+
exec /scripts/kaseki-container-setup-remote.sh "$@"
|
|
51
|
+
;;
|
|
52
|
+
|
|
53
|
+
agent|kaseki-agent)
|
|
54
|
+
# Standard agent execution (existing mode)
|
|
55
|
+
# Usage: docker run kaseki-agent agent <repo> <ref>
|
|
56
|
+
shift || true
|
|
57
|
+
exec /usr/local/bin/kaseki-agent "$@"
|
|
58
|
+
;;
|
|
59
|
+
|
|
60
|
+
api|kaseki-api)
|
|
61
|
+
# REST API service (existing mode)
|
|
62
|
+
# Usage: docker run kaseki-agent api
|
|
63
|
+
shift || true
|
|
64
|
+
exec node /app/dist/kaseki-api-service.js "$@"
|
|
65
|
+
;;
|
|
66
|
+
|
|
67
|
+
*)
|
|
68
|
+
# Passthrough mode for debugging
|
|
69
|
+
exec "$@"
|
|
70
|
+
;;
|
|
71
|
+
esac
|