instar 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +7 -0
- package/.claude/skills/setup-wizard/skill.md +343 -0
- package/.github/workflows/ci.yml +78 -0
- package/CLAUDE.md +82 -0
- package/README.md +194 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.js +141 -0
- package/dist/commands/init.d.ts +40 -0
- package/dist/commands/init.js +568 -0
- package/dist/commands/job.d.ts +20 -0
- package/dist/commands/job.js +84 -0
- package/dist/commands/server.d.ts +19 -0
- package/dist/commands/server.js +273 -0
- package/dist/commands/setup.d.ts +24 -0
- package/dist/commands/setup.js +865 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.js +114 -0
- package/dist/commands/user.d.ts +17 -0
- package/dist/commands/user.js +53 -0
- package/dist/core/Config.d.ts +16 -0
- package/dist/core/Config.js +144 -0
- package/dist/core/Prerequisites.d.ts +28 -0
- package/dist/core/Prerequisites.js +159 -0
- package/dist/core/RelationshipManager.d.ts +73 -0
- package/dist/core/RelationshipManager.js +318 -0
- package/dist/core/SessionManager.d.ts +89 -0
- package/dist/core/SessionManager.js +326 -0
- package/dist/core/StateManager.d.ts +28 -0
- package/dist/core/StateManager.js +96 -0
- package/dist/core/types.d.ts +279 -0
- package/dist/core/types.js +8 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +23 -0
- package/dist/messaging/TelegramAdapter.d.ts +73 -0
- package/dist/messaging/TelegramAdapter.js +288 -0
- package/dist/monitoring/HealthChecker.d.ts +38 -0
- package/dist/monitoring/HealthChecker.js +148 -0
- package/dist/scaffold/bootstrap.d.ts +21 -0
- package/dist/scaffold/bootstrap.js +110 -0
- package/dist/scaffold/templates.d.ts +34 -0
- package/dist/scaffold/templates.js +187 -0
- package/dist/scheduler/JobLoader.d.ts +18 -0
- package/dist/scheduler/JobLoader.js +70 -0
- package/dist/scheduler/JobScheduler.d.ts +111 -0
- package/dist/scheduler/JobScheduler.js +402 -0
- package/dist/server/AgentServer.d.ts +40 -0
- package/dist/server/AgentServer.js +73 -0
- package/dist/server/middleware.d.ts +12 -0
- package/dist/server/middleware.js +50 -0
- package/dist/server/routes.d.ts +25 -0
- package/dist/server/routes.js +224 -0
- package/dist/users/UserManager.d.ts +45 -0
- package/dist/users/UserManager.js +113 -0
- package/docs/dawn-audit-report.md +412 -0
- package/docs/positioning-vs-openclaw.md +246 -0
- package/package.json +52 -0
- package/src/cli.ts +169 -0
- package/src/commands/init.ts +654 -0
- package/src/commands/job.ts +110 -0
- package/src/commands/server.ts +325 -0
- package/src/commands/setup.ts +958 -0
- package/src/commands/status.ts +125 -0
- package/src/commands/user.ts +71 -0
- package/src/core/Config.ts +161 -0
- package/src/core/Prerequisites.ts +187 -0
- package/src/core/RelationshipManager.ts +366 -0
- package/src/core/SessionManager.ts +385 -0
- package/src/core/StateManager.ts +121 -0
- package/src/core/types.ts +320 -0
- package/src/index.ts +58 -0
- package/src/messaging/TelegramAdapter.ts +365 -0
- package/src/monitoring/HealthChecker.ts +172 -0
- package/src/scaffold/bootstrap.ts +122 -0
- package/src/scaffold/templates.ts +204 -0
- package/src/scheduler/JobLoader.ts +85 -0
- package/src/scheduler/JobScheduler.ts +476 -0
- package/src/server/AgentServer.ts +93 -0
- package/src/server/middleware.ts +58 -0
- package/src/server/routes.ts +278 -0
- package/src/templates/default-jobs.json +47 -0
- package/src/templates/hooks/compaction-recovery.sh +23 -0
- package/src/templates/hooks/dangerous-command-guard.sh +35 -0
- package/src/templates/hooks/grounding-before-messaging.sh +22 -0
- package/src/templates/hooks/session-start.sh +37 -0
- package/src/templates/hooks/settings-template.json +45 -0
- package/src/templates/scripts/health-watchdog.sh +63 -0
- package/src/templates/scripts/telegram-reply.sh +54 -0
- package/src/users/UserManager.ts +129 -0
- package/tests/e2e/lifecycle.test.ts +376 -0
- package/tests/fixtures/test-repo/CLAUDE.md +3 -0
- package/tests/fixtures/test-repo/README.md +1 -0
- package/tests/helpers/setup.ts +209 -0
- package/tests/integration/fresh-install.test.ts +218 -0
- package/tests/integration/scheduler-basic.test.ts +109 -0
- package/tests/integration/server-full.test.ts +284 -0
- package/tests/integration/session-lifecycle.test.ts +181 -0
- package/tests/unit/Config.test.ts +22 -0
- package/tests/unit/HealthChecker.test.ts +168 -0
- package/tests/unit/JobLoader.test.ts +151 -0
- package/tests/unit/JobScheduler.test.ts +267 -0
- package/tests/unit/Prerequisites.test.ts +59 -0
- package/tests/unit/RelationshipManager.test.ts +345 -0
- package/tests/unit/StateManager.test.ts +143 -0
- package/tests/unit/TelegramAdapter.test.ts +165 -0
- package/tests/unit/UserManager.test.ts +131 -0
- package/tests/unit/bootstrap.test.ts +28 -0
- package/tests/unit/commands.test.ts +138 -0
- package/tests/unit/middleware.test.ts +92 -0
- package/tests/unit/relationship-routes.test.ts +131 -0
- package/tests/unit/scaffold-templates.test.ts +132 -0
- package/tests/unit/server.test.ts +163 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +9 -0
- package/vitest.e2e.config.ts +9 -0
- package/vitest.integration.config.ts +9 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import request from 'supertest';
|
|
3
|
+
import { AgentServer } from '../../src/server/AgentServer.js';
|
|
4
|
+
import { createTempProject, createMockSessionManager } from '../helpers/setup.js';
|
|
5
|
+
import type { TempProject, MockSessionManager } from '../helpers/setup.js';
|
|
6
|
+
import type { AgentKitConfig } from '../../src/core/types.js';
|
|
7
|
+
|
|
8
|
+
describe('AgentServer', () => {
|
|
9
|
+
let project: TempProject;
|
|
10
|
+
let mockSM: MockSessionManager;
|
|
11
|
+
let server: AgentServer;
|
|
12
|
+
let app: ReturnType<AgentServer['getApp']>;
|
|
13
|
+
|
|
14
|
+
const fakeConfig: AgentKitConfig = {
|
|
15
|
+
projectName: 'test-project',
|
|
16
|
+
projectDir: '/tmp/test',
|
|
17
|
+
stateDir: '/tmp/test/.instar',
|
|
18
|
+
port: 0, // not actually listening in tests
|
|
19
|
+
sessions: {
|
|
20
|
+
tmuxPath: '/usr/bin/tmux',
|
|
21
|
+
claudePath: '/usr/bin/claude',
|
|
22
|
+
projectDir: '/tmp/test',
|
|
23
|
+
maxSessions: 3,
|
|
24
|
+
protectedSessions: [],
|
|
25
|
+
completionPatterns: [],
|
|
26
|
+
},
|
|
27
|
+
scheduler: {
|
|
28
|
+
jobsFile: '',
|
|
29
|
+
enabled: false,
|
|
30
|
+
maxParallelJobs: 2,
|
|
31
|
+
quotaThresholds: { normal: 50, elevated: 70, critical: 85, shutdown: 95 },
|
|
32
|
+
},
|
|
33
|
+
users: [],
|
|
34
|
+
messaging: [],
|
|
35
|
+
monitoring: {
|
|
36
|
+
quotaTracking: false,
|
|
37
|
+
memoryMonitoring: false,
|
|
38
|
+
healthCheckIntervalMs: 30000,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
beforeAll(() => {
|
|
43
|
+
project = createTempProject();
|
|
44
|
+
mockSM = createMockSessionManager();
|
|
45
|
+
|
|
46
|
+
server = new AgentServer({
|
|
47
|
+
config: fakeConfig,
|
|
48
|
+
sessionManager: mockSM as any,
|
|
49
|
+
state: project.state,
|
|
50
|
+
});
|
|
51
|
+
app = server.getApp();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterAll(() => {
|
|
55
|
+
project.cleanup();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('GET /health', () => {
|
|
59
|
+
it('returns ok status', async () => {
|
|
60
|
+
const res = await request(app).get('/health');
|
|
61
|
+
expect(res.status).toBe(200);
|
|
62
|
+
expect(res.body.status).toBe('ok');
|
|
63
|
+
expect(res.body.project).toBe('test-project');
|
|
64
|
+
expect(res.body).toHaveProperty('uptime');
|
|
65
|
+
expect(res.body).toHaveProperty('uptimeHuman');
|
|
66
|
+
expect(res.body).toHaveProperty('version');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('GET /status', () => {
|
|
71
|
+
it('returns session and scheduler info', async () => {
|
|
72
|
+
const res = await request(app).get('/status');
|
|
73
|
+
expect(res.status).toBe(200);
|
|
74
|
+
expect(res.body.sessions).toHaveProperty('running');
|
|
75
|
+
expect(res.body.sessions).toHaveProperty('max');
|
|
76
|
+
expect(res.body.scheduler).toBeNull(); // No scheduler provided
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('GET /sessions', () => {
|
|
81
|
+
it('returns empty array when no sessions', async () => {
|
|
82
|
+
const res = await request(app).get('/sessions');
|
|
83
|
+
expect(res.status).toBe(200);
|
|
84
|
+
expect(res.body).toEqual([]);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('GET /sessions/:name/output', () => {
|
|
89
|
+
it('returns output for valid session', async () => {
|
|
90
|
+
// captureOutput returns 'mock output' for any session
|
|
91
|
+
const res = await request(app).get('/sessions/test-session/output');
|
|
92
|
+
expect(res.status).toBe(200);
|
|
93
|
+
expect(res.body).toHaveProperty('output');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('POST /sessions/:name/input', () => {
|
|
98
|
+
it('rejects missing text', async () => {
|
|
99
|
+
const res = await request(app)
|
|
100
|
+
.post('/sessions/test-session/input')
|
|
101
|
+
.send({});
|
|
102
|
+
expect(res.status).toBe(400);
|
|
103
|
+
expect(res.body.error).toContain('text');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('returns 404 for non-running session', async () => {
|
|
107
|
+
// sendInput returns false when session not in aliveSet
|
|
108
|
+
const res = await request(app)
|
|
109
|
+
.post('/sessions/nonexistent/input')
|
|
110
|
+
.send({ text: 'hello' });
|
|
111
|
+
expect(res.status).toBe(404);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('POST /sessions/spawn', () => {
|
|
116
|
+
it('rejects missing required fields', async () => {
|
|
117
|
+
const res = await request(app)
|
|
118
|
+
.post('/sessions/spawn')
|
|
119
|
+
.send({ name: 'test' });
|
|
120
|
+
expect(res.status).toBe(400);
|
|
121
|
+
expect(res.body.error).toContain('required');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('GET /jobs', () => {
|
|
126
|
+
it('returns empty when no scheduler', async () => {
|
|
127
|
+
const res = await request(app).get('/jobs');
|
|
128
|
+
expect(res.status).toBe(200);
|
|
129
|
+
expect(res.body.jobs).toEqual([]);
|
|
130
|
+
expect(res.body.scheduler).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('POST /jobs/:slug/trigger', () => {
|
|
135
|
+
it('returns 503 when no scheduler', async () => {
|
|
136
|
+
const res = await request(app)
|
|
137
|
+
.post('/jobs/test-job/trigger')
|
|
138
|
+
.send({});
|
|
139
|
+
expect(res.status).toBe(503);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('GET /events', () => {
|
|
144
|
+
it('returns events', async () => {
|
|
145
|
+
project.state.appendEvent({
|
|
146
|
+
type: 'test',
|
|
147
|
+
summary: 'Test event',
|
|
148
|
+
timestamp: new Date().toISOString(),
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const res = await request(app).get('/events');
|
|
152
|
+
expect(res.status).toBe(200);
|
|
153
|
+
expect(res.body.length).toBeGreaterThanOrEqual(1);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('error handling', () => {
|
|
158
|
+
it('DELETE /sessions/:id returns 404 for unknown session', async () => {
|
|
159
|
+
const res = await request(app).delete('/sessions/nonexistent');
|
|
160
|
+
expect(res.status).toBe(404);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "Node16",
|
|
5
|
+
"moduleResolution": "Node16",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist", "tests"]
|
|
20
|
+
}
|
package/vitest.config.ts
ADDED