@cyanautomation/kaseki-agent 1.25.1 → 1.25.3

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/README.md CHANGED
@@ -4,7 +4,7 @@ Kaseki is a proof-of-concept ephemeral coding-agent runner. Each run is a number
4
4
 
5
5
  ## Quick Start
6
6
 
7
- ### **Installation (Recommended)**
7
+ ### Installation (Recommended)
8
8
 
9
9
  ```bash
10
10
  # Global install (recommended)
@@ -21,7 +21,7 @@ kaseki-agent list
21
21
  kaseki-agent report kaseki-1
22
22
  ```
23
23
 
24
- ### **Without Global Install**
24
+ ### Without Global Install
25
25
 
26
26
  ```bash
27
27
  npm install @cyanautomation/kaseki-agent
@@ -29,7 +29,7 @@ npx kaseki-agent setup
29
29
  npx kaseki-agent run https://github.com/CyanAutomation/crudmapper main
30
30
  ```
31
31
 
32
- ### **Using Docker** ⭐ (Alternative)
32
+ ### Using Docker ⭐ (Alternative)
33
33
 
34
34
  If you prefer to avoid installing Node.js globally:
35
35
 
@@ -62,23 +62,23 @@ Each produces a numbered instance (kaseki-1, kaseki-2, …) with isolated worksp
62
62
 
63
63
  ## Getting Started
64
64
 
65
- ### **1. Installation & Setup**
65
+ ### Installation & Setup
66
66
 
67
- **Option A: Global NPM**
67
+ #### Option A: Global NPM
68
68
 
69
69
  ```bash
70
70
  npm install -g @cyanautomation/kaseki-agent
71
71
  kaseki-agent setup
72
72
  ```
73
73
 
74
- **Option B: Local NPM**
74
+ #### Option B: Local NPM
75
75
 
76
76
  ```bash
77
77
  npm install @cyanautomation/kaseki-agent
78
78
  npx kaseki-agent setup
79
79
  ```
80
80
 
81
- **Option C: Docker**
81
+ #### Option C: Docker
82
82
 
83
83
  ```bash
84
84
  docker run -it \
@@ -87,13 +87,13 @@ docker run -it \
87
87
  setup
88
88
  ```
89
89
 
90
- ### **2. Verify Installation**
90
+ ### Verify Installation
91
91
 
92
92
  ```bash
93
93
  kaseki-agent doctor
94
94
  ```
95
95
 
96
- ### **2.5. Configure Authentication**
96
+ ### Configure Authentication
97
97
 
98
98
  Kaseki needs three sets of credentials. Choose your preferred setup method:
99
99
 
@@ -134,7 +134,7 @@ See [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) for setting up the kaseki-api servi
134
134
 
135
135
  **👉 Full guide:** [docs/AUTH_SETUP.md](docs/AUTH_SETUP.md)
136
136
 
137
- ### **3. Run Your First Task**
137
+ ### Run Your First Task
138
138
 
139
139
  ```bash
140
140
  # Simple example
@@ -145,7 +145,7 @@ kaseki-agent run https://github.com/CyanAutomation/crudmapper main \
145
145
  "Fix the TypeScript errors in src/"
146
146
  ```
147
147
 
148
- ### **4. View Results**
148
+ ### View Results
149
149
 
150
150
  ```bash
151
151
  # List all instances
@@ -159,7 +159,7 @@ kaseki-agent report kaseki-1
159
159
 
160
160
  ## CLI Commands
161
161
 
162
- ### `setup` — Interactive Configuration Wizard
162
+ #### `setup` — Interactive Configuration Wizard
163
163
 
164
164
  First-time setup to validate environment and store API credentials securely.
165
165
 
@@ -176,7 +176,7 @@ kaseki-agent setup
176
176
  - Saves configuration (project-local or user-global)
177
177
  - Runs doctor checks to verify everything works
178
178
 
179
- ### `run` — Execute Agent on Repository
179
+ #### `run` — Execute Agent on Repository
180
180
 
181
181
  ```bash
182
182
  kaseki-agent run <REPO_URL> [GIT_REF] [TASK_PROMPT]
@@ -205,7 +205,7 @@ kaseki-agent run https://github.com/CyanAutomation/crudmapper main \
205
205
  5. Stream agent output in real-time
206
206
  6. Collect results and generate report
207
207
 
208
- ### `doctor` — Health Check & Validation
208
+ #### `doctor` — Health Check & Validation
209
209
 
210
210
  ```bash
211
211
  kaseki-agent doctor [--json] [--fix]
@@ -226,7 +226,7 @@ kaseki-agent doctor [--json] [--fix]
226
226
  - `--json` — JSON output (useful for scripts)
227
227
  - `--fix` — Attempt auto-remediation (pull image, show install hints)
228
228
 
229
- ### `list` — Show All Instances
229
+ #### `list` — Show All Instances
230
230
 
231
231
  ```bash
232
232
  kaseki-agent list [--status STATE]
@@ -247,7 +247,7 @@ kaseki-agent list --status running
247
247
  - Creation date
248
248
  - Execution duration
249
249
 
250
- ### `report` — View Instance Results
250
+ #### `report` — View Instance Results
251
251
 
