@rolexjs/local-platform 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -4
- package/dist/index.js +39 -24
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -4,11 +4,13 @@ import { Platform, Organization, Feature, Goal, Plan, Task } from '@rolexjs/core
|
|
|
4
4
|
* LocalPlatform — Local filesystem implementation of Platform.
|
|
5
5
|
*
|
|
6
6
|
* Everything lives under a single .rolex/ directory.
|
|
7
|
-
* rolex.json
|
|
7
|
+
* rolex.json is the single source of truth (CAS):
|
|
8
|
+
* - roles: all born role names
|
|
9
|
+
* - organization: optional org with teams
|
|
8
10
|
*
|
|
9
11
|
* Directory convention:
|
|
10
|
-
* <rootDir>/rolex.json
|
|
11
|
-
* <rootDir>/<role>/identity/*.identity.feature
|
|
12
|
+
* <rootDir>/rolex.json <- Society config (always exists)
|
|
13
|
+
* <rootDir>/<role>/identity/*.identity.feature <- Identity features
|
|
12
14
|
* <rootDir>/<role>/goals/<name>/<name>.goal.feature
|
|
13
15
|
* <rootDir>/<role>/goals/<name>/<name>.plan.feature
|
|
14
16
|
* <rootDir>/<role>/goals/<name>/tasks/<name>.task.feature
|
|
@@ -19,7 +21,8 @@ declare class LocalPlatform implements Platform {
|
|
|
19
21
|
private config;
|
|
20
22
|
constructor(rootDir: string);
|
|
21
23
|
found(name: string): void;
|
|
22
|
-
organization(): Organization;
|
|
24
|
+
organization(): Organization | null;
|
|
25
|
+
allBornRoles(): string[];
|
|
23
26
|
born(name: string, source: string): Feature;
|
|
24
27
|
hire(name: string): void;
|
|
25
28
|
fire(name: string): void;
|
|
@@ -39,6 +42,10 @@ declare class LocalPlatform implements Platform {
|
|
|
39
42
|
completeGoal(roleId: string, experience?: string): void;
|
|
40
43
|
abandonGoal(roleId: string, experience?: string): void;
|
|
41
44
|
completeTask(roleId: string, name: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Load config — always returns a valid RolexConfig.
|
|
47
|
+
* Creates default config if rolex.json doesn't exist yet.
|
|
48
|
+
*/
|
|
42
49
|
private loadConfig;
|
|
43
50
|
private saveConfig;
|
|
44
51
|
private resolveRoleDir;
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,8 @@ var LocalPlatform = class {
|
|
|
10
10
|
}
|
|
11
11
|
// ========== Found ==========
|
|
12
12
|
found(name) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const config = this.loadConfig();
|
|
14
|
+
config.organization = {
|
|
15
15
|
name,
|
|
16
16
|
teams: { default: [] }
|
|
17
17
|
};
|
|
@@ -20,8 +20,9 @@ var LocalPlatform = class {
|
|
|
20
20
|
// ========== Organization ==========
|
|
21
21
|
organization() {
|
|
22
22
|
const config = this.loadConfig();
|
|
23
|
+
if (!config.organization) return null;
|
|
23
24
|
const roles = [];
|
|
24
|
-
for (const [teamName, roleNames] of Object.entries(config.teams)) {
|
|
25
|
+
for (const [teamName, roleNames] of Object.entries(config.organization.teams)) {
|
|
25
26
|
for (const roleName of roleNames) {
|
|
26
27
|
roles.push({
|
|
27
28
|
name: roleName,
|
|
@@ -29,46 +30,52 @@ var LocalPlatform = class {
|
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
return { name: config.name, roles };
|
|
33
|
+
return { name: config.organization.name, roles };
|
|
34
|
+
}
|
|
35
|
+
// ========== Society ==========
|
|
36
|
+
allBornRoles() {
|
|
37
|
+
return this.loadConfig().roles;
|
|
33
38
|
}
|
|
34
39
|
// ========== Born ==========
|
|
35
40
|
born(name, source) {
|
|
36
41
|
const roleDir = join(this.rootDir, name);
|
|
37
|
-
|
|
38
|
-
mkdirSync(
|
|
39
|
-
const filePath = join(
|
|
42
|
+
mkdirSync(join(roleDir, "identity"), { recursive: true });
|
|
43
|
+
mkdirSync(join(roleDir, "goals"), { recursive: true });
|
|
44
|
+
const filePath = join(roleDir, "identity", "persona.identity.feature");
|
|
40
45
|
writeFileSync(filePath, source, "utf-8");
|
|
46
|
+
const config = this.loadConfig();
|
|
47
|
+
if (!config.roles.includes(name)) {
|
|
48
|
+
config.roles.push(name);
|
|
49
|
+
this.saveConfig(config);
|
|
50
|
+
}
|
|
41
51
|
const doc = parse(source);
|
|
42
52
|
return this.toFeature(doc.feature, "persona");
|
|
43
53
|
}
|
|
44
54
|
hire(name) {
|
|
45
|
-
const
|
|
46
|
-
if (!
|
|
55
|
+
const config = this.loadConfig();
|
|
56
|
+
if (!config.organization) throw new Error("No organization found. Call found() first.");
|
|
57
|
+
if (!config.roles.includes(name)) {
|
|
47
58
|
throw new Error(`Role not found: ${name}. Call born() first.`);
|
|
48
59
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (!config.teams[firstTeam].includes(name)) {
|
|
53
|
-
config.teams[firstTeam].push(name);
|
|
60
|
+
const [firstTeam] = Object.keys(config.organization.teams);
|
|
61
|
+
if (!config.organization.teams[firstTeam].includes(name)) {
|
|
62
|
+
config.organization.teams[firstTeam].push(name);
|
|
54
63
|
this.saveConfig(config);
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
fire(name) {
|
|
58
|
-
const roleDir = join(this.rootDir, name);
|
|
59
|
-
const goalsDir = join(roleDir, "goals");
|
|
60
|
-
if (!existsSync(goalsDir)) {
|
|
61
|
-
throw new Error(`Role not hired: ${name}`);
|
|
62
|
-
}
|
|
63
|
-
rmSync(goalsDir, { recursive: true, force: true });
|
|
64
67
|
const config = this.loadConfig();
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
if (!config.organization) throw new Error("No organization found. Call found() first.");
|
|
69
|
+
let found = false;
|
|
70
|
+
for (const teamName of Object.keys(config.organization.teams)) {
|
|
71
|
+
const idx = config.organization.teams[teamName].indexOf(name);
|
|
67
72
|
if (idx !== -1) {
|
|
68
|
-
config.teams[teamName].splice(idx, 1);
|
|
73
|
+
config.organization.teams[teamName].splice(idx, 1);
|
|
74
|
+
found = true;
|
|
69
75
|
break;
|
|
70
76
|
}
|
|
71
77
|
}
|
|
78
|
+
if (!found) throw new Error(`Role not hired: ${name}`);
|
|
72
79
|
this.saveConfig(config);
|
|
73
80
|
}
|
|
74
81
|
// ========== Growup ==========
|
|
@@ -224,6 +231,10 @@ ${source}`;
|
|
|
224
231
|
this.addDoneTag(taskFile);
|
|
225
232
|
}
|
|
226
233
|
// ========== Internal ==========
|
|
234
|
+
/**
|
|
235
|
+
* Load config — always returns a valid RolexConfig.
|
|
236
|
+
* Creates default config if rolex.json doesn't exist yet.
|
|
237
|
+
*/
|
|
227
238
|
loadConfig() {
|
|
228
239
|
if (this.config) return this.config;
|
|
229
240
|
const configPath = join(this.rootDir, "rolex.json");
|
|
@@ -231,9 +242,13 @@ ${source}`;
|
|
|
231
242
|
this.config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
232
243
|
return this.config;
|
|
233
244
|
}
|
|
234
|
-
|
|
245
|
+
mkdirSync(this.rootDir, { recursive: true });
|
|
246
|
+
const config = { roles: [], organization: null };
|
|
247
|
+
this.saveConfig(config);
|
|
248
|
+
return config;
|
|
235
249
|
}
|
|
236
250
|
saveConfig(config) {
|
|
251
|
+
mkdirSync(this.rootDir, { recursive: true });
|
|
237
252
|
writeFileSync(join(this.rootDir, "rolex.json"), JSON.stringify(config, null, 2), "utf-8");
|
|
238
253
|
this.config = config;
|
|
239
254
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LocalPlatform.ts"],"sourcesContent":["/**\n * LocalPlatform — Local filesystem implementation of Platform.\n *\n * Everything lives under a single .rolex/ directory.\n * rolex.json manages organization relationships (including teams).\n *\n * Directory convention:\n * <rootDir>/rolex.json ← Organization config\n * <rootDir>/<role>/identity/*.identity.feature ← Identity features\n * <rootDir>/<role>/goals/<name>/<name>.goal.feature\n * <rootDir>/<role>/goals/<name>/<name>.plan.feature\n * <rootDir>/<role>/goals/<name>/tasks/<name>.task.feature\n */\n\nimport { readdirSync, readFileSync, writeFileSync, mkdirSync, existsSync, rmSync } from \"node:fs\";\nimport { join, basename } from \"node:path\";\nimport { parse } from \"@rolexjs/parser\";\nimport type { Feature as GherkinFeature } from \"@rolexjs/parser\";\nimport type {\n Platform,\n Organization,\n RoleEntry,\n Feature,\n Scenario,\n Goal,\n Plan,\n Task,\n} from \"@rolexjs/core\";\n\ninterface RolexConfig {\n name: string;\n teams: Record<string, string[]>;\n}\n\nexport class LocalPlatform implements Platform {\n private readonly rootDir: string;\n private config: RolexConfig | null = null;\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n // ========== Found ==========\n\n found(name: string): void {\n mkdirSync(this.rootDir, { recursive: true });\n\n const config: RolexConfig = {\n name,\n teams: { default: [] },\n };\n\n this.saveConfig(config);\n }\n\n // ========== Organization ==========\n\n organization(): Organization {\n const config = this.loadConfig();\n const roles: RoleEntry[] = [];\n\n for (const [teamName, roleNames] of Object.entries(config.teams)) {\n for (const roleName of roleNames) {\n roles.push({\n name: roleName,\n team: teamName,\n });\n }\n }\n\n return { name: config.name, roles };\n }\n\n // ========== Born ==========\n\n born(name: string, source: string): Feature {\n const roleDir = join(this.rootDir, name);\n const identityDir = join(roleDir, \"identity\");\n mkdirSync(identityDir, { recursive: true });\n\n const filePath = join(identityDir, \"persona.identity.feature\");\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"persona\");\n }\n\n hire(name: string): void {\n const roleDir = join(this.rootDir, name);\n\n if (!existsSync(join(roleDir, \"identity\", \"persona.identity.feature\"))) {\n throw new Error(`Role not found: ${name}. Call born() first.`);\n }\n\n mkdirSync(join(roleDir, \"goals\"), { recursive: true });\n\n // Update rolex.json — add role to default team\n const config = this.loadConfig();\n const [firstTeam] = Object.keys(config.teams);\n if (!config.teams[firstTeam].includes(name)) {\n config.teams[firstTeam].push(name);\n this.saveConfig(config);\n }\n }\n\n fire(name: string): void {\n const roleDir = join(this.rootDir, name);\n const goalsDir = join(roleDir, \"goals\");\n\n if (!existsSync(goalsDir)) {\n throw new Error(`Role not hired: ${name}`);\n }\n\n rmSync(goalsDir, { recursive: true, force: true });\n\n // Update rolex.json — remove role from team\n const config = this.loadConfig();\n for (const teamName of Object.keys(config.teams)) {\n const idx = config.teams[teamName].indexOf(name);\n if (idx !== -1) {\n config.teams[teamName].splice(idx, 1);\n break;\n }\n }\n this.saveConfig(config);\n }\n\n // ========== Growup ==========\n\n growup(\n roleId: string,\n type: \"knowledge\" | \"experience\" | \"voice\",\n name: string,\n source: string\n ): Feature {\n const roleDir = this.resolveRoleDir(roleId);\n const dir = join(roleDir, \"identity\");\n mkdirSync(dir, { recursive: true });\n\n const filePath = join(dir, `${name}.${type}.identity.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, type);\n }\n\n // ========== Reflect ==========\n\n reflect(\n roleId: string,\n experienceNames: string[],\n knowledgeName: string,\n knowledgeSource: string\n ): Feature {\n const roleDir = this.resolveRoleDir(roleId);\n const identityDir = join(roleDir, \"identity\");\n\n // Delete experience files\n for (const expName of experienceNames) {\n const expFile = join(identityDir, `${expName}.experience.identity.feature`);\n if (!existsSync(expFile)) {\n throw new Error(`Experience not found: ${expName}`);\n }\n rmSync(expFile);\n }\n\n // Create knowledge\n return this.growup(roleId, \"knowledge\", knowledgeName, knowledgeSource);\n }\n\n // ========== Query ==========\n\n identity(roleId: string): Feature[] {\n const roleDir = this.resolveRoleDir(roleId);\n const dir = join(roleDir, \"identity\");\n if (!existsSync(dir)) return [];\n\n return readdirSync(dir)\n .filter((f) => f.endsWith(\".identity.feature\"))\n .sort()\n .map((f) => {\n const source = readFileSync(join(dir, f), \"utf-8\");\n const doc = parse(source);\n return this.toFeature(doc.feature!, this.detectIdentityType(f));\n });\n }\n\n activeGoal(roleId: string): (Goal & { plan: Plan | null; tasks: Task[] }) | null {\n const roleDir = this.resolveRoleDir(roleId);\n const goalsDir = join(roleDir, \"goals\");\n if (!existsSync(goalsDir)) return null;\n\n // If a focused goal is set, try to load it first\n const focusedName = this.getFocusedGoal(roleId);\n if (focusedName) {\n const goalDir = join(goalsDir, focusedName);\n const result = this.loadGoalIfActive(goalDir);\n if (result) return result;\n }\n\n // Fallback: first uncompleted goal alphabetically\n const goalDirs = readdirSync(goalsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort();\n\n for (const goalName of goalDirs) {\n const goalDir = join(goalsDir, goalName);\n const result = this.loadGoalIfActive(goalDir);\n if (result) return result;\n }\n\n return null;\n }\n\n allActiveGoals(roleId: string): Goal[] {\n const roleDir = this.resolveRoleDir(roleId);\n const goalsDir = join(roleDir, \"goals\");\n if (!existsSync(goalsDir)) return [];\n\n const goalDirs = readdirSync(goalsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort();\n\n const goals: Goal[] = [];\n for (const goalName of goalDirs) {\n const goalDir = join(goalsDir, goalName);\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\");\n if (!goalFile) continue;\n\n const source = readFileSync(goalFile, \"utf-8\");\n const doc = parse(source);\n if (!doc.feature) continue;\n\n if (doc.feature.tags.some((t) => t.name === \"@done\" || t.name === \"@abandoned\")) continue;\n\n goals.push(this.toFeature(doc.feature, \"goal\") as Goal);\n }\n\n return goals;\n }\n\n getFocusedGoal(roleId: string): string | null {\n const roleDir = this.resolveRoleDir(roleId);\n const focusFile = join(roleDir, \"goals\", \".focus\");\n if (!existsSync(focusFile)) return null;\n return readFileSync(focusFile, \"utf-8\").trim() || null;\n }\n\n setFocusedGoal(roleId: string, name: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalsDir = join(roleDir, \"goals\");\n const goalDir = join(goalsDir, name);\n\n if (!existsSync(goalDir)) {\n throw new Error(`Goal not found: ${name}`);\n }\n\n writeFileSync(join(goalsDir, \".focus\"), name, \"utf-8\");\n }\n\n // ========== Write ==========\n\n createGoal(roleId: string, name: string, source: string, testable?: boolean): Goal {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = join(roleDir, \"goals\", name);\n mkdirSync(goalDir, { recursive: true });\n\n if (testable) source = `@testable\\n${source}`;\n const filePath = join(goalDir, `${name}.goal.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"goal\") as Goal;\n }\n\n createPlan(roleId: string, source: string): Plan {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const goalName = basename(goalDir);\n const filePath = join(goalDir, `${goalName}.plan.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"plan\") as Plan;\n }\n\n createTask(roleId: string, name: string, source: string, testable?: boolean): Task {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const tasksDir = join(goalDir, \"tasks\");\n mkdirSync(tasksDir, { recursive: true });\n\n if (testable) source = `@testable\\n${source}`;\n const filePath = join(tasksDir, `${name}.task.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"task\") as Task;\n }\n\n // ========== Close ==========\n\n completeGoal(roleId: string, experience?: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\")!;\n this.addDoneTag(goalFile);\n\n if (experience) {\n const goalName = basename(goalDir);\n this.growup(roleId, \"experience\", goalName, experience);\n }\n }\n\n abandonGoal(roleId: string, experience?: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\")!;\n this.addTag(goalFile, \"@abandoned\");\n\n if (experience) {\n const goalName = basename(goalDir);\n this.growup(roleId, \"experience\", goalName, experience);\n }\n }\n\n completeTask(roleId: string, name: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const tasksDir = join(goalDir, \"tasks\");\n const taskFile = join(tasksDir, `${name}.task.feature`);\n if (!existsSync(taskFile)) throw new Error(`Task not found: ${name}`);\n\n this.addDoneTag(taskFile);\n }\n\n // ========== Internal ==========\n\n private loadConfig(): RolexConfig {\n if (this.config) return this.config;\n\n const configPath = join(this.rootDir, \"rolex.json\");\n if (existsSync(configPath)) {\n this.config = JSON.parse(readFileSync(configPath, \"utf-8\"));\n return this.config!;\n }\n\n throw new Error(`No rolex.json found in ${this.rootDir}. Call found() first.`);\n }\n\n private saveConfig(config: RolexConfig): void {\n writeFileSync(join(this.rootDir, \"rolex.json\"), JSON.stringify(config, null, 2), \"utf-8\");\n this.config = config;\n }\n\n private resolveRoleDir(roleId: string): string {\n const roleDir = join(this.rootDir, roleId);\n if (!existsSync(roleDir)) {\n throw new Error(`Role directory not found: ${roleDir}`);\n }\n return roleDir;\n }\n\n private loadGoalIfActive(goalDir: string): (Goal & { plan: Plan | null; tasks: Task[] }) | null {\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\");\n if (!goalFile) return null;\n\n const source = readFileSync(goalFile, \"utf-8\");\n const doc = parse(source);\n if (!doc.feature) return null;\n\n if (doc.feature.tags.some((t) => t.name === \"@done\" || t.name === \"@abandoned\")) return null;\n\n const goal = this.toFeature(doc.feature, \"goal\") as Goal;\n return {\n ...goal,\n plan: this.loadPlan(goalDir),\n tasks: this.loadTasks(goalDir),\n };\n }\n\n private getActiveGoalDir(roleDir: string): string | null {\n const goalsDir = join(roleDir, \"goals\");\n if (!existsSync(goalsDir)) return null;\n\n // Respect focused goal\n const focusFile = join(goalsDir, \".focus\");\n if (existsSync(focusFile)) {\n const focusedName = readFileSync(focusFile, \"utf-8\").trim();\n if (focusedName) {\n const focusedDir = join(goalsDir, focusedName);\n if (existsSync(focusedDir) && this.loadGoalIfActive(focusedDir)) {\n return focusedDir;\n }\n }\n }\n\n // Fallback: first uncompleted goal\n const goalDirs = readdirSync(goalsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort();\n\n for (const goalName of goalDirs) {\n const goalDir = join(goalsDir, goalName);\n if (this.loadGoalIfActive(goalDir)) {\n return goalDir;\n }\n }\n\n return null;\n }\n\n private toFeature(gherkin: GherkinFeature, type: Feature[\"type\"]): Feature {\n return {\n ...gherkin,\n type,\n scenarios: this.extractScenarios(gherkin),\n };\n }\n\n private extractScenarios(feature: GherkinFeature): Scenario[] {\n const featureTestable = feature.tags.some((t) => t.name === \"@testable\");\n return (feature.children || [])\n .filter((c) => c.scenario)\n .map((c) => ({\n ...c.scenario!,\n verifiable: featureTestable || c.scenario!.tags.some((t) => t.name === \"@testable\"),\n }));\n }\n\n private loadPlan(goalDir: string): Plan | null {\n const planFile = this.findFeatureFile(goalDir, \".plan.feature\");\n if (!planFile) return null;\n\n const source = readFileSync(planFile, \"utf-8\");\n const doc = parse(source);\n if (!doc.feature) return null;\n\n return this.toFeature(doc.feature, \"plan\") as Plan;\n }\n\n private loadTasks(goalDir: string): Task[] {\n const tasksDir = join(goalDir, \"tasks\");\n if (!existsSync(tasksDir)) return [];\n\n return readdirSync(tasksDir)\n .filter((f) => f.endsWith(\".task.feature\"))\n .sort()\n .map((f) => {\n const source = readFileSync(join(tasksDir, f), \"utf-8\");\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"task\") as Task;\n });\n }\n\n private detectIdentityType(filename: string): Feature[\"type\"] {\n if (filename === \"persona.identity.feature\") return \"persona\";\n if (filename.endsWith(\".knowledge.identity.feature\")) return \"knowledge\";\n if (filename.endsWith(\".experience.identity.feature\")) return \"experience\";\n if (filename.endsWith(\".voice.identity.feature\")) return \"voice\";\n return \"knowledge\";\n }\n\n private findFeatureFile(dir: string, suffix: string): string | null {\n if (!existsSync(dir)) return null;\n const file = readdirSync(dir).find((f) => f.endsWith(suffix));\n return file ? join(dir, file) : null;\n }\n\n private addTag(filePath: string, tag: string): void {\n const content = readFileSync(filePath, \"utf-8\");\n const updated = content.replace(/^(Feature:)/m, `${tag}\\n$1`);\n writeFileSync(filePath, updated, \"utf-8\");\n }\n\n private addDoneTag(filePath: string): void {\n this.addTag(filePath, \"@done\");\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/LocalPlatform.ts"],"sourcesContent":["/**\n * LocalPlatform — Local filesystem implementation of Platform.\n *\n * Everything lives under a single .rolex/ directory.\n * rolex.json is the single source of truth (CAS):\n * - roles: all born role names\n * - organization: optional org with teams\n *\n * Directory convention:\n * <rootDir>/rolex.json <- Society config (always exists)\n * <rootDir>/<role>/identity/*.identity.feature <- Identity features\n * <rootDir>/<role>/goals/<name>/<name>.goal.feature\n * <rootDir>/<role>/goals/<name>/<name>.plan.feature\n * <rootDir>/<role>/goals/<name>/tasks/<name>.task.feature\n */\n\nimport { readdirSync, readFileSync, writeFileSync, mkdirSync, existsSync, rmSync } from \"node:fs\";\nimport { join, basename } from \"node:path\";\nimport { parse } from \"@rolexjs/parser\";\nimport type { Feature as GherkinFeature } from \"@rolexjs/parser\";\nimport type {\n Platform,\n RolexConfig,\n Organization,\n RoleEntry,\n Feature,\n Scenario,\n Goal,\n Plan,\n Task,\n} from \"@rolexjs/core\";\n\nexport class LocalPlatform implements Platform {\n private readonly rootDir: string;\n private config: RolexConfig | null = null;\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n // ========== Found ==========\n\n found(name: string): void {\n const config = this.loadConfig();\n config.organization = {\n name,\n teams: { default: [] },\n };\n this.saveConfig(config);\n }\n\n // ========== Organization ==========\n\n organization(): Organization | null {\n const config = this.loadConfig();\n if (!config.organization) return null;\n\n const roles: RoleEntry[] = [];\n\n for (const [teamName, roleNames] of Object.entries(config.organization.teams)) {\n for (const roleName of roleNames) {\n roles.push({\n name: roleName,\n team: teamName,\n });\n }\n }\n\n return { name: config.organization.name, roles };\n }\n\n // ========== Society ==========\n\n allBornRoles(): string[] {\n return this.loadConfig().roles;\n }\n\n // ========== Born ==========\n\n born(name: string, source: string): Feature {\n const roleDir = join(this.rootDir, name);\n mkdirSync(join(roleDir, \"identity\"), { recursive: true });\n mkdirSync(join(roleDir, \"goals\"), { recursive: true });\n\n const filePath = join(roleDir, \"identity\", \"persona.identity.feature\");\n writeFileSync(filePath, source, \"utf-8\");\n\n // Register in config (CAS)\n const config = this.loadConfig();\n if (!config.roles.includes(name)) {\n config.roles.push(name);\n this.saveConfig(config);\n }\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"persona\");\n }\n\n hire(name: string): void {\n const config = this.loadConfig();\n if (!config.organization) throw new Error(\"No organization found. Call found() first.\");\n\n if (!config.roles.includes(name)) {\n throw new Error(`Role not found: ${name}. Call born() first.`);\n }\n\n // Pure config update — goals dir already exists from born()\n const [firstTeam] = Object.keys(config.organization.teams);\n if (!config.organization.teams[firstTeam].includes(name)) {\n config.organization.teams[firstTeam].push(name);\n this.saveConfig(config);\n }\n }\n\n fire(name: string): void {\n const config = this.loadConfig();\n if (!config.organization) throw new Error(\"No organization found. Call found() first.\");\n\n // Check role is in org\n let found = false;\n for (const teamName of Object.keys(config.organization.teams)) {\n const idx = config.organization.teams[teamName].indexOf(name);\n if (idx !== -1) {\n config.organization.teams[teamName].splice(idx, 1);\n found = true;\n break;\n }\n }\n if (!found) throw new Error(`Role not hired: ${name}`);\n\n // Pure config update — goals are the role's own, not deleted\n this.saveConfig(config);\n }\n\n // ========== Growup ==========\n\n growup(\n roleId: string,\n type: \"knowledge\" | \"experience\" | \"voice\",\n name: string,\n source: string\n ): Feature {\n const roleDir = this.resolveRoleDir(roleId);\n const dir = join(roleDir, \"identity\");\n mkdirSync(dir, { recursive: true });\n\n const filePath = join(dir, `${name}.${type}.identity.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, type);\n }\n\n // ========== Reflect ==========\n\n reflect(\n roleId: string,\n experienceNames: string[],\n knowledgeName: string,\n knowledgeSource: string\n ): Feature {\n const roleDir = this.resolveRoleDir(roleId);\n const identityDir = join(roleDir, \"identity\");\n\n // Delete experience files\n for (const expName of experienceNames) {\n const expFile = join(identityDir, `${expName}.experience.identity.feature`);\n if (!existsSync(expFile)) {\n throw new Error(`Experience not found: ${expName}`);\n }\n rmSync(expFile);\n }\n\n // Create knowledge\n return this.growup(roleId, \"knowledge\", knowledgeName, knowledgeSource);\n }\n\n // ========== Query ==========\n\n identity(roleId: string): Feature[] {\n const roleDir = this.resolveRoleDir(roleId);\n const dir = join(roleDir, \"identity\");\n if (!existsSync(dir)) return [];\n\n return readdirSync(dir)\n .filter((f) => f.endsWith(\".identity.feature\"))\n .sort()\n .map((f) => {\n const source = readFileSync(join(dir, f), \"utf-8\");\n const doc = parse(source);\n return this.toFeature(doc.feature!, this.detectIdentityType(f));\n });\n }\n\n activeGoal(roleId: string): (Goal & { plan: Plan | null; tasks: Task[] }) | null {\n const roleDir = this.resolveRoleDir(roleId);\n const goalsDir = join(roleDir, \"goals\");\n if (!existsSync(goalsDir)) return null;\n\n // If a focused goal is set, try to load it first\n const focusedName = this.getFocusedGoal(roleId);\n if (focusedName) {\n const goalDir = join(goalsDir, focusedName);\n const result = this.loadGoalIfActive(goalDir);\n if (result) return result;\n }\n\n // Fallback: first uncompleted goal alphabetically\n const goalDirs = readdirSync(goalsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort();\n\n for (const goalName of goalDirs) {\n const goalDir = join(goalsDir, goalName);\n const result = this.loadGoalIfActive(goalDir);\n if (result) return result;\n }\n\n return null;\n }\n\n allActiveGoals(roleId: string): Goal[] {\n const roleDir = this.resolveRoleDir(roleId);\n const goalsDir = join(roleDir, \"goals\");\n if (!existsSync(goalsDir)) return [];\n\n const goalDirs = readdirSync(goalsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort();\n\n const goals: Goal[] = [];\n for (const goalName of goalDirs) {\n const goalDir = join(goalsDir, goalName);\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\");\n if (!goalFile) continue;\n\n const source = readFileSync(goalFile, \"utf-8\");\n const doc = parse(source);\n if (!doc.feature) continue;\n\n if (doc.feature.tags.some((t) => t.name === \"@done\" || t.name === \"@abandoned\")) continue;\n\n goals.push(this.toFeature(doc.feature, \"goal\") as Goal);\n }\n\n return goals;\n }\n\n getFocusedGoal(roleId: string): string | null {\n const roleDir = this.resolveRoleDir(roleId);\n const focusFile = join(roleDir, \"goals\", \".focus\");\n if (!existsSync(focusFile)) return null;\n return readFileSync(focusFile, \"utf-8\").trim() || null;\n }\n\n setFocusedGoal(roleId: string, name: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalsDir = join(roleDir, \"goals\");\n const goalDir = join(goalsDir, name);\n\n if (!existsSync(goalDir)) {\n throw new Error(`Goal not found: ${name}`);\n }\n\n writeFileSync(join(goalsDir, \".focus\"), name, \"utf-8\");\n }\n\n // ========== Write ==========\n\n createGoal(roleId: string, name: string, source: string, testable?: boolean): Goal {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = join(roleDir, \"goals\", name);\n mkdirSync(goalDir, { recursive: true });\n\n if (testable) source = `@testable\\n${source}`;\n const filePath = join(goalDir, `${name}.goal.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"goal\") as Goal;\n }\n\n createPlan(roleId: string, source: string): Plan {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const goalName = basename(goalDir);\n const filePath = join(goalDir, `${goalName}.plan.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"plan\") as Plan;\n }\n\n createTask(roleId: string, name: string, source: string, testable?: boolean): Task {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const tasksDir = join(goalDir, \"tasks\");\n mkdirSync(tasksDir, { recursive: true });\n\n if (testable) source = `@testable\\n${source}`;\n const filePath = join(tasksDir, `${name}.task.feature`);\n writeFileSync(filePath, source, \"utf-8\");\n\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"task\") as Task;\n }\n\n // ========== Close ==========\n\n completeGoal(roleId: string, experience?: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\")!;\n this.addDoneTag(goalFile);\n\n if (experience) {\n const goalName = basename(goalDir);\n this.growup(roleId, \"experience\", goalName, experience);\n }\n }\n\n abandonGoal(roleId: string, experience?: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\")!;\n this.addTag(goalFile, \"@abandoned\");\n\n if (experience) {\n const goalName = basename(goalDir);\n this.growup(roleId, \"experience\", goalName, experience);\n }\n }\n\n completeTask(roleId: string, name: string): void {\n const roleDir = this.resolveRoleDir(roleId);\n const goalDir = this.getActiveGoalDir(roleDir);\n if (!goalDir) throw new Error(\"No active goal\");\n\n const tasksDir = join(goalDir, \"tasks\");\n const taskFile = join(tasksDir, `${name}.task.feature`);\n if (!existsSync(taskFile)) throw new Error(`Task not found: ${name}`);\n\n this.addDoneTag(taskFile);\n }\n\n // ========== Internal ==========\n\n /**\n * Load config — always returns a valid RolexConfig.\n * Creates default config if rolex.json doesn't exist yet.\n */\n private loadConfig(): RolexConfig {\n if (this.config) return this.config;\n\n const configPath = join(this.rootDir, \"rolex.json\");\n if (existsSync(configPath)) {\n this.config = JSON.parse(readFileSync(configPath, \"utf-8\"));\n return this.config!;\n }\n\n // Create default config\n mkdirSync(this.rootDir, { recursive: true });\n const config: RolexConfig = { roles: [], organization: null };\n this.saveConfig(config);\n return config;\n }\n\n private saveConfig(config: RolexConfig): void {\n mkdirSync(this.rootDir, { recursive: true });\n writeFileSync(join(this.rootDir, \"rolex.json\"), JSON.stringify(config, null, 2), \"utf-8\");\n this.config = config;\n }\n\n private resolveRoleDir(roleId: string): string {\n const roleDir = join(this.rootDir, roleId);\n if (!existsSync(roleDir)) {\n throw new Error(`Role directory not found: ${roleDir}`);\n }\n return roleDir;\n }\n\n private loadGoalIfActive(goalDir: string): (Goal & { plan: Plan | null; tasks: Task[] }) | null {\n const goalFile = this.findFeatureFile(goalDir, \".goal.feature\");\n if (!goalFile) return null;\n\n const source = readFileSync(goalFile, \"utf-8\");\n const doc = parse(source);\n if (!doc.feature) return null;\n\n if (doc.feature.tags.some((t) => t.name === \"@done\" || t.name === \"@abandoned\")) return null;\n\n const goal = this.toFeature(doc.feature, \"goal\") as Goal;\n return {\n ...goal,\n plan: this.loadPlan(goalDir),\n tasks: this.loadTasks(goalDir),\n };\n }\n\n private getActiveGoalDir(roleDir: string): string | null {\n const goalsDir = join(roleDir, \"goals\");\n if (!existsSync(goalsDir)) return null;\n\n // Respect focused goal\n const focusFile = join(goalsDir, \".focus\");\n if (existsSync(focusFile)) {\n const focusedName = readFileSync(focusFile, \"utf-8\").trim();\n if (focusedName) {\n const focusedDir = join(goalsDir, focusedName);\n if (existsSync(focusedDir) && this.loadGoalIfActive(focusedDir)) {\n return focusedDir;\n }\n }\n }\n\n // Fallback: first uncompleted goal\n const goalDirs = readdirSync(goalsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort();\n\n for (const goalName of goalDirs) {\n const goalDir = join(goalsDir, goalName);\n if (this.loadGoalIfActive(goalDir)) {\n return goalDir;\n }\n }\n\n return null;\n }\n\n private toFeature(gherkin: GherkinFeature, type: Feature[\"type\"]): Feature {\n return {\n ...gherkin,\n type,\n scenarios: this.extractScenarios(gherkin),\n };\n }\n\n private extractScenarios(feature: GherkinFeature): Scenario[] {\n const featureTestable = feature.tags.some((t) => t.name === \"@testable\");\n return (feature.children || [])\n .filter((c) => c.scenario)\n .map((c) => ({\n ...c.scenario!,\n verifiable: featureTestable || c.scenario!.tags.some((t) => t.name === \"@testable\"),\n }));\n }\n\n private loadPlan(goalDir: string): Plan | null {\n const planFile = this.findFeatureFile(goalDir, \".plan.feature\");\n if (!planFile) return null;\n\n const source = readFileSync(planFile, \"utf-8\");\n const doc = parse(source);\n if (!doc.feature) return null;\n\n return this.toFeature(doc.feature, \"plan\") as Plan;\n }\n\n private loadTasks(goalDir: string): Task[] {\n const tasksDir = join(goalDir, \"tasks\");\n if (!existsSync(tasksDir)) return [];\n\n return readdirSync(tasksDir)\n .filter((f) => f.endsWith(\".task.feature\"))\n .sort()\n .map((f) => {\n const source = readFileSync(join(tasksDir, f), \"utf-8\");\n const doc = parse(source);\n return this.toFeature(doc.feature!, \"task\") as Task;\n });\n }\n\n private detectIdentityType(filename: string): Feature[\"type\"] {\n if (filename === \"persona.identity.feature\") return \"persona\";\n if (filename.endsWith(\".knowledge.identity.feature\")) return \"knowledge\";\n if (filename.endsWith(\".experience.identity.feature\")) return \"experience\";\n if (filename.endsWith(\".voice.identity.feature\")) return \"voice\";\n return \"knowledge\";\n }\n\n private findFeatureFile(dir: string, suffix: string): string | null {\n if (!existsSync(dir)) return null;\n const file = readdirSync(dir).find((f) => f.endsWith(suffix));\n return file ? join(dir, file) : null;\n }\n\n private addTag(filePath: string, tag: string): void {\n const content = readFileSync(filePath, \"utf-8\");\n const updated = content.replace(/^(Feature:)/m, `${tag}\\n$1`);\n writeFileSync(filePath, updated, \"utf-8\");\n }\n\n private addDoneTag(filePath: string): void {\n this.addTag(filePath, \"@done\");\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rolexjs/local-platform",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Local filesystem Platform for RoleX — stores roles in .rolex/ directories",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"clean": "rm -rf dist"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@rolexjs/core": "^0.
|
|
23
|
-
"@rolexjs/parser": "^0.
|
|
22
|
+
"@rolexjs/core": "^0.8.0",
|
|
23
|
+
"@rolexjs/parser": "^0.8.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"rolexjs": "^0.
|
|
26
|
+
"rolexjs": "^0.8.0"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|