@rolexjs/prototype 1.4.0 → 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/dist/index.js CHANGED
@@ -1,466 +1,3 @@
1
- // src/apply.ts
2
- async function applyPrototype(data, repo, direct) {
3
- const sorted = [...data.migrations].sort((a, b) => a.version - b.version);
4
- let applied = 0;
5
- let skipped = 0;
6
- for (const migration of sorted) {
7
- if (await repo.hasMigration(data.id, migration.id)) {
8
- skipped++;
9
- continue;
10
- }
11
- for (const instr of migration.instructions) {
12
- await direct(instr.op, instr.args);
13
- }
14
- await repo.recordMigration(data.id, migration.id, migration.version, migration.checksum);
15
- applied++;
16
- }
17
- await repo.settle(data.id, data.source);
18
- return {
19
- prototypeId: data.id,
20
- applied,
21
- skipped,
22
- upToDate: applied === 0
23
- };
24
- }
25
-
26
- // src/commands.ts
27
- import * as C from "@rolexjs/core";
28
- import { parse } from "@rolexjs/parser";
29
- import { structure } from "@rolexjs/system";
30
- function createCommands(ctx) {
31
- const { rt, society, past: past2, resolve, resourcex, issuex } = ctx;
32
- async function ok(node, process) {
33
- return { state: await rt.project(node), process };
34
- }
35
- async function archive(node, process) {
36
- const target = structure(node.name, node.description ?? "", C.past);
37
- const archived = await rt.transform(node, target);
38
- return ok(archived, process);
39
- }
40
- function validateGherkin(source) {
41
- if (!source) return;
42
- try {
43
- parse(source);
44
- } catch (e) {
45
- throw new Error(`Invalid Gherkin: ${e.message}`);
46
- }
47
- }
48
- function findInState(state, target) {
49
- if (state.id && state.id.toLowerCase() === target) return state;
50
- if (state.alias) {
51
- for (const a of state.alias) {
52
- if (a.toLowerCase() === target) return state;
53
- }
54
- }
55
- for (const child of state.children ?? []) {
56
- const found = findInState(child, target);
57
- if (found) return found;
58
- }
59
- return null;
60
- }
61
- async function removeExisting(parent, id) {
62
- const state = await rt.project(parent);
63
- const existing = findInState(state, id);
64
- if (existing) await rt.remove(existing);
65
- }
66
- function requireResourceX() {
67
- if (!resourcex) throw new Error("ResourceX is not available.");
68
- return resourcex;
69
- }
70
- function requireIssueX() {
71
- if (!issuex) throw new Error("IssueX is not available.");
72
- return issuex;
73
- }
74
- return {
75
- // ---- Individual: lifecycle ----
76
- async "individual.born"(content, id, alias) {
77
- validateGherkin(content);
78
- const node = await rt.create(society, C.individual, content, id, alias);
79
- await rt.create(node, C.identity, void 0, `${id}-identity`);
80
- return ok(node, "born");
81
- },
82
- async "individual.retire"(individual2) {
83
- return archive(await resolve(individual2), "retire");
84
- },
85
- async "individual.die"(individual2) {
86
- return archive(await resolve(individual2), "die");
87
- },
88
- async "individual.rehire"(pastNode) {
89
- const node = await resolve(pastNode);
90
- const ind = await rt.transform(node, C.individual);
91
- return ok(ind, "rehire");
92
- },
93
- // ---- Individual: external injection ----
94
- async "individual.teach"(individual2, principle2, id) {
95
- validateGherkin(principle2);
96
- const parent = await resolve(individual2);
97
- if (id) await removeExisting(parent, id);
98
- const node = await rt.create(parent, C.principle, principle2, id);
99
- return ok(node, "teach");
100
- },
101
- async "individual.train"(individual2, procedure2, id) {
102
- validateGherkin(procedure2);
103
- const parent = await resolve(individual2);
104
- if (id) await removeExisting(parent, id);
105
- const node = await rt.create(parent, C.procedure, procedure2, id);
106
- return ok(node, "train");
107
- },
108
- // ---- Role: focus ----
109
- async "role.focus"(goal2) {
110
- return ok(await resolve(goal2), "focus");
111
- },
112
- // ---- Role: execution ----
113
- async "role.want"(individual2, goal2, id, alias) {
114
- validateGherkin(goal2);
115
- const node = await rt.create(await resolve(individual2), C.goal, goal2, id, alias);
116
- return ok(node, "want");
117
- },
118
- async "role.plan"(goal2, plan2, id, after, fallback) {
119
- validateGherkin(plan2);
120
- const node = await rt.create(await resolve(goal2), C.plan, plan2, id);
121
- if (after) await rt.link(node, await resolve(after), "after", "before");
122
- if (fallback) await rt.link(node, await resolve(fallback), "fallback-for", "fallback");
123
- return ok(node, "plan");
124
- },
125
- async "role.todo"(plan2, task2, id, alias) {
126
- validateGherkin(task2);
127
- const node = await rt.create(await resolve(plan2), C.task, task2, id, alias);
128
- return ok(node, "todo");
129
- },
130
- async "role.finish"(task2, individual2, encounter2) {
131
- validateGherkin(encounter2);
132
- const taskNode = await resolve(task2);
133
- await rt.tag(taskNode, "done");
134
- if (encounter2) {
135
- const encId = taskNode.id ? `${taskNode.id}-finished` : void 0;
136
- const enc = await rt.create(await resolve(individual2), C.encounter, encounter2, encId);
137
- return ok(enc, "finish");
138
- }
139
- return ok(taskNode, "finish");
140
- },
141
- async "role.complete"(plan2, individual2, encounter2) {
142
- validateGherkin(encounter2);
143
- const planNode = await resolve(plan2);
144
- await rt.tag(planNode, "done");
145
- const encId = planNode.id ? `${planNode.id}-completed` : void 0;
146
- const enc = await rt.create(await resolve(individual2), C.encounter, encounter2, encId);
147
- return ok(enc, "complete");
148
- },
149
- async "role.abandon"(plan2, individual2, encounter2) {
150
- validateGherkin(encounter2);
151
- const planNode = await resolve(plan2);
152
- await rt.tag(planNode, "abandoned");
153
- const encId = planNode.id ? `${planNode.id}-abandoned` : void 0;
154
- const enc = await rt.create(await resolve(individual2), C.encounter, encounter2, encId);
155
- return ok(enc, "abandon");
156
- },
157
- // ---- Role: cognition ----
158
- async "role.reflect"(encounter2, individual2, experience2, id) {
159
- validateGherkin(experience2);
160
- if (encounter2) {
161
- const encNode = await resolve(encounter2);
162
- const exp2 = await rt.create(
163
- await resolve(individual2),
164
- C.experience,
165
- experience2 || encNode.information,
166
- id
167
- );
168
- await rt.remove(encNode);
169
- return ok(exp2, "reflect");
170
- }
171
- const exp = await rt.create(await resolve(individual2), C.experience, experience2, id);
172
- return ok(exp, "reflect");
173
- },
174
- async "role.realize"(experience2, individual2, principle2, id) {
175
- validateGherkin(principle2);
176
- if (experience2) {
177
- const expNode = await resolve(experience2);
178
- const prin2 = await rt.create(
179
- await resolve(individual2),
180
- C.principle,
181
- principle2 || expNode.information,
182
- id
183
- );
184
- await rt.remove(expNode);
185
- return ok(prin2, "realize");
186
- }
187
- const prin = await rt.create(await resolve(individual2), C.principle, principle2, id);
188
- return ok(prin, "realize");
189
- },
190
- async "role.master"(individual2, procedure2, id, experience2) {
191
- validateGherkin(procedure2);
192
- const parent = await resolve(individual2);
193
- if (id) await removeExisting(parent, id);
194
- const proc = await rt.create(parent, C.procedure, procedure2, id);
195
- if (experience2) await rt.remove(await resolve(experience2));
196
- return ok(proc, "master");
197
- },
198
- // ---- Role: knowledge management ----
199
- async "role.forget"(nodeId) {
200
- const node = await resolve(nodeId);
201
- await rt.remove(node);
202
- return { state: { ...node, children: [] }, process: "forget" };
203
- },
204
- // ---- Role: skill ----
205
- async "role.skill"(locator) {
206
- const rx = requireResourceX();
207
- const content = await rx.ingest(locator);
208
- const text = typeof content === "string" ? content : JSON.stringify(content, null, 2);
209
- try {
210
- const rxm = await rx.info(locator);
211
- return `${formatRXM(rxm)}
212
-
213
- ${text}`;
214
- } catch {
215
- return text;
216
- }
217
- },
218
- // ---- Project ----
219
- async "project.launch"(content, id, alias, org) {
220
- validateGherkin(content);
221
- const node = await rt.create(society, C.project, content, id, alias);
222
- if (org) await rt.link(node, await resolve(org), "ownership", "project");
223
- return ok(node, "launch");
224
- },
225
- async "project.scope"(project2, scope2, id) {
226
- validateGherkin(scope2);
227
- const node = await rt.create(await resolve(project2), C.scope, scope2, id);
228
- return ok(node, "scope");
229
- },
230
- async "project.milestone"(project2, milestone2, id) {
231
- validateGherkin(milestone2);
232
- const node = await rt.create(await resolve(project2), C.milestone, milestone2, id);
233
- return ok(node, "milestone");
234
- },
235
- async "project.achieve"(milestone2) {
236
- const node = await resolve(milestone2);
237
- await rt.tag(node, "done");
238
- return ok(node, "achieve");
239
- },
240
- async "project.enroll"(project2, individual2) {
241
- const projNode = await resolve(project2);
242
- await rt.link(projNode, await resolve(individual2), "participation", "participate");
243
- return ok(projNode, "enroll");
244
- },
245
- async "project.remove"(project2, individual2) {
246
- const projNode = await resolve(project2);
247
- await rt.unlink(projNode, await resolve(individual2), "participation", "participate");
248
- return ok(projNode, "remove");
249
- },
250
- async "project.deliver"(project2, deliverable2, id) {
251
- validateGherkin(deliverable2);
252
- const node = await rt.create(await resolve(project2), C.deliverable, deliverable2, id);
253
- return ok(node, "deliver");
254
- },
255
- async "project.wiki"(project2, wiki2, id) {
256
- validateGherkin(wiki2);
257
- const node = await rt.create(await resolve(project2), C.wiki, wiki2, id);
258
- return ok(node, "wiki");
259
- },
260
- async "project.archive"(project2) {
261
- return archive(await resolve(project2), "archive");
262
- },
263
- // ---- Org ----
264
- async "org.found"(content, id, alias) {
265
- validateGherkin(content);
266
- const node = await rt.create(society, C.organization, content, id, alias);
267
- return ok(node, "found");
268
- },
269
- async "org.charter"(org, charter2, id) {
270
- validateGherkin(charter2);
271
- const node = await rt.create(await resolve(org), C.charter, charter2, id);
272
- return ok(node, "charter");
273
- },
274
- async "org.dissolve"(org) {
275
- return archive(await resolve(org), "dissolve");
276
- },
277
- async "org.hire"(org, individual2) {
278
- const orgNode = await resolve(org);
279
- await rt.link(orgNode, await resolve(individual2), "membership", "belong");
280
- return ok(orgNode, "hire");
281
- },
282
- async "org.fire"(org, individual2) {
283
- const orgNode = await resolve(org);
284
- await rt.unlink(orgNode, await resolve(individual2), "membership", "belong");
285
- return ok(orgNode, "fire");
286
- },
287
- // ---- Position ----
288
- async "position.establish"(content, id, alias) {
289
- validateGherkin(content);
290
- const node = await rt.create(society, C.position, content, id, alias);
291
- return ok(node, "establish");
292
- },
293
- async "position.charge"(position2, duty2, id) {
294
- validateGherkin(duty2);
295
- const node = await rt.create(await resolve(position2), C.duty, duty2, id);
296
- return ok(node, "charge");
297
- },
298
- async "position.require"(position2, procedure2, id) {
299
- validateGherkin(procedure2);
300
- const parent = await resolve(position2);
301
- if (id) await removeExisting(parent, id);
302
- const node = await rt.create(parent, C.requirement, procedure2, id);
303
- return ok(node, "require");
304
- },
305
- async "position.abolish"(position2) {
306
- return archive(await resolve(position2), "abolish");
307
- },
308
- async "position.appoint"(position2, individual2) {
309
- const posNode = await resolve(position2);
310
- const indNode = await resolve(individual2);
311
- await rt.link(posNode, indNode, "appointment", "serve");
312
- const posState = await rt.project(posNode);
313
- for (const child of posState.children ?? []) {
314
- if (child.name !== "requirement" || !child.information) continue;
315
- await rt.create(indNode, C.procedure, child.information, child.id);
316
- }
317
- return ok(posNode, "appoint");
318
- },
319
- async "position.dismiss"(position2, individual2) {
320
- const posNode = await resolve(position2);
321
- await rt.unlink(posNode, await resolve(individual2), "appointment", "serve");
322
- return ok(posNode, "dismiss");
323
- },
324
- // ---- Census ----
325
- async "census.list"(type) {
326
- const target = type === "past" ? past2 : society;
327
- const state = await rt.project(target);
328
- const children = state.children ?? [];
329
- const filtered = type === "past" ? children : children.filter((c) => type ? c.name === type : c.name !== "past");
330
- return { state: { ...state, children: filtered }, process: "list" };
331
- },
332
- // ---- Resource (proxy to ResourceX) ----
333
- "resource.add"(path) {
334
- return requireResourceX().add(path);
335
- },
336
- "resource.search"(query) {
337
- return requireResourceX().search(query);
338
- },
339
- "resource.has"(locator) {
340
- return requireResourceX().has(locator);
341
- },
342
- "resource.info"(locator) {
343
- return requireResourceX().info(locator);
344
- },
345
- "resource.remove"(locator) {
346
- return requireResourceX().remove(locator);
347
- },
348
- "resource.push"(locator, options) {
349
- return requireResourceX().push(locator, options);
350
- },
351
- "resource.pull"(locator, options) {
352
- return requireResourceX().pull(locator, options);
353
- },
354
- "resource.clearCache"(registry) {
355
- return requireResourceX().clearCache(registry);
356
- },
357
- // ---- Issue (proxy to IssueX) ----
358
- async "issue.publish"(title, body, author, assignee) {
359
- const ix = requireIssueX();
360
- return ix.createIssue({ title, body, author, assignee });
361
- },
362
- async "issue.get"(number) {
363
- return requireIssueX().getIssueByNumber(number);
364
- },
365
- async "issue.list"(status, author, assignee, label) {
366
- const filter = {};
367
- if (status) filter.status = status;
368
- if (author) filter.author = author;
369
- if (assignee) filter.assignee = assignee;
370
- if (label) filter.label = label;
371
- return requireIssueX().listIssues(
372
- Object.keys(filter).length > 0 ? filter : void 0
373
- );
374
- },
375
- async "issue.update"(number, title, body, assignee) {
376
- const ix = requireIssueX();
377
- const issue = await ix.getIssueByNumber(number);
378
- if (!issue) throw new Error(`Issue #${number} not found.`);
379
- const patch = {};
380
- if (title !== void 0) patch.title = title;
381
- if (body !== void 0) patch.body = body;
382
- if (assignee !== void 0) patch.assignee = assignee;
383
- return ix.updateIssue(issue.id, patch);
384
- },
385
- async "issue.close"(number) {
386
- const ix = requireIssueX();
387
- const issue = await ix.getIssueByNumber(number);
388
- if (!issue) throw new Error(`Issue #${number} not found.`);
389
- return ix.closeIssue(issue.id);
390
- },
391
- async "issue.reopen"(number) {
392
- const ix = requireIssueX();
393
- const issue = await ix.getIssueByNumber(number);
394
- if (!issue) throw new Error(`Issue #${number} not found.`);
395
- return ix.reopenIssue(issue.id);
396
- },
397
- async "issue.assign"(number, assignee) {
398
- const ix = requireIssueX();
399
- const issue = await ix.getIssueByNumber(number);
400
- if (!issue) throw new Error(`Issue #${number} not found.`);
401
- return ix.updateIssue(issue.id, { assignee });
402
- },
403
- async "issue.comment"(number, body, author) {
404
- const ix = requireIssueX();
405
- const issue = await ix.getIssueByNumber(number);
406
- if (!issue) throw new Error(`Issue #${number} not found.`);
407
- return ix.createComment(issue.id, body, author);
408
- },
409
- async "issue.comments"(number) {
410
- const ix = requireIssueX();
411
- const issue = await ix.getIssueByNumber(number);
412
- if (!issue) throw new Error(`Issue #${number} not found.`);
413
- return ix.listComments(issue.id);
414
- },
415
- async "issue.label"(number, label) {
416
- const ix = requireIssueX();
417
- const issue = await ix.getIssueByNumber(number);
418
- if (!issue) throw new Error(`Issue #${number} not found.`);
419
- let labelObj = await ix.getLabelByName(label);
420
- if (!labelObj) labelObj = await ix.createLabel({ name: label });
421
- await ix.addLabel(issue.id, labelObj.id);
422
- return ix.getIssueByNumber(number);
423
- },
424
- async "issue.unlabel"(number, label) {
425
- const ix = requireIssueX();
426
- const issue = await ix.getIssueByNumber(number);
427
- if (!issue) throw new Error(`Issue #${number} not found.`);
428
- const labelObj = await ix.getLabelByName(label);
429
- if (!labelObj) throw new Error(`Label "${label}" not found.`);
430
- await ix.removeLabel(issue.id, labelObj.id);
431
- return ix.getIssueByNumber(number);
432
- }
433
- };
434
- }
435
- function formatRXM(rxm) {
436
- const lines = [`--- RXM: ${rxm.locator} ---`];
437
- const def2 = rxm.definition;
438
- if (def2) {
439
- if (def2.author) lines.push(`Author: ${def2.author}`);
440
- if (def2.description) lines.push(`Description: ${def2.description}`);
441
- }
442
- const source = rxm.source;
443
- if (source?.files) {
444
- lines.push("Files:");
445
- lines.push(renderFileTree(source.files, " "));
446
- }
447
- lines.push("---");
448
- return lines.join("\n");
449
- }
450
- function renderFileTree(files, indent = "") {
451
- const lines = [];
452
- for (const [name, value] of Object.entries(files)) {
453
- if (value && typeof value === "object" && !("size" in value)) {
454
- lines.push(`${indent}${name}`);
455
- lines.push(renderFileTree(value, `${indent} `));
456
- } else {
457
- const size = value?.size ? ` (${value.size} bytes)` : "";
458
- lines.push(`${indent}${name}${size}`);
459
- }
460
- }
461
- return lines.filter(Boolean).join("\n");
462
- }
463
-
464
1
  // src/descriptions/index.ts
