@miriad-systems/nuum 0.1.13 → 0.2.0

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/index.js +201 -35
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13356,7 +13356,7 @@ var require_compile = __commonJS((exports) => {
13356
13356
  const schOrFunc = root.refs[ref];
13357
13357
  if (schOrFunc)
13358
13358
  return schOrFunc;
13359
- let _sch = resolve4.call(this, root, ref);
13359
+ let _sch = resolve5.call(this, root, ref);
13360
13360
  if (_sch === undefined) {
13361
13361
  const schema = (_a17 = root.localRefs) === null || _a17 === undefined ? undefined : _a17[ref];
13362
13362
  const { schemaId } = this.opts;
@@ -13383,7 +13383,7 @@ var require_compile = __commonJS((exports) => {
13383
13383
  function sameSchemaEnv(s1, s2) {
13384
13384
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
13385
13385
  }
13386
- function resolve4(root, ref) {
13386
+ function resolve5(root, ref) {
13387
13387
  let sch;
13388
13388
  while (typeof (sch = this.refs[ref]) == "string")
13389
13389
  ref = sch;
@@ -13913,7 +13913,7 @@ var require_fast_uri = __commonJS((exports, module) => {
13913
13913
  }
13914
13914
  return uri;
13915
13915
  }
13916
- function resolve4(baseURI, relativeURI, options) {
13916
+ function resolve5(baseURI, relativeURI, options) {
13917
13917
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
13918
13918
  const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
13919
13919
  schemelessOptions.skipEscape = true;
@@ -14141,7 +14141,7 @@ var require_fast_uri = __commonJS((exports, module) => {
14141
14141
  var fastUri = {
14142
14142
  SCHEMES,
14143
14143
  normalize,
14144
- resolve: resolve4,
14144
+ resolve: resolve5,
14145
14145
  resolveComponent,
14146
14146
  equal,
14147
14147
  serialize,
@@ -16933,7 +16933,7 @@ var require_dist = __commonJS((exports, module) => {
16933
16933
  exports.default = formatsPlugin;
16934
16934
  });
16935
16935
 
16936
- // node_modules/cross-spawn/node_modules/isexe/windows.js
16936
+ // node_modules/cross-spawn/node_modules/which/node_modules/isexe/windows.js
16937
16937
  var require_windows = __commonJS((exports, module) => {
16938
16938
  module.exports = isexe;
16939
16939
  isexe.sync = sync;
@@ -16971,7 +16971,7 @@ var require_windows = __commonJS((exports, module) => {
16971
16971
  }
16972
16972
  });
16973
16973
 
16974
- // node_modules/cross-spawn/node_modules/isexe/mode.js
16974
+ // node_modules/cross-spawn/node_modules/which/node_modules/isexe/mode.js
16975
16975
  var require_mode = __commonJS((exports, module) => {
16976
16976
  module.exports = isexe;
16977
16977
  isexe.sync = sync;
@@ -17002,7 +17002,7 @@ var require_mode = __commonJS((exports, module) => {
17002
17002
  }
17003
17003
  });
17004
17004
 
17005
- // node_modules/cross-spawn/node_modules/isexe/index.js
17005
+ // node_modules/cross-spawn/node_modules/which/node_modules/isexe/index.js
17006
17006
  var require_isexe = __commonJS((exports, module) => {
17007
17007
  var fs7 = __require("fs");
17008
17008
  var core2;
@@ -17022,12 +17022,12 @@ var require_isexe = __commonJS((exports, module) => {
17022
17022
  if (typeof Promise !== "function") {
17023
17023
  throw new TypeError("callback not provided");
17024
17024
  }
17025
- return new Promise(function(resolve4, reject) {
17025
+ return new Promise(function(resolve5, reject) {
17026
17026
  isexe(path8, options || {}, function(er, is2) {
17027
17027
  if (er) {
17028
17028
  reject(er);
17029
17029
  } else {
17030
- resolve4(is2);
17030
+ resolve5(is2);
17031
17031
  }
17032
17032
  });
17033
17033
  });
@@ -17089,27 +17089,27 @@ var require_which = __commonJS((exports, module) => {
17089
17089
  opt = {};
17090
17090
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
17091
17091
  const found = [];
17092
- const step = (i) => new Promise((resolve4, reject) => {
17092
+ const step = (i) => new Promise((resolve5, reject) => {
17093
17093
  if (i === pathEnv.length)
17094
- return opt.all && found.length ? resolve4(found) : reject(getNotFoundError(cmd));
17094
+ return opt.all && found.length ? resolve5(found) : reject(getNotFoundError(cmd));
17095
17095
  const ppRaw = pathEnv[i];
17096
17096
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
17097
17097
  const pCmd = path8.join(pathPart, cmd);
17098
17098
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
17099
- resolve4(subStep(p, i, 0));
17099
+ resolve5(subStep(p, i, 0));
17100
17100
  });
17101
- const subStep = (p, i, ii) => new Promise((resolve4, reject) => {
17101
+ const subStep = (p, i, ii) => new Promise((resolve5, reject) => {
17102
17102
  if (ii === pathExt.length)
17103
- return resolve4(step(i + 1));
17103
+ return resolve5(step(i + 1));
17104
17104
  const ext = pathExt[ii];
17105
17105
  isexe(p + ext, { pathExt: pathExtExe }, (er, is2) => {
17106
17106
  if (!er && is2) {
17107
17107
  if (opt.all)
17108
17108
  found.push(p + ext);
17109
17109
  else
17110
- return resolve4(p + ext);
17110
+ return resolve5(p + ext);
17111
17111
  }
17112
- return resolve4(subStep(p, i, ii + 1));
17112
+ return resolve5(subStep(p, i, ii + 1));
17113
17113
  });
17114
17114
  });
17115
17115
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -34416,6 +34416,164 @@ var activity = {
34416
34416
  mcp: new ActivityLog("mcp")
34417
34417
  };
34418
34418
 
34419
+ // src/skills/index.ts
34420
+ import { readFileSync as readFileSync5, existsSync as existsSync5, readdirSync as readdirSync3, statSync as statSync6 } from "fs";
34421
+ import { join as join6, resolve as resolve4 } from "path";
34422
+ import { homedir as homedir2 } from "os";
34423
+ var MAX_DESCRIPTION_LENGTH = 255;
34424
+ function parseFrontmatter(content) {
34425
+ if (!content.startsWith("---")) {
34426
+ return null;
34427
+ }
34428
+ const endIndex = content.indexOf(`
34429
+ ---`, 3);
34430
+ if (endIndex === -1) {
34431
+ return null;
34432
+ }
34433
+ const frontmatter = content.slice(4, endIndex).trim();
34434
+ const result = {};
34435
+ for (const line of frontmatter.split(`
34436
+ `)) {
34437
+ const colonIndex = line.indexOf(":");
34438
+ if (colonIndex === -1)
34439
+ continue;
34440
+ const key = line.slice(0, colonIndex).trim();
34441
+ let value = line.slice(colonIndex + 1).trim();
34442
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
34443
+ value = value.slice(1, -1);
34444
+ }
34445
+ if (key === "name") {
34446
+ result.name = value;
34447
+ } else if (key === "description") {
34448
+ result.description = value;
34449
+ }
34450
+ }
34451
+ return result;
34452
+ }
34453
+ function isValidSkillName(name17) {
34454
+ if (name17.length < 1 || name17.length > 64)
34455
+ return false;
34456
+ if (!/^[a-z0-9-]+$/.test(name17))
34457
+ return false;
34458
+ if (name17.startsWith("-") || name17.endsWith("-"))
34459
+ return false;
34460
+ if (name17.includes("--"))
34461
+ return false;
34462
+ return true;
34463
+ }
34464
+ function truncateDescription(description) {
34465
+ if (description.length <= MAX_DESCRIPTION_LENGTH) {
34466
+ return description;
34467
+ }
34468
+ return description.slice(0, MAX_DESCRIPTION_LENGTH - 3) + "...";
34469
+ }
34470
+ function scanDirectory(dir, skills) {
34471
+ const skillDirs = [".nuum/skills", ".claude/skills", ".codex/skills"];
34472
+ for (const skillDir of skillDirs) {
34473
+ const skillsPath = join6(dir, skillDir);
34474
+ if (!existsSync5(skillsPath))
34475
+ continue;
34476
+ try {
34477
+ const entries = readdirSync3(skillsPath);
34478
+ for (const entry of entries) {
34479
+ const entryPath = join6(skillsPath, entry);
34480
+ const stat = statSync6(entryPath);
34481
+ if (!stat.isDirectory())
34482
+ continue;
34483
+ const skillFile = join6(entryPath, "SKILL.md");
34484
+ if (!existsSync5(skillFile))
34485
+ continue;
34486
+ try {
34487
+ const content = readFileSync5(skillFile, "utf-8");
34488
+ const frontmatter = parseFrontmatter(content);
34489
+ if (!frontmatter?.name || !frontmatter?.description)
34490
+ continue;
34491
+ if (!isValidSkillName(frontmatter.name))
34492
+ continue;
34493
+ if (!skills.has(frontmatter.name)) {
34494
+ skills.set(frontmatter.name, {
34495
+ name: frontmatter.name,
34496
+ description: truncateDescription(frontmatter.description),
34497
+ path: resolve4(skillFile)
34498
+ });
34499
+ }
34500
+ } catch {}
34501
+ }
34502
+ } catch {}
34503
+ }
34504
+ }
34505
+ function scanSubdirectories(dir, skills) {
34506
+ try {
34507
+ const entries = readdirSync3(dir);
34508
+ for (const entry of entries) {
34509
+ if (entry.startsWith("."))
34510
+ continue;
34511
+ const entryPath = join6(dir, entry);
34512
+ try {
34513
+ const stat = statSync6(entryPath);
34514
+ if (stat.isDirectory()) {
34515
+ scanDirectory(entryPath, skills);
34516
+ }
34517
+ } catch {}
34518
+ }
34519
+ } catch {}
34520
+ }
34521
+ function discoverSkills(cwd = process.cwd()) {
34522
+ const skills = new Map;
34523
+ const home = homedir2();
34524
+ scanDirectory(cwd, skills);
34525
+ scanSubdirectories(cwd, skills);
34526
+ if (cwd !== home) {
34527
+ scanDirectory(home, skills);
34528
+ }
34529
+ return Array.from(skills.values());
34530
+ }
34531
+ function formatSkillsCatalog(skills) {
34532
+ if (skills.length === 0) {
34533
+ return null;
34534
+ }
34535
+ const lines = [
34536
+ "## Skills",
34537
+ "",
34538
+ "Skills are local instructions stored in `SKILL.md` files. Each entry below shows a name, description, and file path.",
34539
+ "",
34540
+ "### Available Skills"
34541
+ ];
34542
+ for (const skill of skills) {
34543
+ lines.push(`- ${skill.name}: ${skill.description} (file: ${skill.path})`);
34544
+ }
34545
+ lines.push("");
34546
+ lines.push("### Using Skills");
34547
+ lines.push("");
34548
+ lines.push("**When to use:** If a task matches a skill's description, use that skill. The user may also request a specific skill by name.");
34549
+ lines.push("");
34550
+ lines.push("**How to use (progressive disclosure):**");
34551
+ lines.push("1. Read the skill's `SKILL.md` file - only what you need for the current task");
34552
+ lines.push("2. If it references `scripts/`, `references/`, or `assets/`, load only the specific files needed");
34553
+ lines.push("3. Prefer running existing scripts over rewriting code");
34554
+ lines.push("");
34555
+ lines.push("**Multiple skills:** Choose the minimal set that covers the request. State which skills you're using and why.");
34556
+ lines.push("");
34557
+ lines.push("**Context hygiene:** Summarize long sections instead of pasting them. Don't bulk-load reference files.");
34558
+ lines.push("");
34559
+ lines.push("**Fallback:** If a skill can't be applied (missing files, unclear instructions), state the issue and continue with your best approach.");
34560
+ return lines.join(`
34561
+ `);
34562
+ }
34563
+ var cachedSkills = null;
34564
+ var cachedCwd = null;
34565
+ function getSkills(cwd = process.cwd()) {
34566
+ if (cachedSkills === null || cachedCwd !== cwd) {
34567
+ cachedSkills = discoverSkills(cwd);
34568
+ cachedCwd = cwd;
34569
+ }
34570
+ return cachedSkills;
34571
+ }
34572
+ function refreshSkills() {
34573
+ cachedSkills = null;
34574
+ cachedCwd = null;
34575
+ }
34576
+
34419
34577
  // src/context/system-prompt.ts
34420
34578
  function estimateTokens(text3) {
34421
34579
  return Math.ceil(text3.length / 4);
@@ -34475,6 +34633,13 @@ Use reflect when:
34475
34633
 
34476
34634
  Messages in your history have automatic prefixes like \`[2026-01-26 15:30 id:msg_xxx]\` showing timestamp and ID. These are added by the system for internal tracking - you don't need to reference or echo them. Just read the message content normally.
34477
34635
  `;
34636
+ const skills = getSkills();
34637
+ const skillsCatalog = formatSkillsCatalog(skills);
34638
+ if (skillsCatalog) {
34639
+ prompt += `
34640
+ ${skillsCatalog}
34641
+ `;
34642
+ }
34478
34643
  const systemPromptOverlay = await storage.session.getSystemPromptOverlay();
34479
34644
  if (systemPromptOverlay) {
34480
34645
  prompt += `
@@ -41236,7 +41401,7 @@ class Protocol {
41236
41401
  return;
41237
41402
  }
41238
41403
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1000;
41239
- await new Promise((resolve4) => setTimeout(resolve4, pollInterval));
41404
+ await new Promise((resolve5) => setTimeout(resolve5, pollInterval));
41240
41405
  options?.signal?.throwIfAborted();
41241
41406
  }
41242
41407
  } catch (error2) {
@@ -41248,7 +41413,7 @@ class Protocol {
41248
41413
  }
41249
41414
  request(request, resultSchema, options) {
41250
41415
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
41251
- return new Promise((resolve4, reject) => {
41416
+ return new Promise((resolve5, reject) => {
41252
41417
  const earlyReject = (error2) => {
41253
41418
  reject(error2);
41254
41419
  };
@@ -41326,7 +41491,7 @@ class Protocol {
41326
41491
  if (!parseResult.success) {
41327
41492
  reject(parseResult.error);
41328
41493
  } else {
41329
- resolve4(parseResult.data);
41494
+ resolve5(parseResult.data);
41330
41495
  }
41331
41496
  } catch (error2) {
41332
41497
  reject(error2);
@@ -41517,12 +41682,12 @@ class Protocol {
41517
41682
  interval = task.pollInterval;
41518
41683
  }
41519
41684
  } catch {}
41520
- return new Promise((resolve4, reject) => {
41685
+ return new Promise((resolve5, reject) => {
41521
41686
  if (signal.aborted) {
41522
41687
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
41523
41688
  return;
41524
41689
  }
41525
- const timeoutId = setTimeout(resolve4, interval);
41690
+ const timeoutId = setTimeout(resolve5, interval);
41526
41691
  signal.addEventListener("abort", () => {
41527
41692
  clearTimeout(timeoutId);
41528
41693
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -42301,7 +42466,7 @@ class StdioClientTransport {
42301
42466
  if (this._process) {
42302
42467
  throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
42303
42468
  }
42304
- return new Promise((resolve4, reject) => {
42469
+ return new Promise((resolve5, reject) => {
42305
42470
  this._process = import_cross_spawn.default(this._serverParams.command, this._serverParams.args ?? [], {
42306
42471
  env: {
42307
42472
  ...getDefaultEnvironment(),
@@ -42317,7 +42482,7 @@ class StdioClientTransport {
42317
42482
  this.onerror?.(error2);
42318
42483
  });
42319
42484
  this._process.on("spawn", () => {
42320
- resolve4();
42485
+ resolve5();
42321
42486
  });
42322
42487
  this._process.on("close", (_code) => {
42323
42488
  this._process = undefined;
@@ -42364,20 +42529,20 @@ class StdioClientTransport {
42364
42529
  if (this._process) {
42365
42530
  const processToClose = this._process;
42366
42531
  this._process = undefined;
42367
- const closePromise = new Promise((resolve4) => {
42532
+ const closePromise = new Promise((resolve5) => {
42368
42533
  processToClose.once("close", () => {
42369
- resolve4();
42534
+ resolve5();
42370
42535
  });
42371
42536
  });
42372
42537
  try {
42373
42538
  processToClose.stdin?.end();
42374
42539
  } catch {}
42375
- await Promise.race([closePromise, new Promise((resolve4) => setTimeout(resolve4, 2000).unref())]);
42540
+ await Promise.race([closePromise, new Promise((resolve5) => setTimeout(resolve5, 2000).unref())]);
42376
42541
  if (processToClose.exitCode === null) {
42377
42542
  try {
42378
42543
  processToClose.kill("SIGTERM");
42379
42544
  } catch {}
42380
- await Promise.race([closePromise, new Promise((resolve4) => setTimeout(resolve4, 2000).unref())]);
42545
+ await Promise.race([closePromise, new Promise((resolve5) => setTimeout(resolve5, 2000).unref())]);
42381
42546
  }
42382
42547
  if (processToClose.exitCode === null) {
42383
42548
  try {
@@ -42388,15 +42553,15 @@ class StdioClientTransport {
42388
42553
  this._readBuffer.clear();
42389
42554
  }
42390
42555
  send(message) {
42391
- return new Promise((resolve4) => {
42556
+ return new Promise((resolve5) => {
42392
42557
  if (!this._process?.stdin) {
42393
42558
  throw new Error("Not connected");
42394
42559
  }
42395
42560
  const json = serializeMessage(message);
42396
42561
  if (this._process.stdin.write(json)) {
42397
- resolve4();
42562
+ resolve5();
42398
42563
  } else {
42399
- this._process.stdin.once("drain", resolve4);
42564
+ this._process.stdin.once("drain", resolve5);
42400
42565
  }
42401
42566
  });
42402
42567
  }
@@ -43970,7 +44135,7 @@ class SSEClientTransport {
43970
44135
  }
43971
44136
  _startOrAuth() {
43972
44137
  const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
43973
- return new Promise((resolve4, reject) => {
44138
+ return new Promise((resolve5, reject) => {
43974
44139
  this._eventSource = new EventSource(this._url.href, {
43975
44140
  ...this._eventSourceInit,
43976
44141
  fetch: async (url2, init) => {
@@ -43991,7 +44156,7 @@ class SSEClientTransport {
43991
44156
  this._abortController = new AbortController;
43992
44157
  this._eventSource.onerror = (event) => {
43993
44158
  if (event.code === 401 && this._authProvider) {
43994
- this._authThenStart().then(resolve4, reject);
44159
+ this._authThenStart().then(resolve5, reject);
43995
44160
  return;
43996
44161
  }
43997
44162
  const error2 = new SseError(event.code, event.message, event);
@@ -44012,7 +44177,7 @@ class SSEClientTransport {
44012
44177
  this.close();
44013
44178
  return;
44014
44179
  }
44015
- resolve4();
44180
+ resolve5();
44016
44181
  });
44017
44182
  this._eventSource.onmessage = (event) => {
44018
44183
  const messageEvent = event;
@@ -45916,6 +46081,7 @@ async function runAgent(prompt, options) {
45916
46081
  });
45917
46082
  },
45918
46083
  onBeforeTurn: async () => {
46084
+ refreshSkills();
45919
46085
  const content = await onBeforeTurn?.();
45920
46086
  if (content) {
45921
46087
  const injectedMsgId = Identifier.ascending("message");
@@ -47191,8 +47357,8 @@ async function runRepl(options) {
47191
47357
  }
47192
47358
 
47193
47359
  // src/version.ts
47194
- var VERSION = "0.1.13";
47195
- var GIT_HASH = "1d9eea4";
47360
+ var VERSION = "0.2.0";
47361
+ var GIT_HASH = "a0d9ba4";
47196
47362
  var VERSION_STRING = `miriad-code v${VERSION} (${GIT_HASH})`;
47197
47363
 
47198
47364
  // src/cli/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miriad-systems/nuum",
3
- "version": "0.1.13",
3
+ "version": "0.2.0",
4
4
  "description": "AI coding agent with continuous memory - infinite context across sessions",
5
5
  "type": "module",
6
6
  "bin": {