@cyanautomation/kaseki-agent 1.40.2 → 1.41.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.
@@ -1 +1 @@
1
- {"version":3,"file":"kaseki-api-web.d.ts","sourceRoot":"","sources":["../src/kaseki-api-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAubjC,wBAAgB,eAAe,IAAI,MAAM,CAQxC"}
1
+ {"version":3,"file":"kaseki-api-web.d.ts","sourceRoot":"","sources":["../src/kaseki-api-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AA+fjC,wBAAgB,eAAe,IAAI,MAAM,CAQxC"}
@@ -152,9 +152,88 @@ const controllerPage = String.raw `<!doctype html>
152
152
  .action-row.controller-actions { justify-content: start; }
153
153
  .run-status { grid-template-columns: minmax(0, 1fr) minmax(160px, max-content); }
154
154
  }
155
+ .tabs-nav {
156
+ display: flex;
157
+ gap: var(--space-2);
158
+ border-bottom: 2px solid var(--line);
159
+ margin-bottom: var(--space-3);
160
+ }
161
+ .tabs-nav button {
162
+ background: transparent;
163
+ border: none;
164
+ color: var(--muted);
165
+ cursor: pointer;
166
+ font-size: 16px;
167
+ font-weight: 600;
168
+ padding: var(--space-2) var(--space-3);
169
+ border-bottom: 3px solid transparent;
170
+ margin-bottom: -2px;
171
+ transition: color 0.2s, border-color 0.2s;
172
+ }
173
+ .tabs-nav button:hover { color: var(--ink); }
174
+ .tabs-nav button.active {
175
+ color: var(--focus);
176
+ border-bottom-color: var(--focus);
177
+ }
178
+ .tabs-nav button:focus {
179
+ outline: 3px solid color-mix(in srgb, var(--focus) 35%, transparent);
180
+ outline-offset: 2px;
181
+ }
182
+ .tab-content {
183
+ display: grid;
184
+ gap: var(--space-3);
185
+ }
186
+ .tab-content.hidden { display: none; }
187
+ .health-checks-grid {
188
+ display: grid;
189
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
190
+ gap: var(--space-3);
191
+ }
192
+ .health-check-button {
193
+ background: var(--focus);
194
+ color: #fff;
195
+ padding: var(--space-3);
196
+ border-radius: 8px;
197
+ border: none;
198
+ cursor: pointer;
199
+ font-weight: 600;
200
+ min-height: 100px;
201
+ display: flex;
202
+ flex-direction: column;
203
+ align-items: center;
204
+ justify-content: center;
205
+ gap: var(--space-2);
206
+ transition: background 0.2s, opacity 0.2s;
207
+ }
208
+ .health-check-button:hover:not(:disabled) { background: #1a5d5f; }
209
+ .health-check-button:disabled { opacity: 0.65; cursor: wait; }
210
+ .health-check-button:focus {
211
+ outline: 3px solid color-mix(in srgb, var(--focus) 35%, transparent);
212
+ outline-offset: 1px;
213
+ }
214
+ .health-check-status {
215
+ display: inline-flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ width: 24px;
219
+ height: 24px;
220
+ font-size: 12px;
221
+ }
222
+ .health-check-status.spinner::after {
223
+ content: '⟳';
224
+ display: inline-block;
225
+ animation: spin 1s linear infinite;
226
+ }
227
+ @keyframes spin {
228
+ from { transform: rotate(0deg); }
229
+ to { transform: rotate(360deg); }
230
+ }
231
+ .health-check-status.ok::before { content: '✓'; }
232
+ .health-check-status.bad::before { content: '✕'; }
155
233
  @media (max-width: 767px) {
156
234
  .action-row.run-actions > .run { order: 1; }
157
235
  .response-panel { min-height: 52vh; }
236
+ .health-checks-grid { grid-template-columns: repeat(2, 1fr); }
158
237
  }
159
238
  </style>
160
239
  </head>
@@ -163,19 +242,42 @@ const controllerPage = String.raw `<!doctype html>
163
242
  <section class="panel" aria-labelledby="page-title">
164
243
  <header>
165
244
  <h1 id="page-title">Kaseki Task Console</h1>
166
- <p>Submit a repository task to this Kaseki API controller and inspect its checks before a run.</p>
245
+ <p>Check system health and submit repository tasks to the Kaseki API controller.</p>
167
246
  </header>
168
247
  </section>
169
- <section class="panel stack" aria-labelledby="run-configuration-heading">
170
- <div>
171
- <h2 id="run-configuration-heading">Run configuration</h2>
248
+ <section class="panel stack" aria-labelledby="tabs-heading">
249
+ <div class="tabs-nav" role="tablist" aria-label="Console tabs">
250
+ <button class="tab-button active" data-tab="health" role="tab" aria-selected="true" aria-controls="health-tab">Health</button>
251
+ <button class="tab-button" data-tab="submit" role="tab" aria-selected="false" aria-controls="submit-tab">Submit Task</button>
252
+ </div>
253
+ <div id="health-tab" class="tab-content" role="tabpanel" aria-labelledby="health-heading">
254
+ <div>
255
+ <h2 id="health-heading">Controller Health Checks</h2>
256
+ <p>Run diagnostics to verify the Kaseki API controller is operating correctly.</p>
257
+ </div>
258
+ <div class="health-checks-grid">
259
+ <button class="health-check-button" data-probe="/health" type="button">Health<span class="health-check-status" data-status="health"></span></button>
260
+ <button class="health-check-button" data-probe="/ready" type="button">Readiness<span class="health-check-status" data-status="readiness"></span></button>
261
+ <button class="health-check-button" data-probe="/api/preflight" data-auth="true" type="button">Preflight<span class="health-check-status" data-status="preflight"></span></button>
262
+ <button class="health-check-button" id="status-check" type="button">Check Status<span class="health-check-status" data-status="status"></span></button>
263
+ </div>
264
+ <div class="form-field">
265
+ <label for="run-id">Run ID (for Check Status)</label>
266
+ <input id="run-id" placeholder="Filled after a run is submitted">
267
+ </div>
268
+ <div id="state" role="status" aria-live="polite"></div>
172
269
  </div>
270
+ <div id="submit-tab" class="tab-content hidden" role="tabpanel" aria-labelledby="submit-heading">
271
+ <div>
272
+ <h2 id="submit-heading">Submit Repository Task</h2>
273
+ <p>Configure and submit a task for the ephemeral agent to execute.</p>
274
+ </div>
173
275
  <form id="run-form">
174
276
  <fieldset class="form-fields">
175
- <legend>Task submission</legend>
277
+ <legend>Required information</legend>
176
278
  <div class="form-field">
177
279
  <label for="token">API bearer token</label>
178
- <input id="token" name="token" type="password" autocomplete="off" placeholder="Required for preflight and task actions">
280
+ <input id="token" name="token" type="password" autocomplete="off" placeholder="Required to submit tasks">
179
281
  <p class="field-helper">Stored in this tab only after a successful request.</p>
180
282
  <p class="field-error" data-error-for="token" aria-live="polite"></p>
181
283
  </div>
@@ -184,64 +286,17 @@ const controllerPage = String.raw `<!doctype html>
184
286
  <input id="repo-url" name="repoUrl" type="url" required placeholder="https://github.com/org/repo">
185
287
  <p class="field-error" data-error-for="repoUrl" aria-live="polite"></p>
186
288
  </div>
187
- <div class="grid">
188
- <div class="form-field">
189
- <label for="ref">Git ref</label>
190
- <input id="ref" name="ref" value="main" required>
191
- <p class="field-error" data-error-for="ref" aria-live="polite"></p>
192
- </div>
193
- <div class="form-field">
194
- <label for="publish-mode">Publish mode</label>
195
- <select id="publish-mode" name="publishMode">
196
- <option value="pr">Pull request</option>
197
- <option value="draft_pr">Draft pull request</option>
198
- <option value="branch">Branch only</option>
199
- <option value="auto">Auto</option>
200
- <option value="none">Do not publish</option>
201
- </select>
202
- <p class="field-error" data-error-for="publishMode" aria-live="polite"></p>
203
- </div>
204
- </div>
205
- <div class="grid">
206
- <div class="form-field">
207
- <label for="task-mode">Task mode</label>
208
- <select id="task-mode" name="taskMode">
209
- <option value="patch">Patch</option>
210
- <option value="inspect">Inspect</option>
211
- </select>
212
- <p class="field-error" data-error-for="taskMode" aria-live="polite"></p>
213
- </div>
214
- <div class="form-field">
215
- <label for="timeout-seconds">Timeout seconds</label>
216
- <input id="timeout-seconds" name="timeoutSeconds" type="number" min="60" max="10800" placeholder="Controller default">
217
- <p class="field-error" data-error-for="timeoutSeconds" aria-live="polite"></p>
218
- </div>
219
- </div>
220
289
  <div class="form-field">
221
290
  <label for="task-prompt">Task details</label>
222
291
  <textarea id="task-prompt" name="taskPrompt" required minlength="10" placeholder="Describe the task for the ephemeral agent."></textarea>
223
292
  <p class="field-error" data-error-for="taskPrompt" aria-live="polite"></p>
224
293
  </div>
225
- </fieldset>
226
- <fieldset aria-describedby="run-options-helper">
227
- <legend>Run options</legend>
228
- <p class="field-helper" id="run-options-helper">These options change how the run executes.</p>
229
- <div class="checks">
230
- <label class="check">
231
- <input name="scouting" type="checkbox" checked>
232
- <span class="check-copy">
233
- <span class="check-label">Enable scouting</span>
234
- <span class="check-helper">Runs an additional scouting pass before the main task.</span>
235
- </span>
236
- </label>
237
- <label class="check">
238
- <input name="startupCheck" type="checkbox">
239
- <span class="check-copy">
240
- <span class="check-label">Startup check only</span>
241
- <span class="check-helper">Performs startup checks only and skips task execution.</span>
242
- </span>
243
- </label>
244
- </div>
294
+ <!-- Hidden fields with defaults -->
295
+ <input id="ref" name="ref" type="hidden" value="main">
296
+ <input id="publish-mode" name="publishMode" type="hidden" value="auto">
297
+ <input id="task-mode" name="taskMode" type="hidden" value="patch">
298
+ <input id="timeout-seconds" name="timeoutSeconds" type="hidden" value="10800">
299
+ <input id="scouting" name="scouting" type="hidden" value="true">
245
300
  </fieldset>
246
301
  <fieldset>
247
302
  <legend>Run actions</legend>
@@ -251,29 +306,7 @@ const controllerPage = String.raw `<!doctype html>
251
306
  </div>
252
307
  </fieldset>
253
308
  </form>
254
- </section>
255
- <section class="panel stack" aria-labelledby="controller-checks-heading">
256
- <div>
257
- <h2 id="controller-checks-heading">Controller checks</h2>
258
- <p>Health and readiness are public probes. Controller preflight uses the bearer token.</p>
259
309
  </div>
260
- <fieldset>
261
- <legend>Controller actions</legend>
262
- <div class="action-row controller-actions">
263
- <button class="secondary" data-probe="/health" type="button">Health</button>
264
- <button class="secondary" data-probe="/ready" type="button">Readiness</button>
265
- <button class="secondary" data-probe="/api/preflight" data-auth="true" type="button">Preflight</button>
266
- <button class="secondary" id="status" type="button">Check status</button>
267
- </div>
268
- <div class="run-status">
269
- <div class="form-field">
270
- <label for="run-id">Run ID</label>
271
- <input id="run-id" placeholder="Filled after a run is submitted">
272
- <p class="field-error" data-error-for="runId" aria-live="polite"></p>
273
- </div>
274
- </div>
275
- </fieldset>
276
- <div id="state" role="status" aria-live="polite"></div>
277
310
  </section>
278
311
  <section class="panel stack" aria-labelledby="responses-heading">
279
312
  <div>
@@ -281,7 +314,7 @@ const controllerPage = String.raw `<!doctype html>
281
314
  </div>
282
315
  <div class="response-panel">
283
316
  <p class="response-meta" id="output-meta" aria-live="polite">Status: idle</p>
284
- <pre class="response-log empty" id="output" aria-live="polite">No output yet. Run a controller action to see responses and events.</pre>
317
+ <pre class="response-log empty" id="output" aria-live="polite">No output yet. Run a health check or submit a task to see responses.</pre>
285
318
  </div>
286
319
  </section>
287
320
  </main>
@@ -323,21 +356,18 @@ const controllerPage = String.raw `<!doctype html>
323
356
 
324
357
  function requestBody() {
325
358
  const data = new FormData(form);
326
- const timeoutSeconds = String(data.get('timeoutSeconds') || '').trim();
359
+ const timeoutSeconds = String(data.get('timeoutSeconds') || '10800').trim();
327
360
  const body = {
328
361
  repoUrl: String(data.get('repoUrl') || '').trim(),
329
362
  ref: String(data.get('ref') || 'main').trim(),
330
363
  taskPrompt: String(data.get('taskPrompt') || '').trim(),
331
- publishMode: String(data.get('publishMode') || 'pr'),
364
+ publishMode: String(data.get('publishMode') || 'auto'),
332
365
  taskMode: String(data.get('taskMode') || 'patch'),
366
+ scouting: { enabled: true },
333
367
  };
334
- if (data.get('scouting')) body.scouting = { enabled: true };
335
- if (data.get('startupCheck')) body.startupCheck = true;
336
- if (timeoutSeconds) {
337
- const parsed = Number(timeoutSeconds);
338
- if (!isNaN(parsed)) {
339
- body.timeoutSeconds = parsed;
340
- }
368
+ const parsed = Number(timeoutSeconds);
369
+ if (!isNaN(parsed)) {
370
+ body.timeoutSeconds = parsed;
341
371
  }
342
372
  return body;
343
373
  }
@@ -389,16 +419,57 @@ const controllerPage = String.raw `<!doctype html>
389
419
  }
390
420
  }
391
421
 
422
+ // Tab switching
423
+ document.querySelectorAll('.tab-button').forEach((button) => {
424
+ button.addEventListener('click', () => {
425
+ const tabName = button.dataset.tab;
426
+ // Update tab buttons
427
+ document.querySelectorAll('.tab-button').forEach(b => {
428
+ b.classList.toggle('active', b.dataset.tab === tabName);
429
+ b.setAttribute('aria-selected', b.dataset.tab === tabName ? 'true' : 'false');
430
+ });
431
+ // Update tab content
432
+ document.querySelectorAll('.tab-content').forEach(content => {
433
+ const contentTabName = content.id.replace('-tab', '');
434
+ content.classList.toggle('hidden', contentTabName !== tabName);
435
+ });
436
+ // Store preference
437
+ sessionStorage.setItem('kasekiActiveTab', tabName);
438
+ });
439
+ });
440
+ // Restore active tab on page load
441
+ const savedTab = sessionStorage.getItem('kasekiActiveTab') || 'health';
442
+ const savedTabButton = document.querySelector('[data-tab="' + savedTab + '"]');
443
+ if (savedTabButton) savedTabButton.click();
444
+
445
+ // Health check button handlers
392
446
  document.querySelectorAll('[data-probe]').forEach((button) => {
393
- button.addEventListener('click', () => run(button, button.dataset.probe, {
394
- auth: button.dataset.auth === 'true',
395
- }));
447
+ button.addEventListener('click', () => {
448
+ const statusKey = button.dataset.probe.replace(/\//g, '-').replace('-api-', '-');
449
+ const statusEl = document.querySelector('[data-status="' + statusKey + '"]');
450
+ if (statusEl) {
451
+ statusEl.className = 'health-check-status spinner';
452
+ }
453
+ run(button, button.dataset.probe, {
454
+ auth: button.dataset.auth === 'true',
455
+ }).then(() => {
456
+ if (statusEl) {
457
+ statusEl.className = 'health-check-status ok';
458
+ }
459
+ }).catch(() => {
460
+ if (statusEl) {
461
+ statusEl.className = 'health-check-status bad';
462
+ }
463
+ });
464
+ });
396
465
  });
466
+
397
467
  document.querySelector('#validate').addEventListener('click', (event) => {
398
468
  if (!form.reportValidity()) return;
399
469
  run(event.currentTarget, '/api/validate', { method: 'POST', auth: true, body: requestBody() });
400
470
  });
401
- document.querySelector('#status').addEventListener('click', (event) => {
471
+
472
+ document.querySelector('#status-check').addEventListener('click', (event) => {
402
473
  const runId = runIdInput.value.trim();
403
474
  if (!runId) {
404
475
  setOutputMetadata('idle');
@@ -408,6 +479,7 @@ const controllerPage = String.raw `<!doctype html>
408
479
  }
409
480
  run(event.currentTarget, '/api/runs/' + encodeURIComponent(runId) + '/status', { auth: true });
410
481
  });
482
+
411
483
  form.addEventListener('submit', (event) => {
412
484
  event.preventDefault();
413
485
  if (!form.reportValidity()) return;
@@ -1 +1 @@
1
- {"version":3,"file":"kaseki-api-web.js","sourceRoot":"","sources":["../src/kaseki-api-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmbhC,CAAC;AAEF,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACrC,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,gIAAgI,CAAC,CAAC;QACrK,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAC1C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"kaseki-api-web.js","sourceRoot":"","sources":["../src/kaseki-api-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2fhC,CAAC;AAEF,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACrC,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,gIAAgI,CAAC,CAAC;QACrK,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAC1C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanautomation/kaseki-agent",
3
- "version": "1.40.2",
3
+ "version": "1.41.0",
4
4
  "description": "Admin/helper/doctor toolbox and local API client for Kaseki diagnostics, setup, and API-backed coding-agent task workflows",
5
5
  "type": "module",
6
6
  "license": "MIT",