claude-threads 0.14.1 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/LICENSE +190 -21
  3. package/README.md +9 -5
  4. package/dist/index.js +20397 -387
  5. package/dist/mcp/permission-server.js +34039 -139
  6. package/package.json +16 -20
  7. package/dist/changelog.d.ts +0 -20
  8. package/dist/changelog.js +0 -134
  9. package/dist/claude/cli.d.ts +0 -50
  10. package/dist/claude/cli.js +0 -181
  11. package/dist/config/migration.d.ts +0 -45
  12. package/dist/config/migration.js +0 -35
  13. package/dist/config.d.ts +0 -21
  14. package/dist/config.js +0 -7
  15. package/dist/git/worktree.d.ts +0 -46
  16. package/dist/git/worktree.js +0 -228
  17. package/dist/index.d.ts +0 -2
  18. package/dist/logo.d.ts +0 -14
  19. package/dist/logo.js +0 -41
  20. package/dist/mattermost/api.d.ts +0 -85
  21. package/dist/mattermost/api.js +0 -124
  22. package/dist/mattermost/api.test.d.ts +0 -1
  23. package/dist/mattermost/api.test.js +0 -319
  24. package/dist/mcp/permission-server.d.ts +0 -2
  25. package/dist/onboarding.d.ts +0 -1
  26. package/dist/onboarding.js +0 -318
  27. package/dist/persistence/session-store.d.ts +0 -71
  28. package/dist/persistence/session-store.js +0 -152
  29. package/dist/platform/client.d.ts +0 -140
  30. package/dist/platform/client.js +0 -1
  31. package/dist/platform/formatter.d.ts +0 -74
  32. package/dist/platform/formatter.js +0 -1
  33. package/dist/platform/index.d.ts +0 -11
  34. package/dist/platform/index.js +0 -8
  35. package/dist/platform/mattermost/client.d.ts +0 -70
  36. package/dist/platform/mattermost/client.js +0 -404
  37. package/dist/platform/mattermost/formatter.d.ts +0 -20
  38. package/dist/platform/mattermost/formatter.js +0 -46
  39. package/dist/platform/mattermost/permission-api.d.ts +0 -10
  40. package/dist/platform/mattermost/permission-api.js +0 -139
  41. package/dist/platform/mattermost/types.d.ts +0 -71
  42. package/dist/platform/mattermost/types.js +0 -1
  43. package/dist/platform/permission-api-factory.d.ts +0 -11
  44. package/dist/platform/permission-api-factory.js +0 -21
  45. package/dist/platform/permission-api.d.ts +0 -67
  46. package/dist/platform/permission-api.js +0 -8
  47. package/dist/platform/types.d.ts +0 -70
  48. package/dist/platform/types.js +0 -7
  49. package/dist/session/commands.d.ts +0 -52
  50. package/dist/session/commands.js +0 -323
  51. package/dist/session/events.d.ts +0 -25
  52. package/dist/session/events.js +0 -368
  53. package/dist/session/index.d.ts +0 -7
  54. package/dist/session/index.js +0 -6
  55. package/dist/session/lifecycle.d.ts +0 -70
  56. package/dist/session/lifecycle.js +0 -456
  57. package/dist/session/manager.d.ts +0 -96
  58. package/dist/session/manager.js +0 -537
  59. package/dist/session/reactions.d.ts +0 -25
  60. package/dist/session/reactions.js +0 -151
  61. package/dist/session/streaming.d.ts +0 -47
  62. package/dist/session/streaming.js +0 -152
  63. package/dist/session/types.d.ts +0 -78
  64. package/dist/session/types.js +0 -9
  65. package/dist/session/worktree.d.ts +0 -56
  66. package/dist/session/worktree.js +0 -339
  67. package/dist/update-notifier.d.ts +0 -3
  68. package/dist/update-notifier.js +0 -41
  69. package/dist/utils/emoji.d.ts +0 -43
  70. package/dist/utils/emoji.js +0 -65
  71. package/dist/utils/emoji.test.d.ts +0 -1
  72. package/dist/utils/emoji.test.js +0 -131
  73. package/dist/utils/logger.d.ts +0 -34
  74. package/dist/utils/logger.js +0 -42
  75. package/dist/utils/logger.test.d.ts +0 -1
  76. package/dist/utils/logger.test.js +0 -121
  77. package/dist/utils/tool-formatter.d.ts +0 -53
  78. package/dist/utils/tool-formatter.js +0 -252
  79. package/dist/utils/tool-formatter.test.d.ts +0 -1
  80. package/dist/utils/tool-formatter.test.js +0 -372
