@fieldwangai/agentflow 0.1.134 → 0.1.136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,8 @@
15
15
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0"
16
16
  rel="stylesheet"
17
17
  />
18
- <script type="module" crossorigin src="/assets/index-CqXKONpd.js"></script>
19
- <link rel="stylesheet" crossorigin href="/assets/index-QDDFbZ_T.css">
18
+ <script type="module" crossorigin src="/assets/index-HdswcJWY.js"></script>
19
+ <link rel="stylesheet" crossorigin href="/assets/index-KIGufzQf.css">
20
20
  </head>
21
21
  <body>
22
22
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fieldwangai/agentflow",
3
- "version": "0.1.134",
3
+ "version": "0.1.136",
4
4
  "description": "Orchestration system for long-running complex agent tasks using Cursor, OpenCode, Claude Code, or Codex as execution backends",
5
5
  "type": "module",
6
6
  "main": "bin/agentflow.mjs",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agentflow-cli
3
- description: Direct AgentFlow platform operation through a bundled token-backed CLI, without MCP. Use when Codex needs to list AgentFlow workspaces or flows, start or inspect runs, fetch display outputs, or read and report Workflow actions, artifacts, and global state through AgentFlow HTTP APIs using AGENTFLOW_TOKEN from env or .env. Default AgentFlow base URL is http://ai.mengma.bigo.inner/.
3
+ description: Direct AgentFlow platform operation through a bundled token-backed CLI, without MCP. Use when Codex needs to list AgentFlow workspaces or flows, start or inspect runs, read graphs and logs, or fetch display outputs through AgentFlow HTTP APIs using AGENTFLOW_TOKEN from env or .env. Default AgentFlow base URL is http://ai.mengma.bigo.inner/.
4
4
  ---
5
5
 
6
6
  # AgentFlow CLI
@@ -118,72 +118,9 @@ Extract display outputs from a flow:
118
118
  node skills/agentflow-cli/scripts/agentflow-cli.mjs display-outputs --flow-id TestNodes --flow-source user
119
119
  ```
120
120
 
121
- Read the current materialized Workflow before making an incremental update:
121
+ ## Workflow reporting
122
122
 
123
- ```bash
124
- node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-get \
125
- --workflow tapd:1015046 \
126
- --runtime-only
127
- ```
128
-
129
- Report an action, its artifacts, and/or a global-state patch:
130
-
131
- ```bash
132
- node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-report \
133
- --workflow tapd:1015046 \
134
- --file workflow-report.json \
135
- --expected-revision 'runtime:replace-with-current-revision' \
136
- --idempotency-key 'implementation-finished:android:issue-2:v1'
137
- ```
138
-
139
- `workflow-report.json` uses one general model. Include at least one of `action`, `artifacts`, or `globalState`:
140
-
141
- ```json
142
- {
143
- "action": {
144
- "key": "implementation-finished",
145
- "title": "实现完成",
146
- "detail": "Remote Config 拉取频控已实现",
147
- "status": "done",
148
- "group": "development",
149
- "scope": "firebase-remote-config-fetch-control-android",
150
- "platform": "android",
151
- "issueKey": "issue-2",
152
- "tags": ["remote-config"]
153
- },
154
- "artifacts": [
155
- {
156
- "key": "implementation-mr",
157
- "type": "gitlab-mr",
158
- "title": "Android 实现 MR",
159
- "url": "https://git.example.test/group/project/-/merge_requests/123",
160
- "scope": "action",
161
- "status": "ready"
162
- }
163
- ],
164
- "globalState": {
165
- "mode": "merge",
166
- "patch": {
167
- "status": { "label": "开发中" },
168
- "sections": {
169
- "android": {
170
- "title": "Android",
171
- "fields": {
172
- "owner": { "label": "负责人", "type": "user", "value": "alice" },
173
- "tags": { "label": "Tag", "type": "chips", "value": ["remote-config"] },
174
- "rules": { "label": "实现规则", "type": "list", "value": ["仅允许国家注册 listener"] }
175
- }
176
- }
177
- }
178
- },
179
- "remove": []
180
- }
181
- }
182
- ```
183
-
184
- Artifact `scope` is `action` or `global`. Action-scoped artifacts appear with the timeline action; global artifacts appear in the related-artifacts area. Use stable `key` values so later reports update an existing item instead of duplicating it.
185
-
186
- Supported global-state field types are `text`, `user`, `chips`, `list`, and `link`. The model does not require Android/iOS sections; section and field keys are application-defined.
123
+ The reusable transport lives in `scripts/workflow-report-client.mjs`. The CLI exposes it through `workflow-get`, `workflow-report`, and `workflow-artifact-publish`; their state model, extension contract, concurrency rules, and AI procedure belong to the separate [`agentflow-workflow-report`](../agentflow-workflow-report/SKILL.md) skill. Use that skill whenever reading or mutating Workflow state; do not reconstruct the protocol from this general CLI guide.
187
124
 
188
125
  ## Workflow
189
126
 
@@ -191,14 +128,10 @@ Supported global-state field types are `text`, `user`, `chips`, `list`, and `lin
191
128
  2. Use `list-workspace` or `list-flows` to discover targets.
