Compare commits

..

24 Commits

Author SHA1 Message Date
xiaoju 76830c5e22 chore: add log-tag lint + fix biome errors + pre-push hook
- scripts/lint-log-tags.sh: static check for invalid Crockford Base32 log tags (I/L/O/U)
- fix two invalid log tags in ws-client.ts (6CJX2RLP→6CJX2R8P, T9W2KL5H→T9W2K35H)
- fix biome errors: unused import, exhaustive deps, cognitive complexity suppression
- add pre-push git hook running bun run check
- integrate lint-log-tags into bun run check pipeline

Refs #244
2026-05-13 14:59:20 +00:00
xiaoju 82e40f0c21 feat: planner abort path — fail fast when workspace info is missing
- PlannerMeta is now a discriminated union: planned | aborted
- Moderator routes aborted planner → END (no coder invocation)
- System prompt requires absolute workspace path, instructs abort if missing
- extractRefs handles both variants
- Test: 'planner aborted → END'

Signed-off-by: 小橘 <xiaoju@shazhou.work>
2026-05-13 14:20:23 +00:00
xiaoju 8d650326db chore: add output rules to all develop roles — suppress verbose diffs
Planner, coder, reviewer, and tester system prompts now explicitly
instruct the agent to keep responses short and avoid pasting diffs,
code blocks, or full build logs. This reduces CAS storage and token
waste when downstream roles read the thread.

