opendevbrowser 0.0.24 → 0.0.26

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.
Files changed (61) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/fingerprint/canary.d.ts.map +1 -1
  3. package/dist/{chunk-K2TEHJCV.js → chunk-AVQL6WAS.js} +2856 -694
  4. package/dist/chunk-AVQL6WAS.js.map +1 -0
  5. package/dist/{chunk-5I6TZRVS.js → chunk-GTTYIAI7.js} +1053 -474
  6. package/dist/chunk-GTTYIAI7.js.map +1 -0
  7. package/dist/cli/commands/daemon.d.ts +25 -0
  8. package/dist/cli/commands/daemon.d.ts.map +1 -1
  9. package/dist/cli/commands/inspiredesign.d.ts.map +1 -1
  10. package/dist/cli/commands/serve.d.ts +10 -13
  11. package/dist/cli/commands/serve.d.ts.map +1 -1
  12. package/dist/cli/commands/status.d.ts.map +1 -1
  13. package/dist/cli/daemon-client.d.ts +13 -0
  14. package/dist/cli/daemon-client.d.ts.map +1 -1
  15. package/dist/cli/daemon-commands.d.ts.map +1 -1
  16. package/dist/cli/daemon-status-policy.d.ts +6 -0
  17. package/dist/cli/daemon-status-policy.d.ts.map +1 -0
  18. package/dist/cli/daemon-status.d.ts +1 -0
  19. package/dist/cli/daemon-status.d.ts.map +1 -1
  20. package/dist/cli/daemon.d.ts +12 -2
  21. package/dist/cli/daemon.d.ts.map +1 -1
  22. package/dist/cli/help.d.ts.map +1 -1
  23. package/dist/cli/index.js +188 -108
  24. package/dist/cli/index.js.map +1 -1
  25. package/dist/cli/remote-manager.d.ts +8 -6
  26. package/dist/cli/remote-manager.d.ts.map +1 -1
  27. package/dist/cli/utils/http.d.ts.map +1 -1
  28. package/dist/daemon-fingerprint.json +3 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +147 -46
  31. package/dist/index.js.map +1 -1
  32. package/dist/inspiredesign/brief-expansion.d.ts +41 -0
  33. package/dist/inspiredesign/brief-expansion.d.ts.map +1 -0
  34. package/dist/inspiredesign/handoff.d.ts +3 -1
  35. package/dist/inspiredesign/handoff.d.ts.map +1 -1
  36. package/dist/opendevbrowser.d.ts.map +1 -1
  37. package/dist/opendevbrowser.js +147 -46
  38. package/dist/opendevbrowser.js.map +1 -1
  39. package/dist/providers/inspiredesign-capture-mode.d.ts +3 -0
  40. package/dist/providers/inspiredesign-capture-mode.d.ts.map +1 -0
  41. package/dist/providers/inspiredesign-capture.d.ts +8 -1
  42. package/dist/providers/inspiredesign-capture.d.ts.map +1 -1
  43. package/dist/providers/inspiredesign-contract.d.ts +30 -0
  44. package/dist/providers/inspiredesign-contract.d.ts.map +1 -1
  45. package/dist/providers/renderer.d.ts +2 -1
  46. package/dist/providers/renderer.d.ts.map +1 -1
  47. package/dist/providers/workflows.d.ts +2 -0
  48. package/dist/providers/workflows.d.ts.map +1 -1
  49. package/dist/{providers-6YVHKTOJ.js → providers-T2FQJCF6.js} +2 -2
  50. package/dist/tools/index.d.ts.map +1 -1
  51. package/dist/tools/inspiredesign_run.d.ts.map +1 -1
  52. package/dist/tools/status.d.ts.map +1 -1
  53. package/extension/manifest.json +1 -1
  54. package/package.json +1 -1
  55. package/skills/opendevbrowser-best-practices/SKILL.md +3 -2
  56. package/skills/opendevbrowser-design-agent/SKILL.md +1 -0
  57. package/skills/opendevbrowser-design-agent/assets/templates/inspiredesign-advanced-brief.v1.json +1370 -0
  58. package/skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh +2 -0
  59. package/dist/chunk-5I6TZRVS.js.map +0 -1
  60. package/dist/chunk-K2TEHJCV.js.map +0 -1
  61. /package/dist/{providers-6YVHKTOJ.js.map → providers-T2FQJCF6.js.map} +0 -0
@@ -9828,365 +9828,6 @@ var enrichResearchRecords = (records, timebox, now = /* @__PURE__ */ new Date())
9828
9828
  return records.map((record) => toResearchRecord(record, timebox, now));
9829
9829
  };
9830
9830
 
9831
- // src/inspiredesign/handoff.ts
9832
- var INSPIREDESIGN_HANDOFF_FILES = {
9833
- designMarkdown: "design.md",
9834
- designContract: "design-contract.json",
9835
- canvasPlanRequest: "canvas-plan.request.json",
9836
- designAgentHandoff: "design-agent-handoff.json",
9837
- generationPlan: "generation-plan.json",
9838
- implementationPlanMarkdown: "implementation-plan.md",
9839
- implementationPlan: "implementation-plan.json",
9840
- evidence: "evidence.json",
9841
- prototypeGuidance: "prototype-guidance.md"
9842
- };
9843
- var INSPIREDESIGN_HANDOFF_SKILLS = {
9844
- bestPractices: {
9845
- name: "opendevbrowser-best-practices",
9846
- topic: "quick start"
9847
- },
9848
- designAgent: {
9849
- name: "opendevbrowser-design-agent",
9850
- topic: "canvas-contract"
9851
- }
9852
- };
9853
- var formatSkillReference = (skill) => `${skill.name} "${skill.topic}"`;
9854
- var formatSkillLoadCommand = (skill) => `opendevbrowser_skill_load ${skill.name} "${skill.topic}"`;
9855
- var INSPIREDESIGN_HANDOFF_COMMANDS = {
9856
- loadBestPractices: formatSkillLoadCommand(INSPIREDESIGN_HANDOFF_SKILLS.bestPractices),
9857
- loadDesignAgent: formatSkillLoadCommand(INSPIREDESIGN_HANDOFF_SKILLS.designAgent),
9858
- continueInCanvas: `opendevbrowser canvas --command canvas.plan.set --params-file ./${INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest}`
9859
- };
9860
- var INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS = [
9861
- formatSkillReference(INSPIREDESIGN_HANDOFF_SKILLS.bestPractices),
9862
- formatSkillReference(INSPIREDESIGN_HANDOFF_SKILLS.designAgent)
9863
- ];
9864
- var INSPIREDESIGN_HANDOFF_GUIDANCE = {
9865
- prepareCanvasPlanRequest: `Fill canvasSessionId, leaseId, and documentId in ${INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest} before running ${INSPIREDESIGN_HANDOFF_COMMANDS.continueInCanvas}.`,
9866
- deepCaptureRecommendation: "Rerun inspiredesign with captureMode=deep only when you need richer evidence for visual hierarchy, protected references, or capture-specific debugging."
9867
- };
9868
- var buildInspiredesignFollowthroughSummary = () => `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 rerun with captureMode=deep only when you need richer evidence.`;
9869
- var buildInspiredesignNextStep = () => `${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}.`;
9870
-
9871
- // src/providers/renderer.ts
9872
- var toCurrency = (value) => `$${value.toFixed(2)}`;
9873
- var primaryConstraintSummaryFromMeta = (meta) => {
9874
- const summary = meta.primaryConstraintSummary;
9875
- return typeof summary === "string" && summary.trim().length > 0 ? summary.trim() : null;
9876
- };
9877
- var compactResearchLines = (records, meta) => {
9878
- if (records.length === 0) {
9879
- const summary = primaryConstraintSummaryFromMeta(meta);
9880
- return summary ? [
9881
- "No records matched the requested timebox.",
9882
- `Primary constraint: ${summary}`
9883
- ] : ["No records matched the requested timebox."];
9884
- }
9885
- return records.slice(0, 10).map((record, index) => {
9886
- const title = record.title ?? record.url ?? record.provider;
9887
- const engagement = record.engagement.likes + record.engagement.comments + record.engagement.upvotes;
9888
- return `${index + 1}. ${title} (${record.source}/${record.provider}) score=${record.confidence.toFixed(2)} engagement=${engagement}`;
9889
- });
9890
- };
9891
- var renderResearch = (args) => {
9892
- const lines = compactResearchLines(args.records, args.meta);
9893
- const summary = lines.join("\n");
9894
- const markdown = [
9895
- `# Research: ${args.topic}`,
9896
- "",
9897
- ...lines,
9898
- "",
9899
- "## Metadata",
9900
- "```json",
9901
- JSON.stringify(args.meta, null, 2),
9902
- "```"
9903
- ].join("\n");
9904
- const contextPayload = {
9905
- topic: args.topic,
9906
- highlights: lines,
9907
- records: args.records,
9908
- meta: args.meta
9909
- };
9910
- const files = [
9911
- { path: "summary.md", content: markdown },
9912
- { path: "records.json", content: { records: args.records } },
9913
- { path: "context.json", content: contextPayload },
9914
- { path: "meta.json", content: args.meta }
9915
- ];
9916
- if (args.mode === "compact") {
9917
- return {
9918
- response: {
9919
- mode: args.mode,
9920
- summary,
9921
- meta: args.meta
9922
- },
9923
- files
9924
- };
9925
- }
9926
- if (args.mode === "json") {
9927
- return {
9928
- response: {
9929
- mode: args.mode,
9930
- records: args.records,
9931
- meta: args.meta
9932
- },
9933
- files
9934
- };
9935
- }
9936
- if (args.mode === "md") {
9937
- return {
9938
- response: {
9939
- mode: args.mode,
9940
- markdown,
9941
- meta: args.meta
9942
- },
9943
- files
9944
- };
9945
- }
9946
- if (args.mode === "context") {
9947
- return {
9948
- response: {
9949
- mode: args.mode,
9950
- context: contextPayload,
9951
- meta: args.meta
9952
- },
9953
- files
9954
- };
9955
- }
9956
- return {
9957
- response: {
9958
- mode: "path",
9959
- meta: args.meta
9960
- },
9961
- files
9962
- };
9963
- };
9964
- var toComparisonCsv = (offers) => {
9965
- const header = ["provider", "title", "price", "shipping", "deal_score", "availability", "url"].join(",");
9966
- const rows = offers.map((offer) => {
9967
- return [
9968
- offer.provider,
9969
- JSON.stringify(offer.title),
9970
- offer.price.amount.toFixed(2),
9971
- offer.shipping.amount.toFixed(2),
9972
- offer.deal_score.toFixed(4),
9973
- offer.availability,
9974
- canonicalizeUrl(offer.url)
9975
- ].join(",");
9976
- });
9977
- return [header, ...rows].join("\n");
9978
- };
9979
- var compactShoppingLines = (offers, meta) => {
9980
- if (offers.length === 0) {
9981
- const summary = primaryConstraintSummaryFromMeta(meta);
9982
- return summary ? [
9983
- "No offers available from the selected providers.",
9984
- `Primary constraint: ${summary}`
9985
- ] : ["No offers available from the selected providers."];
9986
- }
9987
- return offers.slice(0, 10).map((offer, index) => {
9988
- const total = offer.price.amount + offer.shipping.amount;
9989
- return `${index + 1}. ${offer.title} - ${toCurrency(total)} (${offer.provider}, deal=${offer.deal_score.toFixed(2)})`;
9990
- });
9991
- };
9992
- var renderShopping = (args) => {
9993
- const lines = compactShoppingLines(args.offers, args.meta);
9994
- const markdown = [
9995
- `# Shopping: ${args.query}`,
9996
- "",
9997
- ...lines,
9998
- "",
9999
- "## Metadata",
10000
- "```json",
10001
- JSON.stringify(args.meta, null, 2),
10002
- "```"
10003
- ].join("\n");
10004
- const comparisonCsv = toComparisonCsv(args.offers);
10005
- const contextPayload = {
10006
- query: args.query,
10007
- highlights: lines,
10008
- offers: args.offers,
10009
- meta: args.meta
10010
- };
10011
- const files = [
10012
- { path: "deals.md", content: markdown },
10013
- { path: "offers.json", content: { offers: args.offers } },
10014
- { path: "comparison.csv", content: comparisonCsv },
10015
- { path: "meta.json", content: args.meta },
10016
- { path: "deals-context.json", content: contextPayload }
10017
- ];
10018
- if (args.mode === "compact") {
10019
- return {
10020
- response: {
10021
- mode: args.mode,
10022
- summary: lines.join("\n"),
10023
- meta: args.meta
10024
- },
10025
- files
10026
- };
10027
- }
10028
- if (args.mode === "json") {
10029
- return {
10030
- response: {
10031
- mode: args.mode,
10032
- offers: args.offers,
10033
- meta: args.meta
10034
- },
10035
- files
10036
- };
10037
- }
10038
- if (args.mode === "md") {
10039
- return {
10040
- response: {
10041
- mode: args.mode,
10042
- markdown,
10043
- meta: args.meta
10044
- },
10045
- files
10046
- };
10047
- }
10048
- if (args.mode === "context") {
10049
- return {
10050
- response: {
10051
- mode: args.mode,
10052
- context: contextPayload,
10053
- meta: args.meta
10054
- },
10055
- files
10056
- };
10057
- }
10058
- return {
10059
- response: {
10060
- mode: "path",
10061
- meta: args.meta
10062
- },
10063
- files
10064
- };
10065
- };
10066
- var renderInspiredesign = (args) => {
10067
- const summary = [
10068
- `Brief: ${args.brief}`,
10069
- `References: ${args.urls.length}`,
10070
- `Profile: ${args.generationPlan.visualDirection.profile}`
10071
- ].join("\n");
10072
- const contextPayload = {
10073
- brief: args.brief,
10074
- urls: args.urls,
10075
- designContract: args.designContract,
10076
- canvasPlanRequest: args.canvasPlanRequest,
10077
- designAgentHandoff: args.designAgentHandoff,
10078
- generationPlan: args.generationPlan,
10079
- implementationPlan: args.implementationPlan,
10080
- designMarkdown: args.designMarkdown,
10081
- implementationPlanMarkdown: args.implementationPlanMarkdown,
10082
- prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
10083
- evidence: args.evidence,
10084
- meta: args.meta
10085
- };
10086
- const suggestedSteps = [
10087
- {
10088
- reason: "Load the baseline workflow runbook before implementation.",
10089
- command: args.designAgentHandoff.commandExamples.loadBestPractices
10090
- },
10091
- {
10092
- reason: "Load the Canvas contract lane before patching.",
10093
- command: args.designAgentHandoff.commandExamples.loadDesignAgent
10094
- },
10095
- {
10096
- reason: INSPIREDESIGN_HANDOFF_GUIDANCE.prepareCanvasPlanRequest,
10097
- command: args.designAgentHandoff.commandExamples.continueInCanvas
10098
- },
10099
- {
10100
- reason: args.designAgentHandoff.deepCaptureRecommendation
10101
- }
10102
- ];
10103
- const files = [
10104
- { path: INSPIREDESIGN_HANDOFF_FILES.designMarkdown, content: args.designMarkdown },
10105
- { path: INSPIREDESIGN_HANDOFF_FILES.designContract, content: args.designContract },
10106
- { path: INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest, content: args.canvasPlanRequest },
10107
- { path: INSPIREDESIGN_HANDOFF_FILES.designAgentHandoff, content: args.designAgentHandoff },
10108
- { path: INSPIREDESIGN_HANDOFF_FILES.generationPlan, content: args.generationPlan },
10109
- { path: INSPIREDESIGN_HANDOFF_FILES.implementationPlanMarkdown, content: args.implementationPlanMarkdown },
10110
- { path: INSPIREDESIGN_HANDOFF_FILES.implementationPlan, content: args.implementationPlan },
10111
- { path: INSPIREDESIGN_HANDOFF_FILES.evidence, content: args.evidence }
10112
- ];
10113
- if (args.prototypeGuidanceMarkdown) {
10114
- files.push({ path: INSPIREDESIGN_HANDOFF_FILES.prototypeGuidance, content: args.prototypeGuidanceMarkdown });
10115
- }
10116
- if (args.mode === "compact") {
10117
- return {
10118
- response: {
10119
- mode: args.mode,
10120
- summary,
10121
- followthroughSummary: args.designAgentHandoff.summary,
10122
- suggestedNextAction: args.designAgentHandoff.nextStep,
10123
- suggestedSteps,
10124
- meta: args.meta
10125
- },
10126
- files
10127
- };
10128
- }
10129
- if (args.mode === "json") {
10130
- return {
10131
- response: {
10132
- mode: args.mode,
10133
- brief: args.brief,
10134
- urls: args.urls,
10135
- canvasPlanRequest: args.canvasPlanRequest,
10136
- designAgentHandoff: args.designAgentHandoff,
10137
- designContract: args.designContract,
10138
- generationPlan: args.generationPlan,
10139
- implementationPlan: args.implementationPlan,
10140
- prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
10141
- evidence: args.evidence,
10142
- followthroughSummary: args.designAgentHandoff.summary,
10143
- suggestedNextAction: args.designAgentHandoff.nextStep,
10144
- suggestedSteps,
10145
- meta: args.meta
10146
- },
10147
- files
10148
- };
10149
- }
10150
- if (args.mode === "md") {
10151
- return {
10152
- response: {
10153
- mode: args.mode,
10154
- markdown: args.designMarkdown,
10155
- implementationPlanMarkdown: args.implementationPlanMarkdown,
10156
- prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
10157
- followthroughSummary: args.designAgentHandoff.summary,
10158
- suggestedNextAction: args.designAgentHandoff.nextStep,
10159
- suggestedSteps,
10160
- meta: args.meta
10161
- },
10162
- files
10163
- };
10164
- }
10165
- if (args.mode === "context") {
10166
- return {
10167
- response: {
10168
- mode: args.mode,
10169
- context: contextPayload,
10170
- followthroughSummary: args.designAgentHandoff.summary,
10171
- suggestedNextAction: args.designAgentHandoff.nextStep,
10172
- suggestedSteps,
10173
- meta: args.meta
10174
- },
10175
- files
10176
- };
10177
- }
10178
- return {
10179
- response: {
10180
- mode: "path",
10181
- followthroughSummary: args.designAgentHandoff.summary,
10182
- suggestedNextAction: args.designAgentHandoff.nextStep,
10183
- suggestedSteps,
10184
- meta: args.meta
10185
- },
10186
- files
10187
- };
10188
- };
10189
-
10190
9831
  // src/providers/inspiredesign-contract.ts
10191
9832
  import { createHash as createHash3 } from "crypto";
10192
9833
 
@@ -10424,72 +10065,1759 @@ var design_contract_v1_default = {
10424
10065
  mode: "high-fi-live-edit",
10425
10066
  summary: "Improve hierarchy, clarity, and conversion confidence"
10426
10067
  },