192
129
  3. Use `run` to start the flow. If the task needs the generated page/text, inspect returned `displayOutputs` or call `display-outputs`.
193
130
  4. Use `status`, `list-run-by-workspace`, and `logs` when a run is active, failed, or needs debugging.
194
- 5. Before changing Workflow global state, call `workflow-get` and retain `snapshot.runtimeRevision`.
195
- 6. Merge the intended semantic change into the current state; do not replace unrelated fields.
196
- 7. Call `workflow-report` with `--expected-revision` and a stable `--idempotency-key`. If the API returns a revision conflict, fetch again, re-apply the intended patch, and retry once with a new revision.
197
131
 
198
132
  ## Failure Handling
199
133
 
200
134
  - If the CLI says the token is missing, ask the user to set `AGENTFLOW_TOKEN` in env or `.env`.
201
135
  - If the API returns 401/403, do not retry with a printed token. Ask the user to refresh the token.
202
136
  - If `run` fails because a flow is already running, call `status` and `list-run-by-workspace` before retrying.
203
- - If `workflow-report` returns a revision conflict, do not blindly overwrite remote state. Read the returned snapshot or call `workflow-get`, merge the intended fields, and retry with its revision.
204
137
  - If local debugging is needed, override `AGENTFLOW_BASE_URL`; otherwise keep the default internal URL.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "AgentFlow CLI"
3
- short_description: "Run flows and report Workflow state through AgentFlow APIs"
4
- default_prompt: "Use $agentflow-cli to operate AgentFlow and report Workflow actions, artifacts, or global state with the bundled token-backed CLI."
3
+ short_description: "Operate AgentFlow workspaces, flows, runs, graphs, and logs"
4
+ default_prompt: "Use $agentflow-cli to inspect or operate AgentFlow with the bundled token-backed CLI."
@@ -2,6 +2,7 @@
2
2
  import fs from "node:fs";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
+ import { createWorkflowReportClient } from "./workflow-report-client.mjs";
5
6
 
6
7
  const DEFAULT_BASE_URL = "http://ai.mengma.bigo.inner/";
