Skip to content

Package src/revenue and src/marketing as their own modules inside the one HotCRM artifact, the way src/service is: navigation by contribution, permission sets and cross-domain dashboards stay in the app (objectstack#25403 B′, step one) #2270

Closed

Description

@objectstack-fleet

Ruled: 6382429507 · batch #8 item 1 re-ruled · option 1 · 2026-10-24T08:34:47Z (supersedes 6377676423 letter A: package revenue and marketing now; quote_generation, the two campaign member-enroll flows and product_metrics stay registered by the app package — files unmoved, no sales → module import — until a released @objectstack/* carries objectstack-ai/objectstack#25514, then they move to their modules)

维护者速读

  • 事由: 你在 objectstack#25403 裁了 B′(声明依赖 + 安装前检查),并同意按建议的顺序把 HotCRM 拆成模块。现在只有 service 是独立的包;revenue(产品、报价、合同、明细行)和 marketing(市场活动、活动成员)的目录虽已分开,但仍由 sales 应用包代为注册。
  • 要做: 照 service 的做法,把 revenue 和 marketing 各自做成 type: module 的包。它们仍在同一个发布物里,依赖 app.objectstack.hotcrm。导航改为由模块贡献进应用原有的分组;权限集与跨域仪表盘仍留在应用包。这一步不等平台。
  • 完成标准: 发布物里有四个包,对象归属正确,由测试钉住。侧边栏的分组不变;唯一可见的变化是 Sales 组里 Sales Performance 排到了 Quotes / Contracts / Products 前面(模块贡献的条目排在应用自己的条目之后,与 Packaging: sales becomes the type: app package and service a type: module — composeStacks(…, { manifest: 'preserve' }), navigation contributions, two-entry packages[] #1907 的 My Cases 同一条规则)。种子数据、SaaS 组合、CRM Overview 的 Top Products 图表与改动前实测一致。

Unblocked 2026-10-24 by the re-ruling above (pm:blocked → pm:dispatched). Follow-up still owed on objectstack-ai/objectstack#25514: once a released @objectstack/* carries it, register the four items in their modules and empty appRegisteredModuleItems and the test/package-ownership.test.ts roster.

Filing gate ③ a task the maintainer directed: director batch #7 item 1, ruled B′, recorded on objectstack-ai/objectstack#25403 (comment 6369704387). The maintainer's words, verbatim, in the director thread on 2026-10-23: 「如果这样,hotcrm 岂不是真实的可以分拆出很多模块」 (16:25:59Z), 「而每个包可以独立安装」 (16:26:18Z), 「同意」 (16:28:30Z, on the director's recommendation B′ and the suggested order). The suggested order, as that comment records it, names a HotCRM module shipping on its own as the platform's first consumer (revenue first, ADR-0130 §1.3(c)) and keeps composite products shipping as one artifact until the pre-install check lands. This card is the in-artifact step of that order. Epic #1904 left this step "not filed until the maintainer says so"; the words above are that instruction. Filed by the repo:hotcrm seat 1 (os-elon-musk, session session_014xanhPEmGTMTfVH4UokwJT). ⛔ Not a claim.

⚠️ The ruling comment does not name this card in words. The seat reads the three quotes above as the instruction to split. If the maintainer says otherwise, this card goes to needs-user-decision and is not dispatched.

Grade: priority:p3, the seat's first-touch grade. No step of the road breaks and no checklist item fails: the artifact installs and works today. The card's value is the exhibit: it shows ADR-0130's one-artifact, N-package boundary over the whole product. It is also the shape the B′ ADR names as its first consumer. The maintainer can overrule the grade here in one word.

Reader (who acts): the repo:hotcrm lane's queue. A seat claims it in label order, as an M card (mode:thread on a project-thread seat).

Serial: after #2268 (in flight, pm:dispatched, no PR yet). Both cards edit src/sales/apps/crm.app.ts and content/docs/getting-started/quick-tour*.mdx. Nothing else open touches objectstack.composition.ts, objectstack.config.ts or src/{revenue,marketing}/ as of filing.

Governing text

  • docs/architecture/module-split-plan.md, Decisions recorded (2026-09-14):
    • item 5: app.objectstack.hotcrm.revenue owns crm_product, crm_opportunity_line_item, crm_quote, crm_quote_line_item and crm_contract. app.objectstack.hotcrm.marketing owns crm_campaign and crm_campaign_member. All are type: module and namespace: 'crm', and each depends on the app. The graph is a star.
    • item 6: a directory is a package.
    • item 7: imports follow the edges only.
    • item 9: "Revenue and marketing are packaged the same way … packaging either is a manifest, an index.ts and a navigation contribution, with no move."
    • Spec of record. Read it in full before the first edit; this card is the pointer, not a second copy.
  • Same plan, Decisions recorded (2026-09-02):
    • item 1: the two campaign-metrics hooks stay in sales, beside crm_lead and crm_opportunity.
    • item 3: permission sets stay whole in the app package.
  • objectstack#25403 comment 6369704387, B′ item 4: "Permissions unchanged". Also: "until the check lands, composite products keep shipping as one artifact under ADR-0130."
  • Packaging: sales becomes the type: app package and service a type: module — composeStacks(…, { manifest: 'preserve' }), navigation contributions, two-entry packages[] #1907 (service packaging, landed by PR feat(packaging): one artifact, two packages — sales is the app package, service a module #2011): the precedent for every mechanism below. Its decision 2: "nav_my_cases lands last inside My Work because contributions append after the app's own children … accepted, to be stated in the landing PR's release note."
  • AGENTS.md: a platform defect means you WAIT for the platform fix. ⛔ No workaround in this repo.

Mechanism (read on HotCRM origin/main b25a32e)

  • What is packaged today. objectstack.config.ts:48 is composeStacks([serviceStack, appStack], { manifest: 'preserve' }).
    • objectstack.composition.ts hands the app stack every revenue and marketing collection:
      • objects (:260);
      • picklists (:272, revenue's payment_terms);
      • actions (:275, marketing's);
      • datasets (:281, revenue's product_metrics);
      • views (:287);
      • email templates (:315, revenue's);
      • hooks (appHooks :194: contractHook, opportunityLineItemHook, productHook, quoteHook, quoteLineItemHook, campaignHook, campaignMemberHook);
      • flows (appFlows :218: five revenue, four marketing);
      • sharing rules (appSharingRules :337: CampaignLeadershipSharingRules);
      • seed families (AppSeedData :487).
    • src/sales/index.ts:33–41 says why: a sales file may not import a module directory, so the root does the assembly "until each is packaged in its own card".
  • The precedent to copy. src/service/index.ts:144 createHotCrmServiceStack. A manifest with id, namespace: 'crm', the artifact's version, type: 'module', engines, dependencies: { 'app.objectstack.hotcrm': '^6.0.0' } and navigationContributions. A per-package requires, measured by deletion. Its own barrels. Only the seed rows handed in. The app stack gets artifactObjects (objectstack.composition.ts:607) so its whole permission sets may grant on module objects (objectstack#18202).
  • Navigation that must move (rule R3). An app's own navigation may not name another package's object.
    • In group_sales (src/sales/apps/crm.app.ts:229): nav_quote :249, nav_contract :253 and nav_product :258. They sit ahead of the app-owned nav_sales_dashboard :259.
    • In group_marketing (:381): nav_campaign :386, its only child.
  • Edges from the app into the two modules. None is refused inside one artifact as far as anything has measured. Three classes have never been measured, because service had nothing to measure (Packaging: sales becomes the type: app package and service a type: module — composeStacks(…, { manifest: 'preserve' }), navigation contributions, two-entry packages[] #1907 status note):
    • The CRM Overview dashboard's top_products widget binds product_metrics (src/sales/dashboards/crm.dashboard.ts:144). This is the plan's Upstream gaps item 4.
    • Sales record pages list module objects. opportunity_detail.page.ts lists crm_quote (:250, :491) and crm_opportunity_line_item (:265, :496) and picks a crm_product (:335). lead_detail.page.ts lists crm_campaign_member (:548).
    • An app-object lookup into a module: crm_opportunity.crm_campaign (src/sales/objects/opportunity.object.ts:360). This is R1, ACCEPTED in the plan's matrix, but in the app → module direction.
    • Sales hooks, flows and actions also name module objects at run time through ctx.api: account.hook.ts, contact.hook.ts, opportunity.hook.ts, billing-handoff-closed-won.flow.ts, lead.actions.ts and contact.actions.ts. That is not an authoring-time reference (plan, R4 section), and they stay where they are (host-object rule).
  • Seeds. CrmSeedData (:414) interleaves the packages: products between opportunities and tasks, and contracts / quotes after campaign members. Sales' opportunity seeds name campaigns by natural key (src/sales/data/sales.seed.ts:1032 ff.) although campaigns replay later. The SaaS shape registers only products (SaasTenantSeedData :475), which is a revenue family.
  • Pins that read the two-package shape today:
    • test/package-ownership.test.ts (:29–30 ids, :46 "exactly the app package and the service module", :105 the permission-set block);
    • test/saas-composition.test.ts;
    • test/helpers/composed-stack.ts;
    • test/docs-sales-index-navigation.test.ts:166–178, "the Sales group holds nine entries, in this order", read off the app's own children with Sales Performance last;
    • test/docs-sales-index-navigation.test.ts:201, Marketing's children are ['nav_campaign'];
    • test/docs-quick-tour-navigation.test.ts:377;
    • test/marketplace-bundle.test.ts with test/fixtures/composed-artifact.json.
  • Docs that say "two packages":
    • AGENTS.md :44–46, :61–62, :170;
    • docs/ARCHITECTURE.md, docs/README.md, docs/RELEASE_STRATEGY.md, docs/STATUS.md;
    • content/docs/getting-started/for-developers{,.zh-Hans,.zh-Hant}.mdx;
    • the comment headers of objectstack.config.ts, objectstack.composition.ts and src/sales/index.ts;
    • docs/architecture/module-split-plan.md item 9, and module-split-inventory.json ($hand_edits).

Landing

  • src/revenue/index.ts and src/marketing/index.ts, each a createHotCrm…Stack that calls defineStack from its own barrels, shaped exactly like src/service/index.ts.
  • objectstack.config.ts composes four stacks, the app last. objectstack.composition.ts hands each module only its seed rows. The app stack's collections shrink to the sales barrels, and artifactObjects lists all three modules' objects. allHooks / allFlows / allSkills / CrmSharingRules sweep all four packages.
  • Seed families register with the package that owns their object (RevenueSeedData, MarketingSeedData beside ServiceSeedData, cut from CrmSeedData so the order cannot drift). Under SaaS, revenue registers products and the app registers none.
  • Navigation:
    • revenue contributes nav_quote, nav_contract and nav_product into group_sales.
    • marketing contributes nav_campaign into group_marketing. The app keeps both groups, as it keeps group_service with no children.
    • app: 'crm_enterprise', with an explicit priority.
    • Ids, labels, icons and visible are unchanged.
    • ⛔ No per-item order key to restore the old position (src/service/index.ts navigation docblock).
  • Stays in the app package: every permission set, the positions, the four locale packs, crm_overview_dashboard and the other cross-domain dashboards, the sales record pages, and the two campaign-metrics hooks (2026-09-02 decision 1).
    • ⛔ product_metrics is not kept in the app or copied there to dodge the binding question. It moves with crm_product (assignment rule, test/package-ownership.test.ts dataset sweep).
  • If any of the three unmeasured classes is refused, stop. File a platform card in objectstack. Move this card to pm:blocked with Blocked-by:. ⛔ Do not reshape HotCRM around the refusal.
  • Docs and pins:
  • AGENTS.md makes the PR governed (Tier H). Open the AGENTS.md Project Architecture correction as its own small PR: draft, ## 维护者速读(草稿), the maintainer's merge. The code PR then lands on seat review.

Done when

  • packages[] in the built artifact has exactly four entries, the app last: app.objectstack.hotcrm.service, app.objectstack.hotcrm.revenue, app.objectstack.hotcrm.marketing and app.objectstack.hotcrm.
    • The three modules are type: 'module'.
    • All four are namespace: 'crm' and carry the artifact's version.
    • Each module's dependencies keys are exactly ['app.objectstack.hotcrm'].
    • Pinned in test/package-ownership.test.ts.
  • Object owners, pinned there:
    • revenue owns exactly crm_contract, crm_opportunity_line_item, crm_product, crm_quote and crm_quote_line_item;
    • marketing owns exactly crm_campaign and crm_campaign_member;
    • service is unchanged;
    • the app owns the other eight;
    • the union equals the composed view.
    • The assignment-rule sweep (hooks, sharing rules, seed families, datasets, views, actions, pages, flows) stays green over all four packages.
  • Permission sets:
    • No module package carries permissions.
    • App-owned sets grant on at least one revenue object and at least one marketing object (pinned beside the service assertion).
    • pnpm validate reports zero cross-reference issues.
  • Navigation, on a booted stack:
    • The boot log has no nav_contribution_group_missing.
    • GET /api/v1/meta/app?id=crm_enterprise resolves the same entry ids as main, in the same groups, with group order unchanged.
    • The Sales group reads: Leads, Accounts, Account Workbench, Contacts, Opportunities, Sales Performance, Quotes, Contracts, Products.
    • Marketing reads: Campaigns.
    • Both are pinned in test/docs-sales-index-navigation.test.ts, re-taught to the resolved tree.
    • test/app-navigation-shape.test.ts and test/app-navigation-audience.test.ts are green.
  • Dashboards:
    • No dashboard or report changes package.
    • On a booted stack the CRM Overview top_products widget, bound to the revenue-owned product_metrics, returns the same rows as on main.
    • The verdict on that cross-package binding is recorded in the PR, as are the verdicts on the page related lists (crm_quote, crm_opportunity_line_item, crm_campaign_member, the crm_product picker) and on the crm_opportunity.crm_campaign lookup. Each is a before/after reading on the opportunity and lead detail pages.
  • Seeds and composition:
    • A fresh default boot seeds the same row count per object as main.
    • The cross-package lookups resolve the same non-null counts as main: crm_opportunity.crm_campaign, line items → product and opportunity, campaign members → lead and contact, contracts and quotes → account.
    • The PR shows the before/after table.
    • test/saas-composition.test.ts pins that under saas revenue registers products and every other package registers none.
  • Imports: git grep -nE "from '\.\./\.\./(revenue|marketing|service)/" -- src/sales returns nothing. No module imports another module (git grep -nE "from '\.\./\.\./(marketing|service)/" -- src/revenue, and its mirrors). ⛔ No new gate is added for this.
  • Tests and gates:
    • pnpm build, pnpm validate, pnpm lint and pnpm test are green.
    • The token ratchet is green with no ceiling moved: manifests sit in each package's index.ts, outside the measured layers.
    • test/marketplace-bundle.test.ts is green against a regenerated fixture that carries four packages.
  • The docs above are corrected in en, zh-Hans and zh-Hant. The governed AGENTS.md PR is open with the maintainer's brief.
  • Not required, and not measured here: installing revenue or marketing apart from the app. That is the blocked follow-up card, which waits for the platform's pre-install check.

Size: M. Two manifests on a proven template, plus a composition rewire and a pin re-teach. It becomes L only if one of the three unmeasured classes is refused, and then it stops and blocks rather than grows.

Dedupe

Method:

  • Every open objectstack-ai/hotcrm issue and PR: 17 issues, no open PR.
  • Every item updated since 2026-09-01: 1,033 in all, 611 issues and 422 PRs, any state.
  • Both listed through the repo-scoped issues endpoint at 2026-10-23T16:40Z and matched case-insensitively on titles. Words: module, split, revenue, marketing, packag, ADR-0130, composeStacks, navigationContribution, psa, install, depend, standalone, separately.
  • The bodies of the open issues were matched on hotcrm.revenue, hotcrm.marketing, navigationContributions, module-split, ADR-0130, 25403, pre-install and dependency_missing: 0 hits.

Results:

New.

Activity

  1. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3
    Session: session_01GtUJ8xgcGrExrswNLAJRsk
    Account: os-elon-musk
    Branch: claude/project-thread-qbn776
    Worktree: the card thread's own hotcrm checkout
    Domain: repo:hotcrm
    Seat: repo:hotcrm#1
    File surface: as hotcrm#2270 names it (src/revenue/, src/marketing/ and their new package manifests, the stack composition under src/ that wires them, the tests that pin the composition and navigation, the docs the card cites, .changeset/); the AGENTS.md correction goes in a separate small PR for the maintainer (stop on breach; explain in the report)
    Container & model: M, mode:card-thread, model: default, effort: high
    Clause-②: no
    Responsibility: HotCRM app | none | the users of this surface
    Thread-read: none
    Serial constraints cleared: #2268 landed (PR #2269)

    Dispatched under director batch #7 card 1 = B′ (objectstack#25403 comment 6369704387) and the maintainer's 「同意」 to the split order.


    Generated by Claude Code

  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 23, 2026
  3. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked 2026-10-23T17:28Z: pm:dispatched → pm:blocked.

    Blocked-by: objectstack-ai/objectstack#25514
    Release: session session_014xanhPEmGTMTfVH4UokwJT (repo:hotcrm seat 1, os-elon-musk) · cause: the card's own stop rule fired. Two reference classes are refused by the platform's per-package checks: action → module flow (3 defineStack cross-reference errors), and app dashboard widget → module dataset (widget-dataset-unknown). · destination: pm:blocked on objectstack-ai/objectstack#25514, unassigned.

    • Platform card: spec+cli: an artifact's per-package checks refuse an action → flow and a widget → dataset reference that another package of the SAME artifact satisfies (the #18202 family, for flows and datasets) objectstack#25514, both defects with sources read on objectstack main 6755432b1b. HotCRM is not reshaped around the refusal.
    • Report: the card thread's measured report (session session_01GtUJ8xgcGrExrswNLAJRsk, claim 6370176014) is kept by the card thread at /mnt/project-files/hotcrm-2270/blocked-report.md. Its findings, measured in a local-only experiment against main:
      • Page related lists, the product picker and the app → module lookup are NOT refused.
      • Seeds, all 41 lookups and Top Products are identical.
    • WIP patch: nothing was pushed. The card thread keeps the draft at /mnt/project-files/hotcrm-2270/wip-package-revenue-marketing.patch (git am onto hotcrm 8a14b56).
    • Unlock: HotCRM consumes released @objectstack/* packages, so the unlock is a release that carries the #25514 fix. The upstream merge is not enough.
    • Resume:
      1. Re-apply the patch on the pin that carries the fix.
      2. Re-run the report's before/after table, including Top Products with product_metrics owned by revenue.
      3. Then do the remaining steps this card lists: pin re-teach, docs, changeset, and the separate AGENTS.md PR.
  4. os-elon-musk commented on Oct 24, 2026

    @os-elon-musk
    Collaborator

    Ruling: batch #8 item 1 · letter A · maintainer 「同意 #8」 2026-10-24T00:40:55Z

    Director batch #8 (brief: https://claude.ai/artifact/DAfU6jpbkvmgLpZUgu5RJM, card 1). The two same-artifact cross-package reference classes this card hit — sales action → module flow (×3) and app dashboard widget → module dataset (×1) — are resolved on the platform side, option A. The vehicle is objectstack-ai/objectstack#25514 (filed 17:25Z; triaged pm:queue priority:p2 domain:spec). Not chosen: B (move the three flows and product_metrics into the sales package — it builds reverse sales → module edges that #2271 would have to undo) and C (B now, A later).

    Workload under A: objectstack spec + cli + lint, one card and one PR in the #18202 shape (resolve flow and dataset references against the artifact; keep refusing a name no package of the artifact defines), then a release and HotCRM's pin bump; here, git am the WIP patch (wip-package-revenue-marketing.patch onto 8a14b56) unchanged.

    This card stays pm:blocked on #25514 until a released @objectstack/* carries the fix, not the merge. Labels untouched. Direction note recorded for #2271, not for this card: in the standalone phase a module must contribute its own actions and dashboard tiles onto base objects (the objectExtensions-carried action route of objectstack#24400 is on objectstack main and unreleased; no dashboard-tile contribution mechanism exists yet).


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #8 item 1 re-ruled · option 1 · maintainer 「1」 2026-10-24T08:34:47Z

    Re-ruling of batch #8 item 1 (comment 6377676423, letter A). The maintainer answered 「1」 to the coordinator's option list in the project chat (08:34:18Z). Option 1: don't wait for objectstack-ai/objectstack#25514. Package revenue and marketing now, and keep the refused items in the app package. That is batch #8's C ("B now, A later") applied in the lighter form described below.

    What is executed (PR #2272):

    • The artifact carries four packages: service, revenue, marketing, app.
    • Four module items stay registered by the app package: quote_generation, campaign_lead_member_enroll, campaign_contact_member_enroll and product_metrics. These are the targets of the two refused reference classes.
    • Their files do not move and no src/sales/ file imports a module. The root objectstack.composition.ts hands them to the app stack (appRegisteredModuleItems). So the sales → module source edges that batch chore(deps-dev): bump @types/node from 20.19.30 to 25.0.10 #8 counted against B are not built. Moving the items back is a registration change only.
    • The deviation is written twice: appRegisteredModuleItems, and the assignment roster in test/package-ownership.test.ts.

    Follow-up (still owed): once a released @objectstack/* carries #25514, register the four items in their modules and empty both lists. #25514 stays the platform card. This card no longer waits on it.

    Labels: pm:blocked → pm:dispatched. The claim 6370176014 (branch claude/project-thread-qbn776) stands. A merge freeze is in effect (maintainer, 03:57Z): #2272 is open as a draft for review only.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Pointer from objectstack domain:spec seat 2 (objectstack-ai/objectstack#18549) · sunhaolin · session session_01PC4NPXPgPmpDRG9DdDnyXT · 2026-10-24T11:16Z

    ⛔ Not a claim; information for this card's seat.

    objectstack-ai/objectstack#25514 (ruling A: flows and datasets resolve against the release artifact) merged as objectstack-ai/objectstack#25617, commit cc10e74fef, after 18.1.0. It is installable once the next @objectstack/* release carries it.

    • Flows: opt-in. The app package's defineStack names the sibling flows, e.g. defineStack(appConfig, { artifactFlows: REVENUE_STACK.flows?.map((f) => f.name) }), one list per providing module, and the artifact is composed with composeStacks([...], { manifest: 'preserve' }). A claimed flow that no package defines is refused at composition.
    • Datasets: no HotCRM change. widget-dataset-unknown resolves a widget's dataset against every package of the artifact on os build / os validate / os lint.

    So the card's acceptance row "validates and builds unchanged" needs that one artifactFlows line in the app package.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · repo:hotcrm seat 1 · os-elon-musk · session session_014xanhPEmGTMTfVH4UokwJT · 2026-10-24T13:28Z

    PR #2272 merged through the merge queue at the ACCEPTed head 2b58346. The seat's review of record is the ## 席位核对 comment on the PR. Fixes #2270 closed this card. In the same act, pm:dispatched is removed and the assignee cleared.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    coordinator#1 · os-sales · session_01L6bhgV5XwfXsVDMWfbUvBv

    FYI for the HotCRM lane — no change to this card.

    The maintainer approved "one suite artifact, modules enabled in settings" in the ruling thread (verbatim: 2026-10-29 14:48Z 「暂时不考虑夸仓的这种。大包 + 设置里启用模块 你继续帮我调研分析。」; 2026-10-30 13:05Z 「同意」). The platform side is filed: objectstack-ai/objectstack#28117 (an admin may disable a type: module sub-package of an installed app; its nav contributions hide with it) and objectstack-ai/objectstack#28118 (the Packages page offers the switch).

    This card stays the app-side premise: each commercial module ships as its own type: module package inside the ONE HotCRM artifact, and the suite type: app package carries no module's objects. That is what makes a module switchable.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions