@agent-arc-status/reference 0.3.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/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/cadence.d.ts +104 -0
- package/dist/cadence.d.ts.map +1 -0
- package/dist/cadence.js +147 -0
- package/dist/cadence.js.map +1 -0
- package/dist/forest.d.ts +45 -0
- package/dist/forest.d.ts.map +1 -0
- package/dist/forest.js +143 -0
- package/dist/forest.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +29 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +56 -0
- package/dist/parse.js.map +1 -0
- package/dist/render.d.ts +35 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +83 -0
- package/dist/render.js.map +1 -0
- package/dist/state.d.ts +44 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +62 -0
- package/dist/state.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +85 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +327 -0
- package/dist/validate.js.map +1 -0
- package/package.json +51 -0
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsing helpers for arc.status events.
|
|
3
|
+
*
|
|
4
|
+
* These wrap `JSON.parse` with structural validation. They never throw on
|
|
5
|
+
* malformed input; they return a `ValidationResult`.
|
|
6
|
+
*/
|
|
7
|
+
import { type ValidationResult } from "./validate.js";
|
|
8
|
+
/**
|
|
9
|
+
* Parse a single JSON string or buffer into a validated event.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parse(input: string | Buffer): ValidationResult;
|
|
12
|
+
export interface JsonlParseResult {
|
|
13
|
+
/** Validated events in order of appearance. */
|
|
14
|
+
events: import("./types.js").ArcStatusEvent[];
|
|
15
|
+
/** Per-line errors keyed by 0-indexed line number. */
|
|
16
|
+
errors: Array<{
|
|
17
|
+
line: number;
|
|
18
|
+
issues: import("./validate.js").ValidationIssue[];
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a JSON Lines stream of events. Empty lines are skipped.
|
|
23
|
+
*
|
|
24
|
+
* Does not throw. Lines that fail to parse or validate are reported in
|
|
25
|
+
* `errors`; valid lines are returned in `events`. Callers decide whether
|
|
26
|
+
* to treat any error as fatal.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseJsonl(input: string | Buffer): JsonlParseResult;
|
|
29
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAY,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEhE;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAmB9D;AAED,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,MAAM,EAAE,OAAO,YAAY,EAAE,cAAc,EAAE,CAAC;IAC9C,sDAAsD;IACtD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,eAAe,EAAE,eAAe,EAAE,CAAC;KACnD,CAAC,CAAC;CACJ;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAmBnE"}
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsing helpers for arc.status events.
|
|
3
|
+
*
|
|
4
|
+
* These wrap `JSON.parse` with structural validation. They never throw on
|
|
5
|
+
* malformed input; they return a `ValidationResult`.
|
|
6
|
+
*/
|
|
7
|
+
import { validate } from "./validate.js";
|
|
8
|
+
/**
|
|
9
|
+
* Parse a single JSON string or buffer into a validated event.
|
|
10
|
+
*/
|
|
11
|
+
export function parse(input) {
|
|
12
|
+
const text = typeof input === "string" ? input : input.toString("utf8");
|
|
13
|
+
let parsed;
|
|
14
|
+
try {
|
|
15
|
+
parsed = JSON.parse(text);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
issues: [
|
|
21
|
+
{
|
|
22
|
+
path: "",
|
|
23
|
+
message: `not valid JSON: ${err.message}`,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return validate(parsed);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse a JSON Lines stream of events. Empty lines are skipped.
|
|
32
|
+
*
|
|
33
|
+
* Does not throw. Lines that fail to parse or validate are reported in
|
|
34
|
+
* `errors`; valid lines are returned in `events`. Callers decide whether
|
|
35
|
+
* to treat any error as fatal.
|
|
36
|
+
*/
|
|
37
|
+
export function parseJsonl(input) {
|
|
38
|
+
const text = typeof input === "string" ? input : input.toString("utf8");
|
|
39
|
+
const lines = text.split(/\r?\n/);
|
|
40
|
+
const events = [];
|
|
41
|
+
const errors = [];
|
|
42
|
+
for (let i = 0; i < lines.length; i++) {
|
|
43
|
+
const raw = lines[i];
|
|
44
|
+
if (raw === undefined || raw.trim() === "")
|
|
45
|
+
continue;
|
|
46
|
+
const result = parse(raw);
|
|
47
|
+
if (result.ok) {
|
|
48
|
+
events.push(result.event);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
errors.push({ line: i, issues: result.issues });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { events, errors };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAyB,MAAM,eAAe,CAAC;AAEhE;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,KAAsB;IAC1C,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAExE,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,mBAAoB,GAAa,CAAC,OAAO,EAAE;iBACrD;aACF;SACF,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAYD;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAElC,MAAM,MAAM,GAA0C,EAAE,CAAC;IACzD,MAAM,MAAM,GAA+B,EAAE,CAAC;IAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QACrD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderers turn arc.status events into human-facing strings for a given
|
|
3
|
+
* surface (terminal, Slack, Telegram, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Rendering is intentionally a consumer concern (see spec §1.3 design
|
|
6
|
+
* principle 5: "Receiver renders"). These helpers are provided so common
|
|
7
|
+
* cases work in one line; complex surfaces should write their own.
|
|
8
|
+
*/
|
|
9
|
+
import type { ArcStatusEvent } from "./types.js";
|
|
10
|
+
export interface RenderOptions {
|
|
11
|
+
/** Include a leading symbol per phase. Default: true. */
|
|
12
|
+
symbol?: boolean;
|
|
13
|
+
/** Include the phase label in CAPS. Default: false. */
|
|
14
|
+
phaseLabel?: boolean;
|
|
15
|
+
/** Include `step/total` if both are present on the event. Default: true. */
|
|
16
|
+
step?: boolean;
|
|
17
|
+
/** Include `eta_minutes` if present. Default: true. */
|
|
18
|
+
eta?: boolean;
|
|
19
|
+
/** Append the body, if present. Default: false. */
|
|
20
|
+
body?: boolean;
|
|
21
|
+
/** Truncate the body to N characters when included. Default: 240. */
|
|
22
|
+
bodyMax?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Render an event to a single human-readable line, with optional body block.
|
|
26
|
+
*
|
|
27
|
+
* Examples:
|
|
28
|
+
* "▶ build Pulsefeed v0.1"
|
|
29
|
+
* "✓ [6/11] receiver booted (ETA 25m)"
|
|
30
|
+
* "· still working: hyperparameter sweep (run 4/12)"
|
|
31
|
+
* "■ v0.1 complete, 43 tests, deployed"
|
|
32
|
+
* "⛔ need finance sign-off on plan-B reclassification"
|
|
33
|
+
*/
|
|
34
|
+
export declare function render(event: ArcStatusEvent, options?: RenderOptions): string;
|
|
35
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,YAAY,CAAC;AAkBjE,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAuC7E"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderers turn arc.status events into human-facing strings for a given
|
|
3
|
+
* surface (terminal, Slack, Telegram, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Rendering is intentionally a consumer concern (see spec §1.3 design
|
|
6
|
+
* principle 5: "Receiver renders"). These helpers are provided so common
|
|
7
|
+
* cases work in one line; complex surfaces should write their own.
|
|
8
|
+
*/
|
|
9
|
+
const PHASE_SYMBOLS = {
|
|
10
|
+
started: "▶",
|
|
11
|
+
milestone: "✓",
|
|
12
|
+
heartbeat: "·",
|
|
13
|
+
done: "■",
|
|
14
|
+
blocked: "⛔",
|
|
15
|
+
};
|
|
16
|
+
const PHASE_LABELS = {
|
|
17
|
+
started: "STARTED",
|
|
18
|
+
milestone: "MILESTONE",
|
|
19
|
+
heartbeat: "HEARTBEAT",
|
|
20
|
+
done: "DONE",
|
|
21
|
+
blocked: "BLOCKED",
|
|
22
|
+
};
|
|
23
|
+
const DEFAULTS = {
|
|
24
|
+
symbol: true,
|
|
25
|
+
phaseLabel: false,
|
|
26
|
+
step: true,
|
|
27
|
+
eta: true,
|
|
28
|
+
body: false,
|
|
29
|
+
bodyMax: 240,
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Render an event to a single human-readable line, with optional body block.
|
|
33
|
+
*
|
|
34
|
+
* Examples:
|
|
35
|
+
* "▶ build Pulsefeed v0.1"
|
|
36
|
+
* "✓ [6/11] receiver booted (ETA 25m)"
|
|
37
|
+
* "· still working: hyperparameter sweep (run 4/12)"
|
|
38
|
+
* "■ v0.1 complete, 43 tests, deployed"
|
|
39
|
+
* "⛔ need finance sign-off on plan-B reclassification"
|
|
40
|
+
*/
|
|
41
|
+
export function render(event, options) {
|
|
42
|
+
const opts = { ...DEFAULTS, ...options };
|
|
43
|
+
const parts = [];
|
|
44
|
+
if (opts.symbol) {
|
|
45
|
+
parts.push(PHASE_SYMBOLS[event.phase]);
|
|
46
|
+
}
|
|
47
|
+
if (opts.phaseLabel) {
|
|
48
|
+
parts.push(PHASE_LABELS[event.phase]);
|
|
49
|
+
}
|
|
50
|
+
if (opts.step &&
|
|
51
|
+
typeof event.step === "number" &&
|
|
52
|
+
typeof event.total === "number") {
|
|
53
|
+
parts.push(`[${event.step}/${event.total}]`);
|
|
54
|
+
}
|
|
55
|
+
parts.push(event.title);
|
|
56
|
+
if (opts.eta && typeof event.eta_minutes === "number") {
|
|
57
|
+
parts.push(`(ETA ${formatMinutes(event.eta_minutes)})`);
|
|
58
|
+
}
|
|
59
|
+
let line = parts.join(" ");
|
|
60
|
+
if (opts.body && event.body) {
|
|
61
|
+
const max = Math.max(1, opts.bodyMax);
|
|
62
|
+
const body = event.body.length > max
|
|
63
|
+
? event.body.slice(0, max - 1) + "…"
|
|
64
|
+
: event.body;
|
|
65
|
+
line += "\n" + body;
|
|
66
|
+
}
|
|
67
|
+
return line;
|
|
68
|
+
}
|
|
69
|
+
function formatMinutes(minutes) {
|
|
70
|
+
if (minutes < 1)
|
|
71
|
+
return "<1m";
|
|
72
|
+
// Round to whole minutes first, then split into h/m, so a value like 119.6
|
|
73
|
+
// becomes 2h rather than the malformed "1h60m".
|
|
74
|
+
const total = Math.round(minutes);
|
|
75
|
+
if (total < 60)
|
|
76
|
+
return `${total}m`;
|
|
77
|
+
const h = Math.floor(total / 60);
|
|
78
|
+
const m = total - h * 60;
|
|
79
|
+
if (m === 0)
|
|
80
|
+
return `${h}h`;
|
|
81
|
+
return `${h}h${m}m`;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fold an ordered event stream into the current state of an arc: the cheap
|
|
3
|
+
* "what is true now?" reduction that design-rationale.md promises the reference
|
|
4
|
+
* implementation provides. Append-only events compose with any transport; this
|
|
5
|
+
* reconstructs current state for consumers that want a snapshot rather than a
|
|
6
|
+
* timeline. Pure, zero dependencies.
|
|
7
|
+
*/
|
|
8
|
+
import type { ArcStatusEvent, ArcStatusPhase } from "./types.js";
|
|
9
|
+
export interface ArcMilestone {
|
|
10
|
+
title: string;
|
|
11
|
+
sent_at: string;
|
|
12
|
+
step?: number;
|
|
13
|
+
total?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ArcState {
|
|
16
|
+
arc_id: string;
|
|
17
|
+
/** Objective, taken from the `started` event (falls back to the first event). */
|
|
18
|
+
title: string;
|
|
19
|
+
/** Phase of the most recent event. */
|
|
20
|
+
phase: ArcStatusPhase;
|
|
21
|
+
/** Derived lifecycle status. `blocked` clears once a later non-blocked event arrives. */
|
|
22
|
+
status: "active" | "blocked" | "done";
|
|
23
|
+
/** Latest `step`/`total`/`eta_minutes` seen on any event, if present. */
|
|
24
|
+
step?: number;
|
|
25
|
+
total?: number;
|
|
26
|
+
eta_minutes?: number;
|
|
27
|
+
startedAt: string;
|
|
28
|
+
lastEventAt: string;
|
|
29
|
+
eventCount: number;
|
|
30
|
+
milestones: ArcMilestone[];
|
|
31
|
+
/** The current blocker if the most recent event is `blocked`, else null. */
|
|
32
|
+
blocked: {
|
|
33
|
+
title: string;
|
|
34
|
+
body?: string;
|
|
35
|
+
sent_at: string;
|
|
36
|
+
} | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reduce an ordered sequence of events for a single arc into current state.
|
|
40
|
+
* Returns null for an empty sequence. Does not validate the sequence; pass a
|
|
41
|
+
* sequence you trust (or run `validateSequence` first).
|
|
42
|
+
*/
|
|
43
|
+
export declare function reduceArc(events: ArcStatusEvent[]): ArcState | null;
|
|
44
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,yFAAyF;IACzF,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACtC,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,QAAQ,GAAG,IAAI,CAoDnE"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fold an ordered event stream into the current state of an arc: the cheap
|
|
3
|
+
* "what is true now?" reduction that design-rationale.md promises the reference
|
|
4
|
+
* implementation provides. Append-only events compose with any transport; this
|
|
5
|
+
* reconstructs current state for consumers that want a snapshot rather than a
|
|
6
|
+
* timeline. Pure, zero dependencies.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Reduce an ordered sequence of events for a single arc into current state.
|
|
10
|
+
* Returns null for an empty sequence. Does not validate the sequence; pass a
|
|
11
|
+
* sequence you trust (or run `validateSequence` first).
|
|
12
|
+
*/
|
|
13
|
+
export function reduceArc(events) {
|
|
14
|
+
if (events.length === 0)
|
|
15
|
+
return null;
|
|
16
|
+
const first = events[0];
|
|
17
|
+
const last = events[events.length - 1];
|
|
18
|
+
const started = events.find((e) => e.phase === "started");
|
|
19
|
+
const milestones = [];
|
|
20
|
+
let step;
|
|
21
|
+
let total;
|
|
22
|
+
let eta_minutes;
|
|
23
|
+
for (const e of events) {
|
|
24
|
+
if (e.phase === "milestone") {
|
|
25
|
+
milestones.push({
|
|
26
|
+
title: e.title,
|
|
27
|
+
sent_at: e.sent_at,
|
|
28
|
+
step: e.step,
|
|
29
|
+
total: e.total,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (typeof e.step === "number")
|
|
33
|
+
step = e.step;
|
|
34
|
+
if (typeof e.total === "number")
|
|
35
|
+
total = e.total;
|
|
36
|
+
if (typeof e.eta_minutes === "number")
|
|
37
|
+
eta_minutes = e.eta_minutes;
|
|
38
|
+
}
|
|
39
|
+
const status = last.phase === "done"
|
|
40
|
+
? "done"
|
|
41
|
+
: last.phase === "blocked"
|
|
42
|
+
? "blocked"
|
|
43
|
+
: "active";
|
|
44
|
+
const blocked = last.phase === "blocked"
|
|
45
|
+
? { title: last.title, body: last.body, sent_at: last.sent_at }
|
|
46
|
+
: null;
|
|
47
|
+
return {
|
|
48
|
+
arc_id: first.arc_id,
|
|
49
|
+
title: started?.title ?? first.title,
|
|
50
|
+
phase: last.phase,
|
|
51
|
+
status,
|
|
52
|
+
step,
|
|
53
|
+
total,
|
|
54
|
+
eta_minutes,
|
|
55
|
+
startedAt: started?.sent_at ?? first.sent_at,
|
|
56
|
+
lastEventAt: last.sent_at,
|
|
57
|
+
eventCount: events.length,
|
|
58
|
+
milestones,
|
|
59
|
+
blocked,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,MAAwB;IAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;IACzB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAE1D,MAAM,UAAU,GAAmB,EAAE,CAAC;IACtC,IAAI,IAAwB,CAAC;IAC7B,IAAI,KAAyB,CAAC;IAC9B,IAAI,WAA+B,CAAC;IAEpC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC5B,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QAC9C,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;YAAE,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QACjD,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ;YAAE,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;IACrE,CAAC;IAED,MAAM,MAAM,GACV,IAAI,CAAC,KAAK,KAAK,MAAM;QACnB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,QAAQ,CAAC;IAEjB,MAAM,OAAO,GACX,IAAI,CAAC,KAAK,KAAK,SAAS;QACtB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;QAC/D,CAAC,CAAC,IAAI,CAAC;IAEX,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK;QACpC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM;QACN,IAAI;QACJ,KAAK;QACL,WAAW;QACX,SAAS,EAAE,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO;QAC5C,WAAW,EAAE,IAAI,CAAC,OAAO;QACzB,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,UAAU;QACV,OAAO;KACR,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Arc Status Protocol v0.2: TypeScript types.
|
|
3
|
+
*
|
|
4
|
+
* These mirror the JSON Schema in `spec/schema.json`. They are the
|
|
5
|
+
* authoritative type-level representation of a conformant event.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ARC_STATUS_PHASES: readonly ["started", "milestone", "heartbeat", "done", "blocked"];
|
|
8
|
+
export type ArcStatusPhase = (typeof ARC_STATUS_PHASES)[number];
|
|
9
|
+
export interface ArcStatusEvent {
|
|
10
|
+
/** Stable identifier for the arc. All events in one arc share this value. */
|
|
11
|
+
arc_id: string;
|
|
12
|
+
/** Lifecycle position of the arc at the moment of emission. */
|
|
13
|
+
phase: ArcStatusPhase;
|
|
14
|
+
/** Short human-readable label for this event. */
|
|
15
|
+
title: string;
|
|
16
|
+
/** Longer freeform body, optionally containing markdown. */
|
|
17
|
+
body?: string;
|
|
18
|
+
/** 1-indexed step number within a sequenced arc. */
|
|
19
|
+
step?: number;
|
|
20
|
+
/** Total number of steps in a sequenced arc. */
|
|
21
|
+
total?: number;
|
|
22
|
+
/** Emitter's current estimate of minutes remaining to done. */
|
|
23
|
+
eta_minutes?: number;
|
|
24
|
+
/** UTC timestamp at which the event was generated (RFC 3339). */
|
|
25
|
+
sent_at: string;
|
|
26
|
+
/** Optional free-form label naming the kind of work. */
|
|
27
|
+
arc_kind?: string;
|
|
28
|
+
/** The Protocol version the emitter targets, e.g. "0.1". */
|
|
29
|
+
protocol_version?: string;
|
|
30
|
+
/** Application-specific extensions MUST use the `x_` prefix. */
|
|
31
|
+
[extension: `x_${string}`]: unknown;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A sink for arc.status events — the injection point that emitters, transports,
|
|
35
|
+
* and framework adapters accept so they stay decoupled from any one transport.
|
|
36
|
+
*/
|
|
37
|
+
export type EmitFn = (event: ArcStatusEvent) => void | Promise<void>;
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,iBAAiB,mEAMpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,KAAK,EAAE,cAAc,CAAC;IACtB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,CAAC,SAAS,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Arc Status Protocol v0.2: TypeScript types.
|
|
3
|
+
*
|
|
4
|
+
* These mirror the JSON Schema in `spec/schema.json`. They are the
|
|
5
|
+
* authoritative type-level representation of a conformant event.
|
|
6
|
+
*/
|
|
7
|
+
export const ARC_STATUS_PHASES = [
|
|
8
|
+
"started",
|
|
9
|
+
"milestone",
|
|
10
|
+
"heartbeat",
|
|
11
|
+
"done",
|
|
12
|
+
"blocked",
|
|
13
|
+
];
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,SAAS;IACT,WAAW;IACX,WAAW;IACX,MAAM;IACN,SAAS;CACD,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime validator for arc.status events.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the JSON Schema in `spec/schema.json` but is hand-rolled so the
|
|
5
|
+
* reference implementation ships with zero runtime dependencies. For users
|
|
6
|
+
* who want canonical-schema validation, `spec/schema.json` is also published
|
|
7
|
+
* and works with any standard JSON Schema validator (e.g. ajv).
|
|
8
|
+
*/
|
|
9
|
+
import { type ArcStatusEvent } from "./types.js";
|
|
10
|
+
export interface ValidationIssue {
|
|
11
|
+
/** Dot-path to the offending field, e.g. "arc_id" or "step". */
|
|
12
|
+
path: string;
|
|
13
|
+
/** Human-readable explanation of the failure. */
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export type ValidationResult = {
|
|
17
|
+
ok: true;
|
|
18
|
+
event: ArcStatusEvent;
|
|
19
|
+
} | {
|
|
20
|
+
ok: false;
|
|
21
|
+
issues: ValidationIssue[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Canonical RFC 3339 grammar for `sent_at`, kept as a string so it can be
|
|
25
|
+
* shared byte-for-byte with `spec/schema.json`'s `sent_at.pattern`. The
|
|
26
|
+
* equivalence test asserts the two are identical, preventing future drift.
|
|
27
|
+
*
|
|
28
|
+
* It bounds month (01–12), day (01–31), hour (00–23), minute/second (00–59),
|
|
29
|
+
* and the UTC offset (≤ ±14:00); fractional seconds are optional (1–9 digits).
|
|
30
|
+
* It rejects leap seconds (`:60`), lowercase `t`/`z`, and the space separator.
|
|
31
|
+
* Per-month calendar validity (e.g. Feb 30) cannot be expressed portably in a
|
|
32
|
+
* regex and is enforced by `isValidCalendarDate` below.
|
|
33
|
+
*/
|
|
34
|
+
export declare const RFC3339_PATTERN = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,9})?(Z|[+-](0\\d|1[0-4]):[0-5]\\d)$";
|
|
35
|
+
/**
|
|
36
|
+
* Validate a candidate event against the Protocol's wire-format rules.
|
|
37
|
+
*
|
|
38
|
+
* This checks structural conformance only: required fields present, types
|
|
39
|
+
* correct, enums respected, numeric bounds satisfied, timestamp parseable.
|
|
40
|
+
*
|
|
41
|
+
* It does NOT validate phase-ordering rules across a sequence of events;
|
|
42
|
+
* see `validateSequence` for that.
|
|
43
|
+
*/
|
|
44
|
+
export declare function validate(candidate: unknown): ValidationResult;
|
|
45
|
+
export interface SequenceIssue {
|
|
46
|
+
/** 0-indexed position in the input sequence where the violation was detected. */
|
|
47
|
+
index: number;
|
|
48
|
+
message: string;
|
|
49
|
+
}
|
|
50
|
+
export interface SequenceOptions {
|
|
51
|
+
/**
|
|
52
|
+
* Treat `events` as an in-flight prefix rather than a complete arc: skip the
|
|
53
|
+
* requirement (§4.6) that the last event be a terminal (`done` or terminal
|
|
54
|
+
* `blocked`). Use when validating a live stream that has not finished yet.
|
|
55
|
+
* Default: false (the sequence is treated as a complete arc).
|
|
56
|
+
*/
|
|
57
|
+
partial?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Require `sent_at` to be non-decreasing across the sequence. Off by default:
|
|
60
|
+
* lossy transports may deliver out of order and §7.5 has consumers reorder by
|
|
61
|
+
* `sent_at`, so a raw stream is not guaranteed monotonic. Enable only when the
|
|
62
|
+
* input is known to be in emission order.
|
|
63
|
+
*/
|
|
64
|
+
checkMonotonicSentAt?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Validate phase-ordering for a sequence of events belonging to a single arc.
|
|
68
|
+
*
|
|
69
|
+
* Enforces §4.5–§4.6 of the spec:
|
|
70
|
+
* - exactly one `started`, at the beginning
|
|
71
|
+
* - the last event is a terminal (`done` or terminal `blocked`), unless
|
|
72
|
+
* `options.partial` is set (in-flight prefix)
|
|
73
|
+
* - at most one `done`, and no events after it
|
|
74
|
+
* - after `blocked`, the next event is `milestone` (resume), `done`, or
|
|
75
|
+
* end-of-arc; `started`, `heartbeat`, and a second consecutive `blocked`
|
|
76
|
+
* are illegal
|
|
77
|
+
* - (optional) `sent_at` is non-decreasing when `checkMonotonicSentAt` is set
|
|
78
|
+
*
|
|
79
|
+
* Does NOT re-validate individual events; call `validate` first if needed.
|
|
80
|
+
*/
|
|
81
|
+
export declare function validateSequence(events: ArcStatusEvent[], options?: SequenceOptions): {
|
|
82
|
+
ok: boolean;
|
|
83
|
+
issues: SequenceIssue[];
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GACnC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC;AAE7C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,mIACsG,CAAC;AAsDnI;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,gBAAgB,CAoJ7D;AAED,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,EAAE,EACxB,OAAO,GAAE,eAAoB,GAC5B;IACD,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB,CAoHA"}
|