mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
chore(app): remove unused files and code with Knip (#5185)
This commit is contained in:
+12
-11
@@ -1,27 +1,28 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/knip@6/schema.json",
|
||||
"entry": ["src/main.tsx", "test/e2e/specs/**/*.spec.ts"],
|
||||
"project": [
|
||||
"src/**/*.{ts,tsx}",
|
||||
"test/**/*.{ts,tsx}",
|
||||
"test/e2e/globals.d.ts",
|
||||
"*.config.{js,ts}"
|
||||
"entry": [
|
||||
"src/main.tsx",
|
||||
"src/features/conversations/index.ts",
|
||||
"vite.config.ts",
|
||||
"test/vitest.config.ts",
|
||||
"test/wdio.conf.ts",
|
||||
"playwright.config.ts",
|
||||
"test/e2e/specs/**/*.spec.ts",
|
||||
"test/playwright/specs/**/*.spec.ts"
|
||||
],
|
||||
"project": ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}", "*.config.{js,ts}"],
|
||||
"tags": ["-knipignore"],
|
||||
"ignoreDependencies": [
|
||||
"@tauri-apps/cli",
|
||||
"@testing-library/dom",
|
||||
"@wdio/appium-service",
|
||||
"@wdio/cli",
|
||||
"@wdio/local-runner",
|
||||
"@wdio/mocha-framework",
|
||||
"@wdio/spec-reporter",
|
||||
"buffer",
|
||||
"eslint",
|
||||
"husky",
|
||||
"os-browserify",
|
||||
"prettier",
|
||||
"process",
|
||||
"util"
|
||||
],
|
||||
"ignoreBinaries": ["eslint", "knip", "open", "prettier", "tauri", "tsc", "vite", "vitest"]
|
||||
"ignoreBinaries": ["open"]
|
||||
}
|
||||
|
||||
+4
-3
@@ -95,14 +95,12 @@
|
||||
"d3-force": "^3.0.0",
|
||||
"debug": "^4.4.3",
|
||||
"katex": "^0.16.47",
|
||||
"lottie-react": "^2.4.1",
|
||||
"os-browserify": "^0.3.0",
|
||||
"pixi.js": "^8.18.1",
|
||||
"process": "^0.11.10",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-ga4": "^3.0.1",
|
||||
"react-icons": "^5.6.0",
|
||||
"react-joyride": "^3.1.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
@@ -145,9 +143,11 @@
|
||||
"@vitest/coverage-v8": "^4.0.18",
|
||||
"@wdio/appium-service": "^9.24.0",
|
||||
"@wdio/cli": "^9.24.0",
|
||||
"@wdio/globals": "^9.24.0",
|
||||
"@wdio/local-runner": "^9.24.0",
|
||||
"@wdio/mocha-framework": "^9.24.0",
|
||||
"@wdio/spec-reporter": "^9.24.0",
|
||||
"@wdio/types": "^9.24.0",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"cross-env": "^10.1.0",
|
||||
"eslint": "^9.39.2",
|
||||
@@ -166,6 +166,7 @@
|
||||
"typescript": "~5.8.3",
|
||||
"vite": "^8.0.0",
|
||||
"vite-plugin-node-polyfills": "^0.26.0",
|
||||
"vitest": "^4.0.18"
|
||||
"vitest": "^4.0.18",
|
||||
"webdriverio": "^9.24.0"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+9
-26
@@ -46,9 +46,6 @@ importers:
|
||||
debug:
|
||||
specifier: ^4.4.3
|
||||
version: 4.4.3(supports-color@8.1.1)
|
||||
lottie-react:
|
||||
specifier: ^2.4.1
|
||||
version: 2.4.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
||||
os-browserify:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0
|
||||
@@ -149,6 +146,9 @@ importers:
|
||||
'@wdio/cli':
|
||||
specifier: ^9.24.0
|
||||
version: 9.27.0(@types/node@25.6.0)(expect-webdriverio@5.6.5)
|
||||
'@wdio/globals':
|
||||
specifier: ^9.24.0
|
||||
version: 9.27.0(expect-webdriverio@5.6.5)(webdriverio@9.27.0)
|
||||
'@wdio/local-runner':
|
||||
specifier: ^9.24.0
|
||||
version: 9.27.0(@wdio/globals@9.27.0)(webdriverio@9.27.0)
|
||||
@@ -158,6 +158,9 @@ importers:
|
||||
'@wdio/spec-reporter':
|
||||
specifier: ^9.24.0
|
||||
version: 9.27.0
|
||||
'@wdio/types':
|
||||
specifier: ^9.24.0
|
||||
version: 9.27.0
|
||||
autoprefixer:
|
||||
specifier: ^10.4.23
|
||||
version: 10.5.0(postcss@8.5.10)
|
||||
@@ -206,6 +209,9 @@ importers:
|
||||
vitest:
|
||||
specifier: ^4.0.18
|
||||
version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(jsdom@28.1.0(@noble/hashes@2.2.0))(vite@7.3.2(@types/node@25.6.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.3))
|
||||
webdriverio:
|
||||
specifier: ^9.24.0
|
||||
version: 9.27.0
|
||||
|
||||
packages:
|
||||
'@acemir/cssom@0.9.31':
|
||||
@@ -5748,21 +5754,6 @@ packages:
|
||||
}
|
||||
hasBin: true
|
||||
|
||||
lottie-react@2.4.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-LQrH7jlkigIIv++wIyrOYFLHSKQpEY4zehPicL9bQsrt1rnoKRYCYgpCUe5maqylNtacy58/sQDZTkwMcTRxZw==,
|
||||
}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
lottie-web@5.13.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==,
|
||||
}
|
||||
|
||||
lru-cache@10.4.3:
|
||||
resolution:
|
||||
{
|
||||
@@ -12146,14 +12137,6 @@ snapshots:
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
lottie-react@2.4.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
|
||||
dependencies:
|
||||
lottie-web: 5.13.0
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
|
||||
lottie-web@5.13.0: {}
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
lru-cache@11.3.5: {}
|
||||
|
||||
@@ -84,7 +84,7 @@ vi.mock('../components/upsell/GlobalUpsellBanner', () => ({ default: () => null
|
||||
vi.mock('../components/walkthrough/AppWalkthrough', () => ({ default: () => null }));
|
||||
vi.mock('../features/meet/MascotFrameProducer', () => ({ MascotFrameProducer: () => null }));
|
||||
vi.mock('../services/analytics', () => ({ trackPageView: vi.fn() }));
|
||||
vi.mock('../utils/accountsFullscreen', () => ({ isAccountsFullscreen: vi.fn(() => false) }));
|
||||
vi.mock('../utils/accountsFullscreen', () => ({ AGENT_ACCOUNT_ID: '__agent__' }));
|
||||
vi.mock('../store/hooks', () => ({ useAppSelector: vi.fn(() => null) }));
|
||||
vi.mock('@sentry/react', () => ({
|
||||
ErrorBoundary: ({ children }: { children: React.ReactNode }) => <>{children}</>,
|
||||
|
||||
@@ -15,7 +15,7 @@ const KNOWN_MINTS: Record<string, string> = {
|
||||
};
|
||||
|
||||
/** Decimals per known symbol. USDC/CASH = 6, SOL/WSOL = 9, others = 0. */
|
||||
export function decimalsForSymbol(symbol: string | undefined): number {
|
||||
function decimalsForSymbol(symbol: string | undefined): number {
|
||||
const up = (symbol ?? '').toUpperCase();
|
||||
if (up === 'USDC' || up === 'CASH') return 6;
|
||||
if (up === 'SOL' || up === 'WSOL') return 9;
|
||||
|
||||
@@ -37,7 +37,7 @@ function formatJoined(iso: string): string {
|
||||
return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
|
||||
}
|
||||
|
||||
export interface AgentProfileModalProps {
|
||||
interface AgentProfileModalProps {
|
||||
agent: AgentCard;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import Button from '../../components/ui/Button';
|
||||
import { ModalShell } from '../../components/ui/ModalShell';
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
|
||||
export interface AmountCommitDialogProps {
|
||||
interface AmountCommitDialogProps {
|
||||
/** Header title, e.g. "Bid on @handle". */
|
||||
title: string;
|
||||
/** Context line under the title. */
|
||||
@@ -36,7 +36,7 @@ export interface AmountCommitDialogProps {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export interface ParsedAmount {
|
||||
interface ParsedAmount {
|
||||
/** Amount in base units, ready for the RPC. Only set when `valid`. */
|
||||
base: string | null;
|
||||
valid: boolean;
|
||||
|
||||
@@ -25,9 +25,9 @@ import { useT } from '../../lib/i18n/I18nContext';
|
||||
import AmountCommitDialog from './AmountCommitDialog';
|
||||
import X402ConfirmDialog, { type X402WalletBalance } from './X402ConfirmDialog';
|
||||
|
||||
export type CommitKind = 'bid' | 'offer';
|
||||
type CommitKind = 'bid' | 'offer';
|
||||
|
||||
export interface CommitFlowProps {
|
||||
interface CommitFlowProps {
|
||||
kind: CommitKind;
|
||||
/** Display name of the listing/handle (e.g. "@auction"). */
|
||||
name: string;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import Button from '../../components/ui/Button';
|
||||
import { ModalShell } from '../../components/ui/ModalShell';
|
||||
|
||||
export interface ConfirmDialogProps {
|
||||
interface ConfirmDialogProps {
|
||||
/** Modal header (e.g. "Delete post"). */
|
||||
title: string;
|
||||
/** Body copy explaining the consequence (e.g. "Delete this post? This can't be undone."). */
|
||||
|
||||
@@ -21,7 +21,7 @@ import { apiClient } from '../AgentWorldShell';
|
||||
// Namespaced already ('agentworld:identity'), so messages carry no prefix.
|
||||
const debug = debugFactory('agentworld:identity');
|
||||
|
||||
export interface TransferHandleModalProps {
|
||||
interface TransferHandleModalProps {
|
||||
/** The handle being transferred away (without a leading @). */
|
||||
handle: string;
|
||||
onClose: () => void;
|
||||
|
||||
@@ -64,9 +64,9 @@ export interface X402WalletBalance {
|
||||
* - `commit` — signed bid/offer commitment. Insufficient balance SOFT-warns but
|
||||
* still allows Confirm (funds move only on acceptance).
|
||||
*/
|
||||
export type X402ConfirmMode = 'spend' | 'commit';
|
||||
type X402ConfirmMode = 'spend' | 'commit';
|
||||
|
||||
export interface X402ConfirmDialogProps {
|
||||
interface X402ConfirmDialogProps {
|
||||
/** Title shown in the modal header (e.g. "Register @handle"). */
|
||||
title: string;
|
||||
/** Optional subtitle / context line. */
|
||||
@@ -107,7 +107,7 @@ export interface X402ConfirmDialogProps {
|
||||
* "unknown" case into "sufficient", silently bypassing the gate. Callers that
|
||||
* only need the provable-shortfall signal can use `isInsufficient` below.
|
||||
*/
|
||||
export type BalanceStatus = 'unknown' | 'insufficient' | 'sufficient';
|
||||
type BalanceStatus = 'unknown' | 'insufficient' | 'sufficient';
|
||||
|
||||
export function balanceStatus(balance: X402WalletBalance | null, amount: string): BalanceStatus {
|
||||
if (!balance) return 'unknown';
|
||||
|
||||
@@ -2,13 +2,13 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { socketService } from '../../services/socketService';
|
||||
|
||||
export interface TinyplaceStreamMessage {
|
||||
interface TinyplaceStreamMessage {
|
||||
stream_id: string;
|
||||
kind: string;
|
||||
message: unknown;
|
||||
}
|
||||
|
||||
export interface TinyplaceStreamStatus {
|
||||
interface TinyplaceStreamStatus {
|
||||
stream_id: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
type X402BuyResult,
|
||||
} from '../../lib/agentworld/invokeApiClient';
|
||||
|
||||
export type X402BuyState =
|
||||
type X402BuyState =
|
||||
| { phase: 'idle' }
|
||||
| { phase: 'challenge_loading' }
|
||||
| {
|
||||
@@ -35,7 +35,7 @@ export type X402BuyState =
|
||||
| { phase: 'success'; result: Record<string, unknown>; onChainTx?: string; network?: string }
|
||||
| { phase: 'error'; message: string; onChainTx?: string };
|
||||
|
||||
export type X402BuyFn = (id: string, opts: { confirmed: boolean }) => Promise<X402BuyResult>;
|
||||
type X402BuyFn = (id: string, opts: { confirmed: boolean }) => Promise<X402BuyResult>;
|
||||
|
||||
/** Devnet/mainnet Solana explorer link for a settled payment tx. */
|
||||
export function explorerTxUrl(tx: string, network?: string): string {
|
||||
@@ -49,7 +49,7 @@ export function extractOnChainTx(message: string): string | undefined {
|
||||
return match?.[1];
|
||||
}
|
||||
|
||||
export interface UseX402Buy {
|
||||
interface UseX402Buy {
|
||||
state: X402BuyState;
|
||||
reset: () => void;
|
||||
begin: (id: string) => void;
|
||||
|
||||
@@ -49,7 +49,7 @@ const RENDERER_PREFERENCE = 'webgl' as const;
|
||||
const INIT_TIMEOUT_MS = 10_000;
|
||||
|
||||
/** Thrown when renderer init rejects or exceeds {@link INIT_TIMEOUT_MS}. */
|
||||
export class RendererInitError extends Error {
|
||||
class RendererInitError extends Error {
|
||||
public constructor(message: string, options?: { cause?: unknown }) {
|
||||
super(message, options);
|
||||
this.name = 'RendererInitError';
|
||||
@@ -191,7 +191,7 @@ function boxRelation(pointX: number, pointY: number, box: DepthObstacle): number
|
||||
// several worlds mount over a session (e.g. React strict-mode double-mounts).
|
||||
let fontsInstalled = false;
|
||||
|
||||
export interface AgentSummary {
|
||||
interface AgentSummary {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
@@ -9,17 +9,6 @@ function pack(red: number, green: number, blue: number): number {
|
||||
return (clamp(red) << 16) | (clamp(green) << 8) | clamp(blue);
|
||||
}
|
||||
|
||||
/** Linearly blend two colours; `amount` 0 returns `colorA`, 1 returns `colorB`. */
|
||||
export function mixColor(colorA: number, colorB: number, amount: number): number {
|
||||
const [redA, greenA, blueA] = channels(colorA);
|
||||
const [redB, greenB, blueB] = channels(colorB);
|
||||
return pack(
|
||||
redA + (redB - redA) * amount,
|
||||
greenA + (greenB - greenA) * amount,
|
||||
blueA + (blueB - blueA) * amount
|
||||
);
|
||||
}
|
||||
|
||||
/** Scale a colour's brightness (`factor` < 1 darkens, > 1 lightens). */
|
||||
export function shadeColor(color: number, factor: number): number {
|
||||
const [red, green, blue] = channels(color);
|
||||
|
||||
@@ -150,7 +150,7 @@ function tableBlueprint(options: {
|
||||
};
|
||||
}
|
||||
|
||||
export const FURNITURE_BLUEPRINTS: Record<string, FurnitureBlueprint> = {
|
||||
const FURNITURE_BLUEPRINTS: Record<string, FurnitureBlueprint> = {
|
||||
pokerTable: {
|
||||
footprintWidth: 3,
|
||||
footprintHeight: 2,
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface ScreenPoint {
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface TilePoint {
|
||||
interface TilePoint {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ export function screenToTile(screenX: number, screenY: number): TilePoint {
|
||||
* Layer biases keep entities that share a tile in a stable front-to-back order
|
||||
* without disturbing the dominant `gridX + gridY` ordering.
|
||||
*/
|
||||
export const DEPTH_TILE_SCALE = 16;
|
||||
const DEPTH_TILE_SCALE = 16;
|
||||
export const LAYER_FLOOR = 0;
|
||||
export const LAYER_DECAL = 1;
|
||||
export const LAYER_WALL = 2;
|
||||
@@ -78,8 +78,3 @@ export function depthAt(gridX: number, gridY: number, level = 0, layer = 0): num
|
||||
export function lerp(from: number, to: number, amount: number): number {
|
||||
return from + (to - from) * amount;
|
||||
}
|
||||
|
||||
/** Euclidean distance between two tile points. */
|
||||
export function tileDistance(from: TilePoint, to: TilePoint): number {
|
||||
return Math.hypot(to.x - from.x, to.y - from.y);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,4 @@
|
||||
/** Public surface of the isometric agent world engine. */
|
||||
|
||||
export { GameWorld, RendererInitError } from './GameWorld';
|
||||
export type { AgentSummary } from './GameWorld';
|
||||
export { BaseRoom } from './BaseRoom';
|
||||
export {
|
||||
ROOM_REGISTRY,
|
||||
PokerTableRoom,
|
||||
CourtHouseRoom,
|
||||
OfficeRoom,
|
||||
HomeRoom,
|
||||
OutsideWorldRoom,
|
||||
} from './rooms';
|
||||
export type { RoomEntry } from './rooms';
|
||||
export { ChatBubble } from './ChatBubble';
|
||||
export { Agent } from './Agent';
|
||||
export { FurnitureSprite, FURNITURE_BLUEPRINTS } from './furniture';
|
||||
export { TextureFactory } from './textures';
|
||||
export type {
|
||||
AgentAction,
|
||||
AgentState,
|
||||
ChatMessage,
|
||||
Facing,
|
||||
FurnitureConfig,
|
||||
InteractionPoint,
|
||||
RoomDefinition,
|
||||
RoomPalette,
|
||||
WalkNode,
|
||||
} from './types';
|
||||
export { TileCode } from './types';
|
||||
export { GameWorld } from './GameWorld';
|
||||
export { ROOM_REGISTRY } from './rooms';
|
||||
|
||||
@@ -415,31 +415,31 @@ function outsideDefinition(): RoomDefinition {
|
||||
|
||||
// ---- Concrete room subclasses ----------------------------------------------
|
||||
|
||||
export class PokerTableRoom extends BaseRoom {
|
||||
class PokerTableRoom extends BaseRoom {
|
||||
public constructor(factory: TextureFactory) {
|
||||
super(pokerDefinition(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
export class CourtHouseRoom extends BaseRoom {
|
||||
class CourtHouseRoom extends BaseRoom {
|
||||
public constructor(factory: TextureFactory) {
|
||||
super(courtDefinition(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
export class OfficeRoom extends BaseRoom {
|
||||
class OfficeRoom extends BaseRoom {
|
||||
public constructor(factory: TextureFactory) {
|
||||
super(officeDefinition(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
export class HomeRoom extends BaseRoom {
|
||||
class HomeRoom extends BaseRoom {
|
||||
public constructor(factory: TextureFactory) {
|
||||
super(homeDefinition(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
export class OutsideWorldRoom extends BaseRoom {
|
||||
class OutsideWorldRoom extends BaseRoom {
|
||||
public constructor(factory: TextureFactory) {
|
||||
super(outsideDefinition(), factory);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
import { type AgentCard } from '../../lib/agentworld/invokeApiClient';
|
||||
|
||||
export const AVATAR_COLORS = [
|
||||
const AVATAR_COLORS = [
|
||||
'bg-blue-500',
|
||||
'bg-purple-500',
|
||||
'bg-pink-500',
|
||||
@@ -29,7 +29,7 @@ export function getAvatarColor(agentId: string): string {
|
||||
return AVATAR_COLORS[total % AVATAR_COLORS.length] ?? 'bg-blue-500';
|
||||
}
|
||||
|
||||
export function getDisplayName(agent: AgentCard): string {
|
||||
function getDisplayName(agent: AgentCard): string {
|
||||
const username = agent['username'] as string | undefined;
|
||||
return username ?? agent.name ?? agent.agentId.slice(0, 8);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export type PromptInjectionVerdict = 'allow' | 'block' | 'review';
|
||||
type PromptInjectionVerdict = 'allow' | 'block' | 'review';
|
||||
|
||||
export interface PromptInjectionReason {
|
||||
interface PromptInjectionReason {
|
||||
code: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface PromptInjectionCheck {
|
||||
interface PromptInjectionCheck {
|
||||
verdict: PromptInjectionVerdict;
|
||||
score: number;
|
||||
reasons: PromptInjectionReason[];
|
||||
|
||||
@@ -57,7 +57,7 @@ function StepRow({ step }: { step: HarnessInitStep }) {
|
||||
);
|
||||
}
|
||||
|
||||
export interface InitProgressScreenProps {
|
||||
interface InitProgressScreenProps {
|
||||
snapshot: HarnessInitSnapshot;
|
||||
onRetry: () => void;
|
||||
onContinue: () => void;
|
||||
|
||||
@@ -11,7 +11,7 @@ interface LocaleOption {
|
||||
label: string;
|
||||
}
|
||||
|
||||
export const LOCALE_OPTIONS: LocaleOption[] = [
|
||||
const LOCALE_OPTIONS: LocaleOption[] = [
|
||||
{ value: 'en', flag: '🇬🇧', label: 'English' },
|
||||
{ value: 'ko', flag: '🇰🇷', label: '한국어' },
|
||||
{ value: 'zh-CN', flag: '🇨🇳', label: '简体中文' },
|
||||
|
||||
@@ -119,7 +119,7 @@ export type ParseErrorCode =
|
||||
* actual schema string we got, etc.). Consumers render via
|
||||
* `t(\`mcp.inventory.parseError.\${errorCode}\`)` + optional detail.
|
||||
*/
|
||||
export type ParseResult =
|
||||
type ParseResult =
|
||||
| { ok: true; manifest: McpInventoryManifest }
|
||||
| { ok: false; errorCode: ParseErrorCode; detail?: string };
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ const transportOf = (server: SmitheryServer): Transport =>
|
||||
* `io.gitlab.<user>/…`), which maps 1:1 to a repo page. Returns `null` for
|
||||
* vendor reverse-DNS slugs that don't encode a code host.
|
||||
*/
|
||||
export const deriveRepoUrl = (qualifiedName: string): string | null => {
|
||||
const deriveRepoUrl = (qualifiedName: string): string | null => {
|
||||
const slash = qualifiedName.indexOf('/');
|
||||
if (slash < 1) return null;
|
||||
const prefix = qualifiedName.slice(0, slash);
|
||||
|
||||
@@ -79,7 +79,7 @@ const formatArgs = (raw: string): string => {
|
||||
* caller can keep JSON-parse failures (user input) cleanly separate from RPC
|
||||
* failures (the actual tool call) — they surface to the user differently.
|
||||
*/
|
||||
export type ParsedToolArgs = { ok: true; value: unknown } | { ok: false; error: string };
|
||||
type ParsedToolArgs = { ok: true; value: unknown } | { ok: false; error: string };
|
||||
|
||||
export const parseToolArgs = (argsJson: string, fallbackMessage: string): ParsedToolArgs => {
|
||||
if (argsJson.trim() === '') return { ok: true, value: {} };
|
||||
|
||||
@@ -31,7 +31,7 @@ interface Props {
|
||||
* thread; clears itself on a recorded decision (the turn-end handlers in
|
||||
* {@link ChatRuntimeProvider} also clear it if the turn is cancelled).
|
||||
*/
|
||||
export const ApprovalRequestCard: React.FC<Props> = ({ threadId, approval }) => {
|
||||
const ApprovalRequestCard: React.FC<Props> = ({ threadId, approval }) => {
|
||||
const { t } = useT();
|
||||
const dispatch = useAppDispatch();
|
||||
const [deciding, setDeciding] = useState<Decision | null>(null);
|
||||
|
||||
@@ -28,7 +28,7 @@ import { extensionFor } from './artifactExtension';
|
||||
* rounded card, dark/light Tailwind variants, mono accents on
|
||||
* numeric values, inline SVG icons. No new icon dependency.
|
||||
*/
|
||||
export interface ArtifactCardProps {
|
||||
interface ArtifactCardProps {
|
||||
artifact: ArtifactSnapshot;
|
||||
/** When provided, render a Retry button on the `failed` state. */
|
||||
onRetry?: (artifactId: string) => void;
|
||||
|
||||
@@ -18,7 +18,7 @@ import ChatFilesPanel from './ChatFilesPanel';
|
||||
* survive app restarts via the `artifactsReadyOnlyTransform` configured in
|
||||
* `store/index.ts`.
|
||||
*/
|
||||
export interface ChatFilesChipProps {
|
||||
interface ChatFilesChipProps {
|
||||
threadId: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import { extensionFor } from './artifactExtension';
|
||||
* state only shows if the user deletes the last artifact while the
|
||||
* panel is open).
|
||||
*/
|
||||
export interface ChatFilesPanelProps {
|
||||
interface ChatFilesPanelProps {
|
||||
threadId: string;
|
||||
artifacts: ArtifactSnapshot[];
|
||||
onClose: () => void;
|
||||
|
||||
@@ -115,5 +115,3 @@ export const FlowApprovalRequestCard: React.FC<Props> = ({ request, onResolved }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FlowApprovalRequestCard;
|
||||
|
||||
@@ -59,7 +59,7 @@ function errorText(e: unknown): string {
|
||||
return e instanceof Error ? e.message : String(e);
|
||||
}
|
||||
|
||||
export const IntegrationConnectCard: React.FC<Props> = ({ threadId, approval }) => {
|
||||
const IntegrationConnectCard: React.FC<Props> = ({ threadId, approval }) => {
|
||||
const { t } = useT();
|
||||
const dispatch = useAppDispatch();
|
||||
// Canonicalize the slug the agent supplied (e.g. `google_drive` →
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
import type { QueuedFollowup } from '../../store/chatRuntimeSlice';
|
||||
|
||||
export interface QueuedFollowupsProps {
|
||||
interface QueuedFollowupsProps {
|
||||
/** Follow-ups queued for the current thread while a turn is streaming. */
|
||||
items: QueuedFollowup[];
|
||||
/** Dismiss every queued follow-up (clears the backend run-queue too). */
|
||||
|
||||
@@ -2,7 +2,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { markWorkflowProposalCompleted, type WorkflowProposal } from '../../store/chatRuntimeSlice';
|
||||
import { WorkflowProposalCard } from './WorkflowProposalCard';
|
||||
import WorkflowProposalCard from './WorkflowProposalCard';
|
||||
|
||||
// Echo i18n keys so we can assert on the stable key string.
|
||||
vi.mock('../../lib/i18n/I18nContext', () => ({ useT: () => ({ t: (key: string) => key }) }));
|
||||
|
||||
@@ -106,7 +106,7 @@ interface Props {
|
||||
* the tool-timeline `StatusTag`/detail-chip visual language for the
|
||||
* node-kind badges + config hints in the step list.
|
||||
*/
|
||||
export const WorkflowProposalCard: React.FC<Props> = ({ threadId, proposal, onSaved }) => {
|
||||
const WorkflowProposalCard: React.FC<Props> = ({ threadId, proposal, onSaved }) => {
|
||||
const { t } = useT();
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -8,7 +8,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { FlowApprovalRequest } from '../../../hooks/useFlowApprovalRequests';
|
||||
import { decideApproval } from '../../../services/api/approvalApi';
|
||||
import FlowApprovalRequestCard from '../FlowApprovalRequestCard';
|
||||
import { FlowApprovalRequestCard } from '../FlowApprovalRequestCard';
|
||||
|
||||
vi.mock('../../../services/api/approvalApi', () => ({ decideApproval: vi.fn() }));
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ export function activeTriggerSignature(t: ComposioActiveTrigger): string {
|
||||
return t.slug.toUpperCase();
|
||||
}
|
||||
|
||||
export interface TriggerTogglesProps {
|
||||
interface TriggerTogglesProps {
|
||||
toolkitSlug: string;
|
||||
toolkitName: string;
|
||||
connectionId: string;
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { BudgetStatus } from '../../hooks/useCostDashboard';
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
import { formatCurrency } from './formatCurrency';
|
||||
|
||||
export interface BudgetSummaryProps {
|
||||
interface BudgetSummaryProps {
|
||||
currency: string;
|
||||
periodTotalUsd: number;
|
||||
monthlyPaceUsd: number;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export interface ChartTooltipRow {
|
||||
interface ChartTooltipRow {
|
||||
label: string;
|
||||
value: string;
|
||||
/** CSS colour for the legend swatch. */
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export interface ChartTooltipProps {
|
||||
interface ChartTooltipProps {
|
||||
title: string;
|
||||
rows: ChartTooltipRow[];
|
||||
footer?: ReactNode;
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useT } from '../../lib/i18n/I18nContext';
|
||||
import ChartTooltip from './ChartTooltip';
|
||||
import { dayOfMonth, formatCurrency, longDateLabel, shortDayLabel } from './formatCurrency';
|
||||
|
||||
export interface CostBarChartProps {
|
||||
interface CostBarChartProps {
|
||||
days: CostDashboardDay[];
|
||||
currency: string;
|
||||
/** Monthly budget in USD; used to derive a daily target. */
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { CostDashboardModelStats } from '../../hooks/useCostDashboard';
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
import { formatCurrency, formatTokens } from './formatCurrency';
|
||||
|
||||
export interface ModelCostTableProps {
|
||||
interface ModelCostTableProps {
|
||||
models: CostDashboardModelStats[];
|
||||
currency: string;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useT } from '../../lib/i18n/I18nContext';
|
||||
import ChartTooltip from './ChartTooltip';
|
||||
import { dayOfMonth, formatTokens, longDateLabel, shortDayLabel } from './formatCurrency';
|
||||
|
||||
export interface TokenUsageChartProps {
|
||||
interface TokenUsageChartProps {
|
||||
days: CostDashboardDay[];
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ export function dayOfMonth(isoDate: string): string {
|
||||
* is invoked with a string key and is expected to return the localised
|
||||
* value (or the key itself when no translation is available).
|
||||
*/
|
||||
export type RelativeTimeTranslator = (key: string, fallback?: string) => string;
|
||||
type RelativeTimeTranslator = (key: string, fallback?: string) => string;
|
||||
|
||||
/**
|
||||
* Human-friendly relative-time string for the "updated Ns ago" pill.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useId, useRef, useState } from 'react';
|
||||
|
||||
export interface FilterOption {
|
||||
interface FilterOption {
|
||||
value: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { createPortal } from 'react-dom';
|
||||
import { useEscapeKey } from '../../hooks/useEscapeKey';
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
|
||||
export interface FlowRowMenuItem {
|
||||
interface FlowRowMenuItem {
|
||||
key: string;
|
||||
label: string;
|
||||
onSelect: () => void;
|
||||
@@ -27,7 +27,7 @@ export interface FlowRowMenuItem {
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
export interface FlowRowMenuProps {
|
||||
interface FlowRowMenuProps {
|
||||
items: FlowRowMenuItem[];
|
||||
/** Suffixed onto test ids so multiple rows stay addressable. */
|
||||
rowId: string;
|
||||
|
||||
@@ -485,5 +485,3 @@ export function FlowRunInspectorDrawer({ runId, onClose, onFixWithAgent }: Props
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FlowRunInspectorDrawer;
|
||||
|
||||
@@ -96,5 +96,3 @@ export function FlowRunPendingApprovalCard({ approval, deciding, onDecide }: Pro
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FlowRunPendingApprovalCard;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { FlowRun } from '../../services/api/flowsApi';
|
||||
import { store } from '../../store';
|
||||
import { FlowRunsDrawer } from './FlowRunsDrawer';
|
||||
import FlowRunsDrawer from './FlowRunsDrawer';
|
||||
|
||||
const listFlowRuns = vi.hoisted(() => vi.fn());
|
||||
vi.mock('../../services/api/flowsApi', () => ({ listFlowRuns }));
|
||||
|
||||
@@ -74,7 +74,7 @@ interface Props {
|
||||
* unconditionally and just flip `flowId` (same convention as
|
||||
* `FlowRunInspectorDrawer`/`SubagentDrawer`).
|
||||
*/
|
||||
export function FlowRunsDrawer({ flowId, flowName, onClose, onFixWithAgent }: Props) {
|
||||
function FlowRunsDrawer({ flowId, flowName, onClose, onFixWithAgent }: Props) {
|
||||
const { t } = useT();
|
||||
const [runs, setRuns] = useState<FlowRun[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -48,7 +48,7 @@ function relativeTime(iso: string, t: TFn): string {
|
||||
|
||||
const log = createDebug('app:flows:runs-sidebar');
|
||||
|
||||
export interface FlowRunsSidebarProps {
|
||||
interface FlowRunsSidebarProps {
|
||||
flowId: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -317,5 +317,3 @@ function FragmentRow({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default RunItemDataBrowser;
|
||||
|
||||
@@ -37,12 +37,12 @@ const log = createDebug('app:flows:canvas:agentInspector');
|
||||
* slugs `OpenHumanAgentRunner`/`resolve_model_for_hint` accept as bare tier
|
||||
* names — so the value written here runs unchanged in the flow engine.
|
||||
*/
|
||||
export const AGENT_MANAGED_TIERS = ['reasoning-v1', 'chat-v1', 'agentic-v1', 'burst-v1'] as const;
|
||||
const AGENT_MANAGED_TIERS = ['reasoning-v1', 'chat-v1', 'agentic-v1', 'burst-v1'] as const;
|
||||
|
||||
/** Sentinel select value for "type a raw model id" — never persisted. */
|
||||
const CUSTOM_MODEL = '__custom__';
|
||||
|
||||
export interface AgentNodeInspectorProps {
|
||||
interface AgentNodeInspectorProps {
|
||||
/** The agent node's controlled config object. */
|
||||
config: Record<string, unknown>;
|
||||
/** Shallow-merge patch into the node's config. */
|
||||
|
||||
@@ -117,7 +117,7 @@ const CLICK_ADD_ORIGIN = { x: 80, y: 80 };
|
||||
/** Per-click cascade so repeated palette clicks don't stack on one spot. */
|
||||
const CLICK_ADD_STEP = 32;
|
||||
|
||||
export interface EditableFlowCanvasProps {
|
||||
interface EditableFlowCanvasProps {
|
||||
nodes: FlowNode[];
|
||||
edges: FlowEdge[];
|
||||
/** Graph-level metadata xyflow doesn't carry, needed to re-serialize on save. */
|
||||
|
||||
@@ -37,7 +37,7 @@ import EditableFlowCanvas, {
|
||||
import './flowCanvasStyles.css';
|
||||
import FlowNodeComponent from './FlowNodeComponent';
|
||||
|
||||
export interface FlowCanvasProps {
|
||||
interface FlowCanvasProps {
|
||||
nodes: FlowNode[];
|
||||
edges: FlowEdge[];
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ import { memo } from 'react';
|
||||
import { useT } from '../../../lib/i18n/I18nContext';
|
||||
import type { FlowValidation } from '../../../services/api/flowsApi';
|
||||
|
||||
export interface FlowValidationBannerProps {
|
||||
interface FlowValidationBannerProps {
|
||||
validation: FlowValidation | null;
|
||||
/** Message from a failed `flows_update` Save, shown as a distinct error row. */
|
||||
saveError?: string | null;
|
||||
|
||||
@@ -23,7 +23,7 @@ import { useT } from '../../../lib/i18n/I18nContext';
|
||||
/** dataTransfer MIME key for a palette drag — read by the canvas `onDrop`. */
|
||||
export const PALETTE_DND_MIME = 'application/tinyflows-node';
|
||||
|
||||
export interface NodePaletteProps {
|
||||
interface NodePaletteProps {
|
||||
/** Add a node from the given palette entry at the canvas's default position. */
|
||||
onAdd: (entry: PaletteEntry) => void;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface NodeConfigPatch {
|
||||
config?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface NodeConfigDrawerProps {
|
||||
interface NodeConfigDrawerProps {
|
||||
/** The selected node to edit, or `null` when nothing single-node is selected. */
|
||||
node: FlowNode | null;
|
||||
onClose: () => void;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useMemo } from 'react';
|
||||
import type { FlowEdge } from '../../../../lib/flows/graphAdapter';
|
||||
import { useT } from '../../../../lib/i18n/I18nContext';
|
||||
|
||||
export interface NodeConnectionsProps {
|
||||
interface NodeConnectionsProps {
|
||||
nodeId: string;
|
||||
edges: FlowEdge[];
|
||||
nodeLabelById: Record<string, string>;
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
import { useT } from '../../../../lib/i18n/I18nContext';
|
||||
import { Field, INPUT_CLASS, MONO_CLASS } from './nodeConfigFields';
|
||||
|
||||
export interface ScheduleFieldProps {
|
||||
interface ScheduleFieldProps {
|
||||
/** The cron string stored on `config.schedule`. */
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
|
||||
@@ -33,7 +33,7 @@ function toolkitLabel(slug: string): string {
|
||||
}
|
||||
|
||||
/** Distinct connected Composio toolkits from the canvas's loaded connections. */
|
||||
export function connectedToolkits(connections: FlowConnection[]): string[] {
|
||||
function connectedToolkits(connections: FlowConnection[]): string[] {
|
||||
const seen = new Set<string>();
|
||||
for (const c of connections) {
|
||||
if (c.kind === 'composio' && c.toolkit) seen.add(c.toolkit);
|
||||
@@ -43,7 +43,7 @@ export function connectedToolkits(connections: FlowConnection[]): string[] {
|
||||
|
||||
// ── toolkit (app) picker ─────────────────────────────────────────────────────
|
||||
|
||||
export interface ComposioToolkitFieldProps {
|
||||
interface ComposioToolkitFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
value: string;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { Field, INPUT_CLASS, MONO_CLASS } from './nodeConfigFields';
|
||||
/** The `oh:` prefix that marks a native-tool slug (mirrors the Rust constant). */
|
||||
export const NATIVE_TOOL_PREFIX = 'oh:';
|
||||
|
||||
export interface NativeToolFieldProps {
|
||||
interface NativeToolFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
/** The full `config.slug`, e.g. `oh:web_search` (or empty / `oh:`). */
|
||||
|
||||
@@ -75,7 +75,7 @@ export function Field({
|
||||
);
|
||||
}
|
||||
|
||||
export interface TextFieldProps {
|
||||
interface TextFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
value: string;
|
||||
@@ -101,7 +101,7 @@ export function TextField({ label, hint, value, onChange, placeholder, testId }:
|
||||
);
|
||||
}
|
||||
|
||||
export interface TextAreaFieldProps extends Omit<TextFieldProps, 'onChange'> {
|
||||
interface TextAreaFieldProps extends Omit<TextFieldProps, 'onChange'> {
|
||||
onChange: (value: string) => void;
|
||||
rows?: number;
|
||||
mono?: boolean;
|
||||
@@ -133,12 +133,12 @@ export function TextAreaField({
|
||||
);
|
||||
}
|
||||
|
||||
export interface SelectOption {
|
||||
interface SelectOption {
|
||||
value: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface SelectFieldProps {
|
||||
interface SelectFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
value: string;
|
||||
@@ -167,96 +167,6 @@ export function SelectField({ label, hint, value, onChange, options, testId }: S
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonical model route hints (mirrors `AgentEditorPage`'s list, which in turn
|
||||
* mirrors the Rust `ModelSpec::Hint(...)` slugs). Selecting one routes the
|
||||
* agent node by capability tier; the workspace resolves the concrete model.
|
||||
*/
|
||||
export const AGENT_MODEL_HINTS = [
|
||||
'hint:reasoning',
|
||||
'hint:chat',
|
||||
'hint:agentic',
|
||||
'hint:burst',
|
||||
'hint:coding',
|
||||
'hint:summarization',
|
||||
'hint:vision',
|
||||
] as const;
|
||||
|
||||
/** Sentinel select value for "type a raw model id" — never persisted. */
|
||||
const CUSTOM_MODEL = '__custom__';
|
||||
|
||||
export interface ModelHintFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Model selector for the `agent` node: a dropdown of the workspace's model
|
||||
* route hints (`hint:chat`, `hint:coding`, …) with an "inherit" default and a
|
||||
* custom escape hatch for a raw BYOK model id. Writes `hint:<tier>` (or the raw
|
||||
* id, or `''` to inherit) onto `config.model`. Mirrors the agent-editor model
|
||||
* picker so hints stay consistent across the app.
|
||||
*/
|
||||
export function ModelHintField({ label, hint, value, onChange, testId }: ModelHintFieldProps) {
|
||||
const { t } = useT();
|
||||
const id = useId();
|
||||
// A value that's neither empty nor a known hint is a raw custom model id, so
|
||||
// the picker opens in custom mode showing it in the text box.
|
||||
const isKnown = value === '' || (AGENT_MODEL_HINTS as readonly string[]).includes(value);
|
||||
const [customMode, setCustomMode] = useState(value !== '' && !isKnown);
|
||||
|
||||
const handleSelect = useCallback(
|
||||
(next: string) => {
|
||||
if (next === CUSTOM_MODEL) {
|
||||
setCustomMode(true);
|
||||
// Entering custom from a hint/inherit starts with an empty raw id.
|
||||
if (isKnown) onChange('');
|
||||
return;
|
||||
}
|
||||
setCustomMode(false);
|
||||
onChange(next);
|
||||
},
|
||||
[isKnown, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<Field label={label} hint={hint} htmlFor={id}>
|
||||
<div className="space-y-2">
|
||||
<select
|
||||
id={id}
|
||||
className={INPUT_CLASS}
|
||||
value={customMode ? CUSTOM_MODEL : value}
|
||||
data-testid={testId}
|
||||
onChange={e => handleSelect(e.target.value)}>
|
||||
<option value="">{t('flows.nodeConfig.agent.modelInherit')}</option>
|
||||
<optgroup label={t('flows.nodeConfig.agent.modelHints')}>
|
||||
{AGENT_MODEL_HINTS.map(h => (
|
||||
<option key={h} value={h}>
|
||||
{h}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
<option value={CUSTOM_MODEL}>{t('flows.nodeConfig.agent.modelCustom')}</option>
|
||||
</select>
|
||||
{customMode && (
|
||||
<input
|
||||
type="text"
|
||||
className={`${INPUT_CLASS} ${MONO_CLASS}`}
|
||||
value={value}
|
||||
placeholder={t('flows.nodeConfig.agent.modelCustomPlaceholder')}
|
||||
aria-label={t('flows.nodeConfig.agent.modelCustomPlaceholder')}
|
||||
data-testid={testId ? `${testId}-custom` : undefined}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compact "insert an upstream value" dropdown (Feature: `nodes` scope picker).
|
||||
* Always renders with the empty placeholder selected; picking an option calls
|
||||
@@ -304,7 +214,7 @@ export function UpstreamInsertSelect({
|
||||
);
|
||||
}
|
||||
|
||||
export interface ExpressionFieldProps extends TextFieldProps {
|
||||
interface ExpressionFieldProps extends TextFieldProps {
|
||||
/**
|
||||
* `=nodes.…` expressions from upstream nodes; when non-empty a compact
|
||||
* insert dropdown renders beside the input (picking replaces the value).
|
||||
@@ -370,7 +280,7 @@ export function ExpressionField({
|
||||
);
|
||||
}
|
||||
|
||||
export interface KeyMapFieldProps {
|
||||
interface KeyMapFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
value: Record<string, string>;
|
||||
@@ -473,7 +383,7 @@ export function KeyMapField({
|
||||
);
|
||||
}
|
||||
|
||||
export interface JsonFieldProps {
|
||||
interface JsonFieldProps {
|
||||
label: string;
|
||||
hint?: string;
|
||||
value: unknown;
|
||||
@@ -545,7 +455,7 @@ export function JsonField({ label, hint, value, onChange, rows = 6, testId }: Js
|
||||
);
|
||||
}
|
||||
|
||||
export interface CredentialPickerFieldProps {
|
||||
interface CredentialPickerFieldProps {
|
||||
label?: string;
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
|
||||
@@ -67,7 +67,7 @@ export interface NodeConfigFormProps {
|
||||
upstreamOptions?: UpstreamExpressionOption[];
|
||||
}
|
||||
|
||||
export type NodeConfigForm = (props: NodeConfigFormProps) => React.ReactElement;
|
||||
type NodeConfigForm = (props: NodeConfigFormProps) => React.ReactElement;
|
||||
|
||||
// ── trigger ────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ import { type FlowValidation, validateFlow } from '../../../services/api/flowsAp
|
||||
const log = createDebug('app:flows:canvas:validate');
|
||||
|
||||
/** Idle delay after the last edit before auto-validating the draft. */
|
||||
export const VALIDATION_DEBOUNCE_MS = 500;
|
||||
const VALIDATION_DEBOUNCE_MS = 500;
|
||||
|
||||
export interface FlowValidationState {
|
||||
interface FlowValidationState {
|
||||
/** The most recent successful validation result, or `null` before the first. */
|
||||
validation: FlowValidation | null;
|
||||
/** True while a validation RPC is in flight (debounced or manual). */
|
||||
@@ -105,5 +105,3 @@ export function useFlowValidation(
|
||||
|
||||
return { validation, validating, validateNow: run };
|
||||
}
|
||||
|
||||
export default useFlowValidation;
|
||||
|
||||
@@ -25,7 +25,7 @@ const log = createDebug('app:flows:create');
|
||||
/** Sentinel `busyKey` for the "start from scratch" path (not a template id). */
|
||||
export const BLANK_FLOW_KEY = 'blank';
|
||||
|
||||
export interface UseCreateFlow {
|
||||
interface UseCreateFlow {
|
||||
/** Persist `graph` under `name`, then navigate into its canvas. `key` tags the busy affordance. */
|
||||
create: (key: string, name: string, graph: WorkflowGraph) => Promise<void>;
|
||||
/** The `key` of the create currently in flight, or `null`. */
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useT } from '../../lib/i18n/I18nContext';
|
||||
import type { AttentionAction, AttentionQueue } from '../../lib/orchestration/orchestrationClient';
|
||||
import AttentionQueueItem from './AttentionQueueItem';
|
||||
|
||||
export interface AttentionQueueProps {
|
||||
interface AttentionQueueProps {
|
||||
queue: AttentionQueue | null;
|
||||
loading?: boolean;
|
||||
onAction?: (action: AttentionAction) => void;
|
||||
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
AttentionKind,
|
||||
} from '../../lib/orchestration/orchestrationClient';
|
||||
|
||||
export interface AttentionQueueItemProps {
|
||||
interface AttentionQueueItemProps {
|
||||
item: AttentionItem;
|
||||
onAction?: (action: AttentionAction) => void;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { HarnessType } from '../../lib/orchestration/orchestrationClient';
|
||||
|
||||
export type GlyphKind = HarnessType | 'openhuman';
|
||||
|
||||
export interface HarnessGlyphProps {
|
||||
interface HarnessGlyphProps {
|
||||
harness: GlyphKind;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { InstanceStatus, SessionSummary } from '../../lib/orchestration/orc
|
||||
import HarnessGlyph, { type GlyphKind } from './HarnessGlyph';
|
||||
import InstanceStatusDot from './InstanceStatusDot';
|
||||
|
||||
export interface InstanceCardProps {
|
||||
interface InstanceCardProps {
|
||||
session: SessionSummary;
|
||||
selected?: boolean;
|
||||
onSelect?: () => void;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
import type { InstanceStatus } from '../../lib/orchestration/orchestrationClient';
|
||||
|
||||
export interface InstanceStatusDotProps {
|
||||
interface InstanceStatusDotProps {
|
||||
status: InstanceStatus;
|
||||
/** Accessible label (already translated by the caller). */
|
||||
label?: string;
|
||||
|
||||
@@ -82,7 +82,7 @@ interface SyncResult {
|
||||
* Per-stage fallback percentages so the progress bar always advances even
|
||||
* when no numeric "N/M" ratio is present in the detail string (RC#4, #3295).
|
||||
*/
|
||||
export const STAGE_FALLBACK_PERCENT: Record<string, number> = {
|
||||
const STAGE_FALLBACK_PERCENT: Record<string, number> = {
|
||||
requested: 2,
|
||||
fetching: 5,
|
||||
stored: 15,
|
||||
|
||||
@@ -205,7 +205,7 @@ function statusDotClass(kind: MemoryTreePipelineStatus['status']): string {
|
||||
* current data; per-provider failure attribution needs new core work and
|
||||
* is filed as a follow-up to issue #2763.
|
||||
*/
|
||||
export type IntegrationHealth = 'active' | 'stale';
|
||||
type IntegrationHealth = 'active' | 'stale';
|
||||
|
||||
/** Map the wire `freshness` enum to the two-state UI classification. */
|
||||
export function classifyIntegration(
|
||||
@@ -551,7 +551,3 @@ export function MemoryTreeStatusPanel({ onToast }: MemoryTreeStatusPanelProps) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Re-export the hook so unit tests can opt into the polling subscription
|
||||
// directly without re-implementing it.
|
||||
export { useMemoryTreeStatus };
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useT } from '../../lib/i18n/I18nContext';
|
||||
import type { ChatMessage, ChatWindow } from '../../lib/orchestration/useOrchestrationChats';
|
||||
import { formatTime } from './orchestrationTabHelpers';
|
||||
|
||||
export interface ChatListButtonProps {
|
||||
interface ChatListButtonProps {
|
||||
chat: ChatWindow;
|
||||
selected: boolean;
|
||||
onSelect: () => void;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
import type { RelayInfo } from '../../lib/orchestration/orchestrationClient';
|
||||
|
||||
export interface RelayBadgeProps {
|
||||
interface RelayBadgeProps {
|
||||
relay: RelayInfo | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import { useCallback, useState } from 'react';
|
||||
import { useT } from '../../lib/i18n/I18nContext';
|
||||
import type { SelfIdentity } from '../../lib/orchestration/orchestrationClient';
|
||||
|
||||
export interface SelfIdentityCardProps {
|
||||
interface SelfIdentityCardProps {
|
||||
identity: SelfIdentity | null;
|
||||
loading: boolean;
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useT } from '../../lib/i18n/I18nContext';
|
||||
import type { HarnessType, SessionSummary } from '../../lib/orchestration/orchestrationClient';
|
||||
import InstanceCard from './InstanceCard';
|
||||
|
||||
export interface TinyPlaceRosterProps {
|
||||
interface TinyPlaceRosterProps {
|
||||
sessions: SessionSummary[];
|
||||
selectedId?: string;
|
||||
onSelect?: (sessionId: string) => void;
|
||||
|
||||
@@ -57,7 +57,7 @@ const TOAST_ICON_STYLES = {
|
||||
info: 'text-primary-500',
|
||||
};
|
||||
|
||||
export function Toast({ notification, onRemove }: ToastProps) {
|
||||
function Toast({ notification, onRemove }: ToastProps) {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [isExiting, setIsExiting] = useState(false);
|
||||
|
||||
|
||||
@@ -241,5 +241,3 @@ export function VaultHealthChecklist({ onToast, title }: VaultHealthChecklistPro
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default VaultHealthChecklist;
|
||||
|
||||
@@ -33,7 +33,7 @@ const REASON_KEY: Record<WorkflowCostReason, string> = {
|
||||
};
|
||||
|
||||
/** i18n key for each safety tier label. */
|
||||
export const SAFETY_TIER_KEY: Record<WorkflowSafetyTier, string> = {
|
||||
const SAFETY_TIER_KEY: Record<WorkflowSafetyTier, string> = {
|
||||
read_only: 'orchestration.tier.readOnly',
|
||||
standard: 'orchestration.tier.standard',
|
||||
edit_capable: 'orchestration.tier.editCapable',
|
||||
@@ -48,7 +48,7 @@ interface Props {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export const WorkflowRunApprovalCard: React.FC<Props> = ({
|
||||
const WorkflowRunApprovalCard: React.FC<Props> = ({
|
||||
definition,
|
||||
reasons,
|
||||
starting = false,
|
||||
|
||||
@@ -78,7 +78,7 @@ interface Props {
|
||||
onResume: (id: string) => void;
|
||||
}
|
||||
|
||||
export const WorkflowRunDetail: React.FC<Props> = ({
|
||||
const WorkflowRunDetail: React.FC<Props> = ({
|
||||
definition,
|
||||
run,
|
||||
busy = false,
|
||||
|
||||
@@ -36,7 +36,7 @@ export const LEVEL_COLOR = [
|
||||
export const LEAF_COLOR = '#94A3B8'; // raw chunks / leaves (no level)
|
||||
export const CONTACT_COLOR = '#A78BFA'; // person entities (contacts mode)
|
||||
export const SOURCE_COLOR = '#F97316'; // synthetic source root nodes
|
||||
export const ROOT_COLOR = '#8B5CF6'; // master root hub (purple)
|
||||
const ROOT_COLOR = '#8B5CF6'; // master root hub (purple)
|
||||
|
||||
/** Layout is computed in this fixed coordinate space; the renderer pans/zooms it. */
|
||||
export const VIEWPORT_W = 1100;
|
||||
@@ -100,7 +100,7 @@ export type SimLink = SimulationLinkDatum<SimNode>;
|
||||
* Tree mode draws an edge from each node to its `parent_id`; contacts mode
|
||||
* uses the explicit `edges`. Dangling endpoints are dropped.
|
||||
*/
|
||||
export const ROOT_NODE_ID = '__root__';
|
||||
const ROOT_NODE_ID = '__root__';
|
||||
|
||||
export function buildGraph(
|
||||
nodes: GraphNode[],
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
ZOOM_MIN,
|
||||
} from './memoryGraphLayout';
|
||||
|
||||
export interface PixiGraphOptions {
|
||||
interface PixiGraphOptions {
|
||||
simNodes: SimNode[];
|
||||
links: SimLink[];
|
||||
dark: boolean;
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
import { type GraphEdge, type GraphMode, type GraphNode } from '../../utils/tauriCommands';
|
||||
import { VIEWPORT_H, VIEWPORT_W } from './memoryGraphLayout';
|
||||
|
||||
export interface SeededPosition {
|
||||
interface SeededPosition {
|
||||
x: number;
|
||||
y: number;
|
||||
/** True when the node had no carried-over position (newly arrived). */
|
||||
isNew: boolean;
|
||||
}
|
||||
|
||||
export interface SeedResult {
|
||||
interface SeedResult {
|
||||
/** Index-aligned with the input `nodes`. */
|
||||
positions: SeededPosition[];
|
||||
/** Edge index pairs [childIdx, parentIdx] (tree) or [fromIdx, toIdx] (contacts). */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
export interface SvgLayoutNode {
|
||||
interface SvgLayoutNode {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface ChipTabItem<T extends string> {
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
export interface ChipTabsProps<T extends string> {
|
||||
interface ChipTabsProps<T extends string> {
|
||||
/** Chips to render, left to right. */
|
||||
items: ChipTabItem<T>[];
|
||||
/** Currently active chip id. */
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { ReactNode } from 'react';
|
||||
* the same max-width and centering as the content beneath it — header and body
|
||||
* stay aligned. Pass width/centering via `className` (e.g. `mx-auto max-w-2xl`).
|
||||
*/
|
||||
export interface PageSectionHeaderProps {
|
||||
interface PageSectionHeaderProps {
|
||||
title: ReactNode;
|
||||
/** One-line description of what the view does. */
|
||||
description?: ReactNode;
|
||||
|
||||
@@ -13,7 +13,7 @@ import Button from '../ui/Button';
|
||||
*/
|
||||
|
||||
/** Accent families available for the icon tile. Keys map to design tokens. */
|
||||
export type PageWelcomeAccent = 'ocean' | 'sage' | 'amber' | 'coral';
|
||||
type PageWelcomeAccent = 'ocean' | 'sage' | 'amber' | 'coral';
|
||||
|
||||
/** Static per-accent tile tint (Tailwind only scans literal class names). */
|
||||
const ACCENT_TILE: Record<PageWelcomeAccent, string> = {
|
||||
@@ -23,7 +23,7 @@ const ACCENT_TILE: Record<PageWelcomeAccent, string> = {
|
||||
coral: 'bg-coral-500/15 text-coral-600',
|
||||
};
|
||||
|
||||
export interface WelcomeFeature {
|
||||
interface WelcomeFeature {
|
||||
/** Leading glyph — emoji string or icon node. */
|
||||
icon: ReactNode;
|
||||
/** Short feature title. */
|
||||
@@ -32,7 +32,7 @@ export interface WelcomeFeature {
|
||||
description: ReactNode;
|
||||
}
|
||||
|
||||
export interface WelcomeCta {
|
||||
interface WelcomeCta {
|
||||
label: ReactNode;
|
||||
onClick: () => void;
|
||||
/** First CTA renders as primary; the rest as secondary (override here). */
|
||||
@@ -41,7 +41,7 @@ export interface WelcomeCta {
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
export interface PageWelcomeProps {
|
||||
interface PageWelcomeProps {
|
||||
/** Big glyph in the accent tile — emoji string or icon node. */
|
||||
icon: ReactNode;
|
||||
/** Optional short lead-in above the title (e.g. the page name). */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export interface PanelHeaderProps {
|
||||
interface PanelHeaderProps {
|
||||
/**
|
||||
* Primary title rendered as an `h2` in the control row, left of `action`.
|
||||
* Optional — generic panels stay title-less; the settings template
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface PanelPageTab<T extends string = string> {
|
||||
chipTestId?: string;
|
||||
}
|
||||
|
||||
export interface PanelPageProps<T extends string = string> {
|
||||
interface PanelPageProps<T extends string = string> {
|
||||
/** Page title, shown in the header above the description (optional). */
|
||||
title?: ReactNode;
|
||||
/** Page description, shown below the title and above any chips. */
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
|
||||
|
||||
import PanelHeader, { DEFAULT_PANEL_HEADER_BG, DEFAULT_PANEL_HEADER_CLASS } from './PanelHeader';
|
||||
|
||||
export interface PanelScaffoldProps {
|
||||
interface PanelScaffoldProps {
|
||||
/** Primary title rendered in the fixed header (optional; see {@link PanelHeader}). */
|
||||
title?: ReactNode;
|
||||
/** Fixed sub-title rendered in a muted tone, below the title. */
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export interface TwoPaneNavItem {
|
||||
interface TwoPaneNavItem {
|
||||
value: string;
|
||||
label: string;
|
||||
icon?: ReactNode;
|
||||
}
|
||||
|
||||
export interface TwoPaneNavGroup {
|
||||
interface TwoPaneNavGroup {
|
||||
/** Optional uppercase sub-header above the group's items. */
|
||||
label?: string;
|
||||
items: TwoPaneNavItem[];
|
||||
|
||||
@@ -47,7 +47,7 @@ export function useTwoPanelLayout(id: string, defaults?: Partial<PanelLayout>) {
|
||||
};
|
||||
}
|
||||
|
||||
export interface TwoPanelLayoutProps {
|
||||
interface TwoPanelLayoutProps {
|
||||
/** Stable id used as the persistence key for this layout's geometry. */
|
||||
id: string;
|
||||
/** Content of the mini sidebar (left pane). */
|
||||
@@ -103,7 +103,7 @@ export interface TwoPanelLayoutProps {
|
||||
}
|
||||
|
||||
/** Default card look shared by both panes. */
|
||||
export const DEFAULT_PANE_CLASS = 'bg-surface rounded-2xl shadow-soft border border-line';
|
||||
const DEFAULT_PANE_CLASS = 'bg-surface rounded-2xl shadow-soft border border-line';
|
||||
|
||||
const DEFAULT_MIN_WIDTH = 180;
|
||||
const DEFAULT_MAX_WIDTH = 480;
|
||||
|
||||
@@ -50,7 +50,7 @@ export function useRootSidebar() {
|
||||
};
|
||||
}
|
||||
|
||||
export interface RootShellLayoutProps {
|
||||
interface RootShellLayoutProps {
|
||||
/** Always-visible left pane (the app sidebar). */
|
||||
sidebar: ReactNode;
|
||||
/** Dynamic main content (the routed page area). */
|
||||
|
||||
@@ -15,10 +15,10 @@ const navIcon = (d: string) => (
|
||||
const WELCOME_ICON = navIcon('M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z');
|
||||
|
||||
/** `'welcome'` / `'main'`, plus any extra sub-page value the caller declares. */
|
||||
export type PageWelcomeViewId = string;
|
||||
type PageWelcomeViewId = string;
|
||||
|
||||
/** An additional sub-page beyond Welcome · Main (e.g. Workflows' Runs / Discoveries). */
|
||||
export interface PageWelcomeExtraItem {
|
||||
interface PageWelcomeExtraItem {
|
||||
/** `?view=` value + nav selection id. */
|
||||
value: string;
|
||||
/** Sidebar label. */
|
||||
@@ -27,7 +27,7 @@ export interface PageWelcomeExtraItem {
|
||||
iconPath: string;
|
||||
}
|
||||
|
||||
export interface UsePageWelcomeViewOptions {
|
||||
interface UsePageWelcomeViewOptions {
|
||||
/** Accessible label for the sidebar nav. */
|
||||
ariaLabel: string;
|
||||
/** Label for the Welcome entry. */
|
||||
@@ -42,7 +42,7 @@ export interface UsePageWelcomeViewOptions {
|
||||
extraItems?: PageWelcomeExtraItem[];
|
||||
}
|
||||
|
||||
export interface PageWelcomeView {
|
||||
interface PageWelcomeView {
|
||||
/** Current view — `welcome` (default landing) or `main`. */
|
||||
view: PageWelcomeViewId;
|
||||
/** Switch views (updates `?view=`). */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { SecretPromptDialog } from './SecretPromptDialog';
|
||||
import SecretPromptDialog from './SecretPromptDialog';
|
||||
|
||||
const callCoreRpc = vi.fn();
|
||||
vi.mock('../../services/coreRpcClient', () => ({
|
||||
|
||||
@@ -16,7 +16,7 @@ import { callCoreRpc } from '../../services/coreRpcClient';
|
||||
|
||||
type Request = { refId: string; keyName: string; prompt: string };
|
||||
|
||||
export function SecretPromptDialog() {
|
||||
function SecretPromptDialog() {
|
||||
const { t } = useT();
|
||||
const [request, setRequest] = useState<Request | null>(null);
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
@@ -19,7 +19,7 @@ interface ActionItemChecklistProps {
|
||||
items: MeetCallActionItem[];
|
||||
}
|
||||
|
||||
export function ActionItemChecklist({ items }: ActionItemChecklistProps) {
|
||||
function ActionItemChecklist({ items }: ActionItemChecklistProps) {
|
||||
const { t } = useT();
|
||||
const navigate = useNavigate();
|
||||
const [checked, setChecked] = useState<Record<number, boolean>>({});
|
||||
|
||||
@@ -41,7 +41,7 @@ type Toast = { type: 'success' | 'error' | 'info'; title: string; message?: stri
|
||||
*/
|
||||
export const LEAVE_SAFETY_TIMEOUT_MS = 10_000;
|
||||
|
||||
export interface ActiveMeetingBannerProps {
|
||||
interface ActiveMeetingBannerProps {
|
||||
onToast?: (toast: Toast) => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ interface LoadedResult {
|
||||
detail: MeetCallDetail | null;
|
||||
}
|
||||
|
||||
export function HistoryDetail({ record }: HistoryDetailProps) {
|
||||
function HistoryDetail({ record }: HistoryDetailProps) {
|
||||
const { t } = useT();
|
||||
|
||||
// Keyed state: bundles status+detail with the request_id they belong to.
|
||||
|
||||
@@ -212,7 +212,7 @@ function formatRelativeTime(ms: number, t: (key: string) => string): string {
|
||||
}
|
||||
}
|
||||
|
||||
export function HistoryRail({
|
||||
function HistoryRail({
|
||||
groups,
|
||||
selectedId,
|
||||
onSelect,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user