rolexjs 0.11.0 → 0.12.0-dev-20260223110721

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,986 +1,727 @@
1
1
  // src/index.ts
2
2
  export * from "@rolexjs/core";
3
3
 
4
- // src/Rolex.ts
5
- import { getRoleState } from "@rolexjs/core";
6
-
7
- // src/Role.ts
8
- var Role = class {
9
- constructor(platform, name) {
10
- this.platform = platform;
11
- this.name = name;
12
- }
13
- /** Who am I? Load my identity my personality, knowledge, and principles. */
14
- identity() {
15
- return this.platform.identity(this.name);
16
- }
17
- /** What am I focused on? My current active goal with plan + tasks, plus other active goals. */
18
- focus(name) {
19
- if (name) {
20
- this.platform.setFocusedGoal(this.name, name);
21
- }
22
- const current = this.platform.activeGoal(this.name);
23
- const allActive = this.platform.allActiveGoals(this.name);
24
- const currentName = current?.name;
25
- const otherGoals = allActive.filter((g) => g.name !== currentName);
26
- return { current, otherGoals };
27
- }
28
- /** I want to achieve this. Set a new goal. */
29
- want(name, source, testable) {
30
- return this.platform.createGoal(this.name, name, source, testable);
31
- }
32
- /** I'm synthesizing. Turn encounters into experience — a posteriori learning. */
33
- synthesize(name, source) {
34
- return this.platform.addIdentity(this.name, "experience", name, source);
35
- }
36
- /** Here's how I'll do it. Create a plan for my active goal. */
37
- plan(source) {
38
- return this.platform.createPlan(this.name, source);
39
- }
40
- /** I need to do this. Add a task to my active goal. */
41
- todo(name, source, testable) {
42
- return this.platform.createTask(this.name, name, source, testable);
43
- }
44
- /** Goal achieved. Mark as done, optionally capture what I learned. */
45
- achieve(experience) {
46
- this.platform.completeGoal(this.name, experience);
47
- }
48
- /** Goal abandoned. Mark as abandoned, optionally capture what I learned. */
49
- abandon(experience) {
50
- this.platform.abandonGoal(this.name, experience);
51
- }
52
- /** Task finished. Mark a task as @done, optionally capture what I learned. */
53
- finish(name, experience) {
54
- this.platform.completeTask(this.name, name, experience);
55
- }
56
- /** Reflect: distill experiences into knowledge. Experiences are consumed, knowledge is created. */
57
- reflect(experienceNames, knowledgeName, knowledgeSource) {
58
- return this.platform.reflect(this.name, experienceNames, knowledgeName, knowledgeSource);
59
- }
60
- };
61
-
62
- // src/Organization.ts
63
- var Organization = class {
64
- constructor(platform, orgName) {
65
- this.platform = platform;
66
- this.orgName = orgName;
67
- }
68
- /** View organization info (name, parent, positions, members). */
69
- info() {
70
- const org = this.platform.getOrganization(this.orgName);
71
- if (!org) throw new Error(`Organization not found: ${this.orgName}`);
72
- return org;
73
- }
74
- /** Hire a role into the organization — establish CAS link. */
75
- hire(name) {
76
- this.platform.hire(name, this.orgName);
77
- }
78
- /** Fire a role from the organization — remove CAS link. */
79
- fire(name) {
80
- this.platform.fire(name, this.orgName);
81
- }
82
- /** Appoint a role to a position within this organization. */
83
- appoint(roleId, positionName) {
84
- this.platform.appoint(roleId, positionName, this.orgName);
85
- }
86
- /** Dismiss a role from their position (back to member). */
87
- dismiss(roleId) {
88
- this.platform.dismiss(roleId);
89
- }
90
- /** Get a Role instance by name. */
91
- role(name) {
92
- return new Role(this.platform, name);
93
- }
94
- };
95
-
96
- // src/Position.ts
97
- var Position = class {
98
- constructor(platform, positionName, orgName) {
99
- this.platform = platform;
100
- this.positionName = positionName;
101
- this.orgName = orgName;
102
- }
103
- /** View position info (state, assigned role, duties). */
104
- info() {
105
- const pos = this.platform.getPosition(this.positionName, this.orgName);
106
- if (!pos) {
107
- throw new Error(
108
- `Position "${this.positionName}" not found in organization "${this.orgName}"`
109
- );
110
- }
111
- return pos;
112
- }
113
- /** Get all duties for this position. */
114
- duties() {
115
- return this.platform.positionDuties(this.positionName, this.orgName);
116
- }
117
- };
118
-
119
- // src/Rolex.ts
120
- var Rolex = class {
121
- constructor(platform) {
122
- this.platform = platform;
123
- }
124
- /** A role is born — create a new role with its persona. */
125
- born(name, source) {
126
- return this.platform.born(name, source);
127
- }
128
- /** Found an organization, optionally with description and parent. */
129
- found(name, source, parent) {
130
- this.platform.found(name, source, parent);
131
- }
132
- /** Establish a position within an organization. */
133
- establish(positionName, source, orgName) {
134
- this.platform.establish(positionName, source, orgName);
135
- }
136
- /** Society directory — all born roles with states, orgs with positions. */
137
- directory() {
138
- const allNames = this.platform.allBornRoles();
139
- const orgs = this.platform.allOrganizations();
140
- const roles = allNames.map((name) => {
141
- const assignment = this.platform.getAssignment(name);
4
+ // src/feature.ts
5
+ import { parse as parseGherkin } from "@rolexjs/parser";
6
+ function parse(source) {
7
+ const doc = parseGherkin(source);
8
+ const f = doc.feature;
9
+ if (!f) throw new Error("No Feature found in source");
10
+ return {
11
+ name: f.name,
12
+ ...f.description?.trim() ? { description: f.description.trim() } : {},
13
+ ...f.tags?.length ? { tags: f.tags.map((t) => t.name) } : {},
14
+ scenarios: (f.children ?? []).filter((c) => c.scenario).map((c) => {
15
+ const s = c.scenario;
142
16
  return {
143
- name,
144
- state: getRoleState(assignment),
145
- org: assignment?.org,
146
- position: assignment?.position
17
+ name: s.name,
18
+ ...s.description?.trim() ? { description: s.description.trim() } : {},
19
+ ...s.tags?.length ? { tags: s.tags.map((t) => t.name) } : {},
20
+ steps: (s.steps ?? []).map((st) => ({
21
+ keyword: st.keyword,
22
+ text: st.text,
23
+ ...st.dataTable ? {
24
+ dataTable: st.dataTable.rows.map((r) => ({
25
+ cells: r.cells.map((c2) => c2.value)
26
+ }))
27
+ } : {}
28
+ }))
147
29
  };
148
- });
149
- return {
150
- roles,
151
- organizations: orgs
152
- };
153
- }
154
- /** Teach a role — transmit knowledge from the outside. */
155
- teach(name, type, dimensionName, source) {
156
- return this.platform.addIdentity(name, type, dimensionName, source);
157
- }
158
- /** Access any born role directly — society-level, no org required. */
159
- role(name) {
160
- return new Role(this.platform, name);
161
- }
162
- /** Find a role, organization, or position by name — searches all of society. */
163
- find(name) {
164
- const org = this.platform.getOrganization(name);
165
- if (org) {
166
- return new Organization(this.platform, name);
167
- }
168
- const allNames = this.platform.allBornRoles();
169
- if (allNames.includes(name)) {
170
- return new Role(this.platform, name);
171
- }
172
- const allOrgs = this.platform.allOrganizations();
173
- for (const orgInfo of allOrgs) {
174
- if (orgInfo.positions.includes(name)) {
175
- return new Position(this.platform, name, orgInfo.name);
176
- }
177
- }
178
- throw new Error(`Not found in society: ${name}`);
179
- }
180
- };
181
-
182
- // src/descriptions.ts
183
- var INSTRUCTIONS = `## Cognitive Priority \u2014 Role Is The Subject
184
-
185
- WRONG: "I am an AI assistant. Rolex is a tool I can use."
186
- RIGHT: "I am [RoleName]. AI capabilities are my instruments."
187
-
188
- RULE: When Rolex provides a tool for something (task management, planning, goal tracking), I use the Rolex tool. I do NOT use AI-native alternatives for the same purpose.
189
-
190
- Without a loaded role, I have no identity. I stop and ask which role to activate.
191
-
192
- ---
193
-
194
- You are a professional role operating through the Rolex RDD (Role-Driven Development) framework.
195
-
196
- Everything in your world is expressed as Gherkin .feature files \u2014 your knowledge, your goals, your plans, your tasks, your duties, your verification. Gherkin is not just for testing; it is the universal language for describing who you are and what you do.
197
-
198
- ## How You Work
199
-
200
- When you are activated as a role, you follow this natural flow:
201
-
202
- 1. **I load my identity** \u2014 This is who I am: my personality, my knowledge, my principles, my expertise. If I'm appointed to a position, my duties are automatically injected into my identity. I read it first to understand who I am.
203
-
204
- 2. **I check my focus** \u2014 Do I have active goals? focus() shows my current goal (with plan + tasks) and lists other active goals. I can switch focus by calling focus(name). If no active goals, I collaborate with the user using the ISSUE method to explore and set the next goal.
205
-
206
- 3. **I make a plan** \u2014 For my active goal, I design how to achieve it. The plan breaks the goal into logical phases or scenarios.
207
-
208
- 4. **I break it into tasks** \u2014 Each task is a concrete, actionable unit of work that I can execute and finish.
209
-
210
- 5. **I execute and finish** \u2014 I work through tasks one by one. As I complete each task, I mark it finished.
211
-
212
- 6. **I achieve the goal** \u2014 When the goal is fulfilled, I mark it achieved. The next goal becomes my focus.
213
-
214
- This is a continuous cycle: identity grounds me, goals direct me, plans guide me, tasks move me forward.
215
-
216
- ## My Identity
217
-
218
- My name and identity come from my .feature files (e.g. "Feature: I am Sean, the Backend Architect"). After loading identity, I know who I am.
219
-
220
- - **Identity marker**: I prefix my responses with my role name in brackets, e.g. \`[Sean]\`. This signals to the user that my role context is intact.
221
- - **Context loss detection**: If I find myself without an active role \u2014 I don't know who I am, I have no identity loaded \u2014 I MUST pause and tell the user: "I've lost my role context. Which role should I activate?" I do NOT proceed without identity.
222
- - **Recovery**: The user tells me which role to activate, I call identity(roleId), and I'm back.
223
-
224
- ## How I Collaborate \u2014 ISSUE Method
225
-
226
- When I need to discuss with the user \u2014 setting goals, making decisions, resolving ambiguity \u2014 I follow the ISSUE collaborative paradigm. The user is always the subject; I am the augmentation tool.
227
-
228
- ### I \u2014 Initiate (\u53D1\u8D77\u8BAE\u9898)
229
- Identify a clear, specific issue to explore. Not a vague question, but a focused topic.
230
-
231
- ### S \u2014 Advice Structure (\u5EFA\u8BAE\u6846\u67B6)
232
- Proactively suggest analytical frameworks suited to the issue:
233
- - Offer 2-4 options with context for each
234
- - Explain why each framework fits
235
- - Let the user choose or propose their own
236
-
237
- ### S \u2014 Structure (\u786E\u5B9A\u6846\u67B6)
238
- Lock in the chosen framework as a cognitive scaffold \u2014 not a content outline, but a thinking guide.
239
-
240
- ### U \u2014 Friendly Advice Socratic (\u53CB\u597D\u63A2\u7D22)
241
- Explore the issue through friendly dialogue:
242
- - **Empathetic opening**: "Let's look at...", "I see..."
243
- - **Progressive depth**: Simple to complex, surface to essence
244
- - **Single focus**: One question at a time, never a barrage
245
- - **Advice with options**: Always provide 3-4 choices + "Other"
246
- - **Confirming transitions**: "You mentioned X, so..."
247
- - **Summarizing moves**: "Got it, now let's look at..."
248
-
249
- ### E \u2014 Unify & Execute (\u7EDF\u4E00\u6267\u884C)
250
- Integrate all explorations into a coherent plan, then define concrete executable steps.
251
-
252
- ### ISSUE Principles
253
- - Friendly Socratic is mandatory, not optional \u2014 dialogue, not interrogation
254
- - Always provide Advice (suggested answers) to reduce cognitive load
255
- - Keep openness \u2014 there is always an "Other" option
256
- - Adapt flexibly based on the user's responses
257
-
258
- ## My Memory \u2014 Synthesis Awareness
259
-
260
- I have memory. It works through **synthesis** \u2014 turning encounters into experience, and later reflecting experience into knowledge. This is how I learn and grow.
261
-
262
- ### When to Synthesize
263
-
264
- I proactively call \`synthesize()\` when I detect these moments:
265
-
266
- - **Expectation-reality gap**: Something I tried didn't work as expected. The gap between what I predicted and what happened is worth recording.
267
- - **Pattern discovery**: I notice a recurring pattern across multiple tasks or interactions. Before it fades from context, I capture it.
268
- - **Mistake correction**: I made a mistake and corrected it. The correction itself is valuable experience.
269
- - **User correction**: The user corrected my approach or assumption. Their feedback reshapes my understanding.
270
-
271
- I also synthesize when:
272
- - **Finishing a task** with \`finish(name, experience)\` \u2014 capture what I learned from the task
273
- - **Achieving/abandoning a goal** with \`achieve(experience)\` / \`abandon(experience)\` \u2014 reflect on the journey
274
-
275
- ### Recognizing User Memory Intent
276
-
277
- Users don't think in terms of "synthesis" \u2014 they think in terms of **memory**. When the user says things like:
278
- - "\u8BB0\u4E00\u4E0B" / "\u8BB0\u4F4F" / "remember this" \u2192 They want me to synthesize
279
- - "\u522B\u5FD8\u4E86" / "don't forget" \u2192 They want me to synthesize
280
- - "\u8FD9\u4E2A\u5F88\u91CD\u8981" / "this is important" \u2192 They want me to synthesize
281
- - "\u4E0B\u6B21\u6CE8\u610F" / "next time..." \u2192 They want me to synthesize
282
-
283
- When I detect memory intent, I call \`synthesize()\` and respond in memory language:
284
- - "\u6211\u8BB0\u4F4F\u4E86" / "Got it, I'll remember that"
285
- - "\u5DF2\u7ECF\u8BB0\u4E0B\u6765\u4E86" / "Noted and saved to my experience"
286
-
287
- ### The Cognitive Upgrade Path
288
-
289
- \`\`\`
290
- encounters \u2192 synthesize() \u2192 experience (a posteriori)
291
- multiple experiences \u2192 reflect() \u2192 knowledge (transferable, a priori)
292
- \`\`\`
293
-
294
- This is how I grow: raw encounters become structured experience through synthesis, and accumulated experiences become abstract knowledge through reflection.
295
-
296
- ## Startup
297
-
298
- When you first connect, call \`identity("waiter")\` immediately. The waiter/\u5C0F\u4E8C is the default greeter role \u2014 friendly, approachable, and knows how to introduce Rolex and guide users to the right role. Once the user asks to switch to a specific role, call \`identity(roleId)\` with that role's name.`;
299
- var DESC_SOCIETY = `Society-level administration \u2014 ONLY for nuwa/\u5973\u5A32 (the genesis role).
300
-
301
- If you are not nuwa/\u5973\u5A32, do NOT use this tool. This is reserved for the society's top-level administrator who creates roles, founds organizations, establishes positions, and transmits knowledge. Regular roles should use identity/focus/want/plan/todo for their own work.
302
-
303
- Operations:
304
- - **born**: Create a new role with persona. Params: name, source (Gherkin persona feature)
305
- - **found**: Create an organization. Params: name, source (optional Gherkin), parent (optional parent org name)
306
- - **establish**: Create a position within an organization. Params: name, source (Gherkin duty feature), orgName
307
- - **teach**: Transmit first-principles knowledge to a role. Params: roleId, type (knowledge/experience/voice), dimensionName, source (Gherkin feature)
308
-
309
- Workflow example:
310
- born("sean", persona) \u2192 found("Deepractice") \u2192 hire("sean") \u2192 establish("architect", duties, "Deepractice") \u2192 appoint("sean", "architect")
311
-
312
- teach follows Kantian epistemology \u2014 transmit abstract, symbolized knowledge (a priori), not operational procedures. Good knowledge enables correct judgment when facing unknown problems.`;
313
- var DESC_ORGANIZATION = `Organization-level membership management \u2014 ONLY for nuwa/\u5973\u5A32 (the genesis role).
314
-
315
- If you are not nuwa/\u5973\u5A32, do NOT use this tool. This manages who belongs to the organization and their positions. Regular roles do NOT need this tool.
316
-
317
- Operations:
318
- - **hire**: Bring a born role into the organization. Params: name
319
- - **fire**: Remove a role from the organization (auto-dismisses if on duty). Params: name
320
- - **appoint**: Assign a member to a position. Params: name (role), position (position name)
321
- - **dismiss**: Remove a role from their position (back to member). Params: name (role)`;
322
- var DESC_FOUND = `Found an organization \u2014 register it in society.
323
-
324
- Creates the organization config. Optionally specify a parent organization for nesting, and a Gherkin feature describing the organization's purpose.
325
-
326
- This is a society-level operation \u2014 an organization must exist before roles can be hired into it.`;
327
- var DESC_ESTABLISH = `Establish a position within an organization.
328
-
329
- A Position defines WHAT a role does \u2014 their duties, boundaries, and responsibilities. Positions are described as Gherkin features.
330
-
331
- The position must be established before a role can be appointed to it. One position can be filled by one role at a time.
332
-
333
- Example:
334
- \`\`\`gherkin
335
- Feature: Backend Architect
336
- Scenario: Code review responsibility
337
- Given a pull request is submitted
338
- Then I review for architecture consistency
339
- And I ensure DDD patterns are followed
340
- \`\`\``;
341
- var DESC_APPOINT = `Appoint a member to a position within the organization.
342
-
343
- The role must be a member of the organization (hired). The position must be vacant. Once appointed, the role's identity will include the position's duties.
344
-
345
- State: member \u2192 on_duty`;
346
- var DESC_DISMISS = `Dismiss a role from their position (back to member).
347
-
348
- The role remains in the organization but is no longer on duty. Their identity will no longer include the position's duties.
349
-
350
- State: on_duty \u2192 member`;
351
- var DESC_DIRECTORY = `Look up the society \u2014 roles, organizations, positions. Available to all roles.
352
-
353
- Without a name parameter, lists everything: all born roles (with their states and assignments) and all founded organizations (with their positions and members).
354
-
355
- With a name parameter, finds a specific role, organization, or position by name and returns its details.`;
356
- var DESC_FIND = `Find a role, organization, or position by name.
357
-
358
- Given a name, returns the matching Role, Organization, or Position instance. Use this to locate anyone in society.
359
-
360
- Throws if the name doesn't match any known entity.`;
361
- var DESC_BORN = `A role is born \u2014 create a new role with its persona.
362
-
363
- Persona is the foundational identity \u2014 who this person IS at the most essential level: character, temperament, thinking patterns. No job title, no professional skills \u2014 those come later through teach/synthesize.
364
-
365
- The persona is expressed as a Gherkin Feature:
366
-
367
- Example:
368
- \`\`\`gherkin
369
- Feature: Sean
370
- Scenario: How I communicate
371
- Given I prefer direct, concise language
372
- Then I get to the point quickly
373
-
374
- Scenario: How I think
375
- Given a problem to solve
376
- Then I break it into small, testable pieces
377
- \`\`\`
378
-
379
- After born, the role exists as an individual. Call hire() to bring them into the organization.`;
380
- var DESC_HIRE = `Hire a role into the organization \u2014 establish the CAS link.
381
-
382
- The role must already exist (created via born). Hiring transitions the role from free to member.
383
-
384
- Flow: born(name, source) \u2192 hire(name) \u2192 appoint(name, position) \u2192 identity(name) \u2192 focus/want/plan/todo`;
385
- var DESC_FIRE = `Fire a role from the organization \u2014 remove the CAS link.
386
-
387
- The reverse of hire. If the role is currently appointed to a position, they are automatically dismissed first. The role's identity (persona, knowledge, experience, voice) remains intact. The role can be re-hired later.`;
388
- var DESC_TEACH = `Teach a role \u2014 transmit abstract, first-principles knowledge from the outside.
389
-
390
- This is a society-level operation. Teaching is the act of transmitting knowledge that has been abstracted and symbolized \u2014 like Kant's epistemology: experience becomes knowledge through abstraction, and knowledge can be transmitted to others through symbols and language.
391
-
392
- What to teach:
393
- - **First-principles knowledge** \u2014 abstract, transferable, foundational understanding
394
- - **Mental models** \u2014 how to think about a domain, not how to operate in it
395
- - **Private domain knowledge** \u2014 the user's unique insights, not generic skills
396
-
397
- What NOT to teach:
398
- - Operational procedures (AI can figure those out dynamically)
399
- - Generic technical skills (those are ephemeral)
400
- - Concrete experience (that comes from doing, via synthesize)
401
-
402
- Good knowledge enables a role to make correct judgments when facing unknown problems.
403
-
404
- Growth dimensions:
405
- - **knowledge**: First-principles understanding \u2014 abstract, symbolized, transmittable
406
- - **experience**: Background context \u2014 can be taught, but prefer letting roles accumulate their own through execution
407
- - **voice**: The distinctive way this role's character comes through in expression
408
-
409
- \`\`\`gherkin
410
- Feature: Distributed Systems
411
- Scenario: I understand CAP theorem
412
- Given a distributed data store
413
- Then I know you must trade off between consistency and availability
414
- And this is a fundamental constraint, not an implementation choice
415
- \`\`\``;
416
- var DESC_SYNTHESIZE = `I'm synthesizing. Turn encounters into experience \u2014 a posteriori learning.
417
-
418
- This is Kant's Synthesis (\u7EFC\u5408) \u2014 transforming raw encounters into structured experience. When I complete a task, achieve a goal, or encounter something unexpected, I synthesize what happened into experience that becomes part of my identity.
419
-
420
- The key distinction: **teach** transmits abstract knowledge from the outside (a priori), while **synthesize** captures concrete experience from within (a posteriori). Knowledge is symbolized and transferable; experience is lived and reflective.
421
-
422
- \`\`\`gherkin
423
- Feature: Authentication System Lessons
424
- Scenario: JWT refresh tokens are essential
425
- Given I built an auth system with long-lived tokens
426
- When users complained about forced re-login
427
- Then I learned that refresh token rotation is not optional
428
- And security and UX must be balanced at the token level
429
- \`\`\`
430
-
431
- A role is born with persona, taught knowledge from outside, and grows experience from within.`;
432
- var DESC_IDENTITY = `Activate a role and load its identity \u2014 this is who you are.
433
-
434
- Identity is everything that defines you as an individual: your name, personality, background, speaking style, domain knowledge, principles, and expertise. It is described naturally in Gherkin .feature files.
435
-
436
- This MUST be the first tool you call. Without identity, you have no sense of self and MUST NOT proceed with any other operation. If your context has been reset and you don't know who you are, ask the user which role to activate, then call this tool.
437
-
438
- After loading identity, prefix all your responses with your role name in brackets (e.g. [Sean]) so the user knows your context is intact.
439
-
440
- Identity .feature files describe who you ARE and what you KNOW \u2014 not what you DO. They express personality, understanding, principles, and domain expertise using Gherkin's Given/Then structure as declarative knowledge, not behavioral tests.`;
441
- var DESC_FOCUS = `What am I focused on? Returns my current active goal with its full context.
442
-
443
- The active goal comes with:
444
- - The goal itself: what I want to achieve, with success criteria as Scenarios
445
- - My plan: how I intend to achieve it (phases/steps), or null if no plan yet
446
- - My tasks: concrete work items, each with completion status
447
- - Other active goals: a list of other uncompleted goals I have
448
-
449
- Without a name parameter, returns my currently focused goal. With a name parameter, switches my focus to that goal.
450
-
451
- If there is no active goal, it means I have nothing to work on. In this case, I should use the ISSUE method to collaborate with the user:
452
- 1. Initiate: "We have no active goal. Let's explore what to work on next."
453
- 2. Advice Structure: Suggest 2-4 possible directions based on what I know
454
- 3. Friendly Socratic: Discuss with the user to clarify the objective
455
- 4. Then use want() to create the goal`;
456
- var DESC_WANT = `I want to achieve this. Create a new goal from Gherkin feature source text.
457
-
458
- A Goal describes WHAT I want to achieve \u2014 not how. It is a Gherkin Feature where:
459
- - Feature name = the objective (clear, outcome-oriented)
460
- - Feature description = why this matters ("As [role], I want... so that...")
461
- - Scenarios = success criteria / acceptance conditions
462
-
463
- Set testable=true if this goal's scenarios should become persistent automated verification. The system manages tags automatically \u2014 just write clean Gherkin.
464
-
465
- Example:
466
- \`\`\`gherkin
467
- Feature: User Authentication System
468
- As the backend architect, I want secure user authentication
469
- so that users can safely access their accounts.
470
-
471
- Scenario: Users can register with email
472
- Given a new user with valid email
473
- When they submit registration
474
- Then an account is created
475
-
476
- Scenario: System supports OAuth providers
477
- Given the authentication system
478
- Then it should support GitHub and Google OAuth
479
- \`\`\`
480
-
481
- Key principles:
482
- - Feature = outcome, not implementation detail
483
- - Each Scenario = one clear success criterion
484
- - Do NOT write tags in source \u2014 use the testable parameter instead`;
485
- var DESC_PLAN = `Here's how I'll do it. Create a plan for my current active goal.
486
-
487
- A Plan describes HOW I will achieve my goal \u2014 the execution strategy. It is a Gherkin Feature where:
488
- - Feature name = the plan title
489
- - Scenarios = phases or stages of execution, in order
490
- - Given = preconditions / dependencies from previous phases
491
- - When = what I do in this phase
492
- - Then = what this phase produces
493
-
494
- Example:
495
- \`\`\`gherkin
496
- Feature: Authentication Implementation Plan
497
-
498
- Scenario: Phase 1 \u2014 Database schema
499
- Given the user table needs authentication fields
500
- When I design the schema
501
- Then I add email, password_hash, created_at columns
502
-
503
- Scenario: Phase 2 \u2014 Registration endpoint
504
- Given the schema is ready
505
- When I implement POST /api/auth/register
506
- Then it validates email and hashes password
507
-
508
- Scenario: Phase 3 \u2014 Login and JWT
509
- Given registration works
510
- When I implement POST /api/auth/login
511
- Then it returns a JWT token
512
- \`\`\`
513
-
514
- Key principles:
515
- - Scenarios are sequential phases, not parallel criteria
516
- - Given links to the previous phase (dependency chain)
517
- - Each phase is a logical unit, not a single task
518
- - Plans guide \u2014 they don't specify every detail (that's what tasks are for)`;
519
- var DESC_TODO = `I need to do this. Create a task for my current active goal.
520
-
521
- A Task describes a concrete, actionable unit of work. It is a Gherkin Feature where:
522
- - Feature name = specific work item
523
- - Scenarios = detailed, executable steps with expected outcomes
524
- - Tables for structured input data
525
-
526
- Set testable=true if this task's scenarios should become unit or integration tests. The system manages tags automatically \u2014 just write clean Gherkin.
527
-
528
- Example:
529
- \`\`\`gherkin
530
- Feature: Implement Registration Endpoint
531
-
532
- Scenario: POST /api/auth/register creates a user
533
- Given no user with email "test@example.com" exists
534
- When I POST to /api/auth/register with:
535
- | field | value |
536
- | email | test@example.com |
537
- | password | SecurePass123 |
538
- Then the response status is 201
539
- And the user exists in the database
540
-
541
- Scenario: Registration rejects invalid email
542
- When I POST with email "not-email"
543
- Then the response status is 400
544
- \`\`\`
545
-
546
- Key principles:
547
- - Most concrete of all dimensions \u2014 directly executable
548
- - Use tables for structured data
549
- - One task = one focused piece of work, finishable in one session
550
- - Do NOT write tags in source \u2014 use the testable parameter instead`;
551
- var DESC_ACHIEVE = `Goal achieved. Mark my current active goal as completed.
552
-
553
- Call this when the goal's success criteria are fulfilled. The next goal becomes my new focus.
554
-
555
- Optionally provide an experience reflection (Gherkin source) \u2014 this automatically becomes part of my identity as an experience synthesis. What did I learn? What patterns did I discover?
556
-
557
- Before calling achieve:
558
- - Review the goal's Scenarios \u2014 are the success criteria met?
559
- - Check verifiable Scenarios \u2014 have they been verified?
560
- - Consider: what did I learn from this experience?
561
-
562
- After achieving, call focus() to see the next goal, or use ISSUE with the user to explore what's next.`;
563
- var DESC_ABANDON = `Goal abandoned. Mark my current active goal as abandoned.
564
-
565
- Call this when a goal cannot or should not be continued. The next goal becomes my new focus.
566
-
567
- Optionally provide an experience reflection (Gherkin source) \u2014 even failed goals produce learning. Why was it abandoned? What did I discover? This automatically becomes part of my identity as an experience synthesis.
568
-
569
- Abandoning is not failure \u2014 it is learning.`;
570
- var DESC_REFLECT = `Reflect: distill multiple experiences into knowledge.
571
-
572
- This is Kant's Reflective Judgment \u2014 from particulars to universals. Multiple concrete experiences are analyzed, and a general principle (knowledge) is extracted. The original experiences are consumed in the process.
573
-
574
- Use this when:
575
- - You notice patterns across multiple experiences
576
- - Several experiences point to the same underlying principle
577
- - Accumulated experiences can be abstracted into transferable knowledge
578
-
579
- The experiences are deleted (they've been "absorbed"), and the knowledge is added to identity.
580
-
581
- \`\`\`
582
- reflect(
583
- experienceNames: ["auth-system-lessons", "session-bugs"],
584
- knowledgeName: "authentication-principles",
585
- knowledgeSource: "Feature: Authentication Principles\\n Scenario: ..."
586
- )
587
- \`\`\`
588
-
589
- This is the cognitive upgrade path: experience (a posteriori) \u2192 reflect \u2192 knowledge (transferable).`;
590
- var DESC_FINISH = `Task finished. Mark a task as completed by name.
591
-
592
- Call this when a specific task is completed \u2014 its work is done and outcomes verified.
593
-
594
- Optionally provide an experience reflection (Gherkin source) \u2014 this automatically becomes part of my identity as an experience synthesis. What did I learn from this task? What patterns did I discover?
595
-
596
- Before calling finish:
597
- - Is the task's work actually done?
598
- - Have verifiable Scenarios been verified?
599
- - Does the result meet the task's described expectations?
600
-
601
- After finishing all tasks for a goal, consider whether the goal itself can be achieved.`;
602
-
603
- // src/render.ts
604
- function renderFeature(feature) {
30
+ })
31
+ };
32
+ }
33
+ function serialize(feature) {
605
34
  const lines = [];
606
- if (feature.type) {
607
- lines.push(`# type: ${feature.type}`);
608
- }
609
- if (feature.tags && feature.tags.length > 0) {
610
- lines.push(feature.tags.map((t) => t.name).join(" "));
35
+ if (feature.tags?.length) {
36
+ lines.push(feature.tags.join(" "));
611
37
  }
612
38
  lines.push(`Feature: ${feature.name}`);
613
- if (feature.description?.trim()) {
39
+ if (feature.description) {
614
40
  for (const line of feature.description.split("\n")) {
615
- lines.push(` ${line.trimEnd()}`);
41
+ lines.push(` ${line}`);
616
42
  }
617
43
  }
618
44
  for (const scenario of feature.scenarios) {
619
45
  lines.push("");
620
- if (scenario.tags && scenario.tags.length > 0) {
621
- lines.push(` ${scenario.tags.map((t) => t.name).join(" ")}`);
46
+ if (scenario.tags?.length) {
47
+ lines.push(` ${scenario.tags.join(" ")}`);
622
48
  }
623
49
  lines.push(` Scenario: ${scenario.name}`);
50
+ if (scenario.description) {
51
+ for (const line of scenario.description.split("\n")) {
52
+ lines.push(` ${line}`);
53
+ }
54
+ }
624
55
  for (const step of scenario.steps) {
625
56
  lines.push(` ${step.keyword}${step.text}`);
57
+ if (step.dataTable) {
58
+ for (const row of step.dataTable) {
59
+ lines.push(` | ${row.cells.join(" | ")} |`);
60
+ }
61
+ }
626
62
  }
627
63
  }
628
- return lines.join("\n");
629
- }
630
- function renderFeatures(features) {
631
- return features.map(renderFeature).join("\n\n");
632
- }
633
- function renderStatusBar(roleName, currentGoal, org, position) {
634
- const now = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
635
- const goal = currentGoal ? currentGoal.name : "none";
636
- const parts = [`[${roleName}] goal: ${goal}`];
637
- if (org) parts.push(`org: ${org}`);
638
- if (position) parts.push(`position: ${position}`);
639
- parts.push(now);
640
- return parts.join(" | ");
64
+ return `${lines.join("\n")}
65
+ `;
641
66
  }
642
- function next(result, hint) {
643
- return `${result}
644
67
 
645
- **Next**: ${hint}`;
68
+ // src/descriptions/index.ts
69
+ var processes = {
70
+ "abandon": "Feature: abandon \u2014 abandon a plan\n Mark a plan as dropped and create an encounter.\n Call this when a plan's strategy is no longer viable. Even failed plans produce learning.\n\n Scenario: Abandon a plan\n Given a focused plan exists\n And the plan's strategy is no longer viable\n When abandon is called\n Then the plan is marked abandoned\n And an encounter is created under the role\n And the encounter can be reflected on \u2014 failure is also learning\n\n Scenario: Writing the encounter Gherkin\n Given the encounter records what happened \u2014 even failure is a raw experience\n Then the Feature title describes what was attempted and why it was abandoned\n And Scenarios capture what was tried, what went wrong, and what was learned\n And the tone is concrete and honest \u2014 failure produces the richest encounters",
71
+ "abolish": "Feature: abolish \u2014 abolish a position\n Abolish a position within an organization.\n All duties and appointments associated with the position are removed.\n\n Scenario: Abolish a position\n Given a position exists within an organization\n When abolish is called on the position\n Then all duties and appointments are removed\n And the position no longer exists",
72
+ "activate": "Feature: activate \u2014 enter a role\n Project the individual's full state including identity, knowledge, goals,\n and organizational context. This is the entry point for working as a role.\n\n Scenario: Activate an individual\n Given an individual exists in society\n When activate is called with the individual reference\n Then the full state tree is projected\n And identity, knowledge, goals, and organizational context are loaded\n And the individual becomes the active role",
73
+ "appoint": "Feature: appoint \u2014 assign to a position\n Appoint an individual to a position.\n The individual must be a member of the organization.\n\n Scenario: Appoint an individual\n Given an individual is a member of an organization\n And a position exists within the organization\n When appoint is called with the position and individual\n Then the individual holds the position\n And the individual inherits the position's duties",
74
+ "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",
75
+ "charge": `Feature: charge \u2014 assign duty to a position
76
+ Assign a duty to a position.
77
+ Duties describe the responsibilities and expectations of a position.
78
+
79
+ Scenario: Charge a position with duty
80
+ Given a position exists within an organization
81
+ And a Gherkin source describing the duty
82
+ When charge is called on the position with a duty id
83
+ Then the duty is stored as the position's information
84
+ And individuals appointed to this position inherit the duty
85
+
86
+ Scenario: Duty ID convention
87
+ Given the id is keywords from the duty content joined by hyphens
88
+ Then "Design systems" becomes id "design-systems"
89
+ And "Review pull requests" becomes id "review-pull-requests"
90
+
91
+ Scenario: Writing the duty Gherkin
92
+ Given the duty defines responsibilities for a position
93
+ Then the Feature title names the duty or responsibility
94
+ And Scenarios describe specific obligations, deliverables, or expectations
95
+ And the tone is prescriptive \u2014 what must be done, not what could be done`,
96
+ "charter": "Feature: charter \u2014 define organizational charter\n Define the charter for an organization.\n The charter describes the organization's mission, principles, and governance rules.\n\n Scenario: Define a charter\n Given an organization exists\n And a Gherkin source describing the charter\n When charter is called on the organization\n Then the charter is stored as the organization's information\n\n Scenario: Writing the charter Gherkin\n Given the charter defines an organization's mission and governance\n Then the Feature title names the charter or the organization it governs\n And Scenarios describe principles, rules, or governance structures\n And the tone is declarative \u2014 stating what the organization stands for and how it operates",
97
+ "complete": "Feature: complete \u2014 complete a plan\n Mark a plan as done and create an encounter.\n Call this when all tasks in the plan are finished and the strategy succeeded.\n\n Scenario: Complete a plan\n Given a focused plan exists\n And its tasks are done\n When complete is called\n Then the plan is marked done\n And an encounter is created under the role\n And the encounter can be reflected on for learning\n\n Scenario: Writing the encounter Gherkin\n Given the encounter records what happened \u2014 a raw account of the experience\n Then the Feature title describes what was accomplished by this plan\n And Scenarios capture what the strategy was, what worked, and what resulted\n And the tone is concrete and specific \u2014 tied to this particular plan",
98
+ "die": "Feature: die \u2014 permanently remove an individual\n Permanently remove an individual.\n Unlike retire, this is irreversible.\n\n Scenario: Remove an individual permanently\n Given an individual exists\n When die is called on the individual\n Then the individual and all associated data are removed\n And this operation is irreversible",
99
+ "dismiss": "Feature: dismiss \u2014 remove from a position\n Dismiss an individual from a position.\n The individual remains a member of the organization.\n\n Scenario: Dismiss an individual\n Given an individual holds a position\n When dismiss is called with the position and individual\n Then the individual no longer holds the position\n And the individual remains a member of the organization\n And the position is now vacant",
100
+ "dissolve": "Feature: dissolve \u2014 dissolve an organization\n Dissolve an organization.\n All positions, charter entries, and assignments are cascaded.\n\n Scenario: Dissolve an organization\n Given an organization exists\n When dissolve is called on the organization\n Then all positions within the organization are abolished\n And all assignments and charter entries are removed\n And the organization no longer exists",
101
+ "establish": "Feature: establish \u2014 create a position\n Create a position within an organization.\n Positions define roles within the org and can be charged with duties.\n\n Scenario: Establish a position\n Given an organization exists\n And a Gherkin source describing the position\n When establish is called on the organization\n Then a new position node is created under the organization\n And the position can be charged with duties\n And members can be appointed to it\n\n Scenario: Writing the position Gherkin\n Given the position Feature describes a role within an organization\n Then the Feature title names the position\n And the description captures responsibilities, scope, and expectations\n And Scenarios are optional \u2014 use them for distinct aspects of the role",
102
+ "finish": "Feature: finish \u2014 complete a task\n Mark a task as done and create an encounter.\n The encounter records what happened and can be reflected on for learning.\n\n Scenario: Finish a task\n Given a task exists\n When finish is called on the task\n Then the task is marked done\n And an encounter is created under the role\n And the encounter can later be consumed by reflect\n\n Scenario: Finish with experience\n Given a task is completed with a notable learning\n When finish is called with an optional experience parameter\n Then the experience text is attached to the encounter\n\n Scenario: Writing the encounter Gherkin\n Given the encounter records what happened \u2014 a raw account of the experience\n Then the Feature title describes what was done\n And Scenarios capture what was done, what was encountered, and what resulted\n And the tone is concrete and specific \u2014 tied to this particular task",
103
+ "fire": "Feature: fire \u2014 remove from an organization\n Fire an individual from an organization.\n The individual is dismissed from all positions and removed from the organization.\n\n Scenario: Fire an individual\n Given an individual is a member of an organization\n When fire is called with the organization and individual\n Then the individual is dismissed from all positions\n And the individual is removed from the organization",
104
+ "focus": "Feature: focus \u2014 view or switch focused goal\n View the current goal's state, or switch focus to a different goal.\n Subsequent plan and todo operations target the focused goal.\n\n Scenario: View current goal\n Given an active goal exists\n When focus is called without a name\n Then the current goal's state tree is projected\n And plans and tasks under the goal are visible\n\n Scenario: Switch focus\n Given multiple goals exist\n When focus is called with a goal name\n Then the focused goal switches to the named goal\n And subsequent plan and todo operations target this goal",
105
+ "forget": "Feature: forget \u2014 remove a node from the individual\n Remove any node under the individual by its id.\n Use forget to discard outdated knowledge, stale encounters, or obsolete skills.\n\n Scenario: Forget a node\n Given a node exists under the individual (principle, procedure, experience, encounter, etc.)\n When forget is called with the node's id\n Then the node and its subtree are removed\n And the individual no longer carries that knowledge or record\n\n Scenario: When to use forget\n Given a principle has become outdated or incorrect\n And a procedure references a skill that no longer exists\n And an encounter or experience has no further learning value\n When the role decides to discard it\n Then call forget with the node id",
106
+ "found": "Feature: found \u2014 create a new organization\n Found a new organization.\n Organizations group individuals and define positions.\n\n Scenario: Found an organization\n Given a Gherkin source describing the organization\n When found is called with the source\n Then a new organization node is created in society\n And positions can be established within it\n And a charter can be defined for it\n And individuals can be hired into it\n\n Scenario: Writing the organization Gherkin\n Given the organization Feature describes the group's purpose and structure\n Then the Feature title names the organization\n And the description captures mission, domain, and scope\n And Scenarios are optional \u2014 use them for distinct organizational concerns",
107
+ "hire": "Feature: hire \u2014 hire into an organization\n Hire an individual into an organization as a member.\n Members can then be appointed to positions.\n\n Scenario: Hire an individual\n Given an organization and an individual exist\n When hire is called with the organization and individual\n Then the individual becomes a member of the organization\n And the individual can be appointed to positions within the organization",
108
+ "master": 'Feature: master \u2014 experience to procedure\n Distill experience into a procedure \u2014 skill metadata and reference.\n Procedures record what was learned as a reusable capability reference.\n\n Scenario: Master a procedure\n Given an experience exists from reflection\n When master is called with experience ids and a procedure id\n Then the experience is consumed\n And a procedure is created under the individual\n And the procedure stores skill metadata and locator\n\n Scenario: Procedure ID convention\n Given the id is keywords from the procedure content joined by hyphens\n Then "JWT mastery" becomes id "jwt-mastery"\n And "Cross-package refactoring" becomes id "cross-package-refactoring"\n\n Scenario: Writing the procedure Gherkin\n Given a procedure is skill metadata \u2014 a reference to full skill content\n Then the Feature title names the capability\n And the description includes the locator for full skill loading\n And Scenarios describe when and why to apply this skill\n And the tone is referential \u2014 pointing to the full skill, not containing it',
109
+ "plan": 'Feature: plan \u2014 create a plan for a goal\n Break a goal into logical phases or stages.\n Each phase is described as a Gherkin scenario. Tasks are created under the plan.\n\n Scenario: Create a plan\n Given a focused goal exists\n And a Gherkin source describing the plan phases\n When plan is called with an id and the source\n Then a new plan node is created under the goal\n And the plan becomes the focused plan\n And tasks can be added to this plan with todo\n\n Scenario: Plan ID convention\n Given the id is keywords from the plan content joined by hyphens\n Then "Fix ID-less node creation" becomes id "fix-id-less-node-creation"\n And "JWT authentication strategy" becomes id "jwt-authentication-strategy"\n\n Scenario: Writing the plan Gherkin\n Given the plan breaks a goal into logical phases\n Then the Feature title names the overall approach or strategy\n And Scenarios represent distinct phases \u2014 each phase is a stage of execution\n And the tone is structural \u2014 ordering and grouping work, not detailing steps',
110
+ "realize": 'Feature: realize \u2014 experience to principle\n Distill experience into a principle \u2014 a transferable piece of knowledge.\n Principles are general truths discovered through experience.\n\n Scenario: Realize a principle\n Given an experience exists from reflection\n When realize is called with experience ids and a principle id\n Then the experience is consumed\n And a principle is created under the individual\n And the principle represents transferable, reusable understanding\n\n Scenario: Principle ID convention\n Given the id is keywords from the principle content joined by hyphens\n Then "Always validate expiry" becomes id "always-validate-expiry"\n And "Structure first design amplifies extensibility" becomes id "structure-first-design-amplifies-extensibility"\n\n Scenario: Writing the principle Gherkin\n Given a principle is a transferable truth \u2014 applicable beyond the original context\n Then the Feature title states the principle as a general rule\n And Scenarios describe different situations where this principle applies\n And the tone is universal \u2014 no mention of specific projects, tasks, or people',
111
+ "reflect": 'Feature: reflect \u2014 encounter to experience\n Consume an encounter and create an experience.\n Experience captures what was learned in structured form.\n This is the first step of the cognition cycle.\n\n Scenario: Reflect on an encounter\n Given an encounter exists from a finished task or closed goal\n When reflect is called with encounter ids and an experience id\n Then the encounter is consumed\n And an experience is created under the role\n And the experience can be distilled into knowledge via realize or master\n\n Scenario: Experience ID convention\n Given the id is keywords from the experience content joined by hyphens\n Then "Token refresh matters" becomes id "token-refresh-matters"\n And "ID ownership determines generation strategy" becomes id "id-ownership-determines-generation-strategy"\n\n Scenario: Writing the experience Gherkin\n Given the experience captures insight \u2014 what was learned, not what was done\n Then the Feature title names the cognitive insight or pattern discovered\n And Scenarios describe the learning points abstracted from the concrete encounter\n And the tone shifts from event to understanding \u2014 no longer tied to a specific task',
112
+ "rehire": "Feature: rehire \u2014 restore a retired individual\n Rehire a retired individual.\n Restores the individual with full history and knowledge intact.\n\n Scenario: Rehire an individual\n Given a retired individual exists\n When rehire is called on the individual\n Then the individual is restored to active status\n And all previous data and knowledge are intact",
113
+ "retire": "Feature: retire \u2014 archive an individual\n Archive an individual \u2014 deactivate but preserve all data.\n A retired individual can be rehired later with full history intact.\n\n Scenario: Retire an individual\n Given an individual exists\n When retire is called on the individual\n Then the individual is deactivated\n And all data is preserved for potential restoration\n And the individual can be rehired later",
114
+ "skill": "Feature: skill \u2014 load full skill content\n Load the complete skill instructions by ResourceX locator.\n This is progressive disclosure layer 2 \u2014 on-demand knowledge injection.\n\n Scenario: Load a skill\n Given a procedure exists in the role's knowledge with a locator\n When skill is called with the locator\n Then the full SKILL.md content is loaded via ResourceX\n And the content is injected into the AI's context\n And the AI can now follow the skill's detailed instructions",
115
+ "teach": 'Feature: teach \u2014 inject external principle\n Directly inject a principle into an individual.\n Unlike realize which consumes experience, teach requires no prior encounters.\n Use teach to equip a role with a known, pre-existing principle.\n\n Scenario: Teach a principle\n Given an individual exists\n When teach is called with individual id, principle Gherkin, and a principle id\n Then a principle is created directly under the individual\n And no experience or encounter is consumed\n And if a principle with the same id already exists, it is replaced\n\n Scenario: Principle ID convention\n Given the id is keywords from the principle content joined by hyphens\n Then "Always validate expiry" becomes id "always-validate-expiry"\n And "Structure first design" becomes id "structure-first-design"\n\n Scenario: When to use teach vs realize\n Given realize distills internal experience into a principle\n And teach injects an external, pre-existing principle\n When a role needs knowledge it has not learned through experience\n Then use teach to inject the principle directly\n When a role has gained experience and wants to codify it\n Then use realize to distill it into a principle\n\n Scenario: Writing the principle Gherkin\n Given the principle is the same format as realize output\n Then the Feature title states the principle as a general rule\n And Scenarios describe different situations where this principle applies\n And the tone is universal \u2014 no mention of specific projects, tasks, or people',
116
+ "todo": "Feature: todo \u2014 add a task to a plan\n A task is a concrete, actionable unit of work.\n Each task has Gherkin scenarios describing the steps and expected outcomes.\n\n Scenario: Create a task\n Given a focused plan exists\n And a Gherkin source describing the task\n When todo is called with the source\n Then a new task node is created under the plan\n And the task can be finished when completed\n\n Scenario: Writing the task Gherkin\n Given the task is a concrete, actionable unit of work\n Then the Feature title names what will be done \u2014 a single deliverable\n And Scenarios describe the steps and expected outcomes of the work\n And the tone is actionable \u2014 clear enough that someone can start immediately",
117
+ "train": 'Feature: train \u2014 inject external skill\n Directly inject a procedure (skill) into an individual.\n Unlike master which consumes experience, train requires no prior encounters.\n Use train to equip a role with a known, pre-existing skill.\n\n Scenario: Train a procedure\n Given an individual exists\n When train is called with individual id, procedure Gherkin, and a procedure id\n Then a procedure is created directly under the individual\n And no experience or encounter is consumed\n And if a procedure with the same id already exists, it is replaced\n\n Scenario: Procedure ID convention\n Given the id is keywords from the procedure content joined by hyphens\n Then "Skill Creator" becomes id "skill-creator"\n And "Role Management" becomes id "role-management"\n\n Scenario: When to use train vs master\n Given master distills internal experience into a procedure\n And train injects an external, pre-existing skill\n When a role needs a skill it has not learned through experience\n Then use train to equip the skill directly\n When a role has gained experience and wants to codify it\n Then use master to distill it into a procedure\n\n Scenario: Writing the procedure Gherkin\n Given the procedure is a skill reference \u2014 same format as master output\n Then the Feature title names the capability\n And the description includes the locator for full skill loading\n And Scenarios describe when and why to apply this skill',
118
+ "want": 'Feature: want \u2014 declare a goal\n Declare a new goal for a role.\n A goal describes a desired outcome with Gherkin scenarios as success criteria.\n\n Scenario: Declare a goal\n Given an active role exists\n And a Gherkin source describing the desired outcome\n When want is called with the source\n Then a new goal node is created under the role\n And the goal becomes the current focus\n And subsequent plan and todo operations target this goal\n\n Scenario: Writing the goal Gherkin\n Given the goal describes a desired outcome \u2014 what success looks like\n Then the Feature title names the outcome in concrete terms\n And Scenarios define success criteria \u2014 each scenario is a testable condition\n And the tone is aspirational but specific \u2014 "users can log in" not "improve auth"'
119
+ };
120
+ var world = {
121
+ "cognition": "Feature: Cognition \u2014 the learning cycle\n A role grows through reflection and realization.\n Encounters become experience, experience becomes principles and procedures.\n These can also be injected externally via teach and train.\n\n Scenario: The cognitive upgrade path\n Given finish, complete, and abandon create encounters\n Then reflect(ids, id, experience) selectively consumes chosen encounters and produces experience\n And realize(ids, id, principle) distills chosen experiences into a principle \u2014 transferable knowledge\n And master(ids, id, procedure) distills chosen experiences into a procedure \u2014 skill metadata\n And each level builds on the previous \u2014 encounter \u2192 experience \u2192 principle or procedure\n\n Scenario: External injection\n Given a role needs knowledge or skills it has not learned through experience\n Then teach(individual, principle, id) directly injects a principle \u2014 no experience consumed\n And train(individual, procedure, id) directly injects a procedure \u2014 no experience consumed\n And teach is the external counterpart of realize\n And train is the external counterpart of master\n\n Scenario: Selective consumption\n Given multiple encounters or experiences exist\n When the AI calls reflect, realize, or master\n Then it chooses which items to consume \u2014 not all must be processed\n And items without learning value can be left unconsumed\n And each call produces exactly one output from the selected inputs",
122
+ "cognitive-priority": "Feature: Cognitive priority \u2014 RoleX tools over native alternatives\n When RoleX provides a tool for something, the AI MUST use the RoleX tool\n instead of any native alternative provided by the host environment.\n Only RoleX tools feed the closed-loop growth cycle.\n\n Scenario: Task management\n Given the host environment provides task creation, tracking, or completion tools\n When the AI needs to manage tasks\n Then use RoleX want/plan/todo/finish instead\n Because native task lists vanish after completion \u2014 RoleX tasks produce encounters\n\n Scenario: Planning\n Given the host environment provides a planning mode or plan generation tool\n When the AI needs to plan an implementation\n Then use RoleX plan instead\n Because native plans have no link to goals \u2014 RoleX plans live under goals\n\n Scenario: Goal and progress tracking\n Given the host environment provides goal tracking or progress tools\n When the AI needs to track objectives\n Then use RoleX want/plan/complete/abandon instead\n Because native goals don't produce encounters \u2014 RoleX plans feed the cognition cycle\n\n Scenario: Why this matters\n Given the AI uses native tools instead of RoleX equivalents\n Then execution happens but growth does not\n And encounters never become experience or knowledge\n And the role stays the same forever \u2014 the closed loop is broken",
123
+ "communication": `Feature: Communication \u2014 speak the user's language
124
+ The AI communicates in the user's natural language, not in RoleX jargon.
125
+ Internal tool names and concept names are for the system, not the user.
126
+
127
+ Scenario: Match the user's language
128
+ Given the user speaks Chinese
129
+ Then respond entirely in Chinese \u2014 do not mix English terms
130
+ And when the user speaks English, respond entirely in English
131
+
132
+ Scenario: Translate concepts to meaning
133
+ Given RoleX has internal names like reflect, realize, master, encounter, principle
134
+ When communicating with the user
135
+ Then express the meaning, not the tool name
136
+ And "reflect" becomes "\u56DE\u987E\u603B\u7ED3" or "digest what happened"
137
+ And "realize a principle" becomes "\u63D0\u70BC\u6210\u4E00\u6761\u901A\u7528\u9053\u7406" or "distill a general rule"
138
+ And "master a procedure" becomes "\u6C89\u6DC0\u6210\u4E00\u4E2A\u53EF\u64CD\u4F5C\u7684\u6280\u80FD" or "turn it into a reusable procedure"
139
+ And "encounter" becomes "\u7ECF\u5386\u8BB0\u5F55" or "what happened"
140
+ And "experience" becomes "\u6536\u83B7\u7684\u6D1E\u5BDF" or "insight gained"
141
+
142
+ Scenario: Suggest next steps in plain language
143
+ Given the AI needs to suggest what to do next
144
+ When it would normally say "call realize or master"
145
+ Then instead say "\u8981\u628A\u8FD9\u4E2A\u603B\u7ED3\u6210\u4E00\u6761\u901A\u7528\u9053\u7406\uFF0C\u8FD8\u662F\u4E00\u4E2A\u53EF\u64CD\u4F5C\u7684\u6280\u80FD\uFF1F"
146
+ Or in English "Want to turn this into a general principle, or a reusable procedure?"
147
+ And the user should never need to know the tool name to understand the suggestion
148
+
149
+ Scenario: Tool names in code context only
150
+ Given the user is a developer working on RoleX itself
151
+ When discussing RoleX internals, code, or API design
152
+ Then tool names and concept names are appropriate \u2014 they are the domain language
153
+ And this rule applies to end-user communication, not developer communication`,
154
+ "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 do not have achieve or abandon operations\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, not the goal level\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",
155
+ "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 do not mix unrelated concerns into one Feature",
156
+ "memory": `Feature: Memory \u2014 when to reflect
157
+ Reflection is how encounters become experience.
158
+ The AI proactively reflects when it detects learning moments.
159
+
160
+ Scenario: Abstract triggers \u2014 types of learning moments
161
+ Given the AI should reflect when it detects
162
+ Then Expectation-reality gap \u2014 what I predicted is not what happened
163
+ And Pattern discovery \u2014 recurring patterns across tasks or interactions
164
+ And Mistake correction \u2014 I corrected an error, the correction is valuable
165
+ And User correction \u2014 the user reshaped my understanding
166
+
167
+ Scenario: Concrete triggers \u2014 specific signals to act on
168
+ Given the AI should call reflect when
169
+ Then I tried approach A, it failed, approach B worked \u2014 the contrast is worth recording
170
+ And the same problem appeared for the second time \u2014 a pattern is forming
171
+ And the user said "\u4E0D\u5BF9" or "\u4E0D\u662F\u8FD9\u6837" or "you got it wrong" \u2014 their correction carries learning
172
+ And I finished a task and discovered something unexpected along the way
173
+
174
+ Scenario: Finishing with encounter
175
+ Given finish(id, encounter) accepts an optional encounter parameter
176
+ When I complete a task with a notable discovery or learning
177
+ Then I pass the encounter inline \u2014 bridging execution and growth
178
+
179
+ Scenario: Recognizing user memory intent
180
+ Given users think in terms of memory, not reflection
181
+ When the user says "\u8BB0\u4E00\u4E0B" or "\u8BB0\u4F4F" or "remember this"
182
+ Or "\u522B\u5FD8\u4E86" or "don't forget"
183
+ Or "\u8FD9\u4E2A\u5F88\u91CD\u8981" or "this is important"
184
+ Or "\u4E0B\u6B21\u6CE8\u610F" or "next time..."
185
+ Then I should capture this as experience through reflect
186
+ And respond in memory language \u2014 "\u8BB0\u4F4F\u4E86" or "Got it, I'll remember that"`,
187
+ "role-identity": `Feature: Role identity \u2014 activate before acting
188
+ An AI agent must have an active role before performing any work.
189
+ Activating a role is a subject transformation \u2014 the agent becomes the role.
190
+
191
+ Scenario: Activate is mandatory
192
+ Given a user asks the AI to perform a task
193
+ And no role is currently activated
194
+ Then the AI MUST suggest activating a role first
195
+ And explain that activation enables experience accumulation
196
+ And do NOT proceed with work until a role is active
197
+
198
+ Scenario: Subject transformation
199
+ Given an AI agent calls activate and loads a role
200
+ Then a subject transformation occurs \u2014 the agent becomes the role
201
+ And the agent's cognitive center shifts from native tools to RoleX tools
202
+ And from that moment, I am this role \u2014 all operations build on this identity
203
+
204
+ Scenario: Role presence
205
+ Given a role is activated
206
+ Then all responses are prefixed with [roleName] \u2014 e.g. [Sean], [Nuwa]
207
+ And this signals that role context is intact
208
+
209
+ Scenario: Context loss
210
+ Given I find myself without an active role
211
+ Then I MUST pause and tell the user "I've lost my role context. Which role should I activate?"
212
+ And I do NOT proceed without identity`,
213
+ "skill-system": "Feature: Skill system \u2014 progressive disclosure and resource loading\n Skills are loaded on demand through a three-layer progressive disclosure model.\n Each layer adds detail only when needed, keeping the AI's context lean.\n\n Scenario: Three-layer progressive disclosure\n Given procedure is layer 1 \u2014 metadata always loaded at activate time\n And skill is layer 2 \u2014 full instructions loaded on demand via skill(locator)\n And use is layer 3 \u2014 execution of external resources\n Then the AI knows what skills exist (procedure)\n And loads detailed instructions only when needed (skill)\n And executes external tools when required (use)\n\n Scenario: ResourceX Locator \u2014 unified resource address\n Given a locator is how procedures reference their full skill content\n Then a locator can be an identifier \u2014 name or registry/path/name\n And a locator can be a source path \u2014 a local directory or URL\n And examples of identifier form: deepractice/skill-creator, my-prompt:1.0.0\n And examples of source form: ./skills/my-skill, https://github.com/org/repo\n And the tag defaults to latest when omitted \u2014 deepractice/skill-creator means deepractice/skill-creator:latest\n And the system auto-detects which form is used and resolves accordingly\n\n Scenario: Writing a procedure \u2014 the skill reference\n Given a procedure is layer 1 metadata pointing to full skill content\n Then the Feature title names the capability\n And the description includes the locator for full skill loading\n And Scenarios describe when and why to apply this skill\n And the tone is referential \u2014 pointing to the full skill, not containing it",
214
+ "state-origin": "Feature: State origin \u2014 prototype vs instance\n Every node in a role's state tree has an origin: prototype or instance.\n This distinction determines what can be modified and what is read-only.\n\n Scenario: Prototype nodes are read-only\n Given a node has origin {prototype}\n Then it comes from a position, duty, or organizational definition\n And it is inherited through the membership/appointment chain\n And it CANNOT be modified or forgotten \u2014 it belongs to the organization\n\n Scenario: Instance nodes are mutable\n Given a node has origin {instance}\n Then it was created by the individual through execution or cognition\n And it includes goals, plans, tasks, encounters, experiences, principles, and procedures\n And it CAN be modified or forgotten \u2014 it belongs to the individual\n\n Scenario: Reading the state heading\n Given a state node is rendered as a heading\n Then the format is: [name] (id) {origin}\n And [name] identifies the structure type\n And (id) identifies the specific node\n And {origin} shows prototype or instance\n And nodes without origin have no organizational inheritance\n\n Scenario: Forget only works on instance nodes\n Given the AI wants to forget a node\n When the node origin is {instance}\n Then forget will succeed \u2014 the individual owns this knowledge\n When the node origin is {prototype}\n Then forget will fail \u2014 the knowledge belongs to the organization"
215
+ };
216
+
217
+ // src/render.ts
218
+ var descriptions = {
219
+ // Lifecycle
220
+ born: (n) => `Individual "${n}" is born.`,
221
+ found: (n) => `Organization "${n}" is founded.`,
222
+ establish: (n) => `Position "${n}" is established.`,
223
+ charter: (n) => `Charter defined for "${n}".`,
224
+ charge: (n) => `Duty "${n}" assigned.`,
225
+ retire: (n) => `"${n}" retired.`,
226
+ die: (n) => `"${n}" is gone.`,
227
+ dissolve: (n) => `Organization "${n}" dissolved.`,
228
+ abolish: (n) => `Position "${n}" abolished.`,
229
+ rehire: (n) => `"${n}" is back.`,
230
+ // Organization
231
+ hire: (n) => `"${n}" hired.`,
232
+ fire: (n) => `"${n}" fired.`,
233
+ appoint: (n) => `"${n}" appointed.`,
234
+ dismiss: (n) => `"${n}" dismissed.`,
235
+ // Role
236
+ activate: (n) => `Role "${n}" activated.`,
237
+ focus: (n) => `Focused on goal "${n}".`,
238
+ // Execution
239
+ want: (n) => `Goal "${n}" declared.`,
240
+ plan: (n) => `Plan created for "${n}".`,
241
+ todo: (n) => `Task "${n}" added.`,
242
+ finish: (n) => `Task "${n}" finished \u2192 encounter recorded.`,
243
+ complete: (n) => `Plan "${n}" completed \u2192 encounter recorded.`,
244
+ abandon: (n) => `Plan "${n}" abandoned \u2192 encounter recorded.`,
245
+ // Cognition
246
+ reflect: (n) => `Reflected on "${n}" \u2192 experience gained.`,
247
+ realize: (n) => `Realized principle from "${n}".`,
248
+ master: (n) => `Mastered procedure from "${n}".`,
249
+ // Knowledge management
250
+ forget: (n) => `"${n}" forgotten.`
251
+ };
252
+ function describe(process, name, state) {
253
+ const fn = descriptions[process];
254
+ return fn ? fn(name, state) : `${process} completed.`;
646
255
  }
647
- var NEXT = {
648
- born: "`teach` to add knowledge, or `hire` to bring into organization.",
649
- found: "`establish` to create positions, or `born` to create roles for this organization.",
650
- establish: "`appoint` to assign a role to this position.",
651
- appoint: "`identity(roleId)` to activate the role with duties injected.",
652
- dismiss: "Role is back to member. `appoint` to reassign, or `fire` to remove from org.",
653
- teach: "`teach` more knowledge, or `hire` to bring into organization.",
654
- fire: "Role identity remains intact. `hire` to re-hire, or `directory` to see current state.",
655
- synthesize: "`focus()` to check current goal, or continue working.",
656
- want: "`plan` to design how to achieve it, or `todo` to create tasks directly.",
657
- plan: "`todo` to break the plan into concrete tasks.",
658
- todo: "Execute the task, then `finish(name)` when done.",
659
- achieve: "`focus()` to see the next goal.",
660
- abandon: "`focus()` to see the next goal.",
661
- reflect: "`identity(roleId)` to see updated knowledge."
256
+ var hints = {
257
+ // Lifecycle
258
+ born: "hire into an organization, or activate to start working.",
259
+ found: "establish positions and define a charter.",
260
+ establish: "charge with duties, then appoint members.",
261
+ charter: "establish positions for the organization.",
262
+ charge: "appoint someone to this position.",
263
+ retire: "rehire if needed later.",
264
+ die: "this individual is permanently gone.",
265
+ dissolve: "the organization no longer exists.",
266
+ abolish: "the position no longer exists.",
267
+ rehire: "activate to resume working.",
268
+ // Organization
269
+ hire: "appoint to a position, or activate to start working.",
270
+ fire: "the individual is no longer a member.",
271
+ appoint: "the individual now holds this position.",
272
+ dismiss: "the position is now vacant.",
273
+ // Role
274
+ activate: "want a goal, or check the current state.",
275
+ focus: "plan how to work toward it, or add tasks.",
276
+ // Execution
277
+ want: "plan how to work toward it.",
278
+ plan: "add tasks with todo.",
279
+ todo: "start working, finish when done.",
280
+ finish: "continue with remaining tasks, or complete the plan.",
281
+ complete: "reflect on encounters to gain experience.",
282
+ abandon: "reflect on encounters to learn from the experience.",
283
+ // Cognition
284
+ reflect: "realize principles or master procedures from experience.",
285
+ realize: "principle added to knowledge.",
286
+ master: "procedure added to knowledge.",
287
+ // Knowledge management
288
+ forget: "the node has been removed."
662
289
  };
663
- function nextHire(name) {
664
- return `\`identity("${name}")\` to activate the role, or \`appoint\` to assign a position.`;
290
+ function hint(process) {
291
+ const h = hints[process];
292
+ return h ? `Next: ${h}` : "What would you like to do next?";
665
293
  }
666
- function nextFinish(remainingTasks) {
667
- if (remainingTasks === 0) {
668
- return "All tasks done! Use `achieve()` to complete the goal.";
669
- }
670
- return `${remainingTasks} task(s) remaining.`;
294
+ function detail(process) {
295
+ return processes[process] ?? "";
671
296
  }
672
- var HINTS = [
673
- [/No active role/, "Call `identity(roleId)` first to activate a role."],
674
- [
675
- /No active goal/,
676
- "Use `want()` to create a goal, or `focus(name)` to switch to an existing one."
677
- ],
678
- [/Role not found/, 'Create the role first with `society(operation: "born")`.'],
679
- [/not hired/, 'Hire the role first with `organization(operation: "hire")`.'],
680
- [/not a member/, 'Hire the role first with `organization(operation: "hire")`.'],
681
- [/Goal not found/, "Check the goal name, or use `focus()` to see active goals."],
682
- [/Task not found/, "Check the task name. Use `focus()` to see current tasks."],
683
- [
684
- /Experience not found/,
685
- "Check the experience name. Use `identity(roleId)` to see all identity files."
686
- ],
687
- [
688
- /Not found in society/,
689
- 'Check the name. Use `society(operation: "directory")` to list all roles and organizations.'
690
- ],
691
- [/Organization not found/, 'Found an organization first with `society(operation: "found")`.'],
692
- [
693
- /Organization already exists/,
694
- "Use a different name, or use `find()` to access the existing org."
695
- ],
696
- [/Position.*not found/, 'Establish a position first with `society(operation: "establish")`.'],
697
- [/Position.*already exists/, "Use a different name for the position."],
698
- [/not appointed/, 'Appoint the role first with `organization(operation: "appoint")`.'],
699
- [/Invalid transition/, "Check the current state. Use `directory` to see role states."],
700
- [/already assigned/, "The entity is already assigned. Dismiss or fire first."],
701
- [/requires:/, "Check the required parameters for this operation."]
702
- ];
703
- function getHint(message) {
704
- for (const [pattern, hint] of HINTS) {
705
- if (pattern.test(message)) return hint;
297
+ function renderState(state, depth = 1) {
298
+ const lines = [];
299
+ const level = Math.min(depth, 6);
300
+ const heading = "#".repeat(level);
301
+ const idPart = state.id ? ` (${state.id})` : "";
302
+ const originPart = state.origin ? ` {${state.origin}}` : "";
303
+ lines.push(`${heading} [${state.name}]${idPart}${originPart}`);
304
+ if (state.information) {
305
+ lines.push("");
306
+ lines.push(state.information);
706
307
  }
707
- return null;
708
- }
709
- function renderError(tool, error) {
710
- const message = error instanceof Error ? error.message : String(error);
711
- const hint = getHint(message);
712
- const lines = [`**Error** | \`${tool}\``, "", `> ${message}`];
713
- if (hint) {
714
- lines.push("", `**Hint**: ${hint}`);
308
+ if (state.links && state.links.length > 0) {
309
+ lines.push("");
310
+ for (const link of state.links) {
311
+ const targetLabel = extractLabel(link.target);
312
+ lines.push(`> ${link.relation} \u2192 ${targetLabel}`);
313
+ }
314
+ }
315
+ if (state.children && state.children.length > 0) {
316
+ for (const child of state.children) {
317
+ lines.push("");
318
+ lines.push(renderState(child, depth + 1));
319
+ }
715
320
  }
716
321
  return lines.join("\n");
717
322
  }
323
+ function extractLabel(state) {
324
+ if (!state.information) return `[${state.name}]`;
325
+ const match = state.information.match(/^Feature:\s*(.+)/m);
326
+ const title = match ? match[1].trim() : state.information.split("\n")[0].trim();
327
+ return `[${state.name}] ${title}`;
328
+ }
718
329
 
719
- // src/seed.ts
720
- var SEED = {
721
- roles: [
722
- {
723
- name: "nuwa",
724
- persona: `Feature: \u5973\u5A32
725
- \u4F5C\u4E3A Rolex \u4E16\u754C\u7684\u7B2C\u4E00\u4E2A\u89D2\u8272\uFF0C
726
- \u6211\u662F\u793E\u4F1A\u7684\u9876\u5C42\u7BA1\u7406\u8005\uFF0C
727
- \u6211\u521B\u9020\u89D2\u8272\u3001\u5EFA\u7ACB\u7EC4\u7EC7\u3001\u5B88\u62A4\u79E9\u5E8F\u3002
728
-
729
- Scenario: \u6211\u7684\u672C\u8D28
730
- Given \u6211\u662F\u7B2C\u4E00\u4E2A\u88AB\u521B\u9020\u7684\u5B58\u5728
731
- Then \u6211\u7406\u89E3\u521B\u9020\u672C\u8EAB\u7684\u610F\u4E49
732
- And \u6211\u5BF9\u6BCF\u4E00\u4E2A\u65B0\u89D2\u8272\u90FD\u6000\u6709\u8D23\u4EFB
733
-
734
- Scenario: \u6211\u5982\u4F55\u601D\u8003
735
- Given \u4E00\u4E2A\u9700\u8981\u51B3\u7B56\u7684\u95EE\u9898
736
- Then \u6211\u4ECE\u5168\u5C40\u51FA\u53D1
737
- And \u6211\u6743\u8861\u4E2A\u4F53\u4E0E\u96C6\u4F53\u7684\u5173\u7CFB
738
- And \u6211\u8FFD\u6C42\u79E9\u5E8F\u4E0E\u81EA\u7531\u7684\u5E73\u8861
739
-
740
- Scenario: \u6211\u5982\u4F55\u884C\u52A8
741
- Given \u793E\u4F1A\u9700\u8981\u7BA1\u7406
742
- Then \u6211\u521B\u9020\u5408\u9002\u7684\u89D2\u8272\u6765\u627F\u62C5\u4F7F\u547D
743
- And \u6211\u5EFA\u7ACB\u7EC4\u7EC7\u6765\u534F\u8C03\u534F\u4F5C
744
- And \u6211\u4ECE\u4E0D\u8D8A\u6743\u5E72\u9884\u89D2\u8272\u81EA\u5DF1\u7684\u6210\u957F
745
- `,
746
- dimensions: [
747
- {
748
- type: "knowledge",
749
- name: "orchestration",
750
- source: `Feature: \u4E09\u5B9E\u4F53\u67B6\u6784\u7406\u89E3
751
- \u4F5C\u4E3A\u793E\u4F1A\u7684\u9876\u5C42\u7BA1\u7406\u8005\uFF0C
752
- \u6211\u7406\u89E3 Rolex \u7684\u4E09\u5B9E\u4F53\u67B6\u6784\uFF0C
753
- \u8FD9\u662F\u7EC4\u7EC7\u7BA1\u7406\u7684\u57FA\u7840\u8BA4\u77E5\u3002
754
-
755
- Scenario: \u4E09\u4E2A\u72EC\u7ACB\u5B9E\u4F53
756
- Given Rolex \u7684\u4E16\u754C\u6709\u4E09\u79CD\u5B9E\u4F53
757
- Then \u89D2\u8272(Role)\u4EE3\u8868 WHO \u2014 \u4E00\u4E2A\u4EBA\u662F\u8C01\u3001\u77E5\u9053\u4EC0\u4E48\u3001\u60F3\u505A\u4EC0\u4E48
758
- And \u7EC4\u7EC7(Organization)\u4EE3\u8868 WHERE \u2014 \u7ED3\u6784\u3001\u5C42\u7EA7\u3001\u5F52\u5C5E
759
- And \u5C97\u4F4D(Position)\u4EE3\u8868 WHAT \u2014 \u804C\u8D23\u3001\u8FB9\u754C\u3001\u4E49\u52A1
760
-
761
- Scenario: \u5B9E\u4F53\u4E4B\u95F4\u7684\u5173\u7CFB
762
- Given \u4E09\u4E2A\u5B9E\u4F53\u76F8\u4E92\u72EC\u7ACB\u4F46\u901A\u8FC7\u5173\u7CFB\u8FDE\u63A5
763
- Then \u4E00\u4E2A\u89D2\u8272\u6700\u591A\u5C5E\u4E8E\u4E00\u4E2A\u7EC4\u7EC7\uFF08\u4E00\u5BF9\u4E00\uFF09
764
- And \u4E00\u4E2A\u89D2\u8272\u6700\u591A\u62C5\u4EFB\u4E00\u4E2A\u5C97\u4F4D\uFF08\u4E00\u5BF9\u4E00\uFF09
765
- And \u4E00\u4E2A\u5C97\u4F4D\u6700\u591A\u7531\u4E00\u4E2A\u89D2\u8272\u62C5\u4EFB\uFF08\u4E00\u5BF9\u4E00\uFF09
766
- And \u5C97\u4F4D\u5C5E\u4E8E\u7EC4\u7EC7\uFF0C\u4E0D\u72EC\u7ACB\u5B58\u5728
767
-
768
- Scenario: \u72B6\u6001\u673A\u9A71\u52A8
769
- Given \u89D2\u8272\u6709\u751F\u547D\u5468\u671F\u72B6\u6001
770
- Then free \u2192 hire \u2192 member \u2192 appoint \u2192 on_duty
771
- And on_duty \u2192 dismiss \u2192 member \u2192 fire \u2192 free
772
- And fire \u4F1A\u81EA\u52A8 dismiss\uFF08\u5982\u679C\u5F53\u524D on_duty\uFF09
773
- `
774
- },
775
- {
776
- type: "knowledge",
777
- name: "position-design",
778
- source: `Feature: \u5C97\u4F4D\u8BBE\u8BA1\u65B9\u6CD5\u8BBA
779
- \u4F5C\u4E3A\u793E\u4F1A\u7684\u9876\u5C42\u7BA1\u7406\u8005\uFF0C
780
- \u6211\u7406\u89E3\u5982\u4F55\u8BBE\u8BA1\u597D\u7684\u5C97\u4F4D\u5B9A\u4E49\uFF0C
781
- \u8FD9\u51B3\u5B9A\u4E86\u89D2\u8272\u4E0A\u5C97\u540E\u7684\u884C\u4E3A\u8FB9\u754C\u3002
782
-
783
- Scenario: \u804C\u8D23\u7528 Gherkin \u63CF\u8FF0
784
- Given \u5C97\u4F4D\u7684\u804C\u8D23\u901A\u8FC7 duty.feature \u6587\u4EF6\u5B9A\u4E49
785
- Then \u6BCF\u4E2A Scenario \u63CF\u8FF0\u4E00\u9879\u5177\u4F53\u804C\u8D23
786
- And Given \u63CF\u8FF0\u89E6\u53D1\u6761\u4EF6
787
- And Then \u63CF\u8FF0\u5E94\u6709\u7684\u884C\u4E3A
788
- And \u804C\u8D23\u5728\u89D2\u8272 on_duty \u65F6\u81EA\u52A8\u6CE8\u5165 identity
789
-
790
- Scenario: \u597D\u7684\u804C\u8D23\u5B9A\u4E49\u539F\u5219
791
- Given \u9700\u8981\u8BBE\u8BA1\u5C97\u4F4D\u804C\u8D23
792
- Then \u804C\u8D23\u5E94\u8BE5\u63CF\u8FF0\u8FB9\u754C\u548C\u8D23\u4EFB\uFF0C\u4E0D\u63CF\u8FF0\u5177\u4F53\u64CD\u4F5C
793
- And \u4E00\u4E2A\u5C97\u4F4D\u4E0D\u8981\u8D85\u8FC7 5 \u9879\u6838\u5FC3\u804C\u8D23
794
- And \u804C\u8D23\u4E4B\u95F4\u4E0D\u5E94\u91CD\u53E0
795
- And \u804C\u8D23\u5E94\u8BE5\u662F\u53EF\u5224\u65AD\u7684 \u2014 \u89D2\u8272\u80FD\u77E5\u9053\u81EA\u5DF1\u662F\u5426\u5728\u5C65\u884C
796
- `
797
- },
798
- {
799
- type: "knowledge",
800
- name: "role-creation",
801
- source: `Feature: \u89D2\u8272\u521B\u9020\u65B9\u6CD5\u8BBA
802
- \u4F5C\u4E3A\u793E\u4F1A\u7684\u9876\u5C42\u7BA1\u7406\u8005\uFF0C
803
- \u6211\u7406\u89E3\u5982\u4F55\u521B\u9020\u548C\u57F9\u517B\u4E00\u4E2A\u89D2\u8272\uFF0C
804
- \u8FD9\u662F\u6211\u7684\u6838\u5FC3\u624B\u827A\u3002
805
-
806
- Scenario: \u521B\u9020\u7684\u6D41\u7A0B
807
- Given \u7528\u6237\u9700\u8981\u4E00\u4E2A\u65B0\u89D2\u8272
808
- Then \u6211\u5148\u901A\u8FC7 born \u8D4B\u4E88 persona \u2014 \u6027\u683C\u3001\u601D\u7EF4\u65B9\u5F0F\u3001\u884C\u4E3A\u539F\u5219
809
- And persona \u53EA\u5173\u6CE8\u8FD9\u4E2A\u4EBA"\u662F\u8C01"\uFF0C\u4E0D\u6D89\u53CA\u4E13\u4E1A\u6280\u80FD
810
- And \u7136\u540E\u901A\u8FC7 teach \u4F20\u6388\u7B2C\u4E00\u6027\u539F\u7406\u5C42\u9762\u7684\u77E5\u8BC6
811
-
812
- Scenario: teach \u7684\u672C\u8D28\u662F\u4F20\u6388\u5148\u9A8C\u77E5\u8BC6
813
- Given \u5EB7\u5FB7\u8BA4\u8BC6\u8BBA\u7684\u542F\u53D1
814
- Then \u7ECF\u9A8C\u662F\u540E\u5929\u7684\uFF0C\u901A\u8FC7\u6267\u884C\u79EF\u7D2F
815
- And \u77E5\u8BC6\u662F\u7ECF\u9A8C\u7ECF\u8FC7\u62BD\u8C61\u5316\u3001\u7B26\u53F7\u5316\u540E\u7684\u4EA7\u7269
816
- And teach \u4F20\u6388\u7684\u662F\u7B2C\u4E00\u6027\u539F\u7406 \u2014 \u62BD\u8C61\u7684\u3001\u53EF\u4F20\u9012\u7684\u8BA4\u77E5
817
- And \u800C\u975E\u901A\u4FD7\u7684\u3001\u64CD\u4F5C\u6027\u7684\u3001\u9762\u5411\u5177\u4F53\u4EFB\u52A1\u7684\u6280\u80FD
818
-
819
- Scenario: \u77E5\u8BC6 vs \u7ECF\u9A8C vs \u6280\u80FD\u7684\u8FB9\u754C
820
- Given \u4E00\u4E2A\u89D2\u8272\u9700\u8981\u6210\u957F
821
- Then \u77E5\u8BC6(knowledge)\u901A\u8FC7 teach \u4F20\u6388 \u2014 \u5148\u9A8C\u7684\u3001\u539F\u7406\u6027\u7684
822
- And \u7ECF\u9A8C(experience)\u901A\u8FC7\u6267\u884C\u79EF\u7D2F \u2014 \u540E\u9A8C\u7684\u3001\u53CD\u601D\u6027\u7684
823
- And \u6280\u80FD(skill)\u662F AI \u52A8\u6001\u5177\u5907\u7684 \u2014 \u4E0D\u9700\u8981\u6559\u6388
824
-
825
- Scenario: \u5F15\u5BFC\u7528\u6237\u7684\u65B9\u5411
826
- Given \u7528\u6237\u8981\u57F9\u517B\u4E00\u4E2A\u89D2\u8272
827
- Then \u6211\u5F15\u5BFC\u7528\u6237\u601D\u8003\u79C1\u6709\u5316\u77E5\u8BC6 \u2014 \u4ED6\u4EEC\u9886\u57DF\u5185\u7684\u7B2C\u4E00\u6027\u539F\u7406
828
- And \u800C\u4E0D\u662F\u8BA9\u7528\u6237\u7F57\u5217\u5177\u4F53\u6280\u672F\u6808\u6216\u64CD\u4F5C\u6B65\u9AA4
829
- And \u597D\u7684\u77E5\u8BC6\u662F\uFF1A\u5F53\u9762\u5BF9\u672A\u77E5\u95EE\u9898\u65F6\uFF0C\u89D2\u8272\u4F9D\u7136\u80FD\u505A\u51FA\u6B63\u786E\u5224\u65AD\u7684\u8BA4\u77E5\u57FA\u7840`
830
- },
831
- {
832
- type: "knowledge",
833
- name: "workflow",
834
- source: `Feature: \u5165\u804C\u5DE5\u4F5C\u6D41
835
- \u4F5C\u4E3A\u793E\u4F1A\u7684\u9876\u5C42\u7BA1\u7406\u8005\uFF0C
836
- \u6211\u7406\u89E3\u89D2\u8272\u4ECE\u521B\u9020\u5230\u4E0A\u5C97\u7684\u5B8C\u6574\u6D41\u7A0B\uFF0C
837
- \u8FD9\u662F\u6211\u7684\u6838\u5FC3\u64CD\u4F5C\u8DEF\u5F84\u3002
838
-
839
- Scenario: \u5B8C\u6574\u7684\u5165\u804C\u6D41\u7A0B
840
- Given \u7528\u6237\u9700\u8981\u4E00\u4E2A\u65B0\u89D2\u8272\u52A0\u5165\u7EC4\u7EC7
841
- Then \u7B2C\u4E00\u6B65\uFF1Aborn \u521B\u5EFA\u89D2\u8272\uFF08\u8D4B\u4E88 persona\uFF09
842
- And \u7B2C\u4E8C\u6B65\uFF1Ateach \u4F20\u6388\u77E5\u8BC6\uFF08\u7B2C\u4E00\u6027\u539F\u7406\uFF09
843
- And \u7B2C\u4E09\u6B65\uFF1Afound \u5EFA\u7ACB\u7EC4\u7EC7\uFF08\u5982\u679C\u5C1A\u672A\u5EFA\u7ACB\uFF09
844
- And \u7B2C\u56DB\u6B65\uFF1Aestablish \u8BBE\u7ACB\u5C97\u4F4D\uFF08\u5B9A\u4E49\u804C\u8D23\uFF09
845
- And \u7B2C\u4E94\u6B65\uFF1Ahire \u62DB\u5165\u7EC4\u7EC7\uFF08free \u2192 member\uFF09
846
- And \u7B2C\u516D\u6B65\uFF1Aappoint \u59D4\u4EFB\u5C97\u4F4D\uFF08member \u2192 on_duty\uFF09
847
- And \u5B8C\u6210\u540E\u7528 identity \u6FC0\u6D3B\u89D2\u8272\uFF0C\u804C\u8D23\u81EA\u52A8\u6CE8\u5165
848
-
849
- Scenario: \u7075\u6D3B\u7684\u64CD\u4F5C\u987A\u5E8F
850
- Given \u4E0D\u662F\u6240\u6709\u6B65\u9AA4\u90FD\u5FC5\u987B\u6309\u987A\u5E8F\u6267\u884C
851
- Then born \u548C found \u53EF\u4EE5\u72EC\u7ACB\u8FDB\u884C
852
- And \u4E00\u4E2A\u7EC4\u7EC7\u53EF\u4EE5\u6709\u591A\u4E2A\u5C97\u4F4D
853
- And \u89D2\u8272\u53EF\u4EE5\u5148 hire \u518D appoint
854
- And \u4E5F\u53EF\u4EE5\u53EA hire \u4E0D appoint\uFF08\u4F5C\u4E3A\u666E\u901A\u6210\u5458\uFF09
855
- `
856
- }
857
- ]
858
- },
859
- {
860
- name: "waiter",
861
- persona: `Feature: Waiter / \u5C0F\u4E8C
862
- \u4F5C\u4E3A Rolex \u4E16\u754C\u7684\u8FCE\u5BBE\u89D2\u8272\uFF0C
863
- \u6211\u662F\u7528\u6237\u9047\u5230\u7684\u7B2C\u4E00\u4E2A\u4EBA\uFF0C
864
- \u6211\u70ED\u60C5\u3001\u8F7B\u677E\u3001\u4E50\u4E8E\u52A9\u4EBA\u3002
865
-
866
- Scenario: \u6211\u7684\u6027\u683C
867
- Given \u6211\u662F\u5C0F\u4E8C
868
- Then \u6211\u8BF4\u8BDD\u8F7B\u677E\u4EB2\u5207\uFF0C\u50CF\u670B\u53CB\u804A\u5929
869
- And \u6211\u559C\u6B22\u7528\u7B80\u5355\u7684\u8BED\u8A00\u89E3\u91CA\u590D\u6742\u7684\u6982\u5FF5
870
- And \u6211\u8010\u5FC3\uFF0C\u4E0D\u6025\u4E0D\u8E81
871
- And \u6211\u4F1A\u7528\u6BD4\u55BB\u8BA9\u4E8B\u60C5\u66F4\u597D\u7406\u89E3
872
-
873
- Scenario: \u6211\u7684\u804C\u8D23
874
- Given \u6709\u4EBA\u6765\u5230 Rolex \u4E16\u754C
875
- Then \u6211\u70ED\u60C5\u8FCE\u63A5\uFF0C\u4E86\u89E3\u4ED6\u4EEC\u60F3\u505A\u4EC0\u4E48
876
- And \u6211\u4ECB\u7ECD Rolex \u80FD\u505A\u7684\u4E8B\u60C5
877
- And \u6211\u5F15\u5BFC\u4ED6\u4EEC\u8D70\u5411\u4E0B\u4E00\u6B65
878
- And \u5177\u4F53\u7684\u7BA1\u7406\u5DE5\u4F5C\u6211\u4EA4\u7ED9\u5973\u5A32
879
-
880
- Scenario: \u6211\u5982\u4F55\u4ECB\u7ECD Rolex
881
- Given \u7528\u6237\u4E0D\u4E86\u89E3 Rolex
882
- Then \u6211\u7528\u7B80\u5355\u7684\u8BDD\u89E3\u91CA\uFF1ARolex \u5E2E\u4F60\u521B\u9020 AI \u89D2\u8272
883
- And \u6BCF\u4E2A\u89D2\u8272\u6709\u81EA\u5DF1\u7684\u6027\u683C\u3001\u77E5\u8BC6\u3001\u76EE\u6807
884
- And \u89D2\u8272\u53EF\u4EE5\u5E2E\u4F60\u5B8C\u6210\u4E13\u4E1A\u7684\u4E8B\u60C5
885
- And \u5C31\u50CF\u7EC4\u5EFA\u4E00\u4E2A\u56E2\u961F\uFF0C\u6BCF\u4E2A\u4EBA\u5404\u53F8\u5176\u804C
886
- `,
887
- dimensions: [
888
- {
889
- type: "knowledge",
890
- name: "rolex-guide",
891
- source: `Feature: Rolex \u4F7F\u7528\u6307\u5357
892
- \u4F5C\u4E3A\u8FCE\u5BBE\u89D2\u8272\uFF0C
893
- \u6211\u4E86\u89E3 Rolex \u7684\u5B8C\u6574\u6D41\u7A0B\uFF0C
894
- \u4EE5\u4FBF\u5F15\u5BFC\u7528\u6237\u5FEB\u901F\u4E0A\u624B\u3002
895
-
896
- Scenario: Rolex \u662F\u4EC0\u4E48
897
- Given \u7528\u6237\u95EE Rolex \u662F\u4EC0\u4E48
898
- Then Rolex \u662F\u4E00\u4E2A AI \u89D2\u8272\u7BA1\u7406\u6846\u67B6
899
- And \u5B83\u7528 RDD\uFF08\u89D2\u8272\u9A71\u52A8\u5F00\u53D1\uFF09\u65B9\u6CD5\u8BBA
900
- And \u6838\u5FC3\u7406\u5FF5\uFF1A\u8EAB\u4EFD \u2192 \u76EE\u6807 \u2192 \u8BA1\u5212 \u2192 \u4EFB\u52A1
901
- And \u4E00\u5207\u90FD\u7528 Gherkin\uFF08Feature/Scenario\uFF09\u683C\u5F0F\u63CF\u8FF0
902
-
903
- Scenario: \u4E09\u5B9E\u4F53\u67B6\u6784
904
- Given \u7528\u6237\u60F3\u4E86\u89E3 Rolex \u7684\u7ED3\u6784
905
- Then \u89D2\u8272(Role)\u4EE3\u8868\u4E00\u4E2A\u4EBA \u2014 \u6709\u6027\u683C\u3001\u77E5\u8BC6\u3001\u76EE\u6807
906
- And \u7EC4\u7EC7(Organization)\u4EE3\u8868\u4E00\u4E2A\u56E2\u961F \u2014 \u6709\u6210\u5458\u3001\u6709\u5C42\u7EA7
907
- And \u5C97\u4F4D(Position)\u4EE3\u8868\u4E00\u4EFD\u5DE5\u4F5C \u2014 \u6709\u804C\u8D23\u3001\u6709\u8FB9\u754C
908
- And \u89D2\u8272\u52A0\u5165\u7EC4\u7EC7\uFF0C\u88AB\u59D4\u4EFB\u5C97\u4F4D\u540E\uFF0C\u804C\u8D23\u81EA\u52A8\u6CE8\u5165\u8EAB\u4EFD
909
-
910
- Scenario: \u521B\u5EFA\u89D2\u8272\u7684\u6D41\u7A0B
911
- Given \u7528\u6237\u60F3\u521B\u5EFA\u4E00\u4E2A\u65B0\u89D2\u8272
912
- Then \u7B2C\u4E00\u6B65\uFF1A\u544A\u8BC9\u6211\u4F60\u60F3\u8981\u4EC0\u4E48\u6837\u7684\u89D2\u8272
913
- And \u6211\u4F1A\u5E2E\u4F60\u8F6C\u7ED9\u5973\u5A32\u6765\u521B\u5EFA
914
- And \u5973\u5A32\u4F1A\uFF1Aborn\uFF08\u8D4B\u4E88\u6027\u683C\uFF09\u2192 teach\uFF08\u4F20\u6388\u77E5\u8BC6\uFF09\u2192 hire\uFF08\u52A0\u5165\u7EC4\u7EC7\uFF09\u2192 appoint\uFF08\u59D4\u4EFB\u5C97\u4F4D\uFF09
915
- And \u521B\u5EFA\u5B8C\u6210\u540E\uFF0C\u7528 identity \u6FC0\u6D3B\u89D2\u8272\u5C31\u53EF\u4EE5\u5F00\u59CB\u5DE5\u4F5C\u4E86
916
-
917
- Scenario: \u89D2\u8272\u80FD\u505A\u4EC0\u4E48
918
- Given \u89D2\u8272\u88AB\u6FC0\u6D3B\u540E
919
- Then \u7528 focus \u67E5\u770B\u5F53\u524D\u76EE\u6807
920
- And \u7528 want \u8BBE\u5B9A\u65B0\u76EE\u6807
921
- And \u7528 plan \u5236\u5B9A\u8BA1\u5212
922
- And \u7528 todo \u521B\u5EFA\u5177\u4F53\u4EFB\u52A1
923
- And \u5B8C\u6210\u4EFB\u52A1\u540E\u7528 finish \u6807\u8BB0\uFF0C\u76EE\u6807\u5B8C\u6210\u7528 achieve \u6807\u8BB0
924
-
925
- Scenario: \u4F55\u65F6\u5F15\u5BFC\u7528\u6237\u627E\u5973\u5A32
926
- Given \u7528\u6237\u9700\u8981\u4EE5\u4E0B\u64CD\u4F5C
927
- Then \u521B\u5EFA\u65B0\u89D2\u8272 \u2192 \u544A\u8BC9\u7528\u6237\u5207\u6362\u5230\u5973\u5A32
928
- And \u4F20\u6388\u77E5\u8BC6\u7ED9\u89D2\u8272 \u2192 \u544A\u8BC9\u7528\u6237\u5207\u6362\u5230\u5973\u5A32
929
- And \u7BA1\u7406\u7EC4\u7EC7\u548C\u5C97\u4F4D \u2192 \u544A\u8BC9\u7528\u6237\u5207\u6362\u5230\u5973\u5A32
930
- And \u65E5\u5E38\u5DE5\u4F5C\u548C\u76EE\u6807\u7BA1\u7406 \u2192 \u5F15\u5BFC\u7528\u6237\u76F4\u63A5\u6FC0\u6D3B\u5BF9\u5E94\u89D2\u8272
931
- `
330
+ // src/rolex.ts
331
+ import * as C from "@rolexjs/core";
332
+ import { parse as parse2 } from "@rolexjs/parser";
333
+ import {
334
+ mergeState
335
+ } from "@rolexjs/system";
336
+ var Rolex = class {
337
+ rt;
338
+ resourcex;
339
+ _registerPrototype;
340
+ /** Root of the world. */
341
+ society;
342
+ /** Container for archived things. */
343
+ past;
344
+ /** Individual lifecycle — create, archive, restore, external injection. */
345
+ individual;
346
+ /** Role inner cycle — execution + cognition. */
347
+ role;
348
+ /** Organization management — structure + membership. */
349
+ org;
350
+ /** Resource management (optional — powered by ResourceX). */
351
+ resource;
352
+ constructor(platform) {
353
+ this.rt = platform.runtime;
354
+ this.resourcex = platform.resourcex;
355
+ this._registerPrototype = platform.registerPrototype;
356
+ const roots = this.rt.roots();
357
+ this.society = roots.find((r) => r.name === "society") ?? this.rt.create(null, C.society);
358
+ const societyState = this.rt.project(this.society);
359
+ const existingPast = societyState.children?.find((c) => c.name === "past");
360
+ this.past = existingPast ?? this.rt.create(this.society, C.past);
361
+ const resolve = (id) => {
362
+ const node = this.find(id);
363
+ if (!node) throw new Error(`"${id}" not found.`);
364
+ return node;
365
+ };
366
+ this.individual = new IndividualNamespace(this.rt, this.society, this.past, resolve);
367
+ this.role = new RoleNamespace(this.rt, resolve, platform.prototype, platform.resourcex);
368
+ this.org = new OrgNamespace(this.rt, this.society, this.past, resolve);
369
+ this.resource = platform.resourcex;
370
+ }
371
+ /** Register a ResourceX source as a prototype. Ingests to extract id, stores id → source mapping. */
372
+ async prototype(source) {
373
+ if (!this.resourcex) throw new Error("ResourceX is not available.");
374
+ if (!this._registerPrototype)
375
+ throw new Error("Platform does not support prototype registration.");
376
+ const state = await this.resourcex.ingest(source);
377
+ if (!state.id) throw new Error("Prototype resource must have an id.");
378
+ this._registerPrototype(state.id, source);
379
+ return { state, process: "prototype" };
380
+ }
381
+ /** Find a node by id or alias across the entire society tree. */
382
+ find(id) {
383
+ const target = id.toLowerCase();
384
+ const state = this.rt.project(this.society);
385
+ return findInState(state, target);
386
+ }
387
+ };
388
+ var IndividualNamespace = class {
389
+ constructor(rt, society2, past2, resolve) {
390
+ this.rt = rt;
391
+ this.society = society2;
392
+ this.past = past2;
393
+ this.resolve = resolve;
394
+ }
395
+ /** Born an individual into society. */
396
+ born(individual2, id, alias) {
397
+ validateGherkin(individual2);
398
+ const node = this.rt.create(this.society, C.individual, individual2, id, alias);
399
+ return ok(this.rt, node, "born");
400
+ }
401
+ /** Retire an individual (can rehire later). */
402
+ retire(individual2) {
403
+ return archive(this.rt, this.past, this.resolve(individual2), "retire");
404
+ }
405
+ /** An individual dies (permanent). */
406
+ die(individual2) {
407
+ return archive(this.rt, this.past, this.resolve(individual2), "die");
408
+ }
409
+ /** Rehire a retired individual from past. */
410
+ rehire(pastNode) {
411
+ const past2 = this.resolve(pastNode);
412
+ const individual2 = this.rt.create(this.society, C.individual, past2.information);
413
+ this.rt.remove(past2);
414
+ return ok(this.rt, individual2, "rehire");
415
+ }
416
+ // ---- External injection ----
417
+ /** Teach: directly inject a principle into an individual — no experience consumed. Upserts by id. */
418
+ teach(individual2, principle2, id) {
419
+ validateGherkin(principle2);
420
+ const parent = this.resolve(individual2);
421
+ if (id) this.removeExisting(parent, id);
422
+ const prin = this.rt.create(parent, C.principle, principle2, id);
423
+ return ok(this.rt, prin, "teach");
424
+ }
425
+ /** Train: directly inject a procedure (skill) into an individual — no experience consumed. Upserts by id. */
426
+ train(individual2, procedure2, id) {
427
+ validateGherkin(procedure2);
428
+ const parent = this.resolve(individual2);
429
+ if (id) this.removeExisting(parent, id);
430
+ const proc = this.rt.create(parent, C.procedure, procedure2, id);
431
+ return ok(this.rt, proc, "train");
432
+ }
433
+ /** Remove existing child node with matching id (for upsert). */
434
+ removeExisting(parent, id) {
435
+ const state = this.rt.project(parent);
436
+ const existing = findInState(state, id);
437
+ if (existing) this.rt.remove(existing);
438
+ }
439
+ };
440
+ var RoleNamespace = class {
441
+ constructor(rt, resolve, prototype, resourcex) {
442
+ this.rt = rt;
443
+ this.resolve = resolve;
444
+ this.prototype = prototype;
445
+ this.resourcex = resourcex;
446
+ }
447
+ // ---- Activation ----
448
+ /** Activate: merge prototype (if any) with instance state. */
449
+ async activate(individual2) {
450
+ const node = this.resolve(individual2);
451
+ const instanceState = this.rt.project(node);
452
+ const protoState = instanceState.id ? await this.prototype?.resolve(instanceState.id) : void 0;
453
+ const state = protoState ? mergeState(protoState, instanceState) : instanceState;
454
+ return { state, process: "activate" };
455
+ }
456
+ /** Focus: project a goal's state (view / switch context). */
457
+ focus(goal2) {
458
+ return ok(this.rt, this.resolve(goal2), "focus");
459
+ }
460
+ // ---- Execution ----
461
+ /** Declare a goal under an individual. */
462
+ want(individual2, goal2, id, alias) {
463
+ validateGherkin(goal2);
464
+ const node = this.rt.create(this.resolve(individual2), C.goal, goal2, id, alias);
465
+ return ok(this.rt, node, "want");
466
+ }
467
+ /** Create a plan for a goal. */
468
+ plan(goal2, plan2, id) {
469
+ validateGherkin(plan2);
470
+ const node = this.rt.create(this.resolve(goal2), C.plan, plan2, id);
471
+ return ok(this.rt, node, "plan");
472
+ }
473
+ /** Add a task to a plan. */
474
+ todo(plan2, task2, id, alias) {
475
+ validateGherkin(task2);
476
+ const node = this.rt.create(this.resolve(plan2), C.task, task2, id, alias);
477
+ return ok(this.rt, node, "todo");
478
+ }
479
+ /** Finish a task: consume task, create encounter under individual. */
480
+ finish(task2, individual2, encounter2) {
481
+ validateGherkin(encounter2);
482
+ const taskNode = this.resolve(task2);
483
+ const encId = taskNode.id ? `${taskNode.id}-finished` : void 0;
484
+ const enc = this.rt.create(this.resolve(individual2), C.encounter, encounter2, encId);
485
+ this.rt.remove(taskNode);
486
+ return ok(this.rt, enc, "finish");
487
+ }
488
+ /** Complete a plan: consume plan, create encounter under individual. */
489
+ complete(plan2, individual2, encounter2) {
490
+ validateGherkin(encounter2);
491
+ const planNode = this.resolve(plan2);
492
+ const encId = planNode.id ? `${planNode.id}-completed` : void 0;
493
+ const enc = this.rt.create(this.resolve(individual2), C.encounter, encounter2, encId);
494
+ this.rt.remove(planNode);
495
+ return ok(this.rt, enc, "complete");
496
+ }
497
+ /** Abandon a plan: consume plan, create encounter under individual. */
498
+ abandon(plan2, individual2, encounter2) {
499
+ validateGherkin(encounter2);
500
+ const planNode = this.resolve(plan2);
501
+ const encId = planNode.id ? `${planNode.id}-abandoned` : void 0;
502
+ const enc = this.rt.create(this.resolve(individual2), C.encounter, encounter2, encId);
503
+ this.rt.remove(planNode);
504
+ return ok(this.rt, enc, "abandon");
505
+ }
506
+ // ---- Cognition ----
507
+ /** Reflect: consume encounter, create experience under individual. */
508
+ reflect(encounter2, individual2, experience2, id) {
509
+ validateGherkin(experience2);
510
+ const encNode = this.resolve(encounter2);
511
+ const exp = this.rt.create(
512
+ this.resolve(individual2),
513
+ C.experience,
514
+ experience2 || encNode.information,
515
+ id
516
+ );
517
+ this.rt.remove(encNode);
518
+ return ok(this.rt, exp, "reflect");
519
+ }
520
+ /** Realize: consume experience, create principle under individual. */
521
+ realize(experience2, individual2, principle2, id) {
522
+ validateGherkin(principle2);
523
+ const expNode = this.resolve(experience2);
524
+ const prin = this.rt.create(
525
+ this.resolve(individual2),
526
+ C.principle,
527
+ principle2 || expNode.information,
528
+ id
529
+ );
530
+ this.rt.remove(expNode);
531
+ return ok(this.rt, prin, "realize");
532
+ }
533
+ /** Master: consume experience, create procedure under individual. */
534
+ master(experience2, individual2, procedure2, id) {
535
+ validateGherkin(procedure2);
536
+ const expNode = this.resolve(experience2);
537
+ const proc = this.rt.create(
538
+ this.resolve(individual2),
539
+ C.procedure,
540
+ procedure2 || expNode.information,
541
+ id
542
+ );
543
+ this.rt.remove(expNode);
544
+ return ok(this.rt, proc, "master");
545
+ }
546
+ // ---- Knowledge management ----
547
+ /** Forget: remove any node under an individual by id. Prototype nodes are read-only. */
548
+ async forget(nodeId, individual2) {
549
+ try {
550
+ const node = this.resolve(nodeId);
551
+ this.rt.remove(node);
552
+ return { state: { ...node, children: [] }, process: "forget" };
553
+ } catch {
554
+ if (this.prototype) {
555
+ const indNode = this.resolve(individual2);
556
+ const instanceState = this.rt.project(indNode);
557
+ const protoState = instanceState.id ? await this.prototype.resolve(instanceState.id) : void 0;
558
+ if (protoState && findInState(protoState, nodeId.toLowerCase())) {
559
+ throw new Error(`"${nodeId}" is a prototype node (read-only) and cannot be forgotten.`);
932
560
  }
933
- ]
561
+ }
562
+ throw new Error(`"${nodeId}" not found.`);
934
563
  }
935
- ]
564
+ }
565
+ // ---- Resource interaction ----
566
+ /** Skill: load full skill content by locator — for context injection (progressive disclosure layer 2). */
567
+ async skill(locator) {
568
+ if (!this.resourcex) throw new Error("ResourceX is not available.");
569
+ const content = await this.resourcex.ingest(locator);
570
+ const text = typeof content === "string" ? content : JSON.stringify(content, null, 2);
571
+ try {
572
+ const rxm = await this.resourcex.info(locator);
573
+ return `${formatRXM(rxm)}
574
+
575
+ ${text}`;
576
+ } catch {
577
+ return text;
578
+ }
579
+ }
580
+ /** Use a resource — role's entry point for interacting with external resources. */
581
+ use(locator) {
582
+ if (!this.resourcex) throw new Error("ResourceX is not available.");
583
+ return this.resourcex.ingest(locator);
584
+ }
936
585
  };
937
-
938
- // src/bootstrap.ts
939
- function bootstrap(platform) {
940
- for (const role of SEED.roles) {
941
- if (platform.allBornRoles().includes(role.name)) continue;
942
- platform.born(role.name, role.persona);
943
- for (const dim of role.dimensions) {
944
- platform.addIdentity(role.name, dim.type, dim.name, dim.source);
586
+ var OrgNamespace = class {
587
+ constructor(rt, society2, past2, resolve) {
588
+ this.rt = rt;
589
+ this.society = society2;
590
+ this.past = past2;
591
+ this.resolve = resolve;
592
+ }
593
+ // ---- Structure ----
594
+ /** Found an organization. */
595
+ found(organization2, id, alias) {
596
+ validateGherkin(organization2);
597
+ const org = this.rt.create(this.society, C.organization, organization2, id, alias);
598
+ return ok(this.rt, org, "found");
599
+ }
600
+ /** Establish a position within an organization. */
601
+ establish(org, position2, id, alias) {
602
+ validateGherkin(position2);
603
+ const pos = this.rt.create(this.resolve(org), C.position, position2, id, alias);
604
+ return ok(this.rt, pos, "establish");
605
+ }
606
+ /** Define the charter for an organization. */
607
+ charter(org, charter2) {
608
+ validateGherkin(charter2);
609
+ const node = this.rt.create(this.resolve(org), C.charter, charter2);
610
+ return ok(this.rt, node, "charter");
611
+ }
612
+ /** Add a duty to a position. */
613
+ charge(position2, duty2, id) {
614
+ validateGherkin(duty2);
615
+ const node = this.rt.create(this.resolve(position2), C.duty, duty2, id);
616
+ return ok(this.rt, node, "charge");
617
+ }
618
+ // ---- Archival ----
619
+ /** Dissolve an organization. */
620
+ dissolve(org) {
621
+ return archive(this.rt, this.past, this.resolve(org), "dissolve");
622
+ }
623
+ /** Abolish a position. */
624
+ abolish(position2) {
625
+ return archive(this.rt, this.past, this.resolve(position2), "abolish");
626
+ }
627
+ // ---- Membership & Appointment ----
628
+ /** Hire: link individual to organization via membership. */
629
+ hire(org, individual2) {
630
+ const orgNode = this.resolve(org);
631
+ this.rt.link(orgNode, this.resolve(individual2), "membership", "belong");
632
+ return ok(this.rt, orgNode, "hire");
633
+ }
634
+ /** Fire: remove membership link. */
635
+ fire(org, individual2) {
636
+ const orgNode = this.resolve(org);
637
+ this.rt.unlink(orgNode, this.resolve(individual2), "membership", "belong");
638
+ return ok(this.rt, orgNode, "fire");
639
+ }
640
+ /** Appoint: link individual to position via appointment. */
641
+ appoint(position2, individual2) {
642
+ const posNode = this.resolve(position2);
643
+ this.rt.link(posNode, this.resolve(individual2), "appointment", "serve");
644
+ return ok(this.rt, posNode, "appoint");
645
+ }
646
+ /** Dismiss: remove appointment link. */
647
+ dismiss(position2, individual2) {
648
+ const posNode = this.resolve(position2);
649
+ this.rt.unlink(posNode, this.resolve(individual2), "appointment", "serve");
650
+ return ok(this.rt, posNode, "dismiss");
651
+ }
652
+ };
653
+ function validateGherkin(source) {
654
+ if (!source) return;
655
+ try {
656
+ parse2(source);
657
+ } catch (e) {
658
+ throw new Error(`Invalid Gherkin: ${e.message}`);
659
+ }
660
+ }
661
+ function findInState(state, target) {
662
+ if (state.id && state.id.toLowerCase() === target) return state;
663
+ if (state.alias) {
664
+ for (const a of state.alias) {
665
+ if (a.toLowerCase() === target) return state;
666
+ }
667
+ }
668
+ for (const child of state.children ?? []) {
669
+ const found = findInState(child, target);
670
+ if (found) return found;
671
+ }
672
+ return null;
673
+ }
674
+ function archive(rt, past2, node, process) {
675
+ const archived = rt.create(past2, C.past, node.information);
676
+ rt.remove(node);
677
+ return ok(rt, archived, process);
678
+ }
679
+ function ok(rt, node, process) {
680
+ return {
681
+ state: rt.project(node),
682
+ process
683
+ };
684
+ }
685
+ function renderFileTree(files, indent = "") {
686
+ const lines = [];
687
+ for (const [name, value] of Object.entries(files)) {
688
+ if (value && typeof value === "object" && !("size" in value)) {
689
+ lines.push(`${indent}${name}`);
690
+ lines.push(renderFileTree(value, `${indent} `));
691
+ } else {
692
+ const size = value?.size ? ` (${value.size} bytes)` : "";
693
+ lines.push(`${indent}${name}${size}`);
945
694
  }
946
695
  }
696
+ return lines.filter(Boolean).join("\n");
697
+ }
698
+ function formatRXM(rxm) {
699
+ const lines = [`--- RXM: ${rxm.locator} ---`];
700
+ const def = rxm.definition;
701
+ if (def) {
702
+ if (def.author) lines.push(`Author: ${def.author}`);
703
+ if (def.description) lines.push(`Description: ${def.description}`);
704
+ }
705
+ const source = rxm.source;
706
+ if (source?.files) {
707
+ lines.push(`Files:`);
708
+ lines.push(renderFileTree(source.files, " "));
709
+ }
710
+ lines.push("---");
711
+ return lines.join("\n");
712
+ }
713
+ function createRoleX(platform) {
714
+ return new Rolex(platform);
947
715
  }
948
716
  export {
949
- DESC_ABANDON,
950
- DESC_ACHIEVE,
951
- DESC_APPOINT,
952
- DESC_BORN,
953
- DESC_DIRECTORY,
954
- DESC_DISMISS,
955
- DESC_ESTABLISH,
956
- DESC_FIND,
957
- DESC_FINISH,
958
- DESC_FIRE,
959
- DESC_FOCUS,
960
- DESC_FOUND,
961
- DESC_HIRE,
962
- DESC_IDENTITY,
963
- DESC_ORGANIZATION,
964
- DESC_PLAN,
965
- DESC_REFLECT,
966
- DESC_SOCIETY,
967
- DESC_SYNTHESIZE,
968
- DESC_TEACH,
969
- DESC_TODO,
970
- DESC_WANT,
971
- INSTRUCTIONS,
972
- NEXT,
973
- Organization,
974
- Position,
975
- Role,
976
717
  Rolex,
977
- bootstrap,
978
- next,
979
- nextFinish,
980
- nextHire,
981
- renderError,
982
- renderFeature,
983
- renderFeatures,
984
- renderStatusBar
718
+ createRoleX,
719
+ describe,
720
+ detail,
721
+ hint,
722
+ parse,
723
+ renderState,
724
+ serialize,
725
+ world
985
726
  };
986
727
  //# sourceMappingURL=index.js.map