@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/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("║ 2. sudo npm run configure-macos ");
251
- console.log("║ 3. npm run init-agent ║");
252
- console.log('4. claude "/init-maestro" ║');
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
- const frameworkDirs = ["scripts", "policies", "docs", "public/assets"];
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. sudo npm run configure-macos
381
- 4. npm run init-agent
382
- 5. claude "/init-maestro"
837
+ 3. claude "/init-maestro"
383
838
  `);
384
839
  break;
385
840
  default: