agent-relay 9.1.4 → 9.1.6
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/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +4 -0
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/commands/integration.d.ts +38 -0
- package/dist/cli/commands/integration.d.ts.map +1 -1
- package/dist/cli/commands/integration.js +347 -4
- package/dist/cli/commands/integration.js.map +1 -1
- package/dist/cli/commands/reflex.d.ts +20 -0
- package/dist/cli/commands/reflex.d.ts.map +1 -0
- package/dist/cli/commands/reflex.js +192 -0
- package/dist/cli/commands/reflex.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +22 -0
- package/dist/cli/commands/skills.d.ts.map +1 -0
- package/dist/cli/commands/skills.js +147 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/lib/skills-install.d.ts +97 -0
- package/dist/cli/lib/skills-install.d.ts.map +1 -0
- package/dist/cli/lib/skills-install.js +182 -0
- package/dist/cli/lib/skills-install.js.map +1 -0
- package/dist/cli/lib/skills-tui.d.ts +31 -0
- package/dist/cli/lib/skills-tui.d.ts.map +1 -0
- package/dist/cli/lib/skills-tui.js +165 -0
- package/dist/cli/lib/skills-tui.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { chmod, mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import readline from 'node:readline';
|
|
6
|
+
const ALLOWED_RELAYHISTORY_HOSTS = new Set(['history.agentrelay.com']);
|
|
7
|
+
function validateRelayhistoryBaseUrl(raw) {
|
|
8
|
+
let parsed;
|
|
9
|
+
try {
|
|
10
|
+
parsed = new URL(raw);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return { ok: false, error: `AI_HIST_BASE_URL is not a valid URL: ${raw}` };
|
|
14
|
+
}
|
|
15
|
+
const isLocalDev = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1' || parsed.hostname === '::1';
|
|
16
|
+
if (!isLocalDev && !ALLOWED_RELAYHISTORY_HOSTS.has(parsed.hostname)) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
error: `AI_HIST_BASE_URL hostname "${parsed.hostname}" is not an allowed relayhistory host`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return { ok: true, url: parsed };
|
|
23
|
+
}
|
|
24
|
+
function promptYesNo(question) {
|
|
25
|
+
if (!process.stdin.isTTY) {
|
|
26
|
+
return Promise.resolve(false);
|
|
27
|
+
}
|
|
28
|
+
const rl = readline.createInterface({
|
|
29
|
+
input: process.stdin,
|
|
30
|
+
output: process.stdout,
|
|
31
|
+
});
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
rl.question(question, (answer) => {
|
|
34
|
+
rl.close();
|
|
35
|
+
const normalized = answer.trim().toLowerCase();
|
|
36
|
+
resolve(normalized === 'y' || normalized === 'yes');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async function defaultReadRelayAuth() {
|
|
41
|
+
const { readStoredAuth } = await import('@agent-relay/cloud');
|
|
42
|
+
return readStoredAuth();
|
|
43
|
+
}
|
|
44
|
+
async function defaultLoginToCloud(relayAccessToken) {
|
|
45
|
+
const rawBase = process.env.AI_HIST_BASE_URL ?? 'https://history.agentrelay.com';
|
|
46
|
+
const validated = validateRelayhistoryBaseUrl(rawBase);
|
|
47
|
+
if (!validated.ok) {
|
|
48
|
+
return { ok: false, error: validated.error };
|
|
49
|
+
}
|
|
50
|
+
const url = `${rawBase.replace(/\/$/, '')}/v1/cli/login`;
|
|
51
|
+
let resp;
|
|
52
|
+
try {
|
|
53
|
+
resp = await fetch(url, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: { 'Content-Type': 'application/json' },
|
|
56
|
+
body: JSON.stringify({ agentRelayToken: relayAccessToken }),
|
|
57
|
+
signal: AbortSignal.timeout(15_000),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
return { ok: false, error: `Network error: ${err instanceof Error ? err.message : String(err)}` };
|
|
62
|
+
}
|
|
63
|
+
if (!resp.ok) {
|
|
64
|
+
const text = await resp.text().catch(() => '');
|
|
65
|
+
return { ok: false, error: `Login failed (HTTP ${resp.status}): ${text.slice(0, 200)}` };
|
|
66
|
+
}
|
|
67
|
+
let payload;
|
|
68
|
+
try {
|
|
69
|
+
const raw = await resp.json();
|
|
70
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
71
|
+
return { ok: false, error: 'Login response has unexpected shape' };
|
|
72
|
+
}
|
|
73
|
+
payload = raw;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return { ok: false, error: 'Login response was not valid JSON' };
|
|
77
|
+
}
|
|
78
|
+
if (typeof payload.accessToken !== 'string') {
|
|
79
|
+
return { ok: false, error: 'Login response missing accessToken' };
|
|
80
|
+
}
|
|
81
|
+
// Persist rth_at_ tokens so ai-hist sync/push can authenticate on subsequent runs.
|
|
82
|
+
try {
|
|
83
|
+
const configDir = process.env.AI_HIST_CONFIG_DIR ?? path.join(os.homedir(), '.config', 'ai-hist');
|
|
84
|
+
const authPath = path.join(configDir, 'auth.json');
|
|
85
|
+
const auth = {
|
|
86
|
+
baseUrl: rawBase.replace(/\/$/, ''),
|
|
87
|
+
accessToken: payload.accessToken,
|
|
88
|
+
...(typeof payload.refreshToken === 'string' ? { refreshToken: payload.refreshToken } : {}),
|
|
89
|
+
};
|
|
90
|
+
await mkdir(configDir, { recursive: true });
|
|
91
|
+
await writeFile(authPath, JSON.stringify(auth, null, 2));
|
|
92
|
+
// Explicitly tighten perms — writeFile mode only applies to newly created files.
|
|
93
|
+
await chmod(authPath, 0o600);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Non-fatal: local state is written; cloud sync may prompt again next run.
|
|
97
|
+
}
|
|
98
|
+
return { ok: true };
|
|
99
|
+
}
|
|
100
|
+
function withDefaults(overrides = {}) {
|
|
101
|
+
return {
|
|
102
|
+
fs,
|
|
103
|
+
homedir: os.homedir,
|
|
104
|
+
readRelayAuth: defaultReadRelayAuth,
|
|
105
|
+
loginToCloud: defaultLoginToCloud,
|
|
106
|
+
prompt: promptYesNo,
|
|
107
|
+
log: (...args) => console.log(...args),
|
|
108
|
+
...overrides,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function getReflexDir(deps) {
|
|
112
|
+
return path.join(deps.homedir(), '.agentworkforce');
|
|
113
|
+
}
|
|
114
|
+
function getReflexStateFile(deps) {
|
|
115
|
+
return path.join(getReflexDir(deps), 'reflex.json');
|
|
116
|
+
}
|
|
117
|
+
function writeReflexState(deps, state) {
|
|
118
|
+
deps.fs.mkdirSync(getReflexDir(deps), { recursive: true });
|
|
119
|
+
deps.fs.writeFileSync(getReflexStateFile(deps), JSON.stringify(state, null, 2), 'utf-8');
|
|
120
|
+
}
|
|
121
|
+
function readReflexState(deps) {
|
|
122
|
+
const stateFile = getReflexStateFile(deps);
|
|
123
|
+
if (!deps.fs.existsSync(stateFile)) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
return JSON.parse(deps.fs.readFileSync(stateFile, 'utf-8'));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export function registerReflexCommands(program, overrides = {}) {
|
|
134
|
+
const deps = withDefaults(overrides);
|
|
135
|
+
const reflex = program.command('reflex').description('Manage Reflex history sync');
|
|
136
|
+
reflex
|
|
137
|
+
.command('on')
|
|
138
|
+
.description('Enable Reflex history sync')
|
|
139
|
+
.action(async () => {
|
|
140
|
+
deps.log('Reflex will capture your agent sessions and sync to history.agentrelay.com');
|
|
141
|
+
const accepted = await deps.prompt('Enable Reflex? (y/N) ');
|
|
142
|
+
if (!accepted) {
|
|
143
|
+
deps.log('Reflex was not enabled.');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
writeReflexState(deps, {
|
|
147
|
+
enabled: true,
|
|
148
|
+
enabledAt: new Date().toISOString(),
|
|
149
|
+
});
|
|
150
|
+
const relayAuth = await deps.readRelayAuth();
|
|
151
|
+
if (!relayAuth) {
|
|
152
|
+
deps.log('Not logged in to Agent Relay. Run `agent-relay login` first to sync Reflex history to the cloud.');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const result = await deps.loginToCloud(relayAuth.accessToken);
|
|
156
|
+
if (!result.ok) {
|
|
157
|
+
deps.log(`Reflex is enabled locally, but cloud login did not complete: ${result.error}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
deps.log('Reflex is on.');
|
|
161
|
+
deps.log('State file: ~/.agentworkforce/reflex.json');
|
|
162
|
+
});
|
|
163
|
+
reflex
|
|
164
|
+
.command('off')
|
|
165
|
+
.description('Disable Reflex history sync')
|
|
166
|
+
.action(() => {
|
|
167
|
+
writeReflexState(deps, { enabled: false });
|
|
168
|
+
deps.log('Reflex is off.');
|
|
169
|
+
});
|
|
170
|
+
reflex
|
|
171
|
+
.command('status')
|
|
172
|
+
.description('Show Reflex status')
|
|
173
|
+
.action(() => {
|
|
174
|
+
const state = readReflexState(deps);
|
|
175
|
+
if (!state) {
|
|
176
|
+
deps.log('Reflex is off (never enabled).');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (state.enabled) {
|
|
180
|
+
deps.log('Reflex is on.');
|
|
181
|
+
if (state.enabledAt) {
|
|
182
|
+
deps.log(`Enabled at: ${state.enabledAt}`);
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
deps.log('Reflex is off.');
|
|
187
|
+
if (state.enabledAt) {
|
|
188
|
+
deps.log(`Enabled at: ${state.enabledAt}`);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=reflex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflex.js","sourceRoot":"","sources":["../../../src/cli/commands/reflex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { parseSkill, type HarnessTarget, type InstallResult, type SkillScope, type TargetContext } from '../lib/skills-install.js';
|
|
3
|
+
type ExitFn = (code: number) => never;
|
|
4
|
+
/** The plan resolved either interactively or from flags. */
|
|
5
|
+
interface SkillPlan {
|
|
6
|
+
scope: SkillScope;
|
|
7
|
+
harnesses: HarnessTarget[];
|
|
8
|
+
}
|
|
9
|
+
export interface SkillsDependencies {
|
|
10
|
+
fetchSkill: (url: string) => Promise<string>;
|
|
11
|
+
promptScope: () => Promise<SkillScope | null>;
|
|
12
|
+
promptHarnesses: (harnesses: HarnessTarget[]) => Promise<string[] | null>;
|
|
13
|
+
getContext: () => TargetContext;
|
|
14
|
+
isInteractive: () => boolean;
|
|
15
|
+
install: (skill: ReturnType<typeof parseSkill>, plan: SkillPlan, ctx: TargetContext) => InstallResult[];
|
|
16
|
+
log: (...args: unknown[]) => void;
|
|
17
|
+
error: (...args: unknown[]) => void;
|
|
18
|
+
exit: ExitFn;
|
|
19
|
+
}
|
|
20
|
+
export declare function registerSkillsCommands(program: Command, overrides?: Partial<SkillsDependencies>): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,EAOL,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAC;AAGlC,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;AAEtC,4DAA4D;AAC5D,UAAU,SAAS;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,WAAW,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC9C,eAAe,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1E,UAAU,EAAE,MAAM,aAAa,CAAC;IAChC,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,KAAK,aAAa,EAAE,CAAC;IACxG,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AA4HD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAAG,IAAI,CAsC1G"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { getProjectPaths } from '@agent-relay/config';
|
|
2
|
+
import { defaultExit } from '../lib/exit.js';
|
|
3
|
+
import { HARNESS_TARGETS, ORCHESTRATE_SKILL, defaultTargetContext, fetchSkill, findHarnessTarget, installSkill, parseSkill, } from '../lib/skills-install.js';
|
|
4
|
+
import { selectHarnesses, selectScope } from '../lib/skills-tui.js';
|
|
5
|
+
function resolveProjectRoot() {
|
|
6
|
+
// `getProjectPaths()` resolves the nearest project root and otherwise falls
|
|
7
|
+
// back to the cwd; the try/catch is defensive so a global install can never
|
|
8
|
+
// be blocked by project resolution from outside an Agent Relay project.
|
|
9
|
+
try {
|
|
10
|
+
const paths = getProjectPaths();
|
|
11
|
+
return paths.projectRoot ?? process.cwd();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return process.cwd();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function withDefaults(overrides = {}) {
|
|
18
|
+
return {
|
|
19
|
+
fetchSkill,
|
|
20
|
+
promptScope: () => selectScope(),
|
|
21
|
+
promptHarnesses: (harnesses) => selectHarnesses(harnesses),
|
|
22
|
+
getContext: () => defaultTargetContext(resolveProjectRoot()),
|
|
23
|
+
isInteractive: () => Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
24
|
+
install: (skill, plan, ctx) => installSkill({ skill, scope: plan.scope, harnesses: plan.harnesses, ctx }),
|
|
25
|
+
log: (...args) => console.log(...args),
|
|
26
|
+
error: (...args) => console.error(...args),
|
|
27
|
+
exit: defaultExit,
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Parse `--harness a,b` into a deduped list of ids. */
|
|
32
|
+
function parseHarnessFlag(raw) {
|
|
33
|
+
if (!raw)
|
|
34
|
+
return [];
|
|
35
|
+
return [
|
|
36
|
+
...new Set(raw
|
|
37
|
+
.split(',')
|
|
38
|
+
.map((s) => s.trim().toLowerCase())
|
|
39
|
+
.filter(Boolean)),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
/** Resolve scope from flags, or null when it must be asked interactively. */
|
|
43
|
+
function scopeFromFlags(opts, deps) {
|
|
44
|
+
if (opts.global && opts.local) {
|
|
45
|
+
deps.error('Choose only one of --global or --local.');
|
|
46
|
+
deps.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (opts.global)
|
|
49
|
+
return 'global';
|
|
50
|
+
if (opts.local)
|
|
51
|
+
return 'project';
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/** Resolve harness targets from flags, or null when they must be asked. */
|
|
55
|
+
function harnessesFromFlags(opts, deps) {
|
|
56
|
+
if (opts.all)
|
|
57
|
+
return [...HARNESS_TARGETS];
|
|
58
|
+
const ids = parseHarnessFlag(opts.harness);
|
|
59
|
+
if (ids.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
const resolved = [];
|
|
62
|
+
for (const id of ids) {
|
|
63
|
+
const target = findHarnessTarget(id);
|
|
64
|
+
if (!target) {
|
|
65
|
+
deps.error(`Unknown harness "${id}". Known harnesses: ${HARNESS_TARGETS.map((t) => t.id).join(', ')}.`);
|
|
66
|
+
deps.exit(1);
|
|
67
|
+
}
|
|
68
|
+
resolved.push(target);
|
|
69
|
+
}
|
|
70
|
+
return resolved;
|
|
71
|
+
}
|
|
72
|
+
async function resolvePlan(opts, deps) {
|
|
73
|
+
let scope = scopeFromFlags(opts, deps);
|
|
74
|
+
let harnesses = harnessesFromFlags(opts, deps);
|
|
75
|
+
const needsPrompt = scope === null || harnesses === null;
|
|
76
|
+
if (needsPrompt && !deps.isInteractive()) {
|
|
77
|
+
deps.error('Non-interactive terminal: specify the scope and harnesses with flags, e.g.\n' +
|
|
78
|
+
' agent-relay skills add --global --harness claude,codex\n' +
|
|
79
|
+
' agent-relay skills add --local --all');
|
|
80
|
+
deps.exit(1);
|
|
81
|
+
}
|
|
82
|
+
if (scope === null) {
|
|
83
|
+
scope = await deps.promptScope();
|
|
84
|
+
if (scope === null)
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
if (harnesses === null) {
|
|
88
|
+
const ids = await deps.promptHarnesses([...HARNESS_TARGETS]);
|
|
89
|
+
if (ids === null || ids.length === 0)
|
|
90
|
+
return null;
|
|
91
|
+
harnesses = ids.map((id) => findHarnessTarget(id)).filter((t) => Boolean(t));
|
|
92
|
+
}
|
|
93
|
+
return { scope, harnesses };
|
|
94
|
+
}
|
|
95
|
+
function reportResults(results, deps) {
|
|
96
|
+
const ok = results.filter((r) => r.status !== 'failed');
|
|
97
|
+
const failed = results.filter((r) => r.status === 'failed');
|
|
98
|
+
for (const r of ok) {
|
|
99
|
+
const verb = r.status === 'overwritten' ? 'Updated' : 'Installed';
|
|
100
|
+
deps.log(` \x1b[32m✓\x1b[0m ${verb} ${r.label} → ${r.path}`);
|
|
101
|
+
}
|
|
102
|
+
for (const r of failed) {
|
|
103
|
+
deps.error(` \x1b[31m✗\x1b[0m ${r.label} → ${r.path}: ${r.error}`);
|
|
104
|
+
}
|
|
105
|
+
if (ok.length > 0) {
|
|
106
|
+
deps.log('');
|
|
107
|
+
deps.log(`/${ORCHESTRATE_SKILL.slug} is ready in ${ok.length} harness${ok.length === 1 ? '' : 'es'}.`);
|
|
108
|
+
}
|
|
109
|
+
return failed.length > 0 ? 1 : 0;
|
|
110
|
+
}
|
|
111
|
+
export function registerSkillsCommands(program, overrides = {}) {
|
|
112
|
+
const deps = withDefaults(overrides);
|
|
113
|
+
const group = program
|
|
114
|
+
.command('skills')
|
|
115
|
+
.description('Install Agent Relay skills into your coding harnesses');
|
|
116
|
+
group
|
|
117
|
+
.command('add')
|
|
118
|
+
.description(`Install the /${ORCHESTRATE_SKILL.slug} skill into one or more harnesses`)
|
|
119
|
+
.option('-g, --global', 'Install into your global (home) config')
|
|
120
|
+
.option('-l, --local', 'Install into the current project')
|
|
121
|
+
.option('--harness <ids>', 'Comma-separated harness ids (claude, codex, cursor, gemini, opencode)')
|
|
122
|
+
.option('--all', 'Install into every supported harness')
|
|
123
|
+
.action(async (opts) => {
|
|
124
|
+
const plan = await resolvePlan(opts, deps);
|
|
125
|
+
if (!plan) {
|
|
126
|
+
deps.log('Cancelled. Nothing was installed.');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
let raw;
|
|
130
|
+
try {
|
|
131
|
+
raw = await deps.fetchSkill(ORCHESTRATE_SKILL.url);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
deps.error(err instanceof Error ? err.message : String(err));
|
|
135
|
+
deps.exit(1);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const skill = parseSkill(raw);
|
|
139
|
+
const ctx = deps.getContext();
|
|
140
|
+
deps.log(`Installing /${ORCHESTRATE_SKILL.slug} (${plan.scope === 'global' ? 'global' : 'this project'})…`);
|
|
141
|
+
const results = deps.install(skill, plan, ctx);
|
|
142
|
+
const code = reportResults(results, deps);
|
|
143
|
+
if (code !== 0)
|
|
144
|
+
deps.exit(code);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/cli/commands/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core logic for `agent-relay skills add` — fetching a published skill and
|
|
3
|
+
* installing it into the right per-harness directory for either the current
|
|
4
|
+
* project or the user's global config.
|
|
5
|
+
*
|
|
6
|
+
* This module is deliberately free of any interactive/TTY concerns so it can
|
|
7
|
+
* be unit-tested in isolation. The TUI lives in `./skills-tui.ts` and the
|
|
8
|
+
* command wiring in `../commands/skills.ts`.
|
|
9
|
+
*/
|
|
10
|
+
/** Where a skill is installed: into the current project or the user's home. */
|
|
11
|
+
export type SkillScope = 'project' | 'global';
|
|
12
|
+
/** The `/orchestrate` skill published at agentrelay.com. */
|
|
13
|
+
export declare const ORCHESTRATE_SKILL: {
|
|
14
|
+
/** Slug used for the installed file/directory name (the slash command). */
|
|
15
|
+
readonly slug: "orchestrate";
|
|
16
|
+
/** Canonical source of the skill markdown. */
|
|
17
|
+
readonly url: "https://agentrelay.com/skill.md";
|
|
18
|
+
};
|
|
19
|
+
/** A skill split into its YAML frontmatter fields and markdown body. */
|
|
20
|
+
export interface ParsedSkill {
|
|
21
|
+
/** Raw, unmodified source (frontmatter + body). */
|
|
22
|
+
raw: string;
|
|
23
|
+
/** `name:` from frontmatter, if present. */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** `description:` from frontmatter, if present. */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** Markdown body with the leading frontmatter block removed. */
|
|
28
|
+
body: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse a skill markdown document, extracting `name`/`description` from the
|
|
32
|
+
* leading `---` YAML frontmatter block (if any) and the body that follows.
|
|
33
|
+
* Tolerant by design: a document with no frontmatter yields `body === raw`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseSkill(raw: string): ParsedSkill;
|
|
36
|
+
/** Resolution context handed to each harness target. */
|
|
37
|
+
export interface TargetContext {
|
|
38
|
+
projectRoot: string;
|
|
39
|
+
homeDir: string;
|
|
40
|
+
}
|
|
41
|
+
/** A coding harness we know how to install a skill into. */
|
|
42
|
+
export interface HarnessTarget {
|
|
43
|
+
/** Stable id, matches the CLI registry (`claude`, `codex`, …). */
|
|
44
|
+
id: string;
|
|
45
|
+
/** Human-friendly label shown in the TUI. */
|
|
46
|
+
label: string;
|
|
47
|
+
/** Absolute file path the skill is written to for the given scope. */
|
|
48
|
+
resolvePath: (scope: SkillScope, ctx: TargetContext) => string;
|
|
49
|
+
/** Render the on-disk content for this harness from the parsed skill. */
|
|
50
|
+
render: (skill: ParsedSkill, slug: string) => string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The set of harnesses `skills add` can target. Each maps the skill onto the
|
|
54
|
+
* harness's native custom-command / skill convention.
|
|
55
|
+
*/
|
|
56
|
+
export declare const HARNESS_TARGETS: HarnessTarget[];
|
|
57
|
+
/** Look up a harness target by id. */
|
|
58
|
+
export declare function findHarnessTarget(id: string): HarnessTarget | undefined;
|
|
59
|
+
/** Default resolution context: real project root + home directory. */
|
|
60
|
+
export declare function defaultTargetContext(projectRoot: string): TargetContext;
|
|
61
|
+
/** Outcome of installing into a single harness. */
|
|
62
|
+
export interface InstallResult {
|
|
63
|
+
harnessId: string;
|
|
64
|
+
label: string;
|
|
65
|
+
path: string;
|
|
66
|
+
status: 'installed' | 'overwritten' | 'failed';
|
|
67
|
+
error?: string;
|
|
68
|
+
}
|
|
69
|
+
/** Side-effecting writer, injected so tests can capture without touching disk. */
|
|
70
|
+
export interface SkillWriter {
|
|
71
|
+
exists: (filePath: string) => boolean;
|
|
72
|
+
write: (filePath: string, content: string) => void;
|
|
73
|
+
}
|
|
74
|
+
/** Default writer: mkdir -p the parent and write the file. */
|
|
75
|
+
export declare const fsWriter: SkillWriter;
|
|
76
|
+
/**
|
|
77
|
+
* Install the skill into each requested harness for the given scope.
|
|
78
|
+
* Never throws for a single-harness failure — it is recorded in the result so
|
|
79
|
+
* the caller can report a partial success.
|
|
80
|
+
*/
|
|
81
|
+
export declare function installSkill(opts: {
|
|
82
|
+
skill: ParsedSkill;
|
|
83
|
+
scope: SkillScope;
|
|
84
|
+
harnesses: HarnessTarget[];
|
|
85
|
+
ctx: TargetContext;
|
|
86
|
+
writer?: SkillWriter;
|
|
87
|
+
slug?: string;
|
|
88
|
+
}): InstallResult[];
|
|
89
|
+
/** Default time budget for the skill download before it is aborted. */
|
|
90
|
+
export declare const FETCH_SKILL_TIMEOUT_MS = 15000;
|
|
91
|
+
/**
|
|
92
|
+
* Fetch the published skill markdown over HTTPS. Bounded by an abort timeout so
|
|
93
|
+
* a stalled connection can't hang `skills add` (notably in CI). Throws a clear
|
|
94
|
+
* error on timeout or a non-2xx response so the command can surface it.
|
|
95
|
+
*/
|
|
96
|
+
export declare function fetchSkill(url?: string, timeoutMs?: number): Promise<string>;
|
|
97
|
+
//# sourceMappingURL=skills-install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-install.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/skills-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9C,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB;IAC5B,2EAA2E;;IAE3E,8CAA8C;;CAEtC,CAAC;AAEX,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAYnD;AASD,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,KAAK,MAAM,CAAC;IAC/D,yEAAyE;IACzE,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACtD;AAOD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EAwE1C,CAAC;AAMF,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEvE;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAEvE;AAED,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,8DAA8D;AAC9D,eAAO,MAAM,QAAQ,EAAE,WAMtB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,GAAG,EAAE,aAAa,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,aAAa,EAAE,CAwBlB;AAED,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAA8B,EACnC,SAAS,GAAE,MAA+B,GACzC,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
|