465
2
  var processes = {
466
3
  "born": "Feature: born \u2014 create a new individual\n Create a new individual with persona identity.\n The persona defines who the role is \u2014 personality, values, background.\n\n Scenario: Birth an individual\n Given a Gherkin source describing the persona\n When born is called with the source\n Then a new individual node is created in society\n And the persona is stored as the individual's information\n And the individual can be hired into organizations\n And the individual can be activated to start working\n\n Scenario: Writing the individual Gherkin\n Given the individual Feature defines a persona \u2014 who this role is\n Then the Feature title names the individual\n And the description captures personality, values, expertise, and background\n And Scenarios are optional \u2014 use them for distinct aspects of the persona",
@@ -688,95 +225,6 @@ var world = {
688
225
  And this rule applies to end-user communication, not developer communication`,
689
226
  "execution": "Feature: Execution \u2014 the doing cycle\n The role pursues goals through a structured lifecycle.\n activate \u2192 want \u2192 plan \u2192 todo \u2192 finish \u2192 complete or abandon.\n\n Scenario: Declare a goal\n Given I know who I am via activate\n When I want something \u2014 a desired outcome\n Then I declare it with want(id, goal)\n And focus automatically switches to this new goal\n\n Scenario: Plan and create tasks\n Given I have a focused goal\n Then I call plan(id, plan) to break it into logical phases\n And I call todo(id, task) to create concrete, actionable tasks\n\n Scenario: Execute and finish\n Given I have tasks to work on\n When I complete a task\n Then I call finish(id) to mark it done\n And an encounter is created \u2014 a raw record of what happened\n And I optionally capture what happened via the encounter parameter\n\n Scenario: Complete or abandon a plan\n Given tasks are done or the plan's strategy is no longer viable\n When the plan is fulfilled I call complete()\n Or when the plan should be dropped I call abandon()\n Then an encounter is created for the cognition cycle\n\n Scenario: Goals are long-term directions\n Given goals are managed with want and forget\n When a goal is no longer needed\n Then I call forget to remove it\n And learning is captured at the plan and task level through encounters\n\n Scenario: Multiple goals\n Given I may have several active goals\n When I need to switch between them\n Then I call focus(id) to change the currently focused goal\n And subsequent plan and todo operations target the focused goal",
690
227
  "gherkin": 'Feature: Gherkin \u2014 the universal language\n Everything in RoleX is expressed as Gherkin Feature files.\n Gherkin is not just for testing \u2014 it is the language of identity, goals, and knowledge.\n\n Scenario: Feature and Scenario convention\n Given RoleX uses Gherkin to represent goals, plans, tasks, experience, and knowledge\n Then a Feature represents one independent concern \u2014 one topic, explained fully\n And Scenarios represent different situations or conditions within that concern\n And Given/When/Then provides narrative structure within each scenario\n\n Scenario: Writing Gherkin for RoleX\n Given the AI creates goals, plans, tasks, and experiences as Gherkin\n Then keep it descriptive and meaningful \u2014 living documentation, not test boilerplate\n And use Feature as the title \u2014 what this concern is about\n And use Scenario for specific situations within that concern\n And each Feature focuses on one concern \u2014 separate unrelated topics into their own Features\n\n Scenario: Valid step keywords\n Given the only valid step keywords are Given, When, Then, And, But\n When writing steps that express causality or explanation\n Then use And to chain the reason as a follow-up fact\n And example: "Then use RoleX tools" followed by "And RoleX tools feed the growth loop"\n\n Scenario: Expressing causality\n Given you want to write "Then X because Y"\n Then rewrite as two steps \u2014 "Then X" followed by "And Y" stating the reason as a fact',
691
- "issue": `Feature: Issue \u2014 persistent structured collaboration beyond a single context
692
- AI individuals face a fundamental challenge: context breaks.
693
- Each new session starts fresh \u2014 identity and knowledge survive, but the working state is lost.
694
- Like humans writing journals and memos, individuals need externalized records
695
- that persist across sessions and across individuals.
696
-
697
- Issue is the externalized, structured collaboration primitive of the RoleX world.
698
- It enables both self-collaboration (same individual, different sessions)
699
- and inter-individual collaboration (different individuals, asynchronous).
700
-
701
- Scenario: Why issues exist
702
- Given AI individuals have a context window limit
703
- And each new session loses the previous working state
704
- And multiple individuals may need to coordinate without being active simultaneously
705
- When structured, persistent, discoverable records are needed
706
- Then issues serve as externalized working memory for the society
707
- And they survive context breaks, session restarts, and individual switches
708
-
709
- Scenario: Self-collaboration \u2014 continuity across sessions
710
- Given an individual is working on something that spans multiple sessions
711
- When the context window resets or a new session begins
712
- Then the individual can publish or check issues to restore working context
713
- And comments serve as a journal \u2014 recording progress, decisions, and next steps
714
- And the issue persists until explicitly closed, regardless of how many sessions pass
715
-
716
- Scenario: Inter-individual collaboration \u2014 asynchronous coordination
717
- Given multiple individuals need to work together
718
- And they are never active simultaneously
719
- When one individual publishes an issue or leaves a comment
720
- Then other individuals can discover it, respond, and contribute
721
- And assignee indicates who should act next
722
- And labels categorize across concerns
723
-
724
- Scenario: Relationship to goals and tasks
725
- Given goals express intent \u2014 what I want to achieve
726
- And tasks express action \u2014 what I am doing right now
727
- When an issue is something that needs ongoing attention and discussion
728
- Then issues may inspire goals, or goals may spawn issues
729
- And issues may be resolved by tasks, or tasks may surface new issues
730
- But issues are independent \u2014 they belong to the society, not to any single individual's goal tree
731
-
732
- Scenario: Publish a new issue
733
- Given I need to raise a topic for attention
734
- When I call use("!issue.publish", { title, body, author, assignee? })
735
- Then a new issue is created with an auto-incremented number
736
- And author should be the active individual's id
737
-
738
- Scenario: Browse and view issues
739
- Given I need to see what issues exist
740
- When I call use("!issue.list", { status?, author?, assignee?, label? })
741
- Then matching issues are returned ordered by number descending
742
- When I need details of a specific issue
743
- Then I call use("!issue.get", { number })
744
-
745
- Scenario: Update, close, and reopen
746
- Given I need to manage an issue's lifecycle
747
- When I call use("!issue.update", { number, title?, body?, assignee? })
748
- Then the specified fields are updated
749
- When resolved I call use("!issue.close", { number })
750
- And if it needs more work I call use("!issue.reopen", { number })
751
-
752
- Scenario: Assign and discuss
753
- Given I need to delegate or discuss
754
- When I call use("!issue.assign", { number, assignee })
755
- Then the issue is assigned to another individual
756
- When I call use("!issue.comment", { number, body, author })
757
- Then a comment is added to the threaded discussion
758
- And I can view all comments with use("!issue.comments", { number })
759
-
760
- Scenario: Label for categorization
761
- Given I want to categorize issues
762
- When I call use("!issue.label", { number, label })
763
- Then the label is attached \u2014 auto-created if new
764
- And I can remove it with use("!issue.unlabel", { number, label })
765
-
766
- Scenario: Command reference
767
- Given the following commands are available:
768
- | command | required args | optional args |
769
- | !issue.publish | title, body, author | assignee |
770
- | !issue.get | number | |
771
- | !issue.list | | status, author, assignee, label |
772
- | !issue.update | number | title, body, assignee |
773
- | !issue.close | number | |
774
- | !issue.reopen | number | |
775
- | !issue.assign | number, assignee | |
776
- | !issue.comment | number, body, author | |
777
- | !issue.comments | number | |
778
- | !issue.label | number, label | |
779
- | !issue.unlabel | number, label | |`,
780
228
  "memory": `Feature: Memory \u2014 when to reflect
781
229
  Reflection is how encounters become experience.
782
230
  The AI proactively reflects when it detects learning moments.
@@ -813,17 +261,16 @@ var world = {
813
261
  "use-protocol": `Feature: Use tool \u2014 the universal execution entry point
814
262
  The MCP use tool is how you execute ALL RoleX operations beyond the core MCP tools.
815
263
  Whenever you see use("...") or a !namespace.method pattern in skills or documentation,
816
- it is an instruction to call the MCP use tool with that command.
264
+ it is an instruction to call the MCP use tool with that locator.
817
265
 
818
266
  Scenario: How to read use instructions in skills
819
267
  Given a skill document contains use("!resource.add", { path: "..." })
820
- Then this means: call the MCP use tool with command "!resource.add" and path "..."
821
- And all named arguments are passed as flat top-level parameters alongside command
268
+ Then this means: call the MCP use tool with locator "!resource.add" and args { path: "..." }
822
269
  And always use the MCP use tool for RoleX operations
823
270
  And this applies to every use("...") pattern you encounter in any skill or documentation
824
271
 
825
272
  Scenario: ! prefix dispatches to RoleX runtime
826
- Given the command starts with !
273
+ Given the locator starts with !
827
274
  Then it is parsed as !namespace.method
828
275
  And dispatched to the corresponding RoleX API with named args
829
276
 
@@ -832,7 +279,7 @@ var world = {
832
279
  When you need to execute a command you have not seen in a loaded skill
833
280
  Then you MUST call skill(locator) first to load the full instructions
834
281
  And the loaded skill will tell you the exact command name and arguments
835
- And only then call use with the correct command and flat named parameters
282
+ And only then call use(!namespace.method, args) with the correct syntax
836
283
  And do not use commands from other roles' descriptions \u2014 only your own skills
837
284
 
838
285
  Scenario: NEVER guess commands
@@ -842,8 +289,8 @@ var world = {
842
289
  And call skill(locator) with the relevant procedure to learn the correct syntax
843
290
  And if no procedure covers this task, it is outside your duties \u2014 suggest Nuwa
844
291
 
845
- Scenario: Regular commands delegate to ResourceX
846
- Given the command does not start with !
292
+ Scenario: Regular locators delegate to ResourceX
293
+ Given the locator does not start with !
847
294
  Then it is treated as a ResourceX locator
848
295
  And resolved through the ResourceX ingest pipeline`
849
296
  };
@@ -869,7 +316,7 @@ var individualBorn = def(
869
316
  required: false,
870
317
  description: "Gherkin Feature source for the individual"
871
318
  },
872
- id: { type: "string", required: true, description: "User-facing identifier (kebab-case)" },
319
+ id: { type: "string", required: false, description: "User-facing identifier (kebab-case)" },
873
320
  alias: { type: "string[]", required: false, description: "Alternative names" }
874
321
  },
875
322
  ["content", "id", "alias"]
@@ -910,7 +357,7 @@ var individualTeach = def(
910
357
  },
911
358
  id: {
912
359
  type: "string",
913
- required: true,
360
+ required: false,
914
361
  description: "Principle id (keywords joined by hyphens)"
915
362
  }
916
363
  },
