@generacy-ai/generacy 0.0.0-preview-20260304013206
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/LICENSE +191 -0
- package/README.md +207 -0
- package/bin/generacy.js +11 -0
- package/dist/agency/index.d.ts +68 -0
- package/dist/agency/index.d.ts.map +1 -0
- package/dist/agency/index.js +28 -0
- package/dist/agency/index.js.map +1 -0
- package/dist/agency/network.d.ts +41 -0
- package/dist/agency/network.d.ts.map +1 -0
- package/dist/agency/network.js +133 -0
- package/dist/agency/network.js.map +1 -0
- package/dist/agency/subprocess.d.ts +58 -0
- package/dist/agency/subprocess.d.ts.map +1 -0
- package/dist/agency/subprocess.js +216 -0
- package/dist/agency/subprocess.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +10 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +216 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.js +51 -0
- package/dist/cli/commands/doctor/checks/agency-mcp.js.map +1 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.js +68 -0
- package/dist/cli/commands/doctor/checks/anthropic-key.js.map +1 -0
- package/dist/cli/commands/doctor/checks/config.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/config.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/config.js +81 -0
- package/dist/cli/commands/doctor/checks/config.js.map +1 -0
- package/dist/cli/commands/doctor/checks/devcontainer.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/devcontainer.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/devcontainer.js +58 -0
- package/dist/cli/commands/doctor/checks/devcontainer.js.map +1 -0
- package/dist/cli/commands/doctor/checks/docker.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/docker.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/docker.js +71 -0
- package/dist/cli/commands/doctor/checks/docker.js.map +1 -0
- package/dist/cli/commands/doctor/checks/env-file.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/env-file.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/env-file.js +56 -0
- package/dist/cli/commands/doctor/checks/env-file.js.map +1 -0
- package/dist/cli/commands/doctor/checks/github-token.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/github-token.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/github-token.js +99 -0
- package/dist/cli/commands/doctor/checks/github-token.js.map +1 -0
- package/dist/cli/commands/doctor/checks/npm-packages.d.ts +3 -0
- package/dist/cli/commands/doctor/checks/npm-packages.d.ts.map +1 -0
- package/dist/cli/commands/doctor/checks/npm-packages.js +117 -0
- package/dist/cli/commands/doctor/checks/npm-packages.js.map +1 -0
- package/dist/cli/commands/doctor/formatter.d.ts +27 -0
- package/dist/cli/commands/doctor/formatter.d.ts.map +1 -0
- package/dist/cli/commands/doctor/formatter.js +162 -0
- package/dist/cli/commands/doctor/formatter.js.map +1 -0
- package/dist/cli/commands/doctor/index.d.ts +5 -0
- package/dist/cli/commands/doctor/index.d.ts.map +1 -0
- package/dist/cli/commands/doctor/index.js +8 -0
- package/dist/cli/commands/doctor/index.js.map +1 -0
- package/dist/cli/commands/doctor/registry.d.ts +48 -0
- package/dist/cli/commands/doctor/registry.d.ts.map +1 -0
- package/dist/cli/commands/doctor/registry.js +166 -0
- package/dist/cli/commands/doctor/registry.js.map +1 -0
- package/dist/cli/commands/doctor/runner.d.ts +14 -0
- package/dist/cli/commands/doctor/runner.d.ts.map +1 -0
- package/dist/cli/commands/doctor/runner.js +257 -0
- package/dist/cli/commands/doctor/runner.js.map +1 -0
- package/dist/cli/commands/doctor/types.d.ts +87 -0
- package/dist/cli/commands/doctor/types.d.ts.map +1 -0
- package/dist/cli/commands/doctor/types.js +2 -0
- package/dist/cli/commands/doctor/types.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +12 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +97 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init/conflicts.d.ts +36 -0
- package/dist/cli/commands/init/conflicts.d.ts.map +1 -0
- package/dist/cli/commands/init/conflicts.js +165 -0
- package/dist/cli/commands/init/conflicts.js.map +1 -0
- package/dist/cli/commands/init/github.d.ts +32 -0
- package/dist/cli/commands/init/github.d.ts.map +1 -0
- package/dist/cli/commands/init/github.js +161 -0
- package/dist/cli/commands/init/github.js.map +1 -0
- package/dist/cli/commands/init/index.d.ts +21 -0
- package/dist/cli/commands/init/index.d.ts.map +1 -0
- package/dist/cli/commands/init/index.js +175 -0
- package/dist/cli/commands/init/index.js.map +1 -0
- package/dist/cli/commands/init/prompts.d.ts +15 -0
- package/dist/cli/commands/init/prompts.d.ts.map +1 -0
- package/dist/cli/commands/init/prompts.js +281 -0
- package/dist/cli/commands/init/prompts.js.map +1 -0
- package/dist/cli/commands/init/repo-utils.d.ts +32 -0
- package/dist/cli/commands/init/repo-utils.d.ts.map +1 -0
- package/dist/cli/commands/init/repo-utils.js +112 -0
- package/dist/cli/commands/init/repo-utils.js.map +1 -0
- package/dist/cli/commands/init/resolver.d.ts +20 -0
- package/dist/cli/commands/init/resolver.d.ts.map +1 -0
- package/dist/cli/commands/init/resolver.js +273 -0
- package/dist/cli/commands/init/resolver.js.map +1 -0
- package/dist/cli/commands/init/summary.d.ts +21 -0
- package/dist/cli/commands/init/summary.d.ts.map +1 -0
- package/dist/cli/commands/init/summary.js +100 -0
- package/dist/cli/commands/init/summary.js.map +1 -0
- package/dist/cli/commands/init/types.d.ts +53 -0
- package/dist/cli/commands/init/types.d.ts.map +1 -0
- package/dist/cli/commands/init/types.js +2 -0
- package/dist/cli/commands/init/types.js.map +1 -0
- package/dist/cli/commands/init/writer.d.ts +22 -0
- package/dist/cli/commands/init/writer.d.ts.map +1 -0
- package/dist/cli/commands/init/writer.js +96 -0
- package/dist/cli/commands/init/writer.js.map +1 -0
- package/dist/cli/commands/orchestrator.d.ts +11 -0
- package/dist/cli/commands/orchestrator.d.ts.map +1 -0
- package/dist/cli/commands/orchestrator.js +291 -0
- package/dist/cli/commands/orchestrator.js.map +1 -0
- package/dist/cli/commands/run.d.ts +10 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +167 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/setup/auth.d.ts +11 -0
- package/dist/cli/commands/setup/auth.d.ts.map +1 -0
- package/dist/cli/commands/setup/auth.js +108 -0
- package/dist/cli/commands/setup/auth.js.map +1 -0
- package/dist/cli/commands/setup/build.d.ts +11 -0
- package/dist/cli/commands/setup/build.d.ts.map +1 -0
- package/dist/cli/commands/setup/build.js +212 -0
- package/dist/cli/commands/setup/build.js.map +1 -0
- package/dist/cli/commands/setup/services.d.ts +11 -0
- package/dist/cli/commands/setup/services.d.ts.map +1 -0
- package/dist/cli/commands/setup/services.js +294 -0
- package/dist/cli/commands/setup/services.js.map +1 -0
- package/dist/cli/commands/setup/workspace.d.ts +11 -0
- package/dist/cli/commands/setup/workspace.d.ts.map +1 -0
- package/dist/cli/commands/setup/workspace.js +215 -0
- package/dist/cli/commands/setup/workspace.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +7 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +19 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +10 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +164 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/worker.d.ts +10 -0
- package/dist/cli/commands/worker.d.ts.map +1 -0
- package/dist/cli/commands/worker.js +224 -0
- package/dist/cli/commands/worker.js.map +1 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +68 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +49 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +110 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/exec.d.ts +39 -0
- package/dist/cli/utils/exec.d.ts.map +1 -0
- package/dist/cli/utils/exec.js +68 -0
- package/dist/cli/utils/exec.js.map +1 -0
- package/dist/cli/utils/logger.d.ts +47 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/cli/utils/logger.js +97 -0
- package/dist/cli/utils/logger.js.map +1 -0
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +13 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +104 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +266 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +304 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +160 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/validator.d.ts +60 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +112 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/health/server.d.ts +47 -0
- package/dist/health/server.d.ts.map +1 -0
- package/dist/health/server.js +92 -0
- package/dist/health/server.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/async-event-queue.d.ts +28 -0
- package/dist/orchestrator/async-event-queue.d.ts.map +1 -0
- package/dist/orchestrator/async-event-queue.js +57 -0
- package/dist/orchestrator/async-event-queue.js.map +1 -0
- package/dist/orchestrator/client.d.ts +110 -0
- package/dist/orchestrator/client.d.ts.map +1 -0
- package/dist/orchestrator/client.js +288 -0
- package/dist/orchestrator/client.js.map +1 -0
- package/dist/orchestrator/event-bus.d.ts +195 -0
- package/dist/orchestrator/event-bus.d.ts.map +1 -0
- package/dist/orchestrator/event-bus.js +557 -0
- package/dist/orchestrator/event-bus.js.map +1 -0
- package/dist/orchestrator/heartbeat.d.ts +71 -0
- package/dist/orchestrator/heartbeat.d.ts.map +1 -0
- package/dist/orchestrator/heartbeat.js +116 -0
- package/dist/orchestrator/heartbeat.js.map +1 -0
- package/dist/orchestrator/index.d.ts +25 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +15 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/job-handler.d.ts +109 -0
- package/dist/orchestrator/job-handler.d.ts.map +1 -0
- package/dist/orchestrator/job-handler.js +612 -0
- package/dist/orchestrator/job-handler.js.map +1 -0
- package/dist/orchestrator/job-queue.d.ts +81 -0
- package/dist/orchestrator/job-queue.d.ts.map +1 -0
- package/dist/orchestrator/job-queue.js +206 -0
- package/dist/orchestrator/job-queue.js.map +1 -0
- package/dist/orchestrator/label-monitor-bridge.d.ts +25 -0
- package/dist/orchestrator/label-monitor-bridge.d.ts.map +1 -0
- package/dist/orchestrator/label-monitor-bridge.js +57 -0
- package/dist/orchestrator/label-monitor-bridge.js.map +1 -0
- package/dist/orchestrator/log-buffer.d.ts +74 -0
- package/dist/orchestrator/log-buffer.d.ts.map +1 -0
- package/dist/orchestrator/log-buffer.js +104 -0
- package/dist/orchestrator/log-buffer.js.map +1 -0
- package/dist/orchestrator/redis-job-queue.d.ts +44 -0
- package/dist/orchestrator/redis-job-queue.d.ts.map +1 -0
- package/dist/orchestrator/redis-job-queue.js +300 -0
- package/dist/orchestrator/redis-job-queue.js.map +1 -0
- package/dist/orchestrator/router.d.ts +125 -0
- package/dist/orchestrator/router.d.ts.map +1 -0
- package/dist/orchestrator/router.js +143 -0
- package/dist/orchestrator/router.js.map +1 -0
- package/dist/orchestrator/server.d.ts +62 -0
- package/dist/orchestrator/server.d.ts.map +1 -0
- package/dist/orchestrator/server.js +711 -0
- package/dist/orchestrator/server.js.map +1 -0
- package/dist/orchestrator/types.d.ts +184 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +6 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/orchestrator/worker-registry.d.ts +110 -0
- package/dist/orchestrator/worker-registry.d.ts.map +1 -0
- package/dist/orchestrator/worker-registry.js +191 -0
- package/dist/orchestrator/worker-registry.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive prompt flow for `generacy init`.
|
|
3
|
+
*
|
|
4
|
+
* Uses `@clack/prompts` to collect project details from the user.
|
|
5
|
+
* Prompts are skipped when the corresponding value is already provided
|
|
6
|
+
* via CLI flags (passed in as `defaults`). If a `.generacy/config.yaml`
|
|
7
|
+
* already exists the loaded values are used as initial/default values
|
|
8
|
+
* in prompts (re-init flow).
|
|
9
|
+
*/
|
|
10
|
+
import * as p from '@clack/prompts';
|
|
11
|
+
import { basename } from 'node:path';
|
|
12
|
+
import { loadConfig } from '../../../config/index.js';
|
|
13
|
+
import { getLogger } from '../../utils/logger.js';
|
|
14
|
+
import { parseRepoUrl, toShorthand, normalizeRepoUrl } from './repo-utils.js';
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Helpers
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Guard: exit with code 130 if the user cancelled a prompt.
|
|
20
|
+
*/
|
|
21
|
+
function exitIfCancelled(value) {
|
|
22
|
+
if (p.isCancel(value)) {
|
|
23
|
+
p.cancel('Operation cancelled.');
|
|
24
|
+
process.exit(130);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Convert a `github.com/owner/repo` config-format string to `owner/repo`
|
|
29
|
+
* shorthand for display in prompts. Returns the input unchanged if parsing
|
|
30
|
+
* fails (defensive — should not happen with validated config).
|
|
31
|
+
*/
|
|
32
|
+
function configRepoToShorthand(configUrl) {
|
|
33
|
+
try {
|
|
34
|
+
const parsed = parseRepoUrl(configUrl);
|
|
35
|
+
return toShorthand(parsed);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return configUrl;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Validate a repo URL entered at a prompt.
|
|
43
|
+
* Returns `undefined` on success, or an error message string on failure.
|
|
44
|
+
*/
|
|
45
|
+
function validateRepoInput(value) {
|
|
46
|
+
if (!value.trim())
|
|
47
|
+
return undefined; // empty is allowed for optional fields
|
|
48
|
+
try {
|
|
49
|
+
parseRepoUrl(value);
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return err instanceof Error ? err.message : 'Invalid repository URL';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse a comma-separated list of repo URLs.
|
|
58
|
+
* Returns validated `owner/repo` shorthand strings.
|
|
59
|
+
* Throws on the first invalid entry.
|
|
60
|
+
*/
|
|
61
|
+
function parseRepoList(input) {
|
|
62
|
+
if (!input.trim())
|
|
63
|
+
return [];
|
|
64
|
+
return input
|
|
65
|
+
.split(',')
|
|
66
|
+
.map((s) => s.trim())
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.map((raw) => normalizeRepoUrl(raw).shorthand);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validate a comma-separated list of repo URLs.
|
|
72
|
+
* Returns `undefined` on success, or the first error message on failure.
|
|
73
|
+
*/
|
|
74
|
+
function validateRepoList(value) {
|
|
75
|
+
if (!value.trim())
|
|
76
|
+
return undefined;
|
|
77
|
+
const entries = value.split(',').map((s) => s.trim()).filter(Boolean);
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
try {
|
|
80
|
+
parseRepoUrl(entry);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return err instanceof Error ? err.message : `Invalid repository URL: ${entry}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Attempt to load an existing `.generacy/config.yaml` and extract values
|
|
90
|
+
* to use as defaults in the interactive prompt flow.
|
|
91
|
+
* Returns an empty object if no config exists or if loading fails.
|
|
92
|
+
*/
|
|
93
|
+
function loadExistingConfigDefaults(gitRoot) {
|
|
94
|
+
const logger = getLogger();
|
|
95
|
+
try {
|
|
96
|
+
const config = loadConfig({ startDir: gitRoot });
|
|
97
|
+
const defaults = {
|
|
98
|
+
projectId: config.project.id,
|
|
99
|
+
projectName: config.project.name,
|
|
100
|
+
primaryRepo: configRepoToShorthand(config.repos.primary),
|
|
101
|
+
agent: config.defaults?.agent,
|
|
102
|
+
baseBranch: config.defaults?.baseBranch,
|
|
103
|
+
};
|
|
104
|
+
if (config.repos.dev && config.repos.dev.length > 0) {
|
|
105
|
+
defaults.devRepos = config.repos.dev.map(configRepoToShorthand);
|
|
106
|
+
}
|
|
107
|
+
if (config.repos.clone && config.repos.clone.length > 0) {
|
|
108
|
+
defaults.cloneRepos = config.repos.clone.map(configRepoToShorthand);
|
|
109
|
+
}
|
|
110
|
+
if (config.cluster?.variant) {
|
|
111
|
+
defaults.variant = config.cluster.variant;
|
|
112
|
+
}
|
|
113
|
+
logger.debug({ defaults }, 'Loaded existing config defaults for re-init');
|
|
114
|
+
return defaults;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// No config or invalid — start fresh
|
|
118
|
+
logger.debug('No existing config found or config is invalid — starting fresh');
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Public API
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
/**
|
|
126
|
+
* Run the interactive prompt flow using `@clack/prompts`.
|
|
127
|
+
*
|
|
128
|
+
* @param defaults - Partial options already provided via CLI flags or
|
|
129
|
+
* auto-detection. Values present in `defaults` skip the corresponding
|
|
130
|
+
* prompt.
|
|
131
|
+
* @param gitRoot - Absolute path to the git repository root. Used to
|
|
132
|
+
* derive the default project name and to load an existing config.
|
|
133
|
+
* @returns Partial options collected from the user. The resolver merges
|
|
134
|
+
* these with flags and auto-detected values to produce a complete
|
|
135
|
+
* `InitOptions`.
|
|
136
|
+
*/
|
|
137
|
+
export async function runInteractivePrompts(defaults, gitRoot) {
|
|
138
|
+
// Merge existing config values as fallback defaults
|
|
139
|
+
const existing = loadExistingConfigDefaults(gitRoot);
|
|
140
|
+
const result = {};
|
|
141
|
+
// ── Intro ──────────────────────────────────────────────────────────────
|
|
142
|
+
p.intro('generacy init');
|
|
143
|
+
// ── Cluster variant ─────────────────────────────────────────────────────
|
|
144
|
+
if (defaults.variant !== undefined) {
|
|
145
|
+
result.variant = defaults.variant;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const defaultVariant = existing.variant ?? 'standard';
|
|
149
|
+
const variant = await p.select({
|
|
150
|
+
message: 'Cluster variant',
|
|
151
|
+
options: [
|
|
152
|
+
{
|
|
153
|
+
value: 'standard',
|
|
154
|
+
label: 'Standard (DooD)',
|
|
155
|
+
hint: 'Docker-outside-of-Docker — for apps that don\'t run containers',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
value: 'microservices',
|
|
159
|
+
label: 'Microservices (DinD)',
|
|
160
|
+
hint: 'Docker-in-Docker — each worker runs isolated container stacks',
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
initialValue: defaultVariant,
|
|
164
|
+
});
|
|
165
|
+
exitIfCancelled(variant);
|
|
166
|
+
result.variant = variant;
|
|
167
|
+
}
|
|
168
|
+
// ── Project name ───────────────────────────────────────────────────────
|
|
169
|
+
if (defaults.projectName !== undefined) {
|
|
170
|
+
result.projectName = defaults.projectName;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const defaultName = existing.projectName ?? basename(gitRoot);
|
|
174
|
+
const projectName = await p.text({
|
|
175
|
+
message: 'Project name',
|
|
176
|
+
placeholder: defaultName,
|
|
177
|
+
initialValue: defaultName,
|
|
178
|
+
validate(value) {
|
|
179
|
+
if (!value.trim())
|
|
180
|
+
return 'Project name cannot be empty';
|
|
181
|
+
if (value.length > 255)
|
|
182
|
+
return 'Project name cannot exceed 255 characters';
|
|
183
|
+
return undefined;
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
exitIfCancelled(projectName);
|
|
187
|
+
result.projectName = projectName.trim();
|
|
188
|
+
}
|
|
189
|
+
// ── Primary repo ───────────────────────────────────────────────────────
|
|
190
|
+
if (defaults.primaryRepo !== undefined) {
|
|
191
|
+
result.primaryRepo = defaults.primaryRepo;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
const defaultRepo = existing.primaryRepo ?? '';
|
|
195
|
+
const primaryRepo = await p.text({
|
|
196
|
+
message: 'Primary repository (owner/repo)',
|
|
197
|
+
placeholder: 'github.com/owner/repo',
|
|
198
|
+
initialValue: defaultRepo,
|
|
199
|
+
validate(value) {
|
|
200
|
+
if (!value.trim())
|
|
201
|
+
return 'Primary repository is required';
|
|
202
|
+
return validateRepoInput(value);
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
exitIfCancelled(primaryRepo);
|
|
206
|
+
result.primaryRepo = normalizeRepoUrl(primaryRepo.trim()).shorthand;
|
|
207
|
+
}
|
|
208
|
+
// ── Dev repos ──────────────────────────────────────────────────────────
|
|
209
|
+
if (defaults.devRepos !== undefined) {
|
|
210
|
+
result.devRepos = defaults.devRepos;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const defaultDevRepos = existing.devRepos?.join(', ') ?? '';
|
|
214
|
+
const devReposInput = await p.text({
|
|
215
|
+
message: 'Development repositories (comma-separated, or leave empty)',
|
|
216
|
+
placeholder: 'owner/repo-a, owner/repo-b',
|
|
217
|
+
initialValue: defaultDevRepos,
|
|
218
|
+
validate: validateRepoList,
|
|
219
|
+
});
|
|
220
|
+
exitIfCancelled(devReposInput);
|
|
221
|
+
result.devRepos = parseRepoList(devReposInput);
|
|
222
|
+
}
|
|
223
|
+
// ── Clone repos ────────────────────────────────────────────────────────
|
|
224
|
+
// Only prompt for clone repos if dev repos were provided (multi-repo flow)
|
|
225
|
+
const hasDevRepos = (result.devRepos ?? []).length > 0;
|
|
226
|
+
if (defaults.cloneRepos !== undefined) {
|
|
227
|
+
result.cloneRepos = defaults.cloneRepos;
|
|
228
|
+
}
|
|
229
|
+
else if (hasDevRepos) {
|
|
230
|
+
const defaultCloneRepos = existing.cloneRepos?.join(', ') ?? '';
|
|
231
|
+
const cloneReposInput = await p.text({
|
|
232
|
+
message: 'Clone-only repositories (comma-separated, or leave empty)',
|
|
233
|
+
placeholder: 'owner/repo-c, owner/repo-d',
|
|
234
|
+
initialValue: defaultCloneRepos,
|
|
235
|
+
validate: validateRepoList,
|
|
236
|
+
});
|
|
237
|
+
exitIfCancelled(cloneReposInput);
|
|
238
|
+
result.cloneRepos = parseRepoList(cloneReposInput);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
result.cloneRepos = [];
|
|
242
|
+
}
|
|
243
|
+
// ── Agent ──────────────────────────────────────────────────────────────
|
|
244
|
+
if (defaults.agent !== undefined) {
|
|
245
|
+
result.agent = defaults.agent;
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const defaultAgent = existing.agent ?? 'claude-code';
|
|
249
|
+
const agent = await p.select({
|
|
250
|
+
message: 'Default agent',
|
|
251
|
+
options: [
|
|
252
|
+
{ value: 'claude-code', label: 'Claude Code', hint: 'Anthropic Claude agent' },
|
|
253
|
+
{ value: 'cursor-agent', label: 'Cursor Agent', hint: 'Cursor IDE agent' },
|
|
254
|
+
],
|
|
255
|
+
initialValue: defaultAgent,
|
|
256
|
+
});
|
|
257
|
+
exitIfCancelled(agent);
|
|
258
|
+
result.agent = agent;
|
|
259
|
+
}
|
|
260
|
+
// ── Base branch ────────────────────────────────────────────────────────
|
|
261
|
+
if (defaults.baseBranch !== undefined) {
|
|
262
|
+
result.baseBranch = defaults.baseBranch;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
const defaultBranch = existing.baseBranch ?? 'main';
|
|
266
|
+
const baseBranch = await p.text({
|
|
267
|
+
message: 'Default base branch',
|
|
268
|
+
placeholder: defaultBranch,
|
|
269
|
+
initialValue: defaultBranch,
|
|
270
|
+
validate(value) {
|
|
271
|
+
if (!value.trim())
|
|
272
|
+
return 'Base branch cannot be empty';
|
|
273
|
+
return undefined;
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
exitIfCancelled(baseBranch);
|
|
277
|
+
result.baseBranch = baseBranch.trim();
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../../src/cli/commands/init/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ParsedRepo {
|
|
2
|
+
owner: string;
|
|
3
|
+
repo: string;
|
|
4
|
+
}
|
|
5
|
+
export interface NormalizedRepo {
|
|
6
|
+
/** `owner/repo` format — used by templates */
|
|
7
|
+
shorthand: string;
|
|
8
|
+
/** `github.com/owner/repo` format — used by config schema */
|
|
9
|
+
configFormat: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Parse a repo URL in any supported format into `{ owner, repo }`.
|
|
13
|
+
* Throws a descriptive error if the format is unrecognizable.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseRepoUrl(input: string): ParsedRepo;
|
|
16
|
+
/** Returns `owner/repo` — the shorthand format used by templates. */
|
|
17
|
+
export declare function toShorthand(parsed: ParsedRepo): string;
|
|
18
|
+
/** Returns `github.com/owner/repo` — the format used in config schema. */
|
|
19
|
+
export declare function toConfigFormat(parsed: ParsedRepo): string;
|
|
20
|
+
/** Parse any supported repo URL and return both shorthand and config formats. */
|
|
21
|
+
export declare function normalizeRepoUrl(input: string): NormalizedRepo;
|
|
22
|
+
/**
|
|
23
|
+
* Detect the primary repository from the `origin` remote.
|
|
24
|
+
* Returns normalized `owner/repo` shorthand, or `null` if not detectable.
|
|
25
|
+
*/
|
|
26
|
+
export declare function detectPrimaryRepo(cwd: string): string | null;
|
|
27
|
+
/**
|
|
28
|
+
* Detect the git repository root directory.
|
|
29
|
+
* Returns the absolute path, or `null` if not inside a git repo.
|
|
30
|
+
*/
|
|
31
|
+
export declare function detectGitRoot(cwd: string): string | null;
|
|
32
|
+
//# sourceMappingURL=repo-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-utils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/repo-utils.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;CACtB;AAsBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAmCtD;AAMD,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAEtD;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAEzD;AAMD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAM9D;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxD"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo URL parsing, normalization, and auto-detection utilities.
|
|
3
|
+
*
|
|
4
|
+
* Handles all common GitHub repo URL formats:
|
|
5
|
+
* - owner/repo (shorthand)
|
|
6
|
+
* - github.com/owner/repo (no protocol)
|
|
7
|
+
* - https://github.com/owner/repo (HTTPS)
|
|
8
|
+
* - https://github.com/owner/repo.git (HTTPS with .git)
|
|
9
|
+
* - git@github.com:owner/repo.git (SSH)
|
|
10
|
+
*/
|
|
11
|
+
import { execSafe } from '../../utils/exec.js';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Patterns
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/** SSH format: git@github.com:owner/repo.git */
|
|
16
|
+
const SSH_RE = /^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/;
|
|
17
|
+
/** HTTPS format: https://github.com/owner/repo[.git] */
|
|
18
|
+
const HTTPS_RE = /^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/;
|
|
19
|
+
/** Bare domain: github.com/owner/repo */
|
|
20
|
+
const BARE_DOMAIN_RE = /^github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/;
|
|
21
|
+
/** Shorthand: owner/repo (no dots, no colons, no slashes beyond the one) */
|
|
22
|
+
const SHORTHAND_RE = /^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/;
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Parsing
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/**
|
|
27
|
+
* Parse a repo URL in any supported format into `{ owner, repo }`.
|
|
28
|
+
* Throws a descriptive error if the format is unrecognizable.
|
|
29
|
+
*/
|
|
30
|
+
export function parseRepoUrl(input) {
|
|
31
|
+
const trimmed = input.trim();
|
|
32
|
+
if (!trimmed) {
|
|
33
|
+
throw new Error('Repository URL cannot be empty');
|
|
34
|
+
}
|
|
35
|
+
// Try SSH first (git@github.com:owner/repo.git)
|
|
36
|
+
let match = SSH_RE.exec(trimmed);
|
|
37
|
+
if (match) {
|
|
38
|
+
return { owner: match[1], repo: match[2] };
|
|
39
|
+
}
|
|
40
|
+
// Try HTTPS (https://github.com/owner/repo[.git])
|
|
41
|
+
match = HTTPS_RE.exec(trimmed);
|
|
42
|
+
if (match) {
|
|
43
|
+
return { owner: match[1], repo: match[2] };
|
|
44
|
+
}
|
|
45
|
+
// Try bare domain (github.com/owner/repo)
|
|
46
|
+
match = BARE_DOMAIN_RE.exec(trimmed);
|
|
47
|
+
if (match) {
|
|
48
|
+
return { owner: match[1], repo: match[2] };
|
|
49
|
+
}
|
|
50
|
+
// Try shorthand (owner/repo)
|
|
51
|
+
match = SHORTHAND_RE.exec(trimmed);
|
|
52
|
+
if (match) {
|
|
53
|
+
return { owner: match[1], repo: match[2] };
|
|
54
|
+
}
|
|
55
|
+
throw new Error(`Unrecognized repository format: "${trimmed}". ` +
|
|
56
|
+
'Expected one of: owner/repo, github.com/owner/repo, ' +
|
|
57
|
+
'https://github.com/owner/repo, or git@github.com:owner/repo.git');
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Formatting
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
/** Returns `owner/repo` — the shorthand format used by templates. */
|
|
63
|
+
export function toShorthand(parsed) {
|
|
64
|
+
return `${parsed.owner}/${parsed.repo}`;
|
|
65
|
+
}
|
|
66
|
+
/** Returns `github.com/owner/repo` — the format used in config schema. */
|
|
67
|
+
export function toConfigFormat(parsed) {
|
|
68
|
+
return `github.com/${parsed.owner}/${parsed.repo}`;
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Combined normalize
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
/** Parse any supported repo URL and return both shorthand and config formats. */
|
|
74
|
+
export function normalizeRepoUrl(input) {
|
|
75
|
+
const parsed = parseRepoUrl(input);
|
|
76
|
+
return {
|
|
77
|
+
shorthand: toShorthand(parsed),
|
|
78
|
+
configFormat: toConfigFormat(parsed),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Git auto-detection
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
/**
|
|
85
|
+
* Detect the primary repository from the `origin` remote.
|
|
86
|
+
* Returns normalized `owner/repo` shorthand, or `null` if not detectable.
|
|
87
|
+
*/
|
|
88
|
+
export function detectPrimaryRepo(cwd) {
|
|
89
|
+
const result = execSafe('git remote get-url origin', { cwd });
|
|
90
|
+
if (!result.ok || !result.stdout) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const parsed = parseRepoUrl(result.stdout);
|
|
95
|
+
return toShorthand(parsed);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Detect the git repository root directory.
|
|
103
|
+
* Returns the absolute path, or `null` if not inside a git repo.
|
|
104
|
+
*/
|
|
105
|
+
export function detectGitRoot(cwd) {
|
|
106
|
+
const result = execSafe('git rev-parse --show-toplevel', { cwd });
|
|
107
|
+
if (!result.ok || !result.stdout) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
return result.stdout;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=repo-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-utils.js","sourceRoot":"","sources":["../../../../src/cli/commands/init/repo-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { InitOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Error thrown when the resolver cannot produce valid `InitOptions`.
|
|
4
|
+
* Callers should catch this to display the message and exit with code 1.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ResolverError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a fully populated `InitOptions` from CLI flags, existing config,
|
|
11
|
+
* interactive prompts, auto-detection, and defaults.
|
|
12
|
+
*
|
|
13
|
+
* @param flags - Raw option values from Commander.js (`command.opts()`).
|
|
14
|
+
* @param gitRoot - Absolute path to the git repository root (already validated).
|
|
15
|
+
* @returns Fully resolved `InitOptions` — every field is concrete.
|
|
16
|
+
* @throws {ResolverError} If resolution fails (missing required values,
|
|
17
|
+
* invalid project ID, non-TTY without `--yes`, duplicate repos, etc.).
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveOptions(flags: Record<string, unknown>, gitRoot: string): Promise<InitOptions>;
|
|
20
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init/resolver.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkL9C;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAMD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CA2FtB"}
|