@nanobpm/nano-workforce 0.75.0 → 0.77.0

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [0.77.0](https://github.com/nanobpm/nano-workforce/compare/v0.76.0...v0.77.0) (2026-08-17)
2
+
3
+
4
+ ### Features
5
+
6
+ * bind the app to all interfaces so a remote worker fleet can reach it ([#224](https://github.com/nanobpm/nano-workforce/issues/224)) ([#255](https://github.com/nanobpm/nano-workforce/issues/255)) ([5968717](https://github.com/nanobpm/nano-workforce/commit/5968717416e13ff739b797822eb0d44ff51cc9cb)), closes [12778/#828](https://github.com/nanobpm/nano-workforce/issues/828) [12801/#252](https://github.com/nanobpm/nano-workforce/issues/252) [#228](https://github.com/nanobpm/nano-workforce/issues/228)
7
+
8
+ # [0.76.0](https://github.com/nanobpm/nano-workforce/compare/v0.75.0...v0.76.0) (2026-08-17)
9
+
10
+
11
+ ### Features
12
+
13
+ * **ui:** adopt urban 0.52.0 dataGrid subtitle/width/truncate on identity grids ([#250](https://github.com/nanobpm/nano-workforce/issues/250)) ([abcae46](https://github.com/nanobpm/nano-workforce/commit/abcae4678e9b2a481372df3a42bc0ddedaa671b3)), closes [#260](https://github.com/nanobpm/nano-workforce/issues/260) [#259](https://github.com/nanobpm/nano-workforce/issues/259) [owner/repo#N](https://github.com/owner/repo/issues/N) [#248](https://github.com/nanobpm/nano-workforce/issues/248) [#249](https://github.com/nanobpm/nano-workforce/issues/249) [#259](https://github.com/nanobpm/nano-workforce/issues/259)
14
+
1
15
  # [0.75.0](https://github.com/nanobpm/nano-workforce/compare/v0.74.0...v0.75.0) (2026-08-17)
2
16
 
3
17
 
@@ -0,0 +1,22 @@
1
+ // Guard for the app's network posture (nano.app.json). nano-workforce drives a distributed LAN
2
+ // worker fleet: remote `senior:*` agents must reach the capability hooks (`/app/api/hooks/abandon`,
3
+ // `/app/api/hooks/blackboard`) over the app's hostname. Urban's runtime bind default is loopback
4
+ // (secure by default), which silently makes those hooks unreachable off-box — the failure mode
5
+ // behind the wedged review agents (jwulf/c8ctl-plugin-nano#76, issue #224): an agent parked on a
6
+ // wait-answer escalation it could not resolve because the abandon endpoint refused hostname
7
+ // connections. The manifest must therefore declare `network.bind: "all"` so nwf is reachable by
8
+ // its fleet out of the box. The LOCAL agentic-channel token is loopback-guarded independently
9
+ // (#228) so binding wide does not expose it.
10
+ import { test } from "node:test";
11
+ import { assert, assertEquals } from "#test-assert";
12
+ import { readFileSync } from "node:fs";
13
+
14
+ test("nano.app.json binds to all interfaces so a remote worker fleet can reach the capability hooks", () => {
15
+ const manifest = JSON.parse(readFileSync(new URL("../nano.app.json", import.meta.url), "utf8"));
16
+ assert(manifest.network, "nano.app.json must declare a network block (fleet reachability)");
17
+ assertEquals(
18
+ manifest.network.bind,
19
+ "all",
20
+ "network.bind must be \"all\": loopback silently makes the capability hooks unreachable off-box for the distributed fleet",
21
+ );
22
+ });
package/nano.app.json CHANGED
@@ -4,6 +4,7 @@
4
4
  "id": "nano-workforce",
5
5
  "name": "Nano Workforce",
6
6
  "codename": "nano-workforce",
7
+ "network": { "bind": "all" },
7
8
  "data": {
8
9
  "default": "app",
9
10
  "sources": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanobpm/nano-workforce",
3
- "version": "0.75.0",
3
+ "version": "0.77.0",
4
4
  "description": "Nano Workforce — an Agent Graph Orchestration application for Agentic SDLC: durable BPMN processes that coordinate a graph of AI agents across the software delivery lifecycle.",
5
5
  "type": "module",
6
6
  "main": "main.ts",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@nanobpm/agentic": "^0.1.0",
56
- "@nanobpm/urban": "^0.50.0"
56
+ "@nanobpm/urban": "^0.52.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@biomejs/biome": "^2.4.11",
@@ -55,12 +55,12 @@
55
55
  "filter": [{ "field": "plan_key", "eqParam": true }]
56
56
  },
57
57
  "columns": [
58
- { "field": "title", "template": "{{title}}", "header": "Item", "linkField": "issue_url" },
58
+ { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "plan_key", "truncate": true, "width": "34%", "linkField": "issue_url" },
59
59
  { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
60
60
  { "field": "delivery", "header": "Delivery" },
61
61
  { "field": "wave_label", "header": "Wave" },
62
62
  { "field": "task_count", "header": "Tasks" },
63
- { "field": "updated_at", "header": "Updated" }
63
+ { "field": "updated_at", "header": "Updated", "width": "9rem" }
64
64
  ],
65
65
  "detail": {
66
66
  "linkField": "issue_url",
@@ -73,14 +73,14 @@
73
73
  { "label": "All", "filter": [] }
74
74
  ],
75
75
  "columns": [
76
- { "field": "title", "template": "{{title}}", "header": "Item", "link": { "kind": "page", "page": "epic-detail", "keyField": "plan_key" } },
76
+ { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "plan_key", "truncate": true, "width": "34%", "link": { "kind": "page", "page": "epic-detail", "keyField": "plan_key" } },
77
77
  { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
78
78
  { "field": "delivery", "header": "Delivery" },
79
79
  { "field": "base_branch", "header": "Base branch" },
80
80
  { "field": "wave_label", "header": "Wave" },
81
81
  { "field": "task_count", "header": "Tasks" },
82
82
  { "field": "issue_number", "header": "Issue", "linkField": "issue_url" },
83
- { "field": "updated_at", "header": "Updated" }
83
+ { "field": "updated_at", "header": "Updated", "width": "9rem" }
84
84
  ]
85
85
  }
86
86
  }
@@ -70,16 +70,16 @@
70
70
  { "label": "All", "filter": [] }
71
71
  ],
72
72
  "columns": [
73
- { "field": "title", "template": "{{title}}", "header": "Item", "linkField": "issue_url" },
73
+ { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "feature_key", "truncate": true, "width": "34%", "linkField": "issue_url" },
74
74
  { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
75
- { "field": "escalation_question", "header": "Escalation" },
75
+ { "field": "escalation_question", "header": "Escalation", "truncate": true },
76
76
  { "field": "base_branch", "header": "Base branch" },
77
77
  { "field": "pr_key", "header": "PR", "link": { "kind": "page", "page": "home", "keyField": "pr_key" } },
78
78
  { "field": "delivery_label", "header": "Delivery" },
79
79
  { "field": "converge", "header": "Converge" },
80
80
  { "field": "auto_merge", "header": "Auto-merge" },
81
81
  { "field": "outcome", "header": "Outcome" },
82
- { "field": "updated_at", "header": "Updated" }
82
+ { "field": "updated_at", "header": "Updated", "width": "9rem" }
83
83
  ],
84
84
  "rowActions": [
85
85
  {
@@ -166,6 +166,9 @@
166
166
  "field": "title",
167
167
  "template": "{{title}}",
168
168
  "header": "Item",
169
+ "subtitleField": "pr_key",
170
+ "truncate": true,
171
+ "width": "36%",
169
172
  "linkField": "url"
170
173
  },
171
174
  {
@@ -179,6 +182,7 @@
179
182
  {
180
183
  "field": "incident_message",
181
184
  "header": "Incident",
185
+ "truncate": true,
182
186
  "badge": {
183
187
  "tone": "danger",
184
188
  "label": "1"
@@ -194,7 +198,8 @@
194
198
  },
195
199
  {
196
200
  "field": "updated_at",
197
- "header": "Updated"
201
+ "header": "Updated",
202
+ "width": "9rem"
198
203
  }
199
204
  ],
200
205
  "rowActions": [
@@ -63,10 +63,10 @@
63
63
  ]
64
64
  },
65
65
  "columns": [
66
- { "field": "title", "template": "{{title}}", "header": "Item", "link": { "kind": "page", "page": "home", "keyField": "pr_key" } },
66
+ { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "pr_key", "truncate": true, "width": "36%", "link": { "kind": "page", "page": "home", "keyField": "pr_key" } },
67
67
  { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
68
68
  { "field": "current_round", "template": "{{current_round}} · {{active_worker}}", "header": "Round · Agent" },
69
- { "field": "updated_at", "header": "Updated" }
69
+ { "field": "updated_at", "header": "Updated", "width": "9rem" }
70
70
  ]
71
71
  }
72
72
  },
@@ -88,10 +88,10 @@
88
88
  "filter": [{ "field": "status", "in": ["planning", "dispatched"] }]
89
89
  },
90
90
  "columns": [
91
- { "field": "title", "template": "{{title}}", "header": "Item", "link": { "kind": "page", "page": "epic-detail", "keyField": "plan_key" } },
91
+ { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "plan_key", "truncate": true, "width": "36%", "link": { "kind": "page", "page": "epic-detail", "keyField": "plan_key" } },
92
92
  { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
93
93
  { "field": "wave_label", "header": "Wave" },
94
- { "field": "updated_at", "header": "Updated" }
94
+ { "field": "updated_at", "header": "Updated", "width": "9rem" }
95
95
  ]
96
96
  }
97
97
  },
@@ -113,10 +113,10 @@
113
113
  "filter": [{ "field": "status", "in": ["running", "escalated", "awaiting_operator"] }]
114
114
  },
115
115
  "columns": [
116
- { "field": "title", "template": "{{title}}", "header": "Item", "link": { "kind": "page", "page": "feature", "keyField": "feature_key" } },
116
+ { "field": "title", "template": "{{title}}", "header": "Item", "subtitleField": "feature_key", "truncate": true, "width": "36%", "link": { "kind": "page", "page": "feature", "keyField": "feature_key" } },
117
117
  { "field": "status", "header": "Status", "link": { "kind": "processExplorer", "keyField": "process_key" } },
118
118
  { "field": "delivery_label", "header": "Delivery" },
119
- { "field": "updated_at", "header": "Updated" }
119
+ { "field": "updated_at", "header": "Updated", "width": "9rem" }
120
120
  ],
121
121
  "rowActions": [
122
122
  {