@fieldwangai/agentflow 0.1.135 → 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-CmpbCHAj.js"></script>
19
- <link rel="stylesheet" crossorigin href="/assets/index-BFQVTav-.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.135",
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",
@@ -120,7 +120,7 @@ node skills/agentflow-cli/scripts/agentflow-cli.mjs display-outputs --flow-id Te
120
120
 
121
121
  ## Workflow reporting
122
122
 
123
- The CLI implements `workflow-get` and `workflow-report`, but their state model, projection 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.
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.
124
124
 
125
125
  ## Workflow
126
126
 
@@ -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
+ }
@@ -5,11 +5,11 @@ description: Safely read, merge, and report AgentFlow Workflow actions, artifact
5
5
 
6
6
  # AgentFlow Workflow Report
7
7
 
8
- Treat Workflow reporting as a read-modify-report protocol. Keep producer business state opaque to AgentFlow and publish only generic dashboard indexes through projections.
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
9
 
10
10
  ## Prerequisites
11
11
 
12
- Use the CLI bundled with the sibling `agentflow-cli` skill:
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
13
 
14
14
  ```bash
15
15
  node skills/agentflow-cli/scripts/agentflow-cli.mjs <command> [options]
@@ -17,11 +17,11 @@ node skills/agentflow-cli/scripts/agentflow-cli.mjs <command> [options]
17
17
 
18
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
19
 
20
- Read [references/protocol.md](references/protocol.md) completely before implementing a producer, changing the report contract, or constructing a payload beyond the quick pattern below.
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
21
 
22
22
  ## Required sequence
23
23
 
24
- 1. Resolve a canonical Workflow reference such as `tapd:1015046`.
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
25
  2. Read the current materialized state and retain `snapshot.runtimeRevision`:
26
26
 
27
27
  ```bash
@@ -30,7 +30,7 @@ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-get \
30
30
  --runtime-only
31
31
  ```
32
32
 
33
- 3. Compute only the intended semantic update.
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
34
  4. Preserve unrelated `globalState` fields. Never infer or rewrite a producer's private schema.
35
35
  5. When timeline membership changes, derive the complete current `projections.timeline` array from producer state. Use `[]` to clear it.
36
36
  6. Write the payload to a JSON file and report it with the retained revision and a stable operation key:
@@ -43,23 +43,36 @@ node skills/agentflow-cli/scripts/agentflow-cli.mjs workflow-report \
43
43
  --idempotency-key 'implementation-finished:android:issue-2:v1'
44
44
  ```
45
45
 
46
- 7. On HTTP 409, fetch the latest state, reapply the intended semantic update, and retry once with the new revision. Never resend a stale full snapshot.
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
47
 
48
48
  ## Report selection
49
49
 
50
50
  Include at least one capability:
51
51
 
52
+ - `observation`: report the producer's complete current observation when it computes a deterministic workflow view.
52
53
  - `action`: report a stable progress or lifecycle event.
53
54
  - `artifacts`: attach evidence; use stable artifact keys.
54
55
  - `globalState`: merge producer-owned durable state or remove explicit paths.
55
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.
56
65
 
57
66
  Use projection-only reports when the producer state is already current and only dashboard membership needs synchronization.
58
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
+
59
70
  ## Non-negotiable rules
60
71
 
61
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.
62
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.
63
76
  - Give every timeline entry stable `kind` and `id` values.
64
77
  - Treat `dimensions` as opaque facets; do not hardcode Android, iOS, version, or prd-flow fields into AgentFlow state.
65
78
  - Treat `globalState` as the source of truth owned by the producer; treat projections as replaceable derived views.
@@ -67,11 +80,21 @@ Use projection-only reports when the producer state is already current and only
67
80
  - Use `expectedRevision` for state or projection changes and a stable `idempotencyKey` for every logical operation.
68
81
  - Do not include credentials, tokens, cookies, or private environment values in actions, artifacts, state, projections, or logs.
69
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
+
70
94
  ## Failure handling
71
95
 
72
96
  - Missing token: stop and ask the user to configure `AGENTFLOW_TOKEN`.
73
97
  - HTTP 401/403: stop; do not retry with a token printed in a command or answer.
74
98
  - HTTP 409: follow the single read-merge-retry sequence.
75
99
  - HTTP 400: fix the payload against the protocol reference; do not weaken validation.
76
- - Replayed idempotency key: accept `alreadyApplied: true` as success.
77
-
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.