Commit Graph

135 Commits

Author SHA1 Message Date
xiaoju 399b967c59 refactor: reduce cognitive complexity in dispatch.ts and shell-exec.ts
- Extract helpers from promptSecret/onData (32→~4)
- Extract sub-functions from collectInteractiveSetup (36→~8)
- Extract classifyExecError from shell-exec handler (17→~3)
- Replace all non-null assertions with safe .at() access

0 biome errors, 0 warnings.
2026-05-13 07:37:47 +00:00
xiaoju 061926b86a chore: fix all biome lint errors
- Auto-fix string concatenation → template literals
- Remove unused imports
- Prefix unused function with underscore
- Format fixes across multiple files
2026-05-13 07:26:11 +00:00
xiaoju d5d7be6100 chore: add files field to all packages, bump to 0.3.16
Excludes tsconfig.json and source files from published packages.
Fixes TypeScript errors when consuming packages via bun.
2026-05-13 07:19:49 +00:00
xiaoju 1566a43395 chore: bump all packages to 0.3.15 2026-05-13 07:04:12 +00:00
xiaomo ed38543db4 Merge pull request 'docs(skill): add authoring pitfalls to skill author topic' (#231) from fix/skill-author-pitfalls into main 2026-05-13 03:59:50 +00:00
xiaoju c15f58bdeb docs(skill): add authoring pitfalls to skill author topic
Add ModeratorTable syntax, AdapterFn/AdapterBinding types, lazy init
pattern, bundle import restrictions, and descriptor requirements.

Knowledge from smoke test discoveries — these are the most common
mistakes when writing workflow bundles.

小橘 <xiaoju@shazhou.work>
2026-05-13 03:57:49 +00:00
xingyue 5b7c9b844b fix(engine): abort signal races gen.next() to fix flaky kill test (#209)
Root cause: executeThread awaited gen.next() without racing against
the abort signal. When a workflow bundle awaited a long setTimeout
between yields, the engine could not respond to kill until the
Promise resolved — causing the kill test to flake when the thread
completed before kill arrived.

Fix: Promise.race gen.next() with an abort listener so kill takes
effect immediately, even mid-yield. Also move the bundle's delay
to after the first yield (between planner and coder) to ensure the
thread is killable while running.

Closes #209
2026-05-13 11:31:40 +08:00
xiaoju f0d1bb9ae8 chore: bump all to 0.3.11
小橘 🍊
2026-05-13 03:28:33 +00:00
xiaoju 04cfd33f99 chore: bump all to 0.3.10 (regenerate lockfile)
小橘 🍊
2026-05-13 03:27:05 +00:00
xiaoju a8c00f169b chore: bump all packages to 0.3.9 (fix workspace:* dep resolution)
小橘 🍊
2026-05-13 03:25:50 +00:00
xiaoju c4d34530e8 chore: bump cli-workflow 0.3.8 (fix gateway dep resolution)
小橘 🍊
2026-05-13 03:23:09 +00:00
xiaoju 90a410c00a chore: bump cli-workflow to 0.3.7 (fix gateway dep version)
小橘 🍊
2026-05-13 03:21:34 +00:00
xiaoju 8e63f99eb6 chore: bump all public packages to 0.3.6
小橘 🍊
2026-05-13 03:18:25 +00:00
xingyue ec3c97b200 feat: WS request proxy — Gateway proxies HTTP via WebSocket (#210 Phase 2)
- Add ws-protocol.ts with WsRequest/WsResponse types + parsers
- AgentSocket DO: proxy POST handler, pending request map, 30s timeout
- /api/agents/:agent/* routes through DO WS when connected, falls back to HTTP
- ws-client handles incoming WsRequest, fetches local serve, returns WsResponse
- startGatewayWsClient accepts localPort for request handling

Testing: #213
2026-05-13 11:05:03 +08:00
xingyue 18e3dc7603 feat: WebSocket reverse-connection gateway Phase 1 (#210)
- Add AgentSocket Durable Object (holds one WS per agent name)
- Add /ws/connect route with GATEWAY_SECRET auth
- Add ws-client.ts with auto-reconnect (exponential backoff 1s-30s)
- serve defaults to WS mode (no cloudflared needed)
- Keep --tunnel-url and --no-tunnel as fallback options
- Endpoints list merges KV heartbeat + DO WebSocket status

Testing: #211
2026-05-13 11:05:03 +08:00
xingyue 2698e0a6cb fix(setup): add GLM international endpoint (api.z.ai) 2026-05-13 09:52:07 +08:00
xingyue 47f2b1a128 fix(setup): address code review issues (#221)
- Fix resolve variable shadowing in promptSecret (rename to fulfill)
- Fix readline leak on invalid choice (close before returning err)
- Remove Anthropic/Gemini from presets (not OpenAI-compatible)
- Fix GLM URL: api.z.ai → open.bigmodel.cn
- Restore terminal raw mode before process.exit on Ctrl+C
- Add debug logging to fetchAvailableModels failures
- Add comment explaining DashScope-specific model filter patterns
- Move PresetProvider and CmdSetupSuccess types to types.ts per convention
2026-05-13 09:43:57 +08:00
xingyue 0c02cb7574 chore: publish v0.3.5
小橘 <xiaoju@shazhou.work>
2026-05-13 09:34:41 +08:00
xingyue 320810ec25 fix(cli-workflow): workspace path accepts relative/absolute paths with retry
- cmdInitWorkspace now resolves full paths via resolve() instead of
  requiring a single segment name
- mkdir uses recursive: true for nested paths (e.g. ./a/b/workflows)
- Setup interactive prompt retries on existing directory instead of exiting
- Update tests: nested paths are now valid, add accepts-nested-path test
2026-05-13 09:30:41 +08:00
xingyue 91f585c534 feat(cli-workflow): numbered model selection in setup
- Show available models with numbered labels in multi-column layout
- User can pick by number or type model name directly
- Print selected model with arrow confirmation
2026-05-13 09:25:00 +08:00
xingyue 299ff126d9 feat(cli-workflow): preset provider selection in setup
- Add providers.yaml with 18 preset providers (international + China + local)
- Add preset-providers.ts to load and cache YAML presets
- Refactor interactive setup to show numbered provider list
- Only prompt for manual name/URL when choosing Custom
- YAML-driven: add new providers without code changes
2026-05-13 09:19:30 +08:00
xingyue 931eb81458 fix(setup): default workspace to ./workflows when left empty
Enter = use default ./workflows. Type 'skip' to skip.
2026-05-12 22:32:01 +08:00
xingyue c604d1f600 fix(setup): simplify model prompt — just ask for model name
Provider is already known from the first step, so prompt simply
asks 'Default model:' and auto-prepends provider/ prefix.
2026-05-12 22:28:35 +08:00
xingyue 20bcc65f61 fix(setup): auto-prefix provider on model input
Users can now type bare model names (e.g. 'qwen-plus') or paste
model IDs with vendor prefixes (e.g. 'MiniMax/MiniMax-M2.7') —
the provider prefix is normalised automatically.
2026-05-12 22:27:07 +08:00
xingyue f5612ef1b5 fix(setup): filter non-chat models and display in multi-column layout
Filter out speech/embed/image/video/audio/tts/asr/ocr/rerank models
from the /models listing. Display remaining models in a responsive
multi-column grid that adapts to terminal width.
2026-05-12 22:09:13 +08:00
xingyue a92deeaf3f fix(setup): mask each character when pasting API key
Raw mode receives pasted text as a single chunk. Iterate
per-character so every char gets a '*'. Also fix backspace
to erase the visual '*' from the terminal.
2026-05-12 22:03:48 +08:00
xingyue 1e936cf04a fix: improve setup interactive UX
1. Mask API key input with * characters (raw mode)
2. Fetch and list available models from provider /models endpoint
3. Workspace prompt: fill path directly (default skip), not y/n
4. Add .gitkeep to workflows/ in init workspace scaffold
2026-05-12 21:44:21 +08:00
xingyue ea16057803 fix: improve setup interactive prompts with context and examples
- Add intro line explaining what's being configured
- Provider: explain it's a label for the LLM service
- Base URL: explain it's OpenAI-compatible, show examples
- API key: clarify it's for this provider
- Default model: show format with dynamic provider name
- Workspace prompt: clearer wording
2026-05-12 20:52:42 +08:00
xingyue 4493fd8979 chore: publish v0.3.4
小橘 <xiaoju@shazhou.work>
2026-05-12 20:35:02 +08:00
xingyue 0ad5c85f5a chore: address #219 review comments
- Add comment explaining biome.json scripts/bundle.ts exclusion
- Add note about readline API key visibility limitation
2026-05-12 20:27:27 +08:00
xingyue cdf3c95622 feat: add setup command for provider/model config (#216 Phase 2)
New command: uncaged-workflow setup

CLI mode (agent-friendly):
  uncaged-workflow setup \
    --provider <name> --base-url <url> --api-key <key> \
    --default-model <provider/model> [--init-workspace <name>]

Interactive mode: prompts for each value when no flags given.

- Reads/writes workflow.yaml config section
- Idempotent: updates provider without losing workflows
- Sets maxDepth=3, supervisorInterval=3 on fresh config
- Optional --init-workspace creates workspace in cwd

Testing: #218
Ref: #216
2026-05-12 20:18:23 +08:00
xingyue a7fea10383 feat: init workspace generates bundle script (#216 Phase 1)
- Add scripts.bundle to generated package.json
- Generate scripts/bundle.ts that scans workflows/*-entry.ts,
  uses Bun.build() to produce dist/*.esm.js + dist/*.d.ts
- External: @uncaged/workflow-* packages (per bundle contract)
- Add tests for new scaffold files

Testing: #217
Ref: #216
2026-05-12 20:09:41 +08:00
xingyue 3846dc12a9 chore: bump all public packages to 0.3.3 2026-05-12 12:58:17 +08:00
xingyue 4c4dabb7a3 chore: bump all public packages to 0.3.2 2026-05-12 12:55:21 +08:00
xingyue bbb79f821e feat(init): generate bunfig.toml with Gitea scoped registry + fix versions
- init workspace now generates bunfig.toml pointing @uncaged scope to Gitea
- Fix template versions: "*" → "^0.3.1" (packages are now published)
2026-05-12 11:31:41 +08:00
xingyue 0fbbf37548 chore(cli): add bun run link scripts + fix init template versions
- Add link/link:consume/link:unlink scripts to root package.json
- Document cross-repo bun link workflow in CLAUDE.md
- Fix hardcoded @uncaged/workflow-runtime "^0.1.0" → "*" in
  init workspace and init template scaffolds (actual version is 0.3.x)
2026-05-12 11:03:12 +08:00
xiaomo 1c68ce6217 Merge pull request 'feat: Phase 3 — agent observability for Merkle call stack' (#203) from feat/197-agent-observability into main 2026-05-12 02:34:47 +00:00
xingyue 9cb7d68abe feat: Dashboard workflow graph visualization with React Flow (#198)
Phase 1: API + static graph rendering

Backend:
- GET /workflows/:name now returns descriptor (with graph) from bundle YAML
- Graceful fallback to null if YAML missing/invalid

Frontend:
- New workflow-graph/ component module (7 files)
- React Flow + dagre auto-layout (TB direction)
- Custom nodes: RoleNode (rounded rect) + TerminalNode (circle for START/END)
- Custom edges: dashed for FALLBACK, solid with label for conditions
- Self-loop edges supported (e.g. coder → coder)
- Node states: default/completed/active with color-coded borders
- Active node pulse animation
- Collapsible graph panel (300px) above thread records
- Dark theme using existing CSS variables

Integration:
- ThreadDetail extracts workflow name → fetches descriptor → computes node states → renders graph
- Node states derived from ThreadRecord[] (completed/active/default)
2026-05-12 10:27:07 +08:00
xiaoju 98122b446d feat: Phase 3 — agent observability for Merkle call stack
- StartStep gains parentState: string | null (from StartNodePayload)
- buildAgentPrompt injects Parent Context section when parentState is set
- CLI thread show outputs parentState (top-level) and childThread (per step)
- 2 new prompt tests + thread show assertion updates

Refs #197, #194

小橘 🍊(NEKO Team)
2026-05-12 02:23:15 +00:00
xiaomo aebff8b906 Merge pull request 'refactor: replace Moderator function with ModeratorTable in WorkflowDefinition' (#201) from refactor/200-moderator-table into main 2026-05-12 02:06:03 +00:00
xingyue db45089922 refactor: replace Moderator function with ModeratorTable in WorkflowDefinition (#200)
- WorkflowDefinition.moderator → WorkflowDefinition.table (ModeratorTable)
- Moderator type + tableToModerator no longer exported from protocol/runtime
- tableToModerator internalized in workflow-execute engine layer
- WorkflowDescriptor gains graph: WorkflowGraph (auto-extracted from table)
- buildDescriptor extracts serializable graph edges from ModeratorTable
- validateWorkflowDescriptor validates graph structure
- All templates (develop, solve-issue) export table directly
- CLI init scaffold updated to use ModeratorTable
- 99 tests pass, 0 failures
2026-05-12 10:01:30 +08:00
xiaoju a98431a12a feat(#194): Phase 1 — parentState / childThread in CAS nodes
- Protocol: StartNodePayload.parentState, StateNodePayload.childThread
- CAS: putStartNode refs include parentState, collectRefs includes childThread
- Parsing: legacy nodes without new fields default to null
- Engine + fork: all callers pass parentState: null / childThread: null
- Tests: 8 new cases for refs, parsing, collect-refs (+208 lines)

Phase 1 of #194 (Merkle Call Stack). Closes #195.

小橘 <xiaoju@shazhou.work>
2026-05-12 01:42:10 +00:00
xiaoju cf0540d7fa fix: stabilize kill-thread test by polling instead of fixed delay
Replace 50ms setTimeout with waitUntilPredicate polling for first role
completion before issuing kill. Same pattern used by pause/resume test.

小橘 <xiaoju@shazhou.work>
2026-05-11 13:56:14 +00:00
xiaoju 376dd87b6b chore: bump to v0.3.1, fix workspace:* in published packages
v0.3.0 was published with workspace:* deps (npm doesn't resolve them).
Re-published as v0.3.1 with concrete version refs.
Local monorepo deps restored to workspace:*.

小橘 <xiaoju@shazhou.work>
2026-05-11 11:00:49 +00:00
xiaoju 4d8469a649 chore: bump all packages to v0.3.0
Published to Gitea npm registry (git.shazhou.work).

小橘 <xiaoju@shazhou.work>
2026-05-11 10:52:35 +00:00
xiaoju ec13c19505 Merge pull request 'refactor: replace maxRounds with supervisor check interval' (#186) from refactor/185-remove-max-rounds into main 2026-05-11 09:01:24 +00:00
xiaoju 2b587612d5 refactor: replace maxRounds with supervisor check interval
Removes maxRounds as a hard stop limit from the entire stack. The supervisor
(already configured via workflow.yaml supervisorInterval) is now the sole
termination authority.

Changes across 27 files in 11 packages:
- workflow-protocol: StartStep.meta is now empty, StartNodePayload drops maxRounds
- workflow-cas: isStartPayload no longer checks maxRounds
- workflow-execute: engine, worker, fork-thread all stripped of maxRounds plumbing
- cli-workflow: --max-rounds flag removed from CLI and HTTP API
- workflow-runtime: build-context and create-workflow no longer reference maxRounds
- workflow-dashboard: UI no longer sends maxRounds
- workflow-template-develop/solve-issue: moderator no longer checks rounds remaining
- All tests updated

Fixes #185
2026-05-11 08:51:35 +00:00
xingyue 2342a6e3bd fix: login.tsx use new gateway endpoint path 2026-05-11 16:46:38 +08:00
xingyue 0021596ff0 Merge pull request 'refactor: simplify ExtractFn to (schema, contentHash)' (#184) from refactor/180-simplify-extract-fn into main 2026-05-11 08:03:48 +00:00
xiaoju 1742ced6df refactor: simplify ExtractFn to (schema, contentHash)
- Remove extractPrompt from RoleDefinition
- Remove ExtractContext type
- ExtractFn now takes (schema, contentHash) instead of (schema, prompt, ExtractContext)
- createExtract reads CAS content by hash, keeps ReAct loop with cas_get
- Coder schema uses .describe() for phase hash hint
- All role definitions, CLI templates, and skill output updated

Refs #180, closes #174, closes #181
2026-05-11 07:54:09 +00:00