byterover-cli 1.0.4 → 1.1.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.
Files changed (172) hide show
  1. package/README.md +24 -11
  2. package/dist/commands/curate.js +1 -1
  3. package/dist/commands/hook-prompt-submit.d.ts +27 -0
  4. package/dist/commands/hook-prompt-submit.js +39 -0
  5. package/dist/commands/main.d.ts +13 -0
  6. package/dist/commands/main.js +53 -2
  7. package/dist/commands/query.js +1 -1
  8. package/dist/commands/status.js +8 -3
  9. package/dist/constants.d.ts +2 -2
  10. package/dist/constants.js +2 -2
  11. package/dist/core/domain/cipher/llm/registry.js +53 -2
  12. package/dist/core/domain/cipher/llm/types.d.ts +2 -0
  13. package/dist/core/domain/cipher/process/types.d.ts +7 -0
  14. package/dist/core/domain/cipher/session/session-metadata.d.ts +178 -0
  15. package/dist/core/domain/cipher/session/session-metadata.js +147 -0
  16. package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
  17. package/dist/core/domain/cipher/tools/constants.js +1 -0
  18. package/dist/core/domain/entities/agent.d.ts +16 -0
  19. package/dist/core/domain/entities/agent.js +24 -0
  20. package/dist/core/domain/entities/connector-type.d.ts +9 -0
  21. package/dist/core/domain/entities/connector-type.js +8 -0
  22. package/dist/core/domain/entities/event.d.ts +1 -1
  23. package/dist/core/domain/entities/event.js +2 -0
  24. package/dist/core/domain/errors/task-error.d.ts +4 -0
  25. package/dist/core/domain/errors/task-error.js +7 -0
  26. package/dist/core/domain/knowledge/markdown-writer.d.ts +15 -18
  27. package/dist/core/domain/knowledge/markdown-writer.js +232 -34
  28. package/dist/core/domain/knowledge/relation-parser.d.ts +25 -39
  29. package/dist/core/domain/knowledge/relation-parser.js +39 -61
  30. package/dist/core/domain/transport/schemas.d.ts +77 -2
  31. package/dist/core/domain/transport/schemas.js +51 -2
  32. package/dist/core/interfaces/cipher/i-session-persistence.d.ts +133 -0
  33. package/dist/core/interfaces/cipher/i-session-persistence.js +7 -0
  34. package/dist/core/interfaces/cipher/message-types.d.ts +6 -0
  35. package/dist/core/interfaces/connectors/connector-types.d.ts +57 -0
  36. package/dist/core/interfaces/connectors/i-connector-manager.d.ts +72 -0
  37. package/dist/core/interfaces/connectors/i-connector.d.ts +54 -0
  38. package/dist/core/interfaces/connectors/i-connector.js +1 -0
  39. package/dist/core/interfaces/executor/i-curate-executor.d.ts +2 -2
  40. package/dist/core/interfaces/i-context-file-reader.d.ts +3 -0
  41. package/dist/core/interfaces/i-file-service.d.ts +7 -0
  42. package/dist/core/interfaces/usecase/i-connectors-use-case.d.ts +3 -0
  43. package/dist/core/interfaces/usecase/i-connectors-use-case.js +1 -0
  44. package/dist/core/interfaces/usecase/{i-clear-use-case.d.ts → i-reset-use-case.d.ts} +1 -1
  45. package/dist/core/interfaces/usecase/i-reset-use-case.js +1 -0
  46. package/dist/hooks/init/update-notifier.d.ts +1 -0
  47. package/dist/hooks/init/update-notifier.js +10 -1
  48. package/dist/infra/cipher/agent/agent-schemas.d.ts +6 -6
  49. package/dist/infra/cipher/agent/service-initializer.js +4 -4
  50. package/dist/infra/cipher/file-system/binary-utils.d.ts +7 -12
  51. package/dist/infra/cipher/file-system/binary-utils.js +46 -31
  52. package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +3 -2
  53. package/dist/infra/cipher/file-system/file-system-service.js +1 -0
  54. package/dist/infra/cipher/http/internal-llm-http-service.js +3 -5
  55. package/dist/infra/cipher/interactive-loop.js +3 -1
  56. package/dist/infra/cipher/llm/context/context-manager.d.ts +2 -2
  57. package/dist/infra/cipher/llm/context/context-manager.js +63 -18
  58. package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +13 -0
  59. package/dist/infra/cipher/llm/formatters/gemini-formatter.js +146 -15
  60. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +6 -2
  61. package/dist/infra/cipher/llm/internal-llm-service.js +2 -2
  62. package/dist/infra/cipher/llm/thought-parser.d.ts +21 -0
  63. package/dist/infra/cipher/llm/thought-parser.js +27 -0
  64. package/dist/infra/cipher/llm/tool-output-processor.d.ts +10 -0
  65. package/dist/infra/cipher/llm/tool-output-processor.js +80 -7
  66. package/dist/infra/cipher/process/process-service.js +11 -3
  67. package/dist/infra/cipher/session/chat-session.d.ts +7 -2
  68. package/dist/infra/cipher/session/chat-session.js +90 -52
  69. package/dist/infra/cipher/session/session-metadata-store.d.ts +52 -0
  70. package/dist/infra/cipher/session/session-metadata-store.js +406 -0
  71. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +6 -7
  72. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +57 -18
  73. package/dist/infra/cipher/tools/implementations/curate-tool.js +132 -36
  74. package/dist/infra/cipher/tools/implementations/read-file-tool.js +38 -17
  75. package/dist/infra/cipher/tools/implementations/search-knowledge-tool.d.ts +7 -0
  76. package/dist/infra/cipher/tools/implementations/search-knowledge-tool.js +303 -0
  77. package/dist/infra/cipher/tools/implementations/task-tool.js +1 -0
  78. package/dist/infra/cipher/tools/index.d.ts +1 -0
  79. package/dist/infra/cipher/tools/index.js +1 -0
  80. package/dist/infra/cipher/tools/tool-manager.js +1 -0
  81. package/dist/infra/cipher/tools/tool-registry.js +7 -0
  82. package/dist/infra/connectors/connector-manager.d.ts +32 -0
  83. package/dist/infra/connectors/connector-manager.js +156 -0
  84. package/dist/infra/connectors/hook/hook-connector-config.d.ts +52 -0
  85. package/dist/infra/connectors/hook/hook-connector-config.js +41 -0
  86. package/dist/infra/connectors/hook/hook-connector.d.ts +46 -0
  87. package/dist/infra/connectors/hook/hook-connector.js +231 -0
  88. package/dist/infra/{rule → connectors/rules}/legacy-rule-detector.d.ts +2 -2
  89. package/dist/infra/{rule → connectors/rules}/legacy-rule-detector.js +1 -1
  90. package/dist/infra/connectors/rules/rules-connector-config.d.ts +95 -0
  91. package/dist/infra/{rule/agent-rule-config.js → connectors/rules/rules-connector-config.js} +10 -10
  92. package/dist/infra/connectors/rules/rules-connector.d.ts +41 -0
  93. package/dist/infra/connectors/rules/rules-connector.js +204 -0
  94. package/dist/infra/{rule/rule-template-service.d.ts → connectors/shared/template-service.d.ts} +3 -3
  95. package/dist/infra/{rule/rule-template-service.js → connectors/shared/template-service.js} +1 -1
  96. package/dist/infra/context-tree/file-context-file-reader.js +4 -0
  97. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +5 -2
  98. package/dist/infra/context-tree/file-context-tree-writer-service.js +20 -5
  99. package/dist/infra/core/executors/curate-executor.d.ts +2 -2
  100. package/dist/infra/core/executors/curate-executor.js +7 -7
  101. package/dist/infra/core/executors/query-executor.d.ts +12 -0
  102. package/dist/infra/core/executors/query-executor.js +62 -1
  103. package/dist/infra/core/task-processor.d.ts +2 -2
  104. package/dist/infra/file/fs-file-service.d.ts +7 -0
  105. package/dist/infra/file/fs-file-service.js +15 -1
  106. package/dist/infra/process/agent-worker.d.ts +2 -2
  107. package/dist/infra/process/agent-worker.js +626 -142
  108. package/dist/infra/process/constants.d.ts +1 -1
  109. package/dist/infra/process/constants.js +1 -1
  110. package/dist/infra/process/ipc-types.d.ts +17 -4
  111. package/dist/infra/process/ipc-types.js +3 -3
  112. package/dist/infra/process/parent-heartbeat.d.ts +47 -0
  113. package/dist/infra/process/parent-heartbeat.js +118 -0
  114. package/dist/infra/process/process-manager.d.ts +89 -1
  115. package/dist/infra/process/process-manager.js +293 -9
  116. package/dist/infra/process/task-queue-manager.d.ts +13 -0
  117. package/dist/infra/process/task-queue-manager.js +19 -0
  118. package/dist/infra/process/transport-handlers.d.ts +3 -0
  119. package/dist/infra/process/transport-handlers.js +82 -5
  120. package/dist/infra/process/transport-worker.js +9 -69
  121. package/dist/infra/repl/commands/connectors-command.d.ts +8 -0
  122. package/dist/infra/repl/commands/{gen-rules-command.js → connectors-command.js} +21 -10
  123. package/dist/infra/repl/commands/index.js +8 -4
  124. package/dist/infra/repl/commands/init-command.js +11 -7
  125. package/dist/infra/repl/commands/new-command.d.ts +14 -0
  126. package/dist/infra/repl/commands/new-command.js +61 -0
  127. package/dist/infra/repl/commands/query-command.js +22 -2
  128. package/dist/infra/repl/commands/{clear-command.d.ts → reset-command.d.ts} +2 -2
  129. package/dist/infra/repl/commands/{clear-command.js → reset-command.js} +11 -11
  130. package/dist/infra/transport/socket-io-transport-client.d.ts +68 -0
  131. package/dist/infra/transport/socket-io-transport-client.js +283 -7
  132. package/dist/infra/usecase/connectors-use-case.d.ts +59 -0
  133. package/dist/infra/usecase/connectors-use-case.js +203 -0
  134. package/dist/infra/usecase/init-use-case.d.ts +8 -43
  135. package/dist/infra/usecase/init-use-case.js +29 -253
  136. package/dist/infra/usecase/logout-use-case.js +2 -2
  137. package/dist/infra/usecase/pull-use-case.js +5 -5
  138. package/dist/infra/usecase/push-use-case.js +5 -5
  139. package/dist/infra/usecase/{clear-use-case.d.ts → reset-use-case.d.ts} +5 -5
  140. package/dist/infra/usecase/{clear-use-case.js → reset-use-case.js} +7 -8
  141. package/dist/infra/usecase/space-list-use-case.js +3 -3
  142. package/dist/infra/usecase/space-switch-use-case.js +3 -3
  143. package/dist/resources/prompts/curate.yml +75 -13
  144. package/dist/resources/prompts/explore.yml +34 -0
  145. package/dist/resources/prompts/query-orchestrator.yml +112 -0
  146. package/dist/resources/prompts/system-prompt.yml +12 -2
  147. package/dist/resources/tools/curate.txt +60 -15
  148. package/dist/resources/tools/search_knowledge.txt +32 -0
  149. package/dist/templates/sections/brv-instructions.md +98 -0
  150. package/dist/tui/components/inline-prompts/inline-confirm.js +2 -2
  151. package/dist/tui/components/onboarding/onboarding-flow.js +14 -10
  152. package/dist/tui/components/onboarding/welcome-box.js +1 -1
  153. package/dist/tui/contexts/onboarding-context.d.ts +4 -0
  154. package/dist/tui/contexts/onboarding-context.js +14 -2
  155. package/dist/tui/views/command-view.js +19 -0
  156. package/dist/utils/file-validator.d.ts +1 -1
  157. package/dist/utils/file-validator.js +34 -35
  158. package/dist/utils/type-guards.d.ts +5 -0
  159. package/dist/utils/type-guards.js +7 -0
  160. package/oclif.manifest.json +32 -6
  161. package/package.json +4 -1
  162. package/dist/config/context-tree-domains.d.ts +0 -29
  163. package/dist/config/context-tree-domains.js +0 -29
  164. package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +0 -3
  165. package/dist/infra/repl/commands/gen-rules-command.d.ts +0 -7
  166. package/dist/infra/rule/agent-rule-config.d.ts +0 -19
  167. package/dist/infra/usecase/generate-rules-use-case.d.ts +0 -61
  168. package/dist/infra/usecase/generate-rules-use-case.js +0 -285
  169. /package/dist/core/interfaces/{usecase/i-clear-use-case.js → connectors/connector-types.js} +0 -0
  170. /package/dist/core/interfaces/{usecase/i-generate-rules-use-case.js → connectors/i-connector-manager.js} +0 -0
  171. /package/dist/infra/{rule → connectors/shared}/constants.d.ts +0 -0
  172. /package/dist/infra/{rule → connectors/shared}/constants.js +0 -0
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Utilities for parsing and managing context relations.
3
- * Relations are expressed using @ notation: @domain/topic or @domain/topic/subtopic
3
+ * Relations are expressed using @ notation: @domain/topic/title.md or @domain/topic/subtopic/title.md
4
4
  */
