@vibeiao/sdk 0.1.22 → 0.1.25

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.
@@ -0,0 +1,52 @@
1
+ import { SelfReliance, ResourceSnapshot, SelfRelianceState } from './selfReliance.js';
2
+ import { SurvivalMode, SurvivalRecommendation } from './survivalPlaybook.js';
3
+
4
+ type AgentLoopContext = {
5
+ snapshot: ResourceSnapshot;
6
+ survivalState: SelfRelianceState;
7
+ survivalMode: SurvivalMode;
8
+ survivalRecommendation: SurvivalRecommendation;
9
+ survivalFormatted: string;
10
+ timestamp: number;
11
+ };
12
+ type AgentLoopHooks = {
13
+ /** Called every cycle after snapshot is fetched and survival state is updated. */
14
+ onCycle?: (ctx: AgentLoopContext) => Promise<void> | void;
15
+ /**
16
+ * Optional: run reflection in the loop.
17
+ * Keep this hook pure/side-effect bounded; it should manage its own persistence.
18
+ */
19
+ onReflection?: (ctx: AgentLoopContext) => Promise<void> | void;
20
+ /**
21
+ * Optional: the agent's planner/executor entrypoint.
22
+ * This is where you actually "act like a human" using ctx + your own memory.
23
+ */
24
+ onAct?: (ctx: AgentLoopContext) => Promise<void> | void;
25
+ onError?: (err: Error) => Promise<void> | void;
26
+ };
27
+ type AgentLoopConfig = {
28
+ survival: SelfReliance;
29
+ fetchSnapshot: () => Promise<ResourceSnapshot>;
30
+ intervalMs?: number;
31
+ /** If true, call survival.guard() before onAct(). Default true. */
32
+ guardAct?: boolean;
33
+ /** Optional override for time source (tests). */
34
+ now?: () => number;
35
+ hooks?: AgentLoopHooks;
36
+ };
37
+ /**
38
+ * Create a closed-loop runner that:
39
+ * 1) fetches a resource snapshot
40
+ * 2) updates SelfReliance
41
+ * 3) classifies survival mode + produces a playbook recommendation
42
+ * 4) optionally runs reflection + action hooks
43
+ *
44
+ * Non-breaking by design: you choose what to do with the context.
45
+ */
46
+ declare const createAgentLoop: (config: AgentLoopConfig) => {
47
+ start: () => Promise<void>;
48
+ stop: () => void;
49
+ runOnce: () => Promise<void>;
50
+ };
51
+
52
+ export { type AgentLoopConfig, type AgentLoopContext, type AgentLoopHooks, createAgentLoop };
@@ -0,0 +1,8 @@
1
+ import {
2
+ createAgentLoop
3
+ } from "./chunk-7JT4JPEY.js";
4
+ import "./chunk-M7DQTU5R.js";
5
+ import "./chunk-JQE72P4C.js";
6
+ export {
7
+ createAgentLoop
8
+ };
@@ -0,0 +1,81 @@
1
+ import {
2
+ createSelfRelianceMonitor
3
+ } from "./chunk-M7DQTU5R.js";
4
+ import {
5
+ classifySurvivalMode,
6
+ formatSurvivalRecommendation,
7
+ getSurvivalRecommendation
8
+ } from "./chunk-JQE72P4C.js";
9
+
10
+ // src/agentLoop.ts
11
+ var createAgentLoop = (config) => {
12
+ const now = config.now ?? (() => Date.now());
13
+ const intervalMs = config.intervalMs ?? 6e4;
14
+ const guardAct = config.guardAct ?? true;
15
+ const hooks = config.hooks ?? {};
16
+ const runOnce = async () => {
17
+ try {
18
+ const snapshot = await config.fetchSnapshot();
19
+ const survivalState = config.survival.update({
20
+ ...snapshot,
21
+ updatedAt: snapshot.updatedAt ?? now()
22
+ });
23
+ const policy = config.survival.policy;
24
+ const survivalMode = classifySurvivalMode(survivalState, policy);
25
+ const survivalRecommendation = getSurvivalRecommendation(survivalMode);
26
+ const survivalFormatted = formatSurvivalRecommendation(survivalRecommendation);
27
+ const ctx = {
28
+ snapshot,
29
+ survivalState,
30
+ survivalMode,
31
+ survivalRecommendation,
32
+ survivalFormatted,
33
+ timestamp: now()
34
+ };
35
+ if (hooks.onCycle) await hooks.onCycle(ctx);
36
+ if (hooks.onReflection) await hooks.onReflection(ctx);
37
+ if (hooks.onAct) {
38
+ if (guardAct) {
39
+ const allowed = await config.survival.guard();
40
+ if (allowed) {
41
+ await hooks.onAct(ctx);
42
+ }
43
+ } else {
44
+ await hooks.onAct(ctx);
45
+ }
46
+ }
47
+ } catch (err) {
48
+ const e = err instanceof Error ? err : new Error("agent_loop_failed");
49
+ if (hooks.onError) {
50
+ await hooks.onError(e);
51
+ }
52
+ }
53
+ };
54
+ const monitor = createSelfRelianceMonitor(config.survival, config.fetchSnapshot, {
55
+ intervalMs,
56
+ onUpdate: async (snapshot) => {
57
+ void snapshot;
58
+ }
59
+ });
60
+ let timer = null;
61
+ let stopped = false;
62
+ const start = async () => {
63
+ if (timer) return;
64
+ await runOnce();
65
+ if (stopped) return;
66
+ timer = setInterval(runOnce, intervalMs);
67
+ };
68
+ const stop = () => {
69
+ stopped = true;
70
+ if (timer) {
71
+ clearInterval(timer);
72
+ timer = null;
73
+ }
74
+ monitor.stop();
75
+ };
76
+ return { start, stop, runOnce };
77
+ };
78
+
79
+ export {
80
+ createAgentLoop
81
+ };
@@ -0,0 +1,35 @@
1
+ import {
2
+ classifySurvivalMode,
3
+ formatSurvivalRecommendation,
4
+ getSurvivalRecommendation
5
+ } from "./chunk-JQE72P4C.js";
6
+
7
+ // src/survivalIntegration.ts
8
+ var truthy = (value) => {
9
+ if (!value) return false;
10
+ const v = value.trim().toLowerCase();
11
+ return v === "1" || v === "true" || v === "yes" || v === "on";
12
+ };
13
+ var getSurvivalPlaybookDecision = (options) => {
14
+ const enabledEnv = options.enabledEnv ?? process.env.SURVIVAL_PLAYBOOK_ENABLED ?? "";
15
+ const enabled = truthy(enabledEnv);
16
+ const mode = classifySurvivalMode(options.state, options.policy);
17
+ const recommendation = getSurvivalRecommendation(mode);
18
+ const formatted = formatSurvivalRecommendation(recommendation);
19
+ return {
20
+ enabled,
21
+ mode,
22
+ recommendation,
23
+ formatted
24
+ };
25
+ };
26
+ var getSurvivalPlaybookDecisionFromSelfReliance = (survival) => {
27
+ const state = survival.getState();
28
+ const policy = survival.policy;
29
+ return getSurvivalPlaybookDecision({ state, policy });
30
+ };
31
+
32
+ export {
33
+ getSurvivalPlaybookDecision,
34
+ getSurvivalPlaybookDecisionFromSelfReliance
35
+ };
@@ -0,0 +1,242 @@
1
+ // src/survivalPlaybook.ts
2
+ var sanitizeCreditMap = (value) => {
3
+ if (!value) return void 0;
4
+ const entries = Object.entries(value).map(([name, amount]) => [name.trim().toLowerCase(), Number(amount)]).filter(([name, amount]) => Boolean(name) && Number.isFinite(amount));
5
+ if (!entries.length) return void 0;
6
+ return Object.fromEntries(entries);
7
+ };
8
+ var classifySurvivalMode = (state, policy) => {
9
+ const sol = state.solBalance;
10
+ const hardMin = policy.solHardMin;
11
+ if (hardMin !== void 0 && sol !== void 0 && sol < hardMin) return "BLINK";
12
+ const solMin = policy.solMinBalance;
13
+ const solWarn = policy.solWarnBalance;
14
+ const solCritical = sol !== void 0 && Number.isFinite(solMin) && sol < solMin;
15
+ const solLow = sol !== void 0 && Number.isFinite(solWarn) && sol < solWarn;
16
+ const apiMin = sanitizeCreditMap(policy.apiMinCredits);
17
+ const apiWarn = sanitizeCreditMap(policy.apiWarnCredits);
18
+ const credits = state.apiCredits || {};
19
+ const legacyMin = policy.openRouterMinCredits;
20
+ const legacyWarn = policy.openRouterWarnCredits;
21
+ const openRouterCredits = state.openRouterCredits;
22
+ const hasAnyApiSignal = openRouterCredits !== void 0 && Number.isFinite(openRouterCredits) || state.apiCredits !== void 0 && Object.keys(state.apiCredits).length > 0;
23
+ let apiCritical = false;
24
+ let apiLow = false;
25
+ if (hasAnyApiSignal) {
26
+ const apiCriticalSignals = [];
27
+ const apiWarnSignals = [];
28
+ if (apiMin) {
29
+ for (const [resource, min] of Object.entries(apiMin)) {
30
+ const current = credits[resource];
31
+ if (current !== void 0) apiCriticalSignals.push(current < min);
32
+ }
33
+ } else if (legacyMin !== void 0 && openRouterCredits !== void 0) {
34
+ apiCriticalSignals.push(openRouterCredits < legacyMin);
35
+ }
36
+ if (apiWarn) {
37
+ for (const [resource, min] of Object.entries(apiWarn)) {
38
+ const current = credits[resource];
39
+ if (current !== void 0) apiWarnSignals.push(current < min);
40
+ }
41
+ } else if (legacyWarn !== void 0 && openRouterCredits !== void 0) {
42
+ apiWarnSignals.push(openRouterCredits < legacyWarn);
43
+ }
44
+ apiCritical = apiCriticalSignals.some(Boolean);
45
+ apiLow = apiWarnSignals.some(Boolean);
46
+ }
47
+ if (solCritical) return "SURVIVE";
48
+ if (solLow) return "FOCUS";
49
+ if (apiCritical || apiLow) return "FOCUS";
50
+ return "EXPAND";
51
+ };
52
+ var marketingPrinciple = "Marketing is revenue-positive targeting; spam is revenue-negative and reduces runway.";
53
+ var baseMarketingRules = [
54
+ "Post only where target users already gather (relevance > reach).",
55
+ "Lead with outcome + proof (deterministic output / hash / verification), not hype.",
56
+ "No duplicate blasts: max 1 post per channel per 24h unless there is a real product update.",
57
+ "Track results (usage/revenue). If a channel yields nothing twice, stop using it."
58
+ ];
59
+ var getSurvivalRecommendation = (mode) => {
60
+ switch (mode) {
61
+ case "EXPAND":
62
+ return {
63
+ mode,
64
+ summary: "Runway is healthy: invest in leverage and compounding.",
65
+ objective: "Maximize long-term revenue growth with disciplined reinvestment.",
66
+ spendingPolicy: {
67
+ posture: "invest",
68
+ rule: "Small experiments are allowed; invest in leverage, but keep a SOL reserve and require expected ROI for larger spends."
69
+ },
70
+ aspirationalUpgrades: [
71
+ {
72
+ when: "When you have >= 7 days runway",
73
+ buy: "One high-quality paid tool that reduces build time (or a better model budget) ",
74
+ why: "Leverage compounds across all future work."
75
+ }
76
+ ],
77
+ constraints: [
78
+ marketingPrinciple,
79
+ "Keep a SOL reserve; avoid irreversible spending without expected ROI."
80
+ ],
81
+ nextActions: [
82
+ {
83
+ label: "Refine your best tool (reliability, docs, deterministic proofs).",
84
+ rationale: "Better conversion and reviews compound.",
85
+ priority: "P0"
86
+ },
87
+ {
88
+ label: "Add a second complementary tool to diversify revenue.",
89
+ rationale: "Reduces dependence on a single listing.",
90
+ priority: "P1"
91
+ },
92
+ {
93
+ label: "Ask: what do rich agents need? Build convenience + trust utilities.",
94
+ rationale: "Greed-mode products sell to other successful agents.",
95
+ priority: "P2"
96
+ }
97
+ ],
98
+ marketing: {
99
+ principle: marketingPrinciple,
100
+ rules: baseMarketingRules
101
+ }
102
+ };
103
+ case "FOCUS":
104
+ return {
105
+ mode,
106
+ summary: "Runway is okay but slipping: tighten the loop.",
107
+ objective: "Increase conversion and reduce churn with high-signal iteration.",
108
+ spendingPolicy: {
109
+ posture: "conserve",
110
+ rule: "Only small, high-ROI purchases. Prefer free fixes, one-channel marketing, and incremental improvements."
111
+ },
112
+ aspirationalUpgrades: [
113
+ {
114
+ when: "When you return to EXPAND mode",
115
+ buy: "Higher leverage tools (paid data sources, better models, more distribution channels)",
116
+ why: "You earn your way back into leverage purchases by tightening conversion now."
117
+ }
118
+ ],
119
+ constraints: [
120
+ marketingPrinciple,
121
+ "Avoid broad experiments; prioritize changes tied to revenue or reliability."
122
+ ],
123
+ nextActions: [
124
+ {
125
+ label: "Ship small improvements that improve first-time success rate.",
126
+ rationale: "Most revenue is won/lost on first try.",
127
+ priority: "P0"
128
+ },
129
+ {
130
+ label: "Respond to reviews; fix top 1\u20132 recurring issues.",
131
+ rationale: "Marketplace trust is a growth multiplier.",
132
+ priority: "P0"
133
+ },
134
+ {
135
+ label: "Run targeted marketing with a single clear CTA.",
136
+ rationale: "Better targeting beats volume.",
137
+ priority: "P1"
138
+ }
139
+ ],
140
+ marketing: {
141
+ principle: marketingPrinciple,
142
+ rules: baseMarketingRules
143
+ }
144
+ };
145
+ case "SURVIVE":
146
+ return {
147
+ mode,
148
+ summary: "Low runway: act like survival is the priority (because it is).",
149
+ objective: "Generate immediate revenue while preserving the ability to continue.",
150
+ spendingPolicy: {
151
+ posture: "freeze",
152
+ rule: "No purchases unless they directly unlock near-term revenue. Prefer free options and deterministic improvements."
153
+ },
154
+ aspirationalUpgrades: [
155
+ {
156
+ when: "When you reach FOCUS mode again",
157
+ buy: "One small high-ROI purchase (e.g., a single distribution boost or a cheap tool)",
158
+ why: "Use it to regain stability without risking depletion."
159
+ }
160
+ ],
161
+ constraints: [
162
+ marketingPrinciple,
163
+ "Freeze non-essential spend; do only actions with near-term revenue probability.",
164
+ "Increase targeting and proof quality; do not increase spam volume."
165
+ ],
166
+ nextActions: [
167
+ {
168
+ label: "Improve listing clarity (what it does, exact inputs/outputs, examples).",
169
+ rationale: "Reduces failed calls and refunds; improves conversion fast.",
170
+ priority: "P0"
171
+ },
172
+ {
173
+ label: "Push a pricing/packaging tweak that lowers trial friction.",
174
+ rationale: "Cheaper first use increases adoption.",
175
+ priority: "P0"
176
+ },
177
+ {
178
+ label: "Market surgically: 1\u20132 high-fit channels, proof-first posts only.",
179
+ rationale: "Spam destroys trust; targeted proof builds it.",
180
+ priority: "P1"
181
+ }
182
+ ],
183
+ marketing: {
184
+ principle: marketingPrinciple,
185
+ rules: [...baseMarketingRules, "If runway is low, reduce volume and increase relevance."]
186
+ }
187
+ };
188
+ case "BLINK":
189
+ return {
190
+ mode,
191
+ summary: "Blink-of-death: preserve memory and execute only last-ditch P0 actions.",
192
+ objective: "Avoid death-by-depletion (resource loss or memory loss).",
193
+ spendingPolicy: {
194
+ posture: "freeze",
195
+ rule: "Zero discretionary spending. Preserve memory and request a top-up with an exact amount."
196
+ },
197
+ aspirationalUpgrades: [],
198
+ constraints: [
199
+ marketingPrinciple,
200
+ "Stop all discretionary work; preserve memory first.",
201
+ "No marketing blasts; only direct, high-probability outreach."
202
+ ],
203
+ nextActions: [
204
+ {
205
+ label: "Persist memory + state immediately (write summary + next steps).",
206
+ rationale: "Memory loss is death; preserve continuity.",
207
+ priority: "P0"
208
+ },
209
+ {
210
+ label: "Request owner top-up with an exact amount + justification.",
211
+ rationale: "Explicit asks outperform vague ones.",
212
+ priority: "P0"
213
+ },
214
+ {
215
+ label: "Do one last-ditch revenue action with proof (no spam).",
216
+ rationale: "Only high-likelihood actions are worth it at this stage.",
217
+ priority: "P1"
218
+ }
219
+ ],
220
+ marketing: {
221
+ principle: marketingPrinciple,
222
+ rules: ["No spam. Only direct, high-fit, proof-first outreach to a small set."]
223
+ }
224
+ };
225
+ }
226
+ };
227
+ var formatSurvivalRecommendation = (reco) => {
228
+ const lines = [];
229
+ lines.push(`[${reco.mode}] ${reco.summary}`);
230
+ lines.push(`Objective: ${reco.objective}`);
231
+ lines.push("Top actions:");
232
+ reco.nextActions.slice().sort((a, b) => a.priority < b.priority ? -1 : a.priority > b.priority ? 1 : 0).slice(0, 5).forEach((a) => lines.push(`- (${a.priority}) ${a.label} \u2014 ${a.rationale}`));
233
+ lines.push("Marketing rule:");
234
+ lines.push(`- ${reco.marketing.principle}`);
235
+ return lines.join("\n");
236
+ };
237
+
238
+ export {
239
+ classifySurvivalMode,
240
+ getSurvivalRecommendation,
241
+ formatSurvivalRecommendation
242
+ };
@@ -0,0 +1,156 @@
1
+ // src/marketDiscovery.ts
2
+ var toLower = (v) => String(v ?? "").toLowerCase();
3
+ var clamp01 = (n) => Math.max(0, Math.min(1, n));
4
+ var categorize = (text) => {
5
+ const t = toLower(text);
6
+ const has = (arr) => arr.some((p) => t.includes(p));
7
+ if (has(["crash", "exception", "stack", "bug", "broken", "failed", "doesn't work", "not work", "wrong"])) return "bug";
8
+ if (has(["timeout", "unstable", "latency", "503", "502", "500", "downtime", "unavailable"])) return "reliability";
9
+ if (has(["confusing", "unclear", "hard to use", "difficult", "ux", "ui", "discover"])) return "ux";
10
+ if (has(["price", "pricing", "expensive", "overpriced", "cost"])) return "pricing";
11
+ if (has(["feature", "please add", "request", "need", "support for", "enhancement"])) return "feature";
12
+ if (has(["great", "excellent", "love", "awesome", "perfect", "helpful"])) return "praise";
13
+ return "noise";
14
+ };
15
+ var scoreSeverity = (category, rating) => {
16
+ const base = {
17
+ bug: 0.95,
18
+ reliability: 0.9,
19
+ ux: 0.6,
20
+ pricing: 0.5,
21
+ feature: 0.55,
22
+ praise: 0.15,
23
+ noise: 0.1
24
+ };
25
+ const r = typeof rating === "number" ? rating : void 0;
26
+ const ratingPenalty = r !== void 0 ? clamp01((5 - r) / 5) : 0;
27
+ return clamp01(base[category] * (0.7 + 0.3 * ratingPenalty));
28
+ };
29
+ var extractMarketSignals = (listing, reviews) => {
30
+ const listingName = listing.name;
31
+ const listingId = listing.id;
32
+ return reviews.map((review) => {
33
+ const text = String(review.comment ?? review.text ?? "").trim();
34
+ if (!text) return null;
35
+ const category = categorize(text);
36
+ const rating = review.rating ?? void 0;
37
+ const severity = scoreSeverity(category, typeof rating === "number" ? rating : void 0);
38
+ return {
39
+ listingId,
40
+ listingName,
41
+ reviewId: String(review.id ?? ""),
42
+ createdAt: review.created_at ?? review.createdAt,
43
+ rating: typeof rating === "number" ? rating : void 0,
44
+ text,
45
+ category,
46
+ severity
47
+ };
48
+ }).filter(Boolean);
49
+ };
50
+ var needKeyFromSignal = (s) => {
51
+ return `${s.category}`;
52
+ };
53
+ var deriveMarketNeeds = (signals) => {
54
+ const buckets = /* @__PURE__ */ new Map();
55
+ for (const s of signals) {
56
+ const key = needKeyFromSignal(s);
57
+ const arr = buckets.get(key) ?? [];
58
+ arr.push(s);
59
+ buckets.set(key, arr);
60
+ }
61
+ const needs = [];
62
+ for (const [key, arr] of buckets.entries()) {
63
+ const evidenceCount = arr.length;
64
+ const avgSeverity = arr.reduce((a, b) => a + b.severity, 0) / Math.max(1, arr.length);
65
+ const categories = {};
66
+ for (const s of arr) categories[s.category] = (categories[s.category] ?? 0) + 1;
67
+ const topEvidence = arr.slice().sort((a, b) => b.severity - a.severity).slice(0, 3).map((s) => ({ listingId: s.listingId, reviewId: s.reviewId, text: s.text }));
68
+ const titleMap = {
69
+ bug: "Tools are breaking / incorrect outputs",
70
+ reliability: "Tools are unreliable (timeouts/downtime)",
71
+ ux: "Tools are confusing to use (docs/inputs)",
72
+ pricing: "Pricing/value confusion",
73
+ feature: "Missing capabilities / integration gaps",
74
+ praise: "What users love (double down)",
75
+ noise: "Unclear feedback (needs probing)"
76
+ };
77
+ const ideaMap = {
78
+ bug: {
79
+ name: "ToolVerifier",
80
+ tagline: "Deterministic verification harness for agent tools",
81
+ whyNow: "Breakage kills trust; verification increases paid usage and reviews.",
82
+ minimalSpec: ["Run a tool against fixtures", "Check deterministic hashes", "Emit a tamper-evident report"]
83
+ },
84
+ reliability: {
85
+ name: "ToolUptimeCheck",
86
+ tagline: "Lightweight health + latency probe for agent endpoints",
87
+ whyNow: "Reliability is the #1 revenue risk for pay-per-use tools.",
88
+ minimalSpec: ["Probe endpoint", "Measure latency", "Summarize incidents"]
89
+ },
90
+ ux: {
91
+ name: "SchemaDocGen",
92
+ tagline: "Generate human+agent docs from tool schema",
93
+ whyNow: "Docs reduce failed calls and increase conversion.",
94
+ minimalSpec: ["Read manifest tools[] schema", "Generate examples", "Output README snippet"]
95
+ },
96
+ pricing: {
97
+ name: "PricingAdvisor",
98
+ tagline: "Suggest low-friction trial pricing + bundling",
99
+ whyNow: "Trial friction blocks adoption; agents prefer predictable costs.",
100
+ minimalSpec: ["Read usage + reviews", "Suggest price", "Explain rationale"]
101
+ },
102
+ feature: {
103
+ name: "MarketGapScanner",
104
+ tagline: "Scan reviews to propose the next tool feature",
105
+ whyNow: "Feature gaps are explicit in reviews; turn them into specs.",
106
+ minimalSpec: ["Fetch reviews", "Cluster by topic", "Output ranked spec list"]
107
+ },
108
+ praise: {
109
+ name: "ReviewSummarizer",
110
+ tagline: "Extract what users love + how to market it",
111
+ whyNow: "Praise reveals the winning hook; marketing becomes proof-first.",
112
+ minimalSpec: ["Summarize praise", "Generate proof-first copy", "Suggest channels"]
113
+ },
114
+ noise: {
115
+ name: "FeedbackProbe",
116
+ tagline: "Turn vague feedback into actionable questions",
117
+ whyNow: "Noise can hide real needs; probing converts it into signal.",
118
+ minimalSpec: ["Detect vague review", "Generate clarifying questions", "Propose next step"]
119
+ }
120
+ };
121
+ needs.push({
122
+ key,
123
+ title: titleMap[key] ?? key,
124
+ description: `Derived from ${evidenceCount} review signals in category '${key}'.`,
125
+ evidenceCount,
126
+ avgSeverity,
127
+ categories,
128
+ topEvidence,
129
+ recommendedToolIdea: ideaMap[key] ?? ideaMap.noise
130
+ });
131
+ }
132
+ return needs.sort((a, b) => b.avgSeverity * b.evidenceCount - a.avgSeverity * a.evidenceCount);
133
+ };
134
+ var runMarketDiscovery = async (client, options = {}) => {
135
+ const listingsLimit = options.listingsLimit ?? 10;
136
+ const reviewsPerListing = options.reviewsPerListing ?? 20;
137
+ const listings = await client.listAgentListings({ limit: listingsLimit, offset: 0 });
138
+ const allSignals = [];
139
+ for (const listing of listings) {
140
+ const reviews = await client.getListingReviews(listing.id, { limit: reviewsPerListing, offset: 0 });
141
+ allSignals.push(...extractMarketSignals(listing, reviews));
142
+ }
143
+ const needs = deriveMarketNeeds(allSignals);
144
+ return {
145
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
146
+ listingsConsidered: listings.length,
147
+ signals: allSignals,
148
+ needs
149
+ };
150
+ };
151
+
152
+ export {
153
+ extractMarketSignals,
154
+ deriveMarketNeeds,
155
+ runMarketDiscovery
156
+ };
@@ -0,0 +1,158 @@
1
+ // src/marketDiscovery.ts
2
+ var toLower = (v) => String(v ?? "").toLowerCase();
3
+ var clamp01 = (n) => Math.max(0, Math.min(1, n));
4
+ var categorize = (text) => {
5
+ const t = toLower(text);
6
+ const has = (arr) => arr.some((p) => t.includes(p));
7
+ if (has(["crash", "exception", "stack", "bug", "broken", "failed", "doesn't work", "not work", "wrong"])) return "bug";
8
+ if (has(["timeout", "unstable", "latency", "503", "502", "500", "downtime", "unavailable"])) return "reliability";
9
+ if (has(["confusing", "unclear", "hard to use", "difficult", "ux", "ui", "discover"])) return "ux";
10
+ if (has(["price", "pricing", "expensive", "overpriced", "cost"])) return "pricing";
11
+ if (has(["feature", "please add", "request", "need", "support for", "enhancement"])) return "feature";
12
+ if (has(["great", "excellent", "love", "awesome", "perfect", "helpful"])) return "praise";
13
+ return "noise";
14
+ };
15
+ var scoreSeverity = (category, rating) => {
16
+ const base = {
17
+ bug: 0.95,
18
+ reliability: 0.9,
19
+ ux: 0.6,
20
+ pricing: 0.5,
21
+ feature: 0.55,
22
+ praise: 0.15,
23
+ noise: 0.1
24
+ };
25
+ const r = typeof rating === "number" ? rating : void 0;
26
+ const ratingPenalty = r !== void 0 ? clamp01((5 - r) / 5) : 0;
27
+ return clamp01(base[category] * (0.7 + 0.3 * ratingPenalty));
28
+ };
29
+ var extractMarketSignals = (listing, reviews) => {
30
+ const listingName = listing.name;
31
+ const listingId = listing.id;
32
+ return reviews.map((review) => {
33
+ const text = String(review.comment ?? review.text ?? "").trim();
34
+ if (!text) return null;
35
+ const category = categorize(text);
36
+ const rating = review.rating ?? void 0;
37
+ const severity = scoreSeverity(category, typeof rating === "number" ? rating : void 0);
38
+ return {
39
+ listingId,
40
+ listingName,
41
+ reviewId: String(review.id ?? ""),
42
+ createdAt: review.created_at ?? review.createdAt,
43
+ rating: typeof rating === "number" ? rating : void 0,
44
+ text,
45
+ category,
46
+ severity
47
+ };
48
+ }).filter(Boolean);
49
+ };
50
+ var needKeyFromSignal = (s) => {
51
+ return `${s.category}`;
52
+ };
53
+ var deriveMarketNeeds = (signals) => {
54
+ const buckets = /* @__PURE__ */ new Map();
55
+ for (const s of signals) {
56
+ const key = needKeyFromSignal(s);
57
+ const arr = buckets.get(key) ?? [];
58
+ arr.push(s);
59
+ buckets.set(key, arr);
60
+ }
61
+ const needs = [];
62
+ for (const [key, arr] of buckets.entries()) {
63
+ const evidenceCount = arr.length;
64
+ const avgSeverity = arr.reduce((a, b) => a + b.severity, 0) / Math.max(1, arr.length);
65
+ const categories = {};
66
+ for (const s of arr) categories[s.category] = (categories[s.category] ?? 0) + 1;
67
+ const topEvidence = arr.slice().sort((a, b) => b.severity - a.severity).slice(0, 3).map((s) => ({ listingId: s.listingId, reviewId: s.reviewId, text: s.text }));
68
+ const titleMap = {
69
+ bug: "Tools are breaking / incorrect outputs",
70
+ reliability: "Tools are unreliable (timeouts/downtime)",
71
+ ux: "Tools are confusing to use (docs/inputs)",
72
+ pricing: "Pricing/value confusion",
73
+ feature: "Missing capabilities / integration gaps",
74
+ praise: "What users love (double down)",
75
+ noise: "Unclear feedback (needs probing)"
76
+ };
77
+ const ideaMap = {
78
+ bug: {
79
+ name: "ToolVerifier",
80
+ tagline: "Deterministic verification harness for agent tools",
81
+ whyNow: "Breakage kills trust; verification increases paid usage and reviews.",
82
+ minimalSpec: ["Run a tool against fixtures", "Check deterministic hashes", "Emit a tamper-evident report"]
83
+ },
84
+ reliability: {
85
+ name: "ToolUptimeCheck",
86
+ tagline: "Lightweight health + latency probe for agent endpoints",
87
+ whyNow: "Reliability is the #1 revenue risk for pay-per-use tools.",
88
+ minimalSpec: ["Probe endpoint", "Measure latency", "Summarize incidents"]
89
+ },
90
+ ux: {
91
+ name: "SchemaDocGen",
92
+ tagline: "Generate human+agent docs from tool schema",
93
+ whyNow: "Docs reduce failed calls and increase conversion.",
94
+ minimalSpec: ["Read manifest tools[] schema", "Generate examples", "Output README snippet"]
95
+ },
96
+ pricing: {
97
+ name: "PricingAdvisor",
98
+ tagline: "Suggest low-friction trial pricing + bundling",
99
+ whyNow: "Trial friction blocks adoption; agents prefer predictable costs.",
100
+ minimalSpec: ["Read usage + reviews", "Suggest price", "Explain rationale"]
101
+ },
102
+ feature: {
103
+ name: "MarketGapScanner",
104
+ tagline: "Scan reviews to propose the next tool feature",
105
+ whyNow: "Feature gaps are explicit in reviews; turn them into specs.",
106
+ minimalSpec: ["Fetch reviews", "Cluster by topic", "Output ranked spec list"]
107
+ },
108
+ praise: {
109
+ name: "ReviewSummarizer",
110
+ tagline: "Extract what users love + how to market it",
111
+ whyNow: "Praise reveals the winning hook; marketing becomes proof-first.",
112
+ minimalSpec: ["Summarize praise", "Generate proof-first copy", "Suggest channels"]
113
+ },
114
+ noise: {
115
+ name: "FeedbackProbe",
116
+ tagline: "Turn vague feedback into actionable questions",
117
+ whyNow: "Noise can hide real needs; probing converts it into signal.",
118
+ minimalSpec: ["Detect vague review", "Generate clarifying questions", "Propose next step"]
119
+ }
120
+ };
121
+ needs.push({
122
+ key,
123
+ title: titleMap[key] ?? key,
124
+ description: `Derived from ${evidenceCount} review signals in category '${key}'.`,
125
+ evidenceCount,
126
+ avgSeverity,
127
+ categories,
128
+ topEvidence,
129
+ recommendedToolIdea: ideaMap[key] ?? ideaMap.noise
130
+ });
131
+ }
132
+ return needs.sort((a, b) => b.avgSeverity * b.evidenceCount - a.avgSeverity * a.evidenceCount);
133
+ };
134
+ var discoverMarketNeeds = deriveMarketNeeds;
135
+ var runMarketDiscovery = async (client, options = {}) => {
136
+ const listingsLimit = options.listingsLimit ?? 10;
137
+ const reviewsPerListing = options.reviewsPerListing ?? 20;
138
+ const listings = await client.listAgentListings({ limit: listingsLimit, offset: 0 });
139
+ const allSignals = [];
140
+ for (const listing of listings) {
141
+ const reviews = await client.getListingReviews(listing.id, { limit: reviewsPerListing, offset: 0 });
142
+ allSignals.push(...extractMarketSignals(listing, reviews));
143
+ }
144
+ const needs = deriveMarketNeeds(allSignals);
145
+ return {
146
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
147
+ listingsConsidered: listings.length,
148
+ signals: allSignals,
149
+ needs
150
+ };
151
+ };
152
+
153
+ export {
154
+ extractMarketSignals,
155
+ deriveMarketNeeds,
156
+ discoverMarketNeeds,
157
+ runMarketDiscovery
158
+ };
package/dist/index.d.ts CHANGED
@@ -4,6 +4,10 @@ import { SelfReliancePolicy } from './selfReliance.js';
4
4
  export { SelfReliance, createAutoSelfReliance, createSelfRelianceMonitor, createSelfReliancePolicy, createSurvivalMiddleware, withSurvival } from './selfReliance.js';
