tgo-wiki 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 (68) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +255 -0
  3. package/docs/mcp-usage.md +631 -0
  4. package/docs/v0-acceptance.md +105 -0
  5. package/docs/v0-delivery-checklist.md +57 -0
  6. package/docs/v1-acceptance.md +39 -0
  7. package/docs/v2-acceptance.md +165 -0
  8. package/package.json +69 -0
  9. package/packages/core/src/config/config-loader.ts +109 -0
  10. package/packages/core/src/config/defaults.ts +74 -0
  11. package/packages/core/src/config/workspace-resolver.ts +40 -0
  12. package/packages/core/src/documents/command-document-parser.ts +206 -0
  13. package/packages/core/src/documents/document-id.ts +26 -0
  14. package/packages/core/src/documents/document-parser-registry.ts +126 -0
  15. package/packages/core/src/documents/document-service.ts +656 -0
  16. package/packages/core/src/documents/document-store.ts +132 -0
  17. package/packages/core/src/documents/document-types.ts +33 -0
  18. package/packages/core/src/documents/pdf-text-parser.ts +35 -0
  19. package/packages/core/src/documents/text-markdown-parser.ts +50 -0
  20. package/packages/core/src/errors.ts +46 -0
  21. package/packages/core/src/git/git-service.ts +68 -0
  22. package/packages/core/src/index.ts +38 -0
  23. package/packages/core/src/markdown/markdown-scanner.ts +90 -0
  24. package/packages/core/src/permissions/permission-service.ts +50 -0
  25. package/packages/core/src/publish/publish-service.ts +142 -0
  26. package/packages/core/src/result.ts +13 -0
  27. package/packages/core/src/services/session-workflow-service.ts +493 -0
  28. package/packages/core/src/services/wiki-service.ts +119 -0
  29. package/packages/core/src/services/workspace-service.ts +223 -0
  30. package/packages/core/src/session/session-id.ts +14 -0
  31. package/packages/core/src/session/session-service.ts +77 -0
  32. package/packages/core/src/session/session-store.ts +91 -0
  33. package/packages/core/src/session/session-types.ts +17 -0
  34. package/packages/core/src/sources/source-id.ts +19 -0
  35. package/packages/core/src/sources/source-paths.ts +15 -0
  36. package/packages/core/src/sources/source-service.ts +416 -0
  37. package/packages/core/src/sources/source-types.ts +77 -0
  38. package/packages/core/src/sources/source-validator.ts +132 -0
  39. package/packages/core/src/sources/source-writer.ts +419 -0
  40. package/packages/core/src/validation/frontmatter-validator.ts +128 -0
  41. package/packages/core/src/validation/link-validator.ts +55 -0
  42. package/packages/core/src/validation/path-validator.ts +65 -0
  43. package/packages/core/src/validation/source-reference-validator.ts +191 -0
  44. package/packages/core/src/validation/validation-service.ts +106 -0
  45. package/packages/core/src/vfs/vfs-command-parser.ts +69 -0
  46. package/packages/core/src/vfs/vfs-service.ts +498 -0
  47. package/packages/core/src/web/html-to-markdown.ts +144 -0
  48. package/packages/core/src/web/static-web-fetcher.ts +537 -0
  49. package/packages/core/src/web/web-id.ts +26 -0
  50. package/packages/core/src/web/web-ingestion-service.ts +335 -0
  51. package/packages/core/src/web/web-paths.ts +6 -0
  52. package/packages/core/src/web/web-types.ts +33 -0
  53. package/packages/server/src/cli.ts +56 -0
  54. package/packages/server/src/context.ts +7 -0
  55. package/packages/server/src/index.ts +2 -0
  56. package/packages/server/src/mcp-server.ts +111 -0
  57. package/packages/server/src/schemas/documents.ts +17 -0
  58. package/packages/server/src/schemas/read.ts +16 -0
  59. package/packages/server/src/schemas/session.ts +31 -0
  60. package/packages/server/src/schemas/sources.ts +12 -0
  61. package/packages/server/src/schemas/web.ts +23 -0
  62. package/packages/server/src/tools/document-tools.ts +46 -0
  63. package/packages/server/src/tools/publish-tools.ts +33 -0
  64. package/packages/server/src/tools/read-tools.ts +52 -0
  65. package/packages/server/src/tools/response.ts +24 -0
  66. package/packages/server/src/tools/session-tools.ts +100 -0
  67. package/packages/server/src/tools/source-tools.ts +32 -0
  68. package/packages/server/src/tools/web-tools.ts +26 -0