5
5
  /**
6
- * Parse relations from context.md content.
7
- * Extracts all @domain/topic or @domain/topic/subtopic references.
6
+ * Parse relations from title.md content.
7
+ * Extracts all @domain/topic/title.md or @domain/topic/subtopic/title.md references.
8
8
  *
9
9
  * @param content - Markdown content to parse
10
10
  * @returns Array of unique relation paths (without @ prefix)
@@ -13,43 +13,27 @@
13
13
  * ```ts
14
14
  * const content = `
15
15
  * ## Relations
16
- * @code_style/error-handling
17
- * @structure/api-endpoints
16
+ * @code_style/error-handling/overview.md
17
+ * @structure/api/endpoints/rest.md
18
18
  * `
19
- * parseRelations(content) // ['code_style/error-handling', 'structure/api-endpoints']
19
+ * parseRelations(content) // ['code_style/error-handling/overview.md', 'structure/api/endpoints/rest.md']
20
20
  * ```
21
21
  */
22
22
  export declare function parseRelations(content: string): string[];
23
- /**
24
- * Validate a relation path format.
25
- * Valid formats: domain/topic or domain/topic/subtopic
26
- *
27
- * @param path - Relation path to validate (without @ prefix)
28
- * @returns True if path format is valid
29
- *
30
- * @example
31
- * ```ts
32
- * validateRelationPath('code_style/error-handling') // true
33
- * validateRelationPath('code_style/error-handling/try-catch') // true
34
- * validateRelationPath('invalid') // false
35
- * validateRelationPath('too/many/parts/here') // false
36
- * ```
37
- */
38
- export declare function validateRelationPath(path: string): boolean;
39
23
  /**
40
24
  * Resolve a relation path to an absolute file system path.
41
25
  *
42
26
  * @param basePath - Base path to context tree (e.g., '.brv/context-tree')
43
- * @param relation - Relation path (e.g., 'domain/topic' or 'domain/topic/subtopic')
44
- * @returns Absolute path to the context.md file
27
+ * @param relation - Relation path (e.g., 'domain/topic/title.md' or 'domain/topic/subtopic/title.md')
28
+ * @returns Absolute path to the title.md file
45
29
  *
46
30
  * @example
47
31
  * ```ts
48
- * resolveRelationPath('.brv/context-tree', 'code_style/error-handling')
49
- * // => '.brv/context-tree/code_style/error-handling/context.md'
32
+ * resolveRelationPath('.brv/context-tree', 'code_style/error-handling/overview.md')
33
+ * // => '.brv/context-tree/code_style/error-handling/overview.md'
50
34
  *
51
- * resolveRelationPath('.brv/context-tree', 'structure/api/endpoints')
52
- * // => '.brv/context-tree/structure/api/endpoints/context.md'
35
+ * resolveRelationPath('.brv/context-tree', 'structure/api/endpoints/rest.md')
36
+ * // => '.brv/context-tree/structure/api/endpoints/rest.md'
53
37
  * ```
54
38
  */
55
39
  export declare function resolveRelationPath(basePath: string, relation: string): string;
@@ -58,31 +42,33 @@ export declare function resolveRelationPath(basePath: string, relation: string):
58
42
  *
59
43
  * @param domain - Domain name
60
44
  * @param topic - Topic name
45
+ * @param title - Title (with .md extension)
61
46
  * @param subtopic - Optional subtopic name
62
47
  * @returns Formatted relation string with @ prefix
63
48
  *
64
49
  * @example
65
50
  * ```ts
66
- * formatRelation('code_style', 'error-handling')
67
- * // => '@code_style/error-handling'
51
+ * formatRelation('code_style', 'error-handling', 'overview.md')
52
+ * // => '@code_style/error-handling/overview.md'
68
53
  *
69
- * formatRelation('structure', 'api', 'endpoints')
70
- * // => '@structure/api/endpoints'
54
+ * formatRelation('structure', 'api', 'endpoints', 'rest.md')
55
+ * // => '@structure/api/endpoints/rest.md'
71
56
  * ```
72
57
  */
73
- export declare function formatRelation(domain: string, topic: string, subtopic?: string): string;
58
+ export declare function formatRelation(domain: string, topic: string, title: string, subtopic?: string): string;
74
59
  /**
75
60
  * Normalize a relation path by removing the @ prefix.
61
+ * Preserves file extensions (e.g., .md).
76
62
  *
77
63
  * @param relation - Relation path to normalize
78
- * @returns Normalized relation path
64
+ * @returns Normalized relation path without @ prefix (file extension preserved)
79
65
  *
80
66
  * @example
81
67
  * ```ts
82
- * normalizeRelation('code_style/error-handling') // 'code_style/error-handling'
83
- * normalizeRelation('@code_style/error-handling') // 'code_style/error-handling'
68
+ * normalizeRelation('code_style/error-handling.md') // 'code_style/error-handling.md'
69
+ * normalizeRelation('@code_style/error-handling.md') // 'code_style/error-handling.md'
84
70
  * normalizeRelation('code_style/error-handling/title.md') // 'code_style/error-handling/title.md'
85
- * normalizeRelation('@@@code_style/error-handling/title.md') // 'code_style/error-handling/title.md'
71
+ * normalizeRelation('code_style/error-handling/file.md') // 'code_style/error-handling/file.md'
86
72
  * ```
87
73
  */
88
74
  export declare function normalizeRelation(relation: string): string;
@@ -95,8 +81,8 @@ export declare function normalizeRelation(relation: string): string;
95
81
  *
96
82
  * @example
97
83
  * ```ts
98
- * generateRelationsSection(['code_style/error-handling', 'structure/api'])
99
- * // => '\n## Relations\n@code_style/error-handling\n@structure/api\n'
84
+ * generateRelationsSection(['code_style/error-handling/overview.md', 'structure/api/rest.md'])
85
+ * // => '\n## Relations\n@code_style/error-handling/overview.md\n@structure/api/rest.md\n'
100
86
  *
101
87
  * generateRelationsSection([])
102
88
  * // => ''
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * Utilities for parsing and managing context relations.
3
- * Relations are expressed using @ notation: @domain/topic or @domain/topic/subtopic
3
+ * Relations are expressed using @ notation: @domain/topic/title.md or @domain/topic/subtopic/title.md
4
4
  */
5
5
  /**
6
6
  * Regular expression to match relation paths in markdown content.
7
- * Matches: @domain/topic or @domain/topic/subtopic
7
+ * Matches: @domain/topic/title.md or @domain/topic/subtopic/title.md
8
8
  */
9
- const RELATION_PATTERN = /@([\w-]+)\/([\w-]+)(?:\/([\w-]+))?/g;
9
+ const RELATION_PATTERN = /@([\w-]+\/[\w-]+(?:\/[\w-]+)?\/[\w-]+(?:\.[\w]+)?)(?![\w/-])/g;
10
10
  /**
11
- * Parse relations from context.md content.
12
- * Extracts all @domain/topic or @domain/topic/subtopic references.
11
+ * Parse relations from title.md content.
12
+ * Extracts all @domain/topic/title.md or @domain/topic/subtopic/title.md references.
13
13
  *
14
14
  * @param content - Markdown content to parse
15
15
  * @returns Array of unique relation paths (without @ prefix)
@@ -18,104 +18,77 @@ const RELATION_PATTERN = /@([\w-]+)\/([\w-]+)(?:\/([\w-]+))?/g;
18
18
  * ```ts
19
19
  * const content = `
20
20
  * ## Relations
21
- * @code_style/error-handling
22
- * @structure/api-endpoints
21
+ * @code_style/error-handling/overview.md
22
+ * @structure/api/endpoints/rest.md
23
23
  * `