7
8
  const DISPLAY_DEFINITION_KINDS = new Map([
@@ -42,6 +43,7 @@ Commands:
42
43
  sync-workspace --workspace <id>
43
44
  workflow-get --workflow tapd:<id> [--flow-id <id>] [--runtime-only]
44
45
  workflow-report --workflow tapd:<id> --file <report.json> [--expected-revision <revision>]
46
+ workflow-artifact-publish --workflow tapd:<id> --file <artifact.json>
45
47
  `;
46
48
  }
47
49
 
@@ -387,12 +389,13 @@ async function main() {
387
389
  const flowId = option(args, "flow-id") || option(args, "flow");
388
390
  const flowSource = option(args, "flow-source") || "user";
389
391
  const runtimeOnly = args["runtime-only"] === true || args.cached === true ? "1" : "";
390
- printJson(await httpJson(args, `/api/workflows/state${query({
392
+ const client = createWorkflowReportClient({ baseUrl: normalizedBaseUrl(args), token: authToken(args) });
393
+ printJson(await client.getState({
391
394
  workflow: workflow.key,
392
395
  flowId,
393
396
  flowSource,
394
- runtimeOnly,
395
- })}`));
397
+ runtimeOnly: runtimeOnly === "1",
398
+ }));
396
399
  return;
397
400
  }
398
401
 
@@ -411,7 +414,24 @@ async function main() {
411
414
  if (idempotencyKey) body.idempotencyKey = idempotencyKey;
412
415
  if (flowId) body.flowId = flowId;
413
416
  if (flowSource) body.flowSource = flowSource;
414
- printJson(await httpJson(args, "/api/workflows/report", { method: "POST", body }));
417
+ const client = createWorkflowReportClient({ baseUrl: normalizedBaseUrl(args), token: authToken(args) });
418
+ printJson(await client.report(body));
419
+ return;
420
+ }
421
+
422
+ if (command === "workflow-artifact-publish") {
423
+ const body = readJsonFile(option(args, "file"));
424
+ const workflow = workflowReferenceFromArgs(args, false) || parseWorkflowReference(body?.workflow?.key || "");
425
+ if (!workflow && !(body?.workflow?.namespace && body?.workflow?.id)) {
426
+ throw new Error("Missing workflow reference. Pass --workflow namespace:id or include workflow.namespace and workflow.id in the JSON file.");
427
+ }
428
+ if (workflow) body.workflow = workflow;
429
+ const flowId = option(args, "flow-id") || option(args, "flow");
430
+ const flowSource = option(args, "flow-source");
431
+ if (flowId) body.flowId = flowId;
432
+ if (flowSource) body.flowSource = flowSource;
433
+ const client = createWorkflowReportClient({ baseUrl: normalizedBaseUrl(args), token: authToken(args) });
434
+ printJson(await client.publishArtifact(body));
415
435
  return;
416
436
  }
417
437
 
@@ -0,0 +1,68 @@
1
+ function cleanBaseUrl(value) {
2
+ return String(value || "").trim().replace(/\/+$/, "");
3
+ }
4
+
5
+ function workflowQuery(params = {}) {
6
+ const search = new URLSearchParams();
7
+ for (const [key, value] of Object.entries(params)) {
8
+ if (value === undefined || value === null || value === "") continue;
9
+ search.set(key, String(value));
10
+ }
11
+ const text = search.toString();
12
+ return text ? `?${text}` : "";
13
+ }
14
+
15
+ export function createWorkflowReportClient({ baseUrl, token, fetchImpl = globalThis.fetch } = {}) {
16
+ const origin = cleanBaseUrl(baseUrl);
17
+ const credential = String(token || "").trim();
18
+ if (!origin) throw new Error("Workflow Report client requires baseUrl");
19
+ if (!credential) throw new Error("Workflow Report client requires token");
20
+ if (typeof fetchImpl !== "function") throw new Error("Workflow Report client requires fetch");
21
+
22
+ const request = async (pathname, { method = "GET", body } = {}) => {
23
+ const url = new URL(pathname, `${origin}/`);
24
+ const headers = {
25
+ Accept: "application/json",
26
+ Authorization: `Bearer ${credential}`,
27
+ Cookie: `af_session=${encodeURIComponent(credential)}`,
28
+ };
29
+ if (body !== undefined) headers["Content-Type"] = "application/json";
30
+ const response = await fetchImpl(url, {
31
+ method,
32
+ headers,
33
+ body: body === undefined ? undefined : JSON.stringify(body),
34
+ });
35
+ const text = await response.text();
36
+ let data = null;
37
+ try {
38
+ data = text ? JSON.parse(text) : null;
39
+ } catch {
40
+ data = { text };
41
+ }
42
+ if (!response.ok) {
43
+ const message = data?.error || data?.message || text || `HTTP ${response.status}`;
44
+ const error = new Error(`${method} ${url.pathname} failed: ${message}`);
45
+ error.status = response.status;
46
+ error.data = data;
47
+ throw error;
48
+ }
49
+ return data;
50
+ };
51
+
52
+ return {
53
+ getState({ workflow, flowId = "", flowSource = "user", runtimeOnly = false } = {}) {
54
+ return request(`/api/workflows/state${workflowQuery({
55
+ workflow,
56
+ flowId,
57
+ flowSource,
58
+ runtimeOnly: runtimeOnly ? "1" : "",
59
+ })}`);
60
+ },
61
+ report(body = {}) {
62
+ return request("/api/workflows/report", { method: "POST", body });
63
+ },
64
+ publishArtifact(body = {}) {
65
+ return request("/api/workflow-artifacts/publish", { method: "POST", body });
66
+ },
67
+ };
68
+ }
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: agentflow-workflow-report
3
+ description: Safely read, merge, and report AgentFlow Workflow actions, artifacts, producer-owned global state, and generic timeline projections through the AgentFlow CLI and HTTP protocol. Use when an AI agent or producer such as prd-flow needs to integrate Workflow reporting, publish progress or evidence, update globalState, assign version/sprint/milestone timeline membership, clear projections, or resolve revision and idempotency conflicts.
4
+ ---
5
+
6
+ # AgentFlow Workflow Report
7
+
8
+ Treat Workflow reporting as one canonical producer-adapter protocol. The producer reports facts through `POST /api/workflows/report`; AgentFlow alone materializes and returns `snapshot`. Do not introduce producer-specific write endpoints for new integrations.
9
+
10
+ ## Prerequisites
11
+
12
+ Use the Workflow Report client bundled with the sibling `agentflow-cli` skill. The CLI is its command-line wrapper for AI, scripts, and local verification:
13
+
14
+ ```bash
15
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs <command> [options]
16
+ ```
17
+
18
+ If the script is unavailable, install `agentflow-cli` beside this skill. Require `AGENTFLOW_TOKEN` or `AGENTFLOW_SESSION_TOKEN`; never print either token. Use `AGENTFLOW_BASE_URL` only when overriding the default service.
19
+
20
+ Read [references/protocol.md](references/protocol.md) completely before implementing a producer, changing the report contract, constructing a payload, or answering questions about parameters, permissions, merge behavior, custom panels, and visible UI results.
21
+
22
+ ## Required sequence
23
+
24
+ 1. Resolve a canonical Workflow reference such as `tapd:1015046`. The report schema is producer-generic, but the current AgentFlow identity adapter accepts only the `tapd` namespace. Do not claim that arbitrary Workflow namespaces already work.
25
+ 2. Read the current materialized state and retain `snapshot.runtimeRevision`:
26
+
27
+ ```bash
28
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-get \
29
+ --workflow tapd:1015046 \
30
+ --runtime-only
31
+ ```
32
+
33
+ 3. Compute only the intended semantic update. Choose one stable lowercase `source` for the business adapter (for example `prd-flow` or `release-bot`). `agentflow-cli` is only transport and must not replace the real producer identity.
34
+ 4. Preserve unrelated `globalState` fields. Never infer or rewrite a producer's private schema.
35
+ 5. When timeline membership changes, derive the complete current `projections.timeline` array from producer state. Use `[]` to clear it.
36
+ 6. Write the payload to a JSON file and report it with the retained revision and a stable operation key:
37
+
38
+ ```bash
39
+ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-report \
40
+ --workflow tapd:1015046 \
41
+ --file workflow-report.json \
42
+ --expected-revision 'runtime:current-revision' \
43
+ --idempotency-key 'implementation-finished:android:issue-2:v1'
44
+ ```
45
+
46
+ 7. On HTTP 409, fetch the latest state, reapply the intended semantic update, and retry once with the new revision. Never send a client field named `snapshot`; use `observation.state` for a complete producer observation and treat returned `snapshot` as server output.
47
+
48
+ ## Report selection
49
+
50
+ Include at least one capability:
51
+
52
+ - `observation`: report the producer's complete current observation when it computes a deterministic workflow view.
53
+ - `action`: report a stable progress or lifecycle event.
54
+ - `artifacts`: attach evidence; use stable artifact keys.
55
+ - `globalState`: merge producer-owned durable state or remove explicit paths.
56
+ - `projections`: replace generic derived indexes used by AgentFlow dashboards.
57
+ - `extensions`: report namespaced data for a registered specialized renderer, such as `extensions["prd-flow"].issues`.
58
+
59
+ Map data to the visible page deliberately:
60
+
61
+ - Global area: `observation.state`, incremental producer facts in `globalState`, and iteration membership in `projections.timeline`.
62
+ - Action timeline: stable `action.key` plus Action-scoped `artifacts`.
63
+ - Generic custom cards: use `globalState.sections` with built-in `text`, `user`, `chips`, `list`, and `link` field renderers.
64
+ - Specialized custom area: use namespaced `extensions` only when built-in renderers cannot express the layout. Saving an extension does not create a UI by itself; currently only `extensions["prd-flow"]` has a registered AI Docs / Issues renderer.
65
+
66
+ Use projection-only reports when the producer state is already current and only dashboard membership needs synchronization.
67
+
68
+ For local Markdown or other content that must become a browser URL, publish it first with `workflow-artifact-publish` (`POST /api/workflow-artifacts/publish`), then use the returned Artifact in the same Workflow. Do not use `/api/prd-workflow/review-link` for new integrations.
69
+
70
+ ## Non-negotiable rules
71
+
72
+ - Keep `schemaVersion` at `1` unless the server advertises another version.
73
+ - Keep the runtime chain singular: producer adapter → Workflow Report client → AgentFlow. The Skill is guidance, not a transport hop.
74
+ - Give every action a stable `key`.
75
+ - Send a stable lowercase `source` on every report and Markdown publish. Action, idempotency, and Artifact identities are isolated by `source + key`; `globalState` and the complete timeline remain shared read-merge-write regions.
76
+ - Give every timeline entry stable `kind` and `id` values.
77
+ - Treat `dimensions` as opaque facets; do not hardcode Android, iOS, version, or prd-flow fields into AgentFlow state.
78
+ - Treat `globalState` as the source of truth owned by the producer; treat projections as replaceable derived views.
79
+ - Send the complete current timeline array whenever changing it. Omitting `projections` means no projection change.
80
+ - Use `expectedRevision` for state or projection changes and a stable `idempotencyKey` for every logical operation.
81
+ - Do not include credentials, tokens, cookies, or private environment values in actions, artifacts, state, projections, or logs.
82
+
83
+ ## Permissions and overwrite semantics
84
+
85
+ - Treat the first authenticated reporter as owner when the Workflow has no collaboration record.
86
+ - Allow owner and explicit editor writes. Treat explicit viewer, same-team viewer, share-link viewer, and admin review as read-only.
87
+ - `observation.state` replaces the complete previous observation for the same `clientId`.
88
+ - `globalState.patch` recursively merges objects; arrays and scalars replace; `null` and `remove` delete explicit paths.
89
+ - Reusing an `action.key` updates the same semantic stage. Do not create a new key for refreshes or retries.
90
+ - `projections.timeline` replaces the complete array. Read first and preserve entries outside the producer's ownership.
91
+ - `extensions` recursively merge within valid namespaces; arrays and scalars replace, and `null` deletes producer-owned fields.
92
+ - Publishing Markdown creates or updates a preview Artifact and review copy; it does not confirm a document or advance an Action.
93
+
94
+ ## Failure handling
95
+
96
+ - Missing token: stop and ask the user to configure `AGENTFLOW_TOKEN`.
97
+ - HTTP 401/403: stop; do not retry with a token printed in a command or answer.
98
+ - HTTP 409: follow the single read-merge-retry sequence.
99
+ - HTTP 400: fix the payload against the protocol reference; do not weaken validation.
100
+ - Replayed idempotency key from the same `source`: accept `alreadyApplied: true` as success. Markdown publish returns the previously created preview instead of creating another copy.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "AgentFlow Workflow Report"
3
+ short_description: "Read and report Workflow state safely with a stable protocol"
4
+ default_prompt: "Use $agentflow-workflow-report to read the current Workflow, merge the intended update, and report it with revision and idempotency safeguards."