Compare commits

...

9 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
47 changed files with 814 additions and 307 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
]
],
"linked": [],
"access": "restricted",
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
+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>`
+2 -7
View File
@@ -6,18 +6,13 @@
],
"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.sh patch",
"publish:gitea:dry": "./scripts/publish.sh --dry-run patch",
"changeset": "bunx changeset",
"version": "bunx changeset version",
"release": "bunx changeset publish --no-git-tag"
"release": "bun run build && bun test && npx changeset publish --no-git-tag"
},
"devDependencies": {
"@biomejs/biome": "^2.4.14",
+54
View File
@@ -1,5 +1,59 @@
# @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
+11 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@uncaged/cli-workflow",
"version": "0.4.0",
"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) => {
@@ -1,5 +1,51 @@
# @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
+10 -6
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-agent-cursor",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -11,11 +12,11 @@
"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": {
@@ -24,5 +25,8 @@
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
@@ -1,5 +1,37 @@
# @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
+7 -3
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-agent-hermes",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -11,8 +12,8 @@
"test": "bun test"
},
"dependencies": {
"@uncaged/workflow-runtime": "workspace:*",
"@uncaged/workflow-util-agent": "workspace:*"
"@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^"
},
"exports": {
".": {
@@ -20,5 +21,8 @@
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
+32
View File
@@ -1,5 +1,37 @@
# @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
+7 -3
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-agent-llm",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -11,8 +12,8 @@
"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"
@@ -23,5 +24,8 @@
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
@@ -1,5 +1,43 @@
# @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
+8 -4
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-agent-react",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -18,14 +19,17 @@
"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"
}
}
+34
View File
@@ -1,5 +1,39 @@
# @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
+7 -3
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-cas",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -17,12 +18,15 @@
}
},
"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]);
}
+50
View File
@@ -1,5 +1,55 @@
# @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
+11 -7
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-execute",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -17,12 +18,12 @@
"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": {
@@ -30,5 +31,8 @@
},
"devDependencies": {
"zod": "^4.0.0"
},
"publishConfig": {
"access": "public"
}
}
+16
View File
@@ -1,5 +1,21 @@
# @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
+5 -1
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-gateway",
"version": "0.4.0",
"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"
}
}
+24
View File
@@ -1,5 +1,29 @@
# @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
+5 -1
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-protocol",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -24,5 +25,8 @@
"devDependencies": {
"zod": "^4.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+30
View File
@@ -1,5 +1,35 @@
# @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
+6 -2
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-reactor",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -14,7 +15,7 @@
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^"
},
"peerDependencies": {
"zod": "^4.0.0"
@@ -22,5 +23,8 @@
"devDependencies": {
"zod": "^4.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+34
View File
@@ -1,5 +1,39 @@
# @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
+7 -3
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-register",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -14,8 +15,8 @@
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*",
"@uncaged/workflow-util": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^",
"@uncaged/workflow-util": "workspace:^"
},
"peerDependencies": {
"acorn": "^8.0.0",
@@ -27,5 +28,8 @@
"yaml": "^2.7.1",
"zod": "^4.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+34
View File
@@ -1,5 +1,39 @@
# @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
+7 -3
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-runtime",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -11,8 +12,8 @@
"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"
@@ -26,5 +27,8 @@
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
}
}
@@ -1,5 +1,37 @@
# @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
@@ -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,7 +1,8 @@
{
"name": "@uncaged/workflow-template-develop",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -17,11 +18,14 @@
"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.",
@@ -1,5 +1,37 @@
# @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
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-template-solve-issue",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -17,13 +18,16 @@
"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"
}
}
+32
View File
@@ -1,5 +1,37 @@
# @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
+7 -3
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-util-agent",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -18,8 +19,11 @@
"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"
}
}
+30
View File
@@ -1,5 +1,35 @@
# @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
+6 -2
View File
@@ -1,7 +1,8 @@
{
"name": "@uncaged/workflow-util",
"version": "0.4.0",
"version": "0.4.5",
"files": [
"src",
"dist",
"package.json"
],
@@ -14,9 +15,12 @@
}
},
"dependencies": {
"@uncaged/workflow-protocol": "workspace:*"
"@uncaged/workflow-protocol": "workspace:^"
},
"devDependencies": {
"typescript": "^5.8.3"
},
"publishConfig": {
"access": "public"
}
}
+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
-165
View File
@@ -1,165 +0,0 @@
#!/usr/bin/env bash
# publish.sh — Bump version, build, test, topologically publish @uncaged/* to Gitea npm
#
# 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
# ./scripts/publish.sh major # 0.3.1 → 1.0.0
# ./scripts/publish.sh --dry-run patch # dry-run bun publish only (no git commit/push)
#
# Env (via `cfg` or export):
# GITEA_TOKEN — Gitea npm registry auth (see root .npmrc)
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO_ROOT"
GITEA_TOKEN="${GITEA_TOKEN:?GITEA_TOKEN is required}"
REGISTRY="https://git.shazhou.work/api/packages/uncaged/npm/"
DRY_RUN=""
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN="--dry-run"
shift
echo "🔍 Dry run — bun publish will not upload; git commit/push skipped"
echo
fi
# ─── 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 [--dry-run] <version|patch|minor|major>}")
echo "📦 Publish: $CURRENT$VERSION"
# ─── 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
# ─── Topological publish order (workspace:* deps first) ───────────────────────
ORDERED=$(python3 -c "
import json, sys
from pathlib import Path
pkgs_dir = Path('$REPO_ROOT/packages')
name_to_dir = {}
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/') or data.get('private'):
continue
name_to_dir[name] = d.name
deps_graph = {}
for name, dirname in name_to_dir.items():
pj = pkgs_dir / dirname / 'package.json'
data = json.loads(pj.read_text())
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 and ver.startswith('workspace:'):
local_deps.add(dep)
deps_graph[name] = local_deps
in_degree = {n: 0 for n in deps_graph}
for n, ds in deps_graph.items():
in_degree[n] = len(ds)
queue = sorted([n for n, deg in in_degree.items() if deg == 0])
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()
if len(result) != len(deps_graph):
missing = set(deps_graph) - set(result)
sys.stderr.write('publish: cyclic @uncaged/ workspace:* dependencies among: ' + ', '.join(sorted(missing)) + '\n')
sys.exit(1)
for name in result:
print(name_to_dir[name])
")
# ─── Build ────────────────────────────────────────────────────────────────────
echo "🔨 Building..."
bun run build
# ─── Self-test ────────────────────────────────────────────────────────────────
echo "🧪 Running tests..."
if ! bun test; then
echo "❌ Tests failed — aborting publish"
exit 1
fi
# ─── Publish (bun resolves workspace:* for publish) ──────────────────────────
echo "🚀 Publishing to $REGISTRY ..."
ok=0
fail=0
while IFS= read -r pkg; do
[[ -n "$pkg" ]] || continue
dir="$REPO_ROOT/packages/$pkg"
name=$(node -e "console.log(require('$dir/package.json').name)")
if ( cd "$dir" && bun publish --registry="$REGISTRY" ${DRY_RUN:+"$DRY_RUN"} ); then
echo "$name"
ok=$((ok + 1))
else
echo "⚠️ $name (publish failed or version may already exist)"
fail=$((fail + 1))
fi
done <<< "$ORDERED"
echo
echo "Published: $ok Skipped/Failed: $fail"
# ─── Commit ───────────────────────────────────────────────────────────────────
if [[ -n "$DRY_RUN" ]]; then
echo "⏭️ Skipping git commit/push (dry run). Revert bumps with: git checkout -- packages/*/package.json"
exit 0
fi
echo "📝 Committing..."
git add -A
git commit -m "chore: publish v${VERSION}
小橘 <xiaoju@shazhou.work>"
git push
echo "✅ v${VERSION} published"