@clauderecallhq/cli 0.12.1 → 0.61.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/LICENSE +37 -17
- package/README.md +316 -106
- package/dist/cli.js +1641 -361
- package/dist/daemon/entrypoint.js +1872 -54
- package/dist/mcp-server.js +930 -0
- package/dist/share/fonts/Inter-Bold.woff +0 -0
- package/dist/share/fonts/Inter-Regular.woff +0 -0
- package/dist/share/fonts/JetBrainsMono-Regular.woff +0 -0
- package/dist/web/assets/_brand-Bw9uSB4O.js +1 -0
- package/dist/web/assets/captureNode-9CVj9vYC.js +2 -0
- package/dist/web/assets/card-a-minimal-ujNERzX7.js +1 -0
- package/dist/web/assets/card-b-terminal-DpJ_tVpg.js +1 -0
- package/dist/web/assets/card-c-gradient-CZXVGuNd.js +1 -0
- package/dist/web/assets/card-d-dashboard-CHKD-PnB.js +1 -0
- package/dist/web/assets/dist-CWaokT35.js +56 -0
- package/dist/web/assets/index-B-HrjaDy.css +1 -0
- package/dist/web/assets/index-BZYcD76T.js +633 -0
- package/dist/web/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff +0 -0
- package/dist/web/assets/patterns-BPeZb9N0.js +1 -0
- package/dist/web/assets/stats-BSwqSiFU.js +1 -0
- package/dist/web/assets/thread-D2AXyhOx.js +1 -0
- package/dist/web/index.html +8 -2
- package/package.json +57 -16
- package/scripts/postinstall.mjs +38 -0
- package/dist/cli.js.map +0 -1
- package/dist/commands/activate.js +0 -69
- package/dist/commands/activate.js.map +0 -1
- package/dist/commands/audit-secrets.js +0 -103
- package/dist/commands/audit-secrets.js.map +0 -1
- package/dist/commands/blame.js +0 -35
- package/dist/commands/blame.js.map +0 -1
- package/dist/commands/config-verification.js +0 -18
- package/dist/commands/config-verification.js.map +0 -1
- package/dist/commands/context.js +0 -144
- package/dist/commands/context.js.map +0 -1
- package/dist/commands/correlate.js +0 -70
- package/dist/commands/correlate.js.map +0 -1
- package/dist/commands/digest.js +0 -78
- package/dist/commands/digest.js.map +0 -1
- package/dist/commands/health.js +0 -62
- package/dist/commands/health.js.map +0 -1
- package/dist/commands/index.js +0 -247
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/install-extension.js +0 -138
- package/dist/commands/install-extension.js.map +0 -1
- package/dist/commands/installs.js +0 -128
- package/dist/commands/installs.js.map +0 -1
- package/dist/commands/license.js +0 -39
- package/dist/commands/license.js.map +0 -1
- package/dist/commands/list.js +0 -47
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/mcp.js +0 -29
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/open.js +0 -28
- package/dist/commands/open.js.map +0 -1
- package/dist/commands/paste.js +0 -154
- package/dist/commands/paste.js.map +0 -1
- package/dist/commands/projects.js +0 -36
- package/dist/commands/projects.js.map +0 -1
- package/dist/commands/search.js +0 -67
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/semantic.js +0 -173
- package/dist/commands/semantic.js.map +0 -1
- package/dist/commands/show.js +0 -121
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/start.js +0 -47
- package/dist/commands/start.js.map +0 -1
- package/dist/commands/stats.js +0 -133
- package/dist/commands/stats.js.map +0 -1
- package/dist/commands/status.js +0 -45
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/stop.js +0 -29
- package/dist/commands/stop.js.map +0 -1
- package/dist/commands/thread.js +0 -396
- package/dist/commands/thread.js.map +0 -1
- package/dist/context/formatter.js +0 -103
- package/dist/context/formatter.js.map +0 -1
- package/dist/daemon/auto-tag-config.js +0 -103
- package/dist/daemon/auto-tag-config.js.map +0 -1
- package/dist/daemon/auto-tag-config.test.js +0 -72
- package/dist/daemon/auto-tag-config.test.js.map +0 -1
- package/dist/daemon/auto-title-config.js +0 -70
- package/dist/daemon/auto-title-config.js.map +0 -1
- package/dist/daemon/bulk-title-jobs.js +0 -170
- package/dist/daemon/bulk-title-jobs.js.map +0 -1
- package/dist/daemon/correlator.js +0 -320
- package/dist/daemon/correlator.js.map +0 -1
- package/dist/daemon/discover.js +0 -316
- package/dist/daemon/discover.js.map +0 -1
- package/dist/daemon/editor-detection.js +0 -186
- package/dist/daemon/editor-detection.js.map +0 -1
- package/dist/daemon/entrypoint.js.map +0 -1
- package/dist/daemon/git-correlator.js +0 -256
- package/dist/daemon/git-correlator.js.map +0 -1
- package/dist/daemon/mcp-installer.js +0 -108
- package/dist/daemon/mcp-installer.js.map +0 -1
- package/dist/daemon/onboarding-state.js +0 -140
- package/dist/daemon/onboarding-state.js.map +0 -1
- package/dist/daemon/pidfile.js +0 -57
- package/dist/daemon/pidfile.js.map +0 -1
- package/dist/daemon/ports.js +0 -48
- package/dist/daemon/ports.js.map +0 -1
- package/dist/daemon/scanProgressRegistry.js +0 -62
- package/dist/daemon/scanProgressRegistry.js.map +0 -1
- package/dist/daemon/server.js +0 -2010
- package/dist/daemon/server.js.map +0 -1
- package/dist/daemon/tag-scanner/anthropic-client.js +0 -40
- package/dist/daemon/tag-scanner/anthropic-client.js.map +0 -1
- package/dist/daemon/tag-scanner/autopilot.js +0 -131
- package/dist/daemon/tag-scanner/autopilot.js.map +0 -1
- package/dist/daemon/tag-scanner/claude-cli-driver.js +0 -250
- package/dist/daemon/tag-scanner/claude-cli-driver.js.map +0 -1
- package/dist/daemon/tag-scanner/orchestrator.js +0 -88
- package/dist/daemon/tag-scanner/orchestrator.js.map +0 -1
- package/dist/daemon/tag-scanner/prompt.js +0 -46
- package/dist/daemon/tag-scanner/prompt.js.map +0 -1
- package/dist/daemon/tag-scanner/prompt.test.js +0 -48
- package/dist/daemon/tag-scanner/prompt.test.js.map +0 -1
- package/dist/daemon/tag-scanner/scan-state.js +0 -49
- package/dist/daemon/tag-scanner/scan-state.js.map +0 -1
- package/dist/daemon/tag-scanner/session-fetcher.js +0 -82
- package/dist/daemon/tag-scanner/session-fetcher.js.map +0 -1
- package/dist/daemon/tag-scanner/session-fetcher.test.js +0 -34
- package/dist/daemon/tag-scanner/session-fetcher.test.js.map +0 -1
- package/dist/daemon/tag-scanner/validator.js +0 -50
- package/dist/daemon/tag-scanner/validator.js.map +0 -1
- package/dist/daemon/tag-scanner/validator.test.js +0 -41
- package/dist/daemon/tag-scanner/validator.test.js.map +0 -1
- package/dist/daemon/terminal-registry.js +0 -443
- package/dist/daemon/terminal-registry.js.map +0 -1
- package/dist/daemon/ui.js +0 -64
- package/dist/daemon/ui.js.map +0 -1
- package/dist/daemon/watcher.js +0 -256
- package/dist/daemon/watcher.js.map +0 -1
- package/dist/db/client.js +0 -22
- package/dist/db/client.js.map +0 -1
- package/dist/db/schema.js +0 -496
- package/dist/db/schema.js.map +0 -1
- package/dist/license/api-base.js +0 -13
- package/dist/license/api-base.js.map +0 -1
- package/dist/license/manager.js +0 -43
- package/dist/license/manager.js.map +0 -1
- package/dist/license/public-key.js +0 -19
- package/dist/license/public-key.js.map +0 -1
- package/dist/license/storage.js +0 -27
- package/dist/license/storage.js.map +0 -1
- package/dist/license/verify.js +0 -23
- package/dist/license/verify.js.map +0 -1
- package/dist/mcp/audit.js +0 -126
- package/dist/mcp/audit.js.map +0 -1
- package/dist/mcp/prompts.js +0 -180
- package/dist/mcp/prompts.js.map +0 -1
- package/dist/mcp/server.js +0 -502
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/thread-tools.js +0 -363
- package/dist/mcp/thread-tools.js.map +0 -1
- package/dist/mcp/write-tools.js +0 -239
- package/dist/mcp/write-tools.js.map +0 -1
- package/dist/parser/jsonl.js +0 -150
- package/dist/parser/jsonl.js.map +0 -1
- package/dist/semantic/chunker.js +0 -47
- package/dist/semantic/chunker.js.map +0 -1
- package/dist/semantic/config.js +0 -74
- package/dist/semantic/config.js.map +0 -1
- package/dist/semantic/embedder.js +0 -54
- package/dist/semantic/embedder.js.map +0 -1
- package/dist/semantic/fusion.js +0 -38
- package/dist/semantic/fusion.js.map +0 -1
- package/dist/semantic/model-download.js +0 -69
- package/dist/semantic/model-download.js.map +0 -1
- package/dist/semantic/pipeline.js +0 -375
- package/dist/semantic/pipeline.js.map +0 -1
- package/dist/semantic/query.js +0 -42
- package/dist/semantic/query.js.map +0 -1
- package/dist/semantic/worker.js +0 -78
- package/dist/semantic/worker.js.map +0 -1
- package/dist/stats/backfill.js +0 -151
- package/dist/stats/backfill.js.map +0 -1
- package/dist/stats/health.js +0 -102
- package/dist/stats/health.js.map +0 -1
- package/dist/stats/query.js +0 -385
- package/dist/stats/query.js.map +0 -1
- package/dist/utils/aliases.js +0 -107
- package/dist/utils/aliases.js.map +0 -1
- package/dist/utils/autoCollections.js +0 -635
- package/dist/utils/autoCollections.js.map +0 -1
- package/dist/utils/autoTitle.js +0 -348
- package/dist/utils/autoTitle.js.map +0 -1
- package/dist/utils/collections.js +0 -446
- package/dist/utils/collections.js.map +0 -1
- package/dist/utils/format.js +0 -46
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/notes.js +0 -270
- package/dist/utils/notes.js.map +0 -1
- package/dist/utils/paths.js +0 -50
- package/dist/utils/paths.js.map +0 -1
- package/dist/utils/pricing.js +0 -257
- package/dist/utils/pricing.js.map +0 -1
- package/dist/utils/secret-scanner.js +0 -166
- package/dist/utils/secret-scanner.js.map +0 -1
- package/dist/utils/sessionLabel.js +0 -64
- package/dist/utils/sessionLabel.js.map +0 -1
- package/dist/utils/tags.js +0 -97
- package/dist/utils/tags.js.map +0 -1
- package/dist/utils/thread-context.js +0 -129
- package/dist/utils/thread-context.js.map +0 -1
- package/dist/utils/threadFilter.js +0 -18
- package/dist/utils/threadFilter.js.map +0 -1
- package/dist/utils/threads-titler.js +0 -298
- package/dist/utils/threads-titler.js.map +0 -1
- package/dist/utils/threads.js +0 -383
- package/dist/utils/threads.js.map +0 -1
- package/dist/utils/usage.js +0 -76
- package/dist/utils/usage.js.map +0 -1
- package/dist/verification/compute.js +0 -88
- package/dist/verification/compute.js.map +0 -1
- package/dist/verification/config.js +0 -34
- package/dist/verification/config.js.map +0 -1
- package/dist/web/assets/index-CIr6J4Fw.js +0 -1201
- package/dist/web/assets/index-Ctc8g9Jw.css +0 -1
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
/**
|
|
6
|
-
* Auto-tag scanner config. Persisted as `{ autoTag: {...} }` inside
|
|
7
|
-
* `$RECALL_HOME/config.json` (default `~/.recall/config.json`).
|
|
8
|
-
*
|
|
9
|
-
* The file is written with mode 0600 because it may contain an Anthropic
|
|
10
|
-
* API key. Reads are tolerant: a missing or malformed file yields defaults
|
|
11
|
-
* rather than throwing — the daemon must start even if config is broken.
|
|
12
|
-
*
|
|
13
|
-
* Path resolution is lazy (re-reads `process.env.RECALL_HOME` on every call)
|
|
14
|
-
* so tests can redirect the data root per-test without a module-cache dance.
|
|
15
|
-
* `RECALL_HOME` in `src/utils/paths.ts` is captured at module-load and stays
|
|
16
|
-
* authoritative for every other consumer; this module intentionally uses its
|
|
17
|
-
* own lazy lookup so it stays independent and test-friendly.
|
|
18
|
-
*/
|
|
19
|
-
function recallHome() {
|
|
20
|
-
return process.env.RECALL_HOME ?? join(homedir(), '.recall');
|
|
21
|
-
}
|
|
22
|
-
function ensureHome() {
|
|
23
|
-
const home = recallHome();
|
|
24
|
-
if (!existsSync(home))
|
|
25
|
-
mkdirSync(home, { recursive: true });
|
|
26
|
-
}
|
|
27
|
-
function configFile() {
|
|
28
|
-
return join(recallHome(), 'config.json');
|
|
29
|
-
}
|
|
30
|
-
export const AutoTagConfigSchema = z.object({
|
|
31
|
-
enabled: z.boolean().default(false),
|
|
32
|
-
backend: z.enum(['api', 'mcp']).default('api'),
|
|
33
|
-
apiKey: z.string().optional(),
|
|
34
|
-
model: z.string().default('claude-opus-4-7'),
|
|
35
|
-
maxTagsPerSession: z.number().int().min(1).max(10).default(4),
|
|
36
|
-
minTagsPerSession: z.number().int().min(1).max(10).default(2),
|
|
37
|
-
/**
|
|
38
|
-
* When true, daemon background-scans untagged sessions (existing + new)
|
|
39
|
-
* and applies tags automatically — no modal, no review. Only takes effect
|
|
40
|
-
* when backend='api' and an apiKey is set; MCP mode can't be driven by
|
|
41
|
-
* the daemon because it needs the user's agent to make tool calls.
|
|
42
|
-
*/
|
|
43
|
-
autopilot: z.boolean().default(false),
|
|
44
|
-
});
|
|
45
|
-
const DEFAULTS = {
|
|
46
|
-
enabled: false,
|
|
47
|
-
backend: 'api',
|
|
48
|
-
model: 'claude-opus-4-7',
|
|
49
|
-
maxTagsPerSession: 4,
|
|
50
|
-
minTagsPerSession: 2,
|
|
51
|
-
autopilot: false,
|
|
52
|
-
};
|
|
53
|
-
function readFileShape() {
|
|
54
|
-
const path = configFile();
|
|
55
|
-
if (!existsSync(path))
|
|
56
|
-
return {};
|
|
57
|
-
try {
|
|
58
|
-
return JSON.parse(readFileSync(path, 'utf8'));
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
console.error('[auto-tag-config] failed to parse config.json, using defaults:', err);
|
|
62
|
-
return {};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
export function readAutoTagConfig() {
|
|
66
|
-
const raw = readFileShape().autoTag;
|
|
67
|
-
if (!raw)
|
|
68
|
-
return { ...DEFAULTS };
|
|
69
|
-
const parsed = AutoTagConfigSchema.safeParse({ ...DEFAULTS, ...raw });
|
|
70
|
-
return parsed.success ? parsed.data : { ...DEFAULTS };
|
|
71
|
-
}
|
|
72
|
-
export function writeAutoTagConfig(patch) {
|
|
73
|
-
ensureHome();
|
|
74
|
-
const existing = readFileShape();
|
|
75
|
-
const merged = AutoTagConfigSchema.parse({
|
|
76
|
-
...DEFAULTS,
|
|
77
|
-
...(existing.autoTag ?? {}),
|
|
78
|
-
...patch,
|
|
79
|
-
});
|
|
80
|
-
const next = { ...existing, autoTag: merged };
|
|
81
|
-
const path = configFile();
|
|
82
|
-
writeFileSync(path, JSON.stringify(next, null, 2));
|
|
83
|
-
try {
|
|
84
|
-
chmodSync(path, 0o600);
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
console.error('[auto-tag-config] chmod 0600 failed (continuing):', err);
|
|
88
|
-
}
|
|
89
|
-
return merged;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Shape for HTTP `GET /api/config/auto-tag`. Never exposes the raw apiKey over
|
|
93
|
-
* the wire; instead emits a marker and a `hasApiKey` boolean.
|
|
94
|
-
*/
|
|
95
|
-
export function redactForApi(cfg) {
|
|
96
|
-
const { apiKey, ...rest } = cfg;
|
|
97
|
-
return {
|
|
98
|
-
...rest,
|
|
99
|
-
apiKey: apiKey ? 'sk-ant-…' : null,
|
|
100
|
-
hasApiKey: Boolean(apiKey),
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
//# sourceMappingURL=auto-tag-config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-tag-config.js","sourceRoot":"","sources":["../../src/daemon/auto-tag-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import { mkdtempSync, rmSync, existsSync, statSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
describe('auto-tag-config', () => {
|
|
7
|
-
let tmpHome;
|
|
8
|
-
let prevHome;
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
tmpHome = mkdtempSync(join(tmpdir(), 'recall-cfg-'));
|
|
11
|
-
prevHome = process.env.RECALL_HOME;
|
|
12
|
-
process.env.RECALL_HOME = tmpHome;
|
|
13
|
-
});
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
if (prevHome)
|
|
16
|
-
process.env.RECALL_HOME = prevHome;
|
|
17
|
-
else
|
|
18
|
-
delete process.env.RECALL_HOME;
|
|
19
|
-
rmSync(tmpHome, { recursive: true, force: true });
|
|
20
|
-
});
|
|
21
|
-
it('returns defaults when config file does not exist', async () => {
|
|
22
|
-
const { readAutoTagConfig } = await import('./auto-tag-config.js');
|
|
23
|
-
const cfg = readAutoTagConfig();
|
|
24
|
-
assert.equal(cfg.enabled, false);
|
|
25
|
-
assert.equal(cfg.backend, 'api');
|
|
26
|
-
assert.equal(cfg.model, 'claude-opus-4-7');
|
|
27
|
-
});
|
|
28
|
-
it('round-trips writes', async () => {
|
|
29
|
-
const { readAutoTagConfig, writeAutoTagConfig } = await import('./auto-tag-config.js');
|
|
30
|
-
writeAutoTagConfig({
|
|
31
|
-
enabled: true,
|
|
32
|
-
backend: 'api',
|
|
33
|
-
apiKey: 'sk-ant-test',
|
|
34
|
-
model: 'claude-opus-4-7',
|
|
35
|
-
maxTagsPerSession: 4,
|
|
36
|
-
minTagsPerSession: 2,
|
|
37
|
-
});
|
|
38
|
-
const got = readAutoTagConfig();
|
|
39
|
-
assert.equal(got.enabled, true);
|
|
40
|
-
assert.equal(got.apiKey, 'sk-ant-test');
|
|
41
|
-
});
|
|
42
|
-
it('writes with 0600 file mode', async () => {
|
|
43
|
-
const { writeAutoTagConfig } = await import('./auto-tag-config.js');
|
|
44
|
-
writeAutoTagConfig({
|
|
45
|
-
enabled: true,
|
|
46
|
-
backend: 'api',
|
|
47
|
-
apiKey: 'secret',
|
|
48
|
-
model: 'claude-opus-4-7',
|
|
49
|
-
maxTagsPerSession: 4,
|
|
50
|
-
minTagsPerSession: 2,
|
|
51
|
-
});
|
|
52
|
-
const path = join(tmpHome, 'config.json');
|
|
53
|
-
assert.equal(existsSync(path), true);
|
|
54
|
-
const mode = statSync(path).mode & 0o777;
|
|
55
|
-
assert.equal(mode, 0o600);
|
|
56
|
-
});
|
|
57
|
-
it('redacts apiKey via redactForApi', async () => {
|
|
58
|
-
const { redactForApi } = await import('./auto-tag-config.js');
|
|
59
|
-
const redacted = redactForApi({
|
|
60
|
-
enabled: true,
|
|
61
|
-
backend: 'api',
|
|
62
|
-
apiKey: 'sk-ant-XXXXX',
|
|
63
|
-
model: 'claude-opus-4-7',
|
|
64
|
-
maxTagsPerSession: 4,
|
|
65
|
-
minTagsPerSession: 2,
|
|
66
|
-
autopilot: false,
|
|
67
|
-
});
|
|
68
|
-
assert.equal(redacted.apiKey, 'sk-ant-…');
|
|
69
|
-
assert.equal(redacted.hasApiKey, true);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
//# sourceMappingURL=auto-tag-config.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-tag-config.test.js","sourceRoot":"","sources":["../../src/daemon/auto-tag-config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,OAAe,CAAC;IACpB,IAAI,QAA4B,CAAC;IAEjC,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;QACrD,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC;;YAC5C,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACpC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACvF,kBAAkB,CAAC;YACjB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,aAAa;YACrB,KAAK,EAAE,iBAAiB;YACxB,iBAAiB,EAAE,CAAC;YACpB,iBAAiB,EAAE,CAAC;SACrB,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACpE,kBAAkB,CAAC;YACjB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,iBAAiB;YACxB,iBAAiB,EAAE,CAAC;YACpB,iBAAiB,EAAE,CAAC;SACrB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,YAAY,CAAC;YAC5B,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,cAAc;YACtB,KAAK,EAAE,iBAAiB;YACxB,iBAAiB,EAAE,CAAC;YACpB,iBAAiB,EAAE,CAAC;YACpB,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAE,QAAmC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
/**
|
|
6
|
-
* v0.14b (T5) — auto-title config, persisted as `{ autoTitle: {...} }` inside
|
|
7
|
-
* `$RECALL_HOME/config.json` alongside the existing `autoTag` block.
|
|
8
|
-
*
|
|
9
|
-
* Two booleans:
|
|
10
|
-
* - `heuristicEnabled` (default true) — indexer-time heuristic pass.
|
|
11
|
-
* - `agentEnabled` (default false) — `claude -p` summarisation path.
|
|
12
|
-
* OFF by default because it spawns a subprocess and uses the user's
|
|
13
|
-
* subscription. The UI's ✨ Generate title button flips this per-click
|
|
14
|
-
* after an explicit confirmation, identical to the auto-tag opt-in.
|
|
15
|
-
*
|
|
16
|
-
* Path resolution mirrors `auto-tag-config.ts`: lazy re-read of
|
|
17
|
-
* `process.env.RECALL_HOME` on every call so tests can redirect the data
|
|
18
|
-
* root per-test without a module-cache dance.
|
|
19
|
-
*/
|
|
20
|
-
function recallHome() {
|
|
21
|
-
return process.env.RECALL_HOME ?? join(homedir(), '.recall');
|
|
22
|
-
}
|
|
23
|
-
function ensureHome() {
|
|
24
|
-
const home = recallHome();
|
|
25
|
-
if (!existsSync(home))
|
|
26
|
-
mkdirSync(home, { recursive: true });
|
|
27
|
-
}
|
|
28
|
-
function configFile() {
|
|
29
|
-
return join(recallHome(), 'config.json');
|
|
30
|
-
}
|
|
31
|
-
export const AutoTitleConfigSchema = z.object({
|
|
32
|
-
heuristicEnabled: z.boolean().default(true),
|
|
33
|
-
agentEnabled: z.boolean().default(false),
|
|
34
|
-
});
|
|
35
|
-
const DEFAULTS = {
|
|
36
|
-
heuristicEnabled: true,
|
|
37
|
-
agentEnabled: false,
|
|
38
|
-
};
|
|
39
|
-
function readFileShape() {
|
|
40
|
-
const path = configFile();
|
|
41
|
-
if (!existsSync(path))
|
|
42
|
-
return {};
|
|
43
|
-
try {
|
|
44
|
-
return JSON.parse(readFileSync(path, 'utf8'));
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
console.error('[auto-title-config] failed to parse config.json, using defaults:', err);
|
|
48
|
-
return {};
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
export function readAutoTitleConfig() {
|
|
52
|
-
const raw = readFileShape().autoTitle;
|
|
53
|
-
if (!raw)
|
|
54
|
-
return { ...DEFAULTS };
|
|
55
|
-
const parsed = AutoTitleConfigSchema.safeParse({ ...DEFAULTS, ...raw });
|
|
56
|
-
return parsed.success ? parsed.data : { ...DEFAULTS };
|
|
57
|
-
}
|
|
58
|
-
export function writeAutoTitleConfig(patch) {
|
|
59
|
-
ensureHome();
|
|
60
|
-
const existing = readFileShape();
|
|
61
|
-
const merged = AutoTitleConfigSchema.parse({
|
|
62
|
-
...DEFAULTS,
|
|
63
|
-
...(existing.autoTitle ?? {}),
|
|
64
|
-
...patch,
|
|
65
|
-
});
|
|
66
|
-
const next = { ...existing, autoTitle: merged };
|
|
67
|
-
writeFileSync(configFile(), JSON.stringify(next, null, 2));
|
|
68
|
-
return merged;
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=auto-title-config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-title-config.js","sourceRoot":"","sources":["../../src/daemon/auto-title-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;GAcG;AAEH,SAAS,UAAU;IACjB,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3C,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACzC,CAAC,CAAC;AAIH,MAAM,QAAQ,GAAoB;IAChC,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,KAAK;CACpB,CAAC;AAOF,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAc,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,kEAAkE,EAAE,GAAG,CAAC,CAAC;QACvF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC,SAAS,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAA+B;IAClE,UAAU,EAAE,CAAC;IACb,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC;QACzC,GAAG,QAAQ;QACX,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;QAC7B,GAAG,KAAK;KACT,CAAC,CAAC;IACH,MAAM,IAAI,GAAc,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC3D,aAAa,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { generateThreadTitles, } from '../utils/threads-titler.js';
|
|
3
|
-
const REGISTRY = new Map();
|
|
4
|
-
const TTL_AFTER_DONE_MS = 5 * 60 * 1000;
|
|
5
|
-
function pushEvent(state, kind, data) {
|
|
6
|
-
const id = state.events.length + 1;
|
|
7
|
-
state.events.push({ id, kind, data });
|
|
8
|
-
for (const w of state.waiters)
|
|
9
|
-
w.resolve();
|
|
10
|
-
state.waiters.clear();
|
|
11
|
-
}
|
|
12
|
-
function scheduleCleanup(state) {
|
|
13
|
-
if (state.cleanupTimer)
|
|
14
|
-
clearTimeout(state.cleanupTimer);
|
|
15
|
-
state.cleanupTimer = setTimeout(() => {
|
|
16
|
-
REGISTRY.delete(state.jobId);
|
|
17
|
-
}, TTL_AFTER_DONE_MS);
|
|
18
|
-
}
|
|
19
|
-
function snapshot(state) {
|
|
20
|
-
let done = 0;
|
|
21
|
-
let skipped = 0;
|
|
22
|
-
let failed = 0;
|
|
23
|
-
for (const e of state.events) {
|
|
24
|
-
if (e.kind === 'progress')
|
|
25
|
-
done += 1;
|
|
26
|
-
if (e.kind === 'skipped')
|
|
27
|
-
skipped += 1;
|
|
28
|
-
if (e.kind === 'error')
|
|
29
|
-
failed += 1;
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
jobId: state.jobId,
|
|
33
|
-
threadId: state.threadId,
|
|
34
|
-
status: state.status,
|
|
35
|
-
startedAt: state.startedAt,
|
|
36
|
-
endedAt: state.endedAt,
|
|
37
|
-
total: state.total,
|
|
38
|
-
done,
|
|
39
|
-
skipped,
|
|
40
|
-
failed,
|
|
41
|
-
result: state.result,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Spawn a detached bulk-title walk. Returns the jobId immediately. The walk
|
|
46
|
-
* runs on the daemon's event loop and pushes progress events into the
|
|
47
|
-
* registry; SSE subscribers pull from there.
|
|
48
|
-
*/
|
|
49
|
-
export function startBulkTitleJob(input) {
|
|
50
|
-
const jobId = randomUUID();
|
|
51
|
-
const controller = new AbortController();
|
|
52
|
-
const state = {
|
|
53
|
-
jobId,
|
|
54
|
-
threadId: input.threadId,
|
|
55
|
-
status: 'running',
|
|
56
|
-
startedAt: new Date().toISOString(),
|
|
57
|
-
endedAt: null,
|
|
58
|
-
total: 0,
|
|
59
|
-
events: [],
|
|
60
|
-
waiters: new Set(),
|
|
61
|
-
controller,
|
|
62
|
-
result: null,
|
|
63
|
-
cleanupTimer: null,
|
|
64
|
-
};
|
|
65
|
-
REGISTRY.set(jobId, state);
|
|
66
|
-
// Detached: the walk runs to completion or until cancelled. Errors thrown
|
|
67
|
-
// by generateThreadTitles itself (thread not found, fatal db error) end up
|
|
68
|
-
// as a synthetic 'done' event with failed entries so subscribers always
|
|
69
|
-
// get a terminal event.
|
|
70
|
-
//
|
|
71
|
-
// The leading `await Promise.resolve()` yields once so the caller has time
|
|
72
|
-
// to bind the returned jobId before the walk starts. Without it, the spawn
|
|
73
|
-
// override could fire (and call cancelJob with a stale jobId) inside the
|
|
74
|
-
// same sync stack as `startBulkTitleJob(...)`, which is what the cancel
|
|
75
|
-
// test exercises.
|
|
76
|
-
void (async () => {
|
|
77
|
-
await Promise.resolve();
|
|
78
|
-
try {
|
|
79
|
-
const result = await generateThreadTitles(input.threadId, {
|
|
80
|
-
force: input.force ?? false,
|
|
81
|
-
signal: controller.signal,
|
|
82
|
-
model: input.model,
|
|
83
|
-
onProgress: (ev) => {
|
|
84
|
-
state.total = ev.total;
|
|
85
|
-
pushEvent(state, 'progress', ev);
|
|
86
|
-
},
|
|
87
|
-
onSkipped: (ev) => {
|
|
88
|
-
pushEvent(state, 'skipped', ev);
|
|
89
|
-
},
|
|
90
|
-
onFailed: (ev) => {
|
|
91
|
-
pushEvent(state, 'error', ev);
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
state.result = result;
|
|
95
|
-
state.status = controller.signal.aborted ? 'cancelled' : 'done';
|
|
96
|
-
state.endedAt = new Date().toISOString();
|
|
97
|
-
pushEvent(state, 'done', result);
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
const message = err instanceof Error ? err.message : String(err ?? 'unknown error');
|
|
101
|
-
state.result = {
|
|
102
|
-
generated: [],
|
|
103
|
-
skipped: [],
|
|
104
|
-
failed: [{ sessionId: input.threadId, error: message }],
|
|
105
|
-
};
|
|
106
|
-
state.status = 'failed';
|
|
107
|
-
state.endedAt = new Date().toISOString();
|
|
108
|
-
pushEvent(state, 'done', state.result);
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
scheduleCleanup(state);
|
|
112
|
-
}
|
|
113
|
-
})();
|
|
114
|
-
return jobId;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Async iterator over a job's events. Resumes from `afterId` if provided
|
|
118
|
-
* (use `Last-Event-ID` from the SSE protocol). Yields buffered events first,
|
|
119
|
-
* then awaits new ones until the job emits `done`. The consumer is expected
|
|
120
|
-
* to break on the `done` event; the iterator itself does not exit early so
|
|
121
|
-
* heartbeats can interleave.
|
|
122
|
-
*/
|
|
123
|
-
export async function* subscribeJob(jobId, afterId = 0) {
|
|
124
|
-
const state = REGISTRY.get(jobId);
|
|
125
|
-
if (!state)
|
|
126
|
-
return;
|
|
127
|
-
let cursor = afterId;
|
|
128
|
-
while (true) {
|
|
129
|
-
while (cursor < state.events.length) {
|
|
130
|
-
const ev = state.events[cursor];
|
|
131
|
-
cursor += 1;
|
|
132
|
-
yield ev;
|
|
133
|
-
if (ev.kind === 'done')
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
if (state.endedAt)
|
|
137
|
-
return;
|
|
138
|
-
await new Promise((resolve) => {
|
|
139
|
-
state.waiters.add({ resolve });
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
export function cancelJob(jobId) {
|
|
144
|
-
const state = REGISTRY.get(jobId);
|
|
145
|
-
if (!state)
|
|
146
|
-
return false;
|
|
147
|
-
if (state.status !== 'running')
|
|
148
|
-
return false;
|
|
149
|
-
state.controller.abort();
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
export function getJobSnapshot(jobId) {
|
|
153
|
-
const state = REGISTRY.get(jobId);
|
|
154
|
-
if (!state)
|
|
155
|
-
return null;
|
|
156
|
-
return snapshot(state);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Test-only helper: clear every job (useful between tests so registry
|
|
160
|
-
* residue from one test does not leak into the next). Not exported from a
|
|
161
|
-
* module index; tests reach in directly.
|
|
162
|
-
*/
|
|
163
|
-
export function __resetForTests() {
|
|
164
|
-
for (const state of REGISTRY.values()) {
|
|
165
|
-
if (state.cleanupTimer)
|
|
166
|
-
clearTimeout(state.cleanupTimer);
|
|
167
|
-
}
|
|
168
|
-
REGISTRY.clear();
|
|
169
|
-
}
|
|
170
|
-
//# sourceMappingURL=bulk-title-jobs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-title-jobs.js","sourceRoot":"","sources":["../../src/daemon/bulk-title-jobs.ts"],"names":[],"mappings":"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"}
|