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.
Files changed (115) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.claude/skills/setup-wizard/skill.md +343 -0
  3. package/.github/workflows/ci.yml +78 -0
  4. package/CLAUDE.md +82 -0
  5. package/README.md +194 -0
  6. package/dist/cli.d.ts +18 -0
  7. package/dist/cli.js +141 -0
  8. package/dist/commands/init.d.ts +40 -0
  9. package/dist/commands/init.js +568 -0
  10. package/dist/commands/job.d.ts +20 -0
  11. package/dist/commands/job.js +84 -0
  12. package/dist/commands/server.d.ts +19 -0
  13. package/dist/commands/server.js +273 -0
  14. package/dist/commands/setup.d.ts +24 -0
  15. package/dist/commands/setup.js +865 -0
  16. package/dist/commands/status.d.ts +11 -0
  17. package/dist/commands/status.js +114 -0
  18. package/dist/commands/user.d.ts +17 -0
  19. package/dist/commands/user.js +53 -0
  20. package/dist/core/Config.d.ts +16 -0
  21. package/dist/core/Config.js +144 -0
  22. package/dist/core/Prerequisites.d.ts +28 -0
  23. package/dist/core/Prerequisites.js +159 -0
  24. package/dist/core/RelationshipManager.d.ts +73 -0
  25. package/dist/core/RelationshipManager.js +318 -0
  26. package/dist/core/SessionManager.d.ts +89 -0
  27. package/dist/core/SessionManager.js +326 -0
  28. package/dist/core/StateManager.d.ts +28 -0
  29. package/dist/core/StateManager.js +96 -0
  30. package/dist/core/types.d.ts +279 -0
  31. package/dist/core/types.js +8 -0
  32. package/dist/index.d.ts +18 -0
  33. package/dist/index.js +23 -0
  34. package/dist/messaging/TelegramAdapter.d.ts +73 -0
  35. package/dist/messaging/TelegramAdapter.js +288 -0
  36. package/dist/monitoring/HealthChecker.d.ts +38 -0
  37. package/dist/monitoring/HealthChecker.js +148 -0
  38. package/dist/scaffold/bootstrap.d.ts +21 -0
  39. package/dist/scaffold/bootstrap.js +110 -0
  40. package/dist/scaffold/templates.d.ts +34 -0
  41. package/dist/scaffold/templates.js +187 -0
  42. package/dist/scheduler/JobLoader.d.ts +18 -0
  43. package/dist/scheduler/JobLoader.js +70 -0
  44. package/dist/scheduler/JobScheduler.d.ts +111 -0
  45. package/dist/scheduler/JobScheduler.js +402 -0
  46. package/dist/server/AgentServer.d.ts +40 -0
  47. package/dist/server/AgentServer.js +73 -0
  48. package/dist/server/middleware.d.ts +12 -0
  49. package/dist/server/middleware.js +50 -0
  50. package/dist/server/routes.d.ts +25 -0
  51. package/dist/server/routes.js +224 -0
  52. package/dist/users/UserManager.d.ts +45 -0
  53. package/dist/users/UserManager.js +113 -0
  54. package/docs/dawn-audit-report.md +412 -0
  55. package/docs/positioning-vs-openclaw.md +246 -0
  56. package/package.json +52 -0
  57. package/src/cli.ts +169 -0
  58. package/src/commands/init.ts +654 -0
  59. package/src/commands/job.ts +110 -0
  60. package/src/commands/server.ts +325 -0
  61. package/src/commands/setup.ts +958 -0
  62. package/src/commands/status.ts +125 -0
  63. package/src/commands/user.ts +71 -0
  64. package/src/core/Config.ts +161 -0
  65. package/src/core/Prerequisites.ts +187 -0
  66. package/src/core/RelationshipManager.ts +366 -0
  67. package/src/core/SessionManager.ts +385 -0
  68. package/src/core/StateManager.ts +121 -0
  69. package/src/core/types.ts +320 -0
  70. package/src/index.ts +58 -0
  71. package/src/messaging/TelegramAdapter.ts +365 -0
  72. package/src/monitoring/HealthChecker.ts +172 -0
  73. package/src/scaffold/bootstrap.ts +122 -0
  74. package/src/scaffold/templates.ts +204 -0
  75. package/src/scheduler/JobLoader.ts +85 -0
  76. package/src/scheduler/JobScheduler.ts +476 -0
  77. package/src/server/AgentServer.ts +93 -0
  78. package/src/server/middleware.ts +58 -0
  79. package/src/server/routes.ts +278 -0
  80. package/src/templates/default-jobs.json +47 -0
  81. package/src/templates/hooks/compaction-recovery.sh +23 -0
  82. package/src/templates/hooks/dangerous-command-guard.sh +35 -0
  83. package/src/templates/hooks/grounding-before-messaging.sh +22 -0
  84. package/src/templates/hooks/session-start.sh +37 -0
  85. package/src/templates/hooks/settings-template.json +45 -0
  86. package/src/templates/scripts/health-watchdog.sh +63 -0
  87. package/src/templates/scripts/telegram-reply.sh +54 -0
  88. package/src/users/UserManager.ts +129 -0
  89. package/tests/e2e/lifecycle.test.ts +376 -0
  90. package/tests/fixtures/test-repo/CLAUDE.md +3 -0
  91. package/tests/fixtures/test-repo/README.md +1 -0
  92. package/tests/helpers/setup.ts +209 -0
  93. package/tests/integration/fresh-install.test.ts +218 -0
  94. package/tests/integration/scheduler-basic.test.ts +109 -0
  95. package/tests/integration/server-full.test.ts +284 -0
  96. package/tests/integration/session-lifecycle.test.ts +181 -0
  97. package/tests/unit/Config.test.ts +22 -0
  98. package/tests/unit/HealthChecker.test.ts +168 -0
  99. package/tests/unit/JobLoader.test.ts +151 -0
  100. package/tests/unit/JobScheduler.test.ts +267 -0
  101. package/tests/unit/Prerequisites.test.ts +59 -0
  102. package/tests/unit/RelationshipManager.test.ts +345 -0
  103. package/tests/unit/StateManager.test.ts +143 -0
  104. package/tests/unit/TelegramAdapter.test.ts +165 -0
  105. package/tests/unit/UserManager.test.ts +131 -0
  106. package/tests/unit/bootstrap.test.ts +28 -0
  107. package/tests/unit/commands.test.ts +138 -0
  108. package/tests/unit/middleware.test.ts +92 -0
  109. package/tests/unit/relationship-routes.test.ts +131 -0
  110. package/tests/unit/scaffold-templates.test.ts +132 -0
  111. package/tests/unit/server.test.ts +163 -0
  112. package/tsconfig.json +20 -0
  113. package/vitest.config.ts +9 -0
  114. package/vitest.e2e.config.ts +9 -0
  115. package/vitest.integration.config.ts +9 -0
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Core type definitions for instar.
3
+ *
4
+ * These types define the contracts between all modules.
5
+ * Everything flows from these — sessions, jobs, users, messaging.
6
+ */
7
+
8
+ // ── Session Management ──────────────────────────────────────────────
9
+
10
+ export interface Session {
11
+ id: string;
12
+ name: string;
13
+ status: SessionStatus;
14
+ /** The job that spawned this session, if any */
15
+ jobSlug?: string;
16
+ /** tmux session name */
17
+ tmuxSession: string;
18
+ /** When the session was created */
19
+ startedAt: string;
20
+ /** When the session ended (if completed) */
21
+ endedAt?: string;
22
+ /** User who triggered the session, if any */
23
+ triggeredBy?: string;
24
+ /** Model to use for this session */
25
+ model?: ModelTier;
26
+ /** The initial prompt/instruction sent to Claude */
27
+ prompt?: string;
28
+ }
29
+
30
+ export type SessionStatus = 'starting' | 'running' | 'completed' | 'failed' | 'killed';
31
+
32
+ export type ModelTier = 'opus' | 'sonnet' | 'haiku';
33
+
34
+ export interface SessionManagerConfig {
35
+ /** Path to tmux binary */
36
+ tmuxPath: string;
37
+ /** Path to claude CLI binary */
38
+ claudePath: string;
39
+ /** Project directory (where CLAUDE.md lives) */
40
+ projectDir: string;
41
+ /** Maximum concurrent sessions */
42
+ maxSessions: number;
43
+ /** Protected session names that should never be reaped */
44
+ protectedSessions: string[];
45
+ /** Patterns in tmux output that indicate session completion */
46
+ completionPatterns: string[];
47
+ }
48
+
49
+ // ── Job Scheduling ──────────────────────────────────────────────────
50
+
51
+ export interface JobDefinition {
52
+ slug: string;
53
+ name: string;
54
+ description: string;
55
+ /** Cron expression (e.g., "0 0/4 * * *" for every 4 hours) */
56
+ schedule: string;
57
+ /** Priority level — higher priority jobs run first and survive quota pressure */
58
+ priority: JobPriority;
59
+ /** Expected duration in minutes (for scheduling decisions) */
60
+ expectedDurationMinutes: number;
61
+ /** Model tier to use */
62
+ model: ModelTier;
63
+ /** Whether this job is currently enabled */
64
+ enabled: boolean;
65
+ /** The skill or prompt to execute */
66
+ execute: JobExecution;
67
+ /** Tags for filtering/grouping */
68
+ tags?: string[];
69
+ /** Telegram topic ID this job reports to (auto-created if not set) */
70
+ topicId?: number;
71
+ }
72
+
73
+ export type JobPriority = 'critical' | 'high' | 'medium' | 'low';
74
+
75
+ export interface JobExecution {
76
+ /** Type of execution */
77
+ type: 'skill' | 'prompt' | 'script';
78
+ /** The skill name, prompt text, or script path */
79
+ value: string;
80
+ /** Additional arguments */
81
+ args?: string;
82
+ }
83
+
84
+ export interface JobState {
85
+ slug: string;
86
+ lastRun?: string;
87
+ lastResult?: 'success' | 'failure' | 'timeout';
88
+ nextScheduled?: string;
89
+ consecutiveFailures: number;
90
+ }
91
+
92
+ export interface JobSchedulerConfig {
93
+ /** Path to jobs definition file */
94
+ jobsFile: string;
95
+ /** Whether the scheduler is active */
96
+ enabled: boolean;
97
+ /** Maximum parallel job sessions */
98
+ maxParallelJobs: number;
99
+ /** Quota thresholds for load shedding */
100
+ quotaThresholds: {
101
+ /** Below this: all jobs run */
102
+ normal: number;
103
+ /** Above this: only high+ priority */
104
+ elevated: number;
105
+ /** Above this: only critical */
106
+ critical: number;
107
+ /** Above this: no jobs */
108
+ shutdown: number;
109
+ };
110
+ }
111
+
112
+ // ── User Management ─────────────────────────────────────────────────
113
+
114
+ export interface UserProfile {
115
+ id: string;
116
+ name: string;
117
+ /** Communication channels this user is reachable on */
118
+ channels: UserChannel[];
119
+ /** What this user is allowed to do */
120
+ permissions: string[];
121
+ /** How the agent should interact with this user */
122
+ preferences: UserPreferences;
123
+ /** Interaction history summary */
124
+ context?: string;
125
+ }
126
+
127
+ export interface UserChannel {
128
+ /** Channel type (telegram, slack, discord, email, etc.) */
129
+ type: string;
130
+ /** Channel-specific identifier (topic ID, Slack user ID, email address, etc.) */
131
+ identifier: string;
132
+ }
133
+
134
+ export interface UserPreferences {
135
+ /** Communication style (e.g., "technical and direct", "prefers explanations") */
136
+ style?: string;
137
+ /** Whether to auto-execute or confirm with this user */
138
+ autonomyLevel?: 'full' | 'confirm-destructive' | 'confirm-all';
139
+ /** Timezone for scheduling */
140
+ timezone?: string;
141
+ }
142
+
143
+ // ── Messaging ───────────────────────────────────────────────────────
144
+
145
+ export interface Message {
146
+ /** Unique message ID */
147
+ id: string;
148
+ /** User who sent the message */
149
+ userId: string;
150
+ /** The message content */
151
+ content: string;
152
+ /** Channel the message came from */
153
+ channel: UserChannel;
154
+ /** When the message was received */
155
+ receivedAt: string;
156
+ /** Message metadata (platform-specific) */
157
+ metadata?: Record<string, unknown>;
158
+ }
159
+
160
+ export interface OutgoingMessage {
161
+ /** User to send to */
162
+ userId: string;
163
+ /** Message content */
164
+ content: string;
165
+ /** Specific channel to use (optional — uses default if omitted) */
166
+ channel?: UserChannel;
167
+ }
168
+
169
+ /**
170
+ * Messaging adapter interface.
171
+ * Implement this for each platform (Telegram, Slack, Discord, etc.)
172
+ */
173
+ export interface MessagingAdapter {
174
+ /** Platform name (e.g., "telegram", "slack") */
175
+ platform: string;
176
+ /** Start listening for messages */
177
+ start(): Promise<void>;
178
+ /** Stop listening */
179
+ stop(): Promise<void>;
180
+ /** Send a message to a user */
181
+ send(message: OutgoingMessage): Promise<void>;
182
+ /** Register a handler for incoming messages */
183
+ onMessage(handler: (message: Message) => Promise<void>): void;
184
+ /** Resolve a platform-specific identifier to a user ID */
185
+ resolveUser(channelIdentifier: string): Promise<string | null>;
186
+ }
187
+
188
+ // ── Monitoring ──────────────────────────────────────────────────────
189
+
190
+ export interface QuotaState {
191
+ /** Current usage percentage (0-100) */
192
+ usagePercent: number;
193
+ /** When usage data was last updated */
194
+ lastUpdated: string;
195
+ /** Per-account breakdown if multi-account */
196
+ accounts?: AccountQuota[];
197
+ /** Recommended action based on usage */
198
+ recommendation?: 'normal' | 'reduce' | 'critical' | 'stop';
199
+ }
200
+
201
+ export interface AccountQuota {
202
+ email: string;
203
+ usagePercent: number;
204
+ isActive: boolean;
205
+ lastUpdated: string;
206
+ }
207
+
208
+ export interface HealthStatus {
209
+ status: 'healthy' | 'degraded' | 'unhealthy';
210
+ components: Record<string, ComponentHealth>;
211
+ timestamp: string;
212
+ }
213
+
214
+ export interface ComponentHealth {
215
+ status: 'healthy' | 'degraded' | 'unhealthy';
216
+ message?: string;
217
+ lastCheck: string;
218
+ }
219
+
220
+ // ── Relationship Tracking ───────────────────────────────────────────
221
+
222
+ export interface RelationshipRecord {
223
+ /** Unique identifier for this person */
224
+ id: string;
225
+ /** Display name */
226
+ name: string;
227
+ /** Known identifiers across platforms */
228
+ channels: UserChannel[];
229
+ /** When the agent first interacted with this person */
230
+ firstInteraction: string;
231
+ /** When the agent last interacted with this person */
232
+ lastInteraction: string;
233
+ /** Total number of interactions */
234
+ interactionCount: number;
235
+ /** Key topics discussed across conversations */
236
+ themes: string[];
237
+ /** Agent's notes about this person — observations, preferences, context */
238
+ notes: string;
239
+ /** Communication style preferences the agent has observed */
240
+ communicationStyle?: string;
241
+ /** How significant this relationship is (0-10, auto-derived from frequency and depth) */
242
+ significance: number;
243
+ /** Brief summary of the relationship arc */
244
+ arcSummary?: string;
245
+ /** Per-interaction log (last N interactions, kept compact) */
246
+ recentInteractions: InteractionSummary[];
247
+ }
248
+
249
+ export interface InteractionSummary {
250
+ /** When this interaction happened */
251
+ timestamp: string;
252
+ /** Which platform/channel */
253
+ channel: string;
254
+ /** Brief summary of what was discussed */
255
+ summary: string;
256
+ /** Topics touched on */
257
+ topics?: string[];
258
+ }
259
+
260
+ export interface RelationshipManagerConfig {
261
+ /** Directory to store relationship files */
262
+ relationshipsDir: string;
263
+ /** Maximum recent interactions to keep per relationship */
264
+ maxRecentInteractions: number;
265
+ }
266
+
267
+ // ── Activity Tracking ───────────────────────────────────────────────
268
+
269
+ export interface ActivityEvent {
270
+ type: string;
271
+ summary: string;
272
+ /** Which session generated this event */
273
+ sessionId?: string;
274
+ /** Which user triggered this, if any */
275
+ userId?: string;
276
+ timestamp: string;
277
+ metadata?: Record<string, unknown>;
278
+ }
279
+
280
+ // ── Server Configuration ────────────────────────────────────────────
281
+
282
+ export interface AgentKitConfig {
283
+ /** Project name (used in logging, tmux session names, etc.) */
284
+ projectName: string;
285
+ /** Project root directory */
286
+ projectDir: string;
287
+ /** Where instar stores its runtime state */
288
+ stateDir: string;
289
+ /** HTTP server port */
290
+ port: number;
291
+ /** Session manager config */
292
+ sessions: SessionManagerConfig;
293
+ /** Job scheduler config */
294
+ scheduler: JobSchedulerConfig;
295
+ /** Registered users */
296
+ users: UserProfile[];
297
+ /** Messaging adapters to enable */
298
+ messaging: MessagingAdapterConfig[];
299
+ /** Monitoring config */
300
+ monitoring: MonitoringConfig;
301
+ /** Auth token for API access (generated during setup) */
302
+ authToken?: string;
303
+ /** Relationship tracking config */
304
+ relationships: RelationshipManagerConfig;
305
+ }
306
+
307
+ export interface MessagingAdapterConfig {
308
+ type: string;
309
+ enabled: boolean;
310
+ config: Record<string, unknown>;
311
+ }
312
+
313
+ export interface MonitoringConfig {
314
+ /** Enable quota tracking */
315
+ quotaTracking: boolean;
316
+ /** Enable memory pressure monitoring */
317
+ memoryMonitoring: boolean;
318
+ /** Health check interval in ms */
319
+ healthCheckIntervalMs: number;
320
+ }
package/src/index.ts ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * instar — Persistent autonomy infrastructure for AI agents.
3
+ *
4
+ * Public API for programmatic usage.
5
+ */
6
+
7
+ // Core
8
+ export { SessionManager } from './core/SessionManager.js';
9
+ export { StateManager } from './core/StateManager.js';
10
+ export { RelationshipManager } from './core/RelationshipManager.js';
11
+ export { loadConfig, detectTmuxPath, detectClaudePath, ensureStateDir } from './core/Config.js';
12
+
13
+ // Users
14
+ export { UserManager } from './users/UserManager.js';
15
+
16
+ // Scheduler
17
+ export { JobScheduler } from './scheduler/JobScheduler.js';
18
+ export { loadJobs, validateJob } from './scheduler/JobLoader.js';
19
+
20
+ // Server
21
+ export { AgentServer } from './server/AgentServer.js';
22
+ export { createRoutes } from './server/routes.js';
23
+
24
+ // Monitoring
25
+ export { HealthChecker } from './monitoring/HealthChecker.js';
26
+
27
+ // Messaging
28
+ export { TelegramAdapter } from './messaging/TelegramAdapter.js';
29
+
30
+ // Types
31
+ export type {
32
+ Session,
33
+ SessionStatus,
34
+ SessionManagerConfig,
35
+ ModelTier,
36
+ JobDefinition,
37
+ JobPriority,
38
+ JobExecution,
39
+ JobState,
40
+ JobSchedulerConfig,
41
+ UserProfile,
42
+ UserChannel,
43
+ UserPreferences,
44
+ Message,
45
+ OutgoingMessage,
46
+ MessagingAdapter,
47
+ MessagingAdapterConfig,
48
+ QuotaState,
49
+ AccountQuota,
50
+ HealthStatus,
51
+ ComponentHealth,
52
+ ActivityEvent,
53
+ AgentKitConfig,
54
+ MonitoringConfig,
55
+ RelationshipRecord,
56
+ RelationshipManagerConfig,
57
+ InteractionSummary,
58
+ } from './core/types.js';