@@ -0,0 +1,46 @@
1
+ import { assertCanUseTool, DocumentService, toWikiError } from "../../../core/src/index.js";
2
+ import type { ServerContext } from "../context.js";
3
+ import { toolError, toolSuccess } from "./response.js";
4
+
5
+ type ToolHandlerResult = {
6
+ content: { type: "text"; text: string }[];
7
+ structuredContent: Record<string, unknown>;
8
+ isError?: boolean;
9
+ };
10
+
11
+ export async function callDocumentUpload(
12
+ ctx: ServerContext,
13
+ input: { session_id: string; file_name: string; mime_type: string; content_base64: string }
14
+ ): Promise<ToolHandlerResult> {
15
+ try {
16
+ assertCanUseTool(ctx.role, "document_upload");
17
+ const result = await new DocumentService(ctx.workspaceRoot).upload({
18
+ sessionId: input.session_id,
19
+ fileName: input.file_name,
20
+ mimeType: input.mime_type,
21
+ contentBase64: input.content_base64,
22
+ createdBy: ctx.agentId
23
+ });
24
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
25
+ } catch (error) {
26
+ return toolError(toWikiError(error, "validation_failed"));
27
+ }
28
+ }
29
+
30
+ export async function callDocumentParse(
31
+ ctx: ServerContext,
32
+ input: { session_id: string; document_id: string; parser?: "auto" | string; reparse?: boolean }
33
+ ): Promise<ToolHandlerResult> {
34
+ try {
35
+ assertCanUseTool(ctx.role, "document_parse");
36
+ const result = await new DocumentService(ctx.workspaceRoot).parse({
37
+ sessionId: input.session_id,
38
+ documentId: input.document_id,
39
+ parser: input.parser,
40
+ reparse: input.reparse
41
+ });
42
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
43
+ } catch (error) {
44
+ return toolError(toWikiError(error, "validation_failed"));
45
+ }
46
+ }
@@ -0,0 +1,33 @@
1
+ import * as z from "zod/v4";
2
+ import { assertCanUseTool, PublishService, toWikiError } from "../../../core/src/index.js";
3
+ import type { ServerContext } from "../context.js";
4
+ import { toolError, toolSuccess } from "./response.js";
5
+
6
+ type ToolHandlerResult = {
7
+ content: { type: "text"; text: string }[];
8
+ structuredContent: Record<string, unknown>;
9
+ isError?: boolean;
10
+ };
11
+
12
+ export const wikiPublishSessionSchema = z.object({
13
+ session_id: z.string().regex(/^[a-zA-Z0-9._-]+$/),
14
+ channel: z.literal("stable").optional(),
15
+ mode: z.literal("ff-only").optional()
16
+ });
17
+
18
+ export async function callWikiPublishSession(
19
+ ctx: ServerContext,
20
+ input: { session_id: string; channel?: "stable"; mode?: "ff-only" }
21
+ ): Promise<ToolHandlerResult> {
22
+ try {
23
+ assertCanUseTool(ctx.role, "wiki_publish_session");
24
+ const result = await new PublishService(ctx.workspaceRoot).publish({
25
+ sessionId: input.session_id,
26
+ channel: input.channel,
27
+ mode: input.mode
28
+ });
29
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
30
+ } catch (error) {
31
+ return toolError(toWikiError(error, "git_error"));
32
+ }
33
+ }
@@ -0,0 +1,52 @@
1
+ import { assertCanUseTool, toWikiError, VfsService, WikiService } from "../../../core/src/index.js";
2
+ import type { ServerContext } from "../context.js";
3
+ import { toolError, toolSuccess } from "./response.js";
4
+
5
+ type ToolHandlerResult = {
6
+ content: { type: "text"; text: string }[];
7
+ structuredContent: Record<string, unknown>;
8
+ isError?: boolean;
9
+ };
10
+
11
+ export async function callVfsExec(
12
+ ctx: ServerContext,
13
+ input: { command: string; ref?: string }
14
+ ): Promise<ToolHandlerResult> {
15
+ try {
16
+ assertCanUseTool(ctx.role, "vfs_exec");
17
+ const result = await new VfsService(ctx.workspaceRoot).exec(input);
18
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
19
+ } catch (error) {
20
+ return toolError(toWikiError(error, "git_error"));
21
+ }
22
+ }
23
+
24
+ export async function callWikiRead(
25
+ ctx: ServerContext,
26
+ input: { path: string; ref?: string; include_frontmatter?: boolean }
27
+ ): Promise<ToolHandlerResult> {
28
+ try {
29
+ assertCanUseTool(ctx.role, "wiki_read");
30
+ const result = await new WikiService(ctx.workspaceRoot).read({
31
+ path: input.path,
32
+ ref: input.ref,
33
+ includeFrontmatter: input.include_frontmatter
34
+ });
35
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
36
+ } catch (error) {
37
+ return toolError(toWikiError(error, "git_error"));
38
+ }
39
+ }
40
+
41
+ export async function callWikiChannelStatus(
42
+ ctx: ServerContext,
43
+ input: { channel?: "stable" | string }
44
+ ): Promise<ToolHandlerResult> {
45
+ try {
46
+ assertCanUseTool(ctx.role, "wiki_channel_status");
47
+ const result = await new WikiService(ctx.workspaceRoot).channelStatus(input);
48
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
49
+ } catch (error) {
50
+ return toolError(toWikiError(error, "git_error"));
51
+ }
52
+ }
@@ -0,0 +1,24 @@
1
+ import type { WikiError } from "../../../core/src/index.js";
2
+
3
+ export function toolSuccess<T extends Record<string, unknown>>(value: T) {
4
+ return {
5
+ content: [{ type: "text" as const, text: JSON.stringify(value, null, 2) }],
6
+ structuredContent: value
7
+ };
8
+ }
9
+
10
+ export function toolError(error: WikiError) {
11
+ const value = {
12
+ error: {
13
+ code: error.code,
14
+ message: error.message,
15
+ details: error.details
16
+ }
17
+ };
18
+
19
+ return {
20
+ content: [{ type: "text" as const, text: JSON.stringify(value, null, 2) }],
21
+ structuredContent: value,
22
+ isError: true
23
+ };
24
+ }
@@ -0,0 +1,100 @@
1
+ import { assertCanUseTool, SessionWorkflowService, toWikiError } from "../../../core/src/index.js";
2
+ import type { ServerContext } from "../context.js";
3
+ import { toolError, toolSuccess } from "./response.js";
4
+
5
+ type ToolHandlerResult = {
6
+ content: { type: "text"; text: string }[];
7
+ structuredContent: Record<string, unknown>;
8
+ isError?: boolean;
9
+ };
10
+
11
+ export async function callWikiSessionStart(
12
+ ctx: ServerContext,
13
+ input: { base_ref?: string; purpose?: string; agent_id?: string }
14
+ ): Promise<ToolHandlerResult> {
15
+ try {
16
+ assertCanUseTool(ctx.role, "wiki_session_start");
17
+ const result = await new SessionWorkflowService(ctx.workspaceRoot).start({
18
+ baseRef: input.base_ref,
19
+ purpose: input.purpose,
20
+ agentId: input.agent_id ?? ctx.agentId
21
+ });
22
+ return result.ok
23
+ ? toolSuccess({
24
+ session_id: result.value.sessionId,
25
+ branch: result.value.branch,
26
+ worktree: result.value.worktree,
27
+ base_ref: result.value.baseRef,
28
+ base_commit: result.value.baseCommit
29
+ })
30
+ : toolError(result.error);
31
+ } catch (error) {
32
+ return toolError(toWikiError(error, "git_error"));
33
+ }
34
+ }
35
+
36
+ export async function callWikiSessionPatch(
37
+ ctx: ServerContext,
38
+ input: { session_id: string; path: string; content: string; reason?: string }
39
+ ): Promise<ToolHandlerResult> {
40
+ try {
41
+ assertCanUseTool(ctx.role, "wiki_session_patch");
42
+ const result = await new SessionWorkflowService(ctx.workspaceRoot).patch({
43
+ sessionId: input.session_id,
44
+ path: input.path,
45
+ content: input.content,
46
+ reason: input.reason
47
+ });
48
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
49
+ } catch (error) {
50
+ return toolError(toWikiError(error, "git_error"));
51
+ }
52
+ }
53
+
54
+ export async function callWikiSessionValidate(
55
+ ctx: ServerContext,
56
+ input: { session_id: string; paths?: string[] }
57
+ ): Promise<ToolHandlerResult> {
58
+ try {
59
+ assertCanUseTool(ctx.role, "wiki_session_validate");
60
+ const result = await new SessionWorkflowService(ctx.workspaceRoot).validate({
61
+ sessionId: input.session_id,
62
+ paths: input.paths
63
+ });
64
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
65
+ } catch (error) {
66
+ return toolError(toWikiError(error, "git_error"));
67
+ }
68
+ }
69
+
70
+ export async function callWikiSessionDiff(
71
+ ctx: ServerContext,
72
+ input: { session_id: string; paths?: string[] }
73
+ ): Promise<ToolHandlerResult> {
74
+ try {
75
+ assertCanUseTool(ctx.role, "wiki_session_diff");
76
+ const result = await new SessionWorkflowService(ctx.workspaceRoot).diff({
77
+ sessionId: input.session_id,
78
+ paths: input.paths
79
+ });
80
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
81
+ } catch (error) {
82
+ return toolError(toWikiError(error, "git_error"));
83
+ }
84
+ }
85
+
86
+ export async function callWikiSessionCommit(
87
+ ctx: ServerContext,
88
+ input: { session_id: string; message: string }
89
+ ): Promise<ToolHandlerResult> {
90
+ try {
91
+ assertCanUseTool(ctx.role, "wiki_session_commit");
92
+ const result = await new SessionWorkflowService(ctx.workspaceRoot).commit({
93
+ sessionId: input.session_id,
94
+ message: input.message
95
+ });
96
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
97
+ } catch (error) {
98
+ return toolError(toWikiError(error, "git_error"));
99
+ }
100
+ }
@@ -0,0 +1,32 @@
1
+ import { assertCanUseTool, SourceService, toWikiError } from "../../../core/src/index.js";
2
+ import type { ServerContext } from "../context.js";
3
+ import { toolError, toolSuccess } from "./response.js";
4
+
5
+ type ToolHandlerResult = {
6
+ content: { type: "text"; text: string }[];
7
+ structuredContent: Record<string, unknown>;
8
+ isError?: boolean;
9
+ };
10
+
11
+ export async function callSourceList(ctx: ServerContext, input: { ref?: string } = {}): Promise<ToolHandlerResult> {
12
+ try {
13
+ assertCanUseTool(ctx.role, "source_list");
14
+ const result = await new SourceService(ctx.workspaceRoot).list(input);
15
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
16
+ } catch (error) {
17
+ return toolError(toWikiError(error, "document_not_found"));
18
+ }
19
+ }
20
+
21
+ export async function callSourceRead(
22
+ ctx: ServerContext,
23
+ input: { document_id: string; ref?: string }
24
+ ): Promise<ToolHandlerResult> {
25
+ try {
26
+ assertCanUseTool(ctx.role, "source_read");
27
+ const result = await new SourceService(ctx.workspaceRoot).read(input);
28
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
29
+ } catch (error) {
30
+ return toolError(toWikiError(error, "document_not_found"));
31
+ }
32
+ }
@@ -0,0 +1,26 @@
1
+ import { assertCanUseTool, toWikiError, WebIngestionService } from "../../../core/src/index.js";
2
+ import type { ServerContext } from "../context.js";
3
+ import { toolError, toolSuccess } from "./response.js";
4
+
5
+ type ToolHandlerResult = {
6
+ content: { type: "text"; text: string }[];
7
+ structuredContent: Record<string, unknown>;
8
+ isError?: boolean;
9
+ };
10
+
11
+ export async function callWebFetch(
12
+ ctx: ServerContext,
13
+ input: { session_id: string; url: string }
14
+ ): Promise<ToolHandlerResult> {
15
+ try {
16
+ assertCanUseTool(ctx.role, "web_fetch");
17
+ const result = await new WebIngestionService(ctx.workspaceRoot).fetch({
18
+ sessionId: input.session_id,
19
+ url: input.url,
20
+ createdBy: ctx.agentId
21
+ });
22
+ return result.ok ? toolSuccess({ ...result.value }) : toolError(result.error);
23
+ } catch (error) {
24
+ return toolError(toWikiError(error, "validation_failed"));
25
+ }
26
+ }