mergestorm 0.3.9 → 0.3.15
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 +67 -24
- package/dist/api.d.ts +106 -40
- package/dist/api.js +245 -9
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.js +5 -0
- package/dist/commands/branches.d.ts +6 -2
- package/dist/commands/branches.js +29 -14
- package/dist/commands/browse.d.ts +39 -0
- package/dist/commands/browse.js +259 -0
- package/dist/commands/credits.js +30 -12
- package/dist/commands/help.d.ts +5 -0
- package/dist/commands/help.js +93 -0
- package/dist/commands/jobs.d.ts +11 -2
- package/dist/commands/jobs.js +64 -15
- package/dist/commands/login.js +32 -10
- package/dist/commands/logout.js +2 -1
- package/dist/commands/pr.d.ts +22 -0
- package/dist/commands/pr.js +127 -0
- package/dist/commands/queue.d.ts +12 -0
- package/dist/commands/queue.js +160 -0
- package/dist/commands/registry.d.ts +1 -1
- package/dist/commands/registry.js +115 -33
- package/dist/commands/review-client.d.ts +106 -0
- package/dist/commands/review-client.js +399 -0
- package/dist/commands/review.d.ts +36 -6
- package/dist/commands/review.js +395 -145
- package/dist/commands/settings.d.ts +17 -0
- package/dist/commands/settings.js +89 -0
- package/dist/commands/skill.d.ts +20 -0
- package/dist/commands/skill.js +145 -0
- package/dist/commands/stack.d.ts +36 -2
- package/dist/commands/stack.js +341 -113
- package/dist/commands/status.d.ts +18 -2
- package/dist/commands/status.js +236 -21
- package/dist/commands/whoami.d.ts +3 -1
- package/dist/commands/whoami.js +21 -7
- package/dist/errors.d.ts +18 -2
- package/dist/errors.js +22 -1
- package/dist/git-stack.d.ts +2 -0
- package/dist/git-stack.js +4 -0
- package/dist/git.d.ts +12 -1
- package/dist/git.js +52 -7
- package/dist/shell.d.ts +1 -1
- package/dist/shell.js +39 -28
- package/dist/stack-dto.d.ts +266 -0
- package/dist/stack-dto.js +7 -0
- package/dist/submit-pr-base.d.ts +31 -0
- package/dist/submit-pr-base.js +69 -0
- package/dist/ui/ansi.d.ts +2 -0
- package/dist/ui/ansi.js +2 -0
- package/dist/ui/banner.d.ts +34 -2
- package/dist/ui/banner.js +170 -79
- package/dist/ui/box.d.ts +13 -9
- package/dist/ui/box.js +28 -44
- package/dist/ui/findings.d.ts +4 -1
- package/dist/ui/findings.js +14 -7
- package/dist/ui/job-envelope.d.ts +68 -0
- package/dist/ui/job-envelope.js +35 -0
- package/dist/ui/line-tabs.d.ts +27 -0
- package/dist/ui/line-tabs.js +170 -0
- package/dist/ui/logo.d.ts +10 -2
- package/dist/ui/logo.js +13 -9
- package/dist/ui/present.d.ts +10 -0
- package/dist/ui/present.js +13 -0
- package/dist/ui/prompt.d.ts +148 -0
- package/dist/ui/prompt.js +433 -71
- package/dist/ui/select.js +1 -1
- package/dist/ui/tabs.d.ts +125 -0
- package/dist/ui/tabs.js +480 -0
- package/dist/ui/usage.d.ts +29 -1
- package/dist/ui/usage.js +71 -2
- package/dist/ui/width.d.ts +26 -0
- package/dist/ui/width.js +262 -0
- package/package.json +6 -1
- package/skill/SKILL.md +98 -0
- package/skill/mergestorm-pr-loop/SKILL.md +76 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { getSettings, patchSettings, } from "../api.js";
|
|
2
|
+
import { loadConfig } from "../config.js";
|
|
3
|
+
import { CommandError } from "../errors.js";
|
|
4
|
+
import { present } from "../ui/present.js";
|
|
5
|
+
import { buildConfigRows, canBrowse, openTabsBrowser } from "./browse.js";
|
|
6
|
+
/**
|
|
7
|
+
* CLI flag → Bearer settings key. on|off only. The connected flags are
|
|
8
|
+
* read-only on the API and deliberately have no flag here.
|
|
9
|
+
*/
|
|
10
|
+
export const SETTINGS_FLAGS = {
|
|
11
|
+
"--auto-review": "auto_review_enabled",
|
|
12
|
+
"--auto-patch": "auto_patch_enabled",
|
|
13
|
+
"--vortex-thinking": "vortex_show_thinking_traces",
|
|
14
|
+
"--repo-overview": "repo_overview_enabled",
|
|
15
|
+
"--review-unit-land": "review_unit_land_prs_enabled",
|
|
16
|
+
"--cyclone-review-unit-land": "cyclone_review_unit_land_prs_enabled",
|
|
17
|
+
"--vortex-seam": "vortex_seam_specialist_enabled",
|
|
18
|
+
};
|
|
19
|
+
/** Parse `settings` argv. Accepts `--flag on|off` and `--flag=on|off`. */
|
|
20
|
+
export function parseSettingsArgs(args) {
|
|
21
|
+
let json = false;
|
|
22
|
+
const patch = {};
|
|
23
|
+
for (let i = 0; i < args.length; i++) {
|
|
24
|
+
const arg = args[i];
|
|
25
|
+
if (arg === "--json") {
|
|
26
|
+
json = true;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const eq = arg.indexOf("=");
|
|
30
|
+
const flag = eq >= 0 ? arg.slice(0, eq) : arg;
|
|
31
|
+
const key = SETTINGS_FLAGS[flag];
|
|
32
|
+
if (!key) {
|
|
33
|
+
throw new CommandError(`Unknown settings flag: ${flag}. See \`mergestorm --help\`.`, 2, "usage");
|
|
34
|
+
}
|
|
35
|
+
const value = eq >= 0 ? arg.slice(eq + 1) : args[++i];
|
|
36
|
+
if (value !== "on" && value !== "off") {
|
|
37
|
+
throw new CommandError(`${flag} takes on or off.`, 2, "usage");
|
|
38
|
+
}
|
|
39
|
+
patch[key] = value === "on";
|
|
40
|
+
}
|
|
41
|
+
return { json, patch };
|
|
42
|
+
}
|
|
43
|
+
/** Static printout of the GET/PATCH response shape (rows match the Config tab). */
|
|
44
|
+
export function formatSettingsLines(settings) {
|
|
45
|
+
const rows = buildConfigRows(settings);
|
|
46
|
+
const labelWidth = Math.max(...rows.map((r) => r.label.length));
|
|
47
|
+
return rows.map((row) => {
|
|
48
|
+
const value = row.writable
|
|
49
|
+
? row.value
|
|
50
|
+
? "on"
|
|
51
|
+
: "off"
|
|
52
|
+
: row.value
|
|
53
|
+
? "connected"
|
|
54
|
+
: "not connected";
|
|
55
|
+
return ` ${row.label.padEnd(labelWidth + 2)}${value}`;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export async function cmdSettings(args, opts = {}) {
|
|
59
|
+
const { json, patch } = parseSettingsArgs(args);
|
|
60
|
+
const hasPatch = Object.keys(patch).length > 0;
|
|
61
|
+
// Bare `settings` on a TTY: the tabbed browser, opened on Config.
|
|
62
|
+
if (!hasPatch && !json && canBrowse()) {
|
|
63
|
+
await openTabsBrowser("config");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const cfg = await loadConfig();
|
|
67
|
+
let settings;
|
|
68
|
+
if (hasPatch) {
|
|
69
|
+
settings = await patchSettings(patch, cfg);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const got = await getSettings(cfg);
|
|
73
|
+
if (!got) {
|
|
74
|
+
throw new CommandError("Settings are not available (offline or API too old). " +
|
|
75
|
+
"Try again or open https://mergestorm.ai/settings");
|
|
76
|
+
}
|
|
77
|
+
settings = got;
|
|
78
|
+
}
|
|
79
|
+
if (json) {
|
|
80
|
+
const text = JSON.stringify(settings, null, 2);
|
|
81
|
+
if (opts.mode === "shell") {
|
|
82
|
+
await present("Settings", text.split("\n"));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
console.log(text);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
await present("Settings", formatSettingsLines(settings));
|
|
89
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const SKILL_NAME = "mergestorm-review";
|
|
2
|
+
export declare const PR_LOOP_SKILL_NAME = "mergestorm-pr-loop";
|
|
3
|
+
export declare const SKILL_NAMES: readonly ["mergestorm-review", "mergestorm-pr-loop"];
|
|
4
|
+
export type SkillName = (typeof SKILL_NAMES)[number];
|
|
5
|
+
export declare const SKILL_USAGE = "usage:\n mergestorm skill install --claude|--cursor [--json]\n\n Copies mergestorm-review and mergestorm-pr-loop into this repo (git toplevel, else cwd):\n --claude .claude/skills/<name>/SKILL.md\n --cursor .cursor/skills/<name>/SKILL.md\n Pass both flags to write both trees. Overwrites existing copies.";
|
|
6
|
+
export type SkillTarget = "claude" | "cursor";
|
|
7
|
+
export type SkillInstallRequest = {
|
|
8
|
+
help: boolean;
|
|
9
|
+
json: boolean;
|
|
10
|
+
targets: SkillTarget[];
|
|
11
|
+
};
|
|
12
|
+
export declare function parseSkillArgs(args: string[]): SkillInstallRequest;
|
|
13
|
+
/** Prefer the git repo root so `mg skill install` from a subdir still lands in-project. */
|
|
14
|
+
export declare function skillInstallRoot(cwd?: string): string;
|
|
15
|
+
export declare function skillDestination(root: string, target: SkillTarget, name?: SkillName): string;
|
|
16
|
+
export declare function resolveBundledSkillPath(fromFile?: string, name?: SkillName): string;
|
|
17
|
+
export declare function writeSkillCopies(sourcePath: string, destinations: string[]): Promise<string[]>;
|
|
18
|
+
export declare function cmdSkill(args: string[], opts?: {
|
|
19
|
+
cwd?: string;
|
|
20
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { lstat, mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { CommandError, isCommandErrorCode } from "../errors.js";
|
|
6
|
+
import { gitTopLevel } from "../repo-identity.js";
|
|
7
|
+
import { present } from "../ui/present.js";
|
|
8
|
+
export const SKILL_NAME = "mergestorm-review";
|
|
9
|
+
export const PR_LOOP_SKILL_NAME = "mergestorm-pr-loop";
|
|
10
|
+
export const SKILL_NAMES = [SKILL_NAME, PR_LOOP_SKILL_NAME];
|
|
11
|
+
export const SKILL_USAGE = `usage:
|
|
12
|
+
mergestorm skill install --claude|--cursor [--json]
|
|
13
|
+
|
|
14
|
+
Copies mergestorm-review and mergestorm-pr-loop into this repo (git toplevel, else cwd):
|
|
15
|
+
--claude .claude/skills/<name>/SKILL.md
|
|
16
|
+
--cursor .cursor/skills/<name>/SKILL.md
|
|
17
|
+
Pass both flags to write both trees. Overwrites existing copies.`;
|
|
18
|
+
export function parseSkillArgs(args) {
|
|
19
|
+
const [sub, ...rest] = args;
|
|
20
|
+
if (!sub || sub === "-h" || sub === "--help" || sub === "help") {
|
|
21
|
+
return { help: true, json: false, targets: [] };
|
|
22
|
+
}
|
|
23
|
+
if (sub !== "install") {
|
|
24
|
+
throw new CommandError(`${SKILL_USAGE}\nunknown skill subcommand: ${sub}`, 1, "usage");
|
|
25
|
+
}
|
|
26
|
+
let json = false;
|
|
27
|
+
const targets = [];
|
|
28
|
+
for (const arg of rest) {
|
|
29
|
+
if (arg === "--json") {
|
|
30
|
+
json = true;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (arg === "--claude") {
|
|
34
|
+
if (!targets.includes("claude"))
|
|
35
|
+
targets.push("claude");
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (arg === "--cursor") {
|
|
39
|
+
if (!targets.includes("cursor"))
|
|
40
|
+
targets.push("cursor");
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (arg === "-h" || arg === "--help" || arg === "help") {
|
|
44
|
+
return { help: true, json: false, targets: [] };
|
|
45
|
+
}
|
|
46
|
+
throw new CommandError(`${SKILL_USAGE}\nunknown flag: ${arg}`, 1, "usage");
|
|
47
|
+
}
|
|
48
|
+
if (targets.length === 0) {
|
|
49
|
+
throw new CommandError(`${SKILL_USAGE}\npass --claude and/or --cursor`, 1, "usage");
|
|
50
|
+
}
|
|
51
|
+
return { help: false, json, targets };
|
|
52
|
+
}
|
|
53
|
+
/** Prefer the git repo root so `mg skill install` from a subdir still lands in-project. */
|
|
54
|
+
export function skillInstallRoot(cwd = process.cwd()) {
|
|
55
|
+
try {
|
|
56
|
+
return gitTopLevel(cwd);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
if (isCommandErrorCode(err, "not_a_repo"))
|
|
60
|
+
return path.resolve(cwd);
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function skillDestination(root, target, name = SKILL_NAME) {
|
|
65
|
+
if (target === "claude") {
|
|
66
|
+
return path.join(root, ".claude", "skills", name, "SKILL.md");
|
|
67
|
+
}
|
|
68
|
+
return path.join(root, ".cursor", "skills", name, "SKILL.md");
|
|
69
|
+
}
|
|
70
|
+
export function resolveBundledSkillPath(fromFile = import.meta.url, name = SKILL_NAME) {
|
|
71
|
+
const here = path.dirname(fileURLToPath(fromFile));
|
|
72
|
+
const packageRoot = path.resolve(here, "..", "..");
|
|
73
|
+
// The published package ships the review skill at skill/SKILL.md; extra
|
|
74
|
+
// skills sit beside it in per-name directories. The monorepo keeps every
|
|
75
|
+
// skill under skills/<name>/SKILL.md.
|
|
76
|
+
const candidates = name === SKILL_NAME
|
|
77
|
+
? [
|
|
78
|
+
path.join(packageRoot, "skill", "SKILL.md"),
|
|
79
|
+
path.join(packageRoot, "..", "..", "skills", name, "SKILL.md"),
|
|
80
|
+
]
|
|
81
|
+
: [
|
|
82
|
+
path.join(packageRoot, "skill", name, "SKILL.md"),
|
|
83
|
+
path.join(packageRoot, "..", "..", "skills", name, "SKILL.md"),
|
|
84
|
+
];
|
|
85
|
+
for (const candidate of candidates) {
|
|
86
|
+
if (existsSync(candidate))
|
|
87
|
+
return candidate;
|
|
88
|
+
}
|
|
89
|
+
throw new CommandError(`${name} skill is missing (looked in ${candidates.join(" and ")})`);
|
|
90
|
+
}
|
|
91
|
+
async function assertNoSymlink(dest) {
|
|
92
|
+
const parts = dest.split(path.sep);
|
|
93
|
+
const marker = parts.findIndex((p) => p === ".claude" || p === ".cursor");
|
|
94
|
+
const first = marker === -1 ? parts.length - 1 : marker;
|
|
95
|
+
for (let i = first; i < parts.length; i++) {
|
|
96
|
+
const candidate = parts.slice(0, i + 1).join(path.sep);
|
|
97
|
+
let stat;
|
|
98
|
+
try {
|
|
99
|
+
stat = await lstat(candidate);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
if (err.code === "ENOENT")
|
|
103
|
+
continue;
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
if (stat.isSymbolicLink()) {
|
|
107
|
+
throw new CommandError(`refusing to write skill through symlink: ${candidate}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export async function writeSkillCopies(sourcePath, destinations) {
|
|
112
|
+
const body = readFileSync(sourcePath, "utf8");
|
|
113
|
+
const written = [];
|
|
114
|
+
for (const dest of destinations) {
|
|
115
|
+
await assertNoSymlink(dest);
|
|
116
|
+
await mkdir(path.dirname(dest), { recursive: true });
|
|
117
|
+
await writeFile(dest, body, "utf8");
|
|
118
|
+
written.push(dest);
|
|
119
|
+
}
|
|
120
|
+
return written;
|
|
121
|
+
}
|
|
122
|
+
export async function cmdSkill(args, opts = {}) {
|
|
123
|
+
const req = parseSkillArgs(args);
|
|
124
|
+
if (req.help) {
|
|
125
|
+
await present("Skill", SKILL_USAGE.split("\n"));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const root = skillInstallRoot(opts.cwd);
|
|
129
|
+
const sources = {};
|
|
130
|
+
const written = [];
|
|
131
|
+
for (const name of SKILL_NAMES) {
|
|
132
|
+
const source = resolveBundledSkillPath(undefined, name);
|
|
133
|
+
sources[name] = source;
|
|
134
|
+
const destinations = req.targets.map((t) => skillDestination(root, t, name));
|
|
135
|
+
written.push(...(await writeSkillCopies(source, destinations)));
|
|
136
|
+
}
|
|
137
|
+
if (req.json) {
|
|
138
|
+
await present("Skill", JSON.stringify({ names: SKILL_NAMES, sources, written }, null, 2).split("\n"));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
await present("Skill", [
|
|
142
|
+
` Installed ${SKILL_NAMES.join(" and ")}`,
|
|
143
|
+
...written.map((dest) => ` ${dest}`),
|
|
144
|
+
]);
|
|
145
|
+
}
|
package/dist/commands/stack.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import { adoptStack } from "../api.js";
|
|
1
|
+
import { adoptStack, ensureUpperPark, listStacks, type StackDto } from "../api.js";
|
|
2
2
|
import { loadConfig } from "../config.js";
|
|
3
3
|
import { createPr, findOpenPrNumber } from "../gh.js";
|
|
4
4
|
import { parseGithubOriginRepo } from "../git.js";
|
|
5
|
-
import { branchExists, commitsAheadOf, pushBranch, tipCommitMessage, tipCommitSubject } from "../git-stack.js";
|
|
5
|
+
import { branchExists, commitsAheadOf, fetchRemoteBranch, pushBranch, tipCommitMessage, tipCommitSubject } from "../git-stack.js";
|
|
6
6
|
import { buildPrBodyFromCommit } from "../pr-body.js";
|
|
7
7
|
import { loadStackMeta, saveStackMeta } from "../stack-meta.js";
|
|
8
|
+
/** A registered stack layer that would become the parent of a new layer. */
|
|
9
|
+
export type RegisteredParentHit = {
|
|
10
|
+
stackId: string;
|
|
11
|
+
owner: string;
|
|
12
|
+
repo: string;
|
|
13
|
+
branch: string;
|
|
14
|
+
prNumber: number;
|
|
15
|
+
position: number;
|
|
16
|
+
};
|
|
17
|
+
/** Find a registered stack layer whose branch matches `parentBranch`. */
|
|
18
|
+
export declare function findRegisteredParent(stacks: StackDto[], parentBranch: string, owner?: string, repo?: string): RegisteredParentHit | null;
|
|
19
|
+
/**
|
|
20
|
+
* Refuse silently growing an already-registered stack.
|
|
21
|
+
* Local unsubmitted parents are fine; only API-listed layers trip this.
|
|
22
|
+
*/
|
|
23
|
+
export declare function assertMayParentOntoRegistered(parentBranch: string, stacks: StackDto[], extend: boolean, verb: "create" | "submit", owner?: string, repo?: string): RegisteredParentHit | null;
|
|
8
24
|
export declare function requireStackId(raw: string | undefined, usage: string): string;
|
|
9
25
|
/** Parse `owner/repo#12` or `owner/repo 12`. */
|
|
10
26
|
export declare function parseAdoptTarget(args: string[]): {
|
|
@@ -12,14 +28,29 @@ export declare function parseAdoptTarget(args: string[]): {
|
|
|
12
28
|
repo: string;
|
|
13
29
|
prNumber: number;
|
|
14
30
|
};
|
|
31
|
+
/** Empty + populated bodies for the TTY `stack list` panel. */
|
|
32
|
+
export declare function buildStackListLines(stacks: StackDto[]): string[];
|
|
15
33
|
/** Parse `stack create` argv into options. Exported for tests. */
|
|
16
34
|
export declare function parseStackCreateArgs(args: string[]): {
|
|
17
35
|
name?: string;
|
|
18
36
|
onto?: string;
|
|
19
37
|
trunk?: string;
|
|
38
|
+
extend: boolean;
|
|
39
|
+
asJson: boolean;
|
|
40
|
+
};
|
|
41
|
+
/** Parse `stack submit` argv. Exported for tests. */
|
|
42
|
+
export declare function parseStackSubmitArgs(args: string[]): {
|
|
43
|
+
extend: boolean;
|
|
20
44
|
asJson: boolean;
|
|
21
45
|
};
|
|
22
46
|
export declare function parseStackResetArgs(args: string[]): void;
|
|
47
|
+
/** Injectable seams for unit tests. Production callers omit deps. */
|
|
48
|
+
export type StackCreateDeps = {
|
|
49
|
+
cwd?: string;
|
|
50
|
+
listStacks?: typeof listStacks;
|
|
51
|
+
loadConfig?: typeof loadConfig;
|
|
52
|
+
parseGithubOriginRepo?: typeof parseGithubOriginRepo;
|
|
53
|
+
};
|
|
23
54
|
/** Injectable seams for unit tests (STRUCT-04). Production callers omit deps. */
|
|
24
55
|
export type StackSubmitDeps = {
|
|
25
56
|
cwd?: string;
|
|
@@ -29,6 +60,7 @@ export type StackSubmitDeps = {
|
|
|
29
60
|
parseGithubOriginRepo?: typeof parseGithubOriginRepo;
|
|
30
61
|
requireGh?: (cwd?: string) => void;
|
|
31
62
|
branchExists?: typeof branchExists;
|
|
63
|
+
fetchRemoteBranch?: typeof fetchRemoteBranch;
|
|
32
64
|
pushBranch?: typeof pushBranch;
|
|
33
65
|
findOpenPrNumber?: typeof findOpenPrNumber;
|
|
34
66
|
commitsAheadOf?: typeof commitsAheadOf;
|
|
@@ -37,7 +69,9 @@ export type StackSubmitDeps = {
|
|
|
37
69
|
buildPrBodyFromCommit?: typeof buildPrBodyFromCommit;
|
|
38
70
|
createPr?: typeof createPr;
|
|
39
71
|
loadConfig?: typeof loadConfig;
|
|
72
|
+
listStacks?: typeof listStacks;
|
|
40
73
|
adoptStack?: typeof adoptStack;
|
|
74
|
+
ensureUpperPark?: typeof ensureUpperPark;
|
|
41
75
|
};
|
|
42
76
|
export declare function cmdStackSubmit(args: string[], deps?: StackSubmitDeps): Promise<void>;
|
|
43
77
|
export declare function cmdStack(args: string[]): Promise<void>;
|