@loicngr/kobo 0.1.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/AGENTS.md +227 -0
- package/LICENSE +674 -0
- package/README.md +199 -0
- package/dist/mcp-server/kobo-tasks-handlers.js +27 -0
- package/dist/mcp-server/kobo-tasks-server.js +116 -0
- package/dist/server/db/index.js +22 -0
- package/dist/server/db/migrations.js +20 -0
- package/dist/server/db/schema.js +49 -0
- package/dist/server/index.js +178 -0
- package/dist/server/routes/dev-server.js +74 -0
- package/dist/server/routes/git.js +20 -0
- package/dist/server/routes/notion.js +24 -0
- package/dist/server/routes/settings.js +92 -0
- package/dist/server/routes/workspaces.js +730 -0
- package/dist/server/services/agent-manager.js +435 -0
- package/dist/server/services/dev-server-service.js +298 -0
- package/dist/server/services/notion-service.js +369 -0
- package/dist/server/services/pr-template-service.js +38 -0
- package/dist/server/services/settings-service.js +205 -0
- package/dist/server/services/websocket-service.js +212 -0
- package/dist/server/services/workspace-service.js +208 -0
- package/dist/server/services/worktree-service.js +117 -0
- package/dist/server/utils/git-ops.js +117 -0
- package/dist/server/utils/paths.js +95 -0
- package/dist/server/utils/process-tracker.js +46 -0
- package/package.json +84 -0
- package/src/client/dist/spa/assets/ActivityFeed-BveJRagX.js +60 -0
- package/src/client/dist/spa/assets/ActivityFeed-DBNn62g_.css +1 -0
- package/src/client/dist/spa/assets/CreatePage-BlgXsrJO.css +1 -0
- package/src/client/dist/spa/assets/CreatePage-wbOkBwYU.js +2 -0
- package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYjalmUiAw-BepdiOnY.woff +0 -0
- package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtalmUiAw-4ZhHFPot.woff +0 -0
- package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmUiAw-CNa4tw4G.woff +0 -0
- package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWub2bVmUiAw-CHKg1YId.woff +0 -0
- package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbFmUiAw-yBxCyPWP.woff +0 -0
- package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAw-3fZ6d7DD.woff +0 -0
- package/src/client/dist/spa/assets/MainLayout-6hzaLlYO.js +1 -0
- package/src/client/dist/spa/assets/MainLayout-D0OU6djX.css +1 -0
- package/src/client/dist/spa/assets/QBadge-Cb92Ia8-.js +1 -0
- package/src/client/dist/spa/assets/QDialog-B5H6ayTp.js +1 -0
- package/src/client/dist/spa/assets/QExpansionItem-DJgnAZg_.js +1 -0
- package/src/client/dist/spa/assets/QPage-CLk9i9z8.js +1 -0
- package/src/client/dist/spa/assets/QSpinnerDots-DcaNq8uL.js +1 -0
- package/src/client/dist/spa/assets/QTabPanels-DlG5TZhP.js +1 -0
- package/src/client/dist/spa/assets/QTooltip-637ruGFc.js +1 -0
- package/src/client/dist/spa/assets/SettingsPage-B9VYIQs-.css +1 -0
- package/src/client/dist/spa/assets/SettingsPage-KEqbLZUA.js +1 -0
- package/src/client/dist/spa/assets/WorkspacePage-BFuHLjou.css +1 -0
- package/src/client/dist/spa/assets/WorkspacePage-D0Hm21LY.js +2 -0
- package/src/client/dist/spa/assets/_plugin-vue_export-helper-CHpmshS7.js +1 -0
- package/src/client/dist/spa/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff +0 -0
- package/src/client/dist/spa/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-D-x-0Q06.woff2 +0 -0
- package/src/client/dist/spa/assets/index-BThMCiY7.css +1 -0
- package/src/client/dist/spa/assets/index-CMvo3OTb.js +5 -0
- package/src/client/dist/spa/assets/nodes-DeIen-kp.js +1 -0
- package/src/client/dist/spa/assets/use-quasar-Dq-Vjx_2.js +1 -0
- package/src/client/dist/spa/index.html +4 -0
- package/src/mcp-server/kobo-tasks-handlers.ts +54 -0
- package/src/mcp-server/kobo-tasks-server.ts +128 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { getDevServerLogs, getStatus, startDevServer, stopDevServer } from '../services/dev-server-service.js';
|
|
3
|
+
import { getWorkspace } from '../services/workspace-service.js';
|
|
4
|
+
const app = new Hono();
|
|
5
|
+
// GET /api/dev-server/:workspaceId/status
|
|
6
|
+
app.get('/:workspaceId/status', (c) => {
|
|
7
|
+
try {
|
|
8
|
+
const workspaceId = c.req.param('workspaceId');
|
|
9
|
+
const workspace = getWorkspace(workspaceId);
|
|
10
|
+
if (!workspace) {
|
|
11
|
+
return c.json({ error: `Workspace '${workspaceId}' not found` }, 404);
|
|
12
|
+
}
|
|
13
|
+
const status = getStatus(workspace.projectPath, workspace.workingBranch);
|
|
14
|
+
// If runtime detection returns unknown, use persisted status from DB
|
|
15
|
+
if (status.status === 'unknown' && workspace.devServerStatus && workspace.devServerStatus !== 'stopped') {
|
|
16
|
+
status.status = workspace.devServerStatus;
|
|
17
|
+
}
|
|
18
|
+
return c.json(status);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
22
|
+
return c.json({ error: message }, 500);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
// POST /api/dev-server/:workspaceId/start
|
|
26
|
+
app.post('/:workspaceId/start', (c) => {
|
|
27
|
+
try {
|
|
28
|
+
const workspaceId = c.req.param('workspaceId');
|
|
29
|
+
const workspace = getWorkspace(workspaceId);
|
|
30
|
+
if (!workspace) {
|
|
31
|
+
return c.json({ error: `Workspace '${workspaceId}' not found` }, 404);
|
|
32
|
+
}
|
|
33
|
+
const status = startDevServer(workspaceId);
|
|
34
|
+
return c.json(status);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
38
|
+
return c.json({ error: message }, 500);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
// POST /api/dev-server/:workspaceId/stop
|
|
42
|
+
app.post('/:workspaceId/stop', (c) => {
|
|
43
|
+
try {
|
|
44
|
+
const workspaceId = c.req.param('workspaceId');
|
|
45
|
+
const workspace = getWorkspace(workspaceId);
|
|
46
|
+
if (!workspace) {
|
|
47
|
+
return c.json({ error: `Workspace '${workspaceId}' not found` }, 404);
|
|
48
|
+
}
|
|
49
|
+
const status = stopDevServer(workspaceId);
|
|
50
|
+
return c.json(status);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
54
|
+
return c.json({ error: message }, 500);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
// GET /api/dev-server/:workspaceId/logs
|
|
58
|
+
app.get('/:workspaceId/logs', (c) => {
|
|
59
|
+
try {
|
|
60
|
+
const workspaceId = c.req.param('workspaceId');
|
|
61
|
+
const workspace = getWorkspace(workspaceId);
|
|
62
|
+
if (!workspace) {
|
|
63
|
+
return c.json({ error: `Workspace '${workspaceId}' not found` }, 404);
|
|
64
|
+
}
|
|
65
|
+
const tail = parseInt(c.req.query('tail') ?? '200', 10);
|
|
66
|
+
const logs = getDevServerLogs(workspaceId, tail);
|
|
67
|
+
return c.json({ logs });
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
71
|
+
return c.json({ error: message }, 500);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
export default app;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { listBranches, listRemoteBranches } from '../utils/git-ops.js';
|
|
3
|
+
const app = new Hono();
|
|
4
|
+
// GET /api/git/branches?path=<repoPath> — list branches for a repo
|
|
5
|
+
app.get('/branches', (c) => {
|
|
6
|
+
try {
|
|
7
|
+
const repoPath = c.req.query('path');
|
|
8
|
+
if (!repoPath) {
|
|
9
|
+
return c.json({ error: 'Missing required query parameter: path' }, 400);
|
|
10
|
+
}
|
|
11
|
+
const local = listBranches(repoPath);
|
|
12
|
+
const remote = listRemoteBranches(repoPath);
|
|
13
|
+
return c.json({ local, remote });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
17
|
+
return c.json({ error: message }, 500);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
export default app;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { extractNotionPage } from '../services/notion-service.js';
|
|
3
|
+
const app = new Hono();
|
|
4
|
+
// POST /api/notion/extract — extract a Notion page
|
|
5
|
+
app.post('/extract', async (c) => {
|
|
6
|
+
try {
|
|
7
|
+
const body = await c.req.json();
|
|
8
|
+
if (!body.url) {
|
|
9
|
+
return c.json({ error: 'Missing required field: url' }, 400);
|
|
10
|
+
}
|
|
11
|
+
const content = await extractNotionPage(body.url);
|
|
12
|
+
return c.json({
|
|
13
|
+
title: content.title,
|
|
14
|
+
goal: content.goal,
|
|
15
|
+
todos: content.todos,
|
|
16
|
+
gherkinFeatures: content.gherkinFeatures,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21
|
+
return c.json({ error: message }, 500);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
export default app;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import * as settingsService from '../services/settings-service.js';
|
|
3
|
+
const app = new Hono();
|
|
4
|
+
// GET /api/settings — return full settings
|
|
5
|
+
app.get('/', (c) => {
|
|
6
|
+
try {
|
|
7
|
+
const settings = settingsService.getSettings();
|
|
8
|
+
return c.json(settings);
|
|
9
|
+
}
|
|
10
|
+
catch (err) {
|
|
11
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
12
|
+
return c.json({ error: message }, 500);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
// GET /api/settings/global — return global settings
|
|
16
|
+
app.get('/global', (c) => {
|
|
17
|
+
try {
|
|
18
|
+
const global = settingsService.getGlobalSettings();
|
|
19
|
+
return c.json(global);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23
|
+
return c.json({ error: message }, 500);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
// PUT /api/settings/global — update global settings
|
|
27
|
+
app.put('/global', async (c) => {
|
|
28
|
+
try {
|
|
29
|
+
const body = await c.req.json();
|
|
30
|
+
const updated = settingsService.updateGlobalSettings(body);
|
|
31
|
+
return c.json(updated);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
return c.json({ error: message }, 500);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// GET /api/settings/projects — list all projects
|
|
39
|
+
app.get('/projects', (c) => {
|
|
40
|
+
try {
|
|
41
|
+
const projects = settingsService.listProjects();
|
|
42
|
+
return c.json(projects);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
46
|
+
return c.json({ error: message }, 500);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
// GET /api/settings/projects/:encodedPath — get project by path
|
|
50
|
+
app.get('/projects/:encodedPath', (c) => {
|
|
51
|
+
try {
|
|
52
|
+
const encodedPath = c.req.param('encodedPath');
|
|
53
|
+
const projectPath = Buffer.from(encodedPath, 'base64url').toString();
|
|
54
|
+
const project = settingsService.getProjectSettings(projectPath);
|
|
55
|
+
if (!project) {
|
|
56
|
+
return c.json({ error: `Project not found: '${projectPath}'` }, 404);
|
|
57
|
+
}
|
|
58
|
+
return c.json(project);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
62
|
+
return c.json({ error: message }, 500);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// PUT /api/settings/projects/:encodedPath — add or update project
|
|
66
|
+
app.put('/projects/:encodedPath', async (c) => {
|
|
67
|
+
try {
|
|
68
|
+
const encodedPath = c.req.param('encodedPath');
|
|
69
|
+
const projectPath = Buffer.from(encodedPath, 'base64url').toString();
|
|
70
|
+
const body = await c.req.json();
|
|
71
|
+
const project = settingsService.upsertProject(projectPath, body);
|
|
72
|
+
return c.json(project);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
76
|
+
return c.json({ error: message }, 500);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
// DELETE /api/settings/projects/:encodedPath — remove project
|
|
80
|
+
app.delete('/projects/:encodedPath', (c) => {
|
|
81
|
+
try {
|
|
82
|
+
const encodedPath = c.req.param('encodedPath');
|
|
83
|
+
const projectPath = Buffer.from(encodedPath, 'base64url').toString();
|
|
84
|
+
settingsService.deleteProject(projectPath);
|
|
85
|
+
return new Response(null, { status: 204 });
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
89
|
+
return c.json({ error: message }, 500);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
export default app;
|