harness-alchemist 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/.claude-plugin/plugin.json +14 -0
- package/.codex-plugin/plugin.json +13 -0
- package/LICENSE +21 -0
- package/README.md +140 -0
- package/bin/harness-alchemist.mjs +43 -0
- package/cordis.patch.yml +3 -0
- package/dist/deepseek.d.ts +4 -0
- package/dist/deepseek.d.ts.map +1 -0
- package/dist/deepseek.js +5 -0
- package/dist/deepseek.js.map +1 -0
- package/dist/opencode.d.ts +3 -0
- package/dist/opencode.d.ts.map +1 -0
- package/dist/opencode.js +5 -0
- package/dist/opencode.js.map +1 -0
- package/lib/create.mjs +319 -0
- package/lib/validate.mjs +433 -0
- package/package.json +86 -0
- package/plugin.json +5 -0
- package/skills/harness-alchemist/SKILL.md +58 -0
- package/skills/harness-alchemist/references/antigravity.md +37 -0
- package/skills/harness-alchemist/references/claude-code.md +51 -0
- package/skills/harness-alchemist/references/codex.md +37 -0
- package/skills/harness-alchemist/references/compatibility.md +53 -0
- package/skills/harness-alchemist/references/deepseek-harness.md +56 -0
- package/skills/harness-alchemist/references/opencode.md +51 -0
- package/skills/harness-alchemist/references/publishing.md +66 -0
- package/templates/README.md +9 -0
- package/templates/v0.1.0/licenses/Apache-2.0.txt +201 -0
- package/templates/v0.1.0/template.json +13 -0
- package/templates/v0.1.0/universal-typescript/.agents/plugins/marketplace.json.tpl +20 -0
- package/templates/v0.1.0/universal-typescript/.agents/skills/develop-template/SKILL.md.tpl +33 -0
- package/templates/v0.1.0/universal-typescript/.agents/skills/develop-template/references/compatibility.md.tpl +23 -0
- package/templates/v0.1.0/universal-typescript/.agents/skills/develop-template/scripts/check-package.mjs.tpl +69 -0
- package/templates/v0.1.0/universal-typescript/.agents/skills/develop-template/scripts/sync-metadata.mjs.tpl +124 -0
- package/templates/v0.1.0/universal-typescript/.claude-plugin/marketplace.json.tpl +19 -0
- package/templates/v0.1.0/universal-typescript/.claude-plugin/plugin.json.tpl +14 -0
- package/templates/v0.1.0/universal-typescript/.codex-plugin/plugin.json.tpl +13 -0
- package/templates/v0.1.0/universal-typescript/.github/workflows/npm-publish.yml.tpl +43 -0
- package/templates/v0.1.0/universal-typescript/.gitignore.tpl +9 -0
- package/templates/v0.1.0/universal-typescript/AGENTS.md.tpl +16 -0
- package/templates/v0.1.0/universal-typescript/README.md.tpl +131 -0
- package/templates/v0.1.0/universal-typescript/cordis.patch.yml.tpl +3 -0
- package/templates/v0.1.0/universal-typescript/package.json.tpl +70 -0
- package/templates/v0.1.0/universal-typescript/plugin.json.tpl +5 -0
- package/templates/v0.1.0/universal-typescript/skills/shared-skill/SKILL.md.tpl +18 -0
- package/templates/v0.1.0/universal-typescript/src/deepseek.ts.tpl +7 -0
- package/templates/v0.1.0/universal-typescript/src/opencode.ts.tpl +7 -0
- package/templates/v0.1.0/universal-typescript/tests/runtimes.test.mjs.tpl +15 -0
- package/templates/v0.1.0/universal-typescript/tsconfig.json.tpl +17 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync } from "node:fs"
|
|
4
|
+
import { readFile, writeFile } from "node:fs/promises"
|
|
5
|
+
import { dirname, join, resolve } from "node:path"
|
|
6
|
+
import { fileURLToPath } from "node:url"
|
|
7
|
+
|
|
8
|
+
function findRoot(start) {
|
|
9
|
+
let current = resolve(start)
|
|
10
|
+
while (true) {
|
|
11
|
+
if (existsSync(join(current, "package.json")) && existsSync(join(current, ".claude-plugin"))) {
|
|
12
|
+
return current
|
|
13
|
+
}
|
|
14
|
+
const parent = dirname(current)
|
|
15
|
+
if (parent === current) return undefined
|
|
16
|
+
current = parent
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function readJson(path) {
|
|
21
|
+
return JSON.parse(await readFile(path, "utf8"))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function writeJson(path, value) {
|
|
25
|
+
await writeFile(path, `${JSON.stringify(value, null, 2)}\n`)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function authorObject(author, repository) {
|
|
29
|
+
if (typeof author === "string") return { name: author }
|
|
30
|
+
if (author && typeof author === "object") return author
|
|
31
|
+
return { name: "Plugin contributors", url: repository }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const scriptDirectory = dirname(fileURLToPath(import.meta.url))
|
|
35
|
+
const root = findRoot(process.cwd()) ?? findRoot(scriptDirectory)
|
|
36
|
+
if (!root) throw new Error("Could not find the plugin project root")
|
|
37
|
+
const packagePath = join(root, "package.json")
|
|
38
|
+
const packageJson = await readJson(packagePath)
|
|
39
|
+
const pluginName = packageJson.name?.split("/").at(-1)
|
|
40
|
+
|
|
41
|
+
if (!pluginName || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(pluginName)) {
|
|
42
|
+
throw new Error("package.json name must have a lowercase kebab-case basename")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const repository = typeof packageJson.repository === "string"
|
|
46
|
+
? packageJson.repository
|
|
47
|
+
: packageJson.repository?.url
|
|
48
|
+
const author = authorObject(packageJson.author, repository)
|
|
49
|
+
|
|
50
|
+
if (!packageJson.version || !packageJson.description || !repository || !packageJson.license) {
|
|
51
|
+
throw new Error("package.json requires version, description, repository, and license")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const claudePath = join(root, ".claude-plugin/plugin.json")
|
|
55
|
+
const claude = await readJson(claudePath)
|
|
56
|
+
Object.assign(claude, {
|
|
57
|
+
name: pluginName,
|
|
58
|
+
version: packageJson.version,
|
|
59
|
+
description: packageJson.description,
|
|
60
|
+
author,
|
|
61
|
+
homepage: repository,
|
|
62
|
+
repository,
|
|
63
|
+
license: packageJson.license,
|
|
64
|
+
})
|
|
65
|
+
await writeJson(claudePath, claude)
|
|
66
|
+
|
|
67
|
+
const codexPath = join(root, ".codex-plugin/plugin.json")
|
|
68
|
+
const codex = await readJson(codexPath)
|
|
69
|
+
Object.assign(codex, {
|
|
70
|
+
name: pluginName,
|
|
71
|
+
version: packageJson.version,
|
|
72
|
+
description: packageJson.description,
|
|
73
|
+
author: { ...author, url: author.url ?? repository },
|
|
74
|
+
homepage: repository,
|
|
75
|
+
repository,
|
|
76
|
+
license: packageJson.license,
|
|
77
|
+
})
|
|
78
|
+
await writeJson(codexPath, codex)
|
|
79
|
+
|
|
80
|
+
const antigravityPath = join(root, "plugin.json")
|
|
81
|
+
const antigravity = await readJson(antigravityPath)
|
|
82
|
+
Object.assign(antigravity, { name: pluginName, description: packageJson.description })
|
|
83
|
+
await writeJson(antigravityPath, antigravity)
|
|
84
|
+
|
|
85
|
+
const claudeMarketplacePath = join(root, ".claude-plugin/marketplace.json")
|
|
86
|
+
const claudeMarketplace = await readJson(claudeMarketplacePath)
|
|
87
|
+
claudeMarketplace.owner = author
|
|
88
|
+
const claudeEntry = claudeMarketplace.plugins?.find((entry) => entry.name === pluginName)
|
|
89
|
+
if (!claudeEntry) throw new Error("Claude marketplace does not contain the package plugin")
|
|
90
|
+
Object.assign(claudeEntry, { description: packageJson.description, author })
|
|
91
|
+
await writeJson(claudeMarketplacePath, claudeMarketplace)
|
|
92
|
+
|
|
93
|
+
const codexMarketplacePath = join(root, ".agents/plugins/marketplace.json")
|
|
94
|
+
const codexMarketplace = await readJson(codexMarketplacePath)
|
|
95
|
+
const codexEntry = codexMarketplace.plugins?.find((entry) => entry.name === pluginName)
|
|
96
|
+
if (!codexEntry) throw new Error("Codex marketplace does not contain the package plugin")
|
|
97
|
+
await writeJson(codexMarketplacePath, codexMarketplace)
|
|
98
|
+
|
|
99
|
+
const cordisPath = join(root, "cordis.patch.yml")
|
|
100
|
+
const cordisLines = (await readFile(cordisPath, "utf8")).split("\n")
|
|
101
|
+
let updatedCordisEntry = false
|
|
102
|
+
|
|
103
|
+
for (let index = 0; index < cordisLines.length; index += 1) {
|
|
104
|
+
const idMatch = cordisLines[index].match(/^(\s*)-\s+id:\s*['\"]?([^'\"\s]+)['\"]?\s*$/)
|
|
105
|
+
if (!idMatch || idMatch[2] !== pluginName) continue
|
|
106
|
+
|
|
107
|
+
const idIndent = idMatch[1].length
|
|
108
|
+
for (let next = index + 1; next < cordisLines.length; next += 1) {
|
|
109
|
+
const line = cordisLines[next]
|
|
110
|
+
if (line.trim() && line.search(/\S/) <= idIndent) break
|
|
111
|
+
const nameMatch = line.match(/^(\s*)name:\s*.+$/)
|
|
112
|
+
if (nameMatch) {
|
|
113
|
+
cordisLines[next] = `${nameMatch[1]}name: '${packageJson.name}/deepseek'`
|
|
114
|
+
updatedCordisEntry = true
|
|
115
|
+
break
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!updatedCordisEntry) throw new Error(`Could not find Cordis entry '${pluginName}' to update`)
|
|
122
|
+
await writeFile(cordisPath, cordisLines.join("\n"))
|
|
123
|
+
|
|
124
|
+
console.log(`Synchronized plugin manifests from ${packagePath}`)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
+
"name": {{MARKETPLACE_JSON}},
|
|
4
|
+
"description": "Plugin marketplace for {{DISPLAY_NAME}}.",
|
|
5
|
+
"owner": {
|
|
6
|
+
"name": {{AUTHOR_JSON}}
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": {{NAME_JSON}},
|
|
11
|
+
"displayName": {{DISPLAY_NAME_JSON}},
|
|
12
|
+
"description": {{DESCRIPTION_JSON}},
|
|
13
|
+
"author": {
|
|
14
|
+
"name": {{AUTHOR_JSON}}
|
|
15
|
+
},
|
|
16
|
+
"source": "./"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
|
+
"name": {{NAME_JSON}},
|
|
4
|
+
"displayName": {{DISPLAY_NAME_JSON}},
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": {{DESCRIPTION_JSON}},
|
|
7
|
+
"author": {
|
|
8
|
+
"name": {{AUTHOR_JSON}}
|
|
9
|
+
},
|
|
10
|
+
"homepage": {{REPOSITORY_URL_JSON}},
|
|
11
|
+
"repository": {{REPOSITORY_URL_JSON}},
|
|
12
|
+
"license": {{LICENSE_JSON}},
|
|
13
|
+
"skills": "./skills/"
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": {{NAME_JSON}},
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": {{DESCRIPTION_JSON}},
|
|
5
|
+
"author": {
|
|
6
|
+
"name": {{AUTHOR_JSON}},
|
|
7
|
+
"url": {{REPOSITORY_URL_JSON}}
|
|
8
|
+
},
|
|
9
|
+
"homepage": {{REPOSITORY_URL_JSON}},
|
|
10
|
+
"repository": {{REPOSITORY_URL_JSON}},
|
|
11
|
+
"license": {{LICENSE_JSON}},
|
|
12
|
+
"skills": "./skills/"
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Publish npm package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v5
|
|
16
|
+
- uses: actions/setup-node@v5
|
|
17
|
+
with:
|
|
18
|
+
node-version: 22.20.0
|
|
19
|
+
registry-url: https://registry.npmjs.org
|
|
20
|
+
|
|
21
|
+
- name: Resolve release version
|
|
22
|
+
id: version
|
|
23
|
+
shell: bash
|
|
24
|
+
run: |
|
|
25
|
+
TAG="${{ github.event.release.tag_name }}"
|
|
26
|
+
VERSION="${TAG#v}"
|
|
27
|
+
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
|
|
28
|
+
echo "::error::Tag '$TAG' is not a valid semver version"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
32
|
+
|
|
33
|
+
- run: npm ci
|
|
34
|
+
- name: Set package version from tag
|
|
35
|
+
run: npm version "${{ steps.version.outputs.version }}" --no-git-tag-version --allow-same-version
|
|
36
|
+
- run: npm run sync
|
|
37
|
+
- run: npm run verify
|
|
38
|
+
- name: Verify npm package contents
|
|
39
|
+
run: npm pack --dry-run
|
|
40
|
+
- name: Publish npm package
|
|
41
|
+
run: npm publish --provenance --access public
|
|
42
|
+
env:
|
|
43
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Repository Guidance
|
|
2
|
+
|
|
3
|
+
This generated repository packages one shared Agent Skill with separate runtime
|
|
4
|
+
entrypoints for several coding-agent harnesses.
|
|
5
|
+
|
|
6
|
+
- `skills/{{NAME}}/SKILL.md` is the plugin's end-user workflow; keep its
|
|
7
|
+
instructions portable and domain-specific.
|
|
8
|
+
- `.agents/skills/develop-{{NAME}}/` is the project-maintenance workflow. Read
|
|
9
|
+
it before changing manifests, metadata, or runtime entrypoints.
|
|
10
|
+
- Keep OpenCode behavior in `src/opencode.ts`; keep Cordis behavior in
|
|
11
|
+
`src/deepseek.ts` with named exports and no default export.
|
|
12
|
+
- Treat `package.json` as canonical metadata and run `npm run sync` after
|
|
13
|
+
metadata changes.
|
|
14
|
+
- Keep manifest paths inside the repository. Do not add invented connector IDs,
|
|
15
|
+
credentials, legal URLs, or presentation assets.
|
|
16
|
+
- Run `npm run verify` before reporting a change complete.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# {{DISPLAY_NAME}}
|
|
2
|
+
|
|
3
|
+
{{DESCRIPTION}}
|
|
4
|
+
|
|
5
|
+
This repository packages one shared Agent Skill and separate runtime entrypoints for Claude Code, Codex/ChatGPT, OpenCode, Google Antigravity, and DeepSeek Harness/Cordis.
|
|
6
|
+
|
|
7
|
+
## Structure
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
.claude-plugin/ Claude plugin and marketplace manifests
|
|
11
|
+
.codex-plugin/ Codex/ChatGPT plugin manifest
|
|
12
|
+
.agents/plugins/ Codex repository marketplace
|
|
13
|
+
.agents/skills/ Project development skill
|
|
14
|
+
.github/workflows/ GitHub release publishing
|
|
15
|
+
skills/ Shared installable Agent Skills
|
|
16
|
+
src/opencode.ts OpenCode npm plugin entrypoint
|
|
17
|
+
src/deepseek.ts Cordis plugin entrypoint
|
|
18
|
+
cordis.patch.yml DeepSeek Harness bundle layer
|
|
19
|
+
plugin.json Antigravity plugin manifest
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The initial runtime entrypoints are intentionally inert. Add only the hooks, tools, or services the plugin actually needs.
|
|
23
|
+
|
|
24
|
+
## Skill Boundaries
|
|
25
|
+
|
|
26
|
+
`skills/{{NAME}}/SKILL.md` is the plugin's shared end-user workflow. Replace
|
|
27
|
+
its starter procedure with the plugin's domain-specific behavior.
|
|
28
|
+
|
|
29
|
+
`.agents/skills/develop-{{NAME}}/` is this repository's maintenance skill. It
|
|
30
|
+
identifies where shared skills, manifests, runtime code, and metadata belong;
|
|
31
|
+
load it before changing those surfaces.
|
|
32
|
+
|
|
33
|
+
## Development
|
|
34
|
+
|
|
35
|
+
Requires Node.js 22.20 or newer.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install
|
|
39
|
+
npm run verify
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
After changing the version, description, author, repository, or license in `package.json`, synchronize the harness manifests:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm run sync
|
|
46
|
+
npm run verify
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Inspect the npm payload before publishing:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm pack --dry-run
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## GitHub Release Publishing
|
|
56
|
+
|
|
57
|
+
`.github/workflows/npm-publish.yml` publishes when a GitHub release is
|
|
58
|
+
published. Tag the release as `vX.Y.Z` (or a semver prerelease such as
|
|
59
|
+
`vX.Y.Z-rc.1`); the workflow applies that version, synchronizes manifests,
|
|
60
|
+
verifies the package, and publishes with npm provenance.
|
|
61
|
+
|
|
62
|
+
Configure the repository `NPM_TOKEN` secret with an npm publish token before
|
|
63
|
+
creating a release.
|
|
64
|
+
|
|
65
|
+
## Claude Code
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
claude plugin marketplace add {{REPOSITORY_SOURCE}}
|
|
69
|
+
claude plugin install {{NAME}}@{{MARKETPLACE}}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For local development:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
claude --plugin-dir .
|
|
76
|
+
claude plugin validate . --strict
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Codex and ChatGPT
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
codex plugin marketplace add {{REPOSITORY_SOURCE}}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Open `/plugins`, install **{{DISPLAY_NAME}}**, and start a new session.
|
|
86
|
+
|
|
87
|
+
## OpenCode
|
|
88
|
+
|
|
89
|
+
After publishing `{{PACKAGE_NAME}}`, add it to `opencode.json`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"$schema": "https://opencode.ai/config.json",
|
|
94
|
+
"plugin": [{{PACKAGE_NAME_JSON}}]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Install the shared skill separately:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx skills add {{REPOSITORY_SOURCE}} --agent opencode
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Google Antigravity
|
|
105
|
+
|
|
106
|
+
Clone the repository and install its root as a plugin:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
agy plugin install /absolute/path/to/{{NAME}}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Antigravity also discovers repository-local development skills from `.agents/skills/`.
|
|
113
|
+
|
|
114
|
+
## DeepSeek Harness
|
|
115
|
+
|
|
116
|
+
After publishing the npm package:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
dsh plugin --profile demo add {{PACKAGE_NAME}}
|
|
120
|
+
dsh --profile demo --dump-config
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The bundle loads `{{PACKAGE_NAME}}/deepseek`. Install the shared Agent Skill separately when the workflow needs it:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx skills add {{REPOSITORY_SOURCE}}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
{{LICENSE}}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": {{PACKAGE_NAME_JSON}},
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": {{DESCRIPTION_JSON}},
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/opencode.js",
|
|
7
|
+
"types": "./dist/opencode.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/opencode.d.ts",
|
|
11
|
+
"import": "./dist/opencode.js"
|
|
12
|
+
},
|
|
13
|
+
"./deepseek": {
|
|
14
|
+
"types": "./dist/deepseek.d.ts",
|
|
15
|
+
"import": "./dist/deepseek.js"
|
|
16
|
+
},
|
|
17
|
+
"./cordis.patch.yml": "./cordis.patch.yml"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"skills",
|
|
22
|
+
"cordis.patch.yml",
|
|
23
|
+
".claude-plugin/plugin.json",
|
|
24
|
+
".codex-plugin/plugin.json",
|
|
25
|
+
"plugin.json",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc -p tsconfig.json",
|
|
31
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
32
|
+
"test": "npm run build && node --test tests/*.test.mjs",
|
|
33
|
+
"sync": "node .agents/skills/develop-{{NAME}}/scripts/sync-metadata.mjs",
|
|
34
|
+
"validate": "node .agents/skills/develop-{{NAME}}/scripts/validate.mjs",
|
|
35
|
+
"pack:check": "node .agents/skills/develop-{{NAME}}/scripts/check-package.mjs",
|
|
36
|
+
"verify": "npm run check && npm test && npm run validate && npm run pack:check",
|
|
37
|
+
"prepack": "npm run verify"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.20.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
44
|
+
"@opencode-ai/plugin": "^1.18.21"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"@deepseek-ai/cordis": {
|
|
48
|
+
"optional": true
|
|
49
|
+
},
|
|
50
|
+
"@opencode-ai/plugin": {
|
|
51
|
+
"optional": true
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
56
|
+
"@opencode-ai/plugin": "^1.18.21",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
},
|
|
59
|
+
"author": {{AUTHOR_JSON}},
|
|
60
|
+
"license": {{LICENSE_JSON}},
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": {{REPOSITORY_URL_JSON}}
|
|
64
|
+
},
|
|
65
|
+
"dsh": {
|
|
66
|
+
"bundle": {
|
|
67
|
+
"patch": "./cordis.patch.yml"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{NAME}}
|
|
3
|
+
description: {{SHARED_SKILL_DESCRIPTION_JSON}}
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# {{DISPLAY_NAME}}
|
|
7
|
+
|
|
8
|
+
Apply the {{DISPLAY_NAME}} workflow to the user's request.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Confirm the requested outcome and inspect the relevant project context.
|
|
13
|
+
2. Perform the smallest complete change that satisfies the request.
|
|
14
|
+
3. Use harness-provided tools only when they are needed for the workflow.
|
|
15
|
+
4. Verify the result with the project's available checks.
|
|
16
|
+
5. Report the outcome and any unresolved external dependency.
|
|
17
|
+
|
|
18
|
+
Replace this starter workflow with the plugin's domain-specific procedure as the capability develops.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import assert from "node:assert/strict"
|
|
2
|
+
import test from "node:test"
|
|
3
|
+
|
|
4
|
+
import opencodePlugin from "../dist/opencode.js"
|
|
5
|
+
import * as deepseekPlugin from "../dist/deepseek.js"
|
|
6
|
+
|
|
7
|
+
test("OpenCode entrypoint returns an inert hooks object", async () => {
|
|
8
|
+
assert.deepEqual(await opencodePlugin({}), {})
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
test("DeepSeek entrypoint exposes a Cordis namespace plugin", () => {
|
|
12
|
+
assert.equal(deepseekPlugin.name, {{NAME_JSON}})
|
|
13
|
+
assert.equal(typeof deepseekPlugin.apply, "function")
|
|
14
|
+
assert.equal("default" in deepseekPlugin, false)
|
|
15
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"declarationMap": true,
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"verbatimModuleSyntax": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"noUncheckedIndexedAccess": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*.ts"]
|
|
17
|
+
}
|