byterover-cli 3.5.1 → 3.6.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/.env.production +4 -6
- package/dist/agent/core/interfaces/i-cipher-agent.d.ts +1 -0
- package/dist/agent/infra/agent/cipher-agent.d.ts +1 -0
- package/dist/agent/infra/agent/cipher-agent.js +1 -0
- package/dist/oclif/commands/curate/view.js +5 -25
- package/dist/oclif/commands/dream.d.ts +18 -0
- package/dist/oclif/commands/dream.js +230 -0
- package/dist/oclif/commands/query-log/summary.d.ts +18 -0
- package/dist/oclif/commands/query-log/summary.js +75 -0
- package/dist/oclif/commands/query-log/view.d.ts +23 -0
- package/dist/oclif/commands/query-log/view.js +95 -0
- package/dist/oclif/lib/time-filter.d.ts +10 -0
- package/dist/oclif/lib/time-filter.js +21 -0
- package/dist/server/config/environment.d.ts +10 -3
- package/dist/server/config/environment.js +34 -15
- package/dist/server/constants.d.ts +5 -0
- package/dist/server/constants.js +7 -0
- package/dist/server/core/domain/entities/query-log-entry.d.ts +61 -0
- package/dist/server/core/domain/entities/query-log-entry.js +40 -0
- package/dist/server/core/domain/transport/schemas.d.ts +108 -7
- package/dist/server/core/domain/transport/schemas.js +34 -2
- package/dist/server/core/interfaces/executor/i-query-executor.d.ts +23 -2
- package/dist/server/core/interfaces/i-terminal.d.ts +3 -0
- package/dist/server/core/interfaces/i-terminal.js +1 -0
- package/dist/server/core/interfaces/storage/i-query-log-store.d.ts +23 -0
- package/dist/server/core/interfaces/storage/i-query-log-store.js +2 -0
- package/dist/server/core/interfaces/usecase/i-query-log-summary-use-case.d.ts +44 -0
- package/dist/server/core/interfaces/usecase/i-query-log-summary-use-case.js +1 -0
- package/dist/server/core/interfaces/usecase/i-query-log-use-case.d.ts +13 -0
- package/dist/server/core/interfaces/usecase/i-query-log-use-case.js +3 -0
- package/dist/server/infra/daemon/agent-process.js +79 -9
- package/dist/server/infra/daemon/brv-server.js +74 -5
- package/dist/server/infra/dream/dream-lock-service.d.ts +37 -0
- package/dist/server/infra/dream/dream-lock-service.js +88 -0
- package/dist/server/infra/dream/dream-log-schema.d.ts +966 -0
- package/dist/server/infra/dream/dream-log-schema.js +57 -0
- package/dist/server/infra/dream/dream-log-store.d.ts +55 -0
- package/dist/server/infra/dream/dream-log-store.js +141 -0
- package/dist/server/infra/dream/dream-response-schemas.d.ts +219 -0
- package/dist/server/infra/dream/dream-response-schemas.js +38 -0
- package/dist/server/infra/dream/dream-state-schema.d.ts +67 -0
- package/dist/server/infra/dream/dream-state-schema.js +23 -0
- package/dist/server/infra/dream/dream-state-service.d.ts +38 -0
- package/dist/server/infra/dream/dream-state-service.js +91 -0
- package/dist/server/infra/dream/dream-trigger.d.ts +46 -0
- package/dist/server/infra/dream/dream-trigger.js +65 -0
- package/dist/server/infra/dream/dream-undo.d.ts +38 -0
- package/dist/server/infra/dream/dream-undo.js +293 -0
- package/dist/server/infra/dream/operations/consolidate.d.ts +52 -0
- package/dist/server/infra/dream/operations/consolidate.js +514 -0
- package/dist/server/infra/dream/operations/prune.d.ts +45 -0
- package/dist/server/infra/dream/operations/prune.js +362 -0
- package/dist/server/infra/dream/operations/synthesize.d.ts +37 -0
- package/dist/server/infra/dream/operations/synthesize.js +278 -0
- package/dist/server/infra/dream/parse-dream-response.d.ts +11 -0
- package/dist/server/infra/dream/parse-dream-response.js +35 -0
- package/dist/server/infra/executor/curate-executor.js +10 -0
- package/dist/server/infra/executor/dream-executor.d.ts +97 -0
- package/dist/server/infra/executor/dream-executor.js +431 -0
- package/dist/server/infra/executor/query-executor.d.ts +2 -2
- package/dist/server/infra/executor/query-executor.js +92 -22
- package/dist/server/infra/process/feature-handlers.js +10 -6
- package/dist/server/infra/process/query-log-handler.d.ts +42 -0
- package/dist/server/infra/process/query-log-handler.js +150 -0
- package/dist/server/infra/process/task-router.d.ts +40 -0
- package/dist/server/infra/process/task-router.js +67 -9
- package/dist/server/infra/process/transport-handlers.d.ts +4 -0
- package/dist/server/infra/process/transport-handlers.js +1 -0
- package/dist/server/infra/storage/file-curate-log-store.js +1 -1
- package/dist/server/infra/storage/file-query-log-store.d.ts +81 -0
- package/dist/server/infra/storage/file-query-log-store.js +249 -0
- package/dist/server/infra/transport/handlers/config-handler.js +1 -1
- package/dist/server/infra/usecase/curate-log-use-case.js +7 -3
- package/dist/server/infra/usecase/query-log-summary-narrative-formatter.d.ts +15 -0
- package/dist/server/infra/usecase/query-log-summary-narrative-formatter.js +79 -0
- package/dist/server/infra/usecase/query-log-summary-use-case.d.ts +13 -0
- package/dist/server/infra/usecase/query-log-summary-use-case.js +217 -0
- package/dist/server/infra/usecase/query-log-use-case.d.ts +31 -0
- package/dist/server/infra/usecase/query-log-use-case.js +128 -0
- package/dist/server/utils/log-format-utils.d.ts +5 -0
- package/dist/server/utils/log-format-utils.js +23 -0
- package/dist/shared/transport/events/config-events.d.ts +1 -1
- package/oclif.manifest.json +258 -3
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { API_V1_PATH } from '../constants.js';
|
|
1
2
|
const isEnvironment = (value) => value === 'development' || value === 'production';
|
|
2
3
|
/**
|
|
3
4
|
* Current environment - set at runtime by the launcher scripts.
|
|
@@ -17,25 +18,43 @@ const DEFAULTS = {
|
|
|
17
18
|
production: ['read', 'write'],
|
|
18
19
|
},
|
|
19
20
|
};
|
|
21
|
+
const normalizeUrl = (url) => url.replace(/\/+$/, '');
|
|
22
|
+
const assertRootDomain = (name, url) => {
|
|
23
|
+
if (new URL(url).pathname !== '/') {
|
|
24
|
+
throw new Error(`${name} must not include a path component. Provide the root domain only (e.g., https://example.com).`);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Reads a required environment variable and normalizes it by removing any trailing slash.
|
|
29
|
+
* This normalization applies to all required variables (including BRV_GIT_REMOTE_BASE_URL
|
|
30
|
+
* and BRV_WEB_APP_URL, which may carry paths) to prevent double slashes when joining URLs.
|
|
31
|
+
*/
|
|
20
32
|
const readRequiredEnv = (name) => {
|
|
21
|
-
const value = process.env[name];
|
|
33
|
+
const value = process.env[name]?.trim();
|
|
22
34
|
if (!value) {
|
|
23
35
|
throw new Error(`Missing required environment variable: ${name}. Ensure .env files are loaded via dotenv.`);
|
|
24
36
|
}
|
|
25
|
-
return value;
|
|
37
|
+
return normalizeUrl(value);
|
|
38
|
+
};
|
|
39
|
+
export const getCurrentConfig = () => {
|
|
40
|
+
const iamBaseUrl = readRequiredEnv('BRV_IAM_BASE_URL');
|
|
41
|
+
assertRootDomain('BRV_IAM_BASE_URL', iamBaseUrl);
|
|
42
|
+
const cogitBaseUrl = readRequiredEnv('BRV_COGIT_BASE_URL');
|
|
43
|
+
assertRootDomain('BRV_COGIT_BASE_URL', cogitBaseUrl);
|
|
44
|
+
const oidcBase = `${iamBaseUrl}${API_V1_PATH}/oidc`;
|
|
45
|
+
return {
|
|
46
|
+
authorizationUrl: `${oidcBase}/authorize`,
|
|
47
|
+
clientId: DEFAULTS.clientId,
|
|
48
|
+
cogitBaseUrl,
|
|
49
|
+
gitRemoteBaseUrl: readRequiredEnv('BRV_GIT_REMOTE_BASE_URL'),
|
|
50
|
+
hubRegistryUrl: DEFAULTS.hubRegistryUrl,
|
|
51
|
+
iamBaseUrl,
|
|
52
|
+
issuerUrl: oidcBase,
|
|
53
|
+
llmBaseUrl: readRequiredEnv('BRV_LLM_BASE_URL'),
|
|
54
|
+
scopes: [...DEFAULTS.scopes[ENVIRONMENT]],
|
|
55
|
+
tokenUrl: `${oidcBase}/token`,
|
|
56
|
+
webAppUrl: readRequiredEnv('BRV_WEB_APP_URL'),
|
|
57
|
+
};
|
|
26
58
|
};
|
|
27
|
-
export const getCurrentConfig = () => ({
|
|
28
|
-
apiBaseUrl: readRequiredEnv('BRV_API_BASE_URL'),
|
|
29
|
-
authorizationUrl: readRequiredEnv('BRV_AUTHORIZATION_URL'),
|
|
30
|
-
clientId: DEFAULTS.clientId,
|
|
31
|
-
cogitApiBaseUrl: readRequiredEnv('BRV_COGIT_API_BASE_URL'),
|
|
32
|
-
gitRemoteBaseUrl: readRequiredEnv('BRV_GIT_REMOTE_BASE_URL'),
|
|
33
|
-
hubRegistryUrl: DEFAULTS.hubRegistryUrl,
|
|
34
|
-
issuerUrl: readRequiredEnv('BRV_ISSUER_URL'),
|
|
35
|
-
llmApiBaseUrl: readRequiredEnv('BRV_LLM_API_BASE_URL'),
|
|
36
|
-
scopes: [...DEFAULTS.scopes[ENVIRONMENT]],
|
|
37
|
-
tokenUrl: readRequiredEnv('BRV_TOKEN_URL'),
|
|
38
|
-
webAppUrl: readRequiredEnv('BRV_WEB_APP_URL'),
|
|
39
|
-
});
|
|
40
59
|
export const getGitRemoteBaseUrl = () => process.env.BRV_GIT_REMOTE_BASE_URL ?? 'https://byterover.dev';
|
|
41
60
|
export const isDevelopment = () => ENVIRONMENT === 'development';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const BRV_DIR = ".brv";
|
|
2
|
+
export declare const API_V1_PATH = "/api/v1";
|
|
2
3
|
export declare const PROJECT_CONFIG_FILE = "config.json";
|
|
3
4
|
export declare const BRV_CONFIG_VERSION = "0.0.1";
|
|
4
5
|
export declare const WORKTREES_DIR = "worktrees";
|
|
@@ -56,6 +57,10 @@ export declare const AGENT_PROCESS_READY_TIMEOUT_MS = 30000;
|
|
|
56
57
|
export declare const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000;
|
|
57
58
|
export declare const CURATE_LOG_DIR = "curate-log";
|
|
58
59
|
export declare const CURATE_LOG_ID_PREFIX = "cur";
|
|
60
|
+
export declare const QUERY_LOG_DIR = "query-log";
|
|
61
|
+
export declare const QUERY_LOG_ID_PREFIX = "qry";
|
|
62
|
+
export declare const DREAM_LOG_DIR = "dream-log";
|
|
63
|
+
export declare const DREAM_LOG_ID_PREFIX = "drm";
|
|
59
64
|
export declare const REVIEW_BACKUPS_DIR = "review-backups";
|
|
60
65
|
export declare const SUMMARY_INDEX_FILE = "_index.md";
|
|
61
66
|
export declare const ARCHIVE_DIR = "_archived";
|
package/dist/server/constants.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const BRV_DIR = '.brv';
|
|
2
|
+
export const API_V1_PATH = '/api/v1';
|
|
2
3
|
export const PROJECT_CONFIG_FILE = 'config.json';
|
|
3
4
|
export const BRV_CONFIG_VERSION = '0.0.1';
|
|
4
5
|
// Worktree linking (git-style: .brv is a file pointing to parent project)
|
|
@@ -76,6 +77,12 @@ export const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000; // 5s max wait for child proc
|
|
|
76
77
|
// Curate log
|
|
77
78
|
export const CURATE_LOG_DIR = 'curate-log';
|
|
78
79
|
export const CURATE_LOG_ID_PREFIX = 'cur';
|
|
80
|
+
// Query log
|
|
81
|
+
export const QUERY_LOG_DIR = 'query-log';
|
|
82
|
+
export const QUERY_LOG_ID_PREFIX = 'qry';
|
|
83
|
+
// Dream log
|
|
84
|
+
export const DREAM_LOG_DIR = 'dream-log';
|
|
85
|
+
export const DREAM_LOG_ID_PREFIX = 'drm';
|
|
79
86
|
// Review backups (stores pre-curate file content for local HITL review diffs)
|
|
80
87
|
export const REVIEW_BACKUPS_DIR = 'review-backups';
|
|
81
88
|
// === Hierarchical DAG (summary, archive, manifest) ===
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Valid resolution tiers. Add/remove here — the type updates automatically. */
|
|
2
|
+
export declare const QUERY_LOG_TIERS: readonly [0, 1, 2, 3, 4];
|
|
3
|
+
export type QueryLogTier = (typeof QUERY_LOG_TIERS)[number];
|
|
4
|
+
export type TierKey = `tier${QueryLogTier}`;
|
|
5
|
+
/** Named tier constants — single source of truth for tier assignments in QueryExecutor. */
|
|
6
|
+
export declare const TIER_EXACT_CACHE: QueryLogTier;
|
|
7
|
+
export declare const TIER_FUZZY_CACHE: QueryLogTier;
|
|
8
|
+
export declare const TIER_DIRECT_SEARCH: QueryLogTier;
|
|
9
|
+
export declare const TIER_OPTIMIZED_LLM: QueryLogTier;
|
|
10
|
+
export declare const TIER_FULL_AGENTIC: QueryLogTier;
|
|
11
|
+
/** Human-readable labels for each resolution tier (used in detail view). */
|
|
12
|
+
export declare const QUERY_LOG_TIER_LABELS: Record<QueryLogTier, string>;
|
|
13
|
+
/** Abbreviated tier labels for summary display. */
|
|
14
|
+
export declare const QUERY_LOG_TIER_SHORT_LABELS: Record<QueryLogTier, string>;
|
|
15
|
+
/** Tiers considered cache hits for cache-hit-rate calculation. */
|
|
16
|
+
export declare const CACHE_TIERS: readonly [0, 1];
|
|
17
|
+
export type ByTier = Record<TierKey, number> & {
|
|
18
|
+
unknown: number;
|
|
19
|
+
};
|
|
20
|
+
export declare function emptyByTier(): ByTier;
|
|
21
|
+
/** Valid query log statuses. Add/remove here — the type updates automatically. */
|
|
22
|
+
export declare const QUERY_LOG_STATUSES: readonly ["cancelled", "completed", "error", "processing"];
|
|
23
|
+
export type QueryLogStatus = (typeof QUERY_LOG_STATUSES)[number];
|
|
24
|
+
export type QueryLogMatchedDoc = {
|
|
25
|
+
path: string;
|
|
26
|
+
score: number;
|
|
27
|
+
title: string;
|
|
28
|
+
};
|
|
29
|
+
export type QueryLogSearchMetadata = {
|
|
30
|
+
cacheFingerprint?: string;
|
|
31
|
+
resultCount: number;
|
|
32
|
+
topScore: number;
|
|
33
|
+
totalFound: number;
|
|
34
|
+
};
|
|
35
|
+
type QueryLogBase = {
|
|
36
|
+
id: string;
|
|
37
|
+
matchedDocs: QueryLogMatchedDoc[];
|
|
38
|
+
query: string;
|
|
39
|
+
searchMetadata?: QueryLogSearchMetadata;
|
|
40
|
+
startedAt: number;
|
|
41
|
+
taskId: string;
|
|
42
|
+
tier?: QueryLogTier;
|
|
43
|
+
timing?: {
|
|
44
|
+
durationMs: number;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export type QueryLogEntry = (QueryLogBase & {
|
|
48
|
+
completedAt: number;
|
|
49
|
+
error: string;
|
|
50
|
+
status: 'error';
|
|
51
|
+
}) | (QueryLogBase & {
|
|
52
|
+
completedAt: number;
|
|
53
|
+
response?: string;
|
|
54
|
+
status: 'completed';
|
|
55
|
+
}) | (QueryLogBase & {
|
|
56
|
+
completedAt: number;
|
|
57
|
+
status: 'cancelled';
|
|
58
|
+
}) | (QueryLogBase & {
|
|
59
|
+
status: 'processing';
|
|
60
|
+
});
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// ── Single source of truth: runtime arrays → derived types ───────────────────
|
|
2
|
+
// Tiers originate from QueryExecutor (src/server/infra/executor/query-executor.ts).
|
|
3
|
+
// Statuses track the entry lifecycle. Both are domain concepts.
|
|
4
|
+
/** Valid resolution tiers. Add/remove here — the type updates automatically. */
|
|
5
|
+
export const QUERY_LOG_TIERS = [0, 1, 2, 3, 4];
|
|
6
|
+
/** Named tier constants — single source of truth for tier assignments in QueryExecutor. */
|
|
7
|
+
export const TIER_EXACT_CACHE = 0;
|
|
8
|
+
export const TIER_FUZZY_CACHE = 1;
|
|
9
|
+
export const TIER_DIRECT_SEARCH = 2;
|
|
10
|
+
export const TIER_OPTIMIZED_LLM = 3;
|
|
11
|
+
export const TIER_FULL_AGENTIC = 4;
|
|
12
|
+
/** Human-readable labels for each resolution tier (used in detail view). */
|
|
13
|
+
export const QUERY_LOG_TIER_LABELS = {
|
|
14
|
+
[TIER_DIRECT_SEARCH]: 'direct search',
|
|
15
|
+
[TIER_EXACT_CACHE]: 'exact cache hit',
|
|
16
|
+
[TIER_FULL_AGENTIC]: 'full agentic',
|
|
17
|
+
[TIER_FUZZY_CACHE]: 'fuzzy cache match',
|
|
18
|
+
[TIER_OPTIMIZED_LLM]: 'optimized LLM',
|
|
19
|
+
};
|
|
20
|
+
/** Abbreviated tier labels for summary display. */
|
|
21
|
+
export const QUERY_LOG_TIER_SHORT_LABELS = {
|
|
22
|
+
[TIER_DIRECT_SEARCH]: 'direct',
|
|
23
|
+
[TIER_EXACT_CACHE]: 'exact',
|
|
24
|
+
[TIER_FULL_AGENTIC]: 'agentic',
|
|
25
|
+
[TIER_FUZZY_CACHE]: 'fuzzy',
|
|
26
|
+
[TIER_OPTIMIZED_LLM]: 'LLM',
|
|
27
|
+
};
|
|
28
|
+
/** Tiers considered cache hits for cache-hit-rate calculation. */
|
|
29
|
+
export const CACHE_TIERS = [TIER_EXACT_CACHE, TIER_FUZZY_CACHE];
|
|
30
|
+
// Single `as` contained here — TS cannot prove loop exhaustiveness over template literal keys.
|
|
31
|
+
export function emptyByTier() {
|
|
32
|
+
const obj = {};
|
|
33
|
+
for (const t of QUERY_LOG_TIERS) {
|
|
34
|
+
obj[`tier${t}`] = 0;
|
|
35
|
+
}
|
|
36
|
+
obj.unknown = 0;
|
|
37
|
+
return obj;
|
|
38
|
+
}
|
|
39
|
+
/** Valid query log statuses. Add/remove here — the type updates automatically. */
|
|
40
|
+
export const QUERY_LOG_STATUSES = ['cancelled', 'completed', 'error', 'processing'];
|
|
@@ -405,6 +405,7 @@ export declare const TransportTaskEventNames: {
|
|
|
405
405
|
readonly CREATED: "task:created";
|
|
406
406
|
readonly ERROR: "task:error";
|
|
407
407
|
readonly EXECUTE: "task:execute";
|
|
408
|
+
readonly QUERY_RESULT: "task:queryResult";
|
|
408
409
|
readonly STARTED: "task:started";
|
|
409
410
|
};
|
|
410
411
|
export declare const LlmEventNames: {
|
|
@@ -509,33 +510,41 @@ export declare const TaskExecuteSchema: z.ZodObject<{
|
|
|
509
510
|
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
510
511
|
/** Folder path for curate-folder task type */
|
|
511
512
|
folderPath: z.ZodOptional<z.ZodString>;
|
|
513
|
+
/** Force flag for dream tasks (skip time/activity/queue gates) */
|
|
514
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
512
515
|
/** Project path this task belongs to (for multi-project routing) */
|
|
513
516
|
projectPath: z.ZodOptional<z.ZodString>;
|
|
514
517
|
/** Unique task identifier */
|
|
515
518
|
taskId: z.ZodString;
|
|
519
|
+
/** Dream trigger source — how this dream was initiated */
|
|
520
|
+
trigger: z.ZodOptional<z.ZodEnum<["agent-idle", "cli", "manual"]>>;
|
|
516
521
|
/** Task type */
|
|
517
|
-
type: z.ZodEnum<["curate", "curate-folder", "query", "search"]>;
|
|
522
|
+
type: z.ZodEnum<["curate", "curate-folder", "dream", "query", "search"]>;
|
|
518
523
|
/** Workspace root for scoped query/curate */
|
|
519
524
|
worktreeRoot: z.ZodOptional<z.ZodString>;
|
|
520
525
|
}, "strip", z.ZodTypeAny, {
|
|
521
|
-
type: "curate" | "query" | "search" | "curate-folder";
|
|
526
|
+
type: "curate" | "query" | "search" | "curate-folder" | "dream";
|
|
522
527
|
content: string;
|
|
523
528
|
taskId: string;
|
|
524
529
|
clientId: string;
|
|
525
530
|
files?: string[] | undefined;
|
|
531
|
+
force?: boolean | undefined;
|
|
526
532
|
clientCwd?: string | undefined;
|
|
527
533
|
folderPath?: string | undefined;
|
|
528
534
|
projectPath?: string | undefined;
|
|
535
|
+
trigger?: "manual" | "agent-idle" | "cli" | undefined;
|
|
529
536
|
worktreeRoot?: string | undefined;
|
|
530
537
|
}, {
|
|
531
|
-
type: "curate" | "query" | "search" | "curate-folder";
|
|
538
|
+
type: "curate" | "query" | "search" | "curate-folder" | "dream";
|
|
532
539
|
content: string;
|
|
533
540
|
taskId: string;
|
|
534
541
|
clientId: string;
|
|
535
542
|
files?: string[] | undefined;
|
|
543
|
+
force?: boolean | undefined;
|
|
536
544
|
clientCwd?: string | undefined;
|
|
537
545
|
folderPath?: string | undefined;
|
|
538
546
|
projectPath?: string | undefined;
|
|
547
|
+
trigger?: "manual" | "agent-idle" | "cli" | undefined;
|
|
539
548
|
worktreeRoot?: string | undefined;
|
|
540
549
|
}>;
|
|
541
550
|
/**
|
|
@@ -750,6 +759,8 @@ export declare const TaskCompletedEventSchema: z.ZodObject<{
|
|
|
750
759
|
clientId: z.ZodOptional<z.ZodString>;
|
|
751
760
|
/** Log entry ID from CurateLogHandler, if applicable */
|
|
752
761
|
logId: z.ZodOptional<z.ZodString>;
|
|
762
|
+
/** Project path — used by TaskRouter to notify pool for daemon-submitted tasks */
|
|
763
|
+
projectPath: z.ZodOptional<z.ZodString>;
|
|
753
764
|
result: z.ZodString;
|
|
754
765
|
taskId: z.ZodString;
|
|
755
766
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -757,11 +768,92 @@ export declare const TaskCompletedEventSchema: z.ZodObject<{
|
|
|
757
768
|
taskId: string;
|
|
758
769
|
logId?: string | undefined;
|
|
759
770
|
clientId?: string | undefined;
|
|
771
|
+
projectPath?: string | undefined;
|
|
760
772
|
}, {
|
|
761
773
|
result: string;
|
|
762
774
|
taskId: string;
|
|
763
775
|
logId?: string | undefined;
|
|
764
776
|
clientId?: string | undefined;
|
|
777
|
+
projectPath?: string | undefined;
|
|
778
|
+
}>;
|
|
779
|
+
/**
|
|
780
|
+
* task:queryResult - Query execution metadata (Agent → Daemon, before task:completed)
|
|
781
|
+
* Carries tier/timing/matchedDocs from QueryExecutor for QueryLogHandler.
|
|
782
|
+
* Response string is NOT included — it arrives via task:completed.
|
|
783
|
+
*/
|
|
784
|
+
export declare const TaskQueryResultEventSchema: z.ZodObject<{
|
|
785
|
+
matchedDocs: z.ZodArray<z.ZodObject<{
|
|
786
|
+
path: z.ZodString;
|
|
787
|
+
score: z.ZodNumber;
|
|
788
|
+
title: z.ZodString;
|
|
789
|
+
}, "strip", z.ZodTypeAny, {
|
|
790
|
+
path: string;
|
|
791
|
+
title: string;
|
|
792
|
+
score: number;
|
|
793
|
+
}, {
|
|
794
|
+
path: string;
|
|
795
|
+
title: string;
|
|
796
|
+
score: number;
|
|
797
|
+
}>, "many">;
|
|
798
|
+
searchMetadata: z.ZodOptional<z.ZodObject<{
|
|
799
|
+
cacheFingerprint: z.ZodOptional<z.ZodString>;
|
|
800
|
+
resultCount: z.ZodNumber;
|
|
801
|
+
topScore: z.ZodNumber;
|
|
802
|
+
totalFound: z.ZodNumber;
|
|
803
|
+
}, "strip", z.ZodTypeAny, {
|
|
804
|
+
totalFound: number;
|
|
805
|
+
resultCount: number;
|
|
806
|
+
topScore: number;
|
|
807
|
+
cacheFingerprint?: string | undefined;
|
|
808
|
+
}, {
|
|
809
|
+
totalFound: number;
|
|
810
|
+
resultCount: number;
|
|
811
|
+
topScore: number;
|
|
812
|
+
cacheFingerprint?: string | undefined;
|
|
813
|
+
}>>;
|
|
814
|
+
taskId: z.ZodString;
|
|
815
|
+
tier: z.ZodType<0 | 3 | 1 | 2 | 4, z.ZodTypeDef, 0 | 3 | 1 | 2 | 4>;
|
|
816
|
+
timing: z.ZodObject<{
|
|
817
|
+
durationMs: z.ZodNumber;
|
|
818
|
+
}, "strip", z.ZodTypeAny, {
|
|
819
|
+
durationMs: number;
|
|
820
|
+
}, {
|
|
821
|
+
durationMs: number;
|
|
822
|
+
}>;
|
|
823
|
+
}, "strip", z.ZodTypeAny, {
|
|
824
|
+
taskId: string;
|
|
825
|
+
matchedDocs: {
|
|
826
|
+
path: string;
|
|
827
|
+
title: string;
|
|
828
|
+
score: number;
|
|
829
|
+
}[];
|
|
830
|
+
tier: 0 | 3 | 1 | 2 | 4;
|
|
831
|
+
timing: {
|
|
832
|
+
durationMs: number;
|
|
833
|
+
};
|
|
834
|
+
searchMetadata?: {
|
|
835
|
+
totalFound: number;
|
|
836
|
+
resultCount: number;
|
|
837
|
+
topScore: number;
|
|
838
|
+
cacheFingerprint?: string | undefined;
|
|
839
|
+
} | undefined;
|
|
840
|
+
}, {
|
|
841
|
+
taskId: string;
|
|
842
|
+
matchedDocs: {
|
|
843
|
+
path: string;
|
|
844
|
+
title: string;
|
|
845
|
+
score: number;
|
|
846
|
+
}[];
|
|
847
|
+
tier: 0 | 3 | 1 | 2 | 4;
|
|
848
|
+
timing: {
|
|
849
|
+
durationMs: number;
|
|
850
|
+
};
|
|
851
|
+
searchMetadata?: {
|
|
852
|
+
totalFound: number;
|
|
853
|
+
resultCount: number;
|
|
854
|
+
topScore: number;
|
|
855
|
+
cacheFingerprint?: string | undefined;
|
|
856
|
+
} | undefined;
|
|
765
857
|
}>;
|
|
766
858
|
/**
|
|
767
859
|
* Structured error object
|
|
@@ -806,6 +898,8 @@ export declare const TaskErrorEventSchema: z.ZodObject<{
|
|
|
806
898
|
}>;
|
|
807
899
|
/** Log entry ID from CurateLogHandler, if applicable */
|
|
808
900
|
logId: z.ZodOptional<z.ZodString>;
|
|
901
|
+
/** Project path — used by TaskRouter to notify pool for daemon-submitted tasks */
|
|
902
|
+
projectPath: z.ZodOptional<z.ZodString>;
|
|
809
903
|
taskId: z.ZodString;
|
|
810
904
|
}, "strip", z.ZodTypeAny, {
|
|
811
905
|
error: {
|
|
@@ -817,6 +911,7 @@ export declare const TaskErrorEventSchema: z.ZodObject<{
|
|
|
817
911
|
taskId: string;
|
|
818
912
|
logId?: string | undefined;
|
|
819
913
|
clientId?: string | undefined;
|
|
914
|
+
projectPath?: string | undefined;
|
|
820
915
|
}, {
|
|
821
916
|
error: {
|
|
822
917
|
message: string;
|
|
@@ -827,6 +922,7 @@ export declare const TaskErrorEventSchema: z.ZodObject<{
|
|
|
827
922
|
taskId: string;
|
|
828
923
|
logId?: string | undefined;
|
|
829
924
|
clientId?: string | undefined;
|
|
925
|
+
projectPath?: string | undefined;
|
|
830
926
|
}>;
|
|
831
927
|
/**
|
|
832
928
|
* llmservice:response - LLM text output
|
|
@@ -945,7 +1041,8 @@ export type TaskStartedEvent = z.infer<typeof TaskStartedEventSchema>;
|
|
|
945
1041
|
export type TaskCompletedEvent = z.infer<typeof TaskCompletedEventSchema>;
|
|
946
1042
|
export type TaskErrorData = z.infer<typeof TaskErrorDataSchema>;
|
|
947
1043
|
export type TaskErrorEvent = z.infer<typeof TaskErrorEventSchema>;
|
|
948
|
-
export
|
|
1044
|
+
export type TaskQueryResultEvent = z.infer<typeof TaskQueryResultEventSchema>;
|
|
1045
|
+
export declare const TaskTypeSchema: z.ZodEnum<["curate", "curate-folder", "dream", "query", "search"]>;
|
|
949
1046
|
/**
|
|
950
1047
|
* Request to create a new task
|
|
951
1048
|
*/
|
|
@@ -958,28 +1055,32 @@ export declare const TaskCreateRequestSchema: z.ZodObject<{
|
|
|
958
1055
|
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
959
1056
|
/** Folder path for curate-folder task type */
|
|
960
1057
|
folderPath: z.ZodOptional<z.ZodString>;
|
|
1058
|
+
/** Force flag for dream tasks (skip time/activity/queue gates) */
|
|
1059
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
961
1060
|
/** Project path this task belongs to (for multi-project routing) */
|
|
962
1061
|
projectPath: z.ZodOptional<z.ZodString>;
|
|
963
1062
|
/** Task ID - generated by Client UseCase (UUID v4) */
|
|
964
1063
|
taskId: z.ZodString;
|
|
965
1064
|
/** Task type */
|
|
966
|
-
type: z.ZodEnum<["curate", "curate-folder", "query", "search"]>;
|
|
1065
|
+
type: z.ZodEnum<["curate", "curate-folder", "dream", "query", "search"]>;
|
|
967
1066
|
/** Workspace root for scoped query/curate (stable linked root or projectRoot if unlinked) */
|
|
968
1067
|
worktreeRoot: z.ZodOptional<z.ZodString>;
|
|
969
1068
|
}, "strip", z.ZodTypeAny, {
|
|
970
|
-
type: "curate" | "query" | "search" | "curate-folder";
|
|
1069
|
+
type: "curate" | "query" | "search" | "curate-folder" | "dream";
|
|
971
1070
|
content: string;
|
|
972
1071
|
taskId: string;
|
|
973
1072
|
files?: string[] | undefined;
|
|
1073
|
+
force?: boolean | undefined;
|
|
974
1074
|
clientCwd?: string | undefined;
|
|
975
1075
|
folderPath?: string | undefined;
|
|
976
1076
|
projectPath?: string | undefined;
|
|
977
1077
|
worktreeRoot?: string | undefined;
|
|
978
1078
|
}, {
|
|
979
|
-
type: "curate" | "query" | "search" | "curate-folder";
|
|
1079
|
+
type: "curate" | "query" | "search" | "curate-folder" | "dream";
|
|
980
1080
|
content: string;
|
|
981
1081
|
taskId: string;
|
|
982
1082
|
files?: string[] | undefined;
|
|
1083
|
+
force?: boolean | undefined;
|
|
983
1084
|
clientCwd?: string | undefined;
|
|
984
1085
|
folderPath?: string | undefined;
|
|
985
1086
|
projectPath?: string | undefined;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - Zod schemas provide runtime validation for transport messages
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
+
import { QUERY_LOG_TIERS } from '../../domain/entities/query-log-entry.js';
|
|
11
12
|
// ============================================================================
|
|
12
13
|
// Zod Schemas for Runtime Validation (mirrors domain types)
|
|
13
14
|
// ============================================================================
|
|
@@ -216,6 +217,8 @@ export const TransportTaskEventNames = {
|
|
|
216
217
|
ERROR: 'task:error',
|
|
217
218
|
// Internal (Transport → Agent)
|
|
218
219
|
EXECUTE: 'task:execute',
|
|
220
|
+
// Query metadata (Agent → Daemon, before task:completed)
|
|
221
|
+
QUERY_RESULT: 'task:queryResult',
|
|
219
222
|
STARTED: 'task:started',
|
|
220
223
|
};
|
|
221
224
|
export const LlmEventNames = {
|
|
@@ -309,12 +312,16 @@ export const TaskExecuteSchema = z.object({
|
|
|
309
312
|
files: z.array(z.string()).optional(),
|
|
310
313
|
/** Folder path for curate-folder task type */
|
|
311
314
|
folderPath: z.string().optional(),
|
|
315
|
+
/** Force flag for dream tasks (skip time/activity/queue gates) */
|
|
316
|
+
force: z.boolean().optional(),
|
|
312
317
|
/** Project path this task belongs to (for multi-project routing) */
|
|
313
318
|
projectPath: z.string().optional(),
|
|
314
319
|
/** Unique task identifier */
|
|
315
320
|
taskId: z.string(),
|
|
321
|
+
/** Dream trigger source — how this dream was initiated */
|
|
322
|
+
trigger: z.enum(['agent-idle', 'cli', 'manual']).optional(),
|
|
316
323
|
/** Task type */
|
|
317
|
-
type: z.enum(['curate', 'curate-folder', 'query', 'search']),
|
|
324
|
+
type: z.enum(['curate', 'curate-folder', 'dream', 'query', 'search']),
|
|
318
325
|
/** Workspace root for scoped query/curate */
|
|
319
326
|
worktreeRoot: z.string().optional(),
|
|
320
327
|
});
|
|
@@ -407,9 +414,30 @@ export const TaskCompletedEventSchema = z.object({
|
|
|
407
414
|
clientId: z.string().optional(),
|
|
408
415
|
/** Log entry ID from CurateLogHandler, if applicable */
|
|
409
416
|
logId: z.string().optional(),
|
|
417
|
+
/** Project path — used by TaskRouter to notify pool for daemon-submitted tasks */
|
|
418
|
+
projectPath: z.string().optional(),
|
|
410
419
|
result: z.string(),
|
|
411
420
|
taskId: z.string(),
|
|
412
421
|
});
|
|
422
|
+
/**
|
|
423
|
+
* task:queryResult - Query execution metadata (Agent → Daemon, before task:completed)
|
|
424
|
+
* Carries tier/timing/matchedDocs from QueryExecutor for QueryLogHandler.
|
|
425
|
+
* Response string is NOT included — it arrives via task:completed.
|
|
426
|
+
*/
|
|
427
|
+
export const TaskQueryResultEventSchema = z.object({
|
|
428
|
+
matchedDocs: z.array(z.object({ path: z.string(), score: z.number(), title: z.string() })),
|
|
429
|
+
searchMetadata: z
|
|
430
|
+
.object({
|
|
431
|
+
cacheFingerprint: z.string().optional(),
|
|
432
|
+
resultCount: z.number(),
|
|
433
|
+
topScore: z.number(),
|
|
434
|
+
totalFound: z.number(),
|
|
435
|
+
})
|
|
436
|
+
.optional(),
|
|
437
|
+
taskId: z.string(),
|
|
438
|
+
tier: z.custom((val) => new Set(QUERY_LOG_TIERS).has(val), { message: 'Invalid query log tier' }),
|
|
439
|
+
timing: z.object({ durationMs: z.number() }),
|
|
440
|
+
});
|
|
413
441
|
/**
|
|
414
442
|
* Structured error object
|
|
415
443
|
* Matches TaskErrorData interface in task-error.ts
|
|
@@ -428,6 +456,8 @@ export const TaskErrorEventSchema = z.object({
|
|
|
428
456
|
error: TaskErrorDataSchema,
|
|
429
457
|
/** Log entry ID from CurateLogHandler, if applicable */
|
|
430
458
|
logId: z.string().optional(),
|
|
459
|
+
/** Project path — used by TaskRouter to notify pool for daemon-submitted tasks */
|
|
460
|
+
projectPath: z.string().optional(),
|
|
431
461
|
taskId: z.string(),
|
|
432
462
|
});
|
|
433
463
|
/**
|
|
@@ -475,7 +505,7 @@ export const LlmToolResultEventSchema = z.object({
|
|
|
475
505
|
// ============================================================================
|
|
476
506
|
// Request/Response Schemas (for client → server commands)
|
|
477
507
|
// ============================================================================
|
|
478
|
-
export const TaskTypeSchema = z.enum(['curate', 'curate-folder', 'query', 'search']);
|
|
508
|
+
export const TaskTypeSchema = z.enum(['curate', 'curate-folder', 'dream', 'query', 'search']);
|
|
479
509
|
/**
|
|
480
510
|
* Request to create a new task
|
|
481
511
|
*/
|
|
@@ -488,6 +518,8 @@ export const TaskCreateRequestSchema = z.object({
|
|
|
488
518
|
files: z.array(z.string()).optional(),
|
|
489
519
|
/** Folder path for curate-folder task type */
|
|
490
520
|
folderPath: z.string().optional(),
|
|
521
|
+
/** Force flag for dream tasks (skip time/activity/queue gates) */
|
|
522
|
+
force: z.boolean().optional(),
|
|
491
523
|
/** Project path this task belongs to (for multi-project routing) */
|
|
492
524
|
projectPath: z.string().optional(),
|
|
493
525
|
/** Task ID - generated by Client UseCase (UUID v4) */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ICipherAgent } from '../../../../agent/core/interfaces/i-cipher-agent.js';
|
|
2
|
+
import type { QueryLogMatchedDoc, QueryLogSearchMetadata, QueryLogTier } from '../../domain/entities/query-log-entry.js';
|
|
2
3
|
/**
|
|
3
4
|
* Options for executing query with an injected agent.
|
|
4
5
|
* Agent uses its default session (Single-Session pattern).
|
|
@@ -11,6 +12,26 @@ export interface QueryExecuteOptions {
|
|
|
11
12
|
/** Stable workspace root for scoping search and cache isolation */
|
|
12
13
|
worktreeRoot?: string;
|
|
13
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Structured result from QueryExecutor containing the response string
|
|
17
|
+
* plus metadata about how the query was resolved.
|
|
18
|
+
*
|
|
19
|
+
* Consumed by QueryLogHandler (ENG-1893) to persist query log entries.
|
|
20
|
+
*/
|
|
21
|
+
export type QueryExecutorResult = {
|
|
22
|
+
/** Documents matched during search (empty for cache hits) */
|
|
23
|
+
matchedDocs: QueryLogMatchedDoc[];
|
|
24
|
+
/** The response string (includes attribution footer) */
|
|
25
|
+
response: string;
|
|
26
|
+
/** Search statistics (undefined for cache-only tiers 0/1) */
|
|
27
|
+
searchMetadata?: QueryLogSearchMetadata;
|
|
28
|
+
/** Resolution tier: 0=exact cache, 1=fuzzy cache, 2=direct search, 3=optimized LLM, 4=full agentic */
|
|
29
|
+
tier: QueryLogTier;
|
|
30
|
+
/** Wall-clock timing from method entry to return */
|
|
31
|
+
timing: {
|
|
32
|
+
durationMs: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
14
35
|
/**
|
|
15
36
|
* IQueryExecutor - Executes query tasks with an injected CipherAgent.
|
|
16
37
|
*
|
|
@@ -28,7 +49,7 @@ export interface IQueryExecutor {
|
|
|
28
49
|
*
|
|
29
50
|
* @param agent - Long-lived CipherAgent (managed by caller)
|
|
30
51
|
* @param options - Execution options (query)
|
|
31
|
-
* @returns
|
|
52
|
+
* @returns Structured result with response, tier, timing, and search metadata
|
|
32
53
|
*/
|
|
33
|
-
executeWithAgent(agent: ICipherAgent, options: QueryExecuteOptions): Promise<
|
|
54
|
+
executeWithAgent(agent: ICipherAgent, options: QueryExecuteOptions): Promise<QueryExecutorResult>;
|
|
34
55
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { QueryLogEntry, QueryLogStatus, QueryLogTier } from '../../domain/entities/query-log-entry.js';
|
|
2
|
+
export { QUERY_LOG_STATUSES, QUERY_LOG_TIERS } from '../../domain/entities/query-log-entry.js';
|
|
3
|
+
export type { QueryLogStatus, QueryLogTier } from '../../domain/entities/query-log-entry.js';
|
|
4
|
+
export interface IQueryLogStore {
|
|
5
|
+
/** Retrieve an entry by ID. Returns undefined if not found or if the file is corrupt. */
|
|
6
|
+
getById(id: string): Promise<QueryLogEntry | undefined>;
|
|
7
|
+
/** Generate the next monotonic log entry ID. */
|
|
8
|
+
getNextId(): Promise<string>;
|
|
9
|
+
/** List entries sorted newest-first. Filters are applied before limit. */
|
|
10
|
+
list(options?: {
|
|
11
|
+
/** Include only entries with startedAt >= after (ms timestamp). */
|
|
12
|
+
after?: number;
|
|
13
|
+
/** Include only entries with startedAt <= before (ms timestamp). */
|
|
14
|
+
before?: number;
|
|
15
|
+
limit?: number;
|
|
16
|
+
/** Include only entries matching these statuses. */
|
|
17
|
+
status?: QueryLogStatus[];
|
|
18
|
+
/** Include only entries matching these tiers. */
|
|
19
|
+
tier?: QueryLogTier[];
|
|
20
|
+
}): Promise<QueryLogEntry[]>;
|
|
21
|
+
/** Persist (create or overwrite) a log entry. Best-effort — callers should handle errors. */
|
|
22
|
+
save(entry: QueryLogEntry): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ByTier } from '../../domain/entities/query-log-entry.js';
|
|
2
|
+
export type QueryLogSummary = {
|
|
3
|
+
byStatus: {
|
|
4
|
+
cancelled: number;
|
|
5
|
+
completed: number;
|
|
6
|
+
error: number;
|
|
7
|
+
};
|
|
8
|
+
byTier: ByTier;
|
|
9
|
+
cacheHitRate: number;
|
|
10
|
+
coverageRate: number;
|
|
11
|
+
knowledgeGaps: {
|
|
12
|
+
count: number;
|
|
13
|
+
exampleQueries: string[];
|
|
14
|
+
topic: string;
|
|
15
|
+
}[];
|
|
16
|
+
period: {
|
|
17
|
+
from: number;
|
|
18
|
+
to: number;
|
|
19
|
+
};
|
|
20
|
+
queriesWithoutMatches: number;
|
|
21
|
+
responseTime: {
|
|
22
|
+
avgMs: number;
|
|
23
|
+
p50Ms: number;
|
|
24
|
+
p95Ms: number;
|
|
25
|
+
};
|
|
26
|
+
topRecalledDocs: {
|
|
27
|
+
count: number;
|
|
28
|
+
path: string;
|
|
29
|
+
}[];
|
|
30
|
+
topTopics: {
|
|
31
|
+
count: number;
|
|
32
|
+
topic: string;
|
|
33
|
+
}[];
|
|
34
|
+
totalMatchedDocs: number;
|
|
35
|
+
totalQueries: number;
|
|
36
|
+
};
|
|
37
|
+
export type QueryLogSummaryFormat = 'json' | 'narrative' | 'text';
|
|
38
|
+
export interface IQueryLogSummaryUseCase {
|
|
39
|
+
run(options: {
|
|
40
|
+
after?: number;
|
|
41
|
+
before?: number;
|
|
42
|
+
format?: QueryLogSummaryFormat;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { QueryLogStatus, QueryLogTier } from '../storage/i-query-log-store.js';
|
|
2
|
+
export interface IQueryLogUseCase {
|
|
3
|
+
run(options: {
|
|
4
|
+
after?: number;
|
|
5
|
+
before?: number;
|
|
6
|
+
detail?: boolean;
|
|
7
|
+
format?: 'json' | 'text';
|
|
8
|
+
id?: string;
|
|
9
|
+
limit?: number;
|
|
10
|
+
status?: QueryLogStatus[];
|
|
11
|
+
tier?: QueryLogTier[];
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
}
|