Skip to content

Commit

Permalink
feat: add project init
Browse files Browse the repository at this point in the history
  • Loading branch information
jahwag committed Dec 22, 2024
1 parent bdfdbef commit d575a70
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 41 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "claudesync"
version = "0.6.8"
version = "0.6.9"
authors = [
{name = "Jahziah Wagner", email = "[email protected]"},
]
Expand Down
103 changes: 69 additions & 34 deletions src/claudesync/cli/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def project():
@click.option(
"--name",
default=lambda: os.path.basename(os.getcwd()),
prompt="Enter a title for your new project",
prompt="Enter a title for your project",
help="The name of the project (defaults to current directory name)",
show_default="current directory name",
)
Expand All @@ -42,56 +42,91 @@ def project():
help="The local path for the project (defaults to current working directory)",
show_default="current working directory",
)
@click.option(
"--new",
is_flag=True,
help="Create a new remote project on Claude.ai",
)
@click.option(
"--provider",
prompt="Pick the provider to use for this project",
type=click.Choice(["claude.ai"], case_sensitive=False),
default="claude.ai",
help="The provider to use for this project",
)
@click.option(
"--organization",
default=None,
help="The organization ID to use for this project",
)
@click.pass_context
@handle_errors
def create(ctx, name, description, local_path, provider, organization):
"""Creates a new project for the selected provider."""
def init(ctx, name, description, local_path, new, provider):
"""Initialize a new project configuration.
If --new is specified, also creates a remote project on Claude.ai.
Otherwise, only creates the local configuration. Use 'claudesync organization set'
and 'claudesync project set' to link to an existing remote project."""

config = ctx.obj
provider_instance = get_provider(config, provider)

if organization is None:
# Create .claudesync directory and save initial config
claudesync_dir = os.path.join(local_path, ".claudesync")
os.makedirs(claudesync_dir, exist_ok=True)

# Set basic configuration
config.set("active_provider", provider, local=True)
config.set("local_path", local_path, local=True)

if new:
# Create remote project if --new flag is specified
provider_instance = get_provider(config, provider)

# Get organization
organizations = provider_instance.get_organizations()
organization_instance = organizations[0] if organizations else None
organization = organization_instance["id"]
if not organizations:
raise ConfigurationError(
"No organizations with required capabilities found."
)
organization = organizations[0]["id"]

try:
new_project = provider_instance.create_project(organization, name, description)
click.echo(
f"Project '{new_project['name']}' (uuid: {new_project['uuid']}) has been created successfully."
)
try:
new_project = provider_instance.create_project(
organization, name, description
)
click.echo(
f"Project '{new_project['name']}' (uuid: {new_project['uuid']}) has been created successfully."
)

# Update configuration
config.set("active_provider", provider, local=True)
config.set("active_organization_id", organization, local=True)
config.set("active_project_id", new_project["uuid"], local=True)
config.set("active_project_name", new_project["name"], local=True)
config.set("local_path", local_path, local=True)
# Update configuration with remote details
config.set("active_organization_id", organization, local=True)
config.set("active_project_id", new_project["uuid"], local=True)
config.set("active_project_name", new_project["name"], local=True)

# Create .claudesync directory and save config
claudesync_dir = os.path.join(local_path, ".claudesync")
os.makedirs(claudesync_dir, exist_ok=True)
config_file_path = os.path.join(claudesync_dir, "config.local.json")
config._save_local_config()
click.echo("\nProject created:")
click.echo(f" - Project location: {local_path}")
click.echo(
f" - Project config location: {os.path.join(claudesync_dir, 'config.local.json')}"
)
click.echo(
f" - Remote URL: https://claude.ai/project/{new_project['uuid']}"
)

click.echo("\nProject created:")
except (ProviderError, ConfigurationError) as e:
click.echo(f"Failed to create remote project: {str(e)}")
raise click.Abort()
else:
config._save_local_config()
click.echo("\nLocal project configuration created:")
click.echo(f" - Project location: {local_path}")
click.echo(f" - Project config location: {config_file_path}")
click.echo(f" - Remote URL: https://claude.ai/project/{new_project['uuid']}")
click.echo(
f" - Project config location: {os.path.join(claudesync_dir, 'config.local.json')}"
)
click.echo("\nTo link to a remote project:")
click.echo("1. Run 'claudesync organization set' to select an organization")
click.echo("2. Run 'claudesync project set' to select an existing project")


except (ProviderError, ConfigurationError) as e:
click.echo(f"Failed to create project: {str(e)}")
@project.command()
@click.pass_context
def create(ctx, **kwargs):
"""Create a new project (alias for 'init --new')."""
# Forward to init command with --new flag
ctx.forward(init, new=True)


@project.command()
Expand Down
7 changes: 4 additions & 3 deletions tests/test_chat_happy_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ def test_chat_happy_path(self):
self.assertEqual(result.exit_code, 0)
self.assertIn("Selected organization: Test Org 1", result.output)

# Step 3: Create project
# Step 3: Create project using init --new
result = self.runner.invoke(
cli,
[
"project",
"create",
"init",
"--new",
"--name",
"Test Project",
"--description",
Expand All @@ -56,7 +57,7 @@ def test_chat_happy_path(self):
)
self.assertEqual(result.exit_code, 0)
self.assertIn(
"Project 'New Project' (uuid: new_proj) has been created successfully.",
"Project 'New Project' (uuid: new_proj) has been created successfully",
result.output,
)

Expand Down
6 changes: 3 additions & 3 deletions tests/test_happy_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ def test_happy_path(self, mock_get_local_files):
self.assertEqual(0, result.exit_code)
self.assertIn("Successfully authenticated with claude.ai", result.output)

# Create project
# Create project using init --new
result = self.runner.invoke(
cli,
[
"project",
"create",
"init",
"--new",
"--name",
"New Project",
"--description",
Expand All @@ -57,7 +58,6 @@ def test_happy_path(self, mock_get_local_files):
obj=self.config,
)
self.assertEqual(result.exit_code, 0)

self.assertIn(
"Project 'New Project' (uuid: new_proj) has been created successfully",
result.output,
Expand Down

0 comments on commit d575a70

Please sign in to comment.