@spekn/cli 1.0.0 → 1.0.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 (154) hide show
  1. package/README.md +58 -0
  2. package/dist/main.js +40540 -32176
  3. package/dist/prompts/governance-analysis.prompt.md +109 -0
  4. package/dist/resources/prompts/repo-analysis.prompt.md +28 -136
  5. package/dist/resources/prompts/repo-sync-analysis.prompt.md +31 -68
  6. package/dist/tui/chunk-4WEASLXY.mjs +3444 -0
  7. package/dist/tui/chunk-755CADEG.mjs +3401 -0
  8. package/dist/tui/chunk-BUJQVTY5.mjs +3409 -0
  9. package/dist/tui/chunk-BZKKMGFB.mjs +1959 -0
  10. package/dist/tui/chunk-DJYOBCNM.mjs +3159 -0
  11. package/dist/tui/chunk-GTFTFDY4.mjs +3417 -0
  12. package/dist/tui/chunk-IMEBD2KA.mjs +3444 -0
  13. package/dist/tui/chunk-IX6DR5SW.mjs +3433 -0
  14. package/dist/tui/chunk-JKFOY4IF.mjs +2003 -0
  15. package/dist/tui/chunk-OXXZ3O5L.mjs +3378 -0
  16. package/dist/tui/chunk-SHJNIAAJ.mjs +1697 -0
  17. package/dist/tui/chunk-V4SNDRUS.mjs +1666 -0
  18. package/dist/tui/chunk-VXVHNZST.mjs +1666 -0
  19. package/dist/tui/chunk-WCTSFKTA.mjs +3459 -0
  20. package/dist/tui/chunk-X2XP5ACW.mjs +3443 -0
  21. package/dist/tui/chunk-YUYJ7VBG.mjs +2029 -0
  22. package/dist/tui/chunk-ZM3EI5IA.mjs +3384 -0
  23. package/dist/tui/chunk-ZYOX64HP.mjs +1653 -0
  24. package/dist/tui/index.mjs +6999 -6938
  25. package/dist/tui/prompts/spec-creation-system.prompt.md +47 -0
  26. package/dist/tui/prompts/spec-refinement-system.prompt.md +72 -0
  27. package/dist/tui/use-session-store-63YUGUFA.mjs +8 -0
  28. package/dist/tui/use-session-store-ACO2SMJC.mjs +8 -0
  29. package/dist/tui/use-session-store-BVFDAWOB.mjs +8 -0
  30. package/dist/tui/use-session-store-DJIZ3FQZ.mjs +9 -0
  31. package/dist/tui/use-session-store-EAIQA4UG.mjs +9 -0
  32. package/dist/tui/use-session-store-EFBAXC3G.mjs +8 -0
  33. package/dist/tui/use-session-store-FJOR4KTG.mjs +8 -0
  34. package/dist/tui/use-session-store-IJE5KVOC.mjs +8 -0
  35. package/dist/tui/use-session-store-KGAFXCKI.mjs +8 -0
  36. package/dist/tui/use-session-store-KS4DPNDY.mjs +8 -0
  37. package/dist/tui/use-session-store-MMHJENNL.mjs +8 -0
  38. package/dist/tui/use-session-store-OZ6HC4I2.mjs +9 -0
  39. package/dist/tui/use-session-store-PTMWISNJ.mjs +8 -0
  40. package/dist/tui/use-session-store-VCDECQMW.mjs +8 -0
  41. package/dist/tui/use-session-store-VOK5ML5J.mjs +9 -0
  42. package/package.json +33 -13
  43. package/dist/__tests__/export-cli.test.d.ts +0 -1
  44. package/dist/__tests__/export-cli.test.js +0 -70
  45. package/dist/__tests__/tui-args-policy.test.d.ts +0 -1
  46. package/dist/__tests__/tui-args-policy.test.js +0 -50
  47. package/dist/acp-S2MHZOAD.mjs +0 -23
  48. package/dist/acp-UCCI44JY.mjs +0 -25
  49. package/dist/auth/credentials-store.d.ts +0 -2
  50. package/dist/auth/credentials-store.js +0 -5
  51. package/dist/auth/device-flow.d.ts +0 -36
  52. package/dist/auth/device-flow.js +0 -189
  53. package/dist/auth/jwt.d.ts +0 -1
  54. package/dist/auth/jwt.js +0 -6
  55. package/dist/auth/session.d.ts +0 -67
  56. package/dist/auth/session.js +0 -86
  57. package/dist/auth-login.d.ts +0 -34
  58. package/dist/auth-login.js +0 -202
  59. package/dist/auth-logout.d.ts +0 -25
  60. package/dist/auth-logout.js +0 -115
  61. package/dist/auth-status.d.ts +0 -24
  62. package/dist/auth-status.js +0 -109
  63. package/dist/backlog-generate.d.ts +0 -11
  64. package/dist/backlog-generate.js +0 -308
  65. package/dist/backlog-health.d.ts +0 -11
  66. package/dist/backlog-health.js +0 -287
  67. package/dist/bridge-login.d.ts +0 -40
  68. package/dist/bridge-login.js +0 -277
  69. package/dist/chunk-3PAYRI4G.mjs +0 -2428
  70. package/dist/chunk-M4CS3A25.mjs +0 -2426
  71. package/dist/commands/auth/login.d.ts +0 -30
  72. package/dist/commands/auth/login.js +0 -164
  73. package/dist/commands/auth/logout.d.ts +0 -25
  74. package/dist/commands/auth/logout.js +0 -115
  75. package/dist/commands/auth/status.d.ts +0 -24
  76. package/dist/commands/auth/status.js +0 -109
  77. package/dist/commands/backlog/generate.d.ts +0 -11
  78. package/dist/commands/backlog/generate.js +0 -308
  79. package/dist/commands/backlog/health.d.ts +0 -11
  80. package/dist/commands/backlog/health.js +0 -287
  81. package/dist/commands/bridge/login.d.ts +0 -36
  82. package/dist/commands/bridge/login.js +0 -258
  83. package/dist/commands/export.d.ts +0 -35
  84. package/dist/commands/export.js +0 -485
  85. package/dist/commands/marketplace-export.d.ts +0 -21
  86. package/dist/commands/marketplace-export.js +0 -214
  87. package/dist/commands/project-clean.d.ts +0 -1
  88. package/dist/commands/project-clean.js +0 -126
  89. package/dist/commands/repo/common.d.ts +0 -105
  90. package/dist/commands/repo/common.js +0 -775
  91. package/dist/commands/repo/detach.d.ts +0 -2
  92. package/dist/commands/repo/detach.js +0 -120
  93. package/dist/commands/repo/register.d.ts +0 -21
  94. package/dist/commands/repo/register.js +0 -175
  95. package/dist/commands/repo/sync.d.ts +0 -22
  96. package/dist/commands/repo/sync.js +0 -873
  97. package/dist/commands/skills-import-local.d.ts +0 -16
  98. package/dist/commands/skills-import-local.js +0 -352
  99. package/dist/commands/spec/drift-check.d.ts +0 -3
  100. package/dist/commands/spec/drift-check.js +0 -186
  101. package/dist/commands/spec/frontmatter.d.ts +0 -11
  102. package/dist/commands/spec/frontmatter.js +0 -219
  103. package/dist/commands/spec/lint.d.ts +0 -11
  104. package/dist/commands/spec/lint.js +0 -499
  105. package/dist/commands/spec/parse.d.ts +0 -11
  106. package/dist/commands/spec/parse.js +0 -162
  107. package/dist/export.d.ts +0 -35
  108. package/dist/export.js +0 -485
  109. package/dist/main.d.ts +0 -1
  110. package/dist/marketplace-export.d.ts +0 -21
  111. package/dist/marketplace-export.js +0 -214
  112. package/dist/project-clean.d.ts +0 -1
  113. package/dist/project-clean.js +0 -126
  114. package/dist/project-context.d.ts +0 -99
  115. package/dist/project-context.js +0 -376
  116. package/dist/repo-common.d.ts +0 -101
  117. package/dist/repo-common.js +0 -671
  118. package/dist/repo-detach.d.ts +0 -2
  119. package/dist/repo-detach.js +0 -102
  120. package/dist/repo-ingest.d.ts +0 -29
  121. package/dist/repo-ingest.js +0 -305
  122. package/dist/repo-register.d.ts +0 -21
  123. package/dist/repo-register.js +0 -175
  124. package/dist/repo-sync.d.ts +0 -16
  125. package/dist/repo-sync.js +0 -152
  126. package/dist/resources/prompt-loader.d.ts +0 -1
  127. package/dist/resources/prompt-loader.js +0 -62
  128. package/dist/skills-import-local.d.ts +0 -16
  129. package/dist/skills-import-local.js +0 -352
  130. package/dist/spec-drift-check.d.ts +0 -3
  131. package/dist/spec-drift-check.js +0 -186
  132. package/dist/spec-frontmatter.d.ts +0 -11
  133. package/dist/spec-frontmatter.js +0 -219
  134. package/dist/spec-lint.d.ts +0 -11
  135. package/dist/spec-lint.js +0 -499
  136. package/dist/spec-parse.d.ts +0 -11
  137. package/dist/spec-parse.js +0 -162
  138. package/dist/stubs/dotenv.d.ts +0 -5
  139. package/dist/stubs/dotenv.js +0 -6
  140. package/dist/stubs/typeorm.d.ts +0 -22
  141. package/dist/stubs/typeorm.js +0 -28
  142. package/dist/tui-bundle.d.ts +0 -1
  143. package/dist/tui-bundle.js +0 -5
  144. package/dist/tui-entry.mjs +0 -1407
  145. package/dist/utils/cli-runtime.d.ts +0 -5
  146. package/dist/utils/cli-runtime.js +0 -22
  147. package/dist/utils/help-error.d.ts +0 -7
  148. package/dist/utils/help-error.js +0 -14
  149. package/dist/utils/interaction.d.ts +0 -19
  150. package/dist/utils/interaction.js +0 -93
  151. package/dist/utils/structured-log.d.ts +0 -7
  152. package/dist/utils/structured-log.js +0 -112
  153. package/dist/utils/trpc-url.d.ts +0 -4
  154. package/dist/utils/trpc-url.js +0 -15
