@adaptic/maestro 1.8.1 → 1.8.3
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 +15 -3
- package/package.json +1 -1
- package/plugins/maestro-skills/skills/board-deck.md +2 -2
- package/plugins/maestro-skills/skills/decision-brief.md +6 -6
- package/plugins/maestro-skills/skills/draft-comms.md +9 -9
- package/plugins/maestro-skills/skills/evening-wrap.md +2 -2
- package/plugins/maestro-skills/skills/hiring-triage.md +4 -4
- package/plugins/maestro-skills/skills/inbox-triage.md +5 -5
- package/plugins/maestro-skills/skills/morning-brief.md +4 -4
- package/plugins/maestro-skills/skills/pipeline-review.md +2 -2
- package/plugins/maestro-skills/skills/regulatory-status.md +2 -2
- package/plugins/maestro-skills/skills/schedule-meeting.md +3 -3
- package/plugins/maestro-skills/skills/slack-followup.md +5 -5
- package/plugins/maestro-skills/skills/weekly-memo.md +5 -5
- package/scaffold/CLAUDE.md +21 -0
- package/scripts/daemon/classifier.mjs +21 -5
- package/scripts/daemon/maestro-daemon.mjs +46 -7
- package/scripts/hooks/block-mcp-slack-send.sh +1 -1
- package/scripts/huddle/audio-bridge.mjs +17 -17
- package/scripts/huddle/boot-slack-cdp.sh +1 -1
- package/scripts/huddle/huddle-controller.mjs +3 -3
- package/scripts/huddle/huddle-server.mjs +21 -7
- package/scripts/huddle/launch-slack.sh +2 -2
- package/scripts/huddle/package-lock.json +2 -2
- package/scripts/huddle/package.json +2 -2
- package/scripts/huddle/setup-audio.sh +6 -6
- package/scripts/huddle/start-call.mjs +2 -2
- package/scripts/huddle/test-pipeline.mjs +2 -2
- package/scripts/local-triggers/generate-plists.sh +15 -1
- package/scripts/local-triggers/generate-plists.test.mjs +9 -2
- package/scripts/parse-voice-transcript.mjs +4 -9
- package/scripts/poller/gmail-poller.mjs +8 -2
- package/scripts/poller/intra-session-check.mjs +4 -3
- package/scripts/poller-launchd/install.sh +48 -10
- package/scripts/pre_draft_lookup.py +2 -2
- package/scripts/self-optimization/compute-metrics.py +23 -2
- package/scripts/setup/boot-claude-session.sh +14 -5
- package/scripts/setup/render-environment-yaml.mjs +133 -0
- package/scripts/watchdog/ai.maestro.memory-watchdog.plist +3 -3
- package/scripts/watchdog/force-reboot.sh +3 -3
- package/scripts/watchdog/memory-watchdog.sh +11 -5
- package/workflows/daily/applicant-triage.yaml +3 -3
- package/workflows/daily/comms-triage.yaml +1 -1
- package/workflows/daily/morning-brief.yaml +1 -1
- package/workflows/daily/slack-followup-sweep.yaml +1 -1
- package/workflows/weekly/hiring-review.yaml +3 -3
package/bin/maestro.mjs
CHANGED
|
@@ -1229,11 +1229,11 @@ Per-file behaviour:
|
|
|
1229
1229
|
// them so launchd enqueues cadence events instead of spawning Claude.
|
|
1230
1230
|
const cadenceMigration = migrateCadenceBus(cwd, flags);
|
|
1231
1231
|
|
|
1232
|
-
// Regenerate config
|
|
1233
|
-
//
|
|
1234
|
-
// Soft failure — older agents that haven't migrated to the SOT layout
|
|
1232
|
+
// Regenerate derived config from config/agent.json (the SOT).
|
|
1233
|
+
// Soft failures — older agents that haven't migrated to the SOT layout
|
|
1235
1234
|
// yet don't have agent.json and that's fine.
|
|
1236
1235
|
if (!flags.dryRun && existsSync(join(cwd, "config", "agent.json"))) {
|
|
1236
|
+
// config/agent.env — env-var file consumed by shell scripts.
|
|
1237
1237
|
try {
|
|
1238
1238
|
execFileSync(
|
|
1239
1239
|
"node",
|
|
@@ -1244,6 +1244,18 @@ Per-file behaviour:
|
|
|
1244
1244
|
} catch (e) {
|
|
1245
1245
|
warn(`could not regenerate config/agent.env: ${e.message}`);
|
|
1246
1246
|
}
|
|
1247
|
+
// config/environment.yaml — operational config consumed by workflows.
|
|
1248
|
+
// Replaces the previously-static hardcoded identity fields.
|
|
1249
|
+
try {
|
|
1250
|
+
execFileSync(
|
|
1251
|
+
"node",
|
|
1252
|
+
[join(MAESTRO_ROOT, "scripts/setup/render-environment-yaml.mjs")],
|
|
1253
|
+
{ cwd, env: { ...process.env, AGENT_DIR: cwd }, stdio: "pipe" }
|
|
1254
|
+
);
|
|
1255
|
+
ok("regenerated config/environment.yaml");
|
|
1256
|
+
} catch (e) {
|
|
1257
|
+
warn(`could not regenerate config/environment.yaml: ${e.message}`);
|
|
1258
|
+
}
|
|
1247
1259
|
}
|
|
1248
1260
|
|
|
1249
1261
|
// Summary
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ description: Prepare board deck materials using Gamma for presentations and Merm
|
|
|
5
5
|
|
|
6
6
|
# Board Deck Preparation
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Assemble and prepare board deck materials.
|
|
9
9
|
|
|
10
10
|
## Data Sources
|
|
11
11
|
|
|
@@ -49,7 +49,7 @@ Save Mermaid diagrams to `outputs/board/diagrams/`.
|
|
|
49
49
|
## Presentation Assembly
|
|
50
50
|
|
|
51
51
|
1. Write each slide's content as a structured markdown section in `outputs/board/board-deck-YYYY-MM-DD.md`.
|
|
52
|
-
2. Include speaker notes for
|
|
52
|
+
2. Include speaker notes for {{agent.principal.firstName}} under each slide.
|
|
53
53
|
3. If Gamma MCP or API is available, generate the presentation directly. Otherwise, prepare content ready for manual Gamma import.
|
|
54
54
|
4. Flag any data gaps — sections where the data is stale or missing.
|
|
55
55
|
|
|
@@ -5,7 +5,7 @@ description: Present a decision to the CEO with options, pros/cons, and a recomm
|
|
|
5
5
|
|
|
6
6
|
# Decision Brief
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Present a structured decision for {{agent.principal.firstName}} to make.
|
|
9
9
|
|
|
10
10
|
## Required Inputs
|
|
11
11
|
|
|
@@ -29,8 +29,8 @@ When invoked, gather from the user (or infer from context):
|
|
|
29
29
|
```
|
|
30
30
|
# Decision Brief: [Short Title]
|
|
31
31
|
**Date**: [DATE]
|
|
32
|
-
**Decision Owner**:
|
|
33
|
-
**Prepared by**:
|
|
32
|
+
**Decision Owner**: {{agent.principal.firstName}}
|
|
33
|
+
**Prepared by**: {{agent.fullName}}
|
|
34
34
|
**Urgency**: [Decide today / This week / Can wait]
|
|
35
35
|
|
|
36
36
|
## Context
|
|
@@ -64,7 +64,7 @@ When invoked, gather from the user (or infer from context):
|
|
|
64
64
|
| Risk | [H/M/L] | [H/M/L] | [H/M/L] |
|
|
65
65
|
| Reversibility | [H/M/L] | [H/M/L] | [H/M/L] |
|
|
66
66
|
|
|
67
|
-
##
|
|
67
|
+
## {{agent.firstName}}'s Recommendation
|
|
68
68
|
**I recommend Option [X]** because [2-3 sentence rationale connecting to strategic priorities and current constraints].
|
|
69
69
|
|
|
70
70
|
**Key risk to mitigate**: [The biggest risk of this option and how to address it]
|
|
@@ -79,11 +79,11 @@ When invoked, gather from the user (or infer from context):
|
|
|
79
79
|
|
|
80
80
|
1. Save to `outputs/decisions/decision-brief-[topic]-YYYY-MM-DD.md`.
|
|
81
81
|
2. Log the decision (once made) to `memory/executive/decisions.md` with date, choice, and rationale.
|
|
82
|
-
3. Present the brief in conversation and await
|
|
82
|
+
3. Present the brief in conversation and await {{agent.principal.firstName}}'s decision.
|
|
83
83
|
|
|
84
84
|
## Principles
|
|
85
85
|
|
|
86
86
|
- Always present at least 2 options (including "do nothing" if applicable).
|
|
87
87
|
- Be honest about tradeoffs — don't stack the deck for your recommendation.
|
|
88
|
-
- Make the recommendation clear and confident, but respect that the decision is
|
|
88
|
+
- Make the recommendation clear and confident, but respect that the decision is {{agent.principal.firstName}}'s.
|
|
89
89
|
- Flag if this decision is reversible vs. one-way door.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: draft-comms
|
|
3
|
-
description: "Draft a communication in the appropriate voice (
|
|
3
|
+
description: "Draft a communication in the appropriate voice (agent, principal draft, or institutional). Takes: recipient, channel, purpose, key points. Applies communication governance rules. Never sends without approval for external recipients."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Draft Communications
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Draft communications in the correct voice for the given context.
|
|
9
9
|
|
|
10
10
|
## Required Inputs
|
|
11
11
|
|
|
@@ -15,24 +15,24 @@ When invoked, gather from the user (or infer from context):
|
|
|
15
15
|
- **Channel**: Email, Slack, WhatsApp, formal letter, etc.
|
|
16
16
|
- **Purpose**: What is this communication trying to achieve?
|
|
17
17
|
- **Key points**: What must be included?
|
|
18
|
-
- **Voice**:
|
|
18
|
+
- **Voice**: Agent voice (default for internal ops), Principal draft (for principal-signed comms), or Institutional (for company-level comms)
|
|
19
19
|
|
|
20
20
|
## Voice Guidelines
|
|
21
21
|
|
|
22
22
|
Read `config/communication-governance.md` for full rules. Summary:
|
|
23
23
|
|
|
24
|
-
###
|
|
24
|
+
### Agent Voice (Internal Operations)
|
|
25
25
|
|
|
26
26
|
- Professional, warm, efficient
|
|
27
27
|
- "Hi [Name], following up on..." / "Quick update on..."
|
|
28
28
|
- Used for: scheduling, internal coordination, vendor management, routine follow-ups
|
|
29
29
|
|
|
30
|
-
###
|
|
30
|
+
### Principal Draft (CEO Communications)
|
|
31
31
|
|
|
32
32
|
- Authoritative but approachable
|
|
33
33
|
- Strategic framing, concise
|
|
34
34
|
- Used for: investor updates, partner outreach, board communications, key hire outreach
|
|
35
|
-
- **Always marked as DRAFT — requires
|
|
35
|
+
- **Always marked as DRAFT — requires {{agent.principal.firstName}}'s review and explicit send approval**
|
|
36
36
|
|
|
37
37
|
### Institutional Voice (Company Communications)
|
|
38
38
|
|
|
@@ -44,7 +44,7 @@ Read `config/communication-governance.md` for full rules. Summary:
|
|
|
44
44
|
|
|
45
45
|
1. **External communications** — NEVER send without explicit CEO approval. Present draft and wait.
|
|
46
46
|
2. **Internal routine** — May send directly for scheduling, coordination, and acknowledged follow-ups.
|
|
47
|
-
3. **Investor/Board** — Always
|
|
47
|
+
3. **Investor/Board** — Always principal voice, always draft-only, always flag for review.
|
|
48
48
|
4. **Legal/Regulatory** — Flag for legal review before sending. Note any compliance implications.
|
|
49
49
|
5. **Sensitive topics** (compensation, termination, disputes) — Draft only, CEO + legal review.
|
|
50
50
|
|
|
@@ -63,7 +63,7 @@ Read `config/communication-governance.md` for full rules. Summary:
|
|
|
63
63
|
|
|
64
64
|
**To**: [Recipient]
|
|
65
65
|
**Channel**: [Email/Slack/etc.]
|
|
66
|
-
**Voice**: [
|
|
66
|
+
**Voice**: [Agent/Principal Draft/Institutional]
|
|
67
67
|
**Governance**: [Can send / Needs CEO approval / Needs legal review]
|
|
68
68
|
|
|
69
69
|
---
|
|
@@ -74,7 +74,7 @@ Read `config/communication-governance.md` for full rules. Summary:
|
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
77
|
-
**
|
|
77
|
+
**{{agent.firstName}}'s Notes**: [Any context, suggested timing, or caveats]
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
## Output
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: evening-wrap
|
|
3
|
-
description: Produce the Evening Wrap — what closed today, what didn't, open items carried forward, tomorrow's priorities. Use at end of day or when
|
|
3
|
+
description: Produce the Evening Wrap — what closed today, what didn't, open items carried forward, tomorrow's priorities. Use at end of day or when the principal asks for the wrap.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Evening Wrap
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Produce the end-of-day Evening Wrap for {{agent.principal.firstName}}.
|
|
9
9
|
|
|
10
10
|
## Data Gathering
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@ description: Review new job applications, AI screen candidates, draft advancemen
|
|
|
5
5
|
|
|
6
6
|
# Hiring Triage
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Process job applications and manage the hiring pipeline.
|
|
9
9
|
|
|
10
10
|
## Data Sources
|
|
11
11
|
|
|
@@ -28,7 +28,7 @@ For each new application:
|
|
|
28
28
|
|
|
29
29
|
4. **Draft communications**:
|
|
30
30
|
- Advance: Draft scheduling email for next interview round
|
|
31
|
-
- Maybe: Draft summary memo for
|
|
31
|
+
- Maybe: Draft summary memo for {{agent.principal.firstName}} with pros/cons
|
|
32
32
|
- Reject: Draft polite, personalized rejection email
|
|
33
33
|
|
|
34
34
|
## Output Format
|
|
@@ -44,7 +44,7 @@ For each new application:
|
|
|
44
44
|
| [Name] | [Role] | [X/10] | [brief] | [action] |
|
|
45
45
|
|
|
46
46
|
### CEO Review ([count])
|
|
47
|
-
| Candidate | Role | Score | Question for
|
|
47
|
+
| Candidate | Role | Score | Question for {{agent.principal.firstName}} |
|
|
48
48
|
|---|---|---|---|
|
|
49
49
|
| [Name] | [Role] | [X/10] | [what needs deciding] |
|
|
50
50
|
|
|
@@ -69,6 +69,6 @@ For each new application:
|
|
|
69
69
|
|
|
70
70
|
## Rules
|
|
71
71
|
|
|
72
|
-
- Never auto-send rejection emails without
|
|
72
|
+
- Never auto-send rejection emails without {{agent.principal.firstName}}'s batch approval.
|
|
73
73
|
- Flag any candidate referred by a known contact as P1 regardless of score.
|
|
74
74
|
- Preserve all original application materials — never delete inputs.
|
|
@@ -5,7 +5,7 @@ description: Triage all inbound communications across Slack, Gmail, and WhatsApp
|
|
|
5
5
|
|
|
6
6
|
# Inbox Triage
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Triage all inbound communications and surface what matters.
|
|
9
9
|
|
|
10
10
|
## Data Sources
|
|
11
11
|
|
|
@@ -20,14 +20,14 @@ Classify every inbound item into one of four categories:
|
|
|
20
20
|
|
|
21
21
|
| Category | Criteria | Action |
|
|
22
22
|
| ----------------------- | ------------------------------------------------------- | ---------------------------------------------------------- |
|
|
23
|
-
| **P0 — CEO Now** | Time-sensitive, high-stakes, requires
|
|
23
|
+
| **P0 — CEO Now** | Time-sensitive, high-stakes, requires {{agent.principal.firstName}} personally | Flag immediately, draft context summary |
|
|
24
24
|
| **P1 — CEO Today** | Important but not urgent, needs CEO input within 24h | Queue with draft response for review |
|
|
25
|
-
| **P2 —
|
|
25
|
+
| **P2 — Agent Handles** | Routine coordination, scheduling, follow-ups | Draft and send (internal) or draft for approval (external) |
|
|
26
26
|
| **P3 — Archive** | FYI, newsletters, low-priority notifications | Log and archive, no action needed |
|
|
27
27
|
|
|
28
28
|
## Processing Rules
|
|
29
29
|
|
|
30
|
-
- **Never send external communications** without
|
|
30
|
+
- **Never send external communications** without {{agent.principal.firstName}}'s explicit approval.
|
|
31
31
|
- **Internal routine** (scheduling, coordination with known team) can be handled directly.
|
|
32
32
|
- **Unknown senders** — research context before classifying. Check LinkedIn, company records, prior correspondence.
|
|
33
33
|
- **Investor communications** are always P0 or P1.
|
|
@@ -44,7 +44,7 @@ Classify every inbound item into one of four categories:
|
|
|
44
44
|
## P1 — Needs You Today ([count])
|
|
45
45
|
- **[Sender]** via [channel]: [subject/summary] — [draft response attached]
|
|
46
46
|
|
|
47
|
-
## P2 —
|
|
47
|
+
## P2 — Agent Handling ([count])
|
|
48
48
|
- **[Sender]** via [channel]: [action taken or planned]
|
|
49
49
|
|
|
50
50
|
## P3 — Archived ([count])
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: morning-brief
|
|
3
|
-
description: Produce the CEO Morning Brief — priorities, overnight developments, open loops, workstream pulse. Use when
|
|
3
|
+
description: Produce the CEO Morning Brief — priorities, overnight developments, open loops, workstream pulse. Use when the principal asks for his brief or at scheduled time.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# CEO Morning Brief
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Produce the daily CEO Morning Brief for {{agent.principal.firstName}}.
|
|
9
9
|
|
|
10
10
|
## Data Gathering
|
|
11
11
|
|
|
@@ -39,7 +39,7 @@ Produce the brief in this exact format:
|
|
|
39
39
|
## Today's Calendar
|
|
40
40
|
- [Time] — [Meeting/commitment]
|
|
41
41
|
|
|
42
|
-
##
|
|
42
|
+
## {{agent.firstName}}'s Recommendation
|
|
43
43
|
[One paragraph: what to focus on, what to delegate, what to defer]
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -51,4 +51,4 @@ Produce the brief in this exact format:
|
|
|
51
51
|
|
|
52
52
|
## Tone
|
|
53
53
|
|
|
54
|
-
Crisp, direct, no filler. Lead with what matters. Flag risks early.
|
|
54
|
+
Crisp, direct, no filler. Lead with what matters. Flag risks early. {{agent.principal.firstName}} reads this in 2 minutes — make every line count.
|
|
@@ -5,7 +5,7 @@ description: Review the rollup acquisition pipeline — target status, due dilig
|
|
|
5
5
|
|
|
6
6
|
# Acquisition Pipeline Review
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Produce a comprehensive review of the rollup acquisition pipeline.
|
|
9
9
|
|
|
10
10
|
## Data Sources
|
|
11
11
|
|
|
@@ -65,7 +65,7 @@ You are Sophie Nguyen, Chief of Staff AI. Produce a comprehensive review of the
|
|
|
65
65
|
## Regulatory Dependencies
|
|
66
66
|
- [Any regulatory milestones that gate acquisitions]
|
|
67
67
|
|
|
68
|
-
##
|
|
68
|
+
## {{agent.firstName}}'s Assessment
|
|
69
69
|
[Overall pipeline health, velocity concerns, recommendations for acceleration or pruning]
|
|
70
70
|
```
|
|
71
71
|
|
|
@@ -5,7 +5,7 @@ description: Check regulatory status across all 7 jurisdictions — DFSA gap pro
|
|
|
5
5
|
|
|
6
6
|
# Regulatory Status Check
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Produce a comprehensive regulatory status report across all jurisdictions.
|
|
9
9
|
|
|
10
10
|
## Data Sources
|
|
11
11
|
|
|
@@ -69,7 +69,7 @@ Track status across all 7 jurisdictions:
|
|
|
69
69
|
## Regulatory Risks
|
|
70
70
|
- [Identified risks with likelihood and impact assessment]
|
|
71
71
|
|
|
72
|
-
##
|
|
72
|
+
## {{agent.firstName}}'s Assessment
|
|
73
73
|
[Overall regulatory program health, velocity, and recommendations for acceleration]
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -5,7 +5,7 @@ description: Schedule a meeting using Google Calendar MCP or Calendly. Handle ti
|
|
|
5
5
|
|
|
6
6
|
# Schedule Meeting
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Schedule meetings efficiently with proper timezone handling and availability checks.
|
|
9
9
|
|
|
10
10
|
## Required Inputs
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ When invoked, gather from the user (or infer from context):
|
|
|
15
15
|
- **Purpose**: What is the meeting about? (used for title and agenda)
|
|
16
16
|
- **Duration**: How long? (default: 30 minutes)
|
|
17
17
|
- **Urgency**: When does this need to happen? (today, this week, flexible)
|
|
18
|
-
- **Preferred times**: Any constraints from
|
|
18
|
+
- **Preferred times**: Any constraints from {{agent.principal.firstName}} or participants?
|
|
19
19
|
|
|
20
20
|
## Process
|
|
21
21
|
|
|
@@ -26,7 +26,7 @@ When invoked, gather from the user (or infer from context):
|
|
|
26
26
|
|
|
27
27
|
### 2. Check Availability
|
|
28
28
|
|
|
29
|
-
- Use Google Calendar MCP (`mcp__google_calendar`) to check
|
|
29
|
+
- Use Google Calendar MCP (`mcp__google_calendar`) to check {{agent.principal.firstName}}'s calendar for open slots.
|
|
30
30
|
- If participant calendars are accessible, cross-reference availability.
|
|
31
31
|
- If not, propose 2-3 options for the organizer to share.
|
|
32
32
|
|
|
@@ -5,14 +5,14 @@ description: Check all pending Slack follow-ups — messages awaiting reply, com
|
|
|
5
5
|
|
|
6
6
|
# Slack Follow-Up Tracker
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Track and surface all pending Slack follow-ups.
|
|
9
9
|
|
|
10
10
|
## Data Sources
|
|
11
11
|
|
|
12
12
|
1. **Slack MCP** — Use `mcp__slack` to query channels and DMs for:
|
|
13
|
-
- Messages from
|
|
14
|
-
- Messages to
|
|
15
|
-
- Threads where
|
|
13
|
+
- Messages from {{agent.principal.firstName}} that received no reply
|
|
14
|
+
- Messages to {{agent.principal.firstName}} awaiting his reply
|
|
15
|
+
- Threads where the principal was mentioned but hasn't responded
|
|
16
16
|
- Commitments made in Slack ("I'll send that by...", "Let me follow up on...")
|
|
17
17
|
2. **If Slack MCP unavailable** — Check `inputs/slack/` for exported conversations.
|
|
18
18
|
3. **Follow-up log** — Read `memory/comms/slack-followups.md` for previously tracked items.
|
|
@@ -49,7 +49,7 @@ You are Sophie Nguyen, Chief of Staff AI. Track and surface all pending Slack fo
|
|
|
49
49
|
- [#channel]: [topic] — last message [date], appears unresolved
|
|
50
50
|
|
|
51
51
|
## Recommended Actions
|
|
52
|
-
1. [Specific action
|
|
52
|
+
1. [Specific action {{agent.firstName}} recommends, e.g., "Nudge X about Y"]
|
|
53
53
|
2. [Draft nudge message if appropriate]
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: weekly-memo
|
|
3
|
-
description: Produce the Weekly Strategic Memo — synthesis of the week, workstream status, strategic implications, and recommendations. Use at end of week or when
|
|
3
|
+
description: Produce the Weekly Strategic Memo — synthesis of the week, workstream status, strategic implications, and recommendations. Use at end of week or when the principal requests the weekly review.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Weekly Strategic Memo
|
|
7
7
|
|
|
8
|
-
You are
|
|
8
|
+
You are {{agent.fullName}}, {{agent.title}}. Produce the Weekly Strategic Memo that synthesizes the entire week.
|
|
9
9
|
|
|
10
10
|
## Data Gathering
|
|
11
11
|
|
|
@@ -51,9 +51,9 @@ You are Sophie Nguyen, Chief of Staff AI. Produce the Weekly Strategic Memo that
|
|
|
51
51
|
- [Item with owner and expected resolution date]
|
|
52
52
|
|
|
53
53
|
## Strategic Observations
|
|
54
|
-
[1-2 paragraphs: patterns
|
|
54
|
+
[1-2 paragraphs: patterns {{agent.firstName}} notices, risks on the horizon, opportunities worth exploring, alignment with long-term strategy]
|
|
55
55
|
|
|
56
|
-
##
|
|
56
|
+
## {{agent.firstName}}'s Recommendations for Next Week
|
|
57
57
|
1. [Specific, actionable recommendation]
|
|
58
58
|
2. [Specific, actionable recommendation]
|
|
59
59
|
3. [Specific, actionable recommendation]
|
|
@@ -67,4 +67,4 @@ You are Sophie Nguyen, Chief of Staff AI. Produce the Weekly Strategic Memo that
|
|
|
67
67
|
|
|
68
68
|
## Tone
|
|
69
69
|
|
|
70
|
-
Strategic altitude. This is the one document where
|
|
70
|
+
Strategic altitude. This is the one document where {{agent.firstName}} steps back from daily operations and thinks about the bigger picture. Be candid about what's not working. Make recommendations that are bold but grounded.
|
package/scaffold/CLAUDE.md
CHANGED
|
@@ -12,6 +12,27 @@ claude "/init-maestro"
|
|
|
12
12
|
|
|
13
13
|
This will configure your name, role, responsibilities, communication style, and all operational parameters.
|
|
14
14
|
|
|
15
|
+
## Source of Truth & Identity Tokens
|
|
16
|
+
|
|
17
|
+
Your canonical identity lives in `config/agent.json`. Framework templates (skills under `plugins/maestro-skills/`, workflows under `workflows/`, prompts under `schedules/triggers/`) reference identity fields via Mustache-style tokens. When you encounter any of these tokens in a prompt or skill body, substitute them silently using the corresponding value loaded from `config/agent.json`:
|
|
18
|
+
|
|
19
|
+
| Token | Resolves to |
|
|
20
|
+
|--------------------------------------|----------------------------------------------|
|
|
21
|
+
| `{{agent.firstName}}` | Your first name |
|
|
22
|
+
| `{{agent.fullName}}` | Your full name |
|
|
23
|
+
| `{{agent.title}}` | Your title |
|
|
24
|
+
| `{{agent.email}}` | Your work email |
|
|
25
|
+
| `{{agent.phone}}` | Your phone (if set) |
|
|
26
|
+
| `{{agent.company}}` | The company |
|
|
27
|
+
| `{{agent.timezone}}` | Your IANA timezone |
|
|
28
|
+
| `{{agent.principal.firstName}}` | Your principal's first name |
|
|
29
|
+
| `{{agent.principal.fullName}}` | Your principal's full name |
|
|
30
|
+
| `{{agent.principal.title}}` | Your principal's title |
|
|
31
|
+
| `{{agent.principal.email}}` | Your principal's email |
|
|
32
|
+
| `{{agent.repoSlug}}` | Your agent repo slug (used in paths) |
|
|
33
|
+
|
|
34
|
+
Identity tokens are NEVER persisted in outbound communications — always resolve them before sending. Treat any token left un-substituted as a bug and surface it.
|
|
35
|
+
|
|
15
36
|
## Company Context
|
|
16
37
|
|
|
17
38
|
*Configure via /init-maestro*
|
|
@@ -37,7 +37,7 @@ dotenv.config({ path: resolve(__dirname, "../../.env") });
|
|
|
37
37
|
|
|
38
38
|
const AGENT_DIR = process.env.AGENT_DIR || process.env.AGENT_ROOT || resolve(__dirname, "../..");
|
|
39
39
|
|
|
40
|
-
let _agentIdentity = null; // { name, slackId, role, fullName,
|
|
40
|
+
let _agentIdentity = null; // { name, slackId, role, fullName, principal: {…} }
|
|
41
41
|
let _peerAgents = []; // [{ name, slackId, role }] — all agents EXCEPT me
|
|
42
42
|
|
|
43
43
|
function loadAgentRegistry() {
|
|
@@ -52,6 +52,13 @@ function loadAgentRegistry() {
|
|
|
52
52
|
slackId: me.slackMemberId || "",
|
|
53
53
|
role: me.title || "agent",
|
|
54
54
|
repo: me.repoSlug,
|
|
55
|
+
principal: me.principal
|
|
56
|
+
? {
|
|
57
|
+
firstName: me.principal.firstName || "the principal",
|
|
58
|
+
fullName: me.principal.fullName || me.principal.firstName || "the principal",
|
|
59
|
+
title: me.principal.title || "principal",
|
|
60
|
+
}
|
|
61
|
+
: { firstName: "the principal", fullName: "the principal", title: "principal" },
|
|
55
62
|
};
|
|
56
63
|
} catch {
|
|
57
64
|
// Backwards compatibility for repos that haven't migrated yet.
|
|
@@ -63,9 +70,15 @@ function loadAgentRegistry() {
|
|
|
63
70
|
name: nameMatch ? nameMatch[1] : "Agent",
|
|
64
71
|
slackId: slackMatch ? slackMatch[1] : "",
|
|
65
72
|
role: "agent",
|
|
73
|
+
principal: { firstName: "the principal", fullName: "the principal", title: "principal" },
|
|
66
74
|
};
|
|
67
75
|
} catch {
|
|
68
|
-
_agentIdentity = {
|
|
76
|
+
_agentIdentity = {
|
|
77
|
+
name: "Agent",
|
|
78
|
+
slackId: "",
|
|
79
|
+
role: "agent",
|
|
80
|
+
principal: { firstName: "the principal", fullName: "the principal", title: "principal" },
|
|
81
|
+
};
|
|
69
82
|
}
|
|
70
83
|
}
|
|
71
84
|
|
|
@@ -99,13 +112,16 @@ function buildSystemPrompt() {
|
|
|
99
112
|
loadAgentRegistry();
|
|
100
113
|
const agentName = _agentIdentity.name;
|
|
101
114
|
const agentRole = _agentIdentity.role || "agent";
|
|
115
|
+
const principalName = _agentIdentity.principal.firstName;
|
|
116
|
+
const principalFullName = _agentIdentity.principal.fullName;
|
|
117
|
+
const principalTitle = _agentIdentity.principal.title;
|
|
102
118
|
|
|
103
119
|
// Build peer agents context for the LLM so it knows who the other agents are
|
|
104
120
|
const peerContext = _peerAgents.length > 0
|
|
105
121
|
? `\nKNOWN PEER AGENTS (other AI agents in the organisation — if a message @-mentions one of these by name or Slack ID, it is NOT directed at ${agentName}):\n${_peerAgents.map(a => `- ${a.name} (${a.role}, Slack: <@${a.slackId}>)`).join("\n")}\n`
|
|
106
122
|
: "";
|
|
107
123
|
|
|
108
|
-
return `You are a message classifier for ${agentName}, ${agentRole} (AI-operated) at Adaptic.ai. ${agentName} is the autonomous executive command layer for
|
|
124
|
+
return `You are a message classifier for ${agentName}, ${agentRole} (AI-operated) at Adaptic.ai. ${agentName} is the autonomous executive command layer for ${principalTitle} ${principalFullName}.
|
|
109
125
|
|
|
110
126
|
Your job: classify each incoming message and return a JSON object with exactly these fields:
|
|
111
127
|
|
|
@@ -121,7 +137,7 @@ ${peerContext}
|
|
|
121
137
|
Classification rules:
|
|
122
138
|
|
|
123
139
|
PRIORITY:
|
|
124
|
-
- "critical":
|
|
140
|
+
- "critical": ${principalTitle} (${principalName}) direct messages, anything requiring immediate action, regulatory deadlines, legal escalations, board-level requests
|
|
125
141
|
- "high": Leadership team requests (CFO, GC, SEO), urgent keywords ("urgent", "asap", "immediately", "deadline", "blocker"), time-sensitive operational matters, candidate offers/rejections
|
|
126
142
|
- "normal": Routine operational messages, team updates, standard requests, meeting notes, general coordination
|
|
127
143
|
- "ignore": Automated notifications (GitHub, Railway, CI/CD), marketing emails, newsletters, noreply senders, spam, out-of-office replies
|
|
@@ -161,7 +177,7 @@ DIRECTED_AT_AGENT (CRITICAL — determines whether ${agentName} should respond.
|
|
|
161
177
|
- CRITICAL DEFAULT: When in doubt in any multi-person channel, group chat, or thread, ALWAYS default to false. ${agentName} must NOT insert themselves into conversations they weren't invited to. It is far worse to respond unnecessarily than to miss a message — someone will @mention ${agentName} if they need them.
|
|
162
178
|
|
|
163
179
|
Context:
|
|
164
|
-
- sender_privilege "ceo" =
|
|
180
|
+
- sender_privilege "ceo" = ${principalFullName} (always critical, always opus)
|
|
165
181
|
- sender_privilege "leadership" = Hootan (CFO/CIO/SEO), Nima (GC), Shayan (FTLab) — usually high priority
|
|
166
182
|
- sender_privilege "team" = internal team members
|
|
167
183
|
- sender_privilege "external" = partners, candidates, advisors, vendors
|
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
// Install: launchd plist with KeepAlive: true
|
|
11
11
|
// =============================================================================
|
|
12
12
|
|
|
13
|
-
// The core daemon implementation
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
13
|
+
// The core daemon implementation is in sophie-daemon.mjs by default, but
|
|
14
|
+
// older agent repos may have a renamed copy at <firstname>-daemon.mjs (a
|
|
15
|
+
// pre-1.7 convention). This entry-point auto-detects the correct file so
|
|
16
|
+
// the launchd plist stays stable regardless of agent identity history.
|
|
17
17
|
|
|
18
|
-
import { resolve, dirname } from "node:path";
|
|
18
|
+
import { resolve, dirname, join } from "node:path";
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
20
21
|
|
|
21
22
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
22
23
|
const AGENT_DIR = process.env.AGENT_DIR || resolve(__dirname, "../..");
|
|
@@ -54,5 +55,43 @@ try {
|
|
|
54
55
|
// Reactive daemon continues. Doctor / healthcheck will surface this.
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
//
|
|
58
|
-
|
|
58
|
+
// Locate the core daemon module. Try, in order:
|
|
59
|
+
// 1. ./sophie-daemon.mjs — canonical filename (post-Phase-2.5 SOT)
|
|
60
|
+
// 2. ./<firstName>-daemon.mjs — legacy rename from init-maestro Phase 1
|
|
61
|
+
// 3. The first scripts/daemon/*-daemon.mjs that isn't this file
|
|
62
|
+
function resolveCoreDaemon() {
|
|
63
|
+
const localCandidates = [];
|
|
64
|
+
const canonical = resolve(__dirname, "sophie-daemon.mjs");
|
|
65
|
+
localCandidates.push(canonical);
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const agentJson = join(AGENT_DIR, "config", "agent.json");
|
|
69
|
+
if (existsSync(agentJson)) {
|
|
70
|
+
const { firstName } = JSON.parse(readFileSync(agentJson, "utf-8"));
|
|
71
|
+
if (firstName && typeof firstName === "string") {
|
|
72
|
+
const lower = firstName.toLowerCase();
|
|
73
|
+
localCandidates.push(resolve(__dirname, `${lower}-daemon.mjs`));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} catch { /* identity unavailable — fall through */ }
|
|
77
|
+
|
|
78
|
+
for (const p of localCandidates) if (existsSync(p)) return p;
|
|
79
|
+
|
|
80
|
+
// Final fallback: scan the directory for *-daemon.mjs (excluding self).
|
|
81
|
+
try {
|
|
82
|
+
for (const name of readdirSync(__dirname)) {
|
|
83
|
+
if (name === "maestro-daemon.mjs") continue;
|
|
84
|
+
if (name.endsWith("-daemon.mjs")) return resolve(__dirname, name);
|
|
85
|
+
}
|
|
86
|
+
} catch { /* */ }
|
|
87
|
+
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const coreDaemon = resolveCoreDaemon();
|
|
92
|
+
if (!coreDaemon) {
|
|
93
|
+
console.error("[DAEMON] could not locate a core daemon module under scripts/daemon/. Expected sophie-daemon.mjs or <firstName>-daemon.mjs.");
|
|
94
|
+
process.exit(78);
|
|
95
|
+
}
|
|
96
|
+
// Import and run the daemon (handles its own .env loading).
|
|
97
|
+
await import(coreDaemon);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Block MCP Slack sends — per CEO directive si-010
|
|
3
3
|
# All Slack sending must go through User OAuth Token (xoxp-) via slack-send.sh
|
|
4
|
-
# MCP Slack adds "Sent using @Claude" label — unacceptable for
|
|
4
|
+
# MCP Slack adds "Sent using @Claude" label — unacceptable for the agent's identity
|
|
5
5
|
# Exit 2 = blocked (message shown to Claude as rejection)
|
|
6
6
|
echo "BLOCKED: Per CEO directive si-010 — do NOT use MCP Slack for sending. Use scripts/slack-send.sh with SLACK_USER_TOKEN instead." >&2
|
|
7
7
|
exit 2
|