@promptbook/cli 0.103.0-66 → 0.103.0-68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/agents-server/TODO.txt +1 -5
- package/apps/agents-server/config.ts +3 -1
- package/apps/agents-server/package-lock.json +8 -2317
- package/apps/agents-server/package.json +0 -9
- package/apps/agents-server/src/app/agents/[agentName]/AgentOptionsMenu.tsx +34 -2
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileChat.tsx +1 -1
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileWrapper.tsx +4 -0
- package/apps/agents-server/src/app/humans.txt/route.ts +15 -0
- package/apps/agents-server/src/app/layout.tsx +31 -0
- package/apps/agents-server/src/app/robots.txt/route.ts +15 -0
- package/apps/agents-server/src/app/security.txt/route.ts +15 -0
- package/apps/agents-server/src/app/sitemap.xml/route.ts +37 -0
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +28 -23
- package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +19 -18
- package/apps/agents-server/src/components/Footer/Footer.tsx +13 -13
- package/apps/agents-server/src/components/Header/Header.tsx +95 -20
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +3 -0
- package/apps/agents-server/src/components/_utils/generateMetaTxt.ts +28 -0
- package/apps/agents-server/src/components/_utils/headlessParam.tsx +36 -0
- package/apps/agents-server/src/middleware.ts +6 -2
- package/apps/agents-server/src/tools/$provideCdnForServer.ts +13 -1
- package/apps/agents-server/src/utils/cdn/classes/DigitalOceanSpaces.ts +119 -0
- package/apps/agents-server/src/utils/cdn/classes/VercelBlobStorage.ts +2 -1
- package/esm/index.es.js +191 -14
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/components.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +6 -0
- package/esm/typings/src/book-components/BookEditor/BookEditor.d.ts +10 -0
- package/esm/typings/src/book-components/BookEditor/BookEditorActionbar.d.ts +4 -0
- package/esm/typings/src/book-components/icons/CameraIcon.d.ts +11 -0
- package/esm/typings/src/execution/LlmExecutionTools.d.ts +5 -1
- package/esm/typings/src/execution/PromptResult.d.ts +7 -1
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +13 -1
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +4 -0
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +6 -6
- package/esm/typings/src/types/ModelRequirements.d.ts +13 -1
- package/esm/typings/src/types/ModelVariant.d.ts +1 -1
- package/esm/typings/src/types/Prompt.d.ts +13 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +191 -14
- package/umd/index.umd.js.map +1 -1
|
@@ -8,14 +8,5 @@
|
|
|
8
8
|
"start": "next start -p 4440",
|
|
9
9
|
"lint": "next lint",
|
|
10
10
|
"postinstall": "cd ../../ && npm ci"
|
|
11
|
-
},
|
|
12
|
-
"devDependencies": {
|
|
13
|
-
"@tailwindcss/typography": "^0.5.19",
|
|
14
|
-
"autoprefixer": "^10.4.21",
|
|
15
|
-
"postcss": "^8.5.6",
|
|
16
|
-
"tailwindcss": "^3.4.18"
|
|
17
|
-
},
|
|
18
|
-
"dependencies": {
|
|
19
|
-
"remark-gfm": "^4.0.1"
|
|
20
11
|
}
|
|
21
12
|
}
|
|
@@ -32,6 +32,7 @@ const barlowCondensed = Barlow_Condensed({
|
|
|
32
32
|
|
|
33
33
|
type AgentOptionsMenuProps = {
|
|
34
34
|
agentName: string;
|
|
35
|
+
derivedAgentName: string;
|
|
35
36
|
agentUrl: string;
|
|
36
37
|
agentEmail: string;
|
|
37
38
|
brandColorHex: string;
|
|
@@ -42,6 +43,7 @@ type AgentOptionsMenuProps = {
|
|
|
42
43
|
|
|
43
44
|
export function AgentOptionsMenu({
|
|
44
45
|
agentName,
|
|
46
|
+
derivedAgentName,
|
|
45
47
|
agentUrl,
|
|
46
48
|
agentEmail,
|
|
47
49
|
brandColorHex,
|
|
@@ -119,7 +121,33 @@ export function AgentOptionsMenu({
|
|
|
119
121
|
const historyLink = links.find((l) => l.title === 'History & Feedback')!;
|
|
120
122
|
const allLinksLink = links.find((l) => l.title === 'All Links')!;
|
|
121
123
|
|
|
124
|
+
// "Update URL" logic
|
|
125
|
+
const showUpdateUrl = agentName !== derivedAgentName;
|
|
126
|
+
const updateUrlHref = `/agents/${encodeURIComponent(derivedAgentName)}`;
|
|
127
|
+
|
|
128
|
+
const handleUpdateUrl = () => {
|
|
129
|
+
if (
|
|
130
|
+
window.confirm(
|
|
131
|
+
`Are you sure you want to change the agent URL from "/agents/${agentName}" to "/agents/${derivedAgentName}"?`
|
|
132
|
+
)
|
|
133
|
+
) {
|
|
134
|
+
window.location.href = updateUrlHref;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
122
138
|
const menuItems = [
|
|
139
|
+
...(showUpdateUrl
|
|
140
|
+
? [
|
|
141
|
+
{
|
|
142
|
+
type: 'action' as const,
|
|
143
|
+
icon: MoreHorizontalIcon,
|
|
144
|
+
label: 'Update URL',
|
|
145
|
+
onClick: handleUpdateUrl,
|
|
146
|
+
highlight: true,
|
|
147
|
+
},
|
|
148
|
+
{ type: 'divider' as const },
|
|
149
|
+
]
|
|
150
|
+
: []),
|
|
123
151
|
{
|
|
124
152
|
type: 'link' as const,
|
|
125
153
|
href: `/agents/${encodeURIComponent(agentName)}/chat`,
|
|
@@ -268,9 +296,13 @@ export function AgentOptionsMenu({
|
|
|
268
296
|
// Keep menu open for copy feedback
|
|
269
297
|
}
|
|
270
298
|
}}
|
|
271
|
-
className=
|
|
299
|
+
className={`flex items-center gap-3 px-4 py-2.5 w-full text-left transition-colors
|
|
300
|
+
${item.highlight
|
|
301
|
+
? 'bg-yellow-100 text-yellow-900 font-bold hover:bg-yellow-200'
|
|
302
|
+
: 'text-gray-700 hover:bg-gray-50'}
|
|
303
|
+
`}
|
|
272
304
|
>
|
|
273
|
-
<item.icon className=
|
|
305
|
+
<item.icon className={`w-4 h-4 ${item.highlight ? 'text-yellow-700' : 'text-gray-500'}`} />
|
|
274
306
|
<span className="text-sm font-medium">{item.label}</span>
|
|
275
307
|
</button>
|
|
276
308
|
);
|
|
@@ -57,7 +57,7 @@ export function AgentProfileChat({ agentUrl, agentName, fullname, brandColorHex,
|
|
|
57
57
|
// The fallback above matches AgentChat.tsx default.
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
|
-
<div className="w-full h-[
|
|
60
|
+
<div className="w-full h-[calc(100dvh-300px)] min-h-[350px] md:h-[500px]">
|
|
61
61
|
<Chat
|
|
62
62
|
title={`Chat with ${fullname}`}
|
|
63
63
|
participants={[
|
|
@@ -19,6 +19,9 @@ type AgentProfileWrapperProps = {
|
|
|
19
19
|
export function AgentProfileWrapper(props: AgentProfileWrapperProps) {
|
|
20
20
|
const { agent, agentUrl, agentEmail, agentName, brandColorHex, isAdmin, isHeadless, actions, children } = props;
|
|
21
21
|
|
|
22
|
+
// Derived agentName from agent data
|
|
23
|
+
const derivedAgentName = agent.agentName;
|
|
24
|
+
|
|
22
25
|
return (
|
|
23
26
|
<AgentProfile
|
|
24
27
|
agent={agent}
|
|
@@ -28,6 +31,7 @@ export function AgentProfileWrapper(props: AgentProfileWrapperProps) {
|
|
|
28
31
|
renderMenu={({ onShowQrCode }) => (
|
|
29
32
|
<AgentOptionsMenu
|
|
30
33
|
agentName={agentName}
|
|
34
|
+
derivedAgentName={derivedAgentName}
|
|
31
35
|
agentUrl={agentUrl}
|
|
32
36
|
agentEmail={agentEmail}
|
|
33
37
|
brandColorHex={brandColorHex}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Dynamic humans.txt for Agents Server
|
|
2
|
+
|
|
3
|
+
import { generateHumansTxt } from '@/src/components/_utils/generateMetaTxt';
|
|
4
|
+
import { NextResponse } from 'next/server';
|
|
5
|
+
|
|
6
|
+
export const dynamic = 'force-dynamic';
|
|
7
|
+
|
|
8
|
+
export async function GET() {
|
|
9
|
+
const txt = generateHumansTxt();
|
|
10
|
+
return new NextResponse(txt, {
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'text/plain',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -7,6 +7,7 @@ import { $provideAgentCollectionForServer } from '../tools/$provideAgentCollecti
|
|
|
7
7
|
import { $provideServer } from '../tools/$provideServer';
|
|
8
8
|
import { getCurrentUser } from '../utils/getCurrentUser';
|
|
9
9
|
import { isUserAdmin } from '../utils/isUserAdmin';
|
|
10
|
+
import { getFederatedServersFromMetadata } from '../utils/getFederatedServersFromMetadata';
|
|
10
11
|
import './globals.css';
|
|
11
12
|
|
|
12
13
|
const barlowCondensed = Barlow_Condensed({
|
|
@@ -82,6 +83,35 @@ export default async function RootLayout({
|
|
|
82
83
|
console.error('Failed to parse FOOTER_LINKS', error);
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
// Fetch federated servers and add to footerLinks
|
|
87
|
+
let federatedServers: Array<{ url: string; title: string; logoUrl: string | null }> = [];
|
|
88
|
+
try {
|
|
89
|
+
const federatedServersRaw = await getFederatedServersFromMetadata();
|
|
90
|
+
federatedServers = await Promise.all(
|
|
91
|
+
federatedServersRaw.map(async (url: string) => {
|
|
92
|
+
let logoUrl: string | null = null;
|
|
93
|
+
try {
|
|
94
|
+
// Try to fetch logo from metadata endpoint if available
|
|
95
|
+
const res = await fetch(`${url}/api/metadata`);
|
|
96
|
+
if (res.ok) {
|
|
97
|
+
const meta = await res.json();
|
|
98
|
+
logoUrl = meta.SERVER_LOGO_URL || null;
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
logoUrl = null;
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
title: `Federated: ${new URL(url).hostname}`,
|
|
105
|
+
url,
|
|
106
|
+
logoUrl,
|
|
107
|
+
};
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
footerLinks = [...footerLinks, ...federatedServers];
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error('Failed to fetch federated servers for footer', error);
|
|
113
|
+
}
|
|
114
|
+
|
|
85
115
|
const collection = await $provideAgentCollectionForServer();
|
|
86
116
|
const agents = await collection.listAgents();
|
|
87
117
|
|
|
@@ -97,6 +127,7 @@ export default async function RootLayout({
|
|
|
97
127
|
agents={JSON.parse(JSON.stringify(agents))}
|
|
98
128
|
isFooterShown={isFooterShown}
|
|
99
129
|
footerLinks={footerLinks}
|
|
130
|
+
federatedServers={federatedServers}
|
|
100
131
|
>
|
|
101
132
|
{children}
|
|
102
133
|
</LayoutWrapper>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Dynamic robots.txt for Agents Server
|
|
2
|
+
|
|
3
|
+
import { generateRobotsTxt } from '@/src/components/_utils/generateMetaTxt';
|
|
4
|
+
import { NextResponse } from 'next/server';
|
|
5
|
+
|
|
6
|
+
export const dynamic = 'force-dynamic';
|
|
7
|
+
|
|
8
|
+
export async function GET() {
|
|
9
|
+
const txt = generateRobotsTxt();
|
|
10
|
+
return new NextResponse(txt, {
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'text/plain',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Dynamic security.txt for Agents Server
|
|
2
|
+
|
|
3
|
+
import { generateSecurityTxt } from '@/src/components/_utils/generateMetaTxt';
|
|
4
|
+
import { NextResponse } from 'next/server';
|
|
5
|
+
|
|
6
|
+
export const dynamic = 'force-dynamic';
|
|
7
|
+
|
|
8
|
+
export async function GET() {
|
|
9
|
+
const txt = generateSecurityTxt();
|
|
10
|
+
return new NextResponse(txt, {
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'text/plain',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Dynamic sitemap.xml for Agents Server
|
|
2
|
+
|
|
3
|
+
import { NEXT_PUBLIC_SITE_URL } from '@/config';
|
|
4
|
+
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
5
|
+
import { spaceTrim } from '@promptbook-local/utils';
|
|
6
|
+
import { NextResponse } from 'next/server';
|
|
7
|
+
|
|
8
|
+
export const dynamic = 'force-dynamic';
|
|
9
|
+
|
|
10
|
+
export async function GET() {
|
|
11
|
+
const collection = await $provideAgentCollectionForServer();
|
|
12
|
+
|
|
13
|
+
// Assume collection.listAgents() returns an array of agent names
|
|
14
|
+
const agentNames = await collection.listAgents();
|
|
15
|
+
|
|
16
|
+
// Get base URL from environment or config
|
|
17
|
+
const baseUrl = NEXT_PUBLIC_SITE_URL?.href || process.env.PUBLIC_URL || 'https://ptbk.io';
|
|
18
|
+
|
|
19
|
+
const urls = agentNames
|
|
20
|
+
.map(({ agentName }) => `<url><loc>${baseUrl}agents/${encodeURIComponent(agentName)}</loc></url>`)
|
|
21
|
+
.join('\n');
|
|
22
|
+
|
|
23
|
+
const xml = spaceTrim(
|
|
24
|
+
(block) => `
|
|
25
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
26
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
27
|
+
${block(urls)}
|
|
28
|
+
</urlset>
|
|
29
|
+
`,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return new NextResponse(xml, {
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/xml',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -208,11 +208,14 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
208
208
|
)}
|
|
209
209
|
|
|
210
210
|
{/* Main profile content */}
|
|
211
|
-
<div className="relative z-10
|
|
211
|
+
<div className="relative z-10 grid grid-cols-[auto_1fr] gap-x-6 gap-y-4 md:gap-12 max-w-5xl w-full items-start">
|
|
212
212
|
{/* Agent image card (Flippable) */}
|
|
213
|
-
<div
|
|
213
|
+
<div
|
|
214
|
+
className="flex-shrink-0 perspective-1000 group row-start-1 col-start-1 md:row-span-3"
|
|
215
|
+
style={{ perspective: '1000px' }}
|
|
216
|
+
>
|
|
214
217
|
<div
|
|
215
|
-
className="relative w-
|
|
218
|
+
className="relative w-24 md:w-80 transition-all duration-700 transform-style-3d cursor-pointer"
|
|
216
219
|
style={{
|
|
217
220
|
aspectRatio: '1 / 1.618', // Golden Ratio
|
|
218
221
|
transformStyle: 'preserve-3d',
|
|
@@ -222,7 +225,7 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
222
225
|
>
|
|
223
226
|
{/* Front of Card (Image) */}
|
|
224
227
|
<div
|
|
225
|
-
className="absolute inset-0 w-full h-full backface-hidden rounded-3xl shadow-2xl overflow-hidden backdrop-blur-sm"
|
|
228
|
+
className="absolute inset-0 w-full h-full backface-hidden rounded-lg md:rounded-3xl shadow-lg md:shadow-2xl overflow-hidden backdrop-blur-sm"
|
|
226
229
|
style={{
|
|
227
230
|
backfaceVisibility: 'hidden',
|
|
228
231
|
backgroundColor: brandColorDarkHex,
|
|
@@ -234,7 +237,7 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
234
237
|
<img src={imageUrl} alt={fullname} className="w-full h-full object-cover" />
|
|
235
238
|
) : (
|
|
236
239
|
<div
|
|
237
|
-
className="w-full h-full flex items-center justify-center text-8xl font-bold text-white/80"
|
|
240
|
+
className="w-full h-full flex items-center justify-center text-3xl md:text-8xl font-bold text-white/80"
|
|
238
241
|
style={{ backgroundColor: brandColorDarkHex }}
|
|
239
242
|
>
|
|
240
243
|
{fullname.charAt(0).toUpperCase()}
|
|
@@ -242,14 +245,14 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
242
245
|
)}
|
|
243
246
|
|
|
244
247
|
{/* Flip hint icon */}
|
|
245
|
-
<div className="absolute bottom-4 right-4 bg-black/30 p-2 rounded-full text-white/80 backdrop-blur-md opacity-0 group-hover:opacity-100 transition-opacity">
|
|
246
|
-
<RepeatIcon className="w-5 h-5" />
|
|
248
|
+
<div className="absolute bottom-2 md:bottom-4 right-2 md:right-4 bg-black/30 p-1 md:p-2 rounded-full text-white/80 backdrop-blur-md opacity-0 group-hover:opacity-100 transition-opacity">
|
|
249
|
+
<RepeatIcon className="w-3 h-3 md:w-5 md:h-5" />
|
|
247
250
|
</div>
|
|
248
251
|
</div>
|
|
249
252
|
|
|
250
253
|
{/* Back of Card (QR Code) */}
|
|
251
254
|
<div
|
|
252
|
-
className="absolute inset-0 w-full h-full backface-hidden rounded-3xl shadow-2xl overflow-hidden backdrop-blur-sm flex flex-col items-center justify-center p-6"
|
|
255
|
+
className="absolute inset-0 w-full h-full backface-hidden rounded-lg md:rounded-3xl shadow-lg md:shadow-2xl overflow-hidden backdrop-blur-sm flex flex-col items-center justify-center p-2 md:p-6"
|
|
253
256
|
style={{
|
|
254
257
|
backfaceVisibility: 'hidden',
|
|
255
258
|
transform: 'rotateY(180deg)',
|
|
@@ -269,18 +272,18 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
269
272
|
</div>
|
|
270
273
|
|
|
271
274
|
{/* Flip hint icon */}
|
|
272
|
-
<div className="absolute bottom-4 right-4 bg-black/10 p-2 rounded-full text-black/50 backdrop-blur-md">
|
|
273
|
-
<RepeatIcon className="w-5 h-5" />
|
|
275
|
+
<div className="absolute bottom-2 md:bottom-4 right-2 md:right-4 bg-black/10 p-1 md:p-2 rounded-full text-black/50 backdrop-blur-md">
|
|
276
|
+
<RepeatIcon className="w-3 h-3 md:w-5 md:h-5" />
|
|
274
277
|
</div>
|
|
275
278
|
</div>
|
|
276
279
|
</div>
|
|
277
280
|
</div>
|
|
278
281
|
|
|
279
|
-
{/* Agent info */}
|
|
280
|
-
<div className="flex flex-col
|
|
282
|
+
{/* Agent info - Header Area */}
|
|
283
|
+
<div className="row-start-1 col-start-2 flex flex-col justify-center md:justify-start h-full md:h-auto gap-1 md:gap-6">
|
|
281
284
|
{/* Agent name with custom font */}
|
|
282
285
|
<h1
|
|
283
|
-
className="text-
|
|
286
|
+
className="text-2xl md:text-5xl lg:text-6xl font-bold text-gray-900 tracking-tight leading-tight"
|
|
284
287
|
style={{
|
|
285
288
|
textShadow: '0 2px 20px rgba(255, 255, 255, 0.5)',
|
|
286
289
|
}}
|
|
@@ -289,20 +292,22 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
289
292
|
</h1>
|
|
290
293
|
|
|
291
294
|
{/* Short description */}
|
|
292
|
-
<p className="text-
|
|
295
|
+
<p className="text-sm md:text-xl text-gray-700 max-w-lg leading-relaxed font-medium line-clamp-3 md:line-clamp-none">
|
|
293
296
|
{personaDescription}
|
|
294
297
|
</p>
|
|
298
|
+
</div>
|
|
295
299
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
{/* Secondary Actions */}
|
|
300
|
-
{!isHeadless && (
|
|
301
|
-
<div className="flex flex-wrap justify-center md:justify-start items-center gap-4 md:gap-6 mt-2">
|
|
302
|
-
{actions}
|
|
303
|
-
</div>
|
|
304
|
-
)}
|
|
300
|
+
{/* Chat Area */}
|
|
301
|
+
<div className="col-span-2 md:col-span-1 md:col-start-2 w-full mt-2 md:mt-0">
|
|
302
|
+
{children}
|
|
305
303
|
</div>
|
|
304
|
+
|
|
305
|
+
{/* Secondary Actions */}
|
|
306
|
+
{!isHeadless && (
|
|
307
|
+
<div className="col-span-2 md:col-span-1 md:col-start-2 flex flex-wrap justify-center md:justify-start items-center gap-4 md:gap-6 mt-2">
|
|
308
|
+
{actions}
|
|
309
|
+
</div>
|
|
310
|
+
)}
|
|
306
311
|
</div>
|
|
307
312
|
|
|
308
313
|
{/* Subtle gradient overlay at bottom */}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import remarkGfm from 'remark-gfm';
|
|
3
|
-
import { string_book } from '../../../../../src/book-2.0/agent-source/string_book';
|
|
4
|
-
import { BookEditor } from '../../../../../src/book-components/BookEditor/BookEditor';
|
|
1
|
+
import { MarkdownContent } from '@promptbook-local/components';
|
|
5
2
|
import { OpenMojiIcon } from '../OpenMojiIcon/OpenMojiIcon';
|
|
6
3
|
|
|
7
4
|
type DocumentationContentProps = {
|
|
@@ -17,16 +14,22 @@ type DocumentationContentProps = {
|
|
|
17
14
|
|
|
18
15
|
export function DocumentationContent({ primary, aliases = [], isPrintOnly = false }: DocumentationContentProps) {
|
|
19
16
|
return (
|
|
20
|
-
<div
|
|
21
|
-
|
|
17
|
+
<div
|
|
18
|
+
className={`bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden ${
|
|
19
|
+
isPrintOnly ? 'shadow-none border-none' : ''
|
|
20
|
+
}`}
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
className={`p-8 border-b border-gray-100 bg-gray-50/50 ${
|
|
24
|
+
isPrintOnly ? 'border-none bg-white p-0 mb-4' : ''
|
|
25
|
+
}`}
|
|
26
|
+
>
|
|
22
27
|
<div className="flex items-center gap-4 mb-4">
|
|
23
28
|
<h1 className="text-4xl font-bold text-gray-900 tracking-tight">
|
|
24
29
|
<OpenMojiIcon icon={primary.icon} className="mr-3" />
|
|
25
30
|
{primary.type}
|
|
26
31
|
{aliases.length > 0 && (
|
|
27
|
-
<span className="text-gray-400 font-normal ml-4 text-2xl">
|
|
28
|
-
/ {aliases.join(' / ')}
|
|
29
|
-
</span>
|
|
32
|
+
<span className="text-gray-400 font-normal ml-4 text-2xl">/ {aliases.join(' / ')}</span>
|
|
30
33
|
)}
|
|
31
34
|
</h1>
|
|
32
35
|
{!isPrintOnly && (
|
|
@@ -36,16 +39,15 @@ export function DocumentationContent({ primary, aliases = [], isPrintOnly = fals
|
|
|
36
39
|
)}
|
|
37
40
|
</div>
|
|
38
41
|
{primary.description && (
|
|
39
|
-
<p className="text-xl text-gray-600 leading-relaxed max-w-3xl">
|
|
40
|
-
{primary.description}
|
|
41
|
-
</p>
|
|
42
|
+
<p className="text-xl text-gray-600 leading-relaxed max-w-3xl">{primary.description}</p>
|
|
42
43
|
)}
|
|
43
44
|
</div>
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
<div className={`p-8 ${isPrintOnly ? 'p-0' : ''}`}>
|
|
46
47
|
<article className="prose prose-lg prose-slate max-w-none prose-headings:font-bold prose-headings:tracking-tight prose-headings:text-gray-900 prose-h1:text-4xl prose-h1:mb-8 prose-h2:text-2xl prose-h2:mt-12 prose-h2:mb-6 prose-h2:pb-2 prose-h2:border-b prose-h2:border-gray-200 prose-h3:text-xl prose-h3:mt-8 prose-h3:mb-4 prose-h3:text-gray-800 prose-p:text-gray-600 prose-p:leading-relaxed prose-p:mb-6 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:text-blue-700 hover:prose-a:underline prose-a:transition-colors prose-strong:font-bold prose-strong:text-gray-900 prose-code:text-blue-600 prose-code:bg-blue-50 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded-md prose-code:before:content-none prose-code:after:content-none prose-code:font-medium prose-pre:bg-gray-900 prose-pre:text-gray-100 prose-pre:shadow-lg prose-pre:rounded-xl prose-pre:p-6 prose-ul:list-disc prose-ul:pl-6 prose-li:marker:text-gray-400 prose-li:mb-2 prose-ol:list-decimal prose-ol:pl-6 prose-li:mb-2 prose-blockquote:border-l-4 prose-blockquote:border-blue-500 prose-blockquote:bg-blue-50/50 prose-blockquote:py-2 prose-blockquote:px-4 prose-blockquote:rounded-r-lg prose-blockquote:not-italic prose-blockquote:text-gray-700 prose-blockquote:my-8 prose-img:rounded-xl prose-img:shadow-md prose-img:my-8 prose-hr:border-gray-200 prose-hr:my-10 prose-table:w-full prose-th:text-left prose-th:py-2 prose-th:px-3 prose-th:bg-gray-100 prose-th:font-semibold prose-th:text-gray-900 prose-td:py-2 prose-td:px-3 prose-td:border-b prose-td:border-gray-200 prose-tr:hover:bg-gray-50">
|
|
47
|
-
<
|
|
48
|
-
|
|
48
|
+
<MarkdownContent
|
|
49
|
+
content={primary.documentation}
|
|
50
|
+
/* TODO: !!!!
|
|
49
51
|
components={{
|
|
50
52
|
code(props) {
|
|
51
53
|
const { children, className, node, ...rest } = props;
|
|
@@ -77,9 +79,8 @@ export function DocumentationContent({ primary, aliases = [], isPrintOnly = fals
|
|
|
77
79
|
);
|
|
78
80
|
},
|
|
79
81
|
}}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
</ReactMarkdown>
|
|
82
|
+
*/
|
|
83
|
+
/>
|
|
83
84
|
</article>
|
|
84
85
|
</div>
|
|
85
86
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { HeadlessLink } from '../_utils/headlessParam';
|
|
2
2
|
|
|
3
3
|
export type FooterLink = {
|
|
4
4
|
title: string;
|
|
@@ -33,14 +33,14 @@ export function Footer(props: FooterProps) {
|
|
|
33
33
|
<h3 className="font-bold">Product</h3>
|
|
34
34
|
<ul className="space-y-2 text-sm">
|
|
35
35
|
<li>
|
|
36
|
-
<
|
|
36
|
+
<HeadlessLink href="/get-started" className="text-gray-500 hover:text-gray-900">
|
|
37
37
|
Get started
|
|
38
|
-
</
|
|
38
|
+
</HeadlessLink>
|
|
39
39
|
</li>
|
|
40
40
|
<li>
|
|
41
|
-
<
|
|
41
|
+
<HeadlessLink href="/manifest" className="text-gray-500 hover:text-gray-900">
|
|
42
42
|
Manifest
|
|
43
|
-
</
|
|
43
|
+
</HeadlessLink>
|
|
44
44
|
</li>
|
|
45
45
|
<li>
|
|
46
46
|
<a
|
|
@@ -51,14 +51,14 @@ export function Footer(props: FooterProps) {
|
|
|
51
51
|
</a>
|
|
52
52
|
</li>
|
|
53
53
|
<li>
|
|
54
|
-
<
|
|
54
|
+
<HeadlessLink href="/terms" className="text-gray-500 hover:text-gray-900">
|
|
55
55
|
Terms of Service
|
|
56
|
-
</
|
|
56
|
+
</HeadlessLink>
|
|
57
57
|
</li>
|
|
58
58
|
<li>
|
|
59
|
-
<
|
|
59
|
+
<HeadlessLink href="/privacy" className="text-gray-500 hover:text-gray-900">
|
|
60
60
|
Privacy Policy
|
|
61
|
-
</
|
|
61
|
+
</HeadlessLink>
|
|
62
62
|
</li>
|
|
63
63
|
</ul>
|
|
64
64
|
</div>
|
|
@@ -86,9 +86,9 @@ export function Footer(props: FooterProps) {
|
|
|
86
86
|
</a>
|
|
87
87
|
</li>
|
|
88
88
|
<li>
|
|
89
|
-
<
|
|
89
|
+
<HeadlessLink href="/design" className="text-gray-500 hover:text-gray-900">
|
|
90
90
|
Logos & Branding
|
|
91
|
-
</
|
|
91
|
+
</HeadlessLink>
|
|
92
92
|
</li>
|
|
93
93
|
</ul>
|
|
94
94
|
</div>
|
|
@@ -122,9 +122,9 @@ export function Footer(props: FooterProps) {
|
|
|
122
122
|
</a>
|
|
123
123
|
</li>
|
|
124
124
|
<li>
|
|
125
|
-
<
|
|
125
|
+
<HeadlessLink href="/contact" className="text-gray-500 hover:text-gray-900">
|
|
126
126
|
More
|
|
127
|
-
</
|
|
127
|
+
</HeadlessLink>
|
|
128
128
|
</li>
|
|
129
129
|
</ul>
|
|
130
130
|
</div>
|