@arnavpisces/sutra 1.0.0
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 +203 -0
- package/NOTICE +6 -0
- package/README.md +181 -0
- package/dist/api/client.d.ts +24 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +168 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/confluence-client.d.ts +133 -0
- package/dist/api/confluence-client.d.ts.map +1 -0
- package/dist/api/confluence-client.js +224 -0
- package/dist/api/confluence-client.js.map +1 -0
- package/dist/api/jira-client.d.ts +94 -0
- package/dist/api/jira-client.d.ts.map +1 -0
- package/dist/api/jira-client.js +151 -0
- package/dist/api/jira-client.js.map +1 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +135 -0
- package/dist/app.js.map +1 -0
- package/dist/components/common/Badge.d.ts +7 -0
- package/dist/components/common/Badge.d.ts.map +1 -0
- package/dist/components/common/Badge.js +15 -0
- package/dist/components/common/Badge.js.map +1 -0
- package/dist/components/common/Breadcrumbs.d.ts +5 -0
- package/dist/components/common/Breadcrumbs.d.ts.map +1 -0
- package/dist/components/common/Breadcrumbs.js +9 -0
- package/dist/components/common/Breadcrumbs.js.map +1 -0
- package/dist/components/common/Divider.d.ts +7 -0
- package/dist/components/common/Divider.d.ts.map +1 -0
- package/dist/components/common/Divider.js +13 -0
- package/dist/components/common/Divider.js.map +1 -0
- package/dist/components/common/EditableTextBox.d.ts +30 -0
- package/dist/components/common/EditableTextBox.d.ts.map +1 -0
- package/dist/components/common/EditableTextBox.js +512 -0
- package/dist/components/common/EditableTextBox.js.map +1 -0
- package/dist/components/common/Footer.d.ts +9 -0
- package/dist/components/common/Footer.d.ts.map +1 -0
- package/dist/components/common/Footer.js +7 -0
- package/dist/components/common/Footer.js.map +1 -0
- package/dist/components/common/FuzzySelect.d.ts +17 -0
- package/dist/components/common/FuzzySelect.d.ts.map +1 -0
- package/dist/components/common/FuzzySelect.js +72 -0
- package/dist/components/common/FuzzySelect.js.map +1 -0
- package/dist/components/common/Header.d.ts +7 -0
- package/dist/components/common/Header.d.ts.map +1 -0
- package/dist/components/common/Header.js +18 -0
- package/dist/components/common/Header.js.map +1 -0
- package/dist/components/common/HelpModal.d.ts +13 -0
- package/dist/components/common/HelpModal.d.ts.map +1 -0
- package/dist/components/common/HelpModal.js +9 -0
- package/dist/components/common/HelpModal.js.map +1 -0
- package/dist/components/common/KeyHint.d.ts +15 -0
- package/dist/components/common/KeyHint.d.ts.map +1 -0
- package/dist/components/common/KeyHint.js +10 -0
- package/dist/components/common/KeyHint.js.map +1 -0
- package/dist/components/common/MenuList.d.ts +15 -0
- package/dist/components/common/MenuList.d.ts.map +1 -0
- package/dist/components/common/MenuList.js +31 -0
- package/dist/components/common/MenuList.js.map +1 -0
- package/dist/components/common/Panel.d.ts +12 -0
- package/dist/components/common/Panel.d.ts.map +1 -0
- package/dist/components/common/Panel.js +6 -0
- package/dist/components/common/Panel.js.map +1 -0
- package/dist/components/common/ProgressBar.d.ts +11 -0
- package/dist/components/common/ProgressBar.d.ts.map +1 -0
- package/dist/components/common/ProgressBar.js +11 -0
- package/dist/components/common/ProgressBar.js.map +1 -0
- package/dist/components/common/SavedList.d.ts +16 -0
- package/dist/components/common/SavedList.d.ts.map +1 -0
- package/dist/components/common/SavedList.js +37 -0
- package/dist/components/common/SavedList.js.map +1 -0
- package/dist/components/common/ScrollBox.d.ts +9 -0
- package/dist/components/common/ScrollBox.d.ts.map +1 -0
- package/dist/components/common/ScrollBox.js +105 -0
- package/dist/components/common/ScrollBox.js.map +1 -0
- package/dist/components/common/SearchBar.d.ts +10 -0
- package/dist/components/common/SearchBar.d.ts.map +1 -0
- package/dist/components/common/SearchBar.js +7 -0
- package/dist/components/common/SearchBar.js.map +1 -0
- package/dist/components/common/SelectableItem.d.ts +14 -0
- package/dist/components/common/SelectableItem.d.ts.map +1 -0
- package/dist/components/common/SelectableItem.js +14 -0
- package/dist/components/common/SelectableItem.js.map +1 -0
- package/dist/components/common/Spinner.d.ts +7 -0
- package/dist/components/common/Spinner.d.ts.map +1 -0
- package/dist/components/common/Spinner.js +23 -0
- package/dist/components/common/Spinner.js.map +1 -0
- package/dist/components/common/SplitPane.d.ts +8 -0
- package/dist/components/common/SplitPane.d.ts.map +1 -0
- package/dist/components/common/SplitPane.js +10 -0
- package/dist/components/common/SplitPane.js.map +1 -0
- package/dist/components/common/StatusBar.d.ts +9 -0
- package/dist/components/common/StatusBar.d.ts.map +1 -0
- package/dist/components/common/StatusBar.js +6 -0
- package/dist/components/common/StatusBar.js.map +1 -0
- package/dist/components/common/TabBar.d.ts +9 -0
- package/dist/components/common/TabBar.d.ts.map +1 -0
- package/dist/components/common/TabBar.js +12 -0
- package/dist/components/common/TabBar.js.map +1 -0
- package/dist/components/common/Table.d.ts +19 -0
- package/dist/components/common/Table.d.ts.map +1 -0
- package/dist/components/common/Table.js +24 -0
- package/dist/components/common/Table.js.map +1 -0
- package/dist/components/common/TextEditor.d.ts +10 -0
- package/dist/components/common/TextEditor.d.ts.map +1 -0
- package/dist/components/common/TextEditor.js +17 -0
- package/dist/components/common/TextEditor.js.map +1 -0
- package/dist/components/common/Toast.d.ts +8 -0
- package/dist/components/common/Toast.d.ts.map +1 -0
- package/dist/components/common/Toast.js +32 -0
- package/dist/components/common/Toast.js.map +1 -0
- package/dist/components/common/index.d.ts +38 -0
- package/dist/components/common/index.d.ts.map +1 -0
- package/dist/components/common/index.js +22 -0
- package/dist/components/common/index.js.map +1 -0
- package/dist/components/confluence/ConfluenceView.d.ts +6 -0
- package/dist/components/confluence/ConfluenceView.d.ts.map +1 -0
- package/dist/components/confluence/ConfluenceView.js +184 -0
- package/dist/components/confluence/ConfluenceView.js.map +1 -0
- package/dist/components/confluence/DocTree.d.ts +10 -0
- package/dist/components/confluence/DocTree.d.ts.map +1 -0
- package/dist/components/confluence/DocTree.js +125 -0
- package/dist/components/confluence/DocTree.js.map +1 -0
- package/dist/components/confluence/PageAttachments.d.ts +8 -0
- package/dist/components/confluence/PageAttachments.d.ts.map +1 -0
- package/dist/components/confluence/PageAttachments.js +108 -0
- package/dist/components/confluence/PageAttachments.js.map +1 -0
- package/dist/components/confluence/PageBrowser.d.ts +8 -0
- package/dist/components/confluence/PageBrowser.d.ts.map +1 -0
- package/dist/components/confluence/PageBrowser.js +93 -0
- package/dist/components/confluence/PageBrowser.js.map +1 -0
- package/dist/components/confluence/PageComments.d.ts +8 -0
- package/dist/components/confluence/PageComments.d.ts.map +1 -0
- package/dist/components/confluence/PageComments.js +75 -0
- package/dist/components/confluence/PageComments.js.map +1 -0
- package/dist/components/confluence/PageEditor.d.ts +13 -0
- package/dist/components/confluence/PageEditor.d.ts.map +1 -0
- package/dist/components/confluence/PageEditor.js +37 -0
- package/dist/components/confluence/PageEditor.js.map +1 -0
- package/dist/components/confluence/PageLabels.d.ts +8 -0
- package/dist/components/confluence/PageLabels.d.ts.map +1 -0
- package/dist/components/confluence/PageLabels.js +92 -0
- package/dist/components/confluence/PageLabels.js.map +1 -0
- package/dist/components/confluence/PageList.d.ts +8 -0
- package/dist/components/confluence/PageList.d.ts.map +1 -0
- package/dist/components/confluence/PageList.js +95 -0
- package/dist/components/confluence/PageList.js.map +1 -0
- package/dist/components/confluence/PageViewer.d.ts +14 -0
- package/dist/components/confluence/PageViewer.d.ts.map +1 -0
- package/dist/components/confluence/PageViewer.js +160 -0
- package/dist/components/confluence/PageViewer.js.map +1 -0
- package/dist/components/confluence/SpaceTree.d.ts +10 -0
- package/dist/components/confluence/SpaceTree.d.ts.map +1 -0
- package/dist/components/confluence/SpaceTree.js +220 -0
- package/dist/components/confluence/SpaceTree.js.map +1 -0
- package/dist/components/jira/CommentForm.d.ts +7 -0
- package/dist/components/jira/CommentForm.d.ts.map +1 -0
- package/dist/components/jira/CommentForm.js +24 -0
- package/dist/components/jira/CommentForm.js.map +1 -0
- package/dist/components/jira/CreateTicket.d.ts +9 -0
- package/dist/components/jira/CreateTicket.d.ts.map +1 -0
- package/dist/components/jira/CreateTicket.js +106 -0
- package/dist/components/jira/CreateTicket.js.map +1 -0
- package/dist/components/jira/IssueList.d.ts +9 -0
- package/dist/components/jira/IssueList.d.ts.map +1 -0
- package/dist/components/jira/IssueList.js +43 -0
- package/dist/components/jira/IssueList.js.map +1 -0
- package/dist/components/jira/JiraIssueRow.d.ts +7 -0
- package/dist/components/jira/JiraIssueRow.d.ts.map +1 -0
- package/dist/components/jira/JiraIssueRow.js +49 -0
- package/dist/components/jira/JiraIssueRow.js.map +1 -0
- package/dist/components/jira/JiraView.d.ts +7 -0
- package/dist/components/jira/JiraView.d.ts.map +1 -0
- package/dist/components/jira/JiraView.js +283 -0
- package/dist/components/jira/JiraView.js.map +1 -0
- package/dist/components/jira/JqlSearch.d.ts +8 -0
- package/dist/components/jira/JqlSearch.d.ts.map +1 -0
- package/dist/components/jira/JqlSearch.js +51 -0
- package/dist/components/jira/JqlSearch.js.map +1 -0
- package/dist/components/jira/QuickFilters.d.ts +8 -0
- package/dist/components/jira/QuickFilters.d.ts.map +1 -0
- package/dist/components/jira/QuickFilters.js +61 -0
- package/dist/components/jira/QuickFilters.js.map +1 -0
- package/dist/components/jira/StatusSelector.d.ts +9 -0
- package/dist/components/jira/StatusSelector.d.ts.map +1 -0
- package/dist/components/jira/StatusSelector.js +11 -0
- package/dist/components/jira/StatusSelector.js.map +1 -0
- package/dist/components/jira/TicketDetail.d.ts +23 -0
- package/dist/components/jira/TicketDetail.d.ts.map +1 -0
- package/dist/components/jira/TicketDetail.js +409 -0
- package/dist/components/jira/TicketDetail.js.map +1 -0
- package/dist/components/jira/TicketEditor.d.ts +9 -0
- package/dist/components/jira/TicketEditor.d.ts.map +1 -0
- package/dist/components/jira/TicketEditor.js +21 -0
- package/dist/components/jira/TicketEditor.js.map +1 -0
- package/dist/components/jira/TicketList.d.ts +8 -0
- package/dist/components/jira/TicketList.d.ts.map +1 -0
- package/dist/components/jira/TicketList.js +89 -0
- package/dist/components/jira/TicketList.js.map +1 -0
- package/dist/config/config-manager.d.ts +11 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +65 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/types.d.ts +81 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +16 -0
- package/dist/config/types.js.map +1 -0
- package/dist/formatters/adf-converter.d.ts +21 -0
- package/dist/formatters/adf-converter.d.ts.map +1 -0
- package/dist/formatters/adf-converter.js +73 -0
- package/dist/formatters/adf-converter.js.map +1 -0
- package/dist/formatters/confluence-converter.d.ts +25 -0
- package/dist/formatters/confluence-converter.d.ts.map +1 -0
- package/dist/formatters/confluence-converter.js +77 -0
- package/dist/formatters/confluence-converter.js.map +1 -0
- package/dist/formatters/glow-renderer.d.ts +39 -0
- package/dist/formatters/glow-renderer.d.ts.map +1 -0
- package/dist/formatters/glow-renderer.js +136 -0
- package/dist/formatters/glow-renderer.js.map +1 -0
- package/dist/formatters/markdown-ansi-renderer.d.ts +24 -0
- package/dist/formatters/markdown-ansi-renderer.d.ts.map +1 -0
- package/dist/formatters/markdown-ansi-renderer.js +240 -0
- package/dist/formatters/markdown-ansi-renderer.js.map +1 -0
- package/dist/formatters/mdcat-renderer.d.ts +29 -0
- package/dist/formatters/mdcat-renderer.d.ts.map +1 -0
- package/dist/formatters/mdcat-renderer.js +106 -0
- package/dist/formatters/mdcat-renderer.js.map +1 -0
- package/dist/hooks/useConfluencePage.d.ts +9 -0
- package/dist/hooks/useConfluencePage.d.ts.map +1 -0
- package/dist/hooks/useConfluencePage.js +53 -0
- package/dist/hooks/useConfluencePage.js.map +1 -0
- package/dist/hooks/useJiraIssue.d.ts +9 -0
- package/dist/hooks/useJiraIssue.d.ts.map +1 -0
- package/dist/hooks/useJiraIssue.js +52 -0
- package/dist/hooks/useJiraIssue.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +214 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/bookmarks.d.ts +16 -0
- package/dist/storage/bookmarks.d.ts.map +1 -0
- package/dist/storage/bookmarks.js +49 -0
- package/dist/storage/bookmarks.js.map +1 -0
- package/dist/storage/cache.d.ts +12 -0
- package/dist/storage/cache.d.ts.map +1 -0
- package/dist/storage/cache.js +57 -0
- package/dist/storage/cache.js.map +1 -0
- package/dist/storage/db.d.ts +4 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +63 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/recents.d.ts +13 -0
- package/dist/storage/recents.d.ts.map +1 -0
- package/dist/storage/recents.js +40 -0
- package/dist/storage/recents.js.map +1 -0
- package/dist/theme/te.d.ts +12 -0
- package/dist/theme/te.d.ts.map +1 -0
- package/dist/theme/te.js +13 -0
- package/dist/theme/te.js.map +1 -0
- package/dist/utils/cache.d.ts +15 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +34 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/errors.d.ts +16 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +32 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/external-editor.d.ts +32 -0
- package/dist/utils/external-editor.d.ts.map +1 -0
- package/dist/utils/external-editor.js +173 -0
- package/dist/utils/external-editor.js.map +1 -0
- package/dist/utils/jira-colors.d.ts +4 -0
- package/dist/utils/jira-colors.d.ts.map +1 -0
- package/dist/utils/jira-colors.js +47 -0
- package/dist/utils/jira-colors.js.map +1 -0
- package/dist/utils/links.d.ts +5 -0
- package/dist/utils/links.d.ts.map +1 -0
- package/dist/utils/links.js +43 -0
- package/dist/utils/links.js.map +1 -0
- package/dist/utils/markdown-highlighter.d.ts +49 -0
- package/dist/utils/markdown-highlighter.d.ts.map +1 -0
- package/dist/utils/markdown-highlighter.js +282 -0
- package/dist/utils/markdown-highlighter.js.map +1 -0
- package/dist/utils/paths.d.ts +3 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +15 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +74 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import { program } from 'commander';
|
|
5
|
+
import readline from 'readline';
|
|
6
|
+
import { ConfigManager } from './config/config-manager.js';
|
|
7
|
+
import { App } from './app.js';
|
|
8
|
+
import { JiraClient } from './api/jira-client.js';
|
|
9
|
+
import { ConfluenceClient } from './api/confluence-client.js';
|
|
10
|
+
const GREEN = '\x1b[32m';
|
|
11
|
+
const BOLD_GREEN = '\x1b[1;32m';
|
|
12
|
+
const RED = '\x1b[31m';
|
|
13
|
+
const RESET = '\x1b[0m';
|
|
14
|
+
function createReadlineInterface() {
|
|
15
|
+
return readline.createInterface({
|
|
16
|
+
input: process.stdin,
|
|
17
|
+
output: process.stdout,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function prompt(rl, question) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
rl.question(question, (answer) => {
|
|
23
|
+
resolve(answer);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function promptHidden(rl, question) {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
const anyRl = rl;
|
|
30
|
+
const originalWrite = anyRl._writeToOutput?.bind(rl);
|
|
31
|
+
// Temporarily mute only token character echo while still rendering the prompt label.
|
|
32
|
+
anyRl._writeToOutput = (stringToWrite) => {
|
|
33
|
+
if (stringToWrite.startsWith(question)) {
|
|
34
|
+
process.stdout.write(stringToWrite);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (stringToWrite.includes('\n')) {
|
|
38
|
+
process.stdout.write('\n');
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
rl.question(question, (answer) => {
|
|
42
|
+
anyRl._writeToOutput = originalWrite;
|
|
43
|
+
resolve(answer);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function startApp() {
|
|
48
|
+
// Set stdin to raw mode to handle key presses properly
|
|
49
|
+
if (process.stdin.setRawMode) {
|
|
50
|
+
process.stdin.setRawMode(true);
|
|
51
|
+
}
|
|
52
|
+
process.stdin.resume();
|
|
53
|
+
// Suppress console output during TUI - it interferes with rendering
|
|
54
|
+
console.error = () => { };
|
|
55
|
+
console.log = () => { };
|
|
56
|
+
// Global error handlers to prevent crashes
|
|
57
|
+
process.on('uncaughtException', () => {
|
|
58
|
+
// Silently handle - logging would corrupt TUI
|
|
59
|
+
});
|
|
60
|
+
process.on('unhandledRejection', () => {
|
|
61
|
+
// Silently handle - logging would corrupt TUI
|
|
62
|
+
});
|
|
63
|
+
// Clear screen and move cursor to home position
|
|
64
|
+
process.stdout.write('\x1B[2J\x1B[H');
|
|
65
|
+
const { unmount, waitUntilExit, clear } = render(_jsx(App, {}), {
|
|
66
|
+
exitOnCtrlC: false,
|
|
67
|
+
debug: false, // Ensure updates replace previous output (not append)
|
|
68
|
+
patchConsole: true, // Intercept console.log to not interfere with Ink output
|
|
69
|
+
});
|
|
70
|
+
process.on('SIGINT', () => {
|
|
71
|
+
clear();
|
|
72
|
+
unmount();
|
|
73
|
+
process.exit(0);
|
|
74
|
+
});
|
|
75
|
+
waitUntilExit().catch(() => {
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async function setupWizard(force = false) {
|
|
80
|
+
console.log('Sutra - Setup Wizard\n');
|
|
81
|
+
const config = ConfigManager.getConfig();
|
|
82
|
+
if (config.jira && config.confluence && !force) {
|
|
83
|
+
console.log('Configuration already set up.');
|
|
84
|
+
console.log('Run with --force or -f to reconfigure.\n');
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
const validateApiToken = (token) => {
|
|
88
|
+
// Connect App tokens start with ATCTT3x - these won't work with basic auth
|
|
89
|
+
if (token.startsWith('ATCTT')) {
|
|
90
|
+
console.log('\n⚠️ Warning: This looks like a Connect App token (starts with ATCTT).');
|
|
91
|
+
console.log(' You need a regular API token from:');
|
|
92
|
+
console.log(' https://id.atlassian.com/manage-profile/security/api-tokens\n');
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
};
|
|
97
|
+
const normalizeSite = (input) => {
|
|
98
|
+
const trimmed = input.trim().toLowerCase();
|
|
99
|
+
if (!trimmed)
|
|
100
|
+
return '';
|
|
101
|
+
const withoutProtocol = trimmed.replace(/^https?:\/\//, '');
|
|
102
|
+
const host = withoutProtocol.split('/')[0];
|
|
103
|
+
return host.replace(/\.atlassian\.net$/, '');
|
|
104
|
+
};
|
|
105
|
+
const isValidSite = (site) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(site);
|
|
106
|
+
try {
|
|
107
|
+
console.log('--- Atlassian Cloud Configuration ---');
|
|
108
|
+
console.log('Sutra will derive Jira and Confluence base URLs from your site username.');
|
|
109
|
+
console.log('Go to: https://id.atlassian.com/manage-profile/security/api-tokens');
|
|
110
|
+
console.log('Click "Create API token" and copy the generated token.\n');
|
|
111
|
+
const rl = createReadlineInterface();
|
|
112
|
+
let site = '';
|
|
113
|
+
let email = '';
|
|
114
|
+
let apiToken = '';
|
|
115
|
+
try {
|
|
116
|
+
while (!isValidSite(site)) {
|
|
117
|
+
const value = await prompt(rl, 'Site username (e.g., your-team): ');
|
|
118
|
+
site = normalizeSite(value);
|
|
119
|
+
if (!isValidSite(site)) {
|
|
120
|
+
console.log('Invalid site username. Use only letters, numbers, and hyphens.');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
email = (await prompt(rl, 'Email: ')).trim();
|
|
124
|
+
apiToken = (await promptHidden(rl, 'API Token (input hidden): ')).trim();
|
|
125
|
+
while (!validateApiToken(apiToken)) {
|
|
126
|
+
apiToken = (await promptHidden(rl, 'API Token (input hidden): ')).trim();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
rl.close();
|
|
131
|
+
}
|
|
132
|
+
const jiraBaseUrl = `https://${site}.atlassian.net`;
|
|
133
|
+
const confluenceBaseUrl = `${jiraBaseUrl}/wiki`;
|
|
134
|
+
const jiraClient = new JiraClient({
|
|
135
|
+
baseUrl: jiraBaseUrl,
|
|
136
|
+
email,
|
|
137
|
+
apiToken,
|
|
138
|
+
});
|
|
139
|
+
const confluenceClient = new ConfluenceClient({
|
|
140
|
+
baseUrl: confluenceBaseUrl,
|
|
141
|
+
email,
|
|
142
|
+
apiToken,
|
|
143
|
+
});
|
|
144
|
+
const validationErrors = [];
|
|
145
|
+
try {
|
|
146
|
+
await jiraClient.getMyself();
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
validationErrors.push(`Jira: ${err instanceof Error ? err.message : 'Validation failed'}`);
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
await confluenceClient.getSpaces(1);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
validationErrors.push(`Confluence: ${err instanceof Error ? err.message : 'Validation failed'}`);
|
|
156
|
+
}
|
|
157
|
+
if (validationErrors.length > 0) {
|
|
158
|
+
console.log(`\n${RED}✗ Configuration validation failed:${RESET}`);
|
|
159
|
+
for (const issue of validationErrors) {
|
|
160
|
+
console.log(` - ${issue}`);
|
|
161
|
+
}
|
|
162
|
+
console.log('\nFix credentials and run: sutra setup --force\n');
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
ConfigManager.setJiraConfig({
|
|
166
|
+
baseUrl: jiraBaseUrl,
|
|
167
|
+
email,
|
|
168
|
+
apiToken,
|
|
169
|
+
});
|
|
170
|
+
ConfigManager.setConfluenceConfig({
|
|
171
|
+
baseUrl: confluenceBaseUrl,
|
|
172
|
+
email,
|
|
173
|
+
apiToken,
|
|
174
|
+
});
|
|
175
|
+
console.log(`\n${BOLD_GREEN}✓✓✓ Setup successful${RESET}`);
|
|
176
|
+
console.log(`${GREEN}✓ Configuration saved to ~/.sutra/config.json${RESET}`);
|
|
177
|
+
console.log(`${GREEN}✓ Credentials verified with Jira and Confluence${RESET}`);
|
|
178
|
+
console.log(`${GREEN}✓ Jira: ${jiraBaseUrl}${RESET}`);
|
|
179
|
+
console.log(`${GREEN}✓ Confluence: ${confluenceBaseUrl}${RESET}`);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('Setup failed:', error);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
program
|
|
188
|
+
.name('sutra')
|
|
189
|
+
.description('Terminal TUI for Jira tickets and Confluence docs')
|
|
190
|
+
.version('1.0.0');
|
|
191
|
+
program
|
|
192
|
+
.command('setup', { isDefault: false })
|
|
193
|
+
.description('Configure Jira and Confluence credentials')
|
|
194
|
+
.option('-f, --force', 'Force reconfiguration even if already set up')
|
|
195
|
+
.action(async (options) => {
|
|
196
|
+
const success = await setupWizard(options.force);
|
|
197
|
+
if (!success) {
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
console.log(`\n${BOLD_GREEN}✓ Launching Sutra control panels...${RESET}`);
|
|
201
|
+
startApp();
|
|
202
|
+
});
|
|
203
|
+
program
|
|
204
|
+
.command('start', { isDefault: false })
|
|
205
|
+
.description('Start the TUI application')
|
|
206
|
+
.action(() => {
|
|
207
|
+
startApp();
|
|
208
|
+
});
|
|
209
|
+
program.parse(process.argv);
|
|
210
|
+
// Default action: start the app
|
|
211
|
+
if (!process.argv.slice(2).length) {
|
|
212
|
+
startApp();
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type BookmarkKind = 'jira' | 'confluence';
|
|
2
|
+
export interface BookmarkEntry {
|
|
3
|
+
id: number;
|
|
4
|
+
kind: BookmarkKind;
|
|
5
|
+
key: string;
|
|
6
|
+
title: string;
|
|
7
|
+
url: string | null;
|
|
8
|
+
meta: any;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function isBookmarked(kind: BookmarkKind, key: string): boolean;
|
|
12
|
+
export declare function addBookmark(kind: BookmarkKind, key: string, title: string, url?: string, meta?: any): void;
|
|
13
|
+
export declare function removeBookmark(kind: BookmarkKind, key: string): void;
|
|
14
|
+
export declare function toggleBookmark(kind: BookmarkKind, key: string, title: string, url?: string, meta?: any): boolean;
|
|
15
|
+
export declare function listBookmarks(kind?: BookmarkKind, limit?: number): BookmarkEntry[];
|
|
16
|
+
//# sourceMappingURL=bookmarks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bookmarks.d.ts","sourceRoot":"","sources":["../../src/storage/bookmarks.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;CACnB;AA4BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,YAAY,EAClB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,GAAG,GACT,IAAI,CAEN;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpE;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,GAAG,GACT,OAAO,CAOT;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,KAAK,GAAE,MAAW,GAAG,aAAa,EAAE,CAsBtF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { db } from './db.js';
|
|
2
|
+
const insertStmt = db.prepare(`INSERT INTO bookmarks (kind, key, title, url, meta, created_at)
|
|
3
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
4
|
+
ON CONFLICT(kind, key)
|
|
5
|
+
DO UPDATE SET title = excluded.title, url = excluded.url, meta = excluded.meta`);
|
|
6
|
+
const deleteStmt = db.prepare('DELETE FROM bookmarks WHERE kind = ? AND key = ?');
|
|
7
|
+
const existsStmt = db.prepare('SELECT 1 FROM bookmarks WHERE kind = ? AND key = ?');
|
|
8
|
+
const listStmt = db.prepare(`SELECT id, kind, key, title, url, meta, created_at
|
|
9
|
+
FROM bookmarks
|
|
10
|
+
WHERE kind = ?
|
|
11
|
+
ORDER BY created_at DESC
|
|
12
|
+
LIMIT ?`);
|
|
13
|
+
const listAllStmt = db.prepare(`SELECT id, kind, key, title, url, meta, created_at
|
|
14
|
+
FROM bookmarks
|
|
15
|
+
ORDER BY created_at DESC
|
|
16
|
+
LIMIT ?`);
|
|
17
|
+
export function isBookmarked(kind, key) {
|
|
18
|
+
const row = existsStmt.get(kind, key);
|
|
19
|
+
return !!row;
|
|
20
|
+
}
|
|
21
|
+
export function addBookmark(kind, key, title, url, meta) {
|
|
22
|
+
insertStmt.run(kind, key, title, url ?? null, JSON.stringify(meta ?? {}), Date.now());
|
|
23
|
+
}
|
|
24
|
+
export function removeBookmark(kind, key) {
|
|
25
|
+
deleteStmt.run(kind, key);
|
|
26
|
+
}
|
|
27
|
+
export function toggleBookmark(kind, key, title, url, meta) {
|
|
28
|
+
if (isBookmarked(kind, key)) {
|
|
29
|
+
removeBookmark(kind, key);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
addBookmark(kind, key, title, url, meta);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
export function listBookmarks(kind, limit = 50) {
|
|
36
|
+
const rows = (kind
|
|
37
|
+
? listStmt.all(kind, limit)
|
|
38
|
+
: listAllStmt.all(limit));
|
|
39
|
+
return rows.map((row) => ({
|
|
40
|
+
id: row.id,
|
|
41
|
+
kind: row.kind,
|
|
42
|
+
key: row.key,
|
|
43
|
+
title: row.title,
|
|
44
|
+
url: row.url,
|
|
45
|
+
meta: row.meta ? JSON.parse(row.meta) : {},
|
|
46
|
+
createdAt: row.created_at,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=bookmarks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bookmarks.js","sourceRoot":"","sources":["../../src/storage/bookmarks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAc7B,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B;;;kFAGgF,CACjF,CAAC;AACF,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B,kDAAkD,CACnD,CAAC;AACF,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B,oDAAoD,CACrD,CAAC;AACF,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CACzB;;;;WAIS,CACV,CAAC;AACF,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAC5B;;;WAGS,CACV,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,GAAW;IAC1D,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAgC,CAAC;IACrE,OAAO,CAAC,CAAC,GAAG,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,IAAkB,EAClB,GAAW,EACX,KAAa,EACb,GAAY,EACZ,IAAU;IAEV,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAkB,EAAE,GAAW;IAC5D,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,IAAkB,EAClB,GAAW,EACX,KAAa,EACb,GAAY,EACZ,IAAU;IAEV,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5B,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAmB,EAAE,QAAgB,EAAE;IACnE,MAAM,IAAI,GAAG,CAAC,IAAI;QAChB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;QAC3B,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAQxB,CAAC;IAEH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1C,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class PersistentCache<T> {
|
|
2
|
+
private namespace;
|
|
3
|
+
private ttlMs;
|
|
4
|
+
constructor(namespace: string, ttlSeconds?: number);
|
|
5
|
+
get(key: string): T | null;
|
|
6
|
+
set(key: string, value: T, ttlSeconds?: number): void;
|
|
7
|
+
delete(key: string): void;
|
|
8
|
+
clear(): void;
|
|
9
|
+
clearExpired(): void;
|
|
10
|
+
private sweepExpiredIfNeeded;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/storage/cache.ts"],"names":[],"mappings":"AAoBA,qBAAa,eAAe,CAAC,CAAC;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY;IAMvD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAiB1B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAarD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,KAAK,IAAI,IAAI;IAIb,YAAY,IAAI,IAAI;IAIpB,OAAO,CAAC,oBAAoB;CAM7B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { db } from './db.js';
|
|
2
|
+
const getStmt = db.prepare('SELECT value, expires_at FROM cache WHERE namespace = ? AND key = ?');
|
|
3
|
+
const setStmt = db.prepare(`INSERT INTO cache (namespace, key, value, expires_at, updated_at)
|
|
4
|
+
VALUES (?, ?, ?, ?, ?)
|
|
5
|
+
ON CONFLICT(namespace, key)
|
|
6
|
+
DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at, updated_at = excluded.updated_at`);
|
|
7
|
+
const deleteStmt = db.prepare('DELETE FROM cache WHERE namespace = ? AND key = ?');
|
|
8
|
+
const clearStmt = db.prepare('DELETE FROM cache WHERE namespace = ?');
|
|
9
|
+
const clearExpiredStmt = db.prepare('DELETE FROM cache WHERE expires_at < ?');
|
|
10
|
+
const EXPIRED_SWEEP_INTERVAL_MS = 5 * 60 * 1000;
|
|
11
|
+
let lastExpiredSweepAt = 0;
|
|
12
|
+
export class PersistentCache {
|
|
13
|
+
constructor(namespace, ttlSeconds = 300) {
|
|
14
|
+
this.namespace = namespace;
|
|
15
|
+
this.ttlMs = ttlSeconds * 1000;
|
|
16
|
+
this.sweepExpiredIfNeeded();
|
|
17
|
+
}
|
|
18
|
+
get(key) {
|
|
19
|
+
const row = getStmt.get(this.namespace, key);
|
|
20
|
+
if (!row)
|
|
21
|
+
return null;
|
|
22
|
+
if (Date.now() > row.expires_at) {
|
|
23
|
+
this.delete(key);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(row.value);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
this.delete(key);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
set(key, value, ttlSeconds) {
|
|
35
|
+
this.sweepExpiredIfNeeded();
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
const expiresAt = now + (ttlSeconds ? ttlSeconds * 1000 : this.ttlMs);
|
|
38
|
+
setStmt.run(this.namespace, key, JSON.stringify(value), expiresAt, now);
|
|
39
|
+
}
|
|
40
|
+
delete(key) {
|
|
41
|
+
deleteStmt.run(this.namespace, key);
|
|
42
|
+
}
|
|
43
|
+
clear() {
|
|
44
|
+
clearStmt.run(this.namespace);
|
|
45
|
+
}
|
|
46
|
+
clearExpired() {
|
|
47
|
+
clearExpiredStmt.run(Date.now());
|
|
48
|
+
}
|
|
49
|
+
sweepExpiredIfNeeded() {
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
if (now - lastExpiredSweepAt < EXPIRED_SWEEP_INTERVAL_MS)
|
|
52
|
+
return;
|
|
53
|
+
lastExpiredSweepAt = now;
|
|
54
|
+
clearExpiredStmt.run(now);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/storage/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CACxB,qEAAqE,CACtE,CAAC;AACF,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CACxB;;;4GAG0G,CAC3G,CAAC;AACF,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B,mDAAmD,CACpD,CAAC;AACF,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;AACtE,MAAM,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;AAE9E,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAChD,IAAI,kBAAkB,GAAG,CAAC,CAAC;AAE3B,MAAM,OAAO,eAAe;IAI1B,YAAY,SAAiB,EAAE,aAAqB,GAAG;QACrD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,UAAU,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAE9B,CAAC;QACd,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAM,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,UAAmB;QAC5C,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,EACd,GAAG,EACH,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EACrB,SAAS,EACT,GAAG,CACJ,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,KAAK;QACH,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,YAAY;QACV,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IAEO,oBAAoB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,kBAAkB,GAAG,yBAAyB;YAAE,OAAO;QACjE,kBAAkB,GAAG,GAAG,CAAC;QACzB,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/storage/db.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,MAAM,QAA4B,CAAC;AAkBzC,QAAA,MAAM,EAAE,EAA2B,GAAG,CAAC;AAyCvC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { copyFileSync, existsSync, mkdirSync } from 'fs';
|
|
5
|
+
const baseDir = join(homedir(), '.sutra');
|
|
6
|
+
const legacyBaseDir = join(homedir(), '.ticket-tui');
|
|
7
|
+
mkdirSync(baseDir, { recursive: true });
|
|
8
|
+
const dbPath = join(baseDir, 'cache.db');
|
|
9
|
+
// Migrate local cache/bookmarks/recents from legacy app directory when needed.
|
|
10
|
+
if (!existsSync(dbPath)) {
|
|
11
|
+
const legacyDbPath = join(legacyBaseDir, 'cache.db');
|
|
12
|
+
if (existsSync(legacyDbPath)) {
|
|
13
|
+
copyFileSync(legacyDbPath, dbPath);
|
|
14
|
+
const sidecars = ['-wal', '-shm'];
|
|
15
|
+
for (const suffix of sidecars) {
|
|
16
|
+
const oldSidecar = `${legacyDbPath}${suffix}`;
|
|
17
|
+
const newSidecar = `${dbPath}${suffix}`;
|
|
18
|
+
if (existsSync(oldSidecar)) {
|
|
19
|
+
copyFileSync(oldSidecar, newSidecar);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const db = new Database(dbPath);
|
|
25
|
+
// Better concurrency for read-heavy usage
|
|
26
|
+
db.pragma('journal_mode = WAL');
|
|
27
|
+
db.exec(`
|
|
28
|
+
CREATE TABLE IF NOT EXISTS cache (
|
|
29
|
+
namespace TEXT NOT NULL,
|
|
30
|
+
key TEXT NOT NULL,
|
|
31
|
+
value TEXT NOT NULL,
|
|
32
|
+
expires_at INTEGER NOT NULL,
|
|
33
|
+
updated_at INTEGER NOT NULL,
|
|
34
|
+
PRIMARY KEY (namespace, key)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_cache_expires ON cache (expires_at);
|
|
38
|
+
|
|
39
|
+
CREATE TABLE IF NOT EXISTS bookmarks (
|
|
40
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
|
+
kind TEXT NOT NULL,
|
|
42
|
+
key TEXT NOT NULL,
|
|
43
|
+
title TEXT NOT NULL,
|
|
44
|
+
url TEXT,
|
|
45
|
+
meta TEXT,
|
|
46
|
+
created_at INTEGER NOT NULL,
|
|
47
|
+
UNIQUE(kind, key)
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE IF NOT EXISTS recents (
|
|
51
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
52
|
+
kind TEXT NOT NULL,
|
|
53
|
+
key TEXT NOT NULL,
|
|
54
|
+
title TEXT NOT NULL,
|
|
55
|
+
url TEXT,
|
|
56
|
+
meta TEXT,
|
|
57
|
+
accessed_at INTEGER NOT NULL
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_recents_kind ON recents (kind, accessed_at);
|
|
61
|
+
`);
|
|
62
|
+
export { db, dbPath };
|
|
63
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/storage/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC1C,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AACrD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAExC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAEzC,+EAA+E;AAC/E,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IACxB,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,GAAG,YAAY,GAAG,MAAM,EAAE,CAAC;YAC9C,MAAM,UAAU,GAAG,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;YACxC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3B,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAQ,CAAC;AAEvC,0CAA0C;AAC1C,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAEhC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCP,CAAC,CAAC;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type RecentKind = 'jira' | 'confluence';
|
|
2
|
+
export interface RecentEntry {
|
|
3
|
+
id: number;
|
|
4
|
+
kind: RecentKind;
|
|
5
|
+
key: string;
|
|
6
|
+
title: string;
|
|
7
|
+
url: string | null;
|
|
8
|
+
meta: any;
|
|
9
|
+
accessedAt: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function addRecent(kind: RecentKind, key: string, title: string, url?: string, meta?: any, limit?: number): void;
|
|
12
|
+
export declare function listRecents(kind?: RecentKind, limit?: number): RecentEntry[];
|
|
13
|
+
//# sourceMappingURL=recents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recents.d.ts","sourceRoot":"","sources":["../../src/storage/recents.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,YAAY,CAAC;AAE/C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;CACpB;AAgCD,wBAAgB,SAAS,CACvB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,GAAG,EACV,KAAK,GAAE,MAAW,GACjB,IAAI,CAIN;AAED,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,GAAE,MAAW,GAAG,WAAW,EAAE,CAsBhF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { db } from './db.js';
|
|
2
|
+
const insertStmt = db.prepare(`INSERT INTO recents (kind, key, title, url, meta, accessed_at)
|
|
3
|
+
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
4
|
+
const deleteStmt = db.prepare('DELETE FROM recents WHERE kind = ? AND key = ?');
|
|
5
|
+
const listStmt = db.prepare(`SELECT id, kind, key, title, url, meta, accessed_at
|
|
6
|
+
FROM recents
|
|
7
|
+
WHERE kind = ?
|
|
8
|
+
ORDER BY accessed_at DESC
|
|
9
|
+
LIMIT ?`);
|
|
10
|
+
const listAllStmt = db.prepare(`SELECT id, kind, key, title, url, meta, accessed_at
|
|
11
|
+
FROM recents
|
|
12
|
+
ORDER BY accessed_at DESC
|
|
13
|
+
LIMIT ?`);
|
|
14
|
+
const trimStmt = db.prepare(`DELETE FROM recents
|
|
15
|
+
WHERE id NOT IN (
|
|
16
|
+
SELECT id FROM recents
|
|
17
|
+
WHERE kind = ?
|
|
18
|
+
ORDER BY accessed_at DESC
|
|
19
|
+
LIMIT ?
|
|
20
|
+
) AND kind = ?`);
|
|
21
|
+
export function addRecent(kind, key, title, url, meta, limit = 50) {
|
|
22
|
+
deleteStmt.run(kind, key);
|
|
23
|
+
insertStmt.run(kind, key, title, url ?? null, JSON.stringify(meta ?? {}), Date.now());
|
|
24
|
+
trimStmt.run(kind, limit, kind);
|
|
25
|
+
}
|
|
26
|
+
export function listRecents(kind, limit = 50) {
|
|
27
|
+
const rows = (kind
|
|
28
|
+
? listStmt.all(kind, limit)
|
|
29
|
+
: listAllStmt.all(limit));
|
|
30
|
+
return rows.map((row) => ({
|
|
31
|
+
id: row.id,
|
|
32
|
+
kind: row.kind,
|
|
33
|
+
key: row.key,
|
|
34
|
+
title: row.title,
|
|
35
|
+
url: row.url,
|
|
36
|
+
meta: row.meta ? JSON.parse(row.meta) : {},
|
|
37
|
+
accessedAt: row.accessed_at,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=recents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recents.js","sourceRoot":"","sources":["../../src/storage/recents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAc7B,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B;6BAC2B,CAC5B,CAAC;AACF,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B,gDAAgD,CACjD,CAAC;AACF,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CACzB;;;;WAIS,CACV,CAAC;AACF,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAC5B;;;WAGS,CACV,CAAC;AACF,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CACzB;;;;;;kBAMgB,CACjB,CAAC;AAEF,MAAM,UAAU,SAAS,CACvB,IAAgB,EAChB,GAAW,EACX,KAAa,EACb,GAAY,EACZ,IAAU,EACV,QAAgB,EAAE;IAElB,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC1B,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACtF,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAiB,EAAE,QAAgB,EAAE;IAC/D,MAAM,IAAI,GAAG,CAAC,IAAI;QAChB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;QAC3B,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAQxB,CAAC;IAEH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1C,UAAU,EAAE,GAAG,CAAC,WAAW;KAC5B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"te.d.ts","sourceRoot":"","sources":["../../src/theme/te.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;CAWd,CAAC"}
|
package/dist/theme/te.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const te = {
|
|
2
|
+
bg: 'black',
|
|
3
|
+
fg: 'white',
|
|
4
|
+
muted: 'gray',
|
|
5
|
+
// Website-inspired blue palette mapped to terminal-safe colors.
|
|
6
|
+
accent: 'blue',
|
|
7
|
+
accentAlt: 'blueBright',
|
|
8
|
+
info: 'blue',
|
|
9
|
+
success: 'green',
|
|
10
|
+
warning: 'yellow',
|
|
11
|
+
danger: 'red',
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=te.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"te.js","sourceRoot":"","sources":["../../src/theme/te.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,MAAM;IACb,gEAAgE;IAChE,MAAM,EAAE,MAAM;IACd,SAAS,EAAE,YAAY;IACvB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,KAAK;CACd,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface CacheEntry<T> {
|
|
2
|
+
value: T;
|
|
3
|
+
timestamp: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class Cache<T> {
|
|
6
|
+
private store;
|
|
7
|
+
private ttl;
|
|
8
|
+
constructor(ttlSeconds?: number);
|
|
9
|
+
set(key: string, value: T): void;
|
|
10
|
+
get(key: string): T | null;
|
|
11
|
+
has(key: string): boolean;
|
|
12
|
+
clear(): void;
|
|
13
|
+
delete(key: string): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,KAAK,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,GAAG,CAAS;gBAER,UAAU,GAAE,MAAY;IAIpC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAOhC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAiB1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class Cache {
|
|
2
|
+
constructor(ttlSeconds = 300) {
|
|
3
|
+
this.store = new Map();
|
|
4
|
+
this.ttl = ttlSeconds * 1000;
|
|
5
|
+
}
|
|
6
|
+
set(key, value) {
|
|
7
|
+
this.store.set(key, {
|
|
8
|
+
value,
|
|
9
|
+
timestamp: Date.now(),
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
get(key) {
|
|
13
|
+
const entry = this.store.get(key);
|
|
14
|
+
if (!entry) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const isExpired = Date.now() - entry.timestamp > this.ttl;
|
|
18
|
+
if (isExpired) {
|
|
19
|
+
this.store.delete(key);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return entry.value;
|
|
23
|
+
}
|
|
24
|
+
has(key) {
|
|
25
|
+
return this.get(key) !== null;
|
|
26
|
+
}
|
|
27
|
+
clear() {
|
|
28
|
+
this.store.clear();
|
|
29
|
+
}
|
|
30
|
+
delete(key) {
|
|
31
|
+
this.store.delete(key);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,KAAK;IAIhB,YAAY,aAAqB,GAAG;QAH5B,UAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;QAI/C,IAAI,CAAC,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC;QAE1D,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class AtlassianError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class JiraError extends AtlassianError {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class ConfluenceError extends AtlassianError {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class AuthenticationError extends AtlassianError {
|
|
11
|
+
constructor(service?: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class ConfigurationError extends AtlassianError {
|
|
14
|
+
constructor(message: string);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,SAAU,SAAQ,cAAc;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,eAAgB,SAAQ,cAAc;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,cAAc;gBACzC,OAAO,GAAE,MAAoB;CAO1C;AAED,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM;CAI5B"}
|