adispatchd 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -2
- package/dist/api/errors.d.ts +27 -0
- package/dist/api/errors.js +80 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.js +11 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/logs.d.ts +30 -0
- package/dist/api/logs.js +88 -0
- package/dist/api/logs.js.map +1 -0
- package/dist/api/serialize.d.ts +65 -0
- package/dist/api/serialize.js +135 -0
- package/dist/api/serialize.js.map +1 -0
- package/dist/api/server.d.ts +89 -0
- package/dist/api/server.js +751 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/sse.d.ts +90 -0
- package/dist/api/sse.js +225 -0
- package/dist/api/sse.js.map +1 -0
- package/dist/app.d.ts +173 -0
- package/dist/app.js +488 -0
- package/dist/app.js.map +1 -0
- package/dist/cli/config-validate.d.ts +6 -0
- package/dist/cli/config-validate.js +39 -0
- package/dist/cli/config-validate.js.map +1 -0
- package/dist/cli/control.d.ts +31 -0
- package/dist/cli/control.js +186 -0
- package/dist/cli/control.js.map +1 -0
- package/dist/cli/http-client.d.ts +57 -0
- package/dist/cli/http-client.js +174 -0
- package/dist/cli/http-client.js.map +1 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.js +14 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-templates.d.ts +20 -0
- package/dist/cli/init-templates.js +275 -0
- package/dist/cli/init-templates.js.map +1 -0
- package/dist/cli/init.d.ts +16 -0
- package/dist/cli/init.js +107 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +25 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/program.d.ts +102 -0
- package/dist/cli/program.js +133 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/service.d.ts +27 -0
- package/dist/cli/service.js +252 -0
- package/dist/cli/service.js.map +1 -0
- package/dist/cli/start.d.ts +22 -0
- package/dist/cli/start.js +133 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/cli/workflow-dry-run.d.ts +13 -0
- package/dist/cli/workflow-dry-run.js +144 -0
- package/dist/cli/workflow-dry-run.js.map +1 -0
- package/dist/config/field-catalog.d.ts +33 -0
- package/dist/config/field-catalog.js +172 -0
- package/dist/config/field-catalog.js.map +1 -0
- package/dist/config/filter-schema.d.ts +15 -0
- package/dist/config/filter-schema.js +110 -0
- package/dist/config/filter-schema.js.map +1 -0
- package/dist/config/index.d.ts +15 -0
- package/dist/config/index.js +16 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/issues.d.ts +27 -0
- package/dist/config/issues.js +37 -0
- package/dist/config/issues.js.map +1 -0
- package/dist/config/loader.d.ts +32 -0
- package/dist/config/loader.js +250 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/manager.d.ts +153 -0
- package/dist/config/manager.js +276 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/model.d.ts +334 -0
- package/dist/config/model.js +2 -0
- package/dist/config/model.js.map +1 -0
- package/dist/config/normalize.d.ts +20 -0
- package/dist/config/normalize.js +200 -0
- package/dist/config/normalize.js.map +1 -0
- package/dist/config/parameters.d.ts +37 -0
- package/dist/config/parameters.js +71 -0
- package/dist/config/parameters.js.map +1 -0
- package/dist/config/public.d.ts +6 -0
- package/dist/config/public.js +18 -0
- package/dist/config/public.js.map +1 -0
- package/dist/config/schemas.d.ts +538 -0
- package/dist/config/schemas.js +321 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/snapshot.d.ts +38 -0
- package/dist/config/snapshot.js +57 -0
- package/dist/config/snapshot.js.map +1 -0
- package/dist/config/validate.d.ts +33 -0
- package/dist/config/validate.js +346 -0
- package/dist/config/validate.js.map +1 -0
- package/dist/core/clock.d.ts +59 -0
- package/dist/core/clock.js +133 -0
- package/dist/core/clock.js.map +1 -0
- package/dist/core/duration.d.ts +19 -0
- package/dist/core/duration.js +93 -0
- package/dist/core/duration.js.map +1 -0
- package/dist/core/errors.d.ts +62 -0
- package/dist/core/errors.js +72 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/ids.d.ts +57 -0
- package/dist/core/ids.js +88 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +100 -0
- package/dist/core/logger.js +207 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paths.d.ts +84 -0
- package/dist/core/paths.js +138 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/template.d.ts +136 -0
- package/dist/core/template.js +261 -0
- package/dist/core/template.js.map +1 -0
- package/dist/core/types.d.ts +544 -0
- package/dist/core/types.js +172 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/worker-protocol.d.ts +102 -0
- package/dist/core/worker-protocol.js +75 -0
- package/dist/core/worker-protocol.js.map +1 -0
- package/dist/executors/classify.d.ts +25 -0
- package/dist/executors/classify.js +54 -0
- package/dist/executors/classify.js.map +1 -0
- package/dist/executors/dispatcher.d.ts +35 -0
- package/dist/executors/dispatcher.js +68 -0
- package/dist/executors/dispatcher.js.map +1 -0
- package/dist/executors/env.d.ts +43 -0
- package/dist/executors/env.js +66 -0
- package/dist/executors/env.js.map +1 -0
- package/dist/executors/event-parser.d.ts +41 -0
- package/dist/executors/event-parser.js +106 -0
- package/dist/executors/event-parser.js.map +1 -0
- package/dist/executors/index.d.ts +12 -0
- package/dist/executors/index.js +13 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/log-capture.d.ts +57 -0
- package/dist/executors/log-capture.js +155 -0
- package/dist/executors/log-capture.js.map +1 -0
- package/dist/executors/process-identity.d.ts +124 -0
- package/dist/executors/process-identity.js +283 -0
- package/dist/executors/process-identity.js.map +1 -0
- package/dist/executors/shell-executor.d.ts +35 -0
- package/dist/executors/shell-executor.js +478 -0
- package/dist/executors/shell-executor.js.map +1 -0
- package/dist/executors/stream-redactor.d.ts +40 -0
- package/dist/executors/stream-redactor.js +89 -0
- package/dist/executors/stream-redactor.js.map +1 -0
- package/dist/executors/workspace.d.ts +10 -0
- package/dist/executors/workspace.js +47 -0
- package/dist/executors/workspace.js.map +1 -0
- package/dist/filters/evaluate.d.ts +77 -0
- package/dist/filters/evaluate.js +187 -0
- package/dist/filters/evaluate.js.map +1 -0
- package/dist/filters/fields.d.ts +35 -0
- package/dist/filters/fields.js +75 -0
- package/dist/filters/fields.js.map +1 -0
- package/dist/filters/index.d.ts +11 -0
- package/dist/filters/index.js +12 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/filters/iso-date.d.ts +10 -0
- package/dist/filters/iso-date.js +42 -0
- package/dist/filters/iso-date.js.map +1 -0
- package/dist/filters/predicate.d.ts +24 -0
- package/dist/filters/predicate.js +178 -0
- package/dist/filters/predicate.js.map +1 -0
- package/dist/filters/priority.d.ts +51 -0
- package/dist/filters/priority.js +91 -0
- package/dist/filters/priority.js.map +1 -0
- package/dist/filters/pushdown.d.ts +12 -0
- package/dist/filters/pushdown.js +52 -0
- package/dist/filters/pushdown.js.map +1 -0
- package/dist/filters/shell-check.d.ts +110 -0
- package/dist/filters/shell-check.js +304 -0
- package/dist/filters/shell-check.js.map +1 -0
- package/dist/identities/github-app.d.ts +55 -0
- package/dist/identities/github-app.js +160 -0
- package/dist/identities/github-app.js.map +1 -0
- package/dist/identities/index.d.ts +6 -0
- package/dist/identities/index.js +7 -0
- package/dist/identities/index.js.map +1 -0
- package/dist/identities/jwt.d.ts +24 -0
- package/dist/identities/jwt.js +56 -0
- package/dist/identities/jwt.js.map +1 -0
- package/dist/lifecycle/context.d.ts +106 -0
- package/dist/lifecycle/context.js +170 -0
- package/dist/lifecycle/context.js.map +1 -0
- package/dist/lifecycle/engine.d.ts +185 -0
- package/dist/lifecycle/engine.js +551 -0
- package/dist/lifecycle/engine.js.map +1 -0
- package/dist/lifecycle/errors.d.ts +48 -0
- package/dist/lifecycle/errors.js +71 -0
- package/dist/lifecycle/errors.js.map +1 -0
- package/dist/lifecycle/index.d.ts +9 -0
- package/dist/lifecycle/index.js +9 -0
- package/dist/lifecycle/index.js.map +1 -0
- package/dist/lifecycle/performers.d.ts +66 -0
- package/dist/lifecycle/performers.js +179 -0
- package/dist/lifecycle/performers.js.map +1 -0
- package/dist/notifications/index.d.ts +6 -0
- package/dist/notifications/index.js +7 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/service.d.ts +115 -0
- package/dist/notifications/service.js +364 -0
- package/dist/notifications/service.js.map +1 -0
- package/dist/persistence/actions.d.ts +101 -0
- package/dist/persistence/actions.js +196 -0
- package/dist/persistence/actions.js.map +1 -0
- package/dist/persistence/blocks.d.ts +85 -0
- package/dist/persistence/blocks.js +140 -0
- package/dist/persistence/blocks.js.map +1 -0
- package/dist/persistence/cron-firings.d.ts +55 -0
- package/dist/persistence/cron-firings.js +70 -0
- package/dist/persistence/cron-firings.js.map +1 -0
- package/dist/persistence/database.d.ts +60 -0
- package/dist/persistence/database.js +124 -0
- package/dist/persistence/database.js.map +1 -0
- package/dist/persistence/errors.d.ts +39 -0
- package/dist/persistence/errors.js +67 -0
- package/dist/persistence/errors.js.map +1 -0
- package/dist/persistence/events.d.ts +72 -0
- package/dist/persistence/events.js +83 -0
- package/dist/persistence/events.js.map +1 -0
- package/dist/persistence/index.d.ts +18 -0
- package/dist/persistence/index.js +19 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/instance-lock.d.ts +26 -0
- package/dist/persistence/instance-lock.js +117 -0
- package/dist/persistence/instance-lock.js.map +1 -0
- package/dist/persistence/lock-keys.d.ts +16 -0
- package/dist/persistence/lock-keys.js +41 -0
- package/dist/persistence/lock-keys.js.map +1 -0
- package/dist/persistence/notifications.d.ts +113 -0
- package/dist/persistence/notifications.js +213 -0
- package/dist/persistence/notifications.js.map +1 -0
- package/dist/persistence/persistence.d.ts +46 -0
- package/dist/persistence/persistence.js +42 -0
- package/dist/persistence/persistence.js.map +1 -0
- package/dist/persistence/retention.d.ts +46 -0
- package/dist/persistence/retention.js +68 -0
- package/dist/persistence/retention.js.map +1 -0
- package/dist/persistence/runs.d.ts +215 -0
- package/dist/persistence/runs.js +417 -0
- package/dist/persistence/runs.js.map +1 -0
- package/dist/persistence/schema.d.ts +16 -0
- package/dist/persistence/schema.js +183 -0
- package/dist/persistence/schema.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +49 -0
- package/dist/persistence/sqlite.js +131 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/runs/controller.d.ts +307 -0
- package/dist/runs/controller.js +1078 -0
- package/dist/runs/controller.js.map +1 -0
- package/dist/runs/errors.d.ts +20 -0
- package/dist/runs/errors.js +26 -0
- package/dist/runs/errors.js.map +1 -0
- package/dist/runs/event-bus.d.ts +106 -0
- package/dist/runs/event-bus.js +105 -0
- package/dist/runs/event-bus.js.map +1 -0
- package/dist/runs/execution.d.ts +39 -0
- package/dist/runs/execution.js +146 -0
- package/dist/runs/execution.js.map +1 -0
- package/dist/runs/index.d.ts +12 -0
- package/dist/runs/index.js +13 -0
- package/dist/runs/index.js.map +1 -0
- package/dist/runs/retention.d.ts +64 -0
- package/dist/runs/retention.js +232 -0
- package/dist/runs/retention.js.map +1 -0
- package/dist/runs/workspace.d.ts +20 -0
- package/dist/runs/workspace.js +51 -0
- package/dist/runs/workspace.js.map +1 -0
- package/dist/scheduler/checks.d.ts +41 -0
- package/dist/scheduler/checks.js +111 -0
- package/dist/scheduler/checks.js.map +1 -0
- package/dist/scheduler/cron.d.ts +32 -0
- package/dist/scheduler/cron.js +83 -0
- package/dist/scheduler/cron.js.map +1 -0
- package/dist/scheduler/dry-run.d.ts +42 -0
- package/dist/scheduler/dry-run.js +167 -0
- package/dist/scheduler/dry-run.js.map +1 -0
- package/dist/scheduler/errors.d.ts +22 -0
- package/dist/scheduler/errors.js +22 -0
- package/dist/scheduler/errors.js.map +1 -0
- package/dist/scheduler/format.d.ts +3 -0
- package/dist/scheduler/format.js +73 -0
- package/dist/scheduler/format.js.map +1 -0
- package/dist/scheduler/index.d.ts +13 -0
- package/dist/scheduler/index.js +14 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/planner.d.ts +88 -0
- package/dist/scheduler/planner.js +255 -0
- package/dist/scheduler/planner.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +160 -0
- package/dist/scheduler/scheduler.js +680 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/state.d.ts +26 -0
- package/dist/scheduler/state.js +25 -0
- package/dist/scheduler/state.js.map +1 -0
- package/dist/scheduler/types.d.ts +197 -0
- package/dist/scheduler/types.js +3 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/service/index.d.ts +6 -0
- package/dist/service/index.js +7 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/install.d.ts +93 -0
- package/dist/service/install.js +250 -0
- package/dist/service/install.js.map +1 -0
- package/dist/service/unit.d.ts +50 -0
- package/dist/service/unit.js +171 -0
- package/dist/service/unit.js.map +1 -0
- package/dist/sources/github/adapter.d.ts +99 -0
- package/dist/sources/github/adapter.js +336 -0
- package/dist/sources/github/adapter.js.map +1 -0
- package/dist/sources/github/fields.d.ts +8 -0
- package/dist/sources/github/fields.js +72 -0
- package/dist/sources/github/fields.js.map +1 -0
- package/dist/sources/github/http.d.ts +100 -0
- package/dist/sources/github/http.js +288 -0
- package/dist/sources/github/http.js.map +1 -0
- package/dist/sources/github/index.d.ts +6 -0
- package/dist/sources/github/index.js +7 -0
- package/dist/sources/github/index.js.map +1 -0
- package/dist/sources/github/pushdown.d.ts +14 -0
- package/dist/sources/github/pushdown.js +47 -0
- package/dist/sources/github/pushdown.js.map +1 -0
- package/dist/sources/github/refs.d.ts +17 -0
- package/dist/sources/github/refs.js +61 -0
- package/dist/sources/github/refs.js.map +1 -0
- package/dist/sources/index.d.ts +6 -0
- package/dist/sources/index.js +7 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/ui/index.d.ts +12 -0
- package/dist/ui/index.js +28 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/public/app.css +239 -0
- package/dist/ui/public/favicon.svg +1 -0
- package/dist/ui/public/index.html +27 -0
- package/dist/ui/public/js/client/api.js +68 -0
- package/dist/ui/public/js/client/app.js +146 -0
- package/dist/ui/public/js/client/dom.js +34 -0
- package/dist/ui/public/js/client/page.js +9 -0
- package/dist/ui/public/js/client/pages/actions.js +35 -0
- package/dist/ui/public/js/client/pages/blocked.js +58 -0
- package/dist/ui/public/js/client/pages/config.js +126 -0
- package/dist/ui/public/js/client/pages/dashboard.js +175 -0
- package/dist/ui/public/js/client/pages/run.js +367 -0
- package/dist/ui/public/js/client/pages/runs.js +72 -0
- package/dist/ui/public/js/client/pages/views.js +80 -0
- package/dist/ui/public/js/client/pages/workflows.js +291 -0
- package/dist/ui/public/js/client/types.js +1 -0
- package/dist/ui/public/js/client/ui.js +152 -0
- package/dist/ui/public/js/shared/dom.js +77 -0
- package/dist/ui/public/js/shared/events.js +88 -0
- package/dist/ui/public/js/shared/format.js +213 -0
- package/dist/ui/public/js/shared/logs.js +136 -0
- package/dist/ui/public/js/shared/params.js +90 -0
- package/dist/ui/public/js/shared/route.js +36 -0
- package/dist/ui/public/js/shared/sort.js +70 -0
- package/dist/ui/public/js/shared/sse.js +193 -0
- package/dist/ui/public/js/shared/throttle.js +65 -0
- package/dist/views/index.d.ts +6 -0
- package/dist/views/index.js +7 -0
- package/dist/views/index.js.map +1 -0
- package/dist/views/service.d.ts +131 -0
- package/dist/views/service.js +264 -0
- package/dist/views/service.js.map +1 -0
- package/docs/api.md +239 -0
- package/docs/configuration-reference.md +1785 -0
- package/docs/cron-semantics.md +96 -0
- package/docs/manual-tests/github-fixture/config.yaml +30 -0
- package/docs/manual-tests/github-fixture/helpers.sh +93 -0
- package/docs/manual-tests/github-fixture/identities.yaml +18 -0
- package/docs/manual-tests/github-fixture/scripts/test-worker.sh +100 -0
- package/docs/manual-tests/github-fixture/sources.yaml +13 -0
- package/docs/manual-tests/github-fixture/views/dependencies.yaml +17 -0
- package/docs/manual-tests/github-fixture/views/needs-maintainer.yaml +17 -0
- package/docs/manual-tests/github-fixture/workflows/coder-test.yaml +76 -0
- package/docs/manual-tests/github-fixture/workflows/commenter-test.yaml +63 -0
- package/docs/manual-tests/github-fixture/workflows/reviewer-test.yaml +60 -0
- package/docs/manual-tests/github.md +1308 -0
- package/docs/manual-tests/process-supervision.md +64 -0
- package/docs/manual-tests/systemd.md +68 -0
- package/docs/operations.md +271 -0
- package/docs/worker-protocol.md +145 -0
- package/examples/config/config.yaml +35 -0
- package/examples/config/identities.yaml +18 -0
- package/examples/config/sources.yaml +13 -0
- package/examples/config/views/needs-maintainer.yaml +15 -0
- package/examples/config/workflows/coder-project-a.yaml +86 -0
- package/examples/config/workflows/deploy.yaml +15 -0
- package/examples/config/workflows/nightly-maintenance.yaml +13 -0
- package/package.json +75 -4
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files created by `init` (Spec §4): a commented, valid example configuration
|
|
3
|
+
* that starts without any GitHub credentials. Only the manual `hello`
|
|
4
|
+
* workflow is enabled; the GitHub coder workflow and the nightly schedule are
|
|
5
|
+
* disabled examples to copy from. Kept as code (not as package files) so the
|
|
6
|
+
* installed package needs no asset lookup.
|
|
7
|
+
*/
|
|
8
|
+
const CONFIG_YAML = (port) => `# config.yaml – global settings (Spec §5.1). All keys are optional; shown values are the defaults
|
|
9
|
+
# unless noted. Validate after every change: adispatch config validate --config-dir <dir>
|
|
10
|
+
# Apply changes to a running instance: adispatch config reload --config-dir <dir>
|
|
11
|
+
|
|
12
|
+
server:
|
|
13
|
+
# The HTTP API/UI has NO authentication (V1). Keep it on loopback. To expose it, put an
|
|
14
|
+
# AUTHENTICATING reverse proxy / VPN / Tailscale in front (see docs/operations.md).
|
|
15
|
+
host: 127.0.0.1
|
|
16
|
+
port: ${port}
|
|
17
|
+
# Extra host names accepted in the Host/Origin header (DNS-rebinding protection), e.g. the
|
|
18
|
+
# public name of the authenticating reverse proxy: [orchestrator.example.com]
|
|
19
|
+
# ("name" = any port, "name:port" = only that port). Loopback names are always accepted.
|
|
20
|
+
allowed_hosts: []
|
|
21
|
+
|
|
22
|
+
scheduler:
|
|
23
|
+
polling_interval: 30s # how often sources are polled
|
|
24
|
+
max_concurrent: 5 # global limit for automatic starts (manual starts count, but are not limited)
|
|
25
|
+
|
|
26
|
+
workspace:
|
|
27
|
+
# One workspace per run under base_dir/<workflow>/<run> (default: <data-dir>/workspaces).
|
|
28
|
+
# Relative paths are relative to this config dir.
|
|
29
|
+
# base_dir: /var/lib/adispatchd/workspaces
|
|
30
|
+
cleanup: on_success # always | on_success | never
|
|
31
|
+
|
|
32
|
+
lifecycle:
|
|
33
|
+
action_retry: # default retry of lifecycle actions (source.update/comment, shell)
|
|
34
|
+
max_attempts: 3
|
|
35
|
+
delay: 30s
|
|
36
|
+
|
|
37
|
+
retention:
|
|
38
|
+
completed_runs: 30d # successful runs
|
|
39
|
+
failed_runs: 90d # failed, crashed, cancelled ... runs
|
|
40
|
+
blocked_runs: never # runs that led to a retry block
|
|
41
|
+
max_log_size_per_run: 100MB
|
|
42
|
+
cleanup_interval: 24h
|
|
43
|
+
|
|
44
|
+
notifications:
|
|
45
|
+
# Central orchestrator notifications (Spec §18). Secrets come from environment variables:
|
|
46
|
+
# channels:
|
|
47
|
+
# - type: webhook
|
|
48
|
+
# url_env: SLACK_WEBHOOK_URL
|
|
49
|
+
# headers_env: { Authorization: WEBHOOK_AUTH_HEADER }
|
|
50
|
+
on: [retry_block_created, lifecycle_action_failed, recovery_failed]
|
|
51
|
+
`;
|
|
52
|
+
const SOURCES_YAML = `# sources.yaml – external task sources (Spec §5.2). V1: GitHub issues/PRs.
|
|
53
|
+
# Each source uses an identity from identities.yaml for read access.
|
|
54
|
+
# The source ID is part of every run's item key (<source>:<number>) – renaming it detaches the run history.
|
|
55
|
+
sources:
|
|
56
|
+
project_a:
|
|
57
|
+
type: github
|
|
58
|
+
owner: example # GitHub owner/organisation
|
|
59
|
+
repository: project-a
|
|
60
|
+
identity: maintainer
|
|
61
|
+
`;
|
|
62
|
+
const IDENTITIES_YAML = `# identities.yaml – GitHub App identities, one per role (Spec §5.3).
|
|
63
|
+
# The private key is NEVER stored here: private_key_env names an environment variable that holds
|
|
64
|
+
# the PEM (real line breaks or "\\n" escapes). Under systemd put it into the EnvironmentFile
|
|
65
|
+
# (default /etc/default/adispatchd, mode 0640).
|
|
66
|
+
# Minimal app permissions: Issues read/write, Pull requests write (labels/comments on PRs), Metadata read.
|
|
67
|
+
identities:
|
|
68
|
+
maintainer:
|
|
69
|
+
type: github_app
|
|
70
|
+
app_id: 100001
|
|
71
|
+
installation_id: 200001
|
|
72
|
+
private_key_env: GITHUB_MAINTAINER_PRIVATE_KEY
|
|
73
|
+
coder:
|
|
74
|
+
type: github_app
|
|
75
|
+
app_id: 100002
|
|
76
|
+
installation_id: 200002
|
|
77
|
+
private_key_env: GITHUB_CODER_PRIVATE_KEY
|
|
78
|
+
`;
|
|
79
|
+
const HELLO_YAML = `# workflows/hello.yaml – a manual workflow that runs without any external source.
|
|
80
|
+
# Start it in the web UI (Workflows → hello → Start) or via the API:
|
|
81
|
+
# curl -X POST -H 'X-Adispatch-Request: 1' -H 'Content-Type: application/json' \\
|
|
82
|
+
# -d '{"parameters":{"name":"Ada"}}' http://127.0.0.1:8787/api/v1/workflows/hello/start
|
|
83
|
+
id: hello
|
|
84
|
+
name: Hello World
|
|
85
|
+
trigger: { type: manual }
|
|
86
|
+
parameters:
|
|
87
|
+
name:
|
|
88
|
+
type: string
|
|
89
|
+
default: world
|
|
90
|
+
description: Whom to greet
|
|
91
|
+
execute:
|
|
92
|
+
type: shell
|
|
93
|
+
# Relative paths are resolved against the config dir. Arguments are passed as a list (no shell).
|
|
94
|
+
command: scripts/hello.sh
|
|
95
|
+
args: ['{parameters.name}']
|
|
96
|
+
timeout:
|
|
97
|
+
max_duration: 10m # total runtime (default: unlimited)
|
|
98
|
+
idle_timeout: 5m # time without output (default: unlimited)
|
|
99
|
+
on_success:
|
|
100
|
+
- type: shell # lifecycle shell action; gets run + result context (ADISPATCH_CONTEXT_FILE)
|
|
101
|
+
command: scripts/notify.sh
|
|
102
|
+
args: ['{workflow.id}', '{run.id}', '{result.message}']
|
|
103
|
+
timeout: 30s
|
|
104
|
+
`;
|
|
105
|
+
const CODER_YAML = `# workflows/coder.yaml – GitHub-driven agent workflow (Spec §5.4). DISABLED example:
|
|
106
|
+
# configure sources.yaml/identities.yaml, provide the private keys, then set enabled: true.
|
|
107
|
+
id: coder
|
|
108
|
+
name: Coder – Project A
|
|
109
|
+
enabled: false
|
|
110
|
+
priority: 50 # workflow priority (higher first) before item priority
|
|
111
|
+
max_concurrent: 2
|
|
112
|
+
identity: coder # default identity for writes (labels, comments)
|
|
113
|
+
|
|
114
|
+
trigger:
|
|
115
|
+
type: source
|
|
116
|
+
source: project_a
|
|
117
|
+
|
|
118
|
+
filter: # declarative filter (all/any/not; equals, contains, in, greater_than, ...)
|
|
119
|
+
all:
|
|
120
|
+
- { field: labels, operator: contains, value: ready-for-coding }
|
|
121
|
+
- { field: dependencies.blocked_by_open, operator: equals, value: 0 }
|
|
122
|
+
|
|
123
|
+
item_priority:
|
|
124
|
+
rules:
|
|
125
|
+
- when: { field: labels, operator: contains, value: 'priority:high' }
|
|
126
|
+
value: 50
|
|
127
|
+
default: 0
|
|
128
|
+
|
|
129
|
+
conditions:
|
|
130
|
+
workflow: # exit 0 = ok, 1 = not now, >=2 = check error (unknown → no start)
|
|
131
|
+
- type: shell
|
|
132
|
+
command: scripts/check-credits.sh
|
|
133
|
+
timeout: 15s
|
|
134
|
+
cache: 60s
|
|
135
|
+
|
|
136
|
+
execute:
|
|
137
|
+
type: shell
|
|
138
|
+
command: scripts/coder.sh
|
|
139
|
+
working_directory: '{workspace.base_dir}/{workflow.id}/{run.id}'
|
|
140
|
+
env:
|
|
141
|
+
NODE_ENV: production
|
|
142
|
+
secrets:
|
|
143
|
+
GH_TOKEN: { identity: coder } # short-lived installation token, only for this worker
|
|
144
|
+
timeout:
|
|
145
|
+
max_duration: 6h
|
|
146
|
+
idle_timeout: 45m
|
|
147
|
+
cancel_grace: 30s # SIGTERM → SIGKILL of the worker's process group
|
|
148
|
+
|
|
149
|
+
retry:
|
|
150
|
+
max_technical_failures: 3 # consecutive crashes/timeouts/start errors → retry block (remove in UI)
|
|
151
|
+
|
|
152
|
+
on_start:
|
|
153
|
+
- type: source.update
|
|
154
|
+
labels: { add: [coding], remove: [ready-for-coding] }
|
|
155
|
+
on_success:
|
|
156
|
+
- type: source.update
|
|
157
|
+
labels: { add: [ready-for-review], remove: [coding] }
|
|
158
|
+
- type: source.comment
|
|
159
|
+
message: 'Completed: {result.message}'
|
|
160
|
+
continue_on_error: true
|
|
161
|
+
on_failure: # business failure: valid result file with "result": "failure"
|
|
162
|
+
- type: source.update
|
|
163
|
+
labels: { add: [needs-maintainer], remove: [coding] }
|
|
164
|
+
- type: source.comment
|
|
165
|
+
message: 'Needs maintainer: {result.message}'
|
|
166
|
+
on_crash:
|
|
167
|
+
- type: source.update
|
|
168
|
+
labels: { add: [ready-for-coding], remove: [coding] }
|
|
169
|
+
on_start_error:
|
|
170
|
+
- type: source.update
|
|
171
|
+
labels: { add: [ready-for-coding], remove: [coding] }
|
|
172
|
+
on_timeout:
|
|
173
|
+
- type: source.update
|
|
174
|
+
labels: { add: [ready-for-coding], remove: [coding] }
|
|
175
|
+
on_cancel:
|
|
176
|
+
- type: source.update
|
|
177
|
+
labels: { add: [ready-for-coding], remove: [coding] }
|
|
178
|
+
`;
|
|
179
|
+
const NIGHTLY_YAML = `# workflows/nightly-maintenance.yaml – time-triggered workflow (Spec §5.5). DISABLED example.
|
|
180
|
+
# Missed slots (downtime, limits, failing conditions) are skipped, never caught up (docs/cron-semantics.md).
|
|
181
|
+
id: nightly-maintenance
|
|
182
|
+
name: Nightly Maintenance
|
|
183
|
+
enabled: false
|
|
184
|
+
priority: 20
|
|
185
|
+
trigger:
|
|
186
|
+
type: schedule
|
|
187
|
+
cron: '0 3 * * *'
|
|
188
|
+
timezone: Europe/Berlin # default UTC
|
|
189
|
+
execute:
|
|
190
|
+
type: shell
|
|
191
|
+
command: scripts/maintenance.sh
|
|
192
|
+
`;
|
|
193
|
+
const VIEW_YAML = `# views/needs-maintainer.yaml – read-only table over one or more sources (Spec §17).
|
|
194
|
+
# Needs working source credentials; otherwise the view shows a per-source error.
|
|
195
|
+
id: needs-maintainer
|
|
196
|
+
title: Needs Maintainer
|
|
197
|
+
sources: [project_a]
|
|
198
|
+
filter:
|
|
199
|
+
all:
|
|
200
|
+
- { field: labels, operator: contains, value: needs-maintainer }
|
|
201
|
+
fields:
|
|
202
|
+
- { field: repository, label: Repository }
|
|
203
|
+
- { field: number, label: Issue }
|
|
204
|
+
- { field: title, label: Title, link: url }
|
|
205
|
+
- { field: run.last_workflow, label: Last agent }
|
|
206
|
+
- { field: run.last_result.message, label: Result }
|
|
207
|
+
- { field: updated_at, label: Updated }
|
|
208
|
+
sort: { field: updated_at, direction: desc }
|
|
209
|
+
`;
|
|
210
|
+
const HELLO_SH = `#!/bin/sh
|
|
211
|
+
# Example worker (worker protocol: docs/worker-protocol.md).
|
|
212
|
+
# Input: ADISPATCH_* environment variables + JSON context file ADISPATCH_CONTEXT_FILE.
|
|
213
|
+
# Output: stdout/stderr (logged), optional "@@ADISPATCH_EVENT {json}" lines, optional result file ADISPATCH_RESULT_FILE.
|
|
214
|
+
# Exit code: 0 = technically OK (business result from the result file, default success); != 0 = crashed.
|
|
215
|
+
set -eu
|
|
216
|
+
|
|
217
|
+
name="\${1:-world}"
|
|
218
|
+
echo '@@ADISPATCH_EVENT {"type":"status","message":"Saying hello"}'
|
|
219
|
+
echo "Hello, \${name}!"
|
|
220
|
+
echo "run \${ADISPATCH_RUN_ID} of workflow \${ADISPATCH_WORKFLOW_ID} in \${ADISPATCH_WORKSPACE}"
|
|
221
|
+
echo '@@ADISPATCH_EVENT {"type":"progress","value":100}'
|
|
222
|
+
|
|
223
|
+
# Write the result atomically (temp file + rename). "failure" would trigger on_failure instead.
|
|
224
|
+
tmp="\${ADISPATCH_RESULT_FILE}.tmp"
|
|
225
|
+
printf '%s\\n' '{"schema_version":1,"result":"success","message":"Said hello"}' > "\${tmp}"
|
|
226
|
+
mv "\${tmp}" "\${ADISPATCH_RESULT_FILE}"
|
|
227
|
+
`;
|
|
228
|
+
const NOTIFY_SH = `#!/bin/sh
|
|
229
|
+
# Example lifecycle shell action: receives the rendered args and the run/result context
|
|
230
|
+
# (ADISPATCH_CONTEXT_FILE). Replace with e.g. a Slack webhook call. Exit != 0 = action failed (retried).
|
|
231
|
+
set -eu
|
|
232
|
+
echo "workflow $1, run $2 finished: $3"
|
|
233
|
+
`;
|
|
234
|
+
const CODER_SH = `#!/bin/sh
|
|
235
|
+
# Example coder wrapper – replace the body with your agent invocation.
|
|
236
|
+
# GH_TOKEN (declared under execute.secrets) authenticates the GitHub CLI as the coder app.
|
|
237
|
+
set -eu
|
|
238
|
+
echo "Working on \${ADISPATCH_SOURCE_URL:-?} (item \${ADISPATCH_SOURCE_ITEM_ID:-?}) in \${ADISPATCH_WORKSPACE}"
|
|
239
|
+
# git clone ... && your-agent --context "\${ADISPATCH_CONTEXT_FILE}"
|
|
240
|
+
|
|
241
|
+
# Business failure ("needs maintainer"): write a valid result file and exit 0:
|
|
242
|
+
# printf '%s\\n' '{"schema_version":1,"result":"failure","message":"Requirements unclear"}' > "\${ADISPATCH_RESULT_FILE}.tmp"
|
|
243
|
+
# mv "\${ADISPATCH_RESULT_FILE}.tmp" "\${ADISPATCH_RESULT_FILE}"
|
|
244
|
+
# Any exit code != 0 counts as a technical failure (crashed) and towards the retry block.
|
|
245
|
+
exit 0
|
|
246
|
+
`;
|
|
247
|
+
const CHECK_CREDITS_SH = `#!/bin/sh
|
|
248
|
+
# Example workflow condition: exit 0 = start allowed, 1 = not now, >= 2 = check error (unknown).
|
|
249
|
+
exit 0
|
|
250
|
+
`;
|
|
251
|
+
const MAINTENANCE_SH = `#!/bin/sh
|
|
252
|
+
set -eu
|
|
253
|
+
echo "nightly maintenance at $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
254
|
+
`;
|
|
255
|
+
/** All files created by `init`, relative to config-dir. */
|
|
256
|
+
export function initTemplates(options = {}) {
|
|
257
|
+
const port = options.port ?? 8787;
|
|
258
|
+
return [
|
|
259
|
+
{ path: 'config.yaml', content: CONFIG_YAML(port), mode: 0o640 },
|
|
260
|
+
{ path: 'sources.yaml', content: SOURCES_YAML, mode: 0o640 },
|
|
261
|
+
{ path: 'identities.yaml', content: IDENTITIES_YAML, mode: 0o640 },
|
|
262
|
+
{ path: 'workflows/hello.yaml', content: HELLO_YAML, mode: 0o640 },
|
|
263
|
+
{ path: 'workflows/coder.yaml', content: CODER_YAML, mode: 0o640 },
|
|
264
|
+
{ path: 'workflows/nightly-maintenance.yaml', content: NIGHTLY_YAML, mode: 0o640 },
|
|
265
|
+
{ path: 'views/needs-maintainer.yaml', content: VIEW_YAML, mode: 0o640 },
|
|
266
|
+
{ path: 'scripts/hello.sh', content: HELLO_SH, mode: 0o750 },
|
|
267
|
+
{ path: 'scripts/notify.sh', content: NOTIFY_SH, mode: 0o750 },
|
|
268
|
+
{ path: 'scripts/coder.sh', content: CODER_SH, mode: 0o750 },
|
|
269
|
+
{ path: 'scripts/check-credits.sh', content: CHECK_CREDITS_SH, mode: 0o750 },
|
|
270
|
+
{ path: 'scripts/maintenance.sh', content: MAINTENANCE_SH, mode: 0o750 },
|
|
271
|
+
];
|
|
272
|
+
}
|
|
273
|
+
/** Directories created in data-dir (Spec §4); the app creates missing ones itself as well. */
|
|
274
|
+
export const DATA_DIR_LAYOUT = ['logs', 'runs', 'workspaces', 'backups'];
|
|
275
|
+
//# sourceMappingURL=init-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-templates.js","sourceRoot":"","sources":["../../src/cli/init-templates.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC;;;;;;;;UAQpC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCb,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;;;;;CASpB,CAAC;AAEF,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;CAgBvB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyElB,CAAC;AAEF,MAAM,YAAY,GAAG;;;;;;;;;;;;;CAapB,CAAC;AAEF,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;CAgBjB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;CAiBhB,CAAC;AAEF,MAAM,SAAS,GAAG;;;;;CAKjB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;CAYhB,CAAC;AAEF,MAAM,gBAAgB,GAAG;;;CAGxB,CAAC;AAEF,MAAM,cAAc,GAAG;;;CAGtB,CAAC;AAEF,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,OAAO,GAAsB,EAAE;IAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;IAClC,OAAO;QACL,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE;QAChE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE;QAC5D,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,EAAE;QAClE,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE;QAClE,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE;QAClE,EAAE,IAAI,EAAE,oCAAoC,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE;QAClF,EAAE,IAAI,EAAE,6BAA6B,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;QACxE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE;QAC5D,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;QAC9D,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE;QAC5D,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,KAAK,EAAE;QAC5E,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE;KACzE,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,CAAU,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CliIo, InitCliOptions } from './program.js';
|
|
2
|
+
/** Result of {@link initDirectories}. */
|
|
3
|
+
export interface InitResult {
|
|
4
|
+
configDir: string;
|
|
5
|
+
dataDir: string;
|
|
6
|
+
created: string[];
|
|
7
|
+
kept: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Create config-dir and data-dir (idempotent, never overwrites). */
|
|
10
|
+
export declare function initDirectories(options: {
|
|
11
|
+
configDir: string;
|
|
12
|
+
dataDir: string;
|
|
13
|
+
port?: number;
|
|
14
|
+
}): Promise<InitResult>;
|
|
15
|
+
/** Create the `init` handler. */
|
|
16
|
+
export declare function createInitHandler(io: Pick<CliIo, 'stdout' | 'stderr'>): (opts: InitCliOptions) => Promise<number>;
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `init --config-dir <dir> [--data-dir <dir>] [--port <port>]` (Spec §4):
|
|
3
|
+
* creates the config-dir with a commented example configuration and example
|
|
4
|
+
* scripts, and the data-dir layout. Never overwrites or modifies existing
|
|
5
|
+
* files (each file is created with `O_EXCL`); existing files are reported as
|
|
6
|
+
* kept. Afterwards the resulting configuration is validated.
|
|
7
|
+
*
|
|
8
|
+
* Exit codes: 0 = done (configuration valid), 1 = resulting configuration
|
|
9
|
+
* invalid (e.g. because of pre-existing files) or I/O error, 2 = usage error.
|
|
10
|
+
*/
|
|
11
|
+
import { constants } from 'node:fs';
|
|
12
|
+
import { chmod, mkdir, open } from 'node:fs/promises';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { errorMessage } from '../core/index.js';
|
|
15
|
+
import { formatConfigIssue, loadConfig } from '../config/index.js';
|
|
16
|
+
import { DATA_DIR_LAYOUT, initTemplates } from './init-templates.js';
|
|
17
|
+
/** Create a file only if it does not exist yet. Returns false if it existed. */
|
|
18
|
+
async function createExclusive(file, content, mode) {
|
|
19
|
+
let handle;
|
|
20
|
+
try {
|
|
21
|
+
handle = await open(file, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, mode);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (err.code === 'EEXIST')
|
|
25
|
+
return false;
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
await handle.writeFile(content, 'utf8');
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await handle.close();
|
|
33
|
+
}
|
|
34
|
+
await chmod(file, mode); // independent of the umask
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
/** Create config-dir and data-dir (idempotent, never overwrites). */
|
|
38
|
+
export async function initDirectories(options) {
|
|
39
|
+
const configDir = path.resolve(options.configDir);
|
|
40
|
+
const dataDir = path.resolve(options.dataDir);
|
|
41
|
+
const created = [];
|
|
42
|
+
const kept = [];
|
|
43
|
+
for (const sub of ['', 'workflows', 'views', 'scripts']) {
|
|
44
|
+
await mkdir(path.join(configDir, sub), { recursive: true, mode: 0o750 });
|
|
45
|
+
}
|
|
46
|
+
for (const file of initTemplates({ ...(options.port !== undefined ? { port: options.port } : {}) })) {
|
|
47
|
+
const target = path.join(configDir, file.path);
|
|
48
|
+
if (await createExclusive(target, file.content, file.mode))
|
|
49
|
+
created.push(target);
|
|
50
|
+
else
|
|
51
|
+
kept.push(target);
|
|
52
|
+
}
|
|
53
|
+
await mkdir(dataDir, { recursive: true, mode: 0o750 });
|
|
54
|
+
for (const sub of DATA_DIR_LAYOUT) {
|
|
55
|
+
await mkdir(path.join(dataDir, sub), { recursive: true, mode: 0o750 });
|
|
56
|
+
}
|
|
57
|
+
return { configDir, dataDir, created, kept };
|
|
58
|
+
}
|
|
59
|
+
/** Create the `init` handler. */
|
|
60
|
+
export function createInitHandler(io) {
|
|
61
|
+
return async (opts) => {
|
|
62
|
+
if (!opts.configDir) {
|
|
63
|
+
io.stderr('init: --config-dir is required (e.g. init --config-dir ./config --data-dir ./data)\n');
|
|
64
|
+
return 2;
|
|
65
|
+
}
|
|
66
|
+
let port;
|
|
67
|
+
if (opts.port !== undefined) {
|
|
68
|
+
port = Number(opts.port);
|
|
69
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
70
|
+
io.stderr(`init: invalid --port "${opts.port}"\n`);
|
|
71
|
+
return 2;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
let result;
|
|
75
|
+
try {
|
|
76
|
+
result = await initDirectories({ configDir: opts.configDir, dataDir: opts.dataDir ?? 'data', ...(port !== undefined ? { port } : {}) });
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
io.stderr(`init: ${errorMessage(err)}\n`);
|
|
80
|
+
return 1;
|
|
81
|
+
}
|
|
82
|
+
for (const f of result.created)
|
|
83
|
+
io.stdout(`created ${f}\n`);
|
|
84
|
+
for (const f of result.kept)
|
|
85
|
+
io.stdout(`kept ${f} (exists, not modified)\n`);
|
|
86
|
+
io.stdout(`data dir ${result.dataDir}\n`);
|
|
87
|
+
const loaded = await loadConfig(result.configDir, { dataDir: result.dataDir });
|
|
88
|
+
for (const w of loaded.warnings)
|
|
89
|
+
io.stderr(`warning: ${formatConfigIssue(w)}\n`);
|
|
90
|
+
if (!loaded.ok) {
|
|
91
|
+
io.stderr(`init: the configuration in ${result.configDir} is invalid (existing files were kept):\n` +
|
|
92
|
+
loaded.errors.map((e) => ` ${formatConfigIssue(e)}\n`).join(''));
|
|
93
|
+
return 1;
|
|
94
|
+
}
|
|
95
|
+
const q = (p) => (/^[A-Za-z0-9_@%+=:,./-]+$/.test(p) ? p : `'${p.replace(/'/g, `'\\''`)}'`);
|
|
96
|
+
io.stdout([
|
|
97
|
+
'',
|
|
98
|
+
'Next steps:',
|
|
99
|
+
` adispatch start --config-dir ${q(result.configDir)} --data-dir ${q(result.dataDir)}`,
|
|
100
|
+
` open http://127.0.0.1:${loaded.config.global.server.port}/ and start the "hello" workflow`,
|
|
101
|
+
' configure sources.yaml / identities.yaml and enable workflows/coder.yaml for GitHub (see README.md)',
|
|
102
|
+
'',
|
|
103
|
+
].join('\n'));
|
|
104
|
+
return 0;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** Executable entry point of the `adispatch` binary. */
|
|
3
|
+
import { createConfigValidateHandler } from './config-validate.js';
|
|
4
|
+
import { createConfigReloadHandler, createSchedulerHandler, createShutdownHandler, createStatusHandler } from './control.js';
|
|
5
|
+
import { createInitHandler } from './init.js';
|
|
6
|
+
import { createProgram, processIo } from './program.js';
|
|
7
|
+
import { createServiceInstallHandler, createServiceStatusHandler, createServiceUninstallHandler } from './service.js';
|
|
8
|
+
import { createStartHandler } from './start.js';
|
|
9
|
+
import { createWorkflowDryRunHandler } from './workflow-dry-run.js';
|
|
10
|
+
await createProgram({
|
|
11
|
+
init: createInitHandler(processIo),
|
|
12
|
+
start: createStartHandler(processIo),
|
|
13
|
+
configValidate: createConfigValidateHandler(processIo),
|
|
14
|
+
configReload: createConfigReloadHandler(processIo),
|
|
15
|
+
workflowDryRun: createWorkflowDryRunHandler(processIo),
|
|
16
|
+
status: createStatusHandler(processIo),
|
|
17
|
+
pause: createSchedulerHandler('pause', processIo),
|
|
18
|
+
resume: createSchedulerHandler('resume', processIo),
|
|
19
|
+
drain: createShutdownHandler('drain', processIo),
|
|
20
|
+
cancelAll: createShutdownHandler('cancel-all', processIo),
|
|
21
|
+
serviceInstall: createServiceInstallHandler(processIo),
|
|
22
|
+
serviceStatus: createServiceStatusHandler(processIo),
|
|
23
|
+
serviceUninstall: createServiceUninstallHandler(processIo),
|
|
24
|
+
}, processIo).parseAsync(process.argv);
|
|
25
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,wDAAwD;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC7H,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AACtH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,aAAa,CACjB;IACE,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAAC;IAClC,KAAK,EAAE,kBAAkB,CAAC,SAAS,CAAC;IACpC,cAAc,EAAE,2BAA2B,CAAC,SAAS,CAAC;IACtD,YAAY,EAAE,yBAAyB,CAAC,SAAS,CAAC;IAClD,cAAc,EAAE,2BAA2B,CAAC,SAAS,CAAC;IACtD,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC;IACtC,KAAK,EAAE,sBAAsB,CAAC,OAAO,EAAE,SAAS,CAAC;IACjD,MAAM,EAAE,sBAAsB,CAAC,QAAQ,EAAE,SAAS,CAAC;IACnD,KAAK,EAAE,qBAAqB,CAAC,OAAO,EAAE,SAAS,CAAC;IAChD,SAAS,EAAE,qBAAqB,CAAC,YAAY,EAAE,SAAS,CAAC;IACzD,cAAc,EAAE,2BAA2B,CAAC,SAAS,CAAC;IACtD,aAAa,EAAE,0BAA0B,CAAC,SAAS,CAAC;IACpD,gBAAgB,EAAE,6BAA6B,CAAC,SAAS,CAAC;CAC3D,EACD,SAAS,CACV,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command-line interface definition (Spec §4, §14, §19). The command tree is
|
|
3
|
+
* declared here; the behaviour lives in injectable handlers (see `main.ts`).
|
|
4
|
+
*/
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
/** Options available on every command. */
|
|
7
|
+
export interface GlobalOptions {
|
|
8
|
+
configDir?: string;
|
|
9
|
+
dataDir?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Options of commands talking to a running instance over HTTP. */
|
|
12
|
+
export interface ControlCliOptions extends GlobalOptions {
|
|
13
|
+
/** Base URL of the running instance (default: `server.host`/`server.port` of the config, else `http://127.0.0.1:8787`). */
|
|
14
|
+
url?: string;
|
|
15
|
+
/** Print the raw JSON response. */
|
|
16
|
+
json?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Options of `workflow dry-run`. */
|
|
19
|
+
export interface DryRunCliOptions extends ControlCliOptions {
|
|
20
|
+
/** Evaluate locally even if an instance is running. */
|
|
21
|
+
local?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** Options of `drain` / `cancel-all`. */
|
|
24
|
+
export interface ShutdownCliOptions extends ControlCliOptions {
|
|
25
|
+
/** Wait until the instance has stopped. */
|
|
26
|
+
wait?: boolean;
|
|
27
|
+
/** Maximum wait time with `--wait` (duration, default unlimited). */
|
|
28
|
+
timeout?: string;
|
|
29
|
+
/** Reason recorded for cancelled runs (`cancel-all`). */
|
|
30
|
+
reason?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Options of `start`. */
|
|
33
|
+
export interface StartCliOptions extends GlobalOptions {
|
|
34
|
+
/** SIGTERM drain timeout before cancel-all (duration, default 10m). */
|
|
35
|
+
drainTimeout?: string;
|
|
36
|
+
/** Time for cancelled runs incl. `on_cancel` before hooks are interrupted (duration, default 2m). */
|
|
37
|
+
cancelTimeout?: string;
|
|
38
|
+
/** Override `server.host`. */
|
|
39
|
+
host?: string;
|
|
40
|
+
/** Override `server.port`. */
|
|
41
|
+
port?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Options of `init`. */
|
|
44
|
+
export interface InitCliOptions extends GlobalOptions {
|
|
45
|
+
/** `server.port` written into a newly created config.yaml. */
|
|
46
|
+
port?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Options of the `service` commands. */
|
|
49
|
+
export interface ServiceCliOptions extends GlobalOptions {
|
|
50
|
+
/** Print what would be done (unit file + steps) without changing anything. */
|
|
51
|
+
dryRun?: boolean;
|
|
52
|
+
/** Unit name without `.service` (default `adispatchd`). */
|
|
53
|
+
name?: string;
|
|
54
|
+
/** Dedicated service user (default `adispatchd`). */
|
|
55
|
+
user?: string;
|
|
56
|
+
/** Group (default = user). */
|
|
57
|
+
group?: string;
|
|
58
|
+
/** Create the user if missing. */
|
|
59
|
+
createUser?: boolean;
|
|
60
|
+
/** Absolute node executable (default: the running node). */
|
|
61
|
+
node?: string;
|
|
62
|
+
/** Absolute package entry point (default: this installation's `dist/cli/main.js`). */
|
|
63
|
+
entry?: string;
|
|
64
|
+
/** Environment file for secrets (default `/etc/default/<name>`; `none` disables it). */
|
|
65
|
+
envFile?: string;
|
|
66
|
+
/** Directory for unit files (default `/etc/systemd/system`). */
|
|
67
|
+
unitDir?: string;
|
|
68
|
+
drainTimeout?: string;
|
|
69
|
+
cancelTimeout?: string;
|
|
70
|
+
/** `systemctl enable --now`. */
|
|
71
|
+
now?: boolean;
|
|
72
|
+
}
|
|
73
|
+
/** Exit code used by commands that are not implemented yet. */
|
|
74
|
+
export declare const EXIT_NOT_IMPLEMENTED = 70;
|
|
75
|
+
type Handler<O> = (opts: O) => Promise<number>;
|
|
76
|
+
/** Handlers plugged into the command tree; unimplemented commands print a notice. */
|
|
77
|
+
export interface CliHandlers {
|
|
78
|
+
init?: Handler<InitCliOptions>;
|
|
79
|
+
start?: Handler<StartCliOptions>;
|
|
80
|
+
configValidate?: Handler<GlobalOptions>;
|
|
81
|
+
configReload?: Handler<ControlCliOptions>;
|
|
82
|
+
workflowDryRun?: (workflowId: string, opts: DryRunCliOptions) => Promise<number>;
|
|
83
|
+
status?: Handler<ControlCliOptions>;
|
|
84
|
+
pause?: Handler<ControlCliOptions>;
|
|
85
|
+
resume?: Handler<ControlCliOptions>;
|
|
86
|
+
drain?: Handler<ShutdownCliOptions>;
|
|
87
|
+
cancelAll?: Handler<ShutdownCliOptions>;
|
|
88
|
+
serviceInstall?: Handler<ServiceCliOptions>;
|
|
89
|
+
serviceStatus?: Handler<ServiceCliOptions>;
|
|
90
|
+
serviceUninstall?: Handler<ServiceCliOptions>;
|
|
91
|
+
}
|
|
92
|
+
/** Streams/side effects used by the CLI (injectable for tests). */
|
|
93
|
+
export interface CliIo {
|
|
94
|
+
stdout: (text: string) => void;
|
|
95
|
+
stderr: (text: string) => void;
|
|
96
|
+
setExitCode: (code: number) => void;
|
|
97
|
+
}
|
|
98
|
+
/** CLI I/O bound to the real process streams. */
|
|
99
|
+
export declare const processIo: CliIo;
|
|
100
|
+
/** Build the `adispatch` command tree. */
|
|
101
|
+
export declare function createProgram(handlers?: CliHandlers, io?: CliIo): Command;
|
|
102
|
+
export {};
|