@doist/twist-cli 2.21.1 → 2.21.2
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/CHANGELOG.md +6 -0
- package/dist/__mocks__/chalk.d.ts +3 -0
- package/dist/__mocks__/chalk.d.ts.map +1 -0
- package/dist/__mocks__/chalk.js +8 -0
- package/dist/__mocks__/chalk.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +155 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/away.d.ts +3 -0
- package/dist/commands/away.d.ts.map +1 -0
- package/dist/commands/away.js +120 -0
- package/dist/commands/away.js.map +1 -0
- package/dist/commands/changelog.d.ts +8 -0
- package/dist/commands/changelog.d.ts.map +1 -0
- package/dist/commands/changelog.js +113 -0
- package/dist/commands/changelog.js.map +1 -0
- package/dist/commands/channel.d.ts +3 -0
- package/dist/commands/channel.d.ts.map +1 -0
- package/dist/commands/channel.js +53 -0
- package/dist/commands/channel.js.map +1 -0
- package/dist/commands/comment.d.ts +3 -0
- package/dist/commands/comment.d.ts.map +1 -0
- package/dist/commands/comment.js +99 -0
- package/dist/commands/comment.js.map +1 -0
- 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 +3 -0
- package/dist/commands/conversation.d.ts.map +1 -0
- package/dist/commands/conversation.js +458 -0
- package/dist/commands/conversation.js.map +1 -0
- package/dist/commands/inbox.d.ts +3 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +127 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/msg.d.ts +3 -0
- package/dist/commands/msg.d.ts.map +1 -0
- package/dist/commands/msg.js +103 -0
- package/dist/commands/msg.js.map +1 -0
- package/dist/commands/react.d.ts +3 -0
- package/dist/commands/react.d.ts.map +1 -0
- package/dist/commands/react.js +102 -0
- package/dist/commands/react.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +160 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/skill.d.ts +3 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +119 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/thread/create.d.ts +7 -0
- package/dist/commands/thread/create.d.ts.map +1 -0
- package/dist/commands/thread/create.js +45 -0
- package/dist/commands/thread/create.js.map +1 -0
- package/dist/commands/thread/helpers.d.ts +10 -0
- package/dist/commands/thread/helpers.d.ts.map +1 -0
- package/dist/commands/thread/helpers.js +27 -0
- package/dist/commands/thread/helpers.js.map +1 -0
- package/dist/commands/thread/mutate.d.ts +5 -0
- package/dist/commands/thread/mutate.d.ts.map +1 -0
- package/dist/commands/thread/mutate.js +21 -0
- package/dist/commands/thread/mutate.js.map +1 -0
- package/dist/commands/thread/mute.d.ts +8 -0
- package/dist/commands/thread/mute.d.ts.map +1 -0
- package/dist/commands/thread/mute.js +58 -0
- package/dist/commands/thread/mute.js.map +1 -0
- package/dist/commands/thread/reply.d.ts +9 -0
- package/dist/commands/thread/reply.d.ts.map +1 -0
- package/dist/commands/thread/reply.js +68 -0
- package/dist/commands/thread/reply.js.map +1 -0
- package/dist/commands/thread/view.d.ts +9 -0
- package/dist/commands/thread/view.d.ts.map +1 -0
- package/dist/commands/thread/view.js +175 -0
- package/dist/commands/thread/view.js.map +1 -0
- package/dist/commands/thread.d.ts +3 -0
- package/dist/commands/thread.d.ts.map +1 -0
- package/dist/commands/thread.js +70 -0
- package/dist/commands/thread.js.map +1 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +91 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/user.d.ts +3 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +67 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/commands/view.d.ts +3 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +63 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/commands/workspace.d.ts +3 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +48 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +20 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +229 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +21 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +189 -0
- package/dist/lib/auth.js.map +1 -0
- 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/config.d.ts +13 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +26 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/dates.d.ts +3 -0
- package/dist/lib/dates.d.ts.map +1 -0
- package/dist/lib/dates.js +44 -0
- package/dist/lib/dates.js.map +1 -0
- package/dist/lib/input.d.ts +3 -0
- package/dist/lib/input.d.ts.map +1 -0
- package/dist/lib/input.js +52 -0
- package/dist/lib/input.js.map +1 -0
- package/dist/lib/markdown.d.ts +2 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/markdown.js +16 -0
- package/dist/lib/markdown.js.map +1 -0
- package/dist/lib/oauth-server.d.ts +13 -0
- package/dist/lib/oauth-server.d.ts.map +1 -0
- package/dist/lib/oauth-server.js +824 -0
- package/dist/lib/oauth-server.js.map +1 -0
- package/dist/lib/oauth.d.ts +31 -0
- package/dist/lib/oauth.d.ts.map +1 -0
- package/dist/lib/oauth.js +140 -0
- package/dist/lib/oauth.js.map +1 -0
- package/dist/lib/options.d.ts +17 -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/output.d.ts +25 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +128 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/permissions.d.ts +4 -0
- package/dist/lib/permissions.d.ts.map +1 -0
- package/dist/lib/permissions.js +35 -0
- package/dist/lib/permissions.js.map +1 -0
- package/dist/lib/pkce.d.ts +16 -0
- package/dist/lib/pkce.d.ts.map +1 -0
- package/dist/lib/pkce.js +35 -0
- package/dist/lib/pkce.js.map +1 -0
- package/dist/lib/progress.d.ts +29 -0
- package/dist/lib/progress.d.ts.map +1 -0
- package/dist/lib/progress.js +101 -0
- package/dist/lib/progress.js.map +1 -0
- package/dist/lib/public-channels.d.ts +5 -0
- package/dist/lib/public-channels.d.ts.map +1 -0
- package/dist/lib/public-channels.js +35 -0
- package/dist/lib/public-channels.js.map +1 -0
- package/dist/lib/refs.d.ts +37 -0
- package/dist/lib/refs.d.ts.map +1 -0
- package/dist/lib/refs.js +219 -0
- package/dist/lib/refs.js.map +1 -0
- package/dist/lib/search-api.d.ts +25 -0
- package/dist/lib/search-api.d.ts.map +1 -0
- package/dist/lib/search-api.js +85 -0
- package/dist/lib/search-api.js.map +1 -0
- package/dist/lib/secure-store.d.ts +11 -0
- package/dist/lib/secure-store.d.ts.map +1 -0
- package/dist/lib/secure-store.js +57 -0
- package/dist/lib/secure-store.js.map +1 -0
- package/dist/lib/skills/content.d.ts +5 -0
- package/dist/lib/skills/content.d.ts.map +1 -0
- package/dist/lib/skills/content.js +286 -0
- package/dist/lib/skills/content.js.map +1 -0
- package/dist/lib/skills/create-installer.d.ts +9 -0
- package/dist/lib/skills/create-installer.d.ts.map +1 -0
- package/dist/lib/skills/create-installer.js +60 -0
- package/dist/lib/skills/create-installer.js.map +1 -0
- package/dist/lib/skills/index.d.ts +7 -0
- package/dist/lib/skills/index.d.ts.map +1 -0
- package/dist/lib/skills/index.js +54 -0
- package/dist/lib/skills/index.js.map +1 -0
- package/dist/lib/skills/types.d.ts +30 -0
- package/dist/lib/skills/types.d.ts.map +1 -0
- package/dist/lib/skills/types.js +2 -0
- package/dist/lib/skills/types.js.map +1 -0
- package/dist/lib/skills/update-installed.d.ts +9 -0
- package/dist/lib/skills/update-installed.d.ts.map +1 -0
- package/dist/lib/skills/update-installed.js +20 -0
- package/dist/lib/skills/update-installed.js.map +1 -0
- package/dist/lib/spinner.d.ts +24 -0
- package/dist/lib/spinner.d.ts.map +1 -0
- package/dist/lib/spinner.js +126 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/postinstall.d.ts +2 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +3 -0
- package/dist/postinstall.js.map +1 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [2.21.2](https://github.com/Doist/twist-cli/compare/v2.21.1...v2.21.2) (2026-03-29)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* add prepublishOnly script for release safety ([#115](https://github.com/Doist/twist-cli/issues/115)) ([7b50727](https://github.com/Doist/twist-cli/commit/7b5072700f8fac968161ade717cde247ff5e87fe))
|
|
6
|
+
|
|
1
7
|
## [2.21.1](https://github.com/Doist/twist-cli/compare/v2.21.0...v2.21.1) (2026-03-28)
|
|
2
8
|
|
|
3
9
|
### Bug Fixes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chalk.d.ts","sourceRoot":"","sources":["../../src/__mocks__/chalk.ts"],"names":[],"mappings":"+BAA2B,MAAM;AAQjC,wBAAiC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chalk.js","sourceRoot":"","sources":["../../src/__mocks__/chalk.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAA;AAE1C,SAAS,gBAAgB;IACrB,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE;QAC1B,GAAG,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE;KAChC,CAAuB,CAAA;AAC5B,CAAC;AAED,eAAe,gBAAgB,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA4KnC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB1D"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import open from 'open';
|
|
4
|
+
import { getSessionUser } from '../lib/api.js';
|
|
5
|
+
import { clearApiToken, getAuthMetadata, saveApiToken, } from '../lib/auth.js';
|
|
6
|
+
import { buildAuthorizationUrl, exchangeCodeForToken, READ_ONLY_SCOPES, READ_WRITE_SCOPES, registerDynamicClient, } from '../lib/oauth.js';
|
|
7
|
+
import { startCallbackServer } from '../lib/oauth-server.js';
|
|
8
|
+
import { generateCodeChallenge, generateCodeVerifier, generateState } from '../lib/pkce.js';
|
|
9
|
+
async function loginWithOAuth(options) {
|
|
10
|
+
const modeLabel = options.readOnly ? 'read-only' : 'read-write';
|
|
11
|
+
console.log(chalk.blue(`Starting OAuth authentication (${modeLabel})...`));
|
|
12
|
+
try {
|
|
13
|
+
// Register dynamic client
|
|
14
|
+
console.log(chalk.dim('Registering OAuth client...'));
|
|
15
|
+
const client = await registerDynamicClient();
|
|
16
|
+
// Generate PKCE parameters
|
|
17
|
+
const codeVerifier = generateCodeVerifier();
|
|
18
|
+
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
19
|
+
const state = generateState();
|
|
20
|
+
// Start callback server
|
|
21
|
+
console.log(chalk.dim('Starting local callback server...'));
|
|
22
|
+
let cleanup;
|
|
23
|
+
try {
|
|
24
|
+
// Open browser in background after a delay
|
|
25
|
+
setTimeout(async () => {
|
|
26
|
+
try {
|
|
27
|
+
const authUrl = buildAuthorizationUrl(client.client_id, codeChallenge, state, {
|
|
28
|
+
readOnly: options.readOnly,
|
|
29
|
+
});
|
|
30
|
+
console.log(chalk.dim('Opening browser for authorization...'));
|
|
31
|
+
console.log(chalk.dim(`If the browser doesn't open, visit: ${authUrl}`));
|
|
32
|
+
await open(authUrl);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Browser opening failure is not critical - user can use the URL manually
|
|
36
|
+
}
|
|
37
|
+
}, 1000);
|
|
38
|
+
// Wait for callback - this gives us both code and cleanup
|
|
39
|
+
const result = await startCallbackServer(state);
|
|
40
|
+
cleanup = result.cleanup;
|
|
41
|
+
console.log(chalk.dim('Exchanging authorization code for token...'));
|
|
42
|
+
const accessToken = await exchangeCodeForToken(result.code, codeVerifier, client);
|
|
43
|
+
const saveResult = await saveApiToken(accessToken, {
|
|
44
|
+
authMode: options.readOnly ? 'read-only' : 'read-write',
|
|
45
|
+
authScope: options.readOnly ? READ_ONLY_SCOPES : READ_WRITE_SCOPES,
|
|
46
|
+
});
|
|
47
|
+
console.log(chalk.green('✓'), 'OAuth authentication successful!');
|
|
48
|
+
logTokenStorageResult(saveResult, 'Token stored securely in the system credential manager');
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
// Always cleanup the server
|
|
52
|
+
if (cleanup) {
|
|
53
|
+
cleanup();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.log(chalk.red('✗'), 'OAuth authentication failed');
|
|
59
|
+
console.log(chalk.dim(error instanceof Error ? error.message : 'Unknown error'));
|
|
60
|
+
console.log(chalk.dim('You can try manual authentication with `tw auth token <token>`'));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function promptHiddenInput(prompt) {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
const rl = createInterface({
|
|
66
|
+
input: process.stdin,
|
|
67
|
+
output: process.stdout,
|
|
68
|
+
});
|
|
69
|
+
// biome-ignore lint/suspicious/noExplicitAny: accessing private readline property
|
|
70
|
+
const origWrite = rl._writeToOutput;
|
|
71
|
+
rl._writeToOutput = (str) => {
|
|
72
|
+
if (str.includes(prompt)) {
|
|
73
|
+
origWrite.call(rl, prompt);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
rl.question(prompt, (answer) => {
|
|
77
|
+
rl.close();
|
|
78
|
+
process.stdout.write('\n');
|
|
79
|
+
resolve(answer);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function loginWithToken(token) {
|
|
84
|
+
if (!token) {
|
|
85
|
+
token = await promptHiddenInput('API token: ');
|
|
86
|
+
if (!token.trim()) {
|
|
87
|
+
console.error(chalk.red('Error:'), 'No token provided');
|
|
88
|
+
process.exitCode = 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const saveResult = await saveApiToken(token.trim(), { authMode: 'unknown' });
|
|
93
|
+
console.log(chalk.green('✓'), 'API token saved successfully!');
|
|
94
|
+
logTokenStorageResult(saveResult, 'Token stored securely in the system credential manager');
|
|
95
|
+
}
|
|
96
|
+
async function showStatus(options) {
|
|
97
|
+
try {
|
|
98
|
+
// Try to get session user to verify the token works
|
|
99
|
+
const user = await getSessionUser();
|
|
100
|
+
if (options.json) {
|
|
101
|
+
console.log(JSON.stringify({ id: user.id, email: user.email, name: user.name }, null, 2));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const metadata = await getAuthMetadata();
|
|
105
|
+
const modeLabel = metadata.authMode === 'read-only'
|
|
106
|
+
? `read-only (scope: ${metadata.authScope ?? 'unknown'})`
|
|
107
|
+
: metadata.authMode === 'read-write'
|
|
108
|
+
? 'read-write'
|
|
109
|
+
: 'unknown (manual token or env var; assuming write access)';
|
|
110
|
+
console.log(chalk.green('✓'), 'Authenticated');
|
|
111
|
+
console.log(` Email: ${user.email}`);
|
|
112
|
+
console.log(` Name: ${user.name}`);
|
|
113
|
+
console.log(` Mode: ${modeLabel}`);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
if (options.json) {
|
|
117
|
+
console.log(JSON.stringify({ error: 'Not authenticated' }, null, 2));
|
|
118
|
+
process.exitCode = 1;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
console.log(chalk.yellow('Not authenticated'));
|
|
122
|
+
console.log(chalk.dim('Run `tw auth login` for OAuth or `tw auth token <token>` for manual authentication'));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function logout() {
|
|
126
|
+
const clearResult = await clearApiToken();
|
|
127
|
+
console.log(chalk.green('✓'), 'Logged out');
|
|
128
|
+
logTokenStorageResult(clearResult, 'Stored token removed from the system credential manager');
|
|
129
|
+
}
|
|
130
|
+
function logTokenStorageResult(result, secureStoreMessage) {
|
|
131
|
+
if (result.storage === 'secure-store') {
|
|
132
|
+
console.log(chalk.dim(secureStoreMessage));
|
|
133
|
+
if (result.warning) {
|
|
134
|
+
console.error(chalk.yellow('Warning:'), result.warning);
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
console.error(chalk.yellow('Warning:'), result.warning);
|
|
139
|
+
}
|
|
140
|
+
export function registerAuthCommand(program) {
|
|
141
|
+
const auth = program.command('auth').description('Manage authentication');
|
|
142
|
+
auth.command('login')
|
|
143
|
+
.description('Authenticate using OAuth (opens browser)')
|
|
144
|
+
.option('--read-only', 'Authenticate with read-only scope (no write operations)')
|
|
145
|
+
.action(loginWithOAuth);
|
|
146
|
+
auth.command('token [token]')
|
|
147
|
+
.description('Save API token for CLI authentication')
|
|
148
|
+
.action(loginWithToken);
|
|
149
|
+
auth.command('status')
|
|
150
|
+
.description('Show current authentication status')
|
|
151
|
+
.option('--json', 'Output as JSON')
|
|
152
|
+
.action(showStatus);
|
|
153
|
+
auth.command('logout').description('Remove saved authentication token').action(logout);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"away.d.ts","sourceRoot":"","sources":["../../src/commands/away.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkInC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyB1D"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { AWAY_MODE_TYPES, TwistRequestError } from '@doist/twist-sdk';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { getSessionUser, getTwistClient } from '../lib/api.js';
|
|
4
|
+
import { colors, formatJson } from '../lib/output.js';
|
|
5
|
+
function formatLocalDate(d) {
|
|
6
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
7
|
+
}
|
|
8
|
+
function todayStr() {
|
|
9
|
+
return formatLocalDate(new Date());
|
|
10
|
+
}
|
|
11
|
+
function tomorrowStr() {
|
|
12
|
+
const d = new Date();
|
|
13
|
+
d.setDate(d.getDate() + 1);
|
|
14
|
+
return formatLocalDate(d);
|
|
15
|
+
}
|
|
16
|
+
function formatAwayType(type) {
|
|
17
|
+
const labels = {
|
|
18
|
+
vacation: 'Vacation',
|
|
19
|
+
parental: 'Parental leave',
|
|
20
|
+
sickleave: 'Sick leave',
|
|
21
|
+
other: 'Away',
|
|
22
|
+
};
|
|
23
|
+
return labels[type] ?? type;
|
|
24
|
+
}
|
|
25
|
+
async function showAwayStatus(options) {
|
|
26
|
+
const user = await getSessionUser();
|
|
27
|
+
if (options.json) {
|
|
28
|
+
console.log(formatJson(user, 'user', options.full));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!user.awayMode) {
|
|
32
|
+
console.log('Not away.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const { type, dateFrom, dateTo } = user.awayMode;
|
|
36
|
+
console.log(chalk.bold(formatAwayType(type)));
|
|
37
|
+
console.log(`From: ${colors.timestamp(dateFrom)}`);
|
|
38
|
+
console.log(`Until: ${colors.timestamp(dateTo)}`);
|
|
39
|
+
}
|
|
40
|
+
async function setAway(type, until, options) {
|
|
41
|
+
if (!AWAY_MODE_TYPES.includes(type)) {
|
|
42
|
+
console.error(`Invalid away type: ${type}. Use: ${AWAY_MODE_TYPES.join(', ')}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const dateFrom = options.from ?? todayStr();
|
|
46
|
+
const dateTo = until ?? tomorrowStr();
|
|
47
|
+
if (options.dryRun) {
|
|
48
|
+
console.log(`Dry run: would set away to ${formatAwayType(type)} from ${dateFrom} until ${dateTo}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const client = await getTwistClient();
|
|
52
|
+
try {
|
|
53
|
+
const user = await client.users.update({
|
|
54
|
+
awayMode: { type: type, dateFrom, dateTo },
|
|
55
|
+
});
|
|
56
|
+
if (options.json) {
|
|
57
|
+
console.log(formatJson(user, 'user', options.full));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log(`Set away: ${formatAwayType(type)} from ${dateFrom} until ${dateTo}`);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
handleAwayError(error);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function clearAway(options) {
|
|
67
|
+
if (options.dryRun) {
|
|
68
|
+
console.log('Dry run: would clear away status');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const client = await getTwistClient();
|
|
72
|
+
try {
|
|
73
|
+
const user = await client.users.update({ awayMode: '' });
|
|
74
|
+
if (options.json) {
|
|
75
|
+
console.log(formatJson(user, 'user', options.full));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
console.log('Away status cleared.');
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
handleAwayError(error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function isInsufficientScope(error) {
|
|
85
|
+
if (!(error instanceof TwistRequestError))
|
|
86
|
+
return false;
|
|
87
|
+
const data = error.responseData;
|
|
88
|
+
return (error.httpStatusCode === 403 && data?.error_string?.includes('Insufficient scope') === true);
|
|
89
|
+
}
|
|
90
|
+
function handleAwayError(error) {
|
|
91
|
+
if (isInsufficientScope(error)) {
|
|
92
|
+
console.error(chalk.red('Permission denied.'), 'The away status feature requires additional permissions.');
|
|
93
|
+
console.error(`Run ${chalk.cyan('tw auth login')} to re-authenticate with the required scopes.`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
export function registerAwayCommand(program) {
|
|
99
|
+
const away = program
|
|
100
|
+
.command('away')
|
|
101
|
+
.description('Manage away status')
|
|
102
|
+
.option('--json', 'Output as JSON')
|
|
103
|
+
.option('--full', 'Include all fields in JSON output')
|
|
104
|
+
.action((options) => showAwayStatus(options));
|
|
105
|
+
away.command('set <type> [until]')
|
|
106
|
+
.usage('<type> [until] [options]')
|
|
107
|
+
.description('Set away status (type: vacation, parental, sickleave, other)')
|
|
108
|
+
.option('--from <date>', 'Start date (YYYY-MM-DD, defaults to today)')
|
|
109
|
+
.option('--dry-run', 'Show what would happen without executing')
|
|
110
|
+
.option('--json', 'Output as JSON')
|
|
111
|
+
.option('--full', 'Include all fields in JSON output')
|
|
112
|
+
.action((type, until, options) => setAway(type, until, options));
|
|
113
|
+
away.command('clear')
|
|
114
|
+
.description('Clear away status')
|
|
115
|
+
.option('--dry-run', 'Show what would happen without executing')
|
|
116
|
+
.option('--json', 'Output as JSON')
|
|
117
|
+
.option('--full', 'Include all fields in JSON output')
|
|
118
|
+
.action((options) => clearAway(options));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=away.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"away.js","sourceRoot":"","sources":["../../src/commands/away.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
interface ChangelogOptions {
|
|
3
|
+
count: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function changelogAction(options: ChangelogOptions): Promise<void>;
|
|
6
|
+
export declare function registerChangelogCommand(program: Command): void;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=changelog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../../src/commands/changelog.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA2FxC,UAAU,gBAAgB;IACtB,KAAK,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB9E;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAM/D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import packageJson from '../../package.json' with { type: 'json' };
|
|
6
|
+
const CHANGELOG_PATH = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'CHANGELOG.md');
|
|
7
|
+
const CHANGELOG_URL = `https://github.com/Doist/twist-cli/blob/v${packageJson.version}/CHANGELOG.md`;
|
|
8
|
+
function formatInline(text) {
|
|
9
|
+
return text
|
|
10
|
+
.replace(/\*\*([^*]+)\*\*/g, (_, content) => chalk.bold(content))
|
|
11
|
+
.replace(/`([^`]+)`/g, (_, code) => chalk.cyan(code));
|
|
12
|
+
}
|
|
13
|
+
function formatForTerminal(text) {
|
|
14
|
+
let inBullet = false;
|
|
15
|
+
return text
|
|
16
|
+
.split('\n')
|
|
17
|
+
.map((line) => {
|
|
18
|
+
// Version headers: # 1.25.0 or ## 1.25.0 (date) → bold green
|
|
19
|
+
if (/^#{1,2} \d/.test(line)) {
|
|
20
|
+
inBullet = false;
|
|
21
|
+
const content = line.replace(/^#{1,2} /, '');
|
|
22
|
+
return chalk.green.bold(content);
|
|
23
|
+
}
|
|
24
|
+
// Section headers: ### Features → bold
|
|
25
|
+
if (line.startsWith('### ')) {
|
|
26
|
+
inBullet = false;
|
|
27
|
+
return chalk.bold(line.slice(4));
|
|
28
|
+
}
|
|
29
|
+
// Bullet items: * description → dimmed bullet + text
|
|
30
|
+
if (line.startsWith('* ')) {
|
|
31
|
+
inBullet = true;
|
|
32
|
+
return ` ${chalk.dim('•')} ${formatInline(line.slice(2))}`;
|
|
33
|
+
}
|
|
34
|
+
// Continuation lines of a bullet item → indent to match
|
|
35
|
+
if (inBullet && line.length > 0) {
|
|
36
|
+
return ` ${formatInline(line)}`;
|
|
37
|
+
}
|
|
38
|
+
if (line.length === 0) {
|
|
39
|
+
inBullet = false;
|
|
40
|
+
}
|
|
41
|
+
return formatInline(line);
|
|
42
|
+
})
|
|
43
|
+
.join('\n');
|
|
44
|
+
}
|
|
45
|
+
function cleanChangelog(text) {
|
|
46
|
+
return (text
|
|
47
|
+
// Version headers: # [1.25.0](https://...) or ## [1.25.0](https://...) → keep heading level
|
|
48
|
+
.replace(/(#{1,2}) \[([^\]]+)\]\([^)]*\)/g, '$1 $2')
|
|
49
|
+
// Remove commit hash links: ([abc1234](https://...))
|
|
50
|
+
.replace(/ \([a-f0-9]{7}\)/g, '')
|
|
51
|
+
.replace(/ \(\[[a-f0-9]{7}\]\([^)]*\)\)/g, '')
|
|
52
|
+
// Issue/PR links: [#151](https://...) → #151
|
|
53
|
+
.replace(/\[#(\d+)\]\([^)]*\)/g, '#$1')
|
|
54
|
+
// Remove **deps:** dependency update lines (not useful to end users)
|
|
55
|
+
.replace(/^\* \*\*deps:\*\*.*$/gm, '')
|
|
56
|
+
// Remove **scope:** prefixes but keep the text: **task:** foo → foo
|
|
57
|
+
.replace(/\*\*[\w-]+:\*\* /g, '')
|
|
58
|
+
// Clean up blank lines left by removed dep lines
|
|
59
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
60
|
+
// Remove section headers left empty after filtering (e.g. ### Bug Fixes with no items)
|
|
61
|
+
.replace(/### [\w ]+\n\n(?=#{1,3} |$)/gm, ''));
|
|
62
|
+
}
|
|
63
|
+
function isEmptyAfterClean(section) {
|
|
64
|
+
const cleaned = cleanChangelog(section);
|
|
65
|
+
// A section is empty if it only contains the version header line(s) and whitespace
|
|
66
|
+
const withoutHeader = cleaned.replace(/^#{1,2} .+$/m, '').trim();
|
|
67
|
+
return withoutHeader.length === 0;
|
|
68
|
+
}
|
|
69
|
+
function parseChangelog(content, count) {
|
|
70
|
+
const sections = content.split(/\n(?=#{1,2} \[)/);
|
|
71
|
+
// Skip preamble (non-version content) if present
|
|
72
|
+
const allVersions = /^#{1,2} \[/.test(sections[0]) ? sections : sections.slice(1);
|
|
73
|
+
// Filter out versions that become empty after cleaning (e.g. deps-only releases)
|
|
74
|
+
const versionSections = allVersions.filter((s) => !isEmptyAfterClean(s));
|
|
75
|
+
const selected = versionSections.slice(0, count);
|
|
76
|
+
if (selected.length === 0) {
|
|
77
|
+
return { text: 'No changelog entries found.', hasMore: false };
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
text: cleanChangelog(selected.join('\n').trimEnd()),
|
|
81
|
+
hasMore: versionSections.length > count,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export async function changelogAction(options) {
|
|
85
|
+
const count = parseInt(options.count, 10);
|
|
86
|
+
if (Number.isNaN(count) || count < 1) {
|
|
87
|
+
console.error(chalk.red('Error:'), 'Count must be a positive number');
|
|
88
|
+
process.exitCode = 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
let content;
|
|
92
|
+
try {
|
|
93
|
+
content = await readFile(CHANGELOG_PATH, 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
console.error(chalk.red('Error:'), 'Could not read changelog file');
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const { text, hasMore } = parseChangelog(content, count);
|
|
101
|
+
console.log(formatForTerminal(text));
|
|
102
|
+
if (hasMore) {
|
|
103
|
+
console.log(chalk.dim(`\nView full changelog: ${CHANGELOG_URL}`));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export function registerChangelogCommand(program) {
|
|
107
|
+
program
|
|
108
|
+
.command('changelog')
|
|
109
|
+
.description('Show recent changelog entries')
|
|
110
|
+
.option('-n, --count <number>', 'Number of versions to show', '5')
|
|
111
|
+
.action(changelogAction);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=changelog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changelog.js","sourceRoot":"","sources":["../../src/commands/changelog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getCurrentWorkspaceId, getTwistClient } from '../lib/api.js';
|
|
2
|
+
import { colors, formatJson, formatNdjson } from '../lib/output.js';
|
|
3
|
+
import { includePrivateChannels } from '../lib/public-channels.js';
|
|
4
|
+
import { resolveWorkspaceRef } from '../lib/refs.js';
|
|
5
|
+
async function listChannels(workspaceRef, options) {
|
|
6
|
+
if (workspaceRef && options.workspace) {
|
|
7
|
+
throw new Error('Cannot specify workspace both as argument and --workspace flag');
|
|
8
|
+
}
|
|
9
|
+
let workspaceId;
|
|
10
|
+
const ref = workspaceRef || options.workspace;
|
|
11
|
+
if (ref) {
|
|
12
|
+
const workspace = await resolveWorkspaceRef(ref);
|
|
13
|
+
workspaceId = workspace.id;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
workspaceId = await getCurrentWorkspaceId();
|
|
17
|
+
}
|
|
18
|
+
const client = await getTwistClient();
|
|
19
|
+
let channels = await client.channels.getChannels({ workspaceId });
|
|
20
|
+
if (!includePrivateChannels()) {
|
|
21
|
+
channels = channels.filter((ch) => ch.public);
|
|
22
|
+
}
|
|
23
|
+
if (channels.length === 0) {
|
|
24
|
+
console.log('No channels found.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (options.json) {
|
|
28
|
+
console.log(formatJson(channels, 'channel', options.full));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (options.ndjson) {
|
|
32
|
+
console.log(formatNdjson(channels, 'channel', options.full));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const ch of channels) {
|
|
36
|
+
const id = colors.timestamp(`id:${ch.id}`);
|
|
37
|
+
const name = colors.channel(ch.name);
|
|
38
|
+
const archived = ch.archived ? colors.timestamp(' (archived)') : '';
|
|
39
|
+
const visibility = ch.public ? '' : colors.timestamp(' [private]');
|
|
40
|
+
console.log(`${id} ${name}${visibility}${archived}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function registerChannelCommand(program) {
|
|
44
|
+
program
|
|
45
|
+
.command('channels [workspace-ref]')
|
|
46
|
+
.description('List channels in a workspace')
|
|
47
|
+
.option('--workspace <ref>', 'Workspace ID or name')
|
|
48
|
+
.option('--json', 'Output as JSON')
|
|
49
|
+
.option('--ndjson', 'Output as newline-delimited JSON')
|
|
50
|
+
.option('--full', 'Include all fields in JSON output')
|
|
51
|
+
.action(listChannels);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":"comment.d.ts","sourceRoot":"","sources":["../../src/commands/comment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgGnC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiC7D"}
|