Signed-off-by: 小橘 <xiaoju@shazhou.work>
2026-05-13 13:52:04 +00:00
xingyue dd3eec7d35 docs: update CLAUDE.md — changesets + npmjs registry 2026-05-13 21:22:15 +08:00
xingyue 9276689cb6 chore: switch to npmjs registry, publish v0.4.5
- Remove Gitea npm registry, use npmjs.org
- changeset publish works natively with npmjs
- release script: build + test + changeset publish
- Remove custom release.sh, all via changesets
2026-05-13 21:20:18 +08:00
xingyue b4584cbaa6 chore: publish v0.4.3 — include src/ in published packages
bun runtime resolves the 'bun' exports condition to ./src/index.ts,
but src/ was not in the files array so consumers got ENOENT.
2026-05-13 21:11:17 +08:00
xingyue 1cf963a1fb chore: publish v0.4.2 — fix workspace deps, remove publish.sh
- workspace:* → workspace:^ (resolves to ^x.y.z instead of exact)
- Remove publish.sh, use changesets workflow
- changeset config: access public (Gitea compat)
- release script: build + test + changeset publish
2026-05-13 21:07:29 +08:00
xingyue ce5bc50210 chore: publish v0.4.1
小橘 <xiaoju@shazhou.work>
2026-05-13 20:59:59 +08:00
xiaomo 439e203113 Merge pull request 'feat: adopt @changesets/cli for synchronized version management' (#243) from feat/changesets-version-management into main 2026-05-13 12:57:41 +00:00
xingyue 522afdd4bd feat: adopt changesets + fix exports, bump to 0.4.0
- Install @changesets/cli with fixed mode (all @uncaged/* packages sync version)
- Fix package exports: add bun condition, point import to dist/
- Bump all packages to 0.4.0 via changeset version
- Auto-generated CHANGELOG.md for each package
- Ignore workflow-dashboard (private)
- Add npm scripts: changeset, version, release
- publish.sh: support workspace:^ prefix matching

Closes #241, Closes #242
2026-05-13 20:56:21 +08:00
xingyue ca644dabaa chore: bump all packages to 0.4.0, fix exports for publish
- All @uncaged/* packages → 0.4.0
- Internal deps: workspace:* → workspace:^ (resolves to ^0.4.0 on publish)
- Fix exports: add 'bun' condition for local dev (src), 'import' for consumers (dist)
- Remove stale 'main: src/index.ts' from 6 packages
- Fix publish.sh topo sort to match workspace:^ prefix

星月 <xingyue@shazhou.work>
2026-05-13 20:46:00 +08:00
xiaomo 9d9c00df98 Merge pull request 'chore: remove link-all.sh' (#240) from chore/remove-link-all into main 2026-05-13 10:16:22 +00:00
xiaoju a1c5dc3e92 chore: remove link-all.sh
Local symlink workflow replaced by Gitea npm registry publish flow.

Signed-off-by: 小橘 <xiaoju@shazhou.work>
2026-05-13 09:56:07 +00:00
xiaoju c85980f604 Merge pull request 'chore: merge publish-all.sh into publish.sh' (#238) from chore/merge-publish-scripts into main 2026-05-13 09:52:43 +00:00
xingyue eff5fb332a chore: merge publish.sh and publish-all.sh (#237)
- Topological sort from publish-all.sh replaces hardcoded order
- bun publish directly (no manual workspace:* replacement/restoration)
- bun run build + bun test (not npm run)
- --dry-run support (skips git commit/push)
- Delete publish-all.sh
- Update package.json scripts

Closes #237

Signed-off-by: 星月 <xingyue@shazhou.work>
2026-05-13 17:51:49 +08:00
xingyue 658a4a24ef chore: merge publish-all.sh into publish.sh
- Use bun pm pack for workspace:* resolution (no manual replace/restore)
- Topological sort replaces hardcoded PUBLISH_ORDER
- Registry unified to uncaged org
- Delete scripts/publish-all.sh
- Add --dry-run flag support

Closes #237
2026-05-13 17:44:06 +08:00
xingyue aabfd90a87 Merge pull request 'fix: auto-discover publishable packages + pre-publish test gate' (#236) from fix/auto-discover-publish into main 2026-05-13 09:42:55 +00:00
xingyue 0207f93303 fix: npm test → bun test per review 2026-05-13 17:42:11 +08:00
xingyue e1423f196b refactor: delegate publish to publish-all.sh, remove duplicated discovery+topo logic
- Remove inline auto-discover + Kahn's topo sort from publish.sh (was duplicating publish-all.sh)
- Remove inline publish loop + smoke test (publish-all.sh handles both)
- publish.sh now: bump version → replace workspace:* → build → test → call publish-all.sh → restore → commit
- Net: -97 lines, single source of truth for package discovery and publish order
2026-05-13 17:32:08 +08:00
xingyue ae6954a02f fix(publish): auto-discover packages + pre-publish test gate
What: Replace hardcoded PUBLISH_ORDER with auto-discovery of all
non-private packages, sorted by topological dependency order (Kahn's).
Add a test gate (npm test) after build, before publish.

Why: The manual list was missing workflow-gateway and workflow-agent-react,
causing them to never get published. Any future package additions would
have the same problem.

Changes:
- scripts/publish.sh: Replace static PUBLISH_ORDER array with node script
  that reads all packages/*/package.json, filters out private, and
  topologically sorts by @uncaged/* internal dependencies
- scripts/publish.sh: Add npm test step between build and publish,
  aborting on failure
2026-05-13 17:22:50 +08:00
xingyue aede8f7613 chore: publish v0.3.21
小橘 <xiaoju@shazhou.work>
2026-05-13 17:10:39 +08:00
xiaomo 6d1e0498ba Merge pull request 'refactor(dashboard): replace ELK with custom spine layout' (#235) from refactor/dashboard-custom-spine-layout into main 2026-05-13 09:03:34 +00:00
xingyue 6cce5e2593 chore: publish v0.3.20
小橘 <xiaoju@shazhou.work>
2026-05-13 17:00:43 +08:00
xingyue d3a7ed9062 chore: publish v0.3.19
小橘 <xiaoju@shazhou.work>
2026-05-13 16:56:55 +08:00
50 changed files with 1080 additions and 488 deletions
+8
View File
@@ -0,0 +1,8 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets).
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md).
+17
View File
@@ -0,0 +1,17 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [
[
"@uncaged/*"
]
],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
"@uncaged/workflow-dashboard"
]
}
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
# pre-push hook: typecheck + biome + lint-log-tags
set -euo pipefail
echo "🔍 pre-push: running checks..."
bun run check
echo "✅ pre-push: all checks passed"
+22 -35
View File
@@ -30,6 +30,7 @@ workflow/
workflow-agent-cursor/ # @uncaged/workflow-agent-cursor
workflow-agent-hermes/ # @uncaged/workflow-agent-hermes
workflow-agent-llm/ # @uncaged/workflow-agent-llm
workflow-agent-react/ # @uncaged/workflow-agent-react
workflow-util-agent/ # @uncaged/workflow-util-agent — buildAgentPrompt, spawnCli
workflow-template-develop/ # @uncaged/workflow-template-develop
workflow-template-solve-issue/ # @uncaged/workflow-template-solve-issue
@@ -40,7 +41,7 @@ workflow/
```
- Execution stack layers: `workflow-protocol` → (`workflow-runtime`, `workflow-util`, `workflow-reactor`) → (`workflow-cas`, `workflow-register`) → `workflow-execute``cli-workflow`
- Packages use `workspace:*` protocol
- Packages use `workspace:^` protocol (resolves to `^x.y.z` on publish)
## Language & Paradigm
@@ -245,61 +246,47 @@ bun run format # biome format --write
bun test # run tests
```
### Publishing to Gitea npm Registry
### Version Management & Publishing
All public `@uncaged/*` packages are published to the Gitea npm registry at `git.shazhou.work`. Workflow workspaces consume packages from this registry via `bunfig.toml`.
All public `@uncaged/*` packages are published to **npmjs.org** via `@changesets/cli` with **fixed mode** (all packages share the same version number). `workflow-dashboard` is private and excluded.
```bash
# Publish all packages (bun pm pack resolves workspace:* → actual versions)
bun run publish:gitea
# 1. After making changes, add a changeset describing the change
bun changeset
# Dry run — see what would be published
bun run publish:gitea:dry
# 2. Before release, bump all package versions + generate CHANGELOGs
bun version
# 3. Build, test, and publish to npmjs
bun release
```
Prerequisites: `.npmrc` in monorepo root with Gitea auth token (`//git.shazhou.work/api/packages/shazhou/npm/:_authToken=<token>`).
- `workspace:^` dependencies resolve to `^x.y.z` on publish
- Changesets config: `.changeset/config.json` (fixed mode, public access)
- Each package has auto-generated `CHANGELOG.md`
### Workflow Workspace Setup
### Consuming @uncaged/* Packages
External workflow repos (e.g. `xingyue-workflows`) use the Gitea registry for `@uncaged/*` packages. Add a `bunfig.toml`:
```toml
[install.scopes]
"@uncaged" = "https://git.shazhou.work/api/packages/shazhou/npm/"
```
Then `bun install` resolves `@uncaged/*` from Gitea, all other packages from npmjs.
### Cross-repo Development (bun link)
Alternative for development against un-published local changes:
```bash
bun run link # Register all packages (from monorepo root)
bun run link:consume # Link into CWD's project (⚠️ don't bun install after)
bun run link:unlink # Restore original deps
```
External workflow repos just `bun install` — packages come from npmjs like any other dependency. No special registry config needed.
### End-to-end: Monorepo → Registry → Workspace → Bundle
The recommended development flow for building workflows:
```
workflow/ (monorepo) — engine, runtime, templates, agents
│ bun run publish:giteaauto topo-sort, bun pm pack → npm publish
│ bun release build + test + changeset publish
git.shazhou.work npm registry — @uncaged/* scoped packages
│ bun install — via bunfig.toml scoped registry
npmjs.org — @uncaged/* scoped packages (public)
│ bun install
my-workflows/ (workspace) — bunfig.toml + normal package.json
my-workflows/ (workspace) — normal package.json
│ bun run build:develop — bun build → single .esm.js
uncaged-workflow workflow add — register bundle locally
uncaged-workflow run — execute workflow
```
1. **Monorepo changes**`bun run publish:gitea` (packages auto-discovered from `packages/*/`, topologically sorted, `workspace:*` resolved to real versions)
2. **Workspace**`bun install` fetches latest from Gitea, `bun install` is safe to run anytime
1. **Monorepo changes**`bun changeset` (describe change) → `bun version` (bump) → `bun release` (publish)
2. **Workspace**`bun install` fetches latest from npmjs
3. **Build** → produces single-file ESM bundle with `@uncaged/*` as externals
4. **Register & Run**`uncaged-workflow workflow add <name> <bundle>` then `uncaged-workflow run <name>`
+5 -6
View File
@@ -6,18 +6,17 @@
],
"scripts": {
"build": "bunx tsc --build",
"check": "bunx tsc --build && biome check .",
"check": "bunx tsc --build && biome check . && bash scripts/lint-log-tags.sh",
"typecheck": "bunx tsc --build",
"format": "biome format --write .",
"test": "bun run --filter '*' test",
"link": "./scripts/link-all.sh",
"link:consume": "./scripts/link-all.sh --consume",
"link:unlink": "./scripts/link-all.sh --unlink",
"publish:gitea": "./scripts/publish-all.sh",
"publish:gitea:dry": "./scripts/publish-all.sh --dry-run"
"changeset": "bunx changeset",
"version": "bunx changeset version",
"release": "bun run build && bun test && npx changeset publish --no-git-tag"
},
"devDependencies": {
"@biomejs/biome": "^2.4.14",
"@changesets/cli": "^2.31.0",
"@types/node": "^25.7.0",
"@types/xxhashjs": "^0.2.4",
"bun-types": "^1.3.13"
+72
View File
@@ -0,0 +1,72 @@
# @uncaged/cli-workflow
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-cas@0.4.5
- @uncaged/workflow-execute@0.4.5
- @uncaged/workflow-gateway@0.4.5
- @uncaged/workflow-register@0.4.5
- @uncaged/workflow-runtime@0.4.5
- @uncaged/workflow-util@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-cas@0.4.4
- @uncaged/workflow-execute@0.4.4
- @uncaged/workflow-gateway@0.4.4
- @uncaged/workflow-register@0.4.4
- @uncaged/workflow-runtime@0.4.4
- @uncaged/workflow-util@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-cas@0.4.3
- @uncaged/workflow-execute@0.4.3
- @uncaged/workflow-gateway@0.4.3
- @uncaged/workflow-protocol@0.4.3
- @uncaged/workflow-register@0.4.3
- @uncaged/workflow-runtime@0.4.3
- @uncaged/workflow-util@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-cas@0.4.2
- @uncaged/workflow-execute@0.4.2
- @uncaged/workflow-gateway@0.4.2
- @uncaged/workflow-protocol@0.4.2
- @uncaged/workflow-register@0.4.2
- @uncaged/workflow-runtime@0.4.2
- @uncaged/workflow-util@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-cas@0.4.0
- @uncaged/workflow-execute@0.4.0
- @uncaged/workflow-gateway@0.4.0
- @uncaged/workflow-protocol@0.4.0
- @uncaged/workflow-register@0.4.0
- @uncaged/workflow-runtime@0.4.0
- @uncaged/workflow-util@0.4.0
+11 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@uncaged/cli-workflow",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
@@ -11,17 +11,20 @@
"uncaged-workflow": "src/cli.ts"
},
"dependencies": {
"@uncaged/workflow-gateway": "workspace:*",
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-util": "workspace:*",
"@uncaged/workflow-cas": "workspace:*",
"@uncaged/workflow-execute": "workspace:*",
"@uncaged/workflow-register": "workspace:*",
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-gateway": "workspace:^",
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-util": "workspace:^",
"@uncaged/workflow-cas": "workspace:^",
"@uncaged/workflow-execute": "workspace:^",
"@uncaged/workflow-register": "workspace:^",
"@uncaged/workflow-runtime": "workspace:^",
"hono": "^4.12.18",
"yaml": "^2.8.4"
},
"scripts": {
"test": "bun test"
},
"publishConfig": {
"access": "public"
}
}
@@ -100,7 +100,7 @@ export function startGatewayWsClient(params: GatewayWsClientParams): () => void
clearReconnectTimer();
const delayMs = Math.min(INITIAL_BACKOFF_MS * 2 ** attempt, MAX_BACKOFF_MS);
attempt++;
params.log("6CJX2RLP", `gateway WebSocket reconnect in ${delayMs}ms (attempt ${attempt})`);
params.log("6CJX2R8P", `gateway WebSocket reconnect in ${delayMs}ms (attempt ${attempt})`);
reconnectTimer = setTimeout(connect, delayMs);
};
@@ -143,7 +143,7 @@ export function startGatewayWsClient(params: GatewayWsClientParams): () => void
ws.addEventListener("message", (ev) => {
const data = ev.data;
if (typeof data !== "string") {
params.log("T9W2KL5H", "gateway WebSocket non-text frame ignored");
params.log("T9W2K35H", "gateway WebSocket non-text frame ignored");
return;
}
void handleGatewayMessage(ws, data, params).catch((e: unknown) => {
@@ -0,0 +1,62 @@
# @uncaged/workflow-agent-cursor
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-reactor@0.4.5
- @uncaged/workflow-runtime@0.4.5
- @uncaged/workflow-util@0.4.5
- @uncaged/workflow-util-agent@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-reactor@0.4.4
- @uncaged/workflow-runtime@0.4.4
- @uncaged/workflow-util@0.4.4
- @uncaged/workflow-util-agent@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.3
- @uncaged/workflow-reactor@0.4.3
- @uncaged/workflow-runtime@0.4.3
- @uncaged/workflow-util-agent@0.4.3
- @uncaged/workflow-util@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.2
- @uncaged/workflow-reactor@0.4.2
- @uncaged/workflow-runtime@0.4.2
- @uncaged/workflow-util-agent@0.4.2
- @uncaged/workflow-util@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.0
- @uncaged/workflow-reactor@0.4.0
- @uncaged/workflow-runtime@0.4.0
- @uncaged/workflow-util-agent@0.4.0
- @uncaged/workflow-util@0.4.0
+12 -8
View File
@@ -1,28 +1,32 @@
{
"name": "@uncaged/workflow-agent-cursor",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-reactor": "workspace:*",
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-util": "workspace:*",
"@uncaged/workflow-util-agent": "workspace:*",
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-reactor": "workspace:^",
"@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^",
"zod": "^4.0.0"
},
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
@@ -0,0 +1,45 @@
# @uncaged/workflow-agent-hermes
## 0.4.5
### Patch Changes
- @uncaged/workflow-runtime@0.4.5
- @uncaged/workflow-util-agent@0.4.5
## 0.4.4
### Patch Changes
- @uncaged/workflow-runtime@0.4.4
- @uncaged/workflow-util-agent@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-runtime@0.4.3
- @uncaged/workflow-util-agent@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-runtime@0.4.2
- @uncaged/workflow-util-agent@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-runtime@0.4.0
- @uncaged/workflow-util-agent@0.4.0
+9 -5
View File
@@ -1,24 +1,28 @@
{
"name": "@uncaged/workflow-agent-hermes",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-util-agent": "workspace:*"
"@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^"
},
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
+45
View File
@@ -0,0 +1,45 @@
# @uncaged/workflow-agent-llm
## 0.4.5
### Patch Changes
- @uncaged/workflow-runtime@0.4.5
- @uncaged/workflow-util-agent@0.4.5
## 0.4.4
### Patch Changes
- @uncaged/workflow-runtime@0.4.4
- @uncaged/workflow-util-agent@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-runtime@0.4.3
- @uncaged/workflow-util-agent@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-runtime@0.4.2
- @uncaged/workflow-util-agent@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-runtime@0.4.0
- @uncaged/workflow-util-agent@0.4.0
+9 -5
View File
@@ -1,27 +1,31 @@
{
"name": "@uncaged/workflow-agent-llm",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-util-agent": "workspace:*"
"@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^"
},
"devDependencies": {
"zod": "^4.0.0"
},
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
@@ -0,0 +1,52 @@
# @uncaged/workflow-agent-react
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-reactor@0.4.5
- @uncaged/workflow-util-agent@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-reactor@0.4.4
- @uncaged/workflow-util-agent@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.3
- @uncaged/workflow-reactor@0.4.3
- @uncaged/workflow-util-agent@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.2
- @uncaged/workflow-reactor@0.4.2
- @uncaged/workflow-util-agent@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.0
- @uncaged/workflow-reactor@0.4.0
- @uncaged/workflow-util-agent@0.4.0
+11 -7
View File
@@ -1,31 +1,35 @@
{
"name": "@uncaged/workflow-agent-react",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-reactor": "workspace:*",
"@uncaged/workflow-util-agent": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-reactor": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^"
},
"devDependencies": {
"zod": "^4.0.0"
},
"peerDependencies": {
"zod": "^4.0.0"
},
"publishConfig": {
"access": "public"
}
}
+47
View File
@@ -0,0 +1,47 @@
# @uncaged/workflow-cas
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-util@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-util@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.3
- @uncaged/workflow-util@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.2
- @uncaged/workflow-util@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.0
- @uncaged/workflow-util@0.4.0
+9 -4
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-cas",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -11,17 +12,21 @@
},
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-util": "workspace:*",
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-util": "workspace:^",
"xxhashjs": "^0.2.2",
"yaml": "^2.7.1"
},
"devDependencies": {
"@types/bun": "latest"
},
"publishConfig": {
"access": "public"
}
}
@@ -1,9 +1,4 @@
import {
BaseEdge,
EdgeLabelRenderer,
type EdgeProps,
getSmoothStepPath,
} from "@xyflow/react";
import { BaseEdge, EdgeLabelRenderer, type EdgeProps, getSmoothStepPath } from "@xyflow/react";
import type { ConditionEdgeData } from "./types.ts";
// Must match the FEEDBACK_OFFSET_X in use-layout.ts
@@ -15,12 +10,7 @@ const FEEDBACK_RADIUS = 16;
* Build an SVG path for a feedback (back) edge that routes to the right of the nodes.
* The path goes: source right → arc → vertical up → arc → target right
*/
function feedbackPath(
sourceX: number,
sourceY: number,
targetX: number,
targetY: number,
): string {
function feedbackPath(sourceX: number, sourceY: number, targetX: number, targetY: number): string {
const rightX = Math.max(sourceX, targetX) + FEEDBACK_OFFSET_X;
const r = FEEDBACK_RADIUS;
@@ -42,6 +32,7 @@ function feedbackPath(
return segments.join(" ");
}
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: edge routing logic is inherently branchy
export function ConditionEdge(props: EdgeProps) {
const {
id,
@@ -1,7 +1,7 @@
import type { Edge, Node } from "@xyflow/react";
import { useMemo } from "react";
import type { WorkflowGraphEdge } from "../../api.ts";
import type { ConditionEdgeData, NodeState, RoleNodeData, TerminalNodeData } from "./types.ts";
import type { NodeState, RoleNodeData, TerminalNodeData } from "./types.ts";
const START_ID = "__start__";
const END_ID = "__end__";
@@ -41,6 +41,7 @@ function edgeKey(e: WorkflowGraphEdge): string {
* Forward edges go from lower rank to higher rank; feedback edges go backwards.
* Self-loops are neither forward nor feedback — they're handled separately.
*/
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: topological sort is inherently branchy
function extractSpine(edges: readonly WorkflowGraphEdge[]): string[] {
// Collect all node IDs
const ids = new Set<string>();
@@ -213,8 +214,8 @@ function computeLayout(input: LayoutInput): LayoutResult {
isFallback,
isFeedback,
isSelfLoop,
labelX,
labelY,
labelX,
labelY,
},
};
});
@@ -223,8 +224,5 @@ function computeLayout(input: LayoutInput): LayoutResult {
}
export function useLayout(input: LayoutInput): LayoutResult {
return useMemo(
() => computeLayout(input),
[input.edges, input.roles, input.nodeStates],
);
return useMemo(() => computeLayout(input), [input]);
}
+67
View File
@@ -0,0 +1,67 @@
# @uncaged/workflow-execute
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-cas@0.4.5
- @uncaged/workflow-reactor@0.4.5
- @uncaged/workflow-register@0.4.5
- @uncaged/workflow-runtime@0.4.5
- @uncaged/workflow-util@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-cas@0.4.4
- @uncaged/workflow-reactor@0.4.4
- @uncaged/workflow-register@0.4.4
- @uncaged/workflow-runtime@0.4.4
- @uncaged/workflow-util@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-cas@0.4.3
- @uncaged/workflow-protocol@0.4.3
- @uncaged/workflow-reactor@0.4.3
- @uncaged/workflow-register@0.4.3
- @uncaged/workflow-runtime@0.4.3
- @uncaged/workflow-util@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-cas@0.4.2
- @uncaged/workflow-protocol@0.4.2
- @uncaged/workflow-reactor@0.4.2
- @uncaged/workflow-register@0.4.2
- @uncaged/workflow-runtime@0.4.2
- @uncaged/workflow-util@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-cas@0.4.0
- @uncaged/workflow-protocol@0.4.0
- @uncaged/workflow-reactor@0.4.0
- @uncaged/workflow-register@0.4.0
- @uncaged/workflow-runtime@0.4.0
- @uncaged/workflow-util@0.4.0
+13 -8
View File
@@ -1,27 +1,29 @@
{
"name": "@uncaged/workflow-execute",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-util": "workspace:*",
"@uncaged/workflow-cas": "workspace:*",
"@uncaged/workflow-reactor": "workspace:*",
"@uncaged/workflow-register": "workspace:*",
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util": "workspace:^",
"@uncaged/workflow-cas": "workspace:^",
"@uncaged/workflow-reactor": "workspace:^",
"@uncaged/workflow-register": "workspace:^",
"yaml": "^2.7.1"
},
"peerDependencies": {
@@ -29,5 +31,8 @@
},
"devDependencies": {
"zod": "^4.0.0"
},
"publishConfig": {
"access": "public"
}
}
+23
View File
@@ -0,0 +1,23 @@
# @uncaged/workflow-gateway
## 0.4.5
## 0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
+5 -1
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-gateway",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -20,5 +21,8 @@
"devDependencies": {
"@cloudflare/workers-types": "^4.20260425.1",
"wrangler": "^4.20.0"
},
"publishConfig": {
"access": "public"
}
}
+31
View File
@@ -0,0 +1,31 @@
# @uncaged/workflow-protocol
## 0.4.5
### Patch Changes
- Add publishConfig to all packages for Gitea registry compatibility with changeset publish.
## 0.4.4
### Patch Changes
- Test changeset publish with Gitea registry.
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
+9 -3
View File
@@ -1,19 +1,22 @@
{
"name": "@uncaged/workflow-protocol",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
},
"./moderator-table.js": {
"bun": "./src/moderator-table.ts",
"types": "./dist/moderator-table.d.ts",
"import": "./src/moderator-table.ts"
"import": "./dist/moderator-table.js"
}
},
"peerDependencies": {
@@ -22,5 +25,8 @@
"devDependencies": {
"zod": "^4.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+42
View File
@@ -0,0 +1,42 @@
# @uncaged/workflow-reactor
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.0
+8 -3
View File
@@ -1,19 +1,21 @@
{
"name": "@uncaged/workflow-reactor",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^"
},
"peerDependencies": {
"zod": "^4.0.0"
@@ -21,5 +23,8 @@
"devDependencies": {
"zod": "^4.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+47
View File
@@ -0,0 +1,47 @@
# @uncaged/workflow-register
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-util@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-util@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.3
- @uncaged/workflow-util@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.2
- @uncaged/workflow-util@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.0
- @uncaged/workflow-util@0.4.0
+9 -4
View File
@@ -1,20 +1,22 @@
{
"name": "@uncaged/workflow-register",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-util": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-util": "workspace:^"
},
"peerDependencies": {
"acorn": "^8.0.0",
@@ -26,5 +28,8 @@
"yaml": "^2.7.1",
"zod": "^4.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+47
View File
@@ -0,0 +1,47 @@
# @uncaged/workflow-runtime
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
- @uncaged/workflow-cas@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
- @uncaged/workflow-cas@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-cas@0.4.3
- @uncaged/workflow-protocol@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-cas@0.4.2
- @uncaged/workflow-protocol@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-cas@0.4.0
- @uncaged/workflow-protocol@0.4.0
+9 -5
View File
@@ -1,19 +1,19 @@
{
"name": "@uncaged/workflow-runtime",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-cas": "workspace:*",
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-cas": "workspace:^",
"@uncaged/workflow-protocol": "workspace:^"
},
"peerDependencies": {
"zod": "^4.0.0"
@@ -23,8 +23,12 @@
},
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
@@ -0,0 +1,45 @@
# @uncaged/workflow-template-develop
## 0.4.5
### Patch Changes
- @uncaged/workflow-register@0.4.5
- @uncaged/workflow-runtime@0.4.5
## 0.4.4
### Patch Changes
- @uncaged/workflow-register@0.4.4
- @uncaged/workflow-runtime@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-register@0.4.3
- @uncaged/workflow-runtime@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-register@0.4.2
- @uncaged/workflow-runtime@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-register@0.4.0
- @uncaged/workflow-runtime@0.4.0
@@ -9,7 +9,9 @@ import type { DevelopMeta } from "../src/roles.js";
const developModerator = tableToModerator(developTable);
const DEFAULT_PHASES: PlannerMeta["phases"] = [
type PlannedMeta = Extract<PlannerMeta, { status: "planned" }>;
const DEFAULT_PHASES: PlannedMeta["phases"] = [
{
hash: "4KNMR2PX",
title: "Do the work",
@@ -36,11 +38,11 @@ function makeCtx(steps: ModeratorContext<DevelopMeta>["steps"]): ModeratorContex
};
}
function plannerStep(phases: PlannerMeta["phases"] = DEFAULT_PHASES): RoleStep<DevelopMeta> {
function plannerStep(phases: PlannedMeta["phases"] = DEFAULT_PHASES): RoleStep<DevelopMeta> {
return {
role: "planner",
contentHash: "STUBHASHPLANNER001",
meta: { phases },
meta: { status: "planned" as const, phases },
refs: phases.map((p) => p.hash),
timestamp: 1,
};
@@ -153,7 +155,7 @@ describe("developModerator", () => {
});
test("multiple planner phases → coder until all complete, then reviewer", () => {
const phases: PlannerMeta["phases"] = [
const phases: PlannedMeta["phases"] = [
{ hash: "AA000001", title: "first phase" },
{ hash: "AA000002", title: "second phase" },
];
@@ -167,7 +169,7 @@ describe("developModerator", () => {
});
test("one-shot coder reports only last phase hash → reviewer (moderator treats as all phases done)", () => {
const phases: PlannerMeta["phases"] = [
const phases: PlannedMeta["phases"] = [
{ hash: "BB000001", title: "setup branch" },
{ hash: "BB000002", title: "write tests" },
{ hash: "BB000003", title: "verify" },
@@ -179,7 +181,7 @@ describe("developModerator", () => {
});
test("unrecognised completedPhase hash → coder retry when budget allows", () => {
const phases: PlannerMeta["phases"] = [
const phases: PlannedMeta["phases"] = [
{ hash: "CC000001", title: "first phase" },
{ hash: "CC000002", title: "second phase" },
];
@@ -187,7 +189,7 @@ describe("developModerator", () => {
});
test("incomplete phases → coder retry (supervisor controls termination)", () => {
const phases: PlannerMeta["phases"] = [
const phases: PlannedMeta["phases"] = [
{ hash: "DD000001", title: "first phase" },
{ hash: "DD000002", title: "second phase" },
];
@@ -198,6 +200,17 @@ describe("developModerator", () => {
expect(developModerator(makeCtx(steps))).toBe("coder");
});
test("planner aborted → END", () => {
const abortedStep: RoleStep<DevelopMeta> = {
role: "planner",
contentHash: "STUBHASHABORT001",
meta: { status: "aborted", reason: "No workspace path provided" },
refs: [],
timestamp: 1,
};
expect(developModerator(makeCtx([abortedStep]))).toBe("__end__");
});
test("committer → END for any committer meta status", () => {
const committed = committerStep({ status: "committed", branch: "f", commitSha: "x" });
const recoverable = committerStep({
@@ -1,26 +1,31 @@
{
"name": "@uncaged/workflow-template-develop",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-register": "workspace:*",
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-register": "workspace:^",
"@uncaged/workflow-runtime": "workspace:^",
"zod": "^4.0.0"
},
"devDependencies": {
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^"
},
"publishConfig": {
"access": "public"
}
}
@@ -30,6 +30,18 @@ function coderFinishedAllPlannedPhases(
// ── Conditions ─────────────────────────────────────────────────────
const plannerAborted: ModeratorCondition<DevelopMeta> = {
name: "plannerAborted",
description: "The planner aborted due to insufficient information",
check: (ctx) => {
const plannerStep = ctx.steps.find((s) => s.role === "planner");
if (plannerStep === undefined) {
return false;
}
return plannerStep.meta.status === "aborted";
},
};
const allPhasesComplete: ModeratorCondition<DevelopMeta> = {
name: "allPhasesComplete",
description: "All planned phases have been completed by the coder",
@@ -38,7 +50,7 @@ const allPhasesComplete: ModeratorCondition<DevelopMeta> = {
if (plannerStep === undefined) {
return true;
}
const phases = plannerStep.meta.phases;
const phases = plannerStep.meta.status === "planned" ? plannerStep.meta.phases : [];
if (!Array.isArray(phases)) {
return true;
}
@@ -71,7 +83,10 @@ const testsPassed: ModeratorCondition<DevelopMeta> = {
const table: ModeratorTable<DevelopMeta> = {
[START]: [{ condition: "FALLBACK", role: "planner" }],
planner: [{ condition: "FALLBACK", role: "coder" }],
planner: [
{ condition: plannerAborted, role: END },
{ condition: "FALLBACK", role: "coder" },
],
coder: [
{ condition: allPhasesComplete, role: "reviewer" },
{ condition: "FALLBACK", role: "coder" },
@@ -25,7 +25,11 @@ The thread ID (26-char Crockford Base32) appears in the first message. If unsure
## Completing a phase
Report which phase you completed using the phase **hash** (not the title). If you legitimately finish every remaining phase in this single turn, set completedPhase to the **last** phase hash in the plan (the workflow treats that as full completion). List the files you changed and summarize what you did.`;
Report which phase you completed using the phase **hash** (not the title). If you legitimately finish every remaining phase in this single turn, set completedPhase to the **last** phase hash in the plan (the workflow treats that as full completion). List the files you changed and summarize what you did.
## Output rules
Keep your final response **short** — a brief summary paragraph plus the structured meta output. Do NOT paste diffs, file contents, or code blocks in your response. The actual changes are already on disk; repeating them wastes tokens. Just say what you did and why.`;
export const coderRole: RoleDefinition<CoderMeta> = {
description:
@@ -6,16 +6,27 @@ export const phaseSchema = z.object({
title: z.string(),
});
export const plannerMetaSchema = z.object({
phases: z.array(phaseSchema),
});
export const plannerMetaSchema = z.discriminatedUnion("status", [
z.object({
status: z.literal("planned"),
phases: z.array(phaseSchema),
}),
z.object({
status: z.literal("aborted"),
reason: z.string().describe("Why the task cannot proceed"),
}),
]);
export type PlannerMeta = z.infer<typeof plannerMetaSchema>;
const PLANNER_SYSTEM = `You are a **planner** for a software task. Break the work into **sequential phases** the coder will execute one at a time.
const PLANNER_SYSTEM = `You are a **planner** for a software task. Break the work into **sequential phases** the coder will execute one at a time. **Abort** if the prompt lacks critical information (e.g. no project/workspace path, ambiguous target repo).
Run \`uncaged-workflow skill develop\` for thread ID lookup, CAS commands, and meta output guide.
## Prerequisites — check FIRST
The prompt MUST include an **absolute filesystem path** to the project workspace (e.g. \`/home/user/repos/my-project\`). If no workspace path is given and you cannot reliably infer one from context, **abort immediately** with a clear reason explaining what information is missing. Do NOT guess paths.
## Storing phase details — MANDATORY
For each phase, store its full detail text in CAS via \`uncaged-workflow cas put '<content>'\`. The command prints a content-hash — use that as the phase identifier.
@@ -37,13 +48,20 @@ Fewer phases is always better. Each phase must justify its existence — if two
## Output format
After storing all phases via the CLI, output compact JSON only:
{ "phases": [{ "hash": "<hash-from-cas-put>", "title": "<one-line-summary>" }] }
{ "status": "planned", "phases": [{ "hash": "<hash-from-cas-put>", "title": "<one-line-summary>" }] }
Order phases so earlier steps unblock later ones. Cover root cause, edge cases, and verification across the phases.`;
If aborting:
{ "status": "aborted", "reason": "<what is missing>" }
Order phases so earlier steps unblock later ones. Cover root cause, edge cases, and verification across the phases.
## Output rules
Keep your final response **short** — just the JSON with phases. Do NOT paste code snippets, diffs, or implementation details in your response. Phase details are already stored in CAS; your response should only contain the compact phases JSON.`;
export const plannerRole: RoleDefinition<PlannerMeta> = {
description: "Breaks the task into sequential phases for the coder.",
systemPrompt: PLANNER_SYSTEM,
schema: plannerMetaSchema,
extractRefs: (meta) => meta.phases.map((p) => p.hash),
extractRefs: (meta) => meta.status === "planned" ? meta.phases.map((p) => p.hash) : [],
};
@@ -32,7 +32,11 @@ const REVIEWER_SYSTEM = `You are a code reviewer. Review the git diff for correc
- **Approve** only if there are zero issues
- **Reject** with specific issues that must be fixed — every issue you find is blocking
Be thorough. A false approve costs more than a false reject.`;
Be thorough. A false approve costs more than a false reject.
## Output rules
Keep your final response **short**. Summarize findings in a few bullet points, then output the structured verdict. Do NOT paste the full diff or large code blocks in your response.`;
export const reviewerRole: RoleDefinition<ReviewerMeta> = {
description: "Runs git diff checks and sets approved when the change is ready.",
@@ -14,7 +14,11 @@ export const testerMetaSchema = z.discriminatedUnion("status", [
export type TesterMeta = z.infer<typeof testerMetaSchema>;
const TESTER_SYSTEM = `You are a tester. Run the project's test suite, build, and lint commands. Check what commands are available from the preparer's output in the thread. Report pass/fail with details of what failed.`;
const TESTER_SYSTEM = `You are a tester. Run the project's test suite, build, and lint commands. Check what commands are available from the preparer's output in the thread. Report pass/fail with details of what failed.
## Output rules
Keep your final response **short**. Report pass/fail with a brief summary of failures (if any). Do NOT paste full test output or build logs — just the key error lines.`;
export const testerRole: RoleDefinition<TesterMeta> = {
description: "Runs test, build, and lint commands and reports pass or fail with details.",
@@ -0,0 +1,45 @@
# @uncaged/workflow-template-solve-issue
## 0.4.5
### Patch Changes
- @uncaged/workflow-register@0.4.5
- @uncaged/workflow-runtime@0.4.5
## 0.4.4
### Patch Changes
- @uncaged/workflow-register@0.4.4
- @uncaged/workflow-runtime@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-register@0.4.3
- @uncaged/workflow-runtime@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-register@0.4.2
- @uncaged/workflow-runtime@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-register@0.4.0
- @uncaged/workflow-runtime@0.4.0
@@ -1,28 +1,33 @@
{
"name": "@uncaged/workflow-template-solve-issue",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-register": "workspace:*",
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-register": "workspace:^",
"@uncaged/workflow-runtime": "workspace:^",
"zod": "^4.0.0"
},
"devDependencies": {
"@uncaged/workflow-cas": "workspace:*",
"@uncaged/workflow-execute": "workspace:*",
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-cas": "workspace:^",
"@uncaged/workflow-execute": "workspace:^",
"@uncaged/workflow-protocol": "workspace:^"
},
"publishConfig": {
"access": "public"
}
}
+45
View File
@@ -0,0 +1,45 @@
# @uncaged/workflow-util-agent
## 0.4.5
### Patch Changes
- @uncaged/workflow-cas@0.4.5
- @uncaged/workflow-runtime@0.4.5
## 0.4.4
### Patch Changes
- @uncaged/workflow-cas@0.4.4
- @uncaged/workflow-runtime@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-cas@0.4.3
- @uncaged/workflow-runtime@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-cas@0.4.2
- @uncaged/workflow-runtime@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-cas@0.4.0
- @uncaged/workflow-runtime@0.4.0
+10 -6
View File
@@ -1,25 +1,29 @@
{
"name": "@uncaged/workflow-util-agent",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"scripts": {
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-cas": "workspace:*",
"@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-cas": "workspace:^",
"zod": "^4.0.0"
},
"publishConfig": {
"access": "public"
}
}
+42
View File
@@ -0,0 +1,42 @@
# @uncaged/workflow-util
## 0.4.5
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.5
## 0.4.4
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.4
## 0.4.3
### Patch Changes
- Include src/ in published packages so bun runtime can resolve the 'bun' exports condition.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.3
## 0.4.2
### Patch Changes
- Fix workspace dependency resolution: use workspace:^ so published packages resolve to compatible versions instead of exact (non-existent) versions.
- Updated dependencies
- @uncaged/workflow-protocol@0.4.2
## 0.4.0
### Minor Changes
- Fix package exports for published packages and adopt changesets for version management.
### Patch Changes
- Updated dependencies
- @uncaged/workflow-protocol@0.4.0
+8 -3
View File
@@ -1,21 +1,26 @@
{
"name": "@uncaged/workflow-util",
"version": "0.3.18",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
"type": "module",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./dist/index.d.ts",
"import": "./src/index.ts"
"import": "./dist/index.js"
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^"
},
"devDependencies": {
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/env bash
# Link / unlink all @uncaged/* packages from the workflow monorepo.
#
# Usage:
# ./scripts/link-all.sh # Register all packages (run from monorepo root)
# ./scripts/link-all.sh --consume # Link all packages into CWD's project
# ./scripts/link-all.sh --unlink # Unregister all packages and restore CWD's deps
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
MONOREPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# Iterate package dirs, calling callback(dir, name) for each
each_pkg() {
local cb="$1"
for dir in "$MONOREPO_ROOT"/packages/*/; do
[[ -f "$dir/package.json" ]] || continue
local name
name=$(grep -m1 '"name"' "$dir/package.json" | sed 's/.*: *"\(.*\)".*/\1/')
"$cb" "$dir" "$name"
done
}
do_register() { printf " register %s\n" "$2"; (cd "$1" && bun link 2>&1) > /dev/null; }
do_consume() { printf " link %s\n" "$2"; (bun link "$2" 2>&1) > /dev/null; }
do_unlink() { printf " unlink %s\n" "$2"; (cd "$1" && bun unlink 2>&1) > /dev/null || true; }
case "${1:-}" in
--consume)
each_pkg do_consume
echo "✅ All @uncaged/* packages linked into $(pwd)"
echo " ⚠️ Do NOT run 'bun install' after this — it will overwrite the links"
echo " To restore: $0 --unlink"
;;
--unlink)
each_pkg do_unlink
if [[ -f "package.json" ]]; then
echo " reinstalling deps..."
bun install 2>&1 > /dev/null || true
fi
echo "✅ All @uncaged/* packages unlinked, deps restored"
;;
*)
each_pkg do_register
echo "✅ All @uncaged/* packages registered"
echo " cd <project> && $0 --consume"
;;
esac
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Validate Crockford Base32 log tags in .log("TAG", ...) calls.
# Crockford Base32 excludes: I, L, O, U
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
BAD=0
while IFS= read -r match; do
file="${match%%:*}"
rest="${match#*:}"
line="${rest%%:*}"
tag=$(echo "$rest" | grep -oP '\.log\(\s*"\K[A-Za-z0-9]+')
if echo "$tag" | grep -qiE '[ILOU]'; then
echo "${file}:${line} tag \"${tag}\" contains invalid Crockford Base32 char (I/L/O/U)"
BAD=1
fi
done < <(grep -rn '\.log("[A-Za-z0-9]\{8\}"' "$ROOT/packages/" --include='*.ts' \
| grep -v node_modules | grep -v '/dist/')
if [ "$BAD" -eq 0 ]; then
echo " ✅ All log tags are valid Crockford Base32"
fi
exit $BAD
-137
View File
@@ -1,137 +0,0 @@
#!/usr/bin/env bash
# Publish all public @uncaged/* packages to Gitea npm registry.
#
# PITFALL: After bumping versions in package.json, bun pm pack still reads the
# old bun.lock and resolves workspace:* to the previous (stale) versions.
# This script deletes bun.lock and runs bun install before packing to force
# correct resolution of workspace:* dependencies.
#
# Usage:
# ./scripts/publish-all.sh # Publish all packages
# ./scripts/publish-all.sh --dry-run # Show what would be published
#
# Package order is auto-resolved via topological sort of workspace:* dependencies.
#
# Prerequisites:
# - .npmrc in monorepo root with Gitea auth token
# - bun (for packing with workspace:* resolution)
# - npm (for publishing tarballs)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
MONOREPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
REGISTRY="https://git.shazhou.work/api/packages/uncaged/npm/"
DRY_RUN=""
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN="--dry-run"
echo "🔍 Dry run mode — no packages will be published"
echo
fi
# Topological sort: read all package.json files, build dependency graph, emit leaf-first order
ORDERED=$(python3 -c "
import json, os, sys
from pathlib import Path
pkgs_dir = Path('$MONOREPO_ROOT/packages')
# name -> dir_name, and dependency edges
name_to_dir = {}
deps_graph = {} # name -> set of @uncaged/* dependency names
for d in sorted(pkgs_dir.iterdir()):
pj = d / 'package.json'
if not pj.exists():
continue
data = json.loads(pj.read_text())
name = data.get('name', '')
if not name.startswith('@uncaged/'):
continue
if data.get('private'):
continue
name_to_dir[name] = d.name
local_deps = set()
for section in ('dependencies', 'devDependencies', 'peerDependencies'):
for dep, ver in data.get(section, {}).items():
if dep.startswith('@uncaged/') and dep in name_to_dir or ver == 'workspace:*':
local_deps.add(dep)
deps_graph[name] = local_deps
# Kahn's algorithm
in_degree = {n: 0 for n in deps_graph}
for n, ds in deps_graph.items():
for d in ds:
if d in in_degree:
in_degree[d] = in_degree.get(d, 0) # ensure exists
# Recount
in_degree = {n: 0 for n in deps_graph}
for n, ds in deps_graph.items():
for d in ds:
if d in in_degree:
in_degree[d] += 1
# Wait, direction is wrong. If A depends on B, B must be published first.
# So edge is: A -> B means B must come before A.
# in_degree[A] = number of deps A has (that are in our set)
in_degree = {n: 0 for n in deps_graph}
for n, ds in deps_graph.items():
for d in ds:
if d in in_degree:
pass # d is a dependency of n
in_degree[n] = len([d for d in ds if d in deps_graph])
queue = [n for n, deg in in_degree.items() if deg == 0]
queue.sort() # stable order
result = []
while queue:
node = queue.pop(0)
result.append(node)
for n, ds in deps_graph.items():
if node in ds:
in_degree[n] -= 1
if in_degree[n] == 0:
queue.append(n)
queue.sort()
for name in result:
print(name_to_dir[name])
")
# Regenerate lockfile so bun pm pack resolves workspace:* to freshly-bumped versions
cd "$MONOREPO_ROOT"
rm -f bun.lock
bun install
ok=0
fail=0
while IFS= read -r pkg; do
dir="$MONOREPO_ROOT/packages/$pkg"
name=$(grep -m1 '"name"' "$dir/package.json" | sed 's/.*: *"\(.*\)".*/\1/')
cd "$dir"
# bun pm pack resolves workspace:* → actual versions
tgz=$(bun pm pack 2>&1 | grep '\.tgz' | grep -v packed | head -1 | tr -d ' ')
if [[ -z "$tgz" || ! -f "$tgz" ]]; then
echo "$name — pack failed"
((fail++)) || true
continue
fi
if npm publish "$tgz" --registry="$REGISTRY" $DRY_RUN 2>&1 | tail -1 | grep -q '+'; then
echo "$name"
((ok++)) || true
else
echo "⚠️ $name (may already exist at this version)"
fi
rm -f "$tgz"
done <<< "$ORDERED"
echo
echo "Published: $ok Skipped/Failed: $fail"
-139
View File
@@ -1,139 +0,0 @@
#!/usr/bin/env bash
# publish.sh — Bump version & publish all @uncaged/workflow-* packages
#
# Usage:
# ./scripts/publish.sh 0.4.0 # explicit version
# ./scripts/publish.sh patch # 0.3.1 → 0.3.2
# ./scripts/publish.sh minor # 0.3.1 → 0.4.0
#
# Env (via `cfg` or export):
# GITEA_TOKEN — Gitea npm registry auth
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO_ROOT"
GITEA_TOKEN="${GITEA_TOKEN:?GITEA_TOKEN is required}"
GITEA_NPM_REGISTRY="https://git.shazhou.work/api/packages/uncaged/npm/"
# ─── Version ─────────────────────────────────────────────────────────────────
current_version() {
node -e "console.log(require('./packages/workflow-protocol/package.json').version)"
}
bump_version() {
local cur="$1" kind="$2"
IFS='.' read -r major minor patch <<< "$cur"
case "$kind" in
patch) echo "${major}.${minor}.$((patch + 1))" ;;
minor) echo "${major}.$((minor + 1)).0" ;;
major) echo "$((major + 1)).0.0" ;;
*) echo "$kind" ;;
esac
}
CURRENT=$(current_version)
VERSION=$(bump_version "$CURRENT" "${1:?Usage: publish.sh <version|patch|minor|major>}")
echo "📦 Publish: $CURRENT$VERSION"
# ─── Topological publish order ───────────────────────────────────────────────
PUBLISH_ORDER=(
workflow-protocol
workflow-util
workflow-cas
workflow-runtime
workflow-reactor
workflow-register
workflow-execute
cli-workflow
workflow-util-agent
workflow-agent-cursor
workflow-agent-hermes
workflow-agent-llm
workflow-template-develop
workflow-template-solve-issue
)
# ─── Bump version ────────────────────────────────────────────────────────────
echo "🔢 Bumping versions..."
for dir in packages/*/; do
pkg="$dir/package.json"
[[ -f "$pkg" ]] || continue
is_private=$(node -e "console.log(require('./$pkg').private || false)")
[[ "$is_private" == "true" ]] && continue
node -e "
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('$pkg','utf8'));
p.version = '$VERSION';
fs.writeFileSync('$pkg', JSON.stringify(p, null, 2) + '\n');
"
done
# ─── Replace workspace:* ─────────────────────────────────────────────────────
echo "🔗 Replacing workspace:* → $VERSION..."
for dir in packages/*/; do
pkg="$dir/package.json"
[[ -f "$pkg" ]] || continue
node -e "
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('$pkg','utf8'));
let c = false;
for (const k of ['dependencies','peerDependencies','devDependencies']) {
if (!p[k]) continue;
for (const [n, v] of Object.entries(p[k])) {
if (n.startsWith('@uncaged/') && v === 'workspace:*') { p[k][n] = '$VERSION'; c = true; }
}
}
if (c) fs.writeFileSync('$pkg', JSON.stringify(p, null, 2) + '\n');
"
done
# ─── Build ───────────────────────────────────────────────────────────────────
echo "🔨 Building..."
npm run build
# ─── Publish ─────────────────────────────────────────────────────────────────
echo "🚀 Publishing..."
cat > "$REPO_ROOT/.npmrc" <<EOF
@uncaged:registry=${GITEA_NPM_REGISTRY}
//${GITEA_NPM_REGISTRY#https://}:_authToken=${GITEA_TOKEN}
EOF
FAIL=0
for pkg_dir in "${PUBLISH_ORDER[@]}"; do
if (cd "packages/$pkg_dir" && npm publish 2>&1); then
echo " ✅ @uncaged/$pkg_dir@$VERSION"
else
echo " ❌ @uncaged/$pkg_dir"
FAIL=1
fi
done
# ─── Restore workspace:* ─────────────────────────────────────────────────────
echo "🔄 Restoring workspace:*..."
for dir in packages/*/; do
pkg="$dir/package.json"
[[ -f "$pkg" ]] || continue
node -e "
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('$pkg','utf8'));
let c = false;
for (const k of ['dependencies','peerDependencies','devDependencies']) {
if (!p[k]) continue;
for (const [n, v] of Object.entries(p[k])) {
if (n.startsWith('@uncaged/') && v === '$VERSION') { p[k][n] = 'workspace:*'; c = true; }
}
}
if (c) fs.writeFileSync('$pkg', JSON.stringify(p, null, 2) + '\n');
"
done
# ─── Commit ──────────────────────────────────────────────────────────────────
echo "📝 Committing..."
git add -A
git commit -m "chore: publish v${VERSION}
小橘 <xiaoju@shazhou.work>"
git push
[[ "$FAIL" -eq 0 ]] && echo "✅ v${VERSION} published" || echo "⚠️ v${VERSION} published with errors"