@rulemetric/cli 0.1.1 → 0.2.0
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 +66 -0
- package/dist/base-command.d.ts.map +1 -1
- package/dist/base-command.js +15 -0
- package/dist/base-command.js.map +1 -1
- package/dist/commands/auth/login.d.ts.map +1 -1
- package/dist/commands/auth/login.js +7 -0
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/crons/list.d.ts +7 -0
- package/dist/commands/crons/list.d.ts.map +1 -0
- package/dist/commands/crons/list.js +24 -0
- package/dist/commands/crons/list.js.map +1 -0
- package/dist/commands/crons/run.d.ts +13 -0
- package/dist/commands/crons/run.d.ts.map +1 -0
- package/dist/commands/crons/run.js +48 -0
- package/dist/commands/crons/run.js.map +1 -0
- package/dist/commands/evals/listen.d.ts +28 -2
- package/dist/commands/evals/listen.d.ts.map +1 -1
- package/dist/commands/evals/listen.js +159 -25
- package/dist/commands/evals/listen.js.map +1 -1
- package/dist/commands/evals/listen.test.d.ts +2 -0
- package/dist/commands/evals/listen.test.d.ts.map +1 -0
- package/dist/commands/evals/listen.test.js +48 -0
- package/dist/commands/evals/listen.test.js.map +1 -0
- package/dist/commands/gateway/ensure.js +1 -1
- package/dist/commands/gateway/ensure.js.map +1 -1
- package/dist/commands/hooks/install.d.ts.map +1 -1
- package/dist/commands/hooks/install.js +40 -3
- package/dist/commands/hooks/install.js.map +1 -1
- package/dist/commands/hooks/run.js +1 -1
- package/dist/commands/hooks/run.js.map +1 -1
- package/dist/commands/hooks/uninstall.d.ts.map +1 -1
- package/dist/commands/hooks/uninstall.js +9 -1
- package/dist/commands/hooks/uninstall.js.map +1 -1
- package/dist/commands/org/current.d.ts +7 -0
- package/dist/commands/org/current.d.ts.map +1 -0
- package/dist/commands/org/current.js +70 -0
- package/dist/commands/org/current.js.map +1 -0
- package/dist/commands/org/list.d.ts +7 -0
- package/dist/commands/org/list.d.ts.map +1 -0
- package/dist/commands/org/list.js +37 -0
- package/dist/commands/org/list.js.map +1 -0
- package/dist/commands/org/switch.d.ts +13 -0
- package/dist/commands/org/switch.d.ts.map +1 -0
- package/dist/commands/org/switch.js +52 -0
- package/dist/commands/org/switch.js.map +1 -0
- package/dist/commands/proxy/restart.d.ts +11 -0
- package/dist/commands/proxy/restart.d.ts.map +1 -0
- package/dist/commands/proxy/restart.js +36 -0
- package/dist/commands/proxy/restart.js.map +1 -0
- package/dist/commands/proxy/start.d.ts.map +1 -1
- package/dist/commands/proxy/start.js +4 -0
- package/dist/commands/proxy/start.js.map +1 -1
- package/dist/commands/service/install.d.ts +16 -0
- package/dist/commands/service/install.d.ts.map +1 -1
- package/dist/commands/service/install.js +145 -6
- package/dist/commands/service/install.js.map +1 -1
- package/dist/commands/service/uninstall.d.ts.map +1 -1
- package/dist/commands/service/uninstall.js +28 -0
- package/dist/commands/service/uninstall.js.map +1 -1
- package/dist/commands/sessions/start.d.ts.map +1 -1
- package/dist/commands/sessions/start.js +5 -0
- package/dist/commands/sessions/start.js.map +1 -1
- package/dist/commands/signals/report.d.ts +10 -0
- package/dist/commands/signals/report.d.ts.map +1 -0
- package/dist/commands/signals/report.js +35 -0
- package/dist/commands/signals/report.js.map +1 -0
- package/dist/commands/signals/report.test.d.ts +2 -0
- package/dist/commands/signals/report.test.d.ts.map +1 -0
- package/dist/commands/signals/report.test.js +65 -0
- package/dist/commands/signals/report.test.js.map +1 -0
- package/dist/commands/skills/export-approved.d.ts +10 -0
- package/dist/commands/skills/export-approved.d.ts.map +1 -0
- package/dist/commands/skills/export-approved.js +31 -0
- package/dist/commands/skills/export-approved.js.map +1 -0
- package/dist/commands/skills/publish.d.ts +17 -0
- package/dist/commands/skills/publish.d.ts.map +1 -0
- package/dist/commands/skills/publish.js +80 -0
- package/dist/commands/skills/publish.js.map +1 -0
- package/dist/commands/skills/update.d.ts +3 -0
- package/dist/commands/skills/update.d.ts.map +1 -1
- package/dist/commands/skills/update.js +17 -6
- package/dist/commands/skills/update.js.map +1 -1
- package/dist/commands/suggestions/accept.d.ts +16 -0
- package/dist/commands/suggestions/accept.d.ts.map +1 -0
- package/dist/commands/suggestions/accept.js +61 -0
- package/dist/commands/suggestions/accept.js.map +1 -0
- package/dist/commands/suggestions/accept.test.d.ts +2 -0
- package/dist/commands/suggestions/accept.test.d.ts.map +1 -0
- package/dist/commands/suggestions/accept.test.js +52 -0
- package/dist/commands/suggestions/accept.test.js.map +1 -0
- package/dist/commands/suggestions/dismiss.d.ts +10 -0
- package/dist/commands/suggestions/dismiss.d.ts.map +1 -0
- package/dist/commands/suggestions/dismiss.js +26 -0
- package/dist/commands/suggestions/dismiss.js.map +1 -0
- package/dist/commands/suggestions/list.d.ts +10 -0
- package/dist/commands/suggestions/list.d.ts.map +1 -0
- package/dist/commands/suggestions/list.js +40 -0
- package/dist/commands/suggestions/list.js.map +1 -0
- package/dist/commands/suggestions/refresh.d.ts +7 -0
- package/dist/commands/suggestions/refresh.d.ts.map +1 -0
- package/dist/commands/suggestions/refresh.js +11 -0
- package/dist/commands/suggestions/refresh.js.map +1 -0
- package/dist/dashboard/Dashboard.d.ts.map +1 -1
- package/dist/dashboard/Dashboard.js +7 -1
- package/dist/dashboard/Dashboard.js.map +1 -1
- package/dist/lib/active-org-refresh.d.ts +22 -0
- package/dist/lib/active-org-refresh.d.ts.map +1 -0
- package/dist/lib/active-org-refresh.js +108 -0
- package/dist/lib/active-org-refresh.js.map +1 -0
- package/dist/lib/active-org-refresh.test.d.ts +2 -0
- package/dist/lib/active-org-refresh.test.d.ts.map +1 -0
- package/dist/lib/active-org-refresh.test.js +190 -0
- package/dist/lib/active-org-refresh.test.js.map +1 -0
- package/dist/lib/active-org.d.ts +43 -0
- package/dist/lib/active-org.d.ts.map +1 -0
- package/dist/lib/active-org.js +96 -0
- package/dist/lib/active-org.js.map +1 -0
- package/dist/lib/active-org.test.d.ts +2 -0
- package/dist/lib/active-org.test.d.ts.map +1 -0
- package/dist/lib/active-org.test.js +147 -0
- package/dist/lib/active-org.test.js.map +1 -0
- package/dist/lib/cron-registry.d.ts +47 -0
- package/dist/lib/cron-registry.d.ts.map +1 -0
- package/dist/lib/cron-registry.js +102 -0
- package/dist/lib/cron-registry.js.map +1 -0
- package/dist/lib/cron-registry.test.d.ts +2 -0
- package/dist/lib/cron-registry.test.d.ts.map +1 -0
- package/dist/lib/cron-registry.test.js +136 -0
- package/dist/lib/cron-registry.test.js.map +1 -0
- package/dist/lib/cron-runner.d.ts +16 -0
- package/dist/lib/cron-runner.d.ts.map +1 -0
- package/dist/lib/cron-runner.js +68 -0
- package/dist/lib/cron-runner.js.map +1 -0
- package/dist/lib/detect-languages.d.ts +7 -0
- package/dist/lib/detect-languages.d.ts.map +1 -0
- package/dist/lib/detect-languages.js +113 -0
- package/dist/lib/detect-languages.js.map +1 -0
- package/dist/lib/detect-languages.test.d.ts +2 -0
- package/dist/lib/detect-languages.test.d.ts.map +1 -0
- package/dist/lib/detect-languages.test.js +29 -0
- package/dist/lib/detect-languages.test.js.map +1 -0
- package/dist/lib/eval-executor.d.ts.map +1 -1
- package/dist/lib/eval-executor.js +5 -2
- package/dist/lib/eval-executor.js.map +1 -1
- package/dist/lib/gateway-entry.js +4 -1
- package/dist/lib/gateway-entry.js.map +1 -1
- package/dist/lib/gateway-lifecycle.d.ts +1 -1
- package/dist/lib/gateway-lifecycle.d.ts.map +1 -1
- package/dist/lib/gateway-lifecycle.js +13 -2
- package/dist/lib/gateway-lifecycle.js.map +1 -1
- package/dist/lib/gateway.d.ts +4 -5
- package/dist/lib/gateway.d.ts.map +1 -1
- package/dist/lib/gateway.js +68 -2
- package/dist/lib/gateway.js.map +1 -1
- package/dist/lib/graphile-worker-runner.d.ts +124 -0
- package/dist/lib/graphile-worker-runner.d.ts.map +1 -0
- package/dist/lib/graphile-worker-runner.js +526 -0
- package/dist/lib/graphile-worker-runner.js.map +1 -0
- package/dist/lib/graphile-worker-runner.test.d.ts +2 -0
- package/dist/lib/graphile-worker-runner.test.d.ts.map +1 -0
- package/dist/lib/graphile-worker-runner.test.js +153 -0
- package/dist/lib/graphile-worker-runner.test.js.map +1 -0
- package/dist/lib/handlers/cron-close-stale-sessions.d.ts +3 -0
- package/dist/lib/handlers/cron-close-stale-sessions.d.ts.map +1 -0
- package/dist/lib/handlers/cron-close-stale-sessions.js +8 -0
- package/dist/lib/handlers/cron-close-stale-sessions.js.map +1 -0
- package/dist/lib/handlers/cron-data-integrity-audit.d.ts +3 -0
- package/dist/lib/handlers/cron-data-integrity-audit.d.ts.map +1 -0
- package/dist/lib/handlers/cron-data-integrity-audit.js +16 -0
- package/dist/lib/handlers/cron-data-integrity-audit.js.map +1 -0
- package/dist/lib/handlers/cron-refresh-skills.d.ts +3 -0
- package/dist/lib/handlers/cron-refresh-skills.d.ts.map +1 -0
- package/dist/lib/handlers/cron-refresh-skills.js +91 -0
- package/dist/lib/handlers/cron-refresh-skills.js.map +1 -0
- package/dist/lib/handlers/cron-refresh-skills.test.d.ts +2 -0
- package/dist/lib/handlers/cron-refresh-skills.test.d.ts.map +1 -0
- package/dist/lib/handlers/cron-refresh-skills.test.js +114 -0
- package/dist/lib/handlers/cron-refresh-skills.test.js.map +1 -0
- package/dist/lib/handlers/cron-regenerate-insights.d.ts +3 -0
- package/dist/lib/handlers/cron-regenerate-insights.d.ts.map +1 -0
- package/dist/lib/handlers/cron-regenerate-insights.js +6 -0
- package/dist/lib/handlers/cron-regenerate-insights.js.map +1 -0
- package/dist/lib/handlers/cron-suggest-instructions.d.ts +3 -0
- package/dist/lib/handlers/cron-suggest-instructions.d.ts.map +1 -0
- package/dist/lib/handlers/cron-suggest-instructions.js +159 -0
- package/dist/lib/handlers/cron-suggest-instructions.js.map +1 -0
- package/dist/lib/handlers/cron-suggest-instructions.test.d.ts +2 -0
- package/dist/lib/handlers/cron-suggest-instructions.test.d.ts.map +1 -0
- package/dist/lib/handlers/cron-suggest-instructions.test.js +80 -0
- package/dist/lib/handlers/cron-suggest-instructions.test.js.map +1 -0
- package/dist/lib/handlers/process-conversation.d.ts +35 -0
- package/dist/lib/handlers/process-conversation.d.ts.map +1 -0
- package/dist/lib/handlers/process-conversation.js +35 -0
- package/dist/lib/handlers/process-conversation.js.map +1 -0
- package/dist/lib/handlers/process-eval.d.ts +32 -0
- package/dist/lib/handlers/process-eval.d.ts.map +1 -0
- package/dist/lib/handlers/process-eval.js +207 -0
- package/dist/lib/handlers/process-eval.js.map +1 -0
- package/dist/lib/handlers/process-insights.d.ts +39 -0
- package/dist/lib/handlers/process-insights.d.ts.map +1 -0
- package/dist/lib/handlers/process-insights.js +300 -0
- package/dist/lib/handlers/process-insights.js.map +1 -0
- package/dist/lib/handlers/process-launch.d.ts +29 -0
- package/dist/lib/handlers/process-launch.d.ts.map +1 -0
- package/dist/lib/handlers/process-launch.js +41 -0
- package/dist/lib/handlers/process-launch.js.map +1 -0
- package/dist/lib/hooks-config.d.ts +28 -4
- package/dist/lib/hooks-config.d.ts.map +1 -1
- package/dist/lib/hooks-config.js +138 -10
- package/dist/lib/hooks-config.js.map +1 -1
- package/dist/lib/llm-client.d.ts.map +1 -1
- package/dist/lib/llm-client.js +149 -16
- package/dist/lib/llm-client.js.map +1 -1
- package/dist/lib/mirror-writer-db.d.ts +12 -0
- package/dist/lib/mirror-writer-db.d.ts.map +1 -0
- package/dist/lib/mirror-writer-db.js +51 -0
- package/dist/lib/mirror-writer-db.js.map +1 -0
- package/dist/lib/mirror-writer.d.ts +35 -0
- package/dist/lib/mirror-writer.d.ts.map +1 -0
- package/dist/lib/mirror-writer.js +27 -0
- package/dist/lib/mirror-writer.js.map +1 -0
- package/dist/lib/mirror-writer.test.d.ts +2 -0
- package/dist/lib/mirror-writer.test.d.ts.map +1 -0
- package/dist/lib/mirror-writer.test.js +47 -0
- package/dist/lib/mirror-writer.test.js.map +1 -0
- package/dist/lib/permanent-job-error.d.ts +17 -0
- package/dist/lib/permanent-job-error.d.ts.map +1 -0
- package/dist/lib/permanent-job-error.js +23 -0
- package/dist/lib/permanent-job-error.js.map +1 -0
- package/dist/lib/permanent-job-error.test.d.ts +2 -0
- package/dist/lib/permanent-job-error.test.d.ts.map +1 -0
- package/dist/lib/permanent-job-error.test.js +29 -0
- package/dist/lib/permanent-job-error.test.js.map +1 -0
- package/dist/lib/version-check.d.ts +11 -0
- package/dist/lib/version-check.d.ts.map +1 -0
- package/dist/lib/version-check.js +106 -0
- package/dist/lib/version-check.js.map +1 -0
- package/oclif.manifest.json +611 -81
- package/package.json +19 -5
- package/dist/commands/insights/sync.d.ts +0 -17
- package/dist/commands/insights/sync.d.ts.map +0 -1
- package/dist/commands/insights/sync.js +0 -477
- package/dist/commands/insights/sync.js.map +0 -1
- package/dist/lib/eval-worker.d.ts +0 -12
- package/dist/lib/eval-worker.d.ts.map +0 -1
- package/dist/lib/eval-worker.js +0 -395
- package/dist/lib/eval-worker.js.map +0 -1
- package/dist/lib/insights-worker.d.ts +0 -10
- package/dist/lib/insights-worker.d.ts.map +0 -1
- package/dist/lib/insights-worker.js +0 -329
- package/dist/lib/insights-worker.js.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { JobHelpers } from 'graphile-worker';
|
|
2
|
+
interface InsightsPayload {
|
|
3
|
+
mirrorId: string;
|
|
4
|
+
projectPath: string | null;
|
|
5
|
+
config?: {
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Graphile-shaped handler for the `process_insights` task.
|
|
12
|
+
*
|
|
13
|
+
* Lifted from the legacy `insights-worker.ts:processInsightsJob` and
|
|
14
|
+
* `processSessionAnalysisJob`, with the queue plumbing stripped out:
|
|
15
|
+
* - no claim — Graphile already claimed the job before invoking us
|
|
16
|
+
* - no /complete POST — we return the result object (or throw)
|
|
17
|
+
* - no "could not claim" early-return branches
|
|
18
|
+
*
|
|
19
|
+
* Mid-job progress patches still hit the existing
|
|
20
|
+
* `PATCH /api/insights-jobs/:id/progress` endpoint, just keyed by the
|
|
21
|
+
* mirror row's id.
|
|
22
|
+
*
|
|
23
|
+
* The session-analysis branch (selected when `payload.config.sessionId`
|
|
24
|
+
* is set) lives inline below — it's a different code path but cheap to
|
|
25
|
+
* keep co-located.
|
|
26
|
+
*
|
|
27
|
+
* The `buildDataSummary*` helpers are duplicated here as private locals;
|
|
28
|
+
* Task 21 will hoist them into a shared `insights-data.ts` once
|
|
29
|
+
* `insights-worker.ts` is deleted.
|
|
30
|
+
*
|
|
31
|
+
* User-facing notifications go through the API's `notifyUser()` path
|
|
32
|
+
* (insert into `notifications` → Supabase Realtime → service-worker
|
|
33
|
+
* `showNotification` with a deep-link). The worker no longer fires native
|
|
34
|
+
* `osascript` banners — those duplicated the browser path, weren't
|
|
35
|
+
* clickable to a URL, and stacked one-per-project on macOS.
|
|
36
|
+
*/
|
|
37
|
+
export declare function processInsights(payload: InsightsPayload, helpers: JobHelpers): Promise<Record<string, unknown>>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=process-insights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-insights.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/process-insights.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMlD,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4LlC"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { apiGet, apiPost, apiPatch } from '../api-client.js';
|
|
2
|
+
import { RECOMMENDATION_PROMPTS, AT_A_GLANCE_PROMPT, FACET_GENERATION_PROMPT } from '../insights-prompts.js';
|
|
3
|
+
import { runLlmPrompt, detectLlmBackend, runToolPrompt } from '../llm-client.js';
|
|
4
|
+
import { PermanentJobError } from '../permanent-job-error.js';
|
|
5
|
+
/**
|
|
6
|
+
* Graphile-shaped handler for the `process_insights` task.
|
|
7
|
+
*
|
|
8
|
+
* Lifted from the legacy `insights-worker.ts:processInsightsJob` and
|
|
9
|
+
* `processSessionAnalysisJob`, with the queue plumbing stripped out:
|
|
10
|
+
* - no claim — Graphile already claimed the job before invoking us
|
|
11
|
+
* - no /complete POST — we return the result object (or throw)
|
|
12
|
+
* - no "could not claim" early-return branches
|
|
13
|
+
*
|
|
14
|
+
* Mid-job progress patches still hit the existing
|
|
15
|
+
* `PATCH /api/insights-jobs/:id/progress` endpoint, just keyed by the
|
|
16
|
+
* mirror row's id.
|
|
17
|
+
*
|
|
18
|
+
* The session-analysis branch (selected when `payload.config.sessionId`
|
|
19
|
+
* is set) lives inline below — it's a different code path but cheap to
|
|
20
|
+
* keep co-located.
|
|
21
|
+
*
|
|
22
|
+
* The `buildDataSummary*` helpers are duplicated here as private locals;
|
|
23
|
+
* Task 21 will hoist them into a shared `insights-data.ts` once
|
|
24
|
+
* `insights-worker.ts` is deleted.
|
|
25
|
+
*
|
|
26
|
+
* User-facing notifications go through the API's `notifyUser()` path
|
|
27
|
+
* (insert into `notifications` → Supabase Realtime → service-worker
|
|
28
|
+
* `showNotification` with a deep-link). The worker no longer fires native
|
|
29
|
+
* `osascript` banners — those duplicated the browser path, weren't
|
|
30
|
+
* clickable to a URL, and stacked one-per-project on macOS.
|
|
31
|
+
*/
|
|
32
|
+
export async function processInsights(payload, helpers) {
|
|
33
|
+
const { mirrorId, projectPath, config } = payload;
|
|
34
|
+
const log = (msg) => helpers.logger.info(msg);
|
|
35
|
+
// Session-analysis branch — single-session deep analysis through tool CLI
|
|
36
|
+
if (config?.sessionId) {
|
|
37
|
+
return processSessionAnalysisInline({ mirrorId, sessionId: config.sessionId }, log);
|
|
38
|
+
}
|
|
39
|
+
log(`Processing insights job ${mirrorId}...`);
|
|
40
|
+
// Update status to running
|
|
41
|
+
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
42
|
+
status: 'running',
|
|
43
|
+
progress: { step: 'reading_data' },
|
|
44
|
+
});
|
|
45
|
+
// Self-heal orphan analyses missing `analyzed_at`. Without this, the
|
|
46
|
+
// freshness banner on the dashboard nags forever — the worker's
|
|
47
|
+
// facet-drain query (`hasAnalysis=false`) skips already-analyzed rows,
|
|
48
|
+
// so pre-instrumentation orphans never get touched. Stamps a conservative
|
|
49
|
+
// lower bound (`analyzed_at = started_at`); idempotent on subsequent runs.
|
|
50
|
+
// Best-effort: a failure here must not block the recommendation pass.
|
|
51
|
+
try {
|
|
52
|
+
const { repaired } = await apiPost('/api/sessions/repair-analyzed-at', {});
|
|
53
|
+
if (repaired > 0) {
|
|
54
|
+
log(` Repaired analyzed_at on ${repaired} orphan session(s).`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (repairErr) {
|
|
58
|
+
log(` Warning: analyzed_at repair failed: ${repairErr instanceof Error ? repairErr.message : String(repairErr)}`);
|
|
59
|
+
}
|
|
60
|
+
// API-based summary is the only source. The previous file-based fallback
|
|
61
|
+
// (`buildDataSummary` reading ~/.claude/usage-data/) was deleted on
|
|
62
|
+
// 2026-05-05 — it required `rulemetric insights sync` to populate JSON
|
|
63
|
+
// files locally, which nobody ever ran. The DB-derived summary is
|
|
64
|
+
// tool-agnostic and authoritative.
|
|
65
|
+
const data = await buildDataSummaryFromApi(projectPath);
|
|
66
|
+
if (!data) {
|
|
67
|
+
throw new PermanentJobError('No session data found — ensure sessions are captured and enriched.');
|
|
68
|
+
}
|
|
69
|
+
log(` Found ${data.stats.sessions} sessions, generating recommendations...`);
|
|
70
|
+
// Drain un-analyzed sessions in batches until empty (or until we hit the
|
|
71
|
+
// hard cap, to keep the per-job runtime bounded). Previously this took at
|
|
72
|
+
// most 20 sessions per run, which meant catch-up after a backlog could
|
|
73
|
+
// span days. Batching keeps memory bounded while letting one job clear
|
|
74
|
+
// the entire queue when needed.
|
|
75
|
+
const FACET_BATCH_SIZE = 20;
|
|
76
|
+
const FACET_HARD_CAP = 200; // protect against runaway runtime
|
|
77
|
+
if (detectLlmBackend() !== 'none') {
|
|
78
|
+
let totalFaceted = 0;
|
|
79
|
+
try {
|
|
80
|
+
while (totalFaceted < FACET_HARD_CAP) {
|
|
81
|
+
const unfaceted = await apiGet(`/api/sessions?hasAnalysis=false&limit=${FACET_BATCH_SIZE}`);
|
|
82
|
+
if (unfaceted.length === 0)
|
|
83
|
+
break;
|
|
84
|
+
log(` Generating facets for ${unfaceted.length} un-analyzed sessions (drained ${totalFaceted} so far)...`);
|
|
85
|
+
for (const session of unfaceted) {
|
|
86
|
+
if (totalFaceted >= FACET_HARD_CAP)
|
|
87
|
+
break;
|
|
88
|
+
try {
|
|
89
|
+
const events = await apiGet(`/api/sessions/${session.id}/events?limit=100`);
|
|
90
|
+
if (events.length < 2) {
|
|
91
|
+
totalFaceted++;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const eventSummary = events
|
|
95
|
+
.filter(e => e.eventType === 'user_message' || e.eventType === 'human')
|
|
96
|
+
.map(e => e.content?.slice(0, 200) ?? '')
|
|
97
|
+
.filter(Boolean)
|
|
98
|
+
.join('\n---\n');
|
|
99
|
+
if (!eventSummary) {
|
|
100
|
+
totalFaceted++;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const facets = await runLlmPrompt(FACET_GENERATION_PROMPT, eventSummary, 4096);
|
|
104
|
+
if (facets) {
|
|
105
|
+
const userMessageCount = events.filter(e => e.eventType === 'user_message' || e.eventType === 'human').length;
|
|
106
|
+
await apiPatch(`/api/sessions/${session.id}/enrich`, {
|
|
107
|
+
analysis: { source: 'generated_facets', ...facets },
|
|
108
|
+
analyzedEventCount: events.length,
|
|
109
|
+
analyzedTurnCount: userMessageCount,
|
|
110
|
+
});
|
|
111
|
+
log(` Generated facets for session ${session.id} (${session.tool})`);
|
|
112
|
+
}
|
|
113
|
+
totalFaceted++;
|
|
114
|
+
}
|
|
115
|
+
catch (sessionErr) {
|
|
116
|
+
log(` Failed to generate facets for session ${session.id}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`);
|
|
117
|
+
totalFaceted++; // count it so we don't infinite-loop on a poison row
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// If the batch returned fewer than the requested size, the queue is
|
|
121
|
+
// empty — break before another fetch.
|
|
122
|
+
if (unfaceted.length < FACET_BATCH_SIZE)
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (facetErr) {
|
|
127
|
+
log(` Warning: facet generation failed after ${totalFaceted} sessions: ${facetErr instanceof Error ? facetErr.message : String(facetErr)}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Run recommendation prompts sequentially
|
|
131
|
+
const recommendations = {};
|
|
132
|
+
const totalPrompts = RECOMMENDATION_PROMPTS.length + 1; // +1 for at_a_glance
|
|
133
|
+
// Persist sections-so-far on every progress PATCH so the web UI can render
|
|
134
|
+
// them incrementally — each prompt takes 30-60s and shipping a label-only
|
|
135
|
+
// progress update for that whole window leaves the page looking dead. The
|
|
136
|
+
// detail page reads `progress.partial` and renders each section card as it
|
|
137
|
+
// arrives.
|
|
138
|
+
for (let i = 0; i < RECOMMENDATION_PROMPTS.length; i++) {
|
|
139
|
+
const spec = RECOMMENDATION_PROMPTS[i];
|
|
140
|
+
log(` [${i + 1}/${totalPrompts}] Generating ${spec.name}...`);
|
|
141
|
+
try {
|
|
142
|
+
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
143
|
+
status: 'running',
|
|
144
|
+
progress: {
|
|
145
|
+
step: spec.name,
|
|
146
|
+
current: i + 1,
|
|
147
|
+
total: totalPrompts,
|
|
148
|
+
partial: { ...recommendations },
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (patchErr) {
|
|
153
|
+
log(` Warning: progress update failed for ${spec.name}: ${patchErr instanceof Error ? patchErr.message : String(patchErr)}`);
|
|
154
|
+
}
|
|
155
|
+
log(` Running LLM prompt for ${spec.name}...`);
|
|
156
|
+
const result = await runLlmPrompt(spec.prompt, data.summary, spec.maxTokens);
|
|
157
|
+
if (result) {
|
|
158
|
+
recommendations[spec.name] = result;
|
|
159
|
+
log(` Got result for ${spec.name}`);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
log(` No result for ${spec.name} (LLM returned null)`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// At a glance (uses outputs from previous prompts)
|
|
166
|
+
log(` [${totalPrompts}/${totalPrompts}] Generating at_a_glance...`);
|
|
167
|
+
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
168
|
+
status: 'running',
|
|
169
|
+
progress: {
|
|
170
|
+
step: 'at_a_glance',
|
|
171
|
+
current: totalPrompts,
|
|
172
|
+
total: totalPrompts,
|
|
173
|
+
partial: { ...recommendations },
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
const glanceData = [
|
|
177
|
+
data.summary,
|
|
178
|
+
recommendations.what_works ? `\n## What Works\n${JSON.stringify(recommendations.what_works)}` : '',
|
|
179
|
+
recommendations.friction_analysis ? `\n## Friction\n${JSON.stringify(recommendations.friction_analysis)}` : '',
|
|
180
|
+
recommendations.suggestions ? `\n## Suggestions\n${JSON.stringify(recommendations.suggestions)}` : '',
|
|
181
|
+
recommendations.on_the_horizon ? `\n## On the Horizon\n${JSON.stringify(recommendations.on_the_horizon)}` : '',
|
|
182
|
+
].join('\n');
|
|
183
|
+
const glance = await runLlmPrompt(AT_A_GLANCE_PROMPT, glanceData, 8192);
|
|
184
|
+
if (glance) {
|
|
185
|
+
recommendations.at_a_glance = glance;
|
|
186
|
+
}
|
|
187
|
+
log(' Uploading results...');
|
|
188
|
+
log(` Done! Recommendations generated for job ${mirrorId}`);
|
|
189
|
+
const result = { recommendations };
|
|
190
|
+
// Graphile discards task return values, so persist `{ recommendations }`
|
|
191
|
+
// onto the mirror row here so the dashboard can read it. Best-effort.
|
|
192
|
+
await apiPatch(`/api/insights-jobs/${mirrorId}/state`, { result }).catch((err) => {
|
|
193
|
+
log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
194
|
+
});
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Single-session deep analysis branch. Runs the session's own tool CLI
|
|
199
|
+
* against the captured event stream to produce facets, then enriches the
|
|
200
|
+
* session row.
|
|
201
|
+
*
|
|
202
|
+
* Idempotency guard: if the session already has analysis from a prior
|
|
203
|
+
* `session_analysis` run, we short-circuit. This is independent of the
|
|
204
|
+
* Graphile-side `job_key` dedup added in Task 9 — that prevents duplicate
|
|
205
|
+
* enqueues; this prevents redoing work even if a different mirrorId
|
|
206
|
+
* targets the same session.
|
|
207
|
+
*/
|
|
208
|
+
async function processSessionAnalysisInline(args, log) {
|
|
209
|
+
const { mirrorId, sessionId } = args;
|
|
210
|
+
log(`Analyzing session ${sessionId} via tool CLI...`);
|
|
211
|
+
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
212
|
+
status: 'running',
|
|
213
|
+
progress: { step: 'fetching_session' },
|
|
214
|
+
});
|
|
215
|
+
const session = await apiGet(`/api/sessions/${sessionId}`);
|
|
216
|
+
// Idempotency: skip if session already has analysis from a prior run
|
|
217
|
+
if (session.analysis && session.analysis.source === 'session_analysis') {
|
|
218
|
+
log(` Session ${sessionId} already analyzed — skipping (idempotency guard)`);
|
|
219
|
+
return { sessionId, skipped: true, reason: 'already_analyzed' };
|
|
220
|
+
}
|
|
221
|
+
const events = await apiGet(`/api/sessions/${sessionId}/events?limit=100`);
|
|
222
|
+
if (events.length < 2) {
|
|
223
|
+
throw new PermanentJobError('Session has too few events to analyze');
|
|
224
|
+
}
|
|
225
|
+
const eventSummary = events
|
|
226
|
+
.filter(e => e.eventType === 'user_message' || e.eventType === 'human')
|
|
227
|
+
.map(e => e.content?.slice(0, 200) ?? '')
|
|
228
|
+
.filter(Boolean)
|
|
229
|
+
.join('\n---\n');
|
|
230
|
+
if (!eventSummary) {
|
|
231
|
+
throw new PermanentJobError('No user messages found in session');
|
|
232
|
+
}
|
|
233
|
+
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
234
|
+
status: 'running',
|
|
235
|
+
progress: { step: 'running_analysis', tool: session.tool },
|
|
236
|
+
});
|
|
237
|
+
// Run through the session's tool CLI
|
|
238
|
+
const facets = runToolPrompt(session.tool, FACET_GENERATION_PROMPT, eventSummary);
|
|
239
|
+
if (!facets) {
|
|
240
|
+
throw new Error(`Analysis failed — ${session.tool} CLI returned no result`);
|
|
241
|
+
}
|
|
242
|
+
const userMessageCount = events.filter(e => e.eventType === 'user_message' || e.eventType === 'human').length;
|
|
243
|
+
await apiPatch(`/api/sessions/${sessionId}/enrich`, {
|
|
244
|
+
analysis: { source: 'session_analysis', tool: session.tool, ...facets },
|
|
245
|
+
analyzedEventCount: events.length,
|
|
246
|
+
analyzedTurnCount: userMessageCount,
|
|
247
|
+
});
|
|
248
|
+
log(` Session ${sessionId} analyzed via ${session.tool}`);
|
|
249
|
+
return { sessionId, tool: session.tool, facets };
|
|
250
|
+
}
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Local helpers (copied from `insights-worker.ts`; Task 21 hoists to shared)
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
async function buildDataSummaryFromApi(projectPath) {
|
|
255
|
+
try {
|
|
256
|
+
const params = new URLSearchParams();
|
|
257
|
+
if (projectPath)
|
|
258
|
+
params.set('projectPath', projectPath);
|
|
259
|
+
const computed = await apiGet(`/api/insights/compute?${params}`);
|
|
260
|
+
if (!computed || computed.total_sessions === 0)
|
|
261
|
+
return null;
|
|
262
|
+
// Build the same text summary format the prompts expect
|
|
263
|
+
const topTools = Object.entries(computed.tool_counts ?? {})
|
|
264
|
+
.sort((a, b) => b[1] - a[1])
|
|
265
|
+
.slice(0, 10)
|
|
266
|
+
.map(([t, c]) => `${t}: ${c}`)
|
|
267
|
+
.join(', ');
|
|
268
|
+
const summary = [
|
|
269
|
+
`Sessions: ${computed.total_sessions}, Messages: ${computed.total_messages}, Hours: ${Math.round(computed.total_duration_hours)}`,
|
|
270
|
+
`Top tools: ${topTools}`,
|
|
271
|
+
computed.goal_categories && Object.keys(computed.goal_categories).length > 0
|
|
272
|
+
? `Goals: ${JSON.stringify(computed.goal_categories)}`
|
|
273
|
+
: '',
|
|
274
|
+
computed.friction && Object.keys(computed.friction).length > 0
|
|
275
|
+
? `Friction: ${JSON.stringify(computed.friction)}`
|
|
276
|
+
: '',
|
|
277
|
+
computed.outcomes && Object.keys(computed.outcomes).length > 0
|
|
278
|
+
? `Outcomes: ${JSON.stringify(computed.outcomes)}`
|
|
279
|
+
: '',
|
|
280
|
+
computed.projects && Object.keys(computed.projects).length > 0
|
|
281
|
+
? `Projects: ${JSON.stringify(computed.projects)}`
|
|
282
|
+
: '',
|
|
283
|
+
].filter(Boolean).join('\n');
|
|
284
|
+
return {
|
|
285
|
+
summary,
|
|
286
|
+
stats: {
|
|
287
|
+
sessions: computed.total_sessions,
|
|
288
|
+
totalMessages: computed.total_messages,
|
|
289
|
+
totalHours: computed.total_duration_hours,
|
|
290
|
+
toolCounts: computed.tool_counts,
|
|
291
|
+
goalCounts: computed.goal_categories,
|
|
292
|
+
frictionCounts: computed.friction,
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=process-insights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-insights.js","sourceRoot":"","sources":["../../../src/lib/handlers/process-insights.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { JobHelpers } from 'graphile-worker';
|
|
2
|
+
interface LaunchPayload {
|
|
3
|
+
mirrorId: string;
|
|
4
|
+
tool: string;
|
|
5
|
+
config: {
|
|
6
|
+
projectPath: string;
|
|
7
|
+
prompt?: string;
|
|
8
|
+
systemPrompt?: string;
|
|
9
|
+
model?: string;
|
|
10
|
+
mode: 'headless' | 'interactive';
|
|
11
|
+
timeout?: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Graphile-shaped handler for the `process_launch` task.
|
|
16
|
+
*
|
|
17
|
+
* Lifted from the legacy `eval-worker.ts:processLaunchJob`, with the queue
|
|
18
|
+
* plumbing stripped out:
|
|
19
|
+
* - no claim — Graphile already claimed the job before invoking us
|
|
20
|
+
* - no /complete POST — we return the launcher result (or throw)
|
|
21
|
+
* - no surrounding try/catch — errors propagate to Graphile's retry path
|
|
22
|
+
*
|
|
23
|
+
* The dynamic import of `@rulemetric/session` is intentional: it avoids
|
|
24
|
+
* loading the launcher (and its tool-specific subprocess wrappers) unless a
|
|
25
|
+
* launch job actually fires.
|
|
26
|
+
*/
|
|
27
|
+
export declare function processLaunch(payload: LaunchPayload, helpers: JobHelpers): Promise<Record<string, unknown>>;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=process-launch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-launch.d.ts","sourceRoot":"","sources":["../../../src/lib/handlers/process-launch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,UAAU,GAAG,aAAa,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+BlC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { apiPatch } from '../api-client.js';
|
|
2
|
+
import { PermanentJobError } from '../permanent-job-error.js';
|
|
3
|
+
/**
|
|
4
|
+
* Graphile-shaped handler for the `process_launch` task.
|
|
5
|
+
*
|
|
6
|
+
* Lifted from the legacy `eval-worker.ts:processLaunchJob`, with the queue
|
|
7
|
+
* plumbing stripped out:
|
|
8
|
+
* - no claim — Graphile already claimed the job before invoking us
|
|
9
|
+
* - no /complete POST — we return the launcher result (or throw)
|
|
10
|
+
* - no surrounding try/catch — errors propagate to Graphile's retry path
|
|
11
|
+
*
|
|
12
|
+
* The dynamic import of `@rulemetric/session` is intentional: it avoids
|
|
13
|
+
* loading the launcher (and its tool-specific subprocess wrappers) unless a
|
|
14
|
+
* launch job actually fires.
|
|
15
|
+
*/
|
|
16
|
+
export async function processLaunch(payload, helpers) {
|
|
17
|
+
const { mirrorId, tool, config } = payload;
|
|
18
|
+
const log = (msg) => helpers.logger.info(msg);
|
|
19
|
+
// Fail-fast on retry. The launcher spawns subprocesses and registers a
|
|
20
|
+
// session — re-running on Graphile retry would create a second session
|
|
21
|
+
// with no link back to the first. Until the launcher path is properly
|
|
22
|
+
// idempotent (resume from sessionId persisted to the mirror row),
|
|
23
|
+
// surface the failure to the user instead of silently double-launching.
|
|
24
|
+
// See docs/audits/2026-05-07-worker-audit.md "Handlers not idempotent".
|
|
25
|
+
if (helpers.job.attempts > 1) {
|
|
26
|
+
throw new PermanentJobError(`process_launch is not safe to retry (attempt ${helpers.job.attempts}). Re-launch manually.`);
|
|
27
|
+
}
|
|
28
|
+
log(`Launching ${tool}...`);
|
|
29
|
+
const { getLauncher } = await import('@rulemetric/session');
|
|
30
|
+
const launcher = getLauncher(tool);
|
|
31
|
+
const launcherResult = await launcher.launch(config);
|
|
32
|
+
log(`Launch completed: sessionId=${launcherResult.sessionId}`);
|
|
33
|
+
const result = { ...launcherResult };
|
|
34
|
+
// Graphile discards task return values, so persist the launcher result
|
|
35
|
+
// (sessionId, etc.) onto the mirror row. Best-effort.
|
|
36
|
+
await apiPatch(`/api/launch-jobs/${mirrorId}/state`, { result }).catch((err) => {
|
|
37
|
+
log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
38
|
+
});
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=process-launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-launch.js","sourceRoot":"","sources":["../../../src/lib/handlers/process-launch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAe9D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAsB,EACtB,OAAmB;IAEnB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3C,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEtD,uEAAuE;IACvE,uEAAuE;IACvE,sEAAsE;IACtE,kEAAkE;IAClE,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,iBAAiB,CACzB,gDAAgD,OAAO,CAAC,GAAG,CAAC,QAAQ,wBAAwB,CAC7F,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,aAAa,IAAI,KAAK,CAAC,CAAC;IAC5B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,GAAG,CAAC,+BAA+B,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC;IAE/D,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;IAErC,uEAAuE;IACvE,sDAAsD;IACtD,MAAM,QAAQ,CAAC,oBAAoB,QAAQ,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACtF,GAAG,CAAC,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -19,11 +19,19 @@ export declare function generateCursorHooksConfig(): object;
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function generateCopilotHooksConfig(): object;
|
|
21
21
|
/**
|
|
22
|
-
* Write Cursor hooks config to
|
|
22
|
+
* Write Cursor hooks config to `<projectPath>/.cursor/hooks.json`.
|
|
23
23
|
* Merges with existing config — appends rulemetric hooks without duplicating.
|
|
24
24
|
* Returns the config file path, or null if `.cursor/` doesn't exist.
|
|
25
25
|
*/
|
|
26
26
|
export declare function writeCursorHooks(projectPath: string): string | null;
|
|
27
|
+
/**
|
|
28
|
+
* Write Cursor hooks config to user-level `~/.cursor/hooks.json` so capture
|
|
29
|
+
* works for every Cursor conversation without per-project setup.
|
|
30
|
+
*
|
|
31
|
+
* Returns the config file path, or null if `~/.cursor/` doesn't exist
|
|
32
|
+
* (i.e., Cursor has never been launched on this machine).
|
|
33
|
+
*/
|
|
34
|
+
export declare function writeCursorUserHooks(): string | null;
|
|
27
35
|
/**
|
|
28
36
|
* Write Copilot Agent hooks config to `.github/hooks/rulemetric.json`.
|
|
29
37
|
* Creates the hooks directory if needed.
|
|
@@ -31,11 +39,13 @@ export declare function writeCursorHooks(projectPath: string): string | null;
|
|
|
31
39
|
*/
|
|
32
40
|
export declare function writeCopilotHooks(projectPath: string): string | null;
|
|
33
41
|
/**
|
|
34
|
-
* Remove rulemetric hooks from
|
|
35
|
-
* Preserves other hooks and removes empty event arrays.
|
|
36
|
-
* Returns true if changes were made.
|
|
42
|
+
* Remove rulemetric hooks from `<projectPath>/.cursor/hooks.json`.
|
|
37
43
|
*/
|
|
38
44
|
export declare function removeCursorHooks(projectPath: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Remove rulemetric hooks from user-level `~/.cursor/hooks.json`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function removeCursorUserHooks(): boolean;
|
|
39
49
|
/**
|
|
40
50
|
* Write Cursor proxy config to `.cursor/settings.json`.
|
|
41
51
|
* Sets `http.proxy` and `http.proxyStrictSSL` while preserving existing settings.
|
|
@@ -92,4 +102,18 @@ export declare function writeVSCodeUserProxyConfig(gatewayPort: number): boolean
|
|
|
92
102
|
* Remove RuleMetric proxy config from VS Code user settings.
|
|
93
103
|
*/
|
|
94
104
|
export declare function removeVSCodeUserProxyConfig(): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Set http.proxy in Cursor user settings (not workspace). Mirrors
|
|
107
|
+
* `writeVSCodeUserProxyConfig` — workspace-level http.proxy is silently
|
|
108
|
+
* ignored due to APPLICATION-scope restriction (Cursor inherits this from
|
|
109
|
+
* VS Code, see microsoft/vscode#236932).
|
|
110
|
+
*
|
|
111
|
+
* Returns true if config was written, false if Cursor isn't installed
|
|
112
|
+
* (User dir absent) or the user already has a non-localhost proxy set.
|
|
113
|
+
*/
|
|
114
|
+
export declare function writeCursorUserProxyConfig(gatewayPort: number): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Remove RuleMetric proxy config from Cursor user settings.
|
|
117
|
+
*/
|
|
118
|
+
export declare function removeCursorUserProxyConfig(): boolean;
|
|
95
119
|
//# sourceMappingURL=hooks-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-config.d.ts","sourceRoot":"","sources":["../../src/lib/hooks-config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,eAAe,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,EAAE,CAYxE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"hooks-config.d.ts","sourceRoot":"","sources":["../../src/lib/hooks-config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,eAAe,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,EAAE,CAYxE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAqDlD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAkBnD;AAsDD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcpE;AAiDD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAc1G;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoB1G;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA6BpE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ/D;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CA6CnF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAmBhD;AAgBD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAmBvE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAcrD;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAkBvE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAcrD"}
|