opendevbrowser 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -10
- package/dist/browser/canvas-manager.d.ts.map +1 -1
- package/dist/canvas/document-store.d.ts.map +1 -1
- package/dist/canvas/guidance.d.ts +22 -0
- package/dist/canvas/guidance.d.ts.map +1 -0
- package/dist/canvas/types.d.ts +3 -0
- package/dist/canvas/types.d.ts.map +1 -1
- package/dist/{chunk-GTTYIAI7.js → chunk-I5ZCOZZV.js} +316 -94
- package/dist/chunk-I5ZCOZZV.js.map +1 -0
- package/dist/{chunk-AVQL6WAS.js → chunk-T3VVHJTK.js} +2384 -544
- package/dist/chunk-T3VVHJTK.js.map +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/commands/daemon.d.ts +2 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/devtools/console-poll.d.ts.map +1 -1
- package/dist/cli/commands/devtools/network-poll.d.ts.map +1 -1
- package/dist/cli/commands/inspiredesign.d.ts +2 -0
- package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
- package/dist/cli/commands/macro-resolve.d.ts +2 -0
- package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
- package/dist/cli/commands/product-video.d.ts +2 -0
- package/dist/cli/commands/product-video.d.ts.map +1 -1
- package/dist/cli/commands/research.d.ts +2 -0
- package/dist/cli/commands/research.d.ts.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/daemon-autostart.d.ts +6 -2
- package/dist/cli/daemon-autostart.d.ts.map +1 -1
- package/dist/cli/daemon-commands.d.ts.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/index.js +516 -86
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/parse.d.ts.map +1 -1
- package/dist/cli/utils/workflow-message.d.ts +3 -0
- package/dist/cli/utils/workflow-message.d.ts.map +1 -1
- package/dist/daemon-fingerprint.json +1 -1
- package/dist/index.js +39 -15
- package/dist/index.js.map +1 -1
- package/dist/inspiredesign/brief-expansion.d.ts +3 -0
- package/dist/inspiredesign/brief-expansion.d.ts.map +1 -1
- package/dist/{providers/inspiredesign-capture-mode.d.ts → inspiredesign/capture-mode.d.ts} +2 -2
- package/dist/inspiredesign/capture-mode.d.ts.map +1 -0
- package/dist/{providers/inspiredesign-capture.d.ts → inspiredesign/capture.d.ts} +3 -3
- package/dist/inspiredesign/capture.d.ts.map +1 -0
- package/dist/{providers/inspiredesign-contract.d.ts → inspiredesign/contract.d.ts} +70 -6
- package/dist/inspiredesign/contract.d.ts.map +1 -0
- package/dist/inspiredesign/handoff.d.ts +12 -10
- package/dist/inspiredesign/handoff.d.ts.map +1 -1
- package/dist/inspiredesign/reference-pattern-board.d.ts +74 -0
- package/dist/inspiredesign/reference-pattern-board.d.ts.map +1 -0
- package/dist/macros/execute-runtime.d.ts +2 -1
- package/dist/macros/execute-runtime.d.ts.map +1 -1
- package/dist/macros/execute.d.ts +4 -2
- package/dist/macros/execute.d.ts.map +1 -1
- package/dist/opendevbrowser.js +39 -15
- package/dist/opendevbrowser.js.map +1 -1
- package/dist/providers/browser-fallback.d.ts +7 -0
- package/dist/providers/browser-fallback.d.ts.map +1 -1
- package/dist/providers/community/index.d.ts.map +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/renderer.d.ts +1 -1
- package/dist/providers/renderer.d.ts.map +1 -1
- package/dist/providers/research-compiler.d.ts.map +1 -1
- package/dist/providers/runtime-bundle.d.ts +1 -1
- package/dist/providers/runtime-bundle.d.ts.map +1 -1
- package/dist/providers/runtime-factory.d.ts.map +1 -1
- package/dist/providers/shopping/index.d.ts.map +1 -1
- package/dist/providers/social/platform.d.ts.map +1 -1
- package/dist/providers/social/search-quality.d.ts.map +1 -1
- package/dist/providers/social/youtube.d.ts.map +1 -1
- package/dist/providers/workflow-handoff.d.ts +18 -1
- package/dist/providers/workflow-handoff.d.ts.map +1 -1
- package/dist/providers/workflows.d.ts +10 -5
- package/dist/providers/workflows.d.ts.map +1 -1
- package/dist/{providers-T2FQJCF6.js → providers-QF2RFB4J.js} +2 -2
- package/dist/public-surface/generated-manifest.d.ts +8 -8
- package/dist/public-surface/generated-manifest.d.ts.map +1 -1
- package/dist/public-surface/source.d.ts +13 -12
- package/dist/public-surface/source.d.ts.map +1 -1
- package/dist/relay/protocol.d.ts +14 -2
- package/dist/relay/protocol.d.ts.map +1 -1
- package/dist/tools/inspiredesign_run.d.ts.map +1 -1
- package/dist/tools/macro_resolve.d.ts.map +1 -1
- package/dist/tools/product_video_run.d.ts.map +1 -1
- package/dist/tools/research_run.d.ts.map +1 -1
- package/dist/tools/shopping_run.d.ts.map +1 -1
- package/extension/dist/canvas/canvas-runtime.js +13 -6
- package/extension/dist/services/ConnectionManager.js +8 -4
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
- package/skills/opendevbrowser-best-practices/SKILL.md +6 -6
- package/skills/opendevbrowser-best-practices/assets/templates/skill-runtime-pack-matrix.json +1 -1
- package/skills/opendevbrowser-design-agent/SKILL.md +5 -0
- package/skills/opendevbrowser-design-agent/artifacts/design-contract-playbook.md +6 -1
- package/skills/opendevbrowser-design-agent/assets/templates/design-contract.v1.json +15 -1
- package/skills/opendevbrowser-design-agent/assets/templates/inspiredesign-advanced-brief.v1.json +72 -33
- package/skills/opendevbrowser-design-agent/assets/templates/reference-pattern-board.v1.json +2 -0
- package/dist/chunk-AVQL6WAS.js.map +0 -1
- package/dist/chunk-GTTYIAI7.js.map +0 -1
- package/dist/providers/inspiredesign-capture-mode.d.ts.map +0 -1
- package/dist/providers/inspiredesign-capture.d.ts.map +0 -1
- package/dist/providers/inspiredesign-contract.d.ts.map +0 -1
- /package/dist/{providers-T2FQJCF6.js.map → providers-QF2RFB4J.js.map} +0 -0
|
@@ -3595,7 +3595,7 @@ var readFallbackRecord = (details, key) => {
|
|
|
3595
3595
|
};
|
|
3596
3596
|
var readFallbackString = (output, key) => {
|
|
3597
3597
|
const value = output?.[key];
|
|
3598
|
-
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
3598
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
3599
3599
|
};
|
|
3600
3600
|
var fallbackDispositionMessage = (fallback, url) => {
|
|
3601
3601
|
if (typeof fallback.details?.message === "string" && fallback.details.message.trim().length > 0) {
|
|
@@ -3610,32 +3610,67 @@ var fallbackDispositionMessage = (fallback, url) => {
|
|
|
3610
3610
|
return `Browser fallback failed for ${url}`;
|
|
3611
3611
|
}
|
|
3612
3612
|
};
|
|
3613
|
+
var fallbackErrorDetails = (args) => ({
|
|
3614
|
+
url: args.url,
|
|
3615
|
+
disposition: args.fallback.disposition,
|
|
3616
|
+
...args.fallback.mode ? { browserFallbackMode: args.fallback.mode } : {},
|
|
3617
|
+
...args.fallback.challenge ? { challenge: toJsonRecord(args.fallback.challenge) } : {},
|
|
3618
|
+
...args.fallback.preservedSessionId ? { preservedSessionId: args.fallback.preservedSessionId } : {},
|
|
3619
|
+
...args.fallback.preservedTargetId ? { preservedTargetId: args.fallback.preservedTargetId } : {},
|
|
3620
|
+
...toJsonRecord(args.fallback.details ?? {}),
|
|
3621
|
+
...args.extra ?? {}
|
|
3622
|
+
});
|
|
3623
|
+
var addProviderIssueGuidance = (args) => {
|
|
3624
|
+
const hint = readProviderIssueHint({
|
|
3625
|
+
reasonCode: args.reasonCode,
|
|
3626
|
+
details: args.details
|
|
3627
|
+
});
|
|
3628
|
+
const guidanceDetails = args.includeCompleted ? { ...args.details, disposition: "failed" } : args.details;
|
|
3629
|
+
const guidance = hint ? buildProviderIssueGuidance({ provider: args.provider, hint, details: guidanceDetails }) : void 0;
|
|
3630
|
+
return guidance ? { ...args.details, guidance } : args.details;
|
|
3631
|
+
};
|
|
3613
3632
|
var toProviderFallbackError = (args) => {
|
|
3614
3633
|
const { fallback } = args;
|
|
3615
3634
|
const reasonCode = fallback.reasonCode;
|
|
3616
|
-
const details = {
|
|
3635
|
+
const details = fallbackErrorDetails({ url: args.url, fallback });
|
|
3636
|
+
return new ProviderRuntimeError(
|
|
3637
|
+
providerErrorCodeFromReasonCode(reasonCode),
|
|
3638
|
+
fallbackDispositionMessage(fallback, args.url),
|
|
3639
|
+
{
|
|
3640
|
+
provider: args.provider,
|
|
3641
|
+
source: args.source,
|
|
3642
|
+
retryable: reasonCode === "rate_limited",
|
|
3643
|
+
reasonCode,
|
|
3644
|
+
details: addProviderIssueGuidance({
|
|
3645
|
+
provider: args.provider,
|
|
3646
|
+
reasonCode,
|
|
3647
|
+
details
|
|
3648
|
+
})
|
|
3649
|
+
}
|
|
3650
|
+
);
|
|
3651
|
+
};
|
|
3652
|
+
var toCompletedFallbackOutputError = (args) => {
|
|
3653
|
+
const { fallback } = args;
|
|
3654
|
+
const reasonCode = fallback.reasonCode;
|
|
3655
|
+
const details = fallbackErrorDetails({
|
|
3617
3656
|
url: args.url,
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
...fallback.challenge ? { challenge: toJsonRecord(fallback.challenge) } : {},
|
|
3621
|
-
...fallback.preservedSessionId ? { preservedSessionId: fallback.preservedSessionId } : {},
|
|
3622
|
-
...fallback.preservedTargetId ? { preservedTargetId: fallback.preservedTargetId } : {},
|
|
3623
|
-
...toJsonRecord(fallback.details ?? {})
|
|
3624
|
-
};
|
|
3625
|
-
const hint = readProviderIssueHint({
|
|
3626
|
-
reasonCode,
|
|
3627
|
-
details
|
|
3657
|
+
fallback,
|
|
3658
|
+
extra: { fallbackOutputReason: args.outputReason }
|
|
3628
3659
|
});
|
|
3629
|
-
const guidance = hint ? buildProviderIssueGuidance({ provider: args.provider, hint, details }) : void 0;
|
|
3630
3660
|
return new ProviderRuntimeError(
|
|
3631
3661
|
providerErrorCodeFromReasonCode(reasonCode),
|
|
3632
|
-
|
|
3662
|
+
`Browser fallback completed for ${args.url} without usable HTML content.`,
|
|
3633
3663
|
{
|
|
3634
3664
|
provider: args.provider,
|
|
3635
3665
|
source: args.source,
|
|
3636
3666
|
retryable: reasonCode === "rate_limited",
|
|
3637
3667
|
reasonCode,
|
|
3638
|
-
details:
|
|
3668
|
+
details: addProviderIssueGuidance({
|
|
3669
|
+
provider: args.provider,
|
|
3670
|
+
reasonCode,
|
|
3671
|
+
details,
|
|
3672
|
+
includeCompleted: true
|
|
3673
|
+
})
|
|
3639
3674
|
}
|
|
3640
3675
|
);
|
|
3641
3676
|
};
|
|
@@ -5070,6 +5105,10 @@ var toPositiveInt = (value, fallback) => {
|
|
|
5070
5105
|
if (typeof value !== "number" || Number.isNaN(value)) return fallback;
|
|
5071
5106
|
return Math.max(1, Math.floor(value));
|
|
5072
5107
|
};
|
|
5108
|
+
var toNonNegativeInt = (value, fallback) => {
|
|
5109
|
+
if (typeof value !== "number" || Number.isNaN(value)) return fallback;
|
|
5110
|
+
return Math.max(0, Math.floor(value));
|
|
5111
|
+
};
|
|
5073
5112
|
var isHttpUrl2 = (value) => {
|
|
5074
5113
|
try {
|
|
5075
5114
|
const protocol = new URL(value).protocol;
|
|
@@ -5115,11 +5154,11 @@ var mergedTraversal = (options, input) => {
|
|
|
5115
5154
|
asNumber(filters.pageLimit) ?? options.defaultTraversal?.pageLimit,
|
|
5116
5155
|
DEFAULT_TRAVERSAL.pageLimit
|
|
5117
5156
|
),
|
|
5118
|
-
hopLimit:
|
|
5157
|
+
hopLimit: toNonNegativeInt(
|
|
5119
5158
|
asNumber(filters.hopLimit) ?? options.defaultTraversal?.hopLimit,
|
|
5120
5159
|
DEFAULT_TRAVERSAL.hopLimit
|
|
5121
5160
|
),
|
|
5122
|
-
expansionPerRecord:
|
|
5161
|
+
expansionPerRecord: toNonNegativeInt(
|
|
5123
5162
|
asNumber(filters.expansionPerRecord) ?? options.defaultTraversal?.expansionPerRecord,
|
|
5124
5163
|
DEFAULT_TRAVERSAL.expansionPerRecord
|
|
5125
5164
|
),
|
|
@@ -5428,7 +5467,7 @@ var createCommunityProvider = (options = {}) => {
|
|
|
5428
5467
|
};
|
|
5429
5468
|
|
|
5430
5469
|
// src/providers/social/search-quality.ts
|
|
5431
|
-
var TARGETED_PLATFORMS = /* @__PURE__ */ new Set(["x", "bluesky", "reddit", "facebook"]);
|
|
5470
|
+
var TARGETED_PLATFORMS = /* @__PURE__ */ new Set(["x", "bluesky", "reddit", "facebook", "threads"]);
|
|
5432
5471
|
var SOCIAL_JS_REQUIRED_RE = /\b(?:javascript (?:is not available|required|is disabled(?: in this browser)?)|you need to enable javascript|please enable javascript)\b/i;
|
|
5433
5472
|
var BLUESKY_LOGGED_OUT_SEARCH_RE = /\bsearch is currently unavailable when logged out\b/i;
|
|
5434
5473
|
var BLUESKY_EMPTY_SEARCH_SHELL_RE = /\b(?:follow 10 people to get started|find people to follow)\b/i;
|
|
@@ -5496,6 +5535,10 @@ var isPrimaryFacebookHost = (host) => {
|
|
|
5496
5535
|
const normalized = host.toLowerCase();
|
|
5497
5536
|
return normalized === "www.facebook.com" || normalized === "facebook.com" || normalized === "m.facebook.com";
|
|
5498
5537
|
};
|
|
5538
|
+
var isPrimaryThreadsHost = (host) => {
|
|
5539
|
+
const normalized = host.toLowerCase();
|
|
5540
|
+
return normalized === "www.threads.net" || normalized === "threads.net";
|
|
5541
|
+
};
|
|
5499
5542
|
var isFacebookSearchLikePath = (pathname) => pathname === "/watch/search" || pathname === "/watch/search/" || pathname.startsWith("/watch/explore/") || pathname.startsWith("/search/") || pathname.startsWith("/public/") || pathname.startsWith("/hashtag/");
|
|
5500
5543
|
var isBlockedFacebookNonContentUrl = (parsed, options) => {
|
|
5501
5544
|
if (!isPrimaryFacebookHost(parsed.hostname)) {
|
|
@@ -5522,7 +5565,7 @@ var isBlockedRedditNonContentUrl = (parsed, options) => {
|
|
|
5522
5565
|
return false;
|
|
5523
5566
|
}
|
|
5524
5567
|
const pathname = parsed.pathname.toLowerCase();
|
|
5525
|
-
if (pathname === "/" || pathname === "/login" || options.includeSearchRoute && pathname === "/search") {
|
|
5568
|
+
if (pathname === "/" || pathname === "/login" || pathname === "/login/" || options.includeSearchRoute && (pathname === "/search" || pathname === "/search/")) {
|
|
5526
5569
|
return true;
|
|
5527
5570
|
}
|
|
5528
5571
|
const pathSegment = firstPathSegment(pathname);
|
|
@@ -5540,6 +5583,8 @@ var isRootShellUrl = (platform, parsed) => {
|
|
|
5540
5583
|
return isBlockedRedditNonContentUrl(parsed, { includeSearchRoute: false });
|
|
5541
5584
|
case "facebook":
|
|
5542
5585
|
return isBlockedFacebookNonContentUrl(parsed, { includeSearchRoute: false });
|
|
5586
|
+
case "threads":
|
|
5587
|
+
return isPrimaryThreadsHost(host) && (pathname === "/" || pathname === "/login" || pathname === "/login/");
|
|
5543
5588
|
default:
|
|
5544
5589
|
return false;
|
|
5545
5590
|
}
|
|
@@ -5556,6 +5601,8 @@ var isBlockedExpansionPath = (platform, parsed) => {
|
|
|
5556
5601
|
return isBlockedRedditNonContentUrl(parsed, { includeSearchRoute: true });
|
|
5557
5602
|
case "facebook":
|
|
5558
5603
|
return isBlockedFacebookNonContentUrl(parsed, { includeSearchRoute: true });
|
|
5604
|
+
case "threads":
|
|
5605
|
+
return isPrimaryThreadsHost(host) && (pathname === "/" || pathname === "/login" || pathname === "/search" || pathname === "/search/" || isStaticMetadataPath(pathname));
|
|
5559
5606
|
default:
|
|
5560
5607
|
return false;
|
|
5561
5608
|
}
|
|
@@ -5569,9 +5616,11 @@ var isFirstPartySearchRoute = (platform, parsed) => {
|
|
|
5569
5616
|
case "bluesky":
|
|
5570
5617
|
return host === "bsky.app" && pathname === "/search";
|
|
5571
5618
|
case "reddit":
|
|
5572
|
-
return isPrimaryRedditHost(host) && pathname === "/search";
|
|
5619
|
+
return isPrimaryRedditHost(host) && (pathname === "/search" || pathname === "/search/");
|
|
5573
5620
|
case "facebook":
|
|
5574
5621
|
return isPrimaryFacebookHost(host) && isFacebookSearchLikePath(pathname);
|
|
5622
|
+
case "threads":
|
|
5623
|
+
return isPrimaryThreadsHost(host) && (pathname === "/search" || pathname === "/search/");
|
|
5575
5624
|
default:
|
|
5576
5625
|
return false;
|
|
5577
5626
|
}
|
|
@@ -5648,6 +5697,10 @@ var isUsableFacebookSearchEvidenceUrl = (url) => {
|
|
|
5648
5697
|
}
|
|
5649
5698
|
return /^\/reel\/[^/]+\/?$/.test(pathname) || /^\/groups\/[^/]+\/posts\/[^/]+\/?$/.test(pathname) || /^\/[^/]+\/videos\/[^/]+\/?$/.test(pathname) || /^\/share\/v\/[^/]+\/?$/.test(pathname) || (pathname === "/permalink.php" || pathname === "/story.php") && parsed.searchParams.has("story_fbid") || pathname === "/photo/" && parsed.searchParams.has("fbid");
|
|
5650
5699
|
};
|
|
5700
|
+
var isUsableThreadsSearchEvidenceUrl = (url) => {
|
|
5701
|
+
const parsed = parseUrl(url);
|
|
5702
|
+
return parsed !== null && isPrimaryThreadsHost(parsed.hostname) && /^\/@[^/]+\/post\/[^/]+\/?$/.test(parsed.pathname.toLowerCase());
|
|
5703
|
+
};
|
|
5651
5704
|
var isRetainableFacebookSearchSupportUrl = (url) => {
|
|
5652
5705
|
const parsed = parseUrl(url);
|
|
5653
5706
|
if (parsed === null || !isPrimaryFacebookHost(parsed.hostname)) {
|
|
@@ -5670,17 +5723,18 @@ var hasFacebookSearchResultSignals = (input) => {
|
|
|
5670
5723
|
const hasSearchHeading = FACEBOOK_SEARCH_RESULTS_HEADING_RE.test(combined);
|
|
5671
5724
|
const markerCount = FACEBOOK_SEARCH_RESULT_MARKERS.filter((pattern) => pattern.test(combined)).length;
|
|
5672
5725
|
const evidence = collectSocialSearchLinkEvidence("facebook", parsed.toString(), Array.isArray(input.links) ? input.links : []);
|
|
5726
|
+
const hasContentEvidence = evidence.usableContentLinks.length > 0;
|
|
5673
5727
|
const supportLinkCount = evidence.usableLinks.filter(isRetainableFacebookSearchSupportUrl).length;
|
|
5674
|
-
if (markerCount >= 2) {
|
|
5728
|
+
if (markerCount >= 2 && hasContentEvidence) {
|
|
5675
5729
|
return true;
|
|
5676
5730
|
}
|
|
5677
5731
|
if (!hasSearchHeading) {
|
|
5678
5732
|
return false;
|
|
5679
5733
|
}
|
|
5680
|
-
if (markerCount >= 1) {
|
|
5734
|
+
if (markerCount >= 1 && hasContentEvidence) {
|
|
5681
5735
|
return true;
|
|
5682
5736
|
}
|
|
5683
|
-
return supportLinkCount >= 2;
|
|
5737
|
+
return supportLinkCount >= 2 && hasContentEvidence;
|
|
5684
5738
|
};
|
|
5685
5739
|
var isUsableSocialSearchContentUrl = (platform, url) => {
|
|
5686
5740
|
switch (platform) {
|
|
@@ -5692,6 +5746,8 @@ var isUsableSocialSearchContentUrl = (platform, url) => {
|
|
|
5692
5746
|
return isUsableRedditSearchEvidenceUrl(url);
|
|
5693
5747
|
case "facebook":
|
|
5694
5748
|
return isUsableFacebookSearchEvidenceUrl(url);
|
|
5749
|
+
case "threads":
|
|
5750
|
+
return isUsableThreadsSearchEvidenceUrl(url);
|
|
5695
5751
|
default:
|
|
5696
5752
|
return false;
|
|
5697
5753
|
}
|
|
@@ -5865,6 +5921,10 @@ var toPositiveInt2 = (value, fallback) => {
|
|
|
5865
5921
|
if (typeof value !== "number" || Number.isNaN(value)) return fallback;
|
|
5866
5922
|
return Math.max(1, Math.floor(value));
|
|
5867
5923
|
};
|
|
5924
|
+
var toNonNegativeInt2 = (value, fallback) => {
|
|
5925
|
+
if (typeof value !== "number" || Number.isNaN(value)) return fallback;
|
|
5926
|
+
return Math.max(0, Math.floor(value));
|
|
5927
|
+
};
|
|
5868
5928
|
var isHttpUrl3 = (value) => {
|
|
5869
5929
|
try {
|
|
5870
5930
|
const protocol = new URL(value).protocol;
|
|
@@ -5954,11 +6014,11 @@ var mergedTraversal2 = (input, options) => {
|
|
|
5954
6014
|
asNumber2(filters.pageLimit) ?? options.defaultTraversal?.pageLimit,
|
|
5955
6015
|
DEFAULT_TRAVERSAL2.pageLimit
|
|
5956
6016
|
),
|
|
5957
|
-
hopLimit:
|
|
6017
|
+
hopLimit: toNonNegativeInt2(
|
|
5958
6018
|
asNumber2(filters.hopLimit) ?? options.defaultTraversal?.hopLimit,
|
|
5959
6019
|
DEFAULT_TRAVERSAL2.hopLimit
|
|
5960
6020
|
),
|
|
5961
|
-
expansionPerRecord:
|
|
6021
|
+
expansionPerRecord: toNonNegativeInt2(
|
|
5962
6022
|
asNumber2(filters.expansionPerRecord) ?? options.defaultTraversal?.expansionPerRecord,
|
|
5963
6023
|
DEFAULT_TRAVERSAL2.expansionPerRecord
|
|
5964
6024
|
),
|
|
@@ -7412,6 +7472,47 @@ var normalizeYouTubeVideoLink = (url) => {
|
|
|
7412
7472
|
}
|
|
7413
7473
|
};
|
|
7414
7474
|
var YOUTUBE_SEARCH_SHELL_RE = /\b(?:about press copyright contact us creators advertise developers terms privacy policy|google for developers skip to main content youtube)\b/i;
|
|
7475
|
+
var YOUTUBE_FALLBACK_MIN_TEXT_CHARS = 40;
|
|
7476
|
+
var YOUTUBE_CONTENT_MARKER_RE = /"videoId"\s*:|"captionTracks"\s*:|itemprop="author"|itemprop="datePublished"|"viewCount"\s*:/i;
|
|
7477
|
+
var hasYouTubeFallbackEvidence = (html, url) => {
|
|
7478
|
+
if (YOUTUBE_CONTENT_MARKER_RE.test(html)) return true;
|
|
7479
|
+
return extractStructuredContent(html, url).links.some((link) => normalizeYouTubeVideoLink(link) !== null);
|
|
7480
|
+
};
|
|
7481
|
+
var reviewedFallback = (fallback, reasonCode) => ({
|
|
7482
|
+
...fallback,
|
|
7483
|
+
reasonCode: reasonCode ?? fallback.reasonCode
|
|
7484
|
+
});
|
|
7485
|
+
var assertUsableYouTubeFallbackPage = (url, fallback, html) => {
|
|
7486
|
+
const extracted = extractStructuredContent(html, url);
|
|
7487
|
+
const text = extracted.text.trim();
|
|
7488
|
+
const blocker = classifyBlockerSignal({
|
|
7489
|
+
source: "runtime_fetch",
|
|
7490
|
+
url,
|
|
7491
|
+
message: text,
|
|
7492
|
+
status: 200,
|
|
7493
|
+
providerErrorCode: "unavailable",
|
|
7494
|
+
retryable: true
|
|
7495
|
+
});
|
|
7496
|
+
if (blocker && blocker.type !== "unknown") {
|
|
7497
|
+
throw toCompletedFallbackOutputError({
|
|
7498
|
+
provider: "social/youtube",
|
|
7499
|
+
source: "social",
|
|
7500
|
+
url,
|
|
7501
|
+
fallback: reviewedFallback(fallback, blocker.reasonCode),
|
|
7502
|
+
outputReason: blocker.type
|
|
7503
|
+
});
|
|
7504
|
+
}
|
|
7505
|
+
if (hasYouTubeFallbackEvidence(html, url)) return;
|
|
7506
|
+
if (text.length < YOUTUBE_FALLBACK_MIN_TEXT_CHARS || YOUTUBE_SEARCH_SHELL_RE.test(text)) {
|
|
7507
|
+
throw toCompletedFallbackOutputError({
|
|
7508
|
+
provider: "social/youtube",
|
|
7509
|
+
source: "social",
|
|
7510
|
+
url,
|
|
7511
|
+
fallback,
|
|
7512
|
+
outputReason: "youtube_shell_or_metadata"
|
|
7513
|
+
});
|
|
7514
|
+
}
|
|
7515
|
+
};
|
|
7415
7516
|
var extractSearchResultSegment = (html, videoId) => {
|
|
7416
7517
|
const marker = new RegExp(`"videoId"\\s*:\\s*"${escapeRegExp(videoId)}"`);
|
|
7417
7518
|
const match = marker.exec(html);
|
|
@@ -7514,7 +7615,7 @@ var summarizeTranscript = (transcript) => {
|
|
|
7514
7615
|
const lines = transcript.split(/\n+/).map((line) => line.trim()).filter(Boolean);
|
|
7515
7616
|
return lines.slice(0, 8).join(" ").slice(0, 800);
|
|
7516
7617
|
};
|
|
7517
|
-
var
|
|
7618
|
+
var fetchPageDirect = async (url, context) => {
|
|
7518
7619
|
let response;
|
|
7519
7620
|
try {
|
|
7520
7621
|
response = await fetch(url, {
|
|
@@ -7567,6 +7668,108 @@ var fetchPage = async (url, context) => {
|
|
|
7567
7668
|
html: await response.text()
|
|
7568
7669
|
};
|
|
7569
7670
|
};
|
|
7671
|
+
var forcedFallbackReasonCode = (context) => {
|
|
7672
|
+
const policy = context.runtimePolicy;
|
|
7673
|
+
if (policy?.cookies.policy === "required") return "auth_required";
|
|
7674
|
+
return "env_limited";
|
|
7675
|
+
};
|
|
7676
|
+
var fallbackReasonCodeForPageError = (error, context) => {
|
|
7677
|
+
if (!isProviderRuntimeError(error)) return "env_limited";
|
|
7678
|
+
if (error.code === "auth") {
|
|
7679
|
+
return context.runtimePolicy?.cookies.policy === "required" ? "auth_required" : "token_required";
|
|
7680
|
+
}
|
|
7681
|
+
if (error.code === "rate_limited") return "rate_limited";
|
|
7682
|
+
if (error.code === "network" || error.code === "timeout") return "env_limited";
|
|
7683
|
+
if (error.code === "upstream") return "ip_blocked";
|
|
7684
|
+
if (error.reasonCode === "ip_blocked" || error.reasonCode === "challenge_detected") return error.reasonCode;
|
|
7685
|
+
return null;
|
|
7686
|
+
};
|
|
7687
|
+
var fallbackDetailsForError = (error) => {
|
|
7688
|
+
if (!isProviderRuntimeError(error)) return {};
|
|
7689
|
+
return {
|
|
7690
|
+
errorCode: error.code,
|
|
7691
|
+
message: error.message,
|
|
7692
|
+
...error.details ?? {}
|
|
7693
|
+
};
|
|
7694
|
+
};
|
|
7695
|
+
var pageFromFallback = (url, fallback) => {
|
|
7696
|
+
const html = readFallbackString(fallback.output, "html");
|
|
7697
|
+
if (!html) {
|
|
7698
|
+
throw toCompletedFallbackOutputError({
|
|
7699
|
+
provider: "social/youtube",
|
|
7700
|
+
source: "social",
|
|
7701
|
+
url,
|
|
7702
|
+
fallback,
|
|
7703
|
+
outputReason: "missing_or_empty_html"
|
|
7704
|
+
});
|
|
7705
|
+
}
|
|
7706
|
+
assertUsableYouTubeFallbackPage(url, fallback, html);
|
|
7707
|
+
return {
|
|
7708
|
+
status: 200,
|
|
7709
|
+
url: readFallbackString(fallback.output, "url") ?? url,
|
|
7710
|
+
html,
|
|
7711
|
+
browserFallback: toBrowserFallbackObservation(fallback)
|
|
7712
|
+
};
|
|
7713
|
+
};
|
|
7714
|
+
var resolveFallbackPage = async (args) => {
|
|
7715
|
+
const fallback = await resolveProviderBrowserFallback({
|
|
7716
|
+
browserFallbackPort: args.context.browserFallbackPort ?? args.options.browserFallbackPort,
|
|
7717
|
+
provider: "social/youtube",
|
|
7718
|
+
source: "social",
|
|
7719
|
+
operation: args.operation,
|
|
7720
|
+
reasonCode: args.reasonCode,
|
|
7721
|
+
url: args.url,
|
|
7722
|
+
context: args.context,
|
|
7723
|
+
details: args.details,
|
|
7724
|
+
recoveryHints: args.options.recoveryHints?.()
|
|
7725
|
+
});
|
|
7726
|
+
if (!fallback) return null;
|
|
7727
|
+
if (fallback.disposition !== "completed") {
|
|
7728
|
+
throw toProviderFallbackError({
|
|
7729
|
+
provider: "social/youtube",
|
|
7730
|
+
source: "social",
|
|
7731
|
+
url: args.url,
|
|
7732
|
+
fallback
|
|
7733
|
+
});
|
|
7734
|
+
}
|
|
7735
|
+
return pageFromFallback(args.url, fallback);
|
|
7736
|
+
};
|
|
7737
|
+
var fetchPage = async (url, context, options, operation) => {
|
|
7738
|
+
if (context.runtimePolicy?.browser.forceTransport) {
|
|
7739
|
+
const page = await resolveFallbackPage({
|
|
7740
|
+
url,
|
|
7741
|
+
context,
|
|
7742
|
+
options,
|
|
7743
|
+
operation,
|
|
7744
|
+
reasonCode: forcedFallbackReasonCode(context),
|
|
7745
|
+
details: { message: "Direct browser transport was selected for this YouTube provider run." }
|
|
7746
|
+
});
|
|
7747
|
+
if (page) return page;
|
|
7748
|
+
throw new ProviderRuntimeError(providerErrorCodeFromReasonCode(forcedFallbackReasonCode(context)), "Direct browser transport is required for this YouTube provider run, but no browser transport is available.", {
|
|
7749
|
+
provider: "social/youtube",
|
|
7750
|
+
source: "social",
|
|
7751
|
+
retryable: false,
|
|
7752
|
+
reasonCode: forcedFallbackReasonCode(context),
|
|
7753
|
+
details: { browserTransportRequired: true }
|
|
7754
|
+
});
|
|
7755
|
+
}
|
|
7756
|
+
try {
|
|
7757
|
+
return await fetchPageDirect(url, context);
|
|
7758
|
+
} catch (error) {
|
|
7759
|
+
const reasonCode = fallbackReasonCodeForPageError(error, context);
|
|
7760
|
+
if (!reasonCode) throw error;
|
|
7761
|
+
const page = await resolveFallbackPage({
|
|
7762
|
+
url,
|
|
7763
|
+
context,
|
|
7764
|
+
options,
|
|
7765
|
+
operation,
|
|
7766
|
+
reasonCode,
|
|
7767
|
+
details: fallbackDetailsForError(error)
|
|
7768
|
+
});
|
|
7769
|
+
if (page) return page;
|
|
7770
|
+
throw error;
|
|
7771
|
+
}
|
|
7772
|
+
};
|
|
7570
7773
|
var parseBooleanFilter = (value, fallback = false) => {
|
|
7571
7774
|
if (typeof value === "boolean") return value;
|
|
7572
7775
|
if (typeof value === "string") {
|
|
@@ -7609,7 +7812,7 @@ var resolveTranscriptStrategyDetail = (transcript) => {
|
|
|
7609
7812
|
return transcript.attemptChain.at(-1)?.strategy;
|
|
7610
7813
|
};
|
|
7611
7814
|
var buildSearch = (options) => {
|
|
7612
|
-
if (options) return options;
|
|
7815
|
+
if (options.search) return options.search;
|
|
7613
7816
|
return async (input, context) => {
|
|
7614
7817
|
assertYouTubeLegalReviewChecklist();
|
|
7615
7818
|
const query = input.query.trim();
|
|
@@ -7622,7 +7825,7 @@ var buildSearch = (options) => {
|
|
|
7622
7825
|
}
|
|
7623
7826
|
const lookupUrl = isHttpUrl4(query) ? query : `https://www.youtube.com/results?search_query=${encodeURIComponent(query)}`;
|
|
7624
7827
|
const directUrlQuery = isHttpUrl4(query);
|
|
7625
|
-
const page = await fetchPage(lookupUrl, context);
|
|
7828
|
+
const page = await fetchPage(lookupUrl, context, options, "search");
|
|
7626
7829
|
const extracted = extractStructuredContent(page.html, page.url);
|
|
7627
7830
|
const extractedVideoLinks = [...new Set(
|
|
7628
7831
|
extracted.links.map((link) => normalizeYouTubeVideoLink(link)).filter((link) => typeof link === "string" && link.length > 0)
|
|
@@ -7668,7 +7871,8 @@ var buildSearch = (options) => {
|
|
|
7668
7871
|
retrievalPath: isHttpUrl4(query) ? "social:youtube:search:url" : "social:youtube:search:index",
|
|
7669
7872
|
video_id: resolvedVideoId,
|
|
7670
7873
|
...primaryResult?.channel ? { channel: primaryResult.channel } : {},
|
|
7671
|
-
links: extractedVideoLinks.slice(0, 20)
|
|
7874
|
+
links: extractedVideoLinks.slice(0, 20),
|
|
7875
|
+
...browserFallbackObservationAttributes(page.browserFallback)
|
|
7672
7876
|
}
|
|
7673
7877
|
}];
|
|
7674
7878
|
};
|
|
@@ -7677,7 +7881,7 @@ var buildFetch = (options) => {
|
|
|
7677
7881
|
if (options.fetch) return options.fetch;
|
|
7678
7882
|
return async (input, context) => {
|
|
7679
7883
|
assertYouTubeLegalReviewChecklist();
|
|
7680
|
-
const page = await fetchPage(input.url, context);
|
|
7884
|
+
const page = await fetchPage(input.url, context, options, "fetch");
|
|
7681
7885
|
const extracted = extractStructuredContent(page.html, page.url);
|
|
7682
7886
|
const includeFullTranscript = parseBooleanFilter(input.filters?.include_full_transcript, false);
|
|
7683
7887
|
const requireTranscript = parseBooleanFilter(input.filters?.requireTranscript, false);
|
|
@@ -7692,7 +7896,7 @@ var buildFetch = (options) => {
|
|
|
7692
7896
|
legalChecklist: YOUTUBE_LEGAL_REVIEW_CHECKLIST,
|
|
7693
7897
|
config: transcriptConfig,
|
|
7694
7898
|
mode: requestedMode,
|
|
7695
|
-
browserFallbackPort: options.browserFallbackPort,
|
|
7899
|
+
browserFallbackPort: context.browserFallbackPort ?? options.browserFallbackPort,
|
|
7696
7900
|
recoveryHints,
|
|
7697
7901
|
allowBrowserFallbackEscalation: options.antiBotPolicy?.allowBrowserEscalation ?? true,
|
|
7698
7902
|
asrTranscribe: options.asrTranscribe
|
|
@@ -7747,6 +7951,7 @@ var buildFetch = (options) => {
|
|
|
7747
7951
|
transcript_mode: transcript.mode,
|
|
7748
7952
|
translation_applied: translationApplied,
|
|
7749
7953
|
transcript_summary: transcriptSummary,
|
|
7954
|
+
...browserFallbackObservationAttributes(page.browserFallback),
|
|
7750
7955
|
...includeFullTranscript ? { transcript_full: transcriptContent } : {},
|
|
7751
7956
|
...transcriptStrategyDetail ? { transcript_strategy_detail: transcriptStrategyDetail } : {},
|
|
7752
7957
|
...transcript.ok ? {
|
|
@@ -7789,7 +7994,7 @@ var withDefaultYouTubeOptions = (options = {}) => {
|
|
|
7789
7994
|
};
|
|
7790
7995
|
return {
|
|
7791
7996
|
...resolvedOptions,
|
|
7792
|
-
search: buildSearch(resolvedOptions
|
|
7997
|
+
search: buildSearch(resolvedOptions),
|
|
7793
7998
|
fetch: buildFetch(resolvedOptions)
|
|
7794
7999
|
};
|
|
7795
8000
|
};
|
|
@@ -7989,6 +8194,73 @@ var getShoppingRegionSupportDiagnostics = (providerIds, region) => {
|
|
|
7989
8194
|
});
|
|
7990
8195
|
};
|
|
7991
8196
|
var hasValues2 = (values) => values.some((value) => value.trim().length > 0);
|
|
8197
|
+
var FALLBACK_HEAD_RE = /<head\b[^>]*>[\s\S]*?<\/head>/i;
|
|
8198
|
+
var FALLBACK_BODY_RE = /<body\b[^>]*>([\s\S]*?)<\/body>/i;
|
|
8199
|
+
var SHOPPING_FALLBACK_EVIDENCE_LIMIT = 1;
|
|
8200
|
+
var extractShoppingFallbackBodyText = (html) => {
|
|
8201
|
+
const body = FALLBACK_BODY_RE.exec(html)?.[1];
|
|
8202
|
+
return extractText(body ?? html.replace(FALLBACK_HEAD_RE, " "));
|
|
8203
|
+
};
|
|
8204
|
+
var hasShoppingMetadataEvidence = (extracted) => {
|
|
8205
|
+
return extracted.metadata.price !== void 0;
|
|
8206
|
+
};
|
|
8207
|
+
var hasShoppingOfferTextEvidence = (text) => {
|
|
8208
|
+
const price = parsePrice(text);
|
|
8209
|
+
if (price.amount <= 0) return false;
|
|
8210
|
+
return parseRating(text) > 0 || parseReviews(text) > 0 || parseAvailability(text) !== "unknown" || /\b(?:add to cart|buy now|shipping|pickup|deal|save)\b/i.test(text);
|
|
8211
|
+
};
|
|
8212
|
+
var hasShoppingBlockingPageEvidence = (url, extracted) => {
|
|
8213
|
+
const blocker = classifyBlockerSignal({
|
|
8214
|
+
source: "runtime_fetch",
|
|
8215
|
+
url,
|
|
8216
|
+
finalUrl: url,
|
|
8217
|
+
title: typeof extracted.metadata.title === "string" ? extracted.metadata.title : void 0,
|
|
8218
|
+
message: extracted.text,
|
|
8219
|
+
status: 200,
|
|
8220
|
+
providerErrorCode: "unavailable",
|
|
8221
|
+
retryable: true
|
|
8222
|
+
});
|
|
8223
|
+
return blocker?.type === "auth_required" || blocker?.type === "anti_bot_challenge";
|
|
8224
|
+
};
|
|
8225
|
+
var hasShoppingFallbackEvidence = (args) => {
|
|
8226
|
+
return args.extracted.links.some((link) => isLikelyProductUrl(canonicalizeUrl(link), args.profile)) || extractSearchCandidates(args.html, args.url, args.profile, SHOPPING_FALLBACK_EVIDENCE_LIMIT).length > 0 || hasShoppingMetadataEvidence(args.extracted) || hasShoppingOfferTextEvidence(extractShoppingFallbackBodyText(args.html)) || hasShoppingBlockingPageEvidence(args.url, args.extracted);
|
|
8227
|
+
};
|
|
8228
|
+
var toFallbackShellIssueError = (args) => {
|
|
8229
|
+
const issue = classifyProviderIssue({
|
|
8230
|
+
url: args.url,
|
|
8231
|
+
title: args.requirement.title,
|
|
8232
|
+
message: args.requirement.message,
|
|
8233
|
+
providerShell: args.requirement.reason,
|
|
8234
|
+
browserRequired: true,
|
|
8235
|
+
status: 200
|
|
8236
|
+
});
|
|
8237
|
+
const reasonCode = issue?.reasonCode ?? "env_limited";
|
|
8238
|
+
const extracted = extractStructuredContent(args.html, args.url);
|
|
8239
|
+
return new ProviderRuntimeError(
|
|
8240
|
+
providerErrorCodeFromReasonCode(reasonCode),
|
|
8241
|
+
reasonCode === "challenge_detected" ? `Detected anti-bot challenge while retrieving ${args.url}` : `Browser assistance required for ${args.url}`,
|
|
8242
|
+
{
|
|
8243
|
+
provider: args.provider,
|
|
8244
|
+
source: SHOPPING_SOURCE,
|
|
8245
|
+
retryable: reasonCode === "env_limited",
|
|
8246
|
+
reasonCode,
|
|
8247
|
+
details: {
|
|
8248
|
+
...applyProviderIssueHint({
|
|
8249
|
+
status: 200,
|
|
8250
|
+
url: args.url,
|
|
8251
|
+
...args.requirement.title ? { title: args.requirement.title } : {},
|
|
8252
|
+
...args.requirement.message ? { message: args.requirement.message } : {},
|
|
8253
|
+
providerShell: args.requirement.reason,
|
|
8254
|
+
browserRequired: true,
|
|
8255
|
+
extractionFocus: args.profile.extractionFocus,
|
|
8256
|
+
extractedTextLength: extracted.text.length,
|
|
8257
|
+
extractedLinkCount: extracted.links.length
|
|
8258
|
+
}, issue),
|
|
8259
|
+
...browserFallbackObservationDetails(toBrowserFallbackObservation(args.fallback))
|
|
8260
|
+
}
|
|
8261
|
+
}
|
|
8262
|
+
);
|
|
8263
|
+
};
|
|
7992
8264
|
var parseIsoDate2 = (value) => {
|
|
7993
8265
|
const parsed = Date.parse(value);
|
|
7994
8266
|
return Number.isNaN(parsed) ? NaN : parsed;
|
|
@@ -8120,11 +8392,47 @@ var resolveBrowserFallback = async (args) => {
|
|
|
8120
8392
|
};
|
|
8121
8393
|
}
|
|
8122
8394
|
const resolvedUrl = canonicalizeUrl(readFallbackString(fallback.output, "url") ?? args.url);
|
|
8395
|
+
const html = readFallbackString(fallback.output, "html");
|
|
8396
|
+
if (!html) {
|
|
8397
|
+
throw toCompletedFallbackOutputError({
|
|
8398
|
+
provider: args.provider,
|
|
8399
|
+
source: SHOPPING_SOURCE,
|
|
8400
|
+
url: resolvedUrl,
|
|
8401
|
+
fallback,
|
|
8402
|
+
outputReason: "missing_or_empty_html"
|
|
8403
|
+
});
|
|
8404
|
+
}
|
|
8405
|
+
const extracted = extractStructuredContent(html, resolvedUrl);
|
|
8406
|
+
const browserRequirement = requiresBrowserAssistance(args.profile, resolvedUrl, html);
|
|
8407
|
+
if (browserRequirement) {
|
|
8408
|
+
throw toFallbackShellIssueError({
|
|
8409
|
+
provider: args.provider,
|
|
8410
|
+
url: resolvedUrl,
|
|
8411
|
+
html,
|
|
8412
|
+
fallback,
|
|
8413
|
+
profile: args.profile,
|
|
8414
|
+
requirement: browserRequirement
|
|
8415
|
+
});
|
|
8416
|
+
}
|
|
8417
|
+
if (!hasShoppingFallbackEvidence({
|
|
8418
|
+
html,
|
|
8419
|
+
url: resolvedUrl,
|
|
8420
|
+
extracted,
|
|
8421
|
+
profile: args.profile
|
|
8422
|
+
})) {
|
|
8423
|
+
throw toCompletedFallbackOutputError({
|
|
8424
|
+
provider: args.provider,
|
|
8425
|
+
source: SHOPPING_SOURCE,
|
|
8426
|
+
url: resolvedUrl,
|
|
8427
|
+
fallback,
|
|
8428
|
+
outputReason: "empty_extracted_content"
|
|
8429
|
+
});
|
|
8430
|
+
}
|
|
8123
8431
|
return {
|
|
8124
8432
|
record: {
|
|
8125
8433
|
status: 200,
|
|
8126
8434
|
url: resolvedUrl,
|
|
8127
|
-
html
|
|
8435
|
+
html,
|
|
8128
8436
|
browserFallback: toBrowserFallbackObservation(fallback)
|
|
8129
8437
|
}
|
|
8130
8438
|
};
|
|
@@ -8237,6 +8545,7 @@ var defaultFetcher = async ({ url, signal, provider, operation, context }) => {
|
|
|
8237
8545
|
error,
|
|
8238
8546
|
url,
|
|
8239
8547
|
provider: providerId,
|
|
8548
|
+
profile,
|
|
8240
8549
|
operation,
|
|
8241
8550
|
recoveryHints,
|
|
8242
8551
|
context
|
|
@@ -8644,8 +8953,7 @@ var requiresBrowserAssistance = (profile, responseUrl, html) => {
|
|
|
8644
8953
|
}
|
|
8645
8954
|
return null;
|
|
8646
8955
|
};
|
|
8647
|
-
var classifySearchPageIssue = (profile, fetched, extracted, content) => {
|
|
8648
|
-
const providerShell = requiresBrowserAssistance(profile, fetched.url, fetched.html);
|
|
8956
|
+
var classifySearchPageIssue = (profile, fetched, extracted, content, providerShell = requiresBrowserAssistance(profile, fetched.url, fetched.html)) => {
|
|
8649
8957
|
return classifyProviderIssue({
|
|
8650
8958
|
url: fetched.url,
|
|
8651
8959
|
title: providerShell?.title ?? (typeof extracted.metadata.title === "string" ? extracted.metadata.title : void 0),
|
|
@@ -8657,6 +8965,51 @@ var classifySearchPageIssue = (profile, fetched, extracted, content) => {
|
|
|
8657
8965
|
retryable: true
|
|
8658
8966
|
});
|
|
8659
8967
|
};
|
|
8968
|
+
var toExplicitProviderShellIssue = (providerShell, content) => ({
|
|
8969
|
+
reasonCode: "env_limited",
|
|
8970
|
+
blockerType: "env_limited",
|
|
8971
|
+
constraint: {
|
|
8972
|
+
kind: "render_required",
|
|
8973
|
+
evidenceCode: providerShell.reason,
|
|
8974
|
+
providerShell: providerShell.reason,
|
|
8975
|
+
...content ? { message: content } : {}
|
|
8976
|
+
}
|
|
8977
|
+
});
|
|
8978
|
+
var ensureProviderShellIssue = (issue, providerShell, content) => {
|
|
8979
|
+
if (!issue || issue.reasonCode === "env_limited" && !issue.constraint) {
|
|
8980
|
+
return toExplicitProviderShellIssue(providerShell, content);
|
|
8981
|
+
}
|
|
8982
|
+
return issue;
|
|
8983
|
+
};
|
|
8984
|
+
var toShoppingPageIssueMessage = (reasonCode, url) => {
|
|
8985
|
+
if (reasonCode === "token_required") return `Authentication required for ${url}`;
|
|
8986
|
+
if (reasonCode === "env_limited") return `Browser assistance required for ${url}`;
|
|
8987
|
+
return `Detected anti-bot challenge while retrieving ${url}`;
|
|
8988
|
+
};
|
|
8989
|
+
var throwShoppingPageIssue = (args) => {
|
|
8990
|
+
const reasonCode = args.pageIssue.reasonCode;
|
|
8991
|
+
throw new ProviderRuntimeError(
|
|
8992
|
+
providerErrorCodeFromReasonCode(reasonCode),
|
|
8993
|
+
toShoppingPageIssueMessage(reasonCode, args.fetched.url),
|
|
8994
|
+
{
|
|
8995
|
+
provider: args.providerId,
|
|
8996
|
+
source: SHOPPING_SOURCE,
|
|
8997
|
+
retryable: reasonCode === "env_limited",
|
|
8998
|
+
reasonCode,
|
|
8999
|
+
details: {
|
|
9000
|
+
...applyProviderIssueHint({
|
|
9001
|
+
status: args.fetched.status,
|
|
9002
|
+
url: args.fetched.url,
|
|
9003
|
+
...typeof args.extracted.metadata.title === "string" ? { title: args.extracted.metadata.title } : {},
|
|
9004
|
+
...args.content ? { message: args.content } : {},
|
|
9005
|
+
...args.providerShell?.reason ? { providerShell: args.providerShell.reason } : {}
|
|
9006
|
+
}, args.pageIssue),
|
|
9007
|
+
...args.providerShell?.reason ? { browserRequired: true } : {},
|
|
9008
|
+
...browserFallbackObservationDetails(args.fetched.browserFallback)
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
);
|
|
9012
|
+
};
|
|
8660
9013
|
var unwrapTrackingUrl = (url, profile) => {
|
|
8661
9014
|
const normalizedUrl = decodeHrefValue(url);
|
|
8662
9015
|
try {
|
|
@@ -9054,6 +9407,7 @@ var createDefaultSearch = (profile, providerId, fetcher) => async (input, contex
|
|
|
9054
9407
|
context
|
|
9055
9408
|
});
|
|
9056
9409
|
const extracted = extractStructuredContent(fetched.html, fetched.url);
|
|
9410
|
+
const providerShell = requiresBrowserAssistance(profile, fetched.url, fetched.html);
|
|
9057
9411
|
const limit = Math.max(1, Math.min(input.limit ?? 10, 20));
|
|
9058
9412
|
const links = dedupeLinks(
|
|
9059
9413
|
extracted.links.filter((link) => isLikelyProductUrl(canonicalizeUrl(link), profile)),
|
|
@@ -9061,7 +9415,17 @@ var createDefaultSearch = (profile, providerId, fetcher) => async (input, contex
|
|
|
9061
9415
|
);
|
|
9062
9416
|
const content = toSnippet(extracted.text, 2e3);
|
|
9063
9417
|
const candidates = extractSearchCandidates(fetched.html, fetched.url, profile, limit);
|
|
9064
|
-
const pageIssue = candidates.length === 0 ? classifySearchPageIssue(profile, fetched, extracted, content) : null;
|
|
9418
|
+
const pageIssue = providerShell ? classifySearchPageIssue(profile, fetched, extracted, content, providerShell) : candidates.length === 0 ? classifySearchPageIssue(profile, fetched, extracted, content, providerShell) : null;
|
|
9419
|
+
if (providerShell) {
|
|
9420
|
+
throwShoppingPageIssue({
|
|
9421
|
+
providerId,
|
|
9422
|
+
fetched,
|
|
9423
|
+
extracted,
|
|
9424
|
+
content,
|
|
9425
|
+
pageIssue: ensureProviderShellIssue(pageIssue, providerShell, content),
|
|
9426
|
+
providerShell
|
|
9427
|
+
});
|
|
9428
|
+
}
|
|
9065
9429
|
if (candidates.length > 0) {
|
|
9066
9430
|
return candidates.map((candidate, index) => ({
|
|
9067
9431
|
url: candidate.url,
|
|
@@ -9096,28 +9460,7 @@ var createDefaultSearch = (profile, providerId, fetcher) => async (input, contex
|
|
|
9096
9460
|
}));
|
|
9097
9461
|
}
|
|
9098
9462
|
if (pageIssue && (pageIssue.reasonCode !== "env_limited" || pageIssue.constraint)) {
|
|
9099
|
-
|
|
9100
|
-
const providerShell = requiresBrowserAssistance(profile, fetched.url, fetched.html);
|
|
9101
|
-
throw new ProviderRuntimeError(
|
|
9102
|
-
providerErrorCodeFromReasonCode(reasonCode),
|
|
9103
|
-
reasonCode === "token_required" ? `Authentication required for ${fetched.url}` : `Detected anti-bot challenge while retrieving ${fetched.url}`,
|
|
9104
|
-
{
|
|
9105
|
-
provider: providerId,
|
|
9106
|
-
source: SHOPPING_SOURCE,
|
|
9107
|
-
retryable: reasonCode === "env_limited",
|
|
9108
|
-
reasonCode,
|
|
9109
|
-
details: {
|
|
9110
|
-
...applyProviderIssueHint({
|
|
9111
|
-
status: fetched.status,
|
|
9112
|
-
url: fetched.url,
|
|
9113
|
-
...typeof extracted.metadata.title === "string" ? { title: extracted.metadata.title } : {},
|
|
9114
|
-
...content ? { message: content } : {},
|
|
9115
|
-
...providerShell?.reason ? { providerShell: providerShell.reason } : {}
|
|
9116
|
-
}, pageIssue),
|
|
9117
|
-
...browserFallbackObservationDetails(fetched.browserFallback)
|
|
9118
|
-
}
|
|
9119
|
-
}
|
|
9120
|
-
);
|
|
9463
|
+
throwShoppingPageIssue({ providerId, fetched, extracted, content, pageIssue, providerShell });
|
|
9121
9464
|
}
|
|
9122
9465
|
const rows = [
|
|
9123
9466
|
{
|
|
@@ -9828,7 +10171,7 @@ var enrichResearchRecords = (records, timebox, now = /* @__PURE__ */ new Date())
|
|
|
9828
10171
|
return records.map((record) => toResearchRecord(record, timebox, now));
|
|
9829
10172
|
};
|
|
9830
10173
|
|
|
9831
|
-
// src/
|
|
10174
|
+
// src/inspiredesign/contract.ts
|
|
9832
10175
|
import { createHash as createHash3 } from "crypto";
|
|
9833
10176
|
|
|
9834
10177
|
// skills/opendevbrowser-design-agent/assets/templates/canvas-generation-plan.design.v1.json
|
|
@@ -10023,7 +10366,13 @@ var design_contract_v1_default = {
|
|
|
10023
10366
|
"section reveal",
|
|
10024
10367
|
"primary CTA feedback"
|
|
10025
10368
|
],
|
|
10026
|
-
parallaxPolicy: "off unless explicitly justified"
|
|
10369
|
+
parallaxPolicy: "off unless explicitly justified",
|
|
10370
|
+
advancedMotionAdvisory: [
|
|
10371
|
+
"Advisory shader-like gradient depth: describe intent only; implement with approved runtime primitives unless a separate runtime change authorizes more.",
|
|
10372
|
+
"Advisory WebGL-style spatial reveal: document depth and hierarchy without implying WebGL runtime support.",
|
|
10373
|
+
"Advisory Spline-style product orbit: document scene posture and static fallback without approving custom 3D runtime dependencies.",
|
|
10374
|
+
"Runtime boundary: libraryPolicy.motion and libraryPolicy.threeD stay empty unless separately approved."
|
|
10375
|
+
]
|
|
10027
10376
|
},
|
|
10028
10377
|
performanceModel: {
|
|
10029
10378
|
renderHotspots: [
|
|
@@ -10116,6 +10465,14 @@ var design_contract_v1_default = {
|
|
|
10116
10465
|
"spinner-stacking",
|
|
10117
10466
|
"scan-surface-jank"
|
|
10118
10467
|
]
|
|
10468
|
+
},
|
|
10469
|
+
designVectors: {
|
|
10470
|
+
advancedMotionAdvisory: [
|
|
10471
|
+
"Advisory shader-like gradient depth",
|
|
10472
|
+
"Advisory WebGL-style spatial reveal",
|
|
10473
|
+
"Advisory Spline-style product orbit",
|
|
10474
|
+
"Runtime support: none. Library policy authorization: none."
|
|
10475
|
+
]
|
|
10119
10476
|
}
|
|
10120
10477
|
}
|
|
10121
10478
|
};
|
|
@@ -10155,10 +10512,176 @@ var INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS = [
|
|
|
10155
10512
|
formatSkillReference(INSPIREDESIGN_HANDOFF_SKILLS.designAgent)
|
|
10156
10513
|
];
|
|
10157
10514
|
var INSPIREDESIGN_HANDOFF_GUIDANCE = {
|
|
10158
|
-
reviewAdvancedBrief: `${INSPIREDESIGN_HANDOFF_FILES.advancedBrief} is the authoritative
|
|
10515
|
+
reviewAdvancedBrief: `${INSPIREDESIGN_HANDOFF_FILES.advancedBrief} is the authoritative reference-first brief. When URL references exist, captured evidence leads the creative direction; selected format, profile defaults, layout posture, motion grammar, and anti-patterns are route guardrails only. Read it before touching Canvas or implementation files.`,
|
|
10159
10516
|
prepareCanvasPlanRequest: `Fill canvasSessionId, leaseId, and documentId in ${INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest} before running ${INSPIREDESIGN_HANDOFF_COMMANDS.continueInCanvas}.`,
|
|
10160
10517
|
deepCaptureRecommendation: "Any inspiredesign run with reference URLs already uses captureMode=deep. Rerun with the same URLs only when you need refreshed DOM/layout evidence, restored session state, or capture-specific debugging."
|
|
10161
10518
|
};
|
|
10519
|
+
var INSPIREDESIGN_ARTIFACT_GUIDE = {
|
|
10520
|
+
[INSPIREDESIGN_HANDOFF_FILES.advancedBrief]: {
|
|
10521
|
+
purpose: "Authoritative reference-first brief for the downstream design agent.",
|
|
10522
|
+
expectedContents: ["Selected prompt format", "reference pattern board", "route guardrails"],
|
|
10523
|
+
howToUse: ["Read first", "treat captured evidence as creative priority", "use guardrails to avoid route drift"],
|
|
10524
|
+
mustNot: ["Do not treat defaults as stronger than captured references"]
|
|
10525
|
+
},
|
|
10526
|
+
[INSPIREDESIGN_HANDOFF_FILES.designMarkdown]: {
|
|
10527
|
+
purpose: "Human-readable design specification and implementation narrative.",
|
|
10528
|
+
expectedContents: ["inspiration analysis", "unified direction", "governance summary", "deliverables"],
|
|
10529
|
+
howToUse: ["Use as the readable project brief", "cross-check implementation choices against its sections"],
|
|
10530
|
+
mustNot: ["Do not use prose as a substitute for the JSON contract when patching Canvas"]
|
|
10531
|
+
},
|
|
10532
|
+
[INSPIREDESIGN_HANDOFF_FILES.designContract]: {
|
|
10533
|
+
purpose: "Narrowed Canvas governance contract for design decisions.",
|
|
10534
|
+
expectedContents: ["emitted governance blocks", "motion system", "library policy", "runtime budgets"],
|
|
10535
|
+
howToUse: ["Patch only emitted governance blocks", "compare implementation against this contract before shipping"],
|
|
10536
|
+
mustNot: ["Do not add navigation, async, or performance context as Canvas governance patches"]
|
|
10537
|
+
},
|
|
10538
|
+
[INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest]: {
|
|
10539
|
+
purpose: "Ready-to-fill request payload for `canvas.plan.set`.",
|
|
10540
|
+
expectedContents: ["request ids", "Canvas session ids", "mutation-safe generationPlan"],
|
|
10541
|
+
howToUse: ["Fill canvasSessionId, leaseId, and documentId", "submit with the provided canvas.plan.set command"],
|
|
10542
|
+
mustNot: ["Do not add handoff-only fields or reference-only analysis to generationPlan"]
|
|
10543
|
+
},
|
|
10544
|
+
[INSPIREDESIGN_HANDOFF_FILES.designAgentHandoff]: {
|
|
10545
|
+
purpose: "Downstream index for artifact usage, skills, commands, and omitted implementation context.",
|
|
10546
|
+
expectedContents: ["skills", "commands", "contract scope", "implementation context", "artifact and section guides"],
|
|
10547
|
+
howToUse: ["Use as the navigation map for the bundle", "load recommended skills before implementation"],
|
|
10548
|
+
mustNot: ["Do not treat handoff context as runtime Canvas schema"]
|
|
10549
|
+
},
|
|
10550
|
+
[INSPIREDESIGN_HANDOFF_FILES.generationPlan]: {
|
|
10551
|
+
purpose: "Full generated plan for reasoning about design intent.",
|
|
10552
|
+
expectedContents: ["Canvas plan fields", "design vectors", "reference analysis when available"],
|
|
10553
|
+
howToUse: ["Use for agent reasoning and audit traceability", "compare with canvas-plan.request.json for runtime subset"],
|
|
10554
|
+
mustNot: ["Do not submit this file directly to Canvas when it contains non-request context"]
|
|
10555
|
+
},
|
|
10556
|
+
[INSPIREDESIGN_HANDOFF_FILES.implementationPlanMarkdown]: {
|
|
10557
|
+
purpose: "Human-readable engineering sequence for the first implementation pass.",
|
|
10558
|
+
expectedContents: ["build sequence", "component plan", "token strategy", "QA and risk checks"],
|
|
10559
|
+
howToUse: ["Convert sections into implementation tasks", "keep tests and browser validation aligned to the plan"],
|
|
10560
|
+
mustNot: ["Do not implement sections unsupported by brief or reference evidence"]
|
|
10561
|
+
},
|
|
10562
|
+
[INSPIREDESIGN_HANDOFF_FILES.implementationPlan]: {
|
|
10563
|
+
purpose: "Machine-readable implementation plan matching the Markdown plan.",
|
|
10564
|
+
expectedContents: ["architecture steps", "component inventory", "state and validation tasks"],
|
|
10565
|
+
howToUse: ["Use for structured task extraction", "keep it synchronized with implementation-plan.md"],
|
|
10566
|
+
mustNot: ["Do not treat it as a Canvas document patch payload"]
|
|
10567
|
+
},
|
|
10568
|
+
[INSPIREDESIGN_HANDOFF_FILES.evidence]: {
|
|
10569
|
+
purpose: "Evidence digest for brief, reference, capture, and design-vector provenance.",
|
|
10570
|
+
expectedContents: ["brief expansion", "reference outcomes", "capture attempts", "design vectors"],
|
|
10571
|
+
howToUse: ["Audit why choices were made", "prefer evidence over generic template defaults"],
|
|
10572
|
+
mustNot: ["Do not ignore failed or skipped capture statuses when judging confidence"]
|
|
10573
|
+
},
|
|
10574
|
+
[INSPIREDESIGN_HANDOFF_FILES.prototypeGuidance]: {
|
|
10575
|
+
purpose: "Optional first prototype guidance when the workflow requests prototype output.",
|
|
10576
|
+
expectedContents: ["prototype structure", "design-vector guidance", "browser proof checklist"],
|
|
10577
|
+
howToUse: ["Use only for the first prototype pass", "promote proven ideas back into contract-aligned work"],
|
|
10578
|
+
mustNot: ["Do not treat prototype guidance as final implementation authority"]
|
|
10579
|
+
}
|
|
10580
|
+
};
|
|
10581
|
+
var INSPIREDESIGN_CONTRACT_SECTION_GUIDE = {
|
|
10582
|
+
intent: {
|
|
10583
|
+
purpose: "Define why the design exists and what success means.",
|
|
10584
|
+
expectedContents: ["audience", "task", "success criteria", "trust posture"],
|
|
10585
|
+
howToUse: ["Validate the primary user job before styling", "reject sections that do not serve the task"],
|
|
10586
|
+
mustNot: ["Do not start visual polish before the audience and task are clear"]
|
|
10587
|
+
},
|
|
10588
|
+
generationPlan: {
|
|
10589
|
+
purpose: "Mutation-safe subset accepted by Canvas planning.",
|
|
10590
|
+
expectedContents: ["target outcome", "visual, layout, content, component, motion, responsive, accessibility posture"],
|
|
10591
|
+
howToUse: ["Submit only through canvas-plan.request.json", "repair generationPlanIssues before mutation"],
|
|
10592
|
+
mustNot: ["Do not add handoff-only guide fields to the Canvas generation plan"]
|
|
10593
|
+
},
|
|
10594
|
+
designLanguage: {
|
|
10595
|
+
purpose: "Name the coherent visual direction and token ownership.",
|
|
10596
|
+
expectedContents: ["direction", "style axes", "semantic token source", "approved libraries"],
|
|
10597
|
+
howToUse: ["Keep one design language per task", "align repeated components to semantic tokens"],
|
|
10598
|
+
mustNot: ["Do not mix unrelated visual families inside one surface"]
|
|
10599
|
+
},
|
|
10600
|
+
contentModel: {
|
|
10601
|
+
purpose: "Define real content, message hierarchy, and UI states.",
|
|
10602
|
+
expectedContents: ["primary message", "supporting messages", "states", "loading, empty, and error behavior"],
|
|
10603
|
+
howToUse: ["Use real content first", "plan non-happy-path states before polish"],
|
|
10604
|
+
mustNot: ["Do not ship placeholder copy as product content"]
|
|
10605
|
+
},
|
|
10606
|
+
layoutSystem: {
|
|
10607
|
+
purpose: "Describe page architecture and section rhythm.",
|
|
10608
|
+
expectedContents: ["grid", "containers", "spacing rhythm", "alignment rules"],
|
|
10609
|
+
howToUse: ["Use to place sections and scan units consistently", "verify desktop and mobile structure"],
|
|
10610
|
+
mustNot: ["Do not invent one-off layout rules for repeated sections"]
|
|
10611
|
+
},
|
|
10612
|
+
typographySystem: {
|
|
10613
|
+
purpose: "Define type families, scale, measure, and loading behavior.",
|
|
10614
|
+
expectedContents: ["families", "scale", "measure", "fallback policy", "loading strategy"],
|
|
10615
|
+
howToUse: ["Apply type hierarchy consistently", "avoid layout shift from font loading"],
|
|
10616
|
+
mustNot: ["Do not default to unapproved system stacks for a distinctive design"]
|
|
10617
|
+
},
|
|
10618
|
+
colorSystem: {
|
|
10619
|
+
purpose: "Define semantic color roles and theme behavior.",
|
|
10620
|
+
expectedContents: ["primary roles", "surface roles", "text roles", "state colors"],
|
|
10621
|
+
howToUse: ["Map repeated UI to semantic tokens", "validate contrast in every required theme"],
|
|
10622
|
+
mustNot: ["Do not scatter raw color values across leaf components"]
|
|
10623
|
+
},
|
|
10624
|
+
surfaceSystem: {
|
|
10625
|
+
purpose: "Define material, depth, borders, and background behavior.",
|
|
10626
|
+
expectedContents: ["surface hierarchy", "border rules", "shadow rules", "material effects"],
|
|
10627
|
+
howToUse: ["Use depth only to clarify hierarchy", "align material effects with design vectors"],
|
|
10628
|
+
mustNot: ["Do not turn every content group into a card by default"]
|
|
10629
|
+
},
|
|
10630
|
+
iconSystem: {
|
|
10631
|
+
purpose: "Define icon usage and decorative asset boundaries.",
|
|
10632
|
+
expectedContents: ["icon family", "stroke policy", "labeling rules", "decorative rules"],
|
|
10633
|
+
howToUse: ["Use icons to clarify actions", "keep accessible names on icon-only controls"],
|
|
10634
|
+
mustNot: ["Do not rely on icons as the only explanation for critical actions"]
|
|
10635
|
+
},
|
|
10636
|
+
motionSystem: {
|
|
10637
|
+
purpose: "Define motion that supports comprehension.",
|
|
10638
|
+
expectedContents: ["timing", "interaction moments", "reduced-motion posture", "advanced motion advisory"],
|
|
10639
|
+
howToUse: ["Keep shader, WebGL, and Spline cues advisory", "provide reduced-motion replacements"],
|
|
10640
|
+
mustNot: ["Do not use motion cues to authorize new runtime libraries"]
|
|
10641
|
+
},
|
|
10642
|
+
responsiveSystem: {
|
|
10643
|
+
purpose: "Define authored behavior across desktop, tablet, and mobile.",
|
|
10644
|
+
expectedContents: ["breakpoints", "adaptation rules", "touch policy", "overflow policy"],
|
|
10645
|
+
howToUse: ["Validate the primary action at every viewport", "collapse structure before copy becomes cramped"],
|
|
10646
|
+
mustNot: ["Do not assume desktop layouts naturally scale down"]
|
|
10647
|
+
},
|
|
10648
|
+
accessibilityPolicy: {
|
|
10649
|
+
purpose: "Set accessibility requirements before implementation.",
|
|
10650
|
+
expectedContents: ["WCAG target", "keyboard requirements", "focus policy", "semantic requirements"],
|
|
10651
|
+
howToUse: ["Block release on contrast or keyboard regressions", "validate focus on every interactive state"],
|
|
10652
|
+
mustNot: ["Do not defer accessibility until after visual implementation"]
|
|
10653
|
+
},
|
|
10654
|
+
libraryPolicy: {
|
|
10655
|
+
purpose: "Declare approved implementation libraries and runtime boundaries.",
|
|
10656
|
+
expectedContents: ["components", "icons", "styling", "motion", "threeD"],
|
|
10657
|
+
howToUse: ["Use as the dependency authorization boundary", "keep motion and threeD empty unless separately approved"],
|
|
10658
|
+
mustNot: ["Do not infer WebGL, shader, Spline, or 3D runtime support from advisory motion"]
|
|
10659
|
+
},
|
|
10660
|
+
runtimeBudgets: {
|
|
10661
|
+
purpose: "Set practical limits for sections, actions, interaction latency, and preview cost.",
|
|
10662
|
+
expectedContents: ["section budgets", "action budgets", "latency budgets", "preview notes"],
|
|
10663
|
+
howToUse: ["Use as a constraint during implementation", "validate slow or animation-heavy surfaces against it"],
|
|
10664
|
+
mustNot: ["Do not add decorative weight that violates the budget"]
|
|
10665
|
+
},
|
|
10666
|
+
navigationModel: {
|
|
10667
|
+
purpose: "Implementation-only context for route, tab, overlay, and deep-link ownership.",
|
|
10668
|
+
expectedContents: ["route owner", "deep-link policy", "invalid route fallback", "overlay entry points"],
|
|
10669
|
+
howToUse: ["Use from design-agent-handoff.json when wiring implementation state"],
|
|
10670
|
+
mustNot: ["Do not patch this omitted block into Canvas governance"]
|
|
10671
|
+
},
|
|
10672
|
+
asyncModel: {
|
|
10673
|
+
purpose: "Implementation-only context for loading, restart, cancellation, and URL-owned query state.",
|
|
10674
|
+
expectedContents: ["owner", "load trigger", "restart triggers", "cancellation policy"],
|
|
10675
|
+
howToUse: ["Use when wiring fetch/search state and stale-request handling"],
|
|
10676
|
+
mustNot: ["Do not let components invent independent async ownership"]
|
|
10677
|
+
},
|
|
10678
|
+
performanceModel: {
|
|
10679
|
+
purpose: "Implementation-only context for render hotspots and measurement posture.",
|
|
10680
|
+
expectedContents: ["render hotspots", "stable identity policy", "list strategy", "measurement plan"],
|
|
10681
|
+
howToUse: ["Use before building scan-heavy or motion-heavy surfaces"],
|
|
10682
|
+
mustNot: ["Do not ship heavy interaction surfaces without measurement evidence"]
|
|
10683
|
+
}
|
|
10684
|
+
};
|
|
10162
10685
|
var buildInspiredesignFollowthroughSummary = () => `Read ${INSPIREDESIGN_HANDOFF_FILES.advancedBrief} first, then continue in OpenDevBrowser Canvas with ${INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest} and ${INSPIREDESIGN_HANDOFF_FILES.designAgentHandoff}, load ${INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS[0]} plus ${INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS[1]} before implementation, and note that any supplied reference URL already uses captureMode=deep.`;
|
|
10163
10686
|
var buildInspiredesignNextStep = () => `Read ${INSPIREDESIGN_HANDOFF_FILES.advancedBrief} first. ${INSPIREDESIGN_HANDOFF_GUIDANCE.prepareCanvasPlanRequest} Then run ${INSPIREDESIGN_HANDOFF_COMMANDS.continueInCanvas}, confirm planStatus=accepted, then patch only the governance blocks listed in ${INSPIREDESIGN_HANDOFF_FILES.designAgentHandoff}.`;
|
|
10164
10687
|
|
|
@@ -10169,11 +10692,14 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10169
10692
|
commonRules: [
|
|
10170
10693
|
"Preserve only the product, brand, audience, platform, and tone cues that are explicitly present in the source brief.",
|
|
10171
10694
|
"Treat missing details as open constraints instead of inventing brand facts or user needs.",
|
|
10172
|
-
"Use inspiration references to extract transferable design logic rather than copying a single layout, visual treatment, or narrative beat literally."
|
|
10695
|
+
"Use inspiration references to extract transferable design logic rather than copying a single layout, visual treatment, or narrative beat literally.",
|
|
10696
|
+
"Treat shader, WebGL, Spline-style, and 3D motion ideas as advisory design cues only, not as runtime support or dependency approval.",
|
|
10697
|
+
"Carry accepted advanced motion cues in designVectors and motionSystem as intent, and keep libraryPolicy authorization separate."
|
|
10173
10698
|
],
|
|
10174
10699
|
outputRequirements: [
|
|
10175
10700
|
"Return a reusable design contract that can drive design.md, implementation-plan artifacts, and a Canvas-ready prototype path.",
|
|
10176
|
-
"Keep the direction premium, specific, and implementable instead of generic or template-driven."
|
|
10701
|
+
"Keep the direction premium, specific, and implementable instead of generic or template-driven.",
|
|
10702
|
+
"Keep libraryPolicy.motion and libraryPolicy.threeD empty in generated samples unless a separate runtime change explicitly approves those libraries."
|
|
10177
10703
|
],
|
|
10178
10704
|
formats: [
|
|
10179
10705
|
{
|
|
@@ -10182,12 +10708,15 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10182
10708
|
bestFor: [
|
|
10183
10709
|
"product homepages",
|
|
10184
10710
|
"docs homepages",
|
|
10711
|
+
"consulting service homepages",
|
|
10185
10712
|
"launch pages",
|
|
10186
10713
|
"rebrands"
|
|
10187
10714
|
],
|
|
10188
10715
|
businessFocus: [
|
|
10189
10716
|
"premium SaaS marketing",
|
|
10190
10717
|
"product launches",
|
|
10718
|
+
"AI consulting services",
|
|
10719
|
+
"enterprise advisory landing pages",
|
|
10191
10720
|
"docs-first brands",
|
|
10192
10721
|
"brand refresh surfaces"
|
|
10193
10722
|
],
|
|
@@ -10199,6 +10728,11 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10199
10728
|
"editorial",
|
|
10200
10729
|
"hero",
|
|
10201
10730
|
"marketing",
|
|
10731
|
+
"consulting",
|
|
10732
|
+
"advisory",
|
|
10733
|
+
"enterprise AI",
|
|
10734
|
+
"services",
|
|
10735
|
+
"case studies",
|
|
10202
10736
|
"docs"
|
|
10203
10737
|
],
|
|
10204
10738
|
matchSignals: {
|
|
@@ -10212,6 +10746,16 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10212
10746
|
"editorial",
|
|
10213
10747
|
"hero",
|
|
10214
10748
|
"marketing",
|
|
10749
|
+
"consulting",
|
|
10750
|
+
"advisory",
|
|
10751
|
+
"ai consulting",
|
|
10752
|
+
"enterprise ai",
|
|
10753
|
+
"business services",
|
|
10754
|
+
"client services",
|
|
10755
|
+
"case studies",
|
|
10756
|
+
"transformation",
|
|
10757
|
+
"services",
|
|
10758
|
+
"cta",
|
|
10215
10759
|
"docs"
|
|
10216
10760
|
],
|
|
10217
10761
|
excluded: [
|
|
@@ -10219,7 +10763,7 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10219
10763
|
"admin",
|
|
10220
10764
|
"onboarding"
|
|
10221
10765
|
],
|
|
10222
|
-
tieBreaker:
|
|
10766
|
+
tieBreaker: 2
|
|
10223
10767
|
},
|
|
10224
10768
|
lead: "Study the inspiration references and synthesize a premium editorial landing page system that translates the source brief into a reusable, brand-specific direction.",
|
|
10225
10769
|
archetype: "editorial brand campaign",
|
|
@@ -10638,17 +11182,22 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10638
11182
|
label: "Maison campaign world",
|
|
10639
11183
|
bestFor: [
|
|
10640
11184
|
"luxury fashion",
|
|
11185
|
+
"fashion design studios",
|
|
10641
11186
|
"fragrance launches",
|
|
10642
11187
|
"jewelry campaigns",
|
|
10643
11188
|
"premium hospitality brands"
|
|
10644
11189
|
],
|
|
10645
11190
|
businessFocus: [
|
|
10646
11191
|
"fashion maisons",
|
|
11192
|
+
"fashion design studios",
|
|
10647
11193
|
"luxury accessories",
|
|
10648
11194
|
"fragrance campaigns",
|
|
10649
11195
|
"high-end hospitality identity"
|
|
10650
11196
|
],
|
|
10651
11197
|
keywords: [
|
|
11198
|
+
"fashion",
|
|
11199
|
+
"fashion design",
|
|
11200
|
+
"fashion studio",
|
|
10652
11201
|
"maison",
|
|
10653
11202
|
"atelier",
|
|
10654
11203
|
"collection",
|
|
@@ -10660,6 +11209,9 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10660
11209
|
],
|
|
10661
11210
|
matchSignals: {
|
|
10662
11211
|
positive: [
|
|
11212
|
+
"fashion",
|
|
11213
|
+
"fashion design",
|
|
11214
|
+
"fashion studio",
|
|
10663
11215
|
"maison",
|
|
10664
11216
|
"atelier",
|
|
10665
11217
|
"collection",
|
|
@@ -10904,7 +11456,7 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10904
11456
|
},
|
|
10905
11457
|
{
|
|
10906
11458
|
id: "luminous-research-atlas",
|
|
10907
|
-
label: "Luminous
|
|
11459
|
+
label: "Luminous insight landing page",
|
|
10908
11460
|
bestFor: [
|
|
10909
11461
|
"AI labs",
|
|
10910
11462
|
"think tanks",
|
|
@@ -10914,15 +11466,14 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10914
11466
|
businessFocus: [
|
|
10915
11467
|
"research organizations",
|
|
10916
11468
|
"evidence-led storytelling",
|
|
10917
|
-
"
|
|
10918
|
-
"
|
|
11469
|
+
"insight-led public landing pages",
|
|
11470
|
+
"visual research narratives"
|
|
10919
11471
|
],
|
|
10920
11472
|
keywords: [
|
|
10921
11473
|
"atlas",
|
|
10922
11474
|
"observatory",
|
|
10923
|
-
"
|
|
11475
|
+
"insight",
|
|
10924
11476
|
"evidence",
|
|
10925
|
-
"report",
|
|
10926
11477
|
"research",
|
|
10927
11478
|
"index",
|
|
10928
11479
|
"publication"
|
|
@@ -10931,9 +11482,8 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10931
11482
|
positive: [
|
|
10932
11483
|
"atlas",
|
|
10933
11484
|
"observatory",
|
|
10934
|
-
"
|
|
11485
|
+
"insight",
|
|
10935
11486
|
"evidence",
|
|
10936
|
-
"report",
|
|
10937
11487
|
"research",
|
|
10938
11488
|
"map",
|
|
10939
11489
|
"model",
|
|
@@ -10943,37 +11493,43 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10943
11493
|
excluded: [
|
|
10944
11494
|
"checkout",
|
|
10945
11495
|
"festival",
|
|
10946
|
-
"villa"
|
|
11496
|
+
"villa",
|
|
11497
|
+
"consulting",
|
|
11498
|
+
"advisory",
|
|
11499
|
+
"bcg",
|
|
11500
|
+
"services",
|
|
11501
|
+
"landing page",
|
|
11502
|
+
"homepage"
|
|
10947
11503
|
],
|
|
10948
|
-
tieBreaker:
|
|
11504
|
+
tieBreaker: 1
|
|
10949
11505
|
},
|
|
10950
|
-
lead: "Study the inspiration references and synthesize a luminous
|
|
10951
|
-
archetype: "
|
|
10952
|
-
layoutArchetype: "
|
|
11506
|
+
lead: "Study the inspiration references and synthesize a luminous insight landing page that turns research-backed ideas into a premium, text-light public story.",
|
|
11507
|
+
archetype: "luminous insight landing page",
|
|
11508
|
+
layoutArchetype: "full-bleed insight story with visual proof bands",
|
|
10953
11509
|
typographySystem: "precise sans for data and narrative paired with restrained serif emphasis",
|
|
10954
|
-
surfaceTreatment: "ivory research planes, layered evidence visuals, and
|
|
10955
|
-
shapeLanguage: "clean modules,
|
|
10956
|
-
componentGrammar: "
|
|
10957
|
-
motionGrammar: "
|
|
11510
|
+
surfaceTreatment: "ivory research planes, layered evidence visuals, and generous image-led whitespace",
|
|
11511
|
+
shapeLanguage: "clean modules, visual proof frames, and quiet emphasis bands",
|
|
11512
|
+
componentGrammar: "hero composition, insight proof bands, visual story panels, outcome moments, restrained CTA groups",
|
|
11513
|
+
motionGrammar: "calm reveal transitions, proof-panel emphasis, and restrained visual depth",
|
|
10958
11514
|
paletteIntent: "bright ivory base with measured accent coding for evidence groups",
|
|
10959
11515
|
visualDensity: "balanced",
|
|
10960
11516
|
designVariance: "structured expressiveness",
|
|
10961
11517
|
focusAreas: [
|
|
10962
11518
|
"evidence hierarchy",
|
|
10963
|
-
"
|
|
10964
|
-
"
|
|
10965
|
-
"chart
|
|
10966
|
-
"
|
|
11519
|
+
"insight framing",
|
|
11520
|
+
"visual proof bands",
|
|
11521
|
+
"chart restraint",
|
|
11522
|
+
"public story cadence",
|
|
10967
11523
|
"scroll-story beats",
|
|
10968
11524
|
"proof sequencing"
|
|
10969
11525
|
],
|
|
10970
11526
|
responsiveCollapseRules: [
|
|
10971
|
-
"Collapse
|
|
10972
|
-
"Keep
|
|
11527
|
+
"Collapse visual proof bands into a single readable story stack before reducing chart legibility.",
|
|
11528
|
+
"Keep evidence labels visually close to the relevant section without turning mobile into an appendix."
|
|
10973
11529
|
],
|
|
10974
11530
|
guardrails: [
|
|
10975
|
-
"Keep the surface bright, exact, and evidence-
|
|
10976
|
-
"Use motion
|
|
11531
|
+
"Keep the surface bright, exact, and evidence-led without becoming a documentation hub.",
|
|
11532
|
+
"Use motion to clarify priority, proof, and action rather than to explain long-form methodology."
|
|
10977
11533
|
],
|
|
10978
11534
|
antiPatterns: [
|
|
10979
11535
|
"No cyber glow.",
|
|
@@ -10982,14 +11538,14 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
10982
11538
|
"No unexplained iconography."
|
|
10983
11539
|
],
|
|
10984
11540
|
deliverables: [
|
|
10985
|
-
"Define the evidence hierarchy,
|
|
10986
|
-
"Return a premium
|
|
11541
|
+
"Define the evidence hierarchy, visual proof rhythm, insight story cadence, and conversion path.",
|
|
11542
|
+
"Return a premium insight landing contract detailed enough for a visually led Canvas-ready implementation."
|
|
10987
11543
|
],
|
|
10988
11544
|
route: {
|
|
10989
|
-
profile: "
|
|
11545
|
+
profile: "product-story",
|
|
10990
11546
|
themeStrategy: "single-theme",
|
|
10991
|
-
navigationModel: "
|
|
10992
|
-
layoutApproach: "
|
|
11547
|
+
navigationModel: "global-header",
|
|
11548
|
+
layoutApproach: "insight-led-landing-page"
|
|
10993
11549
|
}
|
|
10994
11550
|
},
|
|
10995
11551
|
{
|
|
@@ -11304,7 +11860,13 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
11304
11860
|
excluded: [
|
|
11305
11861
|
"villa",
|
|
11306
11862
|
"festival",
|
|
11307
|
-
"fragrance"
|
|
11863
|
+
"fragrance",
|
|
11864
|
+
"fashion",
|
|
11865
|
+
"fashion design",
|
|
11866
|
+
"maison",
|
|
11867
|
+
"couture",
|
|
11868
|
+
"collection",
|
|
11869
|
+
"campaign"
|
|
11308
11870
|
],
|
|
11309
11871
|
tieBreaker: 3
|
|
11310
11872
|
},
|
|
@@ -11537,6 +12099,8 @@ var inspiredesign_advanced_brief_v1_default = {
|
|
|
11537
12099
|
// src/inspiredesign/brief-expansion.ts
|
|
11538
12100
|
var BRIEF_TEMPLATE = inspiredesign_advanced_brief_v1_default;
|
|
11539
12101
|
var INSPIREDESIGN_BRIEF_TEMPLATE_VERSION = BRIEF_TEMPLATE.version;
|
|
12102
|
+
var INSPIREDESIGN_BRIEF_COMMON_RULES = [...BRIEF_TEMPLATE.commonRules];
|
|
12103
|
+
var INSPIREDESIGN_BRIEF_OUTPUT_REQUIREMENTS = [...BRIEF_TEMPLATE.outputRequirements];
|
|
11540
12104
|
var normalizeInspiredesignBriefText = (value) => value.trim().replace(/\s+/g, " ");
|
|
11541
12105
|
var formatBulletList = (items) => items.map((item) => `- ${item}`).join("\n");
|
|
11542
12106
|
var countMatches = (brief, keywords) => {
|
|
@@ -11546,6 +12110,20 @@ var countMatches = (brief, keywords) => {
|
|
|
11546
12110
|
0
|
|
11547
12111
|
);
|
|
11548
12112
|
};
|
|
12113
|
+
var escapeRegExp2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12114
|
+
var removeNegativeSignal = (brief, keyword) => {
|
|
12115
|
+
const escaped = escapeRegExp2(keyword.toLowerCase());
|
|
12116
|
+
const modifiers = "(?:[a-z0-9-]+\\s+){0,3}";
|
|
12117
|
+
return brief.replace(new RegExp(`\\b(?:not|no|without|avoid|exclude|excluding)\\s+(?:an?\\s+|the\\s+)?${modifiers}${escaped}\\b(?:\\s+[a-z0-9-]+){0,2}`, "g"), " ").replace(new RegExp(`\\b${escaped}\\s+(?:is\\s+)?(?:not|excluded|forbidden)\\b`, "g"), " ");
|
|
12118
|
+
};
|
|
12119
|
+
var positiveSignalText = (brief, formats) => {
|
|
12120
|
+
const keywords = formats.flatMap((format) => [
|
|
12121
|
+
...format.matchSignals.positive,
|
|
12122
|
+
...format.matchSignals.required ?? [],
|
|
12123
|
+
...format.matchSignals.excluded ?? []
|
|
12124
|
+
]);
|
|
12125
|
+
return [...new Set(keywords)].reduce(removeNegativeSignal, brief.toLowerCase());
|
|
12126
|
+
};
|
|
11549
12127
|
var cloneStringList = (items) => [...items];
|
|
11550
12128
|
var cloneRoute = (route) => ({
|
|
11551
12129
|
profile: route.profile,
|
|
@@ -11569,6 +12147,7 @@ var cloneInspiredesignBriefFormat = (format) => ({
|
|
|
11569
12147
|
paletteIntent: format.paletteIntent,
|
|
11570
12148
|
visualDensity: format.visualDensity,
|
|
11571
12149
|
designVariance: format.designVariance,
|
|
12150
|
+
focusAreas: cloneStringList(format.focusAreas ?? []),
|
|
11572
12151
|
responsiveCollapseRules: cloneStringList(format.responsiveCollapseRules),
|
|
11573
12152
|
guardrails: cloneStringList(format.guardrails),
|
|
11574
12153
|
antiPatterns: cloneStringList(format.antiPatterns),
|
|
@@ -11591,6 +12170,7 @@ var summarizeFormat = (format) => ({
|
|
|
11591
12170
|
paletteIntent: format.paletteIntent,
|
|
11592
12171
|
visualDensity: format.visualDensity,
|
|
11593
12172
|
designVariance: format.designVariance,
|
|
12173
|
+
focusAreas: cloneStringList(format.focusAreas),
|
|
11594
12174
|
responsiveCollapseRules: cloneStringList(format.responsiveCollapseRules),
|
|
11595
12175
|
guardrails: cloneStringList(format.guardrails),
|
|
11596
12176
|
antiPatterns: cloneStringList(format.antiPatterns),
|
|
@@ -11611,12 +12191,13 @@ var findFormatById = (formatId) => {
|
|
|
11611
12191
|
return BRIEF_TEMPLATE.formats.find((format) => format.id === formatId);
|
|
11612
12192
|
};
|
|
11613
12193
|
var scoreFormat = (sourceBrief, format) => {
|
|
11614
|
-
const
|
|
12194
|
+
const brief = positiveSignalText(sourceBrief, BRIEF_TEMPLATE.formats);
|
|
12195
|
+
const requiredMatches = countMatches(brief, format.matchSignals.required ?? []);
|
|
11615
12196
|
if ((format.matchSignals.required?.length ?? 0) > 0 && requiredMatches === 0) {
|
|
11616
12197
|
return Number.NEGATIVE_INFINITY;
|
|
11617
12198
|
}
|
|
11618
|
-
const excludedMatches = countMatches(
|
|
11619
|
-
const positiveMatches = countMatches(
|
|
12199
|
+
const excludedMatches = countMatches(brief, format.matchSignals.excluded ?? []);
|
|
12200
|
+
const positiveMatches = countMatches(brief, format.matchSignals.positive);
|
|
11620
12201
|
return positiveMatches * 4 + requiredMatches * 6 - excludedMatches * 8 + (format.matchSignals.tieBreaker ?? 0);
|
|
11621
12202
|
};
|
|
11622
12203
|
var chooseFormat = (sourceBrief) => {
|
|
@@ -11706,10 +12287,390 @@ var expandInspiredesignBrief = (brief, preferredFormatId) => {
|
|
|
11706
12287
|
};
|
|
11707
12288
|
};
|
|
11708
12289
|
|
|
11709
|
-
// src/
|
|
11710
|
-
var
|
|
11711
|
-
var
|
|
11712
|
-
var
|
|
12290
|
+
// src/inspiredesign/reference-pattern-board.ts
|
|
12291
|
+
var SIGNAL_LIMIT = 5;
|
|
12292
|
+
var SIGNAL_CLIP = 180;
|
|
12293
|
+
var PATTERN_LIMIT = 6;
|
|
12294
|
+
var ADVANCED_MOTION_FIELDS = [
|
|
12295
|
+
"Advisory shader-style gradients: specify effect type, uniforms, static fallback, and reduced-motion replacement as design language only.",
|
|
12296
|
+
"Advisory WebGL-style depth cues: describe layered depth, camera-like parallax, and spatial hierarchy without requiring WebGL runtime.",
|
|
12297
|
+
"Advisory Spline-style staging: describe object-like hero composition, scene count, camera posture, depth model, asset source, and spatial sequencing as implementation guidance only.",
|
|
12298
|
+
"Advanced motion performance policy: define frame budget, lazy loading, offscreen pause behavior, and vestibular risk before implementation.",
|
|
12299
|
+
"Runtime boundary: implement with approved CSS and Canvas-safe primitives unless explicit source-owned runtime support is added later."
|
|
12300
|
+
];
|
|
12301
|
+
var trimText = (value) => value.trim().replace(/\s+/g, " ");
|
|
12302
|
+
var clipText = (value, maxLength) => {
|
|
12303
|
+
if (value.length <= maxLength) return value;
|
|
12304
|
+
return `${value.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
|
|
12305
|
+
};
|
|
12306
|
+
var textFromHtml = (html) => {
|
|
12307
|
+
return html ? trimText(html.replace(/<[^>]+>/g, " ")) : void 0;
|
|
12308
|
+
};
|
|
12309
|
+
var stripActionRefs = (value) => value.replace(/\[r\d+\]\s+(?:link|button|combobox|textbox|option)\s+/gi, "").replace(/\[r\d+\]\s+/gi, "").replace(/\bvalue=/gi, "");
|
|
12310
|
+
var isCodeOrCssPreview = (value) => {
|
|
12311
|
+
const lower = value.toLowerCase();
|
|
12312
|
+
return lower.includes("dangerouslysetinnerhtml") || lower.includes("opendevbrowser-root") || lower.includes("align-content:") || lower.startsWith("import ") || /^[.#][a-z0-9_-]+\s*\{/.test(lower) || lower.includes("{") && /[a-z-]+:\s*[^;]+;/.test(lower);
|
|
12313
|
+
};
|
|
12314
|
+
var cleanEvidenceText = (value) => {
|
|
12315
|
+
return trimText(stripActionRefs(value).replace(/[{};]/g, " "));
|
|
12316
|
+
};
|
|
12317
|
+
var DIAGNOSTIC_TEXT_MARKERS = [
|
|
12318
|
+
"authentication required",
|
|
12319
|
+
"sign in",
|
|
12320
|
+
"login required",
|
|
12321
|
+
"challenge page",
|
|
12322
|
+
"access denied",
|
|
12323
|
+
"browser capture unavailable",
|
|
12324
|
+
"javascript required",
|
|
12325
|
+
"javascript is required",
|
|
12326
|
+
"captcha",
|
|
12327
|
+
"verification challenge",
|
|
12328
|
+
"enable cookies",
|
|
12329
|
+
"checking if the site connection is secure",
|
|
12330
|
+
"complete the verification",
|
|
12331
|
+
"blocked reference"
|
|
12332
|
+
];
|
|
12333
|
+
var PUBLIC_LANDING_TEXT_MARKERS = [
|
|
12334
|
+
"church",
|
|
12335
|
+
"landing page",
|
|
12336
|
+
"homepage",
|
|
12337
|
+
"home page",
|
|
12338
|
+
"consulting",
|
|
12339
|
+
"advisory",
|
|
12340
|
+
"bcg",
|
|
12341
|
+
"ai consulting",
|
|
12342
|
+
"enterprise ai",
|
|
12343
|
+
"transformation",
|
|
12344
|
+
"client services",
|
|
12345
|
+
"business services",
|
|
12346
|
+
"case studies",
|
|
12347
|
+
"clients",
|
|
12348
|
+
"industries",
|
|
12349
|
+
"worship",
|
|
12350
|
+
"locations",
|
|
12351
|
+
"gallery",
|
|
12352
|
+
"atelier",
|
|
12353
|
+
"fashion"
|
|
12354
|
+
];
|
|
12355
|
+
var PUBLIC_LANDING_SUPPORT_MARKERS = [
|
|
12356
|
+
"online",
|
|
12357
|
+
"events",
|
|
12358
|
+
"studio",
|
|
12359
|
+
"website",
|
|
12360
|
+
"full-bleed",
|
|
12361
|
+
"hero",
|
|
12362
|
+
"story",
|
|
12363
|
+
"stories",
|
|
12364
|
+
"services",
|
|
12365
|
+
"service",
|
|
12366
|
+
"cta"
|
|
12367
|
+
];
|
|
12368
|
+
var isDiagnosticText = (value) => {
|
|
12369
|
+
const lower = value.toLowerCase();
|
|
12370
|
+
return DIAGNOSTIC_TEXT_MARKERS.some((marker) => lower.includes(marker));
|
|
12371
|
+
};
|
|
12372
|
+
var hasPublicLandingSignal = (value) => {
|
|
12373
|
+
const lower = value.toLowerCase();
|
|
12374
|
+
const strongCount = PUBLIC_LANDING_TEXT_MARKERS.filter((marker) => lower.includes(marker)).length;
|
|
12375
|
+
const supportCount = PUBLIC_LANDING_SUPPORT_MARKERS.filter((marker) => lower.includes(marker)).length;
|
|
12376
|
+
const visualLandingCombo = lower.includes("hero") && (lower.includes("full-bleed") || lower.includes("cta") || lower.includes("website"));
|
|
12377
|
+
return visualLandingCombo || strongCount >= 2 || strongCount >= 1 && strongCount + supportCount >= 2;
|
|
12378
|
+
};
|
|
12379
|
+
var pushSignal = (signals, value) => {
|
|
12380
|
+
if (!value || isCodeOrCssPreview(value)) return;
|
|
12381
|
+
const text = cleanEvidenceText(value);
|
|
12382
|
+
if (isCodeOrCssPreview(text) || isDiagnosticText(text)) return;
|
|
12383
|
+
if (text.length > 0 && !signals.includes(text)) {
|
|
12384
|
+
signals.push(text);
|
|
12385
|
+
}
|
|
12386
|
+
};
|
|
12387
|
+
var getInspiredesignReferenceSignals = (reference) => {
|
|
12388
|
+
const signals = [];
|
|
12389
|
+
pushSignal(signals, reference.title);
|
|
12390
|
+
pushSignal(signals, reference.excerpt);
|
|
12391
|
+
pushSignal(signals, reference.capture?.title);
|
|
12392
|
+
pushSignal(signals, reference.capture?.snapshot?.content);
|
|
12393
|
+
pushSignal(signals, textFromHtml(reference.capture?.clone?.componentPreview));
|
|
12394
|
+
pushSignal(signals, reference.capture?.clone?.cssPreview);
|
|
12395
|
+
pushSignal(signals, textFromHtml(reference.capture?.dom?.outerHTML));
|
|
12396
|
+
return signals.map((signal) => clipText(signal, SIGNAL_CLIP)).slice(0, SIGNAL_LIMIT);
|
|
12397
|
+
};
|
|
12398
|
+
var hasCleanSignal = (value) => {
|
|
12399
|
+
if (!value || isCodeOrCssPreview(value)) return false;
|
|
12400
|
+
const text = cleanEvidenceText(value);
|
|
12401
|
+
return text.length > 0 && !isCodeOrCssPreview(text) && !isDiagnosticText(text);
|
|
12402
|
+
};
|
|
12403
|
+
var hasUsableCloneCreativeEvidence = (reference) => hasCleanSignal(reference.capture?.clone?.componentPreview);
|
|
12404
|
+
var hasUsableCaptureEvidence = (reference) => hasCleanSignal(reference.capture?.snapshot?.content) || hasUsableCloneCreativeEvidence(reference) || hasCleanSignal(textFromHtml(reference.capture?.dom?.outerHTML));
|
|
12405
|
+
var hasInspiredesignUsableReferenceEvidence = (reference) => {
|
|
12406
|
+
if (reference.captureStatus === "captured" && hasUsableCaptureEvidence(reference)) return true;
|
|
12407
|
+
return reference.fetchStatus === "captured" && (hasCleanSignal(reference.title) || hasCleanSignal(reference.excerpt));
|
|
12408
|
+
};
|
|
12409
|
+
var firstSignal = (reference) => {
|
|
12410
|
+
const preferred = [
|
|
12411
|
+
reference.capture?.title,
|
|
12412
|
+
reference.capture?.snapshot?.content,
|
|
12413
|
+
textFromHtml(reference.capture?.clone?.componentPreview),
|
|
12414
|
+
textFromHtml(reference.capture?.dom?.outerHTML),
|
|
12415
|
+
reference.excerpt,
|
|
12416
|
+
reference.title
|
|
12417
|
+
].map((value) => value ? cleanEvidenceText(value) : "").find((value) => value.length > 0 && !isCodeOrCssPreview(value) && !isDiagnosticText(value));
|
|
12418
|
+
return preferred ? clipText(preferred, SIGNAL_CLIP) : reference.url;
|
|
12419
|
+
};
|
|
12420
|
+
var REFERENCE_PATTERN_RULES = [
|
|
12421
|
+
{
|
|
12422
|
+
summary: "location-first church discovery with regional pathways",
|
|
12423
|
+
matches: ["find a church", "church locations", "location", "city or postcode", "current location"]
|
|
12424
|
+
},
|
|
12425
|
+
{
|
|
12426
|
+
summary: "worship and music content as atmosphere and ministry proof",
|
|
12427
|
+
matches: ["music", "worship", "united", "young & free", "chapel", "instrumentals"]
|
|
12428
|
+
},
|
|
12429
|
+
{
|
|
12430
|
+
summary: "global region navigation with online participation path",
|
|
12431
|
+
matches: ["asia pacific", "europe", "north america", "latin america", "africa", "middle east", "online"]
|
|
12432
|
+
},
|
|
12433
|
+
{
|
|
12434
|
+
summary: "story-led editorial pathway after the primary church action",
|
|
12435
|
+
matches: ["stories", "blog", "start reading", "newsroom"]
|
|
12436
|
+
},
|
|
12437
|
+
{
|
|
12438
|
+
summary: "ministry ecosystem pathways for college, conferences, and events",
|
|
12439
|
+
matches: ["college", "conference", "tours", "events"]
|
|
12440
|
+
},
|
|
12441
|
+
{
|
|
12442
|
+
summary: "multilingual/global audience affordance",
|
|
12443
|
+
matches: ["language", '"en"', '"fr"', '"es"', '"pt"', '"de"']
|
|
12444
|
+
},
|
|
12445
|
+
{
|
|
12446
|
+
summary: "full-bleed hero with restrained CTA rail",
|
|
12447
|
+
matches: ["full-bleed", "hero", "cta rail", "primary cta"]
|
|
12448
|
+
},
|
|
12449
|
+
{
|
|
12450
|
+
summary: "premium consulting public landing page with service narrative, client proof, and conversion CTAs",
|
|
12451
|
+
matches: ["consulting", "advisory", "bcg", "enterprise ai", "transformation", "client services", "case studies", "industries"]
|
|
12452
|
+
}
|
|
12453
|
+
];
|
|
12454
|
+
var ruleMatches = (text, rule) => {
|
|
12455
|
+
const lower = text.toLowerCase();
|
|
12456
|
+
return rule.matches.some((match) => lower.includes(match));
|
|
12457
|
+
};
|
|
12458
|
+
var derivePatternSummaries = (signals, fallback) => {
|
|
12459
|
+
const text = signals.join(" ");
|
|
12460
|
+
const matches = REFERENCE_PATTERN_RULES.filter((rule) => ruleMatches(text, rule)).map((rule) => rule.summary);
|
|
12461
|
+
return matches.length > 0 ? matches.slice(0, PATTERN_LIMIT) : [fallback];
|
|
12462
|
+
};
|
|
12463
|
+
var appendSourceDetail = (patterns, primarySignal) => {
|
|
12464
|
+
if (patterns.some((pattern) => primarySignal.toLowerCase().includes(pattern.toLowerCase()))) {
|
|
12465
|
+
return patterns;
|
|
12466
|
+
}
|
|
12467
|
+
return [...patterns, `source detail: ${primarySignal}`].slice(0, PATTERN_LIMIT);
|
|
12468
|
+
};
|
|
12469
|
+
var deriveCapturedVia = (reference) => {
|
|
12470
|
+
const methods = [];
|
|
12471
|
+
if (reference.fetchStatus === "captured") methods.push("fetch");
|
|
12472
|
+
if (reference.capture?.snapshot?.content.trim()) methods.push("snapshot");
|
|
12473
|
+
if (hasUsableCloneCreativeEvidence(reference)) {
|
|
12474
|
+
methods.push("clone");
|
|
12475
|
+
}
|
|
12476
|
+
if (reference.capture?.dom?.outerHTML.trim()) methods.push("dom");
|
|
12477
|
+
return methods;
|
|
12478
|
+
};
|
|
12479
|
+
var deriveComponentFamilies = (format, patterns, isPublicLanding) => {
|
|
12480
|
+
const base = isPublicLanding ? "hero composition, proof bands, narrative pathways, service or story sections, conversion CTA, and footer" : format.componentGrammar;
|
|
12481
|
+
return [base, ...patterns.slice(0, 3)];
|
|
12482
|
+
};
|
|
12483
|
+
var hasReferencePublicLandingEvidence = (reference) => {
|
|
12484
|
+
const text = [
|
|
12485
|
+
reference.surfaceType,
|
|
12486
|
+
reference.layoutRecipe,
|
|
12487
|
+
...reference.contentHierarchy,
|
|
12488
|
+
...reference.patternsToBorrow
|
|
12489
|
+
].join(" ");
|
|
12490
|
+
return hasPublicLandingSignal(text);
|
|
12491
|
+
};
|
|
12492
|
+
var hasBoardPublicLandingEvidence = (board) => board.references.some(hasReferencePublicLandingEvidence);
|
|
12493
|
+
var boardEvidenceText = (board) => board.references.map((reference) => [
|
|
12494
|
+
reference.layoutRecipe,
|
|
12495
|
+
...reference.contentHierarchy,
|
|
12496
|
+
...reference.componentFamilies,
|
|
12497
|
+
...reference.motionPosture,
|
|
12498
|
+
...reference.patternsToBorrow
|
|
12499
|
+
].join(" ")).join(" ").toLowerCase();
|
|
12500
|
+
var hasEvidenceCue = (text, matches) => matches.some((match) => text.includes(match));
|
|
12501
|
+
var deriveReferenceEntry = (reference, format) => {
|
|
12502
|
+
const signals = getInspiredesignReferenceSignals(reference);
|
|
12503
|
+
const primarySignal = firstSignal(reference);
|
|
12504
|
+
const patterns = appendSourceDetail(derivePatternSummaries(signals, primarySignal), primarySignal);
|
|
12505
|
+
const isPublicLanding = signals.some(hasPublicLandingSignal);
|
|
12506
|
+
return {
|
|
12507
|
+
id: reference.id,
|
|
12508
|
+
name: reference.title ?? reference.url,
|
|
12509
|
+
url: reference.url,
|
|
12510
|
+
surfaceType: isPublicLanding ? "public landing page" : format.archetype,
|
|
12511
|
+
capturedVia: deriveCapturedVia(reference),
|
|
12512
|
+
layoutRecipe: patterns.join("; "),
|
|
12513
|
+
contentHierarchy: patterns.slice(0, 4),
|
|
12514
|
+
componentFamilies: deriveComponentFamilies(format, patterns, isPublicLanding),
|
|
12515
|
+
motionPosture: [format.motionGrammar, "Plan hero reveal, scroll reveal, CTA feedback, and reduced-motion behavior."],
|
|
12516
|
+
tokenNotes: [format.paletteIntent, format.typographySystem, format.surfaceTreatment],
|
|
12517
|
+
patternsToBorrow: [...patterns, ...signals.slice(0, 2)].slice(0, PATTERN_LIMIT),
|
|
12518
|
+
patternsToReject: [...format.antiPatterns],
|
|
12519
|
+
whyItWorks: reference.captureStatus === "captured" ? "Captured reference evidence provides reusable hierarchy, rhythm, and component cues." : "Available reference text provides directional content and hierarchy cues."
|
|
12520
|
+
};
|
|
12521
|
+
};
|
|
12522
|
+
var buildInspiredesignReferencePatternBoard = (briefId, format, references) => {
|
|
12523
|
+
const entries = references.filter(hasInspiredesignUsableReferenceEvidence).map((reference) => deriveReferenceEntry(reference, format));
|
|
12524
|
+
const sharedStrengths = entries.flatMap((entry) => entry.patternsToBorrow).slice(0, 6);
|
|
12525
|
+
const targetSurface = entries.some((entry) => entry.surfaceType === "public landing page") ? "reference-led public landing page" : format.layoutArchetype;
|
|
12526
|
+
return {
|
|
12527
|
+
briefId,
|
|
12528
|
+
targetSurface,
|
|
12529
|
+
references: entries,
|
|
12530
|
+
synthesis: {
|
|
12531
|
+
dominantDirection: entries[0]?.layoutRecipe ?? format.archetype,
|
|
12532
|
+
sharedStrengths,
|
|
12533
|
+
sharedFailuresToAvoid: [...format.antiPatterns],
|
|
12534
|
+
contractDeltas: [
|
|
12535
|
+
"Selected prompt format supplies route defaults and guardrails, not the creative source of truth.",
|
|
12536
|
+
"Use captured reference hierarchy before generic profile defaults when URL evidence exists."
|
|
12537
|
+
]
|
|
12538
|
+
}
|
|
12539
|
+
};
|
|
12540
|
+
};
|
|
12541
|
+
var buildInteractionDensity = (format, board) => {
|
|
12542
|
+
if (hasBoardPublicLandingEvidence(board)) {
|
|
12543
|
+
return "low-to-medium; prioritize confident public-page CTAs over app-shell controls.";
|
|
12544
|
+
}
|
|
12545
|
+
if (format.route.navigationModel === "sidebar") {
|
|
12546
|
+
return "medium-to-high; prioritize command surfaces, state clarity, and durable workspace controls.";
|
|
12547
|
+
}
|
|
12548
|
+
if (format.route.profile === "documentation") {
|
|
12549
|
+
return "low-to-medium; prioritize visual overview, proof scanning, and a small number of clear action paths.";
|
|
12550
|
+
}
|
|
12551
|
+
if (format.route.profile === "auth-focused") {
|
|
12552
|
+
return "low; prioritize one confident first action with clear feedback and trust cues.";
|
|
12553
|
+
}
|
|
12554
|
+
return "low-to-medium; prioritize confident public-page CTAs over app-shell controls.";
|
|
12555
|
+
};
|
|
12556
|
+
var buildImageryPosture = (format, board) => {
|
|
12557
|
+
if (hasBoardPublicLandingEvidence(board)) {
|
|
12558
|
+
return [format.surfaceTreatment, "Use dominant atmospheric imagery as the visual anchor."];
|
|
12559
|
+
}
|
|
12560
|
+
if (format.route.navigationModel === "sidebar") {
|
|
12561
|
+
return [format.surfaceTreatment, "Use product state, data hierarchy, and workspace continuity as the visual anchor."];
|
|
12562
|
+
}
|
|
12563
|
+
return [format.surfaceTreatment, "Use dominant atmospheric imagery as the visual anchor."];
|
|
12564
|
+
};
|
|
12565
|
+
var buildInteractionMoments = (format, board) => {
|
|
12566
|
+
const evidenceText = boardEvidenceText(board);
|
|
12567
|
+
const publicLanding = hasBoardPublicLandingEvidence(board);
|
|
12568
|
+
const referenceBacked = board.references.length > 0;
|
|
12569
|
+
const cursorScope = publicLanding ? "hero CTA, media reveals, and primary navigation moments" : "high-value actions and selected command surfaces";
|
|
12570
|
+
const moments = [
|
|
12571
|
+
"Microinteractions: define hover effects, visible focus rings, pressed states, loading states, and confirmation feedback for every primary action.",
|
|
12572
|
+
`Animation choreography: sequence ${format.motionGrammar}, hover feedback, active feedback, and page transitions through one timing system.`
|
|
12573
|
+
];
|
|
12574
|
+
const cursorBacked = hasEvidenceCue(evidenceText, ["cursor", "magnetic", "follow-cursor", "pointer"]);
|
|
12575
|
+
const cursorPolicy = cursorBacked ? `Cursor effects: reference evidence supports premium pointer affordances for ${cursorScope}; keep default cursor behavior for reading surfaces.` : `Cursor effects policy: consider magnetic or follow-cursor affordances only when reference evidence supports ${cursorScope}.`;
|
|
12576
|
+
return referenceBacked ? [...moments, cursorPolicy] : moments;
|
|
12577
|
+
};
|
|
12578
|
+
var buildMaterialEffects = (board) => {
|
|
12579
|
+
if (board.references.length === 0) {
|
|
12580
|
+
return [
|
|
12581
|
+
"Material effects: define elevation, shadows, surface contrast, and reduced-motion-safe depth from the brief.",
|
|
12582
|
+
"Reduced-motion material fallback: preserve hierarchy and CTA clarity without transform-based depth."
|
|
12583
|
+
];
|
|
12584
|
+
}
|
|
12585
|
+
const evidenceText = boardEvidenceText(board);
|
|
12586
|
+
const publicLanding = hasBoardPublicLandingEvidence(board);
|
|
12587
|
+
const glassScope = publicLanding ? "navigation overlays, hero scrims, and atmospheric CTA surfaces" : "focused overlays, inspectors, or state containers";
|
|
12588
|
+
const parallaxBacked = hasEvidenceCue(evidenceText, ["parallax", "depth", "layered", "immersive", "full-bleed"]);
|
|
12589
|
+
const glassBacked = hasEvidenceCue(evidenceText, ["glass", "frosted", "blur", "translucent", "scrim", "overlay"]);
|
|
12590
|
+
const parallax = parallaxBacked ? "Depth language: reference evidence supports restrained parallax, layered shadows, and atmospheric depth where it reinforces hierarchy." : "Depth language policy: use parallax only when reference evidence supports layered depth; otherwise use spacing, scale, and shadow hierarchy.";
|
|
12591
|
+
const glass = glassBacked ? `Glassmorphism/translucency: reference evidence supports frosted or translucent surfaces for ${glassScope}; never use glass as generic decoration.` : `Glassmorphism/translucency policy: use frosted or translucent surfaces only when reference evidence supports ${glassScope}.`;
|
|
12592
|
+
return [
|
|
12593
|
+
parallax,
|
|
12594
|
+
glass,
|
|
12595
|
+
"Reduced-motion material fallback: remove parallax and cursor-follow transforms while preserving hierarchy, depth, and CTA clarity."
|
|
12596
|
+
];
|
|
12597
|
+
};
|
|
12598
|
+
var buildSectionArchitecture = (format, board) => {
|
|
12599
|
+
if (hasBoardPublicLandingEvidence(board)) {
|
|
12600
|
+
return [
|
|
12601
|
+
"Use 8 to 12 primary landing-page sections unless the user explicitly asks for a microsite.",
|
|
12602
|
+
"Build a clear sequence from hero, proof, story, service pathways, impact, conversion CTA, and footer."
|
|
12603
|
+
];
|
|
12604
|
+
}
|
|
12605
|
+
if (format.route.profile === "documentation") {
|
|
12606
|
+
return [
|
|
12607
|
+
"Use a text-light overview sequence for purpose, proof, examples, action paths, and footer.",
|
|
12608
|
+
"Keep long-form reference depth, citation modules, annotation rails, and methodology blocks out of the primary visual route."
|
|
12609
|
+
];
|
|
12610
|
+
}
|
|
12611
|
+
if (format.route.profile === "auth-focused") {
|
|
12612
|
+
return [
|
|
12613
|
+
"Use a screen sequence for value, trust, input, confirmation, and first-action transition.",
|
|
12614
|
+
"Keep the flow compact instead of expanding into marketing section sprawl."
|
|
12615
|
+
];
|
|
12616
|
+
}
|
|
12617
|
+
if (format.route.navigationModel === "immersive") {
|
|
12618
|
+
return [
|
|
12619
|
+
"Use cinematic scene beats for hero, product reveal, proof, detail, and decisive CTA.",
|
|
12620
|
+
"Keep each scroll beat focused on one visual idea."
|
|
12621
|
+
];
|
|
12622
|
+
}
|
|
12623
|
+
if (format.route.navigationModel === "sidebar") {
|
|
12624
|
+
return [
|
|
12625
|
+
"Use workspace shell zones for navigation, command surfaces, primary work area, detail panels, and state feedback.",
|
|
12626
|
+
"Prioritize task continuity over marketing-section cadence."
|
|
12627
|
+
];
|
|
12628
|
+
}
|
|
12629
|
+
return [
|
|
12630
|
+
"Use 8 to 12 primary landing-page sections unless the user explicitly asks for a microsite.",
|
|
12631
|
+
"Build a clear sequence from hero, proof, story, service pathways, impact, conversion CTA, and footer."
|
|
12632
|
+
];
|
|
12633
|
+
};
|
|
12634
|
+
var buildInspiredesignDesignVectors = (format, board) => {
|
|
12635
|
+
const influence = board.synthesis.sharedStrengths.length > 0 ? board.synthesis.sharedStrengths : [format.archetype];
|
|
12636
|
+
const publicLandingEvidence = hasBoardPublicLandingEvidence(board);
|
|
12637
|
+
const surfaceIntent = publicLandingEvidence ? "reference-led public landing page" : format.archetype;
|
|
12638
|
+
const compositionModel = publicLandingEvidence ? ["full-bleed hero with narrative section cadence", ...board.references.map((entry) => entry.layoutRecipe)] : [format.layoutArchetype, ...board.references.map((entry) => entry.layoutRecipe)];
|
|
12639
|
+
return {
|
|
12640
|
+
sourcePriority: board.references.length > 0 ? "reference-evidence-first" : "brief-only",
|
|
12641
|
+
directionLabel: board.synthesis.dominantDirection,
|
|
12642
|
+
surfaceIntent,
|
|
12643
|
+
compositionModel: compositionModel.slice(0, 5),
|
|
12644
|
+
premiumPosture: [
|
|
12645
|
+
"premium visual hierarchy, refined spacing, and editorial image treatment.",
|
|
12646
|
+
"Premium typography, spacing, visual hierarchy, palette, and image treatment must lead the page.",
|
|
12647
|
+
format.surfaceTreatment,
|
|
12648
|
+
format.paletteIntent
|
|
12649
|
+
],
|
|
12650
|
+
motionPosture: [
|
|
12651
|
+
"Use a hero entrance reveal, section scroll reveal, and CTA/focus feedback.",
|
|
12652
|
+
"Respect reduced-motion preference with static hierarchy preserved.",
|
|
12653
|
+
format.motionGrammar
|
|
12654
|
+
],
|
|
12655
|
+
sectionArchitecture: buildSectionArchitecture(format, board),
|
|
12656
|
+
typographyPosture: [format.typographySystem],
|
|
12657
|
+
imageryPosture: buildImageryPosture(format, board),
|
|
12658
|
+
interactionDensity: buildInteractionDensity(format, board),
|
|
12659
|
+
interactionMoments: buildInteractionMoments(format, board),
|
|
12660
|
+
materialEffects: buildMaterialEffects(board),
|
|
12661
|
+
advancedMotionAdvisory: [...ADVANCED_MOTION_FIELDS],
|
|
12662
|
+
referenceInfluence: influence,
|
|
12663
|
+
patternsToBorrow: board.references.flatMap((entry) => entry.patternsToBorrow).slice(0, 8),
|
|
12664
|
+
patternsToReject: board.references.flatMap((entry) => entry.patternsToReject).slice(0, 8),
|
|
12665
|
+
guardrails: [...format.guardrails],
|
|
12666
|
+
antiPatterns: [...format.antiPatterns]
|
|
12667
|
+
};
|
|
12668
|
+
};
|
|
12669
|
+
|
|
12670
|
+
// src/inspiredesign/contract.ts
|
|
12671
|
+
var INSPIREDESIGN_CAPTURE_ATTEMPT_KEYS = ["snapshot", "clone", "dom"];
|
|
12672
|
+
var MALFORMED_CAPTURE_ATTEMPT_DETAIL = "Capture attempt metadata missing or malformed.";
|
|
12673
|
+
var NORMALIZED_CAPTURE_ATTEMPT_DETAIL = "Captured artifact was empty after normalization.";
|
|
11713
12674
|
var isJsonRecord2 = (value) => {
|
|
11714
12675
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11715
12676
|
};
|
|
@@ -12012,15 +12973,15 @@ var PROFILE_CONFIG = {
|
|
|
12012
12973
|
}
|
|
12013
12974
|
},
|
|
12014
12975
|
"documentation": {
|
|
12015
|
-
direction: "
|
|
12016
|
-
visualPersonality: "legible, calm,
|
|
12017
|
-
brandTone: "expert and accessible",
|
|
12018
|
-
hierarchyPrinciples: ["Make scanning effortless.", "
|
|
12019
|
-
interactionPhilosophy: "Light motion,
|
|
12976
|
+
direction: "text-light knowledge story",
|
|
12977
|
+
visualPersonality: "legible, calm, visually led",
|
|
12978
|
+
brandTone: "expert, concise, and accessible",
|
|
12979
|
+
hierarchyPrinciples: ["Make scanning effortless.", "Use visual proof before long explanatory text."],
|
|
12980
|
+
interactionPhilosophy: "Light motion, clear wayfinding, strong anchor visibility.",
|
|
12020
12981
|
navigationModel: "sidebar",
|
|
12021
|
-
layoutApproach: "
|
|
12022
|
-
pagePatterns: ["
|
|
12023
|
-
componentSequence: ["
|
|
12982
|
+
layoutApproach: "knowledge-story-shell",
|
|
12983
|
+
pagePatterns: ["Insight overview", "Visual proof band", "Action path"],
|
|
12984
|
+
componentSequence: ["Navigation", "Search", "Anchored headings", "Proof bands", "Callouts"],
|
|
12024
12985
|
colors: {
|
|
12025
12986
|
primary: "#1D4ED8",
|
|
12026
12987
|
accent: "#0F766E",
|
|
@@ -12036,37 +12997,425 @@ var PROFILE_CONFIG = {
|
|
|
12036
12997
|
}
|
|
12037
12998
|
}
|
|
12038
12999
|
};
|
|
12039
|
-
var
|
|
13000
|
+
var trimText2 = (value) => {
|
|
12040
13001
|
return value.trim().replace(/\s+/g, " ");
|
|
12041
13002
|
};
|
|
12042
|
-
var
|
|
13003
|
+
var clipText2 = (value, maxLength) => {
|
|
12043
13004
|
if (value.length <= maxLength) return value;
|
|
12044
13005
|
return `${value.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
|
|
12045
13006
|
};
|
|
13007
|
+
var REFERENCE_SUMMARY_CLIP_LENGTH = 220;
|
|
13008
|
+
var GENERATION_PLAN_REFERENCE_CLIP_LENGTH = 600;
|
|
13009
|
+
var buildReferenceSynthesis = (references) => {
|
|
13010
|
+
const lines = references.filter(hasInspiredesignUsableReferenceEvidence).map((reference, index) => {
|
|
13011
|
+
const signals = getInspiredesignReferenceSignals(reference);
|
|
13012
|
+
if (signals.length === 0) return "";
|
|
13013
|
+
return `Source ${index + 1} ${reference.title ?? reference.url}: ${signals.join(" | ")}`;
|
|
13014
|
+
}).filter((line) => line.length > 0);
|
|
13015
|
+
return {
|
|
13016
|
+
lines,
|
|
13017
|
+
summary: lines.length > 0 ? lines.map((line) => clipText2(line, REFERENCE_SUMMARY_CLIP_LENGTH)).join(" ") : "No live reference cues were captured."
|
|
13018
|
+
};
|
|
13019
|
+
};
|
|
13020
|
+
var renderReferenceFirstAdvancedBrief = (briefExpansion, board, vectors, references) => {
|
|
13021
|
+
if (board.references.length === 0) {
|
|
13022
|
+
if (references.length > 0) {
|
|
13023
|
+
return [
|
|
13024
|
+
"Reference evidence unavailable:",
|
|
13025
|
+
"URL references were attempted, but no usable creative evidence was captured. Treat this as a capture gap, not a design direction.",
|
|
13026
|
+
"",
|
|
13027
|
+
formatBulletList2(references.map((reference) => renderUnavailableReference(reference))),
|
|
13028
|
+
"",
|
|
13029
|
+
briefExpansion.advancedBrief
|
|
13030
|
+
].join("\n");
|
|
13031
|
+
}
|
|
13032
|
+
return briefExpansion.advancedBrief;
|
|
13033
|
+
}
|
|
13034
|
+
return [
|
|
13035
|
+
"Reference pattern board:",
|
|
13036
|
+
"URL reference evidence is the creative source of truth when references are supplied.",
|
|
13037
|
+
"",
|
|
13038
|
+
"Reference evidence analysis:",
|
|
13039
|
+
formatBulletList2(board.references.map((reference) => `${reference.name}: ${reference.layoutRecipe}`)),
|
|
13040
|
+
"",
|
|
13041
|
+
"Design vectors:",
|
|
13042
|
+
formatBulletList2([
|
|
13043
|
+
`directionLabel: ${vectors.directionLabel}`,
|
|
13044
|
+
`surfaceIntent: ${vectors.surfaceIntent}`,
|
|
13045
|
+
`premiumPosture: ${vectors.premiumPosture.join(" ")}`,
|
|
13046
|
+
`motionPosture: ${vectors.motionPosture.join(" ")}`,
|
|
13047
|
+
`sectionArchitecture: ${vectors.sectionArchitecture.join(" ")}`,
|
|
13048
|
+
`interactionMoments: ${vectors.interactionMoments.join(" ")}`,
|
|
13049
|
+
`materialEffects: ${vectors.materialEffects.join(" ")}`,
|
|
13050
|
+
`advancedMotionAdvisory: ${vectors.advancedMotionAdvisory.join(" ")}`
|
|
13051
|
+
]),
|
|
13052
|
+
"",
|
|
13053
|
+
"Fixed format guardrails:",
|
|
13054
|
+
"Selected prompt format supplies route defaults and guardrails, not the creative source of truth.",
|
|
13055
|
+
"",
|
|
13056
|
+
briefExpansion.advancedBrief
|
|
13057
|
+
].join("\n");
|
|
13058
|
+
};
|
|
13059
|
+
var renderEvidenceDerivedAdvancedBrief = (briefExpansion, format) => [
|
|
13060
|
+
`Selected prompt format: ${format.label}`,
|
|
13061
|
+
"",
|
|
13062
|
+
"Source brief:",
|
|
13063
|
+
briefExpansion.sourceBrief,
|
|
13064
|
+
"",
|
|
13065
|
+
"Prompt objective:",
|
|
13066
|
+
`Use the reference evidence and source brief to define a ${format.archetype}.`,
|
|
13067
|
+
"",
|
|
13068
|
+
"Business focus:",
|
|
13069
|
+
formatBulletList2(format.businessFocus),
|
|
13070
|
+
"",
|
|
13071
|
+
"Keywords:",
|
|
13072
|
+
formatBulletList2(format.keywords),
|
|
13073
|
+
"",
|
|
13074
|
+
"Route defaults:",
|
|
13075
|
+
formatBulletList2([
|
|
13076
|
+
`profile: ${format.route.profile}`,
|
|
13077
|
+
`theme strategy: ${format.route.themeStrategy}`,
|
|
13078
|
+
`navigation model: ${format.route.navigationModel}`,
|
|
13079
|
+
`layout approach: ${format.route.layoutApproach}`
|
|
13080
|
+
]),
|
|
13081
|
+
"",
|
|
13082
|
+
"Design direction:",
|
|
13083
|
+
formatBulletList2([
|
|
13084
|
+
`archetype: ${format.archetype}`,
|
|
13085
|
+
`layout archetype: ${format.layoutArchetype}`,
|
|
13086
|
+
`typography system: ${format.typographySystem}`,
|
|
13087
|
+
`surface treatment: ${format.surfaceTreatment}`,
|
|
13088
|
+
`shape language: ${format.shapeLanguage}`,
|
|
13089
|
+
`component grammar: ${format.componentGrammar}`,
|
|
13090
|
+
`motion grammar: ${format.motionGrammar}`,
|
|
13091
|
+
`palette intent: ${format.paletteIntent}`,
|
|
13092
|
+
`visual density: ${format.visualDensity}`,
|
|
13093
|
+
`design variance: ${format.designVariance}`
|
|
13094
|
+
]),
|
|
13095
|
+
"",
|
|
13096
|
+
"Responsive collapse rules:",
|
|
13097
|
+
formatBulletList2(format.responsiveCollapseRules),
|
|
13098
|
+
"",
|
|
13099
|
+
"Focus areas:",
|
|
13100
|
+
formatBulletList2(format.focusAreas ?? []),
|
|
13101
|
+
"",
|
|
13102
|
+
"Execution rules:",
|
|
13103
|
+
formatBulletList2([...INSPIREDESIGN_BRIEF_COMMON_RULES, ...format.guardrails]),
|
|
13104
|
+
"",
|
|
13105
|
+
"Anti-patterns:",
|
|
13106
|
+
formatBulletList2(format.antiPatterns),
|
|
13107
|
+
"",
|
|
13108
|
+
"Return:",
|
|
13109
|
+
formatBulletList2([...INSPIREDESIGN_BRIEF_OUTPUT_REQUIREMENTS, ...format.deliverables]),
|
|
13110
|
+
"",
|
|
13111
|
+
"Best fit use cases:",
|
|
13112
|
+
formatBulletList2(format.bestFor)
|
|
13113
|
+
].join("\n");
|
|
13114
|
+
var renderUnavailableReference = (reference) => {
|
|
13115
|
+
const reason = reference.fetchFailure ?? reference.captureFailure ?? "no usable creative evidence captured";
|
|
13116
|
+
return `${reference.url}: fetch=${reference.fetchStatus}, capture=${reference.captureStatus}, reason=${clipText2(reason, 160)}`;
|
|
13117
|
+
};
|
|
12046
13118
|
var cloneTemplate = (value) => structuredClone(value);
|
|
12047
13119
|
var referenceFingerprint = (value) => {
|
|
12048
13120
|
return createHash3("sha256").update(value).digest("hex").slice(0, 12);
|
|
12049
13121
|
};
|
|
12050
13122
|
var summarizeBrief = (brief) => {
|
|
12051
|
-
const normalized =
|
|
13123
|
+
const normalized = trimText2(brief);
|
|
12052
13124
|
const sentence = normalized.split(/[.!?]/).map((part) => part.trim()).find(Boolean);
|
|
12053
|
-
return
|
|
13125
|
+
return clipText2(sentence ?? normalized, 140);
|
|
12054
13126
|
};
|
|
12055
13127
|
var buildSupportingMessages = (references) => {
|
|
12056
|
-
const messages = references.map((reference) => reference.title ?? reference.excerpt ?? "").map((value) =>
|
|
13128
|
+
const messages = references.map((reference) => reference.title ?? reference.excerpt ?? "").map((value) => clipText2(trimText2(value), 72)).filter((value) => value.length > 0);
|
|
12057
13129
|
return messages.slice(0, 3);
|
|
12058
13130
|
};
|
|
12059
|
-
var
|
|
13131
|
+
var summarizeDesignVectors = (designVectors) => [
|
|
13132
|
+
`direction: ${designVectors.directionLabel}`,
|
|
13133
|
+
`sections: ${designVectors.sectionArchitecture.join(" ")}`,
|
|
13134
|
+
`motion: ${designVectors.motionPosture.slice(0, 1).join(" ")}`,
|
|
13135
|
+
`interactions: ${designVectors.interactionMoments.slice(0, 1).join(" ")}`,
|
|
13136
|
+
`materials: ${designVectors.materialEffects.slice(0, 1).join(" ")}`,
|
|
13137
|
+
`advancedMotion: ${designVectors.advancedMotionAdvisory.slice(0, 1).join(" ")}`
|
|
13138
|
+
].join(" ");
|
|
13139
|
+
var isReferenceFirstPublicLanding = (designVectors) => {
|
|
13140
|
+
return designVectors.sourcePriority === "reference-evidence-first" && designVectors.surfaceIntent.toLowerCase().includes("public landing page");
|
|
13141
|
+
};
|
|
13142
|
+
var buildEvidenceDerivedFormat = (format, designVectors) => {
|
|
13143
|
+
const clone = cloneInspiredesignBriefFormat(format);
|
|
13144
|
+
if (!isReferenceFirstPublicLanding(designVectors)) return clone;
|
|
13145
|
+
return {
|
|
13146
|
+
...clone,
|
|
13147
|
+
label: "Reference-led public landing page",
|
|
13148
|
+
archetype: "reference-led public landing page",
|
|
13149
|
+
layoutArchetype: "full-bleed hero with narrative section cadence",
|
|
13150
|
+
componentGrammar: "hero composition, proof bands, narrative pathways, service or story sections, conversion CTA, and footer",
|
|
13151
|
+
route: {
|
|
13152
|
+
...clone.route,
|
|
13153
|
+
profile: "product-story",
|
|
13154
|
+
navigationModel: "global-header",
|
|
13155
|
+
layoutApproach: "reference-led-landing-page"
|
|
13156
|
+
}
|
|
13157
|
+
};
|
|
13158
|
+
};
|
|
13159
|
+
var TARGET_KIND_ORDER = ["page", "component", "asset"];
|
|
13160
|
+
var TARGET_CONFIDENCE = {
|
|
13161
|
+
defaultPage: 0.55,
|
|
13162
|
+
pageIntentStep: 0.05,
|
|
13163
|
+
nonPageBase: 0.55,
|
|
13164
|
+
intentStep: 0.08,
|
|
13165
|
+
supportingStep: 0.05,
|
|
13166
|
+
maxPage: 0.7,
|
|
13167
|
+
maxNonPage: 0.95
|
|
13168
|
+
};
|
|
13169
|
+
var TARGET_SIGNAL_PROFILES = {
|
|
13170
|
+
page: {
|
|
13171
|
+
intent: ["page", "landing page", "website", "homepage", "dashboard", "workspace", "screen", "flow", "surface", "microsite"],
|
|
13172
|
+
supporting: ["section", "sections", "navigation", "footer", "hero section", "conversion flow"],
|
|
13173
|
+
incidental: ["card", "cards", "button", "buttons", "image", "images", "media", "hero", "cta", "background"]
|
|
13174
|
+
},
|
|
13175
|
+
component: {
|
|
13176
|
+
intent: ["component", "component family", "reusable component", "component prototype", "hero component", "card component", "storybook"],
|
|
13177
|
+
supporting: ["prop", "props", "slot", "slots", "variant", "variants", "state matrix", "hover", "focus", "disabled", "loading", "error", "fixture", "fixtures", "arg", "args"],
|
|
13178
|
+
incidental: ["card", "cards", "button", "buttons", "form", "modal", "drawer", "navbar", "hero", "input", "tabs", "cta"]
|
|
13179
|
+
},
|
|
13180
|
+
asset: {
|
|
13181
|
+
intent: ["asset", "asset pack", "visual asset", "icon pack", "logo pack", "illustration set", "artwork set"],
|
|
13182
|
+
supporting: ["responsive variant", "responsive variants", "responsive artwork", "provenance", "usage rules", "alt text", "replacement rules", "tokenized usage", "source asset", "source assets"],
|
|
13183
|
+
incidental: ["icon", "icons", "illustration", "illustrations", "logo", "logos", "media", "image", "images", "background", "texture", "sprite", "artwork"]
|
|
13184
|
+
}
|
|
13185
|
+
};
|
|
13186
|
+
var buildTargetCorpus = (brief, references, synthesis) => [
|
|
13187
|
+
brief,
|
|
13188
|
+
synthesis.lines.join(" "),
|
|
13189
|
+
...references.filter(hasInspiredesignUsableReferenceEvidence).flatMap((reference) => getInspiredesignReferenceSignals(reference))
|
|
13190
|
+
].join(" ").toLowerCase();
|
|
13191
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13192
|
+
var matchesTargetSignal = (corpus, signal) => {
|
|
13193
|
+
const pattern = escapeRegex(signal.toLowerCase()).replace(/\s+/g, "\\s+");
|
|
13194
|
+
return new RegExp(`(^|[^a-z0-9])${pattern}([^a-z0-9]|$)`).test(corpus);
|
|
13195
|
+
};
|
|
13196
|
+
var findTargetSignalIndex = (corpus, signal) => {
|
|
13197
|
+
const pattern = escapeRegex(signal.toLowerCase()).replace(/\s+/g, "\\s+");
|
|
13198
|
+
return new RegExp(`(^|[^a-z0-9])${pattern}([^a-z0-9]|$)`).exec(corpus)?.index ?? null;
|
|
13199
|
+
};
|
|
13200
|
+
var findFirstBriefTargetKind = (brief) => {
|
|
13201
|
+
const corpus = brief.toLowerCase();
|
|
13202
|
+
const hits = TARGET_KIND_ORDER.flatMap((kind) => TARGET_SIGNAL_PROFILES[kind].intent.map((signal) => findTargetSignalIndex(corpus, signal)).filter((index) => index !== null).map((index) => ({ kind, index })));
|
|
13203
|
+
return hits.sort((left, right) => left.index - right.index)[0]?.kind ?? null;
|
|
13204
|
+
};
|
|
13205
|
+
var collectTargetSignals = (corpus) => {
|
|
13206
|
+
const collect = (kind) => {
|
|
13207
|
+
const profile = TARGET_SIGNAL_PROFILES[kind];
|
|
13208
|
+
return {
|
|
13209
|
+
intent: profile.intent.filter((signal) => matchesTargetSignal(corpus, signal)),
|
|
13210
|
+
supporting: profile.supporting.filter((signal) => matchesTargetSignal(corpus, signal)),
|
|
13211
|
+
incidental: profile.incidental.filter((signal) => matchesTargetSignal(corpus, signal))
|
|
13212
|
+
};
|
|
13213
|
+
};
|
|
13214
|
+
return {
|
|
13215
|
+
page: collect("page"),
|
|
13216
|
+
component: collect("component"),
|
|
13217
|
+
asset: collect("asset")
|
|
13218
|
+
};
|
|
13219
|
+
};
|
|
13220
|
+
var clampTargetConfidence = (value, max) => Math.min(max, Number(value.toFixed(2)));
|
|
13221
|
+
var buildPageConfidence = (signals) => {
|
|
13222
|
+
return clampTargetConfidence(
|
|
13223
|
+
TARGET_CONFIDENCE.defaultPage + signals.intent.length * TARGET_CONFIDENCE.pageIntentStep,
|
|
13224
|
+
TARGET_CONFIDENCE.maxPage
|
|
13225
|
+
);
|
|
13226
|
+
};
|
|
13227
|
+
var buildTargetEligibility = (kind, briefSignals, supportSignals) => {
|
|
13228
|
+
const eligible = briefSignals.intent.length > 0 && supportSignals.supporting.length > 0;
|
|
13229
|
+
const confidence = eligible ? clampTargetConfidence(
|
|
13230
|
+
TARGET_CONFIDENCE.nonPageBase + briefSignals.intent.length * TARGET_CONFIDENCE.intentStep + supportSignals.supporting.length * TARGET_CONFIDENCE.supportingStep,
|
|
13231
|
+
TARGET_CONFIDENCE.maxNonPage
|
|
13232
|
+
) : 0;
|
|
13233
|
+
return {
|
|
13234
|
+
kind,
|
|
13235
|
+
eligible,
|
|
13236
|
+
confidence,
|
|
13237
|
+
triggeringSignals: [
|
|
13238
|
+
...briefSignals.intent.map((signal) => `${kind} intent: ${signal}`),
|
|
13239
|
+
...supportSignals.supporting.map((signal) => `${kind} support: ${signal}`)
|
|
13240
|
+
]
|
|
13241
|
+
};
|
|
13242
|
+
};
|
|
13243
|
+
var choosePrimaryTargetKind = (pageConfidence, pageSignals, firstBriefTargetKind, component, asset) => {
|
|
13244
|
+
const eligibleTargets = [component, asset].filter((target) => target.eligible);
|
|
13245
|
+
if (eligibleTargets.length === 0) return { primaryKind: "page", reason: "no_non_page_gate" };
|
|
13246
|
+
if (firstBriefTargetKind === "page" && pageSignals.intent.length > 0) {
|
|
13247
|
+
return { primaryKind: "page", reason: "page_first_brief_target" };
|
|
13248
|
+
}
|
|
13249
|
+
const [first, second] = eligibleTargets.sort((left, right) => right.confidence - left.confidence);
|
|
13250
|
+
if (!first || first.confidence <= pageConfidence) {
|
|
13251
|
+
return { primaryKind: "page", reason: "non_page_did_not_beat_page" };
|
|
13252
|
+
}
|
|
13253
|
+
if (second && first.confidence === second.confidence && pageSignals.intent.length > 0) {
|
|
13254
|
+
return { primaryKind: "page", reason: "page_tie_break" };
|
|
13255
|
+
}
|
|
13256
|
+
return { primaryKind: first.kind, reason: "non_page_selected" };
|
|
13257
|
+
};
|
|
13258
|
+
var chooseTargetKinds = (primaryKind, component, asset) => {
|
|
13259
|
+
if (primaryKind === "page") return ["page"];
|
|
13260
|
+
const eligible = new Set([component, asset].filter((target) => target.eligible).map((target) => target.kind));
|
|
13261
|
+
const secondaryKinds = TARGET_KIND_ORDER.filter((kind) => kind !== primaryKind && eligible.has(kind));
|
|
13262
|
+
return [primaryKind, ...secondaryKinds];
|
|
13263
|
+
};
|
|
13264
|
+
var buildTriggeringSignals = (decision, signals, component, asset) => {
|
|
13265
|
+
const pageSignals = signals.page.intent.map((signal) => `page intent: ${signal}`);
|
|
13266
|
+
const eligibleTargets = [component, asset].filter((target) => target.eligible);
|
|
13267
|
+
const targetIntents = eligibleTargets.flatMap((target) => target.triggeringSignals.filter((signal) => signal.includes(" intent: ")));
|
|
13268
|
+
const targetSupport = eligibleTargets.flatMap((target) => target.triggeringSignals.filter((signal) => signal.includes(" support: ")));
|
|
13269
|
+
const defaultSignal = decision.primaryKind === "page" ? [buildPageDecisionSignal(decision.reason)] : [];
|
|
13270
|
+
return [...pageSignals, ...targetIntents, ...targetSupport, ...defaultSignal].slice(0, 12);
|
|
13271
|
+
};
|
|
13272
|
+
var buildPageDecisionSignal = (reason) => {
|
|
13273
|
+
if (reason === "no_non_page_gate") return "page default: non-page targets did not clear brief intent plus support gates";
|
|
13274
|
+
if (reason === "non_page_did_not_beat_page") return "page default: non-page targets did not beat page confidence";
|
|
13275
|
+
if (reason === "page_first_brief_target") return "page default: page was the first explicit target in the brief";
|
|
13276
|
+
if (reason === "page_tie_break") return "page default: page intent won a tied non-page confidence score";
|
|
13277
|
+
return "page default: page selected";
|
|
13278
|
+
};
|
|
13279
|
+
var getTargetConfidence = (primaryKind, pageConfidence, component, asset) => {
|
|
13280
|
+
if (primaryKind === "component") return component.confidence;
|
|
13281
|
+
if (primaryKind === "asset") return asset.confidence;
|
|
13282
|
+
return pageConfidence;
|
|
13283
|
+
};
|
|
13284
|
+
var buildTargetEvidenceBuckets = (primaryKind, format, designVectors) => ({
|
|
13285
|
+
anatomy: [`Map ${primaryKind} anatomy before styling: root, content hierarchy, interaction zones, and supporting regions.`],
|
|
13286
|
+
propsSlots: [`Define props/slots from ${format.componentGrammar}; separate data props, content slots, and visual variant controls.`],
|
|
13287
|
+
stateMatrix: ["Cover default, hover, focus, active, disabled, loading, empty, error, success, and selected where relevant."],
|
|
13288
|
+
tokens: [`Resolve typography, color, spacing, radius, shadow, motion, and z-index through semantic tokens for ${format.paletteIntent}.`],
|
|
13289
|
+
assets: [`Inventory source assets, derived assets, usage rights, responsive variants, and replacement notes for ${primaryKind} prototypes.`],
|
|
13290
|
+
accessibility: ["Validate keyboard order, visible focus, accessible names, ARIA pattern fit, contrast, and WCAG 2.2 states."],
|
|
13291
|
+
motion: [`Use ${format.motionGrammar}; include reduced-motion alternatives for ${designVectors.motionPosture.join(" ") || "all transitions"}.`],
|
|
13292
|
+
previewFixtures: [`Build isolated preview fixtures for ${primaryKind} default, responsive, reduced-motion, and failure states.`]
|
|
13293
|
+
});
|
|
13294
|
+
var buildComponentTargetAnalysis = (briefHash, format) => ({
|
|
13295
|
+
canvasType: "CanvasComponentInventoryItem",
|
|
13296
|
+
inventoryItems: [{
|
|
13297
|
+
id: `component_${briefHash}`,
|
|
13298
|
+
name: `${format.label} Component`,
|
|
13299
|
+
componentName: `${format.route.profile.replace(/-/g, "")}PrototypeComponent`,
|
|
13300
|
+
description: `Reusable component prototype derived from ${format.componentGrammar}.`,
|
|
13301
|
+
sourceFamily: "framework_component",
|
|
13302
|
+
origin: "code_sync",
|
|
13303
|
+
variants: [{
|
|
13304
|
+
id: "default",
|
|
13305
|
+
name: "Default",
|
|
13306
|
+
selector: { interaction: "default" },
|
|
13307
|
+
description: "Default preview fixture.",
|
|
13308
|
+
metadata: {}
|
|
13309
|
+
}],
|
|
13310
|
+
props: [
|
|
13311
|
+
{ name: "variant", type: "string", required: false, description: "Visual variant key.", metadata: {} },
|
|
13312
|
+
{ name: "state", type: "string", required: false, description: "Interaction state fixture.", metadata: {} }
|
|
13313
|
+
],
|
|
13314
|
+
slots: [
|
|
13315
|
+
{ name: "media", description: "Optional visual or icon slot.", allowedKinds: ["asset", "image", "icon"], metadata: {} },
|
|
13316
|
+
{ name: "content", description: "Primary text or rich content slot.", allowedKinds: ["text", "rich-text"], metadata: {} }
|
|
13317
|
+
],
|
|
13318
|
+
events: [{ name: "onPrimaryAction", description: "Primary interaction callback.", payloadShape: {}, metadata: {} }],
|
|
13319
|
+
content: { acceptsText: true, acceptsRichText: true, slotNames: ["media", "content"], metadata: {} },
|
|
13320
|
+
metadata: { targetKind: "component" }
|
|
13321
|
+
}],
|
|
13322
|
+
prototypeGuidance: [
|
|
13323
|
+
"Component prototype target: document anatomy, props/slots, variant rules, and interaction state fixtures before page composition.",
|
|
13324
|
+
"Use Storybook-style args and interaction checks when converting this guidance into executable component previews."
|
|
13325
|
+
]
|
|
13326
|
+
});
|
|
13327
|
+
var buildAssetTargetAnalysis = (briefHash) => ({
|
|
13328
|
+
canvasType: "CanvasAsset",
|
|
13329
|
+
assets: [{
|
|
13330
|
+
id: `asset_${briefHash}`,
|
|
13331
|
+
sourceType: "page-derived",
|
|
13332
|
+
kind: "visual-asset",
|
|
13333
|
+
url: null,
|
|
13334
|
+
status: "needs-production-source",
|
|
13335
|
+
provenanceNotes: ["Derived from brief/reference evidence; recreate rather than copy proprietary source assets."],
|
|
13336
|
+
usageNotes: ["Define responsive variants, token usage, alt text, and replacement rules before implementation."],
|
|
13337
|
+
metadata: { targetKind: "asset" }
|
|
13338
|
+
}],
|
|
13339
|
+
prototypeGuidance: [
|
|
13340
|
+
"Asset prototype target: catalog provenance, variants, token usage, responsive behavior, and replacement rules.",
|
|
13341
|
+
"Pair each visual asset with preview fixtures for default, high contrast, and reduced-motion contexts when relevant."
|
|
13342
|
+
]
|
|
13343
|
+
});
|
|
13344
|
+
var buildPageTargetAnalysis = (format, designVectors) => ({
|
|
13345
|
+
canvasType: "CanvasPage",
|
|
13346
|
+
assemblyFocus: [
|
|
13347
|
+
format.layoutArchetype,
|
|
13348
|
+
...designVectors.sectionArchitecture
|
|
13349
|
+
],
|
|
13350
|
+
implementationNotes: [
|
|
13351
|
+
"Page prototype target: validate section order, navigation model, CTA visibility, responsive collapse, and reduced-motion behavior.",
|
|
13352
|
+
"Use component primitives before page-specific wrappers."
|
|
13353
|
+
]
|
|
13354
|
+
});
|
|
13355
|
+
var buildTargetAnalysis = (brief, format, references, synthesis, designVectors) => {
|
|
13356
|
+
const briefSignals = collectTargetSignals(brief.toLowerCase());
|
|
13357
|
+
const supportSignals = collectTargetSignals(buildTargetCorpus(brief, references, synthesis));
|
|
13358
|
+
const pageConfidence = buildPageConfidence(briefSignals.page);
|
|
13359
|
+
const component = buildTargetEligibility("component", briefSignals.component, supportSignals.component);
|
|
13360
|
+
const asset = buildTargetEligibility("asset", briefSignals.asset, supportSignals.asset);
|
|
13361
|
+
const decision = choosePrimaryTargetKind(
|
|
13362
|
+
pageConfidence,
|
|
13363
|
+
briefSignals.page,
|
|
13364
|
+
findFirstBriefTargetKind(brief),
|
|
13365
|
+
component,
|
|
13366
|
+
asset
|
|
13367
|
+
);
|
|
13368
|
+
const primaryKind = decision.primaryKind;
|
|
13369
|
+
const kinds = chooseTargetKinds(primaryKind, component, asset);
|
|
13370
|
+
const briefHash = referenceFingerprint(brief);
|
|
13371
|
+
return {
|
|
13372
|
+
primaryKind,
|
|
13373
|
+
kinds,
|
|
13374
|
+
confidence: getTargetConfidence(primaryKind, pageConfidence, component, asset),
|
|
13375
|
+
triggeringSignals: buildTriggeringSignals(decision, briefSignals, component, asset),
|
|
13376
|
+
evidenceBuckets: buildTargetEvidenceBuckets(primaryKind, format, designVectors),
|
|
13377
|
+
...kinds.includes("page") ? { page: buildPageTargetAnalysis(format, designVectors) } : {},
|
|
13378
|
+
...kinds.includes("component") ? { component: buildComponentTargetAnalysis(briefHash, format) } : {},
|
|
13379
|
+
...kinds.includes("asset") ? { asset: buildAssetTargetAnalysis(briefHash) } : {}
|
|
13380
|
+
};
|
|
13381
|
+
};
|
|
13382
|
+
var buildGenerationPlan = ({
|
|
13383
|
+
brief,
|
|
13384
|
+
format,
|
|
13385
|
+
synthesis,
|
|
13386
|
+
referencePatternBoard,
|
|
13387
|
+
designVectors,
|
|
13388
|
+
targetAnalysis
|
|
13389
|
+
}) => {
|
|
12060
13390
|
const plan = cloneTemplate(BASE_GENERATION_PLAN);
|
|
12061
13391
|
const profile = format.route.profile;
|
|
12062
|
-
|
|
13392
|
+
const vectorSummary = summarizeDesignVectors(designVectors);
|
|
13393
|
+
plan.targetOutcome.summary = clipText2(
|
|
13394
|
+
`${summarizeBrief(brief)} Reference cues: ${synthesis.summary} ${vectorSummary}`,
|
|
13395
|
+
GENERATION_PLAN_REFERENCE_CLIP_LENGTH
|
|
13396
|
+
);
|
|
12063
13397
|
plan.visualDirection.profile = profile;
|
|
12064
13398
|
plan.visualDirection.themeStrategy = format.route.themeStrategy;
|
|
12065
13399
|
plan.layoutStrategy.approach = format.route.layoutApproach;
|
|
12066
13400
|
plan.layoutStrategy.navigationModel = format.route.navigationModel;
|
|
13401
|
+
plan.contentStrategy.source = clipText2(
|
|
13402
|
+
`${INSPIREDESIGN_HANDOFF_FILES.evidence}, ${INSPIREDESIGN_HANDOFF_FILES.advancedBrief}, ${INSPIREDESIGN_HANDOFF_FILES.designMarkdown}. Use reference pattern board and design vectors from evidence/handoff artifacts. ${synthesis.summary} ${vectorSummary}`,
|
|
13403
|
+
GENERATION_PLAN_REFERENCE_CLIP_LENGTH
|
|
13404
|
+
);
|
|
13405
|
+
plan.componentStrategy.mode = clipText2(
|
|
13406
|
+
`reuse-first, adapted from captured references: ${synthesis.summary}. Include hero entrance reveal, section scroll reveal, CTA/focus feedback, microinteractions, hover effects, evidence-gated cursor effects, material depth, parallax constraints, glass/translucency policy, and prefers-reduced-motion behavior. Capture desktop and mobile browser proof for responsive layout, reduced-motion behavior, focus states, and primary CTA visibility.`,
|
|
13407
|
+
GENERATION_PLAN_REFERENCE_CLIP_LENGTH
|
|
13408
|
+
);
|
|
12067
13409
|
plan.componentStrategy.interactionStates = ["default", "hover", "focus", "disabled", "loading"];
|
|
12068
13410
|
plan.validationTargets.requiredThemes = plan.visualDirection.themeStrategy === "single-theme" ? ["light"] : ["light", "dark"];
|
|
12069
|
-
return
|
|
13411
|
+
return {
|
|
13412
|
+
...plan,
|
|
13413
|
+
referencePatternBoard,
|
|
13414
|
+
designVectors,
|
|
13415
|
+
targetAnalysis,
|
|
13416
|
+
interactionMoments: [...designVectors.interactionMoments],
|
|
13417
|
+
materialEffects: [...designVectors.materialEffects]
|
|
13418
|
+
};
|
|
12070
13419
|
};
|
|
12071
13420
|
var buildIntentBlock = (brief, urls, references, format) => {
|
|
12072
13421
|
const intent = cloneTemplate(BASE_CONTRACT_TEMPLATE.intent);
|
|
@@ -12174,11 +13523,19 @@ var buildIconSystemBlock = () => ({
|
|
|
12174
13523
|
"Decorative icons should remain visually lighter than primary copy."
|
|
12175
13524
|
]
|
|
12176
13525
|
});
|
|
12177
|
-
var buildMotionSystemBlock = (format) => {
|
|
13526
|
+
var buildMotionSystemBlock = (format, designVectors) => {
|
|
12178
13527
|
const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.motionSystem);
|
|
12179
13528
|
return {
|
|
12180
13529
|
...block,
|
|
12181
13530
|
grammar: format.motionGrammar,
|
|
13531
|
+
posture: [...designVectors.motionPosture],
|
|
13532
|
+
interactionMoments: [...designVectors.interactionMoments],
|
|
13533
|
+
materialEffects: [...designVectors.materialEffects],
|
|
13534
|
+
advancedMotionAdvisory: [...designVectors.advancedMotionAdvisory],
|
|
13535
|
+
advancedMotionRuntimePolicy: "Advanced motion fields are advisory contract metadata only and do not authorize shader, WebGL, Spline, R3F, Pixi, Babylon, or GLSL runtime support.",
|
|
13536
|
+
parallaxPolicy: "Use parallax only as a restrained hierarchy cue and remove transform-based depth for reduced-motion users.",
|
|
13537
|
+
hoverPolicy: "Hover effects must clarify clickability without becoming the only visible affordance.",
|
|
13538
|
+
cursorPolicy: "Cursor effects are allowed only on premium hero or CTA moments and must not interfere with reading or form controls.",
|
|
12182
13539
|
durations: {
|
|
12183
13540
|
quick: "120ms",
|
|
12184
13541
|
standard: "180ms",
|
|
@@ -12209,12 +13566,12 @@ var buildLibraryPolicyBlock = () => ({
|
|
|
12209
13566
|
components: ["shadcn"],
|
|
12210
13567
|
icons: ["tabler"],
|
|
12211
13568
|
styling: ["tailwindcss"],
|
|
12212
|
-
motion: [
|
|
13569
|
+
motion: [],
|
|
12213
13570
|
threeD: []
|
|
12214
13571
|
});
|
|
12215
13572
|
var buildRuntimeBudgetsBlock = (plan) => ({
|
|
12216
13573
|
maxHeroActions: 2,
|
|
12217
|
-
maxPrimarySections: 8,
|
|
13574
|
+
maxPrimarySections: plan.layoutStrategy.navigationModel === "global-header" ? 12 : 8,
|
|
12218
13575
|
maxInteractionLatencyMs: plan.validationTargets.maxInteractionLatencyMs,
|
|
12219
13576
|
previewBudgetMs: 1500,
|
|
12220
13577
|
notes: [
|
|
@@ -12254,7 +13611,21 @@ var buildPerformanceModelBlock = () => {
|
|
|
12254
13611
|
var buildCanvasPlanRequest = (brief, generationPlan) => ({
|
|
12255
13612
|
...cloneTemplate(BASE_PLAN_REQUEST_TEMPLATE),
|
|
12256
13613
|
requestId: `req_plan_${referenceFingerprint(brief).slice(0, 12)}`,
|
|
12257
|
-
generationPlan
|
|
13614
|
+
generationPlan: toCanvasGenerationPlan(generationPlan)
|
|
13615
|
+
});
|
|
13616
|
+
var toCanvasGenerationPlan = (plan) => cloneTemplate({
|
|
13617
|
+
targetOutcome: plan.targetOutcome,
|
|
13618
|
+
visualDirection: plan.visualDirection,
|
|
13619
|
+
layoutStrategy: plan.layoutStrategy,
|
|
13620
|
+
contentStrategy: plan.contentStrategy,
|
|
13621
|
+
componentStrategy: plan.componentStrategy,
|
|
13622
|
+
motionPosture: plan.motionPosture,
|
|
13623
|
+
responsivePosture: plan.responsivePosture,
|
|
13624
|
+
accessibilityPosture: plan.accessibilityPosture,
|
|
13625
|
+
validationTargets: plan.validationTargets,
|
|
13626
|
+
interactionMoments: [...plan.interactionMoments],
|
|
13627
|
+
materialEffects: [...plan.materialEffects],
|
|
13628
|
+
designVectors: plan.designVectors
|
|
12258
13629
|
});
|
|
12259
13630
|
var buildContractScope = () => ({
|
|
12260
13631
|
emittedContract: "CanvasDesignGovernance",
|
|
@@ -12267,9 +13638,31 @@ var buildBriefExpansionMetadata = (briefExpansion) => ({
|
|
|
12267
13638
|
file: INSPIREDESIGN_HANDOFF_FILES.advancedBrief,
|
|
12268
13639
|
format: cloneInspiredesignBriefFormat(briefExpansion.format)
|
|
12269
13640
|
});
|
|
12270
|
-
var
|
|
13641
|
+
var buildRequiredReferenceArtifacts = (includePrototypeGuidance) => {
|
|
13642
|
+
const files = [
|
|
13643
|
+
INSPIREDESIGN_HANDOFF_FILES.evidence,
|
|
13644
|
+
INSPIREDESIGN_HANDOFF_FILES.advancedBrief,
|
|
13645
|
+
INSPIREDESIGN_HANDOFF_FILES.designMarkdown,
|
|
13646
|
+
INSPIREDESIGN_HANDOFF_FILES.generationPlan,
|
|
13647
|
+
INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest,
|
|
13648
|
+
INSPIREDESIGN_HANDOFF_FILES.designContract,
|
|
13649
|
+
INSPIREDESIGN_HANDOFF_FILES.implementationPlanMarkdown
|
|
13650
|
+
];
|
|
13651
|
+
return includePrototypeGuidance ? [...files, INSPIREDESIGN_HANDOFF_FILES.prototypeGuidance] : files;
|
|
13652
|
+
};
|
|
13653
|
+
var buildFollowthrough = ({
|
|
13654
|
+
generationPlan,
|
|
13655
|
+
briefExpansion,
|
|
13656
|
+
synthesis,
|
|
13657
|
+
includePrototypeGuidance,
|
|
13658
|
+
referencePatternBoard,
|
|
13659
|
+
designVectors,
|
|
13660
|
+
targetAnalysis
|
|
13661
|
+
}) => ({
|
|
12271
13662
|
summary: buildInspiredesignFollowthroughSummary(),
|
|
12272
13663
|
nextStep: buildInspiredesignNextStep(),
|
|
13664
|
+
artifactGuide: INSPIREDESIGN_ARTIFACT_GUIDE,
|
|
13665
|
+
contractSectionGuide: INSPIREDESIGN_CONTRACT_SECTION_GUIDE,
|
|
12273
13666
|
briefExpansion: buildBriefExpansionMetadata(briefExpansion),
|
|
12274
13667
|
recommendedSkills: [...INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS],
|
|
12275
13668
|
commandExamples: { ...INSPIREDESIGN_HANDOFF_COMMANDS },
|
|
@@ -12278,20 +13671,33 @@ var buildFollowthrough = (generationPlan, briefExpansion) => ({
|
|
|
12278
13671
|
implementationContext: {
|
|
12279
13672
|
navigationModel: buildNavigationModelBlock(generationPlan.layoutStrategy.navigationModel),
|
|
12280
13673
|
asyncModel: buildAsyncModelBlock(),
|
|
12281
|
-
performanceModel: buildPerformanceModelBlock()
|
|
13674
|
+
performanceModel: buildPerformanceModelBlock(),
|
|
13675
|
+
referenceSynthesis: {
|
|
13676
|
+
requiredArtifacts: buildRequiredReferenceArtifacts(includePrototypeGuidance),
|
|
13677
|
+
cues: synthesis.lines
|
|
13678
|
+
},
|
|
13679
|
+
referencePatternBoard,
|
|
13680
|
+
designVectors,
|
|
13681
|
+
targetAnalysis
|
|
12282
13682
|
}
|
|
12283
13683
|
});
|
|
12284
|
-
var buildDesignContract = (
|
|
13684
|
+
var buildDesignContract = ({
|
|
13685
|
+
brief,
|
|
13686
|
+
urls,
|
|
13687
|
+
references,
|
|
13688
|
+
plan,
|
|
13689
|
+
format
|
|
13690
|
+
}) => ({
|
|
12285
13691
|
intent: buildIntentBlock(brief, urls, references, format),
|
|
12286
|
-
generationPlan: plan,
|
|
13692
|
+
generationPlan: toCanvasGenerationPlan(plan),
|
|
12287
13693
|
designLanguage: buildDesignLanguageBlock(plan.visualDirection.profile, format),
|
|
12288
|
-
contentModel: buildContentModelBlock(brief, references),
|
|
13694
|
+
contentModel: buildContentModelBlock(brief, references.filter(hasInspiredesignUsableReferenceEvidence)),
|
|
12289
13695
|
layoutSystem: buildLayoutSystemBlock(plan, format),
|
|
12290
13696
|
typographySystem: buildTypographySystemBlock(format),
|
|
12291
13697
|
colorSystem: buildColorSystemBlock(plan.visualDirection.profile, format),
|
|
12292
13698
|
surfaceSystem: buildSurfaceSystemBlock(format),
|
|
12293
13699
|
iconSystem: buildIconSystemBlock(),
|
|
12294
|
-
motionSystem: buildMotionSystemBlock(format),
|
|
13700
|
+
motionSystem: buildMotionSystemBlock(format, plan.designVectors),
|
|
12295
13701
|
responsiveSystem: buildResponsiveSystemBlock(format),
|
|
12296
13702
|
accessibilityPolicy: buildAccessibilityBlock(),
|
|
12297
13703
|
libraryPolicy: buildLibraryPolicyBlock(),
|
|
@@ -12353,17 +13759,32 @@ var buildComponentBuildPlan = (profile) => {
|
|
|
12353
13759
|
implementationNote: "Use semantic tokens first and keep copy/state logic outside the visual component."
|
|
12354
13760
|
}));
|
|
12355
13761
|
};
|
|
12356
|
-
var buildImplementationPlan = (
|
|
13762
|
+
var buildImplementationPlan = ({
|
|
13763
|
+
profile,
|
|
13764
|
+
format,
|
|
13765
|
+
references,
|
|
13766
|
+
synthesis,
|
|
13767
|
+
designVectors
|
|
13768
|
+
}) => ({
|
|
12357
13769
|
architectureRecommendation: `Implement the surface as a ${format.archetype} using token-first components and shared semantic CSS variables, then compose page sections from those primitives before adding any page-specific polish.`,
|
|
12358
13770
|
tokenStrategy: buildTokenStrategy(profile),
|
|
13771
|
+
referenceImplementationNotes: synthesis.lines.length > 0 ? synthesis.lines : ["No live reference cues were captured; keep implementation anchored to the source brief and selected prompt format."],
|
|
12359
13772
|
componentBuildPlan: buildComponentBuildPlan(profile),
|
|
12360
13773
|
pageAssemblyPlan: [
|
|
12361
13774
|
`Start with the ${format.layoutArchetype} and the primary navigation pattern.`,
|
|
13775
|
+
...designVectors.sectionArchitecture,
|
|
13776
|
+
"Make each major section content-rich with a concrete headline, supporting copy, proof detail, and a clear role in the journey.",
|
|
12362
13777
|
"Compose the hero or primary decision section before supporting sections.",
|
|
12363
13778
|
"Add proof, utility, and footer sections only after the top-level hierarchy is stable."
|
|
12364
13779
|
],
|
|
12365
13780
|
stateAndInteractionPlan: [
|
|
12366
13781
|
`Use ${format.motionGrammar} while keeping hover, focus, loading, success, and error states visually distinct.`,
|
|
13782
|
+
...designVectors.motionPosture,
|
|
13783
|
+
...designVectors.interactionMoments,
|
|
13784
|
+
...designVectors.materialEffects,
|
|
13785
|
+
...designVectors.advancedMotionAdvisory,
|
|
13786
|
+
"Implement hero entrance reveal, section scroll reveal, and CTA/focus feedback as the minimum motion system for landing pages.",
|
|
13787
|
+
"Use @media (prefers-reduced-motion: reduce) to preserve hierarchy without motion.",
|
|
12367
13788
|
"Preserve layout during loading and keep transient confirmations out of the main flow.",
|
|
12368
13789
|
"Use reduced-motion-safe transitions for reveals and CTA feedback."
|
|
12369
13790
|
],
|
|
@@ -12379,25 +13800,33 @@ var buildImplementationPlan = (profile, format, references) => ({
|
|
|
12379
13800
|
"Avoid horizontal scrolling for primary content."
|
|
12380
13801
|
],
|
|
12381
13802
|
risksAndAmbiguities: [
|
|
12382
|
-
references.length === 0 ? "No live references were supplied, so visual cues are derived entirely from the written brief." : "Live references were reduced into reusable patterns; unique brand assets should still be recreated, not copied.",
|
|
12383
|
-
"Any missing interaction states must be validated during visual QA."
|
|
13803
|
+
references.length === 0 ? "No live references were supplied, so visual cues are derived entirely from the written brief." : synthesis.lines.length > 0 ? "Live references were reduced into reusable patterns; unique brand assets should still be recreated, not copied." : "Reference URLs were attempted, but no usable creative evidence was captured; keep implementation anchored to the source brief and selected prompt format.",
|
|
13804
|
+
"Any missing interaction states must be validated during visual QA.",
|
|
13805
|
+
"Capture desktop and mobile browser proof before handoff, including reduced-motion behavior and primary CTA visibility."
|
|
12384
13806
|
],
|
|
12385
13807
|
buildSequence: [
|
|
12386
13808
|
"Define semantic tokens and typography.",
|
|
12387
13809
|
"Build the shell, navigation, and primary CTA components.",
|
|
12388
13810
|
"Implement section-level patterns and proof blocks.",
|
|
12389
13811
|
"Add loading, empty, and error states.",
|
|
12390
|
-
"
|
|
13812
|
+
"Capture desktop and mobile browser proof for responsive layout, reduced-motion behavior, focus states, and primary CTA visibility before final polish."
|
|
12391
13813
|
]
|
|
12392
13814
|
});
|
|
12393
13815
|
var formatBulletList2 = (items) => items.map((item) => `- ${item}`).join("\n");
|
|
13816
|
+
var renderAntiPatternRule = (rule) => {
|
|
13817
|
+
const cleanRule = rule.replace(/\.$/, "").trim();
|
|
13818
|
+
const withoutNo = cleanRule.replace(/^no\s+/i, "");
|
|
13819
|
+
if (withoutNo !== cleanRule) return `Don't use ${withoutNo.charAt(0).toLowerCase()}${withoutNo.slice(1)}.`;
|
|
13820
|
+
const withoutDoNot = cleanRule.replace(/^do not\s+/i, "");
|
|
13821
|
+
if (withoutDoNot !== cleanRule) return `Don't ${withoutDoNot.charAt(0).toLowerCase()}${withoutDoNot.slice(1)}.`;
|
|
13822
|
+
return `Don't ${cleanRule.charAt(0).toLowerCase()}${cleanRule.slice(1)}.`;
|
|
13823
|
+
};
|
|
12394
13824
|
var formatRecordList = (record) => {
|
|
12395
13825
|
return Object.entries(record).map(([key, value]) => `- \`${key}\`: ${value}`).join("\n");
|
|
12396
13826
|
};
|
|
12397
13827
|
var referenceContribution = (reference) => {
|
|
12398
13828
|
if (reference.captureStatus === "captured") return "Live hierarchy and component evidence captured from the page.";
|
|
12399
|
-
|
|
12400
|
-
return "Only operator brief context was available for this reference.";
|
|
13829
|
+
return "Content and structural cues inferred from fetched page data.";
|
|
12401
13830
|
};
|
|
12402
13831
|
var referenceMotionNote = (reference) => {
|
|
12403
13832
|
if (reference.capture?.snapshot?.warnings?.length) {
|
|
@@ -12406,8 +13835,13 @@ var referenceMotionNote = (reference) => {
|
|
|
12406
13835
|
if (reference.captureStatus === "captured") return "Motion should remain subtle until validated against the live capture.";
|
|
12407
13836
|
return "Motion is inferred from the brief rather than directly observed.";
|
|
12408
13837
|
};
|
|
13838
|
+
var referenceLayoutObservation = (reference, excerpt) => {
|
|
13839
|
+
if (!reference.capture?.snapshot && !reference.capture?.clone && !reference.capture?.dom) return excerpt;
|
|
13840
|
+
const signals = getInspiredesignReferenceSignals(reference);
|
|
13841
|
+
return signals.find((signal) => signal !== reference.title) ?? signals[0] ?? excerpt;
|
|
13842
|
+
};
|
|
12409
13843
|
var renderReferenceMarkdown = (reference, index) => {
|
|
12410
|
-
const excerpt = reference.excerpt ?
|
|
13844
|
+
const excerpt = reference.excerpt ? clipText2(reference.excerpt, 220) : "No fetched excerpt captured.";
|
|
12411
13845
|
const title = reference.title ?? reference.url;
|
|
12412
13846
|
return [
|
|
12413
13847
|
`### Source ${index + 1}: ${title}`,
|
|
@@ -12415,13 +13849,20 @@ var renderReferenceMarkdown = (reference, index) => {
|
|
|
12415
13849
|
`- notable UI patterns: ${reference.capture?.snapshot ? "Primary hierarchy and actionables were captured from the live page." : "Patterns inferred from brief and fetched content."}`,
|
|
12416
13850
|
`- typography observations: ${reference.title ? "Headline density and copy hierarchy were inferred from the fetched title and excerpt." : "Typography is inferred."}`,
|
|
12417
13851
|
`- color and theme observations: ${reference.captureStatus === "captured" ? "Color posture should be validated against the captured page before cloning brand treatment." : "Color posture remains a synthesis decision."}`,
|
|
12418
|
-
`- layout and hierarchy observations: ${
|
|
13852
|
+
`- layout and hierarchy observations: ${referenceLayoutObservation(reference, excerpt)}`,
|
|
12419
13853
|
`- component patterns: ${reference.capture?.clone ? "Buttons, cards, or layout wrappers can be inferred from the captured clone preview." : "Component families were inferred from available reference text."}`,
|
|
12420
13854
|
`- motion/interaction observations: ${referenceMotionNote(reference)}`,
|
|
12421
13855
|
`- accessibility/responsiveness notes: ${reference.captureStatus === "captured" ? "Validate focus order, CTA prominence, and stacked layouts during build QA." : "Accessibility and responsiveness are inferred from system defaults."}`,
|
|
12422
13856
|
`- what should be adopted, adapted, or avoided: adopt layout hierarchy, adapt it to the new brand tokens, avoid copying proprietary copy or visual assets directly.`
|
|
12423
13857
|
].join("\n");
|
|
12424
13858
|
};
|
|
13859
|
+
var renderInspirationAnalysis = (references, usableReferences) => {
|
|
13860
|
+
if (usableReferences.length > 0) return usableReferences.map(renderReferenceMarkdown).join("\n\n");
|
|
13861
|
+
if (references.length > 0) {
|
|
13862
|
+
return "- Reference URLs were attempted, but no usable creative evidence was captured. See evidence.json for fetch/capture status.";
|
|
13863
|
+
}
|
|
13864
|
+
return "- No live inspiration source was provided. The system is derived entirely from the brief.";
|
|
13865
|
+
};
|
|
12425
13866
|
var renderGovernanceMarkdown = (designContract, implementationPlan, format) => {
|
|
12426
13867
|
const generationPlan = designContract.generationPlan;
|
|
12427
13868
|
const profileConfig = PROFILE_CONFIG[generationPlan.visualDirection.profile];
|
|
@@ -12516,7 +13957,7 @@ var renderGovernanceMarkdown = (designContract, implementationPlan, format) => {
|
|
|
12516
13957
|
"Do encode repeated visual rules into semantic tokens.",
|
|
12517
13958
|
"Don't copy proprietary logos, screenshots, or brand-only illustrations.",
|
|
12518
13959
|
"Don't hide important actions inside ambiguous hover-only affordances.",
|
|
12519
|
-
...format.antiPatterns.map(
|
|
13960
|
+
...format.antiPatterns.map(renderAntiPatternRule)
|
|
12520
13961
|
]),
|
|
12521
13962
|
"",
|
|
12522
13963
|
"## 4.15 Acceptance Criteria",
|
|
@@ -12539,39 +13980,79 @@ var renderImplementationMarkdown = (implementationPlan) => {
|
|
|
12539
13980
|
"",
|
|
12540
13981
|
formatRecordList(implementationPlan.tokenStrategy.typography),
|
|
12541
13982
|
"",
|
|
12542
|
-
"## 5.3
|
|
13983
|
+
"## 5.3 Reference Implementation Notes",
|
|
13984
|
+
formatBulletList2(implementationPlan.referenceImplementationNotes),
|
|
13985
|
+
"",
|
|
13986
|
+
"## 5.4 Component Build Plan",
|
|
12543
13987
|
implementationPlan.componentBuildPlan.map((component, index) => `${index + 1}. ${component.name}: ${component.purpose}`).join("\n"),
|
|
12544
13988
|
"",
|
|
12545
|
-
"## 5.
|
|
13989
|
+
"## 5.5 Page Assembly Plan",
|
|
12546
13990
|
formatBulletList2(implementationPlan.pageAssemblyPlan),
|
|
12547
13991
|
"",
|
|
12548
|
-
"## 5.
|
|
13992
|
+
"## 5.6 State and Interaction Plan",
|
|
12549
13993
|
formatBulletList2(implementationPlan.stateAndInteractionPlan),
|
|
12550
13994
|
"",
|
|
12551
|
-
"## 5.
|
|
13995
|
+
"## 5.7 Accessibility Implementation Checklist",
|
|
12552
13996
|
formatBulletList2(implementationPlan.accessibilityChecklist),
|
|
12553
13997
|
"",
|
|
12554
|
-
"## 5.
|
|
13998
|
+
"## 5.8 Responsive Implementation Checklist",
|
|
12555
13999
|
formatBulletList2(implementationPlan.responsiveChecklist),
|
|
12556
14000
|
"",
|
|
12557
|
-
"## 5.
|
|
14001
|
+
"## 5.9 Risks and Ambiguities",
|
|
12558
14002
|
formatBulletList2(implementationPlan.risksAndAmbiguities),
|
|
12559
14003
|
"",
|
|
12560
|
-
"## 5.
|
|
14004
|
+
"## 5.10 Recommended Build Sequence",
|
|
12561
14005
|
implementationPlan.buildSequence.map((step, index) => `${index + 1}. ${step}`).join("\n")
|
|
12562
14006
|
].join("\n");
|
|
12563
14007
|
};
|
|
12564
|
-
var
|
|
14008
|
+
var renderTargetAnalysisGuidance = (targetAnalysis) => {
|
|
14009
|
+
const targetGuidance = [
|
|
14010
|
+
...targetAnalysis.page?.implementationNotes ?? [],
|
|
14011
|
+
...targetAnalysis.component?.prototypeGuidance ?? [],
|
|
14012
|
+
...targetAnalysis.asset?.prototypeGuidance ?? []
|
|
14013
|
+
];
|
|
14014
|
+
return [
|
|
14015
|
+
"## 6.3 Target Analysis",
|
|
14016
|
+
formatBulletList2([
|
|
14017
|
+
`primary target: ${targetAnalysis.primaryKind}`,
|
|
14018
|
+
`target kinds: ${targetAnalysis.kinds.join(", ")}`,
|
|
14019
|
+
`confidence: ${targetAnalysis.confidence.toFixed(2)}`,
|
|
14020
|
+
`triggering signals: ${targetAnalysis.triggeringSignals.join("; ")}`,
|
|
14021
|
+
...targetGuidance,
|
|
14022
|
+
`anatomy: ${targetAnalysis.evidenceBuckets.anatomy.join(" ")}`,
|
|
14023
|
+
`props/slots: ${targetAnalysis.evidenceBuckets.propsSlots.join(" ")}`,
|
|
14024
|
+
`state matrix: ${targetAnalysis.evidenceBuckets.stateMatrix.join(" ")}`,
|
|
14025
|
+
`tokens: ${targetAnalysis.evidenceBuckets.tokens.join(" ")}`,
|
|
14026
|
+
`assets: ${targetAnalysis.evidenceBuckets.assets.join(" ")}`,
|
|
14027
|
+
`accessibility: ${targetAnalysis.evidenceBuckets.accessibility.join(" ")}`,
|
|
14028
|
+
`motion: ${targetAnalysis.evidenceBuckets.motion.join(" ")}`,
|
|
14029
|
+
`preview fixtures: ${targetAnalysis.evidenceBuckets.previewFixtures.join(" ")}`
|
|
14030
|
+
])
|
|
14031
|
+
].join("\n");
|
|
14032
|
+
};
|
|
14033
|
+
var renderPrototypeGuidance = (profile, synthesis, designVectors, targetAnalysis) => {
|
|
12565
14034
|
return [
|
|
12566
14035
|
"# 6. Optional Prototype Plan",
|
|
12567
14036
|
"",
|
|
12568
|
-
"
|
|
14037
|
+
"## 6.1 Reference Anchors",
|
|
14038
|
+
formatBulletList2(synthesis.lines.length > 0 ? synthesis.lines : ["No live reference cues were captured."]),
|
|
14039
|
+
"",
|
|
14040
|
+
"## 6.2 Prototype Structure",
|
|
14041
|
+
"- page structure: for public landing pages, build 8 to 12 content-rich sections unless the brief explicitly asks for a microsite.",
|
|
14042
|
+
`- section architecture: ${designVectors.sectionArchitecture.join(" ")}`,
|
|
12569
14043
|
`- section order: ${PROFILE_CONFIG[profile].pagePatterns.join(" -> ")}`,
|
|
12570
14044
|
"- component composition: reuse button, card, input, and navigation primitives before page-specific wrappers.",
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
14045
|
+
`- interaction expectations: ${designVectors.interactionMoments.join(" ")}`,
|
|
14046
|
+
`- motion expectations: ${designVectors.motionPosture.join(" ")}`,
|
|
14047
|
+
`- material and depth expectations: ${designVectors.materialEffects.join(" ")}`,
|
|
14048
|
+
`- advisory advanced motion: ${designVectors.advancedMotionAdvisory.join(" ")}`,
|
|
14049
|
+
"",
|
|
14050
|
+
renderTargetAnalysisGuidance(targetAnalysis),
|
|
14051
|
+
"",
|
|
14052
|
+
"- browser proof: capture desktop and mobile browser screenshots, verify reduced-motion behavior, inspect focus states, and confirm the primary CTA remains visible without overlap.",
|
|
14053
|
+
"- HTML skeleton guidance: start with one main landmark, one primary CTA group, and semantic sections that follow the design vector section architecture instead of fixed industry-specific defaults.",
|
|
14054
|
+
"- styling approach: define CSS variables for timing, easing, elevation, translucency, backdrop blur, cursor effects, hover effects, and parallax distance before mapping components to semantic tokens.",
|
|
14055
|
+
"- first prototype should include vs omit: include shell, primary hero or decision section, CTA group, proof or detail sections, section patterns named in the design vectors, final CTA, and footer; omit analytics, app-shell widgets, empty card grids, and any section not supported by the brief or reference evidence."
|
|
12575
14056
|
].join("\n");
|
|
12576
14057
|
};
|
|
12577
14058
|
var renderDeliverablesSummary = (includePrototypeGuidance) => {
|
|
@@ -12589,27 +14070,38 @@ var renderDeliverablesSummary = (includePrototypeGuidance) => {
|
|
|
12589
14070
|
deliverables.push("Evidence digest describing brief, references, fetch outcomes, and capture outcomes");
|
|
12590
14071
|
return formatBulletList2(deliverables);
|
|
12591
14072
|
};
|
|
12592
|
-
var buildEvidencePayload = (
|
|
14073
|
+
var buildEvidencePayload = ({
|
|
14074
|
+
brief,
|
|
14075
|
+
briefExpansion,
|
|
14076
|
+
advancedBriefMarkdown,
|
|
14077
|
+
urls,
|
|
14078
|
+
references,
|
|
14079
|
+
referencePatternBoard,
|
|
14080
|
+
designVectors,
|
|
14081
|
+
targetAnalysis
|
|
14082
|
+
}) => ({
|
|
12593
14083
|
brief,
|
|
12594
14084
|
briefHash: referenceFingerprint(brief),
|
|
12595
|
-
advancedBrief:
|
|
12596
|
-
advancedBriefHash: referenceFingerprint(
|
|
14085
|
+
advancedBrief: advancedBriefMarkdown,
|
|
14086
|
+
advancedBriefHash: referenceFingerprint(advancedBriefMarkdown),
|
|
12597
14087
|
briefExpansion: {
|
|
12598
14088
|
templateVersion: briefExpansion.templateVersion,
|
|
12599
14089
|
format: cloneInspiredesignBriefFormat(briefExpansion.format)
|
|
12600
14090
|
},
|
|
12601
14091
|
urls,
|
|
12602
14092
|
referenceCount: references.length,
|
|
12603
|
-
references: references.map((reference) => toReferenceEvidenceJson(reference))
|
|
14093
|
+
references: references.map((reference) => toReferenceEvidenceJson(reference)),
|
|
14094
|
+
referencePatternBoard,
|
|
14095
|
+
designVectors,
|
|
14096
|
+
targetAnalysis
|
|
12604
14097
|
});
|
|
12605
|
-
var toCaptureEvidenceJson = (
|
|
12606
|
-
const normalized = normalizeInspiredesignCaptureEvidence(capture);
|
|
14098
|
+
var toCaptureEvidenceJson = (reference) => {
|
|
14099
|
+
const normalized = normalizeInspiredesignCaptureEvidence(reference.capture);
|
|
12607
14100
|
if (!normalized) return null;
|
|
14101
|
+
const signals = getInspiredesignReferenceSignals(reference);
|
|
12608
14102
|
return {
|
|
12609
14103
|
...normalized.title ? { title: normalized.title } : {},
|
|
12610
|
-
...
|
|
12611
|
-
...normalized.dom ? { dom: normalized.dom } : {},
|
|
12612
|
-
...normalized.clone ? { clone: normalized.clone } : {},
|
|
14104
|
+
...signals.length > 0 ? { signals } : {},
|
|
12613
14105
|
...normalized.attempts ? { attempts: normalized.attempts } : {}
|
|
12614
14106
|
};
|
|
12615
14107
|
};
|
|
@@ -12622,33 +14114,87 @@ var toReferenceEvidenceJson = (reference) => ({
|
|
|
12622
14114
|
captureStatus: reference.captureStatus,
|
|
12623
14115
|
...reference.fetchFailure ? { fetchFailure: reference.fetchFailure } : {},
|
|
12624
14116
|
...reference.captureFailure ? { captureFailure: reference.captureFailure } : {},
|
|
12625
|
-
capture: toCaptureEvidenceJson(reference
|
|
14117
|
+
capture: toCaptureEvidenceJson(reference)
|
|
12626
14118
|
});
|
|
12627
14119
|
var buildInspiredesignPacket = (input) => {
|
|
12628
|
-
const brief =
|
|
14120
|
+
const brief = trimText2(input.brief);
|
|
12629
14121
|
const selectedFormat = cloneInspiredesignBriefFormat(input.briefExpansion.format);
|
|
12630
|
-
const
|
|
12631
|
-
const urls = [...new Set(input.urls.map((url) =>
|
|
14122
|
+
const includePrototypeGuidance = input.includePrototypeGuidance ?? false;
|
|
14123
|
+
const urls = [...new Set(input.urls.map((url) => trimText2(url)).filter(Boolean))];
|
|
12632
14124
|
const references = input.references.map((reference) => ({
|
|
12633
14125
|
...reference,
|
|
12634
|
-
title: reference.title ?
|
|
12635
|
-
excerpt: reference.excerpt ?
|
|
14126
|
+
title: reference.title ? trimText2(reference.title) : void 0,
|
|
14127
|
+
excerpt: reference.excerpt ? trimText2(reference.excerpt) : void 0
|
|
12636
14128
|
}));
|
|
12637
|
-
const
|
|
14129
|
+
const usableReferences = references.filter(hasInspiredesignUsableReferenceEvidence);
|
|
14130
|
+
const synthesis = buildReferenceSynthesis(usableReferences);
|
|
14131
|
+
const referencePatternBoard = buildInspiredesignReferencePatternBoard(
|
|
14132
|
+
referenceFingerprint(brief),
|
|
14133
|
+
selectedFormat,
|
|
14134
|
+
references
|
|
14135
|
+
);
|
|
14136
|
+
const designVectors = buildInspiredesignDesignVectors(selectedFormat, referencePatternBoard);
|
|
14137
|
+
const effectiveFormat = buildEvidenceDerivedFormat(selectedFormat, designVectors);
|
|
14138
|
+
const targetAnalysis = buildTargetAnalysis(
|
|
14139
|
+
brief,
|
|
14140
|
+
effectiveFormat,
|
|
14141
|
+
references,
|
|
14142
|
+
synthesis,
|
|
14143
|
+
designVectors
|
|
14144
|
+
);
|
|
14145
|
+
const effectiveBriefExpansion = {
|
|
14146
|
+
...input.briefExpansion,
|
|
14147
|
+
advancedBrief: isReferenceFirstPublicLanding(designVectors) ? renderEvidenceDerivedAdvancedBrief(input.briefExpansion, effectiveFormat) : input.briefExpansion.advancedBrief,
|
|
14148
|
+
format: effectiveFormat
|
|
14149
|
+
};
|
|
14150
|
+
const advancedBriefMarkdown = renderReferenceFirstAdvancedBrief(
|
|
14151
|
+
effectiveBriefExpansion,
|
|
14152
|
+
referencePatternBoard,
|
|
14153
|
+
designVectors,
|
|
14154
|
+
references
|
|
14155
|
+
);
|
|
14156
|
+
const generationPlan = buildGenerationPlan({
|
|
14157
|
+
brief,
|
|
14158
|
+
format: effectiveFormat,
|
|
14159
|
+
synthesis,
|
|
14160
|
+
referencePatternBoard,
|
|
14161
|
+
designVectors,
|
|
14162
|
+
targetAnalysis
|
|
14163
|
+
});
|
|
12638
14164
|
const profile = generationPlan.visualDirection.profile;
|
|
12639
14165
|
const canvasPlanRequest = buildCanvasPlanRequest(brief, generationPlan);
|
|
12640
|
-
const designContract = buildDesignContract(
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
14166
|
+
const designContract = buildDesignContract({
|
|
14167
|
+
brief,
|
|
14168
|
+
urls,
|
|
14169
|
+
references,
|
|
14170
|
+
plan: generationPlan,
|
|
14171
|
+
format: effectiveFormat
|
|
14172
|
+
});
|
|
14173
|
+
const followthrough = buildFollowthrough({
|
|
14174
|
+
generationPlan,
|
|
14175
|
+
briefExpansion: effectiveBriefExpansion,
|
|
14176
|
+
synthesis,
|
|
14177
|
+
includePrototypeGuidance,
|
|
14178
|
+
referencePatternBoard,
|
|
14179
|
+
designVectors,
|
|
14180
|
+
targetAnalysis
|
|
14181
|
+
});
|
|
14182
|
+
const implementationPlan = buildImplementationPlan({
|
|
14183
|
+
profile,
|
|
14184
|
+
format: effectiveFormat,
|
|
14185
|
+
references,
|
|
14186
|
+
synthesis,
|
|
14187
|
+
designVectors
|
|
14188
|
+
});
|
|
14189
|
+
const governanceMarkdown = renderGovernanceMarkdown(designContract, implementationPlan, effectiveFormat);
|
|
12644
14190
|
const implementationPlanMarkdown = renderImplementationMarkdown(implementationPlan);
|
|
12645
|
-
const prototypeGuidanceMarkdown =
|
|
14191
|
+
const prototypeGuidanceMarkdown = includePrototypeGuidance ? renderPrototypeGuidance(profile, synthesis, designVectors, targetAnalysis) : null;
|
|
12646
14192
|
const designMarkdown = [
|
|
12647
14193
|
"# 1. Executive Summary",
|
|
12648
14194
|
"",
|
|
12649
14195
|
formatBulletList2([
|
|
12650
14196
|
`Analyzed brief plus ${references.length || 0} inspiration reference(s).`,
|
|
12651
|
-
`Chosen design direction: ${
|
|
14197
|
+
`Chosen design direction: ${designVectors.surfaceIntent}.`,
|
|
12652
14198
|
`Route profile: ${PROFILE_CONFIG[profile].direction}.`,
|
|
12653
14199
|
`Prompt format: ${selectedFormat.label} (${input.briefExpansion.templateVersion}).`,
|
|
12654
14200
|
"Final outcome: a reusable design contract, engineering plan, and optional prototype guidance.",
|
|
@@ -12657,16 +14203,39 @@ var buildInspiredesignPacket = (input) => {
|
|
|
12657
14203
|
"",
|
|
12658
14204
|
"# 2. Inspiration Analysis",
|
|
12659
14205
|
"",
|
|
12660
|
-
references
|
|
14206
|
+
renderInspirationAnalysis(references, usableReferences),
|
|
12661
14207
|
"",
|
|
12662
14208
|
"# 3. Unified Design Direction",
|
|
12663
14209
|
"",
|
|
14210
|
+
"## 3.1 Reference-Specific Build Rules",
|
|
14211
|
+
"",
|
|
14212
|
+
formatBulletList2(synthesis.lines.length > 0 ? synthesis.lines : ["No live reference cues were captured."]),
|
|
14213
|
+
"",
|
|
14214
|
+
"## 3.2 Reference Pattern Board",
|
|
14215
|
+
"",
|
|
14216
|
+
formatBulletList2(referencePatternBoard.synthesis.sharedStrengths.length > 0 ? referencePatternBoard.synthesis.sharedStrengths : ["No live reference cues were captured."]),
|
|
14217
|
+
"",
|
|
14218
|
+
"## 3.3 Design Vectors",
|
|
14219
|
+
"",
|
|
14220
|
+
formatBulletList2([
|
|
14221
|
+
`source priority: ${designVectors.sourcePriority}`,
|
|
14222
|
+
`direction: ${designVectors.directionLabel}`,
|
|
14223
|
+
`premium posture: ${designVectors.premiumPosture.join(" ")}`,
|
|
14224
|
+
`motion posture: ${designVectors.motionPosture.join(" ")}`,
|
|
14225
|
+
`section architecture: ${designVectors.sectionArchitecture.join(" ")}`,
|
|
14226
|
+
`interaction moments: ${designVectors.interactionMoments.join(" ")}`,
|
|
14227
|
+
`material effects: ${designVectors.materialEffects.join(" ")}`,
|
|
14228
|
+
`advanced motion advisory: ${designVectors.advancedMotionAdvisory.join(" ")}`
|
|
14229
|
+
]),
|
|
14230
|
+
"",
|
|
14231
|
+
"## 3.4 System Direction",
|
|
14232
|
+
"",
|
|
12664
14233
|
formatBulletList2([
|
|
12665
14234
|
`visual personality: ${PROFILE_CONFIG[profile].visualPersonality}`,
|
|
12666
14235
|
`tone: ${PROFILE_CONFIG[profile].brandTone}`,
|
|
12667
|
-
`layout archetype: ${
|
|
12668
|
-
`typography system: ${
|
|
12669
|
-
`motion grammar: ${
|
|
14236
|
+
`layout archetype: ${effectiveFormat.layoutArchetype}`,
|
|
14237
|
+
`typography system: ${effectiveFormat.typographySystem}`,
|
|
14238
|
+
`motion grammar: ${effectiveFormat.motionGrammar}`,
|
|
12670
14239
|
`UX principles: ${PROFILE_CONFIG[profile].hierarchyPrinciples.join(" ")}`,
|
|
12671
14240
|
`interaction philosophy: ${PROFILE_CONFIG[profile].interactionPhilosophy}`,
|
|
12672
14241
|
"branding posture: preserve the intent of the references without cloning brand-only assets.",
|
|
@@ -12695,33 +14264,197 @@ var buildInspiredesignPacket = (input) => {
|
|
|
12695
14264
|
implementationPlan,
|
|
12696
14265
|
implementationPlanMarkdown,
|
|
12697
14266
|
prototypeGuidanceMarkdown,
|
|
12698
|
-
evidence: buildEvidencePayload(
|
|
14267
|
+
evidence: buildEvidencePayload({
|
|
14268
|
+
brief,
|
|
14269
|
+
briefExpansion: effectiveBriefExpansion,
|
|
14270
|
+
advancedBriefMarkdown,
|
|
14271
|
+
urls,
|
|
14272
|
+
references,
|
|
14273
|
+
referencePatternBoard,
|
|
14274
|
+
designVectors,
|
|
14275
|
+
targetAnalysis
|
|
14276
|
+
})
|
|
12699
14277
|
};
|
|
12700
14278
|
};
|
|
12701
14279
|
|
|
12702
|
-
// src/providers/
|
|
12703
|
-
var
|
|
12704
|
-
var
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
}
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
};
|
|
14280
|
+
// src/providers/workflow-handoff.ts
|
|
14281
|
+
var PRODUCT_VIDEO_BRIEF_HELPER_PATH = "./skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh";
|
|
14282
|
+
var PRODUCT_VIDEO_BRIEF_HELPER_COMMAND = `${PRODUCT_VIDEO_BRIEF_HELPER_PATH} <pack>/manifest.json`;
|
|
14283
|
+
var createSuccessHandoff = (followthroughSummary, suggestedNextAction, suggestedSteps) => ({
|
|
14284
|
+
followthroughSummary,
|
|
14285
|
+
suggestedNextAction,
|
|
14286
|
+
suggestedSteps
|
|
14287
|
+
});
|
|
14288
|
+
var cliExample = (command, args = "") => `npx opendevbrowser ${command}${args ? ` ${args}` : ""}`;
|
|
14289
|
+
var quoteCliValue = (value) => JSON.stringify(value);
|
|
14290
|
+
var buildResearchRerunCommand = (input) => cliExample(
|
|
14291
|
+
"research run",
|
|
14292
|
+
`--topic ${quoteCliValue(input.topic)} --days 14 --source-selection auto --sources web,community --browser-mode ${input.browserMode ?? "managed"} --mode json --output-format json`
|
|
14293
|
+
);
|
|
14294
|
+
var buildShoppingRerunCommand = (input) => {
|
|
14295
|
+
const providers = input.providers?.length ? ` --providers ${input.providers.join(",")}` : " --providers shopping/bestbuy,shopping/ebay";
|
|
14296
|
+
const budget = typeof input.budget === "number" ? ` --budget ${input.budget}` : "";
|
|
14297
|
+
const region = input.region ? ` --region ${quoteCliValue(input.region)}` : "";
|
|
14298
|
+
const browserMode = ` --browser-mode ${input.browserMode ?? "managed"}`;
|
|
14299
|
+
const sort = input.sort ? ` --sort ${input.sort}` : "";
|
|
14300
|
+
return cliExample(
|
|
14301
|
+
"shopping run",
|
|
14302
|
+
`--query ${quoteCliValue(input.query)}${providers}${budget}${region}${browserMode}${sort} --use-cookies --challenge-automation-mode browser_with_helper --mode json --output-format json`
|
|
14303
|
+
);
|
|
12722
14304
|
};
|
|
12723
|
-
var
|
|
12724
|
-
const
|
|
14305
|
+
var buildProductVideoRerunCommand = (input = {}) => {
|
|
14306
|
+
const target = input.productUrl ? `--product-url ${quoteCliValue(input.productUrl)}` : `--product-name ${quoteCliValue(input.productName ?? "<product-name>")}`;
|
|
14307
|
+
const providerHint = input.providerHint ? ` --provider-hint ${input.providerHint}` : "";
|
|
14308
|
+
const screenshots = input.includeScreenshots ? " --include-screenshots" : "";
|
|
14309
|
+
const allImages = input.includeAllImages ? " --include-all-images" : "";
|
|
14310
|
+
const includeCopy = input.includeCopy ? " --include-copy" : "";
|
|
14311
|
+
const browserMode = ` --browser-mode ${input.browserMode ?? "managed"}`;
|
|
14312
|
+
return cliExample(
|
|
14313
|
+
"product-video run",
|
|
14314
|
+
`${target}${providerHint}${screenshots}${allImages}${includeCopy}${browserMode} --use-cookies --challenge-automation-mode browser_with_helper --output-format json`
|
|
14315
|
+
);
|
|
14316
|
+
};
|
|
14317
|
+
var buildMacroResolveArgs = (input, options) => {
|
|
14318
|
+
const defaultProvider = input.defaultProvider ? ` --default-provider ${input.defaultProvider}` : "";
|
|
14319
|
+
const execute = options?.execute ? " --execute" : "";
|
|
14320
|
+
const browserMode = options?.browserMode ? ` --browser-mode ${options.browserMode}` : "";
|
|
14321
|
+
const challenge = options?.challengeAutomationMode ? ` --challenge-automation-mode ${options.challengeAutomationMode}` : "";
|
|
14322
|
+
const outputFormat = options?.includeOutputFormat === false ? "" : " --output-format json";
|
|
14323
|
+
return `--expression ${quoteCliValue(input.expression)}${defaultProvider}${execute}${browserMode}${challenge}${outputFormat}`;
|
|
14324
|
+
};
|
|
14325
|
+
var buildMacroPreviewCommand = (input) => cliExample("macro-resolve", buildMacroResolveArgs(input));
|
|
14326
|
+
var buildMacroExecuteCommand = (input, challengeAutomationMode, browserMode) => cliExample("macro-resolve", buildMacroResolveArgs(input, {
|
|
14327
|
+
execute: true,
|
|
14328
|
+
browserMode,
|
|
14329
|
+
challengeAutomationMode
|
|
14330
|
+
}));
|
|
14331
|
+
var buildResearchSuccessHandoff = (input) => {
|
|
14332
|
+
const rerunCommand = buildResearchRerunCommand(input);
|
|
14333
|
+
return createSuccessHandoff(
|
|
14334
|
+
"Review the ranked records and artifact bundle before turning the result into a publishable claim.",
|
|
14335
|
+
`Open the returned artifact path, inspect the supporting records, and rerun ${rerunCommand} if you need a tighter evidence set.`,
|
|
14336
|
+
[
|
|
14337
|
+
{ reason: "Check which records actually support the final claim." },
|
|
14338
|
+
{
|
|
14339
|
+
reason: "Rerun with explicit sources and a narrower timebox if the evidence set is still too broad.",
|
|
14340
|
+
command: rerunCommand
|
|
14341
|
+
}
|
|
14342
|
+
]
|
|
14343
|
+
);
|
|
14344
|
+
};
|
|
14345
|
+
var buildShoppingSuccessHandoff = (input) => {
|
|
14346
|
+
const rerunCommand = buildShoppingRerunCommand(input);
|
|
14347
|
+
return createSuccessHandoff(
|
|
14348
|
+
"Review the offer set and diagnostics before calling any result a strong deal.",
|
|
14349
|
+
`Inspect the offers and meta.offerFilterDiagnostics, then rerun ${rerunCommand} if you need a tighter comparison.`,
|
|
14350
|
+
[
|
|
14351
|
+
{ reason: "Check which offers survived the workflow filters and why." },
|
|
14352
|
+
{
|
|
14353
|
+
reason: "Rerun with explicit providers or updated budget and region inputs if the comparison is still noisy.",
|
|
14354
|
+
command: rerunCommand
|
|
14355
|
+
}
|
|
14356
|
+
]
|
|
14357
|
+
);
|
|
14358
|
+
};
|
|
14359
|
+
var buildProductVideoSuccessHandoff = (input = {}) => {
|
|
14360
|
+
const rerunCommand = buildProductVideoRerunCommand(input);
|
|
14361
|
+
return createSuccessHandoff(
|
|
14362
|
+
"Review the generated asset pack to confirm whether it is visual-ready or metadata-first before briefing production.",
|
|
14363
|
+
"Open the returned pack path, inspect manifest.json plus copy and features, then run the product-video brief helper with that manifest path to generate production briefs and sourcing notes.",
|
|
14364
|
+
[
|
|
14365
|
+
{ reason: "Confirm whether the pack already includes enough images or screenshots for production." },
|
|
14366
|
+
{
|
|
14367
|
+
reason: "Run the product-presentation-asset brief helper on manifest.json to generate the production brief files.",
|
|
14368
|
+
command: PRODUCT_VIDEO_BRIEF_HELPER_COMMAND
|
|
14369
|
+
},
|
|
14370
|
+
{
|
|
14371
|
+
reason: "Rerun the asset workflow with adjusted provider or media flags when the current pack is too thin.",
|
|
14372
|
+
command: rerunCommand
|
|
14373
|
+
},
|
|
14374
|
+
{ reason: "Source or capture visuals before final handoff if the pack is metadata-first." }
|
|
14375
|
+
]
|
|
14376
|
+
);
|
|
14377
|
+
};
|
|
14378
|
+
var buildMacroResolveSuccessHandoff = (input) => {
|
|
14379
|
+
const previewCommand = buildMacroPreviewCommand(input);
|
|
14380
|
+
const executeCommand = buildMacroExecuteCommand(input);
|
|
14381
|
+
const browserRetryCommand = buildMacroExecuteCommand(input, "browser_with_helper", "extension");
|
|
14382
|
+
if (!input.execute) {
|
|
14383
|
+
return createSuccessHandoff(
|
|
14384
|
+
"Review the resolved provider action and provenance before executing the macro.",
|
|
14385
|
+
`Run ${executeCommand} when the resolved action looks correct.`,
|
|
14386
|
+
[
|
|
14387
|
+
{ reason: "Inspect resolution.action and resolution.provenance to confirm provider and query shaping." },
|
|
14388
|
+
{ reason: "Execute the resolved macro once the plan looks correct.", command: executeCommand },
|
|
14389
|
+
{ reason: "Add --default-provider only when you need to force a different provider lane.", command: previewCommand }
|
|
14390
|
+
]
|
|
14391
|
+
);
|
|
14392
|
+
}
|
|
14393
|
+
if (input.blocked) {
|
|
14394
|
+
return createSuccessHandoff(
|
|
14395
|
+
"Review execution.meta.blocker and failures before retrying the macro.",
|
|
14396
|
+
`Run ${browserRetryCommand} after checking execution.meta.blocker and the current recovery path.`,
|
|
14397
|
+
[
|
|
14398
|
+
{ reason: "Inspect execution.meta.blocker and execution.failures before retrying." },
|
|
14399
|
+
{ reason: "Retry with browser-scoped challenge automation when the blocker requires live follow-up.", command: browserRetryCommand },
|
|
14400
|
+
{ reason: "Preview the resolved action again if you need to switch providers before another execute attempt.", command: previewCommand }
|
|
14401
|
+
]
|
|
14402
|
+
);
|
|
14403
|
+
}
|
|
14404
|
+
return createSuccessHandoff(
|
|
14405
|
+
"Review execution.records and trace metadata before widening the macro or changing providers.",
|
|
14406
|
+
`Inspect execution.records and execution.meta, then rerun ${previewCommand} if you need a narrower plan.`,
|
|
14407
|
+
[
|
|
14408
|
+
{ reason: "Inspect execution.records and execution.meta to confirm the resolved action hit the expected lane." },
|
|
14409
|
+
{ reason: "Preview the macro again before changing providers or expression scope.", command: previewCommand },
|
|
14410
|
+
{ reason: "Re-execute with browser-scoped challenge automation when the target requires live browser recovery.", command: browserRetryCommand }
|
|
14411
|
+
]
|
|
14412
|
+
);
|
|
14413
|
+
};
|
|
14414
|
+
var buildInspiredesignSuccessHandoff = (input) => createSuccessHandoff(
|
|
14415
|
+
input.summary,
|
|
14416
|
+
input.nextStep,
|
|
14417
|
+
[
|
|
14418
|
+
{ reason: INSPIREDESIGN_HANDOFF_GUIDANCE.reviewAdvancedBrief },
|
|
14419
|
+
{
|
|
14420
|
+
reason: "Load the baseline workflow runbook before implementation.",
|
|
14421
|
+
command: input.commandExamples.loadBestPractices
|
|
14422
|
+
},
|
|
14423
|
+
{
|
|
14424
|
+
reason: "Load the Canvas contract lane before patching.",
|
|
14425
|
+
command: input.commandExamples.loadDesignAgent
|
|
14426
|
+
},
|
|
14427
|
+
{
|
|
14428
|
+
reason: INSPIREDESIGN_HANDOFF_GUIDANCE.prepareCanvasPlanRequest,
|
|
14429
|
+
command: input.commandExamples.continueInCanvas
|
|
14430
|
+
},
|
|
14431
|
+
{ reason: input.deepCaptureRecommendation }
|
|
14432
|
+
]
|
|
14433
|
+
);
|
|
14434
|
+
|
|
14435
|
+
// src/providers/renderer.ts
|
|
14436
|
+
var toCurrency = (value) => `$${value.toFixed(2)}`;
|
|
14437
|
+
var primaryConstraintSummaryFromMeta = (meta) => {
|
|
14438
|
+
const summary = meta.primaryConstraintSummary;
|
|
14439
|
+
return typeof summary === "string" && summary.trim().length > 0 ? summary.trim() : null;
|
|
14440
|
+
};
|
|
14441
|
+
var isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
14442
|
+
var inspiredesignCaptureAttemptReportFromMeta = (meta) => {
|
|
14443
|
+
const report = meta.captureAttemptReport;
|
|
14444
|
+
if (typeof report !== "object" || report === null || Array.isArray(report)) {
|
|
14445
|
+
return null;
|
|
14446
|
+
}
|
|
14447
|
+
const candidate = report;
|
|
14448
|
+
if (!isStringArray(candidate.worked) || !isStringArray(candidate.didNotWork)) {
|
|
14449
|
+
return null;
|
|
14450
|
+
}
|
|
14451
|
+
return {
|
|
14452
|
+
worked: candidate.worked,
|
|
14453
|
+
didNotWork: candidate.didNotWork
|
|
14454
|
+
};
|
|
14455
|
+
};
|
|
14456
|
+
var inspiredesignCaptureAttemptSummaryFromMeta = (meta) => {
|
|
14457
|
+
const summary = meta.captureAttemptSummary;
|
|
12725
14458
|
if (typeof summary === "string" && summary.trim().length > 0) {
|
|
12726
14459
|
return summary.trim();
|
|
12727
14460
|
}
|
|
@@ -12962,26 +14695,12 @@ var renderInspiredesign = (args) => {
|
|
|
12962
14695
|
evidence: args.evidence,
|
|
12963
14696
|
meta: args.meta
|
|
12964
14697
|
};
|
|
12965
|
-
const
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
command: args.designAgentHandoff.commandExamples.loadBestPractices
|
|
12972
|
-
},
|
|
12973
|
-
{
|
|
12974
|
-
reason: "Load the Canvas contract lane before patching.",
|
|
12975
|
-
command: args.designAgentHandoff.commandExamples.loadDesignAgent
|
|
12976
|
-
},
|
|
12977
|
-
{
|
|
12978
|
-
reason: INSPIREDESIGN_HANDOFF_GUIDANCE.prepareCanvasPlanRequest,
|
|
12979
|
-
command: args.designAgentHandoff.commandExamples.continueInCanvas
|
|
12980
|
-
},
|
|
12981
|
-
{
|
|
12982
|
-
reason: args.designAgentHandoff.deepCaptureRecommendation
|
|
12983
|
-
}
|
|
12984
|
-
];
|
|
14698
|
+
const handoff = buildInspiredesignSuccessHandoff({
|
|
14699
|
+
summary: followthroughSummary,
|
|
14700
|
+
nextStep: args.designAgentHandoff.nextStep,
|
|
14701
|
+
commandExamples: args.designAgentHandoff.commandExamples,
|
|
14702
|
+
deepCaptureRecommendation: args.designAgentHandoff.deepCaptureRecommendation
|
|
14703
|
+
});
|
|
12985
14704
|
const files = [
|
|
12986
14705
|
{ path: INSPIREDESIGN_HANDOFF_FILES.designMarkdown, content: args.designMarkdown },
|
|
12987
14706
|
{ path: INSPIREDESIGN_HANDOFF_FILES.advancedBrief, content: args.advancedBriefMarkdown },
|
|
@@ -13005,9 +14724,7 @@ var renderInspiredesign = (args) => {
|
|
|
13005
14724
|
response: {
|
|
13006
14725
|
mode: args.mode,
|
|
13007
14726
|
summary,
|
|
13008
|
-
|
|
13009
|
-
suggestedNextAction: args.designAgentHandoff.nextStep,
|
|
13010
|
-
suggestedSteps,
|
|
14727
|
+
...handoff,
|
|
13011
14728
|
...captureAttemptFields,
|
|
13012
14729
|
meta: args.meta
|
|
13013
14730
|
},
|
|
@@ -13028,9 +14745,7 @@ var renderInspiredesign = (args) => {
|
|
|
13028
14745
|
implementationPlan: args.implementationPlan,
|
|
13029
14746
|
prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
|
|
13030
14747
|
evidence: args.evidence,
|
|
13031
|
-
|
|
13032
|
-
suggestedNextAction: args.designAgentHandoff.nextStep,
|
|
13033
|
-
suggestedSteps,
|
|
14748
|
+
...handoff,
|
|
13034
14749
|
...captureAttemptFields,
|
|
13035
14750
|
meta: args.meta
|
|
13036
14751
|
},
|
|
@@ -13044,9 +14759,7 @@ var renderInspiredesign = (args) => {
|
|
|
13044
14759
|
markdown: args.designMarkdown,
|
|
13045
14760
|
implementationPlanMarkdown: args.implementationPlanMarkdown,
|
|
13046
14761
|
prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
|
|
13047
|
-
|
|
13048
|
-
suggestedNextAction: args.designAgentHandoff.nextStep,
|
|
13049
|
-
suggestedSteps,
|
|
14762
|
+
...handoff,
|
|
13050
14763
|
...captureAttemptFields,
|
|
13051
14764
|
meta: args.meta
|
|
13052
14765
|
},
|
|
@@ -13058,9 +14771,7 @@ var renderInspiredesign = (args) => {
|
|
|
13058
14771
|
response: {
|
|
13059
14772
|
mode: args.mode,
|
|
13060
14773
|
context: contextPayload,
|
|
13061
|
-
|
|
13062
|
-
suggestedNextAction: args.designAgentHandoff.nextStep,
|
|
13063
|
-
suggestedSteps,
|
|
14774
|
+
...handoff,
|
|
13064
14775
|
...captureAttemptFields,
|
|
13065
14776
|
meta: args.meta
|
|
13066
14777
|
},
|
|
@@ -13070,9 +14781,7 @@ var renderInspiredesign = (args) => {
|
|
|
13070
14781
|
return {
|
|
13071
14782
|
response: {
|
|
13072
14783
|
mode: "path",
|
|
13073
|
-
|
|
13074
|
-
suggestedNextAction: args.designAgentHandoff.nextStep,
|
|
13075
|
-
suggestedSteps,
|
|
14784
|
+
...handoff,
|
|
13076
14785
|
...captureAttemptFields,
|
|
13077
14786
|
meta: args.meta
|
|
13078
14787
|
},
|
|
@@ -13093,251 +14802,119 @@ var CANVAS_GOVERNANCE_BLOCK_KEYS = [
|
|
|
13093
14802
|
"colorSystem",
|
|
13094
14803
|
"surfaceSystem",
|
|
13095
14804
|
"iconSystem",
|
|
13096
|
-
"motionSystem",
|
|
13097
|
-
"responsiveSystem",
|
|
13098
|
-
"accessibilityPolicy",
|
|
13099
|
-
"libraryPolicy",
|
|
13100
|
-
"runtimeBudgets"
|
|
13101
|
-
];
|
|
13102
|
-
var CANVAS_REQUIRED_MUTATION_GOVERNANCE_KEYS = [
|
|
13103
|
-
"intent",
|
|
13104
|
-
"generationPlan",
|
|
13105
|
-
"designLanguage",
|
|
13106
|
-
"contentModel",
|
|
13107
|
-
"layoutSystem",
|
|
13108
|
-
"typographySystem",
|
|
13109
|
-
"motionSystem",
|
|
13110
|
-
"responsiveSystem",
|
|
13111
|
-
"accessibilityPolicy"
|
|
13112
|
-
];
|
|
13113
|
-
var CANVAS_REQUIRED_SAVE_GOVERNANCE_KEYS = [
|
|
13114
|
-
"intent",
|
|
13115
|
-
"generationPlan",
|
|
13116
|
-
"designLanguage",
|
|
13117
|
-
"contentModel",
|
|
13118
|
-
"layoutSystem",
|
|
13119
|
-
"typographySystem",
|
|
13120
|
-
"colorSystem",
|
|
13121
|
-
"surfaceSystem",
|
|
13122
|
-
"iconSystem",
|
|
13123
|
-
"motionSystem",
|
|
13124
|
-
"responsiveSystem",
|
|
13125
|
-
"accessibilityPolicy",
|
|
13126
|
-
"libraryPolicy",
|
|
13127
|
-
"runtimeBudgets"
|
|
13128
|
-
];
|
|
13129
|
-
var CANVAS_OPTIONAL_INHERITED_GOVERNANCE_KEYS = [
|
|
13130
|
-
"colorSystem",
|
|
13131
|
-
"surfaceSystem",
|
|
13132
|
-
"iconSystem",
|
|
13133
|
-
"libraryPolicy",
|
|
13134
|
-
"runtimeBudgets"
|
|
13135
|
-
];
|
|
13136
|
-
var CANVAS_GENERATION_PLAN_REQUIRED_FIELDS = [
|
|
13137
|
-
"targetOutcome",
|
|
13138
|
-
"visualDirection",
|
|
13139
|
-
"layoutStrategy",
|
|
13140
|
-
"contentStrategy",
|
|
13141
|
-
"componentStrategy",
|
|
13142
|
-
"motionPosture",
|
|
13143
|
-
"responsivePosture",
|
|
13144
|
-
"accessibilityPosture",
|
|
13145
|
-
"validationTargets"
|
|
13146
|
-
];
|
|
13147
|
-
var CANVAS_VISUAL_DIRECTION_PROFILES = [
|
|
13148
|
-
"clean-room",
|
|
13149
|
-
"cinematic-minimal",
|
|
13150
|
-
"product-story",
|
|
13151
|
-
"commerce-system",
|
|
13152
|
-
"control-room",
|
|
13153
|
-
"ops-control",
|
|
13154
|
-
"auth-focused",
|
|
13155
|
-
"settings-system",
|
|
13156
|
-
"documentation"
|
|
13157
|
-
];
|
|
13158
|
-
var CANVAS_THEME_STRATEGIES = ["single-theme", "light-dark-parity", "multi-theme-system"];
|
|
13159
|
-
var CANVAS_NAVIGATION_MODELS = ["global-header", "sidebar", "tabbed", "contextual", "immersive"];
|
|
13160
|
-
var CANVAS_INTERACTION_STATES = [
|
|
13161
|
-
"default",
|
|
13162
|
-
"hover",
|
|
13163
|
-
"focus",
|
|
13164
|
-
"active",
|
|
13165
|
-
"disabled",
|
|
13166
|
-
"loading",
|
|
13167
|
-
"empty",
|
|
13168
|
-
"error",
|
|
13169
|
-
"success",
|
|
13170
|
-
"selected"
|
|
13171
|
-
];
|
|
13172
|
-
var CANVAS_PLAN_VIEWPORTS = ["desktop", "tablet", "mobile"];
|
|
13173
|
-
var CANVAS_PLAN_THEMES = ["light", "dark"];
|
|
13174
|
-
var CANVAS_MOTION_LEVELS = ["none", "minimal", "subtle", "expressive"];
|
|
13175
|
-
var CANVAS_REDUCED_MOTION_POLICIES = ["respect-user-preference", "static-alternative"];
|
|
13176
|
-
var CANVAS_KEYBOARD_NAVIGATION_MODES = ["full", "core-flows"];
|
|
13177
|
-
var CANVAS_BROWSER_VALIDATION_MODES = ["required", "optional"];
|
|
13178
|
-
var CANVAS_VALIDATION_TARGET_BLOCK_ON_CODES = [
|
|
13179
|
-
"missing-generation-plan",
|
|
13180
|
-
"invalid-generation-plan",
|
|
13181
|
-
"missing-governance-block",
|
|
13182
|
-
"missing-intent",
|
|
13183
|
-
"missing-design-language",
|
|
13184
|
-
"missing-content-model",
|
|
13185
|
-
"missing-typography-system",
|
|
13186
|
-
"missing-color-role",
|
|
13187
|
-
"missing-surface-policy",
|
|
13188
|
-
"missing-state-coverage",
|
|
13189
|
-
"missing-reduced-motion-policy",
|
|
13190
|
-
"missing-responsive-policy",
|
|
13191
|
-
"overflow",
|
|
13192
|
-
"token-missing",
|
|
13193
|
-
"broken-asset-reference",
|
|
13194
|
-
"contrast-failure",
|
|
13195
|
-
"hierarchy-weak",
|
|
13196
|
-
"asset-provenance-missing",
|
|
13197
|
-
"font-policy-missing",
|
|
13198
|
-
"font-load-failure",
|
|
13199
|
-
"reduced-motion-violation",
|
|
13200
|
-
"unresolved-component-binding",
|
|
13201
|
-
"icon-policy-violation",
|
|
13202
|
-
"library-policy-violation",
|
|
13203
|
-
"responsive-mismatch",
|
|
13204
|
-
"runtime-budget-exceeded",
|
|
13205
|
-
"unsupported-target",
|
|
13206
|
-
"export-warning"
|
|
13207
|
-
];
|
|
13208
|
-
var CANVAS_PUBLIC_WARNING_CLASSES = CANVAS_VALIDATION_TARGET_BLOCK_ON_CODES;
|
|
13209
|
-
|
|
13210
|
-
// src/providers/workflow-handoff.ts
|
|
13211
|
-
var PRODUCT_VIDEO_BRIEF_HELPER_PATH = "./skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh";
|
|
13212
|
-
var PRODUCT_VIDEO_BRIEF_HELPER_COMMAND = `${PRODUCT_VIDEO_BRIEF_HELPER_PATH} <pack>/manifest.json`;
|
|
13213
|
-
var createSuccessHandoff = (followthroughSummary, suggestedNextAction, suggestedSteps) => ({
|
|
13214
|
-
followthroughSummary,
|
|
13215
|
-
suggestedNextAction,
|
|
13216
|
-
suggestedSteps
|
|
13217
|
-
});
|
|
13218
|
-
var cliExample = (command, args = "") => `npx opendevbrowser ${command}${args ? ` ${args}` : ""}`;
|
|
13219
|
-
var quoteCliValue = (value) => JSON.stringify(value);
|
|
13220
|
-
var buildResearchRerunCommand = (topic) => cliExample(
|
|
13221
|
-
"research run",
|
|
13222
|
-
`--topic ${quoteCliValue(topic)} --days 14 --source-selection auto --sources web,community --mode json --output-format json`
|
|
13223
|
-
);
|
|
13224
|
-
var buildShoppingRerunCommand = (input) => {
|
|
13225
|
-
const providers = input.providers?.length ? ` --providers ${input.providers.join(",")}` : " --providers shopping/bestbuy,shopping/ebay";
|
|
13226
|
-
const budget = typeof input.budget === "number" ? ` --budget ${input.budget}` : "";
|
|
13227
|
-
const region = input.region ? ` --region ${quoteCliValue(input.region)}` : "";
|
|
13228
|
-
const browserMode = ` --browser-mode ${input.browserMode ?? "managed"}`;
|
|
13229
|
-
const sort = input.sort ? ` --sort ${input.sort}` : "";
|
|
13230
|
-
return cliExample(
|
|
13231
|
-
"shopping run",
|
|
13232
|
-
`--query ${quoteCliValue(input.query)}${providers}${budget}${region}${browserMode}${sort} --mode json --output-format json`
|
|
13233
|
-
);
|
|
13234
|
-
};
|
|
13235
|
-
var buildProductVideoRerunCommand = (input = {}) => {
|
|
13236
|
-
const target = input.productUrl ? `--product-url ${quoteCliValue(input.productUrl)}` : `--product-name ${quoteCliValue(input.productName ?? "<product-name>")}`;
|
|
13237
|
-
const providerHint = input.providerHint ? ` --provider-hint ${input.providerHint}` : "";
|
|
13238
|
-
const screenshots = input.includeScreenshots ? " --include-screenshots" : "";
|
|
13239
|
-
const allImages = input.includeAllImages ? " --include-all-images" : "";
|
|
13240
|
-
const includeCopy = input.includeCopy ? " --include-copy" : "";
|
|
13241
|
-
return cliExample(
|
|
13242
|
-
"product-video run",
|
|
13243
|
-
`${target}${providerHint}${screenshots}${allImages}${includeCopy} --output-format json`
|
|
13244
|
-
);
|
|
13245
|
-
};
|
|
13246
|
-
var buildMacroResolveArgs = (input, options) => {
|
|
13247
|
-
const defaultProvider = input.defaultProvider ? ` --default-provider ${input.defaultProvider}` : "";
|
|
13248
|
-
const execute = options?.execute ? " --execute" : "";
|
|
13249
|
-
const challenge = options?.challengeAutomationMode ? ` --challenge-automation-mode ${options.challengeAutomationMode}` : "";
|
|
13250
|
-
const outputFormat = options?.includeOutputFormat === false ? "" : " --output-format json";
|
|
13251
|
-
return `--expression ${quoteCliValue(input.expression)}${defaultProvider}${execute}${challenge}${outputFormat}`;
|
|
13252
|
-
};
|
|
13253
|
-
var buildMacroPreviewCommand = (input) => cliExample("macro-resolve", buildMacroResolveArgs(input));
|
|
13254
|
-
var buildMacroExecuteCommand = (input, challengeAutomationMode) => cliExample("macro-resolve", buildMacroResolveArgs(input, {
|
|
13255
|
-
execute: true,
|
|
13256
|
-
challengeAutomationMode
|
|
13257
|
-
}));
|
|
13258
|
-
var buildResearchSuccessHandoff = (topic) => {
|
|
13259
|
-
const rerunCommand = buildResearchRerunCommand(topic);
|
|
13260
|
-
return createSuccessHandoff(
|
|
13261
|
-
"Review the ranked records and artifact bundle before turning the result into a publishable claim.",
|
|
13262
|
-
`Open the returned artifact path, inspect the supporting records, and rerun ${rerunCommand} if you need a tighter evidence set.`,
|
|
13263
|
-
[
|
|
13264
|
-
{ reason: "Check which records actually support the final claim." },
|
|
13265
|
-
{
|
|
13266
|
-
reason: "Rerun with explicit sources and a narrower timebox if the evidence set is still too broad.",
|
|
13267
|
-
command: rerunCommand
|
|
13268
|
-
}
|
|
13269
|
-
]
|
|
13270
|
-
);
|
|
13271
|
-
};
|
|
13272
|
-
var buildShoppingSuccessHandoff = (input) => {
|
|
13273
|
-
const rerunCommand = buildShoppingRerunCommand(input);
|
|
13274
|
-
return createSuccessHandoff(
|
|
13275
|
-
"Review the offer set and diagnostics before calling any result a strong deal.",
|
|
13276
|
-
`Inspect the offers and meta.offerFilterDiagnostics, then rerun ${rerunCommand} if you need a tighter comparison.`,
|
|
13277
|
-
[
|
|
13278
|
-
{ reason: "Check which offers survived the workflow filters and why." },
|
|
13279
|
-
{
|
|
13280
|
-
reason: "Rerun with explicit providers or updated budget and region inputs if the comparison is still noisy.",
|
|
13281
|
-
command: rerunCommand
|
|
13282
|
-
}
|
|
13283
|
-
]
|
|
13284
|
-
);
|
|
13285
|
-
};
|
|
13286
|
-
var buildProductVideoSuccessHandoff = (input = {}) => {
|
|
13287
|
-
const rerunCommand = buildProductVideoRerunCommand(input);
|
|
13288
|
-
return createSuccessHandoff(
|
|
13289
|
-
"Review the generated asset pack to confirm whether it is visual-ready or metadata-first before briefing production.",
|
|
13290
|
-
`Open the returned pack path, inspect manifest.json plus copy and features, then run ${PRODUCT_VIDEO_BRIEF_HELPER_COMMAND} to generate production briefs and sourcing notes.`,
|
|
13291
|
-
[
|
|
13292
|
-
{ reason: "Confirm whether the pack already includes enough images or screenshots for production." },
|
|
13293
|
-
{
|
|
13294
|
-
reason: "Run the product-presentation-asset brief helper on manifest.json to generate the production brief files.",
|
|
13295
|
-
command: PRODUCT_VIDEO_BRIEF_HELPER_COMMAND
|
|
13296
|
-
},
|
|
13297
|
-
{
|
|
13298
|
-
reason: "Rerun the asset workflow with adjusted provider or media flags when the current pack is too thin.",
|
|
13299
|
-
command: rerunCommand
|
|
13300
|
-
},
|
|
13301
|
-
{ reason: "Source or capture visuals before final handoff if the pack is metadata-first." }
|
|
13302
|
-
]
|
|
13303
|
-
);
|
|
13304
|
-
};
|
|
13305
|
-
var buildMacroResolveSuccessHandoff = (input) => {
|
|
13306
|
-
const previewCommand = buildMacroPreviewCommand(input);
|
|
13307
|
-
const executeCommand = buildMacroExecuteCommand(input);
|
|
13308
|
-
const browserRetryCommand = buildMacroExecuteCommand(input, "browser");
|
|
13309
|
-
if (!input.execute) {
|
|
13310
|
-
return createSuccessHandoff(
|
|
13311
|
-
"Review the resolved provider action and provenance before executing the macro.",
|
|
13312
|
-
`Run ${executeCommand} when the resolved action looks correct.`,
|
|
13313
|
-
[
|
|
13314
|
-
{ reason: "Inspect resolution.action and resolution.provenance to confirm provider and query shaping." },
|
|
13315
|
-
{ reason: "Execute the resolved macro once the plan looks correct.", command: executeCommand },
|
|
13316
|
-
{ reason: "Add --default-provider only when you need to force a different provider lane.", command: previewCommand }
|
|
13317
|
-
]
|
|
13318
|
-
);
|
|
13319
|
-
}
|
|
13320
|
-
if (input.blocked) {
|
|
13321
|
-
return createSuccessHandoff(
|
|
13322
|
-
"Review execution.meta.blocker and failures before retrying the macro.",
|
|
13323
|
-
`Run ${browserRetryCommand} after checking execution.meta.blocker and the current recovery path.`,
|
|
13324
|
-
[
|
|
13325
|
-
{ reason: "Inspect execution.meta.blocker and execution.failures before retrying." },
|
|
13326
|
-
{ reason: "Retry with browser-scoped challenge automation when the blocker requires live follow-up.", command: browserRetryCommand },
|
|
13327
|
-
{ reason: "Preview the resolved action again if you need to switch providers before another execute attempt.", command: previewCommand }
|
|
13328
|
-
]
|
|
13329
|
-
);
|
|
13330
|
-
}
|
|
13331
|
-
return createSuccessHandoff(
|
|
13332
|
-
"Review execution.records and trace metadata before widening the macro or changing providers.",
|
|
13333
|
-
`Inspect execution.records and execution.meta, then rerun ${previewCommand} if you need a narrower plan.`,
|
|
13334
|
-
[
|
|
13335
|
-
{ reason: "Inspect execution.records and execution.meta to confirm the resolved action hit the expected lane." },
|
|
13336
|
-
{ reason: "Preview the macro again before changing providers or expression scope.", command: previewCommand },
|
|
13337
|
-
{ reason: "Re-execute with browser-scoped challenge automation when the target requires live browser recovery.", command: browserRetryCommand }
|
|
13338
|
-
]
|
|
13339
|
-
);
|
|
13340
|
-
};
|
|
14805
|
+
"motionSystem",
|
|
14806
|
+
"responsiveSystem",
|
|
14807
|
+
"accessibilityPolicy",
|
|
14808
|
+
"libraryPolicy",
|
|
14809
|
+
"runtimeBudgets"
|
|
14810
|
+
];
|
|
14811
|
+
var CANVAS_REQUIRED_MUTATION_GOVERNANCE_KEYS = [
|
|
14812
|
+
"intent",
|
|
14813
|
+
"generationPlan",
|
|
14814
|
+
"designLanguage",
|
|
14815
|
+
"contentModel",
|
|
14816
|
+
"layoutSystem",
|
|
14817
|
+
"typographySystem",
|
|
14818
|
+
"motionSystem",
|
|
14819
|
+
"responsiveSystem",
|
|
14820
|
+
"accessibilityPolicy"
|
|
14821
|
+
];
|
|
14822
|
+
var CANVAS_REQUIRED_SAVE_GOVERNANCE_KEYS = [
|
|
14823
|
+
"intent",
|
|
14824
|
+
"generationPlan",
|
|
14825
|
+
"designLanguage",
|
|
14826
|
+
"contentModel",
|
|
14827
|
+
"layoutSystem",
|
|
14828
|
+
"typographySystem",
|
|
14829
|
+
"colorSystem",
|
|
14830
|
+
"surfaceSystem",
|
|
14831
|
+
"iconSystem",
|
|
14832
|
+
"motionSystem",
|
|
14833
|
+
"responsiveSystem",
|
|
14834
|
+
"accessibilityPolicy",
|
|
14835
|
+
"libraryPolicy",
|
|
14836
|
+
"runtimeBudgets"
|
|
14837
|
+
];
|
|
14838
|
+
var CANVAS_OPTIONAL_INHERITED_GOVERNANCE_KEYS = [
|
|
14839
|
+
"colorSystem",
|
|
14840
|
+
"surfaceSystem",
|
|
14841
|
+
"iconSystem",
|
|
14842
|
+
"libraryPolicy",
|
|
14843
|
+
"runtimeBudgets"
|
|
14844
|
+
];
|
|
14845
|
+
var CANVAS_GENERATION_PLAN_REQUIRED_FIELDS = [
|
|
14846
|
+
"targetOutcome",
|
|
14847
|
+
"visualDirection",
|
|
14848
|
+
"layoutStrategy",
|
|
14849
|
+
"contentStrategy",
|
|
14850
|
+
"componentStrategy",
|
|
14851
|
+
"motionPosture",
|
|
14852
|
+
"responsivePosture",
|
|
14853
|
+
"accessibilityPosture",
|
|
14854
|
+
"validationTargets"
|
|
14855
|
+
];
|
|
14856
|
+
var CANVAS_VISUAL_DIRECTION_PROFILES = [
|
|
14857
|
+
"clean-room",
|
|
14858
|
+
"cinematic-minimal",
|
|
14859
|
+
"product-story",
|
|
14860
|
+
"commerce-system",
|
|
14861
|
+
"control-room",
|
|
14862
|
+
"ops-control",
|
|
14863
|
+
"auth-focused",
|
|
14864
|
+
"settings-system",
|
|
14865
|
+
"documentation"
|
|
14866
|
+
];
|
|
14867
|
+
var CANVAS_THEME_STRATEGIES = ["single-theme", "light-dark-parity", "multi-theme-system"];
|
|
14868
|
+
var CANVAS_NAVIGATION_MODELS = ["global-header", "sidebar", "tabbed", "contextual", "immersive"];
|
|
14869
|
+
var CANVAS_INTERACTION_STATES = [
|
|
14870
|
+
"default",
|
|
14871
|
+
"hover",
|
|
14872
|
+
"focus",
|
|
14873
|
+
"active",
|
|
14874
|
+
"disabled",
|
|
14875
|
+
"loading",
|
|
14876
|
+
"empty",
|
|
14877
|
+
"error",
|
|
14878
|
+
"success",
|
|
14879
|
+
"selected"
|
|
14880
|
+
];
|
|
14881
|
+
var CANVAS_PLAN_VIEWPORTS = ["desktop", "tablet", "mobile"];
|
|
14882
|
+
var CANVAS_PLAN_THEMES = ["light", "dark"];
|
|
14883
|
+
var CANVAS_MOTION_LEVELS = ["none", "minimal", "subtle", "expressive"];
|
|
14884
|
+
var CANVAS_REDUCED_MOTION_POLICIES = ["respect-user-preference", "static-alternative"];
|
|
14885
|
+
var CANVAS_KEYBOARD_NAVIGATION_MODES = ["full", "core-flows"];
|
|
14886
|
+
var CANVAS_BROWSER_VALIDATION_MODES = ["required", "optional"];
|
|
14887
|
+
var CANVAS_VALIDATION_TARGET_BLOCK_ON_CODES = [
|
|
14888
|
+
"missing-generation-plan",
|
|
14889
|
+
"invalid-generation-plan",
|
|
14890
|
+
"missing-governance-block",
|
|
14891
|
+
"missing-intent",
|
|
14892
|
+
"missing-design-language",
|
|
14893
|
+
"missing-content-model",
|
|
14894
|
+
"missing-typography-system",
|
|
14895
|
+
"missing-color-role",
|
|
14896
|
+
"missing-surface-policy",
|
|
14897
|
+
"missing-state-coverage",
|
|
14898
|
+
"missing-reduced-motion-policy",
|
|
14899
|
+
"missing-responsive-policy",
|
|
14900
|
+
"overflow",
|
|
14901
|
+
"token-missing",
|
|
14902
|
+
"broken-asset-reference",
|
|
14903
|
+
"contrast-failure",
|
|
14904
|
+
"hierarchy-weak",
|
|
14905
|
+
"asset-provenance-missing",
|
|
14906
|
+
"font-policy-missing",
|
|
14907
|
+
"font-load-failure",
|
|
14908
|
+
"reduced-motion-violation",
|
|
14909
|
+
"unresolved-component-binding",
|
|
14910
|
+
"icon-policy-violation",
|
|
14911
|
+
"library-policy-violation",
|
|
14912
|
+
"responsive-mismatch",
|
|
14913
|
+
"runtime-budget-exceeded",
|
|
14914
|
+
"unsupported-target",
|
|
14915
|
+
"export-warning"
|
|
14916
|
+
];
|
|
14917
|
+
var CANVAS_PUBLIC_WARNING_CLASSES = CANVAS_VALIDATION_TARGET_BLOCK_ON_CODES;
|
|
13341
14918
|
|
|
13342
14919
|
// src/providers/shopping-postprocess.ts
|
|
13343
14920
|
import { createHash as createHash4 } from "crypto";
|
|
@@ -14645,6 +16222,16 @@ var resolveResearchAutoExcludedProviders = (sourceSelection, resolvedSources, de
|
|
|
14645
16222
|
return source !== null && sourceSet.has(source);
|
|
14646
16223
|
}).sort((left, right) => left.localeCompare(right));
|
|
14647
16224
|
};
|
|
16225
|
+
var buildResearchSearchFilters = (source, args) => ({
|
|
16226
|
+
include_engagement: args.includeEngagement ?? false,
|
|
16227
|
+
timebox_from: args.timebox.from,
|
|
16228
|
+
timebox_to: args.timebox.to,
|
|
16229
|
+
...source === "community" || source === "social" ? {
|
|
16230
|
+
pageLimit: 1,
|
|
16231
|
+
hopLimit: 0,
|
|
16232
|
+
expansionPerRecord: 0
|
|
16233
|
+
} : {}
|
|
16234
|
+
});
|
|
14648
16235
|
var compileResearchExecutionPlan = (args) => {
|
|
14649
16236
|
const topic = args.input.topic?.trim();
|
|
14650
16237
|
if (!topic) {
|
|
@@ -14681,11 +16268,10 @@ var compileResearchExecutionPlan = (args) => {
|
|
|
14681
16268
|
source,
|
|
14682
16269
|
query: topic,
|
|
14683
16270
|
limit: searchLimit,
|
|
14684
|
-
filters: {
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
}
|
|
16271
|
+
filters: buildResearchSearchFilters(source, {
|
|
16272
|
+
includeEngagement: args.input.includeEngagement,
|
|
16273
|
+
timebox
|
|
16274
|
+
})
|
|
14689
16275
|
}
|
|
14690
16276
|
}));
|
|
14691
16277
|
return {
|
|
@@ -14921,7 +16507,7 @@ var executeResearchWorkflowPlan = async (runtime, plan, options) => {
|
|
|
14921
16507
|
};
|
|
14922
16508
|
};
|
|
14923
16509
|
|
|
14924
|
-
// src/
|
|
16510
|
+
// src/inspiredesign/capture-mode.ts
|
|
14925
16511
|
var hasInspiredesignUrls = (urls) => {
|
|
14926
16512
|
return Array.isArray(urls) && urls.some((url) => url.trim().length > 0);
|
|
14927
16513
|
};
|
|
@@ -15493,6 +17079,7 @@ var workflowTestUtils = {
|
|
|
15493
17079
|
buildWorkflowResumePayload: (kind, input) => buildWorkflowResumePayload(kind, input)
|
|
15494
17080
|
};
|
|
15495
17081
|
var PRODUCT_ASSET_FETCH_TIMEOUT_MS = 15e3;
|
|
17082
|
+
var RESEARCH_PROVIDER_STEP_TIMEOUT_MS = 3e4;
|
|
15496
17083
|
var resolveAuxiliaryFetchTimeoutMs = (timeoutMs) => {
|
|
15497
17084
|
if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
15498
17085
|
return PRODUCT_ASSET_FETCH_TIMEOUT_MS;
|
|
@@ -15676,9 +17263,16 @@ var createRemainingTimeoutResolver = (timeoutMs) => {
|
|
|
15676
17263
|
return Math.max(1, timeoutMs - Math.max(0, Date.now() - startedAtMs));
|
|
15677
17264
|
};
|
|
15678
17265
|
};
|
|
17266
|
+
var resolveResearchProviderStepTimeoutMs = (timeoutMs) => {
|
|
17267
|
+
if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
17268
|
+
return void 0;
|
|
17269
|
+
}
|
|
17270
|
+
return Math.max(1, Math.min(timeoutMs, RESEARCH_PROVIDER_STEP_TIMEOUT_MS));
|
|
17271
|
+
};
|
|
15679
17272
|
var INSPIREDESIGN_RENDER_MODES = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
|
|
15680
17273
|
var INSPIREDESIGN_CAPTURE_MODES = /* @__PURE__ */ new Set(["off", "deep"]);
|
|
15681
17274
|
var INSPIREDESIGN_COOKIE_POLICIES = /* @__PURE__ */ new Set(["off", "auto", "required"]);
|
|
17275
|
+
var WORKFLOW_BROWSER_MODES = /* @__PURE__ */ new Set(["auto", "extension", "managed"]);
|
|
15682
17276
|
var isJsonRecord6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15683
17277
|
var INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE = "Deep capture requested, but browser capture is unavailable in this execution lane.";
|
|
15684
17278
|
var isCanvasVisualDirectionProfile = (value) => {
|
|
@@ -15701,6 +17295,7 @@ var serializeInspiredesignRunInput = (input) => ({
|
|
|
15701
17295
|
...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
|
|
15702
17296
|
...input.outputDir ? { outputDir: input.outputDir } : {},
|
|
15703
17297
|
...typeof input.ttlHours === "number" ? { ttlHours: input.ttlHours } : {},
|
|
17298
|
+
...input.browserMode ? { browserMode: input.browserMode } : {},
|
|
15704
17299
|
...typeof input.useCookies === "boolean" ? { useCookies: input.useCookies } : {},
|
|
15705
17300
|
...input.challengeAutomationMode ? { challengeAutomationMode: input.challengeAutomationMode } : {},
|
|
15706
17301
|
...input.cookiePolicyOverride ? { cookiePolicyOverride: input.cookiePolicyOverride } : {}
|
|
@@ -15775,6 +17370,7 @@ var parseInspiredesignEnvelopeInput = (input) => {
|
|
|
15775
17370
|
...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
|
|
15776
17371
|
...typeof input.outputDir === "string" && input.outputDir.length > 0 ? { outputDir: input.outputDir } : {},
|
|
15777
17372
|
...typeof input.ttlHours === "number" ? { ttlHours: input.ttlHours } : {},
|
|
17373
|
+
...typeof input.browserMode === "string" && WORKFLOW_BROWSER_MODES.has(input.browserMode) ? { browserMode: input.browserMode } : {},
|
|
15778
17374
|
...typeof input.useCookies === "boolean" ? { useCookies: input.useCookies } : {},
|
|
15779
17375
|
...isChallengeAutomationMode(input.challengeAutomationMode) ? { challengeAutomationMode: input.challengeAutomationMode } : {},
|
|
15780
17376
|
...typeof input.cookiePolicyOverride === "string" && INSPIREDESIGN_COOKIE_POLICIES.has(input.cookiePolicyOverride) ? { cookiePolicyOverride: input.cookiePolicyOverride } : {}
|
|
@@ -15868,10 +17464,13 @@ var buildInspiredesignStepEnvelope = (workflowInput, trace, stepIndex, url) => b
|
|
|
15868
17464
|
}
|
|
15869
17465
|
);
|
|
15870
17466
|
var buildInspiredesignFetchOptions = (workflowInput, envelope, timeoutMs) => withWorkflowResumeEnvelopeIntent(
|
|
15871
|
-
|
|
15872
|
-
|
|
15873
|
-
|
|
15874
|
-
|
|
17467
|
+
withBrowserModeOverride(
|
|
17468
|
+
withChallengeAutomationOverride(
|
|
17469
|
+
withCookieOverrides({
|
|
17470
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
17471
|
+
}, workflowInput),
|
|
17472
|
+
workflowInput
|
|
17473
|
+
),
|
|
15875
17474
|
workflowInput
|
|
15876
17475
|
),
|
|
15877
17476
|
"workflow.inspiredesign",
|
|
@@ -16054,8 +17653,12 @@ var excerptFromInspiredesignCapture = (capture) => {
|
|
|
16054
17653
|
return captureSnippet(capture?.snapshot?.content, 240) ?? captureSnippet(capture?.dom?.outerHTML, 240) ?? captureSnippet(capture?.clone?.componentPreview, 240) ?? captureSnippet(capture?.clone?.cssPreview, 240);
|
|
16055
17654
|
};
|
|
16056
17655
|
var isInspiredesignFetchRecovered = (reference) => {
|
|
16057
|
-
return reference.fetchStatus === "failed" && reference.captureStatus === "captured" && (
|
|
17656
|
+
return reference.fetchStatus === "failed" && reference.captureStatus === "captured" && hasInspiredesignUsableReferenceEvidence(reference);
|
|
16058
17657
|
};
|
|
17658
|
+
var summarizeInspiredesignRecoveredFetches = (references) => references.filter(isInspiredesignFetchRecovered).map((reference) => ({
|
|
17659
|
+
url: reference.url,
|
|
17660
|
+
...reference.fetchFailure ? { fetchFailure: reference.fetchFailure } : {}
|
|
17661
|
+
}));
|
|
16059
17662
|
var buildInspiredesignReference = (url, result, capture) => {
|
|
16060
17663
|
const primary = getInspiredesignPrimaryRecord(result, url);
|
|
16061
17664
|
const normalizedCapture = normalizeInspiredesignCaptureEvidence(capture.capture);
|
|
@@ -16102,11 +17705,13 @@ var summarizeInspiredesignFetchConstraint = (references) => {
|
|
|
16102
17705
|
var buildInspiredesignMeta = (runtime, workflowInput, references, failures, followthrough) => {
|
|
16103
17706
|
const failedCaptures = references.filter((reference) => reference.captureStatus === "failed");
|
|
16104
17707
|
const captureAttemptReport = summarizeInspiredesignCaptureAttempts(references);
|
|
17708
|
+
const recoveredFetches = summarizeInspiredesignRecoveredFetches(references);
|
|
16105
17709
|
let reasonCodeDistribution = summarizeReasonCodeDistribution(failures);
|
|
16106
17710
|
let meta = withCamelCasePrimaryConstraintMeta(withReasonCodeDistributionMeta({
|
|
16107
17711
|
selection: {
|
|
16108
17712
|
urls: workflowInput.urls,
|
|
16109
17713
|
capture_mode: workflowInput.captureMode,
|
|
17714
|
+
...workflowInput.browserMode ? { requested_browser_mode: workflowInput.browserMode } : {},
|
|
16110
17715
|
include_prototype_guidance: Boolean(workflowInput.includePrototypeGuidance)
|
|
16111
17716
|
},
|
|
16112
17717
|
metrics: {
|
|
@@ -16115,6 +17720,10 @@ var buildInspiredesignMeta = (runtime, workflowInput, references, failures, foll
|
|
|
16115
17720
|
captured_references: references.filter((reference) => reference.captureStatus === "captured").length,
|
|
16116
17721
|
failed_fetches: references.filter((reference) => reference.fetchStatus === "failed" && !isInspiredesignFetchRecovered(reference)).length,
|
|
16117
17722
|
failed_captures: failedCaptures.length,
|
|
17723
|
+
...recoveredFetches.length > 0 ? {
|
|
17724
|
+
recovered_fetches: recoveredFetches.length,
|
|
17725
|
+
recovered_fetch_details: recoveredFetches
|
|
17726
|
+
} : {},
|
|
16118
17727
|
...captureAttemptReport ? { capture_attempts: captureAttemptReport.counts } : {}
|
|
16119
17728
|
},
|
|
16120
17729
|
alerts: buildWorkflowAlerts(runtime, failures)
|
|
@@ -16657,10 +18266,17 @@ var runResearchWorkflow = async (runtime, input) => {
|
|
|
16657
18266
|
}
|
|
16658
18267
|
];
|
|
16659
18268
|
const buildResearchStepOptions = (step, stepEnvelope) => {
|
|
16660
|
-
const
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
18269
|
+
const timeoutMs = resolveResearchProviderStepTimeoutMs(workflowInput.timeoutMs);
|
|
18270
|
+
const stepOptions = withBrowserModeOverride(
|
|
18271
|
+
withChallengeAutomationOverride(
|
|
18272
|
+
withCookieOverrides({
|
|
18273
|
+
source: step.input.source,
|
|
18274
|
+
...typeof timeoutMs === "number" ? { timeoutMs } : {}
|
|
18275
|
+
}, workflowInput),
|
|
18276
|
+
workflowInput
|
|
18277
|
+
),
|
|
18278
|
+
workflowInput
|
|
18279
|
+
);
|
|
16664
18280
|
return withWorkflowResumeEnvelopeIntent(
|
|
16665
18281
|
stepOptions,
|
|
16666
18282
|
"workflow.research",
|
|
@@ -16723,7 +18339,8 @@ var runResearchWorkflow = async (runtime, input) => {
|
|
|
16723
18339
|
timebox: resolvedTimebox,
|
|
16724
18340
|
selection: withExcludedProviders({
|
|
16725
18341
|
source_selection: plan.compiled.sourceSelection,
|
|
16726
|
-
resolved_sources: plan.compiled.resolvedSources
|
|
18342
|
+
resolved_sources: plan.compiled.resolvedSources,
|
|
18343
|
+
...workflowInput.browserMode ? { requested_browser_mode: workflowInput.browserMode } : {}
|
|
16727
18344
|
}, plan.compiled.autoExcludedProviders),
|
|
16728
18345
|
metrics: {
|
|
16729
18346
|
total_records: mergedRecords.length,
|
|
@@ -16750,7 +18367,10 @@ var runResearchWorkflow = async (runtime, input) => {
|
|
|
16750
18367
|
failures: mergedFailures,
|
|
16751
18368
|
alerts: buildWorkflowAlerts(runtime, mergedFailures)
|
|
16752
18369
|
}, primaryConstraintFailures);
|
|
16753
|
-
const handoff = buildResearchSuccessHandoff(
|
|
18370
|
+
const handoff = buildResearchSuccessHandoff({
|
|
18371
|
+
topic: plan.compiled.topic,
|
|
18372
|
+
browserMode: workflowInput.browserMode
|
|
18373
|
+
});
|
|
16754
18374
|
const responseMeta = withFollowthroughMeta(meta, handoff);
|
|
16755
18375
|
const rendered = renderResearch({
|
|
16756
18376
|
mode: workflowInput.mode,
|
|
@@ -17185,6 +18805,7 @@ var runProductVideoWorkflow = async (runtime, input, options = {}) => {
|
|
|
17185
18805
|
providers: providerHint ? [providerHint] : void 0,
|
|
17186
18806
|
mode: "json",
|
|
17187
18807
|
...timeoutOptions,
|
|
18808
|
+
browserMode: workflowInput.browserMode,
|
|
17188
18809
|
useCookies: workflowInput.useCookies,
|
|
17189
18810
|
challengeAutomationMode: workflowInput.challengeAutomationMode,
|
|
17190
18811
|
cookiePolicyOverride: workflowInput.cookiePolicyOverride
|
|
@@ -17263,12 +18884,15 @@ var runProductVideoWorkflow = async (runtime, input, options = {}) => {
|
|
|
17263
18884
|
details = await runtime.fetch(
|
|
17264
18885
|
{ url: productUrl },
|
|
17265
18886
|
withWorkflowResumeEnvelopeIntent(
|
|
17266
|
-
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17271
|
-
|
|
18887
|
+
withBrowserModeOverride(
|
|
18888
|
+
withChallengeAutomationOverride(
|
|
18889
|
+
withCookieOverrides({
|
|
18890
|
+
source,
|
|
18891
|
+
providerIds: shoppingProviderId ? [shoppingProviderId] : void 0,
|
|
18892
|
+
...timeoutOptions
|
|
18893
|
+
}, workflowInput),
|
|
18894
|
+
workflowInput
|
|
18895
|
+
),
|
|
17272
18896
|
workflowInput
|
|
17273
18897
|
),
|
|
17274
18898
|
"workflow.product_video",
|
|
@@ -17418,14 +19042,16 @@ var runProductVideoWorkflow = async (runtime, input, options = {}) => {
|
|
|
17418
19042
|
productUrl,
|
|
17419
19043
|
productName: workflowInput.product_name,
|
|
17420
19044
|
providerHint,
|
|
19045
|
+
browserMode: workflowInput.browserMode,
|
|
17421
19046
|
includeScreenshots: workflowInput.include_screenshots,
|
|
17422
19047
|
includeAllImages: workflowInput.include_all_images,
|
|
17423
19048
|
includeCopy: workflowInput.include_copy
|
|
17424
19049
|
});
|
|
17425
19050
|
const meta = withFollowthroughMeta({
|
|
19051
|
+
...workflowInput.browserMode ? { selection: { requested_browser_mode: workflowInput.browserMode } } : {},
|
|
17426
19052
|
alerts: buildWorkflowAlerts(runtime, details.failures),
|
|
17427
19053
|
failures: details.failures,
|
|
17428
|
-
...primaryIssue ? { primaryConstraintSummary: primaryIssue.summary } : {},
|
|
19054
|
+
...primaryIssue ? { primaryConstraint: primaryIssue, primaryConstraintSummary: primaryIssue.summary } : {},
|
|
17429
19055
|
reasonCodeDistribution,
|
|
17430
19056
|
transcript_strategy_failures: transcriptStrategyFailures,
|
|
17431
19057
|
transcriptStrategyFailures,
|
|
@@ -17466,11 +19092,11 @@ var WORKFLOW_KIND_BY_SUSPENDED_INTENT_KIND2 = {
|
|
|
17466
19092
|
"workflow.inspiredesign": "inspiredesign",
|
|
17467
19093
|
"workflow.product_video": "product_video"
|
|
17468
19094
|
};
|
|
17469
|
-
var EXTENSION_FIRST_SOCIAL_FALLBACK_PLATFORMS = /* @__PURE__ */ new Set(["x", "reddit", "bluesky", "facebook", "linkedin"]);
|
|
19095
|
+
var EXTENSION_FIRST_SOCIAL_FALLBACK_PLATFORMS = /* @__PURE__ */ new Set(["x", "reddit", "bluesky", "facebook", "linkedin", "threads"]);
|
|
17470
19096
|
var EXTENSION_MINIMAL_TRAVERSAL_SOCIAL_PLATFORMS = /* @__PURE__ */ new Set(["linkedin"]);
|
|
17471
19097
|
var EXTENSION_FIRST_FALLBACK_MODES = ["extension", "managed_headed"];
|
|
17472
19098
|
var SOCIAL_BROWSER_RECOVERY_REASON_CODES = /* @__PURE__ */ new Set(["challenge_detected"]);
|
|
17473
|
-
var SEARCH_RENDER_RECOVERY_SOCIAL_PLATFORMS = /* @__PURE__ */ new Set(["x", "bluesky", "reddit", "facebook"]);
|
|
19099
|
+
var SEARCH_RENDER_RECOVERY_SOCIAL_PLATFORMS = /* @__PURE__ */ new Set(["x", "bluesky", "reddit", "facebook", "threads"]);
|
|
17474
19100
|
var withPrioritizedFallbackModes = (prioritized, existing) => [.../* @__PURE__ */ new Set([...prioritized, ...existing ?? []])];
|
|
17475
19101
|
var buildSocialRecoveryHints = (platform, options) => {
|
|
17476
19102
|
const existing = options?.recoveryHints?.();
|
|
@@ -17629,6 +19255,154 @@ var SOCIAL_SEARCH_ENDPOINTS = {
|
|
|
17629
19255
|
threads: (query, page) => `https://www.threads.net/search?q=${encodeURIComponent(query)}&page=${page}`,
|
|
17630
19256
|
youtube: (query, page) => `https://www.youtube.com/results?search_query=${encodeURIComponent(query)}&page=${page}`
|
|
17631
19257
|
};
|
|
19258
|
+
var FALLBACK_SHELL_LINK_SEGMENTS = /* @__PURE__ */ new Set([
|
|
19259
|
+
"account",
|
|
19260
|
+
"auth",
|
|
19261
|
+
"about",
|
|
19262
|
+
"cart",
|
|
19263
|
+
"categories",
|
|
19264
|
+
"category",
|
|
19265
|
+
"collections",
|
|
19266
|
+
"contact",
|
|
19267
|
+
"explore",
|
|
19268
|
+
"help",
|
|
19269
|
+
"home",
|
|
19270
|
+
"legal",
|
|
19271
|
+
"login",
|
|
19272
|
+
"policies",
|
|
19273
|
+
"product",
|
|
19274
|
+
"products",
|
|
19275
|
+
"privacy",
|
|
19276
|
+
"search",
|
|
19277
|
+
"settings",
|
|
19278
|
+
"shop",
|
|
19279
|
+
"signin",
|
|
19280
|
+
"sign-in",
|
|
19281
|
+
"sitemap",
|
|
19282
|
+
"store",
|
|
19283
|
+
"submit",
|
|
19284
|
+
"support",
|
|
19285
|
+
"terms"
|
|
19286
|
+
]);
|
|
19287
|
+
var FALLBACK_SHELL_TEXT_TOKENS = /* @__PURE__ */ new Set([
|
|
19288
|
+
"account",
|
|
19289
|
+
"ad",
|
|
19290
|
+
"ads",
|
|
19291
|
+
"about",
|
|
19292
|
+
"cart",
|
|
19293
|
+
"contact",
|
|
19294
|
+
"explore",
|
|
19295
|
+
"help",
|
|
19296
|
+
"home",
|
|
19297
|
+
"in",
|
|
19298
|
+
"legal",
|
|
19299
|
+
"log",
|
|
19300
|
+
"login",
|
|
19301
|
+
"policies",
|
|
19302
|
+
"product",
|
|
19303
|
+
"products",
|
|
19304
|
+
"privacy",
|
|
19305
|
+
"search",
|
|
19306
|
+
"settings",
|
|
19307
|
+
"sign",
|
|
19308
|
+
"signin",
|
|
19309
|
+
"submit",
|
|
19310
|
+
"support",
|
|
19311
|
+
"terms"
|
|
19312
|
+
]);
|
|
19313
|
+
var FALLBACK_HEAD_RE2 = /<head\b[^>]*>[\s\S]*?<\/head>/i;
|
|
19314
|
+
var FALLBACK_BODY_RE2 = /<body\b[^>]*>([\s\S]*?)<\/body>/i;
|
|
19315
|
+
var FALLBACK_MIN_MEANINGFUL_TEXT_CHARS = 20;
|
|
19316
|
+
var FALLBACK_MIN_MEANINGFUL_TOKENS = 3;
|
|
19317
|
+
var FALLBACK_SHELL_PHRASES_RE = /\b(?:search results?|please enable javascript|enable javascript|continue|welcome|accept cookies?|privacy policy|terms of service)\b/i;
|
|
19318
|
+
var extractFallbackBodyHtml = (html) => {
|
|
19319
|
+
const body = FALLBACK_BODY_RE2.exec(html)?.[1];
|
|
19320
|
+
return body ?? html.replace(FALLBACK_HEAD_RE2, " ");
|
|
19321
|
+
};
|
|
19322
|
+
var extractFallbackBodyText = (html) => {
|
|
19323
|
+
return extractText(extractFallbackBodyHtml(html));
|
|
19324
|
+
};
|
|
19325
|
+
var hasUsableFallbackText = (html) => {
|
|
19326
|
+
const text = extractFallbackBodyText(html);
|
|
19327
|
+
const blocker = classifyBlockerSignal({
|
|
19328
|
+
source: "runtime_fetch",
|
|
19329
|
+
message: text,
|
|
19330
|
+
status: 200,
|
|
19331
|
+
providerErrorCode: "unavailable",
|
|
19332
|
+
retryable: true
|
|
19333
|
+
});
|
|
19334
|
+
if (blocker && blocker.type !== "unknown") return false;
|
|
19335
|
+
if (text.length < FALLBACK_MIN_MEANINGFUL_TEXT_CHARS || FALLBACK_SHELL_PHRASES_RE.test(text)) {
|
|
19336
|
+
return false;
|
|
19337
|
+
}
|
|
19338
|
+
const tokens = text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
19339
|
+
const meaningfulTokens = tokens.filter((token) => !FALLBACK_SHELL_TEXT_TOKENS.has(token));
|
|
19340
|
+
return meaningfulTokens.length >= FALLBACK_MIN_MEANINGFUL_TOKENS;
|
|
19341
|
+
};
|
|
19342
|
+
var isUsableFallbackLink = (link, documentUrl) => {
|
|
19343
|
+
try {
|
|
19344
|
+
const parsed = new URL(link);
|
|
19345
|
+
const source = new URL(documentUrl);
|
|
19346
|
+
const segments = parsed.pathname.toLowerCase().split("/").filter(Boolean);
|
|
19347
|
+
const firstSegment = segments[0];
|
|
19348
|
+
if (parsed.origin === source.origin && parsed.pathname === source.pathname) {
|
|
19349
|
+
return false;
|
|
19350
|
+
}
|
|
19351
|
+
if (segments.length === 0 && parsed.search.length === 0) {
|
|
19352
|
+
return false;
|
|
19353
|
+
}
|
|
19354
|
+
return firstSegment === void 0 || !FALLBACK_SHELL_LINK_SEGMENTS.has(firstSegment);
|
|
19355
|
+
} catch {
|
|
19356
|
+
return false;
|
|
19357
|
+
}
|
|
19358
|
+
};
|
|
19359
|
+
var hasUsableFallbackBodyLink = (documentUrl, html) => extractStructuredContent(extractFallbackBodyHtml(html), documentUrl).links.some((link) => isUsableFallbackLink(link, documentUrl));
|
|
19360
|
+
var hasUsableFallbackContent = (documentUrl, html) => hasUsableFallbackText(html) || hasUsableFallbackBodyLink(documentUrl, html);
|
|
19361
|
+
var isBlockedRedditFallbackLink = (link) => {
|
|
19362
|
+
try {
|
|
19363
|
+
const hostname = new URL(link).hostname.toLowerCase();
|
|
19364
|
+
const isReddit = hostname === "reddit.com" || hostname.endsWith(".reddit.com");
|
|
19365
|
+
return isReddit && !isAllowedSocialSearchExpansionUrl("reddit", link);
|
|
19366
|
+
} catch {
|
|
19367
|
+
return false;
|
|
19368
|
+
}
|
|
19369
|
+
};
|
|
19370
|
+
var shouldOwnerReviewCommunityRedditSearchFallback = (input) => input.providerId === "community/default" && input.source === "community" && input.operation === "search" && isFirstPartySocialSearchRoute("reddit", input.url) && input.extracted.links.length > 0 && input.extracted.links.every(isBlockedRedditFallbackLink);
|
|
19371
|
+
var shouldReturnCompletedFallbackForOwnerReview = (args) => args.document.browserFallback !== void 0 && args.ownerReview?.({
|
|
19372
|
+
providerId: args.providerId,
|
|
19373
|
+
source: args.source,
|
|
19374
|
+
operation: args.operation,
|
|
19375
|
+
url: args.document.url,
|
|
19376
|
+
html: args.document.html,
|
|
19377
|
+
extracted: extractStructuredContent(args.document.html, args.document.url)
|
|
19378
|
+
}) === true;
|
|
19379
|
+
var toCompletedFallbackDocument = (args) => {
|
|
19380
|
+
const resolvedUrl = canonicalizeUrl(readFallbackString(args.fallback.output, "url") ?? args.url);
|
|
19381
|
+
const html = readFallbackString(args.fallback.output, "html");
|
|
19382
|
+
if (!html) {
|
|
19383
|
+
throw toCompletedFallbackOutputError({ ...args, provider: args.providerId, url: resolvedUrl, outputReason: "missing_or_empty_html" });
|
|
19384
|
+
}
|
|
19385
|
+
const extracted = extractStructuredContent(html, resolvedUrl);
|
|
19386
|
+
const reviewInput = {
|
|
19387
|
+
providerId: args.providerId,
|
|
19388
|
+
source: args.source,
|
|
19389
|
+
operation: args.operation,
|
|
19390
|
+
url: resolvedUrl,
|
|
19391
|
+
html,
|
|
19392
|
+
extracted
|
|
19393
|
+
};
|
|
19394
|
+
if (!hasUsableFallbackContent(resolvedUrl, html) && !args.ownerReview?.(reviewInput)) {
|
|
19395
|
+
throw toCompletedFallbackOutputError({ ...args, provider: args.providerId, url: resolvedUrl, outputReason: "empty_extracted_content" });
|
|
19396
|
+
}
|
|
19397
|
+
return {
|
|
19398
|
+
url: resolvedUrl,
|
|
19399
|
+
status: 200,
|
|
19400
|
+
html,
|
|
19401
|
+
text: extracted.text,
|
|
19402
|
+
links: extracted.links,
|
|
19403
|
+
browserFallback: toBrowserFallbackObservation(args.fallback)
|
|
19404
|
+
};
|
|
19405
|
+
};
|
|
17632
19406
|
var describeDefaultFetchedIssue = (document) => {
|
|
17633
19407
|
const extracted = extractStructuredContent(document.html, document.url);
|
|
17634
19408
|
const title = typeof extracted.metadata.title === "string" ? extracted.metadata.title : void 0;
|
|
@@ -17690,6 +19464,9 @@ var resolveDefaultFallbackDocumentIfNeeded = async (args) => {
|
|
|
17690
19464
|
if (!initialIssue) {
|
|
17691
19465
|
return { document: currentDocument, ...described };
|
|
17692
19466
|
}
|
|
19467
|
+
if (shouldReturnCompletedFallbackForOwnerReview({ ...args, document: currentDocument })) {
|
|
19468
|
+
return { document: currentDocument, ...described };
|
|
19469
|
+
}
|
|
17693
19470
|
if (initialIssue.reasonCode === "env_limited" && !initialIssue.constraint) {
|
|
17694
19471
|
return { document: currentDocument, ...described };
|
|
17695
19472
|
}
|
|
@@ -17720,18 +19497,18 @@ var resolveDefaultFallbackDocumentIfNeeded = async (args) => {
|
|
|
17720
19497
|
fallback
|
|
17721
19498
|
});
|
|
17722
19499
|
}
|
|
17723
|
-
|
|
17724
|
-
|
|
17725
|
-
|
|
17726
|
-
|
|
17727
|
-
url:
|
|
17728
|
-
|
|
17729
|
-
|
|
17730
|
-
|
|
17731
|
-
links: extracted.links,
|
|
17732
|
-
browserFallback: toBrowserFallbackObservation(fallback)
|
|
17733
|
-
};
|
|
19500
|
+
currentDocument = toCompletedFallbackDocument({
|
|
19501
|
+
providerId: args.providerId,
|
|
19502
|
+
source: args.source,
|
|
19503
|
+
operation: args.operation,
|
|
19504
|
+
url: currentDocument.url,
|
|
19505
|
+
fallback,
|
|
19506
|
+
ownerReview: args.ownerReview
|
|
19507
|
+
});
|
|
17734
19508
|
described = describeDefaultFetchedIssue(currentDocument);
|
|
19509
|
+
if (shouldReturnCompletedFallbackForOwnerReview({ ...args, document: currentDocument })) {
|
|
19510
|
+
return { document: currentDocument, ...described };
|
|
19511
|
+
}
|
|
17735
19512
|
if (!described.issue || described.issue.reasonCode === "env_limited" && !described.issue.constraint) {
|
|
17736
19513
|
return { document: currentDocument, ...described };
|
|
17737
19514
|
}
|
|
@@ -18008,6 +19785,57 @@ var readResponseTextWithAbort = async (response, args) => {
|
|
|
18008
19785
|
}
|
|
18009
19786
|
};
|
|
18010
19787
|
var fetchRuntimeDocumentWithFallback = async (args) => {
|
|
19788
|
+
const fallbackPort = args.context?.browserFallbackPort ?? args.browserFallbackPort;
|
|
19789
|
+
const runtimePolicy = args.context?.runtimePolicy;
|
|
19790
|
+
const forcedBrowserTransport = runtimePolicy?.browser.forceTransport === true;
|
|
19791
|
+
const forcedReasonCode = runtimePolicy?.cookies.policy === "required" ? "auth_required" : "env_limited";
|
|
19792
|
+
if (forcedBrowserTransport) {
|
|
19793
|
+
const fallback = await resolveProviderBrowserFallback({
|
|
19794
|
+
browserFallbackPort: fallbackPort,
|
|
19795
|
+
provider: args.provider,
|
|
19796
|
+
source: args.source,
|
|
19797
|
+
operation: args.operation,
|
|
19798
|
+
reasonCode: forcedReasonCode,
|
|
19799
|
+
url: args.url,
|
|
19800
|
+
context: args.context,
|
|
19801
|
+
details: {
|
|
19802
|
+
message: "Direct browser transport was selected for this provider run."
|
|
19803
|
+
},
|
|
19804
|
+
recoveryHints: args.recoveryHints
|
|
19805
|
+
});
|
|
19806
|
+
if (!fallback) {
|
|
19807
|
+
throw new ProviderRuntimeError(
|
|
19808
|
+
providerErrorCodeFromReasonCode(forcedReasonCode),
|
|
19809
|
+
"Direct browser transport is required for this provider run, but no browser transport is available.",
|
|
19810
|
+
{
|
|
19811
|
+
provider: args.provider,
|
|
19812
|
+
source: args.source,
|
|
19813
|
+
retryable: false,
|
|
19814
|
+
reasonCode: forcedReasonCode,
|
|
19815
|
+
details: {
|
|
19816
|
+
reasonCode: forcedReasonCode,
|
|
19817
|
+
browserTransportRequired: true
|
|
19818
|
+
}
|
|
19819
|
+
}
|
|
19820
|
+
);
|
|
19821
|
+
}
|
|
19822
|
+
if (fallback.disposition !== "completed") {
|
|
19823
|
+
throw toProviderFallbackError({
|
|
19824
|
+
provider: args.provider,
|
|
19825
|
+
source: args.source,
|
|
19826
|
+
url: args.url,
|
|
19827
|
+
fallback
|
|
19828
|
+
});
|
|
19829
|
+
}
|
|
19830
|
+
return toCompletedFallbackDocument({
|
|
19831
|
+
providerId: args.provider,
|
|
19832
|
+
source: args.source,
|
|
19833
|
+
operation: args.operation,
|
|
19834
|
+
url: args.url,
|
|
19835
|
+
fallback,
|
|
19836
|
+
ownerReview: args.ownerReview
|
|
19837
|
+
});
|
|
19838
|
+
}
|
|
18011
19839
|
try {
|
|
18012
19840
|
return await fetchRuntimeDocument({
|
|
18013
19841
|
url: args.url,
|
|
@@ -18020,7 +19848,9 @@ var fetchRuntimeDocumentWithFallback = async (args) => {
|
|
|
18020
19848
|
provider: args.provider,
|
|
18021
19849
|
source: args.source
|
|
18022
19850
|
});
|
|
18023
|
-
|
|
19851
|
+
if (args.recoverRuntimeErrors === false) {
|
|
19852
|
+
throw error;
|
|
19853
|
+
}
|
|
18024
19854
|
if (!fallbackPort) {
|
|
18025
19855
|
throw error;
|
|
18026
19856
|
}
|
|
@@ -18054,17 +19884,14 @@ var fetchRuntimeDocumentWithFallback = async (args) => {
|
|
|
18054
19884
|
fallback
|
|
18055
19885
|
});
|
|
18056
19886
|
}
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
url:
|
|
18062
|
-
|
|
18063
|
-
|
|
18064
|
-
|
|
18065
|
-
links: extracted.links,
|
|
18066
|
-
browserFallback: toBrowserFallbackObservation(fallback)
|
|
18067
|
-
};
|
|
19887
|
+
return toCompletedFallbackDocument({
|
|
19888
|
+
providerId: args.provider,
|
|
19889
|
+
source: args.source,
|
|
19890
|
+
operation: args.operation,
|
|
19891
|
+
url: args.url,
|
|
19892
|
+
fallback,
|
|
19893
|
+
ownerReview: args.ownerReview
|
|
19894
|
+
});
|
|
18068
19895
|
}
|
|
18069
19896
|
};
|
|
18070
19897
|
var ProviderRuntime = class {
|
|
@@ -19220,7 +21047,8 @@ var withDefaultCommunityOptions = (options, browserFallbackPort) => {
|
|
|
19220
21047
|
operation: "search",
|
|
19221
21048
|
signal: context.signal,
|
|
19222
21049
|
context,
|
|
19223
|
-
browserFallbackPort
|
|
21050
|
+
browserFallbackPort,
|
|
21051
|
+
ownerReview: shouldOwnerReviewCommunityRedditSearchFallback
|
|
19224
21052
|
});
|
|
19225
21053
|
const { document: resolvedDocument, pageMessage } = await resolveDefaultFallbackDocumentIfNeeded({
|
|
19226
21054
|
providerId,
|
|
@@ -19228,7 +21056,8 @@ var withDefaultCommunityOptions = (options, browserFallbackPort) => {
|
|
|
19228
21056
|
operation: "search",
|
|
19229
21057
|
document,
|
|
19230
21058
|
context,
|
|
19231
|
-
browserFallbackPort
|
|
21059
|
+
browserFallbackPort,
|
|
21060
|
+
ownerReview: shouldOwnerReviewCommunityRedditSearchFallback
|
|
19232
21061
|
});
|
|
19233
21062
|
const links = resolveCommunitySearchLinks(resolvedDocument, limit);
|
|
19234
21063
|
if (shouldRejectBlockedCommunityFallback(resolvedDocument, links)) {
|
|
@@ -19340,6 +21169,12 @@ var withDefaultSocialPlatformOptions = (platform, options, browserFallbackPort)
|
|
|
19340
21169
|
}
|
|
19341
21170
|
);
|
|
19342
21171
|
};
|
|
21172
|
+
const shouldOwnerReviewSocialFallback = (input) => input.source === "social" && input.operation === "search" && detectSocialSearchShell(platform, {
|
|
21173
|
+
url: input.url,
|
|
21174
|
+
title: typeof input.extracted.metadata.title === "string" ? input.extracted.metadata.title : void 0,
|
|
21175
|
+
content: toSnippet(stripUrls(input.extracted.text), 1600),
|
|
21176
|
+
links: input.extracted.links
|
|
21177
|
+
})?.browserRequired === true;
|
|
19343
21178
|
const resolveFallbackDocumentIfNeeded = async (operation, document, context) => {
|
|
19344
21179
|
let currentDocument = document;
|
|
19345
21180
|
let described = describeDocumentIssue(operation, currentDocument);
|
|
@@ -19374,23 +21209,24 @@ var withDefaultSocialPlatformOptions = (platform, options, browserFallbackPort)
|
|
|
19374
21209
|
});
|
|
19375
21210
|
}
|
|
19376
21211
|
const requestedUrl = currentDocument.url;
|
|
19377
|
-
const
|
|
19378
|
-
|
|
19379
|
-
|
|
21212
|
+
const fallbackDocument = toCompletedFallbackDocument({
|
|
21213
|
+
providerId,
|
|
21214
|
+
source: "social",
|
|
21215
|
+
operation,
|
|
21216
|
+
url: currentDocument.url,
|
|
21217
|
+
fallback,
|
|
21218
|
+
ownerReview: shouldOwnerReviewSocialFallback
|
|
21219
|
+
});
|
|
19380
21220
|
const effectiveUrl = resolveRecoveredSocialSearchDocumentUrl({
|
|
19381
21221
|
platform,
|
|
19382
21222
|
operation,
|
|
19383
21223
|
requestedUrl,
|
|
19384
|
-
recoveredUrl:
|
|
19385
|
-
recoveredLinks:
|
|
21224
|
+
recoveredUrl: fallbackDocument.url,
|
|
21225
|
+
recoveredLinks: fallbackDocument.links
|
|
19386
21226
|
});
|
|
19387
21227
|
currentDocument = {
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
html,
|
|
19391
|
-
text: extracted.text,
|
|
19392
|
-
links: extracted.links,
|
|
19393
|
-
browserFallback: toBrowserFallbackObservation(fallback)
|
|
21228
|
+
...fallbackDocument,
|
|
21229
|
+
url: effectiveUrl
|
|
19394
21230
|
};
|
|
19395
21231
|
described = describeDocumentIssue(operation, currentDocument);
|
|
19396
21232
|
if (!described.issue || described.issue.reasonCode === "env_limited" && !described.issue.constraint) {
|
|
@@ -19414,7 +21250,9 @@ var withDefaultSocialPlatformOptions = (platform, options, browserFallbackPort)
|
|
|
19414
21250
|
signal: context.signal,
|
|
19415
21251
|
context,
|
|
19416
21252
|
browserFallbackPort,
|
|
19417
|
-
recoveryHints: extensionFirstRecoveryHints
|
|
21253
|
+
recoveryHints: extensionFirstRecoveryHints,
|
|
21254
|
+
recoverRuntimeErrors: EXTENSION_FIRST_SOCIAL_FALLBACK_PLATFORMS.has(platform),
|
|
21255
|
+
ownerReview: shouldOwnerReviewSocialFallback
|
|
19418
21256
|
});
|
|
19419
21257
|
const { document: resolvedDocument, extracted, pageMessage } = await resolveFallbackDocumentIfNeeded("search", document, context);
|
|
19420
21258
|
const links = dedupeLinks2(
|
|
@@ -19447,7 +21285,9 @@ var withDefaultSocialPlatformOptions = (platform, options, browserFallbackPort)
|
|
|
19447
21285
|
signal: context.signal,
|
|
19448
21286
|
context,
|
|
19449
21287
|
browserFallbackPort,
|
|
19450
|
-
recoveryHints: extensionFirstRecoveryHints
|
|
21288
|
+
recoveryHints: extensionFirstRecoveryHints,
|
|
21289
|
+
recoverRuntimeErrors: EXTENSION_FIRST_SOCIAL_FALLBACK_PLATFORMS.has(platform),
|
|
21290
|
+
ownerReview: shouldOwnerReviewSocialFallback
|
|
19451
21291
|
});
|
|
19452
21292
|
const { document: resolvedDocument, extracted } = await resolveFallbackDocumentIfNeeded("fetch", document, context);
|
|
19453
21293
|
const links = dedupeLinks2(resolvedDocument.links, resolvedDocument.url, 20);
|
|
@@ -19610,10 +21450,10 @@ export {
|
|
|
19610
21450
|
enrichResearchRecords,
|
|
19611
21451
|
INSPIREDESIGN_HANDOFF_COMMANDS,
|
|
19612
21452
|
INSPIREDESIGN_HANDOFF_GUIDANCE,
|
|
21453
|
+
buildMacroResolveSuccessHandoff,
|
|
19613
21454
|
renderResearch,
|
|
19614
21455
|
renderShopping,
|
|
19615
21456
|
renderInspiredesign,
|
|
19616
|
-
buildMacroResolveSuccessHandoff,
|
|
19617
21457
|
resolveInspiredesignCaptureMode,
|
|
19618
21458
|
workflowTestUtils,
|
|
19619
21459
|
runResearchWorkflow,
|
|
@@ -19625,4 +21465,4 @@ export {
|
|
|
19625
21465
|
createProviderRuntime,
|
|
19626
21466
|
createDefaultRuntime
|
|
19627
21467
|
};
|
|
19628
|
-
//# sourceMappingURL=chunk-
|
|
21468
|
+
//# sourceMappingURL=chunk-T3VVHJTK.js.map
|