openspecui 1.5.1 → 1.6.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/dist/cli.mjs +251 -20
- package/dist/index.mjs +1 -1
- package/dist/{src-16GA3our.mjs → src-CVJCbdiP.mjs} +166 -24
- package/package.json +3 -3
- package/web/assets/{BufferResource-Bn1UWy0D.js → BufferResource-BFEntdoN.js} +1 -1
- package/web/assets/{CanvasRenderer-D8NiU8la.js → CanvasRenderer-ZQxN8ITJ.js} +1 -1
- package/web/assets/{Filter-CRwq487x.js → Filter-trCu1CQG.js} +1 -1
- package/web/assets/{RenderTargetSystem-CtoB_qTm.js → RenderTargetSystem-DHoDBu3v.js} +1 -1
- package/web/assets/{WebGLRenderer-BgKO8R0a.js → WebGLRenderer-DYS9LSzA.js} +1 -1
- package/web/assets/{WebGPURenderer-CQeL2efC.js → WebGPURenderer-CDj9ZzDs.js} +1 -1
- package/web/assets/{browserAll-DP6sOYev.js → browserAll-B8FBs1Rt.js} +1 -1
- package/web/assets/{ghostty-web-evxujSxm.js → ghostty-web-C6hNf21K.js} +1 -1
- package/web/assets/{index-B147AOgf.js → index-BByfw4ws.js} +1 -1
- package/web/assets/{index-D2Tp4F9B.js → index-BDu-q_RJ.js} +1 -1
- package/web/assets/{index-B0IbsqHi.js → index-BRrJSB9v.js} +1 -1
- package/web/assets/{index-CBCPR3Qb.js → index-CFiXnV5n.js} +1 -1
- package/web/assets/{index-D6ardy54.js → index-CLKNqdA1.js} +1 -1
- package/web/assets/{index-BPZ3nG0r.js → index-Cja7GFdu.js} +1 -1
- package/web/assets/{index-DcXyAs0z.js → index-Cq8vn29r.js} +1 -1
- package/web/assets/{index-f0QdJSzm.js → index-CqDTsKqD.js} +1 -1
- package/web/assets/{index-DTeOcXKn.js → index-CxCFae0J.js} +1 -1
- package/web/assets/{index-dSf1u0YV.js → index-CxF-jUR9.js} +1 -1
- package/web/assets/{index-BMashGQn.js → index-Dj2t_cJN.js} +1 -1
- package/web/assets/{index-BnT52DZ8.js → index-Drwn-PWd.js} +1 -1
- package/web/assets/index-DzNp3fwv.css +1 -0
- package/web/assets/{index-BejnsZfY.js → index-FMaDFama.js} +1 -1
- package/web/assets/index-YEDqrGu6.js +1540 -0
- package/web/assets/{index-DJqmTRAR.js → index-hID85NKg.js} +1 -1
- package/web/assets/{index-4MAU81Qk.js → index-vJWwTEOs.js} +1 -1
- package/web/assets/{webworkerAll-DA2HufNb.js → webworkerAll-Pgv9S8Bp.js} +1 -1
- package/web/index.html +2 -2
- package/web/assets/index-T8xoxmUb.js +0 -1516
- package/web/assets/index-Ys2MTD3W.css +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as SchemaInfoSchema, c as
|
|
2
|
+
import { a as SchemaInfoSchema, c as toOpsxDisplayPath, d as DEFAULT_CONFIG, f as OpenSpecAdapter, i as SchemaDetailSchema, l as CliExecutor, m as __toESM, o as SchemaResolutionSchema, p as __commonJS, r as require_dist, s as TemplatesSchema, t as startServer, u as ConfigManager } from "./src-CVJCbdiP.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { basename, dirname, extname, join, normalize, relative, resolve } from "path";
|
|
5
5
|
import { readFile } from "node:fs/promises";
|
|
@@ -8,7 +8,8 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync
|
|
|
8
8
|
import { readFileSync as readFileSync$1, readdirSync as readdirSync$1, statSync as statSync$1, writeFile as writeFile$1 } from "fs";
|
|
9
9
|
import { format, inspect } from "util";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
|
-
import { spawn } from "node:child_process";
|
|
11
|
+
import { execFile, spawn } from "node:child_process";
|
|
12
|
+
import { promisify as promisify$1 } from "node:util";
|
|
12
13
|
import { fileURLToPath as fileURLToPath$1 } from "node:url";
|
|
13
14
|
import { notStrictEqual, strictEqual } from "assert";
|
|
14
15
|
|
|
@@ -4506,11 +4507,12 @@ var yargs_default = Yargs;
|
|
|
4506
4507
|
//#endregion
|
|
4507
4508
|
//#region package.json
|
|
4508
4509
|
var import_dist = require_dist();
|
|
4509
|
-
var version = "1.
|
|
4510
|
+
var version = "1.6.2";
|
|
4510
4511
|
|
|
4511
4512
|
//#endregion
|
|
4512
4513
|
//#region src/export.ts
|
|
4513
4514
|
const __dirname$1 = dirname$1(fileURLToPath$1(import.meta.url));
|
|
4515
|
+
const execFileAsync = promisify$1(execFile);
|
|
4514
4516
|
function parseCliJson(raw, schema, label) {
|
|
4515
4517
|
const trimmed = raw.trim();
|
|
4516
4518
|
if (!trimmed) throw new Error(`${label} returned empty output`);
|
|
@@ -4559,6 +4561,184 @@ function parseSchemaYaml(content) {
|
|
|
4559
4561
|
if (!validated.success) throw new Error(`Invalid schema.yaml detail: ${validated.error.message}`);
|
|
4560
4562
|
return validated.data;
|
|
4561
4563
|
}
|
|
4564
|
+
function isAbsoluteFsPath(path$1) {
|
|
4565
|
+
const normalized = path$1.replace(/\\/g, "/");
|
|
4566
|
+
return normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized);
|
|
4567
|
+
}
|
|
4568
|
+
function toAbsoluteProjectPath(projectDir, path$1) {
|
|
4569
|
+
return isAbsoluteFsPath(path$1) ? path$1 : resolve$1(projectDir, path$1);
|
|
4570
|
+
}
|
|
4571
|
+
function normalizeGitPath(path$1) {
|
|
4572
|
+
return path$1.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
4573
|
+
}
|
|
4574
|
+
function parseRelatedChanges(paths) {
|
|
4575
|
+
const related = /* @__PURE__ */ new Set();
|
|
4576
|
+
for (const rawPath of paths) {
|
|
4577
|
+
const path$1 = normalizeGitPath(rawPath);
|
|
4578
|
+
const activeMatch = /^openspec\/changes\/([^/]+)\//.exec(path$1);
|
|
4579
|
+
if (activeMatch?.[1]) {
|
|
4580
|
+
related.add(activeMatch[1]);
|
|
4581
|
+
continue;
|
|
4582
|
+
}
|
|
4583
|
+
const archiveMatch = /^openspec\/changes\/archive\/([^/]+)\//.exec(path$1);
|
|
4584
|
+
if (archiveMatch?.[1]) related.add(archiveMatch[1].replace(/^\d{4}-\d{2}-\d{2}-/, ""));
|
|
4585
|
+
}
|
|
4586
|
+
return [...related].sort((a, b) => a.localeCompare(b));
|
|
4587
|
+
}
|
|
4588
|
+
function parseNumstat(numstatOutput) {
|
|
4589
|
+
let files = 0;
|
|
4590
|
+
let insertions = 0;
|
|
4591
|
+
let deletions = 0;
|
|
4592
|
+
for (const line of numstatOutput.split("\n")) {
|
|
4593
|
+
const trimmed = line.trim();
|
|
4594
|
+
if (!trimmed) continue;
|
|
4595
|
+
const [addRaw, delRaw] = trimmed.split(" ");
|
|
4596
|
+
if (!addRaw || !delRaw) continue;
|
|
4597
|
+
files += 1;
|
|
4598
|
+
if (addRaw !== "-") insertions += Number(addRaw) || 0;
|
|
4599
|
+
if (delRaw !== "-") deletions += Number(delRaw) || 0;
|
|
4600
|
+
}
|
|
4601
|
+
return {
|
|
4602
|
+
files,
|
|
4603
|
+
insertions,
|
|
4604
|
+
deletions
|
|
4605
|
+
};
|
|
4606
|
+
}
|
|
4607
|
+
async function readDefaultBranch(projectDir) {
|
|
4608
|
+
try {
|
|
4609
|
+
const { stdout } = await execFileAsync("git", [
|
|
4610
|
+
"symbolic-ref",
|
|
4611
|
+
"--quiet",
|
|
4612
|
+
"--short",
|
|
4613
|
+
"refs/remotes/origin/HEAD"
|
|
4614
|
+
], {
|
|
4615
|
+
cwd: projectDir,
|
|
4616
|
+
encoding: "utf8",
|
|
4617
|
+
maxBuffer: 1024 * 1024
|
|
4618
|
+
});
|
|
4619
|
+
const branch = stdout.trim();
|
|
4620
|
+
if (branch.length > 0) return branch;
|
|
4621
|
+
} catch {}
|
|
4622
|
+
try {
|
|
4623
|
+
const { stdout } = await execFileAsync("git", [
|
|
4624
|
+
"rev-parse",
|
|
4625
|
+
"--abbrev-ref",
|
|
4626
|
+
"HEAD"
|
|
4627
|
+
], {
|
|
4628
|
+
cwd: projectDir,
|
|
4629
|
+
encoding: "utf8",
|
|
4630
|
+
maxBuffer: 1024 * 1024
|
|
4631
|
+
});
|
|
4632
|
+
const branch = stdout.trim();
|
|
4633
|
+
if (branch.length > 0 && branch !== "HEAD") return branch;
|
|
4634
|
+
} catch {}
|
|
4635
|
+
return "main";
|
|
4636
|
+
}
|
|
4637
|
+
function parseRecentCommitLog(output) {
|
|
4638
|
+
const commits = [];
|
|
4639
|
+
let current = null;
|
|
4640
|
+
const pushCurrent = () => {
|
|
4641
|
+
if (!current) return;
|
|
4642
|
+
commits.push({
|
|
4643
|
+
hash: current.hash,
|
|
4644
|
+
title: current.title,
|
|
4645
|
+
committedAt: current.committedAt,
|
|
4646
|
+
relatedChanges: parseRelatedChanges(current.changedPaths),
|
|
4647
|
+
diff: parseNumstat(current.numstatLines.join("\n"))
|
|
4648
|
+
});
|
|
4649
|
+
current = null;
|
|
4650
|
+
};
|
|
4651
|
+
for (const line of output.split("\n")) {
|
|
4652
|
+
if (line.startsWith("__COMMIT__ ")) {
|
|
4653
|
+
pushCurrent();
|
|
4654
|
+
const [_, hash, tsRaw, ...titleParts] = line.split(" ");
|
|
4655
|
+
const committedAt = Number(tsRaw) * 1e3;
|
|
4656
|
+
current = {
|
|
4657
|
+
hash: hash ?? "",
|
|
4658
|
+
title: titleParts.join(" ").trim() || (hash ? hash.slice(0, 8) : "commit"),
|
|
4659
|
+
committedAt: Number.isFinite(committedAt) && committedAt > 0 ? committedAt : 0,
|
|
4660
|
+
numstatLines: [],
|
|
4661
|
+
changedPaths: []
|
|
4662
|
+
};
|
|
4663
|
+
continue;
|
|
4664
|
+
}
|
|
4665
|
+
if (!current) continue;
|
|
4666
|
+
const trimmed = line.trim();
|
|
4667
|
+
if (!trimmed) continue;
|
|
4668
|
+
const [addRaw, delRaw, ...pathParts] = trimmed.split(" ");
|
|
4669
|
+
if (!addRaw || !delRaw || pathParts.length === 0) continue;
|
|
4670
|
+
const path$1 = pathParts.join(" ");
|
|
4671
|
+
current.numstatLines.push(`${addRaw}\t${delRaw}\t${path$1}`);
|
|
4672
|
+
current.changedPaths.push(path$1);
|
|
4673
|
+
}
|
|
4674
|
+
pushCurrent();
|
|
4675
|
+
return commits.filter((commit) => commit.hash.length > 0);
|
|
4676
|
+
}
|
|
4677
|
+
function normalizeRepositoryUrl(raw) {
|
|
4678
|
+
const value = raw.trim();
|
|
4679
|
+
if (!value) return null;
|
|
4680
|
+
if (value.startsWith("http://") || value.startsWith("https://")) return value.replace(/\.git$/i, "");
|
|
4681
|
+
const gitAtMatch = /^git@([^:]+):(.+)$/.exec(value);
|
|
4682
|
+
if (gitAtMatch?.[1] && gitAtMatch[2]) return `https://${gitAtMatch[1]}/${gitAtMatch[2].replace(/\.git$/i, "")}`;
|
|
4683
|
+
if (value.startsWith("ssh://")) try {
|
|
4684
|
+
const parsed = new URL(value);
|
|
4685
|
+
const pathname = parsed.pathname.replace(/^\/+/, "").replace(/\.git$/i, "");
|
|
4686
|
+
if (!pathname) return null;
|
|
4687
|
+
return `https://${parsed.hostname}/${pathname}`;
|
|
4688
|
+
} catch {}
|
|
4689
|
+
return value.replace(/\.git$/i, "");
|
|
4690
|
+
}
|
|
4691
|
+
async function readSnapshotGit(projectDir) {
|
|
4692
|
+
try {
|
|
4693
|
+
const defaultBranch = await readDefaultBranch(projectDir);
|
|
4694
|
+
const { stdout: latestTsRaw } = await execFileAsync("git", [
|
|
4695
|
+
"log",
|
|
4696
|
+
"-1",
|
|
4697
|
+
"--format=%ct"
|
|
4698
|
+
], {
|
|
4699
|
+
cwd: projectDir,
|
|
4700
|
+
encoding: "utf8",
|
|
4701
|
+
maxBuffer: 1024 * 1024
|
|
4702
|
+
});
|
|
4703
|
+
const latestSeconds = Number(latestTsRaw.trim());
|
|
4704
|
+
const latestCommitTs = Number.isFinite(latestSeconds) && latestSeconds > 0 ? latestSeconds * 1e3 : null;
|
|
4705
|
+
let repositoryUrl = null;
|
|
4706
|
+
try {
|
|
4707
|
+
const { stdout: remoteRaw } = await execFileAsync("git", [
|
|
4708
|
+
"config",
|
|
4709
|
+
"--get",
|
|
4710
|
+
"remote.origin.url"
|
|
4711
|
+
], {
|
|
4712
|
+
cwd: projectDir,
|
|
4713
|
+
encoding: "utf8",
|
|
4714
|
+
maxBuffer: 1024 * 1024
|
|
4715
|
+
});
|
|
4716
|
+
repositoryUrl = normalizeRepositoryUrl(remoteRaw);
|
|
4717
|
+
} catch {
|
|
4718
|
+
repositoryUrl = null;
|
|
4719
|
+
}
|
|
4720
|
+
const { stdout: logOutput } = await execFileAsync("git", [
|
|
4721
|
+
"log",
|
|
4722
|
+
"-n",
|
|
4723
|
+
"5",
|
|
4724
|
+
"--format=__COMMIT__%x09%H%x09%ct%x09%s",
|
|
4725
|
+
"--numstat",
|
|
4726
|
+
"--"
|
|
4727
|
+
], {
|
|
4728
|
+
cwd: projectDir,
|
|
4729
|
+
encoding: "utf8",
|
|
4730
|
+
maxBuffer: 8 * 1024 * 1024
|
|
4731
|
+
});
|
|
4732
|
+
return {
|
|
4733
|
+
defaultBranch,
|
|
4734
|
+
repositoryUrl,
|
|
4735
|
+
latestCommitTs,
|
|
4736
|
+
recentCommits: parseRecentCommitLog(logOutput)
|
|
4737
|
+
};
|
|
4738
|
+
} catch {
|
|
4739
|
+
return;
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4562
4742
|
/**
|
|
4563
4743
|
* Generate a complete data snapshot of the OpenSpec project
|
|
4564
4744
|
* (Kept for backwards compatibility and testing)
|
|
@@ -4586,12 +4766,11 @@ async function generateSnapshot(projectDir) {
|
|
|
4586
4766
|
const changesMeta = await adapter.listChangesWithMeta();
|
|
4587
4767
|
const changes = await Promise.all(changesMeta.map(async (meta) => {
|
|
4588
4768
|
const change = await adapter.readChange(meta.id);
|
|
4589
|
-
if (!change) return null;
|
|
4590
4769
|
const files = await adapter.readChangeFiles(meta.id);
|
|
4591
4770
|
const proposalFile = files.find((f) => f.path === "proposal.md");
|
|
4592
4771
|
const tasksFile = files.find((f) => f.path === "tasks.md");
|
|
4593
4772
|
const designFile = files.find((f) => f.path === "design.md");
|
|
4594
|
-
const deltas = (change
|
|
4773
|
+
const deltas = (change?.deltaSpecs || []).map((ds) => ({
|
|
4595
4774
|
capability: ds.specId,
|
|
4596
4775
|
content: ds.content || ""
|
|
4597
4776
|
}));
|
|
@@ -4601,11 +4780,11 @@ async function generateSnapshot(projectDir) {
|
|
|
4601
4780
|
proposal: proposalFile?.content || "",
|
|
4602
4781
|
tasks: tasksFile?.content,
|
|
4603
4782
|
design: designFile?.content,
|
|
4604
|
-
why: change
|
|
4605
|
-
whatChanges: change
|
|
4606
|
-
parsedTasks: change
|
|
4783
|
+
why: change?.why || "",
|
|
4784
|
+
whatChanges: change?.whatChanges || "",
|
|
4785
|
+
parsedTasks: change?.tasks || [],
|
|
4607
4786
|
deltas,
|
|
4608
|
-
progress: meta.progress,
|
|
4787
|
+
progress: change?.progress ?? meta.progress,
|
|
4609
4788
|
createdAt: meta.createdAt,
|
|
4610
4789
|
updatedAt: meta.updatedAt
|
|
4611
4790
|
};
|
|
@@ -4641,8 +4820,10 @@ async function generateSnapshot(projectDir) {
|
|
|
4641
4820
|
let configYaml;
|
|
4642
4821
|
let schemas = [];
|
|
4643
4822
|
const schemaDetails = {};
|
|
4823
|
+
const schemaYamls = {};
|
|
4644
4824
|
const schemaResolutions = {};
|
|
4645
4825
|
const templates = {};
|
|
4826
|
+
const templateContents = {};
|
|
4646
4827
|
const changeMetadata = {};
|
|
4647
4828
|
try {
|
|
4648
4829
|
configYaml = await readFile(join$1(projectDir, "openspec", "config.yaml"), "utf-8");
|
|
@@ -4660,16 +4841,56 @@ async function generateSnapshot(projectDir) {
|
|
|
4660
4841
|
const resolutionResult = await cliExecutor.schemaWhich(schema.name);
|
|
4661
4842
|
if (resolutionResult.success) {
|
|
4662
4843
|
const resolution = parseCliJson(resolutionResult.stdout, SchemaResolutionSchema, "openspec schema which");
|
|
4663
|
-
schemaResolutions[schema.name] =
|
|
4844
|
+
schemaResolutions[schema.name] = {
|
|
4845
|
+
...resolution,
|
|
4846
|
+
displayPath: toOpsxDisplayPath(resolution.path, {
|
|
4847
|
+
source: resolution.source,
|
|
4848
|
+
projectDir
|
|
4849
|
+
}),
|
|
4850
|
+
shadows: resolution.shadows.map((shadow) => ({
|
|
4851
|
+
...shadow,
|
|
4852
|
+
displayPath: toOpsxDisplayPath(shadow.path, {
|
|
4853
|
+
source: shadow.source,
|
|
4854
|
+
projectDir
|
|
4855
|
+
})
|
|
4856
|
+
}))
|
|
4857
|
+
};
|
|
4664
4858
|
try {
|
|
4665
4859
|
const schemaContent = await readFile(join$1(resolution.path, "schema.yaml"), "utf-8");
|
|
4666
4860
|
schemaDetails[schema.name] = parseSchemaYaml(schemaContent);
|
|
4861
|
+
schemaYamls[schema.name] = schemaContent;
|
|
4667
4862
|
} catch {}
|
|
4668
4863
|
}
|
|
4669
4864
|
} catch {}
|
|
4670
4865
|
try {
|
|
4671
4866
|
const templatesResult = await cliExecutor.templates(schema.name);
|
|
4672
|
-
if (templatesResult.success)
|
|
4867
|
+
if (templatesResult.success) {
|
|
4868
|
+
const parsedTemplates = parseCliJson(templatesResult.stdout, TemplatesSchema, "openspec templates");
|
|
4869
|
+
const normalizedTemplates = Object.fromEntries(Object.entries(parsedTemplates).map(([artifactId, info]) => [artifactId, {
|
|
4870
|
+
...info,
|
|
4871
|
+
path: toAbsoluteProjectPath(projectDir, info.path),
|
|
4872
|
+
displayPath: toOpsxDisplayPath(info.path, {
|
|
4873
|
+
source: info.source,
|
|
4874
|
+
projectDir
|
|
4875
|
+
})
|
|
4876
|
+
}]));
|
|
4877
|
+
templates[schema.name] = normalizedTemplates;
|
|
4878
|
+
const contents = await Promise.all(Object.entries(normalizedTemplates).map(async ([artifactId, info]) => {
|
|
4879
|
+
let content = null;
|
|
4880
|
+
try {
|
|
4881
|
+
content = await readFile(info.path, "utf-8");
|
|
4882
|
+
} catch {
|
|
4883
|
+
content = null;
|
|
4884
|
+
}
|
|
4885
|
+
return [artifactId, {
|
|
4886
|
+
content,
|
|
4887
|
+
path: info.path,
|
|
4888
|
+
displayPath: info.displayPath,
|
|
4889
|
+
source: info.source
|
|
4890
|
+
}];
|
|
4891
|
+
}));
|
|
4892
|
+
templateContents[schema.name] = Object.fromEntries(contents);
|
|
4893
|
+
}
|
|
4673
4894
|
} catch {}
|
|
4674
4895
|
}
|
|
4675
4896
|
try {
|
|
@@ -4680,6 +4901,7 @@ async function generateSnapshot(projectDir) {
|
|
|
4680
4901
|
changeMetadata[changeId] = null;
|
|
4681
4902
|
}
|
|
4682
4903
|
} catch {}
|
|
4904
|
+
const git = await readSnapshotGit(projectDir);
|
|
4683
4905
|
return {
|
|
4684
4906
|
meta: {
|
|
4685
4907
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4691,9 +4913,10 @@ async function generateSnapshot(projectDir) {
|
|
|
4691
4913
|
changesCount: changes.filter((c) => c !== null).length,
|
|
4692
4914
|
archivesCount: archives.length
|
|
4693
4915
|
},
|
|
4916
|
+
git,
|
|
4694
4917
|
config: uiConfig,
|
|
4695
4918
|
specs,
|
|
4696
|
-
changes
|
|
4919
|
+
changes,
|
|
4697
4920
|
archives,
|
|
4698
4921
|
projectMd,
|
|
4699
4922
|
agentsMd,
|
|
@@ -4701,8 +4924,10 @@ async function generateSnapshot(projectDir) {
|
|
|
4701
4924
|
configYaml,
|
|
4702
4925
|
schemas,
|
|
4703
4926
|
schemaDetails,
|
|
4927
|
+
schemaYamls,
|
|
4704
4928
|
schemaResolutions,
|
|
4705
4929
|
templates,
|
|
4930
|
+
templateContents,
|
|
4706
4931
|
changeMetadata
|
|
4707
4932
|
}
|
|
4708
4933
|
};
|
|
@@ -4723,7 +4948,7 @@ function runCommand(cmd, args, cwd) {
|
|
|
4723
4948
|
const child = spawn(cmd, args, {
|
|
4724
4949
|
stdio: "inherit",
|
|
4725
4950
|
cwd,
|
|
4726
|
-
shell:
|
|
4951
|
+
shell: false
|
|
4727
4952
|
});
|
|
4728
4953
|
child.on("close", (code) => {
|
|
4729
4954
|
if (code === 0) resolvePromise();
|
|
@@ -4757,7 +4982,7 @@ function detectPackageManager() {
|
|
|
4757
4982
|
return "npm";
|
|
4758
4983
|
}
|
|
4759
4984
|
/**
|
|
4760
|
-
* Get the command to run a
|
|
4985
|
+
* Get the command to run a binary in a package-manager agnostic way.
|
|
4761
4986
|
*/
|
|
4762
4987
|
function getRunCommand(pm, bin) {
|
|
4763
4988
|
switch (pm) {
|
|
@@ -4767,11 +4992,11 @@ function getRunCommand(pm, bin) {
|
|
|
4767
4992
|
};
|
|
4768
4993
|
case "pnpm": return {
|
|
4769
4994
|
cmd: "pnpm",
|
|
4770
|
-
args: ["
|
|
4995
|
+
args: ["dlx", bin]
|
|
4771
4996
|
};
|
|
4772
4997
|
case "yarn": return {
|
|
4773
4998
|
cmd: "yarn",
|
|
4774
|
-
args: [bin]
|
|
4999
|
+
args: ["dlx", bin]
|
|
4775
5000
|
};
|
|
4776
5001
|
case "deno": return {
|
|
4777
5002
|
cmd: "deno",
|
|
@@ -5043,6 +5268,10 @@ async function main() {
|
|
|
5043
5268
|
}).option("preview-port", {
|
|
5044
5269
|
describe: "Port for the preview server (used with --open)",
|
|
5045
5270
|
type: "number"
|
|
5271
|
+
}).option("port", {
|
|
5272
|
+
alias: "p",
|
|
5273
|
+
describe: "Alias of --open --preview-port <port>",
|
|
5274
|
+
type: "number"
|
|
5046
5275
|
}).option("preview-host", {
|
|
5047
5276
|
describe: "Host for the preview server (used with --open)",
|
|
5048
5277
|
type: "string"
|
|
@@ -5050,6 +5279,8 @@ async function main() {
|
|
|
5050
5279
|
}, async (argv) => {
|
|
5051
5280
|
const projectDir = resolve$1(originalCwd, argv.dir || ".");
|
|
5052
5281
|
const outputDir = resolve$1(originalCwd, argv.output);
|
|
5282
|
+
const previewPort = argv.port ?? argv["preview-port"];
|
|
5283
|
+
const shouldOpen = argv.open || argv.port !== void 0;
|
|
5053
5284
|
try {
|
|
5054
5285
|
await exportStaticSite({
|
|
5055
5286
|
projectDir,
|
|
@@ -5057,16 +5288,16 @@ async function main() {
|
|
|
5057
5288
|
format: argv.format,
|
|
5058
5289
|
basePath: argv["base-path"],
|
|
5059
5290
|
clean: argv.clean,
|
|
5060
|
-
open:
|
|
5061
|
-
previewPort
|
|
5291
|
+
open: shouldOpen,
|
|
5292
|
+
previewPort,
|
|
5062
5293
|
previewHost: argv["preview-host"]
|
|
5063
5294
|
});
|
|
5064
|
-
if (!
|
|
5295
|
+
if (!shouldOpen) process.exit(0);
|
|
5065
5296
|
} catch (error) {
|
|
5066
5297
|
console.error("❌ Export failed:", error);
|
|
5067
5298
|
process.exit(1);
|
|
5068
5299
|
}
|
|
5069
|
-
}).example("$0", "Start server in current directory").example("$0 ./my-project", "Start server with specific project").example("$0 -p 8080", "Start server on custom port").example("$0 export -o ./dist", "Export HTML to ./dist directory").example("$0 export -o ./dist -f json", "Export JSON data only").example("$0 export -o ./dist --base-path=/docs/", "Export for subdirectory deployment").example("$0 export -o ./dist --clean", "Clean output directory before export").version(getVersion()).alias("v", "version").help().alias("h", "help").parse();
|
|
5300
|
+
}).example("$0", "Start server in current directory").example("$0 ./my-project", "Start server with specific project").example("$0 -p 8080", "Start server on custom port").example("$0 export -o ./dist", "Export HTML to ./dist directory").example("$0 export -o ./dist -f json", "Export JSON data only").example("$0 export -o ./dist -p 8092", "Export and open preview on port 8092").example("$0 export -o ./dist --base-path=/docs/", "Export for subdirectory deployment").example("$0 export -o ./dist --clean", "Clean output directory before export").version(getVersion()).alias("v", "version").help().alias("h", "help").parse();
|
|
5070
5301
|
}
|
|
5071
5302
|
main();
|
|
5072
5303
|
|
package/dist/index.mjs
CHANGED