@superdoc-dev/sdk 1.0.0-alpha.3 → 1.0.0-alpha.31
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/README.md +124 -0
- package/dist/generated/client.cjs +284 -0
- package/dist/generated/client.d.ts +8167 -0
- package/dist/generated/client.d.ts.map +1 -0
- package/dist/generated/client.js +279 -0
- package/dist/generated/contract.cjs +82368 -0
- package/dist/generated/contract.d.ts +34 -0
- package/dist/generated/contract.d.ts.map +1 -0
- package/dist/generated/contract.js +82383 -0
- package/dist/helpers/format.d.ts +79 -0
- package/dist/helpers/format.d.ts.map +1 -0
- package/dist/helpers/format.js +121 -0
- package/dist/index.cjs +45 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/runtime/embedded-cli.cjs +100 -0
- package/dist/runtime/embedded-cli.d.ts +5 -0
- package/dist/runtime/embedded-cli.d.ts.map +1 -0
- package/dist/runtime/embedded-cli.js +94 -0
- package/dist/runtime/errors.cjs +22 -0
- package/dist/runtime/errors.d.ts +17 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +18 -0
- package/dist/runtime/host.cjs +352 -0
- package/dist/runtime/host.d.ts +37 -0
- package/dist/runtime/host.d.ts.map +1 -0
- package/dist/runtime/host.js +347 -0
- package/dist/runtime/process.cjs +32 -0
- package/dist/runtime/process.d.ts +16 -0
- package/dist/runtime/process.d.ts.map +1 -0
- package/dist/runtime/process.js +27 -0
- package/dist/runtime/transport-common.cjs +77 -0
- package/dist/runtime/transport-common.d.ts +49 -0
- package/dist/runtime/transport-common.d.ts.map +1 -0
- package/dist/runtime/transport-common.js +72 -0
- package/dist/skills.cjs +148 -0
- package/dist/skills.d.ts +25 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +140 -0
- package/dist/tools.cjs +307 -0
- package/dist/tools.d.ts +90 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +296 -0
- package/package.json +21 -11
- package/skills/editing-docx.md +24 -150
- package/tools/catalog.json +38846 -0
- package/tools/tool-name-map.json +179 -0
- package/tools/tools-policy.json +97 -0
- package/tools/tools.anthropic.json +17311 -0
- package/tools/tools.generic.json +37596 -0
- package/tools/tools.openai.json +17845 -0
- package/tools/tools.vercel.json +17845 -0
- package/src/__tests__/skills.test.ts +0 -166
- package/src/__tests__/tools.test.ts +0 -96
- package/src/generated/client.ts +0 -3643
- package/src/generated/contract.ts +0 -15952
- package/src/index.ts +0 -87
- package/src/runtime/__tests__/process.test.ts +0 -38
- package/src/runtime/__tests__/transport-common.test.ts +0 -174
- package/src/runtime/embedded-cli.ts +0 -109
- package/src/runtime/errors.ts +0 -30
- package/src/runtime/host.ts +0 -481
- package/src/runtime/process.ts +0 -45
- package/src/runtime/transport-common.ts +0 -169
- package/src/skills.ts +0 -195
- package/src/tools.ts +0 -701
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test';
|
|
2
|
-
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { SuperDocCliError } from '../runtime/errors';
|
|
6
|
-
import { getSkill, installSkill, listSkills } from '../skills';
|
|
7
|
-
|
|
8
|
-
describe('listSkills', () => {
|
|
9
|
-
test('returns an array of skill names', () => {
|
|
10
|
-
const skills = listSkills();
|
|
11
|
-
expect(Array.isArray(skills)).toBe(true);
|
|
12
|
-
expect(skills.length).toBeGreaterThan(0);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test('includes the editing-docx skill', () => {
|
|
16
|
-
const skills = listSkills();
|
|
17
|
-
expect(skills).toContain('editing-docx');
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('returns sorted results', () => {
|
|
21
|
-
const skills = listSkills();
|
|
22
|
-
const sorted = [...skills].sort();
|
|
23
|
-
expect(skills).toEqual(sorted);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('does not include file extensions', () => {
|
|
27
|
-
const skills = listSkills();
|
|
28
|
-
for (const name of skills) {
|
|
29
|
-
expect(name).not.toContain('.md');
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe('getSkill', () => {
|
|
35
|
-
test('returns content for a valid skill name', () => {
|
|
36
|
-
const content = getSkill('editing-docx');
|
|
37
|
-
expect(typeof content).toBe('string');
|
|
38
|
-
expect(content.length).toBeGreaterThan(0);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('throws INVALID_ARGUMENT for empty name', () => {
|
|
42
|
-
expect(() => getSkill('')).toThrow(SuperDocCliError);
|
|
43
|
-
try {
|
|
44
|
-
getSkill('');
|
|
45
|
-
} catch (error) {
|
|
46
|
-
expect((error as SuperDocCliError).code).toBe('INVALID_ARGUMENT');
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('throws INVALID_ARGUMENT for whitespace-only name', () => {
|
|
51
|
-
expect(() => getSkill(' ')).toThrow(SuperDocCliError);
|
|
52
|
-
try {
|
|
53
|
-
getSkill(' ');
|
|
54
|
-
} catch (error) {
|
|
55
|
-
expect((error as SuperDocCliError).code).toBe('INVALID_ARGUMENT');
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test('throws INVALID_ARGUMENT for names with path traversal characters', () => {
|
|
60
|
-
const maliciousNames = ['../etc/passwd', './local', 'foo/bar', 'a b c', 'skill.md'];
|
|
61
|
-
|
|
62
|
-
for (const name of maliciousNames) {
|
|
63
|
-
expect(() => getSkill(name)).toThrow(SuperDocCliError);
|
|
64
|
-
try {
|
|
65
|
-
getSkill(name);
|
|
66
|
-
} catch (error) {
|
|
67
|
-
expect((error as SuperDocCliError).code).toBe('INVALID_ARGUMENT');
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('throws SKILL_NOT_FOUND for nonexistent skill', () => {
|
|
73
|
-
expect(() => getSkill('nonexistent-skill-name-xyz')).toThrow(SuperDocCliError);
|
|
74
|
-
try {
|
|
75
|
-
getSkill('nonexistent-skill-name-xyz');
|
|
76
|
-
} catch (error) {
|
|
77
|
-
const sdError = error as SuperDocCliError;
|
|
78
|
-
expect(sdError.code).toBe('SKILL_NOT_FOUND');
|
|
79
|
-
expect((sdError.details as { available: string[] }).available).toContain('editing-docx');
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test('accepts valid skill names with hyphens and underscores', () => {
|
|
84
|
-
// These should not throw INVALID_ARGUMENT (they may throw SKILL_NOT_FOUND)
|
|
85
|
-
const validNames = ['a', 'my-skill', 'my_skill', 'Skill1', '1skill'];
|
|
86
|
-
|
|
87
|
-
for (const name of validNames) {
|
|
88
|
-
try {
|
|
89
|
-
getSkill(name);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
// SKILL_NOT_FOUND is expected; INVALID_ARGUMENT means the regex is wrong
|
|
92
|
-
expect((error as SuperDocCliError).code).not.toBe('INVALID_ARGUMENT');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('installSkill', () => {
|
|
99
|
-
test('installs bundled skill to Claude project skills directory', async () => {
|
|
100
|
-
const workdir = await mkdtemp(path.join(tmpdir(), 'superdoc-sdk-skills-project-'));
|
|
101
|
-
try {
|
|
102
|
-
const result = installSkill('editing-docx', { cwd: workdir });
|
|
103
|
-
const expectedPath = path.join(workdir, '.claude', 'skills', 'editing-docx', 'SKILL.md');
|
|
104
|
-
const content = await readFile(expectedPath, 'utf8');
|
|
105
|
-
|
|
106
|
-
expect(result.path).toBe(expectedPath);
|
|
107
|
-
expect(result.scope).toBe('project');
|
|
108
|
-
expect(result.written).toBe(true);
|
|
109
|
-
expect(result.overwritten).toBe(false);
|
|
110
|
-
expect(content).toContain('superdoc open');
|
|
111
|
-
} finally {
|
|
112
|
-
await rm(workdir, { recursive: true, force: true });
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test('installs bundled skill to Claude user skills directory', async () => {
|
|
117
|
-
const homeDir = await mkdtemp(path.join(tmpdir(), 'superdoc-sdk-skills-user-'));
|
|
118
|
-
try {
|
|
119
|
-
const result = installSkill('editing-docx', { scope: 'user', homeDir });
|
|
120
|
-
const expectedPath = path.join(homeDir, '.claude', 'skills', 'editing-docx', 'SKILL.md');
|
|
121
|
-
const content = await readFile(expectedPath, 'utf8');
|
|
122
|
-
|
|
123
|
-
expect(result.path).toBe(expectedPath);
|
|
124
|
-
expect(result.scope).toBe('user');
|
|
125
|
-
expect(result.written).toBe(true);
|
|
126
|
-
expect(result.overwritten).toBe(false);
|
|
127
|
-
expect(content).toContain('superdoc open');
|
|
128
|
-
} finally {
|
|
129
|
-
await rm(homeDir, { recursive: true, force: true });
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test('returns without writing when overwrite is false and target exists', async () => {
|
|
134
|
-
const workdir = await mkdtemp(path.join(tmpdir(), 'superdoc-sdk-skills-no-overwrite-'));
|
|
135
|
-
const skillFile = path.join(workdir, '.claude', 'skills', 'editing-docx', 'SKILL.md');
|
|
136
|
-
try {
|
|
137
|
-
await mkdir(path.dirname(skillFile), { recursive: true });
|
|
138
|
-
await writeFile(skillFile, 'custom-content', 'utf8');
|
|
139
|
-
const result = installSkill('editing-docx', { cwd: workdir, overwrite: false });
|
|
140
|
-
const content = await readFile(skillFile, 'utf8');
|
|
141
|
-
|
|
142
|
-
expect(result.written).toBe(false);
|
|
143
|
-
expect(result.overwritten).toBe(false);
|
|
144
|
-
expect(content).toBe('custom-content');
|
|
145
|
-
} finally {
|
|
146
|
-
await rm(workdir, { recursive: true, force: true });
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test('overwrites existing target by default', async () => {
|
|
151
|
-
const workdir = await mkdtemp(path.join(tmpdir(), 'superdoc-sdk-skills-overwrite-'));
|
|
152
|
-
const skillFile = path.join(workdir, '.claude', 'skills', 'editing-docx', 'SKILL.md');
|
|
153
|
-
try {
|
|
154
|
-
await mkdir(path.dirname(skillFile), { recursive: true });
|
|
155
|
-
await writeFile(skillFile, 'old-content', 'utf8');
|
|
156
|
-
const result = installSkill('editing-docx', { cwd: workdir });
|
|
157
|
-
const content = await readFile(skillFile, 'utf8');
|
|
158
|
-
|
|
159
|
-
expect(result.written).toBe(true);
|
|
160
|
-
expect(result.overwritten).toBe(true);
|
|
161
|
-
expect(content).toContain('superdoc open');
|
|
162
|
-
} finally {
|
|
163
|
-
await rm(workdir, { recursive: true, force: true });
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
});
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test';
|
|
2
|
-
import { dispatchSuperDocTool, resolveToolOperation } from '../tools';
|
|
3
|
-
import { SuperDocCliError } from '../runtime/errors';
|
|
4
|
-
|
|
5
|
-
describe('tools dispatch constraints', () => {
|
|
6
|
-
test('intent tool name resolves to doc.find operation', async () => {
|
|
7
|
-
const operationId = await resolveToolOperation('find_content');
|
|
8
|
-
expect(operationId).toBe('doc.find');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
test('enforces requiresOneOf for doc.find (type | query)', async () => {
|
|
12
|
-
const client = {
|
|
13
|
-
doc: {
|
|
14
|
-
find: async () => ({ ok: true }),
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
await dispatchSuperDocTool(client, 'find_content', {});
|
|
20
|
-
throw new Error('Expected dispatch to fail.');
|
|
21
|
-
} catch (error) {
|
|
22
|
-
expect(error).toBeInstanceOf(SuperDocCliError);
|
|
23
|
-
const cliError = error as SuperDocCliError;
|
|
24
|
-
expect(cliError.code).toBe('INVALID_ARGUMENT');
|
|
25
|
-
expect(cliError.message).toContain('One of the following arguments is required');
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test('enforces mutuallyExclusive constraints for doc.find query + flat flags', async () => {
|
|
30
|
-
let called = false;
|
|
31
|
-
const client = {
|
|
32
|
-
doc: {
|
|
33
|
-
find: async () => {
|
|
34
|
-
called = true;
|
|
35
|
-
return { ok: true };
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
await dispatchSuperDocTool(client, 'find_content', {
|
|
42
|
-
query: { select: { type: 'text', pattern: 'Wilde' } },
|
|
43
|
-
type: 'text',
|
|
44
|
-
});
|
|
45
|
-
throw new Error('Expected dispatch to fail.');
|
|
46
|
-
} catch (error) {
|
|
47
|
-
expect(error).toBeInstanceOf(SuperDocCliError);
|
|
48
|
-
const cliError = error as SuperDocCliError;
|
|
49
|
-
expect(cliError.code).toBe('INVALID_ARGUMENT');
|
|
50
|
-
expect(cliError.message).toContain('mutually exclusive');
|
|
51
|
-
expect(called).toBe(false);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test('enforces requiredWhen for doc.find text selectors', async () => {
|
|
56
|
-
const client = {
|
|
57
|
-
doc: {
|
|
58
|
-
find: async () => ({ ok: true }),
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
await dispatchSuperDocTool(client, 'find_content', {
|
|
64
|
-
type: 'text',
|
|
65
|
-
});
|
|
66
|
-
throw new Error('Expected dispatch to fail.');
|
|
67
|
-
} catch (error) {
|
|
68
|
-
expect(error).toBeInstanceOf(SuperDocCliError);
|
|
69
|
-
const cliError = error as SuperDocCliError;
|
|
70
|
-
expect(cliError.code).toBe('INVALID_ARGUMENT');
|
|
71
|
-
expect(cliError.message).toContain('required by constraints');
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test('dispatches when constraints are satisfied', async () => {
|
|
76
|
-
const client = {
|
|
77
|
-
doc: {
|
|
78
|
-
find: async (args: Record<string, unknown>) => ({
|
|
79
|
-
ok: true,
|
|
80
|
-
query: args,
|
|
81
|
-
}),
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const result = await dispatchSuperDocTool(client, 'find_content', {
|
|
86
|
-
query: {
|
|
87
|
-
select: { type: 'text', pattern: 'Wilde' },
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
expect(result).toMatchObject({
|
|
92
|
-
ok: true,
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
|