@skillstate/cli 2.0.2 → 2.0.4
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 +79 -9
- package/dist/commands.d.ts +2 -2
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +27 -19
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +144 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +535 -0
- package/dist/install.js.map +1 -0
- package/dist/jsonc.d.ts +46 -0
- package/dist/jsonc.d.ts.map +1 -0
- package/dist/jsonc.js +255 -0
- package/dist/jsonc.js.map +1 -0
- package/package.json +4 -2
package/dist/install.js
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
// skillstate host auto-install (additive, @non-paper Wave-4 DX).
|
|
2
|
+
//
|
|
3
|
+
// `skillstate init` detects the host (opencode | claude | codex) and installs
|
|
4
|
+
// everything in one shot:
|
|
5
|
+
// - state dir `./.skillstate/` in the project (per-project state + manifest);
|
|
6
|
+
// - OpenCode: plugin into `~/.config/opencode/plugins/` (auto-loaded at
|
|
7
|
+
// startup), `mcp.skillstate` entry spliced into `opencode.jsonc` (with a
|
|
8
|
+
// timestamped backup), `SKILL.md` into `~/.config/opencode/skills/`;
|
|
9
|
+
// - Claude: `SKILL.md` into `~/.claude/skills/` + `.mcp.json` in the project;
|
|
10
|
+
// - Codex: `SKILL.md` into `~/.codex/skills/` (no MCP — TOML config untouched).
|
|
11
|
+
//
|
|
12
|
+
// An install manifest (`<stateDir>/install-manifest.json`) records every path
|
|
13
|
+
// touched so `skillstate uninstall` (or `init --uninstall`) can roll it all
|
|
14
|
+
// back exactly.
|
|
15
|
+
/// <reference types="node" />
|
|
16
|
+
import * as fs from 'node:fs';
|
|
17
|
+
import * as os from 'node:os';
|
|
18
|
+
import * as path from 'node:path';
|
|
19
|
+
import { createRequire } from 'node:module';
|
|
20
|
+
import { atomicWriteFile } from '@skillstate/core';
|
|
21
|
+
import { GENERIC_PROCEDURE_SPEC, INTERCODE_CTF_SPEC } from '@skillstate/core/schemas';
|
|
22
|
+
import { OpenCodeAdapter } from '@skillstate/opencode';
|
|
23
|
+
import { findTopLevelObject, insertObjectEntry, removeObjectEntry } from './jsonc.js';
|
|
24
|
+
import { resolveInCwd } from './commands.js';
|
|
25
|
+
const HOSTS = ['opencode', 'claude', 'codex'];
|
|
26
|
+
/** Project runtime directory created by init. */
|
|
27
|
+
export const STATE_DIR_NAME = '.skillstate';
|
|
28
|
+
/** Install manifest file name inside the state dir. */
|
|
29
|
+
export const MANIFEST_FILE_NAME = 'install-manifest.json';
|
|
30
|
+
/** Short skill description used for the SKILL.md frontmatter. */
|
|
31
|
+
const SKILL_DESCRIPTION = 'State-based execution: persist agent state to a JSON file, keep the prompt O(1), and resume any procedure from disk.';
|
|
32
|
+
function isRecord(value) {
|
|
33
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
34
|
+
}
|
|
35
|
+
/** Default home (`$HOME`, else `os.homedir()`); the `main` entry uses this. */
|
|
36
|
+
export function defaultHome() {
|
|
37
|
+
return process.env['HOME'] ?? os.homedir();
|
|
38
|
+
}
|
|
39
|
+
/** True when `dir` resolves inside the system temp directory (`os.tmpdir()`). */
|
|
40
|
+
export function isInsideTemp(dir) {
|
|
41
|
+
const resolved = path.resolve(dir);
|
|
42
|
+
const tmp = path.resolve(os.tmpdir());
|
|
43
|
+
return resolved === tmp || resolved.startsWith(tmp + path.sep);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Detect the host from marker files under `home` (opencode first):
|
|
47
|
+
* - opencode: `~/.config/opencode/opencode.jsonc|opencode.json` or `~/.opencode/bin/opencode`;
|
|
48
|
+
* - claude: `~/.claude`;
|
|
49
|
+
* - codex: `~/.codex`.
|
|
50
|
+
* Returns null when nothing matches.
|
|
51
|
+
*/
|
|
52
|
+
export function detectHost(home) {
|
|
53
|
+
const configDir = path.join(home, '.config', 'opencode');
|
|
54
|
+
if (fs.existsSync(path.join(configDir, 'opencode.jsonc')) ||
|
|
55
|
+
fs.existsSync(path.join(configDir, 'opencode.json')) ||
|
|
56
|
+
fs.existsSync(path.join(home, '.opencode', 'bin', 'opencode'))) {
|
|
57
|
+
return 'opencode';
|
|
58
|
+
}
|
|
59
|
+
if (fs.existsSync(path.join(home, '.claude'))) {
|
|
60
|
+
return 'claude';
|
|
61
|
+
}
|
|
62
|
+
if (fs.existsSync(path.join(home, '.codex'))) {
|
|
63
|
+
return 'codex';
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse `init` flags: `--host <h>`, `--state-path <path>`, `--max-history <n>`,
|
|
69
|
+
* `--no-mcp`, `--no-skill`, `--dry-run`, `--auto`, `--uninstall` (`=`-forms
|
|
70
|
+
* accepted). Throws an `Error` with the usage line on unknown/invalid flags.
|
|
71
|
+
*/
|
|
72
|
+
export function parseInitArgs(args) {
|
|
73
|
+
if (wantsHelpInit(args)) {
|
|
74
|
+
throw new HelpRequestedInitError();
|
|
75
|
+
}
|
|
76
|
+
const flags = { noMcp: false, noSkill: false, dryRun: false, auto: false, uninstall: false };
|
|
77
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
78
|
+
const arg = args[i];
|
|
79
|
+
if (arg === '--auto') {
|
|
80
|
+
flags.auto = true;
|
|
81
|
+
}
|
|
82
|
+
else if (arg === '--dry-run') {
|
|
83
|
+
flags.dryRun = true;
|
|
84
|
+
}
|
|
85
|
+
else if (arg === '--no-mcp') {
|
|
86
|
+
flags.noMcp = true;
|
|
87
|
+
}
|
|
88
|
+
else if (arg === '--no-skill') {
|
|
89
|
+
flags.noSkill = true;
|
|
90
|
+
}
|
|
91
|
+
else if (arg === '--uninstall') {
|
|
92
|
+
flags.uninstall = true;
|
|
93
|
+
}
|
|
94
|
+
else if (arg === '--host' || arg.startsWith('--host=')) {
|
|
95
|
+
const value = arg === '--host' ? args[++i] : arg.slice('--host='.length);
|
|
96
|
+
if (value === undefined ||
|
|
97
|
+
(value !== 'opencode' && value !== 'claude' && value !== 'codex')) {
|
|
98
|
+
throw new Error(`Invalid --host (want opencode|claude|codex)\n${CLI_USAGE_INSTALL}`);
|
|
99
|
+
}
|
|
100
|
+
flags.host = value;
|
|
101
|
+
}
|
|
102
|
+
else if (arg === '--state-path' || arg.startsWith('--state-path=')) {
|
|
103
|
+
const value = arg === '--state-path' ? args[++i] : arg.slice('--state-path='.length);
|
|
104
|
+
if (value === undefined || value.length === 0) {
|
|
105
|
+
throw new Error(`Missing value for --state-path\n${CLI_USAGE_INSTALL}`);
|
|
106
|
+
}
|
|
107
|
+
flags.statePath = value;
|
|
108
|
+
}
|
|
109
|
+
else if (arg === '--max-history' || arg.startsWith('--max-history=')) {
|
|
110
|
+
const value = arg === '--max-history' ? args[++i] : arg.slice('--max-history='.length);
|
|
111
|
+
const parsed = typeof value === 'string' ? Number(value) : NaN;
|
|
112
|
+
if (value === undefined || !Number.isInteger(parsed) || parsed < 1) {
|
|
113
|
+
throw new Error(`Invalid --max-history (want a positive integer)\n${CLI_USAGE_INSTALL}`);
|
|
114
|
+
}
|
|
115
|
+
flags.maxHistory = parsed;
|
|
116
|
+
}
|
|
117
|
+
else if (arg === '--spec' || arg.startsWith('--spec=')) {
|
|
118
|
+
const value = arg === '--spec' ? args[++i] : arg.slice('--spec='.length);
|
|
119
|
+
if (value === undefined || value.length === 0) {
|
|
120
|
+
throw new Error(`Missing value for --spec\n${CLI_USAGE_INSTALL}`);
|
|
121
|
+
}
|
|
122
|
+
flags.specPath = value;
|
|
123
|
+
}
|
|
124
|
+
else if (arg === '--example' || arg.startsWith('--example=')) {
|
|
125
|
+
const value = arg === '--example' ? args[++i] : arg.slice('--example='.length);
|
|
126
|
+
if (value !== 'ctf') {
|
|
127
|
+
throw new Error(`Invalid --example (want ctf)\n${CLI_USAGE_INSTALL}`);
|
|
128
|
+
}
|
|
129
|
+
flags.example = value;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
throw new Error(`Unknown flag for init: ${arg}\n${CLI_USAGE_INSTALL}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return flags;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Parse `uninstall` flags: `--state-dir <path>`, `--remove-state`,
|
|
139
|
+
* `--dry-run`. Throws an `Error` with the usage line on unknown flags.
|
|
140
|
+
*/
|
|
141
|
+
export function parseUninstallArgs(args) {
|
|
142
|
+
if (wantsHelpInit(args)) {
|
|
143
|
+
throw new HelpRequestedInitError();
|
|
144
|
+
}
|
|
145
|
+
const flags = { removeState: false, dryRun: false };
|
|
146
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
147
|
+
const arg = args[i];
|
|
148
|
+
if (arg === '--remove-state') {
|
|
149
|
+
flags.removeState = true;
|
|
150
|
+
}
|
|
151
|
+
else if (arg === '--dry-run') {
|
|
152
|
+
flags.dryRun = true;
|
|
153
|
+
}
|
|
154
|
+
else if (arg === '--state-dir' || arg.startsWith('--state-dir=')) {
|
|
155
|
+
const value = arg === '--state-dir' ? args[++i] : arg.slice('--state-dir='.length);
|
|
156
|
+
if (value === undefined || value.length === 0) {
|
|
157
|
+
throw new Error(`Missing value for --state-dir\n${CLI_USAGE_INSTALL}`);
|
|
158
|
+
}
|
|
159
|
+
flags.stateDir = value;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
throw new Error(`Unknown flag for uninstall: ${arg}\n${CLI_USAGE_INSTALL}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return flags;
|
|
166
|
+
}
|
|
167
|
+
/** Help marker for init/uninstall flags (kept local to avoid a commands.ts cycle). */
|
|
168
|
+
function wantsHelpInit(args) {
|
|
169
|
+
return args.includes('--help') || args.includes('-h');
|
|
170
|
+
}
|
|
171
|
+
/** Thrown by `parseInitArgs`/`parseUninstallArgs` on `--help`/`-h`. */
|
|
172
|
+
export class HelpRequestedInitError extends Error {
|
|
173
|
+
constructor() {
|
|
174
|
+
super('help requested');
|
|
175
|
+
this.name = 'HelpRequestedInitError';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Usage line for init/uninstall (composed with the CLI usage in commands.ts). */
|
|
179
|
+
export const CLI_USAGE_INSTALL = 'Usage: skillstate init [--host opencode|claude|codex] [--state-path <path>] [--max-history <n>] [--no-mcp] [--no-skill] [--dry-run] | init --uninstall | uninstall [--state-dir <path>] [--remove-state] [--dry-run]';
|
|
180
|
+
/** Resolve the MCP server command: the `@skillstate/mcp` bin via `node`, or the global `skillstate-mcp` bin. */
|
|
181
|
+
export function resolveMcpCommandWith(resolve) {
|
|
182
|
+
try {
|
|
183
|
+
const pkg = resolve('@skillstate/mcp/package.json');
|
|
184
|
+
return { command: 'node', args: [path.join(path.dirname(pkg), 'bin', 'mcp.js')] };
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return { command: 'skillstate-mcp', args: [] };
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** `resolveMcpCommandWith` bound to this module's require resolver. */
|
|
191
|
+
export function resolveMcpCommand() {
|
|
192
|
+
return resolveMcpCommandWith((id) => createRequire(import.meta.url).resolve(id));
|
|
193
|
+
}
|
|
194
|
+
function backupPathFor(file) {
|
|
195
|
+
return `${file}.bak.${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
196
|
+
}
|
|
197
|
+
/** Path of the OpenCode host config: existing `.jsonc`, else `.json`, else the canonical `.jsonc`. */
|
|
198
|
+
function resolveOpencodeConfig(home) {
|
|
199
|
+
const dir = path.join(home, '.config', 'opencode');
|
|
200
|
+
const jsonc = path.join(dir, 'opencode.jsonc');
|
|
201
|
+
if (fs.existsSync(jsonc)) {
|
|
202
|
+
return jsonc;
|
|
203
|
+
}
|
|
204
|
+
const json = path.join(dir, 'opencode.json');
|
|
205
|
+
return fs.existsSync(json) ? json : jsonc;
|
|
206
|
+
}
|
|
207
|
+
function skillDirFor(host, home) {
|
|
208
|
+
if (host === 'opencode') {
|
|
209
|
+
return path.join(home, '.config', 'opencode', 'skills', 'skillstate');
|
|
210
|
+
}
|
|
211
|
+
if (host === 'claude') {
|
|
212
|
+
return path.join(home, '.claude', 'skills', 'skillstate');
|
|
213
|
+
}
|
|
214
|
+
return path.join(home, '.codex', 'skills', 'skillstate');
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Spec resolution for `init`: `--spec <path>` wins (validated), then
|
|
218
|
+
* `--example ctf`, then the neutral domain-agnostic default. Never defaults
|
|
219
|
+
* to a domain-specific example.
|
|
220
|
+
*/
|
|
221
|
+
export function resolveInitSpec(cwd, flags) {
|
|
222
|
+
if (flags.specPath !== undefined) {
|
|
223
|
+
const abs = resolveInCwd(cwd, flags.specPath);
|
|
224
|
+
let raw;
|
|
225
|
+
try {
|
|
226
|
+
raw = fs.readFileSync(abs, 'utf-8');
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
throw new Error(`Spec file not found: ${flags.specPath}`);
|
|
230
|
+
}
|
|
231
|
+
let parsed;
|
|
232
|
+
try {
|
|
233
|
+
parsed = JSON.parse(raw);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
throw new Error(`Spec file is not valid JSON: ${flags.specPath}`);
|
|
237
|
+
}
|
|
238
|
+
if (typeof parsed !== 'object' ||
|
|
239
|
+
parsed === null ||
|
|
240
|
+
typeof parsed['id'] !== 'string' ||
|
|
241
|
+
typeof parsed['name'] !== 'string' ||
|
|
242
|
+
typeof parsed['instructions'] !== 'string' ||
|
|
243
|
+
typeof parsed['schema'] !== 'object' ||
|
|
244
|
+
parsed['schema'] === null) {
|
|
245
|
+
throw new Error(`Invalid spec ${flags.specPath}: need { id: string, name: string, instructions: string, schema: object }`);
|
|
246
|
+
}
|
|
247
|
+
return parsed;
|
|
248
|
+
}
|
|
249
|
+
if (flags.example === 'ctf') {
|
|
250
|
+
return INTERCODE_CTF_SPEC;
|
|
251
|
+
}
|
|
252
|
+
return GENERIC_PROCEDURE_SPEC;
|
|
253
|
+
}
|
|
254
|
+
/** SKILL.md with a short frontmatter description + the adapter-generated body. */
|
|
255
|
+
export function buildSkillMd(statePathRel, spec) {
|
|
256
|
+
const generated = new OpenCodeAdapter().generateSkillMd(spec, statePathRel);
|
|
257
|
+
const body = generated.slice(generated.indexOf('\n---', 3) + '\n---\n'.length);
|
|
258
|
+
return `---
|
|
259
|
+
name: skillstate
|
|
260
|
+
description: ${JSON.stringify(SKILL_DESCRIPTION)}
|
|
261
|
+
---
|
|
262
|
+
${body}`;
|
|
263
|
+
}
|
|
264
|
+
/** Skillstate MCP entry shaped like the host's existing local-server entries. */
|
|
265
|
+
export function buildMcpEntry(stateAbs) {
|
|
266
|
+
const cmd = resolveMcpCommand();
|
|
267
|
+
return {
|
|
268
|
+
type: 'local',
|
|
269
|
+
command: [cmd.command, ...cmd.args],
|
|
270
|
+
enabled: true,
|
|
271
|
+
environment: { SKILLSTATE_STATE_PATH: stateAbs },
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Splice the `skillstate` server into the `mcp` object of OpenCode config
|
|
276
|
+
* text. Returns the (possibly unchanged) text and whether anything changed.
|
|
277
|
+
*/
|
|
278
|
+
export function addSkillstateMcp(configText, entry) {
|
|
279
|
+
const root = findTopLevelObject(configText);
|
|
280
|
+
if (root === null) {
|
|
281
|
+
return { text: configText, changed: false };
|
|
282
|
+
}
|
|
283
|
+
const mcp = root.entries.find((e) => e.key === 'mcp');
|
|
284
|
+
if (mcp === undefined) {
|
|
285
|
+
return insertObjectEntry(configText, root.braceStart, 'mcp', JSON.stringify({ skillstate: entry }, null, 2));
|
|
286
|
+
}
|
|
287
|
+
if (configText[mcp.valueStart] !== '{') {
|
|
288
|
+
return { text: configText, changed: false };
|
|
289
|
+
}
|
|
290
|
+
return insertObjectEntry(configText, mcp.valueStart, 'skillstate', JSON.stringify(entry, null, 2));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Splice the `skillstate` server back out of the `mcp` object. Missing
|
|
294
|
+
* `mcp` key / non-object `mcp` / missing `skillstate` are all no-ops.
|
|
295
|
+
*/
|
|
296
|
+
export function removeSkillstateMcp(configText) {
|
|
297
|
+
const root = findTopLevelObject(configText);
|
|
298
|
+
if (root === null) {
|
|
299
|
+
return { text: configText, changed: false };
|
|
300
|
+
}
|
|
301
|
+
const mcp = root.entries.find((e) => e.key === 'mcp');
|
|
302
|
+
if (mcp === undefined || configText[mcp.valueStart] !== '{') {
|
|
303
|
+
return { text: configText, changed: false };
|
|
304
|
+
}
|
|
305
|
+
return removeObjectEntry(configText, mcp.valueStart, 'skillstate');
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Full one-shot install for the detected (or forced) host. Never throws for
|
|
309
|
+
* expected conditions; returns a process exit code (0 ok, 1 no host).
|
|
310
|
+
*/
|
|
311
|
+
export async function autoInstall(options) {
|
|
312
|
+
const { cwd, home, flags } = options;
|
|
313
|
+
if (isInsideTemp(cwd)) {
|
|
314
|
+
console.warn('[skillstate] installing from a temp directory — is this intended?');
|
|
315
|
+
}
|
|
316
|
+
const host = flags.host ?? detectHost(home);
|
|
317
|
+
if (host === null) {
|
|
318
|
+
console.error('No supported host detected (~/.config/opencode, ~/.claude, ~/.codex). Install one or pass --host.');
|
|
319
|
+
return 1;
|
|
320
|
+
}
|
|
321
|
+
const dry = flags.dryRun;
|
|
322
|
+
const say = (line) => {
|
|
323
|
+
console.log(dry ? `[dry-run] ${line}` : line);
|
|
324
|
+
};
|
|
325
|
+
const maxHistory = flags.maxHistory ?? 3;
|
|
326
|
+
const spec = options.spec ?? resolveInitSpec(cwd, flags);
|
|
327
|
+
const stateDir = path.join(cwd, STATE_DIR_NAME);
|
|
328
|
+
const stateAbs = flags.statePath !== undefined ? resolveInCwd(cwd, flags.statePath) : path.join(stateDir, 'skillstate.json');
|
|
329
|
+
const stateCreated = !dry && !fs.existsSync(stateAbs);
|
|
330
|
+
if (!dry) {
|
|
331
|
+
fs.mkdirSync(path.dirname(stateAbs), { recursive: true });
|
|
332
|
+
if (stateCreated) {
|
|
333
|
+
await atomicWriteFile(stateAbs, `${JSON.stringify({ version: 1, state: {} }, null, 2)}\n`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
say(`host: ${host}${flags.host === undefined ? ' (detected)' : ''}`);
|
|
337
|
+
say(`state: ${stateAbs}${stateCreated ? ' (created)' : ''}`);
|
|
338
|
+
const manifest = {
|
|
339
|
+
version: 1,
|
|
340
|
+
host,
|
|
341
|
+
installedAt: new Date().toISOString(),
|
|
342
|
+
statePath: stateAbs,
|
|
343
|
+
maxHistoryMessages: maxHistory,
|
|
344
|
+
};
|
|
345
|
+
if (host === 'opencode') {
|
|
346
|
+
const pluginAbs = path.join(home, '.config', 'opencode', 'plugins', 'skillstate.ts');
|
|
347
|
+
if (!dry) {
|
|
348
|
+
// Thin loader: imports createSkillStatePlugin from @skillstate/opencode
|
|
349
|
+
// (single source of truth) with the real state path baked in. Use
|
|
350
|
+
// generatePluginCode({ standalone: true }) for npm-less environments.
|
|
351
|
+
await new OpenCodeAdapter().savePluginCode(pluginAbs, stateAbs, { maxHistoryMessages: maxHistory });
|
|
352
|
+
}
|
|
353
|
+
say(`plugin: ${pluginAbs} (auto-loaded from plugins/)`);
|
|
354
|
+
manifest.pluginPath = pluginAbs;
|
|
355
|
+
}
|
|
356
|
+
if (!flags.noSkill) {
|
|
357
|
+
const skillAbs = path.join(skillDirFor(host, home), 'SKILL.md');
|
|
358
|
+
if (!dry) {
|
|
359
|
+
await atomicWriteFile(skillAbs, buildSkillMd(relativeStatePath(cwd, stateAbs), spec));
|
|
360
|
+
}
|
|
361
|
+
say(`skill: ${skillAbs}`);
|
|
362
|
+
manifest.skillPath = skillAbs;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
say('skill: skipped (--no-skill)');
|
|
366
|
+
}
|
|
367
|
+
if (flags.noMcp) {
|
|
368
|
+
say('mcp: skipped (--no-mcp)');
|
|
369
|
+
}
|
|
370
|
+
else if (host === 'opencode') {
|
|
371
|
+
const configPath = resolveOpencodeConfig(home);
|
|
372
|
+
let text;
|
|
373
|
+
try {
|
|
374
|
+
text = fs.readFileSync(configPath, 'utf-8');
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
text = '{\n}\n';
|
|
378
|
+
}
|
|
379
|
+
const result = addSkillstateMcp(text, buildMcpEntry(stateAbs));
|
|
380
|
+
if (result.changed) {
|
|
381
|
+
const backup = backupPathFor(configPath);
|
|
382
|
+
if (!dry) {
|
|
383
|
+
await atomicWriteFile(backup, text);
|
|
384
|
+
await atomicWriteFile(configPath, result.text);
|
|
385
|
+
}
|
|
386
|
+
say(`mcp: ${configPath} (skillstate server added)`);
|
|
387
|
+
say(`mcp backup: ${backup}`);
|
|
388
|
+
manifest.mcp = { configPath, format: 'opencode-jsonc' };
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
say(`mcp: ${configPath} (skillstate already registered)`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
else if (host === 'claude') {
|
|
395
|
+
const mcpJson = path.join(cwd, '.mcp.json');
|
|
396
|
+
let doc = {};
|
|
397
|
+
if (fs.existsSync(mcpJson)) {
|
|
398
|
+
try {
|
|
399
|
+
doc = JSON.parse(fs.readFileSync(mcpJson, 'utf-8'));
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
doc = {};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (!isRecord(doc.mcpServers) || doc.mcpServers['skillstate'] === undefined) {
|
|
406
|
+
const servers = isRecord(doc.mcpServers) ? doc.mcpServers : {};
|
|
407
|
+
const backup = fs.existsSync(mcpJson) ? backupPathFor(mcpJson) : null;
|
|
408
|
+
if (!dry) {
|
|
409
|
+
if (backup !== null) {
|
|
410
|
+
await atomicWriteFile(backup, fs.readFileSync(mcpJson, 'utf-8'));
|
|
411
|
+
}
|
|
412
|
+
await atomicWriteFile(mcpJson, `${JSON.stringify({ mcpServers: { ...servers, skillstate: buildMcpEntry(stateAbs) } }, null, 2)}\n`);
|
|
413
|
+
}
|
|
414
|
+
say(`mcp: ${mcpJson} (skillstate server added)`);
|
|
415
|
+
manifest.mcp = { configPath: mcpJson, format: 'claude-mcp-json' };
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
say(`mcp: ${mcpJson} (skillstate already registered)`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
say('mcp: skipped (codex has no JSON MCP config; register the server manually if needed)');
|
|
423
|
+
}
|
|
424
|
+
const manifestAbs = path.join(stateDir, MANIFEST_FILE_NAME);
|
|
425
|
+
if (!dry) {
|
|
426
|
+
await atomicWriteFile(manifestAbs, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
427
|
+
}
|
|
428
|
+
say(`manifest: ${manifestAbs}`);
|
|
429
|
+
say(dry ? 'dry run complete — nothing was written.' : 'Done. Next: `skillstate run` in this project, then open your host.');
|
|
430
|
+
return 0;
|
|
431
|
+
}
|
|
432
|
+
/** State path as the SKILL.md should reference it: relative when inside cwd, absolute otherwise. */
|
|
433
|
+
function relativeStatePath(cwd, stateAbs) {
|
|
434
|
+
const rel = path.relative(cwd, stateAbs);
|
|
435
|
+
return rel.startsWith('..') ? stateAbs : `./${rel}`;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Roll back exactly what an install recorded in the manifest: plugin file,
|
|
439
|
+
* SKILL.md, `mcp.skillstate` entry (with a config backup), and optionally
|
|
440
|
+
* the whole state directory. Returns a process exit code (0 ok, 1 no/manifest
|
|
441
|
+
* unreadable).
|
|
442
|
+
*/
|
|
443
|
+
export async function uninstall(options) {
|
|
444
|
+
const { cwd, flags } = options;
|
|
445
|
+
const dry = flags.dryRun;
|
|
446
|
+
const say = (line) => {
|
|
447
|
+
console.log(dry ? `[dry-run] ${line}` : line);
|
|
448
|
+
};
|
|
449
|
+
const stateDir = flags.stateDir !== undefined ? resolveInCwd(cwd, flags.stateDir) : path.join(cwd, STATE_DIR_NAME);
|
|
450
|
+
const manifestAbs = path.join(stateDir, MANIFEST_FILE_NAME);
|
|
451
|
+
let raw;
|
|
452
|
+
try {
|
|
453
|
+
raw = fs.readFileSync(manifestAbs, 'utf-8');
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
console.error(`No install manifest at ${manifestAbs} — nothing to uninstall.`);
|
|
457
|
+
return 1;
|
|
458
|
+
}
|
|
459
|
+
let manifest;
|
|
460
|
+
try {
|
|
461
|
+
manifest = JSON.parse(raw);
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
console.error(`Corrupt install manifest at ${manifestAbs}`);
|
|
465
|
+
return 1;
|
|
466
|
+
}
|
|
467
|
+
if (!isRecord(manifest) ||
|
|
468
|
+
manifest['version'] !== 1 ||
|
|
469
|
+
typeof manifest['host'] !== 'string' ||
|
|
470
|
+
typeof manifest['statePath'] !== 'string') {
|
|
471
|
+
console.error(`Corrupt install manifest at ${manifestAbs}`);
|
|
472
|
+
return 1;
|
|
473
|
+
}
|
|
474
|
+
const m = manifest;
|
|
475
|
+
say(`uninstall (${m.host})`);
|
|
476
|
+
if (m.pluginPath !== undefined && fs.existsSync(m.pluginPath)) {
|
|
477
|
+
if (!dry) {
|
|
478
|
+
fs.rmSync(m.pluginPath);
|
|
479
|
+
}
|
|
480
|
+
say(`removed plugin: ${m.pluginPath}`);
|
|
481
|
+
}
|
|
482
|
+
if (m.skillPath !== undefined && fs.existsSync(m.skillPath)) {
|
|
483
|
+
if (!dry) {
|
|
484
|
+
fs.rmSync(m.skillPath);
|
|
485
|
+
}
|
|
486
|
+
say(`removed skill: ${m.skillPath}`);
|
|
487
|
+
}
|
|
488
|
+
if (m.mcp !== undefined && fs.existsSync(m.mcp.configPath)) {
|
|
489
|
+
const configPath = m.mcp.configPath;
|
|
490
|
+
if (m.mcp.format === 'claude-mcp-json') {
|
|
491
|
+
try {
|
|
492
|
+
const doc = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
493
|
+
if (isRecord(doc.mcpServers) && doc.mcpServers['skillstate'] !== undefined) {
|
|
494
|
+
const { ['skillstate']: _removed, ...rest } = doc.mcpServers;
|
|
495
|
+
const backup = backupPathFor(configPath);
|
|
496
|
+
if (!dry) {
|
|
497
|
+
await atomicWriteFile(backup, fs.readFileSync(configPath, 'utf-8'));
|
|
498
|
+
await atomicWriteFile(configPath, `${JSON.stringify({ mcpServers: rest }, null, 2)}\n`);
|
|
499
|
+
}
|
|
500
|
+
say(`removed mcp entry: ${configPath} (backup: ${backup})`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
console.error(`Skipping mcp: ${configPath} is unreadable`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
const text = fs.readFileSync(configPath, 'utf-8');
|
|
509
|
+
const result = removeSkillstateMcp(text);
|
|
510
|
+
if (result.changed) {
|
|
511
|
+
const backup = backupPathFor(configPath);
|
|
512
|
+
if (!dry) {
|
|
513
|
+
await atomicWriteFile(backup, text);
|
|
514
|
+
await atomicWriteFile(configPath, result.text);
|
|
515
|
+
}
|
|
516
|
+
say(`removed mcp entry: ${configPath} (backup: ${backup})`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (dry) {
|
|
521
|
+
say('dry run complete — nothing was written.');
|
|
522
|
+
return 0;
|
|
523
|
+
}
|
|
524
|
+
if (flags.removeState) {
|
|
525
|
+
fs.rmSync(stateDir, { recursive: true, force: true });
|
|
526
|
+
say(`removed state dir: ${stateDir}`);
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
fs.rmSync(manifestAbs, { force: true });
|
|
530
|
+
say(`kept state: ${stateDir} (use --remove-state to delete)`);
|
|
531
|
+
}
|
|
532
|
+
say('Uninstalled.');
|
|
533
|
+
return 0;
|
|
534
|
+
}
|
|
535
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/dist/jsonc.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** One `"key": <value>` entry inside a scanned object. */
|
|
2
|
+
export interface JsoncEntry {
|
|
3
|
+
key: string;
|
|
4
|
+
/** Index of the opening quote of the key. */
|
|
5
|
+
entryStart: number;
|
|
6
|
+
/** Index just past the value's trailing comma (when present). */
|
|
7
|
+
entryEnd: number;
|
|
8
|
+
/** Index of the first char of the value. */
|
|
9
|
+
valueStart: number;
|
|
10
|
+
/** Index just past the value's last char. */
|
|
11
|
+
valueEnd: number;
|
|
12
|
+
}
|
|
13
|
+
/** Span of a `{ ... }` object in JSONC text. */
|
|
14
|
+
export interface JsoncObjectSpan {
|
|
15
|
+
braceStart: number;
|
|
16
|
+
braceEnd: number;
|
|
17
|
+
entries: JsoncEntry[];
|
|
18
|
+
}
|
|
19
|
+
/** Result of an in-place entry insertion/removal. */
|
|
20
|
+
export interface JsoncEditResult {
|
|
21
|
+
text: string;
|
|
22
|
+
changed: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Skip whitespace and line/block comments starting at `i`. */
|
|
25
|
+
export declare function skipWsAndComments(text: string, i: number): number;
|
|
26
|
+
/** Scan the object whose `{` sits at `objStart` into a span with entry positions. */
|
|
27
|
+
export declare function scanObject(text: string, objStart: number): JsoncObjectSpan;
|
|
28
|
+
/** Span of the document's root object, or null when the root is not an object. */
|
|
29
|
+
export declare function findTopLevelObject(text: string): JsoncObjectSpan | null;
|
|
30
|
+
/** Strip line/block comments and trailing commas so `JSON.parse` can read the rest. */
|
|
31
|
+
export declare function stripJsonc(text: string): string;
|
|
32
|
+
/** Parse JSONC text (comments + trailing commas tolerated) via JSON.parse. */
|
|
33
|
+
export declare function parseJsonc(text: string): unknown;
|
|
34
|
+
/**
|
|
35
|
+
* Splice one `"key": <valueJson>` entry into the object at `objStart`,
|
|
36
|
+
* preserving all surrounding text (comments included). Idempotent: when the
|
|
37
|
+
* key already exists the text is returned unchanged.
|
|
38
|
+
*/
|
|
39
|
+
export declare function insertObjectEntry(text: string, objStart: number, key: string, valueJson: string): JsoncEditResult;
|
|
40
|
+
/**
|
|
41
|
+
* Splice the `"key"` entry out of the object at `objStart`, keeping the rest
|
|
42
|
+
* valid (the entry's trailing comma, or the previous entry's comma for a last
|
|
43
|
+
* entry, goes with it). Idempotent: a missing key returns the text unchanged.
|
|
44
|
+
*/
|
|
45
|
+
export declare function removeObjectEntry(text: string, objStart: number, key: string): JsoncEditResult;
|
|
46
|
+
//# sourceMappingURL=jsonc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../src/jsonc.ts"],"names":[],"mappings":"AAUA,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAqBjE;AAuDD,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CA6B1E;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAMvE;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkC/C;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AA4BD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,eAAe,CAoBjB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,GACV,eAAe,CAqBjB"}
|