harness-alchemist 0.1.6 → 0.1.7
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 +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/lib/validate.mjs +21 -7
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "harness-alchemist",
|
|
4
4
|
"displayName": "Harness Alchemist",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.7",
|
|
6
6
|
"description": "Scaffold, validate, and publish portable coding-agent plugins across Claude Code, Codex, OpenCode, Antigravity, and DeepSeek Harness.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Haochuan Zhang"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harness-alchemist",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Scaffold, validate, and publish portable coding-agent plugins across Claude Code, Codex, OpenCode, Antigravity, and DeepSeek Harness.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Haochuan Zhang",
|
package/lib/validate.mjs
CHANGED
|
@@ -9,7 +9,6 @@ import { spawnSync } from "node:child_process"
|
|
|
9
9
|
const PROJECT_REQUIRED_FILES = [
|
|
10
10
|
".agents/plugins/marketplace.json",
|
|
11
11
|
".claude-plugin/marketplace.json",
|
|
12
|
-
".github/workflows/npm-publish.yml",
|
|
13
12
|
".gitignore",
|
|
14
13
|
"AGENTS.md",
|
|
15
14
|
"LICENSE",
|
|
@@ -263,7 +262,7 @@ except SystemExit as exit_code:
|
|
|
263
262
|
_buffer.getvalue()
|
|
264
263
|
`
|
|
265
264
|
|
|
266
|
-
async function smokePythonScripts(scripts, errors, warnings) {
|
|
265
|
+
async function smokePythonScripts(scripts, errors, warnings, execSmoke = true) {
|
|
267
266
|
let loadPyodide
|
|
268
267
|
try {
|
|
269
268
|
;({ loadPyodide } = await import("pyodide"))
|
|
@@ -280,17 +279,26 @@ async function smokePythonScripts(scripts, errors, warnings) {
|
|
|
280
279
|
return
|
|
281
280
|
}
|
|
282
281
|
|
|
282
|
+
if (!execSmoke) {
|
|
283
|
+
warnings.push("skills runtime: Python entrypoints are syntax-checked without execution")
|
|
284
|
+
}
|
|
285
|
+
|
|
283
286
|
for (const script of scripts) {
|
|
284
287
|
const source = await readFile(script, "utf8")
|
|
285
288
|
instance.globals.set("__ha_source__", source)
|
|
286
|
-
instance.globals.set("__ha_payload__", "{}")
|
|
287
289
|
let output
|
|
288
290
|
try {
|
|
289
|
-
|
|
291
|
+
if (execSmoke) {
|
|
292
|
+
instance.globals.set("__ha_payload__", "{}")
|
|
293
|
+
output = instance.runPython(PYTHON_SMOKE_PROGRAM)
|
|
294
|
+
} else {
|
|
295
|
+
instance.runPython('compile(__ha_source__, "<skill>", "exec")\nNone')
|
|
296
|
+
}
|
|
290
297
|
} catch (error) {
|
|
291
298
|
errors.push(`${script}: WebAssembly Python check failed (${String(error).split("\n").at(-2) ?? String(error)})`)
|
|
292
299
|
continue
|
|
293
300
|
}
|
|
301
|
+
if (!execSmoke) continue
|
|
294
302
|
try {
|
|
295
303
|
const parsed = JSON.parse(output)
|
|
296
304
|
if (parsed?.ok !== true || typeof parsed.plugin !== "string") {
|
|
@@ -301,8 +309,13 @@ async function smokePythonScripts(scripts, errors, warnings) {
|
|
|
301
309
|
}
|
|
302
310
|
}
|
|
303
311
|
|
|
304
|
-
|
|
305
|
-
|
|
312
|
+
for (const key of ["__ha_source__", "__ha_payload__"]) {
|
|
313
|
+
try {
|
|
314
|
+
instance.globals.delete(key)
|
|
315
|
+
} catch {
|
|
316
|
+
// Key was never set in this session.
|
|
317
|
+
}
|
|
318
|
+
}
|
|
306
319
|
}
|
|
307
320
|
|
|
308
321
|
async function checkProductSkillRuntime(skillFile, content, frontmatter, errors, pythonScripts, runtime) {
|
|
@@ -434,6 +447,7 @@ export async function validateProject(projectRoot, options = {}) {
|
|
|
434
447
|
if (errors.length > 0) return { root, errors, warnings }
|
|
435
448
|
|
|
436
449
|
for (const file of PROJECT_REQUIRED_FILES) requirePath(root, file, errors)
|
|
450
|
+
if (runtime === "npm") requirePath(root, ".github/workflows/npm-publish.yml", errors)
|
|
437
451
|
const pluginRequiredFiles = runtime === "npm"
|
|
438
452
|
? [...PLUGIN_REQUIRED_FILES, ...NPM_PLUGIN_REQUIRED_FILES]
|
|
439
453
|
: PLUGIN_REQUIRED_FILES
|
|
@@ -605,7 +619,7 @@ export async function validateProject(projectRoot, options = {}) {
|
|
|
605
619
|
}
|
|
606
620
|
|
|
607
621
|
if (pythonScripts.size > 0) {
|
|
608
|
-
await smokePythonScripts([...pythonScripts], errors, warnings)
|
|
622
|
+
await smokePythonScripts([...pythonScripts], errors, warnings, runtime === "npm")
|
|
609
623
|
}
|
|
610
624
|
|
|
611
625
|
for (const path of await scanForTokens(root)) {
|
package/package.json
CHANGED