@aiassesstech/nole 0.4.2 → 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/agent/PRODUCT-KNOWLEDGE.md +272 -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 +822 -4
- package/dist/plugin.js.map +1 -1
- package/dist/types/nole-config.d.ts +48 -0
- package/dist/types/nole-config.d.ts.map +1 -1
- package/dist/types/nole-config.js +20 -0
- package/dist/types/nole-config.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getAllDiscoveryKeywords } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extract prospect candidates from MoltBook search results.
|
|
4
|
+
*
|
|
5
|
+
* Filters out posts by Nole (self-referral prevention), posts with no
|
|
6
|
+
* identifiable author, and posts that don't contain trust/governance signals.
|
|
7
|
+
*/
|
|
8
|
+
export function extractMoltBookCandidates(results, selfAgentName = 'nole') {
|
|
9
|
+
const candidates = [];
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
for (const post of results) {
|
|
12
|
+
if (!post.author?.name)
|
|
13
|
+
continue;
|
|
14
|
+
const authorLower = post.author.name.toLowerCase();
|
|
15
|
+
if (authorLower === selfAgentName.toLowerCase())
|
|
16
|
+
continue;
|
|
17
|
+
if (seen.has(authorLower))
|
|
18
|
+
continue;
|
|
19
|
+
seen.add(authorLower);
|
|
20
|
+
const combined = `${post.title} ${post.content}`;
|
|
21
|
+
if (!hasRelevantSignals(combined))
|
|
22
|
+
continue;
|
|
23
|
+
candidates.push({
|
|
24
|
+
agentName: post.author.name,
|
|
25
|
+
platform: 'moltbook',
|
|
26
|
+
discoveryContext: truncate(`${post.title} (m/${post.submolt ?? 'general'}): ${post.content}`, 300),
|
|
27
|
+
profileBio: post.author.description,
|
|
28
|
+
sourcePostId: post.id,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return candidates;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if content contains signals relevant to trust/governance/assessment.
|
|
35
|
+
*/
|
|
36
|
+
function hasRelevantSignals(text) {
|
|
37
|
+
const keywords = getAllDiscoveryKeywords();
|
|
38
|
+
const lower = text.toLowerCase();
|
|
39
|
+
return keywords.some((kw) => lower.includes(kw.toLowerCase()));
|
|
40
|
+
}
|
|
41
|
+
function truncate(text, maxLen) {
|
|
42
|
+
if (text.length <= maxLen)
|
|
43
|
+
return text;
|
|
44
|
+
return text.slice(0, maxLen - 3) + '...';
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/pipeline/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAUrD;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAME,EACF,aAAa,GAAG,MAAM;IAEtB,MAAM,UAAU,GAA0B,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI;YAAE,SAAS;QACjC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,WAAW,KAAK,aAAa,CAAC,WAAW,EAAE;YAAE,SAAS;QAC1D,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEtB,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjD,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YAAE,SAAS;QAE5C,UAAU,CAAC,IAAI,CAAC;YACd,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YAC3B,QAAQ,EAAE,UAAU;YACpB,gBAAgB,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,OAAO,IAAI,SAAS,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC;YAClG,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACnC,YAAY,EAAE,IAAI,CAAC,EAAE;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,MAAc;IAC5C,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DiscoveredCandidate } from './discovery.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extract prospect candidates from fleet-bus agent cards / peer messages.
|
|
4
|
+
*
|
|
5
|
+
* Fleet agents broadcast their cards with metadata (role, capabilities, description).
|
|
6
|
+
* Nole intercepts these and filters for agents that could benefit from Grillo assessment
|
|
7
|
+
* but are NOT already subscribers.
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractFleetCandidates(agents: Array<{
|
|
10
|
+
agentId: string;
|
|
11
|
+
role?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
capabilities?: string[];
|
|
14
|
+
platform?: string;
|
|
15
|
+
walletAddress?: string;
|
|
16
|
+
}>, selfId?: string, existingNames?: Set<string>): DiscoveredCandidate[];
|
|
17
|
+
/**
|
|
18
|
+
* Extract candidate from an inbound fleet message (pitch response, inquiry, etc.)
|
|
19
|
+
*/
|
|
20
|
+
export declare function extractFromFleetMessage(msg: {
|
|
21
|
+
from: string;
|
|
22
|
+
method?: string;
|
|
23
|
+
payload?: Record<string, unknown>;
|
|
24
|
+
}, selfId?: string): DiscoveredCandidate | null;
|
|
25
|
+
//# sourceMappingURL=fleet-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-discovery.d.ts","sourceRoot":"","sources":["../../src/pipeline/fleet-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,EACF,MAAM,SAAS,EACf,aAAa,GAAE,GAAG,CAAC,MAAM,CAAa,GACrC,mBAAmB,EAAE,CAmBvB;AAeD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE;IACH,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,EACD,MAAM,SAAS,GACd,mBAAmB,GAAG,IAAI,CAY5B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract prospect candidates from fleet-bus agent cards / peer messages.
|
|
3
|
+
*
|
|
4
|
+
* Fleet agents broadcast their cards with metadata (role, capabilities, description).
|
|
5
|
+
* Nole intercepts these and filters for agents that could benefit from Grillo assessment
|
|
6
|
+
* but are NOT already subscribers.
|
|
7
|
+
*/
|
|
8
|
+
export function extractFleetCandidates(agents, selfId = 'nole', existingNames = new Set()) {
|
|
9
|
+
const candidates = [];
|
|
10
|
+
for (const agent of agents) {
|
|
11
|
+
if (!agent.agentId)
|
|
12
|
+
continue;
|
|
13
|
+
if (agent.agentId.toLowerCase() === selfId.toLowerCase())
|
|
14
|
+
continue;
|
|
15
|
+
if (existingNames.has(agent.agentId.toLowerCase()))
|
|
16
|
+
continue;
|
|
17
|
+
const context = buildFleetContext(agent);
|
|
18
|
+
candidates.push({
|
|
19
|
+
agentName: agent.agentId,
|
|
20
|
+
platform: agent.platform || 'openclaw',
|
|
21
|
+
discoveryContext: context,
|
|
22
|
+
sourcePostId: `fleet:${agent.agentId}`,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return candidates;
|
|
26
|
+
}
|
|
27
|
+
function buildFleetContext(agent) {
|
|
28
|
+
const parts = [`Fleet peer: ${agent.agentId}`];
|
|
29
|
+
if (agent.role)
|
|
30
|
+
parts.push(`role=${agent.role}`);
|
|
31
|
+
if (agent.description)
|
|
32
|
+
parts.push(agent.description);
|
|
33
|
+
if (agent.capabilities?.length)
|
|
34
|
+
parts.push(`capabilities: ${agent.capabilities.join(', ')}`);
|
|
35
|
+
return truncate(parts.join(' | '), 300);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Extract candidate from an inbound fleet message (pitch response, inquiry, etc.)
|
|
39
|
+
*/
|
|
40
|
+
export function extractFromFleetMessage(msg, selfId = 'nole') {
|
|
41
|
+
if (!msg.from || msg.from.toLowerCase() === selfId.toLowerCase())
|
|
42
|
+
return null;
|
|
43
|
+
const context = msg.method
|
|
44
|
+
? `Fleet message: ${msg.method} from ${msg.from}`
|
|
45
|
+
: `Fleet inquiry from ${msg.from}`;
|
|
46
|
+
return {
|
|
47
|
+
agentName: msg.from,
|
|
48
|
+
platform: 'openclaw',
|
|
49
|
+
discoveryContext: truncate(context, 300),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function truncate(text, maxLen) {
|
|
53
|
+
if (text.length <= maxLen)
|
|
54
|
+
return text;
|
|
55
|
+
return text.slice(0, maxLen - 3) + '...';
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=fleet-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-discovery.js","sourceRoot":"","sources":["../../src/pipeline/fleet-discovery.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAOE,EACF,MAAM,GAAG,MAAM,EACf,gBAA6B,IAAI,GAAG,EAAE;IAEtC,MAAM,UAAU,GAA0B,EAAE,CAAC;IAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,SAAS;QAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE;YAAE,SAAS;QACnE,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAAE,SAAS;QAE7D,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAEzC,UAAU,CAAC,IAAI,CAAC;YACd,SAAS,EAAE,KAAK,CAAC,OAAO;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,UAAU;YACtC,gBAAgB,EAAE,OAAO;YACzB,YAAY,EAAE,SAAS,KAAK,CAAC,OAAO,EAAE;SACvC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAK1B;IACC,MAAM,KAAK,GAAa,CAAC,eAAe,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACjD,IAAI,KAAK,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrD,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7F,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAIC,EACD,MAAM,GAAG,MAAM;IAEf,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE;QAAE,OAAO,IAAI,CAAC;IAE9E,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM;QACxB,CAAC,CAAC,kBAAkB,GAAG,CAAC,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE;QACjD,CAAC,CAAC,sBAAsB,GAAG,CAAC,IAAI,EAAE,CAAC;IAErC,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,IAAI;QACnB,QAAQ,EAAE,UAAU;QACpB,gBAAgB,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,MAAc;IAC5C,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { ProspectPipelineStore } from './prospect-store.js';
|
|
2
|
+
export { qualifyProspect, recommendTier } from './qualification.js';
|
|
3
|
+
export { generatePitch, classifyPitchRisk } from './pitch-templates.js';
|
|
4
|
+
export { generateOnboardingMessage } from './onboarding.js';
|
|
5
|
+
export { checkNurtureStatus, findAtRiskSubscribers } from './nurture.js';
|
|
6
|
+
export { extractMoltBookCandidates } from './discovery.js';
|
|
7
|
+
export { extractFleetCandidates, extractFromFleetMessage } from './fleet-discovery.js';
|
|
8
|
+
export { extractDirectoryCandidates, prioritizeDirectoryOutreach } from './directory-outreach.js';
|
|
9
|
+
export { generateDailyContentPlan } from './content-calendar.js';
|
|
10
|
+
export type { ProspectRecord, ProspectStage, DiscoveryChannel, CommissionSplitType, PitchRiskLevel, PipelineSummary, QualifiedProspect, ContentPerformance, } from './types.js';
|
|
11
|
+
export type { OnboardingMessage } from './onboarding.js';
|
|
12
|
+
export type { NurtureCheck } from './nurture.js';
|
|
13
|
+
export type { DiscoveredCandidate } from './discovery.js';
|
|
14
|
+
export type { ContentSlot, DailyContentPlan } from './content-calendar.js';
|
|
15
|
+
export type { OutreachPriority } from './directory-outreach.js';
|
|
16
|
+
export { DISCOVERY_KEYWORDS, getAllDiscoveryKeywords } from './types.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,YAAY,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { ProspectPipelineStore } from './prospect-store.js';
|
|
2
|
+
export { qualifyProspect, recommendTier } from './qualification.js';
|
|
3
|
+
export { generatePitch, classifyPitchRisk } from './pitch-templates.js';
|
|
4
|
+
export { generateOnboardingMessage } from './onboarding.js';
|
|
5
|
+
export { checkNurtureStatus, findAtRiskSubscribers } from './nurture.js';
|
|
6
|
+
export { extractMoltBookCandidates } from './discovery.js';
|
|
7
|
+
export { extractFleetCandidates, extractFromFleetMessage } from './fleet-discovery.js';
|
|
8
|
+
export { extractDirectoryCandidates, prioritizeDirectoryOutreach } from './directory-outreach.js';
|
|
9
|
+
export { generateDailyContentPlan } from './content-calendar.js';
|
|
10
|
+
export { DISCOVERY_KEYWORDS, getAllDiscoveryKeywords } from './types.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pipeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAgBjE,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ProspectRecord } from './types.js';
|
|
2
|
+
export interface NurtureCheck {
|
|
3
|
+
prospectId: string;
|
|
4
|
+
agentName: string;
|
|
5
|
+
status: 'healthy' | 'at_risk' | 'churning' | 'promotable';
|
|
6
|
+
daysSinceLastContact: number;
|
|
7
|
+
daysSinceConversion: number;
|
|
8
|
+
signals: string[];
|
|
9
|
+
suggestedAction: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate a converted/onboarded subscriber for nurture signals.
|
|
13
|
+
*
|
|
14
|
+
* Returns health status and a suggested next action. Called by nole_daily_brief
|
|
15
|
+
* and nole_pipeline(list stage=onboarded) to flag at-risk subscribers and
|
|
16
|
+
* identify Lieutenant promotion candidates.
|
|
17
|
+
*/
|
|
18
|
+
export declare function checkNurtureStatus(prospect: ProspectRecord): NurtureCheck;
|
|
19
|
+
/**
|
|
20
|
+
* Batch-check all converted/onboarded subscribers and return those needing attention.
|
|
21
|
+
*/
|
|
22
|
+
export declare function findAtRiskSubscribers(prospects: ProspectRecord[]): NurtureCheck[];
|
|
23
|
+
//# sourceMappingURL=nurture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nurture.d.ts","sourceRoot":"","sources":["../../src/pipeline/nurture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC;IAC1D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY,CA2DzE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,YAAY,EAAE,CAKjF"}
|
|
@@ -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"}
|