saasfunnels 0.4.0 → 0.4.1
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/README.md +4 -4
- package/dist/library.js +1 -1
- package/dist/saasfunnels.js +29 -7
- package/dist/types/identity.d.ts +1 -1
- package/dist/types/mcp.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ approved set is reviewable.
|
|
|
51
51
|
- uses: LeadEngine-ai/saasfunnels-cli/action@v0.2.1
|
|
52
52
|
with:
|
|
53
53
|
api-key: ${{ secrets.SAASFUNNELS_API_KEY }}
|
|
54
|
-
cli-version: 0.2.1
|
|
54
|
+
cli-version: 0.2.1 # pin it; a floating version rebaselines drift
|
|
55
55
|
discovery-roots: app,lib
|
|
56
56
|
```
|
|
57
57
|
|
|
@@ -63,8 +63,8 @@ measured against a comparable scan rather than a wider or narrower one.
|
|
|
63
63
|
Plan and pricing upload is opt-in:
|
|
64
64
|
|
|
65
65
|
```yaml
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
plan-sources: "true"
|
|
67
|
+
integration-id: <stripe integration id>
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
It runs only on the default branch, requires a committed
|
|
@@ -100,7 +100,7 @@ Support: support@saasfunnels.ai
|
|
|
100
100
|
|
|
101
101
|
Use `saasfunnels setup run` from the application repository after creating app credentials in Setup. Load `SAASFUNNELS_API_KEY` from **Developer setup access** into the local process environment. Its scopes are `developer:read` and `features:write`; it is not a browser or payment-administration key.
|
|
102
102
|
|
|
103
|
-
The command asks before uploading structured discovery proposals. `--send` provides explicit non-interactive approval. It coordinates features, pricing extraction, and plan branches, reports progress, and waits for the Stripe catalog. Run `saasfunnels setup run --resume` after an interruption. Existing accepted stages and customer review decisions are preserved.
|
|
103
|
+
The command asks before uploading structured discovery proposals. `--send` provides explicit non-interactive approval. It coordinates features, pricing extraction, and plan branches, reports progress, and waits for the Stripe catalog. Run `saasfunnels setup run --resume` after an interruption. Existing accepted stages and customer review decisions are preserved. Coverage questions include a SHA-256 fingerprint of their affected files so changed application behavior can reopen an answer while unrelated file changes keep it. Only the fingerprint and bounded paths are uploaded, never source contents.
|
|
104
104
|
|
|
105
105
|
The scanner reads supported application files one at a time without the old 500-file, 2 MB repository, or 200-candidate cutoffs. Generated code, tests, and symlinks are excluded. Files over 2 MB and uploads over the server limit stop with a specific recovery message.
|
|
106
106
|
|
package/dist/library.js
CHANGED
|
@@ -235858,7 +235858,7 @@ function validateFeatureCatalogManifest(value) {
|
|
|
235858
235858
|
|
|
235859
235859
|
// src/identity.ts
|
|
235860
235860
|
var SAASFUNNELS_CLI_NAME = "saasfunnels";
|
|
235861
|
-
var SAASFUNNELS_CLI_VERSION = "0.4.
|
|
235861
|
+
var SAASFUNNELS_CLI_VERSION = "0.4.1";
|
|
235862
235862
|
var SAASFUNNELS_PRODUCT_NAME = "SaaSFunnels";
|
|
235863
235863
|
var SAASFUNNELS_DEFAULT_API_BASE_URL = "https://app.saasfunnels.ai";
|
|
235864
235864
|
var SAASFUNNELS_ENV = Object.freeze({
|
package/dist/saasfunnels.js
CHANGED
|
@@ -233928,7 +233928,7 @@ function extractSetupPricing(source, kind, catalogPrices = [], options = {}) {
|
|
|
233928
233928
|
|
|
233929
233929
|
// src/identity.ts
|
|
233930
233930
|
var SAASFUNNELS_CLI_NAME = "saasfunnels";
|
|
233931
|
-
var SAASFUNNELS_CLI_VERSION = "0.4.
|
|
233931
|
+
var SAASFUNNELS_CLI_VERSION = "0.4.1";
|
|
233932
233932
|
var SAASFUNNELS_PRODUCT_NAME = "SaaSFunnels";
|
|
233933
233933
|
var SAASFUNNELS_DEFAULT_API_BASE_URL = "https://app.saasfunnels.ai";
|
|
233934
233934
|
var SAASFUNNELS_ENV = Object.freeze({
|
|
@@ -233959,6 +233959,9 @@ function saasFunnelsPublicText(value) {
|
|
|
233959
233959
|
).replaceAll("prevenueFeatureKeys", "saasFunnelsFeatureKeys").replaceAll("PrevenueFeatureKey", "SaaSFunnelsFeatureKey").replaceAll("SaaSFunnels", SAASFUNNELS_PRODUCT_NAME);
|
|
233960
233960
|
}
|
|
233961
233961
|
|
|
233962
|
+
// src/discovery-coverage.ts
|
|
233963
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
233964
|
+
|
|
233962
233965
|
// src/plan-analysis.ts
|
|
233963
233966
|
var import_typescript3 = __toESM(require_typescript(), 1);
|
|
233964
233967
|
function effect(node) {
|
|
@@ -237287,9 +237290,10 @@ async function discoverCoverageLimitations(cwd2) {
|
|
|
237287
237290
|
);
|
|
237288
237291
|
const sources = /* @__PURE__ */ new Map();
|
|
237289
237292
|
const results = /* @__PURE__ */ new Map();
|
|
237293
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
237290
237294
|
const record3 = (code, file2) => {
|
|
237291
237295
|
const paths = results.get(code) ?? /* @__PURE__ */ new Set();
|
|
237292
|
-
|
|
237296
|
+
paths.add(file2);
|
|
237293
237297
|
results.set(code, paths);
|
|
237294
237298
|
};
|
|
237295
237299
|
for (const path of files) {
|
|
@@ -237302,6 +237306,14 @@ async function discoverCoverageLimitations(cwd2) {
|
|
|
237302
237306
|
if (/\.(?:py|rb|go|rs|java|kt|cs|php|ex|exs|scala|swift|vue|svelte)$/.test(
|
|
237303
237307
|
path
|
|
237304
237308
|
)) {
|
|
237309
|
+
if (stat.size > 2e6)
|
|
237310
|
+
throw new Error(
|
|
237311
|
+
"Unsupported source exceeds the 2 MB scan limit. Narrow the discovery scope before retrying."
|
|
237312
|
+
);
|
|
237313
|
+
evidence.set(
|
|
237314
|
+
path,
|
|
237315
|
+
createHash3("sha256").update(await readFile3(join2(cwd2, path))).digest("hex")
|
|
237316
|
+
);
|
|
237305
237317
|
record3("unsupported_language", path);
|
|
237306
237318
|
continue;
|
|
237307
237319
|
}
|
|
@@ -237309,6 +237321,7 @@ async function discoverCoverageLimitations(cwd2) {
|
|
|
237309
237321
|
continue;
|
|
237310
237322
|
const source = await readFile3(join2(cwd2, path), "utf8");
|
|
237311
237323
|
sources.set(path, source);
|
|
237324
|
+
evidence.set(path, createHash3("sha256").update(source).digest("hex"));
|
|
237312
237325
|
const file2 = parseApplicationSource(path, source);
|
|
237313
237326
|
const visit = (node) => {
|
|
237314
237327
|
if (!isProductNode(node)) return;
|
|
@@ -237351,11 +237364,20 @@ async function discoverCoverageLimitations(cwd2) {
|
|
|
237351
237364
|
))
|
|
237352
237365
|
record3("dynamic_access", path);
|
|
237353
237366
|
}
|
|
237354
|
-
return [...results].map(([code, paths]) => ({
|
|
237367
|
+
return [...results].map(([code, paths]) => ({
|
|
237368
|
+
code,
|
|
237369
|
+
files: [...paths].sort().slice(0, 12),
|
|
237370
|
+
// Include all affected files in the receipt, even when the UI path list is capped.
|
|
237371
|
+
sourceFingerprint: createHash3("sha256").update(
|
|
237372
|
+
JSON.stringify(
|
|
237373
|
+
[...paths].sort().map((path) => [path, evidence.get(path)])
|
|
237374
|
+
)
|
|
237375
|
+
).digest("hex")
|
|
237376
|
+
}));
|
|
237355
237377
|
}
|
|
237356
237378
|
|
|
237357
237379
|
// src/setup-run.ts
|
|
237358
|
-
import { createHash as
|
|
237380
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
237359
237381
|
import { execFile as execFile4 } from "node:child_process";
|
|
237360
237382
|
import { promisify as promisify4 } from "node:util";
|
|
237361
237383
|
import { readFile as readFile6, writeFile as writeFile3, mkdir as mkdir3 } from "node:fs/promises";
|
|
@@ -237540,7 +237562,7 @@ function planMappingRequestKey(input) {
|
|
|
237540
237562
|
}
|
|
237541
237563
|
|
|
237542
237564
|
// src/plan-branches.ts
|
|
237543
|
-
import { createHash as
|
|
237565
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
237544
237566
|
import { readdir as readdir3, readFile as readFile5, lstat as lstat4 } from "node:fs/promises";
|
|
237545
237567
|
import { extname as extname3, join as join4, relative as relative3, resolve as resolve4, sep as sep2 } from "node:path";
|
|
237546
237568
|
var maxPlanBranchFileCharacters = 2e6;
|
|
@@ -237562,7 +237584,7 @@ function clusterPlanBranches(branches) {
|
|
|
237562
237584
|
const clusters = /* @__PURE__ */ new Map();
|
|
237563
237585
|
for (const branch of branches) {
|
|
237564
237586
|
const fullLocation = `${branch.repositoryPath}::${branch.symbol}`;
|
|
237565
|
-
const location = fullLocation.length <= 400 ? fullLocation : `${fullLocation.slice(0, 367)}~${
|
|
237587
|
+
const location = fullLocation.length <= 400 ? fullLocation : `${fullLocation.slice(0, 367)}~${createHash4("sha256").update(fullLocation).digest("hex").slice(0, 32)}`;
|
|
237566
237588
|
const key3 = `${branch.shape}|${location}`;
|
|
237567
237589
|
const existing = clusters.get(key3);
|
|
237568
237590
|
if (existing) existing.push(branch);
|
|
@@ -237652,7 +237674,7 @@ async function discoverPlanBranches(input) {
|
|
|
237652
237674
|
|
|
237653
237675
|
// src/setup-run.ts
|
|
237654
237676
|
var exec4 = promisify4(execFile4);
|
|
237655
|
-
var hash2 = (text) =>
|
|
237677
|
+
var hash2 = (text) => createHash5("sha256").update(text).digest("hex");
|
|
237656
237678
|
var contextSchema = external_exports.object({
|
|
237657
237679
|
contractVersion: external_exports.literal(3),
|
|
237658
237680
|
minimumCliVersion: external_exports.string(),
|
package/dist/types/identity.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const SAASFUNNELS_CLI_NAME = "saasfunnels";
|
|
2
|
-
export declare const SAASFUNNELS_CLI_VERSION = "0.4.
|
|
2
|
+
export declare const SAASFUNNELS_CLI_VERSION = "0.4.1";
|
|
3
3
|
export declare const SAASFUNNELS_PRODUCT_NAME = "SaaSFunnels";
|
|
4
4
|
export declare const SAASFUNNELS_DEFAULT_API_BASE_URL = "https://app.saasfunnels.ai";
|
|
5
5
|
export declare const SAASFUNNELS_ENV: Readonly<{
|
package/dist/types/mcp.d.ts
CHANGED
|
@@ -77,7 +77,7 @@ export type SaaSFunnelsMcpOptions = {
|
|
|
77
77
|
output?: Pick<NodeJS.WritableStream, "write">;
|
|
78
78
|
};
|
|
79
79
|
declare const mcpProtocolVersion = "2025-06-18";
|
|
80
|
-
declare const mcpServerVersion = "0.4.
|
|
80
|
+
declare const mcpServerVersion = "0.4.1";
|
|
81
81
|
export declare function saasFunnelsMcpResources(): McpResourceDefinition[];
|
|
82
82
|
export declare function readSaaSFunnelsMcpResource(uri: string, options?: SaaSFunnelsMcpOptions): string;
|
|
83
83
|
export declare function saasFunnelsMcpToolDefinitions({ allowFunnelTests, allowFunnelWrites, allowTestWrites, includeHostedAccountTools, }?: {
|