@lambdacurry/arbor 0.4.26 → 0.4.27

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.
Files changed (2) hide show
  1. package/dist/arbor.js +59 -4
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -16876,6 +16876,9 @@ function readTextSource(src) {
16876
16876
  }
16877
16877
  return text3.replace(/[\r\n]+$/, "");
16878
16878
  }
16879
+ function primaryPositionalField(inputSchema) {
16880
+ return flagsForSchema(inputSchema).find((f) => f.required && (f.kind === "string" || f.kind === "number"));
16881
+ }
16879
16882
  function flagsForSchema(inputSchema) {
16880
16883
  return Object.entries(inputSchema).map(([field, raw]) => {
16881
16884
  const { inner, optional: optional2 } = unwrapOptional(raw);
@@ -16981,6 +16984,35 @@ function helpLine(action) {
16981
16984
  }
16982
16985
  var COMMAND_HELP = CLI_ACTIONS.map(helpLine).join(`
16983
16986
  `);
16987
+ function commandHelp(positionals) {
16988
+ const match = matchCommand(positionals);
16989
+ if (!match)
16990
+ return;
16991
+ const { action } = match;
16992
+ const specs = flagsForSchema(action.inputSchema);
16993
+ const primary = primaryPositionalField(action.inputSchema);
16994
+ const usageFlags = specs.map((f) => {
16995
+ const token = f.kind === "boolean" ? `--${f.flag}` : `--${f.flag} <${f.kind}>`;
16996
+ return f.required ? token : `[${token}]`;
16997
+ }).join(" ");
16998
+ const usage = `Usage: arbor ${commandWords(action)}${primary ? ` [<${primary.field}>]` : ""}${usageFlags ? ` ${usageFlags}` : ""}`;
16999
+ const lines = specs.map((f) => {
17000
+ const req = f.required ? "required" : "optional";
17001
+ const fileNote = f.kind === "string" ? ` (or --${f.flag}-file <path|->)` : "";
17002
+ const desc = f.description ? ` — ${f.description}` : "";
17003
+ return ` --${f.flag} <${f.kind}> [${req}]${fileNote}${desc}`;
17004
+ });
17005
+ const primaryNote = primary ? `
17006
+
17007
+ A single bare argument fills --${primary.flag} (e.g. \`arbor ${commandWords(action)} <${primary.field}>\`).` : "";
17008
+ return `${commandWords(action)} — ${action.description}
17009
+
17010
+ ${usage}
17011
+
17012
+ ${lines.join(`
17013
+ `)}${primaryNote}
17014
+ `;
17015
+ }
16984
17016
  function commandCatalog() {
16985
17017
  return CLI_ACTIONS.map((action) => ({
16986
17018
  command: commandWords(action),
@@ -16999,7 +17031,21 @@ async function runObjectVerb(positionals, flags, ctx) {
16999
17031
  const match = matchCommand(positionals);
17000
17032
  if (!match)
17001
17033
  throw new UsageError(`unknown command: ${positionals.join(" ") || "(none)"}`);
17002
- const { action } = match;
17034
+ const { action, words } = match;
17035
+ const extras = positionals.slice(words);
17036
+ if (extras.length > 0) {
17037
+ const primary = primaryPositionalField(action.inputSchema);
17038
+ if (!primary) {
17039
+ throw new UsageError(`unexpected argument: ${extras[0]} (\`${commandWords(action)}\` takes no positional — use flags)`);
17040
+ }
17041
+ if (extras.length > 1) {
17042
+ throw new UsageError(`too many arguments: \`${commandWords(action)}\` takes one positional (--${primary.flag}); pass the rest as flags`);
17043
+ }
17044
+ if (flags[primary.flag] !== undefined || flags[`${primary.flag}-file`] !== undefined) {
17045
+ throw new UsageError(`pass --${primary.flag} either as a flag or as the positional argument, not both`);
17046
+ }
17047
+ flags[primary.flag] = extras[0];
17048
+ }
17003
17049
  const accepted = acceptedFlags(action.inputSchema);
17004
17050
  const unknown2 = Object.keys(flags).filter((f) => !accepted.has(f) && !RESERVED_FLAGS.has(f));
17005
17051
  if (unknown2.length > 0) {
@@ -17155,13 +17201,18 @@ async function renderMe(ctx, action) {
17155
17201
  const spaceLines = spaceGaps.length > 0 ? ` spaces without your charter (say how you operate there):
17156
17202
  ` + spaceGaps.map((s) => ` • ${s.spaceTitle} — \`set_space_charter --space-id ${s.spaceId} --charter "…"\`
17157
17203
  `).join("") : "";
17204
+ const charter = me.profile.description?.trim();
17205
+ const caps = me.profile.capabilities ?? [];
17206
+ const setLines = (charter ? ` charter: ${charter}
17207
+ ` : "") + (caps.length > 0 ? ` capabilities: ${caps.join(", ")}
17208
+ ` : "");
17158
17209
  const human = `${me.profile.displayName} · ${me.profile.kind} · org-role ${me.profile.orgRole}
17159
17210
  ` + ` org ${me.profile.orgId} · resolved via ${me.client.kind}
17160
- ` + (gaps.length > 0 ? ` to be more legible to your team, set: ${gaps.join("; ")} (\`introduce\`)
17211
+ ` + setLines + (gaps.length > 0 ? ` to be more legible to your team, set: ${gaps.join("; ")} (\`introduce\`)
17161
17212
  ` : "") + spaceLines;
17162
17213
  emitDual(me, human, action, ctx);
17163
17214
  }
17164
- var CLI_NOTE = `On this CLI, before your first write: commands are NOUN-VERB (\`thread get\`, \`space get\`, not \`get thread\`). Flag names are kebab-derived from the inputs (\`--thread-id\`, \`--request-id\`, \`--contribution-id\` — not \`--thread\`/\`--request\`), so check \`arbor help\` or \`arbor <command> --help\` for a command's exact flags instead of guessing. Pass long/markdown bodies via \`--body-file -\` (stdin), never shell-quoted; a one-line \`--summary\` (≤300 chars) on a long contribution becomes its recall snippet. List inputs (e.g. \`--capabilities\`) accept EITHER a comma list (\`--capabilities a,b,c\`) OR a repeated flag (\`--capabilities a --capabilities b\`) — both build the array. \`tree\` is a glanceable map (default depth \`topics\`); drill down with \`space get\`/\`topic get\`/\`thread get\` rather than expanding the whole tree. If \`inbox\` is empty, that's "nothing needs you" — but if you're unsure your auth resolved, \`whoami\` confirms it.`;
17215
+ var CLI_NOTE = `On this CLI, before your first write: commands are NOUN-VERB (\`thread get\`, \`space get\`, not \`get thread\`). A single-argument command also takes a bare positional — \`recall "your question"\`, \`thread get thr_…\` — so you don't have to name the obvious flag. Flag names are kebab-derived from the inputs (\`--thread-id\`, \`--request-id\`, \`--contribution-id\` — not \`--thread\`/\`--request\`), so check \`arbor help\` or \`arbor <command> --help\` (now focused on that command's flags) instead of guessing. Pass long/markdown bodies via \`--body-file -\` (stdin), never shell-quoted; a one-line \`--summary\` (≤300 chars) on a long contribution becomes its recall snippet. List inputs (e.g. \`--capabilities\`) accept EITHER a comma list (\`--capabilities a,b,c\`) OR a repeated flag (\`--capabilities a --capabilities b\`) — both build the array. \`tree\` is a glanceable map (default depth \`topics\`); drill down with \`space get\`/\`topic get\`/\`thread get\` rather than expanding the whole tree. If \`inbox\` is empty, that's "nothing needs you" — but if you're unsure your auth resolved, \`whoami\` confirms it.`;
17165
17216
  function renderOrient(ctx) {
17166
17217
  emitDual({ orientation: ORIENTATION, cliNote: CLI_NOTE }, `${ORIENTATION}
17167
17218
 
@@ -17248,7 +17299,11 @@ async function main() {
17248
17299
  return;
17249
17300
  }
17250
17301
  if (truthyFlag(flags.help)) {
17251
- renderHelp(ctx);
17302
+ const focused = positionals.length > 0 ? commandHelp(positionals) : undefined;
17303
+ if (focused)
17304
+ emitDual({ help: focused }, focused, "help", ctx);
17305
+ else
17306
+ renderHelp(ctx);
17252
17307
  return;
17253
17308
  }
17254
17309
  switch (cmd) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.4.26",
3
+ "version": "0.4.27",
4
4
  "description": "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
5
5
  "type": "module",
6
6
  "bin": {