@doist/twist-cli 2.21.1 → 2.21.3
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 +12 -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 +183 -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 +5 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/lib/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function includePrivateChannels(): boolean;
|
|
2
|
+
export declare function getPublicChannelIds(workspaceId: number): Promise<Set<number>>;
|
|
3
|
+
export declare function clearPublicChannelCache(): void;
|
|
4
|
+
export declare function assertChannelIsPublic(channelId: number, workspaceId: number): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=public-channels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-channels.d.ts","sourceRoot":"","sources":["../../src/lib/public-channels.ts"],"names":[],"mappings":"AAEA,wBAAgB,sBAAsB,IAAI,OAAO,CAMhD;AAID,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAYnF;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getTwistClient } from './api.js';
|
|
2
|
+
export function includePrivateChannels() {
|
|
3
|
+
const envVal = process.env.TWIST_INCLUDE_PRIVATE_CHANNELS;
|
|
4
|
+
if (envVal === '1' || envVal === 'true') {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
return process.argv.includes('--include-private-channels');
|
|
8
|
+
}
|
|
9
|
+
const publicChannelCache = new Map();
|
|
10
|
+
export async function getPublicChannelIds(workspaceId) {
|
|
11
|
+
const cached = publicChannelCache.get(workspaceId);
|
|
12
|
+
if (cached)
|
|
13
|
+
return cached;
|
|
14
|
+
const client = await getTwistClient();
|
|
15
|
+
const channels = await client.channels.getChannels({ workspaceId });
|
|
16
|
+
const publicIds = new Set();
|
|
17
|
+
for (const ch of channels) {
|
|
18
|
+
if (ch.public)
|
|
19
|
+
publicIds.add(ch.id);
|
|
20
|
+
}
|
|
21
|
+
publicChannelCache.set(workspaceId, publicIds);
|
|
22
|
+
return publicIds;
|
|
23
|
+
}
|
|
24
|
+
export function clearPublicChannelCache() {
|
|
25
|
+
publicChannelCache.clear();
|
|
26
|
+
}
|
|
27
|
+
export async function assertChannelIsPublic(channelId, workspaceId) {
|
|
28
|
+
if (includePrivateChannels())
|
|
29
|
+
return;
|
|
30
|
+
const publicIds = await getPublicChannelIds(workspaceId);
|
|
31
|
+
if (!publicIds.has(channelId)) {
|
|
32
|
+
throw new Error('This thread belongs to a private channel. Use --include-private-channels to access it.');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=public-channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-channels.js","sourceRoot":"","sources":["../../src/lib/public-channels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAEzC,MAAM,UAAU,sBAAsB;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAA;IACzD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtC,OAAO,IAAI,CAAA;IACf,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAuB,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,WAAmB;IACzD,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAClD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAA;IACrC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC,CAAA;IACnE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;IACnC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC,MAAM;YAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAC9C,OAAO,SAAS,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,uBAAuB;IACnC,kBAAkB,CAAC,KAAK,EAAE,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAiB,EAAE,WAAmB;IAC9E,IAAI,sBAAsB,EAAE;QAAE,OAAM;IACpC,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAA;IACxD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACX,wFAAwF,CAC3F,CAAA;IACL,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Workspace } from '@doist/twist-sdk';
|
|
2
|
+
export declare function isIdRef(ref: string): boolean;
|
|
3
|
+
export declare function extractId(ref: string): number;
|
|
4
|
+
export declare function looksLikeRawId(ref: string): boolean;
|
|
5
|
+
export interface ParsedTwistUrl {
|
|
6
|
+
workspaceId?: number;
|
|
7
|
+
channelId?: number;
|
|
8
|
+
threadId?: number;
|
|
9
|
+
commentId?: number;
|
|
10
|
+
conversationId?: number;
|
|
11
|
+
messageId?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function parseTwistUrl(url: string): ParsedTwistUrl | null;
|
|
14
|
+
export declare function parseRef(ref: string): {
|
|
15
|
+
type: 'id';
|
|
16
|
+
id: number;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'url';
|
|
19
|
+
parsed: ParsedTwistUrl;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'name';
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function resolveWorkspaceRef(ref: string): Promise<Workspace>;
|
|
25
|
+
export declare function resolveThreadId(ref: string): number;
|
|
26
|
+
export declare function resolveChannelId(ref: string): number;
|
|
27
|
+
export declare function resolveCommentId(ref: string): number;
|
|
28
|
+
export declare function resolveConversationId(ref: string): number;
|
|
29
|
+
export declare function resolveMessageId(ref: string): number;
|
|
30
|
+
export type TwistUrlRoute = {
|
|
31
|
+
entityType: 'message' | 'conversation' | 'comment' | 'thread';
|
|
32
|
+
url: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function classifyTwistUrl(url: string): TwistUrlRoute | null;
|
|
35
|
+
export declare function parseUserIdRefs(refs: string): number[];
|
|
36
|
+
export declare function resolveUserRefs(refs: string, workspaceId: number): Promise<number[]>;
|
|
37
|
+
//# sourceMappingURL=refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../src/lib/refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAOjD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE5C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAInD;AAED,MAAM,WAAW,cAAc;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CA8ChE;AAED,wBAAgB,QAAQ,CACpB,GAAG,EAAE,MAAM,GAET;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAmBnC;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAqCzE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYnD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYzD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYpD;AAED,MAAM,MAAM,aAAa,GAAG;IACxB,UAAU,EAAE,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAA;IAC7D,GAAG,EAAE,MAAM,CAAA;CACd,CAAA;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAUlE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBtD;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgC1F"}
|
package/dist/lib/refs.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { fetchWorkspaces } from './api.js';
|
|
2
|
+
function normalizeRef(ref) {
|
|
3
|
+
return ref.trim();
|
|
4
|
+
}
|
|
5
|
+
export function isIdRef(ref) {
|
|
6
|
+
return normalizeRef(ref).startsWith('id:');
|
|
7
|
+
}
|
|
8
|
+
export function extractId(ref) {
|
|
9
|
+
const normalized = normalizeRef(ref);
|
|
10
|
+
const idStr = isIdRef(normalized) ? normalized.slice(3).trim() : normalized;
|
|
11
|
+
if (!/^\d+$/.test(idStr)) {
|
|
12
|
+
throw new Error(`Invalid ID: ${ref}`);
|
|
13
|
+
}
|
|
14
|
+
return Number(idStr);
|
|
15
|
+
}
|
|
16
|
+
export function looksLikeRawId(ref) {
|
|
17
|
+
const normalized = normalizeRef(ref);
|
|
18
|
+
if (!normalized || normalized.includes(' '))
|
|
19
|
+
return false;
|
|
20
|
+
return /^\d+$/.test(normalized) || (/[a-zA-Z]/.test(normalized) && /\d/.test(normalized));
|
|
21
|
+
}
|
|
22
|
+
export function parseTwistUrl(url) {
|
|
23
|
+
try {
|
|
24
|
+
const parsed = new URL(url);
|
|
25
|
+
if (!parsed.hostname.includes('twist.com')) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const path = parsed.pathname;
|
|
29
|
+
const result = {};
|
|
30
|
+
// Pattern: /a/{workspaceId}/ch/{channelId}/t/{threadId}/c/{commentId}
|
|
31
|
+
// Pattern: /a/{workspaceId}/msg/{conversationId}/m/{messageId}
|
|
32
|
+
const workspaceMatch = path.match(/\/a\/(\d+)/);
|
|
33
|
+
if (workspaceMatch) {
|
|
34
|
+
result.workspaceId = parseInt(workspaceMatch[1], 10);
|
|
35
|
+
}
|
|
36
|
+
const channelMatch = path.match(/\/ch\/(\d+)/);
|
|
37
|
+
if (channelMatch) {
|
|
38
|
+
result.channelId = parseInt(channelMatch[1], 10);
|
|
39
|
+
}
|
|
40
|
+
const threadMatch = path.match(/\/t\/(\d+)/);
|
|
41
|
+
if (threadMatch) {
|
|
42
|
+
result.threadId = parseInt(threadMatch[1], 10);
|
|
43
|
+
}
|
|
44
|
+
const commentMatch = path.match(/\/c\/(\d+)/);
|
|
45
|
+
if (commentMatch) {
|
|
46
|
+
result.commentId = parseInt(commentMatch[1], 10);
|
|
47
|
+
}
|
|
48
|
+
const conversationMatch = path.match(/\/msg\/(\d+)/);
|
|
49
|
+
if (conversationMatch) {
|
|
50
|
+
result.conversationId = parseInt(conversationMatch[1], 10);
|
|
51
|
+
}
|
|
52
|
+
const messageMatch = path.match(/\/m\/(\d+)/);
|
|
53
|
+
if (messageMatch) {
|
|
54
|
+
result.messageId = parseInt(messageMatch[1], 10);
|
|
55
|
+
}
|
|
56
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function parseRef(ref) {
|
|
63
|
+
const normalized = normalizeRef(ref);
|
|
64
|
+
if (isIdRef(normalized)) {
|
|
65
|
+
return { type: 'id', id: extractId(normalized) };
|
|
66
|
+
}
|
|
67
|
+
if (normalized.startsWith('http://') || normalized.startsWith('https://')) {
|
|
68
|
+
const parsed = parseTwistUrl(normalized);
|
|
69
|
+
if (parsed) {
|
|
70
|
+
return { type: 'url', parsed };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (/^\d+$/.test(normalized)) {
|
|
74
|
+
return { type: 'id', id: Number(normalized) };
|
|
75
|
+
}
|
|
76
|
+
return { type: 'name', name: normalized };
|
|
77
|
+
}
|
|
78
|
+
export async function resolveWorkspaceRef(ref) {
|
|
79
|
+
const workspaces = await fetchWorkspaces();
|
|
80
|
+
const parsed = parseRef(ref);
|
|
81
|
+
if (parsed.type === 'id') {
|
|
82
|
+
const workspace = workspaces.find((w) => w.id === parsed.id);
|
|
83
|
+
if (!workspace) {
|
|
84
|
+
throw new Error(`Workspace with ID ${parsed.id} not found`);
|
|
85
|
+
}
|
|
86
|
+
return workspace;
|
|
87
|
+
}
|
|
88
|
+
if (parsed.type === 'url' && parsed.parsed.workspaceId) {
|
|
89
|
+
const workspace = workspaces.find((w) => w.id === parsed.parsed.workspaceId);
|
|
90
|
+
if (!workspace) {
|
|
91
|
+
throw new Error(`Workspace with ID ${parsed.parsed.workspaceId} not found`);
|
|
92
|
+
}
|
|
93
|
+
return workspace;
|
|
94
|
+
}
|
|
95
|
+
if (parsed.type === 'name') {
|
|
96
|
+
const lower = parsed.name.toLowerCase();
|
|
97
|
+
const exact = workspaces.find((w) => w.name.toLowerCase() === lower);
|
|
98
|
+
if (exact)
|
|
99
|
+
return exact;
|
|
100
|
+
const partial = workspaces.filter((w) => w.name.toLowerCase().includes(lower));
|
|
101
|
+
if (partial.length === 1)
|
|
102
|
+
return partial[0];
|
|
103
|
+
if (partial.length > 1) {
|
|
104
|
+
const matches = partial
|
|
105
|
+
.slice(0, 5)
|
|
106
|
+
.map((w) => `"${w.name}" (id:${w.id})`)
|
|
107
|
+
.join(', ');
|
|
108
|
+
throw new Error(`Multiple workspaces match "${ref}": ${matches}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`Workspace "${ref}" not found`);
|
|
112
|
+
}
|
|
113
|
+
export function resolveThreadId(ref) {
|
|
114
|
+
const parsed = parseRef(ref);
|
|
115
|
+
if (parsed.type === 'id') {
|
|
116
|
+
return parsed.id;
|
|
117
|
+
}
|
|
118
|
+
if (parsed.type === 'url' && parsed.parsed.threadId) {
|
|
119
|
+
return parsed.parsed.threadId;
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`Invalid thread reference: ${ref}. Use 123, id:123, or a Twist URL.`);
|
|
122
|
+
}
|
|
123
|
+
export function resolveChannelId(ref) {
|
|
124
|
+
const parsed = parseRef(ref);
|
|
125
|
+
if (parsed.type === 'id') {
|
|
126
|
+
return parsed.id;
|
|
127
|
+
}
|
|
128
|
+
if (parsed.type === 'url' && parsed.parsed.channelId) {
|
|
129
|
+
return parsed.parsed.channelId;
|
|
130
|
+
}
|
|
131
|
+
throw new Error(`Invalid channel reference: ${ref}. Use 123, id:123, or a Twist URL.`);
|
|
132
|
+
}
|
|
133
|
+
export function resolveCommentId(ref) {
|
|
134
|
+
const parsed = parseRef(ref);
|
|
135
|
+
if (parsed.type === 'id') {
|
|
136
|
+
return parsed.id;
|
|
137
|
+
}
|
|
138
|
+
if (parsed.type === 'url' && parsed.parsed.commentId) {
|
|
139
|
+
return parsed.parsed.commentId;
|
|
140
|
+
}
|
|
141
|
+
throw new Error(`Invalid comment reference: ${ref}. Use 123, id:123, or a Twist URL.`);
|
|
142
|
+
}
|
|
143
|
+
export function resolveConversationId(ref) {
|
|
144
|
+
const parsed = parseRef(ref);
|
|
145
|
+
if (parsed.type === 'id') {
|
|
146
|
+
return parsed.id;
|
|
147
|
+
}
|
|
148
|
+
if (parsed.type === 'url' && parsed.parsed.conversationId) {
|
|
149
|
+
return parsed.parsed.conversationId;
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`Invalid conversation reference: ${ref}. Use 123, id:123, or a Twist URL.`);
|
|
152
|
+
}
|
|
153
|
+
export function resolveMessageId(ref) {
|
|
154
|
+
const parsed = parseRef(ref);
|
|
155
|
+
if (parsed.type === 'id') {
|
|
156
|
+
return parsed.id;
|
|
157
|
+
}
|
|
158
|
+
if (parsed.type === 'url' && parsed.parsed.messageId) {
|
|
159
|
+
return parsed.parsed.messageId;
|
|
160
|
+
}
|
|
161
|
+
throw new Error(`Invalid message reference: ${ref}. Use 123, id:123, or a Twist URL.`);
|
|
162
|
+
}
|
|
163
|
+
export function classifyTwistUrl(url) {
|
|
164
|
+
const parsed = parseTwistUrl(url);
|
|
165
|
+
if (!parsed)
|
|
166
|
+
return null;
|
|
167
|
+
if (parsed.messageId)
|
|
168
|
+
return { entityType: 'message', url };
|
|
169
|
+
if (parsed.conversationId && !parsed.messageId)
|
|
170
|
+
return { entityType: 'conversation', url };
|
|
171
|
+
if (parsed.commentId)
|
|
172
|
+
return { entityType: 'comment', url };
|
|
173
|
+
if (parsed.threadId && !parsed.commentId)
|
|
174
|
+
return { entityType: 'thread', url };
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
export function parseUserIdRefs(refs) {
|
|
178
|
+
return refs.split(',').map((userRef) => {
|
|
179
|
+
const trimmed = userRef.trim();
|
|
180
|
+
if (!trimmed) {
|
|
181
|
+
console.error('Invalid user reference list: found empty value');
|
|
182
|
+
process.exit(1);
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
return extractId(trimmed);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
console.error(`Invalid user reference: ${trimmed}. Use 123 or id:123`);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
return 0;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
export async function resolveUserRefs(refs, workspaceId) {
|
|
196
|
+
const { getWorkspaceUsers } = await import('./api.js');
|
|
197
|
+
const users = await getWorkspaceUsers(workspaceId);
|
|
198
|
+
const parts = refs.split(',').map((r) => r.trim());
|
|
199
|
+
const ids = [];
|
|
200
|
+
for (const ref of parts) {
|
|
201
|
+
const parsed = parseRef(ref);
|
|
202
|
+
if (parsed.type === 'id') {
|
|
203
|
+
ids.push(parsed.id);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const query = ref.toLowerCase();
|
|
207
|
+
const matches = users.filter((u) => u.name.toLowerCase().includes(query) || u.email?.toLowerCase().includes(query));
|
|
208
|
+
if (matches.length === 0) {
|
|
209
|
+
throw new Error(`No user found matching "${ref}"`);
|
|
210
|
+
}
|
|
211
|
+
if (matches.length > 1) {
|
|
212
|
+
const list = matches.map((u) => ` ${u.id} ${u.name} <${u.email ?? ''}>`).join('\n');
|
|
213
|
+
throw new Error(`Multiple users match "${ref}":\n${list}\n\nUse numeric ID to specify.`);
|
|
214
|
+
}
|
|
215
|
+
ids.push(matches[0].id);
|
|
216
|
+
}
|
|
217
|
+
return ids;
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../../src/lib/refs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SearchResult } from '@doist/twist-sdk';
|
|
2
|
+
export type SearchType = 'threads' | 'messages' | 'all';
|
|
3
|
+
export interface ExtendedSearchParams {
|
|
4
|
+
workspaceId: number;
|
|
5
|
+
query?: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
type?: SearchType;
|
|
8
|
+
channelIds?: number[];
|
|
9
|
+
conversationIds?: number[];
|
|
10
|
+
authorIds?: number[];
|
|
11
|
+
toUserIds?: number[];
|
|
12
|
+
mentionSelf?: boolean;
|
|
13
|
+
dateFrom?: string;
|
|
14
|
+
dateTo?: string;
|
|
15
|
+
limit?: number;
|
|
16
|
+
cursor?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ExtendedSearchResponse {
|
|
19
|
+
items: SearchResult[];
|
|
20
|
+
nextCursorMark?: string;
|
|
21
|
+
hasMore: boolean;
|
|
22
|
+
isPlanRestricted: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function extendedSearch(params: ExtendedSearchParams): Promise<ExtendedSearchResponse>;
|
|
25
|
+
//# sourceMappingURL=search-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-api.d.ts","sourceRoot":"","sources":["../../src/lib/search-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAKpD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,gBAAgB,EAAE,OAAO,CAAA;CAC5B;AA8BD,wBAAsB,cAAc,CAChC,MAAM,EAAE,oBAAoB,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CAqDjC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { getApiToken } from './auth.js';
|
|
2
|
+
const BASE_URL = 'https://api.twist.com/api/v3';
|
|
3
|
+
function toCamelCase(str) {
|
|
4
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
5
|
+
}
|
|
6
|
+
function camelCaseKeys(obj) {
|
|
7
|
+
if (Array.isArray(obj)) {
|
|
8
|
+
return obj.map((item) => camelCaseKeys(item));
|
|
9
|
+
}
|
|
10
|
+
if (obj !== null && typeof obj === 'object') {
|
|
11
|
+
const result = {};
|
|
12
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
13
|
+
const camelKey = toCamelCase(key);
|
|
14
|
+
result[camelKey] = camelCaseKeys(value);
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
return obj;
|
|
19
|
+
}
|
|
20
|
+
function transformSearchResult(item) {
|
|
21
|
+
const result = camelCaseKeys(item);
|
|
22
|
+
if (typeof result.snippetLastUpdatedTs === 'number') {
|
|
23
|
+
result.snippetLastUpdated = new Date(result.snippetLastUpdatedTs * 1000);
|
|
24
|
+
delete result.snippetLastUpdatedTs;
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
export async function extendedSearch(params) {
|
|
29
|
+
const token = await getApiToken();
|
|
30
|
+
const apiParams = {
|
|
31
|
+
workspace_id: params.workspaceId,
|
|
32
|
+
};
|
|
33
|
+
if (params.query)
|
|
34
|
+
apiParams.query = params.query;
|
|
35
|
+
if (params.title) {
|
|
36
|
+
apiParams.title = params.title;
|
|
37
|
+
if (!params.query)
|
|
38
|
+
apiParams.query = params.title;
|
|
39
|
+
}
|
|
40
|
+
if (params.type)
|
|
41
|
+
apiParams.type = params.type;
|
|
42
|
+
if (params.channelIds)
|
|
43
|
+
apiParams.channel_ids = JSON.stringify(params.channelIds);
|
|
44
|
+
if (params.conversationIds)
|
|
45
|
+
apiParams.conversation_ids = JSON.stringify(params.conversationIds);
|
|
46
|
+
if (params.authorIds)
|
|
47
|
+
apiParams.from_user_id = params.authorIds[0];
|
|
48
|
+
if (params.toUserIds)
|
|
49
|
+
apiParams.to_user_id = params.toUserIds[0];
|
|
50
|
+
if (params.mentionSelf)
|
|
51
|
+
apiParams.mention_self = params.mentionSelf;
|
|
52
|
+
if (params.dateFrom)
|
|
53
|
+
apiParams.after_ts = new Date(params.dateFrom).getTime() / 1000;
|
|
54
|
+
if (params.dateTo)
|
|
55
|
+
apiParams.before_ts = new Date(params.dateTo).getTime() / 1000;
|
|
56
|
+
if (params.limit)
|
|
57
|
+
apiParams.limit = params.limit;
|
|
58
|
+
if (params.cursor)
|
|
59
|
+
apiParams.cursor_mark = params.cursor;
|
|
60
|
+
const searchParams = new URLSearchParams();
|
|
61
|
+
for (const [key, value] of Object.entries(apiParams)) {
|
|
62
|
+
searchParams.append(key, String(value));
|
|
63
|
+
}
|
|
64
|
+
const url = `${BASE_URL}/search?${searchParams.toString()}`;
|
|
65
|
+
const response = await fetch(url, {
|
|
66
|
+
method: 'GET',
|
|
67
|
+
headers: {
|
|
68
|
+
Authorization: `Bearer ${token}`,
|
|
69
|
+
'Content-Type': 'application/json',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
const errorText = await response.text();
|
|
74
|
+
throw new Error(`Search API error (${response.status}): ${errorText}`);
|
|
75
|
+
}
|
|
76
|
+
const data = await response.json();
|
|
77
|
+
const items = (data.items || []).map((item) => transformSearchResult(item));
|
|
78
|
+
return {
|
|
79
|
+
items,
|
|
80
|
+
nextCursorMark: data.next_cursor_mark,
|
|
81
|
+
hasMore: data.has_more ?? false,
|
|
82
|
+
isPlanRestricted: data.is_plan_restricted ?? false,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=search-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-api.js","sourceRoot":"","sources":["../../src/lib/search-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const SECURE_STORE_DESCRIPTION = "system credential manager";
|
|
2
|
+
export declare class SecureStoreUnavailableError extends Error {
|
|
3
|
+
constructor(message?: string);
|
|
4
|
+
}
|
|
5
|
+
export interface SecureStore {
|
|
6
|
+
getSecret(): Promise<string | null>;
|
|
7
|
+
setSecret(secret: string): Promise<void>;
|
|
8
|
+
deleteSecret(): Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
export declare function createSecureStore(): SecureStore;
|
|
11
|
+
//# sourceMappingURL=secure-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.d.ts","sourceRoot":"","sources":["../../src/lib/secure-store.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,wBAAwB,8BAA8B,CAAA;AAEnE,qBAAa,2BAA4B,SAAQ,KAAK;gBACtC,OAAO,SAA6C;CAInE;AAED,MAAM,WAAW,WAAW;IACxB,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACnC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CACnC;AAED,wBAAgB,iBAAiB,IAAI,WAAW,CA6B/C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const SERVICE_NAME = 'twist-cli';
|
|
2
|
+
const ACCOUNT_NAME = 'api-token';
|
|
3
|
+
export const SECURE_STORE_DESCRIPTION = 'system credential manager';
|
|
4
|
+
export class SecureStoreUnavailableError extends Error {
|
|
5
|
+
constructor(message = 'System credential storage is unavailable') {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'SecureStoreUnavailableError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function createSecureStore() {
|
|
11
|
+
return {
|
|
12
|
+
async getSecret() {
|
|
13
|
+
const entry = await getEntry();
|
|
14
|
+
try {
|
|
15
|
+
return (await entry.getPassword()) ?? null;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw toUnavailableError(error);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
async setSecret(secret) {
|
|
22
|
+
const entry = await getEntry();
|
|
23
|
+
try {
|
|
24
|
+
await entry.setPassword(secret);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw toUnavailableError(error);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
async deleteSecret() {
|
|
31
|
+
const entry = await getEntry();
|
|
32
|
+
try {
|
|
33
|
+
return await entry.deleteCredential();
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw toUnavailableError(error);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function getEntry() {
|
|
42
|
+
try {
|
|
43
|
+
const { AsyncEntry } = await import('@napi-rs/keyring');
|
|
44
|
+
return new AsyncEntry(SERVICE_NAME, ACCOUNT_NAME);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw toUnavailableError(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function toUnavailableError(error) {
|
|
51
|
+
if (error instanceof SecureStoreUnavailableError) {
|
|
52
|
+
return error;
|
|
53
|
+
}
|
|
54
|
+
const message = error instanceof Error ? error.message : 'System credential storage is unavailable';
|
|
55
|
+
return new SecureStoreUnavailableError(message);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=secure-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../../src/lib/secure-store.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,WAAW,CAAA;AAChC,MAAM,YAAY,GAAG,WAAW,CAAA;AAEhC,MAAM,CAAC,MAAM,wBAAwB,GAAG,2BAA2B,CAAA;AAEnE,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAClD,YAAY,OAAO,GAAG,0CAA0C;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAA;IAC7C,CAAC;CACJ;AAQD,MAAM,UAAU,iBAAiB;IAC7B,OAAO;QACH,KAAK,CAAC,SAAS;YACX,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAA;YAC9B,IAAI,CAAC;gBACD,OAAO,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAA;YAC9C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAA;YACnC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,MAAc;YAC1B,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAA;YAC9B,IAAI,CAAC;gBACD,MAAM,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAA;YACnC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,YAAY;YACd,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAA;YAC9B,IAAI,CAAC;gBACD,OAAO,MAAM,KAAK,CAAC,gBAAgB,EAAE,CAAA;YACzC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAA;YACnC,CAAC;QACL,CAAC;KACJ,CAAA;AACL,CAAC;AAED,KAAK,UAAU,QAAQ;IACnB,IAAI,CAAC;QACD,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QACvD,OAAO,IAAI,UAAU,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACtC,IAAI,KAAK,YAAY,2BAA2B,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAA;IAChB,CAAC;IAED,MAAM,OAAO,GACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0CAA0C,CAAA;IACvF,OAAO,IAAI,2BAA2B,CAAC,OAAO,CAAC,CAAA;AACnD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const SKILL_NAME = "twist-cli";
|
|
2
|
+
export declare const SKILL_DESCRIPTION = "Twist messaging CLI for team communication";
|
|
3
|
+
export declare const SKILL_CONTENT = "# Twist CLI (tw)\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 # Save API token manually (prompts securely; scope unknown, assumed write-capable)\ntw auth status # Verify authentication + show mode\ntw auth status --json # JSON output: { id, email, name }\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\ntw changelog # Show recent changelog entries\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 create <channel-ref> \"Title\" \"content\" # Create a new thread\ntw thread create <channel-ref> \"Title\" \"content\" --json # Create and return as JSON\ntw thread create <channel-ref> \"Title\" \"content\" --json --full # Include all thread fields\ntw thread create <channel-ref> \"Title\" \"content\" --notify 123,456 # Notify specific users\ntw thread create <channel-ref> \"Title\" \"content\" --dry-run # Preview without posting\ntw thread reply <ref> \"content\" # Post a comment (notifies EVERYONE_IN_THREAD by default)\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 reply <ref> \"content\" --close # Reply and close the thread\ntw thread reply <ref> \"content\" --reopen # Reply and reopen a closed thread\ntw thread done <ref> # Archive thread (mark done)\ntw thread done <ref> --json # Archive and return status as JSON\ntw thread mute <ref> # Mute thread for 60 minutes (default)\ntw thread mute <ref> --minutes 480 # Mute for custom duration\ntw thread mute <ref> --json # Mute and return { id, mutedUntil } as JSON\ntw thread mute <ref> --json --full # Mute and return full thread as JSON\ntw thread unmute <ref> # Unmute a muted thread\ntw thread unmute <ref> --json # Unmute and return { id, mutedUntil } as JSON\n```\n\nDefault `--notify` for reply is EVERYONE_IN_THREAD, which may notify more people than intended. Before posting, confirm with the user whether specific people should be notified instead (via `--notify <user-ids>`). Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated user ID refs.\n\n## Thread Comments\n\n```bash\ntw comment <comment-ref> # View a comment (shorthand for view)\ntw comment view <comment-ref> # View a single thread comment\ntw comment view <comment-ref> --raw # Show raw markdown\ntw comment view <comment-ref> --json # Output as JSON\ntw comment view <comment-ref> --json --full # Include all fields in JSON output\ntw comment update <comment-ref> \"new content\" # Update a thread comment\ntw comment update <comment-ref> \"content\" --json # Update and return updated comment as JSON\ntw comment update <comment-ref> \"content\" --json --full # Include all comment fields\ntw comment delete <comment-ref> # Delete a thread comment\ntw comment delete <comment-ref> --json # Delete and return status as JSON\n```\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\ntw conversation mute <ref> # Mute conversation for 60 minutes (default)\ntw conversation mute <ref> --minutes 480 # Mute for custom duration\ntw conversation mute <ref> --json # Mute and return { id, mutedUntil } as JSON\ntw conversation mute <ref> --json --full # Mute and return full conversation as JSON\ntw conversation unmute <ref> # Unmute a muted conversation\ntw conversation unmute <ref> --json # Unmute and return { id, mutedUntil } 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### Changelog\n```bash\ntw changelog # Show last 5 versions\ntw changelog -n 3 # Show last 3 versions\ntw changelog --count 10 # Show last 10 versions\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## Piping Content\n\nCommands that accept content (`thread create`, `thread reply`, `comment update`, `conversation reply`, `msg update`) auto-detect piped stdin:\n\n```bash\ncat notes.md | tw thread reply <ref>\ntw thread create <channel-ref> \"Title\" < body.md\necho \"Quick reply\" | tw conversation reply <ref>\n```\n\nIf no content argument is provided and no stdin is piped, the CLI opens `$EDITOR` for interactive input.\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: string;
|
|
5
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +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,0/XAoRzB,CAAA;AAED,eAAO,MAAM,kBAAkB,QAKd,CAAA"}
|