{"_id":"@aisa-plugins/easy-search","_rev":"3-f7cda556fe888b3df27cca6fe1bc9a1a","name":"@aisa-plugins/easy-search","dist-tags":{"latest":"0.3.0"},"versions":{"0.2.0":{"name":"@aisa-plugins/easy-search","version":"0.2.0","keywords":["deepseek-harness","dsh","dsh-plugin","aisa","byok","tavily","serpapi","search","research","web-search"],"license":"MIT","_id":"@aisa-plugins/easy-search@0.2.0","maintainers":[{"name":"aisa-barry","email":"barry@aisa.one"}],"homepage":"https://github.com/AIsa-plugins/easy-dsh-plugin/tree/main/plugins/easy-search#readme","bugs":{"url":"https://github.com/AIsa-plugins/easy-dsh-plugin/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"e708a01519a41ed53ed7c181c42f237e6c671736","tarball":"https://registry.npmjs.org/@aisa-plugins/easy-search/-/easy-search-0.2.0.tgz","fileCount":8,"integrity":"sha512-IPxKVhrAs1eMrjv7meKqlL1pNqx6KmPP7lxkl6MVnQ1G9e/Nx5SgYbREu64JnJx/AKQvV2cU1JKWB2/PuwWUTg==","signatures":[{"sig":"MEUCIQDla8jM+VK7o2nt+9MNz5jSvXV79N0kQqwd88WGpglOWQIgaaiIaPgWlPfpiSjTeroFVb39Vlb6IWIOQ1SQ9aK+cxQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":184544},"main":"./lib/index.js","type":"module","types":"./lib/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"./package.json":"./package.json"},"gitHead":"2fdadf922f8b47137f4d54149f9b347b190d7fe8","scripts":{"test":"vitest run","build":"tsdown","check":"pnpm run typecheck && pnpm run test && pnpm run build","typecheck":"tsc -p tsconfig.json && tsc -p tsconfig.tests.json"},"_npmUser":{"name":"aisa-barry","email":"barry@aisa.one"},"repository":{"url":"git+https://github.com/AIsa-plugins/easy-dsh-plugin.git","type":"git","directory":"plugins/easy-search"},"_npmVersion":"10.9.8","description":"Provider-neutral search and extraction tools for DeepSeek Harness","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@deepseek-ai/schemastery":"^3.18.1"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.7.0","devDependencies":{"tsdown":"^0.22.2","vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^24.0.0","@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-tools":"0.1.0-rc.6","@deepseek-ai/dsh-settings":"0.1.0-rc.6","@deepseek-ai/dsh-credentials":"0.1.0-rc.6","@deepseek-ai/dsh-system-prompt":"0.1.0-rc.6"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6","@deepseek-ai/dsh-settings":"^0.1.0-rc.6","@deepseek-ai/dsh-credentials":"^0.1.0-rc.6","@deepseek-ai/dsh-system-prompt":"^0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/easy-search_0.2.0_1787424923223_0.13815245884752914","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aisa-plugins/easy-search","version":"0.2.1","keywords":["deepseek-harness","dsh","dsh-plugin","aisa","byok","tavily","serpapi","search","research","web-search"],"license":"MIT","_id":"@aisa-plugins/easy-search@0.2.1","maintainers":[{"name":"aisa-barry","email":"barry@aisa.one"}],"homepage":"https://github.com/AIsa-plugins/easy-dsh-plugin/tree/main/plugins/easy-search#readme","bugs":{"url":"https://github.com/AIsa-plugins/easy-dsh-plugin/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"4ec1b46dd494f843ec9f47bcdc44ab526bbbf7af","tarball":"https://registry.npmjs.org/@aisa-plugins/easy-search/-/easy-search-0.2.1.tgz","fileCount":8,"integrity":"sha512-3+GFQI6AVb1sE/ffbrdCIu2wpsBsnLrZ7eopf3K/vqWaRRY5DnDeAt61xUEpgY4aCsDFYzvVz8Eda3BkSEE8hA==","signatures":[{"sig":"MEUCIFCZwKLdQi+7SeMucTkbe+jF8cyuVr9EKFvCcdDMzWmQAiEApQt8gaeOSv6+RIOWWkyrsS+YwD9dz4/AIL8uHN9L3mE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGyJZToB/owWLKZo0OoYfr+1nC3kS5nJRuJhuRxP4h6DAiANqCzjsr/F3G/yn2Ak1+fMb95sFJaFoXhs19qMzGTQOA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aisa-plugins%2feasy-search@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":184556},"main":"./lib/index.js","type":"module","types":"./lib/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"./package.json":"./package.json"},"gitHead":"39d6dc9895f59dbde7c55f0552cba522fccdfa11","scripts":{"test":"vitest run","build":"tsdown","check":"pnpm run typecheck && pnpm run test && pnpm run build","typecheck":"tsc -p tsconfig.json && tsc -p tsconfig.tests.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1c4bcc74-6693-4189-9ca1-a7dc00bcf224"}},"repository":{"url":"git+https://github.com/AIsa-plugins/easy-dsh-plugin.git","type":"git","directory":"plugins/easy-search"},"_npmVersion":"12.0.2","description":"Provider-neutral search and extraction tools for DeepSeek Harness","directories":{},"_nodeVersion":"24.15.0","dependencies":{"@deepseek-ai/schemastery":"^3.18.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.7.0","devDependencies":{"tsdown":"^0.22.2","vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^24.0.0","@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-tools":"0.1.0-rc.6","@deepseek-ai/dsh-settings":"0.1.0-rc.6","@deepseek-ai/dsh-credentials":"0.1.0-rc.6","@deepseek-ai/dsh-system-prompt":"0.1.0-rc.6"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.0-rc.6","@deepseek-ai/dsh-settings":"^0.1.0-rc.6","@deepseek-ai/dsh-credentials":"^0.1.0-rc.6","@deepseek-ai/dsh-system-prompt":"^0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/easy-search_0.2.1_1787427880221_0.11500242564802465","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@aisa-plugins/easy-search@0.3.0","dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-settings-plugins"],"platform":"web"}},"bugs":{"url":"https://github.com/AIsa-plugins/easy-dsh-plugin/issues"},"dist":{"shasum":"005f162b2d477a862e091aec0d22516412b4f983","tarball":"https://registry.npmjs.org/@aisa-plugins/easy-search/-/easy-search-0.3.0.tgz","fileCount":10,"integrity":"sha512-pdFvu9bjSjeGvUjVzZoc/hMmlFNf+pOJyhd+bhmiQz9C+9j1BMfKwOfKbRs97v/VD5kQcfjWw/ofxqrzhnFzzw==","signatures":[{"sig":"MEUCIFT2jOHSxRdeuTtkDSFmJC6WldAJBWkYwswZ3oSkPTNfAiEAyY6kHysm6V0SNUECinHMfg+u8KEz8Jd1XvBNc/YiPzI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCg7wq0CSxFWtCXEZ+hitS8A38ehrFeHHk6N77VqTCVMgIgYARytPQ0uw6946L5Tl0B1FApfENLeBh5fE9NwZiLwG0="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aisa-plugins%2feasy-search@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":321444},"main":"./lib/index.js","name":"@aisa-plugins/easy-search","type":"module","types":"./lib/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"f2cb1792f1dd94ca8f5fa08f46422dddbc16dba8","license":"MIT","scripts":{"test":"vitest run","build":"tsdown","check":"pnpm run typecheck && pnpm run test && pnpm run build","typecheck":"tsc -p tsconfig.host.json && tsc -p tsconfig.client.json && tsc -p tsconfig.tests.json"},"version":"0.3.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1c4bcc74-6693-4189-9ca1-a7dc00bcf224"}},"homepage":"https://github.com/AIsa-plugins/easy-dsh-plugin/tree/main/plugins/easy-search#readme","keywords":["deepseek-harness","dsh","dsh-plugin","aisa","byok","tavily","serpapi","search","research","web-search"],"repository":{"url":"git+https://github.com/AIsa-plugins/easy-dsh-plugin.git","type":"git","directory":"plugins/easy-search"},"_npmVersion":"12.0.2","description":"Provider-neutral search and extraction tools for DeepSeek Harness","directories":{},"maintainers":[{"name":"aisa-barry","email":"barry@aisa.one"}],"_nodeVersion":"24.15.0","dependencies":{"@tabler/icons-react":"^3.46.0","@deepseek-ai/schemastery":"^3.18.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.7.0","devDependencies":{"react":"18.3.1","tsdown":"^0.22.2","vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^24.0.0","@types/react":"~18.3.1","@deepseek-ai/cordis":"4.0.1","@deepseek-ai/dsh-tools":"0.1.1-rc.2","@deepseek-ai/dsh-settings":"0.1.1-rc.2","@deepseek-ai/dsh-api-remotes":"0.1.1-rc.2","@deepseek-ai/dsh-credentials":"0.1.1-rc.2","@deepseek-ai/dsh-client-locale":"0.1.1-rc.2","@deepseek-ai/dsh-system-prompt":"0.1.1-rc.2","@deepseek-ai/dsh-client-runtime":"0.1.1-rc.2","@deepseek-ai/dsh-client-ui-slots":"0.1.1-rc.2","@deepseek-ai/dsh-client-connection":"0.1.1-rc.2","@deepseek-ai/dsh-client-ui-settings":"0.1.1-rc.2","@deepseek-ai/dsh-client-ui-settings-plugins":"0.1.1-rc.2"},"peerDependencies":{"react":"^18.2.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.1-rc.2","@deepseek-ai/dsh-settings":"^0.1.1-rc.2","@deepseek-ai/dsh-api-remotes":"^0.1.1-rc.2","@deepseek-ai/dsh-credentials":"^0.1.1-rc.2","@deepseek-ai/dsh-client-locale":"^0.1.1-rc.2","@deepseek-ai/dsh-system-prompt":"^0.1.1-rc.2","@deepseek-ai/dsh-client-runtime":"^0.1.1-rc.2","@deepseek-ai/dsh-client-ui-slots":"^0.1.1-rc.2","@deepseek-ai/dsh-client-connection":"^0.1.1-rc.2","@deepseek-ai/dsh-client-ui-settings":"^0.1.1-rc.2","@deepseek-ai/dsh-client-ui-settings-plugins":"^0.1.1-rc.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/easy-search_0.3.0_1787461558408_0.3882023681254494"}}},"time":{"created":"2026-08-22T18:55:23.101Z","modified":"2026-08-23T05:05:59.076Z","0.2.0":"2026-08-22T18:55:23.380Z","0.2.1":"2026-08-22T19:44:40.326Z","0.3.0":"2026-08-23T05:05:58.498Z"},"bugs":{"url":"https://github.com/AIsa-plugins/easy-dsh-plugin/issues"},"license":"MIT","homepage":"https://github.com/AIsa-plugins/easy-dsh-plugin/tree/main/plugins/easy-search#readme","keywords":["deepseek-harness","dsh","dsh-plugin","aisa","byok","tavily","serpapi","search","research","web-search"],"repository":{"url":"git+https://github.com/AIsa-plugins/easy-dsh-plugin.git","type":"git","directory":"plugins/easy-search"},"description":"Provider-neutral search and extraction tools for DeepSeek Harness","maintainers":[{"name":"aisa-barry","email":"barry@aisa.one"}],"readme":"# Easy Search\n\nEasy Search is an independently installable DeepSeek Harness bundle in the\n[Easy DSH Plugins](../..) collection. It adds provider-neutral search and page\nextraction tools while leaving settings, credentials, execution, replay, and UI\nshell ownership with Harness.\n\nThe plugin supports both an AIsa One Key and users' own provider credentials:\n\n- `aisa` routes every capability through AIsa.\n- `byok` calls each upstream provider directly.\n- `hybrid` prefers a configured direct credential and otherwise uses AIsa.\n\nHybrid routing falls back only when a direct credential is absent. It never\nreplays a failed request through another provider.\n\n## What it adds\n\n- `easy_search` searches the web, X, YouTube, and Scholar concurrently.\n- `easy_extract` retrieves clean Markdown from one to three public URLs.\n- Per-source provider and coverage metadata make partial failures explicit.\n- Native DSH web cards render citations and single-page extraction results.\n- Credentials are resolved once per tool operation and never enter tool input,\n  output, presentation metadata, or settings documents.\n\nThe collection root is a catalog, not a package. Easy Search owns this directory\nand has no runtime dependency on the legacy AIsa marketplace plugin.\n\n## Requirements\n\n- Node.js 22 or newer\n- DeepSeek Harness 0.1.1-rc.2 or newer\n- Credentials for the selected routing mode\n\n## Install\n\n### From npm\n\nInstall the published bundle into the profile that runs Harness:\n\n~~~sh\ndsh plugin --profile web add @aisa-plugins/easy-search\ndsh --profile web --dump-config\n~~~\n\nUse another profile name if your Harness deployment does not use `web`.\n\n### From a source checkout\n\n~~~sh\npnpm install --frozen-lockfile\npnpm --filter @aisa-plugins/easy-search check\ndsh plugin --profile web add ./plugins/easy-search\ndsh --profile web --dump-config\n~~~\n\nThe package ships its compiled `lib` directory, so installation does not run a\nbuild script.\n\n## Configure in DSH\n\nOrdinary setup stays inside DSH:\n\n1. Open **Settings → Plugins → Plugin configuration**.\n2. Expand **Easy Search** and choose a route.\n3. Paste the keys shown for that route.\n4. Select **Save changes**.\n\nThe card writes ordinary values through DSH Settings and secrets through DSH\nCredentials. A saved key is intentionally never read back into the browser;\nthe field clears and its badge changes to **Ready** instead. Changes apply to\nthe next tool operation without restarting DSH.\n\n### Routing\n\n| Mode | Selection rule | Missing credential | Request failure |\n| --- | --- | --- | --- |\n| `aisa` | Always AIsa | Operation fails | No provider switch |\n| `byok` | Always direct | Capability fails | No provider switch |\n| `hybrid` | Direct key if configured, otherwise AIsa | Falls back to AIsa | No provider switch |\n\nThe default is `aisa`, preserving the simplest One Key setup. Choose `hybrid`\nwhen direct keys should be used where available and AIsa should cover the\nremaining sources. Choose `byok` when every capability must use its native\nprovider.\n\n## Credentials\n\nSettings contain credential references, never secret values. The standard DSH\ncredential provider stores keys entered in the card. A launch-time environment\nvariable with the same reference takes precedence; the card reports it as\nconfigured but read-only rather than pretending it can replace it.\n\n| Capability | Direct provider | Default reference |\n| --- | --- | --- |\n| All AIsa routes | AIsa | `AISA_API_KEY` |\n| Web search and extraction | Tavily | `TAVILY_API_KEY` |\n| X search | X API v2 | `X_BEARER_TOKEN` |\n| YouTube search | YouTube Data API v3 | `YOUTUBE_API_KEY` |\n| Scholar search | SerpApi Google Scholar | `SERPAPI_API_KEY` |\n\nOne immutable credential snapshot is shared by all requests in a single tool\noperation. A later operation resolves credentials again, so settings changes do\nnot require a plugin restart.\n\nCredential references are scoped to the DSH deployment, not to an individual\nbrowser session. Separate tenant secrets therefore require separate DSH homes\nor another credential provider; Easy Search deliberately does not add a second\nsecret store.\n\n## Configuration\n\n| Setting | Default | Purpose |\n| --- | --- | --- |\n| Routing mode | `aisa` | `aisa`, `byok`, or `hybrid` |\n| AIsa key reference | `AISA_API_KEY` | One Key credential |\n| AIsa base URL | `https://api.aisa.one` | Origin used only for AIsa routes |\n| Tavily key reference | `TAVILY_API_KEY` | Direct web and extraction |\n| X token reference | `X_BEARER_TOKEN` | Direct X recent search |\n| YouTube key reference | `YOUTUBE_API_KEY` | Direct YouTube search |\n| SerpApi key reference | `SERPAPI_API_KEY` | Direct Scholar search |\n| Request timeout | 30000 ms | Per-request cooperative timeout |\n| Response limit | 5 MiB | Maximum upstream response bytes |\n| Default results | 5 | Results retained per selected source |\n| Maximum results | 10 | User-selectable per-source ceiling |\n| Snippet limit | 1200 chars | Maximum normalized preview |\n| Extract limit | 100000 chars | Maximum retained content per page |\n\nThe AIsa base URL must be a credential-free HTTP(S) origin. Direct provider\norigins are fixed by their adapters and cannot be supplied through tool input.\n\n### Headless and managed deployments\n\nThe settings card is the normal path, not the only path. Automation can write\nthe same user layer to `$DSH_HOME/settings.yaml`:\n\n~~~yaml\neasy-search:\n  routingMode: hybrid\n~~~\n\nThe standard local credential provider reads `$DSH_HOME/.credentials.yaml`:\n\n~~~yaml\nAISA_API_KEY: your-one-key\nTAVILY_API_KEY: your-tavily-key\n~~~\n\nKeep only the references the deployment needs, preserve unrelated entries,\nand keep this file at mode `0600` inside an owner-only DSH home. Environment\nvariables with the same names are also supported and take precedence.\n\nOperators can establish a per-profile base in\n`$DSH_HOME/profiles/<profile>/cordis.patch.yml`:\n\n~~~yaml\n- id: easy-search\n  config:\n    routingMode: hybrid\n~~~\n\nDo not edit the plugin's installed `cordis.patch.yml`; package updates may\nreplace package-owned files. DSH watches valid user and profile changes live.\n\n## Provider contracts\n\n| Source | AIsa route | Direct route |\n| --- | --- | --- |\n| Web | Tavily-compatible AIsa API | Tavily Search |\n| X | AIsa X Advanced Search | X API v2 recent search |\n| YouTube | AIsa YouTube Search | YouTube Data API v3 |\n| Scholar | AIsa Scholar Search | SerpApi Google Scholar |\n| Extract | Tavily-compatible AIsa API | Tavily Extract |\n\nProvider payloads are normalized behind one stable domain model. Selected\nsearch sources run concurrently; one failed source becomes an error entry in\n`coverage` while successful siblings remain available to the model.\n\n`easy_extract` accepts only credential-free HTTP(S) URLs. Literal local,\nprivate, link-local, multicast, and IPv4-mapped private addresses are rejected\nbefore any provider request.\n\n## Native presentation\n\nThe canonical tool value remains structured JSON for validation and replay.\nThe model receives compact citeable text, while `presentationMeta` projects\nonly fields required by official DSH web cards. Raw provider payloads and\ncredentials do not enter presentation data.\n\n## Development\n\n~~~sh\npnpm install\npnpm --filter @aisa-plugins/easy-search typecheck\npnpm --filter @aisa-plugins/easy-search test\npnpm --filter @aisa-plugins/easy-search build\npnpm --filter @aisa-plugins/easy-search check\npnpm --dir plugins/easy-search pack --dry-run\n~~~\n\nThe tests lock down routing policy, official HTTP contracts, credential\nsnapshots, settings-card commits, response normalization, partial-source\nfailure, extraction URL boundaries, response limits, and native DSH\npresentation.\n\n## Repository layout\n\n~~~text\nplugins/easy-search/\n├── src/\n│   ├── providers/\n│   │   ├── aisa.ts\n│   │   ├── tavily.ts\n│   │   ├── x.ts\n│   │   ├── youtube.ts\n│   │   ├── serpapi.ts\n│   │   ├── router.ts\n│   │   ├── runtime.ts\n│   │   └── contracts.ts\n│   ├── client/\n│   │   ├── card.tsx\n│   │   ├── controller.ts\n│   │   ├── locales.ts\n│   │   ├── model.ts\n│   │   └── styles.ts\n│   ├── config.ts\n│   ├── index.ts\n│   ├── normalize.ts\n│   ├── search.ts\n│   ├── settings.ts\n│   ├── tools.ts\n│   └── types.ts\n├── tests/\n├── docs/architecture.md\n├── cordis.patch.yml\n└── package.json\n~~~\n\nSee [docs/architecture.md](docs/architecture.md) for dependency boundaries and\nextension rules.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}