@storyclaw/talenthub 0.2.0 → 0.3.1

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.
@@ -53,7 +53,6 @@ export async function agentInstall(name, options) {
53
53
  id: manifest.id,
54
54
  name: manifest.name,
55
55
  skills: manifest.skills,
56
- model: manifest.model,
57
56
  });
58
57
  writeConfig(updatedCfg);
59
58
  markInstalled(manifest.id, manifest.version);
@@ -56,7 +56,6 @@ async function updateAgent(agentId) {
56
56
  id: manifest.id,
57
57
  name: manifest.name,
58
58
  skills: manifest.skills,
59
- model: manifest.model,
60
59
  });
61
60
  writeConfig(updatedCfg);
62
61
  markInstalled(manifest.id, manifest.version);
@@ -1,7 +1,9 @@
1
1
  import { execSync } from "node:child_process";
2
+ import os from "node:os";
3
+ const SAFE_CWD = os.homedir();
2
4
  function hasClawhub() {
3
5
  try {
4
- execSync("clawhub --version", { stdio: "pipe" });
6
+ execSync("clawhub -V", { stdio: "pipe", cwd: SAFE_CWD });
5
7
  return true;
6
8
  }
7
9
  catch {
@@ -21,8 +23,9 @@ export function isClawhubAvailable() {
21
23
  }
22
24
  export function installSkill(slug, workdir) {
23
25
  try {
24
- execSync(`clawhub install ${slug} --workdir "${workdir}" --no-input`, {
26
+ execSync(`clawhub install ${slug} --workdir "${workdir}" --no-input --force`, {
25
27
  stdio: "inherit",
28
+ cwd: workdir,
26
29
  });
27
30
  return true;
28
31
  }
@@ -33,8 +36,9 @@ export function installSkill(slug, workdir) {
33
36
  }
34
37
  export function updateAllSkills(workdir) {
35
38
  try {
36
- execSync(`clawhub update --all --workdir "${workdir}" --no-input`, {
39
+ execSync(`clawhub update --all --workdir "${workdir}" --no-input --force`, {
37
40
  stdio: "inherit",
41
+ cwd: workdir,
38
42
  });
39
43
  return true;
40
44
  }
@@ -31,12 +31,21 @@ export function findAgentIndex(cfg, agentId) {
31
31
  return cfg.agents?.list?.findIndex((e) => e.id?.toLowerCase() === id) ?? -1;
32
32
  }
33
33
  export function addOrUpdateAgent(cfg, entry) {
34
- const list = [...(cfg.agents?.list ?? [])];
34
+ const existingList = cfg.agents?.list ?? [];
35
+ const list = [...existingList];
35
36
  const idx = findAgentIndex(cfg, entry.id);
36
37
  if (idx >= 0) {
37
38
  list[idx] = { ...list[idx], ...entry };
38
39
  }
39
40
  else {
41
+ // When there was no agents.list (implicit "main" agent from defaults)
42
+ // and we're adding a non-main agent, prepend a "main" placeholder so
43
+ // the gateway still sees the original default agent.
44
+ if (existingList.length === 0 &&
45
+ entry.id.toLowerCase() !== "main" &&
46
+ cfg.agents?.defaults) {
47
+ list.unshift({ id: "main", default: true });
48
+ }
40
49
  list.push(entry);
41
50
  }
42
51
  return { ...cfg, agents: { ...cfg.agents, list } };
@@ -2,6 +2,9 @@
2
2
  * fetch wrapper with timeout + retry for transient network errors.
3
3
  * Retries only on TypeError (network-level failures like ETIMEDOUT,
4
4
  * EHOSTUNREACH, ECONNRESET); HTTP errors are returned as-is.
5
+ *
6
+ * The first retry is silent and fast (500ms) to absorb transient
7
+ * connection-establishment failures (common with Cloudflare + undici).
5
8
  */
6
9
  export declare function fetchRetry(url: string, init?: RequestInit & {
7
10
  retries?: number;
package/dist/lib/fetch.js CHANGED
@@ -1,9 +1,12 @@
1
1
  const DEFAULT_TIMEOUT_MS = 30_000;
2
- const DEFAULT_MAX_RETRIES = 3;
2
+ const DEFAULT_MAX_RETRIES = 4;
3
3
  /**
4
4
  * fetch wrapper with timeout + retry for transient network errors.
5
5
  * Retries only on TypeError (network-level failures like ETIMEDOUT,
6
6
  * EHOSTUNREACH, ECONNRESET); HTTP errors are returned as-is.
7
+ *
8
+ * The first retry is silent and fast (500ms) to absorb transient
9
+ * connection-establishment failures (common with Cloudflare + undici).
7
10
  */
8
11
  export async function fetchRetry(url, init) {
9
12
  const maxRetries = init?.retries ?? DEFAULT_MAX_RETRIES;
@@ -19,8 +22,11 @@ export async function fetchRetry(url, init) {
19
22
  catch (err) {
20
23
  lastError = err;
21
24
  if (attempt < maxRetries) {
22
- const delay = attempt * 1_000;
23
- console.warn(` Network error, retrying (${attempt}/${maxRetries}) in ${delay / 1000}s...`);
25
+ const silent = attempt === 1;
26
+ const delay = silent ? 500 : attempt * 1_000;
27
+ if (!silent) {
28
+ console.warn(` Network error, retrying (${attempt - 1}/${maxRetries - 1}) in ${delay / 1000}s...`);
29
+ }
24
30
  await new Promise((r) => setTimeout(r, delay));
25
31
  }
26
32
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storyclaw/talenthub",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "CLI tool to manage StoryClaw AI agents",
5
5
  "type": "module",
6
6
  "bin": {