@doist/twist-cli 2.13.0 → 2.14.1
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/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +21 -7
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/thread/view.d.ts.map +1 -1
- package/dist/commands/thread/view.js +34 -22
- package/dist/commands/thread/view.js.map +1 -1
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +55 -42
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/auth.d.ts +12 -1
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +35 -1
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/oauth.d.ts +5 -2
- package/dist/lib/oauth.d.ts.map +1 -1
- package/dist/lib/oauth.js +17 -4
- package/dist/lib/oauth.js.map +1 -1
- 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/skills/content.d.ts +2 -2
- package/dist/lib/skills/content.d.ts.map +1 -1
- package/dist/lib/skills/content.js +7 -4
- package/dist/lib/skills/content.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAiKnC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe1D"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -2,12 +2,13 @@ import { createInterface } from 'node:readline';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import open from 'open';
|
|
4
4
|
import { getSessionUser } from '../lib/api.js';
|
|
5
|
-
import { clearApiToken, saveApiToken } from '../lib/auth.js';
|
|
6
|
-
import { buildAuthorizationUrl, exchangeCodeForToken, registerDynamicClient } from '../lib/oauth.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
7
|
import { startCallbackServer } from '../lib/oauth-server.js';
|
|
8
8
|
import { generateCodeChallenge, generateCodeVerifier, generateState } from '../lib/pkce.js';
|
|
9
|
-
async function loginWithOAuth() {
|
|
10
|
-
|
|
9
|
+
async function loginWithOAuth(options) {
|
|
10
|
+
const modeLabel = options.readOnly ? 'read-only' : 'read-write';
|
|
11
|
+
console.log(chalk.blue(`Starting OAuth authentication (${modeLabel})...`));
|
|
11
12
|
try {
|
|
12
13
|
// Register dynamic client
|
|
13
14
|
console.log(chalk.dim('Registering OAuth client...'));
|
|
@@ -23,7 +24,9 @@ async function loginWithOAuth() {
|
|
|
23
24
|
// Open browser in background after a delay
|
|
24
25
|
setTimeout(async () => {
|
|
25
26
|
try {
|
|
26
|
-
const authUrl = buildAuthorizationUrl(client.client_id, codeChallenge, state
|
|
27
|
+
const authUrl = buildAuthorizationUrl(client.client_id, codeChallenge, state, {
|
|
28
|
+
readOnly: options.readOnly,
|
|
29
|
+
});
|
|
27
30
|
console.log(chalk.dim('Opening browser for authorization...'));
|
|
28
31
|
console.log(chalk.dim(`If the browser doesn't open, visit: ${authUrl}`));
|
|
29
32
|
await open(authUrl);
|
|
@@ -37,7 +40,10 @@ async function loginWithOAuth() {
|
|
|
37
40
|
cleanup = result.cleanup;
|
|
38
41
|
console.log(chalk.dim('Exchanging authorization code for token...'));
|
|
39
42
|
const accessToken = await exchangeCodeForToken(result.code, codeVerifier, client);
|
|
40
|
-
const saveResult = await saveApiToken(accessToken
|
|
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
|
+
});
|
|
41
47
|
console.log(chalk.green('✓'), 'OAuth authentication successful!');
|
|
42
48
|
logTokenStorageResult(saveResult, 'Token stored securely in the system credential manager');
|
|
43
49
|
}
|
|
@@ -83,7 +89,7 @@ async function loginWithToken(token) {
|
|
|
83
89
|
return;
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
|
-
const saveResult = await saveApiToken(token.trim());
|
|
92
|
+
const saveResult = await saveApiToken(token.trim(), { authMode: 'unknown' });
|
|
87
93
|
console.log(chalk.green('✓'), 'API token saved successfully!');
|
|
88
94
|
logTokenStorageResult(saveResult, 'Token stored securely in the system credential manager');
|
|
89
95
|
}
|
|
@@ -91,9 +97,16 @@ async function showStatus() {
|
|
|
91
97
|
try {
|
|
92
98
|
// Try to get session user to verify the token works
|
|
93
99
|
const user = await getSessionUser();
|
|
100
|
+
const metadata = await getAuthMetadata();
|
|
101
|
+
const modeLabel = metadata.authMode === 'read-only'
|
|
102
|
+
? `read-only (scope: ${metadata.authScope ?? 'unknown'})`
|
|
103
|
+
: metadata.authMode === 'read-write'
|
|
104
|
+
? 'read-write'
|
|
105
|
+
: 'unknown (manual token or env var; assuming write access)';
|
|
94
106
|
console.log(chalk.green('✓'), 'Authenticated');
|
|
95
107
|
console.log(` Email: ${user.email}`);
|
|
96
108
|
console.log(` Name: ${user.name}`);
|
|
109
|
+
console.log(` Mode: ${modeLabel}`);
|
|
97
110
|
}
|
|
98
111
|
catch {
|
|
99
112
|
console.log(chalk.yellow('Not authenticated'));
|
|
@@ -119,6 +132,7 @@ export function registerAuthCommand(program) {
|
|
|
119
132
|
const auth = program.command('auth').description('Manage authentication');
|
|
120
133
|
auth.command('login')
|
|
121
134
|
.description('Authenticate using OAuth (opens browser)')
|
|
135
|
+
.option('--read-only', 'Authenticate with read-only scope (no write operations)')
|
|
122
136
|
.action(loginWithOAuth);
|
|
123
137
|
auth.command('token [token]')
|
|
124
138
|
.description('Save API token for CLI authentication')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/commands/thread/view.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAMhE,KAAK,WAAW,GAAG,oBAAoB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA2DD,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/commands/thread/view.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAMhE,KAAK,WAAW,GAAG,oBAAoB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA2DD,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA0KjF"}
|
|
@@ -62,17 +62,35 @@ export async function viewThread(ref, options) {
|
|
|
62
62
|
const thread = threadResponse.data;
|
|
63
63
|
const comments = commentsResponse.data;
|
|
64
64
|
await assertChannelIsPublic(thread.channelId, thread.workspaceId);
|
|
65
|
-
|
|
65
|
+
// Resolve unread state and filter comments before any output
|
|
66
|
+
let displayComments = comments;
|
|
67
|
+
let contextComments = [];
|
|
68
|
+
let lastReadObjIndex = 0;
|
|
69
|
+
let hasUnread = false;
|
|
66
70
|
if (options.unread) {
|
|
67
71
|
const unreadData = await client.threads.getUnread(thread.workspaceId);
|
|
68
72
|
const threadUnread = unreadData.find((u) => u.threadId === threadId);
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
if (threadUnread) {
|
|
74
|
+
lastReadObjIndex = threadUnread.objIndex;
|
|
75
|
+
const contextSize = options.context ? parseInt(options.context, 10) : 0;
|
|
76
|
+
displayComments = comments.filter((c) => (c.objIndex ?? 0) > lastReadObjIndex);
|
|
77
|
+
contextComments = comments
|
|
78
|
+
.filter((c) => (c.objIndex ?? 0) <= lastReadObjIndex)
|
|
79
|
+
.sort((a, b) => (b.objIndex ?? 0) - (a.objIndex ?? 0))
|
|
80
|
+
.slice(0, contextSize)
|
|
81
|
+
.reverse();
|
|
82
|
+
hasUnread = displayComments.length > 0;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
displayComments = [];
|
|
86
|
+
hasUnread = false;
|
|
72
87
|
}
|
|
73
|
-
lastReadObjIndex = threadUnread.objIndex;
|
|
74
88
|
}
|
|
75
|
-
const userIds = new Set([
|
|
89
|
+
const userIds = new Set([
|
|
90
|
+
thread.creator,
|
|
91
|
+
...displayComments.map((c) => c.creator),
|
|
92
|
+
...contextComments.map((c) => c.creator),
|
|
93
|
+
]);
|
|
76
94
|
const userCalls = [...userIds].map((id) => client.workspaceUsers.getUserById({ workspaceId: thread.workspaceId, userId: id }, { batch: true }));
|
|
77
95
|
const [channelResponse, ...userResponses] = await client.batch(client.channels.getChannel(thread.channelId, { batch: true }), ...userCalls);
|
|
78
96
|
const channel = channelResponse.data;
|
|
@@ -84,7 +102,7 @@ export async function viewThread(ref, options) {
|
|
|
84
102
|
channelName: channel.name,
|
|
85
103
|
creatorName: userMap.get(thread.creator),
|
|
86
104
|
},
|
|
87
|
-
comments:
|
|
105
|
+
comments: displayComments.map((c) => ({
|
|
88
106
|
...c,
|
|
89
107
|
creatorName: userMap.get(c.creator),
|
|
90
108
|
})),
|
|
@@ -100,7 +118,7 @@ export async function viewThread(ref, options) {
|
|
|
100
118
|
creatorName: userMap.get(thread.creator),
|
|
101
119
|
};
|
|
102
120
|
console.log(JSON.stringify(threadOutput));
|
|
103
|
-
for (const c of
|
|
121
|
+
for (const c of displayComments) {
|
|
104
122
|
console.log(JSON.stringify({ type: 'comment', ...c, creatorName: userMap.get(c.creator) }));
|
|
105
123
|
}
|
|
106
124
|
return;
|
|
@@ -108,22 +126,16 @@ export async function viewThread(ref, options) {
|
|
|
108
126
|
console.log(chalk.bold(thread.title));
|
|
109
127
|
console.log(colors.channel(`[${channel.name}]`));
|
|
110
128
|
console.log('');
|
|
111
|
-
if (options.unread
|
|
112
|
-
const contextSize = options.context ? parseInt(options.context, 10) : 0;
|
|
113
|
-
const unreadComments = comments.filter((c) => (c.objIndex ?? 0) > lastReadObjIndex);
|
|
114
|
-
const contextComments = comments
|
|
115
|
-
.filter((c) => (c.objIndex ?? 0) <= lastReadObjIndex)
|
|
116
|
-
.sort((a, b) => (b.objIndex ?? 0) - (a.objIndex ?? 0))
|
|
117
|
-
.slice(0, contextSize)
|
|
118
|
-
.reverse();
|
|
119
|
-
if (unreadComments.length === 0) {
|
|
120
|
-
console.log('No unread comments.');
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
129
|
+
if (options.unread) {
|
|
123
130
|
const creatorName = userMap.get(thread.creator) || `user:${thread.creator}`;
|
|
124
131
|
console.log(`${colors.author(creatorName)} ${colors.timestamp(formatRelativeDate(thread.posted))} ${chalk.dim('(original post)')}`);
|
|
125
132
|
console.log('');
|
|
126
133
|
console.log(options.raw ? thread.content : renderMarkdown(thread.content));
|
|
134
|
+
if (!hasUnread) {
|
|
135
|
+
console.log('');
|
|
136
|
+
console.log('No unread comments.');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
127
139
|
if (contextComments.length > 0) {
|
|
128
140
|
const firstContextIndex = contextComments[0].objIndex ?? 0;
|
|
129
141
|
const skippedCount = firstContextIndex - 1;
|
|
@@ -140,8 +152,8 @@ export async function viewThread(ref, options) {
|
|
|
140
152
|
else if (lastReadObjIndex > 0) {
|
|
141
153
|
printSeparator(`${lastReadObjIndex} ${pluralize(lastReadObjIndex, 'comment')} skipped`);
|
|
142
154
|
}
|
|
143
|
-
printSeparator(`UNREAD (${
|
|
144
|
-
for (const comment of
|
|
155
|
+
printSeparator(`UNREAD (${displayComments.length} new)`);
|
|
156
|
+
for (const comment of displayComments) {
|
|
145
157
|
printComment(comment, userMap, options.raw ?? false);
|
|
146
158
|
}
|
|
147
159
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../../src/commands/thread/view.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../../src/commands/thread/view.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAkM1F,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAOxD;AAKD,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAO5D;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAsB,qBAAqB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB/E;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAOpD;AAED,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAGrF;AAED,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,CAAA"}
|
package/dist/lib/api.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TwistApi } from '@doist/twist-sdk';
|
|
2
2
|
import { getApiToken } from './auth.js';
|
|
3
3
|
import { getConfig, updateConfig } from './config.js';
|
|
4
|
+
import { ensureWriteAllowed, isMutatingMethod } from './permissions.js';
|
|
4
5
|
import { getProgressTracker } from './progress.js';
|
|
5
6
|
import { withSpinner } from './spinner.js';
|
|
6
7
|
// Mapping of API method paths to user-friendly spinner messages
|
|
@@ -68,53 +69,65 @@ function createNestedSpinnerProxy(obj, basePath) {
|
|
|
68
69
|
return new Proxy(obj, {
|
|
69
70
|
get(target, property, receiver) {
|
|
70
71
|
const originalMethod = Reflect.get(target, property, receiver);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
72
|
+
if (typeof originalMethod !== 'function' || typeof property !== 'string') {
|
|
73
|
+
return originalMethod;
|
|
74
|
+
}
|
|
75
|
+
const fullPath = `${basePath}.${property}`;
|
|
76
|
+
const spinnerConfig = API_SPINNER_MESSAGES[fullPath];
|
|
77
|
+
const shouldCheckPermissions = isMutatingMethod(fullPath);
|
|
78
|
+
if (!spinnerConfig && !shouldCheckPermissions) {
|
|
79
|
+
return originalMethod;
|
|
80
|
+
}
|
|
81
|
+
return (...args) => {
|
|
82
|
+
const progressTracker = getProgressTracker();
|
|
83
|
+
// Extract cursor from args for paginated methods
|
|
84
|
+
let cursor = null;
|
|
85
|
+
if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {
|
|
86
|
+
const options = args[0];
|
|
87
|
+
if ('cursor' in options && typeof options.cursor === 'string') {
|
|
88
|
+
cursor = options.cursor;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Emit progress event for API call start
|
|
92
|
+
if (progressTracker.isEnabled()) {
|
|
93
|
+
progressTracker.emitApiCall(property, cursor);
|
|
94
|
+
}
|
|
95
|
+
// For mutating methods, check permissions before calling the API
|
|
96
|
+
if (shouldCheckPermissions) {
|
|
97
|
+
return ensureWriteAllowed().then(() => {
|
|
90
98
|
const result = originalMethod.apply(target, args);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const wrappedPromise = result
|
|
94
|
-
.then((response) => {
|
|
95
|
-
// Emit progress event for successful response
|
|
96
|
-
if (progressTracker.isEnabled()) {
|
|
97
|
-
analyzeAndEmitApiResponse(progressTracker, response);
|
|
98
|
-
}
|
|
99
|
-
return response;
|
|
100
|
-
})
|
|
101
|
-
.catch((error) => {
|
|
102
|
-
// Emit progress event for error
|
|
103
|
-
if (progressTracker.isEnabled()) {
|
|
104
|
-
progressTracker.emitError(error.name || 'API_ERROR', error.message);
|
|
105
|
-
}
|
|
106
|
-
throw error;
|
|
107
|
-
});
|
|
108
|
-
return withSpinner(spinnerConfig, () => wrappedPromise);
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
};
|
|
99
|
+
return wrapResult(result, progressTracker, spinnerConfig);
|
|
100
|
+
});
|
|
112
101
|
}
|
|
113
|
-
|
|
114
|
-
|
|
102
|
+
const result = originalMethod.apply(target, args);
|
|
103
|
+
return wrapResult(result, progressTracker, spinnerConfig);
|
|
104
|
+
};
|
|
115
105
|
},
|
|
116
106
|
});
|
|
117
107
|
}
|
|
108
|
+
function wrapResult(result, progressTracker, spinnerConfig) {
|
|
109
|
+
// If the method returns a non-thenable (e.g. batch request builder), return as-is
|
|
110
|
+
if (!result || typeof result.then !== 'function') {
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
const wrappedPromise = result
|
|
114
|
+
.then((response) => {
|
|
115
|
+
if (progressTracker.isEnabled()) {
|
|
116
|
+
analyzeAndEmitApiResponse(progressTracker, response);
|
|
117
|
+
}
|
|
118
|
+
return response;
|
|
119
|
+
})
|
|
120
|
+
.catch((error) => {
|
|
121
|
+
if (progressTracker.isEnabled()) {
|
|
122
|
+
progressTracker.emitError(error.name || 'API_ERROR', error.message);
|
|
123
|
+
}
|
|
124
|
+
throw error;
|
|
125
|
+
});
|
|
126
|
+
if (spinnerConfig) {
|
|
127
|
+
return withSpinner(spinnerConfig, () => wrappedPromise);
|
|
128
|
+
}
|
|
129
|
+
return wrappedPromise;
|
|
130
|
+
}
|
|
118
131
|
function analyzeAndEmitApiResponse(progressTracker, response) {
|
|
119
132
|
// For paginated responses, extract metadata
|
|
120
133
|
if (response && typeof response === 'object' && response !== null) {
|
package/dist/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiD,MAAM,kBAAkB,CAAA;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,gEAAgE;AAChE,MAAM,oBAAoB,GACtB;IACI,kBAAkB;IAClB,sBAAsB,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,MAAM,EAAE;IAE7E,cAAc,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAE7D,uBAAuB;IACvB,0BAA0B,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE;IAC5E,kCAAkC,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,MAAM,EAAE;IACzF,4BAA4B,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,EAAE;IAEhF,oBAAoB;IACpB,mBAAmB,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,EAAE;IACjE,mBAAmB,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,MAAM,EAAE;IAEzE,qBAAqB;IACrB,qBAAqB,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,EAAE;IACpE,sBAAsB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,EAAE;IACtE,wBAAwB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE;IACzE,wBAAwB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC1E,wBAAwB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAE1E,qBAAqB;IACrB,qBAAqB,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,EAAE;IACpE,sBAAsB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,EAAE;IACtE,wBAAwB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE;IACzE,wBAAwB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC1E,wBAAwB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAE1E,0BAA0B;IAC1B,gCAAgC,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,KAAK,EAAE,MAAM,EAAE;IACrF,+BAA+B,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,EAAE;IACnF,yBAAyB,EAAE,EAAE,IAAI,EAAE,iCAAiC,EAAE,KAAK,EAAE,MAAM,EAAE;IACrF,kCAAkC,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,KAAK,EAAE,OAAO,EAAE;IACxF,mCAAmC,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC3F,qCAAqC,EAAE;QACnC,IAAI,EAAE,6BAA6B;QACnC,KAAK,EAAE,QAAQ;KAClB;IAED,kCAAkC;IAClC,iCAAiC,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,EAAE;IAChF,kCAAkC,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,EAAE;IAClF,oCAAoC,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,OAAO,EAAE;IACpF,oCAAoC,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IACtF,oCAAoC,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAEtF,mBAAmB;IACnB,gBAAgB,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE;IAC7D,qBAAqB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE;IAEvE,mBAAmB;IACnB,KAAK,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,KAAK,EAAE,MAAM,EAAE;CACnE,CAAA;AAEL,SAAS,uBAAuB,CAAC,GAAa;IAC1C,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE;QAClB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ;YAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;YAErD,yEAAyE;YACzE,IACI,KAAK;gBACL,OAAO,KAAK,KAAK,QAAQ;gBACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBACrB,OAAO,QAAQ,KAAK,QAAQ,EAC9B,CAAC;gBACC,OAAO,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YACpD,CAAC;YAED,OAAO,KAAK,CAAA;QAChB,CAAC;KACJ,CAAC,CAAA;AACN,CAAC;AAED,SAAS,wBAAwB,CAAmB,GAAM,EAAE,QAAgB;IACxE,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE;QAClB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ;YAC1B,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;YAE9D,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
import { type AuthMode } from './config.js';
|
|
1
2
|
export declare const TOKEN_ENV_VAR = "TWIST_API_TOKEN";
|
|
2
3
|
export type TokenStorageLocation = 'secure-store' | 'config-file';
|
|
3
4
|
export interface TokenStorageResult {
|
|
4
5
|
storage: TokenStorageLocation;
|
|
5
6
|
warning?: string;
|
|
6
7
|
}
|
|
8
|
+
export interface SaveApiTokenOptions {
|
|
9
|
+
authMode?: AuthMode;
|
|
10
|
+
authScope?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface AuthMetadata {
|
|
13
|
+
authMode: AuthMode;
|
|
14
|
+
authScope?: string;
|
|
15
|
+
source: 'env' | 'config';
|
|
16
|
+
}
|
|
7
17
|
export declare function getApiToken(): Promise<string>;
|
|
8
|
-
export declare function
|
|
18
|
+
export declare function getAuthMetadata(): Promise<AuthMetadata>;
|
|
19
|
+
export declare function saveApiToken(token: string, options?: SaveApiTokenOptions): Promise<TokenStorageResult>;
|
|
9
20
|
export declare function clearApiToken(): Promise<TokenStorageResult>;
|
|
10
21
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/lib/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAoD,MAAM,aAAa,CAAA;AAO7F,eAAO,MAAM,aAAa,oBAAoB,CAAA;AAC9C,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG,aAAa,CAAA;AAEjE,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,oBAAoB,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAA;CAC3B;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAmEnD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAY7D;AAED,wBAAsB,YAAY,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAwC7B;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAyBjE"}
|
package/dist/lib/auth.js
CHANGED
|
@@ -57,7 +57,19 @@ export async function getApiToken() {
|
|
|
57
57
|
}
|
|
58
58
|
throw new Error(`No API token found. Set ${TOKEN_ENV_VAR} or run \`tw auth login\` or \`tw auth token <token>\`.`);
|
|
59
59
|
}
|
|
60
|
-
export async function
|
|
60
|
+
export async function getAuthMetadata() {
|
|
61
|
+
const envToken = process.env[TOKEN_ENV_VAR];
|
|
62
|
+
if (envToken) {
|
|
63
|
+
return { authMode: 'unknown', source: 'env' };
|
|
64
|
+
}
|
|
65
|
+
const config = await getConfig();
|
|
66
|
+
return {
|
|
67
|
+
authMode: config.authMode ?? 'unknown',
|
|
68
|
+
authScope: config.authScope,
|
|
69
|
+
source: 'config',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export async function saveApiToken(token, options = {}) {
|
|
61
73
|
// Validate token (non-empty, reasonable length)
|
|
62
74
|
if (!token || token.trim().length < 10) {
|
|
63
75
|
throw new Error('Invalid token: Token must be at least 10 characters');
|
|
@@ -68,6 +80,15 @@ export async function saveApiToken(token) {
|
|
|
68
80
|
await secureStore.setSecret(trimmedToken);
|
|
69
81
|
const existingConfig = await getConfig();
|
|
70
82
|
const warning = await cleanupAuthFallbackState(existingConfig, 'Token was stored securely,');
|
|
83
|
+
// Persist auth metadata to config — needed for ensureWriteAllowed() enforcement
|
|
84
|
+
try {
|
|
85
|
+
await saveAuthMetadata(options);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
if (options.authMode && options.authMode !== 'unknown') {
|
|
89
|
+
warn(`Could not persist auth mode '${options.authMode}' to config. CLI-side write protection may not work in future sessions.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
71
92
|
return warning ? { storage: 'secure-store', warning } : { storage: 'secure-store' };
|
|
72
93
|
}
|
|
73
94
|
catch (error) {
|
|
@@ -78,6 +99,8 @@ export async function saveApiToken(token) {
|
|
|
78
99
|
const config = await getConfig();
|
|
79
100
|
config.token = trimmedToken;
|
|
80
101
|
delete config.pendingSecureStoreClear;
|
|
102
|
+
config.authMode = options.authMode ?? 'unknown';
|
|
103
|
+
config.authScope = options.authScope;
|
|
81
104
|
await writeConfig(config);
|
|
82
105
|
return {
|
|
83
106
|
storage: 'config-file',
|
|
@@ -87,6 +110,11 @@ export async function saveApiToken(token) {
|
|
|
87
110
|
export async function clearApiToken() {
|
|
88
111
|
const config = await getConfig();
|
|
89
112
|
const secureStore = createSecureStore();
|
|
113
|
+
// Clear auth metadata from the in-memory config object so all subsequent
|
|
114
|
+
// writes (cleanupAuthFallbackState, withPendingSecureStoreClear) persist
|
|
115
|
+
// the removal atomically alongside other state changes.
|
|
116
|
+
delete config.authMode;
|
|
117
|
+
delete config.authScope;
|
|
90
118
|
try {
|
|
91
119
|
await secureStore.deleteSecret();
|
|
92
120
|
const warning = await cleanupAuthFallbackState(config, 'Secure-store token was removed,');
|
|
@@ -103,6 +131,12 @@ export async function clearApiToken() {
|
|
|
103
131
|
warning: buildFallbackWarning('local auth state cleared in'),
|
|
104
132
|
};
|
|
105
133
|
}
|
|
134
|
+
async function saveAuthMetadata(options) {
|
|
135
|
+
const config = await getConfig();
|
|
136
|
+
config.authMode = options.authMode ?? 'unknown';
|
|
137
|
+
config.authScope = options.authScope;
|
|
138
|
+
await setConfig(config);
|
|
139
|
+
}
|
|
106
140
|
async function writeConfig(config) {
|
|
107
141
|
if (Object.keys(config).length === 0) {
|
|
108
142
|
try {
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
export type AuthMode = 'read-only' | 'read-write' | 'unknown';
|
|
1
2
|
export interface Config {
|
|
2
3
|
token?: string;
|
|
3
4
|
pendingSecureStoreClear?: boolean;
|
|
4
5
|
currentWorkspace?: number;
|
|
6
|
+
authMode?: AuthMode;
|
|
7
|
+
authScope?: string;
|
|
5
8
|
}
|
|
6
9
|
export declare function getConfig(): Promise<Config>;
|
|
7
10
|
export declare function setConfig(config: Config): Promise<void>;
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,MAAM;IAEnB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,CAAA;AAE7D,MAAM,WAAW,MAAM;IAEnB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAOjD;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;AAe1E,MAAM,CAAC,KAAK,UAAU,SAAS;IAC3B,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAA;IACxC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAA;IACb,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAc;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAChC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACrC,MAAM,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB;IACvD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAChC,MAAM,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa;IACzB,OAAO,WAAW,CAAA;AACtB,CAAC"}
|
package/dist/lib/oauth.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ export declare const AUTHORIZATION_URL = "https://twist.com/oauth/authorize";
|
|
|
5
5
|
export declare const TOKEN_URL = "https://twist.com/oauth/access_token";
|
|
6
6
|
export declare const REGISTRATION_URL = "https://twist.com/oauth/register";
|
|
7
7
|
export declare const OAUTH_REDIRECT_URI = "http://localhost:8766/callback";
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const READ_WRITE_SCOPES: string;
|
|
9
|
+
export declare const READ_ONLY_SCOPES: string;
|
|
9
10
|
/**
|
|
10
11
|
* OAuth client credentials from dynamic registration
|
|
11
12
|
*/
|
|
@@ -20,7 +21,9 @@ export declare function registerDynamicClient(): Promise<OAuthClient>;
|
|
|
20
21
|
/**
|
|
21
22
|
* Build the authorization URL for the OAuth flow
|
|
22
23
|
*/
|
|
23
|
-
export declare function buildAuthorizationUrl(clientId: string, codeChallenge: string, state: string
|
|
24
|
+
export declare function buildAuthorizationUrl(clientId: string, codeChallenge: string, state: string, options?: {
|
|
25
|
+
readOnly?: boolean;
|
|
26
|
+
}): string;
|
|
24
27
|
/**
|
|
25
28
|
* Exchange authorization code for access token using PKCE
|
|
26
29
|
*/
|
package/dist/lib/oauth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,iBAAiB,sCAAsC,CAAA;AACpE,eAAO,MAAM,SAAS,yCAAyC,CAAA;AAC/D,eAAO,MAAM,gBAAgB,qCAAqC,CAAA;AAClE,eAAO,MAAM,kBAAkB,mCAAmC,CAAA;AAGlE,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,iBAAiB,sCAAsC,CAAA;AACpE,eAAO,MAAM,SAAS,yCAAyC,CAAA;AAC/D,eAAO,MAAM,gBAAgB,qCAAqC,CAAA;AAClE,eAAO,MAAM,kBAAkB,mCAAmC,CAAA;AAGlE,eAAO,MAAM,iBAAiB,QAenB,CAAA;AAGX,eAAO,MAAM,gBAAgB,QAUlB,CAAA;AAEX;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACxB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,WAAW,CAAC,CAgDlE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,CAaR;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,CAiDjB"}
|
package/dist/lib/oauth.js
CHANGED
|
@@ -6,8 +6,8 @@ export const AUTHORIZATION_URL = 'https://twist.com/oauth/authorize';
|
|
|
6
6
|
export const TOKEN_URL = 'https://twist.com/oauth/access_token';
|
|
7
7
|
export const REGISTRATION_URL = 'https://twist.com/oauth/register';
|
|
8
8
|
export const OAUTH_REDIRECT_URI = 'http://localhost:8766/callback';
|
|
9
|
-
// OAuth scopes needed for
|
|
10
|
-
export const
|
|
9
|
+
// OAuth scopes needed for full read-write CLI operations
|
|
10
|
+
export const READ_WRITE_SCOPES = [
|
|
11
11
|
'user:read', // Read user information and session details
|
|
12
12
|
'user:write', // Update user settings (e.g. away status)
|
|
13
13
|
'workspaces:read', // Read workspace information
|
|
@@ -23,6 +23,18 @@ export const OAUTH_SCOPES = [
|
|
|
23
23
|
'search:read', // Search functionality
|
|
24
24
|
'notifications:read', // Read notifications
|
|
25
25
|
].join(' ');
|
|
26
|
+
// OAuth scopes for read-only CLI operations (no :write scopes)
|
|
27
|
+
export const READ_ONLY_SCOPES = [
|
|
28
|
+
'user:read',
|
|
29
|
+
'workspaces:read',
|
|
30
|
+
'channels:read',
|
|
31
|
+
'threads:read',
|
|
32
|
+
'comments:read',
|
|
33
|
+
'messages:read',
|
|
34
|
+
'reactions:read',
|
|
35
|
+
'search:read',
|
|
36
|
+
'notifications:read',
|
|
37
|
+
].join(' ');
|
|
26
38
|
/**
|
|
27
39
|
* Register a dynamic OAuth client for this CLI session
|
|
28
40
|
*/
|
|
@@ -69,12 +81,13 @@ export async function registerDynamicClient() {
|
|
|
69
81
|
/**
|
|
70
82
|
* Build the authorization URL for the OAuth flow
|
|
71
83
|
*/
|
|
72
|
-
export function buildAuthorizationUrl(clientId, codeChallenge, state) {
|
|
84
|
+
export function buildAuthorizationUrl(clientId, codeChallenge, state, options = {}) {
|
|
85
|
+
const scope = options.readOnly ? READ_ONLY_SCOPES : READ_WRITE_SCOPES;
|
|
73
86
|
const params = new URLSearchParams({
|
|
74
87
|
client_id: clientId,
|
|
75
88
|
response_type: 'code',
|
|
76
89
|
redirect_uri: OAUTH_REDIRECT_URI,
|
|
77
|
-
scope
|
|
90
|
+
scope,
|
|
78
91
|
state,
|
|
79
92
|
code_challenge: codeChallenge,
|
|
80
93
|
code_challenge_method: 'S256',
|
package/dist/lib/oauth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,iBAAiB,GAAG,mCAAmC,CAAA;AACpE,MAAM,CAAC,MAAM,SAAS,GAAG,sCAAsC,CAAA;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,kCAAkC,CAAA;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,gCAAgC,CAAA;AAElE,
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,iBAAiB,GAAG,mCAAmC,CAAA;AACpE,MAAM,CAAC,MAAM,SAAS,GAAG,sCAAsC,CAAA;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,kCAAkC,CAAA;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,gCAAgC,CAAA;AAElE,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC7B,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,0CAA0C;IACxD,iBAAiB,EAAE,6BAA6B;IAChD,eAAe,EAAE,2BAA2B;IAC5C,cAAc,EAAE,0BAA0B;IAC1C,eAAe,EAAE,4BAA4B;IAC7C,eAAe,EAAE,yBAAyB;IAC1C,gBAAgB,EAAE,yBAAyB;IAC3C,eAAe,EAAE,gBAAgB;IACjC,gBAAgB,EAAE,gBAAgB;IAClC,gBAAgB,EAAE,iBAAiB;IACnC,iBAAiB,EAAE,gBAAgB;IACnC,aAAa,EAAE,uBAAuB;IACtC,oBAAoB,EAAE,qBAAqB;CAC9C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEX,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,WAAW;IACX,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,eAAe;IACf,eAAe;IACf,gBAAgB;IAChB,aAAa;IACb,oBAAoB;CACvB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAUX;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACvC,MAAM,UAAU,GAAG;QACf,WAAW,EAAE,WAAW;QACxB,UAAU,EAAE,oCAAoC;QAChD,aAAa,EAAE,CAAC,kBAAkB,CAAC;QACnC,WAAW,EAAE,CAAC,oBAAoB,CAAC;QACnC,cAAc,EAAE,CAAC,MAAM,CAAC;QACxB,0BAA0B,EAAE,qBAAqB,EAAE,oCAAoC;QACvF,gBAAgB,EAAE,QAAQ,EAAE,8BAA8B;QAC1D,QAAQ,EACJ,gHAAgH;KACvH,CAAA;IAED,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,kBAAkB;aAC7B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SACnC,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YACvC,MAAM,IAAI,KAAK,CACX,+BAA+B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,SAAS,EAAE,CACzF,CAAA;QACL,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAEpC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACX,0EAA0E,CAC7E,CAAA;QACL,CAAC;QAED,OAAO;YACH,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;SACtC,CAAA;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACxE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;IACrE,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACjC,QAAgB,EAChB,aAAqB,EACrB,KAAa,EACb,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAA;IACrE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QAC/B,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,MAAM;QACrB,YAAY,EAAE,kBAAkB;QAChC,KAAK;QACL,KAAK;QACL,cAAc,EAAE,aAAa;QAC7B,qBAAqB,EAAE,MAAM;KAChC,CAAC,CAAA;IAEF,OAAO,GAAG,iBAAiB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,IAAY,EACZ,YAAoB,EACpB,MAAmB;IAEnB,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC7B,UAAU,EAAE,oBAAoB;QAChC,IAAI;QACJ,YAAY,EAAE,kBAAkB;QAChC,aAAa,EAAE,YAAY;KAC9B,CAAC,CAAA;IAEF,uDAAuD;IACvD,MAAM,WAAW,GAAG,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa,EAAE,CAAA;IACjE,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;IAE5C,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,mCAAmC;gBACnD,MAAM,EAAE,kBAAkB;gBAC1B,aAAa,EAAE,SAAS,kBAAkB,EAAE;aAC/C;YACD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;SACxB,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YACvC,MAAM,IAAI,KAAK,CACX,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,SAAS,EAAE,CACpF,CAAA;QACL,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAElC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACX,gBAAgB,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,iBAAiB,IAAI,eAAe,EAAE,CAC9E,CAAA;QACL,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;QACjE,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAA;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC1E,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACvE,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const READ_ONLY_ERROR_MESSAGE = "This CLI is authenticated in read-only mode. Re-run `tw auth login` without --read-only to enable write operations.";
|
|
2
|
+
export declare function isMutatingMethod(methodPath: string): boolean;
|
|
3
|
+
export declare function ensureWriteAllowed(): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/lib/permissions.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,wHACqF,CAAA;AA0BzH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKxD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getAuthMetadata } from './auth.js';
|
|
2
|
+
export const READ_ONLY_ERROR_MESSAGE = 'This CLI is authenticated in read-only mode. Re-run `tw auth login` without --read-only to enable write operations.';
|
|
3
|
+
/**
|
|
4
|
+
* Known read-only API method paths. Any method not in this set is assumed to be mutating.
|
|
5
|
+
* This is a safe-by-default approach: new API methods are blocked until explicitly allowed.
|
|
6
|
+
*/
|
|
7
|
+
const KNOWN_SAFE_API_METHODS = new Set([
|
|
8
|
+
'users.getSessionUser',
|
|
9
|
+
'workspaces.getWorkspaces',
|
|
10
|
+
'workspaceUsers.getWorkspaceUsers',
|
|
11
|
+
'workspaceUsers.getUserById',
|
|
12
|
+
'threads.getThread',
|
|
13
|
+
'threads.getUnread',
|
|
14
|
+
'comments.getComment',
|
|
15
|
+
'comments.getComments',
|
|
16
|
+
'channels.getChannel',
|
|
17
|
+
'channels.getChannels',
|
|
18
|
+
'conversations.getConversations',
|
|
19
|
+
'conversations.getConversation',
|
|
20
|
+
'conversations.getUnread',
|
|
21
|
+
'conversationMessages.getMessage',
|
|
22
|
+
'conversationMessages.getMessages',
|
|
23
|
+
'inbox.getInbox',
|
|
24
|
+
'batch',
|
|
25
|
+
]);
|
|
26
|
+
export function isMutatingMethod(methodPath) {
|
|
27
|
+
return !KNOWN_SAFE_API_METHODS.has(methodPath);
|
|
28
|
+
}
|
|
29
|
+
export async function ensureWriteAllowed() {
|
|
30
|
+
const metadata = await getAuthMetadata();
|
|
31
|
+
if (metadata.authMode === 'read-only') {
|
|
32
|
+
throw new Error(READ_ONLY_ERROR_MESSAGE);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/lib/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C,MAAM,CAAC,MAAM,uBAAuB,GAChC,qHAAqH,CAAA;AAEzH;;;GAGG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACnC,sBAAsB;IACtB,0BAA0B;IAC1B,kCAAkC;IAClC,4BAA4B;IAC5B,mBAAmB;IACnB,mBAAmB;IACnB,qBAAqB;IACrB,sBAAsB;IACtB,qBAAqB;IACrB,sBAAsB;IACtB,gCAAgC;IAChC,+BAA+B;IAC/B,yBAAyB;IACzB,iCAAiC;IACjC,kCAAkC;IAClC,gBAAgB;IAChB,OAAO;CACV,CAAC,CAAA;AAEF,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IAC/C,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACpC,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAA;IACxC,IAAI,QAAQ,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;IAC5C,CAAC;AACL,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const SKILL_NAME = "twist-cli";
|
|
2
2
|
export declare const SKILL_DESCRIPTION = "Twist messaging CLI for team communication";
|
|
3
|
-
export declare const SKILL_CONTENT = "# Twist CLI Skill\n\nAccess Twist messaging via the `tw` CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way.\n\n## Setup\n\n```bash\ntw auth login # OAuth login (opens browser)\ntw auth token <your-api-token> # Save API token manually\ntw auth status # Verify authentication\ntw auth logout # Remove saved token\ntw workspaces # List available workspaces\ntw workspace use <ref> # Set current workspace\ntw completion install # Install shell completions\ntw update # Update CLI to latest version\n```\n\nStored auth uses the system credential manager when available. If secure storage is unavailable, `tw` warns and falls back to `~/.config/twist-cli/config.json`. `TWIST_API_TOKEN` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.\n\n## View by URL\n\n```bash\ntw view <url> # View any Twist entity by URL\n```\n\nRoutes automatically based on URL structure:\n- Message URL \u2192 `tw msg view`\n- Conversation URL \u2192 `tw conversation view`\n- Thread+comment URL \u2192 `tw thread view` (comment ID extracted from URL)\n- Thread URL \u2192 `tw thread view`\n\nAll target command flags pass through (e.g. `--json`, `--raw`, `--full`).\n\n## Inbox\n\n```bash\ntw inbox # Show inbox threads\ntw inbox --unread # Only unread threads\ntw inbox --channel <filter> # Filter by channel name (fuzzy)\ntw inbox --since <date> # Filter by date (ISO format)\ntw inbox --limit <n> # Max items (default: 50)\n```\n\n## Threads\n\n```bash\ntw thread <thread-ref> # View thread (shorthand for view)\ntw thread view <thread-ref> # View thread with comments\ntw thread view <ref> --comment <id> # View a specific comment\ntw thread view <url-with-/c/id> # Comment ID extracted from URL\ntw thread view <ref> --unread # Show only unread comments\ntw thread view <ref> --context 3 # Include 3 read comments before unread\ntw thread view <ref> --limit 20 # Limit number of comments\ntw thread view <ref> --since <date> # Comments newer than date\ntw thread view <ref> --raw # Show raw markdown\ntw thread reply <ref> \"content\" # Post a comment\ntw thread reply <ref> \"content\" --notify EVERYONE # Notify all workspace members\ntw thread reply <ref> \"content\" --notify 123,id:456 # Notify specific user IDs\ntw thread reply <ref> \"content\" --json # Post and return comment as JSON\ntw thread reply <ref> \"content\" --json --full # Include all comment fields\ntw thread done <ref> # Archive thread (mark done)\ntw thread done <ref> --json # Archive and return status as JSON\n```\n\nDefault `--notify` is EVERYONE_IN_THREAD. Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated user ID refs.\n\n## Conversations (DMs/Groups)\n\n```bash\ntw conversation unread # List unread conversations\ntw conversation <conversation-ref> # View conversation (shorthand for view)\ntw conversation view <conversation-ref> # View conversation messages\ntw conversation with <user-ref> # Find your 1:1 DM with a user\ntw conversation with <user-ref> --snippet # Include the latest message preview\ntw conversation with <user-ref> --include-groups # List any conversations with that user\ntw conversation reply <ref> \"content\" # Send a message\ntw conversation reply <ref> \"content\" --json # Send and return message as JSON\ntw conversation reply <ref> \"content\" --json --full # Include all message fields\ntw conversation done <ref> # Archive conversation\ntw conversation done <ref> --json # Archive and return status as JSON\n```\n\nAlias: `tw convo` works the same as `tw conversation`.\n\n## Conversation Messages\n\n```bash\ntw msg <message-ref> # View a message (shorthand for view)\ntw msg view <message-ref> # View a single conversation message\ntw msg update <ref> \"content\" # Edit a conversation message\ntw msg update <ref> \"content\" --json # Edit and return updated message as JSON\ntw msg update <ref> \"content\" --json --full # Include all message fields\ntw msg delete <ref> # Delete a conversation message\ntw msg delete <ref> --json # Delete and return status as JSON\n```\n\nAlias: `tw message` works the same as `tw msg`.\n\n## Search\n\n```bash\ntw search \"query\" # Search content\ntw search \"query\" --type threads # Filter: threads, messages, or all\ntw search \"query\" --author <ref> # Filter by author\ntw search \"query\" --to <ref> # Messages sent to user\ntw search \"query\" --title-only # Search thread titles only\ntw search \"query\" --mention-me # Results mentioning current user\ntw search \"query\" --conversation <refs> # Limit to conversations (comma-separated refs)\ntw search \"query\" --since <date> # Content from date\ntw search \"query\" --until <date> # Content until date\ntw search \"query\" --channel <refs> # Filter by channel refs (comma-separated)\ntw search \"query\" --limit <n> # Max results (default: 50)\ntw search \"query\" --cursor <cur> # Pagination cursor\n```\n\n## Users & Channels\n\n```bash\ntw user # Show current user info\ntw users # List workspace users\ntw users --search <text> # Filter by name/email\ntw channels # List workspace channels\n```\n\n## Away Status\n\n```bash\ntw away # Show current away status\ntw away set <type> [until] # Set away (type: vacation, parental, sickleave, other)\ntw away set vacation 2026-03-20 # Away until March 20\ntw away set vacation 2026-03-20 --from 2026-03-15 # Custom start date\ntw away clear # Clear away status\n```\n\n## Reactions\n\n```bash\ntw react thread <ref> \uD83D\uDC4D # Add reaction to thread\ntw react comment <ref> +1 # Add reaction (shortcode)\ntw react message <ref> heart # Add reaction to DM message\ntw unreact thread <ref> \uD83D\uDC4D # Remove reaction\n```\n\nSupported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave\n\n## Shell Completions\n\n```bash\ntw completion install # Install tab completions (prompts for shell)\ntw completion install bash # Install for specific shell\ntw completion install zsh\ntw completion install fish\ntw completion uninstall # Remove completions\n```\n\n### Update\n\n```bash\ntw update # Update CLI to latest version\ntw update --check # Check for updates without installing\n```\n\n## Global Options\n\n```bash\n--no-spinner # Disable loading animations\n--progress-jsonl # Machine-readable progress events (JSONL to stderr)\n--accessible # Add text labels to color-coded output (also: TW_ACCESSIBLE=1)\n```\n\n## Output Formats\n\nAll list/view commands support:\n\n```bash\n--json # Output as JSON\n--ndjson # Output as newline-delimited JSON (for streaming)\n--full # Include all fields (default shows essential fields only)\n```\n\n## Reference System\n\nCommands accept flexible references:\n- **Numeric IDs**: `123` or `id:123`\n- **Twist URLs**: Full `https://twist.com/...` URLs (parsed automatically)\n- **Fuzzy names**: For workspaces/users - `\"My Workspace\"` or partial matches\n\n## Common Workflows\n\n**View by URL (auto-routes to the right command):**\n```bash\ntw view https://twist.com/a/1585/ch/100/t/200 # View thread\ntw view https://twist.com/a/1585/ch/100/t/200/c/300 # View comment\ntw view https://twist.com/a/1585/msg/400 # View conversation\ntw view https://twist.com/a/1585/msg/400/m/500 --json # View message as JSON\n```\n\n**Check inbox and respond:**\n```bash\ntw inbox --unread --json\ntw thread view <id> --unread\ntw thread reply <id> \"Thanks, I'll look into this.\"\ntw thread done <id>\n```\n\n**Search and review:**\n```bash\ntw search \"deployment\" --type threads --json\ntw thread view <thread-id>\n```\n\n**Check DMs:**\n```bash\ntw conversation unread --json\ntw conversation view <conversation-id>\ntw conversation with \"Alice Example\"\ntw conversation reply <id> \"Got it, thanks!\"\n```\n";
|
|
4
|
-
export declare const SKILL_FILE_CONTENT = "---\nname: twist-cli\ndescription: Twist messaging CLI for team communication\n---\n\n# Twist CLI Skill\n\nAccess Twist messaging via the `tw` CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way.\n\n## Setup\n\n```bash\ntw auth login # OAuth login (opens browser)\ntw auth token <your-api-token> # Save API token manually\ntw auth status # Verify authentication\ntw auth logout # Remove saved token\ntw workspaces # List available workspaces\ntw workspace use <ref> # Set current workspace\ntw completion install # Install shell completions\ntw update # Update CLI to latest version\n```\n\nStored auth uses the system credential manager when available. If secure storage is unavailable, `tw` warns and falls back to `~/.config/twist-cli/config.json`. `TWIST_API_TOKEN` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.\n\n## View by URL\n\n```bash\ntw view <url> # View any Twist entity by URL\n```\n\nRoutes automatically based on URL structure:\n- Message URL \u2192 `tw msg view`\n- Conversation URL \u2192 `tw conversation view`\n- Thread+comment URL \u2192 `tw thread view` (comment ID extracted from URL)\n- Thread URL \u2192 `tw thread view`\n\nAll target command flags pass through (e.g. `--json`, `--raw`, `--full`).\n\n## Inbox\n\n```bash\ntw inbox # Show inbox threads\ntw inbox --unread # Only unread threads\ntw inbox --channel <filter> # Filter by channel name (fuzzy)\ntw inbox --since <date> # Filter by date (ISO format)\ntw inbox --limit <n> # Max items (default: 50)\n```\n\n## Threads\n\n```bash\ntw thread <thread-ref> # View thread (shorthand for view)\ntw thread view <thread-ref> # View thread with comments\ntw thread view <ref> --comment <id> # View a specific comment\ntw thread view <url-with-/c/id> # Comment ID extracted from URL\ntw thread view <ref> --unread # Show only unread comments\ntw thread view <ref> --context 3 # Include 3 read comments before unread\ntw thread view <ref> --limit 20 # Limit number of comments\ntw thread view <ref> --since <date> # Comments newer than date\ntw thread view <ref> --raw # Show raw markdown\ntw thread reply <ref> \"content\" # Post a comment\ntw thread reply <ref> \"content\" --notify EVERYONE # Notify all workspace members\ntw thread reply <ref> \"content\" --notify 123,id:456 # Notify specific user IDs\ntw thread reply <ref> \"content\" --json # Post and return comment as JSON\ntw thread reply <ref> \"content\" --json --full # Include all comment fields\ntw thread done <ref> # Archive thread (mark done)\ntw thread done <ref> --json # Archive and return status as JSON\n```\n\nDefault `--notify` is EVERYONE_IN_THREAD. Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated user ID refs.\n\n## Conversations (DMs/Groups)\n\n```bash\ntw conversation unread # List unread conversations\ntw conversation <conversation-ref> # View conversation (shorthand for view)\ntw conversation view <conversation-ref> # View conversation messages\ntw conversation with <user-ref> # Find your 1:1 DM with a user\ntw conversation with <user-ref> --snippet # Include the latest message preview\ntw conversation with <user-ref> --include-groups # List any conversations with that user\ntw conversation reply <ref> \"content\" # Send a message\ntw conversation reply <ref> \"content\" --json # Send and return message as JSON\ntw conversation reply <ref> \"content\" --json --full # Include all message fields\ntw conversation done <ref> # Archive conversation\ntw conversation done <ref> --json # Archive and return status as JSON\n```\n\nAlias: `tw convo` works the same as `tw conversation`.\n\n## Conversation Messages\n\n```bash\ntw msg <message-ref> # View a message (shorthand for view)\ntw msg view <message-ref> # View a single conversation message\ntw msg update <ref> \"content\" # Edit a conversation message\ntw msg update <ref> \"content\" --json # Edit and return updated message as JSON\ntw msg update <ref> \"content\" --json --full # Include all message fields\ntw msg delete <ref> # Delete a conversation message\ntw msg delete <ref> --json # Delete and return status as JSON\n```\n\nAlias: `tw message` works the same as `tw msg`.\n\n## Search\n\n```bash\ntw search \"query\" # Search content\ntw search \"query\" --type threads # Filter: threads, messages, or all\ntw search \"query\" --author <ref> # Filter by author\ntw search \"query\" --to <ref> # Messages sent to user\ntw search \"query\" --title-only # Search thread titles only\ntw search \"query\" --mention-me # Results mentioning current user\ntw search \"query\" --conversation <refs> # Limit to conversations (comma-separated refs)\ntw search \"query\" --since <date> # Content from date\ntw search \"query\" --until <date> # Content until date\ntw search \"query\" --channel <refs> # Filter by channel refs (comma-separated)\ntw search \"query\" --limit <n> # Max results (default: 50)\ntw search \"query\" --cursor <cur> # Pagination cursor\n```\n\n## Users & Channels\n\n```bash\ntw user # Show current user info\ntw users # List workspace users\ntw users --search <text> # Filter by name/email\ntw channels # List workspace channels\n```\n\n## Away Status\n\n```bash\ntw away # Show current away status\ntw away set <type> [until] # Set away (type: vacation, parental, sickleave, other)\ntw away set vacation 2026-03-20 # Away until March 20\ntw away set vacation 2026-03-20 --from 2026-03-15 # Custom start date\ntw away clear # Clear away status\n```\n\n## Reactions\n\n```bash\ntw react thread <ref> \uD83D\uDC4D # Add reaction to thread\ntw react comment <ref> +1 # Add reaction (shortcode)\ntw react message <ref> heart # Add reaction to DM message\ntw unreact thread <ref> \uD83D\uDC4D # Remove reaction\n```\n\nSupported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave\n\n## Shell Completions\n\n```bash\ntw completion install # Install tab completions (prompts for shell)\ntw completion install bash # Install for specific shell\ntw completion install zsh\ntw completion install fish\ntw completion uninstall # Remove completions\n```\n\n### Update\n\n```bash\ntw update # Update CLI to latest version\ntw update --check # Check for updates without installing\n```\n\n## Global Options\n\n```bash\n--no-spinner # Disable loading animations\n--progress-jsonl # Machine-readable progress events (JSONL to stderr)\n--accessible # Add text labels to color-coded output (also: TW_ACCESSIBLE=1)\n```\n\n## Output Formats\n\nAll list/view commands support:\n\n```bash\n--json # Output as JSON\n--ndjson # Output as newline-delimited JSON (for streaming)\n--full # Include all fields (default shows essential fields only)\n```\n\n## Reference System\n\nCommands accept flexible references:\n- **Numeric IDs**: `123` or `id:123`\n- **Twist URLs**: Full `https://twist.com/...` URLs (parsed automatically)\n- **Fuzzy names**: For workspaces/users - `\"My Workspace\"` or partial matches\n\n## Common Workflows\n\n**View by URL (auto-routes to the right command):**\n```bash\ntw view https://twist.com/a/1585/ch/100/t/200 # View thread\ntw view https://twist.com/a/1585/ch/100/t/200/c/300 # View comment\ntw view https://twist.com/a/1585/msg/400 # View conversation\ntw view https://twist.com/a/1585/msg/400/m/500 --json # View message as JSON\n```\n\n**Check inbox and respond:**\n```bash\ntw inbox --unread --json\ntw thread view <id> --unread\ntw thread reply <id> \"Thanks, I'll look into this.\"\ntw thread done <id>\n```\n\n**Search and review:**\n```bash\ntw search \"deployment\" --type threads --json\ntw thread view <thread-id>\n```\n\n**Check DMs:**\n```bash\ntw conversation unread --json\ntw conversation view <conversation-id>\ntw conversation with \"Alice Example\"\ntw conversation reply <id> \"Got it, thanks!\"\n```\n";
|
|
3
|
+
export declare const SKILL_CONTENT = "# Twist CLI Skill\n\nAccess Twist messaging via the `tw` CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way.\n\n## Setup\n\n```bash\ntw auth login # OAuth login (opens browser, read-write)\ntw auth login --read-only # OAuth login with read-only scope\ntw auth token <your-api-token> # Save API token manually (scope unknown; assumed write-capable)\ntw auth status # Verify authentication + show mode\ntw auth logout # Remove saved token and auth metadata\ntw workspaces # List available workspaces\ntw workspace use <ref> # Set current workspace\ntw completion install # Install shell completions\ntw update # Update CLI to latest version\n```\n\nStored auth uses the system credential manager when available. If secure storage is unavailable, `tw` warns and falls back to `~/.config/twist-cli/config.json`. `TWIST_API_TOKEN` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.\n\nIn read-only mode (`tw auth login --read-only`), commands that modify Twist data (reply, archive, react, delete, etc.) are blocked by the CLI. Externally provided tokens (`TWIST_API_TOKEN` or `tw auth token`) are treated as unknown scope and assumed write-capable.\n\n## View by URL\n\n```bash\ntw view <url> # View any Twist entity by URL\n```\n\nRoutes automatically based on URL structure:\n- Message URL \u2192 `tw msg view`\n- Conversation URL \u2192 `tw conversation view`\n- Thread+comment URL \u2192 `tw thread view` (comment ID extracted from URL)\n- Thread URL \u2192 `tw thread view`\n\nAll target command flags pass through (e.g. `--json`, `--raw`, `--full`).\n\n## Inbox\n\n```bash\ntw inbox # Show inbox threads\ntw inbox --unread # Only unread threads\ntw inbox --channel <filter> # Filter by channel name (fuzzy)\ntw inbox --since <date> # Filter by date (ISO format)\ntw inbox --limit <n> # Max items (default: 50)\n```\n\n## Threads\n\n```bash\ntw thread <thread-ref> # View thread (shorthand for view)\ntw thread view <thread-ref> # View thread with comments\ntw thread view <ref> --comment <id> # View a specific comment\ntw thread view <url-with-/c/id> # Comment ID extracted from URL\ntw thread view <ref> --unread # Show only unread comments\ntw thread view <ref> --context 3 # Include 3 read comments before unread\ntw thread view <ref> --limit 20 # Limit number of comments\ntw thread view <ref> --since <date> # Comments newer than date\ntw thread view <ref> --raw # Show raw markdown\ntw thread reply <ref> \"content\" # Post a comment\ntw thread reply <ref> \"content\" --notify EVERYONE # Notify all workspace members\ntw thread reply <ref> \"content\" --notify 123,id:456 # Notify specific user IDs\ntw thread reply <ref> \"content\" --json # Post and return comment as JSON\ntw thread reply <ref> \"content\" --json --full # Include all comment fields\ntw thread done <ref> # Archive thread (mark done)\ntw thread done <ref> --json # Archive and return status as JSON\n```\n\nDefault `--notify` is EVERYONE_IN_THREAD. Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated user ID refs.\n\n## Conversations (DMs/Groups)\n\n```bash\ntw conversation unread # List unread conversations\ntw conversation <conversation-ref> # View conversation (shorthand for view)\ntw conversation view <conversation-ref> # View conversation messages\ntw conversation with <user-ref> # Find your 1:1 DM with a user\ntw conversation with <user-ref> --snippet # Include the latest message preview\ntw conversation with <user-ref> --include-groups # List any conversations with that user\ntw conversation reply <ref> \"content\" # Send a message\ntw conversation reply <ref> \"content\" --json # Send and return message as JSON\ntw conversation reply <ref> \"content\" --json --full # Include all message fields\ntw conversation done <ref> # Archive conversation\ntw conversation done <ref> --json # Archive and return status as JSON\n```\n\nAlias: `tw convo` works the same as `tw conversation`.\n\n## Conversation Messages\n\n```bash\ntw msg <message-ref> # View a message (shorthand for view)\ntw msg view <message-ref> # View a single conversation message\ntw msg update <ref> \"content\" # Edit a conversation message\ntw msg update <ref> \"content\" --json # Edit and return updated message as JSON\ntw msg update <ref> \"content\" --json --full # Include all message fields\ntw msg delete <ref> # Delete a conversation message\ntw msg delete <ref> --json # Delete and return status as JSON\n```\n\nAlias: `tw message` works the same as `tw msg`.\n\n## Search\n\n```bash\ntw search \"query\" # Search content\ntw search \"query\" --type threads # Filter: threads, messages, or all\ntw search \"query\" --author <ref> # Filter by author\ntw search \"query\" --to <ref> # Messages sent to user\ntw search \"query\" --title-only # Search thread titles only\ntw search \"query\" --mention-me # Results mentioning current user\ntw search \"query\" --conversation <refs> # Limit to conversations (comma-separated refs)\ntw search \"query\" --since <date> # Content from date\ntw search \"query\" --until <date> # Content until date\ntw search \"query\" --channel <refs> # Filter by channel refs (comma-separated)\ntw search \"query\" --limit <n> # Max results (default: 50)\ntw search \"query\" --cursor <cur> # Pagination cursor\n```\n\n## Users & Channels\n\n```bash\ntw user # Show current user info\ntw users # List workspace users\ntw users --search <text> # Filter by name/email\ntw channels # List workspace channels\n```\n\n## Away Status\n\n```bash\ntw away # Show current away status\ntw away set <type> [until] # Set away (type: vacation, parental, sickleave, other)\ntw away set vacation 2026-03-20 # Away until March 20\ntw away set vacation 2026-03-20 --from 2026-03-15 # Custom start date\ntw away clear # Clear away status\n```\n\n## Reactions\n\n```bash\ntw react thread <ref> \uD83D\uDC4D # Add reaction to thread\ntw react comment <ref> +1 # Add reaction (shortcode)\ntw react message <ref> heart # Add reaction to DM message\ntw unreact thread <ref> \uD83D\uDC4D # Remove reaction\n```\n\nSupported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave\n\n## Shell Completions\n\n```bash\ntw completion install # Install tab completions (prompts for shell)\ntw completion install bash # Install for specific shell\ntw completion install zsh\ntw completion install fish\ntw completion uninstall # Remove completions\n```\n\n### Update\n\n```bash\ntw update # Update CLI to latest version\ntw update --check # Check for updates without installing\n```\n\n## Global Options\n\n```bash\n--no-spinner # Disable loading animations\n--progress-jsonl # Machine-readable progress events (JSONL to stderr)\n--accessible # Add text labels to color-coded output (also: TW_ACCESSIBLE=1)\n```\n\n## Output Formats\n\nAll list/view commands support:\n\n```bash\n--json # Output as JSON\n--ndjson # Output as newline-delimited JSON (for streaming)\n--full # Include all fields (default shows essential fields only)\n```\n\n## Reference System\n\nCommands accept flexible references:\n- **Numeric IDs**: `123` or `id:123`\n- **Twist URLs**: Full `https://twist.com/...` URLs (parsed automatically)\n- **Fuzzy names**: For workspaces/users - `\"My Workspace\"` or partial matches\n\n## Common Workflows\n\n**View by URL (auto-routes to the right command):**\n```bash\ntw view https://twist.com/a/1585/ch/100/t/200 # View thread\ntw view https://twist.com/a/1585/ch/100/t/200/c/300 # View comment\ntw view https://twist.com/a/1585/msg/400 # View conversation\ntw view https://twist.com/a/1585/msg/400/m/500 --json # View message as JSON\n```\n\n**Check inbox and respond:**\n```bash\ntw inbox --unread --json\ntw thread view <id> --unread\ntw thread reply <id> \"Thanks, I'll look into this.\"\ntw thread done <id>\n```\n\n**Search and review:**\n```bash\ntw search \"deployment\" --type threads --json\ntw thread view <thread-id>\n```\n\n**Check DMs:**\n```bash\ntw conversation unread --json\ntw conversation view <conversation-id>\ntw conversation with \"Alice Example\"\ntw conversation reply <id> \"Got it, thanks!\"\n```\n";
|
|
4
|
+
export declare const SKILL_FILE_CONTENT = "---\nname: twist-cli\ndescription: Twist messaging CLI for team communication\n---\n\n# Twist CLI Skill\n\nAccess Twist messaging via the `tw` CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way.\n\n## Setup\n\n```bash\ntw auth login # OAuth login (opens browser, read-write)\ntw auth login --read-only # OAuth login with read-only scope\ntw auth token <your-api-token> # Save API token manually (scope unknown; assumed write-capable)\ntw auth status # Verify authentication + show mode\ntw auth logout # Remove saved token and auth metadata\ntw workspaces # List available workspaces\ntw workspace use <ref> # Set current workspace\ntw completion install # Install shell completions\ntw update # Update CLI to latest version\n```\n\nStored auth uses the system credential manager when available. If secure storage is unavailable, `tw` warns and falls back to `~/.config/twist-cli/config.json`. `TWIST_API_TOKEN` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.\n\nIn read-only mode (`tw auth login --read-only`), commands that modify Twist data (reply, archive, react, delete, etc.) are blocked by the CLI. Externally provided tokens (`TWIST_API_TOKEN` or `tw auth token`) are treated as unknown scope and assumed write-capable.\n\n## View by URL\n\n```bash\ntw view <url> # View any Twist entity by URL\n```\n\nRoutes automatically based on URL structure:\n- Message URL \u2192 `tw msg view`\n- Conversation URL \u2192 `tw conversation view`\n- Thread+comment URL \u2192 `tw thread view` (comment ID extracted from URL)\n- Thread URL \u2192 `tw thread view`\n\nAll target command flags pass through (e.g. `--json`, `--raw`, `--full`).\n\n## Inbox\n\n```bash\ntw inbox # Show inbox threads\ntw inbox --unread # Only unread threads\ntw inbox --channel <filter> # Filter by channel name (fuzzy)\ntw inbox --since <date> # Filter by date (ISO format)\ntw inbox --limit <n> # Max items (default: 50)\n```\n\n## Threads\n\n```bash\ntw thread <thread-ref> # View thread (shorthand for view)\ntw thread view <thread-ref> # View thread with comments\ntw thread view <ref> --comment <id> # View a specific comment\ntw thread view <url-with-/c/id> # Comment ID extracted from URL\ntw thread view <ref> --unread # Show only unread comments\ntw thread view <ref> --context 3 # Include 3 read comments before unread\ntw thread view <ref> --limit 20 # Limit number of comments\ntw thread view <ref> --since <date> # Comments newer than date\ntw thread view <ref> --raw # Show raw markdown\ntw thread reply <ref> \"content\" # Post a comment\ntw thread reply <ref> \"content\" --notify EVERYONE # Notify all workspace members\ntw thread reply <ref> \"content\" --notify 123,id:456 # Notify specific user IDs\ntw thread reply <ref> \"content\" --json # Post and return comment as JSON\ntw thread reply <ref> \"content\" --json --full # Include all comment fields\ntw thread done <ref> # Archive thread (mark done)\ntw thread done <ref> --json # Archive and return status as JSON\n```\n\nDefault `--notify` is EVERYONE_IN_THREAD. Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated user ID refs.\n\n## Conversations (DMs/Groups)\n\n```bash\ntw conversation unread # List unread conversations\ntw conversation <conversation-ref> # View conversation (shorthand for view)\ntw conversation view <conversation-ref> # View conversation messages\ntw conversation with <user-ref> # Find your 1:1 DM with a user\ntw conversation with <user-ref> --snippet # Include the latest message preview\ntw conversation with <user-ref> --include-groups # List any conversations with that user\ntw conversation reply <ref> \"content\" # Send a message\ntw conversation reply <ref> \"content\" --json # Send and return message as JSON\ntw conversation reply <ref> \"content\" --json --full # Include all message fields\ntw conversation done <ref> # Archive conversation\ntw conversation done <ref> --json # Archive and return status as JSON\n```\n\nAlias: `tw convo` works the same as `tw conversation`.\n\n## Conversation Messages\n\n```bash\ntw msg <message-ref> # View a message (shorthand for view)\ntw msg view <message-ref> # View a single conversation message\ntw msg update <ref> \"content\" # Edit a conversation message\ntw msg update <ref> \"content\" --json # Edit and return updated message as JSON\ntw msg update <ref> \"content\" --json --full # Include all message fields\ntw msg delete <ref> # Delete a conversation message\ntw msg delete <ref> --json # Delete and return status as JSON\n```\n\nAlias: `tw message` works the same as `tw msg`.\n\n## Search\n\n```bash\ntw search \"query\" # Search content\ntw search \"query\" --type threads # Filter: threads, messages, or all\ntw search \"query\" --author <ref> # Filter by author\ntw search \"query\" --to <ref> # Messages sent to user\ntw search \"query\" --title-only # Search thread titles only\ntw search \"query\" --mention-me # Results mentioning current user\ntw search \"query\" --conversation <refs> # Limit to conversations (comma-separated refs)\ntw search \"query\" --since <date> # Content from date\ntw search \"query\" --until <date> # Content until date\ntw search \"query\" --channel <refs> # Filter by channel refs (comma-separated)\ntw search \"query\" --limit <n> # Max results (default: 50)\ntw search \"query\" --cursor <cur> # Pagination cursor\n```\n\n## Users & Channels\n\n```bash\ntw user # Show current user info\ntw users # List workspace users\ntw users --search <text> # Filter by name/email\ntw channels # List workspace channels\n```\n\n## Away Status\n\n```bash\ntw away # Show current away status\ntw away set <type> [until] # Set away (type: vacation, parental, sickleave, other)\ntw away set vacation 2026-03-20 # Away until March 20\ntw away set vacation 2026-03-20 --from 2026-03-15 # Custom start date\ntw away clear # Clear away status\n```\n\n## Reactions\n\n```bash\ntw react thread <ref> \uD83D\uDC4D # Add reaction to thread\ntw react comment <ref> +1 # Add reaction (shortcode)\ntw react message <ref> heart # Add reaction to DM message\ntw unreact thread <ref> \uD83D\uDC4D # Remove reaction\n```\n\nSupported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave\n\n## Shell Completions\n\n```bash\ntw completion install # Install tab completions (prompts for shell)\ntw completion install bash # Install for specific shell\ntw completion install zsh\ntw completion install fish\ntw completion uninstall # Remove completions\n```\n\n### Update\n\n```bash\ntw update # Update CLI to latest version\ntw update --check # Check for updates without installing\n```\n\n## Global Options\n\n```bash\n--no-spinner # Disable loading animations\n--progress-jsonl # Machine-readable progress events (JSONL to stderr)\n--accessible # Add text labels to color-coded output (also: TW_ACCESSIBLE=1)\n```\n\n## Output Formats\n\nAll list/view commands support:\n\n```bash\n--json # Output as JSON\n--ndjson # Output as newline-delimited JSON (for streaming)\n--full # Include all fields (default shows essential fields only)\n```\n\n## Reference System\n\nCommands accept flexible references:\n- **Numeric IDs**: `123` or `id:123`\n- **Twist URLs**: Full `https://twist.com/...` URLs (parsed automatically)\n- **Fuzzy names**: For workspaces/users - `\"My Workspace\"` or partial matches\n\n## Common Workflows\n\n**View by URL (auto-routes to the right command):**\n```bash\ntw view https://twist.com/a/1585/ch/100/t/200 # View thread\ntw view https://twist.com/a/1585/ch/100/t/200/c/300 # View comment\ntw view https://twist.com/a/1585/msg/400 # View conversation\ntw view https://twist.com/a/1585/msg/400/m/500 --json # View message as JSON\n```\n\n**Check inbox and respond:**\n```bash\ntw inbox --unread --json\ntw thread view <id> --unread\ntw thread reply <id> \"Thanks, I'll look into this.\"\ntw thread done <id>\n```\n\n**Search and review:**\n```bash\ntw search \"deployment\" --type threads --json\ntw thread view <thread-id>\n```\n\n**Check DMs:**\n```bash\ntw conversation unread --json\ntw conversation view <conversation-id>\ntw conversation with \"Alice Example\"\ntw conversation reply <id> \"Got it, thanks!\"\n```\n";
|
|
5
5
|
//# sourceMappingURL=content.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,cAAc,CAAA;AAErC,eAAO,MAAM,iBAAiB,+CAA+C,CAAA;AAE7E,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,cAAc,CAAA;AAErC,eAAO,MAAM,iBAAiB,+CAA+C,CAAA;AAE7E,eAAO,MAAM,aAAa,wsRA6NzB,CAAA;AAED,eAAO,MAAM,kBAAkB,8xRAKd,CAAA"}
|
|
@@ -7,10 +7,11 @@ Access Twist messaging via the \`tw\` CLI. Use when the user asks about their Tw
|
|
|
7
7
|
## Setup
|
|
8
8
|
|
|
9
9
|
\`\`\`bash
|
|
10
|
-
tw auth login # OAuth login (opens browser)
|
|
11
|
-
tw auth
|
|
12
|
-
tw auth
|
|
13
|
-
tw auth
|
|
10
|
+
tw auth login # OAuth login (opens browser, read-write)
|
|
11
|
+
tw auth login --read-only # OAuth login with read-only scope
|
|
12
|
+
tw auth token <your-api-token> # Save API token manually (scope unknown; assumed write-capable)
|
|
13
|
+
tw auth status # Verify authentication + show mode
|
|
14
|
+
tw auth logout # Remove saved token and auth metadata
|
|
14
15
|
tw workspaces # List available workspaces
|
|
15
16
|
tw workspace use <ref> # Set current workspace
|
|
16
17
|
tw completion install # Install shell completions
|
|
@@ -19,6 +20,8 @@ tw update # Update CLI to latest version
|
|
|
19
20
|
|
|
20
21
|
Stored auth uses the system credential manager when available. If secure storage is unavailable, \`tw\` warns and falls back to \`~/.config/twist-cli/config.json\`. \`TWIST_API_TOKEN\` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.
|
|
21
22
|
|
|
23
|
+
In read-only mode (\`tw auth login --read-only\`), commands that modify Twist data (reply, archive, react, delete, etc.) are blocked by the CLI. Externally provided tokens (\`TWIST_API_TOKEN\` or \`tw auth token\`) are treated as unknown scope and assumed write-capable.
|
|
24
|
+
|
|
22
25
|
## View by URL
|
|
23
26
|
|
|
24
27
|
\`\`\`bash
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAA;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,4CAA4C,CAAA;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAA;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,4CAA4C,CAAA;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6N5B,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG;QAC1B,UAAU;eACH,iBAAiB;;;EAG9B,aAAa,EAAE,CAAA"}
|