@aigne/afs-sandbox 1.11.0-beta.6 → 1.11.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,7 +38,7 @@ await afs.write("/modules/sandbox/scripts/greet.js", {
38
38
  });
39
39
 
40
40
  // Execute the script
41
- const result = await afs.exec("/modules/sandbox/@exec/greet", { name: "World" });
41
+ const result = await afs.exec("/modules/sandbox/scripts/greet.js", { name: "World" });
42
42
  // result.data = { success: true, result: "Hello, World", logs: [...] }
43
43
  ```
44
44
 
@@ -83,15 +83,15 @@ Scripts are stored at `/scripts/{name}.js` with automatic metadata and version t
83
83
 
84
84
  **Version History:**
85
85
  - Last 5 versions automatically preserved
86
- - Access via `/@history/{name}` path
87
- - Rollback support via `/@actions/rollback`
86
+ - Access via `/scripts/{name}.js/@history`
87
+ - Rollback support via `/.actions/rollback`
88
88
 
89
89
  ### Execution Context & History
90
90
 
91
91
  Track executions with context information:
92
92
 
93
93
  ```typescript
94
- const result = await afs.exec("/modules/sandbox/@exec/script", args, {
94
+ const result = await afs.exec("/modules/sandbox/scripts/script.js", args, {
95
95
  context: {
96
96
  userId: "user-123",
97
97
  sessionId: "session-456"
@@ -110,10 +110,10 @@ Create scripts from built-in templates:
110
110
 
111
111
  ```typescript
112
112
  // List available templates
113
- const templates = await afs.list("/modules/sandbox/@templates");
113
+ const templates = await afs.list("/modules/sandbox/templates");
114
114
 
115
115
  // Create script from template
116
- await afs.exec("/modules/sandbox/@actions/create-from-template", {
116
+ await afs.exec("/modules/sandbox/.actions/create-from-template", {
117
117
  template: "data-transform",
118
118
  name: "my-transformer",
119
119
  variables: {
@@ -135,7 +135,7 @@ Promote tested scripts to formal actions:
135
135
 
136
136
  ```typescript
137
137
  // Promote a script to an action
138
- await afs.exec("/modules/sandbox/@actions/promote", {
138
+ await afs.exec("/modules/sandbox/.actions/promote", {
139
139
  script: "calculator",
140
140
  name: "calculate",
141
141
  description: "Perform arithmetic calculations",
@@ -150,7 +150,7 @@ await afs.exec("/modules/sandbox/@actions/promote", {
150
150
  });
151
151
 
152
152
  // Execute the promoted action
153
- const result = await afs.exec("/modules/sandbox/@actions/calculate", {
153
+ const result = await afs.exec("/modules/sandbox/.actions/calculate", {
154
154
  a: 10, b: 5, op: "mul"
155
155
  });
156
156
  ```
@@ -169,7 +169,7 @@ const sandbox = new AFSSandbox({
169
169
  });
170
170
 
171
171
  // Read audit log
172
- const auditLog = await afs.read("/modules/sandbox/@audit");
172
+ const auditLog = await afs.read("/modules/sandbox/audit");
173
173
  ```
174
174
 
175
175
  **Event Types:**
@@ -200,11 +200,11 @@ Monitor sandbox performance:
200
200
 
201
201
  ```typescript
202
202
  // Global metrics
203
- const metrics = await afs.read("/modules/sandbox/@metrics");
203
+ const metrics = await afs.read("/modules/sandbox/metrics");
204
204
  // { totalExecutions, successCount, failureCount, timeoutCount, averageDuration }
205
205
 
206
206
  // Per-script metrics
207
- const scriptMetrics = await afs.read("/modules/sandbox/@metrics/my-script");
207
+ const scriptMetrics = await afs.read("/modules/sandbox/metrics/scripts/my-script");
208
208
  ```
209
209
 
210
210
  ## Configuration
@@ -246,23 +246,27 @@ interface AFSSandboxOptions {
246
246
  ## Path Structure
247
247
 
248
248
  ```
249
- /modules/sandbox/
250
- ├── /scripts/ # Script storage
251
- │ └── {name}.js # Script content
252
- ├── /@exec/{name} # Execute stored script
253
- ├── /@history/{name} # Script version history
254
- ├── /@actions/
255
- ├── run # Run inline code
256
- ├── validate # Syntax validation
257
- ├── rollback # Rollback to previous version
258
- ├── promote # Promote script to action
259
- ├── create-from-template # Create script from template
260
- │ └── {promoted-action} # User-promoted actions
261
- ├── /@templates # List available templates
262
- │ └── {name} # Template details
263
- ├── /@metrics # Global execution metrics
264
- │ └── {script} # Per-script metrics
265
- └── /@audit # Audit log
249
+ /
250
+ ├── scripts/ # Script storage
251
+ │ └── {name}.js # Script file (executable via exec)
252
+ ├── .meta # Script metadata
253
+ ├── .actions/
254
+ │ │ └── exec # Execute the script
255
+ ├── @history # Version history
256
+ └── {version} # Specific version content
257
+ └── @execHistory # Execution history
258
+ ├── templates/ # Script templates
259
+ └── {name} # Template details
260
+ ├── metrics/ # Global execution metrics
261
+ │ └── scripts/{name} # Per-script metrics
262
+ ├── audit/ # Audit log
263
+ └── .actions/ # Root-level actions
264
+ ├── run # Run inline code
265
+ ├── validate # Syntax validation
266
+ ├── rollback # Rollback to previous version
267
+ ├── promote # Promote script to action
268
+ ├── create-from-template # Create script from template
269
+ └── {promoted-action} # User-promoted actions
266
270
  ```
267
271
 
268
272
  ## Execution Result
@@ -287,51 +291,6 @@ interface LogEntry {
287
291
  }
288
292
  ```
289
293
 
290
- ## Implementation Status
291
-
292
- ### Phase 1: POC (Complete) ✅
293
-
294
- Core execution loop validated with 47 tests.
295
-
296
- | KPI | Status |
297
- |-----|--------|
298
- | Basic execution | ✅ `return 2 + 2` → `{ success: true, result: 4 }` |
299
- | AFS read capability | ✅ `afs.read('/path')` works |
300
- | Error propagation | ✅ Full error messages with line numbers |
301
- | Timeout handling | ✅ Infinite loops timeout correctly |
302
- | Security isolation | ✅ No access to Node.js globals |
303
-
304
- ### Phase 2: MVP (Complete) ✅
305
-
306
- Internal team usable with 54 additional tests (101 total).
307
-
308
- | Feature | Status |
309
- |---------|--------|
310
- | afs.write() capability | ✅ Write to allowed paths |
311
- | Script version history | ✅ Last 5 versions preserved |
312
- | Execution context | ✅ userId, sessionId tracking |
313
- | Execution history | ✅ Per-script history with redaction |
314
- | Rollback support | ✅ Restore previous versions |
315
-
316
- ### Phase 3: Beta (Complete) ✅
317
-
318
- Production-ready with 55 additional tests (156 total).
319
-
320
- | Feature | Status |
321
- |---------|--------|
322
- | Script Promote Workflow | ✅ Promote scripts to formal actions |
323
- | Script Templates | ✅ 4 built-in templates |
324
- | Audit Logging | ✅ 6 event types tracked |
325
- | Rate Limiting | ✅ Global, per-user, per-script |
326
- | Execution Metrics | ✅ Global and per-script tracking |
327
-
328
- ### Phase 4+: Future Vision
329
-
330
- - Agent Tool Marketplace
331
- - Multi-agent orchestration
332
- - Alternative runtimes (Deno)
333
- - Full async/await support (see Limitations below)
334
-
335
294
  ## Known Limitations
336
295
 
337
296
  ### Async/Await Support (Deferred)
@@ -344,15 +303,11 @@ Production-ready with 55 additional tests (156 total).
344
303
  | Single-statement operations | Complex Promise chains |
345
304
  | Synchronous data processing | `setTimeout`/`setInterval` |
346
305
 
347
- **Technical Reason:** QuickJS (WebAssembly) executes JavaScript synchronously. While we set up Promise infrastructure for capability calls, the runtime cannot pause execution to wait for external async operations. Implementing full async/await would require:
306
+ **Technical Reason:** QuickJS (WebAssembly) executes JavaScript synchronously. While we set up Promise infrastructure for capability calls, the runtime cannot pause execution to wait for external async operations.
348
307
 
349
- 1. Custom Promise polling mechanism
350
- 2. Careful handle management to avoid memory leaks
351
- 3. Significant changes to the execution model
308
+ ### In-Memory Storage
352
309
 
353
- **Attempted Solution:** We tried implementing async support but encountered QuickJS handle leaks (`list_empty(&rt->gc_obj_list)` assertion failure) when Promises weren't properly resolved before context disposal.
354
-
355
- **Future Path:** Phase 4 may introduce Deno runtime as an alternative backend with native async support.
310
+ All scripts, versions, execution history, metrics, and audit logs are stored in memory. Data is lost when the process exits. For persistent storage, consider pairing with an external persistence layer.
356
311
 
357
312
  ### Other Limitations
358
313
 
@@ -361,11 +316,6 @@ Production-ready with 55 additional tests (156 total).
361
316
  - **Limited standard library**: Only core JavaScript, no Node.js APIs
362
317
  - **Memory ceiling**: Hard limit of configurable MB (default 128MB)
363
318
 
364
- ## Design Documents
365
-
366
- - **Design Philosophy**: [`/intent/designs/afs-as-llm-runtime.md`](../../intent/designs/afs-as-llm-runtime.md)
367
- - **Implementation Plan**: [`/intent/plans/sandbox-implementation.md`](../../intent/plans/sandbox-implementation.md)
368
-
369
319
  ## Technical Details
370
320
 
371
321
  ### Why QuickJS?
@@ -396,7 +346,7 @@ await afs.write("/modules/sandbox/scripts/calc.js", {
396
346
  `
397
347
  });
398
348
 
399
- const result = await afs.exec("/modules/sandbox/@exec/calc", {
349
+ const result = await afs.exec("/modules/sandbox/scripts/calc.js", {
400
350
  a: 10, b: 5, op: "mul"
401
351
  });
402
352
  // result.data.result = 50
@@ -420,7 +370,7 @@ await afs.write("/modules/sandbox/scripts/process.js", {
420
370
  `
421
371
  });
422
372
 
423
- const result = await afs.exec("/modules/sandbox/@exec/process", {
373
+ const result = await afs.exec("/modules/sandbox/scripts/process.js", {
424
374
  items: [{ id: 1 }, { id: 2 }]
425
375
  });
426
376
  ```
@@ -434,18 +384,18 @@ await afs.write("/modules/sandbox/scripts/greet.js", {
434
384
  });
435
385
 
436
386
  // Test it
437
- const test = await afs.exec("/modules/sandbox/@exec/greet", { name: "Alice" });
387
+ const test = await afs.exec("/modules/sandbox/scripts/greet.js", { name: "Alice" });
438
388
  // test.data.result = "Hello, Alice!"
439
389
 
440
390
  // 2. Promote to a formal action
441
- await afs.exec("/modules/sandbox/@actions/promote", {
391
+ await afs.exec("/modules/sandbox/.actions/promote", {
442
392
  script: "greet",
443
393
  name: "greet-user",
444
394
  description: "Greet a user by name"
445
395
  });
446
396
 
447
397
  // 3. Use the promoted action
448
- const result = await afs.exec("/modules/sandbox/@actions/greet-user", { name: "Bob" });
398
+ const result = await afs.exec("/modules/sandbox/.actions/greet-user", { name: "Bob" });
449
399
  // result.data.result = "Hello, Bob!"
450
400
  ```
451
401
 
@@ -461,7 +411,7 @@ await afs.write("/modules/sandbox/scripts/buggy.js", {
461
411
  });
462
412
 
463
413
  // Execute and get error
464
- const result = await afs.exec("/modules/sandbox/@exec/buggy", {
414
+ const result = await afs.exec("/modules/sandbox/scripts/buggy.js", {
465
415
  json: '{"value": {}}'
466
416
  });
467
417
  // result.data = {
@@ -478,7 +428,7 @@ await afs.write("/modules/sandbox/scripts/buggy.js", {
478
428
  });
479
429
 
480
430
  // Now it works
481
- const fixed = await afs.exec("/modules/sandbox/@exec/buggy", {
431
+ const fixed = await afs.exec("/modules/sandbox/scripts/buggy.js", {
482
432
  json: '{"value": {}}'
483
433
  });
484
434
  // fixed.data.result = 'default'