@gopherine/obsidian-mcp 0.1.1
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 +60 -0
- package/LICENSE +661 -0
- package/README.md +235 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +805 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/brainstorm.d.ts +9 -0
- package/dist/commands/brainstorm.js +37 -0
- package/dist/commands/brainstorm.js.map +1 -0
- package/dist/commands/brainstorm.test.d.ts +1 -0
- package/dist/commands/brainstorm.test.js +110 -0
- package/dist/commands/brainstorm.test.js.map +1 -0
- package/dist/commands/context.d.ts +18 -0
- package/dist/commands/context.js +88 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/context.test.d.ts +1 -0
- package/dist/commands/context.test.js +230 -0
- package/dist/commands/context.test.js.map +1 -0
- package/dist/commands/decide.d.ts +12 -0
- package/dist/commands/decide.js +40 -0
- package/dist/commands/decide.js.map +1 -0
- package/dist/commands/decide.test.d.ts +1 -0
- package/dist/commands/decide.test.js +109 -0
- package/dist/commands/decide.test.js.map +1 -0
- package/dist/commands/graph.d.ts +15 -0
- package/dist/commands/graph.js +89 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/graph.test.d.ts +1 -0
- package/dist/commands/graph.test.js +215 -0
- package/dist/commands/graph.test.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +256 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/learn.d.ts +25 -0
- package/dist/commands/learn.js +92 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/learn.test.d.ts +1 -0
- package/dist/commands/learn.test.js +241 -0
- package/dist/commands/learn.test.js.map +1 -0
- package/dist/commands/prune.d.ts +58 -0
- package/dist/commands/prune.js +246 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/read.d.ts +8 -0
- package/dist/commands/read.js +7 -0
- package/dist/commands/read.js.map +1 -0
- package/dist/commands/read.test.d.ts +1 -0
- package/dist/commands/read.test.js +48 -0
- package/dist/commands/read.test.js.map +1 -0
- package/dist/commands/resume.d.ts +20 -0
- package/dist/commands/resume.js +138 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/resume.test.d.ts +1 -0
- package/dist/commands/resume.test.js +243 -0
- package/dist/commands/resume.test.js.map +1 -0
- package/dist/commands/search.d.ts +8 -0
- package/dist/commands/search.js +25 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/search.test.d.ts +1 -0
- package/dist/commands/search.test.js +61 -0
- package/dist/commands/search.test.js.map +1 -0
- package/dist/commands/session.d.ts +22 -0
- package/dist/commands/session.js +79 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/session.test.d.ts +1 -0
- package/dist/commands/session.test.js +185 -0
- package/dist/commands/session.test.js.map +1 -0
- package/dist/commands/skill/index.d.ts +30 -0
- package/dist/commands/skill/index.js +61 -0
- package/dist/commands/skill/index.js.map +1 -0
- package/dist/commands/skill/index.test.d.ts +1 -0
- package/dist/commands/skill/index.test.js +137 -0
- package/dist/commands/skill/index.test.js.map +1 -0
- package/dist/commands/skill/install.d.ts +14 -0
- package/dist/commands/skill/install.js +107 -0
- package/dist/commands/skill/install.js.map +1 -0
- package/dist/commands/skill/install.test.d.ts +1 -0
- package/dist/commands/skill/install.test.js +225 -0
- package/dist/commands/skill/install.test.js.map +1 -0
- package/dist/commands/skill/list.d.ts +6 -0
- package/dist/commands/skill/list.js +5 -0
- package/dist/commands/skill/list.js.map +1 -0
- package/dist/commands/skill/list.test.d.ts +1 -0
- package/dist/commands/skill/list.test.js +101 -0
- package/dist/commands/skill/list.test.js.map +1 -0
- package/dist/commands/skill/schema.d.ts +27 -0
- package/dist/commands/skill/schema.js +55 -0
- package/dist/commands/skill/schema.js.map +1 -0
- package/dist/commands/skill/schema.test.d.ts +1 -0
- package/dist/commands/skill/schema.test.js +142 -0
- package/dist/commands/skill/schema.test.js.map +1 -0
- package/dist/commands/skill/validate.d.ts +10 -0
- package/dist/commands/skill/validate.js +39 -0
- package/dist/commands/skill/validate.js.map +1 -0
- package/dist/commands/skill/validate.test.d.ts +1 -0
- package/dist/commands/skill/validate.test.js +171 -0
- package/dist/commands/skill/validate.test.js.map +1 -0
- package/dist/commands/task.d.ts +34 -0
- package/dist/commands/task.js +160 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/commands/task.test.d.ts +1 -0
- package/dist/commands/task.test.js +395 -0
- package/dist/commands/task.test.js.map +1 -0
- package/dist/commands/todo.d.ts +15 -0
- package/dist/commands/todo.js +99 -0
- package/dist/commands/todo.js.map +1 -0
- package/dist/commands/todo.test.d.ts +1 -0
- package/dist/commands/todo.test.js +324 -0
- package/dist/commands/todo.test.js.map +1 -0
- package/dist/commands/write.d.ts +12 -0
- package/dist/commands/write.js +40 -0
- package/dist/commands/write.js.map +1 -0
- package/dist/commands/write.test.d.ts +1 -0
- package/dist/commands/write.test.js +79 -0
- package/dist/commands/write.test.js.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.js +48 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +147 -0
- package/dist/config.test.js.map +1 -0
- package/dist/core/executor.d.ts +11 -0
- package/dist/core/executor.js +42 -0
- package/dist/core/executor.js.map +1 -0
- package/dist/core/executor.test.d.ts +1 -0
- package/dist/core/executor.test.js +206 -0
- package/dist/core/executor.test.js.map +1 -0
- package/dist/core/middleware/error-handler.d.ts +2 -0
- package/dist/core/middleware/error-handler.js +29 -0
- package/dist/core/middleware/error-handler.js.map +1 -0
- package/dist/core/middleware/index.d.ts +2 -0
- package/dist/core/middleware/index.js +3 -0
- package/dist/core/middleware/index.js.map +1 -0
- package/dist/core/middleware/logging.d.ts +2 -0
- package/dist/core/middleware/logging.js +18 -0
- package/dist/core/middleware/logging.js.map +1 -0
- package/dist/core/registry.d.ts +12 -0
- package/dist/core/registry.js +407 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/registry.test.d.ts +1 -0
- package/dist/core/registry.test.js +162 -0
- package/dist/core/registry.test.js.map +1 -0
- package/dist/core/types.d.ts +38 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/integration/coordination.test.d.ts +1 -0
- package/dist/integration/coordination.test.js +286 -0
- package/dist/integration/coordination.test.js.map +1 -0
- package/dist/integration/project-artifacts.test.d.ts +1 -0
- package/dist/integration/project-artifacts.test.js +275 -0
- package/dist/integration/project-artifacts.test.js.map +1 -0
- package/dist/integration/registry-graph.test.d.ts +1 -0
- package/dist/integration/registry-graph.test.js +157 -0
- package/dist/integration/registry-graph.test.js.map +1 -0
- package/dist/integration/vault-lifecycle.test.d.ts +1 -0
- package/dist/integration/vault-lifecycle.test.js +183 -0
- package/dist/integration/vault-lifecycle.test.js.map +1 -0
- package/dist/lib/auto-number.d.ts +10 -0
- package/dist/lib/auto-number.js +33 -0
- package/dist/lib/auto-number.js.map +1 -0
- package/dist/lib/auto-number.test.d.ts +1 -0
- package/dist/lib/auto-number.test.js +88 -0
- package/dist/lib/auto-number.test.js.map +1 -0
- package/dist/lib/escape-regex.d.ts +4 -0
- package/dist/lib/escape-regex.js +7 -0
- package/dist/lib/escape-regex.js.map +1 -0
- package/dist/lib/escape-regex.test.d.ts +1 -0
- package/dist/lib/escape-regex.test.js +27 -0
- package/dist/lib/escape-regex.test.js.map +1 -0
- package/dist/lib/frontmatter.d.ts +34 -0
- package/dist/lib/frontmatter.js +74 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/frontmatter.test.d.ts +1 -0
- package/dist/lib/frontmatter.test.js +192 -0
- package/dist/lib/frontmatter.test.js.map +1 -0
- package/dist/lib/project-detector.d.ts +12 -0
- package/dist/lib/project-detector.js +123 -0
- package/dist/lib/project-detector.js.map +1 -0
- package/dist/lib/project-detector.test.d.ts +1 -0
- package/dist/lib/project-detector.test.js +117 -0
- package/dist/lib/project-detector.test.js.map +1 -0
- package/dist/lib/safe-external-path.d.ts +10 -0
- package/dist/lib/safe-external-path.js +46 -0
- package/dist/lib/safe-external-path.js.map +1 -0
- package/dist/lib/safe-external-path.test.d.ts +1 -0
- package/dist/lib/safe-external-path.test.js +99 -0
- package/dist/lib/safe-external-path.test.js.map +1 -0
- package/dist/lib/search-engine.d.ts +19 -0
- package/dist/lib/search-engine.js +157 -0
- package/dist/lib/search-engine.js.map +1 -0
- package/dist/lib/search-engine.test.d.ts +1 -0
- package/dist/lib/search-engine.test.js +120 -0
- package/dist/lib/search-engine.test.js.map +1 -0
- package/dist/lib/session-registry.d.ts +59 -0
- package/dist/lib/session-registry.js +230 -0
- package/dist/lib/session-registry.js.map +1 -0
- package/dist/lib/session-registry.test.d.ts +1 -0
- package/dist/lib/session-registry.test.js +199 -0
- package/dist/lib/session-registry.test.js.map +1 -0
- package/dist/lib/skill-registry.d.ts +13 -0
- package/dist/lib/skill-registry.js +76 -0
- package/dist/lib/skill-registry.js.map +1 -0
- package/dist/lib/token-estimator.d.ts +19 -0
- package/dist/lib/token-estimator.js +58 -0
- package/dist/lib/token-estimator.js.map +1 -0
- package/dist/lib/token-estimator.test.d.ts +1 -0
- package/dist/lib/token-estimator.test.js +65 -0
- package/dist/lib/token-estimator.test.js.map +1 -0
- package/dist/lib/vault-fs.d.ts +39 -0
- package/dist/lib/vault-fs.js +183 -0
- package/dist/lib/vault-fs.js.map +1 -0
- package/dist/lib/vault-fs.test.d.ts +1 -0
- package/dist/lib/vault-fs.test.js +210 -0
- package/dist/lib/vault-fs.test.js.map +1 -0
- package/dist/mcp-server.d.ts +2 -0
- package/dist/mcp-server.js +385 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/test-helpers.d.ts +20 -0
- package/dist/test-helpers.js +46 -0
- package/dist/test-helpers.js.map +1 -0
- package/dist/test-helpers.test.d.ts +1 -0
- package/dist/test-helpers.test.js +90 -0
- package/dist/test-helpers.test.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
2
|
+
import { parseFrontmatter } from "../../lib/frontmatter.js";
|
|
3
|
+
import { validateSkillFrontmatter } from "./schema.js";
|
|
4
|
+
async function fetchUrl(url) {
|
|
5
|
+
const response = await fetch(url);
|
|
6
|
+
if (!response.ok) {
|
|
7
|
+
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
8
|
+
}
|
|
9
|
+
return response.text();
|
|
10
|
+
}
|
|
11
|
+
function isUrl(source) {
|
|
12
|
+
return source.startsWith("http://") || source.startsWith("https://");
|
|
13
|
+
}
|
|
14
|
+
export async function validateSkill(options) {
|
|
15
|
+
const { skillPath } = options;
|
|
16
|
+
let content;
|
|
17
|
+
try {
|
|
18
|
+
if (isUrl(skillPath)) {
|
|
19
|
+
content = await fetchUrl(skillPath);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
content = await readFile(skillPath, "utf-8");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
return {
|
|
27
|
+
valid: false,
|
|
28
|
+
errors: [`Failed to read file: ${e.message}`],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const { data } = parseFrontmatter(content);
|
|
32
|
+
const { valid, errors } = validateSkillFrontmatter(data);
|
|
33
|
+
return {
|
|
34
|
+
valid,
|
|
35
|
+
errors,
|
|
36
|
+
frontmatter: valid ? data : undefined,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/skill/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAoB,MAAM,aAAa,CAAC;AAYzE,KAAK,UAAU,QAAQ,CAAC,GAAW;IACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,KAAK,CAAC,MAAc;IAC3B,OAAO,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAwB;IAExB,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE9B,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACrB,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,CAAC,wBAAyB,CAAW,CAAC,OAAO,EAAE,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAEzD,OAAO;QACL,KAAK;QACL,MAAM;QACN,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,IAAmC,CAAC,CAAC,CAAC,SAAS;KACrE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
|
+
import { mkdir, rm, writeFile } from "fs/promises";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { validateSkill } from "./validate.js";
|
|
6
|
+
describe("validateSkill", () => {
|
|
7
|
+
let vaultRoot;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
vaultRoot = join(homedir(), `.vault-skill-validate-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
10
|
+
await mkdir(vaultRoot, { recursive: true });
|
|
11
|
+
});
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
await rm(vaultRoot, { recursive: true, force: true });
|
|
14
|
+
});
|
|
15
|
+
describe("valid skill files", () => {
|
|
16
|
+
const cases = [
|
|
17
|
+
{
|
|
18
|
+
name: "minimal valid frontmatter",
|
|
19
|
+
content: "---\nname: my-skill\ndescription: Does something\n---\n\n# My Skill",
|
|
20
|
+
expectedName: "my-skill",
|
|
21
|
+
expectedDesc: "Does something",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "full frontmatter with all optional fields",
|
|
25
|
+
content: `---
|
|
26
|
+
name: full-skill
|
|
27
|
+
description: Full skill with all fields
|
|
28
|
+
version: "2.1.0"
|
|
29
|
+
author: test-author
|
|
30
|
+
tags:
|
|
31
|
+
- category
|
|
32
|
+
- utility
|
|
33
|
+
depends_on:
|
|
34
|
+
- base-skill
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# Full Skill
|
|
38
|
+
`,
|
|
39
|
+
expectedName: "full-skill",
|
|
40
|
+
expectedVersion: "2.1.0",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "frontmatter with body content",
|
|
44
|
+
content: "---\nname: body-skill\ndescription: Has body\n---\n\nSome body content here",
|
|
45
|
+
expectedName: "body-skill",
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
for (const { name, content, expectedName, expectedDesc, expectedVersion } of cases) {
|
|
49
|
+
it(name, async () => {
|
|
50
|
+
const skillPath = join(vaultRoot, "skill.md");
|
|
51
|
+
await writeFile(skillPath, content);
|
|
52
|
+
const result = await validateSkill({ skillPath });
|
|
53
|
+
expect(result.valid).toBe(true);
|
|
54
|
+
expect(result.errors).toEqual([]);
|
|
55
|
+
expect(result.frontmatter?.name).toBe(expectedName);
|
|
56
|
+
if (expectedDesc)
|
|
57
|
+
expect(result.frontmatter?.description).toBe(expectedDesc);
|
|
58
|
+
if (expectedVersion)
|
|
59
|
+
expect(result.frontmatter?.version).toBe(expectedVersion);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
describe("invalid skill files", () => {
|
|
64
|
+
const cases = [
|
|
65
|
+
{
|
|
66
|
+
name: "missing name field",
|
|
67
|
+
content: "---\ndescription: No name\n---\n\n# Skill",
|
|
68
|
+
expectedError: "name",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "missing description field",
|
|
72
|
+
content: "---\nname: no-desc\n---\n\n# Skill",
|
|
73
|
+
expectedError: "description",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "empty frontmatter",
|
|
77
|
+
content: "---\n---\n\n# Skill",
|
|
78
|
+
expectedErrorCount: 2,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "no frontmatter at all",
|
|
82
|
+
content: "# Just a heading\n\nNo frontmatter here",
|
|
83
|
+
expectedErrorCount: 2,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "non-string version",
|
|
87
|
+
content: "---\nname: bad-ver\ndescription: Test\nversion: 123\n---\n\n# Skill",
|
|
88
|
+
expectedError: "version",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "non-string author",
|
|
92
|
+
content: "---\nname: bad-author\ndescription: Test\nauthor: 42\n---\n\n# Skill",
|
|
93
|
+
expectedError: "author",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "non-array tags",
|
|
97
|
+
content: "---\nname: bad-tags\ndescription: Test\ntags: not-array\n---\n\n# Skill",
|
|
98
|
+
expectedError: "tags",
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "non-string array tags",
|
|
102
|
+
content: "---\nname: bad-tags2\ndescription: Test\ntags: [1, 2]\n---\n\n# Skill",
|
|
103
|
+
expectedError: "tags",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "non-array depends_on",
|
|
107
|
+
content: "---\nname: bad-deps\ndescription: Test\ndepends_on: string-val\n---\n\n# Skill",
|
|
108
|
+
expectedError: "depends_on",
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
for (const { name, content, expectedError, expectedErrorCount } of cases) {
|
|
112
|
+
it(name, async () => {
|
|
113
|
+
const skillPath = join(vaultRoot, "invalid.md");
|
|
114
|
+
await writeFile(skillPath, content);
|
|
115
|
+
const result = await validateSkill({ skillPath });
|
|
116
|
+
expect(result.valid).toBe(false);
|
|
117
|
+
if (expectedError) {
|
|
118
|
+
expect(result.errors.some((e) => e.includes(expectedError))).toBe(true);
|
|
119
|
+
}
|
|
120
|
+
if (expectedErrorCount) {
|
|
121
|
+
expect(result.errors.length).toBe(expectedErrorCount);
|
|
122
|
+
}
|
|
123
|
+
expect(result.frontmatter).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
describe("file read errors", () => {
|
|
128
|
+
it("returns error for nonexistent file", async () => {
|
|
129
|
+
const result = await validateSkill({ skillPath: "/nonexistent/path/skill.md" });
|
|
130
|
+
expect(result.valid).toBe(false);
|
|
131
|
+
expect(result.errors[0]).toContain("Failed to read file");
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe("URL sources", () => {
|
|
135
|
+
it("validates skill from URL", async () => {
|
|
136
|
+
const mockContent = "---\nname: url-skill\ndescription: From URL\n---\n\n# URL Skill";
|
|
137
|
+
vi.stubGlobal("fetch", vi.fn().mockResolvedValue({
|
|
138
|
+
ok: true,
|
|
139
|
+
text: () => Promise.resolve(mockContent),
|
|
140
|
+
}));
|
|
141
|
+
const result = await validateSkill({ skillPath: "https://example.com/skill.md" });
|
|
142
|
+
expect(result.valid).toBe(true);
|
|
143
|
+
expect(result.frontmatter?.name).toBe("url-skill");
|
|
144
|
+
vi.unstubAllGlobals();
|
|
145
|
+
});
|
|
146
|
+
it("returns error when fetch fails", async () => {
|
|
147
|
+
vi.stubGlobal("fetch", vi.fn().mockResolvedValue({
|
|
148
|
+
ok: false,
|
|
149
|
+
status: 404,
|
|
150
|
+
statusText: "Not Found",
|
|
151
|
+
}));
|
|
152
|
+
const result = await validateSkill({ skillPath: "https://example.com/missing.md" });
|
|
153
|
+
expect(result.valid).toBe(false);
|
|
154
|
+
expect(result.errors[0]).toContain("Failed to fetch");
|
|
155
|
+
vi.unstubAllGlobals();
|
|
156
|
+
});
|
|
157
|
+
it("returns error when fetch throws", async () => {
|
|
158
|
+
vi.stubGlobal("fetch", vi.fn().mockRejectedValue(new Error("Network error")));
|
|
159
|
+
const result = await validateSkill({ skillPath: "https://example.com/error.md" });
|
|
160
|
+
expect(result.valid).toBe(false);
|
|
161
|
+
expect(result.errors[0]).toContain("Failed to read file");
|
|
162
|
+
vi.unstubAllGlobals();
|
|
163
|
+
});
|
|
164
|
+
it("does not treat non-http paths as URLs", async () => {
|
|
165
|
+
const result = await validateSkill({ skillPath: "/local/path.md" });
|
|
166
|
+
expect(result.valid).toBe(false);
|
|
167
|
+
expect(result.errors[0]).toContain("Failed to read file");
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
//# sourceMappingURL=validate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.test.js","sourceRoot":"","sources":["../../../src/commands/skill/validate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CommandContext } from "../core/types.js";
|
|
2
|
+
export type TaskStatus = "backlog" | "in-progress" | "blocked" | "done" | "cancelled";
|
|
3
|
+
export type TaskPriority = "p0" | "p1" | "p2";
|
|
4
|
+
export interface TaskItem {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
status: TaskStatus;
|
|
8
|
+
priority: TaskPriority;
|
|
9
|
+
blocked_by: string[];
|
|
10
|
+
assigned_to: string;
|
|
11
|
+
sprint: string;
|
|
12
|
+
tags: string[];
|
|
13
|
+
created: string;
|
|
14
|
+
updated: string;
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function taskCommand(args: {
|
|
18
|
+
action: "add" | "list" | "update" | "board";
|
|
19
|
+
title?: string;
|
|
20
|
+
taskId?: string;
|
|
21
|
+
status?: TaskStatus;
|
|
22
|
+
priority?: TaskPriority;
|
|
23
|
+
blockedBy?: string[];
|
|
24
|
+
assignedTo?: string;
|
|
25
|
+
sprint?: string;
|
|
26
|
+
tags?: string[];
|
|
27
|
+
project?: string;
|
|
28
|
+
}, ctx: CommandContext): Promise<{
|
|
29
|
+
task_id?: string;
|
|
30
|
+
path?: string;
|
|
31
|
+
updated_fields?: string[];
|
|
32
|
+
tasks?: TaskItem[];
|
|
33
|
+
board?: Record<string, TaskItem[]>;
|
|
34
|
+
}>;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { parseFrontmatter, serializeFrontmatter, createFrontmatter, mergeFrontmatter } from "../lib/frontmatter.js";
|
|
2
|
+
import { resolveProject } from "../config.js";
|
|
3
|
+
import { getNextNumber, slugify } from "../lib/auto-number.js";
|
|
4
|
+
const VALID_TASK_STATUSES = ["backlog", "in-progress", "blocked", "done", "cancelled"];
|
|
5
|
+
const VALID_TASK_PRIORITIES = ["p0", "p1", "p2"];
|
|
6
|
+
const STATUS_COLUMNS = ["backlog", "in-progress", "blocked", "done", "cancelled"];
|
|
7
|
+
export async function taskCommand(args, ctx) {
|
|
8
|
+
const projectSlug = await resolveProject(ctx.vaultPath, args.project);
|
|
9
|
+
const vaultFs = ctx.vaultFs;
|
|
10
|
+
const tasksDir = `projects/${projectSlug}/tasks`;
|
|
11
|
+
switch (args.action) {
|
|
12
|
+
case "add": {
|
|
13
|
+
if (!args.title)
|
|
14
|
+
throw new Error("Title required for add");
|
|
15
|
+
const nextNum = await getNextNumber(vaultFs, tasksDir);
|
|
16
|
+
const padded = String(nextNum).padStart(3, "0");
|
|
17
|
+
const titleSlug = slugify(args.title);
|
|
18
|
+
const taskId = `task-${padded}`;
|
|
19
|
+
const filename = `${taskId}-${titleSlug}.md`;
|
|
20
|
+
const filePath = `${tasksDir}/${filename}`;
|
|
21
|
+
const priority = args.priority ?? "p1";
|
|
22
|
+
if (!VALID_TASK_PRIORITIES.includes(priority)) {
|
|
23
|
+
throw new Error(`Invalid priority "${priority}". Must be one of: ${VALID_TASK_PRIORITIES.join(", ")}`);
|
|
24
|
+
}
|
|
25
|
+
const fm = createFrontmatter({
|
|
26
|
+
type: "task",
|
|
27
|
+
project: projectSlug,
|
|
28
|
+
status: "backlog",
|
|
29
|
+
priority,
|
|
30
|
+
blocked_by: args.blockedBy ?? [],
|
|
31
|
+
assigned_to: args.assignedTo ?? "",
|
|
32
|
+
sprint: args.sprint ?? "",
|
|
33
|
+
tags: args.tags ?? [],
|
|
34
|
+
});
|
|
35
|
+
const body = `\n# ${args.title}\n`;
|
|
36
|
+
await vaultFs.write(filePath, serializeFrontmatter(fm, body));
|
|
37
|
+
return { task_id: taskId, path: filePath };
|
|
38
|
+
}
|
|
39
|
+
case "list": {
|
|
40
|
+
const tasks = await listTasks(vaultFs, tasksDir);
|
|
41
|
+
let filtered = tasks;
|
|
42
|
+
if (args.status) {
|
|
43
|
+
filtered = filtered.filter((t) => t.status === args.status);
|
|
44
|
+
}
|
|
45
|
+
if (args.priority) {
|
|
46
|
+
filtered = filtered.filter((t) => t.priority === args.priority);
|
|
47
|
+
}
|
|
48
|
+
if (args.assignedTo) {
|
|
49
|
+
filtered = filtered.filter((t) => t.assigned_to === args.assignedTo);
|
|
50
|
+
}
|
|
51
|
+
return { tasks: filtered };
|
|
52
|
+
}
|
|
53
|
+
case "update": {
|
|
54
|
+
if (!args.taskId)
|
|
55
|
+
throw new Error("Task ID required for update");
|
|
56
|
+
const tasks = await listTasks(vaultFs, tasksDir);
|
|
57
|
+
const task = tasks.find((t) => t.id === args.taskId);
|
|
58
|
+
if (!task)
|
|
59
|
+
throw new Error(`Task not found: ${args.taskId}`);
|
|
60
|
+
const content = await vaultFs.read(task.path);
|
|
61
|
+
const { data, content: body } = parseFrontmatter(content);
|
|
62
|
+
const updatedFields = [];
|
|
63
|
+
if (args.status) {
|
|
64
|
+
if (!VALID_TASK_STATUSES.includes(args.status)) {
|
|
65
|
+
throw new Error(`Invalid status "${args.status}". Must be one of: ${VALID_TASK_STATUSES.join(", ")}`);
|
|
66
|
+
}
|
|
67
|
+
data.status = args.status;
|
|
68
|
+
updatedFields.push("status");
|
|
69
|
+
}
|
|
70
|
+
if (args.priority) {
|
|
71
|
+
if (!VALID_TASK_PRIORITIES.includes(args.priority)) {
|
|
72
|
+
throw new Error(`Invalid priority "${args.priority}". Must be one of: ${VALID_TASK_PRIORITIES.join(", ")}`);
|
|
73
|
+
}
|
|
74
|
+
data.priority = args.priority;
|
|
75
|
+
updatedFields.push("priority");
|
|
76
|
+
}
|
|
77
|
+
if (args.blockedBy !== undefined) {
|
|
78
|
+
data.blocked_by = args.blockedBy;
|
|
79
|
+
updatedFields.push("blocked_by");
|
|
80
|
+
}
|
|
81
|
+
if (args.assignedTo !== undefined) {
|
|
82
|
+
data.assigned_to = args.assignedTo;
|
|
83
|
+
updatedFields.push("assigned_to");
|
|
84
|
+
}
|
|
85
|
+
if (args.title) {
|
|
86
|
+
const newBody = body.replace(/^# .+$/m, `# ${args.title}`);
|
|
87
|
+
const updated = mergeFrontmatter(data, {});
|
|
88
|
+
await vaultFs.write(task.path, serializeFrontmatter(updated, newBody));
|
|
89
|
+
updatedFields.push("title");
|
|
90
|
+
return { task_id: args.taskId, updated_fields: updatedFields };
|
|
91
|
+
}
|
|
92
|
+
const updated = mergeFrontmatter(data, {});
|
|
93
|
+
await vaultFs.write(task.path, serializeFrontmatter(updated, body));
|
|
94
|
+
return { task_id: args.taskId, updated_fields: updatedFields };
|
|
95
|
+
}
|
|
96
|
+
case "board": {
|
|
97
|
+
const tasks = await listTasks(vaultFs, tasksDir);
|
|
98
|
+
const board = {};
|
|
99
|
+
for (const col of STATUS_COLUMNS) {
|
|
100
|
+
board[col] = tasks.filter((t) => t.status === col);
|
|
101
|
+
}
|
|
102
|
+
return { board };
|
|
103
|
+
}
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`Unknown action: ${args.action}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function listTasks(vaultFs, tasksDir) {
|
|
109
|
+
const tasks = [];
|
|
110
|
+
let files;
|
|
111
|
+
try {
|
|
112
|
+
files = await vaultFs.list(tasksDir, 1);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
for (const file of files) {
|
|
118
|
+
if (!file.endsWith(".md"))
|
|
119
|
+
continue;
|
|
120
|
+
const filePath = file;
|
|
121
|
+
try {
|
|
122
|
+
const content = await vaultFs.read(filePath);
|
|
123
|
+
const { data, content: body } = parseFrontmatter(content);
|
|
124
|
+
if (data.type !== "task")
|
|
125
|
+
continue;
|
|
126
|
+
const basename = file.split("/").pop() ?? file;
|
|
127
|
+
const idMatch = basename.match(/^(task-\d+)/);
|
|
128
|
+
if (!idMatch)
|
|
129
|
+
continue;
|
|
130
|
+
const titleMatch = body.match(/^# (.+)$/m);
|
|
131
|
+
const title = titleMatch ? titleMatch[1].trim() : file;
|
|
132
|
+
tasks.push({
|
|
133
|
+
id: idMatch[1],
|
|
134
|
+
title,
|
|
135
|
+
status: data.status ?? "backlog",
|
|
136
|
+
priority: data.priority ?? "p1",
|
|
137
|
+
blocked_by: Array.isArray(data.blocked_by) ? data.blocked_by : [],
|
|
138
|
+
assigned_to: data.assigned_to ?? "",
|
|
139
|
+
sprint: data.sprint ?? "",
|
|
140
|
+
tags: Array.isArray(data.tags) ? data.tags : [],
|
|
141
|
+
created: data.created ?? "",
|
|
142
|
+
updated: data.updated ?? "",
|
|
143
|
+
path: filePath,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
if (e instanceof Error && "code" in e && e.code !== "ENOENT") {
|
|
148
|
+
console.error("[task] Skipping unreadable task file:", e instanceof Error ? e.message : e);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
tasks.sort((a, b) => {
|
|
153
|
+
const priOrder = VALID_TASK_PRIORITIES.indexOf(a.priority) - VALID_TASK_PRIORITIES.indexOf(b.priority);
|
|
154
|
+
if (priOrder !== 0)
|
|
155
|
+
return priOrder;
|
|
156
|
+
return a.id.localeCompare(b.id);
|
|
157
|
+
});
|
|
158
|
+
return tasks;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAmB/D,MAAM,mBAAmB,GAAiB,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AACrG,MAAM,qBAAqB,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACjE,MAAM,cAAc,GAAiB,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AAEhG,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAWC,EACD,GAAmB;IAQnB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC5B,MAAM,QAAQ,GAAG,YAAY,WAAW,QAAQ,CAAC;IAEjD,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAE3D,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAChD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,MAAM,GAAG,QAAQ,MAAM,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,SAAS,KAAK,CAAC;YAC7C,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAE3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;YACvC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,sBAAsB,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzG,CAAC;YAED,MAAM,EAAE,GAAG,iBAAiB,CAAC;gBAC3B,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,WAAW;gBACpB,MAAM,EAAE,SAAS;gBACjB,QAAQ;gBACR,UAAU,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;gBAChC,WAAW,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;gBAClC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;aACtB,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,KAAK,IAAI,CAAC;YACnC,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,oBAAoB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;YAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC7C,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjD,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClE,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;YACvE,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC7B,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAEjE,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAE7D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC1D,MAAM,aAAa,GAAa,EAAE,CAAC;YAEnC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC/C,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,MAAM,sBAAsB,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxG,CAAC;gBACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC1B,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACnD,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,QAAQ,sBAAsB,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC9G,CAAC;gBACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAC9B,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACjC,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;gBACjC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBAClC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;gBACnC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;YACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC3D,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC3C,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;gBACvE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;YACjE,CAAC;YAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3C,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAEpE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;QACjE,CAAC;QAED,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjD,MAAM,KAAK,GAA+B,EAAE,CAAC;YAE7C,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;gBACjC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC;YACrD,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,CAAC;QAED;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,OAA6C,EAAE,QAAgB;IACtF,MAAM,KAAK,GAAe,EAAE,CAAC;IAE7B,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAE1D,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;YAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAEvD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;gBACd,KAAK;gBACL,MAAM,EAAG,IAAI,CAAC,MAAqB,IAAI,SAAS;gBAChD,QAAQ,EAAG,IAAI,CAAC,QAAyB,IAAI,IAAI;gBACjD,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAsB,CAAC,CAAC,CAAC,EAAE;gBAC7E,WAAW,EAAG,IAAI,CAAC,WAAsB,IAAI,EAAE;gBAC/C,MAAM,EAAG,IAAI,CAAC,MAAiB,IAAI,EAAE;gBACrC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAgB,CAAC,CAAC,CAAC,EAAE;gBAC3D,OAAO,EAAG,IAAI,CAAC,OAAkB,IAAI,EAAE;gBACvC,OAAO,EAAG,IAAI,CAAC,OAAkB,IAAI,EAAE;gBACvC,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,KAAK,IAAI,MAAM,IAAI,CAAC,IAAK,CAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtE,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvG,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QACpC,OAAO,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|