- Add stocks table (server/db) with list/get/add/update/delete actions, scoped per user, backing both the chat agent and the /stocks UI via useActionQuery/useActionMutation - Add mobile-first /stocks page (shadcn table/cards, watchlist, search) and wire it into the sidebar, navigation state, and view-screen context - Install the platform's Claude Agent SDK harness (server/plugins, server/routes/api/claude-agent) so the app agent runs on the platform's own Claude subscription instead of the Builder.io gateway; fix the vendored turn.post.ts route to resolve the session and wrap it in runWithRequestContext, since custom /api/ routes aren't auto-wrapped in request context the way /_agent-native/actions/* are - Add shadcn table/badge/dialog/select components (Tabler icons, not lucide)
46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
/**
|
|
* See what the user is currently looking at on screen.
|
|
*
|
|
* Reads and returns the current navigation state from application state.
|
|
*
|
|
* Usage:
|
|
* pnpm action view-screen
|
|
*/
|
|
|
|
import { defineAction } from "@agent-native/core/action";
|
|
import { readAppState } from "@agent-native/core/application-state";
|
|
import { eq } from "@agent-native/core/db/schema";
|
|
import { z } from "zod";
|
|
|
|
import { getDb } from "../server/db/index.js";
|
|
import { stocks } from "../server/db/schema.js";
|
|
|
|
export default defineAction({
|
|
description:
|
|
"See what the user is currently looking at on screen. Returns the current navigation state for the chat-first app. Always call this first before taking any action.",
|
|
schema: z.object({}),
|
|
http: false,
|
|
readOnly: true,
|
|
run: async (_args, ctx) => {
|
|
const navigation = await readAppState("navigation");
|
|
|
|
const screen: Record<string, unknown> = {};
|
|
if (navigation) screen.navigation = navigation;
|
|
|
|
const view = (navigation as { view?: string } | null)?.view;
|
|
if (view === "stocks" && ctx?.userEmail) {
|
|
const db = getDb();
|
|
const rows = await db
|
|
.select()
|
|
.from(stocks)
|
|
.where(eq(stocks.ownerEmail, ctx.userEmail));
|
|
screen.stocks = { count: rows.length, listings: rows };
|
|
}
|
|
|
|
if (Object.keys(screen).length === 0) {
|
|
return "No application state found. Is the app running?";
|
|
}
|
|
return screen;
|
|
},
|
|
});
|