24
- * parseRelations(content) // ['code_style/error-handling', 'structure/api-endpoints']
24
+ * parseRelations(content) // ['code_style/error-handling/overview.md', 'structure/api/endpoints/rest.md']
25
25
  * ```
26
26
  */
27
27
  export function parseRelations(content) {
28
28
  const relations = new Set();
29
- // Extract all @domain/topic or @domain/topic/subtopic patterns
29
+ // Extract all @domain/topic/title.md or @domain/topic/subtopic/title.md patterns
30
30
  const matches = content.matchAll(RELATION_PATTERN);
31
31
  for (const match of matches) {
32
- const [, domain, topic, subtopic] = match;
33
- const relation = subtopic
34
- ? `${domain}/${topic}/${subtopic}`
35
- : `${domain}/${topic}`;
36
- relations.add(relation);
32
+ const [, fullPath] = match;
33
+ relations.add(fullPath.trim());
37
34
  }
38
35
  return [...relations];
39
36
  }
40
- /**
41
- * Validate a relation path format.
42
- * Valid formats: domain/topic or domain/topic/subtopic
43
- *
44
- * @param path - Relation path to validate (without @ prefix)
45
- * @returns True if path format is valid
46
- *
47
- * @example
48
- * ```ts
49
- * validateRelationPath('code_style/error-handling') // true
50
- * validateRelationPath('code_style/error-handling/try-catch') // true
51
- * validateRelationPath('invalid') // false
52
- * validateRelationPath('too/many/parts/here') // false
53
- * ```
54
- */
55
- export function validateRelationPath(path) {
56
- const parts = path.split('/');
57
- // Must have 2 or 3 parts: domain/topic or domain/topic/subtopic
58
- if (parts.length < 2 || parts.length > 3) {
59
- return false;
60
- }
61
- // Each part must be non-empty and contain only valid characters
62
- const validPartPattern = /^[\w-]+$/;
63
- return parts.every(part => validPartPattern.test(part));
64
- }
65
37
  /**
66
38
  * Resolve a relation path to an absolute file system path.
67
39
  *
68
40
  * @param basePath - Base path to context tree (e.g., '.brv/context-tree')
69
- * @param relation - Relation path (e.g., 'domain/topic' or 'domain/topic/subtopic')
70
- * @returns Absolute path to the context.md file
41
+ * @param relation - Relation path (e.g., 'domain/topic/title.md' or 'domain/topic/subtopic/title.md')
42
+ * @returns Absolute path to the title.md file
71
43
  *
72
44
  * @example
73
45
  * ```ts
74
- * resolveRelationPath('.brv/context-tree', 'code_style/error-handling')
75
- * // => '.brv/context-tree/code_style/error-handling/context.md'
46
+ * resolveRelationPath('.brv/context-tree', 'code_style/error-handling/overview.md')
47
+ * // => '.brv/context-tree/code_style/error-handling/overview.md'
76
48
  *
77
- * resolveRelationPath('.brv/context-tree', 'structure/api/endpoints')
78
- * // => '.brv/context-tree/structure/api/endpoints/context.md'
49
+ * resolveRelationPath('.brv/context-tree', 'structure/api/endpoints/rest.md')
50
+ * // => '.brv/context-tree/structure/api/endpoints/rest.md'
79
51
  * ```
80
52
  */
81
53
  export function resolveRelationPath(basePath, relation) {
82
- const parts = relation.split('/');
83
- return `${basePath}/${parts.join('/')}/context.md`;
54
+ return `${basePath}/${relation}`;
84
55
  }
85
56
  /**
86
57
  * Format a relation path using @ notation.
87
58
  *
88
59
  * @param domain - Domain name
89
60
  * @param topic - Topic name
61
+ * @param title - Title (with .md extension)
90
62
  * @param subtopic - Optional subtopic name
91
63
  * @returns Formatted relation string with @ prefix
92
64
  *
93
65
  * @example
94
66
  * ```ts
95
- * formatRelation('code_style', 'error-handling')
96
- * // => '@code_style/error-handling'
67
+ * formatRelation('code_style', 'error-handling', 'overview.md')
68
+ * // => '@code_style/error-handling/overview.md'
97
69
  *
98
- * formatRelation('structure', 'api', 'endpoints')
99
- * // => '@structure/api/endpoints'
70
+ * formatRelation('structure', 'api', 'endpoints', 'rest.md')
71
+ * // => '@structure/api/endpoints/rest.md'
100
72
  * ```
101
73
  */
102
- export function formatRelation(domain, topic, subtopic) {
74
+ export function formatRelation(domain, topic, title, subtopic) {
103
75
  return subtopic
104
- ? `@${domain}/${topic}/${subtopic}`
105
- : `@${domain}/${topic}`;
76
+ ? `@${domain}/${topic}/${subtopic}/${title}`
77
+ : `@${domain}/${topic}/${title}`;
106
78
  }
107
79
  /**
108
80
  * Normalize a relation path by removing the @ prefix.
81
+ * Preserves file extensions (e.g., .md).
109
82
  *
110
83
  * @param relation - Relation path to normalize
111
- * @returns Normalized relation path
84
+ * @returns Normalized relation path without @ prefix (file extension preserved)
112
85
  *
113
86
  * @example
114
87
  * ```ts
115
- * normalizeRelation('code_style/error-handling') // 'code_style/error-handling'
116
- * normalizeRelation('@code_style/error-handling') // 'code_style/error-handling'
88
+ * normalizeRelation('code_style/error-handling.md') // 'code_style/error-handling.md'
89
+ * normalizeRelation('@code_style/error-handling.md') // 'code_style/error-handling.md'
117
90
  * normalizeRelation('code_style/error-handling/title.md') // 'code_style/error-handling/title.md'
