@thinkingsage/kanon 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +410 -0
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/bridge/mcp-server.cjs +14171 -0
- package/package.json +98 -0
- package/src/adapters/capabilities.ts +178 -0
- package/src/adapters/claude-code.ts +110 -0
- package/src/adapters/cline.ts +98 -0
- package/src/adapters/codex.ts +173 -0
- package/src/adapters/copilot.ts +106 -0
- package/src/adapters/cursor.ts +97 -0
- package/src/adapters/degradation.ts +95 -0
- package/src/adapters/index.ts +324 -0
- package/src/adapters/kiro-frontmatter.ts +139 -0
- package/src/adapters/kiro-inclusion.ts +86 -0
- package/src/adapters/kiro.ts +412 -0
- package/src/adapters/qdeveloper.ts +115 -0
- package/src/adapters/types.ts +81 -0
- package/src/adapters/windsurf.ts +96 -0
- package/src/admin.ts +283 -0
- package/src/asset-conventions.ts +118 -0
- package/src/attribution-backfill.ts +319 -0
- package/src/attribution-report.ts +95 -0
- package/src/attribution.ts +239 -0
- package/src/backends/github.ts +194 -0
- package/src/backends/http.ts +122 -0
- package/src/backends/index.ts +39 -0
- package/src/backends/local.ts +47 -0
- package/src/backends/s3.ts +157 -0
- package/src/backends/types.ts +59 -0
- package/src/base-cache.ts +270 -0
- package/src/browse-ui.ts +3754 -0
- package/src/browse.ts +1038 -0
- package/src/build.ts +1108 -0
- package/src/catalog.ts +204 -0
- package/src/cli-deprecated.ts +29 -0
- package/src/cli.ts +773 -0
- package/src/collection-admin.ts +287 -0
- package/src/collection-builder.ts +464 -0
- package/src/collections.ts +116 -0
- package/src/compatibility.ts +105 -0
- package/src/config.ts +743 -0
- package/src/eval/rubrics/kiro-progressive-steering.ts +841 -0
- package/src/eval.ts +1169 -0
- package/src/file-writer.ts +61 -0
- package/src/format-registry.ts +141 -0
- package/src/guild/auto-updater.ts +163 -0
- package/src/guild/backend-resolver.ts +49 -0
- package/src/guild/cli.ts +592 -0
- package/src/guild/collection-expander.ts +47 -0
- package/src/guild/global-cache.ts +247 -0
- package/src/guild/hook-generator.ts +100 -0
- package/src/guild/manifest.ts +154 -0
- package/src/guild/path-utils.ts +12 -0
- package/src/guild/sync.ts +622 -0
- package/src/guild/version-resolver.ts +42 -0
- package/src/help/metadata.ts +445 -0
- package/src/help/renderer.ts +265 -0
- package/src/help/typo-suggester.ts +25 -0
- package/src/hooks/expression.ts +493 -0
- package/src/hooks/pipeline.ts +141 -0
- package/src/import.ts +773 -0
- package/src/importers/claude-code.ts +134 -0
- package/src/importers/cline.ts +103 -0
- package/src/importers/codex.ts +140 -0
- package/src/importers/copilot.ts +103 -0
- package/src/importers/cursor.ts +105 -0
- package/src/importers/index.ts +390 -0
- package/src/importers/kiro.ts +110 -0
- package/src/importers/qdeveloper.ts +103 -0
- package/src/importers/types.ts +54 -0
- package/src/importers/windsurf.ts +104 -0
- package/src/install.ts +1005 -0
- package/src/manifest-admin.ts +306 -0
- package/src/mcp-bridge.ts +240 -0
- package/src/mutation/delta.ts +50 -0
- package/src/mutation/history.ts +66 -0
- package/src/mutation/operators.ts +524 -0
- package/src/mutation/runner.ts +332 -0
- package/src/new.ts +106 -0
- package/src/outcomes/collision.ts +127 -0
- package/src/outcomes/normalize.ts +208 -0
- package/src/outcomes/registry.ts +173 -0
- package/src/parser.ts +446 -0
- package/src/provenance-backfill-cli.ts +319 -0
- package/src/provenance-backfill.ts +520 -0
- package/src/publish.ts +354 -0
- package/src/reconcile-orchestrator.ts +502 -0
- package/src/reconcile-report-renderer.ts +176 -0
- package/src/resolve-body.ts +15 -0
- package/src/rosetta/builtins/compatibility-profiles.ts +297 -0
- package/src/rosetta/builtins/contracts.ts +1033 -0
- package/src/rosetta/builtins/pretty-printers/claude-code-native.ts +122 -0
- package/src/rosetta/builtins/pretty-printers/cline-native.ts +50 -0
- package/src/rosetta/builtins/pretty-printers/codex-native.ts +127 -0
- package/src/rosetta/builtins/pretty-printers/copilot-native.ts +50 -0
- package/src/rosetta/builtins/pretty-printers/cursor-native.ts +50 -0
- package/src/rosetta/builtins/pretty-printers/index.ts +81 -0
- package/src/rosetta/builtins/pretty-printers/kiro-native.ts +166 -0
- package/src/rosetta/builtins/pretty-printers/kiro-power.ts +108 -0
- package/src/rosetta/builtins/pretty-printers/kiro-skill.ts +88 -0
- package/src/rosetta/builtins/pretty-printers/qdeveloper-native.ts +51 -0
- package/src/rosetta/builtins/pretty-printers/superpowers.ts +97 -0
- package/src/rosetta/builtins/pretty-printers/windsurf-native.ts +50 -0
- package/src/rosetta/builtins/sources/claude-code-native.ts +348 -0
- package/src/rosetta/builtins/sources/cline-native.ts +176 -0
- package/src/rosetta/builtins/sources/codex-native.ts +343 -0
- package/src/rosetta/builtins/sources/copilot-native.ts +178 -0
- package/src/rosetta/builtins/sources/cursor-native.ts +176 -0
- package/src/rosetta/builtins/sources/index.ts +95 -0
- package/src/rosetta/builtins/sources/kiro-native.ts +462 -0
- package/src/rosetta/builtins/sources/kiro-power.ts +285 -0
- package/src/rosetta/builtins/sources/kiro-skill.ts +230 -0
- package/src/rosetta/builtins/sources/qdeveloper-native.ts +181 -0
- package/src/rosetta/builtins/sources/superpowers.ts +240 -0
- package/src/rosetta/builtins/sources/windsurf-native.ts +176 -0
- package/src/rosetta/builtins/targets/claude-code.ts +181 -0
- package/src/rosetta/builtins/targets/cline.ts +87 -0
- package/src/rosetta/builtins/targets/codex.ts +226 -0
- package/src/rosetta/builtins/targets/copilot.ts +103 -0
- package/src/rosetta/builtins/targets/cursor.ts +87 -0
- package/src/rosetta/builtins/targets/index.ts +60 -0
- package/src/rosetta/builtins/targets/kiro.ts +278 -0
- package/src/rosetta/builtins/targets/qdeveloper.ts +103 -0
- package/src/rosetta/builtins/targets/windsurf.ts +87 -0
- package/src/rosetta/canonical.ts +729 -0
- package/src/rosetta/compatibility.ts +432 -0
- package/src/rosetta/contracts.ts +329 -0
- package/src/rosetta/detector.ts +724 -0
- package/src/rosetta/diagnostics.ts +630 -0
- package/src/rosetta/engine-bootstrap.ts +103 -0
- package/src/rosetta/engine.ts +744 -0
- package/src/rosetta/index.ts +381 -0
- package/src/rosetta/inspection.ts +530 -0
- package/src/rosetta/plan.ts +448 -0
- package/src/rosetta/provenance-digest.ts +369 -0
- package/src/rosetta/reconcile.ts +812 -0
- package/src/rosetta/redaction.ts +467 -0
- package/src/rosetta/registry.ts +712 -0
- package/src/rosetta/renderers.ts +571 -0
- package/src/rosetta/request-guard.ts +335 -0
- package/src/rosetta/resolution.ts +419 -0
- package/src/rosetta/source-accounting.ts +233 -0
- package/src/rosetta/templates.ts +129 -0
- package/src/rosetta-cli.ts +717 -0
- package/src/rosetta-docs-generator.ts +793 -0
- package/src/rosetta-profiles-cli.ts +367 -0
- package/src/schemas.ts +1712 -0
- package/src/spec-coordination.ts +1141 -0
- package/src/temper.ts +747 -0
- package/src/template-bundle-loader.ts +312 -0
- package/src/template-engine.ts +53 -0
- package/src/translation-application-policy.ts +496 -0
- package/src/translation-orchestrator.ts +1013 -0
- package/src/translation-plan-applier.ts +473 -0
- package/src/tutorial.ts +305 -0
- package/src/validate.ts +1093 -0
- package/src/versioning.ts +553 -0
- package/src/wizard.ts +660 -0
- package/src/workspace.ts +237 -0
- package/templates/eval-contexts/claude-code.md.njk +6 -0
- package/templates/eval-contexts/cline.md.njk +6 -0
- package/templates/eval-contexts/copilot.md.njk +6 -0
- package/templates/eval-contexts/cursor.md.njk +6 -0
- package/templates/eval-contexts/kiro.md.njk +10 -0
- package/templates/eval-contexts/qdeveloper.md.njk +6 -0
- package/templates/eval-contexts/windsurf.md.njk +6 -0
- package/templates/harness-adapters/_base/attribution-footer.md.njk +17 -0
- package/templates/harness-adapters/_base/base.md.njk +16 -0
- package/templates/harness-adapters/claude-code/claude.md.njk +1 -0
- package/templates/harness-adapters/claude-code/mcp.json.njk +1 -0
- package/templates/harness-adapters/claude-code/settings.json.njk +1 -0
- package/templates/harness-adapters/claude-code/skill-library-index.md.njk +13 -0
- package/templates/harness-adapters/claude-code/skill.md.njk +19 -0
- package/templates/harness-adapters/cline/hook.sh.njk +4 -0
- package/templates/harness-adapters/cline/mcp.json.njk +1 -0
- package/templates/harness-adapters/cline/rule.md.njk +1 -0
- package/templates/harness-adapters/codex/agents-md.md.njk +6 -0
- package/templates/harness-adapters/codex/agents-pointer.md.njk +16 -0
- package/templates/harness-adapters/codex/skill.md.njk +27 -0
- package/templates/harness-adapters/copilot/agents.md.njk +1 -0
- package/templates/harness-adapters/copilot/instructions.md.njk +1 -0
- package/templates/harness-adapters/copilot/scoped.md.njk +6 -0
- package/templates/harness-adapters/cursor/mcp.json.njk +1 -0
- package/templates/harness-adapters/cursor/rule.md.njk +6 -0
- package/templates/harness-adapters/kiro/hook.json.njk +1 -0
- package/templates/harness-adapters/kiro/mcp.json.njk +1 -0
- package/templates/harness-adapters/kiro/power-steering.md.njk +3 -0
- package/templates/harness-adapters/kiro/power.md.njk +12 -0
- package/templates/harness-adapters/kiro/steering.md.njk +16 -0
- package/templates/harness-adapters/qdeveloper/agent.md.njk +1 -0
- package/templates/harness-adapters/qdeveloper/mcp.json.njk +1 -0
- package/templates/harness-adapters/qdeveloper/rule.md.njk +1 -0
- package/templates/harness-adapters/windsurf/mcp.json.njk +1 -0
- package/templates/harness-adapters/windsurf/rule.md.njk +1 -0
- package/templates/harness-adapters/windsurf/workflow.md.njk +1 -0
- package/templates/knowledge/hooks.yaml.njk +4 -0
- package/templates/knowledge/knowledge.md.njk +53 -0
- package/templates/knowledge/mcp-servers.yaml.njk +2 -0
package/src/catalog.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { exists, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { resolveFormat } from "./format-registry";
|
|
5
|
+
import { isParseError, loadKnowledgeArtifact } from "./parser";
|
|
6
|
+
import type { CatalogEntry, HarnessName } from "./schemas";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Load a single artifact directory into a CatalogEntry.
|
|
10
|
+
* `catalogPath` is the path string written to the catalog (relative to CWD).
|
|
11
|
+
*/
|
|
12
|
+
async function loadArtifactEntry(
|
|
13
|
+
artifactPath: string,
|
|
14
|
+
catalogPath: string,
|
|
15
|
+
): Promise<CatalogEntry | null> {
|
|
16
|
+
const result = await loadKnowledgeArtifact(artifactPath);
|
|
17
|
+
if (isParseError(result)) return null;
|
|
18
|
+
|
|
19
|
+
const artifact = result.data;
|
|
20
|
+
const fm = artifact.frontmatter;
|
|
21
|
+
|
|
22
|
+
const hasEvals = await exists(join(artifactPath, "evals"));
|
|
23
|
+
const hasChangelog = await exists(join(artifactPath, "CHANGELOG.md"));
|
|
24
|
+
const hasMigrations = await exists(join(artifactPath, "migrations"));
|
|
25
|
+
|
|
26
|
+
const harnessConfig = (fm as Record<string, unknown>)["harness-config"] as
|
|
27
|
+
| Record<string, Record<string, unknown>>
|
|
28
|
+
| undefined;
|
|
29
|
+
const formatByHarness: Record<string, string> = {};
|
|
30
|
+
for (const harness of fm.harnesses) {
|
|
31
|
+
const config = harnessConfig?.[harness] as
|
|
32
|
+
| Record<string, unknown>
|
|
33
|
+
| undefined;
|
|
34
|
+
const { format } = resolveFormat(harness as HarnessName, config);
|
|
35
|
+
formatByHarness[harness] = format;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Derive feature flags from artifact content
|
|
39
|
+
const features = {
|
|
40
|
+
hooks: artifact.hooks.length > 0,
|
|
41
|
+
mcp: artifact.mcpServers.length > 0,
|
|
42
|
+
workflows: artifact.workflows.length > 0,
|
|
43
|
+
conditionalInclusion:
|
|
44
|
+
fm.inclusion === "fileMatch" || fm.inclusion === "manual",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
name: fm.name,
|
|
49
|
+
displayName: fm.displayName || fm.name,
|
|
50
|
+
description: fm.description,
|
|
51
|
+
keywords: fm.keywords,
|
|
52
|
+
author: fm.author,
|
|
53
|
+
version: fm.version,
|
|
54
|
+
harnesses: fm.harnesses,
|
|
55
|
+
type: fm.type,
|
|
56
|
+
path: catalogPath,
|
|
57
|
+
evals: hasEvals,
|
|
58
|
+
changelog: hasChangelog,
|
|
59
|
+
migrations: hasMigrations,
|
|
60
|
+
categories: fm.categories,
|
|
61
|
+
ecosystem: fm.ecosystem,
|
|
62
|
+
depends: fm.depends,
|
|
63
|
+
enhances: fm.enhances,
|
|
64
|
+
formatByHarness,
|
|
65
|
+
features,
|
|
66
|
+
id: fm.id,
|
|
67
|
+
license: fm.license,
|
|
68
|
+
maturity: fm.maturity,
|
|
69
|
+
trust: fm.trust,
|
|
70
|
+
"risk-level": fm["risk-level"],
|
|
71
|
+
audience: fm.audience,
|
|
72
|
+
"model-assumptions": fm["model-assumptions"],
|
|
73
|
+
successor: fm.successor,
|
|
74
|
+
replaces: fm.replaces,
|
|
75
|
+
collections: fm.collections,
|
|
76
|
+
// Human/legal attribution (ADR-0064) — projected verbatim when present.
|
|
77
|
+
...(fm.attribution ? { attribution: fm.attribution } : {}),
|
|
78
|
+
// Catalog visibility & ordering (Req 4). Default when omitted in frontmatter.
|
|
79
|
+
visibility: fm.visibility ?? "public",
|
|
80
|
+
priority: fm.priority ?? 50,
|
|
81
|
+
// Outcomes registry — projected subset for external discovery (Req 2H.1, 2H.2)
|
|
82
|
+
outcomes: fm.outcomes.map((o) => ({
|
|
83
|
+
id: o.id,
|
|
84
|
+
kind: o.kind,
|
|
85
|
+
inputShape: o.inputShape,
|
|
86
|
+
outputShape: o.outputShape,
|
|
87
|
+
keywords: o.keywords,
|
|
88
|
+
})),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Scan one source directory for artifacts, handling two layouts:
|
|
94
|
+
*
|
|
95
|
+
* Flat: <sourceDir>/<artifact>/knowledge.md
|
|
96
|
+
* Namespaced: <sourceDir>/<prefix>/<artifact>/knowledge.md (e.g. packages/@org/name)
|
|
97
|
+
*
|
|
98
|
+
* Detection: if a subdir contains knowledge.md directly, treat it as a flat
|
|
99
|
+
* artifact; otherwise recurse one level to find namespaced artifacts.
|
|
100
|
+
*/
|
|
101
|
+
async function scanSourceDir(sourceDir: string): Promise<CatalogEntry[]> {
|
|
102
|
+
const entries: CatalogEntry[] = [];
|
|
103
|
+
|
|
104
|
+
if (!(await exists(sourceDir))) return entries;
|
|
105
|
+
|
|
106
|
+
const dirEntries = await readdir(sourceDir, { withFileTypes: true });
|
|
107
|
+
const subdirs = dirEntries
|
|
108
|
+
.filter((e) => e.isDirectory())
|
|
109
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
110
|
+
|
|
111
|
+
for (const subdir of subdirs) {
|
|
112
|
+
const subdirPath = join(sourceDir, subdir.name);
|
|
113
|
+
|
|
114
|
+
// Use basename of sourceDir so paths are repo-relative even when
|
|
115
|
+
// an absolute sourceDir is passed (e.g. in tests using temp directories)
|
|
116
|
+
const sourceDirBase = basename(sourceDir);
|
|
117
|
+
|
|
118
|
+
if (await exists(join(subdirPath, "knowledge.md"))) {
|
|
119
|
+
// Flat layout: this subdir is the artifact
|
|
120
|
+
const entry = await loadArtifactEntry(
|
|
121
|
+
subdirPath,
|
|
122
|
+
`${sourceDirBase}/${subdir.name}`,
|
|
123
|
+
);
|
|
124
|
+
if (entry) entries.push(entry);
|
|
125
|
+
} else {
|
|
126
|
+
// Namespaced layout: look one level deeper (e.g. packages/@org/<artifact>)
|
|
127
|
+
const inner = await readdir(subdirPath, { withFileTypes: true });
|
|
128
|
+
const innerDirs = inner
|
|
129
|
+
.filter((e) => e.isDirectory())
|
|
130
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
131
|
+
|
|
132
|
+
for (const innerDir of innerDirs) {
|
|
133
|
+
const artifactPath = join(subdirPath, innerDir.name);
|
|
134
|
+
if (await exists(join(artifactPath, "knowledge.md"))) {
|
|
135
|
+
const entry = await loadArtifactEntry(
|
|
136
|
+
artifactPath,
|
|
137
|
+
`${sourceDirBase}/${subdir.name}/${innerDir.name}`,
|
|
138
|
+
);
|
|
139
|
+
if (entry) entries.push(entry);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return entries;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Sort catalog entries by priority descending, then name ascending (Req 4.7).
|
|
150
|
+
* Pure function — returns a new sorted array, does not mutate the input.
|
|
151
|
+
*/
|
|
152
|
+
export function sortCatalogEntries(entries: CatalogEntry[]): CatalogEntry[] {
|
|
153
|
+
return [...entries].sort((a, b) => {
|
|
154
|
+
if (b.priority !== a.priority) return b.priority - a.priority;
|
|
155
|
+
return a.name.localeCompare(b.name);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Generate the catalog from one or more source directories.
|
|
161
|
+
*
|
|
162
|
+
* Accepts either a single directory string (legacy) or an array.
|
|
163
|
+
* Directories that do not exist are silently skipped.
|
|
164
|
+
* Artifacts with duplicate names across directories are deduplicated —
|
|
165
|
+
* the first occurrence (in the order dirs are provided) wins.
|
|
166
|
+
* Entries with visibility "private" are excluded entirely (Req 4.5).
|
|
167
|
+
* "unlisted" entries are retained with their visibility field set (Req 4.6).
|
|
168
|
+
*/
|
|
169
|
+
export async function generateCatalog(
|
|
170
|
+
knowledgeDirs: string | string[],
|
|
171
|
+
): Promise<CatalogEntry[]> {
|
|
172
|
+
const dirs = Array.isArray(knowledgeDirs) ? knowledgeDirs : [knowledgeDirs];
|
|
173
|
+
const allEntries: CatalogEntry[] = [];
|
|
174
|
+
const seenNames = new Set<string>();
|
|
175
|
+
|
|
176
|
+
for (const dir of dirs) {
|
|
177
|
+
const dirEntries = await scanSourceDir(dir);
|
|
178
|
+
for (const entry of dirEntries) {
|
|
179
|
+
// Exclude private artifacts entirely (Req 4.5)
|
|
180
|
+
if (entry.visibility === "private") continue;
|
|
181
|
+
if (!seenNames.has(entry.name)) {
|
|
182
|
+
seenNames.add(entry.name);
|
|
183
|
+
allEntries.push(entry);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return sortCatalogEntries(allEntries);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function serializeCatalog(entries: CatalogEntry[]): string {
|
|
192
|
+
return JSON.stringify(entries, null, 2);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export const SOURCE_DIRS = ["knowledge", "packages"] as const;
|
|
196
|
+
|
|
197
|
+
export async function catalogCommand(): Promise<void> {
|
|
198
|
+
const entries = await generateCatalog([...SOURCE_DIRS]);
|
|
199
|
+
const json = serializeCatalog(entries);
|
|
200
|
+
await writeFile("catalog.json", json, "utf-8");
|
|
201
|
+
console.error(
|
|
202
|
+
chalk.green(`✓ Generated catalog.json with ${entries.length} entries`),
|
|
203
|
+
);
|
|
204
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deprecated `forge` bin entry.
|
|
5
|
+
*
|
|
6
|
+
* The CLI binary is being renamed from `forge` to `kanon`. This shim keeps
|
|
7
|
+
* the old `forge` command working for one release cycle: it prints a
|
|
8
|
+
* deprecation warning to stderr, then runs the real CLI (`cli.ts`)
|
|
9
|
+
* unchanged.
|
|
10
|
+
*
|
|
11
|
+
* `cli.ts` guards its command-parsing logic with
|
|
12
|
+
* `import.meta.main !== false`, so a plain `import("./cli.ts")` would be a
|
|
13
|
+
* no-op here (this module is the entry point, not `cli.ts`). Instead we
|
|
14
|
+
* re-exec `cli.ts` as a subprocess with the same argv/stdio, so it runs as
|
|
15
|
+
* if it had been invoked directly.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
process.stderr.write("Warning: `forge` is deprecated, use `kanon` instead.\n");
|
|
19
|
+
|
|
20
|
+
const result = Bun.spawnSync({
|
|
21
|
+
cmd: [
|
|
22
|
+
process.execPath,
|
|
23
|
+
`${import.meta.dir}/cli.ts`,
|
|
24
|
+
...process.argv.slice(2),
|
|
25
|
+
],
|
|
26
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
process.exit(result.exitCode ?? 1);
|