@a16njs/engine 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ import * as path from 'path';
2
+ export { LocalWorkspace, toWorkspace } from '@a16njs/models';
3
+ /**
4
+ * Read-only wrapper around another workspace.
5
+ * Allows read operations but throws on any write operation.
6
+ * Useful for dry-run scenarios.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const ws = new LocalWorkspace('source', '/project');
11
+ * const readOnly = new ReadOnlyWorkspace(ws);
12
+ * await readOnly.read('file.md'); // works
13
+ * await readOnly.write('file.md', 'content'); // throws!
14
+ * ```
15
+ */
16
+ export class ReadOnlyWorkspace {
17
+ underlying;
18
+ /**
19
+ * Create a new ReadOnlyWorkspace wrapping another workspace.
20
+ * @param underlying - The workspace to wrap
21
+ */
22
+ constructor(underlying) {
23
+ this.underlying = underlying;
24
+ }
25
+ get id() {
26
+ return this.underlying.id;
27
+ }
28
+ get root() {
29
+ return this.underlying.root;
30
+ }
31
+ resolve(relativePath) {
32
+ return this.underlying.resolve(relativePath);
33
+ }
34
+ exists(relativePath) {
35
+ return this.underlying.exists(relativePath);
36
+ }
37
+ read(relativePath) {
38
+ return this.underlying.read(relativePath);
39
+ }
40
+ async write(_relativePath, _content) {
41
+ throw new Error('Cannot write to read-only workspace');
42
+ }
43
+ readdir(relativePath) {
44
+ return this.underlying.readdir(relativePath);
45
+ }
46
+ async mkdir(_relativePath) {
47
+ throw new Error('Cannot mkdir in read-only workspace');
48
+ }
49
+ }
50
+ /**
51
+ * In-memory workspace for testing.
52
+ * Stores files in a Map, no filesystem access.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const ws = new MemoryWorkspace('test');
57
+ * await ws.write('rules/my-rule.md', '# Rule');
58
+ * const content = await ws.read('rules/my-rule.md');
59
+ * const entries = await ws.readdir('rules');
60
+ * // entries: [{ name: 'my-rule.md', isFile: true, isDirectory: false }]
61
+ * ```
62
+ */
63
+ export class MemoryWorkspace {
64
+ id;
65
+ root = '/memory';
66
+ files = new Map();
67
+ directories = new Set();
68
+ /**
69
+ * Create a new MemoryWorkspace.
70
+ * @param id - Unique identifier for this workspace
71
+ * @param initialFiles - Optional map of relative paths to file contents
72
+ */
73
+ constructor(id, initialFiles) {
74
+ this.id = id;
75
+ if (initialFiles) {
76
+ for (const [filePath, content] of Object.entries(initialFiles)) {
77
+ this.files.set(this.normalizePath(filePath), content);
78
+ }
79
+ }
80
+ }
81
+ resolve(relativePath) {
82
+ const normalized = this.normalizePath(relativePath);
83
+ if (normalized === '')
84
+ return this.root;
85
+ return this.root + '/' + normalized;
86
+ }
87
+ async exists(relativePath) {
88
+ const normalized = this.normalizePath(relativePath);
89
+ // Check if it's a file
90
+ if (this.files.has(normalized))
91
+ return true;
92
+ // Check if it's an explicit directory
93
+ if (this.directories.has(normalized))
94
+ return true;
95
+ // Check if it's an implicit directory (some file has this as a prefix)
96
+ if (normalized === '')
97
+ return true;
98
+ const prefix = normalized + '/';
99
+ for (const key of this.files.keys()) {
100
+ if (key.startsWith(prefix))
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ async read(relativePath) {
106
+ const normalized = this.normalizePath(relativePath);
107
+ const content = this.files.get(normalized);
108
+ if (content === undefined) {
109
+ throw new Error(`File not found: ${relativePath} in workspace ${this.id}`);
110
+ }
111
+ return content;
112
+ }
113
+ async write(relativePath, content) {
114
+ const normalized = this.normalizePath(relativePath);
115
+ this.files.set(normalized, content);
116
+ }
117
+ async readdir(relativePath) {
118
+ const normalized = this.normalizePath(relativePath);
119
+ // Check directory exists
120
+ if (!(await this.exists(normalized))) {
121
+ throw new Error(`Directory not found: ${relativePath} in workspace ${this.id}`);
122
+ }
123
+ const prefix = normalized === '' ? '' : normalized + '/';
124
+ const entries = new Map();
125
+ // Scan files for entries under this directory
126
+ for (const key of this.files.keys()) {
127
+ if (!key.startsWith(prefix))
128
+ continue;
129
+ const rest = key.slice(prefix.length);
130
+ const slashIndex = rest.indexOf('/');
131
+ if (slashIndex === -1) {
132
+ // Direct child file
133
+ entries.set(rest, { name: rest, isFile: true, isDirectory: false });
134
+ }
135
+ else {
136
+ // Subdirectory (from file path)
137
+ const dirName = rest.slice(0, slashIndex);
138
+ if (!entries.has(dirName)) {
139
+ entries.set(dirName, { name: dirName, isFile: false, isDirectory: true });
140
+ }
141
+ }
142
+ }
143
+ // Also scan explicit directories
144
+ for (const dir of this.directories) {
145
+ if (!dir.startsWith(prefix))
146
+ continue;
147
+ const rest = dir.slice(prefix.length);
148
+ if (rest === '')
149
+ continue;
150
+ const slashIndex = rest.indexOf('/');
151
+ const dirName = slashIndex === -1 ? rest : rest.slice(0, slashIndex);
152
+ if (!entries.has(dirName)) {
153
+ entries.set(dirName, { name: dirName, isFile: false, isDirectory: true });
154
+ }
155
+ }
156
+ return Array.from(entries.values());
157
+ }
158
+ async mkdir(relativePath) {
159
+ const normalized = this.normalizePath(relativePath);
160
+ if (normalized !== '') {
161
+ this.directories.add(normalized);
162
+ }
163
+ }
164
+ /**
165
+ * Get all file paths stored in this workspace (for test assertions).
166
+ * @returns Array of normalized file paths
167
+ */
168
+ getAllPaths() {
169
+ return Array.from(this.files.keys());
170
+ }
171
+ /**
172
+ * Normalize a path to use forward slashes and strip leading slash.
173
+ */
174
+ normalizePath(p) {
175
+ return p.split(path.sep).join('/').replace(/^\//, '');
176
+ }
177
+ }
178
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a16njs/engine",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Conversion engine for a16n",
5
5
  "license": "AGPL-3.0",
6
6
  "author": "Texarkanine",
@@ -31,14 +31,14 @@
31
31
  "dist"
32
32
  ],
33
33
  "dependencies": {
34
- "@a16njs/models": "0.9.0"
34
+ "@a16njs/models": "0.10.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^20.0.0",
38
38
  "typescript": "^5.4.0",
39
39
  "vitest": "^2.0.0",
40
- "@a16njs/plugin-cursor": "0.9.0",
41
- "@a16njs/plugin-claude": "0.9.0"
40
+ "@a16njs/plugin-cursor": "0.10.1",
41
+ "@a16njs/plugin-claude": "0.10.1"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc",