ralphctl 0.1.0 → 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.
- package/README.md +58 -24
- package/dist/add-HGJCLWED.mjs +14 -0
- package/dist/add-MRGCS3US.mjs +14 -0
- package/dist/chunk-6PYTKGB5.mjs +316 -0
- package/dist/chunk-7TG3EAQ2.mjs +20 -0
- package/dist/chunk-EKMZZRWI.mjs +521 -0
- package/dist/chunk-JON4GCLR.mjs +59 -0
- package/dist/chunk-LOR7QBXX.mjs +3683 -0
- package/dist/chunk-MNMQC36F.mjs +556 -0
- package/dist/chunk-MRKOFVTM.mjs +537 -0
- package/dist/chunk-NTWO2LXB.mjs +52 -0
- package/dist/chunk-QBXHAXHI.mjs +562 -0
- package/dist/chunk-WGHJI3OI.mjs +214 -0
- package/dist/cli.mjs +4245 -0
- package/dist/create-MG7E7PLQ.mjs +10 -0
- package/dist/handle-UG5M2OON.mjs +22 -0
- package/dist/multiline-OHSNFCRG.mjs +40 -0
- package/dist/project-NT3L4FTB.mjs +28 -0
- package/dist/resolver-WSFWKACM.mjs +153 -0
- package/dist/sprint-4VHDLGFN.mjs +37 -0
- package/dist/wizard-LRELAN2J.mjs +196 -0
- package/package.json +19 -28
- package/CHANGELOG.md +0 -94
- package/bin/ralphctl +0 -13
- package/src/ai/executor.ts +0 -973
- package/src/ai/lifecycle.ts +0 -45
- package/src/ai/parser.ts +0 -40
- package/src/ai/permissions.ts +0 -207
- package/src/ai/process-manager.ts +0 -248
- package/src/ai/prompts/index.ts +0 -89
- package/src/ai/rate-limiter.ts +0 -89
- package/src/ai/runner.ts +0 -478
- package/src/ai/session.ts +0 -319
- package/src/ai/task-context.ts +0 -270
- package/src/cli-metadata.ts +0 -7
- package/src/cli.ts +0 -65
- package/src/commands/completion/index.ts +0 -33
- package/src/commands/config/config.ts +0 -58
- package/src/commands/config/index.ts +0 -33
- package/src/commands/dashboard/dashboard.ts +0 -5
- package/src/commands/dashboard/index.ts +0 -6
- package/src/commands/doctor/doctor.ts +0 -271
- package/src/commands/doctor/index.ts +0 -25
- package/src/commands/progress/index.ts +0 -25
- package/src/commands/progress/log.ts +0 -64
- package/src/commands/progress/show.ts +0 -14
- package/src/commands/project/add.ts +0 -336
- package/src/commands/project/index.ts +0 -104
- package/src/commands/project/list.ts +0 -31
- package/src/commands/project/remove.ts +0 -43
- package/src/commands/project/repo.ts +0 -118
- package/src/commands/project/show.ts +0 -49
- package/src/commands/sprint/close.ts +0 -180
- package/src/commands/sprint/context.ts +0 -109
- package/src/commands/sprint/create.ts +0 -60
- package/src/commands/sprint/current.ts +0 -75
- package/src/commands/sprint/delete.ts +0 -72
- package/src/commands/sprint/health.ts +0 -229
- package/src/commands/sprint/ideate.ts +0 -496
- package/src/commands/sprint/index.ts +0 -226
- package/src/commands/sprint/list.ts +0 -86
- package/src/commands/sprint/plan-utils.ts +0 -207
- package/src/commands/sprint/plan.ts +0 -549
- package/src/commands/sprint/refine.ts +0 -359
- package/src/commands/sprint/requirements.ts +0 -58
- package/src/commands/sprint/show.ts +0 -140
- package/src/commands/sprint/start.ts +0 -119
- package/src/commands/sprint/switch.ts +0 -20
- package/src/commands/task/add.ts +0 -316
- package/src/commands/task/import.ts +0 -150
- package/src/commands/task/index.ts +0 -123
- package/src/commands/task/list.ts +0 -145
- package/src/commands/task/next.ts +0 -45
- package/src/commands/task/remove.ts +0 -47
- package/src/commands/task/reorder.ts +0 -45
- package/src/commands/task/show.ts +0 -111
- package/src/commands/task/status.ts +0 -99
- package/src/commands/ticket/add.ts +0 -265
- package/src/commands/ticket/edit.ts +0 -166
- package/src/commands/ticket/index.ts +0 -114
- package/src/commands/ticket/list.ts +0 -128
- package/src/commands/ticket/refine-utils.ts +0 -89
- package/src/commands/ticket/refine.ts +0 -268
- package/src/commands/ticket/remove.ts +0 -48
- package/src/commands/ticket/show.ts +0 -74
- package/src/completion/handle.ts +0 -30
- package/src/completion/resolver.ts +0 -241
- package/src/interactive/dashboard.ts +0 -268
- package/src/interactive/escapable.ts +0 -81
- package/src/interactive/file-browser.ts +0 -153
- package/src/interactive/index.ts +0 -429
- package/src/interactive/menu.ts +0 -403
- package/src/interactive/selectors.ts +0 -273
- package/src/interactive/wizard.ts +0 -221
- package/src/providers/claude.ts +0 -53
- package/src/providers/copilot.ts +0 -86
- package/src/providers/index.ts +0 -43
- package/src/providers/types.ts +0 -85
- package/src/schemas/index.ts +0 -130
- package/src/store/config.ts +0 -74
- package/src/store/progress.ts +0 -230
- package/src/store/project.ts +0 -276
- package/src/store/sprint.ts +0 -229
- package/src/store/task.ts +0 -443
- package/src/store/ticket.ts +0 -178
- package/src/theme/index.ts +0 -215
- package/src/theme/ui.ts +0 -872
- package/src/utils/detect-scripts.ts +0 -247
- package/src/utils/editor-input.ts +0 -41
- package/src/utils/editor.ts +0 -37
- package/src/utils/exit-codes.ts +0 -27
- package/src/utils/file-lock.ts +0 -135
- package/src/utils/git.ts +0 -185
- package/src/utils/ids.ts +0 -37
- package/src/utils/issue-fetch.ts +0 -244
- package/src/utils/json-extract.ts +0 -62
- package/src/utils/multiline.ts +0 -61
- package/src/utils/path-selector.ts +0 -236
- package/src/utils/paths.ts +0 -108
- package/src/utils/provider.ts +0 -34
- package/src/utils/requirements-export.ts +0 -63
- package/src/utils/storage.ts +0 -107
- package/tsconfig.json +0 -25
- /package/{src/ai → dist}/prompts/ideate-auto.md +0 -0
- /package/{src/ai → dist}/prompts/ideate.md +0 -0
- /package/{src/ai → dist}/prompts/plan-auto.md +0 -0
- /package/{src/ai → dist}/prompts/plan-common.md +0 -0
- /package/{src/ai → dist}/prompts/plan-interactive.md +0 -0
- /package/{src/ai → dist}/prompts/task-execution.md +0 -0
- /package/{src/ai → dist}/prompts/ticket-refine.md +0 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ProjectsSchema,
|
|
4
|
+
expandTilde,
|
|
5
|
+
fileExists,
|
|
6
|
+
getProjectsFilePath,
|
|
7
|
+
readValidatedJson,
|
|
8
|
+
validateProjectPath,
|
|
9
|
+
writeValidatedJson
|
|
10
|
+
} from "./chunk-6PYTKGB5.mjs";
|
|
11
|
+
|
|
12
|
+
// src/store/project.ts
|
|
13
|
+
import { basename, resolve } from "path";
|
|
14
|
+
var ProjectNotFoundError = class extends Error {
|
|
15
|
+
projectName;
|
|
16
|
+
constructor(projectName) {
|
|
17
|
+
super(`Project not found: ${projectName}`);
|
|
18
|
+
this.name = "ProjectNotFoundError";
|
|
19
|
+
this.projectName = projectName;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var ProjectExistsError = class extends Error {
|
|
23
|
+
projectName;
|
|
24
|
+
constructor(projectName) {
|
|
25
|
+
super(`Project already exists: ${projectName}`);
|
|
26
|
+
this.name = "ProjectExistsError";
|
|
27
|
+
this.projectName = projectName;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
function migrateProjectIfNeeded(project) {
|
|
31
|
+
if (project.repositories) {
|
|
32
|
+
return project;
|
|
33
|
+
}
|
|
34
|
+
if (project.paths) {
|
|
35
|
+
return {
|
|
36
|
+
name: project.name,
|
|
37
|
+
displayName: project.displayName,
|
|
38
|
+
repositories: project.paths.map((p) => ({
|
|
39
|
+
name: basename(p),
|
|
40
|
+
path: resolve(expandTilde(p))
|
|
41
|
+
})),
|
|
42
|
+
description: project.description
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`Invalid project data: no paths or repositories for ${project.name}`);
|
|
46
|
+
}
|
|
47
|
+
async function listProjects() {
|
|
48
|
+
const filePath = getProjectsFilePath();
|
|
49
|
+
if (!await fileExists(filePath)) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const { readFile } = await import("fs/promises");
|
|
53
|
+
const content = await readFile(filePath, "utf-8");
|
|
54
|
+
const rawData = JSON.parse(content);
|
|
55
|
+
const needsMigration = rawData.some((p) => p.paths && !p.repositories);
|
|
56
|
+
if (needsMigration) {
|
|
57
|
+
const migrated = rawData.map(migrateProjectIfNeeded);
|
|
58
|
+
const validated = ProjectsSchema.parse(migrated);
|
|
59
|
+
await writeValidatedJson(filePath, validated, ProjectsSchema);
|
|
60
|
+
return validated;
|
|
61
|
+
}
|
|
62
|
+
const projects = await readValidatedJson(filePath, ProjectsSchema);
|
|
63
|
+
const hasTildePaths = projects.some((p) => p.repositories.some((r) => r.path.startsWith("~")));
|
|
64
|
+
if (hasTildePaths) {
|
|
65
|
+
const corrected = projects.map((project) => ({
|
|
66
|
+
...project,
|
|
67
|
+
repositories: project.repositories.map(
|
|
68
|
+
(repo) => repo.path.startsWith("~") ? { ...repo, path: resolve(expandTilde(repo.path)) } : repo
|
|
69
|
+
)
|
|
70
|
+
}));
|
|
71
|
+
const validated = ProjectsSchema.parse(corrected);
|
|
72
|
+
await writeValidatedJson(filePath, validated, ProjectsSchema);
|
|
73
|
+
return validated;
|
|
74
|
+
}
|
|
75
|
+
return projects;
|
|
76
|
+
}
|
|
77
|
+
async function getProject(name) {
|
|
78
|
+
const projects = await listProjects();
|
|
79
|
+
const project = projects.find((p) => p.name === name);
|
|
80
|
+
if (!project) {
|
|
81
|
+
throw new ProjectNotFoundError(name);
|
|
82
|
+
}
|
|
83
|
+
return project;
|
|
84
|
+
}
|
|
85
|
+
async function projectExists(name) {
|
|
86
|
+
const projects = await listProjects();
|
|
87
|
+
return projects.some((p) => p.name === name);
|
|
88
|
+
}
|
|
89
|
+
async function createProject(project) {
|
|
90
|
+
const projects = await listProjects();
|
|
91
|
+
if (projects.some((p) => p.name === project.name)) {
|
|
92
|
+
throw new ProjectExistsError(project.name);
|
|
93
|
+
}
|
|
94
|
+
const pathErrors = [];
|
|
95
|
+
for (const repo of project.repositories) {
|
|
96
|
+
const resolved = resolve(expandTilde(repo.path));
|
|
97
|
+
const validation = await validateProjectPath(resolved);
|
|
98
|
+
if (validation !== true) {
|
|
99
|
+
pathErrors.push(` ${repo.path}: ${validation}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (pathErrors.length > 0) {
|
|
103
|
+
throw new Error(`Invalid project paths:
|
|
104
|
+
${pathErrors.join("\n")}`);
|
|
105
|
+
}
|
|
106
|
+
const normalizedProject = {
|
|
107
|
+
...project,
|
|
108
|
+
repositories: project.repositories.map((repo) => ({
|
|
109
|
+
...repo,
|
|
110
|
+
name: repo.name || basename(repo.path),
|
|
111
|
+
path: resolve(expandTilde(repo.path))
|
|
112
|
+
}))
|
|
113
|
+
};
|
|
114
|
+
projects.push(normalizedProject);
|
|
115
|
+
await writeValidatedJson(getProjectsFilePath(), projects, ProjectsSchema);
|
|
116
|
+
return normalizedProject;
|
|
117
|
+
}
|
|
118
|
+
async function updateProject(name, updates) {
|
|
119
|
+
const projects = await listProjects();
|
|
120
|
+
const index = projects.findIndex((p) => p.name === name);
|
|
121
|
+
if (index === -1) {
|
|
122
|
+
throw new ProjectNotFoundError(name);
|
|
123
|
+
}
|
|
124
|
+
if (updates.repositories) {
|
|
125
|
+
const pathErrors = [];
|
|
126
|
+
for (const repo of updates.repositories) {
|
|
127
|
+
const resolved = resolve(expandTilde(repo.path));
|
|
128
|
+
const validation = await validateProjectPath(resolved);
|
|
129
|
+
if (validation !== true) {
|
|
130
|
+
pathErrors.push(` ${repo.path}: ${validation}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (pathErrors.length > 0) {
|
|
134
|
+
throw new Error(`Invalid project paths:
|
|
135
|
+
${pathErrors.join("\n")}`);
|
|
136
|
+
}
|
|
137
|
+
updates.repositories = updates.repositories.map((repo) => ({
|
|
138
|
+
...repo,
|
|
139
|
+
name: repo.name || basename(repo.path),
|
|
140
|
+
path: resolve(expandTilde(repo.path))
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
const existingProject = projects[index];
|
|
144
|
+
if (!existingProject) {
|
|
145
|
+
throw new ProjectNotFoundError(name);
|
|
146
|
+
}
|
|
147
|
+
const updatedProject = {
|
|
148
|
+
name: existingProject.name,
|
|
149
|
+
displayName: updates.displayName ?? existingProject.displayName,
|
|
150
|
+
repositories: updates.repositories ?? existingProject.repositories,
|
|
151
|
+
description: updates.description ?? existingProject.description
|
|
152
|
+
};
|
|
153
|
+
projects[index] = updatedProject;
|
|
154
|
+
await writeValidatedJson(getProjectsFilePath(), projects, ProjectsSchema);
|
|
155
|
+
return updatedProject;
|
|
156
|
+
}
|
|
157
|
+
async function removeProject(name) {
|
|
158
|
+
const projects = await listProjects();
|
|
159
|
+
const index = projects.findIndex((p) => p.name === name);
|
|
160
|
+
if (index === -1) {
|
|
161
|
+
throw new ProjectNotFoundError(name);
|
|
162
|
+
}
|
|
163
|
+
projects.splice(index, 1);
|
|
164
|
+
await writeValidatedJson(getProjectsFilePath(), projects, ProjectsSchema);
|
|
165
|
+
}
|
|
166
|
+
async function getProjectRepos(name) {
|
|
167
|
+
const project = await getProject(name);
|
|
168
|
+
return project.repositories;
|
|
169
|
+
}
|
|
170
|
+
async function addProjectRepo(name, repo) {
|
|
171
|
+
const project = await getProject(name);
|
|
172
|
+
const resolvedPath = resolve(expandTilde(repo.path));
|
|
173
|
+
const validation = await validateProjectPath(resolvedPath);
|
|
174
|
+
if (validation !== true) {
|
|
175
|
+
throw new Error(`Invalid path ${repo.path}: ${validation}`);
|
|
176
|
+
}
|
|
177
|
+
if (project.repositories.some((r) => r.path === resolvedPath)) {
|
|
178
|
+
return project;
|
|
179
|
+
}
|
|
180
|
+
const normalizedRepo = {
|
|
181
|
+
...repo,
|
|
182
|
+
name: repo.name || basename(resolvedPath),
|
|
183
|
+
path: resolvedPath
|
|
184
|
+
};
|
|
185
|
+
return updateProject(name, {
|
|
186
|
+
repositories: [...project.repositories, normalizedRepo]
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
async function removeProjectRepo(name, path) {
|
|
190
|
+
const project = await getProject(name);
|
|
191
|
+
const resolvedPath = resolve(expandTilde(path));
|
|
192
|
+
const newRepos = project.repositories.filter((r) => r.path !== resolvedPath);
|
|
193
|
+
if (newRepos.length === 0) {
|
|
194
|
+
throw new Error("Cannot remove the last repository from a project");
|
|
195
|
+
}
|
|
196
|
+
if (newRepos.length === project.repositories.length) {
|
|
197
|
+
return project;
|
|
198
|
+
}
|
|
199
|
+
return updateProject(name, { repositories: newRepos });
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export {
|
|
203
|
+
ProjectNotFoundError,
|
|
204
|
+
ProjectExistsError,
|
|
205
|
+
listProjects,
|
|
206
|
+
getProject,
|
|
207
|
+
projectExists,
|
|
208
|
+
createProject,
|
|
209
|
+
updateProject,
|
|
210
|
+
removeProject,
|
|
211
|
+
getProjectRepos,
|
|
212
|
+
addProjectRepo,
|
|
213
|
+
removeProjectRepo
|
|
214
|
+
};
|