chore(fire-tools): upgrade stamp to v1.13.2
- pnpm catalog: centralize version governance for biome, ts, vitest,
zod, semantic-release, react, vite, and testing deps
- biome 1.9.4 → 2.4.13: migrate config (organizeImports → assist,
files.ignore → files.includes, enable tailwindDirectives for @theme)
- zod 3.24.3 → 4.3.6: update error message API to { message: "..." }
and .errors → .issues in all 4 Zod-using files
- vitest 3.2.3 → 4.1.5
- semantic-release 24.x → 25.0.3
- typescript 6.0.3 (ahead of 5.9.x standard; intentional)
- add commitlint 20.x with conventional config
- add husky 9.x with commit-msg and pre-commit hooks
- add .github/actions/setup composite action; update all 3 workflows
- fix: remove pnpm version: 9 from all workflows (reads packageManager)
- fix: node-version 20 → 24 in all 3 workflows
- add Makefile with dev/build/test/lint/typecheck/install targets
This commit is contained in:
@@ -1,12 +1,36 @@
|
|||||||
{
|
{
|
||||||
"fire_tools_version": "0.1.0",
|
"fire_tools_version": "1.13.2",
|
||||||
"initialized_at": "2026-04-24T00:00:00Z",
|
"initialized_at": "2026-04-24T00:00:00Z",
|
||||||
"profile": "other",
|
"profile": "other",
|
||||||
"features": ["pnpm", "biome", "vitest", "zod"],
|
"features": [
|
||||||
|
"pnpm",
|
||||||
|
"turborepo",
|
||||||
|
"typescript",
|
||||||
|
"biome",
|
||||||
|
"vitest",
|
||||||
|
"zod",
|
||||||
|
"commitlint",
|
||||||
|
"semantic-release",
|
||||||
|
"husky",
|
||||||
|
"actionlint",
|
||||||
|
"github-actions",
|
||||||
|
"makefile"
|
||||||
|
],
|
||||||
"deviations": [
|
"deviations": [
|
||||||
"No SQL database (Honcho API handles persistence)",
|
{
|
||||||
"No turborepo (single package)",
|
"tool": "drizzle",
|
||||||
"No commitlint/husky (small solo project)",
|
"reason": "No SQL database — Honcho API handles all persistence; Drizzle is not applicable",
|
||||||
"No semantic-release (not publishing to npm)"
|
"suppressed_at": "2026-04-27T00:00:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool": "playwright",
|
||||||
|
"reason": "Tauri desktop app — E2E testing approach uses Tauri's native test harness, not browser Playwright",
|
||||||
|
"suppressed_at": "2026-04-27T00:00:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool": "typescript-version",
|
||||||
|
"reason": "Using TypeScript 6.0.3 (ahead of standard 5.9.x) — intentional, team is on leading edge for this solo project",
|
||||||
|
"suppressed_at": "2026-04-27T00:00:00Z"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
15
.github/actions/setup/action.yml
vendored
Normal file
15
.github/actions/setup/action.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
name: Setup pnpm and Node.js
|
||||||
|
description: Configure pnpm and Node.js 24 with caching, then install dependencies
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "24"
|
||||||
|
cache: pnpm
|
||||||
|
|
||||||
|
- run: pnpm install --frozen-lockfile
|
||||||
|
shell: bash
|
||||||
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@@ -13,15 +13,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: ./.github/actions/setup
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: pnpm
|
|
||||||
|
|
||||||
- run: pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- run: pnpm turbo lint typecheck test build --filter=@openconcho/web
|
- run: pnpm turbo lint typecheck test build --filter=@openconcho/web
|
||||||
|
|||||||
12
.github/workflows/release.yml
vendored
12
.github/workflows/release.yml
vendored
@@ -11,20 +11,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: ./.github/actions/setup
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '20'
|
|
||||||
cache: 'pnpm'
|
|
||||||
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Install frontend dependencies
|
|
||||||
run: pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- uses: tauri-apps/tauri-action@v0
|
- uses: tauri-apps/tauri-action@v0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
11
.github/workflows/semantic-release.yml
vendored
11
.github/workflows/semantic-release.yml
vendored
@@ -18,16 +18,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: ./.github/actions/setup
|
||||||
with:
|
|
||||||
version: 9
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: pnpm
|
|
||||||
|
|
||||||
- run: pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- run: pnpm exec semantic-release
|
- run: pnpm exec semantic-release
|
||||||
env:
|
env:
|
||||||
|
|||||||
1
.husky/commit-msg
Executable file
1
.husky/commit-msg
Executable file
@@ -0,0 +1 @@
|
|||||||
|
pnpm exec commitlint --edit ${1}
|
||||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep -E "\.(ts|tsx|js|jsx|css|json)$" || true)
|
||||||
|
[ -z "$STAGED" ] && exit 0
|
||||||
|
pnpm exec biome check --write --staged
|
||||||
22
Makefile
Normal file
22
Makefile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
.PHONY: dev build test lint lint-fix typecheck install
|
||||||
|
|
||||||
|
dev:
|
||||||
|
pnpm --filter @openconcho/desktop dev
|
||||||
|
|
||||||
|
build:
|
||||||
|
pnpm turbo run build
|
||||||
|
|
||||||
|
test:
|
||||||
|
pnpm turbo run test
|
||||||
|
|
||||||
|
lint:
|
||||||
|
pnpm turbo run lint
|
||||||
|
|
||||||
|
lint-fix:
|
||||||
|
pnpm exec biome check --write packages/web/src/
|
||||||
|
|
||||||
|
typecheck:
|
||||||
|
pnpm turbo run typecheck
|
||||||
|
|
||||||
|
install:
|
||||||
|
pnpm install
|
||||||
73
biome.json
73
biome.json
@@ -1,34 +1,43 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.4.13/schema.json",
|
||||||
"files": {
|
"files": {
|
||||||
"ignore": ["src/routeTree.gen.ts", "src/api/schema.d.ts"]
|
"includes": ["**", "!**/src/routeTree.gen.ts", "!**/src/api/schema.d.ts"]
|
||||||
},
|
},
|
||||||
"vcs": {
|
"vcs": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"clientKind": "git",
|
"clientKind": "git",
|
||||||
"useIgnoreFile": true
|
"useIgnoreFile": true
|
||||||
},
|
},
|
||||||
"organizeImports": {
|
"assist": {
|
||||||
"enabled": true
|
"actions": {
|
||||||
},
|
"source": {
|
||||||
"linter": {
|
"organizeImports": "on"
|
||||||
"enabled": true,
|
}
|
||||||
"rules": {
|
}
|
||||||
"recommended": true,
|
},
|
||||||
"style": {
|
"linter": {
|
||||||
"noNonNullAssertion": "warn"
|
"enabled": true,
|
||||||
}
|
"rules": {
|
||||||
}
|
"recommended": true,
|
||||||
},
|
"style": {
|
||||||
"formatter": {
|
"noNonNullAssertion": "warn"
|
||||||
"enabled": true,
|
}
|
||||||
"indentStyle": "tab",
|
}
|
||||||
"lineWidth": 100
|
},
|
||||||
},
|
"formatter": {
|
||||||
"javascript": {
|
"enabled": true,
|
||||||
"formatter": {
|
"indentStyle": "tab",
|
||||||
"quoteStyle": "double",
|
"lineWidth": 100
|
||||||
"semicolons": "always"
|
},
|
||||||
}
|
"css": {
|
||||||
}
|
"parser": {
|
||||||
|
"tailwindDirectives": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"quoteStyle": "double",
|
||||||
|
"semicolons": "always"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
commitlint.config.mjs
Normal file
3
commitlint.config.mjs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
};
|
||||||
10
package.json
10
package.json
@@ -8,17 +8,21 @@
|
|||||||
"build": "turbo run build",
|
"build": "turbo run build",
|
||||||
"lint": "turbo run lint",
|
"lint": "turbo run lint",
|
||||||
"test": "turbo run test",
|
"test": "turbo run test",
|
||||||
"typecheck": "turbo run typecheck"
|
"typecheck": "turbo run typecheck",
|
||||||
|
"prepare": "husky"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4",
|
"@biomejs/biome": "catalog:",
|
||||||
|
"@commitlint/cli": "~20.5.2",
|
||||||
|
"@commitlint/config-conventional": "~20.5.0",
|
||||||
"@semantic-release/changelog": "^6.0.0",
|
"@semantic-release/changelog": "^6.0.0",
|
||||||
"@semantic-release/commit-analyzer": "^13.0.0",
|
"@semantic-release/commit-analyzer": "^13.0.0",
|
||||||
"@semantic-release/exec": "^7.1.0",
|
"@semantic-release/exec": "^7.1.0",
|
||||||
"@semantic-release/git": "^10.0.0",
|
"@semantic-release/git": "^10.0.0",
|
||||||
"@semantic-release/github": "^10.0.0",
|
"@semantic-release/github": "^10.0.0",
|
||||||
"@semantic-release/release-notes-generator": "^14.0.0",
|
"@semantic-release/release-notes-generator": "^14.0.0",
|
||||||
"semantic-release": "^24.0.0",
|
"husky": "~9.1.7",
|
||||||
|
"semantic-release": "catalog:",
|
||||||
"turbo": "^2"
|
"turbo": "^2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,28 +33,28 @@
|
|||||||
"lucide-react": "^1.11.0",
|
"lucide-react": "^1.11.0",
|
||||||
"luxon": "^3.7.2",
|
"luxon": "^3.7.2",
|
||||||
"openapi-fetch": "^0.13.5",
|
"openapi-fetch": "^0.13.5",
|
||||||
"react": "^19.2.5",
|
"react": "catalog:",
|
||||||
"react-dom": "^19.2.5",
|
"react-dom": "catalog:",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"tailwind-merge": "^3.5.0",
|
"tailwind-merge": "^3.5.0",
|
||||||
"tailwindcss": "^4.2.4",
|
"tailwindcss": "^4.2.4",
|
||||||
"zod": "^3.24.3"
|
"zod": "catalog:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tanstack/router-plugin": "^1.120.3",
|
"@tanstack/router-plugin": "^1.120.3",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "catalog:",
|
||||||
"@testing-library/react": "^16.3.0",
|
"@testing-library/react": "catalog:",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "catalog:",
|
||||||
"@types/luxon": "^3.7.1",
|
"@types/luxon": "^3.7.1",
|
||||||
"@types/node": "^25.6.0",
|
"@types/node": "^25.6.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "catalog:",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "catalog:",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@vitejs/plugin-react": "catalog:",
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "catalog:",
|
||||||
"openapi-typescript": "^7.8.0",
|
"openapi-typescript": "^7.8.0",
|
||||||
"typescript": "~6.0.2",
|
"typescript": "catalog:",
|
||||||
"vite": "^8.0.10",
|
"vite": "catalog:",
|
||||||
"vitest": "^3.2.3"
|
"vitest": "catalog:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import createClient from "openapi-fetch";
|
||||||
import { loadConfig } from "@/lib/config";
|
import { loadConfig } from "@/lib/config";
|
||||||
import { httpFetch } from "@/lib/http";
|
import { httpFetch } from "@/lib/http";
|
||||||
import createClient from "openapi-fetch";
|
|
||||||
import type { paths } from "./schema.d.ts";
|
import type { paths } from "./schema.d.ts";
|
||||||
|
|
||||||
export function createHonchoClient() {
|
export function createHonchoClient() {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import { Link, useParams } from "@tanstack/react-router";
|
||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import { Brain, Send } from "lucide-react";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useChat } from "@/api/queries";
|
import { useChat } from "@/api/queries";
|
||||||
import { LoadingSpinner } from "@/components/shared/LoadingSpinner";
|
import { LoadingSpinner } from "@/components/shared/LoadingSpinner";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Textarea } from "@/components/ui/input";
|
import { Textarea } from "@/components/ui/input";
|
||||||
import { SectionHeading } from "@/components/ui/typography";
|
import { SectionHeading } from "@/components/ui/typography";
|
||||||
import { Link, useParams } from "@tanstack/react-router";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { Brain, Send } from "lucide-react";
|
|
||||||
import { useEffect, useRef, useState } from "react";
|
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
import { Link, useParams } from "@tanstack/react-router";
|
||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import { ArrowLeft, Eye, Lightbulb, Plus, Search, Trash2, X } from "lucide-react";
|
||||||
|
import { useMemo, useState } from "react";
|
||||||
|
import { z } from "zod";
|
||||||
import {
|
import {
|
||||||
useConclusions,
|
useConclusions,
|
||||||
useCreateConclusion,
|
useCreateConclusion,
|
||||||
@@ -18,18 +23,13 @@ import { Input, Textarea } from "@/components/ui/input";
|
|||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Body, Caption, MonoCaption, Muted, PageTitle } from "@/components/ui/typography";
|
import { Body, Caption, MonoCaption, Muted, PageTitle } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { Link, useParams } from "@tanstack/react-router";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { ArrowLeft, Eye, Lightbulb, Plus, Search, Trash2, X } from "lucide-react";
|
|
||||||
import { useMemo, useState } from "react";
|
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
type Conclusion = components["schemas"]["Conclusion"];
|
type Conclusion = components["schemas"]["Conclusion"];
|
||||||
|
|
||||||
const createSchema = z.object({
|
const createSchema = z.object({
|
||||||
observer_id: z.string().min(1, "Observer peer ID is required"),
|
observer_id: z.string().min(1, { message: "Observer peer ID is required" }),
|
||||||
observed_id: z.string().min(1, "Observed peer ID is required"),
|
observed_id: z.string().min(1, { message: "Observed peer ID is required" }),
|
||||||
content: z.string().min(1, "Content is required"),
|
content: z.string().min(1, { message: "Content is required" }),
|
||||||
session_id: z.string().optional(),
|
session_id: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ function CreateConclusionModal({
|
|||||||
const result = createSchema.safeParse(fields);
|
const result = createSchema.safeParse(fields);
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
const errs: Record<string, string> = {};
|
const errs: Record<string, string> = {};
|
||||||
for (const issue of result.error.errors) errs[issue.path[0] as string] = issue.message;
|
for (const issue of result.error.issues) errs[issue.path[0] as string] = issue.message;
|
||||||
setValidationErrors(errs);
|
setValidationErrors(errs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
import { Activity, Boxes, ChevronRight, CircleDot, LayoutDashboard } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
import { useQueueStatus, useWorkspaces } from "@/api/queries";
|
import { useQueueStatus, useWorkspaces } from "@/api/queries";
|
||||||
import type { components } from "@/api/schema.d.ts";
|
import type { components } from "@/api/schema.d.ts";
|
||||||
import { ErrorAlert } from "@/components/shared/ErrorAlert";
|
import { ErrorAlert } from "@/components/shared/ErrorAlert";
|
||||||
@@ -5,10 +9,6 @@ import { PageLoader } from "@/components/shared/LoadingSpinner";
|
|||||||
import { Body, Muted, PageTitle, SectionHeading } from "@/components/ui/typography";
|
import { Body, Muted, PageTitle, SectionHeading } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { formatCount } from "@/lib/utils";
|
import { formatCount } from "@/lib/utils";
|
||||||
import { Link } from "@tanstack/react-router";
|
|
||||||
import { motion } from "framer-motion";
|
|
||||||
import { Activity, Boxes, ChevronRight, CircleDot, LayoutDashboard } from "lucide-react";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
type QueueStatus = components["schemas"]["QueueStatus"];
|
type QueueStatus = components["schemas"]["QueueStatus"];
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { useTheme } from "@/hooks/useTheme";
|
|
||||||
import { loadConfig } from "@/lib/config";
|
|
||||||
import { COLOR } from "@/lib/constants";
|
|
||||||
import { Link, useMatchRoute } from "@tanstack/react-router";
|
import { Link, useMatchRoute } from "@tanstack/react-router";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { Boxes, Brain, ChevronRight, LayoutDashboard, Moon, Settings, Sun } from "lucide-react";
|
import { Boxes, Brain, ChevronRight, LayoutDashboard, Moon, Settings, Sun } from "lucide-react";
|
||||||
|
import { useTheme } from "@/hooks/useTheme";
|
||||||
|
import { loadConfig } from "@/lib/config";
|
||||||
|
import { COLOR } from "@/lib/constants";
|
||||||
|
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{ to: "/" as const, label: "Dashboard", icon: LayoutDashboard, exact: true },
|
{ to: "/" as const, label: "Dashboard", icon: LayoutDashboard, exact: true },
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import {
|
||||||
|
ChevronDown,
|
||||||
|
Eye,
|
||||||
|
EyeOff,
|
||||||
|
MessageCircle,
|
||||||
|
Save,
|
||||||
|
Search,
|
||||||
|
User,
|
||||||
|
Users,
|
||||||
|
X,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
import {
|
import {
|
||||||
usePeer,
|
usePeer,
|
||||||
usePeerCard,
|
usePeerCard,
|
||||||
@@ -23,20 +37,6 @@ import {
|
|||||||
SectionHeading,
|
SectionHeading,
|
||||||
} from "@/components/ui/typography";
|
} from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import {
|
|
||||||
ChevronDown,
|
|
||||||
Eye,
|
|
||||||
EyeOff,
|
|
||||||
MessageCircle,
|
|
||||||
Save,
|
|
||||||
Search,
|
|
||||||
User,
|
|
||||||
Users,
|
|
||||||
X,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
export function PeerDetail() {
|
export function PeerDetail() {
|
||||||
const { workspaceId, peerId } = useParams({ strict: false }) as {
|
const { workspaceId, peerId } = useParams({ strict: false }) as {
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||||
|
import { motion, type Variants } from "framer-motion";
|
||||||
|
import { ArrowLeft, ChevronRight, Clock, Eye, Users } from "lucide-react";
|
||||||
|
import { useMemo, useState } from "react";
|
||||||
import { usePeers } from "@/api/queries";
|
import { usePeers } from "@/api/queries";
|
||||||
import type { components } from "@/api/schema.d.ts";
|
import type { components } from "@/api/schema.d.ts";
|
||||||
import { EmptyState } from "@/components/shared/EmptyState";
|
import { EmptyState } from "@/components/shared/EmptyState";
|
||||||
@@ -8,10 +12,6 @@ import { Pagination } from "@/components/shared/Pagination";
|
|||||||
import { SortControl, type SortDir } from "@/components/shared/SortControl";
|
import { SortControl, type SortDir } from "@/components/shared/SortControl";
|
||||||
import { MonoCaption, PageTitle } from "@/components/ui/typography";
|
import { MonoCaption, PageTitle } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
|
||||||
import { type Variants, motion } from "framer-motion";
|
|
||||||
import { ArrowLeft, ChevronRight, Clock, Eye, Users } from "lucide-react";
|
|
||||||
import { useMemo, useState } from "react";
|
|
||||||
|
|
||||||
type Peer = components["schemas"]["Peer"];
|
type Peer = components["schemas"]["Peer"];
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import { AlignLeft, Clock, Copy, MessageSquare, Search, Trash2, Users, X } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
import {
|
import {
|
||||||
useAddPeersToSession,
|
useAddPeersToSession,
|
||||||
useCloneSession,
|
useCloneSession,
|
||||||
@@ -26,10 +30,6 @@ import {
|
|||||||
PageTitle,
|
PageTitle,
|
||||||
SectionHeading,
|
SectionHeading,
|
||||||
} from "@/components/ui/typography";
|
} from "@/components/ui/typography";
|
||||||
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { AlignLeft, Clock, Copy, MessageSquare, Search, Trash2, Users, X } from "lucide-react";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
type Message = components["schemas"]["Message"];
|
type Message = components["schemas"]["Message"];
|
||||||
type SessionSummaries = components["schemas"]["SessionSummaries"];
|
type SessionSummaries = components["schemas"]["SessionSummaries"];
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||||
|
import { motion, type Variants } from "framer-motion";
|
||||||
|
import { ArrowLeft, ChevronRight, CircleDot, Clock, MessageSquare } from "lucide-react";
|
||||||
|
import { useMemo, useState } from "react";
|
||||||
import { useSessions } from "@/api/queries";
|
import { useSessions } from "@/api/queries";
|
||||||
import type { components } from "@/api/schema.d.ts";
|
import type { components } from "@/api/schema.d.ts";
|
||||||
import { EmptyState } from "@/components/shared/EmptyState";
|
import { EmptyState } from "@/components/shared/EmptyState";
|
||||||
@@ -7,10 +11,6 @@ import { Pagination } from "@/components/shared/Pagination";
|
|||||||
import { SortControl, type SortDir } from "@/components/shared/SortControl";
|
import { SortControl, type SortDir } from "@/components/shared/SortControl";
|
||||||
import { MonoCaption, PageTitle } from "@/components/ui/typography";
|
import { MonoCaption, PageTitle } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
|
||||||
import { type Variants, motion } from "framer-motion";
|
|
||||||
import { ArrowLeft, ChevronRight, CircleDot, Clock, MessageSquare } from "lucide-react";
|
|
||||||
import { useMemo, useState } from "react";
|
|
||||||
|
|
||||||
type Session = components["schemas"]["Session"];
|
type Session = components["schemas"]["Session"];
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import { AlertCircle, CheckCircle, Loader, Lock, LockOpen, Wifi, WifiOff } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input, Textarea } from "@/components/ui/input";
|
import { Input, Textarea } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Muted } from "@/components/ui/typography";
|
import { Muted } from "@/components/ui/typography";
|
||||||
import {
|
import {
|
||||||
type Config,
|
type Config,
|
||||||
type HealthStatus,
|
|
||||||
checkConnection,
|
checkConnection,
|
||||||
configSchema,
|
configSchema,
|
||||||
|
type HealthStatus,
|
||||||
loadConfig,
|
loadConfig,
|
||||||
saveConfig,
|
saveConfig,
|
||||||
} from "@/lib/config";
|
} from "@/lib/config";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { AlertCircle, CheckCircle, Loader, Lock, LockOpen, Wifi, WifiOff } from "lucide-react";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
interface SettingsFormProps {
|
interface SettingsFormProps {
|
||||||
onSaved?: () => void;
|
onSaved?: () => void;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AlertTriangle } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -7,7 +8,6 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { AlertTriangle } from "lucide-react";
|
|
||||||
|
|
||||||
interface ConfirmDialogProps {
|
interface ConfirmDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Body, Caption } from "@/components/ui/typography";
|
|
||||||
import { COLOR } from "@/lib/constants";
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import type { LucideIcon } from "lucide-react";
|
import type { LucideIcon } from "lucide-react";
|
||||||
|
import { Body, Caption } from "@/components/ui/typography";
|
||||||
|
import { COLOR } from "@/lib/constants";
|
||||||
|
|
||||||
interface EmptyStateProps {
|
interface EmptyStateProps {
|
||||||
icon?: LucideIcon;
|
icon?: LucideIcon;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { COLOR } from "@/lib/constants";
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
|
import { COLOR } from "@/lib/constants";
|
||||||
|
|
||||||
interface LoadingSpinnerProps {
|
interface LoadingSpinnerProps {
|
||||||
size?: "sm" | "md" | "lg";
|
size?: "sm" | "md" | "lg";
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { TimestampChip } from "@/components/shared/TimestampChip";
|
|
||||||
import { COLOR } from "@/lib/constants";
|
|
||||||
import { Link } from "@tanstack/react-router";
|
import { Link } from "@tanstack/react-router";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import ReactMarkdown, { type Components } from "react-markdown";
|
import ReactMarkdown, { type Components } from "react-markdown";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
|
import { TimestampChip } from "@/components/shared/TimestampChip";
|
||||||
|
import { COLOR } from "@/lib/constants";
|
||||||
|
|
||||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { ChevronDown } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { ChevronDown } from "lucide-react";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
lines: string[];
|
lines: string[];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { COLOR } from "@/lib/constants";
|
|
||||||
import { ArrowDown, ArrowUp } from "lucide-react";
|
import { ArrowDown, ArrowUp } from "lucide-react";
|
||||||
|
import { COLOR } from "@/lib/constants";
|
||||||
|
|
||||||
export type SortDir = "asc" | "desc";
|
export type SortDir = "asc" | "desc";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { DateTime } from "luxon";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { DateTime } from "luxon";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/** ISO-like string: "2026-04-24 18:18:48" or any Luxon-parseable string */
|
/** ISO-like string: "2026-04-24 18:18:48" or any Luxon-parseable string */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { cn } from "@/lib/utils";
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
import { type VariantProps, cva } from "class-variance-authority";
|
|
||||||
import type { HTMLAttributes } from "react";
|
import type { HTMLAttributes } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
const badgeVariants = cva(
|
const badgeVariants = cva(
|
||||||
"inline-flex items-center gap-1 rounded-md border px-2 py-0.5 text-xs font-medium transition-colors",
|
"inline-flex items-center gap-1 rounded-md border px-2 py-0.5 text-xs font-medium transition-colors",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { Slot } from "@radix-ui/react-slot";
|
import { Slot } from "@radix-ui/react-slot";
|
||||||
import { type VariantProps, cva } from "class-variance-authority";
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
const buttonVariants = cva(
|
const buttonVariants = cva(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import type { HTMLAttributes } from "react";
|
import type { HTMLAttributes } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export function Card({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
|
export function Card({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ const Collapsible = CollapsiblePrimitive.Root;
|
|||||||
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
||||||
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
||||||
|
|
||||||
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
export { Collapsible, CollapsibleContent, CollapsibleTrigger };
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||||
import { X } from "lucide-react";
|
import { X } from "lucide-react";
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export const Dialog = DialogPrimitive.Root;
|
export const Dialog = DialogPrimitive.Root;
|
||||||
export const DialogTrigger = DialogPrimitive.Trigger;
|
export const DialogTrigger = DialogPrimitive.Trigger;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import * as LabelPrimitive from "@radix-ui/react-label";
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export const Label = forwardRef<
|
export const Label = forwardRef<
|
||||||
React.ComponentRef<typeof LabelPrimitive.Root>,
|
React.ComponentRef<typeof LabelPrimitive.Root>,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export const Separator = forwardRef<
|
export const Separator = forwardRef<
|
||||||
React.ComponentRef<typeof SeparatorPrimitive.Root>,
|
React.ComponentRef<typeof SeparatorPrimitive.Root>,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export const Table = forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
|
export const Table = forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
|
||||||
({ className, ...props }, ref) => (
|
({ className, ...props }, ref) => (
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cn } from "@/lib/utils";
|
|
||||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export const TooltipProvider = TooltipPrimitive.Provider;
|
export const TooltipProvider = TooltipPrimitive.Provider;
|
||||||
export const Tooltip = TooltipPrimitive.Root;
|
export const Tooltip = TooltipPrimitive.Root;
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
|
import type { UseMutationResult } from "@tanstack/react-query";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { z } from "zod";
|
||||||
import { FormModal } from "@/components/shared/FormModal";
|
import { FormModal } from "@/components/shared/FormModal";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Caption } from "@/components/ui/typography";
|
import { Caption } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import type { UseMutationResult } from "@tanstack/react-query";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
observer: z.string().min(1, "Observer peer ID is required"),
|
observer: z.string().min(1, { message: "Observer peer ID is required" }),
|
||||||
observed: z.string().optional(),
|
observed: z.string().optional(),
|
||||||
session_id: z.string().optional(),
|
session_id: z.string().optional(),
|
||||||
});
|
});
|
||||||
@@ -46,7 +46,7 @@ export function ScheduleDreamModal({ open, onClose, mutation }: Props) {
|
|||||||
session_id: sessionId || undefined,
|
session_id: sessionId || undefined,
|
||||||
});
|
});
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
setValidationError(result.error.errors[0].message);
|
setValidationError(result.error.issues[0].message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await mutation.mutateAsync({
|
await mutation.mutateAsync({
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import { open } from "@tauri-apps/plugin-shell";
|
||||||
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
|
import { ArrowLeft, ExternalLink, Plus, Trash2, Webhook, Zap } from "lucide-react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { z } from "zod";
|
||||||
import { useCreateWebhook, useDeleteWebhook, useTestWebhook, useWebhooks } from "@/api/queries";
|
import { useCreateWebhook, useDeleteWebhook, useTestWebhook, useWebhooks } from "@/api/queries";
|
||||||
import { ConfirmDialog } from "@/components/shared/ConfirmDialog";
|
import { ConfirmDialog } from "@/components/shared/ConfirmDialog";
|
||||||
import { ErrorAlert } from "@/components/shared/ErrorAlert";
|
import { ErrorAlert } from "@/components/shared/ErrorAlert";
|
||||||
@@ -6,14 +12,8 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Body, Muted, PageTitle, SectionHeading } from "@/components/ui/typography";
|
import { Body, Muted, PageTitle, SectionHeading } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { Link } from "@tanstack/react-router";
|
|
||||||
import { open } from "@tauri-apps/plugin-shell";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { ArrowLeft, ExternalLink, Plus, Trash2, Webhook, Zap } from "lucide-react";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { z } from "zod";
|
|
||||||
|
|
||||||
const urlSchema = z.string().url("Must be a valid URL");
|
const urlSchema = z.string().url({ message: "Must be a valid URL" });
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
@@ -34,7 +34,7 @@ export function WebhookManager({ workspaceId }: Props) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const result = urlSchema.safeParse(url);
|
const result = urlSchema.safeParse(url);
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
setUrlError(result.error.errors[0].message);
|
setUrlError(result.error.issues[0].message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await createWebhook.mutateAsync(url);
|
await createWebhook.mutateAsync(url);
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
import { useDeleteWorkspace, useQueueStatus, useScheduleDream, useWorkspace } from "@/api/queries";
|
|
||||||
import { ConfirmDialog } from "@/components/shared/ConfirmDialog";
|
|
||||||
import { ErrorAlert } from "@/components/shared/ErrorAlert";
|
|
||||||
import { JsonViewer } from "@/components/shared/JsonViewer";
|
|
||||||
import { PageLoader } from "@/components/shared/LoadingSpinner";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Body, Caption, PageTitle, SectionHeading } from "@/components/ui/typography";
|
|
||||||
import { ScheduleDreamModal } from "@/components/workspaces/ScheduleDreamModal";
|
|
||||||
import { COLOR } from "@/lib/constants";
|
|
||||||
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
import { Link, useNavigate, useParams } from "@tanstack/react-router";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
import {
|
import {
|
||||||
@@ -22,6 +13,15 @@ import {
|
|||||||
Zap,
|
Zap,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { useDeleteWorkspace, useQueueStatus, useScheduleDream, useWorkspace } from "@/api/queries";
|
||||||
|
import { ConfirmDialog } from "@/components/shared/ConfirmDialog";
|
||||||
|
import { ErrorAlert } from "@/components/shared/ErrorAlert";
|
||||||
|
import { JsonViewer } from "@/components/shared/JsonViewer";
|
||||||
|
import { PageLoader } from "@/components/shared/LoadingSpinner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Body, Caption, PageTitle, SectionHeading } from "@/components/ui/typography";
|
||||||
|
import { ScheduleDreamModal } from "@/components/workspaces/ScheduleDreamModal";
|
||||||
|
import { COLOR } from "@/lib/constants";
|
||||||
|
|
||||||
const NAV_SECTIONS = [
|
const NAV_SECTIONS = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
|
import { motion, type Variants } from "framer-motion";
|
||||||
|
import { Boxes, ChevronRight, Clock } from "lucide-react";
|
||||||
|
import { useMemo, useState } from "react";
|
||||||
import { useWorkspaces } from "@/api/queries";
|
import { useWorkspaces } from "@/api/queries";
|
||||||
import type { components } from "@/api/schema.d.ts";
|
import type { components } from "@/api/schema.d.ts";
|
||||||
import { EmptyState } from "@/components/shared/EmptyState";
|
import { EmptyState } from "@/components/shared/EmptyState";
|
||||||
@@ -7,10 +11,6 @@ import { Pagination } from "@/components/shared/Pagination";
|
|||||||
import { SortControl, type SortDir } from "@/components/shared/SortControl";
|
import { SortControl, type SortDir } from "@/components/shared/SortControl";
|
||||||
import { MonoCaption, Muted, PageTitle } from "@/components/ui/typography";
|
import { MonoCaption, Muted, PageTitle } from "@/components/ui/typography";
|
||||||
import { COLOR } from "@/lib/constants";
|
import { COLOR } from "@/lib/constants";
|
||||||
import { useNavigate } from "@tanstack/react-router";
|
|
||||||
import { type Variants, motion } from "framer-motion";
|
|
||||||
import { Boxes, ChevronRight, Clock } from "lucide-react";
|
|
||||||
import { useMemo, useState } from "react";
|
|
||||||
|
|
||||||
type Workspace = components["schemas"]["Workspace"];
|
type Workspace = components["schemas"]["Workspace"];
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type Theme, applyTheme, getStoredTheme } from "@/lib/theme";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
import { applyTheme, getStoredTheme, type Theme } from "@/lib/theme";
|
||||||
|
|
||||||
export function useTheme() {
|
export function useTheme() {
|
||||||
const [theme, setTheme] = useState<Theme>(() => getStoredTheme());
|
const [theme, setTheme] = useState<Theme>(() => getStoredTheme());
|
||||||
|
|||||||
@@ -87,7 +87,9 @@ body {
|
|||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
color: var(--text-1);
|
color: var(--text-1);
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
transition: background 0.2s ease, color 0.2s ease;
|
transition:
|
||||||
|
background 0.2s ease,
|
||||||
|
color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
@@ -101,7 +103,8 @@ body::before {
|
|||||||
content: "";
|
content: "";
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background-image: linear-gradient(var(--grid-line) 1px, transparent 1px),
|
background-image:
|
||||||
|
linear-gradient(var(--grid-line) 1px, transparent 1px),
|
||||||
linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
|
linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
|
||||||
background-size: 32px 32px;
|
background-size: 32px 32px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { httpFetch } from "@/lib/http";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { httpFetch } from "@/lib/http";
|
||||||
|
|
||||||
const CONFIG_KEY = "openconcho:config";
|
const CONFIG_KEY = "openconcho:config";
|
||||||
|
|
||||||
export const configSchema = z.object({
|
export const configSchema = z.object({
|
||||||
baseUrl: z.string().url("Must be a valid URL"),
|
baseUrl: z.string().url({ message: "Must be a valid URL" }),
|
||||||
token: z.string().optional().default(""),
|
token: z.string().optional().default(""),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { RouterProvider, createRouter } from "@tanstack/react-router";
|
import { createRouter, RouterProvider } from "@tanstack/react-router";
|
||||||
import { StrictMode } from "react";
|
import { StrictMode } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { routeTree } from "./routeTree.gen";
|
import { routeTree } from "./routeTree.gen";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { createRootRoute, Outlet, useRouter } from "@tanstack/react-router";
|
||||||
|
import { useEffect } from "react";
|
||||||
import { Sidebar } from "@/components/layout/Sidebar";
|
import { Sidebar } from "@/components/layout/Sidebar";
|
||||||
import { loadConfig } from "@/lib/config";
|
import { loadConfig } from "@/lib/config";
|
||||||
import { applyTheme, getStoredTheme } from "@/lib/theme";
|
import { applyTheme, getStoredTheme } from "@/lib/theme";
|
||||||
import { Outlet, createRootRoute, useRouter } from "@tanstack/react-router";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
function RootLayout() {
|
function RootLayout() {
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Dashboard } from "@/components/dashboard/Dashboard";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { Dashboard } from "@/components/dashboard/Dashboard";
|
||||||
|
|
||||||
export const Route = createFileRoute("/")({
|
export const Route = createFileRoute("/")({
|
||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SettingsForm } from "@/components/settings/SettingsForm";
|
|
||||||
import { createFileRoute, useNavigate } from "@tanstack/react-router";
|
import { createFileRoute, useNavigate } from "@tanstack/react-router";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { Brain } from "lucide-react";
|
import { Brain } from "lucide-react";
|
||||||
|
import { SettingsForm } from "@/components/settings/SettingsForm";
|
||||||
|
|
||||||
export const Route = createFileRoute("/settings")({
|
export const Route = createFileRoute("/settings")({
|
||||||
component: SettingsPage,
|
component: SettingsPage,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { WorkspaceList } from "@/components/workspaces/WorkspaceList";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { WorkspaceList } from "@/components/workspaces/WorkspaceList";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces")({
|
export const Route = createFileRoute("/workspaces")({
|
||||||
component: WorkspaceList,
|
component: WorkspaceList,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { WorkspaceDetail } from "@/components/workspaces/WorkspaceDetail";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { WorkspaceDetail } from "@/components/workspaces/WorkspaceDetail";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId")({
|
||||||
component: WorkspaceDetail,
|
component: WorkspaceDetail,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ConclusionBrowser } from "@/components/conclusions/ConclusionBrowser";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { ConclusionBrowser } from "@/components/conclusions/ConclusionBrowser";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/conclusions")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/conclusions")({
|
||||||
component: ConclusionBrowser,
|
component: ConclusionBrowser,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { PeerList } from "@/components/peers/PeerList";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { PeerList } from "@/components/peers/PeerList";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/peers")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/peers")({
|
||||||
component: PeerList,
|
component: PeerList,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { PeerDetail } from "@/components/peers/PeerDetail";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { PeerDetail } from "@/components/peers/PeerDetail";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/peers_/$peerId")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/peers_/$peerId")({
|
||||||
component: PeerDetail,
|
component: PeerDetail,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ChatPage } from "@/components/chat/ChatPage";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { ChatPage } from "@/components/chat/ChatPage";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/peers_/$peerId_/chat")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/peers_/$peerId_/chat")({
|
||||||
component: ChatPage,
|
component: ChatPage,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { SessionList } from "@/components/sessions/SessionList";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { SessionList } from "@/components/sessions/SessionList";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/sessions")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/sessions")({
|
||||||
component: SessionList,
|
component: SessionList,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { SessionDetail } from "@/components/sessions/SessionDetail";
|
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
import { SessionDetail } from "@/components/sessions/SessionDetail";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/sessions_/$sessionId")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/sessions_/$sessionId")({
|
||||||
component: SessionDetail,
|
component: SessionDetail,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { WebhookManager } from "@/components/workspaces/WebhookManager";
|
|
||||||
import { createFileRoute, useParams } from "@tanstack/react-router";
|
import { createFileRoute, useParams } from "@tanstack/react-router";
|
||||||
|
import { WebhookManager } from "@/components/workspaces/WebhookManager";
|
||||||
|
|
||||||
export const Route = createFileRoute("/workspaces_/$workspaceId_/webhooks")({
|
export const Route = createFileRoute("/workspaces_/$workspaceId_/webhooks")({
|
||||||
component: WebhookManagerPage,
|
component: WebhookManagerPage,
|
||||||
|
|||||||
1389
pnpm-lock.yaml
generated
1389
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,28 @@
|
|||||||
packages:
|
packages:
|
||||||
- packages/*
|
- packages/*
|
||||||
|
allowBuilds:
|
||||||
|
esbuild: true
|
||||||
|
|
||||||
|
catalog:
|
||||||
|
# Standard tooling
|
||||||
|
"@biomejs/biome": "^2.4.0"
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
"@testing-library/jest-dom": "^6.6.3"
|
||||||
|
"@testing-library/react": "^16.3.0"
|
||||||
|
"@testing-library/user-event": "^14.6.1"
|
||||||
|
"@types/react": "^19.2.14"
|
||||||
|
"@types/react-dom": "^19.2.3"
|
||||||
|
"@vitejs/plugin-react": "^6.0.1"
|
||||||
|
jsdom: "^26.1.0"
|
||||||
|
|
||||||
|
# React
|
||||||
|
react: "^19.2.5"
|
||||||
|
react-dom: "^19.2.5"
|
||||||
|
semantic-release: "^25.0.0"
|
||||||
|
typescript: "~6.0.2"
|
||||||
|
|
||||||
|
# Vite
|
||||||
|
vite: "^8.0.10"
|
||||||
|
vitest: "^4.0.0"
|
||||||
|
zod: "^4.0.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user