@nseng-ai/kernel 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.
@@ -0,0 +1,31 @@
1
+ import { optionalEntry } from "@nseng-ai/foundation/primitives";
2
+
3
+ import { defineExtension } from "../sdk/command.ts";
4
+ import type {
5
+ RepoLocalNsExtensionCommandDescriptor,
6
+ RepoLocalNsExtensionDescriptor,
7
+ } from "../sdk/repo-local-ns-extension.ts";
8
+ import type { PreinstalledNsCommandCatalogEntry } from "./registry.ts";
9
+
10
+ export function repoLocalNsExtensionToPreinstalledCatalog(
11
+ descriptor: RepoLocalNsExtensionDescriptor,
12
+ ): readonly PreinstalledNsCommandCatalogEntry[] {
13
+ return descriptor.commands.map((commandDescriptor) => ({
14
+ group: descriptor.group,
15
+ groupDescription: descriptor.description,
16
+ ...repoLocalNsCommandDescriptorToPreinstalledCatalogEntry(commandDescriptor),
17
+ }));
18
+ }
19
+
20
+ export function repoLocalNsCommandDescriptorToPreinstalledCatalogEntry(
21
+ commandDescriptor: RepoLocalNsExtensionCommandDescriptor,
22
+ ): PreinstalledNsCommandCatalogEntry {
23
+ return {
24
+ name: commandDescriptor.manifestName ?? commandDescriptor.command.name,
25
+ description: commandDescriptor.command.summary,
26
+ fullDescription: commandDescriptor.command.description,
27
+ ...optionalEntry("path", commandDescriptor.manifestPath),
28
+ displayPath: commandDescriptor.packageExport,
29
+ load: () => defineExtension({ commands: [commandDescriptor.command] }),
30
+ };
31
+ }
@@ -0,0 +1,65 @@
1
+ import type { ZodIssueLike } from "@nseng-ai/foundation/primitives";
2
+
3
+ /**
4
+ * Kernel-local classifier for routing Zod issues by structural path shape.
5
+ *
6
+ * This intentionally stays private to `@nseng-ai/kernel`: it is a small, policy-free
7
+ * path-matching utility shared by `extension-discovery.ts` and
8
+ * `command-registry.ts` to avoid raw `issue.path[N]` indexing at call sites.
9
+ * It is not exported from the package and should not be promoted to
10
+ * `@nseng-ai/foundation/primitives` unless a second package needs it.
11
+ */
12
+
13
+ export type ZodIssuePathPatternSegment = string | { readonly type: "number" };
14
+
15
+ export interface ZodIssuePathRule<T extends string> {
16
+ readonly pattern: readonly ZodIssuePathPatternSegment[];
17
+ readonly match: "exact" | "prefix";
18
+ readonly value: T;
19
+ }
20
+
21
+ /**
22
+ * Classify a single issue's path against a list of rules, returning the value
23
+ * of the first matching rule or `fallback` if none match.
24
+ */
25
+ export function classifyZodIssuePath<T extends string>(
26
+ issue: ZodIssueLike | undefined,
27
+ rules: readonly ZodIssuePathRule<T>[],
28
+ fallback: T,
29
+ ): T {
30
+ if (issue === undefined) return fallback;
31
+ for (const rule of rules) {
32
+ if (zodIssuePathMatchesRule(issue.path, rule)) return rule.value;
33
+ }
34
+ return fallback;
35
+ }
36
+
37
+ /**
38
+ * Classify a list of issues by scanning for the first issue whose path
39
+ * matches any rule, rather than assuming `issues[0]` is the actionable one.
40
+ */
41
+ export function classifyFirstMatchingZodIssuePath<T extends string>(
42
+ issues: readonly ZodIssueLike[],
43
+ rules: readonly ZodIssuePathRule<T>[],
44
+ fallback: T,
45
+ ): T {
46
+ for (const issue of issues) {
47
+ const kind = classifyZodIssuePath(issue, rules, fallback);
48
+ if (kind !== fallback) return kind;
49
+ }
50
+ return fallback;
51
+ }
52
+
53
+ function zodIssuePathMatchesRule(
54
+ path: readonly unknown[],
55
+ rule: ZodIssuePathRule<string>,
56
+ ): boolean {
57
+ if (rule.match === "exact" && path.length !== rule.pattern.length) return false;
58
+ if (rule.match === "prefix" && path.length < rule.pattern.length) return false;
59
+ return rule.pattern.every((segment, index) => zodIssuePathSegmentMatches(segment, path[index]));
60
+ }
61
+
62
+ function zodIssuePathSegmentMatches(segment: ZodIssuePathPatternSegment, value: unknown): boolean {
63
+ if (typeof segment === "string") return value === segment;
64
+ return typeof value === "number";
65
+ }