@nseng-ai/ns 0.1.1 → 0.1.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/kernel/cli.js CHANGED
@@ -3458,7 +3458,7 @@ var require_commander = __commonJS({
3458
3458
  });
3459
3459
 
3460
3460
  // ../../kernel/src/cli/index.ts
3461
- import { z as z11 } from "zod";
3461
+ import { z as z13 } from "zod";
3462
3462
 
3463
3463
  // ../../infra/clinkr/src/exit.ts
3464
3464
  import { z } from "zod";
@@ -3516,6 +3516,14 @@ function ok(data, overrides = {}) {
3516
3516
  ...overrides.markdown === void 0 ? {} : { markdown: overrides.markdown }
3517
3517
  };
3518
3518
  }
3519
+ function negative(message, options = {}) {
3520
+ return {
3521
+ type: "negative",
3522
+ message,
3523
+ ...options.data === void 0 ? {} : { data: options.data },
3524
+ ...options.human === void 0 ? {} : { human: options.human }
3525
+ };
3526
+ }
3519
3527
  function failure(errorType, message, data) {
3520
3528
  return { type: "failure", errorType, message, ...data === void 0 ? {} : { data } };
3521
3529
  }
@@ -4714,6 +4722,9 @@ function optionalEntry(key, value) {
4714
4722
  function formatErrorMessage(error) {
4715
4723
  return error instanceof Error ? error.message : String(error);
4716
4724
  }
4725
+ function resolveHomeDir(explicit, env) {
4726
+ return explicit ?? env.HOME;
4727
+ }
4717
4728
  function isPathInside(parent, child) {
4718
4729
  const relativePath = relative(resolve(parent), resolve(child));
4719
4730
  return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
@@ -4925,8 +4936,8 @@ import { spawn } from "node:child_process";
4925
4936
  // ../../infra/foundation/src/time/timers.ts
4926
4937
  var TimerScheduler = class {
4927
4938
  async delay(delayMs) {
4928
- await new Promise((resolve5) => {
4929
- this.setTimeout(resolve5, delayMs);
4939
+ await new Promise((resolve6) => {
4940
+ this.setTimeout(resolve6, delayMs);
4930
4941
  });
4931
4942
  }
4932
4943
  };
@@ -4953,7 +4964,7 @@ var DEFAULT_TIMEOUT_KILL_GRACE_MS = 5e3;
4953
4964
  var TIMEOUT_EXIT_CODE = 124;
4954
4965
  var STARTUP_FAILURE_EXIT_CODE = 127;
4955
4966
  async function runCommand(command, args, options = {}) {
4956
- return new Promise((resolve5) => {
4967
+ return new Promise((resolve6) => {
4957
4968
  const timers = options.timers ?? systemTimerScheduler;
4958
4969
  let stdout = "";
4959
4970
  let stderr = "";
@@ -4983,7 +4994,7 @@ async function runCommand(command, args, options = {}) {
4983
4994
  if (hasSettled) return;
4984
4995
  hasSettled = true;
4985
4996
  clearTimers();
4986
- resolve5({
4997
+ resolve6({
4987
4998
  stdout,
4988
4999
  stderr,
4989
5000
  code: hasTimedOut ? TIMEOUT_EXIT_CODE : exitCode,
@@ -5065,6 +5076,8 @@ function defineRepoLocalNsExtensionDescriptor(descriptor) {
5065
5076
  import { z as z7 } from "zod";
5066
5077
 
5067
5078
  // ../../kernel/src/sdk/extension-manifest.ts
5079
+ var nsExtensionPointAcceptsValues = ["hook", "prompt"];
5080
+ var nsExtensionPointSemanticsValues = ["additive", "override"];
5068
5081
  var nsExtensionManifestCommandSchema = z7.looseObject({
5069
5082
  name: z7.string().optional(),
5070
5083
  path: z7.array(z7.string()).optional(),
@@ -5073,10 +5086,18 @@ var nsExtensionManifestCommandSchema = z7.looseObject({
5073
5086
  fullDescription: z7.string().optional(),
5074
5087
  entry: z7.string().optional()
5075
5088
  });
5089
+ var nsExtensionManifestPointSchema = z7.looseObject({
5090
+ path: z7.array(z7.string()).optional(),
5091
+ accepts: z7.enum(nsExtensionPointAcceptsValues).optional(),
5092
+ semantics: z7.enum(nsExtensionPointSemanticsValues).optional(),
5093
+ default: z7.string().optional(),
5094
+ description: z7.string().optional()
5095
+ });
5076
5096
  var nsExtensionManifestSchema = z7.looseObject({
5077
5097
  description: z7.string().optional(),
5078
5098
  group: z7.string().optional(),
5079
- commands: z7.array(z7.unknown()).optional()
5099
+ commands: z7.array(z7.unknown()).optional(),
5100
+ points: z7.array(z7.unknown()).optional()
5080
5101
  });
5081
5102
  var nsExtensionPackageManifestSchema = z7.looseObject({
5082
5103
  description: z7.string().optional(),
@@ -5175,6 +5196,7 @@ var noopNsCommandIo = {
5175
5196
  }
5176
5197
  };
5177
5198
  var noopNsProgress = {
5199
+ isLive: false,
5178
5200
  phase: () => {
5179
5201
  }
5180
5202
  };
@@ -5365,6 +5387,7 @@ function createTextGenerator() {
5365
5387
  function createRealNsCommandContext(options = {}) {
5366
5388
  const cwd = options.cwd ?? process4.cwd();
5367
5389
  const env = options.env ?? process4.env;
5390
+ const homeDir = resolveHomeDir(options.homeDir, env);
5368
5391
  const textGenerator = createTextGenerator();
5369
5392
  const confirm = createTerminalConfirmPrompt();
5370
5393
  const stdout = (text) => process4.stdout.write(text);
@@ -5373,6 +5396,7 @@ function createRealNsCommandContext(options = {}) {
5373
5396
  return {
5374
5397
  cwd,
5375
5398
  env,
5399
+ ...optionalEntry("homeDir", homeDir),
5376
5400
  textGenerator,
5377
5401
  commandIo,
5378
5402
  progress: noopNsProgress,
@@ -5623,141 +5647,1722 @@ function renderNsShellWrapperScript() {
5623
5647
  }
5624
5648
 
5625
5649
  // ../../kernel/src/extensions/registry.ts
5626
- import { existsSync as existsSync4, readdirSync as readdirSync2 } from "node:fs";
5627
- import { dirname as dirname3, join as join4, resolve as resolve4 } from "node:path";
5650
+ import { existsSync as existsSync6, readdirSync as readdirSync2 } from "node:fs";
5651
+ import { dirname as dirname4, join as join6, resolve as resolve5 } from "node:path";
5628
5652
  import process5 from "node:process";
5629
5653
  import { fileURLToPath as fileURLToPath2 } from "node:url";
5630
5654
 
5631
5655
  // ../../kernel/src/extensions/command-registry.ts
5632
- import { z as z10 } from "zod";
5656
+ import { z as z12 } from "zod";
5633
5657
 
5634
- // ../../kernel/src/extensions/zod-issue-path.ts
5635
- function classifyZodIssuePath(issue, rules, fallback) {
5636
- if (issue === void 0) return fallback;
5637
- for (const rule of rules) {
5638
- if (zodIssuePathMatchesRule(issue.path, rule)) return rule.value;
5658
+ // ../../kernel/src/extensions/built-in-extension-commands.ts
5659
+ import { z as z11 } from "zod";
5660
+
5661
+ // ../../kernel/src/project-config/points.ts
5662
+ import { existsSync as existsSync4, readFileSync as readFileSync2 } from "node:fs";
5663
+ import { dirname as dirname3, join as join3, resolve as resolve3 } from "node:path";
5664
+
5665
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
5666
+ function getLineColFromPtr(string, ptr) {
5667
+ let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
5668
+ return [lines.length, lines.pop().length + 1];
5669
+ }
5670
+ function makeCodeBlock(string, line, column) {
5671
+ let lines = string.split(/\r\n|\n|\r/g);
5672
+ let codeblock = "";
5673
+ let numberLen = (Math.log10(line + 1) | 0) + 1;
5674
+ for (let i = line - 1; i <= line + 1; i++) {
5675
+ let l = lines[i - 1];
5676
+ if (!l)
5677
+ continue;
5678
+ codeblock += i.toString().padEnd(numberLen, " ");
5679
+ codeblock += ": ";
5680
+ codeblock += l;
5681
+ codeblock += "\n";
5682
+ if (i === line) {
5683
+ codeblock += " ".repeat(numberLen + column + 2);
5684
+ codeblock += "^\n";
5685
+ }
5639
5686
  }
5640
- return fallback;
5687
+ return codeblock;
5641
5688
  }
5642
- function classifyFirstMatchingZodIssuePath(issues, rules, fallback) {
5643
- for (const issue of issues) {
5644
- const kind = classifyZodIssuePath(issue, rules, fallback);
5645
- if (kind !== fallback) return kind;
5689
+ var TomlError = class extends Error {
5690
+ line;
5691
+ column;
5692
+ codeblock;
5693
+ constructor(message, options) {
5694
+ const [line, column] = getLineColFromPtr(options.toml, options.ptr);
5695
+ const codeblock = makeCodeBlock(options.toml, line, column);
5696
+ super(`Invalid TOML document: ${message}
5697
+
5698
+ ${codeblock}`, options);
5699
+ this.line = line;
5700
+ this.column = column;
5701
+ this.codeblock = codeblock;
5646
5702
  }
5647
- return fallback;
5703
+ };
5704
+
5705
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/util.js
5706
+ function isEscaped(str, ptr) {
5707
+ let i = 0;
5708
+ while (str[ptr - ++i] === "\\")
5709
+ ;
5710
+ return --i && i % 2;
5711
+ }
5712
+ function indexOfNewline(str, start = 0, end = str.length) {
5713
+ let idx = str.indexOf("\n", start);
5714
+ if (str[idx - 1] === "\r")
5715
+ idx--;
5716
+ return idx <= end ? idx : -1;
5717
+ }
5718
+ function skipComment(str, ptr) {
5719
+ for (let i = ptr; i < str.length; i++) {
5720
+ let c = str[i];
5721
+ if (c === "\n")
5722
+ return i;
5723
+ if (c === "\r" && str[i + 1] === "\n")
5724
+ return i + 1;
5725
+ if (c < " " && c !== " " || c === "\x7F") {
5726
+ throw new TomlError("control characters are not allowed in comments", {
5727
+ toml: str,
5728
+ ptr
5729
+ });
5730
+ }
5731
+ }
5732
+ return str.length;
5648
5733
  }
5649
- function zodIssuePathMatchesRule(path, rule) {
5650
- if (rule.match === "exact" && path.length !== rule.pattern.length) return false;
5651
- if (rule.match === "prefix" && path.length < rule.pattern.length) return false;
5652
- return rule.pattern.every((segment, index) => zodIssuePathSegmentMatches(segment, path[index]));
5734
+ function skipVoid(str, ptr, banNewLines, banComments) {
5735
+ let c;
5736
+ while (1) {
5737
+ while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n"))
5738
+ ptr++;
5739
+ if (banComments || c !== "#")
5740
+ break;
5741
+ ptr = skipComment(str, ptr);
5742
+ }
5743
+ return ptr;
5744
+ }
5745
+ function skipUntil(str, ptr, sep, end, banNewLines = false) {
5746
+ if (!end) {
5747
+ ptr = indexOfNewline(str, ptr);
5748
+ return ptr < 0 ? str.length : ptr;
5749
+ }
5750
+ for (let i = ptr; i < str.length; i++) {
5751
+ let c = str[i];
5752
+ if (c === "#") {
5753
+ i = indexOfNewline(str, i);
5754
+ } else if (c === sep) {
5755
+ return i + 1;
5756
+ } else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
5757
+ return i;
5758
+ }
5759
+ }
5760
+ throw new TomlError("cannot find end of structure", {
5761
+ toml: str,
5762
+ ptr
5763
+ });
5653
5764
  }
5654
- function zodIssuePathSegmentMatches(segment, value) {
5655
- if (typeof segment === "string") return value === segment;
5656
- return typeof value === "number";
5765
+ function getStringEnd(str, seek) {
5766
+ let first = str[seek];
5767
+ let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] ? str.slice(seek, seek + 3) : first;
5768
+ seek += target.length - 1;
5769
+ do
5770
+ seek = str.indexOf(target, ++seek);
5771
+ while (seek > -1 && first !== "'" && isEscaped(str, seek));
5772
+ if (seek > -1) {
5773
+ seek += target.length;
5774
+ if (target.length > 1) {
5775
+ if (str[seek] === first)
5776
+ seek++;
5777
+ if (str[seek] === first)
5778
+ seek++;
5779
+ }
5780
+ }
5781
+ return seek;
5657
5782
  }
5658
5783
 
5659
- // ../../kernel/src/extensions/command-registry.ts
5660
- var NS_COMMAND_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
5661
- var NS_COMMAND_NAME_RULE = "[a-z][a-z0-9-]*";
5662
- var builtInCommandDefinitions = {};
5663
- var nsCommandSchema = z10.object({
5664
- name: z10.string(),
5665
- summary: z10.string(),
5666
- description: z10.string(),
5667
- schema: z10.custom(isZodObjectSchema).optional(),
5668
- positionals: z10.custom(isRecord).optional(),
5669
- options: z10.custom(isRecord).optional(),
5670
- resultSchema: z10.custom(isZodSchema).optional(),
5671
- renderHuman: z10.custom((value) => typeof value === "function").optional(),
5672
- renderMarkdown: z10.custom((value) => typeof value === "function").optional(),
5673
- completionProvider: z10.custom((value) => typeof value === "function").optional(),
5674
- run: z10.custom((value) => typeof value === "function")
5675
- });
5676
- var nsExtensionSchema = z10.object({
5677
- commands: z10.array(nsCommandSchema).optional().default([])
5678
- });
5679
- var nsResultSchema = z10.discriminatedUnion("ok", [
5680
- z10.object({ ok: z10.literal(true), message: z10.string() }),
5681
- z10.object({ ok: z10.literal(false), exitCode: z10.number(), message: z10.string() })
5682
- ]);
5683
- function commandSegments(path) {
5684
- if (path.segments !== void 0) return path.segments;
5685
- return path.group === void 0 ? [path.name] : [path.group, path.name];
5686
- }
5687
- function commandKey(path) {
5688
- return commandSegments(path).join("/");
5689
- }
5690
- function commandLeafName(path) {
5691
- return path.segments?.at(-1) ?? path.name;
5784
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/date.js
5785
+ var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
5786
+ var TomlDate = class _TomlDate extends Date {
5787
+ #hasDate = false;
5788
+ #hasTime = false;
5789
+ #offset = null;
5790
+ constructor(date) {
5791
+ let hasDate = true;
5792
+ let hasTime = true;
5793
+ let offset = "Z";
5794
+ if (typeof date === "string") {
5795
+ let match = date.match(DATE_TIME_RE);
5796
+ if (match) {
5797
+ if (!match[1]) {
5798
+ hasDate = false;
5799
+ date = `0000-01-01T${date}`;
5800
+ }
5801
+ hasTime = !!match[2];
5802
+ hasTime && date[10] === " " && (date = date.replace(" ", "T"));
5803
+ if (match[2] && +match[2] > 23) {
5804
+ date = "";
5805
+ } else {
5806
+ offset = match[3] || null;
5807
+ date = date.toUpperCase();
5808
+ if (!offset && hasTime)
5809
+ date += "Z";
5810
+ }
5811
+ } else {
5812
+ date = "";
5813
+ }
5814
+ }
5815
+ super(date);
5816
+ if (!isNaN(this.getTime())) {
5817
+ this.#hasDate = hasDate;
5818
+ this.#hasTime = hasTime;
5819
+ this.#offset = offset;
5820
+ }
5821
+ }
5822
+ isDateTime() {
5823
+ return this.#hasDate && this.#hasTime;
5824
+ }
5825
+ isLocal() {
5826
+ return !this.#hasDate || !this.#hasTime || !this.#offset;
5827
+ }
5828
+ isDate() {
5829
+ return this.#hasDate && !this.#hasTime;
5830
+ }
5831
+ isTime() {
5832
+ return this.#hasTime && !this.#hasDate;
5833
+ }
5834
+ isValid() {
5835
+ return this.#hasDate || this.#hasTime;
5836
+ }
5837
+ toISOString() {
5838
+ let iso = super.toISOString();
5839
+ if (this.isDate())
5840
+ return iso.slice(0, 10);
5841
+ if (this.isTime())
5842
+ return iso.slice(11, 23);
5843
+ if (this.#offset === null)
5844
+ return iso.slice(0, -1);
5845
+ if (this.#offset === "Z")
5846
+ return iso;
5847
+ let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
5848
+ offset = this.#offset[0] === "-" ? offset : -offset;
5849
+ let offsetDate = new Date(this.getTime() - offset * 6e4);
5850
+ return offsetDate.toISOString().slice(0, -1) + this.#offset;
5851
+ }
5852
+ static wrapAsOffsetDateTime(jsDate, offset = "Z") {
5853
+ let date = new _TomlDate(jsDate);
5854
+ date.#offset = offset;
5855
+ return date;
5856
+ }
5857
+ static wrapAsLocalDateTime(jsDate) {
5858
+ let date = new _TomlDate(jsDate);
5859
+ date.#offset = null;
5860
+ return date;
5861
+ }
5862
+ static wrapAsLocalDate(jsDate) {
5863
+ let date = new _TomlDate(jsDate);
5864
+ date.#hasTime = false;
5865
+ date.#offset = null;
5866
+ return date;
5867
+ }
5868
+ static wrapAsLocalTime(jsDate) {
5869
+ let date = new _TomlDate(jsDate);
5870
+ date.#hasDate = false;
5871
+ date.#offset = null;
5872
+ return date;
5873
+ }
5874
+ };
5875
+
5876
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/primitive.js
5877
+ var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
5878
+ var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
5879
+ var LEADING_ZERO = /^[+-]?0[0-9_]/;
5880
+ var ESCAPE_REGEX = /^[0-9a-f]{2,8}$/i;
5881
+ var ESC_MAP = {
5882
+ b: "\b",
5883
+ t: " ",
5884
+ n: "\n",
5885
+ f: "\f",
5886
+ r: "\r",
5887
+ e: "\x1B",
5888
+ '"': '"',
5889
+ "\\": "\\"
5890
+ };
5891
+ function parseString(str, ptr = 0, endPtr = str.length) {
5892
+ let isLiteral = str[ptr] === "'";
5893
+ let isMultiline = str[ptr++] === str[ptr] && str[ptr] === str[ptr + 1];
5894
+ if (isMultiline) {
5895
+ endPtr -= 2;
5896
+ if (str[ptr += 2] === "\r")
5897
+ ptr++;
5898
+ if (str[ptr] === "\n")
5899
+ ptr++;
5900
+ }
5901
+ let tmp = 0;
5902
+ let isEscape;
5903
+ let parsed = "";
5904
+ let sliceStart = ptr;
5905
+ while (ptr < endPtr - 1) {
5906
+ let c = str[ptr++];
5907
+ if (c === "\n" || c === "\r" && str[ptr] === "\n") {
5908
+ if (!isMultiline) {
5909
+ throw new TomlError("newlines are not allowed in strings", {
5910
+ toml: str,
5911
+ ptr: ptr - 1
5912
+ });
5913
+ }
5914
+ } else if (c < " " && c !== " " || c === "\x7F") {
5915
+ throw new TomlError("control characters are not allowed in strings", {
5916
+ toml: str,
5917
+ ptr: ptr - 1
5918
+ });
5919
+ }
5920
+ if (isEscape) {
5921
+ isEscape = false;
5922
+ if (c === "x" || c === "u" || c === "U") {
5923
+ let code = str.slice(ptr, ptr += c === "x" ? 2 : c === "u" ? 4 : 8);
5924
+ if (!ESCAPE_REGEX.test(code)) {
5925
+ throw new TomlError("invalid unicode escape", {
5926
+ toml: str,
5927
+ ptr: tmp
5928
+ });
5929
+ }
5930
+ try {
5931
+ parsed += String.fromCodePoint(parseInt(code, 16));
5932
+ } catch {
5933
+ throw new TomlError("invalid unicode escape", {
5934
+ toml: str,
5935
+ ptr: tmp
5936
+ });
5937
+ }
5938
+ } else if (isMultiline && (c === "\n" || c === " " || c === " " || c === "\r")) {
5939
+ ptr = skipVoid(str, ptr - 1, true);
5940
+ if (str[ptr] !== "\n" && str[ptr] !== "\r") {
5941
+ throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
5942
+ toml: str,
5943
+ ptr: tmp
5944
+ });
5945
+ }
5946
+ ptr = skipVoid(str, ptr);
5947
+ } else if (c in ESC_MAP) {
5948
+ parsed += ESC_MAP[c];
5949
+ } else {
5950
+ throw new TomlError("unrecognized escape sequence", {
5951
+ toml: str,
5952
+ ptr: tmp
5953
+ });
5954
+ }
5955
+ sliceStart = ptr;
5956
+ } else if (!isLiteral && c === "\\") {
5957
+ tmp = ptr - 1;
5958
+ isEscape = true;
5959
+ parsed += str.slice(sliceStart, tmp);
5960
+ }
5961
+ }
5962
+ return parsed + str.slice(sliceStart, endPtr - 1);
5692
5963
  }
5693
- function commandDisplayName(path) {
5694
- return commandSegments(path).join(" ");
5964
+ function parseValue(value, toml, ptr, integersAsBigInt) {
5965
+ if (value === "true")
5966
+ return true;
5967
+ if (value === "false")
5968
+ return false;
5969
+ if (value === "-inf")
5970
+ return -Infinity;
5971
+ if (value === "inf" || value === "+inf")
5972
+ return Infinity;
5973
+ if (value === "nan" || value === "+nan" || value === "-nan")
5974
+ return NaN;
5975
+ if (value === "-0")
5976
+ return integersAsBigInt ? 0n : 0;
5977
+ let isInt = INT_REGEX.test(value);
5978
+ if (isInt || FLOAT_REGEX.test(value)) {
5979
+ if (LEADING_ZERO.test(value)) {
5980
+ throw new TomlError("leading zeroes are not allowed", {
5981
+ toml,
5982
+ ptr
5983
+ });
5984
+ }
5985
+ value = value.replace(/_/g, "");
5986
+ let numeric = +value;
5987
+ if (isNaN(numeric)) {
5988
+ throw new TomlError("invalid number", {
5989
+ toml,
5990
+ ptr
5991
+ });
5992
+ }
5993
+ if (isInt) {
5994
+ if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
5995
+ throw new TomlError("integer value cannot be represented losslessly", {
5996
+ toml,
5997
+ ptr
5998
+ });
5999
+ }
6000
+ if (isInt || integersAsBigInt === true)
6001
+ numeric = BigInt(value);
6002
+ }
6003
+ return numeric;
6004
+ }
6005
+ const date = new TomlDate(value);
6006
+ if (!date.isValid()) {
6007
+ throw new TomlError("invalid value", {
6008
+ toml,
6009
+ ptr
6010
+ });
6011
+ }
6012
+ return date;
5695
6013
  }
5696
- function commandPathMatches(left, right) {
5697
- return commandKey(left) === commandKey(right);
6014
+
6015
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/extract.js
6016
+ function sliceAndTrimEndOf(str, startPtr, endPtr) {
6017
+ let value = str.slice(startPtr, endPtr);
6018
+ let commentIdx = value.indexOf("#");
6019
+ if (commentIdx > -1) {
6020
+ skipComment(str, commentIdx);
6021
+ value = value.slice(0, commentIdx);
6022
+ }
6023
+ return [value.trimEnd(), commentIdx];
6024
+ }
6025
+ function extractValue(str, ptr, end, depth, integersAsBigInt) {
6026
+ if (depth === 0) {
6027
+ throw new TomlError("document contains excessively nested structures. aborting.", {
6028
+ toml: str,
6029
+ ptr
6030
+ });
6031
+ }
6032
+ let c = str[ptr];
6033
+ if (c === "[" || c === "{") {
6034
+ let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
6035
+ if (end) {
6036
+ endPtr2 = skipVoid(str, endPtr2);
6037
+ if (str[endPtr2] === ",")
6038
+ endPtr2++;
6039
+ else if (str[endPtr2] !== end) {
6040
+ throw new TomlError("expected comma or end of structure", {
6041
+ toml: str,
6042
+ ptr: endPtr2
6043
+ });
6044
+ }
6045
+ }
6046
+ return [value, endPtr2];
6047
+ }
6048
+ let endPtr;
6049
+ if (c === '"' || c === "'") {
6050
+ endPtr = getStringEnd(str, ptr);
6051
+ let parsed = parseString(str, ptr, endPtr);
6052
+ if (end) {
6053
+ endPtr = skipVoid(str, endPtr);
6054
+ if (str[endPtr] && str[endPtr] !== "," && str[endPtr] !== end && str[endPtr] !== "\n" && str[endPtr] !== "\r") {
6055
+ throw new TomlError("unexpected character encountered", {
6056
+ toml: str,
6057
+ ptr: endPtr
6058
+ });
6059
+ }
6060
+ endPtr += +(str[endPtr] === ",");
6061
+ }
6062
+ return [parsed, endPtr];
6063
+ }
6064
+ endPtr = skipUntil(str, ptr, ",", end);
6065
+ let slice = sliceAndTrimEndOf(str, ptr, endPtr - +(str[endPtr - 1] === ","));
6066
+ if (!slice[0]) {
6067
+ throw new TomlError("incomplete key-value declaration: no value specified", {
6068
+ toml: str,
6069
+ ptr
6070
+ });
6071
+ }
6072
+ if (end && slice[1] > -1) {
6073
+ endPtr = skipVoid(str, ptr + slice[1]);
6074
+ endPtr += +(str[endPtr] === ",");
6075
+ }
6076
+ return [
6077
+ parseValue(slice[0], str, ptr, integersAsBigInt),
6078
+ endPtr
6079
+ ];
5698
6080
  }
5699
- function listBuiltInNsCommandCandidates() {
5700
- return Object.entries(builtInCommandDefinitions).map(([name, definition]) => ({
5701
- name,
5702
- description: definition.summary,
5703
- fullDescription: definition.description,
5704
- source: { level: "built-in", label: `built-in command ${name}` },
5705
- command: definition.command
5706
- })).sort((left, right) => commandKey(left).localeCompare(commandKey(right)));
6081
+
6082
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/struct.js
6083
+ var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
6084
+ function parseKey(str, ptr, end = "=") {
6085
+ let dot = ptr - 1;
6086
+ let parsed = [];
6087
+ let endPtr = str.indexOf(end, ptr);
6088
+ if (endPtr < 0) {
6089
+ throw new TomlError("incomplete key-value: cannot find end of key", {
6090
+ toml: str,
6091
+ ptr
6092
+ });
6093
+ }
6094
+ do {
6095
+ let c = str[ptr = ++dot];
6096
+ if (c !== " " && c !== " ") {
6097
+ if (c === '"' || c === "'") {
6098
+ if (c === str[ptr + 1] && c === str[ptr + 2]) {
6099
+ throw new TomlError("multiline strings are not allowed in keys", {
6100
+ toml: str,
6101
+ ptr
6102
+ });
6103
+ }
6104
+ let eos = getStringEnd(str, ptr);
6105
+ if (eos < 0) {
6106
+ throw new TomlError("unfinished string encountered", {
6107
+ toml: str,
6108
+ ptr
6109
+ });
6110
+ }
6111
+ dot = str.indexOf(".", eos);
6112
+ let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
6113
+ let newLine = indexOfNewline(strEnd);
6114
+ if (newLine > -1) {
6115
+ throw new TomlError("newlines are not allowed in keys", {
6116
+ toml: str,
6117
+ ptr: ptr + dot + newLine
6118
+ });
6119
+ }
6120
+ if (strEnd.trimStart()) {
6121
+ throw new TomlError("found extra tokens after the string part", {
6122
+ toml: str,
6123
+ ptr: eos
6124
+ });
6125
+ }
6126
+ if (endPtr < eos) {
6127
+ endPtr = str.indexOf(end, eos);
6128
+ if (endPtr < 0) {
6129
+ throw new TomlError("incomplete key-value: cannot find end of key", {
6130
+ toml: str,
6131
+ ptr
6132
+ });
6133
+ }
6134
+ }
6135
+ parsed.push(parseString(str, ptr, eos));
6136
+ } else {
6137
+ dot = str.indexOf(".", ptr);
6138
+ let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
6139
+ if (!KEY_PART_RE.test(part)) {
6140
+ throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
6141
+ toml: str,
6142
+ ptr
6143
+ });
6144
+ }
6145
+ parsed.push(part.trimEnd());
6146
+ }
6147
+ }
6148
+ } while (dot + 1 && dot < endPtr);
6149
+ return [parsed, skipVoid(str, endPtr + 1, true, true)];
6150
+ }
6151
+ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
6152
+ let res = {};
6153
+ let seen = /* @__PURE__ */ new Set();
6154
+ let c;
6155
+ ptr++;
6156
+ while ((c = str[ptr++]) !== "}" && c) {
6157
+ if (c === ",") {
6158
+ throw new TomlError("expected value, found comma", {
6159
+ toml: str,
6160
+ ptr: ptr - 1
6161
+ });
6162
+ } else if (c === "#")
6163
+ ptr = skipComment(str, ptr);
6164
+ else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
6165
+ let k;
6166
+ let t = res;
6167
+ let hasOwn = false;
6168
+ let [key, keyEndPtr] = parseKey(str, ptr - 1);
6169
+ for (let i = 0; i < key.length; i++) {
6170
+ if (i)
6171
+ t = hasOwn ? t[k] : t[k] = {};
6172
+ k = key[i];
6173
+ if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
6174
+ throw new TomlError("trying to redefine an already defined value", {
6175
+ toml: str,
6176
+ ptr
6177
+ });
6178
+ }
6179
+ if (!hasOwn && k === "__proto__") {
6180
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
6181
+ }
6182
+ }
6183
+ if (hasOwn) {
6184
+ throw new TomlError("trying to redefine an already defined value", {
6185
+ toml: str,
6186
+ ptr
6187
+ });
6188
+ }
6189
+ let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
6190
+ seen.add(value);
6191
+ t[k] = value;
6192
+ ptr = valueEndPtr;
6193
+ }
6194
+ }
6195
+ if (!c) {
6196
+ throw new TomlError("unfinished table encountered", {
6197
+ toml: str,
6198
+ ptr
6199
+ });
6200
+ }
6201
+ return [res, ptr];
6202
+ }
6203
+ function parseArray(str, ptr, depth, integersAsBigInt) {
6204
+ let res = [];
6205
+ let c;
6206
+ ptr++;
6207
+ while ((c = str[ptr++]) !== "]" && c) {
6208
+ if (c === ",") {
6209
+ throw new TomlError("expected value, found comma", {
6210
+ toml: str,
6211
+ ptr: ptr - 1
6212
+ });
6213
+ } else if (c === "#")
6214
+ ptr = skipComment(str, ptr);
6215
+ else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
6216
+ let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
6217
+ res.push(e[0]);
6218
+ ptr = e[1];
6219
+ }
6220
+ }
6221
+ if (!c) {
6222
+ throw new TomlError("unfinished array encountered", {
6223
+ toml: str,
6224
+ ptr
6225
+ });
6226
+ }
6227
+ return [res, ptr];
5707
6228
  }
5708
- function listStaticNsCommandInfos() {
5709
- return listBuiltInNsCommandCandidates().map(toCommandCliInfo);
6229
+
6230
+ // ../../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/parse.js
6231
+ function peekTable(key, table, meta, type) {
6232
+ let t = table;
6233
+ let m = meta;
6234
+ let k;
6235
+ let hasOwn = false;
6236
+ let state;
6237
+ for (let i = 0; i < key.length; i++) {
6238
+ if (i) {
6239
+ t = hasOwn ? t[k] : t[k] = {};
6240
+ m = (state = m[k]).c;
6241
+ if (type === 0 && (state.t === 1 || state.t === 2)) {
6242
+ return null;
6243
+ }
6244
+ if (state.t === 2) {
6245
+ let l = t.length - 1;
6246
+ t = t[l];
6247
+ m = m[l].c;
6248
+ }
6249
+ }
6250
+ k = key[i];
6251
+ if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
6252
+ return null;
6253
+ }
6254
+ if (!hasOwn) {
6255
+ if (k === "__proto__") {
6256
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
6257
+ Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
6258
+ }
6259
+ m[k] = {
6260
+ t: i < key.length - 1 && type === 2 ? 3 : type,
6261
+ d: false,
6262
+ i: 0,
6263
+ c: {}
6264
+ };
6265
+ }
6266
+ }
6267
+ state = m[k];
6268
+ if (state.t !== type && !(type === 1 && state.t === 3)) {
6269
+ return null;
6270
+ }
6271
+ if (type === 2) {
6272
+ if (!state.d) {
6273
+ state.d = true;
6274
+ t[k] = [];
6275
+ }
6276
+ t[k].push(t = {});
6277
+ state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
6278
+ }
6279
+ if (state.d) {
6280
+ return null;
6281
+ }
6282
+ state.d = true;
6283
+ if (type === 1) {
6284
+ t = hasOwn ? t[k] : t[k] = {};
6285
+ } else if (type === 0 && hasOwn) {
6286
+ return null;
6287
+ }
6288
+ return [k, t, state.c];
6289
+ }
6290
+ function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
6291
+ let res = {};
6292
+ let meta = {};
6293
+ let tbl = res;
6294
+ let m = meta;
6295
+ for (let ptr = skipVoid(toml, 0); ptr < toml.length; ) {
6296
+ if (toml[ptr] === "[") {
6297
+ let isTableArray = toml[++ptr] === "[";
6298
+ let k = parseKey(toml, ptr += +isTableArray, "]");
6299
+ if (isTableArray) {
6300
+ if (toml[k[1] - 1] !== "]") {
6301
+ throw new TomlError("expected end of table declaration", {
6302
+ toml,
6303
+ ptr: k[1] - 1
6304
+ });
6305
+ }
6306
+ k[1]++;
6307
+ }
6308
+ let p = peekTable(
6309
+ k[0],
6310
+ res,
6311
+ meta,
6312
+ isTableArray ? 2 : 1
6313
+ /* Type.EXPLICIT */
6314
+ );
6315
+ if (!p) {
6316
+ throw new TomlError("trying to redefine an already defined table or value", {
6317
+ toml,
6318
+ ptr
6319
+ });
6320
+ }
6321
+ m = p[2];
6322
+ tbl = p[1];
6323
+ ptr = k[1];
6324
+ } else {
6325
+ let k = parseKey(toml, ptr);
6326
+ let p = peekTable(
6327
+ k[0],
6328
+ tbl,
6329
+ m,
6330
+ 0
6331
+ /* Type.DOTTED */
6332
+ );
6333
+ if (!p) {
6334
+ throw new TomlError("trying to redefine an already defined table or value", {
6335
+ toml,
6336
+ ptr
6337
+ });
6338
+ }
6339
+ let v = extractValue(toml, k[1], void 0, maxDepth, integersAsBigInt);
6340
+ p[1][p[0]] = v[0];
6341
+ ptr = v[1];
6342
+ }
6343
+ ptr = skipVoid(toml, ptr, true);
6344
+ if (toml[ptr] && toml[ptr] !== "\n" && toml[ptr] !== "\r") {
6345
+ throw new TomlError("each key-value declaration must be followed by an end-of-line", {
6346
+ toml,
6347
+ ptr
6348
+ });
6349
+ }
6350
+ ptr = skipVoid(toml, ptr);
6351
+ }
6352
+ return res;
5710
6353
  }
5711
- function toCommandCliInfo(candidate2) {
5712
- return {
5713
- ...candidate2.group === void 0 ? {} : { group: candidate2.group },
5714
- ...candidate2.segments === void 0 ? {} : { segments: candidate2.segments },
5715
- ...candidate2.groupDescription === void 0 ? {} : { groupDescription: candidate2.groupDescription },
5716
- name: candidate2.name,
5717
- description: candidate2.description,
5718
- fullDescription: candidate2.fullDescription
6354
+
6355
+ // ../../kernel/src/project-config/points.ts
6356
+ import { z as z10 } from "zod";
6357
+
6358
+ // ../../kernel/src/runtime/diagnostics.ts
6359
+ function makeKernelDiagnostic(request) {
6360
+ const base = {
6361
+ severity: request.severity ?? "error",
6362
+ code: request.code,
6363
+ message: request.message,
6364
+ ...optionalEntry("path", request.path)
5719
6365
  };
6366
+ return { ...base, ...request.extra ?? {} };
5720
6367
  }
5721
- function commandInfoForLoadedCommand(command, sourceLevel, path) {
5722
- const definition = path.group === void 0 ? builtInCommandDefinitions[command.name] : void 0;
5723
- if (sourceLevel === "built-in" && definition !== void 0) {
6368
+
6369
+ // ../../kernel/src/runtime/extension-root-discovery.ts
6370
+ import { existsSync as existsSync3, readdirSync, statSync } from "node:fs";
6371
+ import { join as join2 } from "node:path";
6372
+ function scanExtensionRoot(rootDir) {
6373
+ if (!existsSync3(rootDir)) return { entries: [], diagnostics: [] };
6374
+ let isDirectory;
6375
+ try {
6376
+ isDirectory = statSync(rootDir).isDirectory();
6377
+ } catch (error) {
5724
6378
  return {
5725
- name: command.name,
5726
- description: definition.summary,
5727
- fullDescription: definition.description
6379
+ entries: [],
6380
+ diagnostics: [
6381
+ diagnostic(
6382
+ "extension_root_stat_failed",
6383
+ `Could not inspect extension root ${rootDir}.
6384
+ ${formatErrorMessage(error)}`,
6385
+ { path: rootDir }
6386
+ )
6387
+ ]
5728
6388
  };
5729
6389
  }
5730
- return toCommandCliInfo({
5731
- ...path,
5732
- name: command.name,
5733
- description: command.summary,
5734
- fullDescription: command.description
5735
- });
5736
- }
5737
- function validateNsExtensionContribution(contribution, expectedPath, sourceLabel) {
5738
- const expectedName = typeof expectedPath === "string" ? expectedPath : commandLeafName(expectedPath);
5739
- const parsed = nsExtensionSchema.safeParse(contribution);
5740
- if (!parsed.success) {
6390
+ if (!isDirectory) {
5741
6391
  return {
5742
- ok: false,
5743
- message: `Invalid ns extension contribution ${sourceLabel}: ${formatNsExtensionIssue(parsed.error.issues[0])}`
6392
+ entries: [],
6393
+ diagnostics: [
6394
+ diagnostic(
6395
+ "extension_root_not_directory",
6396
+ `Extension root must be a directory: ${rootDir}.`,
6397
+ {
6398
+ path: rootDir
6399
+ }
6400
+ )
6401
+ ]
5744
6402
  };
5745
6403
  }
5746
- const command = findCommandEntry(parsed.data, expectedName);
5747
- if (command === void 0) {
6404
+ let dirents;
6405
+ try {
6406
+ dirents = readdirSync(rootDir, { withFileTypes: true });
6407
+ } catch (error) {
5748
6408
  return {
5749
- ok: false,
5750
- message: `Invalid ns extension contribution ${sourceLabel}: expected a command entry named "${expectedName}" in commands[].`
6409
+ entries: [],
6410
+ diagnostics: [
6411
+ diagnostic(
6412
+ "extension_root_read_failed",
6413
+ `Could not read extension root ${rootDir}.
6414
+ ${formatErrorMessage(error)}`,
6415
+ { path: rootDir }
6416
+ )
6417
+ ]
5751
6418
  };
5752
6419
  }
5753
- return { ok: true, command };
6420
+ const entries = [];
6421
+ for (const dirent of dirents.sort((left, right) => left.name.localeCompare(right.name))) {
6422
+ const entryPath = join2(rootDir, dirent.name);
6423
+ if (dirent.isFile()) {
6424
+ entries.push({ type: "file", name: dirent.name, path: entryPath });
6425
+ continue;
6426
+ }
6427
+ if (!dirent.isDirectory()) continue;
6428
+ const packageJsonPath = join2(entryPath, "package.json");
6429
+ if (existsSync3(packageJsonPath)) {
6430
+ entries.push({ type: "directory", name: dirent.name, path: entryPath, packageJsonPath });
6431
+ continue;
6432
+ }
6433
+ const indexPath = firstExistingDirectoryIndex(entryPath);
6434
+ entries.push({
6435
+ type: "directory",
6436
+ name: dirent.name,
6437
+ path: entryPath,
6438
+ ...indexPath === void 0 ? {} : { indexPath }
6439
+ });
6440
+ }
6441
+ return { entries, diagnostics: [] };
5754
6442
  }
5755
- async function executeNsCommand(ctx, command, request) {
5756
- const parsedRequest = (command.schema ?? z10.object({})).safeParse(request);
5757
- if (!parsedRequest.success) {
5758
- return failed(
5759
- `Invalid request for command ${command.name}: ${parsedRequest.error.issues[0]?.message ?? "request did not match command schema"}`,
5760
- 2
6443
+ function firstExistingDirectoryIndex(entryPath) {
6444
+ for (const indexFileName of ["index.ts", "index.js"]) {
6445
+ const indexPath = join2(entryPath, indexFileName);
6446
+ if (existsSync3(indexPath)) return indexPath;
6447
+ }
6448
+ return void 0;
6449
+ }
6450
+ function diagnostic(code, message, options = {}) {
6451
+ return makeKernelDiagnostic({ code, message, ...optionalEntry("path", options.path) });
6452
+ }
6453
+
6454
+ // ../../kernel/src/sdk/command-name.ts
6455
+ var NS_COMMAND_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
6456
+ var NS_COMMAND_NAME_RULE = "[a-z][a-z0-9-]*";
6457
+
6458
+ // ../../kernel/src/project-config/points.ts
6459
+ var emptyLoadedProjectConfig = { points: [], settings: /* @__PURE__ */ new Map() };
6460
+ function tryProjectConfigProbe(probe) {
6461
+ try {
6462
+ return probe();
6463
+ } catch (error) {
6464
+ if (isNodeFileNotFound(error)) return { type: "missing" };
6465
+ return { type: "error", message: formatErrorMessage(error) };
6466
+ }
6467
+ }
6468
+ var nodeProjectConfigGateway = {
6469
+ readTextFile(request) {
6470
+ return tryProjectConfigProbe(() => ({
6471
+ type: "found",
6472
+ text: readFileSync2(join3(request.repoRoot, request.relativePath), "utf8")
6473
+ }));
6474
+ },
6475
+ pathExists(request) {
6476
+ return tryProjectConfigProbe(
6477
+ () => existsSync4(join3(request.repoRoot, request.relativePath)) ? { type: "present" } : { type: "missing" }
6478
+ );
6479
+ }
6480
+ };
6481
+ function loadProjectConfig(request) {
6482
+ const readResult = request.gateway.readTextFile({
6483
+ repoRoot: request.repoRoot,
6484
+ relativePath: "ns.toml"
6485
+ });
6486
+ if (readResult.type === "missing") {
6487
+ return {
6488
+ ok: true,
6489
+ config: emptyLoadedProjectConfig,
6490
+ diagnostics: []
6491
+ };
6492
+ }
6493
+ if (readResult.type === "error") {
6494
+ return {
6495
+ ok: false,
6496
+ diagnostics: [
6497
+ diagnostic2("ns_toml_read_failed", `Failed to read ns.toml: ${readResult.message}`)
6498
+ ]
6499
+ };
6500
+ }
6501
+ return parseProjectConfigToml(readResult.text, {
6502
+ pathLabel: "ns.toml",
6503
+ pointsTable: { mode: "validate", pointDefinitions: request.pointDefinitions },
6504
+ settingsSchemas: request.settingsSchemas ?? []
6505
+ });
6506
+ }
6507
+ function parseProjectConfigToml(source, request) {
6508
+ const pathLabel = request.pathLabel ?? "ns.toml";
6509
+ let parsed;
6510
+ try {
6511
+ parsed = parse(source);
6512
+ } catch (error) {
6513
+ const causeMessage = formatErrorMessage(error);
6514
+ return {
6515
+ ok: false,
6516
+ diagnostics: [
6517
+ diagnostic2("ns_toml_invalid", `${pathLabel}: Invalid TOML.
6518
+ ${causeMessage}`, {
6519
+ causeMessage
6520
+ })
6521
+ ]
6522
+ };
6523
+ }
6524
+ const documentResult = tomlDocumentSchema.safeParse(parsed);
6525
+ if (!documentResult.success) {
6526
+ return {
6527
+ ok: false,
6528
+ diagnostics: [
6529
+ diagnostic2("ns_toml_invalid", `${pathLabel}: top-level TOML document must be a table.`)
6530
+ ]
6531
+ };
6532
+ }
6533
+ const document = documentResult.data;
6534
+ const pointsResult = request.pointsTable.mode === "skip" ? { installations: [], diagnostics: [] } : parsePointsTable({
6535
+ pathLabel,
6536
+ value: document["points"],
6537
+ pointDefinitions: request.pointsTable.pointDefinitions
6538
+ });
6539
+ const settingsResult = parseDeclaredSettings({
6540
+ pathLabel,
6541
+ document,
6542
+ settingsSchemas: request.settingsSchemas ?? []
6543
+ });
6544
+ const diagnostics = [...pointsResult.diagnostics, ...settingsResult.diagnostics];
6545
+ const config = { points: pointsResult.installations, settings: settingsResult.settings };
6546
+ if (diagnostics.length > 0) return { ok: false, config, diagnostics };
6547
+ return { ok: true, config, diagnostics: [] };
6548
+ }
6549
+ function discoverPointDefinitionsInRoot(rootDir) {
6550
+ const rootScan = scanExtensionRoot(rootDir);
6551
+ if (rootScan.diagnostics.length > 0) {
6552
+ return { pointDefinitions: [], diagnostics: rootScan.diagnostics };
6553
+ }
6554
+ const pointDefinitions = [];
6555
+ const diagnostics = [];
6556
+ for (const entry2 of rootScan.entries) {
6557
+ if (entry2.type !== "directory" || entry2.packageJsonPath === void 0) continue;
6558
+ const packageResult = discoverPackagePointDefinitions(entry2.packageJsonPath);
6559
+ pointDefinitions.push(...packageResult.pointDefinitions);
6560
+ diagnostics.push(...packageResult.diagnostics);
6561
+ }
6562
+ return { pointDefinitions, diagnostics };
6563
+ }
6564
+ function loadPointCatalog(request) {
6565
+ const definitionResult = request.pointDefinitions === void 0 ? discoverPointDefinitionsInRoot(
6566
+ join3(request.repoRoot, request.extensionRoot ?? ".ns/extensions")
6567
+ ) : { pointDefinitions: request.pointDefinitions, diagnostics: [] };
6568
+ const configResult = loadProjectConfig({
6569
+ repoRoot: request.repoRoot,
6570
+ gateway: request.gateway,
6571
+ pointDefinitions: definitionResult.pointDefinitions,
6572
+ settingsSchemas: request.settingsSchemas ?? []
6573
+ });
6574
+ return buildPointCatalog({
6575
+ repoRoot: request.repoRoot,
6576
+ gateway: request.gateway,
6577
+ pointDefinitions: definitionResult.pointDefinitions,
6578
+ config: configResult.config ?? emptyLoadedProjectConfig,
6579
+ diagnostics: [...definitionResult.diagnostics, ...configResult.diagnostics],
6580
+ ...optionalEntry("promptEnvOverride", request.promptEnvOverride),
6581
+ env: request.env ?? {}
6582
+ });
6583
+ }
6584
+ function resolvePromptPointSource(catalog, pointId) {
6585
+ const entry2 = catalog.entries.find((catalogEntry) => catalogEntry.definition.id === pointId);
6586
+ if (entry2 === void 0 || entry2.definition.accepts !== "prompt")
6587
+ return { type: "missing", pointId };
6588
+ const envOverride = findCatalogInstallation(entry2, "env-prompt");
6589
+ if (envOverride !== void 0) {
6590
+ return {
6591
+ type: "env",
6592
+ pointId,
6593
+ envVar: envOverride.envVar,
6594
+ path: envOverride.path
6595
+ };
6596
+ }
6597
+ const configured = findPromptConfigInstallation(entry2);
6598
+ if (configured !== void 0) {
6599
+ return { type: "ns.toml", pointId, path: configured.installation.path };
6600
+ }
6601
+ const conventional = findCatalogInstallation(entry2, "conventional-prompt");
6602
+ if (conventional !== void 0) {
6603
+ return { type: "conventional", pointId, path: conventional.path };
6604
+ }
6605
+ if (entry2.definition.defaultPath !== void 0 && entry2.definition.manifestPath !== void 0) {
6606
+ return {
6607
+ type: "default",
6608
+ pointId,
6609
+ path: entry2.definition.defaultPath,
6610
+ manifestPath: entry2.definition.manifestPath
6611
+ };
6612
+ }
6613
+ return { type: "missing", pointId };
6614
+ }
6615
+ function buildPointCatalog(request) {
6616
+ const diagnostics = [...request.diagnostics ?? []];
6617
+ const installationsByPoint = /* @__PURE__ */ new Map();
6618
+ for (const installation of request.config.points) {
6619
+ const existing = installationsByPoint.get(installation.pointId) ?? [];
6620
+ installationsByPoint.set(installation.pointId, [
6621
+ ...existing,
6622
+ { source: "ns.toml", installation }
6623
+ ]);
6624
+ }
6625
+ const entries = [];
6626
+ for (const definition of [...request.pointDefinitions].sort(
6627
+ (left, right) => left.id.localeCompare(right.id)
6628
+ )) {
6629
+ let installations = installationsByPoint.get(definition.id) ?? [];
6630
+ if (definition.accepts === "prompt") {
6631
+ const envOverride = findPromptEnvOverride({
6632
+ pointId: definition.id,
6633
+ env: request.env ?? {},
6634
+ ...optionalEntry("override", request.promptEnvOverride)
6635
+ });
6636
+ if (envOverride !== void 0) {
6637
+ installations = [{ source: "env-prompt", ...envOverride }, ...installations];
6638
+ diagnostics.push(
6639
+ diagnostic2(
6640
+ "point_prompt_env_override_in_effect",
6641
+ `Prompt point ${definition.id} is overridden by env var ${envOverride.envVar}.`,
6642
+ { path: definition.id, severity: "info" }
6643
+ )
6644
+ );
6645
+ }
6646
+ }
6647
+ if (definition.accepts === "prompt" && installations.length === 0) {
6648
+ const conventionalPath = `.ns/prompts/${definition.id}.md`;
6649
+ const existsResult = request.gateway.pathExists({
6650
+ repoRoot: request.repoRoot,
6651
+ relativePath: conventionalPath
6652
+ });
6653
+ if (existsResult.type === "present") {
6654
+ installations = [
6655
+ { source: "conventional-prompt", pointId: definition.id, path: conventionalPath }
6656
+ ];
6657
+ } else if (existsResult.type === "error") {
6658
+ diagnostics.push(
6659
+ diagnostic2(
6660
+ "point_conventional_prompt_probe_failed",
6661
+ `Failed to inspect conventional prompt installation ${conventionalPath}: ${existsResult.message}`,
6662
+ { path: conventionalPath }
6663
+ )
6664
+ );
6665
+ }
6666
+ }
6667
+ if (definition.semantics === "override" && installations.length > 0) {
6668
+ diagnostics.push(
6669
+ diagnostic2(
6670
+ "point_override_in_effect",
6671
+ `Override point ${definition.id} has a repo installation in effect.`,
6672
+ { path: definition.id, severity: "info" }
6673
+ )
6674
+ );
6675
+ } else if (installations.length === 0) {
6676
+ diagnostics.push(
6677
+ diagnostic2(
6678
+ "point_defined_uninstalled",
6679
+ `Point ${definition.id} is defined but not installed in this repo.`,
6680
+ { path: definition.id, severity: "info" }
6681
+ )
6682
+ );
6683
+ }
6684
+ entries.push({ definition, installations });
6685
+ }
6686
+ return { entries, diagnostics };
6687
+ }
6688
+ function findCatalogInstallation(entry2, source) {
6689
+ return entry2.installations.find(
6690
+ (installation) => installation.source === source
6691
+ );
6692
+ }
6693
+ function findPromptConfigInstallation(entry2) {
6694
+ return entry2.installations.find(
6695
+ (installation) => installation.source === "ns.toml" && installation.installation.accepts === "prompt"
6696
+ );
6697
+ }
6698
+ function findPromptEnvOverride(request) {
6699
+ if (request.override?.pointId !== request.pointId) return void 0;
6700
+ const path = request.env[request.override.envVar]?.trim();
6701
+ if (!path) return void 0;
6702
+ return { pointId: request.pointId, envVar: request.override.envVar, path };
6703
+ }
6704
+ function parsePointsTable(request) {
6705
+ if (request.value === void 0) return { installations: [], diagnostics: [] };
6706
+ const diagnostics = [];
6707
+ const tableResult = recordSchema.safeParse(request.value);
6708
+ if (!tableResult.success) {
6709
+ diagnostics.push(
6710
+ diagnostic2("points_table_invalid", `${request.pathLabel}: [points] must be a TOML table.`, {
6711
+ path: "points"
6712
+ })
6713
+ );
6714
+ return { installations: [], diagnostics };
6715
+ }
6716
+ const definitions = new Map(
6717
+ request.pointDefinitions.map((definition) => [definition.id, definition])
6718
+ );
6719
+ const installations = [];
6720
+ for (const [pointId, value] of Object.entries(tableResult.data)) {
6721
+ const definition = definitions.get(pointId);
6722
+ if (definition === void 0) {
6723
+ diagnostics.push(
6724
+ diagnostic2(
6725
+ "point_installation_undefined",
6726
+ `${request.pathLabel}: [points].${JSON.stringify(pointId)} installs an undefined point.`,
6727
+ { path: `points.${pointId}` }
6728
+ )
6729
+ );
6730
+ continue;
6731
+ }
6732
+ const parsed = parsePointInstallation({
6733
+ pathLabel: request.pathLabel,
6734
+ pointId,
6735
+ definition,
6736
+ value
6737
+ });
6738
+ if (parsed.ok) installations.push(parsed.installation);
6739
+ else diagnostics.push(parsed.diagnostic);
6740
+ }
6741
+ return { installations, diagnostics };
6742
+ }
6743
+ function parsePointInstallation(request) {
6744
+ if (request.definition.accepts === "hook") {
6745
+ return parseInstallationValue({
6746
+ ...request,
6747
+ schema: z10.array(z10.string()),
6748
+ invalidMessage: `${request.pathLabel}: hook point ${request.pointId} must be an array of command strings.`,
6749
+ buildInstallation: (commands) => ({
6750
+ pointId: request.pointId,
6751
+ accepts: "hook",
6752
+ commands
6753
+ })
6754
+ });
6755
+ }
6756
+ return parseInstallationValue({
6757
+ ...request,
6758
+ schema: z10.string().min(1),
6759
+ invalidMessage: `${request.pathLabel}: prompt point ${request.pointId} must be a non-empty path string.`,
6760
+ buildInstallation: (path) => ({ pointId: request.pointId, accepts: "prompt", path })
6761
+ });
6762
+ }
6763
+ function parseInstallationValue(request) {
6764
+ const valueResult = request.schema.safeParse(request.value);
6765
+ if (!valueResult.success) {
6766
+ return {
6767
+ ok: false,
6768
+ diagnostic: diagnostic2("point_installation_invalid", request.invalidMessage, {
6769
+ path: `points.${request.pointId}`
6770
+ })
6771
+ };
6772
+ }
6773
+ return { ok: true, installation: request.buildInstallation(valueResult.data) };
6774
+ }
6775
+ function parseDeclaredSettings(request) {
6776
+ const settings = /* @__PURE__ */ new Map();
6777
+ const diagnostics = [];
6778
+ for (const setting of request.settingsSchemas) {
6779
+ const settingValue = valueAtPath(request.document, setting.path);
6780
+ if (settingValue === void 0) continue;
6781
+ const schemaResult = setting.schema.safeParse(settingValue);
6782
+ const key = setting.path.join(".");
6783
+ if (!schemaResult.success) {
6784
+ const message = setting.invalidMessage?.({ pathLabel: request.pathLabel }) ?? `${request.pathLabel}: [${key}] does not match its declared settings schema.`;
6785
+ diagnostics.push(diagnostic2("settings_table_invalid", message, { path: key }));
6786
+ continue;
6787
+ }
6788
+ settings.set(key, schemaResult.data);
6789
+ }
6790
+ return { settings, diagnostics };
6791
+ }
6792
+ function valueAtPath(document, path) {
6793
+ let current = document;
6794
+ for (const segment of path) {
6795
+ const tableResult = recordSchema.safeParse(current);
6796
+ if (!tableResult.success) return void 0;
6797
+ current = tableResult.data[segment];
6798
+ if (current === void 0) return void 0;
6799
+ }
6800
+ return current;
6801
+ }
6802
+ function discoverPackagePointDefinitions(packageJsonPath) {
6803
+ let parsed;
6804
+ try {
6805
+ parsed = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
6806
+ } catch (error) {
6807
+ return {
6808
+ pointDefinitions: [],
6809
+ diagnostics: [
6810
+ diagnostic2(
6811
+ "extension_manifest_parse_failed",
6812
+ `Could not parse extension manifest ${packageJsonPath}.
6813
+ ${formatErrorMessage(error)}`,
6814
+ { path: packageJsonPath }
6815
+ )
6816
+ ]
6817
+ };
6818
+ }
6819
+ const manifestResult = nsExtensionPackageManifestSchema.safeParse(parsed);
6820
+ if (!manifestResult.success) {
6821
+ return {
6822
+ pointDefinitions: [],
6823
+ diagnostics: [
6824
+ diagnostic2(
6825
+ "extension_manifest_invalid",
6826
+ `Extension manifest contains invalid ns metadata: ${packageJsonPath}.`,
6827
+ { path: packageJsonPath }
6828
+ )
6829
+ ]
6830
+ };
6831
+ }
6832
+ const manifest = manifestResult.data;
6833
+ if (manifest.ns?.points === void 0) return { pointDefinitions: [], diagnostics: [] };
6834
+ const group = readManifestNameSegment(manifest.ns.group);
6835
+ if (group === void 0) {
6836
+ return {
6837
+ pointDefinitions: [],
6838
+ diagnostics: [
6839
+ diagnostic2(
6840
+ "extension_manifest_point_group_invalid",
6841
+ `Extension manifest point group must be a non-empty segment: ${packageJsonPath}.`,
6842
+ { path: packageJsonPath }
6843
+ )
6844
+ ]
6845
+ };
6846
+ }
6847
+ const pointDefinitions = [];
6848
+ const diagnostics = [];
6849
+ const location = { packageJsonPath, packageDir: dirname3(packageJsonPath) };
6850
+ for (const point of manifest.ns.points) {
6851
+ const pointResult = pointDefinitionFromManifestPoint({
6852
+ group,
6853
+ location,
6854
+ point
6855
+ });
6856
+ if (pointResult.ok) pointDefinitions.push(pointResult.definition);
6857
+ else diagnostics.push(...pointResult.diagnostics);
6858
+ }
6859
+ return { pointDefinitions, diagnostics };
6860
+ }
6861
+ function pointDefinitionFromManifestPoint(request) {
6862
+ const pointResult = nsExtensionManifestPointSchema.safeParse(request.point);
6863
+ if (!pointResult.success) {
6864
+ return {
6865
+ ok: false,
6866
+ diagnostics: [
6867
+ diagnostic2(
6868
+ "extension_manifest_point_invalid",
6869
+ `Extension manifest points must be objects with supported known fields: ${request.location.packageJsonPath}.`,
6870
+ { path: request.location.packageJsonPath }
6871
+ )
6872
+ ]
6873
+ };
6874
+ }
6875
+ const point = pointResult.data;
6876
+ const path = parsePointManifestPath(point.path);
6877
+ const diagnostics = [...path.diagnostics];
6878
+ if (point.accepts === void 0) {
6879
+ diagnostics.push(manifestPointFieldDiagnostic("accepts", request.location.packageJsonPath));
6880
+ }
6881
+ if (point.semantics === void 0) {
6882
+ diagnostics.push(manifestPointFieldDiagnostic("semantics", request.location.packageJsonPath));
6883
+ }
6884
+ let defaultPath;
6885
+ if (point.default !== void 0) {
6886
+ const defaultValidation = validateManifestRelativePath({
6887
+ location: request.location,
6888
+ rawPath: point.default
6889
+ });
6890
+ if (defaultValidation.ok) defaultPath = point.default;
6891
+ else diagnostics.push(defaultValidation.diagnostic);
6892
+ }
6893
+ if (diagnostics.length > 0 || path.value === void 0 || point.accepts === void 0 || point.semantics === void 0) {
6894
+ return { ok: false, diagnostics };
6895
+ }
6896
+ const description = readNonEmptyString(point.description);
6897
+ return {
6898
+ ok: true,
6899
+ definition: {
6900
+ id: [request.group, ...path.value].join("."),
6901
+ accepts: point.accepts,
6902
+ semantics: point.semantics,
6903
+ ...description === void 0 ? {} : { description },
6904
+ ...defaultPath === void 0 ? {} : { defaultPath },
6905
+ manifestPath: request.location.packageJsonPath
6906
+ }
6907
+ };
6908
+ }
6909
+ function parsePointManifestPath(value) {
6910
+ if (!Array.isArray(value) || value.length === 0) {
6911
+ return {
6912
+ value: void 0,
6913
+ diagnostics: [manifestPointFieldDiagnostic("path", void 0)]
6914
+ };
6915
+ }
6916
+ const segments = value.filter((segment) => typeof segment === "string");
6917
+ if (segments.length !== value.length || segments.some((segment) => readManifestNameSegment(segment) === void 0)) {
6918
+ return {
6919
+ value: void 0,
6920
+ diagnostics: [manifestPointFieldDiagnostic("path", void 0)]
6921
+ };
6922
+ }
6923
+ return { value: segments, diagnostics: [] };
6924
+ }
6925
+ function validateManifestRelativePath(request) {
6926
+ if (request.rawPath.trim() === "" || request.rawPath.startsWith("/") || request.rawPath.includes("\\")) {
6927
+ return {
6928
+ ok: false,
6929
+ diagnostic: diagnostic2(
6930
+ "extension_manifest_point_default_not_relative",
6931
+ `Extension manifest point default must be a relative POSIX-style path inside the package: ${request.rawPath}.`,
6932
+ { path: request.location.packageJsonPath }
6933
+ )
6934
+ };
6935
+ }
6936
+ if (!request.rawPath.endsWith(".md")) {
6937
+ return {
6938
+ ok: false,
6939
+ diagnostic: diagnostic2(
6940
+ "extension_manifest_point_default_not_markdown",
6941
+ `Extension manifest point default must be a markdown file path: ${request.rawPath}.`,
6942
+ { path: request.location.packageJsonPath }
6943
+ )
6944
+ };
6945
+ }
6946
+ const resolvedPath = resolve3(request.location.packageDir, request.rawPath);
6947
+ if (!isPathInside(request.location.packageDir, resolvedPath)) {
6948
+ return {
6949
+ ok: false,
6950
+ diagnostic: diagnostic2(
6951
+ "extension_manifest_point_default_escapes",
6952
+ `Extension manifest point default must not escape its package directory: ${request.rawPath}.`,
6953
+ { path: request.location.packageJsonPath }
6954
+ )
6955
+ };
6956
+ }
6957
+ return { ok: true };
6958
+ }
6959
+ function manifestPointFieldDiagnostic(field, packageJsonPath) {
6960
+ return diagnostic2(
6961
+ "extension_manifest_point_field_invalid",
6962
+ `Extension manifest point ${field} is required and must match the point manifest schema.`,
6963
+ optionalEntry("path", packageJsonPath)
6964
+ );
6965
+ }
6966
+ function readManifestNameSegment(value) {
6967
+ return typeof value === "string" && NS_COMMAND_NAME_PATTERN.test(value) ? value : void 0;
6968
+ }
6969
+ function readNonEmptyString(value) {
6970
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
6971
+ }
6972
+ function diagnostic2(code, message, options = {}) {
6973
+ return makeKernelDiagnostic({
6974
+ code,
6975
+ message,
6976
+ ...optionalEntry("path", options.path),
6977
+ extra: optionalEntry("causeMessage", options.causeMessage),
6978
+ ...optionalEntry("severity", options.severity)
6979
+ });
6980
+ }
6981
+ function isNodeFileNotFound(error) {
6982
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
6983
+ }
6984
+ var recordSchema = z10.record(z10.string(), z10.unknown());
6985
+ var tomlDocumentSchema = recordSchema;
6986
+
6987
+ // ../../kernel/src/extensions/built-in-extension-commands.ts
6988
+ var knownPromptEnvOverride = {
6989
+ pointId: "flow.submit.pr-description",
6990
+ envVar: "NS_DEV_PR_DESCRIPTION_PROMPT"
6991
+ };
6992
+ var pointDiagnosticSchema = z11.object({
6993
+ severity: z11.enum(["error", "info"]),
6994
+ code: z11.string(),
6995
+ message: z11.string(),
6996
+ path: z11.string().optional()
6997
+ });
6998
+ var pointSourceSchema = z11.union([
6999
+ z11.object({ source: z11.literal("env"), envVar: z11.string(), path: z11.string() }),
7000
+ z11.object({ source: z11.literal("repo-prompt"), path: z11.string() }),
7001
+ z11.object({ source: z11.literal("repo-hook"), commands: z11.array(z11.string()) }),
7002
+ z11.object({ source: z11.literal("conventional"), path: z11.string() }),
7003
+ z11.object({ source: z11.literal("default"), path: z11.string(), manifestPath: z11.string() }),
7004
+ z11.object({ source: z11.literal("missing") })
7005
+ ]);
7006
+ var pointSummarySchema = z11.object({
7007
+ id: z11.string(),
7008
+ accepts: z11.enum(nsExtensionPointAcceptsValues),
7009
+ semantics: z11.enum(nsExtensionPointSemanticsValues),
7010
+ description: z11.string().optional(),
7011
+ manifestPath: z11.string().optional(),
7012
+ defaultPath: z11.string().optional(),
7013
+ activeSource: pointSourceSchema,
7014
+ installationCount: z11.number().int().nonnegative()
7015
+ });
7016
+ var extensionPointsResultSchema = z11.object({
7017
+ points: z11.array(pointSummarySchema),
7018
+ diagnostics: z11.array(pointDiagnosticSchema)
7019
+ });
7020
+ var extensionPointsRequestSchema = z11.object({});
7021
+ var extensionPointDetailRequestSchema = z11.object({ id: z11.string().min(1) });
7022
+ var extensionPointDetailSchema = pointSummarySchema.extend({
7023
+ installations: z11.array(pointSourceSchema)
7024
+ });
7025
+ var extensionPointDetailResultSchema = z11.object({
7026
+ point: extensionPointDetailSchema,
7027
+ diagnostics: z11.array(pointDiagnosticSchema)
7028
+ });
7029
+ var missingPointDataSchema = z11.object({
7030
+ pointId: z11.string(),
7031
+ availablePointIds: z11.array(z11.string()),
7032
+ diagnostics: z11.array(pointDiagnosticSchema)
7033
+ });
7034
+ var extensionPointResultSchema = z11.union([
7035
+ extensionPointDetailResultSchema,
7036
+ missingPointDataSchema
7037
+ ]);
7038
+ var extensionPointsCommand = {
7039
+ name: "points",
7040
+ summary: "List defined ns points and their active sources.",
7041
+ description: "List defined ns points and their active sources.",
7042
+ schema: extensionPointsRequestSchema,
7043
+ resultSchema: extensionPointsResultSchema,
7044
+ run: (ctx) => ok(toPointsResult(loadCatalog(ctx.cwd, ctx.env))),
7045
+ renderHuman: (data) => renderPointsHuman(extensionPointsResultSchema.parse(data))
7046
+ };
7047
+ var extensionPointCommand = {
7048
+ name: "point",
7049
+ summary: "Show one ns point definition and its active source.",
7050
+ description: "Show one ns point definition and its active source.",
7051
+ schema: extensionPointDetailRequestSchema,
7052
+ positionals: { id: { position: 0 } },
7053
+ resultSchema: extensionPointResultSchema,
7054
+ run: (ctx, request) => {
7055
+ const catalog = loadCatalog(ctx.cwd, ctx.env);
7056
+ const entry2 = catalog.entries.find((candidate2) => candidate2.definition.id === request.id);
7057
+ if (entry2 === void 0) {
7058
+ const data = missingPointDataSchema.parse({
7059
+ pointId: request.id,
7060
+ availablePointIds: catalog.entries.map((candidate2) => candidate2.definition.id),
7061
+ diagnostics: catalog.diagnostics
7062
+ });
7063
+ return negative(`Point ${request.id} is not defined.`, { data });
7064
+ }
7065
+ return ok(toPointDetailResult(catalog, entry2));
7066
+ },
7067
+ renderHuman: (data) => renderPointDetailHuman(extensionPointDetailResultSchema.parse(data))
7068
+ };
7069
+ function loadCatalog(cwd, env) {
7070
+ return loadPointCatalog({
7071
+ repoRoot: cwd,
7072
+ gateway: nodeProjectConfigGateway,
7073
+ env,
7074
+ promptEnvOverride: knownPromptEnvOverride
7075
+ });
7076
+ }
7077
+ function toPointsResult(catalog) {
7078
+ return {
7079
+ points: catalog.entries.map((entry2) => toPointSummary(catalog, entry2)),
7080
+ diagnostics: [...catalog.diagnostics]
7081
+ };
7082
+ }
7083
+ function toPointDetailResult(catalog, entry2) {
7084
+ return {
7085
+ point: {
7086
+ ...toPointSummary(catalog, entry2),
7087
+ installations: entry2.installations.map(toPointSource)
7088
+ },
7089
+ diagnostics: [...diagnosticsForPoint(catalog.diagnostics, entry2.definition.id)]
7090
+ };
7091
+ }
7092
+ function toPointSummary(catalog, entry2) {
7093
+ return {
7094
+ id: entry2.definition.id,
7095
+ accepts: entry2.definition.accepts,
7096
+ semantics: entry2.definition.semantics,
7097
+ ...optionalEntries({
7098
+ description: entry2.definition.description,
7099
+ manifestPath: entry2.definition.manifestPath,
7100
+ defaultPath: entry2.definition.defaultPath
7101
+ }),
7102
+ activeSource: activeSourceForEntry(catalog, entry2),
7103
+ installationCount: entry2.installations.length
7104
+ };
7105
+ }
7106
+ function activeSourceForEntry(catalog, entry2) {
7107
+ if (entry2.definition.accepts === "prompt") {
7108
+ return pointSourceFromPromptSource(resolvePromptPointSource(catalog, entry2.definition.id));
7109
+ }
7110
+ const installation = entry2.installations.find(
7111
+ (candidate2) => candidate2.source === "ns.toml" && candidate2.installation.accepts === "hook"
7112
+ );
7113
+ if (installation?.source === "ns.toml" && installation.installation.accepts === "hook") {
7114
+ return pointSourceFromHookCommands(installation.installation.commands);
7115
+ }
7116
+ return missingPointSource();
7117
+ }
7118
+ function toPointSource(installation) {
7119
+ if (installation.source === "env-prompt") {
7120
+ return envPointSource(installation.envVar, installation.path);
7121
+ }
7122
+ if (installation.source === "conventional-prompt") {
7123
+ return conventionalPointSource(installation.path);
7124
+ }
7125
+ if (installation.installation.accepts === "hook") {
7126
+ return pointSourceFromHookCommands(installation.installation.commands);
7127
+ }
7128
+ return repoPromptPointSource(installation.installation.path);
7129
+ }
7130
+ function pointSourceFromPromptSource(source) {
7131
+ switch (source.type) {
7132
+ case "env":
7133
+ return envPointSource(source.envVar, source.path);
7134
+ case "ns.toml":
7135
+ return repoPromptPointSource(source.path);
7136
+ case "conventional":
7137
+ return conventionalPointSource(source.path);
7138
+ case "default":
7139
+ return { source: "default", path: source.path, manifestPath: source.manifestPath };
7140
+ case "missing":
7141
+ return missingPointSource();
7142
+ }
7143
+ }
7144
+ function envPointSource(envVar, path) {
7145
+ return { source: "env", envVar, path };
7146
+ }
7147
+ function repoPromptPointSource(path) {
7148
+ return { source: "repo-prompt", path };
7149
+ }
7150
+ function pointSourceFromHookCommands(commands) {
7151
+ return { source: "repo-hook", commands: [...commands] };
7152
+ }
7153
+ function conventionalPointSource(path) {
7154
+ return { source: "conventional", path };
7155
+ }
7156
+ function missingPointSource() {
7157
+ return { source: "missing" };
7158
+ }
7159
+ function diagnosticsForPoint(diagnostics, pointId) {
7160
+ return diagnostics.filter(
7161
+ (diagnostic5) => diagnostic5.path === pointId || diagnostic5.path === `points.${pointId}`
7162
+ );
7163
+ }
7164
+ function renderPointsHuman(result) {
7165
+ const lines = ["ns points:"];
7166
+ for (const point of result.points) {
7167
+ lines.push(
7168
+ `- ${point.id} (${point.accepts}, ${point.semantics}) \u2014 ${renderSource(point.activeSource)}`
7169
+ );
7170
+ }
7171
+ appendDiagnosticsSection(lines, result.diagnostics, { leadingBlank: true });
7172
+ return `${lines.join("\n")}
7173
+ `;
7174
+ }
7175
+ function renderPointDetailHuman(result) {
7176
+ const point = result.point;
7177
+ const lines = [
7178
+ `${point.id}`,
7179
+ `accepts: ${point.accepts}`,
7180
+ `semantics: ${point.semantics}`,
7181
+ `active source: ${renderSource(point.activeSource)}`
7182
+ ];
7183
+ if (point.description !== void 0) lines.push(`description: ${point.description}`);
7184
+ if (point.manifestPath !== void 0) lines.push(`definition: ${point.manifestPath}`);
7185
+ if (point.defaultPath !== void 0) lines.push(`default: ${point.defaultPath}`);
7186
+ if (point.installations.length > 0) {
7187
+ lines.push(
7188
+ "installations:",
7189
+ ...point.installations.map((source) => `- ${renderSource(source)}`)
7190
+ );
7191
+ }
7192
+ appendDiagnosticsSection(lines, result.diagnostics);
7193
+ return `${lines.join("\n")}
7194
+ `;
7195
+ }
7196
+ function appendDiagnosticsSection(lines, diagnostics, options = {}) {
7197
+ if (diagnostics.length === 0) return;
7198
+ if (options.leadingBlank === true) lines.push("");
7199
+ lines.push("diagnostics:", ...diagnostics.map(renderDiagnostic));
7200
+ }
7201
+ function renderSource(source) {
7202
+ switch (source.source) {
7203
+ case "env":
7204
+ return `env ${source.envVar} -> ${source.path}`;
7205
+ case "repo-prompt":
7206
+ return `repo ns.toml -> ${source.path}`;
7207
+ case "repo-hook":
7208
+ return `repo ns.toml commands: ${source.commands.join(", ")}`;
7209
+ case "conventional":
7210
+ return `conventional ${source.path}`;
7211
+ case "default":
7212
+ return `default ${source.path}`;
7213
+ case "missing":
7214
+ return "missing";
7215
+ }
7216
+ }
7217
+ function renderDiagnostic(diagnostic5) {
7218
+ return `- ${diagnostic5.severity} ${diagnostic5.code}: ${diagnostic5.message}`;
7219
+ }
7220
+
7221
+ // ../../kernel/src/extensions/zod-issue-path.ts
7222
+ function classifyZodIssuePath(issue, rules, fallback) {
7223
+ if (issue === void 0) return fallback;
7224
+ for (const rule of rules) {
7225
+ if (zodIssuePathMatchesRule(issue.path, rule)) return rule.value;
7226
+ }
7227
+ return fallback;
7228
+ }
7229
+ function classifyFirstMatchingZodIssuePath(issues, rules, fallback) {
7230
+ for (const issue of issues) {
7231
+ const kind = classifyZodIssuePath(issue, rules, fallback);
7232
+ if (kind !== fallback) return kind;
7233
+ }
7234
+ return fallback;
7235
+ }
7236
+ function zodIssuePathMatchesRule(path, rule) {
7237
+ if (rule.match === "exact" && path.length !== rule.pattern.length) return false;
7238
+ if (rule.match === "prefix" && path.length < rule.pattern.length) return false;
7239
+ return rule.pattern.every((segment, index) => zodIssuePathSegmentMatches(segment, path[index]));
7240
+ }
7241
+ function zodIssuePathSegmentMatches(segment, value) {
7242
+ if (typeof segment === "string") return value === segment;
7243
+ return typeof value === "number";
7244
+ }
7245
+
7246
+ // ../../kernel/src/extensions/command-registry.ts
7247
+ var builtInCommandDefinitions = {
7248
+ "extension/point": {
7249
+ name: "point",
7250
+ segments: ["extension", "point"],
7251
+ groupDescription: "Inspect ns extension metadata.",
7252
+ command: extensionPointCommand
7253
+ },
7254
+ "extension/points": {
7255
+ name: "points",
7256
+ segments: ["extension", "points"],
7257
+ groupDescription: "Inspect ns extension metadata.",
7258
+ command: extensionPointsCommand
7259
+ }
7260
+ };
7261
+ var nsCommandSchema = z12.object({
7262
+ name: z12.string(),
7263
+ summary: z12.string(),
7264
+ description: z12.string(),
7265
+ schema: z12.custom(isZodObjectSchema).optional(),
7266
+ positionals: z12.custom(isRecord).optional(),
7267
+ options: z12.custom(isRecord).optional(),
7268
+ resultSchema: z12.custom(isZodSchema).optional(),
7269
+ renderHuman: z12.custom((value) => typeof value === "function").optional(),
7270
+ renderMarkdown: z12.custom((value) => typeof value === "function").optional(),
7271
+ completionProvider: z12.custom((value) => typeof value === "function").optional(),
7272
+ run: z12.custom((value) => typeof value === "function")
7273
+ });
7274
+ var nsExtensionSchema = z12.object({
7275
+ commands: z12.array(nsCommandSchema).optional().default([])
7276
+ });
7277
+ var nsResultSchema = z12.discriminatedUnion("ok", [
7278
+ z12.object({ ok: z12.literal(true), message: z12.string() }),
7279
+ z12.object({ ok: z12.literal(false), exitCode: z12.number(), message: z12.string() })
7280
+ ]);
7281
+ function commandSegments(path) {
7282
+ if (path.segments !== void 0) return path.segments;
7283
+ return path.group === void 0 ? [path.name] : [path.group, path.name];
7284
+ }
7285
+ function commandKey(path) {
7286
+ return commandSegments(path).join("/");
7287
+ }
7288
+ function commandLeafName(path) {
7289
+ return path.segments?.at(-1) ?? path.name;
7290
+ }
7291
+ function commandDisplayName(path) {
7292
+ return commandSegments(path).join(" ");
7293
+ }
7294
+ function commandPathMatches(left, right) {
7295
+ return commandKey(left) === commandKey(right);
7296
+ }
7297
+ function listBuiltInNsCommandCandidates() {
7298
+ return Object.entries(builtInCommandDefinitions).map(([name, definition]) => ({
7299
+ name: definition.name ?? name,
7300
+ ...optionalEntries({
7301
+ group: definition.group,
7302
+ segments: definition.segments,
7303
+ groupDescription: definition.groupDescription
7304
+ }),
7305
+ description: definition.command.summary,
7306
+ fullDescription: definition.command.description,
7307
+ source: { level: "built-in", label: `built-in command ${name}` },
7308
+ command: definition.command
7309
+ })).sort((left, right) => commandKey(left).localeCompare(commandKey(right)));
7310
+ }
7311
+ function listStaticNsCommandInfos() {
7312
+ return listBuiltInNsCommandCandidates().map(toCommandCliInfo);
7313
+ }
7314
+ function toCommandCliInfo(candidate2) {
7315
+ return {
7316
+ ...optionalEntries({
7317
+ group: candidate2.group,
7318
+ segments: candidate2.segments,
7319
+ groupDescription: candidate2.groupDescription
7320
+ }),
7321
+ name: candidate2.name,
7322
+ description: candidate2.description,
7323
+ fullDescription: candidate2.fullDescription
7324
+ };
7325
+ }
7326
+ function commandInfoForLoadedCommand(command, sourceLevel, path) {
7327
+ const definition = path.group === void 0 ? builtInCommandDefinitions[command.name] : void 0;
7328
+ if (sourceLevel === "built-in" && definition !== void 0) {
7329
+ return {
7330
+ name: command.name,
7331
+ description: definition.command.summary,
7332
+ fullDescription: definition.command.description
7333
+ };
7334
+ }
7335
+ return toCommandCliInfo({
7336
+ ...path,
7337
+ name: command.name,
7338
+ description: command.summary,
7339
+ fullDescription: command.description
7340
+ });
7341
+ }
7342
+ function validateNsExtensionContribution(contribution, expectedPath, sourceLabel) {
7343
+ const expectedName = typeof expectedPath === "string" ? expectedPath : commandLeafName(expectedPath);
7344
+ const parsed = nsExtensionSchema.safeParse(contribution);
7345
+ if (!parsed.success) {
7346
+ return {
7347
+ ok: false,
7348
+ message: `Invalid ns extension contribution ${sourceLabel}: ${formatNsExtensionIssue(parsed.error.issues[0])}`
7349
+ };
7350
+ }
7351
+ const command = findCommandEntry(parsed.data, expectedName);
7352
+ if (command === void 0) {
7353
+ return {
7354
+ ok: false,
7355
+ message: `Invalid ns extension contribution ${sourceLabel}: expected a command entry named "${expectedName}" in commands[].`
7356
+ };
7357
+ }
7358
+ return { ok: true, command };
7359
+ }
7360
+ async function executeNsCommand(ctx, command, request) {
7361
+ const parsedRequest = (command.schema ?? z12.object({})).safeParse(request);
7362
+ if (!parsedRequest.success) {
7363
+ return failed(
7364
+ `Invalid request for command ${command.name}: ${parsedRequest.error.issues[0]?.message ?? "request did not match command schema"}`,
7365
+ 2
5761
7366
  );
5762
7367
  }
5763
7368
  try {
@@ -5831,13 +7436,13 @@ function formatNsCommandEntryIssueKind(kind) {
5831
7436
  return "command entry must include name, summary, description, and run";
5832
7437
  }
5833
7438
  function isZodObjectSchema(value) {
5834
- if (value instanceof z10.ZodObject) return true;
7439
+ if (value instanceof z12.ZodObject) return true;
5835
7440
  if (!isRecord(value)) return false;
5836
7441
  const candidate2 = value;
5837
7442
  return typeof candidate2.safeParse === "function" && candidate2._zod?.def?.type === "object";
5838
7443
  }
5839
7444
  function isZodSchema(value) {
5840
- if (value instanceof z10.ZodType) return true;
7445
+ if (value instanceof z12.ZodType) return true;
5841
7446
  if (!isRecord(value)) return false;
5842
7447
  const candidate2 = value;
5843
7448
  return typeof candidate2.safeParse === "function" && candidate2._zod?.def !== void 0;
@@ -5862,8 +7467,8 @@ function hasInvalidFailureExitCode(issues) {
5862
7467
  }
5863
7468
 
5864
7469
  // ../../kernel/src/extensions/discovery.ts
5865
- import { existsSync as existsSync3, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
5866
- import { basename as basename3, extname, join as join2, relative as relative3, resolve as resolve3 } from "node:path";
7470
+ import { existsSync as existsSync5, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
7471
+ import { basename as basename3, extname, join as join4, relative as relative3, resolve as resolve4 } from "node:path";
5867
7472
  var requiredManifestCommandStringFields = [
5868
7473
  {
5869
7474
  field: "description",
@@ -5880,56 +7485,14 @@ var manifestStructureIssueRules = [
5880
7485
  { pattern: ["ns", "commands"], match: "prefix", value: "commands-not-array" }
5881
7486
  ];
5882
7487
  function discoverExtensionsInRoot(rootDir) {
5883
- if (!existsSync3(rootDir)) return { commands: [], diagnostics: [] };
5884
- let rootStat;
5885
- try {
5886
- rootStat = statSync(rootDir);
5887
- } catch (error) {
5888
- return {
5889
- commands: [],
5890
- diagnostics: [
5891
- diagnostic(
5892
- "extension_root_stat_failed",
5893
- `Could not inspect extension root ${rootDir}.
5894
- ${formatUnknownError(error)}`,
5895
- { path: rootDir }
5896
- )
5897
- ]
5898
- };
5899
- }
5900
- if (!rootStat.isDirectory()) {
5901
- return {
5902
- commands: [],
5903
- diagnostics: [
5904
- diagnostic(
5905
- "extension_root_not_directory",
5906
- `Extension root must be a directory: ${rootDir}.`,
5907
- { path: rootDir }
5908
- )
5909
- ]
5910
- };
5911
- }
5912
- let entries;
5913
- try {
5914
- entries = readdirSync(rootDir, { withFileTypes: true });
5915
- } catch (error) {
5916
- return {
5917
- commands: [],
5918
- diagnostics: [
5919
- diagnostic(
5920
- "extension_root_read_failed",
5921
- `Could not read extension root ${rootDir}.
5922
- ${formatUnknownError(error)}`,
5923
- { path: rootDir }
5924
- )
5925
- ]
5926
- };
7488
+ const rootScan = scanExtensionRoot(rootDir);
7489
+ if (rootScan.diagnostics.length > 0) {
7490
+ return { commands: [], diagnostics: rootScan.diagnostics };
5927
7491
  }
5928
7492
  const commands = [];
5929
7493
  const diagnostics = [];
5930
- for (const entry2 of entries.sort((left, right) => left.name.localeCompare(right.name))) {
5931
- const entryPath = join2(rootDir, entry2.name);
5932
- if (entry2.isFile()) {
7494
+ for (const entry2 of rootScan.entries) {
7495
+ if (entry2.type === "file") {
5933
7496
  if (isLoadableExtensionFile(entry2.name)) {
5934
7497
  pushDirectEntryCommand(
5935
7498
  commands,
@@ -5937,38 +7500,35 @@ ${formatUnknownError(error)}`,
5937
7500
  commandForDirectEntry({
5938
7501
  rootDir,
5939
7502
  name: basename3(entry2.name, extname(entry2.name)),
5940
- entryPath
7503
+ entryPath: entry2.path
5941
7504
  })
5942
7505
  );
5943
7506
  }
5944
7507
  continue;
5945
7508
  }
5946
- if (!entry2.isDirectory()) continue;
5947
- const packageJsonPath = join2(entryPath, "package.json");
5948
- if (existsSync3(packageJsonPath)) {
5949
- const packageResult = discoverPackageCommands(rootDir, entryPath, packageJsonPath);
7509
+ if (entry2.packageJsonPath !== void 0) {
7510
+ const packageResult = discoverPackageCommands(rootDir, entry2.path, entry2.packageJsonPath);
5950
7511
  commands.push(...packageResult.commands);
5951
7512
  diagnostics.push(...packageResult.diagnostics);
5952
7513
  continue;
5953
7514
  }
5954
- const indexPath = firstExistingDirectoryIndex(entryPath);
5955
- if (indexPath !== void 0) {
7515
+ if (entry2.indexPath !== void 0) {
5956
7516
  pushDirectEntryCommand(
5957
7517
  commands,
5958
7518
  diagnostics,
5959
7519
  commandForDirectEntry({
5960
7520
  rootDir,
5961
7521
  name: entry2.name,
5962
- entryPath: indexPath
7522
+ entryPath: entry2.indexPath
5963
7523
  })
5964
7524
  );
5965
7525
  continue;
5966
7526
  }
5967
7527
  diagnostics.push(
5968
- diagnostic(
7528
+ diagnostic3(
5969
7529
  "extension_directory_missing_entry",
5970
- `Extension directory must contain package.json, index.ts, or index.js: ${entryPath}.`,
5971
- { path: entryPath, commandName: entry2.name }
7530
+ `Extension directory must contain package.json, index.ts, or index.js: ${entry2.path}.`,
7531
+ { path: entry2.path, commandName: entry2.name }
5972
7532
  )
5973
7533
  );
5974
7534
  }
@@ -5980,8 +7540,8 @@ ${formatUnknownError(error)}`,
5980
7540
  };
5981
7541
  }
5982
7542
  function discoverNsPackageCommands(rootDir, packageDir) {
5983
- const packageJsonPath = join2(packageDir, "package.json");
5984
- if (!existsSync3(packageJsonPath)) return { commands: [], diagnostics: [] };
7543
+ const packageJsonPath = join4(packageDir, "package.json");
7544
+ if (!existsSync5(packageJsonPath)) return { commands: [], diagnostics: [] };
5985
7545
  const resolution = resolvePackageManifest(packageJsonPath, () => ({
5986
7546
  commands: [],
5987
7547
  diagnostics: []
@@ -5993,11 +7553,11 @@ function discoverNsPackageCommands(rootDir, packageDir) {
5993
7553
  function readPackageManifest(packageJsonPath) {
5994
7554
  let parsed;
5995
7555
  try {
5996
- parsed = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
7556
+ parsed = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
5997
7557
  } catch (error) {
5998
7558
  return {
5999
7559
  outcome: "parse-failed",
6000
- diagnostic: diagnostic(
7560
+ diagnostic: diagnostic3(
6001
7561
  "extension_manifest_parse_failed",
6002
7562
  `Could not parse extension manifest ${packageJsonPath}.
6003
7563
  ${formatUnknownError(error)}`,
@@ -6027,8 +7587,8 @@ function resolvePackageManifest(packageJsonPath, onSchemaFailed) {
6027
7587
  }
6028
7588
  return { outcome: "ok", manifest: parseResult.manifest };
6029
7589
  }
6030
- function manifestReadFailureResult(diagnostic3) {
6031
- return { commands: [], diagnostics: [diagnostic3] };
7590
+ function manifestReadFailureResult(diagnostic5) {
7591
+ return { commands: [], diagnostics: [diagnostic5] };
6032
7592
  }
6033
7593
  function discoverPackageCommands(rootDir, packageDir, packageJsonPath, parsedManifest) {
6034
7594
  let manifest;
@@ -6048,8 +7608,8 @@ function discoverPackageCommands(rootDir, packageDir, packageJsonPath, parsedMan
6048
7608
  diagnostics: [missingNsDiagnostic(packageJsonPath)]
6049
7609
  };
6050
7610
  }
6051
- const packageGroup = readNonEmptyString(manifest.ns.group);
6052
- const packageGroupDescription = readNonEmptyString(manifest.ns.description) ?? readNonEmptyString(manifest.description);
7611
+ const packageGroup = readNonEmptyString2(manifest.ns.group);
7612
+ const packageGroupDescription = readNonEmptyString2(manifest.ns.description) ?? readNonEmptyString2(manifest.description);
6053
7613
  const packageGroupDiagnostic = groupDiagnostic({
6054
7614
  group: manifest.ns.group,
6055
7615
  packageJsonPath,
@@ -6088,33 +7648,26 @@ function manifestStructureDiagnostic(issues, packageJsonPath) {
6088
7648
  const kind = classifyFirstMatchingZodIssuePath(issues, manifestStructureIssueRules, "other");
6089
7649
  if (kind === "missing-ns") return missingNsDiagnostic(packageJsonPath);
6090
7650
  if (kind === "commands-not-array") return commandsNotArrayDiagnostic(packageJsonPath);
6091
- return diagnostic(
7651
+ return diagnostic3(
6092
7652
  "extension_manifest_invalid",
6093
7653
  `Extension manifest contains invalid ns metadata: ${packageJsonPath}.`,
6094
7654
  { path: packageJsonPath }
6095
7655
  );
6096
7656
  }
6097
7657
  function missingNsDiagnostic(packageJsonPath) {
6098
- return diagnostic(
7658
+ return diagnostic3(
6099
7659
  "extension_manifest_missing_ns",
6100
7660
  `Extension manifest must contain an ns object: ${packageJsonPath}.`,
6101
7661
  { path: packageJsonPath }
6102
7662
  );
6103
7663
  }
6104
7664
  function commandsNotArrayDiagnostic(packageJsonPath) {
6105
- return diagnostic(
7665
+ return diagnostic3(
6106
7666
  "extension_manifest_commands_not_array",
6107
7667
  `Extension manifest ns.commands must be an array: ${packageJsonPath}.`,
6108
7668
  { path: packageJsonPath }
6109
7669
  );
6110
7670
  }
6111
- function firstExistingDirectoryIndex(entryPath) {
6112
- for (const indexFileName of ["index.ts", "index.js"]) {
6113
- const indexPath = join2(entryPath, indexFileName);
6114
- if (existsSync3(indexPath)) return indexPath;
6115
- }
6116
- return void 0;
6117
- }
6118
7671
  function pushDirectEntryCommand(commands, diagnostics, command) {
6119
7672
  if (command.ok) commands.push(command.command);
6120
7673
  else diagnostics.push(command.diagnostic);
@@ -6123,7 +7676,7 @@ function commandForDirectEntry(options) {
6123
7676
  if (!NS_COMMAND_NAME_PATTERN.test(options.name)) {
6124
7677
  return {
6125
7678
  ok: false,
6126
- diagnostic: diagnostic(
7679
+ diagnostic: diagnostic3(
6127
7680
  "extension_command_name_invalid",
6128
7681
  `ns command entry name inferred from ${options.entryPath} must match ${NS_COMMAND_NAME_RULE}.`,
6129
7682
  { path: options.entryPath, commandName: options.name }
@@ -6138,7 +7691,7 @@ function commandForManifestEntry(options) {
6138
7691
  return {
6139
7692
  ok: false,
6140
7693
  diagnostics: [
6141
- diagnostic(
7694
+ diagnostic3(
6142
7695
  "extension_manifest_command_invalid",
6143
7696
  `Extension manifest commands must be objects with supported known fields: ${options.packageJsonPath}.`,
6144
7697
  { path: options.packageJsonPath }
@@ -6156,7 +7709,7 @@ function commandForManifestEntry(options) {
6156
7709
  const commandName = parsedEntry.commandName;
6157
7710
  if (parsedEntry.entry.name !== void 0 && !NS_COMMAND_NAME_PATTERN.test(parsedEntry.entry.name)) {
6158
7711
  diagnostics.push(
6159
- diagnostic(
7712
+ diagnostic3(
6160
7713
  "extension_manifest_command_name_invalid",
6161
7714
  `Extension manifest command name must match ${NS_COMMAND_NAME_RULE}: ${parsedEntry.entry.name}.`,
6162
7715
  diagnosticLocation(options.packageJsonPath, commandName)
@@ -6202,7 +7755,7 @@ function validateManifestEntryPath(options) {
6202
7755
  return {
6203
7756
  ok: false,
6204
7757
  diagnostics: [
6205
- diagnostic(
7758
+ diagnostic3(
6206
7759
  "extension_manifest_entry_not_relative",
6207
7760
  `Extension manifest command entry must be a relative POSIX-style path inside the package: ${options.rawEntryPath}.`,
6208
7761
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6210,12 +7763,12 @@ function validateManifestEntryPath(options) {
6210
7763
  ]
6211
7764
  };
6212
7765
  }
6213
- const resolvedEntry = resolve3(options.packageDir, options.rawEntryPath);
7766
+ const resolvedEntry = resolve4(options.packageDir, options.rawEntryPath);
6214
7767
  if (!isPathInside(options.packageDir, resolvedEntry)) {
6215
7768
  return {
6216
7769
  ok: false,
6217
7770
  diagnostics: [
6218
- diagnostic(
7771
+ diagnostic3(
6219
7772
  "extension_manifest_entry_escapes",
6220
7773
  `Extension manifest command entry must not escape its package directory: ${options.rawEntryPath}.`,
6221
7774
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6227,7 +7780,7 @@ function validateManifestEntryPath(options) {
6227
7780
  return {
6228
7781
  ok: false,
6229
7782
  diagnostics: [
6230
- diagnostic(
7783
+ diagnostic3(
6231
7784
  "extension_manifest_entry_unsupported",
6232
7785
  `Extension manifest command entry must be a .ts or .js file, excluding .d.ts: ${options.rawEntryPath}.`,
6233
7786
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6237,12 +7790,12 @@ function validateManifestEntryPath(options) {
6237
7790
  }
6238
7791
  let entryStat;
6239
7792
  try {
6240
- entryStat = statSync(resolvedEntry);
7793
+ entryStat = statSync2(resolvedEntry);
6241
7794
  } catch {
6242
7795
  return {
6243
7796
  ok: false,
6244
7797
  diagnostics: [
6245
- diagnostic(
7798
+ diagnostic3(
6246
7799
  "extension_manifest_entry_missing",
6247
7800
  `Extension manifest command entry does not exist: ${options.rawEntryPath}.`,
6248
7801
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6254,7 +7807,7 @@ function validateManifestEntryPath(options) {
6254
7807
  return {
6255
7808
  ok: false,
6256
7809
  diagnostics: [
6257
- diagnostic(
7810
+ diagnostic3(
6258
7811
  "extension_manifest_entry_not_file",
6259
7812
  `Extension manifest command entry must be a file: ${options.rawEntryPath}.`,
6260
7813
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6270,10 +7823,10 @@ function commandNameFromManifestPath(segments) {
6270
7823
  }
6271
7824
  function parseManifestCommandEntry(options) {
6272
7825
  const rawPath = parseManifestPath(options.entry.path);
6273
- const explicitName = readNonEmptyString(options.entry.name);
7826
+ const explicitName = readNonEmptyString2(options.entry.name);
6274
7827
  const commandName = explicitName ?? commandNameFromManifestPath(rawPath.value);
6275
7828
  const rawEntryGroup = options.entry.group;
6276
- const entryGroup = rawEntryGroup === void 0 ? options.packageGroup : readNonEmptyString(rawEntryGroup);
7829
+ const entryGroup = rawEntryGroup === void 0 ? options.packageGroup : readNonEmptyString2(rawEntryGroup);
6277
7830
  const segments = rawPath.value === void 0 ? void 0 : [...entryGroup === void 0 ? [] : [entryGroup], ...rawPath.value];
6278
7831
  const packageGroupDescription = options.packageGroupDescription;
6279
7832
  const shouldApplyPackageGroupDescription = packageGroupDescription !== void 0 && (entryGroup !== void 0 || (segments?.length ?? 0) > 1);
@@ -6305,7 +7858,7 @@ function parseManifestCommandEntry(options) {
6305
7858
  });
6306
7859
  }
6307
7860
  for (const { field, code } of requiredManifestCommandStringFields) {
6308
- const value = readNonEmptyString(options.entry[field]);
7861
+ const value = readNonEmptyString2(options.entry[field]);
6309
7862
  if (value !== void 0) {
6310
7863
  fields[field] = value;
6311
7864
  continue;
@@ -6318,7 +7871,7 @@ function parseManifestCommandEntry(options) {
6318
7871
  commandName
6319
7872
  });
6320
7873
  }
6321
- const fullDescription = readNonEmptyString(options.entry.fullDescription);
7874
+ const fullDescription = readNonEmptyString2(options.entry.fullDescription);
6322
7875
  if (fullDescription !== void 0) {
6323
7876
  fields.fullDescription = fullDescription;
6324
7877
  } else if (options.entry.fullDescription === void 0) {
@@ -6336,7 +7889,7 @@ function parseManifestCommandEntry(options) {
6336
7889
  }
6337
7890
  function pushManifestStringDiagnostic(options) {
6338
7891
  options.diagnostics.push(
6339
- diagnostic(
7892
+ diagnostic3(
6340
7893
  options.code,
6341
7894
  `Extension manifest command ${options.field} must be a non-empty string: ${options.packageJsonPath}.`,
6342
7895
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6345,9 +7898,9 @@ function pushManifestStringDiagnostic(options) {
6345
7898
  }
6346
7899
  function groupDiagnostic(options) {
6347
7900
  if (options.group === void 0) return void 0;
6348
- const group = readNonEmptyString(options.group);
7901
+ const group = readNonEmptyString2(options.group);
6349
7902
  if (group !== void 0 && NS_COMMAND_NAME_PATTERN.test(group)) return void 0;
6350
- return diagnostic(
7903
+ return diagnostic3(
6351
7904
  "extension_manifest_command_group_invalid",
6352
7905
  `Extension manifest command group must match ${NS_COMMAND_NAME_RULE}.`,
6353
7906
  diagnosticLocation(options.packageJsonPath, options.commandName)
@@ -6359,7 +7912,7 @@ function parseManifestPath(value) {
6359
7912
  return {
6360
7913
  value: void 0,
6361
7914
  diagnostics: [
6362
- diagnostic(
7915
+ diagnostic3(
6363
7916
  "extension_manifest_command_path_invalid",
6364
7917
  `Extension manifest command path must be a non-empty array of segments matching ${NS_COMMAND_NAME_RULE}.`
6365
7918
  )
@@ -6371,7 +7924,7 @@ function parseManifestPath(value) {
6371
7924
  return {
6372
7925
  value: void 0,
6373
7926
  diagnostics: [
6374
- diagnostic(
7927
+ diagnostic3(
6375
7928
  "extension_manifest_command_path_invalid",
6376
7929
  `Extension manifest command path segments must match ${NS_COMMAND_NAME_RULE}.`
6377
7930
  )
@@ -6380,7 +7933,7 @@ function parseManifestPath(value) {
6380
7933
  }
6381
7934
  return { value: segments, diagnostics: [] };
6382
7935
  }
6383
- function readNonEmptyString(value) {
7936
+ function readNonEmptyString2(value) {
6384
7937
  return typeof value === "string" && value.trim() !== "" ? value : void 0;
6385
7938
  }
6386
7939
  function buildCommand(options) {
@@ -6398,7 +7951,7 @@ function buildCommand(options) {
6398
7951
  function moduleReferenceForEntryPath(entryPath) {
6399
7952
  let source;
6400
7953
  try {
6401
- source = readFileSync2(entryPath, "utf8");
7954
+ source = readFileSync3(entryPath, "utf8");
6402
7955
  } catch {
6403
7956
  return {};
6404
7957
  }
@@ -6418,7 +7971,7 @@ function isLoadableExtensionFile(name) {
6418
7971
  return extension === ".ts" || extension === ".js";
6419
7972
  }
6420
7973
  function relativeDisplayPath(rootDir, entryPath) {
6421
- return join2(basename3(rootDir), relative3(rootDir, entryPath));
7974
+ return join4(basename3(rootDir), relative3(rootDir, entryPath));
6422
7975
  }
6423
7976
  function commandSortKey(command) {
6424
7977
  return command.displayPath;
@@ -6429,13 +7982,13 @@ function diagnosticLocation(path, commandName) {
6429
7982
  ...optionalEntry("commandName", commandName)
6430
7983
  };
6431
7984
  }
6432
- function diagnostic(code, message, options = {}) {
6433
- return {
6434
- severity: "error",
7985
+ function diagnostic3(code, message, options = {}) {
7986
+ return makeKernelDiagnostic({
6435
7987
  code,
6436
7988
  message,
6437
- ...optionalEntries({ path: options.path, commandName: options.commandName })
6438
- };
7989
+ ...optionalEntry("path", options.path),
7990
+ extra: optionalEntry("commandName", options.commandName)
7991
+ });
6439
7992
  }
6440
7993
 
6441
7994
  // ../../kernel/src/extensions/module-reference.ts
@@ -6518,7 +8071,7 @@ async function loadNsExtensionContribution(reference) {
6518
8071
  } catch (error) {
6519
8072
  return {
6520
8073
  ok: false,
6521
- diagnostic: diagnostic2(
8074
+ diagnostic: diagnostic4(
6522
8075
  "ns_extension_contribution_import_failed",
6523
8076
  `Failed to load ns extension contribution ${displayPath}.
6524
8077
  ${formatUnknownError(error)}`,
@@ -6534,12 +8087,12 @@ async function loadDefaultExport(reference) {
6534
8087
  loaded: async (loadedReference) => await loadedReference.load()
6535
8088
  });
6536
8089
  }
6537
- function diagnostic2(code, message, path) {
8090
+ function diagnostic4(code, message, path) {
6538
8091
  return { severity: "error", code, message, path };
6539
8092
  }
6540
8093
 
6541
8094
  // ../../infra/foundation/src/config/xdg-path.ts
6542
- import { isAbsolute as isAbsolute2, join as join3 } from "node:path";
8095
+ import { isAbsolute as isAbsolute2, join as join5 } from "node:path";
6543
8096
 
6544
8097
  // ../../infra/foundation/src/primitives/result.ts
6545
8098
  function resultOk(value) {
@@ -6580,17 +8133,17 @@ function resolveXdgHome(kind, env) {
6580
8133
  message: `HOME environment variable must be absolute to resolve default ${XDG_ENV_BY_KIND[kind]}: ${home}`
6581
8134
  });
6582
8135
  }
6583
- return resultOk(join3(home, ...XDG_DEFAULT_SEGMENTS_BY_KIND[kind]));
8136
+ return resultOk(join5(home, ...XDG_DEFAULT_SEGMENTS_BY_KIND[kind]));
6584
8137
  }
6585
8138
  function resolveNsXdgPath(options) {
6586
8139
  if (options.overrideEnv !== void 0) {
6587
8140
  const override = resolvePathOverride({ env: options.env, name: options.overrideEnv });
6588
8141
  if (!override.ok) return override;
6589
- if (override.value !== void 0) return resultOk(join3(override.value, ...options.segments ?? []));
8142
+ if (override.value !== void 0) return resultOk(join5(override.value, ...options.segments ?? []));
6590
8143
  }
6591
8144
  const home = resolveXdgHome(options.kind, options.env);
6592
8145
  if (!home.ok) return home;
6593
- return resultOk(join3(home.value, "ns", ...options.segments ?? []));
8146
+ return resultOk(join5(home.value, "ns", ...options.segments ?? []));
6594
8147
  }
6595
8148
  function requireXdgPath(result) {
6596
8149
  if (result.ok) return result.value;
@@ -6624,7 +8177,7 @@ function expandHomeRelativePath(path, env) {
6624
8177
  message: `HOME environment variable must be absolute to expand ~/ in storage override: ${home}`
6625
8178
  });
6626
8179
  }
6627
- return resultOk(join3(home, path.slice(2)));
8180
+ return resultOk(join5(home, path.slice(2)));
6628
8181
  }
6629
8182
 
6630
8183
  // ../../kernel/src/extensions/registry.ts
@@ -6659,12 +8212,12 @@ async function loadNsCommandCatalog(options) {
6659
8212
  }
6660
8213
  const projectCandidates = loadRootCandidates({
6661
8214
  level: "project",
6662
- rootDir: join4(options.cwd, ".ns", "extensions")
8215
+ rootDir: join6(options.cwd, ".ns", "extensions")
6663
8216
  });
6664
8217
  diagnostics.push(...projectCandidates.diagnostics);
6665
8218
  orderedSources.push({
6666
8219
  level: "project",
6667
- label: join4(options.cwd, ".ns", "extensions"),
8220
+ label: join6(options.cwd, ".ns", "extensions"),
6668
8221
  candidates: projectCandidates.candidates
6669
8222
  });
6670
8223
  const merged = /* @__PURE__ */ new Map();
@@ -6767,30 +8320,30 @@ function commandInfosForSelectedCommand(commandInfos, loaded) {
6767
8320
  }
6768
8321
  function classifyExtensionDiagnosticsForInvocation(options) {
6769
8322
  const errorDiagnostics = options.diagnostics.filter(
6770
- (diagnostic3) => diagnostic3.severity === "error"
8323
+ (diagnostic5) => diagnostic5.severity === "error"
6771
8324
  );
6772
8325
  if (options.requestedCommandName === void 0) {
6773
8326
  return { fatal: [], warnings: errorDiagnostics };
6774
8327
  }
6775
8328
  const fatal = [];
6776
8329
  const warnings = [];
6777
- for (const diagnostic3 of errorDiagnostics) {
6778
- if (diagnostic3.commandName !== options.requestedCommandName) {
6779
- warnings.push(diagnostic3);
8330
+ for (const diagnostic5 of errorDiagnostics) {
8331
+ if (diagnostic5.commandName !== options.requestedCommandName) {
8332
+ warnings.push(diagnostic5);
6780
8333
  continue;
6781
8334
  }
6782
- if (isFatalForSelectedCandidate(diagnostic3, options.selectedCandidate)) {
6783
- fatal.push(diagnostic3);
8335
+ if (isFatalForSelectedCandidate(diagnostic5, options.selectedCandidate)) {
8336
+ fatal.push(diagnostic5);
6784
8337
  continue;
6785
8338
  }
6786
- warnings.push(diagnostic3);
8339
+ warnings.push(diagnostic5);
6787
8340
  }
6788
8341
  return { fatal, warnings };
6789
8342
  }
6790
8343
  function formatExtensionErrorDiagnostics(diagnostics) {
6791
8344
  return formatExtensionDiagnosticMessages(
6792
8345
  diagnostics.filter(
6793
- (diagnostic3) => diagnostic3.severity === "error"
8346
+ (diagnostic5) => diagnostic5.severity === "error"
6794
8347
  )
6795
8348
  );
6796
8349
  }
@@ -6799,18 +8352,18 @@ function formatExtensionWarningDiagnostics(diagnostics) {
6799
8352
  }
6800
8353
  function formatExtensionDiagnosticMessages(diagnostics, options = {}) {
6801
8354
  const prefix = options.prefix ?? "";
6802
- return diagnostics.map((diagnostic3) => `${prefix}${diagnostic3.message}`).join("\n");
8355
+ return diagnostics.map((diagnostic5) => `${prefix}${diagnostic5.message}`).join("\n");
6803
8356
  }
6804
- function isFatalForSelectedCandidate(diagnostic3, selectedCandidate) {
8357
+ function isFatalForSelectedCandidate(diagnostic5, selectedCandidate) {
6805
8358
  if (selectedCandidate === void 0) return true;
6806
- if (diagnostic3.sourceLevel === void 0) return true;
6807
- return sourceLevelRank(diagnostic3.sourceLevel) >= sourceLevelRank(selectedCandidate.source.level);
8359
+ if (diagnostic5.sourceLevel === void 0) return true;
8360
+ return sourceLevelRank(diagnostic5.sourceLevel) >= sourceLevelRank(selectedCandidate.source.level);
6808
8361
  }
6809
8362
  function loadRootCandidates(options) {
6810
8363
  const discovered = discoverExtensionsInRoot(options.rootDir);
6811
8364
  return {
6812
8365
  diagnostics: discovered.diagnostics.map(
6813
- (diagnostic3) => fromDiscoveryDiagnostic(diagnostic3, options.level)
8366
+ (diagnostic5) => fromDiscoveryDiagnostic(diagnostic5, options.level)
6814
8367
  ),
6815
8368
  candidates: discovered.commands.map(
6816
8369
  (command) => discoveredCommandCandidateForLevel(command, options.level)
@@ -6839,7 +8392,7 @@ function loadSourceDevPreinstalledCandidates(cwd, catalogKeys) {
6839
8392
  const discovered = discoverNsPackageCommands(packagesRoot, packageDir);
6840
8393
  diagnostics.push(
6841
8394
  ...discovered.diagnostics.map(
6842
- (diagnostic3) => fromDiscoveryDiagnostic(diagnostic3, "preinstalled")
8395
+ (diagnostic5) => fromDiscoveryDiagnostic(diagnostic5, "preinstalled")
6843
8396
  )
6844
8397
  );
6845
8398
  candidates.push(
@@ -6849,10 +8402,10 @@ function loadSourceDevPreinstalledCandidates(cwd, catalogKeys) {
6849
8402
  return { diagnostics, candidates };
6850
8403
  }
6851
8404
  function sourceDevWorkspacePackagesRoot(cwd) {
6852
- const packagesRoot = resolve4(dirname3(fileURLToPath2(import.meta.url)), "..", "..", "..");
6853
- const checkoutRoot = resolve4(packagesRoot, "..", "..");
6854
- const kernelSourceDir = join4(packagesRoot, "kernel", "src");
6855
- if (!existsSync4(kernelSourceDir)) return void 0;
8405
+ const packagesRoot = resolve5(dirname4(fileURLToPath2(import.meta.url)), "..", "..", "..");
8406
+ const checkoutRoot = resolve5(packagesRoot, "..", "..");
8407
+ const kernelSourceDir = join6(packagesRoot, "kernel", "src");
8408
+ if (!existsSync6(kernelSourceDir)) return void 0;
6856
8409
  return isPathInside(checkoutRoot, cwd) ? packagesRoot : void 0;
6857
8410
  }
6858
8411
  function discoverWorkspacePackageDirs(packagesRoot) {
@@ -6862,8 +8415,8 @@ function discoverWorkspacePackageDirs(packagesRoot) {
6862
8415
  }
6863
8416
  function collectPackageDirs(options) {
6864
8417
  if (options.depth > 3) return;
6865
- const packageJsonPath = join4(options.current, "package.json");
6866
- if (options.current !== options.root && existsSync4(packageJsonPath)) {
8418
+ const packageJsonPath = join6(options.current, "package.json");
8419
+ if (options.current !== options.root && existsSync6(packageJsonPath)) {
6867
8420
  options.packageDirs.push(options.current);
6868
8421
  return;
6869
8422
  }
@@ -6877,7 +8430,7 @@ function collectPackageDirs(options) {
6877
8430
  if (!entry2.isDirectory() || entry2.name === "node_modules") continue;
6878
8431
  collectPackageDirs({
6879
8432
  root: options.root,
6880
- current: join4(options.current, entry2.name),
8433
+ current: join6(options.current, entry2.name),
6881
8434
  depth: options.depth + 1,
6882
8435
  packageDirs: options.packageDirs
6883
8436
  });
@@ -7063,11 +8616,11 @@ function sourceLevelRank(level) {
7063
8616
  function isBuiltInCandidate(candidate2) {
7064
8617
  return candidate2.source.level === "built-in";
7065
8618
  }
7066
- function fromDiscoveryDiagnostic(diagnostic3, sourceLevel) {
7067
- return { ...diagnostic3, sourceLevel };
8619
+ function fromDiscoveryDiagnostic(diagnostic5, sourceLevel) {
8620
+ return { ...diagnostic5, sourceLevel };
7068
8621
  }
7069
- function fromLoadDiagnostic(diagnostic3, sourceLevel, commandName) {
7070
- return { ...diagnostic3, sourceLevel, commandName };
8622
+ function fromLoadDiagnostic(diagnostic5, sourceLevel, commandName) {
8623
+ return { ...diagnostic5, sourceLevel, commandName };
7071
8624
  }
7072
8625
  function candidateDiagnosticPath(candidate2) {
7073
8626
  if (isBuiltInCandidate(candidate2)) return formatSource(candidate2.source);
@@ -7077,6 +8630,25 @@ function formatSource(source) {
7077
8630
  return source.path === void 0 ? source.label : `${source.label} (${source.path})`;
7078
8631
  }
7079
8632
 
8633
+ // ../../kernel/src/extensions/repo-local-catalog.ts
8634
+ function repoLocalNsExtensionToPreinstalledCatalog(descriptor) {
8635
+ return descriptor.commands.map((commandDescriptor) => ({
8636
+ group: descriptor.group,
8637
+ groupDescription: descriptor.description,
8638
+ ...repoLocalNsCommandDescriptorToPreinstalledCatalogEntry(commandDescriptor)
8639
+ }));
8640
+ }
8641
+ function repoLocalNsCommandDescriptorToPreinstalledCatalogEntry(commandDescriptor) {
8642
+ return {
8643
+ name: commandDescriptor.manifestName ?? commandDescriptor.command.name,
8644
+ description: commandDescriptor.command.summary,
8645
+ fullDescription: commandDescriptor.command.description,
8646
+ ...optionalEntry("path", commandDescriptor.manifestPath),
8647
+ displayPath: commandDescriptor.packageExport,
8648
+ load: () => defineExtension({ commands: [commandDescriptor.command] })
8649
+ };
8650
+ }
8651
+
7080
8652
  // ../../kernel/src/cli/index.ts
7081
8653
  var entry = defineCli({
7082
8654
  metaUrl: new URL("../cli.ts", import.meta.url).href,
@@ -7088,7 +8660,7 @@ var entry = defineCli({
7088
8660
  const resolvedStderr = deps.stderr ?? injectedContext?.stderr ?? stderr;
7089
8661
  const resolvedCwd = deps.cwd ?? injectedContext?.cwd ?? cwd;
7090
8662
  const resolvedEnv = deps.env ?? injectedContext?.env ?? env;
7091
- const homeDir = deps.homeDir ?? resolvedEnv.HOME;
8663
+ const homeDir = resolveHomeDir(deps.homeDir, resolvedEnv) ?? injectedContext?.homeDir;
7092
8664
  const commandCatalog = await (deps.extensionRegistry?.loadCommandCatalog ?? loadNsCommandCatalog)({
7093
8665
  cwd: resolvedCwd,
7094
8666
  env: resolvedEnv,
@@ -7101,12 +8673,14 @@ var entry = defineCli({
7101
8673
  commandCatalog,
7102
8674
  cwd: resolvedCwd,
7103
8675
  env: resolvedEnv,
8676
+ ...optionalEntry("homeDir", homeDir),
7104
8677
  stdout: resolvedStdout,
7105
8678
  stderr: resolvedStderr,
7106
8679
  ...optionalEntries({
7107
8680
  loadSelectedCommand: deps.extensionRegistry?.loadSelectedCommand,
7108
8681
  injectedContext,
7109
8682
  onOutput: deps.onOutput,
8683
+ onProgress: deps.onProgress,
7110
8684
  confirm: deps.confirm,
7111
8685
  caps: io.caps
7112
8686
  })
@@ -7149,11 +8723,13 @@ var entry = defineCli({
7149
8723
  args,
7150
8724
  cwd: resolvedCwd,
7151
8725
  env: resolvedEnv,
8726
+ ...optionalEntry("homeDir", homeDir),
7152
8727
  stdout: resolvedStdout,
7153
8728
  stderr: resolvedStderr,
7154
8729
  ...optionalEntries({
7155
8730
  injectedContext,
7156
8731
  onOutput: deps.onOutput,
8732
+ onProgress: deps.onProgress,
7157
8733
  confirm: deps.confirm,
7158
8734
  caps: io.caps
7159
8735
  })
@@ -7169,7 +8745,7 @@ var entry = defineCli({
7169
8745
  for (const commandInfo of buildState.commandInfos) {
7170
8746
  const parent = groupForCommand(root, groups, commandInfo);
7171
8747
  const selectedCommand = buildState.selectedCommandPath !== void 0 && commandPathMatches(buildState.selectedCommandPath, commandInfo) ? buildState.selectedCommand : void 0;
7172
- const schema = selectedCommand?.schema ?? z11.object({});
8748
+ const schema = selectedCommand?.schema ?? z13.object({});
7173
8749
  const commandOptions2 = {
7174
8750
  name: cliLeafCommandName(commandInfo),
7175
8751
  description: commandInfo.fullDescription,
@@ -7248,11 +8824,13 @@ async function handleCompletionResolverInvocation(options) {
7248
8824
  args: options.args,
7249
8825
  cwd: options.cwd,
7250
8826
  env: options.env,
8827
+ ...optionalEntry("homeDir", options.homeDir),
7251
8828
  stdout: options.stdout,
7252
8829
  stderr: options.stderr,
7253
8830
  ...optionalEntries({
7254
8831
  injectedContext: options.injectedContext,
7255
8832
  onOutput: options.onOutput,
8833
+ onProgress: options.onProgress,
7256
8834
  confirm: options.confirm,
7257
8835
  caps: options.caps
7258
8836
  })
@@ -7294,7 +8872,11 @@ async function resolveSelectedNsCommand(options) {
7294
8872
  };
7295
8873
  }
7296
8874
  async function buildNsCliContext(options) {
7297
- const baseContext = options.injectedContext ?? createRealNsCommandContext({ cwd: options.cwd, env: options.env });
8875
+ const baseContext = options.injectedContext ?? createRealNsCommandContext({
8876
+ cwd: options.cwd,
8877
+ env: options.env,
8878
+ ...optionalEntry("homeDir", options.homeDir)
8879
+ });
7298
8880
  const onOutput = options.onOutput ?? baseContext.onOutput;
7299
8881
  const confirm = options.confirm ?? baseContext.confirm;
7300
8882
  const stdin = baseContext.stdin ?? readStdin;
@@ -7308,9 +8890,10 @@ async function buildNsCliContext(options) {
7308
8890
  const context = {
7309
8891
  cwd: options.cwd,
7310
8892
  env: options.env,
8893
+ ...optionalEntry("homeDir", options.homeDir),
7311
8894
  textGenerator: baseContext.textGenerator,
7312
8895
  commandIo,
7313
- progress: noopNsProgress,
8896
+ progress: options.onProgress === void 0 ? noopNsProgress : { isLive: true, phase: options.onProgress },
7314
8897
  renderCapabilities: renderCapabilities2,
7315
8898
  outputFormat: clinkrFormatFromArgs(options.args),
7316
8899
  exec: baseContext.exec.bind(baseContext),
@@ -7373,7 +8956,7 @@ function buildNsCompletionGroup() {
7373
8956
  completion.command({
7374
8957
  name: shell,
7375
8958
  description: `Print ${shell} completion setup for ns.`,
7376
- schema: z11.object({}),
8959
+ schema: z13.object({}),
7377
8960
  resultSchema: nsCompletionScriptResultSchema,
7378
8961
  handler: async () => ok(buildNsCompletionScript(shell)),
7379
8962
  renderHuman: renderNsCompletionScriptResult
@@ -7388,7 +8971,7 @@ function buildNsCompletionGroup() {
7388
8971
  rawCommand({
7389
8972
  name: "resolve",
7390
8973
  description: "Resolve newline-delimited shell completion candidates.",
7391
- schema: z11.object({ words: z11.array(z11.string()).default([]) }),
8974
+ schema: z13.object({ words: z13.array(z13.string()).default([]) }),
7392
8975
  positionals: { words: { position: 0 } },
7393
8976
  run: async () => 0
7394
8977
  })
@@ -7486,9 +9069,52 @@ function writeNsResultOutput(result, deps) {
7486
9069
  }
7487
9070
  deps.stderr(output);
7488
9071
  }
9072
+ var VERSION = entry.version;
7489
9073
  await entry.runIfMain({ isImportMetaMain: import.meta.main });
7490
9074
  export {
9075
+ VERSION,
7491
9076
  buildCli,
7492
9077
  listNsCommands,
9078
+ repoLocalNsCommandDescriptorToPreinstalledCatalogEntry,
9079
+ repoLocalNsExtensionToPreinstalledCatalog,
7493
9080
  runCli
7494
9081
  };
9082
+ /*! Bundled license information:
9083
+
9084
+ smol-toml/dist/error.js:
9085
+ smol-toml/dist/util.js:
9086
+ smol-toml/dist/date.js:
9087
+ smol-toml/dist/primitive.js:
9088
+ smol-toml/dist/extract.js:
9089
+ smol-toml/dist/struct.js:
9090
+ smol-toml/dist/parse.js:
9091
+ smol-toml/dist/stringify.js:
9092
+ smol-toml/dist/index.js:
9093
+ (*!
9094
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
9095
+ * SPDX-License-Identifier: BSD-3-Clause
9096
+ *
9097
+ * Redistribution and use in source and binary forms, with or without
9098
+ * modification, are permitted provided that the following conditions are met:
9099
+ *
9100
+ * 1. Redistributions of source code must retain the above copyright notice, this
9101
+ * list of conditions and the following disclaimer.
9102
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
9103
+ * this list of conditions and the following disclaimer in the
9104
+ * documentation and/or other materials provided with the distribution.
9105
+ * 3. Neither the name of the copyright holder nor the names of its contributors
9106
+ * may be used to endorse or promote products derived from this software without
9107
+ * specific prior written permission.
9108
+ *
9109
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
9110
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9111
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9112
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
9113
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
9114
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
9115
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
9116
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
9117
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
9118
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9119
+ *)
9120
+ */