@@ -928,7 +375,7 @@ var individualTrain = def(
928
375
  },
929
376
  id: {
930
377
  type: "string",
931
- required: true,
378
+ required: false,
932
379
  description: "Procedure id (keywords joined by hyphens)"
933
380
  }
934
381
  },
@@ -964,7 +411,7 @@ var roleWant = def(
964
411
  required: false,
965
412
  description: "Gherkin Feature source describing the goal"
966
413
  },
967
- id: { type: "string", required: true, description: "Goal id (used for focus/reference)" },
414
+ id: { type: "string", required: false, description: "Goal id (used for focus/reference)" },
968
415
  alias: { type: "string[]", required: false, description: "Alternative names" }
969
416
  },
970
417
  ["individual", "goal", "id", "alias"]
@@ -979,7 +426,7 @@ var rolePlan = def(
979
426
  required: false,
980
427
  description: "Gherkin Feature source describing the plan"
981
428
  },
982
- id: { type: "string", required: true, description: "Plan id (keywords joined by hyphens)" },
429
+ id: { type: "string", required: false, description: "Plan id (keywords joined by hyphens)" },
983
430
  after: {
984
431
  type: "string",
985
432
  required: false,
@@ -1003,7 +450,7 @@ var roleTodo = def(
1003
450
  required: false,
1004
451
  description: "Gherkin Feature source describing the task"
1005
452
  },
1006
- id: { type: "string", required: true, description: "Task id (used for finish/reference)" },
453
+ id: { type: "string", required: false, description: "Task id (used for finish/reference)" },
1007
454
  alias: { type: "string[]", required: false, description: "Alternative names" }
1008
455
  },
