@adaptic/maestro 1.1.0 → 1.1.1
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/commands/init-maestro.md +292 -29
- package/.gitignore +29 -0
- package/README.md +220 -344
- package/bin/maestro.mjs +462 -7
- package/lib/action-executor.js +225 -0
- package/lib/index.js +16 -0
- package/lib/singleton.js +116 -0
- package/lib/tool-definitions.js +510 -0
- package/package.json +10 -1
- package/scaffold/CLAUDE.md +207 -0
- package/scripts/daemon/maestro-daemon.mjs +37 -0
- package/scripts/local-triggers/generate-plists.sh +235 -0
- package/scripts/local-triggers/install-all.sh +18 -12
- package/scripts/setup/init-agent.sh +58 -27
- package/scripts/slack-events-server.mjs +10 -0
- package/scripts/local-triggers/plists/ai.adaptic.slack-events-server.plist +0 -45
package/bin/maestro.mjs
CHANGED
|
@@ -114,6 +114,7 @@ function create(targetName) {
|
|
|
114
114
|
const agentDirs = [
|
|
115
115
|
"config",
|
|
116
116
|
"knowledge/decisions",
|
|
117
|
+
"knowledge/decisions/archive",
|
|
117
118
|
"knowledge/entities",
|
|
118
119
|
"knowledge/memory",
|
|
119
120
|
"knowledge/sources",
|
|
@@ -122,18 +123,30 @@ function create(targetName) {
|
|
|
122
123
|
"memory/profiles/users",
|
|
123
124
|
"memory/profiles/channels",
|
|
124
125
|
"memory/precedents",
|
|
126
|
+
"memory/precedents/market-signals",
|
|
125
127
|
"memory/indexes",
|
|
126
128
|
"memory/templates",
|
|
127
129
|
"state/inbox/slack",
|
|
128
130
|
"state/inbox/gmail",
|
|
129
131
|
"state/inbox/calendar",
|
|
130
132
|
"state/inbox/sms",
|
|
133
|
+
"state/inbox/whatsapp",
|
|
131
134
|
"state/inbox/internal",
|
|
135
|
+
"state/inbox/attachments",
|
|
136
|
+
"state/inbox/processed",
|
|
132
137
|
"state/queues",
|
|
133
138
|
"state/dashboards",
|
|
134
139
|
"state/polling",
|
|
135
140
|
"state/locks/outbound",
|
|
136
141
|
"state/triggers/priority",
|
|
142
|
+
"state/handoffs",
|
|
143
|
+
"state/huddle",
|
|
144
|
+
"state/indexes",
|
|
145
|
+
"state/rag",
|
|
146
|
+
"state/sessions",
|
|
147
|
+
"state/slack-responded",
|
|
148
|
+
"state/slack-thread-tracker",
|
|
149
|
+
"state/tmp",
|
|
137
150
|
"outputs/briefs",
|
|
138
151
|
"outputs/drafts",
|
|
139
152
|
"outputs/memos",
|
|
@@ -148,6 +161,14 @@ function create(targetName) {
|
|
|
148
161
|
"logs/evolution",
|
|
149
162
|
"logs/huddle",
|
|
150
163
|
"logs/daemon",
|
|
164
|
+
"logs/infra",
|
|
165
|
+
"logs/monitor",
|
|
166
|
+
"logs/phone",
|
|
167
|
+
"logs/sms",
|
|
168
|
+
"logs/whatsapp",
|
|
169
|
+
"logs/email",
|
|
170
|
+
"self-optimization/scenarios",
|
|
171
|
+
"tests",
|
|
151
172
|
];
|
|
152
173
|
|
|
153
174
|
for (const dir of agentDirs) {
|
|
@@ -155,6 +176,392 @@ function create(targetName) {
|
|
|
155
176
|
}
|
|
156
177
|
ok(`${agentDirs.length} agent directories`);
|
|
157
178
|
|
|
179
|
+
// ── Step 3b: Generate template files ───────────────────────────────────
|
|
180
|
+
// These are empty-but-structured templates that define the operational
|
|
181
|
+
// schema for queues, dashboards, knowledge, and config. Without them,
|
|
182
|
+
// workflows and triggers have nothing to read/write.
|
|
183
|
+
|
|
184
|
+
log("Generating operational templates...");
|
|
185
|
+
|
|
186
|
+
// Queue templates — 16 operational queues
|
|
187
|
+
const queueTemplates = {
|
|
188
|
+
"action-stack": "Active action items requiring attention or follow-through",
|
|
189
|
+
"decision-queue": "Key decisions awaiting principal input or closure",
|
|
190
|
+
"follow-ups": "Commitments to external parties with due dates",
|
|
191
|
+
"awaiting-reply": "Messages sent that are awaiting responses",
|
|
192
|
+
"awaiting-approval": "Items pending principal or stakeholder approval",
|
|
193
|
+
"blocked-initiatives": "Strategic initiatives blocked by dependencies",
|
|
194
|
+
"high-risk-items": "Items with elevated risk requiring close monitoring",
|
|
195
|
+
"upcoming-deadlines": "Time-sensitive items with approaching deadlines",
|
|
196
|
+
"relationship-health": "Relationship maintenance and engagement tracking",
|
|
197
|
+
"hiring-critical-path": "Critical hiring actions and pipeline blockers",
|
|
198
|
+
"platform-blockers": "Technical and platform issues blocking delivery",
|
|
199
|
+
"capital-watchpoints": "Financial and fundraising items requiring attention",
|
|
200
|
+
"legal-obligations": "Regulatory submissions and legal compliance deadlines",
|
|
201
|
+
"narrative-opportunities": "Strategic narrative and thought leadership opportunities",
|
|
202
|
+
"tech-debt": "Technical debt with strategic impact",
|
|
203
|
+
"improvement-backlog": "Self-improvement and operational enhancement candidates",
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
for (const [name, desc] of Object.entries(queueTemplates)) {
|
|
207
|
+
const content = `queue_name: ${name}\ndescription: ${desc}\nitems: []\n`;
|
|
208
|
+
writeFileSync(join(targetDir, `state/queues/${name}.yaml`), content);
|
|
209
|
+
}
|
|
210
|
+
ok(`${Object.keys(queueTemplates).length} queue templates`);
|
|
211
|
+
|
|
212
|
+
// Dashboard templates — 10 operational dashboards
|
|
213
|
+
const dashboardTemplates = {
|
|
214
|
+
"executive-summary": {
|
|
215
|
+
description: "Primary situational awareness — read at every session start",
|
|
216
|
+
fields: "generated: null\nsummary:\n total_open_items: 0\n critical_items: 0\n overdue_items: 0\n sla_breaches: 0\n items_resolved_today: 0\n items_created_today: 0\nqueue_health: {}\ntop_priorities: []\ntop_blockers: []\n",
|
|
217
|
+
},
|
|
218
|
+
"daemon-health": {
|
|
219
|
+
description: "System health metrics for the daemon and triggers",
|
|
220
|
+
fields: "status: initialising\nlast_check: null\ntrigger_health: {}\npoller_health: {}\n",
|
|
221
|
+
},
|
|
222
|
+
"strategy-scorecard": {
|
|
223
|
+
description: "Progress on strategic priorities and quarterly OKRs",
|
|
224
|
+
fields: "generated: null\npriorities: []\ninitiatives: []\n",
|
|
225
|
+
},
|
|
226
|
+
"risk-register": {
|
|
227
|
+
description: "Enterprise risk register with severity and mitigation",
|
|
228
|
+
fields: "generated: null\nrisks: []\n",
|
|
229
|
+
},
|
|
230
|
+
"engineering-health": {
|
|
231
|
+
description: "Per-repo engineering activity, PRs, delivery confidence",
|
|
232
|
+
fields: "generated: null\nrepositories: []\ndelivery_confidence: null\n",
|
|
233
|
+
},
|
|
234
|
+
"org-health": {
|
|
235
|
+
description: "Hiring pipeline, capability gaps, structural risks",
|
|
236
|
+
fields: "generated: null\nhiring_pipeline: {}\ncapability_gaps: []\n",
|
|
237
|
+
},
|
|
238
|
+
"leadership-accountability": {
|
|
239
|
+
description: "Per-leader commitment follow-through tracking",
|
|
240
|
+
fields: "generated: null\nleaders: []\n",
|
|
241
|
+
},
|
|
242
|
+
"relationship-pipeline": {
|
|
243
|
+
description: "Strategic relationships with stage and warmth tracking",
|
|
244
|
+
fields: "generated: null\nrelationships: []\n",
|
|
245
|
+
},
|
|
246
|
+
"capital-readiness": {
|
|
247
|
+
description: "Runway, fundraising readiness, investor pipeline",
|
|
248
|
+
fields: "generated: null\nrunway_months: null\nreadiness_score: null\npipeline: []\n",
|
|
249
|
+
},
|
|
250
|
+
"system-health": {
|
|
251
|
+
description: "Self-governance metrics — evolution, coverage, queue health",
|
|
252
|
+
fields: "generated: null\nevolution_changes: 0\nknowledge_coverage: null\ntrigger_reliability: null\n",
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
for (const [name, { description, fields }] of Object.entries(dashboardTemplates)) {
|
|
257
|
+
const content = `# ${name.replace(/-/g, " ").replace(/\b\w/g, c => c.toUpperCase())} Dashboard\n# ${description}\n\n${fields}`;
|
|
258
|
+
writeFileSync(join(targetDir, `state/dashboards/${name}.yaml`), content);
|
|
259
|
+
}
|
|
260
|
+
ok(`${Object.keys(dashboardTemplates).length} dashboard templates`);
|
|
261
|
+
|
|
262
|
+
// Config templates — operational config files
|
|
263
|
+
log("Generating config templates...");
|
|
264
|
+
|
|
265
|
+
const configTemplates = {
|
|
266
|
+
"environment.yaml": `# Environment Configuration
|
|
267
|
+
# All environment-specific values — actual secrets are in .env
|
|
268
|
+
# Agent identity is defined in config/agent.ts
|
|
269
|
+
|
|
270
|
+
system:
|
|
271
|
+
name: maestro
|
|
272
|
+
version: 1.0.0
|
|
273
|
+
operator_persona: "UNCONFIGURED"
|
|
274
|
+
operator_role: "UNCONFIGURED"
|
|
275
|
+
company: ""
|
|
276
|
+
ceo: ""
|
|
277
|
+
timezone: UTC
|
|
278
|
+
|
|
279
|
+
machine:
|
|
280
|
+
type: mac-mini
|
|
281
|
+
os: macOS
|
|
282
|
+
hostname: \${HOSTNAME}
|
|
283
|
+
purpose: Autonomous agent operations node
|
|
284
|
+
|
|
285
|
+
paths:
|
|
286
|
+
agent_home: ~/${targetName}
|
|
287
|
+
logs: ~/${targetName}/logs
|
|
288
|
+
outputs: ~/${targetName}/outputs
|
|
289
|
+
`,
|
|
290
|
+
"contacts.yaml": `# Key Contacts
|
|
291
|
+
# Communication classifications and relationship context
|
|
292
|
+
# Updated by: init-maestro wizard, agent interactions
|
|
293
|
+
|
|
294
|
+
contacts: []
|
|
295
|
+
|
|
296
|
+
# Classification levels:
|
|
297
|
+
# - internal: team members, direct reports
|
|
298
|
+
# - external-trusted: partners, advisors, board members
|
|
299
|
+
# - external-standard: vendors, candidates, general contacts
|
|
300
|
+
# - regulatory: regulators, legal counterparties
|
|
301
|
+
`,
|
|
302
|
+
"priorities.yaml": `# Active Strategic Priorities
|
|
303
|
+
# Updated by: weekly-priorities workflow, principal directive
|
|
304
|
+
# Read by: morning-brief, backlog-executor, strategy-scorecard
|
|
305
|
+
|
|
306
|
+
priorities: []
|
|
307
|
+
|
|
308
|
+
# Priority format:
|
|
309
|
+
# - id: P1
|
|
310
|
+
# title: Priority title
|
|
311
|
+
# status: active | paused | completed
|
|
312
|
+
# owner: principal | agent
|
|
313
|
+
# milestones: []
|
|
314
|
+
# deadline: null
|
|
315
|
+
`,
|
|
316
|
+
"sla-defaults.yaml": `# SLA Defaults — response time expectations by item type
|
|
317
|
+
# Used by: inbox-processor, meeting-action-capture, midday-sweep
|
|
318
|
+
|
|
319
|
+
sla_defaults:
|
|
320
|
+
principal_request: 4
|
|
321
|
+
leadership_request: 24
|
|
322
|
+
external_partner: 48
|
|
323
|
+
regulatory: 24
|
|
324
|
+
candidate: 24
|
|
325
|
+
board_member: 12
|
|
326
|
+
investor: 24
|
|
327
|
+
general: 72
|
|
328
|
+
|
|
329
|
+
thresholds:
|
|
330
|
+
at_risk_percent: 75
|
|
331
|
+
breach_percent: 100
|
|
332
|
+
|
|
333
|
+
drift_thresholds:
|
|
334
|
+
critical_priority: 7
|
|
335
|
+
medium_priority: 14
|
|
336
|
+
low_priority: 30
|
|
337
|
+
`,
|
|
338
|
+
"brand-assets.yaml": `# Brand Assets Configuration
|
|
339
|
+
# Official brand assets, design system, and usage rules
|
|
340
|
+
# Assets directory: public/assets/
|
|
341
|
+
|
|
342
|
+
asset_inventory:
|
|
343
|
+
icon_dark: public/assets/adaptic-icon-dark.svg
|
|
344
|
+
icon_light: public/assets/adaptic-icon-light.svg
|
|
345
|
+
logo_dark: public/assets/adaptic-logo-dark.svg
|
|
346
|
+
logo_light: public/assets/adaptic-logo-light.svg
|
|
347
|
+
|
|
348
|
+
usage_rules:
|
|
349
|
+
dark_variants: "Use on light/white backgrounds"
|
|
350
|
+
light_variants: "Use on dark backgrounds"
|
|
351
|
+
full_logo: "Cover pages, document headers, title slides"
|
|
352
|
+
icon_only: "Footers, watermarks, compact placements"
|
|
353
|
+
never: "stretch, rotate, recolour, or modify the assets"
|
|
354
|
+
`,
|
|
355
|
+
"repo-registry.yaml": `# Source Repository Registry
|
|
356
|
+
# Cross-repository map for codebase awareness
|
|
357
|
+
# Updated by: init-maestro wizard
|
|
358
|
+
|
|
359
|
+
repositories: []
|
|
360
|
+
|
|
361
|
+
# Format:
|
|
362
|
+
# - name: repo-name
|
|
363
|
+
# path: ~/repo-name
|
|
364
|
+
# purpose: What this repo contains
|
|
365
|
+
# domains: [domain1, domain2]
|
|
366
|
+
`,
|
|
367
|
+
"slack-channels.yaml": `# Slack Channel Configuration
|
|
368
|
+
# Which channels the agent monitors and their purpose
|
|
369
|
+
# Updated by: init-maestro wizard
|
|
370
|
+
|
|
371
|
+
channels: []
|
|
372
|
+
|
|
373
|
+
# Format:
|
|
374
|
+
# - id: C0XXXXX
|
|
375
|
+
# name: channel-name
|
|
376
|
+
# purpose: What this channel is for
|
|
377
|
+
# monitor: true | false
|
|
378
|
+
# respond: true | false
|
|
379
|
+
`,
|
|
380
|
+
"tooling-map.yaml": `# Tooling Map
|
|
381
|
+
# Maps responsibilities to available tools and scripts
|
|
382
|
+
# Generated by: init-maestro sub-agent 8
|
|
383
|
+
|
|
384
|
+
tools: []
|
|
385
|
+
`,
|
|
386
|
+
"validation-rules.yaml": `# Outbound Correspondence Validation Rules
|
|
387
|
+
# Used by: scripts/validate-outbound.py
|
|
388
|
+
# Purpose: Pre-send gate to prevent factual inaccuracies and protocol violations
|
|
389
|
+
|
|
390
|
+
relationship_claims:
|
|
391
|
+
enabled: true
|
|
392
|
+
severity: block
|
|
393
|
+
patterns: []
|
|
394
|
+
|
|
395
|
+
ai_disclosure:
|
|
396
|
+
enabled: true
|
|
397
|
+
severity: block
|
|
398
|
+
blocked_phrases:
|
|
399
|
+
- "I am an AI"
|
|
400
|
+
- "as an AI"
|
|
401
|
+
- "I'm an artificial intelligence"
|
|
402
|
+
- "language model"
|
|
403
|
+
|
|
404
|
+
tone_violations:
|
|
405
|
+
enabled: true
|
|
406
|
+
severity: warn
|
|
407
|
+
rules: []
|
|
408
|
+
`,
|
|
409
|
+
"mcp-integrations.yaml": `# MCP Server Integration Configuration
|
|
410
|
+
# Which MCP services this agent connects to
|
|
411
|
+
# Updated by: init-maestro wizard
|
|
412
|
+
|
|
413
|
+
integrations:
|
|
414
|
+
slack: { enabled: false, notes: "Configure via .env" }
|
|
415
|
+
gmail: { enabled: false, notes: "Configure via .env" }
|
|
416
|
+
calendar: { enabled: false, notes: "Configure via .env" }
|
|
417
|
+
`,
|
|
418
|
+
"mcp-servers.json": `{}`,
|
|
419
|
+
"caller-id-map.yaml": `# Caller ID Map
|
|
420
|
+
# Maps phone numbers to known contacts for SMS/voice identification
|
|
421
|
+
# Updated by: agent interactions
|
|
422
|
+
|
|
423
|
+
contacts: {}
|
|
424
|
+
`,
|
|
425
|
+
"hiring.yaml": `# Hiring Configuration
|
|
426
|
+
# Pipeline settings, screening rules, and template references
|
|
427
|
+
# Updated by: init-maestro wizard (for executive-operator / operations-leader archetypes)
|
|
428
|
+
|
|
429
|
+
enabled: false
|
|
430
|
+
roles: []
|
|
431
|
+
screening:
|
|
432
|
+
auto_advance_threshold: 75
|
|
433
|
+
auto_reject_threshold: 40
|
|
434
|
+
review_band: [40, 75]
|
|
435
|
+
`,
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
for (const [filename, content] of Object.entries(configTemplates)) {
|
|
439
|
+
const dest = join(targetDir, `config/${filename}`);
|
|
440
|
+
if (!existsSync(dest)) {
|
|
441
|
+
writeFileSync(dest, content);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
ok(`${Object.keys(configTemplates).length} config templates`);
|
|
445
|
+
|
|
446
|
+
// Knowledge templates — schemas and empty indexes
|
|
447
|
+
log("Generating knowledge templates...");
|
|
448
|
+
|
|
449
|
+
const knowledgeTemplates = {
|
|
450
|
+
"decisions/decision-schema.yaml": `# Decision Record Schema
|
|
451
|
+
# Format: DEC-YYYY-MM-DD-NNN
|
|
452
|
+
# See docs for full schema documentation
|
|
453
|
+
|
|
454
|
+
schema:
|
|
455
|
+
version: "1.0"
|
|
456
|
+
fields:
|
|
457
|
+
id: { type: string, format: "DEC-YYYY-MM-DD-NNN", required: true }
|
|
458
|
+
date: { type: date, format: "YYYY-MM-DD", required: true }
|
|
459
|
+
title: { type: string, required: true }
|
|
460
|
+
domain: { type: string, required: true }
|
|
461
|
+
decision_maker: { type: string, required: true }
|
|
462
|
+
decision_text: { type: string, required: true }
|
|
463
|
+
context: { type: string, required: true }
|
|
464
|
+
rationale: { type: string, required: true }
|
|
465
|
+
status: { type: string, enum: [active, superseded, reversed, completed], default: active }
|
|
466
|
+
`,
|
|
467
|
+
"decisions/index.yaml": `# Decision Index
|
|
468
|
+
# Auto-maintained by decision-log agent
|
|
469
|
+
|
|
470
|
+
decisions: []
|
|
471
|
+
`,
|
|
472
|
+
"entities/entity-map.yaml": `# Entity Map
|
|
473
|
+
# All contacts, companies, regulators, advisors
|
|
474
|
+
# De-duplication rules and relationship mapping
|
|
475
|
+
|
|
476
|
+
entities: []
|
|
477
|
+
`,
|
|
478
|
+
"entities/org-chart.md": `# Organisation Chart
|
|
479
|
+
|
|
480
|
+
*Configure via /init-maestro*
|
|
481
|
+
`,
|
|
482
|
+
"sources/source-registry.yaml": `# Authoritative Source Registry
|
|
483
|
+
# Central registry of all information sources
|
|
484
|
+
|
|
485
|
+
sources: {}
|
|
486
|
+
`,
|
|
487
|
+
"sources/blocker-playbooks.yaml": `# Blocker Resolution Playbooks
|
|
488
|
+
# Common blocker patterns and resolution strategies
|
|
489
|
+
|
|
490
|
+
playbooks: []
|
|
491
|
+
`,
|
|
492
|
+
"syntheses/strategy-state.yaml": `# Living Strategy State
|
|
493
|
+
# Evolves weekly with strategic position, assumptions, risks, signals
|
|
494
|
+
|
|
495
|
+
last_updated: null
|
|
496
|
+
strategic_position: ""
|
|
497
|
+
key_assumptions: []
|
|
498
|
+
active_risks: []
|
|
499
|
+
market_signals: []
|
|
500
|
+
`,
|
|
501
|
+
"syntheses/README.md": `# Knowledge Syntheses
|
|
502
|
+
|
|
503
|
+
Strategic syntheses generated by domain agents. Updated weekly.
|
|
504
|
+
`,
|
|
505
|
+
"memory/executive-memory.yaml": `# Executive Memory
|
|
506
|
+
# Institutional memory for strategic context
|
|
507
|
+
|
|
508
|
+
entries: []
|
|
509
|
+
`,
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
for (const [path, content] of Object.entries(knowledgeTemplates)) {
|
|
513
|
+
writeFileSync(join(targetDir, `knowledge/${path}`), content);
|
|
514
|
+
}
|
|
515
|
+
ok(`${Object.keys(knowledgeTemplates).length} knowledge templates`);
|
|
516
|
+
|
|
517
|
+
// Self-optimization templates
|
|
518
|
+
const selfOptTemplates = {
|
|
519
|
+
"program.md": `# Self-Optimization Program
|
|
520
|
+
|
|
521
|
+
This agent evolves its own operating setup through structured experimentation.
|
|
522
|
+
Changes are classified by risk: low (auto-apply), medium (apply + notify), high (escalate).
|
|
523
|
+
`,
|
|
524
|
+
"experiment-log.yaml": `# Experiment Log
|
|
525
|
+
experiments: []
|
|
526
|
+
`,
|
|
527
|
+
"failure-patterns.yaml": `# Failure Patterns
|
|
528
|
+
# Recurring failure modes and mitigations
|
|
529
|
+
patterns: []
|
|
530
|
+
`,
|
|
531
|
+
"metric-snapshots.yaml": `# Metric Snapshots
|
|
532
|
+
# Periodic captures of operational metrics
|
|
533
|
+
snapshots: []
|
|
534
|
+
`,
|
|
535
|
+
"scoring-rubrics.yaml": `# Scoring Rubrics
|
|
536
|
+
# Evaluation criteria for self-assessment
|
|
537
|
+
rubrics: []
|
|
538
|
+
`,
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
for (const [filename, content] of Object.entries(selfOptTemplates)) {
|
|
542
|
+
writeFileSync(join(targetDir, `self-optimization/${filename}`), content);
|
|
543
|
+
}
|
|
544
|
+
ok(`${Object.keys(selfOptTemplates).length} self-optimization templates`);
|
|
545
|
+
|
|
546
|
+
// .gitkeep files for empty directories that git would otherwise ignore
|
|
547
|
+
const gitkeepDirs = [
|
|
548
|
+
"state/handoffs", "state/huddle", "state/indexes", "state/rag",
|
|
549
|
+
"state/sessions", "state/slack-responded", "state/slack-thread-tracker",
|
|
550
|
+
"state/tmp", "state/inbox/attachments", "state/inbox/processed",
|
|
551
|
+
"state/inbox/whatsapp", "memory/precedents/market-signals",
|
|
552
|
+
"knowledge/decisions/archive", "tests",
|
|
553
|
+
"logs/infra", "logs/monitor", "logs/phone", "logs/sms",
|
|
554
|
+
"logs/whatsapp", "logs/email", "self-optimization/scenarios",
|
|
555
|
+
];
|
|
556
|
+
|
|
557
|
+
for (const dir of gitkeepDirs) {
|
|
558
|
+
const keepFile = join(targetDir, dir, ".gitkeep");
|
|
559
|
+
if (!existsSync(keepFile)) {
|
|
560
|
+
writeFileSync(keepFile, "");
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
ok(".gitkeep files for empty directories");
|
|
564
|
+
|
|
158
565
|
// ── Step 4: Generate package.json ───────────────────────────────────────
|
|
159
566
|
|
|
160
567
|
log("Generating package.json...");
|
|
@@ -247,9 +654,10 @@ function create(targetName) {
|
|
|
247
654
|
console.log("║ ║");
|
|
248
655
|
console.log("║ Next steps: ║");
|
|
249
656
|
console.log(`║ 1. cd ${targetName.padEnd(51)}║`);
|
|
250
|
-
console.log(
|
|
251
|
-
console.log("║
|
|
252
|
-
console.log(
|
|
657
|
+
console.log('║ 2. claude "/init-maestro" ║');
|
|
658
|
+
console.log("║ ║");
|
|
659
|
+
console.log("║ The wizard handles everything: system setup, identity, ║");
|
|
660
|
+
console.log("║ service configuration, launchd, and verification. ║");
|
|
253
661
|
console.log("║ ║");
|
|
254
662
|
console.log("╚══════════════════════════════════════════════════════════════╝");
|
|
255
663
|
console.log();
|
|
@@ -269,7 +677,11 @@ function upgrade() {
|
|
|
269
677
|
|
|
270
678
|
log("Upgrading framework files from @adaptic/maestro...");
|
|
271
679
|
|
|
272
|
-
|
|
680
|
+
// Framework directories that get overwritten on upgrade
|
|
681
|
+
const frameworkDirs = [
|
|
682
|
+
"scripts", "policies", "docs", "public/assets",
|
|
683
|
+
"workflows", "schedules", "desktop-control", "ingest", "mcp",
|
|
684
|
+
];
|
|
273
685
|
|
|
274
686
|
let updated = 0;
|
|
275
687
|
for (const dir of frameworkDirs) {
|
|
@@ -281,6 +693,7 @@ function upgrade() {
|
|
|
281
693
|
}
|
|
282
694
|
}
|
|
283
695
|
|
|
696
|
+
// .claude/commands (NOT settings.json — that's agent-specific)
|
|
284
697
|
const commandsSrc = join(MAESTRO_ROOT, ".claude", "commands");
|
|
285
698
|
if (existsSync(commandsSrc)) {
|
|
286
699
|
cpSync(commandsSrc, join(cwd, ".claude", "commands"), { recursive: true, force: true });
|
|
@@ -288,6 +701,7 @@ function upgrade() {
|
|
|
288
701
|
updated++;
|
|
289
702
|
}
|
|
290
703
|
|
|
704
|
+
// Plugins
|
|
291
705
|
const pluginSrc = join(MAESTRO_ROOT, "plugins", "maestro-skills");
|
|
292
706
|
if (existsSync(pluginSrc)) {
|
|
293
707
|
cpSync(pluginSrc, join(cwd, "plugins", "maestro-skills"), { recursive: true, force: true });
|
|
@@ -295,6 +709,42 @@ function upgrade() {
|
|
|
295
709
|
updated++;
|
|
296
710
|
}
|
|
297
711
|
|
|
712
|
+
// Agent definitions (merge: add new agents, update existing, don't delete custom ones)
|
|
713
|
+
const agentsSrc = join(MAESTRO_ROOT, "agents");
|
|
714
|
+
if (existsSync(agentsSrc)) {
|
|
715
|
+
cpSync(agentsSrc, join(cwd, "agents"), { recursive: true, force: false });
|
|
716
|
+
ok("agents (merged, custom agents preserved)");
|
|
717
|
+
updated++;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// Teams
|
|
721
|
+
const teamsSrc = join(MAESTRO_ROOT, "teams");
|
|
722
|
+
if (existsSync(teamsSrc)) {
|
|
723
|
+
cpSync(teamsSrc, join(cwd, "teams"), { recursive: true, force: true });
|
|
724
|
+
ok("teams");
|
|
725
|
+
updated++;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// Create any missing directories from the expanded list
|
|
729
|
+
const ensureDirs = [
|
|
730
|
+
"state/handoffs", "state/huddle", "state/indexes", "state/rag",
|
|
731
|
+
"state/sessions", "state/slack-responded", "state/slack-thread-tracker",
|
|
732
|
+
"state/tmp", "state/inbox/whatsapp", "state/inbox/attachments",
|
|
733
|
+
"state/inbox/processed", "memory/precedents/market-signals",
|
|
734
|
+
"knowledge/decisions/archive", "self-optimization/scenarios", "tests",
|
|
735
|
+
"logs/infra", "logs/monitor", "logs/phone", "logs/sms",
|
|
736
|
+
"logs/whatsapp", "logs/email",
|
|
737
|
+
];
|
|
738
|
+
let newDirs = 0;
|
|
739
|
+
for (const dir of ensureDirs) {
|
|
740
|
+
const dirPath = join(cwd, dir);
|
|
741
|
+
if (!existsSync(dirPath)) {
|
|
742
|
+
mkdirSync(dirPath, { recursive: true });
|
|
743
|
+
newDirs++;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
if (newDirs > 0) ok(`Created ${newDirs} new directories`);
|
|
747
|
+
|
|
298
748
|
console.log();
|
|
299
749
|
ok(`Upgraded ${updated} framework components.`);
|
|
300
750
|
log("Agent-specific files (config/, CLAUDE.md, knowledge/, memory/) were NOT modified.");
|
|
@@ -316,6 +766,13 @@ function doctor() {
|
|
|
316
766
|
"config/agent.ts", "CLAUDE.md", ".claude/settings.json",
|
|
317
767
|
".claude/commands/init-maestro.md", "package.json",
|
|
318
768
|
"scripts/setup/init-agent.sh", "scripts/healthcheck.sh",
|
|
769
|
+
"config/environment.yaml", "config/contacts.yaml",
|
|
770
|
+
"config/priorities.yaml", "config/sla-defaults.yaml",
|
|
771
|
+
"scripts/daemon/maestro-daemon.mjs",
|
|
772
|
+
"scripts/local-triggers/generate-plists.sh",
|
|
773
|
+
"state/dashboards/executive-summary.yaml",
|
|
774
|
+
"state/queues/action-stack.yaml",
|
|
775
|
+
"knowledge/decisions/decision-schema.yaml",
|
|
319
776
|
];
|
|
320
777
|
|
|
321
778
|
for (const file of essentialFiles) {
|
|
@@ -377,9 +834,7 @@ Usage:
|
|
|
377
834
|
Workflow:
|
|
378
835
|
1. npx @adaptic/maestro create my-agent
|
|
379
836
|
2. cd my-agent
|
|
380
|
-
3.
|
|
381
|
-
4. npm run init-agent
|
|
382
|
-
5. claude "/init-maestro"
|
|
837
|
+
3. claude "/init-maestro"
|
|
383
838
|
`);
|
|
384
839
|
break;
|
|
385
840
|
default:
|