@promptbook/cli 0.103.0-47 → 0.103.0-49
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/README.md +1 -1
- package/apps/agents-server/TODO.txt +6 -5
- package/apps/agents-server/config.ts +130 -0
- package/apps/agents-server/next.config.ts +1 -1
- package/apps/agents-server/public/fonts/OpenMoji-black-glyf.woff2 +0 -0
- package/apps/agents-server/public/fonts/download-font.js +22 -0
- package/apps/agents-server/src/app/[agentName]/[...rest]/page.tsx +6 -0
- package/apps/agents-server/src/app/[agentName]/page.tsx +1 -0
- package/apps/agents-server/src/app/actions.ts +37 -2
- package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +68 -0
- package/apps/agents-server/src/app/agents/[agentName]/AgentQrCode.tsx +55 -0
- package/apps/agents-server/src/app/agents/[agentName]/AgentUrlCopy.tsx +4 -5
- package/apps/agents-server/src/app/agents/[agentName]/CopyField.tsx +44 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +8 -8
- package/apps/agents-server/src/app/agents/[agentName]/api/chat/route.ts +100 -18
- package/apps/agents-server/src/app/agents/[agentName]/api/feedback/route.ts +54 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/modelRequirements/route.ts +6 -6
- package/apps/agents-server/src/app/agents/[agentName]/api/modelRequirements/systemMessage/route.ts +3 -3
- package/apps/agents-server/src/app/agents/[agentName]/api/profile/route.ts +6 -7
- package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +6 -7
- package/apps/agents-server/src/app/agents/[agentName]/book/page.tsx +9 -2
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/AgentBookAndChat.tsx +23 -0
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/{AgentBookAndChatComponent.tsx → AgentBookAndChatComponent.tsx.todo} +6 -8
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx +28 -17
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx.todo +21 -0
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatWrapper.tsx +34 -4
- package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +4 -1
- package/apps/agents-server/src/app/agents/[agentName]/generateAgentMetadata.ts +42 -0
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +111 -108
- package/apps/agents-server/src/app/agents/page.tsx +1 -1
- package/apps/agents-server/src/app/api/auth/login/route.ts +65 -0
- package/apps/agents-server/src/app/api/auth/logout/route.ts +7 -0
- package/apps/agents-server/src/app/api/metadata/route.ts +116 -0
- package/apps/agents-server/src/app/api/upload/route.ts +7 -7
- package/apps/agents-server/src/app/api/users/[username]/route.ts +75 -0
- package/apps/agents-server/src/app/api/users/route.ts +71 -0
- package/apps/agents-server/src/app/globals.css +35 -1
- package/apps/agents-server/src/app/layout.tsx +43 -23
- package/apps/agents-server/src/app/metadata/MetadataClient.tsx +271 -0
- package/apps/agents-server/src/app/metadata/page.tsx +13 -0
- package/apps/agents-server/src/app/not-found.tsx +5 -0
- package/apps/agents-server/src/app/page.tsx +84 -46
- package/apps/agents-server/src/components/Auth/AuthControls.tsx +123 -0
- package/apps/agents-server/src/components/ErrorPage/ErrorPage.tsx +33 -0
- package/apps/agents-server/src/components/ForbiddenPage/ForbiddenPage.tsx +15 -0
- package/apps/agents-server/src/components/Header/Header.tsx +146 -0
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +27 -0
- package/apps/agents-server/src/components/LoginDialog/LoginDialog.tsx +40 -0
- package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +109 -0
- package/apps/agents-server/src/components/NotFoundPage/NotFoundPage.tsx +17 -0
- package/apps/agents-server/src/components/UsersList/UsersList.tsx +190 -0
- package/apps/agents-server/src/components/VercelDeploymentCard/VercelDeploymentCard.tsx +60 -0
- package/apps/agents-server/src/database/$getTableName.ts +18 -0
- package/apps/agents-server/src/database/$provideSupabase.ts +29 -0
- package/apps/agents-server/src/{supabase/getSupabaseForBrowser.ts → database/$provideSupabaseForBrowser.ts} +9 -5
- package/apps/agents-server/src/{supabase/getSupabaseForServer.ts → database/$provideSupabaseForServer.ts} +7 -7
- package/apps/agents-server/src/{supabase/getSupabaseForWorker.ts → database/$provideSupabaseForWorker.ts} +5 -4
- package/apps/agents-server/src/database/getMetadata.ts +31 -0
- package/apps/agents-server/src/database/metadataDefaults.ts +32 -0
- package/apps/agents-server/src/database/schema.sql +179 -0
- package/apps/agents-server/src/database/schema.ts +251 -0
- package/apps/agents-server/src/middleware.ts +162 -0
- package/apps/agents-server/src/tools/$provideAgentCollectionForServer.ts +14 -10
- package/apps/agents-server/src/tools/$provideCdnForServer.ts +1 -1
- package/apps/agents-server/src/tools/$provideExecutionToolsForServer.ts +11 -13
- package/apps/agents-server/src/tools/$provideOpenAiAssistantExecutionToolsForServer.ts +7 -7
- package/apps/agents-server/src/tools/$provideServer.ts +39 -0
- package/apps/agents-server/src/utils/auth.ts +33 -0
- package/apps/agents-server/src/utils/cdn/utils/getUserFileCdnKey.ts +2 -1
- package/apps/agents-server/src/utils/cdn/utils/nameToSubfolderPath.ts +1 -1
- package/apps/agents-server/src/utils/getCurrentUser.ts +32 -0
- package/apps/agents-server/src/utils/isIpAllowed.ts +101 -0
- package/apps/agents-server/src/utils/isUserAdmin.ts +31 -0
- package/apps/agents-server/src/utils/session.ts +50 -0
- package/apps/agents-server/tailwind.config.ts +2 -0
- package/esm/index.es.js +310 -49
- package/esm/index.es.js.map +1 -1
- package/esm/typings/servers.d.ts +1 -0
- package/esm/typings/src/_packages/core.index.d.ts +6 -0
- package/esm/typings/src/_packages/types.index.d.ts +4 -0
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +17 -3
- package/esm/typings/src/book-2.0/agent-source/AgentSourceParseResult.d.ts +2 -1
- package/esm/typings/src/book-2.0/agent-source/computeAgentHash.d.ts +8 -0
- package/esm/typings/src/book-2.0/agent-source/computeAgentHash.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/createDefaultAgentName.d.ts +8 -0
- package/esm/typings/src/book-2.0/agent-source/normalizeAgentName.d.ts +9 -0
- package/esm/typings/src/book-2.0/agent-source/normalizeAgentName.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/agent-source/parseAgentSourceWithCommitments.d.ts +1 -1
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +14 -8
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabaseOptions.d.ts +10 -0
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +57 -32
- package/esm/typings/src/commitments/MESSAGE/InitialMessageCommitmentDefinition.d.ts +28 -0
- package/esm/typings/src/commitments/index.d.ts +2 -1
- package/esm/typings/src/config.d.ts +1 -0
- package/esm/typings/src/errors/DatabaseError.d.ts +2 -2
- package/esm/typings/src/errors/WrappedError.d.ts +2 -2
- package/esm/typings/src/execution/ExecutionTask.d.ts +2 -2
- package/esm/typings/src/execution/LlmExecutionTools.d.ts +6 -1
- package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizardOrCli.d.ts +2 -2
- package/esm/typings/src/llm-providers/_common/utils/assertUniqueModels.d.ts +12 -0
- package/esm/typings/src/llm-providers/agent/Agent.d.ts +17 -4
- package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +10 -1
- package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +6 -2
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +30 -4
- package/esm/typings/src/llm-providers/openai/openai-models.test.d.ts +4 -0
- package/esm/typings/src/remote-server/startAgentServer.d.ts +2 -2
- package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -2
- package/esm/typings/src/transpilers/openai-sdk/register.d.ts +1 -1
- package/esm/typings/src/types/typeAliases.d.ts +6 -0
- package/esm/typings/src/utils/color/Color.d.ts +7 -0
- package/esm/typings/src/utils/color/Color.test.d.ts +1 -0
- package/esm/typings/src/utils/environment/$getGlobalScope.d.ts +2 -2
- package/esm/typings/src/utils/misc/computeHash.d.ts +11 -0
- package/esm/typings/src/utils/misc/computeHash.test.d.ts +1 -0
- package/esm/typings/src/utils/normalization/normalize-to-kebab-case.d.ts +2 -0
- package/esm/typings/src/utils/normalization/normalizeTo_PascalCase.d.ts +3 -0
- package/esm/typings/src/utils/normalization/normalizeTo_camelCase.d.ts +2 -0
- package/esm/typings/src/utils/normalization/titleToName.d.ts +2 -0
- package/esm/typings/src/utils/organization/$sideEffect.d.ts +2 -2
- package/esm/typings/src/utils/organization/$side_effect.d.ts +2 -2
- package/esm/typings/src/utils/organization/TODO_USE.d.ts +2 -2
- package/esm/typings/src/utils/organization/keepUnused.d.ts +2 -2
- package/esm/typings/src/utils/organization/preserve.d.ts +3 -3
- package/esm/typings/src/utils/organization/really_any.d.ts +7 -0
- package/esm/typings/src/utils/serialization/asSerializable.d.ts +2 -2
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +311 -50
- package/umd/index.umd.js.map +1 -1
- package/apps/agents-server/config.ts.todo +0 -312
- package/apps/agents-server/src/supabase/TODO.txt +0 -1
- package/apps/agents-server/src/supabase/getSupabase.ts +0 -25
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cookies } from 'next/headers';
|
|
2
|
+
import { getSession } from './session';
|
|
3
|
+
|
|
4
|
+
export type UserInfo = {
|
|
5
|
+
username: string;
|
|
6
|
+
isAdmin: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export async function getCurrentUser(): Promise<UserInfo | null> {
|
|
10
|
+
// Check session
|
|
11
|
+
const session = await getSession();
|
|
12
|
+
if (session) {
|
|
13
|
+
return {
|
|
14
|
+
username: session.username,
|
|
15
|
+
isAdmin: session.isAdmin
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Check legacy admin token
|
|
20
|
+
if (process.env.ADMIN_PASSWORD) {
|
|
21
|
+
const cookieStore = await cookies();
|
|
22
|
+
const adminToken = cookieStore.get('adminToken');
|
|
23
|
+
if (adminToken?.value === process.env.ADMIN_PASSWORD) {
|
|
24
|
+
return {
|
|
25
|
+
username: 'admin',
|
|
26
|
+
isAdmin: true
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { isIPv4, isIPv6 } from 'net';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the IP address is allowed based on the allowed IPs list
|
|
5
|
+
*
|
|
6
|
+
* @param clientIp - The IP address of the client
|
|
7
|
+
* @param allowedIps - Comma separated list of allowed IPs or CIDR ranges
|
|
8
|
+
* @returns true if the IP is allowed, false otherwise
|
|
9
|
+
*/
|
|
10
|
+
export function isIpAllowed(clientIp: string, allowedIps: string | null | undefined): boolean {
|
|
11
|
+
if (!allowedIps || allowedIps.trim() === '') {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const allowedList = allowedIps.split(',').map((ip) => ip.trim());
|
|
16
|
+
|
|
17
|
+
for (const allowed of allowedList) {
|
|
18
|
+
if (allowed === '') {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (allowed.includes('/')) {
|
|
23
|
+
// CIDR
|
|
24
|
+
if (isIpInCidr(clientIp, allowed)) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
// Single IP
|
|
29
|
+
if (clientIp === allowed) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isIpInCidr(ip: string, cidr: string): boolean {
|
|
39
|
+
try {
|
|
40
|
+
const [range, bitsStr] = cidr.split('/');
|
|
41
|
+
const bits = parseInt(bitsStr, 10);
|
|
42
|
+
|
|
43
|
+
if (isIPv4(ip) && isIPv4(range)) {
|
|
44
|
+
return isIPv4InCidr(ip, range, bits);
|
|
45
|
+
} else if (isIPv6(ip) && isIPv6(range)) {
|
|
46
|
+
return isIPv6InCidr(ip, range, bits);
|
|
47
|
+
} else if (isIPv6(ip) && isIPv4(range)) {
|
|
48
|
+
// Check if IPv6 is IPv4-mapped
|
|
49
|
+
if (ip.startsWith('::ffff:')) {
|
|
50
|
+
return isIPv4InCidr(ip.substring(7), range, bits);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error(`Error checking CIDR ${cidr} for IP ${ip}:`, error);
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function ipToLong(ip: string): number {
|
|
60
|
+
return (
|
|
61
|
+
ip.split('.').reduce((acc, octet) => {
|
|
62
|
+
return (acc << 8) + parseInt(octet, 10);
|
|
63
|
+
}, 0) >>> 0
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isIPv4InCidr(ip: string, range: string, bits: number): boolean {
|
|
68
|
+
const mask = ~((1 << (32 - bits)) - 1);
|
|
69
|
+
const ipLong = ipToLong(ip);
|
|
70
|
+
const rangeLong = ipToLong(range);
|
|
71
|
+
|
|
72
|
+
return (ipLong & mask) === (rangeLong & mask);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function parseIPv6(ip: string): bigint {
|
|
76
|
+
// Expand ::
|
|
77
|
+
let fullIp = ip;
|
|
78
|
+
if (ip.includes('::')) {
|
|
79
|
+
const parts = ip.split('::');
|
|
80
|
+
const left = parts[0].split(':').filter(Boolean);
|
|
81
|
+
const right = parts[1].split(':').filter(Boolean);
|
|
82
|
+
const missing = 8 - (left.length + right.length);
|
|
83
|
+
const zeros = Array(missing).fill('0');
|
|
84
|
+
fullIp = [...left, ...zeros, ...right].join(':');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const parts = fullIp.split(':');
|
|
88
|
+
let value = BigInt(0);
|
|
89
|
+
for (const part of parts) {
|
|
90
|
+
value = (value << BigInt(16)) + BigInt(parseInt(part || '0', 16));
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isIPv6InCidr(ip: string, range: string, bits: number): boolean {
|
|
96
|
+
const ipBigInt = parseIPv6(ip);
|
|
97
|
+
const rangeBigInt = parseIPv6(range);
|
|
98
|
+
const mask = (BigInt(1) << BigInt(128)) - BigInt(1) ^ ((BigInt(1) << BigInt(128 - bits)) - BigInt(1));
|
|
99
|
+
|
|
100
|
+
return (ipBigInt & mask) === (rangeBigInt & mask);
|
|
101
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { cookies } from 'next/headers';
|
|
2
|
+
import { getSession } from './session';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks if the current user is an admin
|
|
6
|
+
*
|
|
7
|
+
* Note: If `process.env.ADMIN_PASSWORD` is not set, everyone is admin
|
|
8
|
+
*
|
|
9
|
+
* @returns true if the user is admin
|
|
10
|
+
*/
|
|
11
|
+
export async function isUserAdmin(): Promise<boolean> {
|
|
12
|
+
if (!process.env.ADMIN_PASSWORD) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Check legacy admin token
|
|
17
|
+
const cookieStore = await cookies();
|
|
18
|
+
const adminToken = cookieStore.get('adminToken');
|
|
19
|
+
|
|
20
|
+
if (adminToken?.value === process.env.ADMIN_PASSWORD) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check session
|
|
25
|
+
const session = await getSession();
|
|
26
|
+
if (session?.isAdmin) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createHmac } from 'crypto';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
3
|
+
|
|
4
|
+
const SESSION_COOKIE_NAME = 'sessionToken';
|
|
5
|
+
const SECRET_KEY = process.env.ADMIN_PASSWORD || 'default-secret-key-change-me';
|
|
6
|
+
|
|
7
|
+
type SessionUser = {
|
|
8
|
+
username: string;
|
|
9
|
+
isAdmin: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export async function setSession(user: SessionUser) {
|
|
13
|
+
const payload = JSON.stringify(user);
|
|
14
|
+
const signature = createHmac('sha256', SECRET_KEY).update(payload).digest('hex');
|
|
15
|
+
const token = `${Buffer.from(payload).toString('base64')}.${signature}`;
|
|
16
|
+
|
|
17
|
+
(await cookies()).set(SESSION_COOKIE_NAME, token, {
|
|
18
|
+
httpOnly: true,
|
|
19
|
+
secure: process.env.NODE_ENV === 'production',
|
|
20
|
+
path: '/',
|
|
21
|
+
maxAge: 60 * 60 * 24 * 7, // 1 week
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function clearSession() {
|
|
26
|
+
(await cookies()).delete(SESSION_COOKIE_NAME);
|
|
27
|
+
// Also clear legacy adminToken
|
|
28
|
+
(await cookies()).delete('adminToken');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function getSession(): Promise<SessionUser | null> {
|
|
32
|
+
const cookieStore = await cookies();
|
|
33
|
+
const token = cookieStore.get(SESSION_COOKIE_NAME)?.value;
|
|
34
|
+
|
|
35
|
+
if (!token) return null;
|
|
36
|
+
|
|
37
|
+
const [payloadBase64, signature] = token.split('.');
|
|
38
|
+
if (!payloadBase64 || !signature) return null;
|
|
39
|
+
|
|
40
|
+
const payload = Buffer.from(payloadBase64, 'base64').toString('utf-8');
|
|
41
|
+
const expectedSignature = createHmac('sha256', SECRET_KEY).update(payload).digest('hex');
|
|
42
|
+
|
|
43
|
+
if (signature !== expectedSignature) return null;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(payload) as SessionUser;
|
|
47
|
+
} catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|