@elizaos/plugin-goals 2.0.3-beta.6 → 2.0.3-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/actions/goals.d.ts +16 -0
  2. package/dist/actions/goals.d.ts.map +1 -0
  3. package/dist/actions/goals.js +150 -0
  4. package/dist/actions/goals.js.map +1 -0
  5. package/dist/components/goals/GoalsSpatialView.d.ts +42 -0
  6. package/dist/components/goals/GoalsSpatialView.d.ts.map +1 -0
  7. package/dist/components/goals/GoalsSpatialView.js +149 -0
  8. package/dist/components/goals/GoalsSpatialView.js.map +1 -0
  9. package/dist/components/goals/GoalsView.d.ts +60 -0
  10. package/dist/components/goals/GoalsView.d.ts.map +1 -0
  11. package/dist/components/goals/GoalsView.js +150 -0
  12. package/dist/components/goals/GoalsView.js.map +1 -0
  13. package/dist/components/goals/goals-view-bundle.d.ts +2 -0
  14. package/dist/components/goals/goals-view-bundle.d.ts.map +1 -0
  15. package/dist/components/goals/goals-view-bundle.js +5 -0
  16. package/dist/components/goals/goals-view-bundle.js.map +1 -0
  17. package/dist/db/goals-repository.d.ts +54 -0
  18. package/dist/db/goals-repository.d.ts.map +1 -0
  19. package/dist/db/goals-repository.js +239 -0
  20. package/dist/db/goals-repository.js.map +1 -0
  21. package/dist/db/index.d.ts +2 -0
  22. package/dist/db/index.d.ts.map +1 -0
  23. package/dist/db/index.js +2 -0
  24. package/dist/db/index.js.map +1 -0
  25. package/dist/db/schema.d.ts +826 -0
  26. package/dist/db/schema.d.ts.map +1 -0
  27. package/dist/db/schema.js +61 -0
  28. package/dist/db/schema.js.map +1 -0
  29. package/dist/db/sql.d.ts +32 -0
  30. package/dist/db/sql.d.ts.map +1 -0
  31. package/dist/db/sql.js +130 -0
  32. package/dist/db/sql.js.map +1 -0
  33. package/dist/goal-grounding.d.ts +54 -0
  34. package/dist/goal-grounding.d.ts.map +1 -0
  35. package/dist/goal-grounding.js +148 -0
  36. package/dist/goal-grounding.js.map +1 -0
  37. package/dist/goal-normalize.d.ts +30 -0
  38. package/dist/goal-normalize.d.ts.map +1 -0
  39. package/dist/goal-normalize.js +99 -0
  40. package/dist/goal-normalize.js.map +1 -0
  41. package/dist/goal-semantic-evaluator.d.ts +12 -0
  42. package/dist/goal-semantic-evaluator.d.ts.map +1 -0
  43. package/dist/goal-semantic-evaluator.js +208 -0
  44. package/dist/goal-semantic-evaluator.js.map +1 -0
  45. package/dist/goals-runtime.d.ts +34 -0
  46. package/dist/goals-runtime.d.ts.map +1 -0
  47. package/dist/goals-runtime.js +44 -0
  48. package/dist/goals-runtime.js.map +1 -0
  49. package/dist/goals-service.d.ts +68 -0
  50. package/dist/goals-service.d.ts.map +1 -0
  51. package/dist/goals-service.js +293 -0
  52. package/dist/goals-service.js.map +1 -0
  53. package/dist/index.d.ts +14 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +59 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/plugin.d.ts +13 -0
  58. package/dist/plugin.d.ts.map +1 -0
  59. package/dist/plugin.js +47 -0
  60. package/dist/plugin.js.map +1 -0
  61. package/dist/register-terminal-view.d.ts +15 -0
  62. package/dist/register-terminal-view.d.ts.map +1 -0
  63. package/dist/register-terminal-view.js +25 -0
  64. package/dist/register-terminal-view.js.map +1 -0
  65. package/dist/register.d.ts +9 -0
  66. package/dist/register.d.ts.map +1 -0
  67. package/dist/register.js +5 -0
  68. package/dist/register.js.map +1 -0
  69. package/dist/services/checkin.d.ts +23 -0
  70. package/dist/services/checkin.d.ts.map +1 -0
  71. package/dist/services/checkin.js +27 -0
  72. package/dist/services/checkin.js.map +1 -0
  73. package/dist/services/migration.d.ts +49 -0
  74. package/dist/services/migration.d.ts.map +1 -0
  75. package/dist/services/migration.js +113 -0
  76. package/dist/services/migration.js.map +1 -0
  77. package/dist/types.d.ts +49 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/dist/types.js +53 -0
  80. package/dist/types.js.map +1 -0
  81. package/dist/views/bundle.js +304 -0
  82. package/dist/views/bundle.js.map +1 -0
  83. package/package.json +9 -9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","names":[],"sources":["../../src/types.ts","../../src/components/goals/GoalsSpatialView.tsx","../../src/components/goals/GoalsView.tsx"],"sourcesContent":["/**\n * Public types for @elizaos/plugin-goals.\n *\n * These mirror (and will eventually replace) the action contracts currently\n * declared inside `plugins/plugin-personal-assistant/src/actions/owner-surfaces.ts`.\n * During the decomposition phase the action handlers below remain stubs and\n * delegate (via TODO comments) to the LifeOps implementations.\n */\n\nexport const GOALS_CONTEXTS = [\"goals\", \"self_care\", \"owner\"] as const;\nexport type GoalsContext = (typeof GOALS_CONTEXTS)[number];\n\nexport const GOAL_ACTIONS = [\"create\", \"update\", \"delete\", \"review\"] as const;\nexport type GoalActionName = (typeof GOAL_ACTIONS)[number];\n\nexport const ROUTINE_ACTIONS = [\n \"create\",\n \"update\",\n \"delete\",\n \"complete\",\n \"skip\",\n \"snooze\",\n \"review\",\n] as const;\nexport type RoutineActionName = (typeof ROUTINE_ACTIONS)[number];\n\nexport const REMINDER_ACTIONS = [\n \"create\",\n \"update\",\n \"delete\",\n \"complete\",\n \"snooze\",\n \"list\",\n] as const;\nexport type ReminderActionName = (typeof REMINDER_ACTIONS)[number];\n\nexport const ALARM_ACTIONS = [\n \"create\",\n \"update\",\n \"delete\",\n \"snooze\",\n \"dismiss\",\n \"list\",\n] as const;\nexport type AlarmActionName = (typeof ALARM_ACTIONS)[number];\n\nexport interface GoalsScope {\n agentId: string;\n entityId: string;\n roomId?: string;\n}\n\nexport const GOALS_CHECKIN_SERVICE_TYPE = \"goals_checkin\" as const;\nexport const GOALS_LOG_PREFIX = \"[plugin-goals]\" as const;\n\n// ---------------------------------------------------------------------------\n// View display DTOs.\n//\n// `GoalsView` reads `GET {base}/api/lifeops/goals`, which returns\n// `{ goals: LifeOpsGoalRecord[] }` where each record is\n// `{ goal: LifeOpsGoalDefinition; links: LifeOpsGoalLink[] }`\n// (see LifeOpsGoalDefinition / LifeOpsGoalLink in\n// packages/shared/src/contracts/personal-assistant.ts, served by the\n// `/api/lifeops/goals` branch of\n// plugins/plugin-personal-assistant/src/routes/lifeops-routes.ts).\n//\n// These display DTOs are the flat shape the view renders after mapping each\n// wire record at the fetch boundary. The wire DTOs themselves are declared\n// locally inside GoalsView.tsx; this plugin MUST NOT import the PA contract\n// types. The status / review-state literals below mirror the real enums\n// (LIFEOPS_GOAL_STATUSES / LIFEOPS_REVIEW_STATES) by value.\n// ---------------------------------------------------------------------------\n\n/** Lifecycle status of a goal (mirrors LIFEOPS_GOAL_STATUSES by value). */\nexport const GOAL_STATUSES = [\n \"active\",\n \"paused\",\n \"archived\",\n \"satisfied\",\n] as const;\nexport type GoalStatus = (typeof GOAL_STATUSES)[number];\n\n/** Progress signal a goal review assigns (mirrors LIFEOPS_REVIEW_STATES). */\nexport const GOAL_REVIEW_STATES = [\n \"idle\",\n \"needs_attention\",\n \"on_track\",\n \"at_risk\",\n] as const;\nexport type GoalReviewState = (typeof GOAL_REVIEW_STATES)[number];\n\n/** A goal flattened for display. Mapped from a `LifeOpsGoalRecord` at fetch. */\nexport interface GoalItem {\n id: string;\n title: string;\n /** Empty string when the goal carries no description. */\n description: string;\n status: GoalStatus;\n reviewState: GoalReviewState;\n /** Cadence kind (e.g. \"daily\" / \"weekly\"), or null when the goal is ad-hoc. */\n cadenceKind: string | null;\n /** Human-readable target / next-due from successCriteria, or null. */\n target: string | null;\n /** Count of linked occurrences / tasks / entities backing the goal. */\n linkedCount: number;\n /** ISO timestamp of the last update to the goal. */\n updatedAt: string;\n}\n","/**\n * GoalsSpatialView — the owner life-direction surface authored once with the\n * spatial vocabulary, so it renders correctly wherever it is displayed:\n *\n * - GUI / XR — mounted in `<SpatialSurface>` (DOM; XR scales up).\n * - TUI — rendered to real terminal lines by the agent terminal, via\n * `registerSpatialTerminalView` (see `register-terminal-view.tsx`).\n *\n * It is purely presentational (a snapshot + an action callback in, primitives\n * out) and imports only the cross-modality primitives plus this plugin's own\n * display DTOs, so it is safe to render in the Node agent process where the\n * terminal lives (no browser/data-fetch import).\n *\n * The view is read-only: goals are owned by the personal-assistant routes and\n * created through the assistant chat, not mutated here. The only interactions\n * are the status-filter toggles, a Retry on the error state, and the \"Set a\n * goal\" chat affordance on the empty state.\n */\n\nimport { Button, Card, HStack, List, Text, VStack } from \"@elizaos/ui/spatial\";\nimport {\n GOAL_STATUSES,\n type GoalItem,\n type GoalReviewState,\n type GoalStatus,\n} from \"../../types.ts\";\n\n/** Coarse load state of the goals surface. */\nexport type GoalsLoadStatus = \"loading\" | \"error\" | \"ready\";\n\nexport interface GoalsSnapshot {\n /** Coarse load state. */\n status: GoalsLoadStatus;\n /** Goal records (empty until ready). */\n goals: GoalItem[];\n /** Active status filters; empty = show every status. */\n activeStatuses: GoalStatus[];\n /** Error text when status is \"error\". */\n error?: string | null;\n}\n\nexport interface GoalsSpatialViewProps {\n snapshot: GoalsSnapshot;\n /**\n * Dispatch by agent id: `retry` (re-fetch on the error state), `new` (ask the\n * assistant to set a goal), and `filter:<status>` (toggle one status chip,\n * status ∈ active|paused|archived|satisfied).\n */\n onAction?: (action: string) => void;\n}\n\nconst STATUS_LABELS: Record<GoalStatus, string> = {\n active: \"Active\",\n paused: \"Paused\",\n archived: \"Archived\",\n satisfied: \"Achieved\",\n};\n\nconst REVIEW_LABELS: Record<GoalReviewState, string> = {\n idle: \"not reviewed\",\n on_track: \"on track\",\n at_risk: \"at risk\",\n needs_attention: \"needs attention\",\n};\n\n// Width-1 review marker — filled vs hollow vs cross, never emoji or a checkmark.\n// on_track → ● (settled)\n// at_risk / needs_attention → x (flagged)\n// idle → ○ (not yet reviewed)\nconst REVIEW_GLYPH: Record<GoalReviewState, string> = {\n idle: \"○\",\n on_track: \"●\",\n at_risk: \"x\",\n needs_attention: \"x\",\n};\n\nconst REVIEW_TONE: Record<GoalReviewState, \"muted\" | \"success\" | \"danger\"> = {\n idle: \"muted\",\n on_track: \"success\",\n at_risk: \"danger\",\n needs_attention: \"danger\",\n};\n\nfunction formatDate(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\n// One quiet proactive line: count the goals whose last review flagged them\n// (at_risk / needs_attention). Returns null when nothing is flagged so the line\n// renders only on a real signal (never \"0 goals\").\nfunction reviewNudge(goals: GoalItem[]): string | null {\n const flagged = goals.filter(\n (goal) =>\n goal.reviewState === \"at_risk\" || goal.reviewState === \"needs_attention\",\n ).length;\n if (flagged === 0) return null;\n return flagged === 1\n ? \"1 goal needs a review.\"\n : `${flagged} goals need a review.`;\n}\n\nexport function GoalsSpatialView({\n snapshot,\n onAction,\n}: GoalsSpatialViewProps) {\n const dispatch = (action: string) => () => onAction?.(action);\n const active = new Set(snapshot.activeStatuses);\n\n return (\n <Card gap={1} padding={1}>\n {snapshot.status === \"loading\" ? (\n <Text tone=\"muted\" style=\"caption\">\n Loading goals\n </Text>\n ) : snapshot.status === \"error\" ? (\n <GoalsErrorBody error={snapshot.error} dispatch={dispatch} />\n ) : (\n <GoalsReadyBody\n snapshot={snapshot}\n active={active}\n dispatch={dispatch}\n />\n )}\n </Card>\n );\n}\n\nfunction GoalsErrorBody({\n error,\n dispatch,\n}: {\n error?: string | null;\n dispatch: (action: string) => () => void;\n}) {\n return (\n <>\n <Text bold>Could not load goals</Text>\n {error ? (\n <Text tone=\"muted\" style=\"caption\">\n {error}\n </Text>\n ) : null}\n <HStack gap={1}>\n <Button agent=\"retry\" onPress={dispatch(\"retry\")}>\n Retry\n </Button>\n </HStack>\n </>\n );\n}\n\nfunction GoalsReadyBody({\n snapshot,\n active,\n dispatch,\n}: {\n snapshot: GoalsSnapshot;\n active: Set<GoalStatus>;\n dispatch: (action: string) => () => void;\n}) {\n const nudge = reviewNudge(snapshot.goals);\n\n if (snapshot.goals.length === 0) {\n return (\n <>\n <Text bold>None</Text>\n <HStack gap={1}>\n <Button agent=\"new\" onPress={dispatch(\"new\")}>\n Set a goal\n </Button>\n </HStack>\n </>\n );\n }\n\n // Group by status, dropping empty groups, then apply the active filter.\n const groups = GOAL_STATUSES.map((status) => ({\n status,\n goals: snapshot.goals.filter((goal) => goal.status === status),\n })).filter((group) => {\n if (group.goals.length === 0) return false;\n if (active.size === 0) return true;\n return active.has(group.status);\n });\n\n return (\n <>\n {nudge ? (\n <Text tone=\"muted\" style=\"caption\">\n {nudge}\n </Text>\n ) : null}\n\n <HStack gap={1} wrap>\n {GOAL_STATUSES.map((status) => (\n <Button\n key={status}\n variant={active.has(status) ? \"solid\" : \"outline\"}\n tone={active.has(status) ? \"primary\" : \"default\"}\n agent={`filter:${status}`}\n onPress={dispatch(`filter:${status}`)}\n >\n {STATUS_LABELS[status]}\n </Button>\n ))}\n </HStack>\n\n {groups.length === 0 ? (\n <Text tone=\"muted\" align=\"center\" style=\"caption\">\n None\n </Text>\n ) : (\n groups.map((group) => (\n <GoalsStatusGroup key={group.status} group={group} />\n ))\n )}\n </>\n );\n}\n\nfunction GoalsStatusGroup({\n group,\n}: {\n group: { status: GoalStatus; goals: GoalItem[] };\n}) {\n return (\n <>\n <Text style=\"caption\" tone=\"muted\">\n {STATUS_LABELS[group.status]} ({group.goals.length})\n </Text>\n <List gap={0}>\n {group.goals.map((goal) => (\n <GoalRow key={goal.id} goal={goal} />\n ))}\n </List>\n </>\n );\n}\n\nfunction GoalRow({ goal }: { goal: GoalItem }) {\n const meta: string[] = [];\n if (goal.cadenceKind) meta.push(goal.cadenceKind);\n if (goal.target) meta.push(goal.target);\n if (goal.linkedCount > 0) meta.push(`${goal.linkedCount} linked`);\n\n return (\n <HStack gap={1} align=\"center\">\n <Text tone={REVIEW_TONE[goal.reviewState]} wrap={false}>\n {REVIEW_GLYPH[goal.reviewState]}\n </Text>\n <VStack gap={0} grow={1}>\n <Text bold wrap={false}>\n {goal.title}\n </Text>\n {meta.length > 0 ? (\n <Text style=\"caption\" tone=\"muted\" wrap={false}>\n {meta.join(\" · \")}\n </Text>\n ) : null}\n </VStack>\n <VStack gap={0}>\n <Text\n style=\"caption\"\n tone={REVIEW_TONE[goal.reviewState]}\n wrap={false}\n align=\"end\"\n >\n {REVIEW_LABELS[goal.reviewState]}\n </Text>\n <Text style=\"caption\" tone=\"muted\" wrap={false} align=\"end\">\n {formatDate(goal.updatedAt)}\n </Text>\n </VStack>\n </HStack>\n );\n}\n","/**\n * GoalsView — the single GUI/XR data wrapper for the Goals surface.\n *\n * Data-fetching view over the single read-only goals endpoint served by the\n * personal-assistant routes (PA owns the persistence; this plugin only renders):\n * GET {base}/api/lifeops/goals\n *\n * The wire payload is `{ goals: LifeOpsGoalRecord[] }`, where each record is\n * `{ goal: LifeOpsGoalDefinition; links: LifeOpsGoalLink[] }`. We flatten each\n * record to a `GoalItem` at the fetch boundary so the rest of the view renders\n * display-only.\n *\n * It owns the fetch state machine (loading / error / ready), the status-filter\n * selection, and the quiet 20s background poll, then renders the one\n * presentational {@link GoalsSpatialView} inside a {@link SpatialSurface}.\n * Omitting the `modality` prop lets `SpatialSurface` auto-detect GUI vs XR via\n * `window.__elizaXRContext`, so the SAME component serves both surfaces. The\n * TUI surface renders the same `GoalsSpatialView` through the terminal registry\n * (see `register-terminal-view.tsx`).\n *\n * This plugin MUST NOT import from @elizaos/plugin-personal-assistant. The wire\n * DTOs below are declared locally to match the JSON shape PA emits\n * (LifeOpsGoalDefinition / LifeOpsGoalLink in @elizaos/shared).\n */\n\nimport { client } from \"@elizaos/ui\";\nimport { SpatialSurface } from \"@elizaos/ui/spatial\";\nimport type { ReactNode } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n GOAL_STATUSES,\n type GoalItem,\n type GoalReviewState,\n type GoalStatus,\n} from \"../../types.ts\";\nimport { type GoalsSnapshot, GoalsSpatialView } from \"./GoalsSpatialView.tsx\";\n\n// ---------------------------------------------------------------------------\n// Wire DTOs — local mirror of the JSON shape served by the PA goals route.\n// Never import PA / @elizaos/shared goal types here; keep this view's contract\n// self-contained and aligned by shape.\n// ---------------------------------------------------------------------------\n\ninterface GoalDefinitionWire {\n id: string;\n title: string;\n description: string;\n cadence: Record<string, unknown> | null;\n successCriteria: Record<string, unknown>;\n status: string;\n reviewState: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface GoalLinkWire {\n id: string;\n goalId: string;\n linkedType: string;\n linkedId: string;\n}\n\ninterface GoalRecordWire {\n goal: GoalDefinitionWire;\n links: GoalLinkWire[];\n}\n\ninterface GoalsWire {\n goals: GoalRecordWire[];\n}\n\n// ---------------------------------------------------------------------------\n// Fetcher seam — default to a real GET; tests inject an offline fake.\n// ---------------------------------------------------------------------------\n\nexport interface GoalsFetchers {\n fetchGoals: () => Promise<GoalsWire>;\n}\n\nasync function getGoals(): Promise<GoalsWire> {\n const response = await fetch(`${client.getBaseUrl()}/api/lifeops/goals`);\n if (!response.ok) {\n throw new Error(`Goals request failed (${response.status})`);\n }\n return (await response.json()) as GoalsWire;\n}\n\nconst defaultFetchers: GoalsFetchers = {\n fetchGoals: getGoals,\n};\n\nexport interface GoalsViewProps {\n /** Test/host injection seam. Defaults to the real `/api/lifeops/goals` GET. */\n fetchers?: GoalsFetchers;\n}\n\n// ---------------------------------------------------------------------------\n// Wire -> display DTO mapping.\n// ---------------------------------------------------------------------------\n\nconst KNOWN_STATUSES: ReadonlySet<string> = new Set(GOAL_STATUSES);\nconst KNOWN_REVIEW_STATES: ReadonlySet<string> = new Set([\n \"idle\",\n \"needs_attention\",\n \"on_track\",\n \"at_risk\",\n]);\n\n/** Coerce an unknown wire status to a known one; unknowns settle to \"active\". */\nfunction toStatus(value: string): GoalStatus {\n return KNOWN_STATUSES.has(value) ? (value as GoalStatus) : \"active\";\n}\n\n/** Coerce an unknown wire review state; unknowns settle to \"idle\". */\nfunction toReviewState(value: string): GoalReviewState {\n return KNOWN_REVIEW_STATES.has(value) ? (value as GoalReviewState) : \"idle\";\n}\n\n/** The cadence record carries a `kind` discriminator when present. */\nfunction readCadenceKind(\n cadence: Record<string, unknown> | null,\n): string | null {\n if (cadence && typeof cadence.kind === \"string\" && cadence.kind.length > 0) {\n return cadence.kind;\n }\n return null;\n}\n\n/**\n * successCriteria is a free-form record. We surface a human-readable target\n * only when it carries one of the conventional fields, otherwise null. Display\n * only — no derivation or math.\n */\nfunction readTarget(criteria: Record<string, unknown>): string | null {\n const candidate =\n criteria.targetText ??\n criteria.target ??\n criteria.summary ??\n criteria.deadline ??\n criteria.dueAt;\n if (typeof candidate === \"string\" && candidate.length > 0) return candidate;\n if (typeof candidate === \"number\") return String(candidate);\n return null;\n}\n\nfunction mapGoal(record: GoalRecordWire): GoalItem {\n const { goal, links } = record;\n return {\n id: goal.id,\n title: goal.title,\n description: goal.description ?? \"\",\n status: toStatus(goal.status),\n reviewState: toReviewState(goal.reviewState),\n cadenceKind: readCadenceKind(goal.cadence),\n target: readTarget(goal.successCriteria ?? {}),\n linkedCount: links.length,\n updatedAt: goal.updatedAt,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Fetch-driven state machine.\n// ---------------------------------------------------------------------------\n\ntype LoadState =\n | { kind: \"loading\" }\n | { kind: \"error\"; message: string }\n | { kind: \"ready\"; goals: GoalItem[] };\n\nfunction requestNewGoal(): void {\n client.sendChatMessage?.(\"Help me set a goal to head toward this quarter.\");\n}\n\nexport function GoalsView(props: GoalsViewProps = {}): ReactNode {\n const fetchers = props.fetchers ?? defaultFetchers;\n const [state, setState] = useState<LoadState>({ kind: \"loading\" });\n const [activeStatuses, setActiveStatuses] = useState<Set<GoalStatus>>(\n () => new Set<GoalStatus>(),\n );\n\n const fetchersRef = useRef(fetchers);\n fetchersRef.current = fetchers;\n\n const load = useCallback(() => {\n let cancelled = false;\n setState({ kind: \"loading\" });\n fetchersRef.current\n .fetchGoals()\n .then((wire) => {\n if (cancelled) return;\n setState({ kind: \"ready\", goals: wire.goals.map(mapGoal) });\n })\n .catch((error: unknown) => {\n if (cancelled) return;\n setState({\n kind: \"error\",\n message:\n error instanceof Error ? error.message : \"Could not load goals.\",\n });\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Initial fetch on mount, then a quiet 20s background poll keeps the list\n // fresh (the view has no store subscription and there is no manual refresh).\n // The poll refetches silently: it never drops to the loading skeleton and a\n // transient poll failure leaves the current data on screen.\n useEffect(() => {\n const cancelInitial = load();\n let active = true;\n const interval = setInterval(() => {\n fetchersRef.current\n .fetchGoals()\n .then((wire) => {\n if (active)\n setState({ kind: \"ready\", goals: wire.goals.map(mapGoal) });\n })\n .catch(() => {\n /* keep the last good render on a transient poll failure */\n });\n }, 20000);\n return () => {\n active = false;\n clearInterval(interval);\n cancelInitial();\n };\n }, [load]);\n\n const toggleStatus = useCallback((status: GoalStatus) => {\n setActiveStatuses((prev) => {\n const next = new Set(prev);\n if (next.has(status)) next.delete(status);\n else next.add(status);\n return next;\n });\n }, []);\n\n const onAction = useCallback(\n (action: string) => {\n if (action.startsWith(\"filter:\")) {\n const raw = action.slice(\"filter:\".length);\n if (KNOWN_STATUSES.has(raw)) toggleStatus(raw as GoalStatus);\n return;\n }\n switch (action) {\n case \"retry\":\n load();\n return;\n case \"new\":\n requestNewGoal();\n return;\n }\n },\n [load, toggleStatus],\n );\n\n const snapshot: GoalsSnapshot = useMemo(() => {\n const activeList = Array.from(activeStatuses);\n if (state.kind === \"loading\") {\n return { status: \"loading\", goals: [], activeStatuses: activeList };\n }\n if (state.kind === \"error\") {\n return {\n status: \"error\",\n goals: [],\n activeStatuses: activeList,\n error: state.message,\n };\n }\n return { status: \"ready\", goals: state.goals, activeStatuses: activeList };\n }, [state, activeStatuses]);\n\n return (\n <SpatialSurface>\n <GoalsSpatialView snapshot={snapshot} onAction={onAction} />\n </SpatialSurface>\n );\n}\n\nexport default GoalsView;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/plugin-goals",
3
- "version": "2.0.3-beta.6",
3
+ "version": "2.0.3-beta.7",
4
4
  "type": "module",
5
5
  "description": "Life direction plugin: owner-set long-horizon goals, recurring routines, reminders, alarms, daily check-ins, plus a self-care/mood/journal panel.",
6
6
  "main": "./dist/index.js",
@@ -50,22 +50,22 @@
50
50
  }