1009
456
  ["plan", "task", "id", "alias"]
@@ -1063,7 +510,7 @@ var roleReflect = def(
1063
510
  },
1064
511
  id: {
1065
512
  type: "string",
1066
- required: true,
513
+ required: false,
1067
514
  description: "Experience id (keywords joined by hyphens)"
1068
515
  }
1069
516
  },
@@ -1082,7 +529,7 @@ var roleRealize = def(
1082
529
  },
1083
530
  id: {
1084
531
  type: "string",
1085
- required: true,
532
+ required: false,
1086
533
  description: "Principle id (keywords joined by hyphens)"
1087
534
  }
1088
535
  },
@@ -1100,7 +547,7 @@ var roleMaster = def(
1100
547
  },
1101
548
  id: {
1102
549
  type: "string",
1103
- required: true,
550
+ required: false,
1104
551
  description: "Procedure id (keywords joined by hyphens)"
1105
552
  },
1106
553
  experience: {
@@ -1137,7 +584,7 @@ var orgFound = def(
1137
584
  required: false,
1138
585
  description: "Gherkin Feature source for the organization"
1139
586
  },
1140
- id: { type: "string", required: true, description: "User-facing identifier (kebab-case)" },
587
+ id: { type: "string", required: false, description: "User-facing identifier (kebab-case)" },
1141
588
  alias: { type: "string[]", required: false, description: "Alternative names" }
1142
589
  },
1143
590
  ["content", "id", "alias"]
@@ -1152,7 +599,7 @@ var orgCharter = def(
1152
599
  required: true,
1153
600
  description: "Gherkin Feature source for the charter"
1154
601
  },
1155
- id: { type: "string", required: true, description: "Charter id" }
602
+ id: { type: "string", required: false, description: "Charter id" }
1156
603
  },
1157
604
  ["org", "content", "id"]
1158
605
  );
@@ -1191,7 +638,7 @@ var positionEstablish = def(
1191
638
  required: false,
1192
639
  description: "Gherkin Feature source for the position"
1193
640
  },
1194
- id: { type: "string", required: true, description: "User-facing identifier (kebab-case)" },
641
+ id: { type: "string", required: false, description: "User-facing identifier (kebab-case)" },
1195
642
  alias: { type: "string[]", required: false, description: "Alternative names" }
1196
643
  },
1197
644
  ["content", "id", "alias"]
@@ -1206,7 +653,7 @@ var positionCharge = def(
1206
653
  required: true,
1207
654
  description: "Gherkin Feature source for the duty"
1208
655
  },
1209
- id: { type: "string", required: true, description: "Duty id (keywords joined by hyphens)" }
656
+ id: { type: "string", required: false, description: "Duty id (keywords joined by hyphens)" }
1210
657
  },
