@doist/twist-cli 2.1.0 → 2.3.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/README.md +20 -8
- package/dist/__tests__/completion.test.d.ts +2 -0
- package/dist/__tests__/completion.test.d.ts.map +1 -0
- package/dist/__tests__/completion.test.js +106 -0
- package/dist/__tests__/completion.test.js.map +1 -0
- package/dist/__tests__/lib/refs.test.js +30 -1
- package/dist/__tests__/lib/refs.test.js.map +1 -1
- package/dist/__tests__/react.test.d.ts +2 -0
- package/dist/__tests__/react.test.d.ts.map +1 -0
- package/dist/__tests__/react.test.js +59 -0
- package/dist/__tests__/react.test.js.map +1 -0
- package/dist/__tests__/search.test.js +50 -7
- package/dist/__tests__/search.test.js.map +1 -1
- package/dist/__tests__/thread.test.js +21 -0
- package/dist/__tests__/thread.test.js.map +1 -1
- package/dist/commands/channel.d.ts.map +1 -1
- package/dist/commands/channel.js.map +1 -1
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +121 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/conversation.d.ts.map +1 -1
- package/dist/commands/conversation.js.map +1 -1
- package/dist/commands/inbox.d.ts.map +1 -1
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/msg.d.ts.map +1 -1
- package/dist/commands/msg.js.map +1 -1
- package/dist/commands/react.d.ts.map +1 -1
- package/dist/commands/react.js +10 -8
- package/dist/commands/react.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +25 -10
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/thread.d.ts.map +1 -1
- package/dist/commands/thread.js +16 -6
- package/dist/commands/thread.js.map +1 -1
- package/dist/commands/user.d.ts.map +1 -1
- package/dist/commands/user.js.map +1 -1
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js.map +1 -1
- package/dist/index.js +83 -65
- package/dist/index.js.map +1 -1
- package/dist/lib/completion.d.ts +31 -0
- package/dist/lib/completion.d.ts.map +1 -0
- package/dist/lib/completion.js +173 -0
- package/dist/lib/completion.js.map +1 -0
- package/dist/lib/options.d.ts +15 -0
- package/dist/lib/options.d.ts.map +1 -0
- package/dist/lib/options.js +2 -0
- package/dist/lib/options.js.map +1 -0
- package/dist/lib/refs.d.ts +2 -0
- package/dist/lib/refs.d.ts.map +1 -1
- package/dist/lib/refs.js +36 -17
- package/dist/lib/refs.js.map +1 -1
- package/dist/lib/skills/content.d.ts +2 -2
- package/dist/lib/skills/content.d.ts.map +1 -1
- package/dist/lib/skills/content.js +19 -8
- package/dist/lib/skills/content.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,8 +4,6 @@ A command-line interface for Twist.
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
> **Note**: This package is not yet published to npm. Once published, install with:
|
|
8
|
-
>
|
|
9
7
|
> ```bash
|
|
10
8
|
> npm install -g @doist/twist-cli
|
|
11
9
|
> ```
|
|
@@ -33,23 +31,37 @@ tw auth login
|
|
|
33
31
|
## Usage
|
|
34
32
|
|
|
35
33
|
```bash
|
|
36
|
-
tw workspaces # list all workspaces
|
|
37
34
|
tw inbox # inbox threads
|
|
38
35
|
tw inbox --unread # unread threads only
|
|
39
|
-
tw thread view <
|
|
36
|
+
tw thread view <ref> # view thread with comments
|
|
40
37
|
tw thread view <ref> --comment 123 # view a specific comment
|
|
41
|
-
tw thread reply <
|
|
42
|
-
tw conversation unread
|
|
38
|
+
tw thread reply <ref> # reply to a thread
|
|
39
|
+
tw conversation unread # list unread conversations
|
|
43
40
|
tw conversation view <ref> # view conversation messages
|
|
44
|
-
tw msg view <
|
|
41
|
+
tw msg view <ref> # view a conversation message
|
|
45
42
|
tw search "keyword" # search across workspace
|
|
46
|
-
tw react thread <ref> 👍
|
|
43
|
+
tw react thread <ref> 👍 # add reaction
|
|
47
44
|
```
|
|
48
45
|
|
|
49
46
|
References accept IDs (`123` or `id:123`), Twist URLs, or fuzzy names (for workspaces/users).
|
|
50
47
|
|
|
51
48
|
Run `tw --help` or `tw <command> --help` for more options.
|
|
52
49
|
|
|
50
|
+
## Shell Completions
|
|
51
|
+
|
|
52
|
+
Tab completion is available for bash, zsh, and fish:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
tw completion install # prompts for shell
|
|
56
|
+
tw completion install bash # or: zsh, fish
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Restart your shell or source your config file to activate. To remove:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
tw completion uninstall
|
|
63
|
+
```
|
|
64
|
+
|
|
53
65
|
### Machine-readable output
|
|
54
66
|
|
|
55
67
|
All list/view commands support `--json` and `--ndjson` flags for scripting:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/completion.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Command, Option } from 'commander';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { getCompletions, parseCompLine, withCaseInsensitiveChoices, withUnvalidatedChoices, } from '../lib/completion.js';
|
|
4
|
+
function createTestProgram() {
|
|
5
|
+
const program = new Command();
|
|
6
|
+
program.name('tw');
|
|
7
|
+
const thread = program.command('thread').description('Thread operations');
|
|
8
|
+
thread.command('view').description('View thread').option('--json', 'Output as JSON');
|
|
9
|
+
thread
|
|
10
|
+
.command('reply')
|
|
11
|
+
.description('Reply in thread')
|
|
12
|
+
.addOption(withUnvalidatedChoices(new Option('--notify <recipients>', 'Notification targets'), [
|
|
13
|
+
'EVERYONE',
|
|
14
|
+
'EVERYONE_IN_THREAD',
|
|
15
|
+
]));
|
|
16
|
+
program
|
|
17
|
+
.command('search')
|
|
18
|
+
.description('Search content')
|
|
19
|
+
.addOption(withCaseInsensitiveChoices(new Option('--type <type>', 'Search type'), [
|
|
20
|
+
'threads',
|
|
21
|
+
'messages',
|
|
22
|
+
'all',
|
|
23
|
+
]))
|
|
24
|
+
.option('--json', 'Output as JSON');
|
|
25
|
+
// Hidden command (like completion-server)
|
|
26
|
+
program.command('hidden-cmd', { hidden: true }).description('Internal command');
|
|
27
|
+
return program;
|
|
28
|
+
}
|
|
29
|
+
function names(items) {
|
|
30
|
+
return items.map((i) => i.name);
|
|
31
|
+
}
|
|
32
|
+
describe('getCompletions', () => {
|
|
33
|
+
it('returns visible top-level commands', () => {
|
|
34
|
+
const program = createTestProgram();
|
|
35
|
+
const result = getCompletions(program, [''], '');
|
|
36
|
+
expect(names(result)).toContain('thread');
|
|
37
|
+
expect(names(result)).toContain('search');
|
|
38
|
+
expect(names(result)).not.toContain('hidden-cmd');
|
|
39
|
+
});
|
|
40
|
+
it('returns subcommands inside a command', () => {
|
|
41
|
+
const program = createTestProgram();
|
|
42
|
+
const result = getCompletions(program, ['thread', ''], '');
|
|
43
|
+
const resultNames = names(result);
|
|
44
|
+
expect(resultNames).toContain('view');
|
|
45
|
+
expect(resultNames).toContain('reply');
|
|
46
|
+
});
|
|
47
|
+
it('returns options when current word starts with -', () => {
|
|
48
|
+
const program = createTestProgram();
|
|
49
|
+
const result = getCompletions(program, ['search', '--'], '--');
|
|
50
|
+
const resultNames = names(result);
|
|
51
|
+
expect(resultNames).toContain('--type');
|
|
52
|
+
expect(resultNames).toContain('--json');
|
|
53
|
+
});
|
|
54
|
+
it('suggests option values from argChoices', () => {
|
|
55
|
+
const program = createTestProgram();
|
|
56
|
+
const result = getCompletions(program, ['search', '--type', ''], '');
|
|
57
|
+
expect(names(result)).toEqual(['threads', 'messages', 'all']);
|
|
58
|
+
});
|
|
59
|
+
it('supports --flag=value completion', () => {
|
|
60
|
+
const program = createTestProgram();
|
|
61
|
+
const result = getCompletions(program, ['search', '--type='], '--type=');
|
|
62
|
+
expect(names(result)).toEqual(['--type=threads', '--type=messages', '--type=all']);
|
|
63
|
+
});
|
|
64
|
+
it('supports unvalidated choices for options with extra accepted formats', () => {
|
|
65
|
+
const program = createTestProgram();
|
|
66
|
+
const result = getCompletions(program, ['thread', 'reply', '--notify', ''], '');
|
|
67
|
+
expect(names(result)).toEqual(['EVERYONE', 'EVERYONE_IN_THREAD']);
|
|
68
|
+
});
|
|
69
|
+
it('stops offering options after --', () => {
|
|
70
|
+
const program = createTestProgram();
|
|
71
|
+
const result = getCompletions(program, ['search', '--', '--ty'], '--ty');
|
|
72
|
+
expect(result).toEqual([]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('parseCompLine quoted argument limitation', () => {
|
|
76
|
+
it('splits quoted multi-word arguments into separate tokens', () => {
|
|
77
|
+
const result = parseCompLine('tw thread reply "hello world"');
|
|
78
|
+
expect(result).toEqual(['thread', 'reply', '"hello', 'world"']);
|
|
79
|
+
});
|
|
80
|
+
it('strips completion-server token', () => {
|
|
81
|
+
const result = parseCompLine('tw completion-server thread rep');
|
|
82
|
+
expect(result).toEqual(['thread', 'rep']);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
// These tests verify assumptions we make about Commander internals.
|
|
86
|
+
describe('Commander internal assumptions', () => {
|
|
87
|
+
it('choices() sets parseArg on the option', () => {
|
|
88
|
+
const opt = new Option('--color <c>', 'Pick a color');
|
|
89
|
+
expect(opt.parseArg).toBeUndefined();
|
|
90
|
+
opt.choices(['red', 'blue']);
|
|
91
|
+
expect(opt.parseArg).toBeTypeOf('function');
|
|
92
|
+
});
|
|
93
|
+
it('argChoices set directly is readable by option consumers', () => {
|
|
94
|
+
const opt = new Option('--role <r>', 'Role');
|
|
95
|
+
opt.argChoices = ['ADMIN', 'MEMBER'];
|
|
96
|
+
expect(opt.argChoices).toEqual(['ADMIN', 'MEMBER']);
|
|
97
|
+
});
|
|
98
|
+
it('{ hidden: true } sets _hidden on the command', () => {
|
|
99
|
+
const program = new Command();
|
|
100
|
+
const visible = program.command('visible');
|
|
101
|
+
const hidden = program.command('secret', { hidden: true });
|
|
102
|
+
expect(visible._hidden).toBe(false);
|
|
103
|
+
expect(hidden._hidden).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=completion.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.test.js","sourceRoot":"","sources":["../../src/__tests__/completion.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { classifyTwistUrl, extractId, isIdRef, parseRef, parseTwistUrl, resolveCommentId, resolveConversationId, resolveMessageId, resolveThreadId, } from '../../lib/refs.js';
|
|
2
|
+
import { classifyTwistUrl, extractId, isIdRef, looksLikeRawId, parseRef, parseTwistUrl, resolveChannelId, resolveCommentId, resolveConversationId, resolveMessageId, resolveThreadId, } from '../../lib/refs.js';
|
|
3
3
|
describe('isIdRef', () => {
|
|
4
4
|
it('returns true for id: prefixed strings', () => {
|
|
5
5
|
expect(isIdRef('id:123')).toBe(true);
|
|
@@ -19,9 +19,26 @@ describe('extractId', () => {
|
|
|
19
19
|
it('parses bare numbers', () => {
|
|
20
20
|
expect(extractId('123')).toBe(123);
|
|
21
21
|
});
|
|
22
|
+
it('accepts whitespace around IDs', () => {
|
|
23
|
+
expect(extractId(' 123 ')).toBe(123);
|
|
24
|
+
expect(extractId('id: 456')).toBe(456);
|
|
25
|
+
});
|
|
22
26
|
it('throws on invalid input', () => {
|
|
23
27
|
expect(() => extractId('invalid')).toThrow('Invalid ID');
|
|
24
28
|
expect(() => extractId('id:abc')).toThrow('Invalid ID');
|
|
29
|
+
expect(() => extractId('id:123abc')).toThrow('Invalid ID');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('looksLikeRawId', () => {
|
|
33
|
+
it('detects numeric strings', () => {
|
|
34
|
+
expect(looksLikeRawId('123456')).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it('detects alphanumeric strings', () => {
|
|
37
|
+
expect(looksLikeRawId('abc123')).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it('rejects plain names and spaces', () => {
|
|
40
|
+
expect(looksLikeRawId('workspace')).toBe(false);
|
|
41
|
+
expect(looksLikeRawId('workspace one')).toBe(false);
|
|
25
42
|
});
|
|
26
43
|
});
|
|
27
44
|
describe('parseTwistUrl', () => {
|
|
@@ -79,6 +96,10 @@ describe('parseRef', () => {
|
|
|
79
96
|
it('parses names', () => {
|
|
80
97
|
expect(parseRef('My Workspace')).toEqual({ type: 'name', name: 'My Workspace' });
|
|
81
98
|
});
|
|
99
|
+
it('trims surrounding whitespace', () => {
|
|
100
|
+
expect(parseRef(' 456 ')).toEqual({ type: 'id', id: 456 });
|
|
101
|
+
expect(parseRef(' My Workspace ')).toEqual({ type: 'name', name: 'My Workspace' });
|
|
102
|
+
});
|
|
82
103
|
});
|
|
83
104
|
describe('resolveThreadId', () => {
|
|
84
105
|
it('resolves id: refs', () => {
|
|
@@ -105,6 +126,14 @@ describe('resolveCommentId', () => {
|
|
|
105
126
|
expect(resolveCommentId('https://twist.com/a/12345/ch/67890/t/111/c/222')).toBe(222);
|
|
106
127
|
});
|
|
107
128
|
});
|
|
129
|
+
describe('resolveChannelId', () => {
|
|
130
|
+
it('resolves id: refs', () => {
|
|
131
|
+
expect(resolveChannelId('id:67890')).toBe(67890);
|
|
132
|
+
});
|
|
133
|
+
it('resolves channel URLs', () => {
|
|
134
|
+
expect(resolveChannelId('https://twist.com/a/12345/ch/67890')).toBe(67890);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
108
137
|
describe('resolveConversationId', () => {
|
|
109
138
|
it('resolves id: refs', () => {
|
|
110
139
|
expect(resolveConversationId('id:333')).toBe(333);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refs.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/refs.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EACH,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,GAClB,MAAM,mBAAmB,CAAA;AAE1B,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7C,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC3B,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QACxD,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"refs.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/refs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/react.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
const apiMocks = vi.hoisted(() => ({
|
|
4
|
+
getTwistClient: vi.fn(),
|
|
5
|
+
addReaction: vi.fn(),
|
|
6
|
+
removeReaction: vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
vi.mock('../lib/api.js', () => ({
|
|
9
|
+
getTwistClient: apiMocks.getTwistClient,
|
|
10
|
+
}));
|
|
11
|
+
import { registerReactCommand } from '../commands/react.js';
|
|
12
|
+
function createProgram() {
|
|
13
|
+
const program = new Command();
|
|
14
|
+
program.exitOverride();
|
|
15
|
+
registerReactCommand(program);
|
|
16
|
+
return program;
|
|
17
|
+
}
|
|
18
|
+
describe('react refs', () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
apiMocks.addReaction.mockResolvedValue(undefined);
|
|
22
|
+
apiMocks.removeReaction.mockResolvedValue(undefined);
|
|
23
|
+
apiMocks.getTwistClient.mockResolvedValue({
|
|
24
|
+
reactions: {
|
|
25
|
+
add: apiMocks.addReaction,
|
|
26
|
+
remove: apiMocks.removeReaction,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
it('accepts thread URLs for react', async () => {
|
|
31
|
+
const program = createProgram();
|
|
32
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
33
|
+
await program.parseAsync([
|
|
34
|
+
'node',
|
|
35
|
+
'tw',
|
|
36
|
+
'react',
|
|
37
|
+
'thread',
|
|
38
|
+
'https://twist.com/a/1/ch/2/t/99',
|
|
39
|
+
'+1',
|
|
40
|
+
]);
|
|
41
|
+
expect(apiMocks.addReaction).toHaveBeenCalledWith({ threadId: 99, reaction: '👍' });
|
|
42
|
+
logSpy.mockRestore();
|
|
43
|
+
});
|
|
44
|
+
it('accepts message URLs for unreact', async () => {
|
|
45
|
+
const program = createProgram();
|
|
46
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
47
|
+
await program.parseAsync([
|
|
48
|
+
'node',
|
|
49
|
+
'tw',
|
|
50
|
+
'unreact',
|
|
51
|
+
'message',
|
|
52
|
+
'https://twist.com/a/1/msg/33/m/44',
|
|
53
|
+
'heart',
|
|
54
|
+
]);
|
|
55
|
+
expect(apiMocks.removeReaction).toHaveBeenCalledWith({ messageId: 44, reaction: '❤️' });
|
|
56
|
+
logSpy.mockRestore();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=react.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.test.js","sourceRoot":"","sources":["../../src/__tests__/react.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7D,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/B,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE;IACvB,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE;IACpB,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE;CAC1B,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,cAAc,EAAE,QAAQ,CAAC,cAAc;CAC1C,CAAC,CAAC,CAAA;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAE3D,SAAS,aAAa;IAClB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;IAC7B,OAAO,CAAC,YAAY,EAAE,CAAA;IACtB,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC7B,OAAO,OAAO,CAAA;AAClB,CAAC;AAED,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IACxB,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAA;QAClB,QAAQ,CAAC,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;QACjD,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;QACpD,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC;YACtC,SAAS,EAAE;gBACP,GAAG,EAAE,QAAQ,CAAC,WAAW;gBACzB,MAAM,EAAE,QAAQ,CAAC,cAAc;aAClC;SACJ,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;QAC/B,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAEpE,MAAM,OAAO,CAAC,UAAU,CAAC;YACrB,MAAM;YACN,IAAI;YACJ,OAAO;YACP,QAAQ;YACR,iCAAiC;YACjC,IAAI;SACP,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QACnF,MAAM,CAAC,WAAW,EAAE,CAAA;IACxB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;QAC/B,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAEpE,MAAM,OAAO,CAAC,UAAU,CAAC;YACrB,MAAM;YACN,IAAI;YACJ,SAAS;YACT,SAAS;YACT,mCAAmC;YACnC,OAAO;SACV,CAAC,CAAA;QAEF,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QACvF,MAAM,CAAC,WAAW,EAAE,CAAA;IACxB,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
vi.
|
|
4
|
-
getCurrentWorkspaceId: vi.fn().mockResolvedValue(1),
|
|
5
|
-
}));
|
|
6
|
-
vi.mock('../lib/refs.js', () => ({
|
|
3
|
+
const refsMocks = vi.hoisted(() => ({
|
|
7
4
|
resolveWorkspaceRef: vi.fn(),
|
|
8
5
|
resolveUserRefs: vi.fn(),
|
|
6
|
+
resolveChannelId: vi.fn(),
|
|
7
|
+
resolveConversationId: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
const searchApiMocks = vi.hoisted(() => ({
|
|
10
|
+
extendedSearch: vi.fn(),
|
|
11
|
+
}));
|
|
12
|
+
vi.mock('../lib/api.js', () => ({
|
|
13
|
+
getCurrentWorkspaceId: vi.fn().mockResolvedValue(1),
|
|
9
14
|
}));
|
|
15
|
+
vi.mock('../lib/refs.js', () => refsMocks);
|
|
10
16
|
vi.mock('../lib/public-channels.js', () => ({
|
|
11
17
|
includePrivateChannels: vi.fn().mockReturnValue(true),
|
|
12
18
|
getPublicChannelIds: vi.fn(),
|
|
13
19
|
}));
|
|
14
|
-
vi.mock('../lib/search-api.js', () =>
|
|
15
|
-
extendedSearch: vi.fn(),
|
|
16
|
-
}));
|
|
20
|
+
vi.mock('../lib/search-api.js', () => searchApiMocks);
|
|
17
21
|
vi.mock('chalk', () => ({
|
|
18
22
|
default: {
|
|
19
23
|
bold: vi.fn((text) => text),
|
|
@@ -30,10 +34,49 @@ function createProgram() {
|
|
|
30
34
|
describe('search --workspace conflict', () => {
|
|
31
35
|
beforeEach(() => {
|
|
32
36
|
vi.clearAllMocks();
|
|
37
|
+
refsMocks.resolveWorkspaceRef.mockResolvedValue({ id: 1, name: 'Doist' });
|
|
38
|
+
searchApiMocks.extendedSearch.mockResolvedValue({
|
|
39
|
+
items: [],
|
|
40
|
+
hasMore: false,
|
|
41
|
+
isPlanRestricted: false,
|
|
42
|
+
});
|
|
33
43
|
});
|
|
34
44
|
it('errors when both positional and --workspace are provided', async () => {
|
|
35
45
|
const program = createProgram();
|
|
36
46
|
await expect(program.parseAsync(['node', 'tw', 'search', 'query', 'Doist', '--workspace', 'Other'])).rejects.toThrow('Cannot specify workspace both as argument and --workspace flag');
|
|
37
47
|
});
|
|
48
|
+
it('parses channel and conversation refs using resolvers', async () => {
|
|
49
|
+
refsMocks.resolveChannelId.mockImplementation((ref) => {
|
|
50
|
+
if (ref === 'id:10')
|
|
51
|
+
return 10;
|
|
52
|
+
if (ref === 'https://twist.com/a/1/ch/20')
|
|
53
|
+
return 20;
|
|
54
|
+
throw new Error('Unexpected channel ref');
|
|
55
|
+
});
|
|
56
|
+
refsMocks.resolveConversationId.mockImplementation((ref) => {
|
|
57
|
+
if (ref === 'id:30')
|
|
58
|
+
return 30;
|
|
59
|
+
if (ref === 'https://twist.com/a/1/msg/40')
|
|
60
|
+
return 40;
|
|
61
|
+
throw new Error('Unexpected conversation ref');
|
|
62
|
+
});
|
|
63
|
+
const program = createProgram();
|
|
64
|
+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
65
|
+
await program.parseAsync([
|
|
66
|
+
'node',
|
|
67
|
+
'tw',
|
|
68
|
+
'search',
|
|
69
|
+
'query',
|
|
70
|
+
'--channel',
|
|
71
|
+
'id:10,https://twist.com/a/1/ch/20',
|
|
72
|
+
'--conversation',
|
|
73
|
+
'id:30,https://twist.com/a/1/msg/40',
|
|
74
|
+
]);
|
|
75
|
+
expect(searchApiMocks.extendedSearch).toHaveBeenCalledWith(expect.objectContaining({
|
|
76
|
+
channelIds: [10, 20],
|
|
77
|
+
conversationIds: [30, 40],
|
|
78
|
+
}));
|
|
79
|
+
logSpy.mockRestore();
|
|
80
|
+
});
|
|
38
81
|
});
|
|
39
82
|
//# sourceMappingURL=search.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.test.js","sourceRoot":"","sources":["../../src/__tests__/search.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7D,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"search.test.js","sourceRoot":"","sources":["../../src/__tests__/search.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,10 @@ vi.mock('../lib/public-channels.js', () => ({
|
|
|
9
9
|
vi.mock('../lib/markdown.js', () => ({
|
|
10
10
|
renderMarkdown: vi.fn((text) => text),
|
|
11
11
|
}));
|
|
12
|
+
vi.mock('../lib/input.js', () => ({
|
|
13
|
+
readStdin: vi.fn().mockResolvedValue(''),
|
|
14
|
+
openEditor: vi.fn().mockResolvedValue(''),
|
|
15
|
+
}));
|
|
12
16
|
vi.mock('chalk', () => ({
|
|
13
17
|
default: {
|
|
14
18
|
bold: Object.assign(vi.fn((text) => text), {
|
|
@@ -37,5 +41,22 @@ describe('thread implicit view', () => {
|
|
|
37
41
|
await expect(program.parseAsync(['node', 'tw', 'thread', '100'])).rejects.toThrow('MOCK_API_REACHED');
|
|
38
42
|
consoleSpy.mockRestore();
|
|
39
43
|
});
|
|
44
|
+
it('accepts id: prefixes in --notify for thread reply', async () => {
|
|
45
|
+
const program = createProgram();
|
|
46
|
+
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
47
|
+
await program.parseAsync([
|
|
48
|
+
'node',
|
|
49
|
+
'tw',
|
|
50
|
+
'thread',
|
|
51
|
+
'reply',
|
|
52
|
+
'100',
|
|
53
|
+
'hello',
|
|
54
|
+
'--notify',
|
|
55
|
+
'id:123,456',
|
|
56
|
+
'--dry-run',
|
|
57
|
+
]);
|
|
58
|
+
expect(consoleSpy).toHaveBeenCalledWith('Dry run: would post comment to thread', 100);
|
|
59
|
+
consoleSpy.mockRestore();
|
|
60
|
+
});
|
|
40
61
|
});
|
|
41
62
|
//# sourceMappingURL=thread.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread.test.js","sourceRoot":"","sources":["../../src/__tests__/thread.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7D,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;CAC3E,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE;CACjC,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;CAChD,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACpB,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC,MAAM,CACf,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,EAC7B;YACI,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;SACtC,CACJ;QACD,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;KACtC;CACJ,CAAC,CAAC,CAAA;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,SAAS,aAAa;IAClB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;IAC7B,OAAO,CAAC,YAAY,EAAE,CAAA;IACtB,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,OAAO,CAAA;AAClB,CAAC;AAED,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IAClC,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAA;IACtB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;QAC/B,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAExE,0FAA0F;QAC1F,iEAAiE;QACjE,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAC7E,kBAAkB,CACrB,CAAA;QAED,UAAU,CAAC,WAAW,EAAE,CAAA;IAC5B,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"thread.test.js","sourceRoot":"","sources":["../../src/__tests__/thread.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7D,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;CAC3E,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE;CACjC,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IACjC,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;CAChD,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9B,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACxC,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;CAC5C,CAAC,CAAC,CAAA;AAEH,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACpB,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC,MAAM,CACf,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,EAC7B;YACI,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;SACtC,CACJ;QACD,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;KACtC;CACJ,CAAC,CAAC,CAAA;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,SAAS,aAAa;IAClB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;IAC7B,OAAO,CAAC,YAAY,EAAE,CAAA;IACtB,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,OAAO,CAAA;AAClB,CAAC;AAED,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IAClC,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAA;IACtB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;QAC/B,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAExE,0FAA0F;QAC1F,iEAAiE;QACjE,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAC7E,kBAAkB,CACrB,CAAA;QAED,UAAU,CAAC,WAAW,EAAE,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;QAC/B,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAExE,MAAM,OAAO,CAAC,UAAU,CAAC;YACrB,MAAM;YACN,IAAI;YACJ,QAAQ;YACR,OAAO;YACP,KAAK;YACL,OAAO;YACP,UAAU;YACV,YAAY;YACZ,WAAW;SACd,CAAC,CAAA;QAEF,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAA;QACrF,UAAU,CAAC,WAAW,EAAE,CAAA;IAC5B,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/commands/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/commands/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA0DnC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAS7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/commands/channel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/commands/channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/commands/completion.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA2CnC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkGhE"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { getCompletions, parseCompLine } from '../lib/completion.js';
|
|
5
|
+
// pwsh is included because tabtab supports it — installedShells() needs to
|
|
6
|
+
// detect and clean up pwsh completion files even though we don't advertise it.
|
|
7
|
+
const COMPLETION_EXTENSIONS = {
|
|
8
|
+
bash: 'bash',
|
|
9
|
+
zsh: 'zsh',
|
|
10
|
+
fish: 'fish',
|
|
11
|
+
pwsh: 'ps1',
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Find which shells have tw completions installed by checking for the
|
|
15
|
+
* completion script files that tabtab creates.
|
|
16
|
+
*
|
|
17
|
+
* FIXME: Workaround for https://github.com/pnpm/tabtab/issues/34 —
|
|
18
|
+
* tabtab.uninstall() without a shell tries all shells and throws ENOENT
|
|
19
|
+
* for ones that were never installed. We detect which shells are actually
|
|
20
|
+
* installed and uninstall only those. Remove once the upstream issue is fixed.
|
|
21
|
+
*/
|
|
22
|
+
function installedShells() {
|
|
23
|
+
return Object.entries(COMPLETION_EXTENSIONS)
|
|
24
|
+
.filter(([shell, ext]) => existsSync(join(homedir(), '.config', 'tabtab', shell, `tw.${ext}`)))
|
|
25
|
+
.map(([shell]) => shell);
|
|
26
|
+
}
|
|
27
|
+
function resolveCompleterCommand() {
|
|
28
|
+
const invokedScript = process.argv[1];
|
|
29
|
+
if (!invokedScript) {
|
|
30
|
+
return 'tw';
|
|
31
|
+
}
|
|
32
|
+
const resolvedScript = resolve(invokedScript);
|
|
33
|
+
if (existsSync(resolvedScript)) {
|
|
34
|
+
return resolvedScript;
|
|
35
|
+
}
|
|
36
|
+
return 'tw';
|
|
37
|
+
}
|
|
38
|
+
export function registerCompletionCommand(program) {
|
|
39
|
+
const completion = program.command('completion').description('Manage shell completions');
|
|
40
|
+
completion
|
|
41
|
+
.command('install [shell]')
|
|
42
|
+
.description('Install shell completions (bash, zsh, fish)')
|
|
43
|
+
.action(async (shell) => {
|
|
44
|
+
const tabtab = await import('@pnpm/tabtab');
|
|
45
|
+
const completer = resolveCompleterCommand();
|
|
46
|
+
if (shell && !tabtab.isShellSupported(shell)) {
|
|
47
|
+
console.error(`Unsupported shell: ${shell}. Supported: ${tabtab.SUPPORTED_SHELLS.join(', ')}`);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
await tabtab.install({
|
|
52
|
+
name: 'tw',
|
|
53
|
+
// Use the executable path used to install completions so shell
|
|
54
|
+
// completion doesn't accidentally call an older `tw` on PATH.
|
|
55
|
+
completer,
|
|
56
|
+
shell: shell,
|
|
57
|
+
});
|
|
58
|
+
console.log('Shell completions installed successfully.');
|
|
59
|
+
console.log('Restart your shell or source your shell config to activate.');
|
|
60
|
+
});
|
|
61
|
+
completion
|
|
62
|
+
.command('uninstall')
|
|
63
|
+
.description('Remove shell completions')
|
|
64
|
+
.action(async () => {
|
|
65
|
+
// FIXME: Replace with plain tabtab.uninstall({ name: 'tw' }) once
|
|
66
|
+
// https://github.com/pnpm/tabtab/issues/34 is fixed.
|
|
67
|
+
const shells = installedShells();
|
|
68
|
+
if (shells.length === 0) {
|
|
69
|
+
console.log('No shell completions installed.');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const tabtab = await import('@pnpm/tabtab');
|
|
73
|
+
for (const shell of shells) {
|
|
74
|
+
await tabtab.uninstall({
|
|
75
|
+
name: 'tw',
|
|
76
|
+
shell,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
console.log('Shell completions removed.');
|
|
80
|
+
});
|
|
81
|
+
// Hidden command invoked by the shell completion script at TAB time
|
|
82
|
+
program
|
|
83
|
+
.command('completion-server', { hidden: true })
|
|
84
|
+
.description('Completion server (internal)')
|
|
85
|
+
.allowUnknownOption()
|
|
86
|
+
.allowExcessArguments()
|
|
87
|
+
.action(async () => {
|
|
88
|
+
const tabtab = await import('@pnpm/tabtab');
|
|
89
|
+
const env = tabtab.parseEnv(process.env);
|
|
90
|
+
if (!env.complete) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const shell = tabtab.getShellFromEnv(process.env);
|
|
94
|
+
const words = parseCompLine(env.line);
|
|
95
|
+
let current = env.last;
|
|
96
|
+
// The fish/zsh completion templates always append a trailing space
|
|
97
|
+
// to COMP_LINE, making env.last empty even when the cursor is right
|
|
98
|
+
// after '--flag='. Use env.lastPartial (cursor-position-aware) to
|
|
99
|
+
// detect this case and restore the actual word being completed.
|
|
100
|
+
if (current === '' && env.lastPartial.includes('=')) {
|
|
101
|
+
if (words.at(-1) === '')
|
|
102
|
+
words.pop();
|
|
103
|
+
current = env.lastPartial;
|
|
104
|
+
}
|
|
105
|
+
const completions = getCompletions(program, words, current);
|
|
106
|
+
// Bash treats '=' as a word break (COMP_WORDBREAKS), so readline
|
|
107
|
+
// replaces only the part after '=' with COMPREPLY values. If we
|
|
108
|
+
// return '--flag=value', bash produces '--flag=--flag=value'.
|
|
109
|
+
// Strip the flag prefix so bash gets just the value part.
|
|
110
|
+
if (shell === 'bash' && current.includes('=')) {
|
|
111
|
+
const prefix = current.slice(0, current.indexOf('=') + 1);
|
|
112
|
+
const values = completions
|
|
113
|
+
.map((c) => (c.name.startsWith(prefix) ? c.name.slice(prefix.length) : c.name))
|
|
114
|
+
.filter(Boolean);
|
|
115
|
+
console.log(values.join('\n'));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
tabtab.log(completions, shell);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=completion.js.map
|