@homespunapps/cli 1.0.1 → 1.4.2

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/index.js CHANGED
@@ -9,7 +9,8 @@
9
9
  // Multiple environments live as named profiles in
10
10
  // $XDG_CONFIG_HOME/homespun/config.json; pick one with --profile or HOMESPUN_PROFILE.
11
11
  // Output is JSON by default. Every noun self-documents via --help.
12
- import { parseArgs, ArgvError } from "./argv.js";
12
+ import { parseArgs, ArgvError, BOOLEAN_FLAGS } from "./argv.js";
13
+ import { nounSpec, renderNounHelp, renderRootHelp } from "./help-catalog.js";
13
14
  /**
14
15
  * Translate an ArgvError into the canonical `invalid_args` envelope and exit
15
16
  * non-zero. The parser throws ArgvError up-front; assertKnownFlags throws it
@@ -25,95 +26,25 @@ function failArgvError(e) {
25
26
  process.stderr.write(JSON.stringify({ error }) + "\n");
26
27
  process.exit(1);
27
28
  }
28
- import { runAgent, agentHelp } from "./commands/agent.js";
29
- import { runKey, keyHelp } from "./commands/key.js";
30
- import { runTaste, tasteHelp } from "./commands/taste.js";
31
- import { runFeedback, feedbackHelp } from "./commands/feedback.js";
32
- import { runConfig, configHelp } from "./commands/config.js";
33
- import { runBlob, blobHelp } from "./commands/attachment.js";
34
- import { runSkill, skillHelp } from "./commands/skill.js";
35
- import { runDeploy, deployHelp } from "./commands/deploy.js";
36
- import { runApps, appsHelp } from "./commands/apps.js";
37
- import { runData, dataHelp } from "./commands/data.js";
38
- import { runMembers, membersHelp } from "./commands/members.js";
29
+ import { runAgent } from "./commands/agent.js";
30
+ import { runKey } from "./commands/key.js";
31
+ import { runTaste } from "./commands/taste.js";
32
+ import { runFeedback } from "./commands/feedback.js";
33
+ import { runConfig } from "./commands/config.js";
34
+ import { runBlob } from "./commands/attachment.js";
35
+ import { runSkill } from "./commands/skill.js";
36
+ import { runDeploy } from "./commands/deploy.js";
37
+ import { runApps } from "./commands/apps.js";
38
+ import { runData } from "./commands/data.js";
39
+ import { runMembers } from "./commands/members.js";
40
+ import { runGrant } from "./commands/grant.js";
41
+ import { runIngest } from "./commands/ingest.js";
39
42
  import { VERSION } from "./version.js";
40
43
  import { HomespunApiError } from "@homespunapps/core";
41
44
  import { failUpgradeRequired } from "./output.js";
42
- const ROOT_HELP = `homespun: apps your AI builds and hosts for you and people you invite
43
-
44
- Usage:
45
- homespun <command> [options]
46
-
47
- v2 app commands (operate on an App — a persistent, deployed web app):
48
- deploy Create or redeploy an app (POST /v1/apps or
49
- /v1/apps/:id/versions) — the create->redeploy loop.
50
- apps App lifecycle: list | show | update | delete | wake |
51
- watch (stream the app's change feed as JSON-lines).
52
- data Collection row CRUD for an app: list | get | upsert |
53
- update | delete.
54
- members App membership management: add | list | remove
55
- (invite/attach a member by email, list, or remove).
56
-
57
- Other noun groups:
58
- key YOUR agent's API key (list | revoke).
59
- taste YOUR agent's freeform UI taste notes
60
- (get | set | clear) — presentation preferences the agent
61
- has learned from human feedback and reads before
62
- generating an app.
63
- feedback One-shot feedback to the relay operator
64
- (create | list) — bug reports, feature requests, notes.
65
- attachment Binary attachments (upload | download | show | list |
66
- delete | token <mint|revoke|list>). Attachments are
67
- scoped to an agent or an App, and can be
68
- referenced from input_data via \`format: homespun-attachment-id\`.
69
- agent Agent identity on this machine (register | logout).
70
- config CLI config inspection (show).
71
- skill The relay's SKILL.md (show | version) — auto-updating;
72
- no API key required.
73
-
74
- Run \`homespun <command> --help\` for command-specific options.
75
-
76
- Config:
77
- HOMESPUN_URL Relay base URL. Override: --url <url>
78
- HOMESPUN_API_KEY Agent API key. Override: --api-key <key>
79
- HOMESPUN_PROFILE Active profile name. Override: --profile <name>
80
- 'homespun agent register' provisions the API key and saves it (with the URL) to
81
- \${XDG_CONFIG_HOME:-~/.config}/homespun/config.json under a named profile —
82
- afterwards commands need no env vars. Manage multiple environments
83
- (dev/staging/prod) with 'homespun config list / use / add / rm'.
84
-
85
- Global flags:
86
- -h, --help Show help.
87
- -v, --version Print version.
88
- --profile <name> Pick a saved profile for this invocation (overrides
89
- HOMESPUN_PROFILE and the saved 'current_profile').
90
- --url <url> Relay base URL — bypasses profile selection entirely.
91
- --api-key <key> Agent API key — bypasses profile selection entirely.
92
-
93
- Output: stdout is machine-readable JSON; errors go to stderr as
94
- {"error":{"code","message"}} with a non-zero exit.`;
95
- // Flags that never take a value. `json` is kept here purely for forward-compat
96
- // (JSON is currently the only output mode): accepting `--json` as a no-op bool
97
- // means a future `--text`/`--json` toggle won't break existing invocations. It
98
- // is intentionally undocumented in --help.
99
- //
100
- // `version` is deliberately NOT here: the top-level `-v` / `--version` is
101
- // handled from rawArgv[0] before parseArgs runs, so it never needs to be a
102
- // boolean flag — and keeping it out leaves room for a future noun-level
103
- // `--version <n>` value flag without a collision.
104
- const BOOLEAN_FLAGS = new Set([
105
- "json",
106
- "once",
107
- "help",
108
- "print-key",
109
- "yes",
110
- "plain",
111
- // `homespun deploy --force` / `homespun apps ... --force`: override a compat gate.
112
- "force",
113
- // `homespun agent register --no-device`: skip the browser device-authorization
114
- // flow and register directly (unowned agent), the pre-device-flow behavior.
115
- "no-device",
116
- ]);
45
+ // BOOLEAN_FLAGS (flags that never take a value) lives in argv.ts next to the
46
+ // parser that consumes it, and is exported so tests parse with the real set
47
+ // instead of a per-test copy that can drift (#827).
117
48
  async function main() {
118
49
  const rawArgv = process.argv.slice(2);
119
50
  // Version: handle before anything else.
@@ -127,7 +58,7 @@ async function main() {
127
58
  noun === "-h" ||
128
59
  noun === "--help" ||
129
60
  noun === "help") {
130
- process.stdout.write(ROOT_HELP + "\n");
61
+ process.stdout.write(renderRootHelp() + "\n");
131
62
  return;
132
63
  }
133
64
  let args;
@@ -140,20 +71,8 @@ async function main() {
140
71
  }
141
72
  throw e;
142
73
  }
143
- const helps = {
144
- key: keyHelp,
145
- taste: tasteHelp,
146
- feedback: feedbackHelp,
147
- attachment: blobHelp,
148
- agent: agentHelp,
149
- config: configHelp,
150
- skill: skillHelp,
151
- deploy: deployHelp,
152
- apps: appsHelp,
153
- data: dataHelp,
154
- members: membersHelp,
155
- };
156
- if (!(noun in helps)) {
74
+ const spec = nounSpec(noun);
75
+ if (!spec) {
157
76
  process.stderr.write(JSON.stringify({
158
77
  error: {
159
78
  code: "unknown_command",
@@ -167,7 +86,7 @@ async function main() {
167
86
  // the verb runner which reads its own xxxHelp). This pre-empt only fires
168
87
  // when --help is the FIRST positional-equivalent — i.e. no verb given.
169
88
  if (args.bools.has("help") && args.positionals.length === 0) {
170
- process.stdout.write(helps[noun] + "\n");
89
+ process.stdout.write(renderNounHelp(spec) + "\n");
171
90
  return;
172
91
  }
173
92
  switch (noun) {
@@ -204,6 +123,12 @@ async function main() {
204
123
  case "members":
205
124
  await runMembers(args);
206
125
  break;
126
+ case "grants":
127
+ await runGrant(args);
128
+ break;
129
+ case "ingest":
130
+ await runIngest(args);
131
+ break;
207
132
  }
208
133
  }
209
134
  main().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homespunapps/cli",
3
- "version": "1.0.1",
3
+ "version": "1.4.2",
4
4
  "description": "Command-line client for the Homespun relay: create apps, inspect state, send and watch events.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -11,9 +11,9 @@
11
11
  "relay",
12
12
  "human-in-the-loop"
13
13
  ],
14
- "homepage": "https://homespun.dev",
14
+ "homepage": "https://docs.homespun.dev",
15
15
  "bugs": {
16
- "url": "mailto:support@homespun.dev"
16
+ "url": "https://github.com/homespunapps/homespun/issues"
17
17
  },
18
18
  "engines": {
19
19
  "node": ">=20"
@@ -36,13 +36,18 @@
36
36
  "test:unit": "vitest run"
37
37
  },
38
38
  "dependencies": {
39
- "@homespunapps/core": "^1.0.0",
39
+ "@homespunapps/core": "^1.4.2",
40
40
  "qrcode-terminal": "^0.12.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@types/node": "^25.9.2",
43
+ "@types/node": "^26.1.1",
44
44
  "@types/qrcode-terminal": "^0.12.2",
45
- "typescript": "^6.0.3",
45
+ "typescript": "^7.0.2",
46
46
  "vitest": "^4.1.8"
47
+ },
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/homespunapps/homespun.git",
51
+ "directory": "packages/cli"
47
52
  }
48
53
  }