@hanmariyang/drafting 1.6.3 → 1.6.5
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/api/dist/mcp.js +32 -0
- package/package.json +1 -1
- package/web/dist/assets/index-BKzYowkg.js +125 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-CS06cWP3.js +0 -125
package/api/dist/mcp.js
CHANGED
|
@@ -45,6 +45,10 @@ export function buildMcpServer() {
|
|
|
45
45
|
}, ({ projectId, type, title, parentDocumentId }) => {
|
|
46
46
|
if (!repo.getProject(projectId))
|
|
47
47
|
return fail('project not found');
|
|
48
|
+
// 문서 체인 강제: PRD 외 문서는 부모에서 파생된다 (interview → PRD → feature-spec → IA → user-flow).
|
|
49
|
+
if (type !== 'prd' && !parentDocumentId) {
|
|
50
|
+
return fail(`'${type}' 문서는 parentDocumentId 가 필요합니다 — 문서 체인(PRD → feature-spec → IA → user-flow)을 따라 이전 문서에서 파생시키세요.`);
|
|
51
|
+
}
|
|
48
52
|
if (parentDocumentId && !repo.getDocument(parentDocumentId))
|
|
49
53
|
return fail('parent document not found');
|
|
50
54
|
const d = repo.createDocument({
|
|
@@ -82,6 +86,34 @@ export function buildMcpServer() {
|
|
|
82
86
|
violations: r.violations.filter((v) => !v.waived).slice(0, 20),
|
|
83
87
|
});
|
|
84
88
|
});
|
|
89
|
+
server.tool('drafting-export-project', '프로젝트의 문서 체인 전체(PRD→파생 순서)를 하나의 마크다운 합본으로 내보내고 절대 경로를 반환한다.', { projectId: z.string() }, ({ projectId }) => {
|
|
90
|
+
const project = repo.getProject(projectId);
|
|
91
|
+
if (!project)
|
|
92
|
+
return fail('project not found');
|
|
93
|
+
const docs = repo.listDocuments(projectId);
|
|
94
|
+
if (docs.length === 0)
|
|
95
|
+
return fail('no documents');
|
|
96
|
+
// 체인 순서: 부모 없는 문서(PRD)부터 BFS
|
|
97
|
+
const byParent = new Map();
|
|
98
|
+
for (const d of docs) {
|
|
99
|
+
const k = d.parent_document_id ?? null;
|
|
100
|
+
byParent.set(k, [...(byParent.get(k) ?? []), d]);
|
|
101
|
+
}
|
|
102
|
+
const ordered = [];
|
|
103
|
+
const queue = [...(byParent.get(null) ?? [])];
|
|
104
|
+
while (queue.length) {
|
|
105
|
+
const d = queue.shift();
|
|
106
|
+
ordered.push(d);
|
|
107
|
+
queue.push(...(byParent.get(d.id) ?? []));
|
|
108
|
+
}
|
|
109
|
+
const parts = ordered.map((d) => documentToMarkdown(d.id));
|
|
110
|
+
const dir = path.join(path.dirname(config.databasePath), 'exports');
|
|
111
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
112
|
+
const slug = project.name.replace(/[^\p{L}\p{N}]+/gu, '_').replace(/^_+|_+$/g, '').slice(0, 60) || 'project';
|
|
113
|
+
const file = path.join(dir, `${slug}-set-${project.id.slice(0, 6)}.md`);
|
|
114
|
+
fs.writeFileSync(file, parts.join('\n\n---\n\n'), 'utf8');
|
|
115
|
+
return json({ path: file, documents: ordered.map((d) => `${d.type}: ${d.title}`) });
|
|
116
|
+
});
|
|
85
117
|
server.tool('drafting-export', '문서를 마크다운 파일로 내보낸다. 데이터 폴더의 exports/ 에 쓰고 절대 경로를 반환한다.', { documentId: z.string() }, ({ documentId }) => {
|
|
86
118
|
const d = repo.getDocument(documentId);
|
|
87
119
|
if (!d)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanmariyang/drafting",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.5",
|
|
4
4
|
"description": "AI Planning Workspace — self-hosted, BYOK. Draft PRDs & feature specs via staged AI interviews. Run: npx @hanmariyang/drafting serve",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/hanmariyang/drafting",
|