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.
Files changed (130) hide show
  1. package/README.md +58 -24
  2. package/dist/add-HGJCLWED.mjs +14 -0
  3. package/dist/add-MRGCS3US.mjs +14 -0
  4. package/dist/chunk-6PYTKGB5.mjs +316 -0
  5. package/dist/chunk-7TG3EAQ2.mjs +20 -0
  6. package/dist/chunk-EKMZZRWI.mjs +521 -0
  7. package/dist/chunk-JON4GCLR.mjs +59 -0
  8. package/dist/chunk-LOR7QBXX.mjs +3683 -0
  9. package/dist/chunk-MNMQC36F.mjs +556 -0
  10. package/dist/chunk-MRKOFVTM.mjs +537 -0
  11. package/dist/chunk-NTWO2LXB.mjs +52 -0
  12. package/dist/chunk-QBXHAXHI.mjs +562 -0
  13. package/dist/chunk-WGHJI3OI.mjs +214 -0
  14. package/dist/cli.mjs +4245 -0
  15. package/dist/create-MG7E7PLQ.mjs +10 -0
  16. package/dist/handle-UG5M2OON.mjs +22 -0
  17. package/dist/multiline-OHSNFCRG.mjs +40 -0
  18. package/dist/project-NT3L4FTB.mjs +28 -0
  19. package/dist/resolver-WSFWKACM.mjs +153 -0
  20. package/dist/sprint-4VHDLGFN.mjs +37 -0
  21. package/dist/wizard-LRELAN2J.mjs +196 -0
  22. package/package.json +19 -28
  23. package/CHANGELOG.md +0 -94
  24. package/bin/ralphctl +0 -13
  25. package/src/ai/executor.ts +0 -973
  26. package/src/ai/lifecycle.ts +0 -45
  27. package/src/ai/parser.ts +0 -40
  28. package/src/ai/permissions.ts +0 -207
  29. package/src/ai/process-manager.ts +0 -248
  30. package/src/ai/prompts/index.ts +0 -89
  31. package/src/ai/rate-limiter.ts +0 -89
  32. package/src/ai/runner.ts +0 -478
  33. package/src/ai/session.ts +0 -319
  34. package/src/ai/task-context.ts +0 -270
  35. package/src/cli-metadata.ts +0 -7
  36. package/src/cli.ts +0 -65
  37. package/src/commands/completion/index.ts +0 -33
  38. package/src/commands/config/config.ts +0 -58
  39. package/src/commands/config/index.ts +0 -33
  40. package/src/commands/dashboard/dashboard.ts +0 -5
  41. package/src/commands/dashboard/index.ts +0 -6
  42. package/src/commands/doctor/doctor.ts +0 -271
  43. package/src/commands/doctor/index.ts +0 -25
  44. package/src/commands/progress/index.ts +0 -25
  45. package/src/commands/progress/log.ts +0 -64
  46. package/src/commands/progress/show.ts +0 -14
  47. package/src/commands/project/add.ts +0 -336
  48. package/src/commands/project/index.ts +0 -104
  49. package/src/commands/project/list.ts +0 -31
  50. package/src/commands/project/remove.ts +0 -43
  51. package/src/commands/project/repo.ts +0 -118
  52. package/src/commands/project/show.ts +0 -49
  53. package/src/commands/sprint/close.ts +0 -180
  54. package/src/commands/sprint/context.ts +0 -109
  55. package/src/commands/sprint/create.ts +0 -60
  56. package/src/commands/sprint/current.ts +0 -75
  57. package/src/commands/sprint/delete.ts +0 -72
  58. package/src/commands/sprint/health.ts +0 -229
  59. package/src/commands/sprint/ideate.ts +0 -496
  60. package/src/commands/sprint/index.ts +0 -226
  61. package/src/commands/sprint/list.ts +0 -86
  62. package/src/commands/sprint/plan-utils.ts +0 -207
  63. package/src/commands/sprint/plan.ts +0 -549
  64. package/src/commands/sprint/refine.ts +0 -359
  65. package/src/commands/sprint/requirements.ts +0 -58
  66. package/src/commands/sprint/show.ts +0 -140
  67. package/src/commands/sprint/start.ts +0 -119
  68. package/src/commands/sprint/switch.ts +0 -20
  69. package/src/commands/task/add.ts +0 -316
  70. package/src/commands/task/import.ts +0 -150
  71. package/src/commands/task/index.ts +0 -123
  72. package/src/commands/task/list.ts +0 -145
  73. package/src/commands/task/next.ts +0 -45
  74. package/src/commands/task/remove.ts +0 -47
  75. package/src/commands/task/reorder.ts +0 -45
  76. package/src/commands/task/show.ts +0 -111
  77. package/src/commands/task/status.ts +0 -99
  78. package/src/commands/ticket/add.ts +0 -265
  79. package/src/commands/ticket/edit.ts +0 -166
  80. package/src/commands/ticket/index.ts +0 -114
  81. package/src/commands/ticket/list.ts +0 -128
  82. package/src/commands/ticket/refine-utils.ts +0 -89
  83. package/src/commands/ticket/refine.ts +0 -268
  84. package/src/commands/ticket/remove.ts +0 -48
  85. package/src/commands/ticket/show.ts +0 -74
  86. package/src/completion/handle.ts +0 -30
  87. package/src/completion/resolver.ts +0 -241
  88. package/src/interactive/dashboard.ts +0 -268
  89. package/src/interactive/escapable.ts +0 -81
  90. package/src/interactive/file-browser.ts +0 -153
  91. package/src/interactive/index.ts +0 -429
  92. package/src/interactive/menu.ts +0 -403
  93. package/src/interactive/selectors.ts +0 -273
  94. package/src/interactive/wizard.ts +0 -221
  95. package/src/providers/claude.ts +0 -53
  96. package/src/providers/copilot.ts +0 -86
  97. package/src/providers/index.ts +0 -43
  98. package/src/providers/types.ts +0 -85
  99. package/src/schemas/index.ts +0 -130
  100. package/src/store/config.ts +0 -74
  101. package/src/store/progress.ts +0 -230
  102. package/src/store/project.ts +0 -276
  103. package/src/store/sprint.ts +0 -229
  104. package/src/store/task.ts +0 -443
  105. package/src/store/ticket.ts +0 -178
  106. package/src/theme/index.ts +0 -215
  107. package/src/theme/ui.ts +0 -872
  108. package/src/utils/detect-scripts.ts +0 -247
  109. package/src/utils/editor-input.ts +0 -41
  110. package/src/utils/editor.ts +0 -37
  111. package/src/utils/exit-codes.ts +0 -27
  112. package/src/utils/file-lock.ts +0 -135
  113. package/src/utils/git.ts +0 -185
  114. package/src/utils/ids.ts +0 -37
  115. package/src/utils/issue-fetch.ts +0 -244
  116. package/src/utils/json-extract.ts +0 -62
  117. package/src/utils/multiline.ts +0 -61
  118. package/src/utils/path-selector.ts +0 -236
  119. package/src/utils/paths.ts +0 -108
  120. package/src/utils/provider.ts +0 -34
  121. package/src/utils/requirements-export.ts +0 -63
  122. package/src/utils/storage.ts +0 -107
  123. package/tsconfig.json +0 -25
  124. /package/{src/ai → dist}/prompts/ideate-auto.md +0 -0
  125. /package/{src/ai → dist}/prompts/ideate.md +0 -0
  126. /package/{src/ai → dist}/prompts/plan-auto.md +0 -0
  127. /package/{src/ai → dist}/prompts/plan-common.md +0 -0
  128. /package/{src/ai → dist}/prompts/plan-interactive.md +0 -0
  129. /package/{src/ai → dist}/prompts/task-execution.md +0 -0
  130. /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
+ };