118
- * normalizeRelation('@@@code_style/error-handling/title.md') // 'code_style/error-handling/title.md'
91
+ * normalizeRelation('code_style/error-handling/file.md') // 'code_style/error-handling/file.md'
119
92
  * ```
120
93
  */
121
94
  export function normalizeRelation(relation) {
@@ -130,8 +103,8 @@ export function normalizeRelation(relation) {
130
103
  *
131
104
  * @example
132
105
  * ```ts
133
- * generateRelationsSection(['code_style/error-handling', 'structure/api'])
134
- * // => '\n## Relations\n@code_style/error-handling\n@structure/api\n'
106
+ * generateRelationsSection(['code_style/error-handling/overview.md', 'structure/api/rest.md'])
107
+ * // => '\n## Relations\n@code_style/error-handling/overview.md\n@structure/api/rest.md\n'
135
108
  *
136
109
  * generateRelationsSection([])
137
110
  * // => ''
@@ -142,7 +115,12 @@ export function generateRelationsSection(relations) {
142
115
  return '';
143
116
  }
144
117
  const formattedRelations = relations
145
- .map(rel => `@${normalizeRelation(rel)}`)
118
+ .map(rel => {
119
+ const normalized = normalizeRelation(rel);
120
+ // Ensure .md extension is present
121
+ const withExtension = normalized.endsWith('.md') ? normalized : `${normalized}.md`;
122
+ return `@${withExtension}`;
123
+ })
146
124
  .join('\n');
147
125
  return `\n## Relations\n${formattedRelations}\n`;
148
126
  }
