saasfunnels 0.4.2 → 0.5.0

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
@@ -106,7 +106,11 @@ The scanner reads supported application files one at a time without the old 500-
106
106
 
107
107
  Static pricing supports literal spreads, capability/quota maps, unlimited limits, and exact Stripe lookup-key matching. It never executes customer code. Pricing definitions are inspected beyond the first ten filename matches; unrelated helpers do not count as plans.
108
108
 
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.
109
+ If extraction is unsupported, `.saasfunnels/setup-review.json` lists the files and reasons. Correct those declarations or prepare a targeted `.saasfunnels/setup-pricing.json` patch such as `{ "plans": [{ "key": "pro", "features": { "export": true } }] }`, then start a fresh `setup run` (changed inputs cannot resume an older run). The CLI fetches the existing normalized evidence as its baseline, including in a fresh worktree. Omitted plans, features, quotas, components, and prices are retained. Source content and credentials are never uploaded.
110
+
111
+ Patch mode is the default. Components replace only their matching component key; prices change only when explicitly supplied. Use `removals: [{ "planKey": "pro", "componentKey": "extra_seats" }]` for an exact removal. A full replacement must explicitly use `"mode": "snapshot"`. Removed commercial evidence is held for administrator review, preserving the current review until selected. `withdrawDeveloperAnswers` takes question IDs; `withdrawLifecycle` takes `{family, subjectKey}` identities for explicit withdrawals. Submission and selection do not publish configuration.
112
+
113
+ CLI 0.5.0 requires Setup contract 4 and stops before creating a run against an older application. Deploy the compatible server and preservation migration before releasing this CLI. Supported 0.4.x installers retain their v3 contract, with server-side completeness and removal guards.
110
114
 
111
115
  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
116
 
@@ -146,3 +150,84 @@ file. No source files or credentials belong in either upload.
146
150
  Changes to those files or application source require a fresh run. Use `--resume`
147
151
  only for unchanged interrupted work. The scan identity includes reviewed inputs
148
152
  and scanner contract version, so accepted old submissions cannot hide corrections.
153
+
154
+ ### Lifecycle findings for Funnel preparation
155
+
156
+ The plans stage can also submit `.saasfunnels/setup-lifecycle.json`, a JSON array
157
+ of reviewed application findings. The coding agent should inspect the actual
158
+ billing and entitlement code and include only established facts with relative
159
+ source paths and line numbers. This file is a structured discovery input, not an
160
+ authorization to change subscriptions or publish Funnels. It is sent only through
161
+ the existing approved setup upload.
162
+
163
+ Each finding has `family`, `subjectKey`, `state` (`supported`, `not_applicable`, or
164
+ `unknown`), `provenance`, `reason`, nullable `entry`/`action`, and family-specific
165
+ `terms`. For example:
166
+
167
+ ```json
168
+ [
169
+ {
170
+ "family": "trial_conversion",
171
+ "subjectKey": null,
172
+ "state": "supported",
173
+ "provenance": [{ "file": "src/billing.ts", "line": 42 }],
174
+ "reason": "Subscription creation configures a trial.",
175
+ "entry": null,
176
+ "action": null,
177
+ "terms": {
178
+ "durationDays": 14,
179
+ "endBehavior": "paid_conversion",
180
+ "paymentRequirement": "required",
181
+ "paidPlanKey": "pro"
182
+ }
183
+ }
184
+ ]
185
+ ```
186
+
187
+ These example terms are not defaults. Use `null`/`unknown` for unresolved terms
188
+ and real discovered keys for references. Supported families and their terms are:
189
+
190
+ - `trial_conversion`: durationDays, endBehavior, paymentRequirement, paidPlanKey.
191
+ - `feature_trial`: durationDays, endBehavior, paymentRequirement, trialKey; subjectKey identifies the feature.
192
+ - `cancellation_save`: cancellationTiming.
193
+ - `failed_payment_recovery`: recoveryAction, providerRecovery.
194
+ - `reactivation`: restoration, paidPlanKey.
195
+ - `seat_expansion` and `add_on_expansion`: quantitySourceKey, quantityBasis, includedQuantity, billingTiming; subjectKey identifies the quantity dimension or add-on.
196
+
197
+ See `src/setup-lifecycle-contract.ts` for the exact enum values and bounds. Missing
198
+ findings do not establish that a journey is unsupported. A supported or
199
+ not-applicable finding requires source evidence. Do not infer cancellation,
200
+ recovery, restoration or seat semantics from a plan name. Runtime connection
201
+ verification always remains a separate application check; submitted connections
202
+ are classified as discovered even when a local declaration says tested.
203
+
204
+ Changes to this file require a fresh scan; `--resume` rejects changed input.
205
+ Files larger than 200 KB, invalid or duplicate findings, and sensitive source
206
+ paths are rejected. No raw source or credentials belong in the findings. This
207
+ structured input path does not itself automatically infer lifecycle behavior
208
+ from arbitrary application code.
209
+
210
+ During the ordinary source scan, Setup also discovers a bounded set of billing
211
+ patterns automatically. It recognizes a locally imported Stripe client, literal
212
+ subscription/Checkout `trial_period_days`, trial-end settings needing review,
213
+ subscription cancellation calls and `cancel_at_period_end`. An invoice-payment
214
+ call is surfaced as an unknown recovery capability, because ordinary invoice
215
+ payment does not establish failed-payment recovery.
216
+
217
+ Findings contain only structured terms and source locations. Payment collection,
218
+ application access after expiry, destination plans, entry/action bindings and
219
+ provider recovery policies remain unknown unless reviewed evidence establishes
220
+ them. Conflicting durations or cancellation timings remain unknown rather than
221
+ being resolved by file order. Source declarations do not prove installation.
222
+ Tests, demos, ignored/sensitive files, shadowed clients and ambiguous expressions
223
+ are excluded. This first recognizer handles direct JavaScript/TypeScript client
224
+ calls; imported client factories, other languages, new item-level Trial Offer
225
+ APIs and custom lifecycle implementations still need reviewed evidence. Explicit
226
+ reviewed declarations take precedence per family/subject, as with reviewed
227
+ pricing declarations; they are still presented for workspace approval.
228
+
229
+ Provider references: [subscription cancellation](https://docs.stripe.com/billing/subscriptions/cancel),
230
+ [Checkout free trials](https://docs.stripe.com/payments/checkout/free-trials), and
231
+ [invoice payment](https://docs.stripe.com/api/invoices/pay). New
232
+ [Trial Offers](https://docs.stripe.com/billing/subscriptions/trials) are a different
233
+ contract; this recognizer does not infer their terms from older trial parameters.
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.2";
235861
+ var SAASFUNNELS_CLI_VERSION = "0.5.0";
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({