veryfront 0.1.613 → 0.1.615
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/esm/cli/templates/index.d.ts.map +1 -1
- package/esm/cli/templates/index.js +2 -9
- package/esm/cli/templates/manifest.d.ts +2 -0
- package/esm/cli/templates/manifest.js +8 -6
- package/esm/cli/templates/types.d.ts +1 -0
- package/esm/cli/templates/types.d.ts.map +1 -1
- package/esm/cli/templates/types.js +9 -1
- package/esm/deno.js +6 -6
- package/esm/src/build/bundler/code-splitter/build-context.d.ts.map +1 -1
- package/esm/src/build/bundler/code-splitter/build-context.js +1 -0
- package/esm/src/chat/message-prep.d.ts.map +1 -1
- package/esm/src/chat/message-prep.js +16 -2
- package/esm/src/html/utils.d.ts.map +1 -1
- package/esm/src/html/utils.js +11 -6
- package/esm/src/integrations/_data.js +1 -1
- package/esm/src/integrations/_tool_summaries.d.ts.map +1 -1
- package/esm/src/integrations/_tool_summaries.js +197 -4
- package/esm/src/integrations/schema.d.ts +8 -0
- package/esm/src/integrations/schema.d.ts.map +1 -1
- package/esm/src/integrations/schema.js +2 -1
- package/esm/src/server/handlers/request/lib-modules.handler.d.ts +6 -0
- package/esm/src/server/handlers/request/lib-modules.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/lib-modules.handler.js +11 -4
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/esm/src/workflow/react/use-workflow-list.js +1 -2
- package/esm/src/workflow/react/use-workflow.js +1 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,GACb,CAAC;AAEF,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CAOzE,CAAC;AAIF,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,CAmBpF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,IAAI,CAE3E"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* to inline string templates.
|
|
7
7
|
*/
|
|
8
8
|
import { loadTemplateFromDirectory, templateDirectoryExists } from "./loader.js";
|
|
9
|
+
import { STARTER_TEMPLATE_NAMES } from "./types.js";
|
|
9
10
|
export { AVAILABLE_FEATURES, featureExists, loadFeature, loadFeatureConfig, mergeConfig, mergeDependencies, mergeFiles, resolveFeatures, validateFeatures, } from "./feature-loader.js";
|
|
10
11
|
export const templateConfigs = {
|
|
11
12
|
"docs-agent": {
|
|
@@ -15,15 +16,7 @@ export const templateConfigs = {
|
|
|
15
16
|
},
|
|
16
17
|
},
|
|
17
18
|
};
|
|
18
|
-
const DIRECTORY_BASED_TEMPLATES = [
|
|
19
|
-
"ai-agent",
|
|
20
|
-
"docs-agent",
|
|
21
|
-
"multi-agent-system",
|
|
22
|
-
"agentic-workflow",
|
|
23
|
-
"coding-agent",
|
|
24
|
-
"saas-starter",
|
|
25
|
-
"minimal",
|
|
26
|
-
];
|
|
19
|
+
const DIRECTORY_BASED_TEMPLATES = [...STARTER_TEMPLATE_NAMES];
|
|
27
20
|
export async function getTemplate(name) {
|
|
28
21
|
if (name === "pages-router" || name === "app-router") {
|
|
29
22
|
return getTemplate("ai-agent");
|
|
@@ -262,10 +262,12 @@ declare namespace _default {
|
|
|
262
262
|
"tools/add-issue-comment.ts": string;
|
|
263
263
|
"tools/create-issue.ts": string;
|
|
264
264
|
"tools/create-pr.ts": string;
|
|
265
|
+
"tools/get-current-user.ts": string;
|
|
265
266
|
"tools/get-issue.ts": string;
|
|
266
267
|
"tools/get-pr-diff.ts": string;
|
|
267
268
|
"tools/get-pr.ts": string;
|
|
268
269
|
"tools/get-repo.ts": string;
|
|
270
|
+
"tools/get-user.ts": string;
|
|
269
271
|
"tools/list-commits.ts": string;
|
|
270
272
|
"tools/list-issues.ts": string;
|
|
271
273
|
"tools/list-prs.ts": string;
|
|
@@ -5,13 +5,13 @@ export default {
|
|
|
5
5
|
"files": {
|
|
6
6
|
"agents/researcher.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"researcher\",\n system:\n \"You research topics thoroughly and return structured findings. \" +\n \"Present results as clear bullet points with key facts, data, and sources.\",\n maxSteps: 3,\n});\n",
|
|
7
7
|
"agents/writer.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"writer\",\n system:\n \"You transform research notes into polished, publication-ready content. \" +\n \"Use a professional but approachable tone.\",\n maxSteps: 3,\n});\n",
|
|
8
|
-
"app/api/workflows/[workflowId]/start/route.ts": "
|
|
8
|
+
"app/api/workflows/[workflowId]/start/route.ts": "import { startDemoWorkflowRun } from \"../../sample-runs.ts\";\n\nexport async function POST(\n request: Request,\n context: { params: Record<string, string> },\n): Promise<Response> {\n const body = await request.json().catch(() => ({})) as {\n input?: { topic?: string };\n };\n const run = startDemoWorkflowRun(context.params.workflowId, body.input);\n\n return Response.json({\n success: true,\n runId: run.id,\n id: run.id,\n workflowId: run.workflowId,\n status: run.status,\n input: run.input,\n createdAt: run.createdAt,\n });\n}\n",
|
|
9
9
|
"app/api/workflows/runs/[id]/approvals/[approvalId]/route.ts": "export function POST(): Response {\n return Response.json({ success: true });\n}\n",
|
|
10
|
-
"app/api/workflows/runs/[id]/route.ts": "import {
|
|
11
|
-
"app/api/workflows/runs/route.ts": "import {
|
|
12
|
-
"app/api/workflows/sample-runs.ts": "export interface DemoWorkflowStep {\n id: string;\n name: string;\n status: \"pending\" | \"running\" | \"completed\" | \"waiting_for_approval\" | \"failed\";\n output?: string | Record<string, unknown>;\n}\n\nexport interface DemoWorkflowRun {\n id: string;\n workflowId: string;\n status: \"pending\" | \"running\" | \"completed\" | \"waiting_for_approval\" | \"failed\";\n input: { topic: string };\n createdAt: string;\n currentNodes: string[];\n nodeStates: Record<string, { status: DemoWorkflowStep[\"status\"] }>;\n pendingApprovals: Array<{ id: string; status: \"pending\" | \"approved\" | \"rejected\" }>;\n steps: DemoWorkflowStep[];\n}\n\nexport function createDemoWorkflowRun(\n id = \"test-run\",\n topic = \"Example content pipeline\",\n): DemoWorkflowRun {\n return {\n id,\n workflowId
|
|
10
|
+
"app/api/workflows/runs/[id]/route.ts": "import { getDemoWorkflowRun } from \"../../sample-runs.ts\";\n\nexport function GET(\n _request: Request,\n context: { params: Record<string, string> },\n): Response {\n return Response.json(getDemoWorkflowRun(context.params.id));\n}\n",
|
|
11
|
+
"app/api/workflows/runs/route.ts": "import { listDemoWorkflowRuns } from \"../sample-runs.ts\";\n\nexport function GET(request: Request): Response {\n const url = new URL(request.url);\n const workflowId = url.searchParams.get(\"workflowId\");\n const limit = Number(url.searchParams.get(\"limit\") ?? \"20\");\n\n const runs = listDemoWorkflowRuns({ workflowId, limit });\n\n return Response.json({\n runs,\n totalCount: runs.length,\n });\n}\n",
|
|
12
|
+
"app/api/workflows/sample-runs.ts": "export interface DemoWorkflowStep {\n id: string;\n name: string;\n status: \"pending\" | \"running\" | \"completed\" | \"waiting_for_approval\" | \"failed\";\n output?: string | Record<string, unknown>;\n}\n\nexport interface DemoWorkflowRun {\n id: string;\n workflowId: string;\n status: \"pending\" | \"running\" | \"completed\" | \"waiting_for_approval\" | \"failed\";\n input: { topic: string };\n createdAt: string;\n currentNodes: string[];\n nodeStates: Record<string, { status: DemoWorkflowStep[\"status\"] }>;\n pendingApprovals: Array<{ id: string; status: \"pending\" | \"approved\" | \"rejected\" }>;\n steps: DemoWorkflowStep[];\n}\n\nconst globalStore = globalThis as typeof globalThis & {\n __veryfrontAgenticWorkflowDemoRuns?: Map<string, DemoWorkflowRun>;\n};\nconst demoRuns = globalStore.__veryfrontAgenticWorkflowDemoRuns ??= new Map<\n string,\n DemoWorkflowRun\n>();\n\nexport function createDemoWorkflowRun(\n id = \"test-run\",\n topic = \"Example content pipeline\",\n workflowId = \"content-pipeline\",\n): DemoWorkflowRun {\n return {\n id,\n workflowId,\n status: \"completed\",\n input: { topic },\n createdAt: new Date().toISOString(),\n currentNodes: [],\n nodeStates: {\n research: { status: \"completed\" },\n \"write-article\": { status: \"completed\" },\n \"editorial-review\": { status: \"completed\" },\n publish: { status: \"completed\" },\n },\n pendingApprovals: [],\n steps: [\n {\n id: \"research\",\n name: \"Research\",\n status: \"completed\",\n output: \"Found key points and source material.\",\n },\n {\n id: \"write-article\",\n name: \"Write article\",\n status: \"completed\",\n output: \"Drafted a concise article from the research notes.\",\n },\n {\n id: \"editorial-review\",\n name: \"Editorial review\",\n status: \"completed\",\n },\n {\n id: \"publish\",\n name: \"Publish\",\n status: \"completed\",\n output: { published: true },\n },\n ],\n };\n}\n\nexport function getDemoWorkflowRun(id: string): DemoWorkflowRun {\n return demoRuns.get(id) ?? createDemoWorkflowRun(id);\n}\n\nexport function listDemoWorkflowRuns(options: {\n workflowId?: string | null;\n limit?: number;\n} = {}): DemoWorkflowRun[] {\n if (!demoRuns.has(\"test-run\")) {\n demoRuns.set(\"test-run\", createDemoWorkflowRun());\n }\n\n const limit = Number.isFinite(options.limit) && options.limit && options.limit > 0\n ? options.limit\n : 20;\n\n return Array.from(demoRuns.values())\n .filter((run) => !options.workflowId || run.workflowId === options.workflowId)\n .sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt))\n .slice(0, limit);\n}\n\nexport function startDemoWorkflowRun(\n workflowId: string,\n input: { topic?: string } = {},\n): DemoWorkflowRun {\n const runId = `run-${Date.now()}`;\n const topic = input.topic?.trim() || \"Untitled workflow\";\n const run = createDemoWorkflowRun(runId, topic, workflowId);\n\n demoRuns.set(run.id, run);\n return run;\n}\n",
|
|
13
13
|
"app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>AI Workflows</title>\n </Head>\n {children}\n </>\n );\n}\n",
|
|
14
|
-
"app/page.tsx": "'use client'\n\nimport { useState } from 'react'\nimport { useWorkflowStart, useWorkflowList } from 'veryfront/workflow'\n\nconst STATUS_STYLES: Record<string, string> = {\n running: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n completed: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400',\n waiting_for_approval: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n pending: 'bg-neutral-100 text-neutral-600 dark:bg-neutral-800 dark:text-neutral-400',\n}\n\nexport default function WorkflowDashboard(): JSX.Element {\n const [topic, setTopic] = useState('')\n const { start, isStarting } = useWorkflowStart({ workflowId: 'content-pipeline' })\n const { runs, isLoading } = useWorkflowList()\n\n async function handleStart(e: React.FormEvent) {\n e.preventDefault()\n if (!topic.trim()) return\n await start({ topic: topic.trim() })\n setTopic('')\n }\n\n return (\n <div className=\"min-h-screen bg-neutral-50 dark:bg-neutral-950\">\n <div className=\"max-w-2xl mx-auto px-4 py-12\">\n <div className=\"mb-10\">\n <h1 className=\"text-2xl font-bold text-neutral-900 dark:text-white\">Content Pipeline</h1>\n <p className=\"mt-1 text-neutral-500 dark:text-neutral-400\">Research → Write → Review → Publish</p>\n </div>\n\n {/* Start new workflow */}\n <form onSubmit={handleStart} className=\"mb-10\">\n <div className=\"flex gap-3\">\n <input\n type=\"text\"\n value={topic}\n onChange={(e) => setTopic(e.target.value)}\n placeholder=\"Enter a topic to research and write about...\"\n className=\"flex-1 px-4 py-2.5 bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl text-neutral-900 dark:text-white placeholder-neutral-400 focus:outline-none focus:ring-2 focus:ring-blue-500/30 focus:border-blue-500\"\n />\n <button\n type=\"submit\"\n disabled={isStarting || !topic.trim()}\n className=\"px-5 py-2.5 bg-blue-500 text-white font-medium rounded-xl hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isStarting ? 'Starting...' : 'Start'}\n </button>\n </div>\n </form>\n\n {/* Workflow runs */}\n <div>\n <h2 className=\"text-sm font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-4\">Recent Runs</h2>\n\n {isLoading ? (\n <p className=\"text-neutral-400 text-sm py-8 text-center\">Loading...</p>\n ) : runs.length === 0 ? (\n <div className=\"text-center py-12 bg-white dark:bg-neutral-900 rounded-2xl border border-neutral-200 dark:border-neutral-800\">\n <p className=\"text-neutral-500 dark:text-neutral-400\">No workflows yet. Start one above.</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {runs.map((wf) => (\n <a\n key={wf.id}\n href={`/workflows/${wf.id}`}\n className=\"block bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 hover:border-neutral-300 dark:hover:border-neutral-700 transition-colors\"\n >\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium text-neutral-900 dark:text-white text-sm\">{wf.input?.topic || 'Untitled'}</p>\n <p className=\"text-xs text-neutral-500 mt-1\">{new Date(wf.createdAt).toLocaleString()}</p>\n </div>\n <span className={`px-2.5 py-1 rounded-full text-xs font-medium ${STATUS_STYLES[wf.status] || STATUS_STYLES.pending}`}>\n {wf.status.replace(/_/g, ' ')}\n </span>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n",
|
|
14
|
+
"app/page.tsx": "'use client'\n\nimport { useState } from 'react'\nimport { useWorkflowStart, useWorkflowList } from 'veryfront/workflow'\n\nconst STATUS_STYLES: Record<string, string> = {\n running: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n completed: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400',\n waiting_for_approval: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',\n failed: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n pending: 'bg-neutral-100 text-neutral-600 dark:bg-neutral-800 dark:text-neutral-400',\n}\n\nexport default function WorkflowDashboard(): JSX.Element {\n const [topic, setTopic] = useState('')\n const { start, isStarting } = useWorkflowStart({ workflowId: 'content-pipeline' })\n const { runs, isLoading, refresh } = useWorkflowList()\n\n async function handleStart(e: React.FormEvent) {\n e.preventDefault()\n if (!topic.trim()) return\n await start({ topic: topic.trim() })\n setTopic('')\n await refresh()\n }\n\n return (\n <div className=\"min-h-screen bg-neutral-50 dark:bg-neutral-950\">\n <div className=\"max-w-2xl mx-auto px-4 py-12\">\n <div className=\"mb-10\">\n <h1 className=\"text-2xl font-bold text-neutral-900 dark:text-white\">Content Pipeline</h1>\n <p className=\"mt-1 text-neutral-500 dark:text-neutral-400\">Research → Write → Review → Publish</p>\n </div>\n\n {/* Start new workflow */}\n <form onSubmit={handleStart} className=\"mb-10\">\n <div className=\"flex gap-3\">\n <input\n type=\"text\"\n value={topic}\n onChange={(e) => setTopic(e.target.value)}\n placeholder=\"Enter a topic to research and write about...\"\n className=\"flex-1 px-4 py-2.5 bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl text-neutral-900 dark:text-white placeholder-neutral-400 focus:outline-none focus:ring-2 focus:ring-blue-500/30 focus:border-blue-500\"\n />\n <button\n type=\"submit\"\n disabled={isStarting || !topic.trim()}\n className=\"px-5 py-2.5 bg-blue-500 text-white font-medium rounded-xl hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n {isStarting ? 'Starting...' : 'Start'}\n </button>\n </div>\n </form>\n\n {/* Workflow runs */}\n <div>\n <h2 className=\"text-sm font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-4\">Recent Runs</h2>\n\n {isLoading ? (\n <p className=\"text-neutral-400 text-sm py-8 text-center\">Loading...</p>\n ) : runs.length === 0 ? (\n <div className=\"text-center py-12 bg-white dark:bg-neutral-900 rounded-2xl border border-neutral-200 dark:border-neutral-800\">\n <p className=\"text-neutral-500 dark:text-neutral-400\">No workflows yet. Start one above.</p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {runs.map((wf) => (\n <a\n key={wf.id}\n href={`/workflows/${wf.id}`}\n className=\"block bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl p-4 hover:border-neutral-300 dark:hover:border-neutral-700 transition-colors\"\n >\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium text-neutral-900 dark:text-white text-sm\">{wf.input?.topic || 'Untitled'}</p>\n <p className=\"text-xs text-neutral-500 mt-1\">{new Date(wf.createdAt).toLocaleString()}</p>\n </div>\n <span className={`px-2.5 py-1 rounded-full text-xs font-medium ${STATUS_STYLES[wf.status] || STATUS_STYLES.pending}`}>\n {wf.status.replace(/_/g, ' ')}\n </span>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n",
|
|
15
15
|
"app/workflows/[id]/page.tsx": "'use client'\n\nimport { useState } from 'react'\nimport { usePageContext } from 'veryfront/context'\nimport { useWorkflow } from 'veryfront/workflow'\n\nconst STEP_ICONS: Record<string, string> = {\n completed: '\\u2713',\n running: '\\u25C9',\n pending: '\\u25CB',\n waiting_for_approval: '\\u23F8',\n failed: '\\u2717',\n}\n\nexport default function WorkflowDetail(): JSX.Element {\n const { params } = usePageContext()\n const { run, pendingApprovals, isLoading, refresh } = useWorkflow({ runId: params.id })\n const [isSubmitting, setIsSubmitting] = useState(false)\n\n async function handleApproval(approvalId: string, approved: boolean) {\n setIsSubmitting(true)\n try {\n await fetch(`/api/workflows/runs/${params.id}/approvals/${approvalId}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ approved, approver: 'user' }),\n })\n await refresh()\n } finally {\n setIsSubmitting(false)\n }\n }\n\n if (isLoading) {\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-neutral-50 dark:bg-neutral-950\">\n <p className=\"text-neutral-400\">Loading workflow...</p>\n </div>\n )\n }\n\n if (!run) {\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-neutral-50 dark:bg-neutral-950\">\n <p className=\"text-neutral-400\">Workflow not found</p>\n </div>\n )\n }\n\n return (\n <div className=\"min-h-screen bg-neutral-50 dark:bg-neutral-950\">\n <div className=\"max-w-2xl mx-auto px-4 py-12\">\n <a href=\"/\" className=\"text-sm text-neutral-500 hover:text-neutral-700 dark:hover:text-neutral-300 mb-6 inline-block\">← Back</a>\n\n <h1 className=\"text-2xl font-bold text-neutral-900 dark:text-white mb-1\">{run.input?.topic || 'Workflow'}</h1>\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400 mb-8\">Started {new Date(run.createdAt).toLocaleString()}</p>\n\n {/* Steps */}\n <div className=\"space-y-4 mb-8\">\n {run.steps?.map((step: any) => (\n <div key={step.id} className=\"flex items-start gap-3 bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-xl p-4\">\n <span className=\"text-lg mt-0.5\">{STEP_ICONS[step.status] || '\\u25CB'}</span>\n <div className=\"flex-1\">\n <p className=\"font-medium text-neutral-900 dark:text-white text-sm\">{step.name}</p>\n {step.output && (\n <p className=\"text-xs text-neutral-500 mt-1 line-clamp-2\">{typeof step.output === 'string' ? step.output : JSON.stringify(step.output)}</p>\n )}\n </div>\n <span className=\"text-xs text-neutral-400\">{step.status}</span>\n </div>\n ))}\n </div>\n\n {/* Approval */}\n {pendingApprovals.length > 0 && (\n <div className=\"bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-xl p-6\">\n <h2 className=\"font-medium text-amber-900 dark:text-amber-200 mb-2\">Approval Required</h2>\n <p className=\"text-sm text-amber-700 dark:text-amber-300 mb-4\">Review the draft before publishing.</p>\n <div className=\"flex gap-3\">\n <button\n onClick={() => handleApproval(pendingApprovals[0].id, true)}\n disabled={isSubmitting}\n className=\"px-4 py-2 bg-emerald-500 text-white font-medium rounded-lg hover:bg-emerald-600 disabled:opacity-50 transition-colors text-sm\"\n >\n Approve\n </button>\n <button\n onClick={() => handleApproval(pendingApprovals[0].id, false)}\n disabled={isSubmitting}\n className=\"px-4 py-2 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 text-neutral-700 dark:text-neutral-300 font-medium rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-700 disabled:opacity-50 transition-colors text-sm\"\n >\n Reject\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n",
|
|
16
16
|
"globals.css": "@import \"tailwindcss\";\n",
|
|
17
17
|
"README.md": "# Agentic Workflow\n\nOrchestrated multi-step processes with human approval gates.\n\n## What's included\n\n- Content pipeline workflow (research, write, review, publish)\n- Parallel step execution\n- Human-in-the-loop approval gates\n- Dashboard to start, monitor, and approve workflow runs\n\n## Structure\n\n```\nagents/\n researcher.ts Research agent\n writer.ts Writing agent\nworkflows/content-pipeline.ts Workflow definition\napp/\n api/workflows/ Demo workflow API routes\n page.tsx Workflow dashboard\n workflows/[id]/page.tsx Run detail and approval UI\n```\n\nThis starter is not production-ready.\n",
|
|
@@ -257,15 +257,17 @@ export default {
|
|
|
257
257
|
"files": {
|
|
258
258
|
"app/api/auth/github/callback/route.ts": "import { createOAuthCallbackHandler, githubConfig } from \"veryfront/oauth\";\nimport { tokenStore } from \"../../../../../lib/token-store.ts\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\n\nconst hybridTokenStore = {\n async getTokens(serviceId: string, userId: string) {\n return tokenStore.getToken(userId, serviceId);\n },\n async setTokens(\n serviceId: string,\n userId: string,\n tokens: { accessToken: string; refreshToken?: string; expiresAt?: number },\n ) {\n await tokenStore.setToken(userId, serviceId, tokens);\n },\n async clearTokens(serviceId: string, userId: string) {\n await tokenStore.revokeToken(userId, serviceId);\n },\n setState(\n state: string,\n meta: {\n userId: string;\n serviceId: string;\n codeVerifier?: string;\n redirectUri?: string;\n scopes?: string[];\n createdAt: number;\n },\n ) {\n return oauthMemoryTokenStore.setState(state, meta);\n },\n consumeState(state: string) {\n return oauthMemoryTokenStore.consumeState(state);\n },\n};\n\nexport const GET = createOAuthCallbackHandler(githubConfig, { tokenStore: hybridTokenStore });\n",
|
|
259
259
|
"app/api/auth/github/route.ts": "import { createOAuthInitHandler, githubConfig } from \"veryfront/oauth\";\nimport { oauthMemoryTokenStore } from \"../../../../../lib/oauth-memory-store.ts\";\nimport { requireUserIdFromRequest } from \"../../../../../lib/user-id.ts\";\n\nfunction getUserId(request: Request): string {\n return requireUserIdFromRequest(request);\n}\n\nexport const GET = createOAuthInitHandler(githubConfig, {\n tokenStore: oauthMemoryTokenStore,\n getUserId,\n});",
|
|
260
|
-
"lib/github-client.ts": "/**\n * GitHub API Client\n *\n * Provides a type-safe interface to GitHub API operations.\n */\n\nimport { getValidToken } from \"./oauth.ts\";\n\nfunction getEnv(key: string): string | undefined {\n // @ts-ignore - Deno global\n if (typeof Deno !== \"undefined\") return Deno.env.get(key);\n\n // @ts-ignore - process global\n if (typeof process !== \"undefined\" && process.env) return process.env[key];\n\n return undefined;\n}\n\nconst GITHUB_API_BASE = \"https://api.github.com\";\n\nexport interface GitHubRepo {\n id: number;\n name: string;\n full_name: string;\n description: string | null;\n private: boolean;\n html_url: string;\n default_branch: string;\n language: string | null;\n stargazers_count: number;\n forks_count: number;\n open_issues_count: number;\n updated_at: string;\n}\n\nexport interface GitHubPullRequest {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string; avatar_url: string };\n created_at: string;\n updated_at: string;\n head: { ref: string; sha: string };\n base: { ref: string };\n mergeable: boolean | null;\n additions: number;\n deletions: number;\n changed_files: number;\n draft: boolean;\n labels: Array<{ name: string; color: string }>;\n}\n\nexport interface GitHubIssue {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n labels: Array<{ name: string; color: string }>;\n assignees: Array<{ login: string }>;\n}\n\nexport interface GitHubCommit {\n sha: string;\n commit: {\n message: string;\n author: { name: string; date: string };\n };\n html_url: string;\n author: { login: string; avatar_url: string } | null;\n}\n\nexport interface GitHubMergeResult {\n sha: string;\n merged: boolean;\n message: string;\n}\n\n/**\n * GitHub OAuth provider configuration\n */\nexport const githubOAuthProvider = {\n name: \"github\",\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n tokenUrl: \"https://github.com/login/oauth/access_token\",\n clientId: getEnv(\"GITHUB_CLIENT_ID\") ?? \"\",\n clientSecret: getEnv(\"GITHUB_CLIENT_SECRET\") ?? \"\",\n scopes: [\"repo\", \"read:user\", \"read:org\"],\n callbackPath: \"/api/auth/github/callback\",\n};\n\nexport function createGitHubClient(userId: string): {\n listRepos(options?: {\n sort?: \"created\" | \"updated\" | \"pushed\" | \"full_name\";\n perPage?: number;\n type?: \"all\" | \"owner\" | \"public\" | \"private\" | \"member\";\n }): Promise<GitHubRepo[]>;\n getRepo(owner: string, repo: string): Promise<GitHubRepo>;\n listPullRequests(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubPullRequest[]>;\n getPullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<GitHubPullRequest>;\n getPullRequestDiff(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<string>;\n createIssue(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n getIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n ): Promise<GitHubIssue>;\n updateIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n options: {\n title?: string;\n body?: string;\n state?: \"open\" | \"closed\";\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n addIssueComment(\n owner: string,\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<\n {\n id: number;\n html_url: string;\n body: string;\n user: { login: string };\n created_at: string;\n }\n >;\n listIssues(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubIssue[]>;\n listCommits(\n owner: string,\n repo: string,\n options?: { sha?: string; path?: string; perPage?: number },\n ): Promise<GitHubCommit[]>;\n createPullRequest(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n head: string;\n base: string;\n draft?: boolean;\n },\n ): Promise<GitHubPullRequest>;\n mergePullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n options?: {\n commit_title?: string;\n commit_message?: string;\n merge_method?: \"merge\" | \"squash\" | \"rebase\";\n },\n ): Promise<GitHubMergeResult>;\n getUser(): Promise<{ login: string; name: string; email: string }>;\n} {\n async function getAccessToken(): Promise<string> {\n const token = await getValidToken(githubOAuthProvider, userId, \"github\");\n if (!token) {\n throw new Error(\n \"GitHub not connected. Please connect your GitHub account first.\",\n );\n }\n return token;\n }\n\n async function apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n ...options,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`GitHub API error: ${response.status} - ${error}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n async function apiTextRequest(\n endpoint: string,\n accept: string,\n ): Promise<string> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: accept,\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n },\n });\n\n if (!response.ok) throw new Error(`GitHub API error: ${response.status}`);\n\n return response.text();\n }\n\n function toQueryString(params: URLSearchParams): string {\n const query = params.toString();\n return query ? `?${query}` : \"\";\n }\n\n return {\n listRepos(options = {}): Promise<GitHubRepo[]> {\n const params = new URLSearchParams();\n if (options.sort) params.set(\"sort\", options.sort);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n if (options.type) params.set(\"type\", options.type);\n\n return apiRequest<GitHubRepo[]>(`/user/repos${toQueryString(params)}`);\n },\n\n getRepo(owner, repo): Promise<GitHubRepo> {\n return apiRequest<GitHubRepo>(`/repos/${owner}/${repo}`);\n },\n\n listPullRequests(owner, repo, options = {}): Promise<GitHubPullRequest[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubPullRequest[]>(\n `/repos/${owner}/${repo}/pulls${toQueryString(params)}`,\n );\n },\n\n getPullRequest(owner, repo, pullNumber): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n );\n },\n\n getPullRequestDiff(owner, repo, pullNumber): Promise<string> {\n return apiTextRequest(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n \"application/vnd.github.diff\",\n );\n },\n\n createIssue(owner, repo, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(`/repos/${owner}/${repo}/issues`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n getIssue(owner, repo, issueNumber): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n );\n },\n\n updateIssue(owner, repo, issueNumber, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(options),\n },\n );\n },\n\n addIssueComment(owner, repo, issueNumber, body) {\n return apiRequest(\n `/repos/${owner}/${repo}/issues/${issueNumber}/comments`,\n {\n method: \"POST\",\n body: JSON.stringify({ body }),\n },\n );\n },\n\n listIssues(owner, repo, options = {}): Promise<GitHubIssue[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubIssue[]>(\n `/repos/${owner}/${repo}/issues${toQueryString(params)}`,\n );\n },\n\n listCommits(owner, repo, options = {}): Promise<GitHubCommit[]> {\n const params = new URLSearchParams();\n if (options.sha) params.set(\"sha\", options.sha);\n if (options.path) params.set(\"path\", options.path);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubCommit[]>(\n `/repos/${owner}/${repo}/commits${toQueryString(params)}`,\n );\n },\n\n createPullRequest(owner, repo, options): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(`/repos/${owner}/${repo}/pulls`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n mergePullRequest(owner, repo, pullNumber, options = {}): Promise<GitHubMergeResult> {\n return apiRequest<GitHubMergeResult>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}/merge`,\n {\n method: \"PUT\",\n body: JSON.stringify(options),\n },\n );\n },\n\n getUser(): Promise<{ login: string; name: string; email: string }> {\n return apiRequest(\"/user\");\n },\n };\n}\n\nexport type GitHubClient = ReturnType<typeof createGitHubClient>;\n",
|
|
260
|
+
"lib/github-client.ts": "/**\n * GitHub API Client\n *\n * Provides a type-safe interface to GitHub API operations.\n */\n\nimport { getValidToken } from \"./oauth.ts\";\n\nfunction getEnv(key: string): string | undefined {\n // @ts-ignore - Deno global\n if (typeof Deno !== \"undefined\") return Deno.env.get(key);\n\n // @ts-ignore - process global\n if (typeof process !== \"undefined\" && process.env) return process.env[key];\n\n return undefined;\n}\n\nconst GITHUB_API_BASE = \"https://api.github.com\";\n\nexport interface GitHubUser {\n id: number;\n login: string;\n name: string | null;\n type: string;\n html_url: string;\n avatar_url: string;\n company: string | null;\n blog: string;\n location: string | null;\n email: string | null;\n bio: string | null;\n twitter_username: string | null;\n public_repos: number;\n followers: number;\n following: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GitHubRepo {\n id: number;\n name: string;\n full_name: string;\n description: string | null;\n private: boolean;\n html_url: string;\n default_branch: string;\n language: string | null;\n stargazers_count: number;\n forks_count: number;\n open_issues_count: number;\n updated_at: string;\n}\n\nexport interface GitHubPullRequest {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string; avatar_url: string };\n created_at: string;\n updated_at: string;\n head: { ref: string; sha: string };\n base: { ref: string };\n mergeable: boolean | null;\n additions: number;\n deletions: number;\n changed_files: number;\n draft: boolean;\n labels: Array<{ name: string; color: string }>;\n}\n\nexport interface GitHubIssue {\n id: number;\n number: number;\n title: string;\n body: string | null;\n state: \"open\" | \"closed\";\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n labels: Array<{ name: string; color: string }>;\n assignees: Array<{ login: string }>;\n}\n\nexport interface GitHubCommit {\n sha: string;\n commit: {\n message: string;\n author: { name: string; date: string };\n };\n html_url: string;\n author: { login: string; avatar_url: string } | null;\n}\n\nexport interface GitHubMergeResult {\n sha: string;\n merged: boolean;\n message: string;\n}\n\nexport interface GitHubUser {\n id: number;\n node_id: string;\n login: string;\n name: string | null;\n email: string | null;\n html_url: string;\n avatar_url: string;\n type: string;\n}\n\n/**\n * GitHub OAuth provider configuration\n */\nexport const githubOAuthProvider = {\n name: \"github\",\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n tokenUrl: \"https://github.com/login/oauth/access_token\",\n clientId: getEnv(\"GITHUB_CLIENT_ID\") ?? \"\",\n clientSecret: getEnv(\"GITHUB_CLIENT_SECRET\") ?? \"\",\n scopes: [\"repo\", \"read:user\", \"read:org\"],\n callbackPath: \"/api/auth/github/callback\",\n};\n\nexport function createGitHubClient(userId: string): {\n listRepos(options?: {\n sort?: \"created\" | \"updated\" | \"pushed\" | \"full_name\";\n perPage?: number;\n type?: \"all\" | \"owner\" | \"public\" | \"private\" | \"member\";\n }): Promise<GitHubRepo[]>;\n getRepo(owner: string, repo: string): Promise<GitHubRepo>;\n listPullRequests(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubPullRequest[]>;\n getPullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<GitHubPullRequest>;\n getPullRequestDiff(\n owner: string,\n repo: string,\n pullNumber: number,\n ): Promise<string>;\n createIssue(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n getIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n ): Promise<GitHubIssue>;\n updateIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n options: {\n title?: string;\n body?: string;\n state?: \"open\" | \"closed\";\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<GitHubIssue>;\n addIssueComment(\n owner: string,\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<\n {\n id: number;\n html_url: string;\n body: string;\n user: { login: string };\n created_at: string;\n }\n >;\n listIssues(\n owner: string,\n repo: string,\n options?: { state?: \"open\" | \"closed\" | \"all\"; perPage?: number },\n ): Promise<GitHubIssue[]>;\n listCommits(\n owner: string,\n repo: string,\n options?: { sha?: string; path?: string; perPage?: number },\n ): Promise<GitHubCommit[]>;\n createPullRequest(\n owner: string,\n repo: string,\n options: {\n title: string;\n body?: string;\n head: string;\n base: string;\n draft?: boolean;\n },\n ): Promise<GitHubPullRequest>;\n mergePullRequest(\n owner: string,\n repo: string,\n pullNumber: number,\n options?: {\n commit_title?: string;\n commit_message?: string;\n merge_method?: \"merge\" | \"squash\" | \"rebase\";\n },\n ): Promise<GitHubMergeResult>;\n getUser(): Promise<GitHubUser>;\n getUserByUsername(username: string): Promise<GitHubUser>;\n} {\n async function getAccessToken(): Promise<string> {\n const token = await getValidToken(githubOAuthProvider, userId, \"github\");\n if (!token) {\n throw new Error(\n \"GitHub not connected. Please connect your GitHub account first.\",\n );\n }\n return token;\n }\n\n async function apiRequest<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n ...options,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`GitHub API error: ${response.status} - ${error}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n async function apiTextRequest(\n endpoint: string,\n accept: string,\n ): Promise<string> {\n const accessToken = await getAccessToken();\n\n const response = await fetch(`${GITHUB_API_BASE}${endpoint}`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: accept,\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n },\n });\n\n if (!response.ok) throw new Error(`GitHub API error: ${response.status}`);\n\n return response.text();\n }\n\n function toQueryString(params: URLSearchParams): string {\n const query = params.toString();\n return query ? `?${query}` : \"\";\n }\n\n return {\n listRepos(options = {}): Promise<GitHubRepo[]> {\n const params = new URLSearchParams();\n if (options.sort) params.set(\"sort\", options.sort);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n if (options.type) params.set(\"type\", options.type);\n\n return apiRequest<GitHubRepo[]>(`/user/repos${toQueryString(params)}`);\n },\n\n getRepo(owner, repo): Promise<GitHubRepo> {\n return apiRequest<GitHubRepo>(`/repos/${owner}/${repo}`);\n },\n\n listPullRequests(owner, repo, options = {}): Promise<GitHubPullRequest[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubPullRequest[]>(\n `/repos/${owner}/${repo}/pulls${toQueryString(params)}`,\n );\n },\n\n getPullRequest(owner, repo, pullNumber): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n );\n },\n\n getPullRequestDiff(owner, repo, pullNumber): Promise<string> {\n return apiTextRequest(\n `/repos/${owner}/${repo}/pulls/${pullNumber}`,\n \"application/vnd.github.diff\",\n );\n },\n\n createIssue(owner, repo, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(`/repos/${owner}/${repo}/issues`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n getIssue(owner, repo, issueNumber): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n );\n },\n\n updateIssue(owner, repo, issueNumber, options): Promise<GitHubIssue> {\n return apiRequest<GitHubIssue>(\n `/repos/${owner}/${repo}/issues/${issueNumber}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(options),\n },\n );\n },\n\n addIssueComment(owner, repo, issueNumber, body) {\n return apiRequest(\n `/repos/${owner}/${repo}/issues/${issueNumber}/comments`,\n {\n method: \"POST\",\n body: JSON.stringify({ body }),\n },\n );\n },\n\n listIssues(owner, repo, options = {}): Promise<GitHubIssue[]> {\n const params = new URLSearchParams();\n params.set(\"state\", options.state ?? \"open\");\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubIssue[]>(\n `/repos/${owner}/${repo}/issues${toQueryString(params)}`,\n );\n },\n\n listCommits(owner, repo, options = {}): Promise<GitHubCommit[]> {\n const params = new URLSearchParams();\n if (options.sha) params.set(\"sha\", options.sha);\n if (options.path) params.set(\"path\", options.path);\n if (options.perPage) params.set(\"per_page\", String(options.perPage));\n\n return apiRequest<GitHubCommit[]>(\n `/repos/${owner}/${repo}/commits${toQueryString(params)}`,\n );\n },\n\n createPullRequest(owner, repo, options): Promise<GitHubPullRequest> {\n return apiRequest<GitHubPullRequest>(`/repos/${owner}/${repo}/pulls`, {\n method: \"POST\",\n body: JSON.stringify(options),\n });\n },\n\n mergePullRequest(owner, repo, pullNumber, options = {}): Promise<GitHubMergeResult> {\n return apiRequest<GitHubMergeResult>(\n `/repos/${owner}/${repo}/pulls/${pullNumber}/merge`,\n {\n method: \"PUT\",\n body: JSON.stringify(options),\n },\n );\n },\n\n getUser(): Promise<GitHubUser> {\n return apiRequest(\"/user\");\n },\n\n getUserByUsername(username): Promise<GitHubUser> {\n return apiRequest<GitHubUser>(`/users/${encodeURIComponent(username)}`);\n },\n };\n}\n\nexport type GitHubClient = ReturnType<typeof createGitHubClient>;\n",
|
|
261
261
|
"lib/user-id.ts": "import type { ToolExecutionContext } from \"veryfront/tool\";\n\nexport function requireUserIdFromContext(\n context?: ToolExecutionContext,\n): string {\n const userId = context?.userId;\n if (!userId) {\n throw new Error(\"GitHub tool execution requires an authenticated user.\");\n }\n return userId;\n}\n",
|
|
262
262
|
"tools/add-issue-comment.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"add-issue-comment\",\n description: \"Add a comment to a GitHub issue or pull request\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v.string().describe(\"Repository in format 'owner/repo'\"),\n issueNumber: v.number().int().positive().describe(\n \"Issue or pull request number\",\n ),\n body: v.string().min(1).describe(\"Comment body (supports Markdown)\"),\n })\n )(),\n execute: async ({ repo, issueNumber, body }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const comment = await github.addIssueComment(\n owner,\n repoName,\n issueNumber,\n body,\n );\n return {\n success: true,\n comment: {\n id: comment.id,\n url: comment.html_url,\n body: comment.body,\n author: comment.user.login,\n createdAt: comment.created_at,\n },\n message: `Comment added to issue #${issueNumber} in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
263
263
|
"tools/create-issue.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"create-issue\",\n description: \"Create a new issue in a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n title: v.string().min(1).describe(\"Issue title\"),\n body: v\n .string()\n .optional()\n .describe(\"Issue body/description (supports Markdown)\"),\n labels: v.array(v.string()).optional().describe(\n \"Labels to add to the issue\",\n ),\n assignees: v\n .array(v.string())\n .optional()\n .describe(\"GitHub usernames to assign to the issue\"),\n })\n )(),\n execute: async ({ repo, title, body, labels, assignees }, context) => {\n const userId = requireUserIdFromContext(context);\n\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issue = await github.createIssue(owner, repoName, {\n title,\n body,\n labels,\n assignees,\n });\n\n return {\n success: true,\n issue: {\n number: issue.number,\n title: issue.title,\n url: issue.html_url,\n state: issue.state,\n labels: issue.labels.map((l: { name: string }) => l.name),\n assignees: issue.assignees.map((a: { login: string }) => a.login),\n },\n message: `Issue #${issue.number} created successfully in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
264
264
|
"tools/create-pr.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"create-pr\",\n description: \"Create a new pull request in a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n title: v.string().min(1).describe(\"Pull request title\"),\n head: v\n .string()\n .describe(\n \"Branch to merge from (e.g., 'feature-branch' or 'owner:feature-branch')\",\n ),\n base: v.string().describe(\"Branch to merge into (e.g., 'main')\"),\n body: v\n .string()\n .optional()\n .describe(\"Pull request description (supports Markdown)\"),\n draft: v\n .boolean()\n .default(false)\n .optional()\n .describe(\"Create as a draft pull request\"),\n })\n )(),\n execute: async ({ repo, title, head, base, body, draft }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const pr = await github.createPullRequest(owner, repoName, {\n title,\n head,\n base,\n body,\n draft,\n });\n\n return {\n success: true,\n number: pr.number,\n title: pr.title,\n url: pr.html_url,\n state: pr.state,\n isDraft: pr.draft,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n message: `Pull request #${pr.number} created successfully in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
265
|
+
"tools/get-current-user.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-current-user\",\n description: \"Get the authenticated GitHub user identity\",\n inputSchema: defineSchema((v) => v.object({}))(),\n execute: async (_input, context) => {\n const userId = requireUserIdFromContext(context);\n\n try {\n const github = createGitHubClient(userId);\n const user = await github.getUser();\n\n return {\n user: {\n id: user.id,\n nodeId: user.node_id,\n login: user.login,\n name: user.name ?? null,\n email: user.email ?? null,\n url: user.html_url,\n avatarUrl: user.avatar_url,\n type: user.type,\n },\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
265
266
|
"tools/get-issue.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-issue\",\n description: \"Get details of a GitHub issue\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v.string().describe(\"Repository in format 'owner/repo'\"),\n issueNumber: v.number().int().positive().describe(\"Issue number\"),\n })\n )(),\n execute: async ({ repo, issueNumber }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issue = await github.getIssue(owner, repoName, issueNumber);\n return {\n issue: {\n number: issue.number,\n title: issue.title,\n body: issue.body,\n state: issue.state,\n url: issue.html_url,\n author: issue.user.login,\n labels: issue.labels.map((label: { name: string }) => label.name),\n assignees: issue.assignees.map((assignee: { login: string }) =>\n assignee.login\n ),\n updatedAt: issue.updated_at,\n },\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
266
267
|
"tools/get-pr-diff.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-pr-diff\",\n description: \"Get the diff for a pull request to review code changes\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n prNumber: v.number().int().positive().describe(\"Pull request number\"),\n })\n )(),\n execute: async ({ repo, prNumber }, context) => {\n const userId = requireUserIdFromContext(context);\n\n const [owner, repoName] = repo.split(\"/\");\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n\n const pr = await github.getPullRequest(owner, repoName, prNumber);\n const diff = await github.getPullRequestDiff(owner, repoName, prNumber);\n\n const maxDiffLength = 50000;\n let truncatedDiff = diff;\n\n if (diff.length > maxDiffLength) {\n truncatedDiff = `${\n diff.substring(0, maxDiffLength)\n }\\n\\n... (diff truncated, ${\n diff.length - maxDiffLength\n } characters remaining)`;\n }\n\n return {\n pullRequest: {\n number: pr.number,\n title: pr.title,\n author: pr.user.login,\n url: pr.html_url,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n isDraft: pr.draft,\n state: pr.state,\n },\n diff: truncatedDiff,\n stats: {\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n },\n message:\n `Retrieved diff for PR #${prNumber} (${pr.additions} additions, ${pr.deletions} deletions across ${pr.changed_files} files).`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
267
268
|
"tools/get-pr.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-pr\",\n description: \"Get details of a specific GitHub pull request\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n pull_number: v.number().int().positive().describe(\"Pull request number\"),\n })\n )(),\n execute: async ({ repo, pull_number }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const pr = await github.getPullRequest(owner, repoName, pull_number);\n\n return {\n number: pr.number,\n title: pr.title,\n body: pr.body,\n state: pr.state,\n isDraft: pr.draft,\n url: pr.html_url,\n author: pr.user.login,\n createdAt: pr.created_at,\n updatedAt: pr.updated_at,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n mergeable: pr.mergeable,\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n labels: pr.labels.map(({ name }) => name),\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
268
269
|
"tools/get-repo.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-repo\",\n description: \"Get details of a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n })\n )(),\n execute: async ({ repo }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const result = await github.getRepo(owner, repoName);\n\n return {\n repository: {\n name: result.name,\n fullName: result.full_name,\n description: result.description ?? null,\n isPrivate: result.private,\n url: result.html_url,\n defaultBranch: result.default_branch,\n language: result.language,\n stars: result.stargazers_count,\n forks: result.forks_count,\n openIssues: result.open_issues_count,\n updatedAt: result.updated_at,\n },\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
270
|
+
"tools/get-user.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"get-user\",\n description: \"Get a GitHub user profile by username\",\n inputSchema: defineSchema((v) =>\n v.object({\n username: v.string().describe(\"GitHub username/login to look up\"),\n })\n )(),\n execute: async ({ username }, context) => {\n const userId = requireUserIdFromContext(context);\n\n try {\n const github = createGitHubClient(userId);\n const result = await github.getUserByUsername(username);\n\n return {\n user: {\n login: result.login,\n id: result.id,\n name: result.name ?? null,\n type: result.type,\n url: result.html_url,\n avatarUrl: result.avatar_url,\n company: result.company ?? null,\n blog: result.blog || null,\n location: result.location ?? null,\n email: result.email ?? null,\n bio: result.bio ?? null,\n twitterUsername: result.twitter_username ?? null,\n publicRepos: result.public_repos,\n followers: result.followers,\n following: result.following,\n createdAt: result.created_at,\n updatedAt: result.updated_at,\n },\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
269
271
|
"tools/list-commits.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient, type GitHubCommit } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\nexport default tool({\n id: \"list-commits\",\n description: \"List commits for a repository, branch, or file path\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n sha: v\n .string()\n .optional()\n .describe(\"Branch name or commit SHA to list commits from\"),\n path: v\n .string()\n .optional()\n .describe(\"Only include commits that touch this file path\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(30)\n .describe(\"Maximum number of commits to return\"),\n })\n )(),\n execute: async ({ repo, sha, path, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const commits = await github.listCommits(owner, repoName, {\n sha,\n path,\n perPage: limit,\n });\n\n return {\n commits: commits.map((c: GitHubCommit) => ({\n sha: c.sha.slice(0, 7),\n message: c.commit.message.split(\"\\n\")[0],\n author: c.author?.login ?? c.commit.author.name,\n date: c.commit.author.date,\n url: c.html_url,\n })),\n count: commits.length,\n repository: repo,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
270
272
|
"tools/list-issues.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\ntype GitHubIssueListItem = {\n number: number;\n title: string;\n body: string | null;\n state: string;\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n labels: Array<{ name: string }>;\n assignees: Array<{ login: string }>;\n};\n\nexport default tool({\n id: \"list-issues\",\n description: \"List issues for a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n state: v\n .enum([\"open\", \"closed\", \"all\"])\n .default(\"open\")\n .describe(\"State of issues to list\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(20)\n .describe(\"Maximum number of issues to return\"),\n })\n )(),\n execute: async ({ repo, state, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const issues = await github.listIssues(owner, repoName, {\n state,\n perPage: limit,\n });\n\n return {\n issues: issues.map((issue: GitHubIssueListItem) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body,\n state: issue.state,\n url: issue.html_url,\n author: issue.user.login,\n labels: issue.labels.map((label) => label.name),\n assignees: issue.assignees.map((assignee) => assignee.login),\n createdAt: issue.created_at,\n updatedAt: issue.updated_at,\n })),\n count: issues.length,\n repository: repo,\n message: `Found ${issues.length} ${state} issue(s) in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
271
273
|
"tools/list-prs.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { createGitHubClient } from \"../../lib/github-client.ts\";\nimport { requireUserIdFromContext } from \"../../lib/user-id.ts\";\n\ntype PullRequest = {\n number: number;\n title: string;\n state: string;\n draft: boolean;\n html_url: string;\n user: { login: string };\n created_at: string;\n updated_at: string;\n head: { ref: string };\n base: { ref: string };\n additions: number;\n deletions: number;\n changed_files: number;\n labels: Array<{ name: string }>;\n};\n\nexport default tool({\n id: \"list-prs\",\n description: \"List pull requests for a GitHub repository\",\n inputSchema: defineSchema((v) =>\n v.object({\n repo: v\n .string()\n .describe(\"Repository in format 'owner/repo' (e.g., 'facebook/react')\"),\n state: v\n .enum([\"open\", \"closed\", \"all\"])\n .default(\"open\")\n .describe(\"State of pull requests to list\"),\n limit: v\n .number()\n .min(1)\n .max(100)\n .default(10)\n .describe(\"Maximum number of pull requests to return\"),\n })\n )(),\n execute: async ({ repo, state, limit }, context) => {\n const userId = requireUserIdFromContext(context);\n const [owner, repoName] = repo.split(\"/\");\n\n if (!owner || !repoName) {\n return { error: \"Invalid repository format. Use 'owner/repo' format.\" };\n }\n\n try {\n const github = createGitHubClient(userId);\n const prs = await github.listPullRequests(owner, repoName, {\n state,\n perPage: limit,\n });\n\n return {\n pullRequests: prs.map((pr: PullRequest) => ({\n number: pr.number,\n title: pr.title,\n state: pr.state,\n isDraft: pr.draft,\n url: pr.html_url,\n author: pr.user.login,\n createdAt: pr.created_at,\n updatedAt: pr.updated_at,\n sourceBranch: pr.head.ref,\n targetBranch: pr.base.ref,\n additions: pr.additions,\n deletions: pr.deletions,\n changedFiles: pr.changed_files,\n labels: pr.labels.map(({ name }) => name),\n })),\n count: prs.length,\n repository: repo,\n message: `Found ${prs.length} ${state} pull request(s) in ${repo}.`,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"not connected\")) {\n return {\n error: \"GitHub not connected. Please connect your GitHub account.\",\n connectUrl: \"/api/auth/github\",\n };\n }\n throw error;\n }\n },\n});\n",
|
|
@@ -9,6 +9,7 @@ export interface TemplateConfig {
|
|
|
9
9
|
npmDependencies?: Record<string, string>;
|
|
10
10
|
}
|
|
11
11
|
export type TemplateName = "ai-agent" | "docs-agent" | "multi-agent-system" | "agentic-workflow" | "coding-agent" | "saas-starter" | "minimal" | "pages-router" | "app-router";
|
|
12
|
+
export declare const STARTER_TEMPLATE_NAMES: readonly ["minimal", "ai-agent", "docs-agent", "agentic-workflow", "multi-agent-system", "coding-agent", "saas-starter"];
|
|
12
13
|
export type FeatureName = "ai" | "auth" | "workflows" | "mdx" | "redis" | "blob";
|
|
13
14
|
export interface FeatureConfig {
|
|
14
15
|
name: FeatureName;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAE1C,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,UAAU,GACX,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,YAAY,GACZ,oBAAoB,GACpB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,SAAS,GACT,cAAc,GACd,YAAY,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,WAAW,GACX,SAAS,GACT,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/templates/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAE1C,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,UAAU,GACX,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,YAAY,GACZ,oBAAoB,GACpB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,SAAS,GACT,cAAc,GACd,YAAY,CAAC;AAEjB,eAAO,MAAM,sBAAsB,0HAQS,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,WAAW,GACX,SAAS,GACT,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
package/esm/deno.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"name": "veryfront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.615",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"nodeModulesDir": "auto",
|
|
6
6
|
"workspace": [
|
|
@@ -329,12 +329,12 @@ export default {
|
|
|
329
329
|
"coverage:html": "deno coverage coverage --include=src/ --exclude=tests '--exclude=src/**/*_test.ts' '--exclude=src/**/*_test.tsx' '--exclude=src/**/*.test.ts' '--exclude=src/**/*.test.tsx' --html",
|
|
330
330
|
"bench": "VF_DISABLE_LRU_INTERVAL=1 NODE_ENV=production LOG_FORMAT=text deno bench --no-check --allow-all --unstable-worker-options --unstable-net $(find src -name '*.bench.ts')",
|
|
331
331
|
"clean": "rm -rf .cache/",
|
|
332
|
-
"lint": "DENO_NO_PACKAGE_JSON=1 deno lint src/ cli/ react/",
|
|
333
|
-
"fmt": "deno fmt src/ cli/ react/",
|
|
334
|
-
"fmt:check": "deno fmt --check src/ cli/ react/",
|
|
332
|
+
"lint": "DENO_NO_PACKAGE_JSON=1 deno lint src/ cli/ react/ && deno lint --config=scripts/test.deno.json scripts/test/ scripts/build/npm-package-metadata.test.ts",
|
|
333
|
+
"fmt": "deno fmt src/ cli/ react/ && deno fmt --config=scripts/test.deno.json scripts/test/",
|
|
334
|
+
"fmt:check": "deno fmt --check src/ cli/ react/ && deno fmt --check --config=scripts/test.deno.json scripts/test/",
|
|
335
335
|
"typecheck": "deno task generate:manifests:check && deno check src/index.ts cli/main.ts src/server/index.ts src/routing/api/index.ts src/rendering/index.ts src/platform/index.ts src/platform/adapters/index.ts src/build/index.ts src/build/production-build/index.ts src/transforms/index.ts src/config/index.ts src/utils/index.ts src/data/index.ts src/security/index.ts src/middleware/index.ts src/server/handlers/dev/index.ts src/server/handlers/request/api/index.ts src/rendering/cache/index.ts src/rendering/cache/stores/index.ts src/rendering/rsc/actions/index.ts src/html/index.ts src/modules/index.ts src/proxy/main.ts src/chat/index.ts src/markdown/index.ts src/mdx/index.ts src/fs/index.ts src/oauth/index.ts src/agent/index.ts src/agent/service/route-export.check.ts src/tool/index.ts src/workflow/index.ts src/prompt/index.ts src/resource/index.ts src/jobs/index.ts src/mcp/index.ts src/provider/index.ts",
|
|
336
|
-
"verify": "deno task generate:manifests:check && deno fmt
|
|
337
|
-
"verify:quick": "deno task generate:manifests:check && deno fmt
|
|
336
|
+
"verify": "deno task generate:manifests:check && deno task fmt:check && deno task lint && deno task lint:style && deno task lint:cli-boundary && deno task lint:wildcard-exports && deno task lint:barrel-jsdoc && deno task lint:ban-zod && deno task lint:core-deps && deno task lint:dependency-boundaries && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task docs:validate && deno task typecheck && deno task test && deno task test:e2e:binary",
|
|
337
|
+
"verify:quick": "deno task generate:manifests:check && deno task fmt:check && deno task lint && deno task lint:style && deno task lint:cli-boundary && deno task lint:wildcard-exports && deno task lint:barrel-jsdoc && deno task lint:ban-zod && deno task lint:core-deps && deno task lint:dependency-boundaries && deno task lint:extension-contracts && deno task lint:extension-capabilities && deno task docs:validate && deno task typecheck",
|
|
338
338
|
"docs": "deno run --allow-read --allow-write --allow-run --allow-env scripts/docs/generate-api-reference.ts",
|
|
339
339
|
"docs:coverage": "deno run --allow-read scripts/docs/docs-coverage.ts",
|
|
340
340
|
"docs:copy": "rm -rf ../../docs/docs/code/api-reference && cp -r docs/api-reference/ ../../docs/docs/code/api-reference/",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-context.d.ts","sourceRoot":"","sources":["../../../../../src/src/build/bundler/code-splitter/build-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAW,MAAM,sCAAsC,CAAC;AAKlF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"build-context.d.ts","sourceRoot":"","sources":["../../../../../src/src/build/bundler/code-splitter/build-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAW,MAAM,sCAAsC,CAAC;AAKlF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAU/C,gEAAgE;AAChE,wBAAgB,uBAAuB,CACrC,cAAc,GAAE,MAAM,EAAO,EAC7B,gBAAgB,GAAE,KAAK,GAAG,aAAa,GAAG,SAAiB,GAC1D,MAAM,EAAE,CAeV;AAED,2DAA2D;AAC3D,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBpE;AAED,mEAAmE;AACnE,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,YAAY,CAAC,CA+BvB"}
|
|
@@ -12,6 +12,7 @@ const VERYFRONT_CLIENT_MODULES = [
|
|
|
12
12
|
"veryfront/chat",
|
|
13
13
|
"veryfront/markdown",
|
|
14
14
|
"veryfront/mdx",
|
|
15
|
+
"veryfront/workflow",
|
|
15
16
|
];
|
|
16
17
|
/** Gets list of external dependencies to exclude from bundle */
|
|
17
18
|
export function getExternalDependencies(customExternal = [], moduleResolution = "cdn") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-prep.d.ts","sourceRoot":"","sources":["../../../src/src/chat/message-prep.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AAQjC,OAAO,EAKL,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAMpB,uBAAuB;AACvB,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAOD,qBAAqB;AACrB,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,oBAAoB,EAAE,CAiCxB;AAqCD,kDAAkD;AAClD,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAiExB;AA+BD,4DAA4D;AAC5D,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED,gDAAgD;AAChD,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAwB7F;AAED,qDAAqD;AACrD,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,aAAa,EAAE,GACxB,aAAa,EAAE,CAmDjB;AAyCD,gCAAgC;AAChC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAiBhF;AAsFD,wCAAwC;AACxC,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,oBAAoB,EAAE,GAC/B,oBAAoB,EAAE,CAwBxB;AAED;;GAEG;AACH,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,sCAAgC,CAAC;AAYnE,wDAAwD;AACxD,wBAAgB,0CAA0C,CACxD,QAAQ,EAAE,aAAa,EAAE,GACxB,oBAAoB,EAAE,CAiBxB;
|
|
1
|
+
{"version":3,"file":"message-prep.d.ts","sourceRoot":"","sources":["../../../src/src/chat/message-prep.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AAQjC,OAAO,EAKL,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAE1B,MAAM,YAAY,CAAC;AAMpB,uBAAuB;AACvB,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAOD,qBAAqB;AACrB,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,oBAAoB,EAAE,CAiCxB;AAqCD,kDAAkD;AAClD,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAiExB;AA+BD,4DAA4D;AAC5D,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED,gDAAgD;AAChD,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAwB7F;AAED,qDAAqD;AACrD,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,aAAa,EAAE,GACxB,aAAa,EAAE,CAmDjB;AAyCD,gCAAgC;AAChC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAiBhF;AAsFD,wCAAwC;AACxC,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,oBAAoB,EAAE,GAC/B,oBAAoB,EAAE,CAwBxB;AAED;;GAEG;AACH,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,sCAAgC,CAAC;AAYnE,wDAAwD;AACxD,wBAAgB,0CAA0C,CACxD,QAAQ,EAAE,aAAa,EAAE,GACxB,oBAAoB,EAAE,CAiBxB;AA2OD,6BAA6B;AAC7B,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4E3F;AAWD,yBAAyB;AACzB,wBAAgB,eAAe,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4IxF;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA4B7F;AAED,wBAAwB;AACxB,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,QAAQ,GAAE,MAAU,GACnB,oBAAoB,EAAE,CAexB;AAED,2BAA2B;AAC3B,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CA0D1F;AAED,4BAA4B;AAC5B,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,GAAE,MAA6B,EACrC,QAAQ,GAAE,MAAU,GACnB,oBAAoB,EAAE,CAMxB;AAED;;GAEG;AACH,4DAA4D;AAC5D,eAAO,MAAM,kCAAkC,mDAA6C,CAAC"}
|
|
@@ -481,9 +481,10 @@ function compactContactValue(value) {
|
|
|
481
481
|
if (typeof emailAddress.address === "string")
|
|
482
482
|
compact.address = emailAddress.address;
|
|
483
483
|
}
|
|
484
|
-
for (const field of ["name", "address", "email"]) {
|
|
485
|
-
if (typeof value[field] === "string")
|
|
484
|
+
for (const field of ["login", "name", "address", "email", "id"]) {
|
|
485
|
+
if (typeof value[field] === "string" || typeof value[field] === "number") {
|
|
486
486
|
compact[field] = value[field];
|
|
487
|
+
}
|
|
487
488
|
}
|
|
488
489
|
return Object.keys(compact).length > 0 ? compact : null;
|
|
489
490
|
}
|
|
@@ -505,6 +506,17 @@ function compactHistoricalField(field, fieldValue) {
|
|
|
505
506
|
const strings = fieldValue.filter((item) => typeof item === "string");
|
|
506
507
|
return strings.length > 0 ? strings : null;
|
|
507
508
|
}
|
|
509
|
+
if (field.kind === "object") {
|
|
510
|
+
if (!isRecord(fieldValue))
|
|
511
|
+
return null;
|
|
512
|
+
const compact = {};
|
|
513
|
+
for (const [key, value] of Object.entries(fieldValue)) {
|
|
514
|
+
if (typeof value === "string" || typeof value === "boolean" || typeof value === "number") {
|
|
515
|
+
compact[key] = value;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return Object.keys(compact).length > 0 ? compact : null;
|
|
519
|
+
}
|
|
508
520
|
if (typeof fieldValue === "string") {
|
|
509
521
|
return field.maxLength ? truncate(fieldValue, field.maxLength) : fieldValue;
|
|
510
522
|
}
|
|
@@ -541,6 +553,8 @@ function getHistoricalSummaryItems(parsed, contract) {
|
|
|
541
553
|
if (Array.isArray(value))
|
|
542
554
|
return value;
|
|
543
555
|
}
|
|
556
|
+
if (contract.singleItem)
|
|
557
|
+
return [parsed];
|
|
544
558
|
return null;
|
|
545
559
|
}
|
|
546
560
|
function compactHistoricalToolSummaryOutput(rawValue, contract) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/html/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAc1D,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAQR;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/html/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAc1D,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAQR;AA4ND,UAAU,qBAAqB;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAWD,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvD,OAAO,CAAC,MAAM,CAAC,CA+DjB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAElF"}
|
package/esm/src/html/utils.js
CHANGED
|
@@ -69,6 +69,7 @@ const CDN_URL_TEMPLATES = {
|
|
|
69
69
|
veryfrontChat: (v) => `https://esm.sh/veryfront@${v}/chat?external=react,react-dom&target=es2022`,
|
|
70
70
|
veryfrontMarkdown: (v) => `https://esm.sh/veryfront@${v}/markdown?external=react,react-dom&target=es2022`,
|
|
71
71
|
veryfrontMdx: (v) => `https://esm.sh/veryfront@${v}/mdx?external=react,react-dom&target=es2022`,
|
|
72
|
+
veryfrontWorkflow: (v) => `https://esm.sh/veryfront@${v}/workflow/react?external=react,react-dom&target=es2022`,
|
|
72
73
|
},
|
|
73
74
|
unpkg: {
|
|
74
75
|
react: (v) => `https://unpkg.com/react@${v}/umd/react.production.min.js`,
|
|
@@ -76,9 +77,10 @@ const CDN_URL_TEMPLATES = {
|
|
|
76
77
|
reactDomClient: (v) => `https://unpkg.com/react-dom@${v}/umd/react-dom.production.min.js`,
|
|
77
78
|
jsxRuntime: (v) => `https://unpkg.com/react@${v}/jsx-runtime`,
|
|
78
79
|
jsxDevRuntime: (v) => `https://unpkg.com/react@${v}/jsx-dev-runtime`,
|
|
79
|
-
veryfrontChat: (v) => `https://unpkg.com/veryfront@${v}/
|
|
80
|
-
veryfrontMarkdown: (v) => `https://unpkg.com/veryfront@${v}/
|
|
81
|
-
veryfrontMdx: (v) => `https://unpkg.com/veryfront@${v}/
|
|
80
|
+
veryfrontChat: (v) => `https://unpkg.com/veryfront@${v}/esm/src/chat/index.js`,
|
|
81
|
+
veryfrontMarkdown: (v) => `https://unpkg.com/veryfront@${v}/esm/src/markdown/index.js`,
|
|
82
|
+
veryfrontMdx: (v) => `https://unpkg.com/veryfront@${v}/esm/src/mdx/index.js`,
|
|
83
|
+
veryfrontWorkflow: (v) => `https://unpkg.com/veryfront@${v}/esm/src/workflow/react/index.js`,
|
|
82
84
|
},
|
|
83
85
|
jsdelivr: {
|
|
84
86
|
react: (v) => `https://cdn.jsdelivr.net/npm/react@${v}/umd/react.production.min.js`,
|
|
@@ -86,9 +88,10 @@ const CDN_URL_TEMPLATES = {
|
|
|
86
88
|
reactDomClient: (v) => `https://cdn.jsdelivr.net/npm/react-dom@${v}/umd/react-dom.production.min.js`,
|
|
87
89
|
jsxRuntime: (v) => `https://cdn.jsdelivr.net/npm/react@${v}/jsx-runtime`,
|
|
88
90
|
jsxDevRuntime: (v) => `https://cdn.jsdelivr.net/npm/react@${v}/jsx-dev-runtime`,
|
|
89
|
-
veryfrontChat: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/
|
|
90
|
-
veryfrontMarkdown: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/
|
|
91
|
-
veryfrontMdx: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/
|
|
91
|
+
veryfrontChat: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/esm/src/chat/index.js`,
|
|
92
|
+
veryfrontMarkdown: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/esm/src/markdown/index.js`,
|
|
93
|
+
veryfrontMdx: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/esm/src/mdx/index.js`,
|
|
94
|
+
veryfrontWorkflow: (v) => `https://cdn.jsdelivr.net/npm/veryfront@${v}/esm/src/workflow/react/index.js`,
|
|
92
95
|
},
|
|
93
96
|
};
|
|
94
97
|
function buildCdnImportMapFromTemplates(versions, templates, includePlatformUtilities) {
|
|
@@ -102,6 +105,7 @@ function buildCdnImportMapFromTemplates(versions, templates, includePlatformUtil
|
|
|
102
105
|
"veryfront/chat": templates.veryfrontChat(veryfront),
|
|
103
106
|
"veryfront/markdown": templates.veryfrontMarkdown(veryfront),
|
|
104
107
|
"veryfront/mdx": templates.veryfrontMdx(veryfront),
|
|
108
|
+
"veryfront/workflow": templates.veryfrontWorkflow(veryfront),
|
|
105
109
|
...(includePlatformUtilities ? PLATFORM_UTILITIES : {}),
|
|
106
110
|
};
|
|
107
111
|
}
|
|
@@ -126,6 +130,7 @@ function getSelfHostedImportMap(versions) {
|
|
|
126
130
|
"veryfront/chat": "/_veryfront/lib/chat.js",
|
|
127
131
|
"veryfront/markdown": "/_veryfront/lib/markdown.js",
|
|
128
132
|
"veryfront/mdx": "/_veryfront/lib/mdx.js",
|
|
133
|
+
"veryfront/workflow": "/_veryfront/lib/workflow.js",
|
|
129
134
|
"veryfront/head": PLATFORM_UTILITY_PATHS.head,
|
|
130
135
|
"veryfront/router": PLATFORM_UTILITY_PATHS.router,
|
|
131
136
|
"veryfront/context": PLATFORM_UTILITY_PATHS.context,
|