@bluecopa/harness 0.1.0-snapshot.90 → 0.1.0-snapshot.91

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.
@@ -0,0 +1,61 @@
1
+ type ArcAppProcessMeta = {
2
+ label?: string;
3
+ profile?: string;
4
+ model?: string;
5
+ dispatchedAt: number;
6
+ };
7
+ type ArcAppBackgroundTurn = {
8
+ id: string;
9
+ label?: string;
10
+ profile?: string;
11
+ model?: string;
12
+ dispatchedAt: number;
13
+ };
14
+ type ArcAppState = {
15
+ activeTurnId: string | null;
16
+ processes: Record<string, ArcAppProcessMeta>;
17
+ backgroundTurns: Record<string, ArcAppBackgroundTurn>;
18
+ };
19
+ type ArcAdapterInputEvent = {
20
+ type: string;
21
+ id?: string;
22
+ label?: string;
23
+ profile?: string;
24
+ model?: string;
25
+ summary?: string;
26
+ error?: string;
27
+ };
28
+ type ArcAppEvent = {
29
+ type: 'state_changed';
30
+ state: ArcAppState;
31
+ } | {
32
+ type: 'process_summary';
33
+ id: string;
34
+ meta?: ArcAppProcessMeta;
35
+ summary: string;
36
+ } | {
37
+ type: 'process_failed';
38
+ id?: string;
39
+ error: string;
40
+ };
41
+ type Listener = (event: ArcAppEvent) => void;
42
+ declare function createInitialArcAppState(): ArcAppState;
43
+ declare class ArcAppAdapter {
44
+ private state;
45
+ private listeners;
46
+ constructor(initialState?: ArcAppState);
47
+ subscribe(listener: Listener): () => void;
48
+ getState(): ArcAppState;
49
+ reset(): void;
50
+ beginTurn(turnId: string): void;
51
+ finishTurn(turnId: string): void;
52
+ backgroundTurn(turnId: string, meta: {
53
+ label?: string;
54
+ profile?: string;
55
+ model?: string;
56
+ }): boolean;
57
+ handleArcEvent(event: ArcAdapterInputEvent): void;
58
+ private emit;
59
+ }
60
+
61
+ export { type ArcAdapterInputEvent, ArcAppAdapter, type ArcAppBackgroundTurn, type ArcAppEvent, type ArcAppProcessMeta, type ArcAppState, createInitialArcAppState };
@@ -0,0 +1,135 @@
1
+ // src/arc/app-adapter.ts
2
+ function cloneState(state) {
3
+ return {
4
+ activeTurnId: state.activeTurnId,
5
+ processes: { ...state.processes },
6
+ backgroundTurns: { ...state.backgroundTurns }
7
+ };
8
+ }
9
+ function withDefined(value) {
10
+ return Object.fromEntries(
11
+ Object.entries(value).filter(([, entry]) => entry !== void 0)
12
+ );
13
+ }
14
+ function cleanProcessSummary(summary) {
15
+ const lines = summary.split("\n").map((line) => line.trim()).filter(Boolean);
16
+ const resultLine = lines.find((line) => /^result\s*:/i.test(line));
17
+ if (resultLine) {
18
+ return resultLine.replace(/^result\s*:\s*/i, "").trim();
19
+ }
20
+ const firstUsefulLine = lines.find((line) => !/^(action|status|steps|tools used|files read|files modified)\s*:/i.test(line));
21
+ if (firstUsefulLine) {
22
+ return firstUsefulLine;
23
+ }
24
+ return summary.replace(/^(action|summary|result)\s*:\s*/i, "").trim();
25
+ }
26
+ function createInitialArcAppState() {
27
+ return {
28
+ activeTurnId: null,
29
+ processes: {},
30
+ backgroundTurns: {}
31
+ };
32
+ }
33
+ var ArcAppAdapter = class {
34
+ state;
35
+ listeners = /* @__PURE__ */ new Set();
36
+ constructor(initialState = createInitialArcAppState()) {
37
+ this.state = cloneState(initialState);
38
+ }
39
+ subscribe(listener) {
40
+ this.listeners.add(listener);
41
+ return () => {
42
+ this.listeners.delete(listener);
43
+ };
44
+ }
45
+ getState() {
46
+ return cloneState(this.state);
47
+ }
48
+ reset() {
49
+ this.state = createInitialArcAppState();
50
+ this.emit({ type: "state_changed", state: this.getState() });
51
+ }
52
+ beginTurn(turnId) {
53
+ if (this.state.activeTurnId === turnId) return;
54
+ this.state.activeTurnId = turnId;
55
+ this.emit({ type: "state_changed", state: this.getState() });
56
+ }
57
+ finishTurn(turnId) {
58
+ let changed = false;
59
+ if (this.state.activeTurnId === turnId) {
60
+ this.state.activeTurnId = null;
61
+ changed = true;
62
+ }
63
+ if (this.state.backgroundTurns[turnId]) {
64
+ delete this.state.backgroundTurns[turnId];
65
+ changed = true;
66
+ }
67
+ if (changed) {
68
+ this.emit({ type: "state_changed", state: this.getState() });
69
+ }
70
+ }
71
+ backgroundTurn(turnId, meta) {
72
+ if (this.state.activeTurnId !== turnId) {
73
+ return false;
74
+ }
75
+ this.state.activeTurnId = null;
76
+ this.state.backgroundTurns[turnId] = withDefined({
77
+ id: turnId,
78
+ label: meta.label,
79
+ profile: meta.profile,
80
+ model: meta.model,
81
+ dispatchedAt: Date.now()
82
+ });
83
+ this.emit({ type: "state_changed", state: this.getState() });
84
+ return true;
85
+ }
86
+ handleArcEvent(event) {
87
+ switch (event.type) {
88
+ case "process_dispatched":
89
+ if (!event.id) return;
90
+ this.state.processes[event.id] = withDefined({
91
+ label: event.label,
92
+ profile: event.profile,
93
+ model: event.model,
94
+ dispatchedAt: this.state.processes[event.id]?.dispatchedAt ?? Date.now()
95
+ });
96
+ this.emit({ type: "state_changed", state: this.getState() });
97
+ return;
98
+ case "process_completed":
99
+ if (!event.id) return;
100
+ this.emit(withDefined({
101
+ type: "process_summary",
102
+ id: event.id,
103
+ meta: this.state.processes[event.id],
104
+ summary: cleanProcessSummary(event.summary ?? "")
105
+ }));
106
+ delete this.state.processes[event.id];
107
+ delete this.state.backgroundTurns[event.id];
108
+ this.emit({ type: "state_changed", state: this.getState() });
109
+ return;
110
+ case "process_failed":
111
+ this.emit(withDefined({
112
+ type: "process_failed",
113
+ id: event.id,
114
+ error: event.error ?? "unknown error"
115
+ }));
116
+ if (event.id) {
117
+ delete this.state.processes[event.id];
118
+ delete this.state.backgroundTurns[event.id];
119
+ this.emit({ type: "state_changed", state: this.getState() });
120
+ }
121
+ return;
122
+ default:
123
+ return;
124
+ }
125
+ }
126
+ emit(event) {
127
+ for (const listener of this.listeners) {
128
+ listener(event);
129
+ }
130
+ }
131
+ };
132
+
133
+ export { ArcAppAdapter, createInitialArcAppState };
134
+ //# sourceMappingURL=app-adapter.js.map
135
+ //# sourceMappingURL=app-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/arc/app-adapter.ts"],"names":[],"mappings":"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","file":"app-adapter.js","sourcesContent":["export type ArcAppProcessMeta = {\n label?: string;\n profile?: string;\n model?: string;\n dispatchedAt: number;\n};\n\nexport type ArcAppBackgroundTurn = {\n id: string;\n label?: string;\n profile?: string;\n model?: string;\n dispatchedAt: number;\n};\n\nexport type ArcAppState = {\n activeTurnId: string | null;\n processes: Record<string, ArcAppProcessMeta>;\n backgroundTurns: Record<string, ArcAppBackgroundTurn>;\n};\n\nexport type ArcAdapterInputEvent = {\n type: string;\n id?: string;\n label?: string;\n profile?: string;\n model?: string;\n summary?: string;\n error?: string;\n};\n\nexport type ArcAppEvent =\n | { type: 'state_changed'; state: ArcAppState }\n | { type: 'process_summary'; id: string; meta?: ArcAppProcessMeta; summary: string }\n | { type: 'process_failed'; id?: string; error: string };\n\ntype Listener = (event: ArcAppEvent) => void;\n\nfunction cloneState(state: ArcAppState): ArcAppState {\n return {\n activeTurnId: state.activeTurnId,\n processes: { ...state.processes },\n backgroundTurns: { ...state.backgroundTurns },\n };\n}\n\nfunction withDefined<T extends Record<string, unknown>>(value: T): T {\n return Object.fromEntries(\n Object.entries(value).filter(([, entry]) => entry !== undefined),\n ) as T;\n}\n\nfunction cleanProcessSummary(summary: string): string {\n const lines = summary\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean);\n\n const resultLine = lines.find((line) => /^result\\s*:/i.test(line));\n if (resultLine) {\n return resultLine.replace(/^result\\s*:\\s*/i, '').trim();\n }\n\n const firstUsefulLine = lines.find((line) => !/^(action|status|steps|tools used|files read|files modified)\\s*:/i.test(line));\n if (firstUsefulLine) {\n return firstUsefulLine;\n }\n\n return summary\n .replace(/^(action|summary|result)\\s*:\\s*/i, '')\n .trim();\n}\n\nexport function createInitialArcAppState(): ArcAppState {\n return {\n activeTurnId: null,\n processes: {},\n backgroundTurns: {},\n };\n}\n\nexport class ArcAppAdapter {\n private state: ArcAppState;\n\n private listeners = new Set<Listener>();\n\n constructor(initialState: ArcAppState = createInitialArcAppState()) {\n this.state = cloneState(initialState);\n }\n\n subscribe(listener: Listener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n getState(): ArcAppState {\n return cloneState(this.state);\n }\n\n reset(): void {\n this.state = createInitialArcAppState();\n this.emit({ type: 'state_changed', state: this.getState() });\n }\n\n beginTurn(turnId: string): void {\n if (this.state.activeTurnId === turnId) return;\n this.state.activeTurnId = turnId;\n this.emit({ type: 'state_changed', state: this.getState() });\n }\n\n finishTurn(turnId: string): void {\n let changed = false;\n if (this.state.activeTurnId === turnId) {\n this.state.activeTurnId = null;\n changed = true;\n }\n if (this.state.backgroundTurns[turnId]) {\n delete this.state.backgroundTurns[turnId];\n changed = true;\n }\n if (changed) {\n this.emit({ type: 'state_changed', state: this.getState() });\n }\n }\n\n backgroundTurn(turnId: string, meta: { label?: string; profile?: string; model?: string }): boolean {\n if (this.state.activeTurnId !== turnId) {\n return false;\n }\n\n this.state.activeTurnId = null;\n this.state.backgroundTurns[turnId] = withDefined({\n id: turnId,\n label: meta.label,\n profile: meta.profile,\n model: meta.model,\n dispatchedAt: Date.now(),\n }) as ArcAppBackgroundTurn;\n this.emit({ type: 'state_changed', state: this.getState() });\n return true;\n }\n\n handleArcEvent(event: ArcAdapterInputEvent): void {\n switch (event.type) {\n case 'process_dispatched':\n if (!event.id) return;\n this.state.processes[event.id] = withDefined({\n label: event.label,\n profile: event.profile,\n model: event.model,\n dispatchedAt: this.state.processes[event.id]?.dispatchedAt ?? Date.now(),\n }) as ArcAppProcessMeta;\n this.emit({ type: 'state_changed', state: this.getState() });\n return;\n case 'process_completed':\n if (!event.id) return;\n this.emit(withDefined({\n type: 'process_summary',\n id: event.id,\n meta: this.state.processes[event.id],\n summary: cleanProcessSummary(event.summary ?? ''),\n }) as ArcAppEvent);\n delete this.state.processes[event.id];\n delete this.state.backgroundTurns[event.id];\n this.emit({ type: 'state_changed', state: this.getState() });\n return;\n case 'process_failed':\n this.emit(withDefined({\n type: 'process_failed',\n id: event.id,\n error: event.error ?? 'unknown error',\n }) as ArcAppEvent);\n if (event.id) {\n delete this.state.processes[event.id];\n delete this.state.backgroundTurns[event.id];\n this.emit({ type: 'state_changed', state: this.getState() });\n }\n return;\n default:\n return;\n }\n }\n\n private emit(event: ArcAppEvent): void {\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluecopa/harness",
3
- "version": "0.1.0-snapshot.90",
3
+ "version": "0.1.0-snapshot.91",
4
4
  "description": "Provider-agnostic TypeScript agent framework",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -9,6 +9,10 @@
9
9
  "README.md"
10
10
  ],
11
11
  "exports": {
12
+ "./arc/app-adapter": {
13
+ "types": "./dist/arc/app-adapter.d.ts",
14
+ "import": "./dist/arc/app-adapter.js"
15
+ },
12
16
  "./arc/create-arc-agent": {
13
17
  "types": "./dist/arc/create-arc-agent.d.ts",
14
18
  "import": "./dist/arc/create-arc-agent.js"