1- import {
2- DEFAULT_NEIGHBORHOOD_LIMIT ,
3- DEFAULT_SEARCH_LIMIT ,
4- handleError ,
5- normalizeSort ,
6- parseCsvList ,
7- parseDate ,
8- } from '../shared/utils' ;
1+ import { DEFAULT_NEIGHBORHOOD_LIMIT , handleError } from '../shared/utils' ;
92import { printExplore , selectNode } from '../shared/explore' ;
103import { getVersion } from './version' ;
114import { COMMAND_TLDR , emitTldrAndExit } from '../tldr' ;
@@ -15,136 +8,84 @@ type ClercModule = typeof import('clerc');
158export function createExploreCommand ( clerc : ClercModule ) {
169 return clerc . defineCommand (
1710 {
18- name : 'explore' ,
19- description : 'Search for a note and inspect its graph neighborhood' ,
20- parameters : [ '[term]' ] ,
21- flags : {
22- id : {
23- type : String ,
24- description : 'Node id to focus on' ,
25- } ,
26- title : {
27- type : String ,
28- description : 'Node title to match (case-insensitive)' ,
29- } ,
30- select : {
31- type : Number ,
32- description : '1-based index of the match to explore' ,
33- } ,
34- searchLimit : {
35- type : Number ,
36- description : 'Maximum matches to consider' ,
37- } ,
38- tag : {
39- type : String ,
40- description : 'Filter by notes containing all tags (comma-separated)' ,
41- } ,
42- anyTag : {
43- type : String ,
44- description : 'Filter by notes containing any of the tags (comma-separated)' ,
45- } ,
46- since : {
47- type : String ,
48- description : 'Only include notes updated on/after this date (YYYY-MM-DD or ISO)' ,
49- } ,
50- before : {
51- type : String ,
52- description : 'Only include notes updated before this date (YYYY-MM-DD or ISO)' ,
53- } ,
54- until : {
55- type : String ,
56- description : 'Alias of --before' ,
57- } ,
58- sort : {
59- type : String ,
60- description : 'Sort matches: score|recent|degree' ,
61- } ,
62- depth : {
63- type : Number ,
64- alias : 'd' ,
65- description : 'Neighborhood depth' ,
66- default : 1 ,
67- } ,
68- limit : {
69- type : Number ,
70- alias : 'l' ,
71- description : 'Maximum number of nodes in neighborhood' ,
72- } ,
73- includeSuggestions : {
74- type : Boolean ,
75- description : 'Include suggested edges in the neighborhood output' ,
76- } ,
77- longIds : {
78- type : Boolean ,
79- description : 'Display full ids in human-readable output' ,
80- } ,
81- json : {
82- type : Boolean ,
83- description : 'Emit JSON instead of text output' ,
84- } ,
85- interactive : {
86- type : Boolean ,
87- description : 'Prompt to choose a match' ,
88- } ,
89- showChunks : {
90- type : Boolean ,
91- description : 'Include document chunks in results (default: false)' ,
92- } ,
93- tldr : {
94- type : String ,
95- description : 'Output command metadata for agent consumption (--tldr or --tldr=json)' ,
11+ name : 'explore' ,
12+ description : 'Inspect a node\'s graph neighborhood and related suggestions' ,
13+ parameters : [ '[id]' ] ,
14+ flags : {
15+ id : {
16+ type : String ,
17+ description : 'Node id or short id to focus on (can also be positional)' ,
18+ } ,
19+ title : {
20+ type : String ,
21+ description : 'Exact node title to focus on' ,
22+ } ,
23+ depth : {
24+ type : Number ,
25+ alias : 'd' ,
26+ description : 'Neighborhood depth' ,
27+ default : 1 ,
28+ } ,
29+ limit : {
30+ type : Number ,
31+ alias : 'l' ,
32+ description : 'Maximum number of nodes in neighborhood' ,
33+ } ,
34+ includeSuggestions : {
35+ type : Boolean ,
36+ description : 'Include suggested edges in the neighborhood output' ,
37+ } ,
38+ longIds : {
39+ type : Boolean ,
40+ description : 'Display full ids in human-readable output' ,
41+ } ,
42+ json : {
43+ type : Boolean ,
44+ description : 'Emit JSON instead of text output' ,
45+ } ,
46+ tldr : {
47+ type : String ,
48+ description : 'Output command metadata for agent consumption (--tldr or --tldr=json)' ,
49+ } ,
9650 } ,
9751 } ,
98- } ,
9952 async ( { flags, parameters } ) => {
10053 try {
10154 // Handle TLDR request first
10255 if ( flags . tldr !== undefined ) {
103- const jsonMode = flags . tldr === 'json' ;
10456 emitTldrAndExit ( COMMAND_TLDR . explore , getVersion ( ) ) ;
10557 }
58+
10659 const limitFlag =
10760 typeof flags . limit === 'number' && ! Number . isNaN ( flags . limit ) ? flags . limit : undefined ;
10861 const neighborhoodLimit = limitFlag ?? DEFAULT_NEIGHBORHOOD_LIMIT ;
109- const searchLimit =
110- typeof flags . searchLimit === 'number' && ! Number . isNaN ( flags . searchLimit )
111- ? flags . searchLimit
112- : limitFlag ?? DEFAULT_SEARCH_LIMIT ;
11362
114- const termValue = parameters . term ;
63+ const positionalId = parameters . id as string | undefined ;
64+ const id = flags . id ?? positionalId ;
65+ const title = flags . title ;
66+
67+ if ( ! id && ! title ) {
68+ console . error ( '✖ Provide a node id (or short id) or an exact title to explore.' ) ;
69+ process . exitCode = 1 ;
70+ return ;
71+ }
11572
11673 const selection = await selectNode ( {
117- id : flags . id ,
118- title : flags . title ,
119- term : termValue ,
120- limit : searchLimit ,
121- select : typeof flags . select === 'number' ? flags . select : undefined ,
122- interactive : Boolean ( flags . interactive ) ,
123- tagsAll : parseCsvList ( flags . tag ) ,
124- tagsAny : parseCsvList ( flags . anyTag ) ,
125- since : parseDate ( flags . since ) ,
126- until : parseDate ( flags . before ?? flags . until ) ,
127- sort : normalizeSort ( flags . sort ) ,
128- showChunks : Boolean ( flags . showChunks ) ,
74+ id : id ,
75+ title : title ,
76+ limit : 1 ,
12977 } ) ;
13078
131- const hasSearchTerm = typeof termValue === 'string' && termValue . trim ( ) . length > 0 ;
132- const focusSelected =
133- Boolean ( flags . id ) ||
134- Boolean ( flags . title ) ||
135- typeof flags . select === 'number' ||
136- hasSearchTerm ;
137-
13879 await printExplore ( {
13980 selection,
14081 limit : neighborhoodLimit ,
141- matchLimit : searchLimit ,
82+ matchLimit : selection . limit ,
14283 depth : typeof flags . depth === 'number' && ! Number . isNaN ( flags . depth ) ? flags . depth : 1 ,
14384 includeSuggestions : Boolean ( flags . includeSuggestions ) ,
14485 longIds : Boolean ( flags . longIds ) ,
14586 json : Boolean ( flags . json ) ,
14687 showMatches : ! Boolean ( flags . json ) ,
147- focusSelected : focusSelected || Boolean ( flags . json ) ,
88+ focusSelected : true ,
14889 } ) ;
14990 } catch ( error ) {
15091 handleError ( error ) ;
0 commit comments