rolexjs 1.5.0-dev-20260317103808 → 1.6.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/README.md +347 -97
- package/dist/index.d.ts +269 -23
- package/dist/index.js +681 -333
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,159 +1,409 @@
|
|
|
1
1
|
# rolexjs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Stateless API + Render layer for RoleX — the AI Agent Role Management Framework.
|
|
4
4
|
|
|
5
|
-
`rolexjs`
|
|
5
|
+
`rolexjs` is the integration layer that sits between core concept definitions and I/O adapters (MCP, CLI). It provides:
|
|
6
|
+
|
|
7
|
+
- **Rolex** class — stateless API with 24 operations
|
|
8
|
+
- **Render** functions — shared description & hint templates
|
|
9
|
+
- **Feature** types — Gherkin parse/serialize
|
|
6
10
|
|
|
7
11
|
## Install
|
|
8
12
|
|
|
9
13
|
```bash
|
|
10
|
-
bun add rolexjs
|
|
14
|
+
bun add rolexjs
|
|
11
15
|
```
|
|
12
16
|
|
|
13
17
|
## Quick Start
|
|
14
18
|
|
|
15
19
|
```typescript
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
20
|
+
import { Rolex, describe, hint } from "rolexjs";
|
|
21
|
+
import { createGraphRuntime } from "@rolexjs/local-platform";
|
|
22
|
+
|
|
23
|
+
const rolex = new Rolex({ runtime: createGraphRuntime() });
|
|
24
|
+
|
|
25
|
+
// Born an individual
|
|
26
|
+
const result = rolex.born("Feature: I am Sean");
|
|
27
|
+
console.log(describe("born", "Sean", result.state));
|
|
28
|
+
// → Individual "Sean" is born.
|
|
29
|
+
console.log(hint("born"));
|
|
30
|
+
// → Next: hire into an organization, or activate to start working.
|
|
31
|
+
```
|
|
18
32
|
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
@rolexjs/system → primitives (Structure, State, Runtime)
|
|
37
|
+
@rolexjs/core → concept definitions (19 structures, 24 processes)
|
|
38
|
+
@rolexjs/parser → Gherkin parser (wraps @cucumber/gherkin)
|
|
39
|
+
rolexjs → stateless API + render + Feature types ← you are here
|
|
40
|
+
@rolexjs/local-platform → graph-backed Runtime (graphology)
|
|
41
|
+
MCP / CLI → I/O adapters (state management, sessions)
|
|
42
|
+
```
|
|
21
43
|
|
|
22
|
-
|
|
23
|
-
const role = await rx.individual.activate({ individual: "sean" });
|
|
44
|
+
## Stateless Design
|
|
24
45
|
|
|
25
|
-
|
|
26
|
-
await role.want("Feature: Build Auth", "build-auth");
|
|
27
|
-
await role.plan("Feature: JWT Strategy", "jwt-plan");
|
|
28
|
-
await role.todo("Feature: Implement Login", "login");
|
|
29
|
-
await role.finish("login", "Feature: Login done\n Scenario: OK\n Given login\n Then success");
|
|
46
|
+
Rolex is stateless. Every method takes explicit node references and returns a `RolexResult`. There is no name registry, no active role, no session — those are the I/O layer's responsibility.
|
|
30
47
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
48
|
+
```typescript
|
|
49
|
+
interface RolexResult {
|
|
50
|
+
state: State; // projection of the primary affected node
|
|
51
|
+
process: string; // which process was executed (for render)
|
|
52
|
+
}
|
|
34
53
|
```
|
|
35
54
|
|
|
36
|
-
|
|
55
|
+
The caller (MCP/CLI) holds references to nodes and passes them into each call.
|
|
37
56
|
|
|
38
|
-
|
|
57
|
+
## API Reference
|
|
39
58
|
|
|
40
|
-
###
|
|
59
|
+
### Constructor
|
|
41
60
|
|
|
42
61
|
```typescript
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
const rolex = new Rolex({ runtime: Runtime });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Creates a new Rolex instance. Bootstraps two root nodes:
|
|
45
66
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
await rx.society.found({ id: "dp", content: "Feature: Deepractice" });
|
|
67
|
+
- `rolex.society` — root of the world
|
|
68
|
+
- `rolex.past` — container for archived things
|
|
49
69
|
|
|
50
|
-
|
|
51
|
-
await rx.org.hire({ org: "dp", individual: "alice" });
|
|
52
|
-
await rx.org.establish({ id: "cto", content: "Feature: CTO" });
|
|
70
|
+
### Lifecycle — Creation
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
await rx.position.appoint({ position: "cto", individual: "alice" });
|
|
56
|
-
await rx.position.charge({ position: "cto", content: "Feature: Lead engineering", id: "lead-eng" });
|
|
72
|
+
#### `born(source?: string): RolexResult`
|
|
57
73
|
|
|
58
|
-
|
|
59
|
-
await rx.org.launch({ id: "rolex", content: "Feature: RoleX" });
|
|
74
|
+
Born an individual into society. Auto-scaffolds `identity` and `knowledge` sub-branches.
|
|
60
75
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
76
|
+
```typescript
|
|
77
|
+
const sean = rolex.born("Feature: I am Sean\n As a backend architect...");
|
|
78
|
+
// sean.state.type === "individual"
|
|
79
|
+
// sean.state.children → [identity, knowledge]
|
|
64
80
|
```
|
|
65
81
|
|
|
66
|
-
|
|
82
|
+
#### `found(source?: string): RolexResult`
|
|
83
|
+
|
|
84
|
+
Found an organization.
|
|
67
85
|
|
|
68
86
|
```typescript
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
const org = rolex.found("Feature: Deepractice\n A software company...");
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### `establish(org: Structure, source?: string): RolexResult`
|
|
71
91
|
|
|
72
|
-
|
|
73
|
-
|
|
92
|
+
Establish a position within an organization.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const pos = rolex.establish(orgNode, "Feature: Architect\n Technical leadership...");
|
|
74
96
|
```
|
|
75
97
|
|
|
76
|
-
|
|
98
|
+
#### `charter(org: Structure, source: string): RolexResult`
|
|
99
|
+
|
|
100
|
+
Define the charter (rules and mission) for an organization.
|
|
77
101
|
|
|
78
102
|
```typescript
|
|
79
|
-
|
|
80
|
-
const response = await rx.rpc({
|
|
81
|
-
jsonrpc: "2.0",
|
|
82
|
-
method: "org.hire",
|
|
83
|
-
params: { org: "acme", individual: "alice" },
|
|
84
|
-
id: 1,
|
|
85
|
-
});
|
|
103
|
+
rolex.charter(orgNode, "Feature: Company Charter\n ...");
|
|
86
104
|
```
|
|
87
105
|
|
|
88
|
-
|
|
106
|
+
#### `charge(position: Structure, source: string): RolexResult`
|
|
107
|
+
|
|
108
|
+
Add a duty to a position.
|
|
89
109
|
|
|
90
110
|
```typescript
|
|
91
|
-
|
|
92
|
-
const { tools, instructions } = rx.protocol;
|
|
93
|
-
for (const tool of tools) {
|
|
94
|
-
register(tool.name, tool.description, tool.params);
|
|
95
|
-
}
|
|
111
|
+
rolex.charge(posNode, "Feature: Code Review\n Scenario: Review all PRs...");
|
|
96
112
|
```
|
|
97
113
|
|
|
98
|
-
|
|
114
|
+
### Lifecycle — Archival
|
|
99
115
|
|
|
100
|
-
|
|
116
|
+
All archival methods move the node to `past` and remove it from the active tree.
|
|
101
117
|
|
|
102
|
-
|
|
118
|
+
#### `retire(individual: Structure): RolexResult`
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
|--------|-------------|
|
|
106
|
-
| `role.focus(goalId?)` | View or switch focused goal |
|
|
107
|
-
| `role.want(goal, id)` | Declare a goal |
|
|
108
|
-
| `role.plan(plan, id)` | Create a plan for the focused goal |
|
|
109
|
-
| `role.todo(task, id)` | Add a task to the focused plan |
|
|
110
|
-
| `role.finish(taskId, encounter?)` | Complete a task, optionally record encounter |
|
|
111
|
-
| `role.complete(planId?, encounter?)` | Close a plan as done |
|
|
112
|
-
| `role.abandon(planId?, encounter?)` | Drop a plan |
|
|
120
|
+
Retire an individual (can rehire later).
|
|
113
121
|
|
|
114
|
-
|
|
122
|
+
#### `die(individual: Structure): RolexResult`
|
|
115
123
|
|
|
116
|
-
|
|
117
|
-
|--------|-------------|
|
|
118
|
-
| `role.reflect(encounterIds, experience?, id?)` | Consume encounters into experience |
|
|
119
|
-
| `role.realize(experienceIds, principle?, id?)` | Consume experiences into principle |
|
|
120
|
-
| `role.master(procedure, id?, experienceIds?)` | Create procedure, optionally consuming experiences |
|
|
124
|
+
An individual dies (permanent).
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
#### `dissolve(org: Structure): RolexResult`
|
|
123
127
|
|
|
124
|
-
|
|
125
|
-
|--------|-------------|
|
|
126
|
-
| `role.forget(nodeId)` | Remove a node under this individual |
|
|
127
|
-
| `role.skill(locator)` | Load full skill content by locator |
|
|
128
|
-
| `role.use(locator, args?)` | Subjective execution — `!ns.method` or ResourceX |
|
|
128
|
+
Dissolve an organization.
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
#### `abolish(position: Structure): RolexResult`
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|--------|-------------|
|
|
134
|
-
| `role.project()` | Render the individual's full state tree |
|
|
135
|
-
| `role.snapshot()` | Serialize cursors + cognitive state |
|
|
136
|
-
| `role.restore(snapshot)` | Restore from a snapshot |
|
|
132
|
+
Abolish a position.
|
|
137
133
|
|
|
138
|
-
|
|
134
|
+
#### `rehire(pastNode: Structure): RolexResult`
|
|
135
|
+
|
|
136
|
+
Rehire a retired individual from past. Creates a fresh individual with the same information.
|
|
139
137
|
|
|
140
138
|
```typescript
|
|
141
|
-
const
|
|
142
|
-
|
|
139
|
+
const retired = rolex.retire(seanNode);
|
|
140
|
+
// later...
|
|
141
|
+
const back = rolex.rehire(retiredNode);
|
|
142
|
+
```
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
### Organization — Membership & Appointment
|
|
145
|
+
|
|
146
|
+
These methods create/remove cross-branch **relations** (links between nodes that are not parent-child).
|
|
147
|
+
|
|
148
|
+
#### `hire(org: Structure, individual: Structure): RolexResult`
|
|
149
|
+
|
|
150
|
+
Link an individual to an organization via `membership`.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
rolex.hire(orgNode, seanNode);
|
|
146
154
|
```
|
|
147
155
|
|
|
148
|
-
|
|
156
|
+
#### `fire(org: Structure, individual: Structure): RolexResult`
|
|
157
|
+
|
|
158
|
+
Remove the membership link.
|
|
159
|
+
|
|
160
|
+
#### `appoint(position: Structure, individual: Structure): RolexResult`
|
|
161
|
+
|
|
162
|
+
Link an individual to a position via `appointment`.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
rolex.appoint(posNode, seanNode);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### `dismiss(position: Structure, individual: Structure): RolexResult`
|
|
169
|
+
|
|
170
|
+
Remove the appointment link.
|
|
171
|
+
|
|
172
|
+
### Role — Activation
|
|
173
|
+
|
|
174
|
+
#### `activate(individual: Structure): RolexResult`
|
|
175
|
+
|
|
176
|
+
Pure projection — projects an individual's full state without mutation. Used to "load" a role.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
const role = rolex.activate(seanNode);
|
|
180
|
+
// role.state contains the full subtree + relations
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Execution — Goal Pursuit
|
|
184
|
+
|
|
185
|
+
#### `want(individual: Structure, source?: string): RolexResult`
|
|
186
|
+
|
|
187
|
+
Declare a goal under an individual.
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const goal = rolex.want(seanNode, "Feature: Build Auth System\n ...");
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### `plan(goal: Structure, source?: string): RolexResult`
|
|
194
|
+
|
|
195
|
+
Create a plan for a goal.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const p = rolex.plan(goalNode, "Feature: Auth Plan\n Scenario: Phase 1...");
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### `todo(plan: Structure, source?: string): RolexResult`
|
|
202
|
+
|
|
203
|
+
Add a task to a plan.
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const t = rolex.todo(planNode, "Feature: Implement JWT\n ...");
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### `finish(task: Structure, individual: Structure, experience?: string): RolexResult`
|
|
210
|
+
|
|
211
|
+
Finish a task. Removes the task and creates an `encounter` under the individual.
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
rolex.finish(taskNode, seanNode, "Learned that JWT refresh is essential");
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### `achieve(goal: Structure, individual: Structure, experience?: string): RolexResult`
|
|
218
|
+
|
|
219
|
+
Achieve a goal. Removes the goal and creates an `encounter`.
|
|
220
|
+
|
|
221
|
+
#### `abandon(goal: Structure, individual: Structure, experience?: string): RolexResult`
|
|
222
|
+
|
|
223
|
+
Abandon a goal. Removes the goal and creates an `encounter`.
|
|
224
|
+
|
|
225
|
+
### Cognition — Learning
|
|
226
|
+
|
|
227
|
+
The cognition pipeline transforms raw encounters into structured knowledge:
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
encounter → reflect → experience → realize/master → principle/skill
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### `reflect(encounter: Structure, individual: Structure, source?: string): RolexResult`
|
|
234
|
+
|
|
235
|
+
Consume an encounter, create an `experience` under the individual.
|
|
236
|
+
|
|
237
|
+
#### `realize(experience: Structure, knowledge: Structure, source?: string): RolexResult`
|
|
238
|
+
|
|
239
|
+
Consume an experience, create a `principle` under knowledge.
|
|
240
|
+
|
|
241
|
+
#### `master(experience: Structure, knowledge: Structure, source?: string): RolexResult`
|
|
242
|
+
|
|
243
|
+
Consume an experience, create a `skill` under knowledge.
|
|
244
|
+
|
|
245
|
+
### Query
|
|
246
|
+
|
|
247
|
+
#### `project(node: Structure): State`
|
|
248
|
+
|
|
249
|
+
Project any node's full state (subtree + links). Returns `State` directly, not a `RolexResult`.
|
|
250
|
+
|
|
251
|
+
## Render
|
|
252
|
+
|
|
253
|
+
Standalone functions shared by MCP and CLI. The I/O layer just presents them.
|
|
254
|
+
|
|
255
|
+
### `describe(process, name, state): string`
|
|
256
|
+
|
|
257
|
+
What just happened — past tense description.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
describe("born", "Sean", state) // → 'Individual "Sean" is born.'
|
|
261
|
+
describe("want", "Auth", state) // → 'Goal "Auth" declared.'
|
|
262
|
+
describe("finish", "JWT", state) // → 'Task "JWT" finished → encounter recorded.'
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### `hint(process): string`
|
|
266
|
+
|
|
267
|
+
What to do next — suggestion prefixed with "Next: ".
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
hint("born") // → 'Next: hire into an organization, or activate to start working.'
|
|
271
|
+
hint("want") // → 'Next: plan how to achieve it.'
|
|
272
|
+
hint("finish") // → 'Next: continue with remaining tasks, or achieve the goal.'
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Feature (Gherkin)
|
|
149
276
|
|
|
277
|
+
Own types decoupled from `@cucumber/messages`. All `source` strings in Rolex are Gherkin Features.
|
|
278
|
+
|
|
279
|
+
### Types
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
interface Feature {
|
|
283
|
+
name: string;
|
|
284
|
+
description?: string;
|
|
285
|
+
tags?: string[];
|
|
286
|
+
scenarios: Scenario[];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
interface Scenario {
|
|
290
|
+
name: string;
|
|
291
|
+
description?: string;
|
|
292
|
+
tags?: string[];
|
|
293
|
+
steps: Step[];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
interface Step {
|
|
297
|
+
keyword: string; // "Given ", "When ", "Then ", "And "
|
|
298
|
+
text: string;
|
|
299
|
+
dataTable?: DataTableRow[];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
interface DataTableRow {
|
|
303
|
+
cells: string[];
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### `parse(source: string): Feature`
|
|
308
|
+
|
|
309
|
+
Parse a Gherkin source string into a Feature.
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { parse } from "rolexjs";
|
|
313
|
+
|
|
314
|
+
const feature = parse(`
|
|
315
|
+
Feature: User Authentication
|
|
316
|
+
As a user I want secure login
|
|
317
|
+
|
|
318
|
+
Scenario: Login with email
|
|
319
|
+
Given a registered user
|
|
320
|
+
When they submit credentials
|
|
321
|
+
Then they receive a token
|
|
322
|
+
`);
|
|
323
|
+
|
|
324
|
+
feature.name // → "User Authentication"
|
|
325
|
+
feature.description // → "As a user I want secure login"
|
|
326
|
+
feature.scenarios // → [{ name: "Login with email", steps: [...] }]
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### `serialize(feature: Feature): string`
|
|
330
|
+
|
|
331
|
+
Serialize a Feature back to Gherkin source.
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { serialize } from "rolexjs";
|
|
335
|
+
|
|
336
|
+
const source = serialize({
|
|
337
|
+
name: "My Goal",
|
|
338
|
+
scenarios: [{
|
|
339
|
+
name: "Success",
|
|
340
|
+
steps: [
|
|
341
|
+
{ keyword: "Given ", text: "the system is ready" },
|
|
342
|
+
{ keyword: "Then ", text: "it should work" },
|
|
343
|
+
],
|
|
344
|
+
}],
|
|
345
|
+
});
|
|
346
|
+
// → "Feature: My Goal\n\n Scenario: Success\n Given the system is ready\n Then it should work\n"
|
|
150
347
|
```
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
348
|
+
|
|
349
|
+
## Re-exports
|
|
350
|
+
|
|
351
|
+
`rolexjs` re-exports everything from `@rolexjs/core`:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import {
|
|
355
|
+
// Structure definitions
|
|
356
|
+
society, individual, organization, past,
|
|
357
|
+
identity, knowledge, goal, plan, task,
|
|
358
|
+
encounter, experience, principle, skill,
|
|
359
|
+
// ... and all process definitions
|
|
360
|
+
} from "rolexjs";
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Full Example
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
import { Rolex, describe, hint } from "rolexjs";
|
|
367
|
+
import { createGraphRuntime } from "@rolexjs/local-platform";
|
|
368
|
+
|
|
369
|
+
const rolex = new Rolex({ runtime: createGraphRuntime() });
|
|
370
|
+
|
|
371
|
+
// 1. Born an individual
|
|
372
|
+
const { state: seanState } = rolex.born("Feature: I am Sean");
|
|
373
|
+
const seanNode = seanState.ref; // caller tracks Structure references
|
|
374
|
+
|
|
375
|
+
// 2. Found org + establish position
|
|
376
|
+
const { state: orgState } = rolex.found("Feature: Deepractice");
|
|
377
|
+
const orgNode = orgState.ref;
|
|
378
|
+
const { state: posState } = rolex.establish(orgNode, "Feature: Architect");
|
|
379
|
+
const posNode = posState.ref;
|
|
380
|
+
|
|
381
|
+
// 3. Hire + appoint
|
|
382
|
+
rolex.hire(orgNode, seanNode);
|
|
383
|
+
rolex.appoint(posNode, seanNode);
|
|
384
|
+
|
|
385
|
+
// 4. Activate (pure projection)
|
|
386
|
+
const role = rolex.activate(seanNode);
|
|
387
|
+
console.log(describe("activate", "Sean", role.state));
|
|
388
|
+
// → Role "Sean" activated.
|
|
389
|
+
console.log(hint("activate"));
|
|
390
|
+
// → Next: want a goal, or check the current state.
|
|
391
|
+
|
|
392
|
+
// 5. Goal → plan → task
|
|
393
|
+
const { state: goalState } = rolex.want(seanNode, "Feature: Build Auth");
|
|
394
|
+
const goalNode = goalState.ref;
|
|
395
|
+
const { state: planState } = rolex.plan(goalNode, "Feature: Auth Plan");
|
|
396
|
+
const planNode = planState.ref;
|
|
397
|
+
const { state: taskState } = rolex.todo(planNode, "Feature: Implement JWT");
|
|
398
|
+
const taskNode = taskState.ref;
|
|
399
|
+
|
|
400
|
+
// 6. Finish → reflect → realize
|
|
401
|
+
const { state: encState } = rolex.finish(taskNode, seanNode, "JWT refresh is essential");
|
|
402
|
+
const encNode = encState.ref;
|
|
403
|
+
const { state: expState } = rolex.reflect(encNode, seanNode);
|
|
404
|
+
const expNode = expState.ref;
|
|
405
|
+
const knowledgeNode = /* sean's knowledge child */;
|
|
406
|
+
rolex.realize(expNode, knowledgeNode, "Always use refresh token rotation");
|
|
157
407
|
```
|
|
158
408
|
|
|
159
409
|
## License
|