252
252
  ```bash
253
253
  kaseki-agent report <INSTANCE_ID>
@@ -260,7 +260,7 @@ kaseki-agent report <INSTANCE_ID>
260
260
  - Final status and exit code
261
261
  - Detailed summary (if available)
262
262
 
263
- ### `config` — Manage Configuration
263
+ #### `config` — Manage Configuration
264
264
 
265
265
  ```bash
266
266
  kaseki-agent config <SUBCOMMAND> [OPTIONS]
@@ -285,7 +285,7 @@ kaseki-agent config show
285
285
  kaseki-agent config locations
286
286
  ```
287
287
 
288
- ### `secrets` — Manage Credentials
288
+ #### `secrets` — Manage Credentials
289
289
 
290
290
  ```bash
291
291
  kaseki-agent secrets <SUBCOMMAND>
@@ -318,7 +318,7 @@ kaseki-agent secrets list
318
318
  - Linux: Uses `pass` (password-store) keyring
319
319
  - Headless: Falls back to `~/.kaseki/secrets/` (0600 permissions)
320
320
 
321
- ### `serve` — Start REST API Service
321
+ #### `serve` — Start REST API Service
322
322
 
323
323
  ```bash
324
324
  kaseki-agent serve [--port PORT]
@@ -373,6 +373,8 @@ Configuration is loaded from (in order of precedence):
373
373
  4. **Environment variables** (`KASEKI_*`, `OPENROUTER_*`, `GITHUB_*`)
374
374
  5. **Built-in defaults**
375
375
 
376
+ ### Example Configuration
377
+
376
378
  **Example `kaseki-agent.json`:**
377
379
 
378
380
  ```json
@@ -391,7 +393,7 @@ Configuration is loaded from (in order of precedence):
391
393
  }
392
394
  ```
393
395
 
394
- **Common Environment Variables:**
396
+ ### Common Environment Variables
395
397
 
396
398
  ```bash
397
399
  # Required
@@ -401,7 +403,10 @@ OPENROUTER_API_KEY_FILE=~/.kaseki/secrets/openrouter_api_key
401
403
  KASEKI_ROOT=/agents # Base directory
402
404
  KASEKI_MODEL=openrouter/free # AI model
403
405
  KASEKI_AGENT_TIMEOUT_SECONDS=1200 # Timeout
404
- KASEKI_VALIDATION_COMMANDS="npm run check;npm run test;npm run build"
406
+ KASEKI_PRE_AGENT_VALIDATION=1 # Validate baseline before Pi
407
+ KASEKI_PRE_AGENT_VALIDATION_COMMANDS="npm run check;npm run test;npm run build"
408
+ KASEKI_VALIDATION_COMMANDS="npm run check;npm run test;npm run build" # Validate final diff after Pi
409
+ KASEKI_STARTUP_CHECK_MODE=boot # boot or baseline-validation for dry-run startup checks
405
410
  ```
406
411
 
407
412
  ---
@@ -410,7 +415,7 @@ KASEKI_VALIDATION_COMMANDS="npm run check;npm run test;npm run build"
410
415
 
411
416
  ### Deployment Patterns
412
417
 
413
- **1. CLI (Direct Execution)**
418
+ #### CLI (Direct Execution)
414
419
 
415
420
  ```bash
416
421
  kaseki-agent run <repo> <ref>
@@ -420,7 +425,7 @@ kaseki-agent run <repo> <ref>
420
425
  - Immediate results
421
426
  - Best for: CI/CD, direct usage
422
427
 
423
- **2. REST API (Distributed)**
428
+ #### REST API (Distributed)
424
429
 
425
430
  ```bash
426
431
  kaseki-agent serve --port 8080
@@ -431,7 +436,7 @@ kaseki-agent serve --port 8080
431
436
  - Async execution
432
437
  - Best for: Controllers, distributed systems
433
438
 
434
- **3. Docker (Self-Contained)**
439
+ #### Docker (Self-Contained)
435
440
 
436
441
  ```bash
437
442
  docker run docker.io/cyanautomation/kaseki-agent:latest run <repo> <ref>
@@ -441,6 +446,8 @@ docker run docker.io/cyanautomation/kaseki-agent:latest run <repo> <ref>
441
446
  - Full isolation
442
447
  - Best for: Clean environments, CI/CD containers
443
448
 
449
+ ### Host and Container Layers
450
+
444
451
  **Host layer** — Management and orchestration:
445
452
 
446
453
  - `run-kaseki.sh` — Direct runner (creates workspace, launches container, cleans up)
@@ -449,13 +456,21 @@ docker run docker.io/cyanautomation/kaseki-agent:latest run <repo> <ref>
449
456
 
450
457
  **Container layer** — Agent execution:
451
458
 
452
- - `kaseki-agent.sh` — Inside the container (clones repo, installs deps, invokes Pi, validates, stores results)
459
+ - `kaseki-agent.sh` — Inside the container (clones repo, installs deps, runs pre-agent validation, invokes Pi, runs post-agent validation, stores results)
453
460
  - `entrypoint.sh` — Container startup orchestrator
454
461
 
