@synap-core/workspace-templates 0.6.2 → 0.6.4
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/dist/index.d.ts +114 -10
- package/dist/index.js +178 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/catalog.test.ts +99 -1
- package/src/catalog.ts +181 -0
- package/src/content-os.yaml +23 -2
- package/src/crm.yaml +67 -1
- package/src/define.ts +24 -16
- package/src/ecosystem.yaml +35 -0
- package/src/index.ts +11 -2
- package/src/templates.ts +116 -2
- package/src/types.ts +0 -16
package/dist/index.d.ts
CHANGED
|
@@ -150,13 +150,6 @@ interface TemplateProfileEntityBentoTemplates {
|
|
|
150
150
|
blocks: Array<Record<string, unknown>>;
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
|
-
interface TemplateAutomation {
|
|
154
|
-
name: string;
|
|
155
|
-
description?: string;
|
|
156
|
-
trigger: string;
|
|
157
|
-
action: string;
|
|
158
|
-
config?: Record<string, unknown>;
|
|
159
|
-
}
|
|
160
153
|
/** Mirrors `WorkspaceSourceRole` in synap-backend `schema/workspaces.ts`. */
|
|
161
154
|
type TemplateSourceRole = 'provider' | 'consumer' | 'provider-consumer';
|
|
162
155
|
/** Mirrors `WorkspaceDefaultSource` in synap-backend `schema/workspaces.ts`. */
|
|
@@ -411,8 +404,6 @@ interface WorkspaceYaml {
|
|
|
411
404
|
};
|
|
412
405
|
/** Per-profile entity bento layouts */
|
|
413
406
|
profileEntityBentoTemplates?: TemplateProfileEntityBentoTemplates;
|
|
414
|
-
/** Automations to install on workspace creation */
|
|
415
|
-
automations?: TemplateAutomation[];
|
|
416
407
|
/** Playbooks (session templates) seeded with the workspace */
|
|
417
408
|
playbooks?: TemplatePlaybook[];
|
|
418
409
|
/** Capability templates (tools/connectors) to install on provisioning */
|
|
@@ -546,6 +537,42 @@ interface MergeCatalogInput {
|
|
|
546
537
|
*/
|
|
547
538
|
remoteStatus?: RemoteSourceStatus;
|
|
548
539
|
}
|
|
540
|
+
/**
|
|
541
|
+
* A control-plane package LIST row, as returned by `GET /api/packages` and
|
|
542
|
+
* `GET /api/packages/mine`. This is the raw JSON shape BEFORE it is projected
|
|
543
|
+
* into a `RemoteEntry`. Both list routes STRIP `definition`, so it is absent
|
|
544
|
+
* here (the install path fetches the full row per-slug on demand).
|
|
545
|
+
*
|
|
546
|
+
* `isPublic` is present ONLY on `/mine` rows (`false` ⇒ private). Public browse
|
|
547
|
+
* rows omit it BY CONSTRUCTION (the list route hard-filters `WHERE is_public =
|
|
548
|
+
* true`), so its absence means "public", never "unknown".
|
|
549
|
+
*
|
|
550
|
+
* Consumers used to hand-copy this shape + `rowToRemoteEntry` (browser
|
|
551
|
+
* `useMarketplaceCatalog`, CLI `cp-packages`); this is the ONE canonical copy.
|
|
552
|
+
*/
|
|
553
|
+
interface CpPackageRow {
|
|
554
|
+
slug: string;
|
|
555
|
+
displayName: string;
|
|
556
|
+
description?: string | null;
|
|
557
|
+
/** CP package category / type (e.g. `"workspace"`, `"view"`). */
|
|
558
|
+
category?: string;
|
|
559
|
+
tags?: string[] | null;
|
|
560
|
+
icon?: string | null;
|
|
561
|
+
/** Present only on `/mine` rows. `false` ⇒ private. Browse rows omit it. */
|
|
562
|
+
isPublic?: boolean;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Map a CP list row into the merge door's `RemoteEntry`. THE canonical mapping —
|
|
566
|
+
* browser + CLI import this instead of hand-copying it (the two copies had
|
|
567
|
+
* already drifted in `description`/`isPrivate` handling).
|
|
568
|
+
*
|
|
569
|
+
* `isPrivate` is passed EXPLICITLY by the caller because it depends on WHICH
|
|
570
|
+
* route the row came from: browse rows are all-public (pass `undefined`), `/mine`
|
|
571
|
+
* rows carry the real flag (pass `row.isPublic === false`). Keeping it a param —
|
|
572
|
+
* not derived here — lets a caller that fetches the two routes separately control
|
|
573
|
+
* it per-source; `assembleCatalog` derives it from the row for the common case.
|
|
574
|
+
*/
|
|
575
|
+
declare function rowToRemoteEntry(row: CpPackageRow, isPrivate?: boolean): RemoteEntry;
|
|
549
576
|
interface CatalogEntryBase {
|
|
550
577
|
slug: string;
|
|
551
578
|
name: string;
|
|
@@ -602,6 +629,71 @@ interface MergeCatalogResult {
|
|
|
602
629
|
* entry (a private or third-party package) and is always kept.
|
|
603
630
|
*/
|
|
604
631
|
declare function mergeCatalog(input: MergeCatalogInput): MergeCatalogResult;
|
|
632
|
+
interface AssembleCatalogInput {
|
|
633
|
+
/** Bundled templates (this package). Always in-process. */
|
|
634
|
+
bundled: BundledEntry[];
|
|
635
|
+
/**
|
|
636
|
+
* Raw CP list rows (browse and/or `/mine`, concatenated). Mapped to
|
|
637
|
+
* `RemoteEntry` via `rowToRemoteEntry`; `isPrivate` is DERIVED per-row from
|
|
638
|
+
* `isPublic` (`false` ⇒ private; absent/`true` ⇒ public), which handles both
|
|
639
|
+
* browse rows (no `isPublic`) and `/mine` rows uniformly.
|
|
640
|
+
*/
|
|
641
|
+
remoteRows?: CpPackageRow[];
|
|
642
|
+
/** This client's bundled-package version (the winner signal vs each row). */
|
|
643
|
+
bundleVersion: string;
|
|
644
|
+
/** The transport's verdict on the remote fetch. Default `"ok"`. */
|
|
645
|
+
remoteStatus?: RemoteSourceStatus;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Convenience wrapper over `mergeCatalog`: maps raw CP rows through the canonical
|
|
649
|
+
* `rowToRemoteEntry` and merges them with the bundled templates. Still PURE — the
|
|
650
|
+
* caller fetches the rows (its own transport/auth) and passes them in; this only
|
|
651
|
+
* maps + merges. Use `mergeCatalog` + `rowToRemoteEntry` directly when you need
|
|
652
|
+
* per-source `isPrivate` control (e.g. keeping browse and `/mine` distinct).
|
|
653
|
+
*/
|
|
654
|
+
declare function assembleCatalog(input: AssembleCatalogInput): MergeCatalogResult;
|
|
655
|
+
/** A template a pod has installed — the door reads `settings.packageVersion` off the workspace row. */
|
|
656
|
+
interface InstalledTemplate {
|
|
657
|
+
slug: string;
|
|
658
|
+
version: string;
|
|
659
|
+
}
|
|
660
|
+
/** Per-slug verdict: is a newer catalog version available than what's installed? */
|
|
661
|
+
interface TemplateUpdateCheck {
|
|
662
|
+
slug: string;
|
|
663
|
+
installedVersion: string;
|
|
664
|
+
/** `undefined` when the slug has no matching catalog entry, or a bundled winner and no `bundleVersion` was passed. */
|
|
665
|
+
latestVersion: string | undefined;
|
|
666
|
+
updateAvailable: boolean;
|
|
667
|
+
/** Passed through from the winning catalog entry, so callers can route private updates through the authed path. */
|
|
668
|
+
isPrivate?: boolean;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* `true` when `version` is a CP content-hash stamp (`"h-<hash>"`) rather than semver.
|
|
672
|
+
* Content-hash versions are NOT semver-comparable — see `computeTemplateUpdates`.
|
|
673
|
+
*/
|
|
674
|
+
declare function isHashVersion(version: string | undefined): boolean;
|
|
675
|
+
/**
|
|
676
|
+
* Compute, per installed template, whether the CATALOG (bundled + remote,
|
|
677
|
+
* already merged by `mergeCatalog`/`assembleCatalog`) carries a newer version
|
|
678
|
+
* than what the pod installed — the shared "update available" check all three
|
|
679
|
+
* doors (browser, synap-app, CLI) reuse instead of re-deriving it.
|
|
680
|
+
*
|
|
681
|
+
* `installed` and `catalog` are BOTH already-fetched/computed by the caller —
|
|
682
|
+
* this stays PURE, same as the rest of this module (no fetch, no auth).
|
|
683
|
+
*
|
|
684
|
+
* The catalog's winning entry carries the latest version signal two ways:
|
|
685
|
+
* • `source: "remote"` → `remote.definition?.sourcePackage?.version` (semver
|
|
686
|
+
* OR, going forward, a CP content-hash `"h-<hash>"` stamp).
|
|
687
|
+
* • `source: "bundled"` → bundled entries carry no version field at all
|
|
688
|
+
* (`TemplateMeta` has none); pass `bundleVersion` (this client's compiled
|
|
689
|
+
* package version, the same value fed to `mergeCatalog`) to compare against
|
|
690
|
+
* it. Omit `bundleVersion` and bundled-backed slugs report `latestVersion:
|
|
691
|
+
* undefined, updateAvailable: false` (nothing comparable).
|
|
692
|
+
*
|
|
693
|
+
* A slug with no matching catalog entry ⇒ `updateAvailable: false`,
|
|
694
|
+
* `latestVersion: undefined` — there is nothing to update TO.
|
|
695
|
+
*/
|
|
696
|
+
declare function computeTemplateUpdates(installed: InstalledTemplate[], catalog: CatalogEntry[], bundleVersion?: string): TemplateUpdateCheck[];
|
|
605
697
|
|
|
606
698
|
/**
|
|
607
699
|
* @synap-core/workspace-templates — Definition adapter
|
|
@@ -657,6 +749,18 @@ interface WorkspaceDefinitionInput {
|
|
|
657
749
|
/** VIEW half of the authored bento union — resolved against the viewMap. */
|
|
658
750
|
bentoViewBlocks?: BentoViewBlockWire[];
|
|
659
751
|
profileEntityBentoTemplates?: WorkspaceYaml['profileEntityBentoTemplates'];
|
|
752
|
+
/**
|
|
753
|
+
* Capability integrations (→ tools + skills + vault + capability-embedded
|
|
754
|
+
* automations/playbooks). Emitted from the template's `integrations:` list —
|
|
755
|
+
* IDENTICAL to what `toPackageDefinition` puts in its `capabilities` field. The
|
|
756
|
+
* tRPC door (`workspaces.createFromDefinition`) now declares `capabilities` in
|
|
757
|
+
* its zod input and installs them via the SHARED `applyPackagePostWorkspace`
|
|
758
|
+
* door (same as Hub `/packages/apply`). It was missing from this interface, so
|
|
759
|
+
* `toWorkspaceDefinition` had nowhere to put integrations and the browser
|
|
760
|
+
* BUNDLED install path carried NO capabilities — every capability's
|
|
761
|
+
* tools/skills/automations silently dropped on that door.
|
|
762
|
+
*/
|
|
763
|
+
capabilities?: WorkspaceYaml['integrations'];
|
|
660
764
|
workspaceSubtype?: string;
|
|
661
765
|
workspaceType?: NonNullable<WorkspaceYaml['workspace']>['workspaceType'];
|
|
662
766
|
workspaceVisibility?: string;
|
|
@@ -748,4 +852,4 @@ interface PackageDefinitionOutput {
|
|
|
748
852
|
*/
|
|
749
853
|
declare function toPackageDefinition(slugOrYaml: string | WorkspaceYaml): PackageDefinitionOutput;
|
|
750
854
|
|
|
751
|
-
export { type BentoViewBlockWire, type BentoWidgetBlockWire, type BundledCatalogEntry, type BundledEntry, type CatalogEntry, type MergeCatalogInput, type MergeCatalogResult, PACKAGE_DEPENDENCY_KINDS, type PackageDefinitionOutput, type PackageDependencyKind, type RemoteCatalogEntry, type RemoteEntry, type RemoteSourceStatus, type SplitBentoBlocks, type TemplateAppKind, type TemplateAppRef, type
|
|
855
|
+
export { type AssembleCatalogInput, type BentoViewBlockWire, type BentoWidgetBlockWire, type BundledCatalogEntry, type BundledEntry, type CatalogEntry, type CpPackageRow, type InstalledTemplate, type MergeCatalogInput, type MergeCatalogResult, PACKAGE_DEPENDENCY_KINDS, type PackageDefinitionOutput, type PackageDependencyKind, type RemoteCatalogEntry, type RemoteEntry, type RemoteSourceStatus, type SplitBentoBlocks, type TemplateAppKind, type TemplateAppRef, type TemplateBentoBlock, type TemplateDefaultSource, type TemplateDependency, type TemplateDisplayTemplate, type TemplateEntityLink, type TemplateExtendsRef, type TemplateIntegration, type TemplateLayoutConfig, type TemplateMeta, type TemplateOnboarding, type TemplateOnboardingCollectTarget, type TemplatePlaybook, type TemplatePlaybookParam, type TemplateProfile, type TemplateProfileEntityBentoTemplates, type TemplateProperty, type TemplateSeedEntity, type TemplateSidebarItem, type TemplateSidebarSurface, type TemplateSourceRole, type TemplateSuggestedRelation, type TemplateUpdateCheck, type TemplateView, type ToDefinitionResult, WORKSPACE_TEMPLATES, type WorkspaceDefinitionInput, type WorkspaceTemplateSlug, type WorkspaceYaml, assembleCatalog, computeTemplateUpdates, getWorkspaceTemplate, isHashVersion, listPublicTemplates, listWorkspaceTemplates, mergeCatalog, rowToRemoteEntry, splitBentoBlocks, toPackageDefinition, toWorkspaceDefinition };
|
package/dist/index.js
CHANGED
|
@@ -8485,6 +8485,16 @@ var DATA = {
|
|
|
8485
8485
|
"groupBy": "post-status",
|
|
8486
8486
|
"description": "Content posts by status."
|
|
8487
8487
|
},
|
|
8488
|
+
{
|
|
8489
|
+
"name": "Content Calendar",
|
|
8490
|
+
"slug": "content-calendar",
|
|
8491
|
+
"type": "calendar",
|
|
8492
|
+
"scopeProfileSlug": "post",
|
|
8493
|
+
"description": "Your editorial calendar \u2014 every post on the day it publishes.",
|
|
8494
|
+
"config": {
|
|
8495
|
+
"dateField": "properties.publish-date"
|
|
8496
|
+
}
|
|
8497
|
+
},
|
|
8488
8498
|
{
|
|
8489
8499
|
"name": "Pillars",
|
|
8490
8500
|
"slug": "content-pillars",
|
|
@@ -8526,6 +8536,12 @@ var DATA = {
|
|
|
8526
8536
|
"label": "Posts",
|
|
8527
8537
|
"icon": "file-edit"
|
|
8528
8538
|
},
|
|
8539
|
+
{
|
|
8540
|
+
"kind": "view",
|
|
8541
|
+
"viewName": "Content Calendar",
|
|
8542
|
+
"label": "Calendar",
|
|
8543
|
+
"icon": "calendar"
|
|
8544
|
+
},
|
|
8529
8545
|
{
|
|
8530
8546
|
"kind": "view",
|
|
8531
8547
|
"viewName": "Pillars",
|
|
@@ -8551,10 +8567,20 @@ var DATA = {
|
|
|
8551
8567
|
"blocks": [
|
|
8552
8568
|
{
|
|
8553
8569
|
"kind": "view",
|
|
8554
|
-
"viewName": "
|
|
8570
|
+
"viewName": "Content Calendar",
|
|
8555
8571
|
"pos": {
|
|
8556
8572
|
"x": 0,
|
|
8557
8573
|
"y": 0,
|
|
8574
|
+
"w": 12,
|
|
8575
|
+
"h": 6
|
|
8576
|
+
}
|
|
8577
|
+
},
|
|
8578
|
+
{
|
|
8579
|
+
"kind": "view",
|
|
8580
|
+
"viewName": "Pillars",
|
|
8581
|
+
"pos": {
|
|
8582
|
+
"x": 0,
|
|
8583
|
+
"y": 6,
|
|
8558
8584
|
"w": 6,
|
|
8559
8585
|
"h": 5
|
|
8560
8586
|
}
|
|
@@ -8564,7 +8590,7 @@ var DATA = {
|
|
|
8564
8590
|
"viewName": "Newsletters",
|
|
8565
8591
|
"pos": {
|
|
8566
8592
|
"x": 6,
|
|
8567
|
-
"y":
|
|
8593
|
+
"y": 6,
|
|
8568
8594
|
"w": 6,
|
|
8569
8595
|
"h": 5
|
|
8570
8596
|
}
|
|
@@ -9744,6 +9770,62 @@ var DATA = {
|
|
|
9744
9770
|
"targetProfileSlug": "deal",
|
|
9745
9771
|
"type": "linked_to_deal"
|
|
9746
9772
|
}
|
|
9773
|
+
],
|
|
9774
|
+
"playbooks": [
|
|
9775
|
+
{
|
|
9776
|
+
"name": "Enrich this lead",
|
|
9777
|
+
"description": "Take a thin, freshly-captured lead and fill it out \u2014 company, title, LinkedIn, and the relationships around it.",
|
|
9778
|
+
"goalTemplate": "Enrich this lead ({lead}). Starting from whatever is known, fill out the missing detail \u2014 company, job title, LinkedIn URL, location, and the people and companies around them \u2014 and record it on the lead. Draw on whatever enrichment capability this workspace has connected (e.g. an Apify or Unipile/LinkedIn tool); if none is available, enrich from the public web and what is already in the pod. Link the lead to its company and any related contacts, and note where information is still missing.",
|
|
9779
|
+
"subjectProfile": {
|
|
9780
|
+
"profileSlug": "lead"
|
|
9781
|
+
},
|
|
9782
|
+
"params": [
|
|
9783
|
+
{
|
|
9784
|
+
"name": "lead",
|
|
9785
|
+
"type": "entity",
|
|
9786
|
+
"label": "Lead",
|
|
9787
|
+
"required": true
|
|
9788
|
+
}
|
|
9789
|
+
],
|
|
9790
|
+
"executor": "is-agent",
|
|
9791
|
+
"status": "active"
|
|
9792
|
+
},
|
|
9793
|
+
{
|
|
9794
|
+
"name": "Qualify this lead",
|
|
9795
|
+
"description": "Assess a lead against the ICP, score the fit, and decide the next step \u2014 advance, nurture, or disqualify.",
|
|
9796
|
+
"goalTemplate": "Qualify this lead ({lead}). Assess how well they fit our ideal customer profile \u2014 company, role, industry, size, and the signals of intent or need \u2014 and set an ICP score. Decide the next step: advance them toward a deal, keep nurturing, or disqualify. Write the reasoning and the decision back onto the lead (its stage, score, and next step) so the call is auditable.",
|
|
9797
|
+
"subjectProfile": {
|
|
9798
|
+
"profileSlug": "lead"
|
|
9799
|
+
},
|
|
9800
|
+
"params": [
|
|
9801
|
+
{
|
|
9802
|
+
"name": "lead",
|
|
9803
|
+
"type": "entity",
|
|
9804
|
+
"label": "Lead",
|
|
9805
|
+
"required": true
|
|
9806
|
+
}
|
|
9807
|
+
],
|
|
9808
|
+
"executor": "is-agent",
|
|
9809
|
+
"status": "active"
|
|
9810
|
+
},
|
|
9811
|
+
{
|
|
9812
|
+
"name": "Work this deal",
|
|
9813
|
+
"description": "Move a deal toward Won \u2014 read the current stage, find the blocker, and propose the next step and owner.",
|
|
9814
|
+
"goalTemplate": "Work this deal ({deal}) toward Won. Assess where it stands \u2014 its current stage, value, and close date \u2014 and identify the single thing blocking it from advancing. Propose the concrete next step, who owns it, and by when, and update the deal's next step accordingly. If the stage should change, say so and why.",
|
|
9815
|
+
"subjectProfile": {
|
|
9816
|
+
"profileSlug": "deal"
|
|
9817
|
+
},
|
|
9818
|
+
"params": [
|
|
9819
|
+
{
|
|
9820
|
+
"name": "deal",
|
|
9821
|
+
"type": "entity",
|
|
9822
|
+
"label": "Deal",
|
|
9823
|
+
"required": true
|
|
9824
|
+
}
|
|
9825
|
+
],
|
|
9826
|
+
"executor": "is-agent",
|
|
9827
|
+
"status": "active"
|
|
9828
|
+
}
|
|
9747
9829
|
]
|
|
9748
9830
|
},
|
|
9749
9831
|
"dev-dashboard": {
|
|
@@ -12026,11 +12108,43 @@ var DATA = {
|
|
|
12026
12108
|
}
|
|
12027
12109
|
],
|
|
12028
12110
|
"executor": "is-agent",
|
|
12111
|
+
"schedule": {
|
|
12112
|
+
"cron": "0 9 * * 1",
|
|
12113
|
+
"enabled": false
|
|
12114
|
+
},
|
|
12029
12115
|
"grants": [
|
|
12030
12116
|
"Web Search",
|
|
12031
12117
|
"Entity Creator"
|
|
12032
12118
|
],
|
|
12033
12119
|
"status": "active"
|
|
12120
|
+
},
|
|
12121
|
+
{
|
|
12122
|
+
"name": "Discover Competitors",
|
|
12123
|
+
"description": "Scan the market for competitors we don't track yet and add them to the ecosystem \u2014 the self-generating half of the radar.",
|
|
12124
|
+
"goalTemplate": 'Find companies that compete with us in {ourSpace}. Use neural web search (the exa_search skill with category "company") to surface real, named companies \u2014 direct competitors, adjacent tools that solve the same job a different way, and emerging players. For each genuinely NEW one (not already a competitor in our ecosystem), propose it as a `competitor` entity and ALWAYS include its `website` (its canonical URL) so it de-duplicates against what we already track \u2014 never create a company that already exists. Skip anything already known. Report what you added and why each one matters.',
|
|
12125
|
+
"schedule": {
|
|
12126
|
+
"cron": "0 9 * * 1",
|
|
12127
|
+
"enabled": false
|
|
12128
|
+
},
|
|
12129
|
+
"params": [
|
|
12130
|
+
{
|
|
12131
|
+
"name": "ourSpace",
|
|
12132
|
+
"type": "text",
|
|
12133
|
+
"label": "Our market / category",
|
|
12134
|
+
"required": true
|
|
12135
|
+
}
|
|
12136
|
+
],
|
|
12137
|
+
"executor": "is-agent",
|
|
12138
|
+
"grants": [
|
|
12139
|
+
"exa_search",
|
|
12140
|
+
"Entity Creator"
|
|
12141
|
+
],
|
|
12142
|
+
"status": "active"
|
|
12143
|
+
}
|
|
12144
|
+
],
|
|
12145
|
+
"integrations": [
|
|
12146
|
+
{
|
|
12147
|
+
"templateKey": "exa"
|
|
12034
12148
|
}
|
|
12035
12149
|
],
|
|
12036
12150
|
"onboarding": {
|
|
@@ -24924,6 +25038,19 @@ function listPublicTemplates() {
|
|
|
24924
25038
|
}
|
|
24925
25039
|
|
|
24926
25040
|
// src/catalog.ts
|
|
25041
|
+
function rowToRemoteEntry(row, isPrivate) {
|
|
25042
|
+
return {
|
|
25043
|
+
slug: row.slug,
|
|
25044
|
+
name: row.displayName,
|
|
25045
|
+
description: row.description ?? void 0,
|
|
25046
|
+
category: row.category,
|
|
25047
|
+
tags: row.tags ?? [],
|
|
25048
|
+
icon: row.icon ?? null,
|
|
25049
|
+
isPrivate
|
|
25050
|
+
// Both list routes strip `definition`; absence ⇒ bundle wins a slug conflict,
|
|
25051
|
+
// and the install path fetches the full definition per-slug when needed.
|
|
25052
|
+
};
|
|
25053
|
+
}
|
|
24927
25054
|
function parseSemver(v) {
|
|
24928
25055
|
if (!v) return null;
|
|
24929
25056
|
const m = /^\s*v?(\d+)\.(\d+)\.(\d+)/.exec(v);
|
|
@@ -24998,6 +25125,44 @@ function mergeCatalog(input) {
|
|
|
24998
25125
|
sources: { bundled: "ok", remote: remoteStatus }
|
|
24999
25126
|
};
|
|
25000
25127
|
}
|
|
25128
|
+
function assembleCatalog(input) {
|
|
25129
|
+
const remote = (input.remoteRows ?? []).map(
|
|
25130
|
+
(row) => rowToRemoteEntry(row, row.isPublic === false ? true : void 0)
|
|
25131
|
+
);
|
|
25132
|
+
return mergeCatalog({
|
|
25133
|
+
bundled: input.bundled,
|
|
25134
|
+
remote,
|
|
25135
|
+
bundleVersion: input.bundleVersion,
|
|
25136
|
+
remoteStatus: input.remoteStatus
|
|
25137
|
+
});
|
|
25138
|
+
}
|
|
25139
|
+
function isHashVersion(version) {
|
|
25140
|
+
return typeof version === "string" && version.startsWith("h-");
|
|
25141
|
+
}
|
|
25142
|
+
function isNewerVersion(installedVersion, latestVersion) {
|
|
25143
|
+
if (latestVersion === void 0) return false;
|
|
25144
|
+
if (isHashVersion(installedVersion) || isHashVersion(latestVersion)) {
|
|
25145
|
+
return installedVersion !== latestVersion;
|
|
25146
|
+
}
|
|
25147
|
+
return remoteIsStrictlyNewer(latestVersion, installedVersion);
|
|
25148
|
+
}
|
|
25149
|
+
function computeTemplateUpdates(installed, catalog, bundleVersion) {
|
|
25150
|
+
const bySlug = new Map(catalog.map((entry) => [entry.slug, entry]));
|
|
25151
|
+
return installed.map(({ slug, version: installedVersion }) => {
|
|
25152
|
+
const entry = bySlug.get(slug);
|
|
25153
|
+
if (!entry) {
|
|
25154
|
+
return { slug, installedVersion, latestVersion: void 0, updateAvailable: false };
|
|
25155
|
+
}
|
|
25156
|
+
const latestVersion = entry.source === "remote" ? entry.remote.definition?.sourcePackage?.version : bundleVersion;
|
|
25157
|
+
return {
|
|
25158
|
+
slug,
|
|
25159
|
+
installedVersion,
|
|
25160
|
+
latestVersion,
|
|
25161
|
+
updateAvailable: isNewerVersion(installedVersion, latestVersion),
|
|
25162
|
+
isPrivate: entry.isPrivate
|
|
25163
|
+
};
|
|
25164
|
+
});
|
|
25165
|
+
}
|
|
25001
25166
|
|
|
25002
25167
|
// src/define.ts
|
|
25003
25168
|
function resolveBlockKind(block) {
|
|
@@ -25054,6 +25219,13 @@ function toWorkspaceDefinition(slugOrYaml, nameOverride) {
|
|
|
25054
25219
|
bentoLayout: bento.bentoLayout,
|
|
25055
25220
|
bentoViewBlocks: bento.bentoViewBlocks,
|
|
25056
25221
|
profileEntityBentoTemplates: tpl.profileEntityBentoTemplates,
|
|
25222
|
+
// Capability integrations — forwarded so the tRPC/UI (bundled) install door
|
|
25223
|
+
// seeds the SAME operational payload (tools + skills + capability-embedded
|
|
25224
|
+
// automations/playbooks) the CLI/Hub door gets via `toPackageDefinition`.
|
|
25225
|
+
// `workspaces.createFromDefinition` declares `capabilities` in its zod input
|
|
25226
|
+
// and routes it through the shared `applyPackagePostWorkspace` door. Omitting
|
|
25227
|
+
// it here made the browser bundled-install path carry no capabilities at all.
|
|
25228
|
+
capabilities: tpl.integrations,
|
|
25057
25229
|
workspaceSubtype: ws.subtype,
|
|
25058
25230
|
workspaceType: ws.workspaceType,
|
|
25059
25231
|
workspaceVisibility: ws.visibility,
|
|
@@ -25118,10 +25290,14 @@ function toPackageDefinition(slugOrYaml) {
|
|
|
25118
25290
|
export {
|
|
25119
25291
|
PACKAGE_DEPENDENCY_KINDS,
|
|
25120
25292
|
WORKSPACE_TEMPLATES,
|
|
25293
|
+
assembleCatalog,
|
|
25294
|
+
computeTemplateUpdates,
|
|
25121
25295
|
getWorkspaceTemplate,
|
|
25296
|
+
isHashVersion,
|
|
25122
25297
|
listPublicTemplates,
|
|
25123
25298
|
listWorkspaceTemplates,
|
|
25124
25299
|
mergeCatalog,
|
|
25300
|
+
rowToRemoteEntry,
|
|
25125
25301
|
splitBentoBlocks,
|
|
25126
25302
|
toPackageDefinition,
|
|
25127
25303
|
toWorkspaceDefinition
|