@homespunapps/cli 1.6.42 → 1.6.44

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.
@@ -7,14 +7,19 @@
7
7
  // agent always reads what the relay it's actually talking to wants it
8
8
  // to read.
9
9
  //
10
- // Two verbs:
11
- // `homespun skill show` print the full markdown to stdout (the
10
+ // Three verbs:
11
+ // `homespun skill show` print the full markdown to stdout (the
12
12
  // install / refresh path; pipe to a file).
13
- // `homespun skill version` — print just the relay's skill version (the
13
+ // `--section <slug>` prints one reference section
14
+ // instead, which is how an agent holding the skill
15
+ // as a fetched blob follows a pointer that a
16
+ // file-based agent would follow with a plain read.
17
+ // `homespun skill version` print just the relay's skill version (the
14
18
  // "is my local copy stale?" probe). The agent
15
19
  // compares this to the `<!-- homespun skill v… -->`
16
20
  // comment in its local skill file and re-runs
17
21
  // `homespun skill show > <path>` when they differ.
22
+ // `homespun skill sections` list the reference sections that exist.
18
23
  //
19
24
  // Both are unauthenticated — the skill route is public on the relay and
20
25
  // an agent on a too-old CLI must be able to read the upgrade instructions
@@ -46,11 +51,22 @@ async function failOnNon2xx(res, target) {
46
51
  const body = await res.text().catch(() => "");
47
52
  fail(`relay returned ${res.status} for ${target}${body ? ": " + body.slice(0, 200) : ""}`, "relay_error");
48
53
  }
49
- // `homespun skill show` print the full skill.
54
+ // `homespun skill show [--section <slug>]`: print the full skill, or one
55
+ // reference section of it.
56
+ //
57
+ // SKILL.md carries pointers to sections it does not include, so that an agent
58
+ // pays for them only when it needs them. An agent holding the skill as files on
59
+ // disk follows such a pointer by reading references/<slug>.md; an agent that
60
+ // fetched the skill over the wire has no such file, and `--section` is how it
61
+ // follows the same pointer. Without it the pointer would dangle for exactly the
62
+ // consumers this command exists to serve.
50
63
  async function runSkillFetch(args) {
51
64
  assertKnownFlags(args, ...specFor("skill", "show"));
52
65
  const url = resolveRelayUrl(args);
53
- const target = url + "/skills/homespun/SKILL.md";
66
+ const section = args.flags.get("section");
67
+ const target = section === undefined
68
+ ? url + "/skills/homespun/SKILL.md"
69
+ : `${url}/skills/homespun/references/${encodeURIComponent(section)}.md`;
54
70
  const res = await fetchOrFail(target);
55
71
  await failOnNon2xx(res, target);
56
72
  const text = await res.text();
@@ -61,6 +77,18 @@ async function runSkillFetch(args) {
61
77
  if (!text.endsWith("\n"))
62
78
  process.stdout.write("\n");
63
79
  }
80
+ // `homespun skill sections`: list the reference sections available. The index
81
+ // an agent needs when it holds SKILL.md as a fetched blob rather than a tree.
82
+ async function runSkillSections(args) {
83
+ assertKnownFlags(args, ...specFor("skill", "sections"));
84
+ const url = resolveRelayUrl(args);
85
+ const target = url + "/skills/homespun/references";
86
+ const res = await fetchOrFail(target);
87
+ await failOnNon2xx(res, target);
88
+ const body = (await res.json());
89
+ const sections = Array.isArray(body.sections) ? body.sections : [];
90
+ process.stdout.write(JSON.stringify({ sections }) + "\n");
91
+ }
64
92
  // `homespun skill version [--plain]` — print just the version.
65
93
  async function runSkillVersion(args) {
66
94
  assertKnownFlags(args, ...specFor("skill", "version"));
@@ -100,10 +128,13 @@ export async function runSkill(args) {
100
128
  case "version":
101
129
  await runSkillVersion(args);
102
130
  break;
131
+ case "sections":
132
+ await runSkillSections(args);
133
+ break;
103
134
  case undefined:
104
- fail("missing verb — usage: homespun skill <show|version> (run 'homespun skill --help')", "invalid_args");
135
+ fail("missing verb. Usage: homespun skill <show|version|sections> (run 'homespun skill --help')", "invalid_args");
105
136
  break;
106
137
  default:
107
- fail(`unknown skill verb '${sub}' expected show|version (run 'homespun skill --help')`, "invalid_args");
138
+ fail(`unknown skill verb '${sub}': expected show|version|sections (run 'homespun skill --help')`, "invalid_args");
108
139
  }
109
140
  }
@@ -769,11 +769,18 @@ const SKILL = {
769
769
  noun: "skill",
770
770
  tagline: "the relay's SKILL.md",
771
771
  group: "other",
772
- rootSummary: "The relay's SKILL.md: show, version. Auto-updating, and no API key is required.",
772
+ rootSummary: "The relay's SKILL.md: show, version, sections. Auto-updating, and no API key is required.",
773
773
  verbs: [
774
774
  {
775
775
  verb: "show",
776
776
  summary: "Fetches the relay's SKILL.md and writes the raw markdown to stdout.",
777
+ flags: [
778
+ {
779
+ name: "section",
780
+ value: "<slug>",
781
+ description: "Fetch one reference section instead of the whole skill (see 'skill sections')",
782
+ },
783
+ ],
777
784
  },
778
785
  {
779
786
  verb: "version",
@@ -785,6 +792,10 @@ const SKILL = {
785
792
  },
786
793
  ],
787
794
  },
795
+ {
796
+ verb: "sections",
797
+ summary: "Lists the reference sections SKILL.md points at but does not include.",
798
+ },
788
799
  ],
789
800
  notes: [
790
801
  "The skill is auto-updating: the relay's deployed image owns both the body and the version, so this is always the skill that matches the relay you are talking to.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homespunapps/cli",
3
- "version": "1.6.42",
3
+ "version": "1.6.44",
4
4
  "description": "Command-line client for the Homespun relay: deploy a real multi-user web app from your agent, then keep reading and writing its data.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -36,7 +36,7 @@
36
36
  "test:unit": "vitest run"
37
37
  },
38
38
  "dependencies": {
39
- "@homespunapps/core": "^1.6.42",
39
+ "@homespunapps/core": "^1.6.44",
40
40
  "qrcode-terminal": "^0.12.0"
41
41
  },
42
42
  "devDependencies": {