462
+ ### Validation Lifecycle
463
+
464
+ 1. Clone the target repo/ref and install dependencies.
465
+ 2. Run **pre-agent validation** when `KASEKI_PRE_AGENT_VALIDATION=1` (default). These commands default to `KASEKI_VALIDATION_COMMANDS` through `KASEKI_PRE_AGENT_VALIDATION_COMMANDS` and execute before Pi so Kaseki can detect an already-failing baseline. Inspect `/agents/kaseki-results/kaseki-N/pre-validation.log`, `/agents/kaseki-results/kaseki-N/pre-validation-raw.log`, `/agents/kaseki-results/kaseki-N/pre-validation-env.log`, and `/agents/kaseki-results/kaseki-N/pre-validation-timings.tsv`.
466
+ 3. Invoke Pi only if the baseline validation succeeds (or pre-agent validation is disabled).
467
+ 4. Restore disallowed changes, run quality gates, then run **post-agent validation** with `KASEKI_VALIDATION_COMMANDS` against the final diff. Inspect `/agents/kaseki-results/kaseki-N/validation.log`, `/agents/kaseki-results/kaseki-N/validation-raw.log`, `/agents/kaseki-results/kaseki-N/validation-env.log`, and `/agents/kaseki-results/kaseki-N/validation-timings.tsv`.
468
+ 5. Record phase exit codes and failure reasons in `/agents/kaseki-results/kaseki-N/metadata.json`; `stage-timings.tsv` shows whether the failing phase was `pre-agent validation` or `validation`.
469
+
455
470
  > **Important:** `kaseki-agent.sh` runs from the Docker image (`/usr/local/bin/kaseki-agent`) and is **not** host-mounted during runs.
456
471
  > For Direct CLI mode, the host needs `run-kaseki.sh` (plus `scripts/kaseki-preflight.sh`) and Docker access; the agent script itself stays inside the image.
457
472
 
458
- **Supporting utilities (Node.js):**
473
+ ### Supporting Utilities (Node.js)
459
474
 
460
475
  - `pi-event-filter.js` — Filters raw Pi JSONL, strips thinking blocks, emits `pi-events.jsonl` + `pi-summary.json`
461
476
  - `kaseki-report.js` — Reads a results directory and prints diagnostic report
@@ -463,7 +478,7 @@ docker run docker.io/cyanautomation/kaseki-agent:latest run <repo> <ref>
463
478
  - `kaseki-api-service.js` — REST API service for remote runs
464
479
  - `kaseki-api-client.ts` — TypeScript client for integration
465
480
 
466
- **Directory layout at runtime:**
481
+ ### Directory Layout at Runtime
467
482
 
468
483
  ```
469
484
  /agents/kaseki-template/ # Dockerfile, scripts (this repo)
@@ -478,7 +493,7 @@ docker run docker.io/cyanautomation/kaseki-agent:latest run <repo> <ref>
478
493
 
479
494
  ## Deployment Modes
480
495
 
481
- ### 1. Direct CLI (run-kaseki.sh)
496
+ ### Direct CLI (run-kaseki.sh)
482
497
 
483
498
  Simplest single-run invocation on a host:
484
499
 
@@ -498,7 +513,7 @@ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
498
513
 
499
514
  ---
500
515
 
501
- ### 2. Remote Activation (kaseki-activate.sh)
516
+ ### Remote Activation (kaseki-activate.sh)
502
517
 
503
518
  For SSH/controller-driven setup and execution. Used by OpenClaw and similar orchestrators.
504
519
 
@@ -564,7 +579,7 @@ Returns newline-delimited JSON for each major step.
564
579
 
565
580
  ---
566
581
 
567
- ### 3. REST API Service (kaseki-api)
582
+ ### REST API Service (kaseki-api)
568
583
 
569
584
  Long-running async orchestration service. Ideal for:
570
585
 
@@ -1174,6 +1189,28 @@ container environment.
1174
1189
 
1175
1190
  3. Install the app on the target repository
1176
1191
 
1192
+ ### Single-line/text PEM private keys
1193
+
1194
+ The preferred approach is to paste the GitHub App private key text into a
1195
+ secret file, then reference that file with `GITHUB_APP_PRIVATE_KEY_FILE`. For
1196
+ example, store the value at `/agents/secrets/github_app_private_key` for
1197
+ container or service deployments, or at `~/secrets/github_app_private_key` for
1198
+ local CLI runs.
1199
+
1200
+ Kaseki normalizes the private key after reading it, so the file may contain the
1201
+ original multi-line PEM, a PEM where newlines are escaped as `\n`, a base64-
1202
+ encoded PEM, or a single-line PEM where spaces are used in place of PEM
1203
+ newlines.
1204
+
1205
+ `GITHUB_APP_PRIVATE_KEY` is only for local `run-kaseki.sh` experiments. Config
1206
+ and API service flows may reject inline private keys because they enforce
1207
+ file-based secrets; use `GITHUB_APP_PRIVATE_KEY_FILE` for those flows.
1208
+
1209
+ > **Security warning:** Never paste real private keys into tickets, prompts,
1210
+ > logs, `.env` files, or source control. If a GitHub App private key is exposed,
1211
+ > regenerate the private key in the GitHub App settings and replace the secret
1212
+ > file everywhere it is used.
1213
+
1177
1214
  ### Setup
1178
1215
 
1179
1216
  ```bash
