A Kiro workspace for building on Ericsson/Cradlepoint networking products. Describe what you want in chat and it works out where the code should run — the NetCloud Manager API in the cloud, an NCOS SDK app on the router, or a container on the router — then builds and tests it there.
git clone <this-repo> EEWS-Developer
cd EEWS-Developer
python3 tools/bootstrap.py # python on WindowsThen open the folder in Kiro and start chatting. That's it.
bootstrap.py clones the three Cradlepoint sample projects this workspace builds on. From
then on they update themselves — a session-start hook fast-forwards each one to current
upstream every time you open a session.
Set up an environment when you need one, or just ask Kiro to do it:
cd api-samples && python3 setup_env.py # venv, deps, NCM API keys
cd sdk-samples && python3 setup_env.py # venv, deps, dev router settings
cd container-samples && python3 tools/dev_router.py init # dev router settings; needs Docker| Directory | Build target | Runs on | Runtime |
|---|---|---|---|
api-samples/ |
NCM API integrations, scripts, dashboards | your machine or a server, against NetCloud Manager | Python 3.9+, full pip ecosystem |
sdk-samples/ |
NCOS SDK apps | the router | Python 3.8 (cppython), pure Python only |
container-samples/ |
Docker containers | the router, under cpdockerengine |
anything on Alpine ARM |
Each is self-contained — its own .venv, its own setup_env.py, its own docs/, its own
credentials file. There is no workspace-root virtual environment and there should not be
one.
Kiro decides before writing code, using .kiro/steering/platform-selection.md, and tells
you which it chose and why:
- Off the router → NCM API. Fleet-wide work: inventory, reporting, dashboards, config push to groups, subscriptions, users, alerts, bulk reboots. Anything that must keep working when a given router drops offline.
- On the router → SDK app. Per-device logic, reacting to router state in seconds, GPIO/serial/GPS/modem control, a local web UI for a technician, offline operation. The default for on-router work: smaller, lighter, included with every device licence.
- On the router, but an SDK app can't do it → container. Only for compiled non-Python software (nginx, InfluxDB, ntopng, ffmpeg, OpenCV), root access, or a real LAN IP that goes through the firewall. Needs an Advanced licence and NCOS 7.2.20+, so Kiro always asks before building or deploying one.
A pure-Python package from pip is not a reason to use a container — it installs straight into an SDK app folder.
- "Build a dashboard showing routers with poor signal" → NCM API
- "Export every device with an expiring subscription to CSV" → NCM API
- "Create an app that runs a speedtest every hour and logs to CSV" → SDK app
- "Local web page showing WAN status and signal for all modems" → SDK app
- "Read GPS on the router and report position to a TAK server" → SDK app
- "What would it take to run ntopng on a router?" → container, with the licence caveat
The session-start hook does this for you. To do it by hand:
python3 tools/bootstrap.py # fast-forward all three to upstream
python3 tools/bootstrap.py --check # report state only, no network
python3 tools/bootstrap.py --offline # skip network entirelyYour work is never discarded. A project with uncommitted changes, or on a branch other
than master, is reported and skipped. No reset, no force, no stash.
Entirely optional, and not part of setup. You never need a GitHub account, a fork, or
any URL to use this workspace — bootstrap.py clones the three projects anonymously.
This section only applies if you want to send a change back to Cradlepoint, and then only
for the single project you changed.
The three projects are ordinary clones, so this is the normal GitHub flow. All three are
MIT licensed with no CLA and no contribution guide to satisfy. A new SDK app
(sdk-samples/<app_name>/), a container (container-samples/containers/<name>/), or a
script under api-samples/ is a self-contained path — already the right shape for a pull
request.
tools/contribute.py does the whole GitHub dance for you. Point it at the path you want to
send upstream, from the workspace root:
python3 tools/contribute.py sdk-samples/my_app
python3 tools/contribute.py container-samples/containers/my_container
python3 tools/contribute.py api-samples/scripts/my_script.pyIt works out which project the path belongs to and then, stopping for your confirmation before anything leaves your machine:
- Branches off that project's current upstream
master. - Shows exactly which files it will commit — only the path you named — and asks first.
Build artifacts,
METADATA/,.venv, and credential files are never staged. - Commits with a message you supply.
- Creates your fork if you don't have one and adds it as a remote named
fork, leavingoriginon Cradlepoint sobootstrap.pykeeps fast-forwarding from upstream. - Pushes the branch to your fork and opens the pull request.
First run only: the pull request step uses the GitHub CLI. If
you don't have it, the tool offers to download it into tools/.gh/ (about 10 MB, no admin
rights, git-ignored) and signs you in once with a browser code. Decline, and it falls back
to opening the fork and PR pages in your browser. Later runs skip both.
Nothing touches your GitHub account until after you've approved the commit. If you stop partway, the commit is safe on the branch and the tool prints how to finish by hand.
After the PR is merged or closed, drop the feature branch so the project keeps updating
cleanly — while a clone sits on a feature branch, bootstrap.py skips it:
cd api-samples
git checkout master
git branch -D add-my_script # local branch
git push fork --delete add-my_script # and the copy on your forkLeave the fork remote in place — it's your reusable link for the next contribution, not
per-branch clutter.
If you'd rather run the git yourself:
cd sdk-samples
git remote add fork https://github.com/YOUR-USERNAME/sdk-samples.git
git checkout -b my-app
git commit -am "Add my app"
git push -u fork my-app # then open a PR on GitHubOnly the combined configuration and tooling. The sample projects are fetched, not vendored, so you always get current upstream code and attribution stays with Cradlepoint.
.kiro/steering/ 18 files — the platform decision engine and domain rules
.kiro/hooks/ 2 hooks — session-start sync/check, end-of-session reflection
tools/bootstrap.py clones and updates the three sample projects
tools/workspace_status.py reports which environments are ready
tools/contribute.py opens a pull request upstream for one path, without the git
Always loaded:
| File | Purpose |
|---|---|
workspace.md |
Map of the three targets, repo layout, credentials, shared assets |
platform-selection.md |
The decision procedure and three pre-design gates |
build-and-verify.md |
How to build, deploy and prove it works, per target |
Loaded automatically when a file matching the pattern comes into context. Most are scoped to a whole subproject, but a few only load for the relevant file types or names:
| File | Loads for |
|---|---|
ncm-project-setup.md |
api-samples/** |
ncm-api-development.md |
api-samples/**/*.py |
ncm-code-standards.md |
api-samples/scripts/**/*.py |
ncm-web-ui.md |
api-samples/**/*.html, **/*.css, web_apps/** |
sdk-workflow.md, sdk-coding-standards.md, sdk-ncos-api.md, sdk-web-standards.md |
sdk-samples/** |
sdk-gps.md |
sdk-samples/ files named *gps*, *nmea*, *gnss*, *rtk* |
sdk-speedtest.md |
sdk-samples/ files named *speed*, *iperf*, *netperf* |
container-workflow.md, container-platform-limits.md |
container-samples/** |
Pull in by hand with #: #setup-all, #reflexion, #cradlepoint-docs-api,
#container-lessons-learned (archive of past container builds — provenance only, never
appended to).
Two hooks in .kiro/hooks/, both automatic:
| Hook | Trigger | Does |
|---|---|---|
| Sync and Check | SessionStart | Fast-forwards the three sample projects to upstream (skipping any with local changes or on a feature branch), then reports which environments are ready. Read-only with respect to local work, never prints credentials |
| Reflect and Update Docs | Stop | At the end of a session, routes any generally applicable learning into the right per-subproject docs/ or workspace steering file — and records nothing app-specific |
Two other behaviors that feel hook-like are handled by always-loaded steering, not hooks:
choosing the build target before any code is written (platform-selection.md) and fixing a
failing run instead of reporting success over it (build-and-verify.md).
Three separate gitignored files, none of which should ever be pasted into chat — every setup path takes them with hidden input:
| Subproject | File |
|---|---|
api-samples/ |
.env |
sdk-samples/ |
sdk_settings.ini |
container-samples/ |
.env |
MIT — see LICENSE. The three sample projects are separately licensed, each keeping its own
LICENSE file once cloned.