@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.
- package/README.md +58 -0
- package/dist/main.js +40540 -32176
- package/dist/prompts/governance-analysis.prompt.md +109 -0
- package/dist/resources/prompts/repo-analysis.prompt.md +28 -136
- package/dist/resources/prompts/repo-sync-analysis.prompt.md +31 -68
- package/dist/tui/chunk-4WEASLXY.mjs +3444 -0
- package/dist/tui/chunk-755CADEG.mjs +3401 -0
- package/dist/tui/chunk-BUJQVTY5.mjs +3409 -0
- package/dist/tui/chunk-BZKKMGFB.mjs +1959 -0
- package/dist/tui/chunk-DJYOBCNM.mjs +3159 -0
- package/dist/tui/chunk-GTFTFDY4.mjs +3417 -0
- package/dist/tui/chunk-IMEBD2KA.mjs +3444 -0
- package/dist/tui/chunk-IX6DR5SW.mjs +3433 -0
- package/dist/tui/chunk-JKFOY4IF.mjs +2003 -0
- package/dist/tui/chunk-OXXZ3O5L.mjs +3378 -0
- package/dist/tui/chunk-SHJNIAAJ.mjs +1697 -0
- package/dist/tui/chunk-V4SNDRUS.mjs +1666 -0
- package/dist/tui/chunk-VXVHNZST.mjs +1666 -0
- package/dist/tui/chunk-WCTSFKTA.mjs +3459 -0
- package/dist/tui/chunk-X2XP5ACW.mjs +3443 -0
- package/dist/tui/chunk-YUYJ7VBG.mjs +2029 -0
- package/dist/tui/chunk-ZM3EI5IA.mjs +3384 -0
- package/dist/tui/chunk-ZYOX64HP.mjs +1653 -0
- package/dist/tui/index.mjs +6999 -6938
- package/dist/tui/prompts/spec-creation-system.prompt.md +47 -0
- package/dist/tui/prompts/spec-refinement-system.prompt.md +72 -0
- package/dist/tui/use-session-store-63YUGUFA.mjs +8 -0
- package/dist/tui/use-session-store-ACO2SMJC.mjs +8 -0
- package/dist/tui/use-session-store-BVFDAWOB.mjs +8 -0
- package/dist/tui/use-session-store-DJIZ3FQZ.mjs +9 -0
- package/dist/tui/use-session-store-EAIQA4UG.mjs +9 -0
- package/dist/tui/use-session-store-EFBAXC3G.mjs +8 -0
- package/dist/tui/use-session-store-FJOR4KTG.mjs +8 -0
- package/dist/tui/use-session-store-IJE5KVOC.mjs +8 -0
- package/dist/tui/use-session-store-KGAFXCKI.mjs +8 -0
- package/dist/tui/use-session-store-KS4DPNDY.mjs +8 -0
- package/dist/tui/use-session-store-MMHJENNL.mjs +8 -0
- package/dist/tui/use-session-store-OZ6HC4I2.mjs +9 -0
- package/dist/tui/use-session-store-PTMWISNJ.mjs +8 -0
- package/dist/tui/use-session-store-VCDECQMW.mjs +8 -0
- package/dist/tui/use-session-store-VOK5ML5J.mjs +9 -0
- package/package.json +33 -13
- package/dist/__tests__/export-cli.test.d.ts +0 -1
- package/dist/__tests__/export-cli.test.js +0 -70
- package/dist/__tests__/tui-args-policy.test.d.ts +0 -1
- package/dist/__tests__/tui-args-policy.test.js +0 -50
- package/dist/acp-S2MHZOAD.mjs +0 -23
- package/dist/acp-UCCI44JY.mjs +0 -25
- package/dist/auth/credentials-store.d.ts +0 -2
- package/dist/auth/credentials-store.js +0 -5
- package/dist/auth/device-flow.d.ts +0 -36
- package/dist/auth/device-flow.js +0 -189
- package/dist/auth/jwt.d.ts +0 -1
- package/dist/auth/jwt.js +0 -6
- package/dist/auth/session.d.ts +0 -67
- package/dist/auth/session.js +0 -86
- package/dist/auth-login.d.ts +0 -34
- package/dist/auth-login.js +0 -202
- package/dist/auth-logout.d.ts +0 -25
- package/dist/auth-logout.js +0 -115
- package/dist/auth-status.d.ts +0 -24
- package/dist/auth-status.js +0 -109
- package/dist/backlog-generate.d.ts +0 -11
- package/dist/backlog-generate.js +0 -308
- package/dist/backlog-health.d.ts +0 -11
- package/dist/backlog-health.js +0 -287
- package/dist/bridge-login.d.ts +0 -40
- package/dist/bridge-login.js +0 -277
- package/dist/chunk-3PAYRI4G.mjs +0 -2428
- package/dist/chunk-M4CS3A25.mjs +0 -2426
- package/dist/commands/auth/login.d.ts +0 -30
- package/dist/commands/auth/login.js +0 -164
- package/dist/commands/auth/logout.d.ts +0 -25
- package/dist/commands/auth/logout.js +0 -115
- package/dist/commands/auth/status.d.ts +0 -24
- package/dist/commands/auth/status.js +0 -109
- package/dist/commands/backlog/generate.d.ts +0 -11
- package/dist/commands/backlog/generate.js +0 -308
- package/dist/commands/backlog/health.d.ts +0 -11
- package/dist/commands/backlog/health.js +0 -287
- package/dist/commands/bridge/login.d.ts +0 -36
- package/dist/commands/bridge/login.js +0 -258
- package/dist/commands/export.d.ts +0 -35
- package/dist/commands/export.js +0 -485
- package/dist/commands/marketplace-export.d.ts +0 -21
- package/dist/commands/marketplace-export.js +0 -214
- package/dist/commands/project-clean.d.ts +0 -1
- package/dist/commands/project-clean.js +0 -126
- package/dist/commands/repo/common.d.ts +0 -105
- package/dist/commands/repo/common.js +0 -775
- package/dist/commands/repo/detach.d.ts +0 -2
- package/dist/commands/repo/detach.js +0 -120
- package/dist/commands/repo/register.d.ts +0 -21
- package/dist/commands/repo/register.js +0 -175
- package/dist/commands/repo/sync.d.ts +0 -22
- package/dist/commands/repo/sync.js +0 -873
- package/dist/commands/skills-import-local.d.ts +0 -16
- package/dist/commands/skills-import-local.js +0 -352
- package/dist/commands/spec/drift-check.d.ts +0 -3
- package/dist/commands/spec/drift-check.js +0 -186
- package/dist/commands/spec/frontmatter.d.ts +0 -11
- package/dist/commands/spec/frontmatter.js +0 -219
- package/dist/commands/spec/lint.d.ts +0 -11
- package/dist/commands/spec/lint.js +0 -499
- package/dist/commands/spec/parse.d.ts +0 -11
- package/dist/commands/spec/parse.js +0 -162
- package/dist/export.d.ts +0 -35
- package/dist/export.js +0 -485
- package/dist/main.d.ts +0 -1
- package/dist/marketplace-export.d.ts +0 -21
- package/dist/marketplace-export.js +0 -214
- package/dist/project-clean.d.ts +0 -1
- package/dist/project-clean.js +0 -126
- package/dist/project-context.d.ts +0 -99
- package/dist/project-context.js +0 -376
- package/dist/repo-common.d.ts +0 -101
- package/dist/repo-common.js +0 -671
- package/dist/repo-detach.d.ts +0 -2
- package/dist/repo-detach.js +0 -102
- package/dist/repo-ingest.d.ts +0 -29
- package/dist/repo-ingest.js +0 -305
- package/dist/repo-register.d.ts +0 -21
- package/dist/repo-register.js +0 -175
- package/dist/repo-sync.d.ts +0 -16
- package/dist/repo-sync.js +0 -152
- package/dist/resources/prompt-loader.d.ts +0 -1
- package/dist/resources/prompt-loader.js +0 -62
- package/dist/skills-import-local.d.ts +0 -16
- package/dist/skills-import-local.js +0 -352
- package/dist/spec-drift-check.d.ts +0 -3
- package/dist/spec-drift-check.js +0 -186
- package/dist/spec-frontmatter.d.ts +0 -11
- package/dist/spec-frontmatter.js +0 -219
- package/dist/spec-lint.d.ts +0 -11
- package/dist/spec-lint.js +0 -499
- package/dist/spec-parse.d.ts +0 -11
- package/dist/spec-parse.js +0 -162
- package/dist/stubs/dotenv.d.ts +0 -5
- package/dist/stubs/dotenv.js +0 -6
- package/dist/stubs/typeorm.d.ts +0 -22
- package/dist/stubs/typeorm.js +0 -28
- package/dist/tui-bundle.d.ts +0 -1
- package/dist/tui-bundle.js +0 -5
- package/dist/tui-entry.mjs +0 -1407
- package/dist/utils/cli-runtime.d.ts +0 -5
- package/dist/utils/cli-runtime.js +0 -22
- package/dist/utils/help-error.d.ts +0 -7
- package/dist/utils/help-error.js +0 -14
- package/dist/utils/interaction.d.ts +0 -19
- package/dist/utils/interaction.js +0 -93
- package/dist/utils/structured-log.d.ts +0 -7
- package/dist/utils/structured-log.js +0 -112
- package/dist/utils/trpc-url.d.ts +0 -4
- package/dist/utils/trpc-url.js +0 -15
package/dist/project-context.js
DELETED
|
@@ -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
|
-
}
|
package/dist/repo-common.d.ts
DELETED
|
@@ -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>;
|