@spekn/cli 1.0.0

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 (159) hide show
  1. package/dist/__tests__/export-cli.test.d.ts +1 -0
  2. package/dist/__tests__/export-cli.test.js +70 -0
  3. package/dist/__tests__/tui-args-policy.test.d.ts +1 -0
  4. package/dist/__tests__/tui-args-policy.test.js +50 -0
  5. package/dist/acp-S2MHZOAD.mjs +23 -0
  6. package/dist/acp-UCCI44JY.mjs +25 -0
  7. package/dist/auth/credentials-store.d.ts +2 -0
  8. package/dist/auth/credentials-store.js +5 -0
  9. package/dist/auth/device-flow.d.ts +36 -0
  10. package/dist/auth/device-flow.js +189 -0
  11. package/dist/auth/jwt.d.ts +1 -0
  12. package/dist/auth/jwt.js +6 -0
  13. package/dist/auth/session.d.ts +67 -0
  14. package/dist/auth/session.js +86 -0
  15. package/dist/auth-login.d.ts +34 -0
  16. package/dist/auth-login.js +202 -0
  17. package/dist/auth-logout.d.ts +25 -0
  18. package/dist/auth-logout.js +115 -0
  19. package/dist/auth-status.d.ts +24 -0
  20. package/dist/auth-status.js +109 -0
  21. package/dist/backlog-generate.d.ts +11 -0
  22. package/dist/backlog-generate.js +308 -0
  23. package/dist/backlog-health.d.ts +11 -0
  24. package/dist/backlog-health.js +287 -0
  25. package/dist/bridge-login.d.ts +40 -0
  26. package/dist/bridge-login.js +277 -0
  27. package/dist/chunk-3PAYRI4G.mjs +2428 -0
  28. package/dist/chunk-M4CS3A25.mjs +2426 -0
  29. package/dist/commands/auth/login.d.ts +30 -0
  30. package/dist/commands/auth/login.js +164 -0
  31. package/dist/commands/auth/logout.d.ts +25 -0
  32. package/dist/commands/auth/logout.js +115 -0
  33. package/dist/commands/auth/status.d.ts +24 -0
  34. package/dist/commands/auth/status.js +109 -0
  35. package/dist/commands/backlog/generate.d.ts +11 -0
  36. package/dist/commands/backlog/generate.js +308 -0
  37. package/dist/commands/backlog/health.d.ts +11 -0
  38. package/dist/commands/backlog/health.js +287 -0
  39. package/dist/commands/bridge/login.d.ts +36 -0
  40. package/dist/commands/bridge/login.js +258 -0
  41. package/dist/commands/export.d.ts +35 -0
  42. package/dist/commands/export.js +485 -0
  43. package/dist/commands/marketplace-export.d.ts +21 -0
  44. package/dist/commands/marketplace-export.js +214 -0
  45. package/dist/commands/project-clean.d.ts +1 -0
  46. package/dist/commands/project-clean.js +126 -0
  47. package/dist/commands/repo/common.d.ts +105 -0
  48. package/dist/commands/repo/common.js +775 -0
  49. package/dist/commands/repo/detach.d.ts +2 -0
  50. package/dist/commands/repo/detach.js +120 -0
  51. package/dist/commands/repo/register.d.ts +21 -0
  52. package/dist/commands/repo/register.js +175 -0
  53. package/dist/commands/repo/sync.d.ts +22 -0
  54. package/dist/commands/repo/sync.js +873 -0
  55. package/dist/commands/skills-import-local.d.ts +16 -0
  56. package/dist/commands/skills-import-local.js +352 -0
  57. package/dist/commands/spec/drift-check.d.ts +3 -0
  58. package/dist/commands/spec/drift-check.js +186 -0
  59. package/dist/commands/spec/frontmatter.d.ts +11 -0
  60. package/dist/commands/spec/frontmatter.js +219 -0
  61. package/dist/commands/spec/lint.d.ts +11 -0
  62. package/dist/commands/spec/lint.js +499 -0
  63. package/dist/commands/spec/parse.d.ts +11 -0
  64. package/dist/commands/spec/parse.js +162 -0
  65. package/dist/export.d.ts +35 -0
  66. package/dist/export.js +485 -0
  67. package/dist/index.d.ts +11 -0
  68. package/dist/index.js +21 -0
  69. package/dist/main.d.ts +1 -0
  70. package/dist/main.js +115280 -0
  71. package/dist/marketplace-export.d.ts +21 -0
  72. package/dist/marketplace-export.js +214 -0
  73. package/dist/project-clean.d.ts +1 -0
  74. package/dist/project-clean.js +126 -0
  75. package/dist/project-context.d.ts +99 -0
  76. package/dist/project-context.js +376 -0
  77. package/dist/repo-common.d.ts +101 -0
  78. package/dist/repo-common.js +671 -0
  79. package/dist/repo-detach.d.ts +2 -0
  80. package/dist/repo-detach.js +102 -0
  81. package/dist/repo-ingest.d.ts +29 -0
  82. package/dist/repo-ingest.js +305 -0
  83. package/dist/repo-register.d.ts +21 -0
  84. package/dist/repo-register.js +175 -0
  85. package/dist/repo-sync.d.ts +16 -0
  86. package/dist/repo-sync.js +152 -0
  87. package/dist/resources/prompt-loader.d.ts +1 -0
  88. package/dist/resources/prompt-loader.js +62 -0
  89. package/dist/resources/prompts/README.md +21 -0
  90. package/dist/resources/prompts/prompts/repo-analysis.prompt.md +126 -0
  91. package/dist/resources/prompts/repo-analysis.prompt.md +151 -0
  92. package/dist/resources/prompts/repo-sync-analysis.prompt.md +85 -0
  93. package/dist/skills-import-local.d.ts +16 -0
  94. package/dist/skills-import-local.js +352 -0
  95. package/dist/spec-drift-check.d.ts +3 -0
  96. package/dist/spec-drift-check.js +186 -0
  97. package/dist/spec-frontmatter.d.ts +11 -0
  98. package/dist/spec-frontmatter.js +219 -0
  99. package/dist/spec-lint.d.ts +11 -0
  100. package/dist/spec-lint.js +499 -0
  101. package/dist/spec-parse.d.ts +11 -0
  102. package/dist/spec-parse.js +162 -0
  103. package/dist/stubs/dotenv.d.ts +5 -0
  104. package/dist/stubs/dotenv.js +6 -0
  105. package/dist/stubs/typeorm.d.ts +22 -0
  106. package/dist/stubs/typeorm.js +28 -0
  107. package/dist/tui/app.d.ts +7 -0
  108. package/dist/tui/app.js +122 -0
  109. package/dist/tui/args.d.ts +8 -0
  110. package/dist/tui/args.js +57 -0
  111. package/dist/tui/capabilities/policy.d.ts +7 -0
  112. package/dist/tui/capabilities/policy.js +64 -0
  113. package/dist/tui/components/frame.d.ts +8 -0
  114. package/dist/tui/components/frame.js +8 -0
  115. package/dist/tui/components/status-bar.d.ts +8 -0
  116. package/dist/tui/components/status-bar.js +8 -0
  117. package/dist/tui/index.d.ts +2 -0
  118. package/dist/tui/index.js +23 -0
  119. package/dist/tui/index.mjs +7563 -0
  120. package/dist/tui/keymap/use-global-keymap.d.ts +19 -0
  121. package/dist/tui/keymap/use-global-keymap.js +82 -0
  122. package/dist/tui/navigation/nav-items.d.ts +3 -0
  123. package/dist/tui/navigation/nav-items.js +18 -0
  124. package/dist/tui/screens/bridge.d.ts +8 -0
  125. package/dist/tui/screens/bridge.js +19 -0
  126. package/dist/tui/screens/decisions.d.ts +5 -0
  127. package/dist/tui/screens/decisions.js +28 -0
  128. package/dist/tui/screens/export.d.ts +5 -0
  129. package/dist/tui/screens/export.js +16 -0
  130. package/dist/tui/screens/home.d.ts +5 -0
  131. package/dist/tui/screens/home.js +33 -0
  132. package/dist/tui/screens/locked.d.ts +5 -0
  133. package/dist/tui/screens/locked.js +9 -0
  134. package/dist/tui/screens/specs.d.ts +5 -0
  135. package/dist/tui/screens/specs.js +31 -0
  136. package/dist/tui/services/client.d.ts +1 -0
  137. package/dist/tui/services/client.js +18 -0
  138. package/dist/tui/services/context-service.d.ts +19 -0
  139. package/dist/tui/services/context-service.js +246 -0
  140. package/dist/tui/shared-enums.d.ts +16 -0
  141. package/dist/tui/shared-enums.js +19 -0
  142. package/dist/tui/state/use-app-state.d.ts +35 -0
  143. package/dist/tui/state/use-app-state.js +177 -0
  144. package/dist/tui/types.d.ts +77 -0
  145. package/dist/tui/types.js +2 -0
  146. package/dist/tui-bundle.d.ts +1 -0
  147. package/dist/tui-bundle.js +5 -0
  148. package/dist/tui-entry.mjs +1407 -0
  149. package/dist/utils/cli-runtime.d.ts +5 -0
  150. package/dist/utils/cli-runtime.js +22 -0
  151. package/dist/utils/help-error.d.ts +7 -0
  152. package/dist/utils/help-error.js +14 -0
  153. package/dist/utils/interaction.d.ts +19 -0
  154. package/dist/utils/interaction.js +93 -0
  155. package/dist/utils/structured-log.d.ts +7 -0
  156. package/dist/utils/structured-log.js +112 -0
  157. package/dist/utils/trpc-url.d.ts +4 -0
  158. package/dist/utils/trpc-url.js +15 -0
  159. package/package.json +59 -0
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import { CredentialsStore } from './auth/credentials-store';
3
+ interface CLIOptions {
4
+ projectId?: string;
5
+ output: string;
6
+ apiUrl: string;
7
+ marketplaceName: string;
8
+ ownerName: string;
9
+ }
10
+ interface Deps {
11
+ createClient: (apiUrl: string, organizationId: string, authToken?: string) => any;
12
+ writeFile: (filePath: string, content: string) => void;
13
+ mkdirSync: (dirPath: string) => void;
14
+ stdout: (content: string) => void;
15
+ stderr: (content: string) => void;
16
+ credentialsStore: CredentialsStore;
17
+ }
18
+ declare function parseArgs(args: string[]): CLIOptions;
19
+ export declare function runMarketplaceExportCli(args: string[], deps?: Deps): Promise<number>;
20
+ declare function main(): Promise<void>;
21
+ export { main, parseArgs };
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.runMarketplaceExportCli = runMarketplaceExportCli;
38
+ exports.main = main;
39
+ exports.parseArgs = parseArgs;
40
+ const client_1 = require("@trpc/client");
41
+ const fs = __importStar(require("node:fs"));
42
+ const path = __importStar(require("node:path"));
43
+ const credentials_store_1 = require("./auth/credentials-store");
44
+ const export_1 = require("./export");
45
+ const project_context_1 = require("./project-context");
46
+ const structured_log_1 = require("./utils/structured-log");
47
+ const defaultDeps = {
48
+ createClient: (apiUrl, organizationId, authToken) => (0, client_1.createTRPCProxyClient)({
49
+ links: [
50
+ (0, client_1.httpBatchLink)({
51
+ url: (0, export_1.normalizeTrpcUrl)(apiUrl),
52
+ headers: {
53
+ 'x-organization-id': organizationId,
54
+ authorization: authToken ? `Bearer ${authToken}` : '',
55
+ },
56
+ }),
57
+ ],
58
+ }),
59
+ writeFile: (filePath, content) => {
60
+ fs.writeFileSync(filePath, content, 'utf-8');
61
+ },
62
+ mkdirSync: (dirPath) => {
63
+ fs.mkdirSync(dirPath, { recursive: true });
64
+ },
65
+ stdout: (content) => process.stdout.write(content),
66
+ stderr: (content) => process.stderr.write(content),
67
+ credentialsStore: new credentials_store_1.CredentialsStore(),
68
+ };
69
+ function printHelp(stderr) {
70
+ stderr(`
71
+ marketplace export - Export Claude Code-compatible plugin marketplace to disk
72
+
73
+ USAGE:
74
+ spekn marketplace export --project <uuid> [options]
75
+
76
+ OPTIONS:
77
+ --project <uuid> Project ID (optional if .spekn/context is present)
78
+ --output <dir> Output directory (default: .)
79
+ --api-url <url> API base URL (default: SPEKN_API_URL or https://app.spekn.com)
80
+ --marketplace-name <name> Marketplace identifier (default: spekn-marketplace)
81
+ --owner-name <name> Owner name (default: Spekn)
82
+ --help Show help
83
+ `);
84
+ }
85
+ function parseArgs(args) {
86
+ let projectId = '';
87
+ let output = '.';
88
+ let apiUrl = process.env.SPEKN_API_URL || 'https://app.spekn.com';
89
+ let marketplaceName = 'spekn-marketplace';
90
+ let ownerName = 'Spekn';
91
+ for (let index = 0; index < args.length; index++) {
92
+ const arg = args[index];
93
+ if (arg === '--help' || arg === '-h') {
94
+ throw new Error('__HELP__');
95
+ }
96
+ if (arg === '--project' && args[index + 1]) {
97
+ projectId = args[++index];
98
+ continue;
99
+ }
100
+ if (arg.startsWith('--project=')) {
101
+ projectId = arg.slice('--project='.length);
102
+ continue;
103
+ }
104
+ if (arg === '--output' && args[index + 1]) {
105
+ output = args[++index];
106
+ continue;
107
+ }
108
+ if (arg.startsWith('--output=')) {
109
+ output = arg.slice('--output='.length);
110
+ continue;
111
+ }
112
+ if (arg === '--api-url' && args[index + 1]) {
113
+ apiUrl = args[++index];
114
+ continue;
115
+ }
116
+ if (arg.startsWith('--api-url=')) {
117
+ apiUrl = arg.slice('--api-url='.length);
118
+ continue;
119
+ }
120
+ if (arg === '--marketplace-name' && args[index + 1]) {
121
+ marketplaceName = args[++index];
122
+ continue;
123
+ }
124
+ if (arg.startsWith('--marketplace-name=')) {
125
+ marketplaceName = arg.slice('--marketplace-name='.length);
126
+ continue;
127
+ }
128
+ if (arg === '--owner-name' && args[index + 1]) {
129
+ ownerName = args[++index];
130
+ continue;
131
+ }
132
+ if (arg.startsWith('--owner-name=')) {
133
+ ownerName = arg.slice('--owner-name='.length);
134
+ continue;
135
+ }
136
+ }
137
+ return {
138
+ projectId,
139
+ output,
140
+ apiUrl,
141
+ marketplaceName,
142
+ ownerName,
143
+ };
144
+ }
145
+ async function runMarketplaceExportCli(args, deps = defaultDeps) {
146
+ try {
147
+ const options = parseArgs(args);
148
+ (0, structured_log_1.appendCliStructuredLog)({
149
+ source: 'cli.marketplace.export',
150
+ level: 'info',
151
+ message: 'Starting marketplace export',
152
+ details: { output: options.output, apiUrl: options.apiUrl, marketplaceName: options.marketplaceName },
153
+ });
154
+ const storedToken = await deps.credentialsStore.getValidToken();
155
+ const authToken = storedToken ?? process.env.SPEKN_AUTH_TOKEN;
156
+ const storedCreds = deps.credentialsStore.load();
157
+ const context = (0, project_context_1.resolveProjectContext)({
158
+ explicitProjectId: options.projectId,
159
+ repoPath: process.cwd(),
160
+ credentialsOrganizationId: storedCreds?.organizationId,
161
+ envOrganizationId: process.env.SPEKN_ORGANIZATION_ID,
162
+ });
163
+ const client = deps.createClient(options.apiUrl, context.organizationId, authToken ?? undefined);
164
+ const result = await client.marketplace.exportClaudeCodeCatalog.query({
165
+ marketplaceName: options.marketplaceName,
166
+ ownerName: options.ownerName,
167
+ });
168
+ const outputDir = path.resolve(process.cwd(), options.output);
169
+ // Write marketplace.json
170
+ const marketplaceDir = path.join(outputDir, '.claude-plugin');
171
+ deps.mkdirSync(marketplaceDir);
172
+ deps.writeFile(path.join(marketplaceDir, 'marketplace.json'), typeof result.json === 'string' ? result.json : JSON.stringify(result.json, null, 2));
173
+ // Write per-plugin manifests
174
+ for (const entry of result.entries) {
175
+ const pluginDir = path.join(outputDir, 'plugins', entry.name, '.claude-plugin');
176
+ deps.mkdirSync(pluginDir);
177
+ deps.writeFile(path.join(pluginDir, 'plugin.json'), JSON.stringify({
178
+ name: entry.name,
179
+ description: entry.description,
180
+ version: entry.version,
181
+ author: entry.author,
182
+ }, null, 2));
183
+ }
184
+ deps.stdout(`Exported ${result.pluginCount} plugins to ${outputDir}\n`);
185
+ (0, structured_log_1.appendCliStructuredLog)({
186
+ source: 'cli.marketplace.export',
187
+ level: 'info',
188
+ message: 'Marketplace export complete',
189
+ details: { outputDir, pluginCount: result.pluginCount },
190
+ });
191
+ return 0;
192
+ }
193
+ catch (error) {
194
+ if (error instanceof Error && error.message === '__HELP__') {
195
+ printHelp(deps.stderr);
196
+ return 0;
197
+ }
198
+ const message = error instanceof Error ? error.message : String(error);
199
+ deps.stderr(`Error: ${message}\n`);
200
+ (0, structured_log_1.appendCliStructuredLog)({
201
+ source: 'cli.marketplace.export',
202
+ level: 'error',
203
+ message,
204
+ });
205
+ return 1;
206
+ }
207
+ }
208
+ async function main() {
209
+ const exitCode = await runMarketplaceExportCli(process.argv.slice(2));
210
+ process.exit(exitCode);
211
+ }
212
+ if (require.main === module) {
213
+ void main();
214
+ }
@@ -0,0 +1 @@
1
+ export declare function runProjectDeleteCli(args: string[]): Promise<number>;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runProjectDeleteCli = runProjectDeleteCli;
4
+ const client_1 = require("@trpc/client");
5
+ const credentials_store_1 = require("./auth/credentials-store");
6
+ const trpc_url_1 = require("./utils/trpc-url");
7
+ /**
8
+ * Delete a project using the API. With the fixed foreign key constraints,
9
+ * the database will automatically cascade delete all related entities.
10
+ */
11
+ async function deleteProject(projectId, apiUrl) {
12
+ const credentialsStore = new credentials_store_1.CredentialsStore();
13
+ const authToken = await credentialsStore.getValidToken();
14
+ if (!authToken) {
15
+ throw new Error("Not authenticated. Please run 'spekn auth login' first.");
16
+ }
17
+ const credentials = credentialsStore.load();
18
+ const organizationId = credentials?.organizationId ?? "";
19
+ const trpc = (0, client_1.createTRPCProxyClient)({
20
+ links: [
21
+ (0, client_1.httpBatchLink)({
22
+ url: (0, trpc_url_1.normalizeTrpcUrl)(apiUrl),
23
+ headers: {
24
+ Authorization: `Bearer ${authToken}`,
25
+ "x-organization-id": organizationId,
26
+ },
27
+ }),
28
+ ],
29
+ });
30
+ console.log(`Deleting project ${projectId}...`);
31
+ try {
32
+ // With the fixed foreign key constraints, this single call will
33
+ // automatically cascade delete all related entities
34
+ await trpc.project.delete.mutate({ id: projectId });
35
+ console.log(`✅ Project ${projectId} and all related entities have been successfully deleted.`);
36
+ }
37
+ catch (error) {
38
+ console.error("❌ Error deleting project:", error);
39
+ throw error;
40
+ }
41
+ }
42
+ function printHelp() {
43
+ console.log(`
44
+ project delete - Delete a project and all its related entities
45
+
46
+ USAGE:
47
+ spekn project delete <project-id> [options]
48
+
49
+ ARGUMENTS:
50
+ <project-id> Project ID to delete
51
+
52
+ OPTIONS:
53
+ --api-url <url> API URL (default: SPEKN_API_URL or https://app.spekn.com)
54
+ --force Skip confirmation prompt
55
+ --help Show this help message
56
+
57
+ EXAMPLES:
58
+ spekn project delete 11111111-1111-4111-8111-111111111111
59
+ spekn project delete 11111111-1111-4111-8111-111111111111 --force
60
+ `);
61
+ }
62
+ async function runProjectDeleteCli(args) {
63
+ // Parse arguments manually since we receive already-sliced args
64
+ let projectId;
65
+ let force = false;
66
+ let apiUrl = process.env.SPEKN_API_URL ?? "https://app.spekn.com";
67
+ for (let i = 0; i < args.length; i++) {
68
+ const arg = args[i];
69
+ if (arg === "--help" || arg === "-h") {
70
+ printHelp();
71
+ return 0;
72
+ }
73
+ if (arg === "--force") {
74
+ force = true;
75
+ continue;
76
+ }
77
+ if (arg === "--api-url" && args[i + 1]) {
78
+ apiUrl = args[i + 1];
79
+ i++; // skip next arg
80
+ continue;
81
+ }
82
+ if (arg.startsWith("--api-url=")) {
83
+ apiUrl = arg.slice("--api-url=".length);
84
+ continue;
85
+ }
86
+ // Positional argument (project-id)
87
+ if (!projectId && !arg.startsWith("--")) {
88
+ projectId = arg;
89
+ continue;
90
+ }
91
+ }
92
+ // Validate required arguments
93
+ if (!projectId) {
94
+ console.error("Error: Missing required argument <project-id>");
95
+ printHelp();
96
+ return 1;
97
+ }
98
+ try {
99
+ // Add confirmation prompt unless --force is used
100
+ if (!force) {
101
+ // Note: In a real implementation, we would use a proper prompt library
102
+ // For now, we'll proceed without confirmation to keep it simple
103
+ console.log(`🚨 Warning: This will permanently delete project ${projectId} and all related data.`);
104
+ console.log(`📝 Related entities that will be deleted: git repositories, specifications, tasks, decisions, runs, verifications, notes, worktrees, merge requests`);
105
+ console.log(`🔥 This action cannot be undone.`);
106
+ // TODO: Add proper interactive confirmation
107
+ // const confirmed = await confirm("Are you sure you want to continue? (y/N)");
108
+ // if (!confirmed) {
109
+ // console.log("💡 Deletion cancelled.");
110
+ // return 0;
111
+ // }
112
+ }
113
+ await deleteProject(projectId, apiUrl);
114
+ return 0;
115
+ }
116
+ catch (error) {
117
+ console.error("Error:", error instanceof Error ? error.message : String(error));
118
+ return 1;
119
+ }
120
+ }
121
+ if (require.main === module) {
122
+ runProjectDeleteCli(process.argv.slice(2)).catch((err) => {
123
+ console.error(err);
124
+ process.exit(1);
125
+ });
126
+ }
@@ -0,0 +1,99 @@
1
+ export interface ProjectContextData {
2
+ projectId?: string;
3
+ organizationId?: string;
4
+ updatedAt?: string;
5
+ }
6
+ /** Enhanced global context with multi-project support */
7
+ export interface GlobalContextData {
8
+ /** Default organization for new projects */
9
+ defaultOrganizationId?: string;
10
+ /** List of projects the user has worked with */
11
+ projects?: Array<{
12
+ id: string;
13
+ name?: string;
14
+ organizationId: string;
15
+ lastUsed: string;
16
+ repoPaths: string[];
17
+ repoSync?: {
18
+ checkpoints?: Record<string, {
19
+ lastHeadCommit?: string;
20
+ syncedAt?: string;
21
+ }>;
22
+ };
23
+ }>;
24
+ /** Last used project ID for smart defaults */
25
+ lastUsedProjectId?: string;
26
+ /** User preferences */
27
+ preferences?: {
28
+ defaultAgent?: string;
29
+ defaultFormat?: string;
30
+ };
31
+ /** When the global context was last updated */
32
+ updatedAt?: string;
33
+ /** Repo sync metadata keyed by absolute repo path */
34
+ repoSync?: {
35
+ checkpoints?: Record<string, {
36
+ lastHeadCommit?: string;
37
+ syncedAt?: string;
38
+ }>;
39
+ };
40
+ }
41
+ export interface ResolvedProjectContext {
42
+ projectId: string;
43
+ organizationId: string;
44
+ }
45
+ export declare function findNearestLocalContextFile(startDir?: string): string | null;
46
+ export declare function loadLocalContext(repoPath?: string): ProjectContextData | null;
47
+ export declare function loadGlobalContext(): GlobalContextData | null;
48
+ export declare function resolveProjectContext(input: {
49
+ explicitProjectId?: string;
50
+ explicitOrganizationId?: string;
51
+ repoPath?: string;
52
+ credentialsOrganizationId?: string;
53
+ envOrganizationId?: string;
54
+ }): ResolvedProjectContext;
55
+ /** Get the most recently used project from global context */
56
+ export declare function getLastUsedProject(): {
57
+ projectId: string;
58
+ organizationId: string;
59
+ } | null;
60
+ /** List all recent projects from global context */
61
+ export declare function listRecentProjects(): Array<{
62
+ id: string;
63
+ name?: string;
64
+ organizationId: string;
65
+ lastUsed: string;
66
+ repoPaths: string[];
67
+ }>;
68
+ /** Set the last used project in global context */
69
+ export declare function setLastUsedProject(projectId: string): void;
70
+ /** Get project by ID from global context */
71
+ export declare function getProjectFromGlobalContext(projectId: string): {
72
+ id: string;
73
+ name?: string;
74
+ organizationId: string;
75
+ lastUsed: string;
76
+ repoPaths: string[];
77
+ } | null;
78
+ export declare function saveLocalContext(repoPath: string, context: {
79
+ projectId: string;
80
+ organizationId?: string;
81
+ }): void;
82
+ export declare function saveGlobalContext(context: GlobalContextData): void;
83
+ /** Add or update a project in the global context history */
84
+ export declare function addProjectToGlobalContext(projectId: string, organizationId: string, repoPath: string): void;
85
+ export declare function ensureGitignoreHasSpekn(repoPath: string): void;
86
+ export declare function persistProjectContext(repoPath: string, context: {
87
+ projectId: string;
88
+ organizationId?: string;
89
+ }): void;
90
+ export declare function persistProjectContextWithoutRepoPath(repoPath: string, context: {
91
+ projectId: string;
92
+ organizationId?: string;
93
+ }): void;
94
+ export declare function clearRepoFromGlobalContext(repoPath: string, projectId?: string): {
95
+ removedProjectRefs: number;
96
+ removedSyncCheckpoints: number;
97
+ removedProjects: number;
98
+ clearedLastUsedProjectId: boolean;
99
+ };