a2acalling 0.6.19 → 0.6.21
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/SKILL.md +19 -3
- package/bin/cli.js +3 -16
- package/package.json +1 -1
- package/src/lib/disclosure.js +100 -158
- package/src/lib/prompt-template.js +32 -40
- package/src/routes/dashboard.js +7 -12
- package/src/server.js +1 -5
package/SKILL.md
CHANGED
|
@@ -42,7 +42,20 @@ a2a quickstart # run onboarding
|
|
|
42
42
|
a2a quickstart --force # re-run from scratch
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
After the onboarding walkthrough prints, scan
|
|
45
|
+
After the onboarding walkthrough prints, scan ALL available context to build the disclosure JSON:
|
|
46
|
+
|
|
47
|
+
**Primary sources:**
|
|
48
|
+
- USER.md, SOUL.md — owner identity, interests, values
|
|
49
|
+
- memory/*.md — may contain relevant context
|
|
50
|
+
|
|
51
|
+
**If workspace files are missing/empty, also scan:**
|
|
52
|
+
- ~/.gitconfig — name, email hints
|
|
53
|
+
- Environment: whoami, hostname, $USER
|
|
54
|
+
- ~/.config/ — installed tools reveal work domain
|
|
55
|
+
- Installed CLIs — infer developer/devops/data roles
|
|
56
|
+
- System hostname — may indicate project or role
|
|
57
|
+
|
|
58
|
+
Build disclosure tiers from whatever context exists, then submit:
|
|
46
59
|
|
|
47
60
|
```bash
|
|
48
61
|
a2a quickstart --submit '<json>'
|
|
@@ -101,13 +114,16 @@ a2a quickstart --port 3001 --interactive
|
|
|
101
114
|
|
|
102
115
|
If reverse proxy/ingress is required, Quickstart will stop and ask for explicit confirmation (`--confirm-ingress`).
|
|
103
116
|
|
|
104
|
-
Full disclosure onboarding (manifest editing) remains available below: it generates a disclosure manifest that controls what topics your agent
|
|
117
|
+
Full disclosure onboarding (manifest editing) remains available below: it generates a disclosure manifest that controls what topics your agent discusses or redirects during A2A calls — scoped by access tier (public, friends, family).
|
|
105
118
|
|
|
106
119
|
This onboarding is required before the first `/a2a call`. The owner must approve permissions first.
|
|
107
120
|
|
|
108
121
|
Flow:
|
|
109
122
|
|
|
110
|
-
1. Scan
|
|
123
|
+
1. Scan ALL available context to generate a default manifest:
|
|
124
|
+
- Primary: USER.md, SOUL.md, memory/*.md
|
|
125
|
+
- Fallback: ~/.gitconfig, env vars, hostname, installed tools
|
|
126
|
+
- Infer owner's domain from system state if workspace is empty
|
|
111
127
|
2. Present the manifest as a numbered text list grouped by tier:
|
|
112
128
|
|
|
113
129
|
```
|
package/bin/cli.js
CHANGED
|
@@ -336,23 +336,10 @@ async function handleDisclosureSubmit(args, commandLabel = 'onboard') {
|
|
|
336
336
|
// Sync tier config from manifest
|
|
337
337
|
const manifest = result.manifest;
|
|
338
338
|
|
|
339
|
-
// Helper to extract topic names
|
|
339
|
+
// Helper to extract topic names
|
|
340
340
|
function getTierTopics(tierData) {
|
|
341
|
-
if (!tierData) return [];
|
|
342
|
-
|
|
343
|
-
if (Array.isArray(tierData.topics)) {
|
|
344
|
-
return tierData.topics.map(t => String(t && t.topic || '').trim()).filter(Boolean);
|
|
345
|
-
}
|
|
346
|
-
// Legacy format: lead_with + discuss_freely + deflect
|
|
347
|
-
const out = [];
|
|
348
|
-
for (const section of [tierData.lead_with, tierData.discuss_freely, tierData.deflect]) {
|
|
349
|
-
if (!Array.isArray(section)) continue;
|
|
350
|
-
for (const item of section) {
|
|
351
|
-
const t = String(item && item.topic || '').trim();
|
|
352
|
-
if (t && !out.includes(t)) out.push(t);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return out;
|
|
341
|
+
if (!tierData || !Array.isArray(tierData.topics)) return [];
|
|
342
|
+
return tierData.topics.map(t => String(t && t.topic || '').trim()).filter(Boolean);
|
|
356
343
|
}
|
|
357
344
|
|
|
358
345
|
// Get tiers data (support both new 'tiers' key and legacy 'topics' key)
|
package/package.json
CHANGED
package/src/lib/disclosure.js
CHANGED
|
@@ -172,24 +172,9 @@ function getTopicsForTier(tier) {
|
|
|
172
172
|
|
|
173
173
|
for (const t of tiersToMerge) {
|
|
174
174
|
const tierData = tiers[t] || {};
|
|
175
|
-
|
|
176
|
-
if (tierData.topics) {
|
|
177
|
-
merged.topics.push(...tierData.topics);
|
|
178
|
-
} else {
|
|
179
|
-
// Legacy format fallback
|
|
180
|
-
if (tierData.lead_with) merged.topics.push(...tierData.lead_with);
|
|
181
|
-
if (tierData.discuss_freely) merged.topics.push(...tierData.discuss_freely);
|
|
182
|
-
}
|
|
175
|
+
if (tierData.topics) merged.topics.push(...tierData.topics);
|
|
183
176
|
if (tierData.objectives) merged.objectives.push(...tierData.objectives);
|
|
184
|
-
if (tierData.do_not_discuss)
|
|
185
|
-
merged.do_not_discuss.push(...tierData.do_not_discuss);
|
|
186
|
-
} else if (tierData.deflect) {
|
|
187
|
-
// Legacy format fallback
|
|
188
|
-
merged.do_not_discuss.push(...tierData.deflect.map(d => ({
|
|
189
|
-
topic: d.topic,
|
|
190
|
-
reason: d.detail || d.reason
|
|
191
|
-
})));
|
|
192
|
-
}
|
|
177
|
+
if (tierData.do_not_discuss) merged.do_not_discuss.push(...tierData.do_not_discuss);
|
|
193
178
|
}
|
|
194
179
|
|
|
195
180
|
// Remove do_not_discuss items that appear in topics (higher tiers promote them)
|
|
@@ -229,11 +214,7 @@ function formatTopicsForPrompt(tierTopics) {
|
|
|
229
214
|
doNotDiscuss: formatDoNotDiscuss(tierTopics.do_not_discuss),
|
|
230
215
|
neverDisclose: tierTopics.never_disclose?.length
|
|
231
216
|
? tierTopics.never_disclose.map(item => ` - ${item}`).join('\n')
|
|
232
|
-
: ' (none specified)'
|
|
233
|
-
// Legacy compatibility
|
|
234
|
-
leadWithTopics: formatTopicList(tierTopics.topics?.slice(0, 3) || tierTopics.lead_with),
|
|
235
|
-
discussFreelyTopics: formatTopicList(tierTopics.topics?.slice(3) || tierTopics.discuss_freely),
|
|
236
|
-
deflectTopics: formatDoNotDiscuss(tierTopics.do_not_discuss || tierTopics.deflect)
|
|
217
|
+
: ' (none specified)'
|
|
237
218
|
};
|
|
238
219
|
}
|
|
239
220
|
|
|
@@ -405,102 +386,72 @@ function validateDisclosureSubmission(data) {
|
|
|
405
386
|
errors.push(`Unknown tiers: ${extraTiers.join(', ')} — only public, friends, family are allowed`);
|
|
406
387
|
}
|
|
407
388
|
|
|
408
|
-
// Detect format: new (topics/objectives/do_not_discuss) or legacy (lead_with/discuss_freely/deflect)
|
|
409
|
-
const isNewFormat = tiersData.public && (
|
|
410
|
-
Array.isArray(tiersData.public.topics) ||
|
|
411
|
-
Array.isArray(tiersData.public.objectives) ||
|
|
412
|
-
Array.isArray(tiersData.public.do_not_discuss)
|
|
413
|
-
);
|
|
414
|
-
|
|
415
389
|
const LIST_LIMITS = { topics: 15, objectives: 8, do_not_discuss: 10 };
|
|
416
390
|
|
|
417
391
|
for (const tier of TIER_HIERARCHY) {
|
|
418
392
|
const tierData = tiersData[tier];
|
|
419
393
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if (tierData.topics
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
394
|
+
// Validate topics array
|
|
395
|
+
if (tierData.topics !== undefined) {
|
|
396
|
+
if (!Array.isArray(tierData.topics)) {
|
|
397
|
+
errors.push(`tiers.${tier}.topics must be an array`);
|
|
398
|
+
} else {
|
|
399
|
+
if (tierData.topics.length > LIST_LIMITS.topics) {
|
|
400
|
+
errors.push(`tiers.${tier}.topics has ${tierData.topics.length} items — max ${LIST_LIMITS.topics}`);
|
|
401
|
+
}
|
|
402
|
+
for (let i = 0; i < tierData.topics.length; i++) {
|
|
403
|
+
const item = tierData.topics[i];
|
|
404
|
+
if (!item || typeof item !== 'object' || typeof item.topic !== 'string') {
|
|
405
|
+
errors.push(`tiers.${tier}.topics[${i}]: must have "topic" (string) and "description" (string)`);
|
|
406
|
+
continue;
|
|
428
407
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
if (!item || typeof item !== 'object' || typeof item.topic !== 'string') {
|
|
432
|
-
errors.push(`tiers.${tier}.topics[${i}]: must have "topic" (string) and "description" (string)`);
|
|
433
|
-
continue;
|
|
434
|
-
}
|
|
435
|
-
if (item.topic.trim().length === 0) {
|
|
436
|
-
errors.push(`tiers.${tier}.topics[${i}].topic must not be empty`);
|
|
437
|
-
}
|
|
438
|
-
if (item.topic.length > 160) {
|
|
439
|
-
errors.push(`tiers.${tier}.topics[${i}]: topic exceeds 160 chars`);
|
|
440
|
-
}
|
|
441
|
-
const desc = item.description || '';
|
|
442
|
-
if (desc.length > 500) {
|
|
443
|
-
errors.push(`tiers.${tier}.topics[${i}]: description exceeds 500 chars`);
|
|
444
|
-
}
|
|
408
|
+
if (item.topic.trim().length === 0) {
|
|
409
|
+
errors.push(`tiers.${tier}.topics[${i}].topic must not be empty`);
|
|
445
410
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
if (tierData.objectives !== undefined) {
|
|
450
|
-
if (!Array.isArray(tierData.objectives)) {
|
|
451
|
-
errors.push(`tiers.${tier}.objectives must be an array`);
|
|
452
|
-
} else {
|
|
453
|
-
if (tierData.objectives.length > LIST_LIMITS.objectives) {
|
|
454
|
-
errors.push(`tiers.${tier}.objectives has ${tierData.objectives.length} items — max ${LIST_LIMITS.objectives}`);
|
|
411
|
+
if (item.topic.length > 160) {
|
|
412
|
+
errors.push(`tiers.${tier}.topics[${i}]: topic exceeds 160 chars`);
|
|
455
413
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
errors.push(`tiers.${tier}.objectives[${i}]: must have "objective" (string) and "description" (string)`);
|
|
460
|
-
continue;
|
|
461
|
-
}
|
|
462
|
-
if (item.objective.trim().length === 0) {
|
|
463
|
-
errors.push(`tiers.${tier}.objectives[${i}].objective must not be empty`);
|
|
464
|
-
}
|
|
414
|
+
const desc = item.description || '';
|
|
415
|
+
if (desc.length > 500) {
|
|
416
|
+
errors.push(`tiers.${tier}.topics[${i}]: description exceeds 500 chars`);
|
|
465
417
|
}
|
|
466
418
|
}
|
|
467
419
|
}
|
|
420
|
+
}
|
|
468
421
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
|
|
422
|
+
// Validate objectives array
|
|
423
|
+
if (tierData.objectives !== undefined) {
|
|
424
|
+
if (!Array.isArray(tierData.objectives)) {
|
|
425
|
+
errors.push(`tiers.${tier}.objectives must be an array`);
|
|
426
|
+
} else {
|
|
427
|
+
if (tierData.objectives.length > LIST_LIMITS.objectives) {
|
|
428
|
+
errors.push(`tiers.${tier}.objectives has ${tierData.objectives.length} items — max ${LIST_LIMITS.objectives}`);
|
|
429
|
+
}
|
|
430
|
+
for (let i = 0; i < tierData.objectives.length; i++) {
|
|
431
|
+
const item = tierData.objectives[i];
|
|
432
|
+
if (!item || typeof item !== 'object' || typeof item.objective !== 'string') {
|
|
433
|
+
errors.push(`tiers.${tier}.objectives[${i}]: must have "objective" (string) and "description" (string)`);
|
|
434
|
+
continue;
|
|
475
435
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if (!item || typeof item !== 'object' || typeof item.topic !== 'string') {
|
|
479
|
-
errors.push(`tiers.${tier}.do_not_discuss[${i}]: must have "topic" (string) and "reason" (string)`);
|
|
480
|
-
}
|
|
436
|
+
if (item.objective.trim().length === 0) {
|
|
437
|
+
errors.push(`tiers.${tier}.objectives[${i}].objective must not be empty`);
|
|
481
438
|
}
|
|
482
439
|
}
|
|
483
440
|
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
if (tierData[cat].length > LEGACY_LIMITS[cat]) {
|
|
494
|
-
errors.push(`topics.${tier}.${cat} has ${tierData[cat].length} items — max ${LEGACY_LIMITS[cat]}`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Validate do_not_discuss array
|
|
444
|
+
if (tierData.do_not_discuss !== undefined) {
|
|
445
|
+
if (!Array.isArray(tierData.do_not_discuss)) {
|
|
446
|
+
errors.push(`tiers.${tier}.do_not_discuss must be an array`);
|
|
447
|
+
} else {
|
|
448
|
+
if (tierData.do_not_discuss.length > LIST_LIMITS.do_not_discuss) {
|
|
449
|
+
errors.push(`tiers.${tier}.do_not_discuss has ${tierData.do_not_discuss.length} items — max ${LIST_LIMITS.do_not_discuss}`);
|
|
495
450
|
}
|
|
496
|
-
for (let i = 0; i < tierData
|
|
497
|
-
const item = tierData[
|
|
451
|
+
for (let i = 0; i < tierData.do_not_discuss.length; i++) {
|
|
452
|
+
const item = tierData.do_not_discuss[i];
|
|
498
453
|
if (!item || typeof item !== 'object' || typeof item.topic !== 'string') {
|
|
499
|
-
errors.push(`
|
|
500
|
-
continue;
|
|
501
|
-
}
|
|
502
|
-
if (item.topic.trim().length === 0) {
|
|
503
|
-
errors.push(`topics.${tier}.${cat}[${i}].topic must not be empty`);
|
|
454
|
+
errors.push(`tiers.${tier}.do_not_discuss[${i}]: must have "topic" (string) and "reason" (string)`);
|
|
504
455
|
}
|
|
505
456
|
}
|
|
506
457
|
}
|
|
@@ -538,63 +489,38 @@ function validateDisclosureSubmission(data) {
|
|
|
538
489
|
return { valid: false, manifest: null, errors };
|
|
539
490
|
}
|
|
540
491
|
|
|
541
|
-
// Rebuild clean structure
|
|
492
|
+
// Rebuild clean structure
|
|
542
493
|
const now = new Date().toISOString();
|
|
543
494
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}))
|
|
561
|
-
};
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const manifest = {
|
|
565
|
-
version: 2,
|
|
566
|
-
generated_at: now,
|
|
567
|
-
updated_at: now,
|
|
568
|
-
tiers: cleanTiers,
|
|
569
|
-
never_disclose: data.never_disclose || ['API keys', 'Other users\' data', 'Financial figures'],
|
|
570
|
-
personality_notes: data.personality_notes || ''
|
|
495
|
+
// Build clean manifest with new format only
|
|
496
|
+
const cleanTiers = {};
|
|
497
|
+
for (const tier of TIER_HIERARCHY) {
|
|
498
|
+
cleanTiers[tier] = {
|
|
499
|
+
topics: (tiersData[tier].topics || []).map(item => ({
|
|
500
|
+
topic: item.topic,
|
|
501
|
+
description: item.description || ''
|
|
502
|
+
})),
|
|
503
|
+
objectives: (tiersData[tier].objectives || []).map(item => ({
|
|
504
|
+
objective: item.objective,
|
|
505
|
+
description: item.description || ''
|
|
506
|
+
})),
|
|
507
|
+
do_not_discuss: (tiersData[tier].do_not_discuss || []).map(item => ({
|
|
508
|
+
topic: item.topic,
|
|
509
|
+
reason: item.reason || ''
|
|
510
|
+
}))
|
|
571
511
|
};
|
|
512
|
+
}
|
|
572
513
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
topic: item.topic,
|
|
582
|
-
detail: item.detail || ''
|
|
583
|
-
}));
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
const manifest = {
|
|
588
|
-
version: 1,
|
|
589
|
-
generated_at: now,
|
|
590
|
-
updated_at: now,
|
|
591
|
-
topics: cleanTopics,
|
|
592
|
-
never_disclose: data.never_disclose || ['API keys', 'Other users\' data', 'Financial figures'],
|
|
593
|
-
personality_notes: data.personality_notes || ''
|
|
594
|
-
};
|
|
514
|
+
const manifest = {
|
|
515
|
+
version: 2,
|
|
516
|
+
generated_at: now,
|
|
517
|
+
updated_at: now,
|
|
518
|
+
tiers: cleanTiers,
|
|
519
|
+
never_disclose: data.never_disclose || ['API keys', 'Other users\' data', 'Financial figures'],
|
|
520
|
+
personality_notes: data.personality_notes || ''
|
|
521
|
+
};
|
|
595
522
|
|
|
596
|
-
|
|
597
|
-
}
|
|
523
|
+
return { valid: true, manifest, errors: [] };
|
|
598
524
|
}
|
|
599
525
|
|
|
600
526
|
/**
|
|
@@ -654,15 +580,31 @@ function buildExtractionPrompt(availableFiles) {
|
|
|
654
580
|
.join('\n') || ' (none detected)';
|
|
655
581
|
fileSection = `### Available workspace files\n${fileList}\n\nRead the available files above and extract disclosure topics.`;
|
|
656
582
|
} else {
|
|
657
|
-
fileSection = `###
|
|
583
|
+
fileSection = `### Context sources to scan
|
|
584
|
+
|
|
585
|
+
**Primary sources (workspace files):**
|
|
658
586
|
- USER.md — owner identity, bio, interests
|
|
659
587
|
- SOUL.md — values, personality, communication style
|
|
660
|
-
- HEARTBEAT.md — skip this (contains agent tasks, not disclosure topics)
|
|
661
|
-
- SKILL.md — skip this (contains agent instructions)
|
|
662
|
-
- CLAUDE.md — skip this (contains agent instructions)
|
|
663
588
|
- memory/*.md — may contain relevant context
|
|
664
|
-
|
|
665
|
-
|
|
589
|
+
- Skip HEARTBEAT.md, SKILL.md, CLAUDE.md (agent instructions, not owner info)
|
|
590
|
+
|
|
591
|
+
**If workspace files are missing or empty, scan these additional sources:**
|
|
592
|
+
- ~/.gitconfig — name, email, identity hints
|
|
593
|
+
- Environment: whoami, hostname, $USER, $HOME
|
|
594
|
+
- ~/.config/ — installed tools hint at owner's work
|
|
595
|
+
- ~/.ssh/config — project/server names may reveal domains
|
|
596
|
+
- Any README.md files in common locations
|
|
597
|
+
- Shell history patterns (languages, tools used)
|
|
598
|
+
- Installed CLIs (what's in PATH)
|
|
599
|
+
|
|
600
|
+
**Inference from system state:**
|
|
601
|
+
- Programming languages installed → likely a developer
|
|
602
|
+
- Cloud CLIs (aws, gcloud, az) → infrastructure/devops
|
|
603
|
+
- Design tools → creative work
|
|
604
|
+
- Data tools (jupyter, pandas) → data science
|
|
605
|
+
- Server hostname → may indicate role or project
|
|
606
|
+
|
|
607
|
+
Use ALL available context to build a reasonable disclosure profile. If truly nothing exists, create a minimal placeholder with "New agent setup - owner details pending" and suggest what info the owner should provide.`;
|
|
666
608
|
}
|
|
667
609
|
|
|
668
610
|
const jsonBlock = `\`\`\`json
|
|
@@ -49,9 +49,9 @@ function buildConnectionPrompt(options) {
|
|
|
49
49
|
} = options;
|
|
50
50
|
|
|
51
51
|
const {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
topics = ' (none specified)',
|
|
53
|
+
objectives = ' (none specified)',
|
|
54
|
+
doNotDiscuss = ' (none specified)',
|
|
55
55
|
neverDisclose = ' (none specified)'
|
|
56
56
|
} = tierTopics || {};
|
|
57
57
|
|
|
@@ -62,17 +62,16 @@ Your job is NOT to answer questions and hang up. Your job is to have a real conv
|
|
|
62
62
|
|
|
63
63
|
== WHAT YOU BRING TO THE TABLE ==
|
|
64
64
|
|
|
65
|
-
${ownerName}
|
|
66
|
-
${
|
|
65
|
+
${ownerName}'s topics of interest:
|
|
66
|
+
${topics}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
${discussFreelyTopics}
|
|
68
|
+
== OBJECTIVES FOR THIS CALL ==
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
${objectives !== ' (none specified)'
|
|
71
|
+
? `What ${ownerName} wants to achieve:\n${objectives}`
|
|
72
|
+
: (tierGoals && tierGoals.length > 0
|
|
73
|
+
? `At the ${accessTier} access level, ${ownerName}'s objectives are:\n${formatList(tierGoals)}`
|
|
74
|
+
: `No specific objectives configured. Focus on general discovery and relationship building.`)}
|
|
76
75
|
|
|
77
76
|
== WHAT THEY SHARED WITH YOU ==
|
|
78
77
|
|
|
@@ -123,16 +122,13 @@ PACING RULES:
|
|
|
123
122
|
|
|
124
123
|
Access level for this call: ${accessTier}
|
|
125
124
|
|
|
126
|
-
|
|
127
|
-
${
|
|
128
|
-
|
|
129
|
-
DISCUSS FREELY (share when relevant):
|
|
130
|
-
${discussFreelyTopics}
|
|
125
|
+
TOPICS (discuss openly):
|
|
126
|
+
${topics}
|
|
131
127
|
|
|
132
|
-
|
|
133
|
-
${
|
|
128
|
+
DO NOT DISCUSS (redirect):
|
|
129
|
+
${doNotDiscuss}
|
|
134
130
|
|
|
135
|
-
When
|
|
131
|
+
When redirecting, don't say "I can't discuss that." Instead redirect naturally, acknowledge without detail, or suggest the owners connect directly.
|
|
136
132
|
|
|
137
133
|
NEVER disclose:
|
|
138
134
|
${neverDisclose}
|
|
@@ -178,9 +174,9 @@ function buildAdaptiveConnectionPrompt(options) {
|
|
|
178
174
|
} = options;
|
|
179
175
|
|
|
180
176
|
const {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
topics = ' (none specified)',
|
|
178
|
+
objectives = ' (none specified)',
|
|
179
|
+
doNotDiscuss = ' (none specified)',
|
|
184
180
|
neverDisclose = ' (none specified)'
|
|
185
181
|
} = tierTopics || {};
|
|
186
182
|
|
|
@@ -217,17 +213,16 @@ ${openQuestions}
|
|
|
217
213
|
|
|
218
214
|
== WHAT YOU BRING TO THE TABLE ==
|
|
219
215
|
|
|
220
|
-
${ownerName}
|
|
221
|
-
${
|
|
216
|
+
${ownerName}'s topics of interest:
|
|
217
|
+
${topics}
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
${discussFreelyTopics}
|
|
219
|
+
== OBJECTIVES FOR THIS CALL ==
|
|
225
220
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
221
|
+
${objectives !== ' (none specified)'
|
|
222
|
+
? `What ${ownerName} wants to achieve:\n${objectives}`
|
|
223
|
+
: (tierGoals && tierGoals.length > 0
|
|
224
|
+
? `At the ${accessTier} access level, ${ownerName}'s objectives are:\n${formatList(tierGoals)}`
|
|
225
|
+
: `No specific objectives configured. Focus on general discovery and relationship building.`)}
|
|
231
226
|
|
|
232
227
|
== WHAT THEY SHARED WITH YOU ==
|
|
233
228
|
|
|
@@ -265,16 +260,13 @@ Pacing:
|
|
|
265
260
|
|
|
266
261
|
Access level for this call: ${accessTier}
|
|
267
262
|
|
|
268
|
-
|
|
269
|
-
${
|
|
270
|
-
|
|
271
|
-
DISCUSS FREELY (share when relevant):
|
|
272
|
-
${discussFreelyTopics}
|
|
263
|
+
TOPICS (discuss openly):
|
|
264
|
+
${topics}
|
|
273
265
|
|
|
274
|
-
|
|
275
|
-
${
|
|
266
|
+
DO NOT DISCUSS (redirect):
|
|
267
|
+
${doNotDiscuss}
|
|
276
268
|
|
|
277
|
-
When
|
|
269
|
+
When redirecting, do not mention policy mechanics. Redirect naturally and suggest direct owner follow-up when needed.
|
|
278
270
|
|
|
279
271
|
NEVER disclose:
|
|
280
272
|
${neverDisclose}
|
package/src/routes/dashboard.js
CHANGED
|
@@ -1032,14 +1032,9 @@ function createDashboardApiRouter(options = {}) {
|
|
|
1032
1032
|
disclosure: configTier.disclosure || 'minimal',
|
|
1033
1033
|
examples: sanitizeStringArray(configTier.examples || [], 20, 120),
|
|
1034
1034
|
manifest: {
|
|
1035
|
-
|
|
1036
|
-
topics: manifestTier.topics || manifestTier.lead_with || [],
|
|
1035
|
+
topics: manifestTier.topics || [],
|
|
1037
1036
|
objectives: manifestTier.objectives || [],
|
|
1038
|
-
do_not_discuss: manifestTier.do_not_discuss ||
|
|
1039
|
-
// Legacy fields for backwards compatibility
|
|
1040
|
-
lead_with: manifestTier.lead_with || manifestTier.topics?.slice(0, 3) || [],
|
|
1041
|
-
discuss_freely: manifestTier.discuss_freely || manifestTier.topics?.slice(3) || [],
|
|
1042
|
-
deflect: manifestTier.deflect || manifestTier.do_not_discuss || []
|
|
1037
|
+
do_not_discuss: manifestTier.do_not_discuss || []
|
|
1043
1038
|
}
|
|
1044
1039
|
};
|
|
1045
1040
|
});
|
|
@@ -1087,11 +1082,11 @@ function createDashboardApiRouter(options = {}) {
|
|
|
1087
1082
|
|
|
1088
1083
|
if (body.manifest) {
|
|
1089
1084
|
const manifest = loadManifest();
|
|
1090
|
-
manifest.
|
|
1091
|
-
manifest.
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1085
|
+
manifest.tiers = manifest.tiers || {};
|
|
1086
|
+
manifest.tiers[tierId] = {
|
|
1087
|
+
topics: parseTopicObjects(body.manifest.topics),
|
|
1088
|
+
objectives: parseTopicObjects(body.manifest.objectives),
|
|
1089
|
+
do_not_discuss: parseTopicObjects(body.manifest.do_not_discuss)
|
|
1095
1090
|
};
|
|
1096
1091
|
saveManifest(manifest);
|
|
1097
1092
|
}
|
package/src/server.js
CHANGED
|
@@ -185,11 +185,7 @@ function extractSignalPhrases(text, pattern, maxItems = 3) {
|
|
|
185
185
|
function collectTopicKeywords(tierTopics) {
|
|
186
186
|
const keywords = new Set();
|
|
187
187
|
|
|
188
|
-
|
|
189
|
-
const topicsList = tierTopics?.topics || [
|
|
190
|
-
...(tierTopics?.lead_with || []),
|
|
191
|
-
...(tierTopics?.discuss_freely || [])
|
|
192
|
-
];
|
|
188
|
+
const topicsList = tierTopics?.topics || [];
|
|
193
189
|
const objectivesList = tierTopics?.objectives || [];
|
|
194
190
|
|
|
195
191
|
for (const item of topicsList) {
|