@nextcommerce/campaigns-os 1.33.0 → 1.34.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/CHANGELOG.md +42 -0
- package/README.md +3 -0
- package/compatibility.json +1 -1
- package/contracts/fixtures/runtime-recipe/accept/current.json +3 -5
- package/contracts/fixtures/runtime-recipe/accept/minimal.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/committed-output-claim.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/missing-required-field.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/unknown-kind.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/unknown-output-check.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/unknown-revision.json +2 -4
- package/contracts/fixtures/runtime-recipe/reject/unknown-step-id.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json +3 -5
- package/contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json +3 -5
- package/contracts/release-ledger.json +255 -0
- package/contracts/runtime-recipe.campaigns-os-node-v1.json +3 -5
- package/contracts/supported-surface.json +5 -3
- package/docs/orientation-contract-reference.md +2 -1
- package/docs/qa-and-test-orders.md +26 -0
- package/docs/runtime-readiness.md +3 -3
- package/docs/sdk-storage-compatibility.md +19 -0
- package/docs/supported-surface.md +2 -1
- package/docs/versioning.md +1 -1
- package/package.json +11 -7
- package/src/cli.mjs +22 -2
- package/src/sdk-storage-compatibility.mjs +359 -0
|
@@ -4593,6 +4593,261 @@
|
|
|
4593
4593
|
}
|
|
4594
4594
|
],
|
|
4595
4595
|
"entry_sha256": "76e84afa5f9228efd00a3f8aca8fd2a601a01955ebac370209598633ae3f790c"
|
|
4596
|
+
},
|
|
4597
|
+
{
|
|
4598
|
+
"id": "RL-0119",
|
|
4599
|
+
"sequence": 119,
|
|
4600
|
+
"date": "2026-09-17",
|
|
4601
|
+
"kind": "release",
|
|
4602
|
+
"surface_version": "1.34.0",
|
|
4603
|
+
"changelog_section": "1.34.0",
|
|
4604
|
+
"changelog_sha256": "d0753f1573b293528397ff0d3bee714f6e5fdb74d94d4f19cc14066bf2720ac8",
|
|
4605
|
+
"agent_impact": "New sdk storage-check command scans explicitly scoped Git-tracked HTML/JavaScript against an SDK-owned storage migration manifest. Supply target SDK version and manifest path; inspect incompatible and unknown findings before a bump. The scanner writes neither campaign files nor run journals. Reports carry file hashes and manifest provenance. Unsupported SDK versions and unresolved code cannot establish compatibility; source evidence never replaces browser/order/analytics proof. The SDK manifest is supplied explicitly while campaign-cart #102 awaits publication.",
|
|
4606
|
+
"compatibility": "additive",
|
|
4607
|
+
"migration": "none",
|
|
4608
|
+
"changes": [
|
|
4609
|
+
{
|
|
4610
|
+
"class": "compatibility_policy",
|
|
4611
|
+
"path": "compatibility.json",
|
|
4612
|
+
"surface_entry": "compatibility.json",
|
|
4613
|
+
"summary": "Package compatibility version follows supported surface 1.34.0."
|
|
4614
|
+
},
|
|
4615
|
+
{
|
|
4616
|
+
"class": "compatibility_policy",
|
|
4617
|
+
"path": "contracts/supported-surface.json",
|
|
4618
|
+
"surface_entry": "contracts/supported-surface.json",
|
|
4619
|
+
"summary": "Add sdk CLI command and the scanner reference to supported surface; version 1.34.0."
|
|
4620
|
+
},
|
|
4621
|
+
{
|
|
4622
|
+
"class": "documentation",
|
|
4623
|
+
"path": "docs/orientation-contract-reference.md",
|
|
4624
|
+
"surface_entry": "docs/orientation-contract-reference.md",
|
|
4625
|
+
"summary": "Regenerate the orientation reference for surface 1.34.0."
|
|
4626
|
+
},
|
|
4627
|
+
{
|
|
4628
|
+
"class": "named_surface",
|
|
4629
|
+
"path": "docs/runtime-readiness.md",
|
|
4630
|
+
"surface_entry": "docs/runtime-readiness.md",
|
|
4631
|
+
"summary": "Regenerate runtime readiness for surface 1.34.0."
|
|
4632
|
+
},
|
|
4633
|
+
{
|
|
4634
|
+
"class": "named_surface",
|
|
4635
|
+
"path": "docs/sdk-storage-compatibility.md",
|
|
4636
|
+
"surface_entry": "docs/sdk-storage-compatibility.md",
|
|
4637
|
+
"summary": "Document explicit manifest provenance, target version, tracked scope, statuses, exclusions and source-only evidence limits."
|
|
4638
|
+
},
|
|
4639
|
+
{
|
|
4640
|
+
"class": "compatibility_policy",
|
|
4641
|
+
"path": "docs/versioning.md",
|
|
4642
|
+
"surface_entry": "docs/versioning.md",
|
|
4643
|
+
"summary": "Document package and supported surface version 1.34.0."
|
|
4644
|
+
},
|
|
4645
|
+
{
|
|
4646
|
+
"class": "generated_runtime",
|
|
4647
|
+
"path": "package-lock.json",
|
|
4648
|
+
"surface_entry": null,
|
|
4649
|
+
"summary": "Lockfile package version follows 1.34.0; dependencies unchanged."
|
|
4650
|
+
},
|
|
4651
|
+
{
|
|
4652
|
+
"class": "package_export",
|
|
4653
|
+
"path": "package.json",
|
|
4654
|
+
"surface_entry": null,
|
|
4655
|
+
"summary": "Version 1.34.0 and ship the SDK storage compatibility reference."
|
|
4656
|
+
},
|
|
4657
|
+
{
|
|
4658
|
+
"class": "cli_surface",
|
|
4659
|
+
"path": "src/cli.mjs",
|
|
4660
|
+
"surface_entry": "sdk",
|
|
4661
|
+
"summary": "New read-only sdk storage-check dispatch, flags and report; suppress lifecycle and session writes for this inspection."
|
|
4662
|
+
},
|
|
4663
|
+
{
|
|
4664
|
+
"class": "compatibility_policy",
|
|
4665
|
+
"path": "docs/supported-surface.md",
|
|
4666
|
+
"surface_entry": "docs/supported-surface.md",
|
|
4667
|
+
"summary": "Document sdk storage-check as a supported CLI command."
|
|
4668
|
+
}
|
|
4669
|
+
],
|
|
4670
|
+
"entry_sha256": "1db46aa2c1f7fee6ebc788cb355690113e08ff0542a0494c6011f439f4fa0ba1"
|
|
4671
|
+
},
|
|
4672
|
+
{
|
|
4673
|
+
"id": "RL-0120",
|
|
4674
|
+
"sequence": 120,
|
|
4675
|
+
"date": "2026-09-18",
|
|
4676
|
+
"kind": "release",
|
|
4677
|
+
"surface_version": "1.34.1",
|
|
4678
|
+
"changelog_section": "1.34.1",
|
|
4679
|
+
"changelog_sha256": "79fdc2f42ae0258ffb29a9f8950b50894386cfc38bae80ae711181f0ce5fe872",
|
|
4680
|
+
"agent_impact": "Runtime recipe 1.0.2 reflects Playwright removing fsevents. Exact v1 agreement semantics remain unchanged. Browser installation uses the Playwright resolved beside Campaigns OS.",
|
|
4681
|
+
"compatibility": "compatible",
|
|
4682
|
+
"migration": "After a dependency update, run campaigns-os qa install-browser to install the matching Chromium.",
|
|
4683
|
+
"changes": [
|
|
4684
|
+
{
|
|
4685
|
+
"class": "workflow",
|
|
4686
|
+
"path": ".github/workflows/ci.yml",
|
|
4687
|
+
"surface_entry": null,
|
|
4688
|
+
"summary": "Require independent types, unit, contracts, browser and consumer-install proof behind check."
|
|
4689
|
+
},
|
|
4690
|
+
{
|
|
4691
|
+
"class": "named_surface",
|
|
4692
|
+
"path": "contracts/fixtures/runtime-recipe/accept/current.json",
|
|
4693
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/accept/current.json",
|
|
4694
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4695
|
+
},
|
|
4696
|
+
{
|
|
4697
|
+
"class": "named_surface",
|
|
4698
|
+
"path": "contracts/fixtures/runtime-recipe/accept/minimal.json",
|
|
4699
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/accept/minimal.json",
|
|
4700
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4701
|
+
},
|
|
4702
|
+
{
|
|
4703
|
+
"class": "named_surface",
|
|
4704
|
+
"path": "contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json",
|
|
4705
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json",
|
|
4706
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4707
|
+
},
|
|
4708
|
+
{
|
|
4709
|
+
"class": "named_surface",
|
|
4710
|
+
"path": "contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json",
|
|
4711
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json",
|
|
4712
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4713
|
+
},
|
|
4714
|
+
{
|
|
4715
|
+
"class": "named_surface",
|
|
4716
|
+
"path": "contracts/fixtures/runtime-recipe/reject/committed-output-claim.json",
|
|
4717
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/committed-output-claim.json",
|
|
4718
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4719
|
+
},
|
|
4720
|
+
{
|
|
4721
|
+
"class": "named_surface",
|
|
4722
|
+
"path": "contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json",
|
|
4723
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json",
|
|
4724
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4725
|
+
},
|
|
4726
|
+
{
|
|
4727
|
+
"class": "named_surface",
|
|
4728
|
+
"path": "contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json",
|
|
4729
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json",
|
|
4730
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4731
|
+
},
|
|
4732
|
+
{
|
|
4733
|
+
"class": "named_surface",
|
|
4734
|
+
"path": "contracts/fixtures/runtime-recipe/reject/missing-required-field.json",
|
|
4735
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/missing-required-field.json",
|
|
4736
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4737
|
+
},
|
|
4738
|
+
{
|
|
4739
|
+
"class": "named_surface",
|
|
4740
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unknown-kind.json",
|
|
4741
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unknown-kind.json",
|
|
4742
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4743
|
+
},
|
|
4744
|
+
{
|
|
4745
|
+
"class": "named_surface",
|
|
4746
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json",
|
|
4747
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json",
|
|
4748
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4749
|
+
},
|
|
4750
|
+
{
|
|
4751
|
+
"class": "named_surface",
|
|
4752
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unknown-output-check.json",
|
|
4753
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unknown-output-check.json",
|
|
4754
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4755
|
+
},
|
|
4756
|
+
{
|
|
4757
|
+
"class": "named_surface",
|
|
4758
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unknown-revision.json",
|
|
4759
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unknown-revision.json",
|
|
4760
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4761
|
+
},
|
|
4762
|
+
{
|
|
4763
|
+
"class": "named_surface",
|
|
4764
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unknown-step-id.json",
|
|
4765
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unknown-step-id.json",
|
|
4766
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4767
|
+
},
|
|
4768
|
+
{
|
|
4769
|
+
"class": "named_surface",
|
|
4770
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json",
|
|
4771
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json",
|
|
4772
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4773
|
+
},
|
|
4774
|
+
{
|
|
4775
|
+
"class": "named_surface",
|
|
4776
|
+
"path": "contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json",
|
|
4777
|
+
"surface_entry": "contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json",
|
|
4778
|
+
"summary": "Regenerate recipe fixtures against revision 1.0.2 and surface 1.34.1."
|
|
4779
|
+
},
|
|
4780
|
+
{
|
|
4781
|
+
"class": "hashed_surface",
|
|
4782
|
+
"path": "contracts/runtime-recipe.campaigns-os-node-v1.json",
|
|
4783
|
+
"surface_entry": "contracts/runtime-recipe.campaigns-os-node-v1.json",
|
|
4784
|
+
"summary": "Advance recipe to 1.0.2 with an empty exact install-script dependency expectation."
|
|
4785
|
+
},
|
|
4786
|
+
{
|
|
4787
|
+
"class": "compatibility_policy",
|
|
4788
|
+
"path": "contracts/supported-surface.json",
|
|
4789
|
+
"surface_entry": "contracts/supported-surface.json",
|
|
4790
|
+
"summary": "Advance the supported surface to 1.34.1 and refresh the runtime recipe hash."
|
|
4791
|
+
},
|
|
4792
|
+
{
|
|
4793
|
+
"class": "named_surface",
|
|
4794
|
+
"path": "docs/qa-and-test-orders.md",
|
|
4795
|
+
"surface_entry": "docs/qa-and-test-orders.md",
|
|
4796
|
+
"summary": "Document runtime recipe 1.0.2 and package-owned browser installation and validation."
|
|
4797
|
+
},
|
|
4798
|
+
{
|
|
4799
|
+
"class": "named_surface",
|
|
4800
|
+
"path": "docs/runtime-readiness.md",
|
|
4801
|
+
"surface_entry": "docs/runtime-readiness.md",
|
|
4802
|
+
"summary": "Document runtime recipe 1.0.2 and package-owned browser installation and validation."
|
|
4803
|
+
},
|
|
4804
|
+
{
|
|
4805
|
+
"class": "generated_runtime",
|
|
4806
|
+
"path": "package-lock.json",
|
|
4807
|
+
"surface_entry": null,
|
|
4808
|
+
"summary": "Lock reviewed dependency updates and remove the retired fsevents install script."
|
|
4809
|
+
},
|
|
4810
|
+
{
|
|
4811
|
+
"class": "package_export",
|
|
4812
|
+
"path": "package.json",
|
|
4813
|
+
"surface_entry": null,
|
|
4814
|
+
"summary": "Validate Playwright 1.63 and YAML 2.9.1; expose independent CI checks and automatic unit-test discovery."
|
|
4815
|
+
},
|
|
4816
|
+
{
|
|
4817
|
+
"class": "documentation",
|
|
4818
|
+
"path": "docs/orientation-contract-reference.md",
|
|
4819
|
+
"surface_entry": "docs/orientation-contract-reference.md",
|
|
4820
|
+
"summary": "Regenerate the orientation reference for supported surface 1.34.1."
|
|
4821
|
+
}
|
|
4822
|
+
],
|
|
4823
|
+
"entry_sha256": "e7bb42ad4d748d9fefed5d15a9cef195638f465cf7e93cff2892fde3bd72a1c5"
|
|
4824
|
+
},
|
|
4825
|
+
{
|
|
4826
|
+
"id": "RL-0121",
|
|
4827
|
+
"sequence": 121,
|
|
4828
|
+
"date": "2026-09-18",
|
|
4829
|
+
"kind": "release",
|
|
4830
|
+
"surface_version": null,
|
|
4831
|
+
"changelog_section": "1.34.1+agent.1",
|
|
4832
|
+
"changelog_sha256": "8b3ea071381418b1516d5e02d4b6b26ce39e7b9f4c0b0fc8ff5b3e05a841ae39",
|
|
4833
|
+
"agent_impact": "HTML parsing uses parse5 8.0.1 and entities 8.1.0. Existing ESM imports and the declared Node >=20.19.0 minimum remain compatible. No consumer action is required.",
|
|
4834
|
+
"compatibility": "compatible",
|
|
4835
|
+
"migration": "none",
|
|
4836
|
+
"changes": [
|
|
4837
|
+
{
|
|
4838
|
+
"class": "package_export",
|
|
4839
|
+
"path": "package.json",
|
|
4840
|
+
"surface_entry": null,
|
|
4841
|
+
"summary": "Upgrade parse5 to ^8.0.1 without changing package exports or the supported Node range."
|
|
4842
|
+
},
|
|
4843
|
+
{
|
|
4844
|
+
"class": "generated_runtime",
|
|
4845
|
+
"path": "package-lock.json",
|
|
4846
|
+
"surface_entry": null,
|
|
4847
|
+
"summary": "Lock parse5 8.0.1 and entities 8.1.0 as the reviewed HTML parser dependencies."
|
|
4848
|
+
}
|
|
4849
|
+
],
|
|
4850
|
+
"entry_sha256": "ae6ef7c17e02e52cad5ba4faa1e4adf8ba3bba375acac36e3e9046d8273c053f"
|
|
4596
4851
|
}
|
|
4597
4852
|
]
|
|
4598
4853
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"_growth_note": "When a bound below is genuinely reached, the answer is to find out why before raising it. A dependency install that exceeds its bound on a warm machine is a supply-chain change, not a slow morning; an output inventory that exceeds its file or byte bound is a build that went wrong, not a package that grew 50x overnight. Raising a bound is the fallback, it advances recipe_revision, and it owes a release-ledger entry. Widening the accepted npm range follows the same path, and its trigger is external and checkable: widen when a Node release line ships that npm major by default, not when a particular machine happens to have it installed.",
|
|
4
4
|
"schema": "campaigns-os-runtime-recipe/v1",
|
|
5
5
|
"recipe_kind": "campaigns-os-node-v1",
|
|
6
|
-
"recipe_revision": "1.0.
|
|
6
|
+
"recipe_revision": "1.0.2",
|
|
7
7
|
"refusal_reason_code": "runtime_recipe_refused",
|
|
8
8
|
"fail_closed": true,
|
|
9
9
|
"unperformable_check_disposition": "failed",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"stdin": "closed",
|
|
85
85
|
"lifecycle_scripts": "disabled",
|
|
86
86
|
"timeout_bound": "install_seconds",
|
|
87
|
-
"rationale": "ci rather than install, so the lockfile is authoritative and the tree is reproducible. --ignore-scripts is the load-bearing flag: it suppresses every dependency lifecycle script and the target's own prepare.
|
|
87
|
+
"rationale": "ci rather than install, so the lockfile is authoritative and the tree is reproducible. --ignore-scripts is the load-bearing flag: it suppresses every dependency lifecycle script and the target's own prepare. No dependency in the resolved tree declares an install script. The exact list in target_expectations remains a reviewed expectation: additions and removals require a recipe revision, so existing v1 consumers retain the same agreement semantics. --no-audit and --fund=false remove two network- and output-side effects that are not part of preparing a runtime."
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"id": "build",
|
|
@@ -286,9 +286,7 @@
|
|
|
286
286
|
"build:spec": "tsc -p campaign-spec/tsconfig.build.json",
|
|
287
287
|
"prepare": "npm run build:spec"
|
|
288
288
|
},
|
|
289
|
-
"install_script_dependencies": [
|
|
290
|
-
"fsevents"
|
|
291
|
-
]
|
|
289
|
+
"install_script_dependencies": []
|
|
292
290
|
},
|
|
293
291
|
"capabilities": {
|
|
294
292
|
"_note": "What a generation prepared by this recipe can and cannot do. Stated explicitly because 'runtime ready' invites the wrong reading: the same flag that makes the install safe also means the prepared generation has no browser to drive. Preparing a runtime and being able to run browser QA are different readiness questions, and this recipe answers only the first.",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "The downstream contract manifest. Everything listed here is SUPPORTED SURFACE: consumers (campaigns-agent, campaign-builder, the private ops repo, page-kit campaign repos) may depend on it, and changing it is a deliberate act \u2014 hashed entries require a surface_version bump in the same change (check-supported-surface.mjs --base, mirroring the skills.json bump gate), named entries must keep existing at their path, cli_commands must keep resolving in the CLI dispatch, package_exports must stay exported, and every entry must ship in the npm pack (files[] coverage). Anything NOT listed here \u2014 src/** internals, scripts/** checkers, examples/**, prompts/**, contracts/** other than this file and the entries named[] below (the orientation contract, the release ledger, and the consumer-facing orientation fixtures) \u2014 is implementation: consumers may read it for context but must not build on it, and it can change without notice. Rationale and the compatibility promise: docs/supported-surface.md.",
|
|
3
|
-
"surface_version": "1.
|
|
3
|
+
"surface_version": "1.34.1",
|
|
4
4
|
"package_exports": [
|
|
5
5
|
"./commercial-journey",
|
|
6
6
|
"./commercial-parity",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"checkpoint",
|
|
24
24
|
"page-kit",
|
|
25
25
|
"spec",
|
|
26
|
+
"sdk",
|
|
26
27
|
"doctor",
|
|
27
28
|
"bundle",
|
|
28
29
|
"next",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
"sha256": "f5097f6cccaf211d442c1ebc584d2c76d5a07a44e587df130de02117a9412db0"
|
|
44
45
|
},
|
|
45
46
|
"contracts/runtime-recipe.campaigns-os-node-v1.json": {
|
|
46
|
-
"sha256": "
|
|
47
|
+
"sha256": "90aaaaade90cf2525ea1aa05be5cb2d02b57e6e59f9278a946efa8a087946fd3"
|
|
47
48
|
},
|
|
48
49
|
"schemas/campaign-build-brief.v1.schema.json": {
|
|
49
50
|
"sha256": "d524003184131398dc15fdb84385af1be0de0c69d6c5ede7278689a5b6101b81"
|
|
@@ -175,6 +176,7 @@
|
|
|
175
176
|
"contracts/fixtures/runtime-recipe/reject/missing-required-field.json",
|
|
176
177
|
"contracts/fixtures/orientation/hostile-target/repo/bin/intended.mjs",
|
|
177
178
|
"contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/package.json",
|
|
178
|
-
"contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/tripwire.mjs"
|
|
179
|
+
"contracts/fixtures/orientation/hostile-target/repo/hostile-dependency-tripwire/tripwire.mjs",
|
|
180
|
+
"docs/sdk-storage-compatibility.md"
|
|
179
181
|
]
|
|
180
182
|
}
|
|
@@ -25,7 +25,7 @@ Ledger schema id: `campaigns-os-release-ledger/v1`
|
|
|
25
25
|
Change policy version: `1.0.0`
|
|
26
26
|
Reason-code vocabulary version: `1.0.0`
|
|
27
27
|
Limits version: `1.0.0`
|
|
28
|
-
Supported surface at generation time: `1.
|
|
28
|
+
Supported surface at generation time: `1.34.1`
|
|
29
29
|
|
|
30
30
|
## Forward compatibility
|
|
31
31
|
|
|
@@ -228,6 +228,7 @@ so a renamed command fails here as well as at the supported-surface gate.
|
|
|
228
228
|
- `campaigns-os checkpoint`
|
|
229
229
|
- `campaigns-os page-kit`
|
|
230
230
|
- `campaigns-os spec`
|
|
231
|
+
- `campaigns-os sdk`
|
|
231
232
|
- `campaigns-os doctor`
|
|
232
233
|
- `campaigns-os bundle`
|
|
233
234
|
- `campaigns-os next`
|
|
@@ -1689,3 +1689,29 @@ meta assertions to avoid duplicating their values into the verdict.
|
|
|
1689
1689
|
Older verdicts lacking this assertion were not checked. Consumers must retain
|
|
1690
1690
|
run/time/spec-hash context and segregate server-stamped untrusted submissions;
|
|
1691
1691
|
a trusted submission attests the runner, not execution or resource identity.
|
|
1692
|
+
|
|
1693
|
+
### Playwright updates and consumer installs
|
|
1694
|
+
|
|
1695
|
+
After installing or updating Campaigns OS, run `npx campaigns-os qa install-browser`
|
|
1696
|
+
from the campaign project (or `campaigns-os qa install-browser` for a global
|
|
1697
|
+
installation). This resolves the same Playwright package as QA and polish capture.
|
|
1698
|
+
A project's own `npx playwright install` can resolve a different version and install
|
|
1699
|
+
a different Chromium build. Campaigns OS is an optional-dependency owner, not a
|
|
1700
|
+
Playwright peer dependency: npm may share a compatible copy or install a nested one.
|
|
1701
|
+
The consumer project's lockfile determines its installed version; this repository's
|
|
1702
|
+
lockfile only controls checkout builds.
|
|
1703
|
+
|
|
1704
|
+
CI reports independent types, unit, contracts, and browser lanes under the existing
|
|
1705
|
+
required `check` status. `npm run check:browser` requires working Chromium and fails
|
|
1706
|
+
on launch errors. `npm run check:consumer` installs the packed package into fresh
|
|
1707
|
+
projects with a shared Playwright, an older conflicting version, and `latest`, then
|
|
1708
|
+
installs and launches Campaigns OS's Chromium. These checks use local fixture pages;
|
|
1709
|
+
they do not place merchant orders. `npm run check` remains the browser-free contributor
|
|
1710
|
+
check; run the browser commands separately after installing Chromium.
|
|
1711
|
+
|
|
1712
|
+
Dependency PRs must include any required release-ledger entries. If the set of
|
|
1713
|
+
install-script dependencies changes, update the runtime recipe's exact expectation,
|
|
1714
|
+
advance its revision and the supported-surface/package patch version, and regenerate
|
|
1715
|
+
the runtime-readiness guide and fixtures. The v1 recipe still uses exact agreement:
|
|
1716
|
+
removing a dependency does not authorize silently reinterpreting that field as an
|
|
1717
|
+
allowlist. Dependabot groups minor/patch updates; major API upgrades remain separate.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
How a checkout of this repository at one commit becomes a usable installed runtime, and how a consumer decides whether a prepared one is still trustworthy. Everything below is generated from `contracts/runtime-recipe.campaigns-os-node-v1.json`, which is the only authority for these values.
|
|
10
10
|
|
|
11
|
-
Recipe kind `campaigns-os-node-v1`, revision `1.0.
|
|
11
|
+
Recipe kind `campaigns-os-node-v1`, revision `1.0.2`, validated by `schemas/campaigns-os-runtime-recipe.v1.schema.json` (`Campaigns OS Runtime Recipe v1`). Supported surface at generation time: `1.34.1`.
|
|
12
12
|
|
|
13
13
|
## What this is
|
|
14
14
|
|
|
@@ -65,7 +65,7 @@ npm ci --ignore-scripts --no-audit --fund=false
|
|
|
65
65
|
|
|
66
66
|
Working directory `target_root`, stdin `closed`, lifecycle scripts `disabled`, bounded by `install_seconds`.
|
|
67
67
|
|
|
68
|
-
ci rather than install, so the lockfile is authoritative and the tree is reproducible. --ignore-scripts is the load-bearing flag: it suppresses every dependency lifecycle script and the target's own prepare.
|
|
68
|
+
ci rather than install, so the lockfile is authoritative and the tree is reproducible. --ignore-scripts is the load-bearing flag: it suppresses every dependency lifecycle script and the target's own prepare. No dependency in the resolved tree declares an install script. The exact list in target_expectations remains a reviewed expectation: additions and removals require a recipe revision, so existing v1 consumers retain the same agreement semantics. --no-audit and --fund=false remove two network- and output-side effects that are not part of preparing a runtime.
|
|
69
69
|
|
|
70
70
|
### build
|
|
71
71
|
|
|
@@ -170,7 +170,7 @@ What this revision assumes about the target, stated as values a checker can comp
|
|
|
170
170
|
| Lockfile | `package-lock.json`, version `3`, integrity pinned `true` |
|
|
171
171
|
| Script `build:spec` | `tsc -p campaign-spec/tsconfig.build.json` |
|
|
172
172
|
| Script `prepare` | `npm run build:spec` |
|
|
173
|
-
| Dependencies declaring an install script |
|
|
173
|
+
| Dependencies declaring an install script | none |
|
|
174
174
|
|
|
175
175
|
## Bounds
|
|
176
176
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# SDK storage compatibility before a bump
|
|
2
|
+
|
|
3
|
+
Run the read-only source scanner from a campaign repository before changing its SDK pin:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npx campaigns-os sdk storage-check --target . --target-sdk 0.4.38 --manifest /path/to/campaign-cart/docs/compatibility/storage-migrations.v1.json --scope campaigns/spring,shared --json
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Omit `--json` for the concise human report. Exit 0 means source-compatible; exit 2 means incompatible or unknown; invalid arguments or manifests exit 1. No merchant files or pins are rewritten. This is independent of doctor's built HTML markup check.
|
|
10
|
+
|
|
11
|
+
The manifest is generated and owned by Campaign Cart, from its storage registry. The scanner has no independent SDK key list and fetches no remote code. Supply the generated `storage-migrations.v1.json` from the SDK contract change (campaign-cart #102); until that change is published, this command does **not** imply a released SDK tag contains that file. The report records the full file SHA-256, SDK version, supported target range, registry/extractor/input digest, and Git provenance. When the supplied bytes equal their repository HEAD blob, provenance is `verified-git-blob` with commit and repository path. Proposed, modified, or copied manifests are labeled `unverified-local-file`; the label never certifies a release. Review/pin SDK provenance separately before acting on findings. Targets outside the manifest's supported SDK range report unknown.
|
|
12
|
+
|
|
13
|
+
`--target` must name the Git root. `--scope` is mandatory: comma-separated literal repository-relative directory/file paths; use `.` only when the complete repository is intended. Add shared JavaScript directories explicitly. `--exclude` uses the same syntax and records explicit exclusions. Archives receive no implicit exemption. Only Git-tracked `.html`, `.htm`, `.js`, `.mjs`, and `.cjs` files in the selected scope are scanned, using current working-tree bytes and per-file digests; untracked files and built dependencies are outside this evidence. A selected HTML page's local script outside the selected files reports unknown. Relative scripts affected by an HTML `<base href>` also report unknown; review their actual dependency paths. Remote SDK and third-party scripts are not fetched or analyzed.
|
|
14
|
+
|
|
15
|
+
Acorn parses JavaScript ASTs; parse5 identifies executable inline HTML scripts and source offsets. Findings inventory storage area, operation, key, file/line/column, reason, and SDK-owned public replacement when supplied. The scanner recognizes direct `localStorage`/`sessionStorage`, `window`/`globalThis`/`self` properties, simple constant browser-global/storage aliases and storage destructuring, literal `getItem`/`setItem`/`removeItem` calls (including bracket method notation), property access/assignment/deletion, and lexical constant string indirection. Comments, ordinary strings, JSON script blocks and public store calls do not become storage reads. A literal legacy SDK key at or after its manifest migration boundary is incompatible. Guessed prefixes cannot establish compatibility.
|
|
16
|
+
|
|
17
|
+
Dynamic storage keys, unresolved storage methods, shadowed storage names, missing migration release evidence, unsupported target versions, and JavaScript parse failures report unknown. This bounded analysis does not execute merchant code or prove computed keys correct. It does not follow arbitrary data flow, dynamic imports, event-handler attributes, generated code or runtime-loaded script graphs. Inspect unresolved findings and include all campaign sources in scope; a clean result is only static tracked source compatibility evidence. Browser behavior, order creation, tracking and analytics still require their own proof, especially where multiple campaigns share an origin. Use the SDK public store API where the manifest recommends it; do not invent a prefix-first merchant repair.
|
|
18
|
+
|
|
19
|
+
Storage `length` property reads are unaffected metadata (`storage-metadata-read`). Storage `key()` enumeration, extracted method references, and mutations of reserved members remain unknown; enumeration cannot prove an SDK key lookup safe. Git discovery failures return one bounded CLI error. Local script diagnostics retain repository-relative spellings from HTML source, including `../` paths; excluded/outside sources are not read. The Git root and operator target are compared by filesystem device/inode identity, so supported case aliases and symlinks can name the same root. Source containment uses realpaths below the Git root without case folding. Extra positional CLI arguments are rejected so an accidental scope or version value cannot silently disappear.
|
|
@@ -14,7 +14,8 @@ implementation detail, however stable it looks.
|
|
|
14
14
|
| Surface | Contract | Change discipline |
|
|
15
15
|
|---|---|---|
|
|
16
16
|
| `schemas/*.schema.json` (all of them) | The portable contract catalog: CampaignSpec, Design Source Package, Build Packet, Build Context, Assembly Report, Doctor Output, sidecar-bundle conformance, Run Record, Workflow Finding, Build Brief, Source-HTML Manifest, Tooling Orientation, Release Ledger, QA Verdict, the QA Verdict sidecar projection, Runtime Recipe, and the legacy-migration inventory/plan/receipt trio. | Hashed. Any content change requires updating the recorded hash **and** bumping `surface_version` in the same PR. A shape change that alters meaning gets a new schema-version const — one version identifier must never cover two shapes (the 2026-08 assembly-report drift is the incident this rule encodes). Additions to an open `v0` schema are expected and consumers must tolerate unknown fields; the security-sensitive legacy-migration schemas are closed, so additions there require a new lineage. 1.28.0 (RL entry `surface_version: 1.28.0`, breaking) removed the two required Build Packet booleans `qa.test_orders_allowed` and `qa.sandbox_test_card_confirmed` (nothing read them; test orders run from `--test-order <mode>` alone), added `local-serve` to the `deploy.target` enum, and added the optional `remit_result` / `remit_base_kind` fields to the Run Record. 1.30.0 (additive) added the optional `data_layer` record to the QA Verdict's `test_orders[]` entries — the order's `dl_purchase` reading (#325). 1.33.0 (additive) added the optional `qa_verdict_publish` block to the Run Record — which verdict was posted to the QA portal, by `qa run` or `qa publish`, and what the portal answered, in the `remit_result` vocabulary (#328). |
|
|
17
|
-
| CLI commands: `start`, `prepare-build`, `build`, `polish`, `checkpoint`, `page-kit`, `spec`, `doctor`, `bundle`, `next`, `theme`, `tooling`, `install-skills`, `install-agent-context`, `validate-assembly-report`, `telemetry`, `standardize`, `qa`, `findings`, `run-record`, `run` | Scriptable entry points. The founding list (1.0.0) was the argv surface Campaigns Agent's remit fixture pins; 1.25.0 adds the partner entry path the public guides instruct — `install-skills` (skill install), `tooling status` (preflight), `next --packet` (the runtime cursor) — plus `theme`, `install-agent-context`, `validate-assembly-report`, and `telemetry`, since consent is part of the partner contract. `validate-build-packet`, formerly an undocumented and unsupported alias of `doctor`, was removed in 1.25.0+agent.7 (RL-0036) and now gets the unknown-command error; use `doctor`. `standardization-report`, a supported but redundant second spelling of `standardize` — same flags, same output, same exit codes — was removed in 1.27.0 and now gets the same unknown-command error; use `standardize`. Removing a supported command is a breaking change and is why that release moved the minor. `bundle check` validates the canonical JSON readback set and makes QA required only under `--require-qa`. `polish capture` owns page-load evidence production. `checkpoint waive` currently accepts four registered gates: `page_kit.store_profile`, `page_kit.sdk_version`, `polish.hidden_eager_media`, and `built_output.upsell_selector_scope`. `page-kit sync` (added in 1.29.0) writes the CampaignSpec's Store Profile fields and SDK pin into the target's `_data/campaigns.json` entry — the repair the first two gates name — and is the only `page-kit` subcommand. `spec derive` (added in 1.31.0) is the reverse write for the repo-derived field class (#432): the target's SDK pin, page routes and analytics ids into the packet's local CampaignSpec; it is the only `spec` subcommand, and the `page_kit.sdk_version.repo_newer` advisory names it; its `--write-map` flag (1.33.0+agent.2) also records the derived pin in the saved Map's Build hints field through the proxy Worker, never moving a Map pin backwards. `qa publish` (added in 1.33.0) posts an already-stored verdict to the QA portal without a re-run or an order, refusing a stale `spec_hash` or a verdict its Run Record already records as published (#328). Within Polish, only the broader Source Freshness waiver remains on its existing report lane; theme and QA decisions also retain their existing lanes. | Any change to this list — adding, renaming, or removing a command — bumps `surface_version` in the same PR, and since 1.25.0 `check-supported-surface.mjs --base` enforces that (before, only hashed and named entries owed a bump, so `checkpoint` landed unbumped). Subcommands, registered gates, and flags may grow freely beneath a listed command. Removing a listed command from dispatch fails the gate outright. Do not infer support for an unregistered checkpoint from the top-level command. |
|
|
17
|
+
| CLI commands: `start`, `prepare-build`, `build`, `polish`, `checkpoint`, `page-kit`, `spec`, `doctor`, `bundle`, `next`, `theme`, `tooling`, `install-skills`, `install-agent-context`, `validate-assembly-report`, `telemetry`, `standardize`, `qa`, `findings`, `run-record`, `run`, `sdk` | Scriptable entry points. The founding list (1.0.0) was the argv surface Campaigns Agent's remit fixture pins; 1.25.0 adds the partner entry path the public guides instruct — `install-skills` (skill install), `tooling status` (preflight), `next --packet` (the runtime cursor) — plus `theme`, `install-agent-context`, `validate-assembly-report`, and `telemetry`, since consent is part of the partner contract. `validate-build-packet`, formerly an undocumented and unsupported alias of `doctor`, was removed in 1.25.0+agent.7 (RL-0036) and now gets the unknown-command error; use `doctor`. `standardization-report`, a supported but redundant second spelling of `standardize` — same flags, same output, same exit codes — was removed in 1.27.0 and now gets the same unknown-command error; use `standardize`. Removing a supported command is a breaking change and is why that release moved the minor. `bundle check` validates the canonical JSON readback set and makes QA required only under `--require-qa`. `polish capture` owns page-load evidence production. `checkpoint waive` currently accepts four registered gates: `page_kit.store_profile`, `page_kit.sdk_version`, `polish.hidden_eager_media`, and `built_output.upsell_selector_scope`. `page-kit sync` (added in 1.29.0) writes the CampaignSpec's Store Profile fields and SDK pin into the target's `_data/campaigns.json` entry — the repair the first two gates name — and is the only `page-kit` subcommand. `spec derive` (added in 1.31.0) is the reverse write for the repo-derived field class (#432): the target's SDK pin, page routes and analytics ids into the packet's local CampaignSpec; it is the only `spec` subcommand, and the `page_kit.sdk_version.repo_newer` advisory names it; its `--write-map` flag (1.33.0+agent.2) also records the derived pin in the saved Map's Build hints field through the proxy Worker, never moving a Map pin backwards. `qa publish` (added in 1.33.0) posts an already-stored verdict to the QA portal without a re-run or an order, refusing a stale `spec_hash` or a verdict its Run Record already records as published (#328). Within Polish, only the broader Source Freshness waiver remains on its existing report lane; theme and QA decisions also retain their existing lanes. | Any change to this list — adding, renaming, or removing a command — bumps `surface_version` in the same PR, and since 1.25.0 `check-supported-surface.mjs --base` enforces that (before, only hashed and named entries owed a bump, so `checkpoint` landed unbumped). Subcommands, registered gates, and flags may grow freely beneath a listed command. Removing a listed command from dispatch fails the gate outright. Do not infer support for an unregistered checkpoint from the top-level command. |
|
|
18
|
+
| `sdk storage-check` and `docs/sdk-storage-compatibility.md` | Read-only AST compatibility report for explicitly scoped tracked campaign HTML/JS before an SDK bump; consumes the supplied SDK-owned manifest and records its SHA-256 and verified or unverified local Git provenance. Incompatible and unknown findings exit 2; a clean scan is static source evidence only. | Additive supported CLI and named documentation; no automatic merchant integration repair. |
|
|
18
19
|
| `bin/campaigns-os.mjs` (`campaigns-os`) | The CLI entry itself. | Declared in `package.json` `bin`; the gate fails if it disappears. |
|
|
19
20
|
| Package export `./campaign-spec` | The versioned campaign-spec rule registry, consumed as `@nextcommerce/campaigns-os` (pinned by consumers' lockfiles; lockstep policy — ADR-003 in the ops repo). | Behavior-guarded from the consumer side by their contract tests; the export path itself is gated here. |
|
|
20
21
|
| Package exports `./commercial-journey` and `./commercial-parity` | Portable scenario planning, response normalization, contract-governed source extraction, Exact-only parity comparison, and deterministic QA assertion serialization. These modules own no network transport and do not calculate prices locally. | Consumers execute descriptors through a supported calculate transport, then pass captured envelopes into the pure normalizer. Existing export paths are gated and may not be renamed or removed without a breaking surface change. |
|
package/docs/versioning.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This repo uses independent compatibility versions:
|
|
4
4
|
|
|
5
|
-
- package version: `1.
|
|
5
|
+
- package version: `1.34.0` — equals `surface_version` in
|
|
6
6
|
`contracts/supported-surface.json` (`check:supported-surface` enforces it)
|
|
7
7
|
and is the version published to the npm registry; `+agent.N` changelog
|
|
8
8
|
sections are same-surface changes and are not published on their own
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextcommerce/campaigns-os",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.1",
|
|
4
4
|
"description": "Toolkit for agent-assisted NEXT campaign builds.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"prepare": "npm run build:spec",
|
|
61
61
|
"check:spec": "node --test \"campaign-spec/test/**/*.test.ts\"",
|
|
62
62
|
"check": "npm run check:provenance && npm run check:workflows && npm run check:changelog-structure && npm run build:spec && npm run check:tests && npm run check:spec && npm run check:fixtures && npm run check:legacy-migration && npm run check:spec-conformance && npm run check:private-strings && npm run check:template-doctrine && npm run check:slot-manifest && npm run check:skill-versions && npm run check:cart-readiness && npm run check:sidecar-bundle && npm run check:supported-surface && npm run check:release-ledger && npm run check:runtime-recipe && npm run check:orientation-docs && npm run check:runtime-docs && npm run check:pack -- --skip-prepare",
|
|
63
|
-
"check:tests": "node
|
|
63
|
+
"check:tests": "node ./scripts/check-tests.mjs",
|
|
64
64
|
"check:legacy-migration": "node ./scripts/check-legacy-migration.mjs",
|
|
65
65
|
"check:fixtures": "node ./scripts/check-fixtures.mjs",
|
|
66
66
|
"check:spec-conformance": "node ./scripts/check-campaign-spec-conformance.mjs",
|
|
@@ -80,7 +80,10 @@
|
|
|
80
80
|
"check:runtime-recipe": "node ./scripts/check-runtime-recipe.mjs",
|
|
81
81
|
"check:runtime-docs": "node ./scripts/generate-runtime-readiness.mjs --check",
|
|
82
82
|
"generate:runtime-docs": "node ./scripts/generate-runtime-readiness.mjs --write",
|
|
83
|
-
"check:sidecar-bundle": "node ./bin/campaigns-os.mjs bundle check --packet contracts/fixtures/sidecar-bundle/production-shaped/campaign-runtime.build.json --require-qa --json"
|
|
83
|
+
"check:sidecar-bundle": "node ./bin/campaigns-os.mjs bundle check --packet contracts/fixtures/sidecar-bundle/production-shaped/campaign-runtime.build.json --require-qa --json",
|
|
84
|
+
"check:browser": "node ./scripts/check-tests.mjs --browser",
|
|
85
|
+
"check:consumer": "node ./scripts/check-playwright-consumer.mjs",
|
|
86
|
+
"check:contracts": "npm run check:provenance && npm run check:workflows && npm run check:changelog-structure && npm run check:fixtures && npm run check:legacy-migration && npm run check:spec-conformance && npm run check:private-strings && npm run check:template-doctrine && npm run check:slot-manifest && npm run check:skill-versions && npm run check:cart-readiness && npm run check:sidecar-bundle && npm run check:supported-surface && npm run check:release-ledger && npm run check:runtime-recipe && npm run check:orientation-docs && npm run check:runtime-docs"
|
|
84
87
|
},
|
|
85
88
|
"engines": {
|
|
86
89
|
"node": ">=20.19.0"
|
|
@@ -88,11 +91,11 @@
|
|
|
88
91
|
"dependencies": {
|
|
89
92
|
"acorn": "^8.18.0",
|
|
90
93
|
"ajv": "^8.20.0",
|
|
91
|
-
"parse5": "^
|
|
92
|
-
"yaml": "^2.9.
|
|
94
|
+
"parse5": "^8.0.1",
|
|
95
|
+
"yaml": "^2.9.1"
|
|
93
96
|
},
|
|
94
97
|
"optionalDependencies": {
|
|
95
|
-
"playwright": "^1.
|
|
98
|
+
"playwright": "^1.63.0"
|
|
96
99
|
},
|
|
97
100
|
"devDependencies": {
|
|
98
101
|
"typescript": "^5.9.3"
|
|
@@ -130,6 +133,7 @@
|
|
|
130
133
|
"CONTEXT.md",
|
|
131
134
|
"compatibility.json",
|
|
132
135
|
"AGENTS.md",
|
|
133
|
-
"CHANGELOG.md"
|
|
136
|
+
"CHANGELOG.md",
|
|
137
|
+
"docs/sdk-storage-compatibility.md"
|
|
134
138
|
]
|
|
135
139
|
}
|
package/src/cli.mjs
CHANGED
|
@@ -459,6 +459,7 @@ Usage:
|
|
|
459
459
|
campaigns-os doctor --packet <campaign-runtime.build.json> [--context <json>] [--report <json>] [--strip-paths] [--write] [--no-write] [--doctor-out <path>] [--json] # inspection by default; --doctor-out requires --write; --no-write wins
|
|
460
460
|
campaigns-os doctor --built <page-kit-target-repo> --family <family> [--slug <slug>] [--base-url <url>] [--emit-packet [path]] [--json] # L7: doctor a built _site/ with no Build Packet
|
|
461
461
|
campaigns-os bundle check --packet <campaign-runtime.build.json> [--require-qa] [--json] # validate the canonical migration/readback JSON bundle; never substitutes markdown
|
|
462
|
+
campaigns-os sdk storage-check --target <git-root> --target-sdk <x.y.z> --manifest <SDK-manifest.json> --scope <dir,file> [--exclude <dir,file>] [--json]
|
|
462
463
|
campaigns-os standardize --target <campaign-repo> [--family <family>] [--slug <slug>] [--sdk-support-policy <path.json>] [--field-contract <path.json>] [--no-doctor] [--json]
|
|
463
464
|
campaigns-os theme inspect --packet <campaign-runtime.build.json> [--context <json>] [--theme-policy <inspect_only|auto|off>] [--json]
|
|
464
465
|
campaigns-os theme generate --packet <campaign-runtime.build.json> [--context <json>] [--out-dir <dir>] [--force] [--json]
|
|
@@ -608,7 +609,8 @@ export async function main(argv) {
|
|
|
608
609
|
// run never inherits an old run_id — but an ignored session was also an
|
|
609
610
|
// abandoned one: nine of them were found lingering with no Run Record and
|
|
610
611
|
// nothing remitted. Closing out is best-effort and never blocks the command.
|
|
611
|
-
const
|
|
612
|
+
const storageInspection = command === "sdk" && args._[1] === "storage-check";
|
|
613
|
+
const sweptStale = storageInspection ? [] : await closeOutStaleRunSessions(command, args);
|
|
612
614
|
const ambient = ambientRunSession(args);
|
|
613
615
|
|
|
614
616
|
// Wrap every command in the lifecycle instrumentation (T6): it captures the
|
|
@@ -757,7 +759,7 @@ function resolveLifecycleJournal(args, { ambient = null, fallbackDir = null } =
|
|
|
757
759
|
// not break a command (telemetry never blocks a build). `help` is a no-op
|
|
758
760
|
// command and is not worth recording.
|
|
759
761
|
function persistLifecycleIfRequested(args, command, lifecycle, sessionHolder) {
|
|
760
|
-
if (command === "help") return;
|
|
762
|
+
if (command === "help" || (command === "sdk" && args._[1] === "storage-check")) return;
|
|
761
763
|
// An inspection must not append to a delivered campaign's active run either.
|
|
762
764
|
if (command === "doctor" && args.packet && (args.write !== true || args["no-write"] === true)) return;
|
|
763
765
|
const ambient = sessionHolder?.current || null;
|
|
@@ -1060,6 +1062,24 @@ async function dispatch(command, args, recorder = NOOP_RECORDER, ambient = null,
|
|
|
1060
1062
|
return;
|
|
1061
1063
|
}
|
|
1062
1064
|
|
|
1065
|
+
if (command === "sdk") {
|
|
1066
|
+
if (args._[1] !== "storage-check" || args._.length !== 2) throw new Error("Use: campaigns-os sdk storage-check --target <git-root> --target-sdk <x.y.z> --manifest <SDK-manifest.json> --scope <dir,file> [--exclude <dir,file>] [--json].");
|
|
1067
|
+
const known = new Set(["_", "target", "target-sdk", "manifest", "scope", "exclude", "json"]);
|
|
1068
|
+
if (args.json !== undefined && args.json !== true) throw new Error("--json is a boolean flag and takes no value.");
|
|
1069
|
+
for (const key of Object.keys(args)) if (!known.has(key)) throw new Error(`Unknown SDK storage-check flag: --${key}`);
|
|
1070
|
+
const { scanSdkStorageCompatibility, formatStorageCompatibilityReport } = await import("./sdk-storage-compatibility.mjs");
|
|
1071
|
+
const result = scanSdkStorageCompatibility({
|
|
1072
|
+
cwd: requireArg(args, "target"),
|
|
1073
|
+
targetSdkVersion: requireArg(args, "target-sdk"),
|
|
1074
|
+
manifestPath: requireArg(args, "manifest"),
|
|
1075
|
+
scope: requireArg(args, "scope").split(","),
|
|
1076
|
+
exclude: args.exclude === undefined ? [] : requireArg(args, "exclude").split(","),
|
|
1077
|
+
});
|
|
1078
|
+
console.log(args.json ? JSON.stringify(result, null, 2) : formatStorageCompatibilityReport(result));
|
|
1079
|
+
process.exitCode = result.status === "source-compatible" ? 0 : 2;
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1063
1083
|
if (command === "standardize") {
|
|
1064
1084
|
const result = standardizationReportCommand(args);
|
|
1065
1085
|
writeStandardizationReportResult(result, args);
|