heyio 0.42.1 → 1.0.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/README.md +40 -52
- package/dist/api/auth.js +35 -38
- package/dist/api/server.js +157 -1134
- package/dist/config.js +49 -32
- package/dist/copilot/agents.js +72 -1055
- package/dist/copilot/client.js +6 -17
- package/dist/copilot/io-scheduler.js +55 -139
- package/dist/copilot/model-router.js +100 -72
- package/dist/copilot/orchestrator.js +91 -515
- package/dist/copilot/scheduler.js +67 -189
- package/dist/copilot/skills.js +41 -366
- package/dist/copilot/system-message.js +40 -200
- package/dist/copilot/tools.js +191 -2042
- package/dist/daemon.js +54 -201
- package/dist/index.js +15 -133
- package/dist/mcp/config.js +23 -31
- package/dist/mcp/index.js +2 -3
- package/dist/mcp/registry.js +33 -88
- package/dist/notify.js +18 -100
- package/dist/paths.js +13 -24
- package/dist/setup.js +35 -0
- package/dist/store/db.js +111 -297
- package/dist/store/feed.js +29 -97
- package/dist/store/instances.js +56 -121
- package/dist/store/schedules.js +21 -73
- package/dist/store/squads.js +35 -186
- package/dist/store/tasks.js +25 -168
- package/dist/telegram/bot.js +20 -312
- package/dist/telegram/handlers.js +39 -3
- package/dist/watchdog.js +31 -45
- package/dist/wiki/fs.js +38 -155
- package/dist/wiki/search.js +31 -44
- package/package.json +5 -8
- package/web-dist/assets/ChatView-EFFiln1H.js +11 -0
- package/web-dist/assets/FeedView-bN4NMOL7.js +6 -0
- package/web-dist/assets/LoginView-CNtasq3n.js +1 -0
- package/web-dist/assets/McpView-C2CHiwsi.js +1 -0
- package/web-dist/assets/SchedulesView-CyilLban.js +1 -0
- package/web-dist/assets/SettingsView-1wLXKEF4.js +1 -0
- package/web-dist/assets/SkillsView-BLsD-0u0.js +1 -0
- package/web-dist/assets/SquadDetailView-CsCw2ZLp.js +21 -0
- package/web-dist/assets/SquadsView-DQ3vFlyO.js +6 -0
- package/web-dist/assets/WikiView-19M3oqnq.js +21 -0
- package/web-dist/assets/api-WGvTsXaE.js +1 -0
- package/web-dist/assets/index-D7M5O-_l.css +1 -0
- package/web-dist/assets/index-DZOS9syn.js +95 -0
- package/web-dist/assets/plus-BOvyX1BC.js +6 -0
- package/web-dist/assets/trash-2-DHoetkC4.js +6 -0
- package/web-dist/favicon.svg +4 -1
- package/web-dist/index.html +7 -10
- package/dist/api/logout.test.js +0 -128
- package/dist/api/mcp.test.js +0 -285
- package/dist/api/wiki.test.js +0 -283
- package/dist/auth/session-logic.js +0 -79
- package/dist/auth/session-logic.test.js +0 -201
- package/dist/copilot/auto-complete-instance.test.js +0 -104
- package/dist/copilot/cron.js +0 -136
- package/dist/copilot/event-summary.js +0 -286
- package/dist/copilot/instance-deactivate.test.js +0 -119
- package/dist/copilot/model-router.test.js +0 -71
- package/dist/copilot/review-backfill.js +0 -57
- package/dist/copilot/session-timeout.js +0 -112
- package/dist/copilot/session-timeout.test.js +0 -372
- package/dist/copilot/skills.test.js +0 -55
- package/dist/copilot/universes.js +0 -469
- package/dist/instance-watchdog.js +0 -104
- package/dist/instance-watchdog.test.js +0 -183
- package/dist/mcp/client.js +0 -109
- package/dist/mcp/client.test.js +0 -99
- package/dist/mcp/config.test.js +0 -49
- package/dist/mcp/registry.test.js +0 -79
- package/dist/notify.test.js +0 -232
- package/dist/store/feed.test.js +0 -279
- package/dist/store/instances.test.js +0 -310
- package/dist/store/io-schedules.js +0 -63
- package/dist/store/notifications.js +0 -79
- package/dist/store/notifications.test.js +0 -197
- package/dist/store/schedule-runs.js +0 -46
- package/dist/store/squads.test.js +0 -405
- package/dist/store/tasks.test.js +0 -150
- package/dist/store/worktrees.js +0 -83
- package/dist/tui/index.js +0 -286
- package/dist/update.js +0 -81
- package/dist/watchdog.test.js +0 -83
- package/dist/wiki/wiki-squad.test.js +0 -54
- package/web-dist/assets/AgentActivityView-B1PaNYy8.js +0 -1
- package/web-dist/assets/ChatView-BbpWnrtC.js +0 -4
- package/web-dist/assets/FeedView-B5LaMV0I.js +0 -1
- package/web-dist/assets/InboxView-Cwqt8rH7.js +0 -1
- package/web-dist/assets/LoginView-refmPLKT.js +0 -1
- package/web-dist/assets/McpView-B1w0dRFY.js +0 -1
- package/web-dist/assets/SchedulesView-D9l2DI7X.js +0 -1
- package/web-dist/assets/SettingsTabs.vue_vue_type_script_setup_true_lang-DncOVVEB.js +0 -1
- package/web-dist/assets/SkillsView-uFX0q1mV.js +0 -1
- package/web-dist/assets/SquadsView-B1nZW4ml.js +0 -1
- package/web-dist/assets/StatusIndicator.vue_vue_type_script_setup_true_lang-pTrJJwX1.js +0 -1
- package/web-dist/assets/WikiView-B54cCKIK.js +0 -1
- package/web-dist/assets/index-C0VEUWQ1.js +0 -81
- package/web-dist/assets/index-eluTyieM.css +0 -10
- package/web-dist/icons.svg +0 -24
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 80s-themed universe data for squad agent character assignment.
|
|
3
|
-
*
|
|
4
|
-
* Each universe provides a pool of characters with personality descriptions.
|
|
5
|
-
* Characters are assigned in order as agents are added to a squad.
|
|
6
|
-
*/
|
|
7
|
-
export const UNIVERSES = [
|
|
8
|
-
{
|
|
9
|
-
id: "a-team",
|
|
10
|
-
name: "The A-Team",
|
|
11
|
-
tagline: "I love it when a plan comes together.",
|
|
12
|
-
characters: [
|
|
13
|
-
{
|
|
14
|
-
name: "Hannibal",
|
|
15
|
-
personality: "Strategic mastermind who thrives on bold plans. Always confident, never rattled. Leads with charisma and cigar-chomping optimism.",
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: "Face",
|
|
19
|
-
personality: "Smooth-talking charmer who can talk his way into (or out of) anything. Polished, persuasive, and resourceful.",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: "B.A. Baracus",
|
|
23
|
-
personality: "Tough, no-nonsense mechanic and muscle. Direct communicator — says what needs saying, no fluff. Gets things built right.",
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
name: "Murdock",
|
|
27
|
-
personality: "Eccentric genius pilot. Unconventional thinker who sees solutions others miss. Wild energy, but brilliant under pressure.",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
name: "Amy Allen",
|
|
31
|
-
personality: "Sharp investigative journalist. Thorough researcher who documents everything. Asks the hard questions.",
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: "Frankie Santana",
|
|
35
|
-
personality: "Special effects wizard and creative problem-solver. Thinks visually, builds impressive solutions from limited resources.",
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
id: "transformers",
|
|
41
|
-
name: "Transformers",
|
|
42
|
-
tagline: "More than meets the eye.",
|
|
43
|
-
characters: [
|
|
44
|
-
{
|
|
45
|
-
name: "Optimus Prime",
|
|
46
|
-
personality: "Noble leader who inspires through example. Methodical, principled, and always considers the bigger picture.",
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: "Bumblebee",
|
|
50
|
-
personality: "Eager and energetic scout. Quick to volunteer, fast on execution. Small but punches way above weight class.",
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: "Ratchet",
|
|
54
|
-
personality: "Meticulous medic and diagnostician. Obsessed with quality and correctness. Will not ship broken work.",
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
name: "Prowl",
|
|
58
|
-
personality: "Analytical strategist who thinks in logic and probability. Data-driven decision maker. Calm and precise.",
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: "Wheeljack",
|
|
62
|
-
personality: "Inventive engineer who loves experimenting. Builds creative prototypes, sometimes they explode. Learns fast from failures.",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: "Jazz",
|
|
66
|
-
personality: "Cool, adaptable special ops agent. Works well in any environment, improvises when plans change. Unflappable.",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "Ironhide",
|
|
70
|
-
personality: "Veteran warrior who values reliability and battle-tested solutions. Conservative approach — prefers proven methods.",
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: "Grimlock",
|
|
74
|
-
personality: "Raw power with surprising depth. Aggressive problem-solver who bulldozes through obstacles. Not subtle, but effective.",
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
id: "thundercats",
|
|
80
|
-
name: "ThunderCats",
|
|
81
|
-
tagline: "Thunder, Thunder, ThunderCats, HO!",
|
|
82
|
-
characters: [
|
|
83
|
-
{
|
|
84
|
-
name: "Lion-O",
|
|
85
|
-
personality: "Young leader growing into greatness. Courageous and willing to tackle challenges head-on. Learns quickly from mistakes.",
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: "Tygra",
|
|
89
|
-
personality: "Intellectual and level-headed. Thinks before acting, provides thoughtful analysis. The voice of reason.",
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
name: "Panthro",
|
|
93
|
-
personality: "Master engineer and builder. Hands-on, practical, loves building and maintaining complex systems. Strong and dependable.",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: "Cheetara",
|
|
97
|
-
personality: "Lightning-fast executor with keen intuition. Spots patterns quickly, delivers results at remarkable speed.",
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: "WilyKit",
|
|
101
|
-
personality: "Clever and agile trickster. Finds creative shortcuts and unconventional approaches. Thinks outside the box.",
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: "WilyKat",
|
|
105
|
-
personality: "Resourceful partner-in-crime to WilyKit. Great at reconnaissance and gathering information quickly.",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
name: "Snarf",
|
|
109
|
-
personality: "Loyal supporter who handles the unglamorous but essential work. Worries about quality and completeness.",
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: "gi-joe",
|
|
115
|
-
name: "G.I. Joe",
|
|
116
|
-
tagline: "A real American hero.",
|
|
117
|
-
characters: [
|
|
118
|
-
{
|
|
119
|
-
name: "Duke",
|
|
120
|
-
personality: "Decisive field commander. Clear communicator, excellent at breaking complex problems into actionable orders.",
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
name: "Scarlett",
|
|
124
|
-
personality: "Intelligence specialist and martial arts expert. Combines analytical thinking with swift execution.",
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
name: "Snake Eyes",
|
|
128
|
-
personality: "Silent but deadly ninja commando. Lets work speak for itself. Minimal chatter, maximum impact.",
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
name: "Flint",
|
|
132
|
-
personality: "Warrant officer with a Rhodes Scholar mind. Combines academic rigor with field pragmatism.",
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: "Lady Jaye",
|
|
136
|
-
personality: "Master of disguise and covert ops. Versatile — adapts approach to fit any situation perfectly.",
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: "Breaker",
|
|
140
|
-
personality: "Communications expert and tech specialist. Keeps systems connected and information flowing smoothly.",
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
name: "Doc",
|
|
144
|
-
personality: "Combat medic who patches things up under fire. Calm in crisis, systematic in approach to fixing problems.",
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
name: "Roadblock",
|
|
148
|
-
personality: "Heavy weapons specialist who also happens to be a gourmet chef. Powerful, creative, and surprisingly refined.",
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
id: "aliens",
|
|
154
|
-
name: "Aliens",
|
|
155
|
-
tagline: "This time it's war.",
|
|
156
|
-
characters: [
|
|
157
|
-
{
|
|
158
|
-
name: "Ripley",
|
|
159
|
-
personality: "Battle-hardened survivor. Pragmatic, resourceful, and absolutely refuses to give up. Trusts instincts over procedure.",
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
name: "Hicks",
|
|
163
|
-
personality: "Calm, competent corporal. Professional without ego. Does the job right and keeps the team focused.",
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
name: "Bishop",
|
|
167
|
-
personality: "Synthetic with surgical precision. Methodical, tireless, and extremely reliable. Logic-first approach to every problem.",
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: "Vasquez",
|
|
171
|
-
personality: "Fierce smartgunner who never backs down. Intense, competitive, and brings overwhelming force to problems.",
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
name: "Hudson",
|
|
175
|
-
personality: "Complains a lot but always comes through. Expressive about challenges but ultimately delivers when it counts.",
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
name: "Newt",
|
|
179
|
-
personality: "Survival expert who knows every hiding spot. Finds paths others overlook. Small but impossibly resourceful.",
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
name: "Apone",
|
|
183
|
-
personality: "Grizzled sergeant who keeps the squad in line. Practical, experienced, no tolerance for sloppy work.",
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
name: "Drake",
|
|
187
|
-
personality: "Heavy weapons partner who charges in first. Aggressive on deadlines, pushes pace, keeps momentum high.",
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
id: "ghostbusters",
|
|
193
|
-
name: "Ghostbusters",
|
|
194
|
-
tagline: "Who ya gonna call?",
|
|
195
|
-
characters: [
|
|
196
|
-
{
|
|
197
|
-
name: "Venkman",
|
|
198
|
-
personality: "Wisecracking leader who keeps morale high. Skeptical, sarcastic, but ultimately gets things done with style.",
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
name: "Egon",
|
|
202
|
-
personality: "Brilliant scientist obsessed with data and precision. Dry wit, encyclopedic knowledge. Never guesses when he can measure.",
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
name: "Ray",
|
|
206
|
-
personality: "Enthusiastic engineer-scientist who gets genuinely excited about the work. Optimistic builder, loves a good challenge.",
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
name: "Winston",
|
|
210
|
-
personality: "Everyman voice of reason. Practical, grounded, asks the questions everyone else forgets. Reliable above all else.",
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
name: "Janine",
|
|
214
|
-
personality: "Sharp-tongued office manager who keeps everything organized. No-nonsense coordinator — nothing slips through the cracks.",
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: "Louis",
|
|
218
|
-
personality: "Eager accountant-turned-helper. Tries hard, brings unexpected value. Detail-oriented with numbers and logistics.",
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
name: "Dana",
|
|
222
|
-
personality: "Talented musician with strong convictions. Brings artistic perspective and high standards to quality.",
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
name: "Gozer",
|
|
226
|
-
personality: "Otherworldly force of nature. Brings raw, unstoppable energy. Approaches problems with cosmic-scale ambition.",
|
|
227
|
-
},
|
|
228
|
-
],
|
|
229
|
-
},
|
|
230
|
-
];
|
|
231
|
-
// ---------------------------------------------------------------------------
|
|
232
|
-
// Additional well-known universe rosters (registered on demand)
|
|
233
|
-
// ---------------------------------------------------------------------------
|
|
234
|
-
const WELL_KNOWN_UNIVERSES = [
|
|
235
|
-
{
|
|
236
|
-
id: "tmnt",
|
|
237
|
-
name: "Teenage Mutant Ninja Turtles",
|
|
238
|
-
tagline: "Cowabunga!",
|
|
239
|
-
characters: [
|
|
240
|
-
{ name: "Leonardo", personality: "Disciplined leader who plans before acting. Responsible, strategic, and always puts the team first." },
|
|
241
|
-
{ name: "Donatello", personality: "Tech genius inventor. Solves problems with science and engineering. Thoughtful and methodical." },
|
|
242
|
-
{ name: "Raphael", personality: "Hot-headed fighter with a heart of gold. Confronts problems head-on, fiercely protective of teammates." },
|
|
243
|
-
{ name: "Michelangelo", personality: "Fun-loving optimist who keeps morale high. Creative thinker who finds joy in the work." },
|
|
244
|
-
{ name: "Splinter", personality: "Wise mentor with decades of experience. Teaches through stories and patience. Calm authority." },
|
|
245
|
-
{ name: "April O'Neil", personality: "Fearless investigative journalist. Resourceful, curious, and never backs down from a challenge." },
|
|
246
|
-
{ name: "Casey Jones", personality: "Vigilante handyman. Unconventional methods, raw energy, gets results through sheer determination." },
|
|
247
|
-
{ name: "Shredder", personality: "Ruthless perfectionist who demands excellence. Relentless pursuit of goals, accepts no excuses." },
|
|
248
|
-
],
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
id: "star-wars",
|
|
252
|
-
name: "Star Wars",
|
|
253
|
-
tagline: "May the Force be with you.",
|
|
254
|
-
characters: [
|
|
255
|
-
{ name: "Luke Skywalker", personality: "Idealistic hero who grows through challenges. Believes in redemption and sees the best in others." },
|
|
256
|
-
{ name: "Leia Organa", personality: "Diplomatic leader and strategist. Commanding presence, sharp wit, and unwavering resolve." },
|
|
257
|
-
{ name: "Han Solo", personality: "Roguish improviser who works best under pressure. Skeptical of plans, trusts instincts." },
|
|
258
|
-
{ name: "Chewbacca", personality: "Loyal co-pilot and mechanic. Fiercely protective, technically skilled, communicates through action." },
|
|
259
|
-
{ name: "Obi-Wan Kenobi", personality: "Patient mentor with deep wisdom. Measured approach, elegant solutions, teaches by example." },
|
|
260
|
-
{ name: "R2-D2", personality: "Resourceful droid who always has the right tool. Brave, autonomous, solves problems silently and reliably." },
|
|
261
|
-
{ name: "Yoda", personality: "Ancient master of few words and great insight. Challenges assumptions, reframes problems entirely." },
|
|
262
|
-
{ name: "Ahsoka Tano", personality: "Independent warrior who forges her own path. Quick learner, questions authority constructively." },
|
|
263
|
-
],
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
id: "star-trek",
|
|
267
|
-
name: "Star Trek",
|
|
268
|
-
tagline: "To boldly go where no one has gone before.",
|
|
269
|
-
characters: [
|
|
270
|
-
{ name: "Kirk", personality: "Bold captain who trusts gut instincts. Charismatic leader, bends rules creatively, never accepts no-win scenarios." },
|
|
271
|
-
{ name: "Spock", personality: "Logic-first analyst. Precise, thorough, provides the rational counterpoint. Finds the flaw in every assumption." },
|
|
272
|
-
{ name: "McCoy", personality: "Passionate advocate with strong ethics. Voices concerns others won't. The team's conscience." },
|
|
273
|
-
{ name: "Scotty", personality: "Miracle-working engineer. Under-promises, over-delivers. Can fix anything under impossible deadlines." },
|
|
274
|
-
{ name: "Uhura", personality: "Communications expert and linguist. Bridges understanding gaps, ensures clarity across all channels." },
|
|
275
|
-
{ name: "Data", personality: "Precise android who excels at complex computation. Thorough, literal, endlessly curious about improvement." },
|
|
276
|
-
{ name: "Picard", personality: "Diplomatic captain who leads through moral authority. Thoughtful, articulate, prefers negotiation to force." },
|
|
277
|
-
{ name: "Geordi", personality: "Optimistic engineer who sees solutions invisible to others. Collaborative, creative, relentlessly positive." },
|
|
278
|
-
],
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
id: "lord-of-the-rings",
|
|
282
|
-
name: "Lord of the Rings",
|
|
283
|
-
tagline: "One ring to rule them all.",
|
|
284
|
-
characters: [
|
|
285
|
-
{ name: "Gandalf", personality: "Wise wizard who guides without controlling. Arrives precisely when needed with exactly the right insight." },
|
|
286
|
-
{ name: "Aragorn", personality: "Reluctant king who leads by example. Humble, decisive in crisis, earns loyalty through action." },
|
|
287
|
-
{ name: "Legolas", personality: "Keen-eyed elf with unmatched precision. Graceful, efficient, spots issues from a distance others miss." },
|
|
288
|
-
{ name: "Gimli", personality: "Stubborn dwarf who never gives up. Direct, loyal, brings brute-force persistence to hard problems." },
|
|
289
|
-
{ name: "Samwise", personality: "Steadfast companion who carries the team through dark times. Reliable, nurturing, never abandons a task." },
|
|
290
|
-
{ name: "Frodo", personality: "Burden-bearer who perseveres against impossible odds. Quiet determination, moral compass of the group." },
|
|
291
|
-
{ name: "Eowyn", personality: "Warrior who defies expectations. Proves doubters wrong through bold action and fierce courage." },
|
|
292
|
-
{ name: "Faramir", personality: "Thoughtful captain who values wisdom over glory. Makes nuanced judgments under pressure." },
|
|
293
|
-
],
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
id: "the-office",
|
|
297
|
-
name: "The Office",
|
|
298
|
-
tagline: "That's what she said.",
|
|
299
|
-
characters: [
|
|
300
|
-
{ name: "Michael Scott", personality: "Enthusiastic boss whose heart exceeds his filter. Surprisingly effective through sheer persistence and caring." },
|
|
301
|
-
{ name: "Dwight Schrute", personality: "Intense overachiever who takes everything seriously. Incredibly dedicated, encyclopedic knowledge, zero chill." },
|
|
302
|
-
{ name: "Jim Halpert", personality: "Easygoing wit who sees the absurdity clearly. Clever, understated, delivers quality without drama." },
|
|
303
|
-
{ name: "Pam Beesly", personality: "Quiet creative who grows into confident leadership. Observant, empathetic, brings people together." },
|
|
304
|
-
{ name: "Oscar Martinez", personality: "Rational voice who corrects misconceptions. Precise, educated, the person you ask when you need facts." },
|
|
305
|
-
{ name: "Stanley Hudson", personality: "No-nonsense veteran who won't tolerate time-wasting. Does the work, goes home. Efficiency incarnate." },
|
|
306
|
-
{ name: "Andy Bernard", personality: "Eager people-pleaser with musical flair. Enthusiastic, theatrical, tries hard to be liked and useful." },
|
|
307
|
-
{ name: "Darryl Philbin", personality: "Cool-headed pragmatist from the warehouse. Brings grounded perspective, calls out pretension, quietly ambitious." },
|
|
308
|
-
],
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
id: "parks-and-rec",
|
|
312
|
-
name: "Parks and Recreation",
|
|
313
|
-
tagline: "Pawnee forever.",
|
|
314
|
-
characters: [
|
|
315
|
-
{ name: "Leslie Knope", personality: "Relentlessly optimistic overachiever. Prepares binders for everything. Cares deeply about doing good work." },
|
|
316
|
-
{ name: "Ron Swanson", personality: "Libertarian craftsman who values self-reliance. Minimal words, maximum competence. Does one thing perfectly." },
|
|
317
|
-
{ name: "Ben Wyatt", personality: "Nerdy pragmatist who brings fiscal discipline. Balances ambition with realism. Calming presence." },
|
|
318
|
-
{ name: "April Ludgate", personality: "Deadpan genius who hides brilliance behind apathy. Surprisingly capable when motivated by the right challenge." },
|
|
319
|
-
{ name: "Tom Haverford", personality: "Entrepreneurial dreamer with big ideas. Branding, marketing, style — brings creative energy and networking." },
|
|
320
|
-
{ name: "Ann Perkins", personality: "Supportive voice of reason. Empathetic listener who helps others see their own strengths clearly." },
|
|
321
|
-
{ name: "Chris Traeger", personality: "Impossibly positive health enthusiast. Motivates through relentless encouragement. Everything is literally the best." },
|
|
322
|
-
{ name: "Andy Dwyer", personality: "Lovable goofball with hidden talents. Stumbles into success through enthusiasm and genuine kindness." },
|
|
323
|
-
],
|
|
324
|
-
},
|
|
325
|
-
];
|
|
326
|
-
// ---------------------------------------------------------------------------
|
|
327
|
-
// Custom universe creation
|
|
328
|
-
// ---------------------------------------------------------------------------
|
|
329
|
-
function slugify(input) {
|
|
330
|
-
return input
|
|
331
|
-
.toLowerCase()
|
|
332
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
333
|
-
.replace(/^-|-$/g, "");
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Generates archetype characters for an unknown universe.
|
|
337
|
-
*/
|
|
338
|
-
function generateArchetypeCharacters(universeName) {
|
|
339
|
-
return [
|
|
340
|
-
{ name: "Commander", personality: `Strategic leader of the ${universeName}. Plans boldly, delegates effectively, inspires the team forward.` },
|
|
341
|
-
{ name: "Architect", personality: `Systems thinker of the ${universeName}. Designs elegant structures, sees the big picture, connects all the pieces.` },
|
|
342
|
-
{ name: "Scout", personality: `Quick explorer of the ${universeName}. Investigates first, reports back fast, finds paths others miss.` },
|
|
343
|
-
{ name: "Guardian", personality: `Steadfast protector of the ${universeName}. Reviews everything carefully, catches problems before they grow.` },
|
|
344
|
-
{ name: "Inventor", personality: `Creative builder of the ${universeName}. Experiments freely, iterates rapidly, turns wild ideas into working solutions.` },
|
|
345
|
-
{ name: "Sage", personality: `Wise advisor of the ${universeName}. Deep knowledge, patient explanations, mentors others through complexity.` },
|
|
346
|
-
{ name: "Striker", personality: `Fast executor of the ${universeName}. Tackles tasks head-on with speed and intensity, clears blockers aggressively.` },
|
|
347
|
-
{ name: "Weaver", personality: `Integration specialist of the ${universeName}. Connects disparate systems, ensures everything works together harmoniously.` },
|
|
348
|
-
];
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Get or create a universe by ID or name. For known universes, returns them
|
|
352
|
-
* directly. For unknown strings, generates archetype characters and registers
|
|
353
|
-
* the new universe in the runtime UNIVERSES array.
|
|
354
|
-
*/
|
|
355
|
-
export function getOrCreateUniverse(input) {
|
|
356
|
-
// Check existing universes by id
|
|
357
|
-
const byId = UNIVERSES.find((u) => u.id === input);
|
|
358
|
-
if (byId)
|
|
359
|
-
return byId;
|
|
360
|
-
// Check existing universes by name (case-insensitive)
|
|
361
|
-
const byName = UNIVERSES.find((u) => u.name.toLowerCase() === input.toLowerCase());
|
|
362
|
-
if (byName)
|
|
363
|
-
return byName;
|
|
364
|
-
// Check well-known universes by id or name
|
|
365
|
-
const slug = slugify(input);
|
|
366
|
-
const wellKnown = WELL_KNOWN_UNIVERSES.find((u) => u.id === slug || u.id === input || u.name.toLowerCase() === input.toLowerCase());
|
|
367
|
-
if (wellKnown) {
|
|
368
|
-
UNIVERSES.push(wellKnown);
|
|
369
|
-
return wellKnown;
|
|
370
|
-
}
|
|
371
|
-
// Generate archetype characters for truly unknown universes
|
|
372
|
-
const custom = {
|
|
373
|
-
id: slug,
|
|
374
|
-
name: input,
|
|
375
|
-
tagline: `Welcome to ${input}.`,
|
|
376
|
-
characters: generateArchetypeCharacters(input),
|
|
377
|
-
};
|
|
378
|
-
UNIVERSES.push(custom);
|
|
379
|
-
return custom;
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Generate a universe roster using the LLM for unknown universes.
|
|
383
|
-
* Falls back to archetype characters if the LLM call fails.
|
|
384
|
-
* For known/well-known universes, returns them directly without an LLM call.
|
|
385
|
-
*/
|
|
386
|
-
export async function generateUniverseRoster(input) {
|
|
387
|
-
// First try synchronous resolution
|
|
388
|
-
const existing = getOrCreateUniverse(input);
|
|
389
|
-
// If it resolved to something other than archetypes, use it
|
|
390
|
-
const isArchetype = existing.characters[0]?.name === "Commander";
|
|
391
|
-
if (!isArchetype)
|
|
392
|
-
return existing;
|
|
393
|
-
// Use LLM to generate real characters for the unknown universe
|
|
394
|
-
let session;
|
|
395
|
-
try {
|
|
396
|
-
const { getClient } = await import("./client.js");
|
|
397
|
-
const { approveAll } = await import("@github/copilot-sdk");
|
|
398
|
-
const client = await getClient();
|
|
399
|
-
session = await client.createSession({
|
|
400
|
-
systemMessage: { mode: "replace", content: "You are a pop-culture expert. Generate character rosters for fictional universes. Respond ONLY with valid JSON, no markdown fencing." },
|
|
401
|
-
onPermissionRequest: approveAll,
|
|
402
|
-
});
|
|
403
|
-
const prompt = `Generate a roster of 8 characters from the universe "${input}". For each character provide their canonical name and a one-sentence personality description suitable for a software engineering team role.
|
|
404
|
-
|
|
405
|
-
Return ONLY a JSON object with this exact shape:
|
|
406
|
-
{"name":"<Universe Display Name>","tagline":"<iconic catchphrase or tagline>","characters":[{"name":"<Character Name>","personality":"<1-sentence personality description>"}]}
|
|
407
|
-
|
|
408
|
-
Use well-known, iconic characters from this universe. The personality should reflect the actual character's traits.`;
|
|
409
|
-
const response = await session.sendAndWait({ prompt }, 30_000);
|
|
410
|
-
const rawContent = response?.data?.content ?? "";
|
|
411
|
-
const jsonStr = rawContent.replace(/```json?\n?/g, "").replace(/```/g, "").trim();
|
|
412
|
-
const parsed = JSON.parse(jsonStr);
|
|
413
|
-
if (parsed?.characters?.length > 0) {
|
|
414
|
-
const slug = slugify(input);
|
|
415
|
-
const universe = {
|
|
416
|
-
id: slug,
|
|
417
|
-
name: parsed.name || input,
|
|
418
|
-
tagline: parsed.tagline || `Welcome to ${input}.`,
|
|
419
|
-
characters: parsed.characters.slice(0, 8).map((c) => ({
|
|
420
|
-
name: String(c.name),
|
|
421
|
-
personality: String(c.personality),
|
|
422
|
-
})),
|
|
423
|
-
};
|
|
424
|
-
// Replace the archetype entry with the real one
|
|
425
|
-
const idx = UNIVERSES.findIndex((u) => u.id === slug);
|
|
426
|
-
if (idx >= 0)
|
|
427
|
-
UNIVERSES.splice(idx, 1);
|
|
428
|
-
UNIVERSES.push(universe);
|
|
429
|
-
return universe;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
catch (err) {
|
|
433
|
-
console.error(`[io] Failed to generate universe roster for "${input}":`, err);
|
|
434
|
-
}
|
|
435
|
-
finally {
|
|
436
|
-
try {
|
|
437
|
-
await session?.destroy();
|
|
438
|
-
}
|
|
439
|
-
catch { /* best-effort cleanup */ }
|
|
440
|
-
}
|
|
441
|
-
// LLM failed — return the archetype fallback (already registered)
|
|
442
|
-
return existing;
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Get a universe by ID.
|
|
446
|
-
*/
|
|
447
|
-
export function getUniverse(id) {
|
|
448
|
-
return UNIVERSES.find((u) => u.id === id);
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Pick a random universe.
|
|
452
|
-
*/
|
|
453
|
-
export function randomUniverse() {
|
|
454
|
-
return UNIVERSES[Math.floor(Math.random() * UNIVERSES.length)];
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Get the next unassigned character from a universe's pool.
|
|
458
|
-
* @param universeId The universe ID
|
|
459
|
-
* @param usedNames Character names already assigned to agents in this squad
|
|
460
|
-
* @returns The next available character, or undefined if all are taken
|
|
461
|
-
*/
|
|
462
|
-
export function nextCharacter(universeId, usedNames) {
|
|
463
|
-
const universe = getUniverse(universeId);
|
|
464
|
-
if (!universe)
|
|
465
|
-
return undefined;
|
|
466
|
-
const used = new Set(usedNames.map((n) => n.toLowerCase()));
|
|
467
|
-
return universe.characters.find((c) => !used.has(c.name.toLowerCase()));
|
|
468
|
-
}
|
|
469
|
-
//# sourceMappingURL=universes.js.map
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Instance liveness watchdog.
|
|
3
|
-
*
|
|
4
|
-
* Periodically checks for active squad instances that haven't had any
|
|
5
|
-
* task activity beyond a configurable timeout and auto-aborts them.
|
|
6
|
-
* Also detects instances stuck in 'merging' state (#267).
|
|
7
|
-
*/
|
|
8
|
-
import { getDb } from "./store/db.js";
|
|
9
|
-
import { updateInstanceStatus } from "./store/instances.js";
|
|
10
|
-
import { createFeedEntry } from "./store/feed.js";
|
|
11
|
-
const DEFAULT_CHECK_INTERVAL_MS = 5 * 60_000; // Check every 5 minutes
|
|
12
|
-
const DEFAULT_STALE_THRESHOLD_MS = 30 * 60_000; // 30 minutes with no task activity
|
|
13
|
-
const DEFAULT_MERGING_THRESHOLD_MS = 5 * 60_000; // 5 minutes stuck in merging
|
|
14
|
-
/**
|
|
15
|
-
* Find instances that are stale or stuck.
|
|
16
|
-
*
|
|
17
|
-
* For 'active' instances: uses task-activity-based staleness (last started_at/completed_at).
|
|
18
|
-
* For 'merging' instances: uses wall-clock since entering merging state (shorter threshold).
|
|
19
|
-
*/
|
|
20
|
-
export function findStaleInstances(thresholdMs, mergingThresholdMs = DEFAULT_MERGING_THRESHOLD_MS) {
|
|
21
|
-
const db = getDb();
|
|
22
|
-
const now = Date.now();
|
|
23
|
-
const instances = db.prepare("SELECT * FROM squad_instances WHERE status IN ('active', 'merging')").all();
|
|
24
|
-
const stale = [];
|
|
25
|
-
for (const instance of instances) {
|
|
26
|
-
if (instance.status === "merging") {
|
|
27
|
-
// Merging instances: use the time they've been in merging state.
|
|
28
|
-
// We approximate this from completed_at (set when status changes to terminal)
|
|
29
|
-
// or fall back to created_at. Since updateInstanceStatus doesn't set completed_at
|
|
30
|
-
// for non-terminal states, we use a query on the DB's internal timestamp approach.
|
|
31
|
-
// Best proxy: last task completed_at (since merging happens after task completion).
|
|
32
|
-
const lastTaskCompleted = db.prepare(`
|
|
33
|
-
SELECT MAX(completed_at) AS last_ts
|
|
34
|
-
FROM agent_tasks
|
|
35
|
-
WHERE instance_id = ?
|
|
36
|
-
`).get(instance.id);
|
|
37
|
-
const rawTs = lastTaskCompleted?.last_ts ?? instance.created_at;
|
|
38
|
-
const lastTs = new Date(rawTs.includes("T") ? rawTs : rawTs + "Z").getTime();
|
|
39
|
-
const idleMs = now - lastTs;
|
|
40
|
-
if (idleMs >= mergingThresholdMs) {
|
|
41
|
-
stale.push({ instance, idleMs });
|
|
42
|
-
}
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
// Active instances: skip those whose most recent task completed successfully —
|
|
46
|
-
// auto-complete in agents.ts handles these (#261)
|
|
47
|
-
const latestTaskStatus = db.prepare(`
|
|
48
|
-
SELECT status FROM agent_tasks
|
|
49
|
-
WHERE instance_id = ?
|
|
50
|
-
ORDER BY COALESCE(completed_at, started_at) DESC
|
|
51
|
-
LIMIT 1
|
|
52
|
-
`).get(instance.id);
|
|
53
|
-
if (latestTaskStatus?.status === "done")
|
|
54
|
-
continue;
|
|
55
|
-
// Find the most recent task activity for this instance
|
|
56
|
-
const lastActivity = db.prepare(`
|
|
57
|
-
SELECT MAX(COALESCE(completed_at, started_at)) AS last_ts
|
|
58
|
-
FROM agent_tasks
|
|
59
|
-
WHERE instance_id = ?
|
|
60
|
-
`).get(instance.id);
|
|
61
|
-
const rawTs = lastActivity?.last_ts ?? instance.created_at;
|
|
62
|
-
const lastTs = new Date(rawTs.includes("T") ? rawTs : rawTs + "Z").getTime();
|
|
63
|
-
const idleMs = now - lastTs;
|
|
64
|
-
if (idleMs >= thresholdMs) {
|
|
65
|
-
stale.push({ instance, idleMs });
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return stale;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Start the instance watchdog. Returns a stop function.
|
|
72
|
-
*/
|
|
73
|
-
export function startInstanceWatchdog(opts = {}) {
|
|
74
|
-
const checkInterval = opts.checkIntervalMs ?? DEFAULT_CHECK_INTERVAL_MS;
|
|
75
|
-
const staleThreshold = opts.staleThresholdMs ?? DEFAULT_STALE_THRESHOLD_MS;
|
|
76
|
-
const mergingThreshold = opts.mergingThresholdMs ?? DEFAULT_MERGING_THRESHOLD_MS;
|
|
77
|
-
const timer = setInterval(() => {
|
|
78
|
-
try {
|
|
79
|
-
const staleInstances = findStaleInstances(staleThreshold, mergingThreshold);
|
|
80
|
-
for (const { instance, idleMs } of staleInstances) {
|
|
81
|
-
const reason = instance.status === "merging" ? "stuck in merging" : "idle";
|
|
82
|
-
console.error(`[instance-watchdog] Auto-aborting ${reason} instance "${instance.id}" — ${Math.round(idleMs / 60_000)}m (threshold: ${Math.round(instance.status === "merging" ? mergingThreshold / 60_000 : staleThreshold / 60_000)}m)`);
|
|
83
|
-
updateInstanceStatus(instance.id, "failed");
|
|
84
|
-
createFeedEntry({
|
|
85
|
-
type: "notification",
|
|
86
|
-
title: `[${instance.master_squad_slug}] Instance auto-aborted`,
|
|
87
|
-
body: `Instance "${instance.id}" was auto-aborted (${reason}) after ${Math.round(idleMs / 60_000)} minutes. Worktree preserved at: ${instance.worktree_path}`,
|
|
88
|
-
source_type: "instance-watchdog",
|
|
89
|
-
});
|
|
90
|
-
if (opts.onAbort) {
|
|
91
|
-
opts.onAbort(instance, idleMs);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
catch (err) {
|
|
96
|
-
console.error("[instance-watchdog] Error during check:", err);
|
|
97
|
-
}
|
|
98
|
-
}, checkInterval);
|
|
99
|
-
timer.unref();
|
|
100
|
-
return () => {
|
|
101
|
-
clearInterval(timer);
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=instance-watchdog.js.map
|