Skip to content

Commit ab3e2da

Browse files
Merge branch 'stage' into prod
2 parents 43a7232 + ed555ce commit ab3e2da

4 files changed

Lines changed: 114 additions & 3 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ __pycache__/
33
dist/
44
cli/.venv/
55
cli/build/
6-
cli/dist/
6+
cli/dist/
7+
tests/maxio/

cli/src/stacksync_cli/commands/login.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,39 @@
1616
)
1717

1818

19+
def _format_login_status(*, env: dict) -> str:
20+
token = env.get("user_api_key")
21+
workspaces = env.get("workspaces") or []
22+
default_workspace = env.get("default_workspace")
23+
24+
status = "Logged in" if token else "Not logged in"
25+
26+
if not token:
27+
return status
28+
29+
if workspaces and not default_workspace:
30+
status += " (no default workspace selected, will be prompted on first use of `stacksync create`)"
31+
elif not workspaces and not default_workspace:
32+
status += " (no workspaces found; no default workspace selected)"
33+
34+
return status
35+
36+
1937
@click.command()
20-
def login() -> None:
38+
@click.option(
39+
"--check",
40+
is_flag=True,
41+
help='Print login status ("Logged in" / "Not logged in") and exit.',
42+
)
43+
def login(check: bool) -> None:
2144
"""
2245
The setup command walks the user ID through adding an API key to their account.
2346
"""
47+
if check:
48+
env = get_env_file()
49+
click.echo(_format_login_status(env=env))
50+
is_logged_in = bool(env.get("user_api_key"))
51+
click.get_current_context().exit(0 if is_logged_in else 1)
2452
# Step 1: Initialize the `.stacksync` folder in the home directory.
2553
stacksync_folder = os.path.expanduser("~/.stacksync")
2654
try:

cli/src/stacksync_cli/main.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,50 @@
88
from .commands.replay import replay as replay_cmd
99

1010

11-
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
11+
def _help_callback(ctx: click.Context, _param: click.Parameter, value: bool) -> None:
12+
if not value or ctx.resilient_parsing:
13+
return
14+
help_text = """
15+
Stacksync CLI
16+
17+
Usage:
18+
$ stacksync <command> [options]
19+
20+
Commands:
21+
$ stacksync login # Walks the user through adding API credentials to `.stacksync/env.json`
22+
$ stacksync create # Creates a new Stacksync app in the current directory. Generated app includes a reference implementation and a README.md with coding guidelines.
23+
$ stacksync dev # Runs the app locally and enables traffic forwarding from Stacksync Workflows to localhost. Should be run in the repo created by `stacksync create`.
24+
$ stacksync replay # Replays events from the `.logs` folder of the repo to enable iterative debugging and development.
25+
26+
Development Workflow:
27+
Once installed, the Stacksync CLI can be used to create and manage Stacksync Apps.
28+
To create an app, the following process is recommended:
29+
- Check if logged in: `stacksync login --check`.
30+
This will return a status message prefixed with either "Logged in" or "Not logged in".
31+
- If not logged in: `stacksync login`
32+
- Create an app: `stacksync create <app-name>`
33+
This will create a new directory with the specified app-name and populate it with a reference implementation and a README.md with coding guidelines.
34+
- Run the app locally before making changes to verify functionality: `stacksync dev`
35+
- Once the reference implementation is verified to be working, modify the app as needed, adhering to the coding guidelines in the README.md.
36+
37+
Debugging:
38+
- Event payloads are available for inspection in the `.logs` folder of the repo created by `stacksync create`.
39+
- Events can be replayed by index or ID using the `stacksync replay` command.
40+
"""
41+
click.echo(help_text)
42+
ctx.exit()
43+
44+
45+
@click.group(add_help_option=False)
46+
@click.option(
47+
"-h",
48+
"--help",
49+
is_flag=True,
50+
expose_value=False,
51+
is_eager=True,
52+
callback=_help_callback,
53+
help="Show this message and exit.",
54+
)
1255
def cli() -> None:
1356
pass
1457

tests/test_connectors.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This test script is designed to check that:
2+
# 1. The CLI is installable
3+
# 2. The CLI can be used to create a new connector
4+
# 3. The connector can be hosted locally
5+
# It is designed to be run and checked manually by developers.
6+
7+
# 1. The CLI is installable
8+
curl -fsSL https://cli.stacksync.com/install | sh
9+
10+
# 2. The CLI can be used to create a new connector
11+
rm -rf maxio
12+
stacksync create "maxio"
13+
cd maxio
14+
15+
# 3. The connector can be hosted locally before modifications
16+
stacksync_dev_cleanup() {
17+
if [ -n "${STACKSYNC_DEV_PID:-}" ] && kill -0 "$STACKSYNC_DEV_PID" 2>/dev/null; then
18+
kill "$STACKSYNC_DEV_PID" 2>/dev/null || true
19+
wait "$STACKSYNC_DEV_PID" 2>/dev/null || true
20+
fi
21+
}
22+
trap stacksync_dev_cleanup EXIT
23+
24+
stacksync dev &
25+
STACKSYNC_DEV_PID=$!
26+
27+
sleep 10
28+
29+
# Check that the connector is hosted locally
30+
curl -fsS http://localhost:2323/health \
31+
|| { echo "ERROR: GET /health failed" >&2; exit 1; }
32+
# Check that the connector returns an app config
33+
curl -fsS http://localhost:2323/app-config \
34+
|| { echo "ERROR: GET /app-config failed" >&2; exit 1; }
35+
36+
# 4. The connector can be modified using AI using a known good prompt
37+
prompt="See @README.md and https://developers.maxio.com/http/getting-started/overview. Implement some modules for Maxio."
38+
# Start the cursor agent and send the prompt
39+
agent "$prompt"

0 commit comments

Comments
 (0)