add developer portal planning documentation (M01-M12)
This commit is contained in:
609
DEV_PORTAL_M11_CLI.md
Normal file
609
DEV_PORTAL_M11_CLI.md
Normal file
@@ -0,0 +1,609 @@
|
||||
# Milestone 11: Developer CLI Tool
|
||||
|
||||
**Status**: Planning
|
||||
**Goal**: Command-line tool for app development workflow.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The CLI tool (`mosis`) streamlines the developer workflow: project creation, building, testing, signing, and publishing.
|
||||
|
||||
---
|
||||
|
||||
## Commands Overview
|
||||
|
||||
```
|
||||
mosis
|
||||
├── init Create new app project
|
||||
├── validate Validate manifest and assets
|
||||
├── build Create .mosis package
|
||||
├── sign Sign package with developer key
|
||||
├── run Run in local designer/emulator
|
||||
├── test Run automated tests
|
||||
├── login Authenticate with portal
|
||||
├── logout Clear authentication
|
||||
├── publish Upload and submit for review
|
||||
├── status Check review status
|
||||
├── keys
|
||||
│ ├── generate Generate signing keypair
|
||||
│ ├── list List registered keys
|
||||
│ └── register Upload public key to portal
|
||||
└── config
|
||||
├── get Get config value
|
||||
└── set Set config value
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Command Details
|
||||
|
||||
### `mosis init`
|
||||
|
||||
Create a new app project with boilerplate.
|
||||
|
||||
```bash
|
||||
$ mosis init
|
||||
|
||||
? App name: My Calculator
|
||||
? Package ID: com.myname.calculator
|
||||
? Description: A simple calculator app
|
||||
? Author name: John Doe
|
||||
? Author email: john@example.com
|
||||
|
||||
Creating project structure...
|
||||
|
||||
✓ Created manifest.json
|
||||
✓ Created assets/main.rml
|
||||
✓ Created assets/styles/theme.rcss
|
||||
✓ Created assets/scripts/app.lua
|
||||
✓ Created icons/ (placeholder icons)
|
||||
|
||||
Project created! Next steps:
|
||||
cd my-calculator
|
||||
mosis run # Preview in designer
|
||||
mosis build # Create package
|
||||
mosis publish # Submit to store
|
||||
```
|
||||
|
||||
#### Generated Structure
|
||||
|
||||
```
|
||||
my-calculator/
|
||||
├── manifest.json
|
||||
├── assets/
|
||||
│ ├── main.rml
|
||||
│ ├── styles/
|
||||
│ │ └── theme.rcss
|
||||
│ └── scripts/
|
||||
│ └── app.lua
|
||||
├── icons/
|
||||
│ ├── icon-32.png
|
||||
│ ├── icon-64.png
|
||||
│ └── icon-128.png
|
||||
└── .mosisignore # Files to exclude from package
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis validate`
|
||||
|
||||
Validate project without building.
|
||||
|
||||
```bash
|
||||
$ mosis validate
|
||||
|
||||
Validating manifest.json...
|
||||
✓ Required fields present
|
||||
✓ Package ID format valid
|
||||
✓ Version format valid
|
||||
|
||||
Validating assets...
|
||||
✓ Entry point exists: assets/main.rml
|
||||
✓ All RML files valid (3 files)
|
||||
✓ All RCSS files valid (2 files)
|
||||
✓ All Lua files valid (4 files)
|
||||
|
||||
Validating icons...
|
||||
✓ icon-32.png (32x32)
|
||||
✓ icon-64.png (64x64)
|
||||
✓ icon-128.png (128x128)
|
||||
|
||||
Checking permissions...
|
||||
✓ Permissions declared: storage, network
|
||||
|
||||
All validations passed!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis build`
|
||||
|
||||
Create a .mosis package.
|
||||
|
||||
```bash
|
||||
$ mosis build
|
||||
|
||||
Reading manifest.json...
|
||||
Package: com.myname.calculator v1.0.0 (1)
|
||||
|
||||
Collecting files...
|
||||
✓ manifest.json
|
||||
✓ assets/main.rml
|
||||
✓ assets/styles/theme.rcss
|
||||
✓ assets/scripts/app.lua
|
||||
✓ icons/icon-32.png
|
||||
✓ icons/icon-64.png
|
||||
✓ icons/icon-128.png
|
||||
|
||||
Creating package...
|
||||
✓ Package created: dist/com.myname.calculator-1.0.0.mosis (45.2 KB)
|
||||
|
||||
⚠ Package is unsigned. Run 'mosis sign' before publishing.
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```bash
|
||||
mosis build [options]
|
||||
|
||||
Options:
|
||||
-o, --output <path> Output path (default: dist/)
|
||||
--no-compress Skip compression
|
||||
--include-source Include .lua source maps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis sign`
|
||||
|
||||
Sign a package with developer key.
|
||||
|
||||
```bash
|
||||
$ mosis sign dist/com.myname.calculator-1.0.0.mosis
|
||||
|
||||
Using key: ~/.mosis/signing_key.pem
|
||||
Fingerprint: SHA256:abc123...
|
||||
|
||||
Generating file hashes...
|
||||
Signing MANIFEST.MF...
|
||||
|
||||
✓ Package signed: dist/com.myname.calculator-1.0.0.mosis
|
||||
|
||||
Signature details:
|
||||
Algorithm: Ed25519
|
||||
Key fingerprint: SHA256:abc123...
|
||||
Files signed: 7
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```bash
|
||||
mosis sign <package> [options]
|
||||
|
||||
Options:
|
||||
-k, --key <path> Path to private key (default: ~/.mosis/signing_key.pem)
|
||||
--verify Verify existing signature
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis run`
|
||||
|
||||
Launch in desktop designer for testing.
|
||||
|
||||
```bash
|
||||
$ mosis run
|
||||
|
||||
Starting Mosis Designer...
|
||||
Loading: assets/main.rml
|
||||
|
||||
Designer running at http://localhost:8080
|
||||
Press Ctrl+C to stop
|
||||
|
||||
[Hot reload enabled - changes auto-refresh]
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```bash
|
||||
mosis run [options]
|
||||
|
||||
Options:
|
||||
--entry <file> Override entry point
|
||||
--port <number> Designer port (default: 8080)
|
||||
--no-hot-reload Disable hot reload
|
||||
--device <name> Emulate device (phone, tablet)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis login`
|
||||
|
||||
Authenticate with developer portal.
|
||||
|
||||
```bash
|
||||
$ mosis login
|
||||
|
||||
Opening browser for authentication...
|
||||
Waiting for authorization...
|
||||
|
||||
✓ Logged in as john@example.com
|
||||
API key stored in ~/.mosis/credentials
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```bash
|
||||
mosis login [options]
|
||||
|
||||
Options:
|
||||
--api-key <key> Use API key instead of browser auth
|
||||
--portal <url> Portal URL (default: https://portal.mosis.dev)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis publish`
|
||||
|
||||
Upload and submit for review.
|
||||
|
||||
```bash
|
||||
$ mosis publish
|
||||
|
||||
Checking authentication...
|
||||
✓ Logged in as john@example.com
|
||||
|
||||
Building package...
|
||||
✓ Package created: dist/com.myname.calculator-1.0.0.mosis
|
||||
|
||||
Signing package...
|
||||
✓ Package signed
|
||||
|
||||
Uploading...
|
||||
████████████████████████████████ 100%
|
||||
|
||||
Submitting for review...
|
||||
✓ Version 1.0.0 submitted
|
||||
|
||||
Review status: In Review
|
||||
Estimated review time: 24 hours
|
||||
|
||||
Track status: mosis status
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```bash
|
||||
mosis publish [options]
|
||||
|
||||
Options:
|
||||
--package <path> Use existing package
|
||||
--notes <text> Release notes
|
||||
--notes-file <path> Release notes from file
|
||||
--draft Upload without submitting for review
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis status`
|
||||
|
||||
Check app/version status.
|
||||
|
||||
```bash
|
||||
$ mosis status
|
||||
|
||||
App: My Calculator (com.myname.calculator)
|
||||
|
||||
Versions:
|
||||
v1.0.0 (1) Published Jan 10, 2024 1,234 downloads
|
||||
v1.1.0 (2) In Review Jan 15, 2024 Submitted 2h ago
|
||||
|
||||
Latest review:
|
||||
Status: In Review
|
||||
Submitted: Jan 15, 2024 10:30 AM
|
||||
Estimated completion: Jan 16, 2024
|
||||
|
||||
Run 'mosis status --watch' to monitor in real-time.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis keys generate`
|
||||
|
||||
Generate Ed25519 signing keypair.
|
||||
|
||||
```bash
|
||||
$ mosis keys generate
|
||||
|
||||
Generating Ed25519 keypair...
|
||||
|
||||
Private key saved to: ~/.mosis/signing_key.pem
|
||||
Public key saved to: ~/.mosis/signing_key.pub
|
||||
|
||||
Fingerprint: SHA256:abc123def456...
|
||||
|
||||
⚠ IMPORTANT: Keep your private key secure!
|
||||
- Never share or commit signing_key.pem
|
||||
- Back it up securely
|
||||
- If compromised, revoke immediately
|
||||
|
||||
Next step: Register your public key
|
||||
mosis keys register
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `mosis keys register`
|
||||
|
||||
Upload public key to portal.
|
||||
|
||||
```bash
|
||||
$ mosis keys register
|
||||
|
||||
Reading public key from ~/.mosis/signing_key.pub
|
||||
Fingerprint: SHA256:abc123def456...
|
||||
|
||||
? Key name: MacBook Pro 2024
|
||||
|
||||
Uploading to portal...
|
||||
✓ Key registered successfully
|
||||
|
||||
Your signing key is now active. Packages signed with this
|
||||
key will be accepted for review.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Config File Location
|
||||
|
||||
```
|
||||
~/.mosis/
|
||||
├── config.json # CLI configuration
|
||||
├── credentials # Auth tokens (encrypted)
|
||||
├── signing_key.pem # Private key
|
||||
└── signing_key.pub # Public key
|
||||
```
|
||||
|
||||
### Config Options
|
||||
|
||||
```json
|
||||
{
|
||||
"portal_url": "https://portal.mosis.dev",
|
||||
"api_url": "https://api.mosis.dev",
|
||||
"designer_path": "/usr/local/bin/mosis-designer",
|
||||
"default_author": {
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation
|
||||
|
||||
### Tech Stack Options
|
||||
|
||||
#### Option A: Go
|
||||
|
||||
```go
|
||||
// Using cobra for CLI framework
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "mosis",
|
||||
Short: "Mosis app development CLI",
|
||||
}
|
||||
|
||||
rootCmd.AddCommand(initCmd())
|
||||
rootCmd.AddCommand(buildCmd())
|
||||
rootCmd.AddCommand(signCmd())
|
||||
rootCmd.AddCommand(publishCmd())
|
||||
// ...
|
||||
|
||||
rootCmd.Execute()
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Single binary, fast, cross-platform
|
||||
**Cons**: More code to write
|
||||
|
||||
#### Option B: Node.js (oclif)
|
||||
|
||||
```typescript
|
||||
// Using oclif framework
|
||||
import { Command } from '@oclif/core'
|
||||
|
||||
export default class Build extends Command {
|
||||
static description = 'Build .mosis package'
|
||||
|
||||
async run() {
|
||||
const manifest = await this.readManifest()
|
||||
const files = await this.collectFiles()
|
||||
const package = await this.createPackage(files)
|
||||
this.log(`✓ Package created: ${package.path}`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Fast development, npm distribution
|
||||
**Cons**: Requires Node.js runtime
|
||||
|
||||
#### Option C: Rust (clap)
|
||||
|
||||
```rust
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "mosis")]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
Init { name: Option<String> },
|
||||
Build { output: Option<PathBuf> },
|
||||
Sign { package: PathBuf },
|
||||
Publish,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
match cli.command {
|
||||
Commands::Init { name } => init::run(name),
|
||||
Commands::Build { output } => build::run(output),
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Single binary, very fast
|
||||
**Cons**: Slower development
|
||||
|
||||
---
|
||||
|
||||
## Distribution
|
||||
|
||||
### npm (Node.js version)
|
||||
|
||||
```bash
|
||||
npm install -g @mosis/cli
|
||||
```
|
||||
|
||||
### Homebrew (macOS)
|
||||
|
||||
```bash
|
||||
brew tap mosis/tap
|
||||
brew install mosis
|
||||
```
|
||||
|
||||
### Direct Download
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
curl -fsSL https://mosis.dev/install.sh | sh
|
||||
|
||||
# Windows
|
||||
irm https://mosis.dev/install.ps1 | iex
|
||||
```
|
||||
|
||||
### Package Managers
|
||||
|
||||
| Platform | Package Manager | Command |
|
||||
|----------|-----------------|---------|
|
||||
| macOS | Homebrew | `brew install mosis` |
|
||||
| Windows | Scoop | `scoop install mosis` |
|
||||
| Linux | apt (deb) | `apt install mosis` |
|
||||
| Any | npm | `npm install -g @mosis/cli` |
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
### User-Friendly Errors
|
||||
|
||||
```bash
|
||||
$ mosis build
|
||||
|
||||
Error: manifest.json not found
|
||||
|
||||
Are you in a Mosis project directory?
|
||||
Run 'mosis init' to create a new project.
|
||||
```
|
||||
|
||||
### Verbose Mode
|
||||
|
||||
```bash
|
||||
$ mosis build --verbose
|
||||
|
||||
[DEBUG] Reading manifest from ./manifest.json
|
||||
[DEBUG] Manifest parsed: {id: "com.example.app", ...}
|
||||
[DEBUG] Collecting files from ./assets
|
||||
[DEBUG] Found 7 files
|
||||
[DEBUG] Creating ZIP archive
|
||||
[DEBUG] Writing to dist/com.example.app-1.0.0.mosis
|
||||
[DEBUG] Package size: 45234 bytes
|
||||
✓ Package created
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
name: Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Mosis CLI
|
||||
run: npm install -g @mosis/cli
|
||||
|
||||
- name: Build and Sign
|
||||
env:
|
||||
MOSIS_SIGNING_KEY: ${{ secrets.MOSIS_SIGNING_KEY }}
|
||||
run: |
|
||||
echo "$MOSIS_SIGNING_KEY" > signing_key.pem
|
||||
mosis build
|
||||
mosis sign dist/*.mosis --key signing_key.pem
|
||||
|
||||
- name: Publish
|
||||
env:
|
||||
MOSIS_API_KEY: ${{ secrets.MOSIS_API_KEY }}
|
||||
run: mosis publish --api-key "$MOSIS_API_KEY"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deliverables
|
||||
|
||||
- [ ] CLI framework selection
|
||||
- [ ] `init` command
|
||||
- [ ] `validate` command
|
||||
- [ ] `build` command
|
||||
- [ ] `sign` command
|
||||
- [ ] `run` command (designer integration)
|
||||
- [ ] `login/logout` commands
|
||||
- [ ] `publish` command
|
||||
- [ ] `status` command
|
||||
- [ ] `keys` subcommands
|
||||
- [ ] Configuration management
|
||||
- [ ] Distribution packages
|
||||
- [ ] CI/CD examples
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. Should CLI auto-update itself?
|
||||
2. Offline mode for build/sign?
|
||||
3. Plugin system for custom commands?
|
||||
4. IDE integrations (VS Code extension)?
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Cobra CLI Framework](https://cobra.dev/)
|
||||
- [oclif Framework](https://oclif.io/)
|
||||
- [Clap for Rust](https://docs.rs/clap/)
|
||||
Reference in New Issue
Block a user