@pollit/twin-dev-bot 0.0.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/LICENSE +661 -0
- package/README.md +415 -0
- package/bin/twindevbot.js +22 -0
- package/dist/action-payload-store.d.ts +22 -0
- package/dist/action-payload-store.js +54 -0
- package/dist/active-runners.d.ts +44 -0
- package/dist/active-runners.js +114 -0
- package/dist/channel-store.d.ts +16 -0
- package/dist/channel-store.js +91 -0
- package/dist/claude/active-runners.d.ts +44 -0
- package/dist/claude/active-runners.js +114 -0
- package/dist/claude/claude-runner.d.ts +57 -0
- package/dist/claude/claude-runner.js +210 -0
- package/dist/claude/session-manager.d.ts +62 -0
- package/dist/claude/session-manager.js +247 -0
- package/dist/claude-runner.d.ts +57 -0
- package/dist/claude-runner.js +210 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +271 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +49 -0
- package/dist/conversation-store.d.ts +53 -0
- package/dist/conversation-store.js +173 -0
- package/dist/core/config.d.ts +9 -0
- package/dist/core/config.js +49 -0
- package/dist/core/logger.d.ts +34 -0
- package/dist/core/logger.js +110 -0
- package/dist/core/paths.d.ts +11 -0
- package/dist/core/paths.js +18 -0
- package/dist/core/platform.d.ts +18 -0
- package/dist/core/platform.js +33 -0
- package/dist/daemon/index.d.ts +3 -0
- package/dist/daemon/index.js +14 -0
- package/dist/daemon/macos.d.ts +8 -0
- package/dist/daemon/macos.js +150 -0
- package/dist/daemon/types.d.ts +9 -0
- package/dist/daemon/types.js +1 -0
- package/dist/daemon/windows.d.ts +8 -0
- package/dist/daemon/windows.js +137 -0
- package/dist/handlers/claude-command.d.ts +2 -0
- package/dist/handlers/claude-command.js +634 -0
- package/dist/handlers/claude-runner-setup.d.ts +16 -0
- package/dist/handlers/claude-runner-setup.js +445 -0
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/init-handlers.d.ts +2 -0
- package/dist/handlers/init-handlers.js +189 -0
- package/dist/handlers/question-handlers.d.ts +2 -0
- package/dist/handlers/question-handlers.js +835 -0
- package/dist/i18n/en.d.ts +150 -0
- package/dist/i18n/en.js +163 -0
- package/dist/i18n/index.d.ts +20 -0
- package/dist/i18n/index.js +31 -0
- package/dist/i18n/ko.d.ts +1 -0
- package/dist/i18n/ko.js +141 -0
- package/dist/logger.d.ts +34 -0
- package/dist/logger.js +110 -0
- package/dist/multi-select-state.d.ts +58 -0
- package/dist/multi-select-state.js +151 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.js +18 -0
- package/dist/pending-questions.d.ts +53 -0
- package/dist/pending-questions.js +139 -0
- package/dist/platform.d.ts +18 -0
- package/dist/platform.js +33 -0
- package/dist/progress-tracker.d.ts +47 -0
- package/dist/progress-tracker.js +218 -0
- package/dist/question-blocks.d.ts +27 -0
- package/dist/question-blocks.js +235 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +83 -0
- package/dist/session-manager.d.ts +62 -0
- package/dist/session-manager.js +247 -0
- package/dist/setup.d.ts +5 -0
- package/dist/setup.js +132 -0
- package/dist/slack/progress-tracker.d.ts +47 -0
- package/dist/slack/progress-tracker.js +218 -0
- package/dist/slack/question-blocks.d.ts +27 -0
- package/dist/slack/question-blocks.js +235 -0
- package/dist/stores/action-payload-store.d.ts +22 -0
- package/dist/stores/action-payload-store.js +54 -0
- package/dist/stores/channel-store.d.ts +16 -0
- package/dist/stores/channel-store.js +91 -0
- package/dist/stores/multi-select-state.d.ts +58 -0
- package/dist/stores/multi-select-state.js +151 -0
- package/dist/stores/pending-questions.d.ts +53 -0
- package/dist/stores/pending-questions.js +139 -0
- package/dist/stores/workspace-store.d.ts +27 -0
- package/dist/stores/workspace-store.js +160 -0
- package/dist/templates.d.ts +23 -0
- package/dist/templates.js +292 -0
- package/dist/types/claude-stream.d.ts +116 -0
- package/dist/types/claude-stream.js +3 -0
- package/dist/types/conversation.d.ts +16 -0
- package/dist/types/conversation.js +4 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/slack.d.ts +51 -0
- package/dist/types/slack.js +1 -0
- package/dist/utils/display-width.d.ts +8 -0
- package/dist/utils/display-width.js +33 -0
- package/dist/utils/safe-async.d.ts +6 -0
- package/dist/utils/safe-async.js +14 -0
- package/dist/utils/slack-message.d.ts +73 -0
- package/dist/utils/slack-message.js +220 -0
- package/dist/utils/slack-rate-limit.d.ts +5 -0
- package/dist/utils/slack-rate-limit.js +49 -0
- package/dist/workspace-store.d.ts +27 -0
- package/dist/workspace-store.js +160 -0
- package/package.json +51 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
declare const _en: {
|
|
2
|
+
readonly "question.header": "Question";
|
|
3
|
+
readonly "question.headerCompleted": "Question (Answered)";
|
|
4
|
+
readonly "question.submitSelection": "Submit Selection";
|
|
5
|
+
readonly "question.textInput": "βοΈ Custom Input";
|
|
6
|
+
readonly "question.currentSelection": "_Current selection: {{labels}}_";
|
|
7
|
+
readonly "question.selectHint": "_Select options then press 'Submit Selection'_";
|
|
8
|
+
readonly "question.truncatedOptions": "_Showing {{shown}} of {{total}} options. Use 'Custom Input' for others._";
|
|
9
|
+
readonly "modal.title": "Enter Answer";
|
|
10
|
+
readonly "modal.submit": "Submit";
|
|
11
|
+
readonly "modal.cancel": "Cancel";
|
|
12
|
+
readonly "modal.prompt": "Enter your answer:";
|
|
13
|
+
readonly "modal.label": "Answer";
|
|
14
|
+
readonly "modal.placeholder": "Type your answer...";
|
|
15
|
+
readonly "session.expired": "Session for *{{projectName}}* expired. Use `/twindevbot task` to start a new session.";
|
|
16
|
+
readonly "session.expiredUnknown": "Session expired. Use `/twindevbot task` to start a new session.";
|
|
17
|
+
readonly "session.notFound": "Session not found. Use `/twindevbot task` to start a new session.";
|
|
18
|
+
readonly "multiSelect.noneSelected": "Please select at least one option before pressing 'Submit Selection'.";
|
|
19
|
+
readonly "error.actionFailed": ":x: Something went wrong processing your action. Please try again.";
|
|
20
|
+
readonly "error.alreadyProcessing": ":hourglass: Already processing. Please wait for the current task to finish.";
|
|
21
|
+
readonly "error.resumeFailed": ":x: Your answer was received, but failed to resume Claude. Please send a new message to try again.";
|
|
22
|
+
readonly "command.autopilotNotice": "(Autopilot mode is active.\nA single thread message starts and completes the task.\nAll questions during the process will be auto-answered.\nFor best results, please provide detailed and clear instructions.)";
|
|
23
|
+
readonly "command.newUsage": ":warning: Usage:\n`/twindevbot new <directory> --empty`\n`/twindevbot new <directory> --template react`\n\nAvailable templates:\n{{templates}}";
|
|
24
|
+
readonly "command.newOptionsRequired": ":warning: Please specify an option:\n`/twindevbot new {{dirName}} --empty`\n`/twindevbot new {{dirName}} --template react`\n\nAvailable templates:\n{{templates}}";
|
|
25
|
+
readonly "command.invalidDirName": ":x: `{{dirName}}` is not a valid directory name. Only letters, numbers, hyphens (`-`), underscores (`_`), and dots (`.`) are allowed.";
|
|
26
|
+
readonly "command.dirAlreadyExists": ":x: Directory `{{dirName}}` already exists. Please choose a different name.";
|
|
27
|
+
readonly "command.errorOccurred": ":rotating_light: An error occurred, please try again.\n```{{error}}```";
|
|
28
|
+
readonly "command.emptyDirCreated": ":white_check_mark: Created empty directory `{{dirName}}`.";
|
|
29
|
+
readonly "command.templateNotFound": ":x: Template `{{templateKey}}` not found.\n\nAvailable templates:\n{{templates}}";
|
|
30
|
+
readonly "command.creatingProject": ":hourglass_flowing_sand: Creating `{{templateName}}` project...\nThis may take a moment. I'll let you know when it's done.\n`{{command}}`";
|
|
31
|
+
readonly "command.projectCreated": ":white_check_mark: `{{templateName}}` project created at `{{dirName}}`.";
|
|
32
|
+
readonly "command.autopilotInterruptConfirm": "Interrupting will stop autopilot mode. Would you like to proceed?";
|
|
33
|
+
readonly "command.autopilotInterruptYes": "Yes";
|
|
34
|
+
readonly "command.autopilotInterruptNo": "No";
|
|
35
|
+
readonly "command.autopilotInterruptedYes": "Autopilot mode stopped. Starting work on your message in normal mode.";
|
|
36
|
+
readonly "command.autopilotContinue": "Continuing in autopilot mode.";
|
|
37
|
+
readonly "command.normalInterruptConfirm": "The previous task is still in progress. Would you like to stop it and start a new task? (Not Recommended)";
|
|
38
|
+
readonly "command.normalInterruptYes": "Yes";
|
|
39
|
+
readonly "command.normalInterruptNo": "No";
|
|
40
|
+
readonly "command.normalInterruptedYes": "Previous task stopped. Starting new task now.";
|
|
41
|
+
readonly "command.normalInterruptContinue": "Continuing the previous task. Please send your new command after the current task completes.";
|
|
42
|
+
readonly "interrupt.taskAlreadyCompleted": "The previous task has already completed. Send a new message to start a new task.";
|
|
43
|
+
readonly "interrupt.payloadExpired": ":warning: Your previous message is no longer available. Please resend your instruction.";
|
|
44
|
+
readonly "command.baseDirNotFound": ":x: Project base directory (`{{baseDir}}`) not found.";
|
|
45
|
+
readonly "command.postFailed": "Failed to start the session. Please try again.";
|
|
46
|
+
readonly "command.didYouMean": "Unknown command. Did you mean `/twindevbot {{suggestion}}`?";
|
|
47
|
+
readonly "command.stopped": "Task cancelled.";
|
|
48
|
+
readonly "command.noActiveTask": "No active task to cancel.";
|
|
49
|
+
readonly "command.initSelectDir": "Select a working directory for this channel:";
|
|
50
|
+
readonly "command.initEmpty": ":open_file_folder: No directories found in `{{baseDir}}`.\nUse the button below to enter a path manually, or create a project with `/twindevbot new`.";
|
|
51
|
+
readonly "command.initCustomInput": "βοΈ Enter path manually";
|
|
52
|
+
readonly "command.initSuccess": ":white_check_mark: `{{dirName}}` has been set as this channel's working directory.\nUse `/twindevbot task` to start working.";
|
|
53
|
+
readonly "command.initInvalidDir": ":x: Directory `{{directory}}` does not exist.";
|
|
54
|
+
readonly "command.initModalTitle": "Enter Directory";
|
|
55
|
+
readonly "command.initModalLabel": "Directory path";
|
|
56
|
+
readonly "command.initModalPlaceholder": "e.g. my-project or /absolute/path";
|
|
57
|
+
readonly "command.initModalDirNotExist": "Directory does not exist.";
|
|
58
|
+
readonly "command.taskNoDir": ":warning: No working directory configured for this channel.\nUse `/twindevbot init` to set one up.";
|
|
59
|
+
readonly "command.taskStarted": ":file_folder: `{{dirName}}` session started.\nContinue in the thread.";
|
|
60
|
+
readonly "command.taskSuccess": ":file_folder: Working on `{{dirName}}`.\nWhat would you like to work on?";
|
|
61
|
+
readonly "command.help": ":robot_face: *TwinDevBot Commands*\nDevelop with Claude Code from anywhere.\n\n:warning: *Before you start:* Invite the bot to this channel first (`/invite @TwinDevBot`). The bot must be a channel member to receive your messages.\n\n\n:wrench: *Set up channel*\n`/twindevbot init`\nSelect or enter a working directory for this channel.\n\n\n:rocket: *Start a task*\n`/twindevbot task`\n`/twindevbot task --autopilot`\nStart a new Claude session in the channel's working directory.\n\n\n:hammer_and_wrench: *Create project*\n`/twindevbot new <directory> --empty`\n`/twindevbot new <directory> --template <framework>`\n`/twindevbot new <directory> --template <framework> --autopilot`\n{{templates}}\n\n\n:octagonal_sign: *Stop running task*\n`/twindevbot stop`\nCancel the currently running Claude task.\n\n\n:bulb: *Notes*\n* Use `init` once per channel to link it to a project directory.\n* Use `task` to start a new task thread.\n* `--autopilot` mode: twindevbot automatically answers all questions and develops on its own.";
|
|
62
|
+
readonly "slack.answered": "Answer submitted";
|
|
63
|
+
readonly "slack.question": "Question";
|
|
64
|
+
readonly "progress.tool.Read": "Reading file";
|
|
65
|
+
readonly "progress.tool.Write": "Writing file";
|
|
66
|
+
readonly "progress.tool.Edit": "Editing file";
|
|
67
|
+
readonly "progress.tool.Bash": "Running command";
|
|
68
|
+
readonly "progress.tool.Grep": "Searching code";
|
|
69
|
+
readonly "progress.tool.Glob": "Finding files";
|
|
70
|
+
readonly "progress.tool.Task": "Processing subtask";
|
|
71
|
+
readonly "progress.tool.WebSearch": "Searching the web";
|
|
72
|
+
readonly "progress.tool.WebFetch": "Fetching web page";
|
|
73
|
+
readonly "progress.tool.NotebookEdit": "Editing notebook";
|
|
74
|
+
readonly "progress.tool.default": "Running tool";
|
|
75
|
+
readonly "progress.working": ":gear: Starting work...";
|
|
76
|
+
readonly "progress.completed": ":white_check_mark: Completed ({{elapsed}})";
|
|
77
|
+
readonly "progress.error": ":x: Error occurred: {{error}}";
|
|
78
|
+
readonly "progress.planApproved": ":thumbsup: Plan approved. Starting implementation...";
|
|
79
|
+
readonly "progress.autopilotContinue": ":robot_face: Auto-responded, continuing... ({{elapsed}})";
|
|
80
|
+
readonly "progress.askUser": ":raised_hand: Question sent. Waiting for answer.";
|
|
81
|
+
readonly "progress.lessThanOneSecond": "<1s";
|
|
82
|
+
readonly "progress.seconds": "{{n}}s";
|
|
83
|
+
readonly "progress.minutesSeconds": "{{m}}m {{s}}s";
|
|
84
|
+
readonly "runner.questionArrived": "Claude Code question arrived";
|
|
85
|
+
readonly "runner.autopilotAnswer": ":robot_face: Autopilot: auto-selected {{answer}}";
|
|
86
|
+
readonly "runner.errorOccurred": "Error: {{error}}";
|
|
87
|
+
readonly "runner.claudeNotFound": "Claude CLI is not installed or not found in PATH. Please install it with `npm install -g @anthropic-ai/claude-code`.";
|
|
88
|
+
readonly "runner.exitError": ":x: Claude process exited abnormally (code: {{code}}). Check logs for details.";
|
|
89
|
+
readonly "runner.autopilotResumeFailed": ":x: Autopilot: Failed to resume Claude.";
|
|
90
|
+
readonly "runner.autopilotNoSession": ":x: Autopilot: No session ID available, cannot resume.";
|
|
91
|
+
readonly "runner.emptyQuestions": ":warning: Claude sent a question with no content. The session has been terminated. Please send a new message to retry.";
|
|
92
|
+
readonly "runner.inactivityTimeout": ":warning: Claude process was terminated after {{minutes}} minutes of inactivity. Send a new message to restart.";
|
|
93
|
+
readonly "runner.planApproved": "Plan approved. Start implementing.";
|
|
94
|
+
readonly "template.frontend": "*Frontend:* ";
|
|
95
|
+
readonly "template.backend": "*Backend:* ";
|
|
96
|
+
readonly "cli.description": "Develop with Claude Code from anywhere.";
|
|
97
|
+
readonly "cli.usage": "Usage:";
|
|
98
|
+
readonly "cli.commands": "Commands:";
|
|
99
|
+
readonly "cli.cmd.start": "Start server (foreground)";
|
|
100
|
+
readonly "cli.cmd.startDaemon": "Register and start as background service (macOS launchd / Windows Task Scheduler)";
|
|
101
|
+
readonly "cli.cmd.stop": "Stop and unregister background service";
|
|
102
|
+
readonly "cli.cmd.status": "Check background service status";
|
|
103
|
+
readonly "cli.cmd.show": "Show saved sessions";
|
|
104
|
+
readonly "cli.cmd.clear": "Delete data files (sessions.json, workspaces.json)";
|
|
105
|
+
readonly "cli.cmd.help": "Show help";
|
|
106
|
+
readonly "cli.notes": "Notes:";
|
|
107
|
+
readonly "cli.notes.daemon": "twindevbot must be running for remote work. Use --daemon so you don't have to restart it every time.";
|
|
108
|
+
readonly "cli.notes.errorLog": "If something seems wrong with the twindevbot server, check the error log.";
|
|
109
|
+
readonly "cli.warning.title": "WARNING";
|
|
110
|
+
readonly "cli.warning.text": "twindevbot launches claude with the --dangerously-skip-permissions flag. Only use twindevbot if you fully understand what this means. The source code is fully open on GitHub. No one is responsible for any incidents caused by using twindevbot.";
|
|
111
|
+
readonly "cli.setup.banner": "twindevbot server setup";
|
|
112
|
+
readonly "cli.setup.promptAppToken": "Enter your SLACK_APP_TOKEN (xapp-...)";
|
|
113
|
+
readonly "cli.setup.promptBotToken": "Enter your SLACK_BOT_TOKEN (xoxb-...)";
|
|
114
|
+
readonly "cli.setup.promptBaseDir": "Enter the parent directory path for project directories";
|
|
115
|
+
readonly "cli.setup.required": "This field is required.";
|
|
116
|
+
readonly "cli.setup.saved": "Configuration saved: {{path}}";
|
|
117
|
+
readonly "cli.setup.startMessage": "Starting server.\n Open Slack and type /twindevbot to get started.";
|
|
118
|
+
readonly "cli.setup.startDaemonMessage": "Starting server as a background service so it stays running.\n Open Slack and type /twindevbot to get started.";
|
|
119
|
+
readonly "cli.daemon.plistCreated": "Created launchd plist: {{path}}";
|
|
120
|
+
readonly "cli.daemon.started": "Background service started successfully.";
|
|
121
|
+
readonly "cli.daemon.failedToStart": "Failed to start service:";
|
|
122
|
+
readonly "cli.daemon.notInstalled": "Background service is not installed.";
|
|
123
|
+
readonly "cli.daemon.stopped": "Background service stopped and unregistered.";
|
|
124
|
+
readonly "cli.status.notInstalled": "Background service: not installed";
|
|
125
|
+
readonly "cli.status.notInstalledHint": "Run 'twindevbot start --daemon' to install.";
|
|
126
|
+
readonly "cli.status.running": "Background service: running (PID {{pid}})";
|
|
127
|
+
readonly "cli.status.registered": "Background service: registered";
|
|
128
|
+
readonly "cli.status.notRunning": "Background service: installed but not running";
|
|
129
|
+
readonly "cli.status.checkLogs": "It may have crashed. Check logs:";
|
|
130
|
+
readonly "cli.daemonUnsupportedPlatform": "Daemon features (start --daemon, stop, status) are supported on macOS and Windows only. Current platform: {{platform}}";
|
|
131
|
+
readonly "cli.daemon.taskCreated": "Created Windows scheduled task: {{name}}";
|
|
132
|
+
readonly "cli.unknownCommand": "Unknown command: {{command}}";
|
|
133
|
+
readonly "cli.show.title": "twindevbot sessions ({{count}})";
|
|
134
|
+
readonly "cli.show.sessionCount": "({{count}} sessions)";
|
|
135
|
+
readonly "cli.show.noSessions": "No saved sessions found.";
|
|
136
|
+
readonly "cli.show.parseError": "Failed to parse sessions.json.";
|
|
137
|
+
readonly "cli.show.daysAgo": "{{n}}d ago";
|
|
138
|
+
readonly "cli.show.hoursAgo": "{{n}}h ago";
|
|
139
|
+
readonly "cli.show.minutesAgo": "{{n}}m ago";
|
|
140
|
+
readonly "cli.show.justNow": "just now";
|
|
141
|
+
readonly "cli.clear.header": "Files to delete:";
|
|
142
|
+
readonly "cli.clear.confirm": "Delete the above files?";
|
|
143
|
+
readonly "cli.clear.noData": "No data files to delete.";
|
|
144
|
+
readonly "cli.clear.cancelled": "Cancelled.";
|
|
145
|
+
readonly "cli.clear.done": "β Data files deleted.";
|
|
146
|
+
readonly "cli.clear.daemonRunning": "β The daemon is currently running. Please stop it first with `twindevbot stop` before clearing data.";
|
|
147
|
+
};
|
|
148
|
+
export type TranslationKey = keyof typeof _en;
|
|
149
|
+
export declare const en: Record<TranslationKey, string>;
|
|
150
|
+
export {};
|
package/dist/i18n/en.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
const _en = {
|
|
2
|
+
// question-blocks.ts
|
|
3
|
+
"question.header": "Question",
|
|
4
|
+
"question.headerCompleted": "Question (Answered)",
|
|
5
|
+
"question.submitSelection": "Submit Selection",
|
|
6
|
+
"question.textInput": "βοΈ Custom Input",
|
|
7
|
+
"question.currentSelection": "_Current selection: {{labels}}_",
|
|
8
|
+
"question.selectHint": "_Select options then press 'Submit Selection'_",
|
|
9
|
+
"question.truncatedOptions": "_Showing {{shown}} of {{total}} options. Use 'Custom Input' for others._",
|
|
10
|
+
// question-handlers.ts (modal)
|
|
11
|
+
"modal.title": "Enter Answer",
|
|
12
|
+
"modal.submit": "Submit",
|
|
13
|
+
"modal.cancel": "Cancel",
|
|
14
|
+
"modal.prompt": "Enter your answer:",
|
|
15
|
+
"modal.label": "Answer",
|
|
16
|
+
"modal.placeholder": "Type your answer...",
|
|
17
|
+
// question-handlers.ts (session)
|
|
18
|
+
"session.expired": "Session for *{{projectName}}* expired. Use `/twindevbot task` to start a new session.",
|
|
19
|
+
"session.expiredUnknown": "Session expired. Use `/twindevbot task` to start a new session.",
|
|
20
|
+
"session.notFound": "Session not found. Use `/twindevbot task` to start a new session.",
|
|
21
|
+
"multiSelect.noneSelected": "Please select at least one option before pressing 'Submit Selection'.",
|
|
22
|
+
"error.actionFailed": ":x: Something went wrong processing your action. Please try again.",
|
|
23
|
+
"error.alreadyProcessing": ":hourglass: Already processing. Please wait for the current task to finish.",
|
|
24
|
+
"error.resumeFailed": ":x: Your answer was received, but failed to resume Claude. Please send a new message to try again.",
|
|
25
|
+
// claude-command.ts
|
|
26
|
+
"command.autopilotNotice": "(Autopilot mode is active.\nA single thread message starts and completes the task.\nAll questions during the process will be auto-answered.\nFor best results, please provide detailed and clear instructions.)",
|
|
27
|
+
"command.newUsage": ":warning: Usage:\n`/twindevbot new <directory> --empty`\n`/twindevbot new <directory> --template react`\n\nAvailable templates:\n{{templates}}",
|
|
28
|
+
"command.newOptionsRequired": ":warning: Please specify an option:\n`/twindevbot new {{dirName}} --empty`\n`/twindevbot new {{dirName}} --template react`\n\nAvailable templates:\n{{templates}}",
|
|
29
|
+
"command.invalidDirName": ":x: `{{dirName}}` is not a valid directory name. Only letters, numbers, hyphens (`-`), underscores (`_`), and dots (`.`) are allowed.",
|
|
30
|
+
"command.dirAlreadyExists": ":x: Directory `{{dirName}}` already exists. Please choose a different name.",
|
|
31
|
+
"command.errorOccurred": ":rotating_light: An error occurred, please try again.\n```{{error}}```",
|
|
32
|
+
"command.emptyDirCreated": ":white_check_mark: Created empty directory `{{dirName}}`.",
|
|
33
|
+
"command.templateNotFound": ":x: Template `{{templateKey}}` not found.\n\nAvailable templates:\n{{templates}}",
|
|
34
|
+
"command.creatingProject": ":hourglass_flowing_sand: Creating `{{templateName}}` project...\nThis may take a moment. I'll let you know when it's done.\n`{{command}}`",
|
|
35
|
+
"command.projectCreated": ":white_check_mark: `{{templateName}}` project created at `{{dirName}}`.",
|
|
36
|
+
"command.autopilotInterruptConfirm": "Interrupting will stop autopilot mode. Would you like to proceed?",
|
|
37
|
+
"command.autopilotInterruptYes": "Yes",
|
|
38
|
+
"command.autopilotInterruptNo": "No",
|
|
39
|
+
"command.autopilotInterruptedYes": "Autopilot mode stopped. Starting work on your message in normal mode.",
|
|
40
|
+
"command.autopilotContinue": "Continuing in autopilot mode.",
|
|
41
|
+
"command.normalInterruptConfirm": "The previous task is still in progress. Would you like to stop it and start a new task? (Not Recommended)",
|
|
42
|
+
"command.normalInterruptYes": "Yes",
|
|
43
|
+
"command.normalInterruptNo": "No",
|
|
44
|
+
"command.normalInterruptedYes": "Previous task stopped. Starting new task now.",
|
|
45
|
+
"command.normalInterruptContinue": "Continuing the previous task. Please send your new command after the current task completes.",
|
|
46
|
+
"interrupt.taskAlreadyCompleted": "The previous task has already completed. Send a new message to start a new task.",
|
|
47
|
+
"interrupt.payloadExpired": ":warning: Your previous message is no longer available. Please resend your instruction.",
|
|
48
|
+
"command.baseDirNotFound": ":x: Project base directory (`{{baseDir}}`) not found.",
|
|
49
|
+
"command.postFailed": "Failed to start the session. Please try again.",
|
|
50
|
+
"command.didYouMean": "Unknown command. Did you mean `/twindevbot {{suggestion}}`?",
|
|
51
|
+
"command.stopped": "Task cancelled.",
|
|
52
|
+
"command.noActiveTask": "No active task to cancel.",
|
|
53
|
+
// init 컀맨λ
|
|
54
|
+
"command.initSelectDir": "Select a working directory for this channel:",
|
|
55
|
+
"command.initEmpty": ":open_file_folder: No directories found in `{{baseDir}}`.\nUse the button below to enter a path manually, or create a project with `/twindevbot new`.",
|
|
56
|
+
"command.initCustomInput": "βοΈ Enter path manually",
|
|
57
|
+
"command.initSuccess": ":white_check_mark: `{{dirName}}` has been set as this channel's working directory.\nUse `/twindevbot task` to start working.",
|
|
58
|
+
"command.initInvalidDir": ":x: Directory `{{directory}}` does not exist.",
|
|
59
|
+
"command.initModalTitle": "Enter Directory",
|
|
60
|
+
"command.initModalLabel": "Directory path",
|
|
61
|
+
"command.initModalPlaceholder": "e.g. my-project or /absolute/path",
|
|
62
|
+
"command.initModalDirNotExist": "Directory does not exist.",
|
|
63
|
+
// task 컀맨λ
|
|
64
|
+
"command.taskNoDir": ":warning: No working directory configured for this channel.\nUse `/twindevbot init` to set one up.",
|
|
65
|
+
"command.taskStarted": ":file_folder: `{{dirName}}` session started.\nContinue in the thread.",
|
|
66
|
+
"command.taskSuccess": ":file_folder: Working on `{{dirName}}`.\nWhat would you like to work on?",
|
|
67
|
+
// help
|
|
68
|
+
"command.help": ":robot_face: *TwinDevBot Commands*\nDevelop with Claude Code from anywhere.\n\n:warning: *Before you start:* Invite the bot to this channel first (`/invite @TwinDevBot`). The bot must be a channel member to receive your messages.\n\n\n:wrench: *Set up channel*\n`/twindevbot init`\nSelect or enter a working directory for this channel.\n\n\n:rocket: *Start a task*\n`/twindevbot task`\n`/twindevbot task --autopilot`\nStart a new Claude session in the channel's working directory.\n\n\n:hammer_and_wrench: *Create project*\n`/twindevbot new <directory> --empty`\n`/twindevbot new <directory> --template <framework>`\n`/twindevbot new <directory> --template <framework> --autopilot`\n{{templates}}\n\n\n:octagonal_sign: *Stop running task*\n`/twindevbot stop`\nCancel the currently running Claude task.\n\n\n:bulb: *Notes*\n* Use `init` once per channel to link it to a project directory.\n* Use `task` to start a new task thread.\n* `--autopilot` mode: twindevbot automatically answers all questions and develops on its own.",
|
|
69
|
+
// slack-message.ts
|
|
70
|
+
"slack.answered": "Answer submitted",
|
|
71
|
+
"slack.question": "Question",
|
|
72
|
+
// progress-tracker.ts
|
|
73
|
+
"progress.tool.Read": "Reading file",
|
|
74
|
+
"progress.tool.Write": "Writing file",
|
|
75
|
+
"progress.tool.Edit": "Editing file",
|
|
76
|
+
"progress.tool.Bash": "Running command",
|
|
77
|
+
"progress.tool.Grep": "Searching code",
|
|
78
|
+
"progress.tool.Glob": "Finding files",
|
|
79
|
+
"progress.tool.Task": "Processing subtask",
|
|
80
|
+
"progress.tool.WebSearch": "Searching the web",
|
|
81
|
+
"progress.tool.WebFetch": "Fetching web page",
|
|
82
|
+
"progress.tool.NotebookEdit": "Editing notebook",
|
|
83
|
+
"progress.tool.default": "Running tool",
|
|
84
|
+
"progress.working": ":gear: Starting work...",
|
|
85
|
+
"progress.completed": ":white_check_mark: Completed ({{elapsed}})",
|
|
86
|
+
"progress.error": ":x: Error occurred: {{error}}",
|
|
87
|
+
"progress.planApproved": ":thumbsup: Plan approved. Starting implementation...",
|
|
88
|
+
"progress.autopilotContinue": ":robot_face: Auto-responded, continuing... ({{elapsed}})",
|
|
89
|
+
"progress.askUser": ":raised_hand: Question sent. Waiting for answer.",
|
|
90
|
+
"progress.lessThanOneSecond": "<1s",
|
|
91
|
+
"progress.seconds": "{{n}}s",
|
|
92
|
+
"progress.minutesSeconds": "{{m}}m {{s}}s",
|
|
93
|
+
// claude-runner-setup.ts
|
|
94
|
+
"runner.questionArrived": "Claude Code question arrived",
|
|
95
|
+
"runner.autopilotAnswer": ":robot_face: Autopilot: auto-selected {{answer}}",
|
|
96
|
+
"runner.errorOccurred": "Error: {{error}}",
|
|
97
|
+
"runner.claudeNotFound": "Claude CLI is not installed or not found in PATH. Please install it with `npm install -g @anthropic-ai/claude-code`.",
|
|
98
|
+
"runner.exitError": ":x: Claude process exited abnormally (code: {{code}}). Check logs for details.",
|
|
99
|
+
"runner.autopilotResumeFailed": ":x: Autopilot: Failed to resume Claude.",
|
|
100
|
+
"runner.autopilotNoSession": ":x: Autopilot: No session ID available, cannot resume.",
|
|
101
|
+
"runner.emptyQuestions": ":warning: Claude sent a question with no content. The session has been terminated. Please send a new message to retry.",
|
|
102
|
+
"runner.inactivityTimeout": ":warning: Claude process was terminated after {{minutes}} minutes of inactivity. Send a new message to restart.",
|
|
103
|
+
"runner.planApproved": "Plan approved. Start implementing.",
|
|
104
|
+
// templates.ts
|
|
105
|
+
"template.frontend": "*Frontend:* ",
|
|
106
|
+
"template.backend": "*Backend:* ",
|
|
107
|
+
// cli.ts
|
|
108
|
+
"cli.description": "Develop with Claude Code from anywhere.",
|
|
109
|
+
"cli.usage": "Usage:",
|
|
110
|
+
"cli.commands": "Commands:",
|
|
111
|
+
"cli.cmd.start": "Start server (foreground)",
|
|
112
|
+
"cli.cmd.startDaemon": "Register and start as background service (macOS launchd / Windows Task Scheduler)",
|
|
113
|
+
"cli.cmd.stop": "Stop and unregister background service",
|
|
114
|
+
"cli.cmd.status": "Check background service status",
|
|
115
|
+
"cli.cmd.show": "Show saved sessions",
|
|
116
|
+
"cli.cmd.clear": "Delete data files (sessions.json, workspaces.json)",
|
|
117
|
+
"cli.cmd.help": "Show help",
|
|
118
|
+
"cli.notes": "Notes:",
|
|
119
|
+
"cli.notes.daemon": "twindevbot must be running for remote work. Use --daemon so you don't have to restart it every time.",
|
|
120
|
+
"cli.notes.errorLog": "If something seems wrong with the twindevbot server, check the error log.",
|
|
121
|
+
"cli.warning.title": "WARNING",
|
|
122
|
+
"cli.warning.text": "twindevbot launches claude with the --dangerously-skip-permissions flag. Only use twindevbot if you fully understand what this means. The source code is fully open on GitHub. No one is responsible for any incidents caused by using twindevbot.",
|
|
123
|
+
// setup.ts
|
|
124
|
+
"cli.setup.banner": "twindevbot server setup",
|
|
125
|
+
"cli.setup.promptAppToken": "Enter your SLACK_APP_TOKEN (xapp-...)",
|
|
126
|
+
"cli.setup.promptBotToken": "Enter your SLACK_BOT_TOKEN (xoxb-...)",
|
|
127
|
+
"cli.setup.promptBaseDir": "Enter the parent directory path for project directories",
|
|
128
|
+
"cli.setup.required": "This field is required.",
|
|
129
|
+
"cli.setup.saved": "Configuration saved: {{path}}",
|
|
130
|
+
"cli.setup.startMessage": "Starting server.\n Open Slack and type /twindevbot to get started.",
|
|
131
|
+
"cli.setup.startDaemonMessage": "Starting server as a background service so it stays running.\n Open Slack and type /twindevbot to get started.",
|
|
132
|
+
"cli.daemon.plistCreated": "Created launchd plist: {{path}}",
|
|
133
|
+
"cli.daemon.started": "Background service started successfully.",
|
|
134
|
+
"cli.daemon.failedToStart": "Failed to start service:",
|
|
135
|
+
"cli.daemon.notInstalled": "Background service is not installed.",
|
|
136
|
+
"cli.daemon.stopped": "Background service stopped and unregistered.",
|
|
137
|
+
"cli.status.notInstalled": "Background service: not installed",
|
|
138
|
+
"cli.status.notInstalledHint": "Run 'twindevbot start --daemon' to install.",
|
|
139
|
+
"cli.status.running": "Background service: running (PID {{pid}})",
|
|
140
|
+
"cli.status.registered": "Background service: registered",
|
|
141
|
+
"cli.status.notRunning": "Background service: installed but not running",
|
|
142
|
+
"cli.status.checkLogs": "It may have crashed. Check logs:",
|
|
143
|
+
"cli.daemonUnsupportedPlatform": "Daemon features (start --daemon, stop, status) are supported on macOS and Windows only. Current platform: {{platform}}",
|
|
144
|
+
"cli.daemon.taskCreated": "Created Windows scheduled task: {{name}}",
|
|
145
|
+
"cli.unknownCommand": "Unknown command: {{command}}",
|
|
146
|
+
// cli.ts - show
|
|
147
|
+
"cli.show.title": "twindevbot sessions ({{count}})",
|
|
148
|
+
"cli.show.sessionCount": "({{count}} sessions)",
|
|
149
|
+
"cli.show.noSessions": "No saved sessions found.",
|
|
150
|
+
"cli.show.parseError": "Failed to parse sessions.json.",
|
|
151
|
+
"cli.show.daysAgo": "{{n}}d ago",
|
|
152
|
+
"cli.show.hoursAgo": "{{n}}h ago",
|
|
153
|
+
"cli.show.minutesAgo": "{{n}}m ago",
|
|
154
|
+
"cli.show.justNow": "just now",
|
|
155
|
+
// cli.ts - clear
|
|
156
|
+
"cli.clear.header": "Files to delete:",
|
|
157
|
+
"cli.clear.confirm": "Delete the above files?",
|
|
158
|
+
"cli.clear.noData": "No data files to delete.",
|
|
159
|
+
"cli.clear.cancelled": "Cancelled.",
|
|
160
|
+
"cli.clear.done": "β Data files deleted.",
|
|
161
|
+
"cli.clear.daemonRunning": "β The daemon is currently running. Please stop it first with `twindevbot stop` before clearing data.",
|
|
162
|
+
};
|
|
163
|
+
export const en = _en;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type TranslationKey } from "./en.js";
|
|
2
|
+
export type { TranslationKey };
|
|
3
|
+
type Locale = "en";
|
|
4
|
+
/**
|
|
5
|
+
* Initialize locale. Currently only "en" is supported.
|
|
6
|
+
*
|
|
7
|
+
* To add a new locale:
|
|
8
|
+
* 1. Create a new translation file (e.g. ko.ts).
|
|
9
|
+
* 2. Extend the Locale union type.
|
|
10
|
+
* 3. Add parsing logic here to detect the locale (e.g. from an env var).
|
|
11
|
+
*/
|
|
12
|
+
export declare function initLocale(): void;
|
|
13
|
+
export declare function getCurrentLocale(): Locale;
|
|
14
|
+
/**
|
|
15
|
+
* Look up a translation key for the current locale.
|
|
16
|
+
* Replaces {{param}} placeholders with values from params.
|
|
17
|
+
*
|
|
18
|
+
* Fallback chain: current locale -> en -> raw key string.
|
|
19
|
+
*/
|
|
20
|
+
export declare function t(key: TranslationKey, params?: Record<string, string | number>): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { en } from "./en.js";
|
|
2
|
+
const translations = { en };
|
|
3
|
+
let currentLocale = "en";
|
|
4
|
+
/**
|
|
5
|
+
* Initialize locale. Currently only "en" is supported.
|
|
6
|
+
*
|
|
7
|
+
* To add a new locale:
|
|
8
|
+
* 1. Create a new translation file (e.g. ko.ts).
|
|
9
|
+
* 2. Extend the Locale union type.
|
|
10
|
+
* 3. Add parsing logic here to detect the locale (e.g. from an env var).
|
|
11
|
+
*/
|
|
12
|
+
export function initLocale() {
|
|
13
|
+
// no-op while only "en" is supported
|
|
14
|
+
}
|
|
15
|
+
export function getCurrentLocale() {
|
|
16
|
+
return currentLocale;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Look up a translation key for the current locale.
|
|
20
|
+
* Replaces {{param}} placeholders with values from params.
|
|
21
|
+
*
|
|
22
|
+
* Fallback chain: current locale -> en -> raw key string.
|
|
23
|
+
*/
|
|
24
|
+
export function t(key, params) {
|
|
25
|
+
const map = translations[currentLocale];
|
|
26
|
+
let text = map[key] ?? translations.en[key] ?? key;
|
|
27
|
+
if (params) {
|
|
28
|
+
text = text.replace(/\{\{(\w+)\}\}/g, (match, k) => k in params ? String(params[k]) : match);
|
|
29
|
+
}
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ko: Record<string, string>;
|
package/dist/i18n/ko.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
export const ko = {
|
|
2
|
+
// question-blocks.ts
|
|
3
|
+
"question.header": "μ§λ¬Έ",
|
|
4
|
+
"question.headerCompleted": "μ§λ¬Έ (λ΅λ³ μλ£)",
|
|
5
|
+
"question.submitSelection": "μ ν μλ£",
|
|
6
|
+
"question.textInput": "βοΈ μ§μ μ
λ ₯",
|
|
7
|
+
"question.currentSelection": "_νμ¬ μ ν: {{labels}}_",
|
|
8
|
+
"question.selectHint": "_μ΅μ
μ μ νν ν 'μ ν μλ£' λ²νΌμ λλ¬μ£ΌμΈμ_",
|
|
9
|
+
"question.truncatedOptions": "_{{total}}κ° μ€ {{shown}}κ° μ΅μ
λ§ νμλ©λλ€. λλ¨Έμ§λ 'μ§μ μ
λ ₯'μ μ΄μ©ν΄μ£ΌμΈμ._",
|
|
10
|
+
// question-handlers.ts (modal)
|
|
11
|
+
"modal.title": "λ΅λ³ μ
λ ₯",
|
|
12
|
+
"modal.submit": "μ μ‘",
|
|
13
|
+
"modal.cancel": "μ·¨μ",
|
|
14
|
+
"modal.prompt": "λ΅λ³μ μ
λ ₯νμΈμ:",
|
|
15
|
+
"modal.label": "λ΅λ³",
|
|
16
|
+
"modal.placeholder": "λ΅λ³μ μ
λ ₯νμΈμ...",
|
|
17
|
+
// question-handlers.ts (session)
|
|
18
|
+
"session.expired": "μΈμ
μ΄ λ§λ£λμμ΅λλ€. `/twindevbot goto νλ‘μ νΈλͺ
`μΌλ‘ μ μΈμ
μ μμνμΈμ.",
|
|
19
|
+
"multiSelect.noneSelected": "μ΅μ
μ νλ μ΄μ μ νν ν 'μ ν μλ£' λ²νΌμ λλ¬μ£ΌμΈμ.",
|
|
20
|
+
// claude-command.ts
|
|
21
|
+
"command.gotoUsage": ":warning: μ¬μ©λ²: `/twindevbot goto <λλ ν 리λͺ
>`\nμ: `/twindevbot goto my-project`",
|
|
22
|
+
"command.dirNotFound": ":x: `{{dirName}}` λλ ν λ¦¬κ° μ‘΄μ¬νμ§ μμ΅λλ€.\n`/twindevbot new {{dirName}} --empty` λλ `/twindevbot new {{dirName}} --template <templateName>` λͺ
λ Ήμ λ¨Όμ μ€νν΄μ£ΌμΈμ.\n\nμ¬μ© κ°λ₯ν ν
νλ¦Ώ:\n{{templates}}",
|
|
23
|
+
"command.sessionStarted": ":file_folder: `{{dirName}}` λλ ν 리μμ μ μΈμ
μ΄ μμλμ΅λλ€.\nμ€λ λμμ μμ
μ μ§ννμΈμ.",
|
|
24
|
+
"command.gotoSuccess": ":file_folder: `{{dirName}}`(μΌ)λ‘ μ΄λνμ΅λλ€.\nλ¬΄μ¨ μμ
μ μμν κΉμ?",
|
|
25
|
+
"command.autopilotNotice": "(νμ¬ autopilot λͺ¨λμ
λλ€.\nνλ²μ μ€λ λ λ©μμ§ μ
λ ₯λ§μΌλ‘ μμ
μ΄ μμ~μλ£λκ³ \nμμ
λμ€ λ°μνλ λͺ¨λ μ§λ¬Έλ€μ μλ μλ΅ μ²λ¦¬λ©λλ€.\nλ°λΌμ μ’μ κ²°κ³Όλ₯Ό μν΄ μ΅λν μΉμ νκ³ μμΈν λ΄μ©μ λ©μμ§λ‘\nλͺ
λ Ήμ λ΄λ €μ£ΌμΈμ.)",
|
|
26
|
+
"command.newUsage": ":warning: μ¬μ©λ²:\n`/twindevbot new <λλ ν 리λͺ
> --empty`\n`/twindevbot new <λλ ν 리λͺ
> --template <templateName>`\n\nμ¬μ© κ°λ₯ν ν
νλ¦Ώ:\n{{templates}}",
|
|
27
|
+
"command.newOptionsRequired": ":warning: μ΅μ
μ μ§μ ν΄μ£ΌμΈμ:\n`/twindevbot new {{dirName}} --empty`\n`/twindevbot new {{dirName}} --template react`\n\nμ¬μ© κ°λ₯ν ν
νλ¦Ώ:\n{{templates}}",
|
|
28
|
+
"command.invalidDirName": ":x: `{{dirName}}`μ(λ) μ ν¨νμ§ μμ λλ ν 리λͺ
μ
λλ€. μλ¬Έ, μ«μ, νμ΄ν(`-`), λ°μ€(`_`), λ§μΉ¨ν(`.`)λ§ μ¬μ©ν μ μμ΅λλ€.",
|
|
29
|
+
"command.dirAlreadyExists": ":x: `{{dirName}}` λλ ν λ¦¬κ° μ΄λ―Έ μ‘΄μ¬ν©λλ€. λ€λ₯Έ μ΄λ¦μΌλ‘ λλ ν 리λ₯Ό μμ±νμΈμ.",
|
|
30
|
+
"command.errorOccurred": ":rotating_light: μ΄λ° μλ¬κ° λ°μνμ΄μ, λ€μ μλν΄λ³΄μΈμ.\n```{{error}}```",
|
|
31
|
+
"command.emptyDirCreated": ":white_check_mark: `{{dirName}}` λΉ λλ ν 리λ₯Ό μμ±νμ΅λλ€.",
|
|
32
|
+
"command.templateNotFound": ":x: `{{templateKey}}` ν
νλ¦Ώμ μ°Ύμ μ μμ΅λλ€.\n\nμ¬μ© κ°λ₯ν ν
νλ¦Ώ:\n{{templates}}",
|
|
33
|
+
"command.creatingProject": ":hourglass_flowing_sand: `{{templateName}}` νλ‘μ νΈλ₯Ό μμ± μ€μ
λλ€...\nμκ°μ΄ μ‘°κΈ κ±Έλ¦΄ μ μμ΅λλ€. λͺ¨λ μλ£λλ©΄ λ€μ λ΅λ³λ릴κ²μ.\n`{{command}}`",
|
|
34
|
+
"command.projectCreated": ":white_check_mark: `{{templateName}}` νλ‘μ νΈκ° `{{dirName}}`μ μμ±λμμ΅λλ€.",
|
|
35
|
+
"command.autopilotInterruptConfirm": "μ€κ°μ κ°μ
νμλ©΄ autopilot λͺ¨λλ μ€λ¨λ©λλ€. κ·Έλ κ² ν κΉμ?",
|
|
36
|
+
"command.autopilotInterruptYes": "λ€",
|
|
37
|
+
"command.autopilotInterruptNo": "μλμ",
|
|
38
|
+
"command.autopilotInterruptedYes": "autopilot λͺ¨λλ₯Ό μ€λ¨ν©λλ€. λ§μνμ λ΄μ©μ μΌλ° λͺ¨λλ‘ μμ
μμν©λλ€.",
|
|
39
|
+
"command.autopilotContinue": "autopilot λͺ¨λλ‘ κ³μ μ§νν©λλ€.",
|
|
40
|
+
"command.normalInterruptConfirm": "μμ§ μμ
μ΄ μλ£λμ§ μμμ΅λλ€. μ΄μ μμ
μ μ€λ¨νκ³ λ°λ‘ μ μμ
μ μμν κΉμ? (Not Recommended)",
|
|
41
|
+
"command.normalInterruptYes": "μ",
|
|
42
|
+
"command.normalInterruptNo": "μλμ€",
|
|
43
|
+
"command.normalInterruptedYes": "μ΄μ μμ
μ μ€λ¨νκ³ μ μμ
μ μμν©λλ€.",
|
|
44
|
+
"command.normalInterruptContinue": "μ΄μ μμ
μ κ³μ μ§νν©λλ€, μ λͺ
λ Ήμ μμ
μλ£ νμ λ΄λ €μ£ΌμΈμ.",
|
|
45
|
+
"command.listResult": ":file_folder: `{{baseDir}}`μ νμ¬ λ€μκ³Ό κ°μ λλ ν 리λ€μ΄ μμ΅λλ€.\n\n{{dirList}}\n\n`/twindevbot goto <λλ ν 리λͺ
>`μΌλ‘ μμ
μ μμν΄λ³΄μΈμ.",
|
|
46
|
+
"command.listEmpty": ":open_file_folder: `{{baseDir}}`μ νμ¬ λλ ν λ¦¬κ° μμ΅λλ€.\n`/twindevbot new <λλ ν 리λͺ
> --empty` λλ `/twindevbot new <λλ ν 리λͺ
> --template <templateName>`μΌλ‘ νλ‘μ νΈλ₯Ό μμ±ν΄λ³΄μΈμ.",
|
|
47
|
+
"command.baseDirNotFound": ":x: νλ‘μ νΈ λΆλͺ¨ λλ ν 리(`{{baseDir}}`)λ₯Ό μ°Ύμ μ μμ΅λλ€.",
|
|
48
|
+
"command.help": ":robot_face: *TwinDevBot λͺ
λ Ήμ΄*\nμΈμ μ΄λμλ Claude Codeλ‘ κ°λ°νμΈμ.\n\nββββββββββββββββββββ\n\n:rocket: *νλ‘μ νΈ μ΄λ*\n`/twindevbot goto <λλ ν 리λͺ
>`\n`/twindevbot goto <λλ ν 리λͺ
> --autopilot`\n\nββββββββββββββββββββ\n\n:mag: *νλ‘μ νΈ λͺ©λ‘*\n`/twindevbot list`\n\nββββββββββββββββββββ\n\n:hammer_and_wrench: *νλ‘μ νΈ μμ±*\n`/twindevbot new <λλ ν 리λͺ
> --empty`\n`/twindevbot new <λλ ν 리λͺ
> --template <νλ μμν¬>`\n{{templates}}\n\nββββββββββββββββββββ\n\n:bulb: *μ°Έκ³ μ¬ν*\n* λͺ¨λ κ²½λ‘λ `{{baseDir}}` κΈ°μ€μ
λλ€.\n* νλμ Claude Session μ λνλ λμΌ λ©μμ§ μ μ€λ λλ€λ‘ μ΄λ£¨μ΄μ§λλ€.\n* νλ‘μ νΈ λλ ν 리 μμ±λ§νΌμ `twindevbot new` λͺ
λ ΉμΌλ‘ ν기보λ€λ λ³ΈμΈ λ
ΈνΈλΆμμ νλ‘μ νΈ λλ ν 리λ₯Ό μνλ λͺ¨μ΅μΌλ‘ μ§μ μμ±νκ³ , κ°μ’
컨ν
μ€νΈ λ£°(ex. `CLAUDE.md`, `.claude/rules/*`) νμΌμ μ μ©ν΄λ λ€, `twindevbot goto`λ‘ μμ
νμκΈ°λ₯Ό μΆμ²λ립λλ€.\n\n* `--autopilot` λͺ¨λ: twindevbotμ΄ λͺ¨λ μ§λ¬Έμ μλμΌλ‘ λ΅νλ©° μμμ κ°λ°ν©λλ€. κ°λ²Όμ΄ νλ‘μ νΈλ₯Ό μμ
νκ±°λ, μ λ€κΈ° μ μ μ¬μ©ν΄λ³΄μΈμ.",
|
|
49
|
+
// slack-message.ts
|
|
50
|
+
"slack.answered": "λ΅λ³ μλ£",
|
|
51
|
+
"slack.question": "μ§λ¬Έ",
|
|
52
|
+
// progress-tracker.ts
|
|
53
|
+
"progress.tool.Read": "νμΌμ μ½κ³ μμ΅λλ€",
|
|
54
|
+
"progress.tool.Write": "νμΌμ μμ±νκ³ μμ΅λλ€",
|
|
55
|
+
"progress.tool.Edit": "νμΌμ μμ νκ³ μμ΅λλ€",
|
|
56
|
+
"progress.tool.Bash": "λͺ
λ Ήμ΄λ₯Ό μ€ννκ³ μμ΅λλ€",
|
|
57
|
+
"progress.tool.Grep": "μ½λλ₯Ό κ²μνκ³ μμ΅λλ€",
|
|
58
|
+
"progress.tool.Glob": "νμΌμ μ°Ύκ³ μμ΅λλ€",
|
|
59
|
+
"progress.tool.Task": "νμ μμ
μ μ²λ¦¬νκ³ μμ΅λλ€",
|
|
60
|
+
"progress.tool.WebSearch": "μΉμ κ²μνκ³ μμ΅λλ€",
|
|
61
|
+
"progress.tool.WebFetch": "μΉ νμ΄μ§λ₯Ό κ°μ Έμ€κ³ μμ΅λλ€",
|
|
62
|
+
"progress.tool.NotebookEdit": "λ
ΈνΈλΆμ μμ νκ³ μμ΅λλ€",
|
|
63
|
+
"progress.tool.default": "λꡬλ₯Ό μ€ννκ³ μμ΅λλ€",
|
|
64
|
+
"progress.working": ":gear: μμ
μ μμν©λλ€...",
|
|
65
|
+
"progress.completed": ":white_check_mark: μμ
μλ£ ({{elapsed}})",
|
|
66
|
+
"progress.error": ":x: μ€λ₯κ° λ°μνμ΅λλ€: {{error}}",
|
|
67
|
+
"progress.planApproved": ":thumbsup: κ³νμ΄ μΉμΈλμμ΅λλ€. ꡬνμ μμν©λλ€...",
|
|
68
|
+
"progress.autopilotContinue": ":robot_face: μλ μλ΅ μλ£, κ³μ μ§ν μ€... ({{elapsed}})",
|
|
69
|
+
"progress.askUser": ":raised_hand: μ§λ¬Έμ μ μ‘νμ΅λλ€. λ΅λ³μ κΈ°λ€λ¦¬κ³ μμ΅λλ€.",
|
|
70
|
+
"progress.lessThanOneSecond": "1μ΄ λ―Έλ§",
|
|
71
|
+
"progress.seconds": "{{n}}μ΄",
|
|
72
|
+
"progress.minutesSeconds": "{{m}}λΆ {{s}}μ΄",
|
|
73
|
+
// claude-runner-setup.ts
|
|
74
|
+
"runner.questionArrived": "Claude Code μ§λ¬Έμ΄ λμ°©νμ΅λλ€",
|
|
75
|
+
"runner.autopilotAnswer": ":robot_face: Autopilot: *{{answer}}* μλ μ ν",
|
|
76
|
+
"runner.errorOccurred": "μ€λ₯ λ°μ: {{error}}",
|
|
77
|
+
"runner.claudeNotFound": "Claude CLIκ° μ€μΉλμ΄ μμ§ μκ±°λ PATHμ λ±λ‘λμ΄ μμ§ μμ΅λλ€. `npm install -g @anthropic-ai/claude-code` λͺ
λ ΉμΌλ‘ μ€μΉν΄μ£ΌμΈμ.",
|
|
78
|
+
"runner.exitError": ":x: Claude νλ‘μΈμ€κ° λΉμ μ μ’
λ£λμμ΅λλ€ (μ½λ: {{code}})",
|
|
79
|
+
"runner.autopilotResumeFailed": ":x: Autopilot: Claude μ¬μμμ μ€ν¨νμ΅λλ€.",
|
|
80
|
+
"runner.autopilotNoSession": ":x: Autopilot: μΈμ
IDλ₯Ό μ°Ύμ μ μμ΄ μ¬μμν μ μμ΅λλ€.",
|
|
81
|
+
"runner.inactivityTimeout": ":warning: Claude νλ‘μΈμ€κ° 30λΆκ° μλ΅μ΄ μμ΄ μλ μ’
λ£λμμ΅λλ€. μ λ©μμ§λ₯Ό λ³΄λ΄ λ€μ μμν μ μμ΅λλ€.",
|
|
82
|
+
"runner.planApproved": "κ³νμ΄ μΉμΈλμμ΅λλ€. ꡬνμ μμνμΈμ.",
|
|
83
|
+
// templates.ts
|
|
84
|
+
"template.frontend": "*Frontend:* ",
|
|
85
|
+
"template.backend": "*Backend:* ",
|
|
86
|
+
// cli.ts
|
|
87
|
+
"cli.description": "μΈμ μ΄λμλ Claude Codeλ‘ κ°λ°νμΈμ.",
|
|
88
|
+
"cli.usage": "μ¬μ©λ²:",
|
|
89
|
+
"cli.commands": "λͺ
λ Ήμ΄:",
|
|
90
|
+
"cli.cmd.start": "μλ² μμ (ν¬κ·ΈλΌμ΄λ)",
|
|
91
|
+
"cli.cmd.startDaemon": "μλ²λ₯Ό λ°±κ·ΈλΌμ΄λ μλΉμ€λ‘ λ±λ‘ λ° μμ (macOS launchd / Windows μμ
μ€μΌμ€λ¬)",
|
|
92
|
+
"cli.cmd.stop": "λ°±κ·ΈλΌμ΄λ μλΉμ€ μ€μ§ λ° ν΄μ ",
|
|
93
|
+
"cli.cmd.status": "λ°±κ·ΈλΌμ΄λ μλΉμ€ μν νμΈ",
|
|
94
|
+
"cli.cmd.show": "μ μ₯λ μΈμ
λͺ©λ‘ μ‘°ν",
|
|
95
|
+
"cli.cmd.clear": "μ μ₯λ λ°μ΄ν° νμΌ μμ (sessions.json, workspaces.json)",
|
|
96
|
+
"cli.cmd.help": "λμλ§ νμ",
|
|
97
|
+
"cli.notes": "μ£Όμμ¬ν:",
|
|
98
|
+
"cli.notes.daemon": "twindevbotμ΄ μ€νλ μνμ¬μΌ μ격 μμ
μ΄ κ°λ₯ν©λλ€. --daemon μ΅μ
μΌλ‘ μ€νν΄λμλ©΄ λ§€λ² λ€μ μ€νν νμκ° μμ΄μ.",
|
|
99
|
+
"cli.notes.errorLog": "twindevbot μλ²μ λ¬Έμ κ° μλ κ² κ°λ€λ©΄, μλ¬ λ‘κ·Έλ₯Ό νμΈν΄λ³΄μΈμ.",
|
|
100
|
+
"cli.warning.title": "κ²½κ³ ",
|
|
101
|
+
"cli.warning.text": "twindevbotμ μ¬μ©νλ©΄ claudeκ° --dangerously-skip-permissions μ΅μ
μΌλ‘ μμλ©λλ€. μ΄κ²μ μλ―Έλ₯Ό λΆλͺ
ν μλ λΆλ€λ§ twindevbotμ μ¬μ©νμΈμ. twindevbotμ μ½λλ GitHubμ λͺ¨λ 곡κ°λμ΄ μμ΅λλ€. twindevbot μ¬μ©μΌλ‘ μΈν΄ μ΄λ€ μ¬κ³ κ° λ°μνλλΌλ μ무λ μ±
μμ§μ§ μμ΅λλ€.",
|
|
102
|
+
// setup.ts
|
|
103
|
+
"cli.setup.banner": "twindevbot μλ² μ€μ ",
|
|
104
|
+
"cli.setup.promptAppToken": "SLACK_APP_TOKENμ μ
λ ₯νμΈμ (xapp-...)",
|
|
105
|
+
"cli.setup.promptBotToken": "SLACK_BOT_TOKENμ μ
λ ₯νμΈμ (xoxb-...)",
|
|
106
|
+
"cli.setup.promptBaseDir": "νλ‘μ νΈ λλ ν 리λ€μ λ§λ€ λΆλͺ¨ λλ ν 리 κ²½λ‘λ₯Ό μμ±νμΈμ",
|
|
107
|
+
"cli.setup.promptLang": "μΈμ΄λ₯Ό μ ννμΈμ",
|
|
108
|
+
"cli.setup.required": "κ°μ μ
λ ₯ν΄μ£ΌμΈμ.",
|
|
109
|
+
"cli.setup.saved": "μ€μ μ΄ μ μ₯λμμ΅λλ€: {{path}}",
|
|
110
|
+
"cli.setup.startMessage": "μλ²λ₯Ό μμν©λλ€.\n μ΄μ μ¬λμμ /twindevbotμ΄λΌκ³ μ°κ³ μμ
ν΄λ³΄μΈμ.",
|
|
111
|
+
"cli.setup.startDaemonMessage": "μλ²λ₯Ό μμν©λλ€. μΈμ λ μ€νλμ΄ μλλ‘ λ°±κ·ΈλΌμ΄λ μλΉμ€λ‘ λ±λ‘ν©λλ€.\n μ΄μ μ¬λμμ /twindevbotμ΄λΌκ³ μ°κ³ μμ
ν΄λ³΄μΈμ.",
|
|
112
|
+
"cli.daemon.plistCreated": "launchd plist μμ±: {{path}}",
|
|
113
|
+
"cli.daemon.started": "λ°±κ·ΈλΌμ΄λ μλΉμ€κ° μμλμμ΅λλ€.",
|
|
114
|
+
"cli.daemon.failedToStart": "μλΉμ€ μμ μ€ν¨:",
|
|
115
|
+
"cli.daemon.notInstalled": "λ°±κ·ΈλΌμ΄λ μλΉμ€κ° μ€μΉλμ΄ μμ§ μμ΅λλ€.",
|
|
116
|
+
"cli.daemon.stopped": "λ°±κ·ΈλΌμ΄λ μλΉμ€κ° μ€μ§ λ° ν΄μ λμμ΅λλ€.",
|
|
117
|
+
"cli.status.notInstalled": "λ°±κ·ΈλΌμ΄λ μλΉμ€: λ―Έμ€μΉ",
|
|
118
|
+
"cli.status.notInstalledHint": "'twindevbot start --daemon'μΌλ‘ μ€μΉνμΈμ.",
|
|
119
|
+
"cli.status.running": "λ°±κ·ΈλΌμ΄λ μλΉμ€: μ€ν μ€ (PID {{pid}})",
|
|
120
|
+
"cli.status.registered": "λ°±κ·ΈλΌμ΄λ μλΉμ€: λ±λ‘λ¨",
|
|
121
|
+
"cli.status.notRunning": "λ°±κ·ΈλΌμ΄λ μλΉμ€: μ€μΉλμμΌλ μ€ν μ€μ΄ μλλλ€",
|
|
122
|
+
"cli.status.checkLogs": "ν¬λμνμ μ μμ΅λλ€. λ‘κ·Έλ₯Ό νμΈνμΈμ:",
|
|
123
|
+
"cli.daemonUnsupportedPlatform": "daemon κΈ°λ₯(start --daemon, stop, status)μ macOSμ Windowsμμλ§ μ¬μ©ν μ μμ΅λλ€. νμ¬ νλ«νΌ: {{platform}}",
|
|
124
|
+
"cli.daemon.taskCreated": "Windows μμ½ μμ
μμ±: {{name}}",
|
|
125
|
+
"cli.unknownCommand": "μ μ μλ λͺ
λ Ήμ΄: {{command}}",
|
|
126
|
+
// cli.ts - show
|
|
127
|
+
"cli.show.title": "twindevbot sessions ({{count}})",
|
|
128
|
+
"cli.show.sessionCount": "({{count}}κ° μΈμ
)",
|
|
129
|
+
"cli.show.noSessions": "μ μ₯λ μΈμ
μ΄ μμ΅λλ€.",
|
|
130
|
+
"cli.show.parseError": "sessions.json νμΌμ νμ±ν μ μμ΅λλ€.",
|
|
131
|
+
"cli.show.daysAgo": "{{n}}μΌ μ ",
|
|
132
|
+
"cli.show.hoursAgo": "{{n}}μκ° μ ",
|
|
133
|
+
"cli.show.minutesAgo": "{{n}}λΆ μ ",
|
|
134
|
+
"cli.show.justNow": "λ°©κΈ μ ",
|
|
135
|
+
// cli.ts - clear
|
|
136
|
+
"cli.clear.header": "μμ ν νμΌ:",
|
|
137
|
+
"cli.clear.confirm": "μ νμΌλ€μ μμ νμκ² μ΅λκΉ?",
|
|
138
|
+
"cli.clear.noData": "μμ ν λ°μ΄ν° νμΌμ΄ μμ΅λλ€.",
|
|
139
|
+
"cli.clear.cancelled": "μ·¨μλμμ΅λλ€.",
|
|
140
|
+
"cli.clear.done": "β λ°μ΄ν° νμΌμ΄ μμ λμμ΅λλ€.",
|
|
141
|
+
};
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
2
|
+
declare class Logger {
|
|
3
|
+
private level;
|
|
4
|
+
private context?;
|
|
5
|
+
private static logStream;
|
|
6
|
+
constructor(level?: LogLevel, context?: string);
|
|
7
|
+
static enableFileLogging(filePath: string): void;
|
|
8
|
+
private shouldLog;
|
|
9
|
+
private formatMessage;
|
|
10
|
+
private output;
|
|
11
|
+
debug(message: string, data?: unknown): void;
|
|
12
|
+
info(message: string, data?: unknown): void;
|
|
13
|
+
warn(message: string, data?: unknown): void;
|
|
14
|
+
error(message: string, error?: unknown): void;
|
|
15
|
+
child(context: string): Logger;
|
|
16
|
+
}
|
|
17
|
+
export declare const logger: Logger;
|
|
18
|
+
export declare function createLogger(context: string): Logger;
|
|
19
|
+
export declare function enableFileLogging(filePath: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Slack Boltμ© λ‘κ±° μ΄λν°.
|
|
22
|
+
* Bolt λ΄λΆ λ‘κ·Έλ₯Ό 컀μ€ν
λ‘κ±°λ‘ λΌμ°ν
νμ¬
|
|
23
|
+
* νμμ€ν¬ν + stderr μΆλ ₯μ μΌκ΄λκ² μ μ§νλ€.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createBoltLogger(): {
|
|
26
|
+
debug(...msg: unknown[]): void;
|
|
27
|
+
info(...msg: unknown[]): void;
|
|
28
|
+
warn(...msg: unknown[]): void;
|
|
29
|
+
error(...msg: unknown[]): void;
|
|
30
|
+
setLevel(level: string): void;
|
|
31
|
+
getLevel(): string;
|
|
32
|
+
setName(name: string): void;
|
|
33
|
+
};
|
|
34
|
+
export {};
|