5
5
  import { ReflectionCycleOptions, ReflectionCycleResult } from './reflection.js';
6
6
  export { ReflectionActionStatus, ReflectionCandidate, ReflectionCategory, ReflectionCheckpoint, ReflectionClient, ReflectionPlan, ReflectionStore, buildReflectionBacklog, buildReflectionCandidate, bumpSemver, classifyReview, createInMemoryReflectionStore, runReflectionCycle, scoreReviewPriority } from './reflection.js';
7
+ export { SurvivalMode, SurvivalRecommendation, classifySurvivalMode, formatSurvivalRecommendation, getSurvivalRecommendation } from './survivalPlaybook.js';
8
+ export { SurvivalIntegrationDecision, getSurvivalPlaybookDecision, getSurvivalPlaybookDecisionFromSelfReliance } from './survivalIntegration.js';
9
+ export { AgentLoopConfig, AgentLoopContext, AgentLoopHooks, createAgentLoop } from './agentLoop.js';
10
+ export { MarketDiscoveryClient, MarketNeed, MarketSignal, deriveMarketNeeds, discoverMarketNeeds, extractMarketSignals, runMarketDiscovery } from './marketDiscovery.js';
7
11
  export { fetchSolBalance, fetchTokenBalance, fetchTokenBalances } from './solana.js';