@@ -1208,10 +1245,12 @@ volumes:
1208
1245
  - /agents:/agents:rw
1209
1246
  ```
1210
1247
 
1211
- `GITHUB_APP_PRIVATE_KEY` is still accepted as a fallback for local experiments,
1212
- including escaped `\n` or single-line PEM values, but avoid it for shared hosts:
1213
- environment variables are easier to leak through process inspection, logs, and
1214
- orchestration UIs.
1248
+ `GITHUB_APP_PRIVATE_KEY` is still accepted as a fallback for local
1249
+ `run-kaseki.sh` experiments, including escaped `\n`, base64 PEM, or
1250
+ single-line PEM values after normalization. Avoid inline private keys for shared
1251
+ hosts: environment variables are easier to leak through process inspection,
1252
+ logs, and orchestration UIs, and config/API service flows may reject inline
1253
+ secrets in favor of file-based secret paths.
1215
1254
 
1216
1255
  ### Behavior
1217
1256
 
@@ -1220,15 +1259,20 @@ When credentials are configured and publishing is enabled:
1220
1259
  1. After validation passes and diff is non-empty, Kaseki generates a GitHub App installation token
1221
1260
  2. Creates a feature branch `kaseki/<instance-name>`
1222
1261
  3. Commits and pushes changes to remote
1223
- 4. Creates a draft PR against the target branch when `KASEKI_PUBLISH_MODE=draft_pr` or API `publishMode` is `draft_pr`, with:
1262
+ 4. Creates a draft PR against the target branch when `KASEKI_PUBLISH_MODE=draft_pr` or API `publishMode` is `draft_pr`; `auto` can also create a draft PR when worker credentials are available, with:
1224
1263
  - Title: `Kaseki: <instance-name>`
1225
1264
  - Body: Model, duration, validation result, quality checks
1226
1265
  - Draft: `true` for safety; review before merging
1227
1266
 
1228
- Publishing modes are `none`, `branch`, and `draft_pr`. Controller requests that
1229
- ask for `branch` or `draft_pr` fail before queueing unless GitHub App credentials
1230
- are readable, so orchestrators can surface a clear setup error instead of waiting
1231
- for a run that cannot publish.
1267
+ Publishing modes are `auto`, `none`, `branch`, and `draft_pr`. Controller
1268
+ requests default omitted `publishMode` to `draft_pr`, so the normal controller
1269
+ path pushes a branch and opens a draft pull request after validation. Explicit
1270
+ API `publishMode: "auto"` is accepted for graceful worker auto publishing: the
1271
+ worker publishes when credentials are available and skips GitHub operations when
1272
+ they are not. Requests that resolve to `branch` or `draft_pr` fail before
1273
+ queueing unless GitHub App credentials are readable, so orchestrators can surface
1274
+ a clear setup error instead of waiting for a run that cannot publish. Set
1275
+ `publishMode` to `none` to opt out of GitHub publishing for a specific API run.
1232
1276
 
1233
1277
  ### Result Artifacts
1234
1278
 
@@ -1259,13 +1303,18 @@ for a run that cannot publish.
1259
1303
  | `KASEKI_AGENT_TIMEOUT_SECONDS` | 1200 | Agent timeout (20 min) |
1260
1304
  | `TASK_PROMPT` | *(code fix task)* | Agent instructions |
1261
1305
  | `KASEKI_TASK_MODE` | patch | `patch` (require diff) or `inspect` (no diff) |
1262
- | `KASEKI_PUBLISH_MODE` | auto | `none`, `branch`, or `draft_pr`; API requests use `publishMode` |
1306
+ | `KASEKI_PUBLISH_MODE` | auto | `auto`, `none`, `branch`, or `draft_pr`; controller API requests default omitted `publishMode` to `draft_pr`, while explicit API `publishMode: "auto"` passes graceful auto publishing to workers |
1307
+ | `KASEKI_STARTUP_CHECK_MODE` | boot | Dry-run startup check depth: `boot` or `baseline-validation` |
1263
1308
 
1264
1309
  ### Validation and Quality Gates
1265
1310
 
1266
1311
  | Variable | Default | Notes |
1267
1312
  |---|---|---|
1268
- | `KASEKI_VALIDATION_COMMANDS` | `npm run check;npm run test;npm run build` | Semicolon-separated; set to `none` to skip. Missing npm scripts are skipped with a warning (non-fatal). |
1313
+ | `KASEKI_PRE_AGENT_VALIDATION` | `1` | Run validation before Pi to detect a failing baseline repo/ref. Set to `0` only when you intentionally want to skip baseline validation. |
1314
+ | `KASEKI_PRE_AGENT_VALIDATION_COMMANDS` | same as `KASEKI_VALIDATION_COMMANDS` | Semicolon-separated pre-agent validation commands. Logs: `pre-validation.log`, `pre-validation-raw.log`, `pre-validation-env.log`, `pre-validation-timings.tsv`. |
1315
+ | `KASEKI_VALIDATION_COMMANDS` | `npm run check;npm run test;npm run build` | Semicolon-separated post-agent validation commands for the final diff; set to `none` or empty to skip post-agent validation. Missing npm scripts are skipped with a warning (non-fatal). Logs: `validation.log`, `validation-raw.log`, `validation-env.log`, `validation-timings.tsv`. |
1316
+ | `KASEKI_STARTUP_CHECK_MODE` | `boot` | For `KASEKI_DRY_RUN=1`, `boot` performs a container smoke test through `/bin/bash`; `baseline-validation` runs `/usr/local/bin/kaseki-agent` to clone, install dependencies, run pre-agent validation, and skip Pi. |
1317
+ | `KASEKI_BASELINE_VALIDATION_DRY_RUN` | `0` | Internal/API switch set with `baseline-validation` so pre-agent validation runs even though Pi remains disabled. |
1269
1318
  | `KASEKI_CHANGED_FILES_ALLOWLIST` | `src/lib/parser.ts tests/parser.validation.ts` | Space-separated patterns |
1270
1319
  | `KASEKI_MAX_DIFF_BYTES` | 200000 | Max diff size (200 KB) |
1271
1320
  | `KASEKI_ALLOW_EMPTY_DIFF` | 0 | Set to `1` to allow empty diff with `KASEKI_TASK_MODE=patch` |
@@ -1277,6 +1326,8 @@ for a run that cannot publish.
1277
1326
 
1278
1327
  API controllers may send either the direct fields (`changedFilesAllowlist`, `validationCommands`) or the structured aliases (`allowlist.include`, `validation.commands`). The scheduler normalizes both forms before launching the worker.
1279
1328
 
1329
+ Startup checks have two depths. Boot-only startup checks (`startupCheck: true`, `startupCheckMode: "boot"`, or `KASEKI_DRY_RUN=1 KASEKI_STARTUP_CHECK_MODE=boot`) use the minimal container boot path to verify runtime tools, mounts, and secrets without cloning the repository. Baseline validation startup checks (`startupCheckMode: "baseline-validation"`, or a startup check with validation commands) keep dry-run/Pi-skipping behavior but invoke `/usr/local/bin/kaseki-agent` far enough to clone the repository, prepare dependencies, and execute the pre-agent validation commands. A failure in this mode means the requested baseline already failed before any Pi-authored changes existed; inspect `pre-validation.log` and `pre-validation-timings.tsv`.
1330
+
1280
1331
  ### Paths and Caching
1281
1332
 
1282
1333
  | Variable | Default | Notes |
@@ -132,10 +132,10 @@ export declare const ConfigSchema: z.ZodObject<{
132
132
  publish_mode: z.ZodOptional<z.ZodOptional<z.ZodEnum<["auto", "on", "off"]>>>;
133
133
  }, "strip", z.ZodTypeAny, {
134
134
  app_enabled?: boolean | undefined;
135
- publish_mode?: "off" | "auto" | "on" | undefined;
135
+ publish_mode?: "auto" | "off" | "on" | undefined;
136
136
  }, {
137
137
  app_enabled?: boolean | undefined;
138
- publish_mode?: "off" | "auto" | "on" | undefined;
138
+ publish_mode?: "auto" | "off" | "on" | undefined;
139
139
  }>>;
140
140
  docker: z.ZodOptional<z.ZodObject<{
141
141
  image: z.ZodOptional<z.ZodOptional<z.ZodString>>;
@@ -254,7 +254,7 @@ export declare const ConfigSchema: z.ZodObject<{
254
254
  } | undefined;
255
255
  github?: {
256
256
  app_enabled?: boolean | undefined;
257
- publish_mode?: "off" | "auto" | "on" | undefined;
257
+ publish_mode?: "auto" | "off" | "on" | undefined;
258
258
  } | undefined;
259
259
  docker?: {
260
260
  image?: string | undefined;
@@ -325,7 +325,7 @@ export declare const ConfigSchema: z.ZodObject<{
325
325
  } | undefined;
326
326
  github?: {
327
327
  app_enabled?: boolean | undefined;
328
- publish_mode?: "off" | "auto" | "on" | undefined;
328
+ publish_mode?: "auto" | "off" | "on" | undefined;
329
329
  } | undefined;
330
330
  docker?: {
331
331
  image?: string | undefined;
@@ -0,0 +1,9 @@
1
+ export interface GitHubAppPrivateKeyValidationResult {
2
+ ok: boolean;
3
+ normalized?: string;
4
+ error?: string;
5
+ remediation?: string;
6
+ }
7
+ export declare function normalizeGitHubAppPrivateKey(value: string): string;
8
+ export declare function validateGitHubAppPrivateKey(value: string): GitHubAppPrivateKeyValidationResult;
9
+ //# sourceMappingURL=github-app-private-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-private-key.d.ts","sourceRoot":"","sources":["../src/github-app-private-key.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mCAAmC;IAClD,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA0DD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBlE;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,mCAAmC,CAiD9F"}
@@ -0,0 +1,98 @@
1
+ import crypto from 'crypto';
2
+ const PRIVATE_KEY_HEADER_PATTERN = /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/;
3
+ const ANY_PEM_HEADER_PATTERN = /-----BEGIN [^-]+-----/;
4
+ const MAX_CRYPTO_ERROR_LENGTH = 240;
5
+ function hasPrivateKeyPemHeader(value) {
6
+ return PRIVATE_KEY_HEADER_PATTERN.test(value);
7
+ }
8
+ function looksLikeBase64(value) {
9
+ const compact = value.replace(/\s+/g, '');
10
+ return (compact.length > 0 &&
11
+ compact.length % 4 === 0 &&
12
+ /^[A-Za-z0-9+/]+={0,2}$/.test(compact));
13
+ }
14
+ function removeMatchingOuterQuotes(value) {
15
+ if (value.length >= 2) {
16
+ const first = value[0];
17
+ const last = value[value.length - 1];
18
+ if ((first === '"' || first === "'") && first === last) {
19
+ return value.slice(1, -1);
20
+ }
21
+ }
22
+ return value;
23
+ }
24
+ function normalizePrivateKeyText(value) {
25
+ return removeMatchingOuterQuotes(value.replace(/^\uFEFF/, '').trim().replace(/\\n/g, '\n'));
26
+ }
27
+ function rewrapPrivateKeyPem(value) {
28
+ return value.replace(/-----BEGIN ([A-Z0-9 ]*PRIVATE KEY)-----([\s\S]*?)-----END \1-----/g, (_match, type, body) => {
29
+ const compactBody = body.replace(/\s+/g, '');
30
+ const bodyLines = compactBody.match(/.{1,64}/g) || [];
31
+ return `-----BEGIN ${type}-----\n${bodyLines.join('\n')}\n-----END ${type}-----\n`;
32
+ });
33
+ }
34
+ function sanitizeCryptoError(error) {
35
+ const rawMessage = error instanceof Error ? error.message : String(error);
36
+ const normalizedMessage = rawMessage.replace(/\s+/g, ' ').trim();
37
+ if (normalizedMessage.length <= MAX_CRYPTO_ERROR_LENGTH) {
38
+ return normalizedMessage;
39
+ }
40
+ return `${normalizedMessage.slice(0, MAX_CRYPTO_ERROR_LENGTH)}...`;
41
+ }
42
+ export function normalizeGitHubAppPrivateKey(value) {
43
+ let normalizedPem = rewrapPrivateKeyPem(normalizePrivateKeyText(value));
44
+ if (!hasPrivateKeyPemHeader(normalizedPem) && looksLikeBase64(normalizedPem)) {
45
+ const decodedPem = Buffer.from(normalizedPem.replace(/\s+/g, ''), 'base64').toString('utf8');
46
+ if (hasPrivateKeyPemHeader(decodedPem) ||
47
+ ANY_PEM_HEADER_PATTERN.test(decodedPem)) {
48
+ normalizedPem = rewrapPrivateKeyPem(normalizePrivateKeyText(decodedPem));
49
+ }
50
+ }
51
+ return normalizedPem;
52
+ }
53
+ export function validateGitHubAppPrivateKey(value) {
54
+ const normalized = normalizeGitHubAppPrivateKey(value);
55
+ if (normalized.includes('-----BEGIN OPENSSH PRIVATE KEY-----')) {
56
+ return {
57
+ ok: false,
58
+ error: 'GitHub App private key uses OpenSSH format. GitHub App keys must be the PEM downloaded from GitHub App settings.',
59
+ remediation: 'Download a new private key from the GitHub App settings page and store that PEM content in the github_app_private_key secret file.',
60
+ };
61
+ }
62
+ if (normalized.includes('-----BEGIN ENCRYPTED PRIVATE KEY-----')) {
63
+ return {
64
+ ok: false,
65
+ error: 'GitHub App private key is encrypted. Encrypted keys are not supported unless passphrase support is added.',
66
+ remediation: 'Store an unencrypted GitHub App private key PEM in the github_app_private_key secret file.',
67
+ };
68
+ }
69
+ if (/-----BEGIN [^-]*(PUBLIC KEY|CERTIFICATE)-----/.test(normalized)) {
70
+ return {
71
+ ok: false,
72
+ error: 'GitHub App private key file contains a public key or certificate; this is not the GitHub App private key.',
73
+ remediation: 'Replace github_app_private_key with the private-key PEM downloaded from GitHub App settings, not a public key or certificate.',
74
+ };
75
+ }
76
+ if (!hasPrivateKeyPemHeader(normalized)) {
77
+ return {
78
+ ok: false,
79
+ error: 'GitHub App private key file does not contain a private-key PEM header after normalization/base64 decode. Expected -----BEGIN ... PRIVATE KEY-----.',
80
+ remediation: 'The github_app_private_key secret file must contain the complete PEM private key downloaded from GitHub App settings, including BEGIN and END lines.',
81
+ };
82
+ }
83
+ try {
84
+ crypto.createPrivateKey(normalized);
85
+ }
86
+ catch (error) {
87
+ return {
88
+ ok: false,
89
+ error: `GitHub App private key is not a valid PEM private key: ${sanitizeCryptoError(error)}`,
90
+ remediation: 'Regenerate the GitHub App private key in GitHub App settings and replace the github_app_private_key secret file with the complete downloaded PEM.',
91
+ };
92
+ }
93
+ return {
94
+ ok: true,
95
+ normalized,
96
+ };
97
+ }
98
+ //# sourceMappingURL=github-app-private-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-private-key.js","sourceRoot":"","sources":["../src/github-app-private-key.ts"],"names":[],"mappings":"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"}
@@ -15,10 +15,21 @@
15
15
  import fs from 'fs';
16
16
  import crypto from 'crypto';
17
17
  import https from 'https';
18
+ import { validateGitHubAppPrivateKey } from './github-app-private-key.js';
18
19
  const APP_ID = process.argv[2];
19
20
  const PRIVATE_KEY_FILE = process.argv[3];
20
21
  const OWNER = process.argv[4];
21
22
  const REPO = process.argv[5];
23
+ function loadAndValidatePrivateKey(privateKeyFile) {
24
+ const validation = validateGitHubAppPrivateKey(fs.readFileSync(privateKeyFile, 'utf8'));
25
+ if (!validation.ok || !validation.normalized) {
26
+ const message = validation.remediation
27
+ ? `${validation.error} ${validation.remediation}`
28
+ : validation.error;
29
+ throw new Error(message || 'GitHub App private key is not valid.');
30
+ }
31
+ return crypto.createPrivateKey(validation.normalized);
32
+ }
22
33
  async function generateJWT(appId, privateKey) {
23
34
  const now = Math.floor(Date.now() / 1000);
24
35
  const iat = now - 60; // account for clock skew
@@ -124,8 +135,8 @@ async function main() {
124
135
  process.exit(1);
125
136
  }
126
137
  try {
127
- // Read private key
128
- const privateKey = fs.readFileSync(PRIVATE_KEY_FILE, 'utf8');
138
+ // Read and validate private key
139
+ const privateKey = loadAndValidatePrivateKey(PRIVATE_KEY_FILE);
129
140
  // Generate JWT
130
141
  const jwt = await generateJWT(APP_ID, privateKey);
131
142
  // Get installation ID
@@ -1 +1 @@
1
- {"version":3,"file":"github-app-token.js","sourceRoot":"","sources":["../src/github-app-token.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"github-app-token.js","sourceRoot":"","sources":["../src/github-app-token.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AA8BvE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/B,MAAM,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAE7B,SAAS,yBAAyB,CAAC,cAAsB;IACvD,MAAM,UAAU,GAAG,2BAA2B,CAC5C,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CACxC,CAAC;IAEF,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW;YACpC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,WAAW,EAAE;YACjD,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,sCAAsC,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,UAA4B;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,yBAAyB;IAC/C,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,aAAa;IAExC,MAAM,MAAM,GAAc;QACxB,GAAG,EAAE,OAAO;QACZ,GAAG,EAAE,KAAK;KACX,CAAC;IAEF,MAAM,OAAO,GAAe;QAC1B,GAAG,EAAE,KAAK;QACV,GAAG;QACH,GAAG;KACJ,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/E,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,GAAG,YAAY,IAAI,aAAa,EAAE,CAAC;IAEnD,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,CAAC,GAAG,EAAE,CAAC;IAEb,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACvD,OAAO,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,KAAa,EAAE,IAAY;IACvE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG;YACd,QAAQ,EAAE,gBAAgB;YAC1B,IAAI,EAAE,UAAU,KAAK,IAAI,IAAI,eAAe;YAC5C,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,GAAG,EAAE;gBAChC,QAAQ,EAAE,iDAAiD;gBAC3D,YAAY,EAAE,cAAc;aAC7B;SACF,CAAC;QAEF,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzC,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC/B,IAAI,IAAI,KAAK,CAAC;YAChB,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC3B,MAAM,CACJ,IAAI,KAAK,CACP,kCAAkC,GAAG,CAAC,UAAU,IAAI,IAAI,EAAE,CAC3D,CACF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC;wBACH,MAAM,IAAI,GAA2B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACtD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACnB,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,MAAM,CACJ,IAAI,KAAK,CACP,0CACE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAC3C,EAAE,CACH,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,GAAW,EACX,cAAsB;IAEtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG;YACd,QAAQ,EAAE,gBAAgB;YAC1B,IAAI,EAAE,sBAAsB,cAAc,gBAAgB;YAC1D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,GAAG,EAAE;gBAChC,QAAQ,EAAE,iDAAiD;gBAC3D,YAAY,EAAE,cAAc;gBAC5B,gBAAgB,EAAE,GAAG;aACtB;SACF,CAAC;QAEF,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzC,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC/B,IAAI,IAAI,KAAK,CAAC;YAChB,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC3B,MAAM,CACJ,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC,CACnE,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC;wBACH,MAAM,IAAI,GAAwB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACnD,OAAO,CAAC;4BACN,KAAK,EAAE,IAAI,CAAC,KAAK;4BACjB,UAAU,EAAE,IAAI,CAAC,UAAU;yBAC5B,CAAC,CAAC;oBACL,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,MAAM,CACJ,IAAI,KAAK,CACP,mCACE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAC3C,EAAE,CACH,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACpD,OAAO,CAAC,KAAK,CACX,4EAA4E,CAC7E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,gCAAgC;QAChC,MAAM,UAAU,GAAG,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;QAE/D,eAAe;QACf,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAElD,sBAAsB;QACtB,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAEjE,mBAAmB;QACnB,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAE5D,wBAAwB;QACxB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uBAAuB;QACvB,MAAM,MAAM,GAAgB;YAC1B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"job-scheduler.d.ts","sourceRoot":"","sources":["../src/job-scheduler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAoC,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAclD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAa;IAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kCAAkC,CAAQ;IAClE,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,iBAAiB,CAA6C;IACtE,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,aAAa,CAAC,CAAmC;IACzD,OAAO,CAAC,kBAAkB,CAAwB;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;gBAErC,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;IAcrH;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IAoDlD;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAInC;;;;OAIG;IACH,QAAQ,IAAI,GAAG,EAAE;IAIjB;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IA0EtC;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,UAAU;IAuMlB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,mBAAmB;IAuD3B,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,4BAA4B;IA0BpC,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,yBAAyB;IAIjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,gBAAgB;IAYxB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,GAAG,IAAI;IAS5D,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoB5E,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,cAAc,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;IAQ7E,YAAY,IAAI;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE;IAqBrD;;OAEG;IACH,QAAQ,IAAI,IAAI;CAqDjB"}
1
+ {"version":3,"file":"job-scheduler.d.ts","sourceRoot":"","sources":["../src/job-scheduler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAoC,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAclD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAa;IAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kCAAkC,CAAQ;IAClE,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,iBAAiB,CAA6C;IACtE,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,aAAa,CAAC,CAAmC;IACzD,OAAO,CAAC,kBAAkB,CAAwB;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;gBAErC,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;IAcrH;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IAoDlD;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAInC;;;;OAIG;IACH,QAAQ,IAAI,GAAG,EAAE;IAIjB;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IA0EtC;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,UAAU;IAiNlB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,mBAAmB;IAuD3B,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,4BAA4B;IA0BpC,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,yBAAyB;IAIjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAsCnB,OAAO,CAAC,gBAAgB;IAYxB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,GAAG,IAAI;IAS5D,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoB5E,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,2BAA2B;IAYnC,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,cAAc,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;IAQ7E,YAAY,IAAI;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE;IAqBrD;;OAEG;IACH,QAAQ,IAAI,IAAI;CAqDjB"}
@@ -224,24 +224,33 @@ export class JobScheduler {
224
224
  // directory so the API does not accidentally reserve the final result path.
225
225
  KASEKI_LOG_DIR: this.config.resultsDir,
226
226
  KASEKI_TASK_MODE: job.request.taskMode || this.config.defaultTaskMode,
227
- ...(job.request.publishMode ? { KASEKI_PUBLISH_MODE: job.request.publishMode } : {}),
227
+ KASEKI_PUBLISH_MODE: job.request.publishMode || 'draft_pr',
228
228
  KASEKI_MAX_DIFF_BYTES: String(job.request.maxDiffBytes || this.config.maxDiffBytes),
229
229
  KASEKI_AGENT_TIMEOUT_SECONDS: String(effectiveTimeoutSeconds),
230
230
  };
231
231
  this.populateGitHubAppEnv(env);
232
+ const validationCommands = job.request.validationCommands ?? job.request.validation?.commands;
233
+ const startupCheckMode = job.request.startupCheckMode || (job.request.startupCheck && validationCommands ? 'baseline-validation' : 'boot');
232
234
  if (job.request.startupCheck) {
233
235
  env.KASEKI_DRY_RUN = '1';
234
236
  env.KASEKI_TASK_MODE = 'inspect';
235
- env.KASEKI_VALIDATION_COMMANDS = 'none';
237
+ env.KASEKI_STARTUP_CHECK_MODE = startupCheckMode;
238
+ if (startupCheckMode === 'baseline-validation') {
239
+ env.KASEKI_BASELINE_VALIDATION_DRY_RUN = '1';
240
+ }
241
+ else {
242
+ env.KASEKI_VALIDATION_COMMANDS = 'none';
243
+ }
236
244
  env.TASK_PROMPT =
237
245
  job.request.taskPrompt ||
238
- 'Run Kaseki startup checks only. Verify container boot and dependencies, then exit without agent work.';
246
+ (startupCheckMode === 'baseline-validation'
247
+ ? 'Run Kaseki baseline validation startup checks only. Clone the repo, install dependencies, run pre-agent validation, then exit without Pi agent work.'
248
+ : 'Run Kaseki startup checks only. Verify container boot and dependencies, then exit without agent work.');
239
249
  }
240
250
  const changedFilesAllowlist = job.request.changedFilesAllowlist ?? job.request.allowlist?.include;
241
251
  if (changedFilesAllowlist) {
242
252
  env.KASEKI_CHANGED_FILES_ALLOWLIST = changedFilesAllowlist.join(' ');
243
253
  }
244
- const validationCommands = job.request.validationCommands ?? job.request.validation?.commands;
245
254
  if (validationCommands) {
246
255
  env.KASEKI_VALIDATION_COMMANDS = validationCommands.join(';');
247
256
  }