1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::*;
use carryctx::application;
use carryctx::application::runtime::InvocationContext;
use carryctx::error::ExitCode;
use clap::Parser;
// ── Init ─────────────────────────────────────────────────────────────────
#[derive(Parser, Debug)]
pub struct InitArgs {
/// Provide a custom name for the new project. Defaults to the directory name.
#[arg(long)]
pub name: Option<String>,
/// Task prefix identifier for issue tracking (e.g., 'PROJ' for tasks like 'PROJ-123').
#[arg(long)]
pub task_prefix: Option<String>,
/// Set the main/default branch name for Git (e.g., 'main' or 'master').
#[arg(long)]
pub main_branch: Option<String>,
/// Force initialization even if the directory already contains a .carryctx folder.
#[arg(long)]
pub force: bool,
/// Create a minimal setup without adding standard documentation and agent templates.
#[arg(long)]
pub minimal: bool,
/// Automatically install standard agent skills during initialization.
#[arg(long)]
pub install_skill: bool,
}
// ═══════════════════════════════════════════════════════════════════════════
// Handler: init
// ═══════════════════════════════════════════════════════════════════════════
pub fn handle_init(args: &InitArgs, ctx: &InvocationContext) -> Result<ExitCode, ExitCode> {
let work_dir = resolve_work_dir(ctx);
if ctx.dry_run {
println!(
"[dry-run] Would initialize CarryCtx at {}",
work_dir.display()
);
return Ok(ExitCode::Success);
}
let result = application::init::init_project(
work_dir,
args.name.as_deref(),
args.task_prefix.as_deref(),
args.force,
);
render_and_print("init", result, false, ctx.quiet)
}