51
51
  },
52
52
  "dependencies": {
53
- "@elizaos/agent": "2.0.3-beta.6",
54
- "@elizaos/app-core": "2.0.3-beta.6",
55
- "@elizaos/core": "2.0.3-beta.6",
56
- "@elizaos/shared": "2.0.3-beta.6",
57
- "@elizaos/ui": "2.0.3-beta.6",
53
+ "@elizaos/agent": "2.0.3-beta.7",
54
+ "@elizaos/app-core": "2.0.3-beta.7",
55
+ "@elizaos/core": "2.0.3-beta.7",
56
+ "@elizaos/shared": "2.0.3-beta.7",
57
+ "@elizaos/ui": "2.0.3-beta.7",
58
58
  "drizzle-orm": "0.45.2",
59
59
  "lucide-react": "^1.0.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@elizaos/plugin-sql": "2.0.3-beta.6",
62
+ "@elizaos/plugin-sql": "2.0.3-beta.7",
63
63
  "react": "^19.0.0",
64
64
  "react-dom": "^19.0.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@biomejs/biome": "^2.4.14",
68
- "@elizaos/test-harness": "2.0.3-beta.6",
68
+ "@elizaos/test-harness": "2.0.3-beta.7",
69
69
  "@types/node": "^25.0.6",
70
70
  "@types/react": "^19.0.0",
71
71
  "@types/react-dom": "^19.0.0",
@@ -92,5 +92,5 @@
92
92
  "assets",
93
93
  "dist"
94
94
  ],
95
- "gitHead": "990dc996172b3e0fb525a75052a5ac28a4cd4de5"
95
+ "gitHead": "61094f10458d11055c75b3dd0bae374e3f66bac5"
96
96
  }