@geminilight/mindos 0.6.71 → 0.6.73
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/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +27 -27
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/react-loadable-manifest.json +4 -4
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +1 -1
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/connect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/embedding/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/test/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/webhook/feishu/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/webhook-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/clip/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/lint/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/direct-tools/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/space-overview/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changelog/page.js +1 -1
- package/_standalone/.next/server/app/changelog/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +1 -1
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +1 -1
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +1 -1
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +1 -1
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +1 -1
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +1 -1
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +1 -1
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +2 -2
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +27 -27
- package/_standalone/.next/server/chunks/{3311.js → 2449.js} +2 -2
- package/_standalone/.next/server/chunks/5299.js +1 -1
- package/_standalone/.next/server/chunks/6022.js +34 -34
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/{7143.879daa87569c5b02.js → 4094.09364c01df411380.js} +1 -1
- package/_standalone/.next/static/chunks/{5795.d9099a1afecd6047.js → 5331.c89084fd7f67887d.js} +2 -2
- package/_standalone/.next/static/chunks/app/{layout-a344709b8447be75.js → layout-fcbde5bee626d21a.js} +63 -63
- package/_standalone/.next/static/chunks/app/trash/page-e623ff0ab35de002.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-49c4eff6ffdb5168.js +12 -0
- package/_standalone/.next/static/chunks/{webpack-2f2787d3469d3df1.js → webpack-dc486b68118d1328.js} +1 -1
- package/_standalone/.next/trace +72 -72
- package/_standalone/package-lock.json +2 -2
- package/_standalone/package.json +1 -1
- package/app/package.json +1 -1
- package/package.json +1 -1
- package/_standalone/.next/static/chunks/app/trash/page-0907fdd06a4467de.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-f53ce199b4a4bbb5.js +0 -12
- package/browser-extension/README.md +0 -160
- package/browser-extension/build.mjs +0 -63
- package/browser-extension/extension/background/service-worker.js +0 -1
- package/browser-extension/extension/content/extractor.js +0 -2
- package/browser-extension/extension/icons/icon-128.png +0 -0
- package/browser-extension/extension/icons/icon-128.svg +0 -4
- package/browser-extension/extension/icons/icon-16.png +0 -0
- package/browser-extension/extension/icons/icon-16.svg +0 -4
- package/browser-extension/extension/icons/icon-32.png +0 -0
- package/browser-extension/extension/icons/icon-32.svg +0 -4
- package/browser-extension/extension/icons/icon-48.png +0 -0
- package/browser-extension/extension/icons/icon-48.svg +0 -4
- package/browser-extension/extension/manifest.json +0 -47
- package/browser-extension/extension/popup/popup.css +0 -510
- package/browser-extension/extension/popup/popup.html +0 -128
- package/browser-extension/extension/popup/popup.js +0 -73
- package/browser-extension/package-lock.json +0 -617
- package/browser-extension/package.json +0 -21
- package/browser-extension/scripts/gen-icons.sh +0 -38
- package/browser-extension/src/background/service-worker.ts +0 -27
- package/browser-extension/src/content/extractor.ts +0 -44
- package/browser-extension/src/icons/icon-128.png +0 -0
- package/browser-extension/src/icons/icon-128.svg +0 -4
- package/browser-extension/src/icons/icon-16.png +0 -0
- package/browser-extension/src/icons/icon-16.svg +0 -4
- package/browser-extension/src/icons/icon-32.png +0 -0
- package/browser-extension/src/icons/icon-32.svg +0 -4
- package/browser-extension/src/icons/icon-48.png +0 -0
- package/browser-extension/src/icons/icon-48.svg +0 -4
- package/browser-extension/src/lib/api.ts +0 -146
- package/browser-extension/src/lib/markdown.ts +0 -68
- package/browser-extension/src/lib/storage.ts +0 -37
- package/browser-extension/src/lib/types.ts +0 -42
- package/browser-extension/src/manifest.json +0 -47
- package/browser-extension/src/popup/popup.css +0 -510
- package/browser-extension/src/popup/popup.html +0 -128
- package/browser-extension/src/popup/popup.ts +0 -416
- package/browser-extension/tsconfig.json +0 -16
- package/tests/e2e/README.md +0 -25
- package/tests/e2e/navigation.spec.ts +0 -14
- package/tests/e2e/playwright.config.ts +0 -14
- package/tests/integration/README.md +0 -25
- package/tests/integration/mcp-contract.test.ts +0 -57
- package/tests/integration/mcp-transport.test.ts +0 -361
- package/tests/integration/package-lock.json +0 -1463
- package/tests/integration/package.json +0 -8
- package/tests/integration/vitest.config.ts +0 -11
- package/tests/security-hardening.test.ts +0 -456
- package/tests/unit/build-integrity.test.ts +0 -137
- package/tests/unit/cli-build.test.ts +0 -180
- package/tests/unit/cli-config.test.ts +0 -257
- package/tests/unit/cli-mcp-install-toml.test.ts +0 -586
- package/tests/unit/cli-mcp-install.test.ts +0 -123
- package/tests/unit/cli-mcp-stdio-default.test.ts +0 -180
- package/tests/unit/cli-modules-load.test.ts +0 -64
- package/tests/unit/cli-port.test.ts +0 -87
- package/tests/unit/cli-skill-auto-copy.test.ts +0 -260
- package/tests/unit/cli-smoke.test.ts +0 -88
- package/tests/unit/cli-uninstall.test.ts +0 -218
- package/tests/unit/cli-update-root.test.ts +0 -89
- package/tests/unit/cli-user-flow-sim.test.ts +0 -506
- package/tests/unit/cli-wait-hint.test.ts +0 -86
- package/tests/unit/custom-agents.test.ts +0 -478
- package/tests/unit/dep-safety.test.ts +0 -126
- package/tests/unit/detect-system-lang.test.ts +0 -122
- package/tests/unit/mcp-build.test.ts +0 -162
- package/tests/unit/setup-needs-restart.test.ts +0 -139
- package/tests/unit/stop-restart.test.ts +0 -393
- package/tests/unit/vitest.config.ts +0 -8
- /package/_standalone/.next/static/{w5bqzZbd2_vdoPRB0JQ_I → Dn8EHqUedSzanCfrM8WWS}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{w5bqzZbd2_vdoPRB0JQ_I → Dn8EHqUedSzanCfrM8WWS}/_ssgManifest.js +0 -0
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/* ── Service Worker — Context menu + keyboard shortcut handler ── */
|
|
2
|
-
|
|
3
|
-
/** Create context menu on install */
|
|
4
|
-
chrome.runtime.onInstalled.addListener(() => {
|
|
5
|
-
chrome.contextMenus.create({
|
|
6
|
-
id: 'clip-to-mindos',
|
|
7
|
-
title: 'Save to MindOS',
|
|
8
|
-
contexts: ['page', 'selection'],
|
|
9
|
-
});
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
/** Handle context menu click */
|
|
13
|
-
chrome.contextMenus.onClicked.addListener((info, tab) => {
|
|
14
|
-
if (info.menuItemId !== 'clip-to-mindos' || !tab?.id) return;
|
|
15
|
-
// Open popup programmatically — Manifest V3 doesn't allow this directly,
|
|
16
|
-
// so we send a message to the content script to trigger the popup.
|
|
17
|
-
chrome.action.openPopup().catch(() => {
|
|
18
|
-
// Fallback: some browsers don't support openPopup()
|
|
19
|
-
// The user can click the extension icon instead
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
/** Handle keyboard shortcut */
|
|
24
|
-
chrome.commands.onCommand.addListener((command) => {
|
|
25
|
-
if (command !== 'clip-page') return;
|
|
26
|
-
chrome.action.openPopup().catch(() => {});
|
|
27
|
-
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/* ── Content Script — Extracts page content via Readability ── */
|
|
2
|
-
/* Injected on demand by popup via chrome.scripting.executeScript() */
|
|
3
|
-
|
|
4
|
-
import { Readability } from '@mozilla/readability';
|
|
5
|
-
|
|
6
|
-
/** Extract article content from the current page */
|
|
7
|
-
function extractPageContent() {
|
|
8
|
-
// Clone document so Readability mutations don't affect the live page
|
|
9
|
-
const docClone = document.cloneNode(true) as Document;
|
|
10
|
-
|
|
11
|
-
const reader = new Readability(docClone, {
|
|
12
|
-
charThreshold: 100,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const article = reader.parse();
|
|
16
|
-
|
|
17
|
-
const title = article?.title || document.title || 'Untitled';
|
|
18
|
-
const content = article?.content || document.body.innerHTML;
|
|
19
|
-
const textContent = article?.textContent || document.body.textContent || '';
|
|
20
|
-
|
|
21
|
-
// Word count: handle both space-separated languages and CJK
|
|
22
|
-
const latinWords = textContent.split(/\s+/).filter(Boolean).length;
|
|
23
|
-
// CJK characters (Chinese, Japanese kanji, Korean hangul)
|
|
24
|
-
const cjkChars = (textContent.match(/[\u4e00-\u9fff\u3400-\u4dbf\uac00-\ud7af]/g) || []).length;
|
|
25
|
-
// For CJK-heavy content, use character count; otherwise word count
|
|
26
|
-
const wordCount = cjkChars > latinWords ? cjkChars : latinWords;
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
title,
|
|
30
|
-
byline: article?.byline || null,
|
|
31
|
-
excerpt: article?.excerpt || null,
|
|
32
|
-
content,
|
|
33
|
-
textContent,
|
|
34
|
-
siteName: article?.siteName || null,
|
|
35
|
-
url: window.location.href,
|
|
36
|
-
savedAt: new Date().toISOString(),
|
|
37
|
-
wordCount,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Store result on window so popup can read it via a second executeScript call.
|
|
42
|
-
// (esbuild IIFE wraps in `(() => { ... })()` which discards the return value,
|
|
43
|
-
// so we can't rely on executeScript capturing it directly.)
|
|
44
|
-
(window as any).__mindosClipResult = extractPageContent();
|
|
Binary file
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
|
2
|
-
<rect width="128" height="128" rx="20" fill="#c8873a"/>
|
|
3
|
-
<text x="64" y="96" font-family="Arial,Helvetica,sans-serif" font-weight="bold" font-size="96" fill="#ffffff" text-anchor="middle">M</text>
|
|
4
|
-
</svg>
|
|
Binary file
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
|
2
|
-
<rect width="16" height="16" rx="3" fill="#c8873a"/>
|
|
3
|
-
<text x="8" y="12.5" font-family="Arial,Helvetica,sans-serif" font-weight="bold" font-size="12" fill="#ffffff" text-anchor="middle">M</text>
|
|
4
|
-
</svg>
|
|
Binary file
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
2
|
-
<rect width="32" height="32" rx="6" fill="#c8873a"/>
|
|
3
|
-
<text x="16" y="24" font-family="Arial,Helvetica,sans-serif" font-weight="bold" font-size="24" fill="#ffffff" text-anchor="middle">M</text>
|
|
4
|
-
</svg>
|
|
Binary file
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
|
|
2
|
-
<rect width="48" height="48" rx="8" fill="#c8873a"/>
|
|
3
|
-
<text x="24" y="36" font-family="Arial,Helvetica,sans-serif" font-weight="bold" font-size="36" fill="#ffffff" text-anchor="middle">M</text>
|
|
4
|
-
</svg>
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/* ── MindOS API Client ── */
|
|
2
|
-
|
|
3
|
-
import type { ClipperConfig, MindOSSpace, FileApiResponse } from './types';
|
|
4
|
-
|
|
5
|
-
const REQUEST_TIMEOUT = 8000;
|
|
6
|
-
|
|
7
|
-
/** Fetch with timeout + auth */
|
|
8
|
-
async function apiFetch(
|
|
9
|
-
config: ClipperConfig,
|
|
10
|
-
path: string,
|
|
11
|
-
init?: RequestInit,
|
|
12
|
-
): Promise<Response> {
|
|
13
|
-
const controller = new AbortController();
|
|
14
|
-
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT);
|
|
15
|
-
try {
|
|
16
|
-
const url = `${config.mindosUrl.replace(/\/+$/, '')}${path}`;
|
|
17
|
-
return await fetch(url, {
|
|
18
|
-
...init,
|
|
19
|
-
signal: controller.signal,
|
|
20
|
-
headers: {
|
|
21
|
-
'Content-Type': 'application/json',
|
|
22
|
-
'Authorization': `Bearer ${config.authToken}`,
|
|
23
|
-
...(init?.headers ?? {}),
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
} finally {
|
|
27
|
-
clearTimeout(timer);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Check if MindOS is running and token is valid */
|
|
32
|
-
export async function testConnection(config: ClipperConfig): Promise<{
|
|
33
|
-
ok: boolean;
|
|
34
|
-
error?: string;
|
|
35
|
-
}> {
|
|
36
|
-
try {
|
|
37
|
-
// Health check (no auth required)
|
|
38
|
-
const healthRes = await apiFetch(config, '/api/health');
|
|
39
|
-
if (!healthRes.ok) {
|
|
40
|
-
return { ok: false, error: `Server returned ${healthRes.status}` };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Auth check — try listing spaces
|
|
44
|
-
const spacesRes = await apiFetch(config, '/api/file?op=list_spaces');
|
|
45
|
-
if (spacesRes.status === 401 || spacesRes.status === 403) {
|
|
46
|
-
return { ok: false, error: 'Invalid auth token' };
|
|
47
|
-
}
|
|
48
|
-
if (!spacesRes.ok) {
|
|
49
|
-
return { ok: false, error: `Auth check failed (${spacesRes.status})` };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return { ok: true };
|
|
53
|
-
} catch (err) {
|
|
54
|
-
if (err instanceof DOMException && err.name === 'AbortError') {
|
|
55
|
-
return { ok: false, error: 'Connection timed out' };
|
|
56
|
-
}
|
|
57
|
-
return { ok: false, error: 'Cannot reach MindOS — is it running?' };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** List available spaces (top-level directories) */
|
|
62
|
-
export async function listSpaces(config: ClipperConfig): Promise<MindOSSpace[]> {
|
|
63
|
-
try {
|
|
64
|
-
const res = await apiFetch(config, '/api/file?op=list_spaces');
|
|
65
|
-
if (!res.ok) return [];
|
|
66
|
-
const data = await res.json();
|
|
67
|
-
return (data.spaces ?? []) as MindOSSpace[];
|
|
68
|
-
} catch {
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** List all directory paths (flat list for hierarchical picker) */
|
|
74
|
-
export async function listDirs(config: ClipperConfig): Promise<string[]> {
|
|
75
|
-
try {
|
|
76
|
-
const res = await apiFetch(config, '/api/file?op=list_dirs');
|
|
77
|
-
if (!res.ok) return [];
|
|
78
|
-
const data = await res.json();
|
|
79
|
-
return (data.dirs ?? []) as string[];
|
|
80
|
-
} catch {
|
|
81
|
-
return [];
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** Save markdown to Inbox */
|
|
86
|
-
export async function saveToInbox(
|
|
87
|
-
config: ClipperConfig,
|
|
88
|
-
fileName: string,
|
|
89
|
-
markdown: string,
|
|
90
|
-
): Promise<FileApiResponse> {
|
|
91
|
-
try {
|
|
92
|
-
const res = await apiFetch(config, '/api/inbox', {
|
|
93
|
-
method: 'POST',
|
|
94
|
-
body: JSON.stringify({
|
|
95
|
-
files: [{ name: fileName, content: markdown, encoding: 'text' }],
|
|
96
|
-
source: 'web-clipper',
|
|
97
|
-
}),
|
|
98
|
-
});
|
|
99
|
-
let data: any;
|
|
100
|
-
try {
|
|
101
|
-
data = await res.json();
|
|
102
|
-
} catch {
|
|
103
|
-
return { error: `Server returned invalid response (${res.status})` };
|
|
104
|
-
}
|
|
105
|
-
if (!res.ok) {
|
|
106
|
-
return { error: data.error ?? `Server error (${res.status})` };
|
|
107
|
-
}
|
|
108
|
-
return { ok: true };
|
|
109
|
-
} catch (err) {
|
|
110
|
-
if (err instanceof DOMException && err.name === 'AbortError') {
|
|
111
|
-
return { error: 'Request timed out' };
|
|
112
|
-
}
|
|
113
|
-
return { error: 'Cannot reach MindOS — is it running?' };
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** Create file in a specific space */
|
|
118
|
-
export async function createFile(
|
|
119
|
-
config: ClipperConfig,
|
|
120
|
-
space: string,
|
|
121
|
-
fileName: string,
|
|
122
|
-
content: string,
|
|
123
|
-
): Promise<FileApiResponse> {
|
|
124
|
-
const path = space ? `${space.replace(/\/+$/, '')}/${fileName}` : fileName;
|
|
125
|
-
try {
|
|
126
|
-
const res = await apiFetch(config, '/api/file', {
|
|
127
|
-
method: 'POST',
|
|
128
|
-
body: JSON.stringify({ op: 'create_file', path, content, source: 'web-clipper' }),
|
|
129
|
-
});
|
|
130
|
-
let data: any;
|
|
131
|
-
try {
|
|
132
|
-
data = await res.json();
|
|
133
|
-
} catch {
|
|
134
|
-
return { error: `Server returned invalid response (${res.status})` };
|
|
135
|
-
}
|
|
136
|
-
if (!res.ok) {
|
|
137
|
-
return { error: data.error ?? `Server error (${res.status})` };
|
|
138
|
-
}
|
|
139
|
-
return { ok: true };
|
|
140
|
-
} catch (err) {
|
|
141
|
-
if (err instanceof DOMException && err.name === 'AbortError') {
|
|
142
|
-
return { error: 'Request timed out' };
|
|
143
|
-
}
|
|
144
|
-
return { error: 'Cannot reach MindOS — is it running?' };
|
|
145
|
-
}
|
|
146
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/* ── Markdown Conversion Pipeline ── */
|
|
2
|
-
|
|
3
|
-
import type { PageContent, ClipDocument } from './types';
|
|
4
|
-
|
|
5
|
-
/** Sanitize a string for use as filename */
|
|
6
|
-
export function sanitizeFileName(title: string): string {
|
|
7
|
-
return title
|
|
8
|
-
.replace(/[\/\\?*:|"<>]/g, '-') // illegal fs chars
|
|
9
|
-
.replace(/\s+/g, ' ') // collapse whitespace
|
|
10
|
-
.replace(/^\.+/, '') // no leading dots
|
|
11
|
-
.trim()
|
|
12
|
-
.slice(0, 120) // cap length
|
|
13
|
-
|| 'Untitled';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** Generate YAML frontmatter block */
|
|
17
|
-
function frontmatter(meta: Record<string, string | null | undefined>): string {
|
|
18
|
-
const lines = ['---'];
|
|
19
|
-
// YAML reserved words and special patterns that need quoting
|
|
20
|
-
const yamlReserved = /^(true|false|null|yes|no|on|off|~)$/i;
|
|
21
|
-
const yamlSpecialStart = /^[*&!@`>|%-]/;
|
|
22
|
-
|
|
23
|
-
for (const [key, val] of Object.entries(meta)) {
|
|
24
|
-
if (val == null || val === '') continue;
|
|
25
|
-
// Collapse newlines (YAML scalar values must be single-line in flow style)
|
|
26
|
-
const clean = val.replace(/[\r\n]+/g, ' ').trim();
|
|
27
|
-
// Quote if value contains YAML-special characters or is a reserved word
|
|
28
|
-
const needsQuote = clean.includes(':') || clean.includes('#') || clean.includes("'")
|
|
29
|
-
|| clean.includes('"') || clean.includes('[') || clean.includes('{')
|
|
30
|
-
|| yamlReserved.test(clean) || yamlSpecialStart.test(clean);
|
|
31
|
-
const safe = needsQuote
|
|
32
|
-
? `"${clean.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`
|
|
33
|
-
: clean;
|
|
34
|
-
lines.push(`${key}: ${safe}`);
|
|
35
|
-
}
|
|
36
|
-
lines.push('---', '');
|
|
37
|
-
return lines.join('\n');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Convert extracted PageContent → ClipDocument */
|
|
41
|
-
export function toClipDocument(
|
|
42
|
-
page: PageContent,
|
|
43
|
-
space: string,
|
|
44
|
-
turndownHtml: (html: string) => string,
|
|
45
|
-
): ClipDocument {
|
|
46
|
-
const fileName = sanitizeFileName(page.title) + '.md';
|
|
47
|
-
|
|
48
|
-
// Convert HTML content to Markdown
|
|
49
|
-
const bodyMd = turndownHtml(page.content);
|
|
50
|
-
|
|
51
|
-
// Build frontmatter
|
|
52
|
-
const fm = frontmatter({
|
|
53
|
-
title: page.title,
|
|
54
|
-
source: page.url,
|
|
55
|
-
author: page.byline,
|
|
56
|
-
site: page.siteName,
|
|
57
|
-
saved: page.savedAt,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const markdown = `${fm}# ${page.title}\n\n${bodyMd}\n`;
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
fileName,
|
|
64
|
-
markdown,
|
|
65
|
-
space,
|
|
66
|
-
wordCount: page.wordCount,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/* ── Chrome Storage Wrapper ── */
|
|
2
|
-
|
|
3
|
-
import type { ClipperConfig } from './types';
|
|
4
|
-
|
|
5
|
-
const STORAGE_KEY = 'mindos_clipper_config';
|
|
6
|
-
|
|
7
|
-
const DEFAULT_CONFIG: ClipperConfig = {
|
|
8
|
-
mindosUrl: 'http://localhost:3456',
|
|
9
|
-
authToken: '',
|
|
10
|
-
defaultSpace: 'Inbox',
|
|
11
|
-
connected: false,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/** Read config from chrome.storage.local */
|
|
15
|
-
export async function loadConfig(): Promise<ClipperConfig> {
|
|
16
|
-
try {
|
|
17
|
-
const result = await chrome.storage.local.get(STORAGE_KEY);
|
|
18
|
-
const stored = result[STORAGE_KEY];
|
|
19
|
-
if (!stored) return { ...DEFAULT_CONFIG };
|
|
20
|
-
return { ...DEFAULT_CONFIG, ...stored };
|
|
21
|
-
} catch {
|
|
22
|
-
return { ...DEFAULT_CONFIG };
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Save config to chrome.storage.local */
|
|
27
|
-
export async function saveConfig(config: Partial<ClipperConfig>): Promise<ClipperConfig> {
|
|
28
|
-
const current = await loadConfig();
|
|
29
|
-
const merged = { ...current, ...config };
|
|
30
|
-
await chrome.storage.local.set({ [STORAGE_KEY]: merged });
|
|
31
|
-
return merged;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Check if extension is configured (has URL + token) */
|
|
35
|
-
export function isConfigured(config: ClipperConfig): boolean {
|
|
36
|
-
return !!config.mindosUrl && !!config.authToken;
|
|
37
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/* ── MindOS Web Clipper — Shared Types ── */
|
|
2
|
-
|
|
3
|
-
/** Stored extension configuration */
|
|
4
|
-
export interface ClipperConfig {
|
|
5
|
-
mindosUrl: string; // e.g. "http://localhost:3456"
|
|
6
|
-
authToken: string; // e.g. "abcd-1234-efgh-..."
|
|
7
|
-
defaultSpace: string; // e.g. "Clips"
|
|
8
|
-
connected: boolean; // last health check passed
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** Extracted page content before conversion */
|
|
12
|
-
export interface PageContent {
|
|
13
|
-
title: string;
|
|
14
|
-
byline: string | null; // author
|
|
15
|
-
excerpt: string | null; // description
|
|
16
|
-
content: string; // cleaned HTML from Readability
|
|
17
|
-
textContent: string; // plain text (for word count)
|
|
18
|
-
siteName: string | null;
|
|
19
|
-
url: string;
|
|
20
|
-
savedAt: string; // ISO date
|
|
21
|
-
wordCount: number;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Final markdown document ready to save */
|
|
25
|
-
export interface ClipDocument {
|
|
26
|
-
fileName: string; // sanitized filename with .md
|
|
27
|
-
markdown: string; // full document with frontmatter
|
|
28
|
-
space: string; // target space path
|
|
29
|
-
wordCount: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** MindOS space (folder) */
|
|
33
|
-
export interface MindOSSpace {
|
|
34
|
-
name: string;
|
|
35
|
-
path: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** API response from POST /api/file or /api/inbox */
|
|
39
|
-
export interface FileApiResponse {
|
|
40
|
-
ok?: boolean;
|
|
41
|
-
error?: string;
|
|
42
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"manifest_version": 3,
|
|
3
|
-
"name": "MindOS Web Clipper",
|
|
4
|
-
"version": "0.1.2",
|
|
5
|
-
"description": "Save any web page to your MindOS knowledge base — one click, beautifully formatted Markdown.",
|
|
6
|
-
"icons": {
|
|
7
|
-
"16": "icons/icon-16.png",
|
|
8
|
-
"32": "icons/icon-32.png",
|
|
9
|
-
"48": "icons/icon-48.png",
|
|
10
|
-
"128": "icons/icon-128.png"
|
|
11
|
-
},
|
|
12
|
-
"action": {
|
|
13
|
-
"default_popup": "popup/popup.html",
|
|
14
|
-
"default_icon": {
|
|
15
|
-
"16": "icons/icon-16.png",
|
|
16
|
-
"32": "icons/icon-32.png"
|
|
17
|
-
},
|
|
18
|
-
"default_title": "Clip to MindOS"
|
|
19
|
-
},
|
|
20
|
-
"background": {
|
|
21
|
-
"service_worker": "background/service-worker.js",
|
|
22
|
-
"type": "module"
|
|
23
|
-
},
|
|
24
|
-
"permissions": [
|
|
25
|
-
"storage",
|
|
26
|
-
"activeTab",
|
|
27
|
-
"scripting",
|
|
28
|
-
"contextMenus"
|
|
29
|
-
],
|
|
30
|
-
"host_permissions": [
|
|
31
|
-
"http://localhost:*/*",
|
|
32
|
-
"http://127.0.0.1:*/*",
|
|
33
|
-
"http://[::1]:*/*",
|
|
34
|
-
"http://10.*.*.*:*/*",
|
|
35
|
-
"http://172.16.*.*:*/*",
|
|
36
|
-
"http://192.168.*.*:*/*"
|
|
37
|
-
],
|
|
38
|
-
"commands": {
|
|
39
|
-
"clip-page": {
|
|
40
|
-
"suggested_key": {
|
|
41
|
-
"default": "Ctrl+Shift+M",
|
|
42
|
-
"mac": "Command+Shift+M"
|
|
43
|
-
},
|
|
44
|
-
"description": "Clip current page to MindOS"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|