@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/README.md +4 -12
- package/bin/ns.js +8178 -4199
- package/kernel/cli.js +1885 -259
- package/kernel/command-io.js +12 -1
- package/kernel/context.js +17 -1
- package/kernel/sdk.js +12 -1
- package/package.json +1 -1
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
|
|
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((
|
|
4929
|
-
this.setTimeout(
|
|
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((
|
|
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
|
-
|
|
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
|
|
5627
|
-
import { dirname as
|
|
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
|
|
5656
|
+
import { z as z12 } from "zod";
|
|
5633
5657
|
|
|
5634
|
-
// ../../kernel/src/extensions/
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
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
|
|
5687
|
+
return codeblock;
|
|
5641
5688
|
}
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
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
|
-
|
|
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
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
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
|
|
5655
|
-
|
|
5656
|
-
|
|
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
|
-
//
|
|
5660
|
-
var
|
|
5661
|
-
var
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
}
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
}
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
}
|
|
5690
|
-
|
|
5691
|
-
|
|
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
|
|
5694
|
-
|
|
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
|
-
|
|
5697
|
-
|
|
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
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
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
|
-
|
|
5709
|
-
|
|
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
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
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
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
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
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5743
|
-
|
|
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
|
-
|
|
5747
|
-
|
|
6404
|
+
let dirents;
|
|
6405
|
+
try {
|
|
6406
|
+
dirents = readdirSync(rootDir, { withFileTypes: true });
|
|
6407
|
+
} catch (error) {
|
|
5748
6408
|
return {
|
|
5749
|
-
|
|
5750
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5756
|
-
const
|
|
5757
|
-
|
|
5758
|
-
return
|
|
5759
|
-
|
|
5760
|
-
|
|
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
|
|
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
|
|
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
|
|
5866
|
-
import { basename as basename3, extname, join as
|
|
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
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
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
|
|
5931
|
-
|
|
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 (
|
|
5947
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7528
|
+
diagnostic3(
|
|
5969
7529
|
"extension_directory_missing_entry",
|
|
5970
|
-
`Extension directory must contain package.json, index.ts, or index.js: ${
|
|
5971
|
-
{ path:
|
|
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 =
|
|
5984
|
-
if (!
|
|
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(
|
|
7556
|
+
parsed = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
|
|
5997
7557
|
} catch (error) {
|
|
5998
7558
|
return {
|
|
5999
7559
|
outcome: "parse-failed",
|
|
6000
|
-
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(
|
|
6031
|
-
return { commands: [], diagnostics: [
|
|
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 =
|
|
6052
|
-
const packageGroupDescription =
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
7793
|
+
entryStat = statSync2(resolvedEntry);
|
|
6241
7794
|
} catch {
|
|
6242
7795
|
return {
|
|
6243
7796
|
ok: false,
|
|
6244
7797
|
diagnostics: [
|
|
6245
|
-
|
|
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
|
-
|
|
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 =
|
|
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 :
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
7901
|
+
const group = readNonEmptyString2(options.group);
|
|
6349
7902
|
if (group !== void 0 && NS_COMMAND_NAME_PATTERN.test(group)) return void 0;
|
|
6350
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
6433
|
-
return {
|
|
6434
|
-
severity: "error",
|
|
7985
|
+
function diagnostic3(code, message, options = {}) {
|
|
7986
|
+
return makeKernelDiagnostic({
|
|
6435
7987
|
code,
|
|
6436
7988
|
message,
|
|
6437
|
-
...
|
|
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:
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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:
|
|
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:
|
|
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
|
-
(
|
|
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
|
|
6778
|
-
if (
|
|
6779
|
-
warnings.push(
|
|
8330
|
+
for (const diagnostic5 of errorDiagnostics) {
|
|
8331
|
+
if (diagnostic5.commandName !== options.requestedCommandName) {
|
|
8332
|
+
warnings.push(diagnostic5);
|
|
6780
8333
|
continue;
|
|
6781
8334
|
}
|
|
6782
|
-
if (isFatalForSelectedCandidate(
|
|
6783
|
-
fatal.push(
|
|
8335
|
+
if (isFatalForSelectedCandidate(diagnostic5, options.selectedCandidate)) {
|
|
8336
|
+
fatal.push(diagnostic5);
|
|
6784
8337
|
continue;
|
|
6785
8338
|
}
|
|
6786
|
-
warnings.push(
|
|
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
|
-
(
|
|
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((
|
|
8355
|
+
return diagnostics.map((diagnostic5) => `${prefix}${diagnostic5.message}`).join("\n");
|
|
6803
8356
|
}
|
|
6804
|
-
function isFatalForSelectedCandidate(
|
|
8357
|
+
function isFatalForSelectedCandidate(diagnostic5, selectedCandidate) {
|
|
6805
8358
|
if (selectedCandidate === void 0) return true;
|
|
6806
|
-
if (
|
|
6807
|
-
return sourceLevelRank(
|
|
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
|
-
(
|
|
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
|
-
(
|
|
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 =
|
|
6853
|
-
const checkoutRoot =
|
|
6854
|
-
const kernelSourceDir =
|
|
6855
|
-
if (!
|
|
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 =
|
|
6866
|
-
if (options.current !== options.root &&
|
|
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:
|
|
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(
|
|
7067
|
-
return { ...
|
|
8619
|
+
function fromDiscoveryDiagnostic(diagnostic5, sourceLevel) {
|
|
8620
|
+
return { ...diagnostic5, sourceLevel };
|
|
7068
8621
|
}
|
|
7069
|
-
function fromLoadDiagnostic(
|
|
7070
|
-
return { ...
|
|
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 ??
|
|
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 ??
|
|
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({
|
|
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:
|
|
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:
|
|
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
|
+
*/
|