@agentprojectcontext/apx 1.70.0 → 1.71.0
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.
- package/package.json +1 -1
- package/src/core/agent/tools/handlers/call-agent.js +7 -1
- package/src/core/agent/tools/handlers/obsidian-write-note.js +1 -1
- package/src/core/channels/telegram/dispatch.js +3 -2
- package/src/core/integrations/obsidian-memory.js +82 -11
- package/src/core/integrations/plugins/obsidian.js +40 -0
- package/src/core/memory/broker.js +8 -3
- package/src/core/memory/index.js +36 -3
- package/src/core/memory/store.js +13 -1
- package/src/interfaces/web/dist/assets/{index-YFsZFhM6.js → index-CX15mZXM.js} +99 -99
- package/src/interfaces/web/dist/assets/index-CX15mZXM.js.map +1 -0
- package/src/interfaces/web/dist/index.html +1 -1
- package/src/interfaces/web/src/components/common/TabNav.tsx +10 -3
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +12 -2
- package/src/interfaces/web/dist/assets/index-YFsZFhM6.js.map +0 -1
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<link rel="apple-touch-icon" href="/favicon/dark/apple-touch-icon.png" media="(prefers-color-scheme: dark)" />
|
|
19
19
|
<link rel="manifest" href="/favicon/white/site.webmanifest" media="(prefers-color-scheme: light)" />
|
|
20
20
|
<link rel="manifest" href="/favicon/dark/site.webmanifest" media="(prefers-color-scheme: dark)" />
|
|
21
|
-
<script type="module" crossorigin src="/assets/index-
|
|
21
|
+
<script type="module" crossorigin src="/assets/index-CX15mZXM.js"></script>
|
|
22
22
|
<link rel="stylesheet" crossorigin href="/assets/index-CDz9OwCP.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body class="bg-background text-foreground antialiased">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Left-rail tab nav used inside Settings + per-project screens. Mirrors
|
|
2
2
|
// the panda.project sectioned-nav pattern: optional section title above
|
|
3
3
|
// each group, icon + label rows, active state in the section's tone.
|
|
4
|
-
import { useState, useEffect, useCallback, Fragment, type ElementType } from "react";
|
|
4
|
+
import { useState, useEffect, useCallback, Fragment, type ElementType, type ReactNode } from "react";
|
|
5
5
|
import { PanelLeft } from "lucide-react";
|
|
6
6
|
import { cn } from "../../lib/cn";
|
|
7
7
|
import { Tip } from "../ui/tip";
|
|
@@ -12,6 +12,9 @@ export interface TabItem {
|
|
|
12
12
|
label: string;
|
|
13
13
|
icon: ElementType;
|
|
14
14
|
badge?: string | number;
|
|
15
|
+
// Small decoration (e.g. an Obsidian mark on "Memories" when the vault is
|
|
16
|
+
// wired) — trailing when expanded, a corner overlay when collapsed.
|
|
17
|
+
mark?: ReactNode;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
export interface TabSection {
|
|
@@ -76,7 +79,7 @@ export function TabNav({ sections, active, onChange, collapsed = false }: TabNav
|
|
|
76
79
|
</p>
|
|
77
80
|
)}
|
|
78
81
|
<div className="space-y-0.5">
|
|
79
|
-
{section.items.map(({ key, label, icon: Icon, badge }) => {
|
|
82
|
+
{section.items.map(({ key, label, icon: Icon, badge, mark }) => {
|
|
80
83
|
const isActive = active === key;
|
|
81
84
|
const btn = (
|
|
82
85
|
<button
|
|
@@ -84,7 +87,7 @@ export function TabNav({ sections, active, onChange, collapsed = false }: TabNav
|
|
|
84
87
|
onClick={() => onChange(key)}
|
|
85
88
|
data-testid={`tabnav-${key || "index"}`}
|
|
86
89
|
className={cn(
|
|
87
|
-
"flex cursor-pointer items-center rounded-lg transition-colors",
|
|
90
|
+
"relative flex cursor-pointer items-center rounded-lg transition-colors",
|
|
88
91
|
collapsed ? "size-9 justify-center" : "w-full gap-2 px-2.5 py-1.5",
|
|
89
92
|
isActive
|
|
90
93
|
? "bg-accent text-accent-fg"
|
|
@@ -92,9 +95,13 @@ export function TabNav({ sections, active, onChange, collapsed = false }: TabNav
|
|
|
92
95
|
)}
|
|
93
96
|
>
|
|
94
97
|
<Icon className="size-4 shrink-0" />
|
|
98
|
+
{collapsed && mark && (
|
|
99
|
+
<span className="absolute -bottom-0.5 -right-0.5 flex items-center justify-center rounded-full bg-card">{mark}</span>
|
|
100
|
+
)}
|
|
95
101
|
{!collapsed && (
|
|
96
102
|
<>
|
|
97
103
|
<span className="flex-1 truncate text-left text-xs">{label}</span>
|
|
104
|
+
{mark && <span className="flex shrink-0 items-center">{mark}</span>}
|
|
98
105
|
{badge !== undefined && (
|
|
99
106
|
<span className="rounded-full bg-muted px-1.5 text-[9px] text-muted-fg">{badge}</span>
|
|
100
107
|
)}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
+
import useSWR from "swr";
|
|
2
3
|
import { useParams, Routes, Route, Navigate, useLocation, useNavigate } from "react-router-dom";
|
|
3
4
|
import {
|
|
4
5
|
Bot, Heart, Zap, Puzzle, Settings,
|
|
@@ -8,6 +9,8 @@ import {
|
|
|
8
9
|
} from "lucide-react";
|
|
9
10
|
import { useNavCollapse, type TabSection } from "../components/common/TabNav";
|
|
10
11
|
import { TabLayout } from "../components/common/TabLayout";
|
|
12
|
+
import { Integrations } from "../lib/api";
|
|
13
|
+
import { ObsidianLogo } from "../components/integrations/BrandLogos";
|
|
11
14
|
import { RobyEmpty } from "../components/Roby";
|
|
12
15
|
import { Button } from "../components/ui/button";
|
|
13
16
|
import { useProject } from "../hooks/useProjects";
|
|
@@ -50,7 +53,14 @@ export function ProjectScreen() {
|
|
|
50
53
|
const { collapsed, toggle } = useNavCollapse(STORAGE.sidebarCollapsed + ".project");
|
|
51
54
|
|
|
52
55
|
const isBase = String(pid) === "0";
|
|
56
|
+
// Obsidian-backed memory: when the vault integration is active, mark the
|
|
57
|
+
// Memories nav item so it's clear memory is mirrored through the vault.
|
|
58
|
+
const { data: catalog } = useSWR(`integrations-catalog-${pid}`, () => Integrations.catalog(pid), { shouldRetryOnError: false });
|
|
59
|
+
const obsidianEntry = catalog?.find((e) => e.slug === "obsidian");
|
|
60
|
+
const obsidianActive = obsidianEntry?.status?.status === "active" && !!obsidianEntry?.status?.is_enabled;
|
|
61
|
+
|
|
53
62
|
const sections: TabSection[] = useMemo(() => {
|
|
63
|
+
const memoriesMark = obsidianActive ? <ObsidianLogo className="size-3 text-purple-400" /> : undefined;
|
|
54
64
|
// One shared taxonomy for both Base and projects, in the same order, so the
|
|
55
65
|
// two menus mirror each other. Base additionally gets a "General" admin
|
|
56
66
|
// section (workspaces / engines / agent defaults) and drops "Content"
|
|
@@ -76,7 +86,7 @@ export function ProjectScreen() {
|
|
|
76
86
|
{ key: "", label: t("project.nav.overview"), icon: LayoutDashboard },
|
|
77
87
|
...(isCompany ? [{ key: "structure", label: t("project.nav.structure"), icon: Building2 }] : []),
|
|
78
88
|
{ key: "agents", label: t("project.nav.agents"), icon: Bot },
|
|
79
|
-
{ key: "memories", label: t("project.nav.memories"), icon: Brain },
|
|
89
|
+
{ key: "memories", label: t("project.nav.memories"), icon: Brain, mark: memoriesMark },
|
|
80
90
|
{ key: "skills", label: t("skills_page.title"), icon: Sparkles },
|
|
81
91
|
{ key: "artifacts", label: t("project.nav.artifacts"), icon: FileCode2 },
|
|
82
92
|
],
|
|
@@ -120,7 +130,7 @@ export function ProjectScreen() {
|
|
|
120
130
|
];
|
|
121
131
|
|
|
122
132
|
return out.filter(Boolean) as TabSection[];
|
|
123
|
-
}, [isBase, project?.kind]);
|
|
133
|
+
}, [isBase, project?.kind, obsidianActive]);
|
|
124
134
|
|
|
125
135
|
// First path segment after /p/:pid — so deep routes like agents/:slug still
|
|
126
136
|
// highlight the "agents" nav item.
|