kanbaii 0.1.2 → 0.2.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/dashboard/404.html +1 -1
- package/dashboard/_next/static/chunks/23-74779bf2fc2560e3.js +1 -0
- package/dashboard/_next/static/chunks/app/layout-c4919caf1b2a656c.js +1 -0
- package/dashboard/_next/static/chunks/app/page-0cbaeeff2545315a.js +1 -0
- package/dashboard/_next/static/css/7669ae094c660f9a.css +1 -0
- package/dashboard/index.html +1 -1
- package/dashboard/index.txt +3 -3
- package/dist/cli/banner.d.ts +0 -1
- package/dist/cli/banner.js +0 -1
- package/dist/cli/doctor.d.ts +0 -1
- package/dist/cli/doctor.js +0 -1
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +0 -1
- package/dist/server/engines/claudeRunner.d.ts +0 -1
- package/dist/server/engines/claudeRunner.js +9 -3
- package/dist/server/engines/coordinator.d.ts +0 -1
- package/dist/server/engines/coordinator.js +0 -1
- package/dist/server/engines/coordinatorPrompt.d.ts +0 -1
- package/dist/server/engines/coordinatorPrompt.js +2 -2
- package/dist/server/engines/dependencyResolver.d.ts +0 -1
- package/dist/server/engines/dependencyResolver.js +0 -1
- package/dist/server/engines/planner.d.ts +0 -1
- package/dist/server/engines/planner.js +0 -1
- package/dist/server/engines/plannerStore.d.ts +0 -1
- package/dist/server/engines/plannerStore.js +0 -1
- package/dist/server/engines/ralph.d.ts +0 -1
- package/dist/server/engines/ralph.js +0 -1
- package/dist/server/engines/runStore.d.ts +0 -1
- package/dist/server/engines/runStore.js +0 -1
- package/dist/server/engines/taskRouter.d.ts +0 -1
- package/dist/server/engines/taskRouter.js +3 -3
- package/dist/server/engines/teams.d.ts +0 -1
- package/dist/server/engines/teams.js +0 -1
- package/dist/server/engines/workerPool.d.ts +0 -1
- package/dist/server/engines/workerPool.js +16 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.js +72 -8
- package/dist/server/lib/authMiddleware.d.ts +0 -1
- package/dist/server/lib/authMiddleware.js +0 -1
- package/dist/server/lib/fileWatcher.d.ts +0 -1
- package/dist/server/lib/fileWatcher.js +0 -1
- package/dist/server/lib/generateId.d.ts +0 -1
- package/dist/server/lib/generateId.js +0 -1
- package/dist/server/lib/promptSanitizer.d.ts +5 -0
- package/dist/server/lib/promptSanitizer.js +23 -0
- package/dist/server/lib/rateLimiter.d.ts +4 -0
- package/dist/server/lib/rateLimiter.js +33 -0
- package/dist/server/lib/requestLogger.d.ts +2 -0
- package/dist/server/lib/requestLogger.js +23 -0
- package/dist/server/lib/safePath.d.ts +5 -0
- package/dist/server/lib/safePath.js +24 -0
- package/dist/server/lib/schemas.d.ts +0 -1
- package/dist/server/lib/schemas.js +0 -1
- package/dist/server/lib/secretsEncryption.d.ts +3 -0
- package/dist/server/lib/secretsEncryption.js +38 -0
- package/dist/server/lib/typedEmit.d.ts +0 -1
- package/dist/server/lib/typedEmit.js +0 -1
- package/dist/server/routes/agents.d.ts +0 -1
- package/dist/server/routes/agents.js +0 -1
- package/dist/server/routes/auth.d.ts +0 -1
- package/dist/server/routes/auth.js +0 -1
- package/dist/server/routes/costs.d.ts +0 -1
- package/dist/server/routes/costs.js +0 -1
- package/dist/server/routes/escalation.d.ts +0 -1
- package/dist/server/routes/escalation.js +0 -1
- package/dist/server/routes/generate.d.ts +0 -1
- package/dist/server/routes/generate.js +1 -3
- package/dist/server/routes/mcp.d.ts +0 -1
- package/dist/server/routes/mcp.js +0 -1
- package/dist/server/routes/planner.d.ts +0 -1
- package/dist/server/routes/planner.js +0 -1
- package/dist/server/routes/plugins.d.ts +0 -1
- package/dist/server/routes/plugins.js +0 -1
- package/dist/server/routes/projects.d.ts +0 -1
- package/dist/server/routes/projects.js +0 -1
- package/dist/server/routes/ralph.d.ts +0 -1
- package/dist/server/routes/ralph.js +0 -1
- package/dist/server/routes/scheduler.d.ts +0 -1
- package/dist/server/routes/scheduler.js +0 -1
- package/dist/server/routes/settings.d.ts +0 -1
- package/dist/server/routes/settings.js +0 -1
- package/dist/server/routes/skills.d.ts +0 -1
- package/dist/server/routes/skills.js +0 -1
- package/dist/server/routes/soul.d.ts +0 -1
- package/dist/server/routes/soul.js +0 -1
- package/dist/server/routes/system.d.ts +0 -1
- package/dist/server/routes/system.js +15 -12
- package/dist/server/routes/tasks.d.ts +0 -1
- package/dist/server/routes/tasks.js +0 -1
- package/dist/server/routes/teams.d.ts +0 -1
- package/dist/server/routes/teams.js +0 -1
- package/dist/server/routes/terminal.d.ts +0 -1
- package/dist/server/routes/terminal.js +0 -1
- package/dist/server/routes/voice.d.ts +0 -1
- package/dist/server/routes/voice.js +0 -1
- package/dist/server/routes/workItems.d.ts +0 -1
- package/dist/server/routes/workItems.js +11 -1
- package/dist/server/services/agentRegistry.d.ts +0 -1
- package/dist/server/services/agentRegistry.js +0 -1
- package/dist/server/services/authService.d.ts +0 -1
- package/dist/server/services/authService.js +9 -2
- package/dist/server/services/claudeUsage.d.ts +0 -1
- package/dist/server/services/claudeUsage.js +32 -7
- package/dist/server/services/costTracker.d.ts +0 -1
- package/dist/server/services/costTracker.js +0 -1
- package/dist/server/services/escalationService.d.ts +0 -1
- package/dist/server/services/escalationService.js +5 -2
- package/dist/server/services/mcpConfig.d.ts +0 -1
- package/dist/server/services/mcpConfig.js +1 -2
- package/dist/server/services/pluginLoader.d.ts +0 -1
- package/dist/server/services/pluginLoader.js +19 -1
- package/dist/server/services/projectStore.d.ts +0 -1
- package/dist/server/services/projectStore.js +2 -2
- package/dist/server/services/schedulerService.d.ts +0 -1
- package/dist/server/services/schedulerService.js +0 -1
- package/dist/server/services/settingsService.d.ts +0 -1
- package/dist/server/services/settingsService.js +34 -3
- package/dist/server/services/skillsRegistry.d.ts +0 -1
- package/dist/server/services/skillsRegistry.js +0 -1
- package/dist/server/services/soulStore.d.ts +0 -1
- package/dist/server/services/soulStore.js +0 -1
- package/dist/server/services/telegramService.d.ts +0 -1
- package/dist/server/services/telegramService.js +0 -1
- package/dist/server/services/terminalManager.d.ts +0 -1
- package/dist/server/services/terminalManager.js +3 -2
- package/dist/server/services/workItemStore.d.ts +10 -4
- package/dist/server/services/workItemStore.js +57 -20
- package/dist/shared/types.d.ts +1 -1
- package/dist/shared/types.js +0 -1
- package/package.json +15 -4
- package/dashboard/_next/static/chunks/722-5d5f6d00bb07f427.js +0 -1
- package/dashboard/_next/static/chunks/app/layout-f76af5203e5cab0e.js +0 -1
- package/dashboard/_next/static/chunks/app/page-e5035f252913cddb.js +0 -1
- package/dashboard/_next/static/css/1a1fb46093561e14.css +0 -1
- package/dist/cli/banner.d.ts.map +0 -1
- package/dist/cli/banner.js.map +0 -1
- package/dist/cli/doctor.d.ts.map +0 -1
- package/dist/cli/doctor.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/server/__tests__/api.test.d.ts +0 -2
- package/dist/server/__tests__/api.test.d.ts.map +0 -1
- package/dist/server/__tests__/api.test.js +0 -279
- package/dist/server/__tests__/api.test.js.map +0 -1
- package/dist/server/__tests__/projectStore.test.d.ts +0 -2
- package/dist/server/__tests__/projectStore.test.d.ts.map +0 -1
- package/dist/server/__tests__/projectStore.test.js +0 -153
- package/dist/server/__tests__/projectStore.test.js.map +0 -1
- package/dist/server/__tests__/setup.d.ts +0 -2
- package/dist/server/__tests__/setup.d.ts.map +0 -1
- package/dist/server/__tests__/setup.js +0 -14
- package/dist/server/__tests__/setup.js.map +0 -1
- package/dist/server/__tests__/workItemStore.test.d.ts +0 -2
- package/dist/server/__tests__/workItemStore.test.d.ts.map +0 -1
- package/dist/server/__tests__/workItemStore.test.js +0 -323
- package/dist/server/__tests__/workItemStore.test.js.map +0 -1
- package/dist/server/engines/claudeRunner.d.ts.map +0 -1
- package/dist/server/engines/claudeRunner.js.map +0 -1
- package/dist/server/engines/coordinator.d.ts.map +0 -1
- package/dist/server/engines/coordinator.js.map +0 -1
- package/dist/server/engines/coordinatorPrompt.d.ts.map +0 -1
- package/dist/server/engines/coordinatorPrompt.js.map +0 -1
- package/dist/server/engines/dependencyResolver.d.ts.map +0 -1
- package/dist/server/engines/dependencyResolver.js.map +0 -1
- package/dist/server/engines/planner.d.ts.map +0 -1
- package/dist/server/engines/planner.js.map +0 -1
- package/dist/server/engines/plannerStore.d.ts.map +0 -1
- package/dist/server/engines/plannerStore.js.map +0 -1
- package/dist/server/engines/ralph.d.ts.map +0 -1
- package/dist/server/engines/ralph.js.map +0 -1
- package/dist/server/engines/runStore.d.ts.map +0 -1
- package/dist/server/engines/runStore.js.map +0 -1
- package/dist/server/engines/taskRouter.d.ts.map +0 -1
- package/dist/server/engines/taskRouter.js.map +0 -1
- package/dist/server/engines/teams.d.ts.map +0 -1
- package/dist/server/engines/teams.js.map +0 -1
- package/dist/server/engines/workerPool.d.ts.map +0 -1
- package/dist/server/engines/workerPool.js.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server/lib/authMiddleware.d.ts.map +0 -1
- package/dist/server/lib/authMiddleware.js.map +0 -1
- package/dist/server/lib/fileWatcher.d.ts.map +0 -1
- package/dist/server/lib/fileWatcher.js.map +0 -1
- package/dist/server/lib/generateId.d.ts.map +0 -1
- package/dist/server/lib/generateId.js.map +0 -1
- package/dist/server/lib/schemas.d.ts.map +0 -1
- package/dist/server/lib/schemas.js.map +0 -1
- package/dist/server/lib/typedEmit.d.ts.map +0 -1
- package/dist/server/lib/typedEmit.js.map +0 -1
- package/dist/server/routes/agents.d.ts.map +0 -1
- package/dist/server/routes/agents.js.map +0 -1
- package/dist/server/routes/auth.d.ts.map +0 -1
- package/dist/server/routes/auth.js.map +0 -1
- package/dist/server/routes/costs.d.ts.map +0 -1
- package/dist/server/routes/costs.js.map +0 -1
- package/dist/server/routes/escalation.d.ts.map +0 -1
- package/dist/server/routes/escalation.js.map +0 -1
- package/dist/server/routes/generate.d.ts.map +0 -1
- package/dist/server/routes/generate.js.map +0 -1
- package/dist/server/routes/mcp.d.ts.map +0 -1
- package/dist/server/routes/mcp.js.map +0 -1
- package/dist/server/routes/planner.d.ts.map +0 -1
- package/dist/server/routes/planner.js.map +0 -1
- package/dist/server/routes/plugins.d.ts.map +0 -1
- package/dist/server/routes/plugins.js.map +0 -1
- package/dist/server/routes/projects.d.ts.map +0 -1
- package/dist/server/routes/projects.js.map +0 -1
- package/dist/server/routes/ralph.d.ts.map +0 -1
- package/dist/server/routes/ralph.js.map +0 -1
- package/dist/server/routes/scheduler.d.ts.map +0 -1
- package/dist/server/routes/scheduler.js.map +0 -1
- package/dist/server/routes/settings.d.ts.map +0 -1
- package/dist/server/routes/settings.js.map +0 -1
- package/dist/server/routes/skills.d.ts.map +0 -1
- package/dist/server/routes/skills.js.map +0 -1
- package/dist/server/routes/soul.d.ts.map +0 -1
- package/dist/server/routes/soul.js.map +0 -1
- package/dist/server/routes/system.d.ts.map +0 -1
- package/dist/server/routes/system.js.map +0 -1
- package/dist/server/routes/tasks.d.ts.map +0 -1
- package/dist/server/routes/tasks.js.map +0 -1
- package/dist/server/routes/teams.d.ts.map +0 -1
- package/dist/server/routes/teams.js.map +0 -1
- package/dist/server/routes/terminal.d.ts.map +0 -1
- package/dist/server/routes/terminal.js.map +0 -1
- package/dist/server/routes/voice.d.ts.map +0 -1
- package/dist/server/routes/voice.js.map +0 -1
- package/dist/server/routes/workItems.d.ts.map +0 -1
- package/dist/server/routes/workItems.js.map +0 -1
- package/dist/server/services/agentRegistry.d.ts.map +0 -1
- package/dist/server/services/agentRegistry.js.map +0 -1
- package/dist/server/services/authService.d.ts.map +0 -1
- package/dist/server/services/authService.js.map +0 -1
- package/dist/server/services/claudeUsage.d.ts.map +0 -1
- package/dist/server/services/claudeUsage.js.map +0 -1
- package/dist/server/services/costTracker.d.ts.map +0 -1
- package/dist/server/services/costTracker.js.map +0 -1
- package/dist/server/services/escalationService.d.ts.map +0 -1
- package/dist/server/services/escalationService.js.map +0 -1
- package/dist/server/services/mcpConfig.d.ts.map +0 -1
- package/dist/server/services/mcpConfig.js.map +0 -1
- package/dist/server/services/pluginLoader.d.ts.map +0 -1
- package/dist/server/services/pluginLoader.js.map +0 -1
- package/dist/server/services/projectStore.d.ts.map +0 -1
- package/dist/server/services/projectStore.js.map +0 -1
- package/dist/server/services/schedulerService.d.ts.map +0 -1
- package/dist/server/services/schedulerService.js.map +0 -1
- package/dist/server/services/settingsService.d.ts.map +0 -1
- package/dist/server/services/settingsService.js.map +0 -1
- package/dist/server/services/skillsRegistry.d.ts.map +0 -1
- package/dist/server/services/skillsRegistry.js.map +0 -1
- package/dist/server/services/soulStore.d.ts.map +0 -1
- package/dist/server/services/soulStore.js.map +0 -1
- package/dist/server/services/telegramService.d.ts.map +0 -1
- package/dist/server/services/telegramService.js.map +0 -1
- package/dist/server/services/terminalManager.d.ts.map +0 -1
- package/dist/server/services/terminalManager.js.map +0 -1
- package/dist/server/services/workItemStore.d.ts.map +0 -1
- package/dist/server/services/workItemStore.js.map +0 -1
- package/dist/shared/types.d.ts.map +0 -1
- package/dist/shared/types.js.map +0 -1
- /package/dashboard/_next/static/{WZgWWvl5DWIMdBOLDHyIK → U_eLKLn69LJkGH6AtpAhH}/_buildManifest.js +0 -0
- /package/dashboard/_next/static/{WZgWWvl5DWIMdBOLDHyIK → U_eLKLn69LJkGH6AtpAhH}/_ssgManifest.js +0 -0
|
@@ -82,6 +82,17 @@ router.patch('/:wiId', (req, res) => {
|
|
|
82
82
|
throw err;
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
|
+
// POST /api/projects/:slug/work-items/:wiId/reorder
|
|
86
|
+
router.post('/:wiId/reorder', (req, res) => {
|
|
87
|
+
const { order } = req.body;
|
|
88
|
+
if (typeof order !== 'number')
|
|
89
|
+
return res.status(400).json({ ok: false, error: 'order (number) required' });
|
|
90
|
+
const item = workItemStore.reorderWorkItem(req.params.slug, req.params.wiId, order);
|
|
91
|
+
if (!item)
|
|
92
|
+
return res.status(404).json({ ok: false, error: 'Work item not found' });
|
|
93
|
+
(0, typedEmit_1.emit)('workItem:updated', { projectSlug: req.params.slug, workItem: item });
|
|
94
|
+
res.json({ ok: true, data: item });
|
|
95
|
+
});
|
|
85
96
|
// DELETE /api/projects/:slug/work-items/:wiId
|
|
86
97
|
router.delete('/:wiId', (req, res) => {
|
|
87
98
|
try {
|
|
@@ -97,4 +108,3 @@ router.delete('/:wiId', (req, res) => {
|
|
|
97
108
|
}
|
|
98
109
|
});
|
|
99
110
|
exports.default = router;
|
|
100
|
-
//# sourceMappingURL=workItems.js.map
|
|
@@ -24,7 +24,12 @@ function generateSalt() {
|
|
|
24
24
|
// ─── JWT-like tokens (simple HMAC-based, no jsonwebtoken dependency) ───
|
|
25
25
|
function getSecret() {
|
|
26
26
|
const auth = (0, settingsService_1.getSection)('auth');
|
|
27
|
-
|
|
27
|
+
if (!auth.secret || auth.secret === 'kanbaii-default-secret-change-me') {
|
|
28
|
+
const generated = crypto_1.default.randomBytes(32).toString('hex');
|
|
29
|
+
(0, settingsService_1.updateSection)('auth', { secret: generated });
|
|
30
|
+
return generated;
|
|
31
|
+
}
|
|
32
|
+
return auth.secret;
|
|
28
33
|
}
|
|
29
34
|
function base64url(str) {
|
|
30
35
|
return Buffer.from(str).toString('base64url');
|
|
@@ -73,6 +78,9 @@ function isAuthEnabled() {
|
|
|
73
78
|
return (0, settingsService_1.getSection)('auth').enabled;
|
|
74
79
|
}
|
|
75
80
|
function register(username, password) {
|
|
81
|
+
if (password.length < 8) {
|
|
82
|
+
throw new Error('Password must be at least 8 characters');
|
|
83
|
+
}
|
|
76
84
|
const users = readUsers();
|
|
77
85
|
if (users.find(u => u.username === username)) {
|
|
78
86
|
throw new Error('Username already exists');
|
|
@@ -121,4 +129,3 @@ function parseExpiry(str) {
|
|
|
121
129
|
default: return 86400;
|
|
122
130
|
}
|
|
123
131
|
}
|
|
124
|
-
//# sourceMappingURL=authService.js.map
|
|
@@ -12,4 +12,3 @@ export declare function getCachedUsage(): ClaudeUsageData | null;
|
|
|
12
12
|
export declare function fetchClaudeUsage(): Promise<void>;
|
|
13
13
|
export declare function startPolling(intervalMs?: number): void;
|
|
14
14
|
export declare function stopPolling(): void;
|
|
15
|
-
//# sourceMappingURL=claudeUsage.d.ts.map
|
|
@@ -15,6 +15,9 @@ const typedEmit_1 = require("../lib/typedEmit");
|
|
|
15
15
|
// ─── Cache ───
|
|
16
16
|
let usageCache = null;
|
|
17
17
|
let pollInterval = null;
|
|
18
|
+
// ─── Backoff ───
|
|
19
|
+
let _backoffMs = 0;
|
|
20
|
+
const MAX_BACKOFF = 5 * 60 * 1000; // 5 minutes max
|
|
18
21
|
function getCachedUsage() {
|
|
19
22
|
return usageCache;
|
|
20
23
|
}
|
|
@@ -77,7 +80,8 @@ function fetchClaudeUsage() {
|
|
|
77
80
|
res.on('data', (c) => (data += c));
|
|
78
81
|
res.on('end', () => {
|
|
79
82
|
if (res.statusCode === 429) {
|
|
80
|
-
|
|
83
|
+
_backoffMs = Math.min((_backoffMs || 15000) * 2, MAX_BACKOFF);
|
|
84
|
+
console.warn(`[claude-usage] Rate limited, backing off ${Math.round(_backoffMs / 1000)}s`);
|
|
81
85
|
resolve();
|
|
82
86
|
return;
|
|
83
87
|
}
|
|
@@ -122,6 +126,7 @@ function fetchClaudeUsage() {
|
|
|
122
126
|
});
|
|
123
127
|
}
|
|
124
128
|
usageCache = { entries, timestamp: new Date().toISOString() };
|
|
129
|
+
_backoffMs = 0;
|
|
125
130
|
// Broadcast via Socket.IO
|
|
126
131
|
try {
|
|
127
132
|
(0, typedEmit_1.getIO)().emit('claude-usage', usageCache);
|
|
@@ -132,23 +137,43 @@ function fetchClaudeUsage() {
|
|
|
132
137
|
resolve();
|
|
133
138
|
});
|
|
134
139
|
});
|
|
135
|
-
req.on('error', (err) => {
|
|
140
|
+
req.on('error', (err) => {
|
|
141
|
+
_backoffMs = Math.min((_backoffMs || 15000) * 2, MAX_BACKOFF);
|
|
142
|
+
console.warn(`[claude-usage] Request error: ${err.message}, backing off ${Math.round(_backoffMs / 1000)}s`);
|
|
143
|
+
resolve();
|
|
144
|
+
});
|
|
136
145
|
req.setTimeout(15000, () => { console.warn('[claude-usage] Request timeout (15s)'); req.destroy(); resolve(); });
|
|
137
146
|
req.end();
|
|
138
147
|
});
|
|
139
148
|
}
|
|
140
149
|
// ─── Polling ───
|
|
150
|
+
let _pollActive = false;
|
|
151
|
+
let _pollTimer = null;
|
|
141
152
|
function startPolling(intervalMs = 60000) {
|
|
142
|
-
if (
|
|
153
|
+
if (_pollActive)
|
|
143
154
|
return;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
155
|
+
_pollActive = true;
|
|
156
|
+
console.log(`[claude-usage] Polling started (${intervalMs / 1000}s base interval)`);
|
|
157
|
+
const poll = async () => {
|
|
158
|
+
if (!_pollActive)
|
|
159
|
+
return;
|
|
160
|
+
await fetchClaudeUsage();
|
|
161
|
+
if (!_pollActive)
|
|
162
|
+
return;
|
|
163
|
+
const delay = _backoffMs > 0 ? _backoffMs : intervalMs;
|
|
164
|
+
_pollTimer = setTimeout(poll, delay);
|
|
165
|
+
};
|
|
166
|
+
poll(); // Immediate first fetch
|
|
147
167
|
}
|
|
148
168
|
function stopPolling() {
|
|
169
|
+
_pollActive = false;
|
|
170
|
+
if (_pollTimer) {
|
|
171
|
+
clearTimeout(_pollTimer);
|
|
172
|
+
_pollTimer = null;
|
|
173
|
+
}
|
|
174
|
+
// Legacy: clear interval reference if any
|
|
149
175
|
if (pollInterval) {
|
|
150
176
|
clearInterval(pollInterval);
|
|
151
177
|
pollInterval = null;
|
|
152
178
|
}
|
|
153
179
|
}
|
|
154
|
-
//# sourceMappingURL=claudeUsage.js.map
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.setSourceOverride = setSourceOverride;
|
|
4
7
|
exports.createEscalation = createEscalation;
|
|
@@ -6,6 +9,7 @@ exports.respondToEscalation = respondToEscalation;
|
|
|
6
9
|
exports.getPendingEscalation = getPendingEscalation;
|
|
7
10
|
exports.getEscalationStatus = getEscalationStatus;
|
|
8
11
|
exports.clearEscalation = clearEscalation;
|
|
12
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
9
13
|
const typedEmit_1 = require("../lib/typedEmit");
|
|
10
14
|
const telegramService_1 = require("./telegramService");
|
|
11
15
|
const settingsService_1 = require("./settingsService");
|
|
@@ -18,7 +22,7 @@ function setSourceOverride(source) { sourceOverride = source; }
|
|
|
18
22
|
// ─── API ───
|
|
19
23
|
function createEscalation(data) {
|
|
20
24
|
const escalation = {
|
|
21
|
-
id: `esc-${
|
|
25
|
+
id: `esc-${crypto_1.default.randomBytes(12).toString('hex')}`,
|
|
22
26
|
source: sourceOverride || data.source,
|
|
23
27
|
taskId: data.taskId,
|
|
24
28
|
taskTitle: data.taskTitle,
|
|
@@ -118,4 +122,3 @@ function clearEscalation() {
|
|
|
118
122
|
}
|
|
119
123
|
timeoutHandles.clear();
|
|
120
124
|
}
|
|
121
|
-
//# sourceMappingURL=escalationService.js.map
|
|
@@ -28,4 +28,3 @@ export declare function testServer(name: string): Promise<{
|
|
|
28
28
|
* @param onlyKanbaii If true, only include the KANBAII escalation server (fast). Default: true.
|
|
29
29
|
*/
|
|
30
30
|
export declare function generateMcpConfigForClaude(onlyKanbaii?: boolean): string | null;
|
|
31
|
-
//# sourceMappingURL=mcpConfig.d.ts.map
|
|
@@ -122,7 +122,7 @@ async function testServer(name) {
|
|
|
122
122
|
}, 3000);
|
|
123
123
|
const proc = spawn(server.command, server.args || [], {
|
|
124
124
|
env: { ...process.env, ...server.env },
|
|
125
|
-
|
|
125
|
+
windowsHide: true,
|
|
126
126
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
127
127
|
});
|
|
128
128
|
proc.on('error', (err) => {
|
|
@@ -171,4 +171,3 @@ function generateMcpConfigForClaude(onlyKanbaii = true) {
|
|
|
171
171
|
fs_1.default.writeFileSync(tmpFile, JSON.stringify({ mcpServers: mcpConfig }, null, 2), 'utf-8');
|
|
172
172
|
return tmpFile;
|
|
173
173
|
}
|
|
174
|
-
//# sourceMappingURL=mcpConfig.js.map
|
|
@@ -36,4 +36,3 @@ export interface PluginEntry {
|
|
|
36
36
|
export declare function scanPlugins(): PluginEntry[];
|
|
37
37
|
export declare function togglePlugin(name: string, enabled: boolean): void;
|
|
38
38
|
export declare function runHook(hookName: keyof PluginHooks, ctx: any): Promise<void>;
|
|
39
|
-
//# sourceMappingURL=pluginLoader.d.ts.map
|
|
@@ -41,6 +41,25 @@ function scanPlugins() {
|
|
|
41
41
|
for (const file of files) {
|
|
42
42
|
try {
|
|
43
43
|
const fullPath = path_1.default.join(PLUGINS_DIR, file);
|
|
44
|
+
// Validate plugin is within plugins directory
|
|
45
|
+
const resolvedPath = path_1.default.resolve(fullPath);
|
|
46
|
+
if (!resolvedPath.startsWith(path_1.default.resolve(PLUGINS_DIR))) {
|
|
47
|
+
console.warn(`[plugins] Rejected plugin outside plugins dir: ${file}`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Check for dangerous patterns
|
|
51
|
+
const content = fs_1.default.readFileSync(fullPath, 'utf-8');
|
|
52
|
+
const dangerousPatterns = [
|
|
53
|
+
/child_process/,
|
|
54
|
+
/require\s*\(\s*['"]fs['"]\s*\)/,
|
|
55
|
+
/process\.exit/,
|
|
56
|
+
/eval\s*\(/,
|
|
57
|
+
/Function\s*\(/,
|
|
58
|
+
];
|
|
59
|
+
const hasDangerous = dangerousPatterns.some(p => p.test(content));
|
|
60
|
+
if (hasDangerous) {
|
|
61
|
+
console.warn(`[plugins] Plugin ${file} uses restricted APIs — loading with warning`);
|
|
62
|
+
}
|
|
44
63
|
// Clear require cache for hot-reload
|
|
45
64
|
delete require.cache[require.resolve(fullPath)];
|
|
46
65
|
const mod = require(fullPath);
|
|
@@ -90,4 +109,3 @@ async function runHook(hookName, ctx) {
|
|
|
90
109
|
}
|
|
91
110
|
// Initial scan
|
|
92
111
|
scanPlugins();
|
|
93
|
-
//# sourceMappingURL=pluginLoader.js.map
|
|
@@ -4,4 +4,3 @@ export declare function getProject(slug: string): Project | null;
|
|
|
4
4
|
export declare function createProject(input: unknown): Project;
|
|
5
5
|
export declare function updateProject(slug: string, input: unknown): Project;
|
|
6
6
|
export declare function deleteProject(slug: string): void;
|
|
7
|
-
//# sourceMappingURL=projectStore.d.ts.map
|
|
@@ -12,6 +12,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
12
12
|
const path_1 = __importDefault(require("path"));
|
|
13
13
|
const schemas_1 = require("../lib/schemas");
|
|
14
14
|
const generateId_1 = require("../lib/generateId");
|
|
15
|
+
const safePath_1 = require("../lib/safePath");
|
|
15
16
|
const DATA_DIR = path_1.default.resolve(process.env.KANBAII_DATA_DIR || path_1.default.join(process.cwd(), 'data', 'projects'));
|
|
16
17
|
function ensureDir(dir) {
|
|
17
18
|
if (!fs_1.default.existsSync(dir)) {
|
|
@@ -19,7 +20,7 @@ function ensureDir(dir) {
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
function projectDir(slug) {
|
|
22
|
-
return
|
|
23
|
+
return (0, safePath_1.safePath)(DATA_DIR, slug);
|
|
23
24
|
}
|
|
24
25
|
function projectFile(slug) {
|
|
25
26
|
return path_1.default.join(projectDir(slug), 'project.json');
|
|
@@ -120,4 +121,3 @@ function deleteProject(slug) {
|
|
|
120
121
|
};
|
|
121
122
|
writeProject(updated);
|
|
122
123
|
}
|
|
123
|
-
//# sourceMappingURL=projectStore.js.map
|
|
@@ -41,4 +41,3 @@ export declare function getSettings(): AppSettings;
|
|
|
41
41
|
export declare function updateSettings(partial: Partial<AppSettings>): AppSettings;
|
|
42
42
|
export declare function getSection<K extends keyof AppSettings>(key: K): AppSettings[K];
|
|
43
43
|
export declare function updateSection<K extends keyof AppSettings>(key: K, value: Partial<AppSettings[K]>): AppSettings;
|
|
44
|
-
//# sourceMappingURL=settingsService.d.ts.map
|
|
@@ -9,6 +9,7 @@ exports.getSection = getSection;
|
|
|
9
9
|
exports.updateSection = updateSection;
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const secretsEncryption_1 = require("../lib/secretsEncryption");
|
|
12
13
|
const DATA_DIR = path_1.default.resolve(process.env.KANBAII_DATA_DIR || path_1.default.join(process.cwd(), 'data', 'projects'));
|
|
13
14
|
const SETTINGS_FILE = path_1.default.join(DATA_DIR, '..', '.settings.json');
|
|
14
15
|
const DEFAULTS = {
|
|
@@ -59,7 +60,27 @@ function getSettings() {
|
|
|
59
60
|
try {
|
|
60
61
|
if (fs_1.default.existsSync(SETTINGS_FILE)) {
|
|
61
62
|
const saved = JSON.parse(fs_1.default.readFileSync(SETTINGS_FILE, 'utf-8'));
|
|
62
|
-
|
|
63
|
+
const settings = deepMerge(DEFAULTS, saved);
|
|
64
|
+
// Auto-decrypt sensitive fields
|
|
65
|
+
if (settings.integrations.telegram.botToken) {
|
|
66
|
+
try {
|
|
67
|
+
settings.integrations.telegram.botToken = (0, secretsEncryption_1.decrypt)(settings.integrations.telegram.botToken);
|
|
68
|
+
}
|
|
69
|
+
catch { }
|
|
70
|
+
}
|
|
71
|
+
if (settings.integrations.voice.openaiApiKey) {
|
|
72
|
+
try {
|
|
73
|
+
settings.integrations.voice.openaiApiKey = (0, secretsEncryption_1.decrypt)(settings.integrations.voice.openaiApiKey);
|
|
74
|
+
}
|
|
75
|
+
catch { }
|
|
76
|
+
}
|
|
77
|
+
if (settings.auth.secret && (0, secretsEncryption_1.isEncrypted)(settings.auth.secret)) {
|
|
78
|
+
try {
|
|
79
|
+
settings.auth.secret = (0, secretsEncryption_1.decrypt)(settings.auth.secret);
|
|
80
|
+
}
|
|
81
|
+
catch { }
|
|
82
|
+
}
|
|
83
|
+
return settings;
|
|
63
84
|
}
|
|
64
85
|
}
|
|
65
86
|
catch { }
|
|
@@ -71,7 +92,18 @@ function updateSettings(partial) {
|
|
|
71
92
|
const dir = path_1.default.dirname(SETTINGS_FILE);
|
|
72
93
|
if (!fs_1.default.existsSync(dir))
|
|
73
94
|
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
74
|
-
|
|
95
|
+
// Auto-encrypt sensitive fields before saving
|
|
96
|
+
const toSave = JSON.parse(JSON.stringify(merged)); // deep clone
|
|
97
|
+
if (toSave.integrations?.telegram?.botToken && !(0, secretsEncryption_1.isEncrypted)(toSave.integrations.telegram.botToken)) {
|
|
98
|
+
toSave.integrations.telegram.botToken = (0, secretsEncryption_1.encrypt)(toSave.integrations.telegram.botToken);
|
|
99
|
+
}
|
|
100
|
+
if (toSave.integrations?.voice?.openaiApiKey && !(0, secretsEncryption_1.isEncrypted)(toSave.integrations.voice.openaiApiKey)) {
|
|
101
|
+
toSave.integrations.voice.openaiApiKey = (0, secretsEncryption_1.encrypt)(toSave.integrations.voice.openaiApiKey);
|
|
102
|
+
}
|
|
103
|
+
if (toSave.auth?.secret && !(0, secretsEncryption_1.isEncrypted)(toSave.auth.secret)) {
|
|
104
|
+
toSave.auth.secret = (0, secretsEncryption_1.encrypt)(toSave.auth.secret);
|
|
105
|
+
}
|
|
106
|
+
fs_1.default.writeFileSync(SETTINGS_FILE, JSON.stringify(toSave, null, 2), 'utf-8');
|
|
75
107
|
return merged;
|
|
76
108
|
}
|
|
77
109
|
function getSection(key) {
|
|
@@ -82,4 +114,3 @@ function updateSection(key, value) {
|
|
|
82
114
|
current[key] = deepMerge(current[key], value);
|
|
83
115
|
return updateSettings(current);
|
|
84
116
|
}
|
|
85
|
-
//# sourceMappingURL=settingsService.js.map
|
|
@@ -15,4 +15,3 @@ export declare function toggleSkill(name: string, enabled: boolean): void;
|
|
|
15
15
|
* Build a system prompt from all enabled skills for Claude CLI --append-system-prompt
|
|
16
16
|
*/
|
|
17
17
|
export declare function buildSkillsPrompt(): string | null;
|
|
18
|
-
//# sourceMappingURL=skillsRegistry.d.ts.map
|
|
@@ -43,4 +43,3 @@ export declare function getConfig(projectSlug: string): SoulConfig;
|
|
|
43
43
|
export declare function updateConfig(projectSlug: string, config: Partial<SoulConfig>): SoulConfig;
|
|
44
44
|
export declare function getHealth(projectSlug: string): HealthMetrics;
|
|
45
45
|
export declare function updateHealth(projectSlug: string, metrics: Partial<HealthMetrics>): HealthMetrics;
|
|
46
|
-
//# sourceMappingURL=soulStore.d.ts.map
|
|
@@ -13,4 +13,3 @@ export declare function notifyRalphStarted(projectSlug: string, taskCount: numbe
|
|
|
13
13
|
export declare function notifyRalphCompleted(projectSlug: string, completed: number, failed: number): void;
|
|
14
14
|
export declare function notifyTeamsStarted(projectSlug: string, wiCount: number): void;
|
|
15
15
|
export declare function notifyError(projectSlug: string, message: string): void;
|
|
16
|
-
//# sourceMappingURL=telegramService.d.ts.map
|
|
@@ -21,4 +21,3 @@ export declare function sendInput(projectSlug: string, data: string): void;
|
|
|
21
21
|
export declare function resizeTerminal(projectSlug: string, cols: number, rows: number): void;
|
|
22
22
|
export declare function killSession(projectSlug: string): void;
|
|
23
23
|
export declare function resetSession(projectSlug: string): void;
|
|
24
|
-
//# sourceMappingURL=terminalManager.d.ts.map
|
|
@@ -34,7 +34,9 @@ function spawnPty(projectSlug, workingDir, opts) {
|
|
|
34
34
|
throw new Error('node-pty not available. Install: npm install node-pty');
|
|
35
35
|
const isWindows = process.platform === 'win32';
|
|
36
36
|
const shell = isWindows ? 'cmd.exe' : '/bin/bash';
|
|
37
|
-
const
|
|
37
|
+
const validModels = ['opus', 'sonnet', 'haiku'];
|
|
38
|
+
const model = opts?.model && validModels.includes(opts.model) ? opts.model : undefined;
|
|
39
|
+
const claudeCmd = `claude${model ? ` --model ${model}` : ''}`;
|
|
38
40
|
const shellArgs = isWindows ? ['/c', claudeCmd] : ['-c', claudeCmd];
|
|
39
41
|
const cleanEnv = { ...process.env };
|
|
40
42
|
delete cleanEnv.CLAUDECODE;
|
|
@@ -82,4 +84,3 @@ function resetSession(projectSlug) {
|
|
|
82
84
|
killSession(projectSlug);
|
|
83
85
|
sessions.delete(projectSlug);
|
|
84
86
|
}
|
|
85
|
-
//# sourceMappingURL=terminalManager.js.map
|
|
@@ -20,15 +20,21 @@ export declare function deleteTask(projectSlug: string, wiIdOrSlug: string, task
|
|
|
20
20
|
*/
|
|
21
21
|
export declare function activateWorkItemIfNeeded(projectSlug: string, wiIdOrSlug: string): WorkItem | null;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* Auto-sync work item status based on task distribution:
|
|
24
|
+
* - active → review: when all tasks are in review or done (nothing in backlog/todo/in-progress)
|
|
25
|
+
* - review → done: when ALL tasks are in done column
|
|
26
|
+
* - review → active: if tasks move back to pending columns
|
|
26
27
|
*/
|
|
28
|
+
export declare function syncWorkItemStatus(projectSlug: string, wiIdOrSlug: string): WorkItem | null;
|
|
29
|
+
/** @deprecated Use syncWorkItemStatus instead */
|
|
27
30
|
export declare function promoteWorkItemIfComplete(projectSlug: string, wiIdOrSlug: string): WorkItem | null;
|
|
31
|
+
/**
|
|
32
|
+
* Reorder a work item within its status column.
|
|
33
|
+
*/
|
|
34
|
+
export declare function reorderWorkItem(projectSlug: string, wiIdOrSlug: string, newOrder: number): WorkItem | null;
|
|
28
35
|
export declare function getTaskCounts(wi: WorkItem): Record<TaskColumnName, number>;
|
|
29
36
|
export declare function getProgress(wi: WorkItem): {
|
|
30
37
|
completed: number;
|
|
31
38
|
total: number;
|
|
32
39
|
percent: number;
|
|
33
40
|
};
|
|
34
|
-
//# sourceMappingURL=workItemStore.d.ts.map
|
|
@@ -13,7 +13,9 @@ exports.updateTask = updateTask;
|
|
|
13
13
|
exports.moveTask = moveTask;
|
|
14
14
|
exports.deleteTask = deleteTask;
|
|
15
15
|
exports.activateWorkItemIfNeeded = activateWorkItemIfNeeded;
|
|
16
|
+
exports.syncWorkItemStatus = syncWorkItemStatus;
|
|
16
17
|
exports.promoteWorkItemIfComplete = promoteWorkItemIfComplete;
|
|
18
|
+
exports.reorderWorkItem = reorderWorkItem;
|
|
17
19
|
exports.getTaskCounts = getTaskCounts;
|
|
18
20
|
exports.getProgress = getProgress;
|
|
19
21
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -22,12 +24,13 @@ const types_1 = require("../../shared/types");
|
|
|
22
24
|
const schemas_1 = require("../lib/schemas");
|
|
23
25
|
const generateId_1 = require("../lib/generateId");
|
|
24
26
|
const types_2 = require("../../shared/types");
|
|
27
|
+
const safePath_1 = require("../lib/safePath");
|
|
25
28
|
const DATA_DIR = path_1.default.resolve(process.env.KANBAII_DATA_DIR || path_1.default.join(process.cwd(), 'data', 'projects'));
|
|
26
29
|
function workItemsDir(projectSlug) {
|
|
27
|
-
return
|
|
30
|
+
return (0, safePath_1.safePath)(DATA_DIR, projectSlug, 'work-items');
|
|
28
31
|
}
|
|
29
|
-
function workItemFile(projectSlug,
|
|
30
|
-
return
|
|
32
|
+
function workItemFile(projectSlug, slug) {
|
|
33
|
+
return (0, safePath_1.safePath)(DATA_DIR, projectSlug, 'work-items', `${slug}.json`);
|
|
31
34
|
}
|
|
32
35
|
function ensureDir(dir) {
|
|
33
36
|
if (!fs_1.default.existsSync(dir)) {
|
|
@@ -95,7 +98,7 @@ function listWorkItems(projectSlug) {
|
|
|
95
98
|
if (wi)
|
|
96
99
|
items.push(wi);
|
|
97
100
|
}
|
|
98
|
-
return items.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
101
|
+
return items.sort((a, b) => (a.order ?? 999) - (b.order ?? 999) || b.updatedAt.localeCompare(a.updatedAt));
|
|
99
102
|
}
|
|
100
103
|
function getWorkItem(projectSlug, idOrSlug) {
|
|
101
104
|
return findWorkItemByIdOrSlug(projectSlug, idOrSlug);
|
|
@@ -245,7 +248,10 @@ function moveTask(projectSlug, wiIdOrSlug, taskId, input) {
|
|
|
245
248
|
targetCol.splice(insertIdx, 0, task);
|
|
246
249
|
wi.updatedAt = now;
|
|
247
250
|
writeWorkItem(projectSlug, wi);
|
|
248
|
-
|
|
251
|
+
// Auto-sync work item status based on task distribution
|
|
252
|
+
syncWorkItemStatus(projectSlug, wiIdOrSlug);
|
|
253
|
+
// Re-read after potential status change
|
|
254
|
+
return findWorkItemByIdOrSlug(projectSlug, wiIdOrSlug) || wi;
|
|
249
255
|
}
|
|
250
256
|
function deleteTask(projectSlug, wiIdOrSlug, taskId) {
|
|
251
257
|
const wi = findWorkItemByIdOrSlug(projectSlug, wiIdOrSlug);
|
|
@@ -276,30 +282,62 @@ function activateWorkItemIfNeeded(projectSlug, wiIdOrSlug) {
|
|
|
276
282
|
return wi;
|
|
277
283
|
}
|
|
278
284
|
/**
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
285
|
+
* Auto-sync work item status based on task distribution:
|
|
286
|
+
* - active → review: when all tasks are in review or done (nothing in backlog/todo/in-progress)
|
|
287
|
+
* - review → done: when ALL tasks are in done column
|
|
288
|
+
* - review → active: if tasks move back to pending columns
|
|
282
289
|
*/
|
|
283
|
-
function
|
|
290
|
+
function syncWorkItemStatus(projectSlug, wiIdOrSlug) {
|
|
284
291
|
const wi = findWorkItemByIdOrSlug(projectSlug, wiIdOrSlug);
|
|
285
292
|
if (!wi)
|
|
286
293
|
return null;
|
|
287
|
-
if (wi.status
|
|
294
|
+
if (wi.status === 'planning' || wi.status === 'done')
|
|
295
|
+
return wi;
|
|
296
|
+
const backlog = wi.columns['backlog'].length;
|
|
297
|
+
const todo = wi.columns['todo'].length;
|
|
298
|
+
const inProgress = wi.columns['in-progress'].length;
|
|
299
|
+
const review = wi.columns['review'].length;
|
|
300
|
+
const done = wi.columns['done'].length;
|
|
301
|
+
const total = backlog + todo + inProgress + review + done;
|
|
302
|
+
const pending = backlog + todo + inProgress;
|
|
303
|
+
if (total === 0)
|
|
288
304
|
return wi;
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
305
|
+
let newStatus = wi.status;
|
|
306
|
+
if (done === total) {
|
|
307
|
+
// ALL tasks done → work item done
|
|
308
|
+
newStatus = 'done';
|
|
309
|
+
}
|
|
310
|
+
else if (pending === 0) {
|
|
311
|
+
// No pending tasks (all in review/done) → work item review
|
|
312
|
+
newStatus = 'review';
|
|
313
|
+
}
|
|
314
|
+
else if (wi.status === 'review' && pending > 0) {
|
|
315
|
+
// Tasks moved back to pending → revert to active
|
|
316
|
+
newStatus = 'active';
|
|
317
|
+
}
|
|
318
|
+
if (newStatus !== wi.status) {
|
|
319
|
+
wi.status = newStatus;
|
|
298
320
|
wi.updatedAt = new Date().toISOString();
|
|
299
321
|
writeWorkItem(projectSlug, wi);
|
|
300
322
|
}
|
|
301
323
|
return wi;
|
|
302
324
|
}
|
|
325
|
+
/** @deprecated Use syncWorkItemStatus instead */
|
|
326
|
+
function promoteWorkItemIfComplete(projectSlug, wiIdOrSlug) {
|
|
327
|
+
return syncWorkItemStatus(projectSlug, wiIdOrSlug);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Reorder a work item within its status column.
|
|
331
|
+
*/
|
|
332
|
+
function reorderWorkItem(projectSlug, wiIdOrSlug, newOrder) {
|
|
333
|
+
const wi = findWorkItemByIdOrSlug(projectSlug, wiIdOrSlug);
|
|
334
|
+
if (!wi)
|
|
335
|
+
return null;
|
|
336
|
+
wi.order = newOrder;
|
|
337
|
+
wi.updatedAt = new Date().toISOString();
|
|
338
|
+
writeWorkItem(projectSlug, wi);
|
|
339
|
+
return wi;
|
|
340
|
+
}
|
|
303
341
|
// --- Utilities ---
|
|
304
342
|
function getTaskCounts(wi) {
|
|
305
343
|
const counts = {};
|
|
@@ -317,4 +355,3 @@ function getProgress(wi) {
|
|
|
317
355
|
}
|
|
318
356
|
return { completed, total, percent: total === 0 ? 0 : Math.round((completed / total) * 100) };
|
|
319
357
|
}
|
|
320
|
-
//# sourceMappingURL=workItemStore.js.map
|