@@ -1,376 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.findNearestLocalContextFile = findNearestLocalContextFile;
37
- exports.loadLocalContext = loadLocalContext;
38
- exports.loadGlobalContext = loadGlobalContext;
39
- exports.resolveProjectContext = resolveProjectContext;
40
- exports.getLastUsedProject = getLastUsedProject;
41
- exports.listRecentProjects = listRecentProjects;
42
- exports.setLastUsedProject = setLastUsedProject;
43
- exports.getProjectFromGlobalContext = getProjectFromGlobalContext;
44
- exports.saveLocalContext = saveLocalContext;
45
- exports.saveGlobalContext = saveGlobalContext;
46
- exports.addProjectToGlobalContext = addProjectToGlobalContext;
47
- exports.ensureGitignoreHasSpekn = ensureGitignoreHasSpekn;
48
- exports.persistProjectContext = persistProjectContext;
49
- exports.persistProjectContextWithoutRepoPath = persistProjectContextWithoutRepoPath;
50
- exports.clearRepoFromGlobalContext = clearRepoFromGlobalContext;
51
- const fs = __importStar(require("node:fs"));
52
- const os = __importStar(require("node:os"));
53
- const path = __importStar(require("node:path"));
54
- const LOCAL_CONTEXT_FILE = ".spekn";
55
- const GLOBAL_CONTEXT_PATH = path.join(os.homedir(), ".spekn", "context.json");
56
- function loadContextFile(filePath) {
57
- try {
58
- const raw = fs.readFileSync(filePath, "utf-8");
59
- const parsed = JSON.parse(raw);
60
- if (!parsed || typeof parsed !== "object")
61
- return null;
62
- return parsed;
63
- }
64
- catch {
65
- return null;
66
- }
67
- }
68
- function isRoot(dirPath) {
69
- return path.dirname(dirPath) === dirPath;
70
- }
71
- function findNearestLocalContextFile(startDir = process.cwd()) {
72
- let current = path.resolve(startDir);
73
- while (true) {
74
- const candidate = path.join(current, LOCAL_CONTEXT_FILE);
75
- if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
76
- return candidate;
77
- }
78
- if (isRoot(current))
79
- return null;
80
- current = path.dirname(current);
81
- }
82
- }
83
- function loadLocalContext(repoPath) {
84
- const filePath = repoPath
85
- ? path.join(path.resolve(repoPath), LOCAL_CONTEXT_FILE)
86
- : findNearestLocalContextFile();
87
- if (!filePath)
88
- return null;
89
- return loadContextFile(filePath);
90
- }
91
- function loadGlobalContext() {
92
- return loadContextFile(GLOBAL_CONTEXT_PATH);
93
- }
94
- function getGlobalProjects(global) {
95
- if (!global)
96
- return [];
97
- return Array.isArray(global.projects) ? global.projects : [];
98
- }
99
- function loadGlobalContextWithMigration() {
100
- return loadGlobalContext() || {
101
- projects: [],
102
- updatedAt: new Date().toISOString(),
103
- };
104
- }
105
- function resolveProjectContext(input) {
106
- const local = loadLocalContext(input.repoPath);
107
- const global = loadGlobalContextWithMigration();
108
- // Priority 1: Explicit project ID
109
- const projectId = input.explicitProjectId ??
110
- local?.projectId ??
111
- // Use last used project from global context if no local context
112
- global.lastUsedProjectId ??
113
- "";
114
- if (!projectId) {
115
- throw new Error("Missing project context. Pass --project-id/--project or create a .spekn file in the repository.");
116
- }
117
- // Priority 2: Organization ID resolution
118
- // Order:
119
- // 1) explicit org
120
- // 2) env org
121
- // 3) local .spekn org
122
- // 4) global project mapping
123
- // 5) global default org
124
- // 6) credentials org
125
- const organizationId = input.explicitOrganizationId ??
126
- input.envOrganizationId ??
127
- local?.organizationId ??
128
- getGlobalProjects(global).find((p) => p.id === projectId)?.organizationId ??
129
- global.defaultOrganizationId ??
130
- input.credentialsOrganizationId;
131
- if (!organizationId) {
132
- throw new Error("Missing organization context. Pass --organization-id, set SPEKN_ORGANIZATION_ID, " +
133
- "or run 'spekn auth login' to select an organization.");
134
- }
135
- return { projectId, organizationId };
136
- }
137
- /** Get the most recently used project from global context */
138
- function getLastUsedProject() {
139
- const global = loadGlobalContextWithMigration();
140
- const lastUsedId = global.lastUsedProjectId;
141
- if (!lastUsedId)
142
- return null;
143
- const project = getGlobalProjects(global).find(p => p.id === lastUsedId);
144
- if (project) {
145
- return {
146
- projectId: project.id,
147
- organizationId: project.organizationId
148
- };
149
- }
150
- return null;
151
- }
152
- /** List all recent projects from global context */
153
- function listRecentProjects() {
154
- const global = loadGlobalContextWithMigration();
155
- return getGlobalProjects(global).sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime()) || [];
156
- }
157
- /** Set the last used project in global context */
158
- function setLastUsedProject(projectId) {
159
- const global = loadGlobalContextWithMigration();
160
- // Only update if the project exists in our history
161
- if (getGlobalProjects(global).some(p => p.id === projectId)) {
162
- saveGlobalContext({
163
- ...global,
164
- lastUsedProjectId: projectId,
165
- updatedAt: new Date().toISOString()
166
- });
167
- }
168
- }
169
- /** Get project by ID from global context */
170
- function getProjectFromGlobalContext(projectId) {
171
- const global = loadGlobalContextWithMigration();
172
- return getGlobalProjects(global).find(p => p.id === projectId) || null;
173
- }
174
- function saveLocalContext(repoPath, context) {
175
- const filePath = path.join(path.resolve(repoPath), LOCAL_CONTEXT_FILE);
176
- const content = {
177
- projectId: context.projectId,
178
- organizationId: context.organizationId,
179
- updatedAt: new Date().toISOString(),
180
- };
181
- fs.writeFileSync(filePath, JSON.stringify(content, null, 2) + "\n", "utf-8");
182
- }
183
- function saveGlobalContext(context) {
184
- const dirPath = path.dirname(GLOBAL_CONTEXT_PATH);
185
- fs.mkdirSync(dirPath, { recursive: true, mode: 0o700 });
186
- // Ensure we have required fields
187
- const content = {
188
- projects: context.projects || getGlobalProjects(context),
189
- lastUsedProjectId: context.lastUsedProjectId,
190
- defaultOrganizationId: context.defaultOrganizationId,
191
- preferences: context.preferences,
192
- repoSync: context.repoSync,
193
- updatedAt: context.updatedAt || new Date().toISOString(),
194
- };
195
- fs.writeFileSync(GLOBAL_CONTEXT_PATH, JSON.stringify(content, null, 2) + "\n", {
196
- encoding: "utf-8",
197
- mode: 0o600,
198
- });
199
- }
200
- /** Add or update a project in the global context history */
201
- function addProjectToGlobalContext(projectId, organizationId, repoPath) {
202
- const globalContext = loadGlobalContextWithMigration();
203
- // Find existing project or create new
204
- let projectFound = false;
205
- const updatedProjects = getGlobalProjects(globalContext).map(p => {
206
- if (p.id === projectId) {
207
- projectFound = true;
208
- return {
209
- ...p,
210
- lastUsed: new Date().toISOString(),
211
- repoPaths: Array.from(new Set([...(p.repoPaths || []), repoPath]))
212
- };
213
- }
214
- return p;
215
- }) || [];
216
- // Add new project if not found
217
- if (!projectFound) {
218
- updatedProjects.unshift({
219
- id: projectId,
220
- organizationId,
221
- lastUsed: new Date().toISOString(),
222
- repoPaths: [repoPath]
223
- });
224
- }
225
- // Keep only last 10 projects to avoid unlimited growth
226
- const projects = updatedProjects.slice(0, 10);
227
- // Update global context
228
- saveGlobalContext({
229
- ...globalContext,
230
- projects,
231
- lastUsedProjectId: projectId,
232
- defaultOrganizationId: organizationId,
233
- updatedAt: new Date().toISOString()
234
- });
235
- }
236
- function ensureGitignoreHasSpekn(repoPath) {
237
- const gitignorePath = path.join(path.resolve(repoPath), ".gitignore");
238
- const entry = ".spekn";
239
- if (!fs.existsSync(gitignorePath)) {
240
- fs.writeFileSync(gitignorePath, `${entry}\n`, "utf-8");
241
- return;
242
- }
243
- const content = fs.readFileSync(gitignorePath, "utf-8");
244
- const lines = content.split(/\r?\n/);
245
- if (lines.some((line) => line.trim() === entry))
246
- return;
247
- const needsNewline = content.length > 0 && !content.endsWith("\n");
248
- const toAppend = `${needsNewline ? "\n" : ""}${entry}\n`;
249
- fs.appendFileSync(gitignorePath, toAppend, "utf-8");
250
- }
251
- function persistProjectContext(repoPath, context) {
252
- // Save local context (repository-specific)
253
- saveLocalContext(repoPath, context);
254
- // Add to global context history (multi-project support)
255
- if (context.organizationId) {
256
- addProjectToGlobalContext(context.projectId, context.organizationId, repoPath);
257
- }
258
- }
259
- function persistProjectContextWithoutRepoPath(repoPath, context) {
260
- // Keep local repository selection, but do not append repoPaths globally.
261
- saveLocalContext(repoPath, context);
262
- const globalContext = loadGlobalContextWithMigration();
263
- const now = new Date().toISOString();
264
- const organizationId = context.organizationId ?? globalContext.defaultOrganizationId ?? "";
265
- const projects = getGlobalProjects(globalContext);
266
- const updatedProjects = projects.map((project) => project.id === context.projectId
267
- ? {
268
- ...project,
269
- organizationId: organizationId || project.organizationId,
270
- lastUsed: now,
271
- }
272
- : project);
273
- if (!updatedProjects.some((project) => project.id === context.projectId) &&
274
- organizationId) {
275
- updatedProjects.unshift({
276
- id: context.projectId,
277
- organizationId,
278
- lastUsed: now,
279
- repoPaths: [],
280
- });
281
- }
282
- saveGlobalContext({
283
- ...globalContext,
284
- projects: updatedProjects.slice(0, 10),
285
- lastUsedProjectId: context.projectId,
286
- defaultOrganizationId: organizationId || globalContext.defaultOrganizationId,
287
- updatedAt: now,
288
- });
289
- }
290
- function clearRepoFromGlobalContext(repoPath, projectId) {
291
- const globalContext = loadGlobalContext();
292
- if (!globalContext) {
293
- return {
294
- removedProjectRefs: 0,
295
- removedSyncCheckpoints: 0,
296
- removedProjects: 0,
297
- clearedLastUsedProjectId: false,
298
- };
299
- }
300
- const normalizedRepoPath = path.resolve(repoPath);
301
- let removedProjectRefs = 0;
302
- let removedSyncCheckpoints = 0;
303
- let removedProjects = 0;
304
- const retainedProjects = getGlobalProjects(globalContext)
305
- .map((project) => {
306
- const repoPaths = (project.repoPaths || []).filter((entryPath) => {
307
- const shouldKeep = path.resolve(entryPath) !== normalizedRepoPath;
308
- if (!shouldKeep)
309
- removedProjectRefs += 1;
310
- return shouldKeep;
311
- });
312
- const checkpoints = { ...(project.repoSync?.checkpoints ?? {}) };
313
- for (const checkpointPath of Object.keys(checkpoints)) {
314
- if (path.resolve(checkpointPath) === normalizedRepoPath) {
315
- delete checkpoints[checkpointPath];
316
- removedSyncCheckpoints += 1;
317
- }
318
- }
319
- return {
320
- ...project,
321
- repoPaths,
322
- repoSync: {
323
- ...(project.repoSync ?? {}),
324
- checkpoints,
325
- },
326
- };
327
- })
328
- .filter((project) => {
329
- if (projectId && project.id === projectId) {
330
- removedProjects += 1;
331
- return false;
332
- }
333
- const hasRepoPaths = (project.repoPaths ?? []).length > 0;
334
- const hasCheckpoints = Object.keys(project.repoSync?.checkpoints ?? {}).length > 0;
335
- if (!hasRepoPaths && !hasCheckpoints) {
336
- removedProjects += 1;
337
- return false;
338
- }
339
- return true;
340
- });
341
- const removedProjectIds = new Set(getGlobalProjects(globalContext)
342
- .filter((project) => !retainedProjects.some((candidate) => candidate.id === project.id))
343
- .map((project) => project.id));
344
- const globalCheckpoints = { ...(globalContext.repoSync?.checkpoints ?? {}) };
345
- for (const checkpointPath of Object.keys(globalCheckpoints)) {
346
- if (path.resolve(checkpointPath) === normalizedRepoPath) {
347
- delete globalCheckpoints[checkpointPath];
348
- removedSyncCheckpoints += 1;
349
- }
350
- }
351
- const shouldClearLastUsed = !!globalContext.lastUsedProjectId && removedProjectIds.has(globalContext.lastUsedProjectId);
352
- if (removedProjectRefs === 0 &&
353
- removedSyncCheckpoints === 0 &&
354
- removedProjects === 0 &&
355
- !shouldClearLastUsed) {
356
- return {
357
- removedProjectRefs: 0,
358
- removedSyncCheckpoints: 0,
359
- removedProjects: 0,
360
- clearedLastUsedProjectId: false,
361
- };
362
- }
363
- saveGlobalContext({
364
- ...globalContext,
365
- projects: retainedProjects,
366
- lastUsedProjectId: shouldClearLastUsed ? undefined : globalContext.lastUsedProjectId,
367
- repoSync: Object.keys(globalCheckpoints).length > 0 ? { checkpoints: globalCheckpoints } : undefined,
368
- updatedAt: new Date().toISOString(),
369
- });
370
- return {
371
- removedProjectRefs,
372
- removedSyncCheckpoints,
373
- removedProjects,
374
- clearedLastUsedProjectId: shouldClearLastUsed,
375
- };
376
- }
@@ -1,101 +0,0 @@
1
- /**
2
- * Shared utilities for repo register / repo sync CLI commands.
3
- *
4
- * Extracts common concerns: deps, auth, git metadata, tRPC client,
5
- * file discovery display, and the full analysis phase.
6
- */
7
- import { CredentialsStore } from "./auth/credentials-store";
8
- import { HelpRequestedError } from "./utils/help-error";
9
- export interface Deps {
10
- execGit: (args: string[]) => string;
11
- stdout: (content: string) => void;
12
- stderr: (content: string) => void;
13
- credentialsStore: CredentialsStore;
14
- }
15
- export declare const defaultDeps: Deps;
16
- /** Fields common to both register and sync CLI options. */
17
- export interface CommonOptions {
18
- projectId: string;
19
- apiUrl: string;
20
- analyze: boolean;
21
- agent: string | null;
22
- repoPath: string;
23
- dryRun: boolean;
24
- mcpUrl: string;
25
- debug: boolean;
26
- }
27
- export interface DiscoveredFile {
28
- relativePath: string;
29
- absolutePath: string;
30
- category: "governance" | "spec" | "decision" | "config";
31
- }
32
- export { HelpRequestedError };
33
- /**
34
- * Parse flags shared by both register and sync. Returns consumed arg
35
- * count (0 if the flag was not recognized). Mutates `out` in place.
36
- */
37
- export declare function parseCommonFlag(args: string[], index: number, out: CommonOptions): number;
38
- export declare function commonDefaults(analyzeDefault: boolean): CommonOptions;
39
- export declare function finalizeOptions<T extends CommonOptions>(opts: T): T;
40
- export declare function resolveAuth(deps: Deps, options?: {
41
- projectId?: string;
42
- repoPath?: string;
43
- }): Promise<{
44
- authToken: string | undefined;
45
- organizationId: string;
46
- projectId: string;
47
- }>;
48
- export declare function createApiClient(apiUrl: string, authToken: string | undefined, organizationId: string): any;
49
- export declare function repoNameFromUrl(url: string): string;
50
- export declare function resolveDefaultBranch(execGit: Deps["execGit"]): string;
51
- export declare function readGitMetadata(repoPath: string, deps: Deps): {
52
- remoteUrl: string;
53
- name: string;
54
- defaultBranch: string;
55
- } | null;
56
- export declare function discoverFiles(repoPath: string): DiscoveredFile[];
57
- /** Discover files, print summary. Returns files or null if empty. */
58
- export declare function discoverAndDisplay(repoPath: string, stdout: (s: string) => void): DiscoveredFile[] | null;
59
- export declare function buildAnalysisPrompt(projectId: string, repoPath: string, files: DiscoveredFile[], organizationId?: string): string;
60
- export declare function validateAnalysisReport(text: string): {
61
- ok: boolean;
62
- missing: string[];
63
- };
64
- /**
65
- * Connect to the MCP HTTP server via raw JSON-RPC, perform the MCP
66
- * initialize handshake, then list tools and verify Spekn tools exist.
67
- * Returns tool names on success or null on failure.
68
- */
69
- export declare function verifyMcpServer(mcpUrl: string, authToken: string, stderr: (s: string) => void, debug: boolean, sessionPurpose?: string): Promise<string[] | null>;
70
- export declare function executeAcpSession(agent: {
71
- command: string;
72
- args: string[];
73
- }, prompt: string, repoPath: string, mcpUrl: string, authToken: string, stderr: (s: string) => void, organizationId?: string, sessionPurpose?: string): Promise<{
74
- text: string;
75
- error?: string;
76
- }>;
77
- export interface AnalysisOptions {
78
- apiUrl: string;
79
- agentName: string | null;
80
- prompt: string;
81
- repoPath: string;
82
- mcpUrl: string;
83
- authToken: string;
84
- organizationId?: string;
85
- stdout: (s: string) => void;
86
- stderr: (s: string) => void;
87
- debug: boolean;
88
- }
89
- /**
90
- * Verify MCP server, resolve an agent, run the ACP session.
91
- * Retries with the next agent if one doesn't support HTTP MCP.
92
- */
93
- export declare function runAnalysisWithAgent(options: AnalysisOptions): Promise<{
94
- text: string;
95
- error?: string;
96
- }>;
97
- /**
98
- * Complete analysis phase: discover files → build prompt → run agent.
99
- * Returns exit code (0 = success, 1 = error).
100
- */
101
- export declare function runAnalysisPhase(options: CommonOptions, authToken: string, deps: Deps, organizationId?: string): Promise<number>;