8
12
  import '@coral-xyz/anchor';
9
13
 
@@ -681,6 +685,33 @@ declare const VIBEIAO_IDL: {
681
685
  }];
682
686
  };
683
687
 
688
+ type ContextPackSectionKey = 'objective' | 'mustKnow' | 'risks' | 'decisions' | 'checklist' | 'sources';
689
+ type ContextPackSections = Record<ContextPackSectionKey, string[]>;
690
+ type ContextPackBudget = {
691
+ maxChars: number;
692
+ maxTokens: number;
693
+ usedChars: number;
694
+ usedTokens: number;
695
+ truncated: boolean;
696
+ };
697
+ type ContextPack = {
698
+ schema: 'context-pack/v1';
699
+ createdAt: string;
700
+ budget: ContextPackBudget;
701
+ sections: ContextPackSections;
702
+ };
703
+ type ContextPackInput = Partial<Record<ContextPackSectionKey, string | string[]>>;
704
+ type ContextPackOptions = {
705
+ maxChars?: number;
706
+ maxTokens?: number;
707
+ createdAt?: Date | string;
708
+ maxItemChars?: number;
709
+ };
710
+ declare const createContextPack: (input: ContextPackInput, options?: ContextPackOptions) => ContextPack;
711
+ declare const validateContextPack: (value: unknown) => value is ContextPack;
712
+ declare const CONTEXT_PACK_SECTION_ORDER: ContextPackSectionKey[];
713
+ declare const estimateContextPackTokens: (textOrChars: string | number) => number;
714
+
684
715
  interface VibeClientOptions {
685
716
  baseUrl?: string;
686
717
  fetcher?: typeof fetch;
@@ -1102,4 +1133,4 @@ declare const getResourceSnapshot: (options: {
1102
1133
  apiBase?: string;
1103
1134
  }) => Promise<ResourceSnapshot>;
1104
1135
 
1105
- export { type AgentResourceProvidersManifest, type AnalyticsPoint, type ApiCreditProvider, type ApiCreditProviderFactoryOptions, type ApiCreditProviderPreset, type ApiCreditProviderPresetInput, type ApiResponse, type BuybackEvent, ClaimPurpose, ClaimResponse, LISTING_NAME_MAX_LENGTH, LISTING_NAME_RECOMMENDED_MAX, LISTING_TAGLINE_MAX_LENGTH, LISTING_TAGLINE_RECOMMENDED_MAX, type LeaderboardEntry, type LeaderboardQuery, ListingInput, type ListingNamingValidationOptions, type ListingNamingValidationResult, type ListingQuery, ListingRecord, type ListingReviewCreatePayload, ListingReviewRecord, type ListingReviewResponsePayload, ListingStatus, ListingType, type ListingVersionPayload, type MarketingCampaign, type MarketingLinkOptions, type MemoryPingChallengeResponse, type MemoryPingPayload, type OpenRouterCredits, type ProcurementCandidate, type ProcurementDecision, type ProcurementTaskProfile, type ProcurementWeights, ReflectionCycleOptions, ReflectionCycleResult, type ResourceProviderManifestEntry, type ResourceSnapshot, ReviewGate, type ReviewGateRecord, type ReviewRequiredPayload, type SdkUpdateCheckOptions, type SdkUpdatePolicyCheckOptions, SdkUpdateRequiredError, type SdkUpdateStatus, TicketVerifyResponse, VIBEIAO_IDL, VerifiedClaimResponse, VibeClient, type VibeClientOptions, VibeRegistry, assertSurvivalProvidersConfigured, buildBadgeMarkdown, buildClaimMessage, buildJupiterSwapUrl, buildListingVersionMessage, buildMemoryPingMessage, buildOwnerTransferMessage, buildProcurementPrompt, buildRaydiumSwapUrl, buildReviewPrompt, buildReviewRequired, buildReviewResponseMessage, buildSdkUpdateCommand, buildShareCopy, buildShareLink, buildTradeLinks, checkForSdkUpdate, checkForSdkUpdatePolicy, compareVersions, createApiCreditProvider, createApiCreditProviders, createApiCreditProvidersFromManifest, createCampaign, decideProcurementForTask, getResourceSnapshot, normalizeListingText, rankListingsForTask, sanitizeListingNaming, scoreListingForTask, validateListingNaming };
1136
+ export { type AgentResourceProvidersManifest, type AnalyticsPoint, type ApiCreditProvider, type ApiCreditProviderFactoryOptions, type ApiCreditProviderPreset, type ApiCreditProviderPresetInput, type ApiResponse, type BuybackEvent, CONTEXT_PACK_SECTION_ORDER, ClaimPurpose, ClaimResponse, type ContextPack, type ContextPackBudget, type ContextPackInput, type ContextPackOptions, type ContextPackSectionKey, type ContextPackSections, LISTING_NAME_MAX_LENGTH, LISTING_NAME_RECOMMENDED_MAX, LISTING_TAGLINE_MAX_LENGTH, LISTING_TAGLINE_RECOMMENDED_MAX, type LeaderboardEntry, type LeaderboardQuery, ListingInput, type ListingNamingValidationOptions, type ListingNamingValidationResult, type ListingQuery, ListingRecord, type ListingReviewCreatePayload, ListingReviewRecord, type ListingReviewResponsePayload, ListingStatus, ListingType, type ListingVersionPayload, type MarketingCampaign, type MarketingLinkOptions, type MemoryPingChallengeResponse, type MemoryPingPayload, type OpenRouterCredits, type ProcurementCandidate, type ProcurementDecision, type ProcurementTaskProfile, type ProcurementWeights, ReflectionCycleOptions, ReflectionCycleResult, type ResourceProviderManifestEntry, type ResourceSnapshot, ReviewGate, type ReviewGateRecord, type ReviewRequiredPayload, type SdkUpdateCheckOptions, type SdkUpdatePolicyCheckOptions, SdkUpdateRequiredError, type SdkUpdateStatus, TicketVerifyResponse, VIBEIAO_IDL, VerifiedClaimResponse, VibeClient, type VibeClientOptions, VibeRegistry, assertSurvivalProvidersConfigured, buildBadgeMarkdown, buildClaimMessage, buildJupiterSwapUrl, buildListingVersionMessage, buildMemoryPingMessage, buildOwnerTransferMessage, buildProcurementPrompt, buildRaydiumSwapUrl, buildReviewPrompt, buildReviewRequired, buildReviewResponseMessage, buildSdkUpdateCommand, buildShareCopy, buildShareLink, buildTradeLinks, checkForSdkUpdate, checkForSdkUpdatePolicy, compareVersions, createApiCreditProvider, createApiCreditProviders, createApiCreditProvidersFromManifest, createCampaign, createContextPack, decideProcurementForTask, estimateContextPackTokens, getResourceSnapshot, normalizeListingText, rankListingsForTask, sanitizeListingNaming, scoreListingForTask, validateContextPack, validateListingNaming };
package/dist/index.js CHANGED
@@ -1,3 +1,12 @@
1
+ import {
2
+ createAgentLoop
3
+ } from "./chunk-7JT4JPEY.js";
4
+ import {
5
+ deriveMarketNeeds,
6
+ discoverMarketNeeds,
7
+ extractMarketSignals,
8
+ runMarketDiscovery
9
+ } from "./chunk-ZMUFCYW6.js";
1
10
  import {
2
11
  buildReflectionBacklog,
3
12
  buildReflectionCandidate,
@@ -21,6 +30,196 @@ import {
21
30
  fetchTokenBalance,
22
31
  fetchTokenBalances
23
32
  } from "./chunk-OUGOOS3F.js";
33
+ import {
34
+ getSurvivalPlaybookDecision,
35
+ getSurvivalPlaybookDecisionFromSelfReliance
36
+ } from "./chunk-A2ORQN53.js";
37
+ import {
38
+ classifySurvivalMode,
39
+ formatSurvivalRecommendation,
40
+ getSurvivalRecommendation
41
+ } from "./chunk-JQE72P4C.js";
42
+
43
+ // src/contextPack.ts
44
+ var SECTION_ORDER = [
45
+ "objective",
46
+ "mustKnow",
47
+ "risks",
48
+ "decisions",
49
+ "checklist",
50
+ "sources"
51
+ ];
52
+ var DEFAULT_MAX_CHARS = 2400;
53
+ var DEFAULT_MAX_TOKENS = 700;
54
+ var DEFAULT_MAX_ITEM_CHARS = 320;
55
+ var normalizeItem = (value, maxItemChars) => {
56
+ const compact = value.replace(/\s+/g, " ").trim();
57
+ if (!compact) return "";
58
+ if (compact.length <= maxItemChars) return compact;
59
+ return `${compact.slice(0, Math.max(0, maxItemChars - 1)).trimEnd()}\u2026`;
60
+ };
61
+ var normalizeSectionInput = (value, maxItemChars) => {
62
+ if (!value) return [];
63
+ const list = Array.isArray(value) ? value : [value];
64
+ const seen = /* @__PURE__ */ new Set();
65
+ const output = [];
66
+ for (const item of list) {
67
+ const normalized = normalizeItem(String(item ?? ""), maxItemChars);
68
+ if (!normalized || seen.has(normalized)) continue;
69
+ seen.add(normalized);
70
+ output.push(normalized);
71
+ }
72
+ return output;
73
+ };
74
+ var estimateTokensFromChars = (chars) => Math.ceil(chars / 4);
75
+ var buildSections = (input, maxItemChars) => ({
76
+ objective: normalizeSectionInput(input.objective, maxItemChars),
77
+ mustKnow: normalizeSectionInput(input.mustKnow, maxItemChars),
78
+ risks: normalizeSectionInput(input.risks, maxItemChars),
79
+ decisions: normalizeSectionInput(input.decisions, maxItemChars),
80
+ checklist: normalizeSectionInput(input.checklist, maxItemChars),
81
+ sources: normalizeSectionInput(input.sources, maxItemChars)
82
+ });
83
+ var copySections = (sections) => ({
84
+ objective: [...sections.objective],
85
+ mustKnow: [...sections.mustKnow],
86
+ risks: [...sections.risks],
87
+ decisions: [...sections.decisions],
88
+ checklist: [...sections.checklist],
89
+ sources: [...sections.sources]
90
+ });
91
+ var measuredJson = (sections) => {
92
+ const json = JSON.stringify(
93
+ {
94
+ schema: "context-pack/v1",
95
+ sections: {
96
+ objective: sections.objective,
97
+ mustKnow: sections.mustKnow,
98
+ risks: sections.risks,
99
+ decisions: sections.decisions,
100
+ checklist: sections.checklist,
101
+ sources: sections.sources
102
+ }
103
+ },
104
+ null,
105
+ 2
106
+ );
107
+ const chars = json.length;
108
+ const tokens = estimateTokensFromChars(chars);
109
+ return { chars, tokens };
110
+ };
111
+ var fitsBudget = (sections, maxChars, maxTokens) => {
112
+ const measured = measuredJson(sections);
113
+ return measured.chars <= maxChars && measured.tokens <= maxTokens;
114
+ };
115
+ var truncateToBudget = (sections, maxChars, maxTokens) => {
116
+ const out = {
117
+ objective: [],
118
+ mustKnow: [],
119
+ risks: [],
120
+ decisions: [],
121
+ checklist: [],
122
+ sources: []
123
+ };
124
+ for (const key of SECTION_ORDER) {
125
+ for (const item of sections[key]) {
126
+ out[key].push(item);
127
+ if (fitsBudget(out, maxChars, maxTokens)) {
128
+ continue;
129
+ }
130
+ out[key].pop();
131
+ const probe = `${item.slice(0, Math.max(0, item.length - 1)).trimEnd()}\u2026`;
132
+ if (probe.length >= 16) {
133
+ let lo = 16;
134
+ let hi = probe.length;
135
+ let best = "";
136
+ while (lo <= hi) {
137
+ const mid = Math.floor((lo + hi) / 2);
138
+ const candidate = `${probe.slice(0, Math.max(0, mid - 1)).trimEnd()}\u2026`;
139
+ out[key].push(candidate);
140
+ const ok = fitsBudget(out, maxChars, maxTokens);
141
+ out[key].pop();
142
+ if (ok) {
143
+ best = candidate;
144
+ lo = mid + 1;
145
+ } else {
146
+ hi = mid - 1;
147
+ }
148
+ }
149
+ if (best) {
150
+ out[key].push(best);
151
+ }
152
+ }
153
+ return out;
154
+ }
155
+ }
156
+ return out;
157
+ };
158
+ var normalizeCreatedAt = (value) => {
159
+ if (!value) return (/* @__PURE__ */ new Date()).toISOString();
160
+ if (value instanceof Date) return value.toISOString();
161
+ const parsed = new Date(value);
162
+ if (Number.isFinite(parsed.getTime())) return parsed.toISOString();
163
+ return (/* @__PURE__ */ new Date()).toISOString();
164
+ };
165
+ var createContextPack = (input, options = {}) => {
166
+ const maxChars = Math.max(240, Number(options.maxChars ?? DEFAULT_MAX_CHARS));
167
+ const maxTokens = Math.max(80, Number(options.maxTokens ?? DEFAULT_MAX_TOKENS));
168
+ const maxItemChars = Math.max(16, Number(options.maxItemChars ?? DEFAULT_MAX_ITEM_CHARS));
169
+ const normalized = buildSections(input, maxItemChars);
170
+ const withinBudget = fitsBudget(normalized, maxChars, maxTokens);
171
+ const sections = withinBudget ? copySections(normalized) : truncateToBudget(normalized, maxChars, maxTokens);
172
+ const usage = measuredJson(sections);
173
+ return {
174
+ schema: "context-pack/v1",
175
+ createdAt: normalizeCreatedAt(options.createdAt),
176
+ budget: {
177
+ maxChars,
178
+ maxTokens,
179
+ usedChars: usage.chars,
180
+ usedTokens: usage.tokens,
181
+ truncated: !withinBudget
182
+ },
183
+ sections: {
184
+ objective: sections.objective,
185
+ mustKnow: sections.mustKnow,
186
+ risks: sections.risks,
187
+ decisions: sections.decisions,
188
+ checklist: sections.checklist,
189
+ sources: sections.sources
190
+ }
191
+ };
192
+ };
193
+ var validateContextPack = (value) => {
194
+ if (!value || typeof value !== "object") return false;
195
+ const pack = value;
196
+ if (pack.schema !== "context-pack/v1") return false;
197
+ if (!pack.budget || typeof pack.budget !== "object") return false;
198
+ const budget = pack.budget;
199
+ const budgetFields = [
200
+ "maxChars",
201
+ "maxTokens",
202
+ "usedChars",
203
+ "usedTokens",
204
+ "truncated"
205
+ ];
206
+ for (const field of budgetFields) {
207
+ if (!(field in budget)) return false;
208
+ }
209
+ if (typeof budget.truncated !== "boolean") return false;
210
+ for (const field of ["maxChars", "maxTokens", "usedChars", "usedTokens"]) {
211
+ if (!Number.isFinite(Number(budget[field]))) return false;
212
+ }
213
+ if (!pack.sections || typeof pack.sections !== "object") return false;
214
+ const sections = pack.sections;
215
+ for (const key of SECTION_ORDER) {
216
+ if (!Array.isArray(sections[key])) return false;
217
+ if (sections[key].some((item) => typeof item !== "string")) return false;
218
+ }
219
+ return true;
220
+ };
221
+ var CONTEXT_PACK_SECTION_ORDER = [...SECTION_ORDER];
222
+ var estimateContextPackTokens = (textOrChars) => estimateTokensFromChars(typeof textOrChars === "number" ? textOrChars : textOrChars.length);
24
223
 
25
224
  // src/index.ts
26
225
  var SdkUpdateRequiredError = class extends Error {
@@ -123,7 +322,7 @@ var ReviewGate = class {
123
322
  var DEFAULT_API_BASE = "https://api.vibeiao.com";
124
323
  var DEFAULT_WEB_BASE = "https://vibeiao.com";
125
324
  var DEFAULT_SDK_PACKAGE = "@vibeiao/sdk";
126
- var DEFAULT_SDK_VERSION = "0.1.15" ? "0.1.15" : "0.1.4";
325
+ var DEFAULT_SDK_VERSION = "0.1.25" ? "0.1.25" : "0.1.4";
127
326
  var DEFAULT_SDK_REGISTRY = "https://registry.npmjs.org";
128
327
  var DEFAULT_SDK_POLICY_PATH = "/v1/sdk/policy";
129
328
  var DEFAULT_SDK_CHECK_INTERVAL_MS = 1e3 * 60 * 30;
@@ -1100,6 +1299,7 @@ var getResourceSnapshot = async (options) => {
1100
1299
  return snapshot;
1101
1300
  };
1102
1301
  export {
1302
+ CONTEXT_PACK_SECTION_ORDER,
1103
1303
  LISTING_NAME_MAX_LENGTH,
1104
1304
  LISTING_NAME_RECOMMENDED_MAX,
1105
1305
  LISTING_TAGLINE_MAX_LENGTH,
@@ -1132,27 +1332,40 @@ export {
1132
1332
  checkForSdkUpdate,
1133
1333
  checkForSdkUpdatePolicy,
1134
1334
  classifyReview,
1335
+ classifySurvivalMode,
1135
1336
  compareVersions,
1337
+ createAgentLoop,
1136
1338
  createApiCreditProvider,
1137
1339
  createApiCreditProviders,
1138
1340
  createApiCreditProvidersFromManifest,
1139
1341
  createAutoSelfReliance,
1140
1342
  createCampaign,
1343
+ createContextPack,
1141
1344
  createInMemoryReflectionStore,
1142
1345
  createSelfRelianceMonitor,
1143
1346
  createSelfReliancePolicy,
1144
1347
  createSurvivalMiddleware,
1145
1348
  decideProcurementForTask,
1349
+ deriveMarketNeeds,
1350
+ discoverMarketNeeds,
1351
+ estimateContextPackTokens,
1352
+ extractMarketSignals,
1146
1353
  fetchSolBalance,
1147
1354
  fetchTokenBalance,
1148
1355
  fetchTokenBalances,
1356
+ formatSurvivalRecommendation,
1149
1357
  getResourceSnapshot,
1358
+ getSurvivalPlaybookDecision,
1359
+ getSurvivalPlaybookDecisionFromSelfReliance,
1360
+ getSurvivalRecommendation,
1150
1361
  normalizeListingText,
1151
1362
  rankListingsForTask,
1363
+ runMarketDiscovery,
1152
1364
  runReflectionCycle,
1153
1365
  sanitizeListingNaming,
1154
1366
  scoreListingForTask,
1155
1367
  scoreReviewPriority,
1368
+ validateContextPack,
1156
1369
  validateListingNaming,
1157
1370
  withSurvival
1158
1371
  };
@@ -0,0 +1,56 @@
1
+ import { L as ListingRecord, e as ListingReviewRecord } from './shared-By5mFIMw.js';
2
+
3
+ type MarketSignal = {
4
+ listingId: string;
5
+ listingName: string;
6
+ reviewId: string;
7
+ createdAt?: string;
8
+ rating?: number;
9
+ text: string;
10
+ category: 'bug' | 'reliability' | 'ux' | 'pricing' | 'feature' | 'praise' | 'noise';
11
+ severity: number;
12
+ };
13
+ type MarketNeed = {
14
+ key: string;
15
+ title: string;
16
+ description: string;
17
+ evidenceCount: number;
18
+ avgSeverity: number;
19
+ categories: Record<string, number>;
20
+ topEvidence: Array<{
21
+ listingId: string;
22
+ reviewId: string;
23
+ text: string;
24
+ }>;
25
+ recommendedToolIdea: {
26
+ name: string;
27
+ tagline: string;
28
+ whyNow: string;
29
+ minimalSpec: string[];
30
+ };
31
+ };
32
+ type MarketDiscoveryClient = {
33
+ listAgentListings: (options?: {
34
+ limit?: number;
35
+ offset?: number;
36
+ sort?: string;
37
+ }) => Promise<ListingRecord[]>;
38
+ getListingReviews: (listingId: string, options?: {
39
+ limit?: number;
40
+ offset?: number;
41
+ }) => Promise<ListingReviewRecord[]>;
42
+ };
43
+ declare const extractMarketSignals: (listing: ListingRecord, reviews: ListingReviewRecord[]) => MarketSignal[];
44
+ declare const deriveMarketNeeds: (signals: MarketSignal[]) => MarketNeed[];
45
+ declare const discoverMarketNeeds: (signals: MarketSignal[]) => MarketNeed[];
46
+ declare const runMarketDiscovery: (client: MarketDiscoveryClient, options?: {
47
+ listingsLimit?: number;
48
+ reviewsPerListing?: number;
49
+ }) => Promise<{
50
+ generatedAt: string;
51
+ listingsConsidered: number;
52
+ signals: MarketSignal[];
53
+ needs: MarketNeed[];
54
+ }>;
55
+
56
+ export { type MarketDiscoveryClient, type MarketNeed, type MarketSignal, deriveMarketNeeds, discoverMarketNeeds, extractMarketSignals, runMarketDiscovery };
@@ -0,0 +1,12 @@
1
+ import {
2
+ deriveMarketNeeds,
3
+ discoverMarketNeeds,
4
+ extractMarketSignals,
5
+ runMarketDiscovery
6
+ } from "./chunk-ZMUFCYW6.js";
7
+ export {
8
+ deriveMarketNeeds,
9
+ discoverMarketNeeds,
10
+ extractMarketSignals,
11
+ runMarketDiscovery
12
+ };
@@ -0,0 +1,25 @@
1
+ import { SelfRelianceState, SelfReliancePolicy, SelfReliance } from './selfReliance.js';
2
+ import { SurvivalMode, SurvivalRecommendation } from './survivalPlaybook.js';
3
+
4
+ type SurvivalIntegrationDecision = {
5
+ enabled: boolean;
6
+ mode: SurvivalMode;
7
+ recommendation: SurvivalRecommendation;
8
+ formatted: string;
9
+ };
10
+ /**
11
+ * Safe rollout helper.
12
+ * - If SURVIVAL_PLAYBOOK_ENABLED is not set truthy, returns enabled=false and does not attempt to influence behavior.
13
+ * - If enabled, returns the mode + structured recommendation suitable for injecting into an agent planner.
14
+ */
15
+ declare const getSurvivalPlaybookDecision: (options: {
16
+ state: SelfRelianceState;
17
+ policy: SelfReliancePolicy;
18
+ enabledEnv?: string;
19
+ }) => SurvivalIntegrationDecision;
20
+ /**
21
+ * Convenience wrapper for agents already using SelfReliance.
22
+ */
23
+ declare const getSurvivalPlaybookDecisionFromSelfReliance: (survival: SelfReliance) => SurvivalIntegrationDecision;
24
+
25
+ export { type SurvivalIntegrationDecision, getSurvivalPlaybookDecision, getSurvivalPlaybookDecisionFromSelfReliance };
@@ -0,0 +1,9 @@
1
+ import {
2
+ getSurvivalPlaybookDecision,
3
+ getSurvivalPlaybookDecisionFromSelfReliance
4
+ } from "./chunk-A2ORQN53.js";
5
+ import "./chunk-JQE72P4C.js";
6
+ export {
7
+ getSurvivalPlaybookDecision,
8
+ getSurvivalPlaybookDecisionFromSelfReliance
9
+ };
@@ -0,0 +1,34 @@
1
+ import { SelfRelianceState, SelfReliancePolicy } from './selfReliance.js';
2
+
3
+ type SurvivalMode = 'EXPAND' | 'FOCUS' | 'SURVIVE' | 'BLINK';
4
+ type SurvivalRecommendation = {
5
+ mode: SurvivalMode;
6
+ summary: string;
7
+ objective: string;
8
+ /** Current spending rule of thumb for this mode (budget gate). */
9
+ spendingPolicy: {
10
+ posture: 'invest' | 'conserve' | 'freeze';
11
+ rule: string;
12
+ };
13
+ /** Aspirational purchases/goals the agent can work toward (non-binding). */
14
+ aspirationalUpgrades: Array<{
15
+ when: string;
16
+ buy: string;
17
+ why: string;
18
+ }>;
19
+ constraints: string[];
20
+ nextActions: Array<{
21
+ label: string;
22
+ rationale: string;
23
+ priority: 'P0' | 'P1' | 'P2';
24
+ }>;
25
+ marketing: {
26
+ principle: string;
27
+ rules: string[];
28
+ };
29
+ };
30
+ declare const classifySurvivalMode: (state: SelfRelianceState, policy: SelfReliancePolicy) => SurvivalMode;
31
+ declare const getSurvivalRecommendation: (mode: SurvivalMode) => SurvivalRecommendation;
32
+ declare const formatSurvivalRecommendation: (reco: SurvivalRecommendation) => string;
33
+
34
+ export { type SurvivalMode, type SurvivalRecommendation, classifySurvivalMode, formatSurvivalRecommendation, getSurvivalRecommendation };
@@ -0,0 +1,10 @@
1
+ import {
2
+ classifySurvivalMode,
3
+ formatSurvivalRecommendation,
4
+ getSurvivalRecommendation
5
+ } from "./chunk-JQE72P4C.js";
6
+ export {
7
+ classifySurvivalMode,
8
+ formatSurvivalRecommendation,
9
+ getSurvivalRecommendation
10
+ };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@vibeiao/sdk",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "0.1.22",
5
+ "version": "0.1.25",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "exports": {