termsearch 0.3.8 → 0.3.10

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.
@@ -1148,20 +1148,25 @@ function addToBrowser() {
1148
1148
  // Show inline hint
1149
1149
  const existing = document.querySelector('.add-browser-hint');
1150
1150
  if (existing) { existing.remove(); return; }
1151
+ const searchUrl = `${location.origin}/#/?q=%s`;
1152
+ const urlBox = el('div', { className: 'add-browser-url' });
1153
+ const urlText = el('code', {}, searchUrl);
1154
+ const copyBtn = el('button', { className: 'add-browser-copy', type: 'button', onClick: () => {
1155
+ navigator.clipboard.writeText(searchUrl).then(() => { copyBtn.textContent = 'Copied!'; setTimeout(() => { copyBtn.textContent = 'Copy'; }, 2000); }).catch(() => {});
1156
+ } }, 'Copy');
1157
+ urlBox.append(urlText, copyBtn);
1151
1158
  const hint = el('div', { className: 'add-browser-hint' },
1152
- el('strong', {}, 'Add TermSearch to your browser:'),
1153
- el('div', { style: 'margin-top:6px' },
1154
- el('span', { style: 'color:var(--text2)' }, 'Firefox'), ' click the address bar, look for "Add TermSearch"',
1155
- ),
1156
- el('div', { style: 'margin-top:3px' },
1157
- el('span', { style: 'color:var(--text2)' }, 'Chrome'), ' — Settings → Search engine → Manage → Add',
1158
- ),
1159
- el('div', { style: 'margin-top:3px;font-family:var(--font-mono);font-size:10px;color:var(--text3);word-break:break-all' },
1160
- `URL: ${location.origin}/#/?q=%s`,
1159
+ el('div', { className: 'add-browser-title' }, 'Add TermSearch to your browser'),
1160
+ el('div', { className: 'add-browser-steps' },
1161
+ el('div', {}, el('span', { className: 'add-browser-badge' }, 'Firefox'), ' Address bar click TermSearch icon "Add"'),
1162
+ el('div', {}, el('span', { className: 'add-browser-badge' }, 'Chrome'), ' Settings → Search engine → Manage → Add'),
1163
+ el('div', {}, el('span', { className: 'add-browser-badge' }, 'Safari'), ' Not natively supported — use extension or bookmark'),
1161
1164
  ),
1165
+ el('div', { className: 'add-browser-label' }, 'Search URL (paste in browser settings):'),
1166
+ urlBox,
1162
1167
  );
1163
1168
  document.querySelector('.home-actions')?.after(hint);
1164
- setTimeout(() => hint.remove(), 12000);
1169
+ setTimeout(() => hint.remove(), 20000);
1165
1170
  }
1166
1171
 
1167
1172
  function renderHome(app) {
@@ -937,16 +937,81 @@ a:hover { color: var(--link-h); }
937
937
 
938
938
  /* ─── Add to browser hint ─────────────────────────────────────────────────── */
939
939
  .add-browser-hint {
940
- max-width: 380px;
941
- margin: 16px auto 0;
942
- padding: 12px 16px;
940
+ max-width: 420px;
941
+ margin: 20px auto 0;
942
+ padding: 16px 20px;
943
943
  border-radius: var(--radius);
944
- background: rgba(30,27,75,0.35);
945
- border: 1px solid rgba(109,40,217,0.25);
944
+ background: rgba(30,27,75,0.45);
945
+ border: 1px solid rgba(109,40,217,0.35);
946
+ color: var(--text2);
947
+ font-size: 12px;
948
+ line-height: 1.7;
949
+ animation: fadeIn 0.2s ease;
950
+ }
951
+ .add-browser-title {
952
+ font-size: 13px;
953
+ font-weight: 700;
954
+ color: var(--text);
955
+ margin-bottom: 10px;
956
+ }
957
+ .add-browser-steps {
958
+ display: flex;
959
+ flex-direction: column;
960
+ gap: 5px;
961
+ margin-bottom: 12px;
962
+ }
963
+ .add-browser-badge {
964
+ display: inline-block;
965
+ padding: 1px 7px;
966
+ border-radius: 99px;
967
+ font-size: 10px;
968
+ font-weight: 700;
969
+ background: rgba(167,139,250,0.18);
970
+ color: #a78bfa;
971
+ border: 1px solid rgba(167,139,250,0.3);
972
+ letter-spacing: 0.02em;
973
+ }
974
+ .add-browser-label {
975
+ font-size: 10px;
946
976
  color: var(--text3);
977
+ text-transform: uppercase;
978
+ letter-spacing: 0.04em;
979
+ margin-bottom: 6px;
980
+ }
981
+ .add-browser-url {
982
+ display: flex;
983
+ align-items: center;
984
+ gap: 8px;
985
+ padding: 8px 12px;
986
+ border-radius: var(--radius-sm);
987
+ background: rgba(0,0,0,0.4);
988
+ border: 1px solid rgba(167,139,250,0.25);
989
+ }
990
+ .add-browser-url code {
991
+ flex: 1;
992
+ min-width: 0;
993
+ font-family: var(--font-mono);
994
+ font-size: 12px;
995
+ font-weight: 600;
996
+ color: #c4b5fd;
997
+ word-break: break-all;
998
+ user-select: all;
999
+ }
1000
+ .add-browser-copy {
1001
+ flex-shrink: 0;
1002
+ padding: 4px 12px;
1003
+ border-radius: var(--radius-sm);
1004
+ border: 1px solid rgba(167,139,250,0.35);
1005
+ background: rgba(109,40,217,0.25);
1006
+ color: #e0d4fd;
947
1007
  font-size: 11px;
948
- line-height: 1.6;
949
- animation: fadeIn 0.2s ease;
1008
+ font-weight: 600;
1009
+ cursor: pointer;
1010
+ transition: background 0.15s, border-color 0.15s;
1011
+ }
1012
+ .add-browser-copy:hover {
1013
+ background: rgba(109,40,217,0.45);
1014
+ border-color: rgba(167,139,250,0.55);
950
1015
  }
951
1016
 
952
1017
  /* ─── Footer ──────────────────────────────────────────────────────────────── */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termsearch",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "Personal search engine for Termux/Linux/macOS — zero-config, privacy-first, AI-optional",
5
5
  "type": "module",
6
6
  "bin": {
package/src/api/routes.js CHANGED
@@ -231,6 +231,23 @@ export function createRouter(config, rateLimiters) {
231
231
  });
232
232
  });
