@arbidocs/cli 0.3.66 → 0.3.68

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.68
4
+
5
+ [compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.67...HEAD)
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **e2e:** Revive playwright suite — drift, removed-UX rewrites, helpers ([#779](https://github.com/arbicity/ARBI-frontend/pull/779))
10
+ - **tui:** Pass /pa, /setup, /cold-start through to the backend ([#780](https://github.com/arbicity/ARBI-frontend/pull/780))
11
+
12
+ ## v0.3.67
13
+
14
+ [compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.66...HEAD)
15
+
16
+ ### 🚀 Enhancements
17
+
18
+ - **tui:** SOTA amendments — citations, events, tool blocks, view/sources/history ([#774](https://github.com/arbicity/ARBI-frontend/pull/774))
19
+ - **sdk,cli,tui:** Consume GET /v1/assistant/skills for slash autocomplete ([#776](https://github.com/arbicity/ARBI-frontend/pull/776))
20
+ - **tui,cli:** Unified slash dispatcher + autocomplete merges static commands and skills ([#777](https://github.com/arbicity/ARBI-frontend/pull/777))
21
+ - **sdk,tui,cli,react:** Skill iteration loop — edit/install/pre-flight + React slash menu ([#778](https://github.com/arbicity/ARBI-frontend/pull/778))
22
+
3
23
  ## v0.3.66
4
24
 
5
25
  [compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.65...HEAD)
package/dist/index.js CHANGED
@@ -3694,7 +3694,7 @@ function getLatestVersion(skipCache = false) {
3694
3694
  }
3695
3695
  }
3696
3696
  function getCurrentVersion() {
3697
- return "0.3.66";
3697
+ return "0.3.68";
3698
3698
  }
3699
3699
  function readChangelog(fromVersion, toVersion) {
3700
3700
  try {
@@ -3747,17 +3747,17 @@ function showChangelog(fromVersion, toVersion) {
3747
3747
  async function checkForUpdates(autoUpdate) {
3748
3748
  try {
3749
3749
  const latest = getLatestVersion();
3750
- if (!latest || latest === "0.3.66") return;
3750
+ if (!latest || latest === "0.3.68") return;
3751
3751
  if (autoUpdate) {
3752
3752
  warn(`
3753
- Your arbi version is out of date (${"0.3.66"} \u2192 ${latest}). Updating...`);
3753
+ Your arbi version is out of date (${"0.3.68"} \u2192 ${latest}). Updating...`);
3754
3754
  child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
3755
- showChangelog("0.3.66", latest);
3755
+ showChangelog("0.3.68", latest);
3756
3756
  console.log(`Updated to ${latest}.`);
3757
3757
  } else {
3758
3758
  warn(
3759
3759
  `
3760
- Your arbi version is out of date (${"0.3.66"} \u2192 ${latest}).
3760
+ Your arbi version is out of date (${"0.3.68"} \u2192 ${latest}).
3761
3761
  Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
3762
3762
  );
3763
3763
  }
@@ -3789,10 +3789,10 @@ function markNagShown(latest) {
3789
3789
  function hintUpdateOnError() {
3790
3790
  try {
3791
3791
  const cached = readCache();
3792
- if (!cached || cached.latest === "0.3.66") return;
3792
+ if (!cached || cached.latest === "0.3.68") return;
3793
3793
  if (!shouldShowNag(cached.latest)) return;
3794
3794
  warn(
3795
- `Your arbi version is out of date (${"0.3.66"} \u2192 ${cached.latest}). Run "arbi update".`
3795
+ `Your arbi version is out of date (${"0.3.68"} \u2192 ${cached.latest}). Run "arbi update".`
3796
3796
  );
3797
3797
  markNagShown(cached.latest);
3798
3798
  } catch {
@@ -6371,7 +6371,10 @@ function registerUploadCommand(program2) {
6371
6371
  ).option(
6372
6372
  "-s, --s3",
6373
6373
  "Upload via the direct-to-MinIO flow (SecretBox on the client, presigned PUT)"
6374
- ).option("--folder <name>", "Backend folder for plain-file uploads (direct upload only)").action(
6374
+ ).option("--folder <name>", "Backend folder for plain-file uploads (direct upload only)").option(
6375
+ "--wp-type <type>",
6376
+ "Work product type: source (default), skill, memory, artifact, webpage. Use --wp-type skill with --folder skills/<slug> to upload a SKILL.md."
6377
+ ).action(
6375
6378
  (paths, opts) => runAction(async () => {
6376
6379
  const isManifestMode = Boolean(opts.manifest || opts.log || opts.resume);
6377
6380
  const inputPaths = paths ?? [];
@@ -6528,7 +6531,10 @@ function registerUploadCommand(program2) {
6528
6531
  summary.totalFiles += 1;
6529
6532
  continue;
6530
6533
  }
6531
- const result = await sdk.documentsNode.uploadLocalFile(auth, filePath);
6534
+ const result = await sdk.documentsNode.uploadLocalFile(auth, filePath, {
6535
+ folder: opts.folder,
6536
+ wpType: opts.wpType
6537
+ });
6532
6538
  if (!opts.json) {
6533
6539
  success(`Uploaded: ${result.fileName} (${(result.doc_ext_ids ?? []).join(", ")})`);
6534
6540
  if (result.skipped && result.skipped.length > 0) {
@@ -10076,6 +10082,142 @@ function registerAuthCommand(program2) {
10076
10082
  await auth.commands.find((c) => c.name() === "profile").parseAsync(tail, { from: "user" });
10077
10083
  });
10078
10084
  }
10085
+ function extractSlugFromFrontmatter(body) {
10086
+ const normalized = body.replace(/\r\n/g, "\n");
10087
+ if (!normalized.startsWith("---\n")) return null;
10088
+ const end = normalized.indexOf("\n---", 4);
10089
+ if (end < 0) return null;
10090
+ const block = normalized.slice(4, end);
10091
+ for (const line of block.split("\n")) {
10092
+ const m = /^name:\s*(.+?)\s*$/.exec(line);
10093
+ if (m) {
10094
+ return m[1].toLowerCase().replace(/['"]/g, "").replace(/[_\s]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
10095
+ }
10096
+ }
10097
+ return null;
10098
+ }
10099
+ async function loadSkillSource(source) {
10100
+ if (source.startsWith("http://") || source.startsWith("https://")) {
10101
+ const res = await fetch(source);
10102
+ if (!res.ok) {
10103
+ throw new Error(`Failed to fetch ${source}: HTTP ${res.status} ${res.statusText}`);
10104
+ }
10105
+ return await res.text();
10106
+ }
10107
+ const stat = fs5.statSync(source);
10108
+ if (stat.isDirectory()) {
10109
+ throw new Error(
10110
+ `${source} is a directory. Pass a single SKILL.md file, or use \`\`arbi upload --folder skills/<slug> --wp-type skill\`\` for multi-file skills.`
10111
+ );
10112
+ }
10113
+ return fs5.readFileSync(source, "utf8");
10114
+ }
10115
+ function registerSkillsCommand(program2) {
10116
+ const skills = program2.command("skills").description("Skills: list, show");
10117
+ skills.command("list").description("List user-invocable skills in the active workspace").option("--json", "Output as JSON").option("--include-hidden", "Include skills with user-invocable: false").action(
10118
+ (opts) => runAction(async () => {
10119
+ const { arbi } = await resolveWorkspace();
10120
+ const list = await sdk.assistant.listSkills(arbi, {
10121
+ includeHidden: opts.includeHidden
10122
+ });
10123
+ if (opts.json) {
10124
+ console.log(JSON.stringify(list, null, 2));
10125
+ return;
10126
+ }
10127
+ if (list.length === 0) {
10128
+ process.stderr.write(
10129
+ "No skills in this workspace yet. Upload a SKILL.md with wp_type=skill to add one.\n"
10130
+ );
10131
+ return;
10132
+ }
10133
+ printTable(
10134
+ [
10135
+ { header: "SLUG", width: 20, value: (r) => r.slug ?? "" },
10136
+ { header: "NAME", width: 24, value: (r) => r.name ?? "" },
10137
+ {
10138
+ header: "TYPE",
10139
+ width: 10,
10140
+ value: (r) => r.skill_type ?? "markdown"
10141
+ },
10142
+ {
10143
+ header: "ARGS",
10144
+ width: 20,
10145
+ value: (r) => r.arg_hint ?? ""
10146
+ },
10147
+ {
10148
+ header: "DESCRIPTION",
10149
+ width: 40,
10150
+ value: (r) => r.description ?? ""
10151
+ }
10152
+ ],
10153
+ list
10154
+ );
10155
+ })()
10156
+ );
10157
+ skills.command("install <source>").description(
10158
+ "Install a skill from a URL or local path (SKILL.md). Slug derived from frontmatter unless --slug is given."
10159
+ ).option("--slug <slug>", "Override the slug (default: derived from frontmatter name)").option("--json", "Output the upload result as JSON").action(
10160
+ (source, opts) => runAction(async () => {
10161
+ const ctx = await resolveWorkspace();
10162
+ const authHeaders = {
10163
+ baseUrl: ctx.config.baseUrl,
10164
+ accessToken: ctx.accessToken
10165
+ };
10166
+ const body = await loadSkillSource(source);
10167
+ const slug = opts.slug ?? extractSlugFromFrontmatter(body) ?? (() => {
10168
+ process.stderr.write(
10169
+ "Could not derive slug: no --slug flag and no ``name:`` in frontmatter.\nAdd a frontmatter block like:\n\n ---\n name: my-skill\n description: \u2026\n ---\n\nor pass ``--slug my-skill`` explicitly.\n"
10170
+ );
10171
+ process.exit(1);
10172
+ })();
10173
+ const blob = new Blob([body], { type: "text/markdown" });
10174
+ const result = await sdk.documents.uploadFile(authHeaders, blob, "SKILL.md", {
10175
+ folder: `skills/${slug}`,
10176
+ wpType: "skill"
10177
+ });
10178
+ if (opts.json) {
10179
+ console.log(JSON.stringify({ slug, ...result }, null, 2));
10180
+ return;
10181
+ }
10182
+ console.log(bold(`Installed skill: ${slug}`));
10183
+ console.log(dim(`source: ${source}`));
10184
+ console.log(dim(`folder: skills/${slug}`));
10185
+ console.log(
10186
+ dim("Backend frontmatter loader picks it up on the next /v1/assistant/skills call.")
10187
+ );
10188
+ })()
10189
+ );
10190
+ skills.command("show <slug>").description("Show a skill's SKILL.md body (read-only)").option("--json", "Output as JSON (includes metadata)").action(
10191
+ (slug, opts) => runAction(async () => {
10192
+ const ctx = await resolveWorkspace();
10193
+ const list = await sdk.assistant.listSkills(ctx.arbi, { includeHidden: true });
10194
+ const skill = list.find((s) => s.slug === slug || s.name === slug);
10195
+ if (!skill) {
10196
+ process.stderr.write(
10197
+ `No skill matching "${slug}" in this workspace. Try \`arbi skills list\`.
10198
+ `
10199
+ );
10200
+ process.exit(1);
10201
+ }
10202
+ const authHeaders = {
10203
+ baseUrl: ctx.config.baseUrl,
10204
+ accessToken: ctx.accessToken
10205
+ };
10206
+ const dlRes = await sdk.documents.downloadDocument(authHeaders, skill.doc_ext_id);
10207
+ const body = dlRes.ok ? await dlRes.text() : "";
10208
+ if (opts.json) {
10209
+ console.log(JSON.stringify({ ...skill, body }, null, 2));
10210
+ return;
10211
+ }
10212
+ console.log(bold(`${skill.name} (${skill.slug})`));
10213
+ if (skill.description) console.log(dim(skill.description));
10214
+ if (skill.arg_hint) console.log(dim(`args: ${skill.arg_hint}`));
10215
+ console.log(dim(`type: ${skill.skill_type} doc: ${skill.doc_ext_id}`));
10216
+ console.log("");
10217
+ console.log(body);
10218
+ })()
10219
+ );
10220
+ }
10079
10221
 
10080
10222
  // src/index.ts
10081
10223
  console.debug = () => {
@@ -10086,7 +10228,7 @@ console.info = (...args) => {
10086
10228
  _origInfo(...args);
10087
10229
  };
10088
10230
  var program = new commander.Command();
10089
- program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.66").showHelpAfterError(true).showSuggestionAfterError(true);
10231
+ program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.68").showHelpAfterError(true).showSuggestionAfterError(true);
10090
10232
  registerConfigCommand(program);
10091
10233
  registerLoginCommand(program);
10092
10234
  registerRegisterCommand(program);
@@ -10123,6 +10265,7 @@ registerProjectCommand(program);
10123
10265
  registerFilesCommand(program);
10124
10266
  registerUsageCommand(program);
10125
10267
  registerAuthCommand(program);
10268
+ registerSkillsCommand(program);
10126
10269
  applyHelpGroups(program, {
10127
10270
  "Getting started:": [
10128
10271
  "quickstart",