wordspace 0.0.12 → 0.0.13
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/dist/commands/run.d.ts +5 -1
- package/dist/commands/run.js +34 -5
- package/dist/index.js +21 -5
- package/dist/lib/skills.d.ts +20 -0
- package/dist/lib/skills.js +44 -0
- package/dist/steps/auto-init.d.ts +1 -1
- package/dist/steps/auto-init.js +4 -6
- package/package.json +1 -1
package/dist/commands/run.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface RunOptions {
|
|
2
|
+
params?: Record<string, string>;
|
|
3
|
+
skillsDir?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function run(target: string | undefined, force: boolean, harnessArg?: string, options?: RunOptions): Promise<void>;
|
package/dist/commands/run.js
CHANGED
|
@@ -5,6 +5,7 @@ import { httpGet, getAuthHeaders } from "../lib/workflows.js";
|
|
|
5
5
|
import { HARNESSES, detectInstalled, spawnHarness, } from "../lib/harness.js";
|
|
6
6
|
import { pickOne } from "../lib/prompt.js";
|
|
7
7
|
import { ensureInit } from "../steps/auto-init.js";
|
|
8
|
+
import { discoverSkills } from "../lib/skills.js";
|
|
8
9
|
import * as log from "../lib/log.js";
|
|
9
10
|
/**
|
|
10
11
|
* Build the prompt string for a given harness.
|
|
@@ -27,7 +28,35 @@ function buildPrompt(harness, prosePath, cwd) {
|
|
|
27
28
|
"--- END WORKFLOW ---",
|
|
28
29
|
].join("\n");
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Build a rich passthrough prompt that tells the calling agent where skills
|
|
33
|
+
* are installed, how to use open-prose, and provides workflow params.
|
|
34
|
+
*/
|
|
35
|
+
function buildPassthroughPrompt(prosePath, cwd, params, skillsDir) {
|
|
36
|
+
const fullPath = join(cwd, prosePath);
|
|
37
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
38
|
+
const discovery = discoverSkills(cwd, skillsDir);
|
|
39
|
+
const lines = [];
|
|
40
|
+
if (discovery) {
|
|
41
|
+
const skillList = discovery.skills
|
|
42
|
+
.map((s) => ` - ${s.name}`)
|
|
43
|
+
.join("\n");
|
|
44
|
+
lines.push(`You have access to the following skills installed at ${discovery.dir}:`, skillList, "", "To execute this workflow:", "", `1. Read the open-prose skill: ${discovery.dir}/open-prose/SKILL.md`, "2. Follow its instructions to load the VM (prose.md) and become the OpenProse interpreter", `3. Run the workflow file: ${prosePath}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
lines.push(`You are executing a wordspace workflow defined in the file "${prosePath}".`, `Follow the steps below exactly. Write all output files to the "output/" directory.`);
|
|
48
|
+
}
|
|
49
|
+
if (params && Object.keys(params).length > 0) {
|
|
50
|
+
lines.push("", "The following input parameters have been provided:");
|
|
51
|
+
for (const [key, value] of Object.entries(params)) {
|
|
52
|
+
lines.push(` ${key} = "${value}"`);
|
|
53
|
+
}
|
|
54
|
+
lines.push("Use these values for the corresponding `input` declarations in the workflow.");
|
|
55
|
+
}
|
|
56
|
+
lines.push("", `--- WORKFLOW: ${prosePath} ---`, content, "--- END WORKFLOW ---");
|
|
57
|
+
return lines.join("\n");
|
|
58
|
+
}
|
|
59
|
+
export async function run(target, force, harnessArg, options) {
|
|
31
60
|
if (!target) {
|
|
32
61
|
log.error("Usage: wordspace run <github:owner/repo/path.prose | local-path>");
|
|
33
62
|
process.exit(1);
|
|
@@ -86,7 +115,7 @@ export async function run(target, force, harnessArg) {
|
|
|
86
115
|
}
|
|
87
116
|
const cwd = process.cwd();
|
|
88
117
|
// Auto-init if needed (harness-aware)
|
|
89
|
-
ensureInit(cwd, harness);
|
|
118
|
+
ensureInit(cwd, harness, options?.skillsDir);
|
|
90
119
|
let prosePath;
|
|
91
120
|
if (target.startsWith("github:")) {
|
|
92
121
|
// Remote: download from GitHub
|
|
@@ -116,12 +145,12 @@ export async function run(target, force, harnessArg) {
|
|
|
116
145
|
}
|
|
117
146
|
prosePath = target;
|
|
118
147
|
}
|
|
119
|
-
const prompt = buildPrompt(harness, prosePath, cwd);
|
|
120
148
|
if (harness.mode === "passthrough") {
|
|
121
|
-
|
|
122
|
-
console.log(
|
|
149
|
+
const passthroughPrompt = buildPassthroughPrompt(prosePath, cwd, options?.params, options?.skillsDir);
|
|
150
|
+
console.log(passthroughPrompt);
|
|
123
151
|
process.exit(0);
|
|
124
152
|
}
|
|
153
|
+
const prompt = buildPrompt(harness, prosePath, cwd);
|
|
125
154
|
console.log();
|
|
126
155
|
if (harness.skillNative) {
|
|
127
156
|
log.info(prompt);
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { search } from "./commands/search.js";
|
|
|
4
4
|
import { add } from "./commands/add.js";
|
|
5
5
|
import { run } from "./commands/run.js";
|
|
6
6
|
import * as log from "./lib/log.js";
|
|
7
|
-
const VERSION = "0.0.
|
|
7
|
+
const VERSION = "0.0.13";
|
|
8
8
|
const HELP = `
|
|
9
9
|
Usage: wordspace <command> [options]
|
|
10
10
|
|
|
@@ -17,6 +17,8 @@ Commands:
|
|
|
17
17
|
Options:
|
|
18
18
|
--force Re-run all steps / overwrite existing files
|
|
19
19
|
--harness <name> Use a specific coding agent (e.g. claude, aider, goose)
|
|
20
|
+
--params <json> Workflow input parameters as JSON (e.g. '{"topic":"x402"}')
|
|
21
|
+
--skills-dir <dir> Custom skills directory (default: auto-discover)
|
|
20
22
|
--help Show this help message
|
|
21
23
|
--version Show version number
|
|
22
24
|
`.trim();
|
|
@@ -30,13 +32,27 @@ async function main() {
|
|
|
30
32
|
console.log(VERSION);
|
|
31
33
|
process.exit(0);
|
|
32
34
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
let harnessArg;
|
|
36
|
+
let params;
|
|
37
|
+
let skillsDir;
|
|
35
38
|
// Filter out flags and their values from positional args
|
|
36
39
|
const positional = [];
|
|
37
40
|
for (let i = 0; i < args.length; i++) {
|
|
38
41
|
if (args[i] === "--harness") {
|
|
39
|
-
|
|
42
|
+
harnessArg = args[++i];
|
|
43
|
+
}
|
|
44
|
+
else if (args[i] === "--params") {
|
|
45
|
+
const raw = args[++i];
|
|
46
|
+
try {
|
|
47
|
+
params = JSON.parse(raw);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
log.error("Invalid --params JSON");
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (args[i] === "--skills-dir") {
|
|
55
|
+
skillsDir = args[++i];
|
|
40
56
|
}
|
|
41
57
|
else if (!args[i].startsWith("-")) {
|
|
42
58
|
positional.push(args[i]);
|
|
@@ -54,7 +70,7 @@ async function main() {
|
|
|
54
70
|
await add(positional.slice(1), force);
|
|
55
71
|
}
|
|
56
72
|
else if (command === "run") {
|
|
57
|
-
await run(positional[1], force, harnessArg);
|
|
73
|
+
await run(positional[1], force, harnessArg, { params, skillsDir });
|
|
58
74
|
}
|
|
59
75
|
else if (!command) {
|
|
60
76
|
console.log(HELP);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface SkillInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
}
|
|
5
|
+
export interface SkillDiscoveryResult {
|
|
6
|
+
dir: string;
|
|
7
|
+
skills: SkillInfo[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Discover installed skills by checking directories in priority order:
|
|
11
|
+
* 1. customDir (if --skills-dir provided)
|
|
12
|
+
* 2. <cwd>/.agents/skills/
|
|
13
|
+
* 3. ~/.agents/skills/ (home dir global)
|
|
14
|
+
*
|
|
15
|
+
* Returns the first directory that contains at least the open-prose skill.
|
|
16
|
+
* Lists all skills found in that directory (each subdirectory with a SKILL.md).
|
|
17
|
+
*/
|
|
18
|
+
export declare function discoverSkills(cwd: string, customDir?: string): SkillDiscoveryResult | null;
|
|
19
|
+
/** Check whether the required skills are installed in a given directory. */
|
|
20
|
+
export declare function hasRequiredSkills(dir: string): boolean;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
/**
|
|
5
|
+
* Discover installed skills by checking directories in priority order:
|
|
6
|
+
* 1. customDir (if --skills-dir provided)
|
|
7
|
+
* 2. <cwd>/.agents/skills/
|
|
8
|
+
* 3. ~/.agents/skills/ (home dir global)
|
|
9
|
+
*
|
|
10
|
+
* Returns the first directory that contains at least the open-prose skill.
|
|
11
|
+
* Lists all skills found in that directory (each subdirectory with a SKILL.md).
|
|
12
|
+
*/
|
|
13
|
+
export function discoverSkills(cwd, customDir) {
|
|
14
|
+
const candidates = [];
|
|
15
|
+
if (customDir)
|
|
16
|
+
candidates.push(customDir);
|
|
17
|
+
candidates.push(join(cwd, ".agents", "skills"));
|
|
18
|
+
candidates.push(join(homedir(), ".agents", "skills"));
|
|
19
|
+
for (const dir of candidates) {
|
|
20
|
+
if (!existsSync(dir))
|
|
21
|
+
continue;
|
|
22
|
+
const hasOpenProse = existsSync(join(dir, "open-prose"));
|
|
23
|
+
if (!hasOpenProse)
|
|
24
|
+
continue;
|
|
25
|
+
const skills = [];
|
|
26
|
+
for (const entry of readdirSync(dir)) {
|
|
27
|
+
const entryPath = join(dir, entry);
|
|
28
|
+
if (!statSync(entryPath).isDirectory())
|
|
29
|
+
continue;
|
|
30
|
+
if (existsSync(join(entryPath, "SKILL.md"))) {
|
|
31
|
+
skills.push({ name: entry, path: entryPath });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (skills.length > 0) {
|
|
35
|
+
return { dir, skills };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/** Check whether the required skills are installed in a given directory. */
|
|
41
|
+
export function hasRequiredSkills(dir) {
|
|
42
|
+
const required = ["open-prose", "agentwallet", "registry", "wordspace"];
|
|
43
|
+
return required.every((s) => existsSync(join(dir, s)));
|
|
44
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Harness } from "../lib/harness.js";
|
|
2
2
|
/** Silently initialize the project if not already done. */
|
|
3
|
-
export declare function ensureInit(cwd: string, harness: Harness): void;
|
|
3
|
+
export declare function ensureInit(cwd: string, harness: Harness, customSkillsDir?: string): void;
|
package/dist/steps/auto-init.js
CHANGED
|
@@ -3,6 +3,7 @@ import { execSync } from "node:child_process";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { setupClaude } from "./setup-claude.js";
|
|
5
5
|
import { createDirs } from "./create-dirs.js";
|
|
6
|
+
import { discoverSkills, hasRequiredSkills } from "../lib/skills.js";
|
|
6
7
|
import * as log from "../lib/log.js";
|
|
7
8
|
const SKILL_PACKAGES = [
|
|
8
9
|
"frames-engineering/skills",
|
|
@@ -22,17 +23,14 @@ function installSkills(cwd) {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
/** Silently initialize the project if not already done. */
|
|
25
|
-
export function ensureInit(cwd, harness) {
|
|
26
|
+
export function ensureInit(cwd, harness, customSkillsDir) {
|
|
26
27
|
const isClaude = harness.bin === "claude";
|
|
27
28
|
const hasSettings = isClaude
|
|
28
29
|
? existsSync(join(cwd, ".claude", "settings.local.json"))
|
|
29
30
|
: true; // non-Claude harnesses don't need Claude settings
|
|
30
31
|
const hasOutput = existsSync(join(cwd, "output"));
|
|
31
|
-
const
|
|
32
|
-
const hasSkills =
|
|
33
|
-
existsSync(join(skillsDir, "agentwallet")) &&
|
|
34
|
-
existsSync(join(skillsDir, "registry")) &&
|
|
35
|
-
existsSync(join(skillsDir, "wordspace"));
|
|
32
|
+
const discovery = discoverSkills(cwd, customSkillsDir);
|
|
33
|
+
const hasSkills = discovery !== null && hasRequiredSkills(discovery.dir);
|
|
36
34
|
if (hasSettings && hasOutput && hasSkills)
|
|
37
35
|
return;
|
|
38
36
|
log.info("Auto-initializing project...");
|