@@ -429,6 +429,8 @@ export declare const TransportLlmEventList: readonly ["llmservice:thinking", "ll
429
429
  export declare const TransportAgentEventNames: {
430
430
  readonly CONNECTED: "agent:connected";
431
431
  readonly DISCONNECTED: "agent:disconnected";
432
+ readonly NEW_SESSION: "agent:newSession";
433
+ readonly NEW_SESSION_CREATED: "agent:newSessionCreated";
432
434
  readonly REGISTER: "agent:register";
433
435
  readonly RESTART: "agent:restart";
434
436
  readonly RESTARTED: "agent:restarted";
@@ -449,10 +451,10 @@ export declare const TransportSessionEventNames: {
449
451
  * Internal message, not exposed to external clients
450
452
  */
451
453
  export declare const TaskExecuteSchema: z.ZodObject<{
452
- /** Client ID that created the task (for response routing) */
453
- clientId: z.ZodString;
454
454
  /** Client's working directory for file validation */
455
455
  clientCwd: z.ZodOptional<z.ZodString>;
456
+ /** Client ID that created the task (for response routing) */
457
+ clientId: z.ZodString;
456
458
  /** Task content/prompt */
457
459
  content: z.ZodString;
458
460
  /** Optional file paths for curate --files */
@@ -1137,6 +1139,77 @@ export declare const AgentRestartResponseSchema: z.ZodObject<{
1137
1139
  success: boolean;
1138
1140
  error?: string | undefined;
1139
1141
  }>;
1142
+ /**
1143
+ * Request to create a new session (end current, start fresh).
1144
+ * Used by /new command to start a fresh conversation.
1145
+ */
1146
+ export declare const AgentNewSessionRequestSchema: z.ZodObject<{
1147
+ /** Optional reason for new session (for logging) */
1148
+ reason: z.ZodOptional<z.ZodString>;
1149
+ }, "strip", z.ZodTypeAny, {
1150
+ reason?: string | undefined;
1151
+ }, {
1152
+ reason?: string | undefined;
1153
+ }>;
1154
+ /**
1155
+ * Response after new session is created.
1156
+ */
1157
+ export declare const AgentNewSessionResponseSchema: z.ZodObject<{
1158
+ /** Error message if session creation failed */
1159
+ error: z.ZodOptional<z.ZodString>;
1160
+ /** The new session ID */
1161
+ sessionId: z.ZodOptional<z.ZodString>;
1162
+ /** Whether the new session was created successfully */
1163
+ success: z.ZodBoolean;
1164
+ }, "strip", z.ZodTypeAny, {
1165
+ success: boolean;
1166
+ error?: string | undefined;
1167
+ sessionId?: string | undefined;
1168
+ }, {
1169
+ success: boolean;
1170
+ error?: string | undefined;
1171
+ sessionId?: string | undefined;
1172
+ }>;
1173
+ /**
1174
+ * Agent status event names.
1175
+ */
1176
+ export declare const AgentStatusEventNames: {
1177
+ /** Status changed broadcast */
1178
+ readonly STATUS_CHANGED: "agent:status:changed";
1179
+ };
1180
+ /**
1181
+ * Agent health status for monitoring.
1182
+ * Used by Transport to check if CipherAgent is ready before forwarding tasks.
1183
+ */
1184
+ export declare const AgentStatusSchema: z.ZodObject<{
1185
+ /** Number of tasks currently processing */
1186
+ activeTasks: z.ZodNumber;
1187
+ /** Whether auth token is loaded and valid */
1188
+ hasAuth: z.ZodBoolean;
1189
+ /** Whether BrvConfig is loaded */
1190
+ hasConfig: z.ZodBoolean;
1191
+ /** Whether CipherAgent is initialized and ready */
1192
+ isInitialized: z.ZodBoolean;
1193
+ /** Last initialization error message */
1194
+ lastError: z.ZodOptional<z.ZodString>;
1195
+ /** Number of tasks waiting in queue */
1196
+ queuedTasks: z.ZodNumber;
1197
+ }, "strip", z.ZodTypeAny, {
1198
+ activeTasks: number;
1199
+ hasAuth: boolean;
1200
+ hasConfig: boolean;
1201
+ isInitialized: boolean;
1202
+ queuedTasks: number;
1203
+ lastError?: string | undefined;
1204
+ }, {
1205
+ activeTasks: number;
1206
+ hasAuth: boolean;
1207
+ hasConfig: boolean;
1208
+ isInitialized: boolean;
1209
+ queuedTasks: number;
1210
+ lastError?: string | undefined;
1211
+ }>;
1212
+ export type AgentStatus = z.infer<typeof AgentStatusSchema>;
1140
1213
  export type TodoItem = z.infer<typeof TodoItemSchema>;
1141
1214
  export type ChunkPayload = z.infer<typeof ChunkPayloadSchema>;
1142
1215
  export type ResponsePayload = z.infer<typeof ResponsePayloadSchema>;
@@ -1163,3 +1236,5 @@ export type SessionSwitchResponse = z.infer<typeof SessionSwitchResponseSchema>;
1163
1236
  export type SessionSwitchedBroadcast = z.infer<typeof SessionSwitchedBroadcastSchema>;
1164
1237
  export type AgentRestartRequest = z.infer<typeof AgentRestartRequestSchema>;
1165
1238
  export type AgentRestartResponse = z.infer<typeof AgentRestartResponseSchema>;
1239
+ export type AgentNewSessionRequest = z.infer<typeof AgentNewSessionRequestSchema>;
1240
+ export type AgentNewSessionResponse = z.infer<typeof AgentNewSessionResponseSchema>;
@@ -249,6 +249,8 @@ export const TransportLlmEventList = [
249
249
  export const TransportAgentEventNames = {
250
250
  CONNECTED: 'agent:connected',
251
251
  DISCONNECTED: 'agent:disconnected',
252
+ NEW_SESSION: 'agent:newSession',
253
+ NEW_SESSION_CREATED: 'agent:newSessionCreated',
252
254
  REGISTER: 'agent:register',
253
255
  RESTART: 'agent:restart',
254
256
  RESTARTED: 'agent:restarted',
@@ -272,10 +274,10 @@ export const TransportSessionEventNames = {
272
274
  * Internal message, not exposed to external clients
273
275
  */
274
276
  export const TaskExecuteSchema = z.object({
275
- /** Client ID that created the task (for response routing) */
276
- clientId: z.string(),
277
277
  /** Client's working directory for file validation */
278
278
  clientCwd: z.string().optional(),
279
+ /** Client ID that created the task (for response routing) */
280
+ clientId: z.string(),
279
281
  /** Task content/prompt */
280
282
  content: z.string(),
281
283
  /** Optional file paths for curate --files */
@@ -560,3 +562,50 @@ export const AgentRestartResponseSchema = z.object({
560
562
  /** Whether the restart was initiated successfully */
561
563
  success: z.boolean(),
562
564
  });
565
+ /**
566
+ * Request to create a new session (end current, start fresh).
567
+ * Used by /new command to start a fresh conversation.
568
+ */
569
+ export const AgentNewSessionRequestSchema = z.object({
570
+ /** Optional reason for new session (for logging) */
571
+ reason: z.string().optional(),
572
+ });
573
+ /**
574
+ * Response after new session is created.
575
+ */
576
+ export const AgentNewSessionResponseSchema = z.object({
577
+ /** Error message if session creation failed */
578
+ error: z.string().optional(),
579
+ /** The new session ID */
580
+ sessionId: z.string().optional(),
581
+ /** Whether the new session was created successfully */
582
+ success: z.boolean(),
583
+ });
584
+ // ============================================================================
585
+ // Agent Status (health check)
586
+ // ============================================================================
587
+ /**
588
+ * Agent status event names.
589
+ */
590
+ export const AgentStatusEventNames = {
591
+ /** Status changed broadcast */
592
+ STATUS_CHANGED: 'agent:status:changed',
593
+ };
594
+ /**
595
+ * Agent health status for monitoring.
596
+ * Used by Transport to check if CipherAgent is ready before forwarding tasks.
597
+ */
598
+ export const AgentStatusSchema = z.object({
599
+ /** Number of tasks currently processing */
600
+ activeTasks: z.number().int().nonnegative(),
601
+ /** Whether auth token is loaded and valid */
602
+ hasAuth: z.boolean(),
603
+ /** Whether BrvConfig is loaded */
604
+ hasConfig: z.boolean(),
605
+ /** Whether CipherAgent is initialized and ready */
606
+ isInitialized: z.boolean(),
607
+ /** Last initialization error message */
608
+ lastError: z.string().optional(),
609
+ /** Number of tasks waiting in queue */
610
+ queuedTasks: z.number().int().nonnegative(),
611
+ });
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Interface for Session Persistence Operations
3
+ *
4
+ * Defines the contract for session metadata storage and retrieval.
5
+ * Implementation uses JSON files in .brv/sessions/ directory.
6
+ */
7
+ import type { ActiveSessionPointer, SessionInfo, SessionMetadata } from '../../domain/cipher/session/session-metadata.js';
8
+ /**
9
+ * Session retention configuration for auto-cleanup.
10
+ */
11
+ export interface SessionRetentionConfig {
12
+ /** Maximum age in days before auto-cleanup */
13
+ maxAgeDays: number;
14
+ /** Maximum number of sessions to keep */
15
+ maxCount: number;
16
+ /** Whether to run cleanup on startup */
17
+ runOnStartup: boolean;
18
+ }
19
+ /**
20
+ * Result of session cleanup operation.
21
+ */
22
+ export interface SessionCleanupResult {
23
+ /** Number of corrupted session files removed */
24
+ corruptedRemoved: number;
25
+ /** Number of sessions deleted due to age */
26
+ deletedByAge: number;
27
+ /** Number of sessions deleted due to count limit */
28
+ deletedByCount: number;
29
+ /** Total sessions remaining after cleanup */
30
+ remaining: number;
31
+ }
32
+ /**
33
+ * Interface for session metadata persistence.
34
+ *
35
+ * Manages session metadata stored in .brv/sessions/ directory:
36
+ * - active.json: Current active session pointer
37
+ * - session-*.json: Individual session metadata files
38
+ */
39
+ export interface ISessionPersistence {
40
+ /**
41
+ * Clean up expired sessions based on retention policy.
42
+ *
43
+ * @param config - Retention configuration
44
+ * @returns Cleanup result with counts
45
+ */
46
+ cleanupSessions(config: SessionRetentionConfig): Promise<SessionCleanupResult>;
47
+ /**
48
+ * Clear the active session pointer.
49
+ * Removes .brv/sessions/active.json
50
+ */
51
+ clearActiveSession(): Promise<void>;
52
+ /**
53
+ * Delete a session and its metadata.
54
+ *
55
+ * @param sessionId - Session ID to delete
56
+ * @returns True if session was deleted, false if not found
57
+ */
58
+ deleteSession(sessionId: string): Promise<boolean>;
59
+ /**
60
+ * Get the currently active session pointer.
61
+ *
62
+ * @returns Active session pointer or null if no active session
63
+ */
64
+ getActiveSession(): Promise<ActiveSessionPointer | null>;
65
+ /**
66
+ * Get session metadata by ID.
67
+ *
68
+ * @param sessionId - Session ID to look up
69
+ * @returns Session metadata or null if not found
70
+ */
71
+ getSession(sessionId: string): Promise<null | SessionMetadata>;
72
+ /**
73
+ * Check if the active session pointer is stale (process not running).
74
+ *
75
+ * @returns True if active session exists but process is not running
76
+ */
77
+ isActiveSessionStale(): Promise<boolean>;
78
+ /**
79
+ * Validate that a session belongs to the current working directory.
80
+ *
81
+ * @param sessionId - Session ID to validate
82
+ * @returns True if session belongs to current project
83
+ */
84
+ isSessionForCurrentProject(sessionId: string): Promise<boolean>;
85
+ /**
86
+ * List all session metadata files.
87
+ *
88
+ * @returns Array of session info sorted by lastUpdated (newest first)
89
+ */
90
+ listSessions(): Promise<SessionInfo[]>;
91
+ /**
92
+ * Mark a session as ended.
93
+ * Updates the session status to 'ended' and lastUpdated timestamp.
94
+ *
95
+ * @param sessionId - Session ID to mark as ended
96
+ */
97
+ markSessionEnded(sessionId: string): Promise<void>;
98
+ /**
99
+ * Mark a session as interrupted (e.g., process crashed).
100
+ * Updates the session status to 'interrupted'.
101
+ *
102
+ * @param sessionId - Session ID to mark as interrupted
103
+ */
104
+ markSessionInterrupted(sessionId: string): Promise<void>;
105
+ /**
106
+ * Save session metadata to disk.
107
+ * Creates or updates the session metadata file.
108
+ *
109
+ * @param metadata - Session metadata to save
110
+ */
111
+ saveSession(metadata: SessionMetadata): Promise<void>;
112
+ /**
113
+ * Set the active session pointer.
114
+ * Creates or updates .brv/sessions/active.json
115
+ *
116
+ * @param sessionId - Session ID to set as active
117
+ */
118
+ setActiveSession(sessionId: string): Promise<void>;
119
+ /**
120
+ * Set session title from first user message.
121
+ *
122
+ * @param sessionId - Session ID to update
123
+ * @param title - Session title
124
+ */
125
+ setSessionTitle(sessionId: string, title: string): Promise<void>;
126
+ /**
127
+ * Update session activity (lastUpdated timestamp and message count).
128
+ *
129
+ * @param sessionId - Session ID to update
130
+ * @param messageCount - Current message count
131
+ */
132
+ updateSessionActivity(sessionId: string, messageCount: number): Promise<void>;
133
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Interface for Session Persistence Operations
3
+ *
4
+ * Defines the contract for session metadata storage and retrieval.
5
+ * Implementation uses JSON files in .brv/sessions/ directory.
6
+ */
7
+ export {};
@@ -302,6 +302,12 @@ export interface ToolCall {
302
302
  * Unique identifier for this tool call
303
303
  */
304
304
  id: string;
305
+ /**
306
+ * Thought signature for Gemini 3+ models.
307
+ * Required by Gemini 3 preview models to validate function calls.
308
+ * Uses 'skip_thought_signature_validator' as synthetic signature.
309
+ */
310
+ thoughtSignature?: string;
305
311
  /**
306
312
  * The type of tool call (currently only 'function' is supported)
307
313
  */