byterover-cli 3.5.1 → 3.6.1

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.
Files changed (84) hide show
  1. package/.env.production +4 -6
  2. package/dist/agent/core/interfaces/i-cipher-agent.d.ts +1 -0
  3. package/dist/agent/infra/agent/cipher-agent.d.ts +1 -0
  4. package/dist/agent/infra/agent/cipher-agent.js +1 -0
  5. package/dist/oclif/commands/curate/view.js +5 -25
  6. package/dist/oclif/commands/dream.d.ts +18 -0
  7. package/dist/oclif/commands/dream.js +230 -0
  8. package/dist/oclif/commands/query-log/summary.d.ts +18 -0
  9. package/dist/oclif/commands/query-log/summary.js +75 -0
  10. package/dist/oclif/commands/query-log/view.d.ts +23 -0
  11. package/dist/oclif/commands/query-log/view.js +95 -0
  12. package/dist/oclif/lib/time-filter.d.ts +10 -0
  13. package/dist/oclif/lib/time-filter.js +21 -0
  14. package/dist/server/config/environment.d.ts +10 -3
  15. package/dist/server/config/environment.js +34 -15
  16. package/dist/server/constants.d.ts +5 -0
  17. package/dist/server/constants.js +7 -0
  18. package/dist/server/core/domain/entities/query-log-entry.d.ts +61 -0
  19. package/dist/server/core/domain/entities/query-log-entry.js +40 -0
  20. package/dist/server/core/domain/transport/schemas.d.ts +108 -7
  21. package/dist/server/core/domain/transport/schemas.js +34 -2
  22. package/dist/server/core/interfaces/executor/i-query-executor.d.ts +23 -2
  23. package/dist/server/core/interfaces/i-terminal.d.ts +3 -0
  24. package/dist/server/core/interfaces/i-terminal.js +1 -0
  25. package/dist/server/core/interfaces/storage/i-query-log-store.d.ts +23 -0
  26. package/dist/server/core/interfaces/storage/i-query-log-store.js +2 -0
  27. package/dist/server/core/interfaces/usecase/i-query-log-summary-use-case.d.ts +44 -0
  28. package/dist/server/core/interfaces/usecase/i-query-log-summary-use-case.js +1 -0
  29. package/dist/server/core/interfaces/usecase/i-query-log-use-case.d.ts +13 -0
  30. package/dist/server/core/interfaces/usecase/i-query-log-use-case.js +3 -0
  31. package/dist/server/infra/daemon/agent-process.js +79 -9
  32. package/dist/server/infra/daemon/brv-server.js +74 -5
  33. package/dist/server/infra/dream/dream-lock-service.d.ts +37 -0
  34. package/dist/server/infra/dream/dream-lock-service.js +88 -0
  35. package/dist/server/infra/dream/dream-log-schema.d.ts +966 -0
  36. package/dist/server/infra/dream/dream-log-schema.js +57 -0
  37. package/dist/server/infra/dream/dream-log-store.d.ts +55 -0
  38. package/dist/server/infra/dream/dream-log-store.js +141 -0
  39. package/dist/server/infra/dream/dream-response-schemas.d.ts +219 -0
  40. package/dist/server/infra/dream/dream-response-schemas.js +38 -0
  41. package/dist/server/infra/dream/dream-state-schema.d.ts +67 -0
  42. package/dist/server/infra/dream/dream-state-schema.js +23 -0
  43. package/dist/server/infra/dream/dream-state-service.d.ts +38 -0
  44. package/dist/server/infra/dream/dream-state-service.js +91 -0
  45. package/dist/server/infra/dream/dream-trigger.d.ts +46 -0
  46. package/dist/server/infra/dream/dream-trigger.js +65 -0
  47. package/dist/server/infra/dream/dream-undo.d.ts +38 -0
  48. package/dist/server/infra/dream/dream-undo.js +293 -0
  49. package/dist/server/infra/dream/operations/consolidate.d.ts +52 -0
  50. package/dist/server/infra/dream/operations/consolidate.js +514 -0
  51. package/dist/server/infra/dream/operations/prune.d.ts +45 -0
  52. package/dist/server/infra/dream/operations/prune.js +362 -0
  53. package/dist/server/infra/dream/operations/synthesize.d.ts +37 -0
  54. package/dist/server/infra/dream/operations/synthesize.js +278 -0
  55. package/dist/server/infra/dream/parse-dream-response.d.ts +11 -0
  56. package/dist/server/infra/dream/parse-dream-response.js +35 -0
  57. package/dist/server/infra/executor/curate-executor.js +10 -0
  58. package/dist/server/infra/executor/dream-executor.d.ts +97 -0
  59. package/dist/server/infra/executor/dream-executor.js +431 -0
  60. package/dist/server/infra/executor/query-executor.d.ts +2 -2
  61. package/dist/server/infra/executor/query-executor.js +92 -22
  62. package/dist/server/infra/process/feature-handlers.js +10 -6
  63. package/dist/server/infra/process/query-log-handler.d.ts +42 -0
  64. package/dist/server/infra/process/query-log-handler.js +150 -0
  65. package/dist/server/infra/process/task-router.d.ts +40 -0
  66. package/dist/server/infra/process/task-router.js +67 -9
  67. package/dist/server/infra/process/transport-handlers.d.ts +4 -0
  68. package/dist/server/infra/process/transport-handlers.js +1 -0
  69. package/dist/server/infra/storage/file-curate-log-store.js +1 -1
  70. package/dist/server/infra/storage/file-query-log-store.d.ts +81 -0
  71. package/dist/server/infra/storage/file-query-log-store.js +249 -0
  72. package/dist/server/infra/transport/handlers/config-handler.js +1 -1
  73. package/dist/server/infra/usecase/curate-log-use-case.js +7 -3
  74. package/dist/server/infra/usecase/query-log-summary-narrative-formatter.d.ts +15 -0
  75. package/dist/server/infra/usecase/query-log-summary-narrative-formatter.js +79 -0
  76. package/dist/server/infra/usecase/query-log-summary-use-case.d.ts +13 -0
  77. package/dist/server/infra/usecase/query-log-summary-use-case.js +217 -0
  78. package/dist/server/infra/usecase/query-log-use-case.d.ts +31 -0
  79. package/dist/server/infra/usecase/query-log-use-case.js +128 -0
  80. package/dist/server/utils/log-format-utils.d.ts +5 -0
  81. package/dist/server/utils/log-format-utils.js +23 -0
  82. package/dist/shared/transport/events/config-events.d.ts +1 -1
  83. package/oclif.manifest.json +510 -255
  84. 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";
@@ -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 declare const TaskTypeSchema: z.ZodEnum<["curate", "curate-folder", "query", "search"]>;
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 Result string from agent execution
52
+ * @returns Structured result with response, tier, timing, and search metadata
32
53
  */
33
- executeWithAgent(agent: ICipherAgent, options: QueryExecuteOptions): Promise<string>;
54
+ executeWithAgent(agent: ICipherAgent, options: QueryExecuteOptions): Promise<QueryExecutorResult>;
34
55
  }
@@ -0,0 +1,3 @@
1
+ export interface ITerminal {
2
+ log(msg?: string): void;
3
+ }
@@ -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,2 @@
1
+ // Re-export domain types — single source of truth is in the entity.
2
+ export { QUERY_LOG_STATUSES, QUERY_LOG_TIERS } from '../../domain/entities/query-log-entry.js';
@@ -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,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
+ }
@@ -0,0 +1,3 @@
1
+ // Interface driven by brv query-log view command (ENG-1897).
2
+ // Full implementation in ENG-1895.
3
+ export {};