From 14cfa9f59745178f26edd7d174cf221af5a1f6d6 Mon Sep 17 00:00:00 2001 From: Noah Cardoza Date: Tue, 17 Feb 2026 20:47:40 -0800 Subject: [PATCH 01/13] feat: add OpenClaw skill for iloom CLI Refs #626 Co-Authored-By: Claude Opus 4.6 --- openclaw-skill/SKILL.md | 103 ++++++ openclaw-skill/references/configuration.md | 155 +++++++++ openclaw-skill/references/core-workflow.md | 281 ++++++++++++++++ .../references/development-commands.md | 305 ++++++++++++++++++ .../references/non-interactive-patterns.md | 231 +++++++++++++ .../references/planning-and-issues.md | 229 +++++++++++++ 6 files changed, 1304 insertions(+) create mode 100644 openclaw-skill/SKILL.md create mode 100644 openclaw-skill/references/configuration.md create mode 100644 openclaw-skill/references/core-workflow.md create mode 100644 openclaw-skill/references/development-commands.md create mode 100644 openclaw-skill/references/non-interactive-patterns.md create mode 100644 openclaw-skill/references/planning-and-issues.md diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md new file mode 100644 index 00000000..53417029 --- /dev/null +++ b/openclaw-skill/SKILL.md @@ -0,0 +1,103 @@ +--- +name: iloom +description: Manage isolated Git worktrees and AI-assisted development workflows with iloom CLI. Use when you need to create workspaces for issues/PRs, commit and merge code, run dev servers, plan and decompose features into issues, enhance issue descriptions with AI, list active workspaces, or configure iloom projects. Covers the full loom lifecycle (init, start, finish, cleanup) and all development commands (spin, commit, rebase, build, test, lint). Also use when the user has an idea for improvement or new feature β€” route through `il plan` for ideation and decomposition. +metadata: { "openclaw": { "emoji": "🧡", "requires": { "anyBins": ["il", "iloom"] } } } +--- + +# iloom + +Manage isolated Git worktrees with AI-assisted development workflows. + +## PTY Mode Required + +iloom is an **interactive terminal application**. Always use `pty:true` when running iloom commands: + +```bash +# Correct - with PTY +bash pty:true command:"il list --json" + +# Wrong - may break output or hang +bash command:"il list --json" +``` + +## Project Initialization (First-Time Setup) + +Before using any iloom commands, the project must be initialized: + +```bash +# 1. Initialize your project (if not already done) +bash pty:true command:"pnpm init" # or npm init, cargo init, etc. + +# 2. Initialize git (if not already done) +bash pty:true command:"git init && git add -A && git commit -m 'Initial commit'" + +# 3. Initialize iloom (interactive setup wizard) +bash pty:true command:"il init" +``` + +`il init` launches an interactive configuration wizard. It must run in the foreground with PTY. + +## Quick Start + +### Check active workspaces + +```bash +bash pty:true command:"il list --json" +``` + +### Start a loom for an issue (launches Claude in background) + +```bash +bash pty:true background:true command:"il start 42 --yolo --no-code --json" +# Monitor: process action:log sessionId:XXX +# Check: process action:poll sessionId:XXX +``` + +### Finish and merge a loom + +```bash +bash pty:true command:"il finish --force --cleanup --no-browser --json" +``` + +### Launch Claude in existing loom + +```bash +bash pty:true background:true command:"il spin --yolo" +# Monitor: process action:log sessionId:XXX +``` + +### Commit with AI-generated message + +```bash +bash pty:true command:"il commit --no-review --json" +``` + +## Ideation and Planning + +When the user has an idea for an improvement, new feature, or wants to decompose work into issues, use `il plan`: + +```bash +bash pty:true background:true command:"il plan --yolo" +# Or for headless output: +bash pty:true command:"il plan --yolo --print --output-format json" +``` + +`il plan` launches an interactive AI planning session that creates structured issues with dependencies. Always prefer this over manually creating issues. + +## References + +- **Core lifecycle commands (init, start, finish, cleanup, list):** See `{baseDir}/references/core-workflow.md` +- **Development commands (spin, commit, rebase, build, test, etc.):** See `{baseDir}/references/development-commands.md` +- **Planning and issue management (plan, add-issue, enhance, issues):** See `{baseDir}/references/planning-and-issues.md` +- **Settings, env vars, and global flags:** See `{baseDir}/references/configuration.md` +- **Non-interactive patterns (PTY, background, autonomous operation):** See `{baseDir}/references/non-interactive-patterns.md` + +## Safety Rules + +1. **Always use `pty:true`** for every iloom command. +2. **Use `background:true`** for commands that launch Claude: `start`, `spin`, `plan`. +3. **Never run `il finish` without `--force`** in autonomous mode β€” it will hang on confirmation prompts. +4. **Always pass explicit flags** to avoid interactive prompts. See `{baseDir}/references/non-interactive-patterns.md` for the complete decision bypass map. +5. **Use `--json`** when you need to parse command output programmatically. +6. **Do not run `il init` in background mode** β€” it requires foreground interactive setup. +7. **Respect worktree isolation** β€” each loom is an independent workspace. Run commands from within the correct worktree directory. diff --git a/openclaw-skill/references/configuration.md b/openclaw-skill/references/configuration.md new file mode 100644 index 00000000..d800f20e --- /dev/null +++ b/openclaw-skill/references/configuration.md @@ -0,0 +1,155 @@ +# Configuration + +## Settings System + +iloom uses a layered settings system with three files: + +| File | Location | Scope | Git | +|------|----------|-------|-----| +| Global settings | `~/.config/iloom-ai/settings.json` | All projects | N/A | +| Project settings | `.iloom/settings.json` | This project | Committed | +| Local settings | `.iloom/settings.local.json` | This machine | Gitignored | + +Local overrides project, project overrides global. + +### Key Settings + +| Setting | Description | Default | +|---------|-------------|---------| +| `mainBranch` | Primary branch name | Auto-detected (`main` or `master`) | +| `workflows.issue.permissionMode` | Permission mode for issue looms | `default` | +| `workflows.issue.startIde` | Open IDE on loom start | `true` | +| `workflows.issue.startAiAgent` | Launch Claude on loom start | `true` | +| `mergeBehavior.mode` | Merge strategy | `local` | +| `issueManagement.provider` | Issue tracker | `github` | +| `capabilities.web.basePort` | Base port for dev servers | `3000` | +| `agents..model` | Per-agent model override | β€” | + +### Runtime Setting Overrides + +Use `--set` to override any setting for a single command: + +```bash +bash pty:true command:"il start 42 --set mergeBehavior.mode=github-pr --set capabilities.web.basePort=4000" +``` + +The `--set` flag accepts dot notation and can be repeated. + +--- + +## Environment Variables + +### iloom Variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `ILOOM_DEBUG` | Enable debug logging | `false` | +| `ILOOM_SHELL` | Override shell detection | Auto-detect | +| `ILOOM_SETTINGS_PATH` | Override settings file location | `~/.config/iloom-ai/settings.json` | +| `ILOOM_NO_COLOR` | Disable colored output | `false` | +| `ILOOM_DEV_SERVER_TIMEOUT` | Dev server startup timeout (ms) | `180000` | +| `ILOOM_UPDATE_CACHE_TIMEOUT_MINS` | Update check cache TTL (minutes) | `60` | + +### Issue Tracker Variables + +| Variable | Description | Required For | +|----------|-------------|-------------| +| `LINEAR_API_TOKEN` | Linear API authentication | Linear integration | +| `JIRA_HOST` | Jira instance URL | Jira integration | +| `JIRA_USERNAME` | Jira username | Jira integration | +| `JIRA_API_TOKEN` | Jira API token | Jira integration | +| `JIRA_PROJECT_KEY` | Jira project key | Jira integration | + +### Standard Variables + +| Variable | Description | +|----------|-------------| +| `CI` | When `true`, disables interactive prompts | +| `CLAUDE_API_KEY` | Claude API key (if not using Claude CLI auth) | + +--- + +## Global CLI Flags + +Available on all commands: + +| Flag | Description | +|------|-------------| +| `--help`, `-h` | Display command help | +| `--version`, `-v` | Display iloom version | +| `--debug` | Enable debug output | +| `--no-color` | Disable colored output | +| `--set ` | Override any setting (repeatable) | + +--- + +## il projects + +List all configured iloom projects. + +```bash +bash pty:true command:"il projects --json" +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--json` | boolean | `false` | Output as JSON array | + +### JSON Output + +```json +[ + { + "configuredAt": "2026-01-15T10:00:00.000Z", + "projectPath": "/path/to/project", + "projectName": "my-project", + "activeLooms": 3, + "capabilities": ["web", "cli"] + } +] +``` + +--- + +## il update + +Update iloom CLI to the latest version. + +```bash +bash pty:true command:"il update" +bash pty:true command:"il update --dry-run" +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--dry-run` | boolean | `false` | Check for updates without installing | + +Only works for globally installed iloom (`npm install -g`). + +--- + +## il feedback + +Submit bug reports or feature requests to the iloom repository. + +```bash +bash pty:true command:"il feedback 'The rebase command fails on merge commits' --body 'Steps to reproduce...' --json" +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `` | positional | β€” | Feedback description (>30 chars, >3 words) | +| `--body ` | string | β€” | Detailed body text | +| `--json` | boolean | `false` | Output as JSON | + +--- + +## il contribute + +Fork, clone, and set up the iloom repository for contribution. + +```bash +bash pty:true command:"il contribute" +``` + +No flags. Interactive setup process. diff --git a/openclaw-skill/references/core-workflow.md b/openclaw-skill/references/core-workflow.md new file mode 100644 index 00000000..1829c1ff --- /dev/null +++ b/openclaw-skill/references/core-workflow.md @@ -0,0 +1,281 @@ +# Core Workflow Commands + +## il init + +Initialize iloom for a project. This is always the first iloom command to run. + +### Prerequisites + +1. Project directory must exist with a package manager initialized (`pnpm init`, `npm init`, `cargo init`, etc.) +2. Git repository must be initialized (`git init`) with at least one commit +3. A GitHub remote should be configured (`git remote add origin ...`) + +### Usage + +```bash +# Interactive setup wizard (foreground only, do NOT use background mode) +bash pty:true command:"il init" + +# With a natural language instruction +bash pty:true command:"il init 'set IDE to windsurf'" +``` + +### Behavior + +- Creates `.iloom/` directory with `settings.json` and `settings.local.json` +- Launches Claude Code for guided configuration +- Detects project capabilities (web, CLI, library) +- Configures issue tracker (GitHub, Linear, or Jira) +- Sets merge behavior, IDE preferences, and workflow settings +- Marks the project as configured in `~/.config/iloom-ai/projects/` + +### Important + +- **Must run in foreground** β€” this is an interactive wizard +- **Requires PTY** β€” Claude Code needs a terminal +- Only needs to run once per project + +--- + +## il start + +Create an isolated loom workspace for an issue, PR, or branch. + +**Aliases:** `new`, `create`, `up` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `[identifier]` | positional | β€” | Issue number, PR number (`pr/123`), branch name, or description text | +| `--one-shot ` | enum | `default` | Automation mode: `default`, `noReview`, `bypassPermissions` | +| `--yolo` | boolean | `false` | Shorthand for `--one-shot=bypassPermissions` | +| `--claude` / `--no-claude` | boolean | `true` | Enable/disable Claude integration | +| `--code` / `--no-code` | boolean | `true` | Enable/disable VS Code opening | +| `--dev-server` / `--no-dev-server` | boolean | `true` | Enable/disable dev server | +| `--terminal` / `--no-terminal` | boolean | `false` | Enable/disable terminal tab | +| `--child-loom` / `--no-child-loom` | boolean | β€” | Force child/independent loom (skips prompt) | +| `--body ` | string | β€” | Issue body text (skips AI enhancement) | +| `--json` | boolean | `false` | Output result as JSON | + +### Examples + +```bash +# Start a loom for issue #42 in autonomous mode, no VS Code, JSON output +bash pty:true background:true command:"il start 42 --yolo --no-code --json" + +# Start a loom for a PR +bash pty:true background:true command:"il start pr/99 --yolo --no-code --json" + +# Create a loom from a description (auto-creates GitHub issue) +bash pty:true background:true command:"il start 'Add dark mode support to the settings page' --yolo --no-code --json" + +# Force independent loom (skip child loom prompt) +bash pty:true background:true command:"il start 42 --yolo --no-code --no-child-loom --json" +``` + +### Interactive Prompts and Bypasses + +| Prompt | Bypass | +|--------|--------| +| "Enter issue number..." | Provide `[identifier]` argument | +| "Create as a child loom?" | `--child-loom` or `--no-child-loom` | +| "bypassPermissions warning" | Already implied by `--yolo`; or use `--no-claude` | + +### Background Mode + +This command **launches Claude** by default. Use `background:true` and monitor: + +```bash +bash pty:true background:true command:"il start 42 --yolo --no-code --json" +# Returns sessionId + +process action:poll sessionId:XXX # Check if done +process action:log sessionId:XXX # View output +process action:kill sessionId:XXX # Terminate if needed +``` + +### JSON Output + +```json +{ + "id": "string", + "path": "/path/to/worktree", + "branch": "feat/42-feature-name", + "port": 3042, + "type": "issue", + "identifier": 42, + "title": "Feature name" +} +``` + +--- + +## il finish + +Validate, commit, merge, and clean up a loom workspace. + +**Aliases:** `dn` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `[identifier]` | positional | β€” | Auto-detected from current directory if omitted | +| `-f, --force` | boolean | `false` | Skip confirmation prompts | +| `-n, --dry-run` | boolean | `false` | Preview actions without executing | +| `--pr ` | number | β€” | Treat input as PR number | +| `--skip-build` | boolean | `false` | Skip post-merge build verification | +| `--no-browser` | boolean | `false` | Skip opening PR in browser | +| `--cleanup` / `--no-cleanup` | boolean | β€” | Explicit cleanup decision (skips prompt) | +| `--json` | boolean | `false` | Output result as JSON | + +### Examples + +```bash +# Fully autonomous finish from within a loom directory +bash pty:true command:"il finish --force --cleanup --no-browser --json" + +# Dry run to preview what would happen +bash pty:true command:"il finish --dry-run" + +# Finish a specific issue +bash pty:true command:"il finish 42 --force --cleanup --no-browser --json" +``` + +### Interactive Prompts and Bypasses + +| Prompt | Bypass | +|--------|--------| +| "Clean up worktree?" | `--cleanup` or `--no-cleanup` | +| Commit message review | `--force` | +| General confirmations | `--force` | + +### JSON Output + +```json +{ + "success": true, + "type": "issue", + "identifier": 42, + "operations": [ + { "type": "validation", "message": "...", "success": true }, + { "type": "commit", "message": "...", "success": true }, + { "type": "merge", "message": "...", "success": true } + ], + "prUrl": "https://github.com/owner/repo/pull/99", + "cleanupResult": { ... } +} +``` + +--- + +## il cleanup + +Remove one or more loom workspaces without merging. + +**Aliases:** `remove`, `clean` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `[identifier]` | positional | β€” | Branch name or issue number | +| `-l, --list` | boolean | `false` | List all worktrees (informational) | +| `-a, --all` | boolean | `false` | Remove all worktrees | +| `-i, --issue ` | number | β€” | Cleanup by issue number | +| `-f, --force` | boolean | `false` | Skip confirmations and force removal | +| `--dry-run` | boolean | `false` | Show what would be done | +| `--json` | boolean | `false` | Output result as JSON | +| `--defer ` | number | β€” | Wait before cleanup (milliseconds) | + +### Examples + +```bash +# Remove a specific loom by issue number +bash pty:true command:"il cleanup --issue 42 --force --json" + +# Remove all looms +bash pty:true command:"il cleanup --all --force --json" + +# List worktrees without removing +bash pty:true command:"il cleanup --list" + +# Dry run +bash pty:true command:"il cleanup --issue 42 --dry-run" +``` + +### Interactive Prompts and Bypasses + +| Prompt | Bypass | +|--------|--------| +| "Remove this worktree?" | `--force` | +| "Remove N worktree(s)?" | `--force` | + +### JSON Output + +```json +{ + "identifier": "42", + "success": true, + "dryRun": false, + "operations": [ + { "type": "worktree", "success": true, "message": "...", "deleted": true }, + { "type": "branch", "success": true, "message": "...", "deleted": true } + ], + "errors": [], + "rollbackRequired": false +} +``` + +--- + +## il list + +Display active loom workspaces. + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--json` | boolean | `false` | Output as JSON array | +| `--finished` | boolean | `false` | Show only finished looms | +| `--all` | boolean | `false` | Show both active and finished looms | +| `--global` | boolean | `false` | Show looms from all projects | +| `--children` | boolean | `false` | Include child issues and child looms | + +### Examples + +```bash +# List active looms as JSON +bash pty:true command:"il list --json" + +# List all looms (active + finished) +bash pty:true command:"il list --all --json" + +# List looms across all projects +bash pty:true command:"il list --global --json" +``` + +### No Interactive Prompts + +This is a read-only command with no interactive prompts. + +### JSON Output + +Returns an array of loom objects: + +```json +[ + { + "name": "feat/42-dark-mode", + "worktreePath": "/path/to/worktree", + "branch": "feat/42-dark-mode", + "type": "issue", + "issue_numbers": [42], + "isMainWorktree": false, + "status": "active", + "isChildLoom": false + } +] +``` diff --git a/openclaw-skill/references/development-commands.md b/openclaw-skill/references/development-commands.md new file mode 100644 index 00000000..4b07ad12 --- /dev/null +++ b/openclaw-skill/references/development-commands.md @@ -0,0 +1,305 @@ +# Development Commands + +Commands for working within an active loom workspace. + +## il spin + +Launch Claude CLI with auto-detected loom context. + +**Aliases:** `ignite` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--one-shot ` | enum | `default` | Automation mode: `default`, `noReview`, `bypassPermissions` | +| `--yolo` | boolean | `false` | Shorthand for `--one-shot=bypassPermissions` | +| `-p, --print` | boolean | `false` | Headless mode for CI/CD (implies `bypassPermissions`) | +| `--output-format ` | enum | β€” | Output format: `json`, `stream-json`, `text` (requires `--print`) | +| `--verbose` | boolean | β€” | Verbose output (requires `--print`) | +| `--json` | boolean | `false` | Final result as JSON (requires `--print`) | +| `--json-stream` | boolean | `false` | Stream JSONL output (requires `--print`) | + +### Examples + +```bash +# Launch Claude in background with autonomous mode +bash pty:true background:true command:"il spin --yolo" + +# Headless mode with JSON output +bash pty:true command:"il spin --yolo --print --output-format json" + +# Monitor background session +process action:log sessionId:XXX +process action:poll sessionId:XXX +``` + +### Background Mode + +This command **launches Claude**. Use `background:true` for long-running sessions. + +--- + +## il commit + +Commit all uncommitted files with issue reference trailer. + +**Aliases:** `c` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `-m, --message ` | string | β€” | Custom commit message (skips Claude generation) | +| `--fixes` | boolean | `false` | Use "Fixes #N" trailer instead of "Refs #N" | +| `--no-review` | boolean | `false` | Skip commit message review prompt | +| `--json` | boolean | `false` | Output result as JSON (implies `--no-review`) | +| `--wip-commit` | boolean | `false` | Quick WIP commit: skip validations and pre-commit hooks | + +### Examples + +```bash +# Non-interactive commit with AI-generated message +bash pty:true command:"il commit --no-review --json" + +# Commit with custom message +bash pty:true command:"il commit -m 'fix: resolve auth timeout' --json" + +# Quick WIP commit (skips hooks and validation) +bash pty:true command:"il commit --wip-commit --json" + +# Commit that closes the issue +bash pty:true command:"il commit --fixes --no-review --json" +``` + +### Interactive Prompts and Bypasses + +| Prompt | Bypass | +|--------|--------| +| Commit message review (accept/edit/abort) | `--no-review` or `--json` | + +### JSON Output + +```json +{ + "success": true, + "commitHash": "abc1234", + "message": "fix: resolve auth timeout\n\nRefs #42", + "filesChanged": 3, + "issueNumber": 42, + "trailerType": "Refs" +} +``` + +--- + +## il rebase + +Rebase current loom branch on main with AI-assisted conflict resolution. + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `-f, --force` | boolean | `false` | Force rebase even in edge cases | +| `-n, --dry-run` | boolean | `false` | Simulate rebase without changes | + +### Examples + +```bash +# Rebase with force (skip edge case checks) +bash pty:true command:"il rebase --force" + +# Dry run +bash pty:true command:"il rebase --dry-run" +``` + +### Behavior + +- Detects uncommitted changes and throws if found (commit first) +- Claude assists with conflict resolution if conflicts arise +- Post-rebase: installs dependencies and runs build (non-blocking) +- No JSON output mode + +--- + +## il build + +Run the build script for the current workspace. + +```bash +bash pty:true command:"il build" +``` + +No flags. Runs in foreground. No JSON output. + +--- + +## il test + +Run the test script for the current workspace. + +```bash +bash pty:true command:"il test" +``` + +No flags. Runs in foreground. No JSON output. + +--- + +## il lint + +Run the lint script for the current workspace. + +```bash +bash pty:true command:"il lint" +``` + +No flags. Runs in foreground. No JSON output. + +--- + +## il compile + +Run the TypeScript compiler check for the current workspace. + +**Aliases:** `typecheck` + +```bash +bash pty:true command:"il compile" +``` + +No flags. Runs in foreground. No JSON output. + +--- + +## il dev-server + +Start the development server for a workspace. + +**Aliases:** `dev` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `[identifier]` | positional | β€” | Issue number, PR number, or branch name (auto-detected) | +| `--json` | boolean | `false` | Output result as JSON | + +### Examples + +```bash +# Start dev server (auto-detect workspace) +bash pty:true command:"il dev-server --json" + +# Start dev server for specific issue +bash pty:true command:"il dev-server 42 --json" +``` + +### JSON Output + +```json +{ + "status": "started", + "url": "http://localhost:3042", + "port": 3042, + "pid": 12345, + "message": "Dev server started" +} +``` + +Port is calculated as `basePort + issue/PR number` (default base: 3000). + +--- + +## il shell + +Open an interactive shell with workspace environment variables loaded. + +**Aliases:** `terminal` + +```bash +bash pty:true command:"il shell" +``` + +No flags. Opens a subshell with the loom's `.env` variables injected. + +--- + +## il open + +Open the loom in browser (web projects) or run the configured CLI tool. + +**Aliases:** `run` + +```bash +bash pty:true command:"il open" +bash pty:true command:"il open 42" +``` + +Accepts an optional `[identifier]` positional argument. + +--- + +## il vscode + +Open the workspace in VS Code and install the iloom extension. + +```bash +bash pty:true command:"il vscode" +bash pty:true command:"il vscode --no-wait" +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--no-wait` | boolean | `false` | Don't wait for VS Code to close | + +--- + +## il summary + +Generate a Claude session summary for a loom. + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `[identifier]` | positional | β€” | Issue number, PR number, branch name, or Linear/Jira ID (auto-detected) | +| `--with-comment` | boolean | `false` | Post summary as comment to issue/PR | +| `--json` | boolean | `false` | Output result as JSON | + +### Examples + +```bash +# Generate summary for current loom +bash pty:true command:"il summary --json" + +# Generate and post as comment +bash pty:true command:"il summary --with-comment --json" +``` + +### JSON Output + +```json +{ + "summary": "## Session Summary\n...", + "sessionId": "uuid", + "branchName": "feat/42-feature", + "loomType": "issue", + "issueNumber": 42 +} +``` + +--- + +## il recap + +Get the recap (decisions, insights, risks, assumptions) for a loom. + +```bash +bash pty:true command:"il recap --json" +``` + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--json` | boolean | `false` | Output result as JSON | diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md new file mode 100644 index 00000000..ddddcaee --- /dev/null +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -0,0 +1,231 @@ +# Non-Interactive Patterns + +How to run iloom commands autonomously without hitting interactive prompts. + +## PTY Requirement + +iloom is an interactive terminal application built with Node.js. It uses colored output, spinners, and readline-based prompts that require a pseudo-terminal. + +**Always use `pty:true`** for every iloom command: + +```bash +# Correct +bash pty:true command:"il list --json" + +# Wrong - output may break or command may hang +bash command:"il list --json" +``` + +--- + +## Background vs Foreground Commands + +### Background Commands (use `background:true`) + +These commands launch Claude Code and run for extended periods: + +| Command | Recommended Invocation | +|---------|----------------------| +| `il start` | `bash pty:true background:true command:"il start 42 --yolo --no-code --json"` | +| `il spin` | `bash pty:true background:true command:"il spin --yolo"` | +| `il plan` | `bash pty:true background:true command:"il plan --yolo"` | + +### Foreground Commands (no `background:true`) + +These commands complete quickly and return structured output: + +| Command | Recommended Invocation | +|---------|----------------------| +| `il list` | `bash pty:true command:"il list --json"` | +| `il commit` | `bash pty:true command:"il commit --no-review --json"` | +| `il finish` | `bash pty:true command:"il finish --force --cleanup --no-browser --json"` | +| `il cleanup` | `bash pty:true command:"il cleanup --issue 42 --force --json"` | +| `il build` | `bash pty:true command:"il build"` | +| `il test` | `bash pty:true command:"il test"` | +| `il lint` | `bash pty:true command:"il lint"` | +| `il compile` | `bash pty:true command:"il compile"` | +| `il issues` | `bash pty:true command:"il issues --json"` | +| `il add-issue` | `bash pty:true command:"il add-issue 'description' --json"` | +| `il enhance` | `bash pty:true command:"il enhance 42 --no-browser --json"` | +| `il summary` | `bash pty:true command:"il summary --json"` | +| `il recap` | `bash pty:true command:"il recap --json"` | + +### Special: Foreground Only (no background, no JSON) + +| Command | Note | +|---------|------| +| `il init` | Interactive wizard, must run foreground | +| `il rebase` | May need Claude for conflict resolution | +| `il shell` | Opens interactive subshell | + +--- + +## Session Lifecycle (Background Commands) + +```bash +# 1. Start the command in background +bash pty:true background:true command:"il start 42 --yolo --no-code --json" +# Returns: sessionId + +# 2. Check if still running +process action:poll sessionId:XXX + +# 3. View output / progress +process action:log sessionId:XXX + +# 4. Send input if the agent asks a question +process action:submit sessionId:XXX data:"yes" + +# 5. Send raw data without newline +process action:write sessionId:XXX data:"y" + +# 6. Terminate if needed +process action:kill sessionId:XXX +``` + +--- + +## Decision Bypass Map + +Every interactive prompt in iloom and the flag(s) that bypass it: + +| Command | Prompt | Bypass Flag(s) | +|---------|--------|---------------| +| `start` | "Enter issue number..." | Provide `[identifier]` argument | +| `start` | "Create as a child loom?" | `--child-loom` or `--no-child-loom` | +| `start` | "bypassPermissions warning" | Already implied by `--yolo`; or `--no-claude` | +| `finish` | "Clean up worktree?" | `--cleanup` or `--no-cleanup` | +| `finish` | Commit message review | `--force` | +| `finish` | General confirmations | `--force` | +| `cleanup` | "Remove this worktree?" | `--force` | +| `cleanup` | "Remove N worktree(s)?" | `--force` | +| `commit` | Commit message review | `--no-review` or `--json` | +| `enhance` | "Press q or key to view..." | `--no-browser` or `--json` | +| `enhance` | First-run setup | `--json` | +| `add-issue` | "Press key to view in browser" | `--json` | +| `add-issue` | First-run setup | `--json` | + +--- + +## Recommended Autonomous Flag Combinations + +### Full Autonomous Start (create workspace) + +```bash +bash pty:true background:true command:"il start --yolo --no-code --json" +``` + +- `--yolo`: bypass all permission prompts +- `--no-code`: don't open VS Code +- `--json`: structured output + +### Full Autonomous Finish (merge and cleanup) + +```bash +bash pty:true command:"il finish --force --cleanup --no-browser --json" +``` + +- `--force`: skip all confirmations +- `--cleanup`: auto-cleanup worktree +- `--no-browser`: don't open browser +- `--json`: structured output + +### Headless Planning + +```bash +bash pty:true command:"il plan --yolo --print --output-format json" +``` + +- `--yolo`: autonomous mode +- `--print`: headless output +- `--output-format json`: structured JSON response + +### Non-Interactive Commit + +```bash +bash pty:true command:"il commit --no-review --json" +``` + +- `--no-review`: skip message review +- `--json`: structured output (also implies `--no-review`) + +### Quick Cleanup + +```bash +bash pty:true command:"il cleanup --issue --force --json" +``` + +- `--force`: skip confirmation +- `--json`: structured output + +--- + +## JSON Output Commands + +Commands that support `--json` for machine-parseable output: + +| Command | JSON Flag | Notes | +|---------|-----------|-------| +| `il start` | `--json` | Returns workspace metadata | +| `il finish` | `--json` | Returns operation results | +| `il cleanup` | `--json` | Returns cleanup results | +| `il list` | `--json` | Returns array of loom objects | +| `il commit` | `--json` | Returns commit details (implies `--no-review`) | +| `il issues` | `--json` | Returns array of issues/PRs | +| `il add-issue` | `--json` | Returns created issue | +| `il enhance` | `--json` | Returns enhancement result | +| `il summary` | `--json` | Returns summary text and metadata | +| `il recap` | `--json` | Returns recap data | +| `il dev-server` | `--json` | Returns server status | +| `il projects` | `--json` | Returns project list | +| `il plan` | `--json` | Returns planning result (requires `--print`) | +| `il spin` | `--json` | Returns result (requires `--print`) | + +--- + +## Auto-Notify on Completion + +For long-running background tasks, append a wake trigger so OpenClaw gets notified when iloom finishes: + +```bash +bash pty:true background:true command:"il start 42 --yolo --no-code --json && openclaw system event --text 'Done: Loom created for issue #42' --mode now" +``` + +This triggers an immediate wake event instead of waiting for the next heartbeat. + +--- + +## Error Handling + +### Exit Codes + +| Code | Meaning | +|------|---------| +| `0` | Success | +| `1` | General error | +| `130` | User aborted (e.g., Ctrl+C during commit review) | + +### JSON Error Format + +When `--json` is used and a command fails: + +```json +{ + "success": false, + "error": "Error message describing what went wrong" +} +``` + +### Fallback: process action:submit + +If a command hits an unexpected prompt that can't be bypassed with flags, use `process action:submit` to send input: + +```bash +# If a command unexpectedly asks for confirmation +process action:submit sessionId:XXX data:"y" + +# If it asks for text input +process action:submit sessionId:XXX data:"some value" +``` + +This should be rare β€” the flag combinations above cover all known interactive prompts. If you encounter an undocumented prompt, submit a reasonable default and note it for future reference. diff --git a/openclaw-skill/references/planning-and-issues.md b/openclaw-skill/references/planning-and-issues.md new file mode 100644 index 00000000..0c176255 --- /dev/null +++ b/openclaw-skill/references/planning-and-issues.md @@ -0,0 +1,229 @@ +# Planning and Issue Management + +## il plan + +Launch an interactive AI planning session to decompose features into child issues. + +**When to use:** Whenever the user has an idea for an improvement, new feature, or wants to break down work into implementable tasks. This is the primary ideation tool β€” always prefer `il plan` over manually creating issues. + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `[prompt]` | positional | β€” | Planning topic or issue identifier (e.g., `#123`, `ENG-456`) | +| `--model ` | string | `opus` | Claude model: `opus`, `sonnet`, `haiku` | +| `--yolo` | boolean | `false` | Autonomous mode (bypass all permission prompts) | +| `--planner ` | enum | `claude` | AI planner: `claude`, `gemini`, `codex` | +| `--reviewer ` | enum | `none` | AI reviewer: `claude`, `gemini`, `codex`, `none` | +| `-p, --print` | boolean | `false` | Headless mode for CI/CD (implies `--yolo`) | +| `--output-format ` | enum | β€” | Output format: `json`, `stream-json`, `text` (requires `--print`) | +| `--verbose` | boolean | β€” | Verbose output (requires `--print`) | +| `--json` | boolean | `false` | Final result as JSON (requires `--print`) | +| `--json-stream` | boolean | `false` | Stream JSONL output (requires `--print`) | + +### Modes + +**Fresh Planning Mode** β€” no identifier provided: +```bash +# Interactive planning session (background, autonomous) +bash pty:true background:true command:"il plan --yolo" + +# Headless planning with JSON output +bash pty:true command:"il plan --yolo --print --output-format json" +``` + +**Issue Decomposition Mode** β€” issue identifier provided: +```bash +# Decompose existing issue #123 into child tasks +bash pty:true background:true command:"il plan '#123' --yolo" + +# Linear issue decomposition +bash pty:true background:true command:"il plan 'ENG-456' --yolo" +``` + +### Background Mode + +This command **launches Claude**. Use `background:true` for interactive sessions: + +```bash +bash pty:true background:true command:"il plan --yolo" + +# Monitor the planning session +process action:log sessionId:XXX +process action:poll sessionId:XXX + +# Send input if the planner asks a question +process action:submit sessionId:XXX data:"Option A" +``` + +### JSON Output (with `--print`) + +```json +{ + "success": true, + "output": "[Claude planning response]" +} +``` + +### Capabilities + +The planner has access to: +- Issue management (create issues, child issues, dependencies, comments) +- Code exploration (Read, Glob, Grep) +- Web search and fetch +- Git commands (read-only: status, log, branch, remote, diff, show) + +--- + +## il add-issue + +Create a new issue with AI-enhanced description. + +**Aliases:** `a` + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `` | positional | β€” | Issue title/description (required, >30 chars, >3 words unless `--body` used) | +| `--body ` | string | β€” | Issue body text (bypasses length/word validation) | +| `--json` | boolean | `false` | Output result as JSON (non-interactive) | + +### Examples + +```bash +# Create issue with AI enhancement (non-interactive) +bash pty:true command:"il add-issue 'Add dark mode toggle to settings page' --json" + +# Create issue with explicit body +bash pty:true command:"il add-issue 'Fix login timeout' --body 'Users report 504 errors after 30 seconds' --json" +``` + +### Behavior + +1. Validates description format +2. Runs description through AI enhancement agent (always) +3. Creates the issue on the configured tracker +4. Returns structured result in `--json` mode + +### Interactive Prompts and Bypasses + +| Prompt | Bypass | +|--------|--------| +| First-run setup | `--json` (skips setup) | +| "Press key to view in browser" | `--json` (skips browser) | + +### JSON Output + +```json +{ + "url": "https://github.com/owner/repo/issues/123", + "id": 123, + "title": "Add dark mode toggle to settings page", + "created_at": "2026-02-17T12:00:00.000Z" +} +``` + +--- + +## il enhance + +Apply AI enhancement to an existing issue's description. + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `` | positional | β€” | Issue number or identifier (required) | +| `--no-browser` | boolean | `false` | Skip browser opening prompt | +| `--author ` | string | β€” | GitHub username to tag in questions | +| `--json` | boolean | `false` | Output result as JSON (non-interactive) | + +### Examples + +```bash +# Enhance issue #42 (non-interactive) +bash pty:true command:"il enhance 42 --no-browser --json" + +# Enhance with author tagging +bash pty:true command:"il enhance 42 --author johndoe --no-browser --json" +``` + +### Interactive Prompts and Bypasses + +| Prompt | Bypass | +|--------|--------| +| First-run setup | `--json` (skips setup) | +| "Press q to quit or key to view..." | `--no-browser` or `--json` | + +### JSON Output + +```json +{ + "url": "https://github.com/owner/repo/issues/42#issuecomment-789", + "id": 789, + "title": "Issue Title", + "created_at": "2026-02-17T12:00:00.000Z", + "enhanced": true +} +``` + +The `enhanced` field is `false` if the issue already had a thorough description. + +--- + +## il issues + +List open issues and PRs from the configured tracker. + +### Flags + +| Flag | Type | Default | Description | +|------|------|---------|-------------| +| `--json` | boolean | `false` | Output as JSON array | +| `--limit ` | number | `100` | Max number of results | +| `--sprint ` | string | β€” | Filter by sprint (Jira only) | +| `--mine` | boolean | `false` | Show only my issues (Jira only) | + +### Examples + +```bash +# List all open issues as JSON +bash pty:true command:"il issues --json" + +# List with limit +bash pty:true command:"il issues --json --limit 20" + +# Jira: filter by sprint +bash pty:true command:"il issues --json --sprint 'Sprint 5'" +``` + +### Behavior + +- Always returns JSON array (no interactive output) +- Results cached for 2 minutes +- Includes both issues and PRs (PRs from GitHub regardless of issue tracker) +- Sorted by `updatedAt` descending + +### JSON Output + +```json +[ + { + "id": "123", + "title": "Fix login timeout", + "updatedAt": "2026-02-17T12:00:00.000Z", + "url": "https://github.com/owner/repo/issues/123", + "state": "open", + "type": "issue" + }, + { + "id": "99", + "title": "Add dark mode", + "updatedAt": "2026-02-16T10:00:00.000Z", + "url": "https://github.com/owner/repo/pull/99", + "state": "open", + "type": "pr" + } +] +``` From c0160d8137f58a7c40b4ed46788b0b54f148340a Mon Sep 17 00:00:00 2001 From: Helix Date: Wed, 18 Feb 2026 01:53:12 -0800 Subject: [PATCH 02/13] feat(openclaw-skill): improve agent patterns for initialization, planning, and streaming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add initialization.md reference with full settings schema and manual setup guide - Replace il init recommendation with direct settings file creation for AI agents - Update plan/spin commands to use --print --json-stream in background mode - Document sizeable vs small change workflows (planβ†’reviewβ†’startβ†’spin vs inline start) - Mark il init as human-only, not recommended for AI agents --- openclaw-skill/SKILL.md | 85 ++++-- openclaw-skill/references/initialization.md | 258 ++++++++++++++++++ .../references/non-interactive-patterns.md | 21 +- 3 files changed, 330 insertions(+), 34 deletions(-) create mode 100644 openclaw-skill/references/initialization.md diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index 53417029..6cf1c47d 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -22,48 +22,74 @@ bash command:"il list --json" ## Project Initialization (First-Time Setup) -Before using any iloom commands, the project must be initialized: +Before using any iloom commands, the project must have a `.iloom/settings.json` file. + +**Preferred: Manual setup (recommended for AI agents)** + +Create the settings files directly β€” no interactive wizard needed: ```bash -# 1. Initialize your project (if not already done) -bash pty:true command:"pnpm init" # or npm init, cargo init, etc. +mkdir -p .iloom +echo '{"mainBranch": "main"}' > .iloom/settings.json +``` -# 2. Initialize git (if not already done) -bash pty:true command:"git init && git add -A && git commit -m 'Initial commit'" +See `{baseDir}/references/initialization.md` for the complete settings schema, all configuration options, and example configurations. -# 3. Initialize iloom (interactive setup wizard) +**Alternative: Interactive wizard (for humans at a terminal)** + +```bash bash pty:true command:"il init" ``` -`il init` launches an interactive configuration wizard. It must run in the foreground with PTY. +`il init` launches an interactive Claude-guided configuration wizard. It requires foreground PTY and is designed for human interaction β€” **not recommended for AI agents** due to nested interactive prompts and timeout sensitivity. -## Quick Start +## Workflow: Choosing the Right Approach -### Check active workspaces +### Sizeable Changes (multiple issues, architectural work) -```bash -bash pty:true command:"il list --json" -``` +For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflow: -### Start a loom for an issue (launches Claude in background) +1. **Plan:** Decompose the work into issues + ```bash + bash pty:true background:true command:"il plan --yolo --print --json-stream" + # Monitor: process action:poll sessionId:XXX + ``` -```bash -bash pty:true background:true command:"il start 42 --yolo --no-code --json" -# Monitor: process action:log sessionId:XXX -# Check: process action:poll sessionId:XXX -``` +2. **Review:** Present the created epic to the user for review (unless they've said to proceed without review). Wait for approval before continuing. + +3. **Start:** Create the workspace without launching Claude or dev server + ```bash + bash pty:true command:"il start --yolo --no-code --no-dev-server --no-claude --json" + ``` + +4. **Spin:** Launch Claude separately with streaming output + ```bash + bash pty:true background:true command:"il spin --yolo --print --json-stream" + # Monitor: process action:poll sessionId:XXX + ``` + +5. **Finish:** Merge and clean up + ```bash + bash pty:true command:"il finish --force --cleanup --no-browser --json" + ``` + +### Small Changes (single issue, quick fix) -### Finish and merge a loom +For small, self-contained tasks, use inline start with a description: ```bash -bash pty:true command:"il finish --force --cleanup --no-browser --json" +bash pty:true background:true command:"il start 'Add dark mode support to the settings page' --yolo --no-code --json" +# Monitor: process action:poll sessionId:XXX ``` -### Launch Claude in existing loom +This creates the issue, workspace, and launches Claude in one step. + +## Quick Reference + +### Check active workspaces ```bash -bash pty:true background:true command:"il spin --yolo" -# Monitor: process action:log sessionId:XXX +bash pty:true command:"il list --json" ``` ### Commit with AI-generated message @@ -77,15 +103,18 @@ bash pty:true command:"il commit --no-review --json" When the user has an idea for an improvement, new feature, or wants to decompose work into issues, use `il plan`: ```bash -bash pty:true background:true command:"il plan --yolo" -# Or for headless output: -bash pty:true command:"il plan --yolo --print --output-format json" +bash pty:true background:true command:"il plan --yolo --print --json-stream" +# Monitor: process action:poll sessionId:XXX +# Full log: process action:log sessionId:XXX ``` -`il plan` launches an interactive AI planning session that creates structured issues with dependencies. Always prefer this over manually creating issues. +`il plan` launches an autonomous AI planning session that reads the codebase and creates structured issues with dependencies. Always prefer this over manually creating issues. + +**Important:** Both `plan` and `spin` should always be run in **background mode** (`background:true`) with `--print --json-stream`. These commands can run for several minutes (especially with Opus) as they analyze the codebase, and foreground timeouts will kill them. The `--json-stream` flag ensures incremental output is visible via `process action:poll`. ## References +- **Project initialization and settings schema:** See `{baseDir}/references/initialization.md` - **Core lifecycle commands (init, start, finish, cleanup, list):** See `{baseDir}/references/core-workflow.md` - **Development commands (spin, commit, rebase, build, test, etc.):** See `{baseDir}/references/development-commands.md` - **Planning and issue management (plan, add-issue, enhance, issues):** See `{baseDir}/references/planning-and-issues.md` @@ -99,5 +128,5 @@ bash pty:true command:"il plan --yolo --print --output-format json" 3. **Never run `il finish` without `--force`** in autonomous mode β€” it will hang on confirmation prompts. 4. **Always pass explicit flags** to avoid interactive prompts. See `{baseDir}/references/non-interactive-patterns.md` for the complete decision bypass map. 5. **Use `--json`** when you need to parse command output programmatically. -6. **Do not run `il init` in background mode** β€” it requires foreground interactive setup. +6. **Prefer manual initialization** over `il init` β€” create `.iloom/settings.json` directly. See `{baseDir}/references/initialization.md`. 7. **Respect worktree isolation** β€” each loom is an independent workspace. Run commands from within the correct worktree directory. diff --git a/openclaw-skill/references/initialization.md b/openclaw-skill/references/initialization.md new file mode 100644 index 00000000..2bdea9f3 --- /dev/null +++ b/openclaw-skill/references/initialization.md @@ -0,0 +1,258 @@ +# Initialization (Manual Setup) + +How to set up iloom for a project without using the interactive `il init` wizard. + +## When to Use This + +Use manual initialization instead of `il init` when: +- You are an AI agent and cannot reliably drive the interactive wizard +- You want deterministic, reproducible setup +- You need to initialize many projects quickly + +## Prerequisites + +1. The project must be a **git repository** with at least one commit +2. The project must have a **remote** configured (for GitHub issue tracking) +3. iloom CLI must be installed (`il --version` to verify) + +## Step-by-Step Setup + +### 1. Create the `.iloom` directory + +```bash +mkdir -p /.iloom +``` + +### 2. Create `.iloom/settings.json` (project settings β€” committed to git) + +This file contains shared project configuration. At minimum: + +```json +{ + "mainBranch": "main" +} +``` + +A typical project setup: + +```json +{ + "mainBranch": "main", + "colors": { + "terminal": true, + "vscode": true + }, + "mergeBehavior": { + "mode": "github-draft-pr" + } +} +``` + +### 3. Create `.iloom/settings.local.json` (personal settings β€” gitignored) + +This file contains per-developer preferences that should NOT be committed: + +```json +{ + "workflows": { + "issue": { + "permissionMode": "acceptEdits" + } + } +} +``` + +### 4. Update `.gitignore` + +Ensure local/personal files are not tracked: + +```bash +# Add to .gitignore +echo '.iloom/settings.local.json' >> .gitignore +echo '.vscode/settings.json' >> .gitignore # Only if colors.vscode is true +``` + +### 5. Validate the configuration + +Run any iloom command to verify settings are loaded: + +```bash +il list --json +``` + +If settings are valid, this returns a JSON array of looms. If there are errors, iloom will report them. + +### 6. (Optional) Validate against JSON Schema + +The settings JSON schema is bundled at `/dist/schema/settings.schema.json`. You can validate your settings programmatically: + +```bash +# Using ajv-cli (npm install -g ajv-cli) +ajv validate -s "$(dirname $(which il))/../dist/schema/settings.schema.json" -d .iloom/settings.json + +# Or using node inline +node -e " +const schema = require('$(dirname $(which il))/../dist/schema/settings.schema.json'); +const settings = require('./.iloom/settings.json'); +// Basic structural check β€” schema is JSON Schema Draft 7 +console.log('Settings loaded:', Object.keys(settings)); +" +``` + +## Settings Reference + +### Layering Order (highest to lowest priority) + +1. **Local** β€” `.iloom/settings.local.json` (gitignored, per-machine) +2. **Project** β€” `.iloom/settings.json` (committed, shared with team) +3. **Global** β€” `~/.config/iloom-ai/settings.json` (all projects on this machine) + +Local overrides project, project overrides global. + +### Complete Settings Schema + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `mainBranch` | string | auto-detected | Primary branch name (`main`, `master`, etc.) | +| `sourceEnvOnStart` | boolean | `false` | Source dotenv-flow files when launching processes | +| `worktreePrefix` | string | `-looms` | Prefix for worktree directories (empty string disables) | +| `protectedBranches` | string[] | `[mainBranch, "main", "master", "develop"]` | Branches that cannot be deleted | +| `copyGitIgnoredPatterns` | string[] | `[]` | Glob patterns for gitignored files to copy to looms | + +#### `workflows` β€” Per-workflow-type settings + +Each workflow type (`issue`, `pr`, `regular`) supports: + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `permissionMode` | enum | `"default"` | `"plan"` \| `"acceptEdits"` \| `"bypassPermissions"` \| `"default"` | +| `noVerify` | boolean | `false` | Skip pre-commit hooks during commit/finish | +| `startIde` | boolean | `true` | Open IDE when starting a loom | +| `startDevServer` | boolean | `true` | Launch dev server on start | +| `startAiAgent` | boolean | `true` | Launch Claude Code on start | +| `startTerminal` | boolean | `false` | Open terminal window on start | +| `generateSummary` | boolean | `true` | Generate session summary on finish | + +#### `agents` β€” Per-agent configuration + +Available agents: `iloom-issue-analyzer`, `iloom-issue-planner`, `iloom-issue-analyze-and-plan`, `iloom-issue-complexity-evaluator`, `iloom-issue-enhancer`, `iloom-issue-implementer`, `iloom-code-reviewer`, `iloom-artifact-reviewer` + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `model` | enum | β€” | `"sonnet"` \| `"opus"` \| `"haiku"` | +| `enabled` | boolean | `true` | Whether this agent is enabled | +| `review` | boolean | `false` | Review artifacts before posting | +| `providers` | object | β€” | Map of `claude`/`gemini`/`codex` to model name strings | + +#### `plan` β€” Planning command settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `model` | enum | `"opus"` | Claude model for planning | +| `planner` | enum | `"claude"` | AI provider: `"claude"` \| `"gemini"` \| `"codex"` | +| `reviewer` | enum | `"none"` | Review provider: `"claude"` \| `"gemini"` \| `"codex"` \| `"none"` | + +#### `spin` β€” Spin orchestrator settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `model` | enum | `"opus"` | Claude model for spin | + +#### `summary` β€” Session summary settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `model` | enum | `"sonnet"` | Claude model for summaries | + +#### `issueManagement` β€” Issue tracker configuration + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `provider` | enum | `"github"` | `"github"` \| `"linear"` \| `"jira"` | +| `github.remote` | string | β€” | Git remote name for GitHub operations | +| `linear.teamId` | string | β€” | Linear team identifier (e.g., `"ENG"`) | +| `linear.apiToken` | string | β€” | **Local only** β€” never commit | +| `jira.host` | string | β€” | Jira instance URL | +| `jira.username` | string | β€” | Jira username/email | +| `jira.apiToken` | string | β€” | **Local only** β€” never commit | +| `jira.projectKey` | string | β€” | Jira project key (e.g., `"PROJ"`) | + +#### `mergeBehavior` β€” How looms are merged + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `mode` | enum | `"local"` | `"local"` \| `"github-pr"` \| `"github-draft-pr"` | +| `remote` | string | β€” | Git remote for PR creation | +| `autoCommitPush` | boolean | `true` (draft PR) | Auto-commit and push after code review | + +#### `ide` β€” Editor configuration + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `type` | enum | `"vscode"` | `"vscode"` \| `"cursor"` \| `"webstorm"` \| `"sublime"` \| `"intellij"` \| `"windsurf"` \| `"antigravity"` | + +#### `colors` β€” Visual identification + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `terminal` | boolean | `true` | Terminal background colors per branch (macOS only) | +| `vscode` | boolean | `false` | VSCode title bar colors per branch | + +#### `attribution` + +| Value | Description | +|-------|-------------| +| `"off"` | Never show iloom attribution | +| `"upstreamOnly"` | Only for external/open-source repos (default) | +| `"on"` | Always show attribution | + +#### `git` β€” Git operation settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `commitTimeout` | number | `60000` | Timeout (ms) for git commit operations (1s–600s) | + +## Example: Full Configuration + +**`.iloom/settings.json`** (committed): +```json +{ + "mainBranch": "main", + "mergeBehavior": { + "mode": "github-draft-pr" + }, + "issueManagement": { + "provider": "github" + }, + "colors": { + "terminal": true, + "vscode": true + }, + "agents": { + "iloom-issue-implementer": { "model": "opus" }, + "iloom-code-reviewer": { + "providers": { "gemini": "gemini-3-pro-preview" } + }, + "iloom-artifact-reviewer": { + "enabled": true, + "providers": { "gemini": "gemini-3-pro-preview" } + } + }, + "attribution": "on" +} +``` + +**`.iloom/settings.local.json`** (gitignored): +```json +{ + "workflows": { + "issue": { + "permissionMode": "bypassPermissions", + "noVerify": true, + "startIde": false, + "startAiAgent": true, + "startTerminal": false + } + } +} +``` diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index ddddcaee..0bbee78e 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -22,13 +22,19 @@ bash command:"il list --json" ### Background Commands (use `background:true`) -These commands launch Claude Code and run for extended periods: +These commands launch Claude Code and run for extended periods. **Always run in background** to avoid timeout kills: | Command | Recommended Invocation | |---------|----------------------| | `il start` | `bash pty:true background:true command:"il start 42 --yolo --no-code --json"` | -| `il spin` | `bash pty:true background:true command:"il spin --yolo"` | -| `il plan` | `bash pty:true background:true command:"il plan --yolo"` | +| `il spin` | `bash pty:true background:true command:"il spin --yolo --print --json-stream"` | +| `il plan` | `bash pty:true background:true command:"il plan --yolo --print --json-stream"` | + +**Why `--print --json-stream` for `plan` and `spin`?** +- `--print` enables headless/non-interactive output mode +- `--json-stream` streams JSONL incrementally so you can monitor progress via `process action:poll` +- Without `--json-stream`, `--print` buffers ALL output until completion (no visibility into what Claude is doing) +- These commands can easily run 3-10+ minutes with Opus analyzing a codebase β€” foreground timeouts will kill them ### Foreground Commands (no `background:true`) @@ -54,7 +60,7 @@ These commands complete quickly and return structured output: | Command | Note | |---------|------| -| `il init` | Interactive wizard, must run foreground | +| `il init` | Interactive wizard, must run foreground. **Not recommended for AI agents** β€” use manual setup instead (see `{baseDir}/references/initialization.md`) | | `il rebase` | May need Claude for conflict resolution | | `il shell` | Opens interactive subshell | @@ -133,12 +139,15 @@ bash pty:true command:"il finish --force --cleanup --no-browser --json" ### Headless Planning ```bash -bash pty:true command:"il plan --yolo --print --output-format json" +bash pty:true background:true command:"il plan --yolo --print --json-stream" +# Monitor: process action:poll sessionId:XXX +# Full log: process action:log sessionId:XXX ``` - `--yolo`: autonomous mode - `--print`: headless output -- `--output-format json`: structured JSON response +- `--json-stream`: stream JSONL incrementally (visible via poll/log) +- `background:true`: **required** β€” planning sessions can run 3-10+ minutes ### Non-Interactive Commit From 62b81e5b93fb2dd5c11be97c06937648f0538414 Mon Sep 17 00:00:00 2001 From: Helix Date: Wed, 18 Feb 2026 02:20:15 -0800 Subject: [PATCH 03/13] =?UTF-8?q?docs:=20add=20safety=20rules=20=E2=80=94?= =?UTF-8?q?=20never=20kill=20foreign=20sessions,=20send=20progress=20updat?= =?UTF-8?q?es=20mid-turn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openclaw-skill/SKILL.md | 2 ++ openclaw-skill/references/non-interactive-patterns.md | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index 6cf1c47d..44139d7a 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -130,3 +130,5 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream" 5. **Use `--json`** when you need to parse command output programmatically. 6. **Prefer manual initialization** over `il init` β€” create `.iloom/settings.json` directly. See `{baseDir}/references/initialization.md`. 7. **Respect worktree isolation** β€” each loom is an independent workspace. Run commands from within the correct worktree directory. +8. **NEVER kill a background session you did not start.** Other looms may be running from separate planning or development sessions (the user's own work, other agents, or prior conversations). When you see unfamiliar background sessions, **leave them alone**. Only kill sessions you explicitly launched in the current workflow. If unsure, ask the user. +9. **Send progress updates mid-turn.** Long-running loom operations (plan, spin, commit, finish) can take minutes. Use the `message` tool to send incremental status updates to the user while waiting β€” don't go silent. Examples: "🧡 Spin started for issue #5, monitoring…", "βœ… Tests passing, spin entering code review phase", "πŸ”€ Merging to main…". Keep the user in the loop. diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index 0bbee78e..f1f10832 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -85,10 +85,14 @@ process action:submit sessionId:XXX data:"yes" # 5. Send raw data without newline process action:write sessionId:XXX data:"y" -# 6. Terminate if needed +# 6. Terminate if needed (YOUR sessions only β€” see warning below) process action:kill sessionId:XXX ``` +> ⚠️ **CRITICAL: Never kill a session you did not start.** +> +> When listing background processes, you may see sessions from other workflows β€” the user's own planning sessions, other agents, or prior conversations. These are **not yours to manage**. Only kill sessions you explicitly launched in the current workflow. If you're unsure whether a session is yours, **ask the user** before terminating it. Killing someone else's long-running `plan` or `spin` session destroys work in progress that cannot be recovered. + --- ## Decision Bypass Map From 0cc7a99c66881c35a3eca1d70af7aeeae9f53178 Mon Sep 17 00:00:00 2001 From: Helix Date: Wed, 18 Feb 2026 10:20:58 -0800 Subject: [PATCH 04/13] [iloom] Temporary commit for draft PR (will be removed on finish) From 5e59ff8eb5476959469a3df60e3868809679414a Mon Sep 17 00:00:00 2001 From: Helix Date: Wed, 18 Feb 2026 10:22:21 -0800 Subject: [PATCH 05/13] docs: guide LLM to ask user about GitHub remote config - Add 'GitHub Remote Configuration' section to SKILL.md explaining fork workflows and why agents should ask users instead of auto-configuring - Document settings.local.json for per-developer remote preferences - Add --no-terminal to all autonomous start patterns (SKILL.md and non-interactive-patterns.md) - Add fork workflow step to initialization.md manual setup guide - Add terminal window bypass to decision bypass map Closes #7 --- openclaw-skill/SKILL.md | 37 ++++++++++++++++++- openclaw-skill/references/initialization.md | 29 +++++++++++++-- .../references/non-interactive-patterns.md | 6 ++- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index 44139d7a..fe9b7113 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -43,6 +43,41 @@ bash pty:true command:"il init" `il init` launches an interactive Claude-guided configuration wizard. It requires foreground PTY and is designed for human interaction β€” **not recommended for AI agents** due to nested interactive prompts and timeout sensitivity. +## GitHub Remote Configuration (Fork Workflows) + +When a project has **multiple git remotes** (e.g., `origin` + `fork`, or `upstream` + `origin`), iloom needs to know which remote to use for issue management and which to push to. + +**Do NOT auto-configure `issueManagement.github.remote`.** Instead, **ask the user** which remote to target. The correct choice depends on: + +- Whether the user has write access to the upstream repo +- Whether issues live on the upstream or the fork +- Whether PRs should target the upstream or the fork + +**Use `.iloom/settings.local.json`** (not the shared `settings.json`) for per-developer remote configuration, since this is a personal preference that shouldn't be committed: + +```json +{ + "issueManagement": { + "github": { + "remote": "upstream" + } + }, + "mergeBehavior": { + "remote": "origin" + } +} +``` + +**Standard remote naming convention:** +- `origin` = your fork (where you have push access) +- `upstream` = the original repo (where issues live) + +iloom assumes `origin` is yours by default. If remotes are named differently, configure `issueManagement.github.remote` and `mergeBehavior.remote` explicitly. + +Common patterns: +- **Fork workflow:** Issues on `upstream`, push/PR from `origin` (your fork) +- **Direct access (no fork):** Both issues and push on `origin` β€” no extra config needed + ## Workflow: Choosing the Right Approach ### Sizeable Changes (multiple issues, architectural work) @@ -59,7 +94,7 @@ For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflo 3. **Start:** Create the workspace without launching Claude or dev server ```bash - bash pty:true command:"il start --yolo --no-code --no-dev-server --no-claude --json" + bash pty:true command:"il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json" ``` 4. **Spin:** Launch Claude separately with streaming output diff --git a/openclaw-skill/references/initialization.md b/openclaw-skill/references/initialization.md index 2bdea9f3..3314da33 100644 --- a/openclaw-skill/references/initialization.md +++ b/openclaw-skill/references/initialization.md @@ -62,7 +62,30 @@ This file contains per-developer preferences that should NOT be committed: } ``` -### 4. Update `.gitignore` +### 4. Configure GitHub Remote (Fork Workflows) + +If the project has **multiple git remotes** (e.g., a fork workflow), configure which remote iloom uses for issue tracking vs. pushing. **Do not guess β€” ask the user.** + +Add to `.iloom/settings.local.json` (not `settings.json`, since this is per-developer): + +```json +{ + "issueManagement": { + "github": { + "remote": "upstream" + } + }, + "mergeBehavior": { + "remote": "origin" + } +} +``` + +**Standard convention:** `origin` = your fork, `upstream` = the original repo. iloom assumes `origin` is yours by default. + +`issueManagement.github.remote` controls where issues are read/created. `mergeBehavior.remote` controls where branches are pushed and PRs are created. In fork workflows, issues live on `upstream` while you push to `origin`. + +### 5. Update `.gitignore` Ensure local/personal files are not tracked: @@ -72,7 +95,7 @@ echo '.iloom/settings.local.json' >> .gitignore echo '.vscode/settings.json' >> .gitignore # Only if colors.vscode is true ``` -### 5. Validate the configuration +### 6. Validate the configuration Run any iloom command to verify settings are loaded: @@ -82,7 +105,7 @@ il list --json If settings are valid, this returns a JSON array of looms. If there are errors, iloom will report them. -### 6. (Optional) Validate against JSON Schema +### 7. (Optional) Validate against JSON Schema The settings JSON schema is bundled at `/dist/schema/settings.schema.json`. You can validate your settings programmatically: diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index f1f10832..faa37be1 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -26,7 +26,7 @@ These commands launch Claude Code and run for extended periods. **Always run in | Command | Recommended Invocation | |---------|----------------------| -| `il start` | `bash pty:true background:true command:"il start 42 --yolo --no-code --json"` | +| `il start` | `bash pty:true background:true command:"il start 42 --yolo --no-code --no-terminal --json"` | | `il spin` | `bash pty:true background:true command:"il spin --yolo --print --json-stream"` | | `il plan` | `bash pty:true background:true command:"il plan --yolo --print --json-stream"` | @@ -104,6 +104,7 @@ Every interactive prompt in iloom and the flag(s) that bypass it: | `start` | "Enter issue number..." | Provide `[identifier]` argument | | `start` | "Create as a child loom?" | `--child-loom` or `--no-child-loom` | | `start` | "bypassPermissions warning" | Already implied by `--yolo`; or `--no-claude` | +| `start` | Opens terminal window | `--no-terminal` | | `finish` | "Clean up worktree?" | `--cleanup` or `--no-cleanup` | | `finish` | Commit message review | `--force` | | `finish` | General confirmations | `--force` | @@ -122,11 +123,12 @@ Every interactive prompt in iloom and the flag(s) that bypass it: ### Full Autonomous Start (create workspace) ```bash -bash pty:true background:true command:"il start --yolo --no-code --json" +bash pty:true background:true command:"il start --yolo --no-code --no-terminal --json" ``` - `--yolo`: bypass all permission prompts - `--no-code`: don't open VS Code +- `--no-terminal`: don't open a terminal window - `--json`: structured output ### Full Autonomous Finish (merge and cleanup) From c7ccfeb2b966c9a89089eff634750ccee070f616 Mon Sep 17 00:00:00 2001 From: Helix Date: Mon, 23 Feb 2026 17:07:15 -0800 Subject: [PATCH 06/13] docs: add --json-stream to commit, finish, and rebase patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all skill docs to reflect upstream v0.10.0 adding --json-stream support to commit, finish, and rebase commands: - SKILL.md: update finish/commit examples with --json-stream + background, expand safety rule #2 and Important note to cover all extended commands - non-interactive-patterns.md: add 'Background Commands β€” Extended Operations' section for commit/finish/rebase, move rebase out of 'Foreground Only', add autonomous rebase pattern, update JSON Output table - development-commands.md: add --json-stream flag to commit and rebase tables, update examples to use background mode - core-workflow.md: add --json-stream flag to finish table, update examples Refs #3 --- openclaw-skill/SKILL.md | 10 +++-- openclaw-skill/references/core-workflow.md | 7 ++-- .../references/development-commands.md | 12 +++--- .../references/non-interactive-patterns.md | 42 +++++++++++++++---- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index fe9b7113..c38ca58a 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -105,7 +105,8 @@ For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflo 5. **Finish:** Merge and clean up ```bash - bash pty:true command:"il finish --force --cleanup --no-browser --json" + bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream" + # Monitor: process action:poll sessionId:XXX ``` ### Small Changes (single issue, quick fix) @@ -130,7 +131,8 @@ bash pty:true command:"il list --json" ### Commit with AI-generated message ```bash -bash pty:true command:"il commit --no-review --json" +bash pty:true background:true command:"il commit --no-review --json --json-stream" +# Monitor: process action:poll sessionId:XXX ``` ## Ideation and Planning @@ -145,7 +147,7 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream" `il plan` launches an autonomous AI planning session that reads the codebase and creates structured issues with dependencies. Always prefer this over manually creating issues. -**Important:** Both `plan` and `spin` should always be run in **background mode** (`background:true`) with `--print --json-stream`. These commands can run for several minutes (especially with Opus) as they analyze the codebase, and foreground timeouts will kill them. The `--json-stream` flag ensures incremental output is visible via `process action:poll`. +**Important:** Commands that can run for extended periods β€” `plan`, `spin`, `commit`, `finish`, and `rebase` β€” should be run in **background mode** (`background:true`) with `--json-stream` (and `--print` for plan/spin). The `--json-stream` flag streams JSONL incrementally so you can monitor progress via `process action:poll`. Without it, you get zero visibility until the command completes. ## References @@ -159,7 +161,7 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream" ## Safety Rules 1. **Always use `pty:true`** for every iloom command. -2. **Use `background:true`** for commands that launch Claude: `start`, `spin`, `plan`. +2. **Use `background:true`** for commands that launch Claude or run extended operations: `start`, `spin`, `plan`, `commit`, `finish`, `rebase`. 3. **Never run `il finish` without `--force`** in autonomous mode β€” it will hang on confirmation prompts. 4. **Always pass explicit flags** to avoid interactive prompts. See `{baseDir}/references/non-interactive-patterns.md` for the complete decision bypass map. 5. **Use `--json`** when you need to parse command output programmatically. diff --git a/openclaw-skill/references/core-workflow.md b/openclaw-skill/references/core-workflow.md index 1829c1ff..20e53a7a 100644 --- a/openclaw-skill/references/core-workflow.md +++ b/openclaw-skill/references/core-workflow.md @@ -129,18 +129,19 @@ Validate, commit, merge, and clean up a loom workspace. | `--no-browser` | boolean | `false` | Skip opening PR in browser | | `--cleanup` / `--no-cleanup` | boolean | β€” | Explicit cleanup decision (skips prompt) | | `--json` | boolean | `false` | Output result as JSON | +| `--json-stream` | boolean | `false` | Stream JSONL progress output | ### Examples ```bash -# Fully autonomous finish from within a loom directory -bash pty:true command:"il finish --force --cleanup --no-browser --json" +# Fully autonomous finish from within a loom directory (background recommended β€” can take 1-2+ min) +bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream" # Dry run to preview what would happen bash pty:true command:"il finish --dry-run" # Finish a specific issue -bash pty:true command:"il finish 42 --force --cleanup --no-browser --json" +bash pty:true background:true command:"il finish 42 --force --cleanup --no-browser --json --json-stream" ``` ### Interactive Prompts and Bypasses diff --git a/openclaw-skill/references/development-commands.md b/openclaw-skill/references/development-commands.md index 4b07ad12..6bfd6625 100644 --- a/openclaw-skill/references/development-commands.md +++ b/openclaw-skill/references/development-commands.md @@ -54,13 +54,14 @@ Commit all uncommitted files with issue reference trailer. | `--fixes` | boolean | `false` | Use "Fixes #N" trailer instead of "Refs #N" | | `--no-review` | boolean | `false` | Skip commit message review prompt | | `--json` | boolean | `false` | Output result as JSON (implies `--no-review`) | +| `--json-stream` | boolean | `false` | Stream JSONL progress output | | `--wip-commit` | boolean | `false` | Quick WIP commit: skip validations and pre-commit hooks | ### Examples ```bash -# Non-interactive commit with AI-generated message -bash pty:true command:"il commit --no-review --json" +# Non-interactive commit with AI-generated message (background recommended β€” Claude generates message) +bash pty:true background:true command:"il commit --no-review --json --json-stream" # Commit with custom message bash pty:true command:"il commit -m 'fix: resolve auth timeout' --json" @@ -103,12 +104,13 @@ Rebase current loom branch on main with AI-assisted conflict resolution. |------|------|---------|-------------| | `-f, --force` | boolean | `false` | Force rebase even in edge cases | | `-n, --dry-run` | boolean | `false` | Simulate rebase without changes | +| `--json-stream` | boolean | `false` | Stream JSONL progress output | ### Examples ```bash -# Rebase with force (skip edge case checks) -bash pty:true command:"il rebase --force" +# Rebase with force and progress streaming (background recommended β€” Claude may resolve conflicts) +bash pty:true background:true command:"il rebase --force --json-stream" # Dry run bash pty:true command:"il rebase --dry-run" @@ -119,7 +121,7 @@ bash pty:true command:"il rebase --dry-run" - Detects uncommitted changes and throws if found (commit first) - Claude assists with conflict resolution if conflicts arise - Post-rebase: installs dependencies and runs build (non-blocking) -- No JSON output mode +- Use `--json-stream` for incremental progress visibility --- diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index faa37be1..7966a9ed 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -36,6 +36,21 @@ These commands launch Claude Code and run for extended periods. **Always run in - Without `--json-stream`, `--print` buffers ALL output until completion (no visibility into what Claude is doing) - These commands can easily run 3-10+ minutes with Opus analyzing a codebase β€” foreground timeouts will kill them +### Background Commands β€” Extended Operations + +These commands use Claude for message generation, conflict resolution, or merge validation and support `--json-stream` for progress monitoring: + +| Command | Recommended Invocation | +|---------|----------------------| +| `il commit` | `bash pty:true background:true command:"il commit --no-review --json --json-stream"` | +| `il finish` | `bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream"` | +| `il rebase` | `bash pty:true background:true command:"il rebase --force --json-stream"` | + +**Why `--json-stream` for these commands?** +- `commit` uses Claude to generate commit messages β€” can take 10-30s +- `finish` validates, commits, merges, and may trigger builds β€” can take 1-2+ minutes +- `rebase` may invoke Claude for conflict resolution β€” duration is unpredictable + ### Foreground Commands (no `background:true`) These commands complete quickly and return structured output: @@ -43,8 +58,6 @@ These commands complete quickly and return structured output: | Command | Recommended Invocation | |---------|----------------------| | `il list` | `bash pty:true command:"il list --json"` | -| `il commit` | `bash pty:true command:"il commit --no-review --json"` | -| `il finish` | `bash pty:true command:"il finish --force --cleanup --no-browser --json"` | | `il cleanup` | `bash pty:true command:"il cleanup --issue 42 --force --json"` | | `il build` | `bash pty:true command:"il build"` | | `il test` | `bash pty:true command:"il test"` | @@ -61,7 +74,6 @@ These commands complete quickly and return structured output: | Command | Note | |---------|------| | `il init` | Interactive wizard, must run foreground. **Not recommended for AI agents** β€” use manual setup instead (see `{baseDir}/references/initialization.md`) | -| `il rebase` | May need Claude for conflict resolution | | `il shell` | Opens interactive subshell | --- @@ -134,13 +146,16 @@ bash pty:true background:true command:"il start --yolo --no-code --no-te ### Full Autonomous Finish (merge and cleanup) ```bash -bash pty:true command:"il finish --force --cleanup --no-browser --json" +bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream" +# Monitor: process action:poll sessionId:XXX ``` - `--force`: skip all confirmations - `--cleanup`: auto-cleanup worktree - `--no-browser`: don't open browser - `--json`: structured output +- `--json-stream`: stream progress incrementally +- `background:true`: finish can take 1-2+ minutes (commit, merge, build verification) ### Headless Planning @@ -158,11 +173,23 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream" ### Non-Interactive Commit ```bash -bash pty:true command:"il commit --no-review --json" +bash pty:true background:true command:"il commit --no-review --json --json-stream" +# Monitor: process action:poll sessionId:XXX ``` - `--no-review`: skip message review - `--json`: structured output (also implies `--no-review`) +- `--json-stream`: stream progress (Claude generates commit message) + +### Non-Interactive Rebase + +```bash +bash pty:true background:true command:"il rebase --force --json-stream" +# Monitor: process action:poll sessionId:XXX +``` + +- `--force`: force rebase even in edge cases +- `--json-stream`: stream progress (Claude assists with conflict resolution if needed) ### Quick Cleanup @@ -182,10 +209,10 @@ Commands that support `--json` for machine-parseable output: | Command | JSON Flag | Notes | |---------|-----------|-------| | `il start` | `--json` | Returns workspace metadata | -| `il finish` | `--json` | Returns operation results | +| `il finish` | `--json`, `--json-stream` | Returns operation results. `--json-stream` for progress | | `il cleanup` | `--json` | Returns cleanup results | | `il list` | `--json` | Returns array of loom objects | -| `il commit` | `--json` | Returns commit details (implies `--no-review`) | +| `il commit` | `--json`, `--json-stream` | Returns commit details (implies `--no-review`). `--json-stream` for progress | | `il issues` | `--json` | Returns array of issues/PRs | | `il add-issue` | `--json` | Returns created issue | | `il enhance` | `--json` | Returns enhancement result | @@ -193,6 +220,7 @@ Commands that support `--json` for machine-parseable output: | `il recap` | `--json` | Returns recap data | | `il dev-server` | `--json` | Returns server status | | `il projects` | `--json` | Returns project list | +| `il rebase` | `--json-stream` | Stream progress during rebase | | `il plan` | `--json` | Returns planning result (requires `--print`) | | `il spin` | `--json` | Returns result (requires `--print`) | From 4d93a7fe0eb38f37472a711229e4e441cd5774da Mon Sep 17 00:00:00 2001 From: Helix Date: Mon, 23 Feb 2026 18:19:06 -0800 Subject: [PATCH 07/13] docs: use --json-stream instead of --json for commit/finish/rebase --json and --json-stream are mutually exclusive (per upstream #635). Prefer --json-stream for these commands since it provides incremental progress visibility. --json remains for commands that don't support --json-stream (list, cleanup, start, etc.). Refs #3 --- openclaw-skill/SKILL.md | 4 ++-- openclaw-skill/references/core-workflow.md | 4 ++-- openclaw-skill/references/development-commands.md | 2 +- .../references/non-interactive-patterns.md | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index c38ca58a..3132c1a5 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -105,7 +105,7 @@ For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflo 5. **Finish:** Merge and clean up ```bash - bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream" + bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream" # Monitor: process action:poll sessionId:XXX ``` @@ -131,7 +131,7 @@ bash pty:true command:"il list --json" ### Commit with AI-generated message ```bash -bash pty:true background:true command:"il commit --no-review --json --json-stream" +bash pty:true background:true command:"il commit --no-review --json-stream" # Monitor: process action:poll sessionId:XXX ``` diff --git a/openclaw-skill/references/core-workflow.md b/openclaw-skill/references/core-workflow.md index 20e53a7a..a14135c5 100644 --- a/openclaw-skill/references/core-workflow.md +++ b/openclaw-skill/references/core-workflow.md @@ -135,13 +135,13 @@ Validate, commit, merge, and clean up a loom workspace. ```bash # Fully autonomous finish from within a loom directory (background recommended β€” can take 1-2+ min) -bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream" +bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream" # Dry run to preview what would happen bash pty:true command:"il finish --dry-run" # Finish a specific issue -bash pty:true background:true command:"il finish 42 --force --cleanup --no-browser --json --json-stream" +bash pty:true background:true command:"il finish 42 --force --cleanup --no-browser --json-stream" ``` ### Interactive Prompts and Bypasses diff --git a/openclaw-skill/references/development-commands.md b/openclaw-skill/references/development-commands.md index 6bfd6625..61277251 100644 --- a/openclaw-skill/references/development-commands.md +++ b/openclaw-skill/references/development-commands.md @@ -61,7 +61,7 @@ Commit all uncommitted files with issue reference trailer. ```bash # Non-interactive commit with AI-generated message (background recommended β€” Claude generates message) -bash pty:true background:true command:"il commit --no-review --json --json-stream" +bash pty:true background:true command:"il commit --no-review --json-stream" # Commit with custom message bash pty:true command:"il commit -m 'fix: resolve auth timeout' --json" diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index 7966a9ed..ed99f4c4 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -42,8 +42,8 @@ These commands use Claude for message generation, conflict resolution, or merge | Command | Recommended Invocation | |---------|----------------------| -| `il commit` | `bash pty:true background:true command:"il commit --no-review --json --json-stream"` | -| `il finish` | `bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream"` | +| `il commit` | `bash pty:true background:true command:"il commit --no-review --json-stream"` | +| `il finish` | `bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream"` | | `il rebase` | `bash pty:true background:true command:"il rebase --force --json-stream"` | **Why `--json-stream` for these commands?** @@ -146,7 +146,7 @@ bash pty:true background:true command:"il start --yolo --no-code --no-te ### Full Autonomous Finish (merge and cleanup) ```bash -bash pty:true background:true command:"il finish --force --cleanup --no-browser --json --json-stream" +bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream" # Monitor: process action:poll sessionId:XXX ``` @@ -173,7 +173,7 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream" ### Non-Interactive Commit ```bash -bash pty:true background:true command:"il commit --no-review --json --json-stream" +bash pty:true background:true command:"il commit --no-review --json-stream" # Monitor: process action:poll sessionId:XXX ``` @@ -209,10 +209,10 @@ Commands that support `--json` for machine-parseable output: | Command | JSON Flag | Notes | |---------|-----------|-------| | `il start` | `--json` | Returns workspace metadata | -| `il finish` | `--json`, `--json-stream` | Returns operation results. `--json-stream` for progress | +| `il finish` | `--json-stream` | Stream progress (mutually exclusive with `--json`) | | `il cleanup` | `--json` | Returns cleanup results | | `il list` | `--json` | Returns array of loom objects | -| `il commit` | `--json`, `--json-stream` | Returns commit details (implies `--no-review`). `--json-stream` for progress | +| `il commit` | `--json-stream` | Stream progress (mutually exclusive with `--json`, implies `--no-review`) | | `il issues` | `--json` | Returns array of issues/PRs | | `il add-issue` | `--json` | Returns created issue | | `il enhance` | `--json` | Returns enhancement result | From 18b27ab702ed1162a432d5f4a869e6cfc6ddea03 Mon Sep 17 00:00:00 2001 From: Helix Date: Mon, 23 Feb 2026 18:51:34 -0800 Subject: [PATCH 08/13] docs: clarify remote semantics, label requirements, and plan prompt - Clarify issueManagement.github.remote vs mergeBehavior.remote semantics: issueManagement = canonical repo for issues/PRs/comments, mergeBehavior = where branches are pushed (cross-fork PR support) - Add table showing common workflow patterns (fork, direct, fork+local issues) - Document that GitHub labels must exist before use; guidance on creating labels when user has write/triage permissions, or listing existing ones - Document --json and --json-stream mutual exclusivity in safety rules - Add required prompt argument to all il plan --yolo examples - Update planning references with prompt requirement note --- openclaw-skill/SKILL.md | 37 ++++++++++++------- openclaw-skill/references/initialization.md | 6 ++- .../references/non-interactive-patterns.md | 4 +- .../references/planning-and-issues.md | 12 +++--- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index 3132c1a5..a5f68088 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -45,13 +45,15 @@ bash pty:true command:"il init" ## GitHub Remote Configuration (Fork Workflows) -When a project has **multiple git remotes** (e.g., `origin` + `fork`, or `upstream` + `origin`), iloom needs to know which remote to use for issue management and which to push to. +When a project has **multiple git remotes** (e.g., `origin` + `upstream`), iloom needs to know which remote to use for different operations. -**Do NOT auto-configure `issueManagement.github.remote`.** Instead, **ask the user** which remote to target. The correct choice depends on: +**Do NOT auto-configure remotes.** Instead, **ask the user** which remote to target. The correct choice depends on their workflow and permissions. -- Whether the user has write access to the upstream repo -- Whether issues live on the upstream or the fork -- Whether PRs should target the upstream or the fork +### Understanding the Two Remote Settings + +- **`issueManagement.github.remote`** β€” The **canonical GitHub repository** for all GitHub operations: listing/creating issues, opening PRs, commenting, closing issues. In a fork workflow, this is typically `upstream` because issues and PRs live on the original repo. + +- **`mergeBehavior.remote`** β€” The remote iloom **pushes branches to**. In a fork workflow, this is typically `origin` (your fork), because you have push access there. iloom pushes your branch here, then opens a cross-fork PR on the `issueManagement` repo. **Use `.iloom/settings.local.json`** (not the shared `settings.json`) for per-developer remote configuration, since this is a personal preference that shouldn't be committed: @@ -70,13 +72,17 @@ When a project has **multiple git remotes** (e.g., `origin` + `fork`, or `upstre **Standard remote naming convention:** - `origin` = your fork (where you have push access) -- `upstream` = the original repo (where issues live) +- `upstream` = the original repo (where issues and PRs live) -iloom assumes `origin` is yours by default. If remotes are named differently, configure `issueManagement.github.remote` and `mergeBehavior.remote` explicitly. +iloom assumes `origin` is yours by default. If remotes are named differently, configure both settings explicitly. -Common patterns: -- **Fork workflow:** Issues on `upstream`, push/PR from `origin` (your fork) -- **Direct access (no fork):** Both issues and push on `origin` β€” no extra config needed +### Common Patterns + +| Workflow | `issueManagement.github.remote` | `mergeBehavior.remote` | Notes | +|----------|--------------------------------|----------------------|-------| +| **Fork workflow** | `upstream` | `origin` | Issues/PRs on upstream, push to your fork | +| **Direct access** | `origin` | `origin` | No fork β€” no extra config needed | +| **Fork with local issues** | `origin` | `origin` | Issues on your fork (e.g., fork has issues enabled) | ## Workflow: Choosing the Right Approach @@ -84,9 +90,9 @@ Common patterns: For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflow: -1. **Plan:** Decompose the work into issues +1. **Plan:** Decompose the work into issues (prompt is required with `--yolo`) ```bash - bash pty:true background:true command:"il plan --yolo --print --json-stream" + bash pty:true background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" # Monitor: process action:poll sessionId:XXX ``` @@ -140,13 +146,15 @@ bash pty:true background:true command:"il commit --no-review --json-stream" When the user has an idea for an improvement, new feature, or wants to decompose work into issues, use `il plan`: ```bash -bash pty:true background:true command:"il plan --yolo --print --json-stream" +bash pty:true background:true command:"il plan --yolo --print --json-stream 'Describe the feature or work to plan'" # Monitor: process action:poll sessionId:XXX # Full log: process action:log sessionId:XXX ``` `il plan` launches an autonomous AI planning session that reads the codebase and creates structured issues with dependencies. Always prefer this over manually creating issues. +**Important:** `--yolo` mode requires a **prompt argument** (a description string) or an **issue identifier** (e.g., `il plan --yolo 42`). Without one, the command will fail immediately. + **Important:** Commands that can run for extended periods β€” `plan`, `spin`, `commit`, `finish`, and `rebase` β€” should be run in **background mode** (`background:true`) with `--json-stream` (and `--print` for plan/spin). The `--json-stream` flag streams JSONL incrementally so you can monitor progress via `process action:poll`. Without it, you get zero visibility until the command completes. ## References @@ -164,8 +172,9 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream" 2. **Use `background:true`** for commands that launch Claude or run extended operations: `start`, `spin`, `plan`, `commit`, `finish`, `rebase`. 3. **Never run `il finish` without `--force`** in autonomous mode β€” it will hang on confirmation prompts. 4. **Always pass explicit flags** to avoid interactive prompts. See `{baseDir}/references/non-interactive-patterns.md` for the complete decision bypass map. -5. **Use `--json`** when you need to parse command output programmatically. +5. **Use `--json`** when you need to parse command output programmatically. **`--json` and `--json-stream` are mutually exclusive** β€” prefer `--json-stream` for commands that support it (commit, finish, rebase) since it provides incremental visibility. Use `--json` only for commands without `--json-stream` support (list, cleanup, start, etc.). 6. **Prefer manual initialization** over `il init` β€” create `.iloom/settings.json` directly. See `{baseDir}/references/initialization.md`. 7. **Respect worktree isolation** β€” each loom is an independent workspace. Run commands from within the correct worktree directory. 8. **NEVER kill a background session you did not start.** Other looms may be running from separate planning or development sessions (the user's own work, other agents, or prior conversations). When you see unfamiliar background sessions, **leave them alone**. Only kill sessions you explicitly launched in the current workflow. If unsure, ask the user. 9. **Send progress updates mid-turn.** Long-running loom operations (plan, spin, commit, finish) can take minutes. Use the `message` tool to send incremental status updates to the user while waiting β€” don't go silent. Examples: "🧡 Spin started for issue #5, monitoring…", "βœ… Tests passing, spin entering code review phase", "πŸ”€ Merging to main…". Keep the user in the loop. +10. **GitHub labels must already exist on the repo.** `gh issue create --label` will fail if the label doesn't exist. If the user has **write or triage permissions** on the `issueManagement.github.remote` repo, you can create labels first (`gh label create -R `). Otherwise, list existing labels (`gh label list -R `) and only use those, or omit labels entirely if none match. diff --git a/openclaw-skill/references/initialization.md b/openclaw-skill/references/initialization.md index 3314da33..66176dea 100644 --- a/openclaw-skill/references/initialization.md +++ b/openclaw-skill/references/initialization.md @@ -83,7 +83,11 @@ Add to `.iloom/settings.local.json` (not `settings.json`, since this is per-deve **Standard convention:** `origin` = your fork, `upstream` = the original repo. iloom assumes `origin` is yours by default. -`issueManagement.github.remote` controls where issues are read/created. `mergeBehavior.remote` controls where branches are pushed and PRs are created. In fork workflows, issues live on `upstream` while you push to `origin`. +**Understanding the two settings:** +- **`issueManagement.github.remote`** β€” The canonical GitHub repository for all GitHub operations: listing/creating issues, **opening PRs**, commenting, closing issues. PRs are opened against this repo. +- **`mergeBehavior.remote`** β€” The remote iloom pushes branches to. In a fork workflow, branches are pushed here, then a cross-fork PR is opened on the `issueManagement` repo. + +In fork workflows, issues and PRs live on `upstream` while you push branches to `origin`. ### 5. Update `.gitignore` diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index ed99f4c4..bdc674ad 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -160,12 +160,12 @@ bash pty:true background:true command:"il finish --force --cleanup --no-browser ### Headless Planning ```bash -bash pty:true background:true command:"il plan --yolo --print --json-stream" +bash pty:true background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" # Monitor: process action:poll sessionId:XXX # Full log: process action:log sessionId:XXX ``` -- `--yolo`: autonomous mode +- `--yolo`: autonomous mode (**requires a prompt argument or issue identifier**) - `--print`: headless output - `--json-stream`: stream JSONL incrementally (visible via poll/log) - `background:true`: **required** β€” planning sessions can run 3-10+ minutes diff --git a/openclaw-skill/references/planning-and-issues.md b/openclaw-skill/references/planning-and-issues.md index 0c176255..352396d8 100644 --- a/openclaw-skill/references/planning-and-issues.md +++ b/openclaw-skill/references/planning-and-issues.md @@ -23,15 +23,17 @@ Launch an interactive AI planning session to decompose features into child issue ### Modes -**Fresh Planning Mode** β€” no identifier provided: +**Fresh Planning Mode** β€” prompt describes the work to plan: ```bash -# Interactive planning session (background, autonomous) -bash pty:true background:true command:"il plan --yolo" +# Autonomous planning with prompt (required for --yolo) +bash pty:true background:true command:"il plan --yolo --print --json-stream 'Add authentication to the API'" # Headless planning with JSON output -bash pty:true command:"il plan --yolo --print --output-format json" +bash pty:true command:"il plan --yolo --print --output-format json 'Add authentication to the API'" ``` +> **Note:** `--yolo` mode requires either a **prompt argument** (description string) or an **issue identifier**. Without one, the command fails immediately. + **Issue Decomposition Mode** β€” issue identifier provided: ```bash # Decompose existing issue #123 into child tasks @@ -46,7 +48,7 @@ bash pty:true background:true command:"il plan 'ENG-456' --yolo" This command **launches Claude**. Use `background:true` for interactive sessions: ```bash -bash pty:true background:true command:"il plan --yolo" +bash pty:true background:true command:"il plan --yolo --print --json-stream 'Description of work'" # Monitor the planning session process action:log sessionId:XXX From 8937a42ed786503afe32e0b2e57c447beb122ccd Mon Sep 17 00:00:00 2001 From: Helix Date: Wed, 18 Feb 2026 02:43:33 -0800 Subject: [PATCH 09/13] feat(skill): refine PTY and background requirements per command Replace blanket 'always use pty:true' guidance with three categories: - No PTY needed: list, issues, projects, recap, start --no-claude, cleanup, finish, commit --no-review, build, test, lint, etc. - Background required: plan, spin, start (with Claude), summary, enhance - Foreground PTY only: init, shell, rebase (interactive, not for agents) Updates both SKILL.md and references/non-interactive-patterns.md. Closes #4 --- openclaw-skill/SKILL.md | 64 ++++++++--- .../references/non-interactive-patterns.md | 108 ++++++++---------- 2 files changed, 98 insertions(+), 74 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index a5f68088..6b831ae1 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -8,16 +8,48 @@ metadata: { "openclaw": { "emoji": "🧡", "requires": { "anyBins": ["il", "iloo Manage isolated Git worktrees with AI-assisted development workflows. -## PTY Mode Required +## PTY and Background Requirements -iloom is an **interactive terminal application**. Always use `pty:true` when running iloom commands: +Not all iloom commands need PTY or background mode. Use the right mode for each command: -```bash -# Correct - with PTY -bash pty:true command:"il list --json" +### No PTY needed (plain exec) + +These return clean JSON and complete quickly: -# Wrong - may break output or hang +```bash bash command:"il list --json" +bash command:"il issues --json" +bash command:"il projects --json" +bash command:"il recap --json" +bash command:"il --version" +bash command:"il start --no-claude --no-code --no-dev-server --no-terminal --json" +bash command:"il cleanup --issue --force --json" +bash command:"il build" +bash command:"il test" +bash command:"il lint" +``` + +### Background mode required (long-running, launches Claude or extended ops) + +These spawn Claude Code sessions or run extended operations. Always use `background:true`: + +```bash +bash background:true command:"il plan --yolo --print --json-stream" +bash background:true command:"il spin --yolo --print --json-stream" +bash background:true command:"il start --yolo --no-code --no-terminal --json" # with Claude (default) +bash background:true command:"il summary --json" +bash background:true command:"il enhance --no-browser --json" +bash background:true command:"il commit --no-review --json-stream" +bash background:true command:"il finish --force --cleanup --no-browser --json-stream" +bash background:true command:"il rebase --force --json-stream" +# Monitor: process action:poll sessionId:XXX +``` + +### Foreground PTY only (interactive, not for AI agents) + +```bash +il init # Interactive wizard β€” use manual setup instead +il shell # Opens interactive subshell ``` ## Project Initialization (First-Time Setup) @@ -92,7 +124,7 @@ For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflo 1. **Plan:** Decompose the work into issues (prompt is required with `--yolo`) ```bash - bash pty:true background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" + bash background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" # Monitor: process action:poll sessionId:XXX ``` @@ -100,18 +132,18 @@ For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflo 3. **Start:** Create the workspace without launching Claude or dev server ```bash - bash pty:true command:"il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json" + bash command:"il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json" ``` 4. **Spin:** Launch Claude separately with streaming output ```bash - bash pty:true background:true command:"il spin --yolo --print --json-stream" + bash background:true command:"il spin --yolo --print --json-stream" # Monitor: process action:poll sessionId:XXX ``` 5. **Finish:** Merge and clean up ```bash - bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream" + bash background:true command:"il finish --force --cleanup --no-browser --json-stream" # Monitor: process action:poll sessionId:XXX ``` @@ -120,7 +152,7 @@ For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflo For small, self-contained tasks, use inline start with a description: ```bash -bash pty:true background:true command:"il start 'Add dark mode support to the settings page' --yolo --no-code --json" +bash background:true command:"il start 'Add dark mode support to the settings page' --yolo --no-code --json" # Monitor: process action:poll sessionId:XXX ``` @@ -131,13 +163,13 @@ This creates the issue, workspace, and launches Claude in one step. ### Check active workspaces ```bash -bash pty:true command:"il list --json" +bash command:"il list --json" ``` ### Commit with AI-generated message ```bash -bash pty:true background:true command:"il commit --no-review --json-stream" +bash background:true command:"il commit --no-review --json-stream" # Monitor: process action:poll sessionId:XXX ``` @@ -146,7 +178,7 @@ bash pty:true background:true command:"il commit --no-review --json-stream" When the user has an idea for an improvement, new feature, or wants to decompose work into issues, use `il plan`: ```bash -bash pty:true background:true command:"il plan --yolo --print --json-stream 'Describe the feature or work to plan'" +bash background:true command:"il plan --yolo --print --json-stream 'Describe the feature or work to plan'" # Monitor: process action:poll sessionId:XXX # Full log: process action:log sessionId:XXX ``` @@ -168,8 +200,8 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream 'Des ## Safety Rules -1. **Always use `pty:true`** for every iloom command. -2. **Use `background:true`** for commands that launch Claude or run extended operations: `start`, `spin`, `plan`, `commit`, `finish`, `rebase`. +1. **Use the right execution mode** for each command β€” see PTY and Background Requirements above. Most commands work without PTY. +2. **Use `background:true`** for commands that launch Claude or run extended operations: `start` (with Claude), `spin`, `plan`, `commit`, `finish`, `rebase`. 3. **Never run `il finish` without `--force`** in autonomous mode β€” it will hang on confirmation prompts. 4. **Always pass explicit flags** to avoid interactive prompts. See `{baseDir}/references/non-interactive-patterns.md` for the complete decision bypass map. 5. **Use `--json`** when you need to parse command output programmatically. **`--json` and `--json-stream` are mutually exclusive** β€” prefer `--json-stream` for commands that support it (commit, finish, rebase) since it provides incremental visibility. Use `--json` only for commands without `--json-stream` support (list, cleanup, start, etc.). diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index bdc674ad..cb64fa27 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -2,33 +2,43 @@ How to run iloom commands autonomously without hitting interactive prompts. -## PTY Requirement +## Execution Modes -iloom is an interactive terminal application built with Node.js. It uses colored output, spinners, and readline-based prompts that require a pseudo-terminal. +iloom commands fall into three categories based on their execution requirements: -**Always use `pty:true`** for every iloom command: +### No PTY needed (plain exec) -```bash -# Correct -bash pty:true command:"il list --json" +These commands return clean JSON output and complete quickly. No PTY or background mode required: -# Wrong - output may break or command may hang +```bash bash command:"il list --json" +bash command:"il issues --json" +bash command:"il projects --json" +bash command:"il recap --json" +bash command:"il --version" +bash command:"il start --no-claude --no-code --no-dev-server --no-terminal --json" +bash command:"il cleanup --issue 42 --force --json" +bash command:"il build" +bash command:"il test" +bash command:"il lint" +bash command:"il compile" +bash command:"il add-issue 'description' --json" ``` ---- - -## Background vs Foreground Commands - -### Background Commands (use `background:true`) +### Background mode required (long-running, launches Claude or extended ops) -These commands launch Claude Code and run for extended periods. **Always run in background** to avoid timeout kills: +These commands spawn Claude Code sessions or run extended operations that can take 1-10+ minutes. Always use `background:true`: -| Command | Recommended Invocation | -|---------|----------------------| -| `il start` | `bash pty:true background:true command:"il start 42 --yolo --no-code --no-terminal --json"` | -| `il spin` | `bash pty:true background:true command:"il spin --yolo --print --json-stream"` | -| `il plan` | `bash pty:true background:true command:"il plan --yolo --print --json-stream"` | +```bash +bash background:true command:"il plan --yolo --print --json-stream" +bash background:true command:"il spin --yolo --print --json-stream" +bash background:true command:"il start --yolo --no-code --no-terminal --json" # with Claude (default) +bash background:true command:"il summary --json" +bash background:true command:"il enhance --no-browser --json" +bash background:true command:"il commit --no-review --json-stream" +bash background:true command:"il finish --force --cleanup --no-browser --json-stream" +bash background:true command:"il rebase --force --json-stream" +``` **Why `--print --json-stream` for `plan` and `spin`?** - `--print` enables headless/non-interactive output mode @@ -36,44 +46,18 @@ These commands launch Claude Code and run for extended periods. **Always run in - Without `--json-stream`, `--print` buffers ALL output until completion (no visibility into what Claude is doing) - These commands can easily run 3-10+ minutes with Opus analyzing a codebase β€” foreground timeouts will kill them -### Background Commands β€” Extended Operations - -These commands use Claude for message generation, conflict resolution, or merge validation and support `--json-stream` for progress monitoring: - -| Command | Recommended Invocation | -|---------|----------------------| -| `il commit` | `bash pty:true background:true command:"il commit --no-review --json-stream"` | -| `il finish` | `bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream"` | -| `il rebase` | `bash pty:true background:true command:"il rebase --force --json-stream"` | - -**Why `--json-stream` for these commands?** +**Why `--json-stream` for `commit`, `finish`, and `rebase`?** - `commit` uses Claude to generate commit messages β€” can take 10-30s - `finish` validates, commits, merges, and may trigger builds β€” can take 1-2+ minutes - `rebase` may invoke Claude for conflict resolution β€” duration is unpredictable -### Foreground Commands (no `background:true`) - -These commands complete quickly and return structured output: - -| Command | Recommended Invocation | -|---------|----------------------| -| `il list` | `bash pty:true command:"il list --json"` | -| `il cleanup` | `bash pty:true command:"il cleanup --issue 42 --force --json"` | -| `il build` | `bash pty:true command:"il build"` | -| `il test` | `bash pty:true command:"il test"` | -| `il lint` | `bash pty:true command:"il lint"` | -| `il compile` | `bash pty:true command:"il compile"` | -| `il issues` | `bash pty:true command:"il issues --json"` | -| `il add-issue` | `bash pty:true command:"il add-issue 'description' --json"` | -| `il enhance` | `bash pty:true command:"il enhance 42 --no-browser --json"` | -| `il summary` | `bash pty:true command:"il summary --json"` | -| `il recap` | `bash pty:true command:"il recap --json"` | +### Foreground PTY only (interactive, not for AI agents) -### Special: Foreground Only (no background, no JSON) +These require a real terminal and human interaction: | Command | Note | |---------|------| -| `il init` | Interactive wizard, must run foreground. **Not recommended for AI agents** β€” use manual setup instead (see `{baseDir}/references/initialization.md`) | +| `il init` | Interactive wizard β€” **use manual setup instead** (see `{baseDir}/references/initialization.md`) | | `il shell` | Opens interactive subshell | --- @@ -82,7 +66,7 @@ These commands complete quickly and return structured output: ```bash # 1. Start the command in background -bash pty:true background:true command:"il start 42 --yolo --no-code --json" +bash background:true command:"il start 42 --yolo --no-code --no-terminal --json" # Returns: sessionId # 2. Check if still running @@ -135,32 +119,41 @@ Every interactive prompt in iloom and the flag(s) that bypass it: ### Full Autonomous Start (create workspace) ```bash -bash pty:true background:true command:"il start --yolo --no-code --no-terminal --json" +bash command:"il start --yolo --no-code --no-claude --no-dev-server --no-terminal --json" ``` - `--yolo`: bypass all permission prompts - `--no-code`: don't open VS Code +- `--no-claude`: don't launch Claude (use when you want to spin separately) +- `--no-dev-server`: skip dev server - `--no-terminal`: don't open a terminal window - `--json`: structured output +### Full Autonomous Start (with Claude) + +```bash +bash background:true command:"il start --yolo --no-code --no-terminal --json" +``` + +- Same as above but launches Claude β€” needs `background:true` + ### Full Autonomous Finish (merge and cleanup) ```bash -bash pty:true background:true command:"il finish --force --cleanup --no-browser --json-stream" +bash background:true command:"il finish --force --cleanup --no-browser --json-stream" # Monitor: process action:poll sessionId:XXX ``` - `--force`: skip all confirmations - `--cleanup`: auto-cleanup worktree - `--no-browser`: don't open browser -- `--json`: structured output - `--json-stream`: stream progress incrementally - `background:true`: finish can take 1-2+ minutes (commit, merge, build verification) ### Headless Planning ```bash -bash pty:true background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" +bash background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" # Monitor: process action:poll sessionId:XXX # Full log: process action:log sessionId:XXX ``` @@ -173,18 +166,17 @@ bash pty:true background:true command:"il plan --yolo --print --json-stream 'Des ### Non-Interactive Commit ```bash -bash pty:true background:true command:"il commit --no-review --json-stream" +bash background:true command:"il commit --no-review --json-stream" # Monitor: process action:poll sessionId:XXX ``` - `--no-review`: skip message review -- `--json`: structured output (also implies `--no-review`) - `--json-stream`: stream progress (Claude generates commit message) ### Non-Interactive Rebase ```bash -bash pty:true background:true command:"il rebase --force --json-stream" +bash background:true command:"il rebase --force --json-stream" # Monitor: process action:poll sessionId:XXX ``` @@ -194,7 +186,7 @@ bash pty:true background:true command:"il rebase --force --json-stream" ### Quick Cleanup ```bash -bash pty:true command:"il cleanup --issue --force --json" +bash command:"il cleanup --issue --force --json" ``` - `--force`: skip confirmation @@ -231,7 +223,7 @@ Commands that support `--json` for machine-parseable output: For long-running background tasks, append a wake trigger so OpenClaw gets notified when iloom finishes: ```bash -bash pty:true background:true command:"il start 42 --yolo --no-code --json && openclaw system event --text 'Done: Loom created for issue #42' --mode now" +bash background:true command:"il start 42 --yolo --no-code --no-terminal --json && openclaw system event --text 'Done: Loom created for issue #42' --mode now" ``` This triggers an immediate wake event instead of waiting for the next heartbeat. From 68beb0e5ede0e85e2b452aa6512193c4ea57e1c7 Mon Sep 17 00:00:00 2001 From: Noah Cardoza Date: Mon, 23 Feb 2026 20:12:03 -0800 Subject: [PATCH 10/13] feat(openclaw): add command to install openclaw skill --- docs/iloom-commands.md | 60 ++++++++ src/cli.ts | 20 ++- src/commands/openclaw.ts | 155 +++++++++++++++++++ src/types/telemetry.ts | 6 + tests/commands/openclaw.test.ts | 264 ++++++++++++++++++++++++++++++++ 5 files changed, 504 insertions(+), 1 deletion(-) create mode 100644 src/commands/openclaw.ts create mode 100644 tests/commands/openclaw.test.ts diff --git a/docs/iloom-commands.md b/docs/iloom-commands.md index c57ca67a..bdfc4b01 100644 --- a/docs/iloom-commands.md +++ b/docs/iloom-commands.md @@ -34,6 +34,7 @@ Complete documentation for all iloom CLI commands, options, and flags. - [il update](#il-update) - [il feedback](#il-feedback) - [il contribute](#il-contribute) + - [il openclaw](#il-openclaw) - [il telemetry](#il-telemetry) --- @@ -2056,6 +2057,65 @@ il contribute "facebook/react" --- +### il openclaw + +Register iloom as an OpenClaw skill by creating a symlink from the OpenClaw workspace to the project's `openclaw-skill/` directory. + +**Usage:** +```bash +il openclaw [options] +``` + +**Options:** + +| Flag | Description | Default | +|------|-------------|---------| +| `-f, --force` | Overwrite existing skill registration | `false` | +| `-w, --workspace ` | OpenClaw workspace name | `workspace` | + +**Behavior:** + +1. Verifies `openclaw-skill/` directory exists in the project root +2. Checks that OpenClaw is installed (`~/.openclaw` exists) +3. Checks that the specified workspace exists under `~/.openclaw/` +4. Creates `~/.openclaw//skills/` directory if needed +5. Creates symlink: `~/.openclaw//skills/iloom` β†’ `/openclaw-skill/` + +**Examples:** + +```bash +# Register iloom skill in the default workspace +il openclaw + +# Register in a specific workspace +il openclaw --workspace my-workspace +il openclaw -w my-workspace + +# Force overwrite an existing registration +il openclaw --force +il openclaw -f + +# Combine options +il openclaw -f -w my-workspace +``` + +**Error Handling:** + +| Scenario | Behavior | +|----------|----------| +| `openclaw-skill/` missing from project | Error with clear message | +| `~/.openclaw` not found | Friendly error suggesting OpenClaw is not installed | +| Workspace not found | Error suggesting `--workspace` flag | +| Target already correctly linked | Reports "Already linked" and exits successfully | +| Target exists (wrong symlink/file/dir) | Error suggesting `--force` (and `--workspace` if using default workspace) | + +**Notes:** +- This command does not create `~/.openclaw` or workspace directories β€” those are managed by OpenClaw itself +- The `skills/` subdirectory under the workspace is safe to auto-create +- Running the command multiple times is idempotent when the symlink is already correct + +--- + ### il telemetry Manage anonymous usage telemetry settings. diff --git a/src/cli.ts b/src/cli.ts index c5dbe81c..767fe9d5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -171,7 +171,7 @@ async function validateSettingsForCommand(command: Command): Promise { const commandName = command.name() // Tier 1: Commands that bypass ALL validation - const bypassCommands = ['help', 'init', 'update', 'contribute', 'telemetry'] + const bypassCommands = ['help', 'init', 'update', 'contribute', 'telemetry', 'openclaw'] if (bypassCommands.includes(commandName)) { return @@ -2213,6 +2213,24 @@ program } }) +// OpenClaw skill registration +program + .command('openclaw') + .description('Register iloom as an OpenClaw skill') + .option('-f, --force', 'Overwrite existing skill registration') + .option('-w, --workspace ', 'OpenClaw workspace name', 'workspace') + .action(async (options: { force?: boolean; workspace?: string }) => { + try { + const { OpenclawCommand } = await import('./commands/openclaw.js') + const command = new OpenclawCommand() + const result = await command.execute(options) + logger.info(result.status) + } catch (error) { + logger.error(error instanceof Error ? error.message : 'Unknown error') + process.exit(1) + } + }) + // Telemetry management commands const telemetryCmd = program .command('telemetry') diff --git a/src/commands/openclaw.ts b/src/commands/openclaw.ts new file mode 100644 index 00000000..a96b2770 --- /dev/null +++ b/src/commands/openclaw.ts @@ -0,0 +1,155 @@ +import path from 'path' +import os from 'os' +import fs from 'fs-extra' +import { getLogger } from '../utils/logger-context.js' +import { TelemetryService } from '../lib/TelemetryService.js' + +export interface OpenclawOptions { + force?: boolean + workspace?: string +} + +export interface OpenclawResult { + status: string + source: string + target: string +} + +export class OpenclawCommand { + private readonly projectRoot: string + + constructor(projectRoot?: string) { + this.projectRoot = projectRoot ?? process.cwd() + } + + async execute(options: OpenclawOptions = {}): Promise { + const logger = getLogger() + const workspace = options.workspace ?? 'workspace' + const force = options.force ?? false + + // 1. Resolve and verify openclaw-skill/ exists in the project + const skillSourceDir = path.join(this.projectRoot, 'openclaw-skill') + if (!(await fs.pathExists(skillSourceDir))) { + throw new Error(`openclaw-skill/ directory not found in ${this.projectRoot}`) + } + + // 2. Check ~/.openclaw exists + const openclawHome = path.join(os.homedir(), '.openclaw') + if (!(await fs.pathExists(openclawHome))) { + throw new Error('OpenClaw is not installed (~/.openclaw not found)') + } + + // 3. Check workspace exists + const workspaceDir = path.join(openclawHome, workspace) + if (!(await fs.pathExists(workspaceDir))) { + throw new Error( + `Workspace '${workspace}' not found. Use --workspace to specify a different workspace.` + ) + } + + // 4. Ensure skills/ dir exists + const skillsDir = path.join(workspaceDir, 'skills') + await fs.mkdirp(skillsDir) + + // 5. Check existing target + const targetPath = path.join(skillsDir, 'iloom') + const wasAlreadyLinked = await this.handleExistingTarget(targetPath, skillSourceDir, force, workspace) + + if (wasAlreadyLinked) { + this.trackLinked({ force, wasAlreadyLinked: true, customWorkspace: workspace !== 'workspace' }) + return { + status: 'Already linked', + source: skillSourceDir, + target: targetPath, + } + } + + // 6. Create symlink + await fs.symlink(skillSourceDir, targetPath) + logger.debug(`Created symlink: ${targetPath} -> ${skillSourceDir}`) + + this.trackLinked({ force, wasAlreadyLinked: false, customWorkspace: workspace !== 'workspace' }) + + return { + status: 'Linked successfully', + source: skillSourceDir, + target: targetPath, + } + } + + /** + * Handle an existing file/symlink at the target path. + * Returns true if already correctly linked (no action needed). + * Throws if conflict exists and --force not specified. + * Removes existing target if --force specified. + */ + private async handleExistingTarget( + targetPath: string, + expectedSource: string, + force: boolean, + workspace: string + ): Promise { + if (!(await fs.pathExists(targetPath)) && !(await this.isDeadSymlink(targetPath))) { + return false + } + + const isSymlink = await this.isSymlink(targetPath) + + if (isSymlink) { + const currentTarget = await fs.readlink(targetPath) + const resolvedCurrent = path.resolve(path.dirname(targetPath), currentTarget) + const resolvedExpected = path.resolve(expectedSource) + + if (resolvedCurrent === resolvedExpected) { + return true // Already correctly linked + } + } + + // Conflict exists + if (!force) { + const workspaceHint = workspace === 'workspace' + ? ' Use --workspace if you meant to install to a different workspace.' + : '' + const typeDesc = isSymlink ? 'a symlink pointing elsewhere' : 'a file or directory' + throw new Error( + `${targetPath} already exists as ${typeDesc}. Use --force to overwrite.${workspaceHint}` + ) + } + + // Force: remove existing + await fs.remove(targetPath) + return false + } + + private async isSymlink(filePath: string): Promise { + try { + const stats = await fs.lstat(filePath) + return stats.isSymbolicLink() + } catch { + return false + } + } + + private async isDeadSymlink(filePath: string): Promise { + try { + await fs.lstat(filePath) // lstat succeeds even for dead symlinks + const exists = await fs.pathExists(filePath) // pathExists follows the link + return !exists + } catch { + return false + } + } + + private trackLinked(props: { force: boolean; wasAlreadyLinked: boolean; customWorkspace: boolean }): void { + try { + TelemetryService.getInstance().track('openclaw.linked', { + force: props.force, + was_already_linked: props.wasAlreadyLinked, + custom_workspace: props.customWorkspace, + }) + } catch (error) { + const logger = getLogger() + logger.debug(`Telemetry error: ${error instanceof Error ? error.message : String(error)}`) + } + } +} diff --git a/src/types/telemetry.ts b/src/types/telemetry.ts index 03666733..020d83a3 100644 --- a/src/types/telemetry.ts +++ b/src/types/telemetry.ts @@ -106,6 +106,11 @@ export interface AutoSwarmCompletedProperties { phase_reached: 'plan' | 'start' | 'spin' fallback_to_normal: boolean } +export interface OpenclawLinkedProperties { + force: boolean + was_already_linked: boolean + custom_workspace: boolean +} // --- Event name β†’ properties map (for type-safe track() in downstream issues) --- export interface TelemetryEventMap { @@ -127,6 +132,7 @@ export interface TelemetryEventMap { 'init.completed': InitCompletedProperties 'auto_swarm.started': AutoSwarmStartedProperties 'auto_swarm.completed': AutoSwarmCompletedProperties + 'openclaw.linked': OpenclawLinkedProperties } export type TelemetryEventName = keyof TelemetryEventMap diff --git a/tests/commands/openclaw.test.ts b/tests/commands/openclaw.test.ts new file mode 100644 index 00000000..efad93f0 --- /dev/null +++ b/tests/commands/openclaw.test.ts @@ -0,0 +1,264 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import path from 'path' +import os from 'os' +import fs from 'fs-extra' +import type { Stats } from 'fs' +import { OpenclawCommand } from '../../src/commands/openclaw.js' + +vi.mock('fs-extra') +vi.mock('../../src/utils/logger-context.js', () => ({ + getLogger: () => ({ + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }), +})) +vi.mock('../../src/lib/TelemetryService.js', () => ({ + TelemetryService: { + getInstance: () => ({ + track: vi.fn(), + }), + }, +})) + +const projectRoot = '/test/project' +const homeDir = os.homedir() +const openclawHome = path.join(homeDir, '.openclaw') +const defaultWorkspaceDir = path.join(openclawHome, 'workspace') +const skillsDir = path.join(defaultWorkspaceDir, 'skills') +const targetPath = path.join(skillsDir, 'iloom') +const skillSourceDir = path.join(projectRoot, 'openclaw-skill') + +describe('OpenclawCommand', () => { + let command: OpenclawCommand + + beforeEach(() => { + command = new OpenclawCommand(projectRoot) + }) + + describe('successful linking', () => { + it('should create symlink when everything is in place', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return false + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.symlink).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockRejectedValue(new Error('ENOENT')) + + const result = await command.execute() + + expect(result.status).toBe('Linked successfully') + expect(result.source).toBe(skillSourceDir) + expect(result.target).toBe(targetPath) + expect(fs.symlink).toHaveBeenCalledWith(skillSourceDir, targetPath) + }) + + it('should report already linked when symlink points to correct target', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => true } as unknown as Stats) + vi.mocked(fs.readlink).mockResolvedValue(skillSourceDir) + + const result = await command.execute() + + expect(result.status).toBe('Already linked') + expect(fs.symlink).not.toHaveBeenCalled() + }) + + it('should use custom workspace when specified', async () => { + const customWorkspaceDir = path.join(openclawHome, 'my-workspace') + const customSkillsDir = path.join(customWorkspaceDir, 'skills') + const customTargetPath = path.join(customSkillsDir, 'iloom') + + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === customWorkspaceDir) return true + if (p === customTargetPath) return false + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.symlink).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockRejectedValue(new Error('ENOENT')) + + const result = await command.execute({ workspace: 'my-workspace' }) + + expect(result.status).toBe('Linked successfully') + expect(result.target).toBe(customTargetPath) + expect(fs.mkdirp).toHaveBeenCalledWith(customSkillsDir) + }) + }) + + describe('error cases', () => { + it('should error when openclaw-skill/ directory is missing', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return false + return false + }) + + await expect(command.execute()).rejects.toThrow('openclaw-skill/ directory not found') + }) + + it('should error when ~/.openclaw is not installed', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return false + return false + }) + + await expect(command.execute()).rejects.toThrow('OpenClaw is not installed (~/.openclaw not found)') + }) + + it('should error when workspace does not exist', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return false + return false + }) + + await expect(command.execute()).rejects.toThrow( + "Workspace 'workspace' not found. Use --workspace to specify a different workspace." + ) + }) + + it('should error when target exists as wrong symlink without --force', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => true } as unknown as Stats) + vi.mocked(fs.readlink).mockResolvedValue('/some/other/path') + + await expect(command.execute()).rejects.toThrow('Use --force to overwrite') + await expect(command.execute()).rejects.toThrow('a symlink pointing elsewhere') + }) + + it('should error when target exists as file/directory without --force', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => false } as unknown as Stats) + + await expect(command.execute()).rejects.toThrow('a file or directory') + }) + + it('should mention --workspace when default workspace has conflict', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => false } as unknown as Stats) + + await expect(command.execute()).rejects.toThrow('--workspace') + }) + + it('should not mention --workspace when custom workspace has conflict', async () => { + const customWorkspaceDir = path.join(openclawHome, 'custom') + const customTargetPath = path.join(customWorkspaceDir, 'skills', 'iloom') + + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === customWorkspaceDir) return true + if (p === customTargetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => false } as unknown as Stats) + + try { + await command.execute({ workspace: 'custom' }) + expect.unreachable('Should have thrown') + } catch (error) { + expect((error as Error).message).toContain('Use --force to overwrite') + expect((error as Error).message).not.toContain('--workspace') + } + }) + }) + + describe('--force flag', () => { + it('should overwrite existing symlink with --force', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => true } as unknown as Stats) + vi.mocked(fs.readlink).mockResolvedValue('/some/other/path') + vi.mocked(fs.remove).mockResolvedValue(undefined) + vi.mocked(fs.symlink).mockResolvedValue(undefined) + + const result = await command.execute({ force: true }) + + expect(result.status).toBe('Linked successfully') + expect(fs.remove).toHaveBeenCalledWith(targetPath) + expect(fs.symlink).toHaveBeenCalledWith(skillSourceDir, targetPath) + }) + + it('should overwrite existing directory with --force', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return true + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockResolvedValue({ isSymbolicLink: () => false } as unknown as Stats) + vi.mocked(fs.remove).mockResolvedValue(undefined) + vi.mocked(fs.symlink).mockResolvedValue(undefined) + + const result = await command.execute({ force: true }) + + expect(result.status).toBe('Linked successfully') + expect(fs.remove).toHaveBeenCalledWith(targetPath) + }) + }) + + describe('skills directory creation', () => { + it('should create skills/ directory if it does not exist', async () => { + vi.mocked(fs.pathExists).mockImplementation(async (p: string) => { + if (p === skillSourceDir) return true + if (p === openclawHome) return true + if (p === defaultWorkspaceDir) return true + if (p === targetPath) return false + return false + }) + vi.mocked(fs.mkdirp).mockResolvedValue(undefined) + vi.mocked(fs.symlink).mockResolvedValue(undefined) + vi.mocked(fs.lstat).mockRejectedValue(new Error('ENOENT')) + + await command.execute() + + expect(fs.mkdirp).toHaveBeenCalledWith(skillsDir) + }) + }) +}) From e5efb1780119e89405c5ab4ac2a37c1b482e4312 Mon Sep 17 00:00:00 2001 From: Noah Cardoza Date: Mon, 23 Feb 2026 20:27:24 -0800 Subject: [PATCH 11/13] feat(openclaw): consolidate openclaw skill instructions --- openclaw-skill/SKILL.md | 172 ++---------------- openclaw-skill/references/configuration.md | 13 +- openclaw-skill/references/core-workflow.md | 36 +--- .../references/development-commands.md | 10 +- .../references/planning-and-issues.md | 29 +-- 5 files changed, 26 insertions(+), 234 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index 6b831ae1..7d06b390 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -8,186 +8,48 @@ metadata: { "openclaw": { "emoji": "🧡", "requires": { "anyBins": ["il", "iloo Manage isolated Git worktrees with AI-assisted development workflows. -## PTY and Background Requirements +## Execution Modes -Not all iloom commands need PTY or background mode. Use the right mode for each command: +| Mode | Commands | Notes | +|------|----------|-------| +| **Plain exec** (no PTY, no background) | `list`, `issues`, `projects`, `recap`, `--version`, `start --no-claude --no-code --no-dev-server --no-terminal`, `cleanup --force`, `build`, `test`, `lint`, `compile`, `add-issue` | Fast, clean JSON output | +| **Background** (`background:true`) | `plan`, `spin`, `start` (with Claude), `summary`, `enhance`, `commit`, `finish`, `rebase` | Long-running or spawns Claude β€” monitor with `process action:poll sessionId:XXX` | +| **Foreground PTY only** | `init`, `shell` | Interactive β€” not for AI agents | -### No PTY needed (plain exec) - -These return clean JSON and complete quickly: - -```bash -bash command:"il list --json" -bash command:"il issues --json" -bash command:"il projects --json" -bash command:"il recap --json" -bash command:"il --version" -bash command:"il start --no-claude --no-code --no-dev-server --no-terminal --json" -bash command:"il cleanup --issue --force --json" -bash command:"il build" -bash command:"il test" -bash command:"il lint" -``` - -### Background mode required (long-running, launches Claude or extended ops) - -These spawn Claude Code sessions or run extended operations. Always use `background:true`: - -```bash -bash background:true command:"il plan --yolo --print --json-stream" -bash background:true command:"il spin --yolo --print --json-stream" -bash background:true command:"il start --yolo --no-code --no-terminal --json" # with Claude (default) -bash background:true command:"il summary --json" -bash background:true command:"il enhance --no-browser --json" -bash background:true command:"il commit --no-review --json-stream" -bash background:true command:"il finish --force --cleanup --no-browser --json-stream" -bash background:true command:"il rebase --force --json-stream" -# Monitor: process action:poll sessionId:XXX -``` - -### Foreground PTY only (interactive, not for AI agents) - -```bash -il init # Interactive wizard β€” use manual setup instead -il shell # Opens interactive subshell -``` +See `{baseDir}/references/non-interactive-patterns.md` for the complete execution mode guide, session lifecycle, decision bypass map, and recommended autonomous flag combinations. ## Project Initialization (First-Time Setup) Before using any iloom commands, the project must have a `.iloom/settings.json` file. -**Preferred: Manual setup (recommended for AI agents)** - -Create the settings files directly β€” no interactive wizard needed: - ```bash mkdir -p .iloom echo '{"mainBranch": "main"}' > .iloom/settings.json ``` -See `{baseDir}/references/initialization.md` for the complete settings schema, all configuration options, and example configurations. - -**Alternative: Interactive wizard (for humans at a terminal)** - -```bash -bash pty:true command:"il init" -``` - -`il init` launches an interactive Claude-guided configuration wizard. It requires foreground PTY and is designed for human interaction β€” **not recommended for AI agents** due to nested interactive prompts and timeout sensitivity. - -## GitHub Remote Configuration (Fork Workflows) - -When a project has **multiple git remotes** (e.g., `origin` + `upstream`), iloom needs to know which remote to use for different operations. - -**Do NOT auto-configure remotes.** Instead, **ask the user** which remote to target. The correct choice depends on their workflow and permissions. - -### Understanding the Two Remote Settings - -- **`issueManagement.github.remote`** β€” The **canonical GitHub repository** for all GitHub operations: listing/creating issues, opening PRs, commenting, closing issues. In a fork workflow, this is typically `upstream` because issues and PRs live on the original repo. - -- **`mergeBehavior.remote`** β€” The remote iloom **pushes branches to**. In a fork workflow, this is typically `origin` (your fork), because you have push access there. iloom pushes your branch here, then opens a cross-fork PR on the `issueManagement` repo. - -**Use `.iloom/settings.local.json`** (not the shared `settings.json`) for per-developer remote configuration, since this is a personal preference that shouldn't be committed: - -```json -{ - "issueManagement": { - "github": { - "remote": "upstream" - } - }, - "mergeBehavior": { - "remote": "origin" - } -} -``` - -**Standard remote naming convention:** -- `origin` = your fork (where you have push access) -- `upstream` = the original repo (where issues and PRs live) - -iloom assumes `origin` is yours by default. If remotes are named differently, configure both settings explicitly. - -### Common Patterns - -| Workflow | `issueManagement.github.remote` | `mergeBehavior.remote` | Notes | -|----------|--------------------------------|----------------------|-------| -| **Fork workflow** | `upstream` | `origin` | Issues/PRs on upstream, push to your fork | -| **Direct access** | `origin` | `origin` | No fork β€” no extra config needed | -| **Fork with local issues** | `origin` | `origin` | Issues on your fork (e.g., fork has issues enabled) | +See `{baseDir}/references/initialization.md` for the complete settings schema, all configuration options, remote configuration for fork workflows, and example configurations. ## Workflow: Choosing the Right Approach ### Sizeable Changes (multiple issues, architectural work) -For anything non-trivial, use the **plan β†’ review β†’ start β†’ spin** workflow: - -1. **Plan:** Decompose the work into issues (prompt is required with `--yolo`) - ```bash - bash background:true command:"il plan --yolo --print --json-stream 'Description of work to plan'" - # Monitor: process action:poll sessionId:XXX - ``` +Use the **plan β†’ review β†’ start β†’ spin β†’ finish** workflow: -2. **Review:** Present the created epic to the user for review (unless they've said to proceed without review). Wait for approval before continuing. - -3. **Start:** Create the workspace without launching Claude or dev server - ```bash - bash command:"il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json" - ``` - -4. **Spin:** Launch Claude separately with streaming output - ```bash - bash background:true command:"il spin --yolo --print --json-stream" - # Monitor: process action:poll sessionId:XXX - ``` - -5. **Finish:** Merge and clean up - ```bash - bash background:true command:"il finish --force --cleanup --no-browser --json-stream" - # Monitor: process action:poll sessionId:XXX - ``` +1. **Plan:** `il plan --yolo --print --json-stream 'Description'` (background) β€” decomposes work into issues +2. **Review:** Present the created epic to the user; wait for approval before continuing +3. **Start:** `il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json` (plain exec) β€” creates workspace without Claude +4. **Spin:** `il spin --yolo --print --json-stream` (background) β€” launches Claude separately +5. **Finish:** `il finish --force --cleanup --no-browser --json-stream` (background) β€” merges and cleans up ### Small Changes (single issue, quick fix) -For small, self-contained tasks, use inline start with a description: +Create issue + workspace + launch Claude in one step: ```bash bash background:true command:"il start 'Add dark mode support to the settings page' --yolo --no-code --json" -# Monitor: process action:poll sessionId:XXX ``` -This creates the issue, workspace, and launches Claude in one step. - -## Quick Reference - -### Check active workspaces - -```bash -bash command:"il list --json" -``` - -### Commit with AI-generated message - -```bash -bash background:true command:"il commit --no-review --json-stream" -# Monitor: process action:poll sessionId:XXX -``` - -## Ideation and Planning - -When the user has an idea for an improvement, new feature, or wants to decompose work into issues, use `il plan`: - -```bash -bash background:true command:"il plan --yolo --print --json-stream 'Describe the feature or work to plan'" -# Monitor: process action:poll sessionId:XXX -# Full log: process action:log sessionId:XXX -``` - -`il plan` launches an autonomous AI planning session that reads the codebase and creates structured issues with dependencies. Always prefer this over manually creating issues. - -**Important:** `--yolo` mode requires a **prompt argument** (a description string) or an **issue identifier** (e.g., `il plan --yolo 42`). Without one, the command will fail immediately. - -**Important:** Commands that can run for extended periods β€” `plan`, `spin`, `commit`, `finish`, and `rebase` β€” should be run in **background mode** (`background:true`) with `--json-stream` (and `--print` for plan/spin). The `--json-stream` flag streams JSONL incrementally so you can monitor progress via `process action:poll`. Without it, you get zero visibility until the command completes. +See `{baseDir}/references/core-workflow.md` for full command flags/examples and `{baseDir}/references/planning-and-issues.md` for planning details. ## References @@ -200,7 +62,7 @@ bash background:true command:"il plan --yolo --print --json-stream 'Describe the ## Safety Rules -1. **Use the right execution mode** for each command β€” see PTY and Background Requirements above. Most commands work without PTY. +1. **Use the right execution mode** for each command β€” see the Execution Modes table above and `{baseDir}/references/non-interactive-patterns.md` for details. 2. **Use `background:true`** for commands that launch Claude or run extended operations: `start` (with Claude), `spin`, `plan`, `commit`, `finish`, `rebase`. 3. **Never run `il finish` without `--force`** in autonomous mode β€” it will hang on confirmation prompts. 4. **Always pass explicit flags** to avoid interactive prompts. See `{baseDir}/references/non-interactive-patterns.md` for the complete decision bypass map. diff --git a/openclaw-skill/references/configuration.md b/openclaw-skill/references/configuration.md index d800f20e..a37a27fa 100644 --- a/openclaw-skill/references/configuration.md +++ b/openclaw-skill/references/configuration.md @@ -12,18 +12,7 @@ iloom uses a layered settings system with three files: Local overrides project, project overrides global. -### Key Settings - -| Setting | Description | Default | -|---------|-------------|---------| -| `mainBranch` | Primary branch name | Auto-detected (`main` or `master`) | -| `workflows.issue.permissionMode` | Permission mode for issue looms | `default` | -| `workflows.issue.startIde` | Open IDE on loom start | `true` | -| `workflows.issue.startAiAgent` | Launch Claude on loom start | `true` | -| `mergeBehavior.mode` | Merge strategy | `local` | -| `issueManagement.provider` | Issue tracker | `github` | -| `capabilities.web.basePort` | Base port for dev servers | `3000` | -| `agents..model` | Per-agent model override | β€” | +For the complete settings schema and all configuration options, see `{baseDir}/references/initialization.md`. ### Runtime Setting Overrides diff --git a/openclaw-skill/references/core-workflow.md b/openclaw-skill/references/core-workflow.md index a14135c5..c86f3633 100644 --- a/openclaw-skill/references/core-workflow.md +++ b/openclaw-skill/references/core-workflow.md @@ -74,26 +74,7 @@ bash pty:true background:true command:"il start 'Add dark mode support to the se bash pty:true background:true command:"il start 42 --yolo --no-code --no-child-loom --json" ``` -### Interactive Prompts and Bypasses - -| Prompt | Bypass | -|--------|--------| -| "Enter issue number..." | Provide `[identifier]` argument | -| "Create as a child loom?" | `--child-loom` or `--no-child-loom` | -| "bypassPermissions warning" | Already implied by `--yolo`; or use `--no-claude` | - -### Background Mode - -This command **launches Claude** by default. Use `background:true` and monitor: - -```bash -bash pty:true background:true command:"il start 42 --yolo --no-code --json" -# Returns sessionId - -process action:poll sessionId:XXX # Check if done -process action:log sessionId:XXX # View output -process action:kill sessionId:XXX # Terminate if needed -``` +See `{baseDir}/references/non-interactive-patterns.md` for prompt bypasses and execution mode guidance. ### JSON Output @@ -144,13 +125,7 @@ bash pty:true command:"il finish --dry-run" bash pty:true background:true command:"il finish 42 --force --cleanup --no-browser --json-stream" ``` -### Interactive Prompts and Bypasses - -| Prompt | Bypass | -|--------|--------| -| "Clean up worktree?" | `--cleanup` or `--no-cleanup` | -| Commit message review | `--force` | -| General confirmations | `--force` | +See `{baseDir}/references/non-interactive-patterns.md` for prompt bypasses and execution mode guidance. ### JSON Output @@ -206,12 +181,7 @@ bash pty:true command:"il cleanup --list" bash pty:true command:"il cleanup --issue 42 --dry-run" ``` -### Interactive Prompts and Bypasses - -| Prompt | Bypass | -|--------|--------| -| "Remove this worktree?" | `--force` | -| "Remove N worktree(s)?" | `--force` | +See `{baseDir}/references/non-interactive-patterns.md` for prompt bypasses. ### JSON Output diff --git a/openclaw-skill/references/development-commands.md b/openclaw-skill/references/development-commands.md index 61277251..6e0fb5bc 100644 --- a/openclaw-skill/references/development-commands.md +++ b/openclaw-skill/references/development-commands.md @@ -34,9 +34,7 @@ process action:log sessionId:XXX process action:poll sessionId:XXX ``` -### Background Mode - -This command **launches Claude**. Use `background:true` for long-running sessions. +See `{baseDir}/references/non-interactive-patterns.md` for execution mode guidance. --- @@ -73,11 +71,7 @@ bash pty:true command:"il commit --wip-commit --json" bash pty:true command:"il commit --fixes --no-review --json" ``` -### Interactive Prompts and Bypasses - -| Prompt | Bypass | -|--------|--------| -| Commit message review (accept/edit/abort) | `--no-review` or `--json` | +See `{baseDir}/references/non-interactive-patterns.md` for prompt bypasses and execution mode guidance. ### JSON Output diff --git a/openclaw-skill/references/planning-and-issues.md b/openclaw-skill/references/planning-and-issues.md index 352396d8..308cc979 100644 --- a/openclaw-skill/references/planning-and-issues.md +++ b/openclaw-skill/references/planning-and-issues.md @@ -43,20 +43,7 @@ bash pty:true background:true command:"il plan '#123' --yolo" bash pty:true background:true command:"il plan 'ENG-456' --yolo" ``` -### Background Mode - -This command **launches Claude**. Use `background:true` for interactive sessions: - -```bash -bash pty:true background:true command:"il plan --yolo --print --json-stream 'Description of work'" - -# Monitor the planning session -process action:log sessionId:XXX -process action:poll sessionId:XXX - -# Send input if the planner asks a question -process action:submit sessionId:XXX data:"Option A" -``` +See `{baseDir}/references/non-interactive-patterns.md` for execution mode guidance and session lifecycle. ### JSON Output (with `--print`) @@ -108,12 +95,7 @@ bash pty:true command:"il add-issue 'Fix login timeout' --body 'Users report 504 3. Creates the issue on the configured tracker 4. Returns structured result in `--json` mode -### Interactive Prompts and Bypasses - -| Prompt | Bypass | -|--------|--------| -| First-run setup | `--json` (skips setup) | -| "Press key to view in browser" | `--json` (skips browser) | +See `{baseDir}/references/non-interactive-patterns.md` for prompt bypasses. ### JSON Output @@ -151,12 +133,7 @@ bash pty:true command:"il enhance 42 --no-browser --json" bash pty:true command:"il enhance 42 --author johndoe --no-browser --json" ``` -### Interactive Prompts and Bypasses - -| Prompt | Bypass | -|--------|--------| -| First-run setup | `--json` (skips setup) | -| "Press q to quit or key to view..." | `--no-browser` or `--json` | +See `{baseDir}/references/non-interactive-patterns.md` for prompt bypasses. ### JSON Output From d63e66c964574b8810cbf21dbf6b6cbbb9b97252 Mon Sep 17 00:00:00 2001 From: Noah Cardoza Date: Mon, 23 Feb 2026 20:27:40 -0800 Subject: [PATCH 12/13] feat(openclaw): normalize work item references --- openclaw-skill/SKILL.md | 6 +++++- openclaw-skill/references/core-workflow.md | 2 +- openclaw-skill/references/development-commands.md | 4 ++-- openclaw-skill/references/non-interactive-patterns.md | 10 +++++----- openclaw-skill/references/planning-and-issues.md | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/openclaw-skill/SKILL.md b/openclaw-skill/SKILL.md index 7d06b390..4709a024 100644 --- a/openclaw-skill/SKILL.md +++ b/openclaw-skill/SKILL.md @@ -8,6 +8,10 @@ metadata: { "openclaw": { "emoji": "🧡", "requires": { "anyBins": ["il", "iloo Manage isolated Git worktrees with AI-assisted development workflows. +## Terminology + +`` β€” the identifier for a work item on your configured issue tracker. Examples: `42` or `#42` (GitHub), `ENG-456` (Linear), `PROJ-789` (Jira). + ## Execution Modes | Mode | Commands | Notes | @@ -37,7 +41,7 @@ Use the **plan β†’ review β†’ start β†’ spin β†’ finish** workflow: 1. **Plan:** `il plan --yolo --print --json-stream 'Description'` (background) β€” decomposes work into issues 2. **Review:** Present the created epic to the user; wait for approval before continuing -3. **Start:** `il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json` (plain exec) β€” creates workspace without Claude +3. **Start:** `il start --yolo --no-code --no-dev-server --no-claude --no-terminal --json` (plain exec) β€” creates workspace without Claude 4. **Spin:** `il spin --yolo --print --json-stream` (background) β€” launches Claude separately 5. **Finish:** `il finish --force --cleanup --no-browser --json-stream` (background) β€” merges and cleans up diff --git a/openclaw-skill/references/core-workflow.md b/openclaw-skill/references/core-workflow.md index c86f3633..bf55c61b 100644 --- a/openclaw-skill/references/core-workflow.md +++ b/openclaw-skill/references/core-workflow.md @@ -156,7 +156,7 @@ Remove one or more loom workspaces without merging. | Flag | Type | Default | Description | |------|------|---------|-------------| -| `[identifier]` | positional | β€” | Branch name or issue number | +| `[identifier]` | positional | β€” | Branch name or work item identifier | | `-l, --list` | boolean | `false` | List all worktrees (informational) | | `-a, --all` | boolean | `false` | Remove all worktrees | | `-i, --issue ` | number | β€” | Cleanup by issue number | diff --git a/openclaw-skill/references/development-commands.md b/openclaw-skill/references/development-commands.md index 6e0fb5bc..cdce335d 100644 --- a/openclaw-skill/references/development-commands.md +++ b/openclaw-skill/references/development-commands.md @@ -179,7 +179,7 @@ Start the development server for a workspace. | Flag | Type | Default | Description | |------|------|---------|-------------| -| `[identifier]` | positional | β€” | Issue number, PR number, or branch name (auto-detected) | +| `[identifier]` | positional | β€” | Work item identifier, PR number, or branch name (auto-detected) | | `--json` | boolean | `false` | Output result as JSON | ### Examples @@ -260,7 +260,7 @@ Generate a Claude session summary for a loom. | Flag | Type | Default | Description | |------|------|---------|-------------| -| `[identifier]` | positional | β€” | Issue number, PR number, branch name, or Linear/Jira ID (auto-detected) | +| `[identifier]` | positional | β€” | Work item identifier (auto-detected from any tracker) | | `--with-comment` | boolean | `false` | Post summary as comment to issue/PR | | `--json` | boolean | `false` | Output result as JSON | diff --git a/openclaw-skill/references/non-interactive-patterns.md b/openclaw-skill/references/non-interactive-patterns.md index cb64fa27..bfb9e8c4 100644 --- a/openclaw-skill/references/non-interactive-patterns.md +++ b/openclaw-skill/references/non-interactive-patterns.md @@ -16,7 +16,7 @@ bash command:"il issues --json" bash command:"il projects --json" bash command:"il recap --json" bash command:"il --version" -bash command:"il start --no-claude --no-code --no-dev-server --no-terminal --json" +bash command:"il start --no-claude --no-code --no-dev-server --no-terminal --json" bash command:"il cleanup --issue 42 --force --json" bash command:"il build" bash command:"il test" @@ -32,9 +32,9 @@ These commands spawn Claude Code sessions or run extended operations that can ta ```bash bash background:true command:"il plan --yolo --print --json-stream" bash background:true command:"il spin --yolo --print --json-stream" -bash background:true command:"il start --yolo --no-code --no-terminal --json" # with Claude (default) +bash background:true command:"il start --yolo --no-code --no-terminal --json" # with Claude (default) bash background:true command:"il summary --json" -bash background:true command:"il enhance --no-browser --json" +bash background:true command:"il enhance --no-browser --json" bash background:true command:"il commit --no-review --json-stream" bash background:true command:"il finish --force --cleanup --no-browser --json-stream" bash background:true command:"il rebase --force --json-stream" @@ -119,7 +119,7 @@ Every interactive prompt in iloom and the flag(s) that bypass it: ### Full Autonomous Start (create workspace) ```bash -bash command:"il start --yolo --no-code --no-claude --no-dev-server --no-terminal --json" +bash command:"il start --yolo --no-code --no-claude --no-dev-server --no-terminal --json" ``` - `--yolo`: bypass all permission prompts @@ -132,7 +132,7 @@ bash command:"il start --yolo --no-code --no-claude --no-dev-server --no ### Full Autonomous Start (with Claude) ```bash -bash background:true command:"il start --yolo --no-code --no-terminal --json" +bash background:true command:"il start --yolo --no-code --no-terminal --json" ``` - Same as above but launches Claude β€” needs `background:true` diff --git a/openclaw-skill/references/planning-and-issues.md b/openclaw-skill/references/planning-and-issues.md index 308cc979..a51dd75f 100644 --- a/openclaw-skill/references/planning-and-issues.md +++ b/openclaw-skill/references/planning-and-issues.md @@ -118,7 +118,7 @@ Apply AI enhancement to an existing issue's description. | Flag | Type | Default | Description | |------|------|---------|-------------| -| `` | positional | β€” | Issue number or identifier (required) | +| `` | positional | β€” | Work item identifier (required) | | `--no-browser` | boolean | `false` | Skip browser opening prompt | | `--author ` | string | β€” | GitHub username to tag in questions | | `--json` | boolean | `false` | Output result as JSON (non-interactive) | From 48376c18ea6239bb768015c682d04db2bb454547 Mon Sep 17 00:00:00 2001 From: Noah Cardoza Date: Mon, 23 Feb 2026 21:21:54 -0800 Subject: [PATCH 13/13] feat(openclaw): package skill in build --- scripts/copy-docs.ts | 12 +++++++++++- src/commands/openclaw.ts | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/scripts/copy-docs.ts b/scripts/copy-docs.ts index f60c7666..471b7576 100644 --- a/scripts/copy-docs.ts +++ b/scripts/copy-docs.ts @@ -1,4 +1,4 @@ -import { copyFile } from 'fs/promises' +import { copyFile, cp } from 'fs/promises' import path from 'path' import { existsSync } from 'fs' @@ -14,6 +14,16 @@ async function copyDocs() { } else { console.warn(`⚠ README.md not found at ${readmeSrc} - skipping copy`) } + + // Copy openclaw-skill/ to dist + const openclawSrc = path.join(process.cwd(), 'openclaw-skill') + const openclawDest = path.join(distDir, 'openclaw-skill') + if (existsSync(openclawSrc)) { + await cp(openclawSrc, openclawDest, { recursive: true }) + console.log(`βœ“ openclaw-skill/ copied to ${openclawDest}`) + } else { + console.warn(`⚠ openclaw-skill/ not found at ${openclawSrc} - skipping copy`) + } } copyDocs().catch(console.error) \ No newline at end of file diff --git a/src/commands/openclaw.ts b/src/commands/openclaw.ts index a96b2770..89b0e836 100644 --- a/src/commands/openclaw.ts +++ b/src/commands/openclaw.ts @@ -1,5 +1,6 @@ import path from 'path' import os from 'os' +import { fileURLToPath } from 'url' import fs from 'fs-extra' import { getLogger } from '../utils/logger-context.js' import { TelemetryService } from '../lib/TelemetryService.js' @@ -27,11 +28,9 @@ export class OpenclawCommand { const workspace = options.workspace ?? 'workspace' const force = options.force ?? false - // 1. Resolve and verify openclaw-skill/ exists in the project - const skillSourceDir = path.join(this.projectRoot, 'openclaw-skill') - if (!(await fs.pathExists(skillSourceDir))) { - throw new Error(`openclaw-skill/ directory not found in ${this.projectRoot}`) - } + // 1. Resolve and verify openclaw-skill/ exists + const skillSourceDir = await this.resolveSkillDir() + logger.debug(`Resolved openclaw-skill directory: ${skillSourceDir}`) // 2. Check ~/.openclaw exists const openclawHome = path.join(os.homedir(), '.openclaw') @@ -77,6 +76,37 @@ export class OpenclawCommand { } } + /** + * Resolve the openclaw-skill directory. + * 1. Check relative to the package install location (dist/openclaw-skill/ for npm installs) + * 2. Fall back to projectRoot/openclaw-skill/ (for local dev / repo clones) + * 3. Throw if neither exists + */ + private async resolveSkillDir(): Promise { + // 1. Relative to the installed package (works for npm installs) + const __filename = fileURLToPath(import.meta.url) + const __dirname = path.dirname(__filename) + // In dist: dist/commands/openclaw.js -> walk up to dist/, then openclaw-skill/ + let packageDir = __dirname + while (packageDir !== path.dirname(packageDir)) { + const candidate = path.join(packageDir, 'openclaw-skill') + if (await fs.pathExists(candidate)) { + return candidate + } + packageDir = path.dirname(packageDir) + } + + // 2. Relative to projectRoot (for local dev / repo clones) + const devCandidate = path.join(this.projectRoot, 'openclaw-skill') + if (await fs.pathExists(devCandidate)) { + return devCandidate + } + + throw new Error( + `openclaw-skill/ directory not found. Searched from package location (${__dirname}) and project root (${this.projectRoot}).` + ) + } + /** * Handle an existing file/symlink at the target path. * Returns true if already correctly linked (no action needed).