saasfunnels 0.3.2 → 0.3.3

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 CHANGED
@@ -108,4 +108,6 @@ Static pricing supports literal spreads, capability/quota maps, unlimited limits
108
108
 
109
109
  If extraction is unsupported, `.saasfunnels/setup-review.json` lists the files and reasons. Correct those declarations or review a `.saasfunnels/setup-pricing.json` file with `{ "plans": [{ "key": "pro", "name": "Pro", "features": { "export": true }, "prices": [{ "key": "price_ACTUAL_ID" }] }] }`, then resume. Use real identifiers from the connected merchant. Raw source files are never uploaded by guided setup or the pricing handoff.
110
110
 
111
+ Discovery follows Git ignore rules (including custom build folders) while keeping tracked application sources and new, non-ignored source files. Standalone folders without Git use the standard source filters.
112
+
111
113
  The command does not implement arbitrary payment code, approve feature access, or verify transactions. Complete **Review and verify** in Setup after deploying the runtime and payment integration. Requires the server's guided setup API release.
package/dist/library.js CHANGED
@@ -24187,6 +24187,11 @@ function agentCapabilityAllowedAtBoundary(id, boundary, { mutationsEnabled = fal
24187
24187
  return true;
24188
24188
  }
24189
24189
 
24190
+ // src/source-scope.ts
24191
+ import { execFile } from "node:child_process";
24192
+ import { promisify } from "node:util";
24193
+ var exec = promisify(execFile);
24194
+
24190
24195
  // src/feature-setup.ts
24191
24196
  var import_yaml = __toESM(require_dist(), 1);
24192
24197
  var schemaVersion = 1;
@@ -24264,7 +24269,7 @@ function validateFeatureCatalogManifest(value) {
24264
24269
 
24265
24270
  // src/identity.ts
24266
24271
  var SAASFUNNELS_CLI_NAME = "saasfunnels";
24267
- var SAASFUNNELS_CLI_VERSION = "0.3.2";
24272
+ var SAASFUNNELS_CLI_VERSION = "0.3.3";
24268
24273
  var SAASFUNNELS_PRODUCT_NAME = "SaaSFunnels";
24269
24274
  var SAASFUNNELS_DEFAULT_API_BASE_URL = "https://app.saasfunnels.ai";
24270
24275
  var SAASFUNNELS_ENV = Object.freeze({
@@ -219160,8 +219160,8 @@ function extractSetupPricing(source, kind, catalogPrices = []) {
219160
219160
 
219161
219161
  // src/setup-run.ts
219162
219162
  import { createHash as createHash3 } from "node:crypto";
219163
- import { execFile as execFile2 } from "node:child_process";
219164
- import { promisify as promisify2 } from "node:util";
219163
+ import { execFile as execFile3 } from "node:child_process";
219164
+ import { promisify as promisify3 } from "node:util";
219165
219165
  import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir3 } from "node:fs/promises";
219166
219166
  import { join as join4 } from "node:path";
219167
219167
 
@@ -233679,6 +233679,56 @@ function date4(params) {
233679
233679
  // node_modules/zod/v4/classic/external.js
233680
233680
  config(en_default());
233681
233681
 
233682
+ // src/source-scope.ts
233683
+ import { execFile as execFile2 } from "node:child_process";
233684
+ import { promisify as promisify2 } from "node:util";
233685
+ var exec2 = promisify2(execFile2);
233686
+ async function repositorySourceScope(cwd2) {
233687
+ try {
233688
+ await exec2("git", ["rev-parse", "--is-inside-work-tree"], { cwd: cwd2 });
233689
+ } catch (error51) {
233690
+ const failure = error51;
233691
+ if (failure.code === "ENOENT" || failure.stderr?.includes("not a git repository"))
233692
+ return (_path) => true;
233693
+ throw new Error(
233694
+ "Cannot read repository source scope. Check Git access and retry."
233695
+ );
233696
+ }
233697
+ let stdout;
233698
+ try {
233699
+ ({ stdout } = await exec2(
233700
+ "git",
233701
+ [
233702
+ "ls-files",
233703
+ "--cached",
233704
+ "--others",
233705
+ "--exclude-standard",
233706
+ "-z",
233707
+ "--",
233708
+ "."
233709
+ ],
233710
+ {
233711
+ cwd: cwd2,
233712
+ maxBuffer: 32 * 1024 * 1024
233713
+ }
233714
+ ));
233715
+ } catch {
233716
+ throw new Error(
233717
+ "Cannot list repository sources. Check Git access and retry."
233718
+ );
233719
+ }
233720
+ const included = /* @__PURE__ */ new Set([""]);
233721
+ for (const path of stdout.split("\0").filter(Boolean)) {
233722
+ included.add(path);
233723
+ let end = path.lastIndexOf("/");
233724
+ while (end > 0) {
233725
+ included.add(path.slice(0, end));
233726
+ end = path.lastIndexOf("/", end - 1);
233727
+ }
233728
+ }
233729
+ return (path) => included.has(path);
233730
+ }
233731
+
233682
233732
  // src/feature-setup.ts
233683
233733
  var import_yaml2 = __toESM(require_dist(), 1);
233684
233734
  import { createHash as createHash2, randomUUID } from "node:crypto";
@@ -235973,6 +236023,7 @@ function allowedPath(path, excludes) {
235973
236023
  );
235974
236024
  }
235975
236025
  async function walkFiles(input) {
236026
+ const inRepository = await repositorySourceScope(input.cwd);
235976
236027
  const files = [];
235977
236028
  const queue = input.roots.map((root) => resolve2(input.cwd, root));
235978
236029
  const seen = /* @__PURE__ */ new Set();
@@ -235982,7 +236033,8 @@ async function walkFiles(input) {
235982
236033
  if (seen.has(current)) continue;
235983
236034
  seen.add(current);
235984
236035
  const relativePath = safeRelative(input.cwd, current);
235985
- if (!relativePath || !allowedPath(relativePath, input.excludes)) continue;
236036
+ if (!relativePath || !inRepository(relativePath) || !allowedPath(relativePath, input.excludes))
236037
+ continue;
235986
236038
  let currentStat;
235987
236039
  try {
235988
236040
  currentStat = await lstat(current);
@@ -236709,13 +236761,15 @@ async function discoverPlanSourceCandidates(input) {
236709
236761
  const roots = input.roots ?? [".", "config", ...defaultRoots];
236710
236762
  const seen = /* @__PURE__ */ new Set();
236711
236763
  const candidates = [];
236764
+ const inRepository = await repositorySourceScope(input.cwd);
236712
236765
  const queue = roots.map((root) => resolve3(input.cwd, root));
236713
236766
  while (queue.length) {
236714
236767
  const current = queue.shift();
236715
236768
  if (seen.has(current)) continue;
236716
236769
  seen.add(current);
236717
236770
  const relativePath = normalize(relative2(input.cwd, current));
236718
- if (relativePath && !allowed(relativePath, excludes)) continue;
236771
+ if (!inRepository(relativePath) || relativePath && !allowed(relativePath, excludes))
236772
+ continue;
236719
236773
  let entryStat;
236720
236774
  try {
236721
236775
  entryStat = await lstat2(current);
@@ -236979,13 +237033,15 @@ async function discoverPlanBranches(input) {
236979
237033
  const branches = [];
236980
237034
  const constants = /* @__PURE__ */ new Map();
236981
237035
  const pending = [];
237036
+ const inRepository = await repositorySourceScope(input.cwd);
236982
237037
  const queue = roots.map((root) => resolve4(input.cwd, root));
236983
237038
  while (queue.length) {
236984
237039
  const current = queue.shift();
236985
237040
  if (seen.has(current)) continue;
236986
237041
  seen.add(current);
236987
237042
  const relativePath = normalize2(relative3(input.cwd, current));
236988
- if (relativePath && !allowed2(relativePath, excludes)) continue;
237043
+ if (!inRepository(relativePath) || relativePath && !allowed2(relativePath, excludes))
237044
+ continue;
236989
237045
  let entryStat;
236990
237046
  try {
236991
237047
  entryStat = await lstat3(current);
@@ -237048,7 +237104,7 @@ async function discoverPlanBranches(input) {
237048
237104
  }
237049
237105
 
237050
237106
  // src/setup-run.ts
237051
- var exec2 = promisify2(execFile2);
237107
+ var exec3 = promisify3(execFile3);
237052
237108
  var hash2 = (text) => createHash3("sha256").update(text).digest("hex");
237053
237109
  var contextSchema = external_exports.object({
237054
237110
  workspaceId: external_exports.string(),
@@ -237121,15 +237177,15 @@ async function runGuidedSetup(options) {
237121
237177
  "Connect Stripe and create app credentials in Setup first."
237122
237178
  );
237123
237179
  try {
237124
- await exec2("git", ["rev-parse", "HEAD"], { cwd: options.cwd });
237125
- await exec2("git", ["remote", "get-url", "origin"], { cwd: options.cwd });
237180
+ await exec3("git", ["rev-parse", "HEAD"], { cwd: options.cwd });
237181
+ await exec3("git", ["remote", "get-url", "origin"], { cwd: options.cwd });
237126
237182
  } catch {
237127
237183
  throw new Error(
237128
237184
  "Repository setup needed: run this command inside your app\u2019s Git repository with an initial commit and an origin remote. No push or production deploy is required for discovery."
237129
237185
  );
237130
237186
  }
237131
- const head = (await exec2("git", ["rev-parse", "HEAD"], { cwd: options.cwd })).stdout.trim();
237132
- const diff = (await exec2(
237187
+ const head = (await exec3("git", ["rev-parse", "HEAD"], { cwd: options.cwd })).stdout.trim();
237188
+ const diff = (await exec3(
237133
237189
  "git",
237134
237190
  [
237135
237191
  "diff",
@@ -237142,7 +237198,7 @@ async function runGuidedSetup(options) {
237142
237198
  ],
237143
237199
  { cwd: options.cwd, maxBuffer: 8e6 }
237144
237200
  )).stdout;
237145
- const untracked = (await exec2("git", ["ls-files", "--others", "--exclude-standard", "-z"], {
237201
+ const untracked = (await exec3("git", ["ls-files", "--others", "--exclude-standard", "-z"], {
237146
237202
  cwd: options.cwd
237147
237203
  })).stdout.split("\0").filter(
237148
237204
  (path) => path && !path.startsWith(".saasfunnels/") && !/(^|\/)(\.env|node_modules|dist|\.next)(\/|$|\.)/i.test(path)
@@ -237158,7 +237214,7 @@ async function runGuidedSetup(options) {
237158
237214
  ])
237159
237215
  );
237160
237216
  const revision = `${head}:${hash2(JSON.stringify([diff, sourceHashes]))}`;
237161
- const remote = (await exec2("git", ["remote", "get-url", "origin"], { cwd: options.cwd })).stdout.trim();
237217
+ const remote = (await exec3("git", ["remote", "get-url", "origin"], { cwd: options.cwd })).stdout.trim();
237162
237218
  const repositoryKey = safeRepositoryKey(remote);
237163
237219
  const statePath = join4(options.cwd, ".saasfunnels", "setup-run.json");
237164
237220
  if (options.resume) {
@@ -237477,7 +237533,7 @@ import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from
237477
237533
 
237478
237534
  // src/identity.ts
237479
237535
  var SAASFUNNELS_CLI_NAME = "saasfunnels";
237480
- var SAASFUNNELS_CLI_VERSION = "0.3.2";
237536
+ var SAASFUNNELS_CLI_VERSION = "0.3.3";
237481
237537
  var SAASFUNNELS_PRODUCT_NAME = "SaaSFunnels";
237482
237538
  var SAASFUNNELS_DEFAULT_API_BASE_URL = "https://app.saasfunnels.ai";
237483
237539
  var SAASFUNNELS_ENV = Object.freeze({
@@ -1,5 +1,5 @@
1
1
  export declare const SAASFUNNELS_CLI_NAME = "saasfunnels";
2
- export declare const SAASFUNNELS_CLI_VERSION = "0.3.2";
2
+ export declare const SAASFUNNELS_CLI_VERSION = "0.3.3";
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<{
@@ -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.3.2";
80
+ declare const mcpServerVersion = "0.3.3";
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, }?: {
@@ -0,0 +1 @@
1
+ export declare function repositorySourceScope(cwd: string): Promise<(_path: string) => boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "saasfunnels",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "private": false,
5
5
  "description": "SaaSFunnels CLI and local stdio MCP server",
6
6
  "author": "SaaSFunnels",