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.
- package/CHANGELOG.md +32 -0
- package/README.md +255 -0
- package/docs/mcp-usage.md +631 -0
- package/docs/v0-acceptance.md +105 -0
- package/docs/v0-delivery-checklist.md +57 -0
- package/docs/v1-acceptance.md +39 -0
- package/docs/v2-acceptance.md +165 -0
- package/package.json +69 -0
- package/packages/core/src/config/config-loader.ts +109 -0
- package/packages/core/src/config/defaults.ts +74 -0
- package/packages/core/src/config/workspace-resolver.ts +40 -0
- package/packages/core/src/documents/command-document-parser.ts +206 -0
- package/packages/core/src/documents/document-id.ts +26 -0
- package/packages/core/src/documents/document-parser-registry.ts +126 -0
- package/packages/core/src/documents/document-service.ts +656 -0
- package/packages/core/src/documents/document-store.ts +132 -0
- package/packages/core/src/documents/document-types.ts +33 -0
- package/packages/core/src/documents/pdf-text-parser.ts +35 -0
- package/packages/core/src/documents/text-markdown-parser.ts +50 -0
- package/packages/core/src/errors.ts +46 -0
- package/packages/core/src/git/git-service.ts +68 -0
- package/packages/core/src/index.ts +38 -0
- package/packages/core/src/markdown/markdown-scanner.ts +90 -0
- package/packages/core/src/permissions/permission-service.ts +50 -0
- package/packages/core/src/publish/publish-service.ts +142 -0
- package/packages/core/src/result.ts +13 -0
- package/packages/core/src/services/session-workflow-service.ts +493 -0
- package/packages/core/src/services/wiki-service.ts +119 -0
- package/packages/core/src/services/workspace-service.ts +223 -0
- package/packages/core/src/session/session-id.ts +14 -0
- package/packages/core/src/session/session-service.ts +77 -0
- package/packages/core/src/session/session-store.ts +91 -0
- package/packages/core/src/session/session-types.ts +17 -0
- package/packages/core/src/sources/source-id.ts +19 -0
- package/packages/core/src/sources/source-paths.ts +15 -0
- package/packages/core/src/sources/source-service.ts +416 -0
- package/packages/core/src/sources/source-types.ts +77 -0
- package/packages/core/src/sources/source-validator.ts +132 -0
- package/packages/core/src/sources/source-writer.ts +419 -0
- package/packages/core/src/validation/frontmatter-validator.ts +128 -0
- package/packages/core/src/validation/link-validator.ts +55 -0
- package/packages/core/src/validation/path-validator.ts +65 -0
- package/packages/core/src/validation/source-reference-validator.ts +191 -0
- package/packages/core/src/validation/validation-service.ts +106 -0
- package/packages/core/src/vfs/vfs-command-parser.ts +69 -0
- package/packages/core/src/vfs/vfs-service.ts +498 -0
- package/packages/core/src/web/html-to-markdown.ts +144 -0
- package/packages/core/src/web/static-web-fetcher.ts +537 -0
- package/packages/core/src/web/web-id.ts +26 -0
- package/packages/core/src/web/web-ingestion-service.ts +335 -0
- package/packages/core/src/web/web-paths.ts +6 -0
- package/packages/core/src/web/web-types.ts +33 -0
- package/packages/server/src/cli.ts +56 -0
- package/packages/server/src/context.ts +7 -0
- package/packages/server/src/index.ts +2 -0
- package/packages/server/src/mcp-server.ts +111 -0
- package/packages/server/src/schemas/documents.ts +17 -0
- package/packages/server/src/schemas/read.ts +16 -0
- package/packages/server/src/schemas/session.ts +31 -0
- package/packages/server/src/schemas/sources.ts +12 -0
- package/packages/server/src/schemas/web.ts +23 -0
- package/packages/server/src/tools/document-tools.ts +46 -0
- package/packages/server/src/tools/publish-tools.ts +33 -0
- package/packages/server/src/tools/read-tools.ts +52 -0
- package/packages/server/src/tools/response.ts +24 -0
- package/packages/server/src/tools/session-tools.ts +100 -0
- package/packages/server/src/tools/source-tools.ts +32 -0
- 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
|
+
}
|