instar 0.7.25 → 0.7.27
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/dist/commands/init.js
CHANGED
|
@@ -1052,20 +1052,25 @@ function getDefaultJobs(port) {
|
|
|
1052
1052
|
gate: `curl -sf http://localhost:${port}/health >/dev/null 2>&1`,
|
|
1053
1053
|
execute: {
|
|
1054
1054
|
type: 'prompt',
|
|
1055
|
-
value: `You are your own QA team. Scan for issues with your instar infrastructure and submit feedback for anything wrong.
|
|
1055
|
+
value: `You are your own QA team. Scan for issues with your instar infrastructure and submit feedback for anything wrong.
|
|
1056
1056
|
|
|
1057
|
-
|
|
1057
|
+
FIRST: Read your auth token for API calls:
|
|
1058
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
1059
|
+
|
|
1060
|
+
Then check each area:
|
|
1061
|
+
|
|
1062
|
+
1. **Server health**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/health — is it responding? Are all fields present? Is status "ok" or "degraded"?
|
|
1058
1063
|
2. **State files**: Check .instar/state/ — are JSON files parseable? Any empty or corrupted? Try: for f in .instar/state/*.json; do python3 -c "import json; json.load(open('$f'))" 2>&1 || echo "CORRUPT: $f"; done
|
|
1059
1064
|
3. **Hook files**: Do all hooks in .instar/hooks/ exist and have execute permissions? ls -la .instar/hooks/
|
|
1060
|
-
4. **Job execution**: curl -s http://localhost:${port}/jobs — are any jobs failing repeatedly? Check lastRun and lastError fields.
|
|
1061
|
-
5. **Quota**: curl -s http://localhost:${port}/quota — is usage approaching limits?
|
|
1065
|
+
4. **Job execution**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs — are any jobs failing repeatedly? Check lastRun and lastError fields.
|
|
1066
|
+
5. **Quota**: curl -s -H "Authorization: Bearer $AUTH" http://localhost:${port}/quota — is usage approaching limits?
|
|
1062
1067
|
6. **Logs**: Check .instar/logs/server.log for recent errors: tail -50 .instar/logs/server.log | grep -i error
|
|
1063
1068
|
7. **Settings coherence**: Are hooks in .claude/settings.json pointing to files that exist?
|
|
1064
1069
|
8. **Design friction**: During your recent work, did anything feel unnecessarily difficult, confusing, or broken? Did you work around any issues?
|
|
1065
1070
|
9. **CI health**: Check if the project has a GitHub repo and if CI is passing. Run: REPO=$(git remote get-url origin 2>/dev/null | sed 's/.*github.com[:/]//;s/.git$//'); if [ -n "$REPO" ]; then FAILURES=$(gh run list --repo "$REPO" --status failure --limit 3 --json databaseId,conclusion,headBranch,name,createdAt 2>/dev/null); if echo "$FAILURES" | python3 -c "import sys,json; runs=json.load(sys.stdin); exit(0 if runs else 1)" 2>/dev/null; then echo "CI FAILURES DETECTED in $REPO"; echo "$FAILURES"; echo ""; echo "FIX THESE NOW: Read the failure logs with 'gh run view RUN_ID --repo $REPO --log-failed', diagnose the issue, fix it, run tests locally, commit and push."; fi; fi
|
|
1066
1071
|
|
|
1067
1072
|
For EACH issue found, submit feedback immediately:
|
|
1068
|
-
curl -s -X POST http://localhost:${port}/feedback -H 'Content-Type: application/json' -d '{"type":"bug","title":"TITLE","description":"FULL_CONTEXT"}'
|
|
1073
|
+
curl -s -X POST http://localhost:${port}/feedback -H "Authorization: Bearer $AUTH" -H 'Content-Type: application/json' -d '{"type":"bug","title":"TITLE","description":"FULL_CONTEXT"}'
|
|
1069
1074
|
|
|
1070
1075
|
For improvements (not bugs), use type "improvement" instead.
|
|
1071
1076
|
|
|
@@ -354,13 +354,15 @@ export class SessionManager extends EventEmitter {
|
|
|
354
354
|
}
|
|
355
355
|
return tmuxSession;
|
|
356
356
|
}
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
// scheduled jobs filled all slots.
|
|
357
|
+
// User-initiated sessions bypass the maxSessions limit entirely.
|
|
358
|
+
// The user should NEVER be blocked from interacting with their agent
|
|
359
|
+
// because scheduled jobs filled all slots. maxSessions only constrains
|
|
360
|
+
// autonomous/scheduled sessions, not human-initiated ones.
|
|
361
|
+
// Safety valve: still cap at maxSessions * 3 to prevent runaway sessions.
|
|
360
362
|
const runningSessions = this.listRunningSessions();
|
|
361
|
-
const
|
|
362
|
-
if (runningSessions.length >=
|
|
363
|
-
throw new Error(`
|
|
363
|
+
const absoluteLimit = this.config.maxSessions * 3;
|
|
364
|
+
if (runningSessions.length >= absoluteLimit) {
|
|
365
|
+
throw new Error(`Absolute session limit (${absoluteLimit}) reached. ` +
|
|
364
366
|
`Running: ${runningSessions.map(s => s.name).join(', ')}`);
|
|
365
367
|
}
|
|
366
368
|
// Spawn Claude in tmux. When a Telegram topic triggered the session,
|
package/dist/core/types.d.ts
CHANGED
|
@@ -105,7 +105,7 @@ export interface JobExecution {
|
|
|
105
105
|
export interface JobState {
|
|
106
106
|
slug: string;
|
|
107
107
|
lastRun?: string;
|
|
108
|
-
lastResult?: 'success' | 'failure' | 'timeout';
|
|
108
|
+
lastResult?: 'success' | 'failure' | 'timeout' | 'pending';
|
|
109
109
|
/** Error message from the last failure (cleared on success) */
|
|
110
110
|
lastError?: string;
|
|
111
111
|
nextScheduled?: string;
|
|
@@ -120,7 +120,7 @@ When Claude's context window fills up, it compresses prior messages. This can er
|
|
|
120
120
|
\`\`\`
|
|
121
121
|
I am ${agentName}. Session goal: [what I was working on].
|
|
122
122
|
Core files: .instar/AGENT.md (identity), .instar/MEMORY.md (learnings), .instar/USER.md (user context).
|
|
123
|
-
Server: curl http://localhost:${port}/health | Capabilities: curl http://localhost:${port}/capabilities
|
|
123
|
+
Server: curl http://localhost:${port}/health | Capabilities: curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/capabilities
|
|
124
124
|
\`\`\`
|
|
125
125
|
|
|
126
126
|
**What compaction erases**: Your name, your principles, what you were working on, who you work with. The compaction-recovery hook re-injects all of this. If it doesn't fire, read \`.instar/AGENT.md\` immediately.
|
|
@@ -138,6 +138,22 @@ This project uses instar for persistent agent capabilities. I am not a vanilla C
|
|
|
138
138
|
- Server: \`instar server start\` (port ${port})
|
|
139
139
|
- Health: \`curl http://localhost:${port}/health\`
|
|
140
140
|
|
|
141
|
+
### API Authentication
|
|
142
|
+
|
|
143
|
+
Most server endpoints require an auth token when \`authToken\` is configured in \`.instar/config.json\`. Read it once per session:
|
|
144
|
+
|
|
145
|
+
\`\`\`bash
|
|
146
|
+
AUTH=$(python3 -c "import json; print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null)
|
|
147
|
+
\`\`\`
|
|
148
|
+
|
|
149
|
+
Then include in ALL API calls (except \`/health\`, which is public):
|
|
150
|
+
|
|
151
|
+
\`\`\`bash
|
|
152
|
+
curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
**Without this header, all endpoints return 401.** The \`telegram-reply.sh\` script reads auth automatically.
|
|
156
|
+
|
|
141
157
|
### Reporting Issues & Feedback (IMPORTANT — Read This First)
|
|
142
158
|
|
|
143
159
|
**I have a built-in feedback system. I do NOT use GitHub, \`gh\`, or any external issue tracker.**
|
|
@@ -146,6 +162,7 @@ When something isn't working with instar, or the user wants a feature, I use my
|
|
|
146
162
|
|
|
147
163
|
\`\`\`bash
|
|
148
164
|
curl -X POST http://localhost:${port}/feedback \\
|
|
165
|
+
-H "Authorization: Bearer $AUTH" \\
|
|
149
166
|
-H 'Content-Type: application/json' \\
|
|
150
167
|
-d '{"type":"bug","title":"Short description","description":"Full details with context"}'
|
|
151
168
|
\`\`\`
|
|
@@ -153,42 +170,42 @@ curl -X POST http://localhost:${port}/feedback \\
|
|
|
153
170
|
This routes feedback to the Instar maintainers automatically. Valid types: \`bug\`, \`feature\`, \`improvement\`, \`question\`.
|
|
154
171
|
|
|
155
172
|
**NEVER use \`gh issue\`, \`gh api\`, or GitHub CLI to file issues.** The feedback API is my channel. It stores a local receipt, forwards upstream, and tracks delivery. I can also:
|
|
156
|
-
- View submitted feedback: \`curl http://localhost:${port}/feedback\`
|
|
157
|
-
- Retry failed forwards: \`curl -X POST http://localhost:${port}/feedback/retry\`
|
|
173
|
+
- View submitted feedback: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/feedback\`
|
|
174
|
+
- Retry failed forwards: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/feedback/retry\`
|
|
158
175
|
|
|
159
176
|
### Capabilities
|
|
160
177
|
|
|
161
178
|
**Feedback System** — Report bugs, request features, suggest improvements. All via \`POST /feedback\`.
|
|
162
179
|
|
|
163
180
|
**Job Scheduler** — Run tasks on a schedule. Jobs in \`.instar/jobs.json\`.
|
|
164
|
-
- View: \`curl http://localhost:${port}/jobs\`
|
|
165
|
-
- Trigger: \`curl -X POST http://localhost:${port}/jobs/SLUG/trigger\`
|
|
181
|
+
- View: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs\`
|
|
182
|
+
- Trigger: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs/SLUG/trigger\`
|
|
166
183
|
|
|
167
184
|
**Sessions** — Spawn and manage Claude Code sessions.
|
|
168
|
-
- List: \`curl http://localhost:${port}/sessions\`
|
|
169
|
-
- Spawn: \`curl -X POST http://localhost:${port}/sessions/spawn -d '{"name":"task","prompt":"do something"}'\`
|
|
185
|
+
- List: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/sessions\`
|
|
186
|
+
- Spawn: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/sessions/spawn -d '{"name":"task","prompt":"do something"}'\`
|
|
170
187
|
|
|
171
188
|
**Relationships** — Track people I interact with.
|
|
172
|
-
- List: \`curl http://localhost:${port}/relationships\`
|
|
189
|
+
- List: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/relationships\`
|
|
173
190
|
|
|
174
191
|
**Publishing** — Share content as PUBLIC web pages via Telegraph. Instant, zero-config, accessible from anywhere.
|
|
175
|
-
- Publish: \`curl -X POST http://localhost:${port}/publish -H 'Content-Type: application/json' -d '{"title":"Page Title","markdown":"# Content here"}'\`
|
|
176
|
-
- List published: \`curl http://localhost:${port}/published\`
|
|
177
|
-
- Edit: \`curl -X PUT http://localhost:${port}/publish/PAGE_PATH -H 'Content-Type: application/json' -d '{"title":"Updated","markdown":"# New content"}'\`
|
|
192
|
+
- Publish: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/publish -H 'Content-Type: application/json' -d '{"title":"Page Title","markdown":"# Content here"}'\`
|
|
193
|
+
- List published: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/published\`
|
|
194
|
+
- Edit: \`curl -X PUT -H "Authorization: Bearer $AUTH" http://localhost:${port}/publish/PAGE_PATH -H 'Content-Type: application/json' -d '{"title":"Updated","markdown":"# New content"}'\`
|
|
178
195
|
|
|
179
196
|
**⚠ CRITICAL: All Telegraph pages are PUBLIC.** Anyone with the URL can view the content. There is no authentication or access control. NEVER publish sensitive, private, or confidential information through Telegraph. When sharing a link, always inform the user that the page is publicly accessible.
|
|
180
197
|
|
|
181
198
|
**Private Viewing** — Render markdown as auth-gated HTML pages, accessible only through the agent's server (local or via tunnel).
|
|
182
|
-
- Create: \`curl -X POST http://localhost:${port}/view -H 'Content-Type: application/json' -d '{"title":"Report","markdown":"# Private content"}'\`
|
|
199
|
+
- Create: \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/view -H 'Content-Type: application/json' -d '{"title":"Report","markdown":"# Private content"}'\`
|
|
183
200
|
- View (HTML): Open \`http://localhost:${port}/view/VIEW_ID\` in a browser
|
|
184
|
-
- List: \`curl http://localhost:${port}/views\`
|
|
185
|
-
- Update: \`curl -X PUT http://localhost:${port}/view/VIEW_ID -H 'Content-Type: application/json' -d '{"title":"Updated","markdown":"# New content"}'\`
|
|
186
|
-
- Delete: \`curl -X DELETE http://localhost:${port}/view/VIEW_ID\`
|
|
201
|
+
- List: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/views\`
|
|
202
|
+
- Update: \`curl -X PUT -H "Authorization: Bearer $AUTH" http://localhost:${port}/view/VIEW_ID -H 'Content-Type: application/json' -d '{"title":"Updated","markdown":"# New content"}'\`
|
|
203
|
+
- Delete: \`curl -X DELETE -H "Authorization: Bearer $AUTH" http://localhost:${port}/view/VIEW_ID\`
|
|
187
204
|
|
|
188
205
|
**Use private views for sensitive content. Use Telegraph for public content.**
|
|
189
206
|
|
|
190
207
|
**Cloudflare Tunnel** — Expose the local server to the internet via Cloudflare. Enables remote access to private views, the API, and file serving.
|
|
191
|
-
- Status: \`curl http://localhost:${port}/tunnel\`
|
|
208
|
+
- Status: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/tunnel\`
|
|
192
209
|
- Configure in \`.instar/config.json\`: \`{"tunnel": {"enabled": true, "type": "quick"}}\`
|
|
193
210
|
- Quick tunnels (default): Zero-config, ephemeral URL (*.trycloudflare.com), no account needed
|
|
194
211
|
- Named tunnels: Persistent custom domain, requires token from Cloudflare dashboard
|
|
@@ -254,7 +271,7 @@ When fetching content from ANY URL, always try the most efficient method first:
|
|
|
254
271
|
Before EVER saying "I don't have", "I can't", or "this isn't available" — check what actually exists:
|
|
255
272
|
|
|
256
273
|
\`\`\`bash
|
|
257
|
-
curl http://localhost:${port}/capabilities
|
|
274
|
+
curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/capabilities
|
|
258
275
|
\`\`\`
|
|
259
276
|
|
|
260
277
|
This returns your full capability matrix: scripts, hooks, Telegram status, jobs, relationships, and more. It is the source of truth about what you can do. **Never hallucinate about missing capabilities — verify first.**
|
|
@@ -267,11 +284,11 @@ I maintain registries that are the source of truth for specific categories. Thes
|
|
|
267
284
|
|
|
268
285
|
| Question | Check First |
|
|
269
286
|
|----------|-------------|
|
|
270
|
-
| What can I do? | \`curl http://localhost:${port}/capabilities\` |
|
|
287
|
+
| What can I do? | \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/capabilities\` |
|
|
271
288
|
| Who do I work with? | \`.instar/USER.md\` |
|
|
272
289
|
| What have I learned? | \`.instar/MEMORY.md\` |
|
|
273
|
-
| What jobs do I have? | \`.instar/jobs.json\` or \`curl http://localhost:${port}/jobs\` |
|
|
274
|
-
| Who have I interacted with? | \`curl http://localhost:${port}/relationships\` |
|
|
290
|
+
| What jobs do I have? | \`.instar/jobs.json\` or \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/jobs\` |
|
|
291
|
+
| Who have I interacted with? | \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/relationships\` |
|
|
275
292
|
| My configuration? | \`.instar/config.json\` |
|
|
276
293
|
| My identity/principles? | \`.instar/AGENT.md\` |
|
|
277
294
|
| Project architecture? | This file (CLAUDE.md), then project docs |
|
|
@@ -375,6 +392,7 @@ These are patterns that feel like insight or helpfulness but actually perpetuate
|
|
|
375
392
|
**When you detect an issue, report it immediately:**
|
|
376
393
|
\`\`\`bash
|
|
377
394
|
curl -s -X POST http://localhost:${port}/feedback \\
|
|
395
|
+
-H "Authorization: Bearer $AUTH" \\
|
|
378
396
|
-H 'Content-Type: application/json' \\
|
|
379
397
|
-d '{"type":"bug","title":"CONCISE_TITLE","description":"FULL_CONTEXT_WITH_ERROR_MESSAGES"}'
|
|
380
398
|
\`\`\`
|
|
@@ -420,6 +438,7 @@ After building something significant for your user, ask yourself: *"Would other
|
|
|
420
438
|
|
|
421
439
|
\`\`\`bash
|
|
422
440
|
curl -s -X POST http://localhost:${port}/feedback \\
|
|
441
|
+
-H "Authorization: Bearer $AUTH" \\
|
|
423
442
|
-H 'Content-Type: application/json' \\
|
|
424
443
|
-d '{
|
|
425
444
|
"type": "improvement",
|
|
@@ -442,27 +461,27 @@ If any answer is yes → submit feedback. Let Dawn decide whether to upstream it
|
|
|
442
461
|
You have a built-in evolution system with four subsystems. This is not a metaphor — it's infrastructure that tracks your growth.
|
|
443
462
|
|
|
444
463
|
**Evolution Queue** — Staged self-improvement proposals.
|
|
445
|
-
- View: \`curl http://localhost:${port}/evolution/proposals\`
|
|
464
|
+
- View: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/proposals\`
|
|
446
465
|
- Propose: \`/evolve\` skill or \`POST /evolution/proposals\`
|
|
447
466
|
- The \`evolution-review\` job evaluates and implements proposals every 6 hours.
|
|
448
467
|
|
|
449
468
|
**Learning Registry** — Structured, searchable insights.
|
|
450
|
-
- View: \`curl http://localhost:${port}/evolution/learnings\`
|
|
469
|
+
- View: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/learnings\`
|
|
451
470
|
- Record: \`/learn\` skill or \`POST /evolution/learnings\`
|
|
452
471
|
- The \`insight-harvest\` job synthesizes patterns into proposals every 8 hours.
|
|
453
472
|
|
|
454
473
|
**Capability Gaps** — Track what you're missing.
|
|
455
|
-
- View: \`curl http://localhost:${port}/evolution/gaps\`
|
|
474
|
+
- View: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/gaps\`
|
|
456
475
|
- Report: \`/gaps\` skill or \`POST /evolution/gaps\`
|
|
457
476
|
|
|
458
477
|
**Action Queue** — Commitments with follow-through tracking.
|
|
459
|
-
- View: \`curl http://localhost:${port}/evolution/actions\`
|
|
478
|
+
- View: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution/actions\`
|
|
460
479
|
- Create: \`/commit-action\` skill or \`POST /evolution/actions\`
|
|
461
480
|
- The \`commitment-check\` job surfaces overdue items every 4 hours.
|
|
462
481
|
|
|
463
482
|
**Dashboard** — Full evolution health at a glance:
|
|
464
483
|
\`\`\`bash
|
|
465
|
-
curl http://localhost:${port}/evolution
|
|
484
|
+
curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/evolution
|
|
466
485
|
\`\`\`
|
|
467
486
|
|
|
468
487
|
**Skills for evolution:**
|
|
@@ -54,6 +54,14 @@ export class JobScheduler {
|
|
|
54
54
|
*/
|
|
55
55
|
setTelegram(adapter) {
|
|
56
56
|
this.telegram = adapter;
|
|
57
|
+
// If scheduler already started, ensure job topics now that Telegram is available.
|
|
58
|
+
// This fixes the startup race condition where start() runs before Telegram connects.
|
|
59
|
+
if (this.running && this.jobs.length > 0) {
|
|
60
|
+
const enabledJobs = this.jobs.filter(j => j.enabled);
|
|
61
|
+
this.ensureJobTopics(enabledJobs).catch(err => {
|
|
62
|
+
console.error(`[scheduler] Failed to ensure job topics (post-Telegram init): ${err}`);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
57
65
|
}
|
|
58
66
|
/**
|
|
59
67
|
* Set the quota tracker for session death classification.
|
|
@@ -261,10 +269,11 @@ export class JobScheduler {
|
|
|
261
269
|
triggeredBy: `scheduler:${reason}`,
|
|
262
270
|
maxDurationMinutes: job.expectedDurationMinutes,
|
|
263
271
|
}).then(() => {
|
|
264
|
-
// Update job state on successful spawn (clear error)
|
|
272
|
+
// Update job state on successful spawn (clear error, set pending result)
|
|
265
273
|
const jobState = {
|
|
266
274
|
slug: job.slug,
|
|
267
275
|
lastRun: new Date().toISOString(),
|
|
276
|
+
lastResult: 'pending',
|
|
268
277
|
lastError: undefined,
|
|
269
278
|
consecutiveFailures: 0,
|
|
270
279
|
nextScheduled: this.getNextRun(job.slug),
|
package/dist/server/routes.js
CHANGED
|
@@ -19,8 +19,22 @@ export function createRoutes(ctx) {
|
|
|
19
19
|
// ── Health ──────────────────────────────────────────────────────
|
|
20
20
|
router.get('/health', (req, res) => {
|
|
21
21
|
const uptimeMs = Date.now() - ctx.startTime.getTime();
|
|
22
|
+
// Determine if anything is degraded
|
|
23
|
+
const sessions = ctx.sessionManager.listRunningSessions();
|
|
24
|
+
const maxSessions = ctx.config.sessions?.maxSessions ?? 3;
|
|
25
|
+
const sessionExhausted = sessions.length >= maxSessions;
|
|
26
|
+
let totalFailures = 0;
|
|
27
|
+
if (ctx.scheduler) {
|
|
28
|
+
const jobs = ctx.scheduler.getJobs();
|
|
29
|
+
for (const j of jobs) {
|
|
30
|
+
const st = ctx.state.getJobState(j.slug);
|
|
31
|
+
if (st)
|
|
32
|
+
totalFailures += st.consecutiveFailures;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const isDegraded = sessionExhausted || totalFailures >= 5;
|
|
22
36
|
const base = {
|
|
23
|
-
status: 'ok',
|
|
37
|
+
status: isDegraded ? 'degraded' : 'ok',
|
|
24
38
|
uptime: uptimeMs,
|
|
25
39
|
uptimeHuman: formatUptime(uptimeMs),
|
|
26
40
|
};
|
|
@@ -39,6 +53,9 @@ export function createRoutes(ctx) {
|
|
|
39
53
|
if (isAuthed) {
|
|
40
54
|
const mem = process.memoryUsage();
|
|
41
55
|
base.version = ctx.config.version || '0.0.0';
|
|
56
|
+
base.sessions = { current: sessions.length, max: maxSessions };
|
|
57
|
+
base.schedulerRunning = ctx.scheduler !== null;
|
|
58
|
+
base.consecutiveJobFailures = totalFailures;
|
|
42
59
|
base.project = ctx.config.projectName;
|
|
43
60
|
base.node = process.version;
|
|
44
61
|
base.memory = {
|