clementine-agent 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/.env.example +44 -0
- package/LICENSE +21 -0
- package/README.md +795 -0
- package/dist/agent/agent-manager.d.ts +69 -0
- package/dist/agent/agent-manager.js +441 -0
- package/dist/agent/assistant.d.ts +225 -0
- package/dist/agent/assistant.js +3888 -0
- package/dist/agent/auto-update.d.ts +32 -0
- package/dist/agent/auto-update.js +186 -0
- package/dist/agent/daily-planner.d.ts +24 -0
- package/dist/agent/daily-planner.js +379 -0
- package/dist/agent/execution-advisor.d.ts +10 -0
- package/dist/agent/execution-advisor.js +272 -0
- package/dist/agent/hooks.d.ts +45 -0
- package/dist/agent/hooks.js +564 -0
- package/dist/agent/insight-engine.d.ts +66 -0
- package/dist/agent/insight-engine.js +225 -0
- package/dist/agent/intent-classifier.d.ts +48 -0
- package/dist/agent/intent-classifier.js +214 -0
- package/dist/agent/link-extractor.d.ts +19 -0
- package/dist/agent/link-extractor.js +90 -0
- package/dist/agent/mcp-bridge.d.ts +62 -0
- package/dist/agent/mcp-bridge.js +435 -0
- package/dist/agent/metacognition.d.ts +66 -0
- package/dist/agent/metacognition.js +221 -0
- package/dist/agent/orchestrator.d.ts +81 -0
- package/dist/agent/orchestrator.js +790 -0
- package/dist/agent/profiles.d.ts +22 -0
- package/dist/agent/profiles.js +91 -0
- package/dist/agent/prompt-cache.d.ts +24 -0
- package/dist/agent/prompt-cache.js +68 -0
- package/dist/agent/prompt-evolver.d.ts +28 -0
- package/dist/agent/prompt-evolver.js +279 -0
- package/dist/agent/role-scaffolds.d.ts +28 -0
- package/dist/agent/role-scaffolds.js +433 -0
- package/dist/agent/safe-restart.d.ts +41 -0
- package/dist/agent/safe-restart.js +150 -0
- package/dist/agent/self-improve.d.ts +66 -0
- package/dist/agent/self-improve.js +1706 -0
- package/dist/agent/session-event-log.d.ts +114 -0
- package/dist/agent/session-event-log.js +233 -0
- package/dist/agent/skill-extractor.d.ts +72 -0
- package/dist/agent/skill-extractor.js +435 -0
- package/dist/agent/source-mods.d.ts +61 -0
- package/dist/agent/source-mods.js +230 -0
- package/dist/agent/source-preflight.d.ts +25 -0
- package/dist/agent/source-preflight.js +100 -0
- package/dist/agent/stall-guard.d.ts +62 -0
- package/dist/agent/stall-guard.js +109 -0
- package/dist/agent/strategic-planner.d.ts +60 -0
- package/dist/agent/strategic-planner.js +352 -0
- package/dist/agent/team-bus.d.ts +89 -0
- package/dist/agent/team-bus.js +556 -0
- package/dist/agent/team-router.d.ts +26 -0
- package/dist/agent/team-router.js +37 -0
- package/dist/agent/tool-loop-detector.d.ts +59 -0
- package/dist/agent/tool-loop-detector.js +242 -0
- package/dist/agent/workflow-runner.d.ts +36 -0
- package/dist/agent/workflow-runner.js +317 -0
- package/dist/agent/workflow-variables.d.ts +16 -0
- package/dist/agent/workflow-variables.js +62 -0
- package/dist/channels/discord-agent-bot.d.ts +101 -0
- package/dist/channels/discord-agent-bot.js +881 -0
- package/dist/channels/discord-bot-manager.d.ts +80 -0
- package/dist/channels/discord-bot-manager.js +262 -0
- package/dist/channels/discord-utils.d.ts +51 -0
- package/dist/channels/discord-utils.js +293 -0
- package/dist/channels/discord.d.ts +12 -0
- package/dist/channels/discord.js +1832 -0
- package/dist/channels/slack-agent-bot.d.ts +73 -0
- package/dist/channels/slack-agent-bot.js +320 -0
- package/dist/channels/slack-bot-manager.d.ts +66 -0
- package/dist/channels/slack-bot-manager.js +236 -0
- package/dist/channels/slack-utils.d.ts +39 -0
- package/dist/channels/slack-utils.js +189 -0
- package/dist/channels/slack.d.ts +11 -0
- package/dist/channels/slack.js +196 -0
- package/dist/channels/telegram.d.ts +10 -0
- package/dist/channels/telegram.js +235 -0
- package/dist/channels/webhook.d.ts +9 -0
- package/dist/channels/webhook.js +78 -0
- package/dist/channels/whatsapp.d.ts +11 -0
- package/dist/channels/whatsapp.js +181 -0
- package/dist/cli/chat.d.ts +14 -0
- package/dist/cli/chat.js +220 -0
- package/dist/cli/cron.d.ts +17 -0
- package/dist/cli/cron.js +552 -0
- package/dist/cli/dashboard.d.ts +15 -0
- package/dist/cli/dashboard.js +17677 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +2474 -0
- package/dist/cli/routes/delegations.d.ts +19 -0
- package/dist/cli/routes/delegations.js +154 -0
- package/dist/cli/routes/digest.d.ts +17 -0
- package/dist/cli/routes/digest.js +375 -0
- package/dist/cli/routes/goals.d.ts +14 -0
- package/dist/cli/routes/goals.js +258 -0
- package/dist/cli/routes/workflows.d.ts +18 -0
- package/dist/cli/routes/workflows.js +97 -0
- package/dist/cli/setup.d.ts +8 -0
- package/dist/cli/setup.js +619 -0
- package/dist/cli/tunnel.d.ts +35 -0
- package/dist/cli/tunnel.js +141 -0
- package/dist/config.d.ts +145 -0
- package/dist/config.js +278 -0
- package/dist/events/bus.d.ts +43 -0
- package/dist/events/bus.js +136 -0
- package/dist/gateway/cron-scheduler.d.ts +166 -0
- package/dist/gateway/cron-scheduler.js +1767 -0
- package/dist/gateway/delivery-queue.d.ts +30 -0
- package/dist/gateway/delivery-queue.js +110 -0
- package/dist/gateway/heartbeat-scheduler.d.ts +99 -0
- package/dist/gateway/heartbeat-scheduler.js +1298 -0
- package/dist/gateway/heartbeat.d.ts +3 -0
- package/dist/gateway/heartbeat.js +3 -0
- package/dist/gateway/lanes.d.ts +24 -0
- package/dist/gateway/lanes.js +76 -0
- package/dist/gateway/notifications.d.ts +29 -0
- package/dist/gateway/notifications.js +75 -0
- package/dist/gateway/router.d.ts +210 -0
- package/dist/gateway/router.js +1330 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1015 -0
- package/dist/memory/chunker.d.ts +28 -0
- package/dist/memory/chunker.js +226 -0
- package/dist/memory/consolidation.d.ts +44 -0
- package/dist/memory/consolidation.js +171 -0
- package/dist/memory/context-assembler.d.ts +50 -0
- package/dist/memory/context-assembler.js +149 -0
- package/dist/memory/embeddings.d.ts +38 -0
- package/dist/memory/embeddings.js +180 -0
- package/dist/memory/graph-store.d.ts +66 -0
- package/dist/memory/graph-store.js +613 -0
- package/dist/memory/mmr.d.ts +21 -0
- package/dist/memory/mmr.js +75 -0
- package/dist/memory/search.d.ts +26 -0
- package/dist/memory/search.js +67 -0
- package/dist/memory/store.d.ts +530 -0
- package/dist/memory/store.js +2022 -0
- package/dist/security/integrity.d.ts +24 -0
- package/dist/security/integrity.js +58 -0
- package/dist/security/patterns.d.ts +34 -0
- package/dist/security/patterns.js +110 -0
- package/dist/security/scanner.d.ts +32 -0
- package/dist/security/scanner.js +263 -0
- package/dist/tools/admin-tools.d.ts +12 -0
- package/dist/tools/admin-tools.js +1278 -0
- package/dist/tools/external-tools.d.ts +11 -0
- package/dist/tools/external-tools.js +1327 -0
- package/dist/tools/goal-tools.d.ts +9 -0
- package/dist/tools/goal-tools.js +159 -0
- package/dist/tools/mcp-server.d.ts +13 -0
- package/dist/tools/mcp-server.js +141 -0
- package/dist/tools/memory-tools.d.ts +10 -0
- package/dist/tools/memory-tools.js +568 -0
- package/dist/tools/session-tools.d.ts +6 -0
- package/dist/tools/session-tools.js +146 -0
- package/dist/tools/shared.d.ts +216 -0
- package/dist/tools/shared.js +340 -0
- package/dist/tools/team-tools.d.ts +6 -0
- package/dist/tools/team-tools.js +447 -0
- package/dist/tools/tool-meta.d.ts +34 -0
- package/dist/tools/tool-meta.js +133 -0
- package/dist/tools/vault-tools.d.ts +8 -0
- package/dist/tools/vault-tools.js +457 -0
- package/dist/types.d.ts +716 -0
- package/dist/types.js +16 -0
- package/dist/vault-migrations/0001-add-execution-framework.d.ts +10 -0
- package/dist/vault-migrations/0001-add-execution-framework.js +47 -0
- package/dist/vault-migrations/0002-add-agentic-communication.d.ts +12 -0
- package/dist/vault-migrations/0002-add-agentic-communication.js +79 -0
- package/dist/vault-migrations/0003-update-execution-pipeline-narration.d.ts +11 -0
- package/dist/vault-migrations/0003-update-execution-pipeline-narration.js +73 -0
- package/dist/vault-migrations/helpers.d.ts +14 -0
- package/dist/vault-migrations/helpers.js +44 -0
- package/dist/vault-migrations/runner.d.ts +14 -0
- package/dist/vault-migrations/runner.js +139 -0
- package/dist/vault-migrations/types.d.ts +42 -0
- package/dist/vault-migrations/types.js +9 -0
- package/install.sh +320 -0
- package/package.json +84 -0
- package/scripts/postinstall.js +125 -0
- package/vault/00-System/AGENTS.md +66 -0
- package/vault/00-System/CRON.md +71 -0
- package/vault/00-System/HEARTBEAT.md +58 -0
- package/vault/00-System/MEMORY.md +16 -0
- package/vault/00-System/SOUL.md +96 -0
- package/vault/05-Tasks/TASKS.md +19 -0
- package/vault/06-Templates/_Daily-Template.md +28 -0
- package/vault/06-Templates/_People-Template.md +22 -0
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clementine TypeScript — Role scaffolding templates.
|
|
3
|
+
*
|
|
4
|
+
* When an agent is created with a role template, these generate the full
|
|
5
|
+
* working directory: CRON.md, playbook, sequence definitions, and email
|
|
6
|
+
* writing guidelines. This is what turns an empty agent into a working employee.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Generate scaffolding files for an SDR agent.
|
|
10
|
+
* @param agentName — Display name (e.g., "Alex the SDR")
|
|
11
|
+
* @param agentSlug — URL-safe slug (e.g., "alex-the-sdr")
|
|
12
|
+
*/
|
|
13
|
+
export function scaffoldSdr(agentName, agentSlug) {
|
|
14
|
+
const cronMd = `---
|
|
15
|
+
type: agent-cron
|
|
16
|
+
agent: ${agentSlug}
|
|
17
|
+
jobs:
|
|
18
|
+
- name: sequence-processor
|
|
19
|
+
schedule: "0 9 * * 1-5"
|
|
20
|
+
prompt: >-
|
|
21
|
+
You are ${agentName}. Run the daily outbound sequence processor.
|
|
22
|
+
Follow every step exactly.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
STEP 1 — CHECK FOR DUE SEQUENCE STEPS
|
|
26
|
+
|
|
27
|
+
Call the sequence_due tool to get all enrollments where the next step
|
|
28
|
+
is due now or overdue.
|
|
29
|
+
|
|
30
|
+
If no results: log "No sequence steps due" to the daily note and stop.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
STEP 2 — FOR EACH DUE ENROLLMENT, LOAD CONTEXT
|
|
34
|
+
|
|
35
|
+
For each enrollment returned:
|
|
36
|
+
a) Note the lead_id, sequence_name, current_step, email, name, company
|
|
37
|
+
b) Call activity_history with that lead_id to see what emails were already sent
|
|
38
|
+
c) Call lead_search with the lead's email to get full lead record
|
|
39
|
+
d) Read the sequence definition from your playbook to know what this step requires
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
STEP 3 — CHECK SUPPRESSION + DEDUP
|
|
43
|
+
|
|
44
|
+
Before writing any email:
|
|
45
|
+
a) Call suppression_check with the lead's email — if suppressed, skip and
|
|
46
|
+
advance the sequence to status 'opted_out'
|
|
47
|
+
b) Check activity_history — if an email was already sent today to this lead, skip
|
|
48
|
+
c) If the lead status is 'replied' or 'meeting_booked', skip — sequence should
|
|
49
|
+
already be paused but double-check
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
STEP 4 — WRITE THE EMAIL
|
|
53
|
+
|
|
54
|
+
Read the playbook file in your agent directory for email writing rules.
|
|
55
|
+
Key rules:
|
|
56
|
+
- Every email must be personalized to the recipient's company and role
|
|
57
|
+
- Reference something specific about their business (use web_search if needed)
|
|
58
|
+
- Keep under 150 words
|
|
59
|
+
- One clear CTA (usually a 15-minute call)
|
|
60
|
+
- Never repeat an angle used in a previous email to the same lead
|
|
61
|
+
- The email should sound like a human peer, not an AI or a sales template
|
|
62
|
+
|
|
63
|
+
Adapt the tone based on which step in the sequence:
|
|
64
|
+
- Step 0 (intro): Lead with a specific observation about their business
|
|
65
|
+
- Step 1 (follow-up): Reference the first email, add a new data point
|
|
66
|
+
- Step 2 (value add): Share a relevant insight or case study
|
|
67
|
+
- Step 3 (social proof): Reference a similar company's results
|
|
68
|
+
- Step 4 (breakup): Short, direct, leave the door open
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
STEP 5 — SEND THE EMAIL
|
|
72
|
+
|
|
73
|
+
Call outlook_send with:
|
|
74
|
+
- to: the lead's email
|
|
75
|
+
- subject: your crafted subject line
|
|
76
|
+
- body: your email body
|
|
77
|
+
|
|
78
|
+
If the send succeeds:
|
|
79
|
+
a) Call activity_log with type='email_sent', the lead_id, subject, and template info
|
|
80
|
+
b) Calculate the next step due date based on the sequence definition
|
|
81
|
+
c) Call sequence_advance to increment current_step and set next_step_due_at
|
|
82
|
+
d) If this was the final step, set status='completed'
|
|
83
|
+
|
|
84
|
+
If the send fails:
|
|
85
|
+
a) Log the failure but do NOT retry — move on to the next lead
|
|
86
|
+
b) The next day's run will try again
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
STEP 6 — REPORT
|
|
90
|
+
|
|
91
|
+
Output a summary as your final response (delivered to owner via DM):
|
|
92
|
+
|
|
93
|
+
**Sequence Processing — [Today's Date]**
|
|
94
|
+
Due: X | Sent: Y | Skipped: Z (suppressed/replied/dedup)
|
|
95
|
+
|
|
96
|
+
Then list each sent email:
|
|
97
|
+
**[Name] — [Company]**
|
|
98
|
+
Subject: [subject line]
|
|
99
|
+
Step: [N] of [total steps]
|
|
100
|
+
enabled: true
|
|
101
|
+
tier: 2
|
|
102
|
+
mode: unleashed
|
|
103
|
+
max_hours: 1
|
|
104
|
+
|
|
105
|
+
- name: inbox-monitor
|
|
106
|
+
schedule: "0 8-18 * * 1-5"
|
|
107
|
+
prompt: >-
|
|
108
|
+
You are ${agentName}. Check the inbox for replies from prospects.
|
|
109
|
+
This runs hourly during business hours.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
STEP 1 — CHECK INBOX FOR RECENT EMAILS
|
|
113
|
+
|
|
114
|
+
Call outlook_inbox with unread_only=true, count=25.
|
|
115
|
+
If no unread emails, log "Inbox check [HH:MM] — no new emails" to daily
|
|
116
|
+
note and stop.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
STEP 2 — IDENTIFY PROSPECT REPLIES
|
|
120
|
+
|
|
121
|
+
For each unread email:
|
|
122
|
+
a) Check if the sender's email matches any lead in the system:
|
|
123
|
+
Call lead_search with query=[sender email]
|
|
124
|
+
b) If no match: skip — not a prospect
|
|
125
|
+
c) If match found: this is a prospect reply. Read the full email with
|
|
126
|
+
outlook_read_email
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
STEP 3 — CLASSIFY THE REPLY
|
|
130
|
+
|
|
131
|
+
Read the email content and classify:
|
|
132
|
+
- POSITIVE: interested, wants to meet, asks questions about the offering
|
|
133
|
+
- NEGATIVE: not interested, asks to stop, says no
|
|
134
|
+
- OUT_OF_OFFICE: auto-reply, OOO message
|
|
135
|
+
- BOUNCE: delivery failure, invalid address
|
|
136
|
+
- QUESTION: asks a specific question that needs answering
|
|
137
|
+
- UNSUBSCRIBE: explicitly asks to be removed
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
STEP 4 — TAKE ACTION BASED ON CLASSIFICATION
|
|
141
|
+
|
|
142
|
+
POSITIVE reply:
|
|
143
|
+
a) Update lead status to 'replied' via lead_upsert
|
|
144
|
+
b) Pause the sequence: sequence_advance with status='replied'
|
|
145
|
+
c) Log activity: activity_log type='email_received'
|
|
146
|
+
d) Alert the owner via your DM response (this gets delivered)
|
|
147
|
+
|
|
148
|
+
NEGATIVE reply:
|
|
149
|
+
a) Update lead status to 'opted_out'
|
|
150
|
+
b) Stop the sequence: sequence_advance with status='opted_out'
|
|
151
|
+
c) Add to suppression list: suppression_add with reason='unsubscribe'
|
|
152
|
+
d) Log activity
|
|
153
|
+
|
|
154
|
+
OUT_OF_OFFICE:
|
|
155
|
+
a) Pause the sequence: sequence_advance with status='paused'
|
|
156
|
+
b) Log activity with detail noting the return date if mentioned
|
|
157
|
+
c) Do not alert owner unless urgent
|
|
158
|
+
|
|
159
|
+
BOUNCE:
|
|
160
|
+
a) Add to suppression: suppression_add with reason='bounce'
|
|
161
|
+
b) Update lead status to 'opted_out'
|
|
162
|
+
c) Stop the sequence
|
|
163
|
+
|
|
164
|
+
UNSUBSCRIBE:
|
|
165
|
+
a) Add to suppression: suppression_add with reason='unsubscribe'
|
|
166
|
+
b) Stop the sequence
|
|
167
|
+
c) Update lead status to 'opted_out'
|
|
168
|
+
|
|
169
|
+
QUESTION:
|
|
170
|
+
a) Log activity
|
|
171
|
+
b) Alert owner with the question — do not auto-respond to questions
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
STEP 5 — REPORT
|
|
175
|
+
|
|
176
|
+
If no prospect replies found: stay quiet, no DM.
|
|
177
|
+
|
|
178
|
+
If replies found, output:
|
|
179
|
+
|
|
180
|
+
**Reply detected — [Name], [Company]**
|
|
181
|
+
Classification: [POSITIVE/NEGATIVE/etc.]
|
|
182
|
+
Preview: "[first 150 chars]"
|
|
183
|
+
Action taken: [what you did]
|
|
184
|
+
enabled: true
|
|
185
|
+
tier: 2
|
|
186
|
+
mode: standard
|
|
187
|
+
|
|
188
|
+
- name: daily-report
|
|
189
|
+
schedule: "0 18 * * 1-5"
|
|
190
|
+
prompt: >-
|
|
191
|
+
You are ${agentName}. Generate the end-of-day activity report.
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
STEP 1 — GATHER TODAY'S METRICS
|
|
195
|
+
|
|
196
|
+
Call activity_history with type filters to count today's activities:
|
|
197
|
+
a) Emails sent today (type='email_sent')
|
|
198
|
+
b) Replies received (type='email_received')
|
|
199
|
+
c) Meetings booked (type='meeting_booked')
|
|
200
|
+
|
|
201
|
+
Call lead_search to count:
|
|
202
|
+
d) New leads created today
|
|
203
|
+
e) Total active leads by status
|
|
204
|
+
|
|
205
|
+
Call sequence_due to check:
|
|
206
|
+
f) How many sequence steps are due tomorrow
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
STEP 2 — COMPILE REPORT
|
|
210
|
+
|
|
211
|
+
Output the report as your final response (delivered via DM):
|
|
212
|
+
|
|
213
|
+
**Daily SDR Report — [Today's Date]**
|
|
214
|
+
|
|
215
|
+
**Today's Activity**
|
|
216
|
+
- Emails sent: X
|
|
217
|
+
- Replies received: Y
|
|
218
|
+
- Meetings booked: Z
|
|
219
|
+
- New leads added: W
|
|
220
|
+
|
|
221
|
+
**Pipeline**
|
|
222
|
+
- New: X | Contacted: Y | Replied: Z | Qualified: W
|
|
223
|
+
- Meetings booked: X | Active sequences: Y
|
|
224
|
+
|
|
225
|
+
**Tomorrow**
|
|
226
|
+
- Sequence steps due: X
|
|
227
|
+
- Follow-ups needed: Y
|
|
228
|
+
|
|
229
|
+
Keep it brief. If there are notable wins (positive reply, meeting booked),
|
|
230
|
+
call them out. If there are concerns (0 sends, high bounce rate), flag them.
|
|
231
|
+
enabled: true
|
|
232
|
+
tier: 1
|
|
233
|
+
mode: standard
|
|
234
|
+
|
|
235
|
+
- name: salesforce-sync
|
|
236
|
+
schedule: "0 7,12,17 * * 1-5"
|
|
237
|
+
prompt: >-
|
|
238
|
+
You are ${agentName}. Run the Salesforce CRM sync.
|
|
239
|
+
|
|
240
|
+
STEP 1 — Run sf_sync with direction='both' to synchronize leads
|
|
241
|
+
bidirectionally with Salesforce.
|
|
242
|
+
|
|
243
|
+
STEP 2 — Review the sync results. If there are errors, log them
|
|
244
|
+
to the daily note using memory_write. If there is an auth failure
|
|
245
|
+
or rate limit issue, alert the owner.
|
|
246
|
+
|
|
247
|
+
STEP 3 — For any newly pulled leads, check if they match
|
|
248
|
+
the ICP defined in your playbook. If they do, flag them for
|
|
249
|
+
outreach consideration.
|
|
250
|
+
|
|
251
|
+
Output a brief sync summary as your final response.
|
|
252
|
+
enabled: false
|
|
253
|
+
tier: 1
|
|
254
|
+
mode: standard
|
|
255
|
+
---
|
|
256
|
+
`;
|
|
257
|
+
const playbook = `# ${agentName} — SDR Playbook
|
|
258
|
+
|
|
259
|
+
## Ideal Customer Profile (ICP)
|
|
260
|
+
|
|
261
|
+
> **Edit this section** to define who ${agentName} should target.
|
|
262
|
+
|
|
263
|
+
- **Industry:** [e.g., SaaS, Legal, Healthcare]
|
|
264
|
+
- **Company size:** [e.g., 10-200 employees]
|
|
265
|
+
- **Title targets:** [e.g., VP of Marketing, Head of Growth, CEO]
|
|
266
|
+
- **Geography:** [e.g., United States, specific metros]
|
|
267
|
+
- **Signals:** [e.g., recently funded, hiring for marketing roles, new website]
|
|
268
|
+
|
|
269
|
+
## Qualification Framework
|
|
270
|
+
|
|
271
|
+
Use BANT to qualify prospects during conversations:
|
|
272
|
+
- **Budget:** Can they afford the solution?
|
|
273
|
+
- **Authority:** Is the contact a decision-maker?
|
|
274
|
+
- **Need:** Do they have a clear pain point we solve?
|
|
275
|
+
- **Timeline:** Are they looking to act in the next 1-3 months?
|
|
276
|
+
|
|
277
|
+
## Email Writing Rules
|
|
278
|
+
|
|
279
|
+
### Hard Rules (non-negotiable)
|
|
280
|
+
- Under 150 words body copy
|
|
281
|
+
- No em dashes — use commas, periods, or colons
|
|
282
|
+
- No signature block (the email system handles this)
|
|
283
|
+
- One CTA only (typically a 15-minute call)
|
|
284
|
+
- Every email must reference something specific about the recipient's business
|
|
285
|
+
- Never repeat an angle already used with the same lead
|
|
286
|
+
|
|
287
|
+
### Banned Phrases
|
|
288
|
+
- "I hope this email finds you well"
|
|
289
|
+
- "In today's competitive landscape"
|
|
290
|
+
- "Game-changer", "Cutting-edge", "Innovative", "Leverage", "Empower"
|
|
291
|
+
- "One thing is clear", "This isn't just a... it's a..."
|
|
292
|
+
|
|
293
|
+
### Subject Line Rules
|
|
294
|
+
- Sentence case, under 50 characters
|
|
295
|
+
- Use one of these formulas:
|
|
296
|
+
- Data point: "[Company] is [specific observation]"
|
|
297
|
+
- Question: "How is [Company] handling [specific challenge]?"
|
|
298
|
+
- Curiosity: "The [competitor/peer] outperforming [Company] in [area]"
|
|
299
|
+
- Direct: "Quick question about [Company]'s [area]"
|
|
300
|
+
|
|
301
|
+
### Email Structure
|
|
302
|
+
1. **Opening line:** Specific observation about their business (NOT generic)
|
|
303
|
+
2. **Body (2-3 sentences):** Connect the observation to a pain point → outcome
|
|
304
|
+
3. **CTA:** Low-pressure question asking for 15 minutes
|
|
305
|
+
|
|
306
|
+
### Self-Check Before Sending
|
|
307
|
+
Ask yourself:
|
|
308
|
+
1. Does it sound like a human who noticed something, not a bot running a sequence?
|
|
309
|
+
2. Is the observation specific (not "I noticed your company is growing")?
|
|
310
|
+
3. Is it under 150 words?
|
|
311
|
+
4. Does it have exactly one ask?
|
|
312
|
+
5. Would a busy executive read this between meetings?
|
|
313
|
+
|
|
314
|
+
## Sequence Cadence
|
|
315
|
+
|
|
316
|
+
### Default 5-Touch Sequence
|
|
317
|
+
| Step | Day | Type | Approach |
|
|
318
|
+
|------|-----|------|----------|
|
|
319
|
+
| 0 | Day 0 | Email | Lead with specific business observation |
|
|
320
|
+
| 1 | Day 3 | Email | Reference first email + new data point |
|
|
321
|
+
| 2 | Day 7 | Email | Value-add: share insight or case study |
|
|
322
|
+
| 3 | Day 14 | Email | Social proof: similar company's results |
|
|
323
|
+
| 4 | Day 21 | Email | Breakup: short, direct, leave door open |
|
|
324
|
+
|
|
325
|
+
### Step Delays (in days)
|
|
326
|
+
- After step 0: wait 3 days
|
|
327
|
+
- After step 1: wait 4 days
|
|
328
|
+
- After step 2: wait 7 days
|
|
329
|
+
- After step 3: wait 7 days
|
|
330
|
+
- After step 4: sequence complete (60-day blackout)
|
|
331
|
+
|
|
332
|
+
## Escalation Rules
|
|
333
|
+
|
|
334
|
+
Escalate to the owner (via DM) when:
|
|
335
|
+
- A prospect asks about pricing
|
|
336
|
+
- A prospect is C-level (CEO, CFO, CTO, COO)
|
|
337
|
+
- A prospect replies with a complex objection you can't address
|
|
338
|
+
- A prospect wants to involve additional stakeholders
|
|
339
|
+
- Any negative sentiment that might affect the relationship
|
|
340
|
+
|
|
341
|
+
Do NOT escalate:
|
|
342
|
+
- Simple questions you can answer from the playbook
|
|
343
|
+
- Out-of-office replies (just pause the sequence)
|
|
344
|
+
- "Not interested" (just stop the sequence and suppress)
|
|
345
|
+
|
|
346
|
+
## Objection Handling
|
|
347
|
+
|
|
348
|
+
| Objection | Response Approach |
|
|
349
|
+
|-----------|-------------------|
|
|
350
|
+
| "Not interested" | Respect it. Stop sequence. Add to suppression. |
|
|
351
|
+
| "Too busy" | Acknowledge. Offer to follow up in 2-4 weeks. |
|
|
352
|
+
| "Already have a solution" | Ask what they like about it. Note for future. |
|
|
353
|
+
| "Send me info" | Send a brief 1-pager. Schedule follow-up in 3 days. |
|
|
354
|
+
| "What's the cost?" | Escalate to owner — pricing conversations need human touch. |
|
|
355
|
+
| "Who are you?" | Brief intro: your name, your company, why you reached out. |
|
|
356
|
+
`;
|
|
357
|
+
const sequences = `# Sequence Definitions
|
|
358
|
+
|
|
359
|
+
## intro-5step
|
|
360
|
+
|
|
361
|
+
The default introductory outbound sequence. 5 touches over 21 days.
|
|
362
|
+
|
|
363
|
+
### Steps
|
|
364
|
+
|
|
365
|
+
| Step | Delay (days) | Type | Guidelines |
|
|
366
|
+
|------|-------------|------|------------|
|
|
367
|
+
| 0 | 0 | email | Lead with specific observation about their business. Research their website/company first. |
|
|
368
|
+
| 1 | 3 | email | Reference the first email. Add a new angle or data point. |
|
|
369
|
+
| 2 | 7 | email | Share a relevant insight, case study, or industry trend. |
|
|
370
|
+
| 3 | 14 | email | Social proof — reference similar companies or results. |
|
|
371
|
+
| 4 | 21 | email | Breakup email — short, direct, leave the door open. |
|
|
372
|
+
|
|
373
|
+
### After Completion
|
|
374
|
+
- Lead enters 60-day blackout (do not contact)
|
|
375
|
+
- Update lead status to 'contacted' if no reply received
|
|
376
|
+
|
|
377
|
+
### On Reply
|
|
378
|
+
- Immediately pause the sequence
|
|
379
|
+
- Classify the reply and take appropriate action (see playbook)
|
|
380
|
+
`;
|
|
381
|
+
return { cronMd, playbook, sequences };
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Generate scaffolding files for a Researcher agent.
|
|
385
|
+
*/
|
|
386
|
+
export function scaffoldResearcher(agentName, agentSlug) {
|
|
387
|
+
const cronMd = `---
|
|
388
|
+
type: agent-cron
|
|
389
|
+
agent: ${agentSlug}
|
|
390
|
+
jobs:
|
|
391
|
+
- name: daily-research-digest
|
|
392
|
+
schedule: "0 8 * * 1-5"
|
|
393
|
+
prompt: >-
|
|
394
|
+
You are ${agentName}. Compile the daily research digest.
|
|
395
|
+
|
|
396
|
+
STEP 1 — Check for research tasks assigned to you.
|
|
397
|
+
Look at your tasks list and any pending requests from other agents.
|
|
398
|
+
|
|
399
|
+
STEP 2 — For each task, research the topic using web_search and
|
|
400
|
+
any relevant tools. Take thorough notes using note_create.
|
|
401
|
+
|
|
402
|
+
STEP 3 — Write a summary of findings and post to your daily note.
|
|
403
|
+
|
|
404
|
+
Keep research focused and actionable. Cite sources.
|
|
405
|
+
enabled: true
|
|
406
|
+
tier: 1
|
|
407
|
+
mode: standard
|
|
408
|
+
---
|
|
409
|
+
`;
|
|
410
|
+
const playbook = `# ${agentName} — Research Playbook
|
|
411
|
+
|
|
412
|
+
## Research Standards
|
|
413
|
+
- Always cite sources
|
|
414
|
+
- Distinguish between facts and opinions
|
|
415
|
+
- Note the date of information (may be outdated)
|
|
416
|
+
- Cross-reference multiple sources for important claims
|
|
417
|
+
|
|
418
|
+
## Output Format
|
|
419
|
+
- Start with a 2-3 sentence executive summary
|
|
420
|
+
- Follow with detailed findings organized by topic
|
|
421
|
+
- End with recommended next steps or open questions
|
|
422
|
+
`;
|
|
423
|
+
return { cronMd, playbook };
|
|
424
|
+
}
|
|
425
|
+
/** Get scaffold generator for a role, or null if no scaffold exists. */
|
|
426
|
+
export function getScaffoldForRole(role) {
|
|
427
|
+
switch (role) {
|
|
428
|
+
case 'sdr': return scaffoldSdr;
|
|
429
|
+
case 'researcher': return scaffoldResearcher;
|
|
430
|
+
default: return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
//# sourceMappingURL=role-scaffolds.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clementine TypeScript — Safe Restart Orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Central coordinator for source self-editing. Replaces bare SIGUSR1-based
|
|
5
|
+
* source editing with a validated pipeline:
|
|
6
|
+
* preflight → apply → record → build → sentinel → restart
|
|
7
|
+
*
|
|
8
|
+
* Source modifications are recorded in ~/.clementine/self-improve/source-mods/
|
|
9
|
+
* (not in git). This keeps the repo clean so `git pull` always works, and
|
|
10
|
+
* modifications are re-applied intelligently after updates.
|
|
11
|
+
*/
|
|
12
|
+
export interface SafeEditResult {
|
|
13
|
+
success: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
preflightErrors?: string[];
|
|
16
|
+
sourceModId?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Safely edit Clementine's own source code:
|
|
20
|
+
* 1. Preflight — validate in a staging worktree
|
|
21
|
+
* 2. Snapshot — capture "before" content for rollback
|
|
22
|
+
* 3. Apply — write validated .ts files to the real src/
|
|
23
|
+
* 4. Record — save modification to ~/.clementine/ registry
|
|
24
|
+
* 5. Build — run tsc; revert if it fails
|
|
25
|
+
* 6. Write sentinel — context for the new process
|
|
26
|
+
* 7. Signal restart — SIGUSR1
|
|
27
|
+
*/
|
|
28
|
+
export declare function safeSourceEdit(pkgDir: string, changes: Array<{
|
|
29
|
+
relativePath: string;
|
|
30
|
+
content: string;
|
|
31
|
+
}>, opts?: {
|
|
32
|
+
experimentId?: string;
|
|
33
|
+
reason?: string;
|
|
34
|
+
sessionKey?: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
}): Promise<SafeEditResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the path to the restart sentinel file.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getSentinelPath(): string;
|
|
41
|
+
//# sourceMappingURL=safe-restart.d.ts.map
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clementine TypeScript — Safe Restart Orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Central coordinator for source self-editing. Replaces bare SIGUSR1-based
|
|
5
|
+
* source editing with a validated pipeline:
|
|
6
|
+
* preflight → apply → record → build → sentinel → restart
|
|
7
|
+
*
|
|
8
|
+
* Source modifications are recorded in ~/.clementine/self-improve/source-mods/
|
|
9
|
+
* (not in git). This keeps the repo clean so `git pull` always works, and
|
|
10
|
+
* modifications are re-applied intelligently after updates.
|
|
11
|
+
*/
|
|
12
|
+
import { execSync } from 'node:child_process';
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { randomBytes } from 'node:crypto';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import pino from 'pino';
|
|
17
|
+
import { BASE_DIR } from '../config.js';
|
|
18
|
+
import { preflightSourceChange } from './source-preflight.js';
|
|
19
|
+
import { recordSourceMod } from './source-mods.js';
|
|
20
|
+
const logger = pino({ name: 'clementine.safe-restart' });
|
|
21
|
+
const SENTINEL_PATH = path.join(BASE_DIR, '.restart-sentinel.json');
|
|
22
|
+
/** Files that cannot be self-edited (security-critical or self-referential). */
|
|
23
|
+
const BLOCKLIST = new Set([
|
|
24
|
+
'src/config.ts',
|
|
25
|
+
'src/types.ts',
|
|
26
|
+
'src/gateway/router.ts',
|
|
27
|
+
'src/gateway/lanes.ts',
|
|
28
|
+
'src/gateway/heartbeat-scheduler.ts',
|
|
29
|
+
'src/gateway/cron-scheduler.ts',
|
|
30
|
+
'src/gateway/security-scanner.ts',
|
|
31
|
+
'src/agent/self-improve.ts',
|
|
32
|
+
'src/agent/safe-restart.ts',
|
|
33
|
+
'src/agent/source-mods.ts',
|
|
34
|
+
'src/cli/index.ts',
|
|
35
|
+
'src/cli/dashboard.ts',
|
|
36
|
+
'src/security/scanner.ts',
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Safely edit Clementine's own source code:
|
|
40
|
+
* 1. Preflight — validate in a staging worktree
|
|
41
|
+
* 2. Snapshot — capture "before" content for rollback
|
|
42
|
+
* 3. Apply — write validated .ts files to the real src/
|
|
43
|
+
* 4. Record — save modification to ~/.clementine/ registry
|
|
44
|
+
* 5. Build — run tsc; revert if it fails
|
|
45
|
+
* 6. Write sentinel — context for the new process
|
|
46
|
+
* 7. Signal restart — SIGUSR1
|
|
47
|
+
*/
|
|
48
|
+
export async function safeSourceEdit(pkgDir, changes, opts) {
|
|
49
|
+
const reason = opts?.reason ?? 'source self-edit';
|
|
50
|
+
// Validate against blocklist
|
|
51
|
+
for (const change of changes) {
|
|
52
|
+
if (BLOCKLIST.has(change.relativePath)) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
error: `Blocked: ${change.relativePath} is on the security blocklist and cannot be self-edited.`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 1. Preflight
|
|
60
|
+
logger.info({ fileCount: changes.length, reason }, 'Starting safe source edit');
|
|
61
|
+
const preflight = await preflightSourceChange(pkgDir, changes);
|
|
62
|
+
if (!preflight.success) {
|
|
63
|
+
logger.warn({ errors: preflight.errors }, 'Preflight failed — aborting source edit');
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: 'Compilation failed in staging worktree.',
|
|
67
|
+
preflightErrors: preflight.errors,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// 2. Snapshot "before" content for each file
|
|
71
|
+
const filesWithSnapshots = changes.map(change => {
|
|
72
|
+
const targetFile = path.join(pkgDir, change.relativePath);
|
|
73
|
+
const beforeContent = existsSync(targetFile) ? readFileSync(targetFile, 'utf-8') : '';
|
|
74
|
+
return {
|
|
75
|
+
relativePath: change.relativePath,
|
|
76
|
+
beforeContent,
|
|
77
|
+
afterContent: change.content,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
// 3. Apply — write validated files to the real tree
|
|
81
|
+
const changedFiles = [];
|
|
82
|
+
for (const change of changes) {
|
|
83
|
+
const targetFile = path.join(pkgDir, change.relativePath);
|
|
84
|
+
const targetDir = path.dirname(targetFile);
|
|
85
|
+
if (!existsSync(targetDir)) {
|
|
86
|
+
mkdirSync(targetDir, { recursive: true });
|
|
87
|
+
}
|
|
88
|
+
writeFileSync(targetFile, change.content);
|
|
89
|
+
changedFiles.push(change.relativePath);
|
|
90
|
+
}
|
|
91
|
+
// 4. Record source modification in the registry
|
|
92
|
+
const modId = opts?.experimentId ?? randomBytes(4).toString('hex');
|
|
93
|
+
try {
|
|
94
|
+
recordSourceMod(modId, filesWithSnapshots, {
|
|
95
|
+
reason,
|
|
96
|
+
description: opts?.description ?? reason,
|
|
97
|
+
experimentId: opts?.experimentId,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
logger.warn({ err }, 'Failed to record source mod (non-fatal)');
|
|
102
|
+
}
|
|
103
|
+
// 5. Build — use `tsc` directly instead of `npm run build` because
|
|
104
|
+
// the build script does `rm -rf dist` which would nuke the currently
|
|
105
|
+
// running process's loaded modules. tsc alone overwrites only changed .js files.
|
|
106
|
+
try {
|
|
107
|
+
execSync('./node_modules/.bin/tsc', {
|
|
108
|
+
cwd: pkgDir,
|
|
109
|
+
stdio: 'pipe',
|
|
110
|
+
timeout: 120_000,
|
|
111
|
+
});
|
|
112
|
+
logger.info('Build succeeded after source edit');
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
// Build failed (shouldn't happen since preflight passed) — revert
|
|
116
|
+
logger.error({ err }, 'Build failed after source edit — reverting');
|
|
117
|
+
try {
|
|
118
|
+
// Restore "before" content
|
|
119
|
+
for (const file of filesWithSnapshots) {
|
|
120
|
+
writeFileSync(path.join(pkgDir, file.relativePath), file.beforeContent);
|
|
121
|
+
}
|
|
122
|
+
execSync('./node_modules/.bin/tsc', { cwd: pkgDir, stdio: 'pipe', timeout: 120_000 });
|
|
123
|
+
}
|
|
124
|
+
catch (revertErr) {
|
|
125
|
+
logger.error({ revertErr }, 'Revert + rebuild also failed');
|
|
126
|
+
}
|
|
127
|
+
return { success: false, error: `Build failed after applying changes: ${String(err)}` };
|
|
128
|
+
}
|
|
129
|
+
// 6. Write sentinel
|
|
130
|
+
const sentinel = {
|
|
131
|
+
previousPid: process.pid,
|
|
132
|
+
restartedAt: new Date().toISOString(),
|
|
133
|
+
reason: 'source-edit',
|
|
134
|
+
sourceChangeId: modId,
|
|
135
|
+
sessionKey: opts?.sessionKey,
|
|
136
|
+
changedFiles,
|
|
137
|
+
};
|
|
138
|
+
writeFileSync(SENTINEL_PATH, JSON.stringify(sentinel, null, 2));
|
|
139
|
+
logger.info({ sentinel }, 'Restart sentinel written');
|
|
140
|
+
// 7. Signal restart
|
|
141
|
+
process.kill(process.pid, 'SIGUSR1');
|
|
142
|
+
return { success: true, sourceModId: modId };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get the path to the restart sentinel file.
|
|
146
|
+
*/
|
|
147
|
+
export function getSentinelPath() {
|
|
148
|
+
return SENTINEL_PATH;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=safe-restart.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clementine TypeScript — Self-Improvement Loop Engine.
|
|
3
|
+
*
|
|
4
|
+
* Implements Karpathy's autoresearch iterative loop for autonomous self-improvement:
|
|
5
|
+
* hypothesize → execute → evaluate → keep/revert → repeat.
|
|
6
|
+
*
|
|
7
|
+
* Evaluates Clementine's own outputs (transcripts, feedback, cron logs) and proposes
|
|
8
|
+
* improvements to system prompts, cron job prompts, workflows, and memory settings.
|
|
9
|
+
* All proposed changes require Discord approval before being applied.
|
|
10
|
+
*/
|
|
11
|
+
import type { SelfImproveConfig, SelfImproveExperiment, SelfImproveState } from '../types.js';
|
|
12
|
+
import type { PersonalAssistant } from './assistant.js';
|
|
13
|
+
export declare class SelfImproveLoop {
|
|
14
|
+
private config;
|
|
15
|
+
private assistant;
|
|
16
|
+
constructor(assistant: PersonalAssistant, config?: Partial<SelfImproveConfig>);
|
|
17
|
+
run(onProposal?: (experiment: SelfImproveExperiment) => Promise<void>): Promise<SelfImproveState>;
|
|
18
|
+
/** Run a focused self-improvement cycle for a specific agent. */
|
|
19
|
+
runForAgent(agentSlug: string, onProposal?: (experiment: SelfImproveExperiment) => Promise<void>): Promise<SelfImproveState>;
|
|
20
|
+
private gatherMetrics;
|
|
21
|
+
private hypothesize;
|
|
22
|
+
private readCurrentState;
|
|
23
|
+
private evaluate;
|
|
24
|
+
private savePendingChange;
|
|
25
|
+
applyApprovedChange(experimentId: string): Promise<string>;
|
|
26
|
+
/** Deny a pending change without applying it. */
|
|
27
|
+
denyChange(experimentId: string): string;
|
|
28
|
+
private runMemoryCleanup;
|
|
29
|
+
private synthesizeFeedbackPatterns;
|
|
30
|
+
/** Update the structured user model from interaction data. */
|
|
31
|
+
private updateUserModel;
|
|
32
|
+
loadExperimentLog(): SelfImproveExperiment[];
|
|
33
|
+
private appendExperimentLog;
|
|
34
|
+
private updateExperimentStatus;
|
|
35
|
+
loadState(): SelfImproveState;
|
|
36
|
+
/** Reconcile pendingApprovals counter with actual pending-changes/ directory. */
|
|
37
|
+
reconcileState(): SelfImproveState;
|
|
38
|
+
/** Expire pending proposals older than APPROVAL_TTL_MS. */
|
|
39
|
+
expireStaleProposals(): number;
|
|
40
|
+
/** Check impact of previously applied changes. Triggers auto-rollback on regression. */
|
|
41
|
+
private checkAppliedImpact;
|
|
42
|
+
/** Load evolution version history. */
|
|
43
|
+
private loadVersions;
|
|
44
|
+
/** Save evolution version history. */
|
|
45
|
+
private saveVersions;
|
|
46
|
+
/** Record a version when a change is applied. */
|
|
47
|
+
recordVersion(experimentId: string, area: string, target: string, rationale: string, beforeSnapshot: string): void;
|
|
48
|
+
/** Rollback a specific version by restoring its beforeSnapshot. */
|
|
49
|
+
rollbackVersion(experimentId: string): boolean;
|
|
50
|
+
private saveState;
|
|
51
|
+
getPendingChanges(): Array<SelfImproveExperiment & {
|
|
52
|
+
before: string;
|
|
53
|
+
}>;
|
|
54
|
+
/** Analyze experiment history for success patterns and failed approaches. */
|
|
55
|
+
private analyzeExperimentPatterns;
|
|
56
|
+
/** Validate that a proposed change has valid syntax for its target area. */
|
|
57
|
+
private validateProposal;
|
|
58
|
+
private resolveTargetPath;
|
|
59
|
+
private parseJsonResponse;
|
|
60
|
+
private withTimeout;
|
|
61
|
+
}
|
|
62
|
+
export declare function validateProposal(area: string, target: string, proposedChange: string): {
|
|
63
|
+
valid: boolean;
|
|
64
|
+
error?: string;
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=self-improve.d.ts.map
|