standout 0.5.33 → 0.5.35
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 +7431 -559
- 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/wrapped/tiers.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type TierKey = "still_figuring" | "curious_cat" | "rising_star" | "prompt_wizard" | "escape_velocity" | "unicorn";
|
|
2
|
-
export interface Tier {
|
|
3
|
-
key: TierKey;
|
|
4
|
-
label: string;
|
|
5
|
-
min: number;
|
|
6
|
-
art: string;
|
|
7
|
-
}
|
|
8
|
-
export declare const TIERS: Tier[];
|
|
9
|
-
export declare function tierForScore(score: number): Tier;
|
package/dist/wrapped/tiers.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// Score-tier ladder for the headline /100. Pure function of the score so it
|
|
2
|
-
// works on older payloads (no server field needed) and stays unit-testable.
|
|
3
|
-
// Each tier carries an ASCII figure shown as the hero of the finale card.
|
|
4
|
-
const UNICORN = ` ,.. /
|
|
5
|
-
,' ';
|
|
6
|
-
,,.__ _,' /'; .
|
|
7
|
-
:',' ~~~~ '. '~
|
|
8
|
-
' ( ) )::,
|
|
9
|
-
'. '..=----=..-~ .;'
|
|
10
|
-
' ;' :: ':. '"
|
|
11
|
-
(: ': ;)
|
|
12
|
-
\\\\ '" ./
|
|
13
|
-
'" '"`;
|
|
14
|
-
const ROCKETSHIP = ` .
|
|
15
|
-
.'.
|
|
16
|
-
|o|
|
|
17
|
-
.'o'.
|
|
18
|
-
|.-.|
|
|
19
|
-
' '
|
|
20
|
-
( )
|
|
21
|
-
)
|
|
22
|
-
( )`;
|
|
23
|
-
const WIZARD = ` (\\. \\ ,/)
|
|
24
|
-
\\( |\\ )/
|
|
25
|
-
//\\ | \\ /\\\\
|
|
26
|
-
(/ /\\_#oo#_/\\ \\)
|
|
27
|
-
\\/\\ #### /\\/
|
|
28
|
-
\`##'`;
|
|
29
|
-
const RISING_STAR = ` .
|
|
30
|
-
,O,
|
|
31
|
-
,OOO,
|
|
32
|
-
'oooooOOOOOooooo'
|
|
33
|
-
\`OOOOOOOOOOO\`
|
|
34
|
-
\`OOOOOOO\`
|
|
35
|
-
OOOO'OOOO
|
|
36
|
-
OOO' 'OOO
|
|
37
|
-
O' 'O`;
|
|
38
|
-
const CURIOUS_CAT = ` |\\__/,| (\`\\
|
|
39
|
-
|_ _ |.--.) )
|
|
40
|
-
( T ) /
|
|
41
|
-
(((^_(((/(((_/`;
|
|
42
|
-
const GINGERBREAD = ` ,--.
|
|
43
|
-
_(*_*)_
|
|
44
|
-
(_ o _)
|
|
45
|
-
/ o \\
|
|
46
|
-
(_/ \\_)`;
|
|
47
|
-
// Ordered low → high; tierForScore walks from the top down.
|
|
48
|
-
export const TIERS = [
|
|
49
|
-
{
|
|
50
|
-
key: "still_figuring",
|
|
51
|
-
label: "STILL FIGURING IT OUT",
|
|
52
|
-
min: 1,
|
|
53
|
-
art: GINGERBREAD,
|
|
54
|
-
},
|
|
55
|
-
{ key: "curious_cat", label: "CURIOUS CAT", min: 35, art: CURIOUS_CAT },
|
|
56
|
-
{ key: "rising_star", label: "RISING STAR", min: 60, art: RISING_STAR },
|
|
57
|
-
{ key: "prompt_wizard", label: "PROMPT WIZARD", min: 77, art: WIZARD },
|
|
58
|
-
{
|
|
59
|
-
key: "escape_velocity",
|
|
60
|
-
label: "ESCAPE VELOCITY",
|
|
61
|
-
min: 86,
|
|
62
|
-
art: ROCKETSHIP,
|
|
63
|
-
},
|
|
64
|
-
{ key: "unicorn", label: "UNICORN", min: 95, art: UNICORN },
|
|
65
|
-
];
|
|
66
|
-
export function tierForScore(score) {
|
|
67
|
-
const s = Number.isFinite(score) ? score : 0;
|
|
68
|
-
for (let i = TIERS.length - 1; i >= 0; i--) {
|
|
69
|
-
if (s >= TIERS[i].min)
|
|
70
|
-
return TIERS[i];
|
|
71
|
-
}
|
|
72
|
-
return TIERS[0];
|
|
73
|
-
}
|
package/dist/wrapped/types.d.ts
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
export interface WrappedAggregateView {
|
|
2
|
-
readiness: {
|
|
3
|
-
usage_stats_status: "ready" | "scanning" | "enriching" | "unavailable" | "error";
|
|
4
|
-
profile_basics_status: "ready" | "scanning" | "enriching" | "unavailable" | "error";
|
|
5
|
-
enrichment_status: "ready" | "scanning" | "enriching" | "unavailable" | "error";
|
|
6
|
-
};
|
|
7
|
-
name: string;
|
|
8
|
-
archetype_label: string;
|
|
9
|
-
zinger: string;
|
|
10
|
-
mascot_pose: MascotPose;
|
|
11
|
-
total_hours: number;
|
|
12
|
-
total_sessions: number;
|
|
13
|
-
active_days: number;
|
|
14
|
-
streak_days: number;
|
|
15
|
-
weekend_ratio: number;
|
|
16
|
-
top_tools: {
|
|
17
|
-
name: string;
|
|
18
|
-
count: number;
|
|
19
|
-
}[];
|
|
20
|
-
hour_histogram: number[];
|
|
21
|
-
peak_hour: number | null;
|
|
22
|
-
conductor_workspaces: number;
|
|
23
|
-
top_projects: {
|
|
24
|
-
label: string;
|
|
25
|
-
name: string;
|
|
26
|
-
commits: number;
|
|
27
|
-
sessions: number;
|
|
28
|
-
blurb?: string;
|
|
29
|
-
}[];
|
|
30
|
-
contributions: {
|
|
31
|
-
one_liner: string;
|
|
32
|
-
themes: string[];
|
|
33
|
-
} | null;
|
|
34
|
-
all_time: {
|
|
35
|
-
total_hours: number;
|
|
36
|
-
total_sessions: number;
|
|
37
|
-
active_days: number;
|
|
38
|
-
first_session: string | null;
|
|
39
|
-
last_session: string | null;
|
|
40
|
-
monthly_buckets: {
|
|
41
|
-
month: string;
|
|
42
|
-
sessions: number;
|
|
43
|
-
duration_hours: number;
|
|
44
|
-
}[];
|
|
45
|
-
};
|
|
46
|
-
frameworks: string[];
|
|
47
|
-
prompt_samples: string[];
|
|
48
|
-
top_asks: {
|
|
49
|
-
text: string;
|
|
50
|
-
count: number;
|
|
51
|
-
}[];
|
|
52
|
-
collaboration: CollaborationView | null;
|
|
53
|
-
total_commits: number;
|
|
54
|
-
ai_assisted_commits: number;
|
|
55
|
-
ai_assisted_pct: number;
|
|
56
|
-
code_footprint: {
|
|
57
|
-
lines_added: number;
|
|
58
|
-
lines_deleted: number;
|
|
59
|
-
net: number;
|
|
60
|
-
additive_ratio: number;
|
|
61
|
-
median_commit_size: number;
|
|
62
|
-
biggest_commit_size: number;
|
|
63
|
-
lines_per_commit: number;
|
|
64
|
-
label: "Shipper" | "Refactorer" | "Cleaner";
|
|
65
|
-
line: string | null;
|
|
66
|
-
} | null;
|
|
67
|
-
concurrency: {
|
|
68
|
-
open_tab_avg: number;
|
|
69
|
-
open_tab_peak: number;
|
|
70
|
-
longest_session_hours: number;
|
|
71
|
-
active_juggle_pct: number;
|
|
72
|
-
line: string | null;
|
|
73
|
-
} | null;
|
|
74
|
-
conversation: {
|
|
75
|
-
total_prompts: number;
|
|
76
|
-
question_ratio: number;
|
|
77
|
-
avg_prompt_chars: number;
|
|
78
|
-
line: string | null;
|
|
79
|
-
themes: string[];
|
|
80
|
-
} | null;
|
|
81
|
-
rhythm_comment: string | null;
|
|
82
|
-
stack_comment: string | null;
|
|
83
|
-
early_adopter: boolean;
|
|
84
|
-
cohort_size: number;
|
|
85
|
-
percentile_bands: {
|
|
86
|
-
typescript_shippers: number | null;
|
|
87
|
-
ai_native: number | null;
|
|
88
|
-
open_source: number | null;
|
|
89
|
-
};
|
|
90
|
-
rank_summary: {
|
|
91
|
-
sample_size: number;
|
|
92
|
-
hours_percentile: number | null;
|
|
93
|
-
sessions_percentile: number | null;
|
|
94
|
-
active_days_percentile: number | null;
|
|
95
|
-
tokens_percentile: number | null;
|
|
96
|
-
commit_days_percentile: number | null;
|
|
97
|
-
total_tokens_percentile: number | null;
|
|
98
|
-
avg_agents_percentile: number | null;
|
|
99
|
-
weekend_pct_percentile: number | null;
|
|
100
|
-
ai_assisted_pct_percentile: number | null;
|
|
101
|
-
};
|
|
102
|
-
proficiency: ProficiencyView | null;
|
|
103
|
-
tokens: {
|
|
104
|
-
work_tokens: number;
|
|
105
|
-
cache_tokens: number;
|
|
106
|
-
total_30d: number;
|
|
107
|
-
total_prior_30d: number;
|
|
108
|
-
multiplier_vs_prior: number | null;
|
|
109
|
-
by_tool: {
|
|
110
|
-
tool: string;
|
|
111
|
-
tokens: number;
|
|
112
|
-
}[];
|
|
113
|
-
six_month_buckets: {
|
|
114
|
-
month: string;
|
|
115
|
-
tokens: number;
|
|
116
|
-
}[];
|
|
117
|
-
estimated_retail_cost_usd: number;
|
|
118
|
-
cursor_estimated: boolean;
|
|
119
|
-
cursor_token_share: number;
|
|
120
|
-
};
|
|
121
|
-
tool_relationship: {
|
|
122
|
-
kind: "switch";
|
|
123
|
-
from_tool: string;
|
|
124
|
-
to_tool: string;
|
|
125
|
-
switch_month: string;
|
|
126
|
-
timeline: {
|
|
127
|
-
month: string;
|
|
128
|
-
dominant: string;
|
|
129
|
-
share: number;
|
|
130
|
-
}[];
|
|
131
|
-
} | {
|
|
132
|
-
kind: "loyalist";
|
|
133
|
-
tool: string;
|
|
134
|
-
months_count: number;
|
|
135
|
-
sessions_count: number;
|
|
136
|
-
} | {
|
|
137
|
-
kind: "polyglot";
|
|
138
|
-
tools: {
|
|
139
|
-
tool: string;
|
|
140
|
-
share: number;
|
|
141
|
-
}[];
|
|
142
|
-
} | {
|
|
143
|
-
kind: "insufficient";
|
|
144
|
-
};
|
|
145
|
-
models: {
|
|
146
|
-
by_provider: {
|
|
147
|
-
provider: "anthropic" | "openai" | "other";
|
|
148
|
-
sessions: number;
|
|
149
|
-
share: number;
|
|
150
|
-
models: {
|
|
151
|
-
name: string;
|
|
152
|
-
sessions: number;
|
|
153
|
-
}[];
|
|
154
|
-
}[];
|
|
155
|
-
top_model: {
|
|
156
|
-
name: string;
|
|
157
|
-
sessions: number;
|
|
158
|
-
share: number;
|
|
159
|
-
} | null;
|
|
160
|
-
};
|
|
161
|
-
share_url: string;
|
|
162
|
-
}
|
|
163
|
-
export interface ProficiencyView {
|
|
164
|
-
score: number;
|
|
165
|
-
intensity: number | null;
|
|
166
|
-
consistency: number;
|
|
167
|
-
craft: number | null;
|
|
168
|
-
base: number;
|
|
169
|
-
craft_bonus: number;
|
|
170
|
-
top_dimension: "intensity" | "consistency" | "craft";
|
|
171
|
-
score_percentile: number | null;
|
|
172
|
-
comment: string;
|
|
173
|
-
}
|
|
174
|
-
export interface CollaborationView {
|
|
175
|
-
style_label: string;
|
|
176
|
-
summary: string;
|
|
177
|
-
signals: {
|
|
178
|
-
fact_checking: string;
|
|
179
|
-
depth: string;
|
|
180
|
-
autonomy: string;
|
|
181
|
-
complexity: string;
|
|
182
|
-
};
|
|
183
|
-
fun_facts: {
|
|
184
|
-
most_common_ask: string | null;
|
|
185
|
-
weirdest_prompt: string | null;
|
|
186
|
-
};
|
|
187
|
-
generated_by: "llm" | "heuristic";
|
|
188
|
-
}
|
|
189
|
-
export type MascotPose = "default" | "night" | "caffeinated" | "crown" | "circuit" | "ship";
|
package/dist/wrapped/types.js
DELETED
package/dist/wrapped-client.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { WrappedAggregateView } from "./wrapped/types.js";
|
|
2
|
-
export interface WrappedGroup {
|
|
3
|
-
slug: string;
|
|
4
|
-
label: string;
|
|
5
|
-
}
|
|
6
|
-
export interface WrappedReady {
|
|
7
|
-
id: string;
|
|
8
|
-
share_url: string;
|
|
9
|
-
view: WrappedAggregateView;
|
|
10
|
-
group: WrappedGroup | null;
|
|
11
|
-
}
|
|
12
|
-
export declare function createWrapped(args: {
|
|
13
|
-
profile: Record<string, unknown>;
|
|
14
|
-
submissionId?: string | null;
|
|
15
|
-
group?: string | null;
|
|
16
|
-
}): Promise<WrappedReady | null>;
|
package/dist/wrapped-client.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
// PUBLISHING: this is shipped npm package code. Any runtime change here must bump
|
|
2
|
-
// "version" in package.json in the same PR — that bump is the ONLY trigger for the
|
|
3
|
-
// npm publish on merge. Land a change without it and the fix never reaches users.
|
|
4
|
-
import { STANDOUT_API_URL } from "./api.js";
|
|
5
|
-
import { capPayload } from "./payload.js";
|
|
6
|
-
import { aggregateView } from "./wrapped/aggregate.js";
|
|
7
|
-
const HEADERS = {
|
|
8
|
-
"Content-Type": "application/json",
|
|
9
|
-
// Vercel BotID flagged Anthropic/JS as bot traffic; same goes for default
|
|
10
|
-
// node-fetch UAs on certain paths. Set a clear identity.
|
|
11
|
-
"User-Agent": "Standout/0.4.0 (node)",
|
|
12
|
-
};
|
|
13
|
-
const MAX_ATTEMPTS = 3;
|
|
14
|
-
// The POST now returns as soon as the pending row is created (the LLM card deck
|
|
15
|
-
// runs server-side in the background), so it resolves in a couple seconds. The
|
|
16
|
-
// deck is then read by polling GET /wrapped/[id] — short requests that can't be
|
|
17
|
-
// silently dropped mid-generation the way the old long-held POST was.
|
|
18
|
-
const POST_TIMEOUT_MS = 60000;
|
|
19
|
-
const POLL_REQUEST_TIMEOUT_MS = 15000;
|
|
20
|
-
const POLL_INTERVAL_MS = 2000;
|
|
21
|
-
// Generous ceiling — the deck normally lands in well under a minute; this only
|
|
22
|
-
// bounds a stuck/never-completing background pass.
|
|
23
|
-
const POLL_TIMEOUT_MS = 180000;
|
|
24
|
-
const RETRY_BASE_DELAY_MS = 1000;
|
|
25
|
-
// The POST is NOT idempotent — each one makes a new row + background LLM run. Only
|
|
26
|
-
// retry failures that prove the request never reached the backend; a mid-flight
|
|
27
|
-
// drop may mean the row was already created, so replaying would duplicate it.
|
|
28
|
-
const RETRYABLE_CONNECT_CODES = new Set([
|
|
29
|
-
"ECONNREFUSED",
|
|
30
|
-
"ENOTFOUND",
|
|
31
|
-
"EAI_AGAIN",
|
|
32
|
-
"UND_ERR_CONNECT_TIMEOUT",
|
|
33
|
-
]);
|
|
34
|
-
function isPreConnectError(err) {
|
|
35
|
-
for (const node of [err, err?.cause]) {
|
|
36
|
-
const code = node?.code;
|
|
37
|
-
if (typeof code === "string" && RETRYABLE_CONNECT_CODES.has(code)) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
// `fetch failed` is undici's catch-all message — the real reason (ECONNRESET,
|
|
44
|
-
// UND_ERR_HEADERS_TIMEOUT, …) lives in err.cause. Walk the chain so failures are
|
|
45
|
-
// actually diagnosable instead of all collapsing to "fetch failed".
|
|
46
|
-
function describeError(err) {
|
|
47
|
-
const parts = [];
|
|
48
|
-
let node = err;
|
|
49
|
-
for (let depth = 0; node && depth < 4; depth++) {
|
|
50
|
-
const e = node;
|
|
51
|
-
const code = typeof e.code === "string" ? e.code : null;
|
|
52
|
-
const message = typeof e.message === "string" ? e.message : null;
|
|
53
|
-
const label = [code, message].filter(Boolean).join(" ");
|
|
54
|
-
if (label && !parts.includes(label))
|
|
55
|
-
parts.push(label);
|
|
56
|
-
node = node?.cause;
|
|
57
|
-
}
|
|
58
|
-
return parts.join(" <- ") || String(err);
|
|
59
|
-
}
|
|
60
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
|
-
function isReady(computed) {
|
|
62
|
-
if (!computed)
|
|
63
|
-
return false;
|
|
64
|
-
// status is the explicit signal; archetype is a backstop for any response that
|
|
65
|
-
// predates the status field.
|
|
66
|
-
return computed.status === "ready" || computed.archetype != null;
|
|
67
|
-
}
|
|
68
|
-
// Poll GET /wrapped/[id] until the background card deck is persisted. Each request
|
|
69
|
-
// is short and idempotent, so transient blips are retried freely (unlike the POST).
|
|
70
|
-
async function pollComputed(id) {
|
|
71
|
-
const deadline = Date.now() + POLL_TIMEOUT_MS;
|
|
72
|
-
// The deck never lands in under a second; wait once before the first read.
|
|
73
|
-
await sleep(POLL_INTERVAL_MS);
|
|
74
|
-
while (Date.now() < deadline) {
|
|
75
|
-
try {
|
|
76
|
-
const res = await fetch(`${STANDOUT_API_URL}/api/public/wrapped/${id}`, {
|
|
77
|
-
headers: HEADERS,
|
|
78
|
-
signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS),
|
|
79
|
-
});
|
|
80
|
-
if (res.ok) {
|
|
81
|
-
const data = (await res.json());
|
|
82
|
-
if (isReady(data.computed))
|
|
83
|
-
return data.computed ?? null;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// Transient — keep polling until the deadline.
|
|
88
|
-
}
|
|
89
|
-
await sleep(POLL_INTERVAL_MS);
|
|
90
|
-
}
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
export async function createWrapped(args) {
|
|
94
|
-
// Keep the request under Vercel's 4.5MB body cap (else a heavy history 413s
|
|
95
|
-
// before the handler runs). Trims the bulkiest raw fields only when oversized.
|
|
96
|
-
const { payload: profile, bytesAfter } = capPayload(args.profile);
|
|
97
|
-
const body = JSON.stringify({
|
|
98
|
-
profile,
|
|
99
|
-
submission_id: args.submissionId ?? undefined,
|
|
100
|
-
group: args.group ?? undefined,
|
|
101
|
-
});
|
|
102
|
-
const bodyKb = Math.round(bytesAfter / 1024);
|
|
103
|
-
let created = null;
|
|
104
|
-
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
105
|
-
try {
|
|
106
|
-
const res = await fetch(`${STANDOUT_API_URL}/api/public/wrapped`, {
|
|
107
|
-
method: "POST",
|
|
108
|
-
headers: HEADERS,
|
|
109
|
-
body,
|
|
110
|
-
signal: AbortSignal.timeout(POST_TIMEOUT_MS),
|
|
111
|
-
});
|
|
112
|
-
// Any HTTP response means the request reached the server; don't replay it
|
|
113
|
-
// (a 5xx could land after the row was already created).
|
|
114
|
-
if (!res.ok) {
|
|
115
|
-
const text = await res.text().catch(() => "");
|
|
116
|
-
process.stderr.write(` Standout had a server error (${res.status}) while building your wrapped. Please try again in a minute.\n` +
|
|
117
|
-
(text ? ` (details: ${text.slice(0, 200)})\n` : ""));
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
created = (await res.json());
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
if (isPreConnectError(err) && attempt < MAX_ATTEMPTS) {
|
|
125
|
-
await sleep(RETRY_BASE_DELAY_MS * attempt);
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
const detail = describeError(err);
|
|
129
|
-
// A TLS-layer failure means something is intercepting HTTPS (VPN, proxy, or
|
|
130
|
-
// antivirus), not a transient drop — give targeted guidance.
|
|
131
|
-
const tlsIntercept = /ERR_SSL|ERR_TLS|packet length too long|SSL routines|wrong version number|DECRYPTION|sslv3|unknown ca|self.signed|unable to (verify|get local)/i.test(detail);
|
|
132
|
-
if (tlsIntercept) {
|
|
133
|
-
process.stderr.write(` Couldn't reach Standout: a VPN, proxy, or antivirus is intercepting the HTTPS connection.\n` +
|
|
134
|
-
` Try one of: disconnect the VPN/proxy, switch networks, or set HTTPS_PROXY to your\n` +
|
|
135
|
-
` corporate proxy (and NODE_EXTRA_CA_CERTS if it uses a custom certificate), then re-run: npx standout\n` +
|
|
136
|
-
` (details: ${detail}; body ${bodyKb}KB)\n`);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
process.stderr.write(` Couldn't reach Standout to build your wrapped. Your network (or a VPN/proxy) dropped the connection.\n` +
|
|
140
|
-
` Check your connection and re-run: npx standout\n` +
|
|
141
|
-
` (details: ${detail}; body ${bodyKb}KB)\n`);
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (!created)
|
|
147
|
-
return null;
|
|
148
|
-
// The POST only created a pending row; poll for the finished deck.
|
|
149
|
-
const computed = await pollComputed(created.id);
|
|
150
|
-
if (!computed) {
|
|
151
|
-
process.stderr.write(" Your wrapped is taking longer than usual to finish generating.\n" +
|
|
152
|
-
" Re-run to try again: npx standout\n");
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
const view = aggregateView({
|
|
156
|
-
profile: args.profile,
|
|
157
|
-
computed,
|
|
158
|
-
share_url: created.share_url,
|
|
159
|
-
});
|
|
160
|
-
return {
|
|
161
|
-
id: created.id,
|
|
162
|
-
share_url: created.share_url,
|
|
163
|
-
view,
|
|
164
|
-
group: created.group ?? null,
|
|
165
|
-
};
|
|
166
|
-
}
|
package/dist/wrapped-share.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function openWrapped(shareUrl: string): Promise<void>;
|
package/dist/wrapped-share.js
DELETED