feat: wire mobile workspace into project loop
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import type { Id } from "@code/backend/convex/_generated/dataModel";
|
||||
import {
|
||||
MobileAssistantChatScreen,
|
||||
MobileExpandedWorkScreen,
|
||||
@@ -27,6 +28,8 @@ export const MobileFlowPage = ({ screen }: MobileFlowPageProps) => {
|
||||
selectedWorkUnitId: workUnitId,
|
||||
});
|
||||
const workspace = useMobileWorkspace({
|
||||
onCreateIssue: (title, body) =>
|
||||
projectWorkspace.raiseIssue({ body, title }),
|
||||
onSend: projectWorkspace.sendMessage,
|
||||
});
|
||||
const workPath = "/work";
|
||||
@@ -48,14 +51,38 @@ export const MobileFlowPage = ({ screen }: MobileFlowPageProps) => {
|
||||
|
||||
const screenProps = {
|
||||
composerValue: workspace.composerValue,
|
||||
createIssueBody: workspace.issueBody,
|
||||
createIssueTitle: workspace.issueTitle,
|
||||
data: projectWorkspace.data,
|
||||
onBack: () => navigate(workPath),
|
||||
onComposerChange: workspace.handleComposerChange,
|
||||
onComposerSubmit: workspace.handleComposerSubmit,
|
||||
onCreateBodyChange: workspace.setIssueBody,
|
||||
onCreateIssue: workspace.handleCreateIssueSubmit,
|
||||
onCreateIssueFromSignal: projectWorkspace.data.latestSignal?.projectId
|
||||
? () =>
|
||||
void projectWorkspace.raiseIssueFromSignal(
|
||||
projectWorkspace.data.latestSignal?.id ?? ""
|
||||
)
|
||||
: undefined,
|
||||
onCreateTitleChange: workspace.setIssueTitle,
|
||||
onManageProjects: () => navigate("/dashboard"),
|
||||
onOpenAssistant: () => navigate(chatPath),
|
||||
onOpenUnit: handleOpenUnit,
|
||||
onProjectSelect: (projectId: string) =>
|
||||
projectWorkspace.projectWorkspace.setSelectedProjectId(
|
||||
projectId as Id<"projects">
|
||||
),
|
||||
onReviewUnit: (reviewUrl: string) => {
|
||||
window.open(reviewUrl, "_blank", "noopener,noreferrer");
|
||||
},
|
||||
onStartUnit: (selectedIssueId: string) => {
|
||||
void projectWorkspace.startWorkUnit(
|
||||
selectedIssueId as Id<"projectIssues">
|
||||
);
|
||||
},
|
||||
onViewWork: () => navigate(workPath),
|
||||
pendingAction: projectWorkspace.projectWorkspace.pendingAction,
|
||||
statusMessage: workspace.statusMessage ?? projectWorkspace.error?.message,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { api } from "@code/backend/convex/_generated/api";
|
||||
import type { Id } from "@code/backend/convex/_generated/dataModel";
|
||||
import type {
|
||||
MobileAssistantMessageView,
|
||||
MobileAssistantView,
|
||||
@@ -70,6 +71,7 @@ export const useMobileProjectWorkspace = ({
|
||||
data: buildMobileWorkspaceView({
|
||||
artifacts: projectWorkspace.artifacts,
|
||||
assistant,
|
||||
events: projectWorkspace.events,
|
||||
issues: projectWorkspace.issues,
|
||||
organizationLabel: organization.organizationName,
|
||||
projects: projectWorkspace.projects,
|
||||
@@ -78,6 +80,12 @@ export const useMobileProjectWorkspace = ({
|
||||
signals,
|
||||
}),
|
||||
error: organization.error ?? chatAgent.error,
|
||||
organization,
|
||||
projectWorkspace,
|
||||
raiseIssue: projectWorkspace.raiseIssue,
|
||||
raiseIssueFromSignal: (signalId: string) =>
|
||||
projectWorkspace.raiseIssueFromSignal(signalId as Id<"signals">),
|
||||
sendMessage: chatAgent.sendMessage,
|
||||
startWorkUnit: projectWorkspace.startWorkUnit,
|
||||
} as const;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useState } from "react";
|
||||
|
||||
interface UseMobileWorkspaceOptions {
|
||||
readonly initialExpanded?: boolean;
|
||||
readonly onCreateIssue: (title: string, body: string) => Promise<void>;
|
||||
readonly onSend: (message: string) => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -11,9 +12,12 @@ const errorMessage = (error: unknown) =>
|
||||
|
||||
export const useMobileWorkspace = ({
|
||||
initialExpanded = false,
|
||||
onCreateIssue,
|
||||
onSend,
|
||||
}: UseMobileWorkspaceOptions) => {
|
||||
const [composerValue, setComposerValue] = useState("");
|
||||
const [issueBody, setIssueBody] = useState("");
|
||||
const [issueTitle, setIssueTitle] = useState("");
|
||||
const [expanded, setExpanded] = useState(initialExpanded);
|
||||
const [statusMessage, setStatusMessage] = useState<string>();
|
||||
|
||||
@@ -41,12 +45,38 @@ export const useMobileWorkspace = ({
|
||||
void sendMessage();
|
||||
};
|
||||
|
||||
const handleCreateIssueSubmit = (event: FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
const title = issueTitle.trim();
|
||||
const body = issueBody.trim();
|
||||
if (!title || !body) {
|
||||
return;
|
||||
}
|
||||
setStatusMessage("Creating project work…");
|
||||
const createIssue = async () => {
|
||||
try {
|
||||
await onCreateIssue(title, body);
|
||||
setIssueTitle("");
|
||||
setIssueBody("");
|
||||
setStatusMessage("Project work created");
|
||||
} catch (error) {
|
||||
setStatusMessage(errorMessage(error));
|
||||
}
|
||||
};
|
||||
void createIssue();
|
||||
};
|
||||
|
||||
return {
|
||||
composerValue,
|
||||
expanded,
|
||||
handleComposerChange,
|
||||
handleComposerSubmit,
|
||||
handleCreateIssueSubmit,
|
||||
issueBody,
|
||||
issueTitle,
|
||||
setExpanded,
|
||||
setIssueBody,
|
||||
setIssueTitle,
|
||||
statusMessage,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@ export const useProjectWorkspace = () => {
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const importPublicGit = useAction(api.projects.importPublicGit);
|
||||
const createIssue = useMutation(api.projectIssues.create);
|
||||
const createIssueFromSignal = useMutation(api.projectIssues.createFromSignal);
|
||||
const beginIssue = useMutation(api.projectIssues.begin);
|
||||
const markDispatchFailed = useMutation(api.projectIssues.markDispatchFailed);
|
||||
const activeProjectId =
|
||||
@@ -79,17 +80,22 @@ export const useProjectWorkspace = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const raiseIssue = async () => {
|
||||
const raiseIssue = async (input?: {
|
||||
readonly body?: string;
|
||||
readonly title?: string;
|
||||
}) => {
|
||||
if (!activeProjectId) {
|
||||
return;
|
||||
}
|
||||
const nextTitle = input?.title ?? issueTitle;
|
||||
const nextBody = input?.body ?? issueBody;
|
||||
setPendingAction("issue");
|
||||
setError(null);
|
||||
try {
|
||||
const issueId = await createIssue({
|
||||
body: issueBody,
|
||||
body: nextBody,
|
||||
projectId: activeProjectId,
|
||||
title: issueTitle,
|
||||
title: nextTitle,
|
||||
});
|
||||
setSelectedIssueId(issueId);
|
||||
setIssueTitle("");
|
||||
@@ -101,6 +107,19 @@ export const useProjectWorkspace = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const raiseIssueFromSignal = async (signalId: Id<"signals">) => {
|
||||
setPendingAction(`signal:${signalId}`);
|
||||
setError(null);
|
||||
try {
|
||||
const outcome = await createIssueFromSignal({ signalId });
|
||||
setSelectedIssueId(outcome.issueId);
|
||||
} catch (caughtError) {
|
||||
setError(errorMessage(caughtError));
|
||||
} finally {
|
||||
setPendingAction(null);
|
||||
}
|
||||
};
|
||||
|
||||
const startIssue = async (
|
||||
issueId: Id<"projectIssues">,
|
||||
issueNumber: number,
|
||||
@@ -122,6 +141,15 @@ export const useProjectWorkspace = () => {
|
||||
setPendingAction(null);
|
||||
}
|
||||
};
|
||||
|
||||
const startWorkUnit = async (issueId: Id<"projectIssues">) => {
|
||||
const issue = issues?.find((candidate) => candidate._id === issueId);
|
||||
if (!issue) {
|
||||
setError("That work unit is no longer available");
|
||||
return;
|
||||
}
|
||||
await startIssue(issue._id, issue.number, issue.title);
|
||||
};
|
||||
const selectedProject =
|
||||
projects?.find(
|
||||
(project) => project.id === (activeProjectId as unknown as string)
|
||||
@@ -149,6 +177,7 @@ export const useProjectWorkspace = () => {
|
||||
projects,
|
||||
pullRequest,
|
||||
raiseIssue,
|
||||
raiseIssueFromSignal,
|
||||
repository,
|
||||
selectedIssue,
|
||||
selectedIssueId,
|
||||
@@ -160,5 +189,6 @@ export const useProjectWorkspace = () => {
|
||||
setSelectedIssueId,
|
||||
setSelectedProjectId,
|
||||
startIssue,
|
||||
startWorkUnit,
|
||||
} as const;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import type { api } from "@code/backend/convex/_generated/api";
|
||||
import type { Doc } from "@code/backend/convex/_generated/dataModel";
|
||||
import {
|
||||
getProjectWorkNextAction,
|
||||
getProjectWorkProgress,
|
||||
getProjectWorkStatus,
|
||||
} from "@code/primitives/project-work";
|
||||
import type {
|
||||
MobileAssistantView,
|
||||
MobileProjectView,
|
||||
MobileSignalView,
|
||||
MobileWorkspaceView,
|
||||
MobileWorkUnitTone,
|
||||
@@ -10,11 +16,13 @@ import type {
|
||||
import type { FunctionReturnType } from "convex/server";
|
||||
|
||||
type SignalList = FunctionReturnType<typeof api.signals.list>;
|
||||
type ProjectEventList = FunctionReturnType<typeof api.projectIssues.events>;
|
||||
type ProjectView = FunctionReturnType<typeof api.projects.list>[number];
|
||||
|
||||
interface BuildMobileWorkspaceViewInput {
|
||||
readonly artifacts: readonly Doc<"projectArtifacts">[] | undefined;
|
||||
readonly assistant: MobileAssistantView;
|
||||
readonly events: ProjectEventList | undefined;
|
||||
readonly issues: readonly Doc<"projectIssues">[] | undefined;
|
||||
readonly organizationLabel?: string;
|
||||
readonly projects: readonly ProjectView[] | undefined;
|
||||
@@ -28,68 +36,64 @@ const updatedDateFormatter = new Intl.DateTimeFormat("en", {
|
||||
month: "short",
|
||||
});
|
||||
|
||||
const statusPresentation: Record<
|
||||
Doc<"projectIssues">["status"],
|
||||
{
|
||||
readonly nextAction: string;
|
||||
readonly progress: number;
|
||||
readonly statusLabel: string;
|
||||
readonly tone: MobileWorkUnitTone;
|
||||
const statusTone = (
|
||||
status: ReturnType<typeof getProjectWorkStatus>
|
||||
): MobileWorkUnitTone => {
|
||||
if (status.phase === "completed") {
|
||||
return "green";
|
||||
}
|
||||
> = {
|
||||
completed: {
|
||||
nextAction: "Review completed work",
|
||||
progress: 100,
|
||||
statusLabel: "Ready for review",
|
||||
tone: "green",
|
||||
},
|
||||
failed: {
|
||||
nextAction: "Retry this work unit",
|
||||
progress: 45,
|
||||
statusLabel: "Blocked",
|
||||
tone: "orange",
|
||||
},
|
||||
"needs-input": {
|
||||
nextAction: "Add the missing context",
|
||||
progress: 55,
|
||||
statusLabel: "Needs you",
|
||||
tone: "orange",
|
||||
},
|
||||
open: {
|
||||
nextAction: "Start this work unit",
|
||||
progress: 25,
|
||||
statusLabel: "Researching",
|
||||
tone: "purple",
|
||||
},
|
||||
queued: {
|
||||
nextAction: "Zopu is preparing",
|
||||
progress: 40,
|
||||
statusLabel: "Queued",
|
||||
tone: "blue",
|
||||
},
|
||||
working: {
|
||||
nextAction: "Review current progress",
|
||||
progress: 68,
|
||||
statusLabel: "In progress",
|
||||
tone: "blue",
|
||||
},
|
||||
if (status.phase === "failed" || status.phase === "waiting") {
|
||||
return "orange";
|
||||
}
|
||||
if (status.phase === "captured") {
|
||||
return "purple";
|
||||
}
|
||||
return "blue";
|
||||
};
|
||||
|
||||
const isPullRequestData = (
|
||||
value: unknown
|
||||
): value is {
|
||||
pullRequest: {
|
||||
number: number;
|
||||
status: "open" | "closed" | "merged";
|
||||
url: string;
|
||||
};
|
||||
} =>
|
||||
typeof value === "object" &&
|
||||
value !== null &&
|
||||
"pullRequest" in value &&
|
||||
typeof value.pullRequest === "object" &&
|
||||
value.pullRequest !== null &&
|
||||
"number" in value.pullRequest &&
|
||||
typeof value.pullRequest.number === "number" &&
|
||||
"url" in value.pullRequest &&
|
||||
typeof value.pullRequest.url === "string";
|
||||
|
||||
const toWorkUnit = (
|
||||
issue: Doc<"projectIssues">,
|
||||
artifactCount: number
|
||||
artifactCount: number,
|
||||
events: ProjectEventList | undefined
|
||||
): MobileWorkUnitView => {
|
||||
const presentation = statusPresentation[issue.status];
|
||||
const status = getProjectWorkStatus(issue.status);
|
||||
const pullRequest = events
|
||||
?.filter((event) => event.issueId === issue._id)
|
||||
.map((event) => event.data)
|
||||
.find(isPullRequestData)?.pullRequest;
|
||||
return {
|
||||
artifactCount,
|
||||
canRetry: status.phase === "failed" || status.phase === "waiting",
|
||||
canStart: status.phase === "captured",
|
||||
code: `#${issue.number}`,
|
||||
id: issue._id,
|
||||
nextAction: presentation.nextAction,
|
||||
progress: presentation.progress,
|
||||
statusLabel: presentation.statusLabel,
|
||||
nextAction: getProjectWorkNextAction(issue.status),
|
||||
progress: getProjectWorkProgress(issue.status),
|
||||
pullRequestNumber: pullRequest?.number,
|
||||
reviewUrl: pullRequest?.url,
|
||||
statusLabel: status.label,
|
||||
summary: issue.body,
|
||||
title: issue.title,
|
||||
tone: presentation.tone,
|
||||
tone: statusTone(status),
|
||||
updatedLabel: updatedDateFormatter.format(issue.updatedAt),
|
||||
};
|
||||
};
|
||||
@@ -103,14 +107,34 @@ const toLatestSignalView = (
|
||||
return {
|
||||
desiredOutcome: signal.problemStatement.desiredOutcome,
|
||||
id: signal._id,
|
||||
projectId: signal.projectId ?? undefined,
|
||||
summary: signal.problemStatement.summary,
|
||||
title: signal.problemStatement.title,
|
||||
};
|
||||
};
|
||||
|
||||
const relevantSignalsForProject = (
|
||||
signals: SignalList | undefined,
|
||||
projectId: ProjectView["id"] | undefined
|
||||
) =>
|
||||
signals?.filter(
|
||||
({ signal }) =>
|
||||
!signal.projectId || String(signal.projectId) === String(projectId)
|
||||
) ?? [];
|
||||
|
||||
const makeProjectViews = (
|
||||
projects: readonly ProjectView[] | undefined
|
||||
): readonly MobileProjectView[] =>
|
||||
projects?.map((project) => ({
|
||||
connected: project.sources.length > 0,
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
})) ?? [];
|
||||
|
||||
export const buildMobileWorkspaceView = ({
|
||||
artifacts,
|
||||
assistant,
|
||||
events,
|
||||
issues,
|
||||
organizationLabel = "Personal workspace",
|
||||
projects,
|
||||
@@ -120,18 +144,13 @@ export const buildMobileWorkspaceView = ({
|
||||
}: BuildMobileWorkspaceViewInput): MobileWorkspaceView => {
|
||||
const artifactCount = artifacts?.length ?? 0;
|
||||
const workUnits =
|
||||
issues?.map((issue) => toWorkUnit(issue, artifactCount)) ?? [];
|
||||
issues?.map((issue) => toWorkUnit(issue, artifactCount, events)) ?? [];
|
||||
const selectedWorkUnit =
|
||||
workUnits.find((workUnit) => workUnit.id === selectedWorkUnitId) ??
|
||||
workUnits.find((workUnit) => workUnit.tone === "blue") ??
|
||||
workUnits[0];
|
||||
const selectedProjectId = selectedProject?.id;
|
||||
const relevantSignals =
|
||||
signals?.filter(
|
||||
({ signal }) =>
|
||||
!signal.projectId ||
|
||||
String(signal.projectId) === String(selectedProjectId)
|
||||
) ?? [];
|
||||
const relevantSignals = relevantSignalsForProject(signals, selectedProjectId);
|
||||
const latestSignal = relevantSignals[0]?.signal;
|
||||
const activeCount = workUnits.filter(
|
||||
(workUnit) => workUnit.progress < 100
|
||||
@@ -143,6 +162,7 @@ export const buildMobileWorkspaceView = ({
|
||||
(issue) => issue.status === "completed"
|
||||
).length;
|
||||
const hasSelectedProject = Boolean(selectedProject);
|
||||
const projectViews = makeProjectViews(projects);
|
||||
|
||||
return {
|
||||
activeCount,
|
||||
@@ -156,6 +176,8 @@ export const buildMobileWorkspaceView = ({
|
||||
needsAttentionCount: needsAttentionCount ?? 0,
|
||||
organizationLabel,
|
||||
projectName: selectedProject?.name,
|
||||
projects: projectViews,
|
||||
selectedProjectId: selectedProject?.id,
|
||||
selectedWorkUnit,
|
||||
shippedCount: shippedCount ?? 0,
|
||||
totalCount: workUnits.length,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Doc } from "@code/backend/convex/_generated/dataModel";
|
||||
import type { ProjectIssueStatus } from "@code/primitives/project-issue";
|
||||
import {
|
||||
getProjectWorkNextAction,
|
||||
getProjectWorkProgress,
|
||||
getProjectWorkStatus,
|
||||
} from "@code/primitives/project-work";
|
||||
@@ -65,15 +66,6 @@ const STATUS_TEXT: Readonly<Record<ProjectIssueStatus, string>> = {
|
||||
"The project manager is working through the issue and recording durable evidence.",
|
||||
};
|
||||
|
||||
const NEXT_ACTION: Readonly<Record<ProjectIssueStatus, string>> = {
|
||||
completed: "Review the pull request",
|
||||
failed: "Review the failure and retry",
|
||||
"needs-input": "Resolve the open question",
|
||||
open: "Start the project manager",
|
||||
queued: "Watch the run progress",
|
||||
working: "Wait for verification",
|
||||
};
|
||||
|
||||
const formatTime = (timestamp: number): string =>
|
||||
new Intl.DateTimeFormat(undefined, {
|
||||
hour: "numeric",
|
||||
@@ -312,7 +304,7 @@ export const buildProjectLoopView = ({
|
||||
return {
|
||||
activity: buildActivity(issue, resolvedArtifacts, status.label),
|
||||
currentState: STATUS_TEXT[issue.status],
|
||||
nextAction: NEXT_ACTION[issue.status],
|
||||
nextAction: getProjectWorkNextAction(issue.status),
|
||||
progress: getProjectWorkProgress(issue.status),
|
||||
pullRequest,
|
||||
status,
|
||||
|
||||
134
bun.lock
134
bun.lock
@@ -258,6 +258,11 @@
|
||||
"dependencies": {
|
||||
"@base-ui/react": "^1.6.0",
|
||||
"@shadcn/react": "^0.2.0",
|
||||
"@streamdown/cjk": "^1.0.3",
|
||||
"@streamdown/code": "^1.1.1",
|
||||
"@streamdown/math": "^1.0.2",
|
||||
"@streamdown/mermaid": "^1.0.2",
|
||||
"ai": "^7.0.35",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "catalog:",
|
||||
@@ -265,9 +270,12 @@
|
||||
"react": "^19.2.7",
|
||||
"react-dom": "^19.2.7",
|
||||
"shadcn": "^4.12.0",
|
||||
"shiki": "^4.3.1",
|
||||
"sonner": "catalog:",
|
||||
"streamdown": "^2.5.0",
|
||||
"tailwind-merge": "catalog:",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"use-stick-to-bottom": "^1.1.6",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@code/config": "workspace:*",
|
||||
@@ -342,6 +350,12 @@
|
||||
|
||||
"@agentos-software/tar": ["@agentos-software/tar@0.3.4", "", {}, "sha512-/SSqfgS5xOufvulsz5kVDTCFxpDy+5s7Og1iJe9krjU7Jvtgnp9TpPaJnSr721h6uY6tsWHcs3u8E457EwSkNw=="],
|
||||
|
||||
"@ai-sdk/gateway": ["@ai-sdk/gateway@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "4.0.3", "@ai-sdk/provider-utils": "5.0.12", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-gqTMvV0N8/JirIZ3OzwjSZRYxzwZu/PeOFCKb8NB9fstWH39tI+L6CkeMNVou5/HCKEYAw6RCOHW59Vhquv8vA=="],
|
||||
|
||||
"@ai-sdk/provider": ["@ai-sdk/provider@4.0.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-e0CpNWJUY7OxAFAnCZkw+ri9QOHWwTs1tXP42782KFGCU07qt8NiXCrCVowyCB5dP2r5/Uls+g2oPd8kOJn9dw=="],
|
||||
|
||||
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.12", "", { "dependencies": { "@ai-sdk/provider": "4.0.3", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-bbhlOgHeYwrIGheLkM6fhS8hVger8uFPmcOLg+kxc9EFh7y30XYorWhthlYAgpadO3SJhFZrIcEknN7qEqEVvA=="],
|
||||
|
||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||
|
||||
"@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
|
||||
@@ -1358,6 +1372,22 @@
|
||||
|
||||
"@shadcn/react": ["@shadcn/react@0.2.1", "", { "peerDependencies": { "@types/react": ">=19", "react": ">=19" }, "optionalPeers": ["@types/react", "react"] }, "sha512-5krgi3dRMKb5jH6a+qPzVJUy/54s0kKE4Rw4LjDfLqOdVQTWKUgxWf1kW8r912I0jX/Lzxqc+pgjkjWxUIK5BQ=="],
|
||||
|
||||
"@shikijs/core": ["@shikijs/core@4.3.1", "", { "dependencies": { "@shikijs/primitive": "4.3.1", "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA=="],
|
||||
|
||||
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" } }, "sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ=="],
|
||||
|
||||
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg=="],
|
||||
|
||||
"@shikijs/langs": ["@shikijs/langs@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1" } }, "sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ=="],
|
||||
|
||||
"@shikijs/primitive": ["@shikijs/primitive@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A=="],
|
||||
|
||||
"@shikijs/themes": ["@shikijs/themes@4.3.1", "", { "dependencies": { "@shikijs/types": "4.3.1" } }, "sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA=="],
|
||||
|
||||
"@shikijs/types": ["@shikijs/types@4.3.1", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g=="],
|
||||
|
||||
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
|
||||
|
||||
"@silvia-odwyer/photon-node": ["@silvia-odwyer/photon-node@0.3.4", "", {}, "sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA=="],
|
||||
|
||||
"@sinclair/typebox": ["@sinclair/typebox@0.34.52", "", {}, "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw=="],
|
||||
@@ -1404,6 +1434,14 @@
|
||||
|
||||
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
|
||||
|
||||
"@streamdown/cjk": ["@streamdown/cjk@1.0.3", "", { "dependencies": { "remark-cjk-friendly": "^2.0.1", "remark-cjk-friendly-gfm-strikethrough": "^2.0.1", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-WRg8HR/gHbBoTgsMd91OKFUClIoDcEFVofJvluvEAyjx3KpU0aGgD9tGDqHkHj14ShoMSkX0IYetWGegTcwIJw=="],
|
||||
|
||||
"@streamdown/code": ["@streamdown/code@1.1.1", "", { "dependencies": { "shiki": "^3.19.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-i7HTNuDgZWb+VdrNVOam9gQhIc5MSSDXKWXgbUrn/4vSRaSMM+Rtl10MQj4wLWPNpF7p80waJsAqFP8HZfb0Jg=="],
|
||||
|
||||
"@streamdown/math": ["@streamdown/math@1.0.2", "", { "dependencies": { "katex": "^0.16.27", "rehype-katex": "^7.0.1", "remark-math": "^6.0.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-r8Ur9/lBuFnzZAFdEWrLUF2s/gRwRRRwruqltdZibyjbCBnuW7SJbFm26nXqvpJPW/gzpBUMrBVBzd88z05D5g=="],
|
||||
|
||||
"@streamdown/mermaid": ["@streamdown/mermaid@1.0.2", "", { "dependencies": { "mermaid": "^11.12.2" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-Fr/4sBWnAeSnxM3PcrV/+DiZe5oPMq9gOkUIAH7ZauJeuwrZ/DVzD4g0zlav6AH0axh2m/sOfrfLtY5aLT7niw=="],
|
||||
|
||||
"@t3-oss/env-core": ["@t3-oss/env-core@0.13.11", "", { "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-sM7GYY+KL7H/Hl0BE0inWfk3nRHZOLhmVn7sHGxaZt9FAR6KqREXAE+6TqKfiavfXmpRxO/OZ2QgKRd+oiBYRQ=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="],
|
||||
@@ -1572,6 +1610,8 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/katex": ["@types/katex@0.16.8", "", {}, "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg=="],
|
||||
|
||||
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
||||
|
||||
"@types/mime-types": ["@types/mime-types@2.1.4", "", {}, "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w=="],
|
||||
@@ -1630,6 +1670,8 @@
|
||||
|
||||
"@vercel/detect-agent": ["@vercel/detect-agent@1.2.3", "", {}, "sha512-VYNCgUc0nOmC4WJmWw9GkrKdfr8Zl4/rxhC5SvgacBgxiW9W/9NRttUoHHXV8xdII3MaRgkZZVX8Ikzc/Jmjag=="],
|
||||
|
||||
"@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="],
|
||||
|
||||
"@vitest/browser": ["@vitest/browser@4.1.9", "", { "dependencies": { "@blazediff/core": "1.9.1", "@vitest/mocker": "4.1.9", "@vitest/utils": "4.1.9", "magic-string": "^0.30.21", "pngjs": "^7.0.0", "sirv": "^3.0.2", "tinyrainbow": "^3.1.0", "ws": "^8.19.0" }, "peerDependencies": { "vitest": "4.1.9" } }, "sha512-j1BKtWmPcqpMhmx/L9EPLgAJpCb0zKfwoWLmqBbxaogCXHjOwHFSEoHCBfnGtx93xKQwilZ26m+UOsHqHMkRNg=="],
|
||||
|
||||
"@vitest/browser-preview": ["@vitest/browser-preview@4.1.9", "", { "dependencies": { "@testing-library/dom": "^10.4.1", "@testing-library/user-event": "^14.6.1", "@vitest/browser": "4.1.9" }, "peerDependencies": { "vitest": "4.1.9" } }, "sha512-a4/OrkMDb/WUnE4OOB/4FJbK3rYVO7YykqtUgcTKG4p2a0R3XcjPVu7SLRHFBs2+NIYhv5yxp1Lz3dbdGBjIow=="],
|
||||
@@ -1666,6 +1708,8 @@
|
||||
|
||||
"@voidzero-dev/vite-plus-win32-x64-msvc": ["@voidzero-dev/vite-plus-win32-x64-msvc@0.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-+VUui1OIaFX0tqdUAXjmoKVlujEtWVdcsFDw2Jff+D6b4LUTQaOMAaaic8nNdfZL6wEjweRREQLZi/icZAXtNQ=="],
|
||||
|
||||
"@workflow/serde": ["@workflow/serde@4.1.0", "", {}, "sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ=="],
|
||||
|
||||
"@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="],
|
||||
|
||||
"@xterm/headless": ["@xterm/headless@6.0.0", "", {}, "sha512-5Yj1QINYCyzrZtf8OFIHi47iQtI+0qYFPHmouEfG8dHNxbZ9Tb9YGSuLcsEwj9Z+OL75GJqPyJbyoFer80a2Hw=="],
|
||||
@@ -1682,6 +1726,8 @@
|
||||
|
||||
"agent-cli-detector": ["agent-cli-detector@0.1.4", "", { "bin": { "agent-cli-detector": "dist/cli.js" } }, "sha512-qPgevFvpaQoBaRJVKzr8R7h1WPvV3DtbgRIQlne4le66KBzXx5hNBwo/+NTw67LgkKBlhCzksrdautpUdlls0Q=="],
|
||||
|
||||
"ai": ["ai@7.0.36", "", { "dependencies": { "@ai-sdk/gateway": "4.0.27", "@ai-sdk/provider": "4.0.3", "@ai-sdk/provider-utils": "5.0.12" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-1XJjua58GVQ0CyO2Xbioyladt85x71Joup2U8qKrjHUl8tHYwrDw8iFRtav6e94AxSVCn9FVgTS17oX1OCquKA=="],
|
||||
|
||||
"ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="],
|
||||
|
||||
"ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
|
||||
@@ -2028,7 +2074,7 @@
|
||||
|
||||
"d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
|
||||
|
||||
"d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="],
|
||||
"d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
|
||||
|
||||
"d3-polygon": ["d3-polygon@3.0.1", "", {}, "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="],
|
||||
|
||||
@@ -2168,7 +2214,7 @@
|
||||
|
||||
"enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="],
|
||||
|
||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
|
||||
|
||||
@@ -2448,18 +2494,30 @@
|
||||
|
||||
"hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
|
||||
|
||||
"hast-util-from-dom": ["hast-util-from-dom@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hastscript": "^9.0.0", "web-namespaces": "^2.0.0" } }, "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q=="],
|
||||
|
||||
"hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="],
|
||||
|
||||
"hast-util-from-html-isomorphic": ["hast-util-from-html-isomorphic@2.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-dom": "^5.0.0", "hast-util-from-html": "^2.0.0", "unist-util-remove-position": "^5.0.0" } }, "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw=="],
|
||||
|
||||
"hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="],
|
||||
|
||||
"hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="],
|
||||
|
||||
"hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="],
|
||||
|
||||
"hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
|
||||
|
||||
"hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "unist-util-position": "^5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="],
|
||||
|
||||
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
|
||||
|
||||
"hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="],
|
||||
|
||||
"hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="],
|
||||
|
||||
"hast-util-to-text": ["hast-util-to-text@4.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "hast-util-is-element": "^3.0.0", "unist-util-find-after": "^5.0.0" } }, "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A=="],
|
||||
|
||||
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
|
||||
|
||||
"hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
|
||||
@@ -2628,6 +2686,8 @@
|
||||
|
||||
"json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
|
||||
|
||||
"json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="],
|
||||
|
||||
"json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="],
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||
@@ -2734,7 +2794,7 @@
|
||||
|
||||
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
|
||||
|
||||
"marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="],
|
||||
"marked": ["marked@17.0.6", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA=="],
|
||||
|
||||
"marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="],
|
||||
|
||||
@@ -2758,6 +2818,8 @@
|
||||
|
||||
"mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="],
|
||||
|
||||
"mdast-util-math": ["mdast-util-math@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "longest-streak": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.1.0", "unist-util-remove-position": "^5.0.0" } }, "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w=="],
|
||||
|
||||
"mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="],
|
||||
|
||||
"mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="],
|
||||
@@ -2770,6 +2832,10 @@
|
||||
|
||||
"mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="],
|
||||
|
||||
"mdast-util-to-markdown-cjk-friendly": ["mdast-util-to-markdown-cjk-friendly@1.0.0", "", { "dependencies": { "mdast-util-to-markdown": "^2.1.2", "micromark-extension-cjk-friendly-util": "3.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "@types/mdast": "*" }, "optionalPeers": ["@types/mdast"] }, "sha512-BoaAm8mlJ+LAYz0Qs532Y3ciTuQYgBUPZcSFbvC/ZKmEMAKgulw84YvQK1gI34t/vL2euSfuaWlqczkTBgamkw=="],
|
||||
|
||||
"mdast-util-to-markdown-cjk-friendly-gfm-strikethrough": ["mdast-util-to-markdown-cjk-friendly-gfm-strikethrough@1.0.0", "", { "dependencies": { "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-to-markdown": "^2.1.2", "micromark-extension-cjk-friendly-util": "3.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "@types/mdast": "*" }, "optionalPeers": ["@types/mdast"] }, "sha512-1ePVfB4P/vz3xSsm6H3D32r6VYGErxclnuLLFK02/2ReF+UdEKm7caulK6Vm0LBIp5gPRtB2Z1OYDznCkX3k2w=="],
|
||||
|
||||
"mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="],
|
||||
|
||||
"mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="],
|
||||
@@ -2820,6 +2886,12 @@
|
||||
|
||||
"micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="],
|
||||
|
||||
"micromark-extension-cjk-friendly": ["micromark-extension-cjk-friendly@2.0.1", "", { "dependencies": { "devlop": "^1.1.0", "micromark-extension-cjk-friendly-util": "3.0.1", "micromark-util-chunked": "^2.0.1", "micromark-util-resolve-all": "^2.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "micromark": "^4.0.0", "micromark-util-types": "^2.0.0" }, "optionalPeers": ["micromark-util-types"] }, "sha512-OkzoYVTL1ChbvQ8Cc1ayTIz7paFQz8iS9oIYmewncweUSwmWR+hkJF9spJ1lxB90XldJl26A1F4IkPOKS3bDXw=="],
|
||||
|
||||
"micromark-extension-cjk-friendly-gfm-strikethrough": ["micromark-extension-cjk-friendly-gfm-strikethrough@2.0.1", "", { "dependencies": { "devlop": "^1.1.0", "get-east-asian-width": "^1.4.0", "micromark-extension-cjk-friendly-util": "3.0.1", "micromark-util-character": "^2.1.1", "micromark-util-chunked": "^2.0.1", "micromark-util-resolve-all": "^2.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "micromark": "^4.0.0", "micromark-util-types": "^2.0.0" }, "optionalPeers": ["micromark-util-types"] }, "sha512-wVC0zwjJNqQeX+bb07YTPu/CvSAyCTafyYb7sMhX1r62/Lw5M/df3JyYaANyp8g15c1ypJRFSsookTqA1IDsUg=="],
|
||||
|
||||
"micromark-extension-cjk-friendly-util": ["micromark-extension-cjk-friendly-util@3.0.1", "", { "dependencies": { "get-east-asian-width": "^1.4.0", "micromark-util-character": "^2.1.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "micromark-util-types": "*" }, "optionalPeers": ["micromark-util-types"] }, "sha512-GcbXqTTHOsiZHyF753oIddP/J2eH8j9zpyQPhkof6B2JNxfEJabnQqxbCgzJNuNes0Y2jTNJ3LiYPSXr6eJA8w=="],
|
||||
|
||||
"micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="],
|
||||
|
||||
"micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="],
|
||||
@@ -2834,6 +2906,8 @@
|
||||
|
||||
"micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="],
|
||||
|
||||
"micromark-extension-math": ["micromark-extension-math@3.1.0", "", { "dependencies": { "@types/katex": "^0.16.0", "devlop": "^1.0.0", "katex": "^0.16.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg=="],
|
||||
|
||||
"micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="],
|
||||
|
||||
"micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="],
|
||||
@@ -3004,6 +3078,10 @@
|
||||
|
||||
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
||||
|
||||
"oniguruma-parser": ["oniguruma-parser@0.12.2", "", {}, "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw=="],
|
||||
|
||||
"oniguruma-to-es": ["oniguruma-to-es@4.3.6", "", { "dependencies": { "oniguruma-parser": "^0.12.2", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA=="],
|
||||
|
||||
"open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="],
|
||||
|
||||
"openai": ["openai@6.26.0", "", { "peerDependencies": { "ws": "^8.18.0", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA=="],
|
||||
@@ -3278,6 +3356,12 @@
|
||||
|
||||
"regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="],
|
||||
|
||||
"regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="],
|
||||
|
||||
"regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="],
|
||||
|
||||
"regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="],
|
||||
|
||||
"regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.2", "regjsgen": "^0.8.0", "regjsparser": "^0.13.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
|
||||
|
||||
"regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="],
|
||||
@@ -3286,12 +3370,20 @@
|
||||
|
||||
"rehype-harden": ["rehype-harden@1.1.8", "", { "dependencies": { "unist-util-visit": "^5.0.0" } }, "sha512-Qn7vR1xrf6fZCrkm9TDWi/AB4ylrHy+jqsNm1EHOAmbARYA6gsnVJBq/sdBh6kmT4NEZxH5vgIjrscefJAOXcw=="],
|
||||
|
||||
"rehype-katex": ["rehype-katex@7.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/katex": "^0.16.0", "hast-util-from-html-isomorphic": "^2.0.0", "hast-util-to-text": "^4.0.0", "katex": "^0.16.0", "unist-util-visit-parents": "^6.0.0", "vfile": "^6.0.0" } }, "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA=="],
|
||||
|
||||
"rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="],
|
||||
|
||||
"rehype-sanitize": ["rehype-sanitize@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-sanitize": "^5.0.0" } }, "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg=="],
|
||||
|
||||
"remark-cjk-friendly": ["remark-cjk-friendly@2.3.1", "", { "dependencies": { "mdast-util-to-markdown-cjk-friendly": "1.0.0", "micromark-extension-cjk-friendly": "2.0.1" }, "peerDependencies": { "@types/mdast": "^4.0.0", "unified": "^11.0.0" }, "optionalPeers": ["@types/mdast"] }, "sha512-f+pKZRxCRwNEGFBKNRAZAqU91GIK1SAo3ZyFHWRUgC9zcxRR0BXKd6YwqgSsxtW0rNpUDtONj7H5nje2WL3fcA=="],
|
||||
|
||||
"remark-cjk-friendly-gfm-strikethrough": ["remark-cjk-friendly-gfm-strikethrough@2.3.1", "", { "dependencies": { "mdast-util-to-markdown-cjk-friendly-gfm-strikethrough": "1.0.0", "micromark-extension-cjk-friendly-gfm-strikethrough": "2.0.1" }, "peerDependencies": { "@types/mdast": "^4.0.0", "unified": "^11.0.0" }, "optionalPeers": ["@types/mdast"] }, "sha512-JE3TGgouk/sy92SemNMEUhO5mNP4on04cmzOV3s3R5Dbk160ewmpM4tgPiinKKvoJ5UW2fTu7FOYsjVbusSA9w=="],
|
||||
|
||||
"remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="],
|
||||
|
||||
"remark-math": ["remark-math@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-math": "^3.0.0", "micromark-extension-math": "^3.0.0", "unified": "^11.0.0" } }, "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA=="],
|
||||
|
||||
"remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="],
|
||||
|
||||
"remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="],
|
||||
@@ -3396,6 +3488,8 @@
|
||||
|
||||
"shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="],
|
||||
|
||||
"shiki": ["shiki@4.3.1", "", { "dependencies": { "@shikijs/core": "4.3.1", "@shikijs/engine-javascript": "4.3.1", "@shikijs/engine-oniguruma": "4.3.1", "@shikijs/langs": "4.3.1", "@shikijs/themes": "4.3.1", "@shikijs/types": "4.3.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw=="],
|
||||
|
||||
"side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="],
|
||||
|
||||
"side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="],
|
||||
@@ -3644,10 +3738,14 @@
|
||||
|
||||
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
|
||||
|
||||
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
|
||||
|
||||
"unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
|
||||
|
||||
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
|
||||
|
||||
"unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
|
||||
|
||||
"unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
|
||||
|
||||
"unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
|
||||
@@ -3674,6 +3772,8 @@
|
||||
|
||||
"use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
|
||||
|
||||
"use-stick-to-bottom": ["use-stick-to-bottom@1.1.6", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-z3Up8jYQGTkUCsGBnwg6/wj70KgXoW5Kz1AAc1j8MtQuYMBo6ZsdhrIXoegxa7gaMMilgQYyTohTrt3p94jHog=="],
|
||||
|
||||
"use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
|
||||
|
||||
"util": ["util@0.12.5", "", { "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", "which-typed-array": "^1.1.2" } }, "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA=="],
|
||||
@@ -3900,6 +4000,8 @@
|
||||
|
||||
"@opentui/core/diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="],
|
||||
|
||||
"@opentui/core/marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="],
|
||||
|
||||
"@react-native/dev-middleware/open": ["open@7.4.2", "", { "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="],
|
||||
|
||||
"@react-native/dev-middleware/serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="],
|
||||
@@ -3922,6 +4024,8 @@
|
||||
|
||||
"@secure-exec/nodejs/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="],
|
||||
|
||||
"@streamdown/code/shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="],
|
||||
|
||||
"@tailwindcss/node/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
|
||||
@@ -4008,24 +4112,24 @@
|
||||
|
||||
"d3/d3-hierarchy": ["d3-hierarchy@3.1.2", "", {}, "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="],
|
||||
|
||||
"d3/d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
|
||||
|
||||
"d3/d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
|
||||
|
||||
"d3-chord/d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
|
||||
|
||||
"d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||
|
||||
"d3-dsv/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="],
|
||||
|
||||
"d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="],
|
||||
|
||||
"defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
|
||||
|
||||
"degenerator/ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="],
|
||||
|
||||
"diffie-hellman/bn.js": ["bn.js@4.12.5", "", {}, "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ=="],
|
||||
|
||||
"dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="],
|
||||
|
||||
"elliptic/bn.js": ["bn.js@4.12.5", "", {}, "sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ=="],
|
||||
@@ -4140,8 +4244,6 @@
|
||||
|
||||
"parse-png/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="],
|
||||
|
||||
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="],
|
||||
|
||||
"path-scurry/lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="],
|
||||
@@ -4214,8 +4316,6 @@
|
||||
|
||||
"stacktrace-parser/type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="],
|
||||
|
||||
"streamdown/marked": ["marked@17.0.6", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-gB0gkNafnonOw0obSTEGZTT86IuhILt2Wfx0mWH/1Au83kybTayroZ/V6nS25mN7u8ASy+5fMhgB3XPNrOZdmA=="],
|
||||
|
||||
"string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
||||
|
||||
"strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||
@@ -4470,6 +4570,18 @@
|
||||
|
||||
"@secure-exec/nodejs/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="],
|
||||
|
||||
"@streamdown/code/shiki/@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="],
|
||||
|
||||
"@streamdown/code/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="],
|
||||
|
||||
"@streamdown/code/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="],
|
||||
|
||||
"@streamdown/code/shiki/@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="],
|
||||
|
||||
"@streamdown/code/shiki/@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="],
|
||||
|
||||
"@streamdown/code/shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="],
|
||||
|
||||
"@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||
|
||||
"@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
||||
|
||||
8
packages/backend/convex/_generated/api.d.ts
vendored
8
packages/backend/convex/_generated/api.d.ts
vendored
@@ -12,6 +12,7 @@ import type * as agentWorkspace from "../agentWorkspace.js";
|
||||
import type * as artifactModel from "../artifactModel.js";
|
||||
import type * as auth from "../auth.js";
|
||||
import type * as authz from "../authz.js";
|
||||
import type * as conversationMessages from "../conversationMessages.js";
|
||||
import type * as daemonCommands from "../daemonCommands.js";
|
||||
import type * as daemonRuntime from "../daemonRuntime.js";
|
||||
import type * as daemons from "../daemons.js";
|
||||
@@ -22,7 +23,10 @@ import type * as organizations from "../organizations.js";
|
||||
import type * as privateData from "../privateData.js";
|
||||
import type * as projectArtifacts from "../projectArtifacts.js";
|
||||
import type * as projectIssues from "../projectIssues.js";
|
||||
import type * as projectStore from "../projectStore.js";
|
||||
import type * as projects from "../projects.js";
|
||||
import type * as publicGit from "../publicGit.js";
|
||||
import type * as signals from "../signals.js";
|
||||
import type * as todos from "../todos.js";
|
||||
|
||||
import type {
|
||||
@@ -36,6 +40,7 @@ declare const fullApi: ApiFromModules<{
|
||||
artifactModel: typeof artifactModel;
|
||||
auth: typeof auth;
|
||||
authz: typeof authz;
|
||||
conversationMessages: typeof conversationMessages;
|
||||
daemonCommands: typeof daemonCommands;
|
||||
daemonRuntime: typeof daemonRuntime;
|
||||
daemons: typeof daemons;
|
||||
@@ -46,7 +51,10 @@ declare const fullApi: ApiFromModules<{
|
||||
privateData: typeof privateData;
|
||||
projectArtifacts: typeof projectArtifacts;
|
||||
projectIssues: typeof projectIssues;
|
||||
projectStore: typeof projectStore;
|
||||
projects: typeof projects;
|
||||
publicGit: typeof publicGit;
|
||||
signals: typeof signals;
|
||||
todos: typeof todos;
|
||||
}>;
|
||||
|
||||
|
||||
125
packages/backend/convex/publicGit.ts
Normal file
125
packages/backend/convex/publicGit.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import {
|
||||
CONTEXT_KINDS,
|
||||
contextPathForKind,
|
||||
MAX_CONTEXT_DOCUMENT_CHARACTERS,
|
||||
type PreparedPublicGitSource,
|
||||
type PublicGitImportResult,
|
||||
type RepositoryContextDocument,
|
||||
} from "@code/primitives/project";
|
||||
|
||||
const GITHUB_HOST = "github.com";
|
||||
const REQUEST_HEADERS = {
|
||||
Accept: "application/vnd.github+json",
|
||||
"User-Agent": "zopu-project-importer",
|
||||
} as const;
|
||||
|
||||
const candidatePaths = {
|
||||
agents: ["AGENTS.md"],
|
||||
business: ["business.md", "docs/business.md"],
|
||||
design: ["design.md", "docs/design.md"],
|
||||
product: ["product.md", "docs/product.md"],
|
||||
readme: ["README.md", "README", "readme.md"],
|
||||
tech: ["tech.md", "docs/tech.md"],
|
||||
} as const;
|
||||
|
||||
const encodePath = (path: string) =>
|
||||
path
|
||||
.split("/")
|
||||
.map((segment) => encodeURIComponent(segment))
|
||||
.join("/");
|
||||
|
||||
const fetchTextCandidate = async (
|
||||
repositoryPath: string,
|
||||
branch: string,
|
||||
path: string
|
||||
): Promise<string | null> => {
|
||||
const url = `https://raw.githubusercontent.com/${encodePath(repositoryPath)}/${encodePath(branch)}/${encodePath(path)}`;
|
||||
const response = await fetch(url, { headers: REQUEST_HEADERS });
|
||||
if (response.status === 404) {
|
||||
return null;
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error(`GitHub returned ${response.status} for ${path}`);
|
||||
}
|
||||
const content = await response.text();
|
||||
if (content.trim().length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (content.length > MAX_CONTEXT_DOCUMENT_CHARACTERS) {
|
||||
throw new Error(`${path} exceeds the 200000 character import limit`);
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
const fetchContextDocument = async (
|
||||
source: PreparedPublicGitSource,
|
||||
branch: string,
|
||||
kind: (typeof CONTEXT_KINDS)[number]
|
||||
): Promise<RepositoryContextDocument | null> => {
|
||||
for (const candidate of candidatePaths[kind]) {
|
||||
const content = await fetchTextCandidate(
|
||||
source.repositoryPath,
|
||||
branch,
|
||||
candidate
|
||||
);
|
||||
if (content) {
|
||||
return {
|
||||
content,
|
||||
kind,
|
||||
path: contextPathForKind(kind),
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const readDefaultBranch = async (
|
||||
source: PreparedPublicGitSource
|
||||
): Promise<string> => {
|
||||
if (source.host !== GITHUB_HOST) {
|
||||
throw new Error("Repository import currently supports public GitHub URLs");
|
||||
}
|
||||
const response = await fetch(
|
||||
`https://api.github.com/repos/${encodePath(source.repositoryPath)}`,
|
||||
{ headers: REQUEST_HEADERS }
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
response.status === 404
|
||||
? "Public GitHub repository not found"
|
||||
: `GitHub returned ${response.status} while reading the repository`
|
||||
);
|
||||
}
|
||||
const metadata = (await response.json()) as { default_branch?: unknown };
|
||||
if (
|
||||
typeof metadata.default_branch !== "string" ||
|
||||
metadata.default_branch.length === 0
|
||||
) {
|
||||
throw new Error("GitHub did not return a default branch");
|
||||
}
|
||||
return metadata.default_branch;
|
||||
};
|
||||
|
||||
export const inspectPublicGit = async (
|
||||
source: PreparedPublicGitSource
|
||||
): Promise<PublicGitImportResult> => {
|
||||
const defaultBranch = await readDefaultBranch(source);
|
||||
const candidates = await Promise.all(
|
||||
CONTEXT_KINDS.map((kind) =>
|
||||
fetchContextDocument(source, defaultBranch, kind)
|
||||
)
|
||||
);
|
||||
const documents = candidates.filter(
|
||||
(document): document is RepositoryContextDocument => document !== null
|
||||
);
|
||||
return {
|
||||
defaultBranch,
|
||||
documents,
|
||||
warnings: CONTEXT_KINDS.filter(
|
||||
(kind) => !documents.some((document) => document.kind === kind)
|
||||
).map((kind) => ({
|
||||
message: "Canonical context file was not found in the repository",
|
||||
path: contextPathForKind(kind),
|
||||
})),
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,10 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { getProjectWorkProgress, getProjectWorkStatus } from "./project-work";
|
||||
import {
|
||||
getProjectWorkNextAction,
|
||||
getProjectWorkProgress,
|
||||
getProjectWorkStatus,
|
||||
} from "./project-work";
|
||||
|
||||
describe("project work state mapping", () => {
|
||||
test("maps issue and run statuses to the same product language", () => {
|
||||
@@ -27,4 +31,14 @@ describe("project work state mapping", () => {
|
||||
getProjectWorkProgress("completed")
|
||||
);
|
||||
});
|
||||
|
||||
test("maps each state to the next product action", () => {
|
||||
expect(getProjectWorkNextAction("open")).toBe("Start the project manager");
|
||||
expect(getProjectWorkNextAction("failed")).toBe(
|
||||
"Review the failure and retry"
|
||||
);
|
||||
expect(getProjectWorkNextAction("completed")).toBe(
|
||||
"Review the pull request"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,6 +41,18 @@ export interface ProjectWorkStatus {
|
||||
readonly verification: ProjectVerificationStatus;
|
||||
}
|
||||
|
||||
const NEXT_ACTION_MAP: Readonly<
|
||||
Record<ProjectIssueStatus | ProjectRunStatus, string>
|
||||
> = {
|
||||
completed: "Review the pull request",
|
||||
failed: "Review the failure and retry",
|
||||
"needs-input": "Resolve the open question",
|
||||
open: "Start the project manager",
|
||||
queued: "Watch the run progress",
|
||||
ready: "Watch the run progress",
|
||||
working: "Wait for verification",
|
||||
};
|
||||
|
||||
const STATUS_MAP: Readonly<
|
||||
Record<ProjectIssueStatus | ProjectRunStatus, ProjectWorkStatus>
|
||||
> = {
|
||||
@@ -113,3 +125,7 @@ export const getProjectWorkProgress = (
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const getProjectWorkNextAction = (
|
||||
status: ProjectIssueStatus | ProjectRunStatus
|
||||
): string => NEXT_ACTION_MAP[status];
|
||||
|
||||
@@ -8,6 +8,7 @@ export {
|
||||
export type {
|
||||
MobileAssistantMessageView,
|
||||
MobileAssistantView,
|
||||
MobileProjectView,
|
||||
MobileSignalView,
|
||||
MobileWorkspaceScreenProps,
|
||||
MobileWorkspaceView,
|
||||
|
||||
@@ -4,8 +4,10 @@ import {
|
||||
ArrowUp,
|
||||
Check,
|
||||
ChevronRight,
|
||||
ExternalLink,
|
||||
FileText,
|
||||
ListChecks,
|
||||
LoaderCircle,
|
||||
Mic,
|
||||
MoreHorizontal,
|
||||
Paperclip,
|
||||
@@ -16,6 +18,7 @@ import {
|
||||
import type { FormEvent, ReactNode } from "react";
|
||||
|
||||
import type {
|
||||
MobileProjectView,
|
||||
MobileWorkspaceView,
|
||||
MobileWorkUnitTone,
|
||||
MobileWorkUnitView,
|
||||
@@ -30,14 +33,24 @@ export type MobileWorkspaceVariant =
|
||||
|
||||
export interface MobileWorkspaceRendererProps {
|
||||
composerValue: string;
|
||||
createIssueBody: string;
|
||||
createIssueTitle: string;
|
||||
data: MobileWorkspaceView;
|
||||
onBack?: () => void;
|
||||
onComposerChange: (value: string) => void;
|
||||
onComposerSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
||||
onCreateBodyChange: (value: string) => void;
|
||||
onCreateIssue: (event: FormEvent<HTMLFormElement>) => void;
|
||||
onCreateIssueFromSignal?: () => void;
|
||||
onCreateTitleChange: (value: string) => void;
|
||||
onManageProjects?: () => void;
|
||||
onOpenAssistant?: () => void;
|
||||
onOpenUnit?: (workUnitId?: string) => void;
|
||||
onProjectSelect?: (projectId: string) => void;
|
||||
onReviewUnit?: (reviewUrl: string) => void;
|
||||
onStartUnit?: (workUnitId: string) => void;
|
||||
onViewWork?: () => void;
|
||||
pendingAction?: string | null;
|
||||
statusMessage?: string;
|
||||
variant: MobileWorkspaceVariant;
|
||||
}
|
||||
@@ -203,6 +216,142 @@ const ReferenceComposer = ({
|
||||
</footer>
|
||||
);
|
||||
|
||||
interface CreateWorkFormProps {
|
||||
readonly body: string;
|
||||
readonly onBodyChange: (value: string) => void;
|
||||
readonly onSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
||||
readonly onTitleChange: (value: string) => void;
|
||||
readonly pending: boolean;
|
||||
readonly title: string;
|
||||
}
|
||||
|
||||
const CreateWorkForm = ({
|
||||
body,
|
||||
onBodyChange,
|
||||
onSubmit,
|
||||
onTitleChange,
|
||||
pending,
|
||||
title,
|
||||
}: CreateWorkFormProps) => (
|
||||
<form className="mt-4 rounded-[22px] bg-white p-3" onSubmit={onSubmit}>
|
||||
<div className="flex items-center">
|
||||
<p className="text-[10px] font-semibold uppercase text-[#807b76]">
|
||||
Create project work
|
||||
</p>
|
||||
{pending ? (
|
||||
<LoaderCircle className="ml-auto size-3 animate-spin" />
|
||||
) : null}
|
||||
</div>
|
||||
<input
|
||||
aria-label="Work title"
|
||||
className="mt-2 h-9 w-full rounded-[12px] bg-[#f2f3ef] px-3 text-[13px] outline-none placeholder:text-[#b3afab]"
|
||||
disabled={pending}
|
||||
onChange={(event) => onTitleChange(event.target.value)}
|
||||
placeholder="Outcome or issue title"
|
||||
required
|
||||
value={title}
|
||||
/>
|
||||
<textarea
|
||||
aria-label="Work description"
|
||||
className="mt-2 min-h-16 w-full resize-none rounded-[12px] bg-[#f2f3ef] px-3 py-2 text-[12px] leading-4 outline-none placeholder:text-[#b3afab]"
|
||||
disabled={pending}
|
||||
onChange={(event) => onBodyChange(event.target.value)}
|
||||
placeholder="Describe the desired result or constraints"
|
||||
required
|
||||
value={body}
|
||||
/>
|
||||
<button
|
||||
className="mt-2 h-9 w-full rounded-[12px] bg-black text-[12px] font-semibold text-white disabled:opacity-50"
|
||||
disabled={pending || !title.trim() || !body.trim()}
|
||||
type="submit"
|
||||
>
|
||||
{pending ? "Creating…" : "Create work"}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
|
||||
const ProjectSwitcher = ({
|
||||
data,
|
||||
onManageProjects,
|
||||
onProjectSelect,
|
||||
}: {
|
||||
readonly data: MobileWorkspaceView;
|
||||
readonly onManageProjects?: () => void;
|
||||
readonly onProjectSelect?: (projectId: string) => void;
|
||||
}) => (
|
||||
<div className="flex items-center gap-2 border-b border-[#eff0ec] bg-white px-4 py-2">
|
||||
<label className="sr-only" htmlFor="mobile-project-selector">
|
||||
Active project
|
||||
</label>
|
||||
<select
|
||||
className="min-w-0 flex-1 bg-transparent text-[12px] font-semibold outline-none"
|
||||
id="mobile-project-selector"
|
||||
onChange={(event) => onProjectSelect?.(event.target.value)}
|
||||
value={data.selectedProjectId ?? ""}
|
||||
>
|
||||
{data.projects.length === 0 ? (
|
||||
<option value="">No connected projects</option>
|
||||
) : (
|
||||
data.projects.map((project: MobileProjectView) => (
|
||||
<option key={project.id} value={project.id}>
|
||||
{project.name} {project.connected ? "" : "(not connected)"}
|
||||
</option>
|
||||
))
|
||||
)}
|
||||
</select>
|
||||
<button
|
||||
aria-label="Manage projects"
|
||||
className="flex size-8 items-center justify-center rounded-full bg-[#f2f3ef]"
|
||||
onClick={onManageProjects}
|
||||
type="button"
|
||||
>
|
||||
<MoreHorizontal className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const WorkUnitActions = ({
|
||||
onReview,
|
||||
onStart,
|
||||
pending,
|
||||
workUnit,
|
||||
}: {
|
||||
readonly onReview?: (reviewUrl: string) => void;
|
||||
readonly onStart?: (workUnitId: string) => void;
|
||||
readonly pending: boolean;
|
||||
readonly workUnit?: MobileWorkUnitView;
|
||||
}) => {
|
||||
if (!workUnit) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className="mt-3 flex gap-2">
|
||||
{workUnit.canStart || workUnit.canRetry ? (
|
||||
<button
|
||||
className="flex h-9 flex-1 items-center justify-center gap-2 rounded-[12px] bg-black text-[12px] font-semibold text-white disabled:opacity-50"
|
||||
disabled={pending}
|
||||
onClick={() => onStart?.(workUnit.id)}
|
||||
type="button"
|
||||
>
|
||||
{pending ? <LoaderCircle className="size-3 animate-spin" /> : null}
|
||||
{workUnit.canRetry ? "Retry work" : "Start work"}
|
||||
</button>
|
||||
) : null}
|
||||
{workUnit.reviewUrl ? (
|
||||
<button
|
||||
className="flex h-9 flex-1 items-center justify-center gap-2 rounded-[12px] bg-[#c8ff00] text-[12px] font-semibold text-black"
|
||||
onClick={() => onReview?.(workUnit.reviewUrl as string)}
|
||||
type="button"
|
||||
>
|
||||
<ExternalLink className="size-3.5" />
|
||||
Review PR
|
||||
{workUnit.pullRequestNumber ? ` #${workUnit.pullRequestNumber}` : ""}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const workUnitToneClass: Record<MobileWorkUnitTone, string> = {
|
||||
blue: "bg-[#e8efff] text-[#14265f]",
|
||||
green: "bg-[#e8f7ef] text-[#105c35]",
|
||||
@@ -250,20 +399,38 @@ const EmptyWorkState = ({
|
||||
);
|
||||
|
||||
const WorkFeedScreen = ({
|
||||
createIssueBody,
|
||||
createIssueTitle,
|
||||
data,
|
||||
onChange,
|
||||
onCreateBodyChange,
|
||||
onCreateIssue,
|
||||
onCreateTitleChange,
|
||||
onManageProjects,
|
||||
onOpenAssistant,
|
||||
onOpen,
|
||||
onProjectSelect,
|
||||
onReviewUnit,
|
||||
onStartUnit,
|
||||
onSubmit,
|
||||
onViewWork,
|
||||
pendingAction,
|
||||
statusMessage,
|
||||
value,
|
||||
}: ComposerProps & {
|
||||
createIssueBody: string;
|
||||
createIssueTitle: string;
|
||||
data: MobileWorkspaceView;
|
||||
onCreateBodyChange: (value: string) => void;
|
||||
onCreateIssue: (event: FormEvent<HTMLFormElement>) => void;
|
||||
onCreateTitleChange: (value: string) => void;
|
||||
onManageProjects?: () => void;
|
||||
onOpen?: (workUnitId?: string) => void;
|
||||
onOpenAssistant?: () => void;
|
||||
onProjectSelect?: (projectId: string) => void;
|
||||
onReviewUnit?: (reviewUrl: string) => void;
|
||||
onStartUnit?: (workUnitId: string) => void;
|
||||
pendingAction?: string | null;
|
||||
onViewWork?: () => void;
|
||||
}) => {
|
||||
const primaryWorkUnit = data.selectedWorkUnit;
|
||||
@@ -278,6 +445,11 @@ const WorkFeedScreen = ({
|
||||
onManageProjects={onManageProjects}
|
||||
subtitle={`${data.activeCount} active work units`}
|
||||
/>
|
||||
<ProjectSwitcher
|
||||
data={data}
|
||||
onManageProjects={onManageProjects}
|
||||
onProjectSelect={onProjectSelect}
|
||||
/>
|
||||
<main className="min-h-0 flex-1 bg-[#f7f8f5] px-4 pt-4">
|
||||
<h2 className="text-[29px] leading-9 font-semibold tracking-[-0.05em]">
|
||||
Good morning.
|
||||
@@ -372,6 +544,12 @@ const WorkFeedScreen = ({
|
||||
Open unit →
|
||||
</button>
|
||||
</div>
|
||||
<WorkUnitActions
|
||||
onReview={onReviewUnit}
|
||||
onStart={onStartUnit}
|
||||
pending={pendingAction === `issue:${primaryWorkUnit.id}`}
|
||||
workUnit={primaryWorkUnit}
|
||||
/>
|
||||
</article>
|
||||
) : (
|
||||
<EmptyWorkState
|
||||
@@ -379,6 +557,14 @@ const WorkFeedScreen = ({
|
||||
onManageProjects={onManageProjects}
|
||||
/>
|
||||
)}
|
||||
<CreateWorkForm
|
||||
body={createIssueBody}
|
||||
onBodyChange={onCreateBodyChange}
|
||||
onSubmit={onCreateIssue}
|
||||
onTitleChange={onCreateTitleChange}
|
||||
pending={pendingAction === "issue"}
|
||||
title={createIssueTitle}
|
||||
/>
|
||||
{secondaryWorkUnits[0] ? (
|
||||
<article
|
||||
className={cn(
|
||||
@@ -592,9 +778,15 @@ const ExpandedWorkUnitActivity = ({
|
||||
const ExpandedWorkUnitContent = ({
|
||||
compact = false,
|
||||
data,
|
||||
onReview,
|
||||
onStart,
|
||||
pendingAction,
|
||||
}: {
|
||||
compact?: boolean;
|
||||
data: MobileWorkspaceView;
|
||||
onReview?: (reviewUrl: string) => void;
|
||||
onStart?: (workUnitId: string) => void;
|
||||
pendingAction?: string | null;
|
||||
}) => {
|
||||
const workUnit = data.selectedWorkUnit;
|
||||
const title = getExpandedTitle(workUnit, data.isLoading);
|
||||
@@ -689,22 +881,46 @@ const ExpandedWorkUnitContent = ({
|
||||
data={data}
|
||||
workUnit={workUnit}
|
||||
/>
|
||||
<WorkUnitActions
|
||||
onReview={onReview}
|
||||
onStart={onStart}
|
||||
pending={pendingAction === `issue:${workUnit?.id}`}
|
||||
workUnit={workUnit}
|
||||
/>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
|
||||
const WorkUnitScreen = ({
|
||||
createIssueBody,
|
||||
createIssueTitle,
|
||||
data,
|
||||
onBack,
|
||||
onChange,
|
||||
onCreateBodyChange,
|
||||
onCreateIssue,
|
||||
onCreateTitleChange,
|
||||
onManageProjects,
|
||||
onSubmit,
|
||||
onProjectSelect,
|
||||
onReviewUnit,
|
||||
onStartUnit,
|
||||
pendingAction,
|
||||
statusMessage,
|
||||
value,
|
||||
}: ComposerProps & {
|
||||
createIssueBody: string;
|
||||
createIssueTitle: string;
|
||||
data: MobileWorkspaceView;
|
||||
onCreateBodyChange: (value: string) => void;
|
||||
onCreateIssue: (event: FormEvent<HTMLFormElement>) => void;
|
||||
onCreateTitleChange: (value: string) => void;
|
||||
onBack?: () => void;
|
||||
onManageProjects?: () => void;
|
||||
onProjectSelect?: (projectId: string) => void;
|
||||
onReviewUnit?: (reviewUrl: string) => void;
|
||||
onStartUnit?: (workUnitId: string) => void;
|
||||
pendingAction?: string | null;
|
||||
}) => (
|
||||
<DeviceFrame402>
|
||||
<header className="flex h-20 shrink-0 items-center bg-white px-4">
|
||||
@@ -733,9 +949,27 @@ const WorkUnitScreen = ({
|
||||
<MoreHorizontal className="size-5" />
|
||||
</button>
|
||||
</header>
|
||||
<ProjectSwitcher
|
||||
data={data}
|
||||
onManageProjects={onManageProjects}
|
||||
onProjectSelect={onProjectSelect}
|
||||
/>
|
||||
<main className="min-h-0 flex-1 bg-[#f7f8f5] px-[17px] pt-4">
|
||||
<ExpandedWorkUnitContent data={data} />
|
||||
<ExpandedWorkUnitContent
|
||||
data={data}
|
||||
onReview={onReviewUnit}
|
||||
onStart={onStartUnit}
|
||||
pendingAction={pendingAction}
|
||||
/>
|
||||
</main>
|
||||
<CreateWorkForm
|
||||
body={createIssueBody}
|
||||
onBodyChange={onCreateBodyChange}
|
||||
onSubmit={onCreateIssue}
|
||||
onTitleChange={onCreateTitleChange}
|
||||
pending={pendingAction === "issue"}
|
||||
title={createIssueTitle}
|
||||
/>
|
||||
<ReferenceComposer
|
||||
contextLabel={
|
||||
data.selectedWorkUnit?.title.toUpperCase() ?? "PROJECT WORK"
|
||||
@@ -756,6 +990,7 @@ const VerticalStack = ({
|
||||
onChange,
|
||||
onManageProjects,
|
||||
onOpen,
|
||||
onProjectSelect,
|
||||
onSubmit,
|
||||
statusMessage,
|
||||
value,
|
||||
@@ -763,6 +998,7 @@ const VerticalStack = ({
|
||||
data: MobileWorkspaceView;
|
||||
onManageProjects?: () => void;
|
||||
onOpen?: (workUnitId?: string) => void;
|
||||
onProjectSelect?: (projectId: string) => void;
|
||||
}) => {
|
||||
const { selectedWorkUnit } = data;
|
||||
const secondaryWorkUnits = data.workUnits
|
||||
@@ -783,6 +1019,11 @@ const VerticalStack = ({
|
||||
profileInset
|
||||
subtitle={`${data.activeCount} active work units`}
|
||||
/>
|
||||
<ProjectSwitcher
|
||||
data={data}
|
||||
onManageProjects={onManageProjects}
|
||||
onProjectSelect={onProjectSelect}
|
||||
/>
|
||||
<main className="relative min-h-0 flex-1 bg-[#f7f8f5] px-5 pt-8">
|
||||
<div className="flex items-center">
|
||||
<h2 className="text-[29px] leading-9 font-semibold tracking-[-0.05em]">
|
||||
@@ -908,6 +1149,7 @@ const HomeExpanded = ({
|
||||
onChange,
|
||||
onManageProjects,
|
||||
onOpen,
|
||||
onProjectSelect,
|
||||
onSubmit,
|
||||
statusMessage,
|
||||
value,
|
||||
@@ -915,6 +1157,7 @@ const HomeExpanded = ({
|
||||
data: MobileWorkspaceView;
|
||||
onManageProjects?: () => void;
|
||||
onOpen?: (workUnitId?: string) => void;
|
||||
onProjectSelect?: (projectId: string) => void;
|
||||
}) => (
|
||||
<DeviceFrame402>
|
||||
<ProductHeader
|
||||
@@ -924,6 +1167,11 @@ const HomeExpanded = ({
|
||||
profileInset
|
||||
subtitle={`${data.activeCount} active work units`}
|
||||
/>
|
||||
<ProjectSwitcher
|
||||
data={data}
|
||||
onManageProjects={onManageProjects}
|
||||
onProjectSelect={onProjectSelect}
|
||||
/>
|
||||
<main className="relative min-h-0 flex-1 bg-[#f7f8f5] px-5 pt-[27px]">
|
||||
<div className="flex items-center">
|
||||
<h2 className="text-[29px] leading-9 font-semibold tracking-[-0.05em]">
|
||||
@@ -979,10 +1227,14 @@ const assistantStatusDotClass: Record<
|
||||
const CharacterChat = ({
|
||||
data,
|
||||
onChange,
|
||||
onCreateIssueFromSignal,
|
||||
onSubmit,
|
||||
statusMessage,
|
||||
value,
|
||||
}: ComposerProps & { data: MobileWorkspaceView }) => (
|
||||
}: ComposerProps & {
|
||||
data: MobileWorkspaceView;
|
||||
onCreateIssueFromSignal?: () => void;
|
||||
}) => (
|
||||
<div className="mx-auto h-[min(100dvh,858px)] w-full max-w-[390px] overflow-hidden bg-black">
|
||||
<main className="relative h-full overflow-hidden rounded-[30px] bg-white px-4 text-[#11110f]">
|
||||
<header className="absolute inset-x-4 top-8 flex items-center">
|
||||
@@ -1063,6 +1315,13 @@ const CharacterChat = ({
|
||||
<p className="mt-3 text-[13px] leading-[18px]">
|
||||
{data.latestSignal.summary}
|
||||
</p>
|
||||
<button
|
||||
className="mt-3 h-8 rounded-[11px] bg-black px-3 text-[11px] font-semibold text-white"
|
||||
onClick={onCreateIssueFromSignal}
|
||||
type="button"
|
||||
>
|
||||
Create work from signal
|
||||
</button>
|
||||
</section>
|
||||
) : null}
|
||||
</>
|
||||
@@ -1140,14 +1399,24 @@ const CharacterChat = ({
|
||||
|
||||
export const MobileWorkspaceScreenRenderer = ({
|
||||
composerValue,
|
||||
createIssueBody,
|
||||
createIssueTitle,
|
||||
data,
|
||||
onBack,
|
||||
onComposerChange,
|
||||
onComposerSubmit,
|
||||
onCreateBodyChange,
|
||||
onCreateIssue,
|
||||
onCreateIssueFromSignal,
|
||||
onCreateTitleChange,
|
||||
onManageProjects,
|
||||
onOpenAssistant,
|
||||
onOpenUnit,
|
||||
onProjectSelect,
|
||||
onReviewUnit,
|
||||
onStartUnit,
|
||||
onViewWork,
|
||||
pendingAction,
|
||||
statusMessage,
|
||||
variant,
|
||||
}: MobileWorkspaceRendererProps) => {
|
||||
@@ -1160,7 +1429,13 @@ export const MobileWorkspaceScreenRenderer = ({
|
||||
};
|
||||
|
||||
if (variant === "character-pass") {
|
||||
return <CharacterChat {...composerProps} data={data} />;
|
||||
return (
|
||||
<CharacterChat
|
||||
{...composerProps}
|
||||
data={data}
|
||||
onCreateIssueFromSignal={onCreateIssueFromSignal}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (variant === "expanded-work-unit") {
|
||||
return (
|
||||
@@ -1168,7 +1443,16 @@ export const MobileWorkspaceScreenRenderer = ({
|
||||
{...composerProps}
|
||||
data={data}
|
||||
onBack={onBack}
|
||||
createIssueBody={createIssueBody}
|
||||
createIssueTitle={createIssueTitle}
|
||||
onCreateBodyChange={onCreateBodyChange}
|
||||
onCreateIssue={onCreateIssue}
|
||||
onCreateTitleChange={onCreateTitleChange}
|
||||
onManageProjects={onManageProjects}
|
||||
onProjectSelect={onProjectSelect}
|
||||
onReviewUnit={onReviewUnit}
|
||||
onStartUnit={onStartUnit}
|
||||
pendingAction={pendingAction}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1179,6 +1463,7 @@ export const MobileWorkspaceScreenRenderer = ({
|
||||
data={data}
|
||||
onManageProjects={onManageProjects}
|
||||
onOpen={onOpenUnit}
|
||||
onProjectSelect={onProjectSelect}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1189,6 +1474,7 @@ export const MobileWorkspaceScreenRenderer = ({
|
||||
data={data}
|
||||
onManageProjects={onManageProjects}
|
||||
onOpen={onOpenUnit}
|
||||
onProjectSelect={onProjectSelect}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1200,6 +1486,15 @@ export const MobileWorkspaceScreenRenderer = ({
|
||||
onManageProjects={onManageProjects}
|
||||
onOpen={onOpenUnit}
|
||||
onOpenAssistant={onOpenAssistant}
|
||||
onProjectSelect={onProjectSelect}
|
||||
onReviewUnit={onReviewUnit}
|
||||
onStartUnit={onStartUnit}
|
||||
createIssueBody={createIssueBody}
|
||||
createIssueTitle={createIssueTitle}
|
||||
onCreateBodyChange={onCreateBodyChange}
|
||||
onCreateIssue={onCreateIssue}
|
||||
onCreateTitleChange={onCreateTitleChange}
|
||||
pendingAction={pendingAction}
|
||||
onViewWork={onViewWork}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ export { MobileWorkUnitDetailScreen } from "./mobile-work-unit-detail-screen";
|
||||
export type {
|
||||
MobileAssistantMessageView,
|
||||
MobileAssistantView,
|
||||
MobileProjectView,
|
||||
MobileSignalView,
|
||||
MobileWorkspaceScreenProps,
|
||||
MobileWorkspaceView,
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
export type MobileWorkUnitTone = "blue" | "green" | "orange" | "purple";
|
||||
|
||||
export interface MobileProjectView {
|
||||
readonly connected: boolean;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
}
|
||||
|
||||
export interface MobileWorkUnitView {
|
||||
readonly artifactCount: number;
|
||||
readonly code: string;
|
||||
readonly id: string;
|
||||
readonly canRetry: boolean;
|
||||
readonly canStart: boolean;
|
||||
readonly nextAction: string;
|
||||
readonly pullRequestNumber?: number;
|
||||
readonly progress: number;
|
||||
readonly reviewUrl?: string;
|
||||
readonly statusLabel: string;
|
||||
readonly summary: string;
|
||||
readonly title: string;
|
||||
@@ -16,6 +26,7 @@ export interface MobileWorkUnitView {
|
||||
export interface MobileSignalView {
|
||||
readonly desiredOutcome: string;
|
||||
readonly id: string;
|
||||
readonly projectId?: string;
|
||||
readonly summary: string;
|
||||
readonly title: string;
|
||||
}
|
||||
@@ -42,7 +53,9 @@ export interface MobileWorkspaceView {
|
||||
readonly latestSignal?: MobileSignalView;
|
||||
readonly needsAttentionCount: number;
|
||||
readonly organizationLabel: string;
|
||||
readonly projects: readonly MobileProjectView[];
|
||||
readonly projectName?: string;
|
||||
readonly selectedProjectId?: string;
|
||||
readonly selectedWorkUnit?: MobileWorkUnitView;
|
||||
readonly shippedCount: number;
|
||||
readonly totalCount: number;
|
||||
|
||||
@@ -8,6 +8,7 @@ export type MobileWorkspaceScreenProps = Omit<
|
||||
export type {
|
||||
MobileAssistantMessageView,
|
||||
MobileAssistantView,
|
||||
MobileProjectView,
|
||||
MobileSignalView,
|
||||
MobileWorkspaceView,
|
||||
MobileWorkUnitTone,
|
||||
|
||||
Reference in New Issue
Block a user