@dtoolkit/dwork 0.1.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.
Files changed (134) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -0
  3. package/dist/cli/configure.d.ts +2 -0
  4. package/dist/cli/configure.d.ts.map +1 -0
  5. package/dist/cli/configure.js +83 -0
  6. package/dist/cli/configure.js.map +1 -0
  7. package/dist/cli/index.d.ts +3 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +76 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/init.d.ts +4 -0
  12. package/dist/cli/init.d.ts.map +1 -0
  13. package/dist/cli/init.js +143 -0
  14. package/dist/cli/init.js.map +1 -0
  15. package/dist/cli/keys.d.ts +11 -0
  16. package/dist/cli/keys.d.ts.map +1 -0
  17. package/dist/cli/keys.js +85 -0
  18. package/dist/cli/keys.js.map +1 -0
  19. package/dist/cli/start.d.ts +2 -0
  20. package/dist/cli/start.d.ts.map +1 -0
  21. package/dist/cli/start.js +53 -0
  22. package/dist/cli/start.js.map +1 -0
  23. package/dist/cli/status.d.ts +2 -0
  24. package/dist/cli/status.d.ts.map +1 -0
  25. package/dist/cli/status.js +36 -0
  26. package/dist/cli/status.js.map +1 -0
  27. package/dist/cli/sync.d.ts +4 -0
  28. package/dist/cli/sync.d.ts.map +1 -0
  29. package/dist/cli/sync.js +38 -0
  30. package/dist/cli/sync.js.map +1 -0
  31. package/dist/core/config.d.ts +21 -0
  32. package/dist/core/config.d.ts.map +1 -0
  33. package/dist/core/config.js +31 -0
  34. package/dist/core/config.js.map +1 -0
  35. package/dist/core/db.d.ts +4 -0
  36. package/dist/core/db.d.ts.map +1 -0
  37. package/dist/core/db.js +90 -0
  38. package/dist/core/db.js.map +1 -0
  39. package/dist/core/indexer.d.ts +9 -0
  40. package/dist/core/indexer.d.ts.map +1 -0
  41. package/dist/core/indexer.js +145 -0
  42. package/dist/core/indexer.js.map +1 -0
  43. package/dist/core/models.d.ts +113 -0
  44. package/dist/core/models.d.ts.map +1 -0
  45. package/dist/core/models.js +53 -0
  46. package/dist/core/models.js.map +1 -0
  47. package/dist/core/parser.d.ts +20 -0
  48. package/dist/core/parser.d.ts.map +1 -0
  49. package/dist/core/parser.js +126 -0
  50. package/dist/core/parser.js.map +1 -0
  51. package/dist/core/templates.d.ts +5 -0
  52. package/dist/core/templates.d.ts.map +1 -0
  53. package/dist/core/templates.js +84 -0
  54. package/dist/core/templates.js.map +1 -0
  55. package/dist/dashboard/index.html +1127 -0
  56. package/dist/dashboard/logo-dwork-complete.png +0 -0
  57. package/dist/dashboard/logo-dwork.png +0 -0
  58. package/dist/dashboard/server.d.ts +2 -0
  59. package/dist/dashboard/server.d.ts.map +1 -0
  60. package/dist/dashboard/server.js +27 -0
  61. package/dist/dashboard/server.js.map +1 -0
  62. package/dist/mcp/server.d.ts +5 -0
  63. package/dist/mcp/server.d.ts.map +1 -0
  64. package/dist/mcp/server.js +242 -0
  65. package/dist/mcp/server.js.map +1 -0
  66. package/dist/server/index.d.ts +7 -0
  67. package/dist/server/index.d.ts.map +1 -0
  68. package/dist/server/index.js +63 -0
  69. package/dist/server/index.js.map +1 -0
  70. package/dist/server/routes/docs.d.ts +3 -0
  71. package/dist/server/routes/docs.d.ts.map +1 -0
  72. package/dist/server/routes/docs.js +53 -0
  73. package/dist/server/routes/docs.js.map +1 -0
  74. package/dist/server/routes/health.d.ts +3 -0
  75. package/dist/server/routes/health.d.ts.map +1 -0
  76. package/dist/server/routes/health.js +27 -0
  77. package/dist/server/routes/health.js.map +1 -0
  78. package/dist/server/routes/keys.d.ts +3 -0
  79. package/dist/server/routes/keys.d.ts.map +1 -0
  80. package/dist/server/routes/keys.js +58 -0
  81. package/dist/server/routes/keys.js.map +1 -0
  82. package/dist/server/routes/overview.d.ts +3 -0
  83. package/dist/server/routes/overview.d.ts.map +1 -0
  84. package/dist/server/routes/overview.js +12 -0
  85. package/dist/server/routes/overview.js.map +1 -0
  86. package/dist/server/routes/permissions.d.ts +3 -0
  87. package/dist/server/routes/permissions.d.ts.map +1 -0
  88. package/dist/server/routes/permissions.js +9 -0
  89. package/dist/server/routes/permissions.js.map +1 -0
  90. package/dist/server/routes/projects.d.ts +3 -0
  91. package/dist/server/routes/projects.d.ts.map +1 -0
  92. package/dist/server/routes/projects.js +50 -0
  93. package/dist/server/routes/projects.js.map +1 -0
  94. package/dist/server/routes/search.d.ts +3 -0
  95. package/dist/server/routes/search.d.ts.map +1 -0
  96. package/dist/server/routes/search.js +10 -0
  97. package/dist/server/routes/search.js.map +1 -0
  98. package/dist/server/routes/sync.d.ts +3 -0
  99. package/dist/server/routes/sync.d.ts.map +1 -0
  100. package/dist/server/routes/sync.js +11 -0
  101. package/dist/server/routes/sync.js.map +1 -0
  102. package/dist/server/routes/tasks.d.ts +3 -0
  103. package/dist/server/routes/tasks.d.ts.map +1 -0
  104. package/dist/server/routes/tasks.js +45 -0
  105. package/dist/server/routes/tasks.js.map +1 -0
  106. package/dist/service/docs.d.ts +26 -0
  107. package/dist/service/docs.d.ts.map +1 -0
  108. package/dist/service/docs.js +137 -0
  109. package/dist/service/docs.js.map +1 -0
  110. package/dist/service/overview.d.ts +18 -0
  111. package/dist/service/overview.d.ts.map +1 -0
  112. package/dist/service/overview.js +46 -0
  113. package/dist/service/overview.js.map +1 -0
  114. package/dist/service/projects.d.ts +34 -0
  115. package/dist/service/projects.d.ts.map +1 -0
  116. package/dist/service/projects.js +99 -0
  117. package/dist/service/projects.js.map +1 -0
  118. package/dist/service/search.d.ts +13 -0
  119. package/dist/service/search.d.ts.map +1 -0
  120. package/dist/service/search.js +59 -0
  121. package/dist/service/search.js.map +1 -0
  122. package/dist/service/sync.d.ts +9 -0
  123. package/dist/service/sync.d.ts.map +1 -0
  124. package/dist/service/sync.js +95 -0
  125. package/dist/service/sync.js.map +1 -0
  126. package/dist/service/tasks.d.ts +40 -0
  127. package/dist/service/tasks.d.ts.map +1 -0
  128. package/dist/service/tasks.js +156 -0
  129. package/dist/service/tasks.js.map +1 -0
  130. package/dist/service/utils.d.ts +2 -0
  131. package/dist/service/utils.d.ts.map +1 -0
  132. package/dist/service/utils.js +5 -0
  133. package/dist/service/utils.js.map +1 -0
  134. package/package.json +62 -0
