@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.
Files changed (59) hide show
  1. package/AGENTS.md +227 -0
  2. package/LICENSE +674 -0
  3. package/README.md +199 -0
  4. package/dist/mcp-server/kobo-tasks-handlers.js +27 -0
  5. package/dist/mcp-server/kobo-tasks-server.js +116 -0
  6. package/dist/server/db/index.js +22 -0
  7. package/dist/server/db/migrations.js +20 -0
  8. package/dist/server/db/schema.js +49 -0
  9. package/dist/server/index.js +178 -0
  10. package/dist/server/routes/dev-server.js +74 -0
  11. package/dist/server/routes/git.js +20 -0
  12. package/dist/server/routes/notion.js +24 -0
  13. package/dist/server/routes/settings.js +92 -0
  14. package/dist/server/routes/workspaces.js +730 -0
  15. package/dist/server/services/agent-manager.js +435 -0
  16. package/dist/server/services/dev-server-service.js +298 -0
  17. package/dist/server/services/notion-service.js +369 -0
  18. package/dist/server/services/pr-template-service.js +38 -0
  19. package/dist/server/services/settings-service.js +205 -0
  20. package/dist/server/services/websocket-service.js +212 -0
  21. package/dist/server/services/workspace-service.js +208 -0
  22. package/dist/server/services/worktree-service.js +117 -0
  23. package/dist/server/utils/git-ops.js +117 -0
  24. package/dist/server/utils/paths.js +95 -0
  25. package/dist/server/utils/process-tracker.js +46 -0
  26. package/package.json +84 -0
  27. package/src/client/dist/spa/assets/ActivityFeed-BveJRagX.js +60 -0
  28. package/src/client/dist/spa/assets/ActivityFeed-DBNn62g_.css +1 -0
  29. package/src/client/dist/spa/assets/CreatePage-BlgXsrJO.css +1 -0
  30. package/src/client/dist/spa/assets/CreatePage-wbOkBwYU.js +2 -0
  31. package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYjalmUiAw-BepdiOnY.woff +0 -0
  32. package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtalmUiAw-4ZhHFPot.woff +0 -0
  33. package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmUiAw-CNa4tw4G.woff +0 -0
  34. package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWub2bVmUiAw-CHKg1YId.woff +0 -0
  35. package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbFmUiAw-yBxCyPWP.woff +0 -0
  36. package/src/client/dist/spa/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAw-3fZ6d7DD.woff +0 -0
  37. package/src/client/dist/spa/assets/MainLayout-6hzaLlYO.js +1 -0
  38. package/src/client/dist/spa/assets/MainLayout-D0OU6djX.css +1 -0
  39. package/src/client/dist/spa/assets/QBadge-Cb92Ia8-.js +1 -0
  40. package/src/client/dist/spa/assets/QDialog-B5H6ayTp.js +1 -0
  41. package/src/client/dist/spa/assets/QExpansionItem-DJgnAZg_.js +1 -0
  42. package/src/client/dist/spa/assets/QPage-CLk9i9z8.js +1 -0
  43. package/src/client/dist/spa/assets/QSpinnerDots-DcaNq8uL.js +1 -0
  44. package/src/client/dist/spa/assets/QTabPanels-DlG5TZhP.js +1 -0
  45. package/src/client/dist/spa/assets/QTooltip-637ruGFc.js +1 -0
  46. package/src/client/dist/spa/assets/SettingsPage-B9VYIQs-.css +1 -0
  47. package/src/client/dist/spa/assets/SettingsPage-KEqbLZUA.js +1 -0
  48. package/src/client/dist/spa/assets/WorkspacePage-BFuHLjou.css +1 -0
  49. package/src/client/dist/spa/assets/WorkspacePage-D0Hm21LY.js +2 -0
  50. package/src/client/dist/spa/assets/_plugin-vue_export-helper-CHpmshS7.js +1 -0
  51. package/src/client/dist/spa/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff +0 -0
  52. package/src/client/dist/spa/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-D-x-0Q06.woff2 +0 -0
  53. package/src/client/dist/spa/assets/index-BThMCiY7.css +1 -0
  54. package/src/client/dist/spa/assets/index-CMvo3OTb.js +5 -0
  55. package/src/client/dist/spa/assets/nodes-DeIen-kp.js +1 -0
  56. package/src/client/dist/spa/assets/use-quasar-Dq-Vjx_2.js +1 -0
  57. package/src/client/dist/spa/index.html +4 -0
  58. package/src/mcp-server/kobo-tasks-handlers.ts +54 -0
  59. 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;