@@ -1,151 +0,0 @@
1
- /**
2
- * User reaction handling module
3
- *
4
- * Handles emoji reactions on posts: plan approval, question answers,
5
- * message approval, cancel/escape actions.
6
- */
7
- import { isApprovalEmoji, isDenialEmoji, isAllowAllEmoji, getNumberEmojiIndex, } from '../utils/emoji.js';
8
- import { postCurrentQuestion } from './events.js';
9
- // ---------------------------------------------------------------------------
10
- // Question reaction handling
11
- // ---------------------------------------------------------------------------
12
- /**
13
- * Handle a reaction on a question post (number emoji to select an option).
14
- */
15
- export async function handleQuestionReaction(session, postId, emojiName, username, ctx) {
16
- if (!session.pendingQuestionSet)
17
- return;
18
- const { currentIndex, questions } = session.pendingQuestionSet;
19
- const question = questions[currentIndex];
20
- if (!question)
21
- return;
22
- const optionIndex = getNumberEmojiIndex(emojiName);
23
- if (optionIndex < 0 || optionIndex >= question.options.length)
24
- return;
25
- const selectedOption = question.options[optionIndex];
26
- question.answer = selectedOption.label;
27
- if (ctx.debug)
28
- console.log(` 💬 @${username} answered "${question.header}": ${selectedOption.label}`);
29
- // Update the post to show answer
30
- try {
31
- await session.platform.updatePost(postId, `✅ **${question.header}**: ${selectedOption.label}`);
32
- }
33
- catch (err) {
34
- console.error(' ⚠️ Failed to update answered question:', err);
35
- }
36
- // Move to next question or finish
37
- session.pendingQuestionSet.currentIndex++;
38
- if (session.pendingQuestionSet.currentIndex < questions.length) {
39
- // Post next question
40
- await postCurrentQuestion(session, {
41
- debug: ctx.debug,
42
- registerPost: () => { }, // Will be called by events module
43
- flush: async () => { },
44
- startTyping: ctx.startTyping,
45
- stopTyping: ctx.stopTyping,
46
- appendContent: () => { },
47
- });
48
- }
49
- else {
50
- // All questions answered - send tool result
51
- let answersText = 'Here are my answers:\n';
52
- for (const q of questions) {
53
- answersText += `- **${q.header}**: ${q.answer}\n`;
54
- }
55
- if (ctx.debug)
56
- console.log(' ✅ All questions answered');
57
- // Get the toolUseId before clearing
58
- const toolUseId = session.pendingQuestionSet.toolUseId;
59
- // Clear pending questions
60
- session.pendingQuestionSet = null;
61
- // Send tool result to Claude (AskUserQuestion expects a tool_result, not a user message)
62
- if (session.claude.isRunning()) {
63
- session.claude.sendToolResult(toolUseId, answersText);
64
- ctx.startTyping(session);
65
- }
66
- }
67
- }
68
- // ---------------------------------------------------------------------------
69
- // Plan approval reaction handling
70
- // ---------------------------------------------------------------------------
71
- /**
72
- * Handle a reaction on a plan approval post (thumbs up/down).
73
- */
74
- export async function handleApprovalReaction(session, emojiName, username, ctx) {
75
- if (!session.pendingApproval)
76
- return;
77
- const isApprove = isApprovalEmoji(emojiName);
78
- const isReject = isDenialEmoji(emojiName);
79
- if (!isApprove && !isReject)
80
- return;
81
- const { postId, toolUseId } = session.pendingApproval;
82
- const shortId = session.threadId.substring(0, 8);
83
- console.log(` ${isApprove ? '✅' : '❌'} Plan ${isApprove ? 'approved' : 'rejected'} (${shortId}…) by @${username}`);
84
- // Update the post to show the decision
85
- try {
86
- const statusMessage = isApprove
87
- ? `✅ **Plan approved** by @${username} - starting implementation...`
88
- : `❌ **Changes requested** by @${username}`;
89
- await session.platform.updatePost(postId, statusMessage);
90
- }
91
- catch (err) {
92
- console.error(' ⚠️ Failed to update approval post:', err);
93
- }
94
- // Clear pending approval and mark as approved
95
- session.pendingApproval = null;
96
- if (isApprove) {
97
- session.planApproved = true;
98
- }
99
- // Send tool result to Claude (ExitPlanMode expects a tool_result, not a user message)
100
- if (session.claude.isRunning()) {
101
- const response = isApprove
102
- ? 'Approved. Please proceed with the implementation.'
103
- : 'Please revise the plan. I would like some changes.';
104
- session.claude.sendToolResult(toolUseId, response);
105
- ctx.startTyping(session);
106
- }
107
- }
108
- // ---------------------------------------------------------------------------
109
- // Message approval reaction handling
110
- // ---------------------------------------------------------------------------
111
- /**
112
- * Handle a reaction on a message approval post (approve/invite/deny).
113
- */
114
- export async function handleMessageApprovalReaction(session, emoji, approver, ctx) {
115
- const pending = session.pendingMessageApproval;
116
- if (!pending)
117
- return;
118
- // Only session owner or globally allowed users can approve
119
- if (session.startedBy !== approver && !session.platform.isUserAllowed(approver)) {
120
- return;
121
- }
122
- const isAllow = isApprovalEmoji(emoji);
123
- const isInvite = isAllowAllEmoji(emoji);
124
- const isDeny = isDenialEmoji(emoji);
125
- if (!isAllow && !isInvite && !isDeny)
126
- return;
127
- if (isAllow) {
128
- // Allow this single message
129
- await session.platform.updatePost(pending.postId, `✅ Message from @${pending.fromUser} approved by @${approver}`);
130
- session.claude.sendMessage(pending.originalMessage);
131
- session.lastActivityAt = new Date();
132
- ctx.startTyping(session);
133
- console.log(` ✅ Message from @${pending.fromUser} approved by @${approver}`);
134
- }
135
- else if (isInvite) {
136
- // Invite user to session
137
- session.sessionAllowedUsers.add(pending.fromUser);
138
- await session.platform.updatePost(pending.postId, `✅ @${pending.fromUser} invited to session by @${approver}`);
139
- await ctx.updateSessionHeader(session);
140
- session.claude.sendMessage(pending.originalMessage);
141
- session.lastActivityAt = new Date();
142
- ctx.startTyping(session);
143
- console.log(` 👋 @${pending.fromUser} invited to session by @${approver}`);
144
- }
145
- else if (isDeny) {
146
- // Deny
147
- await session.platform.updatePost(pending.postId, `❌ Message from @${pending.fromUser} denied by @${approver}`);
148
- console.log(` ❌ Message from @${pending.fromUser} denied by @${approver}`);
149
- }
150
- session.pendingMessageApproval = null;
151
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Message streaming and flushing utilities
3
- *
4
- * Handles buffering, formatting, and posting Claude responses to the platform.
5
- */
6
- import type { PlatformClient, PlatformFile } from '../platform/index.js';
7
- import type { Session } from './types.js';
8
- import type { ContentBlock } from '../claude/cli.js';
9
- /**
10
- * Schedule a delayed flush of the session's pending content.
11
- * If an update is already scheduled, this is a no-op.
12
- *
13
- * Used during streaming to batch updates and avoid excessive API calls.
14
- */
15
- export declare function scheduleUpdate(session: Session, onFlush: (session: Session) => Promise<void>): void;
16
- /**
17
- * Build message content for Claude, including images if present.
18
- * Returns either a string or an array of content blocks.
19
- *
20
- * @param text - The text message
21
- * @param platform - Platform client for downloading images
22
- * @param files - Optional files attached to the message
23
- * @param debug - Whether to log debug info
24
- * @returns Plain string or content blocks array with images
25
- */
26
- export declare function buildMessageContent(text: string, platform: PlatformClient, files?: PlatformFile[], debug?: boolean): Promise<string | ContentBlock[]>;
27
- /**
28
- * Start sending typing indicators to the platform.
29
- * Sends immediately, then every 3 seconds until stopped.
30
- */
31
- export declare function startTyping(session: Session): void;
32
- /**
33
- * Stop sending typing indicators.
34
- */
35
- export declare function stopTyping(session: Session): void;
36
- /**
37
- * Flush pending content to the platform.
38
- *
39
- * Handles:
40
- * - Message length limits (splits into multiple posts if needed)
41
- * - Creating vs updating posts
42
- * - Post registration for reaction routing
43
- *
44
- * @param session - The session to flush
45
- * @param registerPost - Callback to register post for reaction routing
46
- */
47
- export declare function flush(session: Session, registerPost: (postId: string, threadId: string) => void): Promise<void>;
@@ -1,152 +0,0 @@
1
- /**
2
- * Message streaming and flushing utilities
3
- *
4
- * Handles buffering, formatting, and posting Claude responses to the platform.
5
- */
6
- /**
7
- * Schedule a delayed flush of the session's pending content.
8
- * If an update is already scheduled, this is a no-op.
9
- *
10
- * Used during streaming to batch updates and avoid excessive API calls.
11
- */
12
- export function scheduleUpdate(session, onFlush) {
13
- if (session.updateTimer)
14
- return;
15
- session.updateTimer = setTimeout(() => {
16
- session.updateTimer = null;
17
- onFlush(session);
18
- }, 500);
19
- }
20
- /**
21
- * Build message content for Claude, including images if present.
22
- * Returns either a string or an array of content blocks.
23
- *
24
- * @param text - The text message
25
- * @param platform - Platform client for downloading images
26
- * @param files - Optional files attached to the message
27
- * @param debug - Whether to log debug info
28
- * @returns Plain string or content blocks array with images
29
- */
30
- export async function buildMessageContent(text, platform, files, debug = false) {
31
- // Filter to only image files
32
- const imageFiles = files?.filter(f => f.mimeType.startsWith('image/') &&
33
- ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(f.mimeType)) || [];
34
- // If no images, return plain text
35
- if (imageFiles.length === 0) {
36
- return text;
37
- }
38
- // Build content blocks with images
39
- const blocks = [];
40
- // Download and add each image
41
- for (const file of imageFiles) {
42
- try {
43
- if (!platform.downloadFile) {
44
- console.warn(` ⚠️ Platform does not support file downloads, skipping ${file.name}`);
45
- continue;
46
- }
47
- const buffer = await platform.downloadFile(file.id);
48
- const base64 = buffer.toString('base64');
49
- blocks.push({
50
- type: 'image',
51
- source: {
52
- type: 'base64',
53
- media_type: file.mimeType,
54
- data: base64,
55
- },
56
- });
57
- if (debug) {
58
- console.log(` 📷 Attached image: ${file.name} (${file.mimeType}, ${Math.round(buffer.length / 1024)}KB)`);
59
- }
60
- }
61
- catch (err) {
62
- console.error(` ⚠️ Failed to download image ${file.name}:`, err);
63
- }
64
- }
65
- // Add the text message
66
- if (text) {
67
- blocks.push({
68
- type: 'text',
69
- text,
70
- });
71
- }
72
- return blocks;
73
- }
74
- /**
75
- * Start sending typing indicators to the platform.
76
- * Sends immediately, then every 3 seconds until stopped.
77
- */
78
- export function startTyping(session) {
79
- if (session.typingTimer)
80
- return;
81
- // Send typing immediately, then every 3 seconds
82
- session.platform.sendTyping(session.threadId);
83
- session.typingTimer = setInterval(() => {
84
- session.platform.sendTyping(session.threadId);
85
- }, 3000);
86
- }
87
- /**
88
- * Stop sending typing indicators.
89
- */
90
- export function stopTyping(session) {
91
- if (session.typingTimer) {
92
- clearInterval(session.typingTimer);
93
- session.typingTimer = null;
94
- }
95
- }
96
- /**
97
- * Flush pending content to the platform.
98
- *
99
- * Handles:
100
- * - Message length limits (splits into multiple posts if needed)
101
- * - Creating vs updating posts
102
- * - Post registration for reaction routing
103
- *
104
- * @param session - The session to flush
105
- * @param registerPost - Callback to register post for reaction routing
106
- */
107
- export async function flush(session, registerPost) {
108
- if (!session.pendingContent.trim())
109
- return;
110
- let content = session.pendingContent.replace(/\n{3,}/g, '\n\n').trim();
111
- // Most chat platforms have post length limits (~16K for Mattermost/Slack)
112
- const MAX_POST_LENGTH = 16000; // Leave some margin
113
- const CONTINUATION_THRESHOLD = 14000; // Start new message before we hit the limit
114
- // Check if we need to start a new message due to length
115
- if (session.currentPostId && content.length > CONTINUATION_THRESHOLD) {
116
- // Finalize the current post with what we have up to the threshold
117
- // Find a good break point (end of line) near the threshold
118
- let breakPoint = content.lastIndexOf('\n', CONTINUATION_THRESHOLD);
119
- if (breakPoint < CONTINUATION_THRESHOLD * 0.7) {
120
- // If we can't find a good line break, just break at the threshold
121
- breakPoint = CONTINUATION_THRESHOLD;
122
- }
123
- const firstPart = content.substring(0, breakPoint).trim() + '\n\n*... (continued below)*';
124
- const remainder = content.substring(breakPoint).trim();
125
- // Update the current post with the first part
126
- await session.platform.updatePost(session.currentPostId, firstPart);
127
- // Start a new post for the continuation
128
- session.currentPostId = null;
129
- session.pendingContent = remainder;
130
- // Create the continuation post if there's content
131
- if (remainder) {
132
- const post = await session.platform.createPost('*(continued)*\n\n' + remainder, session.threadId);
133
- session.currentPostId = post.id;
134
- registerPost(post.id, session.threadId);
135
- }
136
- return;
137
- }
138
- // Normal case: content fits in current post
139
- if (content.length > MAX_POST_LENGTH) {
140
- // Safety truncation if we somehow got content that's still too long
141
- content = content.substring(0, MAX_POST_LENGTH - 50) + '\n\n*... (truncated)*';
142
- }
143
- if (session.currentPostId) {
144
- await session.platform.updatePost(session.currentPostId, content);
145
- }
146
- else {
147
- const post = await session.platform.createPost(content, session.threadId);
148
- session.currentPostId = post.id;
149
- // Register post for reaction routing
150
- registerPost(post.id, session.threadId);
151
- }
152
- }
@@ -1,78 +0,0 @@
1
- /**
2
- * Session management types and interfaces
3
- */
4
- import type { ClaudeCli } from '../claude/cli.js';
5
- import type { PlatformClient } from '../platform/index.js';
6
- import type { WorktreeInfo } from '../persistence/session-store.js';
7
- export interface QuestionOption {
8
- label: string;
9
- description: string;
10
- }
11
- export interface PendingQuestionSet {
12
- toolUseId: string;
13
- currentIndex: number;
14
- currentPostId: string | null;
15
- questions: Array<{
16
- header: string;
17
- question: string;
18
- options: QuestionOption[];
19
- answer: string | null;
20
- }>;
21
- }
22
- export interface PendingApproval {
23
- postId: string;
24
- type: 'plan' | 'action';
25
- toolUseId: string;
26
- }
27
- /**
28
- * Pending message from unauthorized user awaiting approval
29
- */
30
- export interface PendingMessageApproval {
31
- postId: string;
32
- originalMessage: string;
33
- fromUser: string;
34
- }
35
- /**
36
- * Represents a single Claude Code session tied to a platform thread.
37
- * Each session has its own Claude CLI process and state.
38
- */
39
- export interface Session {
40
- platformId: string;
41
- threadId: string;
42
- sessionId: string;
43
- claudeSessionId: string;
44
- startedBy: string;
45
- startedAt: Date;
46
- lastActivityAt: Date;
47
- sessionNumber: number;
48
- platform: PlatformClient;
49
- workingDir: string;
50
- claude: ClaudeCli;
51
- currentPostId: string | null;
52
- pendingContent: string;
53
- pendingApproval: PendingApproval | null;
54
- pendingQuestionSet: PendingQuestionSet | null;
55
- pendingMessageApproval: PendingMessageApproval | null;
56
- planApproved: boolean;
57
- sessionAllowedUsers: Set<string>;
58
- forceInteractivePermissions: boolean;
59
- sessionStartPostId: string | null;
60
- tasksPostId: string | null;
61
- activeSubagents: Map<string, string>;
62
- updateTimer: ReturnType<typeof setTimeout> | null;
63
- typingTimer: ReturnType<typeof setInterval> | null;
64
- timeoutWarningPosted: boolean;
65
- isRestarting: boolean;
66
- isResumed: boolean;
67
- wasInterrupted: boolean;
68
- inProgressTaskStart: number | null;
69
- activeToolStarts: Map<string, number>;
70
- worktreeInfo?: WorktreeInfo;
71
- pendingWorktreePrompt?: boolean;
72
- worktreePromptDisabled?: boolean;
73
- queuedPrompt?: string;
74
- worktreePromptPostId?: string;
75
- }
76
- export declare const MAX_SESSIONS: number;
77
- export declare const SESSION_TIMEOUT_MS: number;
78
- export declare const SESSION_WARNING_MS: number;
@@ -1,9 +0,0 @@
1
- /**
2
- * Session management types and interfaces
3
- */
4
- // =============================================================================
5
- // Configuration Constants
6
- // =============================================================================
7
- export const MAX_SESSIONS = parseInt(process.env.MAX_SESSIONS || '5', 10);
8
- export const SESSION_TIMEOUT_MS = parseInt(process.env.SESSION_TIMEOUT_MS || '1800000', 10); // 30 min
9
- export const SESSION_WARNING_MS = 5 * 60 * 1000; // Warn 5 minutes before timeout
@@ -1,56 +0,0 @@
1
- /**
2
- * Git worktree management utilities
3
- *
4
- * Handles worktree prompts, creation, switching, and cleanup.
5
- */
6
- import type { Session } from './types.js';
7
- import type { WorktreeMode } from '../config.js';
8
- import type { ClaudeEvent } from '../claude/cli.js';
9
- /**
10
- * Check if we should prompt the user to create a worktree.
11
- * Returns the reason for prompting, or null if we shouldn't prompt.
12
- */
13
- export declare function shouldPromptForWorktree(session: Session, worktreeMode: WorktreeMode, hasOtherSessionInRepo: (repoRoot: string, excludeThreadId: string) => boolean): Promise<string | null>;
14
- /**
15
- * Post the worktree prompt message to the user.
16
- */
17
- export declare function postWorktreePrompt(session: Session, reason: string, registerPost: (postId: string, threadId: string) => void): Promise<void>;
18
- /**
19
- * Handle user providing a branch name in response to worktree prompt.
20
- * Returns true if handled (whether successful or not).
21
- */
22
- export declare function handleWorktreeBranchResponse(session: Session, branchName: string, username: string, createAndSwitch: (threadId: string, branch: string, username: string) => Promise<void>): Promise<boolean>;
23
- /**
24
- * Handle ❌ reaction on worktree prompt - skip worktree and continue in main repo.
25
- */
26
- export declare function handleWorktreeSkip(session: Session, username: string, persistSession: (session: Session) => void, startTyping: (session: Session) => void): Promise<void>;
27
- /**
28
- * Create a new worktree and switch the session to it.
29
- */
30
- export declare function createAndSwitchToWorktree(session: Session, branch: string, username: string, options: {
31
- skipPermissions: boolean;
32
- chromeEnabled: boolean;
33
- handleEvent: (sessionId: string, event: ClaudeEvent) => void;
34
- handleExit: (sessionId: string, code: number) => Promise<void>;
35
- updateSessionHeader: (session: Session) => Promise<void>;
36
- flush: (session: Session) => Promise<void>;
37
- persistSession: (session: Session) => void;
38
- startTyping: (session: Session) => void;
39
- stopTyping: (session: Session) => void;
40
- }): Promise<void>;
41
- /**
42
- * Switch to an existing worktree.
43
- */
44
- export declare function switchToWorktree(session: Session, branchOrPath: string, username: string, changeDirectory: (threadId: string, newDir: string, username: string) => Promise<void>): Promise<void>;
45
- /**
46
- * List all worktrees for the current repository.
47
- */
48
- export declare function listWorktreesCommand(session: Session): Promise<void>;
49
- /**
50
- * Remove a worktree.
51
- */
52
- export declare function removeWorktreeCommand(session: Session, branchOrPath: string, username: string): Promise<void>;
53
- /**
54
- * Disable worktree prompts for a session.
55
- */
56
- export declare function disableWorktreePrompt(session: Session, username: string, persistSession: (session: Session) => void): Promise<void>;