@cyanautomation/kaseki-agent 1.40.2 → 1.42.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;AAshBjC,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,63 +286,27 @@ 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>
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">
225
299
  </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">
300
+ <fieldset>
301
+ <legend>Options</legend>
302
+ <div class="form-field">
303
+ <div class="check">
231
304
  <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>
305
+ <div class="check-copy">
306
+ <label class="check-label">Enable scouting mode</label>
307
+ <div class="check-helper">Allow the agent to explore beyond the specified scope (experimental).</div>
308
+ </div>
309
+ </div>
244
310
  </div>
245
311
  </fieldset>
246
312
  <fieldset>
@@ -251,29 +317,7 @@ const controllerPage = String.raw `<!doctype html>
251
317
  </div>
252
318
  </fieldset>
253
319
  </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
320
  </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
321
  </section>
278
322
  <section class="panel stack" aria-labelledby="responses-heading">
279
323
  <div>
@@ -281,7 +325,7 @@ const controllerPage = String.raw `<!doctype html>
281
325
  </div>
282
326
  <div class="response-panel">
283
327
  <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>
328
+ <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
329
  </div>
286
330
  </section>
287
331
  </main>
@@ -323,24 +367,33 @@ const controllerPage = String.raw `<!doctype html>
323
367
 
324
368
  function requestBody() {
325
369
  const data = new FormData(form);
326
- const timeoutSeconds = String(data.get('timeoutSeconds') || '').trim();
370
+ const timeoutSeconds = String(data.get('timeoutSeconds') || '10800').trim();
327
371
  const body = {
328
372
  repoUrl: String(data.get('repoUrl') || '').trim(),
329
373
  ref: String(data.get('ref') || 'main').trim(),
330
374
  taskPrompt: String(data.get('taskPrompt') || '').trim(),
331
- publishMode: String(data.get('publishMode') || 'pr'),
375
+ publishMode: String(data.get('publishMode') || 'auto'),
332
376
  taskMode: String(data.get('taskMode') || 'patch'),
333
377
  };
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
- }
378
+ if (data.get('scouting') === 'on') {
379
+ body.scouting = { enabled: true };
380
+ }
381
+ const parsed = Number(timeoutSeconds);
382
+ if (!isNaN(parsed)) {
383
+ body.timeoutSeconds = parsed;
341
384
  }
342
385
  return body;
343
- }
386
+
387
+
388
+
389
+
390
+
391
+ }
392
+
393
+
394
+
395
+
396
+
344
397
 
345
398
  async function apiRequest(path, options) {
346
399
  const token = tokenInput.value.trim();
@@ -389,16 +442,57 @@ const controllerPage = String.raw `<!doctype html>
389
442
  }
390
443
  }
391
444
 
445
+ // Tab switching
446
+ document.querySelectorAll('.tab-button').forEach((button) => {
447
+ button.addEventListener('click', () => {
448
+ const tabName = button.dataset.tab;
449
+ // Update tab buttons
450
+ document.querySelectorAll('.tab-button').forEach(b => {
451
+ b.classList.toggle('active', b.dataset.tab === tabName);
452
+ b.setAttribute('aria-selected', b.dataset.tab === tabName ? 'true' : 'false');
453
+ });
454
+ // Update tab content
455
+ document.querySelectorAll('.tab-content').forEach(content => {
456
+ const contentTabName = content.id.replace('-tab', '');
457
+ content.classList.toggle('hidden', contentTabName !== tabName);
458
+ });
459
+ // Store preference
460
+ sessionStorage.setItem('kasekiActiveTab', tabName);
461
+ });
462
+ });
463
+ // Restore active tab on page load
464
+ const savedTab = sessionStorage.getItem('kasekiActiveTab') || 'health';
465
+ const savedTabButton = document.querySelector('[data-tab="' + savedTab + '"]');
466
+ if (savedTabButton) savedTabButton.click();
467
+
468
+ // Health check button handlers
392
469
  document.querySelectorAll('[data-probe]').forEach((button) => {
393
- button.addEventListener('click', () => run(button, button.dataset.probe, {
394
- auth: button.dataset.auth === 'true',
395
- }));
470
+ button.addEventListener('click', () => {
471
+ const statusKey = button.dataset.probe.replace(/\//g, '-').replace('-api-', '-');
472
+ const statusEl = document.querySelector('[data-status="' + statusKey + '"]');
473
+ if (statusEl) {
474
+ statusEl.className = 'health-check-status spinner';
475
+ }
476
+ run(button, button.dataset.probe, {
477
+ auth: button.dataset.auth === 'true',
478
+ }).then(() => {
479
+ if (statusEl) {
480
+ statusEl.className = 'health-check-status ok';
481
+ }
482
+ }).catch(() => {
483
+ if (statusEl) {
484
+ statusEl.className = 'health-check-status bad';
485
+ }
486
+ });
487
+ });
396
488
  });
489
+
397
490
  document.querySelector('#validate').addEventListener('click', (event) => {
398
491
  if (!form.reportValidity()) return;
399
492
  run(event.currentTarget, '/api/validate', { method: 'POST', auth: true, body: requestBody() });
400
493
  });
401
- document.querySelector('#status').addEventListener('click', (event) => {
494
+
495
+ document.querySelector('#status-check').addEventListener('click', (event) => {
402
496
  const runId = runIdInput.value.trim();
403
497
  if (!runId) {
404
498
  setOutputMetadata('idle');
@@ -408,6 +502,7 @@ const controllerPage = String.raw `<!doctype html>
408
502
  }
409
503
  run(event.currentTarget, '/api/runs/' + encodeURIComponent(runId) + '/status', { auth: true });
410
504
  });
505
+
411
506
  form.addEventListener('submit', (event) => {
412
507
  event.preventDefault();
413
508
  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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkhBhC,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.42.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",