1211
658
  ["position", "content", "id"]
1212
659
  );
@@ -1222,7 +669,7 @@ var positionRequire = def(
1222
669
  },
1223
670
  id: {
1224
671
  type: "string",
1225
- required: true,
672
+ required: false,
1226
673
  description: "Requirement id (keywords joined by hyphens)"
1227
674
  }
1228
675
  },
@@ -1263,7 +710,7 @@ var projectLaunch = def(
1263
710
  required: false,
1264
711
  description: "Gherkin Feature source for the project"
1265
712
  },
1266
- id: { type: "string", required: true, description: "User-facing identifier (kebab-case)" },
713
+ id: { type: "string", required: false, description: "User-facing identifier (kebab-case)" },
1267
714
  alias: { type: "string[]", required: false, description: "Alternative names" },
1268
715
  org: {
1269
716
  type: "string",
@@ -1283,7 +730,7 @@ var projectScope = def(
1283
730
  required: true,
1284
731
  description: "Gherkin Feature source for the scope"
1285
732
  },
1286
- id: { type: "string", required: true, description: "Scope id" }
733
+ id: { type: "string", required: false, description: "Scope id" }
1287
734
  },
1288
735
  ["project", "content", "id"]
1289
736
  );
@@ -1299,7 +746,7 @@ var projectMilestone = def(
1299
746
  },
1300
747
  id: {
1301
748
  type: "string",
1302
- required: true,
749
+ required: false,
1303
750
  description: "Milestone id (keywords joined by hyphens)"
1304
751
  }
1305
752
  },
@@ -1343,7 +790,7 @@ var projectDeliver = def(
1343
790
  },
1344
791
  id: {
1345
792
  type: "string",
1346
- required: true,
793
+ required: false,
1347
794
  description: "Deliverable id (keywords joined by hyphens)"
1348
795
  }
1349
796
  },
@@ -1361,7 +808,7 @@ var projectWiki = def(
1361
808
  },
1362
809
  id: {
1363
810
  type: "string",
1364
- required: true,
811
+ required: false,
1365
812
  description: "Wiki entry id (keywords joined by hyphens)"
1366
813
  }
1367
814
  },
@@ -1387,6 +834,18 @@ var censusList = def(
1387
834
  },
1388
835
  ["type"]
1389
836
  );
