osuite 2.9.0 → 2.9.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/README.md +122 -62
- package/cli.js +367 -79
- package/index.cjs +29 -139
- package/legacy/index-v1.cjs +2 -90
- package/legacy/osuite-v1-runtime.js +7 -0
- package/legacy/osuite-v1.js +1 -1
- package/osuite.js +505 -10
- package/package.json +3 -9
- package/reviewSurface.js +131 -0
- package/LICENSE +0 -21
- package/dashclaw.js +0 -988
- package/legacy/dashclaw-v1.js +0 -2888
package/index.cjs
CHANGED
|
@@ -1,155 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
* OSuite SDK v2 (Stable Runtime API)
|
|
3
|
-
* CommonJS compatibility bridge.
|
|
4
|
-
*
|
|
5
|
-
* ESM: import { OSuite } from 'osuite'
|
|
6
|
-
* CJS: const { OSuite } = require('osuite')
|
|
7
|
-
*/
|
|
1
|
+
'use strict';
|
|
8
2
|
|
|
9
|
-
|
|
10
|
-
// We use a simplified bridge that forwards calls to the async ESM import
|
|
11
|
-
let _module;
|
|
3
|
+
let modulePromise;
|
|
12
4
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
title: 'Pre-action admissibility',
|
|
17
|
-
summary: 'Evaluate whether the proposed action is allowed, simulated first, blocked, or approval-gated before side effects happen.',
|
|
18
|
-
sdkMethod: 'guard',
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
id: 'action_open',
|
|
22
|
-
title: 'Action open',
|
|
23
|
-
summary: 'Create the portable action record that becomes the trust object for replay, scoring, and proof.',
|
|
24
|
-
sdkMethod: 'createAction',
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: 'assumption_capture',
|
|
28
|
-
title: 'Assumption capture',
|
|
29
|
-
summary: 'Record what the runtime believed or depended on so operators can replay the reasoning boundary later.',
|
|
30
|
-
sdkMethod: 'recordAssumption',
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
id: 'approval_checkpoint',
|
|
34
|
-
title: 'Approval checkpoint',
|
|
35
|
-
summary: 'Pause, wait, or externally hold execution when policy requires a human checkpoint.',
|
|
36
|
-
sdkMethod: 'waitForApproval',
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: 'outcome_closure',
|
|
40
|
-
title: 'Outcome closure',
|
|
41
|
-
summary: 'Write the final result, evidence, and status so the action certificate closes cleanly.',
|
|
42
|
-
sdkMethod: 'updateOutcome',
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
function resolveRouteDecision({ action = null, proofBundle = null } = {}) {
|
|
47
|
-
return (
|
|
48
|
-
proofBundle?.route_decision
|
|
49
|
-
|| proofBundle?.action_certificate?.route_decision
|
|
50
|
-
|| action?.policy_snapshot?.effective_decision
|
|
51
|
-
|| null
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function resolveOutcomeStatus(status) {
|
|
56
|
-
const normalized = String(status || '').toLowerCase();
|
|
57
|
-
if (['completed', 'failed', 'blocked', 'cancelled', 'denied'].includes(normalized)) return 'complete';
|
|
58
|
-
if (['running', 'pending', 'pending_approval'].includes(normalized)) return 'pending';
|
|
59
|
-
return 'inactive';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function buildPcaaCheckpointStates({ action = null, trace = null, proofBundle = null } = {}) {
|
|
63
|
-
const routeDecision = resolveRouteDecision({ action, proofBundle });
|
|
64
|
-
const assumptionCount = Number(
|
|
65
|
-
trace?.trace?.assumptions?.total
|
|
66
|
-
?? trace?.assumptions?.total
|
|
67
|
-
?? (Array.isArray(trace?.assumptions) ? trace.assumptions.length : 0),
|
|
68
|
-
);
|
|
69
|
-
const approvalTriggered = ['require_approval', 'require_dual_approval', 'simulate_first', 'warn', 'block']
|
|
70
|
-
.includes(String(routeDecision || '').toLowerCase())
|
|
71
|
-
|| String(action?.status || '').toLowerCase() === 'pending_approval';
|
|
72
|
-
const approvalComplete = Boolean(
|
|
73
|
-
action?.approved_by
|
|
74
|
-
|| action?.approved_at
|
|
75
|
-
|| (Array.isArray(proofBundle?.approvals) && proofBundle.approvals.length > 0),
|
|
76
|
-
);
|
|
77
|
-
const outcomeStatus = resolveOutcomeStatus(action?.status);
|
|
78
|
-
|
|
79
|
-
return PCAA_CHECKPOINTS.map((checkpoint) => {
|
|
80
|
-
if (checkpoint.id === 'pre_action_admissibility') {
|
|
81
|
-
return {
|
|
82
|
-
...checkpoint,
|
|
83
|
-
status: routeDecision ? 'complete' : 'inactive',
|
|
84
|
-
value: routeDecision || 'not evaluated',
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (checkpoint.id === 'action_open') {
|
|
89
|
-
return {
|
|
90
|
-
...checkpoint,
|
|
91
|
-
status: action?.action_id ? 'complete' : 'inactive',
|
|
92
|
-
value: action?.action_id || '--',
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (checkpoint.id === 'assumption_capture') {
|
|
97
|
-
return {
|
|
98
|
-
...checkpoint,
|
|
99
|
-
status: assumptionCount > 0 ? 'complete' : 'inactive',
|
|
100
|
-
value: assumptionCount > 0 ? `${assumptionCount} recorded` : 'none recorded',
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (checkpoint.id === 'approval_checkpoint') {
|
|
105
|
-
return {
|
|
106
|
-
...checkpoint,
|
|
107
|
-
status: approvalComplete ? 'complete' : approvalTriggered ? 'active' : 'inactive',
|
|
108
|
-
value: approvalComplete ? 'approved' : approvalTriggered ? (routeDecision || 'active') : 'not required',
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
...checkpoint,
|
|
114
|
-
status: outcomeStatus,
|
|
115
|
-
value: action?.status || '--',
|
|
116
|
-
};
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async function loadModule() {
|
|
121
|
-
if (!_module) {
|
|
122
|
-
_module = await import('./osuite.js');
|
|
123
|
-
}
|
|
124
|
-
return _module;
|
|
5
|
+
function loadModule() {
|
|
6
|
+
if (!modulePromise) modulePromise = import('./osuite.js');
|
|
7
|
+
return modulePromise;
|
|
125
8
|
}
|
|
126
9
|
|
|
127
10
|
class OSuiteProxy {
|
|
128
|
-
constructor(
|
|
129
|
-
this.
|
|
130
|
-
|
|
131
|
-
this._instance = new m.OSuite(opts);
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this._ready = loadModule().then((mod) => {
|
|
13
|
+
this._instance = new mod.OSuite(options);
|
|
132
14
|
});
|
|
133
15
|
|
|
134
16
|
return new Proxy(this, {
|
|
135
|
-
get(target,
|
|
136
|
-
if (
|
|
137
|
-
if (
|
|
17
|
+
get(target, property) {
|
|
18
|
+
if (property in target) return target[property];
|
|
19
|
+
if (property === 'then') return undefined;
|
|
138
20
|
|
|
139
21
|
return async (...args) => {
|
|
140
22
|
await target._ready;
|
|
141
|
-
|
|
142
|
-
|
|
23
|
+
const value = target._instance[property];
|
|
24
|
+
if (typeof value !== 'function') {
|
|
25
|
+
throw new Error(`Method ${String(property)} does not exist on OSuite.`);
|
|
143
26
|
}
|
|
144
|
-
return target._instance
|
|
27
|
+
return value.apply(target._instance, args);
|
|
145
28
|
};
|
|
146
29
|
},
|
|
147
30
|
});
|
|
148
31
|
}
|
|
149
32
|
|
|
150
|
-
static async create(
|
|
33
|
+
static async create(options) {
|
|
151
34
|
const mod = await loadModule();
|
|
152
|
-
return new mod.OSuite(
|
|
35
|
+
return new mod.OSuite(options);
|
|
153
36
|
}
|
|
154
37
|
}
|
|
155
38
|
|
|
@@ -163,17 +46,24 @@ class ApprovalDeniedError extends Error {
|
|
|
163
46
|
|
|
164
47
|
class GuardBlockedError extends Error {
|
|
165
48
|
constructor(decision) {
|
|
166
|
-
super(decision.reason || 'Action blocked by policy');
|
|
49
|
+
super((decision && decision.reason) || 'Action blocked by policy');
|
|
167
50
|
this.name = 'GuardBlockedError';
|
|
168
51
|
this.decision = decision;
|
|
169
52
|
}
|
|
170
53
|
}
|
|
171
54
|
|
|
55
|
+
async function buildReviewSurface(...args) {
|
|
56
|
+
const mod = await loadModule();
|
|
57
|
+
return mod.buildReviewSurface(...args);
|
|
58
|
+
}
|
|
59
|
+
|
|
172
60
|
module.exports = {
|
|
173
|
-
OSuite: OSuiteProxy,
|
|
174
|
-
DashClaw: OSuiteProxy,
|
|
175
61
|
ApprovalDeniedError,
|
|
62
|
+
DashClaw: OSuiteProxy,
|
|
176
63
|
GuardBlockedError,
|
|
177
|
-
|
|
178
|
-
|
|
64
|
+
OpenClawAgent: OSuiteProxy,
|
|
65
|
+
OSuite: OSuiteProxy,
|
|
66
|
+
Osuite: OSuiteProxy,
|
|
67
|
+
buildReviewSurface,
|
|
68
|
+
default: OSuiteProxy,
|
|
179
69
|
};
|
package/legacy/index-v1.cjs
CHANGED
|
@@ -1,91 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
* OSuite SDK v1 (Legacy): CommonJS compatibility wrapper.
|
|
3
|
-
* For ESM: import { OSuite } from 'osuite/legacy'
|
|
4
|
-
* For CJS: const { OSuite } = require('osuite/legacy')
|
|
5
|
-
*/
|
|
1
|
+
'use strict';
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
async function loadModule() {
|
|
10
|
-
if (!_module) {
|
|
11
|
-
_module = await import('./osuite-v1.js');
|
|
12
|
-
}
|
|
13
|
-
return _module;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Re-export via dynamic import (CJS → ESM bridge)
|
|
17
|
-
module.exports = new Proxy({}, {
|
|
18
|
-
get(target, prop) {
|
|
19
|
-
if (prop === '__esModule') return true;
|
|
20
|
-
if (prop === 'then') return undefined; // Prevent Promise-like behavior
|
|
21
|
-
|
|
22
|
-
// Return a lazy-loading constructor wrapper
|
|
23
|
-
if (prop === 'GuardBlockedError') {
|
|
24
|
-
const Placeholder = class GuardBlockedError extends Error {
|
|
25
|
-
constructor(decision) {
|
|
26
|
-
const reasons = (decision.reasons || []).join('; ') || 'no reason';
|
|
27
|
-
super(`Guard blocked action: ${decision.decision}. Reasons: ${reasons}`);
|
|
28
|
-
this.name = 'GuardBlockedError';
|
|
29
|
-
this.decision = decision.decision;
|
|
30
|
-
this.reasons = decision.reasons || [];
|
|
31
|
-
this.warnings = decision.warnings || [];
|
|
32
|
-
this.matchedPolicies = decision.matched_policies || [];
|
|
33
|
-
this.riskScore = decision.risk_score ?? null;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// Support instanceof across ESM/CJS boundary
|
|
38
|
-
loadModule().then(m => {
|
|
39
|
-
if (m.GuardBlockedError) {
|
|
40
|
-
Object.defineProperty(Placeholder, Symbol.hasInstance, {
|
|
41
|
-
value: (instance) => instance && (instance.name === 'GuardBlockedError' || instance instanceof m.GuardBlockedError)
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return Placeholder;
|
|
47
|
-
}
|
|
48
|
-
if (prop === 'OSuite' || prop === 'DashClaw' || prop === 'OpenClawAgent' || prop === 'default') {
|
|
49
|
-
return class OSuiteProxy {
|
|
50
|
-
constructor(opts) {
|
|
51
|
-
this._opts = opts;
|
|
52
|
-
this._ready = loadModule().then(m => {
|
|
53
|
-
const Cls = m.OSuite || m.DashClaw || m.default;
|
|
54
|
-
this._instance = new Cls(opts);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Return a proxy that forwards all method calls to the async instance
|
|
58
|
-
return new Proxy(this, {
|
|
59
|
-
get(target, prop) {
|
|
60
|
-
if (prop in target) return target[prop];
|
|
61
|
-
if (prop === 'then') return undefined;
|
|
62
|
-
|
|
63
|
-
return async (...args) => {
|
|
64
|
-
await target._ready;
|
|
65
|
-
if (!target._instance[prop]) {
|
|
66
|
-
throw new Error(`Method ${String(prop)} does not exist on OSuite`);
|
|
67
|
-
}
|
|
68
|
-
return target._instance[prop](...args);
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// For synchronous construction, use OSuite.create()
|
|
75
|
-
static async create(opts) {
|
|
76
|
-
const mod = await loadModule();
|
|
77
|
-
const Cls = mod.OSuite || mod.DashClaw || mod.default;
|
|
78
|
-
return new Cls(opts);
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return undefined;
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Preferred: async factory
|
|
87
|
-
module.exports.create = async function create(opts) {
|
|
88
|
-
const mod = await loadModule();
|
|
89
|
-
const Cls = mod.OSuite || mod.DashClaw || mod.default;
|
|
90
|
-
return new Cls(opts);
|
|
91
|
-
};
|
|
3
|
+
module.exports = require('../index.cjs');
|
package/legacy/osuite-v1.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default,
|
|
1
|
+
export { default, OSuite, OpenClawAgent, GuardBlockedError, ApprovalDeniedError } from './osuite-v1-runtime.js';
|