@circuitwall/jarela 0.8.0 → 0.8.1
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +1 -537
- package/.next/standalone/.next/server/app/_not-found/page.js.map +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +23 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +47 -18
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +47 -18
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +36 -7
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.html +23 -2
- package/.next/standalone/.next/server/app/index.rsc +46 -17
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +46 -17
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +36 -7
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page.js +79690 -79580
- package/.next/standalone/.next/server/app/page.js.map +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup/page.js +1 -1
- package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +48 -19
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +48 -19
- package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +36 -7
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +1 -1
- package/.next/standalone/.next/server/chunks/4045.js +611 -0
- package/.next/standalone/.next/server/chunks/4045.js.map +1 -0
- package/.next/standalone/.next/server/chunks/5432.js +5 -2
- package/.next/standalone/.next/server/chunks/5432.js.map +1 -1
- package/.next/standalone/.next/server/chunks/{5745.js → 6765.js} +9 -551
- package/.next/standalone/.next/server/chunks/6765.js.map +1 -0
- package/.next/standalone/.next/server/chunks/7885.js +5 -2
- package/.next/standalone/.next/server/chunks/7885.js.map +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
- package/.next/standalone/.next/server/pages/404.html +23 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{3741-81560b0aef166f49.js → 3741-b70e2d1a48a087d6.js} +16 -9
- package/.next/standalone/.next/static/chunks/3741-b70e2d1a48a087d6.js.map +1 -0
- package/.next/standalone/.next/static/chunks/app/{layout-31009df0f341ccf5.js → layout-84c6f211a7a1ca36.js} +38 -5
- package/.next/standalone/.next/static/chunks/app/layout-84c6f211a7a1ca36.js.map +1 -0
- package/.next/standalone/.next/static/chunks/app/{page-108f526cb6e48b7b.js → page-31e4d0ad258be21a.js} +258 -122
- package/.next/standalone/.next/static/chunks/app/page-31e4d0ad258be21a.js.map +1 -0
- package/.next/standalone/.next/static/css/af02b3acc7d8f08d.css +5 -0
- package/.next/standalone/.next/static/css/af02b3acc7d8f08d.css.map +1 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/public/manifest.json +2 -2
- package/CHANGELOG.md +24 -0
- package/api/types.ts +3 -1
- package/app/layout.tsx +30 -1
- package/components/agents/AgentEditor.tsx +5 -5
- package/components/layout/AppShell.tsx +36 -18
- package/components/layout/MenuPanel.tsx +7 -7
- package/components/models/ModelEditor.tsx +3 -3
- package/components/profile/ProfileEditor.tsx +9 -9
- package/components/profile/ProfilePanel.tsx +3 -3
- package/components/setup/OnboardingWizard.tsx +4 -4
- package/components/ui/HeaderActivity.tsx +24 -0
- package/contexts/AppContext.tsx +12 -4
- package/contexts/ThemeContext.tsx +30 -1
- package/hooks/useSSE.ts +42 -5
- package/lib/agents/base.ts +3 -1
- package/lib/agents/run-thread.ts +6 -3
- package/lib/ui/loading.ts +59 -0
- package/package.json +1 -1
- package/public/manifest.json +2 -2
- package/.next/standalone/.next/server/chunks/5745.js.map +0 -1
- package/.next/standalone/.next/static/chunks/3741-81560b0aef166f49.js.map +0 -1
- package/.next/standalone/.next/static/chunks/app/layout-31009df0f341ccf5.js.map +0 -1
- package/.next/standalone/.next/static/chunks/app/page-108f526cb6e48b7b.js.map +0 -1
- package/.next/standalone/.next/static/css/a23baa1c79db0435.css +0 -5
- package/.next/standalone/.next/static/css/a23baa1c79db0435.css.map +0 -1
- package/components/ui/TopProgressBar.tsx +0 -32
- /package/.next/standalone/.next/static/{0ImXz-nn9QbojXpTvB3i0 → yk5tOLkAUA4hfQKDjGbzK}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{0ImXz-nn9QbojXpTvB3i0 → yk5tOLkAUA4hfQKDjGbzK}/_ssgManifest.js +0 -0
|
@@ -64,9 +64,26 @@ function readStored() {
|
|
|
64
64
|
return "system";
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
const LIGHT_CHROME = "#ffffff";
|
|
68
|
+
const DARK_CHROME = "#09090b";
|
|
69
|
+
function resolveChrome(theme) {
|
|
70
|
+
if (theme === "light") return LIGHT_CHROME;
|
|
71
|
+
if (theme === "dark") return DARK_CHROME;
|
|
72
|
+
if (false) {}
|
|
73
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? DARK_CHROME : LIGHT_CHROME;
|
|
74
|
+
}
|
|
75
|
+
// Keep the single <meta name="theme-color"> tag (installed by the pre-paint
|
|
76
|
+
// script in app/layout.tsx) aligned with the active surface so the PWA's
|
|
77
|
+
// desktop title bar and mobile address bar match the theme.
|
|
78
|
+
function syncChrome(theme) {
|
|
79
|
+
if (typeof document === "undefined") return;
|
|
80
|
+
const meta = document.querySelector('meta[name="theme-color"]');
|
|
81
|
+
if (meta) meta.setAttribute("content", resolveChrome(theme));
|
|
82
|
+
}
|
|
67
83
|
function apply(theme) {
|
|
68
84
|
if (typeof document === "undefined") return;
|
|
69
85
|
document.documentElement.setAttribute("data-theme", theme);
|
|
86
|
+
syncChrome(theme);
|
|
70
87
|
}
|
|
71
88
|
const ThemeContext = /*#__PURE__*/ (0,react__WEBPACK_IMPORTED_MODULE_1__.createContext)(null);
|
|
72
89
|
function ThemeProvider({ children }) {
|
|
@@ -75,7 +92,16 @@ function ThemeProvider({ children }) {
|
|
|
75
92
|
// React state to whatever the script (or localStorage) decided.
|
|
76
93
|
const [theme, setThemeState] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)("system");
|
|
77
94
|
(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{
|
|
78
|
-
|
|
95
|
+
const stored = readStored();
|
|
96
|
+
setThemeState(stored);
|
|
97
|
+
// When in "system" mode, mirror OS-level changes into the PWA chrome.
|
|
98
|
+
if (false) {}
|
|
99
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
100
|
+
const onChange = ()=>{
|
|
101
|
+
if (readStored() === "system") syncChrome("system");
|
|
102
|
+
};
|
|
103
|
+
mq.addEventListener?.("change", onChange);
|
|
104
|
+
return ()=>mq.removeEventListener?.("change", onChange);
|
|
79
105
|
}, []);
|
|
80
106
|
const setTheme = (0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)((t)=>{
|
|
81
107
|
setThemeState(t);
|
|
@@ -115,6 +141,13 @@ function useTheme() {
|
|
|
115
141
|
/* __next_internal_client_entry_do_not_use__ AppProvider,useAppContext auto */
|
|
116
142
|
|
|
117
143
|
const EXPERIENCE_MODE_KEY = "jarela.experience.mode";
|
|
144
|
+
// Back-compat: pre-rename builds stored "normal" / "advanced". Read those
|
|
145
|
+
// values silently so an upgrade does not reset the user's choice.
|
|
146
|
+
function parseStoredMode(raw) {
|
|
147
|
+
if (raw === "essential" || raw === "normal") return "essential";
|
|
148
|
+
if (raw === "full" || raw === "advanced") return "full";
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
118
151
|
function reducer(state, action) {
|
|
119
152
|
switch(action.type){
|
|
120
153
|
case "SELECT_THREAD":
|
|
@@ -166,13 +199,13 @@ function AppProvider({ children }) {
|
|
|
166
199
|
activeThreadId: null,
|
|
167
200
|
activeAgentId: null,
|
|
168
201
|
activeTab: "chat",
|
|
169
|
-
experienceMode: "
|
|
202
|
+
experienceMode: "essential",
|
|
170
203
|
selectedItem: {}
|
|
171
204
|
});
|
|
172
205
|
(0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{
|
|
173
206
|
try {
|
|
174
|
-
const stored = window.localStorage.getItem(EXPERIENCE_MODE_KEY);
|
|
175
|
-
if (stored
|
|
207
|
+
const stored = parseStoredMode(window.localStorage.getItem(EXPERIENCE_MODE_KEY));
|
|
208
|
+
if (stored) {
|
|
176
209
|
dispatch({
|
|
177
210
|
type: "SET_EXPERIENCE_MODE",
|
|
178
211
|
mode: stored
|
|
@@ -237,4 +270,4 @@ Promise.resolve(/* import() eager */).then(__webpack_require__.bind(__webpack_re
|
|
|
237
270
|
/******/ _N_E = __webpack_exports__;
|
|
238
271
|
/******/ }
|
|
239
272
|
]);
|
|
240
|
-
//# sourceMappingURL=layout-
|
|
273
|
+
//# sourceMappingURL=layout-84c6f211a7a1ca36.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static/chunks/app/layout-84c6f211a7a1ca36.js","mappings":"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","sources":["webpack://_N_E/./components/ui/ServiceWorkerRegistration.tsx","webpack://_N_E/./contexts/ThemeContext.tsx","webpack://_N_E/./contexts/AppContext.tsx","webpack://_N_E/./app/globals.css","webpack://_N_E/?1b55"],"sourcesContent":["\"use client\";\n\nimport { useEffect } from \"react\";\n\n/**\n * Registers the Serwist-generated service worker. Replaces the auto-injected\n * registration script that next-pwa used to emit. Only runs in production\n * (the SW is disabled in dev by withSerwist).\n */\nexport function ServiceWorkerRegistration() {\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (!(\"serviceWorker\" in navigator)) return;\n\n if (process.env.NODE_ENV !== \"production\") {\n // Dev mode safety: if a previous production build registered a SW,\n // it can keep serving stale assets even though SW is disabled now.\n // Purge registrations + caches once per tab session.\n const key = \"jarela.dev.sw-cleaned\";\n if (!window.sessionStorage.getItem(key)) {\n navigator.serviceWorker\n .getRegistrations()\n .then((regs) => Promise.all(regs.map((r) => r.unregister())))\n .catch(() => {\n /* ignore */\n });\n if (\"caches\" in window) {\n caches\n .keys()\n .then((names) => Promise.all(names.map((name) => caches.delete(name))))\n .catch(() => {\n /* ignore */\n });\n }\n window.sessionStorage.setItem(key, \"1\");\n }\n return;\n }\n\n // Defer to idle so we don't compete with the first paint.\n const register = () => {\n navigator.serviceWorker\n .register(\"/sw.js\", { scope: \"/\" })\n .catch((err) => {\n // Swallow — SW failures should never break the app.\n console.warn(\"[sw] registration failed:\", err);\n });\n };\n if (\"requestIdleCallback\" in window) {\n (window as Window & { requestIdleCallback: (cb: () => void) => void })\n .requestIdleCallback(register);\n } else {\n setTimeout(register, 1000);\n }\n }, []);\n return null;\n}\n","\"use client\";\nimport { createContext, useCallback, useContext, useEffect, useState, type ReactNode } from \"react\";\n\nexport type Theme = \"light\" | \"dark\" | \"system\";\n\nconst STORAGE_KEY = \"jarela-theme\";\n\nfunction isTheme(v: unknown): v is Theme {\n return v === \"light\" || v === \"dark\" || v === \"system\";\n}\n\nfunction readStored(): Theme {\n if (typeof window === \"undefined\") return \"system\";\n try {\n const v = window.localStorage.getItem(STORAGE_KEY);\n return isTheme(v) ? v : \"system\";\n } catch {\n return \"system\";\n }\n}\n\nconst LIGHT_CHROME = \"#ffffff\";\nconst DARK_CHROME = \"#09090b\";\n\nfunction resolveChrome(theme: Theme): string {\n if (theme === \"light\") return LIGHT_CHROME;\n if (theme === \"dark\") return DARK_CHROME;\n if (typeof window === \"undefined\") return DARK_CHROME;\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? DARK_CHROME : LIGHT_CHROME;\n}\n\n// Keep the single <meta name=\"theme-color\"> tag (installed by the pre-paint\n// script in app/layout.tsx) aligned with the active surface so the PWA's\n// desktop title bar and mobile address bar match the theme.\nfunction syncChrome(theme: Theme) {\n if (typeof document === \"undefined\") return;\n const meta = document.querySelector('meta[name=\"theme-color\"]');\n if (meta) meta.setAttribute(\"content\", resolveChrome(theme));\n}\n\nfunction apply(theme: Theme) {\n if (typeof document === \"undefined\") return;\n document.documentElement.setAttribute(\"data-theme\", theme);\n syncChrome(theme);\n}\n\ninterface Ctx {\n theme: Theme;\n setTheme: (t: Theme) => void;\n}\n\nconst ThemeContext = createContext<Ctx | null>(null);\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n // Initial state stays \"system\" on the server to match the pre-paint script,\n // which writes data-theme before React hydrates. The effect below syncs the\n // React state to whatever the script (or localStorage) decided.\n const [theme, setThemeState] = useState<Theme>(\"system\");\n\n useEffect(() => {\n const stored = readStored();\n setThemeState(stored);\n // When in \"system\" mode, mirror OS-level changes into the PWA chrome.\n if (typeof window === \"undefined\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const onChange = () => {\n if (readStored() === \"system\") syncChrome(\"system\");\n };\n mq.addEventListener?.(\"change\", onChange);\n return () => mq.removeEventListener?.(\"change\", onChange);\n }, []);\n\n const setTheme = useCallback((t: Theme) => {\n setThemeState(t);\n apply(t);\n try {\n window.localStorage.setItem(STORAGE_KEY, t);\n } catch {\n /* ignore quota / private-mode errors */\n }\n }, []);\n\n return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error(\"useTheme must be used within ThemeProvider\");\n return ctx;\n}\n","\"use client\";\nimport { createContext, useContext, useEffect, useReducer, type ReactNode } from \"react\";\n\nexport type ExperienceMode = \"essential\" | \"full\";\n\nconst EXPERIENCE_MODE_KEY = \"jarela.experience.mode\";\n\n// Back-compat: pre-rename builds stored \"normal\" / \"advanced\". Read those\n// values silently so an upgrade does not reset the user's choice.\nfunction parseStoredMode(raw: string | null): ExperienceMode | null {\n if (raw === \"essential\" || raw === \"normal\") return \"essential\";\n if (raw === \"full\" || raw === \"advanced\") return \"full\";\n return null;\n}\n\nexport type Tab = \"chat\" | \"dashboard\" | \"agents\" | \"memory\" | \"documents\" | \"models\" | \"mcp\" | \"extensions\" | \"tools\" | \"connections\" | \"tasks\" | \"bridges\" | \"profile\" | \"harness\";\n\ninterface AppState {\n activeThreadId: string | null;\n activeAgentId: string | null;\n activeTab: Tab;\n experienceMode: ExperienceMode;\n // Per-tab sub-selection (gmail in connections, an mcp server name, an\n // agent uuid, a profile subsection slug, …). Settings panels read their\n // slot to scroll-to + highlight; the URL mirrors this via `?item=<id>`.\n selectedItem: Partial<Record<Tab, string>>;\n}\n\ntype Action =\n | { type: \"SELECT_THREAD\"; threadId: string; agentId: string }\n | { type: \"NEW_CHAT\" }\n | { type: \"SET_AGENT\"; agentId: string }\n | { type: \"SET_TAB\"; tab: Tab }\n | { type: \"SET_EXPERIENCE_MODE\"; mode: ExperienceMode }\n | { type: \"SET_SELECTION\"; tab: Tab; itemId: string | null };\n\nfunction reducer(state: AppState, action: Action): AppState {\n switch (action.type) {\n case \"SELECT_THREAD\":\n return { ...state, activeThreadId: action.threadId, activeAgentId: action.agentId, activeTab: \"chat\" };\n case \"NEW_CHAT\":\n return { ...state, activeThreadId: null, activeAgentId: null, activeTab: \"chat\" };\n case \"SET_AGENT\":\n return { ...state, activeAgentId: action.agentId };\n case \"SET_TAB\":\n return { ...state, activeTab: action.tab };\n case \"SET_EXPERIENCE_MODE\":\n return { ...state, experienceMode: action.mode };\n case \"SET_SELECTION\": {\n const next = { ...state.selectedItem };\n if (action.itemId == null) delete next[action.tab];\n else next[action.tab] = action.itemId;\n return { ...state, selectedItem: next };\n }\n }\n}\n\nconst AppContext = createContext<{ state: AppState; dispatch: React.Dispatch<Action> } | null>(null);\n\nexport function AppProvider({ children }: { children: ReactNode }) {\n const [state, dispatch] = useReducer(reducer, {\n activeThreadId: null,\n activeAgentId: null,\n activeTab: \"chat\",\n experienceMode: \"essential\",\n selectedItem: {},\n });\n\n useEffect(() => {\n try {\n const stored = parseStoredMode(window.localStorage.getItem(EXPERIENCE_MODE_KEY));\n if (stored) {\n dispatch({ type: \"SET_EXPERIENCE_MODE\", mode: stored });\n }\n } catch {\n // ignore storage failures\n }\n }, []);\n\n useEffect(() => {\n try {\n window.localStorage.setItem(EXPERIENCE_MODE_KEY, state.experienceMode);\n } catch {\n // ignore storage failures\n }\n }, [state.experienceMode]);\n\n return <AppContext.Provider value={{ state, dispatch }}>{children}</AppContext.Provider>;\n}\n\nexport function useAppContext() {\n const ctx = useContext(AppContext);\n if (!ctx) throw new Error(\"useAppContext must be used within AppProvider\");\n return ctx;\n}\n","// extracted by mini-css-extract-plugin","import(/* webpackMode: \"eager\" */ \"/home/runner/work/jarela/jarela/app/globals.css\");\n;\nimport(/* webpackMode: \"eager\", webpackExports: [\"ServiceWorkerRegistration\"] */ \"/home/runner/work/jarela/jarela/components/ui/ServiceWorkerRegistration.tsx\");\n;\nimport(/* webpackMode: \"eager\", webpackExports: [\"AppProvider\"] */ \"/home/runner/work/jarela/jarela/contexts/AppContext.tsx\");\n;\nimport(/* webpackMode: \"eager\", webpackExports: [\"ThemeProvider\"] */ \"/home/runner/work/jarela/jarela/contexts/ThemeContext.tsx\");\n"],"names":["useEffect","ServiceWorkerRegistration","navigator","process","key","window","sessionStorage","getItem","serviceWorker","getRegistrations","then","regs","Promise","all","map","r","unregister","catch","caches","keys","names","name","delete","setItem","register","scope","err","console","warn","requestIdleCallback","setTimeout","createContext","useCallback","useContext","useState","STORAGE_KEY","isTheme","v","readStored","localStorage","LIGHT_CHROME","DARK_CHROME","resolveChrome","theme","matchMedia","matches","syncChrome","document","meta","querySelector","setAttribute","apply","documentElement","ThemeContext","ThemeProvider","children","setThemeState","stored","mq","onChange","addEventListener","removeEventListener","setTheme","t","Provider","value","useTheme","ctx","Error","useReducer","EXPERIENCE_MODE_KEY","parseStoredMode","raw","reducer","state","action","type","activeThreadId","threadId","activeAgentId","agentId","activeTab","tab","experienceMode","mode","next","selectedItem","itemId","AppContext","AppProvider","dispatch","useAppContext"],"sourceRoot":"","ignoreList":[]}
|