837
+ var prototypeSettle = def(
838
+ "prototype",
839
+ "settle",
840
+ {
841
+ source: {
842
+ type: "string",
843
+ required: true,
844
+ description: "ResourceX source \u2014 local path or locator"
845
+ }
846
+ },
847
+ ["source"]
848
+ );
1390
849
  var prototypeEvict = def(
1391
850
  "prototype",
1392
851
  "evict",
@@ -1611,6 +1070,7 @@ var instructions = {
1611
1070
  // census
1612
1071
  "census.list": censusList,
1613
1072
  // prototype
1073
+ "prototype.settle": prototypeSettle,
1614
1074
  "prototype.evict": prototypeEvict,
1615
1075
  // resource
1616
1076
  "resource.add": resourceAdd,
@@ -1663,260 +1123,520 @@ function resolveArg(entry, args) {
1663
1123
  return hasValue ? obj : void 0;
1664
1124
  }
1665
1125
 
1666
- // src/renderer.ts
1667
- var RendererRouter = class {
1668
- renderers = /* @__PURE__ */ new Map();
1669
- /** Register a renderer for a command namespace. */
1670
- register(namespace, renderer) {
1671
- this.renderers.set(namespace, renderer);
1672
- return this;
1126
+ // src/ops.ts
1127
+ import * as C from "@rolexjs/core";
1128
+ import { parse } from "@rolexjs/parser";
1129
+ function createOps(ctx) {
1130
+ const { rt, society, past: past2, resolve, resourcex, issuex } = ctx;
1131
+ async function ok(node, process) {
1132
+ return { state: await rt.project(node), process };
1673
1133
  }
1674
- /** Route a command to the appropriate renderer. */
1675
- render(command, result) {
1676
- const dot = command.indexOf(".");
1677
- const namespace = dot >= 0 ? command.slice(0, dot) : command;
1678
- const renderer = this.renderers.get(namespace);
1679
- if (renderer) return renderer.render(command, result);
1680
- return defaultRender(command, result);
1134
+ async function archive(node, process) {
1135
+ const archived = await rt.transform(node, C.past);
1136
+ return ok(archived, process);
1681
1137
  }
1682
- };
1683
- function defaultRender(_command, result) {
1684
- return JSON.stringify(result, null, 2);
1685
- }
1686
-
1687
- // src/tools.ts
1688
- var worldInstructions = Object.values(world).join("\n\n");
1689
- var tools = [
1690
- // --- Role ---
1691
- {
1692
- name: "activate",
1693
- params: {
1694
- roleId: { type: "string", required: true, description: "Role name to activate" }
1138
+ function validateGherkin(source) {
1139
+ if (!source) return;
1140
+ try {
1141
+ parse(source);
1142
+ } catch (e) {
1143
+ throw new Error(`Invalid Gherkin: ${e.message}`);
1695
1144
  }
1696
- },
1697
- {
1698
- name: "focus",
1699
- params: {
1700
- id: {
1701
- type: "string",
1702
- required: false,
1703
- description: "Goal id to switch to. Omit to view current."
1145
+ }
1146
+ function findInState(state, target) {
1147
+ if (state.id && state.id.toLowerCase() === target) return state;
1148
+ if (state.alias) {
1149
+ for (const a of state.alias) {
1150
+ if (a.toLowerCase() === target) return state;
1704
1151
  }
1705
1152
  }
1706
- },
1707
- // --- Execution ---
1708
- {
1709
- name: "want",
1710
- params: {
1711
- id: { type: "string", required: true, description: "Goal id (used for focus/reference)" },
1712
- goal: {
1713
- type: "gherkin",
1714
- required: true,
1715
- description: "Gherkin Feature source describing the goal"
1716
- }
1153
+ for (const child of state.children ?? []) {
1154
+ const found = findInState(child, target);
1155
+ if (found) return found;
1717
1156
  }
1718
- },
1719
- {
1720
- name: "plan",
1721
- params: {
1722
- id: {
1723
- type: "string",
1724
- required: true,
1725
- description: "Plan id \u2014 keywords from the plan content joined by hyphens"
1726
- },
1727
- plan: {
1728
- type: "gherkin",
1729
- required: true,
1730
- description: "Gherkin Feature source describing the plan"
1731
- },
1732
- after: {
1733
- type: "string",
1734
- required: false,
1735
- description: "Plan id this plan follows (sequential/phase relationship)"
1736
- },
1737
- fallback: {
1738
- type: "string",
1739
- required: false,
1740
- description: "Plan id this plan is a backup for (alternative/strategy relationship)"
1157
+ return null;
1158
+ }
1159
+ async function removeExisting(parent, id) {
1160
+ const state = await rt.project(parent);
1161
+ const existing = findInState(state, id);
1162
+ if (existing) await rt.remove(existing);
1163
+ }
1164
+ function requireResourceX() {
1165
+ if (!resourcex) throw new Error("ResourceX is not available.");
1166
+ return resourcex;
1167
+ }
1168
+ function requireIssueX() {
1169
+ if (!issuex) throw new Error("IssueX is not available.");
1170
+ return issuex;
1171
+ }
1172
+ return {
1173
+ // ---- Individual: lifecycle ----
1174
+ async "individual.born"(content, id, alias) {
1175
+ validateGherkin(content);
1176
+ const node = await rt.create(society, C.individual, content, id, alias);
1177
+ await rt.create(node, C.identity, void 0, id ? `${id}-identity` : void 0);
1178
+ return ok(node, "born");
1179
+ },
1180
+ async "individual.retire"(individual2) {
1181
+ return archive(await resolve(individual2), "retire");
1182
+ },
1183
+ async "individual.die"(individual2) {
1184
+ return archive(await resolve(individual2), "die");
1185
+ },
1186
+ async "individual.rehire"(pastNode) {
1187
+ const node = await resolve(pastNode);
1188
+ const ind = await rt.transform(node, C.individual);
1189
+ return ok(ind, "rehire");
1190
+ },
1191
+ // ---- Individual: external injection ----
1192
+ async "individual.teach"(individual2, principle2, id) {
1193
+ validateGherkin(principle2);
1194
+ const parent = await resolve(individual2);
1195
+ if (id) await removeExisting(parent, id);
1196
+ const node = await rt.create(parent, C.principle, principle2, id);
1197
+ return ok(node, "teach");
1198
+ },
1199
+ async "individual.train"(individual2, procedure2, id) {
1200
+ validateGherkin(procedure2);
1201
+ const parent = await resolve(individual2);
1202
+ if (id) await removeExisting(parent, id);
1203
+ const node = await rt.create(parent, C.procedure, procedure2, id);
1204
+ return ok(node, "train");
1205
+ },
1206
+ // ---- Role: focus ----
1207
+ async "role.focus"(goal2) {
1208
+ return ok(await resolve(goal2), "focus");
1209
+ },
1210
+ // ---- Role: execution ----
1211
+ async "role.want"(individual2, goal2, id, alias) {
1212
+ validateGherkin(goal2);
1213
+ const node = await rt.create(await resolve(individual2), C.goal, goal2, id, alias);
1214
+ return ok(node, "want");
1215
+ },
1216
+ async "role.plan"(goal2, plan2, id, after, fallback) {
1217
+ validateGherkin(plan2);
1218
+ const node = await rt.create(await resolve(goal2), C.plan, plan2, id);
1219
+ if (after) await rt.link(node, await resolve(after), "after", "before");
1220
+ if (fallback) await rt.link(node, await resolve(fallback), "fallback-for", "fallback");
1221
+ return ok(node, "plan");
1222
+ },
1223
+ async "role.todo"(plan2, task2, id, alias) {
1224
+ validateGherkin(task2);
1225
+ const node = await rt.create(await resolve(plan2), C.task, task2, id, alias);
1226
+ return ok(node, "todo");
1227
+ },
1228
+ async "role.finish"(task2, individual2, encounter2) {
1229
+ validateGherkin(encounter2);
1230
+ const taskNode = await resolve(task2);
1231
+ await rt.tag(taskNode, "done");
1232
+ if (encounter2) {
1233
+ const encId = taskNode.id ? `${taskNode.id}-finished` : void 0;
1234
+ const enc = await rt.create(await resolve(individual2), C.encounter, encounter2, encId);
1235
+ return ok(enc, "finish");
1741
1236
  }
1742
- }
1743
- },
1744
- {
1745
- name: "todo",
1746
- params: {
1747
- id: { type: "string", required: true, description: "Task id (used for finish/reference)" },
1748
- task: {
1749
- type: "gherkin",
1750
- required: true,
1751
- description: "Gherkin Feature source describing the task"
1237
+ return ok(taskNode, "finish");
1238
+ },
1239
+ async "role.complete"(plan2, individual2, encounter2) {
1240
+ validateGherkin(encounter2);
1241
+ const planNode = await resolve(plan2);
1242
+ await rt.tag(planNode, "done");
1243
+ const encId = planNode.id ? `${planNode.id}-completed` : void 0;
1244
+ const enc = await rt.create(await resolve(individual2), C.encounter, encounter2, encId);
1245
+ return ok(enc, "complete");
1246
+ },
1247
+ async "role.abandon"(plan2, individual2, encounter2) {
1248
+ validateGherkin(encounter2);
1249
+ const planNode = await resolve(plan2);
1250
+ await rt.tag(planNode, "abandoned");
1251
+ const encId = planNode.id ? `${planNode.id}-abandoned` : void 0;
1252
+ const enc = await rt.create(await resolve(individual2), C.encounter, encounter2, encId);
1253
+ return ok(enc, "abandon");
1254
+ },
1255
+ // ---- Role: cognition ----
1256
+ async "role.reflect"(encounter2, individual2, experience2, id) {
1257
+ validateGherkin(experience2);
1258
+ if (encounter2) {
1259
+ const encNode = await resolve(encounter2);
1260
+ const exp2 = await rt.create(
1261
+ await resolve(individual2),
1262
+ C.experience,
1263
+ experience2 || encNode.information,
1264
+ id
1265
+ );
1266
+ await rt.remove(encNode);
1267
+ return ok(exp2, "reflect");
1752
1268
  }
1753
- }
1754
- },
1755
- {
1756
- name: "finish",
1757
- params: {
1758
- id: { type: "string", required: true, description: "Task id to finish" },
1759
- encounter: {
1760
- type: "gherkin",
1761
- required: false,
1762
- description: "Optional Gherkin Feature describing what happened"
1269
+ const exp = await rt.create(await resolve(individual2), C.experience, experience2, id);
1270
+ return ok(exp, "reflect");
1271
+ },
1272
+ async "role.realize"(experience2, individual2, principle2, id) {
1273
+ validateGherkin(principle2);
1274
+ if (experience2) {
1275
+ const expNode = await resolve(experience2);
1276
+ const prin2 = await rt.create(
1277
+ await resolve(individual2),
1278
+ C.principle,
1279
+ principle2 || expNode.information,
1280
+ id
1281
+ );
1282
+ await rt.remove(expNode);
1283
+ return ok(prin2, "realize");
1763
1284
  }
1764
- }
1765
- },
1766
- {
1767
- name: "complete",
1768
- params: {
1769
- id: {
1770
- type: "string",
1771
- required: false,
1772
- description: "Plan id to complete (defaults to focused plan)"
1773
- },
1774
- encounter: {
1775
- type: "gherkin",
1776
- required: false,
1777
- description: "Optional Gherkin Feature describing what happened"
1285
+ const prin = await rt.create(await resolve(individual2), C.principle, principle2, id);
1286
+ return ok(prin, "realize");
1287
+ },
1288
+ async "role.master"(individual2, procedure2, id, experience2) {
1289
+ validateGherkin(procedure2);
1290
+ const parent = await resolve(individual2);
1291
+ if (id) await removeExisting(parent, id);
1292
+ const proc = await rt.create(parent, C.procedure, procedure2, id);
1293
+ if (experience2) await rt.remove(await resolve(experience2));
1294
+ return ok(proc, "master");
1295
+ },
1296
+ // ---- Role: knowledge management ----
1297
+ async "role.forget"(nodeId) {
1298
+ const node = await resolve(nodeId);
1299
+ await rt.remove(node);
1300
+ return { state: { ...node, children: [] }, process: "forget" };
1301
+ },
1302
+ // ---- Role: skill ----
1303
+ async "role.skill"(locator) {
1304
+ const rx = requireResourceX();
1305
+ const content = await rx.ingest(locator);
1306
+ const text = typeof content === "string" ? content : JSON.stringify(content, null, 2);
1307
+ try {
1308
+ const rxm = await rx.info(locator);
1309
+ return `${formatRXM(rxm)}
1310
+
1311
+ ${text}`;
1312
+ } catch {
1313
+ return text;
1778
1314
  }
1779
- }
1780
- },
1781
- {
1782
- name: "abandon",
1783
- params: {
1784
- id: {
1785
- type: "string",
1786
- required: false,
1787
- description: "Plan id to abandon (defaults to focused plan)"
1788
- },
1789
- encounter: {
1790
- type: "gherkin",
1791
- required: false,
1792
- description: "Optional Gherkin Feature describing what happened"
1315
+ },
1316
+ // ---- Project ----
1317
+ async "project.launch"(content, id, alias, org) {
1318
+ validateGherkin(content);
1319
+ const node = await rt.create(society, C.project, content, id, alias);
1320
+ if (org) await rt.link(node, await resolve(org), "ownership", "project");
1321
+ return ok(node, "launch");
1322
+ },
1323
+ async "project.scope"(project2, scope2, id) {
1324
+ validateGherkin(scope2);
1325
+ const node = await rt.create(await resolve(project2), C.scope, scope2, id);
1326
+ return ok(node, "scope");
1327
+ },
1328
+ async "project.milestone"(project2, milestone2, id) {
1329
+ validateGherkin(milestone2);
1330
+ const node = await rt.create(await resolve(project2), C.milestone, milestone2, id);
1331
+ return ok(node, "milestone");
1332
+ },
1333
+ async "project.achieve"(milestone2) {
1334
+ const node = await resolve(milestone2);
1335
+ await rt.tag(node, "done");
1336
+ return ok(node, "achieve");
1337
+ },
1338
+ async "project.enroll"(project2, individual2) {
1339
+ const projNode = await resolve(project2);
1340
+ await rt.link(projNode, await resolve(individual2), "participation", "participate");
1341
+ return ok(projNode, "enroll");
1342
+ },
1343
+ async "project.remove"(project2, individual2) {
1344
+ const projNode = await resolve(project2);
1345
+ await rt.unlink(projNode, await resolve(individual2), "participation", "participate");
1346
+ return ok(projNode, "remove");
1347
+ },
1348
+ async "project.deliver"(project2, deliverable2, id) {
1349
+ validateGherkin(deliverable2);
1350
+ const node = await rt.create(await resolve(project2), C.deliverable, deliverable2, id);
1351
+ return ok(node, "deliver");
1352
+ },
1353
+ async "project.wiki"(project2, wiki2, id) {
1354
+ validateGherkin(wiki2);
1355
+ const node = await rt.create(await resolve(project2), C.wiki, wiki2, id);
1356
+ return ok(node, "wiki");
1357
+ },
1358
+ async "project.archive"(project2) {
1359
+ return archive(await resolve(project2), "archive");
1360
+ },
1361
+ // ---- Org ----
1362
+ async "org.found"(content, id, alias) {
1363
+ validateGherkin(content);
1364
+ const node = await rt.create(society, C.organization, content, id, alias);
1365
+ return ok(node, "found");
1366
+ },
1367
+ async "org.charter"(org, charter2, id) {
1368
+ validateGherkin(charter2);
1369
+ const node = await rt.create(await resolve(org), C.charter, charter2, id);
1370
+ return ok(node, "charter");
1371
+ },
1372
+ async "org.dissolve"(org) {
1373
+ return archive(await resolve(org), "dissolve");
1374
+ },
1375
+ async "org.hire"(org, individual2) {
1376
+ const orgNode = await resolve(org);
1377
+ await rt.link(orgNode, await resolve(individual2), "membership", "belong");
1378
+ return ok(orgNode, "hire");
1379
+ },
1380
+ async "org.fire"(org, individual2) {
1381
+ const orgNode = await resolve(org);
1382
+ await rt.unlink(orgNode, await resolve(individual2), "membership", "belong");
1383
+ return ok(orgNode, "fire");
1384
+ },
1385
+ // ---- Position ----
1386
+ async "position.establish"(content, id, alias) {
1387
+ validateGherkin(content);
1388
+ const node = await rt.create(society, C.position, content, id, alias);
1389
+ return ok(node, "establish");
1390
+ },
1391
+ async "position.charge"(position2, duty2, id) {
1392
+ validateGherkin(duty2);
1393
+ const node = await rt.create(await resolve(position2), C.duty, duty2, id);
1394
+ return ok(node, "charge");
1395
+ },
1396
+ async "position.require"(position2, procedure2, id) {
1397
+ validateGherkin(procedure2);
1398
+ const parent = await resolve(position2);
1399
+ if (id) await removeExisting(parent, id);
1400
+ const node = await rt.create(parent, C.requirement, procedure2, id);
1401
+ return ok(node, "require");
1402
+ },
1403
+ async "position.abolish"(position2) {
1404
+ return archive(await resolve(position2), "abolish");
1405
+ },
1406
+ async "position.appoint"(position2, individual2) {
1407
+ const posNode = await resolve(position2);
1408
+ const indNode = await resolve(individual2);
1409
+ await rt.link(posNode, indNode, "appointment", "serve");
1410
+ const posState = await rt.project(posNode);
1411
+ for (const child of posState.children ?? []) {
1412
+ if (child.name !== "requirement" || !child.information) continue;
1413
+ await rt.create(indNode, C.procedure, child.information, child.id);
1793
1414
  }
1794
- }
1795
- },
1796
- // --- Cognition ---
1797
- {
1798
- name: "reflect",
1799
- params: {
1800
- ids: {
1801
- type: "string[]",
1802
- required: true,
1803
- description: "Encounter ids to reflect on (selective consumption)"
1804
- },
1805
- id: {
1806
- type: "string",
1807
- required: true,
1808
- description: "Experience id \u2014 keywords from the experience content joined by hyphens"
1809
- },
1810
- experience: {
1811
- type: "gherkin",
1812
- required: false,
1813
- description: "Gherkin Feature source for the experience"
1415
+ return ok(posNode, "appoint");
1416
+ },
1417
+ async "position.dismiss"(position2, individual2) {
1418
+ const posNode = await resolve(position2);
1419
+ await rt.unlink(posNode, await resolve(individual2), "appointment", "serve");
1420
+ return ok(posNode, "dismiss");
1421
+ },
1422
+ // ---- Census ----
1423
+ async "census.list"(type) {
1424
+ const target = type === "past" ? past2 : society;
1425
+ const state = await rt.project(target);
1426
+ const children = state.children ?? [];
1427
+ const filtered = type === "past" ? children : children.filter((c) => type ? c.name === type : c.name !== "past");
1428
+ if (filtered.length === 0) {
1429
+ return type ? `No ${type} found.` : "Society is empty.";
1814
1430
  }
1815
- }
1816
- },
1817
- {
1818
- name: "realize",
1819
- params: {
1820
- ids: {
1821
- type: "string[]",
1822
- required: true,
1823
- description: "Experience ids to distill into a principle"
1824
- },
1825
- id: {
1826
- type: "string",
1827
- required: true,
1828
- description: "Principle id \u2014 keywords from the principle content joined by hyphens"
1829
- },
1830
- principle: {
1831
- type: "gherkin",
1832
- required: false,
1833
- description: "Gherkin Feature source for the principle"
1431
+ if (type) {
1432
+ const lines2 = [];
1433
+ for (const item of filtered) {
1434
+ const tag = item.tag ? ` #${item.tag}` : "";
1435
+ const alias = item.alias?.length ? ` (${item.alias.join(", ")})` : "";
1436
+ lines2.push(`${item.id ?? "(no id)"}${alias}${tag}`);
1437
+ }
1438
+ return lines2.join("\n");
1834
1439
  }
1835
- }
1836
- },
1837
- {
1838
- name: "master",
1839
- params: {
1840
- ids: {
1841
- type: "string[]",
1842
- required: false,
1843
- description: "Experience ids to distill into a procedure"
1844
- },
1845
- id: {
1846
- type: "string",
1847
- required: true,
1848
- description: "Procedure id \u2014 keywords from the procedure content joined by hyphens"
1849
- },
1850
- procedure: {
1851
- type: "gherkin",
1852
- required: true,
1853
- description: "Gherkin Feature source for the procedure"
1440
+ const orgs = filtered.filter((c) => c.name === "organization");
1441
+ const individuals = filtered.filter((c) => c.name === "individual");
1442
+ const affiliatedIndividuals = /* @__PURE__ */ new Set();
1443
+ const individualPositions = /* @__PURE__ */ new Map();
1444
+ for (const ind of individuals) {
1445
+ const serves = ind.links?.filter((l) => l.relation === "serve") ?? [];
1446
+ if (serves.length > 0) {
1447
+ individualPositions.set(
1448
+ ind.id ?? "",
1449
+ serves.map((l) => l.target.id ?? "(no id)")
1450
+ );
1451
+ }
1854
1452
  }
1855
- }
1856
- },
1857
- // --- Knowledge ---
1858
- {
1859
- name: "forget",
1860
- params: {
1861
- id: {
1862
- type: "string",
1863
- required: true,
1864
- description: "Id of the node to remove (principle, procedure, experience, encounter, etc.)"
1453
+ const lines = [];
1454
+ for (const org of orgs) {
1455
+ const alias = org.alias?.length ? ` (${org.alias.join(", ")})` : "";
1456
+ const tag = org.tag ? ` #${org.tag}` : "";
1457
+ lines.push(`${org.id}${alias}${tag}`);
1458
+ const projects = org.links?.filter((l) => l.relation === "project") ?? [];
1459
+ for (const p of projects) {
1460
+ const pAlias = p.target.alias?.length ? ` (${p.target.alias.join(", ")})` : "";
1461
+ const pTag = p.target.tag ? ` #${p.target.tag}` : "";
1462
+ lines.push(` \u{1F4E6} ${p.target.id ?? "(no id)"}${pAlias}${pTag}`);
1463
+ }
1464
+ const members = org.links?.filter((l) => l.relation === "membership") ?? [];
1465
+ if (members.length === 0 && projects.length === 0) {
1466
+ lines.push(" (empty)");
1467
+ }
1468
+ for (const m of members) {
1469
+ affiliatedIndividuals.add(m.target.id ?? "");
1470
+ const mAlias = m.target.alias?.length ? ` (${m.target.alias.join(", ")})` : "";
1471
+ const mTag = m.target.tag ? ` #${m.target.tag}` : "";
1472
+ const posLabels = individualPositions.get(m.target.id ?? "");
1473
+ const posStr = posLabels?.length ? ` \u2014 ${posLabels.join(", ")}` : "";
1474
+ lines.push(` ${m.target.id}${mAlias}${mTag}${posStr}`);
1475
+ }
1476
+ lines.push("");
1865
1477
  }
1866
- }
1867
- },
1868
- {
1869
- name: "skill",
1870
- params: {
1871
- locator: {
1872
- type: "string",
1873
- required: true,
1874
- description: "ResourceX locator for the skill (e.g. deepractice/role-management)"
1478
+ const unaffiliated = individuals.filter((ind) => !affiliatedIndividuals.has(ind.id ?? ""));
1479
+ if (unaffiliated.length > 0) {
1480
+ lines.push("\u2500\u2500\u2500 unaffiliated \u2500\u2500\u2500");
1481
+ for (const ind of unaffiliated) {
1482
+ const alias = ind.alias?.length ? ` (${ind.alias.join(", ")})` : "";
1483
+ const tag = ind.tag ? ` #${ind.tag}` : "";
1484
+ const posLabels = individualPositions.get(ind.id ?? "");
1485
+ const posStr = posLabels?.length ? ` \u2014 ${posLabels.join(", ")}` : "";
1486
+ lines.push(` ${ind.id}${alias}${tag}${posStr}`);
1487
+ }
1875
1488
  }
1876
- }
1877
- },
1878
- // --- Use / Direct ---
1879
- {
1880
- name: "use",
1881
- params: {
1882
- command: {
1883
- type: "string",
1884
- required: true,
1885
- description: "!namespace.method for RoleX commands, or a ResourceX locator for resources"
1886
- },
1887
- args: {
1888
- type: "record",
1889
- required: false,
1890
- description: "Named arguments for the command. Load the relevant skill first to learn what args to pass."
1489
+ return lines.join("\n");
1490
+ },
1491
+ // ---- Prototype ----
1492
+ async "prototype.settle"(source) {
1493
+ const rx = requireResourceX();
1494
+ if (!ctx.prototype) throw new Error("Prototype registry is not available.");
1495
+ if (!ctx.direct) throw new Error("Direct dispatch is not available.");
1496
+ const result = await rx.ingest(source);
1497
+ for (const instr of result.instructions) {
1498
+ await ctx.direct(instr.op, instr.args);
1891
1499
  }
1500
+ ctx.prototype.settle(result.id, source);
1501
+ return `Prototype "${result.id}" settled (${result.instructions.length} instructions).`;
1502
+ },
1503
+ // ---- Resource (proxy to ResourceX) ----
1504
+ "resource.add"(path) {
1505
+ return requireResourceX().add(path);
1506
+ },
1507
+ "resource.search"(query) {
1508
+ return requireResourceX().search(query);
1509
+ },
1510
+ "resource.has"(locator) {
1511
+ return requireResourceX().has(locator);
1512
+ },
1513
+ "resource.info"(locator) {
1514
+ return requireResourceX().info(locator);
1515
+ },
1516
+ "resource.remove"(locator) {
1517
+ return requireResourceX().remove(locator);
1518
+ },
1519
+ "resource.push"(locator, options) {
1520
+ return requireResourceX().push(locator, options);
1521
+ },
1522
+ "resource.pull"(locator, options) {
1523
+ return requireResourceX().pull(locator, options);
1524
+ },
1525
+ "resource.clearCache"(registry) {
1526
+ return requireResourceX().clearCache(registry);
1527
+ },
1528
+ // ---- Issue (proxy to IssueX) ----
1529
+ async "issue.publish"(title, body, author, assignee) {
1530
+ const ix = requireIssueX();
1531
+ return ix.createIssue({ title, body, author, assignee });
1532
+ },
1533
+ async "issue.get"(number) {
1534
+ return requireIssueX().getIssueByNumber(number);
1535
+ },
1536
+ async "issue.list"(status, author, assignee, label) {
1537
+ const filter = {};
1538
+ if (status) filter.status = status;
1539
+ if (author) filter.author = author;
1540
+ if (assignee) filter.assignee = assignee;
1541
+ if (label) filter.label = label;
1542
+ return requireIssueX().listIssues(
1543
+ Object.keys(filter).length > 0 ? filter : void 0
1544
+ );
1545
+ },
1546
+ async "issue.update"(number, title, body, assignee) {
1547
+ const ix = requireIssueX();
1548
+ const issue = await ix.getIssueByNumber(number);
1549
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1550
+ const patch = {};
1551
+ if (title !== void 0) patch.title = title;
1552
+ if (body !== void 0) patch.body = body;
1553
+ if (assignee !== void 0) patch.assignee = assignee;
1554
+ return ix.updateIssue(issue.id, patch);
1555
+ },
1556
+ async "issue.close"(number) {
1557
+ const ix = requireIssueX();
1558
+ const issue = await ix.getIssueByNumber(number);
1559
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1560
+ return ix.closeIssue(issue.id);
1561
+ },
1562
+ async "issue.reopen"(number) {
1563
+ const ix = requireIssueX();
1564
+ const issue = await ix.getIssueByNumber(number);
1565
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1566
+ return ix.reopenIssue(issue.id);
1567
+ },
1568
+ async "issue.assign"(number, assignee) {
1569
+ const ix = requireIssueX();
1570
+ const issue = await ix.getIssueByNumber(number);
1571
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1572
+ return ix.updateIssue(issue.id, { assignee });
1573
+ },
1574
+ async "issue.comment"(number, body, author) {
1575
+ const ix = requireIssueX();
1576
+ const issue = await ix.getIssueByNumber(number);
1577
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1578
+ return ix.createComment(issue.id, body, author);
1579
+ },
1580
+ async "issue.comments"(number) {
1581
+ const ix = requireIssueX();
1582
+ const issue = await ix.getIssueByNumber(number);
1583
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1584
+ return ix.listComments(issue.id);
1585
+ },
1586
+ async "issue.label"(number, label) {
1587
+ const ix = requireIssueX();
1588
+ const issue = await ix.getIssueByNumber(number);
1589
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1590
+ let labelObj = await ix.getLabelByName(label);
1591
+ if (!labelObj) labelObj = await ix.createLabel({ name: label });
1592
+ await ix.addLabel(issue.id, labelObj.id);
1593
+ return ix.getIssueByNumber(number);
1594
+ },
1595
+ async "issue.unlabel"(number, label) {
1596
+ const ix = requireIssueX();
1597
+ const issue = await ix.getIssueByNumber(number);
1598
+ if (!issue) throw new Error(`Issue #${number} not found.`);
1599
+ const labelObj = await ix.getLabelByName(label);
1600
+ if (!labelObj) throw new Error(`Label "${label}" not found.`);
1601
+ await ix.removeLabel(issue.id, labelObj.id);
1602
+ return ix.getIssueByNumber(number);
1892
1603
  }
1893
- },
1894
- {
1895
- name: "direct",
1896
- params: {
1897
- command: {
1898
- type: "string",
1899
- required: true,
1900
- description: "!namespace.method for RoleX commands, or a ResourceX locator for resources"
1901
- },
1902
- args: {
1903
- type: "record",
1904
- required: false,
1905
- description: "Named arguments for the command. Load the relevant skill first to learn what args to pass."
1906
- }
1604
+ };
1605
+ }
1606
+ function formatRXM(rxm) {
1607
+ const lines = [`--- RXM: ${rxm.locator} ---`];
1608
+ const def2 = rxm.definition;
1609
+ if (def2) {
1610
+ if (def2.author) lines.push(`Author: ${def2.author}`);
1611
+ if (def2.description) lines.push(`Description: ${def2.description}`);
1612
+ }
1613
+ const source = rxm.source;
1614
+ if (source?.files) {
1615
+ lines.push("Files:");
1616
+ lines.push(renderFileTree(source.files, " "));
1617
+ }
1618
+ lines.push("---");
1619
+ return lines.join("\n");
1620
+ }
1621
+ function renderFileTree(files, indent = "") {
1622
+ const lines = [];
1623
+ for (const [name, value] of Object.entries(files)) {
1624
+ if (value && typeof value === "object" && !("size" in value)) {
1625
+ lines.push(`${indent}${name}`);
1626
+ lines.push(renderFileTree(value, `${indent} `));
1627
+ } else {
1628
+ const size = value?.size ? ` (${value.size} bytes)` : "";
1629
+ lines.push(`${indent}${name}${size}`);
1907
1630
  }
1908
1631
  }
1909
- ];
1632
+ return lines.filter(Boolean).join("\n");
1633
+ }
1910
1634
  export {
1911
- RendererRouter,
1912
- applyPrototype,
1913
- createCommands,
1635
+ createOps,
1914
1636
  directives,
1915
1637
  instructions,
1916
1638
  processes,
1917
1639
  toArgs,
1918
- tools,
1919
- world,
1920
- worldInstructions
1640
+ world
1921
1641
  };
1922
1642
  //# sourceMappingURL=index.js.map