@nanobpm/nano-workforce 0.170.1 → 0.171.1
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 +12 -0
- package/app/agentic/transcript-events.drift.test.ts +30 -19
- package/app/agentic/transcript-events.ts +17 -719
- package/openapi.yaml +86 -0
- package/operations/cancelInstance.test.ts +138 -0
- package/operations/cancelInstance.ts +80 -0
- package/package.json +2 -2
- package/pages/cockpit/generated/transcript-events.js +105 -122
- package/scripts/build-cockpit-browser.ts +9 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.171.1](https://github.com/nanobpm/nano-workforce/compare/v0.171.0...v0.171.1) (2026-08-31)
|
|
2
|
+
|
|
3
|
+
### Code Refactoring
|
|
4
|
+
|
|
5
|
+
* **agentic:** consume @nanobpm/agentic/transcript, drop the duplicated grammar ([#677](https://github.com/nanobpm/nano-workforce/issues/677)) ([8c8d3fc](https://github.com/nanobpm/nano-workforce/commit/8c8d3fc393134862557a65e2aab2dd9e16292c66)), closes [#676](https://github.com/nanobpm/nano-workforce/issues/676)
|
|
6
|
+
|
|
7
|
+
## [0.171.0](https://github.com/nanobpm/nano-workforce/compare/v0.170.1...v0.171.0) (2026-08-31)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **operations:** app-owned POST /actions/cancel door (cancelInstance) ([#671](https://github.com/nanobpm/nano-workforce/issues/671)) ([835afce](https://github.com/nanobpm/nano-workforce/commit/835afcea6be62fc768979b792217ad5cf246d008)), closes [#605](https://github.com/nanobpm/nano-workforce/issues/605) [#667](https://github.com/nanobpm/nano-workforce/issues/667)
|
|
12
|
+
|
|
1
13
|
## [0.170.1](https://github.com/nanobpm/nano-workforce/compare/v0.170.0...v0.170.1) (2026-08-31)
|
|
2
14
|
|
|
3
15
|
### Documentation
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
// Drift-guard:
|
|
1
|
+
// Drift-guard: the transcript grammar is DERIVED from its one owner, never re-forked here (#676).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
3
|
+
// nano-workforce used to carry a byte-for-byte hand-rolled copy of the transcript-event grammar
|
|
4
|
+
// (marker/version, the ONE parser, the vocabulary, the derive fold). That grammar now lives in exactly
|
|
5
|
+
// one place — `@nanobpm/agentic/transcript` (agentic 0.10.0) — and `transcript-events.ts` is a thin
|
|
6
|
+
// re-export barrel over it. This guard secures the *class* of failure ("a consumer hand-rolls the
|
|
7
|
+
// transcript grammar instead of importing it") structurally, by scanning the app-tier source: it fails
|
|
8
|
+
// if the barrel stops importing agentic, if a local module re-defines the envelope marker literal, or
|
|
9
|
+
// if a transcript consumer re-parses a stored chunk itself instead of folding through the one parser.
|
|
9
10
|
import { test } from "node:test";
|
|
10
11
|
import { readdirSync, readFileSync } from "node:fs";
|
|
11
12
|
import { dirname, join } from "node:path";
|
|
@@ -26,26 +27,36 @@ function sourceFiles(dir: string): string[] {
|
|
|
26
27
|
return out;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
const
|
|
30
|
+
const BARREL_MODULE = join(AGENTIC_DIR, "transcript-events.ts");
|
|
31
|
+
const AGENTIC_TRANSCRIPT_SPECIFIER = "@nanobpm/agentic/transcript";
|
|
30
32
|
|
|
31
|
-
test("the transcript
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
test("the transcript grammar is imported from @nanobpm/agentic/transcript, never redefined locally", () => {
|
|
34
|
+
// The single source of truth is agentic; nano-workforce derives from it via a re-export barrel.
|
|
35
|
+
const barrel = readFileSync(BARREL_MODULE, "utf8");
|
|
36
|
+
assert(
|
|
37
|
+
barrel.includes(AGENTIC_TRANSCRIPT_SPECIFIER),
|
|
38
|
+
`${BARREL_MODULE} must re-export the grammar from "${AGENTIC_TRANSCRIPT_SPECIFIER}"`,
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("no local module re-defines the transcript-event marker literal (no second grammar)", () => {
|
|
43
|
+
// Consumers reference the marker via the imported `TRANSCRIPT_EVENT_MARKER` identifier; only a
|
|
44
|
+
// second, forked grammar would embed the marker's string literal in nano-workforce source. Match
|
|
45
|
+
// every quote form (double, single, backtick) so a re-fork can't bypass the guard by hardcoding the
|
|
46
|
+
// marker in a different literal style. Expect ZERO owners — the literal lives in agentic now.
|
|
36
47
|
const quotedMarkerForms = ['"', "'", "`"].map((q) => `${q}${TRANSCRIPT_EVENT_MARKER}${q}`);
|
|
37
48
|
const owners = sourceFiles(AGENTIC_DIR).filter((path) => {
|
|
38
49
|
const src = readFileSync(path, "utf8");
|
|
39
50
|
return quotedMarkerForms.some((literal) => src.includes(literal));
|
|
40
51
|
});
|
|
41
|
-
assertEquals(owners, [
|
|
52
|
+
assertEquals(owners, []);
|
|
42
53
|
});
|
|
43
54
|
|
|
44
|
-
test("no transcript consumer re-parses raw chunks —
|
|
45
|
-
// The cockpit + read projections must fold through the single parser, never JSON.parse a
|
|
46
|
-
// themselves. Scan the transcript-facing consumers and assert none contains a raw JSON.parse.
|
|
47
|
-
const consumers = sourceFiles(AGENTIC_DIR).filter(
|
|
48
|
-
|
|
55
|
+
test("no transcript consumer re-parses raw chunks — the log is folded only through the one parser", () => {
|
|
56
|
+
// The cockpit + read projections must fold through the single parser (in agentic), never JSON.parse a
|
|
57
|
+
// chunk themselves. Scan the transcript-facing consumers and assert none contains a raw JSON.parse.
|
|
58
|
+
const consumers = sourceFiles(AGENTIC_DIR).filter((path) =>
|
|
59
|
+
/transcript-(read|render|view|derive|fork)\.ts$/.test(path),
|
|
49
60
|
);
|
|
50
61
|
assert(consumers.length >= 3, "expected to scan several transcript consumers");
|
|
51
62
|
for (const path of consumers) {
|