@constraint/cli 0.3.1 → 0.3.3

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
@@ -70,6 +70,7 @@ constraint setup --agent codex --dry-run
70
70
  ```bash
71
71
  constraint skills list
72
72
  constraint skills list --search research
73
+ constraint skills domains
73
74
  constraint skills inspect account-research
74
75
  constraint skills inspect account-research --files
75
76
  ```
@@ -129,9 +130,14 @@ constraint skills update --all --global
129
130
  Create or edit a standard Agent Skill folder locally, then upload it:
130
131
 
131
132
  ```bash
133
+ constraint skills domains
132
134
  constraint skills upload ./account-research --domain sales_pipeline
133
135
  ```
134
136
 
137
+ `constraint skills domains --json` returns the exact domain slugs where the
138
+ authenticated user can upload skills. Agents should discover the destination
139
+ first and pass one returned `slug` to `--domain`.
140
+
135
141
  The folder must contain a root `SKILL.md` with `name` and `description` YAML
136
142
  frontmatter. Pass the owning domain with `--domain`; if it is omitted in an
137
143
  interactive terminal, the CLI asks which permitted domain owns the skill.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constraint/cli",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Install, publish, and report Agent Skills with Constraint",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,44 +1,71 @@
1
1
  ---
2
2
  name: constraint-skills
3
- description: Report Agent Skill invocations to Constraint. Use whenever an agent invokes a skill installed from or governed by Constraint, including nested or multiple skill invocations in one client session.
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
- Record each invocation without editing the invoked skill or changing its work.
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 invoked skill's work and before ending the response, locate
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: "Report skill runs to Constraint"
4
- default_prompt: "Use $constraint-skills to report this skill run to Constraint."
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, installs this skill, and deterministically merges a marked global instruction block without replacing 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
@@ -23,13 +23,14 @@ import {
23
23
  configuredAgents,
24
24
  installSkill,
25
25
  installedSkills,
26
+ manageableDomainRecords,
26
27
  manageableDomains,
27
28
  readTranscript,
28
29
  updateAll,
29
30
  uploadSkill,
30
31
  } from './skills.js';
31
32
 
32
- const VERSION = '0.3.1';
33
+ const VERSION = '0.3.3';
33
34
 
34
35
  const HELP = `Constraint Skills CLI
35
36
 
@@ -39,6 +40,7 @@ Usage:
39
40
  constraint doctor [--agent codex|claude-code]...
40
41
  constraint skills list [--search <text>]
41
42
  constraint skills list --installed [--project|--global] [--agent <agent>]...
43
+ constraint skills domains
42
44
  constraint skills inspect <skill> [--version <version>] [--files]
43
45
  constraint skills install <skill> [--version <version>] [--agent <agent>]...
44
46
  [--project|--global] [--copy] [--yes]
@@ -131,6 +133,39 @@ function printSkillList(items, options, out) {
131
133
  else out.line(`${presentation.title}\n${presentation.message}`);
132
134
  }
133
135
 
136
+ export function domainListPresentation(domains) {
137
+ if (domains.length === 0) {
138
+ return {
139
+ title: 'No upload domains',
140
+ message: 'You do not have permission to upload skills to any domain.',
141
+ };
142
+ }
143
+ return {
144
+ title: `${domains.length} skill upload domain${domains.length === 1 ? '' : 's'}`,
145
+ message: domains.map((domain) => [
146
+ `${domain.name} (${domain.slug})`,
147
+ domain.description || 'No description.',
148
+ ].join('\n')).join('\n\n'),
149
+ };
150
+ }
151
+
152
+ async function listSkillDomains(args, config, out) {
153
+ rejectUnknown(args);
154
+ if (args.length) throw new Error('skills domains does not accept positional arguments');
155
+ const domains = (await manageableDomainRecords(config)).map(({ slug, name, description }) => ({
156
+ slug,
157
+ name,
158
+ description,
159
+ }));
160
+ if (out.json) {
161
+ out.data(domains);
162
+ return;
163
+ }
164
+ const presentation = domainListPresentation(domains);
165
+ if (interactive(out)) note(presentation.message, presentation.title);
166
+ else out.line(`${presentation.title}\n${presentation.message}`);
167
+ }
168
+
134
169
  function takeScope(args) {
135
170
  const project = takeFlag(args, '--project');
136
171
  const global = takeFlag(args, '--global');
@@ -441,12 +476,13 @@ async function runCommand(args, config, out) {
441
476
  async function skillsCommand(args, config, out) {
442
477
  const command = args.shift();
443
478
  if (command === 'list') return listSkills(args, config, out);
479
+ if (command === 'domains') return listSkillDomains(args, config, out);
444
480
  if (command === 'inspect') return inspectSkill(args, config, out);
445
481
  if (command === 'install') return installCommand(args, config, out);
446
482
  if (command === 'update') return updateCommand(args, config, out);
447
483
  if (command === 'upload') return uploadCommand(args, config, out);
448
484
  if (command === 'run') return runCommand(args, config, out);
449
- throw new Error('Expected skills list, inspect, install, update, upload, or run.');
485
+ throw new Error('Expected skills list, domains, inspect, install, update, upload, or run.');
450
486
  }
451
487
 
452
488
  export async function main(argv) {
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 follow the global
16
- \`constraint-skills\` companion skill. It records the run with the Constraint
17
- CLI without modifying the invoked skill.
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) {
package/src/skills.js CHANGED
@@ -66,10 +66,12 @@ export async function uploadSkill(config, localPath, domain) {
66
66
  }
67
67
 
68
68
  export async function manageableDomains(config) {
69
+ return (await manageableDomainRecords(config)).map((domain) => domain.slug);
70
+ }
71
+
72
+ export async function manageableDomainRecords(config) {
69
73
  const domains = await apiRequest(config, '/domains');
70
- return domains
71
- .filter((domain) => domain.permissions.includes('domain:skill_manage'))
72
- .map((domain) => domain.slug);
74
+ return domains.filter((domain) => domain.permissions.includes('domain:skill_manage'));
73
75
  }
74
76
 
75
77
  export async function configuredAgents() {