@@ -0,0 +1,9 @@
1
+ export function requireWrite(request, reply) {
2
+ const perms = request.dworkUser?.permissions;
3
+ if (perms === 'read') {
4
+ reply.code(403).send({ error: 'Write access required' });
5
+ return false;
6
+ }
7
+ return true;
8
+ }
9
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../../src/server/routes/permissions.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,OAAuB,EAAE,KAAmB;IACvE,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC;IAC7C,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ export declare function projectRoutes(app: FastifyInstance): Promise<void>;
3
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/server/routes/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,wBAAsB,aAAa,CAAC,GAAG,EAAE,eAAe,iBAsDvD"}
@@ -0,0 +1,50 @@
1
+ import * as projectService from '../../service/projects.js';
2
+ import { requireWrite } from './permissions.js';
3
+ export async function projectRoutes(app) {
4
+ const { db, config } = app;
5
+ app.get('/projects', async (request) => {
6
+ const { status } = request.query;
7
+ return projectService.listProjects(db, status);
8
+ });
9
+ app.get('/projects/:slug', async (request, reply) => {
10
+ const { slug } = request.params;
11
+ const result = projectService.getProject(db, config, slug);
12
+ if (!result)
13
+ return reply.code(404).send({ error: 'Project not found' });
14
+ return result;
15
+ });
16
+ app.post('/projects', async (request, reply) => {
17
+ if (!requireWrite(request, reply))
18
+ return;
19
+ const { slug, name, description, source_path } = request.body;
20
+ if (!slug || !name)
21
+ return reply.code(400).send({ error: 'slug and name are required' });
22
+ try {
23
+ const result = projectService.createProject(db, config, slug, name, description, source_path);
24
+ return reply.code(201).send(result);
25
+ }
26
+ catch (err) {
27
+ return reply.code(409).send({ error: err.message });
28
+ }
29
+ });
30
+ app.patch('/projects/:slug', async (request, reply) => {
31
+ if (!requireWrite(request, reply))
32
+ return;
33
+ const { slug } = request.params;
34
+ const changes = request.body;
35
+ const ok = projectService.updateProject(db, slug, changes);
36
+ if (!ok)
37
+ return reply.code(404).send({ error: 'Project not found' });
38
+ return { updated: true, slug };
39
+ });
40
+ app.delete('/projects/:slug', async (request, reply) => {
41
+ if (!requireWrite(request, reply))
42
+ return;
43
+ const { slug } = request.params;
44
+ const ok = projectService.archiveProject(db, slug);
45
+ if (!ok)
46
+ return reply.code(404).send({ error: 'Project not found' });
47
+ return { archived: true, slug };
48
+ });
49
+ }
50
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../../src/server/routes/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ export declare function searchRoutes(app: FastifyInstance): Promise<void>;
3
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/server/routes/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/C,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,iBAUtD"}
@@ -0,0 +1,10 @@
1
+ import * as searchService from '../../service/search.js';
2
+ export async function searchRoutes(app) {
3
+ app.post('/search', async (request, reply) => {
4
+ const { query, project, limit } = request.body;
5
+ if (!query)
6
+ return reply.code(400).send({ error: 'query is required' });
7
+ return searchService.search(app.db, query, project, limit);
8
+ });
9
+ }
10
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/server/routes/search.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,aAAa,MAAM,yBAAyB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAoB;IACrD,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC3C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAIzC,CAAC;QACF,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACxE,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ export declare function syncRoutes(app: FastifyInstance): Promise<void>;
3
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/server/routes/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,wBAAsB,UAAU,CAAC,GAAG,EAAE,eAAe,iBAMpD"}
@@ -0,0 +1,11 @@
1
+ import * as syncService from '../../service/sync.js';
2
+ import { requireWrite } from './permissions.js';
3
+ export async function syncRoutes(app) {
4
+ app.post('/sync/:slug', async (request, reply) => {
5
+ if (!requireWrite(request, reply))
6
+ return;
7
+ const { slug } = request.params;
8
+ return syncService.syncProject(app.db, app.config, slug);
9
+ });
10
+ }
11
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/server/routes/sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,WAAW,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAoB;IACnD,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC/C,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC;YAAE,OAAO;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAA0B,CAAC;QACpD,OAAO,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ export declare function taskRoutes(app: FastifyInstance): Promise<void>;
3
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/server/routes/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,wBAAsB,UAAU,CAAC,GAAG,EAAE,eAAe,iBAwDpD"}
@@ -0,0 +1,45 @@
1
+ import * as taskService from '../../service/tasks.js';
2
+ import { requireWrite } from './permissions.js';
3
+ export async function taskRoutes(app) {
4
+ const { db, config } = app;
5
+ app.get('/projects/:slug/tasks', async (request) => {
6
+ const { slug } = request.params;
7
+ const { status, priority } = request.query;
8
+ return taskService.getTasks(db, slug, status, priority);
9
+ });
10
+ app.post('/projects/:slug/tasks', async (request, reply) => {
11
+ if (!requireWrite(request, reply))
12
+ return;
13
+ const { slug } = request.params;
14
+ const { title, ...opts } = request.body;
15
+ if (!title)
16
+ return reply.code(400).send({ error: 'title is required' });
17
+ try {
18
+ const result = taskService.addTask(db, config, slug, title, opts);
19
+ return reply.code(201).send(result);
20
+ }
21
+ catch (err) {
22
+ return reply.code(404).send({ error: err.message });
23
+ }
24
+ });
25
+ app.patch('/tasks/:id', async (request, reply) => {
26
+ if (!requireWrite(request, reply))
27
+ return;
28
+ const { id } = request.params;
29
+ const changes = request.body;
30
+ const ok = taskService.updateTask(db, config, id, changes);
31
+ if (!ok)
32
+ return reply.code(404).send({ error: 'Task not found' });
33
+ return { updated: true, id };
34
+ });
35
+ app.delete('/tasks/:id', async (request, reply) => {
36
+ if (!requireWrite(request, reply))
37
+ return;
38
+ const { id } = request.params;
39
+ const ok = taskService.deleteTask(db, config, id);
40
+ if (!ok)
41
+ return reply.code(404).send({ error: 'Task not found' });
42
+ return { deleted: true, id };
43
+ });
44
+ }
45
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/server/routes/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { Config } from '../core/config.js';
3
+ export interface DocRow {
4
+ id: string;
5
+ project_slug: string;
6
+ title: string;
7
+ type: string;
8
+ file_path: string;
9
+ body_hash: string | null;
10
+ created_at: string;
11
+ updated_at: string;
12
+ }
13
+ export interface DocWithContent extends DocRow {
14
+ content: string;
15
+ }
16
+ export declare function listDocs(db: Database.Database, project: string, type?: string): DocRow[];
17
+ export declare function getDoc(db: Database.Database, config: Config, docId: string): DocWithContent | null;
18
+ export declare function addDoc(db: Database.Database, config: Config, project: string, title: string, body: string, type: string): DocRow;
19
+ export declare function updateDoc(db: Database.Database, config: Config, docId: string, changes: {
20
+ title?: string;
21
+ body?: string;
22
+ type?: string;
23
+ }): boolean;
24
+ export declare function deleteDoc(db: Database.Database, config: Config, docId: string): boolean;
25
+ export declare function getRoadmap(db: Database.Database, config: Config, project: string): string | null;
26
+ //# sourceMappingURL=docs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/service/docs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,MAAM;IAC5C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAWxF;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,cAAc,GAAG,IAAI,CAiBvB;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,MAAM,CAiDR;AAED,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,OAAO,CAmCT;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAiBvF;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWhG"}
@@ -0,0 +1,137 @@
1
+ import { readFileSync, unlinkSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
4
+ import { indexProject } from '../core/indexer.js';
5
+ import { genId } from './utils.js';
6
+ export function listDocs(db, project, type) {
7
+ let sql = 'SELECT * FROM docs WHERE project_slug = ?';
8
+ const params = [project];
9
+ if (type) {
10
+ sql += ' AND type = ?';
11
+ params.push(type);
12
+ }
13
+ sql += ' ORDER BY file_path';
14
+ return db.prepare(sql).all(...params);
15
+ }
16
+ export function getDoc(db, config, docId) {
17
+ const doc = db.prepare('SELECT * FROM docs WHERE id = ?').get(docId);
18
+ if (!doc)
19
+ return null;
20
+ const project = db.prepare('SELECT path FROM projects WHERE slug = ?').get(doc.project_slug);
21
+ if (!project)
22
+ return null;
23
+ let content = '';
24
+ try {
25
+ content = readFileSync(join(project.path, doc.file_path), 'utf-8');
26
+ }
27
+ catch {
28
+ // file may not exist
29
+ }
30
+ return { ...doc, content };
31
+ }
32
+ export function addDoc(db, config, project, title, body, type) {
33
+ const projectRow = db.prepare('SELECT path FROM projects WHERE slug = ?').get(project);
34
+ if (!projectRow)
35
+ throw new Error(`Project '${project}' not found`);
36
+ const existingDocs = db
37
+ .prepare("SELECT file_path FROM docs WHERE project_slug = ? AND file_path LIKE 'docs/%'")
38
+ .all(project);
39
+ let maxNum = 0;
40
+ for (const d of existingDocs) {
41
+ const match = d.file_path.match(/^docs\/(\d+)_/);
42
+ if (match) {
43
+ const num = parseInt(match[1], 10);
44
+ if (num > maxNum)
45
+ maxNum = num;
46
+ }
47
+ }
48
+ const nextNum = String(maxNum + 1).padStart(3, '0');
49
+ const slug = title
50
+ .toLowerCase()
51
+ .replace(/[^a-z0-9]+/g, '-')
52
+ .replace(/(^-|-$)/g, '');
53
+ const fileName = `${nextNum}_${slug}.md`;
54
+ const relPath = `docs/${fileName}`;
55
+ const fm = { title, type };
56
+ const content = ['---', stringifyYaml(fm).trimEnd(), '---', '', body, ''].join('\n');
57
+ writeFileSync(join(projectRow.path, relPath), content);
58
+ indexProject(db, project, projectRow.path);
59
+ const inserted = db
60
+ .prepare('SELECT * FROM docs WHERE project_slug = ? AND file_path = ?')
61
+ .get(project, relPath);
62
+ return (inserted || {
63
+ id: genId('doc'),
64
+ project_slug: project,
65
+ title,
66
+ type,
67
+ file_path: relPath,
68
+ body_hash: null,
69
+ created_at: new Date().toISOString(),
70
+ updated_at: new Date().toISOString(),
71
+ });
72
+ }
73
+ export function updateDoc(db, config, docId, changes) {
74
+ const doc = db.prepare('SELECT * FROM docs WHERE id = ?').get(docId);
75
+ if (!doc)
76
+ return false;
77
+ const projectRow = db
78
+ .prepare('SELECT path FROM projects WHERE slug = ?')
79
+ .get(doc.project_slug);
80
+ if (!projectRow)
81
+ return false;
82
+ const filePath = join(projectRow.path, doc.file_path);
83
+ let content;
84
+ try {
85
+ content = readFileSync(filePath, 'utf-8');
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
91
+ let fmObj = {};
92
+ let body = content;
93
+ if (fmMatch) {
94
+ fmObj = parseYaml(fmMatch[1]) || {};
95
+ body = fmMatch[2];
96
+ }
97
+ if (changes.title)
98
+ fmObj.title = changes.title;
99
+ if (changes.type)
100
+ fmObj.type = changes.type;
101
+ if (changes.body !== undefined)
102
+ body = changes.body;
103
+ const newContent = ['---', stringifyYaml(fmObj).trimEnd(), '---', '', body].join('\n');
104
+ writeFileSync(filePath, newContent);
105
+ indexProject(db, doc.project_slug, projectRow.path);
106
+ return true;
107
+ }
108
+ export function deleteDoc(db, config, docId) {
109
+ const doc = db.prepare('SELECT * FROM docs WHERE id = ?').get(docId);
110
+ if (!doc)
111
+ return false;
112
+ const projectRow = db
113
+ .prepare('SELECT path FROM projects WHERE slug = ?')
114
+ .get(doc.project_slug);
115
+ if (!projectRow)
116
+ return false;
117
+ try {
118
+ unlinkSync(join(projectRow.path, doc.file_path));
119
+ }
120
+ catch {
121
+ // file may already be gone
122
+ }
123
+ indexProject(db, doc.project_slug, projectRow.path);
124
+ return true;
125
+ }
126
+ export function getRoadmap(db, config, project) {
127
+ const projectRow = db.prepare('SELECT path FROM projects WHERE slug = ?').get(project);
128
+ if (!projectRow)
129
+ return null;
130
+ try {
131
+ return readFileSync(join(projectRow.path, 'ROADMAP.md'), 'utf-8');
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+ //# sourceMappingURL=docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/service/docs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type Database from 'better-sqlite3';
2
+ export interface ProjectOverview {
3
+ slug: string;
4
+ name: string;
5
+ status: string;
6
+ tasksByStatus: Record<string, number>;
7
+ tasksByPriority: Record<string, number>;
8
+ totalTasks: number;
9
+ totalDocs: number;
10
+ }
11
+ export interface Overview {
12
+ projects: ProjectOverview[];
13
+ totalProjects: number;
14
+ totalTasks: number;
15
+ totalDocs: number;
16
+ }
17
+ export declare function overview(db: Database.Database): Overview;
18
+ //# sourceMappingURL=overview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../src/service/overview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAyDxD"}
@@ -0,0 +1,46 @@
1
+ export function overview(db) {
2
+ const projects = db
3
+ .prepare("SELECT slug, name, status FROM projects WHERE status != 'archived' ORDER BY updated_at DESC")
4
+ .all();
5
+ let totalTasks = 0;
6
+ let totalDocs = 0;
7
+ const projectOverviews = projects.map((p) => {
8
+ const statusCounts = db
9
+ .prepare('SELECT status, COUNT(*) as count FROM tasks WHERE project_slug = ? GROUP BY status')
10
+ .all(p.slug);
11
+ const priorityCounts = db
12
+ .prepare('SELECT priority, COUNT(*) as count FROM tasks WHERE project_slug = ? GROUP BY priority')
13
+ .all(p.slug);
14
+ const { docCount } = db
15
+ .prepare('SELECT COUNT(*) as docCount FROM docs WHERE project_slug = ?')
16
+ .get(p.slug);
17
+ const tasksByStatus = {};
18
+ let projTasks = 0;
19
+ for (const row of statusCounts) {
20
+ tasksByStatus[row.status] = row.count;
21
+ projTasks += row.count;
22
+ }
23
+ const tasksByPriority = {};
24
+ for (const row of priorityCounts) {
25
+ tasksByPriority[row.priority] = row.count;
26
+ }
27
+ totalTasks += projTasks;
28
+ totalDocs += docCount;
29
+ return {
30
+ slug: p.slug,
31
+ name: p.name,
32
+ status: p.status,
33
+ tasksByStatus,
34
+ tasksByPriority,
35
+ totalTasks: projTasks,
36
+ totalDocs: docCount,
37
+ };
38
+ });
39
+ return {
40
+ projects: projectOverviews,
41
+ totalProjects: projects.length,
42
+ totalTasks,
43
+ totalDocs,
44
+ };
45
+ }
46
+ //# sourceMappingURL=overview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../src/service/overview.ts"],"names":[],"mappings":"AAmBA,MAAM,UAAU,QAAQ,CAAC,EAAqB;IAC5C,MAAM,QAAQ,GAAG,EAAE;SAChB,OAAO,CACN,6FAA6F,CAC9F;SACA,GAAG,EAAsD,CAAC;IAE7D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,gBAAgB,GAAsB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7D,MAAM,YAAY,GAAG,EAAE;aACpB,OAAO,CAAC,oFAAoF,CAAC;aAC7F,GAAG,CAAC,CAAC,CAAC,IAAI,CAAwC,CAAC;QAEtD,MAAM,cAAc,GAAG,EAAE;aACtB,OAAO,CACN,wFAAwF,CACzF;aACA,GAAG,CAAC,CAAC,CAAC,IAAI,CAA0C,CAAC;QAExD,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE;aACpB,OAAO,CAAC,8DAA8D,CAAC;aACvE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAyB,CAAC;QAEvC,MAAM,aAAa,GAA2B,EAAE,CAAC;QACjD,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAC/B,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;YACtC,SAAS,IAAI,GAAG,CAAC,KAAK,CAAC;QACzB,CAAC;QAED,MAAM,eAAe,GAA2B,EAAE,CAAC;QACnD,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;QAC5C,CAAC;QAED,UAAU,IAAI,SAAS,CAAC;QACxB,SAAS,IAAI,QAAQ,CAAC;QAEtB,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,aAAa;YACb,eAAe;YACf,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,QAAQ;SACpB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ,EAAE,gBAAgB;QAC1B,aAAa,EAAE,QAAQ,CAAC,MAAM;QAC9B,UAAU;QACV,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { Config } from '../core/config.js';
3
+ import { genId } from './utils.js';
4
+ export interface ProjectWithContext {
5
+ slug: string;
6
+ name: string;
7
+ description: string | null;
8
+ status: string;
9
+ path: string;
10
+ source_path: string | null;
11
+ created_at: string;
12
+ updated_at: string;
13
+ readme?: string;
14
+ tech?: string;
15
+ taskCounts: Record<string, number>;
16
+ }
17
+ export declare function createProject(db: Database.Database, config: Config, slug: string, name: string, description?: string, sourcePath?: string): ProjectWithContext;
18
+ export declare function getProject(db: Database.Database, _config: Config, slug: string): ProjectWithContext | null;
19
+ export declare function listProjects(db: Database.Database, status?: string): Array<{
20
+ slug: string;
21
+ name: string;
22
+ description: string | null;
23
+ status: string;
24
+ taskCounts: Record<string, number>;
25
+ }>;
26
+ export declare function updateProject(db: Database.Database, slug: string, changes: {
27
+ name?: string;
28
+ description?: string;
29
+ status?: string;
30
+ source_path?: string;
31
+ }): boolean;
32
+ export declare function archiveProject(db: Database.Database, slug: string): boolean;
33
+ export { genId };
34
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/service/projects.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,kBAAkB,CAmBpB;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,kBAAkB,GAAG,IAAI,CAuC3B;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,KAAK,CAAC;IACP,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC,CA4BD;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACtF,OAAO,CA6BT;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED,OAAO,EAAE,KAAK,EAAE,CAAC"}
@@ -0,0 +1,99 @@
1
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { indexProject } from '../core/indexer.js';
4
+ import { scaffoldBacklog, scaffoldReadme, scaffoldRoadmap, scaffoldTech, } from '../core/templates.js';
5
+ import { genId } from './utils.js';
6
+ export function createProject(db, config, slug, name, description, sourcePath) {
7
+ const projectPath = join(config.dataPath, 'projects', slug);
8
+ mkdirSync(join(projectPath, 'docs'), { recursive: true });
9
+ writeFileSync(join(projectPath, 'README.md'), scaffoldReadme(slug, name, description));
10
+ writeFileSync(join(projectPath, 'TECH.md'), scaffoldTech(slug));
11
+ writeFileSync(join(projectPath, 'ROADMAP.md'), scaffoldRoadmap(slug));
12
+ writeFileSync(join(projectPath, 'BACKLOG.md'), scaffoldBacklog(slug));
13
+ const now = new Date().toISOString();
14
+ db.prepare('INSERT INTO projects (slug, name, description, status, path, source_path, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)').run(slug, name, description || null, 'active', projectPath, sourcePath || null, now, now);
15
+ indexProject(db, slug, projectPath);
16
+ const result = getProject(db, config, slug);
17
+ if (!result)
18
+ throw new Error(`Failed to create project '${slug}'`);
19
+ return result;
20
+ }
21
+ export function getProject(db, _config, slug) {
22
+ const project = db.prepare('SELECT * FROM projects WHERE slug = ?').get(slug);
23
+ if (!project)
24
+ return null;
25
+ let readme;
26
+ let tech;
27
+ try {
28
+ readme = readFileSync(join(project.path, 'README.md'), 'utf-8');
29
+ }
30
+ catch {
31
+ // file may not exist
32
+ }
33
+ try {
34
+ tech = readFileSync(join(project.path, 'TECH.md'), 'utf-8');
35
+ }
36
+ catch {
37
+ // file may not exist
38
+ }
39
+ const counts = db
40
+ .prepare(`SELECT status, COUNT(*) as count FROM tasks WHERE project_slug = ? GROUP BY status`)
41
+ .all(slug);
42
+ const taskCounts = {};
43
+ for (const row of counts) {
44
+ taskCounts[row.status] = row.count;
45
+ }
46
+ return { ...project, readme, tech, taskCounts };
47
+ }
48
+ export function listProjects(db, status) {
49
+ let sql = 'SELECT slug, name, description, status FROM projects';
50
+ const params = [];
51
+ if (status) {
52
+ sql += ' WHERE status = ?';
53
+ params.push(status);
54
+ }
55
+ sql += ' ORDER BY updated_at DESC';
56
+ const projects = db.prepare(sql).all(...params);
57
+ return projects.map((p) => {
58
+ const counts = db
59
+ .prepare('SELECT status, COUNT(*) as count FROM tasks WHERE project_slug = ? GROUP BY status')
60
+ .all(p.slug);
61
+ const taskCounts = {};
62
+ for (const row of counts) {
63
+ taskCounts[row.status] = row.count;
64
+ }
65
+ return { ...p, taskCounts };
66
+ });
67
+ }
68
+ export function updateProject(db, slug, changes) {
69
+ const sets = [];
70
+ const params = [];
71
+ if (changes.name !== undefined) {
72
+ sets.push('name = ?');
73
+ params.push(changes.name);
74
+ }
75
+ if (changes.description !== undefined) {
76
+ sets.push('description = ?');
77
+ params.push(changes.description);
78
+ }
79
+ if (changes.status !== undefined) {
80
+ sets.push('status = ?');
81
+ params.push(changes.status);
82
+ }
83
+ if (changes.source_path !== undefined) {
84
+ sets.push('source_path = ?');
85
+ params.push(changes.source_path);
86
+ }
87
+ if (sets.length === 0)
88
+ return false;
89
+ sets.push('updated_at = ?');
90
+ params.push(new Date().toISOString());
91
+ params.push(slug);
92
+ const result = db.prepare(`UPDATE projects SET ${sets.join(', ')} WHERE slug = ?`).run(...params);
93
+ return result.changes > 0;
94
+ }
95
+ export function archiveProject(db, slug) {
96
+ return updateProject(db, slug, { status: 'archived' });
97
+ }
98
+ export { genId };
99
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/service/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type Database from 'better-sqlite3';
2
+ export interface SearchResult {
3
+ type: 'doc' | 'task';
4
+ id: string;
5
+ title: string;
6
+ projectSlug: string;
7
+ docType?: string;
8
+ taskStatus?: string;
9
+ taskPriority?: string;
10
+ score: number;
11
+ }
12
+ export declare function search(db: Database.Database, query: string, project?: string, limit?: number): SearchResult[];
13
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/service/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,SAAK,GACT,YAAY,EAAE,CA+EhB"}