@agentsystemlabs/core
Advanced tools
| import { readFileSync, writeFileSync } from 'node:fs'; | ||
| import { splitFrontmatter, readScalar, truncateDescription } from './codex.js'; | ||
| export { normalizeCodexSkill as normalizeOpencodeSkill } from './codex.js'; | ||
| export function convertAgentToOpencodeMd(agentMdFile, outMdFile, fallbackName) { | ||
| const content = readFileSync(agentMdFile, 'utf-8'); | ||
| const parsed = splitFrontmatter(content); | ||
| let description = `AgentSystem subagent: ${fallbackName}`; | ||
| let body = content; | ||
| if (parsed) { | ||
| description = truncateDescription( | ||
| readScalar(parsed.frontmatterLines, 'description') || | ||
| `AgentSystem subagent: ${fallbackName}` | ||
| ); | ||
| body = parsed.body.replace(/^\n+/, ''); | ||
| } | ||
| const frontmatter = [ | ||
| '---', | ||
| `description: ${JSON.stringify(description)}`, | ||
| 'mode: subagent', | ||
| 'permission:', | ||
| ' edit: deny', | ||
| ' bash: allow', | ||
| '---', | ||
| '', | ||
| ].join('\n'); | ||
| writeFileSync(outMdFile, frontmatter + body, 'utf-8'); | ||
| } |
@@ -8,3 +8,3 @@ { | ||
| "description": "AgentSystem skill collection — feature delivery, debugging, planning, UX, and code-quality skills.", | ||
| "version": "0.47.0" | ||
| "version": "0.48.2" | ||
| }, | ||
@@ -11,0 +11,0 @@ "plugins": [ |
| import { mkdirSync, existsSync, cpSync, copyFileSync } from 'node:fs'; | ||
| import { join } from 'node:path'; | ||
| import { convertAgentToCodexToml, normalizeCodexSkill } from '../lib/codex.js'; | ||
| import { convertAgentToOpencodeMd, normalizeOpencodeSkill } from '../lib/opencode.js'; | ||
| import { resolveAgentsDest, resolveDest, resolveHarness } from '../lib/paths.js'; | ||
@@ -62,2 +63,4 @@ import { | ||
| normalizeCodexSkill(join(target, 'SKILL.md'), skill); | ||
| } else if (harness.id === 'opencode') { | ||
| normalizeOpencodeSkill(join(target, 'SKILL.md'), skill); | ||
| } | ||
@@ -86,2 +89,4 @@ console.log(` ok skill ${plugin}:${skill}`); | ||
| convertAgentToCodexToml(file, target, agent); | ||
| } else if (harness.id === 'opencode') { | ||
| convertAgentToOpencodeMd(file, target, agent); | ||
| } else { | ||
@@ -88,0 +93,0 @@ copyFileSync(file, target); |
+3
-3
@@ -5,3 +5,3 @@ import { readFileSync, writeFileSync } from 'node:fs'; | ||
| function splitFrontmatter(content) { | ||
| export function splitFrontmatter(content) { | ||
| const lines = content.split(/\r?\n/); | ||
@@ -19,3 +19,3 @@ if (lines[0] !== '---') return null; | ||
| function readScalar(lines, key) { | ||
| export function readScalar(lines, key) { | ||
| const prefix = `${key}:`; | ||
@@ -35,3 +35,3 @@ const line = lines.find(candidate => candidate.startsWith(prefix)); | ||
| function truncateDescription(description) { | ||
| export function truncateDescription(description) { | ||
| if (description.length <= MAX_CODEX_DESCRIPTION_LENGTH) return description; | ||
@@ -38,0 +38,0 @@ |
+33
-7
@@ -35,2 +35,12 @@ import { fileURLToPath } from 'node:url'; | ||
| }, | ||
| opencode: { | ||
| id: 'opencode', | ||
| name: 'OpenCode', | ||
| aliases: ['opencode', 'open-code'], | ||
| skillsDir: ['.opencode', 'skills'], | ||
| agentsDir: ['.opencode', 'agents'], | ||
| globalSkillsDir: ['.config', 'opencode', 'skills'], | ||
| globalAgentsDir: ['.config', 'opencode', 'agents'], | ||
| agentFormat: 'md', | ||
| }, | ||
| }; | ||
@@ -57,14 +67,30 @@ | ||
| export function resolveDest({ global, dest, harness }) { | ||
| if (dest) return resolve(process.cwd(), dest); | ||
| function resolveHarnessPath({ global, customDest, harness, projectSegments, globalSegments }) { | ||
| if (customDest) return resolve(process.cwd(), customDest); | ||
| const resolvedHarness = resolveHarness(harness); | ||
| const base = global ? homedir() : process.cwd(); | ||
| return resolve(base, ...resolvedHarness.skillsDir); | ||
| const segments = global | ||
| ? resolvedHarness[globalSegments] ?? resolvedHarness[projectSegments] | ||
| : resolvedHarness[projectSegments]; | ||
| return resolve(base, ...segments); | ||
| } | ||
| export function resolveDest({ global, dest, harness }) { | ||
| return resolveHarnessPath({ | ||
| global, | ||
| customDest: dest, | ||
| harness, | ||
| projectSegments: 'skillsDir', | ||
| globalSegments: 'globalSkillsDir', | ||
| }); | ||
| } | ||
| export function resolveAgentsDest({ global, agentsDest, harness }) { | ||
| if (agentsDest) return resolve(process.cwd(), agentsDest); | ||
| const resolvedHarness = resolveHarness(harness); | ||
| const base = global ? homedir() : process.cwd(); | ||
| return resolve(base, ...resolvedHarness.agentsDir); | ||
| return resolveHarnessPath({ | ||
| global, | ||
| customDest: agentsDest, | ||
| harness, | ||
| projectSegments: 'agentsDir', | ||
| globalSegments: 'globalAgentsDir', | ||
| }); | ||
| } |
+8
-4
| { | ||
| "name": "@agentsystemlabs/core", | ||
| "version": "0.49.0", | ||
| "description": "Install AgentSystem skills into any project — works with Claude Code, the Claude Agent SDK, or any tool that reads SKILL.md files.", | ||
| "version": "0.50.2", | ||
| "description": "Install AgentSystem skills into any project — works with Claude Code, Codex, Cursor, OpenCode, or any tool that reads SKILL.md files.", | ||
| "type": "module", | ||
@@ -13,4 +13,5 @@ "bin": { | ||
| "scripts": { | ||
| "test": "node scripts/run-tests.mjs", | ||
| "check:routing": "node scripts/check-skill-routing.mjs", | ||
| "prepublishOnly": "node cli/index.js --version" | ||
| "prepublishOnly": "npm test && node cli/index.js --version" | ||
| }, | ||
@@ -34,3 +35,6 @@ "files": [ | ||
| "agentsystem", | ||
| "anthropic" | ||
| "anthropic", | ||
| "opencode", | ||
| "codex", | ||
| "cursor" | ||
| ], | ||
@@ -37,0 +41,0 @@ "repository": { |
@@ -65,2 +65,4 @@ --- | ||
| **Host-portability fallback.** If the `Skill` tool is not available in the current session (OpenAI Codex and other non-Claude-Code hosts), Read each applicable skill's SKILL.md at `plugins/agentsystem-core/skills/<skill-name>/SKILL.md` and execute them sequentially in this turn, treating each as the next phase of work. Reviewer subagents (`reviewer-*`) still go through the `Agent` tool — most CLIs that lack `Skill` still have a general-purpose agent primitive, and you can pass the reviewer's SKILL.md path to it. Surface the degradation up-front: tell the user "Skill tool unavailable — audits will run inline, sequentially, without subagent isolation." Inline sequential execution is slower and loses fan-out parallelism, but the findings are still produced. | ||
| **Always (every mode):** | ||
@@ -67,0 +69,0 @@ - `simplify` — DRY, magic numbers, naming, oversized files, parallel-enum drift, repeated literals (override default diff-only scope to Phase 1 scope) |
@@ -106,2 +106,10 @@ --- | ||
| **Host-portability fallback.** The `Skill` tool is a Claude Code primitive and may not exist in other agent CLIs (OpenAI Codex, Cursor, Cline, raw API runs, etc.). If `Skill` is not available in the current session: | ||
| 1. Read the routed skill's SKILL.md directly — for the core skills it's `plugins/agentsystem-core/skills/<skill-name>/SKILL.md` in this repo, or the equivalent path the host loads skills from. | ||
| 2. Execute its instructions inline as your next phase of work, passing the same args you would have passed to `Skill(...)`. | ||
| 3. Surface the degradation in the Step 3 announcement: add a line like `Routing: inline (Skill tool unavailable — no subagent isolation, parent context will carry the routed skill's work)`. The user must know the run isn't isolated. | ||
| Inline execution loses subagent context isolation but preserves routing decisions, mode propagation, and downstream audit gates. That is acceptable degradation. Refusing to run because `Skill` is missing is not. | ||
| **Respect downstream gates.** `add-feature mode=production` has its own Plan-approval gate. Let it fire. Don't bypass it from /ship. | ||
@@ -150,5 +158,5 @@ | ||
| - **NEVER replicate the core skill's pipeline inline** | ||
| **Instead:** Always delegate via the `Skill` tool. /ship is a router; the core skill is the engine. | ||
| **Why:** Inlined pipelines drift from canonical core-skill behavior on every update. Two implementations of the same workflow guarantees one will be wrong after the next change to either. | ||
| - **NEVER replicate the core skill's pipeline inline from memory** | ||
| **Instead:** Always delegate. Use the `Skill` tool when the host exposes it; when it doesn't (Codex and other non-Claude-Code hosts), Read the routed skill's SKILL.md and follow that file verbatim — do not improvise the pipeline from your own recall of what `add-feature` or `fix-bug` "usually does". /ship is a router; the SKILL.md is the engine. | ||
| **Why:** Inlined pipelines drift from canonical core-skill behavior on every update. Two implementations of the same workflow guarantees one will be wrong after the next change to either. Reading the file each run keeps the engine canonical even when the `Skill` tool isn't available. | ||
@@ -155,0 +163,0 @@ - **NEVER hide which mode and pipeline you picked** |
+14
-1
@@ -31,5 +31,7 @@ # AgentSystem | ||
| npx @agentsystemlabs/core init --harness cursor # → ./.cursor/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --harness opencode # → ./.opencode/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --global # → ~/.claude/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --harness codex --global # → ~/.codex/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --harness cursor --global # → ~/.cursor/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --harness opencode --global # → ~/.config/opencode/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --plugin core # subset (short name) | ||
@@ -46,4 +48,15 @@ npx @agentsystemlabs/core init --dest ./my-skills # custom skills path | ||
| Each skill lands as `<harness-root>/skills/<skill-name>/SKILL.md` (with its `references/` folder if present), so any agent that reads SKILL.md format picks them up directly. Subagents land in parallel at `<harness-root>/agents/<agent-name>.<ext>` — `.md` for Claude Code and Cursor (which read the same format), `.toml` for Codex (auto-converted from the source `.md` with descriptions truncated to Codex's 1024-char limit). The supported harnesses are `claude` (alias: `claude-code`), `codex`, and `cursor` (alias: `cursor-cli`); `--dest` overrides the skills path and `--agents-dest` overrides the subagents path. By default `init` skips files that already exist — pass `--force` to overwrite. The `--plugin` flag accepts short names (e.g., `core` for `agentsystem-core`), can be repeated, or comma-separated. Pass `--skip-agents` to install only the skills. | ||
| Each skill lands as `<harness-root>/skills/<skill-name>/SKILL.md` (with its `references/` folder if present), so any agent that reads SKILL.md format picks them up directly. Subagents land in parallel at `<harness-root>/agents/<agent-name>.<ext>` — `.md` for Claude Code and Cursor (which read the same format), `.toml` for Codex (auto-converted from the source `.md` with descriptions truncated to Codex's 1024-char limit), and OpenCode-native `.md` for OpenCode (adds `mode: subagent` and read-only permissions). The supported harnesses are `claude` (alias: `claude-code`), `codex`, `cursor` (alias: `cursor-cli`), and `opencode`; `--dest` overrides the skills path and `--agents-dest` overrides the subagents path. By default `init` skips files that already exist — pass `--force` to overwrite. The `--plugin` flag accepts short names (e.g., `core` for `agentsystem-core`), can be repeated, or comma-separated. Pass `--skip-agents` to install only the skills. | ||
| ### OpenCode | ||
| [OpenCode](https://opencode.ai) can run alongside Codex, Copilot, and OpenCode Go plan in the same project. Install AgentSystem skills and subagents into OpenCode's native layout: | ||
| ```bash | ||
| npx @agentsystemlabs/core init --harness opencode # project: .opencode/{skills,agents}/ | ||
| npx @agentsystemlabs/core init --harness opencode --global # global: ~/.config/opencode/{skills,agents}/ | ||
| ``` | ||
| Skills are discovered from `.opencode/skills/*/SKILL.md` and loaded on demand via OpenCode's `skill` tool. Subagents are written as markdown agents with `mode: subagent` so primary agents (Build, Plan) can invoke them via `@mention` or the Task tool. See the [OpenCode agents](https://opencode.ai/docs/agents/), [skills](https://opencode.ai/docs/skills/), and [plugins](https://opencode.ai/docs/plugins/) docs for configuration beyond the install step. | ||
| ## Autopilot — start here | ||
@@ -50,0 +63,0 @@ |
643602
0.84%87
1.16%538
11.85%188
7.43%