233
233
 
234
+ // ─── OpenSearch (dynamic — adapts to host/port) ─────────────────────────
235
+ router.get('/opensearch.xml', (req, res) => {
236
+ const proto = req.protocol;
237
+ const host = req.get('host') || `${req.hostname}:${req.socket.localPort}`;
238
+ const origin = `${proto}://${host}`;
239
+ res.setHeader('Content-Type', 'application/opensearchdescription+xml; charset=utf-8');
240
+ res.setHeader('Cache-Control', 'public, max-age=3600');
241
+ res.send(`<?xml version="1.0" encoding="UTF-8"?>
242
+ <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
243
+ <ShortName>TermSearch</ShortName>
244
+ <Description>TermSearch — personal search engine</Description>
245
+ <InputEncoding>UTF-8</InputEncoding>
246
+ <Image height="64" width="64" type="image/svg+xml">${origin}/icon.svg</Image>
247
+ <Url type="text/html" method="get" template="${origin}/#/?q={searchTerms}"/>
248
+ </OpenSearchDescription>`);
249
+ });
250
+
234
251
  // ─── OpenAPI ─────────────────────────────────────────────────────────────
235
252
  router.get('/api/openapi.json', (_req, res) => {
236
253
  applySecurityHeaders(res);
@@ -50,7 +50,7 @@ function termuxStatus() {
50
50
  function termuxEnable() {
51
51
  fs.mkdirSync(TERMUX_BOOT_DIR, { recursive: true });
52
52
  const bin = findBin();
53
- const sh = `#!/data/data/com.termux/files/usr/bin/sh\n# TermSearch autostart\n${bin} &\n`;
53
+ const sh = `#!/data/data/com.termux/files/usr/bin/sh\n# TermSearch autostart\n${bin} start --fg &\n`;
54
54
  fs.writeFileSync(TERMUX_BOOT_FILE, sh, { mode: 0o755 });
55
55
  }
56
56
 
@@ -103,7 +103,7 @@ function linuxEnable() {
103
103
  '',
104
104
  '[Service]',
105
105
  'Type=simple',
106
- `ExecStart=${bin}`,
106
+ `ExecStart=${bin} start --fg`,
107
107
  'Restart=on-failure',
108
108
  'RestartSec=5',
109
109
  '',
@@ -156,6 +156,8 @@ function macosEnable() {
156
156
  <key>ProgramArguments</key>
157
157
  <array>
158
158
  <string>${bin}</string>
159
+ <string>start</string>
160
+ <string>--fg</string>
159
161
  </array>
160
162
  <key>RunAtLoad</key>
161
163
  <true/>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
3
- <ShortName>TermSearch</ShortName>
4
- <Description>TermSearch — personal search engine</Description>
5
- <InputEncoding>UTF-8</InputEncoding>
6
- <Image height="64" width="64" type="image/svg+xml">/icon.svg</Image>
7
- <Url type="text/html" method="get" template="http://localhost:3000/#/?q={searchTerms}"/>
8
- </OpenSearchDescription>