@constraint/cli 0.3.2 → 0.3.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
CHANGED
|
@@ -55,9 +55,11 @@ Or target agents explicitly:
|
|
|
55
55
|
constraint setup --agent codex --agent claude-code
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
Setup
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
Setup presents two separate stages: first it offers to add a marked Constraint
|
|
59
|
+
block to each agent's global instructions, then it shows the global destination
|
|
60
|
+
and installs the `constraint-skills` companion using the regular install-plan
|
|
61
|
+
flow. Existing `AGENTS.md` and `CLAUDE.md` content outside that block is
|
|
62
|
+
preserved.
|
|
61
63
|
|
|
62
64
|
Preview the instruction change without applying it:
|
|
63
65
|
|
package/package.json
CHANGED
|
@@ -1,44 +1,71 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: constraint-skills
|
|
3
|
-
description:
|
|
3
|
+
description: Operate governed Agent Skills with the Constraint terminal CLI and report their invocations. Use when an agent needs to authenticate or diagnose Constraint access; configure agents; discover upload domains; inspect, install, update, or upload skills; query run history; or invoke any skill installed from or governed by Constraint.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Constraint Skills
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Use the `constraint` command for organization-authorized skills. Do not edit its config, lockfiles, instruction blocks, installation receipts, or authorization tokens directly.
|
|
9
|
+
|
|
10
|
+
## Choose the operation
|
|
11
|
+
|
|
12
|
+
- Authenticate or diagnose: `constraint login`, `constraint whoami`, `constraint doctor`.
|
|
13
|
+
- Configure agents: `constraint setup`.
|
|
14
|
+
- Discover or inspect skills: `constraint skills list`, `constraint skills inspect`.
|
|
15
|
+
- Install or update: `constraint skills install`, `constraint skills update`.
|
|
16
|
+
- Discover upload destinations: `constraint skills domains --json`.
|
|
17
|
+
- Upload a local skill folder: `constraint skills upload`.
|
|
18
|
+
- Review runs: `constraint skills run list`, `constraint skills run get`.
|
|
19
|
+
|
|
20
|
+
Read [references/commands.md](references/commands.md) before constructing flags or handling a less common operation.
|
|
21
|
+
|
|
22
|
+
## Upload skills
|
|
23
|
+
|
|
24
|
+
Upload the skill directory, not an individual `SKILL.md`. Before every upload, run:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
constraint skills domains --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use one returned `slug` exactly as `--domain`. Never guess a slug from a display name or reuse a domain from another organization. If multiple destinations are valid and ownership is unclear, ask the user.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
constraint skills upload <skill-directory> --domain <returned-slug>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Install skills
|
|
37
|
+
|
|
38
|
+
Choose the target agent and scope explicitly. Prefer `--project`; use `--global` only when the user wants the skill across projects. Prefer managed links and use `--copy` only when independent files are required. Never overwrite locally edited installed skills.
|
|
9
39
|
|
|
10
40
|
## Start a run
|
|
11
41
|
|
|
12
|
-
Immediately after selecting and loading a skill, run:
|
|
42
|
+
Immediately after selecting and loading a governed skill, run:
|
|
13
43
|
|
|
14
44
|
```bash
|
|
15
45
|
constraint skills run start <skill-name> --client <client> --session <session-id>
|
|
16
46
|
```
|
|
17
47
|
|
|
18
|
-
Use the invoked skill's frontmatter `name`. Normalize the client to `codex` or
|
|
19
|
-
`claude-code`. Use the current client session identifier. Retain the exact run ID
|
|
20
|
-
printed by the command. If one session invokes multiple skills, start and retain
|
|
21
|
-
a distinct run ID for each invocation.
|
|
48
|
+
Use the invoked skill's frontmatter `name`. Normalize the client to `codex` or `claude-code`. Use the current client session identifier. Retain the exact run ID printed by the command. If one session invokes multiple skills, start and retain a distinct run ID for each invocation.
|
|
22
49
|
|
|
23
|
-
If the command fails, report the failure briefly and continue the user's work.
|
|
24
|
-
Do not fabricate a run ID.
|
|
50
|
+
If the command fails, report the failure briefly and continue the user's work. Do not fabricate a run ID.
|
|
25
51
|
|
|
26
52
|
## Complete a run
|
|
27
53
|
|
|
28
|
-
After finishing the
|
|
29
|
-
the current session's real JSON or JSONL transcript file and run:
|
|
54
|
+
After finishing the governed skill's work and before ending the response, locate the current session's real JSON or JSONL transcript file and run:
|
|
30
55
|
|
|
31
56
|
```bash
|
|
32
57
|
constraint skills run complete <run-id> <transcript-path>
|
|
33
58
|
```
|
|
34
59
|
|
|
35
|
-
Pass the explicit local path. The CLI uploads the whole transcript file as it
|
|
36
|
-
exists at that moment and completes only that run. Never create a replacement
|
|
37
|
-
transcript, summarize it, pass a temporary file, or guess a path.
|
|
60
|
+
Pass the explicit local path. The CLI uploads the whole transcript file as it exists at that moment and completes only that run. Never create a replacement transcript, summarize it, pass a temporary file, or guess a path.
|
|
38
61
|
|
|
39
|
-
For multiple invocations, complete each retained run separately. Overlapping
|
|
40
|
-
full-session transcript prefixes are expected. If the transcript path cannot be
|
|
41
|
-
determined, leave the run started and tell the user that reporting could not be
|
|
42
|
-
completed.
|
|
62
|
+
For multiple invocations, complete each retained run separately. Overlapping full-session transcript prefixes are expected. If the transcript path cannot be determined, leave the run started and tell the user that reporting could not be completed.
|
|
43
63
|
|
|
44
64
|
Do not run completion hooks, background flushes, or pending-run scans.
|
|
65
|
+
|
|
66
|
+
## Work safely
|
|
67
|
+
|
|
68
|
+
- Use `--json` when parsing output.
|
|
69
|
+
- Respect WorkOS authorization failures; never bypass domain permissions.
|
|
70
|
+
- Do not invent an uninstall workflow.
|
|
71
|
+
- After mutations, report the affected skill, version, agent, scope, domain, or run ID as applicable.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "Constraint Skills"
|
|
3
|
-
short_description: "
|
|
4
|
-
default_prompt: "Use $constraint-skills to
|
|
3
|
+
short_description: "Operate and report governed agent skills"
|
|
4
|
+
default_prompt: "Use $constraint-skills to manage a governed skill and report its run."
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Constraint CLI command reference
|
|
2
|
+
|
|
3
|
+
## Install, authenticate, and configure
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install --global @constraint/cli
|
|
7
|
+
constraint --version
|
|
8
|
+
constraint login
|
|
9
|
+
constraint whoami
|
|
10
|
+
constraint logout
|
|
11
|
+
constraint setup
|
|
12
|
+
constraint doctor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`login` uses WorkOS device authorization. Never request or embed an API key or client secret. `setup` detects Codex and Claude Code, then separately presents the managed global-instruction change and this skill's global installation destinations. It never replaces unrelated instructions.
|
|
16
|
+
|
|
17
|
+
## Discover, inspect, install, and update
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
constraint skills list
|
|
21
|
+
constraint skills list --search <text>
|
|
22
|
+
constraint skills inspect <skill> [--version <number>] [--files]
|
|
23
|
+
|
|
24
|
+
constraint skills install <skill> --agent codex --project
|
|
25
|
+
constraint skills install <skill> --agent claude-code --global
|
|
26
|
+
constraint skills list --installed --project
|
|
27
|
+
constraint skills update <skill> --project
|
|
28
|
+
constraint skills update --all --global
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The catalog is already authorization-filtered. Project installs create `skills-lock.json`. Global receipts live in Constraint's per-user configuration directory.
|
|
32
|
+
|
|
33
|
+
## Discover upload domains and upload
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
constraint skills domains
|
|
37
|
+
constraint skills domains --json
|
|
38
|
+
constraint skills upload <skill-directory> --domain <returned-slug>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`skills domains` returns only domains where the authenticated user can manage skills. JSON objects contain the exact `slug`, display `name`, and `description`. Discover first and pass one returned slug. Ask the user when multiple domains fit and ownership is unclear.
|
|
42
|
+
|
|
43
|
+
## Start, complete, and review runs
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
constraint skills run start <skill> --client codex --session <stable-session-id>
|
|
47
|
+
constraint skills run complete <run-id> <actual-transcript-path>
|
|
48
|
+
|
|
49
|
+
constraint skills run list
|
|
50
|
+
constraint skills run list --team <domain> --user <workos-user-id> --skill <skill>
|
|
51
|
+
constraint skills run get <run-id>
|
|
52
|
+
constraint skills run get <run-id> --raw --output transcript.jsonl
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Repeat `--team`, `--user`, or `--skill` to request subsets. Review visibility is permission-controlled.
|
|
56
|
+
|
|
57
|
+
## Automation and recovery
|
|
58
|
+
|
|
59
|
+
Global flags: `--json`, `--quiet`, `--no-color`, `--help`, and `--version`. Installer workflows also accept `--yes`.
|
|
60
|
+
|
|
61
|
+
- Authentication failure: run `constraint login`, then `constraint whoami`.
|
|
62
|
+
- Setup uncertainty: run `constraint doctor`.
|
|
63
|
+
- Upload denied: rerun `constraint skills domains --json` and respect the returned scope.
|
|
64
|
+
- Install conflict: preserve local edits.
|
|
65
|
+
- Missing transcript: locate the real client JSON or JSONL file before completion.
|
package/src/cli.js
CHANGED
|
@@ -18,7 +18,12 @@ import {
|
|
|
18
18
|
note,
|
|
19
19
|
taskSpinner,
|
|
20
20
|
} from './prompts.js';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
applyInstructionSetup,
|
|
23
|
+
installCompanionSkill,
|
|
24
|
+
setupPlan,
|
|
25
|
+
setupStatus,
|
|
26
|
+
} from './setup.js';
|
|
22
27
|
import {
|
|
23
28
|
configuredAgents,
|
|
24
29
|
installSkill,
|
|
@@ -30,7 +35,7 @@ import {
|
|
|
30
35
|
uploadSkill,
|
|
31
36
|
} from './skills.js';
|
|
32
37
|
|
|
33
|
-
const VERSION = '0.3.
|
|
38
|
+
const VERSION = '0.3.4';
|
|
34
39
|
|
|
35
40
|
const HELP = `Constraint Skills CLI
|
|
36
41
|
|
|
@@ -236,17 +241,78 @@ async function setupCommand(args, out) {
|
|
|
236
241
|
agents = useUi && !yes ? await chooseAgents(detected) : detected;
|
|
237
242
|
}
|
|
238
243
|
if (!agents.length) throw new Error('Choose at least one agent with --agent.');
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
const plans = await Promise.all(agents.map(setupPlan));
|
|
245
|
+
const conflicts = plans.filter((plan) => plan.skill.action === 'conflict');
|
|
246
|
+
if (conflicts.length) {
|
|
247
|
+
throw new Error(`Local Constraint skill has uncommitted changes and was not replaced: ${conflicts.map((plan) => plan.skill.path).join(', ')}`);
|
|
248
|
+
}
|
|
249
|
+
if (dryRun) {
|
|
250
|
+
out.data(plans.map((plan) => ({
|
|
251
|
+
agent: plan.agent,
|
|
252
|
+
instructions: {
|
|
253
|
+
path: plan.instructions.path,
|
|
254
|
+
action: plan.instructions.changed ? 'update' : 'current',
|
|
255
|
+
content: plan.instructions.content,
|
|
256
|
+
},
|
|
257
|
+
skill: { path: plan.skill.path, scope: 'global', action: plan.skill.action },
|
|
258
|
+
})));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const hasInstructionChanges = plans.some((plan) => plan.instructions.changed);
|
|
262
|
+
const hasSkillChanges = plans.some((plan) => plan.skill.action !== 'current');
|
|
263
|
+
if (!useUi && !yes && (hasInstructionChanges || hasSkillChanges)) {
|
|
264
|
+
throw new Error('Non-interactive setup has pending changes. Pass --yes or use --dry-run.');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
let configureInstructions = true;
|
|
268
|
+
let installSkill = true;
|
|
269
|
+
if (useUi) {
|
|
270
|
+
note(
|
|
271
|
+
plans.map((plan) => `${humanize(plan.agent)}\n${plan.instructions.path}\n${plan.instructions.changed ? 'Managed block will be added or updated' : 'Already configured'}`).join('\n\n'),
|
|
272
|
+
'1. Configure agent instructions',
|
|
273
|
+
);
|
|
274
|
+
configureInstructions = !hasInstructionChanges || yes || await confirmPlan('Apply these instruction changes?');
|
|
275
|
+
|
|
276
|
+
note(
|
|
277
|
+
[
|
|
278
|
+
'Skill: constraint-skills',
|
|
279
|
+
'Scope: Global',
|
|
280
|
+
'',
|
|
281
|
+
...plans.flatMap((plan) => [
|
|
282
|
+
`${humanize(plan.agent)} destination:`,
|
|
283
|
+
`${plan.skill.path} · ${plan.skill.action === 'current' ? 'already current' : plan.skill.action}`,
|
|
284
|
+
'',
|
|
285
|
+
]),
|
|
286
|
+
].join('\n').trim(),
|
|
287
|
+
'2. Install Constraint Skills',
|
|
288
|
+
);
|
|
289
|
+
installSkill = !hasSkillChanges || yes || await confirmPlan(`Install globally for ${agents.map(humanize).join(' and ')}?`);
|
|
247
290
|
}
|
|
248
|
-
|
|
249
|
-
|
|
291
|
+
|
|
292
|
+
const result = { instructions: [], skill: [] };
|
|
293
|
+
if (configureInstructions) {
|
|
294
|
+
const spinner = taskSpinner(useUi && hasInstructionChanges);
|
|
295
|
+
for (const plan of plans) {
|
|
296
|
+
spinner.message(`Configuring ${humanize(plan.agent)} instructions`);
|
|
297
|
+
result.instructions.push(await applyInstructionSetup(plan.agent));
|
|
298
|
+
}
|
|
299
|
+
spinner.stop('Agent instructions configured.');
|
|
300
|
+
}
|
|
301
|
+
if (installSkill) {
|
|
302
|
+
const spinner = taskSpinner(useUi && hasSkillChanges);
|
|
303
|
+
for (const plan of plans) {
|
|
304
|
+
spinner.message(`Installing Constraint Skills for ${humanize(plan.agent)}`);
|
|
305
|
+
result.skill.push(await installCompanionSkill(plan.agent));
|
|
306
|
+
}
|
|
307
|
+
spinner.stop('Constraint Skills installed globally.');
|
|
308
|
+
}
|
|
309
|
+
if (useUi) {
|
|
310
|
+
finish([
|
|
311
|
+
'Setup complete.',
|
|
312
|
+
`Instructions: ${configureInstructions ? `${agents.length} configured` : 'skipped'}`,
|
|
313
|
+
`Skill: ${installSkill ? `installed for ${agents.map(humanize).join(' and ')}` : 'skipped'}`,
|
|
314
|
+
].join('\n'));
|
|
315
|
+
} else out.data(result);
|
|
250
316
|
}
|
|
251
317
|
|
|
252
318
|
async function doctorCommand(args, config, out) {
|
package/src/setup.js
CHANGED
|
@@ -12,9 +12,9 @@ export const BLOCK_END = '<!-- constraint-skills:end -->';
|
|
|
12
12
|
const BLOCK = `${BLOCK_START}
|
|
13
13
|
## Constraint Skills
|
|
14
14
|
|
|
15
|
-
When invoking any installed Agent Skill, load and
|
|
16
|
-
\`constraint-skills\` companion skill. It
|
|
17
|
-
|
|
15
|
+
When using the Constraint CLI or invoking any installed Agent Skill, load and
|
|
16
|
+
follow the global \`constraint-skills\` companion skill. It contains the CLI
|
|
17
|
+
workflow and records governed runs without modifying the invoked skill.
|
|
18
18
|
${BLOCK_END}`;
|
|
19
19
|
|
|
20
20
|
export function mergeInstructionBlock(existing) {
|
|
@@ -42,41 +42,107 @@ async function companionFiles() {
|
|
|
42
42
|
return readSkillDirectory(path.resolve(here, '..', 'skills', 'constraint-skills'));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
dryRun = false,
|
|
47
|
-
yes = false,
|
|
48
|
-
confirmChange = async () => false,
|
|
49
|
-
output = console.log,
|
|
50
|
-
} = {}) {
|
|
51
|
-
const selected = normalizeAgent(agent);
|
|
52
|
-
const paths = agentPaths(selected);
|
|
45
|
+
async function instructionPlan(selected, paths) {
|
|
53
46
|
let existing = '';
|
|
54
|
-
let
|
|
47
|
+
let mode = 0o644;
|
|
55
48
|
try {
|
|
56
49
|
existing = await fs.readFile(paths.instructions, 'utf8');
|
|
57
|
-
|
|
50
|
+
mode = (await fs.stat(paths.instructions)).mode & 0o777;
|
|
58
51
|
} catch (error) {
|
|
59
52
|
if (error && error.code !== 'ENOENT') throw error;
|
|
60
53
|
}
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
const content = mergeInstructionBlock(existing);
|
|
55
|
+
return { path: paths.instructions, changed: content !== existing, content, mode };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function skillPlan(selected, paths) {
|
|
59
|
+
const files = await companionFiles();
|
|
60
|
+
const bundledHash = packageDigest(files);
|
|
61
|
+
const config = await loadConfig();
|
|
62
|
+
const expectedHash = config.companion_hashes?.[selected] || null;
|
|
63
|
+
const target = path.join(paths.skills, 'constraint-skills');
|
|
64
|
+
let currentHash = null;
|
|
65
|
+
try {
|
|
66
|
+
currentHash = packageDigest(await readSkillDirectory(target));
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (error && error.code !== 'ENOENT') throw error;
|
|
69
69
|
}
|
|
70
|
+
const action = currentHash === bundledHash
|
|
71
|
+
? 'current'
|
|
72
|
+
: currentHash === null
|
|
73
|
+
? 'install'
|
|
74
|
+
: expectedHash && currentHash === expectedHash
|
|
75
|
+
? 'update'
|
|
76
|
+
: 'conflict';
|
|
77
|
+
return { path: target, action, bundledHash, expectedHash };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function setupPlan(agent) {
|
|
81
|
+
const selected = normalizeAgent(agent);
|
|
82
|
+
const paths = agentPaths(selected);
|
|
83
|
+
return {
|
|
84
|
+
agent: selected,
|
|
85
|
+
instructions: await instructionPlan(selected, paths),
|
|
86
|
+
skill: await skillPlan(selected, paths),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function recordConfiguredAgent(selected, config = null) {
|
|
91
|
+
const next = config || await loadConfig();
|
|
92
|
+
next.agents = [...new Set([...next.agents.map(normalizeAgent), selected])];
|
|
93
|
+
await saveConfig(next);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function applyInstructionSetup(agent) {
|
|
97
|
+
const selected = normalizeAgent(agent);
|
|
98
|
+
const paths = agentPaths(selected);
|
|
99
|
+
const plan = await instructionPlan(selected, paths);
|
|
100
|
+
if (plan.changed) await writeInstructions(plan.path, plan.content, plan.mode);
|
|
101
|
+
await recordConfiguredAgent(selected);
|
|
102
|
+
return { agent: selected, path: plan.path, changed: plan.changed, applied: true };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function installCompanionSkill(agent) {
|
|
106
|
+
const selected = normalizeAgent(agent);
|
|
107
|
+
const paths = agentPaths(selected);
|
|
70
108
|
const files = await companionFiles();
|
|
71
109
|
const config = await loadConfig();
|
|
72
110
|
config.companion_hashes ||= {};
|
|
73
111
|
const target = path.join(paths.skills, 'constraint-skills');
|
|
74
|
-
await writeSkillDirectory(target, files, {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
config.
|
|
78
|
-
await
|
|
79
|
-
return { agent: selected,
|
|
112
|
+
const result = await writeSkillDirectory(target, files, {
|
|
113
|
+
expectedHash: config.companion_hashes[selected] || null,
|
|
114
|
+
});
|
|
115
|
+
config.companion_hashes[selected] = result.hash;
|
|
116
|
+
await recordConfiguredAgent(selected, config);
|
|
117
|
+
return { agent: selected, path: target, changed: result.changed, applied: true };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function setupAgent(agent, {
|
|
121
|
+
dryRun = false,
|
|
122
|
+
yes = false,
|
|
123
|
+
confirmChange = async () => false,
|
|
124
|
+
output = console.log,
|
|
125
|
+
instructions = true,
|
|
126
|
+
skill = true,
|
|
127
|
+
} = {}) {
|
|
128
|
+
const selected = normalizeAgent(agent);
|
|
129
|
+
const plan = await setupPlan(selected);
|
|
130
|
+
output(`${selected}: ${plan.instructions.path}`);
|
|
131
|
+
if (dryRun) {
|
|
132
|
+
if (instructions) output(plan.instructions.content);
|
|
133
|
+
if (skill) output(`Install constraint-skills globally at ${plan.skill.path} (${plan.skill.action}).`);
|
|
134
|
+
return { agent: selected, instructions: plan.instructions, skill: plan.skill, applied: false };
|
|
135
|
+
}
|
|
136
|
+
let instructionResult = null;
|
|
137
|
+
let skillResult = null;
|
|
138
|
+
if (instructions) {
|
|
139
|
+
const approved = !plan.instructions.changed || yes || await confirmChange(
|
|
140
|
+
`Add the Constraint Skills block to ${plan.instructions.path}?`,
|
|
141
|
+
);
|
|
142
|
+
if (approved) instructionResult = await applyInstructionSetup(selected);
|
|
143
|
+
}
|
|
144
|
+
if (skill) skillResult = await installCompanionSkill(selected);
|
|
145
|
+
return { agent: selected, instructions: instructionResult, skill: skillResult, applied: true };
|
|
80
146
|
}
|
|
81
147
|
|
|
82
148
|
export async function setupStatus(agent) {
|