@launch11/srgical 0.0.1
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/LICENSE +21 -0
- package/README.md +164 -0
- package/dist/commands/doctor.js +68 -0
- package/dist/commands/init.js +26 -0
- package/dist/commands/run-next.js +54 -0
- package/dist/commands/studio.js +7 -0
- package/dist/core/agent.js +164 -0
- package/dist/core/claude.js +271 -0
- package/dist/core/codex.js +257 -0
- package/dist/core/execution-controls.js +87 -0
- package/dist/core/execution-state.js +87 -0
- package/dist/core/local-pack.js +125 -0
- package/dist/core/planning-epochs.js +116 -0
- package/dist/core/planning-pack-state.js +121 -0
- package/dist/core/prompts.js +230 -0
- package/dist/core/studio-session.js +99 -0
- package/dist/core/templates.js +189 -0
- package/dist/core/workspace.js +67 -0
- package/dist/index.js +60 -0
- package/dist/ui/studio.js +704 -0
- package/docs/adr/0001-tech-stack.md +27 -0
- package/docs/distribution.md +129 -0
- package/docs/product-foundation.md +50 -0
- package/docs/testing-strategy.md +96 -0
- package/package.json +64 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_STUDIO_MESSAGES = void 0;
|
|
4
|
+
exports.loadStudioSession = loadStudioSession;
|
|
5
|
+
exports.loadStudioSessionState = loadStudioSessionState;
|
|
6
|
+
exports.saveStudioSession = saveStudioSession;
|
|
7
|
+
exports.loadStoredActiveAgentId = loadStoredActiveAgentId;
|
|
8
|
+
exports.saveStoredActiveAgentId = saveStoredActiveAgentId;
|
|
9
|
+
const workspace_1 = require("./workspace");
|
|
10
|
+
exports.DEFAULT_STUDIO_MESSAGES = [
|
|
11
|
+
{
|
|
12
|
+
role: "assistant",
|
|
13
|
+
content: "Describe what you are building, what is already true in the repo, or the next decision you need to make. I will help turn it into a disciplined `.srgical/` execution pack, and `/write` will update the repo files when you are ready."
|
|
14
|
+
}
|
|
15
|
+
];
|
|
16
|
+
async function loadStudioSession(workspaceRoot) {
|
|
17
|
+
return (await loadStudioSessionState(workspaceRoot)).messages;
|
|
18
|
+
}
|
|
19
|
+
async function loadStudioSessionState(workspaceRoot) {
|
|
20
|
+
const paths = (0, workspace_1.getPlanningPackPaths)(workspaceRoot);
|
|
21
|
+
const exists = await (0, workspace_1.fileExists)(paths.studioSession);
|
|
22
|
+
if (!exists) {
|
|
23
|
+
return createDefaultSessionState();
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const raw = await (0, workspace_1.readText)(paths.studioSession);
|
|
27
|
+
const parsed = JSON.parse(raw);
|
|
28
|
+
const messages = Array.isArray(parsed.messages) ? sanitizeMessages(parsed.messages) : [];
|
|
29
|
+
return {
|
|
30
|
+
messages: messages.length > 0 ? messages : cloneMessages(exports.DEFAULT_STUDIO_MESSAGES),
|
|
31
|
+
activeAgentId: sanitizeActiveAgentId(parsed.activeAgentId)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return createDefaultSessionState();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function saveStudioSession(workspaceRoot, messages) {
|
|
39
|
+
const currentState = await loadStudioSessionState(workspaceRoot);
|
|
40
|
+
await writeStudioSession(workspaceRoot, {
|
|
41
|
+
messages,
|
|
42
|
+
activeAgentId: currentState.activeAgentId
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function loadStoredActiveAgentId(workspaceRoot) {
|
|
46
|
+
return (await loadStudioSessionState(workspaceRoot)).activeAgentId;
|
|
47
|
+
}
|
|
48
|
+
async function saveStoredActiveAgentId(workspaceRoot, activeAgentId) {
|
|
49
|
+
const currentState = await loadStudioSessionState(workspaceRoot);
|
|
50
|
+
await writeStudioSession(workspaceRoot, {
|
|
51
|
+
messages: currentState.messages,
|
|
52
|
+
activeAgentId
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function writeStudioSession(workspaceRoot, state) {
|
|
56
|
+
const paths = await (0, workspace_1.ensurePlanningDir)(workspaceRoot);
|
|
57
|
+
const payload = {
|
|
58
|
+
version: 2,
|
|
59
|
+
updatedAt: new Date().toISOString(),
|
|
60
|
+
messages: sanitizeMessages(state.messages),
|
|
61
|
+
activeAgentId: sanitizeActiveAgentId(state.activeAgentId)
|
|
62
|
+
};
|
|
63
|
+
await (0, workspace_1.writeText)(paths.studioSession, JSON.stringify(payload, null, 2));
|
|
64
|
+
}
|
|
65
|
+
function sanitizeMessages(messages) {
|
|
66
|
+
return messages
|
|
67
|
+
.filter((message) => {
|
|
68
|
+
if (!message || typeof message !== "object") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return isRole(message.role) && typeof message.content === "string" && message.content.trim().length > 0;
|
|
72
|
+
})
|
|
73
|
+
.map((message) => ({
|
|
74
|
+
role: message.role,
|
|
75
|
+
content: message.content
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
function cloneMessages(messages) {
|
|
79
|
+
return messages.map((message) => ({
|
|
80
|
+
role: message.role,
|
|
81
|
+
content: message.content
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
function createDefaultSessionState() {
|
|
85
|
+
return {
|
|
86
|
+
messages: cloneMessages(exports.DEFAULT_STUDIO_MESSAGES),
|
|
87
|
+
activeAgentId: null
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function sanitizeActiveAgentId(value) {
|
|
91
|
+
if (typeof value !== "string") {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const normalized = value.trim().toLowerCase();
|
|
95
|
+
return normalized.length > 0 ? normalized : null;
|
|
96
|
+
}
|
|
97
|
+
function isRole(value) {
|
|
98
|
+
return value === "user" || value === "assistant" || value === "system";
|
|
99
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildPlanTemplate = buildPlanTemplate;
|
|
7
|
+
exports.buildContextTemplate = buildContextTemplate;
|
|
8
|
+
exports.buildTrackerTemplate = buildTrackerTemplate;
|
|
9
|
+
exports.buildNextPromptTemplate = buildNextPromptTemplate;
|
|
10
|
+
exports.getInitialTemplates = getInitialTemplates;
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
function projectNameFromRoot(root) {
|
|
13
|
+
return node_path_1.default.basename(root);
|
|
14
|
+
}
|
|
15
|
+
function buildPlanTemplate(root) {
|
|
16
|
+
const projectName = projectNameFromRoot(root);
|
|
17
|
+
return `# ${projectName} Product Plan
|
|
18
|
+
|
|
19
|
+
Updated: ${new Date().toISOString().slice(0, 10)}
|
|
20
|
+
|
|
21
|
+
## Purpose
|
|
22
|
+
|
|
23
|
+
This file is the stable high-level plan for the current project. It should capture the architecture direction, the
|
|
24
|
+
workflow shape, and the non-negotiable product rules that each execution slice must preserve.
|
|
25
|
+
|
|
26
|
+
## Mission
|
|
27
|
+
|
|
28
|
+
Define and ship a local-first CLI that helps a user:
|
|
29
|
+
|
|
30
|
+
1. plan a project with an AI inside a dedicated interface,
|
|
31
|
+
2. write a tracker pack into the repo,
|
|
32
|
+
3. execute the next eligible delivery slice with AI support,
|
|
33
|
+
4. keep progress incremental, validated, and resumable.
|
|
34
|
+
|
|
35
|
+
## Locked Decisions
|
|
36
|
+
|
|
37
|
+
- planning packs live under \`.srgical/\`
|
|
38
|
+
- the workflow remains markdown-first and repo-visible
|
|
39
|
+
- AI actions remain explicit and user-triggered
|
|
40
|
+
- execution should happen in small validated slices
|
|
41
|
+
- the interface should feel intentionally designed, not merely functional
|
|
42
|
+
|
|
43
|
+
## Primary Workflow To Optimize
|
|
44
|
+
|
|
45
|
+
1. open a studio
|
|
46
|
+
2. talk to the planner
|
|
47
|
+
3. trigger plan-pack generation
|
|
48
|
+
4. run the next eligible step block
|
|
49
|
+
5. review validation and continue
|
|
50
|
+
|
|
51
|
+
## Target End State
|
|
52
|
+
|
|
53
|
+
- the tool owns the planning ritual instead of relying on repeated prompt pastes
|
|
54
|
+
- the pack format stays readable by humans and agents
|
|
55
|
+
- agent execution can resume cleanly from repo state
|
|
56
|
+
- the UI feels like a sharp creative control room
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
function buildContextTemplate() {
|
|
60
|
+
return `# Agent Context Kickoff
|
|
61
|
+
|
|
62
|
+
Updated: ${new Date().toISOString()}
|
|
63
|
+
Updated By: srgical
|
|
64
|
+
|
|
65
|
+
## Mission
|
|
66
|
+
|
|
67
|
+
Continue the current project from the planning pack in \`.srgical/\`. Read the stable plan, the tracker, and the next
|
|
68
|
+
agent prompt before making changes.
|
|
69
|
+
|
|
70
|
+
## Working Agreements
|
|
71
|
+
|
|
72
|
+
- execute only the next eligible step or contiguous low-risk step block
|
|
73
|
+
- keep changes incremental and validated
|
|
74
|
+
- update the tracker and this handoff log after each completed block
|
|
75
|
+
- stop when a blocker changes scope materially
|
|
76
|
+
|
|
77
|
+
## Current Position
|
|
78
|
+
|
|
79
|
+
- Last Completed: \`BOOT-001\`
|
|
80
|
+
- Next Recommended: \`PLAN-001\`
|
|
81
|
+
- Updated At: \`${new Date().toISOString()}\`
|
|
82
|
+
- Updated By: \`srgical\`
|
|
83
|
+
|
|
84
|
+
## Handoff Log
|
|
85
|
+
|
|
86
|
+
### ${new Date().toISOString().slice(0, 10)} - BOOT-001 - srgical
|
|
87
|
+
|
|
88
|
+
- Created the initial \`.srgical/\` planning pack.
|
|
89
|
+
- Validation: confirmed the four planning-pack files were written.
|
|
90
|
+
- Blockers: none.
|
|
91
|
+
- Next recommended work: \`PLAN-001\`.
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
function buildTrackerTemplate() {
|
|
95
|
+
return `# Detailed Implementation Plan
|
|
96
|
+
|
|
97
|
+
Updated: ${new Date().toISOString()}
|
|
98
|
+
Updated By: srgical
|
|
99
|
+
|
|
100
|
+
## Status Legend
|
|
101
|
+
|
|
102
|
+
- \`pending\`: not started
|
|
103
|
+
- \`in_progress\`: currently being executed
|
|
104
|
+
- \`done\`: completed and validated
|
|
105
|
+
- \`blocked\`: cannot proceed without resolving a blocker
|
|
106
|
+
- \`skipped\`: intentionally skipped by an explicit design decision
|
|
107
|
+
|
|
108
|
+
## Current Position
|
|
109
|
+
|
|
110
|
+
- Last Completed: \`BOOT-001\`
|
|
111
|
+
- Next Recommended: \`PLAN-001\`
|
|
112
|
+
- Updated At: \`${new Date().toISOString()}\`
|
|
113
|
+
- Updated By: \`srgical\`
|
|
114
|
+
|
|
115
|
+
## Step Rules
|
|
116
|
+
|
|
117
|
+
- Work 1 to 2 contiguous steps only when they stay in the same subsystem and still fit comfortably in context.
|
|
118
|
+
- Do not mark a step \`done\` without recording validation notes.
|
|
119
|
+
- Update the current position and handoff log after each completed block.
|
|
120
|
+
- Stop immediately when a blocker changes scope materially.
|
|
121
|
+
|
|
122
|
+
## Bootstrap
|
|
123
|
+
|
|
124
|
+
| ID | Status | Depends On | Scope | Acceptance | Notes |
|
|
125
|
+
| --- | --- | --- | --- | --- | --- |
|
|
126
|
+
| BOOT-001 | done | - | Create the planning-pack scaffold. | The \`.srgical/\` pack exists. | Completed during \`srgical init\`. |
|
|
127
|
+
|
|
128
|
+
## Planning
|
|
129
|
+
|
|
130
|
+
| ID | Status | Depends On | Scope | Acceptance | Notes |
|
|
131
|
+
| --- | --- | --- | --- | --- | --- |
|
|
132
|
+
| PLAN-001 | pending | BOOT-001 | Convert the planning conversation into a stable product plan, kickoff log, tracker, and next-agent prompt. | The pack reflects the real project direction and is ready for execution. | Pending planner write. |
|
|
133
|
+
|
|
134
|
+
## Delivery
|
|
135
|
+
|
|
136
|
+
| ID | Status | Depends On | Scope | Acceptance | Notes |
|
|
137
|
+
| --- | --- | --- | --- | --- | --- |
|
|
138
|
+
| EXEC-001 | pending | PLAN-001 | Execute the next eligible implementation slice from the tracker. | The selected slice is complete, validated, and logged. | Pending tracker detail. |
|
|
139
|
+
`;
|
|
140
|
+
}
|
|
141
|
+
function buildNextPromptTemplate() {
|
|
142
|
+
return `# Next Agent Prompt
|
|
143
|
+
|
|
144
|
+
You are continuing the current project from the existing repo state. Do not restart product design or casually rewrite
|
|
145
|
+
the whole codebase.
|
|
146
|
+
|
|
147
|
+
## Read Order
|
|
148
|
+
|
|
149
|
+
1. Read \`.srgical/02-agent-context-kickoff.md\`.
|
|
150
|
+
2. Read \`.srgical/01-product-plan.md\`.
|
|
151
|
+
3. Read \`.srgical/03-detailed-implementation-plan.md\`.
|
|
152
|
+
4. Execute only the next eligible step block.
|
|
153
|
+
|
|
154
|
+
## What To Determine Before Editing
|
|
155
|
+
|
|
156
|
+
1. Identify \`Last Completed\` and \`Next Recommended\` in the tracker.
|
|
157
|
+
2. Confirm the next eligible step or contiguous low-risk step block.
|
|
158
|
+
3. Keep scope incremental and validation-aware.
|
|
159
|
+
|
|
160
|
+
## Execution Rules
|
|
161
|
+
|
|
162
|
+
1. Announce the chosen step ID or step IDs before making substantive edits.
|
|
163
|
+
2. Execute the step block end-to-end.
|
|
164
|
+
3. Preserve the locked product decisions from the plan.
|
|
165
|
+
4. Run validation appropriate to the step block.
|
|
166
|
+
5. Update the tracker and kickoff log when the block is complete.
|
|
167
|
+
|
|
168
|
+
## Required Updates After Execution
|
|
169
|
+
|
|
170
|
+
1. Update \`.srgical/03-detailed-implementation-plan.md\`.
|
|
171
|
+
2. Mark finished steps \`done\` only if validation passed.
|
|
172
|
+
3. Update the \`Current Position\` section.
|
|
173
|
+
4. Append a dated handoff entry to \`.srgical/02-agent-context-kickoff.md\`.
|
|
174
|
+
|
|
175
|
+
## Stop Conditions
|
|
176
|
+
|
|
177
|
+
- Stop after finishing the chosen step block.
|
|
178
|
+
- Stop before broadening into a different subsystem unless the tracker explicitly calls for it.
|
|
179
|
+
- Stop and record a blocker if new architecture work is required.
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
function getInitialTemplates(paths) {
|
|
183
|
+
return {
|
|
184
|
+
[paths.plan]: buildPlanTemplate(paths.root),
|
|
185
|
+
[paths.context]: buildContextTemplate(),
|
|
186
|
+
[paths.tracker]: buildTrackerTemplate(),
|
|
187
|
+
[paths.nextPrompt]: buildNextPromptTemplate()
|
|
188
|
+
};
|
|
189
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PLAN_DIR = void 0;
|
|
7
|
+
exports.resolveWorkspace = resolveWorkspace;
|
|
8
|
+
exports.getPlanningPackPaths = getPlanningPackPaths;
|
|
9
|
+
exports.ensurePlanningDir = ensurePlanningDir;
|
|
10
|
+
exports.fileExists = fileExists;
|
|
11
|
+
exports.planningPackExists = planningPackExists;
|
|
12
|
+
exports.readText = readText;
|
|
13
|
+
exports.writeText = writeText;
|
|
14
|
+
exports.isGitRepo = isGitRepo;
|
|
15
|
+
const promises_1 = require("node:fs/promises");
|
|
16
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
+
exports.PLAN_DIR = ".srgical";
|
|
18
|
+
function resolveWorkspace(input) {
|
|
19
|
+
return node_path_1.default.resolve(input ?? process.cwd());
|
|
20
|
+
}
|
|
21
|
+
function getPlanningPackPaths(root) {
|
|
22
|
+
const dir = node_path_1.default.join(root, exports.PLAN_DIR);
|
|
23
|
+
return {
|
|
24
|
+
root,
|
|
25
|
+
dir,
|
|
26
|
+
plan: node_path_1.default.join(dir, "01-product-plan.md"),
|
|
27
|
+
context: node_path_1.default.join(dir, "02-agent-context-kickoff.md"),
|
|
28
|
+
tracker: node_path_1.default.join(dir, "03-detailed-implementation-plan.md"),
|
|
29
|
+
nextPrompt: node_path_1.default.join(dir, "04-next-agent-prompt.md"),
|
|
30
|
+
studioSession: node_path_1.default.join(dir, "studio-session.json"),
|
|
31
|
+
executionState: node_path_1.default.join(dir, "execution-state.json"),
|
|
32
|
+
executionLog: node_path_1.default.join(dir, "execution-log.md")
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async function ensurePlanningDir(root) {
|
|
36
|
+
const paths = getPlanningPackPaths(root);
|
|
37
|
+
await (0, promises_1.mkdir)(paths.dir, { recursive: true });
|
|
38
|
+
return paths;
|
|
39
|
+
}
|
|
40
|
+
async function fileExists(filePath) {
|
|
41
|
+
try {
|
|
42
|
+
await (0, promises_1.access)(filePath);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function planningPackExists(root) {
|
|
50
|
+
const paths = getPlanningPackPaths(root);
|
|
51
|
+
const checks = await Promise.all([
|
|
52
|
+
fileExists(paths.plan),
|
|
53
|
+
fileExists(paths.context),
|
|
54
|
+
fileExists(paths.tracker),
|
|
55
|
+
fileExists(paths.nextPrompt)
|
|
56
|
+
]);
|
|
57
|
+
return checks.every(Boolean);
|
|
58
|
+
}
|
|
59
|
+
async function readText(filePath) {
|
|
60
|
+
return (0, promises_1.readFile)(filePath, "utf8");
|
|
61
|
+
}
|
|
62
|
+
async function writeText(filePath, content) {
|
|
63
|
+
await (0, promises_1.writeFile)(filePath, content, "utf8");
|
|
64
|
+
}
|
|
65
|
+
async function isGitRepo(root) {
|
|
66
|
+
return fileExists(node_path_1.default.join(root, ".git"));
|
|
67
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const commander_1 = require("commander");
|
|
10
|
+
const doctor_1 = require("./commands/doctor");
|
|
11
|
+
const init_1 = require("./commands/init");
|
|
12
|
+
const run_next_1 = require("./commands/run-next");
|
|
13
|
+
const studio_1 = require("./commands/studio");
|
|
14
|
+
const program = new commander_1.Command();
|
|
15
|
+
const packageVersion = readPackageVersion();
|
|
16
|
+
program
|
|
17
|
+
.name("srgical")
|
|
18
|
+
.description("Local-first AI planning and execution orchestration.")
|
|
19
|
+
.version(packageVersion);
|
|
20
|
+
program
|
|
21
|
+
.command("doctor")
|
|
22
|
+
.description("Inspect the workspace and local agent availability.")
|
|
23
|
+
.argument("[workspace]", "Workspace path")
|
|
24
|
+
.action(async (workspace) => {
|
|
25
|
+
await (0, doctor_1.runDoctorCommand)(workspace);
|
|
26
|
+
});
|
|
27
|
+
program
|
|
28
|
+
.command("init")
|
|
29
|
+
.description("Create a local .srgical planning pack scaffold.")
|
|
30
|
+
.argument("[workspace]", "Workspace path")
|
|
31
|
+
.option("-f, --force", "Overwrite an existing planning pack")
|
|
32
|
+
.action(async (workspace, options) => {
|
|
33
|
+
await (0, init_1.runInitCommand)(workspace, Boolean(options.force));
|
|
34
|
+
});
|
|
35
|
+
program
|
|
36
|
+
.command("studio")
|
|
37
|
+
.description("Open the planning studio.")
|
|
38
|
+
.argument("[workspace]", "Workspace path")
|
|
39
|
+
.action(async (workspace) => {
|
|
40
|
+
await (0, studio_1.runStudioCommand)(workspace);
|
|
41
|
+
});
|
|
42
|
+
program
|
|
43
|
+
.command("run-next")
|
|
44
|
+
.description("Run the current next-agent prompt through the active agent adapter.")
|
|
45
|
+
.argument("[workspace]", "Workspace path")
|
|
46
|
+
.option("--dry-run", "Preview the current execution prompt without invoking the active agent")
|
|
47
|
+
.option("--agent <id>", "Temporarily override the active agent for this run only")
|
|
48
|
+
.action(async (workspace, options) => {
|
|
49
|
+
await (0, run_next_1.runRunNextCommand)(workspace, { dryRun: Boolean(options.dryRun), agent: options.agent });
|
|
50
|
+
});
|
|
51
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
52
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
53
|
+
process.stderr.write(`${message}\n`);
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
});
|
|
56
|
+
function readPackageVersion() {
|
|
57
|
+
const packageJsonPath = node_path_1.default.resolve(__dirname, "..", "package.json");
|
|
58
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, "utf8"));
|
|
59
|
+
return packageJson.version ?? "0.0.0";
|
|
60
|
+
}
|