Skip to content

Commit 7902c2f

Browse files
committed
Clarify CLI search and explore roles
1 parent 0424766 commit 7902c2f

3 files changed

Lines changed: 391 additions & 160 deletions

File tree

src/cli/commands/explore.ts

Lines changed: 55 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
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';
92
import { printExplore, selectNode } from '../shared/explore';
103
import { getVersion } from './version';
114
import { COMMAND_TLDR, emitTldrAndExit } from '../tldr';
@@ -15,136 +8,84 @@ type ClercModule = typeof import('clerc');
158
export 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

Comments
 (0)