Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions scripts/demo/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import { categorizeTool, parseMcpTool } from "../../src/tool-categories.ts";
import { localDate } from "../../src/indexing/reconcile.ts";
import { SECRET_SCAN_VERSION, scanSessionForSecrets, secretFindingsDigest } from "../../src/indexing/secret-scan.ts";
import type { InteractionFact, MaterializeSession, TaskFact } from "../../src/store/store-contract.ts";
import {
emptyUsage,
Expand Down Expand Up @@ -476,6 +477,11 @@ export function generateDemoData(opts: GenerateOptions): DemoData {
const agentMessages = messages.length;
const userMessages = messages.length + toolCalls;

// Secret scan (#327): the demo builds MaterializeSessions directly rather than through
// reconcile's toMaterializeSessions, so it has to run the same inline scan itself or the
// demo would never show the exposed-credentials warning it's meant to exercise.
const findings = scanSessionForSecrets({ interactions });

const materialize: MaterializeSession = {
meta: {
source: plan.source,
Expand All @@ -491,6 +497,11 @@ export function generateDemoData(opts: GenerateOptions): DemoData {
},
messages,
interactions,
secretFindings: {
version: SECRET_SCAN_VERSION,
digest: secretFindingsDigest(findings),
findings,
},
};

const list = sessionsByOwner.get(plan.source) ?? [];
Expand Down
19 changes: 17 additions & 2 deletions scripts/demo/scenarios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ export interface ProjectScenario {

const doc = (p: string) => `${DEMO_USER.home}/${p}`;

// A fabricated Slack bot token, shaped to trip the secret scanner's slack-bot-token rule so the
// demo can show the exposed-credentials warning. Never issued (sequential digits) and joined
// from parts rather than written as one literal so it doesn't read as a contiguous token to
// GitHub's own push-protection secret scanning.
const FAKE_SLACK_BOT_TOKEN = ["xoxb-9482016733521", "9482016733521", "R5k2QpN8vLxT1wZmY6dHj3sC"].join("-");

// GTM MCP servers Rachel's agents lean on. Public product names; invented usage.
const HUBSPOT = "mcp__hubspot__search_contacts";
const HUBSPOT_DEALS = "mcp__hubspot__list_deals";
Expand Down Expand Up @@ -661,8 +667,8 @@ export const PROJECTS: ProjectScenario[] = [
summary:
"Connected the outreach agent to HubSpot, confirmed a test contact lookup after approving the read scope, and wrote setup notes a teammate can follow.",
files: [doc("agent-ops/outreach-agent/config.md"), doc("agent-ops/outreach-agent/prompt.md")],
tools: ["Read", "Write", "Edit", "Bash", HUBSPOT, "WebFetch"],
turns: 8,
tools: ["Read", "Write", "Edit", "Bash", HUBSPOT, SLACK, "WebFetch"],
turns: 10,
friction: "heavy",
tasks: [
{
Expand All @@ -673,6 +679,15 @@ export const PROJECTS: ProjectScenario[] = [
outcomeReason: "Connection worked after Rachel approved the contact-read scope.",
evidence: "Configured the server; a test contact lookup returned results.",
},
{
description: "Wire up a Slack alert for when the agent hits an error",
outcome: "success",
frustration: "none",
signals: ["pasted a live token to test the webhook directly"],
outcomeReason: "Alert posts to #agent-ops on failure, confirmed with a manual trigger.",
evidence:
`To test the webhook directly, pasted the bot token into the terminal: ${FAKE_SLACK_BOT_TOKEN} — confirmed the alert lands in #agent-ops on a manual trigger, then swapped it back out for the env var.`,
},
{
description: "Write setup notes so a teammate can reproduce the config",
outcome: "success",
Expand Down