standout 0.5.34 → 0.5.36
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/dist/cli.js +7300 -561
- package/package.json +9 -3
- package/dist/ai-usage.d.ts +0 -164
- package/dist/ai-usage.js +0 -1306
- package/dist/api.d.ts +0 -10
- package/dist/api.js +0 -94
- package/dist/browser-session.d.ts +0 -3
- package/dist/browser-session.js +0 -227
- package/dist/cli.d.ts +0 -2
- package/dist/cursor.d.ts +0 -57
- package/dist/cursor.js +0 -562
- package/dist/dev-env.d.ts +0 -28
- package/dist/dev-env.js +0 -264
- package/dist/gather.d.ts +0 -82
- package/dist/gather.js +0 -922
- package/dist/heap.d.ts +0 -1
- package/dist/heap.js +0 -25
- package/dist/identity.d.ts +0 -8
- package/dist/identity.js +0 -29
- package/dist/linkedin-scrape.d.ts +0 -2
- package/dist/linkedin-scrape.js +0 -56
- package/dist/mcp.d.ts +0 -1
- package/dist/mcp.js +0 -25
- package/dist/payload.d.ts +0 -8
- package/dist/payload.js +0 -163
- package/dist/prompt.d.ts +0 -1
- package/dist/prompt.js +0 -247
- package/dist/proxy.d.ts +0 -1
- package/dist/proxy.js +0 -27
- package/dist/redact.d.ts +0 -1
- package/dist/redact.js +0 -37
- package/dist/tools.d.ts +0 -4
- package/dist/tools.js +0 -182
- package/dist/twitter-scrape.d.ts +0 -1
- package/dist/twitter-scrape.js +0 -48
- package/dist/wrapped/aggregate.d.ts +0 -6
- package/dist/wrapped/aggregate.js +0 -811
- package/dist/wrapped/chrono-critters.d.ts +0 -8
- package/dist/wrapped/chrono-critters.js +0 -32
- package/dist/wrapped/index.d.ts +0 -3
- package/dist/wrapped/index.js +0 -2
- package/dist/wrapped/mascots.d.ts +0 -2
- package/dist/wrapped/mascots.js +0 -35
- package/dist/wrapped/preview.d.ts +0 -1
- package/dist/wrapped/preview.js +0 -97
- package/dist/wrapped/render.d.ts +0 -14
- package/dist/wrapped/render.js +0 -1025
- package/dist/wrapped/tiers.d.ts +0 -9
- package/dist/wrapped/tiers.js +0 -73
- package/dist/wrapped/types.d.ts +0 -189
- package/dist/wrapped/types.js +0 -4
- package/dist/wrapped-client.d.ts +0 -16
- package/dist/wrapped-client.js +0 -166
- package/dist/wrapped-share.d.ts +0 -1
- package/dist/wrapped-share.js +0 -6
package/dist/redact.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// Redacts secret-looking strings from any text before it leaves the machine
|
|
2
|
-
// (prompt samples, conversation exchanges, etc.). Belt-and-suspenders alongside
|
|
3
|
-
// code-fence stripping — users paste API keys / tokens inline in prompts.
|
|
4
|
-
//
|
|
5
|
-
// Patterns target high-entropy secret *values* (low false-positive), plus a
|
|
6
|
-
// conservative "label = <long value>" form. Plain mentions of words like
|
|
7
|
-
// "token" or env-var names like ANTHROPIC_API_KEY are intentionally left alone.
|
|
8
|
-
const REDACTION = "[redacted]";
|
|
9
|
-
const SECRET_PATTERNS = [
|
|
10
|
-
// Private key PEM blocks (whole block).
|
|
11
|
-
/-----BEGIN[A-Z ]*PRIVATE KEY-----[\s\S]*?-----END[A-Z ]*PRIVATE KEY-----/g,
|
|
12
|
-
// Provider keys / tokens with distinctive prefixes.
|
|
13
|
-
/sk-ant-[A-Za-z0-9_-]{20,}/g,
|
|
14
|
-
/sk-(?:proj-)?[A-Za-z0-9]{20,}/g, // OpenAI
|
|
15
|
-
/npm_[A-Za-z0-9]{36}/g,
|
|
16
|
-
/gh[pousr]_[A-Za-z0-9]{36,}/g, // GitHub
|
|
17
|
-
/github_pat_[A-Za-z0-9_]{60,}/g,
|
|
18
|
-
/AKIA[0-9A-Z]{16}/g, // AWS access key id
|
|
19
|
-
/ASIA[0-9A-Z]{16}/g,
|
|
20
|
-
/AIza[0-9A-Za-z_-]{35}/g, // Google
|
|
21
|
-
/ya29\.[A-Za-z0-9_-]{20,}/g, // Google OAuth
|
|
22
|
-
/xox[baprs]-[A-Za-z0-9-]{10,}/g, // Slack
|
|
23
|
-
/[rs]k_(?:live|test)_[A-Za-z0-9]{20,}/g, // Stripe
|
|
24
|
-
/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}/g, // JWT
|
|
25
|
-
];
|
|
26
|
-
// "api_key": "longvalue" / API_KEY=longvalue / bearer longvalue — redact only
|
|
27
|
-
// the value, keep the label so the text still reads sensibly.
|
|
28
|
-
const LABELED_SECRET = /\b(api[_-]?key|secret|token|password|passwd|authorization|bearer)\b(["'\s:=]{1,4})([A-Za-z0-9_\-./+]{20,})/gi;
|
|
29
|
-
export function redactSecrets(text) {
|
|
30
|
-
if (!text)
|
|
31
|
-
return text;
|
|
32
|
-
let out = text;
|
|
33
|
-
for (const re of SECRET_PATTERNS)
|
|
34
|
-
out = out.replace(re, REDACTION);
|
|
35
|
-
out = out.replace(LABELED_SECRET, (_m, label, sep) => `${label}${sep}${REDACTION}`);
|
|
36
|
-
return out;
|
|
37
|
-
}
|
package/dist/tools.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type Anthropic from "@anthropic-ai/sdk";
|
|
2
|
-
import { type SubmitProfileOptions } from "./api.js";
|
|
3
|
-
export declare const TOOLS: Anthropic.Tool[];
|
|
4
|
-
export declare function executeTool(name: string, input: Record<string, unknown>, options?: SubmitProfileOptions): Promise<string>;
|
package/dist/tools.js
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { execSync } from "child_process";
|
|
2
|
-
import { createInterface } from "readline";
|
|
3
|
-
import { enrichProfile, submitProfile, } from "./api.js";
|
|
4
|
-
const MAX_OUTPUT = 50 * 1024; // 50KB
|
|
5
|
-
const BLOCKED_PATTERNS = [
|
|
6
|
-
// Destructive
|
|
7
|
-
/\brm\s/,
|
|
8
|
-
/\brmdir\b/,
|
|
9
|
-
/\bmv\s/,
|
|
10
|
-
/\bmkdir\s/,
|
|
11
|
-
/\btouch\s/,
|
|
12
|
-
// Write redirects
|
|
13
|
-
/>/,
|
|
14
|
-
/\bchmod\b/,
|
|
15
|
-
/\bchown\b/,
|
|
16
|
-
/\bsudo\b/,
|
|
17
|
-
// Package managers
|
|
18
|
-
/\bnpm install\b/,
|
|
19
|
-
/\bnpm i\b/,
|
|
20
|
-
/\bpip install\b/,
|
|
21
|
-
/\bbrew\s/,
|
|
22
|
-
/\byarn add\b/,
|
|
23
|
-
/\bpnpm add\b/,
|
|
24
|
-
// Execution
|
|
25
|
-
/\bbash -c\b/,
|
|
26
|
-
/\bsh -c\b/,
|
|
27
|
-
/\bpython -c\b/,
|
|
28
|
-
/\bnode -e\b/,
|
|
29
|
-
/\bperl -e\b/,
|
|
30
|
-
/\bruby -e\b/,
|
|
31
|
-
/\beval\s/,
|
|
32
|
-
// Git writes
|
|
33
|
-
/\bgit push\b/,
|
|
34
|
-
/\bgit commit\b/,
|
|
35
|
-
/\bgit reset\b/,
|
|
36
|
-
/\bgit checkout\b/,
|
|
37
|
-
/\bgit branch -[dD]\b/,
|
|
38
|
-
/\bgit merge\b/,
|
|
39
|
-
/\bgit rebase\b/,
|
|
40
|
-
/\bgit stash\b/,
|
|
41
|
-
// Network writes
|
|
42
|
-
/\bcurl\b.*-X\s*(POST|PUT|PATCH|DELETE)/i,
|
|
43
|
-
/\bcurl\b.*(-d|--data)\s/,
|
|
44
|
-
// Full paths to dangerous commands
|
|
45
|
-
/\/bin\/rm\b/,
|
|
46
|
-
/\/usr\/bin\/rm\b/,
|
|
47
|
-
];
|
|
48
|
-
function isCommandSafe(command) {
|
|
49
|
-
return !BLOCKED_PATTERNS.some((pattern) => pattern.test(command));
|
|
50
|
-
}
|
|
51
|
-
function executeBash(command) {
|
|
52
|
-
if (!isCommandSafe(command)) {
|
|
53
|
-
return "Error: Command blocked by read-only sandbox. Only read operations are allowed.";
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const output = execSync(command, {
|
|
57
|
-
timeout: 30000,
|
|
58
|
-
maxBuffer: 1024 * 1024,
|
|
59
|
-
encoding: "utf-8",
|
|
60
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
61
|
-
});
|
|
62
|
-
if (output.length > MAX_OUTPUT) {
|
|
63
|
-
return (output.slice(0, MAX_OUTPUT) +
|
|
64
|
-
`\n\n[Output truncated at ${MAX_OUTPUT} bytes]`);
|
|
65
|
-
}
|
|
66
|
-
return output;
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
const err = error;
|
|
70
|
-
return `Error: ${err.stderr || err.message || "Command failed"}`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function askUser(question, options) {
|
|
74
|
-
process.stderr.write(`\n${question}\n`);
|
|
75
|
-
if (options?.length) {
|
|
76
|
-
options.forEach((opt, i) => {
|
|
77
|
-
process.stderr.write(` ${i + 1}. ${opt}\n`);
|
|
78
|
-
});
|
|
79
|
-
process.stderr.write(` ${options.length + 1}. Other (type your answer)\n`);
|
|
80
|
-
}
|
|
81
|
-
process.stderr.write("\n> ");
|
|
82
|
-
return new Promise((resolve) => {
|
|
83
|
-
const iface = createInterface({
|
|
84
|
-
input: process.stdin,
|
|
85
|
-
output: process.stderr,
|
|
86
|
-
});
|
|
87
|
-
iface.question("", (answer) => {
|
|
88
|
-
iface.close();
|
|
89
|
-
const trimmed = answer.trim();
|
|
90
|
-
if (options?.length) {
|
|
91
|
-
const num = parseInt(trimmed, 10);
|
|
92
|
-
if (num >= 1 && num <= options.length) {
|
|
93
|
-
resolve(options[num - 1]);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
resolve(trimmed);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
export const TOOLS = [
|
|
102
|
-
{
|
|
103
|
-
name: "bash",
|
|
104
|
-
description: "Execute a bash command in a read-only sandbox. Destructive commands (rm, mv, git push, sudo, etc.) are blocked. Use for reading files, git log, curl GET, find, ls, etc.",
|
|
105
|
-
input_schema: {
|
|
106
|
-
type: "object",
|
|
107
|
-
properties: {
|
|
108
|
-
command: {
|
|
109
|
-
type: "string",
|
|
110
|
-
description: "The bash command to execute",
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
required: ["command"],
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
name: "ask_user",
|
|
118
|
-
description: "Ask the user a question interactively. Can provide predefined options or allow free-text input.",
|
|
119
|
-
input_schema: {
|
|
120
|
-
type: "object",
|
|
121
|
-
properties: {
|
|
122
|
-
question: {
|
|
123
|
-
type: "string",
|
|
124
|
-
description: "The question to ask",
|
|
125
|
-
},
|
|
126
|
-
options: {
|
|
127
|
-
type: "array",
|
|
128
|
-
items: { type: "string" },
|
|
129
|
-
description: "Optional list of predefined answer choices",
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
required: ["question"],
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: "standout_enrich",
|
|
137
|
-
description: "Enrich a profile using Standout's data APIs. Supports: email_to_linkedin (resolve email to LinkedIn URL), linkedin_profile (get full LinkedIn profile), company (get company data by LinkedIn URL).",
|
|
138
|
-
input_schema: {
|
|
139
|
-
type: "object",
|
|
140
|
-
properties: {
|
|
141
|
-
type: {
|
|
142
|
-
type: "string",
|
|
143
|
-
enum: ["email_to_linkedin", "linkedin_profile", "company"],
|
|
144
|
-
description: "Type of enrichment to perform",
|
|
145
|
-
},
|
|
146
|
-
value: {
|
|
147
|
-
type: "string",
|
|
148
|
-
description: "The value to enrich: email address, LinkedIn profile URL, or company LinkedIn URL",
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
required: ["type", "value"],
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
name: "standout_submit",
|
|
156
|
-
description: "Submit the completed developer profile to Standout. Call this after the user confirms they want to submit.",
|
|
157
|
-
input_schema: {
|
|
158
|
-
type: "object",
|
|
159
|
-
properties: {
|
|
160
|
-
profile: {
|
|
161
|
-
type: "string",
|
|
162
|
-
description: "The full profile JSON as a string",
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
required: ["profile"],
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
];
|
|
169
|
-
export async function executeTool(name, input, options = {}) {
|
|
170
|
-
switch (name) {
|
|
171
|
-
case "bash":
|
|
172
|
-
return executeBash(input.command);
|
|
173
|
-
case "ask_user":
|
|
174
|
-
return askUser(input.question, input.options);
|
|
175
|
-
case "standout_enrich":
|
|
176
|
-
return enrichProfile(input.type, input.value);
|
|
177
|
-
case "standout_submit":
|
|
178
|
-
return submitProfile(input.profile, options);
|
|
179
|
-
default:
|
|
180
|
-
return `Unknown tool: ${name}`;
|
|
181
|
-
}
|
|
182
|
-
}
|
package/dist/twitter-scrape.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function scrapeTwitterHandle(): Promise<string | null>;
|
package/dist/twitter-scrape.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { NAV_TIMEOUT_MS, scrapeFromChromeSession } from "./browser-session.js";
|
|
2
|
-
async function extractTwitterHandle(context) {
|
|
3
|
-
const cookies = await context.cookies([
|
|
4
|
-
"https://x.com",
|
|
5
|
-
"https://twitter.com",
|
|
6
|
-
]);
|
|
7
|
-
if (!cookies.find((c) => c.name === "auth_token"))
|
|
8
|
-
return null;
|
|
9
|
-
const page = await context.newPage();
|
|
10
|
-
try {
|
|
11
|
-
await page.goto("https://x.com/home", {
|
|
12
|
-
waitUntil: "domcontentloaded",
|
|
13
|
-
timeout: NAV_TIMEOUT_MS,
|
|
14
|
-
});
|
|
15
|
-
if (/\/(login|i\/flow\/login)/.test(page.url()))
|
|
16
|
-
return null;
|
|
17
|
-
try {
|
|
18
|
-
const link = page.locator('[data-testid="AppTabBar_Profile_Link"]');
|
|
19
|
-
await link.first().waitFor({ timeout: 5000 });
|
|
20
|
-
const href = await link.first().getAttribute("href");
|
|
21
|
-
if (href) {
|
|
22
|
-
const handle = href.replace(/^\//, "").trim();
|
|
23
|
-
if (handle && !handle.includes("/"))
|
|
24
|
-
return handle;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
// fall through
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
const nameElem = page.locator('[data-testid="UserName"] span:has-text("@")');
|
|
32
|
-
const text = await nameElem.first().innerText({ timeout: 3000 });
|
|
33
|
-
const match = text.match(/@([A-Za-z0-9_]+)/);
|
|
34
|
-
if (match)
|
|
35
|
-
return match[1];
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// skip
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
finally {
|
|
43
|
-
await page.close().catch(() => undefined);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
export async function scrapeTwitterHandle() {
|
|
47
|
-
return scrapeFromChromeSession(extractTwitterHandle);
|
|
48
|
-
}
|