geo-ai-search-optimization 2.8.1 → 2.8.2
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/README.md +4 -2
- package/action.yml +1 -1
- package/package.json +1 -1
- package/src/cli-shared.js +47 -0
- package/src/dashboard-html.js +1 -1
- package/src/fetch-utils.js +1 -1
- package/src/pdf-report.js +1 -1
package/README.md
CHANGED
|
@@ -192,7 +192,9 @@ publish-pack <input> --out-dir <dir> # Full deliverable package
|
|
|
192
192
|
api-server [--port 3456] [--host 127.0.0.1]
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
|
|
195
|
+
**CLI caching:** URL-based analysis results are cached for 5 minutes. Use `--no-cache` to bypass.
|
|
196
|
+
|
|
197
|
+
**API caching:** All API responses are cached for 10 minutes by default. Add `?no-cache=1` to bypass. Use `/api/cache-stats` and `POST /api/cache-clear` to manage.
|
|
196
198
|
|
|
197
199
|
Exposes all analysis functions as HTTP endpoints:
|
|
198
200
|
|
|
@@ -298,7 +300,7 @@ Full TypeScript declarations included (`index.d.ts`) — 300+ exports with IDE a
|
|
|
298
300
|
## GitHub Action
|
|
299
301
|
|
|
300
302
|
```yaml
|
|
301
|
-
- uses: redredchen01/geo-ai-search-optimization@v2.8.
|
|
303
|
+
- uses: redredchen01/geo-ai-search-optimization@v2.8.2
|
|
302
304
|
with:
|
|
303
305
|
project-path: ./your-project
|
|
304
306
|
min-score: 60
|
package/action.yml
CHANGED
package/package.json
CHANGED
package/src/cli-shared.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
import { createCache } from "./cache-layer.js";
|
|
2
|
+
|
|
3
|
+
let _cliCache = null;
|
|
4
|
+
|
|
5
|
+
export function getCliCache() {
|
|
6
|
+
if (!_cliCache) {
|
|
7
|
+
_cliCache = createCache({ cacheDir: ".geo-cache/cli", ttl: 300000 }); // 5 min TTL
|
|
8
|
+
}
|
|
9
|
+
return _cliCache;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function buildCacheKey(commandLabel, args) {
|
|
13
|
+
const input = args.find((v) => !v.startsWith("-"));
|
|
14
|
+
if (!input || !/^https?:\/\//i.test(input)) return null; // Only cache URL inputs
|
|
15
|
+
return `cli:${commandLabel}:${input}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
1
18
|
export function getFlagValue(args, flagName) {
|
|
2
19
|
const index = args.indexOf(flagName);
|
|
3
20
|
if (index === -1) {
|
|
@@ -188,7 +205,37 @@ export function createStructuredOutputCommandHandler({
|
|
|
188
205
|
getOutputJson
|
|
189
206
|
}) {
|
|
190
207
|
return async function structuredOutputCommandHandler(args) {
|
|
208
|
+
const noCache = hasFlag(args, "--no-cache");
|
|
209
|
+
const cacheKey = noCache ? null : buildCacheKey(commandLabel, args);
|
|
210
|
+
const cache = cacheKey ? getCliCache() : null;
|
|
211
|
+
|
|
212
|
+
// Check cache
|
|
213
|
+
if (cache && cacheKey) {
|
|
214
|
+
const cached = await cache.get(cacheKey);
|
|
215
|
+
if (cached.hit) {
|
|
216
|
+
const result = cached.data;
|
|
217
|
+
const outputJson = getOutputJson ? getOutputJson(args, result) : hasFlag(args, "--json");
|
|
218
|
+
const renderedOutput = outputJson ? `${JSON.stringify(result, null, 2)}\n` : renderMarkdown(result);
|
|
219
|
+
const outputPath = getFlagValue(args, "--out");
|
|
220
|
+
process.stderr.write(`(cached, age ${Math.round(cached.age / 1000)}s)\n`);
|
|
221
|
+
|
|
222
|
+
if (outputPath) {
|
|
223
|
+
const resolvedOutputPath = await writeOutput(outputPath, renderedOutput);
|
|
224
|
+
process.stdout.write(`已保存 ${commandLabel} 结果:${resolvedOutputPath}\n`);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
process.stdout.write(renderedOutput);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
191
232
|
const result = await execute(args);
|
|
233
|
+
|
|
234
|
+
// Store in cache
|
|
235
|
+
if (cache && cacheKey) {
|
|
236
|
+
await cache.set(cacheKey, result);
|
|
237
|
+
}
|
|
238
|
+
|
|
192
239
|
const outputJson = getOutputJson ? getOutputJson(args, result) : hasFlag(args, "--json");
|
|
193
240
|
const renderedOutput = outputJson ? `${JSON.stringify(result, null, 2)}\n` : renderMarkdown(result);
|
|
194
241
|
const outputPath = getFlagValue(args, "--out");
|
package/src/dashboard-html.js
CHANGED
|
@@ -232,7 +232,7 @@ function buildHtml(report, options = {}) {
|
|
|
232
232
|
: ""
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
<footer>Generated by geo-ai-search-optimization v2.8.
|
|
235
|
+
<footer>Generated by geo-ai-search-optimization v2.8.2 — ${escapeHtml(timestamp)}</footer>
|
|
236
236
|
</div>
|
|
237
237
|
</body>
|
|
238
238
|
</html>`;
|
package/src/fetch-utils.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
const DEFAULT_TIMEOUT = 10_000;
|
|
6
6
|
const DEFAULT_RETRIES = 2;
|
|
7
7
|
const DEFAULT_RETRY_DELAY = 1000;
|
|
8
|
-
const USER_AGENT = "geo-ai-search-optimization/2.8.
|
|
8
|
+
const USER_AGENT = "geo-ai-search-optimization/2.8.2";
|
|
9
9
|
|
|
10
10
|
export async function fetchWithRetry(url, options = {}) {
|
|
11
11
|
const timeout = options.timeout || DEFAULT_TIMEOUT;
|
package/src/pdf-report.js
CHANGED
|
@@ -184,7 +184,7 @@ export function generatePdfHtml(data, options = {}) {
|
|
|
184
184
|
${body}
|
|
185
185
|
|
|
186
186
|
<div class="footer">
|
|
187
|
-
Generated by geo-ai-search-optimization v2.8.
|
|
187
|
+
Generated by geo-ai-search-optimization v2.8.2 — Open-source GEO toolkit for AI search optimization.
|
|
188
188
|
<br>Print this page to PDF for a polished report.
|
|
189
189
|
</div>
|
|
190
190
|
</body>
|