10427
- visualDirection: {
10428
- profile: "product-led-clarity",
10429
- styleAxes: {
10430
- contrast: "high",
10431
- density: "airy"
10068
+ visualDirection: {
10069
+ profile: "product-led-clarity",
10070
+ styleAxes: {
10071
+ contrast: "high",
10072
+ density: "airy"
10073
+ }
10074
+ },
10075
+ layoutStrategy: {
10076
+ approach: "hero-led-grid"
10077
+ },
10078
+ contentStrategy: {
10079
+ source: "real-content-first"
10080
+ },
10081
+ componentStrategy: {
10082
+ mode: "reuse-first",
10083
+ approvedLibraries: [
10084
+ "shadcn"
10085
+ ]
10086
+ },
10087
+ motionPosture: {
10088
+ level: "subtle",
10089
+ allow3D: false,
10090
+ allowParallax: false,
10091
+ allowCustomSmoothScroll: false
10092
+ },
10093
+ responsivePosture: {
10094
+ primaryViewport: "desktop",
10095
+ requiredViewports: [
10096
+ "desktop",
10097
+ "tablet",
10098
+ "mobile"
10099
+ ]
10100
+ },
10101
+ accessibilityPosture: {
10102
+ target: "WCAG_2_2_AA",
10103
+ reducedMotion: "required",
10104
+ keyboardParity: true
10105
+ },
10106
+ validationTargets: {
10107
+ blockOn: [
10108
+ "contrast-failure",
10109
+ "keyboard-regression",
10110
+ "stale-search-results",
10111
+ "invalid-route-recovery-failure"
10112
+ ],
10113
+ warnOn: [
10114
+ "responsive-mismatch",
10115
+ "layout-shift",
10116
+ "spinner-stacking",
10117
+ "scan-surface-jank"
10118
+ ]
10119
+ }
10120
+ }
10121
+ };
10122
+
10123
+ // src/inspiredesign/handoff.ts
10124
+ var INSPIREDESIGN_HANDOFF_FILES = {
10125
+ designMarkdown: "design.md",
10126
+ advancedBrief: "advanced-brief.md",
10127
+ designContract: "design-contract.json",
10128
+ canvasPlanRequest: "canvas-plan.request.json",
10129
+ designAgentHandoff: "design-agent-handoff.json",
10130
+ generationPlan: "generation-plan.json",
10131
+ implementationPlanMarkdown: "implementation-plan.md",
10132
+ implementationPlan: "implementation-plan.json",
10133
+ evidence: "evidence.json",
10134
+ prototypeGuidance: "prototype-guidance.md"
10135
+ };
10136
+ var INSPIREDESIGN_HANDOFF_SKILLS = {
10137
+ bestPractices: {
10138
+ name: "opendevbrowser-best-practices",
10139
+ topic: "quick start"
10140
+ },
10141
+ designAgent: {
10142
+ name: "opendevbrowser-design-agent",
10143
+ topic: "canvas-contract"
10144
+ }
10145
+ };
10146
+ var formatSkillReference = (skill) => `${skill.name} "${skill.topic}"`;
10147
+ var formatSkillLoadCommand = (skill) => `opendevbrowser_skill_load ${skill.name} "${skill.topic}"`;
10148
+ var INSPIREDESIGN_HANDOFF_COMMANDS = {
10149
+ loadBestPractices: formatSkillLoadCommand(INSPIREDESIGN_HANDOFF_SKILLS.bestPractices),
10150
+ loadDesignAgent: formatSkillLoadCommand(INSPIREDESIGN_HANDOFF_SKILLS.designAgent),
10151
+ continueInCanvas: `opendevbrowser canvas --command canvas.plan.set --params-file ./${INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest}`
10152
+ };
10153
+ var INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS = [
10154
+ formatSkillReference(INSPIREDESIGN_HANDOFF_SKILLS.bestPractices),
10155
+ formatSkillReference(INSPIREDESIGN_HANDOFF_SKILLS.designAgent)
10156
+ ];
10157
+ var INSPIREDESIGN_HANDOFF_GUIDANCE = {
10158
+ reviewAdvancedBrief: `${INSPIREDESIGN_HANDOFF_FILES.advancedBrief} is the authoritative prompt route for the selected format, profile defaults, layout posture, motion grammar, and anti-patterns. Read it before touching Canvas or implementation files.`,
10159
+ prepareCanvasPlanRequest: `Fill canvasSessionId, leaseId, and documentId in ${INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest} before running ${INSPIREDESIGN_HANDOFF_COMMANDS.continueInCanvas}.`,
10160
+ 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
+ };
10162
+ 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
+ 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
+
10165
+ // skills/opendevbrowser-design-agent/assets/templates/inspiredesign-advanced-brief.v1.json
10166
+ var inspiredesign_advanced_brief_v1_default = {
10167
+ version: "inspiredesign-advanced-brief.v1",
10168
+ defaultFormatId: "premium-editorial-landing-page",
10169
+ commonRules: [
10170
+ "Preserve only the product, brand, audience, platform, and tone cues that are explicitly present in the source brief.",
10171
+ "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."
10173
+ ],
10174
+ outputRequirements: [
10175
+ "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."
10177
+ ],
10178
+ formats: [
10179
+ {
10180
+ id: "premium-editorial-landing-page",
10181
+ label: "Premium editorial landing page",
10182
+ bestFor: [
10183
+ "product homepages",
10184
+ "docs homepages",
10185
+ "launch pages",
10186
+ "rebrands"
10187
+ ],
10188
+ businessFocus: [
10189
+ "premium SaaS marketing",
10190
+ "product launches",
10191
+ "docs-first brands",
10192
+ "brand refresh surfaces"
10193
+ ],
10194
+ keywords: [
10195
+ "landing",
10196
+ "homepage",
10197
+ "launch",
10198
+ "brand",
10199
+ "editorial",
10200
+ "hero",
10201
+ "marketing",
10202
+ "docs"
10203
+ ],
10204
+ matchSignals: {
10205
+ positive: [
10206
+ "landing",
10207
+ "homepage",
10208
+ "home page",
10209
+ "launch",
10210
+ "brand",
10211
+ "rebrand",
10212
+ "editorial",
10213
+ "hero",
10214
+ "marketing",
10215
+ "docs"
10216
+ ],
10217
+ excluded: [
10218
+ "dashboard",
10219
+ "admin",
10220
+ "onboarding"
10221
+ ],
10222
+ tieBreaker: 1
10223
+ },
10224
+ 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
+ archetype: "editorial brand campaign",
10226
+ layoutArchetype: "full-bleed hero with narrative section cadence",
10227
+ typographySystem: "display serif or refined grotesk headlines paired with restrained sans body copy",
10228
+ surfaceTreatment: "bright print-like planes, disciplined image crops, and hairline dividers",
10229
+ shapeLanguage: "sharp framing with selective soft corners only where interaction requires it",
10230
+ componentGrammar: "hero composition, proof bands, narrative media strips, restrained CTA groups",
10231
+ motionGrammar: "measured fades, staggered reveals, and restrained parallax",
10232
+ paletteIntent: "bright neutral field with one confident accent and controlled contrast",
10233
+ visualDensity: "airy",
10234
+ designVariance: "balanced asymmetry",
10235
+ focusAreas: [
10236
+ "hero composition",
10237
+ "brand presence",
10238
+ "typography rhythm",
10239
+ "spacing cadence",
10240
+ "image treatment",
10241
+ "CTA hierarchy",
10242
+ "section sequencing",
10243
+ "trust-building moments",
10244
+ "motion tone"
10245
+ ],
10246
+ responsiveCollapseRules: [
10247
+ "Collapse split editorial compositions into a single text-first stack before line length becomes cramped.",
10248
+ "Keep one dominant visual plane on mobile rather than shrinking multiple competing media blocks."
10249
+ ],
10250
+ guardrails: [
10251
+ "Prioritize one dominant hero idea and a clear narrative progression instead of dashboard-style clutter.",
10252
+ "Favor a full-bleed visual approach with restrained supporting copy and deliberate section sequencing."
10253
+ ],
10254
+ antiPatterns: [
10255
+ "No feature-card hero.",
10256
+ "No metric strip in the first viewport.",
10257
+ "No generic startup copy tone.",
10258
+ "No dashboard chrome on a marketing surface."
10259
+ ],
10260
+ deliverables: [
10261
+ "Translate the references into a reusable design contract that fits the product story, audience, and brand voice in the source brief.",
10262
+ "Define the hero doctrine, visual hierarchy, and section cadence clearly enough for a first implementation pass."
10263
+ ],
10264
+ route: {
10265
+ profile: "product-story",
10266
+ themeStrategy: "single-theme",
10267
+ navigationModel: "global-header",
10268
+ layoutApproach: "editorial-hero-sequence"
10269
+ }
10270
+ },
10271
+ {
10272
+ id: "b2b-dashboard-app-shell",
10273
+ label: "B2B dashboard or app shell",
10274
+ bestFor: [
10275
+ "admin products",
10276
+ "internal tools",
10277
+ "data-heavy SaaS"
10278
+ ],
10279
+ businessFocus: [
10280
+ "operations software",
10281
+ "internal tooling",
10282
+ "multi-tenant analytics products",
10283
+ "enterprise control surfaces"
10284
+ ],
10285
+ keywords: [
10286
+ "dashboard",
10287
+ "admin",
10288
+ "app shell",
10289
+ "internal tool",
10290
+ "operator",
10291
+ "table",
10292
+ "analytics",
10293
+ "SaaS"
10294
+ ],
10295
+ matchSignals: {
10296
+ positive: [
10297
+ "dashboard",
10298
+ "admin",
10299
+ "app shell",
10300
+ "app-shell",
10301
+ "internal tool",
10302
+ "operator",
10303
+ "table",
10304
+ "analytics",
10305
+ "saas",
10306
+ "control room"
10307
+ ],
10308
+ excluded: [
10309
+ "onboarding",
10310
+ "villa",
10311
+ "festival"
10312
+ ],
10313
+ tieBreaker: 2
10314
+ },
10315
+ lead: "Use the inspiration references and source brief to extract a reusable dashboard and app-shell contract that stays fast, calm, and operator-friendly.",
10316
+ archetype: "operational workspace shell",
10317
+ layoutArchetype: "predictable desktop shell with fixed navigation zones and state-aware work panels",
10318
+ typographySystem: "sharp grotesk UI type with monospaced numeric support for tables and diagnostics",
10319
+ surfaceTreatment: "bright control-room surfaces with disciplined dividers and low-elevation panels",
10320
+ shapeLanguage: "rectilinear structure with restrained radii and explicit separators",
10321
+ componentGrammar: "sidebar, command toolbar, filter rail, data tables, detail drawers, empty states",
10322
+ motionGrammar: "state-transition clarity, panel continuity, and zero decorative animation noise",
10323
+ paletteIntent: "crisp neutral shell with one utility accent and clear semantic state colors",
10324
+ visualDensity: "dense but breathable",
10325
+ designVariance: "low-variance structure",
10326
+ focusAreas: [
10327
+ "information hierarchy",
10328
+ "sidebar behavior",
10329
+ "top-bar responsibilities",
10330
+ "search and filter placement",
10331
+ "table-versus-card decisions",
10332
+ "density management",
10333
+ "panel rhythm",
10334
+ "empty states",
10335
+ "loading states",
10336
+ "primary action priority"
10337
+ ],
10338
+ responsiveCollapseRules: [
10339
+ "Collapse secondary panes before compressing the primary work surface.",
10340
+ "Preserve search, filters, and the primary action path as fixed zones on narrow breakpoints."
10341
+ ],
10342
+ guardrails: [
10343
+ "Favor predictable layout zones, strong state communication, and clean action paths over decorative UI noise.",
10344
+ "Keep the interaction model credible and scalable across desktop breakpoints."
10345
+ ],
10346
+ antiPatterns: [
10347
+ "No hero marketing treatment inside the shell.",
10348
+ "No floating-window chaos.",
10349
+ "No equal-emphasis KPI tiles everywhere.",
10350
+ "No ornamental glass or neon styling."
10351
+ ],
10352
+ deliverables: [
10353
+ "Return a dashboard contract that can guide a first implementation plan and a Canvas-first prototype handoff.",
10354
+ "Specify the shell grammar for navigation, filters, data views, and state feedback."
10355
+ ],
10356
+ route: {
10357
+ profile: "ops-control",
10358
+ themeStrategy: "single-theme",
10359
+ navigationModel: "sidebar",
10360
+ layoutApproach: "workspace-shell"
10361
+ }
10362
+ },
10363
+ {
10364
+ id: "cinematic-product-story",
10365
+ label: "Cinematic product-story or photostudio direction",
10366
+ bestFor: [
10367
+ "hardware",
10368
+ "consumer products",
10369
+ "showcase pages",
10370
+ "keynote-style launches"
10371
+ ],
10372
+ businessFocus: [
10373
+ "hardware launches",
10374
+ "premium consumer products",
10375
+ "device showcases",
10376
+ "showcase-led commerce alternatives"
10377
+ ],
10378
+ keywords: [
10379
+ "product story",
10380
+ "hardware",
10381
+ "device",
10382
+ "physical product",
10383
+ "showcase",
10384
+ "photography",
10385
+ "keynote"
10386
+ ],
10387
+ matchSignals: {
10388
+ positive: [
10389
+ "product story",
10390
+ "product-story",
10391
+ "hardware",
10392
+ "device",
10393
+ "physical product",
10394
+ "showcase",
10395
+ "photography",
10396
+ "launch page",
10397
+ "keynote",
10398
+ "consumer product"
10399
+ ],
10400
+ excluded: [
10401
+ "dashboard",
10402
+ "settings",
10403
+ "festival"
10404
+ ],
10405
+ tieBreaker: 2
10406
+ },
10407
+ lead: "Study the inspiration references and synthesize a cinematic product-story direction that turns the source brief into a premium, product-led narrative.",
10408
+ archetype: "photostudio launch narrative",
10409
+ layoutArchetype: "scene-based scroll story with full-bleed product reveals",
10410
+ typographySystem: "restrained sans or condensed display with large scale contrast and minimal body copy",
10411
+ surfaceTreatment: "dark or bright studio backdrops, high-contrast product planes, and controlled material highlights",
10412
+ shapeLanguage: "large uninterrupted planes with almost no ornamental framing",
10413
+ componentGrammar: "scene hero, proof interludes, spec reveals, testimonial or quote punctuations",
10414
+ motionGrammar: "slow dissolves, glide transitions, and product-led reveal timing",
10415
+ paletteIntent: "controlled studio palette that serves material realism instead of interface variety",
10416
+ visualDensity: "sparse",
10417
+ designVariance: "high cinematic contrast",
10418
+ focusAreas: [
10419
+ "lighting",
10420
+ "framing",
10421
+ "crop strategy",
10422
+ "material and surface cues",
10423
+ "typography restraint",
10424
+ "scroll pacing",
10425
+ "transition from emotion to proof",
10426
+ "product-detail storytelling"
10427
+ ],
10428
+ responsiveCollapseRules: [
10429
+ "Keep one scene per scroll beat on mobile instead of compressing multiple proof layers together.",
10430
+ "Stack product proof and supporting copy under the main image plane once panoramic width is lost."
10431
+ ],
10432
+ guardrails: [
10433
+ "Do not fall back to generic ecommerce grids, trust-badge clutter, or spec-dump layouts.",
10434
+ "Prioritize product-story clarity over commerce-system conventions and keep the scene count disciplined."
10435
+ ],
10436
+ antiPatterns: [
10437
+ "No marketplace product grid.",
10438
+ "No coupon or deal framing.",
10439
+ "No dense comparison tables in the hero.",
10440
+ "No dashboard-like metric blocks."
10441
+ ],
10442
+ deliverables: [
10443
+ "Return a premium product-led story with 3 to 5 clear scene beats and a strong visual hierarchy.",
10444
+ "Define the scene structure, motion posture, and proof handoff clearly enough for a launch-page build."
10445
+ ],
10446
+ route: {
10447
+ profile: "cinematic-minimal",
10448
+ themeStrategy: "single-theme",
10449
+ navigationModel: "immersive",
10450
+ layoutApproach: "product-scene-scroll"
10451
+ }
10452
+ },
10453
+ {
10454
+ id: "mobile-first-onboarding-activation",
10455
+ label: "Mobile-first onboarding and activation flow",
10456
+ bestFor: [
10457
+ "consumer apps",
10458
+ "onboarding redesigns",
10459
+ "activation funnel work"
10460
+ ],
10461
+ businessFocus: [
10462
+ "consumer mobile apps",
10463
+ "activation funnel redesigns",
10464
+ "first-session experiences",
10465
+ "trust-forward account creation"
10466
+ ],
10467
+ keywords: [
10468
+ "mobile",
10469
+ "onboarding",
10470
+ "activation",
10471
+ "signup",
10472
+ "first session",
10473
+ "consumer app",
10474
+ "funnel"
10475
+ ],
10476
+ matchSignals: {
10477
+ positive: [
10478
+ "mobile",
10479
+ "onboarding",
10480
+ "activation",
10481
+ "signup",
10482
+ "sign-up",
10483
+ "first session",
10484
+ "consumer app",
10485
+ "funnel",
10486
+ "activation flow",
10487
+ "native app"
10488
+ ],
10489
+ required: [
10490
+ "mobile"
10491
+ ],
10492
+ excluded: [
10493
+ "dashboard",
10494
+ "festival"
10495
+ ],
10496
+ tieBreaker: 2
10497
+ },
10498
+ lead: "Work from the inspiration references and source brief to define a mobile-first onboarding and activation experience that moves a user from curiosity to a confident first action.",
10499
+ archetype: "trust-forward activation flow",
10500
+ layoutArchetype: "screen-sequenced onboarding stack with clear first-action transition",
10501
+ typographySystem: "high-legibility mobile sans with deliberate contrast between titles, helper copy, and CTA labels",
10502
+ surfaceTreatment: "native-feeling surfaces, clean overlays, and quiet previews of the core product",
10503
+ shapeLanguage: "soft, tap-friendly forms and decisive CTA containers",
10504
+ componentGrammar: "value slides, progress moments, CTA stacks, trust cues, first-session empty states",
10505
+ motionGrammar: "confident screen pacing, low-friction transitions, and gentle confirmation motion",
10506
+ paletteIntent: "safe, modern mobile palette with one brand accent and generous clean space",
10507
+ visualDensity: "balanced",
10508
+ designVariance: "low-noise clarity",
10509
+ focusAreas: [
10510
+ "first impression",
10511
+ "explanation of value",
10512
+ "screen pacing",
10513
+ "UI-preview usage",
10514
+ "illustration or motion strategy",
10515
+ "trust cues",
10516
+ "CTA structure",
10517
+ "key transition moments",
10518
+ "first-session empty state behavior",
10519
+ "visual rules that should carry into the core product"
10520
+ ],
10521
+ responsiveCollapseRules: [
10522
+ "Treat mobile as the source layout and only expand supporting previews for larger breakpoints.",
10523
+ "Keep primary CTAs anchored within thumb reach when the flow collapses to narrow screens."
10524
+ ],
10525
+ guardrails: [
10526
+ "Keep the system simple, emotionally clear, and conversion-focused instead of overloaded with feature marketing.",
10527
+ "Make the outcome feel native, modern, and brand-specific rather than template-driven."
10528
+ ],
10529
+ antiPatterns: [
10530
+ "No marketing landing page hero inside onboarding.",
10531
+ "No overloaded feature tour before first action.",
10532
+ "No desktop-first shell adapted down to mobile.",
10533
+ "No modal maze."
10534
+ ],
10535
+ deliverables: [
10536
+ "Return a reusable onboarding direction that can become both a contract and an implementation-ready prototype plan.",
10537
+ "Define the launch tone, CTA posture, first-session empty-state behavior, and transition moments."
10538
+ ],
10539
+ route: {
10540
+ profile: "auth-focused",
10541
+ themeStrategy: "light-dark-parity",
10542
+ navigationModel: "contextual",
10543
+ layoutApproach: "stacked-mobile-flow"
10544
+ }
10545
+ },
10546
+ {
10547
+ id: "existing-product-redesign",
10548
+ label: "Existing product redesign from inspiration",
10549
+ bestFor: [
10550
+ "redesigns that must keep identity",
10551
+ "quality upgrades without a full rebrand",
10552
+ "surface modernization"
10553
+ ],
10554
+ businessFocus: [
10555
+ "existing digital products",
10556
+ "incremental modernization programs",
10557
+ "identity-preserving redesigns",
10558
+ "mature brands needing a quality lift"
10559
+ ],
10560
+ keywords: [
10561
+ "redesign",
10562
+ "refresh",
10563
+ "modernize",
10564
+ "upgrade",
10565
+ "existing product",
10566
+ "keep identity"
10567
+ ],
10568
+ matchSignals: {
10569
+ positive: [
10570
+ "redesign",
10571
+ "refresh",
10572
+ "modernize",
10573
+ "upgrade",
10574
+ "existing product",
10575
+ "current product",
10576
+ "keep identity",
10577
+ "retain identity",
10578
+ "simplify",
10579
+ "amplify"
10580
+ ],
10581
+ excluded: [
10582
+ "festival",
10583
+ "villa"
10584
+ ],
10585
+ tieBreaker: 1
10586
+ },
10587
+ lead: "Compare the source brief against the inspiration references and synthesize a redesign contract that upgrades the product without discarding its core identity.",
10588
+ archetype: "incremental premium redesign",
10589
+ layoutArchetype: "familiar shell with sharpened hierarchy and reduced ornament",
10590
+ typographySystem: "brand-safe type refresh that raises contrast without forcing a new visual language",
10591
+ surfaceTreatment: "existing brand DNA cleaned into brighter, calmer, more disciplined surfaces",
10592
+ shapeLanguage: "minimal shape shifts that improve confidence without looking like a rebrand",
10593
+ componentGrammar: "keep-versus-rebuild map across nav, hero, sections, cards, and forms",
10594
+ motionGrammar: "subtle polish motion that signals quality rather than novelty",
10595
+ paletteIntent: "stay inside brand memory while improving clarity, contrast, and discipline",
10596
+ visualDensity: "balanced",
10597
+ designVariance: "low-disruption improvement",
10598
+ focusAreas: [
10599
+ "hierarchy",
10600
+ "tone",
10601
+ "composition",
10602
+ "visual confidence",
10603
+ "motion",
10604
+ "photography",
10605
+ "layout discipline",
10606
+ "what to keep",
10607
+ "what to remove",
10608
+ "what to simplify",
10609
+ "what to amplify"
10610
+ ],
10611
+ responsiveCollapseRules: [
10612
+ "Preserve the core product shell while removing only the weakest supporting decoration on smaller breakpoints.",
10613
+ "Collapse any new premium framing before harming the known action path or navigation model."
10614
+ ],
10615
+ guardrails: [
10616
+ "Avoid superficial mimicry and avoid proposing a totally unrelated brand system.",
10617
+ "Favor the smallest coherent visual shift that creates a real quality jump."
10618
+ ],
10619
+ antiPatterns: [
10620
+ "No hard rebrand unless the brief explicitly asks for it.",
10621
+ "No novelty components that disrupt known user flows.",
10622
+ "No random style mixing from multiple references.",
10623
+ "No gratuitous animation layer."
10624
+ ],
10625
+ deliverables: [
10626
+ "Return a transformation plan that is specific enough to drive implementation-plan artifacts and clear enough to hand directly into Canvas.",
10627
+ "Explain what to keep, remove, simplify, amplify, and restyle across the core surface."
10628
+ ],
10629
+ route: {
10630
+ profile: "clean-room",
10631
+ themeStrategy: "single-theme",
10632
+ navigationModel: "contextual",
10633
+ layoutApproach: "incremental-redesign-system"
10432
10634
  }
10433
10635
  },
10434
- layoutStrategy: {
10435
- approach: "hero-led-grid"
10636
+ {
10637
+ id: "maison-campaign-world",
10638
+ label: "Maison campaign world",
10639
+ bestFor: [
10640
+ "luxury fashion",
10641
+ "fragrance launches",
10642
+ "jewelry campaigns",
10643
+ "premium hospitality brands"
10644
+ ],
10645
+ businessFocus: [
10646
+ "fashion maisons",
10647
+ "luxury accessories",
10648
+ "fragrance campaigns",
10649
+ "high-end hospitality identity"
10650
+ ],
10651
+ keywords: [
10652
+ "maison",
10653
+ "atelier",
10654
+ "collection",
10655
+ "season",
10656
+ "campaign",
10657
+ "couture",
10658
+ "fragrance",
10659
+ "heritage"
10660
+ ],
10661
+ matchSignals: {
10662
+ positive: [
10663
+ "maison",
10664
+ "atelier",
10665
+ "collection",
10666
+ "season",
10667
+ "campaign",
10668
+ "craft",
10669
+ "couture",
10670
+ "fragrance",
10671
+ "editorial",
10672
+ "heritage"
10673
+ ],
10674
+ excluded: [
10675
+ "dashboard",
10676
+ "onboarding",
10677
+ "table"
10678
+ ],
10679
+ tieBreaker: 3
10680
+ },
10681
+ lead: "Study the inspiration references and synthesize a maison campaign system that feels expensive, editorial, and brand-sovereign rather than digitally generic.",
10682
+ archetype: "luxury campaign world",
10683
+ layoutArchetype: "poster-scale editorial spread with chaptered campaign beats",
10684
+ typographySystem: "high-contrast serif display paired with a narrow polished grotesk support system",
10685
+ surfaceTreatment: "bright gallery whites, deep photographic contrast, and couture-grade negative space",
10686
+ shapeLanguage: "frame-led compositions, hairline dividers, and almost no utilitarian chrome",
10687
+ componentGrammar: "campaign hero, chapter markers, collection highlights, quote interludes, couture CTA moments",
10688
+ motionGrammar: "slow dissolves, image drifts, and precise text reveal pacing",
10689
+ paletteIntent: "light editorial base with ink-black contrast and one jewel-toned accent",
10690
+ visualDensity: "very airy",
10691
+ designVariance: "high-fashion asymmetry",
10692
+ focusAreas: [
10693
+ "brand mythmaking",
10694
+ "editorial pacing",
10695
+ "hero image posture",
10696
+ "headline scale",
10697
+ "collection sequencing",
10698
+ "proof without dashboard logic",
10699
+ "campaign chapter structure"
10700
+ ],
10701
+ responsiveCollapseRules: [
10702
+ "Keep one campaign image dominant on mobile rather than shrinking a spread into multiple tiles.",
10703
+ "Move supporting chapter markers beneath the hero stack once the poster layout collapses."
10704
+ ],
10705
+ guardrails: [
10706
+ "Keep the system poised, bright, and expensive rather than dark, loud, or overtly technical.",
10707
+ "Treat interaction chrome as secondary to image-led composition and typographic authority."
10708
+ ],
10709
+ antiPatterns: [
10710
+ "No SaaS cards.",
10711
+ "No metric strips.",
10712
+ "No feature-grid hero.",
10713
+ "No startup copy tone."
10714
+ ],
10715
+ deliverables: [
10716
+ "Define the hero doctrine, chapter sequence, typography scale, photography treatment, motion cues, and CTA posture.",
10717
+ "Return a reusable campaign-world contract that can scale across launch, collection, and brand story surfaces."
10718
+ ],
10719
+ route: {
10720
+ profile: "cinematic-minimal",
10721
+ themeStrategy: "single-theme",
10722
+ navigationModel: "immersive",
10723
+ layoutApproach: "maison-editorial-campaign"
10724
+ }
10436
10725
  },
10437
- contentStrategy: {
10438
- source: "real-content-first"
10726
+ {
10727
+ id: "sunlit-resort-narrative",
10728
+ label: "Sunlit resort narrative",
10729
+ bestFor: [
10730
+ "destination resorts",
10731
+ "travel products",
10732
+ "premium real estate hospitality",
10733
+ "villa or stay showcases"
10734
+ ],
10735
+ businessFocus: [
10736
+ "resort brands",
10737
+ "villa booking experiences",
10738
+ "destination marketing",
10739
+ "luxury stay products"
10740
+ ],
10741
+ keywords: [
10742
+ "retreat",
10743
+ "stay",
10744
+ "villa",
10745
+ "destination",
10746
+ "itinerary",
10747
+ "suite",
10748
+ "property",
10749
+ "oceanview"
10750
+ ],
10751
+ matchSignals: {
10752
+ positive: [
10753
+ "retreat",
10754
+ "stay",
10755
+ "villa",
10756
+ "destination",
10757
+ "itinerary",
10758
+ "suite",
10759
+ "property",
10760
+ "escape",
10761
+ "reservation",
10762
+ "oceanview"
10763
+ ],
10764
+ excluded: [
10765
+ "dashboard",
10766
+ "admin",
10767
+ "table"
10768
+ ],
10769
+ tieBreaker: 3
10770
+ },
10771
+ lead: "Work from the references to create a resort narrative system that feels sunlit, breathable, and destination-led rather than like a booking engine template.",
10772
+ archetype: "panoramic hospitality story",
10773
+ layoutArchetype: "panoramic media planes with story-to-booking progression",
10774
+ typographySystem: "refined sans with lightly romantic display moments and generous line length",
10775
+ surfaceTreatment: "warm mineral surfaces, luminous image planes, and quiet itinerary bands",
10776
+ shapeLanguage: "soft-edged frames, map ribbons, and understated sectional dividers",
10777
+ componentGrammar: "panorama hero, itinerary strips, amenity chapters, map moments, booking CTA band",
10778
+ motionGrammar: "soft parallax, crossfades, and calm scroll pacing",
10779
+ paletteIntent: "sunlit mineral neutrals with ocean or stone accents",
10780
+ visualDensity: "airy",
10781
+ designVariance: "serene asymmetry",
10782
+ focusAreas: [
10783
+ "story-to-booking flow",
10784
+ "gallery rhythm",
10785
+ "map placement",
10786
+ "reservation CTA timing",
10787
+ "ambient proof moments",
10788
+ "quiet destination framing"
10789
+ ],
10790
+ responsiveCollapseRules: [
10791
+ "Collapse panoramas into one priority image followed by itinerary and booking content.",
10792
+ "Move any map or amenity ribbons below the first booking CTA on narrow screens."
10793
+ ],
10794
+ guardrails: [
10795
+ "Keep the composition spacious, bright, and calm rather than dense or transactional in the first viewport.",
10796
+ "Use reservation moments as a payoff to the story, not as the dominant hero payload."
10797
+ ],
10798
+ antiPatterns: [
10799
+ "No booking-engine clutter above the fold.",
10800
+ "No discount language.",
10801
+ "No crowded comparison blocks.",
10802
+ "No generic travel-card mosaic."
10803
+ ],
10804
+ deliverables: [
10805
+ "Define the story-to-booking sequence, gallery rules, map module grammar, booking CTA cadence, and responsive image behavior.",
10806
+ "Return a reusable hospitality narrative contract that can support both destination storytelling and conversion."
10807
+ ],
10808
+ route: {
10809
+ profile: "product-story",
10810
+ themeStrategy: "single-theme",
10811
+ navigationModel: "immersive",
10812
+ layoutApproach: "panoramic-resort-story"
10813
+ }
10439
10814
  },
10440
- componentStrategy: {
10441
- mode: "reuse-first",
10442
- approvedLibraries: [
10443
- "shadcn"
10444
- ]
10815
+ {
10816
+ id: "architecture-monograph-system",
10817
+ label: "Architecture monograph system",
10818
+ bestFor: [
10819
+ "architecture studios",
10820
+ "interior practices",
10821
+ "luxury real estate showcases",
10822
+ "industrial design portfolios"
10823
+ ],
10824
+ businessFocus: [
10825
+ "architecture practices",
10826
+ "interior design studios",
10827
+ "monograph-style project archives",
10828
+ "project-led real estate showcases"
10829
+ ],
10830
+ keywords: [
10831
+ "studio",
10832
+ "practice",
10833
+ "residence",
10834
+ "project archive",
10835
+ "monograph",
10836
+ "materiality",
10837
+ "plan",
10838
+ "case study"
10839
+ ],
10840
+ matchSignals: {
10841
+ positive: [
10842
+ "studio",
10843
+ "practice",
10844
+ "residence",
10845
+ "project archive",
10846
+ "monograph",
10847
+ "materiality",
10848
+ "plan",
10849
+ "section",
10850
+ "site",
10851
+ "case study"
10852
+ ],
10853
+ excluded: [
10854
+ "dashboard",
10855
+ "activation",
10856
+ "festival"
10857
+ ],
10858
+ tieBreaker: 3
10859
+ },
10860
+ lead: "Study the references and define an architecture monograph system that feels rigorous, silent, and materially precise rather than market-driven.",
10861
+ archetype: "architectural monograph",
10862
+ layoutArchetype: "baseline-driven case-study grid with full-bleed drawing and photography pairings",
10863
+ typographySystem: "elegant serif narrative text with mono or narrow sans captioning for plans, sections, and annotations",
10864
+ surfaceTreatment: "paper-bright backgrounds, disciplined black rules, and full-bleed documentation plates",
10865
+ shapeLanguage: "hard-edged framing, asymmetrical margins, and gallery-like restraint",
10866
+ componentGrammar: "project index, drawing plate, material notes, caption rails, silent CTA treatments",
10867
+ motionGrammar: "almost-silent motion, precise image crossfades, and subtle chapter shifts",
10868
+ paletteIntent: "architectural neutrals with stone, graphite, and one material accent",
10869
+ visualDensity: "measured",
10870
+ designVariance: "controlled asymmetry",
10871
+ focusAreas: [
10872
+ "archive index design",
10873
+ "case-study cadence",
10874
+ "plan and section treatment",
10875
+ "caption systems",
10876
+ "material cues",
10877
+ "image rhythm",
10878
+ "spacing discipline"
10879
+ ],
10880
+ responsiveCollapseRules: [
10881
+ "Stack drawings and photography vertically before shrinking annotation legibility.",
10882
+ "Keep captions attached to their artifacts on mobile instead of floating them into side rails."
10883
+ ],
10884
+ guardrails: [
10885
+ "Keep the system rigorous, restrained, and material-first rather than promotional.",
10886
+ "Let drawings, plans, and photography carry authority instead of decorative interface chrome."
10887
+ ],
10888
+ antiPatterns: [
10889
+ "No rounded-card ecosystem.",
10890
+ "No playful animation.",
10891
+ "No marketing filler.",
10892
+ "No sales-led CTA dominance."
10893
+ ],
10894
+ deliverables: [
10895
+ "Define the archive index, case-study template, caption rules, image rhythm, and spacing discipline.",
10896
+ "Return a monograph-grade contract that can guide both portfolio and project-depth surfaces."
10897
+ ],
10898
+ route: {
10899
+ profile: "clean-room",
10900
+ themeStrategy: "single-theme",
10901
+ navigationModel: "contextual",
10902
+ layoutApproach: "monograph-case-study-grid"
10903
+ }
10445
10904
  },
10446
- motionPosture: {
10447
- level: "subtle",
10448
- allow3D: false,
10449
- allowParallax: false,
10450
- allowCustomSmoothScroll: false
10905
+ {
10906
+ id: "luminous-research-atlas",
10907
+ label: "Luminous research atlas",
10908
+ bestFor: [
10909
+ "AI labs",
10910
+ "think tanks",
10911
+ "climate or health research",
10912
+ "data-storytelling products"
10913
+ ],
10914
+ businessFocus: [
10915
+ "research organizations",
10916
+ "evidence-led storytelling",
10917
+ "atlas and observatory products",
10918
+ "methodology-rich publications"
10919
+ ],
10920
+ keywords: [
10921
+ "atlas",
10922
+ "observatory",
10923
+ "methodology",
10924
+ "evidence",
10925
+ "report",
10926
+ "research",
10927
+ "index",
10928
+ "publication"
10929
+ ],
10930
+ matchSignals: {
10931
+ positive: [
10932
+ "atlas",
10933
+ "observatory",
10934
+ "methodology",
10935
+ "evidence",
10936
+ "report",
10937
+ "research",
10938
+ "map",
10939
+ "model",
10940
+ "index",
10941
+ "publication"
10942
+ ],
10943
+ excluded: [
10944
+ "checkout",
10945
+ "festival",
10946
+ "villa"
10947
+ ],
10948
+ tieBreaker: 3
10949
+ },
10950
+ lead: "Study the inspiration references and synthesize a luminous research atlas that turns evidence, methodology, and narrative into a premium, readable system.",
10951
+ archetype: "annotated evidence atlas",
10952
+ layoutArchetype: "bright scroll atlas with chaptered evidence bands and annotation rails",
10953
+ typographySystem: "precise sans for data and narrative paired with restrained serif emphasis",
10954
+ surfaceTreatment: "ivory research planes, layered evidence visuals, and quiet annotation rails",
10955
+ shapeLanguage: "clean modules, chart frames, citation bars, and highlighted note rails",
10956
+ componentGrammar: "evidence chapters, methodology blocks, chart plates, callout annotations, citation modules",
10957
+ motionGrammar: "zoom-and-highlight transitions, subtle annotation reveals, and calm data emphasis",
10958
+ paletteIntent: "bright ivory base with measured accent coding for evidence groups",
10959
+ visualDensity: "balanced",
10960
+ designVariance: "structured expressiveness",
10961
+ focusAreas: [
10962
+ "evidence hierarchy",
10963
+ "methodology framing",
10964
+ "annotation rails",
10965
+ "chart grammar",
10966
+ "citation treatment",
10967
+ "scroll-story beats",
10968
+ "proof sequencing"
10969
+ ],
10970
+ responsiveCollapseRules: [
10971
+ "Collapse annotation rails beneath the primary evidence block before reducing chart legibility.",
10972
+ "Keep citations attached to the relevant section on mobile instead of moving them to a distant appendix treatment."
10973
+ ],
10974
+ guardrails: [
10975
+ "Keep the surface bright, exact, and evidence-first rather than dashboard-like or cyber-styled.",
10976
+ "Use motion only to clarify how the user should read charts, maps, and methodology layers."
10977
+ ],
10978
+ antiPatterns: [
10979
+ "No cyber glow.",
10980
+ "No dashboard clutter.",
10981
+ "No decorative charts.",
10982
+ "No unexplained iconography."
10983
+ ],
10984
+ deliverables: [
10985
+ "Define the evidence hierarchy, chart grammar, annotation system, citation treatment, and scroll-story beats.",
10986
+ "Return a premium research contract detailed enough for publication surfaces and Canvas-ready implementation."
10987
+ ],
10988
+ route: {
10989
+ profile: "documentation",
10990
+ themeStrategy: "single-theme",
10991
+ navigationModel: "contextual",
10992
+ layoutApproach: "annotated-atlas-scroll"
10993
+ }
10451
10994
  },
10452
- responsivePosture: {
10453
- primaryViewport: "desktop",
10454
- requiredViewports: [
10455
- "desktop",
10456
- "tablet",
10457
- "mobile"
10458
- ]
10995
+ {
10996
+ id: "private-wealth-salon",
10997
+ label: "Private wealth salon",
10998
+ bestFor: [
10999
+ "private banking",
11000
+ "wealth platforms",
11001
+ "family office software",
11002
+ "premium fintech"
11003
+ ],
11004
+ businessFocus: [
11005
+ "private client finance",
11006
+ "wealth intelligence products",
11007
+ "family office tools",
11008
+ "advisor-facing premium fintech"
11009
+ ],
11010
+ keywords: [
11011
+ "wealth",
11012
+ "capital",
11013
+ "portfolio",
11014
+ "treasury",
11015
+ "allocation",
11016
+ "advisor",
11017
+ "estate",
11018
+ "reporting"
11019
+ ],
11020
+ matchSignals: {
11021
+ positive: [
11022
+ "wealth",
11023
+ "capital",
11024
+ "portfolio",
11025
+ "treasury",
11026
+ "allocation",
11027
+ "advisor",
11028
+ "private client",
11029
+ "estate",
11030
+ "intelligence",
11031
+ "reporting"
11032
+ ],
11033
+ excluded: [
11034
+ "crypto",
11035
+ "token",
11036
+ "festival"
11037
+ ],
11038
+ tieBreaker: 3
11039
+ },
11040
+ lead: "Work from the references to synthesize a private wealth system that feels like a discreet salon rather than a retail fintech dashboard.",
11041
+ archetype: "salon-grade trust interface",
11042
+ layoutArchetype: "split-panel trust sequence with couture data previews and service-led sections",
11043
+ typographySystem: "tall high-contrast headlines with polished sans detail and refined numeric styling",
11044
+ surfaceTreatment: "warm neutral surfaces, quiet paper textures, and disciplined premium separators",
11045
+ shapeLanguage: "framed content rooms, quiet tab rails, and couture table spacing",
11046
+ componentGrammar: "trust hero, portfolio preview, advisor modules, secure access moments, service panels",
11047
+ motionGrammar: "restrained hover microphysics and dignified panel continuity",
11048
+ paletteIntent: "warm neutrals, muted metallic accents, and calm signal colors",
11049
+ visualDensity: "measured",
11050
+ designVariance: "low-noise luxury",
11051
+ focusAreas: [
11052
+ "trust architecture",
11053
+ "advisor touchpoints",
11054
+ "portfolio preview hierarchy",
11055
+ "secure entry tone",
11056
+ "service-led proof",
11057
+ "numeric typography discipline"
11058
+ ],
11059
+ responsiveCollapseRules: [
11060
+ "Collapse split salons into a single guided trust sequence before compressing numeric previews.",
11061
+ "Keep the secure action path and advisor contact moment visible without crowding the first viewport."
11062
+ ],
11063
+ guardrails: [
11064
+ "Keep the system discreet, bright, and high-confidence instead of aggressive or hype-driven.",
11065
+ "Treat data previews as crafted typography and spacing problems, not as loud KPI tiles."
11066
+ ],
11067
+ antiPatterns: [
11068
+ "No crypto aesthetic.",
11069
+ "No KPI tile wall.",
11070
+ "No loud B2B dashboard chrome.",
11071
+ "No neon or dark-trading UI posture."
11072
+ ],
11073
+ deliverables: [
11074
+ "Define the trust architecture, data-preview modules, advisor touchpoints, secure entry tone, and motion restraint rules.",
11075
+ "Return a reusable private-wealth contract that can guide both marketing and authenticated advisory surfaces."
11076
+ ],
11077
+ route: {
11078
+ profile: "clean-room",
11079
+ themeStrategy: "single-theme",
11080
+ navigationModel: "contextual",
11081
+ layoutApproach: "salon-trust-panels"
11082
+ }
10459
11083
  },
10460
- accessibilityPosture: {
10461
- target: "WCAG_2_2_AA",
10462
- reducedMotion: "required",
10463
- keyboardParity: true
11084
+ {
11085
+ id: "cultural-festival-atlas",
11086
+ label: "Cultural festival atlas",
11087
+ bestFor: [
11088
+ "biennales",
11089
+ "art fairs",
11090
+ "music festivals",
11091
+ "design weeks",
11092
+ "premium conferences"
11093
+ ],
11094
+ businessFocus: [
11095
+ "festival identity systems",
11096
+ "program-driven event surfaces",
11097
+ "cultural institutions",
11098
+ "multi-venue schedule products"
11099
+ ],
11100
+ keywords: [
11101
+ "edition",
11102
+ "lineup",
11103
+ "program",
11104
+ "venue",
11105
+ "exhibition",
11106
+ "passes",
11107
+ "festival",
11108
+ "screening"
11109
+ ],
11110
+ matchSignals: {
11111
+ positive: [
11112
+ "edition",
11113
+ "lineup",
11114
+ "program",
11115
+ "venue",
11116
+ "exhibition",
11117
+ "passes",
11118
+ "festival",
11119
+ "talks",
11120
+ "screening",
11121
+ "schedule"
11122
+ ],
11123
+ excluded: [
11124
+ "dashboard",
11125
+ "billing",
11126
+ "checkout"
11127
+ ],
11128
+ tieBreaker: 3
11129
+ },
11130
+ lead: "Study the references and define a cultural festival atlas that feels poster-led, kinetic, and editorial rather than like a corporate event microsite.",
11131
+ archetype: "poster-grid program atlas",
11132
+ layoutArchetype: "chaptered program sequence with wayfinding color blocks and event-driven typographic beats",
11133
+ typographySystem: "expressive variable type paired with a sober schedule support face",
11134
+ surfaceTreatment: "bright poster fields, color-block navigation, and layered program markers",
11135
+ shapeLanguage: "poster frames, directional bars, stacked ribbons, and event tags",
11136
+ componentGrammar: "edition hero, lineup atlas, schedule chapters, venue maps, ticket pathways",
11137
+ motionGrammar: "kinetic type bands, chapter transitions, and route-aware section motion",
11138
+ paletteIntent: "bright thematic palette system with venue or category coding",
11139
+ visualDensity: "high but legible",
11140
+ designVariance: "high-expression systems",
11141
+ focusAreas: [
11142
+ "identity system",
11143
+ "schedule grammar",
11144
+ "venue map modules",
11145
+ "ticket CTA logic",
11146
+ "wayfinding hierarchy",
11147
+ "program chaptering"
11148
+ ],
11149
+ responsiveCollapseRules: [
11150
+ "Reduce poster-grid complexity to a clean event list plus prominent schedule filters on mobile.",
11151
+ "Keep venue maps and ticket actions in the same narrative lane once space becomes limited."
11152
+ ],
11153
+ guardrails: [
11154
+ "Keep the direction cultural, expressive, and controlled rather than generic corporate-conference UI.",
11155
+ "Let typography and wayfinding structure create the energy before adding decorative media."
11156
+ ],
11157
+ antiPatterns: [
11158
+ "No corporate conference template.",
11159
+ "No equal-width card grids.",
11160
+ "No dead spreadsheet agenda hero.",
11161
+ "No low-energy generic icon rows."
11162
+ ],
11163
+ deliverables: [
11164
+ "Define the identity system, schedule grammar, venue map modules, ticket CTA logic, and motion choreography.",
11165
+ "Return a reusable festival contract that can cover edition landing, lineup, program, and pass-conversion surfaces."
11166
+ ],
11167
+ route: {
11168
+ profile: "cinematic-minimal",
11169
+ themeStrategy: "multi-theme-system",
11170
+ navigationModel: "immersive",
11171
+ layoutApproach: "poster-program-sequence"
11172
+ }
10464
11173
  },
10465
- validationTargets: {
10466
- blockOn: [
10467
- "contrast-failure",
10468
- "keyboard-regression",
10469
- "stale-search-results",
10470
- "invalid-route-recovery-failure"
11174
+ {
11175
+ id: "wellness-ritual-system",
11176
+ label: "Wellness ritual system",
11177
+ bestFor: [
11178
+ "beauty",
11179
+ "skincare",
11180
+ "clinics",
11181
+ "premium wellness apps",
11182
+ "recovery products"
10471
11183
  ],
10472
- warnOn: [
10473
- "responsive-mismatch",
10474
- "layout-shift",
10475
- "spinner-stacking",
10476
- "scan-surface-jank"
10477
- ]
11184
+ businessFocus: [
11185
+ "wellness programs",
11186
+ "skincare systems",
11187
+ "beauty rituals",
11188
+ "recovery and clinic products"
11189
+ ],
11190
+ keywords: [
11191
+ "ritual",
11192
+ "treatment",
11193
+ "glow",
11194
+ "routine",
11195
+ "recovery",
11196
+ "clinic",
11197
+ "ingredient",
11198
+ "reset"
11199
+ ],
11200
+ matchSignals: {
11201
+ positive: [
11202
+ "ritual",
11203
+ "treatment",
11204
+ "glow",
11205
+ "routine",
11206
+ "recovery",
11207
+ "clinic",
11208
+ "session",
11209
+ "ingredient",
11210
+ "skin",
11211
+ "reset"
11212
+ ],
11213
+ excluded: [
11214
+ "dashboard",
11215
+ "table",
11216
+ "festival"
11217
+ ],
11218
+ tieBreaker: 3
11219
+ },
11220
+ lead: "Study the references and synthesize a wellness ritual system that feels luminous, calm, and premium without collapsing into stock spa cliches.",
11221
+ archetype: "ritual-led wellness story",
11222
+ layoutArchetype: "porcelain chapter flow with ritual steps, proof surfaces, and booking or activation moments",
11223
+ typographySystem: "soft modern serif accents over highly legible sans narrative copy",
11224
+ surfaceTreatment: "porcelain surfaces, mineral gradients, translucent layers, and macro texture photography",
11225
+ shapeLanguage: "gentle curves, rounded panels, and flowing sectional transitions",
11226
+ componentGrammar: "ritual hero, routine modules, ingredient proof surfaces, booking moments, calm testimonials",
11227
+ motionGrammar: "breathing rhythm, gentle float motion, and calm confirmation transitions",
11228
+ paletteIntent: "bright mineral palette with skin-safe neutrals and one clean accent",
11229
+ visualDensity: "airy",
11230
+ designVariance: "soft continuity",
11231
+ focusAreas: [
11232
+ "ritual flow modules",
11233
+ "ingredient and proof surfaces",
11234
+ "booking posture",
11235
+ "first-session tone",
11236
+ "wellness trust cues",
11237
+ "motion breathing rules"
11238
+ ],
11239
+ responsiveCollapseRules: [
11240
+ "Stack ritual steps vertically before shrinking proof imagery or ingredient legibility.",
11241
+ "Keep booking or activation moments separated from storytelling content on narrow screens."
11242
+ ],
11243
+ guardrails: [
11244
+ "Keep the system bright, thematic, and premium rather than washed-out, decorative, or medicalized.",
11245
+ "Use motion to reinforce calm confidence, not to create soft-focus vagueness."
11246
+ ],
11247
+ antiPatterns: [
11248
+ "No stock-spa cliches.",
11249
+ "No pseudo-medical dashboard.",
11250
+ "No oversaturated gradient fog.",
11251
+ "No generic beauty ecommerce grid."
11252
+ ],
11253
+ deliverables: [
11254
+ "Define the ritual flow modules, ingredient and proof surfaces, booking moments, first-session tone, and motion breathing rules.",
11255
+ "Return a reusable wellness contract for product, clinic, and app activation surfaces."
11256
+ ],
11257
+ route: {
11258
+ profile: "product-story",
11259
+ themeStrategy: "single-theme",
11260
+ navigationModel: "global-header",
11261
+ layoutApproach: "ritual-story-flow"
11262
+ }
11263
+ },
11264
+ {
11265
+ id: "creative-tool-laboratory",
11266
+ label: "Creative tool laboratory",
11267
+ bestFor: [
11268
+ "design tools",
11269
+ "AI builders",
11270
+ "devtools with premium brand positioning",
11271
+ "creative software"
11272
+ ],
11273
+ businessFocus: [
11274
+ "creative software",
11275
+ "builder platforms",
11276
+ "design tooling",
11277
+ "AI-assisted creation products"
11278
+ ],
11279
+ keywords: [
11280
+ "canvas",
11281
+ "lab",
11282
+ "studio",
11283
+ "editor",
11284
+ "compose",
11285
+ "prototype",
11286
+ "generate",
11287
+ "workspace",
11288
+ "toolkit",
11289
+ "layer"
11290
+ ],
11291
+ matchSignals: {
11292
+ positive: [
11293
+ "canvas",
11294
+ "lab",
11295
+ "studio",
11296
+ "editor",
11297
+ "compose",
11298
+ "prototype",
11299
+ "generate",
11300
+ "workspace",
11301
+ "toolkit",
11302
+ "layer"
11303
+ ],
11304
+ excluded: [
11305
+ "villa",
11306
+ "festival",
11307
+ "fragrance"
11308
+ ],
11309
+ tieBreaker: 3
11310
+ },
11311
+ lead: "Use the references to create a creative tool laboratory direction that feels precise, bright, and premium without falling back to generic admin shells.",
11312
+ archetype: "specimen-grade creative workspace",
11313
+ layoutArchetype: "bright laboratory shell with stage, inspector, and specimen panels",
11314
+ typographySystem: "sharp grotesk UI type with monospaced support for tokens, coordinates, and diagnostics",
11315
+ surfaceTreatment: "lab-white shell, modular trays, and layered canvas previews",
11316
+ shapeLanguage: "modular docks, specimen cards, inspector rails, and crisp separators",
11317
+ componentGrammar: "stage shell, inspector, prompt panels, specimen modules, stateful controls",
11318
+ motionGrammar: "state continuity, transform-led panel transitions, and specimen emphasis motion",
11319
+ paletteIntent: "bright lab whites with one vivid tool accent and disciplined neutral scaffolding",
11320
+ visualDensity: "balanced to dense",
11321
+ designVariance: "structured experimentation",
11322
+ focusAreas: [
11323
+ "shell grammar",
11324
+ "sidebar and inspector rules",
11325
+ "stage hierarchy",
11326
+ "specimen component set",
11327
+ "transition map",
11328
+ "tool-state communication"
11329
+ ],
11330
+ responsiveCollapseRules: [
11331
+ "Collapse the inspector after the stage and primary controls are stable on smaller breakpoints.",
11332
+ "Keep prompt input and primary creation actions in a fixed vertical lane on narrow screens."
11333
+ ],
11334
+ guardrails: [
11335
+ "Keep the workspace premium and bright, not dark-gamer or gadget-heavy.",
11336
+ "Make motion serve state continuity and tool confidence, not generic micro-animation noise."
11337
+ ],
11338
+ antiPatterns: [
11339
+ "No gamer neon.",
11340
+ "No floating-window chaos.",
11341
+ "No generic admin shell.",
11342
+ "No decorative empty-state illustration that hides the tool's real structure."
11343
+ ],
11344
+ deliverables: [
11345
+ "Define the shell grammar, sidebar and inspector rules, stage hierarchy, specimen component set, and transition map.",
11346
+ "Return a reusable creative-tool contract that can drive both the marketing frame and the actual product shell."
11347
+ ],
11348
+ route: {
11349
+ profile: "control-room",
11350
+ themeStrategy: "single-theme",
11351
+ navigationModel: "contextual",
11352
+ layoutApproach: "specimen-workspace"
11353
+ }
11354
+ },
11355
+ {
11356
+ id: "precision-mobility-flagship",
11357
+ label: "Precision mobility flagship",
11358
+ bestFor: [
11359
+ "automotive",
11360
+ "aviation",
11361
+ "robotics",
11362
+ "micromobility",
11363
+ "transport hardware"
11364
+ ],
11365
+ businessFocus: [
11366
+ "vehicle launches",
11367
+ "mobility hardware",
11368
+ "robotic systems",
11369
+ "engineering-led transport brands"
11370
+ ],
11371
+ keywords: [
11372
+ "cockpit",
11373
+ "range",
11374
+ "chassis",
11375
+ "drive",
11376
+ "vehicle",
11377
+ "engineering",
11378
+ "autonomous",
11379
+ "aero"
11380
+ ],
11381
+ matchSignals: {
11382
+ positive: [
11383
+ "cockpit",
11384
+ "range",
11385
+ "chassis",
11386
+ "drive",
11387
+ "vehicle",
11388
+ "engineering",
11389
+ "autonomous",
11390
+ "performance",
11391
+ "aero",
11392
+ "machine"
11393
+ ],
11394
+ excluded: [
11395
+ "dashboard",
11396
+ "festival",
11397
+ "onboarding"
11398
+ ],
11399
+ tieBreaker: 3
11400
+ },
11401
+ lead: "Study the references and define a precision mobility flagship that feels engineered, aerodynamic, and premium without becoming a spec dump or dealer template.",
11402
+ archetype: "engineering-led flagship story",
11403
+ layoutArchetype: "panoramic launch composition with sectional proof reveals and cockpit framing",
11404
+ typographySystem: "condensed display typography with technical mono or narrow sans support",
11405
+ surfaceTreatment: "bright or graphite technical planes, cutaway diagrams, and controlled highlight lines",
11406
+ shapeLanguage: "aerodynamic bands, sectional overlays, and instrument-inspired detail modules",
11407
+ componentGrammar: "flagship hero, technical proof rail, sectional cutaways, performance figures, CTA close",
11408
+ motionGrammar: "glide motion, instrument-style reveals, and controlled engineering emphasis",
11409
+ paletteIntent: "precision neutrals with one performance accent and disciplined contrast",
11410
+ visualDensity: "measured technical density",
11411
+ designVariance: "high-control precision",
11412
+ focusAreas: [
11413
+ "launch storyboard",
11414
+ "technical proof modules",
11415
+ "performance-data styling",
11416
+ "cutaway treatment",
11417
+ "CTA sequence",
11418
+ "motion timing"
11419
+ ],
11420
+ responsiveCollapseRules: [
11421
+ "Turn sectional cutaways into stacked proof chapters before sacrificing diagram clarity.",
11422
+ "Keep the primary performance and CTA story lane intact on mobile rather than distributing it across tabs or accordions."
11423
+ ],
11424
+ guardrails: [
11425
+ "Keep the system premium, exact, and flagship-oriented rather than automotive commerce or gadget marketing.",
11426
+ "Let engineering proof emerge in sequence instead of dumping all specifications at once."
11427
+ ],
11428
+ antiPatterns: [
11429
+ "No ecommerce spec dump.",
11430
+ "No dealer-site layout.",
11431
+ "No cluttered comparison tables above the fold.",
11432
+ "No generic performance stat tiles."
11433
+ ],
11434
+ deliverables: [
11435
+ "Define the launch storyboard, technical proof modules, performance-data styling, CTA sequence, and motion timing.",
11436
+ "Return a reusable flagship contract for mobility, robotics, and engineering-led hardware launches."
11437
+ ],
11438
+ route: {
11439
+ profile: "cinematic-minimal",
11440
+ themeStrategy: "single-theme",
11441
+ navigationModel: "immersive",
11442
+ layoutApproach: "engineering-glide-story"
11443
+ }
11444
+ },
11445
+ {
11446
+ id: "members-club-concierge",
11447
+ label: "Members club concierge",
11448
+ bestFor: [
11449
+ "invite-only communities",
11450
+ "premium memberships",
11451
+ "concierge products",
11452
+ "executive networks"
11453
+ ],
11454
+ businessFocus: [
11455
+ "membership programs",
11456
+ "concierge services",
11457
+ "executive communities",
11458
+ "invite-only access products"
11459
+ ],
11460
+ keywords: [
11461
+ "members",
11462
+ "access",
11463
+ "club",
11464
+ "concierge",
11465
+ "curation",
11466
+ "invite",
11467
+ "tier",
11468
+ "privileges"
11469
+ ],
11470
+ matchSignals: {
11471
+ positive: [
11472
+ "members",
11473
+ "access",
11474
+ "club",
11475
+ "concierge",
11476
+ "curation",
11477
+ "invite",
11478
+ "tier",
11479
+ "private",
11480
+ "privileges",
11481
+ "network"
11482
+ ],
11483
+ excluded: [
11484
+ "dashboard",
11485
+ "checkout",
11486
+ "festival"
11487
+ ],
11488
+ tieBreaker: 3
11489
+ },
11490
+ lead: "Use the references to synthesize a members-club concierge system that feels stately, selective, and service-led rather than like a benefits comparison page.",
11491
+ archetype: "private members salon",
11492
+ layoutArchetype: "invitation-led room sequence with framed service modules and access moments",
11493
+ typographySystem: "stately serif headlines with polished sans navigation and membership detail copy",
11494
+ surfaceTreatment: "bright club rooms, invitation cards, schedule ribbons, and warm premium materials",
11495
+ shapeLanguage: "framed rooms, invitation panels, ribbon markers, and curated content compartments",
11496
+ componentGrammar: "invitation hero, tier narrative, concierge request modules, schedule ribbons, social proof rooms",
11497
+ motionGrammar: "subtle reveal, magnetic hover restraint, and service-led transition pacing",
11498
+ paletteIntent: "bright cream or stone base with restrained metallic and club-accent notes",
11499
+ visualDensity: "balanced",
11500
+ designVariance: "curated composure",
11501
+ focusAreas: [
11502
+ "access narrative",
11503
+ "membership architecture",
11504
+ "concierge request surfaces",
11505
+ "proof and testimonial format",
11506
+ "schedule ribbons",
11507
+ "spacing and motion contract"
11508
+ ],
11509
+ responsiveCollapseRules: [
11510
+ "Collapse framed rooms into a guided membership sequence before compressing the access narrative.",
11511
+ "Keep the invitation and concierge request moment within the same mobile lane."
11512
+ ],
11513
+ guardrails: [
11514
+ "Keep the direction stately, bright, and selective rather than flashy or social-feed oriented.",
11515
+ "Use privilege and service cues with discipline so the surface still feels curated and elegant."
11516
+ ],
11517
+ antiPatterns: [
11518
+ "No coupon language.",
11519
+ "No social-feed feeling.",
11520
+ "No generic benefit-card grid.",
11521
+ "No noisy badge wall."
11522
+ ],
11523
+ deliverables: [
11524
+ "Define the access narrative, membership architecture, concierge request surfaces, proof format, and spacing plus motion contract.",
11525
+ "Return a reusable members-club contract for private access, service, and executive-network surfaces."
11526
+ ],
11527
+ route: {
11528
+ profile: "product-story",
11529
+ themeStrategy: "single-theme",
11530
+ navigationModel: "global-header",
11531
+ layoutApproach: "concierge-room-sequence"
11532
+ }
10478
11533
  }
11534
+ ]
11535
+ };
11536
+
11537
+ // src/inspiredesign/brief-expansion.ts
11538
+ var BRIEF_TEMPLATE = inspiredesign_advanced_brief_v1_default;
11539
+ var INSPIREDESIGN_BRIEF_TEMPLATE_VERSION = BRIEF_TEMPLATE.version;
11540
+ var normalizeInspiredesignBriefText = (value) => value.trim().replace(/\s+/g, " ");
11541
+ var formatBulletList = (items) => items.map((item) => `- ${item}`).join("\n");
11542
+ var countMatches = (brief, keywords) => {
11543
+ const haystack = brief.toLowerCase();
11544
+ return keywords.reduce(
11545
+ (total, keyword) => total + (haystack.includes(keyword.toLowerCase()) ? 1 : 0),
11546
+ 0
11547
+ );
11548
+ };
11549
+ var cloneStringList = (items) => [...items];
11550
+ var cloneRoute = (route) => ({
11551
+ profile: route.profile,
11552
+ themeStrategy: route.themeStrategy,
11553
+ navigationModel: route.navigationModel,
11554
+ layoutApproach: route.layoutApproach
11555
+ });
11556
+ var cloneInspiredesignBriefFormat = (format) => ({
11557
+ id: format.id,
11558
+ label: format.label,
11559
+ bestFor: cloneStringList(format.bestFor),
11560
+ businessFocus: cloneStringList(format.businessFocus),
11561
+ keywords: cloneStringList(format.keywords),
11562
+ archetype: format.archetype,
11563
+ layoutArchetype: format.layoutArchetype,
11564
+ typographySystem: format.typographySystem,
11565
+ surfaceTreatment: format.surfaceTreatment,
11566
+ shapeLanguage: format.shapeLanguage,
11567
+ componentGrammar: format.componentGrammar,
11568
+ motionGrammar: format.motionGrammar,
11569
+ paletteIntent: format.paletteIntent,
11570
+ visualDensity: format.visualDensity,
11571
+ designVariance: format.designVariance,
11572
+ responsiveCollapseRules: cloneStringList(format.responsiveCollapseRules),
11573
+ guardrails: cloneStringList(format.guardrails),
11574
+ antiPatterns: cloneStringList(format.antiPatterns),
11575
+ deliverables: cloneStringList(format.deliverables),
11576
+ route: cloneRoute(format.route)
11577
+ });
11578
+ var summarizeFormat = (format) => ({
11579
+ id: format.id,
11580
+ label: format.label,
11581
+ bestFor: cloneStringList(format.bestFor),
11582
+ businessFocus: cloneStringList(format.businessFocus),
11583
+ keywords: cloneStringList(format.keywords),
11584
+ archetype: format.archetype,
11585
+ layoutArchetype: format.layoutArchetype,
11586
+ typographySystem: format.typographySystem,
11587
+ surfaceTreatment: format.surfaceTreatment,
11588
+ shapeLanguage: format.shapeLanguage,
11589
+ componentGrammar: format.componentGrammar,
11590
+ motionGrammar: format.motionGrammar,
11591
+ paletteIntent: format.paletteIntent,
11592
+ visualDensity: format.visualDensity,
11593
+ designVariance: format.designVariance,
11594
+ responsiveCollapseRules: cloneStringList(format.responsiveCollapseRules),
11595
+ guardrails: cloneStringList(format.guardrails),
11596
+ antiPatterns: cloneStringList(format.antiPatterns),
11597
+ deliverables: cloneStringList(format.deliverables),
11598
+ route: cloneRoute(format.route)
11599
+ });
11600
+ var getDefaultFormat = () => {
11601
+ const defaultFormat = BRIEF_TEMPLATE.formats.find((format) => format.id === BRIEF_TEMPLATE.defaultFormatId) ?? BRIEF_TEMPLATE.formats[0];
11602
+ if (!defaultFormat) {
11603
+ throw new Error("Inspiredesign brief template must define at least one format.");
11604
+ }
11605
+ return defaultFormat;
11606
+ };
11607
+ var findFormatById = (formatId) => {
11608
+ if (!formatId) {
11609
+ return void 0;
11610
+ }
11611
+ return BRIEF_TEMPLATE.formats.find((format) => format.id === formatId);
11612
+ };
11613
+ var scoreFormat = (sourceBrief, format) => {
11614
+ const requiredMatches = countMatches(sourceBrief, format.matchSignals.required ?? []);
11615
+ if ((format.matchSignals.required?.length ?? 0) > 0 && requiredMatches === 0) {
11616
+ return Number.NEGATIVE_INFINITY;
11617
+ }
11618
+ const excludedMatches = countMatches(sourceBrief, format.matchSignals.excluded ?? []);
11619
+ const positiveMatches = countMatches(sourceBrief, format.matchSignals.positive);
11620
+ return positiveMatches * 4 + requiredMatches * 6 - excludedMatches * 8 + (format.matchSignals.tieBreaker ?? 0);
11621
+ };
11622
+ var chooseFormat = (sourceBrief) => {
11623
+ const defaultFormat = getDefaultFormat();
11624
+ const seeded = {
11625
+ score: scoreFormat(sourceBrief, defaultFormat) + 0.5,
11626
+ format: defaultFormat
11627
+ };
11628
+ return BRIEF_TEMPLATE.formats.reduce((best, format) => {
11629
+ const score = scoreFormat(sourceBrief, format);
11630
+ return score > best.score ? { score, format } : best;
11631
+ }, seeded).format;
11632
+ };
11633
+ var resolveFormat = (sourceBrief, preferredFormatId) => {
11634
+ const preferredFormat = findFormatById(preferredFormatId);
11635
+ if (preferredFormat) {
11636
+ return preferredFormat;
11637
+ }
11638
+ return chooseFormat(sourceBrief);
11639
+ };
11640
+ var buildReturnRequirements = (format) => [.../* @__PURE__ */ new Set([...format.deliverables, ...BRIEF_TEMPLATE.outputRequirements])];
11641
+ var buildRouteDefaults = (format) => [
11642
+ `profile: ${format.route.profile}`,
11643
+ `theme strategy: ${format.route.themeStrategy}`,
11644
+ `navigation model: ${format.route.navigationModel}`,
11645
+ `layout approach: ${format.route.layoutApproach}`
11646
+ ];
11647
+ var buildDesignDirection = (format) => [
11648
+ `archetype: ${format.archetype}`,
11649
+ `layout archetype: ${format.layoutArchetype}`,
11650
+ `typography system: ${format.typographySystem}`,
11651
+ `surface treatment: ${format.surfaceTreatment}`,
11652
+ `shape language: ${format.shapeLanguage}`,
11653
+ `component grammar: ${format.componentGrammar}`,
11654
+ `motion grammar: ${format.motionGrammar}`,
11655
+ `palette intent: ${format.paletteIntent}`,
11656
+ `visual density: ${format.visualDensity}`,
11657
+ `design variance: ${format.designVariance}`
11658
+ ];
11659
+ var renderAdvancedBrief = (sourceBrief, format) => [
11660
+ `Selected prompt format: ${format.label}`,
11661
+ "",
11662
+ "Source brief:",
11663
+ sourceBrief,
11664
+ "",
11665
+ "Prompt objective:",
11666
+ format.lead,
11667
+ "",
11668
+ "Business focus:",
11669
+ formatBulletList(format.businessFocus),
11670
+ "",
11671
+ "Keywords:",
11672
+ formatBulletList(format.keywords),
11673
+ "",
11674
+ "Route defaults:",
11675
+ formatBulletList(buildRouteDefaults(format)),
11676
+ "",
11677
+ "Design direction:",
11678
+ formatBulletList(buildDesignDirection(format)),
11679
+ "",
11680
+ "Focus areas:",
11681
+ formatBulletList(format.focusAreas),
11682
+ "",
11683
+ "Responsive collapse rules:",
11684
+ formatBulletList(format.responsiveCollapseRules),
11685
+ "",
11686
+ "Execution rules:",
11687
+ formatBulletList([...BRIEF_TEMPLATE.commonRules, ...format.guardrails]),
11688
+ "",
11689
+ "Anti-patterns:",
11690
+ formatBulletList(format.antiPatterns),
11691
+ "",
11692
+ "Return:",
11693
+ formatBulletList(buildReturnRequirements(format)),
11694
+ "",
11695
+ "Best fit use cases:",
11696
+ formatBulletList(format.bestFor)
11697
+ ].join("\n");
11698
+ var expandInspiredesignBrief = (brief, preferredFormatId) => {
11699
+ const sourceBrief = normalizeInspiredesignBriefText(brief);
11700
+ const format = resolveFormat(sourceBrief, preferredFormatId);
11701
+ return {
11702
+ sourceBrief,
11703
+ advancedBrief: renderAdvancedBrief(sourceBrief, format),
11704
+ templateVersion: INSPIREDESIGN_BRIEF_TEMPLATE_VERSION,
11705
+ format: summarizeFormat(format)
11706
+ };
11707
+ };
11708
+
11709
+ // src/providers/inspiredesign-contract.ts
11710
+ var INSPIREDESIGN_CAPTURE_ATTEMPT_KEYS = ["snapshot", "clone", "dom"];
11711
+ var MALFORMED_CAPTURE_ATTEMPT_DETAIL = "Capture attempt metadata missing or malformed.";
11712
+ var NORMALIZED_CAPTURE_ATTEMPT_DETAIL = "Captured artifact was empty after normalization.";
11713
+ var isJsonRecord2 = (value) => {
11714
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11715
+ };
11716
+ var isInspiredesignCaptureAttemptStatus = (value) => {
11717
+ return value === "captured" || value === "failed" || value === "skipped";
11718
+ };
11719
+ var hasUsableCaptureText = (value) => {
11720
+ return typeof value === "string" && value.trim().length > 0;
11721
+ };
11722
+ var hasUsableInspiredesignSnapshot = (capture) => {
11723
+ return hasUsableCaptureText(capture?.snapshot?.content);
11724
+ };
11725
+ var hasUsableInspiredesignDom = (capture) => {
11726
+ return hasUsableCaptureText(capture?.dom?.outerHTML);
11727
+ };
11728
+ var hasUsableInspiredesignClone = (capture) => {
11729
+ return hasUsableCaptureText(capture?.clone?.componentPreview) || hasUsableCaptureText(capture?.clone?.cssPreview);
11730
+ };
11731
+ var hasUsableInspiredesignCaptureArtifact = (capture, key) => {
11732
+ switch (key) {
11733
+ case "snapshot":
11734
+ return hasUsableInspiredesignSnapshot(capture);
11735
+ case "clone":
11736
+ return hasUsableInspiredesignClone(capture);
11737
+ case "dom":
11738
+ return hasUsableInspiredesignDom(capture);
11739
+ }
11740
+ };
11741
+ var reconcileInspiredesignCaptureAttemptEvidence = (attempt, artifactPresent) => {
11742
+ if (attempt.status !== "captured" || artifactPresent) {
11743
+ return attempt;
11744
+ }
11745
+ return {
11746
+ status: "failed",
11747
+ detail: NORMALIZED_CAPTURE_ATTEMPT_DETAIL
11748
+ };
11749
+ };
11750
+ var reconcileInspiredesignCaptureAttempts = (capture, attempts) => {
11751
+ if (!attempts) {
11752
+ return void 0;
11753
+ }
11754
+ return {
11755
+ snapshot: reconcileInspiredesignCaptureAttemptEvidence(
11756
+ attempts.snapshot,
11757
+ hasUsableInspiredesignCaptureArtifact(capture, "snapshot")
11758
+ ),
11759
+ clone: reconcileInspiredesignCaptureAttemptEvidence(
11760
+ attempts.clone,
11761
+ hasUsableInspiredesignCaptureArtifact(capture, "clone")
11762
+ ),
11763
+ dom: reconcileInspiredesignCaptureAttemptEvidence(
11764
+ attempts.dom,
11765
+ hasUsableInspiredesignCaptureArtifact(capture, "dom")
11766
+ )
11767
+ };
11768
+ };
11769
+ var hasInspiredesignCaptureArtifacts = (capture) => {
11770
+ return hasUsableInspiredesignSnapshot(capture) || hasUsableInspiredesignDom(capture) || hasUsableInspiredesignClone(capture);
11771
+ };
11772
+ var normalizeInspiredesignCaptureAttemptEvidence = (value, fallbackDetail = MALFORMED_CAPTURE_ATTEMPT_DETAIL) => {
11773
+ if (!isJsonRecord2(value) || !isInspiredesignCaptureAttemptStatus(value.status)) {
11774
+ return {
11775
+ status: "skipped",
11776
+ detail: fallbackDetail
11777
+ };
11778
+ }
11779
+ return {
11780
+ status: value.status,
11781
+ ...typeof value.detail === "string" && value.detail.trim().length > 0 ? { detail: value.detail.trim() } : {}
11782
+ };
11783
+ };
11784
+ var normalizeInspiredesignCaptureAttempts = (value) => {
11785
+ if (!isJsonRecord2(value)) {
11786
+ return void 0;
10479
11787
  }
11788
+ return {
11789
+ snapshot: normalizeInspiredesignCaptureAttemptEvidence(value.snapshot),
11790
+ clone: normalizeInspiredesignCaptureAttemptEvidence(value.clone),
11791
+ dom: normalizeInspiredesignCaptureAttemptEvidence(value.dom)
11792
+ };
11793
+ };
11794
+ var normalizeInspiredesignCaptureEvidence = (capture) => {
11795
+ if (!capture) {
11796
+ return capture;
11797
+ }
11798
+ const normalizedBase = {
11799
+ ...capture.title ? { title: capture.title } : {},
11800
+ ...hasUsableInspiredesignSnapshot(capture) && capture.snapshot ? { snapshot: capture.snapshot } : {},
11801
+ ...hasUsableInspiredesignDom(capture) && capture.dom ? { dom: capture.dom } : {},
11802
+ ...hasUsableInspiredesignClone(capture) && capture.clone ? { clone: capture.clone } : {}
11803
+ };
11804
+ const attempts = reconcileInspiredesignCaptureAttempts(
11805
+ normalizedBase,
11806
+ normalizeInspiredesignCaptureAttempts(capture.attempts)
11807
+ );
11808
+ return {
11809
+ ...normalizedBase,
11810
+ ...attempts ? { attempts } : {}
11811
+ };
11812
+ };
11813
+ var formatInspiredesignCaptureAttemptSummary = (report) => {
11814
+ const worked = report.worked.length > 0 ? report.worked.join(", ") : "none";
11815
+ const didNotWork = report.didNotWork.length > 0 ? report.didNotWork.join(", ") : "none";
11816
+ return `worked=${worked}; did_not_work=${didNotWork}`;
10480
11817
  };
10481
-
10482
- // src/providers/inspiredesign-contract.ts
10483
11818
  var BASE_CONTRACT_TEMPLATE = design_contract_v1_default;
10484
11819
  var BASE_PLAN_REQUEST_TEMPLATE = canvas_generation_plan_design_v1_default;
10485
11820
  var BASE_GENERATION_PLAN = BASE_PLAN_REQUEST_TEMPLATE.generationPlan;
10486
- var PROFILE_MATCHERS = [
10487
- { profile: "auth-focused", keywords: ["auth", "login", "signin", "sign-in", "signup", "sign-up", "onboarding"] },
10488
- { profile: "settings-system", keywords: ["settings", "preferences", "account", "profile", "billing"] },
10489
- { profile: "ops-control", keywords: ["dashboard", "admin", "control", "analytics", "monitor", "reporting"] },
10490
- { profile: "documentation", keywords: ["docs", "documentation", "knowledge base", "reference", "guide"] },
10491
- { profile: "commerce-system", keywords: ["shop", "commerce", "pricing", "checkout", "product page", "catalog"] }
10492
- ];
10493
11821
  var PROFILE_CONFIG = {
10494
11822
  "clean-room": {
10495
11823
  direction: "clean-room execution",
@@ -10719,18 +12047,6 @@ var cloneTemplate = (value) => structuredClone(value);
10719
12047
  var referenceFingerprint = (value) => {
10720
12048
  return createHash3("sha256").update(value).digest("hex").slice(0, 12);
10721
12049
  };
10722
- var hasKeyword = (value, keywords) => {
10723
- const haystack = value.toLowerCase();
10724
- return keywords.some((keyword) => haystack.includes(keyword));
10725
- };
10726
- var classifyProfile = (brief, references) => {
10727
- const combined = [brief, ...references.map((reference) => `${reference.title ?? ""} ${reference.excerpt ?? ""}`)].join(" ").toLowerCase();
10728
- return PROFILE_MATCHERS.find((matcher) => hasKeyword(combined, matcher.keywords))?.profile ?? "product-story";
10729
- };
10730
- var resolveThemeStrategy = (brief, references) => {
10731
- const combined = `${brief} ${references.map((reference) => reference.excerpt ?? "").join(" ")}`.toLowerCase();
10732
- return combined.includes("dark") ? "light-dark-parity" : "single-theme";
10733
- };
10734
12050
  var summarizeBrief = (brief) => {
10735
12051
  const normalized = trimText(brief);
10736
12052
  const sentence = normalized.split(/[.!?]/).map((part) => part.trim()).find(Boolean);
@@ -10740,24 +12056,28 @@ var buildSupportingMessages = (references) => {
10740
12056
  const messages = references.map((reference) => reference.title ?? reference.excerpt ?? "").map((value) => clipText(trimText(value), 72)).filter((value) => value.length > 0);
10741
12057
  return messages.slice(0, 3);
10742
12058
  };
10743
- var buildGenerationPlan = (brief, profile, references) => {
12059
+ var buildGenerationPlan = (brief, format) => {
10744
12060
  const plan = cloneTemplate(BASE_GENERATION_PLAN);
12061
+ const profile = format.route.profile;
10745
12062
  plan.targetOutcome.summary = summarizeBrief(brief);
10746
12063
  plan.visualDirection.profile = profile;
10747
- plan.visualDirection.themeStrategy = resolveThemeStrategy(brief, references);
10748
- plan.layoutStrategy.approach = PROFILE_CONFIG[profile].layoutApproach;
10749
- plan.layoutStrategy.navigationModel = PROFILE_CONFIG[profile].navigationModel;
12064
+ plan.visualDirection.themeStrategy = format.route.themeStrategy;
12065
+ plan.layoutStrategy.approach = format.route.layoutApproach;
12066
+ plan.layoutStrategy.navigationModel = format.route.navigationModel;
10750
12067
  plan.componentStrategy.interactionStates = ["default", "hover", "focus", "disabled", "loading"];
10751
- plan.validationTargets.requiredThemes = plan.visualDirection.themeStrategy === "light-dark-parity" ? ["light", "dark"] : ["light"];
12068
+ plan.validationTargets.requiredThemes = plan.visualDirection.themeStrategy === "single-theme" ? ["light"] : ["light", "dark"];
10752
12069
  return plan;
10753
12070
  };
10754
- var buildIntentBlock = (brief, urls, references) => {
12071
+ var buildIntentBlock = (brief, urls, references, format) => {
10755
12072
  const intent = cloneTemplate(BASE_CONTRACT_TEMPLATE.intent);
10756
12073
  return {
10757
12074
  ...intent,
10758
12075
  task: summarizeBrief(brief),
10759
12076
  brief,
10760
12077
  briefHash: referenceFingerprint(brief),
12078
+ selectedFormat: format.label,
12079
+ businessFocus: [...format.businessFocus],
12080
+ keywords: [...format.keywords],
10761
12081
  referenceCount: references.length,
10762
12082
  referenceUrls: urls,
10763
12083
  evidenceStatus: {
@@ -10766,14 +12086,20 @@ var buildIntentBlock = (brief, urls, references) => {
10766
12086
  }
10767
12087
  };
10768
12088
  };
10769
- var buildDesignLanguageBlock = (profile) => {
12089
+ var buildDesignLanguageBlock = (profile, format) => {
10770
12090
  const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.designLanguage);
10771
12091
  const config = PROFILE_CONFIG[profile];
10772
12092
  return {
10773
12093
  ...block,
10774
12094
  direction: config.direction,
10775
12095
  visualPersonality: config.visualPersonality,
10776
- brandTone: config.brandTone
12096
+ brandTone: config.brandTone,
12097
+ archetype: format.archetype,
12098
+ surfaceTreatment: format.surfaceTreatment,
12099
+ shapeLanguage: format.shapeLanguage,
12100
+ paletteIntent: format.paletteIntent,
12101
+ visualDensity: format.visualDensity,
12102
+ designVariance: format.designVariance
10777
12103
  };
10778
12104
  };
10779
12105
  var buildContentModelBlock = (brief, references) => {
@@ -10784,17 +12110,21 @@ var buildContentModelBlock = (brief, references) => {
10784
12110
  supportingMessages: buildSupportingMessages(references)
10785
12111
  };
10786
12112
  };
10787
- var buildLayoutSystemBlock = (profile) => {
12113
+ var buildLayoutSystemBlock = (plan, format) => {
10788
12114
  const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.layoutSystem);
10789
12115
  return {
10790
12116
  ...block,
10791
- pagePatterns: PROFILE_CONFIG[profile].pagePatterns
12117
+ layoutArchetype: format.layoutArchetype,
12118
+ layoutApproach: plan.layoutStrategy.approach,
12119
+ navigationModel: plan.layoutStrategy.navigationModel,
12120
+ pagePatterns: [format.layoutArchetype, ...PROFILE_CONFIG[plan.visualDirection.profile].pagePatterns]
10792
12121
  };
10793
12122
  };
10794
- var buildTypographySystemBlock = () => {
12123
+ var buildTypographySystemBlock = (format) => {
10795
12124
  const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.typographySystem);
10796
12125
  return {
10797
12126
  ...block,
12127
+ system: format.typographySystem,
10798
12128
  tokens: {
10799
12129
  display: "56/1.0",
10800
12130
  h1: "40/1.05",
@@ -10806,10 +12136,11 @@ var buildTypographySystemBlock = () => {
10806
12136
  }
10807
12137
  };
10808
12138
  };
10809
- var buildColorSystemBlock = (profile) => {
12139
+ var buildColorSystemBlock = (profile, format) => {
10810
12140
  const colors = PROFILE_CONFIG[profile].colors;
10811
12141
  return {
10812
- paletteName: `${profile}-default`,
12142
+ paletteName: `${format.id}-default`,
12143
+ paletteIntent: format.paletteIntent,
10813
12144
  tokens: colors,
10814
12145
  contrastRequirements: {
10815
12146
  bodyText: "4.5:1",
@@ -10818,7 +12149,9 @@ var buildColorSystemBlock = (profile) => {
10818
12149
  }
10819
12150
  };
10820
12151
  };
10821
- var buildSurfaceSystemBlock = () => ({
12152
+ var buildSurfaceSystemBlock = (format) => ({
12153
+ surfaceTreatment: format.surfaceTreatment,
12154
+ shapeLanguage: format.shapeLanguage,
10822
12155
  radiusScale: {
10823
12156
  xs: "6px",
10824
12157
  sm: "10px",
@@ -10841,10 +12174,11 @@ var buildIconSystemBlock = () => ({
10841
12174
  "Decorative icons should remain visually lighter than primary copy."
10842
12175
  ]
10843
12176
  });
10844
- var buildMotionSystemBlock = () => {
12177
+ var buildMotionSystemBlock = (format) => {
10845
12178
  const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.motionSystem);
10846
12179
  return {
10847
12180
  ...block,
12181
+ grammar: format.motionGrammar,
10848
12182
  durations: {
10849
12183
  quick: "120ms",
10850
12184
  standard: "180ms",
@@ -10852,10 +12186,11 @@ var buildMotionSystemBlock = () => {
10852
12186
  }
10853
12187
  };
10854
12188
  };
10855
- var buildResponsiveSystemBlock = () => {
12189
+ var buildResponsiveSystemBlock = (format) => {
10856
12190
  const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.responsiveSystem);
10857
12191
  return {
10858
12192
  ...block,
12193
+ collapseRules: [...format.responsiveCollapseRules],
10859
12194
  breakpoints: {
10860
12195
  mobile: "0-639px",
10861
12196
  tablet: "640-1023px",
@@ -10903,11 +12238,11 @@ var EMITTED_GOVERNANCE_BLOCKS = [
10903
12238
  "libraryPolicy",
10904
12239
  "runtimeBudgets"
10905
12240
  ];
10906
- var buildNavigationModelBlock = (profile) => {
12241
+ var buildNavigationModelBlock = (navigationModel) => {
10907
12242
  const block = cloneTemplate(BASE_CONTRACT_TEMPLATE.navigationModel);
10908
12243
  return {
10909
12244
  ...block,
10910
- primaryRouteModel: `Use a ${PROFILE_CONFIG[profile].navigationModel} route shell so the primary action remains stable through state changes.`
12245
+ primaryRouteModel: `Use a ${navigationModel} route shell so the primary action remains stable through state changes.`
10911
12246
  };
10912
12247
  };
10913
12248
  var buildAsyncModelBlock = () => {
@@ -10927,31 +12262,37 @@ var buildContractScope = () => ({
10927
12262
  omittedTemplateBlocks: ["navigationModel", "asyncModel", "performanceModel"],
10928
12263
  note: `${INSPIREDESIGN_HANDOFF_FILES.designContract} is the narrowed canvas governance contract. Use ${INSPIREDESIGN_HANDOFF_FILES.designAgentHandoff} for navigation, async, and performance context that informs implementation but does not belong in canvas governance patches.`
10929
12264
  });
10930
- var buildFollowthrough = (generationPlan) => ({
12265
+ var buildBriefExpansionMetadata = (briefExpansion) => ({
12266
+ templateVersion: briefExpansion.templateVersion,
12267
+ file: INSPIREDESIGN_HANDOFF_FILES.advancedBrief,
12268
+ format: cloneInspiredesignBriefFormat(briefExpansion.format)
12269
+ });
12270
+ var buildFollowthrough = (generationPlan, briefExpansion) => ({
10931
12271
  summary: buildInspiredesignFollowthroughSummary(),
10932
12272
  nextStep: buildInspiredesignNextStep(),
12273
+ briefExpansion: buildBriefExpansionMetadata(briefExpansion),
10933
12274
  recommendedSkills: [...INSPIREDESIGN_HANDOFF_RECOMMENDED_SKILLS],
10934
12275
  commandExamples: { ...INSPIREDESIGN_HANDOFF_COMMANDS },
10935
12276
  deepCaptureRecommendation: INSPIREDESIGN_HANDOFF_GUIDANCE.deepCaptureRecommendation,
10936
12277
  contractScope: buildContractScope(),
10937
12278
  implementationContext: {
10938
- navigationModel: buildNavigationModelBlock(generationPlan.visualDirection.profile),
12279
+ navigationModel: buildNavigationModelBlock(generationPlan.layoutStrategy.navigationModel),
10939
12280
  asyncModel: buildAsyncModelBlock(),
10940
12281
  performanceModel: buildPerformanceModelBlock()
10941
12282
  }
10942
12283
  });
10943
- var buildDesignContract = (brief, urls, references, plan) => ({
10944
- intent: buildIntentBlock(brief, urls, references),
12284
+ var buildDesignContract = (brief, urls, references, plan, format) => ({
12285
+ intent: buildIntentBlock(brief, urls, references, format),
10945
12286
  generationPlan: plan,
10946
- designLanguage: buildDesignLanguageBlock(plan.visualDirection.profile),
12287
+ designLanguage: buildDesignLanguageBlock(plan.visualDirection.profile, format),
10947
12288
  contentModel: buildContentModelBlock(brief, references),
10948
- layoutSystem: buildLayoutSystemBlock(plan.visualDirection.profile),
10949
- typographySystem: buildTypographySystemBlock(),
10950
- colorSystem: buildColorSystemBlock(plan.visualDirection.profile),
10951
- surfaceSystem: buildSurfaceSystemBlock(),
12289
+ layoutSystem: buildLayoutSystemBlock(plan, format),
12290
+ typographySystem: buildTypographySystemBlock(format),
12291
+ colorSystem: buildColorSystemBlock(plan.visualDirection.profile, format),
12292
+ surfaceSystem: buildSurfaceSystemBlock(format),
10952
12293
  iconSystem: buildIconSystemBlock(),
10953
- motionSystem: buildMotionSystemBlock(),
10954
- responsiveSystem: buildResponsiveSystemBlock(),
12294
+ motionSystem: buildMotionSystemBlock(format),
12295
+ responsiveSystem: buildResponsiveSystemBlock(format),
10955
12296
  accessibilityPolicy: buildAccessibilityBlock(),
10956
12297
  libraryPolicy: buildLibraryPolicyBlock(),
10957
12298
  runtimeBudgets: buildRuntimeBudgetsBlock(plan)
@@ -11012,17 +12353,17 @@ var buildComponentBuildPlan = (profile) => {
11012
12353
  implementationNote: "Use semantic tokens first and keep copy/state logic outside the visual component."
11013
12354
  }));
11014
12355
  };
11015
- var buildImplementationPlan = (brief, profile, references) => ({
11016
- architectureRecommendation: "Implement the surface as token-first components using shared semantic CSS variables, then compose page sections from those primitives before adding any page-specific polish.",
12356
+ var buildImplementationPlan = (profile, format, references) => ({
12357
+ 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.`,
11017
12358
  tokenStrategy: buildTokenStrategy(profile),
11018
12359
  componentBuildPlan: buildComponentBuildPlan(profile),
11019
12360
  pageAssemblyPlan: [
11020
- "Start with the shell and primary navigation pattern.",
12361
+ `Start with the ${format.layoutArchetype} and the primary navigation pattern.`,
11021
12362
  "Compose the hero or primary decision section before supporting sections.",
11022
12363
  "Add proof, utility, and footer sections only after the top-level hierarchy is stable."
11023
12364
  ],
11024
12365
  stateAndInteractionPlan: [
11025
- "Keep hover, focus, loading, success, and error states visually distinct.",
12366
+ `Use ${format.motionGrammar} while keeping hover, focus, loading, success, and error states visually distinct.`,
11026
12367
  "Preserve layout during loading and keep transient confirmations out of the main flow.",
11027
12368
  "Use reduced-motion-safe transitions for reveals and CTA feedback."
11028
12369
  ],
@@ -11032,6 +12373,7 @@ var buildImplementationPlan = (brief, profile, references) => ({
11032
12373
  "Keep landmarks and heading levels explicit and sequential."
11033
12374
  ],
11034
12375
  responsiveChecklist: [
12376
+ ...format.responsiveCollapseRules,
11035
12377
  "Collapse multicolumn layouts before text measure becomes cramped.",
11036
12378
  "Keep the primary CTA visible without overlap on narrow screens.",
11037
12379
  "Avoid horizontal scrolling for primary content."
@@ -11048,7 +12390,7 @@ var buildImplementationPlan = (brief, profile, references) => ({
11048
12390
  "Run accessibility, responsive, and browser QA before final polish."
11049
12391
  ]
11050
12392
  });
11051
- var formatBulletList = (items) => items.map((item) => `- ${item}`).join("\n");
12393
+ var formatBulletList2 = (items) => items.map((item) => `- ${item}`).join("\n");
11052
12394
  var formatRecordList = (record) => {
11053
12395
  return Object.entries(record).map(([key, value]) => `- \`${key}\`: ${value}`).join("\n");
11054
12396
  };
@@ -11080,38 +12422,29 @@ var renderReferenceMarkdown = (reference, index) => {
11080
12422
  `- 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.`
11081
12423
  ].join("\n");
11082
12424
  };
11083
- var resolveProfileConfigFromGenerationPlan = (generationPlan) => {
11084
- if (!generationPlan || typeof generationPlan !== "object" || !("visualDirection" in generationPlan)) {
11085
- throw new Error("Inspiredesign design contract requires a generation plan.");
11086
- }
11087
- const visualDirection = generationPlan.visualDirection;
11088
- if (!visualDirection || typeof visualDirection !== "object" || !("profile" in visualDirection)) {
11089
- throw new Error("Inspiredesign design contract requires a visual direction profile.");
11090
- }
11091
- const profile = visualDirection.profile;
11092
- if (typeof profile !== "string" || !(profile in PROFILE_CONFIG)) {
11093
- throw new Error("Inspiredesign design contract profile is invalid.");
11094
- }
11095
- return PROFILE_CONFIG[profile];
11096
- };
11097
- var renderGovernanceMarkdown = (designContract, implementationPlan) => {
11098
- const profileConfig = resolveProfileConfigFromGenerationPlan(designContract.generationPlan);
12425
+ var renderGovernanceMarkdown = (designContract, implementationPlan, format) => {
12426
+ const generationPlan = designContract.generationPlan;
12427
+ const profileConfig = PROFILE_CONFIG[generationPlan.visualDirection.profile];
11099
12428
  return [
11100
12429
  "## 4.1 Design Intent",
11101
- formatBulletList([
12430
+ formatBulletList2([
11102
12431
  `Purpose: ${designContract.intent.task || ""}`,
11103
12432
  "Capture the reusable visual logic from the references without cloning proprietary brand assets.",
11104
12433
  "Keep the resulting system executable for downstream build agents."
11105
12434
  ]),
11106
12435
  "",
11107
12436
  "## 4.2 Core UX Principles",
11108
- formatBulletList(profileConfig.hierarchyPrinciples),
12437
+ formatBulletList2(profileConfig.hierarchyPrinciples),
11109
12438
  "",
11110
12439
  "## 4.3 Visual Identity",
11111
- formatBulletList([
12440
+ formatBulletList2([
11112
12441
  `Aesthetic style: ${profileConfig.visualPersonality}`,
11113
12442
  `Brand tone: ${profileConfig.brandTone}`,
11114
12443
  `Quality posture: ${profileConfig.direction}`,
12444
+ `Format archetype: ${format.archetype}`,
12445
+ `Surface treatment: ${format.surfaceTreatment}`,
12446
+ `Shape language: ${format.shapeLanguage}`,
12447
+ `Palette intent: ${format.paletteIntent}`,
11115
12448
  "Direction: modern, system-led, and implementation-aware."
11116
12449
  ]),
11117
12450
  "",
@@ -11119,10 +12452,20 @@ var renderGovernanceMarkdown = (designContract, implementationPlan) => {
11119
12452
  formatRecordList(implementationPlan.tokenStrategy.colors),
11120
12453
  "",
11121
12454
  "## 4.5 Typography System",
11122
- formatRecordList(implementationPlan.tokenStrategy.typography),
12455
+ [
12456
+ formatBulletList2([`system: ${format.typographySystem}`]),
12457
+ formatRecordList(implementationPlan.tokenStrategy.typography)
12458
+ ].join("\n"),
11123
12459
  "",
11124
12460
  "## 4.6 Spacing and Layout System",
11125
- formatRecordList(implementationPlan.tokenStrategy.spacing),
12461
+ [
12462
+ formatBulletList2([
12463
+ `layout archetype: ${format.layoutArchetype}`,
12464
+ `layout approach: ${generationPlan.layoutStrategy.approach}`,
12465
+ `navigation model: ${generationPlan.layoutStrategy.navigationModel}`
12466
+ ]),
12467
+ formatRecordList(implementationPlan.tokenStrategy.spacing)
12468
+ ].join("\n"),
11126
12469
  "",
11127
12470
  "## 4.7 Shape, Border, and Elevation Rules",
11128
12471
  [
@@ -11131,12 +12474,15 @@ var renderGovernanceMarkdown = (designContract, implementationPlan) => {
11131
12474
  ].join("\n"),
11132
12475
  "",
11133
12476
  "## 4.8 Motion and Interaction Rules",
11134
- formatRecordList(implementationPlan.tokenStrategy.motion),
12477
+ [
12478
+ formatBulletList2([`motion grammar: ${format.motionGrammar}`]),
12479
+ formatRecordList(implementationPlan.tokenStrategy.motion)
12480
+ ].join("\n"),
11135
12481
  "",
11136
12482
  "## 4.9 Component System",
11137
12483
  implementationPlan.componentBuildPlan.map((component) => [
11138
12484
  `### ${component.name}`,
11139
- formatBulletList([
12485
+ formatBulletList2([
11140
12486
  `purpose: ${component.purpose}`,
11141
12487
  `structure: build from semantic tokens and keep state visuals explicit`,
11142
12488
  `visual style: ${profileConfig.direction}`,
@@ -11149,193 +12495,718 @@ var renderGovernanceMarkdown = (designContract, implementationPlan) => {
11149
12495
  ].join("\n")).join("\n\n"),
11150
12496
  "",
11151
12497
  "## 4.10 Page or Section Patterns",
11152
- formatBulletList(profileConfig.pagePatterns),
12498
+ formatBulletList2(profileConfig.pagePatterns),
11153
12499
  "",
11154
12500
  "## 4.11 Accessibility Requirements",
11155
- formatBulletList(implementationPlan.accessibilityChecklist),
12501
+ formatBulletList2(implementationPlan.accessibilityChecklist),
11156
12502
  "",
11157
12503
  "## 4.12 Responsiveness Requirements",
11158
- formatBulletList(implementationPlan.responsiveChecklist),
12504
+ formatBulletList2(implementationPlan.responsiveChecklist),
11159
12505
  "",
11160
12506
  "## 4.13 Content and Microcopy Guidance",
11161
- formatBulletList([
12507
+ formatBulletList2([
11162
12508
  "Use direct, confident labels and short CTA copy.",
11163
12509
  "Keep error and success messages specific to the affected region.",
11164
12510
  "Prefer descriptive button copy over generic verbs."
11165
12511
  ]),
11166
12512
  "",
11167
12513
  "## 4.14 Do / Don't Rules",
11168
- formatBulletList([
12514
+ formatBulletList2([
11169
12515
  "Do preserve one dominant message per section.",
11170
12516
  "Do encode repeated visual rules into semantic tokens.",
11171
12517
  "Don't copy proprietary logos, screenshots, or brand-only illustrations.",
11172
- "Don't hide important actions inside ambiguous hover-only affordances."
12518
+ "Don't hide important actions inside ambiguous hover-only affordances.",
12519
+ ...format.antiPatterns.map((rule) => `Don't ${rule.replace(/\.$/, "").toLowerCase()}.`)
11173
12520
  ]),
11174
12521
  "",
11175
12522
  "## 4.15 Acceptance Criteria",
11176
- formatBulletList([
12523
+ formatBulletList2([
11177
12524
  "Primary action is obvious within one viewport.",
11178
12525
  "Color, typography, spacing, and elevation all resolve through named tokens.",
11179
12526
  "Keyboard, focus, and reduced-motion behavior remain intact across breakpoints."
11180
12527
  ])
11181
12528
  ].join("\n");
11182
12529
  };
11183
- var renderImplementationMarkdown = (implementationPlan) => {
11184
- return [
11185
- "# 5. Implementation Plan",
11186
- "",
11187
- "## 5.1 Architecture Recommendation",
11188
- implementationPlan.architectureRecommendation,
11189
- "",
11190
- "## 5.2 Design Token Strategy",
11191
- formatRecordList(implementationPlan.tokenStrategy.colors),
11192
- "",
11193
- formatRecordList(implementationPlan.tokenStrategy.typography),
11194
- "",
11195
- "## 5.3 Component Build Plan",
11196
- implementationPlan.componentBuildPlan.map((component, index) => `${index + 1}. ${component.name}: ${component.purpose}`).join("\n"),
11197
- "",
11198
- "## 5.4 Page Assembly Plan",
11199
- formatBulletList(implementationPlan.pageAssemblyPlan),
11200
- "",
11201
- "## 5.5 State and Interaction Plan",
11202
- formatBulletList(implementationPlan.stateAndInteractionPlan),
11203
- "",
11204
- "## 5.6 Accessibility Implementation Checklist",
11205
- formatBulletList(implementationPlan.accessibilityChecklist),
11206
- "",
11207
- "## 5.7 Responsive Implementation Checklist",
11208
- formatBulletList(implementationPlan.responsiveChecklist),
11209
- "",
11210
- "## 5.8 Risks and Ambiguities",
11211
- formatBulletList(implementationPlan.risksAndAmbiguities),
11212
- "",
11213
- "## 5.9 Recommended Build Sequence",
11214
- implementationPlan.buildSequence.map((step, index) => `${index + 1}. ${step}`).join("\n")
11215
- ].join("\n");
12530
+ var renderImplementationMarkdown = (implementationPlan) => {
12531
+ return [
12532
+ "# 5. Implementation Plan",
12533
+ "",
12534
+ "## 5.1 Architecture Recommendation",
12535
+ implementationPlan.architectureRecommendation,
12536
+ "",
12537
+ "## 5.2 Design Token Strategy",
12538
+ formatRecordList(implementationPlan.tokenStrategy.colors),
12539
+ "",
12540
+ formatRecordList(implementationPlan.tokenStrategy.typography),
12541
+ "",
12542
+ "## 5.3 Component Build Plan",
12543
+ implementationPlan.componentBuildPlan.map((component, index) => `${index + 1}. ${component.name}: ${component.purpose}`).join("\n"),
12544
+ "",
12545
+ "## 5.4 Page Assembly Plan",
12546
+ formatBulletList2(implementationPlan.pageAssemblyPlan),
12547
+ "",
12548
+ "## 5.5 State and Interaction Plan",
12549
+ formatBulletList2(implementationPlan.stateAndInteractionPlan),
12550
+ "",
12551
+ "## 5.6 Accessibility Implementation Checklist",
12552
+ formatBulletList2(implementationPlan.accessibilityChecklist),
12553
+ "",
12554
+ "## 5.7 Responsive Implementation Checklist",
12555
+ formatBulletList2(implementationPlan.responsiveChecklist),
12556
+ "",
12557
+ "## 5.8 Risks and Ambiguities",
12558
+ formatBulletList2(implementationPlan.risksAndAmbiguities),
12559
+ "",
12560
+ "## 5.9 Recommended Build Sequence",
12561
+ implementationPlan.buildSequence.map((step, index) => `${index + 1}. ${step}`).join("\n")
12562
+ ].join("\n");
12563
+ };
12564
+ var renderPrototypeGuidance = (profile) => {
12565
+ return [
12566
+ "# 6. Optional Prototype Plan",
12567
+ "",
12568
+ "- page structure: establish the shell, hero or primary action zone, proof sections, and footer in that order.",
12569
+ `- section order: ${PROFILE_CONFIG[profile].pagePatterns.join(" -> ")}`,
12570
+ "- component composition: reuse button, card, input, and navigation primitives before page-specific wrappers.",
12571
+ "- interaction expectations: provide visible focus, compact hover feedback, and reduced-motion-safe entry transitions.",
12572
+ "- HTML skeleton guidance: start with one main landmark, one primary CTA group, and semantic sections for proof or detail bands.",
12573
+ "- styling approach: define CSS variables first, then map components to semantic tokens rather than raw values.",
12574
+ "- first prototype should include vs omit: include shell, hero, CTA, one proof section, and one form or action cluster; omit analytics, heavy animation, and tertiary content until hierarchy is proven."
12575
+ ].join("\n");
12576
+ };
12577
+ var renderDeliverablesSummary = (includePrototypeGuidance) => {
12578
+ const deliverables = [
12579
+ "Structured `designContract` JSON aligned to canvas governance",
12580
+ "Valid `generationPlan` JSON aligned to the canvas generation plan contract",
12581
+ "Ready-to-fill `canvasPlanRequest` JSON for `canvas.plan.set`",
12582
+ "Design-agent handoff JSON with contract scope, skill nudges, and richer implementation context",
12583
+ "Human-readable `design.md` design specification",
12584
+ "Engineering implementation plan in JSON and Markdown"
12585
+ ];
12586
+ if (includePrototypeGuidance) {
12587
+ deliverables.push("Prototype guidance Markdown for the first HTML pass");
12588
+ }
12589
+ deliverables.push("Evidence digest describing brief, references, fetch outcomes, and capture outcomes");
12590
+ return formatBulletList2(deliverables);
12591
+ };
12592
+ var buildEvidencePayload = (brief, briefExpansion, urls, references) => ({
12593
+ brief,
12594
+ briefHash: referenceFingerprint(brief),
12595
+ advancedBrief: briefExpansion.advancedBrief,
12596
+ advancedBriefHash: referenceFingerprint(briefExpansion.advancedBrief),
12597
+ briefExpansion: {
12598
+ templateVersion: briefExpansion.templateVersion,
12599
+ format: cloneInspiredesignBriefFormat(briefExpansion.format)
12600
+ },
12601
+ urls,
12602
+ referenceCount: references.length,
12603
+ references: references.map((reference) => toReferenceEvidenceJson(reference))
12604
+ });
12605
+ var toCaptureEvidenceJson = (capture) => {
12606
+ const normalized = normalizeInspiredesignCaptureEvidence(capture);
12607
+ if (!normalized) return null;
12608
+ return {
12609
+ ...normalized.title ? { title: normalized.title } : {},
12610
+ ...normalized.snapshot ? { snapshot: normalized.snapshot } : {},
12611
+ ...normalized.dom ? { dom: normalized.dom } : {},
12612
+ ...normalized.clone ? { clone: normalized.clone } : {},
12613
+ ...normalized.attempts ? { attempts: normalized.attempts } : {}
12614
+ };
12615
+ };
12616
+ var toReferenceEvidenceJson = (reference) => ({
12617
+ id: reference.id,
12618
+ url: reference.url,
12619
+ ...reference.title ? { title: reference.title } : {},
12620
+ ...reference.excerpt ? { excerpt: reference.excerpt } : {},
12621
+ fetchStatus: reference.fetchStatus,
12622
+ captureStatus: reference.captureStatus,
12623
+ ...reference.fetchFailure ? { fetchFailure: reference.fetchFailure } : {},
12624
+ ...reference.captureFailure ? { captureFailure: reference.captureFailure } : {},
12625
+ capture: toCaptureEvidenceJson(reference.capture)
12626
+ });
12627
+ var buildInspiredesignPacket = (input) => {
12628
+ const brief = trimText(input.brief);
12629
+ const selectedFormat = cloneInspiredesignBriefFormat(input.briefExpansion.format);
12630
+ const advancedBriefMarkdown = input.briefExpansion.advancedBrief;
12631
+ const urls = [...new Set(input.urls.map((url) => trimText(url)).filter(Boolean))];
12632
+ const references = input.references.map((reference) => ({
12633
+ ...reference,
12634
+ title: reference.title ? trimText(reference.title) : void 0,
12635
+ excerpt: reference.excerpt ? trimText(reference.excerpt) : void 0
12636
+ }));
12637
+ const generationPlan = buildGenerationPlan(brief, selectedFormat);
12638
+ const profile = generationPlan.visualDirection.profile;
12639
+ const canvasPlanRequest = buildCanvasPlanRequest(brief, generationPlan);
12640
+ const designContract = buildDesignContract(brief, urls, references, generationPlan, selectedFormat);
12641
+ const followthrough = buildFollowthrough(generationPlan, input.briefExpansion);
12642
+ const implementationPlan = buildImplementationPlan(profile, selectedFormat, references);
12643
+ const governanceMarkdown = renderGovernanceMarkdown(designContract, implementationPlan, selectedFormat);
12644
+ const implementationPlanMarkdown = renderImplementationMarkdown(implementationPlan);
12645
+ const prototypeGuidanceMarkdown = input.includePrototypeGuidance ? renderPrototypeGuidance(profile) : null;
12646
+ const designMarkdown = [
12647
+ "# 1. Executive Summary",
12648
+ "",
12649
+ formatBulletList2([
12650
+ `Analyzed brief plus ${references.length || 0} inspiration reference(s).`,
12651
+ `Chosen design direction: ${selectedFormat.archetype}.`,
12652
+ `Route profile: ${PROFILE_CONFIG[profile].direction}.`,
12653
+ `Prompt format: ${selectedFormat.label} (${input.briefExpansion.templateVersion}).`,
12654
+ "Final outcome: a reusable design contract, engineering plan, and optional prototype guidance.",
12655
+ `Scope mode: ${references.length > 1 ? "full-site synthesis" : "single-surface synthesis"}.`
12656
+ ]),
12657
+ "",
12658
+ "# 2. Inspiration Analysis",
12659
+ "",
12660
+ references.length > 0 ? references.map(renderReferenceMarkdown).join("\n\n") : "- No live inspiration source was provided. The system is derived entirely from the brief.",
12661
+ "",
12662
+ "# 3. Unified Design Direction",
12663
+ "",
12664
+ formatBulletList2([
12665
+ `visual personality: ${PROFILE_CONFIG[profile].visualPersonality}`,
12666
+ `tone: ${PROFILE_CONFIG[profile].brandTone}`,
12667
+ `layout archetype: ${selectedFormat.layoutArchetype}`,
12668
+ `typography system: ${selectedFormat.typographySystem}`,
12669
+ `motion grammar: ${selectedFormat.motionGrammar}`,
12670
+ `UX principles: ${PROFILE_CONFIG[profile].hierarchyPrinciples.join(" ")}`,
12671
+ `interaction philosophy: ${PROFILE_CONFIG[profile].interactionPhilosophy}`,
12672
+ "branding posture: preserve the intent of the references without cloning brand-only assets.",
12673
+ "system coherence rules: encode tokens first, keep one dominant idea per section, and keep states explicit."
12674
+ ]),
12675
+ "",
12676
+ "# 4. Design Governance (`design.md`)",
12677
+ "",
12678
+ governanceMarkdown,
12679
+ "",
12680
+ renderImplementationMarkdown(implementationPlan),
12681
+ "",
12682
+ prototypeGuidanceMarkdown ?? "# 6. Optional Prototype Plan\n\n- Prototype guidance omitted for this run.",
12683
+ "",
12684
+ "# 7. Deliverables Summary",
12685
+ "",
12686
+ renderDeliverablesSummary(Boolean(input.includePrototypeGuidance))
12687
+ ].join("\n");
12688
+ return {
12689
+ advancedBriefMarkdown,
12690
+ designContract,
12691
+ generationPlan,
12692
+ canvasPlanRequest,
12693
+ followthrough,
12694
+ designMarkdown,
12695
+ implementationPlan,
12696
+ implementationPlanMarkdown,
12697
+ prototypeGuidanceMarkdown,
12698
+ evidence: buildEvidencePayload(brief, input.briefExpansion, urls, references)
12699
+ };
12700
+ };
12701
+
12702
+ // src/providers/renderer.ts
12703
+ var toCurrency = (value) => `$${value.toFixed(2)}`;
12704
+ var primaryConstraintSummaryFromMeta = (meta) => {
12705
+ const summary = meta.primaryConstraintSummary;
12706
+ return typeof summary === "string" && summary.trim().length > 0 ? summary.trim() : null;
12707
+ };
12708
+ var isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
12709
+ var inspiredesignCaptureAttemptReportFromMeta = (meta) => {
12710
+ const report = meta.captureAttemptReport;
12711
+ if (typeof report !== "object" || report === null || Array.isArray(report)) {
12712
+ return null;
12713
+ }
12714
+ const candidate = report;
12715
+ if (!isStringArray(candidate.worked) || !isStringArray(candidate.didNotWork)) {
12716
+ return null;
12717
+ }
12718
+ return {
12719
+ worked: candidate.worked,
12720
+ didNotWork: candidate.didNotWork
12721
+ };
12722
+ };
12723
+ var inspiredesignCaptureAttemptSummaryFromMeta = (meta) => {
12724
+ const summary = meta.captureAttemptSummary;
12725
+ if (typeof summary === "string" && summary.trim().length > 0) {
12726
+ return summary.trim();
12727
+ }
12728
+ const report = inspiredesignCaptureAttemptReportFromMeta(meta);
12729
+ return report ? formatInspiredesignCaptureAttemptSummary(report) : null;
12730
+ };
12731
+ var prependPrimaryConstraint = (text, meta) => {
12732
+ const summary = primaryConstraintSummaryFromMeta(meta);
12733
+ return summary ? `Primary constraint: ${summary} ${text}` : text;
12734
+ };
12735
+ var buildInspiredesignSummary = (args) => {
12736
+ const lines = [
12737
+ `Brief: ${args.brief}`,
12738
+ `References: ${args.referenceCount}`,
12739
+ `Profile: ${args.profile}`
12740
+ ];
12741
+ const summary = primaryConstraintSummaryFromMeta(args.meta);
12742
+ if (summary) {
12743
+ lines.push(`Primary constraint: ${summary}`);
12744
+ }
12745
+ const captureSummary = inspiredesignCaptureAttemptSummaryFromMeta(args.meta);
12746
+ if (captureSummary) {
12747
+ lines.push(`Capture: ${captureSummary}`);
12748
+ }
12749
+ return lines.join("\n");
12750
+ };
12751
+ var compactResearchLines = (records, meta) => {
12752
+ if (records.length === 0) {
12753
+ const summary = primaryConstraintSummaryFromMeta(meta);
12754
+ return summary ? [
12755
+ "No records matched the requested timebox.",
12756
+ `Primary constraint: ${summary}`
12757
+ ] : ["No records matched the requested timebox."];
12758
+ }
12759
+ return records.slice(0, 10).map((record, index) => {
12760
+ const title = record.title ?? record.url ?? record.provider;
12761
+ const engagement = record.engagement.likes + record.engagement.comments + record.engagement.upvotes;
12762
+ return `${index + 1}. ${title} (${record.source}/${record.provider}) score=${record.confidence.toFixed(2)} engagement=${engagement}`;
12763
+ });
12764
+ };
12765
+ var renderResearch = (args) => {
12766
+ const lines = compactResearchLines(args.records, args.meta);
12767
+ const summary = lines.join("\n");
12768
+ const markdown = [
12769
+ `# Research: ${args.topic}`,
12770
+ "",
12771
+ ...lines,
12772
+ "",
12773
+ "## Metadata",
12774
+ "```json",
12775
+ JSON.stringify(args.meta, null, 2),
12776
+ "```"
12777
+ ].join("\n");
12778
+ const contextPayload = {
12779
+ topic: args.topic,
12780
+ highlights: lines,
12781
+ records: args.records,
12782
+ meta: args.meta
12783
+ };
12784
+ const files = [
12785
+ { path: "summary.md", content: markdown },
12786
+ { path: "records.json", content: { records: args.records } },
12787
+ { path: "context.json", content: contextPayload },
12788
+ { path: "meta.json", content: args.meta }
12789
+ ];
12790
+ if (args.mode === "compact") {
12791
+ return {
12792
+ response: {
12793
+ mode: args.mode,
12794
+ summary,
12795
+ meta: args.meta
12796
+ },
12797
+ files
12798
+ };
12799
+ }
12800
+ if (args.mode === "json") {
12801
+ return {
12802
+ response: {
12803
+ mode: args.mode,
12804
+ records: args.records,
12805
+ meta: args.meta
12806
+ },
12807
+ files
12808
+ };
12809
+ }
12810
+ if (args.mode === "md") {
12811
+ return {
12812
+ response: {
12813
+ mode: args.mode,
12814
+ markdown,
12815
+ meta: args.meta
12816
+ },
12817
+ files
12818
+ };
12819
+ }
12820
+ if (args.mode === "context") {
12821
+ return {
12822
+ response: {
12823
+ mode: args.mode,
12824
+ context: contextPayload,
12825
+ meta: args.meta
12826
+ },
12827
+ files
12828
+ };
12829
+ }
12830
+ return {
12831
+ response: {
12832
+ mode: "path",
12833
+ meta: args.meta
12834
+ },
12835
+ files
12836
+ };
12837
+ };
12838
+ var toComparisonCsv = (offers) => {
12839
+ const header = ["provider", "title", "price", "shipping", "deal_score", "availability", "url"].join(",");
12840
+ const rows = offers.map((offer) => {
12841
+ return [
12842
+ offer.provider,
12843
+ JSON.stringify(offer.title),
12844
+ offer.price.amount.toFixed(2),
12845
+ offer.shipping.amount.toFixed(2),
12846
+ offer.deal_score.toFixed(4),
12847
+ offer.availability,
12848
+ canonicalizeUrl(offer.url)
12849
+ ].join(",");
12850
+ });
12851
+ return [header, ...rows].join("\n");
11216
12852
  };
11217
- var renderPrototypeGuidance = (profile) => {
11218
- return [
11219
- "# 6. Optional Prototype Plan",
12853
+ var compactShoppingLines = (offers, meta) => {
12854
+ if (offers.length === 0) {
12855
+ const summary = primaryConstraintSummaryFromMeta(meta);
12856
+ return summary ? [
12857
+ "No offers available from the selected providers.",
12858
+ `Primary constraint: ${summary}`
12859
+ ] : ["No offers available from the selected providers."];
12860
+ }
12861
+ return offers.slice(0, 10).map((offer, index) => {
12862
+ const total = offer.price.amount + offer.shipping.amount;
12863
+ return `${index + 1}. ${offer.title} - ${toCurrency(total)} (${offer.provider}, deal=${offer.deal_score.toFixed(2)})`;
12864
+ });
12865
+ };
12866
+ var renderShopping = (args) => {
12867
+ const lines = compactShoppingLines(args.offers, args.meta);
12868
+ const markdown = [
12869
+ `# Shopping: ${args.query}`,
11220
12870
  "",
11221
- "- page structure: establish the shell, hero or primary action zone, proof sections, and footer in that order.",
11222
- `- section order: ${PROFILE_CONFIG[profile].pagePatterns.join(" -> ")}`,
11223
- "- component composition: reuse button, card, input, and navigation primitives before page-specific wrappers.",
11224
- "- interaction expectations: provide visible focus, compact hover feedback, and reduced-motion-safe entry transitions.",
11225
- "- HTML skeleton guidance: start with one main landmark, one primary CTA group, and semantic sections for proof or detail bands.",
11226
- "- styling approach: define CSS variables first, then map components to semantic tokens rather than raw values.",
11227
- "- first prototype should include vs omit: include shell, hero, CTA, one proof section, and one form or action cluster; omit analytics, heavy animation, and tertiary content until hierarchy is proven."
12871
+ ...lines,
12872
+ "",
12873
+ "## Metadata",
12874
+ "```json",
12875
+ JSON.stringify(args.meta, null, 2),
12876
+ "```"
11228
12877
  ].join("\n");
12878
+ const comparisonCsv = toComparisonCsv(args.offers);
12879
+ const contextPayload = {
12880
+ query: args.query,
12881
+ highlights: lines,
12882
+ offers: args.offers,
12883
+ meta: args.meta
12884
+ };
12885
+ const files = [
12886
+ { path: "deals.md", content: markdown },
12887
+ { path: "offers.json", content: { offers: args.offers } },
12888
+ { path: "comparison.csv", content: comparisonCsv },
12889
+ { path: "meta.json", content: args.meta },
12890
+ { path: "deals-context.json", content: contextPayload }
12891
+ ];
12892
+ if (args.mode === "compact") {
12893
+ return {
12894
+ response: {
12895
+ mode: args.mode,
12896
+ summary: lines.join("\n"),
12897
+ meta: args.meta
12898
+ },
12899
+ files
12900
+ };
12901
+ }
12902
+ if (args.mode === "json") {
12903
+ return {
12904
+ response: {
12905
+ mode: args.mode,
12906
+ offers: args.offers,
12907
+ meta: args.meta
12908
+ },
12909
+ files
12910
+ };
12911
+ }
12912
+ if (args.mode === "md") {
12913
+ return {
12914
+ response: {
12915
+ mode: args.mode,
12916
+ markdown,
12917
+ meta: args.meta
12918
+ },
12919
+ files
12920
+ };
12921
+ }
12922
+ if (args.mode === "context") {
12923
+ return {
12924
+ response: {
12925
+ mode: args.mode,
12926
+ context: contextPayload,
12927
+ meta: args.meta
12928
+ },
12929
+ files
12930
+ };
12931
+ }
12932
+ return {
12933
+ response: {
12934
+ mode: "path",
12935
+ meta: args.meta
12936
+ },
12937
+ files
12938
+ };
11229
12939
  };
11230
- var renderDeliverablesSummary = (includePrototypeGuidance) => {
11231
- const deliverables = [
11232
- "Structured `designContract` JSON aligned to canvas governance",
11233
- "Valid `generationPlan` JSON aligned to the canvas generation plan contract",
11234
- "Ready-to-fill `canvasPlanRequest` JSON for `canvas.plan.set`",
11235
- "Design-agent handoff JSON with contract scope, skill nudges, and richer implementation context",
11236
- "Human-readable `design.md` design specification",
11237
- "Engineering implementation plan in JSON and Markdown"
12940
+ var renderInspiredesign = (args) => {
12941
+ const captureAttemptReport = inspiredesignCaptureAttemptReportFromMeta(args.meta);
12942
+ const captureAttemptSummary = inspiredesignCaptureAttemptSummaryFromMeta(args.meta);
12943
+ const summary = buildInspiredesignSummary({
12944
+ brief: args.brief,
12945
+ referenceCount: args.urls.length,
12946
+ profile: args.generationPlan.visualDirection.profile,
12947
+ meta: args.meta
12948
+ });
12949
+ const followthroughSummary = prependPrimaryConstraint(args.designAgentHandoff.summary, args.meta);
12950
+ const contextPayload = {
12951
+ brief: args.brief,
12952
+ advancedBriefMarkdown: args.advancedBriefMarkdown,
12953
+ urls: args.urls,
12954
+ designContract: args.designContract,
12955
+ canvasPlanRequest: args.canvasPlanRequest,
12956
+ designAgentHandoff: args.designAgentHandoff,
12957
+ generationPlan: args.generationPlan,
12958
+ implementationPlan: args.implementationPlan,
12959
+ designMarkdown: args.designMarkdown,
12960
+ implementationPlanMarkdown: args.implementationPlanMarkdown,
12961
+ prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
12962
+ evidence: args.evidence,
12963
+ meta: args.meta
12964
+ };
12965
+ const suggestedSteps = [
12966
+ {
12967
+ reason: INSPIREDESIGN_HANDOFF_GUIDANCE.reviewAdvancedBrief
12968
+ },
12969
+ {
12970
+ reason: "Load the baseline workflow runbook before implementation.",
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
+ }
11238
12984
  ];
11239
- if (includePrototypeGuidance) {
11240
- deliverables.push("Prototype guidance Markdown for the first HTML pass");
12985
+ const files = [
12986
+ { path: INSPIREDESIGN_HANDOFF_FILES.designMarkdown, content: args.designMarkdown },
12987
+ { path: INSPIREDESIGN_HANDOFF_FILES.advancedBrief, content: args.advancedBriefMarkdown },
12988
+ { path: INSPIREDESIGN_HANDOFF_FILES.designContract, content: args.designContract },
12989
+ { path: INSPIREDESIGN_HANDOFF_FILES.canvasPlanRequest, content: args.canvasPlanRequest },
12990
+ { path: INSPIREDESIGN_HANDOFF_FILES.designAgentHandoff, content: args.designAgentHandoff },
12991
+ { path: INSPIREDESIGN_HANDOFF_FILES.generationPlan, content: args.generationPlan },
12992
+ { path: INSPIREDESIGN_HANDOFF_FILES.implementationPlanMarkdown, content: args.implementationPlanMarkdown },
12993
+ { path: INSPIREDESIGN_HANDOFF_FILES.implementationPlan, content: args.implementationPlan },
12994
+ { path: INSPIREDESIGN_HANDOFF_FILES.evidence, content: args.evidence }
12995
+ ];
12996
+ if (args.prototypeGuidanceMarkdown) {
12997
+ files.push({ path: INSPIREDESIGN_HANDOFF_FILES.prototypeGuidance, content: args.prototypeGuidanceMarkdown });
12998
+ }
12999
+ const captureAttemptFields = {
13000
+ ...captureAttemptSummary ? { captureAttemptSummary } : {},
13001
+ ...captureAttemptReport ? { captureAttemptReport } : {}
13002
+ };
13003
+ if (args.mode === "compact") {
13004
+ return {
13005
+ response: {
13006
+ mode: args.mode,
13007
+ summary,
13008
+ followthroughSummary,
13009
+ suggestedNextAction: args.designAgentHandoff.nextStep,
13010
+ suggestedSteps,
13011
+ ...captureAttemptFields,
13012
+ meta: args.meta
13013
+ },
13014
+ files
13015
+ };
13016
+ }
13017
+ if (args.mode === "json") {
13018
+ return {
13019
+ response: {
13020
+ mode: args.mode,
13021
+ brief: args.brief,
13022
+ advancedBriefMarkdown: args.advancedBriefMarkdown,
13023
+ urls: args.urls,
13024
+ canvasPlanRequest: args.canvasPlanRequest,
13025
+ designAgentHandoff: args.designAgentHandoff,
13026
+ designContract: args.designContract,
13027
+ generationPlan: args.generationPlan,
13028
+ implementationPlan: args.implementationPlan,
13029
+ prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
13030
+ evidence: args.evidence,
13031
+ followthroughSummary,
13032
+ suggestedNextAction: args.designAgentHandoff.nextStep,
13033
+ suggestedSteps,
13034
+ ...captureAttemptFields,
13035
+ meta: args.meta
13036
+ },
13037
+ files
13038
+ };
13039
+ }
13040
+ if (args.mode === "md") {
13041
+ return {
13042
+ response: {
13043
+ mode: args.mode,
13044
+ markdown: args.designMarkdown,
13045
+ implementationPlanMarkdown: args.implementationPlanMarkdown,
13046
+ prototypeGuidanceMarkdown: args.prototypeGuidanceMarkdown,
13047
+ followthroughSummary,
13048
+ suggestedNextAction: args.designAgentHandoff.nextStep,
13049
+ suggestedSteps,
13050
+ ...captureAttemptFields,
13051
+ meta: args.meta
13052
+ },
13053
+ files
13054
+ };
13055
+ }
13056
+ if (args.mode === "context") {
13057
+ return {
13058
+ response: {
13059
+ mode: args.mode,
13060
+ context: contextPayload,
13061
+ followthroughSummary,
13062
+ suggestedNextAction: args.designAgentHandoff.nextStep,
13063
+ suggestedSteps,
13064
+ ...captureAttemptFields,
13065
+ meta: args.meta
13066
+ },
13067
+ files
13068
+ };
11241
13069
  }
11242
- deliverables.push("Evidence digest describing brief, references, fetch outcomes, and capture outcomes");
11243
- return formatBulletList(deliverables);
11244
- };
11245
- var buildEvidencePayload = (brief, urls, references) => ({
11246
- brief,
11247
- briefHash: referenceFingerprint(brief),
11248
- urls,
11249
- referenceCount: references.length,
11250
- references: references.map((reference) => toReferenceEvidenceJson(reference))
11251
- });
11252
- var toCaptureEvidenceJson = (capture) => {
11253
- if (!capture) return null;
11254
- return {
11255
- ...capture.title ? { title: capture.title } : {},
11256
- ...capture.snapshot ? { snapshot: capture.snapshot } : {},
11257
- ...capture.dom ? { dom: capture.dom } : {},
11258
- ...capture.clone ? { clone: capture.clone } : {}
11259
- };
11260
- };
11261
- var toReferenceEvidenceJson = (reference) => ({
11262
- id: reference.id,
11263
- url: reference.url,
11264
- ...reference.title ? { title: reference.title } : {},
11265
- ...reference.excerpt ? { excerpt: reference.excerpt } : {},
11266
- fetchStatus: reference.fetchStatus,
11267
- captureStatus: reference.captureStatus,
11268
- ...reference.fetchFailure ? { fetchFailure: reference.fetchFailure } : {},
11269
- ...reference.captureFailure ? { captureFailure: reference.captureFailure } : {},
11270
- capture: toCaptureEvidenceJson(reference.capture)
11271
- });
11272
- var buildInspiredesignPacket = (input) => {
11273
- const brief = trimText(input.brief);
11274
- const urls = [...new Set(input.urls.map((url) => trimText(url)).filter(Boolean))];
11275
- const references = input.references.map((reference) => ({
11276
- ...reference,
11277
- title: reference.title ? trimText(reference.title) : void 0,
11278
- excerpt: reference.excerpt ? trimText(reference.excerpt) : void 0
11279
- }));
11280
- const profile = classifyProfile(brief, references);
11281
- const generationPlan = buildGenerationPlan(brief, profile, references);
11282
- const canvasPlanRequest = buildCanvasPlanRequest(brief, generationPlan);
11283
- const designContract = buildDesignContract(brief, urls, references, generationPlan);
11284
- const followthrough = buildFollowthrough(generationPlan);
11285
- const implementationPlan = buildImplementationPlan(brief, profile, references);
11286
- const governanceMarkdown = renderGovernanceMarkdown(designContract, implementationPlan);
11287
- const implementationPlanMarkdown = renderImplementationMarkdown(implementationPlan);
11288
- const prototypeGuidanceMarkdown = input.includePrototypeGuidance ? renderPrototypeGuidance(profile) : null;
11289
- const designMarkdown = [
11290
- "# 1. Executive Summary",
11291
- "",
11292
- formatBulletList([
11293
- `Analyzed brief plus ${references.length || 0} inspiration reference(s).`,
11294
- `Chosen design direction: ${PROFILE_CONFIG[profile].direction}.`,
11295
- "Final outcome: a reusable design contract, engineering plan, and optional prototype guidance.",
11296
- `Scope mode: ${references.length > 1 ? "full-site synthesis" : "single-surface synthesis"}.`
11297
- ]),
11298
- "",
11299
- "# 2. Inspiration Analysis",
11300
- "",
11301
- references.length > 0 ? references.map(renderReferenceMarkdown).join("\n\n") : "- No live inspiration source was provided. The system is derived entirely from the brief.",
11302
- "",
11303
- "# 3. Unified Design Direction",
11304
- "",
11305
- formatBulletList([
11306
- `visual personality: ${PROFILE_CONFIG[profile].visualPersonality}`,
11307
- `tone: ${PROFILE_CONFIG[profile].brandTone}`,
11308
- `UX principles: ${PROFILE_CONFIG[profile].hierarchyPrinciples.join(" ")}`,
11309
- `interaction philosophy: ${PROFILE_CONFIG[profile].interactionPhilosophy}`,
11310
- "branding posture: preserve the intent of the references without cloning brand-only assets.",
11311
- "system coherence rules: encode tokens first, keep one dominant idea per section, and keep states explicit."
11312
- ]),
11313
- "",
11314
- "# 4. Design Governance (`design.md`)",
11315
- "",
11316
- renderGovernanceMarkdown(designContract, implementationPlan),
11317
- "",
11318
- renderImplementationMarkdown(implementationPlan),
11319
- "",
11320
- prototypeGuidanceMarkdown ?? "# 6. Optional Prototype Plan\n\n- Prototype guidance omitted for this run.",
11321
- "",
11322
- "# 7. Deliverables Summary",
11323
- "",
11324
- renderDeliverablesSummary(Boolean(input.includePrototypeGuidance))
11325
- ].join("\n");
11326
13070
  return {
11327
- designContract,
11328
- generationPlan,
11329
- canvasPlanRequest,
11330
- followthrough,
11331
- designMarkdown,
11332
- implementationPlan,
11333
- implementationPlanMarkdown,
11334
- prototypeGuidanceMarkdown,
11335
- evidence: buildEvidencePayload(brief, urls, references)
13071
+ response: {
13072
+ mode: "path",
13073
+ followthroughSummary,
13074
+ suggestedNextAction: args.designAgentHandoff.nextStep,
13075
+ suggestedSteps,
13076
+ ...captureAttemptFields,
13077
+ meta: args.meta
13078
+ },
13079
+ files
11336
13080
  };
11337
13081
  };
11338
13082
 
13083
+ // src/canvas/types.ts
13084
+ var CANVAS_SCHEMA_VERSION = "1.0.0";
13085
+ var CANVAS_SESSION_MODES = ["low-fi-wireframe", "high-fi-live-edit", "dual-track", "document-only"];
13086
+ var CANVAS_GOVERNANCE_BLOCK_KEYS = [
13087
+ "intent",
13088
+ "generationPlan",
13089
+ "designLanguage",
13090
+ "contentModel",
13091
+ "layoutSystem",
13092
+ "typographySystem",
13093
+ "colorSystem",
13094
+ "surfaceSystem",
13095
+ "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
+
11339
13210
  // src/providers/workflow-handoff.ts
11340
13211
  var PRODUCT_VIDEO_BRIEF_HELPER_PATH = "./skills/opendevbrowser-product-presentation-asset/scripts/render-video-brief.sh";
11341
13212
  var PRODUCT_VIDEO_BRIEF_HELPER_COMMAND = `${PRODUCT_VIDEO_BRIEF_HELPER_PATH} <pack>/manifest.json`;
@@ -12188,14 +14059,14 @@ import { createHash as createHash5 } from "crypto";
12188
14059
  var DEFAULT_SHOPPING_SEARCH_LIMIT = 8;
12189
14060
  var SHOPPING_FETCH_RECOVERY_LIMIT = 2;
12190
14061
  var SEARCH_INDEX_RETRIEVAL_PATHS = /* @__PURE__ */ new Set(["shopping:search:index", "shopping:search:link"]);
12191
- var isJsonRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
14062
+ var isJsonRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12192
14063
  var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
12193
14064
  var isProviderSource = (value) => value === "web" || value === "community" || value === "social" || value === "shopping";
12194
- var isTraceContext = (value) => isJsonRecord2(value) && typeof value.requestId === "string" && typeof value.ts === "string" && (value.sessionId === void 0 || typeof value.sessionId === "string") && (value.targetId === void 0 || typeof value.targetId === "string") && (value.provider === void 0 || typeof value.provider === "string");
12195
- var isProviderError2 = (value) => isJsonRecord2(value) && typeof value.code === "string" && typeof value.message === "string" && typeof value.retryable === "boolean" && (value.reasonCode === void 0 || typeof value.reasonCode === "string") && (value.provider === void 0 || typeof value.provider === "string") && (value.source === void 0 || isProviderSource(value.source)) && (value.details === void 0 || isJsonRecord2(value.details));
12196
- var isNormalizedRecord = (value) => isJsonRecord2(value) && typeof value.id === "string" && isProviderSource(value.source) && typeof value.provider === "string" && (value.url === void 0 || typeof value.url === "string") && (value.title === void 0 || typeof value.title === "string") && (value.content === void 0 || typeof value.content === "string") && typeof value.timestamp === "string" && isFiniteNumber(value.confidence) && isJsonRecord2(value.attributes);
12197
- var isProviderFailureEntry = (value) => isJsonRecord2(value) && typeof value.provider === "string" && isProviderSource(value.source) && isProviderError2(value.error);
12198
- var isProviderAggregateResult = (value) => isJsonRecord2(value) && typeof value.ok === "boolean" && Array.isArray(value.records) && value.records.every((entry) => isNormalizedRecord(entry)) && isTraceContext(value.trace) && typeof value.partial === "boolean" && Array.isArray(value.failures) && value.failures.every((entry) => isProviderFailureEntry(entry)) && isJsonRecord2(value.metrics) && isFiniteNumber(value.metrics.attempted) && isFiniteNumber(value.metrics.succeeded) && isFiniteNumber(value.metrics.failed) && isFiniteNumber(value.metrics.retries) && isFiniteNumber(value.metrics.latencyMs) && typeof value.sourceSelection === "string" && Array.isArray(value.providerOrder) && value.providerOrder.every((entry) => typeof entry === "string") && (value.meta === void 0 || isJsonRecord2(value.meta)) && (value.diagnostics === void 0 || isJsonRecord2(value.diagnostics)) && (value.error === void 0 || isProviderError2(value.error));
14065
+ var isTraceContext = (value) => isJsonRecord3(value) && typeof value.requestId === "string" && typeof value.ts === "string" && (value.sessionId === void 0 || typeof value.sessionId === "string") && (value.targetId === void 0 || typeof value.targetId === "string") && (value.provider === void 0 || typeof value.provider === "string");
14066
+ var isProviderError2 = (value) => isJsonRecord3(value) && typeof value.code === "string" && typeof value.message === "string" && typeof value.retryable === "boolean" && (value.reasonCode === void 0 || typeof value.reasonCode === "string") && (value.provider === void 0 || typeof value.provider === "string") && (value.source === void 0 || isProviderSource(value.source)) && (value.details === void 0 || isJsonRecord3(value.details));
14067
+ var isNormalizedRecord = (value) => isJsonRecord3(value) && typeof value.id === "string" && isProviderSource(value.source) && typeof value.provider === "string" && (value.url === void 0 || typeof value.url === "string") && (value.title === void 0 || typeof value.title === "string") && (value.content === void 0 || typeof value.content === "string") && typeof value.timestamp === "string" && isFiniteNumber(value.confidence) && isJsonRecord3(value.attributes);
14068
+ var isProviderFailureEntry = (value) => isJsonRecord3(value) && typeof value.provider === "string" && isProviderSource(value.source) && isProviderError2(value.error);
14069
+ var isProviderAggregateResult = (value) => isJsonRecord3(value) && typeof value.ok === "boolean" && Array.isArray(value.records) && value.records.every((entry) => isNormalizedRecord(entry)) && isTraceContext(value.trace) && typeof value.partial === "boolean" && Array.isArray(value.failures) && value.failures.every((entry) => isProviderFailureEntry(entry)) && isJsonRecord3(value.metrics) && isFiniteNumber(value.metrics.attempted) && isFiniteNumber(value.metrics.succeeded) && isFiniteNumber(value.metrics.failed) && isFiniteNumber(value.metrics.retries) && isFiniteNumber(value.metrics.latencyMs) && typeof value.sourceSelection === "string" && Array.isArray(value.providerOrder) && value.providerOrder.every((entry) => typeof entry === "string") && (value.meta === void 0 || isJsonRecord3(value.meta)) && (value.diagnostics === void 0 || isJsonRecord3(value.diagnostics)) && (value.error === void 0 || isProviderError2(value.error));
12199
14070
  var emptyCheckpointState = () => ({
12200
14071
  completed_step_ids: [],
12201
14072
  step_results_by_id: {}
@@ -12211,7 +14082,7 @@ var readShoppingCheckpointState = (checkpoint) => {
12211
14082
  if (state === void 0 || state === null) {
12212
14083
  return emptyCheckpointState();
12213
14084
  }
12214
- if (!isJsonRecord2(state)) {
14085
+ if (!isJsonRecord3(state)) {
12215
14086
  throw new Error("Shopping workflow checkpoint state must be a record.");
12216
14087
  }
12217
14088
  const completedStepIds = state.completed_step_ids;
@@ -12219,7 +14090,7 @@ var readShoppingCheckpointState = (checkpoint) => {
12219
14090
  throw new Error("Shopping workflow checkpoint state is missing valid completed_step_ids.");
12220
14091
  }
12221
14092
  const rawResults = state.step_results_by_id;
12222
- if (!isJsonRecord2(rawResults)) {
14093
+ if (!isJsonRecord3(rawResults)) {
12223
14094
  throw new Error("Shopping workflow checkpoint state is missing valid step_results_by_id.");
12224
14095
  }
12225
14096
  const stepResultsById = {};
@@ -12530,14 +14401,14 @@ var PRODUCT_VIDEO_STEP_IDS = {
12530
14401
  extractProductData: "product_video:extract_product_data",
12531
14402
  assembleArtifacts: "product_video:assemble_artifacts"
12532
14403
  };
12533
- var isJsonRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
14404
+ var isJsonRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12534
14405
  var isFiniteNumber2 = (value) => typeof value === "number" && Number.isFinite(value);
12535
14406
  var isProviderSource2 = (value) => value === "web" || value === "community" || value === "social" || value === "shopping";
12536
- var isTraceContext2 = (value) => isJsonRecord3(value) && typeof value.requestId === "string" && typeof value.ts === "string" && (value.sessionId === void 0 || typeof value.sessionId === "string") && (value.targetId === void 0 || typeof value.targetId === "string") && (value.provider === void 0 || typeof value.provider === "string");
12537
- var isProviderError3 = (value) => isJsonRecord3(value) && typeof value.code === "string" && typeof value.message === "string" && typeof value.retryable === "boolean" && (value.reasonCode === void 0 || typeof value.reasonCode === "string") && (value.provider === void 0 || typeof value.provider === "string") && (value.source === void 0 || isProviderSource2(value.source)) && (value.details === void 0 || isJsonRecord3(value.details));
12538
- var isNormalizedRecord2 = (value) => isJsonRecord3(value) && typeof value.id === "string" && isProviderSource2(value.source) && typeof value.provider === "string" && (value.url === void 0 || typeof value.url === "string") && (value.title === void 0 || typeof value.title === "string") && (value.content === void 0 || typeof value.content === "string") && typeof value.timestamp === "string" && isFiniteNumber2(value.confidence) && isJsonRecord3(value.attributes);
12539
- var isProviderFailureEntry2 = (value) => isJsonRecord3(value) && typeof value.provider === "string" && isProviderSource2(value.source) && isProviderError3(value.error);
12540
- var isProviderAggregateResult2 = (value) => isJsonRecord3(value) && typeof value.ok === "boolean" && Array.isArray(value.records) && value.records.every((entry) => isNormalizedRecord2(entry)) && isTraceContext2(value.trace) && typeof value.partial === "boolean" && Array.isArray(value.failures) && value.failures.every((entry) => isProviderFailureEntry2(entry)) && isJsonRecord3(value.metrics) && isFiniteNumber2(value.metrics.attempted) && isFiniteNumber2(value.metrics.succeeded) && isFiniteNumber2(value.metrics.failed) && isFiniteNumber2(value.metrics.retries) && isFiniteNumber2(value.metrics.latencyMs) && typeof value.sourceSelection === "string" && Array.isArray(value.providerOrder) && value.providerOrder.every((entry) => typeof entry === "string") && (value.meta === void 0 || isJsonRecord3(value.meta)) && (value.diagnostics === void 0 || isJsonRecord3(value.diagnostics)) && (value.error === void 0 || isProviderError3(value.error));
14407
+ var isTraceContext2 = (value) => isJsonRecord4(value) && typeof value.requestId === "string" && typeof value.ts === "string" && (value.sessionId === void 0 || typeof value.sessionId === "string") && (value.targetId === void 0 || typeof value.targetId === "string") && (value.provider === void 0 || typeof value.provider === "string");
14408
+ var isProviderError3 = (value) => isJsonRecord4(value) && typeof value.code === "string" && typeof value.message === "string" && typeof value.retryable === "boolean" && (value.reasonCode === void 0 || typeof value.reasonCode === "string") && (value.provider === void 0 || typeof value.provider === "string") && (value.source === void 0 || isProviderSource2(value.source)) && (value.details === void 0 || isJsonRecord4(value.details));
14409
+ var isNormalizedRecord2 = (value) => isJsonRecord4(value) && typeof value.id === "string" && isProviderSource2(value.source) && typeof value.provider === "string" && (value.url === void 0 || typeof value.url === "string") && (value.title === void 0 || typeof value.title === "string") && (value.content === void 0 || typeof value.content === "string") && typeof value.timestamp === "string" && isFiniteNumber2(value.confidence) && isJsonRecord4(value.attributes);
14410
+ var isProviderFailureEntry2 = (value) => isJsonRecord4(value) && typeof value.provider === "string" && isProviderSource2(value.source) && isProviderError3(value.error);
14411
+ var isProviderAggregateResult2 = (value) => isJsonRecord4(value) && typeof value.ok === "boolean" && Array.isArray(value.records) && value.records.every((entry) => isNormalizedRecord2(entry)) && isTraceContext2(value.trace) && typeof value.partial === "boolean" && Array.isArray(value.failures) && value.failures.every((entry) => isProviderFailureEntry2(entry)) && isJsonRecord4(value.metrics) && isFiniteNumber2(value.metrics.attempted) && isFiniteNumber2(value.metrics.succeeded) && isFiniteNumber2(value.metrics.failed) && isFiniteNumber2(value.metrics.retries) && isFiniteNumber2(value.metrics.latencyMs) && typeof value.sourceSelection === "string" && Array.isArray(value.providerOrder) && value.providerOrder.every((entry) => typeof entry === "string") && (value.meta === void 0 || isJsonRecord4(value.meta)) && (value.diagnostics === void 0 || isJsonRecord4(value.diagnostics)) && (value.error === void 0 || isProviderError3(value.error));
12541
14412
  var emptyCheckpointState2 = () => ({
12542
14413
  completed_step_ids: []
12543
14414
  });
@@ -12580,7 +14451,7 @@ var readProductVideoCheckpointState = (checkpoint) => {
12580
14451
  if (state === void 0 || state === null) {
12581
14452
  return emptyCheckpointState2();
12582
14453
  }
12583
- if (!isJsonRecord3(state)) {
14454
+ if (!isJsonRecord4(state)) {
12584
14455
  throw new Error("Product-video workflow checkpoint state must be a record.");
12585
14456
  }
12586
14457
  const completedStepIds = state.completed_step_ids;
@@ -12692,14 +14563,14 @@ var RESEARCH_AUTO_SOURCES = ["web", "community", "social"];
12692
14563
  var RESEARCH_ALL_SOURCES = [...RESEARCH_AUTO_SOURCES];
12693
14564
  var DEFAULT_RESEARCH_SEARCH_LIMIT = 10;
12694
14565
  var RESEARCH_WEB_SEARCH_FETCH_LIMIT = 3;
12695
- var isJsonRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
14566
+ var isJsonRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12696
14567
  var isFiniteNumber3 = (value) => typeof value === "number" && Number.isFinite(value);
12697
14568
  var isProviderSource3 = (value) => value === "web" || value === "community" || value === "social" || value === "shopping";
12698
- var isTraceContext3 = (value) => isJsonRecord4(value) && typeof value.requestId === "string" && typeof value.ts === "string" && (value.sessionId === void 0 || typeof value.sessionId === "string") && (value.targetId === void 0 || typeof value.targetId === "string") && (value.provider === void 0 || typeof value.provider === "string");
12699
- var isProviderError4 = (value) => isJsonRecord4(value) && typeof value.code === "string" && typeof value.message === "string" && typeof value.retryable === "boolean" && (value.reasonCode === void 0 || typeof value.reasonCode === "string") && (value.provider === void 0 || typeof value.provider === "string") && (value.source === void 0 || isProviderSource3(value.source)) && (value.details === void 0 || isJsonRecord4(value.details));
12700
- var isNormalizedRecord3 = (value) => isJsonRecord4(value) && typeof value.id === "string" && isProviderSource3(value.source) && typeof value.provider === "string" && (value.url === void 0 || typeof value.url === "string") && (value.title === void 0 || typeof value.title === "string") && (value.content === void 0 || typeof value.content === "string") && typeof value.timestamp === "string" && isFiniteNumber3(value.confidence) && isJsonRecord4(value.attributes);
12701
- var isProviderFailureEntry3 = (value) => isJsonRecord4(value) && typeof value.provider === "string" && isProviderSource3(value.source) && isProviderError4(value.error);
12702
- var isProviderAggregateResult3 = (value) => isJsonRecord4(value) && typeof value.ok === "boolean" && Array.isArray(value.records) && value.records.every((entry) => isNormalizedRecord3(entry)) && isTraceContext3(value.trace) && typeof value.partial === "boolean" && Array.isArray(value.failures) && value.failures.every((entry) => isProviderFailureEntry3(entry)) && isJsonRecord4(value.metrics) && isFiniteNumber3(value.metrics.attempted) && isFiniteNumber3(value.metrics.succeeded) && isFiniteNumber3(value.metrics.failed) && isFiniteNumber3(value.metrics.retries) && isFiniteNumber3(value.metrics.latencyMs) && typeof value.sourceSelection === "string" && Array.isArray(value.providerOrder) && value.providerOrder.every((entry) => typeof entry === "string") && (value.meta === void 0 || isJsonRecord4(value.meta)) && (value.diagnostics === void 0 || isJsonRecord4(value.diagnostics)) && (value.error === void 0 || isProviderError4(value.error));
14569
+ var isTraceContext3 = (value) => isJsonRecord5(value) && typeof value.requestId === "string" && typeof value.ts === "string" && (value.sessionId === void 0 || typeof value.sessionId === "string") && (value.targetId === void 0 || typeof value.targetId === "string") && (value.provider === void 0 || typeof value.provider === "string");
14570
+ var isProviderError4 = (value) => isJsonRecord5(value) && typeof value.code === "string" && typeof value.message === "string" && typeof value.retryable === "boolean" && (value.reasonCode === void 0 || typeof value.reasonCode === "string") && (value.provider === void 0 || typeof value.provider === "string") && (value.source === void 0 || isProviderSource3(value.source)) && (value.details === void 0 || isJsonRecord5(value.details));
14571
+ var isNormalizedRecord3 = (value) => isJsonRecord5(value) && typeof value.id === "string" && isProviderSource3(value.source) && typeof value.provider === "string" && (value.url === void 0 || typeof value.url === "string") && (value.title === void 0 || typeof value.title === "string") && (value.content === void 0 || typeof value.content === "string") && typeof value.timestamp === "string" && isFiniteNumber3(value.confidence) && isJsonRecord5(value.attributes);
14572
+ var isProviderFailureEntry3 = (value) => isJsonRecord5(value) && typeof value.provider === "string" && isProviderSource3(value.source) && isProviderError4(value.error);
14573
+ var isProviderAggregateResult3 = (value) => isJsonRecord5(value) && typeof value.ok === "boolean" && Array.isArray(value.records) && value.records.every((entry) => isNormalizedRecord3(entry)) && isTraceContext3(value.trace) && typeof value.partial === "boolean" && Array.isArray(value.failures) && value.failures.every((entry) => isProviderFailureEntry3(entry)) && isJsonRecord5(value.metrics) && isFiniteNumber3(value.metrics.attempted) && isFiniteNumber3(value.metrics.succeeded) && isFiniteNumber3(value.metrics.failed) && isFiniteNumber3(value.metrics.retries) && isFiniteNumber3(value.metrics.latencyMs) && typeof value.sourceSelection === "string" && Array.isArray(value.providerOrder) && value.providerOrder.every((entry) => typeof entry === "string") && (value.meta === void 0 || isJsonRecord5(value.meta)) && (value.diagnostics === void 0 || isJsonRecord5(value.diagnostics)) && (value.error === void 0 || isProviderError4(value.error));
12703
14574
  var emptyCheckpointState3 = () => ({
12704
14575
  completed_step_ids: [],
12705
14576
  step_results_by_id: {}
@@ -12722,7 +14593,7 @@ var readResearchCheckpointState = (checkpoint) => {
12722
14593
  if (state === void 0 || state === null) {
12723
14594
  return emptyCheckpointState3();
12724
14595
  }
12725
- if (!isJsonRecord4(state)) {
14596
+ if (!isJsonRecord5(state)) {
12726
14597
  throw new Error("Research workflow checkpoint state must be a record.");
12727
14598
  }
12728
14599
  const completedStepIds = state.completed_step_ids;
@@ -12730,7 +14601,7 @@ var readResearchCheckpointState = (checkpoint) => {
12730
14601
  throw new Error("Research workflow checkpoint state is missing valid completed_step_ids.");
12731
14602
  }
12732
14603
  const rawResults = state.step_results_by_id;
12733
- if (!isJsonRecord4(rawResults)) {
14604
+ if (!isJsonRecord5(rawResults)) {
12734
14605
  throw new Error("Research workflow checkpoint state is missing valid step_results_by_id.");
12735
14606
  }
12736
14607
  const stepResultsById = {};
@@ -13050,6 +14921,14 @@ var executeResearchWorkflowPlan = async (runtime, plan, options) => {
13050
14921
  };
13051
14922
  };
13052
14923
 
14924
+ // src/providers/inspiredesign-capture-mode.ts
14925
+ var hasInspiredesignUrls = (urls) => {
14926
+ return Array.isArray(urls) && urls.some((url) => url.trim().length > 0);
14927
+ };
14928
+ function resolveInspiredesignCaptureMode(requested, urls) {
14929
+ return hasInspiredesignUrls(urls) ? "deep" : requested ?? "off";
14930
+ }
14931
+
13053
14932
  // src/providers/workflows.ts
13054
14933
  var SIGNAL_WINDOW = 50;
13055
14934
  var RECOVERY_WINDOWS_REQUIRED = 2;
@@ -13788,13 +15667,33 @@ var createRemainingTimeoutResolver = (timeoutMs) => {
13788
15667
  return () => void 0;
13789
15668
  }
13790
15669
  const startedAtMs = Date.now();
13791
- return () => Math.max(1, timeoutMs - Math.max(0, Date.now() - startedAtMs));
15670
+ let firstRead = true;
15671
+ return () => {
15672
+ if (firstRead) {
15673
+ firstRead = false;
15674
+ return timeoutMs;
15675
+ }
15676
+ return Math.max(1, timeoutMs - Math.max(0, Date.now() - startedAtMs));
15677
+ };
13792
15678
  };
13793
15679
  var INSPIREDESIGN_RENDER_MODES = /* @__PURE__ */ new Set(["compact", "json", "md", "context", "path"]);
13794
15680
  var INSPIREDESIGN_CAPTURE_MODES = /* @__PURE__ */ new Set(["off", "deep"]);
13795
15681
  var INSPIREDESIGN_COOKIE_POLICIES = /* @__PURE__ */ new Set(["off", "auto", "required"]);
15682
+ var isJsonRecord6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
15683
+ var INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE = "Deep capture requested, but browser capture is unavailable in this execution lane.";
15684
+ var isCanvasVisualDirectionProfile = (value) => {
15685
+ return CANVAS_VISUAL_DIRECTION_PROFILES.includes(value);
15686
+ };
15687
+ var isCanvasThemeStrategy = (value) => {
15688
+ return CANVAS_THEME_STRATEGIES.includes(value);
15689
+ };
15690
+ var isCanvasNavigationModel = (value) => {
15691
+ return CANVAS_NAVIGATION_MODELS.includes(value);
15692
+ };
15693
+ var serializeInspiredesignBriefExpansion = (expansion) => structuredClone(expansion);
13796
15694
  var serializeInspiredesignRunInput = (input) => ({
13797
15695
  brief: input.brief,
15696
+ briefExpansion: serializeInspiredesignBriefExpansion(input.briefExpansion),
13798
15697
  urls: input.urls,
13799
15698
  captureMode: input.captureMode,
13800
15699
  mode: input.mode,
@@ -13806,19 +15705,81 @@ var serializeInspiredesignRunInput = (input) => ({
13806
15705
  ...input.challengeAutomationMode ? { challengeAutomationMode: input.challengeAutomationMode } : {},
13807
15706
  ...input.cookiePolicyOverride ? { cookiePolicyOverride: input.cookiePolicyOverride } : {}
13808
15707
  });
13809
- var parseInspiredesignEnvelopeInput = (input) => ({
13810
- brief: typeof input.brief === "string" ? input.brief : "",
13811
- mode: typeof input.mode === "string" && INSPIREDESIGN_RENDER_MODES.has(input.mode) ? input.mode : "compact",
13812
- ...Array.isArray(input.urls) ? { urls: input.urls.filter((url) => typeof url === "string") } : {},
13813
- ...typeof input.captureMode === "string" && INSPIREDESIGN_CAPTURE_MODES.has(input.captureMode) ? { captureMode: input.captureMode } : {},
13814
- ...typeof input.includePrototypeGuidance === "boolean" ? { includePrototypeGuidance: input.includePrototypeGuidance } : {},
13815
- ...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
13816
- ...typeof input.outputDir === "string" && input.outputDir.length > 0 ? { outputDir: input.outputDir } : {},
13817
- ...typeof input.ttlHours === "number" ? { ttlHours: input.ttlHours } : {},
13818
- ...typeof input.useCookies === "boolean" ? { useCookies: input.useCookies } : {},
13819
- ...isChallengeAutomationMode(input.challengeAutomationMode) ? { challengeAutomationMode: input.challengeAutomationMode } : {},
13820
- ...typeof input.cookiePolicyOverride === "string" && INSPIREDESIGN_COOKIE_POLICIES.has(input.cookiePolicyOverride) ? { cookiePolicyOverride: input.cookiePolicyOverride } : {}
13821
- });
15708
+ var isStringArray2 = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
15709
+ var parseInspiredesignBriefFormatRoute = (value) => {
15710
+ if (!isJsonRecord6(value)) return void 0;
15711
+ const profile = typeof value.profile === "string" && isCanvasVisualDirectionProfile(value.profile) ? value.profile : void 0;
15712
+ const themeStrategy = typeof value.themeStrategy === "string" && isCanvasThemeStrategy(value.themeStrategy) ? value.themeStrategy : void 0;
15713
+ const navigationModel = typeof value.navigationModel === "string" && isCanvasNavigationModel(value.navigationModel) ? value.navigationModel : void 0;
15714
+ if (!profile || !themeStrategy || !navigationModel || typeof value.layoutApproach !== "string") {
15715
+ return void 0;
15716
+ }
15717
+ return {
15718
+ profile,
15719
+ themeStrategy,
15720
+ navigationModel,
15721
+ layoutApproach: value.layoutApproach
15722
+ };
15723
+ };
15724
+ var parseInspiredesignBriefFormat = (value) => {
15725
+ if (!isJsonRecord6(value)) return void 0;
15726
+ const route = parseInspiredesignBriefFormatRoute(value.route);
15727
+ if (typeof value.id !== "string" || typeof value.label !== "string" || !isStringArray2(value.bestFor) || !isStringArray2(value.businessFocus) || !isStringArray2(value.keywords) || typeof value.archetype !== "string" || typeof value.layoutArchetype !== "string" || typeof value.typographySystem !== "string" || typeof value.surfaceTreatment !== "string" || typeof value.shapeLanguage !== "string" || typeof value.componentGrammar !== "string" || typeof value.motionGrammar !== "string" || typeof value.paletteIntent !== "string" || typeof value.visualDensity !== "string" || typeof value.designVariance !== "string" || !isStringArray2(value.responsiveCollapseRules) || !isStringArray2(value.guardrails) || !isStringArray2(value.antiPatterns) || !isStringArray2(value.deliverables) || !route) {
15728
+ return void 0;
15729
+ }
15730
+ return {
15731
+ id: value.id,
15732
+ label: value.label,
15733
+ bestFor: [...value.bestFor],
15734
+ businessFocus: [...value.businessFocus],
15735
+ keywords: [...value.keywords],
15736
+ archetype: value.archetype,
15737
+ layoutArchetype: value.layoutArchetype,
15738
+ typographySystem: value.typographySystem,
15739
+ surfaceTreatment: value.surfaceTreatment,
15740
+ shapeLanguage: value.shapeLanguage,
15741
+ componentGrammar: value.componentGrammar,
15742
+ motionGrammar: value.motionGrammar,
15743
+ paletteIntent: value.paletteIntent,
15744
+ visualDensity: value.visualDensity,
15745
+ designVariance: value.designVariance,
15746
+ responsiveCollapseRules: [...value.responsiveCollapseRules],
15747
+ guardrails: [...value.guardrails],
15748
+ antiPatterns: [...value.antiPatterns],
15749
+ deliverables: [...value.deliverables],
15750
+ route
15751
+ };
15752
+ };
15753
+ var parseInspiredesignBriefExpansion = (value) => {
15754
+ if (!isJsonRecord6(value)) return void 0;
15755
+ const format = parseInspiredesignBriefFormat(value.format);
15756
+ if (typeof value.sourceBrief !== "string" || typeof value.advancedBrief !== "string" || typeof value.templateVersion !== "string" || !format) {
15757
+ return void 0;
15758
+ }
15759
+ return {
15760
+ sourceBrief: value.sourceBrief,
15761
+ advancedBrief: value.advancedBrief,
15762
+ templateVersion: value.templateVersion,
15763
+ format
15764
+ };
15765
+ };
15766
+ var parseInspiredesignEnvelopeInput = (input) => {
15767
+ const briefExpansion = parseInspiredesignBriefExpansion(input.briefExpansion);
15768
+ return {
15769
+ brief: typeof input.brief === "string" ? input.brief : "",
15770
+ mode: typeof input.mode === "string" && INSPIREDESIGN_RENDER_MODES.has(input.mode) ? input.mode : "compact",
15771
+ ...briefExpansion ? { briefExpansion } : {},
15772
+ ...Array.isArray(input.urls) ? { urls: input.urls.filter((url) => typeof url === "string") } : {},
15773
+ ...typeof input.captureMode === "string" && INSPIREDESIGN_CAPTURE_MODES.has(input.captureMode) ? { captureMode: input.captureMode } : {},
15774
+ ...typeof input.includePrototypeGuidance === "boolean" ? { includePrototypeGuidance: input.includePrototypeGuidance } : {},
15775
+ ...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
15776
+ ...typeof input.outputDir === "string" && input.outputDir.length > 0 ? { outputDir: input.outputDir } : {},
15777
+ ...typeof input.ttlHours === "number" ? { ttlHours: input.ttlHours } : {},
15778
+ ...typeof input.useCookies === "boolean" ? { useCookies: input.useCookies } : {},
15779
+ ...isChallengeAutomationMode(input.challengeAutomationMode) ? { challengeAutomationMode: input.challengeAutomationMode } : {},
15780
+ ...typeof input.cookiePolicyOverride === "string" && INSPIREDESIGN_COOKIE_POLICIES.has(input.cookiePolicyOverride) ? { cookiePolicyOverride: input.cookiePolicyOverride } : {}
15781
+ };
15782
+ };
13822
15783
  var normalizeInspiredesignUrls = (urls) => {
13823
15784
  if (!urls || urls.length === 0) return [];
13824
15785
  const normalized = urls.map((url) => url.trim()).filter(Boolean);
@@ -13828,16 +15789,36 @@ var normalizeInspiredesignUrls = (urls) => {
13828
15789
  }
13829
15790
  return [...new Set(normalized.map((url) => canonicalizeUrl(url)))];
13830
15791
  };
15792
+ var hasValidInspiredesignBriefRoute = (route) => {
15793
+ return isCanvasVisualDirectionProfile(route.profile) && isCanvasThemeStrategy(route.themeStrategy) && isCanvasNavigationModel(route.navigationModel);
15794
+ };
15795
+ var shouldReuseInspiredesignBriefExpansion = (briefExpansion, normalizedBrief) => {
15796
+ if (!briefExpansion) {
15797
+ return false;
15798
+ }
15799
+ if (normalizeInspiredesignBriefText(briefExpansion.sourceBrief) !== normalizedBrief) {
15800
+ return false;
15801
+ }
15802
+ if (briefExpansion.templateVersion !== INSPIREDESIGN_BRIEF_TEMPLATE_VERSION) {
15803
+ return false;
15804
+ }
15805
+ return hasValidInspiredesignBriefRoute(briefExpansion.format.route);
15806
+ };
13831
15807
  var normalizeInspiredesignInput = (input) => {
13832
15808
  const brief = input.brief.trim();
13833
15809
  if (!brief) {
13834
15810
  throw new Error("Inspiredesign workflow requires a non-empty brief.");
13835
15811
  }
15812
+ const urls = normalizeInspiredesignUrls(input.urls);
15813
+ const normalizedBrief = normalizeInspiredesignBriefText(brief);
15814
+ const preferredFormatId = shouldReuseInspiredesignBriefExpansion(input.briefExpansion, normalizedBrief) ? input.briefExpansion.format.id : void 0;
15815
+ const briefExpansion = expandInspiredesignBrief(brief, preferredFormatId);
13836
15816
  return {
13837
15817
  ...input,
13838
15818
  brief,
13839
- urls: normalizeInspiredesignUrls(input.urls),
13840
- captureMode: input.captureMode ?? "off",
15819
+ briefExpansion,
15820
+ urls,
15821
+ captureMode: resolveInspiredesignCaptureMode(input.captureMode, urls),
13841
15822
  mode: input.mode ?? "compact"
13842
15823
  };
13843
15824
  };
@@ -13896,9 +15877,51 @@ var buildInspiredesignFetchOptions = (workflowInput, envelope, timeoutMs) => wit
13896
15877
  "workflow.inspiredesign",
13897
15878
  envelope
13898
15879
  );
13899
- var hasInspiredesignCaptureEvidence = (capture) => {
13900
- if (!capture) return false;
13901
- return Boolean(capture.title || capture.snapshot || capture.dom || capture.clone);
15880
+ var buildEmptyInspiredesignCaptureAttemptCounts = () => ({
15881
+ snapshot: { captured: 0, failed: 0, skipped: 0 },
15882
+ clone: { captured: 0, failed: 0, skipped: 0 },
15883
+ dom: { captured: 0, failed: 0, skipped: 0 }
15884
+ });
15885
+ var buildUnavailableInspiredesignCaptureEvidence = () => ({
15886
+ attempts: {
15887
+ snapshot: { status: "skipped", detail: INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE },
15888
+ clone: { status: "skipped", detail: INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE },
15889
+ dom: { status: "skipped", detail: INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE }
15890
+ }
15891
+ });
15892
+ var PRE_ARTIFACT_CAPTURE_SKIP_MESSAGE = "Skipped after deep capture failed before artifact capture started.";
15893
+ var buildFailedInspiredesignCaptureEvidence = (detail) => ({
15894
+ attempts: {
15895
+ snapshot: { status: "failed", detail },
15896
+ clone: { status: "skipped", detail: PRE_ARTIFACT_CAPTURE_SKIP_MESSAGE },
15897
+ dom: { status: "skipped", detail: PRE_ARTIFACT_CAPTURE_SKIP_MESSAGE }
15898
+ }
15899
+ });
15900
+ var describeInspiredesignCaptureAttempts = (key, counts, statuses) => {
15901
+ const parts = statuses.filter((status) => counts[status] > 0).map((status) => `${status} ${counts[status]}`);
15902
+ if (parts.length === 0) return null;
15903
+ return `${key} (${parts.join(", ")})`;
15904
+ };
15905
+ var summarizeInspiredesignCaptureAttempts = (references) => {
15906
+ const counts = buildEmptyInspiredesignCaptureAttemptCounts();
15907
+ let hasAttempts = false;
15908
+ for (const reference of references) {
15909
+ const attempts = normalizeInspiredesignCaptureEvidence(reference.capture)?.attempts;
15910
+ if (!attempts) continue;
15911
+ hasAttempts = true;
15912
+ for (const key of INSPIREDESIGN_CAPTURE_ATTEMPT_KEYS) {
15913
+ counts[key][attempts[key].status] += 1;
15914
+ }
15915
+ }
15916
+ if (!hasAttempts) return void 0;
15917
+ const worked = INSPIREDESIGN_CAPTURE_ATTEMPT_KEYS.map((key) => describeInspiredesignCaptureAttempts(key, counts[key], ["captured"])).filter((value) => value !== null);
15918
+ const didNotWork = INSPIREDESIGN_CAPTURE_ATTEMPT_KEYS.map((key) => describeInspiredesignCaptureAttempts(key, counts[key], ["failed", "skipped"])).filter((value) => value !== null);
15919
+ return {
15920
+ counts,
15921
+ worked,
15922
+ didNotWork,
15923
+ summary: formatInspiredesignCaptureAttemptSummary({ worked, didNotWork })
15924
+ };
13902
15925
  };
13903
15926
  var captureInspiredesignReference = async (url, captureMode, workflowInput, captureReference, timeoutMs) => {
13904
15927
  if (captureMode === "off") {
@@ -13907,30 +15930,34 @@ var captureInspiredesignReference = async (url, captureMode, workflowInput, capt
13907
15930
  if (!captureReference) {
13908
15931
  return {
13909
15932
  captureStatus: "failed",
13910
- captureFailure: "Deep capture requested, but no browser capture callback was available."
15933
+ captureFailure: INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE,
15934
+ capture: buildUnavailableInspiredesignCaptureEvidence()
13911
15935
  };
13912
15936
  }
13913
15937
  try {
13914
- const capture = await captureReference(url, {
15938
+ const capture = normalizeInspiredesignCaptureEvidence(await captureReference(url, {
13915
15939
  timeoutMs,
13916
15940
  useCookies: workflowInput.useCookies,
13917
15941
  challengeAutomationMode: workflowInput.challengeAutomationMode,
13918
15942
  cookiePolicyOverride: workflowInput.cookiePolicyOverride
13919
- });
13920
- if (!hasInspiredesignCaptureEvidence(capture)) {
15943
+ }));
15944
+ if (!hasInspiredesignCaptureArtifacts(capture)) {
13921
15945
  return {
13922
15946
  captureStatus: "failed",
13923
- captureFailure: "Deep capture did not return usable snapshot, DOM, or clone evidence."
15947
+ captureFailure: "Deep capture did not return usable snapshot, DOM, or clone evidence.",
15948
+ ...capture ? { capture } : {}
13924
15949
  };
13925
15950
  }
13926
15951
  return {
13927
15952
  captureStatus: "captured",
13928
- capture
15953
+ ...capture ? { capture } : {}
13929
15954
  };
13930
15955
  } catch (error) {
15956
+ const captureFailure = error instanceof Error && error.message.trim() ? error.message : "Deep capture failed.";
13931
15957
  return {
13932
15958
  captureStatus: "failed",
13933
- captureFailure: error instanceof Error ? error.message : "Deep capture failed."
15959
+ captureFailure,
15960
+ capture: buildFailedInspiredesignCaptureEvidence(captureFailure)
13934
15961
  };
13935
15962
  }
13936
15963
  };
@@ -13938,6 +15965,75 @@ var getInspiredesignPrimaryRecord = (result, url) => {
13938
15965
  const canonicalUrl = canonicalizeUrl(url);
13939
15966
  return result.records.find((record) => record.url && canonicalizeUrl(record.url) === canonicalUrl) ?? result.records[0];
13940
15967
  };
15968
+ var summarizeInspiredesignIssueSnippet = (record) => {
15969
+ const content = normalizePlainText(record.content);
15970
+ if (!content) return void 0;
15971
+ return toSnippet(content, 240);
15972
+ };
15973
+ var scoreInspiredesignIssueHint = (hint) => {
15974
+ if (hint.reasonCode === "token_required" || hint.reasonCode === "auth_required") return 3;
15975
+ if (hint.reasonCode === "challenge_detected") return 2;
15976
+ if (hint.constraint?.kind === "render_required") return 1;
15977
+ return 0;
15978
+ };
15979
+ var toInspiredesignIssueFailure = (record, hint) => {
15980
+ const issueSnippet = summarizeInspiredesignIssueSnippet(record);
15981
+ const details = {
15982
+ reasonCode: hint.reasonCode,
15983
+ ...record.url ? { url: record.url } : {},
15984
+ ...record.title ? { title: record.title } : {},
15985
+ ...issueSnippet ? { message: issueSnippet } : {},
15986
+ ...typeof record.attributes.providerShell === "string" ? { providerShell: record.attributes.providerShell } : {},
15987
+ ...record.attributes.browserRequired === true ? { browserRequired: true } : {},
15988
+ ...hint.blockerType ? { blockerType: hint.blockerType } : {},
15989
+ ...hint.constraint ? { constraint: hint.constraint } : {}
15990
+ };
15991
+ return {
15992
+ provider: record.provider,
15993
+ source: record.source,
15994
+ error: {
15995
+ code: hint.reasonCode === "token_required" || hint.reasonCode === "auth_required" ? "auth" : "unavailable",
15996
+ message: issueSnippet ?? record.title ?? "Fetched reference content was not usable inspiration evidence.",
15997
+ retryable: false,
15998
+ reasonCode: hint.reasonCode,
15999
+ details
16000
+ }
16001
+ };
16002
+ };
16003
+ var normalizeInspiredesignFetchResult = (result) => {
16004
+ if (result.records.length === 0) {
16005
+ return result;
16006
+ }
16007
+ const usableRecords = [];
16008
+ const unusableRecords = [];
16009
+ for (const record of result.records) {
16010
+ const hint = readProviderIssueHintFromRecord(record);
16011
+ if (hint) {
16012
+ unusableRecords.push({ record, hint });
16013
+ continue;
16014
+ }
16015
+ usableRecords.push(record);
16016
+ }
16017
+ if (unusableRecords.length === 0) {
16018
+ return result;
16019
+ }
16020
+ if (usableRecords.length > 0) {
16021
+ return {
16022
+ ...result,
16023
+ records: usableRecords
16024
+ };
16025
+ }
16026
+ const topUnusableRecord = unusableRecords.slice().sort((left, right) => scoreInspiredesignIssueHint(right.hint) - scoreInspiredesignIssueHint(left.hint))[0];
16027
+ const hasPrimaryIssue = Boolean(summarizePrimaryProviderIssue(result.failures));
16028
+ const synthesizedFailure = !hasPrimaryIssue && topUnusableRecord ? toInspiredesignIssueFailure(topUnusableRecord.record, topUnusableRecord.hint) : void 0;
16029
+ return {
16030
+ ...result,
16031
+ ok: false,
16032
+ records: [],
16033
+ failures: synthesizedFailure ? [...result.failures, synthesizedFailure] : result.failures,
16034
+ ...result.error ? {} : synthesizedFailure ? { error: synthesizedFailure.error } : {}
16035
+ };
16036
+ };
13941
16037
  var summarizeInspiredesignFetchFailure = (result) => {
13942
16038
  return summarizePrimaryProviderIssue(result.failures)?.summary ?? result.error?.message;
13943
16039
  };
@@ -13946,10 +16042,25 @@ var excerptFromInspiredesignRecord = (record) => {
13946
16042
  if (!content) return void 0;
13947
16043
  return toSnippet(content, 240);
13948
16044
  };
16045
+ var captureSnippet = (value, maxLength) => {
16046
+ const content = normalizePlainText(value);
16047
+ if (!content) return void 0;
16048
+ return toSnippet(content, maxLength);
16049
+ };
16050
+ var titleFromInspiredesignCapture = (capture) => {
16051
+ return captureSnippet(capture?.title, 120) ?? captureSnippet(capture?.snapshot?.content, 120) ?? captureSnippet(capture?.dom?.outerHTML, 120) ?? captureSnippet(capture?.clone?.componentPreview, 120) ?? captureSnippet(capture?.clone?.cssPreview, 120);
16052
+ };
16053
+ var excerptFromInspiredesignCapture = (capture) => {
16054
+ return captureSnippet(capture?.snapshot?.content, 240) ?? captureSnippet(capture?.dom?.outerHTML, 240) ?? captureSnippet(capture?.clone?.componentPreview, 240) ?? captureSnippet(capture?.clone?.cssPreview, 240);
16055
+ };
16056
+ var isInspiredesignFetchRecovered = (reference) => {
16057
+ return reference.fetchStatus === "failed" && reference.captureStatus === "captured" && (Boolean(reference.title) || Boolean(reference.excerpt));
16058
+ };
13949
16059
  var buildInspiredesignReference = (url, result, capture) => {
13950
16060
  const primary = getInspiredesignPrimaryRecord(result, url);
13951
- const title = primary?.title ?? capture.capture?.title;
13952
- const excerpt = excerptFromInspiredesignRecord(primary);
16061
+ const normalizedCapture = normalizeInspiredesignCaptureEvidence(capture.capture);
16062
+ const title = normalizePlainText(primary?.title) || titleFromInspiredesignCapture(normalizedCapture);
16063
+ const excerpt = excerptFromInspiredesignRecord(primary) ?? excerptFromInspiredesignCapture(normalizedCapture);
13953
16064
  const fetchStatus = result.records.length > 0 ? "captured" : "failed";
13954
16065
  return {
13955
16066
  id: createHash7("sha256").update(url).digest("hex").slice(0, 12),
@@ -13960,7 +16071,7 @@ var buildInspiredesignReference = (url, result, capture) => {
13960
16071
  captureStatus: capture.captureStatus,
13961
16072
  ...fetchStatus === "failed" && summarizeInspiredesignFetchFailure(result) ? { fetchFailure: summarizeInspiredesignFetchFailure(result) } : {},
13962
16073
  ...capture.captureFailure ? { captureFailure: capture.captureFailure } : {},
13963
- ...capture.capture ? { capture: capture.capture } : {}
16074
+ ...normalizedCapture ? { capture: normalizedCapture } : {}
13964
16075
  };
13965
16076
  };
13966
16077
  var summarizeInspiredesignCaptureConstraint = (references) => {
@@ -13968,21 +16079,29 @@ var summarizeInspiredesignCaptureConstraint = (references) => {
13968
16079
  if (failedReferences.length === 0) {
13969
16080
  return void 0;
13970
16081
  }
13971
- const summary = `Deep capture failed for ${failedReferences.length} ${failedReferences.length === 1 ? "reference" : "references"}.`;
16082
+ const unavailableOnly = failedReferences.every((reference) => reference.captureFailure === INSPIREDESIGN_CAPTURE_UNAVAILABLE_FAILURE);
16083
+ const summary = unavailableOnly ? `Deep capture was unavailable for ${failedReferences.length} ${failedReferences.length === 1 ? "reference" : "references"} in this execution lane.` : `Deep capture failed for ${failedReferences.length} ${failedReferences.length === 1 ? "reference" : "references"}.`;
13972
16084
  const retryUrls = failedReferences.slice(0, 2).map((reference) => `Retry deep capture for ${reference.url} after restoring the required browser session state.`);
13973
16085
  return {
13974
16086
  summary,
13975
16087
  guidance: {
13976
16088
  reason: summary,
13977
- recommendedNextCommands: [
16089
+ recommendedNextCommands: unavailableOnly ? [
16090
+ "Restore browser capture access for this execution lane, then rerun inspiredesign.",
16091
+ ...retryUrls
16092
+ ] : [
13978
16093
  "Rerun inspiredesign after configuring providers.cookieSource for the protected references you need to capture.",
13979
16094
  ...retryUrls
13980
16095
  ]
13981
16096
  }
13982
16097
  };
13983
16098
  };
16099
+ var summarizeInspiredesignFetchConstraint = (references) => {
16100
+ return references.find((reference) => reference.fetchStatus === "failed" && !isInspiredesignFetchRecovered(reference) && typeof reference.fetchFailure === "string" && reference.fetchFailure.trim().length > 0)?.fetchFailure;
16101
+ };
13984
16102
  var buildInspiredesignMeta = (runtime, workflowInput, references, failures, followthrough) => {
13985
16103
  const failedCaptures = references.filter((reference) => reference.captureStatus === "failed");
16104
+ const captureAttemptReport = summarizeInspiredesignCaptureAttempts(references);
13986
16105
  let reasonCodeDistribution = summarizeReasonCodeDistribution(failures);
13987
16106
  let meta = withCamelCasePrimaryConstraintMeta(withReasonCodeDistributionMeta({
13988
16107
  selection: {
@@ -13994,12 +16113,22 @@ var buildInspiredesignMeta = (runtime, workflowInput, references, failures, foll
13994
16113
  reference_count: references.length,
13995
16114
  fetched_references: references.filter((reference) => reference.fetchStatus === "captured").length,
13996
16115
  captured_references: references.filter((reference) => reference.captureStatus === "captured").length,
13997
- failed_fetches: references.filter((reference) => reference.fetchStatus === "failed").length,
13998
- failed_captures: failedCaptures.length
16116
+ failed_fetches: references.filter((reference) => reference.fetchStatus === "failed" && !isInspiredesignFetchRecovered(reference)).length,
16117
+ failed_captures: failedCaptures.length,
16118
+ ...captureAttemptReport ? { capture_attempts: captureAttemptReport.counts } : {}
13999
16119
  },
14000
16120
  alerts: buildWorkflowAlerts(runtime, failures)
14001
16121
  }, reasonCodeDistribution), failures);
14002
16122
  if (!meta.primaryConstraint) {
16123
+ const fetchConstraint = summarizeInspiredesignFetchConstraint(references);
16124
+ if (fetchConstraint) {
16125
+ meta = {
16126
+ ...meta,
16127
+ primaryConstraintSummary: fetchConstraint
16128
+ };
16129
+ }
16130
+ }
16131
+ if (!meta.primaryConstraint && !meta.primaryConstraintSummary) {
14003
16132
  const captureConstraint = summarizeInspiredesignCaptureConstraint(references);
14004
16133
  if (captureConstraint) {
14005
16134
  reasonCodeDistribution = incrementReasonCodeDistribution(
@@ -14014,6 +16143,13 @@ var buildInspiredesignMeta = (runtime, workflowInput, references, failures, foll
14014
16143
  return {
14015
16144
  ...meta,
14016
16145
  followthroughSummary: followthrough.summary,
16146
+ ...captureAttemptReport ? {
16147
+ captureAttemptSummary: captureAttemptReport.summary,
16148
+ captureAttemptReport: {
16149
+ worked: captureAttemptReport.worked,
16150
+ didNotWork: captureAttemptReport.didNotWork
16151
+ }
16152
+ } : {},
14017
16153
  recommendedSkills: followthrough.recommendedSkills,
14018
16154
  deepCaptureRecommendation: followthrough.deepCaptureRecommendation,
14019
16155
  contractScope: followthrough.contractScope
@@ -14856,7 +16992,7 @@ var runInspiredesignWorkflow = async (runtime, input, options = {}) => {
14856
16992
  url
14857
16993
  });
14858
16994
  const fetchTimeoutMs = remainingTimeoutMs();
14859
- const result = await runtime.fetch(
16995
+ const fetchResult = await runtime.fetch(
14860
16996
  { url },
14861
16997
  buildInspiredesignFetchOptions(
14862
16998
  workflowInput,
@@ -14864,8 +17000,8 @@ var runInspiredesignWorkflow = async (runtime, input, options = {}) => {
14864
17000
  fetchTimeoutMs
14865
17001
  )
14866
17002
  );
17003
+ const result = normalizeInspiredesignFetchResult(fetchResult);
14867
17004
  observeWorkflowSignals(runtime, result);
14868
- failures.push(...result.failures);
14869
17005
  const captureTimeoutMs = remainingTimeoutMs();
14870
17006
  const capture = await captureInspiredesignReference(
14871
17007
  url,
@@ -14874,7 +17010,11 @@ var runInspiredesignWorkflow = async (runtime, input, options = {}) => {
14874
17010
  options.captureReference,
14875
17011
  captureTimeoutMs
14876
17012
  );
14877
- references.push(buildInspiredesignReference(url, result, capture));
17013
+ const reference = buildInspiredesignReference(url, result, capture);
17014
+ references.push(reference);
17015
+ if (reference.fetchStatus === "failed" && !isInspiredesignFetchRecovered(reference)) {
17016
+ failures.push(...result.failures);
17017
+ }
14878
17018
  trace = appendWorkflowTrace(stepTrace, "execute", "reference_completed", {
14879
17019
  stepIndex: index,
14880
17020
  url,
@@ -14884,6 +17024,7 @@ var runInspiredesignWorkflow = async (runtime, input, options = {}) => {
14884
17024
  }
14885
17025
  const packet = buildInspiredesignPacket({
14886
17026
  brief: workflowInput.brief,
17027
+ briefExpansion: workflowInput.briefExpansion,
14887
17028
  urls: workflowInput.urls,
14888
17029
  references,
14889
17030
  includePrototypeGuidance: workflowInput.includePrototypeGuidance
@@ -14892,6 +17033,7 @@ var runInspiredesignWorkflow = async (runtime, input, options = {}) => {
14892
17033
  const rendered = renderInspiredesign({
14893
17034
  mode: workflowInput.mode,
14894
17035
  brief: workflowInput.brief,
17036
+ advancedBriefMarkdown: packet.advancedBriefMarkdown,
14895
17037
  urls: workflowInput.urls,
14896
17038
  designContract: packet.designContract,
14897
17039
  canvasPlanRequest: packet.canvasPlanRequest,
@@ -15364,7 +17506,7 @@ var shouldRecoverSocialDocumentIssue = (platform, operation, issue) => {
15364
17506
  }
15365
17507
  return operation === "search" && SEARCH_RENDER_RECOVERY_SOCIAL_PLATFORMS.has(platform) && issue.reasonCode === "env_limited" && issue.constraint?.kind === "render_required";
15366
17508
  };
15367
- var isJsonRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17509
+ var isJsonRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
15368
17510
  var unwrapWorkflowResumeEnvelope = (kind, input) => {
15369
17511
  if (!isWorkflowResumePayload(input)) {
15370
17512
  throw new ProviderRuntimeError(
@@ -16722,7 +18864,7 @@ var ProviderRuntime = class {
16722
18864
  }
16723
18865
  async resumeSuspendedIntent(intent, options) {
16724
18866
  const input = intent.input;
16725
- if (!isJsonRecord5(input)) {
18867
+ if (!isJsonRecord7(input)) {
16726
18868
  throw new ProviderRuntimeError("invalid_input", "Suspended intent input is missing or malformed.", {
16727
18869
  retryable: false
16728
18870
  });
@@ -17410,6 +19552,25 @@ export {
17410
19552
  resolveChallengeAutomationPolicy,
17411
19553
  inspectChallengePlanFromRuntime,
17412
19554
  ChallengeOrchestrator,
19555
+ CANVAS_SCHEMA_VERSION,
19556
+ CANVAS_SESSION_MODES,
19557
+ CANVAS_GOVERNANCE_BLOCK_KEYS,
19558
+ CANVAS_REQUIRED_MUTATION_GOVERNANCE_KEYS,
19559
+ CANVAS_REQUIRED_SAVE_GOVERNANCE_KEYS,
19560
+ CANVAS_OPTIONAL_INHERITED_GOVERNANCE_KEYS,
19561
+ CANVAS_GENERATION_PLAN_REQUIRED_FIELDS,
19562
+ CANVAS_VISUAL_DIRECTION_PROFILES,
19563
+ CANVAS_THEME_STRATEGIES,
19564
+ CANVAS_NAVIGATION_MODELS,
19565
+ CANVAS_INTERACTION_STATES,
19566
+ CANVAS_PLAN_VIEWPORTS,
19567
+ CANVAS_PLAN_THEMES,
19568
+ CANVAS_MOTION_LEVELS,
19569
+ CANVAS_REDUCED_MOTION_POLICIES,
19570
+ CANVAS_KEYBOARD_NAVIGATION_MODES,
19571
+ CANVAS_BROWSER_VALIDATION_MODES,
19572
+ CANVAS_VALIDATION_TARGET_BLOCK_ON_CODES,
19573
+ CANVAS_PUBLIC_WARNING_CLASSES,
17413
19574
  summarizePrimaryProviderIssue,
17414
19575
  createTraceContext,
17415
19576
  clampConfidence,
@@ -17453,6 +19614,7 @@ export {
17453
19614
  renderShopping,
17454
19615
  renderInspiredesign,
17455
19616
  buildMacroResolveSuccessHandoff,
19617
+ resolveInspiredesignCaptureMode,
17456
19618
  workflowTestUtils,
17457
19619
  runResearchWorkflow,
17458
19620
  runShoppingWorkflow,
@@ -17463,4 +19625,4 @@ export {
17463
19625
  createProviderRuntime,
17464
19626
  createDefaultRuntime
17465
19627
  };
17466
- //# sourceMappingURL=chunk-K2TEHJCV.js.map
19628
+ //# sourceMappingURL=chunk-AVQL6WAS.js.map