@ripla/godd-mcp 1.0.2-canary.7 → 1.0.2-canary.8
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.
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createdFileToContent, createdFileToTreeEntry } from "./created-file";
|
|
3
|
+
|
|
4
|
+
describe("created-file helpers", () => {
|
|
5
|
+
it("作成APIの戻り値からファイルツリー項目を作る", () => {
|
|
6
|
+
const entry = createdFileToTreeEntry({
|
|
7
|
+
path: "docs/project/new-note.md",
|
|
8
|
+
sha: "abc123",
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
expect(entry).toEqual({
|
|
12
|
+
name: "new-note.md",
|
|
13
|
+
path: "docs/project/new-note.md",
|
|
14
|
+
type: "file",
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it(".md 作成直後に表示できる空のファイル内容を作る", () => {
|
|
19
|
+
const content = createdFileToContent({
|
|
20
|
+
path: "docs/project/new-note.md",
|
|
21
|
+
sha: "abc123",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(content).toEqual({
|
|
25
|
+
path: "docs/project/new-note.md",
|
|
26
|
+
sha: "abc123",
|
|
27
|
+
content: "",
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FileContent, TreeEntry } from "@/types";
|
|
2
|
+
|
|
3
|
+
export type CreatedFile = {
|
|
4
|
+
path: string;
|
|
5
|
+
sha: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function createdFileToTreeEntry(file: CreatedFile): TreeEntry {
|
|
9
|
+
return {
|
|
10
|
+
name: file.path.split("/").pop() ?? file.path,
|
|
11
|
+
path: file.path,
|
|
12
|
+
type: "file",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createdFileToContent(file: CreatedFile): FileContent {
|
|
17
|
+
return {
|
|
18
|
+
path: file.path,
|
|
19
|
+
sha: file.sha,
|
|
20
|
+
content: "",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -35,6 +35,7 @@ import IssueList from "@/components/IssueList";
|
|
|
35
35
|
import type { TreeEntry, FileContent, ApiState, FileStyles } from "@/types";
|
|
36
36
|
import { getFileExt } from "@/types";
|
|
37
37
|
import { insertChildEntry, removeEntry } from "@/lib/tree-utils";
|
|
38
|
+
import { createdFileToContent, createdFileToTreeEntry } from "@/lib/created-file";
|
|
38
39
|
|
|
39
40
|
const MarkdownEditor = lazy(() => import("@/components/MarkdownEditor"));
|
|
40
41
|
const SpreadsheetEditor = lazy(() => import("@/components/SpreadsheetEditor"));
|
|
@@ -394,19 +395,36 @@ export default function MainPage() {
|
|
|
394
395
|
const handleCreateFile = useCallback(
|
|
395
396
|
async (fileName: string) => {
|
|
396
397
|
if (!dialog || dialog.type !== "create") return;
|
|
398
|
+
const unsaved = autoSave.status === "unsaved" || autoSave.status === "saving";
|
|
399
|
+
if (unsaved && !window.confirm("未保存の変更があります。ファイルを切り替えてもよろしいですか?")) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
397
402
|
const parentPath = dialog.entry.path;
|
|
398
403
|
const fullPath = `${parentPath}/${fileName}`;
|
|
399
404
|
setDialog(null);
|
|
400
405
|
try {
|
|
401
|
-
await createFileApi(fullPath);
|
|
406
|
+
const created = await createFileApi(fullPath);
|
|
402
407
|
showToast(`${fileName} を作成しました`, "success");
|
|
403
|
-
|
|
404
|
-
|
|
408
|
+
fetchAbortRef.current?.abort();
|
|
409
|
+
autoSave.reset();
|
|
410
|
+
pendingStylesRef.current = null;
|
|
411
|
+
setSelectedIssue(null);
|
|
412
|
+
setSelectedFile(created.path);
|
|
413
|
+
setActiveDir(parentPath);
|
|
414
|
+
setSearchParams({ file: created.path }, { replace: true });
|
|
415
|
+
setFileLoading(false);
|
|
416
|
+
setEditing(false);
|
|
417
|
+
setShowOriginal(false);
|
|
418
|
+
setEditedContent(null);
|
|
419
|
+
setFileContent(createdFileToContent(created));
|
|
420
|
+
setTree((prev) => insertChildEntry(prev, parentPath, createdFileToTreeEntry(created)));
|
|
421
|
+
if (treeSyncTimerRef.current) clearTimeout(treeSyncTimerRef.current);
|
|
422
|
+
treeSyncTimerRef.current = setTimeout(() => loadTree(), 1500);
|
|
405
423
|
} catch (e) {
|
|
406
424
|
showToast(`作成に失敗しました: ${getErrorMessage(e)}`, "error");
|
|
407
425
|
}
|
|
408
426
|
},
|
|
409
|
-
[dialog, showToast,
|
|
427
|
+
[dialog, showToast, autoSave, setSearchParams, loadTree],
|
|
410
428
|
);
|
|
411
429
|
|
|
412
430
|
const handleCreateFolder = useCallback(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripla/godd-mcp",
|
|
3
|
-
"version": "1.0.2-canary.
|
|
3
|
+
"version": "1.0.2-canary.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GoDD (Governance-orchestrated Driven Development) MCP Server - Encrypted prompt distribution via Model Context Protocol",
|
|
6
6
|
"main": "dist/index.js",
|