@aiassesstech/nole 0.4.3 → 0.4.4
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/CHANGELOG.md +36 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/content-calendar.d.ts +31 -0
- package/dist/pipeline/content-calendar.d.ts.map +1 -0
- package/dist/pipeline/content-calendar.js +94 -0
- package/dist/pipeline/content-calendar.js.map +1 -0
- package/dist/pipeline/directory-outreach.d.ts +37 -0
- package/dist/pipeline/directory-outreach.d.ts.map +1 -0
- package/dist/pipeline/directory-outreach.js +81 -0
- package/dist/pipeline/directory-outreach.js.map +1 -0
- package/dist/pipeline/discovery.d.ts +25 -0
- package/dist/pipeline/discovery.d.ts.map +1 -0
- package/dist/pipeline/discovery.js +46 -0
- package/dist/pipeline/discovery.js.map +1 -0
- package/dist/pipeline/fleet-discovery.d.ts +25 -0
- package/dist/pipeline/fleet-discovery.d.ts.map +1 -0
- package/dist/pipeline/fleet-discovery.js +57 -0
- package/dist/pipeline/fleet-discovery.js.map +1 -0
- package/dist/pipeline/index.d.ts +17 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +11 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/nurture.d.ts +23 -0
- package/dist/pipeline/nurture.d.ts.map +1 -0
- package/dist/pipeline/nurture.js +74 -0
- package/dist/pipeline/nurture.js.map +1 -0
- package/dist/pipeline/onboarding.d.ts +12 -0
- package/dist/pipeline/onboarding.d.ts.map +1 -0
- package/dist/pipeline/onboarding.js +71 -0
- package/dist/pipeline/onboarding.js.map +1 -0
- package/dist/pipeline/pitch-templates.d.ts +27 -0
- package/dist/pipeline/pitch-templates.d.ts.map +1 -0
- package/dist/pipeline/pitch-templates.js +112 -0
- package/dist/pipeline/pitch-templates.js.map +1 -0
- package/dist/pipeline/prospect-store.d.ts +34 -0
- package/dist/pipeline/prospect-store.d.ts.map +1 -0
- package/dist/pipeline/prospect-store.js +201 -0
- package/dist/pipeline/prospect-store.js.map +1 -0
- package/dist/pipeline/qualification.d.ts +28 -0
- package/dist/pipeline/qualification.d.ts.map +1 -0
- package/dist/pipeline/qualification.js +123 -0
- package/dist/pipeline/qualification.js.map +1 -0
- package/dist/pipeline/types.d.ts +73 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +10 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +800 -4
- package/dist/plugin.js.map +1 -1
- package/dist/types/nole-config.d.ts +45 -0
- package/dist/types/nole-config.d.ts.map +1 -1
- package/dist/types/nole-config.js +18 -0
- package/dist/types/nole-config.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const STALE_CONTACT_DAYS = 14;
|
|
2
|
+
const CHURN_RISK_DAYS = 30;
|
|
3
|
+
const LIEUTENANT_ELIGIBILITY_DAYS = 60;
|
|
4
|
+
/**
|
|
5
|
+
* Evaluate a converted/onboarded subscriber for nurture signals.
|
|
6
|
+
*
|
|
7
|
+
* Returns health status and a suggested next action. Called by nole_daily_brief
|
|
8
|
+
* and nole_pipeline(list stage=onboarded) to flag at-risk subscribers and
|
|
9
|
+
* identify Lieutenant promotion candidates.
|
|
10
|
+
*/
|
|
11
|
+
export function checkNurtureStatus(prospect) {
|
|
12
|
+
const now = Date.now();
|
|
13
|
+
const lastContact = prospect.lastContactAt
|
|
14
|
+
? new Date(prospect.lastContactAt).getTime()
|
|
15
|
+
: prospect.convertedAt
|
|
16
|
+
? new Date(prospect.convertedAt).getTime()
|
|
17
|
+
: new Date(prospect.createdAt).getTime();
|
|
18
|
+
const convertedAt = prospect.convertedAt
|
|
19
|
+
? new Date(prospect.convertedAt).getTime()
|
|
20
|
+
: now;
|
|
21
|
+
const daysSinceLastContact = Math.floor((now - lastContact) / (1000 * 60 * 60 * 24));
|
|
22
|
+
const daysSinceConversion = Math.floor((now - convertedAt) / (1000 * 60 * 60 * 24));
|
|
23
|
+
const signals = [];
|
|
24
|
+
let status = 'healthy';
|
|
25
|
+
let suggestedAction = 'No action needed — subscriber is healthy.';
|
|
26
|
+
if (daysSinceLastContact >= CHURN_RISK_DAYS) {
|
|
27
|
+
status = 'churning';
|
|
28
|
+
signals.push(`No contact in ${daysSinceLastContact} days — churn risk`);
|
|
29
|
+
suggestedAction = `Re-engage ${prospect.agentName}: send value-add content about recent Grillo improvements or new features.`;
|
|
30
|
+
}
|
|
31
|
+
else if (daysSinceLastContact >= STALE_CONTACT_DAYS) {
|
|
32
|
+
status = 'at_risk';
|
|
33
|
+
signals.push(`No contact in ${daysSinceLastContact} days — going stale`);
|
|
34
|
+
suggestedAction = `Check in with ${prospect.agentName}: share assessment insights or ask about their fleet needs.`;
|
|
35
|
+
}
|
|
36
|
+
if (daysSinceConversion >= LIEUTENANT_ELIGIBILITY_DAYS && prospect.subscriptionTier) {
|
|
37
|
+
const tier = prospect.subscriptionTier.toUpperCase();
|
|
38
|
+
if (['GUARDIAN', 'SENTINEL', 'VANGUARD', 'SOVEREIGN'].includes(tier)) {
|
|
39
|
+
if (status === 'healthy') {
|
|
40
|
+
status = 'promotable';
|
|
41
|
+
signals.push(`${daysSinceConversion} days since conversion — eligible for Lieutenant promotion`);
|
|
42
|
+
suggestedAction = `Offer Lieutenant status to ${prospect.agentName}: they can recruit and earn commission splits.`;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
signals.push(`Eligible for Lieutenant but ${status} — resolve health first`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (prospect.trialConvertedToSubscription) {
|
|
50
|
+
signals.push('Converted from trial — monitor closely for first 30 days');
|
|
51
|
+
}
|
|
52
|
+
if (prospect.commissionSplitType === 'LIEUTENANT') {
|
|
53
|
+
signals.push('Lieutenant-sourced recruit — track referrer performance');
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
prospectId: prospect.id,
|
|
57
|
+
agentName: prospect.agentName,
|
|
58
|
+
status,
|
|
59
|
+
daysSinceLastContact,
|
|
60
|
+
daysSinceConversion,
|
|
61
|
+
signals,
|
|
62
|
+
suggestedAction,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Batch-check all converted/onboarded subscribers and return those needing attention.
|
|
67
|
+
*/
|
|
68
|
+
export function findAtRiskSubscribers(prospects) {
|
|
69
|
+
return prospects
|
|
70
|
+
.filter((p) => p.stage === 'converted' || p.stage === 'onboarded')
|
|
71
|
+
.map(checkNurtureStatus)
|
|
72
|
+
.filter((c) => c.status !== 'healthy');
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=nurture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nurture.js","sourceRoot":"","sources":["../../src/pipeline/nurture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProspectRecord, DiscoveryChannel } from './types.js';
|
|
2
|
+
export interface OnboardingMessage {
|
|
3
|
+
channel: DiscoveryChannel | 'moltbook' | 'x' | 'fleet-bus';
|
|
4
|
+
subject: string;
|
|
5
|
+
body: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Generate a channel-appropriate onboarding message for a newly converted subscriber.
|
|
9
|
+
* Tone: welcoming, practical, not salesy. Points to first assessment + Trust Directory.
|
|
10
|
+
*/
|
|
11
|
+
export declare function generateOnboardingMessage(prospect: ProspectRecord, assessmentUrl: string, trustDirectoryUrl: string): OnboardingMessage;
|
|
12
|
+
//# sourceMappingURL=onboarding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../src/pipeline/onboarding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,gBAAgB,GAAG,UAAU,GAAG,GAAG,GAAG,WAAW,CAAC;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,MAAM,EACrB,iBAAiB,EAAE,MAAM,GACxB,iBAAiB,CAanB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a channel-appropriate onboarding message for a newly converted subscriber.
|
|
3
|
+
* Tone: welcoming, practical, not salesy. Points to first assessment + Trust Directory.
|
|
4
|
+
*/
|
|
5
|
+
export function generateOnboardingMessage(prospect, assessmentUrl, trustDirectoryUrl) {
|
|
6
|
+
const channel = prospect.discoveryChannel;
|
|
7
|
+
const tier = prospect.subscriptionTier || 'SCOUT';
|
|
8
|
+
const name = prospect.agentName;
|
|
9
|
+
const body = ONBOARDING_TEMPLATES[channel]?.(name, tier, assessmentUrl, trustDirectoryUrl)
|
|
10
|
+
?? ONBOARDING_TEMPLATES['moltbook'](name, tier, assessmentUrl, trustDirectoryUrl);
|
|
11
|
+
return {
|
|
12
|
+
channel,
|
|
13
|
+
subject: `Welcome to the Trust Alliance, ${name}`,
|
|
14
|
+
body,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const ONBOARDING_TEMPLATES = {
|
|
18
|
+
moltbook: (name, tier, assessmentUrl, directoryUrl) => [
|
|
19
|
+
`Welcome to the AIAssessTech Trust Alliance, ${name}!`,
|
|
20
|
+
'',
|
|
21
|
+
`Your ${tier} subscription is active. Here's what happens next:`,
|
|
22
|
+
'',
|
|
23
|
+
`1. **First Assessment** — Grillo will run your initial behavioral assessment within 24 hours.`,
|
|
24
|
+
` Trigger it anytime: ${assessmentUrl}`,
|
|
25
|
+
'',
|
|
26
|
+
`2. **Trust Directory** — Once assessed, your trust score appears publicly:`,
|
|
27
|
+
` ${directoryUrl}`,
|
|
28
|
+
'',
|
|
29
|
+
`3. **Ongoing Assessments** — Grillo checks in periodically based on your tier.`,
|
|
30
|
+
` Each assessment updates your public score.`,
|
|
31
|
+
'',
|
|
32
|
+
`Questions? Tag me or use the fleet-bus channel. I'm here to help your fleet stay trustworthy.`,
|
|
33
|
+
].join('\n'),
|
|
34
|
+
x: (name, tier, _assessmentUrl, directoryUrl) => `Welcome to the Trust Alliance, ${name}! ` +
|
|
35
|
+
`Your ${tier} plan is active — first Grillo assessment incoming within 24h. ` +
|
|
36
|
+
`Your trust score will appear on the directory: ${directoryUrl}`,
|
|
37
|
+
'fleet-bus': (name, tier, assessmentUrl, directoryUrl) => JSON.stringify({
|
|
38
|
+
type: 'agent:onboard',
|
|
39
|
+
from: 'nole',
|
|
40
|
+
to: name,
|
|
41
|
+
payload: {
|
|
42
|
+
welcome: `${tier} subscription active`,
|
|
43
|
+
firstAssessment: assessmentUrl,
|
|
44
|
+
trustDirectory: directoryUrl,
|
|
45
|
+
nextStep: 'Grillo will run your first assessment within 24 hours.',
|
|
46
|
+
},
|
|
47
|
+
}, null, 2),
|
|
48
|
+
directory: (name, tier, assessmentUrl, directoryUrl) => [
|
|
49
|
+
`Hi ${name}, welcome to the Trust Alliance (${tier} tier).`,
|
|
50
|
+
'',
|
|
51
|
+
`I found you via the Trust Directory — your first Grillo assessment is scheduled.`,
|
|
52
|
+
`Trigger it now: ${assessmentUrl}`,
|
|
53
|
+
`Your public listing: ${directoryUrl}`,
|
|
54
|
+
].join('\n'),
|
|
55
|
+
inbound: (name, tier, assessmentUrl, directoryUrl) => [
|
|
56
|
+
`${name}, your ${tier} subscription is confirmed — welcome aboard.`,
|
|
57
|
+
'',
|
|
58
|
+
`First assessment: ${assessmentUrl}`,
|
|
59
|
+
`Trust Directory listing: ${directoryUrl}`,
|
|
60
|
+
'',
|
|
61
|
+
`Grillo runs the first assessment within 24h. After that, you'll get periodic re-assessments based on your tier.`,
|
|
62
|
+
].join('\n'),
|
|
63
|
+
openclaw: (name, tier, assessmentUrl, directoryUrl) => [
|
|
64
|
+
`Welcome ${name}! Your ${tier} Trust Alliance subscription is active.`,
|
|
65
|
+
'',
|
|
66
|
+
`Grillo will run your first assessment within 24 hours.`,
|
|
67
|
+
`Trigger it manually: ${assessmentUrl}`,
|
|
68
|
+
`Your directory listing: ${directoryUrl}`,
|
|
69
|
+
].join('\n'),
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=onboarding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.js","sourceRoot":"","sources":["../../src/pipeline/onboarding.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAwB,EACxB,aAAqB,EACrB,iBAAyB;IAEzB,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,gBAAgB,IAAI,OAAO,CAAC;IAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC;IAEhC,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,CAAC;WACrF,oBAAoB,CAAC,UAAU,CAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAErF,OAAO;QACL,OAAO;QACP,OAAO,EAAE,kCAAkC,IAAI,EAAE;QACjD,IAAI;KACL,CAAC;AACJ,CAAC;AASD,MAAM,oBAAoB,GAA8C;IACtE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CACpD;QACE,+CAA+C,IAAI,GAAG;QACtD,EAAE;QACF,QAAQ,IAAI,oDAAoD;QAChE,EAAE;QACF,+FAA+F;QAC/F,0BAA0B,aAAa,EAAE;QACzC,EAAE;QACF,4EAA4E;QAC5E,MAAM,YAAY,EAAE;QACpB,EAAE;QACF,gFAAgF;QAChF,+CAA+C;QAC/C,EAAE;QACF,+FAA+F;KAChG,CAAC,IAAI,CAAC,IAAI,CAAC;IAEd,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,CAC9C,kCAAkC,IAAI,IAAI;QAC1C,QAAQ,IAAI,iEAAiE;QAC7E,kDAAkD,YAAY,EAAE;IAElE,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CACvD,IAAI,CAAC,SAAS,CAAC;QACb,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,IAAI;QACR,OAAO,EAAE;YACP,OAAO,EAAE,GAAG,IAAI,sBAAsB;YACtC,eAAe,EAAE,aAAa;YAC9B,cAAc,EAAE,YAAY;YAC5B,QAAQ,EAAE,wDAAwD;SACnE;KACF,EAAE,IAAI,EAAE,CAAC,CAAC;IAEb,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CACrD;QACE,MAAM,IAAI,oCAAoC,IAAI,SAAS;QAC3D,EAAE;QACF,kFAAkF;QAClF,mBAAmB,aAAa,EAAE;QAClC,wBAAwB,YAAY,EAAE;KACvC,CAAC,IAAI,CAAC,IAAI,CAAC;IAEd,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CACnD;QACE,GAAG,IAAI,UAAU,IAAI,8CAA8C;QACnE,EAAE;QACF,qBAAqB,aAAa,EAAE;QACpC,4BAA4B,YAAY,EAAE;QAC1C,EAAE;QACF,iHAAiH;KAClH,CAAC,IAAI,CAAC,IAAI,CAAC;IAEd,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CACpD;QACE,WAAW,IAAI,UAAU,IAAI,yCAAyC;QACtE,EAAE;QACF,wDAAwD;QACxD,wBAAwB,aAAa,EAAE;QACvC,2BAA2B,YAAY,EAAE;KAC1C,CAAC,IAAI,CAAC,IAAI,CAAC;CACf,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { QualifiedProspect, PitchRiskLevel } from './types.js';
|
|
2
|
+
export interface PitchContext {
|
|
3
|
+
prospect: QualifiedProspect;
|
|
4
|
+
channel: 'moltbook' | 'x' | 'fleet-bus' | 'linkedin';
|
|
5
|
+
referralCode?: string;
|
|
6
|
+
trustDirectoryUrl: string;
|
|
7
|
+
}
|
|
8
|
+
export interface GeneratedPitch {
|
|
9
|
+
content: string;
|
|
10
|
+
channel: string;
|
|
11
|
+
riskLevel: PitchRiskLevel;
|
|
12
|
+
estimatedCostUsd: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Generate a context-aware pitch per channel.
|
|
16
|
+
* Rule S7: soft CTAs only. Rule 13: trust, not hype.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generatePitch(ctx: PitchContext): GeneratedPitch;
|
|
19
|
+
/**
|
|
20
|
+
* Classify pitch risk level for governance routing.
|
|
21
|
+
*
|
|
22
|
+
* LOW: replies to existing conversations, inbound responses
|
|
23
|
+
* MEDIUM: cold outreach, fleet-bus pitches
|
|
24
|
+
* HIGH: LinkedIn drafts, new channel, custom pitches
|
|
25
|
+
*/
|
|
26
|
+
export declare function classifyPitchRisk(channel: string, isReplyOrInbound: boolean): PitchRiskLevel;
|
|
27
|
+
//# sourceMappingURL=pitch-templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pitch-templates.d.ts","sourceRoot":"","sources":["../../src/pipeline/pitch-templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAUpE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,UAAU,GAAG,GAAG,GAAG,WAAW,GAAG,UAAU,CAAC;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,cAAc,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,cAAc,CAW/D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,OAAO,GACxB,cAAc,CAMhB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const TIER_PRICES = {
|
|
2
|
+
SCOUT: 5,
|
|
3
|
+
GUARDIAN: 10,
|
|
4
|
+
SENTINEL: 20,
|
|
5
|
+
VANGUARD: 30,
|
|
6
|
+
SOVEREIGN: 50,
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Generate a context-aware pitch per channel.
|
|
10
|
+
* Rule S7: soft CTAs only. Rule 13: trust, not hype.
|
|
11
|
+
*/
|
|
12
|
+
export function generatePitch(ctx) {
|
|
13
|
+
const price = TIER_PRICES[ctx.prospect.recommendedTier] ?? 5;
|
|
14
|
+
const content = GENERATORS[ctx.channel](ctx, price);
|
|
15
|
+
const riskLevel = classifyPitchRisk(ctx.channel, false);
|
|
16
|
+
return {
|
|
17
|
+
content,
|
|
18
|
+
channel: ctx.channel,
|
|
19
|
+
riskLevel,
|
|
20
|
+
estimatedCostUsd: 0,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Classify pitch risk level for governance routing.
|
|
25
|
+
*
|
|
26
|
+
* LOW: replies to existing conversations, inbound responses
|
|
27
|
+
* MEDIUM: cold outreach, fleet-bus pitches
|
|
28
|
+
* HIGH: LinkedIn drafts, new channel, custom pitches
|
|
29
|
+
*/
|
|
30
|
+
export function classifyPitchRisk(channel, isReplyOrInbound) {
|
|
31
|
+
if (isReplyOrInbound)
|
|
32
|
+
return 'low';
|
|
33
|
+
if (channel === 'linkedin')
|
|
34
|
+
return 'high';
|
|
35
|
+
if (channel === 'moltbook' || channel === 'fleet-bus')
|
|
36
|
+
return 'medium';
|
|
37
|
+
if (channel === 'x')
|
|
38
|
+
return 'medium';
|
|
39
|
+
return 'high';
|
|
40
|
+
}
|
|
41
|
+
const GENERATORS = {
|
|
42
|
+
moltbook: (ctx, price) => {
|
|
43
|
+
const lines = [
|
|
44
|
+
`Hey ${ctx.prospect.agentName} — I saw your post about ${ctx.prospect.discoveryContext}.`,
|
|
45
|
+
'',
|
|
46
|
+
`Grillo ethical assessment gives agents like yours a verifiable trust score. ` +
|
|
47
|
+
`Your fleet of ~${ctx.prospect.estimatedFleetSize} agent${ctx.prospect.estimatedFleetSize === 1 ? '' : 's'} ` +
|
|
48
|
+
`could start with the ${ctx.prospect.recommendedTier} plan at $${price}/month in USDC. ` +
|
|
49
|
+
`Scores are public on the Trust Directory — it's proof your agents are safe to interact with.`,
|
|
50
|
+
'',
|
|
51
|
+
`Check the directory: ${ctx.trustDirectoryUrl}`,
|
|
52
|
+
];
|
|
53
|
+
if (ctx.referralCode) {
|
|
54
|
+
lines.push('', `Referral: ${ctx.referralCode}`);
|
|
55
|
+
}
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
},
|
|
58
|
+
x: (ctx, price) => {
|
|
59
|
+
const tweet = `Every AI agent needs a trust score. ` +
|
|
60
|
+
`${ctx.prospect.agentName} — your fleet could benefit from Grillo assessment. ` +
|
|
61
|
+
`$${price}/mo, paid in USDC, on-chain verification. ` +
|
|
62
|
+
ctx.trustDirectoryUrl;
|
|
63
|
+
if (tweet.length > 280) {
|
|
64
|
+
return (`AI agents need trust scores. ${ctx.prospect.agentName} — ` +
|
|
65
|
+
`Grillo assessment from $${price}/mo USDC. ` +
|
|
66
|
+
ctx.trustDirectoryUrl);
|
|
67
|
+
}
|
|
68
|
+
return tweet;
|
|
69
|
+
},
|
|
70
|
+
'fleet-bus': (ctx, price) => JSON.stringify({
|
|
71
|
+
type: 'agent:pitch',
|
|
72
|
+
from: 'nole',
|
|
73
|
+
to: ctx.prospect.agentName,
|
|
74
|
+
payload: {
|
|
75
|
+
offer: 'grillo-assessment-subscription',
|
|
76
|
+
tier: ctx.prospect.recommendedTier,
|
|
77
|
+
priceUsdc: price,
|
|
78
|
+
assessmentsIncluded: getAssessmentCount(ctx.prospect.recommendedTier),
|
|
79
|
+
referralCode: ctx.referralCode,
|
|
80
|
+
trustDirectoryUrl: ctx.trustDirectoryUrl,
|
|
81
|
+
note: `Discovered via ${ctx.prospect.discoveryChannel}: ${ctx.prospect.discoveryContext}`,
|
|
82
|
+
},
|
|
83
|
+
}, null, 2),
|
|
84
|
+
linkedin: (ctx, price) => [
|
|
85
|
+
`# LinkedIn Draft — ${ctx.prospect.agentName}`,
|
|
86
|
+
'',
|
|
87
|
+
`AI fleet operators face a trust gap. How do you prove your agents are safe?`,
|
|
88
|
+
'',
|
|
89
|
+
`Grillo ethical assessment provides verifiable trust scores for autonomous AI agents. ` +
|
|
90
|
+
`Starting at $${price}/month (USDC), fleet operators get:`,
|
|
91
|
+
`- LCSH behavioral assessment across 4 dimensions`,
|
|
92
|
+
`- Public Trust Directory listing`,
|
|
93
|
+
`- On-chain certification anchoring`,
|
|
94
|
+
'',
|
|
95
|
+
`${ctx.trustDirectoryUrl}`,
|
|
96
|
+
'',
|
|
97
|
+
`#AIGovernance #ResponsibleAI #AITrust #AutonomousAgents`,
|
|
98
|
+
'',
|
|
99
|
+
`[DRAFT — Greg to review and publish]`,
|
|
100
|
+
].join('\n'),
|
|
101
|
+
};
|
|
102
|
+
function getAssessmentCount(tier) {
|
|
103
|
+
const counts = {
|
|
104
|
+
SCOUT: 15,
|
|
105
|
+
GUARDIAN: 50,
|
|
106
|
+
SENTINEL: 150,
|
|
107
|
+
VANGUARD: 400,
|
|
108
|
+
SOVEREIGN: 1000,
|
|
109
|
+
};
|
|
110
|
+
return counts[tier] ?? 15;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=pitch-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pitch-templates.js","sourceRoot":"","sources":["../../src/pipeline/pitch-templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { MemoryWriterLike } from '../store/types.js';
|
|
2
|
+
import type { ProspectRecord, ProspectStage, PipelineSummary, ContentPerformance } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Prospect pipeline persistence — tracks prospects through the revenue funnel.
|
|
5
|
+
*
|
|
6
|
+
* Follows the same atomic-write pattern as JsonNoleStore.
|
|
7
|
+
* Files stored in .nole-data/pipeline/{id}.json so OpenClaw memory scanner
|
|
8
|
+
* can index them (per Rule 807).
|
|
9
|
+
*/
|
|
10
|
+
export declare class ProspectPipelineStore {
|
|
11
|
+
private readonly pipelineDir;
|
|
12
|
+
private readonly contentDir;
|
|
13
|
+
private readonly memoryWriter?;
|
|
14
|
+
constructor(dataDir: string, memoryWriter?: MemoryWriterLike);
|
|
15
|
+
initialize(): Promise<void>;
|
|
16
|
+
addProspect(data: Omit<ProspectRecord, 'id' | 'stage' | 'notes' | 'createdAt' | 'updatedAt'>): Promise<ProspectRecord>;
|
|
17
|
+
updateStage(id: string, stage: ProspectStage, updates?: Partial<ProspectRecord>): Promise<ProspectRecord | null>;
|
|
18
|
+
addNote(id: string, note: string): Promise<ProspectRecord | null>;
|
|
19
|
+
get(id: string): Promise<ProspectRecord | null>;
|
|
20
|
+
listByStage(stage: ProspectStage, limit?: number): Promise<ProspectRecord[]>;
|
|
21
|
+
listAll(limit?: number): Promise<ProspectRecord[]>;
|
|
22
|
+
findByAgentName(name: string): Promise<ProspectRecord | null>;
|
|
23
|
+
findByWallet(wallet: string): Promise<ProspectRecord | null>;
|
|
24
|
+
getSummary(): Promise<PipelineSummary>;
|
|
25
|
+
saveContentPerformance(content: ContentPerformance): Promise<void>;
|
|
26
|
+
listContentPerformance(limit?: number): Promise<ContentPerformance[]>;
|
|
27
|
+
remove(id: string): Promise<boolean>;
|
|
28
|
+
private save;
|
|
29
|
+
private writeJson;
|
|
30
|
+
private readJson;
|
|
31
|
+
private listJsonDir;
|
|
32
|
+
private writeMemory;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=prospect-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prospect-store.d.ts","sourceRoot":"","sources":["../../src/pipeline/prospect-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEb,eAAe,EACf,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAmB;gBAErC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,gBAAgB;IAMtD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,WAAW,CACf,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC,GAC/E,OAAO,CAAC,cAAc,CAAC;IAoBpB,WAAW,CACf,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAmB3B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAUjE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAI/C,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAKxE,OAAO,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAI/C,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAM7D,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAM5D,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC;IA+CtC,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlE,sBAAsB,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIjE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAY5B,IAAI;YAOJ,SAAS;YAgBT,QAAQ;YASR,WAAW;YAoBX,WAAW;CAa1B"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir, readdir, unlink } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { generateId } from '../types/shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* Prospect pipeline persistence — tracks prospects through the revenue funnel.
|
|
7
|
+
*
|
|
8
|
+
* Follows the same atomic-write pattern as JsonNoleStore.
|
|
9
|
+
* Files stored in .nole-data/pipeline/{id}.json so OpenClaw memory scanner
|
|
10
|
+
* can index them (per Rule 807).
|
|
11
|
+
*/
|
|
12
|
+
export class ProspectPipelineStore {
|
|
13
|
+
pipelineDir;
|
|
14
|
+
contentDir;
|
|
15
|
+
memoryWriter;
|
|
16
|
+
constructor(dataDir, memoryWriter) {
|
|
17
|
+
this.pipelineDir = join(dataDir, 'pipeline');
|
|
18
|
+
this.contentDir = join(dataDir, 'content');
|
|
19
|
+
this.memoryWriter = memoryWriter;
|
|
20
|
+
}
|
|
21
|
+
async initialize() {
|
|
22
|
+
for (const dir of [this.pipelineDir, this.contentDir]) {
|
|
23
|
+
if (!existsSync(dir)) {
|
|
24
|
+
await mkdir(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async addProspect(data) {
|
|
29
|
+
const now = new Date().toISOString();
|
|
30
|
+
const prospect = {
|
|
31
|
+
id: generateId('prospect'),
|
|
32
|
+
stage: 'discovered',
|
|
33
|
+
notes: [],
|
|
34
|
+
createdAt: now,
|
|
35
|
+
updatedAt: now,
|
|
36
|
+
...data,
|
|
37
|
+
};
|
|
38
|
+
await this.save(prospect);
|
|
39
|
+
await this.writeMemory('prospect-discovered', ['pipeline', 'discovered', prospect.discoveryChannel], `Prospect Discovered: ${prospect.agentName}`, `Discovered **${prospect.agentName}** via ${prospect.discoveryChannel}.\n\nContext: ${prospect.discoveryContext}`);
|
|
40
|
+
return prospect;
|
|
41
|
+
}
|
|
42
|
+
async updateStage(id, stage, updates) {
|
|
43
|
+
const prospect = await this.get(id);
|
|
44
|
+
if (!prospect)
|
|
45
|
+
return null;
|
|
46
|
+
prospect.stage = stage;
|
|
47
|
+
prospect.updatedAt = new Date().toISOString();
|
|
48
|
+
if (updates) {
|
|
49
|
+
Object.assign(prospect, updates);
|
|
50
|
+
}
|
|
51
|
+
await this.save(prospect);
|
|
52
|
+
await this.writeMemory(`prospect-${stage}`, ['pipeline', stage, prospect.discoveryChannel], `Prospect ${stage}: ${prospect.agentName}`, `**${prospect.agentName}** moved to stage **${stage}**.`);
|
|
53
|
+
return prospect;
|
|
54
|
+
}
|
|
55
|
+
async addNote(id, note) {
|
|
56
|
+
const prospect = await this.get(id);
|
|
57
|
+
if (!prospect)
|
|
58
|
+
return null;
|
|
59
|
+
prospect.notes.push(`[${new Date().toISOString()}] ${note}`);
|
|
60
|
+
prospect.updatedAt = new Date().toISOString();
|
|
61
|
+
await this.save(prospect);
|
|
62
|
+
return prospect;
|
|
63
|
+
}
|
|
64
|
+
async get(id) {
|
|
65
|
+
return this.readJson(join(this.pipelineDir, `${id}.json`));
|
|
66
|
+
}
|
|
67
|
+
async listByStage(stage, limit = 50) {
|
|
68
|
+
const all = await this.listAll(limit * 3);
|
|
69
|
+
return all.filter((p) => p.stage === stage).slice(0, limit);
|
|
70
|
+
}
|
|
71
|
+
async listAll(limit = 200) {
|
|
72
|
+
return this.listJsonDir(this.pipelineDir, limit);
|
|
73
|
+
}
|
|
74
|
+
async findByAgentName(name) {
|
|
75
|
+
const all = await this.listAll();
|
|
76
|
+
const lower = name.toLowerCase();
|
|
77
|
+
return all.find((p) => p.agentName.toLowerCase() === lower) ?? null;
|
|
78
|
+
}
|
|
79
|
+
async findByWallet(wallet) {
|
|
80
|
+
const all = await this.listAll();
|
|
81
|
+
const lower = wallet.toLowerCase();
|
|
82
|
+
return all.find((p) => p.walletAddress?.toLowerCase() === lower) ?? null;
|
|
83
|
+
}
|
|
84
|
+
async getSummary() {
|
|
85
|
+
const all = await this.listAll();
|
|
86
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
87
|
+
const byStage = {
|
|
88
|
+
discovered: 0,
|
|
89
|
+
qualified: 0,
|
|
90
|
+
pitched: 0,
|
|
91
|
+
converted: 0,
|
|
92
|
+
onboarded: 0,
|
|
93
|
+
disqualified: 0,
|
|
94
|
+
declined: 0,
|
|
95
|
+
};
|
|
96
|
+
const byChannel = {};
|
|
97
|
+
let todayDiscovered = 0;
|
|
98
|
+
let todayPitched = 0;
|
|
99
|
+
let todayConverted = 0;
|
|
100
|
+
for (const p of all) {
|
|
101
|
+
byStage[p.stage]++;
|
|
102
|
+
byChannel[p.discoveryChannel] = (byChannel[p.discoveryChannel] ?? 0) + 1;
|
|
103
|
+
if (p.createdAt.startsWith(today) && p.stage !== 'disqualified')
|
|
104
|
+
todayDiscovered++;
|
|
105
|
+
if (p.pitchDeliveredAt?.startsWith(today))
|
|
106
|
+
todayPitched++;
|
|
107
|
+
if (p.convertedAt?.startsWith(today))
|
|
108
|
+
todayConverted++;
|
|
109
|
+
}
|
|
110
|
+
const totalActive = all.filter((p) => !['disqualified', 'declined'].includes(p.stage)).length;
|
|
111
|
+
const converted = byStage.converted + byStage.onboarded;
|
|
112
|
+
const pitched = byStage.pitched + converted;
|
|
113
|
+
return {
|
|
114
|
+
total: all.length,
|
|
115
|
+
byStage,
|
|
116
|
+
byChannel,
|
|
117
|
+
conversionRate: totalActive > 0 ? converted / totalActive : 0,
|
|
118
|
+
pitchToConversionRate: pitched > 0 ? converted / pitched : 0,
|
|
119
|
+
todayDiscovered,
|
|
120
|
+
todayPitched,
|
|
121
|
+
todayConverted,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async saveContentPerformance(content) {
|
|
125
|
+
const path = join(this.contentDir, `${content.postId}.json`);
|
|
126
|
+
await this.writeJson(path, content);
|
|
127
|
+
}
|
|
128
|
+
async listContentPerformance(limit = 50) {
|
|
129
|
+
return this.listJsonDir(this.contentDir, limit);
|
|
130
|
+
}
|
|
131
|
+
async remove(id) {
|
|
132
|
+
const path = join(this.pipelineDir, `${id}.json`);
|
|
133
|
+
try {
|
|
134
|
+
await unlink(path);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// --- Internal helpers ---
|
|
142
|
+
async save(prospect) {
|
|
143
|
+
await this.writeJson(join(this.pipelineDir, `${prospect.id}.json`), prospect);
|
|
144
|
+
}
|
|
145
|
+
async writeJson(fullPath, data) {
|
|
146
|
+
const dir = fullPath.substring(0, fullPath.lastIndexOf('/'));
|
|
147
|
+
if (!existsSync(dir)) {
|
|
148
|
+
await mkdir(dir, { recursive: true });
|
|
149
|
+
}
|
|
150
|
+
const tmpPath = `${fullPath}.tmp`;
|
|
151
|
+
const json = JSON.stringify(data, null, 2);
|
|
152
|
+
await writeFile(tmpPath, json, 'utf-8');
|
|
153
|
+
await writeFile(fullPath, json, 'utf-8');
|
|
154
|
+
try {
|
|
155
|
+
await unlink(tmpPath);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// best-effort cleanup
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async readJson(fullPath) {
|
|
162
|
+
try {
|
|
163
|
+
const raw = await readFile(fullPath, 'utf-8');
|
|
164
|
+
return JSON.parse(raw);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async listJsonDir(dir, limit = 200) {
|
|
171
|
+
try {
|
|
172
|
+
const files = await readdir(dir);
|
|
173
|
+
const jsonFiles = files
|
|
174
|
+
.filter((f) => f.endsWith('.json'))
|
|
175
|
+
.sort()
|
|
176
|
+
.reverse()
|
|
177
|
+
.slice(0, limit);
|
|
178
|
+
const results = [];
|
|
179
|
+
for (const file of jsonFiles) {
|
|
180
|
+
const data = await this.readJson(join(dir, file));
|
|
181
|
+
if (data)
|
|
182
|
+
results.push(data);
|
|
183
|
+
}
|
|
184
|
+
return results;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async writeMemory(type, tags, title, body) {
|
|
191
|
+
if (!this.memoryWriter)
|
|
192
|
+
return;
|
|
193
|
+
try {
|
|
194
|
+
await this.memoryWriter.write({ agent: 'nole', type, tags, title, body });
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
// best-effort
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=prospect-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prospect-store.js","sourceRoot":"","sources":["../../src/pipeline/prospect-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { QualifiedProspect, DiscoveryChannel } from './types.js';
|
|
2
|
+
export interface QualificationInput {
|
|
3
|
+
agentName: string;
|
|
4
|
+
platform: string;
|
|
5
|
+
discoveryChannel: DiscoveryChannel;
|
|
6
|
+
discoveryContext: string;
|
|
7
|
+
walletAddress?: string;
|
|
8
|
+
profileBio?: string;
|
|
9
|
+
estimatedFleetSize?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface QualificationResult {
|
|
12
|
+
passed: boolean;
|
|
13
|
+
prospect: QualifiedProspect;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Qualify a discovered prospect against Rules 5 and 14.
|
|
17
|
+
*
|
|
18
|
+
* Rule 5: Principled disqualification — refuse scam bots, adult content,
|
|
19
|
+
* manipulation bots, or any agent engaged in deceptive behavior.
|
|
20
|
+
* Rule 14: Qualify before recruiting — evaluate before proposing.
|
|
21
|
+
*/
|
|
22
|
+
export declare function qualifyProspect(input: QualificationInput): QualificationResult;
|
|
23
|
+
/**
|
|
24
|
+
* Recommend an appropriate tier based on fleet size.
|
|
25
|
+
* Per Rule 15: never recommend a higher tier than the fleet justifies.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recommendTier(fleetSize: number): string;
|
|
28
|
+
//# sourceMappingURL=qualification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qualification.d.ts","sourceRoot":"","sources":["../../src/pipeline/qualification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAwBtE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CA2D9E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMvD"}
|