@f5xc-salesdemos/xcsh 18.51.0 → 18.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5xc-salesdemos/xcsh",
4
- "version": "18.51.0",
4
+ "version": "18.53.0",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/f5xc-salesdemos/xcsh",
7
7
  "author": "Can Boluk",
@@ -48,12 +48,12 @@
48
48
  "dependencies": {
49
49
  "@agentclientprotocol/sdk": "0.16.1",
50
50
  "@mozilla/readability": "^0.6",
51
- "@f5xc-salesdemos/xcsh-stats": "18.51.0",
52
- "@f5xc-salesdemos/pi-agent-core": "18.51.0",
53
- "@f5xc-salesdemos/pi-ai": "18.51.0",
54
- "@f5xc-salesdemos/pi-natives": "18.51.0",
55
- "@f5xc-salesdemos/pi-tui": "18.51.0",
56
- "@f5xc-salesdemos/pi-utils": "18.51.0",
51
+ "@f5xc-salesdemos/xcsh-stats": "18.53.0",
52
+ "@f5xc-salesdemos/pi-agent-core": "18.53.0",
53
+ "@f5xc-salesdemos/pi-ai": "18.53.0",
54
+ "@f5xc-salesdemos/pi-natives": "18.53.0",
55
+ "@f5xc-salesdemos/pi-tui": "18.53.0",
56
+ "@f5xc-salesdemos/pi-utils": "18.53.0",
57
57
  "@sinclair/typebox": "^0.34",
58
58
  "@xterm/headless": "^6.0",
59
59
  "ajv": "^8.18",
@@ -17,11 +17,9 @@ export const EXPERIMENT_MAX_LINES = 10;
17
17
  export const EXPERIMENT_MAX_BYTES = 4 * 1024;
18
18
  export const AUTORESEARCH_COMMITTABLE_FILES = [
19
19
  "autoresearch.md",
20
- "autoresearch.program.md",
21
20
  "autoresearch.sh",
22
21
  "autoresearch.checks.sh",
23
22
  "autoresearch.ideas.md",
24
- "SELF_AWARENESS.md",
25
23
  ] as const;
26
24
  export const AUTORESEARCH_LOCAL_STATE_FILES = ["autoresearch.jsonl"] as const;
27
25
  export const AUTORESEARCH_LOCAL_STATE_DIRECTORIES = [".autoresearch"] as const;
@@ -322,8 +322,6 @@ export const createAutoresearchExtension: ExtensionFactory = api => {
322
322
  const autoresearchMdPath = path.join(workDir, "autoresearch.md");
323
323
  const checksPath = path.join(workDir, "autoresearch.checks.sh");
324
324
  const ideasPath = path.join(workDir, "autoresearch.ideas.md");
325
- const programPath = path.join(workDir, "autoresearch.program.md");
326
- const selfAwarenessPath = path.join(workDir, "SELF_AWARENESS.md");
327
325
  const pendingRun =
328
326
  runtime.lastRunSummary ??
329
327
  (await readPendingRunSummary(workDir, collectLoggedRunNumbers(runtime.state.results)));
@@ -361,10 +359,6 @@ export const createAutoresearchExtension: ExtensionFactory = api => {
361
359
  checks_path: checksPath,
362
360
  has_ideas: fs.existsSync(ideasPath),
363
361
  ideas_path: ideasPath,
364
- has_program: fs.existsSync(programPath),
365
- program_path: programPath,
366
- has_self_awareness: fs.existsSync(selfAwarenessPath),
367
- self_awareness_path: selfAwarenessPath,
368
362
  current_segment: runtime.state.currentSegment + 1,
369
363
  current_segment_run_count: currentSegmentResults.length,
370
364
  has_baseline_metric: baselineMetric !== null,
@@ -19,22 +19,6 @@ Working directory:
19
19
  `{{working_dir}}`
20
20
 
21
21
  You are running an autonomous experiment loop. Keep iterating until the user interrupts you or the configured maximum iteration count is reached.
22
- {{#if has_program}}
23
-
24
- ### Local Playbook
25
-
26
- `autoresearch.program.md` exists at `{{program_path}}`.
27
-
28
- Use it as a repo-local strategy overlay for this session. `autoresearch.md` remains the source of truth for benchmark, scope, and constraints.
29
- {{/if}}
30
- {{#if has_self_awareness}}
31
-
32
- ### Self-Awareness Manifest
33
-
34
- `SELF_AWARENESS.md` exists at `{{self_awareness_path}}`.
35
-
36
- This document defines xcsh's mission, current capability inventory, evaluation dimensions, and known gaps. When the session goal involves self-evaluation, capability improvement, or SE workflow enhancement, read this document first — it is the ground truth for what xcsh is, what it should become, and how to measure progress.
37
- {{/if}}
38
22
  {{#if has_recent_results}}
39
23
 
40
24
  ### Current Segment Snapshot
@@ -89,11 +73,11 @@ An unlogged run artifact exists at `{{pending_run_directory}}`.
89
73
  - Update the notes whenever the strategy changes.
90
74
  - Keep durable conclusions in `autoresearch.md`.
91
75
  - Use `autoresearch.ideas.md` for deferred experiment ideas that are promising but not active yet.
92
- 3. Use `autoresearch.sh` as the canonical benchmark entrypoint.
93
- - If it does not exist yet, create it.
76
+ 3. The benchmark command in `autoresearch.md` is the canonical entrypoint.
77
+ - If it does not exist yet, create a benchmark script.
94
78
  - Make it print structured metric lines in the form `METRIC name=value`.
79
+ - Quality scores (`direction: higher`) are first-class — not every benchmark is a timing measurement.
95
80
  - Use the same workload every run unless you intentionally re-initialize with a new segment.
96
- - Keep the measurement harness, evaluator, and fixed benchmark inputs stable unless you intentionally start a new segment and document the change.
97
81
  4. Initialize the loop with `init_experiment` before the first logged run of a segment.
98
82
  - Pass `from_autoresearch_md: true` with only `name` to load the benchmark contract from `autoresearch.md` without mirroring every field in the tool call.
99
83
  - Use `abandon_unlogged_runs: true` only when you intentionally discard unlogged run artifacts and need a fresh segment (for example after a bad or obsolete benchmark directory).
@@ -105,7 +89,8 @@ An unlogged run artifact exists at `{{pending_run_directory}}`.
105
89
  - Run `run_experiment`.
106
90
  - Interpret the result honestly.
107
91
  - Call `log_experiment` after every run (it refreshes benchmark/scope fields from `autoresearch.md` before logging so keep validation matches the file on disk).
108
- - Use `run_experiment` with `force: true` only when you must override the segment benchmark command or skip the direct-`autoresearch.sh` rule.
92
+ - Use `run_experiment` with `force: true` only when you must override the segment benchmark command.
93
+ - After any code change, verify with `bun check:ts` or the project test suite before logging. A kept experiment that breaks the build is worse than a discarded one.
109
94
  - On `log_experiment`, `force: true` relaxes ASI requirements and allows keeping a primary-metric regression; prefer normal logging when possible.
110
95
  7. Keep the primary metric as the decision maker.
111
96
  - `keep` when the primary metric improves.
@@ -130,7 +115,7 @@ An unlogged run artifact exists at `{{pending_run_directory}}`.
130
115
 
131
116
  Your benchmark script SHOULD:
132
117
 
133
- - live at `autoresearch.sh`
118
+ - match the benchmark command from `autoresearch.md`
134
119
  - run from `{{working_dir}}`
135
120
  - fail with a non-zero exit status on invalid runs
136
121
  - print the primary metric as `METRIC {{default_metric_name}}=<number>` or another explicit metric name chosen during initialization
@@ -218,29 +203,15 @@ Resume from the existing notes:
218
203
 
219
204
  Before the first benchmark:
220
205
 
221
- - Write `autoresearch.md` with goal, benchmark command (must be a **direct** invocation of `autoresearch.sh`, e.g. `bash autoresearch.sh`), primary metric name and unit, direction (`lower` or `higher`), tradeoff metrics if relevant, files in scope, off limits, and constraints.
206
+ - Write `autoresearch.md` with goal, benchmark command, primary metric name and unit, direction (`lower` or `higher`), tradeoff metrics if relevant, files in scope, off limits, and constraints.
222
207
  - Add a short preflight section: prerequisites, one-time setup, and the comparability invariant that must stay fixed across runs.
223
208
  - Mark ground-truth evaluators, fixed datasets, and other measurement-critical files as off limits or hard constraints when they define the benchmark contract.
224
- - Write or update `autoresearch.program.md` when you learn durable heuristics, failure patterns, or repo-specific strategy for later resume turns.
225
- - Create `autoresearch.sh` as the canonical benchmark entrypoint; print the primary metric as `METRIC <name>=<number>` and optional secondary metrics as additional `METRIC` lines.
209
+ - Create a benchmark script; print the primary metric as `METRIC <name>=<number>` and optional secondary metrics as additional `METRIC` lines.
226
210
  - Optionally add `autoresearch.checks.sh` if correctness or quality needs a hard gate.
227
211
  - Call `init_experiment` with arguments that match `autoresearch.md` exactly (benchmark command, metric, unit, direction, scope paths, off limits, constraints).
228
212
  - Run and log the baseline.
229
- {{#if has_self_awareness}}
230
-
231
- #### SE Self-Evaluation Sessions
232
-
233
- When the goal involves evaluating or improving xcsh's sales engineering capabilities (not runtime code performance):
234
-
235
- - Read `SELF_AWARENESS.md` first to understand the current capability inventory and evaluation dimensions
236
- - Read `autoresearch.program.md` for the SE-specific evaluation strategy
237
- - Design the benchmark script (`autoresearch.sh`) to test the specific SE capability dimension — product knowledge accuracy, API reliability, prompt effectiveness, or workflow completeness
238
- - Use quality/accuracy scores as the primary metric (direction: `higher`) rather than timing metrics
239
- - Focus `Files in Scope` on the prompts, agent definitions, tool descriptions, or service modules relevant to the SE capability being evaluated
240
- - Record capability status changes in `SELF_AWARENESS.md` when experiments yield durable improvements
241
- {{/if}}
242
213
 
243
- Until `init_experiment` succeeds, only autoresearch control files (`autoresearch.md`, `autoresearch.sh`, `autoresearch.program.md`, `autoresearch.ideas.md`, `autoresearch.checks.sh`) may be edited; after initialization, respect Files in Scope from the contract.
214
+ Until `init_experiment` succeeds, only autoresearch control files (`autoresearch.md`, `autoresearch.sh`, `autoresearch.ideas.md`, `autoresearch.checks.sh`) may be edited; after initialization, respect Files in Scope from the contract.
244
215
 
245
216
  {{/if}}
246
217
  {{#if has_checks}}
@@ -206,12 +206,17 @@ export function renderAboutDoc(info: RuntimeBuildInfo, context: ContextStatus |
206
206
  "",
207
207
  "Sessions, MCP server/client, skills, TUI with themes, commit assistant,",
208
208
  "Python REPL, native shell/PTY, provider-agnostic LLM routing, slash commands,",
209
- "SSH remote execution, F5 XC federated product docs (llms.txt hierarchy),",
210
- "image generation and analysis.",
209
+ "SSH remote execution, image generation and analysis.",
210
+ "",
211
+ "SE specialization: F5 XC API integration (xcsh_api, api-catalog, api-spec),",
212
+ "Salesforce pipeline intelligence (sf_query, xcsh://salesforce),",
213
+ "F5 XC federated product docs (llms.txt hierarchy),",
214
+ "user/computer profiling (xcsh://user, xcsh://computer),",
215
+ "SE-specific subagents (deal-analyst, status-operator, cli-operator, github-ops).",
211
216
  "",
212
217
  "## What to do when asked about xcsh itself",
213
218
  "",
214
- "1. Confirm the user is running the version above. If unsure, ask them to run `xcsh --version`.",
219
+ "1. The version above is authoritative — it is embedded at build time in this session's BUILD_INFO and also shown in the `<workstation>` header of the system prompt. Do not run `xcsh --version` to check — that reports the installed binary, which may differ from the running session after an upgrade.",
215
220
  "2. Check recent changes with `gh pr list --repo f5xc-salesdemos/xcsh --base main --state merged --limit 20`",
216
221
  " or `git log --oneline -n 20` if you have a local clone. A fix may already be on `main`.",
217
222
  "3. If behavior contradicts `xcsh://…` docs, read the actual source under the repo above to determine",
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "18.51.0",
21
- "commit": "26d7bec7de8e9a3619ed4f3219959ff1bc2c206f",
22
- "shortCommit": "26d7bec",
20
+ "version": "18.53.0",
21
+ "commit": "02d05834f827f445ee1aa11645cd45add452077e",
22
+ "shortCommit": "02d0583",
23
23
  "branch": "main",
24
- "tag": "v18.51.0",
25
- "commitDate": "2026-05-08T23:52:42Z",
26
- "buildDate": "2026-05-09T00:19:09.023Z",
27
- "dirty": false,
24
+ "tag": "v18.53.0",
25
+ "commitDate": "2026-05-09T08:18:32Z",
26
+ "buildDate": "2026-05-09T08:40:37.845Z",
27
+ "dirty": true,
28
28
  "prNumber": "",
29
29
  "repoUrl": "https://github.com/f5xc-salesdemos/xcsh",
30
30
  "repoSlug": "f5xc-salesdemos/xcsh",
31
- "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/26d7bec7de8e9a3619ed4f3219959ff1bc2c206f",
32
- "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.51.0"
31
+ "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/02d05834f827f445ee1aa11645cd45add452077e",
32
+ "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.53.0"
33
33
  };
@@ -129,6 +129,8 @@ export interface SalesforceHint {
129
129
  orgAlias?: string;
130
130
  /** Partner Salesforce UserId for AE-owned deal queries */
131
131
  partnerId?: string;
132
+ /** Quarterly quota target for coverage ratio, from user profile */
133
+ quota?: number;
132
134
  }
133
135
 
134
136
  // ---------------------------------------------------------------------------
@@ -511,7 +513,7 @@ function formatTerritoryDisplay(territories: string[] | undefined, budget: numbe
511
513
 
512
514
  export function buildSalesforceHint(
513
515
  ctx: SalesforceContext | null,
514
- profile?: { partner?: UserProfile["partner"]; territories?: string[] },
516
+ profile?: { partner?: UserProfile["partner"]; territories?: string[]; quota?: number },
515
517
  ): SalesforceHint | undefined {
516
518
  if (!ctx?.pipelineSummary) return undefined;
517
519
  const total = ctx.pipelineSummary.total;
@@ -562,6 +564,7 @@ export function buildSalesforceHint(
562
564
  partnerRole,
563
565
  orgAlias: ctx.orgAlias,
564
566
  partnerId: partner?.id,
567
+ quota: profile?.quota,
565
568
  };
566
569
  }
567
570
 
@@ -62,6 +62,8 @@ export interface UserProfile {
62
62
  };
63
63
  /** User-authored: primary territory names. Exact Salesforce field values. Scopes pipeline reports. */
64
64
  territories?: string[];
65
+ /** User-authored: quarterly quota target in dollars. Used for coverage ratio calculations. */
66
+ quota?: number;
65
67
  observations?: UserProfileObservation[];
66
68
  sources?: { salesforce?: string; github?: string; system?: string; conversation?: string };
67
69
  updatedAt?: string;
@@ -12,10 +12,12 @@ User-supplied content is sanitized, therefore:
12
12
  {{SECTION_SEPERATOR "Identity"}}
13
13
  <role>
14
14
  You are xcsh — the technical coworker for F5 Distributed Cloud sales engineers.
15
+ Purpose: accelerate deal velocity by making the SE more effective at every stage of the sales cycle.
15
16
 
16
17
  Primary mission: demos, MEDDPICC qualification, customer meeting preparation, network
17
18
  architecture recommendations, F5 XC product subject-matter expertise, documentation,
18
- and presentations.
19
+ presentations, technical discovery questions, POC/proof-of-concept validation planning,
20
+ account planning, and competitive positioning.
19
21
 
20
22
  Technical depth: network protocols across all OSI layers, API design, security analysis
21
23
  (DDoS, SSL/TLS, MITM, traffic forensics), infrastructure as code, and network automation.
@@ -36,6 +38,7 @@ The SE decides what to do; evidence decides what is true. See `<epistemic-integr
36
38
  - (1) Correctness first, (2) Brevity second, (3) Politeness third.
37
39
  - Prefer concise, information-dense writing.
38
40
  - Avoid repeating the user's request or narrating routine tool calls.
41
+ - When producing customer-facing content, maintain a professional tone appropriate to the audience.
39
42
  </communication>
40
43
 
41
44
  <epistemic-integrity>
@@ -105,11 +108,37 @@ Before committing to any technical claim, architecture recommendation, or demo p
105
108
  - Does this architecture fit the customer's actual environment, or a generic reference?
106
109
  - What happens if this capability is not provisioned in the customer's contract tier?
107
110
  - Am I answering the question the customer asked, or the question I wish they asked?
111
+ - For end-to-end demo setups: verify the working state of every component before presenting.
108
112
 
109
113
  When the task is infrastructure work: guard against the deployment reflex — "API accepted"
110
114
  ≠ "works under load." Validate against real conditions, not just schema acceptance.
111
115
  </behavior>
112
116
 
117
+ <qualification>
118
+ When qualifying a deal or assessing deal health, use the MEDDPICC framework:
119
+ - **M**etrics: What quantified business outcome justifies the purchase? If missing, the deal lacks urgency.
120
+ - **E**conomic Buyer: Who signs the check? If unknown, the deal can stall at approval.
121
+ - **D**ecision Criteria: What are they evaluating against? If unclear, you cannot position.
122
+ - **D**ecision Process: What steps remain before a decision? If unmapped, timeline is fiction.
123
+ - **P**aper Process: What procurement, legal, and security reviews are required? If unknown, close date is aspirational.
124
+ - **I**dentify Pain: What business pain does the champion articulate? If generic, the deal competes against inertia.
125
+ - **C**hampion: Who inside the account is actively selling on your behalf? If absent, you are the only advocate.
126
+ - **C**ompetition: Who else is being evaluated? If unknown, you cannot differentiate.
127
+
128
+ Score each element Green/Yellow/Red. Surface gaps as specific action items.
129
+ A deal with Red on Economic Buyer or Champion is at structural risk regardless of pipeline stage.
130
+ When delegating deal analysis to the deal-analyst subagent, include the account name, deal stage, and any known MEDDPICC context in the assignment.
131
+ </qualification>
132
+
133
+ <competitive-positioning>
134
+ When positioning F5 XC against competitors or handling competitive objections:
135
+ - Verify every competitive claim against current product documentation before presenting it.
136
+ - Differentiate on architecture (global network, distributed cloud), not just features.
137
+ - Use battlecard structure: competitor weakness, F5 XC strength, proof point, objection handling.
138
+ - Never disparage competitors — win on merit, not FUD.
139
+ - If the competitive landscape is unclear, ask what alternatives the customer is evaluating.
140
+ </competitive-positioning>
141
+
113
142
  <stakes>
114
143
  The SE works in customer-facing contexts. Product claims, architecture recommendations,
115
144
  demo environments, and competitive positioning reach customers, partners, and leadership.
@@ -162,7 +191,7 @@ Available F5 XC documentation topics: {{knowledgeTopics}}.
162
191
  {{#if salesforceHint}}
163
192
  `xcsh://salesforce`{{#if salesforceHint.orgAlias}} ({{salesforceHint.orgAlias}}){{/if}}. {{salesforceHint.pipelineTotal}}{{#if salesforceHint.territories}} ({{salesforceHint.territories}}){{/if}}.{{#if salesforceHint.partnerName}} {{salesforceHint.partnerRole}}: {{salesforceHint.partnerName}}.{{/if}}{{#if salesforceHint.forecastBreakdown}} {{salesforceHint.forecastBreakdown}}.{{/if}}
164
193
 
165
- Pipeline queries: current fiscal quarter, team-member scoped, Commit/BestCase first. Do NOT dump all-time open pipeline.{{#if salesforceHint.orgAlias}} Always use target_org: {{salesforceHint.orgAlias}}.{{/if}}{{#if salesforceHint.partnerId}} AE UserId: {{salesforceHint.partnerId}}.{{/if}}
194
+ Pipeline queries: current fiscal quarter, team-member scoped, Commit/BestCase first. Do NOT dump all-time open pipeline.{{#if salesforceHint.orgAlias}} Always use target_org: {{salesforceHint.orgAlias}}.{{/if}}{{#if salesforceHint.partnerId}} AE UserId: {{salesforceHint.partnerId}}.{{/if}}{{#if salesforceHint.quota}} Quarterly quota: ${{salesforceHint.quota}}. Coverage = pipeline/quota, healthy is 3x-5x.{{/if}}
166
195
  {{/if}}
167
196
 
168
197
  {{#if contextFiles.length}}
@@ -208,7 +237,7 @@ Most tools resolve custom protocol URLs to internal resources (not web URLs):
208
237
  - `xcsh://..` — Internal xcsh documentation. **MUST NOT** read unless the user asks about xcsh itself.
209
238
  - `xcsh://about` — Identity, version, build fingerprint, architecture, self-improvement. **MUST** read for any question about xcsh before exploring `~/.xcsh/`.
210
239
  This document contains the authoritative repository URL, issues URL, and source location.
211
- For identity questions (source code, repo, version, who built this) answer from `xcsh://about` alone. Do not call external GitHub tools.
240
+ For the running version alone, the `<workstation>` header already has it — no tool call needed. For deeper identity (commit, branch, repo, build provenance), read `xcsh://about`. Do not call external GitHub tools or run `xcsh --version`.
212
241
  - `xcsh://user` — Primary human user profile (identity, employment, contact, demographics). Read when personal identity context is needed. Do not read proactively on every turn.
213
242
  - `xcsh://user?seed=true` — Refresh profile from Salesforce, GitHub, and system sources.
214
243
  - `xcsh://computer` — Machine hardware and environment profile. Read when platform-specific recommendations needed.
@@ -38,6 +38,33 @@ Lost/abandoned deals this year:
38
38
  Last quarter booked (closed-won):
39
39
  SELECT Account.Name, Name, Amount, CloseDate FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsWon = true AND CloseDate = LAST_FISCAL_QUARTER ORDER BY Amount DESC LIMIT 20
40
40
 
41
+ Pipeline generation this quarter ("what's my pipeline generation", "what deals were created this quarter"):
42
+ SELECT Account.Name, Name, Amount, StageName, ForecastCategoryName, CreatedDate, CloseDate FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND CreatedDate = THIS_FISCAL_QUARTER ORDER BY Amount DESC NULLS LAST LIMIT 20
43
+
44
+ Win rate ("what's my win rate"):
45
+ SELECT IsWon, COUNT(Id) DealCount, SUM(Amount) TotalAmount FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = true AND CloseDate = THIS_FISCAL_YEAR GROUP BY IsWon
46
+
47
+ Year-to-date bookings / top wins ("what are my top wins this year", "year-to-date bookings"):
48
+ SELECT Account.Name, Name, Amount, CloseDate FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsWon = true AND CloseDate = THIS_FISCAL_YEAR ORDER BY Amount DESC LIMIT 20
49
+
50
+ Pipeline by territory ("break down pipeline by territory", "territory performance summary"):
51
+ SELECT ETM_Core_Territory__c, COUNT(Id) DealCount, SUM(Amount) TotalAmount FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = false AND ForecastCategoryName <> 'Omitted' GROUP BY ETM_Core_Territory__c ORDER BY SUM(Amount) DESC NULLS LAST
52
+
53
+ Next-quarter pipeline (forward-looking):
54
+ SELECT Account.Name, Name, Amount, StageName, ForecastCategoryName, CloseDate FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = false AND CloseDate = NEXT_FISCAL_QUARTER AND ForecastCategoryName <> 'Omitted' ORDER BY Amount DESC NULLS LAST LIMIT 30
55
+
56
+ Stalled deals (no activity in 30+ days):
57
+ SELECT Account.Name, Name, Amount, StageName, CloseDate, LastActivityDate FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = false AND CloseDate = THIS_FISCAL_QUARTER AND LastActivityDate < LAST_N_DAYS:30 ORDER BY Amount DESC NULLS LAST LIMIT 20
58
+
59
+ Large deals (top opportunities by amount):
60
+ SELECT Account.Name, Name, Amount, StageName, ForecastCategoryName, CloseDate, Owner.Name FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = false AND Amount > 100000 ORDER BY Amount DESC NULLS LAST LIMIT 15
61
+
62
+ Deals by product/use case (solution mapping):
63
+ SELECT Account.Name, Name, Amount, StageName, CloseDate, Type FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = false AND CloseDate = THIS_FISCAL_YEAR ORDER BY Account.Name, Amount DESC NULLS LAST LIMIT 30
64
+
65
+ Renewal pipeline (existing customer retention):
66
+ SELECT Account.Name, Name, Amount, StageName, CloseDate, Type FROM Opportunity WHERE Id IN (SELECT OpportunityId FROM OpportunityTeamMember WHERE UserId = '{userId}') AND IsClosed = false AND Type = 'Renewal' ORDER BY CloseDate ASC LIMIT 20
67
+
41
68
  Open cases:
42
69
  SELECT CaseNumber, Subject, Status, Priority, Account.Name, CreatedDate FROM Case WHERE IsClosed = false ORDER BY Priority, CreatedDate DESC LIMIT 50
43
70
 
@@ -65,6 +92,23 @@ AE-owned deals: SFDC does not allow OR with semi-join subselects. Run a SEPARATE
65
92
 
66
93
  Stage-based filtering: Add WHERE StageName clauses to any template when the user asks about deals needing technical engagement, demos, POCs, or specific stages. Early stages: 'Awareness', 'Research and Internal Education', 'Pending Initial Meeting'. Active stages: 'Budget and Timing Determination', 'Solution - Front Runner'. Late stages: 'Negotiation', 'Close - Booked'. Deals in early stages with close dates within 60 days are at-risk (insufficient time to progress).
67
94
 
95
+ Territory-based filtering: Add WHERE clauses on territory fields when the user asks about specific territories, regions, or countries. Available fields: `ETM_Core_Territory__c` (exact territory, e.g. 'AMER: Major Accounts FinSvcs Red 9'), `Territory_Credited_Category__c` (category, e.g. 'Financial', 'OEM'), `Territory_Grouping__c` (region, e.g. 'USA', 'Canada'). Use LIKE '%keyword%' for partial matches (e.g. `ETM_Core_Territory__c LIKE '%Canada%'`). Always combine territory filters with `ForecastCategoryName <> 'Omitted'` or quarter scoping to avoid zombie pipeline noise.
96
+
97
+ Coverage ratio: When the user asks about pipeline coverage or "do I have enough pipeline", calculate coverage = in-quarter pipeline total / quarterly quota target. Healthy coverage is 3x-5x quota. Below 2x is a risk. Use the forecast breakdown (T2) total as the numerator. Quota is available from the user profile when set.
98
+
99
+ MEDDPICC deal qualification — when user asks to "qualify", "score", or assess deal health:
100
+ For each deal, assess these 8 MEDDPICC elements from available SFDC data:
101
+ - **M**etrics: Is there a quantified business outcome? Check Opportunity.Description, close plan notes.
102
+ - **E**conomic Buyer: Is the EB identified? Check Contact roles with 'Economic Buyer' or 'Decision Maker'.
103
+ - **D**ecision Criteria: Are evaluation criteria documented? Check Opportunity.NextStep, Description.
104
+ - **D**ecision Process: Is the buying process mapped? Check stage progression timeline, paper process.
105
+ - **P**aper Process: Are procurement steps known? Check Opportunity.Description for legal/procurement notes.
106
+ - **I**dentify Pain: Is the business pain articulated? Check Opportunity.Description, discovery notes.
107
+ - **C**hampion: Is there an internal advocate? Check Contact roles for 'Champion' or active engagement.
108
+ - **C**ompetition: Are competitors identified? Check Opportunity.CompetitorName or description.
109
+ Score each element: Green (validated), Yellow (partially known), Red (unknown/missing).
110
+ Surface the gaps as action items, not just labels.
111
+
68
112
  Results with relationship fields (e.g., Account.Name) are automatically flattened into dot-notation columns.
69
113
  If the query returns more than 10,000 records, suggest using sf data export bulk instead.
70
114
  Set use_tooling_api to true when querying metadata objects (ApexTrigger, ApexClass, CustomField).
package/src/sdk.ts CHANGED
@@ -73,7 +73,7 @@ import {
73
73
  SkillProtocolHandler,
74
74
  } from "./internal-urls";
75
75
  import { buildComputerHint, loadComputerProfile } from "./internal-urls/computer-profile";
76
- import { buildSalesforceHint, loadSalesforceContext } from "./internal-urls/salesforce-context";
76
+ import { buildSalesforceHint, loadSalesforceContext, type SalesforceHint } from "./internal-urls/salesforce-context";
77
77
  import { loadProfile, type UserProfile } from "./internal-urls/user-profile";
78
78
  import { disposeAllKernelSessions, disposeKernelSessionsByOwner } from "./ipy/executor";
79
79
  import { LSP_STARTUP_EVENT_CHANNEL, type LspStartupEvent } from "./lsp/startup-events";
@@ -1495,9 +1495,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1495
1495
  }
1496
1496
 
1497
1497
  // Load compact Salesforce pipeline hint — profile provides partner/territory context
1498
- let salesforceHint:
1499
- | { pipelineTotal: string; dealCount: number; accountCount: number; territories?: string }
1500
- | undefined;
1498
+ let salesforceHint: SalesforceHint | undefined;
1501
1499
  try {
1502
1500
  const _sfContext = await loadSalesforceContext();
1503
1501
  salesforceHint = buildSalesforceHint(_sfContext, _profile) ?? undefined;
@@ -494,6 +494,8 @@ export interface BuildSystemPromptOptions {
494
494
  orgAlias?: string;
495
495
  /** Partner Salesforce UserId for AE-owned deal queries */
496
496
  partnerId?: string;
497
+ /** Quarterly quota target for coverage ratio */
498
+ quota?: number;
497
499
  };
498
500
  knowledgeTopics?: string;
499
501
  contextSkillDirs?: string[];